commit 2796ffd5f3ade68d4e9763efc0dfec7c067f76bc Author: IRBorisov <8611739+IRBorisov@users.noreply.github.com> Date: Fri Jun 7 20:30:06 2024 +0300 Initial commit diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..fa906dd --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,40 @@ +Checks: "*,\ + -altera-struct-pack-align,\ + -altera-unroll-loops,\ + -altera-id-dependent-backward-branch,\ + -llvmlibc-callee-namespace,\ + -llvmlibc-restrict-system-libc-headers,\ + -llvmlibc-implementation-in-namespace,\ + -llvmlibc-inline-function-decl,\ + -llvm-else-after-return,\ + -llvm-header-guard,\ + -llvm-include-order,\ + -bugprone-branch-clone,\ + -bugprone-suspicious-include,\ + -bugprone-easily-swappable-parameters,\ + -modernize-use-trailing-return-type,\ + -hicpp-special-member-functions,\ + -google-runtime-references,\ + -fuchsia-overloaded-operator,\ + -fuchsia-default-arguments,\ + -google-readability-todo,\ + -google-global-names-in-headers,\ + -readability-redundant-access-specifiers,\ + -readability-redundant-member-init,\ + -readability-else-after-return,\ + -readability-implicit-bool-conversion,\ + -readability-use-anyofallof,\ + -readability-identifier-length,\ + -performance-inefficient-string-concatenation,\ + -performance-unnecessary-value-param,\ + -fuchsia-default-arguments-declarations,\ + -fuchsia-trailing-return,\ + -fuchsia-multiple-inheritance,\ + -fuchsia-default-arguments-calls,\ + -misc-non-private-member-variables-in-classes,\ + -misc-no-recursion,\ + -misc-include-cleaner,\ + -cppcoreguidelines-special-member-functions,\ + -cppcoreguidelines-prefer-member-initializer,\ + -cppcoreguidelines-avoid-const-or-ref-data-members,\ + -cppcoreguidelines-non-private-member-variables-in-classes" \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..25b081e --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +.vscode +.vs +*.vcxproj.user +*.aps +~* +*.pch.tmp +*.clang.pch + +packages +bin +build +cppunit +import/lib + +Help.chm +src/pch/stdafx.h.hpp diff --git a/Exteor.sln b/Exteor.sln new file mode 100644 index 0000000..340d7c4 --- /dev/null +++ b/Exteor.sln @@ -0,0 +1,36 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28729.10 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Exteor", "Exteor.vcxproj", "{1CBF9FF9-2FA7-495B-BB7D-B6EE85AAAB48}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XTRCoreTest", "test\XTRCoreTest.vcxproj", "{576D16B8-96BF-4B5A-8B09-E1916375E34F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + Testing|x86 = Testing|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1CBF9FF9-2FA7-495B-BB7D-B6EE85AAAB48}.Debug|x86.ActiveCfg = Debug|Win32 + {1CBF9FF9-2FA7-495B-BB7D-B6EE85AAAB48}.Debug|x86.Build.0 = Debug|Win32 + {1CBF9FF9-2FA7-495B-BB7D-B6EE85AAAB48}.Release|x86.ActiveCfg = Release|Win32 + {1CBF9FF9-2FA7-495B-BB7D-B6EE85AAAB48}.Release|x86.Build.0 = Release|Win32 + {1CBF9FF9-2FA7-495B-BB7D-B6EE85AAAB48}.Testing|x86.ActiveCfg = Testing|Win32 + {1CBF9FF9-2FA7-495B-BB7D-B6EE85AAAB48}.Testing|x86.Build.0 = Testing|Win32 + {576D16B8-96BF-4B5A-8B09-E1916375E34F}.Debug|x86.ActiveCfg = Debug|Win32 + {576D16B8-96BF-4B5A-8B09-E1916375E34F}.Debug|x86.Build.0 = Debug|Win32 + {576D16B8-96BF-4B5A-8B09-E1916375E34F}.Release|x86.ActiveCfg = Release|Win32 + {576D16B8-96BF-4B5A-8B09-E1916375E34F}.Release|x86.Build.0 = Release|Win32 + {576D16B8-96BF-4B5A-8B09-E1916375E34F}.Testing|x86.ActiveCfg = Debug|Win32 + {576D16B8-96BF-4B5A-8B09-E1916375E34F}.Testing|x86.Build.0 = Debug|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A6C6D20A-92A6-4950-AC88-470EC707578D} + EndGlobalSection +EndGlobal diff --git a/Exteor.vcxproj b/Exteor.vcxproj new file mode 100644 index 0000000..846e0e0 --- /dev/null +++ b/Exteor.vcxproj @@ -0,0 +1,515 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {1CBF9FF9-2FA7-495B-BB7D-B6EE85AAAB48} + Application + Exteor + Unicode + v143 + false + Dynamic + MFCProj + + 10.0 + + + + false + true + + + false + true + + + true + + + true + + + + + + + + + + + + + + + + + + + + false + build\x86\$(Configuration)\bin\ + build\x86\$(Configuration)\ + + + false + build\x64\$(Configuration)\bin\ + build\x64\$(Configuration)\ + + + true + build\x86\$(Configuration)\bin\ + build\x86\$(Configuration)\ + + + true + build\x64\$(Configuration)\bin\ + build\x64\$(Configuration)\ + + + + include;header;src\pch;..\ConceptCore\output\include;..\OfficeOLE\include;C:\Program Files (x86)\Python312-32\include;%(AdditionalIncludeDirectories) + POCO_STATIC; NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + Use + Level4 + MaxSpeed + true + true + true + true + stdcpplatest + $(IntDir) + $(IntDir)obj\ + $(IntDir)vc$(PlatformToolsetVersion).pdb + $(IntDir)$(ProjectName).pch + false + + + lib\x86;..\ConceptCore\output\lib\x86;..\OfficeOLE\output\lib\x86;C:\Program Files (x86)\Python312-32\libs;%(AdditionalLibraryDirectories) + Version.lib;OfficeOLE.lib;ConceptCoreLibrary.lib;RSlang.lib;cclGraph.lib;cclLang.lib;oldnames.lib;Htmlhelp.Lib;iphlpapi.lib;%(AdditionalDependencies) + Windows + true + true + UseLinkTimeCodeGeneration + /ignore:4099 %(AdditionalOptions) + + + false + true + NDEBUG;%(PreprocessorDefinitions) + + + 0x0419 + NDEBUG;%(PreprocessorDefinitions) + $(IntDir)%(Filename).res + $(IntDir);%(AdditionalIncludeDirectories) + + + xcopy /y /s /q /i "import\cctext\" "$(OutDir)\cctext" +xcopy /y /s /q /i "distr\app" "$(OutDir)" +copy "C:\Program Files (x86)\Python312-32\Python312.dll" "$(OutDir)" +copy "C:\Program Files (x86)\Python312-32\Python312.pdb" "$(OutDir)" +if not exist bin\x86 mkdir bin\x86 +copy "$(OutDir)Exteor.exe" "bin\x86\Exteor.exe" + + + + + include;header;src\pch;..\ConceptCore\output\include;..\OfficeOLE\include;C:\Program Files\Python312\include;%(AdditionalIncludeDirectories) + POCO_STATIC;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + Use + Level4 + MaxSpeed + true + true + true + true + stdcpplatest + $(IntDir) + $(IntDir)obj\ + $(IntDir)vc$(PlatformToolsetVersion).pdb + $(IntDir)$(ProjectName).pch + false + + + lib\x64;..\ConceptCore\output\lib\x64;..\OfficeOLE\output\lib\x64;C:\Program Files\Python312\libs;%(AdditionalLibraryDirectories) + Version.lib;OfficeOLE.lib;ConceptCoreLibrary.lib;RSlang.lib;cclGraph.lib;cclLang.lib;oldnames.lib;Htmlhelp.Lib;iphlpapi.lib;%(AdditionalDependencies) + Windows + true + true + UseLinkTimeCodeGeneration + false + /ignore:4099 %(AdditionalOptions) + + + false + NDEBUG;%(PreprocessorDefinitions) + + + 0x0419 + NDEBUG;%(PreprocessorDefinitions) + $(IntDir)%(Filename).res + $(IntDir);%(AdditionalIncludeDirectories) + + + xcopy /y /s /q /i "import\cctext" "$(OutDir)\cctext\" +xcopy /y /s /q /i "distr\app" "$(OutDir)" +if not exist bin\x64 mkdir bin\x64 +copy "$(OutDir)Exteor.exe" "bin\x64\Exteor.exe" + + + + + Use + Level4 + Disabled + true + stdcpplatest + true + include;header;src\pch;..\ConceptCore\output\include;..\OfficeOLE\include;C:\Program Files (x86)\Python312-32\include;%(AdditionalIncludeDirectories) + POCO_STATIC;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(IntDir) + $(IntDir)obj\ + $(IntDir)$(ProjectName).pch + false + + + Windows + lib\x86;..\ConceptCore\output\lib\x86;..\OfficeOLE\output\lib\x86;C:\Program Files (x86)\Python312-32\libs;%(AdditionalLibraryDirectories) + Version.lib;OfficeOLEd.lib;ConceptCoreLibraryd.lib;cclLangd.lib;RSlangd.lib;cclGraphd.lib;Htmlhelp.Lib;iphlpapi.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + $(OutDir)$(ProjectName).pdb + true + false + /ignore:4099 %(AdditionalOptions) + + + false + true + _DEBUG;%(PreprocessorDefinitions) + + + 0x0419 + _DEBUG;%(PreprocessorDefinitions) + $(IntDir)%(Filename).res + $(IntDir);%(AdditionalIncludeDirectories) + + + xcopy /y /s /q /i "import\cctext" "$(OutDir)\cctext\" +xcopy /y /s /q /i "distr\app" "$(OutDir)" +copy "C:\Program Files (x86)\Python312-32\Python312_d.dll" "$(OutDir)" +copy "C:\Program Files (x86)\Python312-32\Python312_d.pdb" "$(OutDir)" + + + + + + + + + Use + Level4 + Disabled + true + stdcpplatest + true + include;header;src\pch;..\ConceptCore\output\include;..\OfficeOLE\include;C:\Program Files\Python312\include;%(AdditionalIncludeDirectories) + POCO_STATIC; _DEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(IntDir) + $(IntDir)obj\ + $(IntDir)$(ProjectName).pch + false + + + Windows + lib\x64;..\ConceptCore\output\lib\x64;..\OfficeOLE\output\lib\x64;C:\Program Files\Python312\libs;%(AdditionalLibraryDirectories) + Version.lib;OfficeOLEd.lib;ConceptCoreLibraryd.lib;cclLangd.lib;RSlangd.lib;cclGraphd.lib;Htmlhelp.Lib;iphlpapi.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + $(OutDir)$(ProjectName).pdb + true + false + /ignore:4099 %(AdditionalOptions) + + + false + _DEBUG;%(PreprocessorDefinitions) + + + 0x0419 + _DEBUG;%(PreprocessorDefinitions) + $(IntDir)%(Filename).res + $(IntDir);%(AdditionalIncludeDirectories) + + + xcopy /y /s /q /i "import\cctext" "$(OutDir)\cctext\" +xcopy /y /s /q /i "distr\app" "$(OutDir)" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {b0aba27b-9d39-4b48-9977-aff20925b309} + + + {7e5f3034-b8db-4073-bf8f-78ea626d5624} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Exteor.vcxproj.filters b/Exteor.vcxproj.filters new file mode 100644 index 0000000..2d2a085 --- /dev/null +++ b/Exteor.vcxproj.filters @@ -0,0 +1,684 @@ + + + + + {62974fe1-8635-428f-8e02-843dced85479} + + + {6cfd3265-633a-42ae-9c27-5b006d79e94d} + + + {b03512e3-d44b-44b3-b779-12d83db1302a} + + + {923c8b5c-33db-437e-a5db-cce23feed46e} + + + {ff492167-ad8d-4b78-8332-ea4363dfcdad} + + + {884d839f-9a66-48d0-9330-2c6225249817} + + + {8fa01752-ddb0-4486-a7fa-b4afea44ee21} + + + {5edb8888-6a9c-4485-91c8-ad8119e81397} + + + {6214ea60-4da6-44b5-86dd-9c9da72ede71} + + + {45ea4496-d420-4902-bda7-92761cea32de} + + + {c9d55ad9-a051-4356-a5d4-297eaa9f69f8} + + + {b3955260-d6c7-4e41-9a26-327852acf73a} + + + {7a6add22-6a81-4377-a5fc-3082fe49ad91} + + + {4f75beaf-8853-4b61-ba16-f893a82b7c39} + + + {549e9841-0652-43d6-b9b7-ce6273e7efcb} + + + {276e00ce-7a33-4e3f-9461-8234c15ba8c6} + + + {2fdf25f9-7f78-4c1a-853d-83d888e21f22} + + + + + root + + + doc + + + doc + + + doc + + + doc + + + doc + + + doc + + + root + + + root + + + common + + + common + + + common + + + common + + + common + + + common + + + core + + + core + + + core + + + viewmodel + + + viewmodel + + + view + + + view + + + view + + + view + + + view + + + view + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + dialog + + + dialog + + + dialog + + + dialog + + + io + + + io + + + io + + + common + + + doc + + + io + + + io + + + io + + + io + + + io + + + dialog\edit + + + dialog\io + + + dialog\io + + + dialog\edit + + + dialog\ops + + + dialog\ops + + + dialog\io + + + dialog\edit + + + dialog\ops + + + dialog\io + + + dialog\edit + + + dialog\prompt + + + dialog\prompt + + + dialog\prompt + + + dialog\prompt + + + dialog\prompt + + + ui\services + + + ui\services + + + ui\services + + + ui\services + + + core + + + io\loaders + + + io\loaders + + + io\loaders + + + io\loaders + + + common + + + doc + + + root + + + io\loaders + + + core + + + + + root + + + doc + + + doc + + + doc + + + doc + + + root + + + common + + + common + + + common + + + common + + + common + + + common + + + common + + + core + + + core + + + core + + + viewmodel + + + view + + + view + + + view + + + view + + + view + + + view + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + dialog + + + dialog + + + dialog + + + dialog + + + root + + + io + + + io + + + doc + + + io + + + common + + + io + + + io + + + io + + + io + + + dialog\edit + + + dialog\io + + + dialog\io + + + dialog\io + + + dialog\edit + + + dialog\ops + + + dialog\ops + + + dialog\io + + + dialog\edit + + + dialog\ops + + + dialog\edit + + + dialog\prompt + + + dialog\prompt + + + dialog\prompt + + + dialog\prompt + + + dialog\prompt + + + ui\services + + + ui\services + + + ui\services + + + ui\services + + + io\loaders + + + io\loaders + + + io\loaders + + + doc + + + doc + + + core + + + + + !Script + + + !Script + + + !Script + + + root\resource + + + root\resource + + + !Script + + + !Script + + + + + + + + + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + root\resource + + + + + root + + + \ No newline at end of file diff --git a/ExteorWithCCL.sln b/ExteorWithCCL.sln new file mode 100644 index 0000000..e2a71bf --- /dev/null +++ b/ExteorWithCCL.sln @@ -0,0 +1,184 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32505.173 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Exteor", "Exteor.vcxproj", "{1CBF9FF9-2FA7-495B-BB7D-B6EE85AAAB48}" + ProjectSection(ProjectDependencies) = postProject + {B0ABA27B-9D39-4B48-9977-AFF20925B309} = {B0ABA27B-9D39-4B48-9977-AFF20925B309} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ConceptCore", "..\ConceptCore\ccl\core\ConceptLibrary.vcxproj", "{B0ABA27B-9D39-4B48-9977-AFF20925B309}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cclTest", "..\ConceptCore\ccl\core\test\cclTest.vcxproj", "{F87048D4-952A-460E-96E8-1E2E1EAE34FC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XTRCoreTest", "test\XTRCoreTest.vcxproj", "{576D16B8-96BF-4B5A-8B09-E1916375E34F}" + ProjectSection(ProjectDependencies) = postProject + {B0ABA27B-9D39-4B48-9977-AFF20925B309} = {B0ABA27B-9D39-4B48-9977-AFF20925B309} + {F87048D4-952A-460E-96E8-1E2E1EAE34FC} = {F87048D4-952A-460E-96E8-1E2E1EAE34FC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RSlang", "..\ConceptCore\ccl\rslang\RSlang.vcxproj", "{A8529C63-42F5-43E6-97B8-2EC83F23E1F9}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RSLangTest", "..\ConceptCore\ccl\rslang\test\rslTest.vcxproj", "{32469CE1-303B-4DB4-8E03-B7EBED5851EB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cclGraph", "..\ConceptCore\ccl\cclGraph\cclGraph.vcxproj", "{7E1D5338-F819-4C96-B461-9EAAB8D02E1D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cclGraphTest", "..\ConceptCore\ccl\cclGraph\test\cclGraphTest.vcxproj", "{5A2501C1-FEFB-4B14-A94D-E8F19ADEA239}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cclCommonsTest", "..\ConceptCore\ccl\cclCommons\test\cclCommonsTest.vcxproj", "{53A380CF-B599-4170-89B1-642F1C3772E1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cclLang", "..\ConceptCore\ccl\cclLang\cclLang.vcxproj", "{76B03803-56CC-47C2-A8F0-2241FCAF2898}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cclLangTest", "..\ConceptCore\ccl\cclLang\test\cclLangTest.vcxproj", "{4754356B-DC01-4564-A035-270FFB72F6A0}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "libs", "libs", "{DC591058-8A8A-460E-93D0-B57C848DF12B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OfficeOLE", "..\OfficeOLE\OfficeOLE.vcxproj", "{7E5F3034-B8DB-4073-BF8F-78EA626D5624}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1CBF9FF9-2FA7-495B-BB7D-B6EE85AAAB48}.Debug|x64.ActiveCfg = Debug|x64 + {1CBF9FF9-2FA7-495B-BB7D-B6EE85AAAB48}.Debug|x64.Build.0 = Debug|x64 + {1CBF9FF9-2FA7-495B-BB7D-B6EE85AAAB48}.Debug|x86.ActiveCfg = Debug|Win32 + {1CBF9FF9-2FA7-495B-BB7D-B6EE85AAAB48}.Debug|x86.Build.0 = Debug|Win32 + {1CBF9FF9-2FA7-495B-BB7D-B6EE85AAAB48}.Release|x64.ActiveCfg = Release|x64 + {1CBF9FF9-2FA7-495B-BB7D-B6EE85AAAB48}.Release|x64.Build.0 = Release|x64 + {1CBF9FF9-2FA7-495B-BB7D-B6EE85AAAB48}.Release|x86.ActiveCfg = Release|Win32 + {1CBF9FF9-2FA7-495B-BB7D-B6EE85AAAB48}.Release|x86.Build.0 = Release|Win32 + {B0ABA27B-9D39-4B48-9977-AFF20925B309}.Debug|x64.ActiveCfg = Debug|x64 + {B0ABA27B-9D39-4B48-9977-AFF20925B309}.Debug|x64.Build.0 = Debug|x64 + {B0ABA27B-9D39-4B48-9977-AFF20925B309}.Debug|x86.ActiveCfg = Debug|Win32 + {B0ABA27B-9D39-4B48-9977-AFF20925B309}.Debug|x86.Build.0 = Debug|Win32 + {B0ABA27B-9D39-4B48-9977-AFF20925B309}.Release|x64.ActiveCfg = Release|x64 + {B0ABA27B-9D39-4B48-9977-AFF20925B309}.Release|x64.Build.0 = Release|x64 + {B0ABA27B-9D39-4B48-9977-AFF20925B309}.Release|x86.ActiveCfg = Release|Win32 + {B0ABA27B-9D39-4B48-9977-AFF20925B309}.Release|x86.Build.0 = Release|Win32 + {F87048D4-952A-460E-96E8-1E2E1EAE34FC}.Debug|x64.ActiveCfg = Debug|x64 + {F87048D4-952A-460E-96E8-1E2E1EAE34FC}.Debug|x64.Build.0 = Debug|x64 + {F87048D4-952A-460E-96E8-1E2E1EAE34FC}.Debug|x86.ActiveCfg = Debug|Win32 + {F87048D4-952A-460E-96E8-1E2E1EAE34FC}.Debug|x86.Build.0 = Debug|Win32 + {F87048D4-952A-460E-96E8-1E2E1EAE34FC}.Release|x64.ActiveCfg = Release|x64 + {F87048D4-952A-460E-96E8-1E2E1EAE34FC}.Release|x64.Build.0 = Release|x64 + {F87048D4-952A-460E-96E8-1E2E1EAE34FC}.Release|x86.ActiveCfg = Release|Win32 + {F87048D4-952A-460E-96E8-1E2E1EAE34FC}.Release|x86.Build.0 = Release|Win32 + {576D16B8-96BF-4B5A-8B09-E1916375E34F}.Debug|x64.ActiveCfg = Debug|x64 + {576D16B8-96BF-4B5A-8B09-E1916375E34F}.Debug|x64.Build.0 = Debug|x64 + {576D16B8-96BF-4B5A-8B09-E1916375E34F}.Debug|x86.ActiveCfg = Debug|Win32 + {576D16B8-96BF-4B5A-8B09-E1916375E34F}.Debug|x86.Build.0 = Debug|Win32 + {576D16B8-96BF-4B5A-8B09-E1916375E34F}.Release|x64.ActiveCfg = Release|x64 + {576D16B8-96BF-4B5A-8B09-E1916375E34F}.Release|x64.Build.0 = Release|x64 + {576D16B8-96BF-4B5A-8B09-E1916375E34F}.Release|x86.ActiveCfg = Release|Win32 + {576D16B8-96BF-4B5A-8B09-E1916375E34F}.Release|x86.Build.0 = Release|Win32 + {A8529C63-42F5-43E6-97B8-2EC83F23E1F9}.Debug|x64.ActiveCfg = Debug|x64 + {A8529C63-42F5-43E6-97B8-2EC83F23E1F9}.Debug|x64.Build.0 = Debug|x64 + {A8529C63-42F5-43E6-97B8-2EC83F23E1F9}.Debug|x86.ActiveCfg = Debug|Win32 + {A8529C63-42F5-43E6-97B8-2EC83F23E1F9}.Debug|x86.Build.0 = Debug|Win32 + {A8529C63-42F5-43E6-97B8-2EC83F23E1F9}.Release|x64.ActiveCfg = Release|x64 + {A8529C63-42F5-43E6-97B8-2EC83F23E1F9}.Release|x64.Build.0 = Release|x64 + {A8529C63-42F5-43E6-97B8-2EC83F23E1F9}.Release|x86.ActiveCfg = Release|Win32 + {A8529C63-42F5-43E6-97B8-2EC83F23E1F9}.Release|x86.Build.0 = Release|Win32 + {32469CE1-303B-4DB4-8E03-B7EBED5851EB}.Debug|x64.ActiveCfg = Debug|x64 + {32469CE1-303B-4DB4-8E03-B7EBED5851EB}.Debug|x64.Build.0 = Debug|x64 + {32469CE1-303B-4DB4-8E03-B7EBED5851EB}.Debug|x86.ActiveCfg = Debug|Win32 + {32469CE1-303B-4DB4-8E03-B7EBED5851EB}.Debug|x86.Build.0 = Debug|Win32 + {32469CE1-303B-4DB4-8E03-B7EBED5851EB}.Release|x64.ActiveCfg = Release|x64 + {32469CE1-303B-4DB4-8E03-B7EBED5851EB}.Release|x64.Build.0 = Release|x64 + {32469CE1-303B-4DB4-8E03-B7EBED5851EB}.Release|x86.ActiveCfg = Release|Win32 + {32469CE1-303B-4DB4-8E03-B7EBED5851EB}.Release|x86.Build.0 = Release|Win32 + {7E1D5338-F819-4C96-B461-9EAAB8D02E1D}.Debug|x64.ActiveCfg = Debug|x64 + {7E1D5338-F819-4C96-B461-9EAAB8D02E1D}.Debug|x64.Build.0 = Debug|x64 + {7E1D5338-F819-4C96-B461-9EAAB8D02E1D}.Debug|x86.ActiveCfg = Debug|Win32 + {7E1D5338-F819-4C96-B461-9EAAB8D02E1D}.Debug|x86.Build.0 = Debug|Win32 + {7E1D5338-F819-4C96-B461-9EAAB8D02E1D}.Release|x64.ActiveCfg = Release|x64 + {7E1D5338-F819-4C96-B461-9EAAB8D02E1D}.Release|x64.Build.0 = Release|x64 + {7E1D5338-F819-4C96-B461-9EAAB8D02E1D}.Release|x86.ActiveCfg = Release|Win32 + {7E1D5338-F819-4C96-B461-9EAAB8D02E1D}.Release|x86.Build.0 = Release|Win32 + {5A2501C1-FEFB-4B14-A94D-E8F19ADEA239}.Debug|x64.ActiveCfg = Debug|x64 + {5A2501C1-FEFB-4B14-A94D-E8F19ADEA239}.Debug|x64.Build.0 = Debug|x64 + {5A2501C1-FEFB-4B14-A94D-E8F19ADEA239}.Debug|x86.ActiveCfg = Debug|Win32 + {5A2501C1-FEFB-4B14-A94D-E8F19ADEA239}.Debug|x86.Build.0 = Debug|Win32 + {5A2501C1-FEFB-4B14-A94D-E8F19ADEA239}.Release|x64.ActiveCfg = Release|x64 + {5A2501C1-FEFB-4B14-A94D-E8F19ADEA239}.Release|x64.Build.0 = Release|x64 + {5A2501C1-FEFB-4B14-A94D-E8F19ADEA239}.Release|x86.ActiveCfg = Release|Win32 + {5A2501C1-FEFB-4B14-A94D-E8F19ADEA239}.Release|x86.Build.0 = Release|Win32 + {53A380CF-B599-4170-89B1-642F1C3772E1}.Debug|x64.ActiveCfg = Debug|x64 + {53A380CF-B599-4170-89B1-642F1C3772E1}.Debug|x64.Build.0 = Debug|x64 + {53A380CF-B599-4170-89B1-642F1C3772E1}.Debug|x86.ActiveCfg = Debug|Win32 + {53A380CF-B599-4170-89B1-642F1C3772E1}.Debug|x86.Build.0 = Debug|Win32 + {53A380CF-B599-4170-89B1-642F1C3772E1}.Release|x64.ActiveCfg = Release|x64 + {53A380CF-B599-4170-89B1-642F1C3772E1}.Release|x64.Build.0 = Release|x64 + {53A380CF-B599-4170-89B1-642F1C3772E1}.Release|x86.ActiveCfg = Release|Win32 + {53A380CF-B599-4170-89B1-642F1C3772E1}.Release|x86.Build.0 = Release|Win32 + {76B03803-56CC-47C2-A8F0-2241FCAF2898}.Debug|x64.ActiveCfg = Debug|x64 + {76B03803-56CC-47C2-A8F0-2241FCAF2898}.Debug|x64.Build.0 = Debug|x64 + {76B03803-56CC-47C2-A8F0-2241FCAF2898}.Debug|x86.ActiveCfg = Debug|Win32 + {76B03803-56CC-47C2-A8F0-2241FCAF2898}.Debug|x86.Build.0 = Debug|Win32 + {76B03803-56CC-47C2-A8F0-2241FCAF2898}.Release|x64.ActiveCfg = Release|x64 + {76B03803-56CC-47C2-A8F0-2241FCAF2898}.Release|x64.Build.0 = Release|x64 + {76B03803-56CC-47C2-A8F0-2241FCAF2898}.Release|x86.ActiveCfg = Release|Win32 + {76B03803-56CC-47C2-A8F0-2241FCAF2898}.Release|x86.Build.0 = Release|Win32 + {4754356B-DC01-4564-A035-270FFB72F6A0}.Debug|x64.ActiveCfg = Debug|x64 + {4754356B-DC01-4564-A035-270FFB72F6A0}.Debug|x64.Build.0 = Debug|x64 + {4754356B-DC01-4564-A035-270FFB72F6A0}.Debug|x86.ActiveCfg = Debug|Win32 + {4754356B-DC01-4564-A035-270FFB72F6A0}.Debug|x86.Build.0 = Debug|Win32 + {4754356B-DC01-4564-A035-270FFB72F6A0}.Release|x64.ActiveCfg = Release|x64 + {4754356B-DC01-4564-A035-270FFB72F6A0}.Release|x64.Build.0 = Release|x64 + {4754356B-DC01-4564-A035-270FFB72F6A0}.Release|x86.ActiveCfg = Release|Win32 + {4754356B-DC01-4564-A035-270FFB72F6A0}.Release|x86.Build.0 = Release|Win32 + {7E5F3034-B8DB-4073-BF8F-78EA626D5624}.Debug|x64.ActiveCfg = Debug|x64 + {7E5F3034-B8DB-4073-BF8F-78EA626D5624}.Debug|x64.Build.0 = Debug|x64 + {7E5F3034-B8DB-4073-BF8F-78EA626D5624}.Debug|x86.ActiveCfg = Debug|Win32 + {7E5F3034-B8DB-4073-BF8F-78EA626D5624}.Debug|x86.Build.0 = Debug|Win32 + {7E5F3034-B8DB-4073-BF8F-78EA626D5624}.Release|x64.ActiveCfg = Release|x64 + {7E5F3034-B8DB-4073-BF8F-78EA626D5624}.Release|x64.Build.0 = Release|x64 + {7E5F3034-B8DB-4073-BF8F-78EA626D5624}.Release|x86.ActiveCfg = Release|Win32 + {7E5F3034-B8DB-4073-BF8F-78EA626D5624}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {B0ABA27B-9D39-4B48-9977-AFF20925B309} = {DC591058-8A8A-460E-93D0-B57C848DF12B} + {F87048D4-952A-460E-96E8-1E2E1EAE34FC} = {DC591058-8A8A-460E-93D0-B57C848DF12B} + {A8529C63-42F5-43E6-97B8-2EC83F23E1F9} = {DC591058-8A8A-460E-93D0-B57C848DF12B} + {32469CE1-303B-4DB4-8E03-B7EBED5851EB} = {DC591058-8A8A-460E-93D0-B57C848DF12B} + {7E1D5338-F819-4C96-B461-9EAAB8D02E1D} = {DC591058-8A8A-460E-93D0-B57C848DF12B} + {5A2501C1-FEFB-4B14-A94D-E8F19ADEA239} = {DC591058-8A8A-460E-93D0-B57C848DF12B} + {53A380CF-B599-4170-89B1-642F1C3772E1} = {DC591058-8A8A-460E-93D0-B57C848DF12B} + {76B03803-56CC-47C2-A8F0-2241FCAF2898} = {DC591058-8A8A-460E-93D0-B57C848DF12B} + {4754356B-DC01-4564-A035-270FFB72F6A0} = {DC591058-8A8A-460E-93D0-B57C848DF12B} + {7E5F3034-B8DB-4073-BF8F-78EA626D5624} = {DC591058-8A8A-460E-93D0-B57C848DF12B} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0965040D-9561-4A25-A7DA-876C1632BA92} + EndGlobalSection + GlobalSection(SubversionScc) = preSolution + Svn-Managed = True + Manager = AnkhSVN - Subversion Support for Visual Studio + EndGlobalSection + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection + GlobalSection(DPCodeReviewSolutionGUID) = preSolution + DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000} + EndGlobalSection +EndGlobal diff --git a/distr/!!Листовка.docx b/distr/!!Листовка.docx new file mode 100644 index 0000000..89a5bdb Binary files /dev/null and b/distr/!!Листовка.docx differ diff --git a/distr/app/!Памятка.docx b/distr/app/!Памятка.docx new file mode 100644 index 0000000..bf1d959 Binary files /dev/null and b/distr/app/!Памятка.docx differ diff --git a/distr/app/DejaVu Sans.ttf b/distr/app/DejaVu Sans.ttf new file mode 100644 index 0000000..27cff47 Binary files /dev/null and b/distr/app/DejaVu Sans.ttf differ diff --git a/distr/app/UpdateLog.txt b/distr/app/UpdateLog.txt new file mode 100644 index 0000000..33d83ea --- /dev/null +++ b/distr/app/UpdateLog.txt @@ -0,0 +1,349 @@ +13.05.2024 Экстеор 4.9.2 +• Грамматика: разрешено использование пустого множества как литерала с типизацией B(R0) +• Грамматика: разрешено объявление кортежем в императивных блоках +31.03.2024 Экстеор 4.9.1 +• переход на Python 3.12.2 +• обновление ядра для синхронизации с КонцептПортал +01.09.2023 Экстеор 4.9.0 +• изменены горячие клавиши +• доработана установка зависимостей Python +• рефакторинг и подготовка к запуску веб-версии +01.05.2023 Экстеор 4.8.18 +• исправлена ошибка, приводившая к невозможности задания операции синтеза +20.04.2023 Экстеор 4.8.17 +• переработан ASCII синтаксис +• переработаны требования к содержанию файла схемы, сгенерированного сторонней программой +28.10.2022 Экстеор 4.8.16 +• исправлена ошибка в проверке интерпретируемости выражений, содержащих связанные переменные в рекурсии +03.08.2022 Экстеор 4.8.15 +• удалена лишняя строка в выгрузке КС в Word +• обновлен процесс установки. Требуется наличие Интернет соединения +• значительно уменьшен размер дистрибутива +• переход на Python 3.9.13 +----------------------------------------------- +03.06.2022 Экстеор 4.8.14 +• выгрузка в Word: конвенция теперь выгружается в столбец вместе со схемной интерпретацией +• исправлены тексты подсказок к элементам меню +• исправлена ошибка приводящая к зависанию процесса после выхода из Экстеор с открытой ОСС и РС-формой +• исправлена ошибка с флагом несохраненных изменений в документах после сохранения +• исправлена ошибка, приводившая к невозможности удалить таблицу отождествлений при изменнии типа операции на слияние +----------------------------------------------- +30.05.2022 Экстеор 4.8.13 +• удален атрибут "Имя модели". Для КС и КМ используется общий набор атрибутов - Название, Краткое обозначение +• переработана структура JSON выгрузки данных +• изменен формат хранения файлов +• переработан текстовый модуль, улучшена генерация текстовых форм +----------------------------------------------- +04.11.2021 Экстеор 4.8.12 +• исправлена некорректная работа ОСС с путями, содержащими кириллицу +----------------------------------------------- +04.08.2021 Экстеор 4.8.11 +• исправлена ошибка, приводившая к невозможности загрузки некоторых моделей +----------------------------------------------- +19.07.2021 Экстеор 4.8.10 +• добавлена 64-битная версия Экстеор, которая теперь является версией по умолчанию +• исправлен ряд ошибок, приводивших к крешу программы при отображении некоторых сообщений +• переход на 64-битную версию системных библиотек и Python3.9.5 +• добавлена опция отключения автоматического переключения раскладки клавиатуры +• улучшена читаемость JSON для РС-формы КС +----------------------------------------------- +03.05.2021 Экстеор 4.7.21 +• переход на Python 3.9 +• конституенты в подсказке отсылки упорядочены по идентификатору в алфавитном порядке +• исправлена ошибка в генерации структуры +• исправлена ошибка в порядке вставленных конституент при вставке после последней конституенты +----------------------------------------------- +01.09.2020 Экстеор 4.7.20 +• обновление ядра - повышение производительности +• исправлен ряд ошибок при проверке формальных выражений +• исправлен диалог генерации терма по терм-функции +----------------------------------------------- +01.06.2020 Экстеор 4.7.19 +• значительно улучшена производительность графа связей конституент +• добавлено сообщение об ошибки в выражении при попытке перебора множества всех целых чисел +• ОСС: исправлена ошибка в переименовании файлов, названия которых содержат кириллицу +• Модель: исправлен ряд ошибок при загрузке данных из Excel, редактированных вручную +• добавлены функция сброса ширины столбцов в контекстное меню таблицы конституент +• исправлена ошибка в описании логического круга +• исправлено падение программы при вводе некорректного имени отождествляемой конституенты +----------------------------------------------- +07.02.2020 Экстеор 4.7.18 +• исправлена ошибка с некорректным сохранением положения минимизированных окон +• добавлено соощбение об ошибке при попытке вставки отсылки в случае отсутствия терминов +----------------------------------------------- +01.02.2020 Экстеор 4.7.17 +• добавлена поддержка константных и целочисленных множеств (проверка корректности выражений) +• добавлена частичная поддержка вычисления значений выражений, содержащих элементы константных множеств +• улучшена читаемость ASCII синтаксиса +• изменен синтаксис блока объявления императивного определения +• удалена поддержка знака бесконечности +• добавлен идентификатор "Z" для обозначения множества целых чисел +• изменен синтаксис императивного определения +• удалена поддержка устаревшего декларативного синтаксиса +• исправлена ошибка в определении аргументов функций +• исправлена ошибка, приводившая к неполному обновлению типизаций зависимых конституент +----------------------------------------------- +23.12.2019 Экстеор 4.7.16 +• исправлен ряд ошибок в редакторе текстов +• мелкие правки в интерфейсе +----------------------------------------------- +01.11.2019 Экстеор 4.7.15 +• добавлена поддержка предикат-функций +• API ядра переведен на использование UTF8 строк +----------------------------------------------- +01.10.2019 Экстеор 4.7.14 +• добавлена проверка интерпретируемости выражения +• исправлено отображение интерфейса для пользовательского масштаба +----------------------------------------------- +19.09.2019 Экстеор 4.7.13 +• символы нижних индексов заменены на форматирование в RichEdit +• переработана грамматика языка родов структур +• добавлены мультипроекции и мультифитры +• добавлена параметризация функций произвольной типизацией аргументов +• добавлено выражение рекурсивного определения +• добавлено выражение пошагового императивного определения +• изменен синтаксис декларативного определения ("выражение терма") +----------------------------------------------- +02.09.2019 Экстеор 4.7.12 +• удален тип конституенты "Сокращение ступени" +• в выражении ступени теперь можно использовать любые конституенты +• переработана система экспорта/импорта +• добавлен экспорт КС в JSON и CSV +• добавлен экспорт дерева термов в TXT и CSV +• рефакторинг внутренней логики интерфейсов +----------------------------------------------- +05.07.2019 Экстеор 4.7.10.1300 +• исправлен ряд ошибок в интерфейсе ОСС +----------------------------------------------- +28.05.2019 Экстеор 4.7.10.1200 +• удалена возможность задания синонимов для понятий. В дальнейшем будет добавлена возможность работы с несколькими контекстами, позволяющая создавать "слои" терминов +• формат текстовых отсылок обновлен с учетом устранения синонимичности +• при отождествлении понятий удалена опция "сохранить оба термина" +• обновлены форматы хранения файлов с учетом нового формата текстовой отсылки и параметров отождествления +----------------------------------------------- +18.04.2019 Экстеор 4.7.10.1100 +• переход на использование Python 3.7 в модуле обработки текстов +• исправлен баг, приводивший к отображению старой типизации при проверке выражения в редакторе +----------------------------------------------- +11.04.2019 Экстеор 4.6.10.1001 +• изменена нумерация версий +• обновлен логотип +• обновлен установщик +----------------------------------------------- +20.02.2019 Экстеор 4.6 2115 +• улучшена точность определения положения ошибки в РС выражении +• исправлены ошибки, приводившие к некорректному пересинтезу +• исправлена работа операции Релятивизация +----------------------------------------------- +20.02.2019 Экстеор 4.6 2058 +• исправлено вычисление выражений с использованием терм-функций +• исправлено масштабирование таблицы конституент при изменении размера окна +----------------------------------------------- +29.01.2019 Экстеор 4.6 2036 +• улучшена идентификация синтаксических ошибок +• переработан парсер родов структур +----------------------------------------------- +13.12.2018 Экстеор 4.6 1974 +• исправлена ошибка в текстовом поле с отсылками на термины, приводившая к некорректному удалению отсылок +----------------------------------------------- +05.12.2018 Экстеор 4.6 1967 +• исправлена ошибка, приводившая к потере данных при закрытии диалога редактирования конституенты +• исправлен ряд ошибок, приводивших к вылету программы при вычислении объектных интерпретаций +----------------------------------------------- +14.11.2018 Экстеор 4.6 1948 +• скорректирован интерфейс ОСС +• в ОСС добавлена операция проверки операции и данных о наследуемых конституентах +• исправлены ошибки, приводившие к некорректной КС при пересинтезе +----------------------------------------------- +01.08.2018 Экстеор 4.6 1800 +• переписан код с использованием библиотеки ConceptCoreLibrary +• ВНИМАНИЕ! изменены форматы хранения файлов, осуществляется поддержка старых форматов +• ВНИМАНИЕ! изменен алгоритм хеширования РС-форм в ОСС. Потребуется пересинтез после загрузки старых схем синтеза +• скорректирован интерфейс редактирования конституенты +• порядок в списке констиутент теперь не влияет на операции и корректность типизаций +• исправлены ошибки предыдущих версий +----------------------------------------------- +11.01.2018 Экстеор 4.5 1569 +• исправлена ошибка при открытии файлов Экстеор 1 1992 года +----------------------------------------------- +28.06.2017 Экстеор 4.5 1562 +• добавлена поддержка открытия файлов, сохраненных в Экстеор 1 (1993 год и ранее) +• при выгрузке в Word выгружаются все термины каждой конституенты (ранее в выгрузке был только первый термин) +• ОСС: исправлена ошибка, приводившая к сбрасыванию типа отождествления при пересинтезе одной из родительских схем +----------------------------------------------- +04.05.2017 Экстеор 4.5 1555 +• обновлен формат хранения файлов ОСС. Файлы, сохраненные в новой версии не будут открываться в предыдущих версиях +• переработан интерфейс редактирования таблицы отождествлений +• добавлено сообщение после выгрузки в Word +• исправлена ошибка проверки типизации выражений с объявлением нескольких связанных переменных +• исправлен ряд ошибок в наследовании терминов и их вхождений при пересинтезе +----------------------------------------------- +20.04.2017 Экстеор 4.5 1550 +• исправлены ошибки в интерфейсе редактирования терминов +• исправлена в навигации по структуре формального выражения, приводившая к невозможности перехода вниз по структуре из корневого узла +• исправлен ряд ошибок, приводивших к потере синонимов при пересинтезе и установке некорректных флагов наследования кониституент +• исправлена ошибка, приводившая к сбрасыванию статуса наследованной конституенты при изменении интерпретации +• исправлена ошибка, приводившая к некорректной обработке объявления связанных переменных в кванторной декларации +----------------------------------------------- +04.04.2017 Экстеор 4.5 1545 +• устранена ошибка, приводившая к вылету программы при нажатии Del после удаления отсылки на термин +----------------------------------------------- +23.03.2017 Экстеор 4.5 1543 +• время загрузки больших КС значительно снижено +• исправлен ряд ошибок в интерфейсе редактирования текстов +----------------------------------------------- +15.03.2017 Экстеор 4.5 1541 +• ВНИМАНИЕ! Значительно изменен модуль проверки выражения ЯРС. Скобки, не несущие смысловой нагрузки считаются ошибочными +• добавлена подсветка блоков формального выражения в соответствии с деревом разбора +• добавлена навигация по формальному выражения с помощью клавишц CTRL+SHIFT+WASD +• добавлена возможность удалять текст, содержащий полностью несколько отсылок к терминам +• исправлена ошибка, приводившая к возможности редактирования ФВ наследованных констиутент +• исправлен ряд ошибок в текстовом модуле, приводивших к падению программы +----------------------------------------------- +10.03.2017 Экстеор 4.5 1536 +• Внимание! Значительно ужесточена проверка "лишних" пар скобок в формальных выражениях +• наличие синонимов в КС будет отображаться "желтым" статусом +• исправлен ряд ошибок в текстовом модуле, приводившим к некорректному формированию словоформ +----------------------------------------------- +07.03.2017 Экстеор 4.5 1533 +• добавлена возможность вычисления выражений с вложенными зависимыми переменными +• обновлены алгоритм и структура дерева разбора выражения ЯРС +• исправлена ошибка при проверке выражений с вложенными зависимыми переменными +• исправлена ошибка, приводившая к вылету при вызове операции в ОСС при совпадении имен файлов связанных пиктограмм +• исправлена ошибка, приводившая к удалению файла при попытке перезаписать его с помощью "Сохранить как" +• исправлено некорректное обновление выражений терм-функций при отождествлении +----------------------------------------------- +21.11.2016 Экстеор 4.5 1528 +• добавлена операция "Релятивизация" +• добавлена операция "Отождествление понятий" +• расширен синтаксис ЯРС: добавлены символы для присваивания и добавления элемента / подмножества +• расширена грамматика ЯРС: добавлено объявление связанных переменных при определении терма +• добавлено перемещение конституент в списке по нажатию Ctrl + клавиши +• добавлена автоматическое распознавание уже созданных термов при порождении термов из структуры понятия +----------------------------------------------- +22.09.2016 Экстеор 4.5 1516 +• исправлена ошибка, из-за которой текстовый модуль вызывал сбой в РС-модели +----------------------------------------------- +22.09.2016 Экстеор 4.5 1514 +• обновлен интерфейс навигации по терминам +• обновлен интерфейс вставки отсылки +• добавлен выбор конституент по имени при добавлении в формальное выражение +----------------------------------------------- +16.09.2016 Экстеор 4.5 1505 +• добавлен выбор конституент при добавлении отсылок в формальное выражение +• исправлен ряд ошибок текстового модуля +• изменены горячие клавиши для добавления отсылок +----------------------------------------------- +31.08.2016 Экстеор 4.5 1490 +• добавлен Текстовый модуль, позволяющий вставлять отсылки на термины в тексты интерпретаций и других терминов +• добавлена функция поиска конституенты по вхождению подстроки в текст термина или интерпретации +• добавлены сохранение (экспорт) данных концептуальной модели в Excel и их загрузка (импорт) +• добавлена возможность указывать несколько терминов для одной конституенты +• при отождествлении теперь необходимо выбирать что делать с вхождениями терминов удаляемого понятия: объединять с терминами отождествляемого понятия в качестве синонимов, либо заменять на вхождения отождествляемого понятия +• исправлен ряд ошибок в интерфейсе +• Внимание! Изменены форматы хранения файлов. Файлы, сохраненные в версии 1490 и выше не будут открываться в более ранних версиях +----------------------------------------------- +26.05.2016 Экстеор 4.0a 1404 +• исправлена ошибка синтезе с отождествлением терма с РС. От порядка операндов зависел результат операции +----------------------------------------------- +22.01.2016 Экстеор 4.0a 1403 +• исправлены ошибки при вычислении выражений +• изменен тип установочного файла с .exe на .msi +• теперь при установке новой версии не нужно вручную деинсталлировать старую +----------------------------------------------- +26.08.2015 Экстеор 4.0a 1399 +• файлы РС-форм автоматически открываются в уже открытом Экстеор 4 +• исправлен баг при вставке скопированных конституент +• переработан диалог экспорта РС-формы +----------------------------------------------- +04.06.2015 Экстеор 4.0a 1392 +• исправлен баг в сравнении типизаций, полученных путём взятия проекции +• исправлены пути для запуска с сетевого ресурса +• исправлен ряд опечаток +----------------------------------------------- +09.06.2014 Экстеор 4.0а 1369 +• В ОСС добавлена функция создания резервной копии ОСС +• Доработан интерфейс стартовой страницы. Добавлена "Памятка" пользователя. +• Исправлен порядок переносимых конституент при отождествлении БМ и Терма +• Исправлен ряд ошибок, возникавших при работе со списком конституент +• Доработана логика интерфейса редактирования конституенты +----------------------------------------------- +02.06.2014 Экстеор 4.0а 1362 +• Доработана логика прокрутки списка конституент при работе с диалогом редактирования конституент +• Исправлена ошибка, приводившая к некорректному сохранению таблицы отождествлений в пиктограмме ОСС +• Исправлена ошибка, приводившая к отображению ложных сообщений об ошибках при отождествления БМ и Терма +• Исправлена некорректная обработка терм-функций при вычислении. Теперь вложенные терм-функции вычисляются штатно +----------------------------------------------- +04.04.2014 Экстеор 4.0а 1354 +• Исправлена ошибка, приводившая к некорректной работе экспорта в Word при работе с двумя мониторами +• Исправлена ошибка в модуле КМ, приводившая к невозможности использования данных для типизаций вида (X1xX1)xX1 +• Исправлена критическая ошибка, приводившая к сбою программы при открытии диалога редактирования конституенты +• Добавлено автоматическое сохранение документа при нажатии кнопки "Применить" в диалоге редактирования конституенты +----------------------------------------------- +31.01.2014 Экстеор 4.0а 1337 +• Отменено ограничение на длины короткого и длинного имен схемы +• Редизайн диалога редактирования конституенты: добавлено меню +• Добавлена возможность добавления новых конституент из диалога редактировани конституенты +• Добавлено масштабирование ОСС с помощью колеса мыши при зажатом Ctrl +• Комментарий пиктограммы добавлен во всплывающую подсказку в ОСС +----------------------------------------------- +20.01.2014 Экстеор 4.0а 1330 +• Исправлена ошибка при создании документа РС-формы из ОСС, приводившая к необходимости повторно вводить имя РС-формы +• Исправлен ряд опечаток +• Исправлена ошибка при экспорте текста РС-формы в грамматике Тищенко +----------------------------------------------- +10.12.2013 Экстеор 4.0а 1313 +• Переработан шаблон экспорта РС-формы в MS Word +• Добавлена поддержка Копирования / Вставки / Отмены во все текстовые поля +• Переботан механизм пересинтеза: теперь изменения в таблице отождествлений минимально затрагивают протаскиваемые изменения конституент +• Исправлен ряд ошибок в модуле ОСС, приводивших к потере дописанных конституент и интерпретаций при пересинтезе +----------------------------------------------- +03.12.2013 Экстеор 4.0а 1294 +• добавлена поддержка Portable версии +• исправлен ряд ошибок в модуле ОСС +• улучшен интерфейс редактирования конституенты +----------------------------------------------- +25.11.2013 Релиз Экстеор 4.0a +1. Улучшено взаимодействие пользователя с программой. +• Внедрена процедура установки и удаления программы с помощью стандартного установщика Windows. +• В выражениях родов структур используется стандартная кодировка вместо специфического шрифта Boolean (можно копировать текст формального выражения из окна Экстеор 4 в любой другой текстовый редактор). +• Добавлена встроенная справка по нажатию на клавишу F1. +• Во все интерфейсы добавлены контекстные меню, дублирующие часть функций основного меню. +• Переработаны панели инструментов. +• Расширен перечень регулируемых параметров, доступных для подстройки программы под индивидуальные предпочтения каждого пользователя. +• Добавлена возможность написать письмо разработчикам с описанием ошибки. +• Добавлена система версий форматов файлов Экстеор 4, обеспечивающая полную поддержку работы с файлами, сохраненными в предыдущих версиях. +• Устранено множество ошибок и опечаток. +2. Расширены возможности работы с РС-формой КС: +• добавлены атрибуты конституенты комментарий и термин; +• реализовано создание конституент на основе существующих: +• создание терм-функции, +• использование терм-функции для создания термов, +• создание термов, составляющих структуру выражения с заданной типизацией; +• контроль индексации конституент; +• редактирование списка конституент; +• цветовая индикация статусов конституент; +• синтаксический и семантический контроль выражения ЯРС; +• идентификация ошибок в некорректном выражении ЯРС; +• реализовано автоматическое вычисление типизаций конституент; +• осуществляется контроль корректности РС-формы КС. +3. Добавлена возможность работы с концептуальной моделью: +• сохранение и загрузка файла КМ; +• редактирование интерпретации базовых понятий КС; +• вычисление теоретико-множественных интерпретаций термов; +• вычисление значений аксиом и теорем; +• вычисление мощностей множеств, интерпретирующих понятия КС; +• осуществляется контроль корректности КМ. +4. Существенно улучшен интерфейс работы с операционной схемы синтеза: +• переработана система статусов пиктограмм; +• внедрено автоматическое выполнение операций; +• реализовано сквозное внесение изменений в пиктограммы ОСС; +• добавлено сохранение графа ОСС в файл PNG; +• новый набор иконок позволяет четко различать статусы пиктограмм; +• существенно расширены возможности графического интерфейса ОСС: +• добавлена возможность прикрепления гиперссылки к пиктограмме; +• скроллинг в окне графа ОСС; +• иконка наличия связанного с пиктограммой файла; +• выбор активной пиктограммы с помощью клавиш курсора на клавиатуре; +• переработан лог операций ОСС; +• добавлена возможность сохранения лога ОСС в текстовом документе. \ No newline at end of file diff --git a/distr/app/Документация/!Нотация.docx b/distr/app/Документация/!Нотация.docx new file mode 100644 index 0000000..28611eb Binary files /dev/null and b/distr/app/Документация/!Нотация.docx differ diff --git a/distr/app/Документация/README.rtf b/distr/app/Документация/README.rtf new file mode 100644 index 0000000..4e28d31 --- /dev/null +++ b/distr/app/Документация/README.rtf @@ -0,0 +1,362 @@ +{\rtf1\adeflang1025\ansi\ansicpg1251\uc1\adeff0\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1049\deflangfe1049\themelang1049\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\f2\fbidi \fmodern\fcharset204\fprq1{\*\panose 02070309020205020404}Courier New;}{\f3\fbidi \froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}{\f10\fbidi \fnil\fcharset2\fprq2{\*\panose 05000000000000000000}Wingdings;} +{\f34\fbidi \froman\fcharset204\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\flomajor\f31500\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fdbmajor\f31501\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \froman\fcharset204\fprq2{\*\panose 00000000000000000000}Cambria;} +{\fbimajor\f31503\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fdbminor\f31505\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset204\fprq2{\*\panose 020f0502020204030204}Calibri;} +{\fbiminor\f31507\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f46\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\f44\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\f47\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f48\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f49\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f50\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\f51\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f52\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f66\fbidi \fmodern\fcharset0\fprq1 Courier New;}{\f64\fbidi \fmodern\fcharset238\fprq1 Courier New CE;} +{\f67\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f68\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f69\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f70\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);} +{\f71\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f72\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f386\fbidi \froman\fcharset0\fprq2 Cambria Math;}{\f384\fbidi \froman\fcharset238\fprq2 Cambria Math CE;} +{\f387\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f388\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f391\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}{\f392\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);} +{\flomajor\f31510\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31520\fbidi \froman\fcharset0\fprq2 Times New Roman;} +{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31530\fbidi \froman\fcharset0\fprq2 Cambria;}{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;} +{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;}{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;} +{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese);}{\fbimajor\f31540\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} +{\flominor\f31550\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31560\fbidi \froman\fcharset0\fprq2 Times New Roman;} +{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31570\fbidi \fswiss\fcharset0\fprq2 Calibri;}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;} +{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);} +{\fhiminor\f31574\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);} +{\fbiminor\f31580\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;\red96\green94\blue92;\red225\green223\blue221;}{\*\defchp }{\*\defpap \ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{ +\qj \fi425\li0\ri0\sb120\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 \snext0 \sqformat \spriority0 Normal;}{ +\s1\qj \fi425\li0\ri0\sb120\keepn\nowidctlpar\tx240\wrapdefault\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \b\fs22\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 +\sbasedon0 \snext0 \slink15 \sqformat \spriority9 heading 1;}{\*\cs10 \additive \ssemihidden \spriority1 Default Paragraph Font;}{\* +\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv +\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 \snext11 \ssemihidden \sunhideused Normal Table;}{\*\cs15 \additive +\rtlch\fcs1 \ab\af0\afs32 \ltrch\fcs0 \b\fs32\kerning32\loch\f31502\hich\af31502\dbch\af31501 \sbasedon10 \slink1 \slocked \spriority9 \'c7\'e0\'e3\'ee\'eb\'ee\'e2\'ee\'ea 1 \'c7\'ed\'e0\'ea;}{ +\s16\qj \fi567\li0\ri0\sb120\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs22\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 \sbasedon0 \snext16 \slink17 Body Text 2;}{\* +\cs17 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \slink16 \slocked \ssemihidden \'ce\'f1\'ed\'ee\'e2\'ed\'ee\'e9 \'f2\'e5\'ea\'f1\'f2 2 \'c7\'ed\'e0\'ea;}{\*\cs18 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf0 \sbasedon10 Hyperlink;}{ +\s19\ql \li0\ri0\sb100\sa100\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs24\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 \sbasedon0 \snext19 Normal (Web);}{ +\s20\qj \fi425\li0\ri0\sb120\widctlpar\tqc\tx4153\tqr\tx8306\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 +\sbasedon0 \snext20 \slink21 \ssemihidden header;}{\*\cs21 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \slink20 \slocked \ssemihidden \'c2\'e5\'f0\'f5\'ed\'e8\'e9 \'ea\'ee\'eb\'ee\'ed\'f2\'e8\'f2\'f3\'eb \'c7\'ed\'e0\'ea;}{\*\cs22 \additive +\rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \ssemihidden page number;}{\s23\qj \fi425\li0\ri0\sb120\widctlpar\tqc\tx4153\tqr\tx8306\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 +\fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 \sbasedon0 \snext23 \slink24 \ssemihidden footer;}{\*\cs24 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \slink23 \slocked \ssemihidden +\'cd\'e8\'e6\'ed\'e8\'e9 \'ea\'ee\'eb\'ee\'ed\'f2\'e8\'f2\'f3\'eb \'c7\'ed\'e0\'ea;}{\*\cs25 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \cf19\chshdng0\chcfpat0\chcbpat20 \sbasedon10 \ssemihidden \sunhideused \styrsid8206868 Unresolved Mention;}}{\*\listtable +{\list\listtemplateid1549049152\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid68747265\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li1145\lin1145 } +{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid68747267\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li1865\lin1865 }{\listlevel\levelnfc23\levelnfcn23 +\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid68747269\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li2585\lin2585 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0 +\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid68747265\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li3305\lin3305 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative +\levelspace360\levelindent0{\leveltext\leveltemplateid68747267\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li4025\lin4025 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext +\leveltemplateid68747269\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li4745\lin4745 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid68747265 +\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li5465\lin5465 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid68747267\'01o;}{\levelnumbers;}\f2\fbias0 +\fi-360\li6185\lin6185 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace360\levelindent0{\leveltext\leveltemplateid68747269\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li6905\lin6905 } +{\listname ;}\listid8337896}}{\*\listoverridetable{\listoverride\listid8337896\listoverridecount0\ls1}}{\*\pgptbl {\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}{\*\rsidtbl \rsid65690\rsid88900\rsid614011\rsid682434\rsid795446\rsid796894\rsid1066932\rsid1194455 +\rsid1209401\rsid1246336\rsid1258943\rsid1531258\rsid1667611\rsid1842993\rsid1852953\rsid1910866\rsid1917294\rsid2237750\rsid2580806\rsid2715927\rsid2719415\rsid3022656\rsid3099551\rsid3148821\rsid3240529\rsid3700388\rsid3883172\rsid3932480\rsid4005578 +\rsid4201078\rsid4404255\rsid4465316\rsid4599002\rsid4601939\rsid4618004\rsid4945568\rsid5076811\rsid5139095\rsid5207110\rsid5341067\rsid5394278\rsid5639133\rsid6301527\rsid6381161\rsid6515525\rsid6758819\rsid6827480\rsid6906900\rsid7019589\rsid7023896 +\rsid7215318\rsid7503810\rsid7865094\rsid7870292\rsid8206086\rsid8206868\rsid8208739\rsid8351939\rsid8525034\rsid8669217\rsid8674722\rsid8803706\rsid8939224\rsid9131431\rsid9244662\rsid9307041\rsid9450281\rsid9637577\rsid9781973\rsid9965158\rsid10232638 +\rsid10316737\rsid10502241\rsid10503804\rsid10686661\rsid10757963\rsid10831818\rsid11233803\rsid11349481\rsid11472354\rsid11553206\rsid11566552\rsid11933987\rsid12139041\rsid12391614\rsid12405663\rsid12411211\rsid12533947\rsid12725728\rsid12784209 +\rsid12928584\rsid12978005\rsid13261014\rsid13309307\rsid13310419\rsid13334071\rsid13508315\rsid13527126\rsid13575793\rsid13646273\rsid13707144\rsid13774727\rsid13900325\rsid14041924\rsid14234172\rsid14290993\rsid14310684\rsid14420038\rsid14440944 +\rsid14559559\rsid14632231\rsid15032002\rsid15092746\rsid15535730\rsid15671510\rsid15868680\rsid15891779\rsid16007522\rsid16075767\rsid16254696\rsid16257162\rsid16335187\rsid16453070\rsid16470190\rsid16593802}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0 +\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info +{\title \'cb\'c8\'d6\'c5\'cd\'c7\'c8\'ce\'cd\'cd\'ce\'c5 \'d1\'ce\'c3\'cb\'c0\'d8\'c5\'cd\'c8\'c5 \'c0\'cd\'c0\'cb\'c8\'d2\'c8\'d7\'c5\'d1\'ca\'ce\'c3\'ce \'d6\'c5\'cd\'d2\'d0\'c0 "\'ca\'ce\'cd\'d6\'c5\'cf\'d2"} +{\author \'ca\'ee\'ed\'ee\'ed\'e5\'ed\'ea\'ee \'c0\'eb\'e5\'ea\'f1\'e0\'ed\'e4\'f0 \'c0\'ed\'e0\'f2\'ee\'eb\'fc\'e5\'e2\'e8\'f7}{\operator \'c8\'e2\'e0\'ed \'c1\'ee\'f0\'e8\'f1\'ee\'e2}{\creatim\yr2013\mo10\dy22\hr17\min57} +{\revtim\yr2024\mo3\dy31\hr13\min26}{\printim\yr2000\mo2\dy21\hr14\min18}{\version102}{\edmins140}{\nofpages2}{\nofwords524}{\nofchars2989}{\*\company Elcom Ltd}{\nofcharsws3506}{\vern25}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003 +/wordml}}\paperw11907\paperh16840\margl1701\margr3118\margt1134\margb1134\gutter0\ltrsect +\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1\noxlattoyen +\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\lytprtmet\hyphcaps0\formshade\horzdoc\dghspace180\dgvspace180\dghorigin1701\dgvorigin1984\dghshow0\dgvshow0 +\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\bdrrlswsix\nolnhtadjtbl\nojkernpunct\rsidroot10831818 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0{\*\ftnsep \ltrpar \pard\plain \ltrpar +\qj \fi425\li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid11553206 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid13334071 \chftnsep +\par }}{\*\ftnsepc \ltrpar \pard\plain \ltrpar\qj \fi425\li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid11553206 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 { +\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13334071 \chftnsepc +\par }}{\*\aftnsep \ltrpar \pard\plain \ltrpar\qj \fi425\li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid11553206 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 { +\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13334071 \chftnsep +\par }}{\*\aftnsepc \ltrpar \pard\plain \ltrpar\qj \fi425\li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid11553206 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 { +\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13334071 \chftnsepc +\par }}\ltrpar \sectd \ltrsect\psz9\linex0\headery567\footery567\titlepg\sectdefaultcl\sectrsid9781973\sftnbj {\headerl \ltrpar \pard\plain \ltrpar\s20\qj \fi425\li0\ri0\sb120\widctlpar +\tqc\tx4153\tqr\tx8306\pvpara\phmrg\posxr\posy0\wraparound\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\field{\*\fldinst {\rtlch\fcs1 \af0 +\ltrch\fcs0 \cs22\insrsid11553206 PAGE }}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs22\lang1024\langfe1024\noproof\insrsid11553206 2}}}\sectd \ltrsect\linex0\endnhere\sectdefaultcl\sftnbj {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs22\insrsid11553206 +\par }\pard \ltrpar\s20\qj \fi425\li0\ri360\sb120\widctlpar\tqc\tx4153\tqr\tx8306\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin360\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206 +\par }}{\headerr \ltrpar \pard\plain \ltrpar\s20\qj \fi425\li0\ri0\sb120\widctlpar\tqc\tx4153\tqr\tx8306\pvpara\phmrg\posxr\posy0\wraparound\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 +\fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\field{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs22\fs22\insrsid11553206 PAGE }}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs22\fs22\lang1024\langfe1024\noproof\insrsid6906900 2}}}\sectd \ltrsect +\linex0\endnhere\sectdefaultcl\sftnbj {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs22\fs22\insrsid11553206 +\par }\pard \ltrpar\s20\qj \fi425\li0\ri360\sb120\widctlpar\tqc\tx4153\tqr\tx8306\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin360\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206 +\par }}{\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}} +{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8 +\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\s1\qc \li0\ri0\sb120\keepn\nowidctlpar +\tx240\wrapdefault\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0\pararsid10503804 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \b\fs22\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 \fs20\insrsid9637577 +\'cf\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed\'fb\'e9}{\rtlch\fcs1 \af0 \ltrch\fcs0 \fs20\insrsid5139095 \'ea\'ee\'ec\'ef\'eb\'e5\'ea\'f1 \'dd\'ca\'d1\'d2\'c5\'ce\'d0 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \fs20\insrsid4005578 4.}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\fs20\insrsid1852953\charrsid1852953 9}{\rtlch\fcs1 \af0 \ltrch\fcs0 \fs20\insrsid3240529\charrsid1852953 +\par }\pard\plain \ltrpar\qj \fi425\li0\ri0\sb120\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid1917294 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 +\ab\af0 \ltrch\fcs0 \b\insrsid8206868\charrsid8206868 \'d0\'e0\'e7\'f0\'e0\'e1\'ee\'f2\'ea\'e0 \'dd\'ea\'f1\'f2\'e5\'ee\'f0 \'ef\'ee\'e4 }{\rtlch\fcs1 \ab\af0 \ltrch\fcs0 \b\lang1033\langfe1049\langnp1033\insrsid8206868\charrsid8206868 Windows}{ +\rtlch\fcs1 \ab\af0 \ltrch\fcs0 \b\insrsid8206868\charrsid8206868 \'ee\'f1\'f2\'e0\'ed\'ee\'e2\'eb\'e5\'ed\'e0}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1917294\charrsid14290993 . }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid8206868 \'c0\'ea\'f2\'f3\'e0\'eb\'fc +\'ed\'e0\'ff \'e2\'e5\'f0\'f1\'e8\'ff \'f0\'e5\'e4\'e0\'ea\'f2\'ee\'f0\'e0 \'f0\'ee\'e4\'ee\'f1\'f2\'f0\'f3\'ea\'f2\'f3\'f0\'ed\'fb\'f5 \'fd\'ea\'f1\'ef\'eb\'e8\'ea\'e0\'f6\'e8\'e9 \'ee\'f1\'f3\'f9\'e5\'f1\'f2\'e2\'eb\'ff\'e5\'f2\'f1\'ff \'e2 \'f0\'e0\'ec +\'ea\'e0\'f5 \'ef\'f0\'ee\'e5\'ea\'f2\'e0 \'ca\'ee\'ed\'f6\'e5\'ef\'f2\'cf\'ee\'f0\'f2\'e0\'eb: +\par }{\field{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15868680 HYPERLINK "}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15868680\charrsid8206868 https://portal.acconcept.ru/}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15868680 " }}{\fldrslt {\rtlch\fcs1 \af0 +\ltrch\fcs0 \cs18\ul\insrsid15868680\charrsid11151436 https://portal.acconcept.ru/}}}\sectd \ltrsect\psz9\linex0\headery567\footery567\titlepg\sectdefaultcl\sectrsid9781973\sftnbj {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid8206868 +\par }{\field{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15868680 HYPERLINK "}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15868680\charrsid8206868 https://github.com/IRBorisov/ConceptPortal}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15868680 " }}{\fldrslt { +\rtlch\fcs1 \af0 \ltrch\fcs0 \cs18\ul\insrsid15868680\charrsid11151436 https://github.com/IRBorisov/ConceptPortal}}}\sectd \ltrsect\psz9\linex0\headery567\footery567\titlepg\sectdefaultcl\sectrsid9781973\sftnbj {\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid1917294\charrsid14290993 .}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1917294 +\par }\pard\plain \ltrpar\s1\qj \fi425\li0\ri0\sb120\keepn\nowidctlpar\tx240\wrapdefault\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \b\fs22\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 { +\rtlch\fcs1 \af0 \ltrch\fcs0 \fs20\insrsid5139095 \'d2\'e5\'f5\'ed\'e8\'f7\'e5\'f1\'ea\'e8\'e5 \'f2\'f0\'e5\'e1\'ee\'e2\'e0\'ed\'e8\'ff}{\rtlch\fcs1 \af0 \ltrch\fcs0 \fs20\insrsid11553206 +\par }\pard\plain \ltrpar\qj \fi425\li0\ri0\sb120\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid5139095 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 +\ltrch\fcs0 \insrsid5139095 \'d3\'e1\'e5\'e4\'e8\'f2\'e5\'f1\'fc, \'f7\'f2\'ee \'c2\'e0\'f8 \'ea\'ee\'ec\'ef\'fc\'fe\'f2\'e5\'f0 \'f1\'ee\'ee\'f2\'e2\'e5\'f2\'f1\'f2\'e2\'f3\'e5\'f2 \'f1\'eb\'e5\'e4\'f3\'fe\'f9\'e8\'ec \'f2\'f0\'e5\'e1\'ee\'e2\'e0\'ed\'e8 +\'ff\'ec. +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f3\fs20\insrsid6515525 \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \ltrpar +\qj \fi-360\li1145\ri0\sb120\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls1\adjustright\rin0\lin1145\itap0\pararsid6515525 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid6515525 \'cf\'ee\'e4\'e4\'e5\'f0\'e6\'e8\'e2\'e0\'e5\'ec\'fb\'e5 \'ee\'ef\'e5\'f0\'e0\'f6 +\'e8\'ee\'ed\'ed\'fb\'e5}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid6515525\charrsid6515525 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid6515525 \'f1\'e8\'f1\'f2\'e5\'ec\'fb}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid6515525\charrsid6515525 :}{\rtlch\fcs1 \af0 +\ltrch\fcs0 \insrsid4201078 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid6515525 Windows}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid6515525\charrsid6515525 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13309307 10}{\rtlch\fcs1 \af0 +\ltrch\fcs0 \insrsid16254696 64}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid16254696\charrsid16254696 -}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid16254696 bit}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid6515525\charrsid6515525 . +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f3\fs20\lang1033\langfe1049\langnp1033\insrsid12784209 \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \ltrpar +\qj \fi-360\li1145\ri0\sb120\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls1\adjustright\rin0\lin1145\itap0\pararsid12784209 {\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid12784209 Microsoft}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid6515525 Office}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid12784209\charrsid12784209 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid12784209 20}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid16254696 16}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid12784209 +}{\rtlch\fcs1 +\af0 \ltrch\fcs0 \insrsid15891779 .}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5139095 +\par }\pard\plain \ltrpar\s1\qj \fi425\li0\ri0\sb120\keepn\nowidctlpar\tx240\wrapdefault\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0\pararsid16007522 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 +\b\fs22\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 \fs20\insrsid16007522\charrsid16007522 \'c2\'e7\'e0\'e8\'ec\'ee\'e4\'e5\'e9\'f1\'f2\'e2\'e8\'e5 \'f1 \'e4\'f0\'f3\'e3\'e8\'ec\'e8 \'e2\'e5\'f0\'f1\'e8\'ff\'ec\'e8 + +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f3\fs20\insrsid9244662 \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard\plain \ltrpar +\qj \fi-360\li1145\ri0\sb120\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls1\adjustright\rin0\lin1145\itap0\pararsid16007522 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 +\ltrch\fcs0 \insrsid9244662 \'dd\'ea\'f1\'f2\'e5\'ee\'f0}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1852953\charrsid1852953 4.9}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid9244662 \'e0\'e2\'f2\'ee\'ec\'e0\'f2\'e8\'f7\'e5\'f1\'ea\'e8 \'ef\'f0\'e5\'ee\'e1\'f0\'e0 +\'e7\'f3\'e5\'f2 \'e4\'ee\'ea\'f3\'ec\'e5\'ed\'f2\'fb, \'f1\'ee\'f5\'f0\'e0\'ed\'e5\'ed\'ed\'fb\'e5 \'e2 \'e1\'ee\'eb\'e5\'e5 \'f1\'f2\'e0\'f0\'fb\'f5 \'e2\'e5\'f0\'f1\'e8\'ff\'f5 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'fb}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid2580806 .}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13900325 \'d4\'ee\'f0\'ec\'e0\'f2\'fb \'f1\'ee\'f5\'f0\'e0\'ed\'e5}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid14440944 \'ed\'e8\'ff \'e4\'ee\'ea\'f3\'ec\'e5\'ed\'f2\'ee\'e2 \'ec\'e5\'ed\'ff\'fe\'f2\'f1 +\'ff \'e2 \'e8\'f1\'ea\'eb\'fe\'f7\'e8\'f2\'e5\'eb\'fc\'ed\'fb\'f5 \'f1\'eb\'f3\'f7\'e0\'ff\'f5.}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid9244662\charrsid9244662 +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f3\fs20\insrsid16007522 \loch\af3\dbch\af0\hich\f3 \'b7\tab}}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid16007522 \'c5\'f1\'eb\'e8 \'f3 \'c2\'e0\'f1 \'f3\'f1\'f2\'e0\'ed\'ee\'e2\'eb\'e5\'ed\'e0 +\'e2\'e5\'f0\'f1\'e8\'ff \'dd\'ea\'f1\'f2\'e5\'ee\'f0 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid4005578 4.}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid9131431 5}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid16007522 , \'f2\'ee \'ee\'ed\'e0 \'e0\'e2\'f2\'ee\'ec\'e0\'f2\'e8 +\'f7\'e5\'f1\'ea\'e8 \'e4\'e5\'e8\'ed\'f1\'f2\'e0\'eb\'eb\'e8\'f0\'f3\'e5\'f2\'f1\'ff \'ef\'e5\'f0\'e5\'e4 \'f3\'f1\'f2\'e0\'ed\'ee\'e2\'ea\'ee\'e9 \'e4\'e0\'ed\'ed\'ee\'e9 \'e2\'e5\'f0\'f1\'e8\'e5\'e9. +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f3\fs20\insrsid16007522 \loch\af3\dbch\af0\hich\f3 \'b7\tab}\'c5\'f1\'eb\'e8 \'f3 \'c2\'e0\'f1 \'f3\'f1\'f2\'e0\'ed\'ee\'e2\'eb\'e5\'ed\'e0 \'e1\'ee\'eb\'e5\'e5 }{\rtlch\fcs1 \af0 +\ltrch\fcs0 \insrsid10503804\charrsid8206086 \'f1\'f2\'e0\'f0\'e0\'ff}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid16007522 \'e2\'e5\'f0\'f1\'e8\'ff, \'f2\'ee \'ef\'e5\'f0\'e5\'e4 \'f3\'f1\'f2\'e0\'ed\'ee\'e2\'ea\'ee\'e9 \'ed\'e5\'ee\'e1}{\rtlch\fcs1 \af0 +\ltrch\fcs0 \insrsid8206086 \'f5\'ee\'e4\'e8\'ec\'ee \'e4\'e5\'e8\'ed\'f1\'f2\'e0\'eb\'eb\'e8\'f0\'ee\'e2\'e0\'f2\'fc \'dd\'ea\'f1\'f2\'e5\'ee\'f0}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid16007522 \'f7\'e5\'f0\'e5\'e7 \'cf\'e0\'ed\'e5\'eb\'fc \'f3\'ef\'f0 +\'e0\'e2\'eb\'e5\'ed\'e8\'ff.}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid16007522\charrsid12978005 +\par }\pard\plain \ltrpar\s1\qj \fi425\li0\ri0\sb120\keepn\nowidctlpar\tx240\wrapdefault\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0\pararsid12978005 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 +\b\fs22\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 \fs20\insrsid12978005 \'cf\'e5\'f0\'e5\'f7\'e5\'ed\'fc \'f3\'f1\'f2\'e0\'ed\'e0\'e2\'eb\'e8\'e2\'e0\'e5\'ec\'fb\'f5 \'ea\'ee\'ec\'ef\'ee\'ed\'e5\'ed\'f2 +\par }\pard\plain \ltrpar\qj \fi425\li0\ri0\sb120\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid3700388 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 +\ltrch\fcs0 \insrsid3700388 \'cf\'ee\'ec\'e8\'ec\'ee }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1194455 \'e8\'f1\'ef\'ee\'eb\'ed\'ff\'e5\'ec\'fb\'f5 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid3700388 \'f4\'e0\'e9\'eb\'ee\'e2}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid1194455 \'e8 \'e4\'ee\'ea\'f3\'ec\'e5\'ed\'f2\'e0\'f6\'e8\'e8}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid3700388 , \'ed\'e0\'f5\'ee\'e4\'ff\'f9\'e8\'f5\'f1\'ff \'e2 \'ea\'e0\'f2\'e0\'eb\'ee\'e3\'e5 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'fb}{\rtlch\fcs1 +\af0 \ltrch\fcs0 \insrsid4945568 ,}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid3700388 \'ed\'e0 \'c2\'e0\'f8 \'ea\'ee\'ec\'ef\'fc\'fe\'f2\'e5\'f0 \'f3\'f1\'f2\'e0\'ed\'e0\'e2\'eb\'e8\'e2\'e0\'fe\'f2\'f1\'ff \'f1\'eb\'e5\'e4\'f3\'fe\'f9\'e8\'e5 \'ea\'ee\'ec\'ef +\'ee\'ed\'e5\'ed\'f2\'fb.}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid3700388\charrsid3700388 +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f3\fs20\insrsid1066932 \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \ltrpar +\qj \fi-360\li1145\ri0\sb120\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls1\adjustright\rin0\lin1145\itap0\pararsid12978005 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1066932 \'d8\'f0\'e8\'f4\'f2 }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\b\insrsid1066932\charrsid10502241 DejaVu Sans}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1066932 , \'f0\'e0\'f1\'ef}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1209401 \'f0}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1066932 \'ee\'f1\'f2\'f0\'e0\'ed\'ff\'e5\'ec\'fb\'e9 +\'ef\'ee}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15671510 \'f1\'e2\'ee\'e1\'ee\'e4\'ed\'ee\'e9 \'eb\'e8\'f6\'e5\'ed\'e7\'e8\'e8. }{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid15671510\charrsid15671510 Bitstr +eam Vera Fonts Copyright, Arev Fonts Copyright, Public Domain}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid12978005\charrsid15671510 +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f3\fs20\insrsid13575793 \loch\af3\dbch\af0\hich\f3 \'b7\tab}}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13575793 \'c0\'f1\'f1\'ee\'f6\'e8\'e0\'f6\'e8\'ff \'f0\'e0\'f1\'f8\'e8\'f0\'e5\'ed\'e8\'e9 +\'f4\'e0\'e9\'eb\'ee\'e2 TRS, }{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid13575793 RSM}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13575793\charrsid13575793 , }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\lang1033\langfe1049\langnp1033\insrsid13575793 OSS}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13575793\charrsid13575793 \'f1 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ee\'e9 \'dd\'ea\'f1\'f2\'e5\'ee\'f0 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid4005578 4.}{\rtlch\fcs1 +\af0 \ltrch\fcs0 \insrsid5207110\charrsid5207110 9}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13575793\charrsid13575793 (\'ef\'ee\'f1\'f0\'e5\'e4\'f1\'f2\'e2\'ee\'ec \'ec\'ee\'e4\'e8\'f4\'e8\'ea\'e0\'f6\'e8\'e8 \'f1\'e8\'f1\'f2\'e5\'ec\'ed\'ee\'e3\'ee \'f0 +\'e5\'e5\'f1\'f2\'f0\'e0)}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13575793 .}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15671510 +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f3\fs20\insrsid1917294\charrsid1246336 \loch\af3\dbch\af0\hich\f3 \'b7\tab}}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1917294\charrsid1246336 \'c4\'e8\'ed\'e0}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid1246336\charrsid1246336 \'ec\'e8\'f7\'e5\'f1\'ea\'e8 \'ef\'ee\'e4\'ea\'eb\'fe\'f7\'e0\'e5\'ec\'fb\'e5 \'e1\'e8\'e1\'eb\'e8\'ee\'f2\'e5\'ea\'e8}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid8674722\charrsid8674722 , \'ed\'e5\'ee\'e1\'f5\'ee\'e4\'e8\'ec\'fb +\'e5 \'e4\'eb\'ff \'f0\'e0\'e1\'ee\'f2\'fb \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'fb}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1246336 :}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1246336\charrsid1246336 }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\lang1033\langfe1049\langnp1033\insrsid1246336 Visual}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1246336\charrsid1246336 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid1246336 C}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid1246336\charrsid1246336 ++ 1}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2237750\charrsid2237750 4}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1246336\charrsid1246336 .0 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid1246336 MFC}{ +\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1246336\charrsid1246336 (}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid1246336 x}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1246336\charrsid1246336 86), }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\lang1033\langfe1049\langnp1033\insrsid1246336 Visual}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1246336\charrsid1246336 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid1246336 C}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid1246336\charrsid1246336 ++ 1}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2237750\charrsid2237750 4}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1246336\charrsid1246336 .0 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid1246336 CRT}{ +\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1246336\charrsid1246336 (}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid1246336 x}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1246336\charrsid1246336 86)}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1246336 + \'f0\'e0\'f1\'ef\'f0\'ee\'f1\'f2\'f0\'e0\'ed\'ff\'e5\'ec\'fb\'e5 \'f1\'ee\'e3\'eb\'e0\'f1\'ed\'ee }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1246336\charrsid1246336 Microsoft Software License Terms}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid1246336\charrsid8674722 .}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1917294 +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f3\fs20\insrsid7019589 \loch\af3\dbch\af0\hich\f3 \'b7\tab}}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid7019589 \'d8\'e0\'e1\'eb\'ee\'ed \'e4\'ee\'ea\'f3\'ec\'e5\'ed\'f2\'e0 M}{\rtlch\fcs1 \af0 +\ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid7019589 icrosoft}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid7019589 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11233803 Word}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13707144\charrsid1842993 , \'ef\'f0\'e5\'e4\'ed +\'e0\'e7\'ed\'e0\'f7\'e5\'ed\'ed\'fb\'e9}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11233803 \'e4\'eb\'ff \'fd\'ea\'f1\'ef\'ee\'f0\'f2\'e0 \'d0\'d1-\'f4\'ee\'f0\'ec \'e2 \'f2\'e5\'ea\'f1\'f2\'ee\'e2\'fb\'e9 \'f4\'ee\'f0\'ec\'e0\'f2. \'d8\'e0\'e1\'eb\'ee\'ed +\'f0\'e0\'f1\'ef\'ee\'eb\'ee\'e6\'e5\'ed \'ef\'ee\'e4\'ea\'e0\'f2\'e0\'eb\'ee\'e3\'e5 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid7870292 \'ab}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11233803 \'d8\'e0\'e1\'eb\'ee\'ed\'fb}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid7870292 \'bb}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11233803 \'e2\'ed\'f3\'f2\'f0\'e8 \'ea\'e0\'f2\'e0\'eb\'ee\'e3\'e0 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'fb. +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f3\fs20\insrsid13309307 \loch\af3\dbch\af0\hich\f3 \'b7\tab}}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13309307 \'d8\'e0\'e1\'eb\'ee\'ed \'e4\'ee\'ea\'f3\'ec\'e5\'ed\'f2\'e0 M}{\rtlch\fcs1 \af0 +\ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid13309307 icrosoft}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13309307 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid13309307 Excel}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid13309307\charrsid1842993 , \'ef\'f0\'e5\'e4\'ed\'e0\'e7\'ed\'e0\'f7\'e5\'ed\'ed\'fb\'e9}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13309307 \'e4\'eb\'ff \'fd\'ea\'f1\'ef\'ee\'f0\'f2\'e0 \'ea\'ee\'ed\'f6\'e5\'ef\'f2\'f3\'e0\'eb\'fc\'ed\'fb\'f5 \'ec\'ee +\'e4\'e5\'eb\'e5\'e9. \'d8\'e0\'e1\'eb\'ee\'ed \'f0\'e0\'f1\'ef\'ee\'eb\'ee\'e6\'e5\'ed \'ef\'ee\'e4\'ea\'e0\'f2\'e0\'eb\'ee\'e3\'e5 \'ab\'d8\'e0\'e1\'eb\'ee\'ed\'fb\'bb \'e2\'ed\'f3\'f2\'f0\'e8 \'ea\'e0\'f2\'e0\'eb\'ee\'e3\'e0 \'ef\'f0\'ee\'e3\'f0\'e0 +\'ec\'ec\'fb. +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f3\fs20\insrsid2237750 \loch\af3\dbch\af0\hich\f3 \'b7\tab}}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2237750 \'c8\'ed\'f2\'e5\'f0}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2237750\charrsid2237750 +\'ef\'f0\'e5\'f2\'e0\'f2\'ee\'f0 \'ff\'e7\'fb\'ea\'e0 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid2237750 Python}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2237750\charrsid2237750 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid14290993 3}{ +\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid16254696\charrsid16254696 64-}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid16254696 bit}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2237750 \'e4\'eb\'ff \'f0\'e0\'e1\'ee\'f2\'fb \'eb\'e5\'ea\'f1\'e8 +\'f7\'e5\'f1\'ea\'ee\'e3\'ee \'ec\'ee\'e4\'f3\'eb\'ff, \'f0\'e0\'f1\'ef\'f0\'ee\'f1\'f2\'f0\'e0\'ed\'ff\'e5\'ec\'fb\'e9 \'f1\'ee\'e3\'eb\'e0\'f1\'ed\'ee }{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid2237750 Python}{\rtlch\fcs1 +\af0 \ltrch\fcs0 \insrsid2237750\charrsid2237750 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid2237750 Software}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2237750\charrsid2237750 }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\lang1033\langfe1049\langnp1033\insrsid2237750 Foundation}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2237750\charrsid2237750 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid2237750 License}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid2237750\charrsid2237750 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid2237750 Agreement}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2237750\charrsid2237750 .}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid2237750\charrsid13575793 +\par }\pard\plain \ltrpar\s1\qj \fi425\li0\ri0\sb120\keepn\nowidctlpar\tx240\wrapdefault\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0\pararsid12928584 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 +\b\fs22\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 \fs20\insrsid11933987 \'c8\'ed\'f4\'ee\'f0\'ec\'e0\'f6\'e8\'ee\'ed\'ed\'ee\'e5 \'f1\'ee\'ef\'f0\'ee\'e2\'ee\'e6\'e4\'e5\'ed\'e8\'e5}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\fs20\insrsid12928584 +\par }\pard\plain \ltrpar\qj \fi425\li0\ri0\sb120\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid11933987 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 +\ltrch\fcs0 \insrsid11933987 \'cf\'e5\'f0\'e5\'e4 \'f0\'e0\'e1\'ee\'f2\'ee\'e9 \'f1 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ee\'e9 \'ee\'e7\'ed\'e0\'ea\'ee\'ec\'fc\'f2\'e5\'f1\'fc \'f1 \'ef\'f0\'e5\'e4\'ee\'f1\'f2\'e0\'e2\'eb\'ff\'e5\'ec\'fb\'ec\'e8 \'e8\'ed +\'f4\'ee\'f0\'ec\'e0\'f6\'e8\'ee\'ed\'ed\'fb\'ec\'e8 \'ec\'e0\'f2\'e5\'f0\'e8\'e0\'eb\'e0\'ec\'e8, \'ef\'f0\'e8\'e7\'e2\'e0\'ed\'ed\'fb\'ec\'e8 \'ee\'f2\'e2\'e5\'f2\'e8\'f2\'fc \'ed\'e0 \'c2\'e0\'f8\'e8 \'e2\'ee\'ef\'f0\'ee\'f1\'fb.}{\rtlch\fcs1 \af0 +\ltrch\fcs0 \insrsid8208739 \'c2\'f1\'e5 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid6827480 \'ed\'e8\'e6\'e5\'ef\'e5\'f0\'e5\'f7\'e8\'f1\'eb\'e5\'ed\'ed\'fb\'e5}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid8208739 \'f4\'e0\'e9\'eb\'fb \'ed\'e0\'f5\'ee\'e4\'ff\'f2 +\'f1\'ff \'e2 \'e4\'e8\'f0\'e5\'ea\'f2\'ee\'f0\'e8\'e8 \'f3\'f1\'f2\'e0\'ed\'ee\'e2\'ea\'e8 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'fb.}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11933987 +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f3\fs20\insrsid15032002 \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \ltrpar +\qj \fi-360\li1145\ri0\sb120\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls1\adjustright\rin0\lin1145\itap0\pararsid11933987 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15032002 Help.chm \endash \'ee\'f1\'ed\'ee\'e2\'ed\'ee\'e9 \'f4\'e0\'e9\'eb \'f1\'ef\'f0 +\'e0\'e2\'ea\'e8 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'fb}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15032002\charrsid15032002 . }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15032002 \'c4\'ee\'f1\'f2\'f3\'ef\'ed\'e0 \'ea\'ee\'ed\'f2\'e5\'ea\'f1\'f2\'ed\'e0\'ff \'f1\'ef +\'f0\'e0\'e2\'ea\'e0 \'e4\'eb\'ff \'ee\'f1\'ed\'ee\'e2\'ed\'fb\'f5 \'e4\'e8\'e0\'eb\'ee\'e3\'ee\'e2 \'e8 \'f4\'ee\'f0\'ec \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'fb \'ef\'ee \'ed\'e0\'e6\'e0\'f2\'e8\'fe F1.}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11933987 +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f3\fs20\insrsid15032002 \loch\af3\dbch\af0\hich\f3 \'b7\tab}}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15032002 \'c4\'ee\'ea\'f3\'ec\'e5\'ed\'f2\'e0\'f6\'e8\'ff}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid15032002\charrsid12978005 \\}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15032002 !\'cd\'ee\'f2\'e0\'f6\'e8\'ff.doc}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid12391614 x}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid15032002 \endash \'e4\'e0\'ed\'ed\'fb\'e9 \'f4 +\'e0\'e9\'eb \'f1\'ee\'e4\'e5\'f0\'e6\'e8\'f2 \'f2\'e0\'e1\'eb\'e8\'f6\'f3 \'f1\'ee\'ee\'f2\'e2\'e5\'f2\'f1\'f2\'e2\'e8\'ff \'f1\'e8\'ec\'e2\'ee\'eb\'ee\'e2 \'ff\'e7\'fb\'ea\'e0 \'f0\'ee\'e4\'ee\'e2 \'f1\'f2\'f0\'f3\'ea\'f2\'f3\'f0 \'e8 \'f1\'ee\'f7\'e5 +\'f2\'e0\'ed\'e8\'e9 \'ea\'eb\'e0\'e2\'e8\'f8, \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'f3\'e5\'ec\'fb\'f5 \'e4\'eb\'ff \'e8\'f5 \'ed\'e0\'e1\'ee\'f0\'e0 \'e2 \'f0\'e5\'e4\'e0\'ea\'f2\'ee\'f0\'e5 \'e2\'fb\'f0\'e0\'e6\'e5\'ed\'e8\'e9 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec +\'fb. +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f3\fs20\insrsid1842993 \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \ltrpar +\qj \fi-360\li1145\ri0\sb120\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls1\adjustright\rin0\lin1145\itap0\pararsid14234172 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1842993 \'ca\'e0\'f2\'e0\'eb\'ee\'e3 \'cf\'f0\'e8\'ec\'e5\'f0\'fb \'f1\'ee\'e4\'e5\'f0\'e6 +\'e8\'f2 \'ed\'e0\'e1\'ee\'f0 \'e4\'ee\'ea\'f3\'ec\'e5\'ed\'f2\'ee\'e2, \'e8\'eb\'eb\'fe\'f1\'f2\'f0\'e8\'f0\'f3\'fe\'f9\'e8\'f5 \'f0\'e0\'e1\'ee\'f2\'f3 \'ee\'f1\'ed\'ee\'e2\'ed\'fb\'f5 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed\'fb\'f5 \'ec\'ee\'e4\'f3\'eb +\'e5\'e9 \'dd\'ea\'f1\'f2\'e5\'ee\'f0 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid4005578 4.}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1852953\charrsid1852953 9}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1842993 .}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid14234172\charrsid11933987 +\par }\pard\plain \ltrpar\s1\qj \fi425\li0\ri0\sb120\keepn\nowidctlpar\tx240\wrapdefault\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0\pararsid12928584 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 +\b\fs22\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 \fs20\insrsid12928584\charrsid12928584 \'ce\'e1\'f0\'e0\'f2\'ed\'e0\'ff \'f1\'e2\'ff\'e7\'fc}{\rtlch\fcs1 \af0 \ltrch\fcs0 \fs20\insrsid4404255\charrsid12928584 + +\par }\pard\plain \ltrpar\qj \fi425\li0\ri0\sb120\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid12928584 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 +\ltrch\fcs0 \insrsid12928584 \'c2\'cd\'c8\'cc\'c0\'cd\'c8\'c5! \'ca\'e0\'e6\'e4\'fb\'e9 \'ef\'ee\'eb\'fc\'e7\'ee\'e2\'e0\'f2\'e5\'eb\'fc \'dd\'ea\'f1\'f2\'e5\'ee\'f0 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid4005578 4.}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid1852953\charrsid1852953 9}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid12928584 \'ef\'f0\'e8\'e7\'e2\'e0\'ed \'e1\'fb\'f2\'fc \'e5\'e3\'ee \'e1\'e5\'f2\'e0-\'f2\'e5\'f1\'f2\'e5\'f0\'ee\'ec! \'cf\'f0\'e8 \'ee\'e1\'ed\'e0\'f0\'f3\'e6\'e5\'ed\'e8\'e8 \'ee +\'f8\'e8\'e1\'ee\'ea \'e2 \'f0\'e0\'e1\'ee\'f2\'e5 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'fb \'e8\'eb\'e8 \'ef\'f0\'e8 \'ef\'ee\'ff\'e2\'eb\'e5\'ed\'e8\'e8 \'ef\'ee\'e6\'e5\'eb\'e0\'ed\'e8\'e9}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\lang1033\langfe1049\langnp1033\insrsid6827480 \~}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid12928584 /}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid6827480 \~}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid12928584 \'ef\'f0\'e5\'e4\'eb\'ee\'e6 +\'e5\'ed\'e8\'e9 \'f1\'eb\'e5\'e4\'f3\'e5\'f2 \'ee\'f2\'ef\'f0\'e0\'e2\'eb\'ff\'f2\'fc \'e8\'f5}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid14632231 \'ed\'e0}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid12928584 \'fd\'eb\'e5\'ea\'f2\'f0\'ee\'ed\'ed\'fb\'e9 \'ff\'f9 +\'e8\'ea }{\field{\*\fldinst {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid12928584 HYPERLINK "mailto:bugreport@acconcept.ru" }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid9450281 {\*\datafield +00d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b540000006d00610069006c0074006f003a006200750067007200650070006f007200740040006100630063006f006e0063006500700074002e00720075000000795881f43b1d7f48af2c825dc485276300000000a5ab +000000000000c2000070a7ff3900}}}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs18\ul\insrsid12928584\charrsid9307041 bugreport@acconcept.ru}}}\sectd \ltrsect\psz9\linex0\headery567\footery567\titlepg\sectdefaultcl\sectrsid9781973\sftnbj {\rtlch\fcs1 \af0 +\ltrch\fcs0 \insrsid12928584 . \'c4\'eb\'ff \'c2\'e0\'f8\'e5\'e3\'ee \'f3\'e4\'ee\'e1\'f1\'f2\'e2\'e0 \'e2 \'dd\'ea\'f1\'f2\'e5\'ee\'f0 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid4005578 4.}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1852953\charrsid1852953 9}{ +\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid12928584 \'e2\'f1\'f2\'f0\'ee\'e5\'ed\'e0 \'f1\'ef\'e5\'f6\'e8\'e0\'eb\'fc\'ed\'e0\'ff \'ea\'ed\'ee\'ef\'ea\'e0 \'ab\'d1\'ee\'ee\'e1\'f9\'e8\'f2\'fc \'ee\'e1 \'ee\'f8\'e8\'e1\'ea\'e5\'bb (\'ea\'f0\'e0\'f1\'ed\'fb\'e9 +\'e6\'f3\'f7\'ee\'ea \'ed\'e0 \'ee\'f1\'ed\'ee\'e2\'ed\'ee\'e9 \'ef\'e0\'ed\'e5\'eb\'e8).}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid12928584\charrsid16007522 +\par }\pard \ltrpar\ql \fi425\li0\ri0\sb120\widctlpar\tx1908\tx9602\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid3099551 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid3099551 \'cf\'ee\'e6\'e0\'eb\'f3\'e9\'f1\'f2\'e0, \'f3\'ea\'e0\'e7\'fb\'e2 +\'e0\'e9\'f2\'e5 \'f1\'eb\'e5\'e4\'f3\'fe\'f9\'f3\'fe \'e8\'ed\'f4\'ee\'f0\'ec\'e0\'f6\'e8\'fe: +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f3\fs20\insrsid3099551 \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \ltrpar +\qj \fi-360\li1145\ri0\sb120\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls1\adjustright\rin0\lin1145\itap0\pararsid3099551 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid3099551 \'e2\'e5\'f0\'f1\'e8\'ff \'dd\'ea\'f1\'f2\'e5\'ee\'f0 (\'f3\'ea\'e0\'e7\'e0\'ed \'e2 + \'e4\'e8\'e0\'eb\'ee\'e3\'e5 \'ab\'ce \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'e5\'bb); +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f3\fs20\insrsid3099551 \loch\af3\dbch\af0\hich\f3 \'b7\tab}\'ee\'ef\'e5\'f0\'e0\'f6\'e8\'ee\'ed\'ed\'e0\'ff \'f1\'e8\'f1\'f2\'e5\'ec\'e0}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\lang1033\langfe1049\langnp1033\insrsid3099551 ;}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid3099551 +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f3\fs20\insrsid3099551 \loch\af3\dbch\af0\hich\f3 \'b7\tab}\'e2\'e5\'f0\'f1\'e8\'ff Microsoft Office}{\rtlch\fcs1 \af0 \ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid3099551 ;}{ +\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid3099551 +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f3\fs20\insrsid3099551 \loch\af3\dbch\af0\hich\f3 \'b7\tab}\'ee\'ef\'e8\'f1\'e0\'ed\'e8\'e5 \'e2\'ee\'e7\'ed\'e8\'ea\'e0\'fe\'f9\'e5\'e9 \'ee\'f8\'e8\'e1\'ea\'e8}{\rtlch\fcs1 \af0 +\ltrch\fcs0 \lang1033\langfe1049\langnp1033\insrsid3099551 ;}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid3099551 +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f3\fs20\insrsid3099551 \loch\af3\dbch\af0\hich\f3 \'b7\tab}\'ee\'ef\'e8\'f1\'e0\'ed\'e8\'e5 \'ef\'ee\'f1\'eb\'e5\'e4\'ee\'e2\'e0\'f2\'e5\'eb\'fc\'ed\'ee\'f1\'f2\'e8 \'e4\'e5\'e9\'f1\'f2\'e2 +\'e8\'e9, }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid3099551\charrsid4599002 \'ef\'f0\'e5\'e4\'f8\'e5\'f1\'f2\'e2\'f3\'fe\'f9\'e8\'f5 \'e2\'ee\'e7\'ed\'e8\'ea\'ed\'ee\'e2\'e5\'ed\'e8\'fe \'ee\'f8\'e8\'e1\'ea\'e8;}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid3099551 + +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \f3\fs20\insrsid3099551 \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \ltrpar +\qj \fi-360\li1145\ri0\sb120\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls1\adjustright\rin0\lin1145\itap0\pararsid16470190 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid3099551 \'ef\'f0\'e8\'eb\'ee\'e6\'e8\'f2\'e5 \'e8\'f1\'f5\'ee\'e4\'ed\'fb\'e5 \'f4\'e0\'e9 +\'eb\'fb *.RSM, *.TRS \'e8 *.OSS, \'ef\'f0\'e8 \'f0\'e0\'e1\'ee\'f2\'e5 \'f1 \'ea\'ee\'f2\'ee\'f0\'fb\'ec\'e8 \'e2\'ee\'e7\'ed\'e8\'ea\'e0\'e5\'f2 \'ee\'f8\'e8\'e1\'ea\'e0}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid4599002\charrsid795446 .}{\rtlch\fcs1 \af0 +\ltrch\fcs0 \insrsid795446\charrsid16470190 +\par }\pard \ltrpar\ql \li0\ri0\sb120\widctlpar\tx1908\tx9602\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid795446 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid795446\charrsid12978005 +----------------------------------------------------------------------------------------------------------}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid3099551\charrsid12978005 +\par }\pard \ltrpar\ql \fi425\li0\ri0\widctlpar\tx1418\tx9602\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid13309307 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13309307\charrsid9781973 E-mail:\tab post@}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\lang1033\langfe1049\langnp1033\insrsid13309307\charrsid9781973 ac}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13309307\charrsid9781973 concept.ru +\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a +9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad +5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6 +b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0 +0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6 +a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f +c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512 +0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462 +a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865 +6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b +4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b +4757e8d3f729e245eb2b260a0238fd010000ffff0300504b030414000600080000002100a0bc18c6b5060000831b0000160000007468656d652f7468656d652f +7468656d65312e786d6cec59cf6e1b4518bf23f10ea3bdb7b1133b8da33855ecd80db469a3d82dea71bc1eef4e33bbb39a1927f5ad4a8f482044411ca8045c38 +2020528bb8b4efe03e43a0088ad457e09b995d7b27de90a48da082e6107b677fdfff3ff3cd78e5f2dd88a15d2224e571dd2b5f2c7988c43eefd338a87b37bbed +0b4b1e920ac77dcc784ceade8848eff2eabbeface06515928820a08fe532ae7ba152c9f2dc9cf46119cb8b3c2131bc1b701161058f2298eb0bbc077c2336375f +2a2dce4598c61e8a71046cc7df8c7f1a3f191fa01b8301f589b79af16f3110122ba9177c263a9a3bc988be7eb63f3e183f1d3f1e1f3cbb07df9fc2e7c786b6bf +53d61472249b4ca05dccea1e88eef3bd2eb9ab3cc4b054f0a2ee95cc9f37b7ba3287975322a68ea1cdd1b5cd5f4a9712f477e68d4c11f42642cbed4aedd2fa84 +bf0130358b6bb55acd5679c2cf00b0ef83e556973ccf4a7ba9dcc878e640f6eb2cef66a95aaab8f81cff85199d6b8d46a35a4b75b14c0dc87eadcce0974a8b95 +b579076f40165f9dc1571a6bcde6a28337208b5f9cc1b72fd5162b2ede804246e39d19b40e68bb9d729f40069c6d14c29700be544ae1531464c324dbb488018f +d569732fc277b8680381266458d118a9514206d887446fe2a82728d602f132c1b93776c997334b5a3692bea089aa7bef27188a66caefe593ef5f3e79840ef71f +1feeff7c78fffee1fe8f969143b581e3204ff5e2db4ffe7c780ffdf1e8ab170f3e2bc6cb3cfed71f3efce5e9a7c54028a7a93acf3f3ff8edf1c1f32f3efafdbb +0705f035817b7978974644a2eb640f6df3080c335e7135273d71368a6e88699e622d0e248eb19652c0bfa542077d7d84591a1d478f06713d784b403b29025e19 +de7114ee8462a86881e4ab61e4003739670d2e0abd7055cbcab9b93b8c8362e16298c76d63bc5b24bb896327bead61027d354b4bc7f066481c35b7188e150e48 +4c14d2eff80e2105d6dda6d4f1eb26f505977ca0d06d8a1a9816baa44b7b4e364d89366804711915d90cf1767cb3790b35382bb27a9decba48a80acc0a94ef12 +e6b8f10a1e2a1c15b1ece288e51d7e0dabb048c9ce48f8795c4b2a8874401847ad3e91b288e686007b7341bf8aa18315867d938d22172914dd29e2790d739e47 +aef39d6688a3a408dba17198c7be2777204531dae2aa08bec9dd0ad1cf10071c1f1bee5b9438e13eb91bdca481a3d23441f49ba1d0b184d6ed74e088c67fd78e +19857e6c73e0fcda3134c0e75f3e2cc8ac37b511afc19e5454091b47daef71b8a34db7c9459fbef93d771d0fe32d02693ebbf1bc6db96f5baef79f6fb9c7d5f3 +691bedb4b742dbd573831d92cdc81c9d7a621e50c63a6ac4c83569866609fb46bf0d8b9a8f395092c9892a09e16bdae71d5c20b0a14182ab0fa80a3b214e60e0 +2e7b9a492053d68144099770f033cb85bc351e8676658f8d557da0b0fd4162b5c9fb7679412f67e786091bb3fb04e6b09a095ad00c4e2b6ce152ca14cc7e1561 +65add4a9a5958d6aa6f539d22626434c674d83c5893761204130c6809717e148af45c3410533d2d77eb77b7116161385f30c910c719fa431d276cfc6a86c8294 +e58ab93980dc2988913e049ee0b59cb49a66fb1ad24e13a4bcb8ca31e2b2e8bd4e94b20c9e4649d7f191726471be38598cf6ea5ead3a5ff5908f93ba3780332e +7c8d1288bad433206601dc25f94ad8b43fb1984d954fa359cb0c738ba00cd718d6ef33063b7d201152ad6319dad430afd21460b19664f59faf825bcfcb009be9 +afa0c5c21224c3bfa605f8d10d2d190c88aff2c1cead68dfd9c7b495f2a122a213f6f7508f0dc53686f0eb54057bfa54c25585e908fa01eed9b4b7cd2bb739a7 +4597bfdd3238bb8e5912e2b4ddea12cd2ad9c24d1d4f74304f39f5c0b642dd8d716737c594fc3999924fe3ff99297a3f819b8385be8e800f37bf02235daf758f +0b1572e8424948fdb68041c2f40ec816b8ab85d7905470ff6c3e05d9d59fb6e62c0f53d6700054db344082c27ea44241c816b425937d27302ba77b9765c95246 +26a372eacac4aadd23bb8475750f5cd47bbb87424875d34dd236607047f3cf7d4e2ba817e821275f6f4e0f99ecbdb606fee9c9c7163318e5f66133d064fe9fa8 +58b0ab5a7a439eedbd7943f48be99855c9aa0284e5b6825a5af6afa8c219b75adbb1662c9eaf66ca4114672d86c5c94094c0fd0fd2ff60ffa3c267f6970cbda1 +76f936f456043f446866903690d517ece0817483b48b3d189ceca24d26cdcaba361d9db4d7b2cdfa9c27dd89dc23ced69a9d26de6774f6643873c539b5789ece +4e3decf8daae1deb6a88ecd11285a54176b0318131bf82e57fa5e2bd3b10e875b8ef1f32254d32c16f4e02c3e8d9317500c56f251ad2d5bf000000ffff030050 +4b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e +72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae9 +95719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757d +a0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d9850528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d00 +14000600080000002100e9de0fbfff0000001c0200001300000000000000000000000000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d +0014000600080000002100a5d6a7e7c0000000360100000b00000000000000000000000000300100005f72656c732f2e72656c73504b01022d00140006000800 +000021006b799616830000008a0000001c00000000000000000000000000190200007468656d652f7468656d652f7468656d654d616e616765722e786d6c504b +01022d0014000600080000002100a0bc18c6b5060000831b00001600000000000000000000000000d60200007468656d652f7468656d652f7468656d65312e78 +6d6c504b01022d00140006000800000021000dd1909fb60000001b0100002700000000000000000000000000bf0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000ba0a00000000} +{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d +617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 +6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 +656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} +{\*\latentstyles\lsdstimax376\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1; +\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; +\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7; +\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 1; +\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 2;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 3;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 4; +\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 5;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 6;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 7; +\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 8;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority35 \lsdlocked0 caption; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 5;\lsdqformat1 \lsdpriority10 \lsdlocked0 Title; +\lsdsemihidden1 \lsdunhideused1 \lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Salutation;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Date; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent;\lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdpriority59 \lsdlocked0 Table Grid;\lsdsemihidden1 \lsdlocked0 Placeholder Text; +\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2; +\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List; +\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;\lsdpriority61 \lsdlocked0 Light List Accent 1; +\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdsemihidden1 \lsdlocked0 Revision; +\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1; +\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;\lsdpriority72 \lsdlocked0 Colorful List Accent 1; +\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; +\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2; +\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2; +\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; +\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3; +\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4; +\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; +\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4; +\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;\lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5; +\lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; +\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5; +\lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6; +\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6; +\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6; +\lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; +\lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography; +\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4; +\lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4; +\lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1; +\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1; +\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2; +\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2; +\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3; +\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4; +\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4; +\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5; +\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5; +\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6; +\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6; +\lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark; +\lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1; +\lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1; +\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2; +\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3; +\lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3; +\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4; +\lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4; +\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5; +\lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5; +\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6; +\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Mention; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link;}}{\*\datastore 01050000 +02000000180000004d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000 +d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e5000000000000000000000000a0b0 +d2e55583da01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/distr/app/Документация/Лицензионное соглашение.rtf b/distr/app/Документация/Лицензионное соглашение.rtf new file mode 100644 index 0000000..8ecb8e4 --- /dev/null +++ b/distr/app/Документация/Лицензионное соглашение.rtf @@ -0,0 +1,335 @@ +{\rtf1\adeflang1025\ansi\ansicpg1251\uc1\adeff0\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1049\deflangfe1049\themelang1049\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f3\fbidi \froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;} +{\f34\fbidi \froman\fcharset204\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\flomajor\f31500\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fdbmajor\f31501\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \froman\fcharset204\fprq2{\*\panose 00000000000000000000}Cambria;} +{\fbimajor\f31503\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fdbminor\f31505\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset204\fprq2{\*\panose 020f0502020204030204}Calibri;} +{\fbiminor\f31507\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f46\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\f44\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\f47\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f48\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f49\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f50\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\f51\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f52\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f386\fbidi \froman\fcharset0\fprq2 Cambria Math;}{\f384\fbidi \froman\fcharset238\fprq2 Cambria Math CE;} +{\f387\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f388\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f391\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}{\f392\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);} +{\flomajor\f31510\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31520\fbidi \froman\fcharset0\fprq2 Times New Roman;} +{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31530\fbidi \froman\fcharset0\fprq2 Cambria;}{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;} +{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;}{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;} +{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese);}{\fbimajor\f31540\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} +{\flominor\f31550\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31560\fbidi \froman\fcharset0\fprq2 Times New Roman;} +{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31570\fbidi \fswiss\fcharset0\fprq2 Calibri;}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;} +{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);} +{\fhiminor\f31574\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);} +{\fbiminor\f31580\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;}{\*\defchp }{\*\defpap \ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{ +\qj \fi425\li0\ri0\sb120\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 \snext0 \sqformat \spriority0 Normal;}{ +\s1\qj \fi425\li0\ri0\sb120\keepn\nowidctlpar\tx240\wrapdefault\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \b\fs22\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 +\sbasedon0 \snext0 \slink15 \sqformat \spriority9 heading 1;}{\*\cs10 \additive \ssemihidden \spriority1 Default Paragraph Font;}{\* +\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv +\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 \snext11 \ssemihidden \sunhideused Normal Table;}{\*\cs15 \additive +\rtlch\fcs1 \ab\af0\afs32 \ltrch\fcs0 \b\fs32\kerning32\loch\f31502\hich\af31502\dbch\af31501 \sbasedon10 \slink1 \slocked \spriority9 \'c7\'e0\'e3\'ee\'eb\'ee\'e2\'ee\'ea 1 \'c7\'ed\'e0\'ea;}{ +\s16\qj \fi567\li0\ri0\sb120\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs22\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 \sbasedon0 \snext16 \slink17 Body Text 2;}{\* +\cs17 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \slink16 \slocked \ssemihidden \'ce\'f1\'ed\'ee\'e2\'ed\'ee\'e9 \'f2\'e5\'ea\'f1\'f2 2 \'c7\'ed\'e0\'ea;}{\*\cs18 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf0 \sbasedon10 Hyperlink;}{ +\s19\ql \li0\ri0\sb100\sa100\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs24\cf1\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 \sbasedon0 \snext19 Normal (Web);}{ +\s20\qj \fi425\li0\ri0\sb120\widctlpar\tqc\tx4153\tqr\tx8306\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 +\sbasedon0 \snext20 \slink21 \ssemihidden header;}{\*\cs21 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \slink20 \slocked \ssemihidden \'c2\'e5\'f0\'f5\'ed\'e8\'e9 \'ea\'ee\'eb\'ee\'ed\'f2\'e8\'f2\'f3\'eb \'c7\'ed\'e0\'ea;}{\*\cs22 \additive +\rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \ssemihidden page number;}{\s23\qj \fi425\li0\ri0\sb120\widctlpar\tqc\tx4153\tqr\tx8306\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 +\fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 \sbasedon0 \snext23 \slink24 \ssemihidden footer;}{\*\cs24 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \slink23 \slocked \ssemihidden +\'cd\'e8\'e6\'ed\'e8\'e9 \'ea\'ee\'eb\'ee\'ed\'f2\'e8\'f2\'f3\'eb \'c7\'ed\'e0\'ea;}}{\*\pgptbl {\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}{\*\rsidtbl \rsid88900\rsid335403\rsid398448\rsid614011\rsid853259\rsid1014178\rsid1258943\rsid2719415\rsid3240529 +\rsid3295549\rsid3500467\rsid3695137\rsid3697883\rsid3894889\rsid4601939\rsid4618710\rsid4663543\rsid5076811\rsid5123328\rsid5394278\rsid5639133\rsid6381161\rsid6780506\rsid7019855\rsid7023896\rsid7030330\rsid7215318\rsid7221176\rsid7817483\rsid7865094 +\rsid8068798\rsid8350254\rsid8351939\rsid8411065\rsid8939224\rsid9578463\rsid9781973\rsid10316737\rsid10575972\rsid10750365\rsid10757963\rsid10831818\rsid10880150\rsid11083833\rsid11155375\rsid11359257\rsid11472354\rsid11553206\rsid12198165\rsid12405663 +\rsid12725728\rsid13261014\rsid13310419\rsid13569699\rsid13646273\rsid13774727\rsid14310684\rsid14578367\rsid16075767\rsid16141059\rsid16257162\rsid16335187\rsid16453070\rsid16465764}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1 +\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info +{\title \'cb\'c8\'d6\'c5\'cd\'c7\'c8\'ce\'cd\'cd\'ce\'c5 \'d1\'ce\'c3\'cb\'c0\'d8\'c5\'cd\'c8\'c5 \'c0\'cd\'c0\'cb\'c8\'d2\'c8\'d7\'c5\'d1\'ca\'ce\'c3\'ce \'d6\'c5\'cd\'d2\'d0\'c0 "\'ca\'ce\'cd\'d6\'c5\'cf\'d2"} +{\author \'ca\'ee\'ed\'ee\'ed\'e5\'ed\'ea\'ee \'c0\'eb\'e5\'ea\'f1\'e0\'ed\'e4\'f0 \'c0\'ed\'e0\'f2\'ee\'eb\'fc\'e5\'e2\'e8\'f7}{\operator \'c8\'e2\'e0\'ed \'c1\'ee\'f0\'e8\'f1\'ee\'e2}{\creatim\yr2013\mo10\dy22\hr17\min57} +{\revtim\yr2023\mo8\dy6\hr21\min5}{\printim\yr2000\mo2\dy21\hr14\min18}{\version45}{\edmins30}{\nofpages3}{\nofwords881}{\nofchars5028}{\*\company Elcom Ltd}{\nofcharsws5898}{\vern25}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wor +dml}}\paperw11907\paperh16840\margl1701\margr4394\margt1134\margb1134\gutter0\ltrsect +\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1\noxlattoyen +\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\lytprtmet\hyphcaps0\formshade\horzdoc\dghspace180\dgvspace180\dghorigin1701\dgvorigin1984\dghshow0\dgvshow0 +\jexpand\viewkind1\viewscale210\pgbrdrhead\pgbrdrfoot\bdrrlswsix\nolnhtadjtbl\nojkernpunct\rsidroot10831818 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0{\*\ftnsep \ltrpar \pard\plain \ltrpar +\qj \fi425\li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid11553206 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid14578367 \chftnsep +\par }}{\*\ftnsepc \ltrpar \pard\plain \ltrpar\qj \fi425\li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid11553206 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 { +\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid14578367 \chftnsepc +\par }}{\*\aftnsep \ltrpar \pard\plain \ltrpar\qj \fi425\li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid11553206 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 { +\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid14578367 \chftnsep +\par }}{\*\aftnsepc \ltrpar \pard\plain \ltrpar\qj \fi425\li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid11553206 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 { +\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid14578367 \chftnsepc +\par }}\ltrpar \sectd \ltrsect\psz9\linex0\headery567\footery567\titlepg\sectdefaultcl\sectrsid10575972\sftnbj {\headerl \ltrpar \pard\plain \ltrpar\s20\qj \fi425\li0\ri0\sb120\widctlpar +\tqc\tx4153\tqr\tx8306\pvpara\phmrg\posxr\posy0\wraparound\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\field{\*\fldinst {\rtlch\fcs1 \af0 +\ltrch\fcs0 \cs22\insrsid11553206 PAGE }}{\fldrslt {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs22\lang1024\langfe1024\noproof\insrsid11553206 2}}}\sectd \ltrsect\linex0\endnhere\sectdefaultcl\sftnbj {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs22\insrsid11553206 +\par }\pard \ltrpar\s20\qj \fi425\li0\ri360\sb120\widctlpar\tqc\tx4153\tqr\tx8306\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin360\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206 +\par }}{\headerr \ltrpar \pard\plain \ltrpar\s20\qj \fi425\li0\ri360\sb120\widctlpar\tqc\tx4153\tqr\tx8306\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin360\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 +\fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206 +\par }}{\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}} +{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8 +\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\s1\qc \fi425\li0\ri0\sb120\keepn\nowidctlpar +\tx240\wrapdefault\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0\pararsid7221176 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \b\fs22\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 +\fs20\insrsid11553206\charrsid9781973 \'cb\'c8\'d6\'c5\'cd\'c7\'c8\'ce\'cd\'cd\'ce\'c5 \'d1\'ce\'c3\'cb\'c0\'d8\'c5\'cd\'c8\'c5}{\rtlch\fcs1 \af0 \ltrch\fcs0 \fs20\insrsid3240529\charrsid9781973 +\par \'d6\'c5\'cd\'d2\'d0\'c0 \'c8\'cd\'cd\'ce\'c2\'c0\'d6\'c8\'c9 \'c8 \'c2\'db\'d1\'ce\'ca\'c8\'d5 \'d2\'c5\'d5\'cd\'ce\'cb\'ce\'c3\'c8\'c9}{\rtlch\fcs1 \af0 \ltrch\fcs0 \fs20\insrsid11553206\charrsid9781973 \'93\'ca\'ce\'cd\'d6\'c5\'cf\'d2\'94 +\par }\pard\plain \ltrpar\qc \li0\ri0\sb120\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang1049\langfe1049\cgrid\langnp1049\langfenp1049 {\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid11553206\charrsid9781973 \'d0\'e5\'e3\'eb\'e0\'ec\'e5\'ed\'f2}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid3240529\charrsid9781973 \'e8\'f0\'f3\'fe\'f9\'e5\'e5 \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'ee\'e2\'e0\'ed\'e8\'e5 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed\'ee +\'e3\'ee}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 \'ef\'f0\'ee\'e4\'f3\'ea\'f2}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid3240529\charrsid9781973 \'e0}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 }{\rtlch\fcs1 \af0 +\ltrch\fcs0 \b\insrsid3240529\charrsid9781973 \'dd\'ea\'f1\'f2\'e5\'ee\'f0}{\rtlch\fcs1 \af0 \ltrch\fcs0 \b\lang1033\langfe1049\langnp1033\insrsid3295549 \~}{\rtlch\fcs1 \af0 \ltrch\fcs0 \b\insrsid9578463 4.}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\b\insrsid4663543\charrsid4663543 9}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 \'ed\'e0 \'f1\'f2\'e0\'e4\'e8\'e8 \'ef\'f0\'e5\'e4\'e2\'e0\'f0\'e8\'f2\'e5\'eb\'fc\'ed\'ee\'e3\'ee \'f0\'e0\'f1\'ef\'f0\'ee\'f1\'f2\'f0\'e0\'ed\'e5\'ed\'e8 +\'ff \'e2 \'f6\'e5\'eb\'ff\'f5 \'e0\'ef\'f0\'ee\'e1\'e0\'f6\'e8\'e8 \'e8 \'f2\'e5\'f1\'f2\'e8\'f0\'ee\'e2\'e0\'ed\'e8\'ff. \line \'c2 \'cd\'c5\'ca\'ce\'cc\'cc\'c5\'d0\'d7\'c5\'d1\'ca\'c8\'d5 \'d6\'c5\'cb\'df\'d5}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\b\insrsid11553206\charrsid9781973 +\par }\pard \ltrpar\qj \fi425\li0\ri0\sb120\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid10575972 {\rtlch\fcs1 \af0 \ltrch\fcs0 \expnd0\expndtw-4\insrsid11553206\charrsid13774727 \'cd\'e0\'f1\'f2\'ee\'ff\'f9\'e5\'e5 \'eb\'e8 +\'f6\'e5\'ed\'e7\'e8\'ee\'ed\'ed\'ee\'e5 \'f1\'ee\'e3\'eb\'e0\'f8\'e5\'ed\'e8\'e5 (\'e4\'e0\'eb\'e5\'e5 "\'f1\'ee\'e3\'eb\'e0\'f8\'e5\'ed\'e8\'e5") }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid10575972 \'ff\'e2\'eb\'ff\'e5\'f2\'f1\'ff \'fe\'f0 +\'e8\'e4\'e8\'f7\'e5\'f1\'ea\'e8\'ec}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13774727\charrsid10575972 \'e4\'ee\'ea\'f3\'ec\'e5\'ed\'f2\'ee\'ec, \'e7\'e0\'ea\'eb\'fe\'f7\'e0\'e5\'ec\'fb\'ec \'ec\'e5\'e6\'e4\'f3 \'c2}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid11553206\charrsid10575972 \'e0\'ec\'e8 (\'f4\'e8\'e7\'e8\'f7\'e5\'f1\'ea\'e8\'ec \'e8\'eb\'e8 \'fe\'f0\'e8\'e4\'e8\'f7\'e5\'f1\'ea\'e8\'ec \'eb\'e8\'f6\'ee\'ec) \'e8 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid3240529\charrsid10575972 \'d6\'e5\'ed\'f2 +\'f0\'ee\'ec \'e8\'ed\'ed\'ee\'e2\'e0\'f6\'e8\'e9 \'e8 \'e2\'fb\'f1\'ee\'ea\'e8\'f5 \'f2\'e5\'f5\'ed\'ee\'eb\'ee\'e3\'e8\'e9}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid10575972 \'93\'ca\'ee\'ed\'f6\'e5\'ef\'f2\'94 (\'e4\'e0\'eb\'e5\'e5 "\'f6 +\'e5\'ed\'f2\'f0 \'ca\'ee\'ed\'f6\'e5\'ef\'f2") \'ee\'f2\'ed\'ee\'f1\'e8\'f2\'e5\'eb\'fc\'ed\'ee \'f3\'ea\'e0\'e7\'e0\'ed\'ed\'ee\'e3\'ee \'e2\'fb\'f8\'e5 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed\'ee\'e3\'ee \'ef\'f0\'ee\'e4\'f3\'ea\'f2\'e0 \'f6\'e5\'ed\'f2 +\'f0\'e0 \'ca\'ee\'ed\'f6\'e5\'ef\'f2 (\'e4\'e0\'eb\'e5\'e5 "}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1258943\charrsid10575972 \'cf}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid10575972 \'f0\'ee\'e3\'f0\'e0\'ec\'ec\'e0" \'e8\'eb\'e8 "\'ef\'f0\'ee +\'e3\'f0\'e0\'ec\'ec\'ed\'ee\'e5 \'ee\'e1\'e5\'f1\'ef\'e5\'f7\'e5\'ed\'e8\'e5"), \'e2\'ea\'eb\'fe\'f7\'e0\'fe\'f9\'e5\'e3\'ee \'e2 \'f1\'e5\'e1\'ff \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed\'ee\'e5 \'ee\'e1\'e5\'f1\'ef\'e5\'f7\'e5\'ed\'e8\'e5, \'e7\'e0\'ef\'e8 +\'f1\'e0\'ed\'ed\'ee\'e5 \'ed\'e0 \'f1\'ee\'ee\'f2\'e2\'e5\'f2\'f1\'f2\'e2\'f3\'fe\'f9\'e8\'f5 \'ed\'ee\'f1\'e8\'f2\'e5\'eb\'ff\'f5, \'eb\'fe\'e1\'fb\'e5 \'ef\'e5\'f7\'e0\'f2\'ed\'fb\'e5 \'ec\'e0\'f2\'e5\'f0\'e8\'e0\'eb\'fb \'e8 \'eb\'fe\'e1\'f3\'fe "\'e2 +\'f1\'f2\'f0\'ee\'e5\'ed\'ed\'f3\'fe" \'e8\'eb\'e8 "\'fd\'eb\'e5\'ea\'f2\'f0\'ee\'ed\'ed\'f3\'fe" \'e4\'ee\'ea\'f3\'ec\'e5\'ed\'f2\'e0\'f6\'e8\'fe. }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13774727\charrsid10575972 +\par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid10575972 \'ca "\'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed\'ee\'ec\'f3 \'ee\'e1\'e5\'f1\'ef\'e5\'f7\'e5\'ed\'e8\'fe" \'ee\'f2\'ed\'ee\'f1\'ff\'f2\'f1\'ff \'f2\'e0\'ea\'e6\'e5 \'eb\'fe\'e1\'fb\'e5 \'ee\'e1 +\'ed\'ee\'e2\'eb\'e5\'ed\'e8\'ff \'e8 \'e4\'ee\'ef\'ee\'eb\'ed\'e5\'ed\'e8\'ff \'ea \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed\'ee\'ec\'f3 \'ee\'e1\'e5\'f1\'ef\'e5\'f7\'e5\'ed\'e8\'fe, \'e8\'f1\'f5\'ee\'e4\'ed\'ee \'ef\'f0\'e5\'e4\'ee\'f1\'f2\'e0\'e2\'eb\'e5 +\'ed\'ed\'ee\'ec\'f3 "\'f6\'e5\'ed\'f2\'f0\'ee\'ec \'ca\'ee\'ed\'f6\'e5\'ef\'f2". \'cb\'fe\'e1\'fb\'e5 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed\'fb\'e5 \'ea\'ee\'ec\'ef\'ee\'ed\'e5\'ed\'f2\'fb, \'ef\'f0\'e5\'e4\'ee\'f1\'f2\'e0\'e2\'eb\'e5\'ed\'ed\'fb\'e5 \'f1 +\'ee\'e2\'ec\'e5\'f1\'f2\'ed\'ee \'f1 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed\'fb\'ec \'ee\'e1\'e5\'f1\'ef\'e5\'f7\'e5\'ed\'e8\'e5\'ec, \'ef\'f0\'e0\'e2\'e8\'eb\'e0 \'ef\'ee\'eb\'fc\'e7\'ee\'e2\'e0\'ed\'e8\'ff \'ea\'ee\'f2\'ee\'f0\'fb\'ec\'e8 \'ee\'ef\'f0 +\'e5\'e4\'e5\'eb\'ff\'fe\'f2\'f1\'ff \'ee\'f2\'e4\'e5\'eb\'fc\'ed\'fb\'ec \'eb\'e8\'f6\'e5\'ed\'e7\'e8\'ee\'ed\'ed\'fb\'ec \'f1\'ee\'e3\'eb\'e0\'f8\'e5\'ed\'e8\'e5\'ec, \'ef\'f0\'e5\'e4\'ee\'f1\'f2\'e0}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid13774727\charrsid10575972 \'e2\'eb\'ff\'fe\'f2\'f1\'ff \'ed\'e0 \'f3\'f1\'eb\'ee\'e2\'e8\'ff\'f5 \'ef\'ee\'f1\'eb\'e5\'e4\'ed\'e5\'e3\'ee. +\par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid10575972 \'d3\'f1\'f2\'e0\'ed\'e0\'e2\'eb\'e8\'e2\'e0\'ff, \'ea\'ee\'ef\'e8\'f0\'f3\'ff, \'e7\'e0\'e3\'f0\'f3\'e6\'e0\'ff, \'ee\'f1\'f3\'f9\'e5\'f1\'f2\'e2\'eb\'ff\'ff \'e4\'ee\'f1\'f2\'f3\'ef \'e8 +\'eb\'e8 \'e8\'ed\'fb\'ec \'ee\'e1\'f0\'e0\'e7\'ee\'ec \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'f3\'ff \'f3\'ea\'e0\'e7\'e0\'ed\'ed\'ee\'e5 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed\'ee\'e5 \'ee\'e1\'e5\'f1\'ef\'e5\'f7\'e5\'ed\'e8\'e5, \'e2\'fb \'f2\'e5\'ec \'f1\'e0\'ec +\'fb\'ec \'ef\'f0\'e8\'ed\'e8\'ec\'e0\'e5\'f2\'e5 \'ed\'e0 \'f1\'e5\'e1\'ff \'f3\'f1\'eb\'ee\'e2\'e8\'ff \'ed\'e0\'f1\'f2\'ee\'ff\'f9\'e5\'e3\'ee \'f1}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13774727\charrsid10575972 \'ee\'e3\'eb\'e0\'f8\'e5\'ed\'e8\'ff. + +\par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid2719415 \'c5\'f1\'eb\'e8 \'e2\'fb \'ed\'e5 \'f1\'ee\'e3\'eb\'e0\'f1\'ed\'fb \'f1 \'f3\'f1\'eb\'ee\'e2\'e8\'ff\'ec\'e8 \'ed\'e0\'f1\'f2\'ee\'ff\'f9\'e5\'e3\'ee \'eb\'e8\'f6\'e5\'ed\'e7\'e8\'ee\'ed\'ed +\'ee\'e3\'ee \'f1\'ee\'e3\'eb\'e0\'f8\'e5\'ed\'e8\'ff, \'ed\'e5 \'f3\'f1\'f2\'e0\'ed\'e0\'e2\'eb\'e8\'e2\'e0\'e9\'f2\'e5 \'e8 \'ed\'e5 \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'f3\'e9\'f2\'e5 \'e4\'e0\'ed\'ed\'ee\'e5 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed\'ee\'e5 \'ee +\'e1\'e5\'f1\'ef\'e5\'f7\'e5\'ed\'e8\'e5. +\par }\pard \ltrpar\qc \fi425\li0\ri0\sb120\nowidctlpar\tx576\tx1152\tx1728\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid7221176 {\rtlch\fcs1 \af0 \ltrch\fcs0 \b\insrsid11553206\charrsid9781973 \'cb\'c8\'d6\'c5\'cd\'c7\'c8\'df \'cd +\'c0 \'cf\'d0\'ce\'c3\'d0\'c0\'cc\'cc\'d3 +\par }\pard \ltrpar\qj \fi425\li0\ri0\sb120\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 \'cf\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed\'ee\'e5 \'ee\'e1\'e5\'f1\'ef\'e5\'f7\'e5 +\'ed\'e8\'e5 \'e7\'e0\'f9\'e8\'f9\'e5\'ed\'ee \'e7\'e0\'ea\'ee\'ed\'e0\'ec\'e8 \'e8 \'ec\'e5\'e6\'e4\'f3\'ed\'e0\'f0\'ee\'e4\'ed\'fb\'ec\'e8 \'f1\'ee\'e3\'eb\'e0\'f8\'e5\'ed\'e8\'ff\'ec\'e8 \'ee\'e1 \'e0\'e2\'f2\'ee\'f0\'f1\'ea\'e8\'f5 \'ef\'f0\'e0\'e2 +\'e0\'f5, \'e0 \'f2\'e0\'ea\'e6\'e5 \'e4\'f0\'f3\'e3\'e8\'ec\'e8 \'e7\'e0\'ea\'ee\'ed\'e0\'ec\'e8 \'e8 \'e4\'ee\'e3\'ee\'e2\'ee\'f0\'e0\'ec\'e8, \'f0\'e5\'e3\'f3\'eb\'e8\'f0\'f3\'fe\'f9\'e8\'ec\'e8 \'ee\'f2\'ed\'ee\'f8\'e5\'ed\'e8\'ff \'e8\'ed\'f2\'e5\'eb +\'eb\'e5\'ea\'f2\'f3\'e0\'eb\'fc\'ed\'ee\'e9 \'f1\'ee\'e1\'f1\'f2\'e2\'e5\'ed\'ed\'ee\'f1\'f2\'e8. \'c4\'e0\'ed\'ed\'ee\'e5 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed\'ee\'e5 \'ee\'e1\'e5\'f1\'ef\'e5\'f7\'e5\'ed\'e8\'e5 \'eb\'e8\'f6\'e5\'ed\'e7\'e8\'f0\'f3\'e5 +\'f2\'f1\'ff, \'e0 \'ed\'e5 \'ef\'f0\'ee\'e4\'e0\'e5\'f2\'f1\'ff. +\par }\pard \ltrpar\qj \fi-180\li180\ri0\sb120\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin180\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \b\insrsid11553206\charrsid9781973 1. \'ce\'c1\'da\'c5\'cc \'cb\'c8\'d6\'c5\'cd\'c7\'c8\'c8.}{\rtlch\fcs1 +\af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid12725728 +\par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 \'cd\'e0\'f1\'f2\'ee\'ff\'f9\'e5\'e5 \'eb\'e8\'f6\'e5\'ed\'e7\'e8\'ee\'ed\'ed\'ee\'e5 \'f1\'ee\'e3\'eb\'e0\'f8\'e5\'ed\'e8\'e5 \'ef\'f0\'e5\'e4\'ee\'f1\'f2\'e0\'e2\'eb\'ff\'e5\'f2 }{ +\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid10316737 \'c2}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 \'e0\'ec \'f1\'eb\'e5\'e4\'f3\'fe\'f9\'e8\'e5 \'ef\'f0\'e0\'e2\'e0: +\par }\pard \ltrpar\qj \fi-142\li142\ri0\sb120\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin142\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f3\insrsid11553206\charrsid9781973 \u183\'b7 }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\b\insrsid11553206\charrsid9781973 \'cf\'f0\'e8\'ea\'eb\'e0\'e4\'ed\'ee\'e5 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed\'ee\'e5 \'ee\'e1\'e5\'f1\'ef\'e5\'f7\'e5\'ed\'e8\'e5.}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 \'d0\'e0\'e7\'f0\'e5\'f8 +\'e0\'e5\'f2\'f1\'ff \'f3\'f1\'f2\'e0\'ed\'e0\'e2\'eb\'e8\'e2\'e0\'f2\'fc, \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'ee\'e2\'e0\'f2\'fc, \'ee\'f2\'ee\'e1\'f0\'e0\'e6\'e0\'f2\'fc, \'e7\'e0\'ef\'f3\'f1\'ea\'e0\'f2\'fc \'e8\'eb\'e8 \'e8\'ed\'fb\'ec \'f1\'ef\'ee\'f1}{ +\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid16075767 \'ee\'e1\'ee\'ec \'f0\'e0\'e1\'ee\'f2\'e0\'f2\'fc \'f1 \'ea\'ee\'ef\'e8\'e5\'e9 \'e4\'e0\'ed\'ed\'ee\'e3\'ee \'cf}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 \'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed +\'ee\'e3\'ee \'ee\'e1\'e5\'f1\'ef\'e5\'f7\'e5\'ed\'e8\'ff. \'ce\'f1\'ed\'ee\'e2\'ed\'ee\'e9 \'ef\'ee\'eb\'fc\'e7\'ee\'e2\'e0\'f2\'e5\'eb\'fc \'ea\'ee\'ec\'ef\'fc\'fe\'f2\'e5\'f0\'e0, \'ed\'e0 \'ea\'ee\'f2\'ee\'f0\'ee\'ec \'f0\'e0\'e1\'ee\'f2\'e0\'e5\'f2 +\'f3\'ea\'e0\'e7\'e0\'ed\'ed\'e0\'ff \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'e0, \'e2\'ef\'f0\'e0\'e2\'e5 \'f2\'e0\'ea\'e6\'e5 \'f1\'ee\'e7\'e4\'e0\'f2\'fc \'e5\'f9\'e5 \'ee\'e4\'ed\'f3 \'e5\'e5 \'ea\'ee\'ef\'e8\'fe \'e8\'f1\'ea\'eb\'fe\'f7\'e8\'f2\'e5\'eb\'fc +\'ed\'ee \'e4\'eb\'ff \'f1\'ee\'e1\'f1\'f2\'e2\'e5\'ed\'ed\'ee\'e3\'ee \'ef\'ee\'eb\'fc\'e7\'ee\'e2\'e0\'ed\'e8\'ff \'ed\'e0 \'ef\'e5\'f0\'e5\'ed\'ee\'f1\'ed\'ee\'ec \'ea\'ee\'ec\'ef\'fc\'fe\'f2\'e5\'f0\'e5 \'c2 \'cd\'c5\'ca\'ce\'cc\'cc\'c5\'d0\'d7\'c5 +\'d1\'ca\'c8\'d5 \'d6\'c5\'cb\'df\'d5. \'c2 \'ef\'f0\'ee\'f2\'e8\'e2\'ed\'ee\'ec \'f1\'eb\'f3\'f7\'e0\'e5 \'ed\'e5\'ee\'e1\'f5\'ee\'e4\'e8\'ec\'ee \'e7\'e0\'ea\'eb\'fe\'f7\'e0\'f2\'fc \'e8\'ed\'ee\'e5 \'eb\'e8\'f6\'e5\'ed\'e7\'e8\'ee\'ed\'ed\'ee\'e5 \'f1 +\'ee\'e3\'eb\'e0\'f8\'e5\'ed\'e8\'e5 \'ee\'e1 \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'ee\'e2\'e0\'ed\'e8\'e8 \'e8 \'f1\'ee\'ef\'f0\'ee\'e2\'ee\'e6\'e4\'e5\'ed\'e8\'e8. +\par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \f3\insrsid11553206\charrsid13569699 \u183\'b7 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \b\insrsid11553206\charrsid13569699 \'d5\'f0\'e0\'ed\'e5\'ed\'e8\'e5 \'e8 \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'ee\'e2\'e0\'ed\'e8\'e5 \'e2 \'f1\'e5\'f2 +\'e8.}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid13569699 \'d0\'e0\'e7\'f0\'e5\'f8\'e0\'e5\'f2\'f1\'ff \'f2\'e0\'ea\'e6}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid5394278\charrsid13569699 \'e5 \'f5\'f0\'e0\'ed\'e8\'f2\'fc \'e8\'eb\'e8 \'f3\'f1\'f2 +\'e0\'ed\'ee\'e2\'e8\'f2\'fc \'ea\'ee\'ef\'e8\'fe \'cf}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid13569699 \'f0\'ee\'e3\'f0\'e0\'ec\'ec\'fb \'ed\'e0 \'f3\'f1\'f2\'f0\'ee\'e9\'f1\'f2\'e2\'e5 \'f5\'f0\'e0\'ed\'e5\'ed\'e8\'ff \'e4\'e0\'ed\'ed\'fb +\'f5 (\'ed\'e0\'ef\'f0\'e8\'ec\'e5\'f0, \'ed\'e0 \'f1\'e5\'f0\'e2\'e5\'f0\'e5 \'f1\'e5\'f2\'e8), \'ef\'f0\'e5\'e4\'ed\'e0\'e7\'ed\'e0\'f7\'e5\'ed\'ed\'ee\'ec \'e8 \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'f3\'e5\'ec\'ee\'ec \'e8\'f1\'ea\'eb\'fe\'f7\'e8\'f2\'e5\'eb +\'fc\'ed\'ee \'e4\'eb\'ff \'f0\'e0\'e1\'ee\'f2\'fb \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'fb \'ed\'e0 \'e4\'f0\'f3\'e3\'e8\'f5 \'e2\'e0\'f8\'e8\'f5 \'ea\'ee\'ec\'ef\'fc\'fe\'f2\'e5\'f0\'e0\'f5 \'e2 \'ef\'f0\'e5\'e4\'e5\'eb\'e0\'f5 \'eb\'ee\'ea\'e0\'eb\'fc\'ed +\'ee\'e9 \'f1\'e5\'f2\'e8, \'e5\'f1\'eb\'e8 \'ef\'f0\'e8 \'fd\'f2\'ee\'ec \'e3\'e0\'f0\'e0\'ed\'f2\'e8\'f0\'ee\'e2\'e0\'ed\'ee \'ed\'e5\'f0\'e0\'f1\'ef\'f0\'ee\'f1\'f2\'f0\'e0\'ed\'e5\'ed\'e8\'e5 }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid8351939\charrsid13569699 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'fb \'e5\'e5}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid13569699 \'f7\'e0\'f1\'f2\'e5\'e9 \'f2\'f0\'e5\'f2\'fc\'e8\'ec \'eb\'e8\'f6\'e0\'ec. +\par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \f3\insrsid11553206\charrsid9781973 \u183\'b7 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \b\insrsid11553206\charrsid9781973 \'cf\'f0\'e5\'e4\'ee\'f1\'f2\'e0\'e2\'eb\'e5\'ed\'e8\'e5 \'ef\'f0\'e0\'e2. }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid11553206\charrsid9781973 \'d6\'e5\'ed\'f2\'f0 "\'ca\'ee\'ed\'f6\'e5\'ef\'f2" \'ed\'e5 \'ef\'f0\'e5\'e4\'ee\'f1\'f2\'e0\'e2\'eb\'ff\'e5\'f2 \'ed\'e8\'ea\'e0\'ea\'e8\'f5 \'ef\'f0\'e0\'e2 \'e8\'ed\'e0\'f7\'e5, \'f7\'e5\'ec \'ff\'e2\'ed\'fb\'ec \'ee +\'f2\'ee\'ec \'f3\'f2\'e2\'e5\'f0\'e6\'e4\'e5\'ed\'e8\'e5\'ec. +\par }\pard \ltrpar\qj \fi-180\li180\ri0\sb120\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin180\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \b\insrsid11553206\charrsid9781973 2. \'ce\'cf\'c8\'d1\'c0\'cd\'c8\'c5 \'cf\'d0\'ce\'d7\'c8\'d5 \'cf\'d0 +\'c0\'c2 \'c8 \'ce\'c3\'d0\'c0\'cd\'c8\'d7\'c5\'cd\'c8\'c9.}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 +\par }\pard \ltrpar\qj \fi-142\li142\ri0\sb120\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin142\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f3\insrsid11553206\charrsid9781973 \u183\'b7 }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\b\insrsid11553206\charrsid9781973 \'c8\'e7\'e4\'e0\'ed\'e8\'e5 "\'ed\'e5 \'e4\'eb\'ff \'ef\'f0\'ee\'e4\'e0\'e6\'e8". }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 \'cd\'e5\'e7\'e0\'e2\'e8\'f1\'e8\'ec\'ee \'ee\'f2 \'ee\'f1\'f2\'e0\'eb +\'fc\'ed\'fb\'f5 \'f3\'f1\'eb\'ee\'e2\'e8\'e9 \'ed\'e0\'f1\'f2\'ee\'ff\'f9\'e5\'e3\'ee \'eb\'e8\'f6\'e5\'ed\'e7\'e8\'ee\'ed\'ed\'ee\'e3\'ee \'f1\'ee\'e3\'eb\'e0\'f8\'e5\'ed\'e8\'ff, \'ed\'e0\'f1\'f2\'ee\'ff\'f9\'e0\'ff \'eb\'e8\'f6\'e5\'ed\'e7\'e8\'ff }{ +\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid13261014 \'e4\'ee\'ef\'f3\'f1\'ea\'e0\'e5\'f2 \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'ee\'e2\'e0\'ed\'e8\'e5 \'cf}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 \'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed\'ee\'e3\'ee \'ee +\'e1\'e5\'f1\'ef\'e5\'f7\'e5\'ed\'e8\'ff \'f2\'ee\'eb\'fc\'ea\'ee \'e2 \'f6\'e5\'eb\'ff\'f5 \'e4\'e5\'ec\'ee\'ed\'f1\'f2\'f0\'e0\'f6\'e8\'e8, \'ef\'f0\'ee\'e2\'e5\'f0\'ea\'e8 \'e8\'eb\'e8 \'ee\'f6\'e5\'ed\'ea\'e8, \'e0 \'ef\'f0\'ee\'e4\'e0\'e6\'e0, \'ef +\'e5\'f0\'e5\'e4\'e0\'f7\'e0 \'e2 \'ed\'e0\'e5\'ec, \'e0\'f0\'e5\'ed\'e4\'f3 \'e8\'eb\'e8 \'ea\'e0\'ea\'e0\'ff-\'eb\'e8\'e1\'ee \'e8\'ed\'e0\'ff \'e2\'ee\'e7\'ec\'e5\'e7\'e4\'ed\'e0\'ff \'ef\'e5\'f0\'e5\'e4\'e0\'f7\'e0 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed +\'ee\'e3\'ee \'ee\'e1\'e5\'f1\'ef\'e5\'f7\'e5\'ed\'e8\'ff \'e7\'e0\'ef\'f0\'e5\'f9\'e0\'e5\'f2\'f1\'ff. +\par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \f3\insrsid11553206\charrsid9781973 \u183\'b7 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \b\insrsid11553206\charrsid9781973 \'c7\'e0\'ef\'f0\'e5\'f2 \'ed\'e0 \'e2\'f1\'ea\'f0\'fb\'f2\'e8\'e5 \'f2\'e5\'f5\'ed\'ee\'eb\'ee\'e3\'e8\'e8, +\'e8 \'ec\'ee\'e4\'e8\'f4\'e8\'ea\'e0\'f6\'e8\'fe. }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 \'c2\'fb \'ed\'e5 \'ec\'ee\'e6\'e5\'f2\'e5 \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'ee\'e2\'e0\'f2\'fc, \'ea\'ee\'ef\'e8\'f0\'ee\'e2\'e0\'f2\'fc, \'fd +\'ec\'f3\'eb\'e8\'f0\'ee\'e2\'e0\'f2\'fc, \'f1\'ee\'e7\'e4\'e0\'e2\'e0\'f2\'fc \'ed\'ee\'e2\'fb\'e5 \'e2\'e5\'f0\'f1\'e8\'e8, \'ef\'f0\'ee\'e4\'e0\'e2\'e0\'f2\'fc, \'e8\'e7\'ec\'e5\'ed\'ff\'f2\'fc, \'e4\'e5\'ea\'ee\'ec\'ef\'e8\'eb\'e8\'f0\'ee\'e2\'e0\'f2 +\'fc, \'e4\'e8\'e7\'e0\'f1\'f1\'e5\'ec\'e1\'eb\'e8\'f0\'ee\'e2\'e0\'f2\'fc, \'e8\'e7\'f3\'f7\'e0\'f2\'fc \'ea\'ee\'e4 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'fb \'e4\'f0\'f3\'e3\'e8\'ec\'e8 \'f1\'ef\'ee\'f1\'ee\'e1\'e0\'ec\'e8, \'ef\'e5\'f0\'e5\'e4\'e0\'e2\'e0 +\'f2\'fc \'eb\'e8\'f6\'e5\'ed\'e7\'e8\'f0\'ee\'e2\'e0\'ed\'ed\'f3\'fe \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'f3 \'e8\'eb\'e8 \'eb\'fe\'e1\'fb\'e5 \'e8\'e7 \'e5\'e5 \'f1\'ee\'f1\'f2\'e0\'e2\'eb\'ff\'fe\'f9\'e8\'f5, \'e8\'ed\'e0\'f7\'e5, \'f7\'e5\'ec \'ee\'ef +\'f0\'e5\'e4\'e5\'eb\'e5\'ed\'ee \'ed\'e0\'f1\'f2\'ee\'ff\'f9\'e8\'ec \'eb\'e8\'f6\'e5\'ed\'e7\'e8\'ee\'ed\'ed\'fb\'ec \'f1\'ee\'e3\'eb\'e0\'f8\'e5\'ed\'e8\'e5\'ec. \'cb\'fe\'e1\'ee\'e5 \'f2\'e0\'ea\'ee\'e5 \'ed\'e5\'eb\'e5\'e3\'e0\'eb\'fc\'ed\'ee\'e5 +\'e8\'f1\'ef\'ee\'eb\'fc\'e7\'ee\'e2\'e0\'ed\'e8\'e5 \'ee\'e7\'ed\'e0\'f7\'e0\'e5\'f2 \'e0\'e2\'f2\'ee\'ec\'e0\'f2\'e8\'f7\'e5\'f1\'ea\'ee\'e5 \'e8 \'ed\'e5\'ec\'e5\'e4\'eb\'e5\'ed\'ed\'ee\'e5 \'ef\'f0\'e5\'ea\'f0\'e0\'f9\'e5\'ed\'e8\'e5 \'e4\'e5\'e9\'f1 +\'f2\'e2\'e8\'ff \'ed\'e0\'f1\'f2\'ee\'ff\'f9\'e5\'e3\'ee \'f1\'ee\'e3\'eb\'e0\'f8\'e5\'ed\'e8\'ff \'e8 \'ec\'ee\'e6\'e5\'f2 \'ef\'f0\'e5\'f1\'eb\'e5\'e4\'ee\'e2\'e0\'f2\'fc\'f1\'ff \'ef\'ee \'e7\'e0\'ea\'ee\'ed\'f3. +\par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \f3\insrsid11553206\charrsid9781973 \u183\'b7 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \b\insrsid11553206\charrsid9781973 \'d2\'ee\'e2\'e0\'f0\'ed\'fb\'e5 \'e7\'ed\'e0\'ea\'e8.}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid11553206\charrsid9781973 \'cd\'e0\'f1\'f2\'ee\'ff\'f9\'e5\'e5 \'eb\'e8\'f6\'e5\'ed\'e7\'e8\'ee\'ed\'ed}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid88900 \'ee\'e5 \'f1\'ee\'e3\'eb\'e0\'f8\'e5\'ed\'e8\'e5 \'ed\'e5 \'ef\'f0\'e5\'e4\'ee\'f1\'f2\'e0\'e2\'eb +\'ff\'e5\'f2 \'c2}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 \'e0\'ec \'ed\'e8\'ea\'e0\'ea\'e8\'f5 \'ef\'f0\'e0\'e2 \'e2 \'ee\'f2\'ed\'ee\'f8\'e5\'ed\'e8\'e8 \'ea\'e0\'ea\'e8\'f5-\'eb\'e8\'e1\'ee \'f2\'ee\'f0\'e3\'ee\'e2\'fb\'f5 \'e7 +\'ed\'e0\'ea\'ee\'e2 \'e8\'eb\'e8 \'ed\'e0\'e7\'e2\'e0\'ed\'e8\'e9, \'ef\'f0\'e8\'ed\'e0\'e4\'eb\'e5\'e6\'e0\'f9\'e8\'f5 \'f6\'e5\'ed\'f2\'f0\'f3 \'ab\'ca\'ee\'ed\'f6\'e5\'ef\'f2\'bb. +\par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \f3\insrsid11553206\charrsid9781973 \u183\'b7}{\rtlch\fcs1 \af0 \ltrch\fcs0 \b\f3\insrsid11553206\charrsid9781973 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \b\insrsid11553206\charrsid9781973 \'d2\'e5\'f5\'ed\'e8\'f7\'e5\'f1\'ea\'ee +\'e5 \'ee\'e1\'f1\'eb\'f3\'e6\'e8\'e2\'e0\'ed\'e8\'e5. }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 \'d6\'e5\'ed\'f2\'f0 \'ab\'ca\'ee\'ed\'f6\'e5\'ef\'f2\'bb \'ec\'ee\'e6\'e5\'f2 \'ee\'ea}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid88900 \'e0 +\'e7\'fb\'e2\'e0\'f2\'fc \'f3\'f1\'eb\'f3\'e3\'e8 \'ef\'ee \'ee\'e1\'f1\'eb\'f3\'e6\'e8\'e2\'e0\'ed\'e8\'fe \'cf}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 \'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed\'ee\'e3\'ee \'ee\'e1\'e5\'f1\'ef\'e5\'f7\'e5 +\'ed\'e8\'ff. \'cf\'f0\'e0\'e2\'e8\'eb\'e0 \'ee\'e1\'f0\'e0\'f9\'e5\'ed\'e8\'ff \'e8 \'f0\'e0\'e1\'ee\'f2\'fb \'f1\'eb\'f3\'e6\'e1\'fb \'ee\'e1\'f1\'eb\'f3\'e6\'e8\'e2\'e0\'ed\'e8\'ff \'ee\'e3\'ee\'e2\'e0\'f0\'e8\'e2\'e0\'fe\'f2\'f1\'ff \'ee\'f2\'e4\'e5 +\'eb\'fc\'ed\'fb\'ec \'f1\'ee\'e3\'eb\'e0\'f8\'e5\'ed\'e8\'e5\'ec. \'d2\'e5\'f5\'ed\'e8\'f7\'e5\'f1\'ea\'e8\'e5 \'e4\'e0\'ed\'ed\'fb\'e5, \'ea\'ee\'f2\'ee\'f0\'fb\'e5 \'f1\'ee\'ee\'e1\'f9\'e0\'fe\'f2\'f1\'ff \'f1\'eb\'f3\'e6\'e1\'e5 \'f2\'e5\'f5\'ed\'e8 +\'f7\'e5\'f1\'ea\'ee\'e3\'ee \'ee\'e1\'f1\'eb\'f3\'e6\'e8\'e2\'e0\'ed\'e8\'ff \'e2 \'f5\'ee\'e4\'e5 \'ee\'e1\'f0\'e0\'f9\'e5\'ed\'e8\'ff, \'ec\'ee\'e3\'f3\'f2 \'e1\'fb\'f2\'fc \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'ee\'e2\'e0\'ed\'fb \'f6\'e5\'ed\'f2\'f0\'ee\'ec +\'ab\'ca\'ee\'ed\'f6\'e5\'ef\'f2\'bb \'e4\'eb\'ff \'e2\'ed\'f3\'f2\'f0\'e5\'ed\'ed\'e8\'f5 \'f6\'e5\'eb\'e5\'e9, \'e2\'ea\'eb\'fe\'f7\'e0\'ff \'ee\'e1\'f1\'eb\'f3\'e6\'e8\'e2\'e0\'ed\'e8\'e5 \'e8 \'f0\'e0\'e7\'f0\'e0\'e1\'ee\'f2\'ea\'f3}{\rtlch\fcs1 \af0 +\ltrch\fcs0 \insrsid6381161\charrsid9781973 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 . +\par }\pard \ltrpar\qj \fi-180\li180\ri0\sb120\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin180\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \f3\insrsid11553206\charrsid9781973 \u183\'b7 }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\b\insrsid11553206\charrsid9781973 \'d0\'e0\'f1\'f2\'ee\'f0\'e6\'e5\'ed\'e8\'e5 \'f1\'ee\'e3\'eb\'e0\'f8\'e5\'ed\'e8\'ff.}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 \'c1\'e5\'e7 \'f3\'f9\'e5\'f0\'e1\'e0 \'e4\'eb\'ff \'ea\'e0\'ea\'e8 +\'f5-\'eb\'e8\'e1\'ee \'f1\'e2\'ee\'e8\'f5 \'ef\'f0\'e0\'e2 \'f6\'e5\'ed\'f2\'f0 \'ab\'ca\'ee\'ed\'f6\'e5\'ef\'f2\'bb \'ec\'ee\'e6\'e5\'f2 \'ef\'f0\'e5\'ea\'f0\'e0\'f2\'e8\'f2\'fc \'e4\'e5\'e9\'f1\'f2\'e2\'e8\'e5 \'ed\'e0\'f1\'f2\'ee\'ff\'f9\'e5\'e3\'ee +\'f1\'ee\'e3\'eb\'e0\'f8\'e5\'ed\'e8\'ff \'ef\'f0\'e8 \'ed\'e5\'f1\'ee\'e1\'eb\'fe\'e4\'e5\'ed\'e8\'e8 \'e5\'e3\'ee \'f3\'f1\'eb\'ee\'e2\'e8\'e9 \'e8 \'ee\'e3\'f0\'e0\'ed\'e8\'f7\'e5\'ed\'e8\'e9}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid88900 }{\rtlch\fcs1 +\af0 \ltrch\fcs0 \insrsid10757963 \'ee\'e4\'ed\'ee\'e9}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid88900 \'e8\'e7 \'f1\'f2\'ee\'f0\'ee\'ed}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 . \'cf\'f0\'e8 \'ef\'f0\'e5\'ea\'f0\'e0\'f9\'e5\'ed\'e8 +\'e8 \'e4\'e5\'e9\'f1\'f2\'e2\'e8\'ff \'f1\'ee\'e3\'eb\'e0\'f8\'e5\'ed\'e8\'ff \'c2\'fb \'ee\'e1\'ff\'e7\'e0\'ed\'fb \'f3\'ed\'e8\'f7\'f2\'ee\'e6\'e8\'f2\'fc \'e2\'f1\'e5 \'e8\'ec\'e5\'fe\'f9\'e8\'e5\'f1\'ff \'f3 }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid11472354 \'c2}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 \'e0\'f1 \'ea\'ee\'ef\'e8\'e8 \'e8 \'f1\'ee\'f1\'f2\'e0\'e2\'ed\'fb\'e5 \'f7\'e0\'f1\'f2\'e8 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed\'ee\'e3\'ee \'ee\'e1\'e5\'f1\'ef\'e5\'f7 +\'e5\'ed\'e8\'ff.}{\rtlch\fcs1 \af0 \ltrch\fcs0 \b\insrsid11553206\charrsid9781973 +\par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \f3\insrsid11553206\charrsid9781973 \u183\'b7 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \b\insrsid11553206\charrsid9781973 \'ce\'f2\'ec\'e5\'ed\'e0 \'f1\'ee\'e3\'eb\'e0\'f8\'e5\'ed\'e8\'ff.}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid11553206\charrsid9781973 \'d6\'e5\'ed\'f2\'f0 \'ab\'ca\'ee\'ed\'f6\'e5\'ef\'f2\'bb \'ee\'f1\'f2\'e0\'e2\'eb\'ff\'e5\'f2 \'e7\'e0 \'f1\'ee\'e1\'ee\'e9 \'ef\'f0\'e0\'e2\'ee \'ee\'f2\'ec\'e5\'ed\'e8\'f2\'fc \'e4\'e5\'e9\'f1\'f2\'e2\'e8\'e5 \'e4\'e0 +\'ed\'ed\'ee\'e9 \'eb\'e8\'f6\'e5\'ed\'e7\'e8\'e8 \'e4\'eb\'ff \'eb\'fe\'e1\'ee\'e9 \'e8\'e7 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1258943\charrsid9781973 \'ef\'ee}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 \'f1\'eb\'e5\'e4\'f3\'fe +\'f9\'e8\'f5 \'e2\'e5\'f0\'f1\'e8\'e9 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid16453070 \'cf}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid1258943\charrsid9781973 \'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed\'ee\'e3\'ee \'ea\'ee\'ec\'ef\'eb\'e5\'ea\'f1\'e0 \'ab\'dd\'ea\'f1\'f2 +\'e5\'ee\'f0\'bb}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 . +\par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \b\insrsid16335187\charrsid7865094 3}{\rtlch\fcs1 \af0 \ltrch\fcs0 \b\insrsid11553206\charrsid9781973 . \'c0\'c2\'d2\'ce\'d0\'d1\'ca\'ce\'c5 \'cf\'d0\'c0\'c2\'ce. }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\b\insrsid5076811\charrsid7865094 +\par }\pard \ltrpar\qj \li180\ri0\sb120\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin180\itap0\pararsid5076811 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 \'c2\'f1\'e5 \'ef\'f0\'e0\'e2\'e0 \'f1\'ee\'e1\'f1\'f2\'e2\'e5 +\'ed\'ed\'ee\'f1\'f2\'e8 \'e8 \'e0\'e2\'f2\'ee\'f0\'f1\'ea\'e8\'e5 \'ef\'f0\'e0\'e2\'e0 \'ed\'e0 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed\'ee\'e5 \'ee\'e1\'e5\'f1\'ef\'e5\'f7\'e5\'ed\'e8\'e5 (\'e2 \'f2\'ee\'ec \'f7\'e8\'f1\'eb\'e5 \'f2\'e5\'ea\'f1\'f2 \'e8 +\'e2\'f1\'ef\'ee\'ec\'ee\'e3\'e0\'f2\'e5\'eb\'fc\'ed\'fb\'e5 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'fb), \'f1\'ee\'e4\'e5\'f0\'e6\'e0\'ed\'e8\'e5 \'f1\'ee\'ef\'f0\'ee\'e2\'ee\'e6\'e4\'e0\'fe\'f9\'e8\'f5 \'e5\'e5 \'ef\'e5\'f7\'e0\'f2\'ed\'fb\'f5 \'ec\'e0\'f2 +\'e5\'f0\'e8\'e0\'eb\'ee\'e2 \'e8 \'eb\'fe\'e1\'fb\'e5 \'ea\'ee\'ef\'e8\'e8 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'fb \'ef\'f0\'e8\'ed\'e0\'e4\'eb\'e5\'e6\'e0\'f2 \'f6\'e5\'ed\'f2\'f0\'f3 \'ab\'ca\'ee\'ed\'f6\'e5\'ef\'f2\'bb. \'c2\'f1\'e5 \'ef\'f0\'e0\'e2\'e0 +\'f1\'ee\'e1\'f1\'f2\'e2\'e5\'ed\'ed\'ee\'f1\'f2\'e8 \'e8 \'e0\'e2\'f2\'ee\'f0\'f1\'ea\'e8\'e5 \'ef\'f0\'e0\'e2\'e0 \'ed\'e0 \'f1\'ee\'e4\'e5\'f0\'e6\'e0\'ed\'e8\'e5, \'e4\'ee\'f1\'f2\'f3\'ef \'ea \'ea\'ee\'f2\'ee\'f0\'ee\'ec\'f3 \'ef\'f0\'e5\'e4\'ee\'f1 +\'f2\'e0\'e2\'eb\'ff\'e5\'f2 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'e0, \'ef\'f0\'e8\'ed\'e0\'e4\'eb\'e5\'e6\'e0\'f2 \'e2\'eb\'e0\'e4\'e5\'eb\'fc\'f6\'f3 \'e0\'e2\'f2\'ee\'f0\'f1\'ea\'e8\'f5 \'ef\'f0\'e0\'e2 \'ed\'e0 \'f2\'e0\'ea\'ee\'e5 \'f1\'ee\'e4\'e5\'f0 +\'e6\'e0\'ed\'e8\'e5 \'e8 \'e7\'e0\'f9\'e8\'f9\'e5\'ed\'fb \'e7\'e0\'ea\'ee\'ed\'e0\'ec\'e8 \'e8 \'ec\'e5\'e6\'e4\'f3\'ed\'e0\'f0\'ee\'e4\'ed\'fb\'ec\'e8 \'f1\'ee\'e3\'eb\'e0\'f8\'e5\'ed\'e8\'ff\'ec\'e8 \'ee\'e1 \'e0\'e2\'f2\'ee\'f0\'f1\'ea\'e8\'f5 \'ef +\'f0\'e0\'e2\'e0\'f5. \'ca\'ee\'ef\'e8\'f0\'ee\'e2\'e0\'ed\'e8\'e5 \'f1\'ee\'ef\'f0\'ee\'e2\'ee\'e6\'e4\'e0\'fe\'f9\'e8\'f5 \'ef\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'ed\'ee\'e5 \'ee\'e1\'e5\'f1\'ef\'e5\'f7\'e5\'ed\'e8\'e5 \'ef\'e5\'f7\'e0\'f2\'ed\'fb\'f5 \'ec\'e0 +\'f2\'e5\'f0\'e8\'e0\'eb\'ee\'e2 \'e7\'e0\'ef\'f0\'e5\'f9\'e0\'e5\'f2\'f1\'ff. \'c2\'f1\'e5 \'ef\'f0\'e0\'e2\'e0, \'ed\'e5 \'ef\'f0\'e5\'e4\'f1\'f2\'e0\'e2\'eb\'e5\'ed\'ed\'fb\'e5 \'e7\'e4\'e5\'f1\'fc \'ff\'e2\'ed\'ee, \'f1\'ee\'f5\'f0\'e0\'ed\'ff\'fe\'f2 +\'f1\'ff \'e7\'e0 \'f6\'e5\'ed\'f2\'f0\'ee\'ec \'ab\'ca\'ee\'ed\'f6\'e5\'ef\'f2\'bb.}{\rtlch\fcs1 \af0 \ltrch\fcs0 \b\insrsid11553206\charrsid8939224 +\par }\pard \ltrpar\qj \fi-180\li180\ri0\sb120\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin180\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \b\insrsid16335187\charrsid16335187 4}{\rtlch\fcs1 \af0 \ltrch\fcs0 \b\insrsid11553206\charrsid8939224 . +\'d3\'f1\'f2\'e0\'ed\'ee\'e2\'ea\'e0 \'e8 \'e8\'f1\'ef\'ee\'eb\'fc\'e7\'ee\'e2\'e0\'ed\'e8\'e5 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \b\insrsid1258943\charrsid8939224 \'cf\'f0\'ee\'e3\'f0\'e0\'ec\'ec\'fb}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\b\insrsid11553206\charrsid8939224 \'ee\'e7\'ed\'e0\'f7\'e0\'e5\'f2, \'f7\'f2\'ee \'e2\'fb \'ef\'ee\'ed\'e8\'ec\'e0\'e5\'f2\'e5 \'ef\'ee\'eb\'ee\'e6\'e5\'ed\'e8\'ff \'ed\'e0\'f1\'f2\'ee\'ff\'f9\'e5\'e3\'ee \'eb\'e8\'f6\'e5\'ed\'e7\'e8\'ee\'ed\'ed\'ee\'e3 +\'ee \'f1\'ee\'e3\'eb\'e0\'f8\'e5\'ed\'e8\'ff \'e8 \'f1\'ee\'e3\'eb\'e0\'f1\'ed\'fb \'f1 \'ed\'e8\'ec\'e8. +\par }{\rtlch\fcs1 \af0 \ltrch\fcs0 \b\insrsid16335187\charrsid7865094 5}{\rtlch\fcs1 \af0 \ltrch\fcs0 \b\insrsid11553206\charrsid9781973 . \'ce\'d2\'ca\'c0\'c7 \'ce\'d2 \'c3\'c0\'d0\'c0\'cd\'d2\'c8\'c9. }{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid11553206\charrsid9781973 \'cf\'d0\'ce\'c3\'d0\'c0\'cc\'cc\'cd\'ce\'c5 \'ce\'c1\'c5\'d1\'cf\'c5\'d7\'c5\'cd\'c8\'c5 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid7817483 \'dd\'ca\'d1\'d2\'c5\'ce\'d0 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid9578463 4.}{ +\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid4663543\charrsid4663543 9}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 \'cf\'ce\'d1\'d2\'c0\'c2\'cb\'df}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid14310684\charrsid9781973 \'c5}{\rtlch\fcs1 \af0 +\ltrch\fcs0 \insrsid11553206\charrsid9781973 \'d2\'d1\'df \'cf\'ce \'cf\'d0\'c8\'cd\'d6\'c8\'cf\'d3 \'ab}{\rtlch\fcs1 \af0 \ltrch\fcs0 \fs18\insrsid11553206\charrsid9781973 \'ca\'c0\'ca \'c5\'d1\'d2\'dc}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid11553206\charrsid9781973 \'bb ("AS IS"). \'cd\'c8\'ca\'c0\'ca\'c8\'d5 \'c3\'c0\'d0\'c0\'cd\'d2\'c8\'c9 \'cd\'c5 \'cf\'d0\'c8\'cb\'c0\'c3\'c0\'c5\'d2\'d1\'df \'c8 \'cd\'c5 \'cf\'d0\'c5\'c4\'d3\'d1\'cc\'c0\'d2\'d0\'c8\'c2\'c0\'c5\'d2\'d1\'df. \'c2 +\'db \'c8\'d1\'cf\'ce\'cb\'dc\'c7\'d3\'c5\'d2\'c5 \'dd\'d2\'ce \'cf\'d0\'ce\'c3\'d0\'c0\'cc\'cc\'cd\'ce\'c5 \'ce\'c1\'c5\'d1\'cf\'c5\'d7\'c5\'cd\'c8\'c5 \'cd\'c0 \'d1\'c2\'ce\'c9 \'d0\'c8\'d1\'ca. \'d6\'c5\'cd\'d2\'d0 \'ab\'ca\'ce\'cd\'d6\'c5\'cf\'d2\'bb +\'cd\'c5 \'c1\'d3\'c4\'c5\'d2 \'ce\'d2\'c2\'c5\'d7\'c0\'d2\'dc \'cd\'c8 \'c7\'c0 \'ca\'c0\'ca\'c8\'c5 \'cf\'ce\'d2\'c5\'d0\'c8 \'c8\'cb\'c8 \'c8\'d1\'ca\'c0\'c6\'c5\'cd\'c8\'df \'c4\'c0\'cd\'cd\'db\'d5, \'cb\'de\'c1\'d3\'de \'d3\'cf\'d3\'d9\'c5\'cd\'cd +\'d3\'de \'c2\'db\'c3\'ce\'c4\'d3 \'c2 \'cf\'d0\'ce\'d6\'c5\'d1\'d1\'c5 \'c8\'d1\'cf\'ce\'cb\'dc\'c7\'ce\'c2\'c0\'cd\'c8\'df \'c8\'cb\'c8 \'cd\'c5\'cf\'d0\'c0\'c2\'c8\'cb\'dc\'cd\'ce\'c3\'ce \'c8\'d1\'cf\'ce\'cb\'dc\'c7\'ce\'c2\'c0\'cd\'c8\'df \'dd\'d2 +\'ce\'c3\'ce \'cf\'d0\'ce\'c3\'d0\'c0\'cc\'cc\'cd\'ce\'c3\'ce \'ce\'c1\'c5\'d1\'cf\'c5\'d7\'c5\'cd\'c8\'df. +\par }\pard \ltrpar\ql \li0\ri0\sb120\widctlpar\tx1908\tx9602\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid3500467 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid8411065\charrsid8411065 -}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid7030330 +--------------------------------------------------------------------------------------}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid7030330\charrsid7030330 +\par }\pard \ltrpar\ql \fi425\li0\ri0\sb120\widctlpar\tx1908\tx9602\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid7030330\charrsid8411065 \'ca\'ee\'ed\'f2\'e0\'ea\'f2\'ed\'fb\'e5 \'e4\'e0\'ed\'ed\'fb\'e5:} +{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid7030330\charrsid7030330 +\par }\pard \ltrpar\ql \fi425\li0\ri0\widctlpar\tx1418\tx9602\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid11155375 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid10831818\charrsid9781973 E-mail:\tab post@}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\lang1033\langfe1049\langnp1033\insrsid10831818\charrsid9781973 ac}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid10831818\charrsid9781973 concept}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid11553206\charrsid9781973 .ru}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid11553206\charrsid13569699 +\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a +9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad +5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6 +b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0 +0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6 +a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f +c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512 +0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462 +a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865 +6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b +4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b +4757e8d3f729e245eb2b260a0238fd010000ffff0300504b030414000600080000002100a0bc18c6b5060000831b0000160000007468656d652f7468656d652f +7468656d65312e786d6cec59cf6e1b4518bf23f10ea3bdb7b1133b8da33855ecd80db469a3d82dea71bc1eef4e33bbb39a1927f5ad4a8f482044411ca8045c38 +2020528bb8b4efe03e43a0088ad457e09b995d7b27de90a48da082e6107b677fdfff3ff3cd78e5f2dd88a15d2224e571dd2b5f2c7988c43eefd338a87b37bbed +0b4b1e920ac77dcc784ceade8848eff2eabbeface06515928820a08fe532ae7ba152c9f2dc9cf46119cb8b3c2131bc1b701161058f2298eb0bbc077c2336375f +2a2dce4598c61e8a71046cc7df8c7f1a3f191fa01b8301f589b79af16f3110122ba9177c263a9a3bc988be7eb63f3e183f1d3f1e1f3cbb07df9fc2e7c786b6bf +53d61472249b4ca05dccea1e88eef3bd2eb9ab3cc4b054f0a2ee95cc9f37b7ba3287975322a68ea1cdd1b5cd5f4a9712f477e68d4c11f42642cbed4aedd2fa84 +bf0130358b6bb55acd5679c2cf00b0ef83e556973ccf4a7ba9dcc878e640f6eb2cef66a95aaab8f81cff85199d6b8d46a35a4b75b14c0dc87eadcce0974a8b95 +b579076f40165f9dc1571a6bcde6a28337208b5f9cc1b72fd5162b2ede804246e39d19b40e68bb9d729f40069c6d14c29700be544ae1531464c324dbb488018f +d569732fc277b8680381266458d118a9514206d887446fe2a82728d602f132c1b93776c997334b5a3692bea089aa7bef27188a66caefe593ef5f3e79840ef71f +1feeff7c78fffee1fe8f969143b581e3204ff5e2db4ffe7c780ffdf1e8ab170f3e2bc6cb3cfed71f3efce5e9a7c54028a7a93acf3f3ff8edf1c1f32f3efafdbb +0705f035817b7978974644a2eb640f6df3080c335e7135273d71368a6e88699e622d0e248eb19652c0bfa542077d7d84591a1d478f06713d784b403b29025e19 +de7114ee8462a86881e4ab61e4003739670d2e0abd7055cbcab9b93b8c8362e16298c76d63bc5b24bb896327bead61027d354b4bc7f066481c35b7188e150e48 +4c14d2eff80e2105d6dda6d4f1eb26f505977ca0d06d8a1a9816baa44b7b4e364d89366804711915d90cf1767cb3790b35382bb27a9decba48a80acc0a94ef12 +e6b8f10a1e2a1c15b1ece288e51d7e0dabb048c9ce48f8795c4b2a8874401847ad3e91b288e686007b7341bf8aa18315867d938d22172914dd29e2790d739e47 +aef39d6688a3a408dba17198c7be2777204531dae2aa08bec9dd0ad1cf10071c1f1bee5b9438e13eb91bdca481a3d23441f49ba1d0b184d6ed74e088c67fd78e +19857e6c73e0fcda3134c0e75f3e2cc8ac37b511afc19e5454091b47daef71b8a34db7c9459fbef93d771d0fe32d02693ebbf1bc6db96f5baef79f6fb9c7d5f3 +691bedb4b742dbd573831d92cdc81c9d7a621e50c63a6ac4c83569866609fb46bf0d8b9a8f395092c9892a09e16bdae71d5c20b0a14182ab0fa80a3b214e60e0 +2e7b9a492053d68144099770f033cb85bc351e8676658f8d557da0b0fd4162b5c9fb7679412f67e786091bb3fb04e6b09a095ad00c4e2b6ce152ca14cc7e1561 +65add4a9a5958d6aa6f539d22626434c674d83c5893761204130c6809717e148af45c3410533d2d77eb77b7116161385f30c910c719fa431d276cfc6a86c8294 +e58ab93980dc2988913e049ee0b59cb49a66fb1ad24e13a4bcb8ca31e2b2e8bd4e94b20c9e4649d7f191726471be38598cf6ea5ead3a5ff5908f93ba3780332e +7c8d1288bad433206601dc25f94ad8b43fb1984d954fa359cb0c738ba00cd718d6ef33063b7d201152ad6319dad430afd21460b19664f59faf825bcfcb009be9 +afa0c5c21224c3bfa605f8d10d2d190c88aff2c1cead68dfd9c7b495f2a122a213f6f7508f0dc53686f0eb54057bfa54c25585e908fa01eed9b4b7cd2bb739a7 +4597bfdd3238bb8e5912e2b4ddea12cd2ad9c24d1d4f74304f39f5c0b642dd8d716737c594fc3999924fe3ff99297a3f819b8385be8e800f37bf02235daf758f +0b1572e8424948fdb68041c2f40ec816b8ab85d7905470ff6c3e05d9d59fb6e62c0f53d6700054db344082c27ea44241c816b425937d27302ba77b9765c95246 +26a372eacac4aadd23bb8475750f5cd47bbb87424875d34dd236607047f3cf7d4e2ba817e821275f6f4e0f99ecbdb606fee9c9c7163318e5f66133d064fe9fa8 +58b0ab5a7a439eedbd7943f48be99855c9aa0284e5b6825a5af6afa8c219b75adbb1662c9eaf66ca4114672d86c5c94094c0fd0fd2ff60ffa3c267f6970cbda1 +76f936f456043f446866903690d517ece0817483b48b3d189ceca24d26cdcaba361d9db4d7b2cdfa9c27dd89dc23ced69a9d26de6774f6643873c539b5789ece +4e3decf8daae1deb6a88ecd11285a54176b0318131bf82e57fa5e2bd3b10e875b8ef1f32254d32c16f4e02c3e8d9317500c56f251ad2d5bf000000ffff030050 +4b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e +72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae9 +95719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757d +a0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d9850528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d00 +14000600080000002100e9de0fbfff0000001c0200001300000000000000000000000000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d +0014000600080000002100a5d6a7e7c0000000360100000b00000000000000000000000000300100005f72656c732f2e72656c73504b01022d00140006000800 +000021006b799616830000008a0000001c00000000000000000000000000190200007468656d652f7468656d652f7468656d654d616e616765722e786d6c504b +01022d0014000600080000002100a0bc18c6b5060000831b00001600000000000000000000000000d60200007468656d652f7468656d652f7468656d65312e78 +6d6c504b01022d00140006000800000021000dd1909fb60000001b0100002700000000000000000000000000bf0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000ba0a00000000} +{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d +617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 +6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 +656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} +{\*\latentstyles\lsdstimax376\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1; +\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; +\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7; +\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 1; +\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 2;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 3;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 4; +\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 5;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 6;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 7; +\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 8;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority35 \lsdlocked0 caption; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 5;\lsdqformat1 \lsdpriority10 \lsdlocked0 Title; +\lsdsemihidden1 \lsdunhideused1 \lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Salutation;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Date; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent;\lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdpriority59 \lsdlocked0 Table Grid;\lsdsemihidden1 \lsdlocked0 Placeholder Text; +\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2; +\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List; +\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;\lsdpriority61 \lsdlocked0 Light List Accent 1; +\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdsemihidden1 \lsdlocked0 Revision; +\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1; +\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;\lsdpriority72 \lsdlocked0 Colorful List Accent 1; +\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; +\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2; +\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2; +\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; +\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3; +\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4; +\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; +\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4; +\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;\lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5; +\lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; +\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5; +\lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6; +\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6; +\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6; +\lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; +\lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography; +\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4; +\lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4; +\lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1; +\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1; +\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2; +\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2; +\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3; +\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4; +\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4; +\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5; +\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5; +\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6; +\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6; +\lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark; +\lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1; +\lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1; +\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2; +\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3; +\lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3; +\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4; +\lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4; +\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5; +\lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5; +\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6; +\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Mention; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link;}}{\*\datastore 01050000 +02000000180000004d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000 +d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e50000000000000000000000004089 +129090c8d901feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/distr/app/Документация/Описание грамматики ЯРЭ.docx b/distr/app/Документация/Описание грамматики ЯРЭ.docx new file mode 100644 index 0000000..c470897 Binary files /dev/null and b/distr/app/Документация/Описание грамматики ЯРЭ.docx differ diff --git a/distr/app/Документация/Условия биективной переносимости.docx b/distr/app/Документация/Условия биективной переносимости.docx new file mode 100644 index 0000000..488b354 Binary files /dev/null and b/distr/app/Документация/Условия биективной переносимости.docx differ diff --git a/distr/app/Документация/Условия интерпретируемости.docx b/distr/app/Документация/Условия интерпретируемости.docx new file mode 100644 index 0000000..a18d32e Binary files /dev/null and b/distr/app/Документация/Условия интерпретируемости.docx differ diff --git a/distr/app/Примеры/КС Дружба и вражда.trs b/distr/app/Примеры/КС Дружба и вражда.trs new file mode 100644 index 0000000..5faced6 Binary files /dev/null and b/distr/app/Примеры/КС Дружба и вражда.trs differ diff --git a/distr/app/Примеры/Конструкты/001 Подмножество (Абстрактный выбор).trs b/distr/app/Примеры/Конструкты/001 Подмножество (Абстрактный выбор).trs new file mode 100644 index 0000000..6cecd35 Binary files /dev/null and b/distr/app/Примеры/Конструкты/001 Подмножество (Абстрактный выбор).trs differ diff --git a/distr/app/Примеры/Конструкты/002 Биективное отображение.trs b/distr/app/Примеры/Конструкты/002 Биективное отображение.trs new file mode 100644 index 0000000..521f6f5 Binary files /dev/null and b/distr/app/Примеры/Конструкты/002 Биективное отображение.trs differ diff --git a/distr/app/Примеры/Конструкты/010 Линейный порядок.trs b/distr/app/Примеры/Конструкты/010 Линейный порядок.trs new file mode 100644 index 0000000..1740447 Binary files /dev/null and b/distr/app/Примеры/Конструкты/010 Линейный порядок.trs differ diff --git a/distr/app/Примеры/Конструкты/011 Отношение эквивалентности.trs b/distr/app/Примеры/Конструкты/011 Отношение эквивалентности.trs new file mode 100644 index 0000000..af3d33f Binary files /dev/null and b/distr/app/Примеры/Конструкты/011 Отношение эквивалентности.trs differ diff --git a/distr/app/Примеры/Конструкты/012 Последовательность.trs b/distr/app/Примеры/Конструкты/012 Последовательность.trs new file mode 100644 index 0000000..3ff06ef Binary files /dev/null and b/distr/app/Примеры/Конструкты/012 Последовательность.trs differ diff --git a/distr/app/Примеры/Конструкты/020 Группа.trs b/distr/app/Примеры/Конструкты/020 Группа.trs new file mode 100644 index 0000000..cd7e5d4 Binary files /dev/null and b/distr/app/Примеры/Конструкты/020 Группа.trs differ diff --git a/distr/app/Примеры/Конструкты/021 Поле.trs b/distr/app/Примеры/Конструкты/021 Поле.trs new file mode 100644 index 0000000..e773ca2 Binary files /dev/null and b/distr/app/Примеры/Конструкты/021 Поле.trs differ diff --git a/distr/app/Примеры/Конструкты/030 Разбение.trs b/distr/app/Примеры/Конструкты/030 Разбение.trs new file mode 100644 index 0000000..32dc6fa Binary files /dev/null and b/distr/app/Примеры/Конструкты/030 Разбение.trs differ diff --git a/distr/app/Примеры/Конструкты/031 Топология.trs b/distr/app/Примеры/Конструкты/031 Топология.trs new file mode 100644 index 0000000..1ab4ba5 Binary files /dev/null and b/distr/app/Примеры/Конструкты/031 Топология.trs differ diff --git a/distr/app/Примеры/Конструкты/032 Топологический фильтр.trs b/distr/app/Примеры/Конструкты/032 Топологический фильтр.trs new file mode 100644 index 0000000..29ea8d8 Binary files /dev/null and b/distr/app/Примеры/Конструкты/032 Топологический фильтр.trs differ diff --git a/distr/app/Примеры/Конструкты/040 Сеть процессов.trs b/distr/app/Примеры/Конструкты/040 Сеть процессов.trs new file mode 100644 index 0000000..26136f9 Binary files /dev/null and b/distr/app/Примеры/Конструкты/040 Сеть процессов.trs differ diff --git a/distr/app/Примеры/Конструкты/041 Фактор-структура (логическая).trs b/distr/app/Примеры/Конструкты/041 Фактор-структура (логическая).trs new file mode 100644 index 0000000..397742e Binary files /dev/null and b/distr/app/Примеры/Конструкты/041 Фактор-структура (логическая).trs differ diff --git a/distr/app/Примеры/Конструкты/050 Функционально-методные отношения.trs b/distr/app/Примеры/Конструкты/050 Функционально-методные отношения.trs new file mode 100644 index 0000000..e3b27d0 Binary files /dev/null and b/distr/app/Примеры/Конструкты/050 Функционально-методные отношения.trs differ diff --git a/distr/app/Примеры/Концептуальные схемы/0001 Начальники и подчиненные.trs b/distr/app/Примеры/Концептуальные схемы/0001 Начальники и подчиненные.trs new file mode 100644 index 0000000..c4d552f Binary files /dev/null and b/distr/app/Примеры/Концептуальные схемы/0001 Начальники и подчиненные.trs differ diff --git a/distr/app/Примеры/Концептуальные схемы/0002 Генеалогия (рождение + брак).trs b/distr/app/Примеры/Концептуальные схемы/0002 Генеалогия (рождение + брак).trs new file mode 100644 index 0000000..c1cc738 Binary files /dev/null and b/distr/app/Примеры/Концептуальные схемы/0002 Генеалогия (рождение + брак).trs differ diff --git a/distr/app/Примеры/Концептуальные схемы/0003 Теория субъектов (реализация без альтернатив + блокирование).trs b/distr/app/Примеры/Концептуальные схемы/0003 Теория субъектов (реализация без альтернатив + блокирование).trs new file mode 100644 index 0000000..77718f4 Binary files /dev/null and b/distr/app/Примеры/Концептуальные схемы/0003 Теория субъектов (реализация без альтернатив + блокирование).trs differ diff --git a/distr/app/Примеры/Концептуальные схемы/0004 Морфология - деревья - состав изделия.trs b/distr/app/Примеры/Концептуальные схемы/0004 Морфология - деревья - состав изделия.trs new file mode 100644 index 0000000..d38e7d4 Binary files /dev/null and b/distr/app/Примеры/Концептуальные схемы/0004 Морфология - деревья - состав изделия.trs differ diff --git a/distr/app/Примеры/Концептуальные схемы/0006 Друзья и Враги.trs b/distr/app/Примеры/Концептуальные схемы/0006 Друзья и Враги.trs new file mode 100644 index 0000000..7ceecf7 Binary files /dev/null and b/distr/app/Примеры/Концептуальные схемы/0006 Друзья и Враги.trs differ diff --git a/distr/app/Шаблоны/RSFormTemplate.dotx b/distr/app/Шаблоны/RSFormTemplate.dotx new file mode 100644 index 0000000..20eae2e Binary files /dev/null and b/distr/app/Шаблоны/RSFormTemplate.dotx differ diff --git a/distr/app/Шаблоны/RSModelData.xltx b/distr/app/Шаблоны/RSModelData.xltx new file mode 100644 index 0000000..f56b291 Binary files /dev/null and b/distr/app/Шаблоны/RSModelData.xltx differ diff --git a/distr/app/Экстеор - Стабильная версия.lnk b/distr/app/Экстеор - Стабильная версия.lnk new file mode 100644 index 0000000..8a56026 Binary files /dev/null and b/distr/app/Экстеор - Стабильная версия.lnk differ diff --git a/distr/app/Экстеор - Текущая версия.lnk b/distr/app/Экстеор - Текущая версия.lnk new file mode 100644 index 0000000..fb4334b Binary files /dev/null and b/distr/app/Экстеор - Текущая версия.lnk differ diff --git a/distr/design/Exteor.ai b/distr/design/Exteor.ai new file mode 100644 index 0000000..efe57ca --- /dev/null +++ b/distr/design/Exteor.ai @@ -0,0 +1,548 @@ +%PDF-1.6 % +1 0 obj <>/OCGs[19 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + Adobe Illustrator 27.6 (Windows) + 2023-08-06T11:52:00+04:00 + 2023-08-06T11:52:01+03:00 + 2023-08-06T11:52:01+03:00 + + + + 256 + 160 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAoAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 FXYq7FUq8walHZ2jAyemOJeWQmnGNdySfoy3HEczyDhazNwihzKn5a1aG+s0KSeqjoJIJP5kYV74 5AD6hyKNFm4hwlOcqc52KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2K uxV2KuxV2Kpf5h1q00PQdQ1m8PG1063lupzt9iJC56keGKvO/wAmfztl/MqDVbwaMdLsNL9NGneX 1PVkcElFAVfsACv+sMIFsZSERZSb83fNblP0VC9Jrqkl1T9mIH4U/wBlT7vnkNZk4Y8Aee1GUyNp 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 rsVdirsVdirsVdirsVdirsVdir//2Q== + + + + 1 + False + False + + 296.999935 + 210.001656 + Millimeters + + + + + TimesNewRomanPS-BoldMT + Times New Roman + Bold + Open Type + Version 7.00 + False + timesbd.ttf + + + + + + Cyan + Magenta + Yellow + Black + + + + + + Default Swatch Group + 0 + + + + Document + AIRobin + application/pdf + + + Exteor + + + proof:pdf + xmp.did:fff4865f-0a00-804d-803f-69d618f9af7a + uuid:a4aa54bc-047c-43fb-bc6d-d7736282f26e + uuid:4acc53b5-3f9c-4c17-9e62-e9b73cbdf87c + + xmp.iid:f0e5b645-624c-4a4e-be56-46d5e9d248a7 + uuid:4acc53b5-3f9c-4c17-9e62-e9b73cbdf87c + uuid:4acc53b5-3f9c-4c17-9e62-e9b73cbdf87c + proof:pdf + + + + + saved + xmp.iid:fff4865f-0a00-804d-803f-69d618f9af7a + 2023-08-06T11:37:13+03:00 + Adobe Illustrator 27.6 (Windows) + / + + + + Adobe PDF library 17.00 + + + + + + + + + + + + + + + + + + + + + + + + + +endstream endobj 3 0 obj <> endobj 5 0 obj <>/Font<>/ProcSet[/PDF/Text]/Properties<>>>/Thumb 23 0 R/TrimBox[0.0 0.0 841.89 595.28]/Type/Page/PieceInfo<>>> endobj 21 0 obj <>stream +HۊG), 3-`0_H{/EfdUVWKBZz"2?n˫onfy~}[.fo;˯m,Vg]|h会Z~d0i?:y3E)]OuZVo?>`5H˝_\k21N떔֚FcDxD,m83hF?7!cOSb{C3$f69ޙ +~aI\+ـ`r(JX;!6\bw{55ne17sQxIPR{3M#g D1d!sǘ@l@|wGU%wLōp9f9ߏhԁ؞Zӧ62ۚp0R$M(~&?xʧc_2;08%WK ~?]ԈR xp^TP{v|3&s3,9~"ydʥ4Qow`;4b8؟s\Cjz! p/XJ@-Y?kk\]YJ|]Jb/qR "ޯ>˫MDKƟ*PLK"&L+\ 2" 1C=)lŠN /tC|¾Mn(}l~f\x Β&QiQI&HI3$!l +fLPm:Ϊ&+Qx``)2h~8I:=MuO1i:&j@e`HӉL P)*$26!Qy5SJ 7rآd@S~bPeR*Ft9/ +JbKo/]Kms;25J4AEBA$/EAA5-?+a{+gSCIztx`JA([V{{pX,ahd]4N P)H7Fstm\;"!;*˂gW0 ++YkCה,`Pi2\s78^)t"7&cRRJ|3dM[~dRL.J&i]EidcdL@DQS,?)pS|)ةpdhث4̸t`Skle#˧we{|]Vw9{r.yzUdHgܭ]76k;;5I{^ekifLNNtvã4݄Tp/m꾭rAB͗, 2Me]t$v5gF xs!N%I.n#`0,mk̠ +:0(O .J*P8vznU|J!W-4 ˽k_,m'#α$6|K4C V'*bOx겉4OQ9]YsuOMѢB"P> Όz}-{We_"bYLRacJ˂DPP=#ʑɴ hr8RhSx)5ʅF*X͠bHd7eBoFcƝ \Q}7Ɣ!JKQJ B]"68Hw .AHiz4RVq%_. ҁrJ*%)z=){@C9 (ₔ*`! 7[Tlf)@DVt3Vjvq#^7?,{,!2 +y:a^ [_k (qm/X+yY⩱ Gyrv<ѳwc{t923.-&s1)soʓ>ɍܟۓUœyQ=즵g97nBkym=*f 0äg6.i2Q~:77*bx o7{ aN2?P!~zTGfnOg!q}k +"q}"r2y=$Yyê&?OR!>\Bفyu6ƃlLC6"˔~FhyQK3lń]U+2- +(20:y]s;88s3Yfb0%;39ZJ1ɩYB|e$i&\2)yb~|8`qJ>@W3vG7 0d +endstream endobj 23 0 obj <>stream +8;Z]"d>`c4%#-p^4dA$P1/_2aJ`)An4A=>:^d2Hla^$#+[8MHQ'V[EkJ(lr_F%oA' +9he>V9he?S/=LGXNATM/R0i*n&0[(r,QOI1!=(jYZ330+Yoe8sl[pKs*q4MrA.)Qb +LY`W3K9k7c'.kpq#!kN.JKTK5C"92-=b:VIIA3k7X?b!!Du(N[@PDm\%Z%FUCq@.F +g?_O>MpA3/P!=`qSS=QbYCqiA6$)dFG4K/(kc<06c;EZe&8:>MqKaY^iMdMJdF,Mc +k:.,m\ +p8"Hm:bqZ(90&%Q`.,%nJ@J(K*%;HZj?^r/r_O#T"K4 +endstream endobj 8 0 obj <> endobj 9 0 obj <> endobj 10 0 obj <>stream +%!PS-Adobe-3.0 +%%Creator: Adobe Illustrator(R) 24.0 +%%AI8_CreatorVersion: 27.6.1 +%%For: (ArietZ) () +%%Title: (Exteor.ai) +%%CreationDate: 8/6/2023 11:52 AM +%%Canvassize: 16383 +%%BoundingBox: 77 -58 809 390 +%%HiResBoundingBox: 77.6225999999997 -57.3330000000005 808.1728515625 389.766590153668 +%%DocumentProcessColors: Cyan Magenta Yellow Black +%AI5_FileFormat 14.0 +%AI12_BuildNumber: 210 +%AI3_ColorUsage: Color +%AI7_ImageSettings: 0 +%%RGBProcessColor: 0 0 0 ([Совмещение]) +%AI3_Cropmarks: 0 0 841.88957873208 595.280284961955 +%AI3_TemplateBox: 420.5 297.5 420.5 297.5 +%AI3_TileBox: 129.28478936604 -117.319857519022 712.60478936604 712.600142480977 +%AI3_DocumentPreview: None +%AI5_ArtSize: 14400 14400 +%AI5_RulerUnits: 1 +%AI24_LargeCanvasScale: 1 +%AI9_ColorModel: 1 +%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 +%AI5_TargetResolution: 800 +%AI5_NumLayers: 1 +%AI17_Begin_Content_if_version_gt:24 4 +%AI10_OpenToVie: -310 674 1.26388888888889 0 8082.1978021978 8196.52747252747 1616 948 18 0 0 46 87 0 0 0 1 1 0 1 1 0 1 +%AI17_Alternate_Content +%AI9_OpenToView: -310 674 1.26388888888889 1616 948 18 0 0 46 87 0 0 0 1 1 0 1 1 0 1 +%AI17_End_Versioned_Content +%AI5_OpenViewLayers: 7 +%AI17_Begin_Content_if_version_gt:24 4 +%AI17_Alternate_Content +%AI17_End_Versioned_Content +%%PageOrigin:0 0 +%AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 +%AI9_Flatten: 1 +%AI12_CMSettings: 00.MS +%%EndComments + +endstream endobj 11 0 obj <>stream +%AI24_ZStandard_Data(/X<* ?JD r5SD3AF|@ UM>M3޿VNIM& +ţR < ? u zpen kmn\so^t7Ld7|/qc\-"oUDZʟ#jkk{iz * p@$@pH` P@ `H05a3Y=o XiYvlӷְHo9ʾ,4~\ם٢M_8& [aM[׮ D& ;-`6y='9 ؕa0[|kLD~kEo9&4ל u]XѕgK_0k&?g\Cn n=܏w563,ҽ:˳,i]{a;nu v_m4o1Ltyu+G4֥Ԯ^] 0,gñ]Y_e g v9Ӵݷs.' s47f̅0'îL&7~N9ٍi6#mD]v1Nv9 pmN38{?_ܷݵ +w:GPJ?KjS9$÷W瘬274W/p&kݛaf ]jSR zרbH$^r^Wnɚ׼؝]_Ҳhfdx9aF|ר bmUe#X3 3RCoqz=0kHL̞3ڕIv޿ o35_MS$vt~l<'6 Hl950k@˖-w\v|;3㿳;:l6µ̥m٭oԨF7wjTnfwj^s]ݷeu繈/9#Wo_]tx&Ypr-Qݛc86ס | ۯd3z7F\|C\ p$X@\s@$@$p@\@ T?nGtMe:cCcg˝}M4Mh[cwm_VmKs |9ܱ鞋ICܗ7v8 ˽׻Fn쾸߶[^{y@28<: 4bB"GDaٯ~LfG1̾e`ۿ85m0z.'[ dxfò{cz5I=eYd>.v3 M#G]쐳CD@@Z޿a?5s/ sZ^0K2,!{YBD^0ƌ ۦ817|{rnh + M +n: /\/F(^#8;Gr 6/8^0(aqN2"pcچ׏p}FMr( WAxIL\uO!mYl9^0z=FN!]yoCXbå1cØc1ob &`۵`M_ F !728vg1ձ`_s?#ǐgY + '30˜`&ݵzrqs޹s_ +Wf[c3m.q#o /se9f6ҏa] Fkdc|ڝWtm7|#qe86P<ϥxK̾hq^P8t˰۩]ٍc-~v ,']|>m?D? zܯàaW8Lan]>q~ Ľp=߰ +9&k\2,šV2\Ӣ.qJGUda2K.6ɖ +7X0xwǂaqvxGcaw]unQYiLL&8b[ 4@ X0|j4FòcxYup:sv,vg_ߵ{}y#[< ndsc=o=7ٷ  ף<06 ~=F#,. !2,õ{k ȣ ?m_90 6}K#g?l?w= ڭ׭1|8Wg2.؏Ͳs,hc?lڅWv|2ze߮\;V[p2ҹHyr蜇oGG g}G8ΝΕ;$>%Ӡ%Wz-kh-[/-}K n}g/Rn;{0җnUIMo#˒tj$ |@N)}9C8M9;)Bzwp%<3)#^<}aS3E1]%<,#Gh&ងD شڭs@p@$@$(`  @qNbiGĖ}җ5M Q|kZd]vvk1ig`vȮG)#=cp<  ' <``|p~1W0t!B<'gخѨW0pcַ}c Iv}񼂁"UPԹIܾ;6=*aYIŬVz+?r] Iju(xqզRjKdIO=vsp=cUKVUk8x1/tN):բeM1~("6ZJRrA/y[ \ ;CsJT!;`Pn$I*a;M6v&nYp +}&H{+>cwgd˻|gy_tg0,N+6LlaYogE+B"W"$0CΪHU}P~G 9ة+nuA;L:3TؠĮOG{p!"K &`H"ULH$Ah\`)=2jZk +R)!arOq;!"^ +Dٹ| <}RһYeS{-{~ۋW[ORP(TJ:ܾ C"1:2NB|,!H|21L(*U2Ԣ >~P-B-JBW_lte8r?)GzJ*T6m+v&MKW0pzeS;$ r R,[s#xl^Z(lQ&Q!xhY('|޾4Ÿ4y^x<۷g uf+1.q1$$bY!b{H,Kb;Y/j([{P4\_ȑҸ 1Re]e"QHk^ᢋA`Īǘ^/I#H48{Cn5*HL$:!FBa.{L!Ԃ Gr鴵DiQX5۱cJ:aVHLd̛avp1%o H 3C/ +$Qzdc#K{jVFYgCY@CYR(ʓ?I$1΢,( = nس<'=Ǹmբa_Wbuvp]-bNcQ:%:. tDm h4ݟ&t i6+hEM F |LjeRʤqK]~-Z%T!;C{ +ى$HA$KrSLW064Mm|(I Nlrb=5 tEA R3߫G$(دI` +(#{*#+C-glZUXn>#̞!۵(qP_Ghuu־[+Ctv8i#ei-B۞(fB6Q@`,`5+8F{X + i+[]z4-lp\j+D2_e¦,ۣiFTg>t?Ƣ .d$:=g t RX:59 ׭htENL,~X(AW0\؇g€w*ىoT%3W0dT"ռ+m'-qQ!N$nڅ[# Y`t~ypWʨ+' +Aɂ +XJ煂5&4k/)n/Y/!W,1UH`9!Enxy&H*GD(g$AbfWX8>G|*5=e*5NZ%`MQW0hD7MúGUBX+'rce W0J k8 n 6u4Zo ,~⫪ +W!i`M`0ɹ:$ *m"'cPDn+ Z[Q4!H!|4 Vaf +0;;"9ED-=F`0~GAIҌTŌ Ms b]Lc!#c&.JF"*6l9CXĂ?wxOTyF{ƐʋEZq(`(bۊ"{n򄝋v,vՐ5ym Y\ hCD7>"sCS*D]p)0^p<2*@͌ŀ1s"J8ŭu} G]J$Qީu_G,mHfqhVϞ)lK<6 +d 0 v6vSH=q̂X z-AZa[-FG# +6& + +A|G>:MEGBf%O3)ELLGvý>0B)1 { Rĸt& Y])av$G}Duk`@P#%j_lW{8ӨESLH#FUjX˓6ɘ(V+W#BEfBvFEJo^&V/љzI8xhV2Bdh[-wBNDDTPz8rU||* eΰBRGN wԻFL`{anS"p\&R+^rfI̲$WfIC. fL2noϳsiڭK| ?\1_5'̴]07~bGwpn,̘(8h4P+6V Euѭ Ԋ`ȩik4I% }P| d 0,=URV${-K׭vu*,+UR8w!!u)mFְ j\jA#Xj haLJCv J]KQ?PB[W 8%Q@oNP![V3ff9A|zm &]N|rƵvpA&QLťeh8-j'@tPJnVViU £γ3Ja_Q_-K}xy*cuھgKfȣ.6rj W5L(4R$ !2QU2;Ƒ[R(up;2A2QAY9& +V8/Z1X\`Ȝ (8rL)! :p(slI%!,(x|(^bK~1Ș(-W>w\P]B +=x$Lۂ +ϣr0T*U NFz{͉zKGk!•ptSVd`YLGFj_6r"ڄ,( +quk +%ITF~@2B#MGPh5HeE&4A# ֙*dd5E?& +r 퀉Lpt`1L|)|y7\2瘨,e8Gha\ 26#5GnQ!LRD21|fZAC`A#/خ ZIIut̂`v2H E.KȌp~\CAC9FK=H,t!Ax]izSZVjCYxSD`7ZN:SP(輂sn]C8ybԄ)f}Km?%~Vwyj#Du6\0>pÔ#a>Dm$7 24ҡhihTl?јrCb+qj`XC -a&s0I +GʁxDVY !2FUWvHTggV ^` +' +` +bttX->0ͫ GXO3-M H}zBVX=OEJؖ 1 (ub +l.A>F4W0>«'J?M46Ї($7ZlDY+һu5gYFnw(PM |l'i:f7BJ]ߍЎ({($#oJmTV`zez!.Rs.$rzj$? !;%g@${gx>$~4 2S X3鼺W08P\Vؽ!TA +_`EyJ$;:4qt V$bt-8@:c Z=3*HaFOid[%5¦W0` F h)aq!; +L]vĵ5[MF ER9r`h\.Z/A+bFKHdW0h/\]؅u2(OؽPRut$ ;m ^t^rD fanS`~`;3/gV,r tyA?ԣzg3vQi8.^p +Cb +[.%^HJD+@cWI8\ ͸Ls !E^mν)F˄&hYq] rUN*蜪`GPRufNm)fnW0?C$'Z }b=s8Hw[8(!n׊!h 4av^!C2^æG X5uo(Lo#,POCoX_h8.?N +!O=£Z q +<._Ii`D +һ__F4HI.4QQL2MdZdXm_ +/:Y} V4}1bBKF_[ 0?R+w\JޥJWkydW l08EVYޟ{á-RXgR4|.oCƻ)P'۹|ubI0 dzF; l#' HBxK/두W@B4Gzy"(7-UTBACJ>S vB0xȘ +b#򨦳īHv"Jm3t 3ZwynYB)#D]X%),cx- 7̞$g.-Z +n$z tyua2qfJ彂aG^mLDVM| T$ujO] !eD:Z,3^T O0PZK ~GRK +7Lǻ៘Ōp<3IjFj#JE1£Rʹ$6^ZE[HD0 +ƮTieҽo<\=8+%Ha.aOS1 nzp~@>HD^PKxa{@/K(DWlO/! j=JnTG6b*f/F@R"x vR IPcpU~iãey5~TuW_:Sz!vȚZQ ^Z$]~Z\_( +L+#8",2'.˽3+8A \l.K^3U=O;W0>Ym$`uKVfґLpf@tґD8777IE:V<WEmTIG5'{!_IMҥq*`9Ǭ$|G@D\).eFuIy-K:HɒC>ՑK$eYY,;^$e n 1sF; Pσɥr0(J}xL9= \3V^t E%I%a&Xn4 Ł|B\oh“iHFܓ6+Te&;JŸ@a,~!t^bd}"F qo4σET>X̩V*-="a~ kZRz 6 gґrjĽf@%]b",RiAlR$&{಼N0=+AdN +:P#mtґIyQI>C 搏iY$Adrl9 ƭ/f-^b*J>L2.  +8(šFaDQ9Wui)9#n_4YK*WA8(AJ%1)`T٧x+UuҾ6Lt}Lk՜`ȡyiĖ/`eJJE0V`4(0i6B,5DJ+5mvҙ7EzۤM{T\.6;j *X;@%k6FA% _\T Hx5@JҏH!g 8EhI T-g(c2 1GQr+mYHz ,aw >Wc1+j1H =ڢ~M0D +o5mX1KW( )#1axUCިZZֽBŠՉh/@>.r~BU~pKl˘&C`pZ _ |V`sM T &q*t)cS7fc(6AgOT7ϋ=0vC@F4P$݁ZVR((CP|Q PlQh)>ͥDi]/֨ږ3km-ǟY ]ij&@7kjK[#;i?s H eFEyDHF++| W:ο.O6|Ct.2=I-F +ݯ0F#?9zmgˎ^z8oY*lw/ҧd2,|$Fwzi]-Q)teL{UA!\ aN +p7QM KDI`n%Lԩ씪Ў|R:;??OXɛS!Hz֦6ɸR(CtZMo(&|Ѱg{`[ÿd6}BP~'fGCpB^[6ih6 +cV6ʲc\[_ƃ =* ;A3h^ piZg/*?LK_6@p, +8W#@4An툪'Tn,5yi|6'Z[O'J7bXiRDA6+P:C{&3&S/,~ 򤲗5XD,7ӌ~A>QiXyޢ:خus(>1FPMHw:ib鹸DZ]QIf$RIo.f+ o@2 UyֆӏSp`db}M 8ZG+ QoOl[T =6~u\?ithޫ>Qlq4QK ౉lJ:(^3hf]iR;(ĀeYv4DA+s:>-~{5w'5R>]Sوta+P$DIN*YCa@ b:x\_kI;\@޷ 8bsvSt3BM/ 蚎JX̀Ɋ:w4˂PcQ lD3sM۬3  p9;fh cL)Jzd]`Эf|pu,ij0n*1@Z`pAL/xa!pҥguޑ>GFK3Jbn\\R $ +/Iо_Y1Y :}bg%;zNN/Y7K] KU&/%Ko:CҦR΍Jp}k-kZwBMeoc}XrOMjF'4p~'Ԉewar*=rHdi8$ᑽSpr@M6P [QLIIï@YFRL#W + bkW8†C?Vω51Y;kr&6( +`}Jr"2 2?SЖ"]jY^bnPL ȯǢMT< ۏ;ѹH )xR?":tRa~=*p>zy9z>(PuF Y(@سɁZ`мܔ j]9u~dz{Bwb1!7<qzJ]peJ"8:z+J4XV¹A쓋< +BXA uGi\f@?^+7at%r:f9"no# ߏbK)ڛ;RW)Ȉ0e/- 5^HHj>%VR)bȰ_.1R\ aZ$[Ԕ*UmjײK$8<E7MA\SOI(Ԇ2NIOD'#X440 #/Y /+ҘP+Dhx3ۧH񧂕(I4EӐ!6ޗyb1938rH,|g>m;aSJkӐɷJJcViV? C0(#I$hCU䬨B3`O%@/7#S$8=SAܰBD'\gxc8l+4\ G^`WOOGrYʄ ިaoxπgZ)TU =+gq' *|"38\w:I %sơ.up__Kcuvh^l VpL4u:BMo{t" =QN}ԟcA"a뿋cqإ>oN5 +z_x&c!ĭ:SQTyuw -pB TN<,k푅6f:s\'A%Č v S`iJSRFTBT;\,cF˳!`o"S `@!g ޴S{ZPFnIjB @!) j,֨hIEٽLLbNhey2&^%]a͕SME鮎,`K(0*Jm6ʆnIk* wmA(ȦTD臚WT'[@<7 +Fbzg%Д!sOn7P¿I~"ס$g.m|aQ ںgyWLDkbGܹȘ[[1G(uD͎b_eRXHKc{NByȅZwmQ WayYrQ^f9phҙg涘lW? Il 41 V0ү<9VHj^ԕIDPf^7v͏: τh9VI(Eޟ݈ U"_bʯYCg[ᱹ4Au'ƐwL ȰJsg!Gג^p?^̀F/w@y`YԿoQst*e_G7 +!Cap$XVy`LCWM2ۤ\oD'׫"_MA p5QRI$D߶f-/mŨ 5%z^0\aOu܇JUr7.o3i(aiL±LӈpP@@@94<8wOj8 +=6,uK5j16ؒKrS!P6XGB(l- +=$1+nhoCQ6y@IRmYfتݓ;f3"Zs'NJ3b#ͦݸ#IG(KK9kܦo $pǣ?d[u3sơU-PJlíW%W5^_BcO() k*M‹^pB4m`prm*&vVėIYXOa5*VC kDWlUM vbnq{BZ<< )\8 q:$7Ev+•_ $Ό\~=U0r`_]?t[qqϱ!A`}$ɓ0…$׼pKtDRMO֮(kP5h8"ڷGb/9șqyXKjv %WT$ - jyK;@:awv1;]EZOB]Y.ۋ  hw̛ 4 ;O+ھ&'n0,pRX.3zF/P [Z' 8#Qv x:kTTtu r(Z$pXA~ aDxa(E/-J_4Ů3s3ͅ؟z+\q)bu5,f=Y 9چ< ?xGwqI +KRj2s QEўK +)[dIM\q +n4^-XCw1ƗTr+=9q6bI9 +ipKJ 41KʽYɋgR,AnҰ5~}jSuS|\m\bOVoX%LF]` *Ǩɏ foV5Z; ȴaM<TQfe4n93(O0X&ʇhU򉕤`.Tw`T +̯u#B،=)s^S15F*"@.VdL]CU-$O 8.x2[жxP&2AV[vPwm$11(y՚` m,l =ʳ @{/P;g}J6 gObO[Ф< upzMjwcEiRԖ¨T85RB;s㫇)YBwFH-]POќcji2(eYVF3 +BRcW0+OI""O ̱A <hkU0mnܞ=A4TGoԆq-x{~[-4DTExWl-U#^)p?GfAԔL /\Dn<Ck{x;ZB"+?Ԅ Ggn'(˃*v?|rMZZ vv |V3/`2dbY+9ձ g6 +ޭֳI%pqَ{LsAR1u!UD" V̾]Z^wSXa<ԇ8Gle ]t#$yN#E2(|\`x[ VTM +vd IN4`|4"$|4Z 8xvXq\` Dd1ġP@Dj&trG*r0Sf =ܶw(=L2)ٌA7BL=.SiE:~A/:jJ {c3K!eAN#rZ6CUW̩\8jo :n~%/G0F!-hgB,iazιǃ +w w+_BlBf Qb_%7Th"!X3Ӑ?y / j |+:Ĵ,{@v!'3UC*f}?w?qr.!ܧfAYmѠ( +vW.\ D!EUBWp-p\װ4n[xG=\W Lm JOw1 |`.K@[uQ Kw u^Q*|x8G(lN˃`Z0`ob3LU@@. + +?\3!KEfOs!PmB!-_RA T_ k zd>6W( NM~mwD61<+l=4s$զP ܝ`g2:Μu%0oe-JAZ} hLm1 +(saO4I)S +{ *( nCХxn%z[_كPّ)wJlғ^ ]6, qwuBq;(^q)HlO!/A*cV{ *"$1^3:^{+*RjӂٻO#lZ@-2ҁ_y"g:Uq r 5gz{%|3XR|I1{\zzL8Q3\9?YӾ3xÎfp+yA58)bSeAelQjz xGA[D#4g19BnhTM2-6SS^tO[ʸ;B p.I̺źR3fd3HW/~3pNƎx)7x_J-6Dm7dKX \@U %.C8{c/t$Bl& KdܵxN(qGXn { q3Gaϴz@@D4.b^|\HMh.$sC] ?t +E&j9:KSUl'3 (;Itgq oxN!D NTy, +`f(E;E4OXg!3ѸH`hdVn_7꤁ԝ>Nr68kE*U*c"Z\s%B+a| QoZ"BhH[:!.# .ۦ4'7 0ݐ*^мr7}$g} r@ApBxʶ22&@#l |ѳ^Ƚ _Dg>Fk3\=7f ETtb)86r>:V}>ĉATisb 'a@/CQwF+ +?HtМa.BpYRe^;6|iN1˙cX8G5'_2|sg+)\I:N#ӛ2J54';i_P?i\ Ո1RmPvnx"N86p4w18Ю s +^gNQ/u$d\K]^p-Eءlޮ,pw['8?s"V; {ң?p m?> 7“eҺj= +Qx6ў~_DƳv!:s vu7D!DY~QJ;q4X9pp| ?x2F0t :'TJT_Uvʑ{/gp.?M;n?whu0p.F1v,@ ! +UڨFe?k/w{j5Ŭٌ˸bs9 +ٟl?ɳi KFs _GE|g"Ky N4%,%A·bN EX"$q:6R͙:353nI/N[5vy^U9ԳLo\D+ۭA`K[ ٻ&B^ɸJWIt7e=kFGPߪ >z_yo@;VW%B~4GZ +' ϟ/I_JR PP6G { z[7^;db{h;q+*/K&ԙ $37i"qj/j=1{/NG/_!Ej{Y|c'H-!5(є%8~ + b"-k^\s5< )܂ uzl5A~>}Ly >Z;pkPRrLi0\jA +kEMJ +ݛt߷(?> .Ϝ(:~O Ѥb f%2X!eY\%}ɦU/=@03~m2|t5w3,3HC"] <i:"3f[^0*S[JѸ i^@*hE kl$?%D{4B4YmR=2[9Z36WXMs5=JJɄK|pl*ogH@~0fyx0>ygW % )-_DzmMtp iNVi+%| =V; _H7_J4AR[|inEl1 \e0Z1dn .ǫ˔}6ujz,qMo8"Kt QQyH=ޔQ-{=:դb!Gi?@B J`KPxtCb[3Ay*))㇂VrƉc=)E&>-bՏy =RQ)N. ]1Uu/( ]WrzTh +Pve !NźJv +KK Chy4f.2Z +ihLoӾ sυ7fm,YsNiwAi&~xEFl));pJ 3KG-|\(_|e* ZhPz s[xvoE}`}:uH+pH>C0u6 940O2'@q8Jizq}삖[!?,DIe8jeH B-AKi|Dq%h]nZ%6w6JʩYOCm+>iՒnTM2#cA^W}^u͑e23ZY& >GC=13+_(|,.XIhTXz x +VaπҾE([&YS2>ib[s*d(*ׄgS' Ғ+]J[kcJ8 8M7f>";oƕLx~O~8CBl `8JrEzЀΟK"SdۙyXsѧ7!Gzޯ9iUՎ=_x@p;ym+hJ:GJquye_Zk#|Nc/'т,SKgִBMYiv#yBl\wZ`&L$ԅQX>Pw'TR4kYG9``f=^G.&痠"s8N-b9lwLO$īI \,t|%j  8@-Yި[GF V_Bq7O['kj9B.ZE3B x|YeA9̥>?X$`ٵZ>gb{'U`K܀ߠf0Gr9~(hGK P[ٳk^XjX`i#A]OmO&]+S=eѩ{ݙ(8%=N<6C+rypPUzH|tbg= B03'#E_ӳH@WNoFhz >Fi8!ԭWaycҦAqsPt_$P^ l>gvq7N'.*v%Ru81C'i*UvXO9g0ϮAT3{8UЇ!ql @8p|`$\&IRٵm|+BVT0iDʕ.s2~H\f(+Y +pm'59-Rz/XqpHq[ʺZH^t@e gVS%#:A$J*' +Ťo͠*tO"OψUR-]ehT)/1P~;+gZe%k1NzP~t-PʅT󅦔`su?4AY8>/hZ<@[Jf^^!xh<2D6Bh 8Њseb |r;1x,u54Zd}P(o^RxbE^6Jll$ *uf+i&w^Ɯ5Uui,/R>}n[˼51|((H89-(VpoCi+ffgycϰO Ξh;BُP֎xN8? Q/kPf)QXDu#! 1)zJ\\'']d)nD "z=x-3x(bSNyL| ٸs ̍G3KO[*DgfФ+v`9"%cOݺmWdmd78SN>*RU:p~XbyWHeߚ9}a+#CVG{=8KҊKh#2|%"ia;箙!OPa>բ-oC=,ٖH.!t$Zg@c +Ѡ [ӿ{A2W|R̢ 0۝@LxY49!XoMx5o7Xoc+Z +Zhu񊻖g+0̤?YjGycIA +G. [dGތ}|OEfE7w`O&@$+ĩ?j&m00Yp7[zM[psp{B;# >voT,%Ác1V +dں;}Ct:'rD_P0"II1Ғ`B?/h`VSM߮nm}:ɷD,:GAAVmK& +W!R;+GH$pB,Vt-j^ :]Hrt M*ګR0, p^GI`uh<}ݛG4Hf^"3HF8ZA}Xti"*я`~ 8rW8)Uω(B`trxNĻe.B/|V=19u~@HޠkrZŸ][HI5mWgFC +Nn`0"=8FHPuXkv;8JE׉-;Y@v\UQKC\:XQEgAhnwH:Հ**!>?I/(OL.luUK.,'KLBDoGc &vXw't;O$fp=ɑBy's4OˀOZwhP7 4im`EGOFGdmE3)LW*2I(B"`H:X|epw8;`cy*:Y.s? {K8!^A'`B5Ԟt;“4qoSMSs)Go@AxJ2z3۸{ AArmjUM@beW㶍g}R ۍD`N$X,¾ ]K_轜n`ܹfPO8V\бC(0̻@)d++ %w^r4  {`4&K`?9EvI0h|o^k}6Q;RQiR'vF|֪o`ܬf&jIvX1Jp獚H,|nb(n썕A#%7s iV oa9޹:&X7-̵7y#TbZl?BF&PZD{ J{1!l-{G,}T0 +y)AH?߷Hw֡rpQ mHΛ}qN>"lvP( r8?ڨ'SL1E8IJ0MLXqu7%Ѭw/,% + J ӐEW#Cg<.媊@gFbzvbIωD˒}l/!sy,w NyR hsEH0ܺ`tF8`:5JBDJ{X2nKv 1"^r8B P=9}ꤰKP6e]L콮he+&F!|0N3ͻf I +xG/.)y/:=r**XqA?%DU:hC 4Xj!fhX%@5com֒ ~A ôoPnOڠ-@Za66kqj HXx䑖CB72OQŸ\Ęt@y5pE-,%$ (T)#.v$nѢ>oGFsH8o![qD&S uFei@q-e^# V>n!IrV$"Z鐊Ui vuW mwO4;?[w2Ʃ!C =Q~s@U/62~^a/S3d`*ak+A)CÝ JKt)zVj:9v5ݧBFY'9`\Ba* pNCbe>plӣF²Ӑ8>p}ih=Lӥ(YJ衤Ik!2)}.Vp/1;]?"Պ?Ap?TR;z>Q=f2 u߱>G̭Xn,}rJY+EFsl_Eiߙ?g$?T;$CFeRZe"UGE('c+A,A`:;Wڭ#,)o#W_F9~;;-Rv0%JTOGPxK&T)$v2ѝ7>H"rd44| +d:> Ed B" zҶ 23E "0"zfP0 I*&ɦ]o;M$i"iEn,F3'011qR $ +0aq" Bk"II&,Z:,9#i`A `!|h00+fR>$M$880H8<d*>x^R2P1F *2f("4$BfÓAA +Ab#Z:U :0q*pǓlK~>ЃH'C·>J dC:X@™x :,Kb<ˇL<\^*h"II"/b"cOnt4Q“3 cLx`4xRX$XdB&`1*R8Ll=gAQRp%d#8+(D&HqhD><>5c%bF;@E CqJ.8œ\<%CH &P:&PP@q0r)$z:TB6#~$ "DŽw.I/8 z< 0b2p"ɗ +PǥχCGEn0q& b`EcᲙݾu\8)gFR + k{+g4t d> DRKZK om=6KIɇH +y&K=3b]]?GWnk{ϔzV}9]W7fcۗM[6g;?jM}w؎ޟI"飸|_wv\ٮv{hewgǔl&E+ }Q?&ECf.H^4-^o9Uu'owlbSɀn0`HLmg_6jٴ켇ݩV6ٴw~gլϸ[xŦ%]J='WDzHrVuEτdd$31iPOL3Y$| +pxi9qe_s+n,fJnՕޫ]N7Sw3~_ kή]: 뽽@{hykW_$PVNh{n^:˶G|+ݻEƬދ!>w%_$v7S~~s!n$no}vZߺkMǺLrJ{k?u½zTS-̻w竼sT׬o/.H*^GHwoJHrޭͤͿ^~jׯj\z$k" Կ]݌_wo\wVI.eynb{~]>?a"w/ݛNfm랭nՏoY9-9w.nZ=3>_??M{۰R2`6o,gC߳S4{紬M$|=cbzWo~V_9;g='{rk\O3-<~ڻI/wnf][nNfwU+ś6׭3M&U/W0oz:ωQ8}sW@H1=j:fimVlvVu|}ʿ{V~]kxawk~ݾ#z>{рCh")!0dP ̌L(&ʐ!422"!bB-,)1BRF4Gc{V[mZ4߮;#/[1.ڧ;^oj$feMSzXuث7nZ|_-=|gO]wlUDCW{OƭLTH}Wrrۧ} nQ# m]:^*{g^1Zfi-SϝYuSTZAOq5}AE7cЭtzC|uc*)M#{%oe֡s&۝U'FFLʆ)$3=?<)*{鯲If1`hz& @gB̔ rIYy +tZt] 51R%>|wͶHcUk.#o㤧wYv[Ɲno^whW̾ukyw]yvϊVJV]|~ɱ\_ۯ~qz~;G̬MU,WKw+5-mQ>;쿲[L_͉jo\koZٟze}ۼŝy[?j紆[9~K{_E-׵{+,[K-|F] s]ϵK)k'DթսrFD81QK5=u,0;4=ܺٿzVyI>>|v3ZcaZιZxe{WXi߹\9i[>/^=3{絨r嚳aZybiJ! 1ǐ!"CT#IC@ LE" #1Q, ph, R0 0 !(CLa;F @O 6ήS5!Mdœ (pc=[gstj@ +/r`" W6NHCr);B<"rŦ]Ӫ%M*N09jVr8T#VvckENxo>J@VT<<G\\Jи3CXVC_$w)&6(}![3KQ'U7$tEDN?, ZJTp_$RǭDw)tDh'VJkbسes=90SᠧsnZrp`Oj; +Bm^ycF8)KfH9ab +DuW.(gGMPy<3xgIll%]$G@q +GvÈH @aN{8-aQc`hKF"f\-qo u;jU1ㄬBh9o#aH[Ș% %@qD`4xJ8? ̛8H +9wL&gLC囤UF_lpRa_FK.PYsF|g$m`B)p~(ml]I0IYe@e0`"z`mj*nNg%m;Aa;ŁoQt*5熤6?jÈ{9TAaMad 3H@1Ě`/`BX +W+˺i%C\KrvY*QrO5WM ~L2a{;HE_6&b-KsT.or,?:,+]kRQOe-A_Ƅ@ LD~h\qkv-˅Y +'ˉgߢ63/IqxI<:̈́h!7qDz jM:(SL}p 'm^, +!oJI`$rV؇b\tv2? YnVYP)pЄ:# b֨s-iL~=H]dB2O(/Xr*nAcVo눮MK) r\n\т(&p1dn9ٱ +(zuQ8gbs2C]!LFHm3}E;Rвqޚ) ȓ[rFEBѴFٷ1dz*Ne+AUcR!yZB<iiIOgeSy>p@0ܙ |GPV`:e,;c>zQʀ^Etn" ?)@5*݃>3Α!s-h*\Q(#2z%'yb`("2?FgN~8ph
7*Uc\wx+\n܉ R 9BEYqpׇ)z\ +=u@;,:f'90>ӟB̋<{|tesn>! ur B9]3܁U FO4i5a~p#:Y"Z`+Qq'EL9?8humLZ_cک0N, +菉KGN=*%SjEp1=*t8 ,~Ό#\8pJckwO,5jA:@VDj-JDHT}+$DD}r5_AtUKTI*5e`TFDBk>Dq Rqsn Z7ȱUE'Ķ8$~+-Q%}8տ ueƐM-Ԩo{^ +~8g!Z n6hjE #T"FљT e`H-*jm|R,6]tKoGhc^XRA8Uh{LrT$՝c!|)E-#:|I|s[{2cG£¶Aa{E,pU>FalT8 ^{LF] X)Y'11ǨOѵ=6Kǀ!y\:1@V_ 43KH蠫cxf*Z mş܌bj6Q!cx%z'FNRiE齅EjrusN-`VvLvY-jiZMg:%έj5 .(VjQU5ǖyp4q,Nf0X,B(]]K{S4ܬEؽPECAwszPŭi&IpY>cCX@6QԺ:qAXٔJ:7%OHA(hhlgvC{"%YCSpݯ},wT\9rP}7kK0T?,ƣ{PC/jM +_"m+kEWry{w(mfܦ#( Q:w +q͊pțNLe=PCpL>7#dI`Y ɋ̒''hn65'~J} +b:O~@7Yp}Q]zWg0s7/HWG +ϼphG- `l53j/!X}@p}>I6W1NpҎ +pt]ёvnqf>?V.FtҀxq +.7o lZ"ofЭj 7K8B1<j: 8ق~Igj,FH (#,T,06?.GnƫG뮦[t$Zi;.7 Pk%A=/x8*fPq +N aَ)E ?R9xdytu |Ua: N!KxM[ij}u9I w  p3 J"JUc[p䭵Qä ftg삓)- +ܬu9P-t8fv'f.ZĒ?37{sfƶYc3 ƴ.EN{_LSQ KyaOTˈIdxgS} gTne`Dp|qoRWw]ͷDh\%FU;/}j?yK]ٛ?;Vhi4cbWU-I,JR>e0ƌn:|1 ܠ +ㄔi +.K}1$ˊ. _nn +nvPv0ӰdS-vbw+SPe\(1cP{C,A@sQ5AHN!Bzl bWd<x{aX\p&.U[AlI&M3% S,ї#Ubo4כ.6Qb9yD80+Ed7)j(҇)wW& Kx&v>AB4FBfgZ]?ɇP v +endstream endobj 24 0 obj [/Indexed/DeviceRGB 255 25 0 R] endobj 25 0 obj <>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> +endstream endobj 19 0 obj <9 1)/Type/OCG/Usage 27 0 R>> endobj 26 0 obj [/View/Design] endobj 27 0 obj <>>> endobj 18 0 obj <> endobj 28 0 obj [30 0 R] endobj 29 0 obj <>stream +H\˪@@~E/]\|tٝ@$<|NFOO#(Sva{E=EmϭS'w(T׷ˋ·6S㶸a8fVvɽGss?\ۯ}P;B_ksu*iΟ4ӎMMfhP yBn}xdIVP =TJSht!}RCMICd&ڇ*BCH: +JkC9}̱T/N!(˷v@{(d@)D&VLPfJf f~O3 ~?'?g,~O F#b$Y?Vr +TUܯ[~yV6sc}n4Ng= +endstream endobj 30 0 obj <> endobj 31 0 obj <> endobj 32 0 obj <> endobj 33 0 obj <>stream +H  p@*,`{@[ +endstream endobj 34 0 obj <>stream +H\U tW97^7!A(&DX4ztL2MiUC-,QCIYJ=%ܽκ}54]ddžiy1Wz欙7Hc/b|.sjɀ+v9Wwqc ݢ|牼tR~DC'f[{}:N}53yݨ (N~ϴqޥ$ߟ=}\Pm$pˬ Qi{qU DQ"N\)tA&^GH +1#;u_4-]B|OmI2Xgb"2rH'HjD =Mߡ(GeW*tX`=>HZHz5[W<18\$ovЯ8$/|˼isio$&ҋE؊x,FIMyI<%]Y Dy0=Fv](d,b}KCJFR2VRe#'=TNSt9MswWƨWiQ~q\-)5j-e{E^9)g<UZVCSuFMtkK̝Qwְmlͷ[^ƬXduM!,B>|7Nz#XM hQsJKwCe̖R +3!幂Z*ETyzk9}~1I;uW|]5||uk dE#5,k阅ٌ\F|=+!|R jtb>^ޞjIq ʕ67G*p> rfN!#Z,vJ:shu]U931D+x1K$uMvT ++ +!&.n,)ޕ#{Yw,gkȊ +V\/3Cd=ZWS+2@" -|MU/b~ᄲ『FSƜGV×hfD3{`%W*qEHUG)i(w]Z:azzCYQK45ea;BjIC"$͢ۈEqv]c68-$G^b+'n$2E JIGVSe1\î],d,vO'V$sMUa&4fra9i+gi<#Ω>~CFt\(x3Mњqz*fJ- ΖЦCUvEH7Id2Ce/Hq&EWND]o-\:kM&RПU5F+jӏ +@tIJTӷ 'C +r!2'iLd;Q9q CGn/w):cFi*ePoOM7j ~ _f.h%MJH/vZxVEzWI)Wy~G3m#Ig ]DP5"ćC($jQ "->?{T5~3+(8/r: +M)15ajGED3HG_ĞDZ&OH +؛Vb/E0踲}0نzĂBPJKR +hIX?'RyT-Œfi{*U_psG*sQUSUe>ym6 $җ )(lFG!@GBGU߄3‰=L'+hPpf?A ȈA/fG{E]Jw˅-VVQabͧIZ8*)"c Ɉ0M؄M,^8Ȕ¥2I Cq-+CHyF5JMZVBiMS1lUFc*)rH+{h،eۑrtJ<<\BFjGQ>h,xAX3C-2Fɉ[ 2[y-¼]*߼yyf2dGz(0s%=tsօJ{+p|uRFyc r㛈ܴ: &]6mdV%g%N1˹M[Avkk)r8v#dSo4@kRoMvK.}m̓_P0=Lx[V6$umMw\~A~AxVXAer!-k9t-j4so'hN6bepR'9N8*>+YKo~_r.wp =J/ f5D8-&݀[}ذꭗ(X\5CA EZ[)e ǞbJ_}=G{c`d3|^(4 fFN,pIp^>6an+M +[`7ZHGGqvI ~@'>N~Cd,CLf#zL% &15GGCaT箘F T -J~D'[چ wu8F|сKyյKrJkQT@Ac'/?<"<41iW?].-vmwt`PtP.lCV:vZ~(k-^7/=_1QzG] +W8qzE뜚l#U\gnB=(H{*V@r;\uL2CUU5z.~= _H_b o ݵWkU*}ʘ$Kr[]{_-Ʒ.ާh\a7%S?br?18"ш)Tv_ 6DsΚ +ZAPifg~5 \D hD(`HZ-=?.c=fEg@KÝh-utߊWK>Ow80? +&S:sރ`rկW_eo[p''ȋ7Zy~Ѓ}1 ñ +a +ل T3aMu(R +$"N.R09#x{_u|-&[&Fb +osuW_Tc$7O\/uウ}wyv}3qlg865? @ҭ Te"@ &(HᏆv-eT!@'VlSAu +*&s~ݳ~??Q[%ϩ;ӘIJsV9 C(֜KF!㵔SNII"L7Q.B|5nD&Ƶ T~la_5ٶ̿Xt~V:Q9U#`# pXLT\x-PV+eǵ}-{qd̊uOK uo̧{w->2 :vy^+AIlDm +ʱw۔֮QmO.,޵rHS>ծFU |g iFNVz\oB҉F7YPɽ{AmM[1{:7sOxΝay>xA7`:g2fG>&]A/6v4ot0`} +0ۤMgAR%5 +cPrMDt.gKK!H:QE"F` +]rTF:%f(f2[ %byx&_f6I,=KdzC`cAhP݈{%1ĊeȮ~2'(:A4}6Aو:WWefC q77čr$'>n"vиU + "P9(R*~^,.'ԉPܨN?&F +[/ ґVUOk#[g Y o=`B{Lm׎+h5_#h7Qtv'kH@^DS>78>?IWl +,@,+4HE +HP4?`6  L$8JaBwr5563I"JڻZ8_h;Zֵa? wT`y}>]*Gڀ?*dܙEDk[۶/*7ՎTB/m^vd? S'z,Gt=BHS~f@'s^mwHiՁf@:Yu> '*4{7jHH͇ TMc9 +&*^0Fo'稺,ހz>ODSאŏ0FsrU7#RŽfwl_P%d˪ݝ, %5H^pĩjM*˛yqjֆ\;s:Էdկǿ4W.?6۲%E0Ϭ@-: H+kte}}Y~NI7GCr4Ҥ }!7 /ۄNmӿL-4D 4IAIP'\Ei'>{gǝ/w|ll'gB~!@Bh$G`nPZڮPZ5Һ16X5V +D + $1Mjj6ҘԮ c-ΨH{=_+ ֊cuEb0bPTp3̶?3L*ЈF& űt#{en{F J2ABT*.*0)HiЁ"I@i7nw5"䊳)Œ۲+ǖd}bpGF4;݇>ZO>}Q3?گ]'5$kV27!;%Z>/^.⻘._aRMh6˩K!զc'}g gxH_rT-I{j0"H.xZڵƃ#D/%"bff@lNj +#9Ifͩ!44Y7#`/hOPt \~/e_J dQp @ 3K]hj6NVjRCBZW&ԖtopմiՐ%t55CG4SW-MKR<j=e<\ 6=`fՇ|KJIIW H.*`LF"a!l …],U;N C8>p,'&<@O!A&6(94~]kƬ^M_RX~a-  sIsCYDYw#ᜉ51WVܱ@/m& r$<ܵN`ڄ:O6-<hFc(z_]:f~I0k fED+qج,}YcX7suϙpec;駫 ]K`MvSa?: Ri(GfBFQlp&{xz܃w<Meq,gzǬ, 3 *iI')#UbYHf6͙Pt &jOdMjD>m2iL=H7qs:&!PNdN?ʜ/KDD 5u;4YnN WC?riM]6~[޽v{c5;n[xsȎftZ$qp(U<򷣯}z0GѾIHQ-,K +6'T:zizKWz1$FV JI'*7qTn1슑]-Q\W7_wvxُ]zm/` zZ\!Q IcUDVLTu(|&OJ+U'*:Puxf֣ysX)A|On\SPd(6U( SOOEU=oVs砬cN彲GF԰i2jS:hC,oڈoܘ0Ȁ1j\0C9.O/䙁hlGgԻ*I}Z}^=?$ݑwy̼AIuI/:"2%ِUI5<7R"KX|&=o9QX 7Eق>z=(wv}3MD) +} +249;s UgMЅ ċ/I;+moڹqpEvqƢ({\5=Z9[$~Z^UXuRwV\qAch?U|U o@G9Z\i^I-õ<2z11O!4͖ +%p"12f#ނ&9$Ԭ &C4LKoXI/D,YŪ#nfjR\@i^ؙI[(2-J J?>ODVU2ZIwb?/xgka[,=l89.^eYrPCjDA궈UUՓ|fѡ#l%v1ϡyw'HԘ-ѽ-)g6<\rkLȴ_/U{n"v|ҿ㏙J;x P!b8.n(4T5 â +G#4WFǃ?NF?jYuz{SNNjgM0.K4Y-p)J:Ja-V%TA18h(5k!JgNP )(fY%#+Pc ?.t^ ױp$1Fp3/4If fܼ*Q碌A(KPf ua=M/3AT{A0$ΐ;݋r r%)&1>>h|Iԑ_x^>'=bRŨm(v |K+7R]ۿ֛ThʐOYshَC۳t)J-QCs6#wH<}n3j484N5fS5&$|#:JDڿ4M+vʯe q'8볅j2V^uN3#j%Riؼ7[Xa?@_"rŒ h5eKCԽԿ:i!6}fMr[C%TR[nMs$wSZТeKן\X?4}AMm`3s`gނu'yz׹!pR=,ݞWQ~X z5ju<:f9\o%?)v9XZc%N 'rEjlÿٮ&3~}cǝ؉g; ԉ1r僐 SѤj +e nQiنJX!Vm0ں6X+` +!¨F4Iɽ~>h?̳l֍lv2BQ]sX!tI1 q=-~:glB2W}ksX] +d% jKMOhZCxJ<ᰓ% +7X#Bajo8Q3·#څnvU0ԐyMwi?R PMt0Iջ߬Mqm\E8! PIx1Y3 {ǃg77݋~_s,1ejƬjBT|^< ,¨&\ni3|,@>@\Mu^Kz"a QB<-.k1M,+q T+KU2@̱ Y0`aiL5$єp'1EGPև?Pw/Nҋog vlHvz^WLOo1 yl w +'#(8l+s!;LfY0!0Mie ,bJP```/p[|P-a~"68]0**BݢKCYFs|T3Uuv!ęv(t{ޖ@Lc\mVԂEfi`^4I2o<-{ jCuк.Y+!L2: afAaL9$Ȅ$J.ZxR-G4qI%XRXwbr4% I+;`Ä"HO=Jj6;;2";`C=d +БM%7R?|30Yl հou"bSf}K۝$7%l+rJy"{\Én}?m{"JkS=/m/˾V\l%Ut0ꗆ:8wwu\΂׻ Dy +gxt_I,,5<ͻjp 5ťXcЅ}}lUĸA9i| O%"f I~t+}ϢOh}}딪%jc8==l/9َ_/朷^Y6qӆ4Th TժlC>Tʇ2AQ/l"!mBQ5UuHW!$e(ŤҪJSt𖾮Cf֛![.6C64plHG6«Kgۅ㷭/m%ے;\mrGTn@wgl43|sQ'p%|r% +T$ԉC߆RdpƉO1+*g1.s +vWI~}x剎SL. H7Ywݰw-]$Eq1P.GYV:!-eOp㼔TEJ!@!?[!s|̱>dA%K/]^:Etz[UL7v,1iL!GMa@' Q \*p,?j+ʓƗB0mN Ā> k=?Cpcs{:&Xk lx_Ogg?56 tmh<dP +֦Ԣ.(p4DY)& yĿr)EU } [cU5KEv:IC5#bl"'y+A[dKtmnTD_Mp;$;d+-c3fH{8q{0X:S%q:@j$ ՟KXHu}ƴ>2\\уo Z7܇믌Fs4L1G1#i jHAqwJuDhyE cKIN|ҌTUĊ#Mg]i۾b)D"TC` Դ/4 wQ{)4|gm0fO!]<$təw[[|l9Vh}Iy4+կ+ A!5pN jvBbv3$i& Met*%8|H\5%ך 8 )U,3 S!LG{/` %*jqQ<+uM ȮP ~Dvpj.Ў}ݙK鰶~KXj[J?#ǾZ:B hs"hMcjyF .F+DG*"+9jcn@*VµBx9#|ΙWq,2[J+hmEQ*UR:]9drw8h0Qv삮tK5F>ܼkC_X!Z4 Q-TePz_XFk六Ӈ]#Loҗ]㻦Yk1sT?w:|lo$=LR!|yJxEFqY9{0MIoomgw5Dm8̷@fe.9v]Ƕ,o%^AKgZ8$vPn ǁ5Nd2`Q[fg'el`v4S{A9ق*iIKj7IU3Fb U;Mϧ5JEUOѦ4ơ=P=U4N|AM EtC- +npQ4b8"NC̋{zBt]Q^z!8#$@ L)Af%'IE16 + ЄVnaY0(,O:Dd)ϧNuro L](Gr{nwRY$tnSv7{Lxws9rz?w07cs8G +ZFhXݥ-~& S_X_A&-w,eȐ +pag< L^hNH ZXѣqm!o}J}3=b>l$ZAuOQקS%;LSv_43CfjIvuW ө%z䌩]$]T~K#-K~vgfR|IL g܌D9=01:sgx!#@<[j$@Nӏ&3e!dvvĕ cWtGׯ&CC~e,3]Uݬ|wlm" ]eٖ_/swV" H u^w}Ѧc'P/E5ߏ D&kDI!CttKzm=QH4uZK1RU7-7>Eg +b:7gL_Dh5Nh :Q ++ :Pdg:DDq3[qpa9|!z!~>iBp,^ۃXbuQKoj '<l6Sm6);b6#mgjU+q%npRRYS6gQvծ`׭ !4ʪԮ3U䋮*Q>KITz7s.'匐~Sߚ^O.-EBO歝kr=l\|#z\))tns>p$+9FsSLYl)YlAggUIHaj$`lqLn+Edq :%̤ fNm4iF +E8F'tk 0\+-"ekW`aK ?slμ3b:[zms/:P{B5=>G̈>oJ|]y#+u"0̵`#@5byDcu=s.F!3N1@?_&E -P3'P /v;a@:A@D dȆr H5X#N1JBnE +AP3P+EAS1VԼ0 0/EKhGC0p7 nW螡\|}A"#nV1 +PAˡ=MUC}%oύzP<_* ƽ(.>NB#qnc{3ACo=l ܚB5WICPHt}6y0AT̨RsM}aٟ4m| 4 +0pVO%`cQ+p2vܕ ۣrͪ=E[)-2R"XhRlC4\;pu 6020Ⲁ2ݦ1킣:9 qn"Kd2}~{iKs{~;}@.w'S{ u_saT0Mui*sbM$}__%f3nI TR0@B)DBG$t +11xՓjּzk=Ts=Xf +dxV:k[P}TR YnySS<#2M`J\3eV V} dj!'σ}(;_mUu1ة"]d kNW+ɥt/-I)zkF dXv>`ؠYh0!^I!<1Ϩ99Ϧz v^fgT>Rp|wF37a׽@(;?/˝Aro; WX+ɘW_'&0R4bS"L| D:X+kqed& |-~Y?c?&Mܜ ٳeε a"ϙ4^ڦB{P>͓i1AȠBrtüxY+~Rz9#z+̜H[3H +Qڙ2]a|Pf[2O1xZn?IԖw%XY`2a Px_?xKyK˥;{^nS'lc otF蘴6ĖoH\?uBf%Y2=M/Biчn2~,#trQ'#`GwA߿=Xܞ)cd}Qpy7zYYﵗ5Y_z:/z͞y36s>s5tL9'qAv̭U', ugUl-8*Ogb¿x*(e2G¾T>͵yߛZwHUU4M9*nhμH Ӯ3] |CRXz5xMsEFeѡYq>'/U&7u q +/%iLyhwsRid(/_@QbK#ͼCXnq3B!ѷFxqhwӉ8!? KNy沚?kyGwLvj+lwI9H+#)*@=˘k=yrGb5?H9JlM,KcZ[ئ1K_k:%ErX|h-v_w,o!F[|[d"^ʹK{ kvz?kxI[Pqc;e~d X^ggwieX32:qwęg~cMPu3[j~nCdf(w<&'{;~?Z[[byG=zk#V_#[n_'}fmMq򤊸9)~>}oYߒA f8biPj,V#S| myqlF*[;vr7O&yɭ7H;dl,:N2\:~I[m{nȖ*6%}¹ NӖJv<[4^qĠLvԳs4'q,k_o8/_ +|b%{X|n3\?C_S˸'Fc=Xܩ*S#Ej4lw>wksyV:y\(M@}ٜ1.C\1!;lGN?P#%zNꗵR +I,FK0zKéט9C_9!:)g^)h0=.8sBeUkL-]52='KX;f98h3K2ljS/d#JΰS?Srpw_)񥜻}'bOIw/*&C2ڂe1+r:>x]z9T)g ^&0VUg{ߛ,,* 0`ud-#" "+.Pbj2.!M*EV*LYZ6ŀla@hAmHHs}ΖF&wyg/sVb2ۦ4yeAVA9Ry>8eE 7&ޞtl%wz.|kAYQ{#qA:GNI4 2r$-8u-ng2 YdbbKI32V}A%ox^/qk4bi7O|~ʍj!ϧ̋ }*ܹCѺį0ҙ?]$}-XE"U΁w](9F;6T˘*\PG»>NOȏӷ /гCճCR}H8ws6ɸsk>7EhyJ1 =_}F]/ɻl>sϷms2ZƿH?m +И`+Nש̫zV׷7ki엧RVǞ +mc駫j5֞5zQה~,ujuu6׍Qݨ&wfMh%=ln)j Z{}Vh +߼'&wb󭾯G$Kl8AW̻[Wx[ꑯoDxJBDM{wVCSG$ +i2WZ +R+ἇ cNlmf)a/]["!%~߆=5K;W^.UԩFɣpM3I<_zb@CQ0GZuһ}C|WؗUj,8% + +c^rſdML8?S,/h t3 }/1VooH|;/wU<7n@ qנ9!>NG^0g' +kY J&2tml m4N:?-:ӥVF9g3hU]9[y:Z4YWA7tr8 m3`L>2{3]#yӱ+>ϵxVo)UϏi\G_ >Fg˲\XflmBJ;}~u|֬w/k!^#j5|_풹d>`7w7.;qo&I|WӗYI3oBZ=&p~p8 +;:}5s]QAb⭯:(;5uR{0[LBoř\>!wQKj"W \vcry1/[PoU孴 ]E10'aBi0Zb.kL^礔;sdvG$OYȫ."Cc{ҽm=0I;(-sn2 +}ebފ36{:! yYsǑ'7O2Cݙ"VJ8?=ÿ{^!I "6 +L!Tcab@E(;؂JU-v6H-8c8Z*;ī%:dY{ǾZ2wև+939w_yX5O51{%vrv͇qPCF@{`LHА^j{whۄUʵ d(Y02Z$8Ά0r!Rnb6-lHjI}.ZJQJXy+:wx7iOڎ`4Z&_pF/;U~h!6Wş!Γ+bl<;҂#7iuԆTY. O*Lqcؓ eFgiwbݗw5v2mʌmA rh1Cj4]уܻK5jݸ9SWUέSL3{-egmKxQJL圳q|[ò"UUAβU-iwmbhKB>74zDZK{lnk&ɥi 0z›&o*=wN'mGWqNMUӕ7~TSgɧ'+f?x^]]zoa\ %Wf7w#t;̌:r_#݁9ߤ&>tCsQjޛEV4E᝸E xg5[qg9zj.69)43!Q똲K5PzZⱏ?gWpmpX\C1T;։)oQ$Tj}V4]{m׷+ d|2 +L01a%t „v$_u)0~+0,i?<\{g۬ :ĬEk UR fŦ>ϟj= cLlh=ȻH K^g[n)s|9xu@XO[s*pF U>|u/LJ< o(nVw&)R}P J- 9c QI?#yvy״;ӈ~97 FǦkiM^c}n0U)55S }L +0l&! zuN7zw#9^]XRkqvԽ1}RDЈ35Fg7hD!$j<3G=#A~M Z Ơ.$zӶ [m&ܩޕ<@4xw@5݈ckqD|0w-/8TcmQi\MI{mR +W%&wɣGm K'-*`=E8;'b =!+~O沈*ԬٱC8.}4%4sC:o.6J|όՙh Jј#=}c^+WM^y^ގꤵ4SxT.9e_/s7(|sk]6Z٤o +ycI_l7Ao`_( 1_=7uL}|L_͑jN|Wy +M0o6 uj8X\5r~ݟ~2yf=ׂf %s}J.jqfU'__ 蠁)w^1\EJ;ǹDŎ G/ +m.q^R|+np6=mnTc6UU.Ca5 e.yډgƩgn!zE*svs/|`}m ZPx8gso5:Ÿ?ǖa9m bN~h  gbVSh.-qGsfFT.m%>ZmˌWV.ZޥF{ g)k@?v_[[u`ok1hYW`߿7ofTc[ +W{*m0c?4qaGm'Bva^E:r¿_oyW+TJ=33c.Ο`=SyhS5g.HCGϣP>!Nsmsh&8y =g̓m}B'DpC"h/vW>?Sd\xz2{IݖݫXepʳ~VvM)d뤓N:餓o3`@; o:QJӥeRY#5Kǥ8\}.T7H#a~ǶuUqw_8Nc'iڲbJ6<*N6$,6MH4^?c'-)eA@6t![@+UtCMŐhKi@n7ϐ&]Es9s=陾X>/^|E/3V8M| /+ +BP( +BP( +BP( +BP( +BP( +BP( +BP( +BG#j7 t"MVcOšWΠ3>92Yϸ>g0#IىMYy>-q"OǬl: ŭ3V*ex)0O)k::=d߾Dz* ZGdv>;'IpsGH|2eM%_u2N1z }Ry}|'16֥PiBY##|2+?eF]EAیf|f׳+zӼ\0|n;cJ@'?d/8 E&竑|eVg*C"9ORi +[WoXvt$*qhሜ,tu=ZYWqDl MA.0%wDVZft +nѨoԢ+4.5dueאGe)GaSN8GA84g{!6M"{Z.>4DKlGpZ5*im&Oh0AU%^w3G6"~`1|ˀ0(#.tMxS̔'2íy`8A  mj"@?F!@G.(%0&ց}:,y ~ԱsMDA*/F{"^dE(6F?f!:h%/ {a/ xW_D0D<=7#Κ˞ri lF+ZVV [9vd[7llccE=fi֊%j]Z6͊3Y0F}9_¾o>˾9߼owݷe޳lzrx5]55QDS N%ȲrfI; +9,6Ȱ@rd8aA v_ tV¡hHxHҮrH_諲UT*\U*Bm_Qgxfpbcrs3c7 |G?.k]p8bERŕPGi!i&Ep|TꇐG[pUiUCIդ'O<<ϼ;۹Jw:66 ;`-b]-%D< +{.zEB]q`/&|gw$ C?h wD^q^yDZjD<|7oQY~ ۫JSڃ]R$Uqװy|ճ1t&BHF®F^aox샐I7וØZLOֲϑ6 Y+{"M]66m њߎ꿊WQ\TQ*.fie%DF_GEGW"z>?T~S[uE=Yw1zZaڼX +g;`pp[$`p:VOK8p49 MGkW迅| fm'݀w%ܤ#.CGx˰`B}N"6ݎa}W(^f0Uar+ 8/so `^'d9Wq^$‚p ##L +g tN +`\DqwSc5A.K$!ҩ"Z8rK If I>y)ZRQ|2[߹O t8vy' vMچ2d0/Aą" ,gMլVEmT53¿O눫"_B +'*qGgc| + nҼFOM(as'oK(sGeWEx4/+bE/Y ́@ģY>[< f3'2>n1,8挺1T1oNVY[q>TW`/LyCN+}[]7'; Sx<l 7kZA[jVјF46W7 H[&-<016,;l%OfzC=ҫͤ]5{כ^tYo`d(wM5vRB>ẁc> endobj 20 0 obj [19 0 R] endobj 35 0 obj <> endobj xref +0 36 +0000000004 65535 f +0000000016 00000 n +0000000147 00000 n +0000023919 00000 n +0000000000 00000 f +0000023970 00000 n +0000000000 00000 f +0000000000 00000 f +0000027852 00000 n +0000027924 00000 n +0000028064 00000 n +0000029632 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000069714 00000 n +0000069520 00000 n +0000101211 00000 n +0000024379 00000 n +0000101098 00000 n +0000027186 00000 n +0000068958 00000 n +0000069006 00000 n +0000069598 00000 n +0000069629 00000 n +0000069858 00000 n +0000069883 00000 n +0000070399 00000 n +0000070833 00000 n +0000070902 00000 n +0000071188 00000 n +0000071292 00000 n +0000101236 00000 n +trailer +<<7C0B37C0EC5DB64F9024B489070F4AEB>]>> +startxref +101420 +%%EOF diff --git a/distr/design/Exteor.png b/distr/design/Exteor.png new file mode 100644 index 0000000..43feb6e Binary files /dev/null and b/distr/design/Exteor.png differ diff --git a/distr/design/Exteor_v2.ai b/distr/design/Exteor_v2.ai new file mode 100644 index 0000000..f953c8b --- /dev/null +++ b/distr/design/Exteor_v2.ai @@ -0,0 +1,766 @@ +%PDF-1.5 % +1 0 obj <>/OCGs[6 0 R 36 0 R 60 0 R 84 0 R]>>/Type/Catalog>> endobj 100 0 obj <>stream + + + + + Adobe Illustrator CS3 + 2019-05-06T10:47:23+04:00 + 2021-07-15T17:07:19+03:00 + 2021-07-15T17:07:19+03:00 + + + + 256 + 184 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAuAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 FXYq7FXYq7FXYq7FXYq+Hf8AnMO/vZ/zbNpLO72tpYW4toCTwT1OTOVXpVidziq/zZ/ziP518teW tT1+71jTZrbS7aS6miiM/NliUsQvKMCu3c4qzL/nB6+vGuPNli0zmzRLOZLcklFkZpVZlXsSAK06 0xV9W4q+Sv8AnNzzR6mq+XfK8T7W0Muo3SDoWmb0oa+6iKT/AILFXtf/ADjd/wCSS8rf8YJv+omX FXpWKvz9/MvS9W84/wDOQmsaF9b/ANLvtZfTrSa4ZikSer6US7BiEQdgMVVfzX/5x38z/lt5dt9c 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 + + + + + + 1 + False + False + + 296.999938 + 210.001652 + Millimeters + + + + + TimesNewRomanPS-BoldMT + Times New Roman + Bold + Open Type + Version 5.21 + False + timesbd.ttf + + + + + + Cyan + Magenta + Yellow + Black + + + + + + Группа образцов по умолчанию + 0 + + + + + + Document + + + application/pdf + + + Exteor_v2 + + + + + proof:pdf + xmp.did:499F9118D36FE911806BFCAFBC83A9F4 + uuid:7bf5e32c-1de6-40e9-938f-b0d3390c62e9 + uuid:4acc53b5-3f9c-4c17-9e62-e9b73cbdf87c + + uuid:ab6463fb-252c-45cb-be4c-38524b98ed92 + uuid:4acc53b5-3f9c-4c17-9e62-e9b73cbdf87c + uuid:4acc53b5-3f9c-4c17-9e62-e9b73cbdf87c + proof:pdf + + + + + saved + xmp.iid:499F9118D36FE911806BFCAFBC83A9F4 + 2019-05-06T10:46:45+03:00 + Adobe Illustrator CS6 (Windows) + / + + + + + + Adobe PDF library 10.01 + + + + + + + + + + + + + + + + + + + + + + + + + +endstream endobj 3 0 obj <> endobj 6 0 obj <9 1)/Type/OCG>> endobj 36 0 obj <9 1)/Type/OCG>> endobj 60 0 obj <9 1)/Type/OCG>> endobj 84 0 obj <9 1)/Type/OCG>> endobj 85 0 obj [/View/Design] endobj 86 0 obj <>>> endobj 61 0 obj [/View/Design] endobj 62 0 obj <>>> endobj 37 0 obj [/View/Design] endobj 38 0 obj <>>> endobj 15 0 obj [/View/Design] endobj 16 0 obj <>>> endobj 83 0 obj [84 0 R] endobj 8 0 obj <>/ArtBox[65.8599 35.1387 829.909 574.315]/MediaBox[0.0 0.0 841.89 595.28]/Thumb 99 0 R/TrimBox[0.0 0.0 841.89 595.28]/Resources<>/ProcSet[/PDF/Text]/Properties<>/ExtGState<>>>/Type/Page/LastModified(D:20210715170719+04'00')>> endobj 93 0 obj <>stream +H[ϧ& /1K`@|zYN0,vtWWo,oYߟ{|埋m,Z[\tk&,/O~?=dZ!m71^c_mX~0O;5rN5F/nZ5ͷ{`Vtw6lgŔx[jjue*8W'N∄!/ZBlGk䤐]6Wv;"cXJj*O$ +R0zZ<{oO%V {ﳩ$zNɚ6tG;6:ipwδ\NMK=M]'~+|Ko̾<,8'|Mq +o}J$9 +jԯ>%pl R8B-58}+d WKZlI'P + "3b + j၆n" R>2Ώώ-SYC21 Rwycʔ&x ; 4nx.z;-22"_i l1,B`Ha Bqɓȍw"bp FzfuεKfǡ4Nl@5qH[DmipOƑ#8KyQoVZKiEwQ7Sat8,jS9I&smnGO Snud R'FeBJmL;t"ni'#,U^qn28*DĊ'@mT$G"FR$aiHF>#0ʑο hqe Y+;6.kAnR%'l .CXCmm'%%1W@C6/(IZ*xm:2 W\ 9@JێF `J\ IQT>&I G2y8 aXK,$ ~.;8NdJr" z+OcwndG`̰|5BW Яa5VφzRݱWm;LmÔ4YyYguUQk8q0НR 6by$e0ؘⱟ+;iq^EZG9X-M#x5^3; dl '>pRy!zZ!Ƅ/0;ꅃy;! B^͓dpM" $ ~WqѸ~OYgxwz67=m6edr[ߊ +|GUETwUAn2#u|*dA<~Ҩ{jvZ DV Y 0f|3X4(V?O&Tİ3nح:|Ju} bכ:=0w{h?nCySGmw_/WOڻ|:/_['?)mhy߯ a16kH~2*ygq;FOOƼ?#nTk/̬x:rI3l;.>gק-?{kF=dd3Q~֘pSa +;zGU5ǰqR_hȽ{*e})}4qҩ6f#;pb8m`'F-i .|*xjjϾ4iD#[n-aִۛ_i؏'RmuRdtF%45hcYDQzڬ.>ێfd:l G }봣UlHhUqhcgNILoqm_w91_4E=U&^nN>Xf`ۆI2[|hK)v %"d\ 01Lp]HiaX1zѾ~x#; I5L$MDRKlMdG՗1P2蕲*K>stream +8;Z]!bE7H#&;E7L:D/F1XP-W#"9WX=_eCJ0Jg$["<17HV@d>*%.>1"RO.U;dV&n(i +`baDoN:5eWUR^FkVdB85qj2l,%V,S]&Gs*H*9GrXnf2omi%F'3THNX+FYX48JuCu$ +"9bB*kBNYPUb!q.:B1G7;#/4P`Yl,aE^h,S4ndNP^jVZ`El8@sog6);]cE:*di5lmNP +aj:]QS52,`45+7675$EXj@0;&+Tgp,UYcSt;,2P>NGK.m%'5kHVO]ig+_.>kfm^oD +=Ncc.)3LZ8\'Us[Ji1-1;&!`u#El4>dsbM5C)TN]MMa)V%WXE![NbW>0rKr2-KG*' +_&O6'!7;[IgTVt\P*JM7khQ9Mh`kh&l)a52#a(FX^6Io9\tJ/ZQE]'dhT-6B*C1R& +[\j8(<:""JU6H`J"pI'=5:M[1UQBC]FFp58)$5ma18Cdihc,-c/\; +endstream endobj 87 0 obj <> endobj 88 0 obj <> endobj 89 0 obj [90 0 R] endobj 96 0 obj <>stream +H\˪0@ +-]\K $E48("_EB6F34q}~Vw7';K?tLJk:k?Di +LQOlo2F}vOVuپG7YW>?fY%,Ug/ЗfܬCDZ~~~;~>')iާ6$~js/ΗwoO,)mTCkՁCE<֐*H/DM'3dYvJ:d"Ph ~l4PA,'V˗0ʊC{HT 2PZCB!lsl +C=jp]b w].kwnp ]p7 [,[`+le_O0an^sqR>ED +endstream endobj 90 0 obj <> endobj 91 0 obj <> endobj 92 0 obj <> endobj 95 0 obj <>stream +HytWǿooޛ~B,",DZ[@A#HBNȱH= +"Z"H +aKԢRE)EDİ.K@ťi{̻3s3$LaZ[5[?.iQ@q\7:+?^T8u* mI#5Tqs_gf|ޣuɎ=Lmܵ_I\/r}͐j4dMʊ̮Q`+YR0}}v mx 'M..Z= ;ԅEم z? gXFY /Az֣Ey1({"~=Q]bzHK\(4 LPs6O*".3~mL" 1Y5vˍ]=6/w<6-cc;r'Onc90ƞdy8g챹aE؁.[KF ?|ۄZ6V˪Z6 ֲں@{tÝ1y(cx +s,p?v!8)w7f\vgl'Ne׉n~{S_o>dzok8$(7cq 7*;0ca2zRJ8{8252NdA BWQ#HWScHSOhfhJ4UR+bmc9) bc]W*HLN 9QN э&a1"LœLn> XJlTaqM oWl|W6/g'˽׌^7~J orl| +-7xی +rz˽Wx1~JɥJ~ro{ov_ѕB$O13_}`d>d-}Da9V?l\DZ",K!rO-,f|a|i|er%u@?4r"JDDT$ d@DD +@dvb/3 p*QQIU'"n@DDTJ >Q "acTjQ;F5 O3˧r?Snj\ZZ.LRH%icDnD"-HGKK%btDY"HwK{HK%mw̝]fmdZ22ew O>M +@#P?,XU5>LWL7ʏ;`UӘOȎ1b4Ջ8fH‘# G:t,x8҉oFX RUeQpVN +3:fQљ0aFŒ·]3ft5ZNG#_`pDKҜ|sKjnżjs_T}|wvҜtvs3yĿŶBFm(.B;Tkq"0jo>4xIHզIXhbՊI~N \$=P +P P q$*h#|x,>rp2rq"lwOF/UZGTT +E$?"6?h*;\_sJov?X'q/q<|?2fKoQM,KT,Kьxc {_RMiQCuo>|.)h#2LiqDb"?$[3-qg 6E;&mtmJ.w~;gJ6Ԟ:RNOS4fӯiO"ZBwzJHh3mTE;hj:HG$.eJ5l/}d?9@#{}~9\D>$.x9QN//r!g9GZyY&yLV+Y._/5&˝r#}<.Os*oț+nUv7m6v-n[vu3ݞnoԍKMZhWGuNin[V]םt7CߩzGa=Z9zckHhNyZSkjGx:P^2).Mh̀4 TB%R)4ͣyH2^$ZH Qb$2ZV VJԣ5ixNgmXJJbM[Dbߗ XRVUF`4)3t/5j\1Q{Қ x W137-~ݾ1888g"n.k|]s%\qMW.eJhY V*Yf5Z{dz[lCmg ȱ1<6!cs؂<ƓǖylMcHے$Lۑ1t)eCrLrSS?>TSi_՟,u.r3E7m<{WLfq^^8# I;5KIٕfI2qaqc1F "",D9'(]V" n J+]]]{j?a)azXomv(}~@?=װiT3jQF]m53mFxd^mϲ9-99J::tG%GGSGG"ve~%fy3Œ4kQf/3Ό7' sl yټrs6p8;9:{:FR5d}e/Wk{^nx?b80pʭDuʖfheiZHe脑]n +NziЛ-^iCX>]1EQݨS@'VI2RVI*ST){M'97tZI2St):w tq*:1} Vt蜺tܸ<:/owr{@~:_%; [[[k{^ 򲗔zp?7do㳞_K@휵Am)Κ5ڠaY7"zgge&{=K< y3C<=ը'v˹KѕnrruqP ƮewݜIk=*u|s_ݣWXk)/ϰN*P67R{UlPUU5Qf[+(PllTv/s;؞qjs]zS_Vnm.gՓ^""W_p ,x orLX-[wB7f#lnx)~S$_W!X$Ag]0SpNI] X )> ;/LX=7>t觔{ 0( +aQ0vb!}wa2 D j?8C"!b +.T\0+Kp)z^.K@{D(61@qܤdWSJH(PR/QrJA_SJJE) t4S/W2z)e,QvA9eJVY+dlI6*d쐝Kv+drH9*东rJN9^zSc}OE)| +PA*DoTJQi*Ce +T*QeBUUTjQmCuէԐQcjBM5ԒZQkjCmԑ:QgB]uԓzQoC}4`BCi s4F(Mch,4&$,*{ ?EQ.OrY~+\_\rSnor[~;ܕ?%oWCy$rBN$3'$Ă .z)9UHi8-|x8=gHHHHHi1`dFdE6dGD.ęyPPEPP%8 gEIBiAYCyT@ETBeTgUQ-8ꨁڨhhhhX_-m]]_zzcbcͦ9FsiSDȔ@_BEM)RZJ_}Kuu^7Fݤčwd7M7EH- )n6Ļp{wĝpg9wKn;=rO3zFW[.ŹnѭM~w>GD鋋.Sgo; ><|e,V;*;U\?^Ӛjש[խ{φ7iӬyZiٿ}|ة݂٫wh/؀ 4 6|#G3q~7~IL6}FD3g0;9?͝7AE,Y|U׬X6nڼe;vڽG}_>pX'O%Դ3gϝy/]׮(YX@]խbՒ+&Y«W=|ƀ}Y,9?=0C9SauCgP'AW n ?Fw`#v1lQwD_n`AO1` .,d a ԄVmd-! ƙG`b 3kA 6 (D`L@+:2wB[uo9ob ͑ ZU +:!b' طciCa4L.zj΀_K4rGJC7fwA| 8r,X]05n_";yw +=q(J57ی/0b0޻']aY@lk(~eA>\|c0^3!5׌`{a${1{Q +mհ6Y&a ϐn"c"s\Va8 ?Op#wzw)lj̡dzd{^N`I(&aM15 1 +vVyd% +)7hjz`c/é$؊L2|+@8 +WF<4%VWݤ&<,{Tzj);d]Quf+E W3s- 02T zX8p28p +*}/8Qp>:|݇3ӑe~e8|븅/'M02P Bǒ%.̟IVaxk9_F2N^QD.{=CΫ2&VX6[,Vb .&Z S0[|AS$'$yA=l*-E늟s{qx IHɋKH`GX"VV!E-*" X9Da"lS5 UZVٺ-#{ !޹{s9V|bXZ STgI!o|a)#NHM#|;A|N_ B7D{[3Aa(a m ɿߡ]'<p(& y؈?P[P~Fg|05B?|^;n.,X'ӭgZ6*-9"ױ}x *3LKpnqQ~i5xFiRia7@ `?򳔋I!.>.B٫xB0HrЅG|n&`%6P4M 3^Ỵk_!/~ T5$$[X $]Tþ%avlO|ftj E &7AoyayI8KU| _6>cݣkZ[45n]U|dEuUe\/[]Kh+*Z +&A9ѤV%UJr:R :D]2ŤŒ +I/IeVRDQj%zX#XXKNothHbR#H2Le,!94\PLH Q[ޓA: 掴e + Z&#j\e$5nE/^P14( U_F5TFVGL`2}4+@oR;c*k:~VO.yؤء\JZ3>$zb >4UF(>JF*6v0S h]߰z%,$,BS2e" "R/&O%}|".2}ְ"a-\H tJרyˢH@J!ɴ1Oi:DU͡dZlP)R.PS_,I*ŻŻЪ߯\1D>%vSM`*%z` 6o%|dz'6ۖ`3J?ƙ|qm8p'eqRMU?X쌌X?órwOLs[Ԛ(q6G1s)(w kU+gЃz(k4QT=(EU15|lKmz8l_^5`uxQ@tTd:%QNOi:'|l=E`E+`F=oMCJ +&$EeZKZtHc&P\^ۃYa0fD>FPy{ YΤ8ArP`" Uƽ`JW33Axu>^Ip_&+$~HЛŎ][~ick og}YhlqEŬ(nw>qBSJv11U_ L`]tݮ*ԇvt7&&[eM =O +j'Rױ*!-kOf9 YI4Js5TKj-sMt 9.b ]H}znerVE:F:\aܯsNrIbCcve1Xpr:K8HLL)rA.jjl^@5ܰkߨh4XZ7r' nSI\:ُ4't@8l0X,:d33s Z&~bSϪA"T +W$2@!#a[+/9" +,8U<^̊bf1yQV̝1tFS/Jټxŋ޲e6+X"͞ ^ލ31l8MJqaIqѣFV?}L&${keoVhH|Mhj\Pݬd4ypYMg|wOIt:q:tul!j S Pw!h]L$6!mҔbdH҄N BÐ҉픸J&c۽j=7+?X<ʞogP΂0]+)]Tܵ/AytpQe\g#}aj a*`;oZ$^-Ô} ? r@-@ +銱ΐP@0;N,Pz`U+m ֪Mw;1^t[tbu[ԸKWnDžtl +zV[@4oBW*p `$پ#0EmB4MO(f2WR!4ućQς62/oo,ծw^WZ?:3rm(d܀f7Tw rh} 2yQ˪UZchV/fz( MfEt!!LIe4+ uА1|6ϼ'9#`JNVb !B2Jtw#ܹ{2B0A7?X RŴ[&RNoy ? @=\w@~k ^>#}%yB_ pkrE#h5x>z)zLN @$zXI2䯓ua Wpa,@fpaXīU7xkPMlJ*9RD2AӺrĹ8wʻތwLw&NBVE׾N>LLDd$-퐥C.&DO@ cpӏ# ~mN8K[nP0KK]ё_hՅ$a,lᔥ!|%]d/ m%\-ͨݿYݱe[]KŲսV18 j_?q OjNWͺH)3hX<Ušޤ}CpM- ),oJ5z飯M>^r|˛IuF ,,ҹv tn< XVe0JKBc$N[AF|%P%Y2F5oT};qxuv*1Ak¹Ʀ&}fs/ +ga;@B!`XE[%?a%xIT"-@%lOJI&rkRsXP4=MN;4EMN[DC*򆎅( =j"zҒ_ն3C!Aptahr lҬ@Y@ezrHu~D3BA`RoD4gMAS*hK\亮d^)8Hăd(:1!vH&ھx"1jc u3ƦrcQjc8p1*4׀lg&˶cp 3T;l 59H&\H6#PFy]9Peҡ *?V)?WV|L+~f+c2043K(sysa g(+PBE'%Qr  $HY +k'C1@,|*(APM\42h"DBf+#$v{Ո&O"56s;;g;w>9;N3`?$B!-̅U)Qu uluҨF'X0MtBBCS>tL4iK9Qi={;Jt#/uNvQP\gXkFLjF1z7{_uݽPB9hJ иŅ9`m!006Hb 7|Mt^7&2w;4UڤlP"qRP\[a=E 9Ed7Ŗ$4? +GjT⭙$N`N*Dg©^ټ ΄Լ/K9: sEW{HYS,oݻrr6SLD^̑WR;{G:u|pq1TX̲|$1s;ԽL=/=4mRF_oofA),~[:`=`>nӗeyM!oŸB tSA6?b7GF vօ\*"L6P&n S~6TBt(kn]GNUk%X.i9:CtFrdj@A3K#9=-GGd\+=MhcbShSNW*UU㿰Hw2&ŎxCIy3ZPDL UP*IREyhvG2kOe*S#Vtm}w⯎ܼ'ǽ)m;qԡ+wzBnisC-֢8gg˩;w$/.Y?I^{fLS1unp |*e+ rs6cpQ,-Lԭ^UjsUώC5>4V ƱB熁D @鳒^5Q}Д }MCl_ܼ4u?C61S-<_W_x5F{cos260~d:ʮH/;_b~sY6 "{pm䍞SpJ+z-6 ܢ HٸS!6w eMy<\$$O;u$791))neY2a}!mT`ҘI:Sr.a{y GlXt&g=9%p-I)hȈe(\P*zY(:&Ұ<߀*>6 D_Kz'rHY1 㩩Kw o[*.w vQ8̭EVi%× 7&h4&̟)g\E3_iUJ..©g+C|Lbm*1)"Gm1%ˡ^9TY,v9XGg&̀b0$+vy<(xyQylTXV1VF%X*VMiZ(JЖJLAت":ں ve8{߳ymzu{{G-E2++f爎Ee{wTLdz|ePmVYQpqajeqv8 N H`7*7W3߿sęHtaSgT߱"G>`†7zyEVXf=zwVUp5AUسJ/6C6?W}iJ9] `n/qf\klcذ$kX4;LiE㐚Wˌk#E:@RbX Vըl5:3r&t$-봦,ŒZXǚ qdl8$jcq*Вiڮ=(1#yDi=OG#ywFz?U}ɓ1k>B#%?w-nM3=ݢ a,{pu_{m~=ʹi{7f?LHX:́=dF/(Gc+T֕2-sU4Ij%c.y +~#Jp78X)Ӣ\**E,l%zΗ'T:zXV=TR9W8)T$5Sln=i ~%UhQZҲXFq}R;S:ܩ>3w["nst[yE1 +ϛϺ}R@j45z?eK[H|Ͱ 3m^PyA9~!Y~8 1=$(^APr;)()l9=ExJʶQV +p<ǯXArGob{8D}wmQz<=eh 3"{IOgtx KvŜVBop кPp(hб3Ix[Qku 7اBH>Udbx'ԤS׻7j:x@2.%@/#, גeQ&e667 71p>Gmx&3$b.2#5oHU5_Kro$3I.<;͒t+?6wv>L:q"Z9I2}!yS8Q2F s.Lpt4H,~vhKJh,DVyZІK{ 4kb1+Kɯݰ,wL +7%"G z.q4NI$:ɲ30QoS# = +G#wP#4At=h}%SKmK=Y9s@S@F9iE%X v{-=yejc9++ƹq'v$'8@BHĆP՚jڵC6!UPm?ڬ|Vmc0J۪J (jPc{Zi9>9y}գdM Yl?S8-EDLjbjVMrTJ"v\>rDu&#}@ + Pxl5\hS9mF3i.&HRG P25 1%FņPCdq:D#'$kPf- ס'x 29^_Ikt/PľD{eDI5FAW8dr9LvD,rmӤ}%V8E]|}X0RȦuFk}kFInF@0M\+FRSD:UeU^u-*\ ( ۄZx_A4@aTsT mCPFy#2a|-!'7l|BȉUyyC٣S5Z+m5Z Z 9ѼyKh@$|3p4rtwo#hLv.N fjQm:7Sի2qXG~ao:%v)7%ɦvvۛ+I_"Z/z uwe $7zG> h9!bjmtRbL6:8˓R^b?R\{j5̶F +] bZ|7mbFl:v)6cة%Ɯ9V2G] |O/@Dؕ|P=A:&p8~!LQt$JDjgB},u>{V9ֵC䨫W~wwߦF;m{: " +FF>FΙ +Mo{{WQM3Kˡy|O+mj1&w#S5>} ¬jshH +vfdXCPMHxCrv1ϐkA*uWKD%qNEtv0}\@Ke dxB 'sBy Rۀrsp /$tXO?Y|CP'kKTH^τֹDWoӍ]#$1~0BmÌƋ0\V@{BSx).U,X-y mÂE"%zG0Џ`@_Sa@PKyrl; CqAd Ƣ/ + Τ7S[Fr0H鐙hB_P]>SjPj#%MqO`L.]HI +!VRn|ثL$,p_xMA6I$ȢY fv{V@pz#^[rnSG 5%D;DI:vRnU.Hp v\0<*w;3xS[H>qK^s0f`ZƚU{h{[7۳4EcLvvǎ +cp#|R]?|\矱/ύui&k%iC&&aZʴڤIP׎Mʠ:'jN㏨E8}>yt?M˧=b;GDvg XٜȎ}3[jl H'hw%-jjP y}N 6_3n6̝(q/ ?NVmxzAV_IX5: +]&d3}\:oG>~8%`\?;+Wvo%lڻ|ACmz`MҰ2Btϒ-nMo&M#bi +#b np5u5\3WjJ$"GpF*H4Ghm2ЌX>K#3+yT_Yw;hgŎ>unѳ;[7!อG^#[I(.8ҔiB@QF;I} +DG>LE^܉]EBA ǩt,AMl5,,1L$h8"ZXd!OF BS#2W³|T>ivN#>#Zoـ9|V-7וTI)2L3Wjx?IDܝͻEAjs\dxHp}_F : M^Ҟ_7}4s"Y +{X40-nh!,Ræ =+?\xÃ4*%R7ME + NEK{Twv3yL%\©L:]$A)33fp/8V(DU1W)䐢ز5Ywɋ E3 \I=_GaP++,-񞆢41E5IuV= +2AfWQp\St%3)[<"1͖rS멗/x"*mޓq&&4㍧036.澑L~8AH$/?iksVPňA֦J1bTゲCy\=%)YmVk%V1RC,*l|kO$,nInhG/͓o4~iՍ@.6y.u7S7 fut67?rh9"9#=tpl:eBlчO-L<*nraޢCmKl:Liu>1ݚ0 5 ZFU/4 R6&.k06KEV"m&vw2&Q1m39@ ' +%98Rxۗf{_Gܺy׉KI٧^6cl1Rk ^o +7t0k8nQdAtxEy>V̲XGPV:EONJɁ^v z^XX0!Ԅc‚O + EC: JVdh6t|F +UL gS賺o&Zi/eTo6M+oƆ4k:3].^f| ) ",agE7Y}}wώر{ܝ\;kemDm* Ѥ XB5R//PuBZ2FNH4@ۇFȫV$‡,is_r=AV{{PpUn[np4G<.Rd.0͌1Uf90,LEn^1dS0] R1 WbL]m l6\v Ӈv&MiMWm+N4;B=ƾ4tk$鰉UȂ@+H 8G6 +)̈ sP5t24bC-=4diùNtGIDV1j)߼oGe6u&@=pb;9 ! xsYmBPH}-H.^5LP,?U#_fg5WY#|sRo=om7w3f/}5@Xlĥ>D\(,X8BsQfelMYx({Iݟzٖͼ.#A4>h"*N [eKIlt5#+_iö!%+ +'0}8DOp^fc`0^ s^0è@ haʃ=z`,yԅ-ϯ|38:7v5Ow%@ۯu7w+X2DQҔ65?<+!DqdT'J_pS%)}ؗyrD9Zް;& .$x>l Q*l|^]Popyr *R ViNvNN1H${c԰ZQRLsg"ީM7M)7 +czmy~5;`y]Klov={DyҔ_"7A˞}z앪nU63#EtK^ؗtإI09M:+['"iѰ*؅bSE8^**?+zg  A7CҨ'X7:>+:ևc<鬮";<<Ļ;j7D&3Ha,ϋk"+sE\Ql =ح "X'ZdN "M$Ꮏj[|FͶ0mMlO=bDJ>%Hyt-'u:4ܝ+E@\i\LKa#ǟoHCCe8gWZlq&3B|oO.K*TiTKDJ >_^o.;~}Ÿ+x\?4kgP +UɓEY[Qqym٨ter8 GŚ+3sY6w4I\MPr銫:o}m\r:=BVAur6$Թ1 IR'ɣNBz1g/[`T2ĴE|Rop&\ .cA?vq#KQ10ҧ6'0gur#nvTڤS=5"C_D-F6V-ֳ;+Y@rY}.Sh +ypo`*]@J|n7?*_!.[Kڍ<^f{O)~;$vox]m~X셣oQ:H4h?Xp!?-bH etgtHh9JD6Gn9pu@ }6Iېg Դχ= 뭉g`60N +xxnH6r'fT4Z~}WQow\ronH$< Ih+# J B3@C-(eǶ0T mH;*J: <{Yntg~;=|wחMTEgw:oG͊ȿP4WZ+H~T6KOl '},B0TzI<\CzFFEyUJV-Y TEOLy|dx 2`s+ȀT6'|>yJ[!_oS~ SR[[6HE^ϸq4Wztzē'95+6$O߶[.ghǂ|{ƺS&8SJ\b,,]to{7{wtߋnO"O+%8f+~|4JT-tH,P`*Bj)mV[hPz>x6UW| (,;]X#בLʵ)< HD9KF)Mrrl<їBY7+dF=C4BW)1vpBc4\5q@ka>>CJ@ e'?u>c#LgmI}'?6M }s]e}_ ϒs0Y: +3s`('!PB&p Xlf&9Tkk}gI/`j?3p,8>/Yy^pX-֌ͬot4 rpYkld,dh|&lȡt>0㜲-܏dcfL֚hMUK?A~yItЋ_(*5o".WPoW`tNρD*:]?`v!e'GBi 13}wuP#1uQ /klwݤzs`Yb +GS:0~5Q&־VPm}r)~z:IshI^8Ғd3ڻ;Ĕͱ3İ^m]fR.~[:9gO]F[w].6d>8{|$N|cn\'9@.N2WL 3F"s\|YKe=J;Ml4zbS(i>-x> J5ԨF6qb|2-!Z7%MuϚiham.\eOPbJ+0F;@_$cBwu ʔc:)"mPM< $TXEɢTa0ClMjfgrNT0u +>ߵzT7[1 +Jۇ<ȋ{뿝Z1%"VVZ V+eFMT+ { +y4!ZhQX߿QI]O +U2?8yQ5b>΅^;Kڶ +Cy$@uNq`Ֆb%E=OFplr(u?An6S;`;lǡCߧ:XP~jP$jh"m6^gn3V?cz<ȳj=w܍}x ^W1f'4u bn+VvG`Ltje#P/n(-`- + 5Ɍ?>'=;!ΙGu=Jjyc*?aah# QׇNinO_<#voSpZN^.5t'eS҃ʿ+n2:%H{A\76lGy$îGձ'lpSCx ^K 5۳~PGS^Ç1GQ߅sсp.Olƀ03Z-j2vvZy/$36ۗ6&l՚OphV+~@樋>sND]}Z+o"F$mx,?p}AAl +qO ƣ< _~lB@#0qC{_/D[-ƬB Ѐ2/=@^hw0#CYNپgy+^|{kvl%zaitq;Џ i)S9\gm6c+ΜNع$/;8|Kh,Zǧ7/#`q o}]9j^>c4۷=cڷZ5bT "`7ZUq#Pށjx@T2 " @G"TY1CEi}TEp>hZVBKűAZ4V[ZˏP|ݳ{wn%ϔrѹy˖<DF( =.뀎3-uGNy%Q9N[PϜy3sZkCeϛ-'0%rq|x޻x&O!#ҿ{o@ ^cN0_>x-/:MRN7-;}CC?B +Kߚ'csgGxgmi,[G+d_<2M̞-J>dڔ_wT7zcdjINrghnm'KJJگi.! uz ZCXrj8_8H(h\9o6wLu7.OI2^2Jz.S'O9u[:LpW̓bl1>d_'嚯jr}FJ7k/8q~]R!W2ɕkqZ%h$?dsWLrk+nl]S>ߑeNG˷kYXƶPMo eM? <=lLRTl,Cywޙo|,=,|r)c+3Z2M1̨OuTnRƭ\<+ɽ˓7pr8g- bd!m`v-C]>= +Fq6% +> +#Owl59.htQv'KgMzW1&š8ԫ֟zeq/kŏڵG[q/ +hEq/jǿ8Wm8jǏqvrG=.܌݁p-mMI! arH*[xsM QTøp,m{#V k[c";MðׅO hLu`_ѻuq6{pF9NeK.|v?lq6.vo\Rע44,bxHq@\DEz]3:sAͽs|:n6d#덥r5/cъ }:y[='e R;fx;"3Rw1qYYrohwlX=Ü=\b~ÑѧY)Vm#k?QjխڶkVs=oͺU6Eqݦv~M{d 9G)n$ Yw\:~IIvtg;fo _1CvwICpPAomAb}++ Rx璳!)d7vHὐΒDc.;?z_|Un\]"5ɍ|7y&V,vc6',iԛ3#1"S+B~hMjoJ2/I['Uo VyK6UQWhbB\NnƺDzϲjBC3+-7;Ƚ%[Y,B=QؕAV)ʯ[gyoV/^|GV˫ο۴`tv P.y_ƶvQ61um^-_Q|kbuT=Tz'e.y7m:ֿc +zuƆ?vX.gKo19TѨjo +Z-GYwGeqV$f&.̳͡"siܤ#&W#Wmg6}ϙ+2h~- +ï؋&}ʞU~ +xY%Ա㥿mO2Fq/+O=@0FG_~['11<7bG[=$ZeH\*y䤱''yw`{m!uku=œm rGXŌ;L n1cz{&&iGC6FOR~^W1Ɵȋ"G?Ī{vt! b3e_^jَ\-:)C\[\I5╪_F޵rBF؟1kiN9Ƙ}w[;(uq}Uu9̏mjL޲< +/ĕfėXGC:4X@Ǩ$f5~#9הDZI[=,M\Zri%NXN_%<ī{XxJnono ׶hX>=dI-r'ٮYiÖ{Xk>Mo1/XN&|'Od4=JyȧYNB/%)R 9)3G\Ԕ_oȟ|iC9)㷥E?u7]SO}dUOVٕJJj^F (qbY7݉"d+JL<%ZXk/w})=gݬץ +RԤX+5i"}d)#u%bYk|K<{ogD.ʿdiel!+F={?_<Ϣ;Q"l-d5%{%u7%/bK|E Y},-1OPVf8l]KGk%uyj읐nrJQھdM+˽ ^[6y޺=tOx=k#%e5c\7c U{J;$WeSnrQ]*λI1 );E13шYK0b.t9{ q%a1O%Xery9mUjensl&"[7ncfrW +;5bn7Ѷ=y/W'~| + nm'9zuZe Swdws\ .+Zp= nC_Np7GP3OgE2x}7]hS9|  ,!<" ""!2 *!:b &b!6 .!> !!1G$E2$G +D*FE:GdD&dFdE6dGD.y ~E~o(BQEQ Q%J4ʠ,ʡ<*"*2*:j&j6.>!1)9Z%Z5ڠ-ڡ=:#:3+;z'z7/?` a0`(0 (8L$LL4L ,<,",,2, +*:l&ll6l.>!1 )9󸀋˸븁wpp ^^_[xO/o΀ )?0 23#2#3 +23c2V0q ?2)19SSi阞Y٘9sga^|Y wfe1g ,,ò,ʬªڬúlll¦llllöl®þ¡8#88c8 I)iY9y\E\%\e\\U\5\u\ M-m]=}!1>3> +|÷|_] J~PU8WET$EVEU4EW T,VU\ .+Zp= n;^p?x< 'Y| >/[= ~! + # "#"""# +"#b"b#"#"# "#R"RAZCzd@FdBfdAVdCv@NBnA^C~(B("(b((R(2(r( +J*jZ:zhFh&hfhhVh6hvhN.n^>~菿7` a0`(a8F`$Fa4`,a<&`"&a2`*a:f`&fa6`.a>`!a1`)a9V`%*:l&[۰;{ppGpp'ppgppppWpp7ppwppO/o_?!AR40,1<#0"#120*1:c0&c160.1>0!110)19S0%S15`e:gfd&fffe6fgd.fe>gɂ,,¢,,,,ò,ʬªڬúlll¦llllöl®þsrsrsGrGs rs'r's +rsgrgsrsrs rsWjZznFn[۹;{yyyGyy'yygyyyyWyy7yywyO/o_?B!J$+*+"*"+*+b*b+*+*+*+R*RQZSzePFeRfeQVeSvPNRnQ^S~П*B*"*b**R*2*r* +J*jZ:zjFj&jfjjVj6jvjN.n^>~꯿hihiFhFihi&h&ihifhfihihihiVh*:m&Y[U۴];S[{W_tPtXGtTt\'tRtZgtVt^tQtYWtUt]7tSt[wtWt_PXOT\/RZoV^QY_U]?S!ҡځaZ89#8#989c8c9898989S8S9pu:wgt&gvgu6gwt.vu>w.......ʮ⪮ᚮڮ㺮nnnnnnnn{z{z{GzG{z{'z'{z{gzg{z{z{z{WjZzoFoϛ[۽;˻{}}ȇ}G}}'}`?d۶ݲ]˶m.۶ڲm-۶3\p>\ .+Zp= n;^p?x< 'Y| >/[= ~! +a #"""# +"#b"b#"#"# "#R"R# "#2"2# "#r"r#" +BaAQCq@IBiAYCyT@ETBeTAUTßZ:zhFh&hfhhVh6hvhN.n^>~ 11C1 1#1 +1c111 1S1 131 1s1 K ˱+ +c-X؀؄؂؆؁؅؃؇888888pgppppWpp7ppwppO/o_?!aAR4#0"#120*1:c0&c160.1>0!110)19S0%S150-1=30#3130+1;s0's170/1? `!fe1g d)fe9gVd%VfVe5ڬúlll¦llllöl®þ88C88#88c8888S88388s88 K˸+k7u\ M-m]=}~K5H5DC5L5B#5J5Fc5N5A5I5ES5M5C35K5Gs5O@ HDKL˵B+JFkѿZڠڤڢڦڡڥڣڧ::::::tZgtVt^tQtYWtUt]7tSt[wtWt_PXOT\/RZoV^QY_U]?S!ҡaށaZ#8#989c8c9898989S8S989383989s8s989 p!vu1w t)vu9wWt%WvWu5ᚮڮ㺮nnnnnnnn<ЃC>#>c>>Ss6x{Z8iӽvEnIsk]SGvmҽ{ă;ƿyH"2 +{}}}=^``dbfaecg?`?d?b?f?a?e?c?g`dbfaecg`dbfaecg`dbfaeKi:ԥi@hhH(=F/ +z%^Mz#Loz'M@YdC\Oc}>B4)(t.>]' +=IW逮':ݠtH[ݦ;i }>GTi<M6ضlѨ=ݰʳfeYzd ^r{52d,w~,/hbĨPZDDݙ4ҽn~WTU=*mq_׃r-\ Y4goAe#irQY:T(BYUHRo:V"JҬܫ()Q|;h3-xnFAA|ׂuPc:N s|_/ |_/{dnjVr5/.uwq$(WorPqZs丿E"wQ&ub+ZHa;mt*ˍ4O*xwTGbG,]7UE>Ҋ׼y'~zF۬(lM6Q.T]Fz- ;OmllmeL6Ѣ.^M9N,Gt4N!IP8 .a /\W(EaּYܽtݵq>վ*YZ[O?]RI.:QQY܅N:RU!J hRz^hY/P/ ={C^iC,BoOZV,:*&uo +&LBltxP$:PMŻQ&2TSho=2,bDzFJԫRV#'&qʢT/Z]JYW5+]L +eL]4b! +iu, +24I}5! E4΅M\8l ;ȕXkݩzAsӽS߆ӭ'6Rh.wwwwG娿s9ߜs9|>wuuuuM]p]p]p]p]p]p]\XX#MjAmPjyP:N3h :/w 3p<<3&=a,̚O?yf7=^9g=g8{7q9.q# +_fnUC5M?Dm.Ry-"{\d'ߴnGiNNN7:ӫ^~|x|<ޟ痉^ub.1t23ugIة;ubNF&G&Ǥ+zd{TG{8鸹S7o4}frYgMAv ;mݢtnOD4&M'QAR$T}0`!C0` 1c!c0`1c 1c0`L1c +)S0`LQQQQQQQQQQ. ;bd1bbch)F`X0, Âa`X0`-|ns [>uޟ>t:/_2𵅯-|mv:e>mm o[x6o??<~ o[./wO=?_/Ial c[ƶ0-mal c[ƶ0-m~:Pۗ^{<={<}a:0m o[x޶𶅷-mm o[x6koK=1{@~"b%:gB\w;|w;|7 ~7 ~7 ~7 ~?ßg3 ?ßg3 _/ _/ _Vx+ +o=}]hĎHpuݢ1m[m:Օ$itD#؈+ߝ}-|'w ~ {=o_l#l}~ۤ|qtw<}+iyyzyeOߏ__?~tǻ>3q0Z79,FNZcIHcA'9z9׌z9׌z8:qt3gt=Τkkkzciz3Ϛ>k*Q%4%}xK.$ݘ4M7M7MS靦wIӓg&gMϚ^{M5uM>j:TwN$\'Qt=LN8E'´d堓unEZNQjPNE-\pQ  Vt +VԓE=Yԓ,ɢ,JdQOdE=YԓE=YNY4]{v!ԭh*ujԪFjJ߭T:+5J::(>hh*jˊjjZZhj*ZZjjɑl\e*Bҵ;rU\U]rU.WuU]\.Wu9rU\u;p\Gw>i铦\?P\?P\?Pn!L]Gbt1n.N?rpphH +\n'7Nm4t;ii hi h,x=MMNMשaͦljͦl,k6?x~@H.Mgݳg7"sN8 糁ٰ{W~~ܻE + ܅Zih_ஔi]{U{1:fUǬP^˦մiirr!Fc1N\_k3q;??|zzza^23uFK% 3:cΘ3ȠJ BٮAdӁhĎHXNlę; ++ ++ ++ +rεUx^WUx^WUx^W9sx9<sx~~umoo3lteSF4:)NitJSFc, +_W+ +@4bGLLq$N*щ8>7|om|ӧO_ xI'1x'x'x'vJn] ? ^%Ui8N>yGRŀH⥤˦O <}>BGz"rE~.\cʯT]ާ|L>]ߧTO1S1cT{joS3u)j&_O{31c~LޘzۦT{joo׾u)j&_O{}S>^~|3gMot6M]}]:}ǔ_&_O{}S>^~jxs{5o;Ҧ6Դ 5mqOO%~JiLf6Ӵ4m}>6>Ѵ}4i}4iMhG> \g?ϴ3iOOOOOO~o 7~o 7|{nsӞܴ=7iM{nsӞܴ=7iM{lcӞ'=! iOH{BҞN}W]}:eH{E+^W"iH{E^߭"iH{E+///¯O~?EȽ}7ynwݼ}7yn{:~C:~K/?~~~~~~~~~~~>>>>>0pަ>w}]kvvvSzO^奔C={?ןAyE0Fc1c4h 1Dc!C4h 1Dc!#4Fh1Bc#4Fh'ZOta!bq8ī.>C<ŗn/a%,X|ˆn/g,ŗ츾_ Z|A/h-;Ѿ뿏ϷqM>n_wv|_C 1&.*vqOO%g|??OOOOOOOOo 7~o 7~_____W_W_W_Ww;~w;~ zCPo7 6lgs?7 ?(**********!K⣊xxo <))))))q/ 7wwww'?qO'}>q{{{{'{x'މwx'މs8/ r/}p_/ܗ|_WxW8S8S8S8S8w5>qxowu]5_/??埿~;*Z3 +xޛ yĖ=U]^^ l$11!L< [Dee+ ⳱ӽk2+>+PD !%c+#$:}_X>ܮ=哇 Ksh '/_(K'!`2Z ʘs`,cO2-0&/Ⳙt"!"!"!"! +~r`,c_1DC1DC1DCFGqDGqDGqD.oDKDKDKDKDKDKDKDKDKDKDKDKDKDKDKDKDKDKDKFODODOD.o1ES1ES1ES1ESAT.oqEDF[E[E[E[E[E[V} @Fh]v){ds_>wWLx<翀 +']qx2@D +3gB-0&06B"B}Jm,5Rxx,p6ʷB`H]!RW"Hac)oq[NJq[dl` l"Xdl#}6ȀM 9 e,L#+$>raR%ՆN#bđ"q#E6Jq?SRDV9vx)j +q2NV@p-#%SϊִDR&k_&DKDK^xr>>z'%F<+^}&%xӖ}{^HI{)%}ߕH߲ˢ>XD~d&R"%'Dd{*z)>zf4^"@})s}nD$zG/k߱%.&3=.u|"_!_;s!_;k|퐯^p83g? 3g? 9s?9s? /_ /_%K/_ %K/_ +W௠$\js(#Q/(Q^˽k$i&KKśwf$\8rf$\8rf$0/ψgŋKKse H+:xvs,L;z @o͇1&t14] MCt14] Mo>uj͟8a\ڬ +zr1\L 'vFQagTvFQagTc"?~G3I1F@^Ls`,^W8Џ? s`ф@Y-$d&+ʾ;+ʾ;+ʾ,dAGQ T8e&c0>+.dm+ ޣcq*{}}ȟwWOEbkoV0XVljGٞdsF77a> +'Ԉ f/.K8iV1(um6PZ񭚕O}FW ffRf.V )YuSnͪ +,WQZ"}_4CGd[g:?g5f޶ԃ[u{7/A5b|cJ3u{/G0H?tެ=ϛ!S]gUxN?]MJm|=fKU?vs?s}>V?hvłaq3Z\oXWy'zgWm/v1_jW~GoÙQ*dA}wmyyjyj9m^J_:vT꜇V-m}Gbc7å5smd]]tKVd {ݯ\mh[ nl;[z]Ѝ|_yt5 K +i~~v-jN'4W?,`S?5ThG[8n{>`Px:ȌR&X WGo9OgF56-5cZ~*xO}b0pWm?2)l7c ϱQow%M]6>jژ3|ι`  !؎#adk&dݰP|*"?uU-ZUZfmU|l4mڇ"30-նlZMt{1 _ y&m3ar6co@pƐcЄ`# Xv$SJAٰ9XV*/EF٘B0fppge6hQ@М*/)QJ̒S-a5z֧vԝ>1H"^t5*/[K3WMz/o>U% fU۬lV1|2=\g!RSJ$ZnVTͭ.jn= ZZ,+[N.˸~aw\\ *Z~<]kAf{nп4CW> $.sjJ:}:Ls\GsCW}@p]Ax,;<}4CGD1y^$AnU#<-[cjᛠ<|[,OO6M]vu{o$$ݤIfĖlI"*-Hv3mYzdaA,O-<=>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> +endstream endobj 77 0 obj <> endobj 78 0 obj <> endobj 79 0 obj <>stream +%!PS-Adobe-3.0 +%%Creator: Adobe Illustrator(R) 13.0 +%%AI8_CreatorVersion: 13.0.1 +%%For: (\701\756\760\750\761\756\742 \710\742\740\755) () +%%Title: (Exteor_v2.ai) +%%CreationDate: 7/15/2021 5:07 PM +%%BoundingBox: 65 35 830 575 +%%HiResBoundingBox: 65.8599 35.1387 829.9092 574.3154 +%%DocumentProcessColors: Cyan Magenta Yellow Black +%AI5_FileFormat 9.0 +%AI12_BuildNumber: 420 +%AI3_ColorUsage: Color +%AI7_ImageSettings: 0 +%%RGBProcessColor: 0 0 0 ([Совмещение]) +%AI3_TemplateBox: 421.5 296.7803 421.5 296.7803 +%AI3_TileBox: 129.2847 -117.3203 712.6045 712.6001 +%AI3_DocumentPreview: None +%AI5_ArtSize: 841.8896 595.2803 +%AI5_RulerUnits: 1 +%AI9_ColorModel: 1 +%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 +%AI5_TargetResolution: 800 +%AI5_NumLayers: 1 +%AI9_OpenToView: 104 402.2803 4 1841 965 26 0 0 44 75 0 0 1 1 1 0 1 +%AI5_OpenViewLayers: 7 +%%PageOrigin:0 0 +%AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 +%AI9_Flatten: 1 +%AI12_CMSettings: 00.MS +%%EndComments + +endstream endobj 80 0 obj <>stream +%%BoundingBox: 65 35 830 575 +%%HiResBoundingBox: 65.8599 35.1387 829.9092 574.3154 +%AI7_Thumbnail: 128 92 8 +%%BeginData: 8577 Hex Bytes +%0000330000660000990000CC0033000033330033660033990033CC0033FF +%0066000066330066660066990066CC0066FF009900009933009966009999 +%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 +%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 +%3333663333993333CC3333FF3366003366333366663366993366CC3366FF +%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 +%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 +%6600666600996600CC6600FF6633006633336633666633996633CC6633FF +%6666006666336666666666996666CC6666FF669900669933669966669999 +%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 +%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF +%9933009933339933669933999933CC9933FF996600996633996666996699 +%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 +%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF +%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 +%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 +%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF +%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC +%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 +%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 +%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 +%000011111111220000002200000022222222440000004400000044444444 +%550000005500000055555555770000007700000077777777880000008800 +%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB +%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF +%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF +%524C45FD3DFF7DFD07F827FD08FF52F827FD08FFFD07F827FD06FFA827FD +%07F8A8FD09FF52F8F87DFD3FFF27FD08F8A8FD07FFF8F8F8FD07FF7DFD08 +%F8A8FD05FF7DFD08F852FD09FFF8F8F8FD40FF27F8F87D7DA827F8F8FD07 +%FF7DF8F827FD07FF7DF8F852A87D52F8F87DFD05FF7DF8F8527DA852F8F8 +%7DFD08FF7DF8F852FD40FF27F8F8FFFFFF52F8F8A8FD06FF52F8F8F8FD07 +%FF7DF8F87DFFFF52F8F8A8FD05FF7DF8F87DFFFFA8F8F852FD08FF52F8F8 +%7DFD40FF27F8F8FFFFFF52F8F8FD07FF27F8F827FD07FF7DF8F87DFFFF7D +%F8F87DFD05FF7DF8F87DFFFF7DF8F87DFD08FFF8F827FD41FF27F8F8A8FF +%FF52F8F8A8FD06FF7DF8F827FD07FFA85227A8FFFF52F8F8A8FD05FFA827 +%527DFFFFA8F8F852FD07FF7DF8F852FD41FF27F8F8FFFFFF52F8F8A8FD07 +%FF27F827FD0CFFA8F8F827FD0CFF27F8F87DFD07FF52F8F87DA87DA8FD3E +%FF52F8F8A8FFFF52F8F8A8FD07FFF8F8F8FD0CFF52F8F852FD0AFF7DF8F8 +%F852FD08FFF8F8F8FFF8F827FD3EFF27F8F8FFFFFF52F8F8FD08FF27F827 +%FD0BFFA8F8F827FD0AFF7DF8F8F87DFD08FF7DF8F87DFF27F852FD3EFF52 +%F8F8A8FFFF52F8F8A8FD07FF27F8F8FD0BFF27F8F8A8FD0AFFA852F8F8F8 +%7DFD07FF52F8F8A8FFF8F827FD3EFF27F8F8FFFFFF52F8F8FD08FF27F827 +%FD0AFF7DF8F852FD0DFFA8F8F8F87DFD06FFF8F8F8FFFF27F852FD3EFF27 +%F8F8A8FFFF52F8F8A8FD07FFF8F8F8FD09FFA827F8F8A8FD0BFFA8FFFFA8 +%F8F852FD05FF52F8F852FFFFF8F827FD3EFF27F8F8FFFFFF52F8F8FD08FF +%27F827FD09FF7DF8F852FD09FF7D27F8A8FFFFA8F8F87DFD05FF52F8F827 +%5227F8F82727FD3DFF27F8F8A8FFFF52F8F8A8FD07FFF8F827FD09FFF8F8 +%F8FD0AFF7DF8F87DFFFFA8F8F852FD05FFFD0AF8FD3DFF27F8F8FFFFFF52 +%F8F8A8FD07FF27F827FD08FF52F8F8A8FD0AFF7DF8F8A8FFFFA8F8F87DFD +%05FF7DFD0552F8F82752FD3DFF27F8F8527D5227F8F8A8FD07FFF8F8F8FD +%07FF7DF8F8F8527D527D52A8FD05FF7DF8F8277D5252F8F852FD0BFFF8F8 +%27FD3EFF27FD08F8FD08FF27F827FD07FF52FD08F87DFD05FF7DFD08F87D +%FD0BFF27F852FD3EFF7DFD07F852FD08FF27F827FD07FF52FD08F8A8FD06 +%FF27FD06F827A8FD0BFFF8F827FD5AFFA8FD0FFFA8FD13FFA8FDFCFFFDFC +%FFFDFCFFFDFCFFFDFCFFFDFCFFFD47FFAFA9FD7EFF84AFFD7DFFA95F59AF +%FD7BFFAF842D3484FD7AFFAFAF34330B5FA9FD75FF7D52FFFFFF60333334 +%338AA87D527D527D527DA8FD6BFFA8F8F8CFFF84582D332D335F52FD07F8 +%7DFD6BFF52F852FFAF5F2D3433342D8352F852FFA8FF52F852FD6BFF27F8 +%A8FF8A2D332D342D335852F87DFFFFFF7DF87DFD6AFFA8F827FFAF583333 +%3433342D8352F87DFFFFFF52F852FD6AFF52F852FF5F332D332D332D3358 +%52F87DFFFFFF7DF87DFD6AFF27F8A8AFAE838AFD0584AF52F87DFFFFFF52 +%F852FD69FFA8F827AFA8277DFFFFAFFFAFFFFFA8F8F859FF52F8F8A8FD69 +%FF52F852FF7DF852FD09FF52F8F8F852FD6AFFA827F8A8837DF852FD08FF +%7D27F852F8277DFD69FFA8F84CAE587DF852FD07FF7DF827AE83AF27F87D +%FD68FF52F87D84337DF852FD07FF52F87D3433837DF852FD68FF27F87D7D +%8452F827A8FD06FF52F87D5E338352F852FD67FFA8FD09F8AFFD04FFAF52 +%F87D3433587DF852FD67FFA87EFD047D52F827A8AFFFFFFFAFAF51F87D58 +%0B5F52F852FD68FF8B5F33585883F8525F58A87D7DAF5F52F87D8383837D +%F852FD67FFAF5F2D332D587DF852832DA8F827835F52F8F8272727F8F852 +%FD66FFAFAF5F84606060A8277D8484A85252AE84A82751272E275227A88B +%FD66FF613D5AA19AA19A846161376161853D3D61855AA2A1A17D856185AF +%FD1BFFA8A8FFFFA8FFFFFFA8FD07FF7DFFFFFFA8FD07FF7DFD2CFFAE610E +%2F8C934B6F0D0E29150D300E2F072F0D15688C458C45155AFD1CFF7D52FD +%0A277D2752F8272727F8FD042752275227F8F85227FD2AFF61152FB46F53 +%4C1530936F932F308CB48C5314936F538C931561FD20FFA8FF7DFD0CFFA8 +%A8FFA8FFA8FFA8FF7D7DA8A8FD29FFAE610F2F8C6F4C4C0E154CFC6F1514 +%308C53151468928C8C2F1560FD1CFFFD057D52A87D5252FD047DA852A8FD +%047D527D7DFD32FF36152FFC6F542F3614708C930E1530FC28150E8C6F53 +%8C530F61FD1CFF5252527D527D7D7D527D52FD047D527D7D527D52527DA8 +%FD31FFAF610E30689368932F2F68306F701436685315378C700E938C3036 +%FD1CFF7D2752FD047D52A8527DA87D5252527D7D7D52A8527DFD05527D7D +%FD2CFF85AF85AF85AF85AF84AF8BAF84AF85AF85AF85AF84AF85AF84AFFD +%1CFF7D7D2752527D527D7D5252A85252527D527D527D7DFD0752277DFD65 +%FFA8FFFFA87DFFFFFFA8FD74FF52FD04277D272727522752277D27522752 +%5227275227272752A8FD65FFA87DFFA8FFFFFFA8FFA8A8A8FFFFFD04A8FF +%A8FFA8FFA8FFA8FD66FF52527D7D527D7D7D52FFFD077DA87D7D52527DA8 +%7D7DFD66FF7D52522727527D52527D7D527D2752527D527D2752F827527D +%52FD84FFA8FD33FFFD08A8FD26FF52F8272727F827F827277D2727F8FD04 +%27F827A8F8272727F827F827F827F8A8FD23FF7D7D7DA8FD047DA8FD05FF +%27FD07F852FD26FFA8A8FFFFFFA8FFFFFFA8FFA8A87DFFA8A8A8FFFFA8A8 +%FFA8A8A8FFA8A8A8FD0AFFFD08527DFD04FF27FD07F8A8FD04FF7DFD08F8 +%27FD05FF27F852527D5227F87DFD08FFFD07A8FD16FFA87D7D527D7D7D52 +%7DFD20FF27FD07F87DFFFFFFA8FD08F852FD04FFA8FD08F827FD05FF27F8 +%A8FFFFFF27F8A8FD07FF27FD07F87DFD15FF7D7D277DFD0552FD20FFF8F8 +%F827F827F8F852FFFFFF7DF8F827527D27F8F87DFD04FF7DF8F852A8FF52 +%F8F852FD05FF27F8A8FFFFA8F8F8FD07FFA8FD08F827FD15FFA87DFFFFFF +%A8FFFFFF7DA8A8FFA8FFA8FFA8FF7DFFA8FFA8FFA8FFA8FFA8FFA8FD09FF +%27F827FD09FFA8F8F87DFFFFA8F8F852FD04FFA8F8F852FFFF7DF8F87DFD +%05FFA8A8FFFFFF7DF852FD08FFF8F827A87D7DF8F827FD15FF525252FD07 +%27527D27FD04522727F82752527DF8FD042752525227A8FD07FFF8F827FD +%09FF7DF8F87DFFFF7DF8F87DFD04FFA827277DFFFF27F8F8FD0BFF27F87D +%FD07FFA8F8F852FFFFFFF8F852FD15FFA8A8A87DA87DFD05A87DA8A8FFA8 +%A87DA87D7DA8A8A8FD057DFD05A8FD07FFF8F852FD09FFA8F8F852FFFFFF +%52527DFD09FFA8F8F827FD0BFF27F8A8FD07FFA8F8F852FFFFFFF8F827FD +%15FF52FD0427522727277DFD0427F82752A8527D2727F8FD0427525252A8 +%FD0AFFF8F827A87DA87DA8FD04FF7DF8F87DFD06FFA8FD08FF7DF8F852FD +%0AFFA8F827FD08FFA8F8F852FFFFA8F8F827FD16FFA8FFA8FFA8A8A8FFFF +%FFFD04A87DFD0CA8FFA8FD0BFFFD08F87DFFFFFFA8F8F852A87DA8A8A8FD +%0AFF52F8F8A8FD0AFF7DF852FD09FFF8F852FFFFFFF8F827FD15FF5252FD +%047DA87D527D527DFD1DFFFD08F827FFFFFF7DFD08F87DFD09FF27F8F8A8 +%FD0AFF52F87DFD08FFA8F8F852A8A8A8F8F827FD15FFA85252277D52A827 +%52527D52FD1DFFA8A8A87DA87DF8F852FFFFFFA8FD08F852FD08FFA8F8F8 +%27FD0BFFF8F8A8FD09FFFD08F827FD15FF7DA8FD0EFFA8FFA8A8FD1BFFF8 +%F827FFFFFF7DF8F852A8FF7DF8F87DFD08FF7DF8F852FD0AFF7DF8F8FD09 +%FFA827FD07F852FD15FF522727F82752522727277D275252522727F82727 +%52F827F852FD15FFA8F8F852FFFFFFA8F8F852FFFFA8F8F852FD08FF52F8 +%F8A8FD0AFF7DF852FD0BFFA87DA8A8A8F8F827FD15FFA8FFFFFFA8FFFFFF +%A8FD06FFA8A8FFA8FD16FF527D7DFFFFA8F8F852FFFFFF7DF8F87DFFFF7D +%F8F87DFD08FF27F8F8FD0BFF27F87DFD10FFF8F852FD15FF52277D527D52 +%7D7DA852FD077D52A8FD047D5252527D527D7D7D527D527DA8FD05FFF8F8 +%27FFFFA8F8F852FFFFFFA8F8F852FFFFA8F8F852FD07FFA8F8F852FD0BFF +%27F8FD0BFF52527DFFFFFFF8F827FD15FF7DFD04527D7DA87D5252522752 +%527D525252A85252277D27FD06527D5252277DFD05FFF8F827FFFFA8F8F8 +%52FFFFFF7DF8F87DFFFF7DF8F87DFD07FF7DF8F852FD0AFFA8F827FD0AFF +%A8F8F827FFFFA8F8F827FD1CFFA8FD07FFA8FD07FF7DFD05FFA8FFA8FD09 +%FFF8F852FFFFA827F852FFFFFFA8F8F827A87D7DF8F852FD07FF52F8F8A8 +%FD0AFF52F852FD0BFFF8F827FFFFFFF8F827FD15FF7DFD082752277D527D +%525227272752275227277D27F8522727F82752FD08FFFD08F852FFFFFF7D +%FD08F852FD07FFF8F8F8A8FD0BFFA8FD0BFFA8F8F827527D52F8F827FD16 +%FFA8FFA8FFA8A8A8FFA8FFA8FFA8FFA8A8A8FFA8FFA8FFA8FFA8FFA8FFA8 +%FFA8FD09FF27FD07F87DFD04FF27FD06F827A8FD07FF272752FD19FFFD08 +%F827FD15FF5252FD067D52FD047DA87D7D52A852FD087DA852A87D7D52A8 +%7D7D52A8FFFFFFA8FD077DA8FD05FFFD07A8FD24FF52FD07F87DFD15FFFD +%047DFD04527D527D52FD047D527D5252527D7D277D527D52277D7D7D277D +%52522752FD5AFF5252FD067D527D7DA8527D277D52A8FD047D527D527D7D +%7D27A87D7D52A8FD5EFF7D7D52275227FD05527D27275252527D5227FD06 +%52FD047D2727527DFDFCFFFD0AFFFF +%%EndData + +endstream endobj 81 0 obj <>stream +%AI12_CompressedDataxYsJ8@jྈNJHj6 (Q&<>Le3vد4{o_?@,@pi'ʬ*hyv<7Y-LԄ6'dODB3*]ww4Î(~!z"P  +/)s$?zlvj{rwKzt<}<%^HS JL+$3_͆{f)00B4nҬ'DC0Do=>2GՔ-|@lv>3lԔ73]Iԡ'oMIo%}0-m{MYo㗡2ת́(Kڔm5Թ u uj/&?{ĭ0[[˷:ǜnAπXoӓ@֝09zw ^ie^7ZVc q\\œo~o8i~^]qV2|Vw~/11~~>M;ω@fA HM~6#5uUF}jS  dfVt煠0b]ӳ+z +jQ'qV г}4C7胿7N}d{L/߀:ArZط`yڟOE5 R~{u&&5?ɡ zh~Ȭ326 K<b<`<hοZx VY}M,b?L|rR!j?ꡐ;@3f#X7>*ds=0DȚLnVSjw"36X ؠ3b=?b~_~/ߣ/n^ń^D胐=K>5LM'3hɌVC ͑H >dߊ2y@cIIfݟz Z"gYdn gv<6ql4B) i^^c W1|lLq8!H}Bq? #.? 8+v9 +_ElYdH1Ω5 k_RfGrx`mҽΰ?h[fhⅦ + +=?:ߎC[*']lφFdTBVɶQΘ +dOf>O;F\nm1)lẀYCTݯ) :29C<'iPYfH3t7q [?ӏ&/M@G@1]&I:؃eL|2͘ KgVz_P2Pp< aN{rRٮ7 k+$Hb? F$blJsSKC+{M#Eoa)51 M PH. jizBzm奙h-+Xh< hbl"Ě}jtb5\2q Cxh:TTX)%ֶRd6q eӈy6-Mx'nZoӦ|ii^dx w&+5_Z,?Eto.7z ,]Za%&* a$R fO` &ـV ^#?(o4В՚M z\e[/aޔt!3(N*T5r&cB"j2J*%f˱ D`OZ tG& PfZw4FF-}f?ؖpcCo^ϗ$׀g ++ToLi44(子lWi$]jT'fmO\5Q.%TGh·QvtRVs|BC`Mխ|Al 7 e'iKR k0pFctӛL 6%9V}lBTdi6i<ÂvΎE>q;Bk6y!E,$6 +b[HĀQzv#gZ)U9e$sF&ek^C< cme6 VA 3-HQסkC2CJe|v L>2d`<\]gFCz[M$(Ie[iU;D4[ʂX»'O_4OQGoǟZJjJL[ɰT"n\Xf3uc9H~f7׽mmb2Px3Vh 闇EE5h 'QmĂ=-ͧL@#8h%3=j=Mk4!؎FGoEU! vRJnᑻjF Zp-1j60&>plpV>J匭[f\ "tM})E#0lۂ<̙ԍF3l +P[m7- Jhɡd + bLtk'n)50tx9-ȐA Ns]II}tsgΠ^UZh. `I#qo1=ï^fBP ʖ@Fu˓3~i\Τ#>3W +f͚mA~e?X<}83׮7g*k-d#qW9 /ؙ>8$텘[tZf&Iq>ҵ U>K*=X˫74}B^vK32. +{ YнFYo&]tfjL1tjl9~vwE#W~ +%B3~7|RobvCJghZ"U"ey*-A`+70D_B+~rա3Ȼ\2~^\c 3 T((&jEos&l| ~ܧ37V<Dz6ȍZKQw]cK:2tfǟAol4x/dGhx ù0VZهU:%X`8wonH`veJZYTĒ^Sod(<|oBxrfW|ɉ+\a28I~+L'4)*b[!1ĝ[6zDH_&rW]YGw<_atXشCĨ)X]S ̞}ȳ඙=Ryh&wOyQ]tja2Η]SU_mϲQ7&B.H97T# 5@(t;-p9Qu;X]k`qч^{d/:|H=/m_!~[O^ Xy;K~?'8n^@` +|BH$IE"I.Eͣxڶ tkA+#߃@\MҭJI⥬݁"<$6sFo_ |ܷyVQC=`ڟoC][쒙{vK#]YEDs.wIa|O>{j>nnp-{RNS_J/2KtS ۋ/ސ{d-'~ІS +͍+,=窙 ԓ#ssĖ;Q)!_:aS<V=g?Y)t7*<,S%&r^GD0X/bf|Rx+ +TO+~]аn(3\8ck#[V 5ݚ79h&T붃z}bb< /ǯdz9 +Hw x`j ~Sc_/(rc^3_ԥY|y":N4U$:}0S=BY!?[Qi/׹)*FA;kU"}sݺCOt +"73)u9"h@W-Ba>nѫ$#7fQ$[Ȕ2U?JnYl^ӑXս~{ixwJ఻ s gBn@cYi~8[cІO9kKɝ07UL z˺17+ +-Vܶ}bTWcv̍O`c忳. 'PS \X>Np(6_2]Cn"/pq ,h;͍I"-q=7'<8~/QB*5IBhDo/nN}g^mk> DtDZܲ" x^{ƺZʜktCgdso܀(&,OZr){ot,//9d `.Ś,&n:qC+ܶ +3K'7e&sWbD7//-"yCj;w-lͼΗ59@=S1wַ8|9E֛+0\(:%Țӳ^;Gz+W;:\Gq5$ALt+Px)N+j ^:cA\}pI2P^g +[1`O`U7aSˑx;GeMu_Z~)9JUʲ9WA~~q LL&ܜFz|HH<pmonf$FSR,/oŋb^ќ`ER@ƷУv]PȎeB + +c +|}䊉 H $u1 ,)-RhjwD&DRXW 9_nu _jb4qz ]`J-꓉N`cDxH{y0Y4ۺBBw NR|:\dh_ߍ@}%olZ0] +:=-䀖U:_K47s"6Z rjy%/#5ydxPHV>װg"r)SW+s)x4?XvaىArp} Rix9TVp囱BϒO^n 8 =jxH7'{Q$<=XiZ(GuYȵ PWӫV0W16ZnEV<2G*J vLy’"հ8/!PϽ_`)IkR +kUx{Y}+_`zu2_9gqTtKBifPDD}g"S|L.xƂ;-0istp@⠘^df&p 7eUw!^jԗ ~X~7%{mc{{܅ sSJ"҂b`{7WOOF8\ /cNΗQZHȡ\U_Ͷ+#2c{OL!7VsR[Y3#kSNTJLh{L$+~?3n0 #u毜03<+ 9!fRT_A֔p|%p0F* +[ZTiP8,h&)V|ZY(GFսf>sθ6W;P@ "4擱n >Ny6P dqV-9[FO'㔇x4MfN8B#=`ޒ@8ԏ}T5vFћRQ7&/r\dzTS˅8U",;ge(5UhZVjMLZ:㙐W-6-J |\?I~@OHZdz?KY$P\h/DhM _{w $WJ}`f{ |Z~{X2w?˿?/l~^z?Г@?/aM?=\o@`/~w&{Nc; +HETew-_5ҏzD#?CoEgx'ЈP+~h/?#p})90_qE?A?€U:L57n'ߺLYץ3?I4G3n0|LpCwyų'xWǘtxa+qWm<2\TdﰲՠmXH %:S63^Fg='({4@<z"&Ut{W$4mBֲ7,Kғ]@bJn0)e2l9k?v%?@T@qA[<_R[eñz,A +u4\ P*Mx[r`oIS@w &-jڟƓ ªbE]f/}Juc&9u͒V',N+ZC7S^=}i\ErG,I=ʾ'ӛG:ҡYP5 `l]ͮEZf[u~p qp=+S~fˇ j-V_]:ˆ 6etΉ1{@W<]) +wk^6\FKqwrk,G%֨^& H>>j.U/9MC R^>uޫCn*`5Q.ZJ܄fwPglPRzZxcTK2Ք_j@uK34\4-dVZ,QmD CgW <lߜZ[4!?ߘ!Pa*BwY[j IUɷҹ{dpnCӚTglM(r`=^=ԡ;ODoB=-L#܍T0tU,Wu&7gc'.w-Z`HجbCm +V*Ƞ>&Z9CPc-}}֐?%íMG&UO-(:1U+_Hj5>C-peV| +B#cMm!BE&\&^ ufNBwY4-v51|Uz]?MKJF+:V4>'״_jypT`iU7BPNFC+%ԊP"nh`5a+5O/Km{/&NJ"ut*qVo s 0z0[i[P +\9IV@=mWڜ%ok5*aj93S&6|{|bVRaNA5f*RILA٭:fӆQZg6 eOϯ_ӾR +)"7U<j9םX w +.l;6מEt8sjvf]iV;6[VW.sa4_ά.μ˾4!ٔ Q攲^6ܼ3tiHƚ8Y9CSGޫ̊Mˇ"TPQR*Q WP +5/2[v5ѼiC-=*rswjq"7ۥPs)JuhI(l Y- 7a%&PmGH r-4v:PA- .v-4FJO jSظz )=GO]ܼ*Dl$ѴvhȆE ^ Y1'^H!KYDƧ%\y dݎ:$෦33g9$ +1h jAa  p"0v̡Ф}..ď6l,PM}sd7tA.ٚ@p cxʑskiMCJ~@H'jStݒ.IʅPxǭ.!|Җn#<=D]mw!6S9DY ZRIe,}yѩ$AwK#BCld-j1_1FzSgg{K! \ +R[7< vp=r)D7<77u%:ݕDkM>^Q-T*sjN<\ [Kv ^K +LDq-֋Mo\Ūg?jC!!oQ(cw hS%:l#'mD(TG;c+>[1R0]I7XP[Z O *q^q vO76"4Hֻ[gW9Ly)hL gCʦ:۔B)Eґ,k5Wx)4uMetוB]eTR{^"pR:9S-Rkt 6Tg^ەɰH1ru>GI ao޼þވ<Ѩw xMͳkӻ}/Ck/iՊ4=˙< U_ ˤyLX$-e|Gw +sZayq(,jli"^֠Mw˚6 x +Lu-+X  (Ndc\2eQEgp()#NEx\eҖc`?e%]SeY7pB}6I_Qɤ& +T,rwm[oM# Zex%RL;D4\wXKE$RH/QȁRžA/a,@VXbGnX@AyvX1hW\z W}6s Q`!x4 +'++۹א">q +U ڌGjwԄ,$!7fl^Iaf3}.k-:ZAdj$ܫe%=ºYTEh74 sAWP IuE`Y@$CfnuCi2t\%O +~m d!l:0[~}Ah4䆺*in DiQo%C-!(7v$w6Uz*VvRTEȄ<>EC"7j']&l4Ura#cEyWZLl&~PW;l4m+ ~Ӓnַ1ս@}鶱H_AW5sPo MH4ԋtSr֎n +OwttCȤۉm܈A|lx@1VԊmdj_֔,r\ۇe K?oT?t]\]2mX-G'S (mkvTS}vSMY,TzcXlf鑠 5Nhsއ$Y)g še + x e4@Enel١I-p0Ewq. n-ɺtr5TZ>.a||'CZkNd"-ӯ7$y޷OO/O9"ZCsRr9|u`wQ 'QC p4Ʉ=o%$8jpsJ @ef6|\d^͍f +%K2BE|FGڕ"N Ɗao t鯛TLj-R˪U:; _jrD^k֥6F# m l+3Hl+3iGp`dZ痈fmw+ x)Ji{z'x9DBEA3VS ;ǽNE֪{Sz@grt2 q~e+ƀq=o>c=9_M +ٯ65r|Je.֙&N͡J2B!yUoxjr+1b7SC6tZh[*vv$NDSH݆/8DQIYUX)Fђ5H ͽeR?÷dV`ɀ?(VHh%vH@,OZ+̒V1p S.7tW3 SİMVА`+">:ʞgY4/O*v6C[kv@%w^Ń/]"8eL*\&$_ [F4U5z"z7xFōGo|/N,yE䩪kf݊dSNz0ќ6PoBHXEG)Ww\]T=U'Mqе,B+If(֣Aר"V_N+ivEyEyG=mJ u5m2xom๏W|sZa +A錅mQ:ƭ.Sn=*DNSXtn[3Vl:zj1uԮ\'l3%tTrswYO+l.mOFc|htݶ\m8IrXߚm|Ķ"A-ߒCȅ}b6}j^$lw>O;baNiO-D y>=qʱ +.wExfa@iUv&ޅ}j<'hTا]h}jU}]#UUXاV'(#iZاd[)SI3f¾9:?ri}:1 ԺR,>Oo[}G!¾]v@aZU!D(OR=RaM*>)wpT*S; t.q8faڐN7_O+ȅ}|cilOmH'Z''iثĻQK_ؾG#wz;-8Ʌ‰CWf @ކSlTHe\*]&Tڵ-Ib ͦcZNXњ}.یrkfwO#ܭo!_' BwRS]C3H^ya\O5m@A9V8688^5}r|nxzkC2oS0R<ܸKڢsnwoL׵n4vQ~[5U[}ScZAoJjLZטo,W3z8lhGC9@J̦!: V7CBoTmnTPs=7C e [B!?jZ?G7  ws5~w[F5Gޛ!IbrG:8yB]m c^qh +eHbQ(f* +.7ף{N{޿Ivcq.e$ '.<½'e[/S6o?1`oi2xվ^7WO ܎}Z'\!վЋfk.r;:z?n{tv&4eG ]]fs=o`v-IzÅTZ o({씺z3K[MomfJ< ytcu}O !{!ʹCHn|xEt9b'Ģ[hS$ 7Tɮϛ_2]~5ݳ6«[*QP/* |ՁZ4Lg 5yIwpU#SI5%P5rLlrUp z@*D;!WkBėVc{ׂӄ +`DTs ^9ӄj~> jQ%Bc-Ekԍ㿄P6ZMOfUB8ѨRFE l +e_՛*OymX!׺-vFҮ?J)s椥$;]z^){N+ev- UC;m#RT֭V/-qKMC%lU1BvzF(8-Ϟi3lc7(ባ40$nprm#4:.e>0m揵 qa(o]kqp ;9#[/ԉHK3﷖$=6ֶz5+y4y*yw:Mau,Op\{Sļ̓=#a>s3#aX<BG`.},$mPoԝF2YrFLu9Z2o.Qc#0\83R$i+2RT zoE]OT[ۥ;m[5nD۲0pњBRż&Whժ1XhQsy+I4Zm}]h$G$%F:[gP=ot$G<1\I#K۫J# +~I"?A2zYQ.zY[pxu/+u.+DӮm/;dv(Fcٚ?_x*ַ^xˉ{ +/)<…3T.<ܡT#C>k ժhC EěF{s煇}[/<g㫅W|ZW *dYc;q>c ^[Zi2p;ۅ5quQD?wfiqP̌_U;*70$bvN7 2u~{Xh +za-ەFQhټ!m]תusu:O +|˰LV IX1m-"oԈxiNS@49O6Ny.Gקɛ'k2x]:M:r跫D"E0Ũ ׎ "[[) oNhM5V"d |՘dAK)k†dR+2XrP\989x|"=i)8W/4hs@كѡ0AMZyWwRd}% jr/m{Rfh%=cLӡ +2_7y<}5~+]"޼sC$r:(r[k jAAty1.hJFI"4zV n>w,싓=0%j>s,Vd9r U:iYXMj T#"bbcs×S`>zӆw$)p}`CsZog86HkIXsx,Т#Y|_v_&pƩ WeԗEUCIt*৺eǵ/QoL7rpM"^؜ĨKTգs/=Η||SAHр&Ebx1ˁ9wHiL> x<<4EIs}m2L} [΅#кp]6 +y +i PV6"ZV`կo>ݸJ[Yg_$jOEρ- *A5sg,5#Qǡ#=+/W׆osy ^.u$:LrlKv$ʚ:<tpJ$58|bD"p Fǹ\*CIS#QЁˍP}OjEd7/2yNy`>M"n~S0fɟ{pHN,BЁ;nC:JE!XKWF@z8:w9 +|j +3rk !c5H +l10#ԍ#Kx|@yS'"Cg(NMլ!6EGk5#.p-45%"U2!Ԕp!\^!%]_^e\L"A+$Jrm'>Z(Jʔ1(!l)iJAQ[^+)|baF_Dk6/9VpHߞ!O~neCDqxO RH+Dzjt"yF͸ Ll^~ :o\ ]/w}Wt#)75x="H0諲о>eRu/hΓ* vZwFq:&}545LhY.tNw9x="+H"-CrL€/}l誸 ]yZ7sA&+<ye/*(aRaF-lY>~1j._ΖweSuZ^:s]FZ{C{2:*cLw[Mxn'J𚥰0^]G@H +/\o:}A%@7QM̼LҘ^l)U^Ĥc +sm|aL._\ڥ⻘73PR5Lk\~K(MM +J1S̭0iULxoO1a૳B'V9H&HՀj-Ls/bʦtcb"0Jʕ"ܪ׿@=U$ہAL `15x ͉v2[.ѩf +qa9-6IbQiHIW*zQj|RJ-fâ"EdvJt?&K<}MG }%r݊'&vT] )r(Q wBHB'ok5tg17^$ E\J'Fׯ('LPCYtPv0).y$6[vxb0;Z|Vn+m?JR1l;x:cT ͻʑTJC2%]7vl2BV m",a rCqJ;<gk,S!o&DA4+W~|,Ֆ5oi*2Ur'_=12\!v6ˣj,zH=g)XKAv*Sa-Lk1_D @%*zS_m%I] YR,{0[Ȼ@.Y»b!GuT r:$!$i0nYD>f*́wОKQd;lء$G#wqp]ey:TS3? +yD`9? SGRV?倏:) /s3A~(%zbVĉg>~F)Rd)dRavTHӡg%KXߜ]&v6XX O9"~ +ox>K[=A^?|)H\Ҙ{[Epqw.YyQ.rSDt:WșXνч}?z@ +OW:#ж +(܃qB~x- pZUIt( ~E +B nጬgVB ]3 D @; 6cN l < aCu'kܟA^)*`jq@έ ČS!o7琬8QIJEE䱒Nq*Vг[`ƢC<+{Ct 9o^݊_%樴}AK5J4hBACذjDK *DrnnX_8ك$ /gnX/:^M32 l&sG xX2ን oy'j y + Q}@wՍT`-TF^h452J_s蕥hh3U dDgg?)1Z-wG5lnlr]]UatN,)mBv +5[B #G`=>i$0, AtY?(zF\K&D/vVU.\)!ig<(g}GՀU;!àSJh k%g (%bi> d|iZ՘:WRIŃSq28N&:);YJ `tTל&1528I),x"*'t/eA9a) NӲIv7H@E]Ev +H }3 Iwv@{0JjxҼydIs$үo(PkG)C;$o[6$;7#)*b䈤Dmf@Y\@~I"FRեF]3-`=F٢/}°PmzDoء3W +m~>"œ`Nws@qIl 1k +&7G6 V?b(M'vY +η~T loR@:#AyrÃ{* ^ot ;REpppqK-Awyl V܍:Q︨2҉o /2'a%ߦ]&uȿBtϳȑkY6$莹j + +o8\#*j!DUx ?p1ʈ̹C҉xL5^֬ڸlW%L4cIC/< + I/˟FzB5q^8/x+dJG= 'xҨi #qܛt,#x8'2pqr"-@/-0-[jaZ +3 +-SUSOSq}ISd`-50Z+}9@lBaCZtiGlؔK0`١ٺٌlge.cb"KR* gNGptI%RIz4ZF֧u^ٛ8 +s9ÍswAayDHȕLS~|"B#l%PB\$fϜmL Sz<߆ +uCkʲ,Le0XʮHd CiБR)5jύxEڍyeHĞ/G8 lޙCNɥ̰I=̀Ḇf2ePL/V,񨭲}$%@OSpd~E!Pc_|vLsN~5B虏'PaULjXCdZXj3>gء| :M}<\lN"6ՋHz}<ғ&[r}ZyjMBnm}8~mm%~a=oM أL( YCԟkbizySK:AVw"BzyuNB7ݰ9^\'3߃Y%(eZ!nu(#]xחt&GO ^0HN ,Os}&c%®8(3|9MN[8T( \`-2zauE^+ʠ_jhq!Fd26r"|Z|{1e-CGĒ-?Oװ[R"Y諴^mZ|%6=+ bS_`umaB*?1?j?\}?ӣk\{ ^0G6qjJMhsRi#M Ж7ռ;OÈux|m<#O+͙uQ S\e\Rg+V./&\N]n/O?+ЦsWw^)pAYQ+ ŁM]t$ D-uq'([ʍ,.БGV"g3 Mo AݓPI*G2錸+"q)/_͠,?ǩ0)JT 81i=zBùZЍƓ-hee; gZ%ۻXX 4~/M<5wNHdjCd>A`gC7 -N|}xy6[|pTo1w{yvqy>egBzn-𡅤  +2fwMF9\cgC$/抧^.W;79z<+,@YIEMύbaXmv22:.-wkǫ̷͵qԨКߌ,|k]7 +43- \?M&Ez(;m p4 ͊o%wfg^Mjnl^l1ݛKh3h=.甩?'(yٚVaijmKXOvnnۈ%~=˜Vwo-z5oGfʷnX7=_/m_Cc +%I`3%1tT]pDߛYϞ-V}am珧N$aFqtb65EhXT`\l[rl`y|䋰x:sHqsSK:/AW2닥>wO-QJ |oLHy>MƤ@J-oSZءD^Ģc!PT,2Cx:bZ~ ڎgĭx¹VPtIpV^i堜uJo@a(^'yr@HH>oarO11Sv^^ì:þ)f>h*]5A<fuIn{;p]ol)BCcTZN[N^ +Ng'$ڋE]VϢ써94>΄piqO Tp6 Ҵ*(FA"0^ς]98{M|"EXx +iT?OݜL{4sk>| Hxd2c2;f>c>8̀]`oaI C9 *6Iȯi5zCU@7&W@f:薷f"#/`GN^@NGvGhȕu\>EȕdڻݰB:Ll*c?"0+0髣ꈼꊐ =r6|G~=]63*wי |PMBu͵NCҷfҠ!Gzу/>%mXi=񺔘H_֎>p3;#i#G?a׸ė;fU@~40K̸ #}q1%v􂑾aS%Pldl2̞{ɰ{N2\NsI^ֿ$ed_Ez3z_J8yvL +2*_^\~˰M2ih38S;2зݤRh|~QqB:Ϗbm)w ӈ;LYvH ݿ$^#x뎓w}ɛe8I6b&u;ML+$k0ҏuܾMYIٶk>$s"rNs] ۋNm'99ݷޓ$K-֩枓Ultr1p0wĶSfw/ZtD{skn}vr;$\y,m')mizSSK#zyL"ya?Rk#գ#{{lv=R[Ic~r6oԜ.[?M|]WYǬ><_:Z_-|dWذ5Xױ#KDydjgWDS KP,ɰsҒ#&ַO4tG@-]5R}nJV!;+9cg[XX!dHer<1̏~"7ؘ5ؑݗQw]ZjN%)7~6չ󫑑XbF^Mwb/ +~Acgi'7v)ot`loL oBѹgz.Wel:6& ^]ШE6(Vi.2QH+p9e$H45 jNʓO#B%њWo૷/=^C\jUB +QM:\bbq~C!ɏ6wTYW6w6+{N.lڪ*&yyjn`A_h +qTXkX +nv?R=`T?R2k3[V݇/U!VDf5oj*2.]fjr94Wٟn3OcxS0W{4~fnoGנ=55~/F <Ԯʁ;Ip|QmwFUY ,$:fZv0lZ)&M7f)@̀CNì w*Pf8 @zU'HNo: PCkg{< Fs`|)Si!f^7 ܢrTH yDz<Ȇ;t#AAO p!aF5Z +ɤFvwsʋ>.u~Z++NxI_k:2 %,ګ!X +ǰԵW\RuQ^!!Ws=<4 O ꀬ:NgO Dv!ubb>^CUلt{. V@ g@+ô, +>arN}R_/ЫPXWug|q$Bkpl2RwtXWF" ƕ),j5{pf" uu8,:<>i!!Ui* FN_qP"+1NhP]"QB٬ >r{Y؛thhZ 7>%=PUvSCiv޿k\X!,aqD_q?4JA + B(ۏ 7Q?Wu-ᓦ9$cVi=dYeWsH}z{xdyk2kʯjq<?7,ԛ"8=$,T a g"OC\M%1CJ§`‹SPT 7FD WZQ p!öK?h}ơ53oVQ Pv$'_!DSo\!)7GK>f-7U!$I"/OB <pϨ[tx{Bs1 c!>ƼrxW [̰Û!$okjwNVIaÛ}:!%-CS䧁zr'5BrjN ݩ}ژ\|=HѩG'(hB]B"* 4ے(*OwTw$=>7Zs >)/6rFgWK۞;͎U]aLG, 6rPg@{L],Zl+L|HңHڸozbC/#빝[dO(5+qu 񇇚Rg^^q\{viFќB7_ܡ'@Z&(iҤ$KS5i a + |Tu"<K4L؜;-[!2~3q+k(vEd?|{>vC~z MZ!f3xvI,o +~ 4k'cij GԈi=*Zڲ#0b <47諨ucZ<y/%k>b1ʟf/mk[ +CH?o?SY(}~,fʞ^]N +-SP^‡f/ +%oڿήe ̷s\v7Ow, &3v̇kE ZqF joCNęvY6^A{ك'rD-a$v{ +G"n $1ѳ ""? +=Mr +x%}=wNh;:nCF Y'}?0 :W؅` R_\4 7:o9Aa<Y.uCA586<_=i;A{h]P+8G6"#9uqEL)F#| @b0|92bFؼ_hȐñHvyw\u5mھp%Riq @st+<ĸ> "Tqqr!6f#hm:ĎGaD&^Dm\E 3~Ub(`mhOD8z;jN{x8^ȕQ|f"X|9<-D<pՌH%k% LN$ aQ02.*5o]^>0 Rd A]qAԓd/u1%6ht8UF4V}˪~ka#y&&6G b|cM{BM'iuE4+`b'4مC?_UԤ`|jȲ?E=Uջe$ԇ'5;(ƕsP`A}' ^`?$<ƾKZ14@jʆ+Acp τ9 *jf=0 胦@c8e (ߍDPǒDPցt#ڠ11lT1R ɛ8! +Gi!D'VyKfUt"r[xme5Y@;df.%1p@ e>5H, Oo:a\LQ4oNAmN+sF/9 ܚ,<98hr=@z0<5Y<16>̬Uq!iv$aUUK}{PjQZڨTA6jM')-srFȅJPl4`[?ArtT bS&M"0 ++h&9w<xP76h +ߘuXgT#׮)s %sV1AIjb$U:!w^;[‹>O܎B_oKÿ5a6ID4})딊D(CH8\DYDUR#n6\T'ΤC^<ȲAO8|"/cl>B@ icZۤan Aqi"@WƆ2`̸O#ron0Ֆ)JAIqB<p>L䒋Fx~&kb$:`'Bo 13bi$n"^o3'!I0>$S r6r_ߓ˄hcD&,0|] N$\ <-#d8e*R(`FwXƐvIb r Qʱ0Aﻁi1 Z N698qpi;L,c)DF RE 9J&֏nB9OCܾ9ISbTu"`{h +9r㱶ITN +KwbDdxD8]ȁ9ՔCGE;=8L1ŮY20ŘaH] m -8]u±@E0J\ C}rD9&0 0QàiL}Y۵K2=36ϯ?qu緷wOO{){}O}q/`!]`llqc)2 +endstream endobj 94 0 obj <> endobj xref +0 101 +0000000002 65535 f +0000000016 00000 n +0000000004 00000 f +0000024001 00000 n +0000000005 00000 f +0000000007 00000 f +0000024052 00000 n +0000000009 00000 f +0000024852 00000 n +0000000010 00000 f +0000000011 00000 f +0000000012 00000 f +0000000013 00000 f +0000000014 00000 f +0000000017 00000 f +0000024711 00000 n +0000024742 00000 n +0000000018 00000 f +0000000019 00000 f +0000000020 00000 f +0000000021 00000 f +0000000022 00000 f +0000000023 00000 f +0000000024 00000 f +0000000025 00000 f +0000000026 00000 f +0000000027 00000 f +0000000028 00000 f +0000000029 00000 f +0000000030 00000 f +0000000031 00000 f +0000000032 00000 f +0000000033 00000 f +0000000034 00000 f +0000000035 00000 f +0000000039 00000 f +0000024129 00000 n +0000024595 00000 n +0000024626 00000 n +0000000040 00000 f +0000000041 00000 f +0000000042 00000 f +0000000043 00000 f +0000000044 00000 f +0000000045 00000 f +0000000046 00000 f +0000000047 00000 f +0000000048 00000 f +0000000049 00000 f +0000000050 00000 f +0000000051 00000 f +0000000052 00000 f +0000000053 00000 f +0000000054 00000 f +0000000055 00000 f +0000000056 00000 f +0000000057 00000 f +0000000058 00000 f +0000000059 00000 f +0000000063 00001 f +0000024207 00000 n +0000024479 00000 n +0000024510 00000 n +0000000064 00000 f +0000000065 00000 f +0000000066 00000 f +0000000067 00000 f +0000000068 00000 f +0000000069 00000 f +0000000070 00000 f +0000000071 00001 f +0000000072 00000 f +0000000073 00000 f +0000000074 00000 f +0000000075 00000 f +0000000076 00000 f +0000000082 00000 f +0000081355 00000 n +0000081429 00000 n +0000081603 00000 n +0000082647 00000 n +0000091427 00000 n +0000000000 00001 f +0000024827 00000 n +0000024285 00000 n +0000024363 00000 n +0000024394 00000 n +0000029121 00000 n +0000029234 00000 n +0000029378 00000 n +0000029917 00000 n +0000030351 00000 n +0000030623 00000 n +0000025235 00000 n +0000126380 00000 n +0000030692 00000 n +0000029403 00000 n +0000080793 00000 n +0000080841 00000 n +0000028363 00000 n +0000000189 00000 n +trailer +<]>> +startxref +126554 +%%EOF diff --git a/distr/design/Exteor_v2.png b/distr/design/Exteor_v2.png new file mode 100644 index 0000000..afd63eb Binary files /dev/null and b/distr/design/Exteor_v2.png differ diff --git a/distr/design/oss.ai b/distr/design/oss.ai new file mode 100644 index 0000000..4d8f139 --- /dev/null +++ b/distr/design/oss.ai @@ -0,0 +1,1827 @@ +%PDF-1.5 % +1 0 obj <>/OCGs[6 0 R 30 0 R 53 0 R 76 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + application/pdf + + + Печать + + + + + 2019-04-30T13:27:05+03:00 + 2019-04-30T13:27:05+03:00 + 2019-04-29T16:37:19+03:00 + Adobe Illustrator CS6 (Windows) + + + + 200 + 256 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAADIAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A87adp3nD8w/OAtLQPq/m TV3lkVZJURpGRGmf45mRFCojEAsOlBirM/8AoVz89v8AqWf+n7T/APsoxV3/AEK5+e3/AFLP/T9p /wD2UYq7/oVz89v+pZ/6ftP/AOyjFXf9Cufnt/1LP/T9p/8A2UYq7/oVz89v+pZ/6ftP/wCyjFXf 9Cufnt/1LP8A0/af/wBlGKu/6Fc/Pb/qWf8Ap+0//soxV3/Qrn57f9Sz/wBP2n/9lGKu/wChXPz2 /wCpZ/6ftP8A+yjFXf8AQrn57f8AUs/9P2n/APZRirv+hXPz2/6ln/p+0/8A7KMVd/0K5+e3/Us/ 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 + + + + + + uuid:5904569b-e4b9-49ae-9f31-2925c8a5166e + xmp.did:133A89E9836AE9119321B2441BD85ACE + uuid:5D20892493BFDB11914A8590D31508C8 + proof:pdf + + uuid:ed609a61-4e0b-e047-bd4d-722efb68a6ed + xmp.did:0980117407206811822A897E387FE54C + uuid:5D20892493BFDB11914A8590D31508C8 + proof:pdf + + + + + saved + xmp.iid:133A89E9836AE9119321B2441BD85ACE + 2019-04-29T16:37:20+03:00 + Adobe Illustrator CS6 (Windows) + / + + + + + + Document + Print + + + False + False + 1 + + 256.000000 + 256.000000 + Pixels + + + + + AgencyFB-Bold + Agency FB + Bold + Open Type + Version 1.01 + False + AGENCYB.TTF + + + + + + Cyan + Magenta + Yellow + Black + + + + + + Группа образцов по умолчанию + 0 + + + + Белый + RGB + PROCESS + 255 + 255 + 255 + + + Черный + RGB + PROCESS + 29 + 29 + 27 + + + CMYK красный + RGB + PROCESS + 227 + 6 + 19 + + + CMYK желтый + RGB + PROCESS + 255 + 237 + 0 + + + CMYK зеленый + RGB + PROCESS + 0 + 150 + 64 + + + CMYK голубой + RGB + PROCESS + 0 + 159 + 227 + + + CMYK синий + RGB + PROCESS + 49 + 39 + 131 + + + CMYK пурпурный + RGB + PROCESS + 230 + 0 + 126 + + + C=15 M=100 Y=90 K=10 + RGB + PROCESS + 190 + 22 + 34 + + + C=0 M=90 Y=85 K=0 + RGB + PROCESS + 230 + 51 + 42 + + + C=0 M=80 Y=95 K=0 + RGB + PROCESS + 233 + 78 + 27 + + + C=0 M=50 Y=100 K=0 + RGB + PROCESS + 243 + 146 + 0 + + + C=0 M=35 Y=85 K=0 + RGB + PROCESS + 249 + 178 + 51 + + + C=5 M=0 Y=90 K=0 + RGB + PROCESS + 252 + 234 + 16 + + + C=20 M=0 Y=100 K=0 + RGB + PROCESS + 222 + 220 + 0 + + + C=50 M=0 Y=100 K=0 + RGB + PROCESS + 149 + 193 + 31 + + + C=75 M=0 Y=100 K=0 + RGB + PROCESS + 58 + 170 + 53 + + + C=85 M=10 Y=100 K=10 + RGB + PROCESS + 0 + 141 + 54 + + + C=90 M=30 Y=95 K=30 + RGB + PROCESS + 0 + 102 + 51 + + + C=75 M=0 Y=75 K=0 + RGB + PROCESS + 47 + 172 + 102 + + + C=80 M=10 Y=45 K=0 + RGB + PROCESS + 0 + 161 + 154 + + + C=70 M=15 Y=0 K=0 + RGB + PROCESS + 54 + 169 + 225 + + + C=85 M=50 Y=0 K=0 + RGB + PROCESS + 29 + 113 + 184 + + + C=100 M=95 Y=5 K=0 + RGB + PROCESS + 45 + 46 + 131 + + + C=100 M=100 Y=25 K=25 + RGB + PROCESS + 41 + 35 + 92 + + + C=75 M=100 Y=0 K=0 + RGB + PROCESS + 102 + 36 + 131 + + + C=50 M=100 Y=0 K=0 + RGB + PROCESS + 149 + 27 + 129 + + + C=35 M=100 Y=35 K=10 + RGB + PROCESS + 163 + 25 + 91 + + + C=10 M=100 Y=50 K=0 + RGB + PROCESS + 214 + 11 + 82 + + + C=0 M=95 Y=20 K=0 + RGB + PROCESS + 231 + 29 + 115 + + + C=25 M=25 Y=40 K=0 + RGB + PROCESS + 203 + 187 + 160 + + + C=40 M=45 Y=50 K=5 + RGB + PROCESS + 164 + 138 + 123 + + + C=50 M=50 Y=60 K=25 + RGB + PROCESS + 123 + 106 + 88 + + + C=55 M=60 Y=65 K=40 + RGB + PROCESS + 99 + 78 + 66 + + + C=25 M=40 Y=65 K=0 + RGB + PROCESS + 202 + 158 + 103 + + + C=30 M=50 Y=75 K=10 + RGB + PROCESS + 177 + 127 + 74 + + + C=35 M=60 Y=80 K=25 + RGB + PROCESS + 147 + 96 + 55 + + + C=40 M=65 Y=90 K=35 + RGB + PROCESS + 125 + 78 + 36 + + + C=40 M=70 Y=100 K=50 + RGB + PROCESS + 104 + 60 + 17 + + + C=70 M=50 Y=80 K=70 + RGB + PROCESS + 67 + 41 + 24 + + + + + + Оттенки серого + 1 + + + + C=0 M=0 Y=0 K=100 + RGB + PROCESS + 29 + 29 + 27 + + + C=0 M=0 Y=0 K=90 + RGB + PROCESS + 60 + 60 + 59 + + + C=0 M=0 Y=0 K=80 + RGB + PROCESS + 87 + 87 + 86 + + + C=0 M=0 Y=0 K=70 + RGB + PROCESS + 112 + 111 + 111 + + + C=0 M=0 Y=0 K=60 + RGB + PROCESS + 135 + 135 + 135 + + + C=0 M=0 Y=0 K=50 + RGB + PROCESS + 157 + 157 + 156 + + + C=0 M=0 Y=0 K=40 + RGB + PROCESS + 178 + 178 + 178 + + + C=0 M=0 Y=0 K=30 + RGB + PROCESS + 198 + 198 + 198 + + + C=0 M=0 Y=0 K=20 + RGB + PROCESS + 218 + 218 + 218 + + + C=0 M=0 Y=0 K=10 + RGB + PROCESS + 237 + 237 + 237 + + + C=0 M=0 Y=0 K=5 + RGB + PROCESS + 246 + 246 + 246 + + + + + + Яркость + 1 + + + + C=0 M=100 Y=100 K=0 + RGB + PROCESS + 227 + 6 + 19 + + + C=0 M=75 Y=100 K=0 + RGB + PROCESS + 234 + 91 + 12 + + + C=0 M=10 Y=95 K=0 + RGB + PROCESS + 255 + 222 + 0 + + + C=85 M=10 Y=100 K=0 + RGB + PROCESS + 0 + 152 + 58 + + + C=100 M=90 Y=0 K=0 + RGB + PROCESS + 39 + 52 + 139 + + + C=60 M=90 Y=0 K=0 + RGB + PROCESS + 130 + 54 + 140 + + + + + + + + + Adobe PDF library 10.01 + + + + + + + + + + + + + + + + + + + + + + + + + +endstream endobj 3 0 obj <> endobj 8 0 obj <>/Resources<>/ExtGState<>/Font<>/ProcSet[/PDF/Text]/Properties<>>>/Thumb 82 0 R/TrimBox[0.0 0.0 256.0 256.0]/Type/Page>> endobj 78 0 obj <>stream +HT]k@ |_Ƕ`~ +4^Kh=wd'=I(b^hFxw9b:8R؍H\t߆'}?;.YE?ղϠ8J-7N Fn@!\[{׷nW%P +4~ ~3w9 j*JbzK*Yd2xCz1q볠=OkeOHly"hyOú<*lNi .|緇< >>Iy de-P8!Y8/elmJCDtC&OS3gj^-o}ה!]7nfT54^CLW\ZpGHs/,ԫ`3m +endstream endobj 82 0 obj <>stream +8;W"`d1O8=#_k-%T&L`813["M,<-*-3Z@=K#d&X0E^rAZs/:JkijLUQqa>@[2lJm) +#Rr=e03f-\H?Ht4/K&`P=T(ZYA +Itm-/Aoc'ViTK%GbNT6rH^^;t/(-4L6gsc!*JqEZo:="dqf,,b`gH4u]-cH$FU,'t +aE;Ji]id8bp.*H@_igL)r940?l;'";k1'D58"<=/Ij_!mP6'8piaus(B9U"6!+9?G=o~> +endstream endobj 83 0 obj [/Indexed/DeviceRGB 255 84 0 R] endobj 84 0 obj <>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> +endstream endobj 76 0 obj <9 1)/Type/OCG/Usage 86 0 R>> endobj 85 0 obj [/View/Design] endobj 86 0 obj <>>> endobj 75 0 obj <> endobj 87 0 obj <> endobj 88 0 obj <>stream +HV \TU{gg:,J# /"MlcZ楬V>G-wuustwgrs{; .=*7!iޥ-qβ!~X N+S6mgq٤/n hIk$|J4 +K)!CI}*)< g%7(po. Dq2zM4tgi'\"U6cVEG\ʋg[i+ +ieZu:}wq*-`JPFh2ӇqqOtoZX5'[KzEJ]󳛉ޘJ w ӅGtGvե[=$2GwocIH쓔ܷ_JSM4xehzՖXְ#F>>jtΘܱO=o'a' +'L2uZe3gU̞TyO_׳=h K.sW-_r׬}u?~Mu7ܱ]#׼v}xG~'ǎ8gq_}}\ˍW( a}X:eNV51pI|I!븎yWރx4OwMh`ҘLHSWSS)0O Rgl"ܡl spϷȣx7νnBe YL聦p_lDF_!7^ٸs5liޠ^0Ɇ ?{7v@,Ӱ <۷]x X*lpZƿ`)؂8cx(jS8N |z|NOX1)L-gP&a +&c*J1 ӱ 30e(,F)\G%a.G-6 .<<"c.2{>s8%xVr4.jm=^G+4c61,z;)/IROfj~/{;ZynP殒z/hwWʘOӌgpJ)kɶkpCY,iGT퀕,ZMyFH(8RYGna2*ZM|sl!ܫdÇe=if <(ԁKx$>wdׅj4j(0٤L*ZʊWtIg+Cdl#s7PdqH/t< iq&q*Z6>N +^yWVE{RFmQ%V.3əsJ6j28L[*a3 І(ʢ,GmVј!Ë%k2/pFs/!ۡP*tNˢE۽Dc$3(Zr'YmrD`cZ&`ڬtF[oјuw[DfčFKUȮO7KBl,8O]' j wHFT6S%y|e{$?hG~Arw%՗vb%V@N-b z)@`r;?LgpG 6‹%!XӗMF_)|pVu+1&6}}LzOݙt;Z+_:]cl^_e3:G KUan)מFiL}\'%H-( Lw>p1% O]j'!BE`a>yn Щt疢 s" Ͱv8fՊu^`M]hVA]%"$}0kI\'1bKFSƤHV6כZJմz4Uս4X VtL`@Ka.lIOš(kHZ݉e1Uݫ[: ]H&H_?&'12P0 tBF;H€va!FvS@CiB a[0͐n6j:im6M1Mi63Ǔ!4ϻ{{MVVzr,e b7z%-ާZNqeeTz_O\+F*'oM9aD ԷVzY{HN]!wr2!]NW*,Yނ)L. ],A?2I]NzR;}fTQXZQQtg }ӃL{:Mk}kŦsL~SwYiqUvz:s/l]"?0Y34@&*R)U*#|Rz|aݣ8ic|tjq*59fS=VZ>>peNWQЫ '~Ӊy$sn^u#^q8f uŞb;V71ge(?HrIMQ˱%lZfZed|yDSCdž<9-زzȩ/*8Ax ^=LYpjt脮|hAq &莂F@- j TUfF*(@fخGy}ɱ'w)YJP 6e(J"+B!v!%XT2|DpG-69?$ĕѢ 9-3AEs?_jnŠ\8'vˇͭ:9N׳^PQ^i u~ӇmzLFSb +endstream endobj 81 0 obj <> endobj 80 0 obj [/ICCBased 89 0 R] endobj 89 0 obj <>stream +HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  + 2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 +V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= +x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- +ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 +N')].uJr + wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 +n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! +zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km +endstream endobj 79 0 obj <> endobj 90 0 obj <> endobj 91 0 obj <>stream +%!PS-Adobe-3.0 +%%Creator: Adobe Illustrator(R) 14.0 +%%AI8_CreatorVersion: 16.0.0 +%%For: (\715\750\752\750\762\750\755 \700\753\745\752\761\745\751) () +%%Title: (OCC.ai) +%%CreationDate: 4/30/2019 1:27 PM +%%Canvassize: 16383 +%%BoundingBox: 28 -256 227 0 +%%HiResBoundingBox: 28.1514 -256 226.46 0 +%%DocumentProcessColors: Cyan Magenta Yellow Black +%AI5_FileFormat 10.0 +%AI12_BuildNumber: 682 +%AI3_ColorUsage: Color +%AI7_ImageSettings: 0 +%%RGBProcessColor: 0 0 0 ([Совмещение]) +%AI3_Cropmarks: 0 -256 256 0 +%AI3_TemplateBox: 128.5 -128.5 128.5 -128.5 +%AI3_TileBox: -163.6602 -542.96 419.6602 286.96 +%AI3_DocumentPreview: None +%AI5_ArtSize: 14400 14400 +%AI5_RulerUnits: 6 +%AI9_ColorModel: 1 +%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 +%AI5_TargetResolution: 800 +%AI5_NumLayers: 1 +%AI9_OpenToView: -553 115 2 2502 1274 18 0 0 9 117 0 0 0 1 1 0 1 1 0 +%AI5_OpenViewLayers: 7 +%%PageOrigin:-178 -524 +%AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 +%AI9_Flatten: 1 +%AI12_CMSettings: 00.MS +%%EndComments + +endstream endobj 92 0 obj <>stream +%%BoundingBox: 28 -256 227 0 +%%HiResBoundingBox: 28.1514 -256 226.46 0 +%AI7_Thumbnail: 100 128 8 +%%BeginData: 12241 Hex Bytes +%0000330000660000990000CC0033000033330033660033990033CC0033FF +%0066000066330066660066990066CC0066FF009900009933009966009999 +%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 +%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 +%3333663333993333CC3333FF3366003366333366663366993366CC3366FF +%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 +%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 +%6600666600996600CC6600FF6633006633336633666633996633CC6633FF +%6666006666336666666666996666CC6666FF669900669933669966669999 +%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 +%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF +%9933009933339933669933999933CC9933FF996600996633996666996699 +%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 +%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF +%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 +%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 +%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF +%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC +%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 +%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 +%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 +%000011111111220000002200000022222222440000004400000044444444 +%550000005500000055555555770000007700000077777777880000008800 +%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB +%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF +%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF +%524C457DFD61F852FFFD63F8A8FD04F827F827F827F827F827F827F827F8 +%27F827F827F827F827F827F827F827F827F827F827F827F827F827F827F8 +%27F827F827F827F827F827F827F827F827F827F827F827F827F827F827F8 +%27F827F827F827F827F827F827F827F827FD04F8A8F8F8F8FFFFFFA8FFA8 +%FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 +%FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 +%FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFF8F8F8 +%A8F8F827FD5DFF27F827A8F8F8F8FD5DFF27F8F8A8F8F827FD0BFFCA9AC3 +%A0C39AC3A0C39AC3A0C39ACAFD0EFFCAC3A0C39AC3A0C39AC3A0C39ACAFD +%0FFFC99AC39AC3A0C39AC3A0C39AC3CAFD0AFF27F8F8A8F8F8F8FD0AFFC3 +%8C8C688C8C8C688C8C8C688C8C8C68BCFD0CFF9A8C688C8C8C688C8C8C68 +%8C8C8C689AFD0CFFCA93688C8C8C688C8C8C688C8C8C688CA1FD09FFF8F8 +%F8A8F8F827FD0AFF938C8C938C928C938C928C938C928C928CFD0CFF938C +%938C928C938C928C938C928C938CCAFD0BFFC38C938C928C938C928C938C +%928C938CBCFD09FF27F8F8A8F8F8F8FD09FFCA938C8C8C92FD078C92FD04 +%8CA1FD0BFF8C8C8C92FD078C92FD048CA1FD0BFF9A8C8C92FD0C8C93FD09 +%FFF8F8F8A8F8F827FD0AFF8C928C928C9392938C9392938C938C928CCAFD +%0AFFCA938C928C938C938C9392938C938C928CCAFD0BFFC38C928C938C93 +%8C938C938C938C928CBCFD09FF27F8F8A8F8F8F8FD09FFCA92688C8C8CA7 +%FFCAFFA8FFCA93688C8C8CA1FD0AFFCFFD058CCAFFFFA8FFFF99688C8C8C +%A1FD0BFF9A8C8C8C68BCFFFFA8FFFFCA688C8C8C93FD09FFF8F8F8A8F8F8 +%27FD0AFF8C928C928CFD07FF93928C928CCAFD0AFFCA938C928C93FD06FF +%998C8C928CCAFD0BFFC38C928C8C9AFD05FFCA938C928CBCFD09FF27F827 +%A8F8F8F8FD09FFCA928C928C8CA8FD06FF938C928C8CA1FD0BFFFD058CFD +%06FF9A68928C8CA1FD0BFF9A8C8C8C68C3FD05FFCA8C928C8C93FD09FF27 +%F8F8A8F8F827FD0AFF8C8C8C928CCAFD06FF938C8C928CCAFD0AFFCA938C +%938C93CAFD05FF998C8C928CCAFD0BFFC38C938C8C9AFD05FFCA928C938C +%9AFD09FF27F8F8A8F8F8F8FD09FFA8938C8C6892A8FD05FFCA938C8C688C +%A1FD0BFF8C8C688C8CFD06FF9A8C8C688CA1FD0BFF9A8C688C8C9AFD05FF +%CA8C8C688C93FD09FFF8F8F8A8F8F827FD0AFF92928C938CFD07FF938C8C +%938CCAFD0AFFCA938C938C93CAFD05FF9A928C938CCAFD0BFFC38C938C8C +%9AFD05FFCA938CB58CBCFD09FF27F8F8A8F8F8F8FD09FFCA938C8C8C92CA +%FD06FF93FD048CA1FD0BFF8C8C8C928C99FD06FFCAFFCAFD0DFF9A8C8C92 +%8C8CA1FD05FFCAFFCAFD0BFFF8F8F8A8F8F827FD0AFF8C928C928CFD07FF +%93928C928CCAFD0BFFBC8C928C938C99FD15FFCA8C8C8C938C8CA1FD12FF +%27F8F8A8F8F8F8FD09FFCA92688C8C8CA8FD06FF93688C8C8CA1FD0BFFA8 +%938C8C688C8C93A8FD14FFC28C8C68928C8CA1FD11FFF8F8F8A8F8F827FD +%0AFF8C928C928CFD07FF93928C928CCAFD0CFFCA938C938C938CB5FD15FF +%C38C938C938C8CA1FD10FF27F827A8F8F8F8FD09FFCA928C928C8CA8FD06 +%FF938C928C8CA1FD0DFFCA9368928C8C6893CAFD14FFC368FD058C9AFD0F +%FF27F8F8A8F8F827FD0AFF8C8C8C928CCAFD06FF938C8C928CCAFD0EFFCA +%938C938C928C93CAFD14FFC38C928C928C8CA1FD0EFF27F8F8A8F8F8F8FD +%09FFA8938C8C6892A8FD05FFCA938C8C688CA1FD0FFFCA9368928C8C6893 +%CAFD14FFC3688C8C8C688C9AFD0DFFF8F8F8A8F8F827FD0AFF92928C938C +%FD07FF938C8C938CCAFD10FFCAB58C938C938C93CAFD14FFC38C928C938C +%8C9AFD0CFF27F8F8A8F8F8F8FD09FFCA938C8C8C92CAFD06FF93FD048CA1 +%FD11FFCA938C8C8C928C92A8FD14FFC38C8C8C928C8C9AFD0BFFF8F8F8A8 +%F8F827FD0AFF8C928C928CFD07FF93928C928CCAFD13FFBB8C928C938C93 +%CAFD14FFC98C8C8C938C8C9AFD0AFF27F8F8A8F8F8F8FD09FFCA92688C8C +%8CA8FD06FF93688C8C8CA1FD13FFCA998C8C68928C93CAFD14FFC98C8C68 +%8C8C8CA1FD09FFF8F8F8A8F8F827FD0AFF8C928C928CFD07FF93928C928C +%CAFD15FFBC8C938C928CCAFD15FFCA8C928C928CBCFD09FF27F827A8F8F8 +%F8FD09FFCA928C928C8CA8FD06FF938C928C8CA1FD0BFF9AC39AC39AFD06 +%FF938C928C8CA1FD0BFFA1C39AC39ACAFD05FFC38C928C8C93FD09FF27F8 +%F8A8F8F827FD0AFF8C8C8C928CCAFD06FF938C8C928CCAFD0AFFCAFD058C +%CAFD05FF9A8C8C928CCAFD0BFFBCFD048C9AFD05FFCA928C938C9AFD09FF +%27F8F8A8F8F8F8FD09FFA8938C8C6892A8FD05FFCA938C8C688CA1FD0BFF +%8C8C688C8CCFFD05FF9A8C8C688CA1FD0BFF9A8C688C8C9AFD05FFCA8C8C +%688C93FD09FFF8F8F8A8F8F827FD0AFF92928C938CFD07FF938C8C938CCA +%FD0AFFCA938C938C93CAFD05FF998C8C938CCAFD0BFFC38C938C8C9AFD05 +%FFCA928C938CBCFD09FF27F8F8A8F8F8F8FD09FFCA938C8C8C92CAFD06FF +%93FD048CA1FD0BFFFD058CFD06FFBCFD048CA1FD0BFF9A8C8C928CBCFD05 +%FFCAFD048C93FD09FFF8F8F8A8F8F827FD0AFF8C928C928CFD07FF93928C +%928CCAFD0AFFCA938C928C93CFFD05FF938C8C928CCAFD0BFFC38C928C8C +%9AFD05FFCA928C928CBCFD09FF27F8F8A8F8F8F8FD09FFCA92688C8C8CA7 +%FFCAFFA8FFCA93688C8C8CA1FD0AFFCFFD058CCAFFFFA8FFFF99688C8C8C +%A1FD0BFF9A8C8C8C68BCFFFFA8FFFFCA688C8C8C93FD09FFF8F8F8A8F8F8 +%27FD0AFF8C928C928C9392938CB592938C938C928CCAFD0AFFCA938C928C +%9392938CB592938C938C928CCAFD0BFFC38C928C938C938CB592938C938C +%928CBCFD09FF27F827A8F8F8F8FD09FFCA928C92FD0B8C928C8CA1FD0BFF +%FD0D8C928C8CA1FD0BFF9AFD048C92FD078C928C8C93FD09FF27F8F8A8F8 +%F827FD0AFF938C8C938C928C938C928C938C928C928CCAFD0BFF938C938C +%928C938C928C938C928C928CCAFD0BFFC38C928C928C938C928C938C928C +%938C9AFD09FF27F8F8A8F8F8F8FD0AFFC38C8C688C8C8C688C8C8C688C8C +%8C68BCFD0CFF9A8C688C8C8C688C8C8C688C8C8C689AFD0CFFCA93688C8C +%8C688C8C8C688C8C8C688CA1FD09FFF8F8F8A8F8F827FD0BFFCAA0C3A1C3 +%A0C3A1C3A0C3A1C39ACAFD0EFFCAC3A0C3A0C3A1C3A0C3A1C39ACAFD0FFF +%CAA0C3A0C3A1C3A0C3A1C39AC3CAFD0AFF27F8F8A8F8F8F8FD5DFFF8F8F8 +%A8F8F827FD5DFF27F8F8A8F8F8F8FD5DFFF8F8F8A8F8F827FD5DFF27F827 +%A8F8F8F8FD0AFF8536613637366136373661363736613637366136373661 +%363736613661A9FD0EFFAE585F5858585F5858585F5858585F5858585F58 +%58585F5858585F585883FD09FF27F8F8A8F8F827FD09FFAF0E150E150E15 +%0E150E150E150E150E150E150E150E150E150E150E150E85FD0EFF58332D +%330B330B330B330B330B330B330B330B330B330B330B330B333333A8FD08 +%FF27F8F8A8F8F8F8FD09FF84150E37366136373661363736613637366136 +%3736613637366136370E1436FD0EFF580B34585F5858585F5858585F5858 +%585F5858585F5858585F585833332DAEFD08FFF8F8F8A8F8F827FD09FFAF +%1415A9FD18FF3D0E61FD0EFF583358FD18FFAE3334A8FD08FF27F8F8A8F8 +%F8F8FD09FF84150EA9FD18FF14155AFD0EFF5F0B58FD18FF833333AEFD08 +%FFF8F8F8A8F8F827FD09FFAF0E15A9FD18FF370E61FD0EFF583358FD18FF +%A82D34AEFD08FF27F8F8A8F8F8F8FD09FF84140EAFFD18FF140E36FD0EFF +%580A5FFD18FF83332DFD09FFF8F8F8A8F8F827FD09FFAF1415A9FD18FF37 +%0E61FD0EFF583358FD18FFA82D58AEFD08FF27F827A8F8F8F8FD09FF8514 +%0EAFFD18FF36145AFD0EFF580B5FFD18FF83332DFD09FF27F8F8A8F8F827 +%FD09FFAF141585FD18FF370E61FD0EFF583358FD18FFAE3334A8FD08FF27 +%F8F8A8F8F8F8FD09FF84150EA9FD18FF14145AFD0EFF5F0B58FD18FF8333 +%2DAEFD08FFF8F8F8A8F8F827FD09FFAF141585FD18FF3D0E61FD0EFF5833 +%58FD18FFAE3334A8FD08FF27F8F8A8F8F8F8FD09FF84150EA9FD18FF1415 +%5AFD0EFF5F0B58FD18FF833333AEFD08FFF8F8F8A8F8F827FD09FFAF0E15 +%A9FD18FF370E61FD0EFF583358FD18FFA82D34AEFD08FF27F8F8A8F8F8F8 +%FD09FF84140EAFFD18FF140E36FD0EFF580A5FFD18FF83332DFD09FFF8F8 +%F8A8F8F827FD09FFAF1415A9FD18FF370E61FD0EFF583358FD18FFA82D58 +%AEFD08FF27F827A8F8F8F8FD09FF85140EAFFD18FF36145AFD0EFF580B5F +%FD18FF83332DFD09FF27F8F8A8F8F827FD09FFAF141585FD17FFAF370E61 +%FD0EFF583358FD18FFA83334A8FD08FF27F8F8A8F8F8F8FD09FF84150E14 +%0E1514140E1514140E1514140E1514140E1514140E1514140E1436FD0EFF +%580B332D3433342D3433342D3433342D3433342D3433342D3433342D332D +%AEFD08FFF8F8F8A8F8F827FD09FFAF14150E150E150E150E150E150E150E +%1515150E150E150E150E150E150E85FD0EFF83330B332D330B332D330B33 +%333433332D330B332D330B332D330B332D58AFFD08FF27F8F8A8F8F8F8FD +%0AFFA960855A8560855A8560855A85615A06063685618560855A8560855A +%85FD10FF83837D8383837D8383A88352042D598383837D8383837D838383 +%7D83A8FD09FFF8F8F8A8F8F827FD19FFA84B2752FD23FFA24CF87DCBFD18 +%FF27F8F8A8F8F8F8FD1BFFA852F852A8FD1EFF7DF82752FD1BFFF8F8F8A8 +%F8F827FD1EFF522727A8FD1AFF7D27277DFD1DFF27F827A8F8F8F8FD1FFF +%A852F827A8FD16FF7DF8277DFD1FFF27F8F8A8F8F827FD22FF522727A8FD +%12FF522727A8FD21FF27F8F8A8F8F8F8FD23FFA852F8277DFD0DFFA852F8 +%277DFD23FFF8F8F8A8F8F827FD26FF522727A8A8FD07FFA8FF522727A8FD +%25FF27F8F8A8F8F8F8FD27FFA852F8F8F8A8FD04FF27F8F852A8FD27FFF8 +%F8F8A8F8F827FD29FFA8F8F8F8A8FFAFF8F8F87DFD29FF27F8F8A8F8F8F8 +%FD21FFA8CAA8CAA8CAA8CAA8A17651277D274B52A1A1CAA8CAA8CAA8CAA8 +%FD21FFF8F8F8A8F8F827FD20FF93928C938C938C938C938CB59393689393 +%B592B58C938C938C938C938CCAFD1FFF27F827A8F8F8F8FD1FFFA18C8C8C +%688C8C8C688C8C8C68FD078C688C8C8C68FD058C9AFD1FFF27F8F8A8F8F8 +%27FD1FFFC38C93A1C9A1C9C3C3A1C9C3C3A1C9C3C3A1C9C3C3A1C9C3C3A1 +%CAA1938CC3FD1FFF27F8F8A8F8F8F8FD1FFFA18C68FD19FF8C8C9AFD1FFF +%F8F8F8A8F8F827FD1FFFC98C93CAFD18FF938CC3FD1FFF27F8F8A8F8F8F8 +%FD1FFFA18C8CCAFD18FF8C8C9AFD1FFFF8F8F8A8F8F827FD1FFFC98C92CA +%FD18FF938CC3FD1FFF27F8F8A8F8F8F8FD1FFFA18C8CCAFD18FF8C8C9AFD +%1FFFF8F8F8A8F8F827FD1FFFCA8C93CAFD18FFB58CC3FD1FFF27F827A8F8 +%F8F8FD1FFFA18C8CCAFD18FF8C8C9AFD1FFF27F8F8A8F8F827FD1FFFC38C +%93CAFD18FF938CC3FD1FFF27F8F8A8F8F8F8FD1FFFA18C68CAFD18FF8C8C +%9AFD1FFFF8F8F8A8F8F827FD1FFFC98C93CAFD18FF938CC3FD1FFF27F8F8 +%A8F8F8F8FD1FFFA18C8CCAFD18FF8C8C9AFD1FFFF8F8F8A8F8F827FD1FFF +%C98C92CAFD18FF938CC3FD1FFF27F8F8A8F8F8F8FD1FFFA18C8CCAFD18FF +%8C8C9AFD1FFFF8F8F8A8F8F827FD1FFFCA8C93CAFD18FFB58CC3FD1FFF27 +%F827A8F8F8F8FD1FFFA18C8CC3A1C3A1C3A1C3A1C3A1C3A1C3A1C3A1C3A1 +%C3A1C3A1C3A1C38C8C9AFD1FFF27F8F8A8F8F827FD1FFFC38C92FD198C92 +%8CC3FD1FFF27F8F8A8F8F8F8FD1FFFCA9368928C8C68928C8C68928C8C68 +%928C8C68928C8C68928C8C68928C92A1FFFFA8527D527D527D527D527D52 +%7D527D527D527D527D527D527D527D527DF8F8F8A8F8F827FD22FFCAFFCA +%FFCAFFCAFFCAFFCAFFCAFFCAFFCAFFCAFFCAFFCAFFCACFCFFFFFA8FD20F8 +%A8F8F8F8FD3FFF52FD20F8FFF8F827FD3FFF7DF8F8206E4444444A444444 +%4A4444444A4444444A4444444A446820FD04F87DFFF8F8F8FD3FFF52F8F8 +%448CB48C8C8CB48C8C8CB48C8C8CB48C8C8CB48C8C8CB46820F8F8F852FF +%FFF8F827FD3FFF7DF8F844B58C928C938C928C938C928C938C928C938C92 +%8CB56820F8F8F87DFFFFFFF8F8F8FD3FFF52F8F8448C928C8C8C928C8C8C +%928C8C8C928C8C8C928C8C6820F8F8F852FD04FFF8F827FD3FFF7DF8F844 +%B48C938C928C938C928C938C928C938C928CB56820F8F8F852FD05FFF8F8 +%F8FD3FFF52F8F8448C8C688C8C8C688C8C8C688C8C8C688C8C8C68FD04F8 +%52FD06FFF8F827FD3FFF7DF8F844B58C938C928C938C928C938C928C938C +%B56820F8F8F87DFD07FFF8F8F8FD3FFF52F8F8448C8C8C928C8C8C928C8C +%8C928C8C8CB468FD04F852FD08FFF8F827FD3FFF7DF8F844B58C928C938C +%928C938C928C938CB46820F8F8F87DFD09FFF8F8F8FD3FFF52F8F844FD04 +%8C688C8C8C688C8C8C689268FD04F852FD0AFFF8F827FD3FFF7DF8F844B5 +%8C928C938C928C938C928CB56820F8F8F87DFD0BFFF8F8F8FD3FFF52F8F8 +%448C928C8C8C928C8C8C928C8C6820F8F8F852FD0CFFF8F827FD3FFF7DF8 +%F844B48C938C928C938C928CB56820F8F8F852FD0DFFF8F8F8FD3FFF52F8 +%F8448C8C688C8C8C688C8C8C68FD04F852FD0EFFF8F827FD3FFF7DF8F844 +%B58C938C928C938CB56820F8F8F87DFD0FFFF8F8F8FD3FFF52F8F8448C8C +%8C928C8C8CB468FD04F852FD10FFF8F827FD3FFF7DF8F844B58C928C938C +%B46820F8F8F87DFD11FFF8F8F8FD3FFF52F8F844FD048C689268FD04F852 +%FD12FFF8F827FD3FFF7DF8F844B58C928CB56820F8F8F87DFD13FFF8F8F8 +%FD3FFF52F8F8448C928C8C6820F8F8F852FD14FFF8F827FD3FFF7DF8F844 +%B48CB56820F8F8F852FD15FFF8F8F8FD3FFF52F8F8448C8C68FD04F852FD +%16FFF8F827FD3FFF7DF8F844B56820F8F8F87DFD17FFF8F8F8FD3FFF52F8 +%F8688CFD04F852FD18FFF8F827FD3FFF7DF8F82020F8F8F87DFD19FFF8F8 +%F8FD3FFF52FD06F852FD1AFFF8F827A8FD3EFF7DFD05F87DFD1BFFFD47F8 +%52FD1CFFFD46F852FD1DFF52FD44F87DFD1DFFFF +%%EndData + +endstream endobj 93 0 obj <>stream +%AI12_CompressedDataxkə&Syu܋ZZGF5Y[$i06??x c{4 yo'fɫTU'322~'?{yvœnݬ??]]ኻWx+tB\7j^W_*F>=jWCj軕Li/ݯ>>0>d[?gGO۟OYלMVɏW>{)ucWϞr{?\IUK|?x=dRv]\|ū7?|zvߜZK|ˋ/.ھ8W=Wo ]ų_\/hxAhZ=v1_lMzbU tcO y#.~7?\Յdcl_?W?K,CMP?|vC_p //\xOo.A> ꓔUiEB;Ua_(Fy?_ISuC?~X|O╽G4 >z|xfAK4o~/?꦳kjϾ:rp+>?}qmWsgοJgO_|Ͼz篞嫳//.xsɁ%wZد#RC>-9xWg/:g8]`g//Ξ]# +i:WƯWg>Jdzo ˿x9Џgv˯1}q=ū7g_}Wήh+^ӫ]<;{yӢeM:=ٛ\~KWWӷo.^%θSų/^HtO߾#>oϯ/zl@Cm䉛b77 ^ls8|فoQccy557_H|"7|"7|Ro⛳O^L^rϋwR>+ ^˃}΋>9/S[ BF7P~s\xs悖oo7XG!٧K>H霰YY} O<23wۋOh?3OhiO^sO"Jl W]_u)H_꩟>'>_qB1DI۟G29"W+?y_U״2khRD} w;}U~}k<~]ѱX28u~>p*nu:ݜba%?po?'sp?9'Ӵ ~M{75 +^P|tG8V"b?| 7g} QwϾy_Υ\{B޷zx EQY$*9+QRCq},_>|vj(*0TSm &W&O {}P; +L|~wNl:z~_-ܮQn8)>宙S>) ycPycC8.S+Tt?*YN5k~7OZϯ5xMgo,*>>i$%͌e۬K +7?\^$KZzR/q}xh7pK⮣R flv[|mj=-n;j}h5#=F͸-R븵fLGiMj{jiKmMFj~JSzq0uک~܍u1f8 {z 4 v?;zM?>~} &Ҟ^z41.nbm ݱrn!uѼ={ZM;=gj &žl }Bh͞ӌ =M -WZh:'Qz9Ozᆖmo-y6{{gu4yo?߫W%D;JKyWo#iIƛBpy{;h;J}-xku"m_ro" Z{ M' 7;p] +cK`qxh x7t +wʇH;#XOa$#f!Kt:|-=C=نa{ :Bi0ohe,ǿeuDʸ22ͣj@L^@7kӴS]l?S`:G{aG9:kQ@xO>^ js'o5Uȝ>*8C{ 坌OHﲧk:h1AAL$18_Wnz5L`j@&/Sbe1ːe8%vXԬq݅cD?18cD^VT3kBpGt6J߷w(}'uŴ>t$ϔR;( 9T^ ,|>p$T:Ӻw]E01cSФ)Б0>5ƚܙ]ifΰ [n/~Wla){Rb:n_ZFˆmՔ7$mu=Tm_3gS6%g؃ܒ2bшIu)UkF0{v:&ʶ'aFm3̲uD[0n4#=3pm$ֆ(\d +[G<Ё-Sc’D'h` @A[(2;!FfN|I82sx Ҷa&qb=Ğ8N[x"2 +ΘxW4:G5p~GjD7fK@o0'ض`:Ñ#1c}C8Wr~³@@A!mP32:($`2 kM0"ƻÖ䂉yMH<-hX6'D63]&AW*lY@Dđ +!"~,x0LYX0cb"Cd!0\"Ccƒ}#/1*LzVʼn)&WCU`xIƄ 3*hL =^EpY 1c32vLcbEBߧ`=Θx件Fl2V{>,eVZGTjCƪMUXs[]Uui%LUߪUF#U6VmfTC#o6{5ey20Xb:;1ݲ|c:|5,gBl +F7sXsbV=oّePB[VDEE0h2Ng%$<ҩK&S&))M+Yr%aɖ˖-Ud2Ted$L1鄰IMd̽˘ 939SaXI/84+ӾD Lap;z uhHD/eKTdOGH<uU#*XY݊ڙz5+"|E\y<~]5D3Z:iyYs*g'\θY3WB8Sx i[gۦh[o srU8R0x<ɣ0X84qdh$(ujSU=rNOO)(u''+yҨXI3魤N+rnTdݹd\C'mδROPRAkЖ!oRhd(M,AB}#ȁc;5o,I).t*Yڥ|8^}9m ,')6[V:|ʚ)E֩t%&EϨzԄ/&buAvsZhy`mh Q@Hp4 Q<1N4kݤuau]I>uM@0ayȦy +1HzU5$J2~D(U,7Fmk+DH4)Z8m,]e3&#}fj}a9ݱLPڷQ$vBYӶ$v8ݻ5˼.m +""v [BDZ"O:wW(iBp# o;oצjB+6F:RJKҵM6u姬4fu4 T 79\X薺ZLD#f-qAiggy#F`Ŷ喵([XtlrJʄmD:)uZ\Fב~Tu[ݢgzQrgS]TiA5n\jz~ցLVR{h&M0`wk)`HTq 63x`m!:]BLܳmؘޝhq567*s+0ƪַL[կT.zurGت]S̜6jݹ?s۫%WԒUݹί斟ì}jv(,6eTViS3Dhר6f2oػ+;7; +5ǎ 0Qas>dg؎ db}70wYv`m|Ny{3F3̲;A匍kzZW횟n;cqg4U&6Sƙtj2alsj@cE9t:sX +TwKMOQSUW:[uòǴ˕٪ט%u"Bh4!{gC2,H|Gf;Ef(20dˎ۞W6D陝}͝/7f4[Lbj hr3VRCTjcT恡0d6FTw',)_[%;_3I9<WsI]Z397O닕Ɗcg$x}-*EˎYT7 :$hpaRzAeI 4gҩ>UGp.{2qoP"‘icAT:,¼Բ^HێA\?Ĵg~642;@Y3wW("(Q̷yeH#oB#΃d#N6ǏJcSzSڞ)׎4l]왒%u#wTP] ;q[6DnOL"k[qEѼYR6G΂t6)QX3]9uڕnXL#npQ[]-7^%HCiso"|wh6~r#+iMJ{O6DۉFb@Ѕ8=6%'a=U> 2Ký 3#G1{0Lwlu9NH'SKR9{?tWL.+A"#H# @#Gt1 O:bi蠈^v '#V{mdYȜ˺axl@U-JO,)JK{dC1Z,1ϟ:dPzlSo(șgP wWINXS5s  ﷙+!w]7}`V ̷D}{5yĤs)q4@$Č ^ܿ+{w>-RŲ=~t"!{u0Ո*x!-3ubW} +Yx9: Bڙ:fͣW1jr +\ruD=:/-݊Ba\$n,غF|no&^hT`ǛpF#?g"U(IspT#Y)wUi0. +7!-&MH1`qUw=, X>-4K, sg6[і`[)%'j\JyKޥ-=t`~]Yq8bm<}1k'&o"v0rCg/aQ# Dr}+7vU6{5Ҷ͍v)mgy{She%ĎȒhea/f*̎МRR{!CtQZmz mpyzx6YK'-.X~wlF#I&l4z}0O q=>Сš H=رEq[?e T;g=:1o?g3[gڶ^3cZ9fbZN ?ͽq% S0c +̑G % 5Xo5 m`jnkjkҶwk4crnqNq2UGB)NM$ͮq9-Pj_ܪ\+nC,e[eS܁u24GxY +Q{i +U+\u>os+MͿ6JwqA^йUK|4b=>KשB*kp#wBA'FRx9P]-TBHtMINJ\C"prRM: *g$TQpU |B$XT%bkeXrq>˕0U Jd|U> e0IƊ}Lg5OK֎x6*URpϫ +s^GkSEo-t̋,攷rmK.]Ŷo}S;|>E[  {Fa]Jd@\A!(o:J ޡ4&WK"" +~LL.qhhC!)憶JFj.]s5%;A{TfS,kAYdiĒ+J2"c\X +, + +f<5VVp2/t m.sIL@fI?Y/vM-J"6{c;oiK+[Rm hV2y3țLpYtFvMu^pi]?Ja%mOKhҢ>ivx|p{&΍zY vׁ-*^7,7K%)hQvS޼ԞM:|Dӈт<N0yMyT%ySԺ9f:9̄MPLGz;C!f:$]hJPP^.hEΛ#꒓e)6x6Yuu_J--󘦥h4N*#5]|}WG2]ݱ0G)&7/#%V̶^| Ǒ\{6x&Ll(KF O3zP=l Լ>Ex όgs;L? _5bqeٞh$V3KiH9qV>6vd,pm'gţլ8̈kx+\c$3YNEqL=#9q$~ʓ?ǂ); ^PxCL;١"B3ISd7Mv{`(IjyL0Cq4''}t 2fX]4yqk$/U %sP/K_,g,exo6ƪvEڹ"=ffWdML{c);S-cر@ y|B3&nRpVVAž30]&\ʰ k6Ч=̵DkZMqYxnDQj0֛*fX:'{>_\^pV}#dÇP"M151=$b1=$bzH!C"DL1=$bzH!C"DLxH!C"U"ԯB9d=bCHŔ=R;/W]l7UvO( WY/K"579l@jDgpڨ>c&FtUv i>ڬwvF8UC\X4 ʶL9P@C83 T$vELnm ͭn4⨆2p*SCY3VaE冭$eV[J䐳Q1FmM%Sw̤)qYlj5pk m*Q]+0:l5wPEh"dNZ`hO,X"D4"B˦w  8{=r_ [ClL 󮣲iɍ&}QbD"압aFG%C|8O(eac.h(YPᢄvB$d90Nd{E9h0 +:r[K74Ј֔ʆrj3qkǎsZi5)Òs[p; l' +:D 8&ٖA=0OJiK/Vx3k%}.;3 +>Nڴby𑉦}K?ҽde w)d}RA\6׶²46%9m54fJ_}pZ^)Ow}=J]u¿z5r?tKcGUG>B=ٍ}:mFa('_}}P})bp ~sM נ>ef`:g{#[SЛ:QUіF a&&n,ʾmpQm [.]>oRr=MY3?y6KZY6&NUs\bLӡ=;fQ U ]/n| hޜ`YRm% +4bFuZEpޭb444{ Ql|tG^84,L *073ԓ>Pn5qWY +*Xd."peh tmX OpU$?}I A1aqTw +Z?T0.q\}&{g?V>DB|S>M +hxFйVB 1-$ij,!a; 6 EqNq3 +$QE:hE肱+bU.lwMѪ`a.F/Wr5"}0}gXeD"h*R!v&8xo)K0>HXqI=:30 7 +u7R 2;䷊s[.|עw%MངQ D&xXX*x߃JNMW0$/*Ֆ=DSߴbN)@6j^0F! ]:aƼa= +>އ +㢬>BTOKiqeCU5vF '}E#ο6֪,Ҿ#g?p.Ƒ㏎pXY&9D5O7],[9Tg_Ѧ^JL+D)mZZ*YZfsDZEqHA5H8n4`όLo=в[zVo-Xc?^";Ξ5HAG hQ"ؗ{OkvyjE+}p:Ef-qx]a]F#ݩ][:.H=0È#LjU62#<3ݬVami3,x uޅbqtԐ6щDt':NxӍ0#] r!a>ȵ4X5XL] ONjq[B:4"m k^Xp +&\BspNjypJݮMN>4(yl EKhD ;m.<Z)weENIuF־#Vئ߇(]hӴC|RhE5%C {*`+tsեu>n)w._2aSۯfB0<0s?b-y] y@g'd퓫ns ْlZ;%\rfD9'8SX4ea2É_yq-fPbKOSk҈,UVnGθM1t՛˒drjE(5,xXrN%zg)xzR _*Ц`y퀜ډ_f\'tS:[RgK,ӯx`gG՞ \a"V1)lQ4U g==wMbi5ƐF$cG4<)t\n|Bo!l#ʟWQ>sa x'VjHa ؎E._*m}ks׷R/~ĉEV&VuC|]C1YLš)PM oOww߽ooo{}?RsA|h%hzQH#[XrŃ;Ν Qhobb+lecGZ@+m@T?Jt=Sh#]X}ӭi= ަ}cSZB7~?߮0qI_BulHңc(wF5fi% *iLJm>wg⇎)~'iиNvYBۓr:WQi +`歨bhR<K)Y[LQ:Ѭ<̋ Hf ɶFg:=beOaśosTI^`JCRkHTr{)erAVl8arR}(+&>G-X&_PBXDS8{-$|RҚTH3XX*9O~4Z%<#}E5 VnM{T%>ʩ#U^Z,."STRV^]V{|?U}}Og5,J{[|GmOmWD]4Al}[O5b 7W ߼;6w7WQo KwpbNĩBk4uȲۭa\aO[#2_zC+/uz){HڣlKt:x0At =|V<&IDVD +'@hd@4z :͈!nر'`=vXr" ,=P jaD':v`nOȩDB 4BI`8/'wn?{ޥVO`݆8sd*=H.IX)P$>~Aa'1GtBh7'QMK &6LUh~#>>zZ\F}:i=C*Ni8[[&@ 8& 6~>xʺ:TB )Yٱ:"rWh;4^\g?87WW~|l<Χ_\^όh}vgh2?{ Q<9mGgV_Ö_/~o}9_FL#M¹ܴʡ@MDWĐ >cI?{:>ՠtA'.[MCtdӏsOG8YĴDyL:QHo4F#kZ O"bNg+#:Da䧣nά`OħpRm@(X&J!aՏӺ-!1PJG>l!Ⴎ"gED$=1s"_E,IR4i: HD{hz: 4}tc kǘ@7 y@%̈W[N88|;0`uiwv[>\ FlA"r%*M,9doC!KC-b#=O>& +M h`ITtB.-6O|2I%"\OfM- }F<$1BRPobt -*h&.z a·"1FV wzt; +Ǣv\2-{4Rê6 Ö$eAHV"4r=B 4 /F<1#]"ix|d!3Nq#ys F. qB"~(fHD! #E!RIdhƫU"Aw)0P#G\F\k(4bC7wc~B !$ c'c@ Cga0 TOC"c6)E0b- Lɑ<k  %gy]i$2P&;@kFk"k X0VqE\|_58*ykKr|QØ7%y)H.wXV<1xR6U8x*VOol,gʔLd>1 ˜ԌpReH PMGbSƝC7ïk;t,l>$㦅RBz嘸PG*<`8嬡0DP0" tSX% YyjJ?uq2 +N^P1Rh~Ir*s&zqD2XU-Y Y:< L1S)D {P@Y%41v%+O]I4 nM/AAt+{bt Nu5@"m%PtL"srĺD`M(VEߛˮkNӇjA"3 i=.1I;~)TI +DU^ᩴkpԘ- !-f( OndMLpiDDM(w?8ŎD Zl {qb:V1 pUdVtē2&vo4a*xZ`>"l R1un儆D +uFNm؂~d*4`ngv PFOx ' + n',hM6[#?MDr(/sB5f-p$3@<˓p==%]NXN73n ˂s +#8}k8zؙ|$,z} +g& 'L%u!tabGfp *1bX@(aYj̰aNw9 V-Ƅt%΅4s&\E +0Ҷ v"@ Q;4ɱ\zY|.a}゘km9°tDNn=qahptME`&iB) ]orky2n-PY =-k.)),: -̷$=F~J0J9w[,  CZ:G{#ﶹg+DڎX̪)N¬orO3]N~ߕ5C"9E3R=P t}WwS9llDb3`sãjuCr>,BSZF?yk-,gŦB֓ȚTC1pPQrխ5WU(MYlU5uͳfWN+vv]F/\eteWi֍ԯwf|y񯉣)jnp{*F w`g*܎Rsnnq6 2K=%St+k6 VTYnSyl;1b6.gVsn3sjΚ`H眮v{_5]k: MHgXil4km&Fu% 3Z]t1kK7n 횸_J\ +^nKv.ùY|R[MptCx-`LuKn{Zѻ&!g%J;XjyLL. +ǐ,5Yᛲ6`|bg6׈&"ҫ'ĕ +1YяJ\!rd`lRz*%_fF͞9Aº Xd^团;MV$+#t0Fԫ;o÷!)e[ž4AȄ7?A*FHlHbI8刑G2KQE.5/\8Rn4CdZ㡶C\4o".4eA2JO +ct]3= +!fB׵0~kDo3-V8, RDCZV Sنk96~(Mfq"n& O}a@2_4o}3l.Ma-*u&"`_?{$;lVO$%1>+`ҁVe=B/1V (^!E0!$&0O!c}ӓ"(rbu+* K\ +a4H%ygi9lO j4K7f+0C<&Qa6˗Z\6mON \r&uJFd]e +cPs: Jvc${O+>h† eQ 1g[%Ƚ2pgg5_1AְZZ8$,..jkE)$Sʏ CX$>1 }B&ymZ&abmTemWeK7c*cdy0S "+ K`VGOk~BZl!Aǯ?o.i͑Ԕ 6eNjɞRNǀ"]T-74?t N U:0bSt A9ٲ\ch 5O$͖E *U2L%ǒ1)?bha婒10Ϫ%ch1#4C;@?ԹHRcb}<yMfr1ve\ U 4C nM +ꞌsjNlwe~8C H* #$&tkIH>Ɉ 1ta#GKK O@yH:53B(c*ܾ h | mO 9|iٔj'N{51))Mr,Y:%81tJCd/*qS#Y)A2l[:wp:$=bkNk:yDYy` PJJTyatg5ky`bExV<.B*J :hpiKINWyQY`8qkN4wMty=T24s_ë'i$!Ұk6mS495Pߓa)Rݽ̄ȾKEjV2iD+U+(ǂM> U_fh⴮8 zql"2< f1"vXcSA Ff%E2/e@"ob!D({iFS`-%ޒ!z lp\DIʔ +솣=R4$$<1y $/8! bӨtJnQBSSE;(xTf,N>/1<+-,I3uPCfcOo9"04jT 0/T fʑߨ^:WX6xs0*/ &e*uZv'C7z4xa^aH KEx7vuR UEQE :ޤ*T ΩR!a8f$"g+pDbex1/ay:T", ȣgJ1ʖ-7+q",Ȳ^liJ|H8]sP3` Dq*q +88^K Ҵ`79Ӳ`pQ掠̩UZA~}c8 Җ_UV4Y Dl6a|6YnY'fA +3UiۘI\=8: }߅в8skyBReڦ,ɐІY"晴yLU;$FRD _[e~dO4lq8JN +|]X}q}#zbeywn9T|Lwdsĵ9! 9` p㇣+#Ӝ 2]C3G(a$YҊC `i("-Yef-Ѯα#@ jBı0k%nI|G<:= G/xERe^`n8?G Ge#90j(G(FYH?{'ڹYANVjj&g M#ZGM{)4Ȝp3fjJ/^=`躂;AH]xÊi;eP叒eR!1Mm 3WK~5IpV ;3EZZj0$YEcs +MGń¶14PYS]3-N6]ȞdGQIȧF= FO +v;(Jbŕ [$GL" YWًr"{s -32EuH7zHR [_Y:xK!}NCdP!r19R4RqE3PIK\iPLL)&lUT"+&yf..y-ˑu7= :U˷&:9 ԞDen˳y%xOۓEK{@Zȧz:'~wLe_T+w5w*[Se3Ul}]aJY<)*fdz-9S|e4 zM`6? `zϞiggԔ0:Q{V:VX!+' {d!rVhu\[̵5scGWt=nf]5Š]o\cu/;wQT\u"׏ge*tpj)k`>USϨ2V3A&Q|uy0Ō0GfG +S6x 3d> 43 9Bd̍B5g#̼B3C8G3We,Z uWŮ̹Z7eW-m59gdvU,ww+qnL7:fI&|YKnt-.ŴtܰjY^]`rm)Ve/xZs˱K{n\6ymеؘ3Ҭ.ѻS8l6ț-h ;eh% jTxˑR{![$B)-v"1U+ED@Cb}"2cJLEe:rnA9\.L2?>2M|_TAy%LW)5ݓ)|*)& ɇpTV9X߀cfbtt4ei3zi0@/48R~9 $ŵ*W d"唁vB;A7T\qLXYV<K[%ey*F˜C8 nN Utd+Cb z=f ?2U;5< ^`ܑ}@p#^],-kT<ͧGgQC=K2)E_p9Gl0Uژ<7/o9hVBT^jckfyoV rT,N'˶Ze=6,O*C rBe!oʎG~); JIrP/_/Ct|[8§QÏcID:COCCtB.u!н-N0 ݌ '%Y<Br0*U*u"r c3WCВhyh-ai0;Iak&d ܠe'q%xlEwx<`C{<[ D~F,ƫ/W?n7O}7X}\!9ٱA)w#=xîA`7ȝBVRXd !d bA : HOKDc f_޷Ҳz@ϸKDhorO#(S9pF$ !wɄ֋B[ƀāR0܌dJ3L:úsbH؏%NG'q2Lxф7HЂnB'/jh7`pGABTQc5 į#S M$RJ1Eiڐv-a50r&҄Pfڿvfԯq +uJʋu֫ u]lY/j:0o\J*V e:f,7e(٫8uۄ\ MyY(,Zᨮ[s}UL';l:d@j%UY`OVLk_u ++ꗕN+NZXip`IV |V oF^HAajy!ZYF\dJu͐kuH$j13v.he.ZeiӺ۝Zc Z/5fU:5[FoV$Q uzy9ŵtŅZ br\i࿣z7 -WEVOzs*|x\f,zXu;\< ~e;f, vIZVc亰8x}gV4WV ŐjDDt^#.ء-#ndPc;is!)W5GXmȮAJA +_Or.& !d5t,,wjʖ}sPj[g]&kEi2K٣8ZY[zu][ vVpexIPdDb/zQl3rcN*).!xS~GZTjZ-UA)r@[]V1^g=R"-#.ɫSh,pyqKr +\JN-?ǔ+vjI\`f +s܉(19fuxp^7 V"꩹ۦ煉] L}QWMV7W]%mVs^ ?;lxY%i66!RנƽƵ\ :0^5UG+pG4궳yye+ +dr +䆶rrCm^߼Ɓ^ݑJwW׫;Ž{/ +ë;*NS_3n7m$P13RNS鑮.˭:AS<cti>TLA6R kZ.\V"ILe*%%18)(Y.'T#0̞b$eHꐄ%.T5.=9pKXAa&A05`Lf.*.΄?h"dTH}t9 +j3_(r)Qhy&-[SJ o8MJ¬]7i9% b>q|`1&N h6`VE EH=g%lL8O\B$z]g)m;Nc .~85<I<{4Xcʍ,ʂxn@*_Z PnWSljs(yk( Zǩ&ETgfda`E .؍YHc9'.lG@IL<5˻p*&ĄdXƉc?Qc7EZɰ=uuMS F +?+"5x12ʉ\MzM gbh">׮DdRFr.}kB`zj&)7e/+lLU/j|UK;ʴz+]4s›\l]ZH?4LӎGZT?îis*!1w"B1vtZeGi~qI*񨫼Ktqʮ=wjŻ>i\jʮ8rcS_#Ԫ$ F>QG7d8ucSZ$٭'N=T@6:T>Nlےz*V-X=f&/4lV1wbst&A'gsVĊuksntM56Nglx6VVwn74_80\%n@V,.߸!b[]rw-~4(Zs˼ˆnw/T\fuςZuٟ{ssɛtɤsaYJz~t ƬR(9MD{DHLz* }NLяt +QrN҅d`rSnPZ/4 M̴8yZB5L6$Yi!P 5hbZZEɪVS!q! ns>73#+5L2'ucy,>&7(G|+g"c`9eS,6cj}#{я~k?"ek|rW D[սA=]s:sJ$>rfW6X +xW_/Z!bG[ѦִQkRDJH4}L8^.4=ӟ动樯e]MMq|Jw*jo0nf tɬ7|G UC?6}Gs2éX6pa~T>3i^xFG2tl,򴡫-VU$|]B],,*gsvQ؎JQ܁̹ju ߅ +93/xR)lU")y[V_*Ne0R̓g-AQ@sEb c|&Qը)R=l`1Md7'm[IyWL4-%\k[EOM&{y2qa> \O?6{hl +] -;'97 ۠}]g;},S9^(Nb~gLb}cy\U+X머--˖W } 2h)c{ΟٷqG1f]'LcەGLBW01Q].rj,bqטVQWި҇}Zu?xSAi~C?~džbm3ks!TK + Ԛ׎2"rYNPc'!ֶR5b֕s8|ڵV ȫ" ?J[g z+iJNr-?1yYkO%Y gvB!~VJ%RWMojiSULJJԗ598ynO2N( +A\*ٹÁZ@"돭B姺{HP~aEdݜkt{Ng9[2 +xmwp3qT_"G~A_Ii\BO0)uD~XPMA6*;K]FJwֽ|9a\Czߛ=yJdUkE<],s𼍇gC E7Y20[;I!#WBB;[4Jc cKሚGsZM4kkf|``̇_tDZOb~tNjEOM=)*`?>(V8DssX3\m!Ygcs菊eŚw\9$rǷoad=i#B!6YT B-=$F5N|&r* "J_ÿܭ ^TE"z؂7V;"lK@@F_U"8j*&xO\p~k]U` 0^ح4#Z͈Sɉ!RU- ob][uEA_¢aBvh١9*ďhFF +:?^1ibe}nP}ChGAhrp'D4xR']Nu=GmWbTt%ޤT qA)&TJ(%b t7L)Aj:)%.\}PJbICh +cRJR4EHtp諽+%ju:IU/BtR[tk%ԺNzPLW;zC1Wogi%}C&]W#?饟:t¬- +_2A+ЪoCRbYX'0-M痁5*".cU.c7݀PS,.P7]* =BdQ]SתAo1< ]Rm;WëZ Ze-,>)εB1t*>tiocfv5i7 ѽX>n=޾+PJz/+8e^)D׊`h-Xp]_ _*XZja4 +VAzEZޚpc+_`Jvm<`I4=e5Oo:ByP`+X=N`[u9& |fғ:)ykHSqpstp/ʃYq͊$PڭV(? Nxp ]aOv:mPq R^GSٖ9V;ɑOʑ~=Zfvӭ1<\L }s1_`ۭwg℅m3@yjNSp:[-c[)c2cP:M/L6^ǶC1ۭBw ]vH6۴ +Q=&uǶuNg7M~jͳElqtkko8ݼmu? z'dzs<5G.N '7Op3?c}^'7gFl> 3NnzN'79GOnqr'8  ̡@%@%e(PBݖP Kь*c@bFUpMT1ةa wdF V\,Ķ7[Te : 2$"9YUX6T }pUk@A-C b$,%CԅވvH 6vi {me=!Ё{QW#^x~| ~+l{+_)`l O +%2g"p!)oJ Գˬ Zˬ)P.3*]f(4+\3mzV+8+dg +oǎU ]R081LA1CΣV,:Gc\p1yy]ѕ, 16 Mbnb+;U&>&]fpŇVes vFT8dG=79ml-` PoܬÈ{cS6LL1CV`pbN$@jY.G-ѠQl_L[?5pRotLC@مeY /%2HwyV,0Vp(uOÉH/pq 8Lwӛ,($lB%pK[HRԁȩ( m@is&&P1G56" PG7j2DZWvnUnpRtFUceIa rMj!%- +B২['/>"oElgbY!Мݐ$ɂ5~oJrUp@~ m%y~ƹsrۢ` 5T3']Qۧ:0LY,^"V%qUhgHF"`dj13S$Aƥ_QNK -*! J4,$rnpN+{#Rِ5tҐUl>P47lbŜ8 Pgl0Һvz8 +HOH?yJ +Q8mĤҍQfhc:fEgݼB'6e +arТб&MG}qD+?[ҶIv4jcQCd T`݌@սot~,hW}wźU^gߝ2&F8n +cO/\A.*Mq Nu"?>RY{xpQ<.K* Xӳu<S]gwQt W\Yjw~J>k7IiۆCEu9#| qZapWx1wɽ66>C]2*C99!/^;Aoj !xE`e`#g d}"2w\ÛPrE@0cFU\ yd\3vT>setޜL]5BpCsd7Kg-QTWYN!Ie:UdSf{ַO!j|0Ȱ}?/"˧)'P& 2)*䉖y<2A1s4|(g$O̰ s3)i3dZ'H&Rɤd2{GJ*]/V$ĺ926x KgXɨ왿>3;jf'C+VvS8ӛa[h=W:=|ϻ͟9DnzMO#“G\2M$g'WIz{rz<l*qgɟϓ⢔BVRj(*5pXg=|fܧX7 z pK؃(Cà5fC_ȁËB!ډ]Bb'-f#N^1UG2UԼsuނ'ZCIZY`:e>(xfY +~d[;>xG],fԟ9P/? V~A7ꥢWYo[ pOĐ2!!'av>Q8_fh@Cr!T&VGƼuw^G%R a͉Db$a[;w>E:Z}L*aVR:6(}W^*gO,+ +o\JKG5Wt/K"x`*b[y]|VnGck]:in1jMӐz&*[)ۀx:1շ$D5Jg$1b.[b䭧'F6; #kMPGY9-~zx=@(DR7Ah4Ub, vwrD 0y :L4L<ص 'NuHyȖ|x.O], +B"̽a >(y`}\$HG^ y`3-uo|6NGU }ՁB_%0ج,Ur`YY%0X* eq&e`,U*R[uh0VlV,UG mՑ&mՑB[udMlV,U m&mB[uxVO}٥L`V 1\u<ȃ|l`{`B[M[[x_P{-jOTU`(HIQ I +R4bEO@ ECA +h HAA)(:RKA +h HA0d}AJAJDAJ)))9i/T4?Oﱃi۠ 7^< _& +zE@;gA IS. D)B!jxDݧw!jR?RUqDZR3ˬUV`6/}.S( +]54݊a讗=\ƣyV'_rYM?:_KyKG= 9h r +CLO2Dp!Mfa8jtjEyEp~*Op1$DT&'Dm8 +䆴bm{Ok\F1y].|V7s;i 9l}ˌ;+go.Ex_١h5ׇq3mk&1=$AI/GEެ9@M92o%DMj)ѻ- pq?rBarO\{8yPXEG@,$J{o=m^}mD?;Fo?v<⠘7 +# 2yMɑ +Tz8曢øiK>7gBmmI ѱ#E0~fB`\ECﻟAXWJUl,k)?o5W5Qӭ/w8Obκ'F|oD*$xYzOZAUZ!6xmzuz ;zUiFoTL5W6T8,8"|(QXOf\O=mJ5'V,Ġ24 +;C~rD<|47.5:{7O)tjDsUT8,(1:vJUEA[7Q, KPR2Bn#Lf&h /dM>C²IL{:}yZ᯶v-n :vlS)TsFW|˲Pu ƚBbgmBeN׽ (hgŻCW$aGz ${իcf-F'qU͐X$۩4!ewʳ2:ѵA_d QG;s ԻWe+ŇL57:NDEmXZud^-;wѳ";eeJp&]80GJKu0VحA +uA?T|9XG(%c D},M 3Vz{*p@TES$eQz\30_̻2R|P8:#~@d1QfD]޵ZyP`Xk 'daD/e,.emJ&fmCW[ [0*_q^6բh3툎fTVZ4Jݴsm/hbp꩏o; Ps`Տns8WOBY)w:^S3/t7TxXJ_MqZW ͽǷjAN-E1nD;/{3'>}dϲyVYo°BnUjh݁,z`{mq 3nËszo-$7Jw*Mk0޹I:`ܤ@n?euP0DTQxԮ]Bxn/Imf q" C1BhNu-ch$ G@;_ qa>I NM<RtTqFejR;"ݹ +y/ͥ^pĖg qdcnI-橞OqZ -ʾˋ۳ ϯw!9PRNju8pcRnD@G dNd^e&I E䲂>FO_{( 7fm\?C^A;Pl!lAIwiO7Vta4TK$yXD(+JF V>niʭ8?Edt ?0IZb݆y8r`3i4 [8i +/B6K-<17 `n)G@ {sX \վ,7uVv|UwOຫasQ|.\ d6cV\?K/3%2 U*rYSCb x۞ ߌ=O܅9g C=* 1A{]K"N}F`FvxެJ{3r (ið 5lWY`oo$ מ4M 5BMMkQ +%Xrq| bPN]v45F?,%8_/6"3D(,bI/cA> PWqe"חdD^nrg/AVoaiwFobo>82`z#Z2:kҦ@n게*/Cé3|3̣pt* Y3?y8dD=OOS7sTV0`#.I<03HGǴg6AiJC\^Hts$8o$iaEڨI_z1"/dU25q^ȺI1n\-Venzp63t& ,όfL?ӣ+yt2NEdg#sdv7]ϮN%r:MyLQI2=rO/f}vdF>LjӫBAÓ[d +g[X1E%[;EwV7=7Ek#݈XTF! [0(~VՊyCգ!ύowuV鏊Kbh>O/q1҈ шQ)7"Q9ɚBZ9g~± Ju GQ2^Qn/pY=/_cۭ%e Q #~2$-w~['_$MV\]ZWޝ4sJv]bʛ.cLJLL9oҳd3{;~~W~:duI{ܣj vw`ryӴi?(~HTJ脶Ѹeb9FMҮMc|Jwb6* ArYe fO>vH?P.\ze0( yN(UZ)]iW=^q9@qXYlo˘xnX- +n͚5pb^F +%4 +l7P0Mw3efQtG%) +c +>rJ[U+rQ==!owb W N0jsx9`Uy/^?0#r%ny0F 0.W;Z8޾2-tr텲4[ P%s8W[(ޖB~kLx݆Eovt"FjorEҙ‘\bS۲)x0AXnWs_򡹕sDr稥^7HC*PFΊO#b^E(s=}ZCG{g7{3Bq7ohothoDPG=gâI/"@*٠D8}ڀјQa,E?$w.*FH1+ۤDt[>"pBH=Qxcz`H!̶8 m\7HoC<#峑2w-)AA3֡YnE%Eg RSųNvrh` 0LS$ϳ'm~ +zoW~f_ e/pt O _OENL0㨯N[4ӫQ4$e@/MU=}+}!Ga311E j"(%)u %a}_<9N-C_OĢ_W[=ȧ?d !>m^1(4[s +`BOG):\xv4~ի2^ao'P*t (ћz;6&q B96\U_RmXQ^~ӗ[[|\Mw4r֋zn|~~[e/_o~7Wu5@O/wE?=e!X![4$%_;oCo.ŇZ>?]2mɁ~5~5={C~f//g}h=C_wrKg}\rH-~ZOjϭ)2q,n_wv+.Ff>Á`[oUt2>mЪ^qS1ku8PajU^v+E~DDp]&&k$7RvF(m*vac=eSE2"إ7ū/UTf>4]4+|k2%vE,I+ ܫkqbM-jzER%F `mÊXZ/+tJ19e3>sȖ* [rح$"LUըC[T7+pC-2jVo NF\$b)U.:Hٍ]|6B|}K7^1z<&#:ISxUVJU_kTgJ;Pc*Bwı4"V%6/;E#pA/G)iv~K1zq *~B=$>` +).d-T4l '&ŔڭI h؂ I &ev`FZzjyxi\=unvesI"(ޗh`abZR"&2 .;Eb\1zkyd%5dJZWSjᠴw@ &]ҹ>/)m85)_5ګ:T1n%kh*CBMR}63o})jKf[@R_[/(PMkI +a_d&9XbXE鹚hSӾt!O#RR4Z6s.`pJb-~3PJ)kӼ|v*xnTp~"啺\饰B9֋[w&\v}5ڔitP.GW#m+45q2PV>p2]ozctVKX.h)gl1l[L- Óf5oFkpWwVOoaIrqTLU #쎔0Â%߫eDI=H: e6Bu]`} (3.5Lp(:Z]&k x}.hle2-[!筠Āæoait>w.[:NUM e78~Y!p/yBRy{4Zc*U)/LHps(]Ѷ}GGzvRp̱m!sjGqPWu͹AP4IBi{ExvZ7 _NXf3TV <-fQm$)zY: vЀ<& oqF,X 690Sw@`%͕t%Ćݻ 衛JʎT2Tt_1-Z=UӲp};m 34ZN^e@j`އȥq_jgYg~#8c^II$VbDp ӏ +vQ7C~LbҦ{#o, [ڥFM5l#6hy¡a-r۝.S!VzsouoG;,mJS~RBh// AX,]c**OO6Wd\`Z9p2:z(s/`4oB +BM/7Aα/%%4lD諾,*߭V(5ƗX^v@\N+8z.Wlt,~6mtѳ󲲛ȎK5Qw,R76ZRӎB܁FilJem*UXJ< IR6G[iS?򘖹QG%f ?^f1-Fۥ b][JW3*Ժ৾{4dz_uD."שM,ՏR~(j40nA*EWc]|ۼM{,f궃b}'b,ZԞTt]D8g!L(,U +9þB!qs*^l3I>X:ݞTs4a{C*4N Z`)S<;L,T4V"La-Sڗ~gd%FS{M1&•?΁V`a;.^Bޚ2F9T""e +eI%ha?dİ˧|5SYPd9eU*ZX8bK5jSSQ +( +Ui?P!ڶ9\5KLu,Aβ64BxT%!!ŧ,f^󧀾wH!fbHX>*y8Ajp.LqC7cL:M n"c'h!VDQ_Oc3VL(%>Tㅷu{Fl( +JK}6٢jpQ!8ݛL1Sp:0t޺ģWo@NE),㷆XL zYa=RkCZز!F9 "T>Ub+t9WȤh0;M_, )+"b E4UY  t6See=)0l36v ĿZ*0"2FixbnnJ Zo*ĵksPծK8D|^xFu#R#04A?)-R>JE=~rTAMLNW7"!Q"d3\yrd=B >B<@;j%oG;춵0B,գP$AJ8=؝!EQ$!Cu8o-^ʫvopi1{v` UWl*U֗/HiH_ Qse[j*-kCE2%/(hi%if)?S8p"q +* /`.V-T¼HOC_k/ӅDE"ķ&e&(;xخh5,4p/L6Z^-WpZ+ n SSxyHZ/,*ִG>sWΨKX-€q=(lQ +cOS࿽/*M=Z% Z3 Bݎ}Z\xUVjX0 =\c3{TbQ%NV zb{xa$LZEAb,Cj-5m[69DWUCeTmUH^[Y:t7~mrX +X~ iAlRB'jƌ8Xr@%R(Sx=@$%m^}m%yQ=E͚ %eRES*)B[O98J +7<ݭ]gꨘ1\;\,#;Ta`cv$9No=[|On"hBG**~f?}z44'AQI)ݤ +D~&HZVMǃ E}8 Cx.!qZ38H%(iEmg<]"sZS!f8.-:j%S1h]V[JZȽɿ,QaJ Zg1SZYNx*ȹh6<qe#r0Pƻ5|l@V ՆRB_CF17(Dݮ:Vሲ5껗:H1es=kU>܆RLzh]3/sPTu1g5pߤUF1LV;$ݝ uBw%]Ľ99 АVWeN'E}G!*Br> 2nWYtnNVueyU>(:"Nf^u'&kpcWBu^(f0*вCԐAZF8Bק{CiVl%pI@ ._#M¡/Qr1rl׈Jd hIm&$R]vf**DllߩP苼h'*h wX (XMwɈkR 6q!TfԗiSʙ_{ . a*QBΉ\@a̙֓h|,B\![(nK3f݀ExA=w)r[Tt^+bX릦Y}2h>XC*eΫ>F!1aqԁ|ɂT};(c_0Z S|hmWu6/z./ *Z&VjnTsh'־,qZ'6 #ͻ*0y"fUa,$bAC?U?&"CpG\U~u>Vk[K?^L%6 + K-z. "DJVxEVofұjY; FW3؛ X79f QvKX0^OGQ.eL:W×!v$%q'^G]n{g֛ +F x4ԼF 4?0 t*'tC=qE]OߟfRIn*UBwڶUX%b$BridDIEDŽun0ަsȎ%&SKB8[q#nɾfk$]WGk`VWAr:jiCeYOU1tc}n~júi|cjIz0JT-x|ܽ%# Ҍ|AM<)T .l._Np",~D<7W@+yB:rDLftbП:V8YiW K-ۢhPP_iD,:KOW+x{&LQ]@C KZE͋cPY@갴Nl)x讠C^pHⰭz_А`lJ`V* +ޫ٭ +Ίȼf*" dիpNԬE AEp +PߏJLDUZB T.m8]Wk:,F*(ͭKp Eefjٚڟ pn.DSuJw%bRuqaN)CtDY}- jbUm~Me=lZ+Me-k5e1zr-8iYv-Qt\Bj[љKr=p32'UFlL&Ck,, :Xx !`Ͳv1fKe؄_Yת\˪nD^Bᓶ63J,"j:\|$/䱅q4&ciB{^!e2N(]e+K?\gT$u.PG}l;eO7 5L` 3גhf%Pv|.HT@qbq;4^Y e6 :%j`5UxTt+DuLISW5M֧n'€UG`ǾTOy:vuTW(34@\߅vUUHao3$=z-RK(zYDLF@AL~ iMh "vj\|Ѭ@Ȩxӕ`N) RKB5fPkmSզjATۑVf0jzFQm)wѾYt I+rWF^Uac.Y?'Z;m}F7 +L՗[Q @m4Kn+u׭n-A^XWضvmM!擄6X5CЃUv)Swbq^2:tIPNPgQK ׃ 4b /c9VH1 +{b7b0AH¸tWLR Z0AhU)v{H2kkVOJY1ԥrܘ"wxcjr1tR >; d|JXZAKݘLBWJePwRQu^ˀ&y +X +eIU| Ÿ\(ۦNZ!,Mv4SSp-Fbo^tcχ~ZuVHՑ[1> b^2J=/ײN *sD)f Pw! њ4/d=QOM+Fzcٲq0v r# "r?Q[%wdj%!W-(Iϴmc9Af>-:O_}(j-5 frb$\c&]Ut1V Qddy$w ڐ]alpriUL8ʱRt 'a 7YtḨgP)ID)ƅKfR{gTR[@JgG1$ ~[ug +S:L|#1@h)#(8ˮRf%ñ=A #a|( )mUu5]]gm^[d^uh;Dl#+9?`V+83^0XxU{-Adyπ˩µZ&?|ЯݶP { NU{bT˱Pْ4q] UΓnm6gy?䭩˝k3r0T..*XT:'+bJh0s R E~z|' +k\KҎuZQk1ljum2jJSE7^JgUjK. q:I A)CHtO®\*X! LiˮEo5THd]B6dFoJ}$x .aUe\ٚE[唴a"NSkUzhsj Wy:t '˰WO31Q/Sjkld,Qz[ +I6͗XyetS E%ocD.Y]EӶK}i,Ӆa](G0Ε_ Z9)[\ Eئx3w |omNJެUgJu׀ !”mrnN{Uy8r}NPϡ^UJ}wL̼ x)8CYa֬޷w/D2dCUcϝ$XOI̤ޡx4˒)9Hf*i*X0')T|g!f1 »5HTo+xR u\׌TfT1 +\ժR~NM#(HxKr54)){49c% qthiքb*zR YSk_gE6B"V SOɬR,#^L"&/&=V/Nyn\*~D$\e!v +mSuR +_z}5D|%|>\Jp.9BrD *p~*X-j夨d˔_A 6bmk x)]y&}r,[c +s6\ XȄ*=dDšf]ppűT×W1`EJ8ot]J7lsq. 5 rWy327JDA] +@습I +b]0`)R|1ܽQeӝJmRˈ!`Ղɲ0`82fhvaB7/Fc˚ר*s.h^[Zjx&jSm9qjkbvx Ԭx߼Eq=*#qf6^TөFC2ItHbѷ n}rlJkŅI& W4+BF|<[7dVTvH [26K?j)/X xl&LpuunKU!!o8.Bۚnͣq WxJgR„arQ . qܩlF3 +rP~tP A3{dg#ݪБɮKI1^7LvLv9_$$ ^7I|\*DvDv#']Y'0ODv('#{:C!S֫CdWi쟈j3]xLdWN<$DvʛLd ]7j9_ꭃU DvUw#]Id'Dd'Dd ]U#Hdd&CȮȮ +i {秜J5DdF";O";oH:]Q@dWJdW(M87'"1ܺ!]I0ٕ!CzDd'ȮDvHdW(7z%+ F['+܉R0u'JOCt3Ȯ ":e$+f=Jf"; ։t߃Ȯ_` +Dv$+DvEŨ]Dv) ";?a= +PO#]!p>٥`"KiA Dve;"B)HdWpDvHdwȮ\ ҉ȮpDvuY!LDvU֯DvH'"; F"; ^슲f"{h~R$#}:Qj4ف$C: i$ӃNґNDvzO|"퟈H ?Ȏ&";y";#Id?DvDvDvW";>y"'"Dv) ";3]IdWuDvΑȮ MDvAD$DdPLDv)RDvjNDv^3]%=٥`"R'8#O";b": Ad'Hd'HdWDd`"*{%&";gDv:^jf";#`RWv";~Id2D=٥`"KiU Dv(1#@'˿&"`U#c"3@NE#Ȯ š#NW:f";Dv`MDvhȮ F".u";Dd=#NG";Dvm${%㔙8@'".RDvUHd''a"Hd֓NU#`"DvF";ܜ.FiUpF"norDvu3] 6m$+d~Ddw3N‘ ^NDvDv<3~&C0ȮG"Hd$+Dv&";9O"; ";G|f"+@*=Ld!x"C2!yCdILDv +=XN]%}2}CdGLp&{y!ȎHdGg&#dDdF";o$쐼!S.c"Ȯ/O";fDvīf";5i?Dk0=U%DvtDvȎ~!Dv)x7I2I$C<٩}"cD1AȎЙN$#6>١9U5܏Dv!T3]BLd'Dd'ɓNّȎט }UUmDvh'ρN*v"{j޿2%*^Pq#] G{!LDv<$NdO";ؑȮ*j9U!q١'";S#zId`$*|$x!$t߃f"DvW "; Dv[쐴x%XFmI z!9=Q2,}CdW&";*u6!^5٩g"5BdWBdX΁I]W"; +Mf";sG";oODvE@";3]}2!\}zJi]1΃N!Ld'ɓLd'@dgzr36)$#4)`9QqDdǴDv|:F";"o +9׉Ȏ0Ldٱf";6O";^f&Sj$GI<I0!yٕDv6f#7DvLdWi2=?1ԞDvEDaDv\$t$Cb C쐞 #kȮ~ +bjIdWN%#EFՈ<쐎DvEWf";$ "; "; (z%DdGIdF(({ّsSODvE+Zh$+:IM=HLDvJ Dvd)DvtDv&eO";Id8HdWT;}٩ g #V;aNDvDd'Ȯ +P}O~ٕ`X"uIDvE\]+˃NķBO";V8}$STt$+b;o$Ԙ.ODvDvao"rz]SpDvDd'<ٕ!t$`_;]Q%Bdt"5'";ߖMc*%m Y:٭*mȎϓNA{"#Bd'qu";@ԫ0䙈V_쬭f$#NNDvU7DvLdWeҍDvJs?hF";Vf";=DvΟxȎ7DvUT9#=٩Idg=l";#&";IDvJODvgԶ g";DdG ]w'Ϛx7Dv&~!#?ٱg";u#>H[DvBdّǞ4#Id昈쪖@d6٩6i u"Q 5UiW";,ȎlDdO";lȮB` AdWu٩ȎDdp@dLDv*gT0I$X-O";#]JdDv&";O"ڮ 9١Dva"Id0Q3ٱDv*T2!xI:I0A";h&";F"F̓NmWȮ F".u";#;GHbPq]g#_$$eG>$ eQvQBⱂSz(%dRe7":(;2Na?|P_(;[AٱHL(wFم(AJFi(;pAiPPv&|(;|3N[7ʮ_gE٩h{d((;pQv*(;2NHoBeBE-9PvxN(ϖ eD`QvװBS=UD]T̄eRn/Κ*N(o]a8b<`Ѕu*Mzkݢx9uB^Cs|N|Ů;Nt\g.c뀾kq봬ڟ [7.='NS!u/d~Epk>{; n)UdHRi=d^) T'NϩҲS0}4-3uj8/@Du}O>^x:u{tu$tVgbuh:H_BFM5ts +1K;n[@oAų^; 8/J?HzT>sǟYaÈ&q{\s^陇 Ps\.A?m9+UfB8g_qP 9U&?..):=j:pA+=N_XɎ[BFJ-,y5NOcbI3{m!qS(<4Vc=,̎5g;U7*&:ΌM8̂up VgI`QqU8 Xq;#Hg維qd]`PC0mV<'N!8 5jl:MAؐ`0y0bL8 ur8mi29N Q4o r29nAl?㍨J*(;e(㻏"J˹i,`"h$sDZMJc&oSl]COy"QiUqvk9ฆ/ X7Sqt: 6Z2'&6C89,Uqh5q}ܓ8ޭ@XW61qOiKĸ1qx>WN+bZ5aqor +μ&)FipN_&EP"݅wy8q DN`ntBfC= .ĉ{6:0,B[ i)rD0G5xN+< \#C Yd:~ N{Ņ2Ts* +kHp6›r8m!x7}],8KvN -p89 1Q9hB8d'NE'eŁ# BT98pÕ'YaL?)Y1psНɩ cP1pK }oܫώTq͌+*8] +*nF#`-æ)R(+J5WafÅS̻zLhJ8v&[Kw9n)c_p7=CU +ͫQB_7^դnSƖr7n:@Cnx\7 u\yhA`I'؍e73 uS4uuda릖h+ʢvɶeI!IƱqݤh7Y5]܉vC2n(L +M2ѷv7EftlH+h74#n). vvwvS$dhn:xx{ wlTp7]5#&C=M!3s)p7fAp7}{W'B )IXn(v#q-8n \v pԚc(:a wskCc22 [t7^8ݍGPs{q8n AABwCx7;8&Mf@[?nFj|Vn4}vXf\=neטt7~㠻27 +M ׂ͂.\k_K|MVGY^NvSU?N\7 x֍kiL1n#|^KgVLlX +endstream endobj 94 0 obj <>stream +95a 禧vv77t soB,}3Anws&o~6q{(5nYP0p(kíE|2ܴ- [nX3Í({`L%ZnN/mƐnMex{1ܤX\.n(Fq@5)7L N5F.7GCO=N4ܰDg( +MAV?&?8*mV|av6ր=gT4fv`LtV6QcJ^v?^ܶWۦQ xS mȶ- bȉp$׵ٽ~ݞHھÿ?)+y ]1Im$!6yUފ[J*:8m*S {`¦]2DOq@ڰ׼hS|Jkbt& Rj ЦUz峩X[=x`fnΦ:Y AǪ'M?}hS{L2z.G'u*cëMC⥔WG.plc86 +%3 G˧=06(\]06k bS8ĦIaÒZFv,(l;MGEO +M$J8M8=A`{o w)}5{Mk,53'y2S7Gݎ +z)5 =t`AΉ\n& '6k*U0.Ԧ}mG):x2Om)5id?Xk$}*Dp}ZԢk58}RvgX Y rvV|5}A52eB[\MQ; ,U6ڏVʛdYtj݃&L3\qMڰVTFS9 cl$R7!OڸmZhj 9MM3cLQajzQRSkD)zO$5lXlHMđ0jVT0jEMM }2R0:PSf@1 +Pix>~4r5i,(tkPi򸾸iR-4 , ?-Riov+ibl~{6 c$[4PC^bQ_4ZMINeMcE!`#6-37싛F.2Q`=\iz{7 *>*i4 n%7 'Jhpp'3]n8iLlΠVtlnkV>ViR Pv^啋34lunKnZÎ6*4=fFq&zpĘ 7 'Gহ7p4X<>ԝmYG74aM3,ny-jDjM0it07O⦑j7V۽i^iJOn`V޺c 3*7ݑ n}7M9))4^ʳ4|<?ob+us׳i$hRӔe#`5i$>Y 5dld(*RM`Ӕ^i6MgZ?Ǧ\ef)',[1{27M~F/1⋛M#[Ml9iZ4l0#fj~;^@YSo4e>Yyfs@nL>`C}!S^\i}6Mm7F ޅDƦ)#*i25 Ph*fW`"R0&3V)L8μ_BUC徵jfR?i)(4LR48Si)~4>i>vVf83MB>pfiͬm0Vh;9+ Al$hPPiMTZWVсJ:}W`×K[gXTI-X ߰4\3,M6zB X/XZ7 +KÝ?dfXB, 1;dX7,MwN‘7 + +˭D&'XitTܪJB|*Pi1?;˨4jD3*]&@iwK/PiLMg_$7Yb'2{&բFJ#rJe[S%\Ii6CR l#Hiʳ~WRlقF`B$';PPbJz *"=JHk6ӚܳsqX-vDIOɰ4UІlrt*4l&Zcdv^ +/mK,r>BjTff9EtܫqҴKS샗~~f܉S546tĜFB!PЬ[UZߙz/?҈vE+F9+͎ڟJsx42 +T{Sǎ&HiG8(p'I;ybXkןII;@Ұ`A[G/;3i+@fޓ ,<)LGóbIQ+ +(1cSh +1 +2ygD_T.TvD=hgA@cMPCS^\J]\(4)0kUW ȂA0>"fRL@ s GIGahS \H5ͩhf&YUT3+3$SSU]=>Sgw}vK֖|&{v%K;LƅzvGR١g|'qGxi!TnoN<!_V0 4Z* 7WO}W4UpіzydMΦ-}&q@Eop4XGΖRPg&7vk%N0e3Ÿhs:pf9lvn/;㔊A~TƧ1eA7;Pq˵*lýYz 2lp7X39ӣUfUCR0zi&ev!ʦZ㚕y/eJw,w&Ûfﭬ]]b2Ls?r:n`&^b/)݋J+{L/cghAWUp)1M.CP<.L 65$( vT +l.]r[vaex_|d.S6}]'e\GmJa:dQ(r,Huߕ]F 'GBzp)Df@mt;Lg7eS)b|KکL/c%6̿3l2P5g%m^My*@1;#aZ2kO˜#Pɨt_I}D` /ӗ|^fHfcrɈƜe^ynM/emaYK|_X#븂/a /#"%I\^5cּV4eS(:rݲD<=_F6][I8r6pZ2TFz*/Å[F5 G>_/[zL8s|Eu۠L=e:_wӈ2_ 0j̴5b,UuWjɖX z"̦3,io|\=LĬYIZ= /{84)ho+LYCh)`E;=Q&q2U6םvx2$uR +L+K)璉*M5I8e)Q2yo*e 7@Uѯ0o/i!b%`>T L?cT=/TZͪ2dVttXNx\V[k;)hc`Ee)*Ze!Y~&?;nq/^財 ^&A|MqL5/#-ܹM6|l:QJ&5B5'(G0TKC\xo@6]R.̔7U|Ϧ#ytON*'L .=OR G3r褞6ƉӰg((2v :gf/56z|}*=)=H r y잂ޓp{|!da~K&ž[ǔ:0+vAF;mWFu Ev3uCNJ}[}5\D) +.~v%VR eK'm356λH6ባF`NQ vK"!w-/x1,51&y,7^)Qd+ѩ[P/˱:zPywU' mb$f"/R(_ +txg-H* 1n+B-KgvXDQv#i£8{OE-L3ʋd]A/";Xt +K\d-N`80ܭ0ATSOu7cP^pL}ۦzgPy];O^F3U;29?qځDYy)?@sO/f2 vlso >zJo{pu!owA ӉSD}!;^8p.̪4/n='V, w~ЅcC޶䍊2?ڇ)-f[:1̯g~/vkNS78TMiVrQb ^d=* |y\֧";tgt6Яڡ(k.C:ׁf,TƕlKCWuJYy{I* VΊڒԖY)M{iT eSz:P؝x>fOXm6Kptba>2Ka;Zk*KQS zho:U|&a +9K;/(vLJvY:?f0gv/^ c?@mG3쵿G"PCneH7,iB՞dWKu?5WOےU)dZ”^FŃ4z-:Dq(nY1I9wo߭R<:fIk# e/~;; h?tr4^)i{ ߶%N=v[T+9 +s1EVЫ7H]h7 r {cP=@Yg»i4k[ŮDxӴJ' `ά+ 8]L[l/Z a]Sy8lP=nFYCnnK#D?zPw_sgdĈ膳TdE1z}wߕ]EsbMۮ+ (ySYM3<Օr|D|1X#?rшs +ז?Zq< 4Z~s:o 0}fJ$:&;IݙNeIAY ]xN9J7{3zTR=?sxI`C1|$a~w@ m#jezQ#~ LY8ɟm0H g(9\B^[UI`=i~d)jo%G;w[4};F۷bp]cO-X/= WȮƣ9VD:P'SkaY/T[0jTf H:I}ֆV􂃼TʼnCJKmMe*&N-2LfГԥw(~X>Rpi,pfPyZa<3xܲG5E:PaZyն2!v]^ZRT#䖬 o)+֝b!XHnK޺g@=pSe1tɡ$/xC(+*JͺC7\ZRlG M<۵¿b,=qx+A{GR5SIliQNv.|Zݙ^܁ҮU1[<|(n?hNl*qfD!o\UYRZYO~zOT⥛eJYNQ喢ެƕin/\E5)* .N>BUS,ߛlt.<찛Vȁ$Řc/(SYJZPOJNe9x%x9B7(pxvAPb.)grXr"ai>z>9-uV-ӳm~a@/2NYfUD9-خðLb)Q\B2^6KʶڬrtP(}ۿn#{:ZAon[(}_7Tg`Xveܓ2lɇ;}&+P'|d(s^ByclĠGȪ!Mn(E|,mϢ)h5[Yq0m4UT峈ф)պ$^hU1s hF6J>  ŷ{,Ir ;d:?vn˃-Rp[ZkNѴ{Pdys\;x|-21sLG *.)QB%/_:rxm׺Tt.2g8W9RL[$䓈,]2u=tWQҳ?x(|ٜ[ȲWfAd! +vF7!CO :Ž=ZQ0k #1I08ΊHļ %ocq@TB'P9fa`ݴXvYNvBWKgϘ +NUoqX󿆖VE +b۞JiP*!D[8<obUU9mk'NЅROtFS~-OHF)wl'dPc +:ܛ:g\~Z°,UEֆ_؝fFhPz tljEM=}̇G^zQ6r{ή:)&xK:v$P@qJjRs~:o kJMhPLΠyŬEAXʹfzS,I>aRDV pHhCySiJJ^6; ck<e?RHkE4jWXAuBR[wOp:d-z;MeڏKQ^ +ّdf,lrlv4JL\%szURA'O)Vé'*I=iY:ɍ[2Xh7^y",Nݰ::x2F:U|ƚhbfa]06Cv heũ++i3NWdř-UGe"i>4,XG(}7TGxN/iQW_'RGTlda41m ʰID;Z,{MPs$xL,JpK*~.*LXd>Ғpt=ogEvyPn\Ι LcR_ROZ@x ~ +YRɲS;+|+xI= +'Wy4"NDžFl| +jZKdµ6ͨk~X n&BDYHvԋ~f@C:Lu'/$,|`x(r3>lO +Je]Rn$/ +/ۓ!Y`Y`,'vcr"j_@(/ +0*/{>ts KD ϠօvEq-hYW;EAw7U*X<.-YGWX[Lp /w,Ki$hCյ*y*NP&5O$6Do3慧|ifYw`YMuoqz-71Zkp1= Ǿ(zD] zYC僢̡ah϶F]*;vQRqmF{0KSENTN6CJ5j[PS gn%ÌT*p 8 ~Kf#GD.Vi +@H{7 tZU}('+Wt! mܬ2b#hڤܵOحbP$ӝ{ /==n$krt`7O2VR9gE ++rk˃FC,>`|q|W+Ss2Mqn$qKݖTigd i0Sv^j~3O)CIm? %ϽQˮXvFk滭aAPMZ6qRIz|y`c w{V$Gb{QDHe|}mO*&Gwn=L]Xv"}P3 #}+e5LcФ]n͍3O{'OSG&C9}6i@%cI]!2‡WIa!-2vSH@0T^&a%Jr5y21P:-ٴS0{DjltMJI1/ nc̈́g}˲KiDUvLZV{\P4f*],dr$ЋL+ +#}؃Kd"5A,&R*\SEH6ن$ߑQSN>TrJo.O!#V7 'uJYIJj`i^{݋w S+t .qGΦ@V:(/HBb{eRA=l&o'Qv^j9HHQgy&`߮}$<=,aJ*虪O8wvʣ>"=Y Qb*⮤֋%ٵ'TVmd9A!pY +QDפc)!ev/T>'wGFꌺ{#q( |ʅ"ze["K"6Z.'K]V5}lw"ivA-DLVMjN}a1=XB3)vǶfBزV\jIvP;!ӿ!)Ёby)W9L6)+daSWvRsŅ)yD6/qBHU)E>FYji8KUIE884(XrXV_>̨r`f=Z\j5]0ܶ;)O=-%Tn{y5}]Vف2BU +p NQ; =ff17̨a2Ÿ$4i$7j#axtX/ST@#AFH@]lIE&,nQA^w0[\eYhn}`sX TrLg} F df#Q' jSd{?j~ -! !$eVJ`d{!5|htWGʂ'ƴmԡA_~ޅY%:3 +^fJ庅@fA7_ e_A^֐;, eaL6qBT@_ܠOJf(x)J7eˇ3MʢWD4O2ٱ䀙E.2~ANKl" ^6-1nkRK!ubpNECkM!}wvi.Ys!`CLr\[Pz"pݦP imZaBA: ЪCߛ'Fv!涗5Q]Zk>^ZaFy2SlSe]n|LelCH]D0(JH? " 5֥U [Fa1sЋ"Lsy[ $cHR= rVk)w4w߽7Nҳ]b1`ۭta'ǮgDSv8ۮ&XpgrwS@6aW2ń*k+ڢ^o]?N 0c_ ϓIL=KiBd-'pJzbzMw) ~yq3@߳P*p7c9^5 dfzZҬ$`W΂Cl7E3 %ɝ#Kxe4;I¨F/Wc\>>wKf}J(K؀\YaY ,|Nm9&<{4h x +(mO=0m~l'HHnR&#PwgyMސTklߣ嬌&7x:p쾼/af +l;HR,fVM@eT Q=[ +)O-Ai֣xb:N@dZ!M3zuOddbțu.@ IV6%$P&5p5"ȤYyhSi2ryO~-s9Dqf2T~YDBA \aETfhV'f=oZ:m\(+CtYlnJL^W~3GITKCpvGlx$"?R^ ^,m&g/T0Aӣow;8k,5SnN;k7CX骅D=  5SˇzVnrlt H*n{!@U;pXp;1An_Vզv#N5xRP*}#$Ah^'A<-gXM>p mO$٠~:loam|O'?P/ Qi#mN5})0K=vs,,@TW;G,.eka, 2 +?[vXk1<o1K},ˏ +@c3 hVqJ+L$^YS!6n "z}S[.;5_uMJFTXjŽĄ#J7K<}ć%Ȼ\k*{8~#(cɏFye[.TILAj8V9!DzVg$smem袥)4UJdAU2TP[FPFSQU2M&v2i[9m oS{_ iIfsF$>6nCwfgAu* #du 9h q8p8TzU%AnayrX5nY ?*3qK/,ys >Wd 3-FIaӁcӅJc{Xn)iVMTjͼA +7S1%%KϮ2/e yʵɽ)Rr0ϯ&ݓC8[YBv&-Lh 1wNf[f0aeZ*jˆۙ&P2ffs+3Zڧ؇p\6 v(:n 2qp"XQS+w|'dIƵ˃D! +xO|]'N5}JHf TUy/3[aWTp7$ j''sq +'hBVyk>cM4{Te-2Eno4Qu*nm˓Ć[ *CTQk*ec#cKW͘D-X ŁUY =7#Y8{ +-1uIJ0ynQdlriS= |Ccy#A[TN/R3ӛ%hw0ɇSd>30Uʜu}tAU .y^%{Y;JPmOD +BYVes?ܙCIܑEǐZi-Z۳?Oaf=< K%O"tL\Zks2gye"ݻ!~^{)+ J!x[%飒3qYCJonç>KDܛ +nZ\<7 ³ݹp`^pt3 +3f n'Je,ʩDHLf/3HK .׃1U5c.N"rU.PgNEZf$J5А.jqD&hkBpTfTqķH!mrd64v^ bGbkyᬪtH_jg#݊MTFt5i>hLc["'UW׎5 +񔑢)O-\Uǐ^Q +Lq@*^jeM*yYtx~`E՘+RzVQb%ǥ(\Z:+*](h|yVR\ܯ`E='V+j)`NV`Eno +Vd=V9:r ț{NϮta|} +V\J%*NX⫀!(bSy}[O`EV(%TzY/f2XqV/`E͞? p+ڬI)fVu< +Xɳ*""J*UDUR~qUUv*j*|q;dUKUD.\E3W=.4~*r +WU6*(\EY3WWQL*Õ{\EJ WQUE/ܛH~:sy +WQWpQ +WQURTa\ŁV*?|s%W"\E(h_HAG&bX4s0U$VF+Ws~s%N\EU~UP&b'(oZ\E, +WQobXw;W C*&%s\>afKdxxs5U]U\J*&ոU&*boS(H\E^*J\_(q%*RC\XR +W1UgTր?PbŠpRIvG*W77W} WQB蕫Hr**2*\EfU(rTU\(*v7arߣTU^􃫨p*r(r1*\Eܻ\EU䥅ۿW +}7s-\Eo"U*\(g_K\ťWQюUTWQ(UT\E߅0U᜸:#U\rpq*\͕(UT`*.p\En +WQ?28UĤUD.\EUGU\R*WQ"~҅HpyqU._\Ťd|ڒ#s"=s5~puU" ULJ*.9U +Wu;pٜ,p\EQ*R*b.^U4//"S(r*n-\E)1/B(U!ԛy*j\ťb1r?|URW&g",\E/U\K)\$;WqO\E>_\E.L*VWUR*,\E*Wq)u`rp)0-\ю_\Ej Wql㋫8&pd"&>/"%IrawhJ**RQ(*RRR +WQ›hUEX\7WOs*Y\E* +WєU +WUTKf*;݋=Q**_I\%Wcڝ^\E6Q*(WQr*WVWQr*E*RBS"OoUR*UD.\E^Q\ť⒃ؙ2Ww7W#UPSK)\%WQ{BQ/UmVv23W1)*"?UD.\E)(WT*Z*sQ\EɕUx*{U\cXr ,\Es;\E3%|q5(V"UمU\rpT7WѦUT|rItR+XTg"뛫(rQ +W6dUUԷ\EUWR +WqUQ^*.U^z, +WQU_ +}?N WOB*~}q6)sKb}sI"ۖ(o"r*'so" UbmU\s;LN盫Hp+\E-p1sUdZI\%WQU{UԀXAR +WqU-U\EJ +WQqUh*2^O*Qrḽ@3\ť⒝H+Z*I*҈[꒭\w|-∾U*r`**rcUԕUD.\E- +WQ"׶p"Q7WQwU*7TLvo"(U?WQqUT0rsU\~p WN*JU$RVޘC7WTK**Uǿ`2 +WQ8}j\E~U*dR WQB*5xs"J*+WUUTdpAp?jɭ\E00**TW-V**j*\E~p%W|*͋L*"ʛHr&s5*WQUTo*RS $/[y h9WQwW*E *N\E)*"g~pl WQתrUԠ_Z8h{q#s򙫈*R X(K\Ez*WQ?r~}s%ב=q7W*P\E켞/"UT\p)\*j?U3\En&WڥU*"݉(e盫:Umb*k**DX +/|?8bڂUԖWA*-\Eo"U\EF~p UDysi,\EUzqqJ,\EU$*R^D63WU,HUT@r;2WQ)\R'sf\E~onUp!2Hp+s}s3Wp(*9\E)?rU|~UH\*RW*""uǞì\Ec f"ys}qUT3*Ҿo"Ⅻl{=۹ +*˜\E WWQW/g$/}~s5{=YrUP|\E,^\E%n*WQ1UU&U4|ɋHpfR? +WQ+v.+ W 2WQ\E:2WQqU*U++WQ\D\EoW(obUfWQrH\E%o"gp9YzcCp{*bP@y*u-\L\E}\Exb* |s)(\ErUijp;잸T Tf 3W7WpQΖRUp T;^狫!)\E +m\E l'\E& WapF*"\E)]iUŠrmI\E /|syaWoW*RǑ 7WQSϬ\EM?֫4M\/p?U-AUj*RQ*W_/b +rbUD.\EUd*2.\N{*JUԔ]TL"%Co"r*J)\E o"U$~p\E)"řH@**)q,\E6o"ULi*tWq@\EUoUWQU$PUU\X*b*J-\ENe*D,2WQUWU$yTpDD*bW\ELc WU*b*b^8 ~pq-\EUTUZ$by*""(WqL/*LPzhp)-\EG*IHL?si(\EǾ*W+U$*O*\Q89_*2eUUD.\E)(W~U}* +VBfHUA*.VJ**Z;ʀ**Y@TQ_\Ecg"9Uԧ*+Ptd"_U$W\E^**WtgاUTr(sgU䥅n*zRe^*s\ERDžHUp5*WQ)\𑹊:㙫Hޛh~(r*J\Ez +WU$_\E:u^\EU$ퟹJ *N* +WQ_W?8d9quW"oꕫIw*<{*r W4қVmqIXF\E +2WJ*jI*jRzt~p*\E 8h~q![,Y:7HZ*\w'p)xs)(\E.2WU4gnUUQ(hǼc*J\Aϋ8gr)\E ?L*WQG*8WQUT)O*jU's))\E)?ȅRٛ(E*\ŝ0w<əI%WQ L斴q=ә=Z((WqoWqWik*Jysw4Uܷ_8Wq "&WQ/B3ߔEw}pR/ʔhHY|qs9ÂEQk%lȊp$+Ja1SɊ,ZdE]JV&+jPɊR +Y7YT{hϦ2YޛȞdE7YѬ2Yy雬( "!7YR򙬨n%+vj_dE*YXs!+P&+""J!+R"+<Ȋe"ɧ7YQBVed]Ȋ Y,͛\ȊtdEBȅRȊv̋ɫie*dxM?ȊZYdbYkBVĚ)y"(ye!+o5$"5AֽȊf͖ɊVd>1HQ +YB!/"r!+d"&+bSȊ28JV49'b#FȊY%d?Ȋ8u"UȘʊM9+Y1IV(i{5R +YqAVk"MV4M&+*nUɊȊRȊRdE}B%+JdE)?Ȋ2Y,hwˋ‹JVdŤdtZHq!+<YBVĴ3PȊN>us +;)dEm;*Yq*hr&+.qoyU_Ɋ=C&Yj7YLVs"+)dE Ycd>/"]H~2YBVLJ&+.ȊzJVzȊ|BVQdE3Y헾Ȋ, YK!+.dN #q{4h~ٙMVCSɊ8 "̨7Y i!+R'YQZ%+ËhYHV_dEoreb$+Y,^!+Jhr&+ɊȊZnW"J!+ɊYBVS㛬TȊ4"Fo&T"{YBV, +MVԆ5td"VdEZt +YQJ%+&%MdEN +Y7Y:LVc"+2.Ɋ+Y3BV&+JdEBV7Y?BV"AV\Ɋ  +Y#7Y9ye!+o~F%+*dE7Yqdhk/&LVRȊK)d%YQkJVPMVĨXdŤd⒃8d1#ZȊMdE֮dEɊo޿-ɊZ +by Yq) +G$"Y~BVp"+*P R +YLVж-"+/XȊR +YMV'Q +Y67YQu. Yq +$+Z`2ɊLЅH1k&+.<[dEo Ȋ}HL!+s&+'Q2YWɊȅR!+EVԷKdE2Yq +hr&+RiɊdEkݽqG"+j?r!+EC&+*z Y(k!+R6&+*_ɊzȊK)d$;YBVS_dE +YQJ%+Ɋȅțe,dE\B +YڮBVLJ&+&Ɋch"sB%+ʋYMV;V" LV dE +YnW!+vVhʋ +YȊdEe +YQy%+ү&+jSɊtBȊ2^!+YLVT2RȊKbߦ㣓z=dE]JV|~p`5UK]B;*ʰD-&Y/PWREVñ'('jn&τ$}DB0(DKw6#z +IF~%$TxLW#3m0gQY㲱rA~싌Fگq-,"ۿv*>W@E٬;02BʼnL b7ՉCT) toA&Q|L`X!n)$ΟĠT"Bgqi@8jotU_Cĩ49Uoma V_n8U1Lȡ`r؍ =`}pg:d Wc%fnH|y7`sֶYGGB=ц6B6FX;PMaT5|k8ܡ` 5l@i3B^܅B& +q q-k(el6-Y@װkmr Ç + 6lZv'N!"(Ô6`C)$s&PDa;}=V /?oBdCd"&ِwɆ̓l(Jau;mXZi`FpM +)4s @:yڒ\X8C _4Ct{:`73MĂ2Sb#$Cae4M(2p1 5`_ c> @N! hCNjU:p9b Lx.W1*P ͧpA+0|D/Gx7E.-T])jRZEx]A|BQnp) +Uk6X8+\ +~g3Fa>B 0 J6\?hj"'//(:f:^'3[]J6be8)6̫/m_*P*MsSB +WᢂA +߃&z +2A*L"3AD,9@[kc +q埠B*"+R3+Z+P7()$:Lh;T9tw L95"6c +ٌ+01(%N"BUBIB{[g2k[OP +)K J"7mƦR +'k((()O8Sآ}b +AiSAԮ S&SrYGab +R0KL!=8}წb)l*_;fR8)j0 +Hu63 +MjZ|n +٦@Gpv{yEJC +aa/1#JlQ/ -s*PA}?mzb "[rDsgA} C+P2V>IɈ%1Ѓ)X 1;D +B{ *PM0r>p:B!N͛|Gz$2Ks +[ϾRgBdk>k5mMB՘EN_QȠ |wr:K)$;{r̂mYs.@ P'4'lOh$ +5OdžU. |]g*'(*YZxBUbp 3q[e RG)Fx *u5U +Z$XOpXggJ$NPUD0 e,yn>}^Jg.pگ ++43VZ#DL Y*(BX0 &G +S8'PS-}`)S !%^~Aشdf(B'tZ~^fqJ6Tp@X]@ԏ!L_@@%0#LֈַȜB(1Cc1%0 N8!7sš9k l섶k2g;<8ؘϨv`STbo_Os;N.T6H9W+ +-nu~ϛd6شy4JFi "\A)D,'mP)+0ID ,'AV߅6(uuop`.'sd~ .A\ AiAm'9Tt! k&(ypwYzu5\T1|q֠фPY}p }9YP,^Me ~Xlu*(h)5` \8B5AUa8SZ;q@0 +QR@e wyjAeP_ǜgʠds AB_ "'魅uQPPNlJ R +epAlVg|i5Rp~?.lO4aF [ܫXp +8 +*_`lVJt6TP5QCt< hOtN çSOܭiŃ i%$%Bח` F|0+%x5 Uv-Vk %dT#8S¹vh&ܣ6"(K)%EPc4~"HLTjϊ"0!x#pU #FP/uGjG}j7oeLQvj˲8{* +Q"l0B\Snjuk M簝ПURPߑ(|QI@J#"(^6Y \4;E/[;EP"l!;!GD+ ! RHD/cCP+ TȥuGj$%B>H=1ߊr<>R[@C`Rr + +>y=HvJ0O/;@݈kTzE(ru| t>&pPi )!j^ uE@KU>'VbEDGhؘAr; q:dDXA949F|j *P ?ůwWHA A# +ZA,d 9BPfk'B ȽLXg"ZAXr u ,!8k&B<MBP_DIRRx4ZAv5#mb22C=6/3-i/:p!؞H(CpTO*Rj,@2(< AdƩځ)f]a+A\0cT"o +Ԡo2i%Ud8Dׄ(o]! ?F46@xCaJ" !%x!_ro2~Q_A9O %UY@ +:k%Y@5@j`F%oNn  Tџ/jLg_@v3k@nJoa&.PA $7ӾX1T`T)&9,uV +.j 󙙻[F$ 4{3ƚ%hJ@k)Drm0D +,@[5R R~A +$jCII +,F2/N& 6HR}6H((z`b}Ԁ9G$5'PQp QGBٟ(gWek٩@hhxϲ(qU)w``sJn xd>+zp 0mڢƖ2g寙PlJdU|\Tc Tx29kAR{j>#P@u&`gk5RPBK;{Je4@zXv ,Ig'yMKsFىa>=~QUXM#:|HPFݧt։Ċ( Nn2ē4wRroꟆ=vY x&Ozw* @eClv;,yOfia{̿4cHb}wz-:k,5}Y+ӺisF=W +} ֟d8L"X=p Ο)L?EFv Stn-ƟK* 2ApqL¼gGW+jݞTl+D'BQadxD*~`;O,Z0au`oRhw$kX?wZSG4 )9lFW&ř~!up8?rS`'6_UNӨl$= 74(~N?2jFC~- ЄlU75 \},Z-}-⅏Xhd%dUѬ&,}%ܧ:,ނۧ*j%^ӧ8ݶ*̾ ғ٧'vBz_اDQ8_>zO-V>ʰ>q1Oqzb&Rsp,}G.(}~5H>*`SR ܎cT H1VԶy<heꇗN@_)>f@_i(M }% +2lPУpZ"I6Q +ݏ1bbW–r2ܙ[-k9G]> AOB/ӫs6|b+͓J'ţU冭}E#ez Ч|OWT̃oѼ|*TgS:ֿSͶ!|9/:T qx[S?d8T(ո]|͊&^+C@Ek%82|v!#uyN+Qt>K |pqvh +W,:%$:_"t>͞tBGq>fɗIS#ISwY$:_ۢT:z|Ei? +Χ?7t*+Q1|nst! :<&O-$:_OAKG4D磺Ԇu_8=HGg' Vk`Sgy04*XU4ymT1gT󱥩z|I+|Ev>^\@ $ЇL<}RӿA&:m&gy,:J|2RcIS &79,Ez;|Y|IUN:B 3tGU늠ѻBsYzR|4ǽ|00!dt>:x~Wd: B8^|_}fCcA+/8fWY]ς2StlG[g s|(&Y/Χ7>XՔ`!Qfp>Ь| Mq96:ZDS· #^_Aڽ|cۭ|z9UO2Es\"TDh>}ƅCƫ4w[QShZ ey 65/4_ o qiky{gU"~.K4z װjdFSQ+ۀIrXOQd%&OQީ +`]췅̧Cx2Og( 2vj|I#(ɼU!byX>zPP`qTWG+@Vg-( AG:83i_"aDFOldQDl `.D>;vUڽ0IoP@|?-0oH> V|jr׶n7 =NcGm:@ha(9F^$Ϩ}T^LJ9oCkU,8,O сa,^Eñ-*[ȷ);mA=@=|O̓NVNCJ/|(fD>bYZd1\SޢQbDͲp#ZGV ɷa+S@BMH2@KaC{!X'$79!Pv$/$ ||z2O7 gG|xQk;N.ihԼh!A3|aߛ~@>x@ڏI^a@KYV#!h1y|eI&X<>"׸V/┉Gx3li-vtxiTB5dLbѪg.'2Y~;ϢZGdO!a9D#{7pӏ@ +-|{|2Q&! +E9 W(dODq"NCщȧWz'.TID>mGiP5g iCz7q' "I;~vAcMf(| ` @L"y3MD>}ȧCt$Rok8mU'k<NL>nИw̼ALhnSKb˧AhTX>)guh+֚vv,_XN˷){ɒ˧?:mʱ q; F[BmVɼ6(OP>io#HȳMNXLP~[M҅n2 +@P>m##3CC-ۣNH +Q+͋2]?Ŏ8O1sZȧX@߽4zpFoX{5t^78"f$>qk& U N +,p3JDw_?|y4+|F2O ^8OT=A∍ktOK8Jt3{ƓB^ ̗]v݀{wPLSԜNzl PWY{Jiy)@{ۺ&^:q݋wQouQֲ2-%Q玾Sgqn0?]޳^wG D"Csdr F:]j֊Nl=h;WcAS +#rcPs$5^ KbOdSHDP'Qi΋m7Kocz&z"pN%jHLUw6=\ eqMT/L '^:'^k;[QӝÃu0spRC& 7[ŽϛFSDžBVO<(UwzE%ݍVx(9>;duŃjzaE<|R7ӲRR)^ez]bt@BVܕQ7^WbO[7fߵ;ы}9uo=Qmo/~pUDu7-MF+ gJaz`bQQ"furCkP %ܟIƿ4Ax8ΊsK|c1{-YdSꠕA\ԏDZ|T_LN>Ȗz:" -=g]Q=R(XjRIJڣK<Lƞ ɗeAB][٩_?C'q2-ůf,En + F@o̔/ϴwrE 'o;jŗ3vŴ'Um2ج#@Q;ʂ!߇jNⱿSRLF'`gޚ&w㗜*TC䱆@[!>X*:)-=yM^n<>n7FJP?ں9|m )+IMiC}ǭ:>uvNQLx>#cN]+j#!2%ȟCk(ݓicќw&Ah +Fԙ4/ǚW/.aǧ}?c7\ƂID^hQ$M߫T `h|Ob*tjV{RuBX<|p|]5+X^YKmBiXl}6s'657h +W<;ja$BOJ2raU,^& fOFWUXq.u+w|1XϷɷŹ&CYm4M9@a ʛoS+0~@Tsе}W|h&(*g#J;@º`B7b4ߡ>}ݛ5]Ưl%H[;& +dhX>jQa~o*hX{*S\ױS.WCZb-t_'p]%UnMYn+AR0*Zr|>,t #$:y! +oŢI"\2ecR>kQ{}>L|xLKaxܭEU%\|aѭJ3"mˣT䌇FH0>ɏI+1TwIyb]I.~|f&Z}Qrz[5*D1#[^j*זL+U_y;3qVZ7Pɪr2$ЃR +]oAjGFW{GB/K?~vb32i=k=;Z#ӢXw)i`f`bq;/P)pɎ[yK/@G%)d_;Z./[ja00ki!+ CAֽ~M9+=J-${-LX J>y6/OdrwRNJB+t,+ttuنpn?8n +,K6FUZ7|ZO2k0ԮrBS 4nAufa6˚30B?sBM;Z~iOTdS|XVÛ26ǒDjZA%Hav,-wb[;dǾ=~֘?D6[JS -.#"kKP|>p\$Y/Ĭ1;͢C-U\EKd`"Ild _aLXN4h __J? }{W%KQ̌/Y< e;߾ӟ0OŶZYٺmc_$ůHցX}\JKn?iSBgyx!՞mvR(-sh۩|cՙ9(Z[?,l&=N[{*XTM<-Y^%k̿HaV^P5loׁ +ZZ!T+.Z-іGi/{/2G*1\ Eff=t 'J>yf@2i챫*tkfeʧ_RnʊrAZ.veq;TP]fIZ}xz]n42i<8OM~ 3}z90iYQnזLqE{kPXo=e"sea \**`2 ȂT~{XXʵjejEW>NVPcCDDv{_Tg`XVmb-Y&⪠ukK.ڕ eoОTGȪEUQTgcj~T@jp`lò|>|@wP3֑|@}Z^{}5/PݼјR|cQ&2hD,W5T4XLLqל98 ,&9EP^)?+%-blǽI9Pw)t +y8Ѓb'񥫬P s םY?cq-FŅ*{WJ5!Hn:Y CzTңr +zE/ז[:jd! +>JـD:-{=9{7{i:`!TZ)8QJ֖X5(8Yok sG +BefxHf-ҴNo ('D-bۮªH B +LNxU9Tă}F{ p}U&ȏ .6k'&PjӍ[aKL8ẓۙQ@ }>|c +@.]%P3e~X9tXd0֢2-L$p1 J؝Ş r1;?/vEHw[g]]&04ؑ V@3p9a&u?#p`:%$+JM!Y@eF_QE@~!: 5XH^F +9C+@rFBs0} JLQxBG̬pb}(q<t*j@?bmarm@=]EX׏ KK.@ȁ/^,؁Dx`l(ΦXzִ긡wFT[`Eq2<;g'=PTxb2蠰JX'x54 4s}e=؛tE_? KQt|*ځȾZ[L|g6H>e#р}?"yR_|Z;{u"{jhZՔz)> TMD;ОU 4hBf~ڵ^^|OԏEPu%Y#L1wPFEK'HP_⚎W&ߎaվSp vI!xpX +&uPW!5c9P!3[jԗ~Ŏ/3=FϿ?̦nXAJFw p*6Q9"]x9=D44Z.jnW0+x-r a[|kn5 +( FRܪ +ƕfjbBWĐGdPCFYSO'ָsJmbtgyQ(~ͰR7˪c=i2dohSu8r8ju;R~?-u375{SuJq+]AlvXQxG[cǪ|4a;zb )jzIi/s{UB+x.7.WQff٦q:1Fd!R%j䅴ə5aAzhDvoi +:qiRU3+:Jw'_Z%`AHX )w#M}PE嵑C9/h=׆"/dKe7 -n{h90mb=EIg2K]a_$])HaGUY>V?rp +\ylcTAtϨ#ÓLZGugn` n +nSO]oK)&3{_J=V3NY"X})I^) PVRғbdczH%%<*C.봌 7)CUJ[~Tb%2a +P^F+<=ppbZW93,^N!)O!ŐW9b2縊3|곀T Zȉ*ʏ7dvʴ(fF7/ӮF +_BUL+c}Cs^LMi^nE˹sQЋb6V@JG .PHNoLƨn[NeJDYǻ7! p p,00gu%{I1dGN;}61E]-ha[,ˆ1̲SN8Sfd`53w5*[)A+ckHS<.\Oj=6ϙ EZ5fՒӖ^%ЂS1cIS-,Ma +&J +<QDCfPxM V&ufWT +|.ht–=ݨe\Z*Vbɋ+^ʕ'fT3QADh#i-x*(DRvu#J&L JYiR Xa(D(JQWm'P2[dH) e(Х$|XebY7K-uQ+6W:gѧ]r=Ӱt$1+I2d"4 +g[ ^iͬ:ttX!hK[~l$Cmm٣NX\RBX+eկ[]»Xrz"hQ_KY-K2E2Df)Dm +,TW4K@ +L5UXK]qu5>~_~\vW7!A}2dJh[Qh=Hl V$OD@OztGfVeչV(F۶fb2 ϲETB,}6-NO_Ta<؞ h?Y'Aiw\5\tLNTh` +Sg TI+6W<3/[kHY&6,:Tۊ}ew;sVTݍ42/~i-MY]8j*#ajtreZ!w?Bck۱)MYsp¥7Zgi[ 5,^<{5*﵍i8eE +o#7vVBe \nSf|j?0O;[2)65kv,|r3dYfC37a~} 7eg+UmVw8TڲɇWn*t.5|;@t[xKP?( ߮aumN s:pv}  GY_oexX +ָ9պ]r4mE4D&\3h.Vsc:dz-Pl-ag8΍-V ԐN&<"OQп?kXj ՖhSݬb]cU :Qѳĩ[ +GnS zpGLXRpfj(6LTU# + i̙MQ-hiǼv!6 G-I Sps\[Yd^@(t%(eq1jCݙfӢFK9!{Z0*@h'UEV R. Ã=TH\hۮovC! 6i 7E +Uνڠ&+9$o+>]4[eS[%x}!6vkeso2?f+j8sopDf.csڽ=OTEc[iHq2)j.88@^KȶaO!Wl( f`(UZWo(%Q1iLdgɴY \%ȊU"0lmIF CZR{7%g_eC-⬏b9#zi5OXVm>>!ہSÔU8l hX|+@(RUI^.yr`HOz^US +?N,EXE[Gs + +垕BwرVًbW6#*W{#(׌"bБ@K  dNr☛,9PbnR#;PyDδ嗊AOLJ3[Ne(jl'J6VC`D88;2{'|;Lv`Mk˶SGy]\nTI5sdtwOoVqCa"'>Q7oD쀨P 6nqG)e~nw7~dDv`ZKvˇiU6k|"g{,U>=Xś&7GJB6/nB-Qׁ*$ zo6o]nD@d僎[QzI1g ʒkIrβqh~&㏭@ؕ!MT ~SM} ro +hB&Qxğ exZWfvUlǼ,r{VTP6@4ݓĆ[ *RE[,,UfKBj\[݂Lr,Kx[0r,E2" +CPU_DQ j&6yf8q&1}ЬnW!SzfJC&hw0 APх"-Zz*tnӘ>]fx?bRBY;^8te +G{߶N}ŭ Ȅp};7{dl[3.qގ+u* İ5%O"tz5b)euӖ8Lۜë،ѱrm!xc2ZGَd%EJHRX{[Mqo*vaeʛvI.L^BgD+AEIEO.l[r*O\./n/+֬KՆ +.IWV:znDh\D}Yvq{qZ֛mT=SQތJXbi]M + +VF*Sm-RȟYQR\_dEDVD."kId:(pgWjmrGSMV,w`7 Gw%YhеK +` ?ȊYQ_-=eYeY\7~U"+@/bT22YQgp9?s|And)$R_ɊV׋(y&+x'+.%ߘ)Y\a`dłXLdŢu'X%\-b;XzTvR2X/b! ("XK/\o`E? (s+5zZ+ VlrOH`V[+6 w3XE+$bVlJ`E)(XQ Vl+z+65\+V`EVDI`ņ (9d`V/bCKV|-o (990q+J`E)؎ Xb(i4?DoX%l`Eɟ V(obUwq-bXXeXVKI`Mb4%2<2XQ߮Vܔ Vg%bUA(9Q:3XXV>7e+.95b'ֈ Vd+VXXXR`+VvbUgZ+~vVI`v3Xa/ VDI`EXӗEפm)UIX`E)W+zXSX|e"VyFK`Eb H V$~Q3 VDN`EVo;XQ?K (.@~[/_`E hs ;uE2Xq) 8 VQ([87gbSu+6qsXq) +gjBVԗ`6X7X9QX (9!%`E} V$ԼBewḾ( g,!'RXqB+H`EI6g+.9 VTXQ VdK`E+b;R2X V$ܚR2Xc^`E#f`Eo"f+b`EVV$X7Xș hV$řzq2Xq) +66X ȍXQ`ELX.VT";VN,'X)[h_` VԊo`JXUUS `ES^`E(ob$$7X Xe6ڪ+i`E). V`EN%ДUVXQ`EXQ Vܔ+V +vb V_ (9dbVv";X? V +V/"r+rV`vi+~V_`ť$XvbU VO+j`ť$XPnŪXUTv1w`%XFtIo"r+J`E)?i_`EVDy%go+;zXq@K$RXqVVT; &B?&"QV\J+.M Vu% VDI`EN}SV+`z]?6e`Eŧ2Xq)Xql+jV L`E~  VDI`EN}XR+ebU2Kb/}? +f Xrx%gb +BobXi+ SH`Z/2Vd+*AH>\DZQ`EVX_+*Q67֟ILTV*K`Ee#XQ% ?ÐLM`ũdXe~5g6.8 V\r5go8X+*_+`Em3XQ V" h];Xq) d+ZVē V7A$;x!b} +r`+JVlWH`EXQwX9n`EVD`E=U xN+6K5v"ћV$D`E;7IEhI q;XDuX`H%q+V4VR>d$";X~'$"j+bm+bIz$<_`E" e+B H`E!`E]`EB9;XVTlXQ V8gXVp+Bzy%g"9V VX"b+$gvF+u|`F Vl 6~n`EV|kx`EˉXMO (5d" HV VdM`E 2XQ VdJ`EM? h(obâr+$"Zd~B+?XQy + (0+" " +5V+N`E$?V ";XQ5Ixeҟ HR+r1 ȟ8 (ҙ V}V+%+%kX*+*5 &XQ{` +f+M`Eºobb+I~#?LXQJ+3Xe+Gr˖D8`JV$2/NL`Eݖ VTXQ Vʩ+VyXQq VgV VJ2Htk++ֳe"B+Jy&]Xu~e3XQ =_+Vm+VawVDN`JuAR+VޱQXoy?X%bX{7XVT1z VTWfWXQzVTh .5eRx?*3XQ7XQ VT;+XQT+VCm`EƱ7XbI`E%?%b8XQXe+*Ȗ ++Ҳ`E-#~uf+j|`EBo VԷ`E7X+ک;XQUR+V-6b+2n'>*+\XQc`Eﺁ&CV$ɹu5dT"5 S3XQ+`E V`Ee"{+Z~X,XQJѪ=%go+JU<_`X`E`"V,A XXU4 XU7Xz6<+JaEg (6)`ENVJm+7oXQ-_wX+/73XQˁ`EkVC~}X+jHiVz*X+j`E hKXsVx`E X`f%b +hrb VDN`EV (9+U;XQb5? HD+jRXQX͆p+~+6/;XQJ+j=X5`EeXQe{o"= چ VTIV$VTb#nQXS`E(e+?H&"VXQr+I`E)oVR&" o`E3X+R֙HXD`E^XVTh+Xr:5PobS23XQEob;/)X1 (%+i`vX+ziM`EG+6/"M;XVT!5e +'%b Vlӝo+2`E HR2XQ" 7 h+"X`EK`f]XQY`EVXqxXީ7X[+jŖ~ +fXfV%+o"iV4V7XV=#[p2XI+ZVl+rj+6X]2X`EE2XV47XރV`EE2~$" Hh XS+b1+J4%"H?- iy3XQG+*8iJ`E}`Ed>i|i9H`E\X_`fX`E a+jtVj+P7$xU*Vl/`E3XQ+jڲe +VUfe"}/jHc+?4_H` V#;X Vlt`EXQ`?3X%XOL`E)(XgL`E ?:#Iz2X]+yyw"; o{X%7XQ=bEo+2XkKI Mv" ü1fǹ 7aK`E_`EVDI`EB\o"!VTF z#XbXqv(, |F0"*َ@⦤2+."HAVdNfYϳHIdE* ъn=ъ,"VĮLB+깲heu;3ZL_hE,:ZUJB+ҷF+"'FhMAi"q7Zъ f"H0QZShE H7f{ x&beSU(˖VA1(|Z%by[ъ]hEOobΌVmh??[i_hEE~=Zq) @+ڟЊٿъ*hE ohEhEb V4yG+RhЊM-oVЊoVDIh|V-MhE]˄VŽVb)BHhŦЊh%$&GTE Z/5td?Њ3ZeG+rЊR2ZQ݆VĊ`G+.!MъThEoYZVVZ94hEhEЊDYZ7Z6ĄV"7eG+.9Њ(%"V 1IhE7Z98 2ZV+7eG+.9ЊmМh/"s H1aъo"= tG+N!hE/&Vъښd)/fB+jCX V_VT#~,ъ +%~MhE eRZqɁVTTF+Z޳XWЊ_n/w>7jVb>R)}*jF]NPRT(Ul63E;Ƴٷ:Q#ړ-: (}s6;4E=弿`Jm-0J<ҋUF@f)Y8N +"i>Gv-VRn19Za +4ce(Z`( + +uPZ@ڵ^O*DɜQ*GMd`L&KKT닖X}Ꞵď| [JvuH BB%.Q +c ^楗A$T< D"nQ7K&Qݚ!V&,b)h*-,ĦᲡd ѡ7_ j&@fjHB|5ATq gA #$YB b~]>לbE {vvb!e bدkQz/bԻ/b2I@zy^_2eY,9 i:`2`7B FhZm8'-(Ee!%p2Q2g"D)eb9Fc" nWc,VL Dɤ,&Q2@T(ŶӁ@G2yZU5LDj2$.A~_C?}q +|Vч8kwagS[{TPyQzrꡊyCqҦCQ j>l +xTOd!qwx$Te +n=vuDC<^ӃssQ q@S['ȡ' (;c`2:h8q:t 8\7j C ypCM䣷 @N! `COOғ0` ID[Ұ(V]h(œiXń4Zk" bҰؓ'dk HÂ' ]7(A4D!I$XwO{P\ӤzNvaPBE4wHÊ\i i:,(b i9Q/|:D4Ծ$jfN4T Sw~v%|ά [1 ! +y@q! iQD*g<֦1yf3 @jz3ySH8éͰh 1 1u2P¨@ЛIcƳ3D)aR aq8 %b0C) auc~\f?`#3RڎaSvd&{^wƫ(,4Cց4vRpfXъ7 EMZM'[vi30%Pd;E} }SK i2xwmzeX9Zn3S|s<} `>YcLјe(+\%'PLO0Z<~e);p2xzyì93ʰe eBHQ8FIֺHHB wv+[4PdD2\r +[wRςؒF]̿ d2[MY3Ȑ-@qjxɞJB â!y2,* MaUl +62ԂwBa!|b3UƧ4+a +~]4q ?[qCB08Mdd>c4JE0ԈGP Uoþ mlBZs '6 n|.= ;l +YB-C|en+-'cR u-ܭf2 5ٞ,d#XH<:'jL.aN5p*O"r¢! +pǟ¢f툰ív^_By/\*&e܋% J`V ^!Gp(m&OȸBF+x +KqL+Dnv-u3A+Y&Z~z +gq +k ϳ؄Li@ł{BzZ|,1S ,sM`Q%,ȸhQh۱tzO`K}d^X¥$,Kh ړ#*rܹh5df? :酓S K6*aQO =*bJ(PyŁrcNb֞/<@q-J#CpP^h>B%WnG|M.gؽ6byKޠh'oPZ<;oP=oPa*s +!AlNؑ +02lf79]V OeY(\J .ygݗ%&U7 7Hw*ۯ'o^Qo7Xz+7Xp˼E['>mIAyȽ,ܠnX~/ w15pRHn/cmP+Չ,Y^6X 4y%hPd&hA T@ٻ +hP›4 A΃ +UA@l03(v <9Vw3X53k#9KXhh/@t+|@`#TA5SJy<_AufA~ޯ ŶI" JƤs8AOR;j8nD hAT2jP2-^k͉5bd˨AHM ԓ_A!xqϬAO d +45+̃aϘMI0 /ŸlP!7y2lP2a ԋ Jaɑa 'lE; D9/ y 6k :5Xƌ,uײX% eؠ m,  !N|kp˴AKZ6ǜ 'AG$wڠT5{,@2i( +e 2< ځ4Ŗq WiB%BAe` * 2iܠ%eܠdJ&ne +~# 7(k9DԒI/Ua Ni_A_8#%U؀;iP%U4(np%YAExd@5GM#t3bP(Aa0¨_P<=c<:tآaǽЂj-O" &XP۾{ +ާM*a +=%, `d +j@V83馮e2j7^Gm_LAXHM`1yYLA6xw2Ssߋ)(d +o`nىDQDؑw=RPM+IE#fDAb;QP"&QPQ>6A,jFԉVHA? 'l [ (c,a(Žp݋&ZҀ >1$&6!lsV} }ߋ#drfCg>LuM.$ '#/FN($xWiޑ | .0Mzh@QWp7nbYKV^t@\Ux$5O/1 u' $ZkzRP1ϰK@Db )'S4!Co/1 @՝[H&o"[Z:F]wRb g);l>SbgBQ@:*$wL GK]ԿW9O2w-3otޟ#=OiLh*!\kϯLx2gaAUfΟC[q?fy5u'_D5)??O՜(ޯ._mU~D/8O6>'ΫMA磴O}Oqu`Ю`?-^tݱ~^ƕ~zS'կȳfNI` Ay"_@K]^>9~(6y_3oWxraǯ5ѓ%JXKq*58~JfQ*?m1~* _ew= G;&OY@f⧮[O M?*PW hn|U0?z nU `W]MW1=I9~8~jY49~(Y?XϲkѤ,Sۭ!~z9!~̲I ??OLuBl\H?dLOj|'OmBG" 㧌5몠am.Nba 6>c ?=L ?TOօ| _칿XUdSU+ۀrڒ SEY SE*?Vt?e __ ?4~کY5~ bŷ#n$]>hMxs|NO M~bP +]| թ| GeoA1:3i_#kբSGdE݇SX1Ӭ}Lv O +ԙݧ=`hxm4l[Ti +I4j;*u#`}ZRx}Lxy`R v0IT1 vJba \ξ}A‘|T;%}KIMf,(;(ċWYzo>}7 r)vv*C*gI"Z9EGO +iuO$ +6ۄ޷?#I}dxߦ2ua鮼} Op>C}>D$>anOzOLiY`8N5SeH<O +@oOT~dJD1Kyij܇}8S+LL4}Dlr^fZ>ՁP"əļmGuXA+Dfr2ACSj谀hBX>G=~3qR +spxnG9]}ĥv8PwPZ>ɼGv +x6gvb@EE4O]^n;O;vݧ]L}ؓO%W,UUgbOBEu{bl:}5ݧid; +}8rπmN[r0b >T>imE!Sh 3/~&{D="^? ~DH?Ek?\eͮmU^O o)d?:O^)D,2]?Ŏ8O1szݧX9=9Gi"iMA n*}ʙЬ>Vc絨}3Oj ں=:MD [?f`U N^,\vx|=`}@J;ZP}J/R{$ (9/Nv`$écUƓ7COMv滽5E OfDE^g4a{'F M! +goG) KZ;-4UԨ\[Mfz +l(yotc;ϻjAaWCy;=.ƭ'l, .Ã%Y}B[zfy7 l8V(՞q7vzk߽(amyיִ-ވT[3~ze/7M`&ǖF +¸Q i`9 +bCMc0m,È\YX* Yh7$H..#Wk6 +ȅ( +DXK=1ZqG&ȳWHƦzihgGG=P58LHdqtjp'k,H)m,tc2gqy=ִw^:/iy +Z +.qЁ>jRQ۽w]x"?/H |i7}/og&{IO{)_3#gq~}v{O~!PX sptwJK?DLjXa5B(iQ/+lI: + Jm#s];4壥!xONR{V>B:Y!g Y§q?(uT5YW>|8iJb='M_,1B^ Q^0.~ʇg}}xënbL9vh'1LPyx(D؆|aǵ!=OD7VȣpA+y}mK '6B͎~3Ǫ>ȆyR/v̯JEϱ@_ Ut s\}! :1Iݗ2 di%d\׉yIza`Y rpf.@2Dt [A^=S\,&L *vPIdb,8k*8׀Z9V0)vDqR*DWz5`-Gi'd$,m'yfZ D7=({Յu/J $%3gŀ'61Buʊz\b8rƢ)h]5mӹEP~pCaωaW>o؄XH_qxzV4F80@rc{ +t^nl}B.#˔PSBXRbd+(%ߒgr c-x4Mp]>OpmN0i,{,@"&`tgR=HcCsNkO'u1X`:+ ))kkY(2Dԛ Lc%c ;Rt>Iy'¤(IRXގ^:(`{ed +$/kiY:{ox M Ix7]뛐aLML^ϳO</}ze,?=?^苟K3YNW_6'Eyyy|qd,!RC1,_OԒXxD.G믘 d(ՖYs' l8v6ЖHB0;/Vui4'hNgݡMr/O$iJ+IG5wy1He]2JTxk4k|rU _]eKEof@% +Fz!ٳ>{+[qdaV УX7v aO: SCD0ݏX| ]Gv8n3A`y#v.{ݺ&uqǜEȐ2idմ]ϥs:wDp>)B23"uRiا>Id`&7! nnq6*NblIG%DeiNg9jg4nw+5 ;)NZJCAEj\&[6ԄE)7_WTp{*lD5Db ǘSě9>:f ́G0/Ztĭ:$*ꌖ8HRz#L"}))"ju~ /pyh'֡둰w]`LYb nL9 + Ǯpr+PuRr=4]"mdՄR;p8Vgb$08 +*׮ Lۿjv܁vV[ q!Ϊ2ru)%(f\z_$5]Ƥz!cK&6L)'1i9\?H>7,"0a)43A Nfb/dž4#Mg _Odś +B0f-4XMJd} PxGDdLy6r10Z5%:ad_2g<|ͱZG99"mNO)p1ixLNk,e8=!= +ù_HMXFF%q7x^ԅ£\|Bt8!]ȣ3E%|nQMp¦>-**Br?I]"f Eui%6/XYW(d.:-2à7J-A ak1ϕ`6\R7cM ]4 ̮ +sA:Z&wnȦ\;4 lv&&?{ rT:ɤ˚MQbV籠#58CmEG=4xDXA=z8 +rApnYmH8{[ݥ~Ks +w]#D;gd:]Wč&&x*/cQT Oe^g3a89A;`ż٩:i>]I6Se d2Ά^qV{jcܙ٤^Dv ++cgx֬瘷Q0_q 媘b4NE\Rؖaw<>' K{9O`Y͌]or}a`*Vn= FA ^ )2 #h c+3Fsk xRǓ +誮j7v~̘109\w"Naڹ8sQr)up? +S3yv$ 68W'ju cu )ڠpcʡ%|\p]bϪ:irm8tC0kcE(*zfzvI@bb?o1խΤ*TJ`P365NB/\YRYX_jnޙ@MffIn{~x8ix/8݁y +<#1|֓-Rk u8pXްƙu +M.M`>75=VXU&MA=hd#0TbC= jB1WI,>UŦ;\(6)8}2B +Q =`Ľ]B0N̶ ʱ!:@KzX4#rdpN !t?gfm[U,S%OC;W;=&0И. >2: 0]3 Vd7b)ۍ:B>x`o.`>&EdTD-VioñwW 4W3դ4.ݞ8[Gv"(;A-b'&#&{_5sSn|V I(. +2F o)%(ςW%Qc0xqrN tdⴿaX~.@ V3&Ml )Z{-fodđvcHuGA*=!'_P4I`(έ QyT P۠)Ep B 2TAbUTٔ"~d<"wR 4z;_fV3@mΦ\} e6NOHM"|p8k(bvs`LXM5u&C>$`rvQ@wiYadaGT[ #A$i?wCh=N#Mkf/G>EA4u %MB0SR_dxvM,C +Q* V+5Z0A2 @T-@$EFa8:LET4uZz~r;PM[ m TZ40,@ +KKj6ƨ79RPta!HJr\D#p_τuI&'! +s;}(m 4qT&rE@``ix֪\C;7L T`%T?-x#1J|׆k\svtֻWh$p"Yq|;U0)Ui'{ L3ø5Z<&FUR jUS< ًr4 ]b,BM*UԪjX\F/"?b:1sG!:;4&^%^v\VG(/V]1( +^ML9&"(!c"O{e.g1 3}&1Kx z& i/1Hx*#IڿÒi{pe)UXʷ}Ft۲x֤;O +-{͏FW.r=:۸TƼ79Mc^ 'ZֳSDvj0ts7׺*ƧidѯLUz)\> Kޡw2=oG%7VA,#D9|y}XXu+QM}چuiDF<:Ƽ,MFĕy ˚m*a'npuJ %X +$~YutQ-F%dۜYYJh: ,0"]LЙLx617U@ʖ014W{c}FIY) y WF oJAٓecsBR5Wye)b`A~EjJ.KfsgA#J򎎜Fbl43> #LQi+Pbg@OsHm}Dr"dIZ|P}eW; r3E`A#Wwa$g!QS%6Ean`Sn0>stream +:XJEM薒ˡcs4ɦu>ˑ)m&׵VD$0Y }܀(}i&~ 9A/i' kG^J͗ N`Acvx/#SF+9-g驤2{" qBI ^L %U~Z/:+`I>Qn_1Gv+HD Ф(RLT"Rq +Y۹VVц2R58bhc%M6('Hgmzh@9EY , -ǹktKf/$vJh Ehh42'h=I$LY#K&mFQ3{ #d&`30Nw/e$i*8 U85 .85EKWm OIe2~88hq4).WqJscҰRE5;hܕi%B,͢  9쯔[m6DS|<-dQs^FU:P(#K SMk涢R3UʢMAټ=KTS,f΢3IS65Y d26l,0܇&!呾"Zʳ"E O!ĢzDzp>]# 9P^Olq47L 0ĸ mq$p k5 *DS,`FMq8$mOvQEb c$7 '-rv²!įu`u$ Bp<:/DeĩUNC晝u7%oxr +RnZ"')r·>RF ,54ɲ"RY>jf p}E3,)|@Lqf91@4DWՒ^b`&#_WHdGZĘSԾ۪oiI*cjΈ MgԜAa Ӗ|F=8Kfr FKX"IN  R*H$?R`S.=O +0Q)( (ٖG},[޽frGJmL571w xWO"wkP4T#wǔNBPk)U<9 %m'\n5N5E'Ba|0%upX9G)f3pg $l˃ɸ7&Aڮ<ӝ0ўśáL#e͊teјj|ԻُZc7+#e x0d˯Z>I8!&hj;8qɈRF. Ӑ+  k'Cij +EhrY*f)1 -.g ܜ +ݔhV4twuc+T.yre2d$=u):3gYʥ xRj +0QPȺף?CW-ɝqUC.w?mNլ_v ,AiCH{t,בS#GTGܐ8PҤrB/S.%vFLt63Vw 90աՊa}0Bef#0Mqdp[˒::ݛBe7x_}xrXK'e:EHQYLNle"!%2$8EV־d{%LAԒYI✚`̓ MJvwҷz,Ո]\;Q)i +E|.%Q$mHL.O6# +wɹBGgue"܇d4/jETKkšZ)pIcuZ2t`?cY +'u6 =כ6րVfjAVuxTN8 nwg֙La~Ԥ3:y[:m(Ѓsn0:TM⸑C)Ӵi*e~Y `TY6 K< S/?Y*Iu&5Z}f!R+`yN/t ֚Lm2,5)%#i5X*uU J/K znC&,,,NB /ٓ\VUr23hoc}̝FNBrfq[hΣrx 9HǟkD`#)ӠI6ȑ +XZcgИ-(e$ @-?ӅenSd+ˇo/gbPعATfy()՜˼2 b&aGƵ-]E`"PեV4Ԥ`bRiH#xYdгqKmL5?*4m@~յՒثxt0$&KȨ" `ŲL,^YDokЮ^pGo%ߖN#t?}$ڐfEYp}ipCHrjWaQGjsoמadz-"-|b[WVP&βIL|I¯ACJ2M8}nGcPU'@4)8hVo7uK@k*mTvjb9-WGL.f+UZA2 Lo#7NpLtT72T@SktV0҉ZPc +-X'e M TDPɴU,ra]H*cf#*oA_( w;JU_\#lhLɣOtTdCb2͟"Q 3GKZ!R9HͣZRff +F9gUXJCUǓ-:RTN:=%]sW üԇ,4W˓Sr2n2_(A2iʾJhFܣOF&lLS_ihG`%6p6F&0m~ IR[_JJV50ul7̒`HElAқy70ol171V/ ԡȁ wU/gT$[-܇(9R0 1ciZK' "jBL~܆_D,XD!nfHV`*,͋%)EEÏ`.7KxF.M36s,-)X2kM7LMl.\eFzK +4wapG o-FIMyV"W7NSl G<Ī`LY%5 G72R!dT-˷I+Ss,{= nf諅rkB<3Ej졃׏+38Ifqi9 4΢Xs7ÞEBhk>*oFh#}+Xgʣ El?@)P3dvGs {8raiAڨ.jF)! ԋjE ^T" GfÎKs8W5r(f`+cт +Vo/꣎bҨxiyM[$nT(X M\VH 9H-4L o4h< Kad-Np^Wuq1k&8 f8t&Q.Ʌ12,B5[x&9C\}/sf3 ƙXeMEU1eZ-"ōɢ/)S22r ۏ-ƍj*TuVϻQB3^ja=P ?j +Ҩ2vj'3*BOř0}p&t Sh>pF_dou'bʑ} f&%Lfˮ wL49,3g(lU)S˼fF,FS<K:]KEF%$GW)cr4ó4(v `/Wf2酩 ѧs[ah`+6ύVG+o?-XS΃R~hK@+S }{{|Ϟ~㛛KEw{:_3/_OC/{g=W> ZFG %ih ڏht0}߃?";jBJ-ݹ0hoC ZΛOO\P_>ځkiټ=G=F={Q# ɬ!W.[LЗ`jIg(R^3Oat +IM3M\OA .KrIs6A:7JK'ig8\>&< }8Y qȺf;ago_Πm _3J-;g0N{3ӛ'oQf{]v]{-]݋nJW{[5I/m"{,DU ^nRkʠ6&KZ2 +JDg!`@̌j$+ڒtZ|I97TO;cuH3үG$܀}C +'Ega + 'v9, !Qa:̺B&(bM)I"f܄Et r69\F@i66>$.6EDY[U8GVV +I|*$W?>9d_,~N?9 ??;G^=9tvrsvuy|Kw}q~Iܧ ^}O}}}ɧgOO/?|)޹|oyyvBhO>ٓOil0MG6,ӳO>Ym}-nzUz+ tߜ^r }ԂyJ^5/?=o_{gOї}?4*{g秗'koO^gPZ{Ӂk/㧧?>7 SKR|v񳓛O7PwkWݜݜD-)?˳MVҚ$E_朕rM3Wν{WϮONz}٧g'볕rKK-e?[g7Wlz/gWOn6_dX\{?{o4ԝM; u>p 54T;c߽:{QPG]ֲ*7vTԝSQw*NE(6 S]e?on?<o?_n~uM>|}|#8On˗M=ۀm^?r%-}ȇjVǗgkxO͢n`B{ώ1MlhkL6bFcj]\_2?=~_ƇMB6;-_ך3|.>ey'fٳPWCκЈ7-uĩt+ڀ =R %_X2·]LySee[Xͧ7Κק(;޼<4kФLLd^OwVOםw?Q?6wm2m9p_R*`{$5n^/<ꋵzzz`|{ }񳧧W$N^n@YV^7e}.cX7ŷn Wzo}C 1UqgUbYwVŝUqgU|p}јE{˷H=}x'Wo}~vu~z铷/_ذ9޻v;xIɾ}!jYqf6+l+GU79V8n!Zv47ye l= VlGosOOop}OlmtPX)Xæ_]=?og'g7_;Dr>yPsXmxnO|6<׶/#_#O8|̄5 ¤_|IX_O%}M-jW[a~.afnػk{$Nu^2N.Z䵨׵y׵j_r];m|+mmr[4ٕ{.B+SKw~jޕ{r+E⏎?< w{Sa.]ns_Kz%^LD<˳MV=3uof4[==Y{Bma!Jo?}ycPRϯY>l*%ףзnzT__ޖ9~ηe}^rxlͅM9 ByQD|6Hb~'n{,e@>>1=ӿ9h&n[ߟ»ۅ/ +=^<<{nğ0AbHBgJ˧oBގ%SmuӠvFc#|HGo?zh5Qz'NL1v{]﷿{?~;[=o;,[O>].8~%_קWRHHx$RߧM^~vz| |W_㓓gΏ7P޹EКy&>OxR''\m޸?Q/^m ^ߚϿ8r}|$iz3N^뫋 X?}_"b}~A'g7g/ rq_k@ޞ&./f./.6akߜ5$2n"-oN+8j\V[ٝ7oo|0Ͳz}޻ûz꭯K=N}ϷKʮF7n>~rl߀=Zrk ޹ӫO3 eG$u}ĎHH>B"ڈٓMuK6Zڧ۠=hIgc@D_oH"ď?8>?}A#Dv^~e,/ܠӳ돏ON{yU-(ԷtXZl+or7^%s|ӛ[4gG-1xɢ 6Z߭wAWg7GϾ=G*l)k k}5~@-UE ]5W|?g%w0bƶ]OO䡱a@*=c5ju]Yo޼e]+l~.Baˈ]΃OB +v __hCujC;ou'S0O|G1%h%mGnٰ|:i;=:+ڙov曝fu0 +<ڙovGdq|Ҷ|<1?>}Fx+l:fn N50>uo{.׷:~q}JQFf[>ZURvNW} ۧ/?v]c߽:{VP[]?f׹SVw%0;euGǫ>/,~Y_?oHotTH' +lg'Afּ:>קBߔhzhD%|(Z7(}(@.?ZR֑ m}&Yù m @2R6ڷe~e-p ~ #sGךmKp8K^_^wz~z9jZFjW߼g^^޼s6cn}6nn_q6m#-C5H&Ж\ :Nos%[G46̷yDҏOOn}sga_^]㓓g^/o}-2D;7)ע.O/xr|~foܛ}t& R7\_=@9qEeɓ7Zb|6wy-kv{U/.6a&xP?:ԏ/rF.m-" m x̑KMiDec6[G"v.m{bNoK.bvKإ_إMpҶLx$KЖ\#v.m-#߀ mC69͉}hƸIxu26v1A ˟x=oenag60nYuoャdqTzūvkƲwbGwqGm݇?|2h$2@{usW1˛o}y9M?_yt{o7x~ ձ/觿!{ikM/|cko堶R.tGTC T]=Co=y<b!1va{8%װ_A(6jٔzj{м@Ϗ&ߒzg\v>Y5дAJ>y~,|n^:{֞{l=Z~/~TS zܷ7݁_L@Ca4SK4Zyy~>SR+>ͱ5zU;]oZhiP>ȱ;<Oo\p4Tv6W<- -{@e9E \igJ 4mQwOV:|x08`YTT>m1o~$b7h!a2 +ŕ/%3ɥ̖eZƒX t&܄rDHst@$B@Oc qZE+DFB Gbo* +jBˢ!"6p$ A +Z;`@J#+J|);:v OD[ +}OpYF +Ɂ,{NQ&. A6D+i~0_¼I*rfN9e#"Eo&pNi>h#i{o5@:8_^9 +l8,ȸD5v b$ﱱE,N=iA._<oD' +K S{랝C[\h6V H v2SjIr¡*aB@ Z\m'1kfVL9&xfdpХ Ő]:JGڈBZKt["ݍ{y> OKX Io%i$so,0y*60j&$G.}GDnCO8 zl]t@#`/ +͜&̚kI0[ZӽAV;/3;RCX yφfôٱW `sH!lEAfs8@%)A|щ +x"&R!x:vM:T܅W!&+_INqI`>8o~|>$bl9]xA$fGavμ5H2l>ɴlj0mkakj$l̾h"U|΋`B6'=~~,)|S +*TB#CaQ𻳈]YB@gC +~d} $D,(`U`7Y5UBˬ|9hNtW$"~ɩ"vb7qc49u椊1iؾ:T`_` 5vpݙE\Oy=B ~MVm"߄: mW<Ϡȃt!z*:'*b,g"{D8 J (xAy2d*bYFU] )}}Ъ̧KtC_A6gLq6Ql)"0֞.*P,zdew^+/!/#6/v|9}*Cr7w;^AH,M0QAPqblg#}Y{5[RX`Ȃ +MUˡ^,tYN罪@H RԮcKp1\-̂NLT~#kR騳HE¶vy '-D +> +FއptK=HySS-$2[RD@bclϮF=DD/ JSkBe{n,%b?.Jf2|͔Cx'AGB,"hsBӆ{hbPz l6NBjAL|BmxLuboh +[UJx(Qh)X&4TcbѪ"*Aѩ U: J#,ië3'}y N D+IRtH,1xD!U &2Ce"(tqb.p.]hfS(f3fp*dnC Z[.&{4%PCͱ N$&^G@ӤQA0,pقY$ᬍ|\: aJ*TرYFI'xݬ`9Uc*Uwl̝QJ7 o^ۧ[ LjLDHylw bLc3bdN&g4 ,AUJL$l0Sybiѳ9"oer!4F (58$b΁a"c!X8b,E#Lc̏ +2K?07.aXp^{T#m_!u!peIĖ9݃ +[)8#gl[fQbt@캇0i .V32\`_*hDJ aIyGa +L?2ݲ5Ih@`LW +03gF R^xW-¥YD{u`OU@-bGM>mY,)Мk) Bt0Py X2T&Rk_XT4*N"eR YJ Do@f^S +̍q(Dyx7 S8}a < rSP5@]qUX 3J;]aNa/^!['Y60(7K.]X; $Ybj&#Q9SID$GPX]1| ,v"q.j]">,#h_ Dne2~:$yP"-6F&IoF +p/<͟~'3_]pbVKzъ:3e4qhu yNB @?05`Ad B!_٣>4фfl^ Jژ6$ YDTLQ4+u2LP +ZUt62D?IDV!B@<[H4-{3@FxDB/19HUa#fXhτ$ +Y`obyL< +Dft%/=MEqYL[C6Yy7oB22ExbV zBIb31ۂP h0E~ȷ!nhE +*ߛ +JM"Z9,X,;T?"K$5%~^ئ`ENLZ)gVx$ S /McmT1 T"0Cu5ˊ<43'Ě>R0aU 8(BW O mw>7YiX:N.>zvdǟ]\i|Xyw_8y_ӓ G{ONDI\'rG9/Nϥ&^ϏonN/{g']~'OKϮo~i$쉦|ü:/N?9{zs"f ܛ"5^r翹ߕy; ЈjP 8a2b;/ub?xr 7or8H;<_Ax8{6#p\,!UA(,]p,)]$J+'$2(Bq^=X+  g;{hD ~܂|9MjQ+QJh6*pV9m5(Y鬼xx=dQ(Cl} ;W=r؈{+KPHALJ< +PHxC 6C줆1 +T<9< += b@ ɒ+ @*6Ḩ!G"_NX@R 7Kcmo@ dDBeIr4 \ܕuSnChKCH-XAAiYY,({x"|b} +q 7>#E.؅]t#p&1Ubr?tVV XcW>)@!8Uw=", rB:Fp糁  +7\kɝU61)[*5z2g KTFQOI$q'[YaK +1:WB]f;.HNpC cD1ji"YP`@҉&F>l~*p '#IxBfr읙xzNrHi[R\š4qJp +Jn>ۢwD|^3p?3fDѫۏjC`7OS Q %Wg?.OSg)>Ȗ4WSYNÌ*:dLݵs:5"VSwLYAFbW8 (:>Ț <;( p=T xrFԑ$ +[H- )\cK{PX8]"u,> ]9tϛDQ4@ճ:č+HB4'>fZmAJe/-6y <* 2@]z%w1AWB2Y}U2ۢ&*; . 8CL*cYC$1d @=x5[(ˇ?~qsVtOětGP]@[̬wt߆b]T$Hj:pVF]3jT̅9L[66J6hς}+kbUˁsaA blvif Wԁ +W v.'a`Q +m u쾯H/?+i5&҄#|JyIo䠱:|ra.J,&Ekge,9 {fKn'/PB΅dO]`Iw }%7!;t!W8Xr,b!:ƂJ<;Z5ځEo֗4f  r0K_yWJT]-;*qC$nŬg +}i:֯46fr39Fpi?~!M6;FpF$;,keKs"WбBlV%-h0̬߂vvg6QB^f>q4#pPhAm $e,`7=0ߞzE$Q "hc[JIL ̠dM2 ElZ9GC#Rpk8)7, +wggb (NX2Z%s1۹„iPh"B22Q2ﲅ޵b10-nH8,e?V0?l ȘO\ jКV6@;;@EUfo6cRU=!a:@<(S\.e/dժ;3*ӱj\/ bECуSsd\[ +{+3e{ ā@pJ1qF9C>Ļ[gVn'M3o//Y,vCECd]As![= wqm,65l=kj!9ufCZW u^d*,BK+ +qĎ#^EosXn qeL8jmmŧ`ۂa/q󢫉1MbP`s&]Hhh:rƓw(43JC=!}!@-W\g(ΖTM_YSݥ0QrZѢ PȲir6q}-;1]hh%8).-aǎ]}I$gODsOTV+_T?缦 +x9xMbWV,%٧BAW,nDKVʫ%YdCl䕹\` (+fepNz3%Ű$uk +CP +!eIdN29V];/.c?g뚓⎾JH^^0xI+<\a n<}{`?~x?HO^RS)׍l]RjQVWF="^`rQ@A/#S | %XAYd:L6 H+fZY87huWR1$+5TgPŶDh͊REA\Czr3N>" 5D-NU4ܬ.򊲙M}R԰=WeT[,\B5J2!ĦY$`3Rt +6Tc֑;n /gy?W|dNķa)3Pv3DC +A^~9@sq.QZD+66%'P++q\}LRRÁx+HG1QYك>(PŇE({xb쒐PIK4ԱZrwDĨ,gOiaTssJQ,3"!ښRr%KgLW"?Zo r a$&w|ۼxւslXŖN"-'NsxwrX\ X XYX +3xZ kiD\P$ιεXC!>atf}xFra$ +c;>mYwQl~ +8ЊhիxƤvKs4۴`^zfəYu ?.-EݒɻI-F햐1ôcz4գ.H(Yg!i$rOzmtdEp!URDN/= W,IՁbӪjM΂ _P p3氁kC 0*8<|v/*A 9X9bXgwЮW׃Uz+{Qݭ6pKTt|?@AAޠA;V<]{b%fN"#-U!󹁱/fa9H6ɧTVSrGzΠ=AKnÕ#"'|*2UWq6*PC#1i,YkФP.zϠ+fVJ0)<1*=@,`V̻l.!@0aEٰ J;F䭸^g̚gͳNMYV8W5^ǭnQ#\UxU,yp :#AiD>5[H$I)&YIEᆒHt6 !:6}/t(3Nbd2HNmPlX Yz}[π&FhJ"0Eq(kÖBS0.?~maǍl47Q; +o(( ָ, %˨>Z y%AawV Rptϰ9\`0Yaj']OQ;!<4 K-%T)*@l4 baotBŎRJ +jZM4#P +,ϐm%N4}|2( 8 DipIs(k9`եбxT2 +٫䒧!J +B2^sux%Sk:ep#r$ $_\[ +8lq*)y7֝@@t'EJKFu +"\n +C95/E £ zn@Rn#j@\sa5fbj j:KMiTq%#qUTZNm@R[Kav@(PP %loDF|`X8>v a;!l0O;FyBQ{6mڣB'/" ]2Ll<~O#1|6Kfʽ* owW)ر0/XyL +HN@aBz˔i1lBQ5p-(0m~vzR7]Bɪ\+aY9f A\S .tJ)%E2W擀ۙ/ +0._^`Lh&Ipd@3%2캤,k.!6c6ևG,ESו@PBTI2I0$S*;L ՔK̔WZ3A"f}9 DF9Jm0'vPkeܹ/3XPHЎø 4J)2:* +{㘏4˨F4>d2f+$?YyF&az%R$p.vK#e`\PQ8 +2C/MVpPZX:ctnLrMKnJO^0Ӡ(EjHF)ɩVn$"wxLry<ʥ ]PZ +~C!h= ?)]6d G@%zfb\$>6AMYP &8%YS%HUMb\D󒀑jP6.| c&jDM0HAu`1M1x9H)5@!G O07B*@B~(L5 b(ƊeշQ8CDK*b@Q 6m7 $ ( /,B fBsN)H30[F `ysoOL + zhuǪ*- S7}Ct3H "#'𜱘=JrGj/@$a]6†QM/ <ƺl݀9RFHզBpREW]!1f1찉~5B4`dzceGK`cʥÌIH190}"\ 0i$qI^XYR1%e;zvOhx MWrL}ƥS|Ȱ6E%i +yIBKH1`ɇsNBv7 " /lҴFȀZu^M&yjRTQbSrQ?*b:Of+eeP}o\r~|L`A=hH޷$D?%p.-:gMv'߷b0 Z\1S,ٽᛝK"@%vbJ!%ȀGoz)ȰHʁK8gPJd9X(d +)rB5d̄9q׺(Q{#Qp1[@!(SIT|8 R3S)&9enHD`ė\|D .Ё : P\SFJJfC#Ii5áN@SKjL؛!ˉBY)'ۥD +EU lkJ nM,MPaB^fy.9&+8)JP- A5iGTA*xj(;"#./b̥2 EAov&N驴$[`|)\bxH.] "`^D &MFmaF䊰#, +%)&8Wf!1/ /!0^*U~'tc^! ,%}a Ƒ`wJmeb@Pr~ #@b`+1Eɩt|^($Vx$Ff۴p5B)%lHNhI{,,?2#$K:%8Sc0W0f iGp[ TD."pJqRj! u!Gu8,t<$B?)[un2I Hz^HҾ`@@K& TMVM> :s}L@dh'HIɎ!$VG;e + $8Ј:&47RR5ݻBWƛ’BR3bJՊ$@6= JɅ~OF@sP@B(ɓFSAk3 99ôd1dp$ir:* +ǡR'k 94'ۀ&'SiM0AKeC@ijXxDP#G[n:CEY|m2 6؉o^}ޟm}_}l@?z_?@ /j~ﻆ|o5;<8YrZԃ*]b4rOİwN̿msЮJ!:[U-SLˁoU}ÓxN~$_D)-odIg}=ܟ-N@g5ϑ` bvAaDy >4en0GEٹŎS?VL-5#\DiES 8`Qs=SD[ݕ +A09'm~hH͐ފqʜ`x +,`F߈نI=zɣKoA0,ɚ {)%p:%Ti9slz6Ͼ:ʼj!^u~9P ~e +T%ZE ',yTj"~W6Y)_(j +L,YRq@D?2%\Ѩ$I# Op'$چX`{XLx w$:8G09T! %ҥw(8*{*APrAPkmOf=&Bƣo@P8et("$- %b߸횰wy´j[dY*TF ĺ$}*3cP.Zr~Ky*%i +̋M]3IjDPt^{L +O9!e bEAТHhm _% 1i"tG8l  IwA9$f7YҎd&"[\&TɻڴwlpD2.OEqA r)†3Fcz\e1P6jN͏![jEso)QGrḁ1%lkOAebz +nPvCҰ#ht)E[DmJdJJЙhtEZޔ, ?j3/ DπKepoC؊-hHPB5ĸ' +馔SD$yj3C" ?<yjgt}N 8HʔQMg%hږ`ז.=s@i]JAj9Dl*_nI#4͂XgHonOҬ)FIД= !;hB&a2 mN=e'@Bp3hY: i9E%sqF<:?TDpZ93m +uEmf2OhlA%X"6:}!G  $O\޳ĝg#/B Q̢Jh\J=PRmI xRq$-Cz+eevh5dY0&bO0EBY=TtPpV%!#>C-U1H\Z,,UV*N[#@~ʃ+r{*7Ly4Ơ\]WӁ4NtKBD[;y +bUS/]Eȯ[ta&FhH(u(U9 3_ܸoRoW7z>0li|Ӫ(x$xaxR|+?'Y?(̰L(pщEqȚ(A,}Rm a.A,mY{-9_>w|sz3H<sIG/w1+?XAY |*mohYEkyx~A,f YС +PdTV,k @"OmovGfbgEEϳ*,W*X +;ĪU( %*,GyBd~Z7^Ptz(h@sI/S!!#0=0y jW7v (M1y)%bG%ߔr K):>n=DwxIUQ=Fb%A6e$ģv`Rvʊ +1"Pu(*֢>)Kd42I]@dBP3ٍ=7UV(GJ +6 - JFZ4r0d7Jshf7dJ0$C?mX0$CyhBC??Z|F\N2ARߜlS6Jx +F ț  UF;Hn#2@%ňabg%Rۉ8ZqҲ(/ҙBPݧ ]+$0Y @٤ AeO&=$E5 ޤg&=غ.ql>,OYVf֢X=Hu(ЬEOaseV1A~=ikѳ آ +TJTglDjrRb6mfTQLiɻ@ qب@Eh ֨*MF,Bخ 6iRZ8˸rg!\IH\8e7MzS3q 6Ig~{C>lS{  Ґbtrr{-zʞw,z +ڕ4AE/Zj*H=.B"UrrnTT΢})jV)@3SJe,@)[0|JPYh w5Z34۰jBO[0*WY^ +LzZZf*IO3WS&̩kpMulzQ:h0q&EJP%&)]je6=xቈ3D O$ZDPrr]ԓ +h03ѷ)zhBeU>Ϧ%&ɸdڞOdVu|Iic) EjV$CX(Y )֏r7 +P[(tjiщ<|YelRtUXo@I6@,Okȫ%!@Yo-O,n[ZMO#K*]_ RD8%z*ҬɁ"㓇ZfӝQQvUJ6a7> O@v0ز){ " .e֧J ;˸~mF"zcAa/!8\7ZϏpr:KӢ/msFPǮaζ'Pk=Α#jO!(/H$6B,DxY{ ;vׄ\EKXos\gD ^zVNڬB"ZcxX̿19TGmJ"H^0yLNgDQq{_(/4¾b%o6~:me_+>wG0 -wż剨29A%!"%V=Hb'@%"À @^ PvWA:ؕsw;݊ӿX= {:g|lƥ4 9Pަyȁ ,@>2dK +yW3kRL9ԥR0L,ǶS*}a 4sB\wy|.M^8C҃,5@?4FJѮy@]8CG r8 /Kt[9+֑@1>@M#CLK2.# j9PE {̌=G݂Rr kMPoQ:XE&wΧRLڬjqFrs̍*Т#;#&Cp DIчRYEf񠺉`*ҥpYAŢ.UJEgɏ]t {(@L5EסI3UPt ^ļ=6߿N!?c!;oXX=3Bp >S@6;<*s?uZjpu@ e (()--q 9j9AoX.]SRΏ**O󠡗y U]h6O;e_`q(v'vPwz劜),8#$]^rmķQi%#2@)P ELW/WEߐ(2ҁ'S CLps6d21T3~k" 4u(U8 =)%(AzxߚЋ"(h񑤬o ΪN= Ǫte .攈x}o"(G#uƂ +xP23\p$.CzQ[[GΕZA/2}Ę$b >4KJƁSL<X=x]!Luf958`z$oWZ%B` "HQ 5hDg0#^0} t k$^Mi.9 ;Rqݑ#uuGq;RW]wH=u'nŮ;Rsݑ#uuGq;RW]wW~0#}4ȑ#8k;RW]w$>]wH]sݑzN0-ӈH]sݑ#8k;R\w#uuG\w#uuGq;R\wH5uGTUƹHUsݑcANκHUsݑQ8>HUsݑ#8p#B,S5ƸHUsݑcANԐ\wBk2#UuGT\wHUsݑtrݑo7Gq;R\wH5uGLk;25$ST5םxuGT5ƹH]uݑ#8k;R\w#uuG\wH]sݑpX3 8̀Nyv奪iPb˪f@L QoÙT4h=c̀Ś 5!@u6$Ӷ4F3w+譢j3$I3`Af{ bQZX3Phi, ǭ@}\M3 uM34 @/ U5Ԯl@ JipX3Sip-fWk @V3 gg5 [̀=X36%n˼2:s/.5ѢIƃX3GkXkCvjEX\*W5VF)V5]!V LWzf\q Z X` +Ir52WSFScBna^A t1"Hfxd> )倦"en:p7 Hr,SR*Ȕ )z F ɡ{ccv"!)w<;/׃r *>V9*@ďmCA o2'e,*4'i-:U$Zi^CX#Ҏ)4r 8%Nt +!4;sc8{_QI%Qa*9$v +]=e㒷A6̖e?gµI~|:9 Q69,B7!-5O2&^%* Nd:KX4HPNߧ \$4(\&.ހy0%5.΂ރ_:R)SJa7*r&rȥCK%B./dR),!.'NqBƪQ*ƃgQID%}prdTN;(HQ_SI""h(=dsL EVκ[i +˧E{CiaD5uc[qG|mU)H%U(&+EĠc|Bؙid=!s|͜E1S)Q0y<0X9'tȟC-Oh<le20[-Jk4gv1f4(\zY0ME{Kp=H oNHb\_t1igGE\E^8Ƚ=rPEfr/,$^r +*#PShw<;>h%IpegfOW1E9'<֨;YOBϹ<zQ(bbk<)-d\>4]pWjS4WЋB0æAF$ed9n5Rς bArKF0OV',ڦADړPΔ܇MLh3~{0s&N<`Ek7Znm֥L9Ġ_f6%@UbČCT)* &9YE'`{- QRڜͤ9&_INX%pBϲ{QF3Վ ;ZRNr^OO;$^K,FMhog +SBz!1.`_4g6>o7Vдp +6@yD*AUO4d-һoN2~8|eCV=bo0WUfB'n?I͒nO]$>)M2A4j#(̘dȨ_#c|@jj{ *hOU/ɶŸ:A5j#U#Iψ/I +QbՒFGء›Ai:p8-BC2FZ#.DB12FW7?9e8,\mp| 7)>LBĈq&F(.H1<|uru(B,꧈/-cL38㰿1x[E:#9~F1uE4sXNjɪ{SE1\g8UE:fF[TE:NF8%rpQe~~# +zw4=;-tۣ~81=7'f[ 7;[b<|yq2'ŬLu_0bHhwƊa*A$0D$ʜl4 XR42J?aSHP)?/؁z"Vi TbESCsPLpF1$*KdU 2:ѰNrebÿɐ,2 + {iHPgE;b!ٳ`xG"= +s+>/ V,,&g 6Ԫf5^IlAA)1DcFMaz!W UYg_K-0昏3 J='w<*0 Ie 1S#9CyJ% 4"mn. X_Od6t{6?([w~we>V.>2j]`)*ܸ3 ';1$3sA0X,UJjYb]LFd7`"k21N<v|psD(DZ? Qxj(Wygo +Jo'H^Ncnqo= 7ɣؠηzy_ttͬr Kx M ]=jNaO6jO 7`?r4% L;;hGh3^o&?\}OƍT,kscW W&IlAh7)jee}W%ue>I fۢ7`̄N6| ͈oK$In?D4*Ȭ+`=|w|(NN5q `Catn%/kz7DSrܔtj'2ּhGIpA޷_aO| kk8{p#2oLnx?𿭓ƠjW'PiZ23EAd,s@ۃ'eVN綋;:U 7s|/{ÛO_>oz2s:9g cY}z~=o,u{fVߠ&&49 \NNVGgdm7vɾ6\qcz5ju4<λ*(TV< r?m: 'ןsDkaopײzΏ?@VR*K.^q +8?#|'Vd?X<62aA/Bp0`ߝ)ޏS{XtM`*}v{Y׆`u(6[' ~7#A0$ pHƟ3-x"*'䑝fn >2l ?X005fG*;5)JuRD_Q$o ,g"<t@o)(W0w, t*'BRix4{=&?t,}c /JQjʖ" ZD(*s-aޒ~o~o~vߒ[rj~@/ߟ_ +Gai +⓴!V/ZBZݟӣRrqb}@?>H! 5 uP랄Ӎvgwj=#oxrԦM4 +}X|XrXM_J/ۧE\2V dϰ6FhB;Ϣ)UŞ +|9C5,4/ w/OnAEGÕU=+݈@3mVAM:|,_[S^64鵸^ RrP M #^Dӵ'?_]UgcqW^3$' qPeـgcI̖3f_3HƱ8x5rx YPZ@^@+E.I)P/N?Ri^SWD3yNMyaiA4u2WKsfKa/]_j6l>U^oYNϼbyV66K!hygؒrYx޿};`g$1]ol=#NWL4tN?3/(u$t,qeYgPb$+"S5 RW;W:HKN,!g2\}_Ecz4kP-L.2" D)`n/ȶʬrhY8^nePoͿct顓&E,&ٷWB’L `nxt) wEODdIrm'aSb5ЍS|4Y*q$,fڔ^]yst{4QDUwtJ8#7uZ,N$D簯)bx(6#@O }㙦H('N2hYٙ.hsG2"=Ңti#q RdH܁}MJJOIۘp}ۅؕ[L" |{~ۦRܴ\gE YvPo`*6!dJl* a D/3 ib`TR^v dvliR N%ֵjLKjp. kЂ27(@y>ڻjcȋIH^Ne}NG[(UY76%ETZhR 17]hr̵G-W<:M {JpO@kr~@y[ +roSF}1y5OLRKQt՚DiLqbt|8,K!›]2mY4=)5 a_c-u h{+!3r(!',,S~`MBV^&sdc2!jgX2`L 8}(~0~$cUB/VGňF*}E&tKyay &ʎ<_Y+W{8MXybyznYr#R f˰(@='R9;2$#\ +$zk@ԘTh"iZ"Ϥ$P940H. +`c=D1f7,iJ7Z):6$> vO=PF4ψ+]dcz^[Ioa841y}$ڠiNUo H50"$:Mt$c!jd#PU)YDGVa TR$~1,Y$-Eq\rUMʿF FhX}Ajs#6iz\wF`AA3gI]%lR8*W_@ҁ1z0sisínrjMhku¬[<1:I>f#['kyoFɅA{w-F-nT +=`]G x3n,w[;.EJdu:˝ѝVo7۳N//?0_lTk4vwGpv?L7/h]I1M9a '<59- ~l;a瀆`v<Vwfb2[j}ܓ +l"zޠ1"m#1Yw[D7c3MNh +gvZPlCh&ެBWk>?+?J:d\E3M̲.$\ܹ+A>zeO:O&.+6FưkDXX,B ui~1mzEV55 ~9ђ|X a3د/aWb[Qk0Y/`2̱ ִLdAcoLya8׼a1ZEޠna6= f4fwGƭΨ3#AX h<Qs;j<BҸݝA54iZvgn횦fK*`v_K3lw4yWа5ZÍY.QK%5;#BLC'gZ"Ñm9AdiVQ8Y38ʕag3X|1j,ntGn;TQ}@hgn\ {U)+z7؀Fhe^ ,ȸCD:XoZ~u ]].<6'|s<` wfᕅm5P Е ++S8-rNF|jy xX9ۡC?^ lElH?!,T<6eL,8| +ÀF5̫@f@wRNwG[ i/xM2Xon7j`VJvvBnhpSpYZT9,,˲JA`ǯ֯7r̀id֗cr0zr>wG[-  o?z\;lrj ڏ[cNǐc`R\ไ|z͍fk7Bpw~wA }NƖs?7&@qH=vix{mQ-hȴnFu}uQ2Oj= PRo,}'.4O GO[}*C:`͑Sh#hFg?N0B>%<4lݛްc}@t؂{>7!$Jh|lM< ͐897GEndVm@\oG6숕{]oԦȈ +U뵶'nx-AJ;xC1HLD탫2G yLS|R\!SG5jGkرځcwv59Hc%x&h=\n<<#_˨ÙYQsw=FAPbvv-Mǝ֎Yn]EQiCi;[5U܁ ͫ?h>4y2Q݂Vf~~?Wi{ nJ.޸fÚqM853ֹҐG4u&[ +ဖa[vbcK8ϥԯxb loEԈ54xQVh5H9q7|#DC2gmPU@kW_tz+!$ o5>MooYPC +}C +MCuKJ4)y0lт=Xm}ֹnDv3[Q11k \v6g !/Q7KV+ K{GM׆Z +h8&moF=Tf.vFw;wϝ ax Gu1@{_ǧ; @WBQG3Bbe0LcW940ĆDƟfĝG1kSt_ٚ/$S_ `BLeeq3vX=vV -_0[+|-|C- @p4{ƕofpG7~Ѵgj$\5ndQL=n%!Fxz_ ou_ti̅ʛ*yئ+Fra [ +ՑNkS53jsԚMB>%`\{btw$7| &[?DkOZL4.F'[Vg~0\ACxOF?o'dM^M8 ]Q=)TT\~ژf\ !.v.q 1ӹZ&V.?XY}L$vaQ4ϳrCW +SQu'qm{z,_Cp|Ӹq ~Q&E \0w φWO81V'59&`fzk3|>9Z!> X:T1lnus]]r .xswϿ{uSs3K[OtƦkcs( s޽3sOFOE#˟Μ]Lzg O|peʛsS'oϮN$6v0''N'swNͽS3^wcOζۭSZ$ӭ|}3ݏn_|wjx;NΜ$5dg<:u|nOlql/\ݹcv.M39dqӝ^Ek`s..5^r?;v!|tܝgq {Xgw}ت sOOfSw6ֹw<a/ uE/.,]FO/~LS., ?wv?t36ݘvjC?q-hQo-<6 E}}Ҟ][O[wߞou|_gWOݛ7µk-W\~դ u_Գ{̝|? V۳Ťt1S+k۟,_?Y[f/d)?jQoKY!U6.MG8}b>ܞ5Ø]_YDiZnN1^ t#&fhpE%7k0*,&#wLB%3{?}z۹ vi!fYЏC/pf$.Gu?>߮&*;pqpW%v闎k10 -a!vdgN]θas%, +:k5|W+P˯f =^Wˮ&Np"t,e ⷙQ`)䋸fs͍MM{ -8h`28sQ0eQd)Xw&{;Lg<>^a<91tcgAHNhI46y9aàob!=*daԘ?~+ +T<4')0(g6_3,ʋ6vZ"^:~}" ݛ-=7s6Yy{S;gy@x`6E1x,$ +dIQ\aQO'apZfӧo_E%^)h$_:]T=ޞ]]Z<<}"k 4S߶RЭ^`_t܊c1R30Z(?۾} %Wo-\>fWfݽ!vnt̢.gsxtNs'thI6}vscÉ'̞\g~kcܫޞG2L* +}9f2QA{Nqaɋ4džSOw/?e BU\撗ߣ[G`FMc4 @fxV.xi%U#-v͛%mZхrӓhW*;76oBm^E(]kX;O +/}cKݏr@8wE^:wseƬ惭Y/ٛYZ8aq~Ntw}%YeD~o9uңG66=~!+%GsO7 +#9KyÃ5524QS>#3g}x ^K9?3,9?+;xOvv˛ã;h[Ϝn3I{'k[CpnL/Yz0]r|){K̓p5}Wk,wUg_c$6cor0ɏ/\]ZS>x^CdDrp=[zuwykcji3w?ݼx̽Ao$ҡ\'ysb[ ?<پ Fvl µo)wzk⣤pasmas^靬pQ\}|[wfזg2ʷ6s'fSʭg<86HY^zttuTy-s̏߄MbG;[o?nwN3̜tSK';p-Vg gn|0svqSl7&to>ZH]dOgZbW+y̙7{ALljƖ{Y>{km +0v̜Y:.f.Ϳ?-uo̩rT;i^҉F;uAkkon.<>PgOWm3Ļ[\p;6Ċw^]zt"O=X #͂zOz(s=Dޑ;ZM`fUVVVZqׄOӘ+hx^Zx\fӚ%%Nţ>FTp^xhu{kKc[ipGGRF럥qQۂ0«H m~pEl?b z2Mx ~w-$n@Wdj6|yY>ƒfV|s̗k~yd1-7/'g^B156?Hys[-TOAI_)n'VjݚJ/ZSmA +KuhW{%~+F@A +V["U(`9U~0vnKDf {X>&6@ hE?eȮޯ~IJTvrXFXnJF5UPh2ꮫQ_&ڌ"h#4y#IzWQ!L(/K ?Xzh&v% 1@0>7u>*iuahlYK4zI=݇6=Y8 `(L)&lyC.&e2Z\@5rhE!T;k1aEW7 +y0[T"9 ̈_}5)Ij[е8:3Kߜ(vA4WӅeƴyđ?{}';m1)`sLwԖT" +{R$rC +Fxt,,;Y#)ye3jQ 2^=gVMٚ +g?ԖYWNO\CN.=.71g 41CSUc059h%X0e eDzKz҇#̌^v҉U"P[ٟ[ IvoZ)-@dR ~UFC =O6ҩf%+*EtRY$ZY}vh% ߕro-1OV ӷ}PEMB84Su)x\MM'iZ\1SSE[@ [h clX:@O9ƒ[UŜƔ=9%m23kFkW,o tL($-~N.8\bY eveIIA \ nM]j& t0]kW GUW2-۴X՚%>뇷tvQtHO +)-9DߌyK>ٶhgX&9蓳j)g!j$7W88JaHuXʉwWY(&";]q1OkSx\&`A5DάvrQ52VMVꏠ9h=EqXs`ۭ0#.Ri@!͘/ 倌#34 7*s`<5ҥ [6ʆ0}/] kG&1k7h7߾#؇>i6v \cCG`/UhNݪ%zTIeT;txOʞ!BB;uaK*kŸ8 >E}E)'Vl_ _XnS\Jes1 K\luC!*a/gDEu0l1#SwNzZÌ* 3TYHeh02f A_!8X*cE >;#ף,_kk~ћT-`PA >+40z[S>YJI4+H*|.P; Z?L3F~M+=/˹f /87_U8GlT!lbvk%H@o 9>ȟ!'< +jLd"|qnG6:d> 9ZhOf M}sWQ #t\ρCp}}~XKT;;`7bXPHǺZ6bIځFd-wCs" +&u)Ʊon1G`{A`[A +e+?y9Y,Y6' Ҝfk_!2+/b1bjl Kyq p*f +3:;ӫ avajuf.=29TS[%LC v.XLӘ! fm(:5la~MF̾bRň{QNMrˢbnb<"yS kbC?e‚ re, +.ab>SGXR`.e>-oXhXaaوUt,VFzxN?*$(3װ~Ɔ>6n8-شUcV}Ck39b+־۔mil7kﰣ̨RocE.֩ _*A;Vʼn_EEx|?ST~__OȾSſjuUjw쯪ϔUyѡVTcP?RH5]ԟ,nkvV?!w E # Ofyn[0p˫bfPÃ͘%Ɗm57vrqP1~=N63l5HLcePLLbhNt܌>Fr`&=ٟQM͉1i.Yv7OT豙FꘅLeKuaIRߖ젶t2SIzj[Uժ n5jvmkscm9uo+[zZp9Qt_[k -C*4I~[k3W;Sfh/ ]e8 hvNRxXQeO@q m-(Dn"H47n 񗩴H;JA md>>-Mu7+1Q\㘊;M威W~ +KC.h~[u*GǤ9:]q4ye::mʙǵΦltάKܹ.)W*f55vޮm;\nqRwz[!r7&ab d2[O>sxz!x%7kmW;^h,>wT_ᴯ|#YSDB7 3|*_l`8h win &_ਥ9'P01JyS64! []j¡~.o $eIۉ7b/푨G-W(6;wOyu,a,m33-LTOUOj7~]ƚ^ka]kyں ]צaٸm`iPn,ӦiR7cy_WTrD*>uɟ1Vy32NlwkkĠ9>HO||_pamz뤱A|Lyj918qwߟnCl`yx74`uzXzo95Q@GΗyltdO?&;O‘V{ҋTSRkʴ5oU{Ӵ6lN.g^a\8rsQ b߸Ievrs\}F%ERe-W EU_}}| +P1qUfٟz߼.W;_QUoD,֪:L/'3;Xܶ&ڛi(%z[ۍ4;8ܵl}6hG&w`~z9 +#rkS#V=m+wƗ%n{۷̂ |T$ɽ$nߛCαnM\4_G +~"ܨ^>~*8*'O% oG<|3d L 맆?JV'7VPcJ8D<*B]<3Z/Bi\FMʜlU{&G3p<;:1p?ϭ̸`-ӃF3č?@ +f*t_~O&ga. RXq889wrK ~h?&f4?)>J4Vgk;h=:Sk5:wzƚRBKAĦ+6άvnG,Ê֟ Ibr8EXG o.5m^kHŰBS".yt֍XOz!+:X_RXxkc-x-V + B4qI5RX%8Z.~ FD;XW_}Nk?Q+DC#.U[XT UXߧ* b)P.u5 Faǿ!"4tosLB-۰k9,mq1lE-Miu }9d3ڮ/ .: bnmXDފhĪFA +*,XFƏ3ktÄ0>f?RU9wEPE9 -+|6"۳Pk`3Ew)sסqv@[oy2w15FmSh!ϧ\{-+n'B2~{xF殫oJpv@a;XwG+Br98C!黎u"G4"hlJXUM+ XxӅXkw$5qIb*4$ 4hLd(\ʷz`P/޵\>Y-+z|) (>6 +C+7qכXĺpBt'Nx҆:B'n5/6}u \c7 hm%zS:5+UU錁֎i ۞G* SeyѦ v8#;?ٿ XHP_d9|$FА02, BȚQJIMXzDHudџI'b34|Alh6$e<^` Fm6L鵲Rg: +%jKBFMHi2o/ 4?yӖR(R()B #Vkhx4_ +-*6]/8mʌhtQ_\g 0INޞOdrVka_xc%)2o/;~zהąMY|\asُC;f`8'XsC9DAAD67`J}I~AjaD" +qD5R-)D[U-X( |qlgC%V$%iژղ][-L aO$(yLEWĥ@Z(ecZdNeD +tWCQ\e(wZym5lqvC BPA43d 4uD#^J4D$0fn|$ל8Xg./D8L;2}oe?=a͝4슬fsԲa SlpN!dTolFFR[ J|0]dɵYnlYv$gKh1ǴșA>{LwH56$`9{0H?~( .QJrLohփ4EhH8Ѡ/ =C*j婎8M nB_z(4?+#hאTt[N[rՖU” H/ ΆtV"nv_o𕹥EC e_3?U FaȔ>4%T Mu0\ֵ-v8>p&zA@k(c ŠZQpdM8Z#T'$Gf 3)h[ +֩D f$4`g*Q~+[hJ4jҢSdx0,T;3cڭ4Cg“jz>cJ-yRmR%'d܆wn+S{;]6w 4"_x3ezP䇖*W~>A;`,FhX +B.47<s~|Tc~4)亖MXh9|-r>Z>x9|-tr>Z7~||okהѥϗ?v~Odsjnk=f9 Z-e3屢]cpa5OKmÉWk'rqBܳ|H!PNeT/^ʊ-H Y^JfH{o)a_Xzof՘ī"]2c)cfsGBg95t_]%uZPjYvcrz=k*{*aӞfN"#4n=_67 V +uUq'4~:3I L%t.˘ٞR$%YzW]SSXQy%iWFʣː㡠WG1*6XZIԣT)Ӭ{rA)Ŝ+ZrX)[C)y4-!-z[59rƭ,f,Z/6n"Ys4)$n'&I{g ch'݉u}q $`K:J0J@nXgQ`\rnr{PɄ}cWZ*WH|{b[R/;#ipt0wP"r YίfQa +ætԍJ]hI܈5tmK(Zk$Y=GV,Iu/HϬ$'=JQ =4ᎉoߠº72cj%ǚ zon+(ϓ[F(we{orPJ|:{s("g7<zrb6eDy=B{rެs"E +㽑@8vuPf Jc}@L\u%4 +fvB2mͿ'gAyyb!n $Joݙ+ KʗMȭN]wIO/C }]H2O6<+JU^w#Uy[veޛKN%ZՕysqޫ+ۇÕyR:$B2?\˦ RZTzTzy[ +6OWCydVpyL`1 := +EFϼb hWon>ޏڍJ f|ُD˲fǤߏ-4ReUuH#8-(aWH~?*3qi@˴ͨX U`t &|^}ǰҬpC͖7Ya^Jf!?4Ua,rIʴEBIͫuQwpQߟ#EyIӔYpWoH +oCT_={6=p,To^f)qiJF&޸0曇;]3FAյO![p]"a+=Qf=,1_uYZ$fRC̚&1`@*ҥۭ?l$jqj. īC- (Pʡ"}^J'Wvgr 7b?Z~H~n}XuDn4:n;AٝkJHa)ZhY_*,"/I`u559~UwpHcM[-IkLBւ^ aXᾉ .牣ObZsO{ԥ M/V=5Ɔ3Nݢ[y6(GBA⢊>%>MA ?&=,|w}a{=+?K(ļQ6BS;xvv֓uNJrX8o{=hjHaXU-}l,X +ĪDgTaQd<['VuO̍/xa0Ӟ)uIQ|]aÇ}}bq>>_}b.7^S'gMܗ<}bU},WUq}/*S,S[c핅}bk(j\aXU_xIa¾{DaXU눦畅}*^T'}b>`U}bB`⾢OXyMaXUyAa9 +OO"eHSD)fWfҚ۞Op?1iol'r($.Rtz԰dok +KI_\a7ӛ{7[2u_)Dw#UѿK~2d +&,-k2nͳQ?OZp=>9kI?VӧЗMɻ*'$w|Et7 +﮴c)R^]x]@iwxP[AA<(Q)YbxKC[yOEhn;*ʕ/vH'7ޓ+%Vo +LUId$oo +ZE x_J|eT+ꅩVT+H3_!Q.@& (h`8Y^2/a7fcdL5^S:W@{Ig&Pq3Iju]pMmۦE>{[zp 'TE(:V҉wH:?^Ȧ1@0{zՌh~\uHX/4T  +d+ɨtb҅tIolt?Fiu}>׵)}};,)},Hʫ} +6wVojBT*X  ίk/ V6CZ H&(+(PTbTXug`ol/7TT>Zk +jTjsFОMl^[A!z Vb>Z +)Xkh0ѺARF}jyfʴݤZ4v!ncfӽ&~ a&} |SR}IXrlٺ[VBF'R)'P ,1uke4o`F?UP!f͏r3Qpo$+bǹTk6[kMgjj+6| TURk(H +@2i)5w/Xx92"Fm4ȦH۴* "(%A^[[S)O  oXDvՔhkV'HK  }:W^H>HQU9)?VZ g}w0&/k"ǟ\vfEF$fss}VRL.(͙c/u3^Y4t"+sTs, KW\Ջ4/3ˏbE\<3C) 5&}.04aI7ri`x@tu-H7&ZPLtu-=ɗrWUDu*)%y.kw-[1Oew5/EQYI#ia*,I|0nZ5t"}wZ< +#",i:S'G"4L +b7}|h2uF<}WJ^Vq|1FqA!%.;4 Ir7Uu9P%jԖ%O!7VP*#xmV#_9h]V5 [#?VK8JAbQ/D{$Qi=J϶vzD1?%5Gda*I1$I?Zz[)n-ITZHDIe%ț뾒DKD'=y=ݬ&u7+?׬PhVxɹ6+DѬdY?ѬP e 塠H+c$' +d K vn|jsChx(Qhx(Unjxx9ΔӐQnox(ZX{MC@3@=>O\,$]Jjx(]r$Άj>ZW4ykaZ lƇTuP$ʱnx( E׽ }uZͳ 2Zbn&P^{w;F +1mP*ixg(Uʣ ixD!ǟ\Cn~t?2 ǮG'Q]ymx(6lC_ =nxbIQ5nmc!!$py#gq=aF7^<ܳr4t/.7Xp-geܞkMq<[{|F 7M|}3֟Q#ϦNd5 +j q4CT 3 c +GZͬA>eG,/MVj4Z0a4#~OZ׶4E+B" DZ#Tмd9"=yI+85Ҏ20+Rg^j8X/m+! 3Ϸ6= AlSq?QOFҿbǀRpYz}/p MK4jy6=qƃum5#~K䁍Jexnz}tkC:5nu ǘJ%-ZZ~\;炌j4 +-zJƺR1}xpOlnn<9)E:qV-G/ާntB7"9?V&tdž{xhO}£G[ ";+Y RߪxG7j:m;S :%og^ 0-D/Ӓjg0Cdž%:1q , |r0:JSЁV@3^R:x#a<)]Dїt9X l&8`@;P]2% 7*n # n-5В9a+F/[{jAZ~]ȹ-f_i"ݜe8<-Χ8y/pQСC=5=GDh`.c^g"4" 7 А#"@f3 +,@"b@1f@FelcOtǺ,s`4q `cu^3, )HAXkOß\4ky2mHPD LT $\吕U åfWJ&9=k rfp\N#4 8$ CӬ +C8;! ChdaHQSъ@?;!b-buQl汉w qP7j, !'@ +!AE',k61OtJTs#:g7;IBFRL0ɝA W`V%u+YuePg8:Ov7`[/?kDԇT qsly8ήcڝPc {݄"r^m!丸uB;JɊd"ٙMvv &^"K 8i=v]2i&c??8F-y'/)0=j:ߓizΑ%= D(]񼏰y2 mD ady8ǟ8)ڣ3ncq1)@#]= +AA*Ek>9Fڼ5զ?3_h:) N(7eƱ.4!fi{Tb.MAQMcGE`su)/IpB!}Z%vmo@;7Dٿ,'V@$9ƒ^yζcP1Ճ}ξP]ng*Ab7Sڹ&G&`Y> kJcwkI"*4^'FSnγ;:yCƕOXʭ:!b1ia'Y2$ /#s*~Hrq(S~h]`X71]68ЮY,gh/9;Qb#L@h_p,( :D|&בf;FkR@s1X˲\Bjk$?j+̖10~(edbZasg6ce(8ML,~ 4ۡ% b9rƽ  +P[gD~U|n0"f^5^FPV3'Uj )\PLLKjW-Tripp`jXD\qTqe+w b}ջ&.߅0 }JC0HsӿwR=X4v?ˊ/E Nxz-%ZΚ _0鱅 "Z(n_8P8H&Be'3RB-Kƞ6ӹ䪃?F&ԙW 3~Laƕ3!EArE~``mf(t%ݶq< l=`&4g%9j1$H-_`u~@{8nb'^Y {ؗwD@+GoRŢ_fvZ/w{f=b/5u:=FɢHh9M2ZpĻ!a~axa b:f,kv1A'ƀM\&ubb-؃ir,َ-jag|j##9+T v+:(90]߂/ŇNL11s*0fRsRd0N6J@cJ@cxߏ{Si 67s͜4P=^6k +$Ɉe\tI2+.GLBE `}+e;2W>`u6pNw 3>A<߃DK'ooIǏ x~x gA;'j*y6 ƜSΙ7ӃyuK" )HqdӲ:?ig95O@ y$XB`wUC Ȏ_;#r? Yp! g587U|FU(κj3JE8?t-9w9q"MD ӄ8jٌ9ʎ?8[VU15.jCfi \ZP{hqz6}7sSЁ=G@B;30BC]G2@0[3Y}(X͢Y`{`D hqr[ +Pe!W5ifD'a8ѓ6@KO(b!@9h-3# +]T X9FY22mlE*@:0]*>stream +y[_tѸ=kiC%*̚Wܤ'/L\FE6G&$e X:qťƴ1M c$1; n;##]j&-|;_?3k cIa3_ q8R!P +3t3f"l4@nrd0e0DqBhٞ8t@Q;KA;#ΩowI˧h"9Oc Y7hV<53!ɭRQĔW0Y <>幉mVvkD{"M-iMϰ6t(8iq$?I>~ FUVDRjpP31@â;Σ{'X-+[˜X鯃%'UaTa%&U226uAu UܢR0V1SJvK (4 +EqPAPx84z!cqPAPZ +<U<UeRM* 25AAJGJhm* <U}>?U 㠐1ass#\/-z9-/$q/t:'Zc {A1=;~o&~kbM/? `d5Pw:>n23#v&J y v6"m.puP1In;q/)v!!nAic#ݔC 0 "y\Na@8Q 礯^W|n0wWoט$Ez)8RNj`)u%\8t;r$ƃCc/@)/qf::W? %<7$ny09u^d\7\{RHʋ,E9_ǿ$XQbw"y 8irK^9 7zECvR dVLN>83 s2%$K58Bڼ-q0 qP@@M{ 6w"%y0#\'xq s;^0'@.q:xD\㒋|C+x +1Pg<:ҭЀV&Ec?g0qr\l~q[~t`  +endstream endobj 6 0 obj <9 1)/Type/OCG/Usage 17 0 R>> endobj 30 0 obj <9 1)/Type/OCG/Usage 40 0 R>> endobj 53 0 obj <9 1)/Type/OCG/Usage 63 0 R>> endobj 62 0 obj [/View/Design] endobj 63 0 obj <>>> endobj 39 0 obj [/View/Design] endobj 40 0 obj <>>> endobj 16 0 obj [/View/Design] endobj 17 0 obj <>>> endobj 77 0 obj [76 0 R] endobj 97 0 obj <> endobj xref +0 98 +0000000004 65535 f +0000000016 00000 n +0000000187 00000 n +0000052969 00000 n +0000000005 00000 f +0000000007 00000 f +0000274983 00000 n +0000000009 00000 f +0000053020 00000 n +0000000010 00000 f +0000000011 00000 f +0000000012 00000 f +0000000013 00000 f +0000000014 00000 f +0000000015 00000 f +0000000018 00000 f +0000275448 00000 n +0000275479 00000 n +0000000019 00000 f +0000000020 00000 f +0000000021 00000 f +0000000022 00000 f +0000000023 00000 f +0000000024 00000 f +0000000025 00000 f +0000000026 00000 f +0000000027 00000 f +0000000028 00000 f +0000000029 00000 f +0000000031 00000 f +0000275060 00000 n +0000000032 00000 f +0000000033 00000 f +0000000034 00000 f +0000000035 00000 f +0000000036 00000 f +0000000037 00000 f +0000000038 00000 f +0000000041 00000 f +0000275332 00000 n +0000275363 00000 n +0000000042 00000 f +0000000043 00000 f +0000000044 00000 f +0000000045 00000 f +0000000046 00000 f +0000000047 00000 f +0000000048 00000 f +0000000049 00000 f +0000000050 00000 f +0000000051 00000 f +0000000000 00000 f +0000000000 00000 f +0000275138 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000275216 00000 n +0000275247 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000055103 00000 n +0000054909 00000 n +0000275564 00000 n +0000053415 00000 n +0000062592 00000 n +0000059908 00000 n +0000059795 00000 n +0000053938 00000 n +0000054347 00000 n +0000054395 00000 n +0000054987 00000 n +0000055018 00000 n +0000055275 00000 n +0000055530 00000 n +0000059943 00000 n +0000062666 00000 n +0000062906 00000 n +0000063991 00000 n +0000076426 00000 n +0000142015 00000 n +0000207604 00000 n +0000273193 00000 n +0000275589 00000 n +trailer +<<56B93DB26AEE3D4BA4C5BF668C1C36CE>]>> +startxref +275780 +%%EOF diff --git a/distr/design/oss.png b/distr/design/oss.png new file mode 100644 index 0000000..c3567ef Binary files /dev/null and b/distr/design/oss.png differ diff --git a/distr/design/rsm.ai b/distr/design/rsm.ai new file mode 100644 index 0000000..831132a --- /dev/null +++ b/distr/design/rsm.ai @@ -0,0 +1,2352 @@ +%PDF-1.5 % +1 0 obj <>/OCGs[5 0 R 27 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + application/pdf + + + Печать + + + + + 2019-04-30T13:25:15+03:00 + 2019-04-30T13:25:15+03:00 + 2019-04-30T11:24:28+03:00 + Adobe Illustrator CS6 (Windows) + + + + 212 + 256 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAADUAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7F XYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FX Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FWD/nH+aVp+WnlAeYJ7FtRlluorO0s1k9EPLIG c8peEvALHE7fZNSAO9cVeG/9Dz/9+T/3NP8AszxV3/Q8/wD35P8A3NP+zPFXf9Dz/wDfk/8Ac0/7 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 + + + + + + uuid:4680cdef-2fed-4e2e-a7e5-7e979abe89ea + xmp.did:163A89E9836AE9119321B2441BD85ACE + uuid:5D20892493BFDB11914A8590D31508C8 + proof:pdf + + uuid:ed609a61-4e0b-e047-bd4d-722efb68a6ed + xmp.did:0980117407206811822A897E387FE54C + uuid:5D20892493BFDB11914A8590D31508C8 + proof:pdf + + + + + saved + xmp.iid:163A89E9836AE9119321B2441BD85ACE + 2019-04-30T11:24:29+03:00 + Adobe Illustrator CS6 (Windows) + / + + + + + + Document + Print + + + False + True + 1 + + 256.000000 + 256.000000 + Pixels + + + + Cyan + Magenta + Yellow + Black + + + + + + Группа образцов по умолчанию + 0 + + + + Белый + RGB + PROCESS + 255 + 255 + 255 + + + Черный + RGB + PROCESS + 29 + 29 + 27 + + + CMYK красный + RGB + PROCESS + 227 + 6 + 19 + + + CMYK желтый + RGB + PROCESS + 255 + 237 + 0 + + + CMYK зеленый + RGB + PROCESS + 0 + 150 + 64 + + + CMYK голубой + RGB + PROCESS + 0 + 159 + 227 + + + CMYK синий + RGB + PROCESS + 49 + 39 + 131 + + + CMYK пурпурный + RGB + PROCESS + 230 + 0 + 126 + + + C=15 M=100 Y=90 K=10 + RGB + PROCESS + 190 + 22 + 34 + + + C=0 M=90 Y=85 K=0 + RGB + PROCESS + 230 + 51 + 42 + + + C=0 M=80 Y=95 K=0 + RGB + PROCESS + 233 + 78 + 27 + + + C=0 M=50 Y=100 K=0 + RGB + PROCESS + 243 + 146 + 0 + + + C=0 M=35 Y=85 K=0 + RGB + PROCESS + 249 + 178 + 51 + + + C=5 M=0 Y=90 K=0 + RGB + PROCESS + 252 + 234 + 16 + + + C=20 M=0 Y=100 K=0 + RGB + PROCESS + 222 + 220 + 0 + + + C=50 M=0 Y=100 K=0 + RGB + PROCESS + 149 + 193 + 31 + + + C=75 M=0 Y=100 K=0 + RGB + PROCESS + 58 + 170 + 53 + + + C=85 M=10 Y=100 K=10 + RGB + PROCESS + 0 + 141 + 54 + + + C=90 M=30 Y=95 K=30 + RGB + PROCESS + 0 + 102 + 51 + + + C=75 M=0 Y=75 K=0 + RGB + PROCESS + 47 + 172 + 102 + + + C=80 M=10 Y=45 K=0 + RGB + PROCESS + 0 + 161 + 154 + + + C=70 M=15 Y=0 K=0 + RGB + PROCESS + 54 + 169 + 225 + + + C=85 M=50 Y=0 K=0 + RGB + PROCESS + 29 + 113 + 184 + + + C=100 M=95 Y=5 K=0 + RGB + PROCESS + 45 + 46 + 131 + + + C=100 M=100 Y=25 K=25 + RGB + PROCESS + 41 + 35 + 92 + + + C=75 M=100 Y=0 K=0 + RGB + PROCESS + 102 + 36 + 131 + + + C=50 M=100 Y=0 K=0 + RGB + PROCESS + 149 + 27 + 129 + + + C=35 M=100 Y=35 K=10 + RGB + PROCESS + 163 + 25 + 91 + + + C=10 M=100 Y=50 K=0 + RGB + PROCESS + 214 + 11 + 82 + + + C=0 M=95 Y=20 K=0 + RGB + PROCESS + 231 + 29 + 115 + + + C=25 M=25 Y=40 K=0 + RGB + PROCESS + 203 + 187 + 160 + + + C=40 M=45 Y=50 K=5 + RGB + PROCESS + 164 + 138 + 123 + + + C=50 M=50 Y=60 K=25 + RGB + PROCESS + 123 + 106 + 88 + + + C=55 M=60 Y=65 K=40 + RGB + PROCESS + 99 + 78 + 66 + + + C=25 M=40 Y=65 K=0 + RGB + PROCESS + 202 + 158 + 103 + + + C=30 M=50 Y=75 K=10 + RGB + PROCESS + 177 + 127 + 74 + + + C=35 M=60 Y=80 K=25 + RGB + PROCESS + 147 + 96 + 55 + + + C=40 M=65 Y=90 K=35 + RGB + PROCESS + 125 + 78 + 36 + + + C=40 M=70 Y=100 K=50 + RGB + PROCESS + 104 + 60 + 17 + + + C=70 M=50 Y=80 K=70 + RGB + PROCESS + 67 + 41 + 24 + + + + + + Оттенки серого + 1 + + + + C=0 M=0 Y=0 K=100 + RGB + PROCESS + 29 + 29 + 27 + + + C=0 M=0 Y=0 K=90 + RGB + PROCESS + 60 + 60 + 59 + + + C=0 M=0 Y=0 K=80 + RGB + PROCESS + 87 + 87 + 86 + + + C=0 M=0 Y=0 K=70 + RGB + PROCESS + 112 + 111 + 111 + + + C=0 M=0 Y=0 K=60 + RGB + PROCESS + 135 + 135 + 135 + + + C=0 M=0 Y=0 K=50 + RGB + PROCESS + 157 + 157 + 156 + + + C=0 M=0 Y=0 K=40 + RGB + PROCESS + 178 + 178 + 178 + + + C=0 M=0 Y=0 K=30 + RGB + PROCESS + 198 + 198 + 198 + + + C=0 M=0 Y=0 K=20 + RGB + PROCESS + 218 + 218 + 218 + + + C=0 M=0 Y=0 K=10 + RGB + PROCESS + 237 + 237 + 237 + + + C=0 M=0 Y=0 K=5 + RGB + PROCESS + 246 + 246 + 246 + + + + + + Яркость + 1 + + + + C=0 M=100 Y=100 K=0 + RGB + PROCESS + 227 + 6 + 19 + + + C=0 M=75 Y=100 K=0 + RGB + PROCESS + 234 + 91 + 12 + + + C=0 M=10 Y=95 K=0 + RGB + PROCESS + 255 + 222 + 0 + + + C=85 M=10 Y=100 K=0 + RGB + PROCESS + 0 + 152 + 58 + + + C=100 M=90 Y=0 K=0 + RGB + PROCESS + 39 + 52 + 139 + + + C=60 M=90 Y=0 K=0 + RGB + PROCESS + 130 + 54 + 140 + + + + + + + + + Adobe PDF library 10.01 + + + + + + + + + + + + + + + + + + + + + + + + + +endstream endobj 3 0 obj <> endobj 7 0 obj <>/Resources<>/ExtGState<>/ProcSet[/PDF/ImageC/ImageI]/Properties<>/XObject<>>>/Thumb 43 0 R/TrimBox[0.0 0.0 256.0 256.0]/Type/Page>> endobj 29 0 obj <>stream +HWێe9 }Hgw{^HP=%` lǹkjzFB/'N|IO|>>x)˿ww'_ ǭO~OAUPB9xA"::[kQ|O=ckcm p,Aײױ,?fL}f tp9zg-8~x5kCsgpMN?>r:^o+ʏ?<_WtuW^ ~~1طri +K~!(C gyԦr[ E/SSgI\)Gntf%<+Z'Ќ̥3 HΑ9tG}F.seM̷ FuSKhK%Ϩ{pYȋJh͗YwtZC +.ʶp$ @uKV<~͒k{sYM糡O{]az0S~ى5o>o4lsSBhvimY1g!0X9uuˊ.۶=!MɖsƲfMݰYYaͬ0mXo4ĸ* 65b.SO+ReLwH6=yٙHvQRET`M>bұ.7pf? q,< 6/lC6c2{q pbH@d[Uբ'˦HK^ĎĶ-ߩ*pX kLh Y#] +/\LX~9e9cue3VjĬκ2f]ﶧf*GUUe vrz_XFL$Yh~lFC-H R]BܧUa=챇/=܋K9X}V5uv^6sFsK +wg )mu=:M3V76cIn:l֍>hlSh,}H=m[}~ǯ@/;nxK ZaJox%sA'haK9iė5ۙh'm퉹m:MԞ36cih:-MLml>hlSj|t*6F?Lݞ8g >>HB7>)>B~`& +%9X}AHDهo:t1wnޖJ]G5j%M~T[$Urv475qn«#M ?q-KK&˪ީo3*d-|^[jĒm2 UlE$;-n1aN/Յ xbqIh*.M)QEK5j5ŒWiNlp^`J|WK_U+ﴯY.lkiokqokŭşhmkiok񃶆A6v~WJ هReF'4yjg43LJ3>m{m* ] f6'::5^ :;{4tvQ:+*^n~ïne5wٜ*#vnl$0_ڔ%gjǏxCHm:7fLVewcPJrɶԬ_͸UxĞIAS;1^el.G#懘JGٵ@HmrzݑKITx56%'ZRzŨ *?x=}Ϋ CYhIϰo?B*k}?o(P;8\.R Y +pU6 :^%WsF[UxPy+Pd7&bs_%ɑ8^F{d6'`DV3)ApEE}*Y3,ݻ᳙O=rY) +-ڠe|3xZ 2Htd9×ud܄dCH[m ya#1"%~avhC'$,+?lYf&!ĒLRk ϑ7^kxPئ,&.+Ey"RQlhMwnS.LkGviXݪj,h/fS􁽨P+zK-a,QCIwHE4 $$"'v3E +lY<FNz‘[r_wS7t Ns[nnܽ6wrþHq*[`z{YoLE$:4T?BqFn~LFi׏y׏y׋a&4؜~M=M>F/[1Y11M/(;\D-V*a{W';YVn'tv]jF(ŷгT. 9d_{NvpM)Fq)Pʁa2sGb6%m[ĥB)R.֤ru.kAMX=jkHOH++OTH=A_8uP-!uu ٵbBoq0p*qD9kVsRosld #$Jl~{j +UFXƿR U߳S2YUIrT=4-1&(I?N>WDƄ.91*%D3ǂh?ޤ8]ڬ}i.dwRt;!,ǯ Du^OZc}Zg:uA_t3^Uß&'08g҄8G9J5U& ?lu+f:ص]J`jh9Pw6EYKVgۘVs +8KdA/ ='uPmJP>nB鍢 M,QD%5a+|cQ isZ#jN:"bbE);̤Sxlέ`O{yɄ$ P!u9E@oW)Ny z +ӖҟlEU$w]Wr%_@pb~ tH5W2F'Yڔ?ku/NxKopҶ#q+ CxXU(Yثm^C7nw]B?#w鄷IFk72ˮh0V[…L.^/4^7EYKۘۺѣK>Fo.|kRmloS_}ɸJI;:78cֶv?:TP\LHTÁ2 3 +gSv;D"'~𓴿*r/|֬b" <6u}ݛo)wtkE ,,W8iqӡ9{tV6Fb=cMaKˊg [3,E&,6]*T޽e{v׻( شݺѓO|ޒP^'8X|@Ye-8[5Z怉uSKZ\N\DK.0V,r\^X.9KratgP)ḽ78QB>w|VjrL)+G$e#Jǘ~Ȍ3cbfoay5C +_6id~wq˫Dk94z-`,] ÕtӶє0$M82Ÿ4:JEn 70!=( +!rK$3fr?UpHfJ|Z Xֵ Cp@oP°ƱV^Їu9R7{&o?/ݿ}4+qXD7%quXxyc`_$9uU/R'7 ×lO}wFI)9;_wyݼG9X`&KI&gӮ,D6?~,2;Q>Bx9^0%ǖ~-.||dy 0=r[T|0M)K+PϚ20_t%[O]śq?}MOJlv%6%64-X-_)z/½dW-a̐ٙ4BJ0bXe8O!u#WeX%Kf/eCZ=J_3 @=Ś&Dws +`kտ|ONz$aN9.9kNXlZj5kl^ȭ}eR|Hi%P(+PZ?i7%A MZ붾cFOj8 xϾ¦DA(m7.ge6BӴY=$!ku?}x:ƗchGQ?G6[lb:]e&-=L8 +3)Mo,s38%'iIIzo\ԥb.:ȎR\bd:`GOIW5<DE ƓOj63=43fB33B33iflfq3)?ʹ;r7C;3?ngr[d GK9oLPD/ >工S-u9 +> oJN玒-( 6% ﶭsPRt/u^@_1ɶĺeDɦymxem0ؗ)ˬh)4C (w'lTP)Ӈƭ*3Ty9Ü:wP,Uf0"mLʶsdSSS{I%taIỮtX3+UZxf<;ڜo;o67_RRyq)#Զd:Aq$^GdmLx?Kyf_|R^)j(qA'ДjJuTGϻT·إu. +~}دЯ6ߒ2tvvuvU?q4H]~>!5>s}J>*%ʤ|Rö=;zlUR@trӶYm쁿Ll,?OeX(7Q qøOagb;wSr@& dz"X´ib,6|vj >(j S"Y`B}=\ɽw>qI͖Q1 FIbzQx Ska77g̥A0fQ c-6ƶsd0ko$NهXZPk>@|v?XekV_n}xQ*n~^.$7o{U?pXNS +C+ەxɻ!eT~ZU棏_Uj[/նj;|ڎ.N1& Uy7OP@]_!!ڐo5 Q9v϶kwv[j stRYmh.9mQe[ۘm]ԧbmH̢ ȡ vw6$5$1g#Jbܪ*l,2$.ǵv$&``<*"xgm3_vAx +Θd,$83np0(9򱼳W;s6Dp*rkg dC20X w=KMyE=Оmlqb_v5:GN\ښz)~A_[\o(QB8@.a, +HQӊPĀ$G\:}FeF.Ouz{,G0tps0O_ǻJs:!eGUh>:EHR[$ W 5Dc-%wF9sCQjAv=>+q[1Uwg3CyPU=aSF PӍ+>Y-U9ڀ&64PB$ph, , tQfU /H,% +.LoGHdi~ A*уFsc'%43L=wAxآA}|Б+)%{A nL;Y6.^ˠn:v%)y ݩYԧRjt;3ӽ><P @>>egVZgo[T;01TWjLL?F0aq03 aƣ͔_ڴym:^ii[?M'n۰n>D8ʱt3%TOc]qAY +5${ӀK H' a [^M$1DDh]N*)z.Bp [!L i^4.4k!VL)k)NݡX4މUKfB*ġZ +;I+U9a D v [ ` [ DŽ2KY߀٣70(X0 2A~!Q6{tLxz/<5(]a=JbtǴBYm%0$VGWnR.m g ʻIύM,6YH^UIӴ@As Wi|?|d _nSc,Q1#Xc7BTj@ĕs:`t Iˢ$E KU\&_c1=q^ybGajmŊ˝5{{ 7$ \,0now]o_׺ruvv5&a̠] +̅]|ZS|GK {zI`p~*'D|9l_6}Wc:z4kI?eiDXe2MP\Gt/ wIaIQmY)Z(tN7]ul}᳭9 SRfQ2㯵g^ ??jC\}@#ī{GcmalJxT K[U׼=5p3ҽ^޵΋fJys ֬f\۶DXOP7Ie&bfdG to-t>&HTmk!B8zPBxs;le4,$-d\ Ω.ѝ-ѽ16$So$Π +)kK(ι+ +P9ǀߜ<.!JnpAevs#`tXʃf[Tͥ%`\ݕf8GP,H;`%Dd ljV&3Lj̊yztǕגL1&]}}C\?$]JrY&?uK6Y1򤈙Stkc)vn]BQ1MD4,-\ Ω).ZН-Z=N鰔E˃Fߕs V5|mYZq}'c;>(!@dһRK!IgB^aicKne}y#GF5O1p[AL3 +5&a 8к?1 DZ N]'iy'ƣk *Nc#w +S5F]&-Ҽq8H.xԗU( _cP'⎙;x5b;&!B)o;T%J`eu(Vozb) |.WMT!$%FyGA2 +z;fU{&: z\;2 PćD_NeY8f,Xx2[,xq2+{Kĵ*(eV]{zFq`!YeVI2)ܥ:t$W8{Om +G t`?r`)~L7DN{;_Zb$=G_,n+}95c7m:2ݗ2/4:ygA[sGxi7 }돌VװgU,ٱ=nAhYAGg3M ex#Lq1x5fk6ԺMiE[pEЖ~[2)h_3>h0*׭,?pHI'1~^-sL/s#$ɗoR5(XPM{=M@];&I+@ʊs4́4t ՈrD )Rq:PuѝK1bH*9!QjoܳVV *RI}WVB}hC+7&ab'GqeH%GaG̵]N Y:I߸ZH&nİKߘ7h@+?aQ>mYZͨ"K.m-Ӎ1|0 ]oIyrK 332IQBVA]M^tJ.U&7<ĪFbB3[B *l,V6)Rމ0 XhڏEjQWc)#iJ@*z}tx+M"Eqd,\HCum6 YY}]Oo9>=9yY=v])m$8hP /TliнPTyU`CB5[J: !%mJ,TbB[ۚRTG4mP>hʵP^hT.b:zS5MO[!~f_$9~?NOPO_%y</R%7 (;7*1}l.4K*|׵ܦ<8yhoijȒѴ/s/os-\rR-C|0XFYkpЗqcc _XJg #NB̴d5] nF\7+ 2R][9|rn^BI; +>ϢQU=znPͤrTs%{|.^>I=dj%!.*'hϼVTa#0*A)9,tӨkpa5Xj sRƒsjs0?nrNnsJ冢̢:Q)󲫑{ZLZ&[m{۵pbsF/I ~W&l[qA '%ZրB1 +؇0BggװK+aN-jw0ºn^vnS`ㆷfT-R򅆢.1믥DC1m3w !?Ich7(Z/kaTPX=+W~VG$ΕF¿&$nҴǑ \cS`LPuعjm]bT5iGd 4쬤LY1ٿk-)gT-A&gT9W I +ps. JJ2 a4;tAK(ݔ%n[ĥRG̢udrwUc<בo-V5/""s˷xy߮HY o70'\n,{>gfj|>>~>9cg-g@]gX`mW`f "@,ς`GFOxZ.C:G^ݶ#e3L Af"Xδr׆lٲWT`OZvtD(̲ 3]$ʜqk>8:R",ΒYWУ,TOo)?gV@a#e`"C8cOd4,[ {#$M6B,?Ri4oiυ[ Ĩ Ҽb`KZaN>RɘWbmˀ$5-nsS1zeb)A`F"?KJ3D1YLFXCu:tv%9 $ӳn>kdztxYJ5vYz47z?2{lh.H@qNAe\26Y8էj;=Tq-\t^$T_XTtV)/,?ZlfItQώ U9aJA%ʳJyc\C-[q 8Ȁm`i5)%dla 3O}f]"Cwf{9zZ@ʋ*=<x>S, mZnpD5ѳvh~6]ڃ+j,0/;`ry ҠScs 6>\E@.0rPN>A;L? 7 7dIlJo `/E62)4Em!]+Ã!!յs~WwM+MR [j +,@a\%Y4 .5?tM)ٖ[I٣ZIEmeGoMEdjr+(BaWZ#|mG\a:Җis;­qqw^9z9Cw/x>Sn:\qj"s% 7XJD`k)y2ϠQEY(ķOI]t'ΚsgUVof#59Ww9iweizիm9퍙M=~߂^}Eֶhn.JF:FK[aN%dlmlpB[nSXvb.jP߸zej2ULjC%}A^p133 +̳z< S#`,uڐ Z;-XL$ KV-wPw--rެF QQ{"Lc3vu(W|Lł8IcӡԍyN}6rnx;8bINN ->?TK( } *K6d8>"}ӪxO„+UQ ~ +צq%msōJM(ssǡG'nw2 LJTNW(+7xYY͙e?C#tV#cUqX.Gl2XVd,(Xsdl+Li(%c#-(iIF\*[/-ݹѳK[f)G +,+e)Eyֺ 򟐓 +LNN濸dIrS dЬY~ۈA w)W?''aA1?ݎ|~fMr5k],yK/QjS 6)< 2?g5J,mfa"RJTMnsSq]o`*gʙ h>:eNgR6jڢB%er{Af,4Qhn%'v5El]<>Nz[r_S<wWM1ox6R=xHtU8)i{? AW̋Z/W+*O܌Zj/쵛Km6gЦ7^|r@*^'G-febL>{TgrY ,$uax'-oS~ͥã̝ 1k~L-ʘ] 3|=4\2y0C4"jT--_ugY-i H n`})bmbfǶC}Ak,'5[-mfqY,rcq)>FҸ}7:6gn\XX-+9.5'uQKcݘņbc3DmTv,zg屭u`'LCofqL +Ԋ5SVtff)ApGPFPmh*~9Ls%Zڡ0\ƃXJL-ΖixzzWlICAcn +b.}3g)<[Y>G`q;o^mAGEQ ]3 AZji'c/C 8I֧oՁnaš&п)Nmd'AФqyw˭-`/䫩L}+Z"WKa^d{̥tY:=(UQW\tmjRݵCCTGl=Y"!0 ՓA"\vRh(fP0Ґ 1/!t\d/)^Z\\|,ֺ}Dd2N̻̻` 7Ř/ $ ' 76^?#o +ǘ7V:8˭ x] +oYc/!Jl% W/z ]k#?< aWL6"0Jz0Bb~Vl8>X'/#l4(!!nO].,uA-.9\<*Vk- qRcXʂ(c+svi"|XYBEq(nEckF*~BZCZNrF)i/i/V y+#1$M88o@rrգd/1VPhPh-OVSKi@ʗAEi ŸN~f"@+Vjfʱ ֹYC}<GC~xttEk6^svjnh6?~ T!٠+Ikypq>5o2]vSnF~zWM+BCZ3g^eO]Se3 +2Zl%Y".[ĮSӌVR6'e+V^b ZMYm>TLX";kʋ ziHmO?}4&+;(HUxE%5a+tc lhsZ#jN:bb5)9̜Sxdέ`џ H@}`l-ՠAz`l ed-"HX O [o}6bF3 >hb)/p l78y[sRpgaea~  +?-WA?#w鄷 IB{2&h7,TѶ2VZE +υeU3p)PZ*tQ+/1+/uG33Ct.pmnOlֺbӁ)x (S[ ȥhj~"( C3iE"S;y_6b٫,-):@Z@Ni͞yi-pK۠ShhqѲoђotF7Za.gX"'~&-̓aĹufPӌ͖R95s.n x+e|ac >\Wq`ti㴮XFZrPͽJ4!T3G M5/,9dsdp&Zy!7qtPuyc<o澆ҷ2ͳpwUC%w EFou [o=Yr)ሆDI4'e~xU3yհ~)j|RcԘ1?[$̫–WI'󻳜]^]_sϡ7sI#C\\(0-L'9m_M 4H2p +eqw&bH!qG(g'w'+.x)U>C2WZDz%]LV2&- +j>;@ViV(lPD7n%qu;v5 ? }{l_LJ0_%q0WྼGW!Vdkb"u( +?M_aw{(?!@s1~78xt$9)%*\Z>bZ#Ӭd@ޙN@_ +;G )3%r^qzik0~c6Vij&ca>nJLK$[ +ea(@I(H1`)uEt +nA\ddCK, +*l2M9|D4f~)K&|SkhCDr ؛ovްj!2%ZMp.= v=N/9-9N&=VǷJ{h1p&ČV3ڌ+qV#_3Z? ap-Aov #չ!5֎* +![AكbVQJ<pt:m rR}3 +Xf4 @I譩,ǚx 4j(eZLM%L>hcd!XCG>Q9%EW.% Rcɒ:eUPdVG0<#(ҡ{+`nܵ}847즙i^i)ꯧl LO33<g~.U[ƀ0ԋ/x8֖֔POC\JX<ť|tlll}moK>?,`BZqG s ѽ 6'ޯG:2@ZPF,8ɪ"Z IDhsVIZi[F35Zhz Swu`!`(#׬9 r3 1F _X1 ~ ɊkeӬY8YmlkccA!.EGm#[5r4i0k)Fa$Y|gY=s֚_PyU貌oP |'wDw}i/C֧.ȰoX8rF Zq}*աeKڌס'B*QkDҙ/ә ( >lF~.B6o'bE(H& +#!V0$ǩWl<ӸAq+I]g"ƍ4wQ1{bYyC"VB\~ y>Z6 !hYIyX`" ,8\NHYD0^lx`XQV~7egY8%`ٯ.K{[ٵ-HC>*U@Qčֲ#o48<[hxt O}rWt_|CoʉLZHM$&@5a0}NJ'TQjb~!Juf4 Q&[>,V1HGh_W~"?EE8 +4&̰܈syk#GR=9156S$)Fm5(OUb>ćXV#M_eL>Hl|c TꩯrϴfMC$" Ա4#$Q*92;3@"2Le=Ec#ȃ + /9 +h!Mw(T4V:$ 7 gi2xØ/ +iӻC;`Q/ya)_Qfd ~P ʝk YړD>MfR?AiM&yJ_3lRBw[`8/Jt7%GwBԴ!GGvcuu[gv ױp /O-:ޗ:ܷY2BgyR$>F'c4;Wi&9̈́0 %].ٱkvYPKjei&Ku~,I2m;jS'1|lx@]5@&\\q j'T&A2łÛJ~@^ y?j(bҞ SM.a$FA>] Ie>ڄ|j~HY"U׭>.y ۏQlJl7K4fTefqhYד`hz', P B7Co`Wƕ:Odȁ"Nɼ>5_GA +Y Go"c_8JV>`+ٞE $f1Nq +kpkPvA䮷nM_/2'6VIxגO~hq"׬E 'JwJ 47:56R2wnjY`JQ , ? x;`NՐa Y:D .Jè\C *!lq(f"My9Ee>5RY)bD1ֹs_ 6~:~ ` 1M.uw0.*?xͽIbDHfξ-m}r_}ko'tF@ ܳۄa|^Mi[e5 +#-:$h̗(|2 #64G( V-%`epL\v Q3XVG.}%66ݘ؋S 1-H<jHwfHn S]+)lnE3( x'q<  dDt_ +0Qi‘|[y9;NdԗG}"P~Upӂidd1bߵ]ENA*PFw[5_^fFlwF,OkJ2ϔֈѝE*0l!9Ǿczw̑t& xi=VKqyqքk*1'[kGopae.Vkpل#k6op(4H -e!ɩ!NJ`VKC[>v7?`X)SpCuJo{Q4mZhCGs +Z:qgNb|^˸rƥ3pFN y\ +nF6**w"bu}V/X/Ŋ}1)U/Fba߬~ͺy~VcASeTAjL[Un&:fT&!LZ4c^sn,L%-TXE֑E7S6SeM.SU6U? +E˦8#)Q(NW(ABFNh0eb{R&ebe"xxYɫ:0_) T/ 鲤ִ\)) + d˥%$˥vE/K؏ʥd˥Һ:vDe4ܹٱ$No*-aWEMd-@7ȑ/m3ii  +)`1b$l ";RnŐDp!+Lӂ"lYCղG+|Rts +f>Ӏ"S*|1>CGs +FgSg}@b~[{㥨P3eRTǧ:RET%IuNi=qnl R=#w2 wC5{Ñ'L*:A!܏|PoI$d +"8Y)bRTo|œY S8c!b$ЊĴqu4(BdÍy?Vf](MɆ>ɖ:ҞS0>:Cuj+۽>S$G~?Pߗw T:ɈVKS1i4ZgN')},4kY +zY׳җzbP8&IE_$yN$N5Q"SkbCtUxῢ +ai+1KpЧa {js|7PPa,\u Ki$^[&qvt|GHg.pJxp,ǩX8-Ι#5tWSܯGj!?>|W5 +lڕ~-au:o#TGGٯF(faʆ`f̒C ~Θѧb-j9 LR]bb[9|4󩘊 4mX߉eѤS-_PݤqTi z#zyx\^.T-Z7^.R?XRStѿfqcn?aļTA!kݥP4cʙp..}!&la$TާbM93E-tcruG3Eٗ\v>XTm-?-l)_hjz5}jgpR@ڿr'k[@.2mk0 W̡ +*M[^%.'DI6~E΍(Ţ?aZ6J]'VnueAOo`p0H,;BM^64bN<`˟Q_Rl[Θ\p !]Sf_#?JM~JJɾ6oJRR^v9-k=N%Ծ!R}N.%a*2瀺E5lcWuاǔWTJPb)u|capKY)Ai]kkS"ZjRfsJg^|E٥=/꟯q{>޺Q .ۊ'?oFu/EJ<-R{nOg|9E ~/3YqAXhz20}ހGnen1`^Ч]+gaVg ++p8 L(vpK̦-v9O:S;=wgQ:- TjQe=X/W:Ȓ",*ZrF p|ul`cCJk| ̇r #Ȇ 2XMJ{x٤q4Ԃ ,6 +xh|!p W>[fS|%0n5T!r|ƲqVe>xglawYԧb\@će;wy=y`E؞055ir`{R5FuUkݙŵlݦ̥bk9͢>[no,YY?++F(=3&qTÔ(Fw7t9FY WP(V aϩ5Ta O}c]Bwfa{9|65݁$]66Iؖ]QoN($FFt>0jgaWߵ'Jk j6$: +K>BL7#!! ZܟyxźƂMɣ]t \`V8ʱ'5CnHIf{r^ɠ%JMZ~&ZD5kS׾.˫ Cz+plڰX!C9X (=֬ReY8ĥ&iI%۲}=z4:zGGcMS Ł# ک -hpP֕XK:0:ŕf|=Rh|s՟Ƴ׿sz'Ӷ>NdY(qζ4!<K  e0\*96BA~|J'mξNޜ-Wy?%WwI&Mz7/7f/g7< P(pwA +0,7ZsZb lX`0(U-ugٲu2rXķ;;o4 q"Rۭt7w5uQquܻj)}Sz@bo=)Y FH Q݂#_s$pލS_]޼Z-5>iME?kbqd]OĜхxBx} ez0%?: ralxyV Tŗx^0}C9~78Zu "9ڧ^NNeub`w Y4jAul=V+[yekw*[ʖ}e뱲T-tmV]; wеfa +Scza; hLjn|@*jb,@S Zݑ Zݳ3SG^*P-_~QQ>zǵhodj] f +%q%oS}fTiQ.@'9&[Z0KP10\a.Wx>40 }xIJMxз鐱%2S;۩f >U5 +g]ȞIXe 90/RS*Ey]) JTw(+W"BK9+s*~XSsՄ[f+p + ;ҕY^/OW{yj^})]Tc,0ÈK% ]HKe;9|2sXI..rq_%ɱ8pSRpTDmAUlw' R"e+]V P XIF$_ %,%%7d.w%iQbJŊcs`wnaɃE -,x]5= z +OlYJM|*VfK])iH}*MFm36ݻIħb# ,nfEI?KY&щ^TE}S~| [8X~1o{oQ1M/ ;64UJZ<FzI‘[v_S<կ_5Ktӣ("F&7)iT8M4[_+ gW̋++*O쌯 +^5aa?-^ێِA_xv'}rtKb$+n@Ebk1,DSZKLdXAN{5'[RߦKsQ!Q K%*e.>=xs%\D>ҺPo,\g% rxGBaD0ڮ0`;KppSph3۵[ ^+=C9nԜn9ܶ Oշ6 'T]B$nqM͙>kEX-rR3R$֍Ymmԓjlsmk>4m,_jk~Q,I~u@X3?x,#43@ky+ EtjC;U.' NQV˾V4+I3븩؍圾Õse޹2Бc>BO3v+itex֬..Tc :x6`5Jw 쟕*{E G78Wv4Q)63 AZg0&cĢ^OnaB(Y*JorI(82ilRPCs|Õ~%`Ȝ +RtaKj~1}1 p-~QLnbZӁ}QRr@nm@ƗȾ: ]-Z:rt+l:TeᲧ(ꊫM:|OeP_,)~C`.eA*(5'DXބh(fP0Ґ6Yf8_wϵ /EVN8xaJYiXm;¨$YapqJJ!-O{þPB^T+ +N*hR4 -5-s:F}lA?ӘbOfѨWD E-ucuG[.\X$r] ѭtHqlĝwXvXv o\@ӏ8~cc~K>ƁS1M/Gr+}p+aJؾVK@Z;[ 퀞vBZy?(g4j4E9~[ += 8 +re. hq [Ct_>PHEPf.kY0Gex]Ҫn˪nd_hZ梎̅ۍE]ɠUV +usf1~֌\4s+3g7^Փ^ |" B>l0iggM,5|u<'?/mOs{ҫTP]ͪYBY޾S`ve衩z +4 ^Cj%HP2zc"1jп7hoRhm־ƼMa\;y))`J{Z|\'|u>)t$'T!eЩQG7 C"^(xLА)%fO 6l@ƫŖ +m.ku4#UhT椲L{^bbVuSVu6\)>kdwmZx9/8DjS~zQJ$_DAS\T CXipUf>p%@(ɟ H@}`jՠO}IW)N z Ӟҟ(ˮkJż.rC[GVf_Hem#1o|Rώe%~k?amIVW (9 qОg¾ϒ*윊CCK[V|}Р s=F::[UiL8ђ:{rq4Y>Ra%z .PbAˁOؠG[9z2x^E` 78Ίƒ,k ;|Ԗd怉I楑E2fΛfDK340\S3yǛ%װ@V3yҺ?.z,m_p +y(S +pDC+,2ZG%3y>j)f|&dF̘|[ EWY𻳖.2U[LpIC\\(0-L'9m_M񗃤+PfgY*^ߍ2}Ai2LKpvr[ @p2Hx%2e*GrHfJ|Z+Xѵ G!ıWaA^ۏ.o@2Ga#MKmםbbl_6O>3e0 +/UI +Cu@$xkhAd]U׽+@LWAAas/ﰻN"4w8' Bs'XRpGixH P埼@䟙^Gmj(V[x:^4Ǻy-|<^| + ,w7^@+'8L,BaHk3&dT)pZ&3һԕbaeW+/ݥCeϕFA`{ڋ>ͬp I9dKzaM91Zf B4!j]^S)얿p:8 ^rZ8 KpZnJj(`c1$ e|h}t0n=fX'.u/5'F|TT;Ҭhƨ-qD+} {v9uo\GuT}'AHR7D[:Zۅf;V4Yj).cNݻŽ4N;oA>/JX|:puc'3iUFT5>"n-vmߓNE^eTep+u88Մ|Δ33ukgjg3 +o樿ng3|_gд MU0-睅cm9qaIi 5r~Y$?KߵژںͱOs#9@>L C_$f*kxgcman%0@7rYXɽʛqX` Km[`9 y[\ȃհ fqBeZRbd-jq6fq5wnS\ʤt>aV,(R?|fYT{f|BެIwSg Zxl7RuI;Z?FAm5%x2QGśr'Wqxz>'pj䪿2*^NkUa. 5ZqZoLk-IZ|Z>Ij,JiMk$} ؟=l"4^Pb3? +]fUNnb Iu . YxŶ2sh9EwlKؖ-ls DrBf[obF/*l7&lnsdӰHC">k?x7i?=_-~VCGqM}bpUeG#$G%Z!?TƉ!lLDru$'c4,pB#j0zN0%9p-sFdğ ܪT} KvMPeb>X9vuvioױ]; $wzτDڅ,SSh<2*BQOmej ]%S + ZиOKGb jvgwaJ#!UCa(dܩT48] xӵ V[&H}cۘY^5)kxthY̥Q.X6XN&؉)`T3<"vg$_Hs_U*mZWV`״9cIhIܿA99Ql.䢳|Z3sKƀŴ<@QsVI:&@BK%Xaַ(Y UIJFQFQߠ\XuN-,oE02P3Pe;|!;1Q%iJC۽sF;RL_zV KB0y" DvJ6 oD|QtI+f}/醋wp8w}V?hAH0! *~,A +Qs!nܟe, NlZpRO~hѾk{ER#JH%"BFj]fpc̘ iz7fP0 s_e_T;bĦ k!QutUx8F?2g@U)aC5RmʫԜ)*9J gBDt ΝOK=\u*{  +NyU7!q(H/<<3>ј(ӃPNow\UjW;W--װ!$/r+16w`yTxC稹Z OyZzˆHgX(Ӈ}5A/+ci!7]ț.Cc]Hoх:0% 0Mꄡ~:+ +{ Z(i;h6_/տSC@8[Vz!BxiVixVT6en)Ҳ̦KyYmQ A1r.SqJ2,hZ'ˤ9 P.+4$4D~j0]m;'<׹cO':ks Z@ڊ {t׫uu~ūfUUWj>fNS}*PղЇ*lߕU-=>?RB 4JTsi| :ieaH>E}bB,KBzZ +@/Xgn#v56b&kzq-H2i#2}9̩.qytTHY^)DA]*MJ^7FT' ElT}ZуrKws(ùTX̼fnےj;FJP!8\zd\f#\w^.U#1&d2h+e;S"]p\VQ6/R|C㿊o?q%4}ך\O`;I6^0,߰LJ:H)Z8`/ܜX0ofc='̷}^6bkJp-(@%2 BI4aß‐X +M&jxbFvYx3up4|iE!2 +ԅGYV r#5r^r'i].:Q)c X mh>j`a^(6oF"1*p$`CN68*J=Šoz'T +F&]W0ۊM['eC_lv#0=.9{1CP:˯|PNiY(f4Hh<n[р̝ha2{Kd طUZlxl'8i422q[AsSqSPZ(qBn+áykJlw2'LŃ5%gʻށѝEo*0/Bsczp\t ̙0߸<ʸNor$8#[kGpa7\X=XװgBh ׆ `?.}(˃%-c b4aȴ2/8RЖwj}S>`Xz9ؔx/(a6F-4mtJ:jp );rO=R=r))GF'q'H[nJ6*wL=_,}b}#/VI*/b~1Z(/f{߬7g ;&tQt0hhi+kA\LGSX%W>heʧ-|ؔb*nLOnch:Bd|ߒuв6ݖu:e3֛x-j9tw>~VNSZW|DjiuBʺE*"rrëC(]zPV[kH1Ӣq;+܀E{-ӣrh/ƎV`z= 74o88i0(Zy3I3XC_6.i4kX!Ӗj:gY{SD'~AJXцbERo a܇IDJJ8WqX2n<5!$ʣOI*9sZ5 k5Ț 5o93\83 *Ě}ߩm W`F+}c_;s.@K1sTsy_!m3\7iczΙcsѶ n/g(qe|8 󽜅TX9v\S߳A)M4 o^2|ף׸N +^o6S: RB#;k4p!2ɰZGԻ`9 `Ѓޜ7]&{h[mˮ76 ,U-㯯1VF1aLWe ).'JZ;$r$JˠsanuvZtfz\ĥ40h=;A&O_Rq#hcƌgLܱKdIB//7F˙dE n DwBRE eZS9ju$JjL*ĥrlieϫ /nҒ6r,u9D KMpcvwwZx|¸P{5w}xVcU$IM5< IȇN~4,{C"-&1dX|@quAECTz oŻ(+Kyy;tS0"Ę%s|/S"+*eFs +i;'9Er^VD!C2Z2U*A_t1gS[JcJ;6}~&q^<)~`[ QpxH"j90t0q(T`MŰ +<T} IcXw}=eS$!9t Zn:@6ZDy>⅊9g:C(cN`L{r^-Ba9^` PaN +T毯뫿ϩ=Wͦnx4lʡ*k$7 &q!j_! +/ҳ#bӰiCH@EkM/˘U@9vW1D*j`\˳Lй]S +r_$Vmf*KIWM031s./RH>{-\1@B~;!P}.sL d_>y6Q٠{y3=ꫭדg1? ͿVfEj7r1ؓZtۦӹ&ypE|t^ϣ׿szo~CǦ6#+y˩C=rd`2kP;A\dk|ǐK>\o`? Y:Cn"'1@!S#?ˑ%[#rdMrBDt$92 `EjЂX[!u7bǣXI#.PL92mۅ>#:G&᪛LZtc>hg x7*@XdȠ%]jWXQ~VR)Vdb*@.0z"B]$k^|- Vx^0]൒[Ux JJU%*m3T%pT!ӬW+jM&xaPFڤxmRo]ϲ)ڴVH=RD;s_%ْ(pxtxW?m ǔUY=" &qa0*^Cc4/zXF' ߠ  & °c@& eb|xQGoI+OCiL*4FRZũAk8\nJ.YNP Ufl$}y6!1}yd``:TD< hZ<9-J^OIۀ֋ηixbȀoUؽ'6!U4<[݂҈Y!B-QtU5dcrhiǣ|)Hr|P䳉@`.:U׽&żm7'6 \1o(;Q0>*ThRWa.5alRޤv'~HӃ]<i^ iBs/> xZ: _ePuZ^-)ڜ!H.I0P@0tQv(4y'r!zv/ rAЦ[' {JϤj~ҧjRuk6S R#\mtbMiru8d5=rUc* t[N&27?lTFMqAu:Y@׊#C6VmEP O10}7M C3jh +]B`撁 w@xM%iGp7O91{B;!:G#_"}r(tk.pĆN +΂vL5r7 ,YN?ӘYIFyHHAߕaڃRWrv%=e BɚHT4B[L(ᗑYM"d;Zi|P!9̙ ̱gڐ/3;Ta˥VI'-岼*0 T%; 8 riYo&j9mj9b9y4lHjV47YL*l*eUJ9}Nװr %tv!̨:+oQߎCdR]:ƼMa)^r:y(NصV +Uf idjo+]*s[*/< C32!|%C"%e 1dZEx!Պ*Bkua4TRq3kUv,g,g t[N c-M+n븁|%*RO"Mt<}d(H6a+FT\8?p%< +nyI_+eI< +/N "'niO|P!|&i$ZԸ[`_H]:A4f#ee:9 iP$n4%Z.ya!#\eDI[=c_nit NVzyg&ul9s.NQ3:!KC[w |нn%}rҽ6ݻtyí4 )|<Kn@ +U3k,u\ +\uPќ"\NٍYS_AC&+R0V>bWr)g|| ۝0VR1fRY .ZSyl,&j ! 4OFhʘ$q8{ +t+NU{d.(de/@<sJK2frUm~[+vѽ zPݢXUX>(+6y64+sXE7n$ku; %ϗ >0<07Ց$|>=.h}XZ#֒%-W ҡ,qM"??@Է<tsEg̾nV(fHϋ_ z*J0?1,MSnKHHֿjLO乕ꢮy!qfJ_sAUt4y%U7C[|XH,V)fqWZZ5 == ++P[eZ}Ah5>D3}z:LG謿!nAkf-YF>*t(]1=ξ®4A(};3!ge5BeYY<$!k@~78oOycFwOw܁NXҖn#QN Mѵd:A1Ɔs;.'pP`-n +d޴|:x>'u|9-PSW@(1z%rDkBp&*T5+خʇyJ w_;ږq-󃶥m<ږmJҟ˶-5- ?ݷqY7.yG_8 7$@8%,N_13 -@p1xSRӄ<@r`@gx}h\GOKʢrqQ@@b>0plY[&5Si5Q)XYw#0 GN1D|aQz\M<.iTvFr #>jh/Z\9z$=TnuELSK-_KhiN5;[wsmd+N`EGr'_n0SM>_%yf_\|Jx^!v +v J@= +Rx3-gŸgY ɠnَ#=MT{N9=PWU_R Uv^p)72U($tjb`0wk'u|9rZlLW+ueyOWRRa%WZ.< ljBeKTK3j]d%DIݰI(O S*z jY$:`zjfIiKR/c3 } dC8&+`њ!>;d*ߝLpPd +,j$S:)֊ T2d9FTd* -{2ݏ/NK}~_櫾/tf볝tgVW|Jl59j O jmHy^J Ki皐<7>z{q +|amڏ:cagara- ^ \RdVjjJ6+v| Lm*컜iԴ?ET억ysQǰ B,NNN+r!)yvjECm˩ y 5帜@V3(r-Li)ځZ> dj ץvkh0wT,;X;qF܋̀6Tpuv&7; @Y69\ +x[60o.'zy =6|nj(ȁpv"E,/)et2r+T,!p@Z9PB`0jBS XV29H9$`r;E$(b(|E=3` $~}9;|4gCPgq9. c?S=86SmYM6IAN 뚵TL,r3K?=F͊#~Jʪi'IyTyx1m+M_a/Gvm|BdܝTgeO.v47Du +R+o\qH%Ox31' #Y`5ۘ;YAؘ +amHQwV}('ቜh)(fQ,AɯJrSzA󼈉Y$*#dL$#Pa@#] +i+$?*3@ԸH.j_{" +,D=9s4- } :?*gBe$Z]DaLZ:SLEeCxk%FD9v>uۯ9}W(=?+eCXI$M$HB^ߥ &Mӄ4|`7 {H +,jd,>z/،Eрqΰ42|r45IC? ASxiH/s2Y!-&܎4hROԞ͇i!|F(V?[UOw>A}`?s+~vu]q&)LH8{-I0R8A 6 |1\٧0I,t{{5a);>L[}hOO%n7],(O}t<E}bd D.4!TnW-3{w= 7yO};cPIGh>,6i4,HWyqm s-TeEVgg~D{[\!u݋xdS[ +B:Fb8q@w2O!m;~@l34 HfCz3bJt;Jtk;lJ:ysFOH$D5A\Mr+ՊU-EReMAWrwshԢ?I$&U@f,% クO`8a-2\+-7MYrPeZ> Wqb!`pu? P3$G;2M!5+HO7A&`ڗߥ$Q#;T?p}xlhjEX@7 1=DњJ׆!\̺~~G5OmP>ofw6>`ETf5U^g,niK4 e&Bfph^6a D)!(F5ۂMԖN$u@Ԥ"cLWҚD- BW7p@Rj")3I) Lk,2`"wp5]Fj=&Lu*FTyV(o`( Iwq-jؽyFt\>bgGi[ztwr=\s֓jq,U@\AV[0o^r?Eft6`PLӊI8"9}s8śfQF&j,L%;G7ܢNd$;NI_[ScV`YYY5a̗ SH:.sŶjN!e J'VjAF:0Jb LbŚr+beoʢwXEV 9b󎽣lu쏹̹U_&jMUu`?HÕQZig;!pCtcF4'Bk؞?ȞCa1QKw Т4A6 V`2%s Aޤ4?l s6ݗ@]0k:q\+މ+M|Y?`ҫ~9RKpNNLI|;mU~fG>+9K `ڇ5`h_`i₉\Bα +)9aY:RJ]_L'4qC]fncpA.X#7ʌgN17HTO[j^-/j^38׳Z&*b\b<J-|AOR-nhQ\iamu^MH^7[yR4D)&(Rq'hǰOq}+'(lKϘfh .`MP ^ GVGkz> :l$ Zm9Y>Nq  7p̫7]RhRhW 0.BNpX l(Gm%x4X)Wz3H)xm CPR3Z ,G?qBg{h{eo~Z|VL_ %߼)ڏ$'7jz7G 20N!-wRϏ: 7*k3˯&{'<}d@̰lGSb@9~i-n,I*$P\l3-1^I-w\}Tlcmbx8{1I^[a4'Թ7Ej :f!y ~J î1|>Ϫfhu=zm6 c]E ԙKjgRRt)\Y?0w +;=6!›گ3^j"{~5ozu?_qw +)c +.)w!YBQ֝@l8$ Ћ5N}`+bn5e,voCl@o,QB8&*F.rWAiQVzjJsU(|د%xz)^*a%n%E`uX=bEXq9C@H!_q'1k3 50.R, BW x~mżzΟT? -ZEkr3b]6,'?kNJQn7ƓO5G +io~CǦöLqϏEi)C&Wℚ7E!j ify~AK)GО K>t\pߠ:Y:]trw)R)߬/JyJyRFê1x! 򡔗Mh}o,a w˲RRW0x~})4kJJyY &J *ɸ`kJol6z$_izi:;cls8\?\ +2/xH\ R.Ť\]Rj=Vݲ6*ҟL42+W>&jIX8(JoޥrQmXLIK_0}G$tIN˨3 @FRd`ocͽ()6AgHkenFy57Qq +PZ߶&Ű5HTOLOT'Lnw۟_nV^t-HBG~p8KC>TncejRH+Re l +%¦YOε9!*rY}Md YY]Qگ}S0p0 +QaKmA$&eA$ V2RRrUV4O=m-Vm/[^})TU!hSZGjS;VkTQ^+%u8)8zIoB ǴR bKd.''9^0ycW)$S$43фƲJCz(\f}|vn:@$Ƞ.d1)^usR+IV\`^?Dg +vP4oRQ`* ty~œJ:Tn1K=nH1ms :1!CS 5iMԛqqr>ShkDG"\ڣH`Wy*Jaݯ+HG>j$XUjIK,Hta=߬ Ӆz/ ø)2[?ϔ!/:ȊGJqYB> e{TLV8 Bk0 L2BX*dzTj\k0Gmx/qQϋ>}^US-]iaP+n k05&HgxϽWRJfX݄m7 Pb0xcnH6=vgy`g+\c3K byodB226aAecÚ Lk*J6x-\U9}-Iu~f)b(>K瀤UfrOʅ%iͲ BޛBKRXI:$ԝ.T7T,o +-Ga2/r +[N< IJeb+_@ef`wKmAWq',Y!0B&QVЦ6`Ӷ_67LJJu<(6CSaީ0ܗq_>B}J'sC0wr]Ǧۭ(hgKMѿI"KӬ[Plt'GʿAߍaur#rtmbd]}n l"=/GZI4K6;Zi|P?9,i G_f633JA%hMo*eyZ);AR j7ARD11~@T)nKs+jeg T7AV)BiX*K:YuR7 (˝B)Ǫo@Wsɓ-xԜ䬷/uF!)Ciǟ4ZdBP?AEIO8dQ`IXw- $^ )\!WIjg9u3Xh߼< BxuM2E^{!>$(ƴ"k!{-%nVa(΢V[aZa^|Ny67/4uK98n@yeea\r99l^ ַ`*K ?| j\Җ@=оh1Vz| ]=:}~!YW(6^me#$dǤK(4}g>us)58@zh7A'OmmeGY*߯vg_ӊ9]ayG u+-td*1 :O)WEH;"q@$ؼ)) +.*nhU`)|@@n'v.952ѧfP{>N:+-A@qR3 ay>CJ/xjs}@ oJ6;p: |5֌8[ +FӠ%yKi @đ nR.nzM|VCUkFjF\R6 CzͦĎD+N/1$u<2ս")w5no8Ȓq 3xc9A۶!}+3vWȝ?vG{>7=&a_E>~zVHC}A)2!~ugeA[eD7ʈnxq;e߇khKlۼ%.[m\qh@dū0m[a5)UxI^d+LaIq `* cy5uGNZ`8UmżIz!~V OZM-_Z\ *Eff+mVV5eگC5V'4FbްrkX@*!#!+_eOΟ7<| SXm^${C9GĜ 4ӛ"ZXx9hq\dn!ܕjNe8PGњ^J9^2WUo:޼<w {7usc'e;>/>? O^+uTwQ/dpWeuY q`V`}`=,Nch^фR]L K~/__ 0X`PJRȓnJS['rhk.&n aP6g*r d:]3PfѶ K S8W!+Uzs~A(Œ +"CQ4`iZ{$BV.ZŠHv$ Yļ9zŦo?[e j&Mfmn*i |k<ag|/;+d}\dq@_WI$7)|' 41 Ed.?{SЈ}Dzgo+YNv5?`Q.mߤ +TdM}?joGD;炡6c_oN&aV`aWoqYI<){х8[El׈+UW<+zM] ?c='pk5-Y^~l]{M'vX :eP($e0]w$К,f&\w~ZȪZV!lg5 C>Y7^4S k-W1X r[~{pDh +'YluGG̖lYg. >D3}vC^l66gvQ6\*qGk}:ɧq!ҿng_a5k:73qkVeeHfX rVݞyҮ7$oOyGwQOwXNLsE[+ := @sVma3M -q5k7 ͦ!˛`(4b|=)Jh20O[U̖_:1Ət kZw ݅BQy"lO\:cT8xt?jYѲZ8Z~,},+-K×- ?nY ,zzYѴ2:'2ߎ9! fM=2`j!{r;^h+iNvOn;ZXL.V+HDN`5`ʷ8K*Xq{x>g:x6^^̉eS,wh;z +~, /NFcS8F=Za<,f! |_M(r/GE\9T2-VZ ea-_ݿ7{Ҝ ;{=7{T5+m FqT'g܌`: _%ef_\|Jm^!M<&^eC^fjTft҈a Wl3a!1󆳾ppS +~w~~}~ӾYZ Mz6 8_R_$[@&lrƊF”&B*E|q>(02 h<33VtV<[ymFWs$j%\s!Ő̰3p .jEe1ZZ;Ro]Y9׏RT#Tm-T}`9te`@\NKA}˫mnjkKsWS\W6&S]قו=]U˄W ]iH飵 ̫60vC?C( "L+- u;LmfZ +J`hԄ }uEE~ b$G%x ldIϦ +e+ǩSmW}uէ@Oz,ȉ@.Ņ6*`QcE?]*J;D*up_qfrJN*$jfP":4*UæR7dyX^͘QwTT6TW]YTZԕBW_uev/AbSFS lʰw!w (p4%uy2Ox>_\eu:?_VRVQV{,,_/s]%p%E:XTsoЏNWx#D~dBGӬM8´R7M!_(;"#iD?iG 2 +-g<*S2I`)w +UδmbBwkEQb#TH0YhmiI3}֞*z sVِŏ*@lJ€60d1nj&/qhcv@.$ord +~G z["k~Ɗ σ|nzᢷkpcUqAY Y"=i qP Ȱ[Mu`C*B]m򾒃Y4P'K7/6Z06px:AJ ZJ%3^ k0H]ҕJꟿɯHrxW#>b%Ȉ7NAN/߻5XW )@[ ݗ-Wc`!o7_0(X0 2A~!Q.;dLxzsXPt,ꓮUbǣJ6+ٸ?uWLTUǣBn%~q.lE GԲKwK +;7>661JwEbP u*p0'T׈i|?|D _nPcQ1#Xc76ՅTj@8`?- kIˢ$Ű KU\% zbn94ԽS?<({UGGxW!I<9ax<|}x1 v>Zתe~*Wwz$ vtf\y^ka.ˑe R%0}WاrHG˦j Y?:jԆ!,Y"Mp(Bzi%PwIg>M5hMJV[(Y(]0:¤VۧDgd|  +ĭ#W{ø kQ'U*ŋ[/Vu+ͻ?bE 7y/}mCG&67*ym լNe\۶:Dt #i3D̀|1/~_&"uRKz}dU[2J&uf!эBt>ɤ}'p)2%@/)7jLd?LdkFSxK&kIsOHYC%D1@\UW0ALݐ⾒-EQ0*Hr״jr7Qq7gB(XL˽B 3T'[aƗ P$(3}8(k#W_(yƐ758\'R6kzɂ':{z_ ~87/_ӿ=(~@cI[j|4e]oGOo ^+fmPoziPSoܛ>9iF!)AMd˛R閶J!I2gBc^ai#KhhАe}rlhGϊ8yLyGPȤ!5 \)nVHWj IH2)7tu gɌ*LS D2tk[YT?^HI' ~^ܥW}9RӋqNNI|;mU~fŃ}Uq>y?X`Zoű? ꃅQ_|Oܓ-7ZJKj "iF3Rx^>PlAyi5t3mH68<݂0|(VmkoJ.(脮k[Ƶ~p[E_uB8 2+0W+t\! -%{ץЫLJBҲp 5},UU:uuP zguPuP:Oik0:Hc9g#Q.*$##RWWܳ |N^so}a41d.[0>NHCP&>II("!ݹhW Ie2$Ji{ւDUOj2 aʅ[u 쬉)KLՙ^RQb%[BM&x <^䔶&7[ $KDkBTn^ 9ͦPDTVƒevTl:@)$s %F_8w + wmS +7:sg߹ɝ^NrϸhC6C6:dS  ReJcԸ!Q܀wǡ< 4 v4DTer2@(G}2@9)[9-cTDZ/:B"B>y0gQ?~0Ohݳ`|:Zս R C2=f͆㆒oVn@qoTZP2rxt n)-<>'{,NtSB PAB'_74JG* Ֆݕv`=n𫨻 m4aH$^0 =ψa>L,իYT$v7ˆIagNٙ:t+CWL9m( ڭK=qjFtI|Vn+U%}`Wq gnmMA 2wg %QmxZQo?Nyu1wq2CTUH;k1X8}-Z?Ƨ#% +endstream endobj 30 0 obj <> endobj 43 0 obj <>stream +8;WRobmhND%#*R?Pp.N[=$boc&ki9aQJfh9V_SGIGT@d%<2l?.E0W?,e*!@Q+sK!% +C%hFMqa9O3@6G.)[Q9sInuB$BI,FKekjEgY=-b]"Nb9Sr,pC<-i6$fj.;Lf4-d-=T +ed0t!_B6&,(+$We]Wq1mqV4R5CBr@4NaF>1X(-@'.5!Q'1VM#/oQlBD@dRMVQhNt9 +3!""SYEVPVbND[k'L@"Q?2hhG'Po6U_!L[E%EK%LecN>R:N])[:p\'[Q\:RAJ2GjO +0+fPc)+OS6D*&^/07,dLhr"2nO7YKXN2r#GqYD!hH(ap(8C+t3co:Ngri>X]Fn0_V +$[QC_~> +endstream endobj 45 0 obj [/Indexed/DeviceRGB 255 46 0 R] endobj 46 0 obj <>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> +endstream endobj 38 0 obj <>stream +H˩@'EAoTЇ$I$I$I$I$/}/xƣhGx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4GxO_xO?{86{Xqc8zXqc996zXqcYu9yXqcyU86yXqc58xXqc=96xXqc]9{qc}8&{c8zc;9&zc[q9yc{Q8&yL1c 1C8xL:<^s x15,{m[)$I$I$I$I$Ig;Q +endstream endobj 39 0 obj <>stream +HK@ D((04Y:AEX~&„crI?rnR95)DNL"IU$=)d'u0TFRHfRIL#<2;LN"25Df&DOTDMtD9(#ihLđ:;G&ٞ8"KdklLL+5E>'YOyx#os5qG{1GX|h6h6h6h6{ŝ0v`F_ +endstream endobj 40 0 obj <>stream +H1 EANX^+H[8I$I{笛Zp6 += np8:ruچ\6*!W ]q޷>von.;1WsiNjKNsE=\ ^4ܥKMsڸP.֓$I$Im +endstream endobj 41 0 obj <>stream +H1 N@f[KL\$I$IJv5*Vv,6`i bD#;H`-wFMkIljgZk _ m5fXCڦX_+Z%I$I= )& +endstream endobj 42 0 obj <>stream +H1B1 Q/M%ɇLl+ +ADDDDDDDLz<\Ziz *S4 t| *cTK'tCB 7T9XءVs?T=4ʏIЏ ZwA7A68qB'Z\0DӁ|Ftz +[(ѷW +endstream endobj 34 0 obj [/Indexed 35 0 R 1 52 0 R] endobj 51 0 obj <>/Filter/FlateDecode/Height 146/Intent/RelativeColorimetric/Length 475/Name/X/Subtype/Image/Type/XObject/Width 117>>stream +H[q0D  AAA$uG~d5=l׍B!B!oeSNߒ}|_Z?ex J@ԕFti䇶t䧶$m`4V]:MЗ:G}͚b4Bu鉐v1 !Fc!n4#uM1f4kH(Ve'Jzh35i5 &#E4EDzNvt)F#*F#*F!p b,ciWw{ڦj0t߫UWZ &(KJ\u-ͥrӋI[*>K.R;/tJR/*H(JR#*HRFږ`MJҦT6Z.ՠUiUIR-NZJ58i.zeHw{M T +M UJɌPJ鿕B!B!|y' +endstream endobj 35 0 obj [/ICCBased 53 0 R] endobj 52 0 obj <>stream + +endstream endobj 53 0 obj <>stream +HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  + 2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 +V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= +x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- +ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 +N')].uJr + wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 +n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! +zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km +endstream endobj 50 0 obj <>/Filter/FlateDecode/Height 146/Intent/RelativeColorimetric/Length 286/Name/X/Subtype/Image/Type/XObject/Width 109>>stream +HAm0@@0C0CX`!,@0@Cĭ׭43m$KDDDDDDDDݖi]nTU[Rb}iԨ=SZRլ<$yb'<[c`````iX>helm,橅VKZzj[fOM iWUꩥF~W+ؔv\9)jSZ԰ެ&=ӛΊ('{TM+n +endstream endobj 49 0 obj <>/Filter/FlateDecode/Height 146/Intent/RelativeColorimetric/Length 338/Name/X/Subtype/Image/Type/XObject/Width 111>>stream +HAm0FaC0@0f1VvZwTO3mDDDDDDDۯі+ׇԕNK3w}+^pp<~}1Wΐ]NwaqY}JLw.qa)vFfLsЁK2џ `4-e\'{n9fz?2_dNBp?Ӵ^d5NY0^dUn׋KY]dun9=U;NiY\d N"kqzFNς"kqz YifN[dMq3`Y/J +endstream endobj 33 0 obj [/Indexed 35 0 R 3 54 0 R] endobj 48 0 obj <>/Filter/FlateDecode/Height 137/Intent/RelativeColorimetric/Length 302/Name/X/Subtype/Image/Type/XObject/Width 138>>stream +HKuP EQA00@(B@gu~?Jl3౹En+8&:*VdYxF&odaxG'ىdrDD&!ILdbDE'aI\dpDF&Ild`DG'I|s"M$3D:&H{4'Hk4&DH#Wmb"OԑӉ>stream +5T +endstream endobj 32 0 obj [/Indexed 35 0 R 4 55 0 R] endobj 47 0 obj <>/Filter/FlateDecode/Height 328/Intent/RelativeColorimetric/Length 714/Name/X/Subtype/Image/Type/XObject/Width 272>>stream +HKUQ0 O +R`wϧ'TI$I$I$I$I_s3O9+Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4Gx4G߾=!<^q|'9>ǣ=0t9{<1y 8&{채c8z걌c: 9&z豔cZq9y汜czQ8&y䱅c18xⱍc>9&xౕ~{lc79q=Np\q^3zǥ88qA=Nr\q>y4e98qouO?$I$I$I$I$}~ 0w! +endstream endobj 55 0 obj <>stream +@@@ +endstream endobj 27 0 obj <9 1)/Type/OCG/Usage 57 0 R>> endobj 56 0 obj [/View/Design] endobj 57 0 obj <>>> endobj 36 0 obj <> endobj 37 0 obj <> endobj 31 0 obj <> endobj 58 0 obj <> endobj 59 0 obj <>stream +%!PS-Adobe-3.0 +%%Creator: Adobe Illustrator(R) 14.0 +%%AI8_CreatorVersion: 16.0.0 +%%For: (\715\750\752\750\762\750\755 \700\753\745\752\761\745\751) () +%%Title: (РСМ.ai) +%%CreationDate: 4/30/2019 1:25 PM +%%Canvassize: 16383 +%%BoundingBox: -7 -292 265 36 +%%HiResBoundingBox: -7 -292 265 36 +%%DocumentProcessColors: Cyan Magenta Yellow Black +%AI5_FileFormat 10.0 +%AI12_BuildNumber: 682 +%AI3_ColorUsage: Color +%AI7_ImageSettings: 0 +%%RGBProcessColor: 0 0 0 ([Совмещение]) +%AI3_Cropmarks: 0 -256 256 0 +%AI3_TemplateBox: 128.5 -128.5 128.5 -128.5 +%AI3_TileBox: -163.6602 -542.96 419.6602 286.96 +%AI3_DocumentPreview: None +%AI5_ArtSize: 14400 14400 +%AI5_RulerUnits: 6 +%AI9_ColorModel: 1 +%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 +%AI5_TargetResolution: 800 +%AI5_NumLayers: 1 +%AI9_OpenToView: -271 15.6641 3 2502 1274 18 0 0 9 117 0 0 0 1 1 0 1 1 0 +%AI5_OpenViewLayers: 7 +%%PageOrigin:-178 -524 +%AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 +%AI9_Flatten: 1 +%AI12_CMSettings: 00.MS +%%EndComments + +endstream endobj 60 0 obj <>stream +%%BoundingBox: -7 -292 265 36 +%%HiResBoundingBox: -7 -292 265 36 +%AI7_Thumbnail: 108 128 8 +%%BeginData: 11292 Hex Bytes +%0000330000660000990000CC0033000033330033660033990033CC0033FF +%0066000066330066660066990066CC0066FF009900009933009966009999 +%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 +%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 +%3333663333993333CC3333FF3366003366333366663366993366CC3366FF +%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 +%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 +%6600666600996600CC6600FF6633006633336633666633996633CC6633FF +%6666006666336666666666996666CC6666FF669900669933669966669999 +%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 +%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF +%9933009933339933669933999933CC9933FF996600996633996666996699 +%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 +%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF +%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 +%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 +%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF +%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC +%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 +%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 +%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 +%000011111111220000002200000022222222440000004400000044444444 +%550000005500000055555555770000007700000077777777880000008800 +%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB +%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF +%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF +%524C45FDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDA0FFA8FFA8FFA8FFA8FFA8 +%FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 +%FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8 +%FFA8FFA8FFA8FD20FF27F8F827F827F827F827F827F827F827F827F827F8 +%27F827F827F827F827F827F827F827F827F827F827F827F827F827F827F8 +%27F827F827F827F827F827F827F827F827F827F827F827F827F827A8FD1C +%FF7DFD4EF87DFD1CFFA8F8F8527D527D527D527D527D527D527D527D527D +%527D527D527D527D527D527D527D527D527D527D527D527D527D527D527D +%527D527D527D527D527D527D527D527D527D527D527D527D527D27F87DFD +%1CFF7DF8F8A8FD49FF52F87DFD1CFFA8F8F87DFD49FF27F87DFD1CFF7DF8 +%F87DFD49FF52F87DFD1CFFA8F8F87DFD49FF52F87DFD1CFF7DF8F87DFD49 +%FF52F87DFD1CFFA8F8F87DFD06FFAF8585858B8585858B858585AFFD1DFF +%AF858B85AFFD09FF8B858585FD07FF27F87DFD1CFF7DF8F8A8FD06FF1414 +%0E140E140E140E140E140E37FD1CFF360E0E1436FD08FF850E140E37FD07 +%FF52F87DFD1CFFA8F8F87DFD06FF6114151415141514151415141514AFFD +%1BFF3D0E15143DFD08FF3615141536FD07FF27F87DFD1CFF7DF8F8A8FD06 +%FF36150E140E150E140E150E140E1585FD1BFF36140E1514AFFD06FFA914 +%0E150E37FD07FF52F87DFD1CFFA8F8F87DFD06FF3D0E1514618485618560 +%3714150EAFFD1BFF3D1415141561FD06FF850E15141536FD07FF27F87DFD +%1CFF7DF8F87DFD06FF36140E1460FD05FF14140E1484FD1BFF36140E140E +%37FD06FF5A140E140E37FD07FF52F87DFD1CFFA8F8F87DFD06FF3D0E370E +%85FD05FF3D14150EAFFD1BFF611415141514AFFD05FF611415141536FD07 +%FF52F87DFD1CFF7DF8F87DFD06FF36140E1560FD05FF14150E1484FD1BFF +%36150E140E155AFD04FFAF0E150E140E3DFD07FF52F87DFD1CFFA8F8F87D +%FD06FF6114150E85FD05FF370E1514AFFD1BFF370E1514150E3DFD04FF61 +%151415141536FD07FF27F87DFD1CFF7DF8F8A8FD06FF36140E145AFD05FF +%14140E1484FD07FFAF611437143714371437143736A9FD06FF36140E150E +%1414FD04FF370E140E150E37FD07FF52F87DFD1CFFA8F8F87DFD06FF6114 +%150E85FD05FF370E1514AFFD07FF850E1514150E1514150E15141514FD06 +%FF3D0E3714151415A9FFFFAF14151437141536FD07FF27F87DFD1CFF7DF8 +%F8A8FD06FF36150E145AFD05FF14140E1585FD07FF36140E150E140E150E +%140E150E1484FD05FF36140E150E140E61FFFF5A150E140E150E37FD07FF +%52F87DFD1CFFA8F8F87DFD06FF3D0E150E85FD05FF3714150EAFFD07FF61 +%14150E373637363736150E1514AFFD05FF3D14151415141514FFFF610E15 +%1415141536FD07FF27F87DFD1CFF7DF8F87DFD06FF36140E1460FF5A8560 +%850E150E1484FD07FF36140E1460FD05FF14140E1585FD05FF36140E140E +%150E1484FF36140E370E140E37FD07FF52F87DFD1CFFA8F8F87DFD06FF3D +%0E370E85A9150E150E1514150EAFFD07FF6114150E8BFD05FF37141514AF +%FD05FF611415143714150EAFAF1514155B37141536FD07FF52F87DFD1CFF +%7DF8F87DFD06FF36140E1584AF0E150E140E150E37AFFD07FF36150E1484 +%FD05FF14140E15A9FD05FF36150E1414150E1460850E140E8514140E3DFD +%07FF52F87DFD1CFFA8F8F87DFD06FF6114150E85FF370E15146185AFFD09 +%FF610E150E85FD05FF3714150EAFFD05FF370E1514613615143714151437 +%A937141536FD07FF27F87DFD1CFF7DF8F8A8FD06FF36140E145AFF5A140E +%1436FD0BFF36140E1484FD05FF0E140E1484FD05FF36140E145A850E150E +%140E1460FF0E150E37FD07FF52F87DFD1CFFA8F8F87DFD06FF6114150E85 +%FF850E371415A9FD0AFF610E371437A9FD04FFAFA9AF85FD06FF3D0E3714 +%61A915141514370E8BAF37141536FD07FF27F87DFD1CFF7DF8F8A8FD06FF +%36150E145AFFA9140E150E61FD0AFF60140E150E1484FD0DFF36140E155A +%FF14150E140E1585FF0E150E37FD07FF52F87DFD1CFFA8F8F87DFD06FF3D +%0E150E85FFFF3615141514FD0BFF14151415143785FD0CFF3D14150E61FF +%850E15141514FFAF150E1536FD07FF27F87DFD1CFF7DF8F87DFD06FF3614 +%0E1460FFFFAF0E140E15A9FD0BFF36140E150E1484FD0BFF36140E1436FF +%A9140E150E61FFAF0E140E37FD07FF52F87DFD1CFFA8F8F87DFD06FF3D0E +%370E85FFFFFF370E371485FD0CFF361514150E1561FD0AFF6114150E61FF +%AF1415141585FFAF15141536FD07FF52F87DFD1CFF7DF8F87DFD06FF3614 +%0E1560FFFFFF36140E1514AFFD0CFF36150E140E1560FD09FF36150E1436 +%FFA9140E1514FFFFAF0E140E3DFD07FF52F87DFD1CFFA8F8F87DFD06FF61 +%14150E85FFFFFFAF1415141561FD0DFF5A1514150E155BFD08FF370E1514 +%61FFFF5A150E61FFFFA915141536FD07FF27F87DFD1CFF7DF8F8A8FD06FF +%36140E145AFD04FF370E140E61FD0EFF5A140E140E1436FD07FF36140E14 +%36FFFF850E0E5AFFFFAF0E150E37FD07FF52F87DFD1CFFA8F8F87DFD06FF +%6114150E85FD04FF8515141536FD0FFF8515143714155AFD06FF3D0E3714 +%61FFFFAF6136AFFFFFA937141536FD07FF27F87DFD1CFF7DF8F8A8FD06FF +%36150E145AFD05FF14140E1584FD0FFF5A140E150E14A9FD05FF36140E15 +%36FD08FFAF0E150E37FD07FF52F87DFD1CFFA8F8F87DFD06FF370E150E85 +%FD05FF370E150E37FD07FF85366136AFFD04FF85150E1514AFFD05FF370E +%150E61FD08FFA9150E1536FD07FF27F87DFD1CFF7DF8F87DFD06FF84615A +%6184FD05FF848560855AAFFD06FF36140E0E60FD05FF14140E1585FD05FF +%8485606184FD09FF60855A85FD07FF52F87DFD1CFFA8F8F87DFD1CFF6114 +%150E8BFD05FF37141514AFFD1EFF52F87DFD1CFF7DF8F87DFD0AFFAFFD11 +%FF36150E1484FD05FF14140E15A9FD1EFF52F87DFD1CFFA8F8F87DFD07FF +%A85F11343483FD0FFF610E150E85FD05FF3714150EAFFD1EFF27F87DFD1C +%FF7DF8F8A8FD06FF84110A110B110A5FFD0EFF36140E1484FD05FF0E150E +%1484FD0EFFCAA0C3A1C3A1C3A0C3CAFD06FF52F87DFD1CFFA8F8F87DFD06 +%FF3A0B5FAEFF84340B8AFD0DFF610E371437366137613637141514AFFD0E +%FF93BB9ABC93BC93BC93FD07FF27F87DFD1CFF7DF8F8A8FD05FFA80B34FD +%04FF831134FD0DFF36140E150E140E150E140E150E1484FD0EFF9A9AC3A1 +%C39AC2A19ACAFD06FF52F87DFD1CFFA8F8F87DFD05FF841134FD05FF1134 +%FD0DFF610E150E1514150E1514150E1514FD0FFF9ABC9AC39AC39AC39AFD +%07FF27F87DFD1CFF7DF8F87DFD05FFAE0B34A8FFFFFF5F1134FD0DFFA861 +%14140E1514140E15141414A9FD0CFFA87D526FA0C39AC3A1C3A1BCCAFD06 +%FF52F87DFD1CFFA8F8F87DFD06FF340B5FAEFF8334112E76A8FD04FF835F +%3484FD1CFFA827F8599ABC99BC99BC9ABC93FD07FF52F87DFD1CFF7DF8F8 +%7DFD06FFA8120A1111110B5FA852F827A8AF11110B110A34A8FD11FFCACA +%A1C9A1CAA1C3A17D52A8FFCAA1C3A1C3A1C3A1CAFD07FF52F87DFD1CFFA8 +%F8F87DFD07FFAE5F11343484FFFFFFA8527D341134AE843A0B34FD11FFC3 +%92BC939A93BC9A93CAFD13FF27F87DFD1CFF7DF8F8A8FD0AFFA8FD07FF83 +%1111FD04FF340AA8FD10FF9A9AA0C39AC39ACA9ACAFD13FF52F87DFD1CFF +%A8F8F87DFD12FFAE0B5FFD04FF5F1183FD10FFC39AC3A1C3A0C3A1BCCAFD +%13FF27F87DFD1CFF7DF8F8A8FD12FF841134FD04FF340A84FD04FF363714 +%3736371437A9FFFFFF9A9A9AC3A1C39AC39ACAFD13FF52F87DFD1CFFA8F8 +%F87DFD08FF8A585F59FD05FFCB830B1134AFA85F1112277DA8FFAF151415 +%0E1514150EAFFF7D526F93BC93BC9ABC9993CAFD13FF27F87DFD1CFF7DF8 +%F87DFD06FFAE340A110B0B0B84FFFF27F852A80B110B110A1184CB27F827 +%AF0E150E140E150E158452F827A1C39AC39AC39AC39AFD05FFA7CAA1CAA8 +%CAA1FD08FF52F87DFD1CFFA8F8F87DFD06FF5F0B3483AE5912117D27527D +%FFFFFF5F34345FAEFFFFFF7D525237141514371415147D52A8A8FD0DFF9A +%BC9ABC9ABC9ABC93FD07FF52F87DFD1CFF7DF8F87DFD05FFAE0B11A8FFFF +%FF58110BA8FD0FFFAF0E150E140E150E14A8FD10FFBC9AC3A0C3A0BCA8BC +%CAFD06FF52F87DFD1CFFA8F8F87DFD05FF831134FD04FFAF0B3BFD10FFAF +%150E151415141514AFFD10FF9ABCA0C39AC39AC399FD07FF27F87DFD1CFF +%7DF8F8A8FD05FF840B34FD04FF841134FD11FF0E140E150E140E14A9FD0E +%FFA87D6F9AC39AC3A1C3A19AA8FD06FF52F87DFD1CFFA8F8F87DFD05FFAF +%341184FFFFAF340B84FD06FF84845F84FD06FF7D1514371415368536AFFD +%0DFF52F85293BC9ABC93BC9ABC93FD07FF27F87DFD1CFF7DF8F8A8FD06FF +%83110B3434340B34A8FD05FF34110A110B34A8FFA8F8F87D14140E150EA9 +%A9857D2752A8FFFFCAFFFFFFCAFFA852277DA8C399BC9A9A9ABC9AC3FD07 +%FF52F87DFD1CFFA8F8F87DFD07FF833411110B5FAFFD05FF341111835F3A +%0B34525227A8FF150E1514153685FFFF7DF8F8A193BC93BC99BC9399A8FD +%13FF27F87DFD1CFF7DF8F87DFD08FFA8AE84AEFD06FF84110BAEFFFFAE34 +%0B34CAFFFFFF8485852F2E8BFD04FFA87D44BCA0C39AC39AC39ACAFD13FF +%52F87DFD1CFFA8F8F87DFD12FF840B5FFD04FF841158FD07FF5252FD07FF +%C39AC3A1C3A1C3A1BCCAFD13FF52F87DFD1CFF7DF8F87DFD12FF831158FD +%04FF840B59FD07FF5227FD07FF9ABC9AC39AC39AC393CAFD13FF52F87DFD +%1CFFA8F8F87DFD09FF8384A8FD06FF840B1284FFFFFF341183FD07FF5252 +%FD07FFC393C39AC39AC3A1BCC9FD13FF27F87DFD1CFF7DF8F8A8FD07FF83 +%0B110A1134AEFFFF27F8525F0A113483110B11FD08FF5227FD07FFA19393 +%9A939A939A93A8FD13FF52F87DFD1CFFA8F8F87DFD06FF840B1134833411 +%1283272752FFFF5F0B110B1134FD09FF5252FD10FF522752FFC3BC9ABC99 +%BC9ABC9AFD07FF27F87DFD1CFF7DF8F8A8FD06FF0B1183FFFFFF34110BCA +%FD05FFAE5F8384FD09FFA8F8F8A8FD10FF52F8279399C39A9A9ABCA19ACA +%FD06FF52F87DFD1CFFA8F8F87DFD05FF841134FD04FFAE0B5FFD14FFF8F8 +%A8FD11FFA8A86FC29AC3A1C39ACA9AFD07FF27F87DFD1CFF7DF8F87DFD05 +%FF840B34FD04FF841134FD14FF27F8FD14FFBC9AC39AC3A09A9A9ACAFD06 +%FF52F87DFD1CFFA8F8F87DFD05FFAE1211AFFFFFFF5F0B5FFD14FF527DFD +%14FF9AC3A0C39AC3A1C39AFD07FF52F87DFD1CFF7DF8F87DFD06FF58110B +%8383340B12A8FD14FFA8A8FD14FFBC939A939A939A939ACFFD06FF52F87D +%FD1CFFA8F8F87DFD07FF34110A110B1283FD2DFFCAFFCAFFCAFD09FF27F8 +%7DFD1CFF7DF8F8A8FD08FF835F3483A8FD3CFF52F87DFD1CFFA8F8F87DFD +%32FFA8527D527D527D527D527D527D527D527D527D527D527D27F87DFD1C +%FF7DF8F8A8FD31FFA8FD19F852FD1CFFA8F8F87DFD31FFA8F8F800F800F8 +%05F800F805F800F805F800F805F805FD04F852FD1CFF7DF8F87DFD31FFA8 +%F8F807150E140E140E140E140E140E140E140E150DF8F8F852FD1DFFA8F8 +%F87DFD31FFA8F8F80E151514371415143714151437141514370E05F8F852 +%FD1EFF7DF8F87DFD31FFA8F8F80D150E140E150E140E150E140E150E150D +%F8F8F852FD1FFFA8F8F87DFD31FF7DF8F80D141514151415141514151415 +%14150E05F8F852FD20FF7DF8F8A8FD31FFA8F8F80D150E150E140E150E14 +%0E150E150DF8F8F87DFD21FFA8F8F87DFD31FFA8F8F80D15371415143714 +%15143714150D05F8F852FD22FF7DF8F8A8FD31FFA8F8F80D150E150E140E +%150E140E150DF8F8F87DFD23FFA8F8F87DFD31FFA8F8F80E151514151415 +%141514150D05F8F87DFD24FF7DF8F87DFD31FFA8F8F807150E140E150E14 +%0E150DF8F8F87DFD25FFA8F8F87DFD31FFA8F8F80E15151437141514370E +%05F8F87DFD26FF7DF8F87DFD31FFA8F8F80D150E140E150E150D00F8F87D +%FD27FFA8F8F87DFD31FF7DF8F80D1415141514150DF8F8F87DFD28FF7DF8 +%F8A8FD31FFA8F8F80D150E150E150DF8F8F87DFD29FFA8F8F87DFD31FFA8 +%F8F80D153714150DF8F8F87DFD2AFF7DF8F8A8FD31FFA8F8F80D150E150D +%F8F8F852FD2BFFA8F8F87DFD31FFA8F8F80E15150DF8F8F8A8FD2CFF7DF8 +%F87DFD31FFA8F8F8071506F8F8F87DFD2DFFA8F8F87DFD31FFA8F8F8360D +%F8F8F87DFD2EFF7DF8F87DFD31FFA8F8F805F8F8F87DFD2FFFA8F8F8A8FD +%31FFA8FD05F8A8FD30FF7DF8F852527D527D527D527D527D527D527D527D +%527D527D527D527D527D527D527D527D527D527D527D527D527D527D527D +%527D5252FD04F8A8FD31FFA8FD38F8A8FD32FFA827FD35F827A8FDFCFFFD +%FCFFFDFCFFFDFCFFFDFCFFFDFCFFFD24FFFF +%%EndData + +endstream endobj 61 0 obj <>stream +%AI12_CompressedDataxۮ%y&v_@ÚŌ<(HJCA4VW3 c`6 |[Y W~#\U{bS{G{ʌ?Ov'qm??:y7p/t}GmBvj^g|l°3Ɛ6掾{9Ϝ7?;6, Amɋ/@w}# =-}o]7;}{|W|/U":zW_l'o!o‏?z _?gϿ7_~gsW=>y/_f鳿{vO/^>%M}O_xi _p42~??GџP/o-?w7_wyw7#{›_|_az^9P,^%Q8|-<}ׯ_~vf|鯟cO>_<S}ҏa2U +HF/1mď! ?8:8F8CyًWyƉOŧe~32۩[L+WjUmc<ϱ_xN hz3_}/͋Wg'?|}'o^ǯ~o *] Agg17ΝsBF>H~ʍ gr8<_|th<ȧt/I?t?]/Ʈ-HҗCI:󗯿Wn7_f.?|7St3usǍlM9[<%մX|A{75 +7^P}tG=}˻/PF^v<63?/t.Re(ʦ:'Ad|6\Lڗ;OW?x% /rׯ_}X0C% 0weF 2obޱWew_7/@xԿxS菿ze]d]DG Pp\ \?!f#.Oy)9s:Cڧ9RSxܑ=Divԓ@S8ҒMat[ݹ;ﺩu!{u+7海.D?qO2ϑ wo;ȳ9{_;u'Ho@7T^~_,-wނ^[G=&o7|vvvF#N[{m_so& i ZG؍Mu wx] +SO`Di")<(3` Nb~G`#sϴCCȍtf:{:G:}LJh!:L)DB00he,ǿgtDʸ22ͣj@LӁ^@7u<kptSvL]Ñ8S`:GGxṣttt~r; +z5J؂H2z6L;GQѺ8`0z A؜x4vy.cu|:?X[+:-"3~+m6,m",uOnZjZehDn&_]݈(z㿉LVSӎM{;0zvuS_z榁=(-+!-uiIǬK"4Ԏٳ31Q#3j󄯁_b-ETԎ c~Xsk/l@'fNLL K]>50:TN8%=ቨHێęF``E# E d1xif%EG5p~gjDwfK@o0'`:Ù31p`}G8Wr~³@@I!P31:*$`2 k&xϧiOrL<&dZrG4D@hD:]ODSKD. B+'TvgL,h"I?"~<?P:=ֵ$Ȭ=T!rT-D`I}XW +S%;bx;|=/u,>tAAQl;86gPSzN1UaK+T|s|y +F*pZ|54\ ا3FH8E-9OhN7=t9QrJ\Jk[?"VrB6{Um!b S. +ǟU +/XƔqveg& Nm'U)$x%ycbMjdr$trfiVt 4׳_'+?n]xe*朠gaXE@g=rn!I-i9e'DE sSe<&uK@0axnx{ +1HzVU5Ui]%>g*I̶oGPEG#=#Oc +bU8Ĩ1&iQ3:VjƬf gz5lTNA^g5tƴX-ibFV혜#Xvf:E&rIq;bc$v,ۏjJ\ɇ&=uU `׊/66Sa2ȏogQlf =V +};U K5&d88!AF'e wt|TXCdROh{V O-(mTp Tݏ&o7C]@i}ienS[M;sH=.}b6)s9ZgYT{p^Sԋ}~VOSv;ϔ3` |Ȝ|^ /Tlݹ.ش=÷iقʶZ +3Kf0s!܉%Òjqe+3k*qeVzv7VJqYiUqWa- +dS;f 9LEX;#mmZXg.ͺoc-wGִe7y#꠺N|.2rB+/j?CŞ!c `e(6(nP +%Vt5m^iզ҈_[gUjzM6=IF5.2T,NӀdʗ kZ hĢ%n5 Bll,ֺފ|}MUtYENVIOGwNk:R׏n[t"B/jZBz -I^Ɲ@U:PiJ^$}â W{f u{`-eLp]؞*1`~ϲ 6x$vr=d]gٻX]HÐ {-3&enXv @yE>VW{sN80#`}G +Zw;s8^EXW/V+Gޟ{f'(.;RP݀萠A:uH%= hhϤS |+N]XeP?ިQ5D#+Ɗ^kt,Ef7ye1`JiN͛6l}k{3ibv 'fr3ZPkEX"+đFs Gs)Fb -w+W44#S#ӯiĻ80%2/FL emLݞ%<⊴p]y$.l\bR2+ruݰG+&1njkyuйw`ve;c0%xʵ'sC}1b 8NOmɅrtfH[p/̈h>'{JF {w]N304TO^ǽaX7> !ppL2r$"049Ħ$@H:D>da@"z~j5$ҎXOQd]"s.;k\ ȷ2=*+ .F)~?5bNYb?ml'7P3Ϡғ\bnmkF#Vo [u#VlCnn=|8bŬ=<j:I)Sd8HY AWj}Ẓe{£ECa%v;5104B0[xd&į߲rtA 3EfͣpP1jv +\ruD=֢F1D+zeb&oFRWB#`w+-x#f"Fvk4-Cq!R˨4G7͕8R:|Wuz.\㲰Rsb8܄4? QuS€sMX~+4~mY[ &\}5-cҗʕ9`%ަ_쓫sW[6my#-ʎ{m[|I@ّL,c zEL0vS̬?8gtL21+!P;ެUdWH&kwڵ]];"KZTzZqX.0;BsJk/ a$ fFl5TmmmT5^ +H-__4b߲xͧXш}7qʜ<'vlήH΂ 'X Bp` |ęAk.s_ltۀtgO|aYLnj7z͂ ZTpGk5~GK`\  +1V`Aj|3dT<{Ə$5XnZ^^YwLF _JڱqZq%AzLG8][*P%jai +_9g Q)mćE},Ȕ=ʪZTFihژ;`L'YGJY]/E?(k'N;?4qi='=(r{N7YոK+/c-Uq^lEQ.v&.jN?sZ&nRf:صɹ""ujZ{23YX\=sؙ9C'$C<@̇>27spެ\hiO]cD bB*MsO\! +j8Wx/|!򅿯Q?1o|A?:=LyKW̏ g1?E%\i;;ƃHA:9U>>ǽk^7q10Wћ)soM+`zgi 5끙2ӈ"fT(JgH^٥y%A­JQ +ӑP 7! FS /z#{M)~V ]V?xj a"&\$'%!ŒTS[§yǁʳ3 + +$'$1%O]"ցV5'sW*ޯW^2rW-(򝪾'V$ԕ¬&+bU䨙g-jFQ7YyceAm"6URrk +s^GkKEo-vK,䔷rWlk.]vn}]|7>E[  GFa]Jd@\AdrY7rFP%Wڄ?&&N8L4U43bZQ + ^-:HSU)𛘏NC_;g6i1im]PD(j U׬-#alWUiG]eClczXt4HGZՙ`g92QWPG9v&7 +l5&NԘ(d(1T9Auhfc:[quX)0f5TPOC(E:)j!7 Ylꯝ䟺1N];i+cڈ佂ȑ`gPTJ|&eǏ7.df+ke_ϕe`S)2+>zR|tQ273+ik\yngYFi+ޟ^΍ߡ5ҞU5RKY/ڳRX:0+DA/Q]NuK()q[`)[\Y5{jIet^x *]BtIN0T@fI?E/vM֖颭J"6{mohk+[ZM hń6:y=țLp[uFtHmHWtmF#.no]njxn}ڈ"S"|/ҽˎ\nGɵ .NHڳZF+im/bnYZfJW]au)~4Ţe6RgCS qM9qǁő+uQjH}",EY}܎4a rY.Hw()Em0Ia%/Khwļϡn_d%i5ss^Wݫu`JW wr8ZIʵ"Z]Wn),gh-;o.I|Zzl:,Qˈhf(3#-qd~g5!6 "7EwZj},E% ܏jpנR M\.ȩ:fv.W{ޱRW#Y5-`)<_:|B'T1H{c",Re5hud1%AFxJdpvk3kNr=U;2[KnPbΕMdzų)5שpsslbu(vms*6"* +pjZpwtr݄GݷgJ=nMe~43,r[fs+jRdFduĆ@s_{XJ+8"-g^%g +io4|Yp23 ''FZY"cN& NJ8w>!5Y$D5>Ox-/G_Yq0X,VmKߥHf곜s(vFrH>'#~sS;U+^PxmCL;5,١*BT2ISb7Mv{`(Ij}L0Su4g'Ct 2Xծu^k2Ÿ+*Zū9˥KsE3Inz:N@sgGN;*5F3+ =)ia<p͢ܩq?'Gui<-  E2 S6af\vtiM)6S:\Z{3 'nqnb9ދMԷ"aX%wDt]!1=$b1=$bzH=$bzH!C"DL1=$bzH!C"DLT!C"DLߨDLy؎ro{H){t_ڮXP"گh_),Ejirl{*f4R;Q}Ld&FtU i:>ڬwhvF8UC\X5ƍʶ̕9@Cܴ0 5"vEBnl5ͭn4⤆:pjSCY3^aE冭$V_j쐳S1F홐M%SGN%fR cvWF9, AUbf j&5ZzH +7UTolb&F\HvUE WU퉥QI Ac/>+!p83+(蚽71. pw|}?5ȞɴA:*i҇CC!&O!BQY9f$?V8h>leBD! KADqԆV +%\tb'̑q {5؛U.*ElW~+M-_܊B#[Sʥf +; +/koҤ k**v>.lmD$qYr%Ls)Kz`^.Җ^pW.kb||]gK%3 >Nڴnc?x𑉦CK?ҽe w-b}WRA\vWʲ4ӕ65.m-4J}D@Fo藻>]ڮk}_=.v_;ӵ#_y%֞vȿĂ<$8 *1E oθ@QCg"R 4FhƩ~ƻػ!L' ^Ć^/W4R 6p;PhK]lk`}X#rx[* iʚͳ]ʲ-5!wnBcg1RUjww[ gȊVW{v=B/n{FŠŠ{b2Ge;j Lġ{D`aQY7ƅ[fǏ\rNcc)hb͒}P܊ĻwWɞ" Ģq7l5ڸ&WW H<@Wb,%/i:~Uȥ`\㖥L>-,<|UA|x;QyKqm'cZHՀEBvlp㒚$94KgHuu)bш׊XWcW@/| g%]1 {WUlR^nJY5pQ3Eja*ϰ +OEthuY.,E 'V\S/ |nfkݍ51 5""R|!7 ߭@I+v_/x+k7 ֱ +޴RaSS JuѕoDn_G1Di;4L_֖)kW+jOYWЮ՟Vk_=z̝ḙF\|Zi8_w,T ,H{>; 5hk S4_(DzZk=\iY`-y9Uau~}uvQyˌ@ϱ~_}=jF6x!E+*шkkZ*_4kwd:s1Ntf2A&*՝|TMgYʡ$w>v6^b\$JiһU0[b HZ"C +JQ mvGf`5}[zPoĢ9{v A#G4EGD`_"F=i[ۉ:V[ UsÉ&˺RMպm:-xwvEl2>7? È#>#6vYZQ4nն̰3̷y[Mux}oh[_#^VmaoȈls ZO`La~_eJkg,C&<1aٮ_ 6 Ww)$D-ejK/ -.Tz +uJPU-(-R (Qd*EJ/z۔/%}Jަ=}B7=>butԐ6ӉDtg:NxӍ0#] r!a>ȵ4XXL]+ONjqSB6*m kQXp ^ +W&\BKp j=hWoCnצef'UD+J^j,:(jjCղ5QŽK[~+-66p5cmYtR~xU7U8&q/ 6Юn6/Vk k{T6RWKե!lni;;/Y06}0\;[8.Zx5?-<J<gćGuh'#M$o1 :wp;҄P66bM7&66ۀ~y-j;{d;r1lqގci_א7_{~7: y>5|\'kiQ>b:f'J仑k-YF@J:3G3dž0p[ǒ=qV*uM?ZBT!Rx!hLiRH9[U*z+v]q+aFN!8.jg].ӝڞڮZqh *Pl}{O5b <{沫e_Ǻ] xo2 qt#EY[k[[(cʹ9YUьNDQe/KҤ1,C(J*zT Jf2`Gʒ0p!,̔AnLC0d; %6В\Vx%d\,&qDZZR|;gZNi%nF'OYA[V8^^ 5%#j#⽖m)}޾QӽJ|]jgDA.K,)d3> ,\1dAu M+^u b%|ׯ~ū/^}I-n֟<~/(۷߼$?oIBܼQ{t~,MH6 ame7n8mgy+#2M{|׏Ce#o>G7mmbmXmx{_=}wWׯ_nXWӧ/޾~鳿'/^>GϟhǸի@n &gA!e5& `ޑ."Tǃ˅ haۏTHua!oF&,T/A vgo+@:]QsjWGvΨ* =[adI/黼%DOO&XBh{DLLmzhn`ڣ}(.Fa@]&Zn7`6bW͎bdҥ6Ɖ@$1I1zXO#`4,) utznL5T4QO=@M(w=!O Ɇ4awFiCMtܚ`%ЈCuy0Aq>lz+}ii|$L"["3F ytJ `舂sw=^OLmfi7GR?& ` + aG}(ֆv5V{H{ 6t#&X;r4D(@[3 ,F^ ^xOl[%iޅ< ;z<%%jgI < ݠdF5=}B@P8'T!M)H|-=}$6rv"fUip tMڧiL` Al +&}&0FTP'xSoo["r|J%ʅ?}o߼zcq~o>όhϟx&㷿&Zf(~ib `ؒ o}¯+yߣ|ΗHtpnwr(fЄG3 1D(Ϙ`ρ6|3*e bGsX~Li3ЁlvWyy'h?OI' +MFp_4AXcx s:|X%*#?u']Otf{ +&>ƞnGO%4aV-᎛aq ^vB)$X}!Ⴎ"gCD$=1s3_E,IR4i: HD{hzfeGҫ-e$lpM8 <Q)؎- #ʅ`d0hxe,I34X8: hПj:y +1QhZ0@K3piɨyI,2|2{hboI +!QGy:‡RxchL%PA6qH }uOu4[h$hqiʴ4r9m"GgĖdeAHV"4r#=B 4 /F<1#]\E4<>ffv SbDHGC\0(q<ѐ(`Yh|H] +P01q!x#T@y:-=pYCaqlE"J:d!`aq2 +N^P1҈h~Ir*sfzqD2XU-Y Y:<L1s)D g{P@Y%41ޒp'Ю$7ns=3";8o;~ xHt$o TKy)%~.,(". XUQzzLk|N.Q8 "wtǟ UwBl&QdSvCpx*-pR7!$e^,D3uxoڠbaEX}~Qژ0ĹЀntׄ hPQ#Sc;ߡP3! qq&9 "ldzjVm@=eܦT.4l>0wb2m\$-&fl՜5u[9]97kvn9t^MԻ~i>MpKfDm%bXnhۊAn5qɭ.Qܖ򙛛]st+ڥBpV,י$6uVފnwMB.F@w.s<$\,1OE'j7mFm@WoQ LDW@++]# +1E1LJ\!rddlRFz*ƥ\f2io3M󬝜[Hl^*api|L|WMV6޴l.!HuiG8A$uzU`YE%7&Nt>'F##T0*e\4t}l\ETxQ$$Dѝ>}`[#^f wWf9/n;n. +Ѿl}59 %eG2xqWM,w me{>X>7"߅'r`m!f4Fd-LNÃqs{--)ܔ C, \ۃIϛTByGee }޳pz\W=HLnj)b@+0g5pIIeVF"XBr;\(*…NznU9;t|aCH `LN31nY# WzgPl"i0ó2`$y_Df6 e\N.Vʅ=~iP'm*e^;V$huN$6|mۓUC͞f=h}3 @| jx ).jGF0\^#sy6u ȓM>{X&5^*=W N=lqa +YoչߑIO6t΢u! +lL`N(6ѓ# +Mt B5T ?\_Ʊc>ϓMϜ܎f~:SnkUAobTP˦9-/̣# .2Ċ#k#z麕9Dg[?p֟u1 Y.욿虝9A@T#<҉2C <6!u:Üƞ=Z\Z1}qOO C@`M$F@CP +/a&t]0d4jXJb,8#s($ +chqGg3H& +b!3D  l2SB]#&^µfF2ױ[eƶ-= .$g1\a&z|]"rj-QV2̒bT$4ioF%ғY͆F9̐ؕ4vYf%бYanm` Q4)àz(70E%{\uYIޯL]&u63H㳣9u1]>SZe'lijzA[Y 8汣a k,-X[{ ;.Kb-VWM)*#,6Ƞ('27d7c]ޓ84C/v %  !-k˛̺ۨJX)WFIrAGhT2= +:1Ҭp9XZТ[ O~O>HkH8DˮaA&{0P>eq&H`ɛ@XL%agq= +J* `MeIOeуfSYp4T=;k\RYq*T0T򕧲`hV,ɵkYJHY$x" EoY` +0i{ t6ƒrK Oʞ5X  \7QWJJ>yAP4 MjqB@l"洈,tLk@4Yb_R߆2bxVZX#?d~^vc sW0146l]ĩT/`Mlh nBeZ*[j71iOrz[0E‹uP]܋Slz'VTY4,F#uIM +᳧a iP`by3EIT3Y$K %,FH%ҠA=Ԁ8M5ćYD69[2,f+qn`0psXF-Ḋ2T䘃 m3lw|wM:8Ti( M ~6!MHz 4b{Zׄ G9|,M +V4QDvzLasp6Y^Y_3M&4O^ m̤ix d +Bh ![j:uC`mSΖAi,w4"W}L#i!Q@Ä/m2>z}2Dj'}8K޾:`C_ <dm:GUA^ݢ8X7i]Ü!1B!7SCgx!.p)0xedZ@5P?EYq;P=st +ϒ:d֎"rU^H,3튎I-j47 +>#^ʑ%:Y$<:=C/xE%Re^`h G G:XG5M҉y.,f=.\xb$j'ã+BIF^u + B2$ٴGr0a*y3b3 h>N/* _ i‚ih ,]r˲-)ؙ9, +eg`bҲ!*/l%Sh:&O%]ڬȂBal1+wRyH&^GL'HrLF>wi&F15zR:h0$v(L`Z$ ogB̘ذ58Ҙ̞A"QvMHTg.ǔi2Č H/"ІQ7v(ZؓKJ d"eF Jx}Tc"ZغCM&a0C%*m`l(P*t?6'4#|:dn2G苕 fe,9#t 4 9B̍B-g#̼TB3C-8G3W,Z uWî̹Z7W-m-9gdv5,ww+qnLl7:fI&|Jnt-.ŴtܰjY^]`rm-Ve/xVs˱K{n\6ymЭX3Ҭ.ѻS8l1[,h ;eh% j4x1/R{!{$;J/AdtU%J&6`G}ɘS2虩.i4{PqSK*SLl2?LS$~ePY %ktJemMo)ߧFi G$~t7 3G@ Fk,=޻݃m/LAZYly_]X57>VH 9~^p`Wix~^\k?X/S AvR9 #ϙEF2K][%e7#uh +U{ݢ Lm$Wݒ\T2))x*,Yl"efͫF95< ]`ܑ}@ Al}zSKT6&ρSeQ’;,ZH*S r՟ ΀ItPue>EG6!en_oE^V2 +ؚY΁Mr2bP26|-oB KPf -nۯ#Qig'Χn}C?ž~}%v'_;NsiX.-C?B:ft! x!>007c\ۡA VRO[_2ƭGqZ&Cpqb9<>,%OExu 4R9SY4pH իp@Lu],܂C䴫KBQr^ Ӵ\X{uf4Gေp2G6enD\o= \,x̧m]6FYPu&|Р f`x}Uo_?l~VCQmx9w|]RAE !1ű<{ h<njZE<} T0- ,}Ҿ3Dc6zRYdw>&Ԓ~ >fMKAC>? ں*>mc`D?̂72>aO 4U dPͺCI@E~HWb?"}jqZ(MсW0l$)iY_$Y掹yxuo=KqDcb1^}~{S\WmDXKCvIt$d '^ co"fHJ]Q] {<"QBJ|uSw: Xgư +GXD_D .$*a%q8qq%BҒrGV^,p6 +k#xFދ(AzƀāR bXQ 0%& +~a]K87"ZG27#8 +p*rhFGRogb/xK"\ u}"(āJ* jtcҟ0{n]H8{A/"{x\ %j.Jydf cM1Pmm:q¢vg5SޑVyd*_Kq +K%[1e\Kn$ٳGԬBrsF/kqCd cAJ^=g7]?|E={ %[f~;A{K ;NKZKiiicpe0_KiVa),+k#l\R=SVMΥC,?9ݽXvX +N`wjmlBh"F=žU+pkH5\TN+` +W=VP6D=\z`ƄTonZ-UV'xR"rO7U=&A.^ Z[ȎX^,\YkqD6!؊v b[hNlV#wPX&FzQ;^ysm~֒^$"!Wϰb'5GXM!јKw>.V !ŵ%wjHo5]3yڔR~ˀT^Hfjg&XUi& >g)= ߮p4 /d5sЗTJxcřY1'^M[?45l s!m=V$l.j"V(e*HcT)'^\-4*K~yLs'tSϮg) +OcgbwR]ƻm&H˽+I&~el|0iZmz^_+w-ū٪yfuKY1ۅRzk|߽ÆWF[UPsh*k"[ ^ak9(E\rz\{DK:;˥x,!R9ϐL`RV)g8 :PK1zA^б0lѽW:tvxD1Z]щatՖw5zǖTzH^I鮗l צ4B+֗)(=xL0fˉxNgYRJGxqI^9)!ڲ\^l\hIʥ-N#*2zԖ΄^Ur^9_̱ׅmh/ uܫѶU5ںo[q\tM𚻭y].xF*.=y`p+ybټPJu^ϸ ^H +BKKVpK^ڥeb>QKJѲZ阡_FS2ALDXO/#"a!yQl-'ّ3T33`1ֺ쎜B{hB)7⭠xQ"*Vi<|0u*i͝(5iQQ<=bW 2X0`=߉Ll{rvlk[h/&uNP* +(I` 4M&Ol Ḛ̈(aCBx6Orn;X O`.ҏjm +S}´{g ;$8AӼ`$oDĤsx]>HȪsVh.'s $+"`᧜(poĐ:TNzض`egLYWziP03 +d/ʂVp*Id U&!;~';Y&&XQD4ũis+*y~ttVb,iy\#tKU|^",@vK8qxX~\dO&߳lAW_8݃) +2B!!P&̏ ߮HU 2}ѬiRz V!3qJB/87$Fѧ/tVzni+ʩ}SKrV[ª_dCLkҵneM3p*%!8l5߮3Nϔ=عz>E3V?箒mns~ב+[,cGWUvڑʻFwsܮfoQɅ 78j;I3Ã=O NE֭"-Ivn8}/= #Pc03ni9ⶤ婺5r sOnj, n<[15̝t;nkI9YƜabܮ[$#ve9Yl:^ Ug꼿[i[!͹.M3 rU|1 7nn!XVm݊_n'w9-&ʹŽ2ﲡ[]~t3+h U uYݳn`rrghj//풷Wv+UbWvy߫^NcZ/* }W- m:J^Sxx) fZPS6VFڦfuu^Wj[y veXom~znwh@ȫ;ypG/0=?9,CmrAazCفِ 'RaluW)ptLZ^| GF,,DQzH<@&Wpވgk_819ڻvժ1ǰg;c59~@,Ks-!oxc;^x2|_-Q6K,`k/ Qfg7%c>CUꇍAm^HIPatEKvW9{٩K%-2 ڈ<݇7E' ,6/V`āׂ֟wX;: o?uSCGN"iYxNczSNjd>k N>c$K;y.6q_p ]._3v?B>;'@'q4p<~i[2?\Y12|>!{?2OиOf|n> >}IO:{S`)unSB@Bq.pJ>Nrᔐo-N)(NJpJ\"q}8%b)'D$uY|Ҷ$$>T 4}Rx~|9u/L_ ~|Rx +/_/Fo/n1ČT:>DQVP h"ÐOQIj>;R< 8榡u6*.c.k7t&TtIəS>,"t\4MY mr @q{lGWb7Hl@ypv:άԸjffC ϦSmrŻLPDY#~ Nqؑ跹!C:7\*<+"j5ݔW{ƈ.*M0H~>])\uyǬ>!_M\H$hEXUDfBSW|Hx'fOoNEEgY4\%y~p|YgPT诺w/P- 1>QJwa>XZ,5 Ln^2vsM3BŇm oľL]j + +ԄSߌkB1ʗ5X߿cp iPYNYuOC0|$ ,<+=MY ov:|#?ŭiCq?46癫@P]ɩkntE9x7SHLlMRklA?͙3[ f+؎;q*ޓm]:4H`(Sy{֭mbx6nA1DUnΐOnhesCl,64B Oz;)m}ݶom5Xb߆a<, ]m.Ćm4YlalP;Trbnn`qC6mܜji)1ousn*p|Юln"M^P_lZc\m~UouS2o[vv΅a'SvDhc[j7wwدMi~u }Fy gm_wws`je_ƮoۢGDlۀɎ>퍺jԱmoEoIBٶ .ZB߶5ymoj~moʶlsޤ4cְڲw3`QܻmMl9Ǿ-hbCf[@/Mqͼs}y8nj>΍9s՝bfB+LPr͇OyPL5L$Cr3yr;iV1%>1z&T6}yD`Id'נ (!YLCCΫŅ(j_*Eca)cioK|"(uC<.J=U7Ȥu۪jnQrٗ"5ŋ~;;cs u ai%AǶva[Zu톧 bXd3BrL4Z\UOFS~oT#61bWaa;$` wtPm&ƚɴ$"MÀ>nɤ. yjqgCd:Ǘ +6m3p"uyw,Nȩ 麸_ 폌ٙ6Hsq>#0Kؗu^RcNȭɢr) -]xv 8 +KO1>*-+ӜFAz܀_hZFqUꭅy<ĔB ><ώZEE8\nQyEArQX +Tͫk`}/I{EF|(chxM)Ax)cyӮJfhV5Ѷ]^dOI& ijh>%qKR[W:i *|?.J^UĚBP(m1&7x>w#xeQ]+Wm]t"6EcQfLјn츚3S|Sqmd\elP4G@Ms"%@HAUbÞ4g|IC:b(b4DvȬVOm@WvKƁWX4qJ#L,oƧJlmdD|nIDx ‪g f,@a5hetO/HU."3 +VVA.E +^mԤ2Qgjc:ͪTלyE's';6f~eԡ$bxQp<]wTLهq$~hYۙER8L~N7ǁr+IZT2VE1k8W++Rkn e msְFxRGPVZUAʻx#9>;Պ W}ChБ;ۥ&:{ nr"V +nA[Iܗ7$4[Ɔx\ZUpE=ݧqǷ>{?C҉!]+o +} v[[|8ExKv<e0ciGB?}~sIQ-e[-dMoVq>'~,^\*R蛯,R"&"4wD:b$6PY!0;1Jzb(6k1~3p/u89\`plݿtlZX @  Y0apBnHM@Ͷp+"t??56&o~ă=Kpv8{n̔l׹O3x hleHMܜEߙ .=Du#"H:LFA|NBsq7|5%$$tVF$TiQh!z.X$#p²usv*K-ĜY("Sy!1d<_q Ű&#BT߷=~~gnmFTAwE$W^l)v4h Ģ7 $|xg3=0ovOc[ЃJ\u?}Ox0"qSI/3<;Q~ +r8<[41%5A~}\[HP cGP,ٻj-Rb=3|~:{{WY`rm#]玈H+L봱~l1sEIl4pjbfŁ~fGi8Z/ap߁T%e[赖CZ/tbE&R0 k^WԎƵG7&!o~EaFl<崏uܣ6K#kxu e/Zs9f尬ڬ0*dYoJ5gsY#/gS-΂kQ! 9ƛ% e8UVӥe ,UrvѬ{WYBOߝ&A~X~*܁a[i}XW!w;䮗 =f'#v6"uSIa~fJ(03d['$EfRžQt2FG je,l/p NW3fxX~ٵ!hoFl=Z^j1gkr"ٛFvKF\M4k +4֑+vS]$ -eǽf{ٚϬp#s}b#W$*D<0 %b?n]u?JIdGτQO?*!"K 0% &(Ws6n5im@Q" پl +̢PI2ob*?#G͟eqK-x QϫƃxQu{#__yA/T*tm wT=w0a`rZ I:dnB{Ι$Ɓ$ÞQ~)~uy޿t'&DEͯ>h3Tn p㈟#\' y>jǭ:?Jt)qqYVk vhQ\mm ƭ'H V}DMD LmH㣂:4>,Vֲ'~ʈAGReS >62F:Wއ#>),?HS,J6j|:<-;5qWg~Xox|4+eD{cC.V(2nqw߄HN[kcuO$~ZP3A uy-^d~=D+a 8P%ڙ +.$ x_c,XۙS3vv*IPK~%AT)+aۡC_pǽEMM|ǃ"jD/h==21(bueU&cr#ԤTJK ?\Vh|+5UՕ_@%DS?I']Kv{q1@d GUOk +yNq\J๊5לa,KjK[y\ Y/W+/.__sޒ|㮥kw7}H>3!g+~:\ yu%%vo߫NAaRxfh{a:Ò9Ò91%FKFKFKց́,9+_eTldldldQɜڈQY:a99ud#g% ++f6rVldldlda1Òcf#%F KFKFK̙֙&ŷ/mA('AC>Io|.m;LAQ{B+gPA- +(BUn\prR>ri8ߊ|a$NvO"狡;~es"(X|LO$%MO~=ļ/KNߝߚ`q5HY_ RWIRU +RtWNRUJRpV8$e g,鬒:$eIo5hY[ V+Kxjo5XY[ VMxj𲄷,[ bV%{17?䬎哖EDdV6(x}PqWE҅e5o}W%_AU[{U\( {0PA` @G%EW +EcAA@؃"EcP= ؒd,("EcOwGVNNǮ I ɏ y5_W6'~ NQ Ҏ#¥S'I>^>eooE?7$U _%dDT(_M[FT99qV:z<婞CwbL3x;O b_?=>'u!D:M;Ps6ֻDoǀ/3@Ѧwcct|r^*PB Ɩ?l-m{v5fz'`kڣPTrţryg:ߙ ./.d\*[oB޶̷7ެ| +'zKGFOeF,AL5Yf!?y,U*/F,Ԓh*q}֛3ulhSj@8FpǤKӸ&)f3np9+[2(3[sBwOpKUcO݄=&mCUi9;sYY6'XDgSBη0i݉19ⶓ$y[ :3߀œ'aZ%C^_w>7Ǿv/e_,-2/{"_4D ^mD/bΊ~Q;(xdin5 +||7f-k)o|S 9.t 3,~0ƭն}E{ y0#`]j㩋52b|Ɗ=(g/WZ: ieP4rO: 0ů`жA45[DW|rIM44>l3*O:dc=dA.(pz-n8mՄ6I_V^o:K}gXW"RѦY! ~]2U:aM(9 1 +nsǮ՞OKELhĥL5f.h4 ݷb8ȎU@5i<ӸG;)m4z*&]<8 ǃANK94ݟ*]> @l +Dø#F%yUA"gS#[ !o/] wtK9L m=,hSʲMs\ ?pH#w$Q-r8MLJ~k̟Z0 8w7?/F:3ijuʏSeh8Y6WJ|,%F&%dXiGu޻M:?ބӁ|*߬/_aKepe`_z[t`8 ;wᰔãAuIp$ ! U_{8\?}C|gޮ~llk?cXOgq&̹0")أ4dA@v2 .i5"Q*,ͥŶ(׽xuvز LT$̑^"DQjp\ J + ȟLm9~q6&yi=ehP.iWYY9Q>`4`ۍ˚KT858Нh9wOZfKk~"̻^I(Qh<⺤`#TKVuy3"Rsm1im1dG*jjLx}udƚڇB3Bi6!17-Fju@(lB4ۨ2llϰdsu,b?clq;avr.TFbly 2|DќH4pXjh3EhI_5fՈβUøhp/Zd#$^GMdfc.Ո;}f3pD4Ar63dۣSYhf] =ZSfʐH*%[szLa \SlgJL\lQgMҲ]slgΗL ^q'Ѫ,4[5[ffncۊLZW)myb݌7A6rw@wA|cO*UrH0GAkMQwHB'oy1aX1uHvG5iIeQQyo¢3~@{9iԅ݈Ѹm4oTd*V)iCxQ{CM_xX$[g(}ݵUy!ܘcnB:1ygWםmJ\8 }=_UN@8r됺 O~WcQ|OVs}'`\J%t`8`_%{6"nC)MA%T>1nͲc3۲hyO pZAa3.t9;EInֲSYnp$dc$}瘭l< BaҊ7q'vx]ez2>luj 1A"(,T^$x";!#"7}zѱOϩ.WdAK#/!VL)jT@qd0p oknٽ˓L~esD@l~Ho*yoUq%d*q烂Px*rUJ`?p>-c7wW QusE2+Vf.]i+ُ5>`|X0[󽊫7/?Џrޑ|_7H>t2'>+|\yuvNWKoi"i٫Qcs@Z3­$ ax+uS3"[|% 0ՊEE@@ }.#a0hS{I:sqȯR,ۦ% R cU,[6m6UP;hߦc;S|QZi6l>ri;'-vO@5;6޻GyI OI3-& .᲋"L +BnEt *э _4C3y] V/C\.\:Sά +v/sTM*ެdZ9KyTl +س~V ݳם}Az[=d{=KDSuyIXJ$N5 |Jv+ԭkXUSdzn ǰ}ml0_bM@:#%%=,N'_cMkGyh¨6MDa5 +_NI&bElB QJߗAX\? ]'g'Kt',$>#y +?>7m`^`'={.@bqw.'/|`7e$?-9Wq?U-3 +He2s\{v5yJc3 J@bc=|b+P:8@d9UH/}L&I9ʸ(:3)Rc[w *rzgbPn1[R+漲+kC7x +_ٿß?͟<{ȳi~2ߗgMMS$H ?1_f6$nNHԠͼ/ 8HYt}e8m7sXBpkcV"LYR7T;wAl >.^v.st vӐAWa}6!X0.! +(\sހ.X2\ތ~y=FjQP˥$ٖa; v/yzuPV'x]cgFٮfz!0. x߈gP<7%#l1^A;LcO~ ߷Bc,O m@ 'dXRT I<2 +WeTia]9#HwUVh6S'0>H>w]47"qY@PՌ.OE9^nB2Ezu2[!?¸hK\Vgp-Nj6{oai ]*nWumO:zP82 -h^Ft$idž<>ws +;J9rPY"("bާ.˦y5F[Cf59Kl7QP̘Gqs9nd࢟ $J! ѐa=V!}]cy˧hT[Ak2OtS~v*<iZc?) +luF"X 9;}Sks'@`%S͕u]W +8h8sn/]ű~ޑ.SkeU'oݼ:;dR('/=1~]`ÁGS4klӋWa1g$CӟTb'KY~x@Ïck7T*tl^ %4x?tq&7 pxo'Ba3ASЛ.l6u .=YyEᰍ+sQs>/o8NO(ں }%0FDmǁ̡soǣߜsvMSYew ۈ.mZ:Cnh-l8qhE5[[V7؉B ȮiQǚ!;CPҫ/pN^މ[>EY.q+KDBOǷ@Vvj0D 1ȗA-rc.k{wU2'D)̱ձisRt< lk~_XiW^|,4&yvXH#$Q}X>&J==!o疆|a$بA>b;mѓM\|w}H+prlfޔN>un bǸ[؄oBV#;X֋/-i:8e8:+\P|NCq񷿮%$"ژðY:YI|PVםMC2m`b"Fű[ԟB>Sw-괓b:vB1E4m="Ea5zڟcf}gO{׆CZs8>)6:ެI|R&"Id~B%}2 2k D|h'lU[S4qE.gY>dc>d=ƒ |̰!X.y7  6C}3,y ?C3d +w7&\ J[>ZI3Y7|deI.Dհ,`89cY J 1J惴zgҘu\KϻD/FXLϧ \m/OuxAbWY(Ei}83F|JEly2}[x"m7B~B<$Dt&KfҢ{KNwߖ ɜ(RQ w}J9OwJv +jsȺ.gIovhAf>!R%( 9FuYRO-uahE+$m*Æ.iRJˢD8e0Ú]Nߐ)lFa#aA1+i,dv*4iZϗ+a<, JAaxo?1cҫ.̊o +@'B+[.-_^Ɲ5s&eoЦtoۣd̋*1.^G\Z;wL,oG}߱L,b?̊y>Pמsjz6"Q35jr +m$`@of^,@"y Hqqڇ" d$@-)( ˨= s֤saa8 ,(2͎۶4y0i@˒-a<6DгnBxv5!ŧ.fH򧂾&nfMcȢ< +*yij/q9CvM+}Z Dr0aVD}$_9.STM(-~AԉM&Xq5AK}eݼg3;Z[G~Jp$wǙ˥c:-cjnzì)TwU,Jm?5̒Ҹ*{ +ANwZ\G Yi)Eυe9e29=4RuiZ}Tu,P:EnXIpvu}t;DE{/u3>vX7ړ +B;7'SLE2XeJZeF7qnrsXr;F|x:yZ©7 4vX|^zC.)|:oTB#dǣfV99VE$r􅺁eպKMsN=}"IGΐlZ=ؙaQQ&AzVK@I/U.UuGrW}zm$کoL+d'bo8sky@GL.QڮOKt1'y㬓~)W߅ thqjȌ2ԍwâ:,@Q/CY.ezCABbܗAW)#o*TKzϫ=Ŝv!a4dX.'ٓd߽M̕4n#;jfJW9Qຜ H. +$oN@qouMqBl4fW!K?w_GOQ4ݱ Z^֗ +/iNil_`[(}eSO0Hc +JTX7xŝ**s kȾy8=n140jj%6)Kvp'^ਃO[%8 e݋3-47>w;Kףn +Kjhx>}) U  ˅aj] }Σ @f WLGzC_|d40WWz6 TX?ǩԊ*# +XԼ艧[tpZ5r6(ĩP@qG~$$Y Z|ɢAwYl_ZWИEV 9*cK8SalE+ГIxj^fIn!& cJ8py-!œ2<ݞAIaMGz4)hH4AtVf܎6}FT\UxVUVh5"\a},"xE,B⌒0-j{`,&-t"1)6QmUY6b87VmS/uW }6-[VvB޻,2ަu' +lt.< JwgT>ݳfH,fu(僕rHxz3J>KdI|mPw|GWyD > 2C&!˾GSVSūŴN`pR+q掚X,#eHAK]ܬ FG#͘GuXD|y۸x@ثYOo_lć-_ GQT ~L[+0̐Q5>^[dSXw޵hio k7mAu͆4IŵwYo:C Tƍ2 9cpjXQ;Ucae-0\XDN|5xn?-^="9ezDu)R!4X6!%m0]^Ea+#gYтT#Æ!>ur5VU}8,t͐Yp_*] lҾ'~wk&(b=13:U9.ꦿ/jh +JjBBt:HawBYtBt1QKt8Q]hY99(+@)7B&r1 ;WuavVNjIrU۸Q 3u'}cH.P:WEo:QfhYJm!k(Ԡ-u`13=m-aXah*8݅IzJvi }{ƈUBNsF@w!SР+ʚ/m6d%R_v]Q*DblwAye>{Z3yM'wOR!ҩ4PwτY!P9LC=s^CaJBAT9ˡ(Ea=)\9,!m>É1cؖcY0Rf%>gqphdy"h]rEڌj54k;O"kbdyW㐺 3"9G[>t0vP#&,} xX@1٧w$jEgQ#Ll 9$>LXe<'^4bw'rEf B~ٕWsRR;ДB;hz"euן2Ӵc_lg[;hKD6hi:OeQ"bUf ¬$],OFfq MŸrzJ]V)mA#kV<@FѬlݡTX֪HOshXg`RMNTPƶ !UErNp6|EQoZBl]o3>)a2Ǯbrti {WvBD7oڷ0. 3ayWfv_bVSUF\ݑdV-jX a31apOAlVlNzT-XmOm\ xp +0Xaf R^*JV(w&TMl_٫h57r2|₁Nx޼\B˘v&/!v5,"9 Of%π]^{h7U>66^1`rPU&x(;"+#PNDlgiy xГ +\x?rvGd1C ' +Bgk+X-b,rehd"MۄupBȥ;XBʯf;Cu,Ú}:ݣ麪u+?k>Ǧ#ͬ}EMEJ_@ QΤXɓ<*Pǚ`v%T<裝CEEou耗^jVM ֠$]1)+KZ%'Dk"@x~Dټ[ +0:_z5\F6Ҷ8AW54,D(h~Y%xov 8o[J]q*\hu^}{P3\bBc5O1LNSU"]@!pCp4Oqs-|ф(`Yp)^@3 f}863yB z%RQ+ 5jb {DkPNv w4nk.a3zVl",[o ֺkӉ;ѐ+|A_mnlI$!]NJ[c+"GV!#v+&ӡJt w0l&"- >KGn];-JlFVqU-zK;8UӈӶ0J:݋I&/qn>M# +1Wu.%w6W +s6I np$Y>xp4 s)6qVޒߏD&u~%/.0@y뺑;Q9ꘓDjx?o{X?EwK(3F +ӿ|דM> `]$Jp[Wa*/}d4`>)' / YS<9_Tn410@S8m&K5nrDޛW;Oj w$_ 4P2j>t%S`AY+r~qXo>w B66qmg`4F"l)CߢcI+hs]ص 7 |׉NL}ۜn,@1 <CQu߅[;k]y3iL qQ;ؾv}M#פX5C0(;4ݾcnJp2v:S44{X!IhP6%8L8,:9=45p2&_kgi]{ӄq@:@O+`u?LA*Om*يgRbeTEp u E|@7=cwe5xWe9"@ٕ:H zld~ ` Vp/$ ;R*#Є iR&0-Sh.zLU*%eWvtc' PﴚaAnܰ +~k3a&L9i5eX1UG[n"Dy+V)\~Jj:6䟣.Q4[)܅Nƶ}YJq 44*fvq8==N *+VL5/ѾSC) tj/M !K#~}skPܭnjb'/FTluo3,⒉|:˪TZmIWaPpڽj%#pXlfA*(-+4\lCt3ɝH,ct`e 7YtX,geJ(*0%8qY>YT瞲StVh;coL\UaaIO) 굥GK +Ď,oJ=+n9<0: m۰/UQ29:{/Ntsl=-GCegVڬY$7U%nu:XCJH`]K+1^#žXmuJq %KSŧj6 +aI1JiWprJ&QBFNqM[ok&_U&{ ) epU}n [`uϡ +6%83&chm sWu$y"·  i62xۅ[9m"KQPr+pj_ՅEem@VڵPh:f2Kސhefv +"!kXz,Ÿ.Ȍc#,̭s5W#HWk1'pckÒk@ۄA-da#[4g1P!{/w 80"+cVU37i굉Y^3ҀڊڔumfM;N"z!Ѫ͟,1(=buR,>œe.fPN`> { Y0 ĸeQZR +ij}K u~^ަ*rAp)=vsYcRb6GTiHyeioSxyAHBGE4~fcM +(njG$(1M a@d@*t38?a͢y^/:as/Bd4:]We|PbUe5S0ND`g41Jg.8u l.Ä?l[ 9egv + J,W &w.0<ԭAgq*:^'H0U{qVɁ!ب<,<2%]DmpvTm< D*KCTdXu(S}`F?ueH1յAU,?rwyOV07P¢2H +H욍I2 +c]8`EV+⨲ +I%p;jZ@zU.AnօznKHc軳}1a5|#~Vf8K ==Tjթ.qsHvO>Av!ݽnhuonWyF;xOSeA +Im^.+]D)R^%(ϹVئ&?qB޲49C؁=̪䶑mJu$D7SӔj A@(M6C'*~6'ҚY~G9gOnIW(TÍ|)o7^8 +`J0SfD Lo G"F](` +S܌ P5P. cKv4\.> 8=\S߰Sˠauc^f(NcsD\1:OYg]Ӌ<]aD0 0$@Z/'&l}8&!C*^-.Oglva?!^|HUa P?Yi-уʛqu1+|2ZMl p^R+ +RFh/q``Uh,m0eX\4 #f8wj)Lk|5@3WG70dSQ1K8/s‹f-[D0(=Sҙ`fӵQCCB/_6_}?r⒢GQ-5OO~o{Kda~9Ojo%;ECQkSPkDKEɮY7mRCUNdg|(d勒]CI(5hJv1Tk$ºW{EUk걽Z"]c(`EsUrmR܊O%;,6)öVZυO^Jvt_Jvu%;zUn̂iٕBwQdJv\ZU[|~*ɼINd勒d*ayBO%;CJv%aJvdGQJvfBg%a&ͦdGy*̿(ARDr}Xd)Bv/bқd>IK3XKz*d< Ql} ٵ5~Œ|Ad0%d)BvMFI..d2 5Y/!*d'C߇{ 5 LBvM1CȎBv*dFaKkEȎ-dנzY. E.!dD}7 ٵ"dTPYȮV]YY1UȮ!;EȮBv}Ya-Bv]"d',d'ç]Sc!!"dԨZ4 ى%d',df!;}KȎLّ!;Zo!;~N"dL%d?KNYNYN)dO.Bv\uK,d Q:.o!tvBv_8II<-d'"dǭ(Bvi(Bvi !;Bv=xz]wg!4!au!NR; ١L*]*d'2 ]!;EC} +qYENٳO!U'!a]cCȎ ٱdg!4!]x$d'}#BvWKk!E]0 r!;#$Bvb.0!~/Bv*kBv>Z&f'!;^Bv`!;ehY.!dוNBvj| 9!;QoBvPoDY5 ]S5 ّ!4=!dABv}ݿBv}UȮs#F*BvOQл +Yd0 ٙSka%dU,d/!_\TI[ȮVa(BvJ^BvX&!;G}5(g!&IȎ[Ȏc<^PҚBvܽ*d],d(Bv}\T!!"dao!&&YȮIak0W!;,U \t,dO 3]c1!a)Bvi!lkEȮݽ +H]0WkBv D8 K.dBv=o!;*d勐*d'K-dqEȮ]!tyjKC/HQBvf!;*o!;*J]0]Gy2EsRZ!;UN"dSBvnBv*d7,EnCȎ7 +ٵ"dg[,dG٧ +M!d79ݟp_o]k^Bv,ENd.BvM/Bv\]ktd9y|QE"dCȎtko!&YȎ +Qb| ٵk!dגݾٵv~aBvekBv|[NM"d\INENVKBv5c]&!2 MVk : +/!lٵ~W!֯oBv5mCNh,0]8[p4_ΫH"d7!d'Bv]Bv4䪐"dG%䋐E*dǙ_(T!;_4ZiKKK i6jKNÚEU뿖] *dCN!.KȮ3_HEKENa)Bv*ŽXNEȮ>)BvTuQBvhBv QsT!;J&_0!;7 a"d'sSQa"d^F3$dd3f!;UUNC/!;!;]W%dxӯo!;ECY[NŻ"d'K-d +iqQ+Bv(Bv~c< +IqwBv۪EEȮk~Es㥪Bv] /!;UN"d'[NݑYȎ˨BvE >P۳-dgs-Bvo5 Bv f!.$d'Kkay/!;"d׷^^_|~|$dy&!;,u~ +ɬ6d5ay).Bv]/BvMYȎ|ف[ün$d'HO1!d!dXIK_O!;&UYȎz!;0#UȎ"zk"~ QBv-)dGEȎ| +٩ZT} QzBv-CȮI%dHRdy aBvLBvQ/!;. +qۊ +o!;IUNYȮIjSȎ +Q"dG +iuBvtE5zEȎ2RӿٱܪVM췐ST/Bv2Bv2!;,o!v*dglEȎBvM&y8[ȮI!;žYȎBvBv!; "d0d0}V!&mIȮIkK!FuBvHBv* Qy ax'!;vW!;"$ !; " !;!;jD)dU载EHlR(S!S/4 ٵ{BvrS/!;Z7ENIȎ.[NYȮ$)dǣ| ٩8 5~'!;*o!;LBvj[Ȏӊ٩Z츪"d'KȮ PykBvMk운'!&O!;[-!;aBvp,d,dפPq !;-dǮQ.!;o!;af!;+BvDNo!;5)!d} ّ9!;9YȮ :욐"de!; CcEnĒBvz ),VA}!dG-d",dG],}zCCOBv1!&6!dE !;3|v!&>4BvZf!;">V5?(!&$dK熐5?T5ٗIȮ%l|`kf!&O!;6*d_%dB 1q~ㅯBv U^3}\Ȯ +\d)BvXaBvMY!;*d'\Bc"d'sR0V!;ug!; _?*dGEȮIgU@4VT!޷oBv􈪐ԛp!;_f!;YN} aBvX&!;"d +٩dT:0o!;UȮKiZt+,/!v$dGs +u ~ YX/UNp]S*d5)d׍k1Xzm*d&| uԊ +ف} aBvfʉCN"d +a"d׃!+F!d+EN"d(Bv]r/!;hBv5(Bvk +E?TܽBv-}BȮ;1[xWg!;͊d.BvX]mKNc%Ez೐,o!; x"dVK*f!;:w_DY] I-dGk +QBv3qYNYȎ/"d'}ӴQ+Bv!;iVaS?lfEN!J$d!;. +uto!.YYȎ*dǴ[N"deT!;&.uIBvYNcgo!;a0T!;,_0Bv*BvN/Bvg4W!;ލ"dG]wU츈/Bvf_XUNӈo!;UNEn[/Bv,db~ r!e8 Bv&MBv^K,T֟BvD$EȎnp㈷1rkBLBv?_Bvm_U"dO!;:WENIUkgx P^dx uMOBv,"dLj[ka#>i"d-d׷;~U!;[Ȏ}CSxBvLBvBBvBvBv2Bv2E,d1ao;0YHmX]NȮQ'c߶T,d'>O!;g!;f!; o!;EnjA>> ١0 ٍg!tP!;q[]ìBvi?!dg-BwBvNJv((JvBRv2ƹkd\הYvHaPQX8*HI%e6^JRv|K\T)_l/)$eGHi}I٩6K0K鼗YNYNS[/);g);E["e YNs/);Yg);f);!:>LRv(yItxE~׈ڪo);i,RvXH\T:-RvMKʎBL_W_4\؎);],e勔R"e׃J)/RvUʎ狔],e4H٥H  ďP5Yʮ;3K 8IߟRvi );I^EN"e勔2"e׏Jى-eRvUnXa);JqHىsH٩6K C搲H-V);슔]W%eGYHQRvTH٩0\);5GRv2);,U);n,EΎyIQRvT|ۅ[9/RvӋ][);ھHaRvM!,eZ&e',e3>-egPIʮik +{IّmW);`Uʮ.gHR 󒲓H2KKRv~OJ K3,e,t:@RvB# );1Rv (HىjH 7IفyK%C);|H٥1섨)Rv Hs#RvR&Kٵ#\C)fk>pv%e'kHayK5U_g),e勔j]-]U,eRve֪.e'm ENEN|]]ZCʎ/(Rv/Rv*eGQ솥HٙyQf_Rv۫]/[NĜx8yRv*ecRvoRva(Rvߤp|UN8"e7Yf),);>J_t)EK-egYN"eg%e;KٱW)2K sH5(f)&1M3YH);^*e'"eENhR솥4]ߩRvN3NYYʎ>);#좋]d]7,e);3Rvf#ήRv);YRvORv]_Rvn]);ν0W);,UNKNEʮX43Rv쳔iTR솥Hٙy);QJzߪo);EN<ܳ/);EC/);RvX"eHaxK:IYN~');& /)<,6T]?IJ]Z]ZCʎHى%e +H.Rvi(RvRvĊ],e',eץHّJa+Rv2LRv%eG);.J&en9H٥H٥5 ]JC`T(EʎsSH٥HٙuNu{"/RvXYN);f).O);,eח^Y.l!e,e׉^Rvag);?'),e֘Ǜro);YgP(();&);uP0츪!eIn=KٙuuS%ed,e5;)e' +YʎHQ|K,RvRvW();8]ݰP!Y}(a9m=^ؔUFͅ 4Ց-ZuEC. E-)TTs -ۧJ(u[@FSNr5PmP$ʓPk%)NRMל*hDz‡aKkHӵݦzSUa:Y}[ q㗔[݊YDGt|*89K?׌HϵxB}=sf\RP!94d!9n^ìsXdI96@8%3udIV| Κ.b="B##(0#F{pVc1޷u׵"&3Zs9 !簊'9zm,\ކ+TEr74RPJӷ9Pdd/'a7=5D ͑?~As+$c( {)`PP+"O+&3Gp1Q')sSTtrche$ol- St+wcoo˧5O'&鍶J;i&rjhrA*)v,@'b1qW\&6<({y-%N$$nʯ#h)rދ+94:ؿ=rGhh7rj$O9Z.BPnNCg0(;Unk t X@<q c̑*՚qRu)츥:;Ne'Z3[LJS66d!L;, 7rچ:9`{99~fم(q7Y9n ;9nAl?㍨L.(;e(㻏"J˹i,`"h$|rDZMJc&oSl]Coy"Qiqvk9ข/ Xדqt9 J27&:C8*۹qh5q{ܓ8-AXW61qOӖ\?/; |p} ;}Xqm5Iq7(N =?w'0q.&HQ`i>V6q8}FD=q " .p!N<yaHx8=l'NKh{t?!/gI2pu/;<^g %Sx8,@v·x}JfaPv4|8*aFx7: 0NW,3ڵ,#C Yd&:~ N{Ņr'©~í 3 ^2 +kHp6›wM50p>QC6n#8pz@]_[Jms4D8~L u!kG=9pR,8)4QYb_8p(Zgd?2w+gAw&&28B-90p '̽(˩@ۻd(N#ŠM!Sl8 =2 +>l232Y[Pa@Ys/ +6k6\8μgQԍюԤQck.-%Q8w;D[ټ%dqpߋRmT7NRCGp=uM-wd9 e8 ^7{ϾoRMfRO0&M_O\YY۔d&=0&Tn7Ӗvbg߮ȷMF:Z% ľi{|sp'QC߰maA3oK؉oS ZOaiMFD`FY[I{;ݧ,ޤr~p+6ggT:aޖh7 o&&`9 vSDPI*qLUL?ݐ1uB&vǙF7nVwVo\7(vS0ѲLv_upMjp*Y|qmuWYnض,Id786NB};+v#;n(Z& IBI&6nf i f "nb.n}l7ߋ+̃npFI%w]3Qi1S23Wwlwӷzu!丿nr_l7Ђl7hL3F sfF0$ m, !Nw{kpt7$%xt7^AVtAw@$n +%acLލV~t %43ލiJvqf #ǻ{Nx7*ˮ6n?ݍHt7j0\ 7 r?)Qi_l7Y^ZeEx=;MaT v;Rzr$YX7*Euc@4GL//|ߑnJZiG0nb@ Mo6 +xn7t sB,}3AnOs&o~6q{(5nYP51p(kíD|2ܴ- nX3Í({`L%nN/-Ɛ./Mfx{1ܤX\.n(Fq@5$sڀMšNp#G'Ώ#l|Npf'ܰDg( +MAV?&V p{]o3EKm;yEk۞3*wv`LtV6QcJ^;~9m4&MUT?&l''#ۢ4m\#'‘\{꫻=3qmi+}RVhINBAnmTIBIm*fUtpTMDie‴ayhS|Jkdt& Rj ЦUSj泩X[=8ki[DNCP*dOvjsIfS7֐a8eq>lWu~S/^x|8mF/mI}>xǦx16LcZ_ruG^ff8Fb${Pl +Gu44ɀ9lXR{ǰ$ +aQѓ`S7+`6NoinO6m40nf55%?Q&`"zLk$]5y~HصYA]S5F]#aXsAn/ 50A +5>pMŵ +ƅݘڴc$ޚQ'Q8뤭&[ӞV*XkJqF2j]'iMgY%Ӓ Mݻ}kCzT:c-PgX`mt@}A52t5 vXThʛdvXtjՃ&a&ˏ~nt&UYwb5]RMATӄ qjv QQ'NݶjM45s뜦&C1ƿ05TkԔ:3QjJIM5?R16U=%`0yAQScC L 5:1j*L5悚j`:? /S1ݏ=ޙFn&<Ji$h5<Ʀ OkbZ4EE:l=@]J0Ӳ`+N+QWiDB¼4nNi,MvZzi& +endstream endobj 62 0 obj <>stream +j";M3"΅F.LӨW!i&@Ib4@bKy-K qiR.(iZ+™4)"\cGjiMN#C4<"b0iZ0Y4:E2e+I^q渾iR-4 , Z%a߶V`ӈ&8"mMlwP@ yAuFsif +"ƞ=B`#6-wnY7\eMg8q +,nU,i8Tj4X7:(MÝخxtUi 2i8ZQнFYHX MjE4|Jg.n2lp0CqֹiR,ђi;&kZڼdrڇ%nř M{7{dq(' +pvnJg25M#il>Qܴ-.M+]#X6;9M+vNM2NC&4)u%۹itS<~Mbi(nH0MS΃঑)ԝM4}mr4%,-i892m7ͽJI4onS :"iq%n|dziD浨vQ&n%伇Mˆ9-iv7w;i:MT.{)=5 47enZ#!40(nnr$VSiʻ4|<?ob+Us׳i$hRӔe#`5i$>Y 54jӟPtU);f7=a*c6MWZ?Ǧ\e;6.>=}4M_MC8a꬙ lyn6 ˉ0kaԴ,@iJt8i_ۃFDKL3s4Z3M8~. +U֪AK`iΧd#AӴ3! 0KOQVy@}2 +}41qfօ`i#Yn!+F'A;GI\+)@yi~߀K@:m(Y<\gnz'+M'W7Xi.Sx|2XifܓfGWfi탕&n + fXivK=g4 P,M+i< *#b`iZ& XJK{?;7V#!HI/P)dH0b5Jヌ1*}jrUɬ4vVZe/Җ47V.߬4;+v7 V +m4DcJC4 Z $TZ(VU>Ut$cImXuEֿwXTVI-X ߰4\wX,,m +43_j^!;Kq6X!n4;,M''t r#9G V݆7,*4XiRO*=WsFXhJc2Pi TӪu/Bm7Yb'q뽝&բFJ#rJe[S%\,?l9n *Iiӳe R] +FDJC4n@5)M4Z;+&#F.;Lm5g4[89,uO T=X8;}Mk-_LeX g5:zYiڎYL9XiZHX4EW\c|vխx+M ++uI4d"Jc7YiR(!ʬ4Y+,'Xiռ+=?5J\ҴaYi,d#zK[Jm'q`4Ʀii^WpX$SgåEjz=inLC\=i( @Lb? n;Hv`܁iyxB*0mSʋ%0MthC69h%^6q +12;/m Qx?w5*M3ƉKZnmf0j\4m-/xॱp_w̸4TM. 1AiiIhVŭV*Lٿ҈vE+Z9+͎8ʟJ3t +OO*=Ge")m[҆;QeNpIcu^&%mDma⃶nN;[3i DDIa< }!~YEԨrh4HSM3"3&MYP4b&m<)$`hʋk]i+ Z fM +*gw}vK֖ |&{v%K;LƉzvGR١g|'Dxi!TnoN<!_V0hTU*@n,h˰3ྭ,v:BbM5Xg[L$:#p{_i@-%L.f5^5J`&W ˎ盧 +RW9`rcfCpw{Q`T, p26Z37;7:f*NWm6ܛeyot͖͖ +l)Ě D5wxœz+H3 , 6W6]#jgƏ+Vpf]vQ(V7Yf;, ob#ztu¯0f3~H^T2u]2vtuY^#T˾䠗݉eZ ^fB/x٬V2m)ȭ,`/#(f.d&k _fr _~=trr2r^b;5h`@|\0Ua3%95fx!0+Xԏ#'~/bxo.SzS{4>Xe4_N ~ܼI^˖e&~ָKC0t˨Ҳ8ff1[,T0ـfg0OI0z>e}ړt _-_V8&L\/ʞ.e.)e%hEeZ=$`Y>KPܢ $a_VWȍmK4c[uϻ.(_6iA%dx3ХGD ^6Eg\Q?5e% ; x&̖ tJ]]&}}O|L2}6j,}$ӂ,vtqgFl*]6`.cW;2T/Td.S6}]'e\GmJbdQ(r,Huߙ]F 'GBz,p)i}f@mt;LW7eSeS z4: >S; (cLL0˦-C +QsXe__TH-Lq$A9T)~zo痡&~>M#fX"Šs~vT`eRcM݃n +2l0R6ǮEBѣHX yy@z%m ~щ_IA{^Y`,Dwz,\T s2.sTYL*SORu{n%W`^AgiJYPiB&L2p)KU{Q/kxHUz~y})N+/yWA۱zS7b39JL!_oLjz'NTZͪ2dVtSSta,:6}um'mL\T2z \֕hgݘ^lJx˚7T"z151^VH^Fmd5 b4F);!4?Aa0SEp:X=[̅G[mP@?Ao;M4&=q:gWJ-QkI궮ZWL&뫁lxI?[teϊ,d(M+#R?FNĒJR-KeD6ӷ?mnL`B6fGF LPTIm>ʅײxRҍ +n:G"y2B)r#Nja8 {bi/eE>C;(;+J|u`QwXt#&ȑF'g { +v歙nr9{|!da~K&ž[ǔ<0+ 'Qov<OZ4u~W3ɵK/V2/N>AJ0S'?<ښt@-s!:,-2c>8 +=Wme,Z&az¥xIӳP&~È[CP9sxN`1k-Yni U*]3.0Tm?K ~wl<kT;29?vځDY9ʹ 3B9ۂ>}oj.n(Z7&?VAiw|G 6SǦjQz T!Tʽ6yac b=]MBtm59 *)u]7ǝ#'lZ/]%ց#̺XoM2:ʐ5tDa]{{v!$S]-2-)u #}u1L5n0dTGh*8_: +;a>=IuX.Pq1T*&T OSVϮeKROd6/r |8pu!ߛ;qPCAtQ_Ȏ9ΥYeWf + +}YCIc#wex)]w:bҬdUjOE{"fAGmЯڡ(k.C?*Wu {f,Tڵٖ,r딲:8Me)vT VO %k'-Y)M{iT e^Svj9n);x>fOXm6K6Tba6\2KaZkE()}t4N_C[ܻ$L=5YX|ٔE#KV'Cmև3k|aRJvYP |6e_rsWnG}9Ԑ[iYMOKP' +bOՓduse +YoV0eT(xn^~E7_Cfrt[O͊Iٽ-~:JYiv&2=FfAN:~t3mxSy*]Ք@٦QYtÊV֬EU^ӞjTs9=aLrox%S&/z|{CdoSϿٺ ˳39+AF{=87PjyJ4_Gl94-˩RJP|>p&Bv֠rayuuȺbr.>Wqwd`Ild R\5{Pr"۵-UI`ȯ=tF}UX3>C_ǨCP|vXLx.<5ۚl%_^C5 +j29[<k)1jH)j"&JJdzsJ6ZEnVLdi,b}}4s +1W. :3#j>&tnyj)Th2DԚ&XŁaR//e ;d:?vn˃-|Rp--5hkj>cKL#4f.@EߥP>#"]D_FKWYo#Zw#]CfsUO<ޘ#jȴɊAxL>8 +햩C0 ?[P8ZeNRC 出p +nDNqf/VL"[\YA~l w0)X``e@"c(cXQ? +B(3Ci 㲚NvBWKgϘ +NUo1_Cc"6YmO5T9T辊pv B7'M*[J18ָm ]DImQ)n`44@2Hi[e;@%SGRS СP$I~'eZ--|$ ! GѠ@ƉEM=}·GN(ݽXWWMP;`^2'P\r2\9ŀJ[5mR T$Sh|*/գ1sRlS'N-D RU9(+@rF[Vڨ =x@7Rx1Q]EY}gMwo9?;-j꣇S{t^_YNL4] +Fֺ:r`tOj*s4tR̠("eRUfqf=gB2÷ zm$\;$Fn^ EASb" ,^PGr^K"8ҬU +>(UJ9iW}(U9X@͆alG9[-/eZdFcfxث4_X*/$C֢TE륐iQKṼ6;B{؎@&u DvNUJ*i?j9D%IU'M8R'0uKӂ4 U+OũkV`2Z +:)M)hɪSg/f9T;ɫt@DO/+NkM'_EgJV 6Xzc&Ұ bX?<{R+4^HO(Ha41ޘu +6[3.qc%j5u:imʕmrIwPB؈J +hPϤ::՝/~87l](GD sH\V>ݶ :=n[ 0f07Ae*VeV[WsQ`*T" [t1qO;|w=+~Azpfz$X2P{^J}YK=rrBV2ji5x]+8f-JU'NPߛVDo%CzN)r4X"JDžFl]| +jJFYɄko|_XWZvޗ0)u"h}xWbck^ 5ra5v`G>Y/QN'f}9-+tIrÓ(Ծf*c9эX2xlH2 eUC4O~6A[0 cUqE)ZE A:*0l8Fu +g/u Jz쉗pzB xn?ac5<Q3(E*uc]Q"qlpEl8%z) g7>V~g2&nd9z*$[Fxx"cu, &uXKeQiS,Q/۵_*hSZϵzYx)5R +*IS֪G/&9̲_독LzQ3xi}Ea佇H&ԣAv`)6?rMk7Ӗ &G;!j*bsO2[ӫHMI=4lV@5=X^ arnA%nQJgIH1z^yqL +8 uo(TvP @B:{su#HxO1B+g>S?JG7="=X ޻D*⮤֋%շ7TVmd5AVŰ},(_kROguEk2} Oɝđ:{l+kmdw1߃raifDz%|-VvF.+ۚ> u֝"kZ/]P |>R<,֣9%4iZ~a7lk,-ۿfťdey +I奴^a2)?<~*S%W mKm_NㄐRe=qge lϥ5cogj//-"Cs +诞W:6V{y5}]Vف2BU + =NQS_^J33|g +ygT0~1E3 F*ɍH^3?֩U;U6PH;HQoqaOŖ4Zdb2?dS5)~UVh~ȏHV7;jh c +8k0Q'7?Ŝ:۞{+). SV8]gEWD4O2ٱ䀙En2~AS^'Kl" n,Vht5A*˥:1KTK]!浦{vi.^,~ZPm&Re-XX = +8iS(rZ-X0AOThաMӓfjqT&=4ѥckL3Ðbw7P(èrgR(`k2ED AQ6pO/B3P]_ ~D%h;7j(j r41͠HX[=$ň5@ZHĿQUC3lX8I`vӗ* k c==~`[ta'gDKva,^W^C3N.MjL1n?bEG4k{ǩA@Vq|x̴|(MlOÿQ薬$NZOWtLN(Kwa,@b|EgT + +6c9^5 dv3j 8t;sTݰR+,d'wV,Z?PivFQy_L +!|}f}J)K؀C,YB-K)h[I4ڋgsT goQl|FJDqkF2z>U=7yCReI~2P|%b}y-^bO3Xv"XTۨ@z^+S-Ai֣xb:N@4dZ!M3zuOddbȇu.@ IV6%$P&5p"ȤXyhSi2ryZ܅4r ݉d P!d" 1($RETfhV%f=ߴt,PVt[lnJL^w3GITKCKsvGy$"?R^ ^,m&g/T0AӣowՖc)kr7'͐6Vj!1x;! b2H0CŔUܻ"IEm (QA=nÂy6H *zYxZVZ 8sPIA'NoFÀo +z$=4q$oInڽߠ@Ѻw 7] +v*NSZike-( hYb]GM^ڲd9PE%{kD,Op˙2Vl. ɷq6=,Tȫ^Ou^6b,նhXӗcG(* ͒ʲ$:MKqsRRvx"#ŚoCZVcY~d,Wsa@;7*SB^)f"ZGȪ|WA 7uraYkRFP5JƂU/%&,(dnoQ1OsyKO\k*{h8yh#G͏Fy eG.T٘q%(rCBe'ΨI"ۖEK%S6>hR+eUQI@[".D5dLb2dR51@rh@ڿI~P}|1&5۸OZKTiD^Z ΂TONՕj2)&sbPU H%*2=B`ըz@~hUf"_IY@Wd 3-Ɠa m֧ yb0Fg#pr`)JANܗHVtVLDx9vT5q^@nav$Mh7dBtE!_7K2O] +QXǫ籮J 5H1(KU/LaY/&=I#Hu" dlwLdOqnJ&hw'룣[$К3YB.:Jo\CaʿfSy98T2n[{ik=@&U 9 [7~',aҧ🱞+w~j491r\BBg[YIaCW<-(VR6n!I{*r)v  ` ?z,h}pTҥMVoQZ?ݰ;R9"r3yB-LJ3WM}*7É𕴱lH2tr$W +jkR q;ZY/[INRF-42-N".R 0ux jfp)ye׶Ѕ2L4+:d8K^R@f]letV6Jj2ML.Z +ή b('ة֒%uS},EvL8Y|WpboɹèPȐ{y:P13Zk[ɷ7~A*kYc7RCUP (hjPY:u݇ץܻҔeޥمg*QX܈*֏-X~yO>O|]'N5}JHf TUy/3[aWT?^ +598L !<5cM 7![d1/ni :T"ȗ' S7ZS TTffG9۱_I6ccTu/=#Y8G1uKJ0ynQdlriS8HJ𱉼̠Yl*R7L)뉙MK;)F!Fjϩy;{n:>L2g=<;Gl_i:G7Y8je8Kd3~>ec "k[X )(@dPֶU;;@6|Y<C;2uR+Evy)p?aiБ.yUD'dB҂_])떩=C-&qT `iz;h$k *`أJڦR΍ɇ5DQDIF:j{SaM+Zx{/hW(j4a%tFTެ{#*mRuK{r*u#$npB$XWV: sLm͘m OٿvǾe {z;EmоS3E%1mM*Sm-Rȥx3h ]z+{++ֺ֊ΪJx6ҭD9lDWv4lDʁ_[a`02R{˓+kK7W1ncS'{tĻ~AhӸtUwփ(<%ށ|`ij~)=K`E(X Vj`E-`EVc|^+J`E[Zg^ Vԛ+bC5$b%+eb`E `Eno Vd=QV9`EVD}+afb VԴٕN"obVtKIMvS?  VdXa弾ȥn`EV(9%dz,Y/`%`ũXQ<5{+;Xf)LT'b'Z+yV_\EUDI\r[_\EٸR2W/J2W޹Z༹<_\ +Y~**"'NW=.4~*rWcUlQ0?\E{^\E3h/U$*W*\E|\E;W!q|qW%q*J\E)HA՛UlXhm\groUUE qk*Ҡ*VБWR,s0U$ܖF3Ws~s%޸(ƛ(ܸUDyseow*bQ}súظlWqSv⒃X',p oFUԷqs7ոU&*bo(ml\EN}s%gb/q%*RCX&RWqZ*CUU\J*nsU=H7q5K**4+'"o")UdN\E|?3WQJ*6_\Eə(/b%qs5Le{]ʋ~p\EURe~p%g"\{כ| ~**J~*6ww"vHU$~QX\E*"'"J*7_\EU\ť\ťWQюUTWQ(UT\E߉0UlquE2Wq)*(-3WQ&BU\J*.9T$J%~pe2WUĤUDN\EUl*J\E)(W?U$Լ*\E\MiK񃫨g,s'\%WJ*sD$"U\L\%WQ/'bh*W۩UR~p &UWQU W*UĂ9sdWQ.sQ\6Nh\E}~a*)q\Ub%b*jpl UW7"QUN΍0qU\E2o"%S3WQ+\E<WW*WU4UxUDN\El\E)E{*R*WQg**j+ +WB7WQ[*?p􍫨AWUdO\EV3WQJUbr"\Es6ϗ۸|s9>W7"=q*Rsuq o +2WQ3s5*ZU%qmzq}W*jHeUd\E߉H2qm* "P7WUz~qPpEwske"r*$"+7Wq*Vw\EMٙHD*R2*"'U*L\E;WQV5(%sUx*R%s}q}۴qL\E6o"U$UTbsQWS\Eə(e*?d"UUlv"v/UR&"ʋHb*j7*Rՙ$W7Wع%"l7WU|X';n\E?&~}***J\ES6b:qqWUئZpq&H\E?&"#q$U$siH\EǾ2W+U$*OJ\Qئ9Ud4ڹzkW.7W9qd\EmW;WUT(0s2\ERo v"b"^8M  D*U4&U$? +$"Y~sI%%v"e"&)q@\Ek6ڹ3*rj*ⶻs=Uw\2o*s\ERljHU q52WQ)\suw"yom\E (WQUg-qQ\Eh9H΋w?6?UԗU4O*6+Y޸z3W7WQYUĤ;qqg\Enr*Fzsʸ," UH!UZڽd^\EjWmC*6Z_\Ec*"*2K&M***>v;lCaa$"E;WUl4\E=Hӛ#qQWюyqUWgrI\E ?L2WQG*8WQUT)O*jUg*RR~pW%q7WQ(Ulϙ0O<ɹq7eG-90$fD&<ܒ6gz*b*&"J*JU*v&7Wy.b?b\%$&1"E\Ex,胫|S\ECbUfU= ƻ!r;X +"+Jl#+k‹(L&+깲heu;3Y ̛B&+JIdEVdEDVɊdEzo"{DV:dEɊ(ȩoDV$ȊddEKdEt3YR3"+*ɊĚY7Y9QY*Y汍H{NV$&+*֐Ȋ-񛬨*LVDV򃬈ȊpYQ|&+*Hx"+RȊ +"'LV򃬈A"+NdH!)gMdEm~μ;YQ58DV\WQJȊ XoәHFVdEI;Y/"r"+$dE+}/NVT|!7e/nYrG3YQYӓDV$ƷȊ(*HYXЛh;Ya"+jG"+lHdƖEV$>ȊY,͛Ȋt&dEBȉȊv̋+ieJdxM?ȊZ%YdZ/"<5O"+R&+EFVDVdEkȊl$bY"+5NVTB&+։MdEȊ +yYe'+GdExYQw&Ɋ&dE2YndEʬ6dEqHdEwV?Ȋ"c(+DV4d'YDVMVzԝHt<ȊK"_;voqmvVH9؋Ȋ((MV_dE)(YNVMVdE6[&+ؘK@mEVԤ$RYqAVԚ%1x1jIdE74);YqAVlx d6#;Y5mY~%f"NVDxh,ǩ:ȊKEV_5-2bAVȊĆYq)hNV6-"+/ȊRYMV''QY67YQ4u-Yq +;Y1IVNV&+2A'"Ŭ;Yq 8J(W&+zEVKdEgY;7Yр<;Ye'+r曬Ȋ(%^dE}NVB&+ɊdEkݽF"+j?r"+ENVTYQ&"QDVlMVT>|ȊdEJY"+RuȊR2YMVDNdE>l'+LV%$JdMɊd6ShLT4Y¹DVTv!E񃬈&+3YNV !dEYnW"+vVhʋ +⟙ȊdEeYQy&+ү&+jœɊtBȊ2^"+Ydl&+.%dzLG'+_&+{u3YwȊˁWKT/u R.0k%jQe6JT}J|܀?,r [SǞs07&$ `$6AB$j_ڽی*$駎˷xR}.B$NG4/g`Ϣ3ecd#苌FZF_9Cls# d!XD,BMuU,ȡ2/vmA B_RXNaiVebذPX5q U)t.)8иO!I h3ԖJh !of,3 e(BhIh&P%é '`~F*,La8`D<^\m=]u30º^hB&4NV`^ +P!J\*D3)SwyR +Q3g:YKj|RRԠ*rp flz2pbցbB Cc +K4OL!(m:>hu}a +dWpJ.*LLRpɁ)ĠG|U 0E灢(SH©Ph0Kz\WPhwF u @M ⏏ YB".QXno:ψBbD!3^@;fyDۙV +AA{dF{?i[MAdKpW=ɃL(TCS:LND(xӕHNB!Sp`;x"J} +9cӾV$*\Y$j% q×A(\J"n +Ͻ',xaPL<ܠAilL|BSk]|BNd|B|OHY3zmX5M>RpOXٺ˃ЃTC%w] O<'~#& >< i=l[&p)yTr `RW^~xt Վ`P_fat +ǧO +Z$XO%W7P5IuA W$Oݻ]z&+ٟ#Tj*,Xi0d#6PZ`B$BM'"^'qo_OZ.aN5 xi a2!ApǟiMB9^ !lJB# B(J`V +!G!tϢ>wyq0Q D/_ROs;N.$T6XH9WR+2 +-nu}ϛMiK`"(پ{ +;m. J!b9iR:,K&m%QX}'ڠd׽ 3<T\J .9`7s1'/\`w|=[@|@ӿ8r +Sǵ\,G@cVڅ܇~zّA]#/BqN?4J 9=b浐X%B)' J}HbE⯆ml%^z'*qx&*d{PA<% YYz!H6 ҙ#5xz}TpD5 L =YRq-z= Hտ؁Z] ti$PL\vp! d!ذ*?ʴ?}As(4x_32Pq/`/^y&j5Q@r3(@FX\h%R5X"?I6{u"-)p){ z5סDG$#E +TdW' x@)>@ +j= +D>j@#@nF(8(wN`^OsTwNN4iuWAjgY8;0z09% |e2||Ʉ@m6_XMmQcKL (%NA|| 2* > Xo@fx< v 5r )~ +`5ޑ (J :{0XM@@Hz(Xؽ? ifwXWg`$DV؀O(A~ x}DbE}ET'uSO`IT;OPQ]n)97OIS,KȿVL5,镀iu9NK#+ ucXOKsr2 N&xCyO]W&̟@ #Q|)F[aO%NBK I8ݸgf&dkaXγȋ˫g5nO*Msr}0 ]<"`?R|˝'-y`T|LGD0: 7~4;~5v?wZSG4 )9lFW&ř~!up8?rS`'6_UNӨl$= 74(~N?2jFC~- ЄlU75 \},Z-}-⅏Xhd%dUѬ&,}%ܧ:,ނۧ*j%^ӧ8ݶ*̾ ғ٧'vBz_اDQ8_>zO-V>ʰ>q1Oqzb&Rsp,}G.(}~5H>*`SR ܎cT H1VԶy<heꇗN@_)>f@_i(M }% +2lPУpZ"I6Q +ݏ1bbW–r2ܙ[-k9G]> AOB/ӫs6|b+͓J'ţU冭}E#ez Ч|OWT̃oѼ|*TgS:ֿSͶ!|9/:T qx[S?d8T(ո]|͊&^+C@Ek%82|v!#uyN+Qt>K |pqvh +W,:%$:_"t>͞tBGq>fɗIS#ISwY$:_ۢT:z|Ei? +Χ?7t*+Q1|nst! :<&O-$:_OAKG4D磺Ԇu_8=HGg' Vk`Sgy04*XU4ymT1gT󱥩z|I+|Ev>^\@ $ЇL<}RӿA&:m&gyޛ\mY}KNiŪh…(1-$,N@H69ZsN۲,#sx|(J$'O%Ft>2ȉg-:_IS*NzFubIt>Vg[=XWJYt>C{*0;;:y{,؉4/:y'|8ET·a !љtx$ hظ}j1|ʗLT UJ7|( 8_ew= G;ʠ&O) +6m>p61f!s 8Ī 0фf-;Lh\a"2eރTIh"t>_,8b :$GͧnEA*|JޗT,2ʝAէ"R'@G#0.d42^ Χ%ΧފG" G}/͇3Opٯ}jx#_f67wV%2 +'OB[O㺭r J։`d> d>-%TEVbT;P? e~[H/|:;-~ iGd>[;^+gx/,7I O A{ +P>Y{ GaC둹< Cm׸|D>?Y!$(|(Kώ9fv!CR,D>)Pg"_B &OöU'$_ZܵBC49H>=mVH>p#+ +aN絑㻱ID>3jn?$bZ N3 wzDtk~plKDʖd'm[r`D>P/"FDg'P "Y/9XiV+C ehT.(Dx#,֑BBm{(/!w4|Ao)Wr !@ѽ|,Eɇ|(;FuGIH>lH>Xɧ gG##vV'\ Ѩy{#CNۃg ukƳuN~L +Z/|Ҵ' A;L(3O2ƽx|zL<>›aKkÃHǧ:'c V=3vuܑLJ+x|(}:"|J Y ˉ| E$٣о-~O?M>J(|ԢŚ+ ' W"8|DmUDS ȂA+=ړ_U$" Ŷ4]!|ȸO +w$I +ӝG? &3DjGYj z&O&">YASW{:o)ɷ5Wx'&W`~h;f^à|&47[%_Q1Ӡk@ ˇL `P4*M, ֳrpkM;;HOX,'@s۔dɁӛAcrl߿g\NQ|Uj2 ʧ6}8'OgZ[@rEӆ:_짦qJqB7_Yg(qi +ǶJƀ򑙡zgQ'$(dEzG ɇ/bGȧ9-SrW{߽4zpFoX{5t^78"f$>qk& U N +,p3JDw_?|y4+|FdAFp˩z$ (9J= 8|O8JtcbǍ'u/ CrOӑ/ӻ"ș9k='=z%P{"SNuM'hOu:gᆪwSieeA[J-9({} `zq9/JgaDػ=V?{w۽2^Ot&9()$_!zD3zwGۂj'GHy/af-աzD'*OIjhRt+K>ɦzN&JS ,B־2 ԛJ\Ë';!fOO"1izWel2p1L75Q;43%zH +|zw()z;CO `ᤆLnp3U7U( +xpgx"#l~I`yw_ؼՓǗ+ y-f^l$߉b1gu']9 TȂ'Wn'>q-JD^;5񺉑gU2԰Oy2Jg <3p 3&ȓ/y3$$Ϭܜb Δ<-0zF$O)2$r@w= vs2&7G +Gq!yHLH^_<X10yڣ٤?Hw &uLI%%O:2~aD9 y*8vtFvDTHI+3[PgJim;!O*-C(~B3L!`E˕yiwBR!oAȳd }3!OEU9 XXqaCDžBVO(UwzE%ݍVc)QDϓiYwTǾ?tK-^W=:m㇕2w?_|ԍוzalv'zpԸ/4g'#m%½obQ] GKm8;YzRv^1إdnT驈ٻNn0bHw- +iQ"4jm +uVܟ7FS7ےE6ZE(Q{=xK|d}4fZvb9FQYHlQ>ڏ2RFǒTJT\Rv0e2`H-pPq ~ٛmach]@:>[Ռ=4\~,}v*R:q|zA+;[oqll혻8|F2~QWܓsT磅Y:-_BhN35b7T󘥴;UF{T\V&aRZ}Dm b273 +oƊu55+X!n yR0xM-݅5چAT]יcPޔ }ZImF3E)U>S%QiTkwD;U| ,+ެO,孚odޔg-YF1=Sc*E`lE֣ `.Or5n_ǎOuG_5i}DivT:6eEKmIbX`CتjHYNc$Ӂ8‡F^3(<'pɔIE[/v2}W2-!qzU +s.톕G+ S7Xj.kRx3>o("$?&Pm'-C w7&ۚp`)Tm_>xYpjGI^^uil9hרs #wez*]ָɖZ^t*=&a*RTŰX|ٔEV,-G"ECN bgVbvڇ-0u[ʳc#mxX'_Dڭ2롲9QK5֟Փdʟ=fe|mbz>ʦ08nyMg$ԒQM!Ic?m5Ia1eʴ@h8_b|yHO߶%ގ{y]R ?Sm7|֛^]Yx񆋙b\kA(˱o14ӴekEYXܻ6[ኣ6l + +Hs.s*8͐/1X؟*Gpu~Fc(ʫsg_k_vbsZ.% SV65XL,nGe=?.v"y+i{8}(DY.l%7)QWyZTeuKun8(WIv( +7+ƶ:,Hgda|W:a)kTاUWgkk,ŷ=uq`h"i)&Nʒq\CE54w+rLmS4%赚R;x^@\l- 7)*.N27gw1_$tUj;an%l@dXzGqޕ-R{p{8LDl@U*Q9C̗k-j5 Tb~gl@d=e@Ž=Z`!Tmqe^@(%kqV,` QHX@ج5չJ!T230b%@̢5~ǢRȎYKwsD6Gܵ +r藰 ";>.S +!a6,b w sd-)^RAErWdzm뤀 ҔF@|+\ԁ;Xda;؉zqFQMmtiqCZ4}^hexwVeZAa]걶w:kidz Ji!u[,z 1'gNj-~( ,-`EUX?}/< @}:l|&"FQF"cRV +I}icGhԉ쩡imVS%o H,6R"4C{BWLmZGjzya#>Q?FoAn/aՋa; +5*Z:A0t2-}wTLxN +#ZU01s2DU ci +)1z/V>垆+v|a!4zl:mtw7RZjiSX+r(LTOC«ve"{؄BdAcmkt*hBneKqsB(WŊNYd _ECjYAɃdO=XR˺-+RzX]E:7JMT,51)MY6⠆JMHc(H?wS?Su[b eúR;J Oj;w]Lp Lovzb PeiA~p )VJ`*m-96R!~PJ(e&c*l佔VxzF# +5+ŴPsgX(Cd<C^V(YȜ*δQ|ZR6h!'7Ug,W~̏!0SUE638튐o0on.T[/=2ևJq<4$D +˞V9E =/,fn+;[{R+TjdO՛\J uz %?SYMZU2[nۚ5aˀ +R<s-!+:f"1mse"hyT4?ǏY&^ +^WF6(' Uȉ\dhIߨH}٦6UeɩR;8CI$a }0ҁI2TړnHf+- + ِjqA"B)ыQQORN3ڎzWR$,S)BhbӁuYi#GUZ2~@`s9\P >޵߿"gFfd{MBKUjucʻ*J yy2g%ʜp(gw[蟖 +ܚ,X +n&Y$hVW})n*ĔSYF'Uk/ 8*\lg/g&؝HuV+*b%ۉV`7hźIY(CXFܧsZ6 +0Oǂm3$Om!memAݽ,{5k8C lDY>q}o]. 4h9QJJ6{ÙFj Q6fcDyr.>0p(i$|WxDDm \j&HuTR<ٌhI'P0yw`mDNKm0kvimV&zƬV ZLTA"h2KdF }EPY52Ї²]G6R4jh5a4LR6(K:iFpbn]~1 !=`p9efЇWl6$)Htz}R UVZK5nzܪPCM&TQ%>JwgWZWju_1>@! dտ&X^sXyE5DPOXQt4:[~X(b|i0?j8rq2͛"8$(m+Ѽ렝n)؉AӴP5tS]ap,!7 tÆgcek )+$Æ|_j[/UngΊ_8= L _Z.EgSVHg]\1x|*Ovl,9 j8Tқe-Գ4-DŽ,<{4*﵍i8eE +o#@!K +Ό5U fjY!9)5 .8Fs(e;!Rp +b.k+L}eؙySRR&'󁭆;/,xZh)>d|uϰWfX"oSUdE,0Hkk ,v*^jU#/YU1~R 7 +%ަCh(E\lJ;nʳ!ҖL +Y-EŞS +x9cvoKq2̓Ju$TRPh@{SPK hCkeOSՎQ:]bcnVf[<΋ +c"X/zHH?Glzn~16n O#D5q\45'3%@m%S_'+{z6b =*B<׼TU-a ,uCeu< +5<7-Vٿ,6K1b"Y*Pf۝M-Idh?]Y]jd>ql{EVL4g=QM& ӊWP4yˇ3p>u;Qs|*yx*G5WYr-!oE** <`tcP4O.)X`JK4IŠ hr _~h\\ܳR;*{QuByoE1TR0:(bacy>ZNs1JύVqy`jښoۙR1IiflEmD|yȒ'6gG\rSXo.lD/ڲ& r^W*q7~"UR[.ec\PȉO 3b7دhVhZ>R#31?; *TgQJ߅۝('ة֒%u`ZՋZdșxW+mɍЬ͋.PKTuc(IgD۷ ˍh 5|q+\[/ 7ƾZlvAYr-QY:da+2veFHSnG;ٍق&r#l SCcmEW5 ֮9[LD4z2ܶg_X뱷]]j+A۲ⷁ8TSCܛZI O*y Ѯj9B-2Enoߊ*>f{0U|s5;AeChlcCHk+[МI.@so Y.~1\QD\y xj +k('*mºퟚDzɥMAt*qjal4us|AȔP L&GTwtaH ;>J*9<;Gl94fᠪO<*0PD֎W2'x(~٬޷SdBMʾC=2u- Z}ָ{oǕۺabX~D'@ce:JnCCiCs&@QZImΌDYUlF`DXD1q-lRFP\j@IRxӻ>VSDܛ +nn{9gdpnҠ 09ӄQyJP'bbD4ʳˋJ5R4=+~ja}; }?9*?Qh]jf<UvO|TcԴ7cp𱘭wZsWQ +ĔgG|綵6Og2N +tׅʀ'-C]}{PZ>sqzR ǻ>Q+Ft'HaroDf^_[aBzFBX[dەv(NE8e N00|T=ML4,"gխ*Ezqw`glg(9+;YbMVm4 YQdŪޒDVDIdE;括%LV4(`z&+xɊbȊUr>gMdJEVɊ>MVɊ k(s)/"r"+^Y$b~AV+6QMV,w`7 Gw%YhеK +` ?ȊYQ-=eYeY\7U"+@/bT22YQgp9?s|And)$RoɊV׋(y&+x'+.%0S6b$ȊYhȊE VDL`EV,r8}`ES!K`rdV,wob-arS5B+"'υ lehM7X=![m0` +X"(d`Ea3X pFD|p Z}X%/ VR~[ -/X{e8%g"&b;_`E(%1~+XR,Vc<5f'(<VDI`*7XQgCd"X]r\ XV+V7'RXq=X',x oF Vԧ7e+nZ XUP+J`E66bo V6bV~`MK#V$b1`ŪPQ+q+V"vb;_+V +_`JuVLK`XU~1 ؎XQr+6̶wbV( +V7;XbߣTx e*2X(91J`E"@o"r+rj+o V$<"o"h H0X" +L" h3Xq* +*ڑ±+:l?P XV6XQW$S`EXss+6U\'b7'Kxf&`E} Vl|1yX%ۨ3XR[+JV`EH hw (4[+~+nOdB?2X|+.%<(VԞd+?3XqV e?Jd"]+X۩V(o"V+ VT=5 V+nV\rXQogI`E!6"Uo;X3XѾ H3dRXqVll7"kXf+L`E1!K`EXQ ?XQ; V\JB`ŦVle++}[p3XR++ob[b+VUM%o"j+My%g"J+UV`:/bX+jXZd"7XQr+9@S+VfXjN`EE'J`E3XqSvX)\*?m2X~+~>/ VVXQr+J+Vwb2X*+V6;XQJ+~ ȩ;XW+ۥ Y~KbeU7X> &Kb%CaXobUQI+`V+ (%+֧}QX VXIH`9U,KI`%Xc+j;0v+M`EPkM`E V\;XQ`E(%4K`E+֧~u-3Xq) 8 V#~mOeR6'M) VPzXQ`E+"'b>j+JVԧ`Ūe+N%`z_`E~>`EX*+J`#`ED`/"V^_`Ee3Xq) VTP7+7X}+Jc+ ȋ%" VT"m8˱7e+n+?&1QQXl,H`E4+JV v C"25Kb_+VԼڸdT2XqVH +J6f` H|3q`Ems3XQ?&v`ť$h5XO7XFVq +{{M`VXXQbB+↖%~XV oRX*`fV$z$XHqVT0)Hy-ɲ9n+XN+L~I$7n`Eݐ?F^X'"/"Vz+6r/"V[`E^`E̳v"IV H$0QXѳ,`E h4+H(g+⚘+*B``XX\p+@`EH/o V$g]K$U^`E7XV`Eo6بa 7X y 2Xr"/ƸVl`E7|+J`E)+"`E;n+xlXQ9 VpA?XQ"C+6w"ذ( ȩoV=/XtXQga VDf`Ej~ȋVdI`EW+ٹXDvj`Eɥ?XVc|QX8 (ҙ V}V+%+%kX*+*5 &XQ{` +f+M`Eºobb+I~#?LXQJ+3Xe+Kp˖D8`JV$2/NL`E,"ݱSVJ&LX -bXDa2XVԛ+ֳe"B+Jy&]Xu~a3XQ =  V0V>`Eꂾ V]+5|&XNz`E2Xj1+Xq;RXzԤ+Rl} '7"aVO '`EH`EZ+[db5VԨ+-X (gRV(9y3XQg2+6++$b o`ܿ+V$bUN`ER(y+V7χ|9>X*Ix HSܸjJ`E|ml`B +F V{f?֬u3XQ+86b s VԚX҈XuW$bʼnVԤ$"Xі/b +jX2X^J`,3\^`q( XXQr+Vw`j~XVX9$7X V$%+Vl^v VzXjlʊ%`EzXQ `E2XqI`Fv+$"3XQVԟ?H&"VXQr+I`E)oVR&" o`E3X+R֙HXD`E^XVTh+Xr:5PobS23XQEob;/)X1 (%+i`vX+zhM`E>G+6/"M;XVT!5e +'%b Vlӝo+2`E= HR2XQ" 7 h+"X`EK`f]XQY`EVXqxXީ7X[+jŖ~ +fXfV%+o"iV4V7XV=#[p2XI+ZVl+rj+6XY2X`EE2XV47XރV`EE2~$" Hh XS+b1+J4%"H?- iy3XQG+*8iJ`E}`E`E3XQ}++rt'=ͼ7"?r+{dVXJB VԒ VTV+xXѾ`Eet+j˖*XVTe+*bʪe"`E0X밃`FVQ. (9QXюyyVR~[&XVبC?2Xd.%"Q7Xx+R|7X9QX{#Pv"YƁlO d+0̛avy8,S^++&"J+z '2( V`EgY`E3u`EQvz7%(S11+*`EjYB+'MhE]˄VŽVb)BHhŦЊh%$&GTE Z/5td?Њ3ZeG+rЊR2ZQ>݆VĊ`G+.!MъThEoYZVVZ94hE}hEЊDYZ7Z6ĄV"7eG+.9Њ(%"B+RuЊ$"Њ؎VrHIB+RەЊhŶRhNL4Z¹V$ЊhE7Z„VdaЊS ZQMF+RhEmM2ZєZqɁV@3VVTTF+үF+*̑ъtBЊjhEZQV?Њ +&z2Zq) @+]*HَV+Lhw`gl/g>7jVb>R)}*jF]NPRT(Ul63E;Ƴٷ:Q#ړ-: (}s6;4Eݧ弿`Jm-0J<ҋUF@f)Y8N +"i>Gv-VRn19Za +4ce(Z`( + +uPZ@ڵz^O*DɜQ*GMd`L&KKT닖X}Ꞵď| [JvuHBB%.Q +c ^楗A$T< D"lQ7K&Qݚ!V&,b)h*-,ĦᲡd ѡ7_ j&@fjHB|5ATq gA #$YB b~]>לbE wvb?C8 .Ă19_" ^Bw_eޓ($ JiGex$ Xfs?Ӳudb +n@,Zkz-b:p2QOZP<$B Jed~@Bg"P@,]/WW݊(d r q` JYF|J~"v:gH&  ;T|`âBuPMU?<5ȏ (c@O!NO_R3q-.L|xzj+s!*/j]ON=T;z(;Nڔy( +$QM!I??&rH\A% UO.ac.P.WaGiܣCTBxԨ r(2INCN&!NN8PhDC}JxeY6 ٵc@CB4D B"nTyMc f4x\3J.5x +1,SXdӓxu`Ma^Ha4ԁtO!mV)~ہ+\luIl@å$''SXpLV }+N! 4âm,DĀqi$F޴h-N0%!M3bwM Kf(ÄJ1h ̤0CynїWdv|Ӧ'#6C3^MFabm| `S0BV),jj: u;ز{7Nk03 0C]`%2,gMd>,24ۧ12ߑ a"h͠N2dr>~2Ec +|pBy0Y~> k8:n,MYK˛w̬f͙Q.\(CB +21 +(N24E2Ddhߓ 5]٢)Hm$å$ᒃdXٺy,} .Tǖ4dM CLhF:\nʚAlhASUSMT  aQIo~ؾn `P/ + ᓶ9N0^YY Scxق I1Dh!CtJN>Fa(t\CxP6P֮ˆ/5>zb&gPyR.2TWҚ¸3&PJj&PYB9sbZkt`v^TW$"A+,JP7{+,j֎Nh+,t@J"o + ^ƽXi \fr: +BO^a9ܶl +K+,YoB ,'7 +ʴB/hRj?B^5mK0y֝PMA*| +Πϩ `%mLT 'TyNg-a1TD>f0Kd'SP™)M7u-)HT$:jb +*Bj2Ab +*D<^LA)&S~#KtN "Ž빾lZqM.1 +މ6 `QmU7Nb@ +W@ +}" +վ1:"8A +۽hϨ% Mb jrnY(AȖ:gw 8A&GPm6~&Tor!,m<!~ 5rB!9ǻJ3?OqmG?^с 9ߊʛOAu5WpS*,*>udU EN Q\i+JRÊNjtrQwb@Ū*',5@s:- ; TIT-fxi~ZaHx 3zjs[wE9b|@ { >g\|@AIʠ:,6c5\5? :`54jH46ŀTF^f1j׹mlT@&ITT TMb7+LIN? x{dBR@0u{9@UBN֚12r]͖2O g8Oa8*NӉV!g]?\u'_d̙) ߰O{eD$~yJcESQ € _;L֟|~e“YW?&T_`h8dcVY#{QXG~b5L_IS9loZyRPVřGd._isQzd~>Jg1P +Je\ 맻O_uRL_oL?D 'ү뺱Aw?$zWN#`~~40LMYlܿX~ƎOKmK'ζoۊ2P~DQ~Ym +m6+Q!Y~ȌC/7Y~R,X~i,B}O%fX ,'ˏ2K)yj3Yq@I*P~za=N#iw_!(/_= 'U@(TpQ~*\kF5P~tQ$?X?H~-O ֿ2A+ԮW”|PzY ?O*1I`Ma?I'cTjobQB; '갠ǼX搌|?j]UHBUOsǣM`r +v&UZMn+5$ +ǯ/T+_+'O}'ǯӆ8q +O 8~EdF}+WpҪ\icR 11~xsCt! &ǯ/s +;|%_/]&OOXQ^júszGk'Vl@28~j$Z8~? D Jl*H?4tǯDK-Xd+o'fWY]:IS٤kAS|Əgb"(0~ꭰ>a*=DхF+a̮uqK?VAj?z,?_,tgٵ{QhRa)~VW?=V?efY$͟+Q:!~6.$2& ?56!kbSƚuUP06kf S` c ?L ?=TOօ| _칿XUdSU+ۀrڒ SEY SE*?Vt?e __ ?4~کY5~ bŷ#n$]>hMxs|NO M~bP +]}T6T-| <!S#>ܦ}%OUOMeسAMvJ{LabǜOj#1}R,>)TPgvlUѷ ӰmS ާ)'ӨApvԍmiI :_`4@ oj9F^O +݇Le^Pxs0᪘uSMt gM}-[Jm7cA)}@!^{cY0}HPv[9O')W8M?}RevLӭ[6}"Qx&%O 'xH@ 6%*SxQ6x~7D އ}(;Oއ$x>Xާt}ZX.%eMԼh!B|4}a5T~dJD1Kyij܇}8S+LL4}Dlr^fZLr@_(Lb޶AW: #3 tGYTvB)5tX}4!s,x٣xU)~8O?M>ZS'. ǁ'E :}DmWaS}f)=^PT +AcX d*C4cm7}Ŕ˹z݇=YXb.}RUu&v t(]timY/v +W#8}OfN +ޯݧC+ xߦ%#Ac:/zV2j>mWL#Ӡk@ L PIO}cY{]$JgUv_}YHJM6~z0|J%~Fd'qaU%$~&;pk>Idӎ ,&|>ťV>Yg|qi+s|F#3PbQI!b}}R/vQ}ӓ>Śͱ'}ϟ{Ԛ&rvto8}M2O95joxqIA[?N39}֏GUBGc< G%;?_X6#/TA'r J7> p>S }XqXx|ׂܗ]v|Wй9i¬Xpܙ&lO$ 7 B=o $;oSI ݱOj:{]<>d!x|KI<%﹣){mm6i|e( ӯz-JX}ns >@S3-a)L>0|x (z}&IЎ#!Q>?CG{ ;`kSpl*o u8Vx-agM5{(MDy2zO?;S.<&zo) W~TaEAS=wUs +w6c_OdCl;[LD;o4IS3uZO*;LU{>F M! +goG) KZ32`Ja +Y3,=}V|}'#O{.WB魱{w^%,$ޒgo'JO;m"*L8bb)l8`$ɭ-tKhh۝'}7'Jڝ@z.$H(=W:o Qz<䓥ԠQ 0`:$@{My'VDI@a: y̜D0fM0=O9KWludr PZ>%>*jĔ`zKH0=KLJq:kizyb=;Ns_a<)1tՇ8Nc亩:G)(nu);MoAӣV{0:ouW1w^3qACN*>*ڬ>{ڥ͗~]/C߿a=7t OW:or7VcB,oeWe5~_\lyߣoyϳ4eGH?DtϾ9-=?/׽z[o[_}ThJ^qȗKX.=hƏKu.uOo][=͓#~Im^ŻwMĄ MkX~Q ؁^/cb72Ez3&RV66%)j˝s)Ǒь5ZF?ej#NQ.fele1 G'hc"^> _`҅_A3u|೻څwmU/Ks|i/Aozm]֣v/2*nH[Ίw|Dgőc&+|67*>`}:4Evմ^G5P|Dy7Jޭ#E[@ f\u(_}h2nq7`bV,ot6v!x_bCV)Ұw\<=̺5W^APk,R5͌]oRl^G[w ?@Ud.=tQVF!PLb/j*S.3t`pӞ._`[kg9%0 +ŽceŊu +;(4DžXA<KN +fð=tSCX-t2tĤLN||eLQa; g.WFtriRIKrKlP̀ 雚(~ނ +>$㎘RA=,%fo4( ez 5xSW{nNS=:~Re~4S''a}Oyuy鉾DA~z4ŧL}"}/}X~z~=諟^o2)髟O/}ۋ>:vb~KI.`MZ*ODp?~/^aTPj.Mfz D/AhChP10*-AД胵 ?Uȿ s>eyeNG^ޔhvN'`}. Ⱦ:mtELv0h[g +ٙMLE.t!('>j_,>k!iƠy}8pתMO*Jd0Jғ ѩTD%Z R]G{ַq+q5||m_*V 4Pu^ٷUٮop[жv^)DoLmP&FmuڵazF +&z{fDg}=;u: xzYWKȼ褓sAL$v2΋/{'%]@=\"U1}I2M{݄ny8hӾoJT|A{:o'x>dm`cM#.@~ %V{zW)܃V +b֩Zԗ:ۨͭEDECUvNw:ʡ:eA9"I j6F|L{KZ)`vmG{?鏏PU9|Ԩ] [!&I$Zv"we20I$xMN0XDV좢+QAvQSeJRckFS3c#CUr5Wcɬ mq\tet+/Q; MUM,6H1dYtֺp<[^bUf0-Ӹ@U;׳j$c2.Zpky'Nu}wQM3|G!PSfM+1U;D"aώ6)VYlks1n`͏})>Lf6Sj>LKe"G;XA_FCE! ݔF=|%ώ%}_fS'<z!0} WcyM+TL O8W8*W{vBP$G8D<y]{fsL}=s?B4.Vb^CXTF]Rb+͙5rKG0&mGZ tS:&e0R;:RSg8T=GF̈́obQQo껁vi‭f;U5l dzjxѝ|H!va6uM׳7ٞdtO*bkC1f ՜!V6ĠXߙ+kvV33bz^B1L5jC4Y m=)m#v*1;]8$gsbnڒa +6~MKfvFgʝ{5=0N Hi>j҇3CPo( -|uYFtXsI:t"O9E\{Okﵖg_2\`)sMWw p%QhclZSez>mMB{d5u3%?HNfүk(ѥ_3^Lj Jʊ&«8c8hj4!Wo`7)Oa!!dl,",YR|?3n8)D>#aώ|~,ΌWC hCȣ4{y w*#4k9H@5BL±U+fZ觲S u_[.}K&6/e'Υn69c>HՇMmv4N4ɉXqz0b +}Kj@hZ;߻WFHyO3[Nghh>N@Q +ȣ3uEoAq[C(3$%fbng7 xdbtK:eB)keAgRr47yΌUG; %&k)UMO0Ii$DMD>N8ч42qͺ(~I4=fIA DԓW3|ZXvhCvY/V $fSqr3ʶѳ~a>r6(Q +M>oF34QD=MG r(*.yv@/=ʬ!NZ*ckV[p?@n9AZu(q)-#vz{ƼAQ?}F,d5_g٨_D2؟5:c).l ++ќ Z #dkԇUr(*cgQC:Q@%u5rp&/!+WFC=hwbGLݼA cZuokݡbZт[qhl>XWeGwqotj oO + 5أ0Sp33-j pepDd]2*Q 5ck GM;%Ӯ +׃Ic,r*S!]x,SPbʈw,mf]h +׻օr2c:redң,Phi|7*"G 5 J*ͦTى7KB53 mW| (D|2dAxS3KEE8$`ԉ̥bN>\aB鹽gM0S3B4CrTĺ+J,b0@NrFU +v_e w(M$&QMJmmFhT{ f:Q;S;)jd3~5Y"$.VUzӞDII&]BdEM=AZC|O#i +@F +VtE襚#: 1)g$ZZNy׉ѽ RuֈUI ps -jP pΆ hpM#nHEMPmevmfkM9]S-TŬVmY!T A-lֹ͢ƫ\} Etˌi)v94ӳ (=y&DTg:hkNHV>}4+rSi/.wgT ĬBC}*cYiz~Uq 1fq.Q`ˠE1E5'"ԙb޲MPyKI.a|E =}v3V ,i~}*+\.D,!+l l3MZxBЄ2ͣH*f]A9ĩE=}6|8/.75Q5@zk Dž+9mv@V(J>{Ɍɨ.:+iŒͧD߉՛E|E[6=5 +;2刺?1e)=D~,?('3~ർr\5yCЧ.fGa/ܼ?$n@ѓBkKW~pbċ&Ї41L-{M0G$A\<$8MN쑨*API}%{0jtvfW4ȜшU>H<ƅ4)G[LhEA7DBQ2e_!;kB(L4ZhtA۞B*mz^ ITe߷,Bl)9VkVUj즟6=QerUQz hi~؍ڏiDQ԰RUnKu-@aǶrww8ЃZ4SɆP\LĨs^+1 ôki^ZBHN"jcW\=UR +t& \3ݹÊ~&j VUT%` Uk\f=Bd 9+&%.TSH!>l00!N-%áyLļ߭+ Z Sԫ܋[F[KdP J+ګ+GRuLxs&Y|pI\tEQgY3 +ZL,#=ĕ{R\KJK,UgӴXރfahq(խ(e;'!PG K^,$7V´&ޯL˸9L;DܤK~vnBEڀ.,znt7X4B5\(:J7*w%7&S=ٗPP \h194ӊYe'U7 K>Xx9@)uևc fYY2 -^[(tC'p=08uA=S,9 =̏+gˬ)OQyz-,o1lNæw{~B1y3H +Ta }+vuӐ,5T!b NPi.z"{)r6O:Tn#c"J~D1մRs-X$NN5PI-W'"Yj0Cg`j9NBٖ>H"w8䞚R\jū za0nЛ-W5,-tz,?>P +A 7fJ(Y5ɡn ڌ9Hv0CQ.N8,V >Hp]0XK^tcHyE[m/~CCѩ@ zvW(R)DM0cdv^iq0|+n St{ZIrބh5z9F5 E%톞ٶaW%Ea0, 7W."^i186fiiУOSi=(:{&N %ӷTcz;]މ_>>{Bc7VA [ +y  uU7ij=0OW̴Mc(~JUb>?`+8°"T>O-!Zgq l=w2RD3mBCz 8h9Qz?ډD|:6N6kFhj* (B9{SmG8MۘJ[KP S薇lbM"Ĕ:y_>zڄnCԕfՊH]ԮĢqWzǎqձNKB(nOLq@NsX4b m5ة% n"Ө!Pc#ɢ7A Se/Dr V/bo!tm̠7kwJOCxf 䞝Z/fU]pyOo@)==͙hB7-(^qn;6Wk#ɥڇ+mh@ nA]l&!Tt޽1 kd`:`б1Y#pxrRwZ*'P `OGj9jè@7T4']WEēS:Mckdހa\%DJ='В?cY˔i|/֙@PgTf={ +endstream endobj 63 0 obj <>stream +eԙ.b8\! +*c2jU/*S>NIʠg+HsjI"&D)w]By$ɠRb2}LŶTc*M{Jdݙ8SsfykV+0lʽTW:I@{ᛒ\5diIq硃Lpmg<蝗daQ9 9"p#}-! +~#`Mtqm0PaVfYHC#lo޹GQ+9~}*Ԁifr%u(wk :ͳgIʦuzTiD +12RKϼו? {VɛrD>wn?k#r'ݪVՂ]&}Mk7~XzZ!9"?v +VUS8' x;3ă-4' @[eC%7ZqbtC%IљAexܰϾq_{Cp|fp)F":%&+̒(2(Stl +Q.i℡-M${ ,Q.R7`hAވgS?`ԇ&D^u%;E#.yn+Ȯcԅ,|.G%Xz1 ,'DGɺ•B vs.ڽkrKGp+vM`٤&k +~=R,iZrlmFr<:!ZԥJ1nZ p!βoͥWw4GSSdhپQͮpWr + }5nޟ.#)ա IV#vh ֪b tKHT(lDOcrj|f|تAܓ9u<5y͔7su!U QN,̶;1zJveMɩ_3]t ~T9ufWJUfn UɩK))C\!ġHS\3e9KYp=;d@*0OI* +??Vh:eW-@v6M5 : \-1~P.1fJ3:O%Nkzu6y ;jED"/bO=:aMX& +Ћ&\S#~*P{DD Mk%%ZY :;LeP(y=|a-Fc/ItDKr-]B\g[B,Z$齑 '&G,>\!iJם$$^LiKΌ\?.5+4Sߕћث(8+pSL@% gF՘fE/R1u3jA8ag zp +WFrë+JJ~ge%C(x[N)Z͖qӜ׺{7P2BWtr~k la=:Zg% $gjU'{Z'+1Mן5سHzO2]x,BF 0*qW0欝43UJ!6y-`qB&WZw_ kƨ4/VU Y{t?h]{mWXx^ VːxA%&bW^L1*n M u=X5g1WF]Gžp#0 ]h"$^a<!S4K`JCO(ծ#{7`{) "U}C Eֻ6whi@Zx3hx-TSLthE̛ߓw﵂sO\|ywh͵yvHR +P2REfx;0 (qZ˄]LX6#3e,6;z?IWniӱNaM'Qtyj uxV3vtKe b/ hVg b [ V4%N%WbV.{0 etpjfA7OqF^4s2fA2ߞeź,+YO,Ij9~PG|O"Zj۽הBI8fjI8m[ag'TH&3)@{ +K>yE;әz-@Of\oM=Hev."e ɩ/Sfe2ro '[,G"h*!Zك2^BӳO^ uU @5nҨgj**BO%K~xS +qZHFz;SO-J0lqyf(S6s #MY#eLK9d df^2Y.JUx@H>٪Y0H][g!0krU"%^ ҿrpZ*{%X2R4kZfVڎXKc#:}nϫ P<~BQe>Tk#/s}H%&'ރUb(!Kq~EΓik}F+ ().'h!yNJzFX+'U=<\`uHW`9S ` ͆~~{V?g߿}'?=}Z?*~=?`~%~_5n87Ɔh -¤kމ%dAGHܐtYQ2k +TWt6?E;G"e{01G?`_P_oF9}N A 5XgMv;XtwdnӾ$rel<_Z}8]_l99 +B_'nϒn-YAkڴV{DmAZ}8ʽN>SNھ|!mCF5׎ٲS3Oz/gTJ{6oTCZ{#/mىڃ9wvjvrr;ɳy|69wUN# %<:QILRkQ +CZ*!"XJr˨(WZ.U!b)].0%fi*鋟wذ􌍲ɬt|IOin[SܙTVf"_be}ADBJW +3}fd 4. T%YJ*CF`&KWɀDr96YWֈ(1c"J2UC[htg#@>osJI~^\?ҩw~)O/.[S|~N~|?헯ӻۋ^ya_^_5_> }g?ꧡ}{0O/~f?گ6կvb@_n>/n@7߼~ֺ,l|SZgHW^z1gw?~xڣ!flRۏ^\_o<%?`x`矽B&>:Oo틶[k5T8_\[H;5_r 5-T[Ӧ_⳽6澖6Q7߱{uoMԽ7Q&7Ei8HÖ϶ֳW·k,_ۻ_w__o]XW7!B_nyZ<;tŒ^lql^y8z!zqyC G1>f=}wvzyF|tfnn+?N/8rݞv;7Plt g/^wCqCn>J9ڃ\jm?m8x=6ޣZw'OgQp=6>[5ʏ._c{Ѳڔ/77)O_|_;-B[_כw|.23xkݛ;}lBds_W>^\Q|@Mm!kۭCy[ceWۋ\?Bys?7^v2!G緿<>ttd77O}FH}SEn2 w>jSaָѶC痗7_l~ӿzMɾC1j|p|W} '[U7K'*wy4Y|Y3n$Gϟ:Ou3t槗uz{{OD=Q{OD=Qqx$(uK!D횡D)OÉ-h{ +NuieCʷ'Qf!4D;RfB;;Ri_5sg㷤&^.ı?ř/}&o-v8zH~GDܖg.,_}y߳3#Oo/7wo^o.FM>m?_ ޼^1DS)x6{ű-Fn'osǟ?=c JŸl0-?y&?=ͧgϿhm˭2bλݎ?ru;q'\|t>9}vSodw ~6;_,bs;u_uZ.75}]o{tM| g6wwF PK%;/`[\ksoW}= ٗ{xr?iðvXޗ{ء3y_rLޗ{#ɻ[ˤ\U-׷qp"}eno.MylJŋۏ^\_oqŮc~vE-2}=Q s'm~wj7?x~(J&"mFV}H\6/޲Kǃ;):fW]9`ǧ`^h=SގR@vCnR=pszW>9ߖAUHgWnܝ0r"lueɓ@|⎶Ha'{*=?O/n 豭ӏX]r)ܮO_\lãr0]='>JNtoHc>CU=-ykT0~48}d ƿw|Œ>cY6?_߳3#O񶽷>ww7/n_Ox~ގ0CV@Ef3]Ǚ?-}=|#) 1?*C?ަErm͇xzv;5Y3)n~r./O7/{vzy-,*֛-՛_nΏM[{~zz'/~G~q5a}yEg/^w>Cq }{>Rď9چJ7:XQO$qmyGl}7ڹX5/˿o>w~/[[OT|}u1Sz~[/7woю|&nO]"6`?Ut+z4,~/73y/$u|^H^H>A!ݍ鋋gӧ?.jhou\wpVC, ~Tԑ˿//Ç[&/?My*!(#u^Y'y-tS_R#>]m1-+(7;ilƾwԦݭu*t{[uo>mݳU7W񟺭i/|sZAkusnsoG+`XOXuOX}r<=X6˵WYoVwN5tynބ4=hSɺ`g[RRޝu{(Yo/ $|-<<{IГzz>ŏ6Զsa"t#v'܆vETlPw;d9b&dw䎝pO# +yg[^7"Շ?ڜwbh_C=Ȑ~y/϶rGP}o|O/Oίί]>ۮN[swvk?7>BwA ;r͇cv1Pq mhG7Nr%;'4̷yBҏofsw[.no7ًχ7^`[ɔjP秛\<;<fo<}tmH}rsf Ftz闛/W;㞟nw( _j ϧjTt;l~<{vmƸ9ƣ]}A닫m}Sy:e^꧇\:{ȥ-c=riA0߮\zkJ#-{ң.m'w{إU.`Ξ.viK{.}}{Kۈ]9.viDK,ЎlttK[ mDŽ7BE(6 y~1n/Ϸg]F@7?m_|1Kq2㡃v:g^Yųy.~hqӛa[߿\}x{~V|wƃ?Ã9+)1>Oq?(0|a`c8('k+)!y 4F]MmnsrڮK ,f\}FjZ-G%3f[["Rnщk5B(.Ŷ|"Rgo7`10o_wJ@Ml4Җ.@,X[m rY75[r5BUm\Q"g~t׸-~Wo𩶮1j!PFPe Ch#Y*zBùմ ]w6` } BЊz'VMmHE4C{k'axdO#%}J{]4D{XR +xp +f@-P»غPam Ԏ~ŨAp. a ڄ`QR&|twMW +4u0'5fVhYPhr#i/<whz\RGV\,Ƒ1sl |C5rMszW7]D F1e`mFcfz +ëF]~EZé!4':I5^ +mMRq^|b]繶Ĩ0#Pgڎ8*rw9׺Dm+QEa+O|x"x.mg:Sg$& i2hSUA }2ny*g0*ڦmm ĆhP_&m>@Ny0-mYᶀn 92rihFj>/3>=ސi&^Qik&H7p ? \ߦ7zōq\ *Z!tx6uDuT L ,XdC+0`ENdM O8p([c?GmwJLG桃g#kCM:'aL8v`NK? w6C^S'aM^[e9Q]ېuz k?f()~ǡ3߃THAώtD+ZOd%*Yqm*vQb6 ?)g1P`8r٘zIV-yc:9)mי +OE%:9E A`0v5;xL՝i$Uܦ-<)5)ZnjOs" +5ڈ4A"vuӫ8r,X4AL PbT G@'! mL ;A@x ZbJ;{) FqPǠ샍VoH\&|`yI5SMP6}3YVKԐNj&YKƆ}/{OEnk 4(~u~n}ǐ`)~Rt6{VzMO +5nzX{tg**s0SZV,9_ZyH)4b]4m#"1(WFƔ A1d]FVxnRmjREm?%5~h^*iMD8ZPqp`eBZy u9 j:K8.wXіʏUF8*i'1T-Xs6Y4/u] %D7 +?CI$Cݥ~ɨ<`Hۦ| +Nčqi VDl lFKMtлh ;`!\%>ӳUȄ(B;xⰀHi'‹#{N +0T AN$VMI41bf# jc/D过,Qv% ;/ S$,H3 6H3+-Ĥ8SX8%͏C!v.57m^m(M(lNMmhKB=d/ (5XM3Ĕ!`1a"M}gxu[$s+~യ} &ۧjSyqx!KLI= A{^*vfm[(}#Re{xCB9B89 "W#J H nvk0BA'm1(\맱L`XDxfRZo-3nFB/ԈXF +vhMoТJ[pP/\ٜquᄤt/U;N𖵎:(vX4N{YBr x*Nا, aHt$ #%49 6D R6D@ԐA,+Ż WBPӗ1DbG((JA =$ +yK/ЮJ#5 Naaa L@PtoG<FpJ*Ũ!U!261b@A| &gq:GnM΢ d$-1#& fx[@5'¬`|K&#۰](B@J*@R7I -: Io&w t ;G ݡ +58/|Sgc#A\Z1%<jUkHfڀ"gA +AV29fWuf~ix Bs%4 ;aC8κ(LG`ht$_>Lӛ>󃫛g TW5a:g..x՛ ^Pr~ؽ{u˿j;x< z,jpT{%hxt28z/qv'ē;`_ ~  +6hM?>)DpHDQṁ.%E'rD;lAES <吠 Z{#e' ,>: s5~= n:cSg#&x ?md(Ƙ!۷Ft6aJf +)u<` sP0B8j*(ǜ$ kmGlv)=qP$ aAed!"=e mbF 9:Ƭ[o0 &s7V0wY3(m+TEcD=돵|76V` 퓑HΜO z:c%$IBmcPE%Iq҂ w}x#;m;Cc$839# e|d0g# 7Ĕ0"%괥'rt cT 2Xc*$KZtT,УB ď(kHBw=ȴ*GO"vNp0CphȘ@gXuY^y_,^D )tFA1ģ0Tmu"4AUa +c K +Wb3nwA2:י$1 +4]s2)>D'0jL'}]y.ATh#U +h8CL>Z0m_C|}6ǑE1M_Y`$k?! +3Rs#l +!rCh9 p TǬ%qTz_)kR >~qpv#{ P+DnQsdϐq=A!>{oLWd,c"2FL6Da P|!q/\qE^u 6$kM6p.ftփ("EsyVkpr-b$r%"(-l,\NնMk:rg<"٨53N\y0-gt6Lb־ P4C=1Yz.8@cmE +8\3 +7n *BNGc8! +lN !(oxv?yxKT:DG]C - J˕\tx1Š|A6p4ݱ{T! [MON',C/lY,`|2X?NNр=Ei}D1dxJR|AJ&)9H!)J4tgtYPGvbZ#cd10aVL@>KD$y9҃9IE^]6fC + ]'x2Y&Vr"=@0c2?Is-pT#VN pi%- 0Ath69Ĉ%PH d ++2J >Z5[~d Y M9#FM$xE UCN͑p[ +}#a)KϿ;|bAsN)N#fT(% O'|jd<0h+z^Ų_9isԙoy+XX!89$uGe g BYZ .;Ƭ5߭6WWg 70AcoqY$PԦ*[s@Ëѹ#',]7(>[$N4,pջsSs;X&Qdy'*WJ +8#UvF?Azn[ ;% ^"(x$ +lfr@NUИPu`Ɠ@t<:qã&dP:[1V@l Ǡ+Yh­gj Rw1*ӊBOBtmX_ @Ai |h\V« APK@WG˃N2{"HD +_r. ?͋UAǃP eRᅧzdE۾hSg@-P2]Ξz%_ +tl2("͓JFK"fr`1+&Jsr)b#}^ .;% 1"TW1åG6%{E5elt=z|k=Jf1e0mp[˝-],"<=8:i\[@Ax&uK:Wԓz9}D{@{'t|oy-9T}fנOU jͬYT%(r/V^=/Bgf 7{ M ,썅\ Q2aAj$$đ&/12QVH?Hs@Z@Y˸zlzD=~Eu59kwtE"%*_Q_WDDY2c a<3uXODx^ p2*N%k +rx/H+^'X46 +GbT0`fTlaP[tЬ" ++fZ>ks}ƥT$$,PKլL)Ud:$;ǃ#'i>3H,`ӏU 2aWt<~XΛ2iICe3tE <$V j8`* ~(^V NP96EGиoc52$Dq8\ʜIl/z a)e0M ` +E^~ \B :b L[MRAZ-3M- X}LR9Vj8hpsܓC{+}C"`{8mWY>^%cz +r$E$Z܃@Yè,,gӹ09xhd֪RPvF$\doH^D@#YGHӼsnX疵d#-00dpQ7KX\?A$@ +cr/xZ 5gK12WulKm(Aw']PYpǑH%Zẓ&ۛo +"|{=-raH0C,+/3b2 55|WG4Ng/L,M6qS_yQW.Ȋ/驿-Hk=u,2BJx}0 +\\z!Q=iF^F^| [eU,`jx~2,HRjGZEIRLBRED Mzy~6Ec#QqЌ@HTaմĦy͠ݜFQ +Z 8 H 1C9U8)" LXPIZk\t2 .@]c`/pek2CVQZt JrBtV׼SXD-1 *DVEA!ek8#uڗ"m?kʆblYS2 נi, +mTa_kIZU4ИQ*α8x ʌR|*@` 8Porj@PvM\l{Q^kЧs3瀤5#F4fe$'elUS1u&U^$JV+7fU7aR=kZ@-(}3:@Ư/A]2G9EeNZ ooBqiCWi}ɉRNF3qﺬ..@&pj搏0H&m6[ã-0k2b/P)>L6aB`2"^X=+55{QRa +V'<gjݢ^&,X=Wʼϑjj$MP[^@Zn d9Ziё\(ۂyD*Yti ''n mw?"OŌY⸗(‘ `Trg~XV7QO([-UrB%t <=cr\ٖIGxe<0w~vI>_#H6%}z=\-W0AAJ +?C<KdD[b"(*,9 ig\K + +lcĠ.`48AУD8c{am +ʸHT2 (A%|SKլ<=9HSEbOEwxW^5b.u&.N5W@=Ƀ#`D| +U].sfpў$HqyEM b9!Dg +jsrQ2 .+0$Mz lHSiYBixAUВ,+֦KγB++ , +/J#'F?smr x`"k.gL$z5AuFwhxo!0x aQ@5ru\K.Y[y ŗVak{qe!j %h-y(ӫyglYG, S% wbd3*NDX0*ܠSq*Ez\h"{_x5 %>սѭ Y1 )ʂEk# 9փPĪ"Zk1~n2"x_YxSY`hK]e~{<嫎RyKgҍjO@yg0\z-a٪FvH_o\>zi  +szҺwBZ0>έƵ?X+^K] ĚBӋH,U;xFXiZK}aRe-2V>Rt\Z9ԇV D/OM0pQpKmLpޫ +R^3EXIZnݛݵL[&ZX*btB(9w*-K*Sg#U>HȉΗvС҄xl"(/gMd?نcF8N fM$Cp$jC#/+,8(Z33jjR44RUak/NQEZRX6U'ˬ!YHs,A" A$}D"LԢ'cmlf^lfn[?[*Z M{$IY*azTqbpmȮݴ膶X&ք!fsvj[zC 0oHCdE,=UtVQr* +%h$i77dSeqM]p tK}ƣi.(2]=X%1|4'{X:t"=-PKgFhJ"0Nq(kܖ`Sх0J1TQkPo% {US%!WOtT$3sRgl3p$;[^@"iT&R/S* vA[~\3JmD st;F`waocϸj:* TL=d C5aB`CەnX3 4Ɖo"tȀ}KN;A +/]4ԣ,Y!&IW_*1rl]rZctPL2R纡gK*A aBupWkDtԖl+8Z~=8V <8%Ɇ{UZzp&Ax%!W8 +*+oM;3RSJ/dOVByu^BT]QD]7&c؅JhmFff*vk6z #3N(w1Ӭ69m#nU{L}ɕ`P ~)bU\kT P1Jq@߽B/,Gn$'dNtBRs%`c-9!2 lVډNCaN" *RK:k5,E t( +D1C aotBŎBJ +jF~`T)fҌ@*xy$h㙊QHӧNW !>* 8#Qrt95}0RZXr<4t3*CAJ) +CrQ!LpD! +LBPXZQdPL@(9M8ْ恹FTZ.ADM&n]fe9 >C- >] 'C`n{@'cDHt'ۦ* xxЌ 9H,.T 0"LpLEa^K;ʱ0/XI6163F5(2g ;ư +FGaEhcIo 7Sg+{iT80>YH( aE4,+DBP1F$0tUac %V AD +W擀. +(.8"*b(]1RUcU&W~Is$b,O19'Iѣ$w10L%+q%BA(BzctBPn9#֦BSiG]AbbƔ&0Aڀ/ʓ8($sK/.'eK)$L }^cU*=ċ kjc GXTR9M,Id u)Bܙл 13i` ,/Jq?P +F9DtLE9L@dNCI9ǩEZ VPb.!M(hG4SA\|ܥz WX7_?}zsx@EM/L +3G|˕ᙀ} s8iIP9'?>qvgAPL%ҋp=*a$v.ٝD&<Y# (%sAEEE۸?;sX0"X^)FʉA<7s\Bfɏ\(2LJM Q|=nЮ;>r?sa ?΅c18$3h.9Gv*!]wљkC< + rC‹H +M3}8ӀFѠeЀ1x!&M3=D!A4 + 2PF{H<ӣFjx&+"ѷ0: +,NUPLa= N)\y#-G\2 .EP A2$*P#1 +_.e)r4l  z~tAhl*@[-$HN4lsfgLI5vAY"9Aa䵃 CGg{ ](\5S\@6Xkě%G -C_|%VpPޟvszN&zQ, PsObtC)i"2$ԙ!G ?Yfgӕ9. tlR;,F _pmI̲:ޥ +n۩ +hֈ APNȬcdx$ւP ['HCi֔RjId/А= f!h@O2dJZNo> SCuȠeЂ ef()HLSa#i%fX(9 4jnNn"zAI$IHM0x- SD$ C@Un^4b(6Ԣ$^CrqZT$f /!Vk੢d\ibL^(Ès/ƀ }y \ABz4V J bVaX4#9"yWD=Y2cƠ\YTL-;5.M+cwps{tmݼQ`bRARRGXջWΟ{;ٻ˅;zSaL߮ ݫ5|E8׷9Kߝ9@aya"OH7vE8%W֌D ^& z$K0Y2N$%6t[Vzs/]ݜ޳ R7#\("K*@ ^Ӏ(B@P\2iJâh)K72iH]B14rA.f,ԠPflF6LO[8GH9r%#Vp j|fd +0$ÈC?v Q;*t]sڋY/ݜ޳+p(s oB@*yƋ`3/ +N 3 sbD0Ӛ D j8c\< @#a>e Z1, Γ~zҋ jA' UOz0HB`Fj@3:@쓞V$T?B]`|zD =Yk+HYa]ERr4as0A~/zC EOkR/zÝ;;hոL#^?g6 o9 )1BmfT<JSzzT? MFE| +~SROudo2)>_HsOz Eb~ Ns I)2' +wE/=P#J Eρ `F 8uTZrQj^"%>ȾE*9J͋^D2ĔR@%N(Iww!֚YJ7l+]r 4OzB=`FyJã)% ezsG&$T /UDHwjпp\$qE1g`d_yx<\%"\SeSv2\a1}˱65qs}mjcX5ݐ C=cS}-iׁXT6>$x>c&ARgLwmYZ +̏\?%uZCQS`:CAJ/J j^-$l}ic./S(_b7݁'^VuRı-9=[s%'ƶ͵DOOaKUtc"pP%(u(P {|PmÌ{03*i&l|ZC[ T^8(9$^(=0]TO!6Az >AnX5dگHio,(`AE6T0 Z#g=\EVA9krK@1Na¹cϹ#]5nS`@J +'"/T$({dk= *`1\HjCU0ס\1!9w&P7ksqoz9WθƮ0q%Pp'"F +`%LB+y֤<2K4aX,NH9 r%9º4m}0-NK rϯN~Dtg!E&wQ:ÁY [A*rrXG*H`17d|.ї7Gs 7fP-F uiuDj-( E sQa[ 2 ~7l.4YP)\<1 ?@kc*2@k#9  h3#&C0 cD*Od чREfȠ`d<U:K`<2i4mR]vA,EB4>^%,^Fe\<vrAs#]{V('6E̿y.s3đ +̝}''Gm.7x4K?KEji.OE1˛Ja*_Dgqw'6Pwmz)#$]reOAS3EHF,Cy(B4A)2 tRu@X@RčXfADT{ +=IKΌrк"6Lz8EƐ +R'FAH ]~*iW=J,ȢƅJ:ߒP[Ӧ%gC+!Ȟ9iN1l8 RGrA3.԰zݛƳ3q*n/BG\ +< PyנkIC)G0L FOa9@*WrJq筙&tC'ܝ9!vs^\wEu\wȻpQpᢟ0]wEu\wȻpw /s`uh|Eu~;\\wȻpUwEu~;^X8ﺃN#"Eu\w(pQpᢟ. +;\s.pQpã~;<ʻ(ã~;<*ຣANýp|ã +; )〠"UQ&U%4nR5PYdU DOy +d>EoA!94`o걈n=#PuB?d4SJnJ[candb-(sd8@,5-U$yj m@`\;GBcʕeOmqBcTA6 37C,4 2סk*8iu5޵(е W!A҈JX@ihXŗikp4Km)q4C@D1 7}q!:KhBF1o5 ,/c*-OR{G6 U!6 T}jpUy +! +%q +Jل^6P\g, $H񊂌-Bg&7lbu* sU\'.f*lbu x&TMЙve9 OP-yެx´1,w("}[x!:r=&* +)jt'e[:20 فcVd蘶Mʚ-5m[h_) 'G*/=j^fL jN7ؙ.PL=ֶM/5|Mʸdmܶ ׸m@B ֺjVLKjzuvSY2,ʓ@rNxd44؁4Q&T;*NQj)ɿ rQhUQ.ܑTwgBrYJ-X\>E:yѴM3L 'BHb!-dBmofTo;4y]b[F51HțΫw &I$e~5X~Qp($u*. ~$7O6ID!Aw{$&ܐـ~™ rSnPL$V5LD oA9k7AfYJEW8)8$qZ쪔aP {kL!V(50#̀mh%Pp5D9"nε{5T!CC,r)DaҐ~%W +h60 T +A!"HmMo5fJ&xU^ +sqA(adHH@i?#6:0m Ü1Χ!)拉7F,WȨ Hfj'*(skYIP̤D5 ÁZ/!Kt 2]b1!q}>*NuĿh~fh*0UyCWGnjya+Nه* 1C6},\]%/Nm43Lge[U ̧0#xjek=a8ԏ OȊmhU R e$m$w}B9G^z3ldBjFR$,R.AIH_%㫂SDqΐܻ Ƅu^a:*qi P1Lh}ł5=ҍn/+ek9 +Yܛ2T!$,.ܵ!p Jq*E΃IBwV٢U佊/mQ̛I_IZɜီ΍F1HT;tƑ?uP|!Z6ZBLld3< VX$rr@*sw-OKQGLi]t~s-*M?zUߝ+?&B5J﶑;sgd]%vҘB ;҇R!T+Fj>o:b;?}tz`H,*3/3w:2WHuƬw~9&zǬZzHrӯzmo~ҭ'mzJ̪W#{҂TC?z]d{8{ [(F.tl璏O[.铫ќ2n%H70| ۹[K>d?&cG\izPXyؑ@&ػͻΜ6H& _6 s;qW\qXj5Rf,FQG&ģ[APib:<,脙CoöN<ޏTtBP~4d>hg<I{YG?;6Q^ݪv>/]XPi"ˍzg^|nηN4gYBYyQۉ{jVi|mp;l٨Wjfuظi,M,z^ڝ{uL4¹]olԻ(vu:UX$磟eңI6ڠu Z_4h_/<7r=7((U`}QR>nȟ^I#KO #I3$cq*,d9-C4լJ;b8B98v-Jfx MO%ea0ˡ .y \TR:pVuQT7uIl1xR`;%{pip9He_UZ_{XTz} % +AJu35[&K8rܙ]'ZD>!.rK6gbI>9!wGä@}a<7qt!ʟ=!̷!L-lmQ§Q*eq9CA04FCq޶%'>Řvj| ? e߱2\4 e\KG"V,eʩb}+GTu؏c-~= ?s̾1p 2⊂!?C਄YNB/T1eߚD.,]ZBՄ(scgw*dY…APnj&L1: Bn>@oyX1\U-3[}=ߍ~k5~Qϵ]G]qjWgn!-ɾo)moiRQ}Tjhh;O +@@ &i=d (` Ƃh80Pc̹/@UB +=!ʚal<-Y6*sB#J^ nQ3S4b84AnXVL x71J(Eb8qL3o"!%TcO  Ձ_$KA#/}gTQ0^0Vd8P2Jl =/'|^!KIƒ9,CI5Ͳ_+nWY>%_#m8f!X{sI(Oi hA*9Ha=ǿH )͂W*gaIwCp^ +O :| ㅹf֊quΥ=i#W<14'8w񟵧RA0v2-,'K8i)ژ3>فd cYDs+y֥KzD̄9S0@KDJq:s +5q+ ꏸ9 7)DJKlC|6`K ' b %7v̳uMR0 /? )*ż1J@aP Rx?HA`@`[nqjtJnHbXG/+o#z0dFwY~= +8Ӭ6ވ?؟EF޲s\+ݡ w[w66`7{Dw 277 ˇBBwGB?DNv'o7?/} /?1(U٭vwFՄ Rm6ȑ).Q{2B" {և"k|X3<'sp3:o0da)h7'k =Gvw"H's3v9Jcwi9)75oPIi#^e}{CM/;a'B%D?*ӟp?F_AFك3&3ߞ}(]2}bGg=C Я!q?M֣DMx_jw;V;Vwt jm؛@qB![o ==5wl{R7]LLݫksNn:ukfBk1d6}WhT[]oOז{YK:N2^٬zr+$,׽OJ}Oy3+# _xŚCwr$4%,04@qr"q +E6Ƃ?/}ZK(J̲sA#\YǨ?T=?'OÛ~ +ۗ:?}tY?ydCNp(?[?uDzTT̏g̡{ը~Nh2ć }j}Ɂ'bl 0eѾCIAI ؉ aq",Y@(i(O?b4'QgXԙ$!ua2DvÎa'9?yrX;a7M~/~j V࢏˒˻vhN㰉GF_A磸G?t}|Z?9Xm#vAQw `CXPY+$ CL +KrKG"(K3 3UTA%F8N+> *YC,f4&BNb_f mJzTSu:#1Fu$X$Xt2Htl  30ӵ'l۷7Hؗ%,…a@AL#%wQ!"}q$ r+m@11(ݚITnq²,H`ie{3-s%^I XTCQslxĂہTB19g'>e sU[#D478eq/yJjYdXg f-sqd+ ++y Yh.t"*me +B:N<!MD-u+ɄfԚ5qq0;u羙C2=G,2s`1>pyx%܄nJ]>bB@?Z SGa45;}L<"੖7=0.lOۇrq"5>aK6$1tDt'\5FRbH$ro+uyЙ1<3A(Wk&C2 (N_j__1X|mY +^oKHUUj%/mI~0Cv}ů|{7}y~J[F[L_Z.Q$*@mƱh9(=9s$,L<#@Ge QOשu0Pf8PH="=iC% 0&\@$KL! +?7vؿICb~"1^.u~pk}%]IL8)^FЧgtHC'G%!T>:KV6"q@x{j2~5weP$KJTde$2C40Rd(oӜcS=ݶ6eE+5.uŠZ;j#_"u'T40zfUy&y'JaaH+<# -AsOpk&,# рΌL OUz`Q+qb`{syZٚ]G?,7m^jt{vޏQFpު7Ӓ[ǕwMAw8!$E!'1@kor5r +HTW_ABA z)g##j=[)?' 喀dw/ +op+Rgj[#Gqw/G5$j=oEsn՛$џ]x/_ۛxd{{jkkU/-)-5=Ӭ7꛽~*z/'Zި1g͖l0^:z藍+NU~yG8jۍFRt gO=s'Nwrr8h?th/ѪMGFkC. )RIݷ'Cm.jfSj$v<"FuYd ?9Sl~Dw{WԭB%Rs#'u~#fa<1;GZbUq<zck{(b~k39Z\z'o,ЉtRjŏ>Վ'78҇ >u? 9J{Sπ!Aȋ탘nWݐ;L'szCW"2Xӧx`rkLQkŲfg +pnRev9I/Ӓ +f{W]CRnYKH,QTl{NݗM%Jr `^Un_s9lcC6y=GWа魷\a[/QG6*q9;BLkB̝6s`q6V[T+>\Ի'j^i~ѫ7R?%4@`Oo5jXDЄWr,5L[%,Vmɦt.mߡ0>ۓT;#wAiH|Ѫ)Mrఀ~W_5JV}HOG~rjG"M<k+.wK{!5y{Mor#ΟgPw> 89BuF/IAE9Ôo7{{(@YI[O  .a@ayVh{G1G5[=؆x: 3ൽ?aJ+o-h=]ƃ;chH8cj[Ujô^oCVx^/IV~bv0tg fݝ޺\E]vf::L3@դTshMqLJ6h/6%83`m,{7Zcf%髪qxtZ{V_3mS^,EKG߭vvw߭Kv|2c@+uW3nYިoV=$ߩs6v埛絷1|c?G{{=rlSӈ#[zT$[5v%C*7:\^[_"͎'8SHCqlGqw}x%tT3w hyW[qg)sd\y˛:Ԩi j"kCcځݕ\jYqA]vm/8w{Cэ;oJOx[zLhΤlu6ۭc!Sۭ\nDkM[lyDZwdCy+d5ͧԌa Z{`zjY|/,w|W\8~:-mnS85Tos=!Y4m6&؄ ሖq[t~lo52z H%;6[㨈) 7 +~Tm;ZK6H4#7{Vi]|$ +_-]u5 k=\n|Vo.;= IatRjkC=B_A޶RC_P% Io<}6hVoI׬WrAI_bW1l]-ޣ/--i1v{{Z2h8c#&mo<8֮.TFs?`淇ErB/_? : ɡ(ţ2%<~!% *8АY.?(!~i}$_Tȗ"zq}YR\K |1%-EۃcGrop6\)k$o(k +i)vx5-B7/J9Tn gj|'ܰw_qJUb|qҤ/S4i 4B C-Kƌk|XC7]ʇni3>敞仒=%+b[28힕'Z7Jo(z5+[=d |zlսrj׶;\y(.AyU Zs~KGk/on6ZƛX|'p| +0pM߭L3}VgaXj rR? mGLp+1gpW=2B|~{sZNᝫ!# +=<{XC؟ޏYdd`碾#|AryA} z:6oJOյ@o?7bC;ya{ R"N)]ChZ^-U?wގ?Y XDaoUd#YkLC*+psO/^~8u~hFxt֩ F6׮܊^Zzvtg,[YE;jnk,83=|a^w{Oa'Nutw/Gԕ\|~0c9`2pRZoXeԭ,/^O/Egμj( nLm&>}VY-?8zTݥӗwO_w/΍_)A|-2a2Ӝn>9ݛN0#/W?䤻/^O^-n,O_n$U70٫;2M^ ]= W8=YUwͥmդ8Rō٫;WVνNO0ӕVũ[FLt7J.\b܍|=yUX},/]|X& QdO/ϱ+rIW a[-@Օx\胍=?}knz©O:0L x`9Lb\pYtMj?;6zG+Wխ)é˓n43ݙzj憙s;62uZ#S3skn)0^'ZeuŹ͉gfw/_[RYݮ*gj*<$m<G/vloiܹ7q{nse~Q*^rz!,_cDn,Lw:K^]JE0vqc_z*\J3yqjdafϵA]ӓ+7zElvAGS[ܨQ//ݎ=_._w:cA}yj̄0bбtv!]GfynURU\v5]y{r̭ino,n>FNg4㩇4d$0r;svXw/ KOck{gv'lۈu?]棧uM/ەg(٭S7Уn=<-=tZomcDcjd:<=joM?X].̧wa._ ͏osGrsz<(*sO/I^9urwmwz]QroBrJKpt`mz59wgv* 6+_xW½S۸ɀ[uyzw8_jmJ"Cyxe*񯕕lqww +ݼy}|ſj.3A=G?%UO] ϝ:S_^g^_?qk=9 gQ`d/3[rv-NX 3)a _ܕef*3lldܯanx4?08Aҕ􇱑;zAW+8el"W_x +$nVaX]== 'Ƈ+xFcd9Mཱྀaozg=mZay;0] 9 +L⺇+vp~lhȭN/_`bإ]:v a7}[aZBHϜ68Kij:k|Hˮ-^GK9N#-dbѬH`GU\!YZfnzQsR $h&\A*<G!iv*)*sخx,XpP.#ô7K7doWcd( +NGQDNdIݼ:rYWVWVz&F60 = +#tu̲w=HE@LCٍ{s7:^"?_|x;׺w%.3RxV6Nt$~snnweTRY BӜ iBő]QܫkW-)_`'W^LmaVS2Jyу0êBE½NzP|1m^W^Jy틏g'W.xТSv(/Xu9jxKD@ +$)jAۣ|j+liS9+qqڕldsfgtOע[~}Oң;y"rmylQDnÌ8؋v 8#,x~|k%?HL{d̝ c9:s׷/=Z8FWu/=ce#5ѫ=|29W߻F|z [)$Kzf~-h=\ۜkگrs4'E)]եi8&-Ltg<ۯ,ߛx~"ݔ+45!f邔Y_Xܞȏʯޕۼu +jn[_I1;y=0Fs`Kv`[n{s{I|ҝӓ{+.N5vIz}&66_йy2>dO/\4i^7/ݹTMe<^Un>fnޘƼHggrcb9)xWӲ͹ J1ZustnN|qy—0^MdυQR@~>ۇaN.,VgO/-ZY8I>5"z|o͕l_vJ<^0:K(:+5&>Nֳ߸+*__66Fn^mFz4&:Zlc=#poՇ7jOD/⬠?8z :$$!@X}w μϼR9]M:$.AzZe㬘sWWh7rϾoKwmJ@$T*TWšq_cv=r^>&HbɃz%zƗFU?|aޮjg'EKG7%!aV[I7mrG=rf_> /=fwGw)t٨ߥr鑥'sOM,| fΆ*/o=WYpeыܐ/_6rJ〸]T*~ZיsgW&{|-aR9I2$tsSYx,>hX1M,3 MAjv=~`{t bD7qAZ} %k=wtT{l_eU|m9ZW^#i lY> +B5?5nG|Z& Vkg%^Xl!v=;MެyW&N}Z6dݮۏ\m2i$73 ׋tu1?i 2Ddeb:TnH6PAqzbܤ8 p(x.2 # ٿ>h4` [vd&6UY:wKɥBm=߶lvLid{|*l_=|dJ779e7L 3I6>dc +AM_+eq0'ٵFH];p_ve涼A_.1/*}~6E_2/3p0ė3{s̢ݗ.-;agytw%cjTd>%}yL_z7F~$cͼd&IlE߆_ }H}saG|UW8e>:ȺBDoUnM]0#gQѓpg,PIm-k{mi~?a +}]/웜OmLvW7韓7ȥ7/O/Sv8Si/X̞dVmټa,r>ݹJ^qKγqԨatzI#+=| Xl[- ,[XyMre#]pG;˴⤳P2L; ^*wJ|rOٝ&/U;ݖFbW4yEżAz']r/CLVe8N W3w,7l2N#MՍ.+0lrT>LTTvtWz븢ȭ==v}uC~䥕d3mW)œ1YCi1NضKg LThr^wksgrsr}b^Mi?<o{`'0-])y3EmrmmSbm;lJ"%StmZdZMƮid Mٔ+gZTMy[j*}JKSye1m;iX5=[lگgL8P96|>MwOt^];Lzts'JjKok]Ӌ-P2>L﻾JfSif[b3;+fj,ޘ۵%s8MosjÜر;K9m-gǃCsz3b.__[]v|4wOgel~2?,+sk/Qt1m"S=,Yݖ[cYY<[r;a`:}Y]G,G+^˙i\%[fKmֶ4,ϡM:7ei?Z:̃ռzo{5l߬52YsAxӨYREdZKY.ۛ֗2huE +1Uvݟvkݩ5c݌{qyǖ^ۛ+øomܭ,^|,=?7{7_m>[lm) ؊Mvi;yVlźx [3w}zv[k6{g__g7#}2j?}rןؙUڻ/ktkÞ^19|Ɋ#+ω#_X8I8j[Fk i6nu3v^w|G9+ΛwӦ)}Dq~&܇]X\܇kyqֆk^s7]ڥ}^·+w(^u/uw&p^ݧەf,>w|'xUK*w< OSxv,&_Nы׻v{)oƛ8n޿{Oaw|8ًm_V=h6ǩdkm|Wy#;KԿY了aƵTǨcp82ˁ%=K!w[d\,;'q+`Czp=,흄?2ЊJ_CgW 5㡏-=6ñ&9ų᫤u-Owju]wGVƙHډtNFqs=:އ@\,uuSa5Vu>g2'wtT/^oV'Kwf{4\*Hm|6r/M`?}NPvs&eͦxx]p;ۥ@rsk*tPm||q^~NFaqo=^m<4қ݋A$SwˑhmTCܭC{Ƶxr NOsvɴ? Wb&gbtg%=,!yy|"ܓgٮLv(_9s0GMH'&^"7p6N!9,l4~(UtGrS_ԙ\or/ֲx[x XT殄͜x|zJ4׫ݗ2+s]A"DuLleoSR$q !kbk6]yiF2N}rqo\L!{Q_Vƕ\=\i64cGyrj]8\g2Q;ifm^rIݑvd7Fӊw5dnMk@kiIk'yVS>۳!7FU:]$?=H}(,~?8gsR6z߰F\i,>$F3|4Wľ{ԥ䧉Fڵ}(2![jHSh1ˮ^DVZ>?=v?AsjTaS ls%?=]Mҟ^R+DpxJ~k$?}9 eRH_K9i)*F(Ȉx۬nId+_$?g O7B栌hSLI|-+UKOGާ,]"?F[/{M+QʾwvmZkuw#yFFG􇏾W0yr)3֢a o}ek8OK[voС3ۉ v+5H˃ -4T|嵽mr>̘ +IqЅxs\=9(q/ +IJRqsґ4'Nfʌ  +ӱZ\g1O䕐d@"W2d$cajx{%+Ε $s%.|rn%se:\V1h񊶑+ ݛ]5yWc|ewk7/3sĉooTdN35,)G;iԛH˭A&td}fH'9҈4/~x{90~^'\J`Yc#8qMv_l X@;6tb{ƙs {6):bq`#T03%Yŵi'5x8n DFut^}f7 Og"Wh7I^!-E2?$_eh\_.keR^L- <%ZЕ}.H&Դվגw5\4[/*=+ꇲ y$BV:o’ӦɖHj80m3=yGO`S\3ItOfO̓_\_xh{M[o)BԒ[p]{>[ +yD$ؐDF|VXWIY%ƈo܏~VhfH<Ēb.FVPG5sS@-AqC\9K#u4XRѸJR`Vr&ql^M(j[XH]Z=F3(v]q\Li+Вw*I+y2,,NRE*KiNh+pW"zm26uW7=M~wOŘ6Ǝx\mLPŽaR +=CjMQT3a^jgI.ۛ]j[Mۄs67趛LsJbF=;<Ƶi޷{vWgal8ͮ쎔fl a tf) {Bҝz|x$hf|Q;@% +=j̘@%^ti8Fn{Cy_L0tg6BW3N~+Ӻ E4lD[ G)EXQleʦ@tR߻.ߩ6aSx^@ + +Tׁͪ?!sftiTWⰍI ݉ <^ʝ]rX^:;O3&_|O`좃sQNM:l'rM +'S6{\rqWgT6Nm!aИOzR>B%`FLyy D~Լ]'>i +`vP(HPb*4MIxOa7T~ Mv'Oc,ZHDDx8nT hm[㦠<ߤ7oحMP%<Oj68MSzӦԦ:f~?5Qn.Hpw_vs{Wù.;wS.!} +N,M6[>zՕC۟`yUR&IMjVl7𐚥M*<$8W +&lNfNMhVWdS8 ZIF8I8mhg3Ueyb:XGZ7JDςnu)R1M}ok֭i:/e@d:fcxغ o݆c֠hjӷnC,кk&oHBnlBn4VqdX>7tqp>X>~wpp>X>/tqp>X>LD||&tQp>zQ3x0/o81O>mt۳z2;弄h$>AWܥ,h IO6'L"( {w0'2TK.^D%AiɸJ\j򻼔]!;;8.O +&DFmfOt$\D{` gda\݉n1|Yj}[g^ Fk.'Jd+4)Ygٰ;e0j\؝ V~teƯF)yA,5O=16SYU+L42fSjp\Ko՜(Dm+?@[F5$ZǢtY*Jv$Ѹ(a<ϱ;')渤c䤃p";+)bFp{YO24()Lxj1ẉd`$ƟU/sغM'8yJ2eܑq$:CiH$bܤEҸ ]Y?/)cƃ%AFvBNƸ縐6 ,joRoqvg# s4Kl0SG@uŠT~.O6$2u4@aY]4R:t?<\t椩z3%z0 &dD&W+HQjӘ-lyʈO0ŏE1{̺ +fo+c)m7$ܖ ᦙ1.>{C7έXD7k +EhAx +*-#9HUWґ- +jA>BlRvufťv+r<~C#٤&c a ]7]ͰL=!~`VAcm'1)po=wHnzR'2Fm{y2jFn{S;2o "d7êLw +" +7!j#ڑyT<#8 ofGl.2od&.DcT<ն^[/%{J^+z9輄g3{.mglP(Tz4&!FFߺ8? i>[-1!pF驡,8N?$5ixRr]udcJң&s#!.*q9؄w,(0ݣ;87l`QpO;n;\SU* JƄ${R,MH Y6{,ME Y] ͢{G~~cefIijq{/Ճf&?ğd9CPw>˛KP$zF}>\գX%O}cMJѤ&!L<Ԥ7ifʓL8g +׀߳?o lޘ-?6xFWx8(_xl9쎋mQ|q+NTz7vZJ[~^QL4q;C;ld67NI +$9Y(#Y[&(Xɫ6=Jj6e|Zc+jE?MV+M;P@WRY2O=W ):W,ƱC5\Ie$ <>ҞIMQhhaST9i^% f&摘elvӠ-v]ۍ΋:1';O޽MjSQSI)`OzYy+p<ޒKx,l*G'HH z7Jwω#Dώ l!&g>Џ:o +ٯ1MS?z[?j`2QJS9 w..=os?`{1HqGw~èqѾSFbFgmۢqڼ( Mшr0 `P8Zt| jЁN}/H[^mgS1`? Oa,@*ʵpʽ)_ aRòJ9ˎr(qO%Tc>س2Q $zwcЋ,AQ乏36Un}Ec77a23u.w{&T)z6Da;@?e-Q[; +±chal3 i]i(\7Ns̭Vo1[q 5,T. w!{ڜcoĎ0gι/pg+/2dӱqgGӥ/$"ϛTPB B.@Ę?p^I^JJ\h%/7PKj/}RG9eC!N=n]:bl“x!5a "W=\cN3s+ ΫZƤs-[r50g%JPOar',nHHV^Tkϯ $g{n\$ݩn~x$W}vG=!t]f~ypS;u2IܞMNMk0jdtX-I +-mֺUZ0Q:߸%Y| ϬI +9CxܘNeJp6i GPJ4lo ?0Y˓DNm`=F +e_ ϋ3H$^Vxq3yDy5 #d/]gyĮa!9ܻ׿[$N7#ߥʄ$t]$ƍjFw'3@OoEY&:A)6Fi?)fdzMF0~S(9ّhOIH1N6z 'GS&JN(Mܜخ:&N@%XĖ蒉Kw2,LJ +)c Lڸ#!2 2366HeW@gmBHm$YmʐDo)G $Qi<<$!Ja +ITNwOȫ/2Б=$*GdD>$q(| bGzM4q8*$Q¦xD޺'ku~XA!uVȽ9V8:0 + S^Ċ|e + "E+a[?Р|Y+M?PbfT,}ڡ|`OImCeOCũT+'5큇MBNuĀ}ūS8PAVC&É<PぇwuɆ%sxX|Em]p&8P>釉WO;Vy +\|*Ԭ*?pġ$#ʄ\ۘCn>U<,HNF?X<_lKC4]uSCT11d# +Gdg;7#>r!x-ٳWg>P#U&>PC̏x8pi)*4Xtx8}>Cn63x8:=pBOw okSx(J85"e9PRIbaҵ;r'+(y wSeش.\nm#'ؓFAKX]-ml73o[i՝?o^}4NgmfwtC˶-`f:&yw1Q^ra!76ye_ȇ$R,~r9?o_>:yt֟j `|@a?YW{ʞ?(2f赖m;NҌ[=~x|~J{^*1OoRl+&_ci&\C^ö7Lc6 .ooO7=D uˋ%LN[-S7my!ν9mٖzhڏ ȳ &~'xB'az$Ǻ3I:7Dfow+\Z%/ڣаDBתWj5M7٫]/S{5~z%o䷋`_)z-.¤+ߗ&I/E%/+߾\]o+͘\]ٵ)\-Tռ?gRy+f_g@98n7Weׁ`1 ՂBsdĜhdSp9KypE ۪x`莒J2uRܵ`˼-Wo_t/͙Kdyu悼\4{tky9z(~-ZGŷmh|z(Q2R 0iWO54 mSKF:VbḠr 7ӈJ/mbZR;⦳\JVjƛ"cA7wG` qש{kLsm;mpz{3#K{Ǽdlu D mp0CQ0fPo8R^-{W3{ҪG;^t™g #_;u] 0a}L7?̄9z{KvPK;T3ǰl*wg E֭D#逢/ڧjbՌt.lT*Sq)INn"=3Co:DCE/ö'N:."|^D`y^w8ڟѽT^qL+0^l Ae(] +*ɆKOgTe`-=&*|L'vpu!oF%TL B{hӕ["c}lNEDi(U1T +F4 YM4i;bS4;Pid > (;(+AGkԴa4 +eςe˫njc2lMo>熟F< dn$MބL]U;vʍ7l!73NUMn?~>l=if7b1΢>?ߞ'%godn/)78gql{81(f" 4ovns|y?3Loq2 =m)k)kXN^3Zu7 8 +_/PLh:{-5dO;h꾏ml=D_hm;x[e^ҽ=JLxzOCXj ̑oMiMByOy89nܽ\:8_(Ftt~Kg}Ԏ#;՝7`φ燦p:&l]^a' w/}N=9\i;Xr ;qݍ2{8{qPY~ =йSvJ T=_Il`yKYLStvfyYd0MP\ͩizud_}Vnl:. 6¯Oщ.֬P6Ynssqm +lKo{N2s]rѥ=_2KLp[-Yd ̣'gaT0ofaT0[iQ"{mQbzH@,ld~>_SH%Â?Swvq[5zw #*z4ޕ"9J"fsKrRIq{y|OwEzwa +&G/ؙv-]tYqYrv3: 3c9*V48Xwfprޙɝޢ)og]d=6sy'b'tYn4Ys \[ooz;U73y+޴~#]>l٨}ބpk*)mVI9C2q{ܬ~o{42V.L?'jKUR%Rv[bKj,i +VI\%["[%["evJ*DJFUR%RߨJ*DJ*.h7sr'-i9wm`@̹zdr>M%mX6akc,0Sj&ۡ9lU7D &~> 6^I0n,guφ>Jv<)7ci hy2BT1&M'+ZYf i`>U}57 Au| wq ̆7v9cg=^iyPv؞<{="2$c[RN]<1 JF׹{eI>!#paȠ-8V3rh]MlfvA{/RʼM\^ۜWG,[xYLYkNf6$,TAf[b kHgq1f{{gmn=0m֛_,)ZMd3v5q%$ WH6t3NDfWbUutI5pp#xBK%XUlIu0*;[*7˵ݐ)"tm/- +TE`MxR̈H]\Tw-V/8h[==ɮkMR;A .3L |L"xQ(Tn 2 tR=8dh?8_-f?nPzսVZH1[Mۊ H4434ch:gl=ck 7*5:Dĺ_,ZӔQ2[ GОP܈kd%Bc}N:6[FBJd>2bDlٵ;VBchAM9iԯg%MZ#ZA%0 +ƽ3U[o&sk[uvI#D*eiwr8Ì% +9<ٍ165Frj%Y+n_m5\Dt?OENM,=Iԇ?&,isN`!q`=Fb~A6gAnFp`Ic;Xp?x hF$v6,v}Mxw7'?xe +RiFW˽y^19j{]usz#y1kK +jATɁTXxuwVh[+Åhw(^'2֧9 +qz7qvuFsʜz{KI:$^`Yo6[<LB8u>}x~{g19 &-h;޸  ֜8jaszE~:ؚvd^Bܯn?D{zΝp +Zg-hS1ZK}}\lSL6lSfJmQ48T"3p6.. +endstream endobj 64 0 obj <>stream +r0X7︋EabfOͭo r 'PFɋ(}wnXp?NVSgmYkfL1U9c8*%X :*jX3G>W-oO7jL^/c0`6^\w7)<6Rk;uNFѰ5t8(f ox&MR}߄1L3_KTmƄ\[KCx,2,T *ZGC=_Vh]҂+ZZu#ZK ~@s䧺X:kkk?U.Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm-zE@O_ ="'/Z[Ekhm ׿~ן +T TDY~*S],P gOu@~Zg &gv/`~rg g ga(2'|08 (d@ +8(gRQ,R@ "\,@02X,J2/8b (Y&Y&*YBYZYrlYfTYf7kߌ{ZwGl|vߍO7Fa|0z{Q͔z[㮺~}0,כMc,9 TxzmzgO;dDakqP+DNjA11^A{$F|yN c a#_"V,2&rL#X(D0X {/*bzBL*1UbTSE @L*1UbT"SE @L*1UbT"SE @L*1Ubr|bBL*1U+:"_&U|Z^עZ^LĔGu1f='b1UdbzN ĔbNbzBLN) *2&s 1UdA yS9 1Udv) 怯'b*:@L/gbZ"@̿V^O"**=!@LQ'0|{n){fǸ4f~__~mvk?Cv!;dx٩|wRSd7xvsy p?-U3f/[f$/rT8jXvpdw|Av*e˿o9&GM5K쌜n//ȮŹ<÷ToDnDݟώ Xv-qo *7dɹ{[P!,snj6dRqo *6dRqo *6d3ۂ dv\5ow^C&`T-?̍|.W aa1SV;N6, c`U~ 1i?>dœFo2'7f<鋅[X bFo,# Ѩ/Fw _8HS7%wc_$K5!ECAB!_$o&B [&Pfb I_q]]r5C &|H2dL$|dd ވdQ;6/wCp(BEٯ_4ƭXI1F4鏀ёi7@<:(cӟiwsOݧf1{]Ȕ;O7Fa|0zHwF5SNVwFof*=ðsXLMdjk鵑m<<5uNakqP+B_ ҈޸ $HGϙW07q|XȘ@*e_cNTb~?Q |?Q *@FUCF8#Q *@FUU2dTȨ +Q *@FUPr +/2 +r!o{H=^*/9np:- +-rQT}r ++ysgC WR^ZGJ ]HtB9 M_/LvŹ|oJڱ\wnU~^=C)So?_/?|񻇿$O>헿z~7_~Cŧ}OOw_GۧVަmO?~w}L{?ӧÇeR^$hwW".T-,/7='ڕ~yD?ß 뻾뻾뻾뻾뻾뻾뻾뻾뻾뻾뻾뻾뻾뻾뻾뻾뻾뻾뻾뻾뻾뻾뻾뻾}_凌E^ay/c&ey/_}/.^}(kDE^ߪڋy{!:\E^߶΋ߊyNw"Ewwj\"~/5ޭy~ rwGsUy/="]}w"Ew/\]~ Yc%y/P"STrEw IiE/wE%7/'y_E^ߪ૏/}_E^߶+U/}ہ_VE^߽2EaywEEo^KCyywh"7,nM\ޭ߰5q|&.hy_/Em"6qE_w}w}w}w}w}w}w}w}w}w}w}w}w}w}w}w}w}w}w}w}w}w}w}w}־\]]]]]]]?x_|}5a]cŝn}Fޖ?e|Fy|~goK7_tI74_|7:M|N8i5&ׯ0i>~FI4j'_Q3i~4j&_Q4Z^g^Q4Z_?ȟz5er^?f[9>ݶ|s? S+ʟQJ|RNT_7o9Яk*j-aP`Cvbqs鳎idJQ%7WPQ.lHRsKD?JGkZQ:y^tOR ڏ?~!lŗ?~'_/ ~~d~?>Ï/>}(UW~?/~/?/~W{ԓœv;4Mo[aZ]ގ):?|I-߾w>J(?^$/ՙY[R =EVX|掖_d>.[+/ZQ}ҍs@ +o~y?\tZR{NghQR@rG(Һ*]KjkE*Œ*CM4EVk)e?FB[ϭe +U盧S6"~.t*z"E^[%}YE`,ߕF^lM,S% 5Snۺ&~qK.T)9+ѩW+JQ*ܒ/]C(&"KߙT.UqG}>q*rn=1N(+)V{T$Ym"]ITvNWeuRO}ftUej(TßJE[ \rVg&s /.@Һ??k*]kӲ+GU9SU)UYb-ZMUQUo)#9&8K?ĥ>CԘZ𯊍]Z9\ wZ;]ф>ZX7>jkmutޣ_ }^j`-A;[ΛG [ܠqz#n\AۇЈB3\۞H(ũ[~D5r yPmeZ_V44~Jr12v^mhyY[/J!6_JZ gjvD +QPR8ܟgi=(񢆈 ,>7 +V(bT DQڈh *9*"gB@#JU%vj<ΰ ]xEC8exPeKB5!*V;Z.Yj=LeI=t9Uzz`=$ȅ S/wP 94=*Dj#"{93!DG#\cƄ"Sou)ZC(>hAG#\N\]A"<@c=o +#]y; y,`Ɗ*)>"u>N4]"o:8QeK0lAk*PdpuЇYH[gK&–Rǹ9K +bZWȕ#Wb7v&D"Jz*;%, z44S> :vbAH! =6ޠ2Ԟ##zBAڨ2ha!B ־ Uu8ջTx4ħx;0(|BT{^yy$`&4|0DǭQǿFmǸ{Xd8ҸzMZ,Rnn(PG]ְZ +5XJk55$\-PpU~` ʏ3?(98G˞ O;-62QUvFDioPj-xP 7XTDGdU"{]ޡޥ +̷DҐ +RmzD&'亃iٛ%(ґo۹t(fc :&R{&Sj?h=Ⱥ&taTkdVdb͓0iDQ ".X ԡeH%W)DiȊF\ܩ|9/6(44DU(*<2uu3!D5O25m + !샆T&b5iHQ `רTzhAR_Ɠxt }}*hV0`(rLTᛱZJيZG鱣.mƙPpfHfAUtPqj+߂b <5j;5CE5D5ٱnPTwAa7XXp +6R+ᬠ5Y!]FRV Gv fǵzE–})!nڊݜ)>DʒvJXTgГb uBNV.uШwGv"0vC 2+euwQ~be=C8x nW&aѠ4r-*JA ˡOYbe{Y>/V3Sҹ(j5 /F(ςP&xbw2> 2zWd>n +-$P&a +F-豏KW@-{Zkk ,A/.UQi=*C4+6$l8eQzIr_Q$VeHyc1WPYKMԵa˩ASFRqE=J =C[k,BGXP js6_qwgG52-EP<8iDD6kt;6?|!jٗUS<`Yl|Z(gѹn +}:ފ !ODU`W(rpUYE\XS`ڞq PUXjԉ3C]FbHd^6XC=֨:uD*ư{xxgwMB]xq>q fUO{"A5sskm\)(;܈B:Up[7uUUQD%jdINoA%LhD{fkhAu1=\]. +#>Zʕ ?iӂЩރ:d$P}[J"TlµS t5 ]H=#vŤ{*3Dqܓ%&t-' J̮vGA7{^S1SJXF]2hS +#榍\7 Mc^ +}?PA!T*e̲,.vc75UVx߉RȢ@3$ /;,=Ȏom EQ<h%bB<S(Y)/Kz4a;Wd҈Bj +USX)mDl8F=" Ap۲NI6)5[Fsר}2)>)8l4֤Q5z5pwኑP˺htЎ%lu8Gu8eu8ku8v݌EEØęǙc8ubFڬQ]q#רďuSPy >:\];jp9O֮'nJ$+ND>BtsYE8 +gOlb L5j{5Cu5:|̐6&؜j?N I+Vc>:2ގnj(4(Il3b}E5؃!07,"XFDhoP%iϑ:D(΄F6&:e'|DUKU!]K+X}r՘RyIcJb N8puen)E<З~s^ds*$Tp`Qz׈v;n"5%֘DylqGEN$k,^1q$cwi="IT*n't[Yy1^4ZM QG OF,iT/ЙVs!t QZ[4" ^;5@BܯRІnc)Ic4=6Pﱁ/TqR轨gd,V|unug5E(V0|Tar rd(ܲ?$Avo>;77K9\+ ]PJ >Z!U#I zU1V(` ۮQ[bϴ5kP<{fF`@܈GE=]Eqz\]6yU8DW ERaA+N∸V73e}0"9_ж_I(oIC·*iJ9s[l9땅:pI-kDɔ"Fz[F?PhI!1#G$ + +$z'ɱU{sZE+zQҔ6ha_tb0:)$6i;Qи寧B焼[$ru˦@4{a-"vz xyuhVA(a +/W +qUʪBlLr>Wfc#"(Z7I&LG ͲշJUtx2K 2D2DTR%X!eBmSѝâOwo``-X먼r,kP^rrZn|;>. +(Ӄ˞q +BTY ?^m^8<)DFRF px@StoC5aF%J]([3S (TRfzͷ8 ]{ JAC̒-3stCrō)`Vofs$uXrQЩu9Q|P;mB갢ti +DSZIZc@a)/ĩyGӨ"tY +4.w CFE%_{ xJuvti'宝 dh(#;>llĆTvJyE*+ +ʾ +5(LkX⭘[=3#3FL ;B|Q(Fqj츃ҧFN^ [p!zSd@GD=MeJ?P&B2;F9q J@Tώ3{g(1ͬCl,D;3hwLݽ2}t[g1m-;3xgF7zgO1zg?3fޢwf̠⇙QzWY;7fR/APuy՝8:H3 J֨gu/|eqžf. 6q]0J~7&tEv }**;Τ@E'+Le9k~>3=;uRDFDH4(yF<.xtROYk8X8S줞AWv + ayuRZAՅfRK&R矢PA8- z>һO V$떪_ r҇8MVr,6!3K`SQY6Ts5%3A|ZCC +M8PuqIɇCA ^  Vأ$l5O`~05J'ybԝDlEPQ{b1 ުE=$P˳ zubnH2W4fm3 bji,Z~] ;UL2bð4zQӤHGDFQ +k0I+kQְFue5l}uDf?dV4Ę :zξ 㲠xL#@\tldӭ` I]0($9@"/Jg +(AYBiC!ND%GhJ!̅SμPYE [=s@0K伉) AbOQXmB.P⓲YM1ӑZImHth٩+`8Z~{ʈۧc/" +GJmPˌ3K2/Z&SѢY>0vU5QXX>-T1/L zOLNa:zdE y[8"hXJa +# 4ÿb @/JO0# $2c"̍(!r8[T= +Ƹhsc\͑u1FH1j%CM5ž1N#/tpR\( MDBaS[uFV4yjAlx+@­#OhQb֨F[z_jarch+[t#{ BgAkK_'8ET_( +7h,pBv+}xdhHA{5g|{a=%Q,OW@,ƕ4yy^.bx0nM&kݜ5jG5Qz܄PYٓ,rOk#х@ZH1ATWmCf2Ni}f +3֬/f +R5 K9== Ń'ߺz</TM<ܽ7yָ2+98 +N'w9EɝPPaC4K ДO9*Yi-v G-GYݑ*2U$9F; +\犓8?{ ($: G⬰y&=sC|B}F'}J^ZBNdS +6'WYeրuwl\AdMoajh^qa }^; C4aE{`l{@k8)M#F{y"Fn7$rQCz \ںSPOzb3BNrRa'˛2ps jV%QLFHa2z9eO~A)dm"6 Vz-P@|mPMݝb/ˇrO<P ޺xv.BNm){ )j%]I?{gi:Y6yxX&73<7vwO\Ltw!Q3v0Aꋱs. N(WtA $d"cO&m]f"_zd6w#oYkJ|+w97X)f}";8xQvX͈rR =z QNCԻs!Ӓn@I>$&X$C +:GݎbX -I3U/3ɨtCRt <`PB!FsG$BrF8(q^y+sDq+V5oPqj9v$B~fmY$`iIۛqmٶQ/#F_Ajheޠ" "bg\ ,6q?l0 -[kk 15(Ut]d!v15d $2$K/MP\DQH $Mf"MtiM;U;ջ4Y2g|nro'qDfNC >{UrCkPmwq;~dYi,ז~BKɝ>ܯ`ɂg QTi_j`W(_kOcĔ%|eW[X¹@iUKy@%(>sw1hŲĘBV 7ȉ !DE"H [ %=QF^g:~iB!р̺qdhyUJO3|>o )\;I՟廈vOQTpL[jL Sq&0%' S [yzoJcȣ{U3Cq5Ԅ2) *JxJHSHרDڅ<$zϋi36I͠< '!P2 Q$=R\Y((ijڀU3YU3D_kkW)dkskcmX,xA𺍦42Pwl*f7+HCXpcbn"*8>)4F(ZuվAE÷6T\R5"'@- }(ְ6ҠSaD@:;G{hPd$$-PymBC LYrbht=XLqK8a vvi&&/ KQnL8Fcj JiD!nt;9kn_:ݦzDx3cr@] >C Oi )pJڭ~@V|zhS*] R3 MT')+[E7hNA@*N=;v5jkQ왃okЩ2Q{fhYw)A#sX:$N(Dk⿽kJp];v\;l+xU_!ooW,wj@>2A"w; +`\l,dT>DHu~tRA}T]l +A\W]Յ-*KvvPW 6l/?@0b|ԩ RQ&L"Y c]Jr>T +( )܆Bb' 2!!`C7yAT2;NcJE[J>n/IqH9јSWѓ֤8ESg ɩh˩P˩H˩Uo`NA%{O5:N6M~l梳dqN]=-B"9u:JNA{N:ej~ΩL@Hʹfws +*q? bl)uRgQG#$lqٻRݮz-"z;زnp8%~:JNA{NiԙHR<ܥpJ){@y3\a1ݘU =e@}LDA+(ypmW@UptT)@m $A9*Eimԩ5;r~g欙 X10>3xG®*n7 +*oqWA " î +H8WH# + eCTu([P]L.0Pi >E$wˍT{ eS܂NEL֫ThS?#$FGћ>rCovʅqr]綥A.>Mt!;7Aj&6Tsj?9Fsj"0w~sDEc H DS>oF=£8v@0$ԍSo :msIvGr\Q2E01D([jfQUXQ,ATk=%AkXG(Za3/lAn:q4H$D5M%v䔆p|? jDe"H[Ɇ]ѩFqVy[H#vڒƸG=@SrQ5cK^S.3ҨmhxԈQn_&Q%/xJ",7J2 }ZF8tK(DHnÕ0(L&yp#! DU%JXʐ4c ( yvtk{5Q c :S&jW-;13&&7MiQN@oM=MD9͛9L=n $/H~[Y dP7ahH+m(>$êTYqQxr?-7r>- *+ax$7=r9+,=2+gEwe *=Iw!k"hX$_83@9e!W0 =k@, Hv[ k=O;Ii5PH|5!^cL%Yc¼5'F&/k$4ָ`i \v{.W[כZm$ٶ +b^/Σ?fB]0U$~=S"I֯=\D;mUZك}F hF~t;s&\20TpQBImc뷞`_6:My8 +mi@SE#DX)FKZY.c3PRbpxΎ,k7'4 +I/g;(Uu5ʏhCo.~=56zj@Q, AO꽃W 9G䦸j1:j p2hJdM+Cg{#BgyZ~T2=i&]D}[w>VrX^Pe +ְFCwQ)p՞a +>m3C̈́2fP nG>J=4* VIc`¨,tm9@LhrF:1o,jYK8wPڡޥ*l4EKSKes@%U'.~9<< + N6rd8<̠_3mlaX +Zo$pt3%OG-O6Bh#2De/!]:F+ozAIޏ%gaCGeJwіg"}bFU+ +|( ~SX(-R` Q?m.1aGnZ'c'Ve`a_iU~O +ޓe [-^K2 aBK+ހ3RLd#W1aqz> +H8 S!0ّ%X+І" X:kEY>-Gi#f)([5%8/ e4X5DH%xmFN~}y5|NEebDAک{7Br$tgΓ3 +8s~PD:/fUgP{2{PowGe ʍI~J|A=A|8lGQu2?~U/KX3Ơ]s?;2IÔad~(@#ɔd8Jt^e>j]:'_/ ZtZ,A4hteG__Uy4m(h|UNяΪ8j6$FQkDN2cd2 =+QQٟiI $svF 2@{ۿx$%|)#|T4h ˮdm-2K&dQ7cg ~B%4ZCde +(8ҩWP[ۈh2 LfhCJ]K]jj?Ƹ=b+IIt gYƊC)Hq-c tB/sZFwF@62jbuЭcHb㈊ lcP4ye,*bj#6fX)GW5- YD Qe PۿRFqMM-i[]>Z^dDk >/?c7ZmMiWn<]Buzh׮9V-(P!qjeOR @V&@rhd4d=S}dί +ۢm!p>nz=EzES hj53[LHL-(Yd#sH+#"F)Fը"?֨Zy4Sbk[dk $vQKM; YFO {l#+bbP 7|X1qNG1!Bq'PD@ɬiձFY4;iAM 5 +5ؼ$L|5둼9M~ +;U3OԝmQu' +%rߢ'?c P݉7P/IO.mEgBQt&%gBgvm,]З@yeFk8T@(z?ŌN\6=& Q D?bu)0Vq:ЮEef%ׁ3Of*sqͺF0iGkN|mDXA;Uxi DGa['WF +ŕT^~=u:]E2Bk{5P+toCZ +Vmȍř2<^z)%GF2(1|;iF^yc 7"(rXkX{MXX>Ԅb c1vD2zE}I)lw哔BJ0Yw>1e&h}zL|x%{~X|b,Y8;%!ubĞ`fao!i0y>;ɠ]mRdQnsH.| $3LQLFCӢA\r]h4X2=I@t8Zf)j;M9'U7;LnvWftO6jnAxLsk?]PbG h+jҬ}=#)F SYh>κWŝmfB[ZFIPڬ,B1)8*]UVtצd3A0#]/ WWLŒaY +3b%*̉3f.Ps-BfMj)S8>b`0G/͹R :Zr MR$UmAh' s9"cϡ Ĵ(Š]k#b"niDjd ( eATJ}w ?A?<5Q%l]JgY5i\ Q?@FZfl!)*5 N%؈V+P^FSc 6W(M^b>x}3O,zIQ2eqfЃ)X4{ci!y Ը'F1ߞAH ϊ5y1`ؼY (Q-th˓F뙱|U H(,6SCQ7J{GX!(gᙤWeUy9T[=b} Pt*ԋڍ;xJ1 cVs,LjE[KNJ+^#W/+Z+te9|wқ|ͥpQ;dOO%Y0-R_vcG^EJ:m/Vrr6jX| Zv#Z5qBwΈ qĴ1=$Rd!RՊuFI#6yC;kAiظUZY]ABq"͏Pݜ8շ'F\O,tObmjU 9km>bk=o!|_x[ֵ7?=]uLuE`( +E%h:PQu1^'>+:KD32Fi9aYi$*)y0$i0r N+xݤ[g)j^&i&ƦKԇ_Xgyʗe[aPh/ofI| y9єߺ3ҩNs&3ϯ`,K` ծPV=WZ 6Duk_Pusf@ %z`|oi|cAإ;(Xq BEiЮ(wDQY顢ko4e}A Q.G@T&H{ MCUT"p{U UjCQ:pєAQFEl` IREj(w(EIq |5ikԩ;KZ{ePI5'"T dIe==IoOTdRQ?'(ʤxLMPr4Sp,dwqV&8d V&2 QTLF&GcY(,R/Ahn"?H%JV>)n);?fѴA" 6 fL{6P{2ÓJi@b'(5m`D{dy.`2Pf.Αvkq ']gVyopc#ky +97KAޠMBϐ8^DZ>/Y Vmg6*zǑm3%"OޥhwF vGA[6`kT~[H0 fO4͞hKXUj7X3[-p.E~޲FNr9V[д[\Whe]G$ӧaDn*7Q@CQ%6TK'IN({Ďj'pw!7@X4H=[H@zOe7] +3=j\~QJXn R䓥8;5qvLԛ(UJ\*q/9]lDd+S:Q,@IǪ^vs';җ<r_B̈́fv&O7,CBAe˧ S]v/#"| 2s O\m$ 1!_}G&PHQs _$* }^r=fN}^Uw.Yo+Bl>swP+ZUba-}z z YΈ&z9$?dz`s1CTtz wEeۘl7Zw0<1?䃆Y!^-̊Omr%`Hv0Lt&m`U ̊hrQlHPMJT?a +83p#d}H t3Qd^Zw/ weҢ|#7›ؽlh7a@C8yҸR6qyZu/ބ,Ė PKxv$9 şI_X=V: ]9>4{A&z rCQ0ʑch+@qp9 +PQO629\S#-wAݠrLN a0}拤h.du q&++ym$kxm^!XXb)NT&a?Aq[ul!lJ(x +G ~Yc4 *.Gqw)e (EGQTL;h+QVI<eЊ4/A-t9C! s@4Lfڋ luskt)0br<;E7/e7,|߇\B(vʽ#Uatm4wng&Lt}pRN9.){8_o $>; 'A'G{6Gama/ t4wYjV1\RDsZ* +kΥ'A*q6| %fm-89PG% '7$:ipCQ n7n8w uCYqBdEQS簃:'&Bi[U9rN"X#mDp8Sj ^8jz8=mPي +d'zmv0%je"kj4mLˑ@Y7h XS/;$R>lP+܆"D`WڀL(o\r)Aq8mÍ$Q]z bF +Ũ9kԉfcMHET5ԩޥi7(j7qDee<=4hUQz)xqD<9w³4K$Wf "2K W5s( cvAu` +ph ^X1Ib +)T3BLV6HULI}PߤF2Π] i#MPІ"Fm*h:8 jjk]燑vǞ̙R +z}<%HHx($@v]>K"[/yIVdЇ.9+tgEZsU, E&bD˕Rb܁] m("b $?QI~D>,AIl$D޺uO^|Hp:$֊rJmG׭xʥ p5.Zf2h4i颁 Խm)L)=fr (,coP.(ig8qrI=CD~Q z@Yb`v#v)%!ݤl2DE3( !'D|7N9!=dz@ }T:VYV(}ӚPU9~Q;җ s]ćʻ%VH"ZэOoՂ ]*ʧ*9ܹhj`Bu,qDJO`!]޺' &BOuJr)?UJ8PCkt Qi60p..uە"]_,&`nisw(Lm 7@)e18ԥT/38?6:pm͡]:_^x>Beaif)U75|>2ʏx R*[OL-v-+n"_Few'_})o4_~K[O8>#A:v2H$.<]qeuj%wq&Ml|EkV&Lٯ  (cq?:AF㈶G +UiW +ӌR}lXX"M(*\*vyT~hyYʢzٿ*ע6*+ 5VGZ{6_\!% +sZXGWI9y[ϟjv;A_=Pzĺb~ZÈJAS}͈e'buPPE-eOI "Nik *= %%r()ygI 2Q &THO>"CJiB! uh`ay9E]~M>]󒯃j=-E͈bkf#nSEItZFC /#ڗ\\F` +*>Ed#gt]..(KdAFUqGdQPynaq%4 +DC#Xr 1q]T5TRbOWϩuaqDU7G-7YP@o*FQBqj#?1RA+J cU .8PI!1Y0!xNSG@Ó#<Vl=y~*r$Fr$q1p$%>tN|%a05?tT $ =#Q A|Z};lDTu Ubۆ88D5H?3xUU*ޥ|wNRyN#(p!wQ`@2$jk@ÿbϴ5^8ր,Yކ-&B0(zEQ {$V(ԠÿJL kTajfLĞi=E9̊ +S/xNA)ʶ"l! *ZϠ]#i/4jk\3aT Ğ{&eE,34ZE- hcuQ4h6@J<ɃwHg9Y|W'#YPpj$#9R|VɇDxC=ő^+T0Vl$gEagDH?KԽAzZyiUѐ7*wFbP2H0k-'S9̰F#J_[g |hP2Xb!)c.9f?H\3Ɣ±5zO0NZqĖ2E5XDU|.V(ohwQְF` j FbDZV(tn8~ŐGր\*V?*!㩇w0LXqCW΃ލ?/ʒE-D|5/ddHZ54.˭{~ണ,=>}Y{״9vhvb꿪CDIUq{iF2w2VPH!É@k7 ר$8~>=>jg:/*/Ɖ9&z6*W"2`ר2kX<=z53aJTYaw t8ZE#Ia{4t l7=fl7kw{ȑ@?~WFSAm;Ywcn│]VќV3Io4fȠWDu& AԈMO5!]DeC$38XrL8ػ5ޥc8%SNԺ8*BX^@OFM$NnIR ";RG}(uER2fzԮߌo5:N|]TrHvuw[FH׈A$:@K3kf$ 1Y@kTWH5aa]$9~5vzQ h+* KYbݎ)(PkXN|@ÿbϴ5+lAW#gf- eCX + h9AK=ky]@2ijZAft(UAUj( QzI;\@@hn]n"Z Q҆JmC=WH# +ZhhfuTysz*cKy-"Kˡ4I6Jt1"AmN 'p zQ(2,뼌~gh^2߷/z`,r B$I>Ϸܟ( #Î$b ?,cS@[Vikj"X0Th~}%/ Q'{{h(nPGImZ zL˵Q.5E)v (=gC*Ȁt`vf4)P7 ڍknEw@;1G:nq{YF;ڪdv/7ݻE(:ZѪЯXND+t|߉ 'ӷ]JP'$=|Wj +R0jH .J s!sQ zȖ4ʤrU@yiF󮙧iD(4 l|G* R`yhGۄ>҈i|R\ 䂜fܩWsvq;8N} @+'Ӈ>/ynfDv{ ZW~R=K*A"NN {+ ʻ(ְFmcuN k{5У_8KrZ mi5`sӀ5A;(* W( g\7cӟbdve\;&gT=Ot9̨g~r2Il{zg 8s69gHsj _+83t|P(1UϑFE58óFQ=cT=O5kR(n/AUSK%AoϊPۜc#Uu9,dԁV8FhwФjһ:pgӑ{!,tNVA' uu,2R}0~iғE+zRĠjvZc # +Jw͈2)21(E%I(` kTMtX=V(l$3?vEKUWt +@fgjiU7yY8w h@)X.SfNѢ9Vȫxw+ 5ZḠ`HInRș]U$>Ɲ:㴺.|ʓ@2)g qڎ,n #=D*~W-s fFmHgsy~t[2\Q\慨q7~ t=}8Hh[?9tcC .EUu!FZEգA%}Fťc:4H27jo_h[P`$J0 G]m +\R| 9 su#l8YGKA-;hRpnuV“C)HrJрiv[$Mjʉ?`JVd|> M 2%A?;*䘢ZVsHSgph8UaFQ(h tfdy/"0fC֋"x`!h|EcL$ B*GƜ|0\hfG;cK "DQt2?*G5*a/`ÂDUe"̋VY(Nx:I5h k' [,}ezx')7lUO~y o$AH'D17AC?Kz5S!@;Nt D!F ޖj6PatPIm(b99ĉ͛= +cVp(k& kR QqΠ+LΥ拗 R(*בE}b4R[i*je BBk4)aa^w Sv&s$Wch+ [C~\B=N~U7|v T}p. +k4w=1C0?$IG>zt]=uET]W@=ױVv\l4$WSY(Tp.-trA{Ӡ.bЗp4.6X]dؖCwM7?@%PY&y&P䜘v=NhdP#|`o5Fl2NiIsu+NeQXsyw& "ΤFQ5˲IKTkPCgZ +VkG5X. A!Aրj +#+#W6VF{bG14+8ۖ<>(DFDA + |ZI8l.=p=5h,kmgX'e-ks a`mOlk2 +I z +Y =P3- #k O=@`PhD0&29$W@]sL{#\"I H&) kT2jf33;e2L q&,J V$InʧA{O6j}CMlX|6p؎~9Nw JI6FhW 9Ӕ)V9gZѣ˚h%=I9Zdbc̚y8g`54 {GaZA 5jk e( 3KftsLhJcgAbFʪ#:{dHf G{H*,X}?VDV(QG}0&~Y\rc$̌Ni3w"g[I@C7̯^CnaUmA̒vv2#*$54 +[㐋\<ձF1Z(a8k@I㰈qpHT "dOp;_&uۮ_B[glە8D+R`w߷v&  +Kץxmmo< a(j@;}$'3u]|?J1Sۅ W-DYMbNsN'kOsܸ鎜#ڒהAfR*HuC_e0_$/NYʯPxE#t-b /R/~KѹPsE]LT2Чd. #maw]dCzNF9OՒ~3T5(Qȕn@u{ו-aXlm3ԏ>*R >MVQmj*,6p"[VKDG(kUvYBmf~_9"wɢ?J}Yt+؅8*Ak%>~oŵ}8QjYB9` ®A5ҩ嘈<6.N4T -:,?z fd/e$gdک/_i=&_= 2?LT`Ȣ˟/q ` *J_0M#e<᡾`x|Sbs "|AE@Pz}$' OM9 |AC_p"COz?$ر]} 4-9 ÞBMA{sVh}@JI[5'dn$u=ܠ L)P]7H:k.릠|U`aLb)sߑ^^M4u N{(g^d3'{h7];=3\8#3!WTu3(z-U=DYy_qDERw `jv"a]R;l:|gm=X:(%#w}Q4({䮖޿.F>VDE@".LLM>GmŅ8(*^b:B=?~@l2E9u2y؍󇦆~S`lz<UD_AKqwC\=yf ә enn+Ľa}k.+ï<pD *f8ٯ[2Bm_w*h +f+>GJchr"c&x(]Q|%bt%(&xuec|7 QwT,h\,~-xFz5&?f6\E4Bnw!UBv%GML(*g1(g3x{` @ .P} +Yy.0\+0+ĦRxBW DYh ȫLh I_Dioisz"AU!++CșG+BqcЈn=&x!utwo{:w!w?WP8yOxooDPR@)'/UMG(xe93mRS{X.5#_.t.aUyqw(=e>ڃS3c++ Rej^4Xh&S!w@#AD,ŬJb7@, 5)}vbwi3{, @LD [Ƀ7 ~B}=( hT}=A}оG|m~GCuG2)V"/i4T(ne< (uNh7OH>!A..А"A*XkRFJ/I\-z]G h+{]<́d){RZo){򔽈Dz^Sۖ!O٫S RF _kT'@hLlޡK yP٫z^gq"7RMb[߶ tV+l}|œA]GF gBODs@Q\(~GM)A"TyP. K=š(.~;#a@dOP=^̀Nꢢc`#!%Ɍԅ"\IB UyDuT(SЎ~͚;-pSǯ2do^e.h\J͝*elvt'zawriMcЀj PbK#dK+8} e$ h_9%f+t_#O3jID@+OQd/2Z{<_vI'@8Qz#}QDXiRyT'֣3H_n91 9 O_T&JϬ4T+QSPSiX޵s^Cs A5о8gkt\Q+!df':k_J}ъ"2Uk?5×ltZ>>e| ➎E.ck4R;ݟ1= @гLf= J"Y`w\Ƹ^񇤣=DȖZ-Vd +^445h#VVYΑu j{Z5B rkdAtd#jpH: bA 7d 7 W7&m9 ?]s x([7 ­qW] E1AU]dkA+"5a@F%lzff56y׬k4W0@P{0Ֆ K 2}h,zzXxǰT}A_g}YwB K'/K#jZF~Gp3Owzɯ 45my2ѹ\8Ƥ/çm;z \22+"Z#NRV D$<'td%&LTR^t+ZH;`_[ϲV++9m;~SozeûJjFﯻ},q,iw *§7dw8K%;, okZlG dU(erߋUԕ_<<}NgNP{X牒U~O(=At#j4~pGxPtC{B!DFDp#Y2(1zGKhAcЃ<ΛFޞP+407T7^^R%dGI$x=TO %rպJHj{ gW,5)1y\h#X䃠;y]d%Woz9^jΆXAKޟċsbX,ثFė0-Q?~h{P?0fv@ sA=-VnFI7%7,A +gojQ<-hs%vq I-ץ]{EiT G?<>`J}6LJ#_`o0`ڡA +h654r D ЧA'iO^ω 'ƀs.*YV?Pd"Kqe*,㧛P߹S~jϊa]`#J]}B[?~ aaSkajFg(2 Gʸ?z@ +)epչJ?,jT>{?Pz_7qW]>.@zBs  $OAEh|?@cSu_n--"X}ף +Y^$4Ɠ"kL(WGc-#Y~ר2ܫ 83Oa?# Gm52\Hky5*ǎB? Ufsc]t*ZȜ+znM\H#B:,7;MZU1{QbܟtA3 ~ݨr㷵?QetY䑭YŽ"DKΫV`N"fqBn)^zt:Hsn0@nڒ%}Bw1dkC-r?hH|})Q +<#f!|Gji*uOn#XkeD'Xgt[ us0^ +m!:amȒoa# 8P01wew\[?Nc +}4}fŹk>Mk3ϊڣ%Ekf)u. /︚ ugpv ֺ>?_on*T:bzJJI+ı~M{R c{ruVRǣKPmB7}Lzg7[.ԃQHw{sa&W+P埽31k}ƒ,koBQ2řbg)ò{4L;t6瀹2wK0|wh(}QKΈ' -m{B HAN#߻``pX+HPؾy.LJ=VihZ!D~1mF羺@ԭ!~Digd;F=jdDyuZ?A0y)1_E6w˸=  XI2$])v>~SK6dӻnO*` Yk, lL*'5U_-/V +%ѲY +4h F +hB"t*N$l(EpbC +z@&ABBU#g9LZQP +[Ń?;Jsd7dܹ+M>ӞZ@ODW ԧĶ>u-rRȭTKplB =8Ey>eFy?Py 7'*d`ChaC=,|Rݳ9Tr)%R*n(u-Qe"{X"9KP?C΋=PYzLWd."(<FxxW#iQ!!wdx#fZTh;x]\/թ\ +dQNQzr2x W@fK1jkrY!v4wA1$*w*Ct#w'ҽ$@S'Szu/qy\. a4G)0BY҈^ ʹBrmdiVɩ6zLkΓsY6uW8[UJF\!P) -% k&$Ҳ]nluͲaUvuQ;AGar"+t(%8>6@s>gYGJC Ȓiz0 ro(a +?Ȓ B۠S5qy2Cv +E*% Z}`@At&K,:,h č'"Rh<BD*k4'O!"u +kRJ6nBd3$+qA)E!p# 1uh< QӁ"캥䗪%=t/5j~$/@yz "m^B}N#k:O=~Ohj%R+S}t:{C֙Q+}>WB=Zgz Bd GIoUHŋ:rX(ϲAge{יڡU/.Z]òi +X?6}`vPzFY2gj{8gN EڠvI~`嗷/+*^^Vрw; }~@jGs/Z:ݓIp/#DŽ7~SV‰/Rˡ9 ^ƌY'W.EvlW+k#NEVhͻ^bH"ROIP)Y (T\\`Xʳ2=bֻ|CCm5# +tʩ +}Ĕ 8UɽoN(5h'귒 1Qdk糔DI[6`.-:]]嚸lh[QZ:\U& D%QByF3R#ͻZcwD_xmE$5HxWWDB%`inO@\kwqcqjz3QY+QhK4w" d,id?(U#r>ܲTW +h2cUUOqvU8=P"·ʅ\#$`Q{B(5cתUU3*{V͞e/wu(J5#<ȟX] +B:.UF~TTTJz*ՌJ;0P:U)-jM"I2)e 2l.I?>^QE(RK0 +Hz"!"UӣHzn=MaHzR$B9o0Dt4J%RIګT#Q*A*9aJKD5*xU+<rTE7}h!TԌ)lr*D40 # d<߈8^*SK3X;GR0z22|_>"AU7Gr_v3&cۻv(Z>-^ͽ B^{2!2bd*Z>ys' BnLؾl?-Ryٯ-='\Fs Yr8, =QakzYArͽTa?u\rL_emJ8FaAuv\qektC-Ϝ0|,i;(P /Z8 Jh8~wa#e4-8|(>ϡ>YZ{*h +vÝQ'\$Q=ڃ,U+Oc巡{LSD=Иz\QS +A2g$'JsgWqÚ$ϭi5ʭ;tNGrêsupP7Duk4`uwia8ІWAd#34D,usa(Djt~uKӁ0pb(ĵɾTԕۘP.B( tBufajT)Kg̐GR]) +:?˒N%)AX?8+CRV:jOQHz+ut|3(=A D70,Yt^FĀF.UKb寢F2$˔e1bD빇;0!2XQ$CV-k_P]VR$ IHFS$JUԤK.1bl=۬#!i->!JH}B )zdmHz)=K2B%9 +YoTgUGut07+MWB4>u% pn,/Bx MS Ά)td1"^cCqD𝒫%H|=P g\p7(v>#Q1%B H_U.w ^bh&xeЛwH B(^s48C*(|O#Tx1ՅioKY%2*{aؓ˞3- }e~+-C/zZ60٠mP8!Ym;[.$6ѝ䌪HNaa~#ՂpyII^R'~Ytb"7aj`s1E4qmJ E$AA]r]6 {7~ {_GO͚eneO5ml=/1?(זAo?;{ U[e5=|/}/:#o;\ݼNOZw;{7Ԥ{0U=r8,;xJsUD+gnEoz9+G |eK'!x,f 8CC֡}4v"\,i]ۣ^ֳ0?ϲ՞=?DvdEC9V*H}r[9#s/Dc nY<*v{#ZBvbul|^eVV0ܢ>e/>:daCis P3, xT5֋2Nhz =`>Ŕ!M-sbA\P"'}ە5 Q$2jL[ ?OZ;dB$Jg=b5_:87~shϒвѭ?;pZ?~?8+ +UVKxf0m0Vw4ICW1y"V( /OO`AQ艪+jA J=gbON~c.%qfow)\(9_Ep{0N:Q(4iKF(LddV?2i45FPIh''ʏ/{Ĝ"A5YC{`fPY~@왅dLA2&{Zֆ+vۭȍFME!e" +<+hnI_gqRTVlT)rco:` AGX๪F,ReU8Ԉ²+^80xT3BdRę/U&mB易-F'TgVJY@aբqf~*U0u02\?Ū~DDb(H_}EBO(fzX@Y0d,\ӹU(;VQnϟP n<6?y c/ ЮdWa2р2Bi-v3*pVbxF^W +Խ!TzJE1Ү!RC*6T^t&DP Tc0pK*WRǧѼ +s"׸ +!Lb#X^̔ -}UT@8=#HnuU ^@[l%[nۃqU5tV!/!pgBcXGzXM(J"WlJEHW_8EVT<>B0+jV?nY"{y W +*f;^?.v(wiϯ,3PT5Zh^==#`kvEKP{XjG%tA9zF%RCGf YK%Kpr%,_Q˪P.k<~ 'P R DUWkz0SN)~ylۮF%% W娨)k<Լtz݄ IkgAQE% +oK#hI&.}˫U_=iϧGwۯQ(XT( nXO(Y=Q*|DOΌ=PUJW׉3;Gc:߷G&{RPu5J}jB<+xP})_O Oȶ; +>2a̐@@߿"ofS"!P"KNnG5RdB9_]0i~@ZDAH<~g/rri[!nQ:JM];.,>B\;on@+T7$w28/?qoEx԰5L_"uڭX dUB*לV⅊*V,swcjNOΌ=P݀+e=3n4f^o*ԯ7(ub4S㗖٧(EMܽDX-0Aq١RC)jڃ@p68s%!?Q;!dBTQ-~YŸiSDU^ȆUUIj,|Ǎ0ǒ./.HnE,H4ʂIEo4M` dE?VM vkbj$M(?\QpEΣ?d1ZFgDޡ=0cw|E&J]n%J gǻ?z_5{6@u e*j6Ȓ}m\oki:CX}1v f<ݛ+ק"T O42\l\~S80OB1N\Qxo$LL>ǟi/WՈ ݫ9=V3CBm FzOhLEluZuW}=aV+զ +bw ojV~贬;"y D3W=whG;ƻn, +ِVyd }Uy Q{Ռ] Rײm~W'9 A6m6Fbal>]Oڟ +L94gauBOwDkiKYcEjA52]GV{=|B:'y}B3>=4gIY^hv`#CRE?s*ZQoQUJ%ń~`JA*駿JA ѧj?95TG$$V?!UpJ:K {=iWdB\dRI в*i\?Q;!d҆JZQ*+y|B|O(΁JzpP:%H%=T ~j!.S QꄄEU=ĵF$xQ^NHISVƂkP +NsR >݊ĨRH>p=VPS+LB^2nixvEl@|z +s6FAajQHe]* J̀'T{p +83J=lO`{Z(YCѧ{hϲ_SJ()i@Usq_ZCq.d4D@j,&DG.'m󌳽j= ^%ͧ^6|G.]u 6DW;y(QfׁyYpâY2L*1@Ϋ%]Zg-~V@mk4, >}4/}^䚦P>_By+M^+U贄UNDRoN,D +'WO~Vh_Q)-!P,^A}] d6xetDi~I>i;QW샚Q:0s+G]UfzHUEK;{U[dgUG;Lِ(MCxx8*}1~ f/!Ҭq,Ivm9L_pqe:U}eBceL&ߙE@B)V[ZB!O64?t>nߞg(*kكsa4RIh(?4(cŇ D(Qù´U{ +u1JPD (E9 p0q5qz@g5\*p$j w%jPt*Rc%{B_H톾Us][T:qz =A_(>'srB_*/'Z,{DW =`8k(P}wtrF^qwlJ00Q!"x.rAi>c(DNU\-p<0"xhJzUdS T +S'9qQs.ٯKohPAQ.⫒{r*K'6P8/%HEoh=3Č*9UZ;H>ݜSk×H^~D {EPKPlmkUZ H&|P\5EM/ +b.2jA_H~kJ (6p8|.F=6L\5v 2)CMQ:m.v}ͧ@ +=_Ӧ(6mӞ) +MM}.ݶisWTt6Q8]ڃרK7Zn* KbDkZ[|isЮg0 kgԥ?DTj5 +#t. t`s ̓3;P2C +Wk!N!{@)R|3 #"Ϊ=A4ء@_߳vKL<<"r~$(ăt=d(Wvٿ 6]"ypTguPz`FFz^9KΨ? ,۲Ԟx{B#jgq6 biX^F,?<}33ЗOB'Ui=|B5{$}R`ƙyPٴ&zJ(ជ 5:1'A~l +3ADJLE9 +ǝ`s69DiAH&:.x% ߏ27tySѾ¼"k11L#Kz`B` d?HidDC Fim|%{CPMGEl>.Re3˕fFqi3ll*D>C EC1uJiaR=!@HsxTarjS2TJ +G*t>7\e\0w/> C~I Q *c,qkٙy>_=2r)r^6J??(QB< Ϛ(=h>bƣgfiK.Lk~ImdP jif4dj&]S5fAF'=2Z凢kT)>|A=m": %?5~Pr/+1{fߕ vYQ3 an +f|=E=,hYV(qlԶq!O8R2 M ʖ^'2[' BaYE .Af^a}yoD{D *z`*+ \=|D*>BmcǭmXjhNeSAZ}Ǒ ϓ tk4%)>L8,;?kI*~~aB?Z{5zw6;j=PަmZAqv3Գ~)f?8y)dmmo'#5z7B{$?;9_M[,ZOlO 3ȯ[/sh x@L݊zAns6 _fu'9 A)v='ۑݯ- [-eKUGtBϲU@]<& hפ!GσJ#*}j=/:D HϻOhN\'yB>dKn9@%/ẗ́=s-=&J#Et(x| BGѳ޴Fg¯z8S/ȎUB)5B}sǼhKQz`UG 5S O!L-K yOПeT =*JAwR/1GuDw^9vpZ'TGוHxÊ4I+zY$ JwQ﫺W +ѽ>sc~y h5\_ w e 5y4K )PSH֣TrP]hlyvk\}Xm3ϚhY)h0ʷ(j#Ӽ˾P+zz.*'Uf.+j'8H| +sy&YU4,TwA6_yx+02`Ui?fx,5@v Cm'St/7쟬~~ =M+P]8D!ӅK') >sQ\lp& +G)*(߶YMs,](^T%5ya.lc+ + +D!a(_=Z=*AN>}VFPp)2KF/8j"j.{Z/WҌD1VC֯,kN.>uCy5t\bPvy~ P#,H$ 401qX_W>ѝxj < +F_hka3im3Xea{t]H"Wt/ + F[evBܜcTt燛{lplp lp@amםak66ylںkO1Q:ZSP0!Yt`7dBa~W߫GQ[F}h~51ׅ?Jpu\.oWȮ{Uv> +$;5~Hrv 7?TT_Pݥ@:GHz_Q2@:X`>-4w,Jg=L)<+RxVS)SL< EDE *X=ClCҷP'K y("TALlut~"5DǠw*z0,h[eK}x'k֮p +xgFԋ() 1)EB>__ 뙁0gʌ* `PK' .e8u۵V(Csf "ǵkϿѵyCV̓taR=H! [Q[sJ"[JK.l"( PX\ E,NkeP 6uΩѹIxG>_^k'Kމ >SRzT"id%(T@)1亀) hNB`BA(~_ѝ<H?'ȫ v FLVRQ&گ0&Qi%p-CKMQ.5Em\-Rә)hNB`B\jRo]i,zps=c\fcUv# _+7S)ʍǗ]QѕK~+7ίFW%ę҈-Q"TJIʂ>@)Lmnၝ2{ri0@X9,?ylB/nT[~r3Sڞ+e jhn5yq#6*/ Uj5NVnl-tk2GZ6lo 4v}Ruh>24oD(zPP]z$`d=:'!dqAelXQ ~YAÊ2~Vcۀ2{&Ai5|~$y54\ APO RaE ~$r2><bגіWC=ծBzZ*A]x)w_S9% +_(eOQEi^t ۗ<" g WPY$,~p]f* Qςg=pm>pN@7&1Ism$j wJ#b>pDW">p$Hat嘒QTV YTկ"hj v{ +(joj߃_S[⸩"?)ڊgHl<h鬚k`ؐ5ުnh,v TAS=6#iqO!ΜLODs)rO!=C4>£w3.}z4*Q {hTD=gF=w_tn R@t Ϫ7` mo7TȮP Gy)*]qW nʑ[[UmAoC{/f!.>O8=P?663s]T?!}Ѻf+7巣T$\x?ߎ`"=LգT); kDqFBYuTImW]"o#V@u~Ok ~]Qe vC0IJ_vXtˮ.J`$R擴Gd hN \tdYJT@i*`"X6W_róF}zZV){BV SiJwDt~kw4neuikjJש*V?Q}hX{.f(㮿 fHQ! es `0B*O( +=}Bu + /*h.P!=9Ep *F(ojptkfh{F-w((&6\F*nlc {Q@b(?Cak_Rj ZJ @@(>)[G + +YH1FNSyԩ}{#nרr۫ gùnK> LW#%HY./[̦L(QjxSr]t&ZȔ+znML@#:,tEyL/WU+{QRܟtAr,QƯkB[3e u*\G5ڙխ(LZD"Mj %)/ MX$H "葷sԼTkgy|1qZOJ^(mQwȩ&ޑJT*Nn t4ŨṘ94x3DCnoCEOAsIS{B-RѾ$NKp 'hY *1@C|R ِGm0b5TbVΟwQNCsH[CVsxF{DaqP5Jb +0XМAs8 VXJC2Din?rGri6{D__ =4gٯ}!a4 =›=YqvTTZx5ݮQZ 3EGsd0%?N!NfPu S^ caK#D/Kػow9nP<ۺ3?vC|V{wch >p٧>Qp)JЮNt wʾ +\yps_P;jZ>{YE4V]v˞Dxg>muY-EPBPAoZU;D햨2='xn +=<81X:3Fz@L!׻)'+tqeQ^= ޅ]}%y#.np.!8zS:K?#a)J~5`݅DPv S}8eb*=J܅EZl9'SO(ݼۥwIm]Lؽ3Ԋt1&'_ RO(2AW(,s"Fµ:*)KN±3"EN8FCJ5JcT_7.YUvQ_W +ir#Ћߨ%[@9@3QଣtH!Q$Ѵ 25tikI4aȢy4!x"f^#j{U?En 267cb\t~r㢲Q?"@#D32t$Un%=(]J0RTעP$,#0]bd: 3$qAEIg%~Qdw;>BU?Ϭ-v̨v 8[>.Bqv;=?eqV~Z\bQ%RK/q%X"¼p]ڃQU57YV٥55Lю)M~ ta *͢!J3 P[Z~z%Y(V HgESYliF% + E;k+6:8Sh_U?sEL=!)g/T]A}Q%]sg/E(%4 I "싢3Rc5ʈQƙt3MV {bIQF#tkq߅kV?b Ѧza[6tۏ(dQq<2F}f*y+#}~$~QXY?xʵȤ_ ?:gC9| ≨#֨#רL}A^eJn1?@_qV, p{[Ћ8#D<1tZ?~ު޽\YUӋ:Zr̰ Vi@ۑЁ諻N+n*)CdңzR8i^dY_t̊Wr዁^vs{G1C{[2FwCZ +;=)p/C|ũBLeiUxNApT#e,)>v6px leC"oU6?T^->Db[ +V(Jv}2Ő3 He2%TqO |%Q b`Xʲ|wM_[Ps UJVI[]2c +]MﯜWixMF~vGAlcjL-ӟjkP/Ai͵klXm@6#Kim*@tD-6BAeP菡=r#58糔DJ[6`NMEO_}b9oeFЃɨ.AoVTbd,?b!Q2rKݷ:%:,o%6@\qaI5.Pkc&AkcցIt%t=00) ȹG4m˾Re ueuem|3 \d(BQ#ݦ4p=|DVsMjFaՌ`VBˡ/3Ef 30Ŵ" bJUQjU%Z5{edU14^_宴*b]&( +>;U(/ÿbPIOD7=D$zIOG!"+ID( Ry-(DU*IJ^^9n҆J/8̠ffJ*8V.y +rol + 0Ha2&XB<)>Qc(;80Hǣ^ h0xgK4 w2z22b/ivD Dq+?`D")]/}Bki9lrٴH7+/ڋZ /Ps __'ֲ11$R'F_șfb~בG(2L=-E"~.^ͽwПe}Bò4CPge:]сi%":LLA8ABkfw;UhD@#+=V(<կXtDIKX՟>sz%qnT+f]lȫ'U^"M_P_VN PGK@fӮP=K"fm32Q{6tkA6\a߮q[:EIS%)h +=PK:PgJonÉBH_yKOitrwY^_udY9;}X4~Pmw@q9,?z傕GOPЍ`=b_VJ!L*W`p!:1y]Ν^L@Kxg+>_Q {!\ɤ0gП%О#xm=, {9^jUa4?u;ktg:T ¾P ߔpP!mc5g(˚ߪqU'To_P> ?k8rk#ꇗ%w+C+yY%貂~Y<>-G/*^KB]G=Fߎ.[a!e4 H-X@@ |D刊˙a+pzFƾI׌n8꧗d姗ˀ2 d27O/+C~<O^f9_9-ޞ>=wt/w~͎3lfڸ]*iRKĶr_>I +sb %&"BGs~!`DI 58QRСma%NuvJTd1^FaU >V܂|y3=P`$f7TI[@vh~LjrPNqMbAbaLAkOޠOԸTD%_og0x:zGuО *JOgF N.ABAAd pR:o.Yf)*jCa.=$ `wR\⑘f4J5 + 0eTq~3?mKv]MxtcJϐ8CwB`8{wb\;4?@ g` ԨTEq~NI$Ǡ7ЍݣH(LE{-%6С^mN rNBpFOǎ4ө-iDwG}*ԅnsOا2)zb-ܞүEb,ό1?~u8 ,][WY͙%+b X) a^-+s5Pvv"Z=`{Gyfa)SB!}U1jtN+W(X)JCbV: U&B:D=s M*ψCd*oS- ЉщS[R/B..9Z Ça?`Ce>6"~ +{4P>d֔CV<|nV#CPȧCTs  2[ӥV PF-gZ|6ڥA<[{J$d0hJ4%rYU1J쓠d;6 փ1,ۥt9.C.,:&C/.@p݌Pəِtb$t zP4|&Q$я↷NsOgHsނ^7*`LU:DRaRnwFu.$^Sw]T%P.ڙLO+OXoKscDrSUNI $3`ɛK{R +U"{:z(l J.j{hIt^?h"j zd9<vr>stream +xIQ/lptfl;y< +ڷYmF*Zx}^JZ\CAwGCChҫsAcAHC9 JnHCBp. _ĩǨs,a'w 8ȼ)NZ?]܄PA$éINNcq7S&ö|%p;=yq|eKmwm4sK;rf1\>妈1r?۸s 5qlډ C8V2c {1,U sCUn(IoQ1mtLFݒ}{@z[4E\—E(1b-﯋7`Tm;vRLm9@9"t>fqk7qz?~~ؓStk$)PSuX`>5?%-5ϑ R/ +w([*,BYBPSόE:WTr?cZF*?^[νgTd)H\bνqLn:QБ4 +k\-PYjly6;TnTe+۪ >4&kA@O-.|J\_sC bI(ȉ\x7vv B}#4' +5ir?Nz:źgvҭm0gF%A,jgӗYb9&brdVA0A< H- pB! ]$ʼ_F@΀: +A[ӅೱˎjsmQZSNx:ɋFaVr6./(۸g^QX>L[>Fax{ow Z9uͨD!kNѫNV'trhC챁n/(EO=v?I{ldQFE˔Ĥu)Jkc3u(vL=4bb](4-̓چC<&'niarEkM*VY@e~J5qǵ%桃-M{:yVhCyT.{ p9hY"h= hAKs_ǀD*l|uuslbTdjgH4jʮnW FbT4QɐF¼|>U":Yt#pK4]3Ͻne=d4PQPPC@uF{#RTU4߀6KaiNh*b뢫D@ԌJ'H`?K\/ڵgPfpHXD[eF1QϱPk]p4G v9e>ASgeIzm%aMQ90ӱ[@t_-F]ڵ R+AUhny/-h'њ6C}6ߞbaigօߤDg}{21s7T;5g_v;=~z~|v!X"+d3d&?$9 ) 1lPY,a^kr=3C;}{UeT~1gEYC'AQNeN|`::Y tt;HƎ{(MvJwJM ^>%[hFE=ld;-d#Glױۂ._fV<#GY,gU-Ѹ>,͏^wbt23A nsyZD!qBZc0dkd̖`U[cTD?XHBu(,iZ(Po +˅ٰ֨*} V21 +-حOvz3I\ j>3̜kC?1 +-n6MPE(+h5Y=h=Xai&VF. +QS2-c7e KCD/#Z1y3"ZڣZ,Fy *Nb'OH "Z&r]%3֗'!ӌΚ1jyx_#m2 +::kCB"e߰b8z`uwL͓>⠥X<T9Ǡ4"~|,x{H?^.v&|o)-erNMM4;4V7ki m焓*͝ g:fz@kη+$ 8 mח) *r5Y?t;ȯ2.dE;H#^K4Fql3̯+4@B-QfZ#TQ\3׃'#n7oY_\尷!@=UqԳGY,QE3C;lLYlzZ(-0*tsJFћgff6kNZH!)5ff|0*{U#叙{&'Rs% N!dh Ee07#/gu'3Q}s<[ϵ07J=kNibpMG  T3* h mހF2SmY}|,f98Ȳ F dJp,VC0d@oe97536Tuk,aY˖cR,ԡJ(YQUQp܄0. Bne_a| y*Jpn68Å8Qw WT҄JR&;jo($ChZ=:fg&;?GNgvnu{+ҙ37*:OK`Q +p;^-\G}yoF;t.=Q0Qaeu0 +VL^9C"3*Ʋ~%[lº0f 2P6j f06jGrgWLlǶ5kʕ{CmGjYfd:Gp@Q^y{!٥ߍ/^T>u9 ޻8(@ ,T7'[])(3nXP999!#xGu!CAPІF%1V,ǣy ^ۣ-BwS?:AڮLgzO' ]D}݄hB{4I`z8wL$a#r%TȒ9 ~X i+:M/ wa'#f34Ȏ0N<;-|s}g= +ڮe 4K( F ң~"5WB lgZ& gLgCGfC=κP@'~v*浈"Z4IVaE/Y |d򩹾0G1z]"՗л譵4 +viVDO"o#YPVCHQjD?Y(^9 Law&K+_Rc<1gc1!//CMB<+dy!lU("&ww8`-Z:Z^3џmO8e1;wR-,ַpsù{%g"G͹\d{#L0g.s sv:NCٳhTU+! XEC+&P}ϣxXݖɈ+Ms^x uu$=81AhmLgg*/mP^@U%^*Y^*GyD㖦yN9 +Go;L`)i@VB!%Z +@^ȡ?C+ˈI*/`b;?9vNs^/{w>:"Iezu6o`bL~C%\+jQDZǐOX,@FC+V_Xe +R[@F;p|Cn`"^#57u4s(@FC̏+myq`o|A dpqZn _ d)7!ưTVŒФ.֮vquڜ %?bzPcl?Ҷj8t*@L 7i1/TAuz4bJb[ھHʋsR*hUEޟw +!,Ee}ڵ϶߭^vt%^ xWj˔J{З8}A+KW;5Wڭ5QH!j%A}:3|!献8OABI~{O z%5V(=bkr\+S +ohm҄3 bq;GqKl˭pWPo,@x0qZ`/}/oq +ZAlkQ0CiUer{!M@ڣCQyxON{ȭnDQJYpK_q*s=hsa]i4t&Za^a0QF؁fnضc65am]{fo5HP ,*O 2t(^Y+ZH]ό~5բ8}A7" +6nI07HnwnV ܿri!!9,,pYA"ss(8s>c s/82=h\9heiRE=W9M%b~\$fC-AeWIWP1+9 t/W{-C +s0'MFǘWZ @c.ZUh==[;-!$Q.,yhGE+"ro(M l@,OU+3wpypie=3 ^EPsh cG"gs@\9g%9n?k3W%xI(ϡU`6Mi^.J62@W:j\W3c!2ri/F vc'{"Ĩ@b ~C n(,5bD(טr6fz_SԜ `r 1'ʅܣ/n vfygD;fW)I$Lᴍ$=YG{zEuhO!+Y^XC5SBd);w$|<7Wg5wF4OPJs#i2-oLckF.e\KD="kBGi1yJOVq-QvF&K֯5ȥZ<~TьX@$16r<(Eoڭh!kk;6F!V8]7ޱٱxiNAUnu238@MEO^9φf"O S. 5vϩĿvuKBnvIh[ Ȧ['%ыI=&ztoHE/%Z K^N:)ǨɄ?\xa uĹn\}P-w '0o?ha%]rռf;[l5̍VL7Zm`pl{(4-`Z Zg54fP~ +iǨ§gcyI+0X6j~F[8)V E7=O>Di&e= ᴇQ(FeUD-9ʬOGe5Q.CPhyCpdq䃚8|fpl'r}~>_CFAÒaPS.yRb,5.J@ (GH #GLP ,d^faT@DʦZ-L&a|s \+07̆+fe'x-΄Aa.ttR1Xʅ JdKCo26l❌"Y +;<u,YuBZ619 jZuV +`J!#:J!:{"$j{$KТحC+!]7())Ŀ~/= iY{ye>(7 j&4'C7J ')5'AAޘ߶Cлwu!O8z2x1 +'B`F}ɲ P~fI[hJc Ph62k.s v+.^\}ᾸhZ:1~h-'eQuhQpf-*r5ԵkV*RС:tnܑo%5;?q %Mp; "mɯ6sM洧J f+ t 7?fj~l|l \.qy9:{%yM ֨K2E#9!~Dӄv>Pvn4hOxQl;\ M/losm}[a `;ĬP֍ں]%\ئ@7ۍ½nupo7 +7mfPJݷ o<(jeEP"Տͫ$9. SS5cW o(3=Qߘ4qr [gv(]8ZJ!b" aԜJ * VuR/d{=Ht mzԋ>C1 +QVxm20p3%W`Ň(1FEô8_`ʹXc6@]r#/6 +ov/ +ph%zKsZA+< dzDAe +A5 vU .sr.9,咋 vNmC wʴҹI-͍6!Mb6L)g-(X&6ҖWL,J,,#f`gy +٥. +?岊d@5,Nbm 9ث3atf&Ҵޟ>-A#=j 2io͸)XZS'Kc]RVEl~dԼ D9b'͉|=V,1,&.%S>R "x<m6i1eFʶء0'HP:s},aZGU\h@'d$I1D #n7:`+QTmBXe"kcdMcM.FJHsa&ʻ5uB]h踛ay%J7DK/܅WՒ;QKB;'Z){E@h={ЇPzأw Ѥ6yKy{vjP> y}V!Vleze{ = +3kF(߭]*s\AFKrG#,v!gYBpڱp(tO򟋕`GA5e ;L<2?pJZ + !z(kZ58ɳ]БQh6Z`VlcQb*Lma]@OΡ̖PKtʄtӘS312*h̅+n%QYp2~=a`UΜRVHpg.?}!//S*y+?^W t:?RIJRr<&Ғb!Ȭ P. f;VR9o”:TP(f.w$:Q"S@xiaXK: D匁 ᥥߍ姖6h"!KV5ɭq^Ss}!HϣܣRRհ+JMdR 3.L"}%Π 9l9fҥ(b>;1zE~r;-rŰ'Hb)ޫ7ZΎpsL${FA~Nʽ+GZfU4QΑf$hf#M=堤uP{Y9:RgZWׯ Z!9/wy/#dJ}1c zI?5+adzuG/8h+~Kt5qTǫGj3uFl!߈ZT!-3Lв;ʷ ;}qmb +*jHa.y|yݙ ]Y;ǎ{zm،jVjh§aeԼOx["gAO)`$-61&S#ジ`sS*WL=Uʸj`?;8vk1&ҹft8zm':AR؁=YqcrAd.UF힎\cL%VA:ޣnz{<6TeB;AШ1P4ѾtPXUe@"NJE֡f$qd*q*%T2$YW_u  G3@EVKˊ+ _'铺e5;4 FVAKƣR`Ac&A):o[#?ۯmHM`V*eMd=zvk"˿nMdk$<lXSyƜ45W` BijB'E;Z|Co(ꃚfZ0j_NI8Rŗ,j!27d(UF2hө@Y:rRe@MtVN Ъ˜j<_Tb bb)ObVK9c~%m,?mT{,q/xC'!!{B*/L4ߣZEF їwbJ*yR,ܱW +KrW g?~e98愮)wzMPt-5$M.@O4mzqPIi2VD_:ǔYD|P;lѺZ:d) Q;l 1Og*Y6DV̲PKk_=tY:,=zJōY*Bvে}f@d\Zda2S+Z t+ޱL-]ﶩkrXΫƱ8PWڱG6!4[6nqmv{ݓ\R6cx:FWZ,]ָ>~ rG w(E5 Z;kE U9qʶ֊=Vwa nvFƚ^ͫ[CpxIN15v0b`W!뷦mrDO +Mdj4/[J1O[S-ʫF*xkKݔGk<_@<37Ueۣ.n@Vz@N\аcݛZE*MZ5.Ĩ/GW!WEEĨAR)c ,ˀ,@qp~Vl;Ұu"JkAUʹsҵC\g"o yP&+<+7%Z ivrҡ +!fyFY9HLz&TH1U7ϩ@ +sur&suwR^f:pн߹|Ǻ$1j nR 1D@KmlQ}բ&<leG7!Mx$ӡ'0!Y2AtLcFAIf, +Kmt١H4ߣF4F% FG'#CHטּwfjIF:ҫ]6#W[TC~Uuȅ3TpvHѢ" +WX. f 䒦 0KO,u;jDpk/GXGTЏWǹ#@ mAv ^7ZUT8U`)Lt 5Ԍ^%.Y+ Pl$INe7Lf&$nJ%zmwӌȁ\,rPէtohB 5[3`%1 +Qݦ^ ZXRƳHhEh5YobC`g՛^dEp2J뽠^ cMU*sz_%M36 +Q4O)i2y8ԃ,('':_݉Y&M7sĢ>WP +EtR>C +\7z?#{s߉ޜ{|/Vl_{KՀOzkq⑰0q+rǕó?쌧G<:4;:󩧭{T{l}%84%=Ǘ\zI^яG[Z)|A}{JoyJ}67lg;g.w+;=ߑhtYTPZO8(ƒQg MݲARd"鼓PVh@sCiE*O/w/-k<m +r7 Ѳ o4 㔽!# QImJi@è_Pʷv!~CsWMHsZvt())LwB6&(?;Xk$&Hq+el!B2::^uREJE<ڝ>*ԩ\AA䁲3*ATl1y̛D߇JD~yRxe3Fo[z݊Ugc;ǭAǶB9'N9+,/5݃fl`V0.D4ؾ {xQba\h>/91;eْXx-D{;/(q݃Ɩae3#3J[Gavr~$bLD"T2*:*'e,kSϪOghn0CP@Y2*z +2dHb̞bo " A.4t0ʊ0 + ʪpw +0^v<ʚ,&Y0u$Z 'R5b OLb:t"MEN,\|iCz0N"CE8y i_#Hh :L2TL~x,3OvQYUY`F$0RoɡP*e4 P$B̓!My&MBjaJ +y"LR5EIf'00I%EGoAsGW:ЏyRhCI':N\)=ԛ+4Yt| Kk/(Gu l`4ut,-Mf !]yFG6 5~Rt̕+S4SN}_ƑϡI]$+ԠYJ$0۞j"ָ2j(퇈U< #I^GFlQ82=&I=eo=j C>'>QƲAI!}yr75q*qzQc)yNQ`錠JLCwg_KI2́C9`(ӖrλU?+J1ZP6DRXγ޹LkgHpVPG?3zUyxџm"{eˎ9b4:q ~g$zۻɊgal:OmVQAe>DC=z6,rCThFU99&gY2*?cmsϋ֯'OtyC-;Ӛ}‹yP˻9{|L7[YGцŏ,'ֺh޴dystmf 5q[&pR/ +w(kQ*B0#@vo:UO w _P= +ƒpo6ïFo-`~1]~hZ|QjW/d( Ϩ~BtbΎHAa>5ɨ(7e&C󦕁C TԲNP7mBIMr)p[Ԣ:nY<\NCcoEu~nx,Fs{[SF1v3,SHaTteseha y"/y< ^1;aN2*r5큂Vq{4hPaʹbTQ]ɐ¼|>U":|L6߬oe,K[iZx③u6eA9a0g=S*?EN\*ު"-{(7l̞h-zJ( w9'ˏ ~C,L~]dHe;Y,|l|7;oyVhC9N#V6hٳAQVn r{Ky{0G9 vyڹfۏ5:f:71'+v3iq#fBg\bƚQ([ю +Y/g!*F0@VT1ɘ58j!A#3ݛ` +yCyP gJ枠#XPeUђ(}.k2beKF2 {S$G] VnT$RJw£TA\ aކ.``! vPyt:4^#:X8|eb@0u\d7=QdvPA)e[͔^2DkSaH}<+5})๟7ڣێl0#w1*--k6g2glYkr+CWF/ɨäОS9 Py)%OU!TuCv!9|,8ƛQ1 ": A\Hf~BzejOurD1kg1׻9]{(lglj4ozLmnZRLm@e!glqӌ-C0 gf +Q ]?n2]S6!(`Feqa[ `̜n_HoHPѹ':g=su>\k1)J ]tHRڍblC!1MՌZ/,ַs"f ح][$!~!M!.n+c tne6]qV&CX g&Y{?Q)ʪi%M΂ ?9M'8œhpWJpt@Pe@Y1*j2lXa\ A.c!P3 ڜrA E0`ad'*m6 (~ZU&V:2_y%%0 _P/ y$0hJZ +),)*!`E[(:thSLSkѡJ&:t!ux;Ʋ dCm!jH׃m"~Ez|ND(umɵKWK5?$~;4y5ߓ׃Zw+do. *n"ئ F;"]syqF:/DM@FLL9"sr_JO]YqBm췛ٙt(=Q 5Lo( =Pce͏Y2C6ȋ  Pn$~(0ccOn96LN+i@Wf-m.s2ad!̗˪P¡J.滵׺.ޥzCE|7QfC͜5G|4 w=wkswsyiPg͡滹9r}7דnF3ܣ仭|~X'` z} Ԃ֕ߣ!ڄt%G{Դk|hK2|henHɍz5Hj2u贠Z+ mϠ90Nrm6UqȔ/x:+u>@?-iO#CЏ޶'c?Qإ_co;BK@^ qإKx'[XbT~_P[5U}U@E] /j̷UҪO^kLyTTA Ws'̘0ς3 c#E^04igH! F +8.ׁHNHE{lqޥ_B2얀`GSS`k(|_fX1e9GW ϊtHZ((KzأبElߣbf۷Գv +㜳!oBq" 5'3#Km>Ҋŏ=mBG " +;"ԳEHzNnq\d3*OW=[OYx+$o2g1 f1P}/>io%Di]6&5"1 +,.J@>UvTu @Oe>8P| ¿gy40-Lc#MkC8!VY:6*I4W bj6v#Jv=C-kyʥ^˗(i*vᚢQ + mt-HuJg2 +)c6 WT4+~fGՋko(#C=5qdF33ㄔڝ? 'spF'ZϬti5[l(PP{ءLl1={8M +(όc;`Tx #/`L9j SjT܍esǝȅq2n2 eƨ, v:DF:n  fk"7AYb3g $  ,_i9\~7x @rC-II`IСCQWWU淧6/c2Y杳l6wҫu<ޭZdpE[=өgzrV1\)4A&:?Qђ,'Ms~``%@~ /pRLFt~`҇I&?!@dT\4p8?Z,^O8E@f7\>"dTߣ~ OJ@l ;ao:4nVl'}jۣױuRR`uLlO3 fQޒaZ^s Ɨg˴fhlW/b#cq [E;ss"YnA2 mMEa|~Ʒj:^v#[+(o4g| kF.LmumǠSuEk `yhrjiߪwZ`SbwƷe \ia,6LBDWlpXء(SA\G/(qd +NV-y CBFQ"YLgM!1,vȽC2\āQT"S^0RPւ *(A3:5V":XC@>*;`+(v} j&# @bJI);TN]~OEH6k9iW7>JiY5tiY8tlAkҟ]<hq5Apj=jA.) X\urXֈ9bqvXuD$]DMZDy/"j^A8na7GJq7h\HJkF4MkD<ѸUgAo2 QS_« r$7s3C b>-VBg΂O)y?AlBۄG$+5yf֜gFA9LDAYUuP]2)Qi2' zeT-ѮG:d.ޭXi=/7{-7Fe%\޼C1,ڝre+޲AE6uƨk<^n l-K_v|z-ɑ*oCmFŔnӹ $';*Zҫ3I眰}k~ip8L*Rc鿄:ܦR{oy;@nW^ +]--KjA*잖{Z0I݁2-9Y),faDbsV;xZq/sSY%զ~{zwbσ)E?"RI|V;vˉn#g"40h0Ss_WoDAs82#Guvs{\l5W@\J#tG& 6qzC,bBq a,Wp}<-fг?uíפCgI,--ph>hS$}#"lybc.t {%$~^YCBH@-Ol>8 EB"J3@=6F`ls1r! +I<$P ɫ;;=$/" !yB=$OCO%$LۈzF_om~ƲGE*CV6o`2?EPqYGD^ym*^n">?d;hAC'"}.zMYPh +1dqcBC<ÖhqrNgR"\\4Pĩ@ Z Dq%ŹP 7 - 炄 }#{yێYH!{rTe#—pE/h q/!% )` mZ(|9)}龮K JЎC=@AFF.R=5pwZ@at?~A1CX|Vw Vw +4_Vw#0[eMCP-Ж #ΆS+6zJmTq'*6Fz^e)=+ Sʭ)R: +j}r#qTÊe@DC j6~m}y'=vc TwzVTwzk?H{u&!;IG1~$΄JٺO U +E,`|K* |~M;v|o ®1 ʍ~3QjB%B}syЂcQ2<.)%D7fxBf68F+kez\B^ddv؎ax%(v3"smI4`}()_a*={)~D9w?k%R1!Q2vyY!"fIЭM|ELeIIE/bVp@O<@\y${<5+.+P[H@se@@Y~Y* +Uqu1ca\SęWlMUA(~Hf'f;3zfX>NC o鍜^iqLS;nvKfY"?Dcƿ;~9aN[+Yz"RnMkr0a.JKIeR@襴Մk%-VȚ7PH^VϳG[y ?=;|Nh?8/4IVPA2׫PV~Dۀ\T@u POBկDqtM0r+緢o,` -8MKRHia4MalQ+gRh׼9 ͦs;)?myR+} wvK Ĭ<6<ΆKa (=.]fY<:D[TXF?=FԴRoi ״,w9>[OhXIl\{BY9Q)3ݦi?JsC;Ç)) LIJ9%)))# SRݱ|icSR.-ÌOG>R'wp`pd';)i,{x.@Bz. +\r6z,\X7ӛ9^/ ^ x1 +K$?ƌW`lq,_kӅ%0ٶ4-RjxPRBm[lb˾SZ@-}%im$=]2LB/գ=,~ա)R w_4ed5/o4U~U.Hq;${p&za-үQ `]ͳ#^QK+cw8;ʕsog Jbz!U:5VV +æ4Tg1,vvXM; +9ռ7U@\Z7n7.̿oǴHnj1ϒdSO M?f qJ-SJxx֔C&.uc|cA>ܡ٬SVA3PO[Bx7N齣bݷ~ߎe93gϙP͑}g3jUL7<;#`P;r@~JFo|WZykF69t+o&"Tn?=edA:gA󀬓MF.S +%b֌iUaڃRoY?G!s)pѕ}s3=]`o!V[NGU,AS@{L}GXk߼Ru+Ar-;նz+|iAc%h@L\"q؄wE}8;QL:7brK_ü$̖# >n~DuW⽚iR4>՗rD#2ω0 sbZ}2P̉So9k4/&Ӎ~.ʴoG԰^=r3EMaNBxu?@Z5^[Z%h"?@$Kԧi`wޖ/.;d{L]'(BEqw[F4}lT\G@nqXBx0*'u-~-[]muސh–֑$(tb]am`jJq[ZŕBǸRZQ)ҡ+ku}y]}bؗzY'I I$*G.HW:4vk%xi"#ؿy& Fu/)`TdVݎDj=t;a5n!#Wζ]1#"7Yh7K\2ͬՃmmCN)rQqNSFdv%GMRM2+%& +]%Ғq0}7Q:Lv2a7-N;Lŷ%+𒀠rRqn9BrոrNWnS3u>V +P?/Vb7"'=ǵ%A@rRZSNkʩkY\ղ6 ̵&it)?cQCXRʙ6P@.y|q( +=/~D1G1Ox "hZq/hkX@w4ZL}@9!xE?3F2h&OMS$dFnR0#LI0),Bq4(U֟REB) +fPK̠uрocОPuZSZJHBB JQt4,v c0zCAq!zYh5%b~~͉A7 vXոfS-{"3%㌯KA*e/A6v0?QgC%S;>e.@<:e:[S.r}K{#e$8#4U猪iI/MyVYa]:pf/l FO1U}7a(e^5=%,>{cl`,  d^-dڕ~GRw$K8.ƃA9T9!>DGN-_H{h'@YNpB{ml\7vAXJ9! +3 +kkOx LHS; )L#k5t-PlGL&Ҽb"yD~Y4$W[5nC&ˬuI ;7F xRM ? ,D[(FSu)iY]6ԥ2'LaB%T4a-B[>0HWWF./=dX^ߠuρR-u9IWsbֽ4u.$n2&1y/ +l=sXo^)l;eiX/AͮQ tj k} iY.I+u0:Ucx ,J9ڕ>_`,*~ fwE)]JW8qb} :b;Jրw’RRJå HTrƋ!ڔ;]& +Th 6){~gDO)=E Ho}UBo}YEŽ>xr-$r/,2ceSJ+\K&k#W|ϺFT۲4tؾm \;e-hXEcF?Y Wʽw%XG?"җVgeޡ~.?BUWh߭Ӄu==T˩~9>M-+̪NkHydԼ}gB~G_@p6j7I=Ip#ve-/_HcvRO 3l^z3BQAwlm+ |Nak }%4g"y/s!ٝ{ zEcO +C5CJ~rE/{k[Dte6 +i;1͒D ymNM;l%} fʤ*JCFUsZؐQ; 㐖n{pՖxIh4۾yDܽqA`H턏>*x[Y_wrVtTD^¦g:wC滯0zunĒK&?7$˩Q3=I}5gH.F~,j qA<> +YIjqY;pPũuִMSc);Z-Sc5w50ktE(ힺd ~5яʏF?ڠ EaA9xV>_Z7xQeLLu +rO묣TKxMHAZšr/}~Q$=Rd2[Wt/5i~@v;ƭ +O}Knz%PW~F썧ULzMhۑjJ`튈ZFDxo4ޡW:`k-Y(i6 T +!ͺ.bݚY~x +$_%azAyz bR%QƩeCY'QؤM #.$ђhޙY,d&X[[@wbSoMӵ^NQ1n=KƖ42{SzX켘bޖ٨%v(SAn)-+ѺЖzS4_!ҳH}wIn+|x#Z|ZiX.l[U ;4T5m|J}#o%:&])a}j/(2wT%%)텇b77G{h`1l@gqvJV7(-;:!, +GŐ_Ni<蛘5 =ㅤ7ْpt/vR~ ml`R(~ .}3 lbMH7Kw=V̉Y)&a[zIG([UQ9wy-; +ow}70#fWPl~72L<=Iig%WTD6yX. +5\j(~՚k5c k +'G(GSy'J15#YTKP3Sp,aMejIWr.`̈́; }fh9WB4KCeQٯl>3D3s moacdFEym4b4x a +a"F[3xBMyxmo pQ!V[}h5Z(Vاab`  +[0TnMa!LDz`G  8ZvR-?K⌭%`kJmbeW~0<7ee bt6PԼ.enu*{v! q{* BUOXIzj| x5_[d,SA!N8*ĽQjB;o=zԓP-V q^LȹYr2\KV3@G8l7)y0eH|3Q7}G˂&dt6e# yʍӻǟ}Gmo5|]_mk8/C%/w^+"JSze̬X7@<.!0p6 +󪐋|LQ\L. sH!-f@8. OqԣQ3YyHwƩ}x4NހKAKC)]v|'OP79N0Y9%HJQ#k|J<@UP6tRGŝ w]V'Fŝg jAj[½y`6IZg~5!PJ,Msd~M5=T+eحakA\* +T\N.$jrIOGp#b(e>ҸJaV{!Q)&ȆN5@~׬D{*.2#Zy4 @[ؗ /hIYTt0&}:$Uv[#imh?IK4x|/=q5 Bw>`<1J~ uyc@wHbCR,);xXKq mq&_B=:sb}YBzc 8. i\Q6SQS#> E\1^c/ Ř-!"j7  'BH&.uBzS"x&6CG I4xi]>5W=M!Aoׂh *ݧ[SZSK^d+b'ŎĎ+j]uˎ3mx|/1P>";@M$ +͠9 1)/Type/OCG/Usage 16 0 R>> endobj 15 0 obj [/View/Design] endobj 16 0 obj <>>> endobj 28 0 obj [27 0 R] endobj 66 0 obj <> endobj xref +0 67 +0000000004 65535 f +0000000016 00000 n +0000000159 00000 n +0000053053 00000 n +0000000000 00000 f +0000437463 00000 n +0000000000 00000 f +0000053104 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000437540 00000 n +0000437571 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000124910 00000 n +0000437656 00000 n +0000053607 00000 n +0000114870 00000 n +0000125329 00000 n +0000123838 00000 n +0000123181 00000 n +0000118550 00000 n +0000119318 00000 n +0000125104 00000 n +0000125216 00000 n +0000115973 00000 n +0000116883 00000 n +0000117370 00000 n +0000117772 00000 n +0000118138 00000 n +0000114932 00000 n +0000437428 00000 n +0000115411 00000 n +0000115459 00000 n +0000123881 00000 n +0000123224 00000 n +0000122593 00000 n +0000122057 00000 n +0000118593 00000 n +0000119353 00000 n +0000119408 00000 n +0000123776 00000 n +0000124845 00000 n +0000124988 00000 n +0000125019 00000 n +0000125403 00000 n +0000125665 00000 n +0000126751 00000 n +0000138231 00000 n +0000203820 00000 n +0000269409 00000 n +0000334998 00000 n +0000400587 00000 n +0000437681 00000 n +trailer +<<0A543FA23F3478469BE2937957F107A4>]>> +startxref +437872 +%%EOF diff --git a/distr/design/rsm.png b/distr/design/rsm.png new file mode 100644 index 0000000..b9f016b Binary files /dev/null and b/distr/design/rsm.png differ diff --git a/distr/design/trs.ai b/distr/design/trs.ai new file mode 100644 index 0000000..9d8859b --- /dev/null +++ b/distr/design/trs.ai @@ -0,0 +1,1779 @@ +%PDF-1.5 % +1 0 obj <>/OCGs[5 0 R 26 0 R 46 0 R 66 0 R 86 0 R 106 0 R 126 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + application/pdf + + + Печать + + + + + 2019-04-30T15:01:43+03:00 + 2019-04-30T15:01:43+03:00 + 2019-04-25T13:28:27+03:00 + Adobe Illustrator CS6 (Windows) + + + + 256 + 256 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq+Yv+c39Y1O2 0zyppkFw8VjfvfSXkCMQsrW4txFzp1C+q22KvCPK35Cfmx5q0K117QdC+uaTec/q1z9as4uXpSNE /wAEsyOKOjDdcVTX/oVz89v+pZ/6ftP/AOyjFXf9Cufnt/1LP/T9p/8A2UYq7/oVz89v+pZ/6ftP /wCyjFXf9Cufnt/1LP8A0/af/wBlGKu/6Fc/Pb/qWf8Ap+0//soxV3/Qrn57f9Sz/wBP2n/9lGKu /wChXPz2/wCpZ/6ftP8A+yjFXf8AQrn57f8AUs/9P2n/APZRirv+hXPz2/6ln/p+0/8A7KMVd/0K 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 uxV2KuxV2Kv/2Q== + + + + + + uuid:5e4a5887-4bf9-4149-8cf9-3b0bce5a9ed4 + xmp.did:2D16266CAD66E9119321B2441BD85ACE + uuid:5D20892493BFDB11914A8590D31508C8 + proof:pdf + + uuid:ed609a61-4e0b-e047-bd4d-722efb68a6ed + xmp.did:0980117407206811822A897E387FE54C + uuid:5D20892493BFDB11914A8590D31508C8 + proof:pdf + + + + + saved + xmp.iid:2D16266CAD66E9119321B2441BD85ACE + 2019-04-25T13:28:27+03:00 + Adobe Illustrator CS6 (Windows) + / + + + + + + Document + Print + + + False + False + 1 + + 256.000000 + 256.000000 + Pixels + + + + Cyan + Magenta + Yellow + Black + + + + + + Группа образцов по умолчанию + 0 + + + + Белый + RGB + PROCESS + 255 + 255 + 255 + + + Черный + RGB + PROCESS + 29 + 29 + 27 + + + CMYK красный + RGB + PROCESS + 227 + 6 + 19 + + + CMYK желтый + RGB + PROCESS + 255 + 237 + 0 + + + CMYK зеленый + RGB + PROCESS + 0 + 150 + 64 + + + CMYK голубой + RGB + PROCESS + 0 + 159 + 227 + + + CMYK синий + RGB + PROCESS + 49 + 39 + 131 + + + CMYK пурпурный + RGB + PROCESS + 230 + 0 + 126 + + + C=15 M=100 Y=90 K=10 + RGB + PROCESS + 190 + 22 + 34 + + + C=0 M=90 Y=85 K=0 + RGB + PROCESS + 230 + 51 + 42 + + + C=0 M=80 Y=95 K=0 + RGB + PROCESS + 233 + 78 + 27 + + + C=0 M=50 Y=100 K=0 + RGB + PROCESS + 243 + 146 + 0 + + + C=0 M=35 Y=85 K=0 + RGB + PROCESS + 249 + 178 + 51 + + + C=5 M=0 Y=90 K=0 + RGB + PROCESS + 252 + 234 + 16 + + + C=20 M=0 Y=100 K=0 + RGB + PROCESS + 222 + 220 + 0 + + + C=50 M=0 Y=100 K=0 + RGB + PROCESS + 149 + 193 + 31 + + + C=75 M=0 Y=100 K=0 + RGB + PROCESS + 58 + 170 + 53 + + + C=85 M=10 Y=100 K=10 + RGB + PROCESS + 0 + 141 + 54 + + + C=90 M=30 Y=95 K=30 + RGB + PROCESS + 0 + 102 + 51 + + + C=75 M=0 Y=75 K=0 + RGB + PROCESS + 47 + 172 + 102 + + + C=80 M=10 Y=45 K=0 + RGB + PROCESS + 0 + 161 + 154 + + + C=70 M=15 Y=0 K=0 + RGB + PROCESS + 54 + 169 + 225 + + + C=85 M=50 Y=0 K=0 + RGB + PROCESS + 29 + 113 + 184 + + + C=100 M=95 Y=5 K=0 + RGB + PROCESS + 45 + 46 + 131 + + + C=100 M=100 Y=25 K=25 + RGB + PROCESS + 41 + 35 + 92 + + + C=75 M=100 Y=0 K=0 + RGB + PROCESS + 102 + 36 + 131 + + + C=50 M=100 Y=0 K=0 + RGB + PROCESS + 149 + 27 + 129 + + + C=35 M=100 Y=35 K=10 + RGB + PROCESS + 163 + 25 + 91 + + + C=10 M=100 Y=50 K=0 + RGB + PROCESS + 214 + 11 + 82 + + + C=0 M=95 Y=20 K=0 + RGB + PROCESS + 231 + 29 + 115 + + + C=25 M=25 Y=40 K=0 + RGB + PROCESS + 203 + 187 + 160 + + + C=40 M=45 Y=50 K=5 + RGB + PROCESS + 164 + 138 + 123 + + + C=50 M=50 Y=60 K=25 + RGB + PROCESS + 123 + 106 + 88 + + + C=55 M=60 Y=65 K=40 + RGB + PROCESS + 99 + 78 + 66 + + + C=25 M=40 Y=65 K=0 + RGB + PROCESS + 202 + 158 + 103 + + + C=30 M=50 Y=75 K=10 + RGB + PROCESS + 177 + 127 + 74 + + + C=35 M=60 Y=80 K=25 + RGB + PROCESS + 147 + 96 + 55 + + + C=40 M=65 Y=90 K=35 + RGB + PROCESS + 125 + 78 + 36 + + + C=40 M=70 Y=100 K=50 + RGB + PROCESS + 104 + 60 + 17 + + + C=70 M=50 Y=80 K=70 + RGB + PROCESS + 67 + 41 + 24 + + + + + + Оттенки серого + 1 + + + + C=0 M=0 Y=0 K=100 + RGB + PROCESS + 29 + 29 + 27 + + + C=0 M=0 Y=0 K=90 + RGB + PROCESS + 60 + 60 + 59 + + + C=0 M=0 Y=0 K=80 + RGB + PROCESS + 87 + 87 + 86 + + + C=0 M=0 Y=0 K=70 + RGB + PROCESS + 112 + 111 + 111 + + + C=0 M=0 Y=0 K=60 + RGB + PROCESS + 135 + 135 + 135 + + + C=0 M=0 Y=0 K=50 + RGB + PROCESS + 157 + 157 + 156 + + + C=0 M=0 Y=0 K=40 + RGB + PROCESS + 178 + 178 + 178 + + + C=0 M=0 Y=0 K=30 + RGB + PROCESS + 198 + 198 + 198 + + + C=0 M=0 Y=0 K=20 + RGB + PROCESS + 218 + 218 + 218 + + + C=0 M=0 Y=0 K=10 + RGB + PROCESS + 237 + 237 + 237 + + + C=0 M=0 Y=0 K=5 + RGB + PROCESS + 246 + 246 + 246 + + + + + + Яркость + 1 + + + + C=0 M=100 Y=100 K=0 + RGB + PROCESS + 227 + 6 + 19 + + + C=0 M=75 Y=100 K=0 + RGB + PROCESS + 234 + 91 + 12 + + + C=0 M=10 Y=95 K=0 + RGB + PROCESS + 255 + 222 + 0 + + + C=85 M=10 Y=100 K=0 + RGB + PROCESS + 0 + 152 + 58 + + + C=100 M=90 Y=0 K=0 + RGB + PROCESS + 39 + 52 + 139 + + + C=60 M=90 Y=0 K=0 + RGB + PROCESS + 130 + 54 + 140 + + + + + + + + + Adobe PDF library 10.01 + + + + + + + + + + + + + + + + + + + + + + + + + +endstream endobj 3 0 obj <> endobj 7 0 obj <>/Resources<>/ExtGState<>/Properties<>>>/Thumb 132 0 R/TrimBox[0.0 0.0 256.0 256.0]/Type/Page>> endobj 128 0 obj <>stream +HWn7 }߯sImQ @Z~m CJ3ٙd'h`{GԎx=<~7r?xq#g㞟>~֟ϧ KEI3drXK+7Rn>Iԍ|w?^ޞ>bgoCh&ɹ/{;4zOoOG>Psh ^bd"G33SYzc﫶$u"\VgwSkq)N/#WWc#v2BK:q$hͺ4rp Jv%{ iipYr򌒝/8d0Rtg8C_*Qf_S19 i@%Ip\Em3`eX >"z(DY64jB^>ʆHztoXi <Ɍn5 Y ghRL-ZR +Ѭ#H3^˕$@Q[zP +mɏR_8P7N3.H,t#ln|(;AP{ #7s"U:Db* }e.AVPtk37sP'ҁ}pr0Uӽ6GX􅏂_v޿zDF+$9B "N%:%pSʃoS='|%~v`}4A۪KA+,C-H}e%mRTe[dl\aNtR5(FXzAetpI/>8[oEFPQ +qB~h ̝ӍO+a [iЁ_.b2xhy[܎=;fMz_ ;nGkFN7> ˄kBG^=uu=cR3D :TԻLtoaO:T`3*md )aDpO&K `r}Ao`T+}E4^>ˉLD e&4)U1Iǩp!zбD7;tjjA|E1Ŋ$6 j6yMj>Sx6aStPkS|Q4:knb)pB'%7!]tY1{"xSFFc.IsiP[ X {8l-uU\tx|Y.s3 +?8X5m*P\a~3%ss:*cByuN=Լv/IcQzsqx'G +endstream endobj 132 0 obj <>stream +8;VFe_%D;R%.ab;a;hj_4''H/%-(D+c0J>K;M^NEY%OsgaXX9idT:-7FQOgR4r*U( +o0496f8GtCmW"5AFp5:kj-@lGc),[)kJh"L?!$sV^,Yqpq.#=->).^M;qjD(dhdC\ +HX-EVrU&5#nNODlF7aMa21OB\QL+)mCp+0mP/ZbUJO7o6/2r^HUH`Vma'Zi +:Ek1JgUMOeK*r3dP+/7\?pX7b\;3*Wf[0-b"!hE]q[6p?q##hMp+I@WL5*j4^YRKb +nr*6D?ZZ4W54SIH&%K<&rl4=F4Q?U*F7;p@GiEVNik*Ynj)4MfcURj;!1QMb>l~> +endstream endobj 133 0 obj [/Indexed/DeviceRGB 255 134 0 R] endobj 134 0 obj <>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> +endstream endobj 126 0 obj <9 1)/Type/OCG/Usage 136 0 R>> endobj 135 0 obj [/View/Design] endobj 136 0 obj <>>> endobj 131 0 obj <> endobj 130 0 obj [/ICCBased 137 0 R] endobj 137 0 obj <>stream +HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  + 2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 +V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= +x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- +ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 +N')].uJr + wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 +n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! +zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km +endstream endobj 129 0 obj <> endobj 138 0 obj <> endobj 139 0 obj <>stream +%!PS-Adobe-3.0 +%%Creator: Adobe Illustrator(R) 16.0 +%%AI8_CreatorVersion: 16.0.0 +%%For: (\715\750\752\750\762\750\755 \700\753\745\752\761\745\751) () +%%Title: (ТРС.ai) +%%CreationDate: 4/30/2019 3:01 PM +%%Canvassize: 16383 +%%BoundingBox: 0 -257 257 0 +%%HiResBoundingBox: 0.583008 -256.9365 256.583 0 +%%DocumentProcessColors: Cyan Magenta Yellow Black +%AI5_FileFormat 12.0 +%AI12_BuildNumber: 682 +%AI3_ColorUsage: Color +%AI7_ImageSettings: 0 +%%RGBProcessColor: 0 0 0 ([Совмещение]) +%AI3_Cropmarks: 0 -256 256 0 +%AI3_TemplateBox: 128.5 -128.5 128.5 -128.5 +%AI3_TileBox: -163.6602 -542.96 419.6602 286.96 +%AI3_DocumentPreview: None +%AI5_ArtSize: 14400 14400 +%AI5_RulerUnits: 6 +%AI9_ColorModel: 1 +%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 +%AI5_TargetResolution: 800 +%AI5_NumLayers: 1 +%AI9_OpenToView: -389 163 2 2502 1274 18 0 0 9 117 0 0 0 1 1 0 1 1 0 1 +%AI5_OpenViewLayers: 7 +%%PageOrigin:-178 -524 +%AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 +%AI9_Flatten: 1 +%AI12_CMSettings: 00.MS +%%EndComments + +endstream endobj 140 0 obj <>stream +%%BoundingBox: 0 -257 257 0 +%%HiResBoundingBox: 0.583008 -256.9365 256.583 0 +%AI7_Thumbnail: 128 128 8 +%%BeginData: 13337 Hex Bytes +%0000330000660000990000CC0033000033330033660033990033CC0033FF +%0066000066330066660066990066CC0066FF009900009933009966009999 +%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 +%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 +%3333663333993333CC3333FF3366003366333366663366993366CC3366FF +%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 +%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 +%6600666600996600CC6600FF6633006633336633666633996633CC6633FF +%6666006666336666666666996666CC6666FF669900669933669966669999 +%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 +%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF +%9933009933339933669933999933CC9933FF996600996633996666996699 +%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 +%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF +%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 +%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 +%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF +%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC +%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 +%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 +%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 +%000011111111220000002200000022222222440000004400000044444444 +%550000005500000055555555770000007700000077777777880000008800 +%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB +%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF +%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF +%524C45FD0EFF7DFD60F852FD1EFFFD62F8A8FD1CFFA827F8F8F827F827F8 +%27F827F827F827F827F827F827F827F827F827F827F827F827F827F827F8 +%27F827F827F827F827F827F827F827F827F827F827F827F827F827F827F8 +%27F827F827F827F827F827F827F827F827F827F827F827F827F827F8F8F8 +%A8FD1DFFF8F8F8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF +%A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF +%A8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FFA8FF +%A8FFA8FFA8FFA8FFA827F8F8A8FD1DFF27F827FD5CFF27F8F8FD1EFFF8F8 +%F8FD5CFF27F8F8A8FD1DFF27F827FD5CFF27F8F8FD1EFFF8F8F8FD07FFA8 +%58345833583458335834583358345834FD2BFFA883345833583458335834 +%58335858AEFD08FFA827F8F8A8FD1DFF27F827FD07FFAE33333334333433 +%343334333433342D34AEFD2AFF830B3433343334333433343334333333FD +%09FF27F8F8FD1EFFF8F8F8FD07FFA8332D332D3433332D3433332D343333 +%2DFD2BFF2D3333332D3433332D3433332D342D3383FD08FF27F8F8A8FD1D +%FF27F827FD07FFAE0B3333332D343334333433332D343333A8FD29FFAE34 +%333433342D332D330B333334333433A8FD08FF27F8F8A8FD1DFFF8F8F8FD +%07FFA858585F585833332D330BFD0658FD2BFF2D332D332D837D8383837D +%582D332D3383FD08FF27F8F8A8FD1DFF27F827FD0DFF833334333383FD2F +%FFAE3433583334FD06FF5833335833A8FD08FF27F8F8FD1EFFF8F8F8FD0D +%FF583333330B83FD30FF33332D3433AEFD05FF5F2D332D3383FD08FF27F8 +%F8A8FD1DFF27F827FD0DFF832D34333383FD2FFFA85833343358AEFD05FF +%583433342DAEFD08FF27F8F8FD1EFFF8F8F8FD0DFF58332D340B83FD2FFF +%AE2D332D332DFD06FF580B342D3383FD07FFA827F8F8A8FD1DFF27F827FD +%0DFF832D58333383FD2FFFA85833343358AEFD05FF583333340BAEFD08FF +%27F8F8FD1EFFF8F8F8FD0DFF59332D340B83FD11FFAE3458345834583458 +%34583458345858AEFD0DFFAE2D3433332DAEFD05FF833358345883FD08FF +%27F8F8A8FD1DFF27F827FD0DFF833334333383FD11FFA83333332D343333 +%2D3433332D34333333FD0EFF342D34333433AFFD12FF27F8F8A8FD1DFFF8 +%F8F8FD0DFF58332D330B83FD11FFA82D332D332D342D332D342D332D342D +%3383FD0DFF58332D342D332DAEFD11FF27F8F8A8FD1DFF27F827FD0DFF83 +%3334333383FD11FFA8343334335833332D343333335833342DAEFD0EFF33 +%343334333433AEFD10FF27F8F8FD1EFFF8F8F8FD0DFF583333330B83FD11 +%FFA82D3433332D835983588359582D342D3383FD0EFFAFFD04332D332DA8 +%FD0FFF27F8F8A8FD1DFF27F827FD0DFF832D34333383FD11FFA834333433 +%58FD06FF5833333433A8FD10FF34333334333433A8FD0EFF27F8F8FD1EFF +%F8F8F8FD0DFF58332D340B83FD11FFAE2D332D3333FD06FF5F0B332D3383 +%FD11FF33332D332D330B83FD0CFFA827F8F8A8FD1DFF27F827FD0DFF832D +%58333383FD11FFA83433583358FD06FF5833335833A8FD12FF5833335833 +%342D84FD0CFF27F8F8FD1EFFF8F8F8FD0DFF59332D340B83FD11FFAE2D33 +%2D3333FD06FF5F2D332D3383FD13FF58332D3433330B83FD0BFF27F8F8A8 +%FD1DFF27F827FD0DFF833334333383FD11FFA83433342D58FD06FF583433 +%342DAEFD14FF5833333433342D83FD0AFF27F8F8A8FD1DFFF8F8F8FD0DFF +%58332D330B83FD11FFA82D332D332DFD06FF580B342D3383FD15FF58332D +%342D330A83FD09FF27F8F8A8FD1DFF27F827FD0DFF833334333383FD11FF +%A83433343358FD06FF583433342DAEFD16FF59343334333433FD09FF27F8 +%F8FD1EFFF8F8F8FD0DFF583333330B83FD11FFA82D34333333FD06FF580B +%342D3383FD0DFFA8AEA8FFA8FD05FF59332D332D3383FD08FF27F8F8A8FD +%1DFF27F827FD0DFF832D34333383FD11FFA83433343358FD06FF58333334 +%33A8FD0CFFA85833343358AEFD05FF583433342DAEFD08FF27F8F8FD1EFF +%F8F8F8FD0DFF58332D340B83FD11FFAE2D332D3333FD06FF5F0B332D3383 +%FD0CFFAE2D332D332DFD06FF580B342D3383FD07FFA827F8F8A8FD1DFF27 +%F827FD0DFF832D58333383FD11FFA83433583358FF845883588334343358 +%33A8FD0CFFA85833343358AEFD05FF583433342DAEFD08FF27F8F8FD1EFF +%F8F8F8FD0DFF59332D340B83FD11FFAE2D332D3333FF58332D330B343333 +%2D3383FD0CFFAE2D3433332DFD06FF580B342D3383FD08FF27F8F8A8FD1D +%FF27F827FD0DFF833334333383FD11FFA83433342D58FF5F2D3433343334 +%333333FD0DFFAE3433343334A8FD05FF5833333433A8FD08FF27F8F8A8FD +%1DFFF8F8F8FD0DFF58332D330B83FD11FFA82D332D332DFF58332D342D34 +%585F59AEFD0EFF2D332D332DFD06FF5F0B332D3383FD08FF27F8F8A8FD1D +%FF27F827FD0DFF833334333383FD11FFA83433343358FFAE2D58333434FD +%11FFAE343358333483FFA8AEA8AF5834335833A8FD08FF27F8F8FD1EFFF8 +%F8F8FD0DFF583333330B83FD11FFA82D34333333FFFF342D342D3383FD11 +%FF33332D3433332D332D332D3433332D3383FD08FF27F8F8A8FD1DFF27F8 +%27FD0DFF832D34333383FD11FFA83433343358FFFF83333334335FFD10FF +%AE5833343334333433343334333433342DAEFD08FF27F8F8FD1EFFF8F8F8 +%FD0DFF58332D330B83FD11FFAE2D332D3333FFFFAE2D332D332DFD11FF33 +%332D332D332D332D332D332D332D33A8FD07FFA827F8F8A8FD1DFF27F827 +%FD0DFF832D58333383FD11FFA83433583358FFFFFF583358333383FD11FF +%583433583334335833343358335883FD09FF27F8F8FD1EFFF8F8F8FD0DFF +%AEAEA8FFA8FD12FFAE2D332D3333FFFFFF7D332D342D58FD12FFA8AEA8FF +%A8AEA8FFA8AEA8FFAEFD0AFF27F8F8A8FD1DFF27F827FD24FFA83433342D +%58FD04FF3334333433AFFD28FF27F8F8A8FD1DFFF8F8F8FD24FFA82D332D +%332DFD04FF582D332D337DFD28FF27F8F8A8FD1DFF27F827FD24FFA83433 +%343358FD04FF833333583358FD28FF27F8F8FD1EFFF8F8F8FD24FFA82D34 +%333333FD05FF33332D342DA8FD27FF27F8F8A8FD1DFF27F827FD24FFA834 +%33343358FD05FF5F333433335FFD27FF27F8F8FD1EFFF8F8F8FD0BFF5A37 +%143636AFFD13FFAE2D332D3333FD05FF83332D330B34A8FD15FF9A939293 +%93CAFD0AFFA827F8F8A8FD1DFF27F827FD0AFF36150E150E151485FD12FF +%A83433583358FD06FF3334335833AEFD14FF938C8C928C8C8CC3FD0AFF27 +%F8F8FD1EFFF8F8F8FD09FF360E14A9A9AF5A150E85FD11FFAE2D332D3333 +%FD06FF5F0B332D3358FD13FF938C8CC9CACA9A8C8CC3FD09FF27F8F8A8FD +%1DFF27F827FD08FF851514FD05FF601536FD11FFA83433343358FD06FF83 +%3433343358AEFD11FFA18C8CFD05FFA18C93FD09FF27F8F8A8FD1DFFF8F8 +%F8FD08FF610E85FD06FF0E14A9FD11FFA8FFA8AEA8FD07FFA8AFA8AEA8FD +%12FF9A68C3FD06FF928CA7FD08FF27F8F8A8FD1DFF27F827FD08FF3615A9 +%FD06FF610EAFFD34FF9A8CC3FD06FFBC8CCAFD08FF27F8F8FD1EFFF8F8F8 +%FD08FF610E85FD06FF1415AFFD34FFBC68C3FD06FF938CA7FD08FF27F8F8 +%A8FD1DFF27F827FD08FF851514FD05FF85150DA8FD2AFFCAFD09FFA18C92 +%FD05FFC38C8CFD09FF27F8F8FD1EFFF8F8F8FD09FF360E14AFFFFF5A150E +%59F82752A8FD04FF846136375AFD1BFF9A938C8C93C3FD04FF7D52F85993 +%8C92CACFFF9A8C68C3FD08FFA827F8F8A8FD1DFF27F827FD0AFF14151437 +%14150E85FFFF52F8F87DFFFF5A150E150E1514AFFD18FF928C8C938C8C8C +%BCFFFF7DF8F87DFFFF938C8C938C8C8CC2FD0AFF27F8F8FD1EFFF8F8F8FD +%0BFF5A370E1436AFFD04FF7D52F87D60140E85A9A936150EAFFD16FF938C +%93CAFFFFA1928C9AF827527DFD04FF9A938C9293C9FD0BFF27F8F8A8FD1D +%FF27F827FD18FF841514AFFD04FF36155BFD15FFA18C93FD05FFA18C687D +%FD18FF27F8F8A8FD1DFFF8F8F8FD18FF850E61FD05FFAF0E37AFFD14FF9A +%68C3FD06FF928CCAFD18FF27F8F8A8FD1DFF27F827FD18FF611561FD06FF +%3714FD15FF9A8CC3FD06FFBC8CCAFD18FF27F8F8FD1EFFF8F8F8FD18FF85 +%0E3DFD05FFAF0E37FD15FFC268C3FD06FF928CCAFD18FF27F8F8A8FD1DFF +%27F827FD0CFFAFAFA9FD09FFA8150E85FD04FF36150652A8FD08FFAEA8FD +%09FFA08C8CFD05FFA18C92FD0AFFCACAFD0DFF27F8F8FD1EFFF8F8F8FD0A +%FFAF36150E140E85FD04FF7D5227525A140E618485141414A827272752FD +%04FF58340B332D83A8FFFFFF5227F8A8938C8CC3CACA9A8C68C3FD08FF9A +%938C8C8C9ACAFD09FFA827F8F8A8FD1DFF27F827FD09FFAF1415143D3615 +%0E61FFFFA8F8F852FFFF61150E150E1536AFFFFFA8F8F827FFFF5833335E +%58340B58AEFF27F8F8FFFFFF938C8C928C8C8CC3FD08FF938C8CBB93928C +%93CAFD09FF27F8F8FD1EFFF8F8F8FD09FF141436FFFFFF84150E5A272752 +%7DFD04FFA9855A6184FD05FFA87D277D583333AEFFFFA8580B33F8777DA8 +%FD04FFA19A929399CAFD08FF9A8C92CAFFFFA8998C93FD09FF27F8F8A8FD +%1DFF27F827FD08FF841536FD05FF85150E52CAFD13FFA83433FD05FFAF58 +%2DA8FD14FFCA928CCAFD05FF938CCAFD08FF27F8F8A8FD1DFFF8F8F8FD08 +%FF5B0E85FD06FF1415A9FD14FFA80A5FFD06FF591183FD14FFC3689AFD06 +%FF9A8C9AFD08FF27F8F8A8FD1DFF27F827FD08FF3615A9FD06FF610EAFFD +%14FF833383FD06FFA80B83FD14FFA18C9AFD06FFC98CC2FD08FF27F8F8FD +%1EFFF8F8F8FD08FF610E85FD06FF0E15A9FD14FFAE0B58FD06FF583383FD +%14FFCA6893FD06FF938CA1FD08FF27F8F8A8FD1DFF27F827FD08FFA91514 +%AFFD04FF611536FD09FFA98585FD09FF7D340BA8FD04FF84330B52A8FD07 +%FFCACAA1CAFD08FFA1938CC3FD04FFC38C8CFD09FF27F8F8FD1EFFF8F8F8 +%FD09FF360E0E85848536140EA9FD07FFAF36140E0E0E61A9FFFFFF52F8F8 +%7D83330B8384A858330B8352F82752A8FFFFFF9992688C6893A1FFFFFF52 +%27F87DA18C689AA1CA9A8C689AFD08FFA827F8F8A8FD1DFF27F827FD0AFF +%36150E150E1514AFFD07FFAF1415146136370E37AFFF27F8F8A8FFFF8334 +%0B3433333383FFFFFF27F827A8FF938C8CBC9AB58C8CC3FF52F8F8A8FFFF +%A192FD058CC3FD0AFF27F8F8FD1EFFF8F8F8FD0BFF846136375AFD09FF14 +%0E36FFFFFFA9370E36F852A8A8FD04FFA8832D2D58AEFD04FFA87D525999 +%8C92CAFFFFFFC28C8CF8527DA8FD04FFA8C393999ACAFD0BFF27F8F8A8FD +%1DFF27F827FD18FF851536FD05FFAF370EA9FD09FF2727FD09FFCA938CCA +%FD05FFBC8CA1FD18FF27F8F8A8FD1DFFF8F8F8FD18FF610E85FD06FF3614 +%85FD09FF2727FD09FFCA6899FD06FFA18C9AFD18FF27F8F8A8FD1DFF27F8 +%27FD18FF601585FD06FF610E85FD09FF5227FD09FFC38C99FD06FFCA8CBC +%FD18FF27F8F8FD1EFFF8F8F8FD18FF850E61FD06FF141585FD09FF2727FD +%09FFCA8C93CAFD05FF9A8CC2FD18FF27F8F8A8FD1DFF27F827FD0CFF8585 +%84AFFD06FFA8A87D150E85FD04FF611536FD0AFF2727FD0AFFBC8CBCFD04 +%FFC38C6851A8FD07FFCAC39ACACAFD0BFF27F8F8FD1EFFF8F8F8FD0AFF85 +%0E140E0E0E37A9FFFFFF27F8F8A885140E61848536140EA9FD0AFF2727FD +%0AFFA88C6893A1C3998C8C9A2EF82752A8FFFFFF938C688C68929AFD09FF +%A827F8F8A8FD1DFF27F827FD09FF850E1536855A370E37AFA827F827FFFF +%FF85370E150E1514AFFD0AFFA827F8A8FD0AFFCAB5FD058CC3FFFFA827F8 +%27A8FF938C8CBCA0BC8C8C9AFD09FF27F8F8FD1EFFF8F8F8FD08FFAF0E14 +%60FFFFFFA9370E0D207DA8FD05FFA9855A6184FD0CFF7DF8F852FD0BFFCA +%C39A9A9ACAFD04FFA87D27599A8C92CFFFFFFFC38C8CA1FD08FF27F8F8A8 +%FD1DFF27F827FD08FF60155BFD05FFA91514FD19FFA8F8F8A8FD19FF938C +%CAFD05FFC38CBCFD08FF27F8F8A8FD1DFFF8F8F8FD08FF370EA9FD06FF36 +%1585FD19FFF8F8A8FD18FFCA6893FD06FFA88C93FD08FF27F8F8A8FD1DFF +%27F827FD08FF361585FD06FF610EAFFD19FF5227FD19FFCA9293FD06FFCF +%8CB5FD08FF27F8F8FD1EFFF8F8F8FD08FF610E61FD05FFAF0E15A9FD19FF +%527DFD1AFF8C8CA7FD05FF9A8C9AFD08FF27F8F8A8FD1DFF27F827FD08FF +%AF150E85FD04FF361536FD1BFFA8FD1AFFC38CB5CAFFFFFFC38C8CCAFD08 +%FF27F8F8FD1EFFF8F8F8FD09FF600E0E3760610E1414FD38FF9368929AC3 +%938C689AFD08FFA827F8F8A8FD1DFF27F827FD0AFF85370E150E1536FD3A +%FFBCFD058CC3FD0AFF27F8F8FD1EFFF8F8F8FD0BFFA985608584FD3CFFCA +%A0C3A1FD0CFF27F8F8A8FD1DFF27F827FD5CFF27F8F8A8FD1DFFF8F8F8FD +%5CFF27F8F8A8FD1DFF27F827FD5CFF27F8F8FD1EFFF8F8F8FD5CFF27F8F8 +%A8FD1DFF27F827FD5CFF27F8F8FD1EFFF8F8F8FD5CFF27F8F8A8FD1DFF27 +%F827FD40FFA8A87DA8A8A87DA8A8A87DA8A8A87DA8A8A87DA8A8A87DFD05 +%A8F8F8F8FD1EFFF8F8F8FD40FF27FD1EF8A8FD1DFF27F827FD40FFF8F8F8 +%27F8270427F8270427F8270427F8270427F8270427F82704F8F8F852FD1E +%FFF8F8F8FD40FF27F83333332D3433332D3433332D3433332D3433332D34 +%2D33332DF8F852FD1FFF27F827FD40FF27F82D3433583334335833343358 +%33343358333433583334332DF8F852FD20FFF8F8F8FD40FF27F83333332D +%3433332D3433332D3433332D3433332D34332DF8F852FD21FF27F827FD40 +%FF27F82D58333433343334333433343334333433343334332DF8F852FD22 +%FFF8F8F8FD3FFFA827F82D2D342D332D342D332D342D332D342D332D3433 +%2DF8F852FD23FF27F827FD40FF27F82D5833343358333433583334335833 +%343358332DF8F852FD24FFF8F8F8FD40FF27F82D333433332D3433332D34 +%33332D343333332DF8F852FD25FF27F827FD40FF27F82D34333433343334 +%3334333433343334332DF8F852FD26FFF8F8F8FD40FF27F82D33332D342D +%332D342D332D342D33332DF8F852FD27FF27F827FD40FF27F82D34335833 +%343358333433583334332DF8F852FD28FFF8F8F8FD40FF27F83333332D34 +%33332D3433332D34332DF8F852FD29FF27F827FD40FF27F82D5833343334 +%333433343334332DF8F852FD2AFFF8F8F8FD3FFFA827F82D2D342D332D34 +%2D332D34332DF8F852FD2BFF27F827FD40FF27F82D583334335833343358 +%332DF8F852FD2CFFF8F8F8FD40FF27F82D333433332D343333332DF8F852 +%FD2DFF27F827FD40FF27F82D34333433343334332DF8F852FD2EFFF8F8F8 +%FD40FF27F82D33332D342D33332DF8F852FD2FFF27F827FD40FF27F82D34 +%33583334332DF8F852FD30FFF8F8F8FD40FF27F83333332D34332DF8F852 +%FD31FF27F827FD40FF27F82D583334332DF8F852FD32FFF8F8F8FD3FFFA8 +%27F82D2D34332DF8F852FD33FF27F827FD40FF27F82D58332DF8F852FD34 +%FFF8F8F8FD40FF27F82D332DF8F852FD35FF27F827FD40FF27F8332DF8F8 +%52FD36FFF8F8F8FD40FF27F82DF8F852FD37FF27F8F8527D527D527D527D +%527D527D527D527D527D527D527D527D527D527D527D527D527D527D527D +%527D527D527D527D527D527D527D527D527D527D527D527D7D7DFD04F852 +%FD38FFFD46F852FD39FF27FD44F852FD3AFFA87D527D527D527D527D527D +%527D527D527D527D527D527D527D527D527D527D527D527D527D527D527D +%527D527D527D527D527D527D527D527D527D527D527D527D527D7DFD2CFF +%FF +%%EndData + +endstream endobj 141 0 obj <>stream +%AI12_CompressedDataxێey&v@@ LCPbuQuUjF06<` 2hȶ(BSDvfVgRSQY{X"χ~𣧻OӸ6O>;}ݛp滯^}Ż?ބawO?yo^?Oϸ[?C;?stK防\0=|/߽zA_z>Az;0};v0owg/^/08Et|ӗᄈ6OE+i7OG]L>5Cooa,Dk9 e _勿o^uڽ}#ٿN׏~ow4gjޛO_;Wx}^goW_c)W/AGx7S}wb&L Pס1FGlhG_|a$}/?-=IWNl:czw^W @;|n٧ן|O ҫ7O 2 ޾||}l/?럿yѷɋ8h{?-A'17!ΝsBF>H~ʍ gr8ͳןne.?xSt3usǍlM9[/IyFriӱoknNz Ax_0ʍ0z_y]f_}7^~+\)C9P+MuNL lʑQ{//w4݋,/͏߼yuc + + ܕey'2Ȅy_y^! 򀏳zo}/? 5+ +t_|IYe00=ItIzYGNMTQK__>{7go}ןDw/- $#$B=R +cj2 5͌emKO_J~3b*]@Y%9m>Ϟ||ten¡;t3#_;n@-sKHߓܺݙۉڑځ~'_nڍԆ]斨En=@uYړ#ü&_Q0ߋ'8s7tvt8 Sn#.Oy)9s:Cڧ9 RSxܑ >Divԓ@$S8ҒMat[ݹ;ﺩu!{u+7海.D?qO2ϑ wo;ȳ9{_;u'Ho@7T^~_,-wނ^[ړh{Mfm;o +,F<%42L@40H `Q!@7L4 DSx P>Mg@:@G4i7H,ӑtt t8mO8B t':g;::v7R a#6a>X!2&FqedG 3)Ԁ=n8x8Q;֎HHx#-qt'xv> 謝SxkiN4{}+qOϝiqFV!w& vHǤ། ʻN͙Hot=" ѨNc0DPfcp>`f +f ~mLr/yrf +5vv%ۘ7&lM6! Ol1"]/-!i#2 =2oI}G93љQn(8(a R#|0E)FE01cs幌UHXcM̮tJdXLF[ڰnt=ii[~oN|uu#&2I[]zOM;6m ĮM~陛L%i4bV#Z.u[jhS;f@DَD2v̨YHFS=S;2',܎Abm%u;1 35&,Ity&TԼgR8)xpbbV_D >X33' m;fgFcX3H6QpĻ⥙r aVI,-df7S߃ gf;x9}\ +'Blꨐ0D` =ND=3mHiyzQm@t=N-*mfL<-&TP1"#'BDX`J`"bDBC`<)DGƒ'}/3ڎ*L^ʼn)fWCU`xYƄ 3N*h QEpX 1c31v̌cbEBߗ`.x|u #v}W=vu MSnдiSшoڡiǦ_綁oŦшCƦMM[4ЈۡiǦ-^MlgY L?#K"W@[Lgg{/LO Gp:Q9Lb$0i[DEttDQZ52͉eܽH IqY"QuǓ΃ZdVh9"0$>LyثA ӝ?1 Iy>ޞ::Ƞ(A BC3qK=sL'm%vZU>9><#^U8`p^H$sâ勖']4rv匛Nu(NIN|9G%. %̍N΀lF+u!J)]*,c82 +C؉e3KgFKR6YՓ*⌂\;|> ^ ;eŐF] +O +\Oo5tZ)w߱uq 6:pJ=K?A3KA'KC{Y!S4| ) +4'ǐjޘX"eZ2\6*Yڥ|8]Ѿ\z dI6Pڭ+oLTeݜll!gU(:kgUk2KsreYm0޿wȚ&q3Ow]T׷ޕϥo9]uYnS(`aE'q`3d: %q J\u*•3_+TwJ-YIצG4ڨfEftEib,RR1 pamWZ[z[=0AXĭya^ ޖZw[;[іocұi.*)iU2sך\GQmvNDZEMu\C/us=ދָsYj0ZIKoX4~RX_|>v  S9L0`Yv=vN 0{w i2aczafܤ̭¼XNP@0H6U~Rݺjcv]sp۩f̱猪\aPkVnz[[~NjgšMؔIY]K1_ژLUb8߬`?+<;1/Fl]c#d;7$#La,۳?fMfew;u 5?GwyᙫMamߝ35j2alsLj@cE9t:sX +TwKMOQSUW:{uòǴˍ٫ט5u*Bh!GgC +,H|ԬGa;(Ea( +0^dˎ۞W6D]|]/76[-Lb+hv3VVCTZc\恱26FTw',)_{%_3I9<zPs+I]Z397O닕ƊcGg$x};= *EˎET7 :$hNpaRd }`{ yf3$3TJc#S#oŸ7*yT ʴWKMa^kYLb$XҟAbڳS# Ao ¬̻+jZ?VĨH2qŷ\i{B\ixn*C˓jcSzSڑ)ׁ4l]eu#wTP]N q{6&nLk{qEZѼYR6G.t1)Q\ ]t:nXL= npQ`Wk5W=QAAG"1\2bJ >13#b8<*]Oy4lO>hPj}`jNFL< Ϳ /:1+,>ķ,`!HLw(TݫpssQ~OQ} ъ^٭[ƕH[LGfc'>#<{9X|{ioEX-bk׬%6nnK߭шwwy +:֝e +hSunq;9HZ\s[ԾWbW܆;YLOG&'69x"eRJ6(s;U)*u4X9-_bhX'G8467wZUkD*3"}86L1rI7N61,1f؄Iuq\q,m "c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4c4d4F(QΒ䴩!!Ò9*'2F_˘?Y)s(GyX9sqtsds8Z2q4#7%N;|G&=aY'v۱%`}sf>2d{o=2yIk0bݴ^j: Cߵc]I*zz)J8t p$ַTg J'fY7*DWsϺ[RڈXj),2e){&ǕU{1;v!(0O`"H#^~PNw`h*l9zi;^ٳuO8{P<o`wqV48a_Zj26iي]*MP]լ<~Lݤ̮uksErE(ӍeMkgV9z3%rN`I#W Rl星&y5TL\2r*o4Go9W5U굟.ԬfޖofPN#&Q}\(=\50+ʹȻ! +)^ U%g `}W8TjaR2G23ixtc""# qFD:n/hwAPUX٣*YUWU(8vʩ_IKcXB(@eDVfDi,߁k.% f"YĥDA3gp_qxvJV=D16ȊAp~ߛ>Z(ZBwĠpVrqTX 22t5}Qefi17RS/: W|ٖQjuW۶E[~֕4ʽKh"m{|zenSU*F)LGB-܄0.M-Ll!45z;%v/Z:>1p LKRM:n &g=*(* E[  GFa]Jd@\AdrY7rFP%Wڄ?&&N8L4U43bZQ + ^-:HSU)𛘏NC_;g6i1im]PD(j U׬-#_kh,QW#[|8<(Vu&YΪL&Q⣺ {S.5&, +JDq;UqP1ؠoV\ݦ*yo@e +Yp U5Ӑ&JNEZMm$%6.dk?+nSm}hjc]9Y?P[ݔW9̰*U/դl#>;Dg9:8 +ZsuXT +&ʅTo=+߾wp<(w2]@sTL .'Gi暿f9WfYrOTڊsh}URnkKv-); +QKT"kA]diĒ+J +"cX +e}͞aF+tj^BJ]Ҫ' GRO`DyhH.[ښʖ%c!rZ1afx<&\V/+En2nlqhe]m&<֡mW|h[t[dJ$|ERuّ˭76%щI{W]0j%Z?UV2K6^;ZZ/K)-i?mkʉ{.\e Ŷ箋RCc)rmv Uf*dw? ^GCIm/ +nI + -H}Y +!F>'U}u2hX d'+,IM;^%g[Uڽ7ܭ7Vk%)׊hQvS޲ԞM9|Dу<N0{MyT%xSԺ9nuu@3aG9(_w(\L$~_ozA4/*pA?זTE?#Lpl. +M^։Z~IH(^hx1MkhTGk05쨎u$i;D)f7/#%V^| Ǒ\8x6x63m2v0LݐGZY4q3;:N.ᝀ_&0Q4r}J& 㐋Ԏ3i3fJǙKkpf1ㄢ`<ԭ7U̾X:'{>_\^pV}# dCݗ+Dc"DLc"DLDL1=&bzL1c"DL1=&bzL1j01=&bzL)ۑP΃-x)b`9,׫﮶*j;'`.W +eofZ`6i ^ +Y8vMNmAaѢk1irGfZ6ݩ2NuVq-se;53P7-p¸tMfejt[pCs8PLWtQ0ea,f-Im~}ŬWFx4;AQ{&dGF T:ѵSAØ]?ŕv7vmPmUYI ҦMXfG&W&ҷD]hW ўX**4V"Bˮ  '8{ {SL 4𮣲ɝ&}8TQ'=TbD"aFc#JjV_AL(_uac)h(يPᢄvB$92Nd{*E%hW0 +rehukJcCLAu`GrMaM]Gۅ $.k@Ipn5eiP˴R7EҋU7&wyw}]T~}]>50wgiWV>5]>2thbG պ_{#]J*+mwUUXҢpZ(kX~Q_x{Vwkvk:~~LƎ|X{3NC#w ~8rn/TPcߜqSGo-hvE~h SÌwow=B?LEȽq Y4R 6p;PhK݄]lk`}X#rx[* iʚͳ]ʲ-5!wnBcg1RU軻&VBټ9."{FhjlЋ[^ib1hr1h)Q#h&9qh)*7XDn_G1Di;4L_֖)kW+X+hWMϹ&sfY 5;sGzVbNd+  Ҟ`ag+9N*,vB.ښze'.ʱ{(oWZDXK^cNjUD,_`5ebE]cy}%20?E$s_W_ϬQ80b Έ̌`hUXE#m^m:z <|wa4O!-Ԫ 7F0MayGxv=Z~,Z&jp2k³H +l3puHBRV`"B^)A,OZ(]UՂ"jMe]E&U)Rz˖ޥ|)%R.m:?ܴN| >9tnm 9`RNg EO%*׮ %&EbXy|rR%Vi+,lX…K2T +0a Ҵ*\KpPAýz+u:|v6-3; ZQRcAQUшv\_iay+Sʊ\rmkFkslW jb86yJ@3Elp.Za6ztXSK]!"./UV>;CO&rj\d1H~6B228.s.m1&㸬k7x3X(򄬓}rmt<[My$gI>*iI.,ac=u z6ZNMݵRuu٫.RhltIj[6]Mn$Yv=rIjh +)w8Ρ0iyq6XFA~%sO7T@xO_7~_wW nfLbS_n Um{uV0LYKEF+ +IIhi%Y-w%Ztk~_5I*hH CxkICWYyfj {g*dP6˿b,]X5VteB/}A_.*[vc'iJ99-iRU!M:'%)t.2y9n2 daK4Pc w UE]ыƾw*BM] WD[rnF[Yŭ۾֞h W0;;׮+|Y@2C䔜r?kX%5#9@ؘƢ) SN̋rZ@e[= MI#bVmZUnKq]bw+5ɚ!H((5,xXqN)%g)xzR Y _&V'-X'_P[BXDS{+$|QؔҚTH XX+L~$*#U^Z,."SڪTRV^ޮ=.wuw%f򗪏~Rio=_h`8 ܷT3*Pȳ8m.Z5{ ؀6)A>WYA[R$ޜ62*LXN[$MJ"8Ċ򮤒G- jh6_Q)v,S* +"L1d(J֨QinJaC +-IeeQBb2wu*\w߹^s[z֚_UZY-at+*i5XS26">hɈ{ǽU;=ީ7ߥvvLtD!벴ϒBf +1s`JˍcnLTW +Ҵ n+y/_{Ofɓ9<{אD-Iyț ʷί%;] if6!L[M#M-,/?KR ?_zVr͟n!i7⁛?lmb،}{w/߼~Wo޼|k]]ON|'g|xUG +ws1?Sf*'h+٥lO(3M- BDhզX-(>!G & i'Qn&:䛜01PCEQꙶli;Hy)'3ҍ? X.Lp#0YŸ⺟!G= z.o{r#-׆%&z/SOb_;gC7'5l.:m={~3g))ۭ6a#t!:,tX.LF~b?D  Ax35aP + zn;{[⌚Sj=sFU)Lx9:]Sʹ&MxM-!zz0B;'zg<`bĝh3MGw8C0u62"u3ͮ zhv#.  6N"Lfz`HN4 psDsfZ ڧzmB 1}zENH6$34RLm;4+F2Mṽ 4%a[LH&`Y)y0ỴUDG䟻tzb'l{4&LaǞ87ampgUH `?C6h3p@cA12݁S$B 4BI`4/w&ҧ=7Oa݆8sb*=H.iؐ)G(WC 0SzH ifT'D( sB2ڴ0>ćGOCh/G!o'bv\6 xpK@>}F@BĦ`0@?dO[cI uw:vݱ߼#"_/.٫={՛ov5?3̈&O'Οd~WDU O>-V [a7?_~){2bn W,h&!3L9oF XpAhn 07׏)m:yM0J?2:0tWd2 0D!(F#z O"bNg+#:Da䧣nl`OpRmH$X&J!q3L6}֋N(% #$\UD lDu=vnyZA V^}櫈c#I&Mghz/}M3ϖRL GpXF.vO{[:Dbh|b%ys%XD,>l<@6blIx[H~ -DWs c BiQ ȁ9z,&q:r_6b"Bc%W>% Hz 5G 79}Dp;  /lA"r%Iq& GG2 SC-R'=O>& +M h`ITtF.#-6|2I%#\OfM- CA<$1BRPobt-*h&.z!a")NV wMc ;.MF=q9qM0ؒ,v +Q$yxVndGR܈'f$kBcKH,tvJ#6p:Pف<%Ü₟'(>#Ͼ(XXz'+2GE Uhf[gݝy]:=9pMԆ_ush` ' RLze0 t\f1Aȏ_@`6O^L_>f@ԋwҿ Yei ,lkkC0Uio"m7=Dio72,h(͠}7L;3q5fv*3!fp|DNFvA(ts{xXa;dy;it&>qB"~(fD! #E RɡdhÎkU&cJԠa;ڃKxl#.#7A!Ż1Ҡ h1 !0`_r!1`RFO"SOH?-†NF2}: o*(hFI35ѐd5 ,xNq^yk8"+EVy 4Jǥwړ߲6x82:tI#A|pxZ^h=1CṠ2,cs y1o ^fTbd#U3c(%˙!2e9 i ,.-r0,-#1~>A1Թ`Qnw2q, -ɸ롔PaF9&.9do +(XN9k(L67]A$VI:CV,21"4V&Y0Ӊ0 J?fS/3IXp^8v@U&72%Ay#4P^gR2)by0%(!\`b48Fb:["$ڕD tNgF]ypmǯPy n-j)=e򖘛E$%kB* +T_v]w>TߞI؜u +$]SJP$lznO]Pc^&KPx`5>'HHޫ &!J  +lͩOŐ24s +P%m@aAGڞ(t;;NH%۱9,m4ټ NXNz R٥B'$Q72ƀuX4"TV; +bea&mȶD=h1/uCx+h C:I[CϷGR0p-0N6)]:Os8a-Ѩ"Azuݹ.yh` ++ ,X;݂i%3i. Z3yS (<7APycbYZE'FDYt(L[-i;B` c;.θ5. )ȢOZG=J` (00IpAbDzJӅCgD"4FLj4cLmg0z:ݍG4U,.$A_S"\rfdalz,ʺ b&D&9~l {*")M,҄Rc75we͐k|L.lTCzv;]UTb:[ \躺p]j??lTOk##ZK?Eǽ?P?&P+\TT\uhU-sU#JS*urr]ٕӊ]"yWu;50e W;]94u?w:Ky*Ꝡ*ik[n;pJ6$-i+(1ę +܇[MqZOT ȹ'l۔ʅfvrاNX˙Dܤ̜tn~9X79vsspnn=7_Tn +:DݦҪ[m.;I߈en$ˁe9~1HDMt !٨ -;~Ɂt1qekD!ơh5Iɛ?UΣ ד`MTUHbVѸL3S2Myy3}Py S^WKe=LTQT6)|ݘ睊ƛ%Ɏ6xc9ZsA|'ǚu + AMIh4/^Jn_hgA-E^w.a+D(l O5pP$4 5@Nen#XF/`| w>*1~2-{ (9p F ci :1e,CC * /88N"F +mA(H\Ѣr2`}O p<5@&܂[2{h~f(߳ѭa4Iwe.$",f0'B EVLYf(#O\@}:՗ V BH gb'h"|gE&w`GG8[!M CMP|f AWy.BX4hiP5O +m 2$ݙmR"X5]]~ yH)*gE|B&ԇ%V4@bCL!.G< +]"rey‘g3~ VF*j{F !Acmqaxުs!)/ulS (mE7C+A0-a!:YfzڌHF +06SrǎI8?O6-?s6s;lPNUA͚a_pmPABPʶ`42~ +48DKlz_ Dﷆ@yl]Qb9!6*k,V$ob?~\kk9)%<šv9A}3?vCmǞiD]J=9i6>A JO +ctLM:R#Xa 0:BLqЁɂ89܏q-?4,@0s8 r% +b_C +\(|[y Io i90mXiɰvIOlC!d('p3%dx3–:vyK+<bKn +KYUmf 4}= +ڒ]<{PGӜ\T?C@_ IGZ$Z5D^xf2OϊH?t<ȉyVNXU EJ/;;ͳ7,ygZhT\01ވ=(z 1 +Y%i{v35W5* Vꝣ0!ŠD' a{$&G`21nVaG%(م=} +:7El'Ę'm"j9|Yfi;zϒ׺IeO<2;w:c]ޓ4xP/x@vN%  j+k˛uQˀ\9Η :`FDW0mAŏ/fn Ul%Aw/>݋OHj.{NF:'H5d\1 HM:tc =}SCLT,s}I%,4r1)CecJSld }bzyyd = jzLi5MЏPm.jp0 e^Y\ x],nU/#$c賂'c,Z2K@#s=gc4SIe5XqdمbgOFIFOj^[bim/-%< +!cHWfQTIT^us _;|iٔj'N{51)Mr,Y:%81tJCd/&qS#Yh)A2[:w(p6$=b: R!)a1!$Z֖y͆tzm + C<។xX˄&wo3!1 +WJ:he6{vXi0xclX'&: l(8FO͞Pf +$; N/*, i܂ih ,]r˲-)ؙ9, +eg`bҲ!*/l%Sh:&O%eȂBal1+wRyh톷&^GlG';JrLF>wF15zbTh0$U(L`Z$9"ogB̘ذ^}78ҘR"QFvMRKTg.ǔni2Č H/"ІQP*(ZؿBKZ#deV#ӓiXTc"b+ٺeƛCM6a0C%3*m.`>~ Ǽ(Pu? F6'04|:n鋕EZ f.e,ytYtxLTxPXUnI*9QRѫz6hAʆ0= &ЯE+zimazvZڅhQN[<ɏ;j#ɝyȹS2M|_TAe%LWT)5ݓ)|)ʖ& ɇpTV9Y߀cfbtd~a +q2=4H˲6iKBˁr񦏀r4"AEJ& *ҔCi~j nKZBe&qR ueK> u:ɋ%4ʹg))8c[ 3S !,gE4 -ccQy jI-t-s]0[M5Z`\nЂqiBa^$0[/xDPPl:yٵU-z +WEى׿|k=g?|GKs5|ˈHI(H͸$"A=x 8ʝOBVRTe !d bE Ft$y>2$x&ExRxuL`I5}/N+={8pQ +$,LD&xN,4b@9EhgDBHaxLh轘,g H ! c,@&S`օ͞C~H,s?=)d‹ft$A:Et:y^Di QQDn@TP=;GCHb +K=Ҵ!\{xd-%j.aLȥ alG---ޫ؎4.JʋEbzXuUbL-KE\RnPVy)p5c/dQ AP8XcQ1-LTD[!lH䵪+xQ3~ +eZ*v(_V+v +VF8H +/VP ڪE8/$_Y++oEXLR,"}ުx۹9֪I(JT+ywxy@&&XFf- FD]-I.x!-ҊDzeuc,T &ebqaňҷp +uUBϽcDR&"hEk$ڐCJQ +_OK9LB[ +p;deϾ9( f-3yR5&BP jtaw[,-:We<1]1,@^2QkKEU/2RBXq&pVtIW5e|Y+C>[ +:>E^nh +P6 Fxs)E+QlqI^ s*EcˋEeG^zSrVv9R6N,Ւ31Q=Skszͤu@!u)oD=SKM +xx5d[5ܬn)lPJ0>yv;~v + Jm^m@nAW;{k?vs`jRY[Wnh)mgT^~7˃) ɔJ 6*% mڼy#KUoW_w {!{w ^iWw Uy9zZghz'o^Ic=BO3 ]]?[i t yh}imִ:%]l8E˂U;j{KTcqRxsgQ\x$ŗ vߠ"-;a8Bd2fwnxKLO$lcB]*r@_-G`k|!.sapEg$ie6vv,9`PXûgeŇ?&Q) CK7B%`rE>'T#0̞b$eHꐄ%.T5.=9pKXAq!A0w`Lf.*4n*$>V KY.(<\=) I%aT𮛴fuZ8J8ZFv́S~mwl`AS@*D6_ ٨&I#9):x'KDO`)CϜ6rkp 3ũWdNb=#GӨr)7 + !2SAOUH%僡ׯN3yn@aWeWy_Cf&_p᡽bU ;Xbmmsk-~XScМ@3 g : 90$.MQq4{ifΡ\J ІI`q3؞5P/58q=G'Xf0^΂s᧜(poĐTNzض`egLYWzŕP03 +E޺/ʂVp*Id U&!;~';Y&&XQD4ũis+*y~tt`XSù GNmBL/ L `l8uIuȞM.CP u#D| @P60\BJq֖}y֣ l g˗|;,6LrzUDX3ھgKD8[N9C$K+rAZ|u<~FJBl!NҧȤ +fя(tGmZYΝfV5@db;,W +)c)"*ϬU]VyGqGġ G?k{[?<U|I7CTR ql@epxRuR]/-^k In zƬ%mgEXd'YY;j\(+d#1D&Q!8{2\=ݩ6;s|C.W;rξPPV %"4k"gKf/M<*$գZaDk.'sW(5-*IAܩDa!L΍#*V 1ci53M >E듇HfU%9aF6t0iW6sn([' mŊ-NjX1wY4 6%/=KtƘ }0HS^}2>&<]|P-{6UYN͙E9.< r[+SN(D;(.-띶̽Љ`{9Cc^ lew2.3P f})[9v6};kclQY aPmTDKw 52 +4h[A85,X%??Щs]:IRi>f?x~p﵁ eU AUYVd&e=UϢSANJl Nk9[Jg1FK^sIs;ZO @Eg k%svR0FM.Iy A1Oc]voIJʌy>%- [a4ڇ%luWl3~+%"v:iFkdĊu>cҵ ^ieyDޤI@,tT +0M5-%g@ SU'#'.WSs|JY gvB!~VJ%RWMojiSULJLاkrvazdP4TsVD[;Ou[ +p +Ʉ?9f/q8-lf(M]Ϗ*{}s&T"G|A_IC3 aR.*mT a'v"\{r¸J$7 {,ii?0*K_3Fϋ۹rYy@)@hn2Ϸe9Sa{ƕVC8{#GBB=[4Jc cKሚG#ZPZipy1wtDZObtNjEWM=)*`?>(V8և=4׿վaapd}<.fGTL{|s@LMsBa+f߾C ?c@#TK] ,bEـ,CblT4Qk:!{ Ԉc@k57ԫSDo[PUSj;S-MѳTJYH]l^vWZ%aeAWTE Yͯ_o!UJ3=Ռ82?X=,UڒT/*ց^'\%,jp>w]Zv(a +#(QgLq2ޟf?p]jSZ^Z\1I'4^IvtNi1VIG PJHfoRJ8ڠ`nav*yJ^OR:B~SJP]'ā˺J]Q4pMaLJ_WJ.}qDxB'EhߓNjK˜N`ZIϯS7^⡘.b^ٷ3g%MۅLT[?ugKSK!ڢ!* 0$%ߊ5]{x~[S"2V|ݥz&U7sJJ桺8.sQ\,kZ5C5s _yjxUYgM&ó׎8{UP '!VP%NmH h5Бh+Tw +ǃSnRY#<$>r.M*,!iaO{ %8¦R|kx?8==Sln}`*Z>0j+U1i􂋆R-5RNR1xX; 4hzkT,Z-zu*ӅrԛݡVY=N`ۭ:hLCrd^v SLAIuD÷)\fC'61Z|иBeTܸ/Ɵ5t$X8x{*ĭN*OL4l@Fm2%Wฦc++O~_XgJoB'9O3OW<9HoI{Cԋ4&bQUj\ϯqj8n"YulG@"@ͭ[7;7ઌouډܷ[/Ӿ+]6Vy0mP~a ȟ:}x۸Twno;7q|nsI;{R-y&$4ع;iDtܹ􈝛F8}ΠQ +T@0A +TR\ m2hH2(f$PWAݔ@JrGomƥ@r=-h=Hآ,<ɷ@ Cr (\^s Ye@ʐ@nK<]i !z PF$'|~ 8#q_xK;R4a=2G=/Fx ~#l{+!`l +%2g"p!)oJ ԳˬZˬ)P.3*]f(4+\=mzV-8+dg +oǎU YR081LA1CΣV,:1EW8Xeml-` PoܬÈ{cS6LL1CV`$Y:E)BJU >/8`Nn[lWآFcG`qkWP0j~qTU)KaL6QB5"= Hl B-|:B˔IDPt˺u1JlG0ޢ@DI^ ~BB, IaxO"Gb2 ی=:cXs$mt]f7cGYLJc}`S`A?T,v bu2$a"b >F.M&űknvgTqeIR)o|4||xͅҳ-/ iCv_`&y|NNB]t+Vѿ<9;lYBF3Hi登]bjZŗE^ouEFUcGm^z zf#W 4*W9=Ȟ &I KKP/J9N/ʼRI[{q~OXjY/0r*Wn2>͍܍6s/v-%HmUV>!I;vSh4sU LM3Qwd 8b;$ +cS tK ˪fO>E6bzDHfOm+4wp"[u[j<{6*YqrZ޴Oȩd6de'^g榝ZlgjPZ"NGYS`QBxC\=!FL*e6jVzX+tr;)IicW@q&G - +kb}OCus;Hfw~)*+RU*Bzʹ5$"2O[D&1v`y#>DY* onSGOv$E[]{Z4)񕛳 l󞹉Erld;[)qcM:@`\+׋:OFMGI3R2+ݒTP)Qt//&kI4ߔHZbyLa9a3"lF$VKƥ&b,JZrک,Hm iV׭lN밐9Us/@7uO0mn_[v=$,4YL A-U+Z:=${f(H~3?mAzWP|ѡZ[ESG7B镮 WýESS<~]ϽO~,=Tݡy-8T O˔>%:)뮳بwY:ᅫL,댈`H?[ayp%Ei DmCá ̜^`Gh8 08Ϋ<ށ!,[THM塜~ i>WĎG!}>^z؈/Q"9#ֿ{rjd oB˩9fmFsrg2@+畒qXQ51yqf05Wq\sG`v ͑1T. PFS]ed9UZ'՗TN5qYF|UoLM,P=~"Fn8Tl||m%~O0UoKr{ E^͆'#qy{~q| ^LI` +:7`QvN,Sl˹ <^r\ l"b{A]FwTWrIГgl]~X(GW1tOLnX; Zc6h9(%$sPRoVm>>9YS~4.#YPK;[-%9TTHeSV#9 )g&ߞ)Z@8LF#SZw4abFJ3erK Q/zz0U쩦1$CnC{W‡[KhH~z!ّ1Ϣ{ޝ9N79ÖC@dXs"~WL$lO]|ΧHU'WI%̪Qqx>7`1]GFE[)ۀx:1ջ$D5Jg$1b.[b䭧'F23 #k}ǵs[|Cz Pnh6[$om/ y<䉒?5`X'tP!Խb] y›y'D"nfZ %EC %EC %EÌ  4}h~G÷B?x,/HNŘs0٫z+Q7=„}AHAH sPj|H<Q55AF)z]9>qZ~wU:9V~Ժ2fAU=cfح =ee,3 j.BkG{ Mabcq)z>S+6I'߸]{b)5O3؀`騇!֡aGމTC? )=HY54B]H;7{:Ȃ7Pn5_5HjsDO6V_ܐT|*EE3Q|<.G^+|Ϝpp9'ro<$WB[_2ʯ_|*Ex_١h5ׇq3-k&2=$AI/GE=߬9@M92o%DMj)ѻ- pq7mfp0n9^-fV RSO. ɾ + +6\L +;uWdxUWtoVqP̛SX +x{&H^=Maܴ3s $|W6cYG6a1C̄ +t>E])VeceX kG2jç[_q:V;k6J:y-j@gd=z`TjmlCDVjÇ؄9.mj >w1&AJ5+z}S^z":3tڂ:{yc4ciMe)z(ޱFJ4cd '[+!tq)-՝Xai*PD`W*6)B4@Xm) l$RjPy:WU+GK2Fq|1KEzXoTEqoqmBhD}uy׎k}@@a2[,ÈR_*KIY]H?.=Z[ .2|9k_NS[no$l~WlxuEfsͨ4hi-foSvns8WOBY)g:^S=IK\,%]SU{~BCs1[sPSKQ?/ žqo>c2v5 UTmrtڋƴ\끝Yis0/:W;V'ĉ,.9uֵN><6|7&7{W2&Ql4<$έKQF? S⾗yVSͿxU(({j.Z-D8|ދWg-sKj1w̻J`Ӑ7Oflq-O~Hc"y#̜=f]qUcMK]/x,Ҝ+M?E}4xv$Khip/F)=„ו^wC2̧cY 1>.5a%1u>tL>|.Y脀 pVm2XϨ컼=;-#.Ɂb<^ܬi:vs('"?:uƇw@x& hv"(s5HJ/J u&1*ҵUE^Ֆ΃=e_aE*絁P^ +/V^d]"©nrw(6xF|P=#~kpZ8\TLta)8\,/y{U=|{k>TC~@܅GKTa:& %5(kQ㋨Po) P'`9{6k<܆XeN~1HDxcƁS11G #7 iivR-ea- %}ڻ=] P3):/3&#=|(CPVqW6 𬮑[H{ F!&W?-h +5) C2p 6]S'C/3 +0;`0 sD}G!-ÌS}{b}1B6&Gon6{+(Yj!]%->^$Px^]8s0r/.twݵ*B!'mfd*]|ͪtxI=c!ǀ) {xhPͦx/qfFpyM1rX#TTѴeYO]B%w' ԕoюFF>"dk"`_!";zHĈr"2t!SCEFqi>"קdD^nrg/A\VoaiuF/bo:82`z#Z2:kҦ@n게*/Cé3|3̣pt* Y3?9dD=wSo7}TV0o`-.N037HG쾑۴g6FyiJC\^Hts$8o$iaEڨI_z1"dU25q^ȺI1n\-Venzp63t& ,όfL?ӣ+yt2NEdg#sdv7]ϮN%r:MyLQI2=rO/f}vdF>LjӫBAÓShg +g[X1E%[;EwV7=7Ek#݈h[TF! [0(~fՊyCգ!ύowqV闊K148N iąhDaʏ5f=KMtW# +_h9Tr%uJ6:M7GaT[xlDL~ $R4AW`-C8-T|;9i}/x)WVwj"͜]Rw)mTz6vlbԯ~|z}M0fw1Kr ߠ߷;\~,뽫*6F><2rטlݩ&'G5$-/ƥeL>( +M'W^([A#Py?αU88 UB1?x/^[pVrrzn$7:}lD79#LVHN]mYs_,|\Wtch.\9jM!L~PFM_>ZN|yTJ7iϊA3n vb~~D{C{#j$2-A<Nx~ Hy(dVA%‰FS4: ӼUe/!9sQ1:[]9&%r،B"0;Ez Ed)dhyG"x lU- thI!XfUO C mP%KM:[zc~{E'faB'>C$*mcFt9W@bNZ"p)VQ 6 Jv/ + +9|jŠ6K:g(l^t?[+vȴ}{K`Ȑ*͔1 $ddnz3xU@+22'#X S LFqe̵Vk-7] +:D-Xܵ{NaCoFDž%lt",Mbi|axkS } 1XI$VD6p=7/x^ʂh=m+p|[@ܜPp0'U*9+@Z$u݋QkM⋿O %[Rm~ +zoW~f_ @fڏ o93t>v8/3o@OF;` /;7OCW!CCBĐǨ jxp/@zUH$y҂}B"8 k#je\z>Xs돶SzO1&B`}<1bP2i瑭,' deMö~YpW.x=@7W[o{ژP ?|4 Eۇ=<ݿվyQ%eѾ}_*=}ϩ;hL\9h}L*?C_zk'O*O͗Ͽ՗?͗zUW$7^}zkW__럟Ϸ:g?/C!n)7_g?ݪp8+gw/xU?__׿ݾ/՗{ o|?|矾_և__~{͇׿_m +`=76ΰ/7?֟/vO~?w??'So@"&[b[?oobc7o_/o?ˇOt֟{7^9@^n᧓8EA<_C17?L7}ێz| CߚQ[]2Wn 8vk[Q&oת?F)iۭ!us6scm/z.㓝va*+߮zVh7pY*R[N֐87$vB6D*!)bRj3z\K쳤nޛvm** =-kw H7oEt@*pWƯ2.d`kS6VƮ0x*qaXY#sW`ٌ=*T$ԭvcHMS5 +8@Uuӛ\ShˬVⷝ1,s#י $ͪ).>ţl[g+%~OЮẠ-.9 N#(k Wnc[ ST +ك(G+=H *EUͫLj*׍}]OiE~K,F`e ۅOH|toXZ[(n_ڶA2S + &}/LxHb~SpW'2-= 8ޗ~ZȘrYC->;u0/K@ji?$UZYD tm3`jr)^2(u7zI UPeI#woѨIFԔ64(c5:&`,%k|Uk$>T7KgST)Cf*چ.*iN`xDe>)ن%+.Pօz=zjTG.ǫ) +bz1KcߒV[hV>{vĴ㘏ziVlHĆZTj'uvPoQ: zEtV-aE>DHjImWsBH[r/u +6i0%)NTou,vfHk ]/l#t#-lie +Ge?km6@+4=w,P)j^ z tUv`#<}|t@1 ~c8 IvB; E˥ISW@i =~޶4=z[f܂%l7ly*XZaӻ05\*jOuV(ՆTwyX!)u/k0Sy7{4Qc*kVo*l/źkO;S-1sE_ѶGzDot"c&dKW>RG* uug v{&'m@TЛ*v[#lERI@I}wr5ؿH 2t (~z׼_HkVtM3v,<R@W)=pT/͸ Πrg!@#NJvZL )\ƶsm%N NRG[iShRVL+ {S9j +_t2#=K n:b?$8_gU*ܧA~+4dzuه$\Df T7).VJQ;lt~^ՂTFa.!]*ƱVX>t0rHIV+Jqs*lזI>X{:ݞTrs4a T~t SJ;g'8wYHhE ${-:4-2IˇxF`A؞ey$u,! PL\HIf\0 ZE(uX1AQ s!A̻U _eWSLrrNx, 8{N=! %&"_DkEp^>wҠ+paaQ-uSX%~O,\KWb|a[^L_洁:Hٌnd_'MjY{e@R*aԷj!͓bD/<9`;jܫg [{1Agķځ"J +b.vEǔ6rB:$03\N`L5C @D@s)dviX͍ K0 c܊Էu t UjxfćD ~ڶWX.%_hȚ8`fo#&wo1:y_f7(Kykg$p~]=ꊻcSrq2VI0xe'_#2 (# =Wy9^rc~K>EW>e?&KeQ!E0-ˈH*yB9@m#8 "b#x* vYuobb؁T6!'4Q4S]>&iIJITYYHzq,v 1cI:]=Xfl®Bw_p&Tf>-u 50%Sf]7D 5͋A9U kHi)) -Dg7B)XmS(}Je:.G4fw=.fDTgIm -$qh?5 +շA4mńRL:x[m쁪9IG[.k-l@clݽo.!u9T.C\=mA7K<|XXۙ=~jz*V-81-,>hT +*cP%ګ[ bK"FϱYJlt9.]L^p@J-OIeIEIBӸ#("c//vViiAˍp5z:$sKgTG!$! mI1QtQ*6z wbDp +нʼ V4 w,-K#_FHJTF.yd1dd +P2RI )'H6DnnT DoT^TK|ħ{ںGi:{&9jsײe7‘*g~q n$9 HP=FO +,Fv2LoJq +a #V'PR(2A”KW(@wlQ(ΒzL/sJ%^HT ) Hȍ8{aV6,r#9W-3ma]MOKd+%,~WTJ}`KN@ĤT$PA/uݐ(N-I&PːF'^ I_2 0M5! Ub\"G^CU臛՚O[#?n]ptѐ`9pKDm41OR yjl*Uj5 U)A*ҏ; )k3shzȴ= +aƪ+6V|ӪFT~NXCe z~k.V-YT¼H@Ek/ӅvEE"ķ&e&(;xh5,p/L6њ^P-WӰ[+ SSIZ{,*ִG6?sW?%76E +g& <giC5E1bm{RpTQ;e,e J->7K˝lǩQb%Ze TUjy4+IB*MB0$U1ŎFZ_ >*c0l6>˃˦#mno ߃ ~]=tVs@<9Ofm8ՌZ!(RLj:%/jS9Xe9}( 8'Pxp۳$X Zcd V8-VtQīvhbT!ݼ*cD֬)3{0u ymЁIrB9ż,oYўx Qy* ^pxsO&gl|b_[ +wn.&eTk=sfoF +Y2"Co}ML짂WQJE`ֈXݎ3uT̘Gb.C̑X%~1;X-k>x6jiLhqWwM?3i񟄸X[j= nRV`?Nz&kBxew 6Z«o"jC)!ޯ!u,~bPnWpDYȚ>}tIƘ]a_kU>܆RLzh]A/@ȩbjHWv=XwI^ KU;,$0:!,&y{sSt!.ʜvvO)BՑU*b@; +em1ݫc$*Nq }^/;kQPtD4tDJ^~#ѫq=<%D*/{u1DOUMOtQ+mQ}{(ȝ!?!Q'S) +㞭 8jp[VqzkV0P}:,<[ +L::7Qsuhk.|#ui[[IXϫ, Tid?u|Y +}5;UY)7,XEzN#͉uuؾ9.RO‘ɱ"*>VY" j`cp|QR@^5q AHE2L- [S7Å=yW}U,V9:.쫓GP/QV_Kp2íEQʲ دp Co1ƕ֡uS##/vUpZ݂*,5 *aRNd&ZH9o_qm3~1ֆUFlL&Ck,, ˈ !Ͳv1fK؄Yת&˪nDD0PBᓶ63J6j:\$/䱅q4&@"BUdʝP@ӻ6W +UI\Jf wʞV j$f%%&UJUaV5CvhDҼl~O?m;%䬺j`5UxTt+DuLISW5P}ݒJOׁЩ}3r  :F Q*g(hű~b[U!V#]S;|o:4IMS/HHIdF21 m2TU,7#Z,yFpEN!MWBޥ,K%/  8͠jۦMՂ#뭶`􆍢RxW}IVЦ)$v⽪ \ Oo' e;m}F]D&ЀKޭŒ(}S -l 4vΥK7,{SЌ VQ l[㷝E:v[S3)'f`gBݾb.rp32piv@AٔM3oԒ+ {MXe, +)F!}opt^~&uI2I`Q &*%@<Uڴl)Ҫ܀V u|7=mwײx|ZlrL6TN5P6330*VP/S72eRy:ԝV2`IlB1>I$BYf~jo=*9 PmﴘRya[31:WakM096|UZ`i{)ϳ %[r-)л?EtB Pu +9Y|OYJp 4*b'q0=-hO<+$0Z-L;25(TWhjm; iisl M|Z >~9,0`|r,$́̇C Y0# VZHg$K&3('o LnІ>b6c;Nb±PH? KнɤCb>=OI: PUL(,7^5Ö6?R:^Zm!/so۪Î$WT@a$/ʵFKAYVB5#.aR6/U2WZ iؔvvNJym=-{ Ce* YQ'[2]2wqR6E0R&XŔxbKBs!uNu"5C,#bJ(+ͺJjbb7ͩVF&j;E5n, :~UV<5#: ޚzY\bU ^XHY@!MSkL(~,?=3T+'m{0WAdٓ@C*}}9Va|[&u["yҩl#<59sw;~WgЕeX*Pde}TP rD +h쨍Ê(;IPXڠX"vӒ +I q"㡣&g5qJ(p k3W +(ŊEy/q,8|jb!.)4YS$Ԩl+T6OY>bX?{)QW-$dK$e( @k3l8C` s]kU(1B(<ҙ(']UU%tG'j15 -j' n͑Ⱥl~ɌR/_͕\.H=\êʸ~ }5`)ib5:E* +!40DlmpeuNaf&b3vL«ͱDAm($B/ڬ7_bq8M%elSSLЎ!ndu N.祱N.ug X +T\jO6ޕh"'2i@.Il?3m!zQ(0J!#:L; +Nڒ,Ԅ歄Lցo]KuƟ꒬95!(sx\#HMs$ +!$EY@ԯ̺Yؚl:x5FpTAa7c`~Z b/RV@#,,k$Ͻ@ jf7=} 9K<@QkTCND|_ ex̄( O]ؑ=;}Ks0՟l[59y= + B,g &W.5.=/:wWձn[=](fۓ AQ<,zdBbW"waw jvxWe8 X*+ׇI %(]}WGF?l $\KC"悇?Ldge";qf"UȎ`ȮoHd|I:!=re}U'"ZLdW:ըO";I&":]f"C2!yCdW &"Z"z7DvUe]UHdWkyI8I2!yCdWH2!쐼!x!kc~J5DdF";O";oH:]Q@dWJdW(M7'"1ܺ!]I0ٕ!CzDd'ȮDvHdW(7z%+ F['+܉R0u'JOCt3Ȯ ":e$+f=Jf"; ։tރȮ_` +Dv~ٕZf"bԁȮ F"DvȮ8R0٥4슠"o]z$+U"Ba$gLdWDdWOF",oNDv&"*xW";#DvEَU3=4`yّ>(5@bz!4 Ad'HdF";]Ad'>ODvDvDdy<\|$##Jd+ODv&";AoDv@o=Y5١&"JAd'k$͙R0/] +g$Ȯ.LdW:`sF"H GLDv=aY>$L0ٙDd'Hd'g";#Dv>F";'] C0yz!L0<3]q$+p-?:F";] +&"&7ٕc}CdWn<&"!DvEM";N<슐F""zȮz$C<!nNt'1&Dd%]ȮhٕDv(.3]D[Wsx&&";ǑȮK&"ADv%*{N$x"C2!yCdx&d"Idx"i'"r7Dv0HdȮn06!#;)9i|R0uUG";"oDvHf"bNN>U^șȮK&".";VLdW m#ant". ΩNo"cMDvELd'DdSDvODvE#7DvLDvRS;w,QJdj]=ړDd`"Ad'@dgGu";~?bG"@dWJdODv'vȮy Adt"`$y"; Ȯ:=>K0|!ޏm @d+2jNռ. ȎzȎ`"Hd4Q#@ڮN%=Y"R";b9";$u^(4 !fd&#>q?Dv%Id|&Spu"SIdGa&+IDvE8";D&";$3$O";3$]AdDv DdƓȎ`LdHdWDJdlje&#ȎLd1ّyCdWȹNDvf";Ȏ6qȮ~03W#7}Cd'Hd'DdIdW:٘DvH3]@dTP{Nd3qNґNtr"CzTDvDv:f""nȮѫ%]";HDvUnaW##$C::Dv\嚉 +4 6$8t"#FnDvl_'q"$v"AdGe"#L=9~DvhȮ\Ld'5 #u3)7ّ|)5=O";G"߁ȎNm8ډIdi +k"SDAdt"&"; Dv%PȮzEȮNw$+rؗ^oUDv%z1##]Cމx'DdGvy"#-$S HdyӓȎg슘K'C>'";)Ȯ #ډ*ٷ";9!8thVO,IdnґnUoDvxDv +Dv8񀥖";I!( ,Ȯ~Ndg";UNdWDV;Ȏ@Hdwݪ Ȯzt SlAdgsȎ֯Dvl@dWW6a٩`$+F""W";6NY ] $Cd3 ~&+nkDv%f";'";I&";$oDvE5#7Dvl3&";67DvODvH&";O";3#7Dv3 ]@dG +j"Id&ȎBȮȎLd7&Ȏj7DvUD#$N}! Dv|CdGLdDdWy!؟F";$O";r"AdWHDvU/Dv*/3%DvEȎSg"W"j ^ȎęȮ;"Z";N*ĄO" +DdǻDvԃ>Dv&;"YIdW6 +";";UNDvzȮnAd͑N";Dd({ɣJt]u`NJh cDvyI<!`SDvj+,>I$`""S*AdgNO#7Dvל:\ىIdGjq&#?_ȕG";eF";nNe&";=NNN>@ԫ0䙈V_쬭f$#NNDvU7DvH[DvBdّǞG";&Ȏ1UMÁm$Sm@dGDdǾ j"֯DvX$Ȏ#Dv]Q@dGȮlLdGTg"SW+Nኁ Dv*gx٩a"SHd'Ȯ | cNDvX>NDvDvv+6!htDe B]y#3SU/WoSٕhH*;r>9R sS7Led1O*R z&*RwTv(Nuf Le=PQ&*;$3$O*;TvLTv*"ߑʎx$#]]Qb+"CyPLTv8QM5'ʎNʎ7jC2SuDegʎSQ@eWk~R!=RmC8Q!tăN6#ʎZ'҉DeIe'@eF*;]AeWTvt$NTv<򰤲蒥N@Tv@e*R2Q٥4p'*;aB<4J#] +&*.u*;Bb]He'HeWeC6QI0PʎKOTv@e;\I%n%V0eF9]=U7(T5x7͙%ByvS@PvʎPv;NBBIxʎ eQvn(;P7N5 ; eFa촄H(;E7(6#(zO(;y4$ngGy(;r;NBB!Pv;ʎ7Pvx,gN(;vvRe":(;v e(~F١Pvzc;.@5zUveG.(;m΄oTe/㎲Ӗ⍲יQv$J(;^(;ʎ&o:N1e7N!eBF-9Pvx$NQv-Ewf%dz,!1˙ ;I8kBw ;wVA$C=ޫ4u ^wRWDVdT z 1bם ]7Nt]RL3Ķu@_ʵuZVֵFI쯥q0T|ZuFN˙xuWT"l"I;N'nJxꦐhS:j? ?JMH<趀Dԩ⼾u=tvt"z}TIi ӭŦnw5tZH_Žj갮s 1KX@Awij^; 8/J͟fs5ϩT|0k +Yf_*&w0prZ cΑ=b'tNs4 լ4s]$}k.+=2p %Y R5NCThq"ٝ]qNOΓ8gOJqQ/Z:O✊l"N`eYE#]{s^ 9Œ9;s`'/!$su&rN +Ir'r4bν/?kEL.zgI38L-szCaO)$)sX,( +4 9W%"Oh"),>~oys>p^NAnN{,ɷ3jN\A#XWIhPAƁSQ̝WDVLf48c+NSsSTtrche$Ϳ7\hx˩J +Ε;ÊձriӋ]TF`4L9h4HH9 ;QN[rT {Ʌ89Di'tLggɩ O-!^^˼@߉$bMsm2E{q"f3_ۣ !Xp)ZyVmq!/F#R U9CrR'A䜉+K_ ' !ifń+d9r;B5N/T}&Җ}BN%>k!'$zBNjQ NQrX,φC!мj&D imNSF;AyM>ý-@CP%rzC8qe8``wD?n +;?nfX8%mGqv3$;hu +x ha&Or%]s)$T Q -N+bȽagqiM~\qStzzu` +3=N_XQC6n#8p@_[Jms4D8~L u!kG=9pR,8)4QYb8p(Zgd?2w+gAw&&28B-90p}_^}v~ mf]PPH]TbPঐ)pK6 +k6MG,-(p]q WҬ5.g׳(pfFSNhGjR਱tS(pK +-Sl^Ո8@Z "&u2MTuƿqӑFOriK&7tCN#K /=g_7)& 3'q/\YY۔d&=0&Tn7Ӗvbg߮ȷMF:Z% ľi{|sp'QC߰maA3oK؉oS ZOaiMFD`FY[I{;ݧ,ޤr~p+6ggT:aޖh7 ooÂtluؐ=U;`l] }Q;|HdS ޖަ_NS!w[J-9n͞|7b~z6iiBcwS x`x7B)lBq߭t &O*L%ݦ|74; 3f}wKRwS#ņw{W\⻱Zn`+JMg/co1nJfwb)df0 &,oꄻCq0!p7 9 >stream +i^Ѧfɶ uMB*MgS-&{q`f|gS,~cU|fOvjsIfS7֐a8|p 8JX:שl v<>6 FrkwM9vvDVPcMQH\е+u8'r L;qMO=\Sqqa76c?`:ikw 'ִշ +֚i\`;Z#IZӫIkiZS]pIY5!k=*c@ r 6U _Mvqͨ`;]M-E*#:^y:XzP2q/1d1υnפ5kNL汋@i4՚#j0!PM"uӎ!j9ĩV`.`d^?3f SӋ}Mr\G}&JM|#b@j ƆQQ F?/(j*~l`BFG9&CM\P3@ L8|We &;ׄ4VI<;<-24it_4C] hB'4= tZ)>ftZ1,qi%2; HhP7 ;;ŢN+T/?mӤXMdbiFĹp峛 v* ; $PS4 Hz)e!;:MeE;:MkR8&BD+y4Z- i$)Q6tZ&9 @+Csr1VuӶTl>VkPzY4^9/nT 886M æO$l۶ +lG_ رi +!/H(y6MAVpDRS"tY$?qسGQHl~rӦM":⦑ LĘ7 'Gহ7p4X<>ԝmYG74aM3x7ȼNlQBs4lӂfl~qHOqf ^4^iO4!CM+w$䂛FMSjJ7,7 O&y OƦ%i,lI(04eXMjOAM#{iu9;6g])&iʎEOشXqM٦ϱi4WYkM39-V cOMl_ыdqL禡faV[l%V`3 ̈;5M[/i䬩7ph2<39юO7&uMW>AӐ)/Nش:kf{޶MrbǦ)#*i256 P%h*fW`"R!1&3V)L8μBUC徵jfR?i)H4LR48Ǔi)~4w̴Bk933 g|@u!4 vd=-dq4{49k4Ȣ:/;8piT-\5ǣӁKCۤ^J V8 #* V?dYif`I`B?,VZr@R,MC2;K#`iEJĈ&X mx΃Fi-d(K4T +<XMx#cm9cZ\+ hx2+ cVKl%쬮:+ g7+MJoaB;+ 4+M V?DUOj4 X+bg~V]|ﰴKj*KakK{M!_Pf V+$pai2PwXK/XK$ais,MQP`?0 /:qᛜ`mx{SrBA&Tc6wQiՈ4v,-@1Z7>b-&);)IiR-ji4"T5P…;)fHj)PyVLJӞ-[R4zt%Rw,tx7h!4X0枝t l䰴׵%JzZ7KScK@5|1aiK$؞9+~gi;f1`i!b}"]r}MoۡjTi4m(%Ґ4+M +dI(:g 4`UҮ_4 +RHrrJֆFfdz:;9,m)ɞuXPOiK{]aL fBsr[#]0 r00MLcX,rx فiZsUy ^M+/4}ІlrtJ4l&Zcdv^/mK,r>BjTff"La:8iZ[^¥)` Kcn?3Dqi +\:b΁K#!PЬ[UZߙz/8V]sVq?gx42 +T{SyzDJ뱣 R wʜZLJڈIÂm]lD wWL4&',<)gŒGSVQc'b Md4 Έ_d.T6"X4}cﳠhzL 8,|;yhSH84kД׺@gW? +M@ +̚DU&y2a@:o,Ip2r[Qeq͸0cY3D`lϠa`&n}x' ~ '~,ZpuM~6_&=]peW]R˰KЊ PF +tZr[gi<./cCIr&/M|Yas_!7-/ӌm}~j>A>$~T_1yPΌ/7CnNA/l.+~kJdvvLt-2֕:?;L|w`!(^ezo`YIYr5$( vTl..cG;2T/T>W[2g)Jm.Y2#\ +%Lmm(J9e. Omn#!=e>e=er=@[2]@. vvx^f1>̓%@N/c%6̿wzTeH"jK6<L560UcvzYqG/39eZ^1/C&ҁ%^fvx.6^e̕9&hm;+S˴:gYe:e_ė):.tåˈH>ebɨr9W)`嘇 zlN/[66;Ȧk2 SΚN+69/Cչ +|o7~٬J2\eXR3eKeKu~YRgNnCUܝߺv~n4b%"8-aM5fzX+8d=puSfS X|>v.Œ Ea&b;$-̞nq7N2M +ڛ}֐f!f Z[ƞh'q2U֦םʺWgRzۋu,S +8R)eB F2,3J\W5EA&U6F18<]-}o,M :(1|#ꑟxjV!c9k;)hc`J墲t-w{lಮD`7D;bg-.P ]Tы$50)eDBm2:wn _&a`X1J f0d a +*}bNl2>ڠ,~o{hL9 un-4Vӯ8Z6&w'T+m]O+;7د>70MW?[teϊ,d(M+#R?FNĒJR-KeD6ӷ?mnL`B6fGF LPTIm>?ʅײxR҅ +l:G$y2B)r#Nja8 {bi/eE>C{Qw W`QwXt#&ȑF'g { +[3{N%rJzId!2C2M} j)y`^ӭWVuAFO :{ ux Bi"7vңf^k(幫]Ai_le^)MT^:9h)֤jmHባF`NQ Ѻ%F{ȮexRO:ERQ8 |=1hH{ +NҙQ 7_S}=:YO8.h&3ybDxGRCOK?kyFRAǸ*k/Y.sDQG ^YuFKhSit>:,-2c>8 +=Wme,Z&az¥xIӽP&~È[CP9sxN`1k-Yni *ZRcs6ACv5fJJ;@ʹ 3B9ۂ}Oj..(Z7&?VϠRcS|ȊJJoh=Zt*j<ֱwT Lk!6̚^9 ,)u7ǝ#'lZ]%ց#̺XoM2:ʐ5tDa]{{v!$S]-2-)u -}u1L5n0dTGh*8_: +;a>=IuX.Pq1T*&T OSVϮe=KROd6/r |xiB޾7w⠆ )/s K-** >~77Oz)9f ņG &MX jA 86oTVx鵝&a~e>#wex)]w:bҬɺ$ +AsZfqE͂ڔ_CQuc] +Eb*Wu {f,Tڵٖ,r딲:8Me)҃$L+*hKNR[AI"+R!Ҩ<&@r6R`w>}̞vڐmlsCƩ?,mev*KQS zh7*wIBkƳ)vc?PceSŎ;,Y Y:`YKWVvڇ#۔k]ɵ"r!Ҳ464jO{OՓduse +YoV0eT(xn~E7_Cfrt[O͊Iٽ-~:JYiv&=2=FfA^z%u6;gR9Yyʽoo=v[T+9 +s1EVЫH]h7 r {cP=iC,sû\i4k[Ůi5NYCWp*jM.VW;_r'>-6º0qXznZY!>c +yP5w%k'FQ3tUNRw"sYiRyP Z#7TaoF8C*7g65!nl(O2"ۯxp=mc\L/jdNI52>dU컪)'&UMۣ.T[6j隇孬YՋ4;Z=(=Q̩+rF{TØ6KBM^vn7(ٺ ˳WsVv{qn8DKirhZNK)C{qriY9nյ"늅˹$:_]ݑ?O) '.7; Hq]8 ?@ɉlrBW&)N?!>f1UR>cKvw[4}mrCa1u hpXlk*A|ye+()~sZXV;A,̺v],6iyO'i!Ъ~^p8B߷r6ZiR?/D!}sAaٮJlK d/uil߄1%\}Kn)TV vr _f{T9EB @obnT6QKo^j}56ܒ$Rm;EbźT,a7mG?53i +7m5Fj<9e/zeESeXYF<9KKBYJ7%*E="M5p⺖~@CW</c%w,]3%2-ɶA["̧kH؝[‹;PYu4fRĦk5# +0x*{٨rz`/Ԋh>zuqK3JYNlQ喢ެƕin/]X` M,t.<찛Vȁ$Řc/(,%-L'@F%f'\C|/G ?N_a{ܽ.7J<srnK^,gYor:'>NˊrV4ezOZAz "seZeOӂJ;4/֜%$ljM9qRUZ62Z +md;VЛ[䖬n*% +&oPo:#2*{՜)m-yciW3yXɅ:Iy + wT^KA'UCJQ! ܐ5QY:ESj,Jp`6h%Hg SuI9:cB hFaxpI%&CDiBmlE]6)rRذsKa<Ѳϛ|/ +0p2]sAq +[9J4"Nc= *@T] +3R)݅J_l$tf;u%8\9dO8W9RL[$䓈,.:ԉY Cs(9e{/sYʌ1,8DP~ Ъ1@)1njuG$BZ cc Itg+1oC:V@*G, Mk,t_<{ƜTpԕzaZ[)DɊo{Z<)rΡmEUC<ܷfl1<obUU9mk'NjӅROt)?QEJ*ۉj/:2-&NW>0,KjiW-v'n Y8@7ը@7N,oUg><ҋ݋uvO1[ +ձ#Q %Cq5n+'(I]şS U3V<(5٠AN25:ͧP= +?'Ŗ!zIB +uڡj;reHQyK_Js>^1oFUn/"& +ðh6 ?ggGE]}q*{kx9ˉ)86Ƹ@V\ZWGIMe&n`<\zZʣ5QZ䜶Lj2 ;ά:B[uRfVOm;khmk4zPZ$D V5b^'@UJ*[)'"jbO +QhP01(gu+5}_,ZLhL {ѱ @兤[wtZVʴh#-j꽛y&yGqHФ+A0qΩUIj0yuv heũu핕iq'+}L V4ê£f_oDD#>Q}GqO*nt&Ki׳",f3!籵ʝQYY> Kֽ +ځȾ6a Y!gi uT/fUrq47fM98}K`\nnuMf^H6JxB(@lzlD%4gZhw[Η ?C-9W^$.+_n[PUMrn%KjfDZu2j +-XJl0b^-:KK8 ?Tnݸ3 =,v=Z/Vno9T9!+4Ё<evVVM+!= +'Wk,BKCB#N>5ldµ6ͨk~Xk n&BDYclvԋ~f@C:LƮqHX=' %܌8dzy%_.)VNwxڗ!Y`Y`,'19#Ӈ)dž .PIQ&Z]0TOTyg4 =Vu[tQҭ{P0x밬 +[cTǪ|,Q;RB񽭤̞x WW!1p&n7/&A)R qccѲDvTv7S*bf,D^iOssio|+B-XŁs&8脗} RIRhu0}RЩ$vMⅿ׽x}v\[v>r6l٬GyEpkx+ydC5y}DF1zm;( !E=D~rtXT3UpV%wvʣ],^Q LejzA~\umuqWRMŒ*+j62㜠tb_},(_kRwguEk2} Oɝđ:x{l+kmdw1߃raifDz%|-VvF.+ۚ> u֝"kZ/]P |>R<,֣9%4iZ~a7lk,-ۿfťdeع I奴^a2)? -iem:*pkR"+XmPo 6wHH%p`Nov-0!9u y8Ejg?G߯v"2ANRfd KR_bMpu,~1kL]AN']U:kTZH[ d$z`(R µްt"C3 Se}q>{+). ]SVn8]gEWD4O2ٱ䀙E.2~AS^'Kl" np/Vht5A*˥:1JTK]!浦琾{vi.^,~ZPm&Re-XX = +8nS(rZ-X0AOThաMӓfjqDM1zi8KkK f!#8E6OQQƧ ΤQ&#ͯ]xN#ҝh7LJOv 20H(B"+5,^,ͪìR1MKG͒ eeIiVuE79c:A$?47o@|ĚׁH)ZСL C-p*-frr?Io4=F|^m)>?&ws icBBP + & 0TLY.Ye˽)@TDfB؁Utf{8,GkcԠ2U!iS +8z x}߈?@p(j~`8 (k[V8|O')#xkL*uF0M 7R@6l8VvJXLͨ .A n@*:jRҖ%ȁM-*>^g'`y[p oMA5lofm|O'?P/ Qi#RmN5})0K=vq,,@TW;G,.eka, 2 +?[vXk1<o1K},ˏ +@c3 hVqJ+L$^YS!6DP[.;5_uMJFTXjŽĄ-J7K<}ć%Ȼ5U f=4 +t?#XG<j#jA +XFlLAj8V9!DzVgT$smem袥)4UJdAU2nTP֭K#(Qy &X la P6ݩx/$9f@vvIkj!K ۺYp}4Y]}.CrkB.6^UI`qQT",/S#Vڭ7 Vef@Q>n)ş4%d-|E;8ߢm6n`M>Jc{Xn)iVMTjküA +7S1%%KϪ2^2J_:E9#zh(-䴫_a:e;Mk0#sߛO%!F>Zp7Ƽ6pc \(oRð8pWb ͒>F*} +Y{BxG&Osɞaa Mn!͕++{V +?tV3(ނb+e׌"bБPǂȍއA GJ*JdEE #Ś8yP,,{{%TIi¿oB&p8Q6 CN +[A}MjvS\;.xGK1e+IJߨ&_fe۩=@dE*Op!UR ;.e:P;^枉~E]Lg@yKzLΪBGMSIe@+U!ٵA %[$;Zrp| dg#H>TJ9MgO\Ƹ "ÏYYvKUMСAџ܎J DuՕ8{.~Űaxr%6!=*̏yKj Tڄsb'eK0DUM䅎`jegS9 dJYOLoZ$Ny6 5R+|N}sKqa699b +O9jiAU .y^%{S6"v*bJ+> ۅKqgȆ;K'c}sGVCjh.R|>y.0, :R%O"tL\Z+s2gye"t ? A`ѕrm!x[{QITʹq7( +()>HO}7Fݴ2xJ@vzNfLVBgD*7q7e*.9UWu;"qٜ,3q\EQ*R*b. h^R_\ElWQJ*JU$ܚR2Wc^\En3WQ&\(C7W U KI\MvUԇ*]WQJ*_*sye*/}q5mefU\J*ns狫ȅٹ%bUĄ,q5d;?WQ;U\J\E +LWH~*}qĜ'"Qϋ}UԤ^\EU4e**R(*RݒRWQ›h늝0q>objU3q役T0$);WhJ\EWQ-ht/Dp*nU\rp+;W܋&s2\E*J\E<WҊ*JN\Eh6"$"yHӛ(9sd~pW\EUH\EUeRWqU;Ww7W#UPKI\%WQ{DQ/Umv2w\%WFtpIo"r*J\E)?dWrT;WUX'b/灲K\ť$⒃hsT*iW7WQU$JKI\%WbW7WUG0qke"6hn;WL _\E HUv*.%q\E="U){**>Kٸ4d3WQWW;0q8޹7Vo`2WѶ;W_7WQ!UTx)qU?qkL?@WPl*}s %b**6H$qd"ʛHe*l\E{WUiK\Eo"eHds*r[@v.K*||s\Ebesf\E~onU=q!2Hpk*R*"\EUohl*JUԗ\E&{;o"lm\Ev"uo"r*R8U`f*bdpPv*қw<WQKH=SHSԋ'"P{s(U1s1&O\E>_\Ef/\Eד(U]FyWQZ** !q sxq\EŸ3W7WU4\E×$WUT*WpY*|:U4Wxe*UTlWo*R*ꕙw\E"o"YUԷ\E7W*KwWQ0sظK\EX*rWzq586Ɔ*Rk}׍AeWk*Vx'UUw*f"7WUK3WQ+\E<WW*WU4UxUDN\El\E)E{*R*WQ\UUVX"oUWQ"e0q~sg +4*JaE6l\E /qM*l\z޸č뛫HUTU,d0*\E}f*jU^ōH3J** 86b oUԚWʈz)qYW)qk4GMb|;Wh*M\Eh\EUR~pI\EK\E7WQUT,sI3ع%?x&42?zf2hWј;WF*SpH\E:W/*K\EK\E^**tg$bاUT=sh**KWݝAoK*6y;W,\e*:N\E2/"J1*63s{so*J\E)?w"=k*O\E\E:u^\EU$s@UU{%2WYU}oʪg"&݉؏<{*rW4қVeqIX$F\E +v"PUԒU%s*RlW2*BH\E-3WQ'WY2qun2W6WQYU$saU U #q)عob~*\E\E@v̋;&Ul4?HN*jUd?2WQy?Z]dJy2WQ"%>;WU򃫈(țBYdb{U_\EClO΍);oU!a7&87?pK8靫=((W㋫UښR\Ŏ湸sV*A#sEh曲RErp QWW:G,φH`Ed,r^(gZ7/O3ʢAVdE00o*%i[}YQJ&+l +/ɊYYQ[LVd~͊k'+$"/}%'"ADV$$&+ZJ~'+*ɊYQLV$֜Ȋ4ɊȉȊTȊ4mdEv"ɧ7YQDVed.7e'+.ȊzLVzȊ|DV0QdEw"J"+/}Y&"DV\J"+.9Ȋ@NVMV$edEeoLVY8aFɊlHYQ<<<Ɋz2Y^dE3ɊnEVy&+)NVdz&+KdEdZ~MɊdES^dE-3Y%QdEYDVS㛬Ȋ4&"Fobf'+JdE/"l x囬 s"+jɊX|iIdE));Y䝬I"+bs&+R'[_dE7YQr&+bƞȊzdESȊ&+ȊWdEm%g"DVĈMVDɊ2y7YQ?#l%"ʛ bc,M5YQNVȊKId%YQkLVPMVĨ%d,d%Y1̎dEDVuFVdMVɊ(;YMVgwV?ȊjDV\J"+.9ȊYHj"+Zdx#+*P1 'RY䝬Hm"+ZHEV_0$"›ON"+$"mo.i"+\&vbhɝMVdNdEYwYqʳLQLV달ݗȊ$b3woyv"NVo"r"+bȊ>z6"N;Yq +hNVv'+|uގ勬"ʉh ;YQdEȊDYY7YQ!LVlEV\J"+n)QJdE>EV d"ʛȊNVrKH"+RەȊ7Ɋmh"sB&+ʋYMV;f" ӝB&+N5Ȋڛ%"ܮDVddE@3YєYqAV?3a7Ɋ$&LV_MVԊ'~eYQDVT" f;YQLV\J"+.9ȊNVMVl'+g;0 +^B]$ UaNKԢlr&%Yd=A$>Qsa:oLH"P{Hm.HԾ{UHO5җo3!ĥ\1.H6^h^#F#jEqg#FQ;U (^mq%v-,"ۿr&*b+ ",GBp;Bʼn{Y&1ݛ!YCe:7 Q_ۂJ(iy`X!j)$ΟĠd"Bgqi@A;jotU̯!ĩdX2P7H거׉?g+/wʘj&PO0yD9BXS0UZ p3S 3I7$)؜&mfHg;jƚȆW })5y XְȼX2NG:ְ ݹ.45,Tp5,ǹRXOvkXg\rKXNgƖ5,g 6+&ذhUZX8Ɇft5)Ô6`C)$s&PD&a9}=eDg ߗu՛7!fd2lȁֻdA 6Jv} `Ҭ^-s ˴aV/\aQkR+Pe38J]TSpqA OwELCHC=P dg-u3jC34YgPNЂ L4`K9S N1<cLUYp +;p0oyZ*z뼭g` %uѤхMh>>>y8A0D7 Q2PAQ9zyD1wxyT/lv;P+I`^}Y5 7m 9RiBƀ@^Y}גw9@LN!ѩ_S3P.$3|ֈĖڞSf\)D(@(qϤgF)u+p);pA)TfAdJ|%0 thnBPڔu}&ɮ\)Q¥$LSA>A, ,a +ʗEmQ + S F` `B}@Ƴ(D)%\0&t-Bg<8(, &;uYA? , +?JPkyvGO,GLNTyzfn LG]9bUv;aP}upJmpAǏbx wyĽ87(KعS R1XV,*Dw)mAU8dJN7)Hӽ&QH +2|:onM'(dH,a NY(tJy} ;l䞪zoXWPF +" jyi\j`1{JJ8.rց=j#"D\rP5F>))JY1BP2O`9ja1Q?1ڍt@)Ss(ڲ,ÞBL%QAǽ,1ZZ"Hlo2gwd{E- ;r<_=^9)HidP"+~eKzB!=Q{Y"h{}A"([@2f1uKRA\Jur_@B+ZRN| !"@*Y@V>/|>:w;t*$| q-z 1;=(ةv!a^vd%|9遺i@P@| Mv| 4oNتy-$VI0֗ | N|$"а1,hwJAt R3s hspMA-TA_A20Ay  +4 G $+KX &A:sOA& BP2a$GkA n`ɑ% +qA"7!A} A$HmJ" +b jkYL!hg! ؼQ0 `y" inR=HdXlg"3ND]qY-ArDPy{2DP~"ȤE~ JQ!d_"u@!+$<8M~˽|_#G}<'Tg5+>Pj;Epgֺ;Pk⑁6 +כ=d; 86Pg>_@/h{;BC!ǽӾxm `Fmo͔/Vx l0`A +,JrѢH + R`$j`ՉXk8@¥H\vXd^)P L +$AlXlQ7(P(:n +w@4BF $Daos Bd _XesBC(PWxEJ,-SpKMǻX&#i^LJL܆o59+4b;PtǗ 㺿όP3,P5`S\@ΑsIS =O@UH֙߃ߟJelBZ׍<@ +-<(%vI7cڽ<'I& +"ϛ^iݗD挲yzJGt\ <7O-PSPO=ie'QiRwRroꟆ=vY x&Ozw* @eClv;,yOfia{̿4cHb}wz-:k,5}Y+ӺisF5W +} ֟d8L"X=p Ο)L?EFv Stn-ƟK* 2ApqL<Ύ"/.V=4~WNa4~wTJ-wX w+i#40>xlr"=>--s}tZY᥽WOЗeZ4lrB_LC&(>A+(־} bByc>}XX"> ,wV˚)A΄>QOeP\ ks>9Xx0JIhgta+%@_b)>խ5}4s>,|>U=oTmH+E|(,<g'B^y*O"<G} #D5nDW;g8d"w (,PbZ '` :]Hj]^JTOi<:_?ܼ1rvݶ>tU/G0W&Or'Б|_tχYez|ԝh;W|:ճ?*-k$8_QڏB 'ʪ"JBL8)ܦ-|,m'Ib} Wr+Ҧ ?,.aN|1A+{I|XEA,Lt> +et> D^t>U<|li*/_#h +o,w<cϧGv!0@oPG|F)·̡X@2~TonA#MNt>mjN:rvV!|uCt>7GL:;hU}ź"|P|FϢދW|kyNyY8A3Dq/:7Lt> cYߠ&AƽP+%A+Wd:WXD +y ΧbUx׳|丣 j2۪`ag_p> + hr0ˀ)p>'V5p>XH&4k|fBSz/|OGԠgHc!v/6=*l>v+"t4^BUSb̥bW>::O_q!*Mp>(p>=Vp>)Hp>*{Yl>lyg~ W9|alY|z9(d> md>5+Y'T6`SAYSAw*hB90Xe m! L:J̧_aJ2o`{~dȯX9|$5T>2X +P>Y{ GaC둹 Cm׸|D>?Y!$(|(Kώ9fv!CR,D>)Pg"_B &OöU'$_ZܵBC49ؑ|z۬!|D#+ +aN絑㷱ID>3jn?$aZ N3 wzDtk~plKDʖd'm[r`D>P/"FDw'P "Y/9XiV+C ehT.(Fx#,֑BBm{(/!w4|Ao)L9|Rؐ|^H> "CNH>G ɇ#@$$6o$ 5C 홹Qd$^ڎKD>5o/Z~di{ . {X40=;@pjcWR|c?x|ALgjEy| 5Ջ8e [ZD<>Ձo<>1x|꙱/hL<>d_CSjbXN(z m9#|1B $ iIHBj})@x +ٓ+sH>SPt")d ɯ*Ub}T.|ŐD>dɂ'pxN䣿]FE +"_5CE#@,|5=ȧG}A Ы=ɷN[ ++0?43aP>-ԒxiеFC?|(&OcY{]|z?Z`Wy'D,m^jAcrl?g\NQ|Uj2 ʧ6}8'OgZ[@Eӆ:_V8t/Ь34ccH%c@3PBz2J"#p|ׅCb|#ES̜)lп?w/5<\<)i|^̀1b o3(Oa ƚ GUBGc< ܌ѝh +D S"Ȩߓp9U?G8b]'Ҁ==L{Bi:2%`zW]795g{q Tw֞ⵄjo@zy +鶮 Ng\wTj4{]=L"({KI%e﹣y8AL/.eOW"Q{'`nP}7YN$%+d[(z}&ZX=~@Bp)%ج:TD)ImBne5Q/IԻD)@yj"tR(d(@dɥ/j=9yl&D -wU&c$psY\K3SɬɧcE;Et`)v?Ԑ z nvjTļw71!\BƝ^)OF^,1gnyfDby4oƀ15SX,!RڙfRUb)]\Cߖ@9CgzNFB(VA3ȝ3;$Oɕ += <&O{4ݜ<ɖ L˅&m[3%mPSy y: S':%Ox+m(yX]PoP6e䙬7< Zn/]< + +IU<9v[nI>a'nbt_I.vadC"(yJ_STd[''IɓbQDCf).a䣎)i_GPf0($OeCvq^<[Žțj"p4 yef+vB,@^x\Nlj<& \GƸ3yR>eD*Dgm)dDm7%Zqž#Ng];#O%!062L<} H& H~-$Ox?uޤkQIw>1{*JN+z2y]`-E@lXQ((c>(M봬_T׾?tG-^W=:m㇕2w??|ԍו3wNq_h~EOGTK"{{bQ] GKm8;YzRv^1إdnT驈_falŐZ6*?EDq,$&A$՗7Ӳ1BbK&@Y~aϨ*7ʴ8T`2>)gCngktdoyvк u}LKKywvQ5}3KuD3ݼ{~rcɭNZ%L]1 CUb~(*6"|Ԏ |a.qEAgx쯮e𔦷c$Fщ쇶!ؙ% ++y!2VȢO3ʷN} 6)y`^ӭiyAƍQ",xybgJaR4Z?Ϲ.|^) ǧ/]N^BJS'Oo9qxvP_qmΟmpOsq:^HƘg׊-_W͊,ׁfo@w)[yz,܉䯲M͍5C/ON沚|X0 %jsx nX ٓUxc5V\ˬiG] +w]6_@mmq.mjMFSf?~<}J"c#?tm~4,JJ*N;.XcM&ة;M`wO_af e};,d)o<}%<o2֎I:uZϦi)ZTحہ +k=VJ)WuTqyU㐖X I$9iWID R2wGQU 02nXytk0uȁv(&Ձ79"OcҊi 6pR2yzs>hK).,_ 7BECVq\gƖFx,>g ÖD<ʵ%f<}^LU To@&o` TB[k¬De%QQR&Ofg䮌~tZO+RYuYa +9`]K*>2T}jQWqͫJP +k%wrCQ s؛o612>MQړMNhJ@-TOb=ہw|a`) +3O7%k'-ZQDӆKZ(L@Vo)paCY +}RcHY ?;ª ((:( cM ajq> &!ΊIʩ%}(EVCg|^kc˔i70%q~(=E9ڟ mKy]R ?Sm7|j1Ef =JF 3 Ÿ$7Pcĸ Ҵ_OӖ> OgζbYs@&oɊ+>)* ͹FBX7T c?~q>!g_&bx?T$f ǃ_k=PTO_ξ־dĈ(]Jmj&X܎Fz3109~ +\#EV2pwF PQ5x +NE ӖZqy< 4Z~fnPmu_SJ| j@:e0+UOjK'"-iZaX_M> zԙHYL>>je?cn^h\c)E~NKQ4q"W+*i׎kXcjԜiw(AՔXْr}Jޤg:<}]T|UV]NxQȬDӱ8Wď#B+[ Rqq$gLDl@=U*Q9C̗k-j5 Tb~gl@f=e@ŽZQ0mqe^@(%kqV,` QHX@ج5չJ!T23ng1J +(j2?,K:,l|SkQ]8 Հ%b;lZIDMBuHMNho+0R80PHT&,FdjtW2/(|"F ?GN@ ,h/#b 9WqGuU([Dp8UDk:5LFVxcZ 6z rkxˈ@ˉd6D"y~Gq#6\=\zZC Kmp9m¨`wZaV2֞ eol/"*AL VeuZ@ wCؚH>wE2HyMYӢZ(j:KK>X`QV|d H--&>P_$鲑y}h@>{l@ +ݟCa-r :=5?jJDFRD&~ڝthOHc? !Yh3v?^Z//L}'Ljt"s:Z}جxP$/S qM+oAj)8Ȅgl[=1̂h5޽*<~Y3lƸi_#f5B_̚U0 +M =K4@4G4eժ~[Bi%];/YHWX{0} $ 딻&TžQfx͢ȡJIex{kCӥ^U=xZĂzr6uo U$Ԏ3idoڮﰊO/GYDB®$Ⱓ ˪,ZNT9 +PtYZxaҊ<61PwJ*FlgTISࣺ3z7l'U.շ Ԃ陽/%jftPc|n$b|ɔ|p(E+F)TI@l2N=XSS ![uZF!*VT LE?F*BF X +[(y/egB Jx1-+guJf/b«ڊe1 s\řV|>Y@ Q*-DS a}vr2 ~;UeZNi3iWl~#y/t*z镱> U9/&&RXD/T\̹O(Z_Ep|a1p+] q} %#XEJ]I($Rk&{cTU|thmUP\Ȭ]Đ8t᳈:ؒ{}Ȥrx>FC"^_^ޮ0܊-{efYC) Z`G}) K2ݻǚQh +ؠ 5$rLRlwR 5e LusfP-BKjiK /Bzh籁Ҥ&0%X{md yM! I~(&+}W+*>g[4ja˞Mn2R-+1lq E/ʓȍ[3] bn<DAs) owk %B&4qH)JFPJ\0K"U%ȇe(RNV-2?|n{2zRm>,@A`[_欛%Cؖ˨ޕ^aKw+zӮP9diX:ǘ$v2ijxɉi[/vff^::,4%ȭ}y?66߶юsG'y],ze)|V Dzϭ.MJ],zP9= +x~""~I+XG b*Q%@oZ/kmd?m{ ;lثɐ>a;\d2 \E2@%-(sZl6` 'a"bj=XB3ZK\f+m[f1lZAgu1D>=xRL$mL 7ʔf01K(ݦda`*H4 + ݗmhSUV*i04T/H{PZ֐ߗ3*$C=醴m2" )>,x$=ۭWOJ*$Cx+B=-Ys:к.+@>{Jk[ƏlN5Ǒk#*gVû7T,w Aq/I66aJ4YNSRi-?G>v5wx ]lI2'Y48Q[Wڴ@ R].Tw/O0@;{6#Z`l 3:L6!E[7Ӓl̚]mgZU1kՂl@wD074M]fIv׵ب*RU#X<PZXF +!uUC4!d.xQ5^zAQ\5qO3cZďHpa喸)$\W4>|bg!IFˏ?#jFXpc Vӄj2*A54~P;պJP z@<쒝gW?`rG{m:~aRjBAo?cEa2q*b@i>٧/MlO4o⟊ଓÇ;pD~vQ`'*k4RM +0BCu©P*$Е+] 뗭5 d}mžWMkλ9+qzLd]BߋΦ.5ro05}2-Tc;rTڟ +ؔ,9 j8Tқe-Գ4-DŽnn/J 4Ͳf p u`뾼a'gb%v"1 XTߛPCz jȎwKP2kcmf@3陬iVljY2?}F cf+)j()-+1c, )jh y<fnۢ՝f*6<ͨD)`><Vk'2<)HB K3Ԑ1*rпyR]YN(Mw:Mc$%&;_x[Oߐx(c9.u- -@ZСL!C1eh"CY:'eaD0B[1xG|!_m)>? pi7S٘8zvVGLЃDEeUz*fAQڇ4|(ﵭ:nMTqħ[xZ%jCl +m#N +L)_b }Pi+!]z2] +ǩv3>t-Z?F puX`;C{d3sț0p2ೕ6+GpJ*m+7ex:DΝM iy Z- +<%( WD|Àoװ6P'9ERpeXmy달Z ޲a7"*a~%)q(Jf̼6 n]kCjd0*&}ѩ.0|GPm:;iiч?]KS<"mɤ`e{ܢyHYQ9 ҁZ;\J&_e۩#L@伮T.7xoD92p+\xǸ0(gn_Ѭl}|ze7Fog:0cl7~"v@T 7θ2 ;?QO";S%;Jn >3=*VMa#|%uY7\@@Phodo.7T {pAǭO\rmn$jeɵ$G9gW84?Ve؍ ݎ +wMF50:Tjf]os6hJ='Cdm2Ͽkoù+ +>Veqꩦ>n7 !(hV+_)e=q3`;M VIv?|-e=}xU:sxv~7siAU .y^Ua1) dOP:Yi#~o[Ua>dBMʾC=2u- Z}ָ{oǕۺabX~D'@ce:JnCCiCs&@QZImΌDYUlF`DXD1q-lRFP\j@IRx_}7Ft;ݰr +2W@;ݤA`Ts /3敠"O$Ĉ"'Jei6-U9g'.YBkhzVjvaj$++ +o=7~"rU.~>Ѭ 8-6x +ĩvǨio +%vc1[&hj+X)6)ckmd& O[|:w-|V2tsUX+Q +Mq`*^azӛ~ahXTE:Ϫ[U~_ng(9+;YbMVm4 YQdŪޒDVDIdE;括%LV4(`z&+xɊbȊUrgMdJEVɊ>MVɊ k(s)/"r"+^Y$b~AV+6)\&+;~;YqSvߒX}%0QdEՉɊE,Ҳ,F. +} YZd*[ (^8WӜ9Ȋ wYqNV/dEV<io̔X00 bEV,Zh&bѺ E|=v*;d)XXLV V%Bp7F`EVpum +6'$b-آ`~QXQA+6U% V(ls+z[=sֈ_.[o"b+$bÁVR2XQbX+?V8%g VlVrl`JVXQ V4["@7XQry U6oφr+J`E7XX X[V2n,c+\O`ť$&{zNY`E@oWs+nVT+X V(ml`j`EX m`Ŋ X[+ +{`E VX +ƓUkV\J+nBE X XU| X)0~+Y;X3-?;_` +f+V$b;_`E0 CXQr+$" XI`ŊV|kRŶ Vԋ`EB,o VĔ+ ȩ ǿz2XxZ+t%"1V$ ++?H`E(`E+"'"J+7_`ESI`ťXQю VXdb`EM ?/"V9V"V+(-3X:9 V\r3`E5!+db I( FVXQ^+BO`E{j^`E2Xh;XqSv~&{@VV3Xq) 8 Vl`E~D$$Xq3`E}P+*M+2%yI}J`E)Ȍ+nM`E)1/ +g7Xq3J`MK"z++]Xf hVV_+L`E8V\r ZV`E u"&d Hu+AX`+j'KCT”_`v\_`v/b y+Vj7b% VxKl`ŪV VDM`ESv)/ VDI`E7X^RXQXV2K`Em~4W Vd+J`ESv"hJ`ŪL+V HD p+nV\r+k;X^XQM+~/_`wVR2XҊ+JN`E ;X`ŊVS+V|`f|+J`RX99u+obe?/RXqV;X*+֧}5dRXqVd(7b V**I`E;XqSvXz:7X9d`/"J+3XQ7= 8u%Xq) ++*iXQ!`EZX(m+.%l`&~VTXQr+J`:XQr+$"_`E] V\J+Nydb`EwS 8@SJ65T+&^VTXQr+$" XR~2X*cS`%X^XQ`E3XQV +93XHeXQ!7X H4)$bXQ V\J+nM` V$iR(o"r+a /}`Eerl`Mj`JF$&*J+V% `E?aH`X&T2XqVK`z]3XQ VJ+.93XQ7XQ VT,iVT/u6mn+_XVV4îV\Fy+I+҈ X<_X;Vle|90+6+$"nh ;lu7_`Em+JI`E~oVT<'[;XM+LH`E"Wo"ŝXQ V" V$VHT VDN`E: H0 V$͒V޸@+ye+b)ǿ`2X}X_z1$=Xr/"VDI`Eϲ|$v"kb+*6U+I`E^`Er Hj+jVT 8!3Xa+Rt+R,VyQ`E3;XQ_#:Bdb}+6[`E?7"Cl+G5eD^`Eq &'nVR2X VDvV$++2&rXQ~+2k%`EfVl`E7XaQQXS`Ez2XQ?!ha(VdVYYX+a|Yn'jzXQ`Jvn+V$<2XQrVx)9_`EVOV VTL+>q+~U X]{F`=bq&"a7XB$XQ`Eb& (%Q`E^`E} VeK`E"obpi+UXQ'&nK+*BF+t`ET~Ҽ 8S+ֳ+q`E}X+V%`E} V$G2X!RXѮV:zV|j~+;XQ+"'bo`E)u}+X( Xٷ<ן VzX X=Hx+tӉ[z=d+JN`ŊVDy+3+e( =ˋByl+*T2XQ)`E  + VT}M+*ȝ A*!6"Xq1$w?Xju {H2d`EWiY +f?:35e"!7XQr+e"XiV*)cXByXQ AM +"wz̡}+vM` +?x2XQ VT*XVԩ~E+V[cn`Eoz2X=k- r (h՞3XQ7q*?/baw,"]lobYK+ʠV, _`ŪzV*i|=XQJUb"`ŊVrXєo"'g+V% i7XQ_ XHa~ȗ5+n`E] V!?> X\xfV4b+V= Xq5ie"V% X9Z+Vw VW0X1 WW9XF}\+"'"J+V*(XVd"rVDN`E) ( VfCI`E ?(%V[vb 7XVTmC+XQi V\y+vX( ȩo V`EJ$XHU+(9A$7XQj+r)XVld7@G)L`ŊAV Vd"vN`F/ J+4`9`EM7X)A7XXє N\`EVR~4C b;`E?&"#XHE+A V2XQ?XFw+ηvV VDN`E)(XV VDy]jt`Ero% vb "f 8]HȊ-b`E|F3 H@+Ғ|7X4d+_d+rO+Ҟ-O$h+Q~95 .X`Eo"bHwH+HA+kd"?kXVA V H)z%`EX V$ݟ#AV Vg%2XQ Vs4p$". h}/b3o MN`EBzo^ V05+RIUZ*`Eo+6vRc~`Em2XQ?*`EE2X>XQY V$aV$0+R\+6:w"r n`Ev '& V3xU&`FV$`EtH.¼;XʝV䷽ | V`E5d{rn`ť$&;XaތS0%"/"j+$"!7Xp+*#R`E h1 ;XqVqVT>YVXlG XqSMrQX Wq+VU3ȊY$"uVDaahEn7hERZ @+bWb&\Y2Њh&/" *%[}Z|#v{h4ZXaqhE3ZV$[Њ( ȩoV$Њtъ<Z)ъPVeKF+ҠЊtъ ЊTЊ-hE.w"ɧ7Z^gF+dob%U90@+V`nhEb (ZQVlNvl~Y-&FՌV~Z9dhE ZuB+phE ،@+2'$Zq ;ZqVĖ"9;ZVRsC+ڿъKuZ9QZQ"τVlъъyG+⢞ЊKI-hEьVdF+zЊvZqB iB+䈄VԩH0Vl6@"VdЊdihEVъ oZrB+$B+*|ъ +B+&eB+NaG+N1Њ!$bZVdNhEYwZq#"VӗЊ:2ZQhE9VDNhE)(ZQnC+bEЊ&hE*mw"7ZQ, sB+F+bЊZd~LhE HHbB+sЊhEJZB+RuЊ$"Њ|؎VrHIB+RەЊhŶRhNL4Z¹V$ЊhE7Z„VdaЊS ZQMF+RhEmM2ZєZqɁV@3VVTTF+үF+*̑ъtBЊjhEZQV?Њ +&z2Zq) @+]*HَV+Lhw`/Z7ZrLV;z5+1\E >a .'t)*KPEu*6"YHE[I@ŇSھ9r_0[6ޖFGr%*#PL ORuJ4#I\+)vEU1AuRyUu0FB(JW[E SZE}N/g'v_L|dR(__ #O#':q + 'fY8DՖoj qAE&2Q0&JT%%*SEK>uOZG`[>aDUf% +{Pz}FO!DEڱ/ˠDc* x|]c"Ci%jng|Q4DƖobSpP2Л/chH ZY [ΌA$Yg>E *,m!cE@| kNbu=;;2N `{D@D׵(wP]D$ Ja< RQ/b2 ,ٜϴl0Xc!Z^ X|6 Dԓɢx(3RL2^11}KYw]t+&dRȁႁ(eE F*i@b@ ~ #X<R} ^&J +A5UR ?/>8>}O+KCZƵȇڻ3 驭=T\{u=9PEK`"j_ ` w3T'*솩;P?v>YgVxM@CvuP Q븐("3DykӘi Yh*S0?.8W-¸L!B !S2u2 1C ["jģx(*av]6|!a7y>c؅f_ȅ,pz2Ɠ1:P^V3lZvϑL,  5Zc +B'ZaT̐pz8O\aQvDVwB;/\aP +yWXh2LA +%0#ЉWXT~ +eWX'd\azJ`akKSH\©P9&n~BOxUdn4o(7s \Rf-Bu"k?RXN.%K\B Kreq Q\BXB}]:'mPsoA>2NM,RpɁ%qnBX^9m\4Úl2⟄XJHȩKIT%S nD%|sJ(@hRL%lGP QYTBN&S K>TB]Jp)J8I% ҅ ,>3_]~,?HDaNA9( Ig!Oyy`q#T9%N!pB!a!N=G|}f8TnG#TPQK:|RĢo^V :1ڏ\pAxgUc)$R@@sT79X3%T.UA Ny~MA*| +Πϩ `%&={4u،VT| rQRay7P1ѬK%Z/vj|M[ TVtrUW-Vյ\UYM=Yfrig%XJj1kxL/c +CS]SkۺxT6,*l((V:J԰g)|T h3YX~;PP}M#$IPkS 8 :kA58o4e ^lq 8f,KIg (OL@ulH@O9Pq)vxώTVU +ӤTµJ$g~8Ge0o,Q$ogd +NsK@)!N-$@TzP T -dy#.gMIl)P1z6`)L3B ?hAOOq&kΥ._w+JƜQ»@ 7WFO金4_?. dW& ︌~mhWp/VX?/JX?=}׼}fBz@hf?$J0ռ?~ /_׃B./8 ([0u+ )ajug3vP~Zj[9~cd=>9~͜6ĉW@8~:+"3k$_LNw!0~sIrӧuJ% ҙ&8~Rp+8\~it?aGy { WZwdXG͓haiTpćs4Yd/8~* q-AWdc @_$2R7ݮl>#+$?u?Ӈ19~0ɉg-MR7H#e9~8{& [FSцSZU)ώirJJ?cPgqH _-λ? +y-G+\pD8ǯ=?Sb7BVQL<9~0CW{rIazp%q8?%(6?}[Ư#uP, aIS׊[&D(ƫ4P`[a7>a*DхF+a̮uqG?VAj?z,?_,tgٵ{QhRa)~VW?V?efY$͟'Q:!~ +6.$2& ?56!kbSƚuUP06kf S`qzeT&^*'OB[ïOENVcmdi9@mI"Ą"[wV+T:L2xï`T/R ?, ?|~w~.&<9~&O ({~tʆT dxE߇p۴b鑵j` ӣ {VT2ȢCi)@iVmw>&O' +Sߞm0 +<6}r*4$}5Np>-)<>Up&O HJh~v*Wْ쾥$L&{3,7v ݇9;{` ~h}}R"}U#']Pf4ݺe'm[r}$H>2oS]rtW> '8xr> ox"}R~`exn07'L '&,\J ˚`ѩy{2$C'h7}y} +b?2}xo}e&I&X>"^/ Gx3 l-vtLr@_(Lb޶AW: x"3 tGYTvB)5tX}4!s,x٣xU)~8O7Vh{㣜u>u;}?}(Zexd^ #j;Z3O1 񢇢R'.TwDk.\[>dɂ'sX3hC!}KkWͺ~6PHy~4sW~d>UZg6e-9}1*y̐)|Vob/]J?djBL"~R$["U?sf׶* ȂFුTjl˧ NTaAvbV[Bm'(ʼ6|_ әD' !9hpZb)(j]S\ZaՉSu1md>23;8:!)z"G އbGݧ9=S{@ߣ4˦ }o 7>Lh lZԾ}'5mwr"3R'DxR;JDwZ_<>YEm %G_>%O=oy;0}1}{OɪcaqB^ Χ{s_wEuC^A皢̧ ~cqg"n3=H&(t< 4|gH)Ou:$w>W&qB;#G )%쀭~Oyu%VXM7`4zdn;S.<&zo) W~TaEAS=wUs +w6c_OdCl;[LD;o4IS3uZO{Y{n=v@{K7#mb-Q{^> $N=Ի/|=~\_x=lkL^;\=B ZG{0 +63]n:3za'Dq-ji7 J:Dc”U2N[Jzٗ4RYbLCe̥:W2NϼܝXLigI-&NORXe5~nm 3{5פ!P04=*HM9$\8=@=XAG z͙ԓ.!ԓB.t;M%%| +WTYZyPl<=nOOm);OdބEph`v(X"ެN~P[1yzKI<%OO:cV&*wʆ25MvTH+H,=Y(ҽ%*jĔ`zKH0=K&%84rE*dal!fⓨ;x '#zH"I'Oӻ:0y2)o#fvEѣjz'[sv^ _@ugddr:[uJq޻V~]wb n_'ӴlX"#Ųf$+ON d3=<' +o4.?T%ubDE.kݫy_2]̻GwW2G N{gf*ӛh1?5ק~NS:ʞ1鳵&O7Ϯ>Klc~~F{gOn>/?y~~{G_>ѯ轫˟&2+[}k^?;|O#iow~z#ޟOEޏ/ß>vov|DDDG/:ş/E8RU +fw:#4]3e[9RFAT=PyO¶dQ'|O$Uke@/J\nÀN5Hӄly§~F,m𕡽!^CCiw깴tqx8 2=8Q`%-b) 3.ܫ.{WOh.#N [xl=T窬h73PHH@{%6Kp͎tUN an0J*x#Q2s^=Hnl/Uˍ-}[zP y +tJ(CJlwRBa؂\͟N# ?I64HF kR$H΁2' ئ#=h(E;wd$~/YE +:y°x4%e-ej*PRo6}GlG6Hy$E;EOzIUJץ*K<,!e5tPփkpW/6AA3Ix_ӲttS<A:1@nP1!ây./͋%xԌG/ufH'Yp{E// |qxJ\z/$7KC *2ЫOC{3y6D3qN+'Yz/COšW4j2|i0/9)'{e ߐ%a|,% 9~'>']5͚+0=ycm)lxDcWil6Ը2SrU:E\H]3\E'#ws4@, R\!Lp^$; '_ik2hN;goMr>7O$i<^ و5휣cʺEqe,t9x|+UO/=tTxeB̀KX C=t~i -v}a8RPM+MwS[OQ?v aO: SCDpݏX|E]G}8hn3A`y#6v.{ݺ&uAǜ@ɩ.I!e0Yw~.S[jH)U 4 ZJ.9UW)(&3} +.XaDJ6-Mm>kzg3 cK +,=*!-/Ks:.Q<4s3}9HS D8@cmFX^iH>V 8ͥ.j#lp 5Ek2X +NR +qg[ Y@{;6Ҡcp4>Gp&y|bUE yTש' WTg D֏a0xLIM Vȏ^ҍ9>ۋS]%t%^?JRĘC렪@z:'UDcs~K,?%ٟ. )ʵDB5/c;ZagM[t9AIf麔AFa3^T(AEփϵZϮO ^כF= ޝsOh&åRlP)%pLި)g+07!bmrW.2sL]}-ջq|KqƌAmnC4miq S.vV`]PW~a\hiܜ2PEGn225Id%y"1p +o!\1VbF-ܔy<2 /DۧXɑG/gNkƧc-MZqqyzBiSO4CDt$v(m="+|-,.:./ w.`~y֍q:kUX׎%\&| el9LZSue(Z"sNTE( +l6 ˑ0k3]K +vvu~ifsdZiƎヂݶ40RX^ ssG1=(4ՓƸ%sXgzRRt;!#4/ p!ll8_z]s2^(ݡإ T-a4E ` %:;}Ք +j<>C6z6H +)`NTxl֩Ɂi@J,"ֲ6&dTId3*ánTA ڠ5fTk\fQ[ƹU\>hMyrapyTTlC}~P=f~g@Mo$P9Ŧ#U3aTK9f:X ~QT5IMhW1i>^ؒ s +>ILaZ׃&]EÃs@~4f&Hh&rJ3s}"+Tr1[l֍nR"kG8'VF'Cv.`ʳ$F8oЪ,Y'{m8a6Khy洊~9=%;`kbJ])S0Yvqj!= +ù_JMXFF%Qu7x^ԅ£0iq8Bۑ3E%|nQMp¦>-**򈉚DE: :AjJ6/YYW(d.:-3à7J-A9ak1ϕ`6\R7cMڐa:fWùj-;wQdS{6YJ8&&?{Ċw9OIdjMQbV籠#58pEG=4xDXA=zI?ӊrApnYNW#bstw7c[ݥ8%9g.@qPh˝}d:]W"82ML +T^'xGcPT}Oe^g389A;`żZ٩:>]I6Se*d2Ά^qVkN`1@L6WD ݟŠsmmzy{ui q9%>!^)F TA(EmI+1(^[8iX`uGyjfoxI% jE +GЇ(ak*EڠM<02m4Vp'uʹ*]1AС)E}wd0F}XgRr*p +0SSU~'V\z!V, +ffU57@]MffI~)p5f_ xq7Mx8z5p'[238֤x?(Lqֹ᰼a3sQ  imN&0=VXU&MA}hd#0TcCk2: 0f @d QQnfQSSʂz{7)*!2o j,N7`NsTU _!м_]4Vлt{lى0Jo3;6D01C,ps]_6.SaRf=xZwJ]p[%4F}s|Ds(AE.ipڲqhrdm7 u֪i ]›58&сbcmDKFu6-x!O_ҊUT󣾕(;6pRQ`dEIu5smqxhĢ@N,N+k33tV+=)? bC-O=DgS~KAM0z$J]^n"lSb7THE Uq6M,NW1Tg'{TDLfl{A{%I "i +!z:M QTB 8[D,` l3]4xOVײ^% Xb9Uq:h/(9+uH=n7UgAAAM<89' +]: q0 +}D G?BUW+Gl )Z{-m^KHCD:)+=!'#(Ai|0 秾 QyT P۠;-@£;k +a_(ldRMnƊ}VR-fSBI-t|F [=e)#q~BmS CW`OڅΡ{1- IFcM |0HL? @ӏ*2.wiGYadaGT[e 4޳wCh=N=Mkf/G>EA,&vaF/DQ5f m@kfS d 2ҙtvi{pe)Uu/&iWű8/oN;(nRX&}&1} Whk~00rс@ԑƵLݤ2Uql2=hR?ղ""vځ&"znCZ7X4B,:#J/*׷ÒwxV7t#XB MZlF>q>,KIڃl٦>SMmC)Z4so"y O1/ p"qGcmf1vʰ{7LEcI#%X +$~&tQ-F%dۜYYJh:t,0_982 E^3Ag3= +T!s([(DB\`95u&mfe0q\7)A=OqTJJͩ +IlO\Y略}e*QC0Ğ; 7Qo$4efٞ a26O;6X]ڄ<~DRos#`_!Ht(x'(i,_˝)B *¸ #y,4> *) +sWָax xu~f=TR2[GWyJCX6dKTjⷹ:1R%*47O>^gqHR(jA\=X,&O65t>XHAh7I &lG%GADyghWJАC*N ;}D&f р8#ce0CS'l>XИKJaYz* ހHaCP"d/&*GqmEG(?G2Gv+HD Ф(RLT"Rq +YTvg ejp",T+K-nm]E PN"544*ǁr؋Y^Sʮ2--Bav)=lӢ-DCG1Wt<@' +endstream endobj 143 0 obj <>stream +3iJFLFQ3{ #p2 R}q'MVŻ—qIfCNCU0&8CF NCQP䧍$2^M48zP”b8%ƹ?iXDVp +m4J?hlj6DS|<-dQd8/BOcU:P(#K SMkgbf UʢMAټ%iz`WgGݤpl嚬2 nxYx[XKStXڐH_ZPM-mtY"AJbQxc}DAWsj.vxxL(]'8j@ib\jM[ Z͂ +Q2K98DQ)cN$_%Goc>o,ɍI{ ꄰ8zC315TD'A9\[神h8յiH<|9Dr-NyT((0iVa"S9![:eHgL0 "h+kFe Sdd$$qN;XA~њ`Ԇ&@~Jvwҷz,Ո]\;Q)i +E E^AnrMN#Ch!9N3ոk-Krx 9HǟkD`#)YAl#;Π1[QRH1Z~ ܦVE\M71.vnjYO܍gztdXٔV՜˼2 b&aGƵ-]E`"PեV]%=i4ɃG-JYkWKO#׏MpfQAϮQ/g-Pacn W][^-K{Cj"T*V, MyϙV#7 oK cH7o6$yDQV'\_.@xؤבg~x[kσ%yA H:q !V}uo+ {Mg$&k>lƠ!%Ge&h]#ԍ)U'@4)8hVo7uK@k*mTvjb9-WGL.f+UZA2 Lo#7NpLW72T@SktV0҉ZPg Z[O5t$|DPɴU,rU.erj +yjI o /YV͝D%Ϫpݑs6V4EO'LUyȒd,͟"Qn䙣%)TUMb^-vDNx]m33ó*,%!ݪ٣e v2SNO~G)2U0/! -͠rPSM%l'=aC&©ѯS4qULCrU8=[E|}6$eH/C|%e%+0ul7̒`HElAқyzo` +߆0YEcn2bJ^@N#%CAW +MRdn rTJ 4(ǔiY./y 67pVbk6H gR}'b q# 7C@Pfi^. ?AV#H:g,Bs!x4̿FepxX`ˬU6y^ބ27eciڔIVhFdHgB/,<ΊwMlB7Ł}1OCBג0"0! 蠍$^tա:XCSpF_do'bʑ} f&%LfA +R`e KU,Sh/ ޽2ȟg9V{g۝JiF\ xk6=d82{~c]{^DW{pc((U1xpgnJ 6M!Ji]?tX|uuLzajCu?ޭ +4][^!-Ŋs2ʛ`f >ha&/'/,H{|o/|O~z|ssz}rGvyy|qd{~ ~9~{O駿"{x/=O> ZFG %ih ڏxh>.1##&DhjwՎDZds` ?7:߅:" !{io?>sAm}\Ks8}0< +$96܋XHf͸p8.e:XLe8׆F%Hz6?|ǫa+$ $!g1W!䉟,#]~*-5NbpqsҖdn>! κa 3AmQ F3JˍR3dngZفսZ͓*|.;߮qǽHIߖ.AEgxkJW{[5I/m"{,D<1UIME*ژ$.b(\(a9넀Mӈ BawHfӧOIi2riov 3ґVg_I+*N介@V@N0srYª\ZɸX n2ye܄et r69\F@i6ycqm|H\(jqm3HpluwyeRI.z}vysv}2o);go}g'ۇ?>z)/^wW}oN}{mN>9;r}z-w~ty3Sy ߧ/'7|yklܘx/?Ym>_o~o_{gOFW/{/y9.|t_kOXi_lł^qjY?4*{秗'k|֌eyWߜݜ5t}-5?99l%ο{ڋOs HgT\˵z}_dlVp7+ӟIzfS㸗:\>=>^/._AD94eǟ~rv6Y޽_ëOltɰ0<ӧ{4ԝu,nQCM; u./m>*Ξt-Qק۫oܩ;uTԝSQ&$n/ msgܧ:Oy^G//J?3?ѿy#_g65{|=wg+7@ +k_^^V8&/c݅.}v_>xO'g7gB/kps|f!ܛ>F4=r}<9>?1_Ž  (n| DokgON]RX-|os}r&Gu{~vvimbuZ~ru_uu^/uOɽ[e~xٳr=|;QήOo޹>}7[ln܄l;渳90l;MXYWzzNmfq}roĤ9xIM=wV9VT| )3oQ_}zzBJ'gwQcs'oS3r/wfRX,%jgYv%jgYyM,Q'ݷwMJc0%ikW:,j>nKY JlIY V+Ks_7,[Ôw2IѸ٫\; xTɻRq;@xWS'/o̹%Jmȓ1bޕ'&x_+diZ?_n߷}񷷿'jMԛX^ּ#-x|c5 +liDc)x>yQ}ú V{rQ\=}fFed=l$F'Ξ>=>9O&e/JBͲAm-w?n{䁋̆7l'<4'W>fB(Aތ* +oRa?$jkFn)/%FC7gYfn^Ht-z37KzrQkum^ .׵ж_@gr"#=GaWaiEro~EoHjv]-ɻr'=xɻr;m4AQ}W*Ў뛠9[wH_d[^wub,3c-ozNÅ.4&,|to*N⏏?Rqݕ>l&qqLݭ_tf؃s~?n@x]m?:s x;̛T qʣt}^R=g__ޖ9ߔ^{UOgy \@ c%"jlWBmu'n{,f>=1=ӿ9x&n[cĻۅ϶ +=^<<{n0AbHwBg峧<o#7|_rd>C9?_wdDk{xw/}mIۣ_^\}>K!^ +coǍ}z}u/\m \ߚ6*6x.tZd?yrvs˺}/^f E>]_lW/ky{At4?rwrÅokgON]nR69'k +A_b#Q$p_=pMT2%_?nwۏno^}񷷿hMLۨ=Iyj 꽾د;zգ{ůo{o|^Q qw}O^? +ey}1Wן~ru~n;":dI];#;"#H侵6|~dg}]F80z/'o# z~7`ǠAe_m$+l&<.+ڒpY齉N* ܹ>G'DCޔwq-{(f xwZFl˔S1H[/\t՝FOI9N[rmuV_NY);eu՝ht*]NIf%ul5uDOaٽv8Fwʘ/{Vu_ͺM][B _َދruX:֑ m}GsR9m^jv;m?@6ap ~Nس F7:?Buo|H@w~r|yyzF/k?[ߕW==ǟn3o8wdo{+?^>`n 3\upmp7yrר&h-Dc}K ^?xh߬o~zv~QP1jV>-n=^ź\쾖|}*}M:5~+EVrs|/MeZqrkag;=9>?f_]lP^Xע..7 )''/:m̾W%b5SzVm~t\`i[fE.qNkTAK~}.1OoK28b+viۚإGȳOoK.bvKإ߸إM0ҶL.mQ&h-D.m-#_ mC69ͯ}xq|dz{vؽ5ړ~׷umE+/{30Jūv+ƲwbGwqG +mֻ?_>4a޻)rC+TIꜦt__fmo?XW^oJ?>K{?t{OF^ݻx}H~?JCN5}Br!/4|+h|텃rOz[F[aGYO-0g{nts;o}ݫ߿<Ϟ(룰ͬzBxG\,hEs:^=_hg~ѷ>9*)6<'¡yw'l߼ǽ{7(OpZ\~+"xjґ +Ck :}vh}+ ɣU8 B;2!tPr {b6MFB~Zh^ Gvoʳ.JCV=H'BhO0^:w֞{luDQ JL&_o _CGLQWX43MV^^?cꘜ\*Q4X{4cZrUv +aZhi(ZSW65+M5 |ItAvi&hV{ΔhB20$%&- 4}ړLۼ8"O/ @ńs1`A;T#tjHHBKGMPiÁP3:k MtP\S~O @* }VБU }NVFg'G-t6 Q є}yS8uB}h!Ec|WBJpr73|Bt:hǮ3W62=̀\hO `&Ew?FBS)'npY8DWM$](ا=.˗m(! Vz#O9y00#a^$N32HW$# cڷOHpĞWMh5N&qABcGD]&zN#~(dvI rAx#:QX\JoLL+\F)Mo/f@Pd@,RKUY r_g*2]Dm;Y3bQ46 (WJ`CWj|w+mh#9jm;t7rnBfS n& :XuI_hAڪbɜia,eC`B;\Z_y#! `RJq8J6&@$J%%K1"Յ̕naHD@;Jw 5}tyvw;qCEW"$mpI)KH<1bBޛ`He :8F4d&c=7i6иT  R!T,#Ky.J +EuhAC{ ¢*+P Wn{n ԙy1:7bW K¡-эH _$x S{O A [wR/hE'40KȜqhi-:OѓҔ: -la qقraX<]Qd,{p-x1yF5LqA|b9R( Wfѹ [(vg-9˸tHԘ3ED[Jgf&qsf,& +is#T@u8"Q P};DX8RAn0@DNG%˱B3 -Ztop̎<  l14͎U|C +! lwϗ@+E'RL(`㉔fX"Hq67R!p8^eX FLWa<8},p&|H66cq=/l(tΙ7¾2tR]ס Sہ`'0|CX -t-LwMm^dJf.ds"CnaZy;ThSe|Z + +HM)FQZ"vU`d9.  )v'6IXP|=]nLk :UyXpi^< Bˬ|9hNtW$"~ɩ"vb7qc49u椊1iؾ:T`_` 5vpݙQE\OQky{11z_FE% +7NCiU:3(9,]g^Ή!ˠMBpP'QCi& !Ux&SrTw1P\zq6 ;UsO@_A6gLq6Ql)"0֞.*P,zdew^+/!/#6v>j!9YIrĻMێA $&@W(UTHD>+X}fK +KC ؜YPx9tbً.W d_Uzpl .CUB؜YЉOrdX*uIF$l. +lrb٢٫'i}*舗zޑ + -`[H.d/.AV_R]z0^ք2,YzKc~1].e3)wRNAGB,"hsBӆ{hbPz l6NBjAL|Bmh&iX_S4*%<(f4@36oDJ;%5aH^JYKH$X P0d BZ +5e(o/lć1:U1vAb3JaWi$j'IS-'%`xpZ`pd J$/5]O͒ORE}0m"c=]!s˄tB3EE16U!pr1٣y.8lGLox4'17:9b;OzMH8 e f솳6F3oDCL2Pu"}!VgUĩc$JO Y's>U/x~!Ǚ;/ţn1R'߼O @4A LE`(oA&Ř +fȜM,h ,AUJL$Cl0Sybiѳ9"oer!4F (58$b΁a"c!X8b,E#Lc̏ +2K?07.aXp^{˶\ ತYbKNAyM3a6-(1EbVwazvBuRQ+qHKүW 4N"%r[^Gw$v<0OBnٚ$4 c&+fk|p3]VlUSz ;[AvL"%> +׍~`<]`#CuQKTe%F&a8aDIO ts()!;i12a4Hr DB}'A4t~u ‰Y-AD+lΰġ6ŲN̂8r91D]X` ͼ8caY "CU%#$%"3w +bg&!v:7:7bOG2b+*Xx9q<`S# |aOD'Cas1KQlzPs tKFa t]=CMhvHِ4iCHNEb[_}.<,˚XEg#KIDId-D̳DC޲7 kA$󐣎T%;6a +LHN,K&DŽ1IC!@dF7\bmУٙ\8Ŵ5dӘ7y& $#3oY7!fw.$&9;3l3-AuNQ1_X,, cCC:x4@T7!/(EspY7X)Dwp9ӳ۩-rh#YvME)سqVʙ iTeXbu2.uf~YB`dCXgS*0f5ñJ{@E +Ľ<߽4MnӫO}rՓŨ/fD矞OOOn$\\z0{F= _DٝCyZkvB_n׷57x< X40T{!hX t4rq4NKO8܃MϗCPE Fއǜ%B8qpTNUbD0tpt| iV", $OHd&Qb9.z2$۱nWZ ,[vZQlyw3t15£VVvmUHᰭr kQYyPyx@.@UQ=bj Rr>x=dQ(CllƉlqY9vlĽ%(A @&%e( + i!LvR*BƶfO.&'Qk*~M,)aa@QcԁXWqQ4YcY͂pC Z}CmsK9;-+{e#^\O[!Ap1>`t|#E7 WmS5!&p#XsO`|[Y Oc]('OT D9ỏRpj :*C$vpyVTڮ&wVbhhlʜT$ | QE=%W4HO^;6!{ 2ct v\@Ӊb+1ҎwE8(˥MTU}D]=ئ7QLj~*p '#IxBfr읙xzNrHi[R\š4qJp +Zn>ۢwD|^3p?3fDѫۏjC`7OS Q %Wg?.OSg)>Ȗ4׆S4,'aFEB2 9 Bo{Y?;&gŃ#px+ퟃPd͆ +IB &:]^}_:|oHSU8skl𶃜u$0b ,H +ט޿&T,~%`{]8h=O}0q;}W2)} A;F,x"_4|;q# +:R (g #{[8mG/"_ۅ{;RuJt Q[k I:_F) j#fFܼ:Dd9E"ōcײz[_"+|"AyR UdX!t$#K ct>{m"A?",Sd;EMTv-A\q.U/DzEI"bɒA3${(-\zd2# Q;ͫ4V+pqҹ7]%4;4F\Y c ź셩It9D?'\;γj߱fugԨ 7/sll6"lў3+kbUˁsaA blvif Wԁ +W v.'aGgQ +m u~$Mz@gz4C^9hly_#\˥ /hi|hYle"<h+a/R _貐s!Y@dz`&usC_ˍFccG)]d?9Ϋ',s'XR2N(8Dv`ћ%(+̒a@j"Uas:J[1AQ-`Jcl6A 7c aC9iD gDB/ʲV;'r;[-fXY`Uc!@Sff ّןYD {ь}PDNCj¶%`|{5ồD9)gkn)%e35/p3u7$="q +k H@$4f((ܝ]4#H;Uc8hUƈo +u@@%8GsRF˼~xnHL.{r[Ӟjd͵ i5 +p `i T$[ef3&U՛cV2ER"MQ-8}8ߙ,-uUx^p+#"lܪTX9/k'2Sш3(X`O!U6=:u;iy~y1p:7uf*r" +900\} &0/I6Hsl;Xg11aY ek(<צ nűhh&>a1G9vuyٳϱrjtC64Uؚ~ L֐]La=(^;d 9 aGKj]_,yX,}r<,g*cd*H1;xnpi`? y`21gm n΋&B4YBe͙ :wY쟲x,}!0N Pu'Uxb>"QvSRT.VLqpx lǨ8vBflZ r8-V K%eeVӲi˴:aJVp1_+ Ǚ $on1.+^;\ B:(`LL"p ! F.b [Ĝ9*< 4Mcʛ% vcqa#'"sYp%#q%͊g#*:kE0lj4ĺőעP9e'E.{fفXS36D) k]9IkJ6?/Yq 7Zt.}o"b-M !)Fe\B֪RiD$5&ٹ\ŌdiCI (43KC=!}!@-W\g(ΖTM_YSݥ0QrZѢ PȲir6q}-;1]FNs 4VUlZڰrcǮ$w'9'*+BK?,VKNǣ@@ e K; t}2ji4v%9\E6lfPgaDIŬ8QBÞ"vb{_PsCμlY; kJL_TWQåG4#{ \j>.>}û51U/0i܉(قQV@$ӹlš,eozɉzO?39)D4.q,OE7$#(?CWNgDh/ 𲗚*5HnDf%Rr0\Ņ9 \Ko,2Rvvf&ڏjttYnHʕq0VV. Zĕ>T dY^Q6OW +qޱGBb2W8`+ ~ ^V @F29lfCNVၰ߆jړpՍ:,/̉RP3?{`hb{xS!/H|&.ڥ8XhAffDj`_;}%Y"Wj8ope ;F8=+=T?{(VqeB]ޓSP*i"f:VBKN~@8-jnN)*%tF$28D[S*TYdJ$gBW"DN4`!d5䮀͋g-1džUlYD.R q24wG,5|&.̕@ +ݜը;G ++иF;Fĥ E蜫hK\:R 9FynAKWt']u7_W Q` "$Xx `\ˎ 55$*G2N9\$3airƩȇ"`V,rXxeJK1.a0K2JcY)qm8;'񐨞4 lMj@#6}\UU *cqg@Rc#@9y`d &."It" =lGs*Ov d9^rմ]36~KrU*j2a Rip̐yN5#D]U*1{`].RZ9C0@Nb@]}@/`eg24x^1rh2 ,]9]sjú%oYr|X~\5Rs('|c:˨$mV0l եdOb"jh=S33o[TeeUfGmw1s3wpBTD107ڵ!.`S7U|8S& pa3(C9 #cUpx$#\i ?ThasIσAtsB uj"b>Aj_W9-Eq/Q~<˟|IGz#ꗈZt+Շ񋖘9H.wWƾ 䚅 ='#PSNԀSNm)9.9@PWcL|`V*x]iH@I ĤdABi>;ǙL +OJarbq̠BA nf<C  ĘOނ%>V,yp<4HސU;j9|aW+5-w+ʕ0w%4/l.>.11T!W<%g/|w+y +~VvQ+5/]~K쬱Eaeik)z_R)6wԅMjEFY=ePU-T(Y鱲;l/n_03))VC[Ya3CI( *YST6B U,Z%orK30"ʒʟ)߸@ Tb!@ۢ)N ~ƨ& g + +âF"/(|] u C1= +*AV9xяn, +mUDIDSI`K(RyQj/HK|H?_[ cQA~ +rR o_xO5b#\[nPn$F *n *ļ2|"@.J,%$X@ IrFϔ2ST~DmfXE_PDS ´`XD%:dP3@122SXBk0>R ^KHu1%,,en!br;M& s!GFQ#3^̹Iu EOHcZ~!6r>v3_nhqjbM{;b6Whbo-30nCE,=9S9xŨ,"$i77tՓ3_8@o  C$)M¸ {[DuDJAfb&a"`sc|e 8T*g[iF 75K >m4 hHfl:*̪a E`ILb|ZJ՜H@<6Z2 6 Fm'9..D +n,Y-IR7Sb2 wiLfm{*̋׋1tt|mP$p|QdXr闂Z~bfKgm;aotS6)BX/`u"J)M()葠 +"@\$tpCI}e:>ctbNbd2HN=fbF.= {>oi_4|<6i6FS)*C]G«9Ř ӦyҰw/MT2"J5.KnC&kbEřmYn;H -/ ƶ\^e*t^;JktD  KL;AΰS9}Yjgޱ4<(I# gcv!;TJ( ar5+G#0M!qM)oigdx:(Q ोC [ِ!&I?+@r:AKNKSsL IFB@ih߳4K0!\4RJby2I_D6A*Bfdý"-/4no80e}ֶ/Yf4c?Ƀw\I pu1XY%!W|0Dd}x$&S=VTPCdPz䵌bM(:a $ q+P2x8AY6C FCԺJ+#k` 4V {>O=ye2VHj1bEف '-\;2elRPE0) (!Ȟ +:F ++Jb@xscM<.h3ꕧ;&J¾[Bf!W:b@]ưbY] uÔ CزZjEf`ࡔ3z8{h2hjPݣaoTư Ay]i4vwX[5,-9֠lX[nT3j}ԗ=_&B@m& eUԨuA1JI6x`]]Sȍr.`H1gX >Ɗzr! +S;җ|= UAEXj)R` +1Wb^(L7 8p@3HX~C*v +W"XQ3u@PQYH3e IЦ2QHǧ+ߐj+H4fqP]J+knA%s(H)9ZaH.y +T *)QIPo7Љ'\=SXGP<"LJБ䣕(cTaP-N%ƺNHiHbNAnMaHVDiN Ep+1s^$ +)`f8B@3ՊQ3 N5,5.`ՠ4Q +q%#q\EHM*nB2JxhPex#bd(m `1~"a&òml 8Ѹ" ~MLJI ]F>D9*d6 ^t, &صuR!T1&"!fɁV +`#TLڢ0#&VX=h|@N  3_H0oo}eF6RP5qD!I!kv9ڈ I TQg&HrlXXnAje `ݐhZh;]r<4ݨFq^0gXmj…q=Ø#QSEL"j]`1XFL'qL3pN'+rD3CAP`S. yx$IQ|i!M?-b KEy  1WcE5};H(#f%3D1(XPOsdR3Yw-Tt0='ArW=Հckf)I 6 D$ xXL%H5h0}@.SBAa(¤zct|BQn)#֦BSiG]!1d1찉~5B4d_71&ďfTA_ƔK=85cXM+*xaD+A`HT9 $ybjdEKsaa~9c3&BԪB,$llbC)n sdrYVy2[[LQy),g&$CVd-}3BNS̠s\c7x}(P1%@/_ŵ3UN͒A3Ԩ.BTbWQZFV2}"p Q2)R9#2tg J,Gk#0LAb\:cPm 3nBܵJ3ԞcpT Ac +PR oL" +XYɲ '$L"0r Q>V"H@S(.eN#DHA%lKסN@QK*L#ˉ"2VS2O K"1B[GR3J2j+e`54eBV! IZje/|(@MЉoRRWUCI߱qy`6LScɅ~pHOy0$ +0K1eS-0=@GzΦ(TSTג$:5(0l 7"WG0/4eaU(I72f YxFծ0o TT:xDt#7ر( + q`d,+( #L0뿃MYo+N).ې8"$ZdHW([%T2mk~3GbdI WaqN.Rbjs.3BR$PS(j@# $.YuA*^ENEoZp#'}C]HD#:EEJP:o8C?)Su0cJH Hz`@@K& TMFM>LRڂs}L@dh'IɎ!$"Jv +R%DIpuLh*H<_ܥz)w?|ů ?/MZ; $t>oy_=(Z9kaEP0Oja;'p/wgںvЗ XErk:DϴLƩz߽}z-"|!)z|%$0:}=-WNp@g5ϑ`;cѬX*0Z%1 FǎEwCw)q,!!XsE8>?:wmgWFhU[\$4Ҁ؁$<m_O 'K( ǎ!1|1rl_,3-'CElE {o9V| =Y-!Bj!16kG:`4N;L1?gK۴q?WP[O8*PPj~4>r2# T(hJPԔ46JP3R; 2O* { u33(J8`oV*Kc{dYPTB3Ad1S9()8@Ys@"5YJyDo%iN x+!i%44Ċ)b3-Q,49| yHJNQl +`ĀRZLiӻqE#+APrAPkmOb=&B£ȯAP8!$D˨b;Q|t24-̣ +}FlׄS.EV>k\6,KiTcHb\xxwP.Xr-+pߩ(sx7! "S%f +F (7Aj(w +G0d̂MI~ H2,7∥asQ^2ksA5ρF>*bX<@MzyP.Y&=xIBk@5:@r4Ԙ`ZdD2|{0%60ܢ%mEX@QL%rP&c3 آQ9܉ѳSS`΅B߀S$Cwc^ܢNEV% Kܢ@E/Ev1hkD*ㆁܨiZ^3r^QQj-zEZ Ț)2dƜ[0|*JNd@kf;VK)aUTv7eT&t 2&=,43&=(&=Ō,2.`N]@lsgӣNgRtUhPabPd l_M.y$cgx" 5N>TAl s>An +Fw$7FA Eސ a.7k||䬇yLZ - ~).cՃZv sO5WunEc9b\z<1k"$SQxkD 1Ĺx( 4!94 a1{"oL*Jh):ʯ?*Hy7FĻ&`}Q,ޱk9_,jr@Y4&;u|=v׸=L?i㜼(ODH* (4rA3>*1\hjCUܘVY([sq?G ߘ>Nd\ +c5m(8QX!L H{Z&E]/e@vJEB1 ^b(]#K6̱A͡ 5@?0FHѮC]8CG r80\9. +z +XGH 7 >I@[w3@#Jx$wiuDj-( E {Qa[ 0}B9 KET158 &lJF0xҨ{pڏ|!":s@;k[mn.ωbȜ=2LNBݥ!g݆s *4 0cDF\(e*BQbє.I!77$2[,))S CLpse21T?xh 9P8r)qrA7OBJP҃(AҸP^A鬴D$d}wFps`X=l +ŬÙ\jۉ ƈɍK|;Ƃ + w s=pEmv9*pz$IeKPL` {RJ6b$0S!ˏу;qԛ:;ou8Iś핆iY;BTu Q:t5it)_~:U~\M:.wsߘ~HUrݑ#0;R\w7 |HUrݑ#0;R]w@?rݑy4ȑ#0J;R]w$>]w*HUrݑj0%.ӈ*HUrݑ#0J;R\w#UuGT\w#UuGa;R\w*h뎌;2*h뎌J;2*3;2*H/]wdTrݑQuGF\wP +,*h뎌J;2*5$52#뎌;2#뎌J;N;2*X͑0\wdTrݑ0\wdXrݑ0!reTrk\wdTrݑQuGF\w*HUrݑjT%J;R sݑ#UuGa;R\w*R80̀N7m_3S#˨@-.Bʚi25x52hA3k '̀ GC3l#;s@C4j94̀GF3$i `D,4FkJܰ̀T%̀Q4p4+i*i5ނ^CrhXD|eUr@13cArF>JMrU8#a@)6e:PV$P0 r@qcUPNY985 (r@+ +W5 n@Q#X4l4EhuDeCW788ib̺fݍ( XېK҈J䪁Њ1ǗjpF5۠K)RHW5C@\ mV^H% !7j(W  (NGœxo~tu +aΨ ϶Qu r<)iS@0NCseY倢BT̹@%An@q%%HpF7j#De.'j@ըɢ"J (%)1Nh]w 2@5 b.Aj؜i!3X-̟+TN`L1jmXs@ZBCY GaC(nٕJpz]PY47`li9+*ȏDhZxՖSr] hC'!Ņ!rQ! + +TQhw!3P+X! =#-TrWRqJ^IyL{r]s&%olr)1eSHׅs|ȃހ"0>z /PVJ>"dj8oeIqN˕9a 4O'M.N.Qo<u|@N܃oܥR08.,RIQ7ME?MeAKe5.$ + +T㾐K08w rg +(|~jH<3!$ +%נ*eifɶ^7$jr0u. 8 \cѐ_SIpSn+17&.\1lBaX̛8j8[Ξl scH^,܁z2nj)c;1t4,[3$fQm[TAj;&yLq٩3W26ce:粫^ޮΌvɇJVmJ}iM&HR)vr9T1ӟkSC]vNaIug-1h%h*\"pXwΔ[.auᎤ;+dq4rLb>z%^SZIi.?@Upn7儙XMj|]\(/`[v voiCjb7w V$%$ TwY00+75pHD&8( 0(g톞8ȬۣHj['E $s ]ː]:# *aOaRxbR !*,8C(2@ E8QH![J%q=!0PgLwRv.J2Z w_)Z0TŒ8 +kk{=h5P)Vz)Xs<*=nL:F # -uRV 3y4$ AM`ԫ Å=$^%cnU+)Qt`0Y= Bs/!KL R]ODbxC}dAV;C_ =J3TX*!G[r-|\؊So!4Aj@u w02 VBVa18v6}lj`>Yðи(ODơ1*{<<-V|z&Es(:3ldBK֚R#L)"T)נ$jM_ѪIT:h(SSR{ ò e|+LG%n0*ɿ#Z{`{ Atk7ZhOp~KMrAN?KwmH>~d}E#fJQc0I +h}恼W)Lh@UL t-Gtn,5iD*};4A|Χh&4tΖ7CϳkE@z!1a?4gVDϸliSt *M*w'TWP=o~^^~wClhMhua*V[ i"Χ6IQ)ICaF;c-~4]gm~cwNs +VN{jf_i!dg!$?# +|$)GU7 ]~7:bǼz=YLڨ@<$E>/}8\qE;#}t#XÍٺW7w E g|ܭE [|THT?&c›GG\i{<ȗHCCbCl`w9mMLM@hǿ}mnv¹48drԊPE5 %d 2w[l ~V)`Ԣfw;86IT\"ԑx"~kȲ 3Ld~Y"j=l1E.w.痵?6Et%pSE+c~kME+㤇?"w2(oCл`zEn]Yjum6ovֻN}n~3QUez3j}0h:[A>f-ӱiJkm4yb _v{,!m ∀<`Bz{>赾^OZh5V^k㎝%糟eʓ~,x٠y z5'1z7>~q_~~+>-_fqⳠ2~pOo7FʳAeC?D̔>Xl\:J;K!!b4  !jR莮Nc<]}$'4a.y Ҽ|:u ;NsWh55 \,Tkd; CE}R_+ {XTy= % +fMHy = :%\c!z=&?C/SDp,?MLx!'{&a=i٭Cm6-|>R"=TE#l4w۶t>ƽNMKO Av좠& =v>A2G5'#3IrX_D+GTuȇc-?}[zR=1p 2?DAJ$T!zܡUS8mP,B_K(ʼ =ߩg BmA^b{1ԙy#F ߄|7݀U镧YXjni,6b2_h".f;4]0t L[/7!w'ZhCOo-hKD2cKD"KF)U8Q~ҀN@ZV 0cRC_tɓr*Jl2Tި)&8$*KE 2jzZ)f~&F^2RH_{OSH{/xHM?+ډ'vS ;Rqo1 `XWbazrpjjCj˫W[ۋqrE k!t1QPJ̵ywFMaz!7SYG?_"Œm>l`Eyձm/ȣbTy!/;h,́W*atCpY '`NXJuf3AqNd~ʇ|VCinpۃ?G8Jڙʜ77Em4L ̲($l`\Mḛ.E,DMLOfJ0~ꤳkmXφ4V ` p~|u8=W>-JWw^3hu^OM1*~vwKweM1ВFwY*NuWYm4{X_vK߯[7}Wb!D@u߂B=Dh`/'AqeflRk]WskzuסUxuav1 Őq%1grU~8e)MBe,Ag j/@XY5?@ݎD8Cȵ#\pJ;DKz_wp {KE3D#3񊘮¡N1Yn^3m2LT?r/1 Es={RH;8 l1vۘ>vzc)G=_w_.*UwZր凞ozkߴZܙ~o3?}W3icFgm[ +5!0)$--`C:Yljv6Z=j7ڠnh$^Ы+'7]-AlԐEvca7\;=ܬ\wإ +/jA[78C_lS۫5#hlk8`42uaP T/tS F㋝u }+n }8|Eߡ[,jmlh`EͶw€O/DQuYәj3p-մ<7lvV66y5-7l l@igX>*> +w2X>W%'^w?/= ] gE'?C0G&Rwfm~zFg%땿Xo~*p*pׂ\yǍ/ip5{H3ͺͽ65k 2%>a,Q8}9(uU;PҊ1yJN1yJN_'}>wkeo~ +w2J0>"s^QN2R8UJc"Nub8QCP|:&ǁO#*a1J֓$8ձg + I_0eZ;mluun.詷:#'_U~'V+:=qJ7 _#oj(~p  zN@&8݂C-x+< I\E$j瘤Lh οI +'\ၙ{TQ`8zGV.~֫觝Ԡf<=%doy=oKN_~-uA}}y!)w[nk 5|k6w6;o/3mqO4.E}{'}~J_9FNO '& no:IBsA-Ux V"$UPZ\&.a;K~"wѳW~juzu(1y*BFaE4J>5TR7rtRB]!ĭ3z9'a);B'?Dn}EKG*G$at/ՍHYI*Aނu7犬ڙ`򆺪7Ag5bσ8SqZ*8NJL 'a2u$χ\'%Hd2H~zJ>)F,$ I1s w);%`l(;MGW)קf܌c/OM?I'q?^wU~u4[Gi]a%o{~2NCYo "̠tf,72 ;5ȨRHZ8]X.Ǯ$e&,ӛeO[%*NcxHgvh fn/ҨDRsdWuHwB!ыuo)vDlRR]JlsY "Y-2n\3 w\NVeQB!"v1O:*M3#IC&%"pF'*b *Ye1k`jTNƓ45bƏZYhypa#H7c%R! n0O$SMk)~dQS&"Uŝ]yzE{M#}# TRD 0d3z%:(_%JatS$KTߪ)#`KNr +/#UyaԊN+Ga +[&Ȑh?H}x}V1 ^^0,CϝCUDA%ܒ^Mh" G!ȇ7ӫ@Ȑ!c]p`qa XԐ1:1d{W%Dg ݔHeb6a-}CGYB0ŗ4(#w"xZOt?>]e8[_W;T^!m Uee Q(1v(o&^R}҅%gJ8s8\gdNÞМ)I[GS|uI Zѕ(5 0=asfEX!tzOTH)5qCXI.Gtak6ng$E3Ě@Q +%$}1ޢ uM$w5r4Gn$G>9=Bi_29[!Tww i]G<`ER>UxuU +R ּ=Xާ[U9s®{'M)_K ql&d즨0 Ը^_J,]5DOӇ'3: p,+~}> \?/MwfU1-.az6-ƯOC4o_OUxXoFnco}5m`;-ְ5n67GqW4`3fLW~V=^nVz-=[*Ӳ1}[gZ%U̔GD +NhN`}ICfA>`> NG@ž>;zocYka^2M\[Ow`>K7` |8[Fid[2??ovRuz_n/4cZ^)-UidvsDd~H} :z$8Cy?$R|EG/ɖU_o7Ot2NuDxwp˓hi <̳tw>QQbeC5(iu_}#v!k?b_6  [~[Ϭ:vz[Qԉg͉&eXch'2'+:@-0 W~&Luz,섾>q4 g}d{0:9/ =LQvFn!;?خnMmfB]a'UbefoЭܯ͞%tzYb&PhѺ7uvnwA٦Ĺ:wJ6@ݭk|_Ϳm +YkU3)*FGgض9i@Jñm184M>v_^}٬CNzgЪh\7y\D8ɍv 7_ac\}vnu5w;\=<\vi:fiETڡmۭ7rxq~U∖I1x= mm[~ZkM_k\zNGzHlB>NcAw5e V<''wH(ʆ$ +uudžGb)6Qo4g:-%C;j~O|?p]ݧ"4N@ukJggQqIm jMss,k}Ƿ){{ua`2-ccbg[qV\yac{k$iبt#27v9jֱ_`9:0{ |hzo_j?l~{f ơGn?J+?h61 Q1$n۝kwݓD0$qF76SPu5+e tñHjhTkKd-]Ӳ=gi-0\v:G]mA4{x+oe;خLyˏ9~ug}(!^gkԑ}bKԶaOtׇ1幷{\=!O478'rhFۃzumYC#/~];s+^PY{g\[k;8cKu>4vG2dmv16#!Sۭn/5 QޯuN!%3С 9hLp8 [u-5Z-hǗ +͒a׻5_֬W#:a"ǰ|e:Ʈa{7${1MۭnD8ewq[l2{Y =îh1muGa5bŤcn|X7lvtE^Ҍ߮;9򃀂w_1$g]%=V[_7۫$;4ggωth7MeȞH^GS:2ӣЗ.R>ͮZʴVkˊ+xqhej:@=GLXlW PDJjӄ1==2CY[\L|pV {WէW+K7g{Wf6GKw:ݺAֺt֍K~m:|zH:~{DwoT޽E?3ɋm=Hzsz&hl ^Νï _4oKu6L/]+獋_g{0>_IWlOWj3jͳwC]x|a0 _qjv?L \>S _\};Lʭ~dzlܘ|qxwkaA0rL-\v>Zyy{7:;g/|q&gF[r~1\g] x$8z?z\NNo\4{?Ѱ7y oN@3=:#֓km=sw^jv4[Jx?pH3{oZ>[7g~~ƵمG4^{+ c'o>ݾqۧYnWߠgg 6ƶt_ݸ|cq%4͵ܺ8$H&n܍3{o޾}:yuKx:/ά]ޙk Njmٿ,|ycŻolNF30K[+ ;OG7~=_Xwn}&oN=g7w[Dob:ƭ7H#ooZv{# 8b:qyDv]݄O 6zcƏړSi +:V{q:zan\M)ܬ_k?N,u\U'V/5Q~ݺR vVUE?iVj0˷їDUa5ݪ^|X}Yh6U=NW^^{tuzGLVg/=}U]띩X}{zhLu~UɉXX>Ӫ-.GՇG{oFOyaR}yuZuեV>n;vWj7oV䭑b}odtwvydlvtld|ÑɹkT#rH(wkFԛGһG.]<z~yzۑk#7^މF_,GZYXFuF=y莞ϴGF^U_Wo^Z##"fpa<:;3:]h?Zoi:tť|>:譵+E\}::qnE;2Z_FvF;okF;Fc3ό\hL3wl;;Y;[wEؓKg'=?+;gwǮ 6ܺuvΕkI٧#'g_ߞxӊϾyXu޸7VKcWų뭙q;cO;c.\zЊ^7ճscS禚OE^]w;ƹW{=rokfts׀z:^̞Y|qʛt0pғeM#tƟ?77n.gx|0{gdl11=7:,-]_v?Zޘxr{ꝉ𚉷T?;v|mnEoguv/ϯo^<;?z691ŤL&/Y"؜{a=xIo>?;f9MF'5_^7^<}vauajxEpag}H٫SũoOiov/OmoM[c]xMΣǵGKwުow#SOjzn镋p_NktToW_3vpMo{ +:~w'ŕ-Xn"źέG֌WMʫ݅3|rvSjf?oFυk0&dv";s=|:F5`n2r9n??3O~x&T8Q7Ϊ+1:Po/OgũV|cvz-~pUoocQd7ΓUl\6+˷nwf;d+e&wVٱGٽ3䧗/\uyux>v/L]{:w+w[+se +^yww_e@ݱkSSs׮z~n=>rsL6~z}cg{wLX֚YxzǛ3oշf]~3ۙf_5&kjwχs3r`p{ns3O6擕+[3_,-L]m-̦'>,|֘[|ݞؓwo_mN^{֣;+w|-!exKiҕWr,9ٛ Q}|5;aK.T;޺;/<|>v7>}v׮{{pizyE8zozO~ +#6=O>y^O9S|vU2MJ?Zt;f[E|UO' XM|(~_U/Cizr]yr'y粘_{@}ChBMz|4s;sĨC?|,zJ7@U|^.o2Z"!<_o:z: :E&#~gn1D7XؗZx\yr\4q'EjpKU`FקV i*f/Nuviߜxӧdw?;? -z 5_PgA3$g``?d +$@,̽|w&ܤO L&.R9Ѵ<*yȠw:E?;^?=`(@C*ß,&_B ^4T[?,|Lt8|]tl=xوV.<+]=g!"lɍ{^3?z=q^%n2x]dǯ&"턏Kj)S0[;#Z;4+K֞n +LR{2K2)ti]kU㖋ߧ,E#3fg'ڡI/L.3SY?%JI84*5u"4!I 7_?T—f +6S'"29LJcK_hBʗO-sɞso(Ebnƒ`Jo^/Ö3]'3k /kطC'տ +O MN+[sc|l0^gt?5}ELv?>T%O XxJ'sR͇?VKBz%:'x?W48zbx41yyveTףPO|+aQn_nϒ8~a"FS?~/]ԜGTQwzY-4O:9`3 @RntCmy5b/wt릞"0n#DВu1Od? )$S!Цܠ\a4L]N~0^N# +dB+hA04L(p)S.)_ FG +OY~uYR>m(H,LSKc2t ڼ5- 42$ 1 dZFC>ǽ0{ d9e_Upi>'ƀI.M*KK rB3BEfٍֈ@2,P9,,nU"I$ B -C\hN_&dfHb'%Wɋ-dTQ54"Qgdni>Lx4 +dHܘ19aK" +9h +.hyS-4?ӇVSޚ߅`wbб8s^6h]m PQUGD SHtBFld ޮ ߄? XQgaJc2$F%#~V沘>ۏ4q 4I)\&AEuUhA(8dsc '17E0\'/ݹ;L:!P!x]CFO`eQ'/2'B+$I8^Y +bhMՔFZ4_X޲#oA2)qzWU%a}ʿԆ`P K[h7 Ihy.1y9q~cTxWW4s!%mW殘 +ONPF- ^O^.aFǓ#O]C0Zvt;,8ru#́H -0B[fԢnZZЕ?u04i}C;.{fnJ/uĔy8,!b7 1_♎]|4~BwJӧDNߖLFAOizTʲZ|}'ofrߓ2dV,cϜFYXdUgJ~,zߧ|'ϾU *uJֻI|zćd=9ѹ ,N>iZ"{ ;/s(N"hg?ɈFಗKh}=/}p&E[.4%CD͗1pf.Gy ++i~8cwALYnӏ+i~w ^34eL?}廀3mI̫{@F ﷨b'4FN|'D&>WAW +Y7<{psC~i{t;RL39H6+-gGX}+ކx ﱫA3̟3,Fp4ZF / PV9Q"lijх_;}c`/SQE%:R@.2EO'xpkʁ,JQ5" ^84n NC^4蕓y?+vu9GΓ-xg$PhM<"MԳa +wu ZfqæU[]r4|1M sfTXE|<H7&E7jĹH0z'(Ը+RL4pd`[S+ӌɉ|c?}#6%g_**]KQo0{6N.-Df6,:4 +/箘VpO\uKF46 rPnW'υK(?1سe$uтTKЁRVB2\ua.˾_+*I5s'0-`A2+?(P;H++tn8_x([!wkLI!6kFʭΜ}̕$tV rAUK jk3~//q+xPs0|h'pQG.Z/jb;VaF>!ߠ_?7ŵ2=5dxd]kQV}#ͤpgMA셟#0n%nuѬ dA'.O?ڇ%2`2%tq"5JBlx1 󓿍IMc @F7biN1Ctjn[7%Wq-S7)0]\ƨo=࢙U^9Aebއk۴AnV}U/[͞tQuffyתk<O"kthF?i?'(!ˇ??gXh!i){7Rzxߴ@7Bɮ /ݿ# IIO)<ɒC1paUv).)  0@U+F++)/X+)/d*Cr}~ E+qߨϠHr2hB32jv&eYg_?}ꆬ;$+T}6ؚƻ6z jnz11Yo:UjaJWٻa.bLD2eè2|.2_Es@jm2)BFyMELGU)߄k=ҬwZF +xV$M77[pfu߹bL}߀jǵ%<'~igIč{[869^ݦjfÚt"V=%9=EmQVƯo2?:4Nz?Y ԠϋWf J_{~a}W VmTDL,b%t^SV_!DŰ{v, +Q5Ul!DS}%!. +i9&x}Γ]7x;?XrO;T2/4ʵT1F]b=* ?̥Vx~. wFU +c-Q#1V@'HXAȩ LpiT`}HPu!H#>V@3?*'u/bagC+Fb k:=0ViV~ŵ!֛S7k6a)#x#M{d4Q^+YcMX붘NcV" uKG "?^RZy\=?b}U0V߬M>Ew2euX[ M ] b`]=j+F#">z1JfDbCu;O*~Qh2|i6akU=LOWϝZ*OW7aN9c_CAݦt>.O~q2zHF%d4_̟~:nh/dWӧu8Ř?_*OD㝗GI9q;'Oܿ1ݷOIm}DWoF/fO]S>~&WG86}hL˦OGwLJyJQ11tu1}Zed˂hqn3}ZȜOLꈶ Z{&O#epFW4J,r(/ps.prEы=&k!R(;__Z,s6X_MOusM<پ#BDػJRpvĸAQӒN _VAjeϣc7%٣@:ßg}/l +jd ]ɫ Ʀ VމGc\+)_^OSBXju KZ8zQa86: +#@k[&&g)Vl`lF3gS@9gX 2>pݦX`R@)Mc~K oacg&Nuȇ}¨2\Y/Dk3'Y\D9sr֭3PIN=h#$Sob*`X #+=A +5) OD X;0(Z'w6%oU a%s֦Eۥr)RMI(mZNI"Z(Uchhi(T5r[(nb]}.ƝT~7Se7a:B47 ?(9t#If4HZN0MzY@}ٯ)(ik^ip#RKI*=nN}C҃ 1g51L襕BU))hk*LSei O2&_5&= +|ؘ|T.O3\hi5<>6u<_GRD E$׍K5lNDX@s7hH8,zTzʛLU`Je 1F%m(c?Gd &:L[]h;j--'Inѯ +qIOf4hYE*U"qA.>:FF(-Y͆v:-*ܿ:-:̮EtM*/0ݦpm2%DJRۀ^e/"U5=/O択4}d1ckmcEƱR`K;@Zi7M;&Ehmk#ga݉֝hZaǦ:͋0[n6~=*fd[u2M}/Eh3=̜&ݕ,K]67'PĮmhz%N`1uxݬ +Dbάz:#hIM2y?n`ئrjyC*W8 /l*J1$& buc[-ENtpYvEAE#t۠U_KxWU + +  95vw\(MBa{ɶ'͏ƙo=jXd4؏{ǧ^)@4a3#nȞ@3Ym˓-psndE&md+\2r>64Û0+ue'=k~Tswn3reWU_:_(:yT[Ji2Z磭Ul.מ 6Ʃqș'X'gNnrFp{%pFgrr8Bw$A[L&lm=o@4[vWM\?LEmG4ɶA!8AB=5wUjkia`tۤ `0b6A(\cmۃfVNBnc=.0.ec偒{#e8;otg-(bgƞx TWV/5z+<-kaoU}ei_|A+&n<6`COuSb'Yۧ5GקYi喑oLҢὩbͮ@K>ὑ"k㡓]7j@uw X nJ[FAF - C;"PZE(g(l~F้_=NɇԼfAl澨 VC.KaXgLe*UrlxfyjN」UQ͝O顧da48gggfϾ3v 302{ǥh#3O ?Cf{ߙyTIr޾3Tyڠ#eXkfq!S%4::zV +G쮪Awr=Z N)QOÀPr6zhT|LX}+Gݿk&C]C]֣v?582t=vףhMin{l^2aZ@]fv{׹iٺ(7BYp7R5e}ըnMumM֤'IwOI^dQI^d {]fóx_%oPbzluIy&2mIy$>fIy;:D67=wHSH^_g~ Li6-ƨ +>Lڹ^Bk&=' 3f~?ߦʛF&Tm1 A*4볮)~O +٥j](+ !M^~zݼs,cNlmfJhr,)j.z*p3'׷ӢJf(1Q<.zoLvwzyvZF>|cr`ǵ[Viw)VZ&.?{fX_,1V}FX?Wiw\.mԥy끶NYt'G췟5~fI}10:\SepX2=aEީ{A*T6{fZ T ٌJ=l|VhL~l;Xkz:fѭu`M}3*r`p _Uyvy'1$g.78;A\W7yVFuۄ_WcEE6X7y=&ӣvqoطf>#+Ar1}6;&yW}FY}&b'Mا!xH@dľm7 <>>_`?}FY}vO mg䥗L=&0q5HќRObQV߁;$i@mgb7hZاV}Z~6 .}:P+=%mG3g>#͞-{H3:w}+{J쳱#ψ*U}_}kgg|d1؈*}U6sʼj Oe;wͲП;T[]BG߽:i\$ѵچM>ФFcuK'BAFYtKڪOhЭT[l Ej5ɔsǦk*[mͲTwt׷)g*l4|ہYB>[g.֜V6_NK띐6;4;; Yxk ?MkMAGmoǟ5E7:c{pg^\j&Be֞p\ǥ({[9}vNP#4ONvDh,7npH Ych{ӭOiBWV+Qe~֚3趏Zlh6[Ƃp?GRPE[% V \#(c7XJaL{ Vi }x5f }&#ԛ)5F4iuj۷FIG vSh?1ΛK[ZRx06ۗ6 Zt; h +sbDٵ)~xg#ž~RY-֣y2m/uUuߎ&|6߁\@phQ@e';eVuqQپ`(?&l_^ͨuپO[f$bFv6dsOǶʻEh21BI'Dwf~D}9"`>iM^<*5paT0QlD#94k5VMf; gK[.{ldyg˗8к@g;kY>)V45.Ur>ܚbuWwt^끜PaTX9rspTXduI^O+ADWӤj + ]_T[}r^k7Zr>a=eMUڝ9Bᶨ=8 ,`L;P{R/xH|(('Q9#i¿,|6Og]#^NRk6y4mlL\ޙbzp˴Oͻ_>j~40]SI[7qJ_CzܚN*]l*nq J>[Y7 0@c-sf}Bأs:UxJAŘ, ^q:m(A^le閶&vb@ɐ\n;絪O )Z%mK\WzT!+}`Xfgh + WR~-v60]fDsO&VFh[$G\>QV>Ցx)v Л$GTnh7NIrvDhۧ$*$ LMS#*V)&}ZG=IVǵ{Ev)V_Xp+,- +em*Kp{NIvۂJڡZCRc낇Hi-c(\ܽF=#l}_Da)ӔOl',Gg& +m吗IzV(g6cf1nr'+!3v_;ϱ['ugT"]fySo¯+=-_^G~GmTCyfHĽdG9^D~<÷5kw5<߮뚥">f=%XxGn4KRg&o7wv0wNSl-K^T?^bb)AEFXS# W>0mdDG= KhR'*? Lj +TB9O?tqlD[Fڧ;n }쁄c(P׸ PDQ_ȆoF,|΄=n׃jHh^"C0%Ncm1QthR뿒,KtqSAJEKŴ{Wgi#hij2#yd"&E2y^mX~~=Ҳ80X)X׀0]cAŸ葒~uh;}I<рU=8n}1/.q4s6eÎ-/QgTePIɐRy +X_EYt(D=GKh0ҝ}p<:/bhjIw.PՒ?̋E9HWQïձ; xW=_׏҉H(]8JfyQ&:j9yyqzy?sˣd8ޫ%S9SmH(`MGZcqB/>(DY-Y +`SMtA22ȳV&W䃏~,DeYjH;kTRjBIk{q p$Kb(fP"a#KZ -T$f:!.=®Od5;pt?AM#;'LbGAmCdbu}:;[J"Y1rsN"dy+iw2 ӗ]lȳwn ? agi +.hM_bt`Oڳ6vVF%(YP4!DO~E಩&0$9q+Lp7ܾ )(@c;OQ\c밵M1 +mY<=9}}ig!?kH3d=f%of=rs/^xA0/;#^O]ˍ-Պ.e +Ct-#ĥI _i(LrƏzʕrƏ9iS!"KX-X9ALx e=ȯSO~zxgqm ?kL'R-.pʞ|N"K8?,Qϒ_zXB!h腰L'lh ߿Dc PхoDk< !qSlOD>9C9ռjw`lv_VzZMtinC>ǰ~-s6R{9JE^QpfQFN|t +^+J!'|.g3&pu3/MRF`xHLE^dsrNQc6+^j'o||!m `7Oy@ #}p]|E/c/jtx3C&^P$>9g3fq&.8G0Cxt:qo:zr38oE~7',2ՆQvYoLT˛)p{,@ߌD" ɪew"/?@r@֞VBZJ~Z5"߸Y@TN3IҙtԨK^1֓Qh(9׀Q4tK]@g@(*)u{ ECDh4{ECfOQh(w@t5ZD,6#p)o9Q. $` XSM;`mX{{"NY=Y#KLŷgI8rDhѽ?HtEщ*ٞD+xSEg?[95 2P5JcVԣ$9+/!KA'e$ +Fˈ()0M0J +endstream endobj 144 0 obj <>stream +Yzz)UY҄`=e$΅D; k*iIS*]RDbUEYX,veC$"-9VD(̨N@gP|R3a4V"ʙ]SbOB"xDV#%'Hl V'HvV9Lƀ-]jڳد0iNhQs^|SoϵuR-H {mot/> >ϷvS5phX$ƒ],vJtH*:`ϖH.ug hF9|.-ipbTŊykH&P1 + \^'$ + \kiimgM;a :_SeZmAuMl4x)_Jsd_D$-KuP{6U$@`<)>W}@λG 䤋:BcluhvBL3b,-{FF=-9q<-YGNx!(gx䬟J9tԝV ?:_9$b{W!F'u8)V'qVgOO^ +>QzΡ6\_ڹ?- wQ}8CAt v[L+ͼ[UQ[-]$Hjϛ8ASt0삦b9ůD!DHzϟǟia3Eu9f?y?tCԋ]a9E^(G?jB1 + Qg!EY~Z(-w4*u퐦,= 2G7{X?a1+1.(jyC0& Ta[Q@# +ѱE?(E8:bG#pU oA Xll@f >x:E6շ*F٨qA۠㖐Px;YhU+4c(t2Ap &&AF:"FmT&Bk!jх ZxiZ0@WDA1bAo"Ǥ2bb!f BQ^ yHRΒv84>g?((.z\ )qa`%-aQ cex|E&7"4YB,b6 +,?7 kԤ>,#la~4:c3=T)^H(n3";Ս52YEPOjAd:֫2R2e>|@7xMi:a#9- sC.4Rep# JЖUw;"vEW#.U;x[X\n0 ͑Ňl +$oD$ - 8/˛»W~21GC !:BsI765҃:j@]dƓ!50t:b fa9i9G|ߑc0k1>X0+b4,n5927% I3hPpмҏְ?Y1Ll. ;!HD<1Q~\c! t2>#+အ}+aW03!Jz *+Dc;3D& +!# { +rP(L*n8^h__NpYcBR1;qFwxgr *(`CBUI('M@ؑQPdI($(@Eu6/-AG#`[zWCo'G뗉"& W0b(8w a%=!{#RFJ-2<4 $o'rdNSQ!Dit:FD˱QvlDALU$\4t e%,F35iv' O14ck7ʅx=Îŋ&lţ#1"4z'm[5Pж̢91Qؑ+c!,=D1fXxdĈCJ)2R6<ȏfgpS +9`{X44!.֐hA,CfG.c"BFA sAaՁaBDDJnEQ<S OX>X +*$Y"Mf k1B\@QAk@̒oAD@ p|4!; ^bg U8"0a6%!Q,/*|C\nD~ I%DDIaL=:&H8_IPl`*XpJ-$)M~Ole\AH4JTdD E(PQ(EyU8FD^JǤFՈDPc܃eB8YFfESwe'F74lIi2 PO $C$Ũ: 2B3Ë?P1IFXF:E4Db$HyFl^l4E+ChGBu<+ - +5pԢYQaF "a,ۄgA0J-U#Aq/< [4M` + %MSEѨ4ay?0I@kķf1pEXx[bnBY$&_)>">pQ8a2d*`ED*0hC*pp˹jV}li=x 3M!&|DH$Tn@:"hߒJy?jD@D&E,YH?`)*j[)F ߏgCkY F}؜>y? {1φd6<LZG.Wx<$ +endstream endobj 5 0 obj <9 1)/Type/OCG/Usage 16 0 R>> endobj 26 0 obj <9 1)/Type/OCG/Usage 36 0 R>> endobj 46 0 obj <9 1)/Type/OCG/Usage 56 0 R>> endobj 66 0 obj <9 1)/Type/OCG/Usage 76 0 R>> endobj 86 0 obj <9 1)/Type/OCG/Usage 96 0 R>> endobj 106 0 obj <9 1)/Type/OCG/Usage 116 0 R>> endobj 115 0 obj [/View/Design] endobj 116 0 obj <>>> endobj 95 0 obj [/View/Design] endobj 96 0 obj <>>> endobj 75 0 obj [/View/Design] endobj 76 0 obj <>>> endobj 55 0 obj [/View/Design] endobj 56 0 obj <>>> endobj 35 0 obj [/View/Design] endobj 36 0 obj <>>> endobj 15 0 obj [/View/Design] endobj 16 0 obj <>>> endobj 127 0 obj [126 0 R] endobj 145 0 obj <> endobj xref +0 146 +0000000004 65535 f +0000000016 00000 n +0000000234 00000 n +0000056742 00000 n +0000000006 00000 f +0000278602 00000 n +0000000008 00000 f +0000056793 00000 n +0000000009 00000 f +0000000010 00000 f +0000000011 00000 f +0000000012 00000 f +0000000013 00000 f +0000000014 00000 f +0000000017 00000 f +0000279654 00000 n +0000279685 00000 n +0000000018 00000 f +0000000019 00000 f +0000000020 00000 f +0000000021 00000 f +0000000022 00000 f +0000000023 00000 f +0000000024 00000 f +0000000025 00000 f +0000000027 00000 f +0000278679 00000 n +0000000028 00000 f +0000000029 00000 f +0000000030 00000 f +0000000031 00000 f +0000000032 00000 f +0000000033 00000 f +0000000034 00000 f +0000000037 00000 f +0000279538 00000 n +0000279569 00000 n +0000000038 00000 f +0000000039 00000 f +0000000040 00000 f +0000000041 00000 f +0000000042 00000 f +0000000043 00000 f +0000000044 00000 f +0000000045 00000 f +0000000047 00000 f +0000278757 00000 n +0000000048 00000 f +0000000049 00000 f +0000000050 00000 f +0000000051 00000 f +0000000052 00000 f +0000000053 00000 f +0000000054 00000 f +0000000057 00000 f +0000279422 00000 n +0000279453 00000 n +0000000058 00000 f +0000000059 00000 f +0000000060 00000 f +0000000061 00000 f +0000000062 00000 f +0000000063 00000 f +0000000064 00000 f +0000000065 00000 f +0000000067 00000 f +0000278835 00000 n +0000000068 00000 f +0000000069 00000 f +0000000070 00000 f +0000000071 00000 f +0000000072 00000 f +0000000073 00000 f +0000000074 00000 f +0000000077 00000 f +0000279306 00000 n +0000279337 00000 n +0000000078 00000 f +0000000079 00000 f +0000000080 00000 f +0000000081 00000 f +0000000082 00000 f +0000000083 00000 f +0000000084 00000 f +0000000085 00000 f +0000000087 00000 f +0000278913 00000 n +0000000088 00000 f +0000000089 00000 f +0000000090 00000 f +0000000091 00000 f +0000000092 00000 f +0000000093 00000 f +0000000094 00000 f +0000000097 00000 f +0000279190 00000 n +0000279221 00000 n +0000000098 00000 f +0000000099 00000 f +0000000100 00000 f +0000000101 00000 f +0000000102 00000 f +0000000103 00000 f +0000000104 00000 f +0000000105 00000 f +0000000000 00000 f +0000278991 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000279072 00000 n +0000279104 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000059692 00000 n +0000279770 00000 n +0000057155 00000 n +0000062692 00000 n +0000060005 00000 n +0000059891 00000 n +0000058655 00000 n +0000059127 00000 n +0000059177 00000 n +0000059773 00000 n +0000059805 00000 n +0000060042 00000 n +0000062768 00000 n +0000063015 00000 n +0000064112 00000 n +0000077650 00000 n +0000143240 00000 n +0000208830 00000 n +0000274420 00000 n +0000279797 00000 n +trailer +<<0273E798DCABFC4085A2D3483F945805>]>> +startxref +279989 +%%EOF diff --git a/distr/design/trs.png b/distr/design/trs.png new file mode 100644 index 0000000..23883d2 Binary files /dev/null and b/distr/design/trs.png differ diff --git a/doc/!Testing ascpects.txt b/doc/!Testing ascpects.txt new file mode 100644 index 0000000..7ede493 --- /dev/null +++ b/doc/!Testing ascpects.txt @@ -0,0 +1,18 @@ + , + + +- nullptr, nullopt +- +- CCL +- +- Drag'nDrop +- +- +- + +Exteor (Application) +- + +OSS +- +- \ No newline at end of file diff --git a/doc/TO INSTALL.txt b/doc/TO INSTALL.txt new file mode 100644 index 0000000..0911f3d --- /dev/null +++ b/doc/TO INSTALL.txt @@ -0,0 +1,8 @@ +0. Visual Studio +- clang power tools +1. Python 3.9 +2. pymorphy2 https://github.com/kmike/pymorphy2 +3. Innos Setup http://www.jrsoftware.org/isinfo.php +4. WinFlexBison https://sourceforge.net/p/winflexbison/wiki/Visual%20Studio%20custom%20build%20rules/ +5. Help- HTML Help Workshop Microsoft ( Windows, ): +https://www.microsoft.com/en-us/download/details.aspx?id=21138 \ No newline at end of file diff --git a/doc/Как ребилдить lib.txt b/doc/Как ребилдить lib.txt new file mode 100644 index 0000000..7460384 --- /dev/null +++ b/doc/Как ребилдить lib.txt @@ -0,0 +1,4 @@ + , lib- + +1. htmlhelp.lib + HTML Help Workshop \ No newline at end of file diff --git a/doc/Порядок выпуска версии.txt b/doc/Порядок выпуска версии.txt new file mode 100644 index 0000000..adc450f --- /dev/null +++ b/doc/Порядок выпуска версии.txt @@ -0,0 +1,11 @@ +1. Testing +2. ( !) Installer +3. ChangeLog +4. +5. Release +6. .exe, .chm, .. +7. +8. +9. +10. FTP +11. \ No newline at end of file diff --git a/header/SetupManager.h b/header/SetupManager.h new file mode 100644 index 0000000..b9558a8 --- /dev/null +++ b/header/SetupManager.h @@ -0,0 +1,18 @@ +#pragma once + +namespace xtr { + +class SetupManager { +public: + static void CCLInitSequence(); + static void CCLExitSequence(); + static void InitEnvironment(); + +protected: + static void InitSourceManager(); + static void InitTextModule(); + static void KillTextModule(); + static bool LoadPython(); +}; + +} // namespace xtr \ No newline at end of file diff --git a/help/Index.hhk b/help/Index.hhk new file mode 100644 index 0000000..c0ba08a --- /dev/null +++ b/help/Index.hhk @@ -0,0 +1,9 @@ + + + + + + +
    +
+ diff --git a/help/Table of Contents.hhc b/help/Table of Contents.hhc new file mode 100644 index 0000000..1382689 --- /dev/null +++ b/help/Table of Contents.hhc @@ -0,0 +1,199 @@ + + + + + + + + + +
    +
  • + + + + +
  • + + + + +
      +
    • + + + +
    • + + + +
    • + + + +
    • + + + +
    +
  • + + + + +
      +
    • + + + +
    +
  • + + + + +
      +
    • + + + +
    • + + + +
    • + + + + +
    • + + + + +
        +
      • + + + +
      • + + + +
      • + + + +
      • + + + +
      +
    • + + + + +
        +
      • + + + +
      • + + + +
      • + + + +
      • + + + +
      • + + + +
      • + + + +
      • + + + +
      • + + + +
      • + + + +
      • + + + +
      +
    • + + + + +
        +
      • + + + +
      • + + + +
      • + + + +
      • + + + +
      • + + + +
      • + + + +
      • + + + +
      +
    • + + + + +
        +
      • + + + +
      • + + + +
      • + + + +
      • + + + +
      +
    +
+ diff --git a/help/help.hhp b/help/help.hhp new file mode 100644 index 0000000..b5a2d25 --- /dev/null +++ b/help/help.hhp @@ -0,0 +1,62 @@ +[OPTIONS] +Compatibility=1.1 or later +Compiled file=..\distr\app\Help.chm +Contents file=Table of Contents.hhc +Default Window=Window +Default topic=html\010000.htm +Display compile progress=Yes +Full text search stop list file=stoplist.stp +Full-text search=Yes +Index file=Index.hhk +Language=0x419 Russian (Russia) +Title= 4.9 + +[WINDOWS] +Window=" 4.9 - ","Table of Contents.hhc",,"html\010000.htm","html\010000.htm",,,,,0x62520,,0x304e,[92,138,1117,967],,,,,,,0 + + +[FILES] +html\010000.htm +html\030000.htm +html\030100.htm +html\030300.htm +html\030400.htm +html\040000.htm +html\050100.htm +html\050200.htm +html\050300.htm +html\050600.htm +html\050601.htm +html\050602.htm +html\050603.htm +html\050604.htm +html\050700.htm +html\050702.htm +html\050703.htm +html\050704.htm +html\050705.htm +html\050706.htm +html\050707.htm +html\050708.htm +html\050709.htm +html\050710.htm +html\050800.htm +html\050802.htm +html\050803.htm +html\050804.htm +html\050805.htm +html\050806.htm +html\050807.htm +html\050808.htm +html\050900.htm +html\blank.htm +html\050000.htm +html\050902.htm +html\050903.htm +html\050905.htm +html\050904.htm +html\041000.htm +html\050711.htm + +[INFOTYPES] + diff --git a/help/html/010000.htm b/help/html/010000.htm new file mode 100644 index 0000000..8076f17 --- /dev/null +++ b/help/html/010000.htm @@ -0,0 +1,97 @@ + + + + + + + + + + +

+ +

4.9 + , + .

+

!! . : portal.acconcept.ru

+

(), . + , . , + . + (. 1). +

+

.

+ +
+ +
+
. 1.
+ + + diff --git a/help/html/020000.htm b/help/html/020000.htm new file mode 100644 index 0000000..558fc73 --- /dev/null +++ b/help/html/020000.htm @@ -0,0 +1,59 @@ + + + + + + + + + + +

+ +

.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
- ,
-
- ( -)
- ()
- , ,
+ + diff --git a/help/html/030000.htm b/help/html/030000.htm new file mode 100644 index 0000000..4eaf11c --- /dev/null +++ b/help/html/030000.htm @@ -0,0 +1,24 @@ + + + + + + + + + + +

+ +

4 . +

+ +

+ + + diff --git a/help/html/030100.htm b/help/html/030100.htm new file mode 100644 index 0000000..700ca35 --- /dev/null +++ b/help/html/030100.htm @@ -0,0 +1,95 @@ + + + + + + + + + + +

+ +

4 , - , + . + + .

+
+

1990 , + 4.

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
. .
ExTeor 3.0, ExTeor 3.1 . .
4 . .
. .
. .
. .
. .
. .
+ . .
+ . .
+ . .
+ . .
+ . .
+ . .
+ . .
+ . .
+ . . +

+ ..
+ ..
+ ..
+ ..
+ . .
+ . .
+ . .
+ . . +
, Exteor 1.0 -> 4 . .
+ ..
+ ..
+ . . +
+ + diff --git a/help/html/030200.htm b/help/html/030200.htm new file mode 100644 index 0000000..d63a355 --- /dev/null +++ b/help/html/030200.htm @@ -0,0 +1,77 @@ + + + + + + + + + + +

4

+ +

4 ExTeor 3.0.

+
    +
  1. +
      +
    • Windows.
    • +
    • Boolean + ( 4 ).
    • +
    • F1.
    • +
    • , .
    • +
    • .
    • +
    • , + .
    • +
    • .
    • +
    • 4, + , .
    • +
    • .
    • +
    +
  2. +
  3. - : +
      +
    • ;
    • +
    • : c -, + - , + , ;
    • +
    • ;
    • +
    • ;
    • +
    • ;
    • +
    • c ;
    • +
    • ;
    • +
    • ;
    • +
    • - .
    • +
    +
  4. +
  5. : +
      +
    • ;
    • +
    • ;
    • +
    • - ;
    • +
    • ;
    • +
    • , ;
    • +
    • .
    • +
    +
  6. +
  7. : +
      +
    • ;
    • +
    • ;
    • +
    • ;
    • +
    • PNG;
    • +
    • ;
    • +
    • : +
        +
      • ;
      • +
      • ;
      • +
      • ;
      • +
      • ;
      • +
      +
    • +
    • ;
    • +
    • .
    • +
    +
  8. +
+ + diff --git a/help/html/030300.htm b/help/html/030300.htm new file mode 100644 index 0000000..a656616 --- /dev/null +++ b/help/html/030300.htm @@ -0,0 +1,24 @@ + + + + + + + + + + +

+
+

4

+

, , + . ,

+

.rtf,

+

+

4 ܻ ("AS IS"). + . + . + һ , +

+ + diff --git a/help/html/030400.htm b/help/html/030400.htm new file mode 100644 index 0000000..d212a83 --- /dev/null +++ b/help/html/030400.htm @@ -0,0 +1,36 @@ + + + + + + + + + + + +

+ +

Web: www.acconcept.ru

+

E-mail: bugreport@acconcept.ru + / post@acconcept.ru

+
+ +

! 4 -! + / + bugreport@acconcept.ru. 4 . +

+

, :

+
    +
  • / ( - );
  • +
  • ;
  • +
  • Microsoft Office;
  • +
  • ;
  • +
  • , ;
  • +
  • *.RSM, *.TRS *.OSS, .
  • +
+ +
+ + + diff --git a/help/html/040000.htm b/help/html/040000.htm new file mode 100644 index 0000000..152e55e --- /dev/null +++ b/help/html/040000.htm @@ -0,0 +1,26 @@ + + + + + + + + 4.9 + + +

4.9

+ +

4.9.

+

, !.

+

: bugrepport@acconcept.ru

+ +

+ +
    +
  • +
+ +
+

+ + diff --git a/help/html/041000.htm b/help/html/041000.htm new file mode 100644 index 0000000..db90e67 --- /dev/null +++ b/help/html/041000.htm @@ -0,0 +1,26 @@ + + + + + + + + + + +

+ +

, ExTeor 3.1 + .

+
    +
  1. .
  2. +
  3. ! ! + . .
  4. +
  5. ! , . + .
  6. +
  7. .
  8. +
  9. .
  10. +
  11. .
  12. +
+ + diff --git a/help/html/050000.htm b/help/html/050000.htm new file mode 100644 index 0000000..daa0e2a --- /dev/null +++ b/help/html/050000.htm @@ -0,0 +1,71 @@ + + + + + + + + 4.9 + + +

4.9

+ +

. + ... ? ? + .

+

3 : - , , .

+ +

+ + + diff --git a/help/html/050100.htm b/help/html/050100.htm new file mode 100644 index 0000000..969b60c --- /dev/null +++ b/help/html/050100.htm @@ -0,0 +1,53 @@ + + + + + + + + + + +

+ +

, .

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
4.9.
TRS -
RSM
OSS
+

- . + - . + - TRS.

+

, + -

+

. + . + -, + -, + - -.

+ + diff --git a/help/html/050200.htm b/help/html/050200.htm new file mode 100644 index 0000000..f0b2b5f --- /dev/null +++ b/help/html/050200.htm @@ -0,0 +1,250 @@ + + + + + + + + + + +

+ +

:

+
    +
  • (. 1);
  • +
  • - (. 2);
  • +
  • (. 3).
  • +
+ +

, , + / , + . +

+ + + +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
. 1.
!
+ +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
. 2.
- -
+ +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
. 3.
-
-
+ +

+ +

+
    +
  • CapsLock ( ).
  • +
  • NumLock ( ).
  • +
  • ScrollLock ( ).
  • +
  • . .
  • +
+ + diff --git a/help/html/050300.htm b/help/html/050300.htm new file mode 100644 index 0000000..7d701b8 --- /dev/null +++ b/help/html/050300.htm @@ -0,0 +1,32 @@ + + + + + + + + + + +

+ +

, . + 4.9.

+


+ +
+ +
+ - +
+ +
+ +
+ +
+ +
+

+ + diff --git a/help/html/050600.htm b/help/html/050600.htm new file mode 100644 index 0000000..9d2e48d --- /dev/null +++ b/help/html/050600.htm @@ -0,0 +1,24 @@ + + + + + + + + + + +

+ +

, . + , , .

+ +

+ + + diff --git a/help/html/050601.htm b/help/html/050601.htm new file mode 100644 index 0000000..c8c5ccf --- /dev/null +++ b/help/html/050601.htm @@ -0,0 +1,50 @@ + + + + + + + + + + +

+ +

, .

+ +
+
    +
  1. +
      +
    • .
    • +
    • .
    • +
    • .
    • +
    • .
    • +
    • .
    • +
    +
  2. + +
  3. +
      +
    • : , , .
    • +
    • .
    • +
    +
  4. + +
  5. +
      +
    • .
    • +
    +
  6. + +
  7. +
      +
    • .
    • +
    • .
    • +
    • .
    • +
    • .
    • +
    +
  8. +
+ + diff --git a/help/html/050602.htm b/help/html/050602.htm new file mode 100644 index 0000000..50c84c8 --- /dev/null +++ b/help/html/050602.htm @@ -0,0 +1,86 @@ + + + + + + + + - + + +

-

+ +

, - .

+ +
+
    +
  1. +
      +
    • .
    • +
    • -.
    • +
    • .
    • +
    • .
    • +
    • .
    • +
    • - Microsoft Word .
    • +
    • - .
    • +
    • .
    • +
    +
  2. + +
  3. +
      +
    • / / .
    • +
    • ( ).
    • +
    • .
    • +
    • - .
    • +
    • .
    • +
    • , .
    • +
    • , .
    • +
    • .
    • +
    • , .
    • +
    • .
    • +
    +
  4. + +
  5. ( - ) +
      +
    • .
    • +
    • - .
    • +
    • - .
    • +
    • - .
    • +
    +
  6. + +
  7. +
      +
    • .
    • +
    • .
    • +
    • .
    • +
    • .
    • +
    +
  8. + +
  9. +
      +
    • : , , .
    • +
    • .
    • +
    +
  10. + +
  11. +
      +
    • .
    • +
    +
  12. + +
  13. +
      +
    • .
    • +
    • .
    • +
    • .
    • +
    • .
    • +
    +
  14. +
+ + diff --git a/help/html/050603.htm b/help/html/050603.htm new file mode 100644 index 0000000..0839c71 --- /dev/null +++ b/help/html/050603.htm @@ -0,0 +1,77 @@ + + + + + + + + + + +

+ +

, .

+ +
+
    +
  1. +
      +
    • .
    • +
    • .
    • +
    • .
    • +
    • .
    • +
    • .
    • +
    • - Microsoft Word .
    • +
    • - , , .
    • +
    • .
    • +
    +
  2. + +
  3. +
      +
    • / / .
    • +
    • .
    • +
    • - .
    • +
    • .
    • +
    • , .
    • +
    • , .
    • +
    • + .
    • +
    • + , .
    • +
    +
  4. + +
  5. +
      +
    • .
    • +
    • .
    • +
    • .
    • +
    • .
    • +
    +
  6. + +
  7. +
      +
    • : , , .
    • +
    • .
    • +
    +
  8. + +
  9. +
      +
    • .
    • +
    +
  10. + +
  11. +
      +
    • .
    • +
    • .
    • +
    • .
    • +
    • .
    • +
    +
  12. +
+ + diff --git a/help/html/050604.htm b/help/html/050604.htm new file mode 100644 index 0000000..d76cdca --- /dev/null +++ b/help/html/050604.htm @@ -0,0 +1,82 @@ + + + + + + + + + + +

+ +

, .

+ +
+
    +
  1. +
      +
    • .
    • +
    • -.
    • +
    • .
    • +
    • .
    • +
    • .
    • +
    • - Microsoft Word .
    • +
    • - .
    • +
    • .
    • +
    +
  2. + +
  3. +
      +
    • .
    • +
    • .
    • +
    • .
    • +
    • .
    • +
    • / .
    • +
    • .
    • +
    +
  4. + +
  5. +
      +
    • .
    • +
    • .
    • +
    • .
    • +
    • .
    • +
    +
  6. + +
  7. +
      +
    • .
    • +
    • .
    • +
    • .
    • +
    • .
    • +
    +
  8. + +
  9. +
      +
    • : , , .
    • +
    • .
    • +
    +
  10. + +
  11. +
      +
    • .
    • +
    +
  12. + +
  13. +
      +
    • .
    • +
    • .
    • +
    • .
    • +
    • .
    • +
    +
  14. +
+ + diff --git a/help/html/050700.htm b/help/html/050700.htm new file mode 100644 index 0000000..081fd2c --- /dev/null +++ b/help/html/050700.htm @@ -0,0 +1,31 @@ + + + + + + + + - + + +

-

+ +

, , -. + , -.

+

, - -.

+ +

+ + + diff --git a/help/html/050702.htm b/help/html/050702.htm new file mode 100644 index 0000000..894930b --- /dev/null +++ b/help/html/050702.htm @@ -0,0 +1,60 @@ + + + + + + + + - + + +

-

+ +

. 1.

+ +
. 1. - .
+ + +

, -. ѻ .

+

-. - . + .

+

(View) : . + (), .

+

: , + ( ), , , . + (. 2). + .

+ +
. 2.
+ +
+ +

.

+
    +
  • .
  • +
  • .
  • +
  • (Enter).
  • +
  • . 1 Ctrl Shift, .
  • +
  • . , (. 3).
  • +
+ +
. 3. .
+ + +

.

+
    +
  • .
  • +
  • .
  • +
  • , .
  • +
  • , ( ).
  • +
+ +

. + . .

+

txt- (. 1). + . + , , , + Graphviz.

+ + + diff --git a/help/html/050703.htm b/help/html/050703.htm new file mode 100644 index 0000000..4e97f35 --- /dev/null +++ b/help/html/050703.htm @@ -0,0 +1,113 @@ + + + + + + + + + + +

+ +

, . 1. + + . + , Alt + Shift + < / Alt + Shift + >.

+ +
. 1. .
+ + +

, + .

+

, + . + , .

+

+ , .

+

, . + .

+

, MATH . + . Control.

+

Control : -> -> MATH -> .

+

Control : -> MATH -> .

+

, . 1. + , . + .

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
. 1. .
pr, Pr, bool, debool, card
, , + ( 1 )
: 0
: 1
: 2
: 3
: 4
: 5
+ +

. Shift + F3 .

+

, , .

+

, .

+

. , . + , + (. 2).

+

. .

+ +
. 2. .
+ + +

+

- :

+
    +
  • / ;
  • +
  • ;
  • +
  • (. 1).
  • +
+ +

. + , + ( ).

+ +
. 3. .
+ + + diff --git a/help/html/050704.htm b/help/html/050704.htm new file mode 100644 index 0000000..768b81c --- /dev/null +++ b/help/html/050704.htm @@ -0,0 +1,38 @@ + + + + + + + + - + + +

-

+ +

- - , -, . ( -). -.

+
    +
  • .
  • +
  • .
  • +
  • .
  • +
  • .
  • +
  • .
  • +
+ +

. .

+

- (. 1).

+ +
. 1. -. 1: .
+ + +

. . 2.

+ +
. 2. -. 2: .
+ + +

, - (. 3).

+ +
. 3. -. 3: .
+ + + diff --git a/help/html/050705.htm b/help/html/050705.htm new file mode 100644 index 0000000..5d5313e --- /dev/null +++ b/help/html/050705.htm @@ -0,0 +1,52 @@ + + + + + + + + + + +

+ +

-, + .

+

. + 4 : - ().

+ +

+
. 1. .
+ + +

+ . 1. , + .

+

, . + . + . 1 .

+ +

-

+

-. + - , + -> .

+ +
. 2. - .
+ + +

- . 2. + , + . + - .

+ +

-, + - -> . + , . + + ( - ) , + -. - . 3.

+ +
. 3. -.
+ + + diff --git a/help/html/050706.htm b/help/html/050706.htm new file mode 100644 index 0000000..f1702c3 --- /dev/null +++ b/help/html/050706.htm @@ -0,0 +1,75 @@ + + + + + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID
X# () ,
C# ,
S# () ,
H# -. . , .
A# , . .
D# , -
F#- - . , .
T# ,
+

-

+

F# = [α11, α22, ... ,αkk] (α1, ... , αk),

+

F# -

+

α1, ... , αk - -. - - (α1, ... , αk) -.

+

1, ... , k - -, , -.

+

 

+

1, ... , αk) - "" - - - , - , , , , .

+

-

+

F#[A1, A2, ... , Ak],

+

F# - -

+

A1, A2, ... , Ak - , ( ) 1>∈1 & 22 & ... & kk.

+ + diff --git a/help/html/050707.htm b/help/html/050707.htm new file mode 100644 index 0000000..da7d1ef --- /dev/null +++ b/help/html/050707.htm @@ -0,0 +1,169 @@ + + + + + + + + + + +

+ +

- - , , + ( ). + ( ) , + . 1. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
. 1. - .
ID
006FFFC1
FF0000C2
00C8C8C3
964600C4
000000C5
+ +

- + , + . 2. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
. 2. - .
ID
FFFFFFCO1
D3D3D3CO2
E9E9E9CO3
+ +

, + , . 3. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
. 3. -.
ID
006FFFCM1
FF0000CM2
00C8C8C3
964600C4
321EAECM5
FF6600CM6
FF0066CM7 ( = false)
00B408CM8
000000CM9
+ + diff --git a/help/html/050708.htm b/help/html/050708.htm new file mode 100644 index 0000000..453bea3 --- /dev/null +++ b/help/html/050708.htm @@ -0,0 +1,38 @@ + + + + + + + + - + + +

-

+

+ - - ,

+ + + + + + + + + + + + + + + + + + + + + + +
ID
00FF00F1-
FF0000F2
+ + diff --git a/help/html/050709.htm b/help/html/050709.htm new file mode 100644 index 0000000..500777f --- /dev/null +++ b/help/html/050709.htm @@ -0,0 +1,238 @@ + + + + + + + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID
L8201 2147483647
L8203
P8400
P8406 )
P8407 }
P8408
P8414
P8415
S2801
S2802 ,
S8801
S8802
S8803
S8804
S8805
S8806
S8807 -
S8808 card
S8809 debool
S880A
S880B
S8810 red
S8811 :
S8812 : T(Pri(a)) = B(Pi(D(T(a))))
S8813
S8814 :
S8815
S8816 ?
S8818 -
S8819 -
S881A
S881C
S881F
S8820
S8821 -
S8822
S8823
S8824
S8825 /
S8826
S8840
S8841
S8842
S8843
V8A00 :
V8A01
V8A02
V8A03
V8A04
V8A05 debool
V8A06
+ + diff --git a/help/html/050710.htm b/help/html/050710.htm new file mode 100644 index 0000000..f11c152 --- /dev/null +++ b/help/html/050710.htm @@ -0,0 +1,82 @@ + + + + + + + + MS Word + + +

MS Word

+

- DOC (MS Word) , , . + - / . + . 1.

+
! + Microsoft Office Word 2003
+ +
. 1. - Word.
+ + +

, . + . , . . . . , + . . . . "DBTeor". + , . . , . . "". + . 1. # , .

+ +

4 . - .

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
. 1.
( )
X#X#
C#C#
S#D#
H#S#
A#Ax#
D#Tr#
-F#TF#
T#Th#
+ + diff --git a/help/html/050711.htm b/help/html/050711.htm new file mode 100644 index 0000000..b870be5 --- /dev/null +++ b/help/html/050711.htm @@ -0,0 +1,239 @@ + + + + + + + + + + +

+ +

, MATH . + . Control.

+

Control : -> -> MATH -> .

+

Control : -> MATH -> .

+

( MATH).

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID
αA
βB
γG
δD
εE
ζZ
ηH
θV
λL
μM
νN
ξX
οO
πP
ρR
σS
τT
υQ
φF
χC
ψJ
ωW
` ( 1 Esc)
Shift + ` (~ )
BShift + B
x Shift + 8
0123456789 Alt + 0123456789
Alt + Shift + 9
Alt + Shift + 0
Alt + Shift + C
N Alt + Shift + N
R Alt + Shift + R
cardAlt + C
bool ()Alt + B
deboolAlt + D
red-Alt + R
pr Alt + Q
Pr Alt + W
Alt + Y
Alt + U
Alt + ;
Alt + Shift + ;
Alt + '
Alt + Shift + '
Alt + Shift + L
Alt + Shift + =
Alt + =
()Alt + }
Alt + {
Alt + Shift + -
Alt + Shift + 7
&& (Shift + 7)
+ + diff --git a/help/html/050800.htm b/help/html/050800.htm new file mode 100644 index 0000000..375dd03 --- /dev/null +++ b/help/html/050800.htm @@ -0,0 +1,27 @@ + + + + + + + + + +

+ +

- + - . + .

+ +

+ + + diff --git a/help/html/050802.htm b/help/html/050802.htm new file mode 100644 index 0000000..625d0e3 --- /dev/null +++ b/help/html/050802.htm @@ -0,0 +1,108 @@ + + + + + + + + + + + +

+ +

(View) : + . + (), + . +

+ +
. 1. .
+ + +

: , , + . + + . +

+

: + , + . + , / . + / . +

+

, :

+
    +
  • , 0;
  • +
  • - + (, , ), 1.
  • +
+

+ ( 3 ), , + / / , NUM+, NUM-.

+

, + . + . + Shift .

+

, + , . + 4 , + - , . + () . + , + ( , , , ). +

+

. + , + Ctrl + / Ctrl + .

+

, . + .

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
. 1. .
: : :
:
: : + :
+ +

, + (. )

+ +

( ).

+
    +
  • .
  • +
  • .
  • +
  • .
  • +
  • , .
  • +
+ +

(. 2). + .

+ +
. 2. .
+ + + + diff --git a/help/html/050803.htm b/help/html/050803.htm new file mode 100644 index 0000000..aab0ed3 --- /dev/null +++ b/help/html/050803.htm @@ -0,0 +1,22 @@ + + + + + + + + + + +

+ +

, + / (. 1). .

+ +

, . + txt , .

+ +
. 1. .
+ + + diff --git a/help/html/050804.htm b/help/html/050804.htm new file mode 100644 index 0000000..0945d62 --- /dev/null +++ b/help/html/050804.htm @@ -0,0 +1,24 @@ + + + + + + + + + + +

+ +

. + / (Ctrl + E). + (. 1) , + .

+ +

, + .

+ +
. 1. .
+ + + diff --git a/help/html/050805.htm b/help/html/050805.htm new file mode 100644 index 0000000..661687e --- /dev/null +++ b/help/html/050805.htm @@ -0,0 +1,19 @@ + + + + + + + + + + +

+

- . + + .

+

, + , + .

+ + diff --git a/help/html/050806.htm b/help/html/050806.htm new file mode 100644 index 0000000..a293de0 --- /dev/null +++ b/help/html/050806.htm @@ -0,0 +1,56 @@ + + + + + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
,
,
,
,
+ + diff --git a/help/html/050807.htm b/help/html/050807.htm new file mode 100644 index 0000000..e5c221c --- /dev/null +++ b/help/html/050807.htm @@ -0,0 +1,45 @@ + + + + + + + + + + +

+ +

, .

+

: : - . + + .

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
-
-
-
-
-
+ + diff --git a/help/html/050808.htm b/help/html/050808.htm new file mode 100644 index 0000000..2f47664 --- /dev/null +++ b/help/html/050808.htm @@ -0,0 +1,21 @@ + + + + + + + + + + +

+ +

PNG , , . + / .

+

. . + . + .

+ + + + diff --git a/help/html/050900.htm b/help/html/050900.htm new file mode 100644 index 0000000..51fbe0e --- /dev/null +++ b/help/html/050900.htm @@ -0,0 +1,24 @@ + + + + + + + + + + +

+ +

- -. + - .

+ +

+ + + diff --git a/help/html/050902.htm b/help/html/050902.htm new file mode 100644 index 0000000..f588cc6 --- /dev/null +++ b/help/html/050902.htm @@ -0,0 +1,33 @@ + + + + + + + + + + +

+ +

. 1. - . + - , .

+ +
. 1. .
+ + +

, .

+
    +
  • , .
  • +
  • , , .
  • +
  • ( ).
  • +
  • , .
  • +
+ +

( / ) + ( ).

+

- , . + / - .

+ + + diff --git a/help/html/050903.htm b/help/html/050903.htm new file mode 100644 index 0000000..c73497b --- /dev/null +++ b/help/html/050903.htm @@ -0,0 +1,44 @@ + + + + + + + + + + +

+ +

+ .

+ +

- + ( ). . 1.

+ +
. 1. .
+ + +

(. 1) + , :

+
    +
  • , _.ID ;
  • +
  • (ID1, , IDn);
  • +
  • {ID1, IDn}.
  • +
+ +

, (. 2).

+ +
. 2. .
+ + +

+ / (. 3).

+

, . . + NUM+ NUM- .

+

, : , .

+ +
. 3. .
+ + + diff --git a/help/html/050904.htm b/help/html/050904.htm new file mode 100644 index 0000000..d28b8c6 --- /dev/null +++ b/help/html/050904.htm @@ -0,0 +1,47 @@ + + + + + + + + + + +

+ +

+ ,

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID
00FF00M1 ,
FFFF00M2 ,
FF0000M3
+ + + diff --git a/help/html/050905.htm b/help/html/050905.htm new file mode 100644 index 0000000..3e608b1 --- /dev/null +++ b/help/html/050905.htm @@ -0,0 +1,43 @@ + + + + + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID
V8A00
V8A01
V8A02
V8A03
V8A04
+ + diff --git a/help/html/blank.htm b/help/html/blank.htm new file mode 100644 index 0000000..4044808 --- /dev/null +++ b/help/html/blank.htm @@ -0,0 +1,16 @@ + + + + + + + + + + +

+ +

, - !

+

+ + diff --git a/help/html/css/style.css b/help/html/css/style.css new file mode 100644 index 0000000..3399245 --- /dev/null +++ b/help/html/css/style.css @@ -0,0 +1,54 @@ +table { + width:auto; + border-collapse:collapse; + margin-bottom:10px; +} + +thead { + text-align:center; + font-weight:bold; +} + +tbody { + margin: 5px; +} + +table caption { + text-align:left; + font-weight:bold; + text-indent:10px; + font-size:14px; + margin-bottom:5px; +} + +ol{ + margin-top:0px; + padding-left: 30px; +} + +ul { + margin-top:0px; + padding-left: 30px; +} +.contents { + list-style-type: none; +} + +td { + border:solid 1px black; + padding: 4px 5px 4px 5px +} +.cellCenter { + text-align: center; +} + +p { + text-align:justify; /* Выравниваение по ширине*/ + margin: 5px 5px 5px 0px; /* Поля*/ +} +.picCaption { + text-align:left; + font-weight:bold; + font-size:14px; + margin-bottom:2px; +} diff --git a/help/html/pic/diagramma.png b/help/html/pic/diagramma.png new file mode 100644 index 0000000..d5009b0 Binary files /dev/null and b/help/html/pic/diagramma.png differ diff --git a/help/html/pic/from_description/001.png b/help/html/pic/from_description/001.png new file mode 100644 index 0000000..97d385f Binary files /dev/null and b/help/html/pic/from_description/001.png differ diff --git a/help/html/pic/from_description/002.png b/help/html/pic/from_description/002.png new file mode 100644 index 0000000..edb9a3e Binary files /dev/null and b/help/html/pic/from_description/002.png differ diff --git a/help/html/pic/from_description/003.png b/help/html/pic/from_description/003.png new file mode 100644 index 0000000..5ce90ca Binary files /dev/null and b/help/html/pic/from_description/003.png differ diff --git a/help/html/pic/from_description/004.png b/help/html/pic/from_description/004.png new file mode 100644 index 0000000..a8684ff Binary files /dev/null and b/help/html/pic/from_description/004.png differ diff --git a/help/html/pic/from_description/011.png b/help/html/pic/from_description/011.png new file mode 100644 index 0000000..2c49cf0 Binary files /dev/null and b/help/html/pic/from_description/011.png differ diff --git a/help/html/pic/from_description/012.png b/help/html/pic/from_description/012.png new file mode 100644 index 0000000..ac03e27 Binary files /dev/null and b/help/html/pic/from_description/012.png differ diff --git a/help/html/pic/from_description/101.png b/help/html/pic/from_description/101.png new file mode 100644 index 0000000..53e6903 Binary files /dev/null and b/help/html/pic/from_description/101.png differ diff --git a/help/html/pic/from_description/102.png b/help/html/pic/from_description/102.png new file mode 100644 index 0000000..15bb858 Binary files /dev/null and b/help/html/pic/from_description/102.png differ diff --git a/help/html/pic/from_description/103.png b/help/html/pic/from_description/103.png new file mode 100644 index 0000000..9abef71 Binary files /dev/null and b/help/html/pic/from_description/103.png differ diff --git a/help/html/pic/from_description/104.png b/help/html/pic/from_description/104.png new file mode 100644 index 0000000..2cf2fcf Binary files /dev/null and b/help/html/pic/from_description/104.png differ diff --git a/help/html/pic/from_description/105.png b/help/html/pic/from_description/105.png new file mode 100644 index 0000000..8c21611 Binary files /dev/null and b/help/html/pic/from_description/105.png differ diff --git a/help/html/pic/from_description/106.png b/help/html/pic/from_description/106.png new file mode 100644 index 0000000..286faff Binary files /dev/null and b/help/html/pic/from_description/106.png differ diff --git a/help/html/pic/from_description/107.png b/help/html/pic/from_description/107.png new file mode 100644 index 0000000..b7f300e Binary files /dev/null and b/help/html/pic/from_description/107.png differ diff --git a/help/html/pic/from_description/108.png b/help/html/pic/from_description/108.png new file mode 100644 index 0000000..ee1a628 Binary files /dev/null and b/help/html/pic/from_description/108.png differ diff --git a/help/html/pic/from_description/110.png b/help/html/pic/from_description/110.png new file mode 100644 index 0000000..9e5f8b6 Binary files /dev/null and b/help/html/pic/from_description/110.png differ diff --git a/help/html/pic/from_description/111.png b/help/html/pic/from_description/111.png new file mode 100644 index 0000000..52bc63f Binary files /dev/null and b/help/html/pic/from_description/111.png differ diff --git a/help/html/pic/from_description/112.png b/help/html/pic/from_description/112.png new file mode 100644 index 0000000..d462bc9 Binary files /dev/null and b/help/html/pic/from_description/112.png differ diff --git a/help/html/pic/from_description/113.png b/help/html/pic/from_description/113.png new file mode 100644 index 0000000..5a0da56 Binary files /dev/null and b/help/html/pic/from_description/113.png differ diff --git a/help/html/pic/from_description/114.png b/help/html/pic/from_description/114.png new file mode 100644 index 0000000..e4a0135 Binary files /dev/null and b/help/html/pic/from_description/114.png differ diff --git a/help/html/pic/from_description/201.png b/help/html/pic/from_description/201.png new file mode 100644 index 0000000..95c7aed Binary files /dev/null and b/help/html/pic/from_description/201.png differ diff --git a/help/html/pic/from_description/202.png b/help/html/pic/from_description/202.png new file mode 100644 index 0000000..ed3cc83 Binary files /dev/null and b/help/html/pic/from_description/202.png differ diff --git a/help/html/pic/from_description/203.png b/help/html/pic/from_description/203.png new file mode 100644 index 0000000..8967690 Binary files /dev/null and b/help/html/pic/from_description/203.png differ diff --git a/help/html/pic/from_description/204.png b/help/html/pic/from_description/204.png new file mode 100644 index 0000000..f672bc5 Binary files /dev/null and b/help/html/pic/from_description/204.png differ diff --git a/help/html/pic/from_description/301.png b/help/html/pic/from_description/301.png new file mode 100644 index 0000000..a5c5b9f Binary files /dev/null and b/help/html/pic/from_description/301.png differ diff --git a/help/html/pic/from_description/302.png b/help/html/pic/from_description/302.png new file mode 100644 index 0000000..57025dc Binary files /dev/null and b/help/html/pic/from_description/302.png differ diff --git a/help/html/pic/from_description/303.png b/help/html/pic/from_description/303.png new file mode 100644 index 0000000..fc13450 Binary files /dev/null and b/help/html/pic/from_description/303.png differ diff --git a/help/html/pic/from_description/305.png b/help/html/pic/from_description/305.png new file mode 100644 index 0000000..e4058d4 Binary files /dev/null and b/help/html/pic/from_description/305.png differ diff --git a/help/html/pic/from_description/307.png b/help/html/pic/from_description/307.png new file mode 100644 index 0000000..884e017 Binary files /dev/null and b/help/html/pic/from_description/307.png differ diff --git a/help/html/pic/helpView.png b/help/html/pic/helpView.png new file mode 100644 index 0000000..0d9e34c Binary files /dev/null and b/help/html/pic/helpView.png differ diff --git a/help/html/pic/icons/oss.png b/help/html/pic/icons/oss.png new file mode 100644 index 0000000..e9ad60b Binary files /dev/null and b/help/html/pic/icons/oss.png differ diff --git a/help/html/pic/icons/rsm.png b/help/html/pic/icons/rsm.png new file mode 100644 index 0000000..fe9fcbf Binary files /dev/null and b/help/html/pic/icons/rsm.png differ diff --git a/help/html/pic/icons/trs.png b/help/html/pic/icons/trs.png new file mode 100644 index 0000000..dfe5750 Binary files /dev/null and b/help/html/pic/icons/trs.png differ diff --git a/help/html/pic/panels/1.standart/bug.png b/help/html/pic/panels/1.standart/bug.png new file mode 100644 index 0000000..eaf8c9a Binary files /dev/null and b/help/html/pic/panels/1.standart/bug.png differ diff --git a/help/html/pic/panels/1.standart/copy.png b/help/html/pic/panels/1.standart/copy.png new file mode 100644 index 0000000..591ffef Binary files /dev/null and b/help/html/pic/panels/1.standart/copy.png differ diff --git a/help/html/pic/panels/1.standart/create.png b/help/html/pic/panels/1.standart/create.png new file mode 100644 index 0000000..903bc24 Binary files /dev/null and b/help/html/pic/panels/1.standart/create.png differ diff --git a/help/html/pic/panels/1.standart/cut.png b/help/html/pic/panels/1.standart/cut.png new file mode 100644 index 0000000..c4e0aaf Binary files /dev/null and b/help/html/pic/panels/1.standart/cut.png differ diff --git a/help/html/pic/panels/1.standart/hor.png b/help/html/pic/panels/1.standart/hor.png new file mode 100644 index 0000000..52940b5 Binary files /dev/null and b/help/html/pic/panels/1.standart/hor.png differ diff --git a/help/html/pic/panels/1.standart/open.png b/help/html/pic/panels/1.standart/open.png new file mode 100644 index 0000000..02cac05 Binary files /dev/null and b/help/html/pic/panels/1.standart/open.png differ diff --git a/help/html/pic/panels/1.standart/panel.png b/help/html/pic/panels/1.standart/panel.png new file mode 100644 index 0000000..5e48579 Binary files /dev/null and b/help/html/pic/panels/1.standart/panel.png differ diff --git a/help/html/pic/panels/1.standart/paste.png b/help/html/pic/panels/1.standart/paste.png new file mode 100644 index 0000000..33f941c Binary files /dev/null and b/help/html/pic/panels/1.standart/paste.png differ diff --git a/help/html/pic/panels/1.standart/save.png b/help/html/pic/panels/1.standart/save.png new file mode 100644 index 0000000..0aa2f3b Binary files /dev/null and b/help/html/pic/panels/1.standart/save.png differ diff --git a/help/html/pic/panels/1.standart/vert.png b/help/html/pic/panels/1.standart/vert.png new file mode 100644 index 0000000..dfcacb6 Binary files /dev/null and b/help/html/pic/panels/1.standart/vert.png differ diff --git a/help/html/pic/panels/2.constit/A.png b/help/html/pic/panels/2.constit/A.png new file mode 100644 index 0000000..e2e45cb Binary files /dev/null and b/help/html/pic/panels/2.constit/A.png differ diff --git a/help/html/pic/panels/2.constit/C.png b/help/html/pic/panels/2.constit/C.png new file mode 100644 index 0000000..f29fea4 Binary files /dev/null and b/help/html/pic/panels/2.constit/C.png differ diff --git a/help/html/pic/panels/2.constit/D.png b/help/html/pic/panels/2.constit/D.png new file mode 100644 index 0000000..363ad0f Binary files /dev/null and b/help/html/pic/panels/2.constit/D.png differ diff --git a/help/html/pic/panels/2.constit/F.png b/help/html/pic/panels/2.constit/F.png new file mode 100644 index 0000000..8f727e2 Binary files /dev/null and b/help/html/pic/panels/2.constit/F.png differ diff --git a/help/html/pic/panels/2.constit/H.png b/help/html/pic/panels/2.constit/H.png new file mode 100644 index 0000000..632ab32 Binary files /dev/null and b/help/html/pic/panels/2.constit/H.png differ diff --git a/help/html/pic/panels/2.constit/S.png b/help/html/pic/panels/2.constit/S.png new file mode 100644 index 0000000..c56087a Binary files /dev/null and b/help/html/pic/panels/2.constit/S.png differ diff --git a/help/html/pic/panels/2.constit/Th.png b/help/html/pic/panels/2.constit/Th.png new file mode 100644 index 0000000..2ee03c1 Binary files /dev/null and b/help/html/pic/panels/2.constit/Th.png differ diff --git a/help/html/pic/panels/2.constit/X.png b/help/html/pic/panels/2.constit/X.png new file mode 100644 index 0000000..48b3f05 Binary files /dev/null and b/help/html/pic/panels/2.constit/X.png differ diff --git a/help/html/pic/panels/2.constit/blank.png b/help/html/pic/panels/2.constit/blank.png new file mode 100644 index 0000000..dd517d3 Binary files /dev/null and b/help/html/pic/panels/2.constit/blank.png differ diff --git a/help/html/pic/panels/2.constit/del.png b/help/html/pic/panels/2.constit/del.png new file mode 100644 index 0000000..3919046 Binary files /dev/null and b/help/html/pic/panels/2.constit/del.png differ diff --git a/help/html/pic/panels/2.constit/panel.png b/help/html/pic/panels/2.constit/panel.png new file mode 100644 index 0000000..af1f28e Binary files /dev/null and b/help/html/pic/panels/2.constit/panel.png differ diff --git a/help/html/pic/panels/3.synthesis/add_pictogramm.png b/help/html/pic/panels/3.synthesis/add_pictogramm.png new file mode 100644 index 0000000..d9c46bd Binary files /dev/null and b/help/html/pic/panels/3.synthesis/add_pictogramm.png differ diff --git a/help/html/pic/panels/3.synthesis/del_pictogramm.png b/help/html/pic/panels/3.synthesis/del_pictogramm.png new file mode 100644 index 0000000..f840711 Binary files /dev/null and b/help/html/pic/panels/3.synthesis/del_pictogramm.png differ diff --git a/help/html/pic/panels/3.synthesis/left.png b/help/html/pic/panels/3.synthesis/left.png new file mode 100644 index 0000000..b874c41 Binary files /dev/null and b/help/html/pic/panels/3.synthesis/left.png differ diff --git a/help/html/pic/panels/3.synthesis/log.png b/help/html/pic/panels/3.synthesis/log.png new file mode 100644 index 0000000..a650979 Binary files /dev/null and b/help/html/pic/panels/3.synthesis/log.png differ diff --git a/help/html/pic/panels/3.synthesis/minus.png b/help/html/pic/panels/3.synthesis/minus.png new file mode 100644 index 0000000..47b8e83 Binary files /dev/null and b/help/html/pic/panels/3.synthesis/minus.png differ diff --git a/help/html/pic/panels/3.synthesis/nam.png b/help/html/pic/panels/3.synthesis/nam.png new file mode 100644 index 0000000..06500ee Binary files /dev/null and b/help/html/pic/panels/3.synthesis/nam.png differ diff --git a/help/html/pic/panels/3.synthesis/panel.png b/help/html/pic/panels/3.synthesis/panel.png new file mode 100644 index 0000000..79d5cc2 Binary files /dev/null and b/help/html/pic/panels/3.synthesis/panel.png differ diff --git a/help/html/pic/panels/3.synthesis/plus.png b/help/html/pic/panels/3.synthesis/plus.png new file mode 100644 index 0000000..cec3b6c Binary files /dev/null and b/help/html/pic/panels/3.synthesis/plus.png differ diff --git a/help/html/pic/panels/3.synthesis/q.png b/help/html/pic/panels/3.synthesis/q.png new file mode 100644 index 0000000..e835a33 Binary files /dev/null and b/help/html/pic/panels/3.synthesis/q.png differ diff --git a/help/html/pic/panels/3.synthesis/red.png b/help/html/pic/panels/3.synthesis/red.png new file mode 100644 index 0000000..20029c4 Binary files /dev/null and b/help/html/pic/panels/3.synthesis/red.png differ diff --git a/help/html/pic/panels/3.synthesis/redact.png b/help/html/pic/panels/3.synthesis/redact.png new file mode 100644 index 0000000..13a5d15 Binary files /dev/null and b/help/html/pic/panels/3.synthesis/redact.png differ diff --git a/help/html/pic/panels/3.synthesis/resh.png b/help/html/pic/panels/3.synthesis/resh.png new file mode 100644 index 0000000..5576d87 Binary files /dev/null and b/help/html/pic/panels/3.synthesis/resh.png differ diff --git a/help/html/pic/panels/3.synthesis/right.png b/help/html/pic/panels/3.synthesis/right.png new file mode 100644 index 0000000..b5af353 Binary files /dev/null and b/help/html/pic/panels/3.synthesis/right.png differ diff --git a/help/html/pic/panels/3.synthesis/sop.png b/help/html/pic/panels/3.synthesis/sop.png new file mode 100644 index 0000000..8f6f537 Binary files /dev/null and b/help/html/pic/panels/3.synthesis/sop.png differ diff --git a/help/html/pic/panels/3.synthesis/synth.png b/help/html/pic/panels/3.synthesis/synth.png new file mode 100644 index 0000000..c2e7e38 Binary files /dev/null and b/help/html/pic/panels/3.synthesis/synth.png differ diff --git a/help/html/pic/panels/3.synthesis/vip.png b/help/html/pic/panels/3.synthesis/vip.png new file mode 100644 index 0000000..74e2c7e Binary files /dev/null and b/help/html/pic/panels/3.synthesis/vip.png differ diff --git a/help/html/pic/panels/panels.png b/help/html/pic/panels/panels.png new file mode 100644 index 0000000..d5bd3cc Binary files /dev/null and b/help/html/pic/panels/panels.png differ diff --git a/help/html/pic/pictogramm_stat/1.png b/help/html/pic/pictogramm_stat/1.png new file mode 100644 index 0000000..4ac597b Binary files /dev/null and b/help/html/pic/pictogramm_stat/1.png differ diff --git a/help/html/pic/pictogramm_stat/2.png b/help/html/pic/pictogramm_stat/2.png new file mode 100644 index 0000000..b414a47 Binary files /dev/null and b/help/html/pic/pictogramm_stat/2.png differ diff --git a/help/html/pic/pictogramm_stat/3.png b/help/html/pic/pictogramm_stat/3.png new file mode 100644 index 0000000..7570d85 Binary files /dev/null and b/help/html/pic/pictogramm_stat/3.png differ diff --git a/help/html/pic/pictogramm_stat/4.png b/help/html/pic/pictogramm_stat/4.png new file mode 100644 index 0000000..86907b1 Binary files /dev/null and b/help/html/pic/pictogramm_stat/4.png differ diff --git a/help/html/pic/pictogramm_stat/5.png b/help/html/pic/pictogramm_stat/5.png new file mode 100644 index 0000000..c557ecc Binary files /dev/null and b/help/html/pic/pictogramm_stat/5.png differ diff --git a/help/html/pic/pictogramm_stat/6.png b/help/html/pic/pictogramm_stat/6.png new file mode 100644 index 0000000..b9688ab Binary files /dev/null and b/help/html/pic/pictogramm_stat/6.png differ diff --git a/help/stoplist.stp b/help/stoplist.stp new file mode 100644 index 0000000..3136d3c --- /dev/null +++ b/help/stoplist.stp @@ -0,0 +1,4 @@ + + + + diff --git a/help/template.htm b/help/template.htm new file mode 100644 index 0000000..89c9a38 --- /dev/null +++ b/help/template.htm @@ -0,0 +1,137 @@ + + + + + + + + Index + + +

+ +

+

+ +

+ +

+
+ +
+ +
+ +
+ + +
+ + +
+ +
+ +
+ +
+

+ + + + + + + + + + + + + + + + + + + +
1 2 3
1 2 3
+ +
+ + + diff --git a/import/cctext/__init__.py b/import/cctext/__init__.py new file mode 100644 index 0000000..35bcebe --- /dev/null +++ b/import/cctext/__init__.py @@ -0,0 +1,16 @@ +''' Concept core text processing library. ''' +# pylint: skip-file +from .syntax import RuSyntax, Capitalization +from .rumodel import Morphology, SemanticRole, WordTag, morpho, split_grams, combine_grams +from .ruparser import PhraseParser, WordToken, Collation +from .reference import EntityReference, ReferenceType, SyntacticReference, parse_reference +from .context import TermForm, Entity, TermContext +from .resolver import Reference, Position, Resolver, ResolvedReference, resolve_entity, resolve_syntactic, extract_entities + +from .conceptapi import ( + parse, normalize, + generate_lexeme, inflect, inflect_context, inflect_substitute, inflect_dependant, + match_all_morpho, find_substr +) + +# TODO: implement Part of speech transition for VERB <-> NOUN diff --git a/import/cctext/conceptapi.py b/import/cctext/conceptapi.py new file mode 100644 index 0000000..f6f8e2d --- /dev/null +++ b/import/cctext/conceptapi.py @@ -0,0 +1,90 @@ +''' +Concept API Python functions. + +::guarantee:: doesn't raise exceptions and returns workable outputs +''' +from cctext.rumodel import Morphology +from .syntax import RuSyntax +from .ruparser import PhraseParser +from .rumodel import split_grams + +parser = PhraseParser() + + +def parse(text: str, require_grams: str = '') -> str: + ''' Determine morpho tags for input text. + ::returns:: string of comma separated grammar tags or empty string ''' + model = parser.parse(text, require_grams=split_grams(require_grams)) + if model is None: + return '' + result = model.get_morpho().to_text() + return result if result != 'UNKN' else '' + + +# def parse_variants(text: str, require_grams: str = '') -> list[tuple[str, str]]: +# ''' Get all variants of a parse. +# ::returns:: string of comma separated grammar tags or empty string ''' + + +def generate_lexeme(text_normal: str) -> list[tuple[str, str]]: + ''' Get all inflected forms belonging to same Lexeme. ''' + model = parser.parse(text_normal) + if not model: + return [] + result = [] + for form in model.get_form().lexeme: + result.append((model.inflect(form.tag.grammemes), Morphology(form.tag).to_text())) + return result + + +def normalize(text: str) -> str: + ''' Generate normal form. + ::returns:: normal form of input text or text itself if no parse is available ''' + model = parser.parse(text) + if model is None: + return text + return model.normal_form() + + +def inflect(text: str, target_grams: str) -> str: + ''' Inflect text to match required tags. + ::returns:: infected text or initial text if infection failed ''' + target_set = split_grams(target_grams) + model = parser.parse(text) + if model is None: + return text + return model.inflect(target_set) + + +def inflect_context(target: str, before: str = '', after: str = '') -> str: + ''' Inflect text in accordance to context before and after. ''' + return parser.inflect_context(target, before, after) + + +def inflect_substitute(substitute_normal: str, original: str) -> str: + ''' Inflect substitute to match original form. ''' + return parser.inflect_substitute(substitute_normal, original) + + +def inflect_dependant(dependant_normal: str, master: str) -> str: + ''' Inflect dependant to coordinate with master text. ''' + return parser.inflect_dependant(dependant_normal, master) + + +def match_all_morpho(text: str, filter_grams: str) -> list[list[int]]: + ''' Search for all words corresponding to tags. ''' + target_set = split_grams(filter_grams) + if len(target_set) == 0: + return [] + + result = [] + for elem in RuSyntax.tokenize(text): + model = parser.parse(elem.text, require_grams=target_set) + if model: + result.append([elem.start, elem.stop]) + return result + + +def find_substr(text: str, sub: str) -> tuple[int, int]: + ''' Search for substring position in text regardless of morphology. ''' + return parser.find_substr(text, sub) diff --git a/import/cctext/context.py b/import/cctext/context.py new file mode 100644 index 0000000..de487cd --- /dev/null +++ b/import/cctext/context.py @@ -0,0 +1,84 @@ +''' Term context for reference resolution. ''' +from typing import Iterable, Optional, TypedDict + +from .ruparser import PhraseParser +from .rumodel import WordTag + + +parser = PhraseParser() + + +class TermForm(TypedDict): + ''' Represents term in a specific form. ''' + text: str + grams: Iterable[str] + + +def _match_grams(query: Iterable[str], test: Iterable[str]) -> bool: + ''' Check if grams from test fit query. ''' + for gram in test: + if not gram in query: + if not gram in WordTag.PARTS_OF_SPEECH: + return False + for pos in WordTag.PARTS_OF_SPEECH: + if pos in query: + return False + return True + + +def _search_form(query: Iterable[str], data: Iterable[TermForm]) -> Optional[str]: + for form in data: + if _match_grams(query, form['grams']): + return form['text'] + return None + + +class Entity: + ''' Represents text entity. ''' + def __init__(self, alias: str, nominal: str, manual_forms: Optional[Iterable[TermForm]]=None): + if manual_forms is None: + self.manual = [] + else: + self.manual = list(manual_forms) + self.alias = alias + self._nominal = nominal + self._cached: list[TermForm] = [] + + def get_nominal(self) -> str: + ''' Getter for _nominal. ''' + return self._nominal + + def set_nominal(self, new_text: str): + ''' Setter for _nominal. + Note: clears manual and cached forms. ''' + if self._nominal == new_text: + return + self._nominal = new_text + self.manual = [] + self._cached = [] + + def get_form(self, grams: Iterable[str]) -> str: + ''' Get specific term form. ''' + if all(False for _ in grams): + return self._nominal + text = _search_form(grams, self.manual) + if text is not None: + return text + text = _search_form(grams, self._cached) + if text is not None: + return text + + model = parser.parse(self._nominal) + if model is None: + text = self._nominal + else: + try: + text = model.inflect(grams) + except ValueError as error: + text = f'!{error}!'.replace('Unknown grammeme', 'Неизвестная граммема') + self._cached.append({'text': text, 'grams': grams}) + return text + + +# Represents term context for resolving entity references. +TermContext = dict[str, Entity] diff --git a/import/cctext/reference.py b/import/cctext/reference.py new file mode 100644 index 0000000..c2733bb --- /dev/null +++ b/import/cctext/reference.py @@ -0,0 +1,60 @@ +''' Text reference API. ''' +from enum import Enum, unique +from typing import Optional, Union + + +@unique +class ReferenceType(Enum): + ''' Text reference types. ''' + entity = 'entity' + syntactic = 'syntax' + + +class EntityReference: + ''' Reference to entity. ''' + + def __init__(self, identifier: str, form: str): + self.entity = identifier + self.form = form + + def get_type(self) -> ReferenceType: + return ReferenceType.entity + + def to_text(self) -> str: + return f'@{{{self.entity}|{self.form}}}' + + +class SyntacticReference: + ''' Reference to syntactic dependency on EntityReference. ''' + + def __init__(self, referral_offset: int, text: str): + self.nominal = text + self.offset = referral_offset + + def get_type(self) -> ReferenceType: + return ReferenceType.syntactic + + def to_text(self) -> str: + return f'@{{{self.offset}|{self.nominal}}}' + + +Reference = Union[EntityReference, SyntacticReference] + + +def parse_reference(text: str) -> Optional[Reference]: + if len(text) < 4 or text[-1] != '}' or text[0:2] != '@{': + return None + blocks: list[str] = [block.strip() for block in text[2:-1].split('|')] + if len(blocks) != 2 or blocks[0] == '' or blocks[0][0] in '0': + return None + if blocks[0][0] in '-123456789': + if blocks[1] == '': + return None + try: + offset = int(blocks[0]) + return SyntacticReference(offset, blocks[1]) + except ValueError: + return None + else: + form = blocks[1].replace(' ', '') + return EntityReference(blocks[0], form) diff --git a/import/cctext/resolver.py b/import/cctext/resolver.py new file mode 100644 index 0000000..e9df3df --- /dev/null +++ b/import/cctext/resolver.py @@ -0,0 +1,140 @@ +''' Reference resolution API. ''' +import re +from typing import cast, Optional +from dataclasses import dataclass + +from .rumodel import split_grams + +from .conceptapi import inflect_dependant +from .context import TermContext +from .reference import EntityReference, SyntacticReference, parse_reference, Reference + + +_REF_ENTITY_PATTERN = re.compile(r'@{([^0-9\-][^\}\|\{]*?)\|([^\}\|\{]*?)}') + + +def extract_entities(text: str) -> list[str]: + ''' Extract list of entities that are referenced. ''' + result: list[str] = [] + for segment in re.finditer(_REF_ENTITY_PATTERN, text): + entity = segment.group(1) + if entity not in result: + result.append(entity) + return result + + +def resolve_entity(ref: EntityReference, context: TermContext) -> str: + ''' Resolve entity reference. ''' + alias = ref.entity + if alias not in context: + return f'!Неизвестная сущность: {alias}!' + grams = split_grams(ref.form) + resolved = context[alias].get_form(grams) + if resolved == '': + return f'!Отсутствует термин: {alias}!' + else: + return resolved + + +def resolve_syntactic(ref: SyntacticReference, index: int, references: list['ResolvedReference']) -> str: + ''' Resolve syntactic reference. ''' + offset = ref.offset + master: Optional['ResolvedReference'] = None + if offset > 0: + index += 1 + while index < len(references): + if isinstance(references[index].ref, EntityReference): + if offset == 1: + master = references[index] + else: + offset -= 1 + index += 1 + else: + index -= 1 + while index >= 0: + if isinstance(references[index].ref, EntityReference): + if offset == -1: + master = references[index] + else: + offset += 1 + index -= 1 + if master is None: + return f'!Некорректное смещение: {ref.offset}!' + return inflect_dependant(ref.nominal, master.resolved) + + +@dataclass +class Position: + ''' 0-indexed contiguous segment position in text. ''' + start: int = 0 + finish: int = 0 + + def __hash__(self) -> int: + return hash((self.start, self.finish)) + + +@dataclass +class ResolvedReference: + ''' Resolved reference data ''' + ref: Reference + resolved: str = '' + pos_input: Position = Position() + pos_output: Position = Position() + + def __hash__(self) -> int: + return hash((self.resolved, self.pos_input, self.pos_output, self.ref.to_text())) + + +class Resolver: + ''' Text reference resolver ''' + REFERENCE_PATTERN = re.compile(r'@{[^\}\{]*?}') + + def __init__(self, context: TermContext): + self.context = context + self.refs = cast(list[ResolvedReference], []) + self.input = '' + self.output = '' + + def resolve(self, text: str) -> str: + ''' Resolve references in input text. + Note: data on references positions is accessed through class attributes ''' + self._reset(text) + self._parse_refs() + if len(self.refs) == 0: + self.output = self.input + return self.output + else: + self._resolve_refs() + self._combine_output() + return self.output + + def _reset(self, input_text: str): + self.refs = cast(list[ResolvedReference], []) + self.input = input_text + self.output = '' + + def _parse_refs(self): + for segment in re.finditer(Resolver.REFERENCE_PATTERN, self.input): + parse = parse_reference(segment[0]) + if parse is not None: + ref_info = ResolvedReference(ref=parse, + resolved='', + pos_input=Position(segment.start(0), segment.end(0))) + self.refs.append(ref_info) + + def _resolve_refs(self): + for ref in self.refs: + if isinstance(ref.ref, EntityReference): + ref.resolved = resolve_entity(ref.ref, self.context) + for (index, ref) in enumerate(self.refs): + if isinstance(ref.ref, SyntacticReference): + ref.resolved = resolve_syntactic(ref.ref, index, self.refs) + + def _combine_output(self): + pos_in = 0 + for ref in self.refs: + self.output += self.input[pos_in : ref.pos_input.start] + self.output += ref.resolved + ref.pos_output = Position(len(self.output) - len(ref.resolved), len(self.output)) + pos_in = ref.pos_input.finish + self.output += self.input[pos_in : len(self.input)] diff --git a/import/cctext/rumodel.py b/import/cctext/rumodel.py new file mode 100644 index 0000000..8f5b4cc --- /dev/null +++ b/import/cctext/rumodel.py @@ -0,0 +1,118 @@ +''' Russian language models. ''' +from __future__ import annotations +from enum import Enum, unique +from typing import Iterable, Optional + +from pymorphy3 import MorphAnalyzer +from pymorphy3.tagset import OpencorporaTag as WordTag + +# ''' Morphology parser. ''' +morpho = MorphAnalyzer() +Grammemes = Iterable[str] + + +def split_grams(text: str) -> list[str]: + ''' Split grammemes string into set of items. ''' + return [tag.strip() for tag in filter(None, text.split(','))] + + +def combine_grams(tags: Iterable[str]) -> str: + ''' Combine grammemes into string. ''' + return ','.join(tags) + + +@unique +class SemanticRole(Enum): + ''' Enumerating semantic types for different parse patterns. ''' + unknwn = 0 + term = 1 + action = 2 + definition = 3 + + @staticmethod + def from_POS(pos: Optional[str]) -> SemanticRole: + ''' Production method: types from part of speech. ''' + if pos in ['NOUN', 'NPRO']: + return SemanticRole.term + elif pos in ['VERB', 'INFN', 'PRTF', 'PRTS']: + return SemanticRole.action + elif pos in ['ADJF', 'ADJS']: + return SemanticRole.definition + return SemanticRole.unknwn + + +class Morphology: + ''' Wrapper for OpencorporaTag expanding functionality for multiword. + Full morphology tags see http://opencorpora.org/dict.php?act=gram + ''' + def __init__(self, tag: WordTag, semantic=SemanticRole.unknwn): + self.tag = tag + self.semantic = semantic if semantic != SemanticRole.unknwn else SemanticRole.from_POS(tag.POS) + + _TAGS_IMMUTABLE = frozenset(['INFN', 'ADVB', 'COMP', 'PNCT', 'PREP', 'CONJ', 'PRCL', 'INTJ']) + + _TAGS_NO_TENSE = frozenset(['NOUN', 'NPRO', 'ADJF', 'ADJS']) + _TAGS_NO_CASE = frozenset(['GRND', 'VERB', 'ADJS', 'PRTS']) + _TAGS_NO_NUMBER = frozenset(['GRND']) + _TAGS_NO_GENDER = frozenset(['GRND', 'NOUN', 'NPRO', 'plur']) + _TAGS_NO_PERSON = frozenset(['GRND', 'NOUN', 'ADJF', 'ADJS', 'PRTF', 'PRTS', 'past']) + + @property + def can_coordinate(self) -> bool: + ''' Check if coordination can change text. ''' + return self.tag.POS in ['NOUN', 'NPRO', 'NUMR', 'ADJF', 'ADJS', 'PRTF', 'PRTS'] + + @staticmethod + def is_dependable(pos: str): + ''' Check if this morphology can be dependant. ''' + return pos in ['ADJF', 'ADJS', 'PRTF', 'PRTS'] + + @property + def effective_POS(self) -> Optional[str]: + ''' Access part of speech. Pronouns are considered as nouns ''' + pos: Optional[str] = self.tag.POS + if pos and self.tag.POS == 'NPRO': + return 'NOUN' + return pos + + def complete_grams(self, grams: Iterable[str]) -> set[str]: + ''' Add missing tags before inflection. ''' + result = set(grams) + pos = self.tag.POS + if pos and result.isdisjoint(WordTag.PARTS_OF_SPEECH): + result.add(pos if pos != 'INFN' or len(result) == 0 else 'VERB') + if not result.isdisjoint(self._TAGS_IMMUTABLE): + return result + if self.tag.case and result.isdisjoint(WordTag.CASES) and result.isdisjoint(self._TAGS_NO_CASE): + result.add(self.tag.case) + if self.tag.tense and result.isdisjoint(WordTag.TENSES) and result.isdisjoint(self._TAGS_NO_TENSE): + if (self.tag.tense != 'past' or result.isdisjoint(WordTag.PERSONS)) \ + and (self.tag.tense != 'pres' or result.isdisjoint(WordTag.GENDERS)): + result.add(self.tag.tense) + if self.tag.number and result.isdisjoint(WordTag.NUMBERS) and result.isdisjoint(self._TAGS_NO_NUMBER): + if self.tag.number != 'plur' or result.isdisjoint(WordTag.GENDERS): + result.add(self.tag.number) + if self.tag.gender and result.isdisjoint(WordTag.GENDERS) and result.isdisjoint(self._TAGS_NO_GENDER): + if 'PRTF' in result or 'pres' not in result: + result.add(self.tag.gender) + if self.tag.person and result.isdisjoint(WordTag.PERSONS) and result.isdisjoint(self._TAGS_NO_PERSON): + result.add(self.tag.person) + if 'plur' in result and not result.isdisjoint(WordTag.GENDERS): + result = result.difference(WordTag.GENDERS) + return result + + def coordination_grams(self) -> set[str]: + ''' Return set of grammemes for inflection to keep coordination . ''' + result = set() + if self.tag.case: + result.add(self.tag.case) + if self.tag: + number = self.tag.number + result.add(number) + if self.tag.gender and 'plur' not in result: + result.add(self.tag.gender) + return result + + def to_text(self) -> str: + ''' Produce string of all grammemes. ''' + return combine_grams(self.tag.grammemes) diff --git a/import/cctext/ruparser.py b/import/cctext/ruparser.py new file mode 100644 index 0000000..7b64cd2 --- /dev/null +++ b/import/cctext/ruparser.py @@ -0,0 +1,486 @@ +''' Parsing russian language using pymorphy3 library. ''' +from __future__ import annotations +from typing import Optional + +from razdel.substring import Substring as Segment +from pymorphy3.analyzer import Parse as WordParse + +from .syntax import RuSyntax, Capitalization +from .rumodel import SemanticRole, Morphology, WordTag, morpho, Grammemes + +INDEX_NONE = -1 +NO_COORDINATION = -1 +WORD_NONE = -1 + + +class WordToken: + ''' Atomic text token. ''' + def __init__(self, segment: Segment, parse: list[WordParse], main_parse: int = 0): + self.segment: Segment = segment + self.forms: list[WordParse] = parse + self.main: int = main_parse + + def get_morpho(self) -> Morphology: + ''' Return morphology for current token. ''' + return Morphology(self.get_parse().tag) + + def get_parse(self) -> WordParse: + ''' Access main form. ''' + return self.forms[self.main] + + def inflect(self, inflection_grams: set[str]) -> Optional[WordParse]: + ''' Apply inflection to segment text. Does not modify forms ''' + inflected = self.get_parse().inflect(inflection_grams) + if not inflected: + return None + self.segment.text = Capitalization.from_text(self.segment.text).apply_to(inflected.word) + return inflected + + +class Collation: + ''' Parsed data for input coordinated text. ''' + def __init__(self, text: str): + self.text = text + self.words: list[WordToken] = [] + self.coordination: list[int] = [] + self.main_word: int = WORD_NONE + + def is_valid(self) -> bool: + ''' Check if data is parsed correctly ''' + return self.main_word != WORD_NONE + + def get_form(self) -> WordParse: + ''' Access WordParse. ''' + return self.words[self.main_word].get_parse() + + def get_morpho(self) -> Morphology: + ''' Access parsed main morphology. ''' + return self.words[self.main_word].get_morpho() + + def add_word(self, segment, forms: list, main_form: int, need_coordination: bool = True): + ''' Add word information. ''' + self.words.append(WordToken(segment, forms, main_form)) + self.coordination.append(NO_COORDINATION if not need_coordination else 0) + + def inflect(self, target_grams: Grammemes) -> str: + ''' Inflect text to match required tags. ''' + if self.is_valid(): + origin = self.get_morpho() + if not origin.tag.grammemes.issuperset(target_grams): + if self._apply_inflection(origin, target_grams): + return self._generate_text() + return self.text + + def inflect_like(self, base_model: Collation) -> str: + ''' Create inflection to substitute base_model form. ''' + if self.is_valid(): + morph = base_model.get_morpho() + if morph.effective_POS: + tags = set() + tags.add(morph.effective_POS) + tags = morph.complete_grams(tags) + return self.inflect(tags) + return self.text + + def inflect_dependant(self, master_model: Collation) -> str: + ''' Create inflection to coordinate with master_model form. ''' + assert self.is_valid() + morph = master_model.get_morpho() + tags = morph.coordination_grams() + tags = self.get_morpho().complete_grams(tags) + return self.inflect(tags) + + def normal_form(self) -> str: + ''' Generate normal form. ''' + if self.is_valid(): + main_form = self.get_form() + new_morpho = Morphology(main_form.normalized.tag) + new_grams = new_morpho.complete_grams(frozenset()) + return self.inflect(new_grams) + return self.text + + def _iterate_coordinated(self): + words_count = len(self.words) + current_word = self.coordination[words_count] + while current_word != words_count: + yield self.words[current_word] + current_word += self.coordination[current_word] + + def _inflect_main_word(self, origin: Morphology, target_grams: Grammemes) -> Optional[Morphology]: + full_grams = origin.complete_grams(target_grams) + inflected = self.words[self.main_word].inflect(full_grams) + if not inflected: + return None + return Morphology(inflected.tag) + + def _apply_inflection(self, origin: Morphology, target_grams: Grammemes) -> bool: + new_moprho = self._inflect_main_word(origin, target_grams) + if not new_moprho: + return False + inflection_grams = new_moprho.coordination_grams() + if len(inflection_grams) == 0: + return True + for word in self._iterate_coordinated(): + word.inflect(inflection_grams) + return True + + def _generate_text(self) -> str: + current_pos = 0 + result = '' + for token in self.words: + if token.segment.start > current_pos: + result += self.text[current_pos: token.segment.start] + result += token.segment.text + current_pos = token.segment.stop + if current_pos + 1 < len(self.text): + result += self.text[current_pos:] + return result + + +class PhraseParser: + ''' Russian grammar parser. ''' + def __init__(self): + pass + + def __del__(self): + pass + + _FILTER_SCORE = 0.005 + _SINGLE_SCORE_SEARCH = 0.2 + _PRIORITY_NONE = NO_COORDINATION + + _MAIN_WAIT_LIMIT = 10 # count words until fixing main + _MAIN_MAX_FOLLOWERS = 3 # count words after main as coordination candidates + + def parse(self, text: str, + require_index: int = INDEX_NONE, + require_grams: Optional[Grammemes] = None) -> Optional[Collation]: + ''' + Determine morpho tags for input text. + ::returns:: Morphology of a text or None if no suitable form is available + ''' + segments = list(RuSyntax.tokenize(text)) + if len(segments) == 0: + return None + elif len(segments) == 1: + return self._parse_single(segments[0], require_index, require_grams) + else: + return self._parse_multiword(text, segments, require_index, require_grams) + + def normalize(self, text: str): + ''' Get normal form for target text. ''' + processed = self.parse(text) + if processed: + return processed.normal_form() + return text + + def find_substr(self, text: str, sub: str) -> tuple[int, int]: + ''' Search for substring position in text regardless of morphology. ''' + if not text or not sub: + return (0, 0) + query = [self.normalize(elem.text) for elem in RuSyntax.tokenize(sub)] + query_len = len(query) + start = 0 + current_index = 0 + for token in RuSyntax.tokenize(text): + text_word = self.normalize(token.text) + if text_word != query[current_index]: + current_index = 0 + else: + if current_index == 0: + start = token.start + current_index += 1 + if current_index == query_len: + return (start, token.stop) + return (0, 0) + + def inflect_context(self, text: str, before: str = '', after: str = '') -> str: + ''' Inflect text in accordance to context before and after. ''' + target = self.parse(text) + if not target: + return text + target_morpho = target.get_morpho() + if not target_morpho or not target_morpho.can_coordinate: + return text + + model_after = self.parse(after) + model_before = self.parse(before) + etalon = PhraseParser._choose_context_etalon(target_morpho, model_before, model_after) + if not etalon: + return text + etalon_moprho = etalon.get_morpho() + if not etalon_moprho.can_coordinate: + return text + + new_form = PhraseParser._combine_morpho(target_morpho, etalon_moprho.tag) + return target.inflect(new_form) + + def inflect_substitute(self, substitute_normal: str, original: str) -> str: + ''' Inflect substitute to match original form. ''' + original_model = self.parse(original) + if not original_model: + return substitute_normal + substitute_model = self.parse(substitute_normal) + if not substitute_model: + return substitute_normal + return substitute_model.inflect_like(original_model) + + def inflect_dependant(self, dependant_normal: str, master: str) -> str: + ''' Inflect dependant to coordinate with master text. ''' + master_model = self.parse(master) + if not master_model: + return dependant_normal + dependant_model = self.parse(dependant_normal) + if not dependant_model: + return dependant_normal + return dependant_model.inflect_dependant(master_model) + + def _parse_single(self, segment, require_index: int, require_grams: Optional[Grammemes]) -> Optional[Collation]: + forms = list(self._filtered_parse(segment.text)) + parse_index = INDEX_NONE + if len(forms) == 0 or require_index >= len(forms): + return None + + if require_index != INDEX_NONE: + tags = forms[require_index].tag + if require_grams and not tags.grammemes.issuperset(require_grams): + return None + parse_index = require_index + else: + current_score = 0 + for (index, form) in enumerate(forms): + if not require_grams or form.tag.grammemes.issuperset(require_grams): + if form.tag.case == 'nomn': + parse_index = index + break + elif parse_index == INDEX_NONE: + current_score = form.score + parse_index = index + elif form.score / current_score < self._SINGLE_SCORE_SEARCH: + break + + if parse_index == INDEX_NONE: + return None + result = Collation(segment.text) + result.add_word(segment, [forms[parse_index]], main_form=0, need_coordination=False) + result.coordination.append(len(result.words)) + result.main_word = 0 + return result + + def _parse_multiword(self, text: str, segments: list, require_index: int, + require_grams: Optional[Grammemes]) -> Optional[Collation]: + result = Collation(text) + priority_main: float = self._PRIORITY_NONE + segment_index = 0 + main_wait = 0 + word_index = 0 + for segment in segments: + if main_wait > PhraseParser._MAIN_WAIT_LIMIT: + break + segment_index += 1 + priority = self._parse_segment(result, segment, require_index, require_grams) + if priority is None: + continue # skip non-parsable entities + main_wait += 1 + if priority > priority_main: + result.main_word = word_index + priority_main = priority + word_index += 1 + if result.main_word == INDEX_NONE: + return None + self._finalize_coordination(result) + if segment_index < len(segments): + pass # finish to parse segments after main if needed + return result + + def _parse_segment(self, + output: Collation, + segment: Segment, + require_index: int, + require_grams: Optional[Grammemes]) -> Optional[float]: + ''' Return priority for this can be a new main word ''' + forms = list(self._filtered_parse(segment.text)) + if len(forms) == 0: + return None + main_index: int = INDEX_NONE + segment_score: float = self._PRIORITY_NONE + needs_coordination = False + local_sum: float = 0 + score_sum: float = 0 + if require_index != INDEX_NONE: + form = forms[require_index] + if not require_grams or form.tag.grammemes.issuperset(require_grams): + (local_max, segment_score) = PhraseParser._get_priorities_for(form.tag) + main_index = require_index + needs_coordination = Morphology.is_dependable(form.tag.POS) + else: + local_max = self._PRIORITY_NONE + for (index, form) in enumerate(forms): + if require_grams and not form.tag.grammemes.issuperset(require_grams): + continue + (local_priority, global_priority) = PhraseParser._get_priorities_for(form.tag) + needs_coordination = needs_coordination or Morphology.is_dependable(form.tag.POS) + local_sum += global_priority * form.score + score_sum += form.score + if local_priority > local_max: + local_max = local_priority + # segment_score = global_priority + main_index = index + if score_sum == 0: + return None + segment_score = local_sum / score_sum + output.add_word(segment, forms, main_index, needs_coordination) + return segment_score + # Alternative: return segment_score + # penalty_suspicious = 0 if local_max == 0 else (1 - local_sum / local_max) * self._PRIORITY_PENALTY + # return segment_score - penalty_suspicious + + @classmethod + def _finalize_coordination(cls, target: Collation): + main_morpho: Morphology = target.get_morpho() + main_coordinate = main_morpho.can_coordinate + target.coordination[target.main_word] = NO_COORDINATION + first_change = INDEX_NONE + current_len = 0 + for (index, word) in enumerate(target.words): + if target.coordination[index] == NO_COORDINATION or index - target.main_word > cls._MAIN_MAX_FOLLOWERS: + needs_change = False + if index != target.main_word: + word.main = INDEX_NONE + else: + word.main = PhraseParser._find_coordination(word.forms, main_morpho.tag, index < target.main_word) + needs_change = word.main != INDEX_NONE + if not needs_change or not main_coordinate: + target.coordination[index] = NO_COORDINATION + current_len += 1 + if needs_change and main_coordinate: + target.coordination[index] = current_len + current_len = 0 + if first_change == INDEX_NONE: + first_change = index + if first_change == INDEX_NONE: + target.coordination.append(len(target.words)) + return + previous_reference = first_change + current_word = len(target.words) + target.coordination.append(current_len + 1) + while target.coordination[current_word] != INDEX_NONE: + previous_word = current_word - target.coordination[current_word] + target.coordination[current_word] = previous_reference + previous_reference = current_word - previous_word + current_word = previous_word + if previous_reference == 0 or current_word < 0: + break + + @staticmethod + def _find_coordination(forms: list, main_tag: WordTag, before_main: bool) -> int: + for (index, form) in enumerate(forms): + pos = form.tag.POS + case = form.tag.case + if pos not in ['ADJF', 'ADJS', 'PRTF', 'PRTS']: + continue + if SemanticRole.from_POS(pos) == SemanticRole.term and case == 'gent': + if before_main: + continue + else: + return INDEX_NONE + if case == main_tag.case: + return index + elif main_tag.case in ['accs', 'gent'] and case in ['accs', 'gent']: + return index + return INDEX_NONE + + @staticmethod + def _filtered_parse(text: str): + capital = Capitalization.from_text(text) + score_filter = PhraseParser._filter_score(morpho.parse(text)) + yield from PhraseParser._filter_capital(score_filter, capital) + + @staticmethod + def _filter_score(generator): + for form in generator: + if form.score < PhraseParser._FILTER_SCORE: + break + yield form + + @staticmethod + def _filter_capital(generator, capital: Capitalization): + if capital in [Capitalization.upper_case, Capitalization.mixed]: + for form in generator: + if 'Abbr' not in form.tag.grammemes: + continue + yield form + else: + yield from generator + + @staticmethod + def _parse_word(text: str, require_index: int = INDEX_NONE, + require_grams: Optional[Grammemes] = None) -> Optional[Morphology]: + parsed_variants = morpho.parse(text) + if not parsed_variants or require_index >= len(parsed_variants): + return None + if require_index != INDEX_NONE: + tags = parsed_variants[require_index].tag + if not require_grams or tags.grammemes.issuperset(require_grams): + return Morphology(tags) + else: + return None + else: + for variant in parsed_variants: + tags = variant.tag + if not require_grams or tags.grammemes.issuperset(require_grams): + return Morphology(tags) + return None + + @staticmethod + def _get_priorities_for(tag: WordTag) -> tuple[float, float]: + ''' Return pair of local and global priorities. ''' + if tag.POS in ['VERB', 'INFN']: + return (9, 10) + if tag.POS in ['NOUN', 'NPRO']: + return (10, 9) if 'nomn' in tag.grammemes and 'Fixd' not in tag.grammemes else (8, 8) + if tag.POS in ['PRTF', 'PRTS']: + return (6, 6) + if tag.POS in ['ADJF', 'ADJS']: + return (5, 5) + if tag.POS == 'ADVB': + return (7, 4) + return (0, 0) + + @staticmethod + def _choose_context_etalon(target: Morphology, + before: Optional[Collation], + after: Optional[Collation]) -> Optional[Collation]: + if not before or not before.get_morpho().can_coordinate: + return after + if not after or not after.get_morpho().can_coordinate: + return before + + before_semantic = before.get_morpho().semantic + after_semantic = after.get_morpho().semantic + if target.semantic == SemanticRole.definition: + if after_semantic == SemanticRole.term: + return after + if before_semantic == SemanticRole.term: + return before + if before_semantic == SemanticRole.definition: + return before + return after + + if target.semantic == SemanticRole.term: + if before_semantic == SemanticRole.definition: + return before + if after_semantic == SemanticRole.definition: + return after + + return before + + @staticmethod + def _combine_morpho(target: Morphology, etalon: WordTag) -> frozenset[str]: + part_of_speech = target.tag.POS + number = etalon.number + if number == 'plur': + return frozenset([part_of_speech, number, etalon.case]) + else: + gender = etalon.gender if target.semantic != SemanticRole.term else target.tag.gender + return frozenset([part_of_speech, number, gender, etalon.case]) diff --git a/import/cctext/syntax.py b/import/cctext/syntax.py new file mode 100644 index 0000000..012b396 --- /dev/null +++ b/import/cctext/syntax.py @@ -0,0 +1,87 @@ +''' Russian language syntax incapsulation. ''' +from __future__ import annotations +from enum import Enum, unique + +from razdel import tokenize + + +@unique +class Capitalization(Enum): + ''' Enumerating capitalization types. ''' + unknwn = 0 + lower_case = 1 + upper_case = 2 + first_capital = 3 + mixed = 4 + + @staticmethod + def from_text(text: str) -> Capitalization: + ''' Fabric method to identify capitalization in text. ''' + if len(text) == 0: + return Capitalization.unknwn + first_capital = Capitalization._is_capital(text[0]) + has_mid_capital = False + has_lower = not first_capital + for symbol in text[1:]: + if Capitalization._is_capital(symbol): + if has_lower: + return Capitalization.mixed + has_mid_capital = True + else: + if has_mid_capital: + return Capitalization.mixed + else: + has_lower = True + if has_mid_capital: + return Capitalization.upper_case + elif first_capital: + return Capitalization.first_capital + else: + return Capitalization.lower_case + + def apply_to(self, text: str) -> str: + ''' Apply capitalization to text. ''' + if not text or self in [Capitalization.unknwn, Capitalization.mixed]: + return text + elif self == Capitalization.lower_case: + return text.lower() + elif self == Capitalization.upper_case: + return text.upper() + else: + return text[0].upper() + text[1:] + + @staticmethod + def _is_capital(symbol: str) -> bool: + return 'А' <= symbol <= 'Я' or 'A' <= symbol <= 'Z' + + +class RuSyntax: + ''' Russian language syntax parser. ''' + def __init__(self): + pass + + def __del__(self): + pass + + @staticmethod + def is_single_word(text: str) -> bool: + ''' Test if text is a single word. ''' + try: + gen = tokenize(text) + if next(gen) == '': + return True + if next(gen) == '': + return True + return False + except StopIteration: + return True + + @staticmethod + def tokenize(text: str): + ''' Split text into words. Returns list[(start, stop, text)]. ''' + return tokenize(text) + + @staticmethod + def split_words(text: str) -> list[str]: + ''' Split text into words. ''' + return [elem.text for elem in tokenize(text)] diff --git a/include/Exteor.RC b/include/Exteor.RC new file mode 100644 index 0000000..fb37d44 --- /dev/null +++ b/include/Exteor.RC @@ -0,0 +1,3777 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Russian (Russia) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT +#pragma code_page(1251) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\0" +END + +3 TEXTINCLUDE +BEGIN + "#include ""afxres.rc"" \t// Standard components\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IXTRAD_MENU_MAINFRAME ICON "..\\resource\\ExteorApp.ico" + +IXTRAD_MENU_RSFORM ICON "..\\resource\\trsFile.ico" + +IXTRAD_MENU_OSS ICON "..\\resource\\ossFile.ico" + +IXTRAD_MENU_RSMODEL ICON "..\\resource\\rsmFile.ico" + +IXTRR_PICT_BASIS ICON "..\\resource\\PICT_BASIS.ICO" + +IXTRR_PICT_UNDEFINED ICON "..\\resource\\PICT_UNDEFINED.ICO" + +IXTRR_PICT_DEFINED ICON "..\\resource\\PICT_DEFINED.ICO" + +IXTRR_PICT_DONE ICON "..\\resource\\PICT_DONE.ICO" + +IXTRR_PICT_REDO ICON "..\\resource\\PICT_REDO.ICO" + +IXTRR_PICT_BROKEN ICON "..\\resource\\PICT_BROKEN.ICO" + +IXTRR_PICT_HASFILE ICON "..\\resource\\PICT_HASFILE.ICO" + +IXTRR_NEW_DOC ICON "..\\resource\\NEW_DOC.ico" + +IXTRR_HELP ICON "..\\resource\\HELP.ico" + +IXTRR_OPEN_DOC ICON "..\\resource\\OPEN_DOC.ico" + +IXTRR_SAMPLES ICON "..\\resource\\SAMPLES.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IXTRR_TOOLBAR_MAINFRAME BITMAP "..\\resource\\TOOLBAR_MAINFRAME.BMP" + +IXTRR_TOOLBAR_RSFORM BITMAP "..\\resource\\TOOLBAR_RSFORM.BMP" + +IXTRR_TOOLBAR_OSS BITMAP "..\\resource\\TOOLBAR_OSS.BMP" + +IXTRR_BTN_BOOLEAN BITMAP "..\\resource\\BTN_BOOLEAN.BMP" + +IXTRR_BTN_DECART BITMAP "..\\resource\\BTN_DECART.BMP" + +IXTRR_BTN_LOGIC_NOT BITMAP "..\\resource\\BTN_LOGIC_NOT.BMP" + +IXTRR_BTN_SET_UNION BITMAP "..\\resource\\BTN_SET_UNION.BMP" + +IXTRR_BTN_SET_INTERSECT BITMAP "..\\resource\\BTN_SET_INTERSECT.BMP" + +IXTRR_BTN_LOGIC_OR BITMAP "..\\resource\\BTN_LOGIC_OR.BMP" + +IXTRR_BTN_ELEMENT BITMAP "..\\resource\\BTN_ELEMENT.BMP" + +IXTRR_BTN_LOGIC_IMPLICAT BITMAP "..\\resource\\BTN_LOGIC_IMPLICAT.BMP" + +IXTRR_BTN_NOTEQUAL BITMAP "..\\resource\\BTN_NOTEQUAL.BMP" + +IXTRR_BTN_EMPTYSET BITMAP "..\\resource\\BTN_EMPTYSET.BMP" + +IXTRR_BTN_LOGIC_EXISTS BITMAP "..\\resource\\BTN_LOGIC_EXISTS.BMP" + +IXTRR_BTN_LOGIC_FORALL BITMAP "..\\resource\\BTN_LOGIC_FORALL.BMP" + +IXTRR_BTN_LOGIC_EQUAL BITMAP "..\\resource\\BTN_LOGIC_EQ.BMP" + +IXTRR_BTN_LOGIC_AND BITMAP "..\\resource\\BTN_LOGIC_AND.BMP" + +IXTRR_BTN_EQUAL BITMAP "..\\resource\\BTN_EQUAL.BMP" + +IXTRR_BTN_SUBSET_OR_EQ BITMAP "..\\resource\\BTN_SUBSET_OR_EQ.BMP" + +IXTRR_BTN_NOTELEMENT BITMAP "..\\resource\\BTN_NOTELEMENT.BMP" + +IXTRR_BTN_NOTSUBSET BITMAP "..\\resource\\BTN_NOTSUBSET.BMP" + +IXTRR_BTN_SET_MINUS BITMAP "..\\resource\\BTN_SET_MINUS.BMP" + +IXTRR_BTN_SUBSET BITMAP "..\\resource\\BTN_SUBSET.BMP" + +IXTRR_BTN_SETDECLARATION BITMAP "..\\resource\\BTN_SETDECLARATION.BMP" + +IXTRR_BTN_DOUBLEPAR BITMAP "..\\resource\\BTN_DOUBLEPAR.BMP" + +IXTRR_BTN_GREATER_OR_EQ BITMAP "..\\resource\\BTN_GREATER_OR_EQ.BMP" + +IXTRR_BTN_LESSER_OR_EQ BITMAP "..\\resource\\BTN_LESSER_OR_EQ.BMP" + +IXTRR_BTN_SYMMINUS BITMAP "..\\resource\\BTN_SYMMINUS.BMP" + +IXTRR_BTN_DOUBLESQR BITMAP "..\\resource\\BTN_DOUBLESQR.bmp" + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IXTRAD_MENU_MAINFRAME MENU +BEGIN + POPUP "" + BEGIN + MENUITEM "...\tCtrl+N", ID_FILE_NEW + MENUITEM "...\tCtrl+O", ID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "Recent File", ID_FILE_MRU_FILE1, GRAYED + MENUITEM SEPARATOR + MENUITEM "", ID_APP_EXIT + END + POPUP "" + BEGIN + MENUITEM "...", IXTRC_EDIT_OPTIONS + END + POPUP "" + BEGIN + MENUITEM " ", IXTRC_START_PAGE + MENUITEM " \tF1", IXTRC_XTR_HELP + MENUITEM " ...", ID_APP_ABOUT + MENUITEM SEPARATOR + MENUITEM " ", IXTRC_BUG_REPORT + MENUITEM " ", IXTRC_MAIL_DEVELOPERS + END +END + +IXTRAD_MENU_RSFORM MENU +BEGIN + POPUP "" + BEGIN + MENUITEM "\tCtrl+N", ID_FILE_NEW + MENUITEM "...\tCtrl+O", ID_FILE_OPEN + MENUITEM "\tCtrl+W", ID_FILE_CLOSE + MENUITEM "\tCtrl+S", ID_FILE_SAVE + MENUITEM " ...", ID_FILE_SAVE_AS + MENUITEM SEPARATOR + POPUP "" + BEGIN + MENUITEM " ...", IXTRC_EXPORT_SCHEMA + MENUITEM " ...", IXTRC_EXPORT_GRAPH + END + MENUITEM " ", IXTRC_CONVERT_TO_RSFORM + MENUITEM SEPARATOR + MENUITEM "Recent File", ID_FILE_MRU_FILE1 + MENUITEM SEPARATOR + MENUITEM "", ID_APP_EXIT + END + POPUP "" + BEGIN + MENUITEM "\tCtrl+R", IXTRC_RENAME + MENUITEM "\tCtrl+C", ID_EDIT_COPY + MENUITEM "\tCtrl+V", ID_EDIT_PASTE + MENUITEM "\tDelete", IXTRC_DELETE_CST + MENUITEM SEPARATOR + POPUP " " + BEGIN + MENUITEM " \tCtrl+Shift+X", IXTRC_INSERT_BASE_SET + MENUITEM " \tCtrl+Shift+C", IXTRC_INSERT_CONST_SET + MENUITEM " \tCtrl+Shift+S", IXTRC_INSERT_RS + MENUITEM "\tCtrl+Shift+A", IXTRC_INSERT_AXIOM + MENUITEM "\tCtrl+Shift+D", IXTRC_INSERT_TERM + MENUITEM "-\tCtrl+Shift+F", IXTRC_INSERT_FUNCTION + MENUITEM "-\tCtrl+Shift+G", IXTRC_INSERT_PREDICATE + MENUITEM "\tCtrl+Shift+T", IXTRC_INSERT_THEOREMA + MENUITEM SEPARATOR + MENUITEM " \tCtrl+Shift+Q", IXTRC_INSERT_FREE + END + POPUP " " + BEGIN + MENUITEM " -> ", IXTRC_TERM_TO_FUNC + MENUITEM " -> ", IXTRC_FUNC_TO_TERM + MENUITEM " -> ", IXTRC_STRUCTURE_TO_TERMS + END + MENUITEM SEPARATOR + MENUITEM " \tCtrl+Q", IXTRC_SELECT_BASIS + MENUITEM " \tCtrl+E", IXTRC_SELECT_DEPENDENT + MENUITEM SEPARATOR + MENUITEM "\tF5", IXTRC_RESET_NAMES + MENUITEM " ", IXTRC_RESET_OSSFLAG + END + POPUP "" + BEGIN + MENUITEM " ", IXTRC_OP_MAX_PART + MENUITEM " ", IXTRC_OP_SELECT_BASIS + MENUITEM SEPARATOR + MENUITEM " ", IXTRC_CST_MERGING + MENUITEM "", IXTRC_SYNTHES + MENUITEM "", IXTRC_OP_MERGE + MENUITEM "", IXTRC_RELATION + END + POPUP "" + BEGIN + MENUITEM "...", IXTRC_EDIT_OPTIONS + END + POPUP "" + BEGIN + MENUITEM "", ID_WINDOW_CASCADE + MENUITEM " ", ID_WINDOW_TILE_HORZ + MENUITEM " ", ID_WINDOW_TILE_VERT + END + POPUP "" + BEGIN + MENUITEM " ", IXTRC_START_PAGE + MENUITEM " ", IXTRC_XTR_HELP + MENUITEM " ...", ID_APP_ABOUT + MENUITEM SEPARATOR + MENUITEM " ", IXTRC_BUG_REPORT + MENUITEM " ", IXTRC_MAIL_DEVELOPERS + END +END + +IXTRAD_MENU_OSS MENU +BEGIN + POPUP "" + BEGIN + MENUITEM "...\tCtrl+N", ID_FILE_NEW + MENUITEM "...\tCtrl+O", ID_FILE_OPEN + MENUITEM "\tCtrl+W", ID_FILE_CLOSE + MENUITEM "\tCtrl+S", ID_FILE_SAVE + MENUITEM SEPARATOR + POPUP "" + BEGIN + MENUITEM " PNG", IXTRC_SAVE_IMAGE + MENUITEM " JSON", IXTRC_EXPORT_OSS + END + MENUITEM SEPARATOR + MENUITEM "Recent File", ID_FILE_MRU_FILE1 + MENUITEM SEPARATOR + MENUITEM "", ID_APP_EXIT + END + POPUP "" + BEGIN + MENUITEM "\tF3", IXTRC_OSS_ENABLE_LEGEND + MENUITEM "", IXTRC_OSS_ENABLE_GRID + MENUITEM SEPARATOR + MENUITEM "\tNUM -", IXTRC_OSS_ZOOM_OUT + MENUITEM "\tNUM +", IXTRC_OSS_ZOOM_IN + END + POPUP "" + BEGIN + MENUITEM " \tCtrl+Q", IXTRC_OSS_ADD + MENUITEM SEPARATOR + MENUITEM " \tCtrl+D", IXTRC_OSS_OP_NEW + MENUITEM " \tCtrl+F7", IXTRC_OSS_OP_RUN_ALL + MENUITEM SEPARATOR + MENUITEM " ", IXTRC_BACKUP + END + POPUP "" + BEGIN + MENUITEM " \tEnter", IXTRC_OSS_EDIT_DOC + MENUITEM " \tCtrl+A", IXTRC_OSS_ASSIGN_DOC + MENUITEM " ", IXTRC_OSS_DISCARD_DOC + MENUITEM SEPARATOR + MENUITEM " \tCtrl+E", IXTRC_OSS_OP_EDIT + MENUITEM " ", IXTRC_OSS_OP_CHECK + MENUITEM " \tF7", IXTRC_OSS_OP_RUN_SINGLE + MENUITEM SEPARATOR + MENUITEM " \tCtrl+R", IXTRC_FOLLOW_HLINK + MENUITEM " \tCtrl+K", IXTRC_EDIT_HLINK + MENUITEM SEPARATOR + MENUITEM " \tCtrl+Right", IXTRC_OSS_SHIFT_RIGHT + MENUITEM " \tCtrl+Left", IXTRC_OSS_SHIFT_LEFT + MENUITEM "\tDelete", IXTRC_OSS_DEL + END + POPUP "" + BEGIN + MENUITEM "...", IXTRC_EDIT_OPTIONS + END + POPUP "" + BEGIN + MENUITEM "", ID_WINDOW_CASCADE + MENUITEM " ", ID_WINDOW_TILE_HORZ + MENUITEM " ", ID_WINDOW_TILE_VERT + END + POPUP "" + BEGIN + MENUITEM " ", IXTRC_START_PAGE + MENUITEM " ", IXTRC_XTR_HELP + MENUITEM " ...", ID_APP_ABOUT + MENUITEM SEPARATOR + MENUITEM " ", IXTRC_BUG_REPORT + MENUITEM " ", IXTRC_MAIL_DEVELOPERS + END +END + +IXTRAD_RSVIEW_POPUP MENU +BEGIN + POPUP "POPUP MENU" + BEGIN + MENUITEM "", IXTRC_RENAME + MENUITEM "", ID_EDIT_COPY + MENUITEM "", ID_EDIT_PASTE + MENUITEM "", IXTRC_DELETE_CST + MENUITEM "", IXTRC_CALCULATE + MENUITEM SEPARATOR + MENUITEM " -> ", IXTRC_TERM_TO_FUNC + MENUITEM " -> ", IXTRC_FUNC_TO_TERM + MENUITEM " -> ", IXTRC_STRUCTURE_TO_TERMS + MENUITEM SEPARATOR + MENUITEM " ", IXTRC_RESET_COLUMNS + END +END + +IXTRAD_MENU_RSMODEL MENU +BEGIN + POPUP "" + BEGIN + MENUITEM "\tCtrl+N", ID_FILE_NEW + MENUITEM "...\tCtrl+O", ID_FILE_OPEN + MENUITEM "\tCtrl+W", ID_FILE_CLOSE + MENUITEM "\tCtrl+S", ID_FILE_SAVE + MENUITEM " ...", ID_FILE_SAVE_AS + MENUITEM SEPARATOR + POPUP "" + BEGIN + MENUITEM " ...", IXTRC_EXPORT_SCHEMA + MENUITEM " ...", IXTRC_EXPORT_GRAPH + MENUITEM " ...", IXTRC_EXPORT_MODEL + END + MENUITEM " - ", IXTRC_CONVERT_TO_RSFORM + MENUITEM SEPARATOR + MENUITEM "Recent File", ID_FILE_MRU_FILE1 + MENUITEM SEPARATOR + MENUITEM "", ID_APP_EXIT + END + POPUP "" + BEGIN + MENUITEM "\tCtrl+G", IXTRC_CALCULATE + MENUITEM "\tCtrl+R", IXTRC_RENAME + MENUITEM "\tCtrl+C", ID_EDIT_COPY + MENUITEM "\tCtrl+V", ID_EDIT_PASTE + MENUITEM "\tDelete", IXTRC_DELETE_CST + MENUITEM SEPARATOR + POPUP " " + BEGIN + MENUITEM " \tCtrl+Shift+X", IXTRC_INSERT_BASE_SET + MENUITEM " \tCtrl+Shift+C", IXTRC_INSERT_CONST_SET + MENUITEM " \tCtrl+Shift+S", IXTRC_INSERT_RS + MENUITEM "\tCtrl+Shift+A", IXTRC_INSERT_AXIOM + MENUITEM "\tCtrl+Shift+D", IXTRC_INSERT_TERM + MENUITEM "-\tCtrl+Shift+F", IXTRC_INSERT_FUNCTION + MENUITEM "-\tCtrl+Shift+G", IXTRC_INSERT_PREDICATE + MENUITEM "\tCtrl+Shift+T", IXTRC_INSERT_THEOREMA + MENUITEM SEPARATOR + MENUITEM " \tCtrl+Shift+Q", IXTRC_INSERT_FREE + END + POPUP " " + BEGIN + MENUITEM " -> ", IXTRC_TERM_TO_FUNC + MENUITEM " -> ", IXTRC_FUNC_TO_TERM + MENUITEM " -> ", IXTRC_STRUCTURE_TO_TERMS + END + MENUITEM SEPARATOR + MENUITEM " \tCtrl+Q", IXTRC_SELECT_BASIS + MENUITEM " \tCtrl+E", IXTRC_SELECT_DEPENDENT + MENUITEM SEPARATOR + MENUITEM "\tF5", IXTRC_RESET_NAMES + END + POPUP "" + BEGIN + MENUITEM " ", IXTRC_CALCULATE + MENUITEM " ", IXTRC_MODEL_CALCULATE + END + POPUP "" + BEGIN + MENUITEM "...", IXTRC_EDIT_OPTIONS + END + POPUP "" + BEGIN + MENUITEM "", ID_WINDOW_CASCADE + MENUITEM " ", ID_WINDOW_TILE_HORZ + MENUITEM " ", ID_WINDOW_TILE_VERT + END + POPUP "" + BEGIN + MENUITEM " ", IXTRC_START_PAGE + MENUITEM " ", IXTRC_XTR_HELP + MENUITEM " ...", ID_APP_ABOUT + MENUITEM SEPARATOR + MENUITEM " ", IXTRC_BUG_REPORT + MENUITEM " ", IXTRC_MAIL_DEVELOPERS + END +END + +IXTRAD_OSS_POPUP MENU +BEGIN + POPUP "POPUP MENU" + BEGIN + MENUITEM " ", IXTRC_OSS_EDIT_DOC + MENUITEM " ", IXTRC_OSS_ASSIGN_DOC + MENUITEM " ", IXTRC_OSS_DISCARD_DOC + MENUITEM SEPARATOR + MENUITEM " ", IXTRC_OSS_OP_RUN_SINGLE + MENUITEM " ", IXTRC_OSS_OP_CHECK + MENUITEM " ", IXTRC_OSS_OP_EDIT + MENUITEM SEPARATOR + MENUITEM " ", IXTRC_FOLLOW_HLINK + MENUITEM " ", IXTRC_EDIT_HLINK + MENUITEM SEPARATOR + MENUITEM " ", IXTRC_OSS_DEL + END +END + +IXTRAD_MENU_CST MENU +BEGIN + POPUP "" + BEGIN + MENUITEM " ", IXTRC_INSERT_BASE_SET + MENUITEM " ", IXTRC_INSERT_CONST_SET + MENUITEM " ", IXTRC_INSERT_RS + MENUITEM "", IXTRC_INSERT_AXIOM + MENUITEM "", IXTRC_INSERT_TERM + MENUITEM "-", IXTRC_INSERT_FUNCTION + MENUITEM "-", IXTRC_INSERT_PREDICATE + MENUITEM "", IXTRC_INSERT_THEOREMA + END + POPUP "" + BEGIN + MENUITEM "", IXTRC_AUTOCHECK + MENUITEM " ", IXTRC_EDITREF + MENUITEM " ", IXTRC_RSNAVIGATOR + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IXTRAD_MENU_MAINFRAME ACCELERATORS +BEGIN + "W", ID_FILE_CLOSE, VIRTKEY, CONTROL, NOINVERT + "N", ID_FILE_NEW, VIRTKEY, CONTROL, NOINVERT + "O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT + "S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT + VK_F6, ID_NEXT_PANE, VIRTKEY, NOINVERT + VK_F6, ID_PREV_PANE, VIRTKEY, SHIFT, NOINVERT + VK_F1, IXTRC_XTR_HELP, VIRTKEY, NOINVERT +END + +IXTRAD_MENU_RSFORM ACCELERATORS +BEGIN + "C", ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT + "V", ID_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT + "A", IXTRC_INSERT_AXIOM, VIRTKEY, SHIFT, CONTROL, NOINVERT + "X", IXTRC_INSERT_BASE_SET, VIRTKEY, SHIFT, CONTROL, NOINVERT + "C", IXTRC_INSERT_CONST_SET, VIRTKEY, SHIFT, CONTROL, NOINVERT + "Q", IXTRC_INSERT_FREE, VIRTKEY, SHIFT, CONTROL, NOINVERT + "F", IXTRC_INSERT_FUNCTION, VIRTKEY, SHIFT, CONTROL, NOINVERT + "G", IXTRC_INSERT_PREDICATE, VIRTKEY, SHIFT, CONTROL, NOINVERT + "S", IXTRC_INSERT_RS, VIRTKEY, SHIFT, CONTROL, NOINVERT + "D", IXTRC_INSERT_TERM, VIRTKEY, SHIFT, CONTROL, NOINVERT + "T", IXTRC_INSERT_THEOREMA, VIRTKEY, SHIFT, CONTROL, NOINVERT + VK_F6, ID_NEXT_PANE, VIRTKEY, NOINVERT + VK_F6, ID_PREV_PANE, VIRTKEY, SHIFT, NOINVERT + "R", IXTRC_RENAME, VIRTKEY, CONTROL, NOINVERT + VK_F5, IXTRC_RESET_NAMES, VIRTKEY, NOINVERT + "Q", IXTRC_SELECT_BASIS, VIRTKEY, CONTROL, NOINVERT + "E", IXTRC_SELECT_DEPENDENT, VIRTKEY, CONTROL, NOINVERT + ">", IXTRC_NEXT, ASCII, ALT, NOINVERT + "<", IXTRC_PREV, ASCII, ALT, NOINVERT + VK_UP, IXTRC_MOVE_UP, VIRTKEY, CONTROL, NOINVERT + VK_DOWN, IXTRC_MOVE_DOWN, VIRTKEY, CONTROL, NOINVERT +END + +IXTRAD_MENU_RSMODEL ACCELERATORS +BEGIN + "G", IXTRC_CALCULATE, VIRTKEY, CONTROL, NOINVERT + "A", IXTRC_INSERT_AXIOM, VIRTKEY, SHIFT, CONTROL, NOINVERT + "X", IXTRC_INSERT_BASE_SET, VIRTKEY, SHIFT, CONTROL, NOINVERT + "C", IXTRC_INSERT_CONST_SET, VIRTKEY, SHIFT, CONTROL, NOINVERT + "Q", IXTRC_INSERT_FREE, VIRTKEY, SHIFT, CONTROL, NOINVERT + "F", IXTRC_INSERT_FUNCTION, VIRTKEY, SHIFT, CONTROL, NOINVERT + "G", IXTRC_INSERT_PREDICATE, VIRTKEY, SHIFT, CONTROL, NOINVERT + "S", IXTRC_INSERT_RS, VIRTKEY, SHIFT, CONTROL, NOINVERT + "D", IXTRC_INSERT_TERM, VIRTKEY, SHIFT, CONTROL, NOINVERT + "T", IXTRC_INSERT_THEOREMA, VIRTKEY, SHIFT, CONTROL, NOINVERT + VK_F6, ID_NEXT_PANE, VIRTKEY, NOINVERT + VK_F6, ID_PREV_PANE, VIRTKEY, SHIFT, NOINVERT + "R", IXTRC_RENAME, VIRTKEY, CONTROL, NOINVERT + VK_F5, IXTRC_RESET_NAMES, VIRTKEY, NOINVERT + "Q", IXTRC_SELECT_BASIS, VIRTKEY, CONTROL, NOINVERT + "E", IXTRC_SELECT_DEPENDENT, VIRTKEY, CONTROL, NOINVERT + ">", IXTRC_NEXT, ASCII, ALT, NOINVERT + "<", IXTRC_PREV, ASCII, ALT, NOINVERT + "C", ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT + "V", ID_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT + VK_UP, IXTRC_MOVE_UP, VIRTKEY, CONTROL, NOINVERT + VK_DOWN, IXTRC_MOVE_DOWN, VIRTKEY, CONTROL, NOINVERT +END + +IXTRAD_MENU_OSS ACCELERATORS +BEGIN + "K", IXTRC_EDIT_HLINK, VIRTKEY, CONTROL, NOINVERT + "R", IXTRC_FOLLOW_HLINK, VIRTKEY, CONTROL, NOINVERT + "Q", IXTRC_OSS_ADD, VIRTKEY, CONTROL, NOINVERT + "A", IXTRC_OSS_ASSIGN_DOC, VIRTKEY, CONTROL, NOINVERT + VK_DELETE, IXTRC_OSS_DEL, VIRTKEY, NOINVERT + VK_NUMPAD5, IXTRC_OSS_EDIT_DOC, VIRTKEY, NOINVERT + VK_RETURN, IXTRC_OSS_EDIT_DOC, VIRTKEY, NOINVERT + VK_F3, IXTRC_OSS_ENABLE_LEGEND, VIRTKEY, NOINVERT + "E", IXTRC_OSS_OP_EDIT, VIRTKEY, CONTROL, NOINVERT + "D", IXTRC_OSS_OP_NEW, VIRTKEY, CONTROL, NOINVERT + VK_F7, IXTRC_OSS_OP_RUN_ALL, VIRTKEY, CONTROL, NOINVERT + VK_F7, IXTRC_OSS_OP_RUN_SINGLE, VIRTKEY, NOINVERT + "A", IXTRC_OSS_SHIFT_LEFT, VIRTKEY, SHIFT, CONTROL, NOINVERT + VK_LEFT, IXTRC_OSS_SHIFT_LEFT, VIRTKEY, CONTROL, NOINVERT + "D", IXTRC_OSS_SHIFT_RIGHT, VIRTKEY, SHIFT, CONTROL, NOINVERT + VK_RIGHT, IXTRC_OSS_SHIFT_RIGHT, VIRTKEY, CONTROL, NOINVERT + VK_F7, IXTRC_OSS_SYNT_ALL, VIRTKEY, CONTROL, ALT, NOINVERT + VK_ADD, IXTRC_OSS_ZOOM_IN, VIRTKEY, NOINVERT + VK_SUBTRACT, IXTRC_OSS_ZOOM_OUT, VIRTKEY, NOINVERT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IXTRD_ABOUTBOX DIALOGEX 50, 40, 167, 92 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About Exteor" +FONT 8, "Arial", 400, 0, 0xCC +BEGIN + LTEXT " 4.9",IXTRC_LEGALTRADEMARKS,7,10,101,8 + LTEXT "Copyright CIHT CONCEPT 1994 - 2023",IXTRC_COPYRIGHT,7,39,149,8 + DEFPUSHBUTTON "OK",IDOK,128,6,35,14 + CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME,8,54,144,1 + LTEXT "Version 4.9",IXTRC_VERSION,7,21,152,8 + LTEXT "Site:\t\twww.acconcept.ru",IXTRC_COPYRIGHT2,7,71,147,8 + LTEXT "Contact e-mail:\tbugreport@acconcept.ru",IXTRC_COPYRIGHT3,7,79,150,8 + LTEXT "Bug reports and suggestions are appreciated",IXTRC_COPYRIGHT4,7,61,152,8 +END + +IXTRD_VIEW_RSFORM DIALOGEX 0, 0, 456, 194 +STYLE DS_ABSALIGN | DS_SETFONT | WS_CHILD +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + CONTROL "Generic2",IXTRC_RSFORM_LIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,2,42,449,148,WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE + EDITTEXT IXTRC_TITLE,58,9,176,15,ES_AUTOHSCROLL + EDITTEXT IXTRC_ALIAS,58,25,87,15,ES_AUTOHSCROLL + PUSHBUTTON "",IXTRC_COMMENT_B,148,25,86,14,BS_CENTER + PUSHBUTTON " ",IXTRC_TRS_UPDATE_STATUS,236,25,57,14,BS_CENTER + LTEXT ":",IDC_STATIC,3,11,50,8 + LTEXT ":",IDC_STATIC,3,28,49,8 + CONTROL "",IXTRC_RSFORM_STATUS,"RichEdit20W",0x881,237,10,55,13 + GROUPBOX "- ",IXTRC_STATIC_BORDER,2,0,452,42 + EDITTEXT IXTRC_RSFORM_SEARCH,296,9,151,15,ES_AUTOHSCROLL + PUSHBUTTON "",IXTRC_TRS_SEARCH,295,25,152,14,BS_CENTER +END + +IXTRD_CST_EDIT_DATA DIALOGEX 0, 0, 553, 385 +STYLE DS_SETFONT | WS_DISABLED | WS_CAPTION | WS_SYSMENU +CAPTION "" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + COMBOBOX IXTRC_NAME_CB,5,1,56,276,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "",IXTRC_EXPRESSION,"RichEdit20W",WS_BORDER | WS_VSCROLL | WS_TABSTOP | 0x44,53,76,490,90 + CONTROL "",IXTRC_TERM,"RichEdit20W",WS_BORDER | WS_VSCROLL | WS_TABSTOP | 0x44,112,3,432,31 + CONTROL "",IXTRC_INTERPRETATION,"RichEdit20W",WS_BORDER | WS_VSCROLL | WS_TABSTOP | 0x44,6,265,537,61 + CONTROL "",IXTRC_COMMENT_KS,"RichEdit20W",WS_BORDER | WS_VSCROLL | WS_TABSTOP | 0x44,6,342,537,41 + PUSHBUTTON "&<<",IXTRC_PREV,5,15,27,16,NOT WS_TABSTOP + PUSHBUTTON "&>>",IXTRC_NEXT,34,15,27,16,NOT WS_TABSTOP + LTEXT " ",IXTRC_FORM_WYR_STATIC,53,65,106,8 + LTEXT " ",IXTRC_INTERPRETATION_STATIC,7,252,229,8 + LTEXT " / ",IXTRC_COMMENT_STATIC,7,330,95,11 + EDITTEXT IXTRC_NAME,4,46,39,13,ES_AUTOHSCROLL + CONTROL "",IXTRC_EXP_STATUS,"RichEdit20W",0x881,430,61,48,13 + CONTROL "",IXTRC_SYNTAX,"RichEdit20W",WS_BORDER | WS_VSCROLL | 0x844,53,194,490,52 + LTEXT "",IXTRC_FORM_WYR_STATIC2,9,174,38,8 + CONTROL "",IXTRC_TYPIFICATION,"RichEdit20W",WS_BORDER | WS_VSCROLL | 0x844,53,170,490,17 + LTEXT "",IXTRC_FORM_WYR_STATIC3,71,6,35,8 + CONTROL "",IXTRC_LANGUAGE,"RichEdit20W",WS_BORDER | 0x881,479,60,65,14 + LTEXT " ",IXTRC_FORM_WYR_STATIC4,479,48,43,8 + LTEXT "",IXTRC_CSTNAME_STATIC,6,34,54,8 + CONTROL "",IXTRC_ALLOW_EDIT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,65,20,42,10 + CONTROL "",IXTRC_BOOLEAN,"MfcButton",0x0,94,45,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_CARTPROD,"MfcButton",0x0,116,45,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_DOUBLEPAR,"MfcButton",0x0,139,45,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_DOUBLESQR,"MfcButton",0x0,161,45,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_QUANTUNIVERSAL,"MfcButton",0x0,183,45,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_QUANTEXIST,"MfcButton",0x0,205,45,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_NEGATION,"MfcButton",0x0,227,45,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_OR,"MfcButton",0x0,249,45,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_LOGIC_AND,"MfcButton",0x0,271,45,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_IMPLICATION,"MfcButton",0x0,293,45,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_LOGIC_EQUAL,"MfcButton",0x0,315,45,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_NULLSET,"MfcButton",0x0,337,45,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_EQUAL,"MfcButton",0x0,359,45,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_INEQ,"MfcButton",0x0,381,45,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_GREATER_OR_EQ,"MfcButton",0x0,403,45,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_LESSER_OR_EQ,"MfcButton",0x0,425,45,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_BELONG,"MfcButton",0x0,183,60,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_NOTELEMENT,"MfcButton",0x0,205,60,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_SUBSET,"MfcButton",0x0,227,60,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_NOTSUBSET,"MfcButton",0x0,249,60,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_SUBSET_OR_EQ,"MfcButton",0x0,271,60,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_INTERSECT,"MfcButton",0x0,293,60,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_UNION,"MfcButton",0x0,315,60,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_SET_MINUS,"MfcButton",0x0,337,60,19,11,WS_EX_TRANSPARENT + CONTROL "",IXTRC_SET_SYMMINUS,"MfcButton",0x0,359,60,19,11,WS_EX_TRANSPARENT + CONTROL "Pr",IXTRC_PR_L,"MfcButton",0x0,8,85,12,14 + CONTROL "pr",IXTRC_PR_S,"MfcButton",0x0,21,85,12,14 + CONTROL "bool",IXTRC_BOOL,"MfcButton",0x0,8,102,35,14 + CONTROL "debool",IXTRC_DEBOOL,"MfcButton",0x0,8,118,35,14 + CONTROL "red",IXTRC_RED,"MfcButton",0x0,8,134,35,14 + CONTROL "card",IXTRC_CARD,"MfcButton",0x0,8,150,35,14 + CONTROL "?",IXTRC_INPUT_HELP,"MfcButton",0x0,526,44,17,14 + CONTROL "",IXTRC_ANALYSE,"MfcButton",WS_TABSTOP,2,194,48,16 + CONTROL "",IXTRC_CALCULATE,"MfcButton",WS_TABSTOP,2,213,48,16 + CONTROL "ASCII",IXTRC_SHOW_SSYNTAX,"MfcButton",0x0,390,60,37,14 + CONTROL "R",IXTRC_RS_RECURSIVE,"MfcButton",0x0,35,67,12,14 + CONTROL "D",IXTRC_RS_DECLARATIVE,"MfcButton",0x0,8,67,12,14 + CONTROL "I",IXTRC_RS_IMPERATIVE,"MfcButton",0x0,21,67,12,14 + CONTROL "Fi",IXTRC_FILTER,"MfcButton",0x0,35,85,12,14 +END + +IXTRD_VIEW_TERMTREE DIALOGEX 0, 0, 108, 146 +STYLE DS_ABSALIGN | DS_SETFONT | WS_CHILD +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + CONTROL "Tree1",IXTRC_TERM_TREE,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS | WS_BORDER | WS_HSCROLL | WS_TABSTOP,3,2,100,140 +END + +IXTRD_EDIT_COMMENT DIALOGEX 0, 0, 346, 177 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + DEFPUSHBUTTON "OK",IDOK,55,158,50,14 + PUSHBUTTON "",IDCANCEL,252,158,50,14 + CONTROL "",IXTRC_COMMENT_EC,"RichEdit20W",WS_BORDER | WS_VSCROLL | WS_TABSTOP | 0x44,5,7,332,146 +END + +IXTRD_CST_RENAME DIALOGEX 0, 0, 146, 81 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + DEFPUSHBUTTON "OK",IDOK,3,61,63,14 + PUSHBUTTON "",IDCANCEL,76,61,67,14 + LTEXT " ",IDC_STATIC,8,9,40,8 + LTEXT " ",IDC_STATIC,9,28,38,8 + COMBOBOX IXTRC_NAME_CB,59,7,56,276,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL " ",IXTRC_CHANGE_EXPR, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,46,131,10 + EDITTEXT IXTRC_NAME,59,26,56,12,ES_AUTOHSCROLL +END + +IXTRD_NEW_OSSDOC DIALOGEX 0, 0, 343, 87 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION " " +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + LTEXT " :",IDC_STATIC,7,7,118,8 + EDITTEXT IXTRC_OSS_NAME,7,19,260,12,ES_AUTOHSCROLL + LTEXT " :",IDC_STATIC,7,44,182,8 + EDITTEXT IXTRC_OSS_PATH,7,55,260,12,ES_AUTOHSCROLL + DEFPUSHBUTTON "OK",IDOK,286,7,50,14,WS_DISABLED + PUSHBUTTON "",IDCANCEL,286,24,50,14 + PUSHBUTTON "...",IXTRC_BROWSE,286,54,50,14 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDVERT,274,7,1,73 +END + +IXTRD_VIEW_PICT DIALOGEX 0, 0, 239, 381 +STYLE DS_ABSALIGN | DS_SETFONT | WS_CHILD +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + EDITTEXT IXTRC_VIEW_OSS_NAME,48,15,182,14,ES_AUTOHSCROLL + EDITTEXT IXTRC_TITLE,60,70,170,14,ES_AUTOHSCROLL + EDITTEXT IXTRC_ALIAS,60,86,62,14,ES_AUTOHSCROLL + CONTROL "",IXTRC_COMMENT,"RichEdit20W",WS_BORDER | WS_VSCROLL | WS_TABSTOP | 0x44,9,135,221,48 + PUSHBUTTON "",IXTRC_PICT_LINK,125,86,51,14 + PUSHBUTTON " ",IXTRC_FILE_NAME,181,86,49,14 + PUSHBUTTON "",IXTRC_OSS_COMMENT,7,33,51,14 + PUSHBUTTON " ",IXTRC_OSS_FILE,63,33,49,14 + PUSHBUTTON " ",IXTRC_OPEN_FOLDER,115,33,56,14 + EDITTEXT IXTRC_STATUS,51,208,177,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP + EDITTEXT IXTRC_OPERATION,51,226,178,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP + EDITTEXT IXTRC_OPERAND1,51,245,178,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP + EDITTEXT IXTRC_OPERAND2,51,263,178,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP + CONTROL "ListTabl",IXTRC_OTOGDESWLENYA,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_NOSORTHEADER | WS_BORDER,7,295,221,70 + GROUPBOX " ",IXTRC_STATIC_BORDER,4,56,231,133 + LTEXT " ",IDC_STATIC,7,72,48,8 + LTEXT " ",IDC_STATIC,7,88,51,8 + LTEXT "",IDC_STATIC,7,210,35,8 + LTEXT " 1",IDC_STATIC,7,247,40,10 + LTEXT "",IXTRC_STATIC_OP_SINT,7,227,34,8 + LTEXT "",IXTRC_STATIC_OTOGD,7,282,40,8 + GROUPBOX " ",IXTRC_STATIC_BORDER2,4,194,231,181 + LTEXT " 2",IDC_STATIC,7,265,39,10 + GROUPBOX " ",IXTRC_STATIC_BORDER3,4,3,231,48 + LTEXT ":",IDC_STATIC,7,17,39,8 + LTEXT "",IDC_STATIC,7,124,48,8 + PUSHBUTTON " ",IXTRC_BACKUP,174,33,58,14 + EDITTEXT IXTRC_SRC_TYPE,60,106,170,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP + LTEXT " ",IDC_STATIC,7,108,52,8 +END + +IXTRD_OPTION_OSS DIALOGEX 0, 0, 287, 222 +STYLE DS_SETFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + LTEXT " :",IDC_STATIC,7,24,179,8 + CONTROL " ",IXTRC_OSS_RUN_AFTER_CLK_OK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,52,228,10 + EDITTEXT IXTRC_ZOOM_INT,189,22,37,14,ES_AUTOHSCROLL + CONTROL " ",IXTRC_OSS_GRID_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,38,229,10 + GROUPBOX " ",IDC_STATIC,4,7,275,205 +END + +IXTRD_OSS_OPERATIONS DIALOGEX 0, 0, 219, 129 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION " " +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + LISTBOX IXTRC_OSS_SINT_DEF_LC,7,7,205,80,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + CONTROL " ",IXTRC_OSS_RUN_AFTER_CLK_OK, + "Button",BS_AUTOCHECKBOX,17,89,171,10 + PUSHBUTTON "OK",IDOK,10,106,50,14 + PUSHBUTTON "",IDCANCEL,85,106,50,14 + PUSHBUTTON "",IXTRC_XTR_HELP,159,106,50,14 +END + +IXTRD_EXPORT_SCHEMA DIALOGEX 0, 0, 131, 171 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX " Word",IDC_STATIC,7,65,114,79 + CONTROL "",IXTRC_CBTYPIFICATION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,79,62,10 + CONTROL "",IXTRC_CBTERMIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,91,62,10 + CONTROL " ",IXTRC_CBFORMEXPR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,103,99,10 + CONTROL ". ",IXTRC_CBINTERPRET,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,115,80,10 + CONTROL "/",IXTRC_CBCOMMENT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,127,62,10 + DEFPUSHBUTTON "OK",IDOK,7,150,50,14 + PUSHBUTTON "",IDCANCEL,67,150,50,14 + GROUPBOX " ",IDC_STATIC,7,7,114,58 + CONTROL " Word",IXTRC_FILE_DOCX,"Button",BS_AUTORADIOBUTTON | WS_GROUP,15,18,97,10 + CONTROL " CSV",IXTRC_FILE_CSV,"Button",BS_AUTORADIOBUTTON,15,32,97,10 + CONTROL " JSON",IXTRC_FILE_JSON,"Button",BS_AUTORADIOBUTTON,15,47,97,10 +END + +IXTRD_SYNT_OPERANDS DIALOGEX 0, 0, 457, 231 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION " 1: " +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + LTEXT " 1",IXTRC_SHEMA1_NAME,195,7,245,8 + CONTROL "List1",IXTRC_SYNT_OP1,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,109,19,345,94 + CONTROL "",IXTRC_SYNT_OP2,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,109,126,345,94 + LTEXT " 2",IXTRC_SHEMA2_NAME,195,116,243,8 + LTEXT " 2 ():",IDC_STATIC,113,116,77,8 + LTEXT " 1 ():",IDC_STATIC,113,7,78,8 + GROUPBOX " ",IDC_STATIC,4,9,98,40 + CONTROL "",IXTRC_SYNT_MERGE,"Button",BS_AUTORADIOBUTTON | WS_GROUP,12,20,45,10 + CONTROL " ",IXTRC_SYNT_ABSTRACT,"Button",BS_AUTORADIOBUTTON,12,33,86,10 +END + +IXTRD_SYNT_MAPTABLE DIALOGEX 0, 0, 457, 231 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION " 2: " +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + CONTROL "List1",IXTRC_BM_OP1,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,0,14,203,107 + CONTROL "List1",IXTRC_BM_OP2,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,254,14,203,107,WS_EX_LEFTSCROLLBAR + CONTROL "List1",IXTRC_SYNT_FLAG_CTABLE,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,0,161,456,69 + CTEXT "2. 2",IXTRC_NAME2,267,3,187,8 + CTEXT "1. 1",IXTRC_NAME1,0,4,194,8 + CTEXT "3. ",IDC_STATIC,0,126,456,8 + CTEXT "",IXTRC_NAME3,217,48,23,8 + CTEXT "",IXTRC_NAME4,217,64,23,8 + CTEXT "",IXTRC_NAME5,217,80,23,8 + CONTROL "",IXTRC_FLAG_BM,"Button",BS_AUTOCHECKBOX | WS_GROUP,207,47,11,11 + CONTROL "",IXTRC_FLAG_RS,"Button",BS_AUTOCHECKBOX | WS_GROUP,207,63,11,11 + CONTROL "",IXTRC_FLAG_TERM,"Button",BS_AUTOCHECKBOX | WS_GROUP,207,79,11,11 + CONTROL "",IXTRC_FLAG_TERM2,"Button",BS_AUTOCHECKBOX | WS_GROUP,242,79,11,11 + CONTROL "",IXTRC_FLAG_RS2,"Button",BS_AUTOCHECKBOX | WS_GROUP,242,63,11,11 + CONTROL "",IXTRC_FLAG_BM2,"Button",BS_AUTOCHECKBOX | WS_GROUP,242,47,11,11 + CTEXT "",IXTRC_NAME6,209,34,40,8 + PUSHBUTTON "-> 1 ->",IXTRC_IN1,2,137,162,19 + PUSHBUTTON "<- 2 <-",IXTRC_IN2,294,137,162,19 + PUSHBUTTON "~ ~",IXTRC_IN3,176,137,105,19 +END + +IXTRD_SYNT_NAMES DIALOGEX 0, 0, 457, 231 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_WINDOWEDGE +CAPTION " 3: -" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + COMBOBOX IXTRC_RESULT_TITLE,7,210,358,50,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP + COMBOBOX IXTRC_RESULT_ALIAS,382,210,61,47,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT ": ",-1,7,9,71,8 + EDITTEXT IXTRC_OP_NAME,77,7,366,12,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP + LTEXT " :",-1,7,25,71,8 + EDITTEXT IXTRC_FIRST_OP,77,25,366,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP + EDITTEXT IXTRC_SECOND_OP,77,42,366,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP + CONTROL "",-1,"Static",SS_ETCHEDHORZ,7,186,436,1 + LTEXT " -:",IXTRC_STATIC_FULL_NAME,7,194,169,8 + LTEXT " ",IXTRC_STATIC_SHORT_NAME,395,193,48,8 + CTEXT " ",-1,7,61,437,8 + LTEXT " :",-1,7,42,68,12 + CONTROL "",IXTRC_SYNT_FLAG_CTABLE,"SysListView32",LVS_REPORT | LVS_SINGLESEL | WS_BORDER,7,74,437,102 +END + +IXTRD_OPTION_ANALYZER DIALOGEX 0, 0, 287, 222 +STYLE DS_SETFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + CONTROL "",IXTRC_INDEXCST0,"Button",BS_AUTORADIOBUTTON | WS_GROUP,124,75,11,10 + CONTROL "",IXTRC_INDEXCST1,"Button",BS_AUTORADIOBUTTON,177,75,9,10 + CONTROL "",IXTRC_INDEXCST2,"Button",BS_AUTORADIOBUTTON,227,75,9,10 + CONTROL "",IXTRC_INDEXLOCAL0,"Button",BS_AUTORADIOBUTTON | WS_GROUP,124,88,11,10 + CONTROL "",IXTRC_INDEXLOCAL1,"Button",BS_AUTORADIOBUTTON,177,88,11,10 + CONTROL "",IXTRC_INDEXLOCAL2,"Button",BS_AUTORADIOBUTTON,227,88,11,10 + CONTROL "",IXTRC_INDEXPR0,"Button",BS_AUTORADIOBUTTON | WS_GROUP,124,102,11,10 + CONTROL "",IXTRC_INDEXPR1,"Button",BS_AUTORADIOBUTTON,177,102,11,10 + CONTROL "",IXTRC_INDEXPR2,"Button",BS_AUTORADIOBUTTON,227,102,11,10 + CONTROL " ",IXTRC_SA_AUTOCHECK, + "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,7,6,203,10 + GROUPBOX " ",IDC_STATIC,7,54,276,66 + CONTROL " ",IXTRC_SA_COLOR_PAR, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,126,257,10 + LTEXT "",IDC_STATIC,17,75,43,8 + LTEXT "",IDC_STATIC,17,104,34,8 + LTEXT " ",IDC_STATIC,17,89,83,8 + LTEXT " ",IDC_STATIC,106,62,45,8 + LTEXT "",IDC_STATIC,164,62,38,8 + LTEXT "",IDC_STATIC,214,62,46,8 + CONTROL " ( )",IXTRC_SA_AST, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,140,173,10 + CONTROL " -",IXTRC_SA_RSNAVIGATOR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,157,119,10 +END + +IXTRD_GENERATE_FUNC DIALOGEX 0, 0, 477, 294 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION " -" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + COMBOBOX IXTRC_TERM_CB,4,2,56,276,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "",IXTRC_GLOBAL_LIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,5,79,223,88 + DEFPUSHBUTTON ">>>",IXTRC_RIGHT,229,79,21,43 + DEFPUSHBUTTON "<<<",IXTRC_LEFT,229,121,21,43 + CONTROL "List1",IXTRC_ARG_LIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,251,79,223,88 + DEFPUSHBUTTON "",IXTRC_UPDATE_EXP,117,172,54,11 + CONTROL "",IXTRC_EXPR_OUTPUT,"RichEdit20W",WS_BORDER | WS_VSCROLL | WS_TABSTOP | 0x44,5,184,469,41 + CONTROL "",IXTRC_INTER,"RichEdit20W",WS_BORDER | WS_VSCROLL | WS_TABSTOP | 0x44,5,239,469,31 + DEFPUSHBUTTON " ",IXTRC_ADDFUNC,39,275,94,14 + DEFPUSHBUTTON " ",IDOK,190,275,94,14 + PUSHBUTTON "",IDCANCEL,341,275,94,14 + LTEXT " ",IDC_STATIC,5,68,209,8 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,5,170,469,1 + CONTROL "",IXTRC_EXPR_INPUT,"RichEdit20W",WS_BORDER | WS_VSCROLL | 0x44,3,16,469,45 + LTEXT " ",IDC_STATIC,70,5,231,8 + LTEXT " -",IDC_STATIC,5,174,106,8 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,5,66,465,1 + LTEXT " -",IDC_STATIC,5,228,304,8 + LTEXT " ",IDC_STATIC,265,68,209,8 +END + +IXTRD_NEW_TRSDOC DIALOGEX 0, 0, 307, 81 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION " " +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + COMBOBOX IXTRC_RS_TITLE,14,21,280,56,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT " :",IDC_STATIC,14,41,50,8 + COMBOBOX IXTRC_RS_ALIAS,71,39,63,50,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "OK",IDOK,48,62,50,14,WS_DISABLED + PUSHBUTTON "",IDCANCEL,210,62,50,14 + GROUPBOX "",IDC_STATIC,7,7,293,51 +END + +IXTRD_GENERATE_TERM DIALOGEX 0, 0, 477, 294 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION " " +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + COMBOBOX IXTRC_FUNC_CB,4,2,56,276,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "",IXTRC_EXPR_INPUT,"RichEdit20W",WS_BORDER | WS_VSCROLL | 0x844,4,16,469,45 + CONTROL "",IXTRC_GLOBAL_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,5,79,209,85 + DEFPUSHBUTTON "<<<",IXTRC_LEFT,215,79,17,85 + CONTROL "List1",IXTRC_ARG_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,233,79,241,85 + CONTROL "",IXTRC_EXPR_OUTPUT,"RichEdit20W",WS_BORDER | WS_VSCROLL | WS_TABSTOP | 0x44,4,184,469,41 + LTEXT " ",IDC_STATIC,5,174,106,8 + CONTROL "",IXTRC_INTER,"RichEdit20W",WS_BORDER | WS_VSCROLL | WS_TABSTOP | 0x44,4,239,469,31 + DEFPUSHBUTTON " ",IXTRC_APPLY,39,275,94,14 + DEFPUSHBUTTON " ",IDOK,186,275,94,14 + PUSHBUTTON "",IDCANCEL,333,275,94,14 + LTEXT " ",IDC_STATIC,5,68,209,8 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,4,170,469,1 + LTEXT " -",IDC_STATIC,70,5,231,8 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,4,66,469,1 + LTEXT " ",IDC_STATIC,5,228,304,8 + DEFPUSHBUTTON "",IXTRC_UPDATE_EXP,72,172,54,11 + LTEXT " ",IDC_STATIC,233,68,209,8 + CONTROL " ",IXTRC_FULL_EXPR,"Button",BS_AUTOCHECKBOX,133,172,81,10 +END + +IXTRD_GENERATE_TERM_STRUC DIALOGEX 0, 0, 634, 308 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION " " +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + COMBOBOX IXTRC_TERM_CB,8,9,56,276,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "",IXTRC_EXPR_INPUT,"RichEdit20W",WS_BORDER | WS_VSCROLL | WS_TABSTOP | 0x844,112,9,512,17 + CONTROL "",IXTRC_INTERP,"RichEdit20W",WS_BORDER | WS_VSCROLL | WS_TABSTOP | 0x844,74,31,550,30 + CONTROL "",IXTRC_GLOBAL_LIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,10,80,226,204 + DEFPUSHBUTTON ">>>",IXTRC_RIGHT,236,80,16,91 + DEFPUSHBUTTON "<<<",IXTRC_LEFT,236,192,16,91 + CONTROL "List1",IXTRC_ARG_LIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,253,80,372,204 + DEFPUSHBUTTON " ",IDOK,390,289,106,14 + PUSHBUTTON "",IDCANCEL,530,289,94,14 + CTEXT " ",IDC_STATIC,10,70,228,8 + LTEXT ":",IDC_STATIC,69,12,40,8 + CTEXT " ",IDC_STATIC,253,70,372,8 + DEFPUSHBUTTON " ",IXTRC_APPLY,262,289,94,14 + CONTROL " ",IXTRC_SHORTEXPR,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED,10,289,87,10 + CONTROL " ",IXTRC_CONTROL_STRUC,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED,109,289,87,10 + LTEXT ":",IDC_STATIC,14,44,48,8 + GROUPBOX " ",IDC_STATIC,4,0,626,68,BS_CENTER +END + +IXTRD_EDIT_TERM DIALOGEX 0, 0, 316, 81 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION " " +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IXTRC_INTER,"RichEdit20W",WS_BORDER | WS_VSCROLL | WS_TABSTOP | 0x44,2,6,310,53 + DEFPUSHBUTTON "",IDOK,57,63,50,14 + PUSHBUTTON "",IDCANCEL,215,63,50,14 +END + +IXTRD_OPTION_MODEL DIALOGEX 0, 0, 287, 222 +STYLE DS_SETFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + CONTROL " : / ID",IXTRC_DATAMODE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,253,10 +END + +IXTRD_OPTION_APPLICATION DIALOGEX 0, 0, 287, 222 +STYLE DS_SETFONT | WS_CHILD | WS_DISABLED | WS_CAPTION +CAPTION "" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + CONTROL " ",IXTRC_FILE_VERSION_PROMT, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,203,10 + CONTROL " ",IXTRC_START_PAGE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,20,203,10 + EDITTEXT IXTRC_PYTHONPATH,64,93,214,14,ES_AUTOHSCROLL + CONTROL " ",IXTRC_LOAD_PYTHON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,33,203,10 + LTEXT " Python",IDC_STATIC,7,95,53,8 + CONTROL " ",IXTRC_DISABLE_AUTOLANG, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,46,207,10 + LTEXT "! Python ",IDC_STATIC,7,111,271,8 +END + +IXTRD_CST_EDIT_MODEL DIALOGEX 0, 0, 553, 369 +STYLE DS_SETFONT | WS_DISABLED | WS_CAPTION | WS_SYSMENU +CAPTION "" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + CONTROL "",IXTRC_DATA_TABLE,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,5,57,544,306,WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE + COMBOBOX IXTRC_NAME_CB,5,1,56,276,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "",IXTRC_TYPIFICATION,"RichEdit20W",WS_BORDER | WS_VSCROLL | WS_TABSTOP | 0x844,71,3,317,18 + CONTROL "",IXTRC_INTERPRETATION,"RichEdit20W",WS_BORDER | WS_VSCROLL | WS_TABSTOP | 0x844,71,25,317,28 + CONTROL " ",IXTRC_FILL_INTERP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,397,8,147,10 + COMBOBOX IXTRC_EDIT_DATA,505,5,48,114,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL + PUSHBUTTON "",IXTRC_EXPORT_DATA,411,28,53,20 + PUSHBUTTON "",IXTRC_IMPORT_CSTDATA,477,28,53,21 + PUSHBUTTON "&<<",IXTRC_PREV,5,14,27,16,NOT WS_TABSTOP + PUSHBUTTON "&>>",IXTRC_NEXT,34,14,27,16,NOT WS_TABSTOP + PUSHBUTTON "",IXTRC_ERASE_DATA,6,34,53,20 +END + +IXTRD_EDIT_FILENAME DIALOGEX 0, 0, 267, 69 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION " " +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + EDITTEXT IXTRC_FILENAME,6,9,254,37,ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL + DEFPUSHBUTTON "",IDOK,27,48,50,14 + PUSHBUTTON "",IDCANCEL,159,48,50,14 +END + +IXTRD_EDIT_HYPERLINK DIALOGEX 0, 0, 276, 75 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION " " +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + EDITTEXT IXTRC_ADDRESS,6,19,260,12,ES_AUTOHSCROLL + PUSHBUTTON " ...",IXTRC_BROWSE,211,2,55,14 + EDITTEXT IXTRC_SUBADDRESS,57,34,209,12,ES_AUTOHSCROLL + DEFPUSHBUTTON "OK",IDOK,21,54,50,14 + PUSHBUTTON "",IDCANCEL,189,54,50,14 + LTEXT " URL:",IDC_STATIC,7,7,40,8 + LTEXT "",IDC_STATIC,6,36,42,8 +END + +IXTRD_NEW_FILE DIALOGEX 0, 0, 167, 135 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION " " +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "- ",IXTRC_RSFORM,"MfcButton",WS_TABSTOP,7,7,154,26 + CONTROL " -",IXTRC_RSMODEL,"MfcButton",WS_TABSTOP,7,39,154,26 + CONTROL " ",IXTRC_OSS,"MfcButton",WS_TABSTOP,7,71,154,26 + PUSHBUTTON "",IDCANCEL,7,103,154,23 +END + +IXTRD_START_PAGE DIALOGEX 0, 0, 455, 236 +STYLE DS_ABSALIGN | DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION " " +FONT 8, "MS Shell Dlg", 400, 0, 0xCC +BEGIN + CONTROL "",IXTRC_NEW_DOCUMENT,"MfcButton",WS_TABSTOP,13,17,50,35,WS_EX_DLGMODALFRAME + CONTROL "",IXTRC_OPEN_DOC,"MfcButton",WS_TABSTOP,107,17,50,35,WS_EX_DLGMODALFRAME + CONTROL "",IXTRC_SAMPLES,"MfcButton",WS_TABSTOP,295,17,50,35,WS_EX_DLGMODALFRAME + CONTROL "",IXTRC_START_HELP,"MfcButton",WS_TABSTOP,389,17,50,35,WS_EX_DLGMODALFRAME + CONTROL " ",IXTRC_DONT_PROMT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,336,225,115,10 + CTEXT " ",IDC_STATIC,182,79,84,9 + CTEXT " ",IDC_STATIC,13,55,50,17 + CTEXT "",IDC_STATIC,389,55,50,9 + CTEXT " ",IDC_STATIC,107,55,50,17 + CONTROL " 1994-2023",IXTRC_MFCLINK1,"MfcLink",WS_TABSTOP,9,224,124,12 + GROUPBOX " ",IDC_STATIC,6,5,447,74,BS_CENTER + CTEXT "",IDC_STATIC,295,55,50,9 + CONTROL "",IXTRC_CHANGE_LOG,"RichEdit20W",WS_BORDER | WS_VSCROLL | WS_TABSTOP | 0x844,8,90,437,131 + CONTROL "",IXTRC_MEMO,"MfcButton",WS_TABSTOP,201,17,50,35,WS_EX_DLGMODALFRAME + CTEXT "",IDC_STATIC,201,55,50,9 +END + +IXTRD_AUTOCOMPLETE DIALOGEX 50, 40, 124, 44 +STYLE DS_SETFONT | WS_POPUP +FONT 8, "Arial", 400, 0, 0xCC +BEGIN + LISTBOX IXTRC_AC_LIST1,41,0,41,44,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + LISTBOX IXTRC_AC_LIST2,0,0,41,44,LBS_NOINTEGRALHEIGHT | NOT WS_VISIBLE | WS_TABSTOP + LISTBOX IXTRC_AC_LABELSLIST,81,0,41,44,LBS_NOINTEGRALHEIGHT | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP +END + +IXTRD_CST_CHANGE_TERM_FORM DIALOGEX 50, 40, 40, 12 +STYLE DS_SETFONT | WS_POPUP +FONT 8, "Arial", 400, 0, 0xCC +BEGIN + EDITTEXT IXTRC_CST_TERM_FORM_EDIT,0,0,40,12,ES_AUTOHSCROLL +END + +IXTRD_CST_SET_CHANGING_WORD_TEXT DIALOGEX 50, 40, 40, 12 +STYLE DS_SETFONT | WS_POPUP | WS_BORDER +FONT 8, "Arial", 400, 0, 0xCC +BEGIN + EDITTEXT IXTRC_SET_WORDREF_EDIT,0,0,40,12,ES_AUTOHSCROLL | NOT WS_BORDER +END + +IXTRD_CST_SET_CHANGING_WORD_REF DIALOGEX 50, 40, 40, 12 +STYLE DS_SETFONT | WS_POPUP | WS_BORDER +FONT 8, "Arial", 400, 0, 0xCC +BEGIN + CTEXT "<- ->",IXTRC_WORDREF_CONTROL,0,0,40,12 +END + +IXTRD_WORKSHEET DIALOGEX 0, 0, 157, 174 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION " " +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,7,143,72,24 + PUSHBUTTON "Cancel",IDCANCEL,79,143,72,24 + LISTBOX IXTRC_WSLIST,7,7,143,135,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP +END + +IXTRD_EXPORT_CSTGRAPH DIALOGEX 0, 0, 127, 118 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION " " +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL " ",IXTRC_TRIPLET_CB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,69,96,10 + CONTROL " ",IXTRC_FORMULA,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,8,18,98,10 + CONTROL "",IXTRC_LINK_TERM,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,30,40,10 + GROUPBOX " ",-1,7,7,101,61 + CONTROL " ",IXTRC_LINK_DEFINITION,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,42,82,10 + CONTROL " ",IXTRC_LINK_ALL,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,8,54,48,10 + CONTROL " CSV",IXTRC_EXPORT_CSV_CB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,83,96,10 + DEFPUSHBUTTON "OK",IDOK,7,97,50,14 + PUSHBUTTON "",IDCANCEL,63,97,50,14 +END + +IXTRD_EXPORT_MODEL DIALOGEX 0, 0, 131, 90 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL " Excel",IXTRC_FILE_XLSX,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,15,21,97,10 + CONTROL " JSON",IXTRC_FILE_JSON,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,15,38,97,10 + DEFPUSHBUTTON "OK",1,7,69,50,14 + PUSHBUTTON "",IDCANCEL,67,69,50,14 + GROUPBOX " ",-1,7,7,114,58 +END + +IXTRD_VIEW_RSMODEL DIALOGEX 0, 0, 542, 193 +STYLE DS_ABSALIGN | DS_SETFONT | WS_CHILD +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + CONTROL "Generic2",IXTRC_RSFORM_LIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,2,47,537,142,WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE + EDITTEXT IXTRC_TITLE,58,9,188,15,ES_AUTOHSCROLL + EDITTEXT IXTRC_ALIAS,58,27,119,15,ES_AUTOHSCROLL + PUSHBUTTON " ",IXTRC_TRS_UPDATE_STATUS,251,25,55,14,BS_CENTER + PUSHBUTTON " ",IXTRC_MODEL_CALCULATE,311,25,75,14,BS_CENTER + PUSHBUTTON "",IXTRC_COMMENT_B,186,27,60,14,BS_CENTER + LTEXT ":",-1,3,11,50,8 + LTEXT ":",-1,3,30,52,8 + CONTROL "",IXTRC_RSFORM_STATUS,"RichEdit20W",0x881,251,9,55,13 + GROUPBOX " - ",IXTRC_STATIC_BORDER,2,0,530,44 + CONTROL "",IXTRC_MODEL_STATUS,"RichEdit20W",0x881,311,9,74,13 + EDITTEXT IXTRC_RSMODEL_SEARCH_TEXT,388,9,141,15,ES_AUTOHSCROLL + PUSHBUTTON "",IXTRC_MODEL_SEARCH,388,25,141,14,BS_CENTER +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 4,9,2,1000 + PRODUCTVERSION 4,9,2,1000 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "041904b0" + BEGIN + VALUE "Comments", " " + VALUE "CompanyName", " " + VALUE "FileDescription", " 4.9" + VALUE "FileVersion", "4.9.2.1000" + VALUE "InternalName", " 4.9" + VALUE "LegalCopyright", "Copyright NPMP CIHT CONCEPT 1994-2024" + VALUE "LegalTrademarks", "" + VALUE "OriginalFilename", "Exteor.exe" + VALUE "ProductName", " 4.9" + VALUE "ProductVersion", "4.9.2.1000" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x419, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IXTRD_ABOUTBOX, DIALOG + BEGIN + RIGHTMARGIN, 164 + BOTTOMMARGIN, 90 + END + + IXTRD_VIEW_RSFORM, DIALOG + BEGIN + RIGHTMARGIN, 444 + BOTTOMMARGIN, 124 + END + + IXTRD_CST_EDIT_DATA, DIALOG + BEGIN + LEFTMARGIN, 4 + RIGHTMARGIN, 544 + TOPMARGIN, 6 + BOTTOMMARGIN, 379 + END + + IXTRD_VIEW_TERMTREE, DIALOG + BEGIN + LEFTMARGIN, 3 + RIGHTMARGIN, 105 + BOTTOMMARGIN, 142 + END + + IXTRD_EDIT_COMMENT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 339 + TOPMARGIN, 7 + BOTTOMMARGIN, 170 + END + + IXTRD_CST_RENAME, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 139 + TOPMARGIN, 7 + BOTTOMMARGIN, 74 + END + + IXTRD_NEW_OSSDOC, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 336 + TOPMARGIN, 7 + BOTTOMMARGIN, 80 + END + + IXTRD_VIEW_PICT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 232 + TOPMARGIN, 7 + BOTTOMMARGIN, 375 + END + + IXTRD_OPTION_OSS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 279 + TOPMARGIN, 7 + BOTTOMMARGIN, 207 + END + + IXTRD_OSS_OPERATIONS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 212 + TOPMARGIN, 7 + BOTTOMMARGIN, 122 + END + + IXTRD_EXPORT_SCHEMA, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 125 + TOPMARGIN, 7 + BOTTOMMARGIN, 164 + END + + IXTRD_SYNT_OPERANDS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 449 + TOPMARGIN, 7 + BOTTOMMARGIN, 224 + END + + IXTRD_SYNT_MAPTABLE, DIALOG + BEGIN + VERTGUIDE, 20 + END + + IXTRD_SYNT_NAMES, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 443 + TOPMARGIN, 7 + BOTTOMMARGIN, 222 + END + + IXTRD_OPTION_ANALYZER, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 280 + TOPMARGIN, 6 + BOTTOMMARGIN, 214 + END + + IXTRD_GENERATE_FUNC, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 470 + TOPMARGIN, 7 + BOTTOMMARGIN, 287 + END + + IXTRD_NEW_TRSDOC, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 139 + TOPMARGIN, 7 + BOTTOMMARGIN, 34 + END + + IXTRD_GENERATE_TERM, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 470 + TOPMARGIN, 7 + BOTTOMMARGIN, 287 + END + + IXTRD_GENERATE_TERM_STRUC, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 627 + TOPMARGIN, 7 + BOTTOMMARGIN, 301 + END + + IXTRD_EDIT_TERM, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 309 + TOPMARGIN, 7 + BOTTOMMARGIN, 74 + END + + IXTRD_OPTION_MODEL, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 274 + TOPMARGIN, 7 + BOTTOMMARGIN, 212 + END + + IXTRD_OPTION_APPLICATION, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 278 + TOPMARGIN, 7 + BOTTOMMARGIN, 208 + END + + IXTRD_CST_EDIT_MODEL, DIALOG + BEGIN + RIGHTMARGIN, 548 + VERTGUIDE, 144 + TOPMARGIN, 1 + BOTTOMMARGIN, 272 + END + + IXTRD_EDIT_FILENAME, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 260 + TOPMARGIN, 7 + BOTTOMMARGIN, 62 + END + + IXTRD_EDIT_HYPERLINK, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 269 + TOPMARGIN, 7 + BOTTOMMARGIN, 68 + END + + IXTRD_NEW_FILE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 161 + TOPMARGIN, 7 + BOTTOMMARGIN, 128 + END + + IXTRD_START_PAGE, DIALOG + BEGIN + RIGHTMARGIN, 454 + BOTTOMMARGIN, 228 + END + + IXTRD_AUTOCOMPLETE, DIALOG + BEGIN + RIGHTMARGIN, 77 + END + + IXTRD_CST_CHANGE_TERM_FORM, DIALOG + BEGIN + END + + IXTRD_CST_SET_CHANGING_WORD_TEXT, DIALOG + BEGIN + END + + IXTRD_CST_SET_CHANGING_WORD_REF, DIALOG + BEGIN + END + + IXTRD_WORKSHEET, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 150 + TOPMARGIN, 7 + BOTTOMMARGIN, 167 + END + + IXTRD_EXPORT_CSTGRAPH, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 120 + TOPMARGIN, 7 + BOTTOMMARGIN, 111 + END + + IXTRD_EXPORT_MODEL, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 125 + TOPMARGIN, 7 + BOTTOMMARGIN, 83 + END + + IXTRD_VIEW_RSMODEL, DIALOG + BEGIN + RIGHTMARGIN, 539 + BOTTOMMARGIN, 124 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Cursor +// + +IXTRR_CREATE_OPERATION CURSOR "..\\resource\\CREATE_OPERATION.CUR" + +IXTRR_HYPERLINK CURSOR "..\\resource\\HYPERLINK.CUR" + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog Info +// + +IXTRD_NEW_FILE DLGINIT +BEGIN + IXTRC_RSFORM, 0x37c, 458, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x343e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x4d2f, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, +0x543e, 0x5552, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, +0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, 0x3e65, 0x3231, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, +0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x5465, 0x7079, 0x3e65, 0x3c39, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, 0x3c33, 0x4d2f, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, 0x3c3e, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x3e65, 0x4449, +0x5f52, 0x454d, 0x554e, 0x525f, 0x4653, 0x524f, 0x3c4d, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x463e, +0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x4f65, 0x546e, 0x706f, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, 0x543e, 0x5552, +0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, +0x6e4f, 0x6952, 0x6867, 0x3e74, + IXTRC_RSMODEL, 0x37c, 459, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x343e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x4d2f, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, +0x543e, 0x5552, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, +0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, 0x3e65, 0x3231, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, +0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x5465, 0x7079, 0x3e65, 0x3c39, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, 0x3c35, 0x4d2f, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, 0x3c3e, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x3e65, 0x4449, +0x5f52, 0x454d, 0x554e, 0x525f, 0x4d53, 0x444f, 0x4c45, 0x2f3c, 0x464d, +0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x3e65, 0x4d3c, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, +0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, 0x5254, +0x4555, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x4f65, 0x526e, 0x6769, 0x7468, "\076" + IXTRC_OSS, 0x37c, 455, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x343e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x4d2f, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, +0x543e, 0x5552, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, +0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, 0x3e65, 0x3231, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, +0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x5465, 0x7079, 0x3e65, 0x3c39, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, 0x3c36, 0x4d2f, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, 0x3c3e, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x3e65, 0x4449, +0x5f52, 0x454d, 0x554e, 0x4f5f, 0x5353, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4146, 0x534c, +0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, +0x6e4f, 0x6f54, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, 0x5254, 0x4555, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, +0x6769, 0x7468, "\076" + 0 +END + +IXTRD_START_PAGE DLGINIT +BEGIN + IXTRC_NEW_DOCUMENT, 0x37c, 457, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x353e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x4d2f, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, +0x543e, 0x5552, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, +0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, 0x3e65, 0x3231, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, +0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x5465, 0x7079, 0x3e65, 0x3c39, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, 0x3432, 0x3c39, +0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, +0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x3e65, +0x4449, 0x5f49, 0x454e, 0x5f57, 0x4f44, 0x3c43, 0x4d2f, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x3c3e, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x463e, 0x4c41, +0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x4f65, 0x546e, 0x706f, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, +0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, 0x463e, 0x4c41, 0x4553, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, +0x526e, 0x6769, 0x7468, "\076" + IXTRC_OPEN_DOC, 0x37c, 458, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x353e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x4d2f, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, +0x543e, 0x5552, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, +0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, 0x3e65, 0x3231, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, +0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x5465, 0x7079, 0x3e65, 0x3c39, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, 0x3532, 0x3c31, +0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, +0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x3e65, +0x4449, 0x5f49, 0x504f, 0x4e45, 0x445f, 0x434f, 0x2f3c, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x3e65, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4146, +0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, 0x4146, 0x534c, +0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, +0x6e4f, 0x6952, 0x6867, 0x3e74, + IXTRC_SAMPLES, 0x37c, 457, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x353e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x4d2f, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, +0x543e, 0x5552, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, +0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, 0x3e65, 0x3231, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, +0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x5465, 0x7079, 0x3e65, 0x3c39, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, 0x3532, 0x3c32, +0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, +0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x3e65, +0x4449, 0x5f49, 0x4153, 0x504d, 0x454c, 0x3c53, 0x4d2f, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x3c3e, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x463e, 0x4c41, +0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x4f65, 0x546e, 0x706f, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, +0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, 0x463e, 0x4c41, 0x4553, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, +0x526e, 0x6769, 0x7468, "\076" + IXTRC_START_HELP, 0x37c, 454, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x353e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x4d2f, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, +0x543e, 0x5552, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, +0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, 0x3e65, 0x3231, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, +0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x5465, 0x7079, 0x3e65, 0x3c39, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, 0x3532, 0x3c30, +0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, +0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x3e65, +0x4449, 0x5f49, 0x4548, 0x504c, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4146, 0x534c, 0x3c45, +0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, +0x6f54, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, 0x4146, 0x534c, 0x3c45, 0x4d2f, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, +0x6867, 0x3e74, + IXTRC_MFCLINK1, 0x37c, 209, 0 +0x4d3c, 0x4346, 0x694c, 0x6b6e, 0x555f, 0x6c72, 0x683e, 0x7474, 0x3a70, +0x2f2f, 0x7777, 0x2e77, 0x6361, 0x6f63, 0x636e, 0x7065, 0x2e74, 0x7572, +0x3c2f, 0x4d2f, 0x4346, 0x694c, 0x6b6e, 0x555f, 0x6c72, 0x3c3e, 0x464d, +0x4c43, 0x6e69, 0x5f6b, 0x7255, 0x506c, 0x6572, 0x6966, 0x3e78, 0x2f3c, +0x464d, 0x4c43, 0x6e69, 0x5f6b, 0x7255, 0x506c, 0x6572, 0x6966, 0x3e78, +0x4d3c, 0x4346, 0x694c, 0x6b6e, 0x545f, 0x6f6f, 0x746c, 0x7069, 0xd03e, +0xd09d, 0x209f, 0xa6d0, 0x98d0, 0x92d0, 0xa2d0, 0xd020, 0xd09a, 0xd09e, +0xd09d, 0xd0a6, 0xd095, 0xd09f, 0x3ca2, 0x4d2f, 0x4346, 0x694c, 0x6b6e, +0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x464d, 0x4c43, 0x6e69, 0x5f6b, +0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, 0x6974, 0x3e70, 0x4146, +0x534c, 0x3c45, 0x4d2f, 0x4346, 0x694c, 0x6b6e, 0x465f, 0x6c75, 0x546c, +0x7865, 0x5474, 0x6f6f, 0x746c, 0x7069, "\076" + IXTRC_MEMO, 0x37c, 462, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x353e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x4d2f, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, +0x543e, 0x5552, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, +0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, 0x3e65, 0x3231, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, +0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x5465, 0x7079, 0x3e65, 0x3c39, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, 0x3c32, 0x4d2f, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, 0x3c3e, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x3e65, 0x4449, +0x5f52, 0x454d, 0x554e, 0x4d5f, 0x4941, 0x464e, 0x4152, 0x454d, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x3e65, 0x4d3c, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, +0x3e70, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, +0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, + 0 +END + +IXTRD_CST_EDIT_DATA DLGINIT +BEGIN + IXTRC_BOOLEAN, 0x37c, 472, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x4520, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, +0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, +0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, +0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, +0x5472, 0x7079, 0x3e65, 0x3231, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3031, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, +0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x4449, 0x323e, 0x3931, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x493e, 0x5458, 0x5252, 0x425f, 0x4e54, +0x425f, 0x4f4f, 0x454c, 0x4e41, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4146, 0x534c, 0x3c45, +0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, +0x6f54, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, 0x4146, 0x534c, 0x3c45, 0x4d2f, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, +0x6867, 0x3e74, + IXTRC_CARTPROD, 0x37c, 491, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x533e, 0x6968, 0x7466, 0x2b20, +0x3820, 0x2f20, 0x4120, 0x746c, 0x2b20, 0x5320, 0x6968, 0x7466, 0x2b20, +0x4520, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, +0x6974, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, +0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, +0x6f6f, 0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, +0x6f73, 0x5472, 0x7079, 0x3e65, 0x3231, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, +0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, +0x3031, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x5465, 0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x4449, 0x313e, 0x3433, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x493e, 0x5458, 0x5252, 0x425f, +0x4e54, 0x445f, 0x4345, 0x5241, 0x3c54, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x463e, 0x4c41, 0x4553, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, +0x546e, 0x706f, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, 0x463e, 0x4c41, 0x4553, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, +0x6769, 0x7468, "\076" + IXTRC_DOUBLEPAR, 0x37c, 524, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0xd03e, 0xd0a1, 0xd1be, 0xd087, +0xd1b5, 0xd082, 0xd0b0, 0xd0bd, 0xd0b8, 0x20b5, 0xbad0, 0xbbd0, 0xb0d0, +0xb2d0, 0xb8d0, 0x88d1, 0xd020, 0xd0bd, 0x20b5, 0xbed0, 0xbfd0, 0x80d1, +0xb5d0, 0xb4d0, 0xb5d0, 0xbbd0, 0xb5d0, 0xbdd0, 0xbed0, 0x2f3c, 0x464d, +0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, 0x3e70, 0x4d3c, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, +0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, +0x3e65, 0x3231, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, +0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3031, 0x2f3c, 0x464d, +0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, +0x323e, 0x3434, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x4965, 0x3e44, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x493e, 0x5458, 0x5252, 0x425f, 0x4e54, 0x445f, 0x554f, +0x4c42, 0x5045, 0x5241, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, +0x6d49, 0x6761, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4146, 0x534c, 0x3c45, 0x4d2f, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, +0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, +0x6e4f, 0x6952, 0x6867, 0x3e74, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, +0x3e74, + IXTRC_DOUBLESQR, 0x37c, 524, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0xd03e, 0xd0a1, 0xd1be, 0xd087, +0xd1b5, 0xd082, 0xd0b0, 0xd0bd, 0xd0b8, 0x20b5, 0xbad0, 0xbbd0, 0xb0d0, +0xb2d0, 0xb8d0, 0x88d1, 0xd020, 0xd0bd, 0x20b5, 0xbed0, 0xbfd0, 0x80d1, +0xb5d0, 0xb4d0, 0xb5d0, 0xbbd0, 0xb5d0, 0xbdd0, 0xbed0, 0x2f3c, 0x464d, +0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, 0x3e70, 0x4d3c, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, +0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, +0x3e65, 0x3231, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, +0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3031, 0x2f3c, 0x464d, +0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, +0x323e, 0x3036, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x4965, 0x3e44, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x493e, 0x5458, 0x5252, 0x425f, 0x4e54, 0x445f, 0x554f, +0x4c42, 0x5345, 0x5251, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, +0x6d49, 0x6761, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4146, 0x534c, 0x3c45, 0x4d2f, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, +0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, +0x6e4f, 0x6952, 0x6867, 0x3e74, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, +0x3e74, + IXTRC_QUANTUNIVERSAL, 0x37c, 471, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x603e, 0x2f3c, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, 0x3e70, 0x4d3c, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, +0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, 0x3e65, +0x3231, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, +0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, +0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3031, 0x2f3c, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x4d3c, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, 0x323e, +0x3033, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x4965, 0x3e44, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x493e, 0x5458, 0x5252, 0x425f, 0x4e54, 0x4c5f, 0x474f, 0x4349, +0x465f, 0x524f, 0x4c41, 0x3c4c, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x495f, 0x616d, 0x6567, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, +0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x463e, 0x4c41, 0x4553, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, +0x706f, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x4f65, 0x526e, 0x6769, 0x7468, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, +0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, +0x7468, "\076" + IXTRC_QUANTEXIST, 0x37c, 479, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x533e, 0x6968, 0x7466, 0x2b20, +0x6020, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, +0x6974, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, +0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, +0x6f6f, 0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, +0x6f73, 0x5472, 0x7079, 0x3e65, 0x3231, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, +0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, +0x3031, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x5465, 0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x4449, 0x323e, 0x3932, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x493e, 0x5458, 0x5252, 0x425f, +0x4e54, 0x4c5f, 0x474f, 0x4349, 0x455f, 0x4958, 0x5453, 0x3c53, 0x4d2f, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x3c3e, 0x464d, +0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, +0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, +0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x3c3e, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, 0x463e, +0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, "\076" + IXTRC_NEGATION, 0x37c, 476, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x2220, +0x222d, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, +0x6974, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, +0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, +0x6f6f, 0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, +0x6f73, 0x5472, 0x7079, 0x3e65, 0x3231, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, +0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, +0x3031, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x5465, 0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x4449, 0x323e, 0x3032, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x493e, 0x5458, 0x5252, 0x425f, +0x4e54, 0x4c5f, 0x474f, 0x4349, 0x4e5f, 0x544f, 0x2f3c, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x3e65, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4146, +0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, 0x4146, 0x534c, +0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, +0x6e4f, 0x6952, 0x6867, 0x3e74, + IXTRC_OR, 0x37c, 481, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x5320, +0x6968, 0x7466, 0x2b20, 0x3320, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6f54, 0x6c6f, 0x6974, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, +0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, +0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, 0x3e65, 0x3231, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, +0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x5465, 0x7079, 0x3e65, 0x3031, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, 0x323e, 0x3332, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x493e, +0x5458, 0x5252, 0x425f, 0x4e54, 0x4c5f, 0x474f, 0x4349, 0x4f5f, 0x3c52, +0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x3c3e, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, +0x706f, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, +0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, +0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, "\076" + IXTRC_LOGIC_AND, 0x37c, 474, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x3320, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, +0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, +0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, +0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, +0x5472, 0x7079, 0x3e65, 0x3231, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3031, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, +0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x4449, 0x323e, 0x3533, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x493e, 0x5458, 0x5252, 0x425f, 0x4e54, +0x4c5f, 0x474f, 0x4349, 0x415f, 0x444e, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4146, 0x534c, +0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, +0x6e4f, 0x6f54, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, 0x4146, 0x534c, 0x3c45, +0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, +0x6952, 0x6867, 0x3e74, + IXTRC_IMPLICATION, 0x37c, 479, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x3420, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, +0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, +0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, +0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, +0x5472, 0x7079, 0x3e65, 0x3231, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3031, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, +0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x4449, 0x323e, 0x3532, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x493e, 0x5458, 0x5252, 0x425f, 0x4e54, +0x4c5f, 0x474f, 0x4349, 0x495f, 0x504d, 0x494c, 0x4143, 0x3c54, 0x4d2f, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x3c3e, 0x464d, +0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, +0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, +0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x3c3e, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, 0x463e, +0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, "\076" + IXTRC_LOGIC_EQUAL, 0x37c, 484, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x5320, +0x6968, 0x7466, 0x2b20, 0x3420, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6f54, 0x6c6f, 0x6974, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, +0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, +0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, 0x3e65, 0x3231, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, +0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x5465, 0x7079, 0x3e65, 0x3031, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, 0x323e, 0x3433, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x493e, +0x5458, 0x5252, 0x425f, 0x4e54, 0x4c5f, 0x474f, 0x4349, 0x455f, 0x5551, +0x4c41, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, +0x6e4f, 0x6f54, 0x3e70, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4d3c, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, +0x6867, 0x3e74, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, + IXTRC_NULLSET, 0x37c, 473, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x5820, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, +0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, +0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, +0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, +0x5472, 0x7079, 0x3e65, 0x3231, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3031, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, +0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x4449, 0x323e, 0x3732, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x493e, 0x5458, 0x5252, 0x425f, 0x4e54, +0x455f, 0x504d, 0x5954, 0x4553, 0x3c54, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x463e, 0x4c41, 0x4553, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, +0x546e, 0x706f, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, 0x463e, 0x4c41, 0x4553, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, +0x6769, 0x7468, "\076" + IXTRC_EQUAL, 0x37c, 464, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3d3e, 0x2f3c, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, 0x3e70, 0x4d3c, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, +0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, 0x3e65, +0x3231, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, +0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, +0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3031, 0x2f3c, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x4d3c, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, 0x323e, +0x3733, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x4965, 0x3e44, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x493e, 0x5458, 0x5252, 0x425f, 0x4e54, 0x455f, 0x5551, 0x4c41, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, +0x6f54, 0x3e70, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4d3c, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, +0x3e74, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, + IXTRC_INEQ, 0x37c, 481, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x5320, +0x6968, 0x7466, 0x2b20, 0x3d20, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6f54, 0x6c6f, 0x6974, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, +0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, +0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, 0x3e65, 0x3231, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, +0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x5465, 0x7079, 0x3e65, 0x3031, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, 0x323e, 0x3632, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x493e, +0x5458, 0x5252, 0x425f, 0x4e54, 0x4e5f, 0x544f, 0x5145, 0x4155, 0x3c4c, +0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x3c3e, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, +0x706f, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, +0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, +0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, "\076" + IXTRC_GREATER_OR_EQ, 0x37c, 528, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0xd03e, 0xd0a1, 0xd1be, 0xd087, +0xd1b5, 0xd082, 0xd0b0, 0xd0bd, 0xd0b8, 0x20b5, 0xbad0, 0xbbd0, 0xb0d0, +0xb2d0, 0xb8d0, 0x88d1, 0xd020, 0xd0bd, 0x20b5, 0xbed0, 0xbfd0, 0x80d1, +0xb5d0, 0xb4d0, 0xb5d0, 0xbbd0, 0xb5d0, 0xbdd0, 0xbed0, 0x2f3c, 0x464d, +0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, 0x3e70, 0x4d3c, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, +0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, +0x3e65, 0x3231, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, +0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3031, 0x2f3c, 0x464d, +0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, +0x323e, 0x3534, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x4965, 0x3e44, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x493e, 0x5458, 0x5252, 0x425f, 0x4e54, 0x475f, 0x4552, +0x5441, 0x5245, 0x4f5f, 0x5f52, 0x5145, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4146, 0x534c, +0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, +0x6e4f, 0x6f54, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, 0x4146, 0x534c, 0x3c45, +0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, +0x6952, 0x6867, 0x3e74, + IXTRC_LESSER_OR_EQ, 0x37c, 527, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0xd03e, 0xd0a1, 0xd1be, 0xd087, +0xd1b5, 0xd082, 0xd0b0, 0xd0bd, 0xd0b8, 0x20b5, 0xbad0, 0xbbd0, 0xb0d0, +0xb2d0, 0xb8d0, 0x88d1, 0xd020, 0xd0bd, 0x20b5, 0xbed0, 0xbfd0, 0x80d1, +0xb5d0, 0xb4d0, 0xb5d0, 0xbbd0, 0xb5d0, 0xbdd0, 0xbed0, 0x2f3c, 0x464d, +0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, 0x3e70, 0x4d3c, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, +0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, +0x3e65, 0x3231, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, +0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3031, 0x2f3c, 0x464d, +0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, +0x323e, 0x3634, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x4965, 0x3e44, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x493e, 0x5458, 0x5252, 0x425f, 0x4e54, 0x4c5f, 0x5345, +0x4553, 0x5f52, 0x524f, 0x455f, 0x3c51, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x463e, 0x4c41, 0x4553, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, +0x546e, 0x706f, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, 0x463e, 0x4c41, 0x4553, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, +0x6769, 0x7468, "\076" + IXTRC_BELONG, 0x37c, 472, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x3120, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, +0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, +0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, +0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, +0x5472, 0x7079, 0x3e65, 0x3231, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3031, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, +0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x4449, 0x323e, 0x3432, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x493e, 0x5458, 0x5252, 0x425f, 0x4e54, +0x455f, 0x454c, 0x454d, 0x544e, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4146, 0x534c, 0x3c45, +0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, +0x6f54, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, 0x4146, 0x534c, 0x3c45, 0x4d2f, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, +0x6867, 0x3e74, + IXTRC_NOTELEMENT, 0x37c, 483, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x5320, +0x6968, 0x7466, 0x2b20, 0x3120, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6f54, 0x6c6f, 0x6974, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, +0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, +0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, 0x3e65, 0x3231, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, +0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x5465, 0x7079, 0x3e65, 0x3031, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, 0x323e, 0x3933, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x493e, +0x5458, 0x5252, 0x425f, 0x4e54, 0x4e5f, 0x544f, 0x4c45, 0x4d45, 0x4e45, +0x3c54, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, +0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, +0x546e, 0x706f, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x3c3e, 0x464d, +0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, +0x7468, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, "\076" + IXTRC_SUBSET, 0x37c, 471, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x3720, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, +0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, +0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, +0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, +0x5472, 0x7079, 0x3e65, 0x3231, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3031, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, +0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x4449, 0x323e, 0x3234, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x493e, 0x5458, 0x5252, 0x425f, 0x4e54, +0x535f, 0x4255, 0x4553, 0x3c54, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x495f, 0x616d, 0x6567, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, +0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x463e, 0x4c41, 0x4553, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, +0x706f, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x4f65, 0x526e, 0x6769, 0x7468, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, +0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, +0x7468, "\076" + IXTRC_NOTSUBSET, 0x37c, 482, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x5320, +0x6968, 0x7466, 0x2b20, 0x3220, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6f54, 0x6c6f, 0x6974, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, +0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, +0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, 0x3e65, 0x3231, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, +0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x5465, 0x7079, 0x3e65, 0x3031, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, 0x323e, 0x3034, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x493e, +0x5458, 0x5252, 0x425f, 0x4e54, 0x4e5f, 0x544f, 0x5553, 0x5342, 0x5445, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, +0x6f54, 0x3e70, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4d3c, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, +0x3e74, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, + IXTRC_SUBSET_OR_EQ, 0x37c, 477, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x3220, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, +0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, +0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, +0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, +0x5472, 0x7079, 0x3e65, 0x3231, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3031, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, +0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x4449, 0x323e, 0x3833, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x493e, 0x5458, 0x5252, 0x425f, 0x4e54, +0x535f, 0x4255, 0x4553, 0x5f54, 0x524f, 0x455f, 0x3c51, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x463e, +0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x4f65, 0x546e, 0x706f, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, 0x463e, 0x4c41, +0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x4f65, 0x526e, 0x6769, 0x7468, "\076" + IXTRC_INTERSECT, 0x37c, 478, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x4120, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, +0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, +0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, +0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, +0x5472, 0x7079, 0x3e65, 0x3231, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3031, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, +0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x4449, 0x323e, 0x3232, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x493e, 0x5458, 0x5252, 0x425f, 0x4e54, +0x535f, 0x5445, 0x495f, 0x544e, 0x5245, 0x4553, 0x5443, 0x2f3c, 0x464d, +0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x3e65, 0x4d3c, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, +0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, 0x4146, +0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, + IXTRC_UNION, 0x37c, 474, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x5320, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, +0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, +0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, +0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, +0x5472, 0x7079, 0x3e65, 0x3231, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3031, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, +0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x4449, 0x323e, 0x3132, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x493e, 0x5458, 0x5252, 0x425f, 0x4e54, +0x535f, 0x5445, 0x555f, 0x494e, 0x4e4f, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4146, 0x534c, +0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, +0x6e4f, 0x6f54, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, 0x4146, 0x534c, 0x3c45, +0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, +0x6952, 0x6867, 0x3e74, + IXTRC_SET_MINUS, 0x37c, 468, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x5c3e, 0x2f3c, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, 0x3e70, 0x4d3c, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, +0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, 0x3e65, +0x3231, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, +0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, +0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3031, 0x2f3c, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x4d3c, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, 0x323e, +0x3134, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x4965, 0x3e44, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x493e, 0x5458, 0x5252, 0x425f, 0x4e54, 0x535f, 0x5445, 0x4d5f, +0x4e49, 0x5355, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, +0x6952, 0x6867, 0x3e74, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, + + IXTRC_SET_SYMMINUS, 0x37c, 481, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x363e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x5320, +0x6968, 0x7466, 0x2b20, 0x3520, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6f54, 0x6c6f, 0x6974, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, +0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, +0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, 0x3e65, 0x3231, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, +0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x5465, 0x7079, 0x3e65, 0x3031, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x4449, 0x323e, 0x3734, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4965, 0x3e44, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x493e, +0x5458, 0x5252, 0x425f, 0x4e54, 0x535f, 0x4d59, 0x494d, 0x554e, 0x3c53, +0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x3c3e, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, +0x706f, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, +0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, +0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, "\076" + IXTRC_PR_L, 0x37c, 377, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x353e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x5120, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, +0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, +0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, +0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, +0x5472, 0x7079, 0x3e65, 0x3131, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3c38, +0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x7954, +0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x4f65, 0x546e, 0x706f, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x3c3e, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, +0x6769, 0x7468, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, "\076" + IXTRC_PR_S, 0x37c, 377, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x353e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x5720, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, +0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, +0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, +0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, +0x5472, 0x7079, 0x3e65, 0x3131, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3c38, +0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x7954, +0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x4f65, 0x546e, 0x706f, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x3c3e, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, +0x6769, 0x7468, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, "\076" + IXTRC_BOOL, 0x37c, 377, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x353e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x4220, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, +0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, +0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, +0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, +0x5472, 0x7079, 0x3e65, 0x3131, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3c38, +0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x7954, +0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x4f65, 0x546e, 0x706f, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x3c3e, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, +0x6769, 0x7468, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, "\076" + IXTRC_DEBOOL, 0x37c, 377, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x353e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x5620, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, +0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, +0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, +0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, +0x5472, 0x7079, 0x3e65, 0x3131, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3c38, +0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x7954, +0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x4f65, 0x546e, 0x706f, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x3c3e, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, +0x6769, 0x7468, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, "\076" + IXTRC_RED, 0x37c, 377, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x353e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x5220, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, +0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, +0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, +0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, +0x5472, 0x7079, 0x3e65, 0x3131, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3c38, +0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x7954, +0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x4f65, 0x546e, 0x706f, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x3c3e, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, +0x6769, 0x7468, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, "\076" + IXTRC_CARD, 0x37c, 377, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x353e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x4320, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, +0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, +0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, +0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, +0x5472, 0x7079, 0x3e65, 0x3131, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3c38, +0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x7954, +0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x4f65, 0x546e, 0x706f, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x3c3e, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, +0x6769, 0x7468, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, "\076" + IXTRC_INPUT_HELP, 0x37c, 370, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x353e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x4d2f, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, +0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, +0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x313e, +0x3c31, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, +0x5472, 0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x7954, 0x6570, 0x383e, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x4d3c, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, +0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, 0x4146, +0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, + IXTRC_ANALYSE, 0x37c, 370, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x353e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x4d2f, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, +0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, +0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x313e, +0x3c31, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, +0x5472, 0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x7954, 0x6570, 0x383e, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x4d3c, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, +0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, 0x4146, +0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, + IXTRC_CALCULATE, 0x37c, 370, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x353e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x4d2f, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, +0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, +0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x313e, +0x3c31, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, +0x5472, 0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x7954, 0x6570, 0x383e, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x4d3c, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, +0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, 0x4146, +0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, + IXTRC_SHOW_SSYNTAX, 0x37c, 370, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x353e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x4d2f, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, +0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, +0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x313e, +0x3c31, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, +0x5472, 0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x7954, 0x6570, 0x383e, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x4d3c, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, +0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, +0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, 0x4146, +0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, +0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, + IXTRC_RS_RECURSIVE, 0x37c, 377, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x353e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x5420, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, +0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, +0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, +0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, +0x3e6c, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, +0x5472, 0x7079, 0x3e65, 0x3131, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x7543, 0x7372, 0x726f, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, 0x3e65, 0x3c38, +0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x7954, +0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x4f65, 0x546e, 0x706f, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x3c3e, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, +0x6769, 0x7468, 0x463e, 0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, +0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, "\076" + IXTRC_RS_DECLARATIVE, 0x37c, 376, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x343e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x4420, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, +0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, +0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x5254, 0x4555, 0x2f3c, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, +0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, +0x7954, 0x6570, 0x313e, 0x3c31, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x7954, 0x6570, 0x383e, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, +0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, +0x6e4f, 0x6f54, 0x3e70, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4d3c, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, +0x6867, 0x3e74, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, + IXTRC_RS_IMPERATIVE, 0x37c, 376, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x343e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x413e, 0x746c, 0x2b20, 0x4720, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6f54, 0x6c6f, 0x6974, +0x3e70, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, 0x6c75, 0x546c, +0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x5254, 0x4555, 0x2f3c, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, +0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, +0x7954, 0x6570, 0x313e, 0x3c31, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, 0x3e65, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x7954, 0x6570, 0x383e, 0x2f3c, +0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x5465, 0x7079, +0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, +0x6e4f, 0x6f54, 0x3e70, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6f54, 0x3e70, 0x4d3c, +0x4346, 0x7542, 0x7474, 0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, +0x6867, 0x3e74, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x6e4f, 0x6952, 0x6867, 0x3e74, + IXTRC_FILTER, 0x37c, 369, 0 +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x535f, 0x7974, 0x656c, 0x343e, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7453, 0x6c79, 0x3e65, +0x4d3c, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x415f, 0x7475, 0x736f, 0x7a69, +0x3e65, 0x4146, 0x534c, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, +0x415f, 0x7475, 0x736f, 0x7a69, 0x3e65, 0x4d3c, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x4d2f, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x545f, 0x6f6f, 0x746c, 0x7069, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x7546, 0x6c6c, 0x6554, 0x7478, 0x6f54, 0x6c6f, +0x543e, 0x5552, 0x3c45, 0x4d2f, 0x4346, 0x7542, 0x7474, 0x6e6f, 0x465f, +0x6c75, 0x546c, 0x7865, 0x5474, 0x6f6f, 0x3e6c, 0x4d3c, 0x4346, 0x7542, +0x7474, 0x6e6f, 0x435f, 0x7275, 0x6f73, 0x5472, 0x7079, 0x3e65, 0x3131, +0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x7543, 0x7372, 0x726f, +0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x5465, 0x7079, 0x3e65, 0x3c38, 0x4d2f, 0x4346, 0x7542, 0x7474, +0x6e6f, 0x495f, 0x616d, 0x6567, 0x7954, 0x6570, 0x3c3e, 0x464d, 0x4243, +0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x546e, 0x706f, 0x463e, +0x4c41, 0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, +0x6761, 0x4f65, 0x546e, 0x706f, 0x3c3e, 0x464d, 0x4243, 0x7475, 0x6f74, +0x5f6e, 0x6d49, 0x6761, 0x4f65, 0x526e, 0x6769, 0x7468, 0x463e, 0x4c41, +0x4553, 0x2f3c, 0x464d, 0x4243, 0x7475, 0x6f74, 0x5f6e, 0x6d49, 0x6761, +0x4f65, 0x526e, 0x6769, 0x7468, "\076" + 0 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// AFX_DIALOG_LAYOUT +// + +IXTRD_CST_EDIT_DATA AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_VIEW_RSFORM AFX_DIALOG_LAYOUT +BEGIN + 0, + 0, 0, 100, 100, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 +END + +IXTRD_AUTOCOMPLETE AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_CST_CHANGE_TERM_FORM AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_CST_SET_CHANGING_WORD_TEXT AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_CST_SET_CHANGING_WORD_REF AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_START_PAGE AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_OPTION_ANALYZER AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_SYNT_MAPTABLE AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_SYNT_OPERANDS AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_EDIT_FILENAME AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_GENERATE_FUNC AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_GENERATE_TERM AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_GENERATE_TERM_STRUC AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_EDIT_TERM AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_EXPORT_SCHEMA AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_NEW_FILE AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_NEW_OSSDOC AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_ABOUTBOX AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_EDIT_COMMENT AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_SYNT_NAMES AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_OPTION_OSS AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_VIEW_TERMTREE AFX_DIALOG_LAYOUT +BEGIN + 0, + 0, 0, 100, 100 +END + +IXTRD_VIEW_PICT AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_CST_EDIT_MODEL AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_OPTION_MODEL AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_EXPORT_CSTGRAPH AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_CST_RENAME AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_EXPORT_MODEL AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_OPTION_APPLICATION AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_NEW_TRSDOC AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IXTRD_VIEW_RSMODEL AFX_DIALOG_LAYOUT +BEGIN + 0, + 0, 0, 100, 100, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + AFX_IDS_APP_TITLE " 4.9" + AFX_IDS_IDLEMESSAGE " " +END + +STRINGTABLE +BEGIN + ID_SEPARATOR " " + IXTRAD_MENU_MAINFRAME " 4.9" + IXTRAD_MENU_RSFORM "\n\n- \nTRS Files (*.trs)\n.trs\nTRS.Document\n - " + IXTRAD_MENU_RSMODEL "\n\n - \nRSM Files (*.rsm)\n.rsm\nRSM.Document\n " + IXTRAD_MENU_OSS "\n\n \nOSS Files (*.oss)\n.oss\nOSS.Document\n " + IXTRAD_FRAME_CLASSNAME "Exteor" +END + +STRINGTABLE +BEGIN + IXTRS_URL_CONFIRM " :\n%1\n " + IXTRS_ERASE_SRC_CONFIRM " !\n \n . ?" + IXTRS_BROWSE_TITLE " ..." + IXTRS_TERMFUNC_FROM_TERM "- %1" + IXTRS_TERM_FROM_TERMFUNC " - %1" + IXTRS_RSMODEL_DATA_IMPORT_FAIL " " + IXTRS_RSMODEL_DATA_IMPORT_SUCCESS " " + IXTRE_CLIPBOARD_OPEN " " + IXTRE_CLIPBOARD_CLEAR " " + IXTRE_CLIPBOARD_COPY " " + IXTRE_DATA2EXCEL_FORMAT " " + IXTRE_EXCEL_OPENWB " Excel" + IXTRS_DELCST_USED_IN_OSS + " %1 - !\n ?" + IXTRS_SRC_TYPE_TBA " " +END + +STRINGTABLE +BEGIN + IXTRS_RSFORM_OK "- \n " + IXTRS_RSMODEL_OK " \n " + IXTRE_EXPORT_TYPIF " . " + IXTRE_IMPORT_EXCEL_HEADER + " " + IXTRE_IMPORT_EXCEL_INVALID_DATA " " + IXTRS_DEL_CST_LOCAL_USE "!!\n :\n\n%1\n\n .\n\n ?" + IXTRS_PROPSHT_CAPTION "" + IXTRS_APP_PROPERTIES "" + IXTRS_SEARCH_NO_MATCH " " + IXTRS_ASK_REWRITE_FILE "%1\n , ?" + IXTRS_PROPERTI_TITLE " " + IXTRE_OLE_INIT_FAILED "OLE initialization failed. Make sure that the OLE libraries are the correct version." + IXTRE_MOVECST " !" + IXTRE_OSS_DIR_EXISTS " : %1 !" + IXTRE_OSS_DIR_NOT_FOUND " : %1" + IXTRS_REPORT_TYPIFICATION ": %1" +END + +STRINGTABLE +BEGIN + IXTRE_OSS_ASSOSIATION ": " + IXTRS_REPORT_VALUE_CLASS ": %1" + IXTRS_IS_CHANGE_TRS_NAME + " ?" + IXTRS_OSS_CANT_CREATE_ICON_LIST + " , " + IXTRE_PICT_FILE " ! " + IXTRE_OSS_DELETE_PICT " !\n " + IXTRS_OSS_LOG_CANT_CREATE_ICON_LIST + " " + IXTRS_OSS_SINTEZ_GO " : %1?" + IXTRE_OSS_RESULT_SAVE " !\n !" + IXTRE_LOG_ADD " " + IXTRE_EXPORT_WORD " !" + IXTRS_CALCULATION_SUCCESS " " + IXTRS_TEXT_TOOLTIP_DEFAULT + "Ctrl+ - \nCtrl+Shift+ - \nDelete/Backspace - \nCtrl+Shift+C - \nCtrl+Shift+T - \n - " + IXTRS_EXP_TOOLTIP_DEFAULT + "Ctrl - \nCtrl+F3 - \nCtrl+ - \n - \nCtrl+Shift+WASD - \nCtrl+Shift+Q - " + IXTRS_OP_NEW_TERM " " +END + +STRINGTABLE +BEGIN + IXTRE_TEMPLATE_NOT_FOUND " !\n%1" + IXTRS_PICT_DONE " " + IXTRS_PICT_REDO " " + IXTRS_PICT_BROKEN " " + IXTRS_PICT_DEFINED " " + IXTRS_PICT_UNDEFINED " " + IXTRS_PICT_DEFAULT "" + IXTRS_PICT_BASIC "" + IXTRS_PROP_SAVE " \n ?" + IXTRS_PROPERTI_ONCANCELQUESTION + " ?" + IXTRS_COPYRIGHT "Copyright NPMP CIHT CONCEPT 1994-2023" + IXTRE_INVALID_NAME " !\n " + IXTRE_NAME_TAKEN " !\n " + IXTRE_UNKNOWN_EXTENSION " : %1" + IXTRE_NO_ARGS "! 1 -" + IXTRE_NO_VAL "! " +END + +STRINGTABLE +BEGIN + ID_WINDOW_NEW " " + ID_WINDOW_ARRANGE " \n " + ID_WINDOW_CASCADE " " + ID_WINDOW_TILE_HORZ " \n " + ID_WINDOW_TILE_VERT " \n " +END + +STRINGTABLE +BEGIN + ID_FILE_MRU_FILE1 " " + ID_FILE_MRU_FILE2 " " + ID_FILE_MRU_FILE3 " " + ID_FILE_MRU_FILE4 " " + ID_FILE_MRU_FILE5 " " + ID_FILE_MRU_FILE6 " " + ID_FILE_MRU_FILE7 " " + ID_FILE_MRU_FILE8 " " + ID_FILE_MRU_FILE9 " " + ID_FILE_MRU_FILE10 " " +END + +STRINGTABLE +BEGIN + ID_NEXT_PANE " " + ID_PREV_PANE " " +END + +STRINGTABLE +BEGIN + IXTRC_INDICATOR_CAPS "CAP" + IXTRC_INDICATOR_NUM "NUM" + IXTRC_INDICATOR_SCRL "SCRL" +END + +STRINGTABLE +BEGIN + IXTRC_INDICATOR_LANGUAGE "DEFAULT" + IXTRC_INDICATOR_RUSSIAN "RUSSIAN" + IXTRC_INDICATOR_ENGLISH "ENGLISH" + IXTRC_INDICATOR_GOTHIC "MATH" +END + +STRINGTABLE +BEGIN + IXTRS_REPORT_SUGGESTION "mailto:bugreport@acconcept.ru ? subject=[ %1] " + IXTRE_BROWSE_DLG " " + IXTRE_CANTLOADFONT "! !" + IXTRE_TEXT_METRICS " ..." + IXTRS_GENERATE_TERM " " + IXTRE_EMPTY_SHEMA " " + IXTRE_OSS_NOTSAVED " !" + IXTRE_NOT_IMPLEMENTED " " + IXTRS_PROMT_RESET_FLAGS " , ?\n !" + IXTRE_DELETE_CST " %1! , - -" + IXTRE_DELETE_CST_PARTIAL + " " + IXTRE_LIST_CLEAR " ListCtrl" + IXTRE_OP_APPLICABLE " "" "" , " + IXTRE_SYNT_INCORRECT " ! , " + IXTRE_SELECTION_EMPTY " -" +END + +STRINGTABLE +BEGIN + IXTRE_RSFORM_OP_COUNT " - " + IXTRE_REF_CANNOT_ADD " " + IXTRS_PROMT_ERASE_DATA "! \n ?" +END + +STRINGTABLE +BEGIN + IXTRS_OSS_RUN_PARENT " .\n ?" + IXTRE_EXT1_FILE " , " + IXTRE_RENAME_NOOP " " + IXTRS_DELCST_USED_IN_OPS + " %1 ! , " + IXTRS_PROMT_MERGE_DATA " \n ?" + IXTRS_DISCARD_SRC_CONFIRM + "! \n " + IXTRS_STATUS_UNKNOWN "" + IXTRS_STATUS_NORMAL "" + IXTRS_STATUS_ERROR "" + IXTRS_STATUS_READONLY "" + IXTRS_STATUS_CHECK " " + IXTRS_DEFAULT_TOOLTIP_DATA + " (Enter) " + IXTRE_IMPORT_TYPIF " . " + IXTRE_PICT_NO_SRC " " + IXTRE_PICT_RENAME_OPENED + " !\n " +END + +STRINGTABLE +BEGIN + ID_APP_ABOUT " , \n " + ID_APP_EXIT " \n" + ID_HELP_INDEX " \n " + ID_HELP_USING " " + ID_CONTEXT_HELP " " +END + +STRINGTABLE +BEGIN + IXTRC_XTR_HELP " " +END + +STRINGTABLE +BEGIN + ID_FILE_NEW " \n" + ID_FILE_OPEN " \n" + ID_FILE_CLOSE " \n" + ID_FILE_SAVE " \n" + ID_FILE_SAVE_AS " \n " +END + +STRINGTABLE +BEGIN + IXTRC_RESET_OSSFLAG " , - " + IXTRC_SAVE_IMAGE " " + IXTRC_OSS_ENABLE_LEGEND " \n (F3)" + IXTRC_BUG_REPORT " !\n " + IXTRC_MAIL_DEVELOPERS " " +END + +STRINGTABLE +BEGIN + IXTRC_TOOLBAR_OSS "/ \n " +END + +STRINGTABLE +BEGIN + IXTRC_OP_MAX_PART " - " + IXTRC_OP_SELECT_BASIS " -, () " + IXTRC_RESET_NAMES " " + IXTRC_DELETE_CST " " + IXTRC_EDIT_OPTIONS " " + IXTRC_OSS_DEL " \n (Delete)" + IXTRC_OSS_ADD " - \n (Ctrl + Q)" +END + +STRINGTABLE +BEGIN + ID_VIEW_TOOLBAR "/ \n " + ID_VIEW_STATUS_BAR "/ \n " +END + +STRINGTABLE +BEGIN + IXTRC_SYNTHES " -" + IXTRC_OSS_SHIFT_LEFT " \n (Ctrl + Left)" + IXTRC_OSS_SHIFT_RIGHT " \n (Ctrl + Right)" +END + +STRINGTABLE +BEGIN + IXTRC_FOLLOW_HLINK " " + IXTRC_EDIT_HLINK " \n" + IXTRC_OSS_ENABLE_GRID " \n " +END + +STRINGTABLE +BEGIN + IXTRC_OSS_SYNT_ALL " \n (Ctrl+Alt+F7)" + IXTRC_OSS_OP_RUN_ALL " \n (Ctrl+F7)" + IXTRC_OSS_ZOOM_OUT " \n (NUM -)" + IXTRC_OSS_ZOOM_IN " \n (NUM +)" +END + +STRINGTABLE +BEGIN + IXTRC_OSS_ASSIGN_DOC " -\n (Ctrl+A)" + IXTRC_OSS_EDIT_DOC " \n (Enter)" + IXTRC_OSS_OP_NEW " \n (Ctrl+D)" + IXTRC_OSS_OP_RUN_SINGLE " \n (F7)" + IXTRC_OSS_OP_EDIT " \n (Ctrl+E)" +END + +STRINGTABLE +BEGIN + IXTRC_MODEL_CALCULATE " " + IXTRC_EXPORT_MODEL " " + IXTRC_BACKUP " " +END + +STRINGTABLE +BEGIN + IXTRC_RSNAVIGATOR " " + IXTRC_OSS_DISCARD_DOC " . " + IXTRC_OSS_OP_CHECK " " + IXTRC_EXPORT_GRAPH " " +END + +STRINGTABLE +BEGIN + IXTRC_CONVERT_TO_RSFORM " , - , " +END + +STRINGTABLE +BEGIN + IXTRC_CALCULATE " " +END + +STRINGTABLE +BEGIN + IXTRC_INSERT " \n (Ctrl+Shift+T)" + IXTRC_INSERT_BASE_SET " " + IXTRC_INSERT_TERM " " + IXTRC_INSERT_AXIOM " " + IXTRC_INSERT_CONST_SET " " + IXTRC_INSERT_STUPEN_PRS " \n (Ctrl+Shift+C)" +END + +STRINGTABLE +BEGIN + IXTRC_INSERT_RS " " + IXTRC_INSERT_STUPEN_PT " \n (Ctrl+Shift+S)" + IXTRC_INSERT_THEOREMA " " + IXTRC_INSERT_FREE " " + IXTRC_OP_MERGE " - " + IXTRC_SELECT_BASIS " , " +END + +STRINGTABLE +BEGIN + IXTRC_SELECT_DEPENDENT " , " + IXTRC_INSERT_FUNCTION " -" + IXTRC_INSERT_PREDICATE " -" + IXTRC_TERM_TO_FUNC " -" + IXTRC_FUNC_TO_TERM " -" + IXTRC_STRUCTURE_TO_TERMS " " + IXTRC_RESET_COLUMNS " " + IXTRC_RENAME " " +END + +STRINGTABLE +BEGIN + IXTRS_SYNT_MERGE "" + IXTRS_SYNT_BM " " + IXTRS_SYNT_STRUCTURE " " + IXTRS_OP_NOT_DEF " " + IXTRS_OSS_CREATE_NEW_FILE " ?" + IXTRS_PICT_NAME_AT " " + IXTRS_OWER_MAXSLOI " " + IXTRE_OSS_UNARYOP " " + IXTRS_OSS_CANT_OPEN_PARENT " " + IXTRS_OSS_UNDEF_OP " %1 " + IXTRS_OSS_UNDEF_OTGD " \n\n ?" + IXTRS_OSS_WRONG_PARENT " ! " + IXTRS_EXPORT_WORD_OK " \n! DejaVu Sans\n , " + IXTRE_OSS_SAVE_PICT " %1 , .\n ?" + IXTRE_SINGLE_OSS " " +END + +STRINGTABLE +BEGIN + IXTRE_FILE_MOVE " " + IXTRS_LOG_TASK_NAME " " + IXTRS_LOG_TASK_STATE "" + IXTRS_CHANGE_OPTS_CAUTION + "! \n \n?" + IXTRS_LOG_ERR_STATE "" + IXTRS_LOG_LOAD_FILE " -" + IXTRS_LOG_ERR_LOAD_FILE " -" + IXTRS_LOG_UNKNOW " ! " + IXTRS_PYTHON_CRASH_PROMPT + " - . ?" + IXTRS_PYERR_NOLOAD " Python. Python " + IXTRS_PYERR_NOCORE " . pymorphy2" + IXTRE_FAILED_ADD_TERMIN " " + IXTRS_CANT_DELETE_TERMIN + " " + IXTRE_DELETE_TERMIN " " + IXTRE_SYNT " " + IXTRS_INPUT_WORD " " +END + +STRINGTABLE +BEGIN + IXTRS_LEX_EOL " " + IXTRE_RSMODEL_TYPIFICATION " " + IXTRS_LEX_UNKNOWN_SYM "! : %1" + IXTRE_RSMODEL_DATA " " + IXTRE_CST_INSERT " ListCtrl" +END + +STRINGTABLE +BEGIN + IXTRO_ZOOM_VISIBLE "ZoomOSS" + IXTRO_SECTION_TRSVIEW "RSForm" + IXTRO_SECTION_MODEL "RSModel" + IXTRO_SECTION_OSS "OSSView" + IXTRO_RUN_AFTER_OK "RunAfterClickOK" + IXTRO_SECTION_APPLICATION "Application" + IXTRO_OSS_LEGEND "EnableLegend" + IXTRO_TRSV_NAME_WIDTH "NameWidth" + IXTRO_TRSV_EXP_WIDTH "ExpressionWidth" + IXTRO_TRSV_INTER_WIDTH "InterpretationWidth" + IXTRO_TRSV_TYPE_WIDTH "TypingWidth" + IXTRO_TRSV_COMMENT_WIDTH "CommentaryWidth" + IXTRO_SAMPLES_DIR "DefaultDirectory" + IXTRO_SAVEAS_PATH "SaveAsDirectory" +END + +STRINGTABLE +BEGIN + IXTRO_OSS_SPLITTER "SplitterPostion" + IXTRO_TRSV_DATAMODE "DataMode" + IXTRO_RSM_VAL_WIDTH "ValueWidth" + IXTRO_OSS_GRID "EnableGrid" + IXTRO_TRSV_EXPT_TERM "ExportTerm" + IXTRO_TRSV_EXPT_FORM "ExportExpression" + IXTRO_LOG_AUTO_OPEN "LookProcesWnd" + IXTRO_OSS_STOP_ERROR "StopByError" + IXTRO_TRSV_EXPT_INTER "ExportInterpretation" + IXTRO_TRSV_EXPT_COM "ExportComment" + IXTRO_TRSV_SPLITTER_POS "SplitterPosition" + IXTRO_TRSV_EXPT_TYPE "ExportTyping" + IXTRO_SECTION_ANALYZER "Analyzer" + IXTRO_CST_AUTOCHECK "AutoCheck" +END + +STRINGTABLE +BEGIN + IXTRO_RSFORM_INDEXCST "IndexCst" + IXTRO_RSFORM_INDEXLOCAL "IndexLocal" + IXTRO_RSFORM_INDEXPR "IndexPr" + IXTRO_RSFORM_AUTOINDEX "AutoIndex" + IXTRO_SA_COLORPAR "PaintParanthesis" + IXTRO_SA_AST "AbstractSyntaxTree" + IXTRO_SA_NAVIGATOR "RSNavigator" + IXTRO_APP_TOOLBAR "ToolbarState" + IXTRO_TRSV_TERM_WIDTH "TermWidth" + IXTRO_TB_MAIN "MainToolbar" + IXTRO_TB_CST "CstToolbar" + IXTRO_TB_OSS "OSSToolbar" + IXTRO_TB_STATUS "StatusBar" + IXTRO_START_PAGE "StartPage" + IXTRO_PYSTART "PyStart" + IXTRO_PYPATH32 "PyPath312_32" +END + +STRINGTABLE +BEGIN + IXTRO_PYPATH64 "PyPath312_64" + IXTRO_PYCRASH "PyCrash" + IXTRO_SECTION_TEXT "TextForm" + IXTRO_TXT_EDITREF "EditRef" + IXTRO_DISABLE_KEYBOARD "DisableAutoKeyboard" +END + +STRINGTABLE +BEGIN + IXTRE_RENAME_UNKNOWN " !\n !" + IXTRS_DEFAULT_SAMPLES_DIR " " + IXTRS_DEFAULT_CS_OSS_DIR "" + IXTRS_RENAME_FILE_EXISTS + " : %1" +END + +STRINGTABLE +BEGIN + IXTRS_TITLE_TOOLBAR "" + IXTRS_TITLE_INSTOOL " " + IXTRS_TITLE_OSS " " + IXTRS_OSS_LOG_PROCES " " + IXTRS_TRSV_TOOLTIP_DEFAULT + " Ctrl+/\nCtrl+Q - \nCtrl+E - " + IXTRE_FILE_NOT_FOUND " : %1" +END + +STRINGTABLE +BEGIN + IXTRE_EQUATION_INVALID " " + IXTRE_EQUATION_ARGS " , " + IXTRE_EQUATION_UNKNOWN " " +END + +STRINGTABLE +BEGIN + IXTRS_SRC_TYPE_TRS " - " +END + +STRINGTABLE +BEGIN + IXTRS_CASEQ_ACCS " ? ?" + IXTRS_CASEQ_ABLT " ? ?" + IXTRS_CASEQ_LOCT " ? ?" + IXTRE_FUNC2TERM " !" + IXTRE_WORD_APPL " Word" + IXTRS_EXPORTXL_SUCCESS " Excel" + IXTRS_EXPORTXL_FAIL " " + IXTRE_UNARY_OP " !\n%1" + IXTRS_REPORT_ERR_COUNT " : %1!d!\n : %2!d!" + IXTRS_REPORT_NORMALIZED_AST + " \n%1\n : http://mshang.ca/syntree/" + IXTRS_REPORT_SET_VALUE " : %1!d!\n : %2" + IXTRS_REPORT_VALUE " : %1" + IXRE_EMPTY_TERMS " " +END + +STRINGTABLE +BEGIN + IXTRS_RSLOOP_FOUND " !\n : %1" + IXTRS_TERMFUNC_SUCCESS "- %1 " + IXTRE_HYPERLINK_FOLLOW " : %1" + IXTRE_RENAME_FAIL " . " + IXTRS_PICTINFO_TBA " " + IXTRS_OPTS_BROKEN " " + IXTRS_EXECUTE_OP_FAIL " ! " + IXTRS_DATA_ADD_BASE_ELEMENT " %1 %2\n ?" +END + +STRINGTABLE +BEGIN + IXTRE_WORD_BOOKMARK_MISSING " Word %1" + IXTRS_CST_MOVE_INFO " \n%1\n%2" + IXTRS_EXECUTION_FAILED " , . , " + IXTRS_FOLLOW_HYPERLINK " " + IXTRS_EDITING_CST " " + IXTRS_CAPTION_DEFAULT_FILE " " + IXTRS_SELECT_ALL " " + IXTRS_OSS_RUNALL_PROMPT "! ! .\n ?" + IXTRS_OSS_RUNALL_SUCCESS " " + IXTRE_CANNOT_SAVE_DATA " " +END + +STRINGTABLE +BEGIN + IXTRS_PICK_REF " , , " + IXTRE_TERMIN_INDEX "! " + IXTRE_TERMIN_SWAP " " + IXTRE_RELATE_RS " " + IXTRE_OSS_SOURCE_UNACCESSIBLE + " : %1\n ?" + IXTRS_OPLABEL_MERGE "" + IXTRS_ERR_MOVE_CST " " + IXTRS_OPLABEL_SYNT " " + IXTRS_OPLABEL_UNDEF " " + IXTRS_PICTINFO_NO_ACCESS " : %1" + IXTRS_SCC_INFO_COUNT "\n %1!d!: " +END + +STRINGTABLE +BEGIN + IXTRS_GLOBAL_NO_VALUE_CLASS + " : %1" + IXTRS_PROXY_AS_VALUE " " + IXTRS_GLOBAL_NO_AST " : %1" + IXTRS_FUNCTION_CALL_INVALID + " " + IXTRS_NO_ARITHMETIC " : %1" + IXTRS_INCOMPATIBLE_TYPES + " : %1 %2" + IXTRS_NO_ORDERING " : %1" + IXTRS_PAR_SYNTHAXERROR " " + IXTRS_RS_CHECK_SUCCESS " : " + IXTRS_PAR_FAILURE " : " + IXTRS_TYPE_INCONSISTENT " \n\n" +END + +STRINGTABLE +BEGIN + IXTRS_TYPE_STRUCTURE " " + IXTRS_TYPE_FUNCTION " " + IXTRS_USE_RADICAL " -: %1" + IXTRS_FILTER_ARGUMENT " : %1(%2)" + IXTRS_FILTER_PARAM_ARITY + " " +END + +STRINGTABLE +BEGIN + IXTRS_PAR_EXPECTED_RP " , " + IXTRS_PAR_EXPECTED_RC " '}'" + IXTRS_PAR_QUANTDECL " " + IXTRS_PAR_IMPERATIVE " " + IXTRS_TYPE_UNKNOWN_FUNCTION " : %1" + IXTRS_TYPE_FUNCTION_AS_GLOBAL + " : %1" + IXTRS_TYPE_NAME_UKNOWN " : %1" + IXTRS_TYPE_NAME_DECLARED " : %1" + IXTRS_TYPE_GLOBAL_NOTYPE " : %1" + IXTRS_TYPE_CART "T(a*b) = B(D(T(a)) * D(T(b))). : " + IXTRS_TYPE_WRONG_TYPE " ! %1 != %2" +END + +STRINGTABLE +BEGIN + IXTRS_TYPE_NAME_REDECLARED + "! %1" + IXTRS_VALUECHECK_FAILURE " : " + IXTRS_TYPE_BOOL "T(B(a)) = BB(D(T(a))). : %1" + IXTRS_TYPE_SET_OPERATOR " : %1" + IXTRS_TYPE_CARD " : %1" + IXTRS_TYPE_DEBOOL "T(debool(a)) = D(T(a)). : %1" + IXTRS_TYPE_RED "T(red(a)) = B(DD(T(a))). : %1" + IXTRS_TYPECHECK_FAILURE " : " + IXTRS_TYPE_PR_ERROR " : %1 -> %2 " + IXTRS_TYPE_BIGPR "T(Pri(a)) = B(Pi(D(T(a)))). : %1" + IXTRS_TYPE_ENUMERATION " : %1 != %2" + IXTRS_TYPE_DECLARE_CORTEGE + " !" + IXTRS_TYPE_NAME_SCOPE " : %1" + IXTRS_TYPE_EL_WRONG_TYPE + " : %1%2%3" + IXTRS_TYPE_NAME_NOT_USED + "! : %1" +END + +STRINGTABLE +BEGIN + IXTRS_VALUE_FAILURE " : " + IXTRS_TYPE_FUNC_ARGNUM " -: %1 != %2" + IXTRS_TYPE_FUNC_WRONG_ARG + " - : %1 != %2" + IXTRS_PAR_EXPECTED_VAR " : " + IXTRS_VALUE_UNKNOWN_ERROR + " ! " + IXTRS_VALUE_SUCCESS " : " + IXTRS_VALUE_SET_LIMIT " : %1" + IXTRS_VALUE_BOOL_LIMIT " : %1" + IXTRS_VALUE_VAR_INCALC " : " + IXTRS_VALUE_ITER_LIMIT " : %1" + IXTRS_EXPORT_SUCCESS " :\n%1" + IXTRS_OPEN_CLAIMED " !\n , \n ?" + IXTRE_OP_SELECT_BASIS " " +END + +STRINGTABLE +BEGIN + IXTRS_PAR_EXPECTED_ARGDECL " -" + IXTRS_REPORT_AST " \n%1\n : http://mshang.ca/syntree/" + IXTRS_REPORT_NORMALIZED_EXPR " : %1" + IXTRS_REPORT_BUG_PROMPT " ...\n\n, , .\n !" + IXTRS_VALUE_DEBOOL " debool " + IXTRS_REPORT_ITERATIONS " : %1!d!" + IXTRS_ITERATE_INFINITY " " + IXTRS_CORE_CORRECT "" + IXTRS_CORE_WARNING " " + IXTRS_CORE_INCORRECT "" + IXTRS_MODEL_CORRECT "" + IXTRS_MODEL_WARNING " " + IXTRS_MODEL_INCORRECT " " + IXTRS_TYPE_INTEGRAL "" + IXTRS_TYPE_BOOLEAN "" +END + +STRINGTABLE +BEGIN + IXTRC_RELATION " - " + IXTRC_CST_MERGING " -" +END + +STRINGTABLE +BEGIN + IXTRC_START_PAGE " " +END + +STRINGTABLE +BEGIN + IXTRE_DOC_FRAME " " + IXTRE_FILE_UNAVAILABLE " \n%1" + IXTRS_RENAME_SUCCESS " " + IXTRS_DRAW_UNDEFINED "\n " + IXTRS_DRAW_DEFINED "\n" + IXTRS_DRAW_DONE "\n" + IXTRS_DRAW_REDO "\n" + IXTRS_DRAW_BROKEN "\n" + IXTRS_DRAW_BASE "\n" + IXTRS_DRAW_HAS_FILE "\n" + IXTRS_VERSION_TEXT " %1 Powered by %2" + IXTRS_REPORT_BUG_SUBJECT + "mailto:bugreport@acconcept.ru ? subject=[ %1] " +END + +STRINGTABLE +BEGIN + IXTRS_SCC_INFO " : %1!d!" + IXTRS_CASE_NOMN "" + IXTRS_CASE_GENT "" + IXTRS_CASE_DATV "" + IXTRS_CASE_ACCS "" + IXTRS_CASE_ABLT "" + IXTRS_CASE_LOCT "" + IXTRS_PLUR_SINGULAR "" + IXTRS_PLUR_PLURAL "" + IXTRS_CALC_TIME " \n : %1 " + IXTRS_GENDER_MASC "" + IXTRS_GENDER_FEMN "" + IXTRS_GENDER_NEUT "" + IXTRS_CASEQ_NOMN "? ?" + IXTRS_CASEQ_GENT " ? ?" + IXTRS_CASEQ_DATV " ? ?" +END + +STRINGTABLE +BEGIN + IXTRS_VC_VALUE " " + IXTRS_VC_PROPERTY " " + IXTRS_VC_INVALID " " + IXTRS_YES "" + IXTRS_NO "" + IXTRS_DESCRIPTION_CORE " : %1\n\n : %2!d!\n : %3!d!" + IXTRS_EMPTY_CST_FOUND "\n\n \n" + IXTRS_FORMULA_CYCLE_FOUND "\n\n \n" + IXTRS_REFERENCE_CYCLE_FOUND "\n\n \n" + IXTRS_SYNONYMS_FOUND "\n\n \n" + IXTRS_DESCRIPTION_MODEL " : %1\n\n : %2!d!\n : %3!d!\n : %4!d!\n : %5!d!" + IXTRS_DESCRIPTION_REFERENCE + " : \n : %1\n: %2\n: %3\n\n : %4" + IXTRS_DESCRIPTION_DEPENDANT_WORD + " : \n : %1\n: %2\n\n : %3" +END + +STRINGTABLE +BEGIN + IXTRS_DESCRIPTION_OPERATION + " : %1\n : %2" + IXTRS_EXCEPTION_ON_SAVE " : %1\n : %2" +END + +STRINGTABLE +BEGIN + IXTRE_FOLDER_CREATE_FAIL " %1" + IXTRS_OSS_ARCH_SUCCESS " : %1" + IXTRE_LOG_NOT_FOUND " " + IXTRE_OSS_PNG_FAIL " !" + IXTRS_PICT_NONAME " " + IXTRS_COMMENT "" + IXTRS_CONVENTION "" + IXTRS_ERASE_PICT_FAIL " , " + IXTRE_EDIT_OPT_NO_ARG " ! " + IXTRE_IMPORT_DOC_FAIL " : %1" + IXTRS_BROKEN_OP "! .\n """" " + IXTRS_CCL_INIT_OP_FAIL " ! " + IXTRS_TERM_CREATE_SUCCESS " %1 " + IXTRS_CAPTION_TERM " " + IXTRS_LABEL_IGNORE_RELATION " " + IXTRS_CAPTION_EQUATE " " +END + +STRINGTABLE +BEGIN + IXTRS_HEADER_NO "" + IXTRS_HEADER_NAME "" + IXTRS_HEADER_TERM "" + IXTRS_HEADER_TYPE "" + IXTRS_HEADER_CONVENTION "" + IXTRS_HEADER_TEXTDEF ". " +END + +STRINGTABLE +BEGIN + IXTRS_FILTER_DEFAULT " (*.*)|*.*||" + IXTRS_FILTER_EXCEL "Excel Files (*.xlsx)|*.xlsx|Excel Files (*.xls)|*.xls|" + IXTRS_FILTER_MAIN "Exteor files (*.trs;*.rsm;*.oss)|*.trs; *.rsm; *.oss|RSForm (*.trs)|*.trs|RSModel (*.rsm)|*.rsm|Operation schema (*.oss)|*.oss| (*.*)|*.*||" + IXTRS_FILTER_OSS_PROMPT "TRS Files (*.trs)|*.trs | (*.*)|*.*||" +END + +STRINGTABLE +BEGIN + IXTRS_HEADER_RSDEF " " + IXTRS_HEADER_CARD "Mod" + IXTRS_HEADER_VALUE "VAL" + IXTRS_HEADER_ARGUMENT "ARG" + IXTRS_HEADER_EXPRESSION "" + IXTRS_HEADER_INTERPRETATION "" + IXTRS_HEADER_ID "ID" + IXTRS_HEADER_CONSTITUENTA "" + IXTRS_HEADER_PATH "" + IXTRS_HEADER_FILENAME " " + IXTRS_HEADER_SHORTNAME "" + IXTRS_HEADER_RS_FULL " " +END + +STRINGTABLE +BEGIN + IXTRS_PATH_MODEL_TEMPLATE "\\RSModelData.xltx" + IXTRS_PATH_RSDOC_TEMPLATE "\\RSFormTemplate.dotx" + IXTRS_FILE_HELP "Help.chm" + IXTRS_FILE_FAQ "!.rtf" + IXTRS_FOLDER_SAMPLES "" + IXTRS_FILE_UPDATELOG "UpdateLog.txt" +END + +STRINGTABLE +BEGIN + IXTRC_EXPORT_OSS " JSON" +END + +STRINGTABLE +BEGIN + IXTRC_EXPORT_SCHEMA " " +END + +STRINGTABLE +BEGIN + ID_EDIT_COPY " " + ID_EDIT_PASTE " " +END + +#endif // Russian (Russia) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#include "afxres.rc" // Standard components +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/include/resource.h b/include/resource.h new file mode 100644 index 0000000..308e2c8 --- /dev/null +++ b/include/resource.h @@ -0,0 +1,781 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Exteor.RC +// +#define IXTRAD_MENU_MAINFRAME 2 +#define IXTRR_TOOLBAR_MAINFRAME 2 +#define IXTRAD_MENU_RSFORM 3 +#define IXTRC_ADDFUNC 4 +#define IXTRAD_MENU_RSMODEL 5 +#define IXTRAD_MENU_OSS 6 +#define IXTRAD_FRAME_CLASSNAME 10 +#define IXTRR_TOOLBAR_RSFORM 100 +#define IXTRR_BTN_DECART 134 +#define IXTRR_CREATE_OPERATION 139 +#define IXTRR_PICT_BASIS 150 +#define IXTRR_PICT_UNDEFINED 153 +#define IXTRR_PICT_DEFINED 155 +#define IXTRR_PICT_DONE 157 +#define IXTRR_PICT_REDO 158 +#define IXTRR_PICT_BROKEN 159 +#define IXTRR_BTN_BOOLEAN 219 +#define IXTRR_BTN_LOGIC_NOT 220 +#define IXTRR_BTN_SET_UNION 221 +#define IXTRR_BTN_SET_INTERSECT 222 +#define IXTRR_BTN_LOGIC_OR 223 +#define IXTRR_BTN_ELEMENT 224 +#define IXTRR_BTN_LOGIC_IMPLICAT 225 +#define IXTRR_BTN_NOTEQUAL 226 +#define IXTRR_BTN_EMPTYSET 227 +#define IXTRR_BTN_LOGIC_EXISTS 229 +#define IXTRR_BTN_LOGIC_FORALL 230 +#define IXTRR_BTN_LOGIC_EQUAL 234 +#define IXTRR_BTN_LOGIC_AND 235 +#define IXTRR_BTN_EQUAL 237 +#define IXTRR_BTN_SUBSET_OR_EQ 238 +#define IXTRR_BTN_NOTELEMENT 239 +#define IXTRR_BTN_NOTSUBSET 240 +#define IXTRR_BTN_SET_MINUS 241 +#define IXTRR_BTN_SUBSET 242 +#define IXTRR_BTN_SETDECLARATION 243 +#define IXTRR_BTN_DOUBLEPAR 244 +#define IXTRR_BTN_GREATER_OR_EQ 245 +#define IXTRR_BTN_LESSER_OR_EQ 246 +#define IXTRR_BTN_SYMMINUS 247 +#define IXTRR_TOOLBAR_OSS 248 +#define IXTRR_NEW_DOC 249 +#define IXTRR_HELP 250 +#define IXTRR_OPEN_DOC 251 +#define IXTRR_SAMPLES 252 +#define IXTRAD_RSVIEW_POPUP 256 +#define IXTRAD_OSS_POPUP 257 +#define IXTRAD_MENU_CST 258 +#define IXTRR_BTN_DOUBLESQR 260 +#define IXTRR_HYPERLINK 263 +#define IXTRR_PICT_HASFILE 264 +#define IXTRC_ALIAS 1000 +#define IXTRC_TITLE 1001 +#define IXTRC_SYNT_OP1 1002 +#define IXTRC_RSFORM_LIST 1003 +#define IXTRC_RSFORM_SEARCH 1004 +#define IXTRC_INTERPRETATION 1005 +#define IXTRC_FORM_WYR_STATIC 1009 +#define IXTRC_EXPRESSION 1010 +#define IXTRC_COMMENT_EC 1011 +#define IXTRC_OP_NAME 1012 +#define IXTRC_OSS_NAME 1013 +#define IXTRC_OPERAND1 1014 +#define IXTRC_ZOOM_INT 1015 +#define IXTRC_FILENAME 1017 +#define IXTRC_OSS_PATH 1018 +#define IXTRC_OPERAND2 1019 +#define IXTRC_EXPR_OUTPUT 1020 +#define IXTRC_FORM_WYR_STATIC2 1021 +#define IXTRC_INTERPRETATION_STATIC 1022 +#define IXTRC_INTER 1023 +#define IXTRC_FORM_WYR_STATIC3 1024 +#define IXTRC_FORM_WYR_STATIC4 1025 +#define IXTRC_NAME 1026 +#define IXTRC_COMMENT 1027 +#define IXTRC_CSTNAME_STATIC 1028 +#define IXTRC_VERSION 1029 +#define IXTRC_LEGALTRADEMARKS 1030 +#define IXTRC_COPYRIGHT 1031 +#define IXTRC_COPYRIGHT2 1032 +#define IXTRC_COPYRIGHT3 1033 +#define IXTRC_COPYRIGHT4 1034 +#define IXTRC_OPERATION 1035 +#define IXTRC_TERM_TREE 1036 +#define IXTRC_COMMENT_B 1038 +#define IXTRC_TRS_UPDATE_STATUS 1039 +#define IXTRC_MODEL_CALCULATE 1040 +#define IXTRC_TRS_SEARCH 1041 +#define IXTRC_STATUS 1042 +#define IXTRC_EXPORT_MODEL 1043 +#define IXTRC_MODEL_SEARCH 1044 +#define IXTRC_SRC_TYPE 1045 +#define IXTRC_FIRST_OP 1046 +#define IXTRC_SECOND_OP 1047 +#define IXTRC_FILE_NAME 1048 +#define IXTRC_RS_TITLE 1049 +#define IXTRC_BM_OP2 1050 +#define IXTRC_OSS_FILE 1051 +#define IXTRC_RS_ALIAS 1052 +#define IXTRC_OPEN_FOLDER 1053 +#define IXTRC_RESULT_TITLE 1054 +#define IXTRC_BACKUP 1055 +#define IXTRC_RESULT_ALIAS 1056 +#define IXTRC_NEXT 1057 +#define IXTRC_PREV 1058 +#define IXTRC_BM_OP1 1059 +#define IXTRC_IN1 1060 +#define IXTRC_BROWSE 1061 +#define IXTRC_IN2 1062 +#define IXTRC_XTR_HELP 1063 +#define IXTRC_IN3 1064 +#define IXTRC_STATIC_BORDER 1065 +#define IXTRC_STATIC_BORDER2 1066 +#define IXTRC_NAME2 1067 +#define IXTRC_STATIC_FULL_NAME 1068 +#define IXTRC_STATIC_SHORT_NAME 1069 +#define IXTRC_STATIC_BORDER3 1070 +#define IXTRC_OTOGDESWLENYA 1071 +#define IXTRC_STATIC_OP_SINT 1072 +#define IXTRC_STATIC_OTOGD 1073 +#define IXTRC_SA_AUTOCHECK 1075 +#define IXTRC_OSS_SINT_DEF_LC 1100 +#define IXTRC_OSS_RUN_AFTER_CLK_OK 1101 +#define IXTRC_FILL_INTERP 1102 +#define IXTRC_OSS_GRID_ENABLED 1103 +#define IXTRC_EXPORT_DATA 1104 +#define IXTRC_IMPORT_CSTDATA 1105 +#define IXTRC_NAME_CB 1106 +#define IXTRC_BOOL 1107 +#define IXTRC_ERASE_DATA 1107 +#define IXTRC_BOOLEAN 1108 +#define IXTRC_ALPCLASSIC 1109 +#define IXTRC_DEBOOL 1110 +#define IXTRC_FILE_XLSX 1111 +#define IXTRC_RED 1123 +#define IXTRC_FILE_DOCX 1124 +#define IXTRC_FILE_CSV 1125 +#define IXTRC_CARD 1126 +#define IXTRC_FILE_JSON 1126 +#define IXTRC_PR_S 1127 +#define IXTRC_PR_L 1128 +#define IXTRC_OR 1129 +#define IXTRC_CARTPROD 1130 +#define IXTRC_INPUT_HELP 1131 +#define IXTRC_NEGATION 1132 +#define IXTRC_SHEMA1_NAME 1133 +#define IXTRC_SHOW_SSYNTAX 1133 +#define IXTRC_SHEMA2_NAME 1134 +#define IXTRC_RS_RECURSIVE 1134 +#define IXTRC_UNION 1135 +#define IXTRC_SYNT_OP2 1136 +#define IXTRC_RS_DECLARATIVE 1136 +#define IXTRC_INTERSECT 1137 +#define IXTRC_SYNT_MERGE 1138 +#define IXTRC_RS_IMPERATIVE 1138 +#define IXTRC_SYNT_FLAG_CTABLE 1139 +#define IXTRC_FILTER 1139 +#define IXTRC_COMMENT_KS 1140 +#define IXTRC_PICT_LINK 1141 +#define IXTRC_BELONG 1142 +#define IXTRC_OSS_COMMENT 1143 +#define IXTRC_SYNTAX 1144 +#define IXTRC_IMPLICATION 1145 +#define IXTRC_EXP_STATUS 1146 +#define IXTRC_INEQ 1147 +#define IXTRC_ANALYSE 1148 +#define IXTRC_NULLSET 1149 +#define IXTRC_SYNT_ABSTRACT 1150 +#define IXTRC_QUANTEXIST 1152 +#define IXTRC_QUANTUNIVERSAL 1153 +#define IXTRC_LOGIC_EQUAL 1154 +#define IXTRC_COMMENT_STATIC 1155 +#define IXTRC_EQUAL 1156 +#define IXTRC_CALCULATE 1157 +#define IXTRC_LANGUAGE 1158 +#define IXTRC_RSFORM_STATUS 1159 +#define IXTRC_LOGIC_AND 1160 +#define IXTRC_MODEL_STATUS 1161 +#define IXTRC_SET_MINUS 1162 +#define IXTRC_NOTELEMENT 1163 +#define IXTRC_SUBSET 1164 +#define IXTRC_DOUBLEPAR 1166 +#define IXTRC_SET_SYMMINUS 1167 +#define IXTRC_SA_COLOR_PAR 1168 +#define IXTRC_NOTSUBSET 1169 +#define IXTRC_INDEXCST0 1170 +#define IXTRC_SUBSET_OR_EQ 1171 +#define IXTRC_INDEXCST1 1172 +#define IXTRC_ARG_LIST 1173 +#define IXTRC_GREATER_OR_EQ 1174 +#define IXTRC_INDEXCST2 1175 +#define IXTRC_GLOBAL_LIST 1176 +#define IXTRC_LESSER_OR_EQ 1177 +#define IXTRC_INDEXLOCAL0 1178 +#define IXTRC_RIGHT 1179 +#define IXTRC_INDEXLOCAL1 1180 +#define IXTRC_LEFT 1181 +#define IXTRC_INDEXLOCAL2 1182 +#define IXTRC_EXPR_INPUT 1183 +#define IXTRC_INDEXPR0 1184 +#define IXTRC_UPDATE_EXP 1185 +#define IXTRC_INTERP 1186 +#define IXTRC_INDEXPR1 1187 +#define IXTRC_TERM_CB 1188 +#define IXTRC_INDEXPR2 1189 +#define IXTRC_CHANGE_EXPR 1190 +#define IXTRC_SA_AST 1191 +#define IXTRC_SA_RSNAVIGATOR 1193 +#define IXTRC_FUNC_CB 1194 +#define IXTRC_FULL_EXPR 1195 +#define IXTRC_APPLY 1196 +#define IXTRC_SHORTEXPR 1197 +#define IXTRC_CONTROL_STRUC 1198 +#define IXTRC_TYPIFICATION 1199 +#define IXTRC_DATA_TABLE 1200 +#define IXTRC_TERM 1201 +#define IXTRC_EDIT_DATA 1202 +#define IXTRC_DATAMODE 1203 +#define IXTRC_VIEW_OSS_NAME 1204 +#define IXTRC_NAME1 1205 +#define IXTRC_ADDRESS 1206 +#define IXTRC_NAME3 1207 +#define IXTRC_SUBADDRESS 1208 +#define IXTRC_NAME4 1209 +#define IXTRC_FILE_VERSION_PROMT 1210 +#define IXTRC_NAME5 1211 +#define IXTRC_START_PAGE 1212 +#define IXTRC_NAME6 1213 +#define IXTRC_LOAD_PYTHON 1214 +#define IXTRC_RSFORM 1215 +#define IXTRC_DISABLE_AUTOLANG 1215 +#define IXTRC_RSMODEL 1216 +#define IXTRC_OSS 1217 +#define IXTRC_DONT_PROMT 1218 +#define IXTRC_NEW_DOCUMENT 1219 +#define IXTRC_START_HELP 1220 +#define IXTRC_CHANGE_LOG 1221 +#define IXTRC_OPEN_DOC 1222 +#define IXTRC_MEMO 1223 +#define IXTRC_MFCLINK1 1224 +#define IXTRC_SAMPLES 1225 +#define IXTRC_CBTYPIFICATION 1226 +#define IXTRC_CBTERMIN 1227 +#define IXTRC_CBCOMMENT 1228 +#define IXTRC_CBINTERPRET 1229 +#define IXTRC_CBFORMEXPR 1230 +#define IXTRC_AC_LIST1 1231 +#define IXTRC_DOUBLESQR 1232 +#define IXTRC_CST_TERM_FORM_EDIT 1233 +#define IXTRC_AC_LIST2 1234 +#define IXTRC_AC_LABELSLIST 1235 +#define IXTRC_SET_WORDREF_EDIT 1236 +#define IXTRC_WORDREF_CONTROL 1237 +#define IXTRC_WSLIST 1239 +#define IXTRC_PYTHONPATH 1240 +#define IXTRC_RSMODEL_SEARCH_TEXT 1241 +#define IXTRC_FLAG_BM 1242 +#define IXTRC_FLAG_RS 1243 +#define IXTRC_FLAG_TERM 1244 +#define IXTRC_ALLOW_EDIT 1245 +#define IXTRC_FLAG_TERM2 1246 +#define IXTRC_FLAG_RS2 1247 +#define IXTRC_FLAG_BM2 1248 +#define IXTRC_INDICATOR_LANGUAGE 1250 +#define IXTRC_INDICATOR_RUSSIAN 1251 +#define IXTRC_INDICATOR_ENGLISH 1252 +#define IXTRC_INDICATOR_GOTHIC 1253 +#define IXTRC_TRIPLET_CB 1257 +#define IXTRC_FORMULA 1258 +#define IXTRC_LINK_TERM 1259 +#define IXTRC_LINK_DEFINITION 1260 +#define IXTRC_LINK_ALL 1261 +#define IXTRC_EXPORT_CSV_CB 1262 +#define IXTRD_ABOUTBOX 2048 +#define IXTRD_VIEW_RSFORM 2049 +#define IXTRD_CST_EDIT_DATA 2050 +#define IXTRD_VIEW_TERMTREE 2051 +#define IXTRD_EDIT_COMMENT 2052 +#define IXTRD_NEW_TRSDOC 2053 +#define IXTRD_CST_RENAME 2054 +#define IXTRD_NEW_OSSDOC 2055 +#define IXTRD_OSS_OPERATIONS 2056 +#define IXTRD_EXPORT_SCHEMA 2057 +#define IXTRD_VIEW_PICT 2058 +#define IXTRD_OPTION_OSS 2059 +#define IXTRD_SYNT_OPERANDS 2060 +#define IXTRD_SYNT_MAPTABLE 2061 +#define IXTRD_SYNT_NAMES 2062 +#define IXTRD_OPTION_ANALYZER 2063 +#define IXTRD_GENERATE_FUNC 2064 +#define IXTRD_GENERATE_TERM 2065 +#define IXTRD_GENERATE_TERM_STRUC 2066 +#define IXTRD_OPTION_MODEL 2068 +#define IXTRD_OPTION_APPLICATION 2069 +#define IXTRD_VIEW_RSMODEL 2070 +#define IXTRD_CST_EDIT_MODEL 2071 +#define IXTRD_EDIT_FILENAME 2072 +#define IXTRD_EDIT_HYPERLINK 2073 +#define IXTRD_NEW_FILE 2074 +#define IXTRD_START_PAGE 2075 +#define IXTRD_AUTOCOMPLETE 2076 +#define IXTRD_CST_CHANGE_TERM_FORM 2077 +#define IXTRD_CST_SET_CHANGING_WORD_TEXT 2078 +#define IXTRD_CST_SET_CHANGING_WORD_REF 2079 +#define IXTRD_EDIT_TERM 2080 +#define IXTRD_WORKSHEET 2081 +#define IXTRS_LEX_EOL 3000 +#define IXTRE_RSMODEL_TYPIFICATION 3001 +#define IXTRS_LEX_UNKNOWN_SYM 3005 +#define IXTRE_RSMODEL_DATA 3006 +#define IXTRE_CST_INSERT 3007 +#define IXTRS_OSS_RUN_PARENT 3008 +#define IXTRE_EXT1_FILE 3009 +#define IXTRE_RENAME_NOOP 3010 +#define IXTRS_DELCST_USED_IN_OPS 3011 +#define IXTRS_PROMT_MERGE_DATA 3012 +#define IXTRS_DISCARD_SRC_CONFIRM 3013 +#define IXTRS_STATUS_UNKNOWN 3014 +#define IXTRS_STATUS_NORMAL 3015 +#define IXTRS_STATUS_ERROR 3016 +#define IXTRS_STATUS_READONLY 3017 +#define IXTRS_STATUS_CHECK 3018 +#define IXTRS_DEFAULT_TOOLTIP_DATA 3019 +#define IXTRE_IMPORT_TYPIF 3020 +#define IXTRE_PICT_NO_SRC 3021 +#define IXTRE_PICT_RENAME_OPENED 3022 +#define IXTRS_URL_CONFIRM 3024 +#define IXTRS_ERASE_SRC_CONFIRM 3025 +#define IXTRS_BROWSE_TITLE 3026 +#define IXTRS_TERMFUNC_FROM_TERM 3028 +#define IXTRS_TERM_FROM_TERMFUNC 3029 +#define IXTRS_RSMODEL_DATA_IMPORT_FAIL 3030 +#define IXTRS_RSMODEL_DATA_IMPORT_SUCCESS 3031 +#define IXTRE_CLIPBOARD_OPEN 3032 +#define IXTRE_CLIPBOARD_CLEAR 3033 +#define IXTRE_CLIPBOARD_COPY 3034 +#define IXTRE_DATA2EXCEL_FORMAT 3035 +#define IXTRE_EXCEL_OPENWB 3036 +#define IXTRS_DELCST_USED_IN_OSS 3037 +#define IXTRS_SRC_TYPE_TBA 3039 +#define IXTRE_TEMPLATE_NOT_FOUND 3040 +#define IXTRS_PICT_DONE 3041 +#define IXTRS_PICT_REDO 3042 +#define IXTRS_PICT_BROKEN 3043 +#define IXTRS_PICT_DEFINED 3044 +#define IXTRS_PICT_UNDEFINED 3045 +#define IXTRS_PICT_DEFAULT 3046 +#define IXTRS_PICT_BASIC 3047 +#define IXTRS_PROP_SAVE 3048 +#define IXTRS_PROPERTI_ONCANCELQUESTION 3049 +#define IXTRS_COPYRIGHT 3050 +#define IXTRE_INVALID_NAME 3051 +#define IXTRE_NAME_TAKEN 3052 +#define IXTRE_UNKNOWN_EXTENSION 3053 +#define IXTRE_NO_ARGS 3054 +#define IXTRE_NO_VAL 3055 +#define IXTRS_RSFORM_OK 3056 +#define IXTRS_RSMODEL_OK 3057 +#define IXTRE_EXPORT_TYPIF 3058 +#define IXTRE_IMPORT_EXCEL_HEADER 3059 +#define IXTRE_IMPORT_EXCEL_INVALID_DATA 3060 +#define IXTRS_DEL_CST_LOCAL_USE 3061 +#define IXTRS_PROPSHT_CAPTION 3062 +#define IXTRS_APP_PROPERTIES 3063 +#define IXTRS_SEARCH_NO_MATCH 3064 +#define IXTRS_ASK_REWRITE_FILE 3065 +#define IXTRS_PROPERTI_TITLE 3066 +#define IXTRE_OLE_INIT_FAILED 3067 +#define IXTRE_MOVECST 3068 +#define IXTRE_OSS_DIR_EXISTS 3069 +#define IXTRE_OSS_DIR_NOT_FOUND 3070 +#define IXTRS_REPORT_TYPIFICATION 3071 +#define IXTRE_OSS_ASSOSIATION 3072 +#define IXTRS_REPORT_VALUE_CLASS 3073 +#define IXTRS_IS_CHANGE_TRS_NAME 3074 +#define IXTRS_OSS_CANT_CREATE_ICON_LIST 3075 +#define IXTRE_PICT_FILE 3076 +#define IXTRE_OSS_DELETE_PICT 3077 +#define IXTRS_OSS_LOG_CANT_CREATE_ICON_LIST 3078 +#define IXTRS_OSS_SINTEZ_GO 3079 +#define IXTRE_OSS_RESULT_SAVE 3080 +#define IXTRE_LOG_ADD 3081 +#define IXTRE_EXPORT_WORD 3082 +#define IXTRS_CALCULATION_SUCCESS 3083 +#define IXTRS_TEXT_TOOLTIP_DEFAULT 3084 +#define IXTRS_EXP_TOOLTIP_DEFAULT 3085 +#define IXTRS_OP_NEW_TERM 3086 +#define IXTRS_SYNT_MERGE 3089 +#define IXTRS_SYNT_BM 3090 +#define IXTRS_SYNT_STRUCTURE 3091 +#define IXTRS_OP_NOT_DEF 3092 +#define IXTRS_OSS_CREATE_NEW_FILE 3093 +#define IXTRS_PICT_NAME_AT 3094 +#define IXTRS_OWER_MAXSLOI 3095 +#define IXTRE_OSS_UNARYOP 3096 +#define IXTRS_OSS_CANT_OPEN_PARENT 3097 +#define IXTRS_OSS_UNDEF_OP 3098 +#define IXTRS_OSS_UNDEF_OTGD 3099 +#define IXTRS_OSS_WRONG_PARENT 3100 +#define IXTRS_EXPORT_WORD_OK 3101 +#define IXTRE_OSS_SAVE_PICT 3102 +#define IXTRE_SINGLE_OSS 3103 +#define IXTRE_FILE_MOVE 3104 +#define IXTRS_LOG_TASK_NAME 3105 +#define IXTRS_LOG_TASK_STATE 3106 +#define IXTRS_CHANGE_OPTS_CAUTION 3107 +#define IXTRS_LOG_ERR_STATE 3108 +#define IXTRS_LOG_LOAD_FILE 3109 +#define IXTRS_LOG_ERR_LOAD_FILE 3110 +#define IXTRS_LOG_UNKNOW 3111 +#define IXTRS_PYTHON_CRASH_PROMPT 3112 +#define IXTRS_PYERR_NOLOAD 3113 +#define IXTRS_PYERR_NOCORE 3114 +#define IXTRE_FAILED_ADD_TERMIN 3115 +#define IXTRS_CANT_DELETE_TERMIN 3116 +#define IXTRE_DELETE_TERMIN 3117 +#define IXTRE_SYNT 3118 +#define IXTRS_INPUT_WORD 3119 +#define IXTRS_PICK_REF 3121 +#define IXTRE_TERMIN_INDEX 3122 +#define IXTRE_TERMIN_SWAP 3123 +#define IXTRE_RELATE_RS 3124 +#define IXTRE_OSS_SOURCE_UNACCESSIBLE 3125 +#define IXTRS_OPLABEL_MERGE 3126 +#define IXTRS_ERR_MOVE_CST 3127 +#define IXTRS_OPLABEL_SYNT 3128 +#define IXTRS_OPLABEL_UNDEF 3129 +#define IXTRS_PICTINFO_NO_ACCESS 3130 +#define IXTRS_SCC_INFO_COUNT 3135 +#define IXTRS_SCC_INFO 3136 +#define IXTRS_CASE_NOMN 3137 +#define IXTRS_CASE_GENT 3138 +#define IXTRS_CASE_DATV 3139 +#define IXTRS_CASE_ACCS 3140 +#define IXTRS_CASE_ABLT 3141 +#define IXTRS_CASE_LOCT 3142 +#define IXTRS_PLUR_SINGULAR 3143 +#define IXTRS_PLUR_PLURAL 3144 +#define IXTRS_CALC_TIME 3145 +#define IXTRS_GENDER_MASC 3146 +#define IXTRS_GENDER_FEMN 3147 +#define IXTRS_GENDER_NEUT 3148 +#define IXTRS_CASEQ_NOMN 3149 +#define IXTRS_CASEQ_GENT 3150 +#define IXTRS_CASEQ_DATV 3151 +#define IXTRS_CASEQ_ACCS 3152 +#define IXTRS_CASEQ_ABLT 3153 +#define IXTRS_CASEQ_LOCT 3154 +#define IXTRE_FUNC2TERM 3155 +#define IXTRE_WORD_APPL 3156 +#define IXTRS_EXPORTXL_SUCCESS 3157 +#define IXTRS_EXPORTXL_FAIL 3158 +#define IXTRE_UNARY_OP 3159 +#define IXTRS_REPORT_ERR_COUNT 3160 +#define IXTRS_REPORT_NORMALIZED_AST 3161 +#define IXTRS_REPORT_SET_VALUE 3162 +#define IXTRS_REPORT_VALUE 3163 +#define IXRE_EMPTY_TERMS 3164 +#define IXTRS_RSLOOP_FOUND 3192 +#define IXTRS_TERMFUNC_SUCCESS 3193 +#define IXTRE_HYPERLINK_FOLLOW 3194 +#define IXTRE_RENAME_FAIL 3195 +#define IXTRS_PICTINFO_TBA 3196 +#define IXTRS_OPTS_BROKEN 3197 +#define IXTRS_EXECUTE_OP_FAIL 3198 +#define IXTRS_DATA_ADD_BASE_ELEMENT 3199 +#define IXTRE_WORD_BOOKMARK_MISSING 3200 +#define IXTRS_CST_MOVE_INFO 3201 +#define IXTRS_EXECUTION_FAILED 3202 +#define IXTRS_FOLLOW_HYPERLINK 3203 +#define IXTRS_EDITING_CST 3204 +#define IXTRS_CAPTION_DEFAULT_FILE 3205 +#define IXTRS_SELECT_ALL 3206 +#define IXTRS_OSS_RUNALL_PROMPT 3209 +#define IXTRS_OSS_RUNALL_SUCCESS 3210 +#define IXTRE_CANNOT_SAVE_DATA 3211 +#define IXTRS_TYPE_STRUCTURE 3480 +#define IXTRS_TYPE_FUNCTION 3483 +#define IXTRS_USE_RADICAL 3485 +#define IXTRS_FILTER_ARGUMENT 3486 +#define IXTRS_FILTER_PARAM_ARITY 3487 +#define IXTRS_GLOBAL_NO_VALUE_CLASS 3488 +#define IXTRS_PROXY_AS_VALUE 3489 +#define IXTRS_GLOBAL_NO_AST 3490 +#define IXTRS_FUNCTION_CALL_INVALID 3491 +#define IXTRS_NO_ARITHMETIC 3492 +#define IXTRS_INCOMPATIBLE_TYPES 3493 +#define IXTRS_NO_ORDERING 3494 +#define IXTRS_PAR_SYNTHAXERROR 3500 +#define IXTRS_RS_CHECK_SUCCESS 3501 +#define IXTRS_PAR_FAILURE 3502 +#define IXTRS_TYPE_INCONSISTENT 3503 +#define IXTRS_PAR_EXPECTED_RP 3504 +#define IXTRS_PAR_EXPECTED_RC 3505 +#define IXTRS_PAR_QUANTDECL 3506 +#define IXTRS_PAR_IMPERATIVE 3507 +#define IXTRS_TYPE_UNKNOWN_FUNCTION 3511 +#define IXTRS_TYPE_FUNCTION_AS_GLOBAL 3512 +#define IXTRS_TYPE_NAME_UKNOWN 3515 +#define IXTRS_TYPE_NAME_DECLARED 3516 +#define IXTRS_TYPE_GLOBAL_NOTYPE 3517 +#define IXTRS_TYPE_CART 3518 +#define IXTRS_TYPE_WRONG_TYPE 3519 +#define IXTRS_TYPE_NAME_REDECLARED 3520 +#define IXTRS_VALUECHECK_FAILURE 3521 +#define IXTRS_TYPE_BOOL 3522 +#define IXTRS_TYPE_SET_OPERATOR 3523 +#define IXTRS_TYPE_CARD 3524 +#define IXTRS_TYPE_DEBOOL 3525 +#define IXTRS_TYPE_RED 3526 +#define IXTRS_TYPECHECK_FAILURE 3527 +#define IXTRS_TYPE_PR_ERROR 3529 +#define IXTRS_TYPE_BIGPR 3530 +#define IXTRS_TYPE_ENUMERATION 3531 +#define IXTRS_TYPE_DECLARE_CORTEGE 3532 +#define IXTRS_TYPE_NAME_SCOPE 3533 +#define IXTRS_TYPE_EL_WRONG_TYPE 3534 +#define IXTRS_TYPE_NAME_NOT_USED 3535 +#define IXTRS_VALUE_FAILURE 3537 +#define IXTRS_TYPE_FUNC_ARGNUM 3538 +#define IXTRS_TYPE_FUNC_WRONG_ARG 3539 +#define IXTRS_PAR_EXPECTED_VAR 3542 +#define IXTRS_VALUE_UNKNOWN_ERROR 3543 +#define IXTRS_VALUE_SUCCESS 3544 +#define IXTRS_VALUE_SET_LIMIT 3545 +#define IXTRS_VALUE_BOOL_LIMIT 3546 +#define IXTRS_VALUE_VAR_INCALC 3547 +#define IXTRS_VALUE_ITER_LIMIT 3548 +#define IXTRS_EXPORT_SUCCESS 3549 +#define IXTRS_OPEN_CLAIMED 3550 +#define IXTRE_OP_SELECT_BASIS 3551 +#define IXTRE_FOLDER_CREATE_FAIL 3552 +#define IXTRS_OSS_ARCH_SUCCESS 3553 +#define IXTRE_LOG_NOT_FOUND 3554 +#define IXTRE_OSS_PNG_FAIL 3555 +#define IXTRS_PICT_NONAME 3556 +#define IXTRS_COMMENT 3557 +#define IXTRS_CONVENTION 3558 +#define IXTRS_ERASE_PICT_FAIL 3559 +#define IXTRE_EDIT_OPT_NO_ARG 3560 +#define IXTRE_IMPORT_DOC_FAIL 3561 +#define IXTRS_BROKEN_OP 3562 +#define IXTRS_CCL_INIT_OP_FAIL 3563 +#define IXTRS_TERM_CREATE_SUCCESS 3564 +#define IXTRS_CAPTION_TERM 3565 +#define IXTRS_LABEL_IGNORE_RELATION 3566 +#define IXTRS_CAPTION_EQUATE 3567 +#define IXTRS_PAR_EXPECTED_ARGDECL 3569 +#define IXTRS_REPORT_AST 3570 +#define IXTRS_REPORT_NORMALIZED_EXPR 3571 +#define IXTRS_REPORT_BUG_PROMPT 3572 +#define IXTRS_VALUE_DEBOOL 3573 +#define IXTRS_REPORT_ITERATIONS 3574 +#define IXTRS_ITERATE_INFINITY 3575 +#define IXTRS_CORE_CORRECT 3576 +#define IXTRS_CORE_WARNING 3577 +#define IXTRS_CORE_INCORRECT 3578 +#define IXTRS_MODEL_CORRECT 3579 +#define IXTRS_MODEL_WARNING 3580 +#define IXTRS_MODEL_INCORRECT 3581 +#define IXTRS_TYPE_INTEGRAL 3582 +#define IXTRS_TYPE_BOOLEAN 3583 +#define IXTRS_VC_VALUE 3584 +#define IXTRS_VC_PROPERTY 3585 +#define IXTRS_VC_INVALID 3586 +#define IXTRS_YES 3587 +#define IXTRS_NO 3588 +#define IXTRS_DESCRIPTION_CORE 3592 +#define IXTRS_EMPTY_CST_FOUND 3593 +#define IXTRS_FORMULA_CYCLE_FOUND 3594 +#define IXTRS_REFERENCE_CYCLE_FOUND 3595 +#define IXTRS_SYNONYMS_FOUND 3596 +#define IXTRS_DESCRIPTION_MODEL 3597 +#define IXTRS_DESCRIPTION_REFERENCE 3598 +#define IXTRS_DESCRIPTION_DEPENDANT_WORD 3599 +#define IXTRS_DESCRIPTION_OPERATION 3600 +#define IXTRS_EXCEPTION_ON_SAVE 3601 +#define IXTRS_TITLE_TOOLBAR 6152 +#define IXTRS_TITLE_INSTOOL 6153 +#define IXTRS_TITLE_OSS 6154 +#define IXTRS_OSS_LOG_PROCES 6157 +#define IXTRS_TRSV_TOOLTIP_DEFAULT 6158 +#define IXTRE_FILE_NOT_FOUND 6159 +#define IXTRE_RENAME_UNKNOWN 6160 +#define IXTRS_DEFAULT_SAMPLES_DIR 6171 +#define IXTRS_DEFAULT_CS_OSS_DIR 6172 +#define IXTRS_RENAME_FILE_EXISTS 6173 +#define IXTRE_EQUATION_INVALID 6717 +#define IXTRE_EQUATION_ARGS 6718 +#define IXTRE_EQUATION_UNKNOWN 6719 +#define IXTRS_SRC_TYPE_TRS 6720 +#define IXTRE_DOC_FRAME 6772 +#define IXTRE_FILE_UNAVAILABLE 6773 +#define IXTRS_RENAME_SUCCESS 6774 +#define IXTRS_DRAW_UNDEFINED 6775 +#define IXTRS_DRAW_DEFINED 6776 +#define IXTRS_DRAW_DONE 6777 +#define IXTRS_DRAW_REDO 6778 +#define IXTRS_DRAW_BROKEN 6779 +#define IXTRS_DRAW_BASE 6780 +#define IXTRS_DRAW_HAS_FILE 6781 +#define IXTRS_VERSION_TEXT 6782 +#define IXTRS_REPORT_BUG_SUBJECT 6783 +#define IXTRS_REPORT_SUGGESTION 6784 +#define IXTRE_BROWSE_DLG 6786 +#define IXTRE_CANTLOADFONT 6787 +#define IXTRE_TEXT_METRICS 6788 +#define IXTRS_GENERATE_TERM 6789 +#define IXTRE_EMPTY_SHEMA 6790 +#define IXTRE_OSS_NOTSAVED 6791 +#define IXTRE_NOT_IMPLEMENTED 6792 +#define IXTRS_PROMT_RESET_FLAGS 6793 +#define IXTRE_DELETE_CST 6794 +#define IXTRE_DELETE_CST_PARTIAL 6795 +#define IXTRE_LIST_CLEAR 6796 +#define IXTRE_OP_APPLICABLE 6797 +#define IXTRE_SYNT_INCORRECT 6798 +#define IXTRE_SELECTION_EMPTY 6799 +#define IXTRE_RSFORM_OP_COUNT 6800 +#define IXTRE_REF_CANNOT_ADD 6801 +#define IXTRS_PROMT_ERASE_DATA 6802 +#define IXTRS_HEADER_NO 7001 +#define IXTRS_HEADER_NAME 7002 +#define IXTRS_HEADER_TERM 7003 +#define IXTRS_HEADER_TYPE 7004 +#define IXTRS_HEADER_CONVENTION 7006 +#define IXTRS_HEADER_TEXTDEF 7007 +#define IXTRS_HEADER_RSDEF 7008 +#define IXTRS_HEADER_CARD 7009 +#define IXTRS_HEADER_VALUE 7010 +#define IXTRS_HEADER_ARGUMENT 7011 +#define IXTRS_HEADER_EXPRESSION 7012 +#define IXTRS_HEADER_INTERPRETATION 7013 +#define IXTRS_HEADER_ID 7014 +#define IXTRS_HEADER_CONSTITUENTA 7015 +#define IXTRS_HEADER_PATH 7016 +#define IXTRS_HEADER_FILENAME 7017 +#define IXTRS_HEADER_SHORTNAME 7018 +#define IXTRS_HEADER_RS_FULL 7019 +#define IXTRS_FILTER_DEFAULT 7100 +#define IXTRS_FILTER_EXCEL 7101 +#define IXTRS_FILTER_MAIN 7102 +#define IXTRS_FILTER_OSS_PROMPT 7103 +#define IXTRS_PATH_MODEL_TEMPLATE 7201 +#define IXTRS_PATH_RSDOC_TEMPLATE 7202 +#define IXTRS_FILE_HELP 7204 +#define IXTRS_FILE_FAQ 7205 +#define IXTRS_FOLDER_SAMPLES 7206 +#define IXTRS_FILE_UPDATELOG 7207 +#define IXTRD_EXPORT_CSTGRAPH 7209 +#define IXTRD_EXPORT_MODEL 7210 +#define IXTRO_ZOOM_VISIBLE 10001 +#define IXTRO_SECTION_TRSVIEW 10002 +#define IXTRO_SECTION_MODEL 10003 +#define IXTRO_SECTION_OSS 10004 +#define IXTRO_RUN_AFTER_OK 10005 +#define IXTRO_SECTION_APPLICATION 10006 +#define IXTRO_OSS_LEGEND 10007 +#define IXTRO_TRSV_NAME_WIDTH 10008 +#define IXTRO_TRSV_EXP_WIDTH 10009 +#define IXTRO_TRSV_INTER_WIDTH 10010 +#define IXTRO_TRSV_TYPE_WIDTH 10011 +#define IXTRO_TRSV_COMMENT_WIDTH 10012 +#define IXTRO_SAMPLES_DIR 10014 +#define IXTRO_SAVEAS_PATH 10015 +#define IXTRO_OSS_SPLITTER 10016 +#define IXTRO_TRSV_DATAMODE 10017 +#define IXTRO_RSM_VAL_WIDTH 10018 +#define IXTRO_OSS_GRID 10019 +#define IXTRO_TRSV_EXPT_TERM 10021 +#define IXTRO_TRSV_EXPT_FORM 10022 +#define IXTRO_LOG_AUTO_OPEN 10024 +#define IXTRO_OSS_STOP_ERROR 10025 +#define IXTRO_TRSV_EXPT_INTER 10026 +#define IXTRO_TRSV_EXPT_COM 10027 +#define IXTRO_TRSV_SPLITTER_POS 10028 +#define IXTRO_TRSV_EXPT_TYPE 10029 +#define IXTRO_SECTION_ANALYZER 10030 +#define IXTRO_CST_AUTOCHECK 10031 +#define IXTRO_RSFORM_INDEXCST 10032 +#define IXTRO_RSFORM_INDEXLOCAL 10033 +#define IXTRO_RSFORM_INDEXPR 10034 +#define IXTRO_RSFORM_AUTOINDEX 10035 +#define IXTRO_SA_COLORPAR 10036 +#define IXTRO_SA_AST 10037 +#define IXTRO_SA_NAVIGATOR 10038 +#define IXTRO_APP_TOOLBAR 10039 +#define IXTRO_TRSV_TERM_WIDTH 10040 +#define IXTRO_TB_MAIN 10041 +#define IXTRO_TB_CST 10042 +#define IXTRO_TB_OSS 10043 +#define IXTRO_TB_STATUS 10044 +#define IXTRO_START_PAGE 10045 +#define IXTRO_PYSTART 10046 +#define IXTRO_PYPATH32 10047 +#define IXTRO_PYPATH64 10048 +#define IXTRO_PYCRASH 10049 +#define IXTRO_SECTION_TEXT 10050 +#define IXTRO_TXT_EDITREF 10051 +#define IXTRO_DISABLE_KEYBOARD 10052 +#define IXTRC_INSERT 32775 +#define IXTRC_INSERT_BASE_SET 32776 +#define IXTRC_INSERT_TERM 32777 +#define IXTRC_INSERT_AXIOM 32778 +#define IXTRC_INSERT_CONST_SET 32782 +#define IXTRC_INSERT_STUPEN_PRS 32783 +#define IXTRC_INSERT_RS 32784 +#define IXTRC_INSERT_STUPEN_PT 32785 +#define IXTRC_INSERT_THEOREMA 32787 +#define IXTRC_INSERT_FREE 32789 +#define IXTRC_OP_MERGE 32791 +#define IXTRC_SELECT_BASIS 32797 +#define IXTRC_OP_MAX_PART 32801 +#define IXTRC_OP_SELECT_BASIS 32802 +#define IXTRC_RESET_NAMES 32804 +#define IXTRC_DELETE_CST 32806 +#define IXTRC_EDIT_OPTIONS 32810 +#define IXTRC_OSS_DEL 32812 +#define IXTRC_OSS_ADD 32813 +#define IXTRC_OSS_ASSIGN_DOC 32818 +#define IXTRC_OSS_EDIT_DOC 32819 +#define IXTRC_OSS_OP_NEW 32820 +#define IXTRC_OSS_OP_RUN_SINGLE 32821 +#define IXTRC_OSS_OP_EDIT 32825 +#define IXTRC_OSS_SYNT_ALL 32834 +#define IXTRC_OSS_OP_RUN_ALL 32836 +#define IXTRC_OSS_ZOOM_OUT 32842 +#define IXTRC_OSS_ZOOM_IN 32843 +#define IXTRC_EXPORT_SCHEMA 32874 +#define IXTRC_SYNTHES 32881 +#define IXTRC_OSS_SHIFT_LEFT 32888 +#define IXTRC_OSS_SHIFT_RIGHT 32889 +#define IXTRC_TOOLBAR_OSS 32897 +#define IXTRC_SELECT_DEPENDENT 32912 +#define IXTRC_INSERT_FUNCTION 32916 +#define IXTRC_INSERT_PREDICATE 32917 +#define IXTRC_TERM_TO_FUNC 32919 +#define IXTRC_FUNC_TO_TERM 32921 +#define IXTRC_STRUCTURE_TO_TERMS 32923 +#define IXTRC_RESET_COLUMNS 32924 +#define IXTRC_RENAME 32925 +#define IXTRC_CONVERT_TO_RSFORM 32928 +#define IXTRC_FOLLOW_HLINK 32948 +#define IXTRC_EDIT_HLINK 32949 +#define IXTRC_OSS_ENABLE_GRID 32952 +#define IXTRC_RESET_OSSFLAG 32961 +#define IXTRC_SAVE_IMAGE 32962 +#define IXTRC_OSS_ENABLE_LEGEND 32967 +#define IXTRC_BUG_REPORT 32971 +#define IXTRC_MAIL_DEVELOPERS 32973 +#define IXTRC_AUTOCHECK 32974 +#define IXTRC_RELATION 32980 +#define IXTRC_EDITREF 32981 +#define IXTRC_CST_MERGING 32987 +#define IXTRC_MOVE_UP 32988 +#define IXTRC_MOVE_DOWN 32989 +#define IXTRC_RSNAVIGATOR 32992 +#define IXTRC_OSS_DISCARD_DOC 32993 +#define ID_Menu 32998 +#define IXTRC_OSS_OP_CHECK 32999 +#define IXTRC_EXPORT_GRAPH 33003 +#define IXTRC_EXPORT_OSS 33008 +#define AFX_IDS_APP_TITLE 0xE000 +#define IXTRC_INDICATOR_CAPS 0xE701 +#define IXTRC_INDICATOR_NUM 0xE702 +#define IXTRC_INDICATOR_SCRL 0xE703 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 7215 +#define _APS_NEXT_COMMAND_VALUE 33009 +#define _APS_NEXT_CONTROL_VALUE 1260 +#define _APS_NEXT_SYMED_VALUE 142 +#endif +#endif diff --git a/include/xtr/ExtSourceManager.h b/include/xtr/ExtSourceManager.h new file mode 100644 index 0000000..a22e0b4 --- /dev/null +++ b/include/xtr/ExtSourceManager.h @@ -0,0 +1,40 @@ +#pragma once + +namespace xtr { + +namespace doc { class RSFormDoc; } // namespace doc + +class ExtSourceManager final : public ccl::SourceManager { +public: + [[nodiscard]] bool TestDomain(const ccl::src::Descriptor& global, + const std::u8string& domain) const override; + + [[nodiscard]] ccl::src::Descriptor + Convert2Local(const ccl::src::Descriptor& global, + const std::u8string& domain) const override; + + [[nodiscard]] ccl::src::Descriptor + Convert2Global(const ccl::src::Descriptor& local, + const std::u8string& domain) const override; + + [[nodiscard]] ccl::src::Descriptor + CreateLocalDesc(ccl::src::SrcType type, + std::u8string localName) const override; + [[nodiscard]] ccl::src::Source* Find(const ccl::src::Descriptor& desc) override; + [[nodiscard]] ccl::src::Descriptor GetDescriptor(const ccl::src::Source& src) const override; + bool ChangeDescriptor(const ccl::src::Descriptor& desc, const ccl::src::Descriptor& newDesc) override; + + [[nodiscard]] ccl::src::Source* CreateNew(const ccl::src::Descriptor& desc) override; + [[nodiscard]] ccl::src::Source* Open(const ccl::src::Descriptor& desc) override; + void Close(ccl::src::Source& src) override; + bool SaveState(ccl::src::Source& src) override; + void Discard(const ccl::src::Descriptor& desc) override; + +private: + static const doc::RSFormDoc& RSCast(const ccl::src::Source& src); + static doc::RSFormDoc& RSCast(ccl::src::Source& src); + + [[nodiscard]] static std::u8string FixFilename(const std::u8string& name); +}; + +} // namespace xtr \ No newline at end of file diff --git a/include/xtr/Exteor.h b/include/xtr/Exteor.h new file mode 100644 index 0000000..42b2a4e --- /dev/null +++ b/include/xtr/Exteor.h @@ -0,0 +1,77 @@ +#pragma once + +#include "xtr/doc/DocumentManager.h" +#include "xtr/ExteorOptions.h" +#include "xtr/ui/ExteorFrame.h" +#include "xtr/ui/KeyboardHandler.h" +#include "xtr/dialog/StartPage.h" + +namespace xtr { + +//! Exteor Application +class ExteorApplication final : public CWinAppEx { + // NOTE: no static objects allowed in Application class - otherwise app crashes in debug builds +public: + struct Version { + CString text{}; + CString copyright{}; + CString id{}; + }; + Version version; + + std::vector cstClipboard{}; + +private: + std::unique_ptr docs; + + HANDLE mutex{}; + std::unique_ptr startPage{ nullptr }; + +public: + ExteorApplication(); + +private: + BOOL InitInstance() override; + int32_t ExitInstance() override; + + void LoadCustomState() override; + void SaveCustomState() override; + +public: + static doc::DocumentManager& Docs() noexcept; + static ui::ExteorFrame& MainFrame() noexcept; + + [[nodiscard]] CString GetModuleFolder() const; + + BOOL RemoveMRUItem(CString item); + +private: +DECLARE_MESSAGE_MAP() + afx_msg void OnAppAbout(); + afx_msg void OnStartPage(); + afx_msg void OpenHelp(); + afx_msg void OnBugReport(); + afx_msg void OnMailDevelopers(); + afx_msg void OnOpenOptions(); + +public: + afx_msg void OnFileNew(); + afx_msg void OnFileOpen(); + +private: + BOOL CheckIfAnotherExteorIsRunning() noexcept; + void FeedCommandLineToAnotherExteor() noexcept; + void DefaultInitApplication(); + BOOL InitVersion(); + BOOL InitVersionID(); + BOOL CreateMainFrame(); + BOOL InitControls(); + void CreateStartingLook(); + + void LoadOptions(); +}; + +// The one and only ExteorApplication object +extern ExteorApplication g_Exteor; // NOLINT + +} // namespace xtr \ No newline at end of file diff --git a/include/xtr/ExteorOptions.h b/include/xtr/ExteorOptions.h new file mode 100644 index 0000000..0634966 --- /dev/null +++ b/include/xtr/ExteorOptions.h @@ -0,0 +1,235 @@ +#pragma once + +#include "xtr/core/rslIndex.hpp" +#include "xtr/io/OptionsIO.hpp" + +namespace xtr { + +//! Abstract options section +class OptionsSection { + uint32_t sectionID; + CString registrySection{}; + CWinAppEx* application{ nullptr }; + +public: + virtual ~OptionsSection() = default; + OptionsSection(const OptionsSection&) = delete; + OptionsSection& operator=(const OptionsSection&) = delete; + OptionsSection(OptionsSection&&) noexcept = default; + OptionsSection& operator=(OptionsSection&&) noexcept = default; + + explicit OptionsSection(uint32_t sectionID) noexcept + : sectionID{ sectionID } {} + +public: + virtual void InitDefault() = 0; + virtual void LoadTable() = 0; + virtual BOOL SaveTable() = 0; + virtual BOOL CreateTable(CWinAppEx *pWinApp); + +protected: + using EntryID = uint32_t; + BOOL Save(EntryID entry, int32_t value); + BOOL Save(EntryID entry, CString value); + + void Load(EntryID entry, int32_t& output) const; + void Load(EntryID entry, CString& output) const; + + CString LoadHKLMRegistry(CString folder, CString keyName, CString defaultValue); + + template + BOOL SaveAs(EntryID entry, const Object& obj) { + return Save(entry, static_cast(obj)); + } + template + void LoadAs(EntryID entry, Object& output) { + Item result = static_cast(output); + Load(entry, result); + output = static_cast(result); + } +}; + +//! Application options +class GeneralOptions final : public OptionsSection { +public: + using SilentGuard = ccl::types::CounterGuard; + + CString pathSaveAs; // полный путь директории сохранения + CString pythonPath; // Путь к Python + + BOOL promptVersion; // Показывать сообщение при загрузка старых файлов + BOOL showStartPage; // Отображать стартовую страницу + BOOL disableAutoKeyboard; // Отключить автоматическое переключючение раскладки + + BOOL enablePython; // Загружать Python Module + BOOL pyCrashed; // Флаг креша Python + + CFont fontMath; // Математический шрифт (DejaVu Sans) + CFont fontMathComment; // Математический шрифт (DejaVu Sans) для комментов + CFont fontMathTT; // Математический шрифт (DejaVu Sans) для подсказок + CFont fontTable; // Математический шрифт (DejaVu Sans) для таблиц + CFont fontData; // Математический шрифт (DejaVu Sans) для данных + CFont fontTooltip; // Шрифт для всплывающих подсказок + CFont fontText; // Стандартный шрифт для текста + +private: + uint32_t silentCount{ 0 }; + +public: + GeneralOptions(); + +public: + void InitDefault() override; + void LoadTable() override; + BOOL SaveTable() override; + + [[nodiscard]] BOOL IsSilent() const noexcept { + return silentCount > 0; + } + [[nodiscard]] SilentGuard GuardSilence() noexcept { + return SilentGuard(silentCount); + } + +private: + BOOL CreateFonts(); + static BOOL InitializeFont(CFont& font, CString name, uint32_t size); +}; + +//! RSForm options +struct RSFormOptions final : OptionsSection { + BOOL inlineFunctionOnGenerate; // Генерировать полное выражение терма из терм-функции + + int32_t nameWidth; // Ширина колонки с именем + int32_t typeWidth; // Ширина колонки с типизацией + int32_t expWidth; // Ширина колонки с формальным выражением + int32_t termWidth; // Ширина колонки с термином выражением + int32_t interWidth; // Ширина колонки с интерпретацией + int32_t conventionWidth; // Ширина колонки с комментарием + + int32_t splitterPos; // Положение сплиттера + + io::SchemaOptions exportOptions; + +public: + RSFormOptions(); + +public: + void ResetTableWidth() noexcept; + void InitDefault() noexcept override; + void LoadTable() override; + BOOL SaveTable() override; +}; + +//! OSS options +struct ossOptions final : OptionsSection { + static constexpr auto zoomMin = 1U; + static constexpr auto zoomMax = 3U; + + int32_t zoom; // коэфициент уменьшения 1, 2, 3 + int32_t splitterPos; // Положение сплиттера + + BOOL runOpAfterEdit; + BOOL showGrid; + BOOL showLegend; + +public: + ossOptions(); + +public: + void InitDefault() noexcept override; + void LoadTable() override; + BOOL SaveTable() override; +}; + +//! RS parsing options +struct ParsingOptions final : OptionsSection { + BOOL autoCheck; // Проверять ФВ при изменении + BOOL colorBrackets; // Форматировать скобки цветом по уровню + BOOL showAST; // Отображать дерево разбора + BOOL enableNavigator; // Навигация по ФВ + index::IndexingParams indexing; // Параметры индексации + +public: + ParsingOptions(); + +public: + void InitDefault() noexcept override; + void LoadTable() override; + BOOL SaveTable() override; +}; + +//! RSModel options +struct ModelOptions final : OptionsSection { + BOOL m_DataMode; // Режим отображения данных интерпретации + + int32_t nameWidth; // Ширина колонки с именем + int32_t typeWidth; // Ширина колонки с типизацией + int32_t expWidth; // Ширина колонки с формальным выражением + int32_t valWidth; // Ширина колонки с мощностью интерпретации + int32_t termWidth; // Ширина колонки с термином выражением + int32_t interWidth; // Ширина колонки с интерпретацией + int32_t conventionWidth; // Ширина колонки с комментарием + + int32_t splitterPos; // Положение сплиттера + +public: + ModelOptions(); + +public: + void ResetTableWidth() noexcept; + void InitDefault() noexcept override; + void LoadTable() override; + BOOL SaveTable() override; +}; + +//! Text processing options +struct TextOptions final : OptionsSection { + BOOL editReference; + +public: + TextOptions(); + +public: + void InitDefault() noexcept override; + void LoadTable() override; + BOOL SaveTable() override; +}; + +//! Abstract options object +struct ApplicationOptions : CObject { + virtual BOOL LoadParameters(CWinAppEx* app) = 0; + virtual BOOL SaveParameters() = 0; + + BOOL Load(CWinAppEx* pApp); + BOOL Save(); +}; + +//! Exteor options +struct XTROptions final : ApplicationOptions { + RSFormOptions schema; + ossOptions oss; + GeneralOptions general; + ParsingOptions parsing; + ModelOptions model; + TextOptions texting; + +private: + XTROptions() = default; + +public: + [[nodiscard]] static XTROptions& Get() noexcept; + [[nodiscard]] static RSFormOptions& RS() noexcept { return Get().schema; } + [[nodiscard]] static ossOptions& OSS() noexcept { return Get().oss; } + [[nodiscard]] static GeneralOptions& App() noexcept { return Get().general; } + [[nodiscard]] static ParsingOptions& ParseRSL() noexcept { return Get().parsing; } + [[nodiscard]] static ModelOptions& Model() noexcept { return Get().model; } + [[nodiscard]] static TextOptions& Text() noexcept { return Get().texting; } + +public: + static void SaveWindowPlacement(const CWnd& wnd, CString entryName); + static BOOL LoadWindowPlacement(CWnd& wnd, CString entryName); + BOOL LoadParameters(CWinAppEx *pApp) override; + BOOL SaveParameters() override; +}; + +} // namespace xtr \ No newline at end of file diff --git a/include/xtr/cclDescriptor.h b/include/xtr/cclDescriptor.h new file mode 100644 index 0000000..1cb3d4f --- /dev/null +++ b/include/xtr/cclDescriptor.h @@ -0,0 +1,71 @@ +#pragma once + +#include "ccl/Operation.hpp" +#include "ccl/oss/Pict.hpp" + +//! Text descriptions of ccl entities for user +namespace xtr::info { + +enum class ErrorType : uint32_t { + UNKNOWN, + LEXER, + PARSER, + SEMANTIC, + VALUE, +}; + +enum class CoreStatus : uint8_t { + CORRECT, + WARNING, + INCORRECT +}; + +enum class ModelStatus : uint8_t { + CORRECT, + WARNING, + INCORRECT +}; + +[[nodiscard]] CoreStatus StatusOf(const ccl::semantic::RSCore& core); +[[nodiscard]] ModelStatus StatusOf(const ccl::semantic::RSModel& target); + +[[nodiscard]] CString ValueStatus(EntityUID target, const ccl::semantic::RSModel& model); + +[[nodiscard]] CString LabelBool(bool flag); +[[nodiscard]] CString Label(ccl::ops::Type type); +[[nodiscard]] CString Label(ccl::ops::Status status); +[[nodiscard]] CString Label(CoreStatus status); +[[nodiscard]] CString Label(ModelStatus status); +[[nodiscard]] CString Label(ccl::src::SrcType type); +[[nodiscard]] CString Label(ccl::lang::Grammem gram); +[[nodiscard]] CString Label(const ccl::rslang::ExpressionType* type); +[[nodiscard]] CString Label(ccl::rslang::ValueClass cls); + +[[nodiscard]] CString DrawableLabel(ccl::ops::Status status); + +[[nodiscard]] CString IndicatorFor(const ccl::semantic::RSCore& core); +[[nodiscard]] CString BasicDescriptionOf(const ccl::semantic::RSCore& core); +[[nodiscard]] CString DescriptionOf(const ccl::semantic::RSCore& core); +[[nodiscard]] CString DescriptionOf(ccl::lang::Grammem gram); + +[[nodiscard]] CString IndicatorFor(const ccl::semantic::RSModel& model); +[[nodiscard]] CString BasicDescriptionOf(const ccl::semantic::RSModel& model); +[[nodiscard]] CString DescriptionOf(const ccl::semantic::RSModel& model); + +[[nodiscard]] CString BasicDescriptionOf(ccl::oss::PictID pict, ccl::oss::OSSchema& oss); + +[[nodiscard]] CString DescriptionOf(const ccl::rslang::Auditor& analytics, BOOL showAST); +[[nodiscard]] CString DescriptionOf(const ccl::rslang::Interpreter& calculator, + const std::optional& result, + BOOL showAST); +[[nodiscard]] CString DescriptionOf(const ccl::lang::Reference& ref); +[[nodiscard]] CString DescriptionOf(ccl::oss::ossOperationsFacet& ops, ccl::oss::PictID pid); +[[nodiscard]] CString DescriptionOf(const ccl::StrSubstitutes& substitutes); + +[[nodiscard]] CString DescriptionOf(const ccl::rslang::ErrorLogger& log); +[[nodiscard]] CString DescriptionOf(const ccl::rslang::Error& error); +[[nodiscard]] CString Label(ErrorType type); + +[[nodiscard]] CString GenerateLoopStr(const ccl::semantic::RSCore& schema, const std::vector& loops); + +}// namespace xtr::info diff --git a/include/xtr/core/Encoder.h b/include/xtr/core/Encoder.h new file mode 100644 index 0000000..9e65547 --- /dev/null +++ b/include/xtr/core/Encoder.h @@ -0,0 +1,86 @@ +#pragma once + +namespace xtr::encode { + +//! Unicode math symbols enumerations +enum UTF8Codes : wchar_t { + US_LOGIC_NOT = 0xAC, //отрицание + US_CARTH = 0xD7, //декартово произведение + US_BOOL = 0x212C, //булеан + US_A = 0x03B1, //альфа + US_B = 0x03B2, //бэта + US_G = 0x03B3, //гамма + US_D = 0x03B4, //дельта + US_E = 0x03B5, //экпсилон + US_Z = 0x03B6, //зетта + US_H = 0x03B7, //эта + US_V = 0x03B8, //тэта + US_L = 0x03BB, //лямбда + US_M = 0x03BC, //мю + US_N = 0x03BD, //ню + US_X = 0x03BE, //кси + US_O = 0x03BF, //о + US_P = 0x03C0, //пи + US_R = 0x03C1, //ро + US_S = 0x03C3, //сигма + US_T = 0x03C4, //тау + US_Q = 0x03C5, //ипсилон + US_F = 0x03C6, //фи + US_C = 0x03C7, //хи + US_J = 0x03C8, //пси + US_W = 0x03C9, //омега + US_DIGIT_SUB0 = 0x2080, // 0 + US_DIGIT_SUB1 = 0x2081, // 1 + US_DIGIT_SUB2 = 0x2082, // 2 + US_DIGIT_SUB3 = 0x2083, // 3 + US_DIGIT_SUB4 = 0x2084, // 4 + US_DIGIT_SUB5 = 0x2085, // 5 + US_DIGIT_SUB6 = 0x2086, // 6 + US_DIGIT_SUB7 = 0x2087, // 7 + US_DIGIT_SUB8 = 0x2088, // 8 + US_DIGIT_SUB9 = 0x2089, // 9 + US_INTEGERS = 0x2102, //множество целых чисел + US_NATURALS = 0x2115, //множество натуральных чисел + US_REALS = 0x211D, //множество действительных чисел + US_IMPLICATION = 0x21D2, //импликация + US_LOGIC_EQUAL = 0x21D4, //тогда и только тогда + US_LOGIC_FORALL = 0x2200, //для любого + US_LOGIC_EXISTS = 0x2203, //существует + US_EMPTYSET = 0x2205, //пустое множество + US_ELEMENT = 0x2208, //принадлежность + US_NOTELEMENT = 0x2209, //не принадлежность + US_MINUS = 0x2212, //минус + US_INFINITY = 0x221E, //бесконечность + US_SET_UNION = 0x222A, //объединение + US_SET_SYMMINUS = 0x2206, //симметрическая разность + US_LOGIC_OR = 0x2228, //или + US_SET_INTERSECTION = 0x2229, //пересечение + US_NOTEQUAL = 0x2260, //не равно + US_GREATER_OR_EQ = 0x2265, //больше или равно + US_LESSER_OR_EQ = 0x2264, //меньше или равно + US_IDENTITY = 0x2261, //тождественно равно + US_SUBSET = 0x2282, //включение + US_NOTSUBSET = 0x2284, //не включение + US_SUBSET_OR_EQ = 0x2286 //нестрогое включение +}; + +constexpr bool IsGreek(const wchar_t uc) noexcept { + return uc >= US_A && uc <= US_W; +} + +constexpr bool IsIndex(const wchar_t uc) noexcept { + return + (uc >= US_DIGIT_SUB0 && uc <= US_DIGIT_SUB9) || + (uc >= '0' && uc <= '9'); +} + +bool IsCstName(wchar_t uc) noexcept; +bool IsAlphaNumber(wchar_t uc) noexcept; + +wchar_t Bulean2ToUnicodeChar(wchar_t ac); + +void EncodeToUnicode(CString& str); + +uint8_t Encode1251To866(uint8_t c) noexcept; + +} // namespace xtr::encode \ No newline at end of file diff --git a/include/xtr/core/PyCore.h b/include/xtr/core/PyCore.h new file mode 100644 index 0000000..e47c8c5 --- /dev/null +++ b/include/xtr/core/PyCore.h @@ -0,0 +1,116 @@ +#pragma once + +#include +#include + +// Note: forward declare basic object class for Python +struct _object; // NOLINT(bugprone-reserved-identifier, cert-dcl37-c, cert-dcl51-cpp) + +namespace cxxpython { + +//! PyObject wrapper +/*! + Uses Python ref counting +*/ +class Object { + _object* object; + +public: + ~Object() noexcept; + Object(const Object& obj2) noexcept; + Object& operator=(const Object& obj2) noexcept; + Object(Object&& obj2) noexcept; + Object& operator=(Object&& obj2) noexcept; + +private: + explicit Object(_object* objectIn) noexcept + : object{ objectIn } {} + +public: + explicit(false) Object(nullptr_t) noexcept // NOLINT(google-explicit-constructor, hicpp-explicit-conversions) + : object{ nullptr } {} + [[nodiscard]] static Object FromNew(_object* objectIn) noexcept; + [[nodiscard]] static Object FromBorrowed(_object* objectIn) noexcept; + +public: + [[nodiscard]] Object at(int index) const noexcept; + [[nodiscard]] constexpr bool operator!=(nullptr_t) const noexcept { return object != nullptr; } + [[nodiscard]] constexpr bool operator==(nullptr_t) const noexcept { return object == nullptr; } + + // Note: use with Python/C API only! + [[nodiscard]] constexpr _object* get() noexcept { return object; } + [[nodiscard]] constexpr _object* get() const noexcept { return object; } + +private: + void DecreaseRefCount() noexcept; +}; + +//! Convert object to string +std::string ToString(const Object& object); + +//! Convert object to long +long ToLong(const Object& object) noexcept; + +//! Convert object to bool +bool ToBool(const Object& object) noexcept; + +//! Python callable wrapper +class Callable { + Object func; + +public: + explicit(false) Callable(nullptr_t) noexcept // NOLINT(google-explicit-constructor, hicpp-explicit-conversions) + : func{ nullptr } {} + explicit Callable(_object* object) noexcept; + +public: + constexpr bool operator!=(nullptr_t) const noexcept { return func != nullptr; } + constexpr bool operator==(nullptr_t) const noexcept { return func == nullptr; } + + Object operator()() const noexcept; + Object operator()(const char* format, ...) const noexcept; +}; + +//! Python interpreter wrapper +class PyCore { + struct Module { + Object pyModule{ nullptr }; + Object pyDictionary{ nullptr }; + }; + + bool isRunning{ false }; + std::map modules{}; + +public: + PyCore(const PyCore&) = delete; + PyCore& operator=(const PyCore&) = delete; + +private: + ~PyCore(); + PyCore() = default; + +public: + static PyCore& Instance(); + +public: + //! Start Python interpreter from local path. + /*! + Requires: The argument should point to a zero-terminated character string + in static storage whose contents will not change + for the duration of the program’s execution + see https://docs.python.org/3/c-api/init.html#c.Py_SetPythonHome + */ + bool Start(const wchar_t* pyPath = nullptr) noexcept; + + //! Stop Python interpreter. + /*! + Requires: Every Object should be destroyed before calling PyCore.Stop() + */ + void Stop() noexcept; + [[nodiscard]] bool IsRunning() const noexcept; + + bool LoadModule(const std::string& moduleName, const std::string& pyFileName); + [[nodiscard]] Callable PyFunction(const std::string& moduleName, const std::string& funcName) const; +}; + +} // namespace cxxpython \ No newline at end of file diff --git a/include/xtr/core/PyTextProcessor.h b/include/xtr/core/PyTextProcessor.h new file mode 100644 index 0000000..adbf2f7 --- /dev/null +++ b/include/xtr/core/PyTextProcessor.h @@ -0,0 +1,21 @@ +#pragma once + +#include "ccl/lang/TextProcessor.h" + +namespace xtr::core { + +//! Python implementation for ccl::lang::TextProcessor +class PyTextProcessor final : public ccl::lang::TextProcessor { + bool isInit{ false }; + std::string moduleKey{}; + +public: + void InitModule(const std::string& key); + + [[nodiscard]] std::string Inflect(const std::string& target, const ccl::lang::Morphology& form) const override; + [[nodiscard]] std::string InflectDependant(const std::string& dependant, const std::string& main) const override; + [[nodiscard]] bool IsSubstr(const std::string& needle, + const std::string& haystack) const override; +}; + +} // namespace xtr::core \ No newline at end of file diff --git a/include/xtr/core/SelectableSet.h b/include/xtr/core/SelectableSet.h new file mode 100644 index 0000000..2706e23 --- /dev/null +++ b/include/xtr/core/SelectableSet.h @@ -0,0 +1,18 @@ +#pragma once + +namespace xtr::core { + +class SelectableSet { +protected: + ccl::SetOfEntities selection{}; + +public: + void ResetSelection() noexcept; + void Select(EntityUID uid); + void SetSelection(const SetOfEntities& newSelection); + + [[nodiscard]] const ccl::SetOfEntities& Selection() const noexcept { return selection; } + [[nodiscard]] BOOL IsSelected(EntityUID uid) const; +}; + +} // namespace xtr::core \ No newline at end of file diff --git a/include/xtr/core/rslIndex.hpp b/include/xtr/core/rslIndex.hpp new file mode 100644 index 0000000..a15e1e8 --- /dev/null +++ b/include/xtr/core/rslIndex.hpp @@ -0,0 +1,42 @@ +#pragma once + +namespace xtr::index { + +static constexpr auto UNICODE_SUB_0 = 0x2080; +static constexpr auto UNICODE_SUB_1 = 0x2081; +static constexpr auto UNICODE_SUB_2 = 0x2082; +static constexpr auto UNICODE_SUB_3 = 0x2083; +static constexpr auto UNICODE_SUB_4 = 0x2084; +static constexpr auto UNICODE_SUB_5 = 0x2085; +static constexpr auto UNICODE_SUB_6 = 0x2086; +static constexpr auto UNICODE_SUB_7 = 0x2087; +static constexpr auto UNICODE_SUB_8 = 0x2088; +static constexpr auto UNICODE_SUB_9 = 0x2089; + +//! Indecies formatting options enumeration +enum class Digits : uint32_t { + plainText = 1, + subText +}; + +//! Indexing symbol options +struct IndexingParams { + Digits global{ Digits::plainText }; + Digits local{ Digits::plainText }; + Digits operators{ Digits::subText }; +}; + +inline void FixLegacy(CString& input) { + input.Replace(UNICODE_SUB_0, '0'); + input.Replace(UNICODE_SUB_1, '1'); + input.Replace(UNICODE_SUB_2, '2'); + input.Replace(UNICODE_SUB_3, '3'); + input.Replace(UNICODE_SUB_4, '4'); + input.Replace(UNICODE_SUB_5, '5'); + input.Replace(UNICODE_SUB_6, '6'); + input.Replace(UNICODE_SUB_7, '7'); + input.Replace(UNICODE_SUB_8, '8'); + input.Replace(UNICODE_SUB_9, '9'); +} + +} // namespace xtr::index diff --git a/include/xtr/dialog/BasicDlg.h b/include/xtr/dialog/BasicDlg.h new file mode 100644 index 0000000..5a7933a --- /dev/null +++ b/include/xtr/dialog/BasicDlg.h @@ -0,0 +1,57 @@ +#pragma once + +#include "xtr/ui/BuffRichEdit.h" + +namespace xtr::dialog { + +//! Dialog: Edit comment +class EditComment : public CDialog { +public: + CString comment; + +private: + CString title; + ui::BuffRichEdit textControl; + +public: + EditComment(CString comment, CString title, CWnd* pParent = nullptr); + +private: + void DoDataExchange(CDataExchange* pDX) override; + BOOL OnInitDialog() override; +}; + +//! Dialog: Edit abstract text field +class EditString : public CDialog { +public: + CString resultStr; + +private: + CString m_Caption; + +public: + explicit EditString(CString initData, CString caption = {}, CWnd* pParent = nullptr); + +private: + void DoDataExchange(CDataExchange* pDX) override; + BOOL OnInitDialog() override; +}; + +//! Dialog: Edit hyperlink +class EditHyperlink : public CDialog { +public: + CString address; + CString subAddr; + +public: + explicit EditHyperlink(const ccl::oss::MediaLink& lnk, CWnd* pParent = nullptr); + +private: + void DoDataExchange(CDataExchange* pDX) override; + BOOL OnInitDialog() override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnBrowse(); +}; + +} // namespace xtr::dialog \ No newline at end of file diff --git a/include/xtr/dialog/CstDataPage.h b/include/xtr/dialog/CstDataPage.h new file mode 100644 index 0000000..9e09219 --- /dev/null +++ b/include/xtr/dialog/CstDataPage.h @@ -0,0 +1,94 @@ +#pragma once + +#include "xtr/doc/Documents.h" + +#include "xtr/ui/RSEdit.h" +#include "xtr/ui/TextEdit.h" + +namespace xtr::dialog { + +class EditConstituentaDlg; + +//! Edit constituenta attributes +class CstDataPage : public CPropertyPage { + EditConstituentaDlg& parent; + + CEdit cstNameCtrl; + ui::RSEdit expressionCtrl; + ui::TextEdit definitionCtrl; + ui::TextEdit termCtrl; + ui::RSEdit conventionCtrl; + ui::RSEdit typificationCtrl; + ui::RSEdit logCtrl; + + CString expression{}; + CString convention{}; + CString cstName{}; + CString typification{}; + CString term{}; + CString definition{}; + + CMFCButton allowEditCtrl; + + BOOL isModified{ FALSE }; + BOOL allowEdit{ TRUE }; + CComboBox namePicker; + CMFCButton evaluateBtn; + ui::RSEdit languageIndicator; + ccl::semantic::ParsingStatus parseStatus{}; + ccl::rslang::ValueClass valueStatus{}; + +public: + explicit CstDataPage(EditConstituentaDlg& parent); + +private: + void DoDataExchange(CDataExchange* pDX) override; + void LoadDataFrom(EntityUID target); + void SaveDataFor(EntityUID activeUID); + + BOOL OnInitDialog() override; + void InitControls(); + + BOOL OnApply() override; + void OnCancel() override; + void OnOK() override; + BOOL PreTranslateMessage(MSG* pMsg) override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnDestroy(); + afx_msg BOOL OnInsertBtn(uint32_t command); + afx_msg void OnChangeExpression(); + afx_msg void OnKillfocusExpression(); + afx_msg void OnAllowEdit(); + afx_msg void OnChange(); + afx_msg void OnChangeInterpretation(); + afx_msg void OnChangeComment(); + afx_msg void OnChangeName(); + afx_msg void OnChangeTerm(); + afx_msg void OnSetfocusName(); + afx_msg void OnSelchangeName(); + afx_msg void OnPrev(); + afx_msg void OnNext(); + afx_msg void OnHelpInput(); + afx_msg void OnAnalyse(); + afx_msg void OnCalculate(); + afx_msg void OnSimpleSyntax(); + +private: + std::tuple GetAnalyseExpr() const; + + void UpdateStatus(ccl::semantic::ParsingStatus status, ccl::rslang::ValueClass vclass); + void SetModified(BOOL bChanged = TRUE); + BOOL IsModified() const noexcept; + + void RunAutocheck(); + + void ClearSyntaxWindow(); + void UpdateFormat(); + void InitCstNameList(); + void UpdateStatusBar(); + + void Analyse(); +}; + +} // namespace xtr::dialog \ No newline at end of file diff --git a/include/xtr/dialog/CstRenameDialog.h b/include/xtr/dialog/CstRenameDialog.h new file mode 100644 index 0000000..0120c0f --- /dev/null +++ b/include/xtr/dialog/CstRenameDialog.h @@ -0,0 +1,31 @@ +#pragma once + +namespace xtr::dialog { + +//! Dialog: Rename constituent +class CstRename final : public CDialog { +public: + EntityUID target; + CString oldName; + CString newName{ oldName }; + BOOL doUpdateExpr{ TRUE }; + +private: + const ccl::semantic::RSCore& core; + CComboBox nameCtrl; + +public: + CstRename(const ccl::semantic::RSCore& core, EntityUID target, CWnd* pParent = nullptr); + +private: + void DoDataExchange(CDataExchange* pDX) override; + BOOL OnInitDialog() override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnCbnSelchangeNameCb(); + +private: + void InitCstNameList(); +}; + +} // namespace xtr::dialog \ No newline at end of file diff --git a/include/xtr/dialog/EditConstituenta.h b/include/xtr/dialog/EditConstituenta.h new file mode 100644 index 0000000..b747e25 --- /dev/null +++ b/include/xtr/dialog/EditConstituenta.h @@ -0,0 +1,49 @@ +#pragma once + +#include "xtr/doc/RSFacade.h" + +#include "xtr/dialog/CstDataPage.h" +#include "xtr/dialog/RSModelPage.h" + +namespace xtr::dialog { + +//! Dialog: Edit constituenta +class EditConstituentaDlg final : public CPropertySheet { +public: + EntityUID activeUID{}; + doc::RSFacade* editor{ nullptr }; + +private: + std::unique_ptr m_CstPage{ nullptr }; + std::unique_ptr m_ModelPage{ nullptr }; + std::unique_ptr m_Menu{ nullptr }; + +public: + ~EditConstituentaDlg() override; + EditConstituentaDlg(doc::RSFacade& editor, EntityUID activeUID, CWnd* pParentWnd = nullptr); + +private: + BOOL OnInitDialog() override; + void CreateMenu(); + void FixWindowSize(); + +public: + void StepNext(); + void StepPrev(); + +private: + BOOL PreTranslateMessage(MSG* pMsg) override; + [[nodiscard]] static BOOL IsControlAndSPressed(const WPARAM& key) noexcept; + [[nodiscard]] static BOOL IsControlAndEnterPressed(const WPARAM& key) noexcept; + +DECLARE_MESSAGE_MAP() + afx_msg void OnInitMenuPopup(CMenu* pMenu, uint32_t nIndex, BOOL bSysMenu); + afx_msg BOOL OnInsertCst(uint32_t command); + afx_msg BOOL OnCommandRun(uint32_t command); + afx_msg void OnUpdateCommandUI(CCmdUI* pCmdUI); + +private: + void UpdateMenuState(CMenu& menu); +}; + +} // namespace xtr::dialog \ No newline at end of file diff --git a/include/xtr/dialog/ExportCstGraphDlg.h b/include/xtr/dialog/ExportCstGraphDlg.h new file mode 100644 index 0000000..24b4eda --- /dev/null +++ b/include/xtr/dialog/ExportCstGraphDlg.h @@ -0,0 +1,28 @@ +#pragma once + +#include "xtr/doc/FileTypes.h" +#include "xtr/io/OptionsIO.hpp" + +namespace xtr::dialog { + +class ExportCstGraphDlg final : public CDialog { +public: + FileType exportType{ FileType::txt }; + io::CstGraphOptions options{ io::LinkType::formula, FALSE }; + +private: + BOOL exportCSV{ false }; + +public: + explicit ExportCstGraphDlg(CWnd* pParent = nullptr); + +private: + void DoDataExchange(CDataExchange* pDX) override; + DECLARE_MESSAGE_MAP() + +private: + [[nodiscard]] int32_t GetLinkType() const noexcept; // NOLINT(bugprone-exception-escape) + void SetLinkType(int32_t type) noexcept; +}; + +} // namespace xtr::dialog \ No newline at end of file diff --git a/include/xtr/dialog/ExportModel.h b/include/xtr/dialog/ExportModel.h new file mode 100644 index 0000000..01dc0c1 --- /dev/null +++ b/include/xtr/dialog/ExportModel.h @@ -0,0 +1,22 @@ +#pragma once + +#include "xtr/doc/FileTypes.h" + +namespace xtr::dialog { + +class ExportModel final : public CDialog { +public: + FileType exportType{ FileType::docx }; + +private: + int32_t typeRadio{}; + +public: + explicit ExportModel(CWnd* pParent = nullptr); + DECLARE_MESSAGE_MAP() + +private: + void DoDataExchange(CDataExchange* pDX) override; +}; + +} // namespace xtr::dialog \ No newline at end of file diff --git a/include/xtr/dialog/ExportSchema.h b/include/xtr/dialog/ExportSchema.h new file mode 100644 index 0000000..ae4d6fd --- /dev/null +++ b/include/xtr/dialog/ExportSchema.h @@ -0,0 +1,26 @@ +#pragma once + +#include "xtr/doc/FileTypes.h" +#include "xtr/io/OptionsIO.hpp" + +namespace xtr::dialog { + +class ExportSchema final : public CDialog { +public: + FileType exportType{ FileType::docx }; + io::SchemaOptions options{}; + +private: + int32_t typeRadio{}; + +public: + ~ExportSchema() override; + explicit ExportSchema(CWnd* pParent = nullptr); + + DECLARE_MESSAGE_MAP() + +private: + void DoDataExchange(CDataExchange* pDX) override; +}; + +} // namespace xtr::dialog \ No newline at end of file diff --git a/include/xtr/dialog/Function2Term.h b/include/xtr/dialog/Function2Term.h new file mode 100644 index 0000000..989e91b --- /dev/null +++ b/include/xtr/dialog/Function2Term.h @@ -0,0 +1,65 @@ +#pragma once + +#include "xtr/ui/RSEdit.h" +#include "xtr/ui/RSListCtrl.h" +#include "xtr/doc/RSFacade.h" + +namespace xtr::dialog { + +//! Dialog: Create RSTerm from RSTerm-Function +class Func2Term final : public CDialog { + struct ValuesHeader; + struct ArgsHeader; + +public: + VectorOfEntities addedCst{}; + CString expression; + CString textRef; + +private: + doc::RSFacade& editor; + + EntityUID activeUID; + CString activeName; + CString inputExpr; + + ui::RSEdit inputCtrl{}; + ui::RSEdit expressionCtrl{}; + ui::RSEdit definitionCtrl{}; + ui::RSListCtrl argsCtrl{}; + ui::RSListCtrl valuesCtrl{}; + CComboBox namesCB{}; + + BOOL doInline; + +public: + Func2Term(doc::RSFacade& editor, EntityUID startID, CWnd* pParent = nullptr); + ~Func2Term() override; + +private: + void DoDataExchange(CDataExchange* pDX) override; + BOOL OnInitDialog() override; + void InitControls(); + void InitHeaders(); + void InitCstNameList(); + void OnOK() override; + BOOL PreTranslateMessage(MSG* pMsg) override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnChangeFunction(); + afx_msg void OnBnClickedUpdateExp(); + afx_msg void OnBnClickedLeft(); + afx_msg void OnBnClickedApply(); + afx_msg void OnDblClickArgument(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnSelectArg(NMHDR* pNMHDR, LRESULT* pResult); + +private: + std::optional AddTerm(); + + void UpdateValueList(); + void UpdateUI(); + void Clear(); + void InputArgs(); +}; + +} // namespace xtr::dialog \ No newline at end of file diff --git a/include/xtr/dialog/GenerateStructure.h b/include/xtr/dialog/GenerateStructure.h new file mode 100644 index 0000000..009eaad --- /dev/null +++ b/include/xtr/dialog/GenerateStructure.h @@ -0,0 +1,76 @@ +#pragma once + +#include "xtr/ui/BuffRichEdit.h" +#include "xtr/ui/RSEdit.h" +#include "xtr/ui/RSListCtrl.h" +#include "xtr/doc/RSFacade.h" + +namespace xtr::dialog { + +//! Dialog: Create RSTerms from Typification +class Structure2Terms final : public CDialog { + struct ArgsHeader; + struct GlobalsHeader; + +public: + VectorOfEntities addedCst{}; + +private: + doc::RSFacade& editor; + + EntityUID activeUID{}; + CString activeName; + CString inputExpr; + CString m_Interp; + + ui::RSEdit inputCtrl{}; + ui::BuffRichEdit textCtrl{}; + ui::RSListCtrl globalsCtrl{}; + ui::RSListCtrl argsCtrl{}; + CComboBox nameCtrl{}; + +public: + Structure2Terms(doc::RSFacade& editor, EntityUID startID, CWnd* pParent = nullptr); + +private: + void DoDataExchange(CDataExchange* pDX) override; + BOOL OnInitDialog() override; + void InitControls(); + void InitHeaders(); + void InitCstNameList(); + void OnOK() override; + BOOL PreTranslateMessage(MSG* pMsg) override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnSelchangeTermCb(); + afx_msg void OnBnClickedRight(); + afx_msg void OnBnClickedLeft(); + afx_msg void OnBnClickedApply(); + + afx_msg void OnDblClickList(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnItemActivateArgList(NMHDR *pNMHDR, LRESULT *pResult); + +private: + void UpdateUI(); + void InputArguments(); + void Clear(); + int AddTerms(); +}; + +//! Dialog: Edit text definition +class GetInterpDialog final : public CDialog { +public: + CString textDef; + +private: + ui::BuffRichEdit input; + +public: + explicit GetInterpDialog(CString text, CWnd* pParent = nullptr); + +private: + BOOL OnInitDialog() override; + void DoDataExchange(CDataExchange* pDX) override; +}; + +} // namespace xtr::dialog \ No newline at end of file diff --git a/include/xtr/dialog/ImportWSDialog.h b/include/xtr/dialog/ImportWSDialog.h new file mode 100644 index 0000000..f6ef7b5 --- /dev/null +++ b/include/xtr/dialog/ImportWSDialog.h @@ -0,0 +1,24 @@ +#pragma once + +namespace xtr::dialog { + +class ImportWSDialog final : public CDialog { +public: + int32_t selection{ 0 }; + +private: + std::vector m_List{}; + CListBox m_ListControl{}; + +public: + explicit ImportWSDialog(std::vector wsList, CWnd* pParent = nullptr); + +private: + void DoDataExchange(CDataExchange* pDX) override; + BOOL OnInitDialog() override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnBnClickedOk(); +}; + +} // namespace xtr::dialog \ No newline at end of file diff --git a/include/xtr/dialog/InsertCstDlg.h b/include/xtr/dialog/InsertCstDlg.h new file mode 100644 index 0000000..10437df --- /dev/null +++ b/include/xtr/dialog/InsertCstDlg.h @@ -0,0 +1,44 @@ +#pragma once + +namespace xtr::dialog { + +//! Dialog: Select constituenta from typification +class InsertCstDlg final : public CDialog { +public: + CString cstName{}; + +private: + const ccl::semantic::RSCore& context; + CListBox pickerControl{}; + + enum State : uint8_t { + DS_DEFAULT = 0, + DS_CSTS, + }; + State state{ DS_DEFAULT }; + + CPoint position{}; + CString hint{}; + + std::vector typifications{}; + CString choice{}; + +public: + InsertCstDlg(const ccl::semantic::RSCore& context, CPoint pos, + CString hint, CWnd* pParent = nullptr); + +private: + BOOL OnInitDialog() override; + void DoDataExchange(CDataExchange* pDX) override; + BOOL PreTranslateMessage(MSG* pMsg) override; + +private: + void FitDialogSize(); + void OnSelectTyping(); + void OnSelectCst(); + + void UpdateContextNameList(); + void UpdateTypingNameList(); +}; + +} // namespace xtr::dialog \ No newline at end of file diff --git a/include/xtr/dialog/NewDocument.h b/include/xtr/dialog/NewDocument.h new file mode 100644 index 0000000..58cab26 --- /dev/null +++ b/include/xtr/dialog/NewDocument.h @@ -0,0 +1,69 @@ +#pragma once + +#include "xtr/ui/ElementShell.h" + +namespace xtr::dialog { + +//! Dialog: New document +class NewDocument final : public CDialog { +public: + NewDocument(); + +DECLARE_MESSAGE_MAP() + afx_msg void OnOSS(); + afx_msg void OnRSModel(); + afx_msg void OnRSForm(); +}; + +//! Dialog: New RSForm or RSModel +class NewRSForm final : public CDialog { +public: + CString newTitle; + CString newAlias; + +private: + CString title; + + ui::CstPicker aliasCB; + ui::CstPicker titleCB; + +public: + explicit NewRSForm(CString title, CWnd* pParent = nullptr); + +private: + void DoDataExchange(CDataExchange* pDX) override; + BOOL OnInitDialog() override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnChange(); + + void DDV_Names(); +}; + +//! Dialog: New OSS +class NewOSS final : public CDialog { +public: + CString ossName; + CString fullPath; + +private: + BOOL pathModified{ TRUE }; + +public: + explicit NewOSS(CWnd* pParent = nullptr); + +protected: + void DoDataExchange(CDataExchange* pDX) override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnBrowse(); + afx_msg void OnAccept(); + afx_msg void OnChangeOssName(); + afx_msg void OnChangeOssPath(); + afx_msg void OnBnClickedCancel(); + +private: + void ShowBrowseDlg(); +}; + +} // namespace xtr::dialog \ No newline at end of file diff --git a/include/xtr/dialog/OpSyntGUI.h b/include/xtr/dialog/OpSyntGUI.h new file mode 100644 index 0000000..ca974f2 --- /dev/null +++ b/include/xtr/dialog/OpSyntGUI.h @@ -0,0 +1,169 @@ +#pragma once + +#include "xtr/doc/RSFormDoc.h" +#include "xtr/ui/ElementShell.h" + +namespace xtr::dialog { + +//! Synthesis options dialog +class SynthesUI : public CPropertySheet { + class OperandsPage; + class OptionsPage; + class ConfirmPage; + +public: + BOOL ossModeOn; + ccl::ops::Type opType; + + CString title{}; + CString alias{}; + + ccl::ops::EquationOptions equations{}; + const ccl::semantic::RSForm* operand1{ nullptr }; + const ccl::semantic::RSForm* operand2{ nullptr }; + +private: + std::unique_ptr operandsPage; + std::unique_ptr optionsPage; + std::unique_ptr confirmationPage; + +public: + explicit SynthesUI(ccl::ops::Type type, BOOL fromOSS = FALSE, CWnd* pWndParent = nullptr); + +public: + [[nodiscard]] BOOL IsCorrect() const; + +private: + BOOL PreTranslateMessage(MSG* pMsg) override; +}; + +//! DialogPage: Choose operands +class SynthesUI::OperandsPage final : public CPropertyPage { + struct OperandsHeader; + + SynthesUI& parentSht; + + ui::RSListCtrl firstOperandList{}; + ui::RSListCtrl secondOperandList{}; + + CString firstOperand{}; + CString secondOperand{}; + +public: + explicit OperandsPage(SynthesUI& parent); + +private: + void DoDataExchange(CDataExchange* pDX) override; + BOOL OnInitDialog() override; + void InitControls(); + void InitHeaders(); + void InputData(); + +private: + BOOL OnSetActive() override; + LRESULT OnWizardNext() override; + + DECLARE_MESSAGE_MAP() + afx_msg void OnChangeOperands(NMHDR* pNMHDR, LRESULT* pResult); + +private: + [[nodiscard]] static int32_t TypeToRadio(ccl::ops::Type type) noexcept; + [[nodiscard]] static ccl::ops::Type RadioToType(int32_t radio) noexcept; + + void DDVNextBtn(int32_t nItem1, int32_t nItem2); + + [[nodiscard]] static doc::RSFormDoc* GetTRSDocFromCList(const ui::RSListCtrl& lc); + static void UpdateDocList(ui::RSListCtrl& lc, + const doc::RSFormDoc* docExclude = nullptr); +}; + +//! DialogPage: Setup equation options +class SynthesUI::OptionsPage final : public CPropertyPage { + struct ArgHeader; + + CButton operand1Btn{}; + CButton operand2Btn{}; + CButton equalsBtn{}; + + ui::RSListCtrl operand2List{}; + ui::RSListCtrl operand1List{}; + + ui::EquationsRSLC equationsCtrl{}; + + BOOL basic1Flag{ TRUE }; + BOOL structure1Flag{ TRUE }; + BOOL term1Flag{ TRUE }; + BOOL basic2Flag{ TRUE }; + BOOL structure2Flag{ TRUE }; + BOOL term2Flag{ TRUE }; + + SynthesUI& parentSht; + +public: + explicit OptionsPage(SynthesUI& parent); + +private: + void DoDataExchange(CDataExchange* pDX) override; + BOOL OnInitDialog() override; + void InitHeaders(); + +private: + BOOL OnSetActive() override; + LRESULT OnWizardNext() override; + + DECLARE_MESSAGE_MAP() + afx_msg void OnIn1(); + afx_msg void OnIn2(); + afx_msg void OnIn3(); + afx_msg void OnChange(); + afx_msg void OnDblClickList(NMHDR* pNMHDR, LRESULT* pResult); + +private: + static CString AskForTerm(CString initial); + + void DDV_Buttons(); + + void AddPair(ccl::ops::Equation::Mode type); + void RemovePair(); + + void UpdateCstLists(); + void FillCstOfType(int32_t list1Or2, ccl::semantic::CstType type, const SetOfEntities& ignoreList); + static void FillCstInCL(ui::RSListCtrl& lc, const ccl::semantic::RSForm& schema, + int32_t nameCol, int32_t termCol, + ccl::semantic::CstType type, const SetOfEntities& ignoreList); +}; + +//! DialogPage: Confirm options +class SynthesUI::ConfirmPage : public CPropertyPage { +public: + CString operation{}; + CString firstOperand{}; + CString secondOperand{}; + +private: + ui::EquationsRSLC equationsCtrl; + ui::CstPicker shortNameCtrl; + ui::CstPicker fullNameCtrl; + + SynthesUI& parentSht; + +public: + explicit ConfirmPage(SynthesUI& parent); + +private: + void DoDataExchange(CDataExchange* pDX) override; + BOOL OnInitDialog() override; + void InitControls(); + +private: + BOOL OnSetActive() override; + + DECLARE_MESSAGE_MAP() + afx_msg void OnChange(); + afx_msg void OnComboChanged(); + +private: + void DDV_Names(); +}; + +} // namespace xtr::dialog \ No newline at end of file diff --git a/include/xtr/dialog/OptionsDialog.h b/include/xtr/dialog/OptionsDialog.h new file mode 100644 index 0000000..2c4414e --- /dev/null +++ b/include/xtr/dialog/OptionsDialog.h @@ -0,0 +1,100 @@ +#pragma once + +namespace xtr::dialog { + +//! Dialog: Application options page +class GeneralPage final : public CPropertyPage { + BOOL promptVersion; + BOOL disableAutoKeyboard; + BOOL showStartPage; + BOOL enablePython; + + CString pythonPath; + +public: + GeneralPage(); + +private: + void DoDataExchange(CDataExchange* pDX) override; + void OnOK() override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnChange() { SetModified(); } +}; + +//! Dialog: OSS options page +class OSSPage final : public CPropertyPage { + BOOL m_RunOperation; + BOOL m_EnableGrid; + + int32_t zoom; + +public: + OSSPage(); + +private: + void DoDataExchange(CDataExchange* pDX) override; + BOOL OnInitDialog() override; + void OnOK() override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnChange() { + SetModified(); + } +}; + +//! Dialog: RS parsing options page +class ParsingPage final : public CPropertyPage { + BOOL autoCheck; + BOOL colorBrackets; + BOOL showAST; + BOOL enableNavigator; + int32_t m_IndexCst; + int32_t m_IndexLocal; + int32_t m_IndexPr; + +public: + ParsingPage(); + +private: + void DoDataExchange(CDataExchange* pDX) override; + void OnOK() override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnChange() { + SetModified(); + } +}; + +//! Dialog: RSModel options page +class ModelPage final : public CPropertyPage { + BOOL m_DataMode; + +public: + ModelPage(); + +private: + void DoDataExchange(CDataExchange* pDX) override; + void OnOK() override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnChange() { + SetModified(); + } +}; + +//! Dialog: Exteor options +struct ExteorOptionsSheet final : CPropertySheet { + GeneralPage m_App; + OSSPage m_OSS; + ParsingPage parsing; + ModelPage m_RSModel; + +public: + explicit ExteorOptionsSheet(CWnd* pWndParent = nullptr); + +private: + BOOL PreTranslateMessage(MSG* pMsg) override; +}; + +} // namespace xtr::dialog \ No newline at end of file diff --git a/include/xtr/dialog/PickOperation.h b/include/xtr/dialog/PickOperation.h new file mode 100644 index 0000000..775808a --- /dev/null +++ b/include/xtr/dialog/PickOperation.h @@ -0,0 +1,39 @@ +#pragma once + +namespace xtr::dialog { + +//! Dialog: Choose OSS operation type +class PickOperationDlg final : public CDialog { +public: + BOOL autorun{ FALSE }; + +private: + int32_t type{}; + CListBox m_OperationList; + + ccl::oss::OSSchema& oss; + const ccl::oss::PictID activePID; + std::vector operations; + +public: + PickOperationDlg(ccl::oss::OSSchema& schema, ccl::oss::PictID pid, CWnd* pParent = nullptr); + +private: + void DoDataExchange(CDataExchange* pDX) override; + BOOL OnInitDialog() override; + +public: + [[nodiscard]] ccl::ops::Type GetSelectedOperation() const { + return ID2Operation(type); + } + +DECLARE_MESSAGE_MAP() + afx_msg void OpenHelp(); + afx_msg void OnChange(); + +private: + [[nodiscard]] ccl::ops::Type ID2Operation(int32_t selectedID) const; + [[nodiscard]] int32_t Operation2ID(ccl::ops::Type operation) const noexcept; +}; + +} // namespace xtr::dialog \ No newline at end of file diff --git a/include/xtr/dialog/RSModelPage.h b/include/xtr/dialog/RSModelPage.h new file mode 100644 index 0000000..d21e450 --- /dev/null +++ b/include/xtr/dialog/RSModelPage.h @@ -0,0 +1,62 @@ +#pragma once + +#include "xtr/ui/RSEdit.h" +#include "xtr/ui/DataGridCtrl.h" + +namespace xtr::dialog { + +class EditConstituentaDlg; + +//! Dialog: Edit RSModel data +class RSModelPage : public CPropertyPage { + EditConstituentaDlg& parent; + + CString typification; + CString textDef; + BOOL isModified{ FALSE }; + BOOL canceled{ FALSE }; + + CComboBox nameCtrl; + ui::RSEdit exprCtrl; + ui::RSEdit textCtr; + CComboBox dataEditCtrl; + CButton textBtn; + ui::DataGridCtrl dataCtrl; + +public: + explicit RSModelPage(EditConstituentaDlg& parent); + +private: + void DoDataExchange(CDataExchange* pDX) override; + BOOL OnInitDialog() override; + void InitControls(); + void InitCstNameList(); + + BOOL OnApply() override; + void OnCancel() override; + void OnOK() override; + BOOL PreTranslateMessage(MSG* pMsg) override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnConfirm(); + afx_msg void OnSelchangeName(); + afx_msg void OnCbnKillfocusEditData(); + afx_msg void OnBnClickedFillInterp(); + afx_msg void OnEraseData(); + afx_msg void OnExportData(); + afx_msg void OnImportData(); + afx_msg void OnDataChange(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnPrev(); + afx_msg void OnNext(); + +private: + void SetModified(BOOL bChanged = TRUE); + BOOL IsModified() const noexcept; + + void UpdateFormat(); + void UpdateCellText(); + + void CancelEdit(); +}; + +} // namespace xtr::dialog \ No newline at end of file diff --git a/include/xtr/dialog/StartPage.h b/include/xtr/dialog/StartPage.h new file mode 100644 index 0000000..75181ea --- /dev/null +++ b/include/xtr/dialog/StartPage.h @@ -0,0 +1,41 @@ +#pragma once + +#include "xtr/ui/BuffRichEdit.h" + +namespace xtr::dialog { + +class ExtStartPage final : public CDialog { + CMFCButton newDocBtn{}; + CMFCButton openDocBtn{}; + CMFCButton helpBtn{}; + CMFCButton examplesBtn{}; + + CButton promtBtn{}; + ui::BuffRichEdit releaseLog{}; + HICON xtrIcon{}; + +public: + ~ExtStartPage() override; + ExtStartPage() = default; + ExtStartPage(const ExtStartPage&) = delete; + ExtStartPage& operator=(const ExtStartPage&) = delete; + +private: + void DoDataExchange(CDataExchange* pDX) override; + BOOL OnInitDialog() override; + void InitTitle(); + void LoadExteorIcon(); + void InitControls(); + [[nodiscard]] static CString LoadLog(); + +private: +DECLARE_MESSAGE_MAP() + afx_msg void OnNewDoc(); + afx_msg void OnOpenDoc(); + afx_msg void OnOpenHelp(); + afx_msg void OnSamples(); + afx_msg void OnPromt(); + afx_msg void OnMemo(); +}; + +} // namespace xtr::dialog \ No newline at end of file diff --git a/include/xtr/dialog/Term2Function.h b/include/xtr/dialog/Term2Function.h new file mode 100644 index 0000000..fb544f6 --- /dev/null +++ b/include/xtr/dialog/Term2Function.h @@ -0,0 +1,61 @@ +#pragma once + +#include "xtr/ui/RSEdit.h" +#include "xtr/ui/RSListCtrl.h" +#include "xtr/doc/RSFacade.h" + +namespace xtr::dialog { + +//! Dialog: Create RSTerm-Function from RSTerm +class Term2Function final : public CDialog { + struct Header; + +public: + CString expression{}; + CString textRef{}; + VectorOfEntities addedCst{}; + +private: + doc::RSFacade& editor; + + ui::RSEdit inputCtrl{}; + ui::RSEdit expressionCtrl{}; + ui::RSEdit definitionCtrl{}; + + ui::RSListCtrl globalsCtrl{}; + ui::RSListCtrl argsCtrl{}; + + CComboBox cstPicker{}; + + CString cstName{}; + CString inputExpr{}; + +public: + Term2Function(doc::RSFacade& editor, EntityUID startID, CWnd* pParent = nullptr); + +private: + void DoDataExchange(CDataExchange* pDX) override; + BOOL OnInitDialog() override; + void InitControls(); + void InitHeaders(); + void InitCstNameList(); + void OnOK() override; + BOOL PreTranslateMessage(MSG* pMsg) override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnSelchangeTermCb(); + afx_msg void OnBnClickedUpdateExp(); + afx_msg void OnBnClickedRight(); + afx_msg void OnBnClickedLeft(); + afx_msg void OnBnClickedApply(); + afx_msg void OnDblClickGlobal(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnDblClickArg(NMHDR* pNMHDR, LRESULT* pResult); + +private: + void UpdateUI(); + void UpdateArgs(); + void InputGlobals(); + std::optional AddFunction(); +}; + +} // namespace xtr::dialog \ No newline at end of file diff --git a/include/xtr/dialog/TerminRefDlg.h b/include/xtr/dialog/TerminRefDlg.h new file mode 100644 index 0000000..b5c689d --- /dev/null +++ b/include/xtr/dialog/TerminRefDlg.h @@ -0,0 +1,73 @@ +#pragma once + +#include "xtr/doc/RSFacade.h" + +namespace xtr::dialog { + +//! Choose term data parameters +class TerminRefDlg final : public CDialog { + CListBox singForms{}; + CListBox plurForms{}; + CListBox captionList{}; + + enum ACStatus : int32_t { + ACS_TERMS, + ACS_WORDFORMS, + }; + ACStatus state{ ACS_TERMS }; + + CPoint position; + CString initialText; + doc::RSFacade& editor; + + std::vector entities{}; + + std::string cstName{}; + ccl::lang::Morphology termForm{}; + +public: + TerminRefDlg(doc::RSFacade& editor, CPoint position, CString selection, CWnd* pParent = nullptr); + +private: + BOOL OnInitDialog() override; + void DoDataExchange(CDataExchange* pDX) override; + +public: + [[nodiscard]] ccl::lang::Reference CreateRef() const; + +private: + BOOL PreTranslateMessage(MSG* pMsg) override; + +private: + void SetPositionAndSize(BOOL fitBoth = FALSE); + + void SelectTermRef(); + void SelectTermForm(int32_t selection, ccl::lang::Grammem plurality); + void ChangeTermForm(CListBox* selectedCListBox, ccl::lang::Grammem plurality); + void UpdateContextNameList(); +}; + +//! Edit form of a term +class TermFormDlg final : public CDialog { +public: + TermFormDlg(CString initText, RECT position, CWnd* pParent = nullptr); + +private: + void DoDataExchange(CDataExchange* pDX) override; + BOOL OnInitDialog() override; + +public: + CString termFormText; + +private: + CEdit textControl; + RECT position; + +private: + BOOL PreTranslateMessage(MSG* pMsg) override; + +private: + void SetPositionAndSize(); +}; + +} // namespace xtr::dialog \ No newline at end of file diff --git a/include/xtr/dialog/WordRefDlg.h b/include/xtr/dialog/WordRefDlg.h new file mode 100644 index 0000000..2c89561 --- /dev/null +++ b/include/xtr/dialog/WordRefDlg.h @@ -0,0 +1,56 @@ +#pragma once + +namespace xtr::dialog { + +//! Choose companion word data options +class WordRefDlg final : public CDialog { +private: + CEdit textControl; + RECT position; + + CString dependantWord; + int16_t offset{ 0 }; + +public: + WordRefDlg(RECT position, CString selection, CWnd* pParent = nullptr); + +private: + BOOL OnInitDialog() override; + void DoDataExchange(CDataExchange* pDX) override; + +public: + [[nodiscard]] ccl::lang::Reference CreateRef() const; + +private: + BOOL PreTranslateMessage(MSG* pMsg) override; + +private: + void SetPositionAndSize(); + void SelectOffset(); +}; + +//! Select companion offset +class RefOffsetDlg final : public CDialog { +public: + int16_t offset{ 0 }; + +private: + CString offsetText{ L"<- ->" }; + CStatic textControl; + RECT position; + +public: + explicit RefOffsetDlg(RECT position, CWnd* pParent = nullptr); + +private: + BOOL OnInitDialog() override; + void DoDataExchange(CDataExchange* pDX) override; + BOOL PreTranslateMessage(MSG* pMsg) override; + void OnOK() override; + +private: + void SetPositionAndSize(); + void UpdateOffset(BOOL decrease); +}; + +} // namespace xtr::dialog \ No newline at end of file diff --git a/include/xtr/doc/DocumentManager.h b/include/xtr/doc/DocumentManager.h new file mode 100644 index 0000000..3beb198 --- /dev/null +++ b/include/xtr/doc/DocumentManager.h @@ -0,0 +1,49 @@ +#pragma once + +namespace xtr { class ExteorApplication; } + +namespace xtr::doc { + +struct XTRDocument; +class RSFormDoc; +class OSSDoc; +class RSModelDoc; + +//! Exteor documents manager +class DocumentManager { + friend class xtr::ExteorApplication; + + ExteorApplication& exteor; + CMultiDocTemplate* m_RSFormTemplate{ nullptr }; + CMultiDocTemplate* m_RSModelTemplate{ nullptr }; + CMultiDocTemplate* m_OSSTemplate{ nullptr }; + +public: + explicit DocumentManager(ExteorApplication& app) noexcept + : exteor{ app } {} + +public: + void ShowDocument(doc::XTRDocument& doc); + + doc::RSFormDoc* NewRSFormDoc(const ccl::semantic::RSForm& schema, BOOL noView = FALSE); + doc::RSFormDoc* NewRSFormDoc(BOOL noView = FALSE); + doc::RSModelDoc* NewRSModelDoc(BOOL noView = FALSE); + doc::OSSDoc* NewOSSDoc(BOOL noView = FALSE); + + [[nodiscard]] doc::RSFormDoc* OpenRSFormDoc(CString path, BOOL noView = FALSE); + + [[nodiscard]] std::vector RSFormList() const; + [[nodiscard]] std::vector RSModelList() const; + [[nodiscard]] std::vector RSFormDocList() const; + + [[nodiscard]] doc::RSFormDoc* FindRSDocByPath(CString path); + +private: + BOOL Initialize(); + + static CDocument* NewDoc(CMultiDocTemplate& templ, BOOL noView); + static CDocument* OpenDoc(CMultiDocTemplate& templ, CString path, BOOL noView); + BOOL CreateViewFor(doc::XTRDocument& doc); +}; + +} // namespace xtr::doc \ No newline at end of file diff --git a/include/xtr/doc/Documents.h b/include/xtr/doc/Documents.h new file mode 100644 index 0000000..a8bd031 --- /dev/null +++ b/include/xtr/doc/Documents.h @@ -0,0 +1,16 @@ +#pragma once + +#include "xtr/core/SelectableSet.h" + +namespace xtr::doc { + +//! Abstract Exteor document +struct XTRDocument : CDocument { + void SetModifiedFlag(BOOL modified) override; +}; + +//! Abstract RS document +class SelectableDoc : public XTRDocument, public core::SelectableSet { +}; + +} // namespace xtr::doc \ No newline at end of file diff --git a/include/xtr/doc/FileTypes.h b/include/xtr/doc/FileTypes.h new file mode 100644 index 0000000..46a330e --- /dev/null +++ b/include/xtr/doc/FileTypes.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +namespace xtr { + +enum class FileType : uint32_t { + trs, + rsm, + oss, + + json, + docx, + csv, + txt, + xlsx, + png, +}; + +CString ExtensionFor(FileType type); + +} // namespace xtr \ No newline at end of file diff --git a/include/xtr/doc/FileVersions.hpp b/include/xtr/doc/FileVersions.hpp new file mode 100644 index 0000000..dd1a9bb --- /dev/null +++ b/include/xtr/doc/FileVersions.hpp @@ -0,0 +1,88 @@ +#pragma once + +#include "xtr/doc/FileTypes.h" + +namespace xtr { + +struct OSSVersion : ccl::meta::Orderable { + enum VersionID : uint16_t { + old = 0, + r1092 = 1, // Exteor 4.0 R1092 - 09/27/2013 + r1483 = 2, // Exteor 4.5 R1438 - 08/04/2016 + r1553 = 3, // Exteor 4.5 R1553 - 04/26/2017 + r1800 = 4, // Exteor 4.6 R1800 - 09/21/2018 + r47101200 = 5, // Exteor 4.7.10.1200 - 05/28/2019 + r202205 = 6, // Exteor 4.8.13.1000 - 30/05/2022 + }; + + VersionID v; + + constexpr OSSVersion(VersionID ver) noexcept : v{ ver } {} + constexpr operator VersionID() const noexcept { return v; } + constexpr VersionID get() const noexcept { return v; } + + static OSSVersion Latest() noexcept { + static const OSSVersion latest{ r202205 }; + return latest; + } + static CString LastestInfo() { + static const CString info{ LR"(Exteor 4.8.13.1000 - 30/05/2022)" }; + return info; + } +}; + +struct TRSVersion : ccl::meta::Orderable { + enum VersionID : uint16_t { + old = 10, + r1010 = 11, + r1092 = 12, // Exteor 4.0 R1092 - 09/27/2013 + r1438 = 13, // Exteor 4.5 R1438 - 08/04/2016 + r1800 = 14, // Exteor 4.6 R1800 - 09/21/2018 + r47101200 = 15, // Exteor 4.7.10.1200 - 05/28/2019 + r202205 = 16, // Exteor 4.8.13.1000 - 30/05/2022 + }; + + VersionID v; + + constexpr TRSVersion(VersionID ver) noexcept : v{ ver } {} + constexpr operator VersionID() const noexcept { return v; } + constexpr VersionID get() const noexcept { return v; } + + static TRSVersion Latest() noexcept { + static const TRSVersion latest{ r202205 }; + return latest; + } + static const CString LastestInfo() { + static const CString info{ LR"(Exteor 4.8.13.1000 - 30/05/2022)" }; + return info; + } +}; + +struct RSMVersion : ccl::meta::Orderable { + enum VersionID : uint16_t { + old = 0, + r1010 = 1, + r1092 = 2, // Exteor 4.0 R1092 - 09/27/2013 + r1438 = 3, // Exteor 4.5 R1438 - 08/04/2016 + r1800 = 4, // Exteor 4.6 R1800 - 09/21/2018 + r47101200 = 5, // Exteor 4.7.10.1200 - 05/28/2019 + r202205 = 6, // Exteor 4.8.13.1000 - 30/05/2022 + }; + + VersionID v; + + constexpr RSMVersion(VersionID ver) noexcept : v{ ver } {} + constexpr operator VersionID() const noexcept { return v; } + constexpr VersionID get() const noexcept { return v; } + + static RSMVersion Latest() noexcept { + static const RSMVersion latest{ r202205 }; + return latest; + } + static const CString LastestInfo() { + static const CString info{ LR"(Exteor 4.8.13.1000 - 30/05/2022)" }; + return info; + } +}; + +} // namespace xtr \ No newline at end of file diff --git a/include/xtr/doc/OSSDoc.h b/include/xtr/doc/OSSDoc.h new file mode 100644 index 0000000..cc74004 --- /dev/null +++ b/include/xtr/doc/OSSDoc.h @@ -0,0 +1,49 @@ +#pragma once + +#include "xtr/doc/Documents.h" +#include "xtr/io/SerializationManager.hpp" + +namespace xtr::doc { + +//! OSS document +class OSSDoc final : public XTRDocument, public ccl::types::Observer, public io::MFCSerializable { + DECLARE_DYNCREATE(OSSDoc) + +public: + ccl::oss::PictID selection{}; + +private: + std::unique_ptr oss{ nullptr }; + +public: + ~OSSDoc() override; + +private: + OSSDoc(); + +public: + void OnObserve(const ccl::types::Message& change) override; + + [[nodiscard]] const ccl::oss::OSSchema& OSS() const noexcept { return *oss; } + [[nodiscard]] ccl::oss::OSSchema& OSS() noexcept { return *oss; } + +public: + void Serialize(CArchive& ar) override; + BOOL CanCloseFrame(CFrameWnd* pFrame) override; + BOOL OnNewDocument() override; + BOOL OnOpenDocument(LPCTSTR path) override; + BOOL OnSaveDocument(LPCTSTR path) override; + +private: + JSON ExtractData() const override; + bool LoadData(const JSON& object) override; + bool LegacyLoad(io::CArchiveAdapter& archive) override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnUpdateFileSaveAs(CCmdUI *pCmdUI); + +private: + void SaveAllDocs(); +}; + +} // namespace xtr::doc \ No newline at end of file diff --git a/include/xtr/doc/RSFacade.h b/include/xtr/doc/RSFacade.h new file mode 100644 index 0000000..bb2cecc --- /dev/null +++ b/include/xtr/doc/RSFacade.h @@ -0,0 +1,63 @@ +#pragma once + +#include "xtr/doc/RSFormDoc.h" +#include "xtr/doc/RSModelDoc.h" + +namespace xtr::doc { + +//! RS editing Facade +class RSFacade { +private: + bool isModel{ false }; + RSFormDoc* schemaDoc{}; + RSModelDoc* modelDoc{}; + +public: + explicit RSFacade(RSFormDoc& doc) noexcept + : isModel{ false }, schemaDoc{ &doc } {} // NOLINT(modernize-use-default-member-init) + explicit RSFacade(RSModelDoc& doc) noexcept + : isModel{ true }, modelDoc{ &doc } {} + + RSFacade() noexcept = default; + RSFacade(const RSFacade&) noexcept = default; + RSFacade& operator=(const RSFacade&) noexcept = default; + RSFacade(RSFacade&&) noexcept = default; + RSFacade& operator=(RSFacade&&) noexcept = default; + +public: + [[nodiscard]] bool IsModel() const noexcept { return isModel; } + [[nodiscard]] SelectableDoc& Document() noexcept; + + [[nodiscard]] const ccl::semantic::RSCore& Core() const noexcept; + [[nodiscard]] ccl::semantic::RSForm& EditSchema() noexcept; + [[nodiscard]] const ccl::semantic::RSForm& Schema() const noexcept; + [[nodiscard]] ccl::semantic::RSModel& EditModel() noexcept; + [[nodiscard]] const ccl::semantic::RSModel& Model() const noexcept; + + [[nodiscard]] const ccl::semantic::Thesaurus& Texts() const noexcept; + [[nodiscard]] const ccl::semantic::Schema& RSLang() const noexcept; + [[nodiscard]] const ccl::semantic::CstList& List() const noexcept; + + [[nodiscard]] bool Contains(EntityUID entity) const; + [[nodiscard]] const ccl::semantic::RSConcept& GetRS(EntityUID entity) const; + [[nodiscard]] const ccl::semantic::TextConcept& GetText(EntityUID entity) const; + [[nodiscard]] const ccl::semantic::ParsingInfo& GetParse(EntityUID entity) const; + + void SetComment(const std::string& newComment); + + ccl::EntityUID Emplace(ccl::semantic::CstType type, const std::string& definition = {}); + ccl::VectorOfEntities InsertCopy(const std::vector& input); + + bool MoveBefore(EntityUID what, ccl::semantic::ListIterator iWhere); + + bool SetAliasFor(EntityUID target, const std::string& newName, bool substitue = true); + bool SetExpressionFor(EntityUID target, const std::string& expression); + bool SetTermFor(EntityUID target, const std::string& termRef); + bool SetTermFormFor(EntityUID target, const std::string& termRef, const ccl::lang::Morphology& form); + bool SetDefinitionFor(EntityUID target, const std::string& textDef); + bool SetConventionFor(EntityUID target, const std::string& convention); + + void ResetAliases(); +}; + +} // namespace xtr::doc \ No newline at end of file diff --git a/include/xtr/doc/RSFormDoc.h b/include/xtr/doc/RSFormDoc.h new file mode 100644 index 0000000..b6b7faa --- /dev/null +++ b/include/xtr/doc/RSFormDoc.h @@ -0,0 +1,51 @@ +#pragma once + +#include "xtr/doc/Documents.h" +#include "xtr/io/SerializationManager.hpp" + +namespace xtr::doc { + +class RSModelDoc; + +//! RSForm document +class RSFormDoc final + : public ccl::src::Source, public SelectableDoc, public io::MFCSerializable, public ccl::types::Observer { + DECLARE_DYNCREATE(RSFormDoc) + +private: + ccl::semantic::RSForm schema{}; + +public: + ~RSFormDoc() override; + +public: + RSFormDoc(); + +public: + ccl::semantic::RSForm& Schema() noexcept { return schema; } + const ccl::semantic::RSForm& Schema() const noexcept { return schema; } + + [[nodiscard]] ccl::src::SrcType Type() const noexcept override { return ccl::src::SrcType::rsDoc; } + [[nodiscard]] ccl::change::Hash CoreHash() const override { return schema.CoreHash(); } + [[nodiscard]] ccl::change::Hash FullHash() const override { return schema.FullHash(); } + + bool WriteData(ccl::meta::UniqueCPPtr data) override; + [[nodiscard]] const ccl::src::DataStream* ReadData() const noexcept override { return &schema; } + [[nodiscard]] ccl::src::DataStream* AccessData() override; + + void OnObserve(const ccl::types::Message& change) override; + +public: + void Serialize(CArchive& ar) override; + BOOL OnNewDocument() override; + BOOL OnOpenDocument(LPCTSTR path) override; + BOOL OnSaveDocument(LPCTSTR path) override; + void OnCloseDocument() override; + +private: + JSON ExtractData() const override; + bool LoadData(const JSON& object) override; + bool LegacyLoad(io::CArchiveAdapter& archive) override; +}; + +} // namespace xtr::doc \ No newline at end of file diff --git a/include/xtr/doc/RSModelDoc.h b/include/xtr/doc/RSModelDoc.h new file mode 100644 index 0000000..92773d6 --- /dev/null +++ b/include/xtr/doc/RSModelDoc.h @@ -0,0 +1,43 @@ +#pragma once + +#include "xtr/doc/Documents.h" +#include "xtr/io/SerializationManager.hpp" + +namespace xtr::doc { + +class RSFormDoc; + +//! RSModel document +class RSModelDoc final + : public SelectableDoc, public io::MFCSerializable, public ccl::types::Observer { + DECLARE_DYNCREATE(RSModelDoc) + +private: + ccl::semantic::RSModel model{}; + +public: + ~RSModelDoc() override; + +private: + RSModelDoc(); + +public: + void OnObserve(const ccl::types::Message& change) override; + +public: + ccl::semantic::RSModel& Model() noexcept { return model; } + const ccl::semantic::RSModel& Model() const noexcept { return model; } + +public: + void Serialize(CArchive& ar) override; + BOOL OnNewDocument() override; + BOOL OnOpenDocument(LPCTSTR path) override; + BOOL OnSaveDocument(LPCTSTR path) override; + +private: + JSON ExtractData() const override; + bool LoadData(const JSON& object) override; + bool LegacyLoad(io::CArchiveAdapter& archive) override; +}; + +} // namespace xtr::doc \ No newline at end of file diff --git a/include/xtr/io/CArchiveAdapter.hpp b/include/xtr/io/CArchiveAdapter.hpp new file mode 100644 index 0000000..d64a487 --- /dev/null +++ b/include/xtr/io/CArchiveAdapter.hpp @@ -0,0 +1,66 @@ +#pragma once + +#include "xtr/core/rslIndex.hpp" + +namespace xtr::io { + +//! MFC serialization adapter for CCL +class CArchiveAdapter { +public: + CArchiveAdapter(CArchive& ar) noexcept + : archive{ ar } {} + +private: + CArchive& archive; + +public: + CArchive& get() noexcept { return archive; } + bool IsStoring() const { + return archive.IsStoring(); + } + + template + CArchiveAdapter& operator>>(Object& obj) { + archive >> obj; + return *this; + } + + template<> + CArchiveAdapter& operator>>(std::string& obj) { + CString str{}; + archive >> str; + index::FixLegacy(str); + obj = mfc::ToSTL(str); + return *this; + } + + CArchiveAdapter& operator>>(std::u8string& obj) { + CString str{}; + archive >> str; + index::FixLegacy(str); + obj = mfc::ToUTF8(str); + return *this; + } + + template + void Skip() { + Object discard{}; + *this >> discard; + } + + template + void SkipN(uint32_t count) { + while (count--) { + Skip(); + } + } + + template + Object Load() { + Object obj{}; + *this >> obj; + return obj; + } +}; + +} // namespace xtr::io \ No newline at end of file diff --git a/include/xtr/io/CstGraphExporter.h b/include/xtr/io/CstGraphExporter.h new file mode 100644 index 0000000..4328646 --- /dev/null +++ b/include/xtr/io/CstGraphExporter.h @@ -0,0 +1,57 @@ +#pragma once + +#include "xtr/io/OptionsIO.hpp" +#include "xtr/doc/FileTypes.h" + +#include + +namespace xtr::io { + +//! Export CstGraph +class CstGraphExporter { + const ccl::semantic::RSCore& target; + CstGraphOptions options{}; + +public: + explicit CstGraphExporter(const ccl::semantic::RSCore& target) noexcept + : target{ target } {} + +public: + [[nodiscard]] BOOL Export(const CstGraphOptions& exportParams, CString fileName, FileType type); + +private: + struct Triplet { + std::string_view from; + io::LinkType type; + std::string_view to; + }; + + template + void OutputLinks(const io::LinkType linkType, LinePutter out) { + for (const auto toID : target.List()) { + switch (linkType) { + case io::LinkType::formula: { + for (const auto fromID : target.RSLang().Graph().InputsFor(toID)) { + out(Triplet{ target.GetRS(fromID).alias, linkType, target.GetRS(toID).alias }); + } + break; + } + case io::LinkType::lexTerm: { + for (const auto fromID : target.Texts().TermGraph().InputsFor(toID)) { + out(Triplet{ target.GetRS(fromID).alias, linkType, target.GetRS(toID).alias }); + } + break; + } + case io::LinkType::lexDef: { + for (const auto fromID : target.Texts().DefGraph().InputsFor(toID)) { + out(Triplet{ target.GetRS(fromID).alias, linkType, target.GetRS(toID).alias }); + } + break; + } + case io::LinkType::size_: break; + } + } + } +}; + +} // namespace xtr::io \ No newline at end of file diff --git a/include/xtr/io/ModelDataExchange.h b/include/xtr/io/ModelDataExchange.h new file mode 100644 index 0000000..c65c83d --- /dev/null +++ b/include/xtr/io/ModelDataExchange.h @@ -0,0 +1,36 @@ +#pragma once + +#include "office/ExcelWrapper.h" + +#include "ccl/rslang/SDataCompact.h" + +namespace xtr::io { + +//! RSModel data exchange +class RSMDataX { +protected: + MSO::Excel::ExcelWrapper xlWrapper{}; + MSO::Excel::EXLWorkbook workingWb{ nullptr }; + MSO::Excel::EXLWorksheet workingWs{ nullptr }; + +public: + RSMDataX(const RSMDataX&) = delete; + RSMDataX& operator=(const RSMDataX&) = delete; + +protected: + ~RSMDataX() = default; + RSMDataX() = default; + +public: + [[nodiscard]] static RSMDataX& Instance(); + + static BOOL ExportModel(const ccl::semantic::RSModel& model); + static BOOL ExportDataFor(EntityUID target, const ccl::semantic::RSModel& model); + + [[nodiscard]] static std::optional + ImportStructured(const ccl::semantic::RSModel& model, const ccl::rslang::Typification& structure); + [[nodiscard]] static std::optional + ImportText(const ccl::semantic::RSModel& model); +}; + +} // namespace xtr::io \ No newline at end of file diff --git a/include/xtr/io/ModelExporter.h b/include/xtr/io/ModelExporter.h new file mode 100644 index 0000000..6e57240 --- /dev/null +++ b/include/xtr/io/ModelExporter.h @@ -0,0 +1,19 @@ +#pragma once + +#include "xtr/doc/FileTypes.h" + +namespace xtr::io { + +//! Export RSModel +class ModelExporter { + const ccl::semantic::RSModel& target; + +public: + explicit ModelExporter(const ccl::semantic::RSModel& model) noexcept + : target{ model } {} + +public: + [[nodiscard]] BOOL Export(CString fileName, FileType type); +}; + +} // namespace xtr::io \ No newline at end of file diff --git a/include/xtr/io/OSSExporter.h b/include/xtr/io/OSSExporter.h new file mode 100644 index 0000000..71d0c5f --- /dev/null +++ b/include/xtr/io/OSSExporter.h @@ -0,0 +1,19 @@ +#pragma once + +#include "xtr/doc/FileTypes.h" + +namespace xtr::io { + +//! Export OSS graph as picture +class OSSExporter { + const ccl::oss::OSSchema& target; + +public: + explicit OSSExporter(const ccl::oss::OSSchema& oss) noexcept + : target{ oss } {} + +public: + [[nodiscard]] BOOL Export(CString fileName, FileType type); +}; + +} // namespace xtr::io \ No newline at end of file diff --git a/include/xtr/io/OSSLegacyLoader.h b/include/xtr/io/OSSLegacyLoader.h new file mode 100644 index 0000000..053a223 --- /dev/null +++ b/include/xtr/io/OSSLegacyLoader.h @@ -0,0 +1,44 @@ +#pragma once + +#include "xtr/doc/OSSDoc.h" + +namespace xtr::io { + +//! Legacy loader +class OSSLegacyLoader { + io::CArchiveAdapter& ar; + ccl::oss::OSSchema& oss; + +public: + OSSVersion version{ OSSVersion::old }; + ccl::oss::PictID selection{}; + +public: + OSSLegacyLoader(CArchiveAdapter& ar, ccl::oss::OSSchema& oss) noexcept + : ar{ ar }, oss{ oss } {} + +public: + void LoadVersion(); + void DoLoad(); + +private: + void LoadFirstGen(); + void LoadPictGen1(); + [[nodiscard]] static uint32_t LoadPictStatus(uint32_t code) noexcept; + [[nodiscard]] static ccl::ops::Type LoadOperationType(uint32_t code) noexcept; + + void LoadSecondGen(); + void LoadPictGen2(); + ccl::meta::UniqueCPPtr LoadOptionsGen2(); + ccl::meta::UniqueCPPtr LoadTranslationsGen2(); + + void LoadThirdGen(); + void LoadPictGen3(); + ccl::meta::UniqueCPPtr LoadOptionsGen3(); + ccl::meta::UniqueCPPtr LoadTranslationsGen3(); + + void LoadDependencies(); +}; + + +} // namespace xtr::io \ No newline at end of file diff --git a/include/xtr/io/OptionsIO.hpp b/include/xtr/io/OptionsIO.hpp new file mode 100644 index 0000000..1d62e39 --- /dev/null +++ b/include/xtr/io/OptionsIO.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include + +namespace xtr::io { + +struct SchemaOptions { + BOOL bTerm; + BOOL bRSDef; + BOOL bTextDef; + BOOL bComment; + BOOL bTyping; +}; + +enum class LinkType : uint32_t { + formula = 0, + lexTerm, + lexDef, + size_ +}; + +struct CstGraphOptions { + std::optional linkage{ std::nullopt }; + BOOL triplets{ TRUE }; +}; + +} // namespace xtr::io \ No newline at end of file diff --git a/include/xtr/io/RSExcelIOManager.h b/include/xtr/io/RSExcelIOManager.h new file mode 100644 index 0000000..8f98ffb --- /dev/null +++ b/include/xtr/io/RSExcelIOManager.h @@ -0,0 +1,64 @@ +#pragma once + +#include "office/ExcelWrapper.h" + +#include "ccl/rslang/SDataCompact.h" + +namespace xtr::io { + +class RSExcelIOManager { + MSO::Excel::ExcelWrapper xlWrapper{}; + MSO::Excel::EXLWorkbook workingWb{ nullptr }; + MSO::Excel::EXLWorksheet workingWs{ nullptr }; + const ccl::semantic::RSModel& model; + + enum class OutputColumn : long { + id = 1, + constituenta = 2, + expression = 3, + type = 4, + term = 5, + interpretation = 6, + convention = 7 + }; + +public: + ~RSExcelIOManager(); + RSExcelIOManager(const RSExcelIOManager&) = delete; + RSExcelIOManager& operator=(const RSExcelIOManager&) = delete; + + explicit RSExcelIOManager(const ccl::semantic::RSModel& model) + : model{ model } {} + +public: + BOOL ExportModel(); + BOOL ExportDataFor(EntityUID target); + + [[nodiscard]] std::optional ImportStructured(const ccl::rslang::Typification& structure); + [[nodiscard]] std::optional ImportText(); + +private: + using RawStringData = std::vector>; + + void ExportCstProperties(EntityUID target, MSO::Excel::EXLWorksheet rsFormSheet, MSO::SizeT nRow); + BOOL ExportCstDataInternal(EntityUID target); + std::optional ImportStructuredInternal(const ccl::rslang::Typification& structure); + std::optional ImportTextInternal(); + + BOOL PrepareNewWorkbook(); + MSO::Excel::EXLWorksheet InitModelWorksheet(CString label); + MSO::Excel::EXLWorksheet CreateOutputSheet(CString label); + void ExportNamedData(EntityUID target); + BOOL ExportStructuredData(EntityUID target); + void InitCstDataHeader(const std::vector& header); + + BOOL PrepareInputWorksheet(); + BOOL DetermineWorksheet(); + + BOOL CheckHeaders(const std::vector& header); + RawStringData ExtractRawData(MSO::SizeT columnCount); + static std::optional DataToTextInterpretation(const RawStringData& data); + static std::optional DataToRSI(const RawStringData& data); +}; + +} // namespace xtr::io \ No newline at end of file diff --git a/include/xtr/io/RSForm2DOCX.h b/include/xtr/io/RSForm2DOCX.h new file mode 100644 index 0000000..60a9e58 --- /dev/null +++ b/include/xtr/io/RSForm2DOCX.h @@ -0,0 +1,36 @@ +#pragma once + +#include "xtr/io/OptionsIO.hpp" + +namespace xtr::io { + +//! Export RSForm as docx +class RSForm2DOCX { + MSO::Word::WApplication wordApplication{}; + MSO::Word::WDocuments docs{}; + MSO::Word::WDocument workingDocument{}; + SchemaOptions params{}; + const ccl::semantic::RSForm& source; + +public: + explicit RSForm2DOCX(const ccl::semantic::RSForm& source) + : source{ source } {} + +public: + BOOL Export(const SchemaOptions& exportParams, CString fileName); + +private: + [[nodiscard]] static std::optional GetPathToTemplate(); + + BOOL LoadApplication(); + BOOL CreateDocument(); + + BOOL WriteContent(); + BOOL PutTextIntoBookmark(CString bookmarkName, CString text); + BOOL WriteHeaderFooter(); + void WriteConstituenta(EntityUID target, MSO::Word::WTable& outTable, long nRow); + + void SaveFile(CString fileName); +}; + +} // namespace xtr::io \ No newline at end of file diff --git a/include/xtr/io/RSMLegacyLoader.h b/include/xtr/io/RSMLegacyLoader.h new file mode 100644 index 0000000..f459939 --- /dev/null +++ b/include/xtr/io/RSMLegacyLoader.h @@ -0,0 +1,40 @@ +#pragma once + +#include "xtr/doc/RSModelDoc.h" + +namespace xtr::io { + +//! RSM legacy loader +class RSMLegacyLoader { + io::CArchiveAdapter& ar; + ccl::semantic::RSModel& model; + + SetOfEntities calculated{}; + +public: + RSMVersion version{ RSMVersion::old }; + SetOfEntities selection{}; + +public: + RSMLegacyLoader(CArchiveAdapter& ar, ccl::semantic::RSModel& model) + : ar{ ar }, model{ model } {} + +public: + using LegacyData = std::vector>; + void LoadVersion(); + void DoLoad(); + +private: + void LoadFirstGen(); + void LoadCst(); + void LoadCstData(); + LegacyData LoadRSITable(); + ccl::semantic::TextInterpretation LoadTextData(BOOL skipIndex); + + void LoadSecondGen(); + void LoadDataFor(EntityUID uid); + + void LoadModelProperties(BOOL loadModelName); +}; + +} // namespace xtr::io \ No newline at end of file diff --git a/include/xtr/io/SchemaExporter.h b/include/xtr/io/SchemaExporter.h new file mode 100644 index 0000000..ac49616 --- /dev/null +++ b/include/xtr/io/SchemaExporter.h @@ -0,0 +1,20 @@ +#pragma once + +#include "xtr/doc/FileTypes.h" +#include "xtr/io/OptionsIO.hpp" + +namespace xtr::io { + +//! Export RSForm schema +class SchemaExporter { + const ccl::semantic::RSForm& target; + +public: + explicit SchemaExporter(const ccl::semantic::RSForm& schema) noexcept + : target{ schema } {} + +public: + [[nodiscard]] BOOL Export(const SchemaOptions& params, CString fileName, FileType type); +}; + +} // namespace xtr::io \ No newline at end of file diff --git a/include/xtr/io/SerializationManager.hpp b/include/xtr/io/SerializationManager.hpp new file mode 100644 index 0000000..d910c40 --- /dev/null +++ b/include/xtr/io/SerializationManager.hpp @@ -0,0 +1,99 @@ +#pragma once + +#include "ccl/tools/JSON.h" +#include "xtr/doc/FileVersions.hpp" + +#include "CArchiveAdapter.hpp" + +using JSON = nlohmann::ordered_json; + +inline void to_json(JSON& object, const CString str) { + object = xtr::mfc::ToSTL(str); +} + +inline void from_json(const JSON& object, CString& str) { + const auto result = object.get(); + str = xtr::mfc::ToMFC(result); +} + +namespace xtr::io { + +//! MFC serializable abstract base +template +class MFCSerializable { + inline static const std::string jsonDocumentName = "document.json"; + +public: + void Serialize(CArchive& ar) { + CArchiveAdapter adapter{ ar }; + ASSERT(!ar.IsStoring()); + if (!LegacyLoad(adapter)) { + AfxThrowArchiveException(CArchiveException::genericException); + } + } + + bool SaveJSON(const std::u8string& path) { + auto json = ExtractData(); + json["version"] = static_cast(Version::Latest()); + json["versionInfo"] = Version::LastestInfo(); + return WriteToFile(json.dump(4), path); + } + + bool LoadJSON(const std::u8string& path) { + const auto data = ReadFromFile(path); + if (!data.has_value()) { + return false; + } + const Version versionID = static_cast(data->at("version").get()); + return Version::Latest() >= versionID && LoadData(data.value()); + } + +private: + virtual JSON ExtractData() const = 0; + virtual bool LoadData(const JSON& object) = 0; + virtual bool LegacyLoad(CArchiveAdapter& ar) = 0; + + bool WriteToFile(std::string_view data, const std::u8string& path) { + try { + std::ofstream outputFile(std::filesystem::path(path), std::ios::binary); + Poco::Zip::Compress archive(outputFile, true); + Poco::MemoryInputStream inputStream(data.data(), size(data)); + archive.addFile(inputStream, Poco::DateTime(), jsonDocumentName); + archive.close(); + outputFile.close(); + } catch (const Poco::Exception& /*error*/) { + return false; + } + return true; + } + + std::optional ReadFromFile(const std::u8string& path) { + namespace fs = std::filesystem; + auto tmpDirectory = fs::temp_directory_path() / "exteor" / fs::path(path).filename().replace_extension(""); + std::ifstream inputFile(fs::path(path), std::ios::binary); + if (!inputFile) { + return std::nullopt; + } + try { + const auto u8folder = tmpDirectory.u8string(); + const auto outputFolder = Poco::Path(std::string{ begin(u8folder), end(u8folder) }); + Poco::Zip::Decompress(inputFile, outputFolder).decompressAllFiles(); + inputFile.close(); + } catch (const Poco::Exception& /*error*/) { + return std::nullopt; + } + + std::ifstream jsonFile(tmpDirectory / jsonDocumentName); + if (!jsonFile) { + fs::remove_all(tmpDirectory); + return std::nullopt; + } else { + auto jsonData = JSON::parse(jsonFile); + jsonFile.close(); + fs::remove_all(tmpDirectory); + return jsonData; + } + } +}; + +} // namespace xtr::io \ No newline at end of file diff --git a/include/xtr/io/TRSLegacyLoader.h b/include/xtr/io/TRSLegacyLoader.h new file mode 100644 index 0000000..b7f419d --- /dev/null +++ b/include/xtr/io/TRSLegacyLoader.h @@ -0,0 +1,76 @@ +#pragma once + +#include "xtr/core/SelectableSet.h" +#include "xtr/doc/FileVersions.hpp" +#include "xtr/io/CArchiveAdapter.hpp" + +namespace xtr::io { + +//! Shared CstLoader for rsm and trs +class LegacyCstLoader { + BOOL needEncoding{ FALSE }; + std::unique_ptr cst{ nullptr }; + CArchiveAdapter& ar; + +public: + explicit LegacyCstLoader(CArchiveAdapter& ar) noexcept + : ar(ar) {} + +public: + void InitOldEncoding() noexcept { needEncoding = TRUE; } + + void LoadBasicProperties(BOOL oldType = FALSE); + void LoadTerms(BOOL hasTerms, BOOL multipleTerms); + void LoadInterpretation(BOOL loadWithRef); + void LoadID(); + + [[nodiscard]] const ccl::semantic::ConceptRecord& GetResult() const noexcept { return *cst; } + +private: + [[nodiscard]] static ccl::semantic::CstType LoadV0CstType(int32_t code) noexcept; +}; + +//! Shared CoreLoader for rsm and trs +class LegacyCoreLoader { + CArchiveAdapter& ar; + +public: + explicit LegacyCoreLoader(CArchiveAdapter& ar) noexcept + : ar{ ar } {} + +public: + void DoLoad(ccl::semantic::RSCore& core); + +private: + ccl::lang::ManagedText LoadText(); + ccl::lang::LexicalTerm LoadTerm(); +}; + +//! TRS file legacy loader +class TRSLegacyLoader { + CArchiveAdapter& ar; + ccl::semantic::RSForm& schema; + +public: + TRSVersion version{ TRSVersion::old }; + SetOfEntities selection{}; + bool isClaimed{ false }; + +public: + explicit TRSLegacyLoader(CArchiveAdapter& ar, ccl::semantic::RSForm& schema) noexcept + : ar{ ar }, schema{ schema } {} + +public: + void LoadVersion(); + void DoLoad(); + +private: + void LoadSecondGen(); + void LoadSchemaProperties(BOOL loadFullName); + void LoadFirstGen(); + void LoadCst(); + void LoadInheritanceDataFromOldFlag(EntityUID uid, uint16_t loadedStatus); + void LoadInheritance(); +}; + +} // namespace xtr::io \ No newline at end of file diff --git a/include/xtr/mfcHelper.h b/include/xtr/mfcHelper.h new file mode 100644 index 0000000..a3cde6a --- /dev/null +++ b/include/xtr/mfcHelper.h @@ -0,0 +1,41 @@ +#pragma once + +namespace xtr::mfc { + +static constexpr auto noItems = -1; + +CString ToMFC(std::string_view str); +CString ToMFC(std::u8string_view str); +std::string ToSTL(CString str); +std::u8string ToUTF8(CString str); + +CString LoadSID(uint32_t sid); + +template +CString FormatSID(uint32_t sid, Args ...args) { + // Note: this requirement is imposed by MFC FormatMessgeW + // vararg functions are breaking static typing and using opType punning + + auto result = LoadSID(sid); + result.FormatMessageW(sid, args...); + return result; +} + +std::optional FileStatus(const CFile& file); + +// Parameters for bracket search +struct BracketSearchParams { + wchar_t openBracket{ '(' }; + wchar_t closeBracket{ ')' }; + int initialPosition{ 0 }; +}; + +// Backet searchers +std::optional FindBracketBlockStart(CString inputText, const BracketSearchParams& searchParams); +std::optional FindBracketBlockEnd(CString inputText, const BracketSearchParams& searchParams); +std::optional FindOpeningParanthesis(CString text, int startPos = 0); +std::optional FindClosingParanthesis(CString text, int startPos = 0); + +CString FirstWordOf(CString str); + +} // namespace xtr::mfc \ No newline at end of file diff --git a/include/xtr/mfcMessageManager.h b/include/xtr/mfcMessageManager.h new file mode 100644 index 0000000..59cc8ab --- /dev/null +++ b/include/xtr/mfcMessageManager.h @@ -0,0 +1,12 @@ +#pragma once + +#include "xtrServices.h" + +namespace xtr { + +struct mfcMessageManager final : MessageManager { + uint32_t ShowMessage(CString text, uint32_t type) override; + uint32_t ShowMessage(uint32_t messageID, uint32_t type) override; +}; + +} // namespace xtr \ No newline at end of file diff --git a/include/xtr/ui/BuffRichEdit.h b/include/xtr/ui/BuffRichEdit.h new file mode 100644 index 0000000..b258e1e --- /dev/null +++ b/include/xtr/ui/BuffRichEdit.h @@ -0,0 +1,114 @@ +#pragma once + +#include "xtr/viewmodel/vmMeta.hpp" +#include "xtr/ui/KeyboardHandler.h" + +#include "tom.h" + +namespace xtr::ui { + +//! Extended rich edit control +/* + * Context aware tooltip + * Formatting items + * StrRange based API +*/ +class BuffRichEdit : public CRichEditCtrl, public viewmodel::IFreezable { +protected: + struct FormatItem { + StrRange cr{}; + CHARFORMAT2W format{}; + }; + +protected: + BOOL readOnly{ FALSE }; + BOOL switchLayoutOnCtrl{ FALSE }; + std::vector formatItems{}; + + CString defaultToolTipText{}; + Keyboard::Layout defaultKL{ Keyboard::Layout::ENG }; + +private: + BOOL enableTooltip{ FALSE }; + CToolTipCtrl tooltips; + + BOOL enableFormat{ FALSE }; + BOOL alreadyUpdating{ FALSE }; + StrPos cursorFormatPos{ 0 }; + + mutable ITextDocument* textInterface{nullptr}; + mutable uint32_t eventOptions{}; + + std::unique_ptr freezeUID{nullptr}; + int32_t freezeCount{0}; + StrRange storedSelection{}; + +public: + CString Text() const; + void InitRE(Keyboard::Layout kl = Keyboard::Layout::ENG, + BOOL enableFormat = FALSE, + BOOL enableTooltip = FALSE); + void UpdateFormat(BOOL ignoreSelection = FALSE); + + void SetReadOnly(BOOL readOnlyFlag); + void LockInput(); + void UnlockInput(); + + CPoint GetSubscriptDialogPosition() const; + StrRange GetSelectionRange() const; + + CString FixSelection(); + void MoveCaretTo(StrPos position); + void SelectRange(StrRange range); + void SelectChar(StrPos position); + void SelectAll(); + + CHARFORMAT2W GetSelectionFormat() const; + CHARFORMAT2W DefaultFormat() const; + void SelectAndFormat(StrRange range, CHARFORMAT2W format); + +protected: + BOOL PreTranslateMessage(MSG* pMsg) override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnKeyDown(uint32_t nChar, uint32_t nRepCnt, uint32_t nFlags); + afx_msg void OnKeyUp(uint32_t nChar, uint32_t nRepCnt, uint32_t nFlags); + afx_msg BOOL OnSetCursor(CWnd* pWnd, uint32_t nHitTest, uint32_t message); + + afx_msg BOOL OnTextChange(); + afx_msg BOOL OnSelChange(NMHDR* pNotifyStruct , LRESULT* result); + afx_msg void OnSetFocus(CWnd* pOldWnd); + afx_msg void OnKillFocus(CWnd* pOldWnd); + + afx_msg BOOL OnEnLink(NMHDR* pNMHDR, LRESULT* pResult); + +protected: + void InsertChar(uint32_t ch); + void InsertString(CString str); + StrRange ExpandRange(StrRange cr) const; + void UpdateBackground(); + + [[nodiscard]] BOOL IsFrozen() const noexcept { return freezeUID == nullptr; } + void FreezeUI() override; + void UnFreezeUI() override; + void UnFreezeUI(StrRange newSelection); + +private: + +#pragma warning( push ) +#pragma warning( disable : 26440 ) // do not warn about virtual functions noexcept + + virtual void UpdateFormatItems() {} + virtual void AdditionalFormat() {} + virtual CString GenerateToolTipText() { return CString{}; } + +#pragma warning( pop ) + + void DeepCopy(); + void ResetFormatting(); + void ApplyFormatTokens(); + void InitToolTips(); + ITextDocument* GetFixedTextDocumentInterface() const; +}; + +} // namespace xtr::ui \ No newline at end of file diff --git a/include/xtr/ui/ComHelper.h b/include/xtr/ui/ComHelper.h new file mode 100644 index 0000000..135f726 --- /dev/null +++ b/include/xtr/ui/ComHelper.h @@ -0,0 +1,15 @@ +#pragma once + +namespace xtr::ui { + +class ComInitializer { + bool needClose{ false }; + +public: + ~ComInitializer(); + ComInitializer(); + ComInitializer& operator=(const ComInitializer&) = delete; + ComInitializer(const ComInitializer&) = delete; +}; + +} // namespace xtr::ui diff --git a/include/xtr/ui/DataGridCtrl.h b/include/xtr/ui/DataGridCtrl.h new file mode 100644 index 0000000..a7059f3 --- /dev/null +++ b/include/xtr/ui/DataGridCtrl.h @@ -0,0 +1,98 @@ +#pragma once + +#include "ccl/rslang/SDataCompact.h" +#include "xtr/doc/RSModelDoc.h" + +namespace xtr::ui { + +//! Control: Edit structured data in table +class DataGridCtrl final : public CListCtrl { + BOOL isModified{ FALSE }; + + doc::RSModelDoc* m_Doc{ nullptr }; + ccl::semantic::RSModel* model{ nullptr }; + + EntityUID activeCst{}; + std::vector> headerIDs{}; + + CToolTipCtrl tooltips{}; + CComboBox* editCtrl{ nullptr }; + + BOOL showText{ FALSE }; + BOOL isEditable{ FALSE }; + BOOL isBasic{ FALSE }; + const ccl::rslang::Typification* typification{ nullptr }; + + // Selected cell state + int32_t columnCount{ 0 }; + // Note: Число строк можно получить командой GetItemCount + + int32_t topIndex{}; + int32_t ensureVisible; + + int32_t selectedRow; + int32_t selectedColumn; + +public: + DataGridCtrl(); + +public: + void Init(CComboBox* box, BOOL textFlag, doc::RSModelDoc& _doc); + [[nodiscard]] BOOL IsInit() const noexcept { + return model != nullptr; + + } + void SetActive(EntityUID activeUID); + void SetTextFlag(BOOL flag); + + [[nodiscard]] ccl::object::SDCompact::Data GetIDTable() const; + + void SaveData(); + void UpdateSelectedCellText(); + +private: + BOOL PreTranslateMessage(MSG* pMsg) override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnSetFocus(CWnd* pOldWnd); + afx_msg void OnMouseMove(uint32_t nFlags, CPoint point); + afx_msg void OnClick(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnDbClick(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnKeydown(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnCustomDraw(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnPaint(); + +private: + void InitToolTips(); + void UpdateToolTipText(int32_t row, int32_t col); + + void ReloadData(); + void Clear(); + + void LoadBasicData(); + void CreateBasicHeader(CString basicName); + void InputTextData(const ccl::semantic::TextInterpretation & input); + + void LoadSData(); + void CreateHeader(); + void InputStructuredtData(const ccl::object::SDCompact::Data& data); + + void InvalidateCell(int32_t row, int32_t col); + void ShowEditWindowAtCell(int32_t row, int32_t col); + + void OnFirstDraw(); + void OnDrawItem(NMLVCUSTOMDRAW& drawer); + + void CopyCurrentRow(); + void DeleteCurrentRow(); + int32_t AddBaseRow(); + [[nodiscard]] int32_t GetMaxIndex() const; + + void SortData(); + void SwapItems(int32_t item1, int32_t item2); + [[nodiscard]] int32_t CompareItems(int32_t item1, int32_t item2) const; + + void SetTableItem(int32_t row, int32_t col, CString text); +}; + +} // namespace xtr::ui \ No newline at end of file diff --git a/include/xtr/ui/ElementShell.h b/include/xtr/ui/ElementShell.h new file mode 100644 index 0000000..1ab411a --- /dev/null +++ b/include/xtr/ui/ElementShell.h @@ -0,0 +1,66 @@ +#pragma once + +#include "RSListCtrl.h" + +namespace xtr::ui { + +//! Control: RS Equations options table +class EquationsRSLC { + struct EquationsHeader; + +public: + RSListCtrl control{}; + +public: + void InitHeader(); + +public: + struct Item { + CString name1{}; + CString name2{}; + CString term1{}; + CString term2{}; + ccl::ops::Equation::Mode type{ ccl::ops::Equation::Mode::keepHier }; + }; + + using Index = int32_t; + Index InsertItem(const Item& input); + [[nodiscard]] std::optional GetSelectedItem() const; + [[nodiscard]] std::optional GetItem(Index nItem) const; + + void LoadTableSynth(const ccl::ops::EquationOptions& aMap, + const ccl::semantic::RSForm& ks1, + const ccl::semantic::RSForm& ks2); + [[nodiscard]] std::optional + CreateEquations(const ccl::semantic::RSForm& schema1, const ccl::semantic::RSForm& schema2) const; + + [[nodiscard]] ccl::SetOfEntities Inputs(const ccl::semantic::RSForm& ks1) const; + [[nodiscard]] ccl::SetOfEntities Outputs(const ccl::semantic::RSForm& ks2) const; + +private: + [[nodiscard]] static ccl::ops::Equation::Mode Str2Type(CString str) noexcept; + [[nodiscard]] static CString Type2Str(ccl::ops::Equation::Mode type); +}; + +//! Control: Constituent picker ComboBox +class CstPicker : public CComboBox { +public: + enum class Mode : uint8_t { + TITLE = 1, + ALIAS, + DEFAULT, + }; + +private: + Mode menuMode{ Mode::DEFAULT }; + CString m_Exclude{}; + +public: + uint32_t Init(Mode mode = Mode::TITLE, CString exclude = {}); + [[nodiscard]] BOOL IsValid() const; + +private: + void UpdateList(); +}; + +} // namespace xtr::ui \ No newline at end of file diff --git a/include/xtr/ui/ExteorFrame.h b/include/xtr/ui/ExteorFrame.h new file mode 100644 index 0000000..cbec8ce --- /dev/null +++ b/include/xtr/ui/ExteorFrame.h @@ -0,0 +1,40 @@ +#pragma once + +namespace xtr::ui { + +//! Frame: Exteor Application +class ExteorFrame final : public CMDIFrameWndEx { + enum MenuMode : uint8_t { + MODE_DEFAULT, + MODE_RSFORM, + MODE_RSMODEL, + MODE_OSS, + }; + + CMFCStatusBar statusbar{}; + CMFCToolBar mainTool{}; + CMFCToolBar rsTool{}; + CMFCToolBar ossTool{}; + +public: + void SetLangStatusText(CString text); + void UpdateUI(); + +private: + BOOL PreCreateWindow(CREATESTRUCT& cs) override; + +DECLARE_MESSAGE_MAP() + afx_msg int32_t OnCreate(LPCREATESTRUCT lpCreateStruct); + + BOOL CreateControls(); + void InitControls(); + + afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCDS); + afx_msg void OnActivateApp(BOOL bActive, DWORD dwThreadID); + afx_msg void OnDropFiles(HDROP hDropInfo); + +private: + static void InitVisualStyle(); +}; + +} // namespace xtr::ui \ No newline at end of file diff --git a/include/xtr/ui/HelpHandler.h b/include/xtr/ui/HelpHandler.h new file mode 100644 index 0000000..aa2f3bc --- /dev/null +++ b/include/xtr/ui/HelpHandler.h @@ -0,0 +1,43 @@ +#pragma once + +namespace xtr::ui { + +enum class HelpID : uint32_t { + mainPage, + + viewRSForm, + viewRSModel, + viewRSOSS, + + editCst, + generateCst, + synthes, + exportRSForm, + options, + operations, + editData, + + rslanguage, +}; + +//! Help file handler +class HelpHandler { + std::map helpBase{}; + +public: + HelpHandler(const HelpHandler&) = delete; + HelpHandler& operator=(const HelpHandler&) = delete; + +private: + HelpHandler(); + ~HelpHandler() noexcept = default; + +public: + [[nodiscard]] static HelpHandler& Instance(); + static void RunHelp(HelpID targetPage = HelpID::mainPage); + +private: + static CString HID2CStr(HelpID pageID); +}; + +} // namespace xtr::ui \ No newline at end of file diff --git a/include/xtr/ui/KeyboardHandler.h b/include/xtr/ui/KeyboardHandler.h new file mode 100644 index 0000000..3e3f596 --- /dev/null +++ b/include/xtr/ui/KeyboardHandler.h @@ -0,0 +1,51 @@ +#pragma once + +namespace xtr::ui { + +//! Keyboard layout handler +class Keyboard { +public: + enum class Layout : uint32_t { ENG, RUS, MATH, }; + +private: + Layout systemLayout{ Layout::ENG }; + Layout currentLayout{ Layout::ENG }; + + std::set indicators; + + HKL russianHKL; + HKL englishHKL; + +public: + ~Keyboard() noexcept = default; + Keyboard(const Keyboard&) = delete; + Keyboard& operator=(const Keyboard&) = delete; + +private: + Keyboard(); + +public: + [[nodiscard]] static Keyboard& Instance(); + [[nodiscard]] static inline BOOL IsPressed(int keyID) noexcept { + return HIWORD(::GetKeyState(keyID)) != 0; + } + + void SetLayout(Layout newLang); + [[nodiscard]] Layout GetLayout() const noexcept; + + void ResetSystemLayout(); + void ImportSystemLayout(); + void RotateLayout(); + + void RegisterIndicator(CWnd* wnd); + void UnregisterIndicator(CWnd* wnd); + +private: + [[nodiscard]] static Layout GetKeybLang(); + static void SetSystemLayout(HKL newLayout) noexcept; + + void UpdateIndicators(); + void SetInternalLayout(Layout newLang); +}; + +} // namespace xtr::ui \ No newline at end of file diff --git a/include/xtr/ui/RSEdit.h b/include/xtr/ui/RSEdit.h new file mode 100644 index 0000000..34dbf3d --- /dev/null +++ b/include/xtr/ui/RSEdit.h @@ -0,0 +1,83 @@ +#pragma once + +#include "xtr/core/rslIndex.hpp" +#include "xtr/ui/BuffRichEdit.h" + +namespace xtr::ui { + +//! Control: Edit RS expression +class RSEdit : public BuffRichEdit { + const ccl::semantic::RSCore* context{ nullptr }; + EntityUID activeUID{}; + + ccl::rslang::Parser parser{}; + std::unique_ptr checker{ nullptr }; + CString astText{}; + + StrPos prefixLen{ 0 }; + bool navigatorEnabled{ false }; + std::optional activeNode{}; + +public: + RSEdit(); + RSEdit(const RSEdit&) = delete; + RSEdit& operator=(const RSEdit&) = delete; + +public: + void InputBrackets(); + void InputParenthesis(); + void InputToken(ccl::rslang::TokenID token); + void Init(const ccl::semantic::RSCore& cntxt, EntityUID active); + +private: + void PreSubclassWindow() override; + BOOL PreTranslateMessage(MSG* pMsg) override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnChar(uint32_t nChar, uint32_t nRepCnt, uint32_t nFlags); + afx_msg void OnSysChar(uint32_t nChar, uint32_t nRepCnt, uint32_t nFlags); + afx_msg void OnKeyDown(uint32_t nChar, uint32_t nRepCnt, uint32_t nFlags); + +private: + BOOL UpdateAST(); + + struct BracketPair { + std::optional left{ std::nullopt }; + std::optional right{ std::nullopt }; + + [[nodiscard]] StrRange Range() const { + return StrRange{ left.value(), right.value() }; + } + [[nodiscard]] bool IsNull() const noexcept { + return !left.has_value() && !right.has_value(); + } + [[nodiscard]] bool IsCorrect() const noexcept { + return left.has_value() && right.has_value(); + } + }; + + void UpdateFormatItems() override; + void AdditionalFormat() override; + [[nodiscard]] CString GenerateToolTipText() override; + + void FormatBracketsAround(StrPos caretPos); + void FormatSelectedBlock(StrRange selection); + void FormatIdentifier(ccl::rslang::TokenID tid, StrRange pos); + void FormatBracket(int32_t level, StrRange pos); + + void SelectPairedBracket(StrPos caretPos); + [[nodiscard]] std::optional GetBracketPair(StrPos pos, TCHAR leftBracket, TCHAR rightBracket) const; + + void FormatIndex(ccl::rslang::TokenID tid, StrRange pos, StrPos prefix, BOOL subscript); + void AddReference(); + + void InsertRSText(CString text, StrRange sel); + + BOOL NavigatorOn(); + BOOL MoveUp() noexcept; + BOOL MoveDown(); + BOOL MoveLeft(); + BOOL MoveRight(); +}; + +} // namespace xtr::ui \ No newline at end of file diff --git a/include/xtr/ui/RSListCtrl.h b/include/xtr/ui/RSListCtrl.h new file mode 100644 index 0000000..93a6680 --- /dev/null +++ b/include/xtr/ui/RSListCtrl.h @@ -0,0 +1,24 @@ +#pragma once + +namespace xtr::ui { + +//! Control: List of constituents +class RSListCtrl : public CListCtrl { +public: + [[nodiscard]] int32_t GetColumnCount() const; + [[nodiscard]] int32_t GetFocusIndex() const; + [[nodiscard]] int32_t GetSelectedIndex() const; + void SetSelection(int32_t nIndex); + void ClearSelection(); + + void MoveSelectedItemsTo(RSListCtrl& dest, int32_t coloumns); + +protected: + BOOL PreTranslateMessage(MSG* pMsg) override; + void PreSubclassWindow() override; + +private: + [[nodiscard]] BOOL IsItemSelected(int32_t item); +}; + +} // namespace xtr::ui \ No newline at end of file diff --git a/include/xtr/ui/RSTableCtrl.h b/include/xtr/ui/RSTableCtrl.h new file mode 100644 index 0000000..80f6465 --- /dev/null +++ b/include/xtr/ui/RSTableCtrl.h @@ -0,0 +1,90 @@ +#pragma once + +#include "RSListCtrl.h" +#include "xtr/doc/RSFacade.h" + +namespace xtr::ui { + +//! Control: Table of constituents for RSFormDoc and RSModelDoc +class RSTableCtrl final : public RSListCtrl { + struct SchemaHeader; + struct ModelHeader; + +public: + enum ViewMode { MODE_RSFORM = 1, MODE_RSMODEL, }; + +private: + doc::RSFacade* editor{ nullptr }; + ccl::SetOfEntities selection{}; + + BOOL disableReentrance{ FALSE }; + + struct DnD { + BOOL active{ FALSE }; + + int32_t dragFrom{}; + std::optional dragTo{}; + CWnd* source{ nullptr }; + CWnd* destination{ nullptr }; + }; + DnD dnd{}; + + CToolTipCtrl tooltips{}; + +public: + [[nodiscard]] BOOL IsInit() const noexcept { + return editor != nullptr; + } + void Init(doc::RSFacade& doc); + void Update(BOOL updateSelection = FALSE); + + [[nodiscard]] const ccl::SetOfEntities& Selection() const noexcept { + return selection; + } + void Select(EntityUID uid, BOOL bClearSelection = FALSE); + void SelectMultiple(const ccl::SetOfEntities& selList); + void EnsureVisibleCst(EntityUID uid); + void ResetColumns(); + + [[nodiscard]] std::optional UIDForIndex(int nItem) const; + [[nodiscard]] std::optional IndexForUID(EntityUID uid) const; + + [[nodiscard]] BOOL IsCommandActive(uint32_t command) const noexcept; + BOOL RunCommand(uint32_t command); + +private: + BOOL PreTranslateMessage(MSG *pMsg) override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnDestroy(); + afx_msg void OnMouseMove(uint32_t nFlags, CPoint point); + afx_msg void OnLButtonUp(uint32_t nFlags, CPoint point); + afx_msg BOOL OnBegindragConstituenta(NMHDR *pNMHDR, LRESULT *result); + afx_msg BOOL OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *result); + afx_msg BOOL OnDblclkConstituenta(NMHDR *pNMHDR, LRESULT *result); + afx_msg BOOL OnSelectChange(NMHDR *pNMHDR, LRESULT *result); + +private: + void InitToolTips(); + void InitHeaders(); + + void InsertCst(EntityUID target); + void InputCstData(int32_t nItem, EntityUID target); + void UpdateSelList(); + + void ResetHighlightScroll(); + void UpdateHighlightScroll(CPoint cursorPos); + void DrawSingleCell(NMLVCUSTOMDRAW* device); + + void PasteFromClipboard(); + ccl::VectorOfEntities InsertClipboard(); + void MoveUp(); + void MoveDown(); + + void ActivateCst(); + void MoveSelectedBefore(int32_t index); + + static BOOL ProcessDrawStages(const NMLVCUSTOMDRAW* device, LRESULT* result) noexcept; +}; + +} // namespace xtr::ui \ No newline at end of file diff --git a/include/xtr/ui/SplitterFrame.h b/include/xtr/ui/SplitterFrame.h new file mode 100644 index 0000000..f1edd9c --- /dev/null +++ b/include/xtr/ui/SplitterFrame.h @@ -0,0 +1,63 @@ +#pragma once + +namespace xtr::ui { + +// don't sugget noexcept for default virtual implementations +#pragma warning( push ) +#pragma warning( disable : 26440 ) + +//! Frame: 2 pane splitter +class Split2ViewFrame : public CMDIChildWndEx { + CString registryName; + SIZE minSize; + uint32_t minPane2Width; + + int32_t& secondViewWidth; + + CSplitterWnd splitterWnd{}; + +public: + ~Split2ViewFrame() override = default; + Split2ViewFrame(const Split2ViewFrame&) = delete; + Split2ViewFrame& operator=(const Split2ViewFrame&) = delete; + +protected: + Split2ViewFrame(uint32_t registryID, SIZE minSize, + uint32_t minPane2Width, int& splitterTracker); + +private: + BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) override; + +private: + DECLARE_MESSAGE_MAP() + afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI); + afx_msg void OnDestroy(); + afx_msg void OnMDIActivate(BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd); + +private: + virtual CRuntimeClass* SecondViewClass() { return nullptr; } + virtual void PostCreateSetup(CWnd* /*firstView*/, CWnd* /*secondView*/) {} +}; + +class RSFormFrame : public Split2ViewFrame { + DECLARE_DYNCREATE(RSFormFrame) + RSFormFrame(); + CRuntimeClass* SecondViewClass() override; +}; + +class RSModelFrame final : public Split2ViewFrame { + DECLARE_DYNCREATE(RSModelFrame) + RSModelFrame(); + CRuntimeClass* SecondViewClass() override; +}; + +class OSSFrame final : public Split2ViewFrame { + DECLARE_DYNCREATE(OSSFrame) + OSSFrame(); + CRuntimeClass* SecondViewClass() override; + void PostCreateSetup(CWnd* firstView, CWnd* secondView) override; +}; + +#pragma warning( pop ) + +} // namespace xtr::ui \ No newline at end of file diff --git a/include/xtr/ui/TextEdit.h b/include/xtr/ui/TextEdit.h new file mode 100644 index 0000000..3b76480 --- /dev/null +++ b/include/xtr/ui/TextEdit.h @@ -0,0 +1,68 @@ +#pragma once + +#include "xtr/ui/BuffRichEdit.h" +#include "xtr/viewmodel/vmTextEdit.h" +#include "xtr/doc/RSFacade.h" + +namespace xtr::ui { + +//! Referenced text editor control +class TextEdit : public BuffRichEdit, public viewmodel::ITextEdit { + xtr::viewmodel::vmTextEdit presenter; + + BOOL resolveRefs{ FALSE }; + BOOL ignoreReturn{ FALSE }; + + doc::RSFacade* editor{ nullptr }; + +public: + TextEdit(); + + void Initialize(CString refStr, doc::RSFacade& targetEditor, BOOL advancedRefs, BOOL wantReturn = TRUE); + +public: + void SetRefStr(CString refStr); + [[nodiscard]] CString GetRefStr(); + +private: + [[nodiscard]] CString GetText() const override; + void SetText(CString text) override; + void ReplaceRange(StrRange range, CString replacement) override; + + void Highlight(viewmodel::HighlightItem item) override; + [[nodiscard]] std::optional NextHighlighted(StrPos start) override; + +private: + void PreSubclassWindow() override; + BOOL PreTranslateMessage(MSG* pMsg) override; + + void UnFreezeUI() override; + CString GenerateToolTipText() override; + +DECLARE_MESSAGE_MAP() + afx_msg BOOL OnTextChange(); + afx_msg BOOL OnSelChange(NMHDR* pNotifyStruct, LRESULT* result); + afx_msg void OnKeyDown(uint32_t key, uint32_t nRepCnt, uint32_t nFlags); + + [[nodiscard]] BOOL ProcessKeyDown(uint32_t key, uint32_t nRepCnt, uint32_t nFlags); + [[nodiscard]] BOOL PreProcessKey(uint32_t key); + [[nodiscard]] BOOL ProcessKeyConst(uint32_t key); + [[nodiscard]] BOOL ProcessKeyEdit(uint32_t key); + +private: + void UpdateLock(); + + BOOL RunAddTerminRef(); + BOOL RunAddDependWord(); + [[nodiscard]] RECT GetWordDlgPos(); + + void CopyWithReferences(StrRange range); + StrRange ShrinkSelection(); + + void ResetHighlight(StrRange hlRange); + + [[nodiscard]] BOOL IsBorderHL(StrPos position, BOOL oneSide = FALSE); + [[nodiscard]] std::optional ScanHighlight(StrPos start); +}; + +} // namespace xtr::ui \ No newline at end of file diff --git a/include/xtr/ui/UIHelper.h b/include/xtr/ui/UIHelper.h new file mode 100644 index 0000000..b6d50e6 --- /dev/null +++ b/include/xtr/ui/UIHelper.h @@ -0,0 +1,63 @@ +#pragma once + +#define XTR_COMMAND_UPD(cmd) \ +ON_UPDATE_COMMAND_UI(cmd, &ThisClass::OnUpdateCommandUI) \ +ON_COMMAND_EX(cmd, &ThisClass::OnCommandRun) + +#define XTR_COMMAND(cmd) \ +ON_COMMAND_EX(cmd, &ThisClass::OnCommandRun) + +namespace xtr::ui { + +static constexpr auto s_ScrollWidth = 22; +static constexpr auto s_TooltipWidth = 400; + +TEXTMETRIC GlobalTextMetrics(); +TEXTMETRIC TextMetricsOf(const CWnd& wndCtrl); + +CRect LocalCoordinatesFor(const CWnd& wndCtrl); +CRect ClientRect(const CWnd& wndCtrl); +CRect WindowRect(const CWnd& wndCtrl); +CString WindowText(const CWnd& wndCtrl); + +CString TrimText(CString text); + +class Header { +public: + struct Column; +private: + std::vector columns{}; + +public: + ~Header() = default; + Header() = default; + Header(const Header&) = delete; + Header& operator=(const Header&) = delete; + +public: + enum Alignment : uint8_t { left = LVCFMT_LEFT, right = LVCFMT_RIGHT, center = LVCFMT_CENTER}; + struct Column { + CString label; + Alignment alignment; + std::optional width; + + Column(CString label, Alignment alignment, std::optional width) + : label{ label }, alignment{ alignment }, width{ width } {} + Column(uint32_t sid, Alignment alignment, std::optional width) + : label{ mfc::LoadSID(sid) }, alignment{ alignment }, width{ width } {} + }; + +public: + void AddColumn(const Column& newColumn) { + columns.emplace_back(newColumn); + } + +private: + friend void InitHeaderFor(CListCtrl& listCtr, const Header& header); + friend void InitReversedHeaderFor(CListCtrl& listCtr, const Header& header); +}; + +void InitHeaderFor(CListCtrl& listCtr, const Header& header); +void InitReversedHeaderFor(CListCtrl& listCtr, const Header& header); + +} // namespace xtr::ui \ No newline at end of file diff --git a/include/xtr/view/OSSLayout.h b/include/xtr/view/OSSLayout.h new file mode 100644 index 0000000..e1df546 --- /dev/null +++ b/include/xtr/view/OSSLayout.h @@ -0,0 +1,89 @@ +#pragma once + +namespace xtr::view { + +//! OSS drawing manager +class OSSLayout { + enum class IconID : uint8_t { + OSSI_PICT_BASIS = 0, + OSSI_PICT_UNDEFINED = 1, + OSSI_PICT_DEFINED = 2, + OSSI_PICT_DONE = 3, + OSSI_PICT_REDO = 4, + OSSI_PICT_BROKEN = 5, + OSSI_PICT_HASFILE = 6, + }; + + struct Buffer { + CRect rect{}; + CBitmap bmp{}; + CBitmap* oldBitmap{ nullptr }; + CDC context{}; + }; + +public: + mutable CImageList icons{}; + + float zoom; + + int32_t charHeight; + int32_t charWidth; + + int32_t cellWidth; + int32_t cellHeight; + + int32_t pictWidth; + int32_t pictHeight; + + mutable int32_t legendYBase{ 0 }; + +private: + const ccl::oss::OSSchema* oss; + + BOOL saveImage{ FALSE }; + CDC* drawDC{ nullptr }; + float drawScale{ 1 }; + std::unique_ptr buffer{}; + +public: + explicit OSSLayout(const ccl::oss::OSSchema& oss); + +public: + void InitImageList(); + + [[nodiscard]] int32_t GetClientHeight() const; + [[nodiscard]] int32_t GetClientWidth() const; + + [[nodiscard]] CRect PictRect(ccl::oss::PictID pid, float scale = 1) const; + [[nodiscard]] CRect CellRect(ccl::oss::GridPosition pos, float scale = 1) const noexcept; + + [[nodiscard]] ccl::oss::PictPtr PictFromPoint(CPoint point) const; + + void Draw(CDC* pDC, std::optional active = std::nullopt); + CImage GetImage(); + +private: + std::optional PositionFromPoint(CPoint point) const noexcept; + + CRect DetermineDrawArea(); + void PrepareBuffer(CDC* pDC, CRect clientArea); + void DrawBackground(CRect bgRect); + void DrawGrid(); + void DrawCell(ccl::oss::GridPosition pos); + void DrawPictConnections(const ccl::oss::Pict& pict); + void DrawPict(const ccl::oss::Pict& pict, bool isActive); + void DrawLegend(); + void DrawLegendItem(IconID icon, CString text); + void LoadFromBuffer(CDC* pDC); + + void DrawActiveRect(CRect rect); + void DrawInactiveRect(CRect rect); + void DrawPictStatus(CRect rect, ccl::oss::PictID pid); + void DrawPictText(CRect rect, const ccl::oss::Pict & pict); + + void DrawStatusIcon(CPoint topLeft, ccl::oss::PictID pid) const; + + IconID GetIconID(ccl::oss::PictID pid) const; +}; + +} // namespace xtr::view \ No newline at end of file diff --git a/include/xtr/view/OSSView.h b/include/xtr/view/OSSView.h new file mode 100644 index 0000000..a00ef82 --- /dev/null +++ b/include/xtr/view/OSSView.h @@ -0,0 +1,69 @@ +#pragma once + +#include "OSSLayout.h" +#include "xtr/doc/OSSDoc.h" + +namespace xtr::view { + +//! View: OSS +class OSSView final : public CScrollView { + friend class OSSLayout; + DECLARE_DYNCREATE(OSSView) + + doc::OSSDoc* document{ nullptr }; + ccl::oss::OSSchema* oss{ nullptr }; + std::unique_ptr layout{ nullptr }; + + CToolTipCtrl tooltips; + + HCURSOR cursorHyperlink{}; + HCURSOR cursorMarkOperation{}; + BOOL newOperationMode{ FALSE }; + + std::optional pictUnderCursor{}; + +private: + OSSView() = default; + +private: + void DoDataExchange(CDataExchange* pDX) override; + void OnInitialUpdate() override; + void InitCursor(); + void InitTooltips(); + +private: + BOOL PreTranslateMessage(MSG* pMsg) override; + void OnDraw(CDC* pDC) override; + void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) override; + BOOL OnScrollBy(CSize sizeScroll, BOOL bDoScroll) override; + +DECLARE_MESSAGE_MAP() + afx_msg BOOL OnCommandRun(uint32_t command); + afx_msg void OnUpdateCommandUI(CCmdUI* pCmdUI); + + afx_msg BOOL OnMouseWheel(uint32_t fFlags, short zDelta, CPoint pt); + afx_msg BOOL OnSetCursor(CWnd* pWnd, uint32_t nHitTest, uint32_t message); + afx_msg void OnMouseMove(uint32_t nFlags, CPoint point); + afx_msg void OnMouseHover(uint32_t nFlags, CPoint point); + afx_msg void OnLButtonUp(uint32_t nFlags, CPoint point); + afx_msg void OnRButtonUp(uint32_t nFlags, CPoint point); + afx_msg void OnLButtonDblClk(uint32_t nFlags, CPoint point); + afx_msg void OnContextMenu(CWnd* pWnd, CPoint point); + afx_msg void OnSetFocus(CWnd* pOldWnd); + +private: + void StartHoverTimer() noexcept; + + void UpdateScrollSize(); + void UpdateCursor(ccl::oss::PictPtr pict = nullptr) const; + void ScrollToSelected(); + + [[nodiscard]] BOOL IsCommandActive(uint32_t command) const; + + void DocToClient(CRect& rect); + void DocToClient(CPoint& point); + void ClientToDoc(CPoint& point); + void ClientToDoc(CRect& rect); +}; + +} // namespace xtr::view \ No newline at end of file diff --git a/include/xtr/view/PictView.h b/include/xtr/view/PictView.h new file mode 100644 index 0000000..a43ef96 --- /dev/null +++ b/include/xtr/view/PictView.h @@ -0,0 +1,68 @@ +#pragma once + +#include "xtr/doc/OSSDoc.h" + +#include "xtr/ui/RSEdit.h" +#include "xtr/ui/RSListCtrl.h" + +namespace xtr::view { + +//! View: OSS pictogramm +class PictView final: public CFormView { + DECLARE_DYNCREATE(PictView) + + struct TableHeader; + + ccl::oss::OSSchema* oss{ nullptr }; + + CListCtrl optionsCtrl; + CEdit fullNameCtrl; + CEdit shortNameCtrl; + CEdit ossNameCtrl; + CEdit opStatusCtrl; + CEdit operationCtrl; + ui::RSEdit commentCtrl; + CButton changeFileBtn; + + CString ossTitle; + CString pictAlias; + CString pictTitle; + CString operand1; + CString operand2; + CString status; + CString opType; + CString dataType; + CString comment; + +private: + PictView(); + +private: + void DoDataExchange(CDataExchange* pDX) override; + void LoadData(); + void LoadOperation(); + void SaveData(); + void UpdateUI(); + void OnInitialUpdate() override; + void InitMapCtrl(); + void InitCommentCtrl(); + +private: + void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) override; + +DECLARE_MESSAGE_MAP() + afx_msg void OpenHelp(); + afx_msg void OnChange(); + afx_msg void OnOSSComment(); + afx_msg void OnPictLink(); + afx_msg void OnOSSFileName(); + afx_msg void OnPictFileName(); + afx_msg void OnOpenOSSFolder(); + afx_msg void OnBackup(); + +private: + doc::OSSDoc& Document() noexcept; + void UpdateMapCtrl(ccl::oss::PictID pid); +}; + +} // namespace xtr::view \ No newline at end of file diff --git a/include/xtr/view/RSFormView.h b/include/xtr/view/RSFormView.h new file mode 100644 index 0000000..3aef3bf --- /dev/null +++ b/include/xtr/view/RSFormView.h @@ -0,0 +1,70 @@ +#pragma once + +#include "xtr/ui/RSTableCtrl.h" +#include "xtr/ui/RSEdit.h" +#include "xtr/doc/RSFacade.h" + +namespace xtr::view { + +//! View: RSForm table +class RSFormView : public CFormView { + DECLARE_DYNCREATE(RSFormView) + + doc::RSFacade editor{}; + ccl::semantic::RSForm* schema{ nullptr }; + + CString alias{}; + CString title{}; + + ui::RSEdit titleCtrl{}; + ui::RSEdit aliasCtrl{}; + CRichEditCtrl rsformStatusCtrl{}; + ui::RSEdit searchCtrl{}; + CToolTipCtrl tooltips{}; + ui::RSTableCtrl cstTable{}; + +private: + RSFormView(); + +private: + void DoDataExchange(CDataExchange* pDX) override; + void OnInitialUpdate() override; + void InitControls(); + void InitTooltips(); + +private: + BOOL PreTranslateMessage(MSG* pMsg) override; + BOOL OnCmdMsg(uint32_t nID, int32_t nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) override; + void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnContextMenu(CWnd* pWnd, CPoint point); + afx_msg void OnChange(); + afx_msg BOOL OnCopy(uint32_t msgID); + afx_msg BOOL OnPaste(uint32_t msgID); + afx_msg void OnEditComment(); + afx_msg void OnUpdateCommandUI(CCmdUI *pCmdUI); + afx_msg BOOL OnCommandRun(uint32_t command); + afx_msg BOOL OnInsertCst(uint32_t command); + afx_msg BOOL OnOperation(uint32_t command); + afx_msg void OpenHelp(); + afx_msg void OnOpMaxPart(); + afx_msg void OnOpExtractBasis(); + afx_msg void OnUpdateStatus(); + +private: + BOOL IsCommandActive(uint32_t command) const; + BOOL IsContextActive(uint32_t command) const; + + void InsertNew(ccl::semantic::CstType cstType, int32_t nWhere = -1); + void InsertFree(); + + const SetOfEntities& Selection() const noexcept; + + void UpdateStatusBar(); + + void RunRelation(); + void OnSearch(); +}; + +} // namespace xtr::view \ No newline at end of file diff --git a/include/xtr/view/RSModelView.h b/include/xtr/view/RSModelView.h new file mode 100644 index 0000000..3eeecc1 --- /dev/null +++ b/include/xtr/view/RSModelView.h @@ -0,0 +1,67 @@ +#pragma once + +#include "xtr/ui/RSTableCtrl.h" +#include "xtr/ui/RSEdit.h" +#include "xtr/doc/RSModelDoc.h" + +namespace xtr::view { + +//! View: RSModel table +class RSModelView : public CFormView { + DECLARE_DYNCREATE(RSModelView) + + doc::RSFacade editor{}; + ccl::semantic::RSModel* model{ nullptr }; + + CString title{}; + CString alias{}; + + ui::RSEdit titleCtrl{}; + ui::RSEdit aliasCtrl{}; + ui::RSEdit searchCtrl{}; + CRichEditCtrl rsformStatusCtrl{}; + CRichEditCtrl rsModelStatusCtrl{}; + + CToolTipCtrl tooltips{}; + ui::RSTableCtrl cstTable{}; + +private: + RSModelView(); + +private: + void DoDataExchange(CDataExchange* pDX) override; + void OnInitialUpdate() override; + void InitControls(); + void InitTooltips(); + +private: + BOOL PreTranslateMessage(MSG* pMsg) override; + BOOL OnCmdMsg(uint32_t nID, int32_t nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) override; + void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) override; + +DECLARE_MESSAGE_MAP() + afx_msg void OnContextMenu(CWnd* pWnd, CPoint point); + afx_msg void OnChange(); + afx_msg void OpenHelp(); + afx_msg BOOL OnCopy(uint32_t msgID); + afx_msg BOOL OnPaste(uint32_t msgID); + afx_msg void OnEditComment(); + afx_msg void OnUpdateStatus(); + afx_msg void OnCalculateAll(); + afx_msg BOOL OnOperation(uint32_t command); + afx_msg BOOL OnInsertCst(uint32_t command); + afx_msg BOOL OnCommandRun(uint32_t command); + afx_msg void OnUpdateCommandUI(CCmdUI* pCmdUI); + +private: + const SetOfEntities& Selection() const noexcept; + BOOL IsCommandActive(uint32_t command) const noexcept; + BOOL IsContextActive(uint32_t command) const; + void UpdateStatusBar(); + void OnSearch(); + + void InsertNew(ccl::semantic::CstType cstType, int32_t nWhere = -1); + void InsertFree(); +}; + +} // namespace xtr::view \ No newline at end of file diff --git a/include/xtr/view/TermTreeView.h b/include/xtr/view/TermTreeView.h new file mode 100644 index 0000000..fad98d3 --- /dev/null +++ b/include/xtr/view/TermTreeView.h @@ -0,0 +1,36 @@ +#pragma once + +#include "xtr/doc/Documents.h" + +namespace xtr::view { + +//! View: RSForm TermTree +class TermTreeView : public CFormView { + DECLARE_DYNCREATE(TermTreeView) + + doc::SelectableDoc* document{ nullptr }; + const ccl::semantic::RSCore* core{ nullptr }; + CTreeCtrl termTreeCtrl{}; + +private: + TermTreeView(); + +private: + void DoDataExchange(CDataExchange* pDX) override; + void OnInitialUpdate() override; + +private: + void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) override; + +DECLARE_MESSAGE_MAP() + afx_msg void OpenHelp(); + afx_msg void OnDblclkTermTree(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnBuild(); + +private: + BOOL BuildTree(); + static HTREEITEM FindItemInTree(const CTreeCtrl* termTree, CString sFindName); + static int32_t InsertSubTree(CTreeCtrl* termTree, HTREEITEM current, CString sName); +}; + +} // namespace xtr::view \ No newline at end of file diff --git a/include/xtr/viewmodel/vmMeta.hpp b/include/xtr/viewmodel/vmMeta.hpp new file mode 100644 index 0000000..43f7961 --- /dev/null +++ b/include/xtr/viewmodel/vmMeta.hpp @@ -0,0 +1,11 @@ +#pragma once + +namespace xtr::viewmodel { + +//! Abstract freezable UI control +struct IFreezable { + virtual void FreezeUI() = 0; + virtual void UnFreezeUI() = 0; +}; + +} // namespace xtr::viewmodel \ No newline at end of file diff --git a/include/xtr/viewmodel/vmTextEdit.h b/include/xtr/viewmodel/vmTextEdit.h new file mode 100644 index 0000000..e0a3e5c --- /dev/null +++ b/include/xtr/viewmodel/vmTextEdit.h @@ -0,0 +1,55 @@ +#pragma once + +#include "vmMeta.hpp" + +#include "ccl/lang/RefsManager.h" + +namespace xtr::viewmodel { + +struct HighlightItem { + StrRange rng{}; + COLORREF color{}; +}; + +//! Abstract interface for TextEdit control +struct ITextEdit { + [[nodiscard]] virtual CString GetText() const = 0; + virtual void SetText(CString newText) = 0; + virtual void ReplaceRange(StrRange range, CString replacement) = 0; + + virtual void Highlight(HighlightItem item) = 0; + [[nodiscard]] virtual std::optional NextHighlighted(StrPos start) = 0; +}; + +//! Presenter: TextEdit +class vmTextEdit { + ITextEdit& control; + + bool outdated{ true }; + const ccl::lang::EntityTermContext* context{ nullptr }; + ccl::lang::RefsManager references{}; + +public: + explicit vmTextEdit(ITextEdit& control) noexcept + : control{ control } {} + void Initialize(const ccl::lang::EntityTermContext& cntxt) noexcept; + +public: + void SetRefStr(CString refStr); + + [[nodiscard]] const ccl::lang::EntityTermContext& Context() const noexcept { return *context; } + + [[nodiscard]] CString GetRefStr(); + [[nodiscard]] CString GetRefSubstr(StrRange cr); + + void Invalidate() noexcept { outdated = true; } + + void OnEraseText(StrRange range, BOOL lookBehind); + void OnInsertRef(ccl::StrRange rWhere, ccl::lang::Reference data); + [[nodiscard]] const ccl::lang::Reference* RepresentativeOf(StrRange range); + +private: + void UpdateData(); +}; + +} // namespace xtr::viewmodel \ No newline at end of file diff --git a/include/xtr/xtrDesign.h b/include/xtr/xtrDesign.h new file mode 100644 index 0000000..ca259c1 --- /dev/null +++ b/include/xtr/xtrDesign.h @@ -0,0 +1,45 @@ +#pragma once + +#include "xtr/cclDescriptor.h" + +namespace xtr::design { + +static constexpr auto clrWhite = RGB(255, 255, 255); +static constexpr auto clrBlack = RGB(0, 0, 0); +static constexpr auto clrGray200 = RGB(200, 200, 200); +static constexpr auto clrGray211 = RGB(211, 211, 211); +static constexpr auto clrGray233 = RGB(233, 233, 233); + +static constexpr auto clrRed = RGB(255, 0, 0); +static constexpr auto clrGreen = RGB(0, 255, 0); +static constexpr auto clrBlue = RGB(0, 0, 255); +static constexpr auto clrYellow = RGB(255, 255, 0); + +static constexpr auto clrTeal = RGB(0, 200, 200); +static constexpr auto clrJade = RGB(0, 168, 107); +static constexpr auto clrPurple = RGB(178, 102, 255); + +[[nodiscard]] CHARFORMAT2W CharFormatRE() noexcept; + +[[nodiscard]] COLORREF Color(ccl::rslang::TokenID token) noexcept; +[[nodiscard]] COLORREF Color(ccl::semantic::ParsingStatus status) noexcept; +[[nodiscard]] COLORREF Color(info::CoreStatus status) noexcept; +[[nodiscard]] COLORREF Color(info::ModelStatus status) noexcept; +[[nodiscard]] COLORREF Color(ccl::semantic::EvalStatus status) noexcept; +[[nodiscard]] COLORREF Color(ccl::rslang::ValueClass status) noexcept; +[[nodiscard]] COLORREF Color(ccl::lang::ReferenceType type) noexcept; + +[[nodiscard]] COLORREF TextColor(const ccl::semantic::RSForm& schema, EntityUID target); +[[nodiscard]] COLORREF TextColor(const ccl::semantic::RSModel& model, EntityUID target); +[[nodiscard]] COLORREF BackgroundColor(const ccl::semantic::RSForm& schema, EntityUID target); +[[nodiscard]] COLORREF BackgroundColor(const ccl::semantic::RSModel& model, EntityUID target) noexcept; + +[[nodiscard]] COLORREF BackgroundColor(const ccl::oss::OSSchema& oss, ccl::oss::PictID target); + +[[nodiscard]] COLORREF BracketsColor(int32_t level); + +[[nodiscard]] constexpr BOOL IsReference(const COLORREF color) noexcept { + return color == clrYellow || color == clrGray200; +} + +} // namespace xtr::design \ No newline at end of file diff --git a/include/xtr/xtrProcedures.h b/include/xtr/xtrProcedures.h new file mode 100644 index 0000000..095b3f1 --- /dev/null +++ b/include/xtr/xtrProcedures.h @@ -0,0 +1,64 @@ +#pragma once + +namespace xtr::doc { +class SelectableDoc; +class RSFormDoc; +class RSModelDoc; +class RSFacade; +class OSSDoc; +} // namespace xtr::doc + +namespace xtr::view { class OSSLayout; } // namespace xtr::view + +//! Namespace to extract task logic from ui, dialog and view +namespace xtr::proc { + +void ImportCstDataFromExcel(ccl::semantic::RSModel& model, EntityUID target); +void ExportCstGraph(const ccl::semantic::RSCore& source, CString path); +void ExportSchema(const ccl::semantic::RSForm& schema, CString path); +void ExportModelSchema(const ccl::semantic::RSModel& model, CString path); +void ExportModel(const doc::RSModelDoc& document); +void EraseCstData(ccl::semantic::RSModel& model, EntityUID target); +void ExportCstDataToExcel(const ccl::semantic::RSModel& model, EntityUID target); +void ExportOSS(const doc::OSSDoc& document); +void ExportOSSGraph(const doc::OSSDoc& document, view::OSSLayout& layout); + +void EditConstituenta(doc::RSFacade& editor, EntityUID target); +void EditComment(doc::RSFacade& editor); +void ResetNames(doc::RSFacade& editor); +void RenameCst(doc::RSFacade& editor); +void Term2Function(doc::RSFacade& editor); +void Function2Term(doc::RSFacade& editor); +void Structure2Terms(doc::RSFacade& editor); +void MoveCstBefore(doc::RSFacade& editor, const SetOfEntities& what, ccl::semantic::ListIterator pos); + +void StandaloneEquation(doc::RSFormDoc& document); +void ResetClaims(doc::RSFormDoc& document); +void EraseSelected(doc::RSFormDoc& document); + +void EraseSelected(doc::RSModelDoc& document); +void CalculateSelected(doc::RSModelDoc& document); +void CalculateAll(doc::RSModelDoc& document); + +void DoAction(doc::OSSDoc& document); +void EditSelectedOperation(doc::OSSDoc& document); +void EditSelectedHyperlink(doc::OSSDoc& document); +void EditActiveFilename(doc::OSSDoc& document); +void EditOSSFilename(doc::OSSDoc& document); +void EditComment(doc::OSSDoc& document); +void OpenSelectedSource(doc::OSSDoc& document); +void EraseSelected(doc::OSSDoc& document); +void DiscardSelectedSource(doc::OSSDoc& document); +void RunSelectedOperation(doc::OSSDoc& document); +void AttachSourceToSelected(doc::OSSDoc& document); +void RerunAllOperations(doc::OSSDoc& document); +void BackupOSS(const doc::OSSDoc& document); + +void StandaloneSynthes(ccl::ops::Type type); +void SpawnModelDocument(const ccl::semantic::RSForm& schema); +void SpawnSchemaDocument(const ccl::semantic::RSModel& model); +void ExecuteRelation(const ccl::semantic::RSForm& schema, EntityUID target); + +void FollowHyperlink(CString address, CString subaddress); + +} // namespace xtr::proc \ No newline at end of file diff --git a/include/xtr/xtrServices.h b/include/xtr/xtrServices.h new file mode 100644 index 0000000..fb22bc8 --- /dev/null +++ b/include/xtr/xtrServices.h @@ -0,0 +1,33 @@ +#pragma once + +namespace xtr { + +#pragma warning( push ) +#pragma warning( disable : 26440 ) // Don't warn about noexcept in base class + +//! Base class for message manager +struct MessageManager { + virtual ~MessageManager() noexcept = default; + + virtual uint32_t ShowMessage(CString /*text*/, uint32_t /*type*/) { return 0; } + virtual uint32_t ShowMessage(uint32_t /*messageID*/, uint32_t /*type*/) { return 0; } +}; + +#pragma warning( pop ) + +//! Enivroment Exteor configuration - !Global state! +class Global final { + std::unique_ptr messager{ std::make_unique() }; + +private: + Global() = default; + +public: + [[nodiscard]] static Global& Instance() noexcept; + [[nodiscard]] static MessageManager& Msg() noexcept { + return *Instance().messager; + } + void SetMessageManager(std::unique_ptr newMessager) noexcept; +}; + +} // namespace xtr \ No newline at end of file diff --git a/lib/x64/Htmlhelp.Lib b/lib/x64/Htmlhelp.Lib new file mode 100644 index 0000000..3f6c16e Binary files /dev/null and b/lib/x64/Htmlhelp.Lib differ diff --git a/lib/x86/Htmlhelp.Lib b/lib/x86/Htmlhelp.Lib new file mode 100644 index 0000000..1200055 Binary files /dev/null and b/lib/x86/Htmlhelp.Lib differ diff --git a/packages.config b/packages.config new file mode 100644 index 0000000..4bcfec8 --- /dev/null +++ b/packages.config @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resource/BTN_BOOLEAN.BMP b/resource/BTN_BOOLEAN.BMP new file mode 100644 index 0000000..d000c14 Binary files /dev/null and b/resource/BTN_BOOLEAN.BMP differ diff --git a/resource/BTN_DECART.BMP b/resource/BTN_DECART.BMP new file mode 100644 index 0000000..81a054b Binary files /dev/null and b/resource/BTN_DECART.BMP differ diff --git a/resource/BTN_DOUBLEPAR.bmp b/resource/BTN_DOUBLEPAR.bmp new file mode 100644 index 0000000..33a4a6c Binary files /dev/null and b/resource/BTN_DOUBLEPAR.bmp differ diff --git a/resource/BTN_DOUBLESQR.bmp b/resource/BTN_DOUBLESQR.bmp new file mode 100644 index 0000000..c00c80d Binary files /dev/null and b/resource/BTN_DOUBLESQR.bmp differ diff --git a/resource/BTN_ELEMENT.BMP b/resource/BTN_ELEMENT.BMP new file mode 100644 index 0000000..a146128 Binary files /dev/null and b/resource/BTN_ELEMENT.BMP differ diff --git a/resource/BTN_EMPTYSET.BMP b/resource/BTN_EMPTYSET.BMP new file mode 100644 index 0000000..f0bf92f Binary files /dev/null and b/resource/BTN_EMPTYSET.BMP differ diff --git a/resource/BTN_EQUAL.bmp b/resource/BTN_EQUAL.bmp new file mode 100644 index 0000000..1781399 Binary files /dev/null and b/resource/BTN_EQUAL.bmp differ diff --git a/resource/BTN_GREATER_OR_EQ.bmp b/resource/BTN_GREATER_OR_EQ.bmp new file mode 100644 index 0000000..9d87975 Binary files /dev/null and b/resource/BTN_GREATER_OR_EQ.bmp differ diff --git a/resource/BTN_LESSER_OR_EQ.bmp b/resource/BTN_LESSER_OR_EQ.bmp new file mode 100644 index 0000000..7909e2e Binary files /dev/null and b/resource/BTN_LESSER_OR_EQ.bmp differ diff --git a/resource/BTN_LOGIC_AND.bmp b/resource/BTN_LOGIC_AND.bmp new file mode 100644 index 0000000..e6855e7 Binary files /dev/null and b/resource/BTN_LOGIC_AND.bmp differ diff --git a/resource/BTN_LOGIC_EQ.bmp b/resource/BTN_LOGIC_EQ.bmp new file mode 100644 index 0000000..e146b4a Binary files /dev/null and b/resource/BTN_LOGIC_EQ.bmp differ diff --git a/resource/BTN_LOGIC_EXISTS.BMP b/resource/BTN_LOGIC_EXISTS.BMP new file mode 100644 index 0000000..94d798a Binary files /dev/null and b/resource/BTN_LOGIC_EXISTS.BMP differ diff --git a/resource/BTN_LOGIC_FORALL.BMP b/resource/BTN_LOGIC_FORALL.BMP new file mode 100644 index 0000000..4d07965 Binary files /dev/null and b/resource/BTN_LOGIC_FORALL.BMP differ diff --git a/resource/BTN_LOGIC_IMPLICAT.BMP b/resource/BTN_LOGIC_IMPLICAT.BMP new file mode 100644 index 0000000..c2d9d5f Binary files /dev/null and b/resource/BTN_LOGIC_IMPLICAT.BMP differ diff --git a/resource/BTN_LOGIC_NOT.BMP b/resource/BTN_LOGIC_NOT.BMP new file mode 100644 index 0000000..22445a7 Binary files /dev/null and b/resource/BTN_LOGIC_NOT.BMP differ diff --git a/resource/BTN_LOGIC_OR.BMP b/resource/BTN_LOGIC_OR.BMP new file mode 100644 index 0000000..4ba2321 Binary files /dev/null and b/resource/BTN_LOGIC_OR.BMP differ diff --git a/resource/BTN_NOTELEMENT.bmp b/resource/BTN_NOTELEMENT.bmp new file mode 100644 index 0000000..d11e925 Binary files /dev/null and b/resource/BTN_NOTELEMENT.bmp differ diff --git a/resource/BTN_NOTEQUAL.BMP b/resource/BTN_NOTEQUAL.BMP new file mode 100644 index 0000000..8b63c69 Binary files /dev/null and b/resource/BTN_NOTEQUAL.BMP differ diff --git a/resource/BTN_NOTSUBSET.bmp b/resource/BTN_NOTSUBSET.bmp new file mode 100644 index 0000000..b9dbb01 Binary files /dev/null and b/resource/BTN_NOTSUBSET.bmp differ diff --git a/resource/BTN_SETDECLARATION.bmp b/resource/BTN_SETDECLARATION.bmp new file mode 100644 index 0000000..a94f3d3 Binary files /dev/null and b/resource/BTN_SETDECLARATION.bmp differ diff --git a/resource/BTN_SET_INTERSECT.BMP b/resource/BTN_SET_INTERSECT.BMP new file mode 100644 index 0000000..6b624d2 Binary files /dev/null and b/resource/BTN_SET_INTERSECT.BMP differ diff --git a/resource/BTN_SET_MINUS.bmp b/resource/BTN_SET_MINUS.bmp new file mode 100644 index 0000000..fa5353c Binary files /dev/null and b/resource/BTN_SET_MINUS.bmp differ diff --git a/resource/BTN_SET_UNION.BMP b/resource/BTN_SET_UNION.BMP new file mode 100644 index 0000000..a15c166 Binary files /dev/null and b/resource/BTN_SET_UNION.BMP differ diff --git a/resource/BTN_SUBSET.bmp b/resource/BTN_SUBSET.bmp new file mode 100644 index 0000000..b2f1a69 Binary files /dev/null and b/resource/BTN_SUBSET.bmp differ diff --git a/resource/BTN_SUBSET_OR_EQ.bmp b/resource/BTN_SUBSET_OR_EQ.bmp new file mode 100644 index 0000000..e42eb41 Binary files /dev/null and b/resource/BTN_SUBSET_OR_EQ.bmp differ diff --git a/resource/BTN_SYMMINUS.bmp b/resource/BTN_SYMMINUS.bmp new file mode 100644 index 0000000..7a8599b Binary files /dev/null and b/resource/BTN_SYMMINUS.bmp differ diff --git a/resource/CREATE_OPERATION.CUR b/resource/CREATE_OPERATION.CUR new file mode 100644 index 0000000..1e61c92 Binary files /dev/null and b/resource/CREATE_OPERATION.CUR differ diff --git a/resource/ExteorApp.ico b/resource/ExteorApp.ico new file mode 100644 index 0000000..f3918ff Binary files /dev/null and b/resource/ExteorApp.ico differ diff --git a/resource/HELP.ico b/resource/HELP.ico new file mode 100644 index 0000000..35d5962 Binary files /dev/null and b/resource/HELP.ico differ diff --git a/resource/HYPERLINK.CUR b/resource/HYPERLINK.CUR new file mode 100644 index 0000000..9adfc88 Binary files /dev/null and b/resource/HYPERLINK.CUR differ diff --git a/resource/NEW_DOC.ico b/resource/NEW_DOC.ico new file mode 100644 index 0000000..71a94a8 Binary files /dev/null and b/resource/NEW_DOC.ico differ diff --git a/resource/OPEN_DOC.ico b/resource/OPEN_DOC.ico new file mode 100644 index 0000000..98fc3d4 Binary files /dev/null and b/resource/OPEN_DOC.ico differ diff --git a/resource/PICT_BASIS.ICO b/resource/PICT_BASIS.ICO new file mode 100644 index 0000000..8e54c88 Binary files /dev/null and b/resource/PICT_BASIS.ICO differ diff --git a/resource/PICT_BROKEN.ICO b/resource/PICT_BROKEN.ICO new file mode 100644 index 0000000..80c5cac Binary files /dev/null and b/resource/PICT_BROKEN.ICO differ diff --git a/resource/PICT_DEFINED.ICO b/resource/PICT_DEFINED.ICO new file mode 100644 index 0000000..04433ce Binary files /dev/null and b/resource/PICT_DEFINED.ICO differ diff --git a/resource/PICT_DONE.ICO b/resource/PICT_DONE.ICO new file mode 100644 index 0000000..10603ec Binary files /dev/null and b/resource/PICT_DONE.ICO differ diff --git a/resource/PICT_HASFILE.ICO b/resource/PICT_HASFILE.ICO new file mode 100644 index 0000000..f2a87bc Binary files /dev/null and b/resource/PICT_HASFILE.ICO differ diff --git a/resource/PICT_REDO.ICO b/resource/PICT_REDO.ICO new file mode 100644 index 0000000..f822948 Binary files /dev/null and b/resource/PICT_REDO.ICO differ diff --git a/resource/PICT_UNDEFINED.ICO b/resource/PICT_UNDEFINED.ICO new file mode 100644 index 0000000..900bd47 Binary files /dev/null and b/resource/PICT_UNDEFINED.ICO differ diff --git a/resource/SAMPLES.ico b/resource/SAMPLES.ico new file mode 100644 index 0000000..95521f1 Binary files /dev/null and b/resource/SAMPLES.ico differ diff --git a/resource/TOOLBAR_MAINFRAME.BMP b/resource/TOOLBAR_MAINFRAME.BMP new file mode 100644 index 0000000..3071436 Binary files /dev/null and b/resource/TOOLBAR_MAINFRAME.BMP differ diff --git a/resource/TOOLBAR_OSS.BMP b/resource/TOOLBAR_OSS.BMP new file mode 100644 index 0000000..1abe09d Binary files /dev/null and b/resource/TOOLBAR_OSS.BMP differ diff --git a/resource/TOOLBAR_RSFORM.BMP b/resource/TOOLBAR_RSFORM.BMP new file mode 100644 index 0000000..8ac8a40 Binary files /dev/null and b/resource/TOOLBAR_RSFORM.BMP differ diff --git a/resource/ossFile.ico b/resource/ossFile.ico new file mode 100644 index 0000000..61a770e Binary files /dev/null and b/resource/ossFile.ico differ diff --git a/resource/rsmFile.ico b/resource/rsmFile.ico new file mode 100644 index 0000000..1fadc69 Binary files /dev/null and b/resource/rsmFile.ico differ diff --git a/resource/trsFile.ico b/resource/trsFile.ico new file mode 100644 index 0000000..a7a2dbf Binary files /dev/null and b/resource/trsFile.ico differ diff --git a/script/ExteorSetup_x64.iss b/script/ExteorSetup_x64.iss new file mode 100644 index 0000000..6eeacf8 --- /dev/null +++ b/script/ExteorSetup_x64.iss @@ -0,0 +1,205 @@ +#define ExteorName 'Экстеор 4.9' +#define ExteorEXE 'Exteor.exe' +#define Platform 'x64' +#define UpdateURL 'https://drive.google.com/open?id=1IJt25ZRQ-ZMA6t7hOqmo5cv05WJCQKMv&usp=drive_fs' +#define ExteorVersion() GetVersionNumbersString('..\bin\' + Platform + '\Exteor.exe') + +#define ConceptDomain 'CONCEPT' +#define ExteorAppID '{EB3E39CA-7B66-42B3-8688-FE56D4BB0B23}' +#define PythonVer '3.12.2' +#define PythonRedist 'python-' + PythonVer + '-amd64.exe' +#define PythonDownload 'https://www.python.org/ftp/python/' + PythonVer + '/' + PythonRedist +#define VSRedist 'VC_redist.' + Platform + '.exe' +#define VSDownload 'https://aka.ms/vs/17/release/' + VSRedist + +#define RK_Python3 'SOFTWARE\Python\PythonCore\3.12\InstallPath' +#define RK_PyPath 'PyPath312_64' +#define RK_VCRedistr 'SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\' + Platform + +#define RK_Exteor 'SOFTWARE\CIHT Concept\Экстеор 4.9' +#define RK_ExteorUninstall 'SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{EB3E39CA-7B66-42B3-8688-FE56D4BB0B23}_is1' + +[Setup] + +; NOTE: The value of AppId uniquely identifies this application. +; Do not use the same AppId value in installers for other applications. +; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) +AppId = {{#ExteorAppID} + +AppName = {#ExteorName} +AppVersion = {#ExteorVersion} +AppVerName = {#ExteorName} +VersionInfoVersion = {#ExteorVersion} +AppPublisher = НП ЦИВТ КОНЦЕПТ +AppPublisherURL = http://www.acconcept.ru/ +AppSupportURL = bugreport@acconcept.ru +AppUpdatesURL = {#UpdateURL} + +DefaultDirName = {autopf64}\CIHT Concept\{#ExteorName} +DefaultGroupName = {#ExteorName} + +LicenseFile = ..\distr\app\Документация\Лицензионное соглашение.rtf +SetupIconFile = ..\resource\ExteorApp.ico + +SourceDir = ..\distr + +OutputDir = ..\bin\{#Platform} +OutputBaseFilename = ExteorSetup + +AllowNoIcons = yes +ChangesAssociations = yes + +UninstallDisplayIcon={app}\{#ExteorEXE} + +[Languages] +Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl" + +[Tasks] +Name: desktopicon; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" +Name: quicklaunchicon; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked + +[Files] +Source: "..\bin\x64\Exteor.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\import\cctext\*"; DestDir: "{app}\cctext"; Flags: ignoreversion +Source: "app\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs +Source: "..\distr\app\DejaVu Sans.ttf"; DestDir: "{app}"; Flags: ignoreversion + +Source: "..\script\PymorphyInstall.bat"; DestDir: {tmp}; Flags: deleteafterinstall + +[Icons] +Name: "{group}\{#ExteorName}"; Filename: "{app}\{#ExteorEXE}" +Name: "{group}\{cm:UninstallProgram,{#ExteorName}}"; Filename: "{uninstallexe}" +Name: "{autodesktop}\{#ExteorName}"; Filename: "{app}\{#ExteorEXE}"; Tasks: desktopicon +Name: "{autodesktop}\Экстеор - Текущая версия"; Filename: "{app}\Экстеор - Текущая версия.lnk"; Tasks: desktopicon; Check: IsConceptDomain +Name: "{autoappdata}\Microsoft\Internet Explorer\Quick Launch\{#ExteorName}"; Filename: "{app}\{#ExteorEXE}"; WorkingDir: {app}; Tasks: quicklaunchicon + +[CustomMessages] +russian.NewerVersionExists = Более поздняя версия {#ExteorName} уже установлена. %n%nУстанавливаемая версия: {#ExteorVersion}%nТекущая версия: +russian.SameVersionExists = На компьютере уже установлен {#ExteorName} версия {#ExteorVersion}.%n%nХотите переустановить программу? +russian.ReadMe = Ознакомиться с ReadMe +russian.CppRedist = Установка Visual C++ Redistributable... +russian.PythonInstall = Установка Python 3.12... + +[Registry] +Root: HKCR; Subkey: ".oss"; ValueType: string; ValueName: ""; ValueData: "OSS File"; Flags: uninsdeletevalue +Root: HKCR; Subkey: "OSS File"; ValueType: string; ValueName: ""; ValueData: "Операционная схема синтеза"; Flags: uninsdeletekey +Root: HKCR; Subkey: "OSS File\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\Exteor.exe,3" +Root: HKCR; Subkey: "OSS File\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\Exteor.EXE"" ""%1""" + +Root: HKCR; Subkey: ".rsm"; ValueType: string; ValueName: ""; ValueData: "RSM File"; Flags: uninsdeletevalue +Root: HKCR; Subkey: "RSM File"; ValueType: string; ValueName: ""; ValueData: "Модель РС-формы"; Flags: uninsdeletekey +Root: HKCR; Subkey: "RSM File\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\Exteor.exe,2" +Root: HKCR; Subkey: "RSM File\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\Exteor.EXE"" ""%1""" + +Root: HKCR; Subkey: ".trs"; ValueType: string; ValueName: ""; ValueData: "TRS File"; Flags: uninsdeletevalue +Root: HKCR; Subkey: "TRS File"; ValueType: string; ValueName: ""; ValueData: "Файл РС-формы КС"; Flags: uninsdeletekey +Root: HKCR; Subkey: "TRS File\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\Exteor.exe,1" +Root: HKCR; Subkey: "TRS File\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\Exteor.EXE"" ""%1""" + +[Run] +Filename: "{app}\{#ExteorEXE}"; Description: "{cm:LaunchProgram,{#StringChange(ExteorName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent +Filename: "{app}\Документация\README.rtf"; Description: "{cm:ReadMe}"; Flags: nowait postinstall skipifsilent unchecked shellexec +Filename: "{tmp}\{#VSRedist}"; Parameters: "/install /quiet /NORESTART"; StatusMsg: {cm:CppRedist}; Check: VCRedistNeedsInstall() +Filename: "{tmp}\{#PythonRedist}"; Parameters: "/quiet InstallAllUsers=1 PrependPath=1 Include_test=0"; StatusMsg: {cm:PythonInstall}; Check: PythonNeedsInstall() +Filename: "{tmp}\PymorphyInstall.bat"; Parameters: """{code:PythonPath}""" + +[Code] +function IsPythonMissing: Boolean; forward; +function GetPythonInstallPath: String; forward; +function VCRedistNeedsInstall: Boolean; forward; +function GetExteorInstalledVersion: String; forward; +function DownloadFile(url_from: String; fileName: String): Boolean; forward; + +function InitializeSetup: Boolean; +var + installedVersion: String; + comparison: Integer; +begin + installedVersion := GetExteorInstalledVersion + if installedVersion = '' then begin + Result := True + exit + end; + comparison := CompareText(installedVersion,'{#ExteorVersion}') + if comparison = 0 then + Result := MsgBox(ExpandConstant('{cm:SameVersionExists}'), mbConfirmation, MB_YESNO) = IDYES + else begin + Result := comparison <= 0 + if not Result then + MsgBox(ExpandConstant('{cm:NewerVersionExists}') + installedVersion, mbInformation, MB_OK); + end +end; + +function GetExteorInstalledVersion: String; +begin + if not RegQueryStringValue(HKEY_LOCAL_MACHINE,'{#RK_ExteorUninstall}', 'DisplayVersion', Result) then + Result := '' +end; + +function IsConceptDomain: Boolean; +begin + Result := GetEnv('UserDomain') = '{#ConceptDomain}' +end; + +function PythonNeedsInstall: Boolean; +begin + Result := IsPythonMissing; + if Result then + Result := DownloadFile('{#PythonDownload}', '{#PythonRedist}') +end; + +function PythonRegistryExists: Boolean; +begin + Result := RegValueExists(HKLM64, '{#RK_Python3}', ''); +end; + +function GetPythonInstallPath: String; +begin + Result := ''; + if PythonRegistryExists then + RegQueryStringValue(HKLM64, '{#RK_Python3}', '', Result); +end; + +function IsPythonMissing: Boolean; +var + python: String; +begin + python := GetPythonInstallPath; + Result := python = ''; + if not Result then + Result := not FileExists(python + 'python312.dll') or not FileExists(python + 'Scripts\pip.exe'); +end; + +function VCRedistNeedsInstall(): Boolean; +begin + Result := not RegValueExists(HKLM64, '{#RK_VCRedistr}', 'Version'); + if Result then + Result := DownloadFile('{#VSDownload}', '{#VSRedist}') +end; + +function DownloadFile(url_from: String; fileName: String): Boolean; +begin + try + DownloadTemporaryFile(url_from, fileName, '', nil); + Result := True; + except + Log(GetExceptionMessage); + Result := False; + end; +end; + +function PythonPath(dummyValue: String): String; +begin + Result := GetPythonInstallPath +end; + +procedure DeinitializeSetup(); +var + python: String; + destination: String; +begin + python := GetPythonInstallPath + 'python312.dll'; + destination := ExpandConstant('{app}\python312.dll') + if FileExists(python) then + FileCopy(python, destination, False); +end; diff --git a/script/ExteorSetup_x86.iss b/script/ExteorSetup_x86.iss new file mode 100644 index 0000000..82aabbd --- /dev/null +++ b/script/ExteorSetup_x86.iss @@ -0,0 +1,205 @@ +#define ExteorName 'Экстеор 4.9' +#define ExteorEXE 'Exteor.exe' +#define Platform 'x86' +#define UpdateURL 'https://drive.google.com/open?id=1IHlMMwaYlAUBRSxU1RU_hXM5mFU9-oyK&usp=drive_fs' +#define ExteorVersion() GetVersionNumbersString('..\bin\' + Platform + '\Exteor.exe') + +#define ConceptDomain 'CONCEPT' +#define ExteorAppID '{EB3E39CA-7B66-42B3-8688-FE56D4BB0B23}' +#define PythonVer '3.12.2' +#define PythonRedist 'python-' + PythonVer + '.exe' +#define PythonDownload 'https://www.python.org/ftp/python/' + PythonVer + '/' + PythonRedist +#define VSRedist 'VC_redist.' + Platform + '.exe' +#define VSDownload 'https://aka.ms/vs/17/release/' + VSRedist + +#define RK_Python3 'SOFTWARE\Python\PythonCore\3.12-32\InstallPath' +#define RK_PyPath 'PyPath312_32' +#define RK_VCRedistr 'SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\' + Platform + +#define RK_Exteor 'SOFTWARE\CIHT Concept\Экстеор 4.9' +#define RK_ExteorUninstall 'SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{EB3E39CA-7B66-42B3-8688-FE56D4BB0B23}_is1' + +[Setup] + +; NOTE: The value of AppId uniquely identifies this application. +; Do not use the same AppId value in installers for other applications. +; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) +AppId = {{#ExteorAppID} + +AppName = {#ExteorName} +AppVersion = {#ExteorVersion} +AppVerName = {#ExteorName} +VersionInfoVersion = {#ExteorVersion} +AppPublisher = НП ЦИВТ КОНЦЕПТ +AppPublisherURL = http://www.acconcept.ru/ +AppSupportURL = bugreport@acconcept.ru +AppUpdatesURL = {#UpdateURL} + +DefaultDirName = {autopf64}\CIHT Concept\{#ExteorName} +DefaultGroupName = {#ExteorName} + +LicenseFile = ..\distr\app\Документация\Лицензионное соглашение.rtf +SetupIconFile = ..\resource\ExteorApp.ico + +SourceDir = ..\distr + +OutputDir = ..\bin\{#Platform} +OutputBaseFilename = ExteorSetup + +AllowNoIcons = yes +ChangesAssociations = yes + +UninstallDisplayIcon={app}\{#ExteorEXE} + +[Languages] +Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl" + +[Tasks] +Name: desktopicon; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}" +Name: quicklaunchicon; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked + +[Files] +Source: "..\bin\x64\Exteor.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\import\cctext\*"; DestDir: "{app}\cctext"; Flags: ignoreversion +Source: "app\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs +Source: "..\distr\app\DejaVu Sans.ttf"; DestDir: "{app}"; Flags: ignoreversion + +Source: "..\script\PymorphyInstall.bat"; DestDir: {tmp}; Flags: deleteafterinstall + +[Icons] +Name: "{group}\{#ExteorName}"; Filename: "{app}\{#ExteorEXE}" +Name: "{group}\{cm:UninstallProgram,{#ExteorName}}"; Filename: "{uninstallexe}" +Name: "{autodesktop}\{#ExteorName}"; Filename: "{app}\{#ExteorEXE}"; Tasks: desktopicon +Name: "{autodesktop}\Экстеор - Текущая версия"; Filename: "{app}\Экстеор - Текущая версия.lnk"; Tasks: desktopicon; Check: IsConceptDomain +Name: "{autoappdata}\Microsoft\Internet Explorer\Quick Launch\{#ExteorName}"; Filename: "{app}\{#ExteorEXE}"; WorkingDir: {app}; Tasks: quicklaunchicon + +[CustomMessages] +russian.NewerVersionExists = Более поздняя версия {#ExteorName} уже установлена. %n%nУстанавливаемая версия: {#ExteorVersion}%nТекущая версия: +russian.SameVersionExists = На компьютере уже установлен {#ExteorName} версия {#ExteorVersion}.%n%nХотите переустановить программу? +russian.ReadMe = Ознакомиться с ReadMe +russian.CppRedist = Установка Visual C++ Redistributable... +russian.PythonInstall = Установка Python 3.9... + +[Registry] +Root: HKCR; Subkey: ".oss"; ValueType: string; ValueName: ""; ValueData: "OSS File"; Flags: uninsdeletevalue +Root: HKCR; Subkey: "OSS File"; ValueType: string; ValueName: ""; ValueData: "Операционная схема синтеза"; Flags: uninsdeletekey +Root: HKCR; Subkey: "OSS File\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\Exteor.exe,3" +Root: HKCR; Subkey: "OSS File\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\Exteor.EXE"" ""%1""" + +Root: HKCR; Subkey: ".rsm"; ValueType: string; ValueName: ""; ValueData: "RSM File"; Flags: uninsdeletevalue +Root: HKCR; Subkey: "RSM File"; ValueType: string; ValueName: ""; ValueData: "Модель РС-формы"; Flags: uninsdeletekey +Root: HKCR; Subkey: "RSM File\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\Exteor.exe,2" +Root: HKCR; Subkey: "RSM File\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\Exteor.EXE"" ""%1""" + +Root: HKCR; Subkey: ".trs"; ValueType: string; ValueName: ""; ValueData: "TRS File"; Flags: uninsdeletevalue +Root: HKCR; Subkey: "TRS File"; ValueType: string; ValueName: ""; ValueData: "Файл РС-формы КС"; Flags: uninsdeletekey +Root: HKCR; Subkey: "TRS File\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\Exteor.exe,1" +Root: HKCR; Subkey: "TRS File\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\Exteor.EXE"" ""%1""" + +[Run] +Filename: "{app}\{#ExteorEXE}"; Description: "{cm:LaunchProgram,{#StringChange(ExteorName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent +Filename: "{app}\Документация\README.rtf"; Description: "{cm:ReadMe}"; Flags: nowait postinstall skipifsilent unchecked shellexec +Filename: "{tmp}\{#VSRedist}"; Parameters: "/install /quiet /NORESTART"; StatusMsg: {cm:CppRedist}; Check: VCRedistNeedsInstall() +Filename: "{tmp}\{#PythonRedist}"; Parameters: "/quiet InstallAllUsers=1 PrependPath=1 Include_test=0"; StatusMsg: {cm:PythonInstall}; Check: PythonNeedsInstall() +Filename: "{tmp}\PymorphyInstall.bat"; Parameters: """{code:PythonPath}""" + +[Code] +function IsPythonMissing: Boolean; forward; +function GetPythonInstallPath: String; forward; +function VCRedistNeedsInstall: Boolean; forward; +function GetExteorInstalledVersion: String; forward; +function DownloadFile(url_from: String; fileName: String): Boolean; forward; + +function InitializeSetup: Boolean; +var + installedVersion: String; + comparison: Integer; +begin + installedVersion := GetExteorInstalledVersion + if installedVersion = '' then begin + Result := True + exit + end; + comparison := CompareText(installedVersion,'{#ExteorVersion}') + if comparison = 0 then + Result := MsgBox(ExpandConstant('{cm:SameVersionExists}'), mbConfirmation, MB_YESNO) = IDYES + else begin + Result := comparison <= 0 + if not Result then + MsgBox(ExpandConstant('{cm:NewerVersionExists}') + installedVersion, mbInformation, MB_OK); + end +end; + +function GetExteorInstalledVersion: String; +begin + if not RegQueryStringValue(HKEY_LOCAL_MACHINE,'{#RK_ExteorUninstall}', 'DisplayVersion', Result) then + Result := '' +end; + +function IsConceptDomain: Boolean; +begin + Result := GetEnv('UserDomain') = '{#ConceptDomain}' +end; + +function PythonNeedsInstall: Boolean; +begin + Result := IsPythonMissing; + if Result then + Result := DownloadFile('{#PythonDownload}', '{#PythonRedist}') +end; + +function PythonRegistryExists: Boolean; +begin + Result := RegValueExists(HKEY_LOCAL_MACHINE, '{#RK_Python3}', ''); +end; + +function GetPythonInstallPath: String; +begin + Result := ''; + if not PythonRegistryExists then + RegQueryStringValue(HKEY_LOCAL_MACHINE, '{#RK_Python3}', '', Result); +end; + +function IsPythonMissing: Boolean; +var + python: String; +begin + python := GetPythonInstallPath; + Result := python = ''; + if not Result then + Result := not FileExists(python + 'python312.dll') or not FileExists(python + 'Scripts\pip.exe'); +end; + +function VCRedistNeedsInstall(): Boolean; +begin + Result := not RegValueExists(HKEY_LOCAL_MACHINE, '{#RK_VCRedistr}', 'Version'); + if Result then + Result := DownloadFile('{#VSDownload}', '{#VSRedist}') +end; + +function DownloadFile(url_from: String; fileName: String): Boolean; +begin + try + DownloadTemporaryFile(url_from, fileName, '', nil); + Result := True; + except + Log(GetExceptionMessage); + Result := False; + end; +end; + +function PythonPath(dummyValue: String): String; +begin + Result := GetPythonInstallPath +end; + +procedure DeinitializeSetup(); +var + python: String; + destination: String; +begin + python := GetPythonInstallPath + 'python312.dll'; + destination := ExpandConstant('{app}\python312.dll') + if FileExists(python) then + FileCopy(python, destination, False); +end; diff --git a/script/PymorphyInstall.bat b/script/PymorphyInstall.bat new file mode 100644 index 0000000..f14f9c2 --- /dev/null +++ b/script/PymorphyInstall.bat @@ -0,0 +1,20 @@ +@echo off + +SET python3Path=%~1 + +ECHO Checking connection, please wait... +PING -n 1 www.google.com > nul && (goto :SUCCESS) || (goto :FAILURE) + +:SUCCESS +@echo off +"%python3Path%Scripts\pip.exe" install razdel || (goto :FAILURE) +"%python3Path%Scripts\pip.exe" install pymorphy3 || (goto :FAILURE) +goto :END + +:FAILURE +ECHO Cannot install pymorphy3 via pip install +pause +goto :END + +:END +exit /b \ No newline at end of file diff --git a/script/buildHelp.bat b/script/buildHelp.bat new file mode 100644 index 0000000..e2a057e --- /dev/null +++ b/script/buildHelp.bat @@ -0,0 +1,2 @@ +hhc.exe help\help.hhp +if not errorlevel 1 exit /B 1 \ No newline at end of file diff --git a/script/deployLocal.bat b/script/deployLocal.bat new file mode 100644 index 0000000..4648897 --- /dev/null +++ b/script/deployLocal.bat @@ -0,0 +1,29 @@ +@echo off + +chcp 65001 + +echo Deploy path = %XTR_CURRENT_PATH% +echo Installer path = %XTR_DISTR_PATH% + +if "%XTR_CURRENT_PATH%" == "" ( + echo Exteor local path not set +) else ( + echo Replacing current version... + rmdir /s /q "%XTR_CURRENT_PATH%" + mkdir "%XTR_CURRENT_PATH%" + xcopy /y /s /q /i "distr\app" "%XTR_CURRENT_PATH%\" + xcopy /y /s /q /i "import\cctext" "%XTR_CURRENT_PATH%\cctext\" + copy /y bin\x64\Exteor.exe "%XTR_CURRENT_PATH%\Exteor.exe +) + +if "%XTR_DISTR_PATH%" == "" ( + echo Exteor distribution path not set +) else ( + echo Replacing installer distributive... + + copy /y bin\x64\ExteorSetup.exe "%XTR_DISTR_PATH%\ExteorSetup.exe" + copy /y bin\x86\ExteorSetup.exe "%XTR_DISTR_PATH%\ExteorSetup_32bit.exe" + copy /y bin\x64\Exteor.7z "%XTR_DISTR_PATH%\!Архив\%DATE%.7z" + copy /y distr\!!Листовка.docx "%XTR_DISTR_PATH%\..\!!Листовка.docx" + copy /y distr\app\!Памятка.docx "%XTR_DISTR_PATH%\..\!Памятка.docx" +) \ No newline at end of file diff --git a/src/ExtSourceManager.cpp b/src/ExtSourceManager.cpp new file mode 100644 index 0000000..a089528 --- /dev/null +++ b/src/ExtSourceManager.cpp @@ -0,0 +1,233 @@ +#include "stdafx.h" + +#include "xtr/ExtSourceManager.h" + +#include "resource.h" +#include "xtr/dialog/BasicDlg.h" +#include "xtr/Exteor.h" +#include "xtr/doc/RSFormDoc.h" +#include "xtr/doc/OSSDoc.h" + +namespace xtr { + +static constexpr auto noView = true; + +using ccl::src::Descriptor; +using ccl::src::Source; +using ccl::src::SrcType; + +Source* ExtSourceManager::Find(const Descriptor& desc) { + switch (desc.type) { + default: return SourceManager::Find(desc); + case SrcType::rsDoc: + return ExteorApplication::Docs().FindRSDocByPath(std::filesystem::path(desc.name).c_str()); + } +} + +bool ExtSourceManager::TestDomain(const Descriptor& global, const std::u8string& domain) const { + switch (global.type) { + default: return SourceManager::TestDomain(global, domain); + case SrcType::rsDoc: { + auto domainDir = std::filesystem::path(domain); + if (std::empty(domainDir.filename())) { + domainDir = domainDir.parent_path(); + } + return std::filesystem::path(global.name).parent_path().lexically_normal() == domainDir.lexically_normal(); + } + } +} + +Descriptor ExtSourceManager::Convert2Local(const Descriptor& global, const std::u8string& domain) const { + switch (global.type) { + default: return SourceManager::Convert2Local(global, domain); + case SrcType::rsDoc: + Descriptor local = global; + if (!std::empty(domain)) { + local.name = std::filesystem::relative(std::filesystem::path(global.name), std::filesystem::path(domain)).u8string(); + } + return local; + } +} + +Descriptor ExtSourceManager::Convert2Global(const Descriptor& local, const std::u8string& domain) const { + switch (local.type) { + default: return SourceManager::Convert2Global(local, domain); + case SrcType::rsDoc: { + Descriptor global = local; + if (!std::empty(domain)) { + global.name = (std::filesystem::path(domain) / std::filesystem::path(local.name).filename()).u8string(); + } + return global; + } + } +} + +Descriptor ExtSourceManager::CreateLocalDesc(SrcType type, std::u8string localName) const { + switch (type) { + default: return SourceManager::CreateLocalDesc(type, localName); + case SrcType::rsDoc: { + Descriptor result{}; + result.type = type; + result.name = FixFilename(localName) + mfc::ToUTF8(ExtensionFor(FileType::trs)); + return result; + } + } +} + +std::u8string ExtSourceManager::FixFilename(const std::u8string& name) { + std::u8string result{}; + for (const auto symb : name) { + if (symb != '?' && symb != '\\' && symb != ':' && symb != '*' + && symb != '"' && symb != '<' && symb != '>' && symb != '|') { + result += symb; + } + } + if (std::empty(result)) { + return u8"noname"; + } else { + return result; + } +} + +Descriptor ExtSourceManager::GetDescriptor(const Source& src) const { + switch (src.Type()) { + default: return SourceManager::GetDescriptor(src); + case SrcType::rsDoc: { + const auto& path = RSCast(src).GetPathName(); + return Descriptor{ src.Type(), mfc::ToUTF8(path.IsEmpty() ? RSCast(src).GetTitle() : path) }; + } + } +} + +bool ExtSourceManager::ChangeDescriptor(const Descriptor& desc, const Descriptor& newDesc) { + if (desc.type != newDesc.type) { + return false; + } + if (auto* src = Find(desc); src != nullptr) { + Close(*src); + } + const auto oldPath = std::filesystem::path(desc.name); + const auto newPath = std::filesystem::path(newDesc.name); + switch (desc.type) { + default: return false; + case SrcType::rsDoc: { + if (!std::filesystem::exists(oldPath)) { + ::AfxMessageBox(mfc::FormatSID(IXTRE_FILE_NOT_FOUND, oldPath.c_str()), MB_ICONEXCLAMATION); + return false; + } else if (std::filesystem::exists(newPath)) { + ::AfxMessageBox(mfc::FormatSID(IXTRS_RENAME_FILE_EXISTS, newPath.c_str()), MB_ICONEXCLAMATION); + return false; + } + + try { + std::filesystem::rename(oldPath, newPath); + g_Exteor.RemoveMRUItem(oldPath.c_str()); + return true; + } catch (...) { + ::AfxMessageBox(mfc::LoadSID(IXTRE_RENAME_UNKNOWN), MB_ICONEXCLAMATION); + return false; + } + } + } +} + +Source* ExtSourceManager::CreateNew(const Descriptor& desc) { + if (Find(desc) != nullptr) { + return nullptr; + } + const auto path = std::filesystem::path(desc.name); + if (std::filesystem::exists(path) && + ::AfxMessageBox(mfc::FormatSID(IXTRS_ASK_REWRITE_FILE, path.c_str()), MB_YESNO | MB_ICONQUESTION) != IDYES) { + return nullptr; + } + + const auto guardSilent = XTROptions::App().GuardSilence(); + switch (desc.type) { + default: break; + case SrcType::rsDoc: { + if (auto* src = ExteorApplication::Docs().NewRSFormDoc(noView); src != nullptr) { + if (auto& doc = RSCast(*src); doc.OnSaveDocument(path.c_str())) { + return src; + } else { + src->OnCloseDocument(); + } + } + break; + } + } + return nullptr; +} + +void ExtSourceManager::Discard(const Descriptor& desc) { + auto* src = Open(desc); + if (src == nullptr) { + return; + } + + src->ReleaseClaim(); + Close(*src); + + switch (desc.type) { + default: break; + case SrcType::rsDoc: { + auto newPath = std::filesystem::path(desc.name); + CString newName = newPath.stem().c_str(); + newName += CTime::GetCurrentTime().Format(LR"(%Y%m%d_%H%M)"); + newName += newPath.extension().c_str(); + newPath = newPath.replace_filename(newName.GetString()); + ChangeDescriptor(desc, Descriptor{ SrcType::rsDoc, newPath.u8string() }); + } + } +} + +Source* ExtSourceManager::Open(const Descriptor& desc) { + const auto path = std::filesystem::path(desc.name); + if (!std::filesystem::exists(path)) { + return nullptr; + } + const auto guardSilent = XTROptions::App().GuardSilence(); + switch (desc.type) { + default: return SourceManager::Open(desc); + case SrcType::rsDoc: return ExteorApplication::Docs().OpenRSFormDoc(path.c_str(), noView); + } +} + +void ExtSourceManager::Close(Source& src) { + switch (src.Type()) { + default: break; + case SrcType::rsDoc: { + RSCast(src).OnCloseDocument(); + break; + } + } +} + +bool ExtSourceManager::SaveState(Source& src) { + switch (src.Type()) { + default: return false; + case SrcType::rsDoc: { + const auto path = std::filesystem::path(RSCast(src).GetPathName().GetString()); + if (path.has_parent_path() && !std::filesystem::exists(path)) { + return false; + } else { + return RSCast(src).DoFileSave(); + } + } + } +} + +// false positive noexcept recomendation for function using dynamic_cast to references +#pragma warning( push ) +#pragma warning( disable : 26496 26440 ) + +const doc::RSFormDoc& ExtSourceManager::RSCast(const Source& src) { + return dynamic_cast(src); +} + +doc::RSFormDoc& ExtSourceManager::RSCast(Source& src) { + return dynamic_cast(src); +} + +#pragma warning( pop ) + +} // namespace xtr \ No newline at end of file diff --git a/src/Exteor.cpp b/src/Exteor.cpp new file mode 100644 index 0000000..d068694 --- /dev/null +++ b/src/Exteor.cpp @@ -0,0 +1,306 @@ +#include "stdafx.h" + +#include "xtr/Exteor.h" + +#include "SetupManager.h" +#include "xtr/ui/HelpHandler.h" +#include "xtr/dialog/OptionsDialog.h" +#include "xtr/dialog/NewDocument.h" + +#include "resource.h" + +#include "ccl/lang/TextEnvironment.h" + +namespace xtr { + +using ui::ExteorFrame; + +namespace { + +class AboutDlg : public CDialog { +public: + explicit AboutDlg(CWnd* pParent = nullptr) + : CDialog(IXTRD_ABOUTBOX, pParent) {} + +private: + BOOL OnInitDialog() override { + CDialog::OnInitDialog(); + SetDlgItemTextW(IXTRC_VERSION, g_Exteor.version.text); + SetDlgItemTextW(IXTRC_COPYRIGHT, g_Exteor.version.copyright); + return TRUE; + } +}; + +} // anonymous namespace + +#pragma warning( push ) +#pragma warning( disable : 26426 ) + +// The one and only ExteorApplication object +ExteorApplication g_Exteor{}; // NOLINT + +#pragma warning( pop ) + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(ExteorApplication, CWinAppEx) + ON_COMMAND(ID_APP_ABOUT, &ThisClass::OnAppAbout) + ON_COMMAND(IXTRC_EDIT_OPTIONS, &ThisClass::OnOpenOptions) + ON_COMMAND(IXTRC_XTR_HELP, &ThisClass::OpenHelp) + ON_COMMAND(IXTRC_BUG_REPORT, &ThisClass::OnBugReport) + ON_COMMAND(IXTRC_MAIL_DEVELOPERS, &ThisClass::OnMailDevelopers) + ON_COMMAND(ID_FILE_OPEN, &ThisClass::OnFileOpen) + ON_COMMAND(ID_FILE_NEW, &ThisClass::OnFileNew) + ON_COMMAND(IXTRC_START_PAGE, &ThisClass::OnStartPage) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +ExteorApplication::ExteorApplication() { + SetAppID(L"CIHT CONCEPT.EXTEOR"); + docs = std::make_unique(*this); +} + +doc::DocumentManager& ExteorApplication::Docs() noexcept { + return *g_Exteor.docs; +} + +ExteorFrame& ExteorApplication::MainFrame() noexcept { + return dynamic_cast(*g_Exteor.m_pMainWnd); +} + +int32_t ExteorApplication::ExitInstance() { + ::AfxOleTerm(FALSE); + + SetupManager::CCLExitSequence(); + CMFCVisualManager::DestroyInstance(); + ::ReleaseMutex(mutex); + ::CloseHandle(mutex); + return CWinAppEx::ExitInstance(); +} + +BOOL ExteorApplication::InitInstance() { + if (CheckIfAnotherExteorIsRunning()) { + if (*m_lpCmdLine != '\0') { + FeedCommandLineToAnotherExteor(); + } + return FALSE; + } + + DefaultInitApplication(); + if (!InitVersion()) { + return FALSE; + } else if (!InitControls()) { + return FALSE; + } else if (!CreateMainFrame()) { + return FALSE; + } + CreateStartingLook(); + return TRUE; +} + +BOOL ExteorApplication::CheckIfAnotherExteorIsRunning() noexcept { + mutex = ::CreateMutexW(nullptr, FALSE, L"Exteor"); + const auto res = mutex != nullptr && GetLastError() == ERROR_ALREADY_EXISTS; + if (res) { + mutex = nullptr; + } + return res; +} + +void ExteorApplication::DefaultInitApplication() { + SetRegistryKey(L"CIHT Concept"); + ::setlocale(LC_ALL, "RUSSIAN"); + + InitContextMenuManager(); + InitShellManager(); + InitTooltipManager(); + + CMFCToolTipInfo ttParams{}; + ttParams.m_bVislManagerTheme = TRUE; + GetTooltipManager()->SetTooltipParams(AFX_TOOLTIP_TYPE_ALL, RUNTIME_CLASS(CMFCToolTipCtrl), &ttParams); +} + +void ExteorApplication::FeedCommandLineToAnotherExteor() noexcept { + COPYDATASTRUCT messageData{}; + messageData.cbData = static_cast((wcslen(m_lpCmdLine) + 1) * sizeof(wchar_t)); // NOLINT + messageData.lpData = m_lpCmdLine; + + auto* const hWnd = FindWindowW(L"Exteor", nullptr); + assert(hWnd != nullptr); + ::SetForegroundWindow(hWnd); + ::SendMessageW(hWnd, WM_COPYDATA, 0, reinterpret_cast(&messageData)); +} + +BOOL ExteorApplication::InitVersion() { + if (!InitVersionID()) { + return FALSE; + } + version.text = mfc::FormatSID(IXTRS_VERSION_TEXT, version.id.GetString(), mfc::ToMFC(ccl::Environment::VersionInfo()).GetString()); + version.copyright = mfc::LoadSID(IXTRS_COPYRIGHT); + return TRUE; +} + +BOOL ExteorApplication::InitVersionID() { + static constexpr auto VERSION_PREFIX_LEN = 6; + // get the filename of the executable containing the version resource + CString extFileName{}; + if (::GetModuleFileNameW(nullptr, extFileName.GetBuffer(MAX_PATH), MAX_PATH) == 0) { + TRACE("GetModuleFileName failed with error %d\n", GetLastError()); + return FALSE; + } + extFileName.ReleaseBuffer(); + + // allocate a block of memory for the version info + DWORD dummy{}; + const auto dwSize = ::GetFileVersionInfoSizeW(extFileName, &dummy); + if (dwSize == 0) { + TRACE("GetFileVersionInfoSize failed with error %d\n", GetLastError()); + return FALSE; + } + + // load the version info + std::vector data(dwSize); + if (!::GetFileVersionInfoW(extFileName, NULL, dwSize, &data.at(0))) { + TRACE("GetFileVersionInfo failed with error %d\n", GetLastError()); + return FALSE; + } + + // 041904b0 - russian language resource ID + void* pvProductVersion{ nullptr }; + unsigned int iProductVersionLen{ 0 }; + if (!::VerQueryValueW(&data.at(0), LR"(\StringFileInfo\041904b0\ProductVersion)", &pvProductVersion, &iProductVersionLen)) { + TRACE("Can't obtain ProductVersion from resources\n"); + return FALSE; + } + + version.id.SetString(static_cast(pvProductVersion), iProductVersionLen); // NOLINT + if (version.id.GetLength() <= VERSION_PREFIX_LEN) { + TRACE("Invalid version format\n"); + return FALSE; + } + version.id = version.id.Left(version.id.GetLength() - VERSION_PREFIX_LEN); // NOLINT + +#ifdef _WIN64 + version.id.Append(L" 64bit"); +#else + version.id.Append(L" 32bit"); +#endif + + return TRUE; +} + +BOOL ExteorApplication::CreateMainFrame() { + m_pMainWnd = new ExteorFrame(); + if (MainFrame().LoadFrame(IXTRAD_MENU_MAINFRAME)) { + m_pMainWnd->DragAcceptFiles(); + m_pMainWnd->ShowWindow(SW_SHOW); + m_pMainWnd->UpdateWindow(); + return TRUE; + } else { + return FALSE; + } +} + +BOOL ExteorApplication::InitControls() { + if (!docs->Initialize()) { + return FALSE; + } else if (AfxOleInit()) { + ::AfxEnableControlContainer(); + ::AfxInitRichEdit2(); + return TRUE; + } else { + ::AfxMessageBox(IXTRE_OLE_INIT_FAILED, MB_ICONERROR); + return FALSE; + } +} + +void ExteorApplication::LoadCustomState() { + CWinAppEx::LoadCustomState(); + + LoadOptions(); + SetupManager::InitEnvironment(); + SetupManager::CCLInitSequence(); +} + +void ExteorApplication::LoadOptions() { + static constexpr auto COUNT_RECENT_FILE = 10; + LoadStdProfileSettings(COUNT_RECENT_FILE); + XTROptions::Get().Load(this); +} + +void ExteorApplication::SaveCustomState() { + CWinAppEx::SaveCustomState(); + XTROptions::Get().Save(); +} + +void ExteorApplication::CreateStartingLook() { + if (*m_lpCmdLine != '\0') { + OpenDocumentFile(m_lpCmdLine); + } else if (!XTROptions::App().showStartPage) { + OnStartPage(); + } +} + +CString ExteorApplication::GetModuleFolder() const { + CString path{}; + ::GetModuleFileNameW(m_hInstance, path.GetBuffer(_MAX_PATH + 1), _MAX_PATH + 1); + path.ReleaseBuffer(); + return path.Mid(0, path.ReverseFind('\\') + 1); +} + +BOOL ExteorApplication::RemoveMRUItem(const CString item) { + for (auto i = 0; i < m_pRecentFileList->GetSize(); ++i) { + if ((*m_pRecentFileList)[i] == item) { + m_pRecentFileList->Remove(i); + return TRUE; + } + } + return FALSE; +} + +void ExteorApplication::OnAppAbout() { // NOLINT(readability-convert-member-functions-to-static) + AboutDlg(&MainFrame()).DoModal(); +} + +void ExteorApplication::OnStartPage() { + startPage = std::make_unique(); + startPage->Create(IXTRD_START_PAGE, m_pMainWnd); +} + +void ExteorApplication::OnFileOpen() { + if (::_wchdir(XTROptions::App().pathSaveAs) != 0) { + TRACE0("Cannot set default browsing directory"); + } + CFileDialog dialog(TRUE, nullptr, nullptr, 0, mfc::LoadSID(IXTRS_FILTER_MAIN)); + if (dialog.DoModal() != IDOK) { + return; + } + OpenDocumentFile(dialog.GetPathName()); +} + +void ExteorApplication::OnFileNew() { // NOLINT(readability-convert-member-functions-to-static) + dialog::NewDocument().DoModal(); +} + +void ExteorApplication::OnOpenOptions() { // NOLINT(readability-convert-member-functions-to-static) + dialog::ExteorOptionsSheet().DoModal(); +} + +void ExteorApplication::OpenHelp() { // NOLINT(readability-convert-member-functions-to-static) + ui::HelpHandler::RunHelp(); +} + +void ExteorApplication::OnBugReport() { // NOLINT(readability-convert-member-functions-to-static) + ::AfxMessageBox(IXTRS_REPORT_BUG_PROMPT, MB_ICONASTERISK); + const auto email = mfc::FormatSID(IXTRS_REPORT_BUG_SUBJECT, g_Exteor.version.id.GetString()); + ::ShellExecuteW(nullptr, L"open", email, nullptr, nullptr, SW_SHOWNORMAL); +} + +void ExteorApplication::OnMailDevelopers() { // NOLINT(readability-convert-member-functions-to-static) + const auto email = mfc::FormatSID(IXTRS_REPORT_SUGGESTION, g_Exteor.version.id.GetString()); + ::ShellExecuteW(nullptr, L"open", email, nullptr, nullptr, SW_SHOWNORMAL); +} + +} // namespace xtr \ No newline at end of file diff --git a/src/ExteorOptions.cpp b/src/ExteorOptions.cpp new file mode 100644 index 0000000..49f29cb --- /dev/null +++ b/src/ExteorOptions.cpp @@ -0,0 +1,406 @@ +#include "stdafx.h" + +#include "xtr/ExteorOptions.h" + +#include "resource.h" + +namespace xtr { + +#pragma warning( push ) +#pragma warning( disable : 26495 ) // Do not warn about uninitialized variables in options constructors + +BOOL OptionsSection::CreateTable(CWinAppEx* pWinApp) { + registrySection = mfc::LoadSID(sectionID); + application = pWinApp; + InitDefault(); + LoadTable(); + return TRUE; +} + +BOOL OptionsSection::Save(EntryID entry, int32_t value) { + return application->WriteProfileInt(registrySection, mfc::LoadSID(entry), value); +} + +BOOL OptionsSection::Save(EntryID entry, const CString value) { + return application->WriteProfileStringW(registrySection, mfc::LoadSID(entry), value); +} + +void OptionsSection::Load(EntryID entry, int32_t& output) const { + output = application->GetProfileIntW(registrySection, mfc::LoadSID(entry), output); +} + +void OptionsSection::Load(EntryID entry, CString& output) const { + output = application->GetProfileStringW(registrySection, mfc::LoadSID(entry), output); +} + +CString OptionsSection::LoadHKLMRegistry(const CString folder, const CString keyName, const CString defaultValue) { + HKEY key; + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, folder, 0, KEY_READ | KEY_QUERY_VALUE, &key) != ERROR_SUCCESS) { + return defaultValue; + } + DWORD type, size; + wchar_t data[1024]; + size = sizeof(data); + if (RegQueryValueEx(key, keyName, 0, &type, (BYTE*)data, &size) != ERROR_SUCCESS) { + return defaultValue; + } + const CString result(data); + RegCloseKey(key); + if (result.IsEmpty()) { + return defaultValue; + } else { + return result; + } +} + +BOOL ApplicationOptions::Load(CWinAppEx* pApp) { + return LoadParameters(pApp); +} + +BOOL ApplicationOptions::Save() { + return SaveParameters(); +} + +XTROptions& XTROptions::Get() noexcept { + static XTROptions options{}; + return options; +} + +void XTROptions::SaveWindowPlacement(const CWnd& wnd, const CString entryName) { + WINDOWPLACEMENT wp{}; + wnd.GetWindowPlacement(&wp); + ::AfxGetApp()->WriteProfileBinary(L"WindowPosition", entryName, reinterpret_cast(&wp), sizeof(wp)); +} + +// do not warn about pos object. See GetProfileBinary docs +#pragma warning( push ) +#pragma warning( disable : 26494 26401 ) + +BOOL XTROptions::LoadWindowPlacement(CWnd& wnd, const CString entryName) { + WINDOWPLACEMENT* pos{}; + auto size = 0U; + if (!::AfxGetApp()->GetProfileBinary(L"WindowPosition", entryName, reinterpret_cast(&pos), &size)) { + return FALSE; + } else { + wnd.SetWindowPlacement(pos); + delete[] pos; // NOLINT(cppcoreguidelines-owning-memory) + return TRUE; + } +} + +#pragma warning( pop ) + +BOOL XTROptions::LoadParameters(CWinAppEx* pApp) { + auto flag = true; + + flag = flag && schema.CreateTable(pApp); + + flag = flag && oss.CreateTable(pApp); + flag = flag && general.CreateTable(pApp); + flag = flag && parsing.CreateTable(pApp); + flag = flag && model.CreateTable(pApp); + flag = flag && texting.CreateTable(pApp); + + return flag; +} + +BOOL XTROptions::SaveParameters() { + auto flag = true; + + flag = oss.SaveTable() && flag; + flag = general.SaveTable() && flag; + flag = parsing.SaveTable() && flag; + flag = model.SaveTable() && flag; + flag = texting.SaveTable() && flag; + + flag = schema.SaveTable() && flag; + + return flag; +} + +GeneralOptions::GeneralOptions() // NOLINT(cppcoreguidelines-pro-type-member-init, hicpp-member-init) + : OptionsSection(IXTRO_SECTION_APPLICATION) {} + +void GeneralOptions::InitDefault() { + pathSaveAs = mfc::LoadSID(IXTRS_DEFAULT_CS_OSS_DIR); + + promptVersion = TRUE; + showStartPage = FALSE; + disableAutoKeyboard = FALSE; + + enablePython = TRUE; + pyCrashed = FALSE; +#ifndef _WIN64 + pythonPath = LoadHKLMRegistry(LR"(SOFTWARE\Python\PythonCore\3.12-32\InstallPath)", L"", LR"(C:\Program Files (x86)\Python312-32)"); +#else + pythonPath = LoadHKLMRegistry(LR"(SOFTWARE\Python\PythonCore\3.12\InstallPath)", L"", LR"(C:\Program Files\Python312)"); +#endif + CreateFonts(); +} + +void GeneralOptions::LoadTable() { + Load(IXTRO_SAVEAS_PATH, pathSaveAs); +#ifndef _WIN64 + Load(IXTRO_PYPATH32, pythonPath); +#else + Load(IXTRO_PYPATH64, pythonPath); +#endif + Load(IXTRO_START_PAGE, showStartPage); + + Load(IXTRO_PYSTART, enablePython); + Load(IXTRO_DISABLE_KEYBOARD, disableAutoKeyboard); + Load(IXTRO_PYCRASH, pyCrashed); +} + +BOOL GeneralOptions::SaveTable() { + auto flag = true; + + flag = Save(IXTRO_SAVEAS_PATH, pathSaveAs) && flag; +#ifndef _WIN64 + flag = Save(IXTRO_PYPATH32, pythonPath) && flag; +#else + flag = Save(IXTRO_PYPATH64, pythonPath) && flag; +#endif + + flag = Save(IXTRO_START_PAGE, showStartPage) && flag; + flag = Save(IXTRO_PYSTART, enablePython) && flag; + flag = Save(IXTRO_DISABLE_KEYBOARD, disableAutoKeyboard) && flag; + flag = Save(IXTRO_PYCRASH, pyCrashed) && flag; + + return flag; +} + +BOOL GeneralOptions::CreateFonts() { + static const CString mathFont = L"DejaVu Sans"; + static const CString textFont = L"Times New Roman"; + static const CString defaultFontFile = L"DejaVu Sans.ttf"; + + static constexpr auto mathSize = 20U; + static constexpr auto mathSizeCC = 18U; + static constexpr auto mathSizeTT = 16U; + static constexpr auto tableSize = 20U; + static constexpr auto plainTextSize = 18U; + static constexpr auto tooltipSize = 16U; + static constexpr auto dataSize = 14U; + + ::AddFontResourceExW(defaultFontFile, FR_PRIVATE, nullptr); + + if (InitializeFont(fontMath, mathFont, mathSize) && + InitializeFont(fontMathComment, mathFont, mathSizeCC) && + InitializeFont(fontMathTT, mathFont, mathSizeTT) && + InitializeFont(fontTooltip, mathFont, tooltipSize) && + InitializeFont(fontText, textFont, plainTextSize) && + InitializeFont(fontTable, mathFont, tableSize) && + InitializeFont(fontData, mathFont, dataSize)) { + return TRUE; + } else { + ::AfxMessageBox(IXTRE_CANTLOADFONT, MB_ICONERROR); + return FALSE; + } +} + +#pragma warning( push ) +#pragma warning( disable : 26485 ) // ignore array to pointer decay + +BOOL GeneralOptions::InitializeFont(CFont& font, const CString name, const uint32_t size) { + LOGFONT lfInit{}; + ::memset(&lfInit, 0, sizeof(LOGFONT)); + lfInit.lfHeight = size; + + ::wcscpy_s(lfInit.lfFaceName, static_cast(name.GetLength()) + 1, name); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay, hicpp-no-array-decay) + return font.CreateFontIndirectW(&lfInit); +} + +#pragma warning( pop ) + +RSFormOptions::RSFormOptions() // NOLINT(cppcoreguidelines-pro-type-member-init, hicpp-member-init) + : OptionsSection(IXTRO_SECTION_TRSVIEW) {} + +void RSFormOptions::InitDefault() noexcept { + exportOptions.bTerm = TRUE; + exportOptions.bRSDef = TRUE; + exportOptions.bTextDef = TRUE; + exportOptions.bComment = TRUE; + exportOptions.bTyping = FALSE; + + splitterPos = 200; // NOLINT + + ResetTableWidth(); +} + +void RSFormOptions::ResetTableWidth() noexcept { + nameWidth = 70; // NOLINT + typeWidth = 150; // NOLINT + expWidth = 250; // NOLINT + termWidth = 150; // NOLINT + interWidth = 220; // NOLINT + conventionWidth = 220; // NOLINT +} + +void RSFormOptions::LoadTable() { + Load(IXTRO_TRSV_NAME_WIDTH, nameWidth); + Load(IXTRO_TRSV_TYPE_WIDTH, typeWidth); + Load(IXTRO_TRSV_EXP_WIDTH, expWidth); + Load(IXTRO_TRSV_TERM_WIDTH, termWidth); + Load(IXTRO_TRSV_INTER_WIDTH, interWidth); + Load(IXTRO_TRSV_COMMENT_WIDTH, conventionWidth); + + Load(IXTRO_TRSV_EXPT_TERM, exportOptions.bTerm); + Load(IXTRO_TRSV_EXPT_FORM, exportOptions.bRSDef); + Load(IXTRO_TRSV_EXPT_INTER, exportOptions.bTextDef); + Load(IXTRO_TRSV_EXPT_COM, exportOptions.bComment); + Load(IXTRO_TRSV_EXPT_TYPE, exportOptions.bTyping); + + Load(IXTRO_TRSV_SPLITTER_POS, splitterPos); +} + +BOOL RSFormOptions::SaveTable() { + auto flag = true; + flag = Save(IXTRO_TRSV_NAME_WIDTH, nameWidth) && flag; + flag = Save(IXTRO_TRSV_TYPE_WIDTH, typeWidth) && flag; + flag = Save(IXTRO_TRSV_EXP_WIDTH, expWidth) && flag; + flag = Save(IXTRO_TRSV_TERM_WIDTH, termWidth) && flag; + flag = Save(IXTRO_TRSV_INTER_WIDTH, interWidth) && flag; + flag = Save(IXTRO_TRSV_COMMENT_WIDTH, conventionWidth) && flag; + + flag = Save(IXTRO_TRSV_EXPT_TERM, exportOptions.bTerm) && flag; + flag = Save(IXTRO_TRSV_EXPT_FORM, exportOptions.bRSDef) && flag; + flag = Save(IXTRO_TRSV_EXPT_INTER, exportOptions.bTextDef) && flag; + flag = Save(IXTRO_TRSV_EXPT_COM, exportOptions.bComment) && flag; + flag = Save(IXTRO_TRSV_EXPT_TYPE, exportOptions.bTyping && flag); + + flag = Save(IXTRO_TRSV_SPLITTER_POS, splitterPos) && flag; + return flag; +} + +ossOptions::ossOptions() // NOLINT(cppcoreguidelines-pro-type-member-init, hicpp-member-init) + : OptionsSection(IXTRO_SECTION_OSS) {} + +void ossOptions::InitDefault() noexcept { + zoom = 1; + splitterPos = 300; // NOLINT + runOpAfterEdit = TRUE; + showGrid = TRUE; + showLegend = TRUE; +} + +void ossOptions::LoadTable() { + Load(IXTRO_ZOOM_VISIBLE, zoom); + Load(IXTRO_OSS_SPLITTER, splitterPos); + Load(IXTRO_RUN_AFTER_OK, runOpAfterEdit); + Load(IXTRO_OSS_GRID, showGrid); + Load(IXTRO_OSS_LEGEND, showLegend); +} + +BOOL ossOptions::SaveTable() { + auto flag = true; + flag = Save(IXTRO_ZOOM_VISIBLE, zoom) && flag; + flag = Save(IXTRO_OSS_SPLITTER, splitterPos) && flag; + flag = Save(IXTRO_RUN_AFTER_OK, runOpAfterEdit) && flag; + flag = Save(IXTRO_OSS_GRID, showGrid) && flag; + flag = Save(IXTRO_OSS_LEGEND, showLegend) && flag; + return flag; +} + +ParsingOptions::ParsingOptions() // NOLINT(cppcoreguidelines-pro-type-member-init, hicpp-member-init) + : OptionsSection(IXTRO_SECTION_ANALYZER) {} + +void ParsingOptions::InitDefault() noexcept { + autoCheck = FALSE; + colorBrackets = TRUE; + showAST = TRUE; + enableNavigator = TRUE; + indexing.global = index::Digits::subText; + indexing.local = index::Digits::subText; + indexing.operators = index::Digits::subText; +} + +void ParsingOptions::LoadTable() { + Load(IXTRO_CST_AUTOCHECK, autoCheck); + Load(IXTRO_SA_COLORPAR, colorBrackets); + Load(IXTRO_SA_AST, showAST); + Load(IXTRO_SA_NAVIGATOR, enableNavigator); + LoadAs(IXTRO_RSFORM_INDEXCST, indexing.global); + LoadAs(IXTRO_RSFORM_INDEXLOCAL, indexing.local); + LoadAs(IXTRO_RSFORM_INDEXPR, indexing.operators); +} + +BOOL ParsingOptions::SaveTable() { + auto flag = true; + flag = Save(IXTRO_CST_AUTOCHECK, autoCheck) && flag; + flag = Save(IXTRO_SA_COLORPAR, colorBrackets) && flag; + flag = Save(IXTRO_SA_AST, showAST) && flag; + flag = Save(IXTRO_SA_NAVIGATOR, enableNavigator) && flag; + flag = SaveAs(IXTRO_RSFORM_INDEXCST, indexing.global) && flag; + flag = SaveAs(IXTRO_RSFORM_INDEXLOCAL, indexing.local) && flag; + flag = SaveAs(IXTRO_RSFORM_INDEXPR, indexing.operators) && flag; + return flag; +} + +ModelOptions::ModelOptions() // NOLINT(cppcoreguidelines-pro-type-member-init, hicpp-member-init) + : OptionsSection(IXTRO_SECTION_MODEL) {} + +void ModelOptions::InitDefault() noexcept { + m_DataMode = TRUE; + splitterPos = 200; // NOLINT + ResetTableWidth(); +} + +void ModelOptions::ResetTableWidth() noexcept { + nameWidth = 70; // NOLINT + typeWidth = 150; // NOLINT + expWidth = 220; // NOLINT + valWidth = 60; // NOLINT + termWidth = 150; // NOLINT + interWidth = 220; // NOLINT + conventionWidth = 220; // NOLINT +} + +void ModelOptions::LoadTable() { + Load(IXTRO_TRSV_DATAMODE, m_DataMode); + Load(IXTRO_TRSV_NAME_WIDTH, nameWidth); + Load(IXTRO_TRSV_TYPE_WIDTH, typeWidth); + Load(IXTRO_TRSV_EXP_WIDTH, expWidth); + Load(IXTRO_RSM_VAL_WIDTH, valWidth); + Load(IXTRO_TRSV_TERM_WIDTH, termWidth); + Load(IXTRO_TRSV_INTER_WIDTH, interWidth); + Load(IXTRO_TRSV_COMMENT_WIDTH, conventionWidth); + Load(IXTRO_TRSV_SPLITTER_POS, splitterPos); +} + +BOOL ModelOptions::SaveTable() { + BOOL flag = TRUE; + flag = Save(IXTRO_TRSV_DATAMODE, m_DataMode) && flag; + flag = Save(IXTRO_TRSV_NAME_WIDTH, nameWidth) && flag; + flag = Save(IXTRO_TRSV_TYPE_WIDTH, typeWidth) && flag; + flag = Save(IXTRO_TRSV_EXP_WIDTH, expWidth) && flag; + flag = Save(IXTRO_RSM_VAL_WIDTH, valWidth) && flag; + flag = Save(IXTRO_TRSV_INTER_WIDTH, interWidth) && flag; + flag = Save(IXTRO_TRSV_TERM_WIDTH, termWidth) && flag; + flag = Save(IXTRO_TRSV_COMMENT_WIDTH, conventionWidth) && flag; + flag = Save(IXTRO_TRSV_SPLITTER_POS, splitterPos) && flag; + return flag; +} + +TextOptions::TextOptions() // NOLINT(cppcoreguidelines-pro-type-member-init, hicpp-member-init) + : OptionsSection(IXTRO_SECTION_TEXT) {} + +void TextOptions::InitDefault() noexcept { + editReference = FALSE; +} + +void TextOptions::LoadTable() { + Load(IXTRO_TXT_EDITREF, editReference); +} + +BOOL TextOptions::SaveTable() { + auto flag = true; + + flag = flag && Save(IXTRO_TXT_EDITREF, editReference); + + return flag; +} + +#pragma warning( pop ) + +} // namespace xtr \ No newline at end of file diff --git a/src/SetupManager.cpp b/src/SetupManager.cpp new file mode 100644 index 0000000..3507955 --- /dev/null +++ b/src/SetupManager.cpp @@ -0,0 +1,85 @@ +#include "stdafx.h" + +#include "SetupManager.h" + +#include "resource.h" + +#include "xtr/ExteorOptions.h" +#include "xtr/ExtSourceManager.h" +#include "xtr/xtrServices.h" +#include "xtr/mfcMessageManager.h" + +#include "xtr/core/PyTextProcessor.h" +#include "xtr/core/PyCore.h" + +#include "ccl/lang/TextEnvironment.h" + +namespace xtr { + +using core::PyTextProcessor; +using cxxpython::PyCore; + +void SetupManager::InitEnvironment() { + Global::Instance().SetMessageManager(std::make_unique()); +} + +void SetupManager::CCLInitSequence() { + InitSourceManager(); + InitTextModule(); +} + +void SetupManager::CCLExitSequence() { + KillTextModule(); +} + +void SetupManager::InitSourceManager() { + ccl::Environment::Instance().SetSourceManager(std::make_unique()); +} + +void SetupManager::InitTextModule() { + static const std::string moduleName = "cctext"; + if (!LoadPython()) { + return; + } else { + auto processor = std::make_unique(); + if (!PyCore::Instance().LoadModule(moduleName, moduleName)) { + ::AfxMessageBox(IXTRS_PYERR_NOCORE, MB_ICONERROR); + } else { + processor->InitModule(moduleName); + } + ccl::lang::TextEnvironment::SetProcessor(std::move(processor)); + } +} + +bool SetupManager::LoadPython() { + if (!XTROptions::App().enablePython) { + return false; + } + + if (XTROptions::App().pyCrashed) { + if (::AfxMessageBox(IXTRS_PYTHON_CRASH_PROMPT, MB_YESNO | MB_ICONQUESTION) != IDYES) { + XTROptions::App().enablePython = FALSE; + XTROptions::App().pyCrashed = FALSE; + XTROptions::Get().Save(); + return false; + } + } + + XTROptions::App().pyCrashed = TRUE; + XTROptions::Get().Save(); + + if (!cxxpython::PyCore::Instance().Start(XTROptions::App().pythonPath)) { + ::AfxMessageBox(IXTRS_PYERR_NOLOAD, MB_ICONERROR); + return false; + } else { + XTROptions::App().pyCrashed = FALSE; + XTROptions::Get().Save(); + return true; + } +} + +void SetupManager::KillTextModule() { + cxxpython::PyCore::Instance().Stop(); +} + +} // namespace xtr \ No newline at end of file diff --git a/src/cclDescriptor.cpp b/src/cclDescriptor.cpp new file mode 100644 index 0000000..047ec9b --- /dev/null +++ b/src/cclDescriptor.cpp @@ -0,0 +1,615 @@ +#include "stdafx.h" + +#include "xtr/cclDescriptor.h" + +#include "resource.h" + +#include "xtr/mfcHelper.h" +#include "xtr/core/rslIndex.hpp" +#include "xtr/ExteorOptions.h" +#include "ccl/rslang/RSGenerator.h" +#include "ccl/semantic/CstFilters.hpp" + +using ccl::rslang::AST2String; + +namespace xtr::info { + +#pragma warning( push ) +#pragma warning( disable : 26485 ) // do not complain about array to pointer decay for strings + +using ccl::semantic::RSCore; +using ccl::semantic::RSForm; +using ccl::semantic::RSModel; +using ccl::semantic::EvalStatus; +using ccl::semantic::ParsingStatus; +using ccl::object::StructuredData; +using ccl::rslang::ExpressionType; + +namespace { + +[[nodiscard]] ErrorType ResolveErrorType(const uint32_t error) noexcept { + static constexpr auto ERRCODE_LEXER_MASK = 0x0200U; + static constexpr auto ERRCODE_PARSER_MASK = 0x0400U; + static constexpr auto ERRCODE_TYPE_MASK = 0x0800U; + static constexpr auto ERRCODE_VALUE_MASK = 0x0A00U; + + if ((error & ERRCODE_VALUE_MASK) == ERRCODE_VALUE_MASK) { + return ErrorType::VALUE; + } else if ((error & ERRCODE_LEXER_MASK) != 0) { + return ErrorType::LEXER; + } else if ((error & ERRCODE_PARSER_MASK) != 0) { + return ErrorType::PARSER; + } else if ((error & ERRCODE_TYPE_MASK) != 0) { + return ErrorType::SEMANTIC; + } else { + return ErrorType::UNKNOWN; + } +} + +[[nodiscard]] constexpr uint32_t MsgIDFor(const ccl::rslang::LexerEID error) noexcept { + switch (error) { + default: + case ccl::rslang::LexerEID::unknownSymbol: return IXTRS_LEX_UNKNOWN_SYM; + } +} + +[[nodiscard]] constexpr uint32_t MsgIDFor(const ccl::rslang::ParseEID error) noexcept { + using ccl::rslang::ParseEID; + switch (error) { + default: + case ParseEID::syntax: return IXTRS_PAR_SYNTHAXERROR; + case ParseEID::missingParenthesis: return IXTRS_PAR_EXPECTED_RP; + case ParseEID::missingCurlyBrace: return IXTRS_PAR_EXPECTED_RC; + case ParseEID::invalidQuantifier: return IXTRS_PAR_QUANTDECL; + case ParseEID::invalidImperative: return IXTRS_PAR_IMPERATIVE; + case ParseEID::expectedDeclaration: return IXTRS_PAR_EXPECTED_ARGDECL; + case ParseEID::expectedLocal: return IXTRS_PAR_EXPECTED_VAR; + } +} + +[[nodiscard]] constexpr uint32_t MsgIDFor(const ccl::rslang::SemanticEID error) noexcept { + using ccl::rslang::SemanticEID; + switch (error) { + default: + case SemanticEID::localUndeclared: return IXTRS_TYPE_NAME_UKNOWN; + case SemanticEID::localShadowing: return IXTRS_TYPE_NAME_DECLARED; + case SemanticEID::globalFuncMissing: return IXTRS_TYPE_UNKNOWN_FUNCTION; + case SemanticEID::globalFuncWithoutArgs: return IXTRS_TYPE_FUNCTION_AS_GLOBAL; + case SemanticEID::typesNotEqual: return IXTRS_TYPE_WRONG_TYPE; + case SemanticEID::globalNotTyped: return IXTRS_TYPE_GLOBAL_NOTYPE; + case SemanticEID::invalidDecart: return IXTRS_TYPE_CART; + case SemanticEID::localDoubleDeclare: return IXTRS_TYPE_NAME_REDECLARED; + case SemanticEID::invalidBoolean: return IXTRS_TYPE_BOOL; + case SemanticEID::invalidTypeOperation: return IXTRS_TYPE_SET_OPERATOR; + case SemanticEID::invalidCard: return IXTRS_TYPE_CARD; + case SemanticEID::invalidDebool: return IXTRS_TYPE_DEBOOL; + case SemanticEID::invalidReduce: return IXTRS_TYPE_RED; + case SemanticEID::invalidProjectionTuple: return IXTRS_TYPE_PR_ERROR; + case SemanticEID::invalidProjectionSet: return IXTRS_TYPE_BIGPR; + case SemanticEID::invalidEnumeration: return IXTRS_TYPE_ENUMERATION; + case SemanticEID::invalidBinding: return IXTRS_TYPE_DECLARE_CORTEGE; + case SemanticEID::localOutOfScope: return IXTRS_TYPE_NAME_SCOPE; + case SemanticEID::invalidElementPredicate: return IXTRS_TYPE_EL_WRONG_TYPE; + case SemanticEID::localNotUsed: return IXTRS_TYPE_NAME_NOT_USED; + case SemanticEID::invalidArgsArity: return IXTRS_TYPE_FUNC_ARGNUM; + case SemanticEID::invalidArgumentType: return IXTRS_TYPE_FUNC_WRONG_ARG; + case SemanticEID::globalStructure: return IXTRS_TYPE_STRUCTURE; + case SemanticEID::globalExpectedFunction: return IXTRS_TYPE_FUNCTION; + case SemanticEID::radicalUsage: return IXTRS_USE_RADICAL; + case SemanticEID::invalidFilterArgumentType: return IXTRS_FILTER_ARGUMENT; + case SemanticEID::invalidFilterArity: return IXTRS_FILTER_PARAM_ARITY; + case SemanticEID::arithmeticNotSupported: return IXTRS_NO_ARITHMETIC; + case SemanticEID::typesNotCompatible: return IXTRS_INCOMPATIBLE_TYPES; + case SemanticEID::orderingNotSupported: return IXTRS_NO_ORDERING; + + case SemanticEID::globalNoValue: return IXTRS_GLOBAL_NO_VALUE_CLASS; + case SemanticEID::invalidPropertyUsage: return IXTRS_PROXY_AS_VALUE; + case SemanticEID::globalMissingAST: return IXTRS_GLOBAL_NO_AST; + case SemanticEID::globalFuncNoInterpretation: return IXTRS_FUNCTION_CALL_INVALID; + } +} + +[[nodiscard]] constexpr uint32_t MsgIDFor(const ccl::rslang::ValueEID error) noexcept { + using ccl::rslang::ValueEID; + switch (error) { + default: + case ValueEID::unknownError: return IXTRS_VALUE_UNKNOWN_ERROR; + case ValueEID::typedOverflow: return IXTRS_VALUE_SET_LIMIT; + case ValueEID::booleanLimit: return IXTRS_VALUE_BOOL_LIMIT; + case ValueEID::globalMissingValue: return IXTRS_VALUE_VAR_INCALC; + case ValueEID::iterationsLimit: return IXTRS_VALUE_ITER_LIMIT; + case ValueEID::invalidDebool: return IXTRS_VALUE_DEBOOL; + case ValueEID::iterateInfinity: return IXTRS_ITERATE_INFINITY; + } +} + +[[nodiscard]] CString ErrorMessage(const uint32_t errorCode, const std::vector& params) { + const auto errType = ResolveErrorType(errorCode); + auto prefix = Label(errType); + prefix.AppendFormat(LR"(%04X)", errorCode); + prefix += LR"(: )"; + const uint32_t msgID = [&]() noexcept -> uint32_t { + switch (errType) { + default: + case ErrorType::UNKNOWN: return 0; + case ErrorType::LEXER: return MsgIDFor(static_cast(errorCode)); + case ErrorType::PARSER: return MsgIDFor(static_cast(errorCode)); + case ErrorType::SEMANTIC: return MsgIDFor(static_cast(errorCode)); + case ErrorType::VALUE: return MsgIDFor(static_cast(errorCode)); + } + }(); + if (msgID == 0) { + return prefix; + } else { + switch (std::size(params)) { + default: return prefix + mfc::LoadSID(msgID); + case 1: return prefix + mfc::FormatSID(msgID, + mfc::ToMFC(params.at(0)).GetString()); + case 2: return prefix + mfc::FormatSID(msgID, + mfc::ToMFC(params.at(0)).GetString(), + mfc::ToMFC(params.at(1)).GetString()); + case 3: return prefix + mfc::FormatSID(msgID, + mfc::ToMFC(params.at(0)).GetString(), + mfc::ToMFC(params.at(1)).GetString(), + mfc::ToMFC(params.at(2)).GetString()); + } + } +} + +} // namespace + +CoreStatus StatusOf(const ccl::semantic::RSCore& core) { + if (core.RSLang().Graph().HasLoop()) { + return CoreStatus::INCORRECT; + } else if (core.Texts().TermGraph().HasLoop()) { + return CoreStatus::INCORRECT; + } else if (std::any_of(std::begin(core), std::end(core), + [&parse = core](const auto uid) { + return parse.GetParse(uid).status != ParsingStatus::VERIFIED; + })) { + return CoreStatus::INCORRECT; + } else if (std::any_of(std::begin(core), std::end(core), [&core](const auto uid) { + return core.GetRS(uid).IsEmpty() && core.GetText(uid).IsEmpty(); })) { + return CoreStatus::WARNING; + } else if (core.Texts().HasHomonyms()) { + return CoreStatus::WARNING; + } else { + return CoreStatus::CORRECT; + } +} + +ModelStatus StatusOf(const ccl::semantic::RSModel& target) { + if (target.Calculations().Count(EvalStatus::INCALCULABLE) > 0 || + target.Calculations().Count(EvalStatus::NEVER_CALCULATED) > 0) { + return ModelStatus::INCORRECT; + } else if (target.Calculations().Count(EvalStatus::AXIOM_FAIL) > 0) { + return ModelStatus::WARNING; + } else { + return ModelStatus::CORRECT; + } +} + +CString ValueStatus(const EntityUID target, const RSModel& model) { + static const CString strTrue = L"T"; + static const CString strFalse = L"F"; + static const CString strEmptySet = L"0"; + static const CString strNoValue = LR"(N/A)"; + static const CString strSingleValue = L"S"; + + if (!model.Contains(target)) { + return CString{}; + } else if (const auto status = model.Calculations()(target); status <= EvalStatus::INCALCULABLE) { + return strNoValue; + } else if (!ccl::semantic::IsRSObject(model.GetRS(target).type)) { + const auto logicVal = model.Values().StatementFor(target); + return logicVal.has_value() && logicVal.value() ? strTrue : strFalse; + } else if (status == EvalStatus::EMPTY) { + return strEmptySet; + } else if (auto val = model.Values().SDataFor(target); !val.has_value()) { + return strNoValue; + } else if (!val->IsCollection()) { + return strSingleValue; + } else { + CString result{}; + result.Format(L"%d", static_cast(val->B().Cardinality())); + return result; + } +} + +CString Label(const ccl::ops::Status status) { + using ccl::ops::Status; + switch (status) { + default: return mfc::LoadSID(IXTRS_PICT_DEFAULT); + case Status::undefined: return mfc::LoadSID(IXTRS_PICT_UNDEFINED); + case Status::defined: return mfc::LoadSID(IXTRS_PICT_DEFINED); + case Status::done: return mfc::LoadSID(IXTRS_PICT_DONE); + case Status::outdated: return mfc::LoadSID(IXTRS_PICT_REDO); + case Status::broken: return mfc::LoadSID(IXTRS_PICT_BROKEN); + } +} + +CString DrawableLabel(const ccl::ops::Status status) { + using ccl::ops::Status; + switch (status) { + default: return mfc::LoadSID(IXTRS_PICT_DEFAULT); + case Status::undefined: return mfc::LoadSID(IXTRS_DRAW_UNDEFINED); + case Status::defined: return mfc::LoadSID(IXTRS_DRAW_DEFINED); + case Status::done: return mfc::LoadSID(IXTRS_DRAW_DONE); + case Status::outdated: return mfc::LoadSID(IXTRS_DRAW_REDO); + case Status::broken: return mfc::LoadSID(IXTRS_DRAW_BROKEN); + } +} + +CString LabelBool(const bool flag) { + return mfc::LoadSID(flag ? IXTRS_YES : IXTRS_NO); +} + +CString Label(const ccl::ops::Type type) { + switch (type) { + default: return mfc::LoadSID(IXTRS_OP_NOT_DEF); + case ccl::ops::Type::rsMerge: return mfc::LoadSID(IXTRS_OPLABEL_MERGE); + case ccl::ops::Type::rsSynt: return mfc::LoadSID(IXTRS_OPLABEL_SYNT); + } +} + +CString Label(const ccl::src::SrcType type) { + using ccl::src::SrcType; + switch (type) { + case SrcType::tba: + default: return mfc::LoadSID(IXTRS_SRC_TYPE_TBA); + case SrcType::rsDoc: return mfc::LoadSID(IXTRS_SRC_TYPE_TRS); + } +} + +CString Label(ccl::lang::Grammem gram) { + using ccl::lang::Grammem; + switch (gram) { + default: + case Grammem::nomn: return mfc::LoadSID(IXTRS_CASE_NOMN); + case Grammem::gent: return mfc::LoadSID(IXTRS_CASE_GENT); + case Grammem::datv: return mfc::LoadSID(IXTRS_CASE_DATV); + case Grammem::accs: return mfc::LoadSID(IXTRS_CASE_ACCS); + case Grammem::ablt: return mfc::LoadSID(IXTRS_CASE_ABLT); + case Grammem::loct: return mfc::LoadSID(IXTRS_CASE_LOCT); + + case Grammem::sing: return mfc::LoadSID(IXTRS_PLUR_SINGULAR); + case Grammem::plur: return mfc::LoadSID(IXTRS_PLUR_PLURAL); + + case Grammem::masc: return mfc::LoadSID(IXTRS_GENDER_MASC); + case Grammem::femn: return mfc::LoadSID(IXTRS_GENDER_FEMN); + case Grammem::neut: return mfc::LoadSID(IXTRS_GENDER_NEUT); + } +} + +CString DescriptionOf(const ccl::lang::Grammem gram) { + using ccl::lang::Grammem; + switch (gram) { + default: + case Grammem::nomn: return mfc::LoadSID(IXTRS_CASEQ_NOMN); + case Grammem::gent: return mfc::LoadSID(IXTRS_CASEQ_GENT); + case Grammem::datv: return mfc::LoadSID(IXTRS_CASEQ_DATV); + case Grammem::accs: return mfc::LoadSID(IXTRS_CASEQ_ACCS); + case Grammem::ablt: return mfc::LoadSID(IXTRS_CASEQ_ABLT); + case Grammem::loct: return mfc::LoadSID(IXTRS_CASEQ_LOCT); + } +} + +CString Label(const CoreStatus status) { + switch (status) { + case CoreStatus::CORRECT: return mfc::LoadSID(IXTRS_CORE_CORRECT); + case CoreStatus::WARNING: return mfc::LoadSID(IXTRS_CORE_WARNING); + default: + case CoreStatus::INCORRECT: return mfc::LoadSID(IXTRS_CORE_INCORRECT); + } +} + +CString Label(const ModelStatus status) { + switch (status) { + case ModelStatus::CORRECT: return mfc::LoadSID(IXTRS_MODEL_CORRECT); + case ModelStatus::WARNING: return mfc::LoadSID(IXTRS_MODEL_WARNING); + default: + case ModelStatus::INCORRECT: return mfc::LoadSID(IXTRS_MODEL_INCORRECT); + } +} + +CString IndicatorFor(const RSCore& core) { + CString message{}; + const auto invalidCount = std::count_if( + std::begin(core), std::end(core), + [&parse = core](const auto uid) { + return parse.GetParse(uid).status != ParsingStatus::VERIFIED; + } + ); + message.Format(LR"(%d | %d)", static_cast(std::ssize(core)), static_cast(invalidCount)); + return message; +} + +CString BasicDescriptionOf(const RSCore& core) { + const auto invalidCount = std::count_if( + std::begin(core), std::end(core), + [&parse = core](const auto uid) { + return parse.GetParse(uid).status != ParsingStatus::VERIFIED; + } + ); + const auto statusLabel = Label(StatusOf(core)); + return mfc::FormatSID(IXTRS_DESCRIPTION_CORE, statusLabel.GetString(), std::size(core), invalidCount); +} + +CString DescriptionOf(const RSCore& core) { + auto message = BasicDescriptionOf(core); + if (const auto emptyCst = ccl::semantic::FilterEmpty(core); !std::empty(emptyCst)) { + message += mfc::LoadSID(IXTRS_EMPTY_CST_FOUND); + for (const auto uid : emptyCst) { + message += mfc::ToMFC(core.GetRS(uid).alias); + message += L" "; + } + } + + if (core.RSLang().Graph().HasLoop()) { + message += mfc::LoadSID(IXTRS_FORMULA_CYCLE_FOUND); + message += GenerateLoopStr(core, core.RSLang().Graph().GetAllLoopsItems()); + } + if (core.Texts().TermGraph().HasLoop()) { + message += mfc::LoadSID(IXTRS_REFERENCE_CYCLE_FOUND); + message += GenerateLoopStr(core, core.Texts().TermGraph().GetAllLoopsItems()); + } + if (const auto homonyms = core.Texts().GetHomonyms(); !std::empty(homonyms)) { + message += mfc::LoadSID(IXTRS_SYNONYMS_FOUND); + message += DescriptionOf(homonyms); + } + return message; +} + +CString DescriptionOf(const ccl::StrSubstitutes& substitutes) { + CString info{}; + for (const auto& [key, value] : substitutes) { + if (!info.IsEmpty()) { + info += L" "; + } + info += mfc::ToMFC(key); + info += L" => "; + info += mfc::ToMFC(value); + info += ';'; + } + return info; +} + +CString IndicatorFor(const RSModel& model) { + CString message{}; + message.Format(LR"(%d | %d | %d | %d)", + model.Calculations().Count(EvalStatus::NEVER_CALCULATED), + model.Calculations().Count(EvalStatus::INCALCULABLE), + model.Calculations().Count(EvalStatus::AXIOM_FAIL), + model.Calculations().Count(EvalStatus::EMPTY)); + return message; +} + +CString BasicDescriptionOf(const RSModel& model) { + return mfc::FormatSID(IXTRS_DESCRIPTION_MODEL, + Label(StatusOf(model)).GetString(), + model.Calculations().Count(EvalStatus::NEVER_CALCULATED), + model.Calculations().Count(EvalStatus::INCALCULABLE), + model.Calculations().Count(EvalStatus::AXIOM_FAIL), + model.Calculations().Count(EvalStatus::EMPTY)); +} + +CString DescriptionOf(const RSModel& model) { + auto message = BasicDescriptionOf(model); + if (const auto emptyCst = ccl::semantic::FilterEmpty(model.Core()); !std::empty(emptyCst)) { + message += mfc::LoadSID(IXTRS_EMPTY_CST_FOUND); + for (const auto uid : emptyCst) { + message += mfc::ToMFC(model.GetRS(uid).alias); + message += L" "; + } + } + + if (model.Core().RSLang().Graph().HasLoop()) { + message += mfc::LoadSID(IXTRS_FORMULA_CYCLE_FOUND); + message += GenerateLoopStr(model.Core(), model.RSLang().Graph().GetAllLoopsItems()); + } + + if (model.Core().Texts().TermGraph().HasLoop()) { + message += mfc::LoadSID(IXTRS_REFERENCE_CYCLE_FOUND); + message += GenerateLoopStr(model.Core(), model.Texts().TermGraph().GetAllLoopsItems()); + } + + if (const auto homonyms = model.Core().Texts().GetHomonyms(); !std::empty(homonyms)) { + message += mfc::LoadSID(IXTRS_SYNONYMS_FOUND); + message += DescriptionOf(homonyms); + } + return message; +} + +CString BasicDescriptionOf(const ccl::oss::PictID pict, ccl::oss::OSSchema& oss) { + CString infoStr{}; + if (const auto* schema = ccl::src::CastData(oss.Src().DataFor(pict)); schema != nullptr) { + infoStr = info::BasicDescriptionOf(schema->Core()); + } else if (const auto& srcName = oss.Src()(pict)->desc.name; !empty(srcName)) { + infoStr = mfc::FormatSID(IXTRS_PICTINFO_NO_ACCESS, mfc::ToMFC(srcName).GetString()); + } else { + infoStr = mfc::LoadSID(IXTRS_PICTINFO_TBA); + } + + if (!std::empty(oss(pict)->comment)) { + infoStr += L"\n"; + infoStr += mfc::ToMFC(oss(pict)->comment); + } + return infoStr; +} + +CString DescriptionOf(const ccl::rslang::Auditor& analytics, const BOOL showAST) { + CString msgLog{}; + const ccl::rslang::ExpressionType* type = &analytics.GetType(); + if (!analytics.isParsed) { + msgLog += mfc::LoadSID(IXTRS_PAR_FAILURE); + } else if (!analytics.isTypeCorrect) { + type = nullptr; + msgLog += mfc::LoadSID(IXTRS_TYPECHECK_FAILURE); + } else if (!analytics.isValueCorrect) { + msgLog += mfc::LoadSID(IXTRS_VALUECHECK_FAILURE); + } else { + msgLog += mfc::LoadSID(IXTRS_RS_CHECK_SUCCESS); + } + + msgLog += DescriptionOf(analytics.Errors()); + + msgLog += '\n'; + msgLog += mfc::FormatSID(IXTRS_REPORT_TYPIFICATION, Label(type).GetString()); + + msgLog += '\n'; + msgLog += mfc::FormatSID(IXTRS_REPORT_VALUE_CLASS, Label(analytics.GetValueClass()).GetString()); + + if (showAST && analytics.isParsed) { + msgLog += '\n'; + msgLog += mfc::FormatSID(IXTRS_REPORT_AST, mfc::ToMFC(AST2String::Apply(analytics.parser.AST())).GetString()); + } + + return msgLog; +} + +CString DescriptionOf(const ccl::rslang::Interpreter& calculator, + const std::optional& result, const BOOL showAST) { + using ccl::rslang::Generator; + CString msgLog{}; + const auto calculateOk = !calculator.Errors().HasCriticalErrors(); + msgLog += mfc::LoadSID(calculateOk ? IXTRS_VALUE_SUCCESS : IXTRS_VALUE_FAILURE); + + msgLog += '\n'; + msgLog += DescriptionOf(calculator.Errors()); + + msgLog += '\n'; + msgLog += mfc::FormatSID(IXTRS_REPORT_ITERATIONS, calculator.Iterations()); + + msgLog += '\n'; + msgLog += mfc::FormatSID(IXTRS_REPORT_NORMALIZED_EXPR, + mfc::ToMFC(Generator::FromTree(calculator.NormalizedParseTree())).GetString()); + if (showAST) { + msgLog += '\n'; + msgLog += mfc::FormatSID(IXTRS_REPORT_NORMALIZED_AST, + mfc::ToMFC(AST2String::Apply(calculator.NormalizedParseTree())).GetString()); + } + if (result.has_value()) { + msgLog += '\n'; + msgLog += std::visit(ccl::meta::Overloads{ + [&](const StructuredData& data) { + if (data.IsCollection()) { + return mfc::FormatSID(IXTRS_REPORT_SET_VALUE, + data.B().Cardinality(), + mfc::ToMFC(data.ToString()).GetString()); + } else { + return mfc::FormatSID(IXTRS_REPORT_VALUE, mfc::ToMFC(data.ToString()).GetString()); + } + }, + [](const bool& data) { return data ? CString{L"TRUE"} : CString{L"FALSE"}; }, + [](const auto& /*data*/) { return CString{L"ERROR"}; } + }, result.value()); + } + return msgLog; +} + +CString DescriptionOf(const ccl::rslang::ErrorLogger& log) { + using ccl::rslang::ErrorStatus; + CString msgLog{}; + if (!empty(log.All())) { + for (const auto& err : log.All()) { + msgLog += '\n'; + msgLog += DescriptionOf(err); + } + msgLog += '\n'; + msgLog += mfc::FormatSID(IXTRS_REPORT_ERR_COUNT, + log.Count(ErrorStatus::WARNING), + log.Count(ErrorStatus::CRITICAL)); + } + return msgLog; +} + +CString DescriptionOf(const ccl::rslang::Error& error) { + return ErrorMessage(error.eid, error.params); +} + +CString Label(const ErrorType type) { + switch (type) { + default: + case ErrorType::UNKNOWN: return L"U"; + case ErrorType::LEXER: return L"L"; + case ErrorType::PARSER: return "P"; + case ErrorType::SEMANTIC: return "S"; + case ErrorType::VALUE: return "V"; + } +} + +CString DescriptionOf(const ccl::lang::Reference& ref) { + using ccl::lang::ReferenceType; + switch (ref.GetType()) { + case ReferenceType::entity: { + const auto& form = ref.GetForm(); + return mfc::FormatSID(IXTRS_DESCRIPTION_REFERENCE, + mfc::ToMFC(ref.GetEntity()).GetString(), + Label(form.GetCase()).GetString(), + Label(form.GetNumber()).GetString(), + mfc::ToMFC(ref.ToString()).GetString()); + } + case ReferenceType::collaboration: { + return mfc::FormatSID(IXTRS_DESCRIPTION_DEPENDANT_WORD, + mfc::ToMFC(ref.GetNominal()).GetString(), + mfc::ToMFC(std::to_string(ref.GetOffset())).GetString(), + mfc::ToMFC(ref.ToString()).GetString()); + } + default: + case ReferenceType::invalid: return L"DESCRIPTION NOT AVAILABLE"; + } +} + +CString DescriptionOf(ccl::oss::ossOperationsFacet& ops, const ccl::oss::PictID pid) { + return mfc::FormatSID(IXTRS_DESCRIPTION_OPERATION, + LabelBool(ops.IsExecutable(pid)).GetString(), + LabelBool(ops.IsTranslatable(pid)).GetString()); +} + +CString GenerateLoopStr(const RSCore& schema, const std::vector& loops) { + if (!empty(loops)) { + auto i = 0; + auto str = mfc::FormatSID(IXTRS_SCC_INFO, size(loops)); + for (const auto& loop : loops) { + str += mfc::FormatSID(IXTRS_SCC_INFO_COUNT, i + 1); + for (const auto item : loop) { + str += mfc::ToMFC(schema.GetRS(item).alias) + ' '; + } + ++i; + } + return str; + } else { + return CString{}; + } +} + +CString Label(const ExpressionType* type) { + if (type == nullptr) { + return LR"(N/A)"; + } else { + return std::visit(ccl::meta::Overloads{ + [](const ccl::rslang::Typification& t) { + if (t == ccl::rslang::Typification::Integer()) { + return mfc::LoadSID(IXTRS_TYPE_INTEGRAL); + } else { + return mfc::ToMFC(t.ToString()); + } + }, + [](const ccl::rslang::LogicT& /*t*/) { return mfc::LoadSID(IXTRS_TYPE_BOOLEAN); } + }, *type); + } +} + +CString Label(const ccl::rslang::ValueClass cls) { + using ccl::rslang::ValueClass; + switch (cls) { + default: + case ValueClass::value: return mfc::LoadSID(IXTRS_VC_VALUE); + case ValueClass::props: return mfc::LoadSID(IXTRS_VC_PROPERTY); + case ValueClass::invalid: return mfc::LoadSID(IXTRS_VC_INVALID); + } +} + +} // namespace xtr::info + +#pragma warning( pop ) \ No newline at end of file diff --git a/src/core/Encoder.cpp b/src/core/Encoder.cpp new file mode 100644 index 0000000..66e720c --- /dev/null +++ b/src/core/Encoder.cpp @@ -0,0 +1,128 @@ +#include "stdafx.h" + +#include "xtr/core/Encoder.h" + +#include + +namespace xtr::encode { + +bool IsCstName(wchar_t uc) noexcept { + switch (uc) { + default: return false; + case 'X': case 'C': + case 'S': case 'H': + case 'D': case 'A': + case 'T': + return true; + } +} + +bool IsAlphaNumber(const wchar_t uc) noexcept { + if (IsGreek(uc)) { + return false; + } else if (IsIndex(uc)) { + return true; + } else { + return iswalnum(uc) != 0; + } +} + +void EncodeToUnicode(CString& str) { + CString result{}; + for (auto i = 0; i < str.GetLength(); ++i) { + result.AppendChar(Bulean2ToUnicodeChar(str[i])); + } + str = result; +} + +uint8_t Encode1251To866(uint8_t c) noexcept { + if ((c >= 0x80) && (c <= 0xAF)) { // NOLINT + return static_cast(c + 0x40); // NOLINT + } else if ((c >= 0xE0) && (c <= 0xEF)) { // NOLINT + return static_cast(c + 0x10); // NOLINT + } else if (c == 0xF0) { // NOLINT + return 0xA8; // NOLINT + } else if (c == 0xF1) { // NOLINT + return 0xB8; // NOLINT + } else { + return c; + } +} + +wchar_t Bulean2ToUnicodeChar(wchar_t ac) { + // Note: Преобразуем код Bulean2 в стандартную таблицу Unicode + static const std::unordered_map codeTable = { + { 0x23, US_GREATER_OR_EQ }, + { 0x24, US_LOGIC_EXISTS }, + + { 0x40, US_LESSER_OR_EQ }, + + { 0x80, US_A }, { 0x0402, US_A }, + { 0x81, US_B }, { 0x0403, US_B }, + { 0x82, US_G }, { 0x201A, US_G }, + { 0x83, US_D }, { 0x0453, US_D }, + { 0x84, US_E }, { 0x201E, US_E }, + { 0x85, US_Z }, { 0x2026, US_Z }, + { 0x86, US_H }, { 0x2020, US_H }, + { 0x87, US_V }, { 0x2021, US_V }, + { 0x8A, US_L }, { 0x0409, US_L }, + { 0x8B, US_M }, { 0x2039, US_M }, + { 0x8C, US_N }, { 0x040A, US_N }, + { 0x8D, US_X }, { 0x040C, US_X }, + { 0x8E, US_O }, { 0x040B, US_O }, + { 0x8F, US_P }, { 0x040F, US_P }, + { 0x90, US_R }, { 0x0452, US_R }, + { 0x91, US_S }, { 0x2018, US_S }, + { 0x92, US_T }, { 0x2019, US_T }, + { 0x93, US_Q }, { 0x201C, US_Q }, + { 0x94, US_F }, { 0x201D, US_F }, + { 0x95, US_C }, { 0x2022, US_C }, + { 0x96, US_J }, { 0x2013, US_J }, + { 0x97, US_W }, { 0x2014, US_W }, + { 0x98, US_SET_INTERSECTION }, + { 0x99, US_SET_UNION }, { 0x2122, US_SET_UNION }, + { 0x9A, US_SUBSET }, { 0x0459, US_SUBSET }, + { 0x9B, US_NOTSUBSET }, { 0x203A, US_NOTSUBSET }, + { 0x9C, US_ELEMENT }, { 0x045A, US_ELEMENT }, + { 0x9D, US_NOTELEMENT }, { 0x045C, US_NOTELEMENT }, + { 0x9E, US_SUBSET_OR_EQ }, { 0x045B, US_SUBSET_OR_EQ }, + { 0x9F, US_NOTEQUAL }, { 0x045F, US_NOTEQUAL }, + + { 0xA2, US_LOGIC_FORALL }, { 0x045E, US_LOGIC_FORALL }, + { 0xA3, US_MINUS }, { 0x0408, US_MINUS }, + + { 0xA5, US_DIGIT_SUB0 }, { 0x0490, US_DIGIT_SUB0 }, + { 0xA6, US_DIGIT_SUB1 }, + { 0xA7, US_DIGIT_SUB2 }, + { 0xA8, US_DIGIT_SUB3 }, { 0x0401, US_DIGIT_SUB3 }, + { 0xA9, US_DIGIT_SUB4 }, + { 0xAA, US_DIGIT_SUB5 }, { 0x0404, US_DIGIT_SUB5 }, + { 0xAB, US_DIGIT_SUB6 }, + { 0xAC, US_DIGIT_SUB7 }, + { 0xAD, US_DIGIT_SUB8 }, + { 0xAE, US_DIGIT_SUB9 }, + { 0xAF, US_IDENTITY }, { 0x0407, US_IDENTITY }, + + { 0xB1, US_IMPLICATION }, + { 0xB2, US_LOGIC_EQUAL }, { 0x0406, US_LOGIC_EQUAL }, + { 0xB3, US_LOGIC_NOT }, { 0x0456, US_LOGIC_NOT }, + { 0xB4, US_LOGIC_OR }, { 0x0491, US_LOGIC_OR }, + { 0xB5, US_CARTH }, + + { 0xB7, US_SET_SYMMINUS }, + + { 0xBA, US_INFINITY }, { 0x0454, US_INFINITY }, + { 0xBB, US_EMPTYSET }, + { 0xBC, US_BOOL }, { 0x0458, US_BOOL }, + { 0xBD, US_INTEGERS }, { 0x0405, US_INTEGERS }, + { 0xBE, US_NATURALS }, { 0x0455, US_NATURALS }, + { 0xBF, US_REALS }, { 0x0457, US_REALS } + }; + if (!codeTable.contains(ac)) { + return ac; + } else { + return codeTable.at(ac); + } +} + +} // namespace xtr::encode \ No newline at end of file diff --git a/src/core/PyCore.cpp b/src/core/PyCore.cpp new file mode 100644 index 0000000..06c752c --- /dev/null +++ b/src/core/PyCore.cpp @@ -0,0 +1,193 @@ +#include "stdafx.h" + +#include "xtr/core/PyCore.h" + +#pragma warning( push ) +#pragma warning( disable : 4100 ) +#include "Python.h" +#pragma warning( pop ) + +namespace cxxpython { + +Object Object::FromNew(_object* objectIn) noexcept { + return Object{ objectIn }; +} + +Object Object::FromBorrowed(_object* objectIn) noexcept { + Py_IncRef(objectIn); + return Object{ objectIn }; +} + +Object::~Object() noexcept { + DecreaseRefCount(); +} + +void Object::DecreaseRefCount() noexcept { + if (object != nullptr) { + try { + Py_DecRef(object); + } catch (...) {} + } +} + +Object::Object(const Object& obj2) noexcept { + object = obj2.object; + Py_IncRef(object); +} + +Object& Object::operator=(const Object& obj2) noexcept { + if (this != &obj2) { + DecreaseRefCount(); + object = obj2.object; + Py_IncRef(object); + } + return *this; +} + +Object::Object(Object&& obj2) noexcept { + object = obj2.object; + obj2.object = nullptr; +} + +Object& Object::operator=(Object&& obj2) noexcept { + if (this != &obj2) { + DecreaseRefCount(); + object = obj2.object; + obj2.object = nullptr; + } + return *this; +} + +Object Object::at(int index) const noexcept { + return Object::FromBorrowed(PyTuple_GetItem(object, index)); +} + +std::string ToString(const Object& object) { + Py_ssize_t size{}; + const auto* charsFromPython = PyUnicode_AsUTF8AndSize(object.get(), &size); + if (charsFromPython == nullptr) { + return {}; + } else { + std::string result(charsFromPython, size); + return result; + } +} + +long ToLong(const Object& object) noexcept { + return PyLong_AsLong(object.get()); +} + +bool ToBool(const Object& object) noexcept { + return object.get() == Py_True; +} + +Callable::Callable(_object* object) noexcept + : func{ Object::FromBorrowed(object) } {} + +Object Callable::operator()() const noexcept { + return Object::FromNew(PyObject_CallObject(func.get(), nullptr)); +} + +#pragma warning( push ) +#pragma warning( disable : 26492 26477 26481 ) // ignore warnings for variadic function + +Object Callable::operator()(const char* format, ...) const noexcept { + va_list args; // NOLINT + va_start(args, format); // NOLINT + auto argsObject = Object::FromNew(Py_VaBuildValue(format, args)); + va_end(args); + return Object::FromNew(PyObject_CallObject(func.get(), argsObject.get())); +} + +#pragma warning( pop ) + +PyCore::~PyCore() { + Stop(); +} + +PyCore& PyCore::Instance() { + static PyCore instance{}; + return instance; +} + +bool PyCore::IsRunning() const noexcept { + return isRunning; +} + +bool PyCore::Start(const wchar_t* pyPath) noexcept { + if (IsRunning()) { + return false; + } + + PyConfig config; + PyConfig_InitPythonConfig(&config); + if (pyPath != nullptr) { + PyStatus err = PyConfig_SetString(&config, &config.home, pyPath); + if (PyStatus_Exception(err)) { + PyConfig_Clear(&config); + return false; + } + } + + const PyStatus status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + /*if (PyStatus_IsExit(status)) { + } + Py_ExitStatusException(status);*/ + PyConfig_Clear(&config); + return false; + } + + PyConfig_Clear(&config); + isRunning = true; + return true; +} + +void PyCore::Stop() noexcept { + if (IsRunning()) { + isRunning = false; + modules.clear(); + Py_FinalizeEx(); + } +} + +bool PyCore::LoadModule(const std::string& moduleName, const std::string& pyFileName) { + if (!IsRunning()) { + return false; + } else if (moduleName.empty()) { + return false; + } else if (modules.contains(moduleName)) { + return true; + } else if (auto nameObj = Object::FromNew(PyUnicode_FromString(pyFileName.c_str())); + nameObj == nullptr) { + return false; + } else if (auto moduleObj = Object::FromNew(PyImport_Import(nameObj.get())); + moduleObj == nullptr) { + return false; + } else if (auto dictionaryObj = Object::FromBorrowed(PyModule_GetDict(moduleObj.get())); + dictionaryObj == nullptr) { + return false; + } else { + modules.insert(std::pair(moduleName, Module{ .pyModule = moduleObj, .pyDictionary = std::move(dictionaryObj) })); + return true; + } +} + +Callable PyCore::PyFunction(const std::string& moduleName, const std::string& funcName) const { + if (!IsRunning()) { + return nullptr; + } else if (const auto it = modules.find(moduleName); it == std::end(modules)) { + return nullptr; + } else if (const auto nameObj = Object::FromNew(PyUnicode_FromString(funcName.c_str())); + nameObj == nullptr) { + return nullptr; + } else if (auto* pFunc = PyDict_GetItem(it->second.pyDictionary.get(), nameObj.get()); + PyCallable_Check(pFunc) == 0) { + PyErr_Print(); + return nullptr; + } else { + return Callable(pFunc); + } +} + +} // namespace cxxpython \ No newline at end of file diff --git a/src/core/PyTextProcessor.cpp b/src/core/PyTextProcessor.cpp new file mode 100644 index 0000000..e74113e --- /dev/null +++ b/src/core/PyTextProcessor.cpp @@ -0,0 +1,65 @@ +#include "stdafx.h" + +#include "xtr/core/PyTextProcessor.h" +#include "xtr/core/PyCore.h" + +namespace xtr::core { + +using cxxpython::PyCore; + +void PyTextProcessor::InitModule(const std::string& key) { + moduleKey = key; + isInit = true; +} + +std::string PyTextProcessor::Inflect(const std::string& target, const ccl::lang::Morphology& form) const { + if (!isInit || empty(target)) { + return target; + } + + const auto inflect = PyCore::Instance().PyFunction(moduleKey, "inflect"); + if (inflect == nullptr) { + return target; + } + + const auto value = inflect("(s, s)", target.c_str(), form.ToString().c_str()); + if (value == nullptr) { + return target; + } + return cxxpython::ToString(value); +} + +std::string PyTextProcessor::InflectDependant(const std::string& dependant, const std::string& main) const { + if (!isInit || empty(dependant) || empty(main)) { + return dependant; + } + + const auto inflect_dependant = PyCore::Instance().PyFunction(moduleKey, "inflect_dependant"); + if (inflect_dependant == nullptr) { + return dependant; + } + + const auto value = inflect_dependant("(s, s)", dependant.c_str(), main.c_str()); + if (value == nullptr) { + return dependant; + } + return cxxpython::ToString(value); +} + +bool PyTextProcessor::IsSubstr(const std::string& needle, const std::string& haystack) const { + if (TextProcessor::IsSubstr(needle, haystack)) { + return true; + } else if (!isInit) { + return false; + } else if (const auto find_substr = PyCore::Instance().PyFunction(moduleKey, "find_substr"); + find_substr == nullptr) { + return false; + } else if (const auto value = find_substr("(s, s)", needle.c_str(), haystack.c_str()); + value == nullptr) { + return false; + } else { + return cxxpython::ToLong(value.at(0)) != 0 || cxxpython::ToLong(value.at(1)) != 0; + } +} + +} // namespace xtr::core \ No newline at end of file diff --git a/src/core/SelectableSet.cpp b/src/core/SelectableSet.cpp new file mode 100644 index 0000000..ab8ac4c --- /dev/null +++ b/src/core/SelectableSet.cpp @@ -0,0 +1,23 @@ +#include "stdafx.h" + +#include "xtr/core/SelectableSet.h" + +namespace xtr::core { + +void SelectableSet::SetSelection(const SetOfEntities& newSelection) { + selection = newSelection; +} + +void SelectableSet::ResetSelection() noexcept { + selection.clear(); +} + +BOOL SelectableSet::IsSelected(const EntityUID uid) const { + return selection.contains(uid); +} + +void SelectableSet::Select(const EntityUID uid) { + selection.emplace(uid); +} + +} // namespace xtr::core \ No newline at end of file diff --git a/src/dialog/BasicDlg.cpp b/src/dialog/BasicDlg.cpp new file mode 100644 index 0000000..195dd40 --- /dev/null +++ b/src/dialog/BasicDlg.cpp @@ -0,0 +1,88 @@ +#include "stdafx.h" + +#include "xtr/dialog/BasicDlg.h" + +#include "resource.h" + +#include "xtr/ui/KeyboardHandler.h" + +namespace xtr::dialog { + +EditComment::EditComment(const CString comment, const CString title, CWnd* pParent) + : CDialog(IXTRD_EDIT_COMMENT, pParent), comment{ comment }, title{ title } {} + +BOOL EditComment::OnInitDialog() { + CDialog::OnInitDialog(); + + SetWindowTextW(title); + + textControl.SetAutoURLDetect(); + textControl.InitRE(ui::Keyboard::Layout::RUS); + + // Note: Перезаливаем коммент, чтобы обновить URL'ы + textControl.SetWindowTextW(CString{}); + textControl.SetWindowTextW(comment); + + return TRUE; +} + +void EditComment::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + + ::DDX_Control(pDX, IXTRC_COMMENT_EC, textControl); + ::DDX_Text(pDX, IXTRC_COMMENT_EC, comment); +} + +EditString::EditString(const CString initData, const CString caption, CWnd* pParent) + : CDialog(IXTRD_EDIT_FILENAME, pParent), resultStr{ initData }, m_Caption{ caption } {} + +BOOL EditString::OnInitDialog() { + CDialog::OnInitDialog(); + if (!m_Caption.IsEmpty()) { + SetWindowTextW(m_Caption); + } + return TRUE; +} + +void EditString::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + ::DDX_Text(pDX, IXTRC_FILENAME, resultStr); +} + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(EditHyperlink, CDialog) + ON_BN_CLICKED(IXTRC_BROWSE, &ThisClass::OnBrowse) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +EditHyperlink::EditHyperlink(const ccl::oss::MediaLink& lnk, CWnd* pParent /*= nullptr*/) + : CDialog(IXTRD_EDIT_HYPERLINK, pParent), + address{ mfc::ToMFC(lnk.address) }, subAddr{ mfc::ToMFC(lnk.subAddr) }{} + +BOOL EditHyperlink::OnInitDialog() { + CDialog::OnInitDialog(); + return TRUE; +} + +void EditHyperlink::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + + ::DDX_Text(pDX, IXTRC_ADDRESS, address); + ::DDX_Text(pDX, IXTRC_SUBADDRESS, subAddr); +} + +void EditHyperlink::OnBrowse() { + UpdateData(TRUE); + CFileDialog dialog(TRUE, LR"(*.*)", LR"(*.*)", OFN_HIDEREADONLY | OFN_EXPLORER, + mfc::LoadSID(IXTRS_FILTER_DEFAULT)); + dialog.m_ofn.lpstrTitle = mfc::LoadSID(IXTRS_CAPTION_DEFAULT_FILE); + if (dialog.DoModal() == IDOK) { + address = dialog.GetPathName(); + UpdateData(FALSE); + } +} + +} // namespace xtr::dialog \ No newline at end of file diff --git a/src/dialog/CstDataPage.cpp b/src/dialog/CstDataPage.cpp new file mode 100644 index 0000000..e98431e --- /dev/null +++ b/src/dialog/CstDataPage.cpp @@ -0,0 +1,574 @@ +#include "stdafx.h" + +#include "ccl/rslang/RSGenerator.h" +#include "xtr/dialog/CstDataPage.h" + +#include "resource.h" + +#include "xtr/ExteorOptions.h" +#include "xtr/cclDescriptor.h" +#include "xtr/xtrDesign.h" + +#include "xtr/ui/UIHelper.h" +#include "xtr/ui/HelpHandler.h" +#include "xtr/ui/KeyboardHandler.h" + +#include "xtr/dialog/EditConstituenta.h" + +namespace xtr::dialog { + +using ccl::semantic::ParsingStatus; +using ccl::semantic::CstType; +using ccl::rslang::TokenID; +using ccl::rslang::ValueClass; +using ui::Keyboard; + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(CstDataPage, CPropertyPage) + ON_WM_DESTROY() + + ON_EN_SETFOCUS(IXTRC_NAME, &ThisClass::OnSetfocusName) + ON_EN_KILLFOCUS(IXTRC_EXPRESSION, &ThisClass::OnKillfocusExpression) + ON_EN_CHANGE(IXTRC_EXPRESSION, &ThisClass::OnChangeExpression) + ON_EN_CHANGE(IXTRC_INTERPRETATION, &ThisClass::OnChangeInterpretation) + ON_EN_CHANGE(IXTRC_COMMENT_KS, &ThisClass::OnChangeComment) + ON_EN_CHANGE(IXTRC_NAME, &ThisClass::OnChangeName) + ON_EN_CHANGE(IXTRC_TERM, &ThisClass::OnChangeTerm) + ON_CBN_SELCHANGE(IXTRC_NAME_CB, &ThisClass::OnSelchangeName) + + ON_BN_CLICKED(IXTRC_ALLOW_EDIT, &ThisClass::OnAllowEdit) + ON_BN_CLICKED(IXTRC_PREV, &ThisClass::OnPrev) + ON_BN_CLICKED(IXTRC_NEXT, &ThisClass::OnNext) + ON_BN_CLICKED(IXTRC_INPUT_HELP, &ThisClass::OnHelpInput) + ON_BN_CLICKED(IXTRC_ANALYSE, &ThisClass::OnAnalyse) + ON_BN_CLICKED(IXTRC_CALCULATE, &ThisClass::OnCalculate) + ON_BN_CLICKED(IXTRC_SHOW_SSYNTAX, &ThisClass::OnSimpleSyntax) + + ON_COMMAND_EX(IXTRC_BOOLEAN, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_BOOL, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_PR_S, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_PR_L, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_FILTER, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_CARD, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_DEBOOL, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_RED, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_CARTPROD, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_NEGATION, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_UNION, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_INTERSECT, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_OR, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_BELONG, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_IMPLICATION, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_INEQ, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_NULLSET, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_QUANTEXIST, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_QUANTUNIVERSAL, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_LOGIC_EQUAL, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_EQUAL, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_LOGIC_AND, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_SET_MINUS, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_NOTELEMENT, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_SUBSET, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_NOTSUBSET, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_SUBSET_OR_EQ, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_DOUBLEPAR, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_DOUBLESQR, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_GREATER_OR_EQ, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_LESSER_OR_EQ, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_SET_SYMMINUS, &ThisClass::OnInsertBtn) + + ON_COMMAND_EX(IXTRC_RS_RECURSIVE, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_RS_DECLARATIVE, &ThisClass::OnInsertBtn) + ON_COMMAND_EX(IXTRC_RS_IMPERATIVE, &ThisClass::OnInsertBtn) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +CstDataPage::CstDataPage(EditConstituentaDlg& parent) + : CPropertyPage(IXTRD_CST_EDIT_DATA), parent(parent) {} + +BOOL CstDataPage::OnInitDialog() { + CPropertyPage::OnInitDialog(); + + InitControls(); + InitCstNameList(); + UpdateData(FALSE); + return TRUE; +} + +void CstDataPage::InitControls() { + static constexpr auto PROPERTI_DROPPED_WIDTH = 820U; + + Keyboard::Instance().RegisterIndicator(&languageIndicator); + + expressionCtrl.InitRE(Keyboard::Layout::MATH, TRUE, TRUE); + typificationCtrl.InitRE(Keyboard::Layout::MATH, TRUE, FALSE); + definitionCtrl.InitRE(Keyboard::Layout::RUS, FALSE, TRUE); + termCtrl.InitRE(Keyboard::Layout::RUS, FALSE, TRUE); + + conventionCtrl.SetAutoURLDetect(); + conventionCtrl.InitRE(Keyboard::Layout::RUS); + + logCtrl.SetAutoURLDetect(); + logCtrl.InitRE(); + + namePicker.SetDroppedWidth(PROPERTI_DROPPED_WIDTH); + + cstNameCtrl.SetFont(&XTROptions::App().fontMath); + logCtrl.SetFont(&XTROptions::App().fontTooltip); + definitionCtrl.SetFont(&XTROptions::App().fontText); + termCtrl.SetFont(&XTROptions::App().fontText); + conventionCtrl.SetFont(&XTROptions::App().fontMathComment); + languageIndicator.SetFont(&XTROptions::App().fontTooltip); + namePicker.SetFont(&XTROptions::App().fontText); + + if (!parent.editor->IsModel()) { + GetDlgItem(IXTRC_CALCULATE)->ShowWindow(FALSE); + } +} + +void CstDataPage::DoDataExchange(CDataExchange* pDX) { + CPropertyPage::DoDataExchange(pDX); + + ::DDX_Control(pDX, IXTRC_NAME, cstNameCtrl); + ::DDX_Control(pDX, IXTRC_NAME_CB, namePicker); + ::DDX_Control(pDX, IXTRC_ALLOW_EDIT, allowEditCtrl); + ::DDX_Control(pDX, IXTRC_CALCULATE, evaluateBtn); + ::DDX_Control(pDX, IXTRC_EXPRESSION, expressionCtrl); + ::DDX_Control(pDX, IXTRC_INTERPRETATION, definitionCtrl); + ::DDX_Control(pDX, IXTRC_TERM, termCtrl); + ::DDX_Control(pDX, IXTRC_COMMENT_KS, conventionCtrl); + ::DDX_Control(pDX, IXTRC_TYPIFICATION, typificationCtrl); + ::DDX_Control(pDX, IXTRC_SYNTAX, logCtrl); + ::DDX_Control(pDX, IXTRC_LANGUAGE, languageIndicator); + + const auto& core = parent.editor->Core(); + const auto& cst = core.GetRS(parent.activeUID); + if (!pDX->m_bSaveAndValidate) { + const auto isInherited = parent.editor->IsModel() ? FALSE : parent.editor->Schema().Mods().IsTracking(parent.activeUID); + + LoadDataFrom(parent.activeUID); + + allowEditCtrl.ShowWindow(isInherited); + + expressionCtrl.Init(core, parent.activeUID); + expressionCtrl.SetReadOnly(isInherited); + + termCtrl.Initialize(term, *parent.editor, !XTROptions::Text().editReference, FALSE); + termCtrl.SetReadOnly(!allowEdit); + definitionCtrl.Initialize(definition, *parent.editor, !XTROptions::Text().editReference); + definitionCtrl.SetReadOnly(!allowEdit); + + if (ccl::semantic::IsBaseNotion(cst.type)) { + GetDlgItem(IXTRC_COMMENT_STATIC)->SetWindowTextW(mfc::LoadSID(IXTRS_CONVENTION)); + } else { + GetDlgItem(IXTRC_COMMENT_STATIC)->SetWindowTextW(mfc::LoadSID(IXTRS_COMMENT)); + } + conventionCtrl.SetReadOnly(!allowEdit); + + InitCstNameList(); + } + + auto sellectedName = mfc::ToMFC(cst.alias); + ::DDX_Check(pDX, IXTRC_ALLOW_EDIT, allowEdit); + ::DDX_Text(pDX, IXTRC_EXPRESSION, expression); + ::DDX_Text(pDX, IXTRC_TYPIFICATION, typification); + ::DDX_Text(pDX, IXTRC_COMMENT_KS, convention); + ::DDX_Text(pDX, IXTRC_NAME, cstName); + ::DDX_CBString(pDX, IXTRC_NAME_CB, sellectedName); + + if (!pDX->m_bSaveAndValidate) { + UpdateFormat(); + } else { + SaveDataFor(parent.activeUID); + InitCstNameList(); + } + UpdateStatusBar(); + ClearSyntaxWindow(); +} + +void CstDataPage::LoadDataFrom(const EntityUID target) { + allowEdit = TRUE; + if (!parent.editor->IsModel()) { + if (parent.editor->Schema().Mods().IsTracking(target)) { + allowEdit = parent.editor->Schema().Mods()(target)->allowEdit; + } + } + const auto& rsCst = parent.editor->GetRS(target); + const auto& textCst = parent.editor->GetText(target); + + cstName = mfc::ToMFC(rsCst.alias); + expression = mfc::ToMFC(rsCst.definition); + convention = mfc::ToMFC(rsCst.convention); + + typification = info::Label(parent.editor->GetParse(target).TypePtr()); + parseStatus = parent.editor->GetParse(target).status; + valueStatus = parent.editor->GetParse(target).valueClass; + + definition = mfc::ToMFC(textCst.definition.Raw()); + term = mfc::ToMFC(textCst.term.Text().Raw()); +} + +void CstDataPage::SaveDataFor(const EntityUID uid) { + auto expr = mfc::ToSTL(expressionCtrl.Text()); + // Note: dont use ::DDX_Text value because of line breakes are doubled ('\r\n') + auto stlComment = mfc::ToSTL(conventionCtrl.Text()); + auto definitionRef = ui::TrimText(definitionCtrl.GetRefStr()); + auto termRef = ui::TrimText(termCtrl.GetRefStr()); + + if (!parent.editor->IsModel() && parent.editor->Schema().Mods().IsTracking(uid)) { + parent.editor->EditSchema().Mods()(uid)->allowEdit = allowEdit; + } + parent.editor->SetAliasFor(uid, mfc::ToSTL(cstName)); + parent.editor->SetExpressionFor(uid, expr); + parent.editor->SetConventionFor(uid, stlComment); + parent.editor->SetDefinitionFor(uid, mfc::ToSTL(definitionRef)); + parent.editor->SetTermFor(uid, mfc::ToSTL(termRef)); +} + +BOOL CstDataPage::PreTranslateMessage(MSG* pMsg) { + if (pMsg->message == WM_KEYDOWN) { + if (pMsg->wParam == VK_ESCAPE) { + OnCancel(); + return TRUE; + } else if (pMsg->wParam == VK_F1) { + ui::HelpHandler::RunHelp(parent.editor->IsModel() ? ui::HelpID::editData : ui::HelpID::editCst); + return TRUE; + } + } + return CPropertyPage::PreTranslateMessage(pMsg); +} + +void CstDataPage::OnSetfocusName() { // NOLINT(readability-convert-member-functions-to-static) + Keyboard::Instance().SetLayout(Keyboard::Layout::ENG); +} + +void CstDataPage::OnKillfocusExpression() { + if (GetFocus() == nullptr || + (GetFocus() != GetDlgItem(IXTRC_ANALYSE) && + !GetFocus()->IsKindOf(RUNTIME_CLASS(CButton)))) { + RunAutocheck(); + } +} + +void CstDataPage::OnDestroy() { + Keyboard::Instance().UnregisterIndicator(&languageIndicator); + CPropertyPage::OnDestroy(); +} + +void CstDataPage::OnCancel() { + CPropertyPage::OnCancel(); + EndDialog(IDCANCEL); +} + +BOOL CstDataPage::OnApply() { + if (!CPropertyPage::OnApply()) { + return FALSE; + } else { + if (parent.GetActivePage() == this) { + RunAutocheck(); + UpdateData(FALSE); + } + return TRUE; + } +} + +void CstDataPage::OnOK() { + if (parent.GetActivePage() == this) { + UpdateData(TRUE); + SetModified(FALSE); + } + CPropertyPage::OnOK(); +} + +void CstDataPage::OnSelchangeName() { + const auto index = namePicker.GetCurSel(); + assert(index != mfc::noItems); + + OnApply(); + + CString name{}; + namePicker.GetLBText(index, name); + name = mfc::FirstWordOf(name); + + parent.activeUID = parent.editor->Core().FindAlias(mfc::ToSTL(name)).value(); + UpdateData(FALSE); +} + +void CstDataPage::OnChangeExpression() { + if (expressionCtrl.Text() != expression) { + OnChange(); + UpdateStatus(ParsingStatus::UNKNOWN, ValueClass::invalid); + } +} + +void CstDataPage::OnAllowEdit() { + UpdateData(); + UpdateData(FALSE); +} + +void CstDataPage::OnChange() { + SetModified(); +} + +void CstDataPage::OnChangeInterpretation() { + if (GetFocus() != nullptr && *GetFocus() == definitionCtrl) { + OnChange(); + } +} + +void CstDataPage::OnChangeTerm() { + if (GetFocus() != nullptr && *GetFocus() == termCtrl) { + OnChange(); + } +} + +void CstDataPage::OnChangeComment() { + if (GetFocus() != nullptr && *GetFocus() == conventionCtrl) { + OnChange(); + } +} + +void CstDataPage::OnChangeName() { + if (GetFocus() != nullptr && *GetFocus() == cstNameCtrl) { + OnChange(); + } +} + +void CstDataPage::OnPrev() { + UpdateData(TRUE); + parent.StepPrev(); + UpdateData(FALSE); +} + +void CstDataPage::OnNext() { + UpdateData(TRUE); + parent.StepNext(); + UpdateData(FALSE); +} + +void CstDataPage::OnHelpInput() { // NOLINT(readability-convert-member-functions-to-static) + ui::HelpHandler::RunHelp(ui::HelpID::rslanguage); +} + +BOOL CstDataPage::OnInsertBtn(uint32_t command) { + switch(command) { + case IXTRC_EQUAL: expressionCtrl.InputToken(TokenID::EQUAL); break; + case IXTRC_INEQ: expressionCtrl.InputToken(TokenID::NOTEQUAL); break; + case IXTRC_LESSER_OR_EQ: expressionCtrl.InputToken(TokenID::LESSER_OR_EQ); break; + case IXTRC_GREATER_OR_EQ: expressionCtrl.InputToken(TokenID::GREATER_OR_EQ); break; + + case IXTRC_QUANTUNIVERSAL: expressionCtrl.InputToken(TokenID::FORALL); break; + case IXTRC_QUANTEXIST: expressionCtrl.InputToken(TokenID::EXISTS); break; + case IXTRC_LOGIC_AND: expressionCtrl.InputToken(TokenID::AND); break; + case IXTRC_OR: expressionCtrl.InputToken(TokenID::OR); break; + case IXTRC_NEGATION: expressionCtrl.InputToken(TokenID::NOT); break; + case IXTRC_IMPLICATION: expressionCtrl.InputToken(TokenID::IMPLICATION);break; + case IXTRC_LOGIC_EQUAL: expressionCtrl.InputToken(TokenID::EQUIVALENT); break; + + case IXTRC_NULLSET: expressionCtrl.InputToken(TokenID::LIT_EMPTYSET); break; + case IXTRC_UNION: expressionCtrl.InputToken(TokenID::UNION); break; + case IXTRC_SET_MINUS: expressionCtrl.InputToken(TokenID::SET_MINUS); break; + case IXTRC_SET_SYMMINUS: expressionCtrl.InputToken(TokenID::SYMMINUS); break; + case IXTRC_INTERSECT: expressionCtrl.InputToken(TokenID::INTERSECTION); break; + case IXTRC_BELONG: expressionCtrl.InputToken(TokenID::IN); break; + case IXTRC_NOTELEMENT: expressionCtrl.InputToken(TokenID::NOTIN); break; + case IXTRC_SUBSET: expressionCtrl.InputToken(TokenID::SUBSET); break; + case IXTRC_NOTSUBSET: expressionCtrl.InputToken(TokenID::NOTSUBSET); break; + case IXTRC_SUBSET_OR_EQ: expressionCtrl.InputToken(TokenID::SUBSET_OR_EQ); break; + + case IXTRC_BOOLEAN: expressionCtrl.InputToken(TokenID::BOOLEAN); break; + case IXTRC_PR_S: expressionCtrl.InputToken(TokenID::SMALLPR); break; + case IXTRC_PR_L: expressionCtrl.InputToken(TokenID::BIGPR); break; + case IXTRC_FILTER: expressionCtrl.InputToken(TokenID::FILTER); break; + case IXTRC_CARD: expressionCtrl.InputToken(TokenID::CARD); break; + case IXTRC_CARTPROD: expressionCtrl.InputToken(TokenID::DECART); break; + + case IXTRC_BOOL: expressionCtrl.InputToken(TokenID::BOOL); break; + case IXTRC_DEBOOL: expressionCtrl.InputToken(TokenID::DEBOOL); break; + case IXTRC_RED: expressionCtrl.InputToken(TokenID::REDUCE); break; + case IXTRC_RS_DECLARATIVE: expressionCtrl.InputToken(TokenID::DECLARATIVE); break; + case IXTRC_RS_RECURSIVE: expressionCtrl.InputToken(TokenID::RECURSIVE); break; + case IXTRC_RS_IMPERATIVE: expressionCtrl.InputToken(TokenID::IMPERATIVE); break; + + case IXTRC_DOUBLEPAR: expressionCtrl.InputParenthesis(); break; + case IXTRC_DOUBLESQR: expressionCtrl.InputBrackets(); break; + } + return TRUE; +} + +void CstDataPage::OnAnalyse() { + auto [str, basePos] = GetAnalyseExpr(); + auto analyser = parent.editor->Core().RSLang().MakeAuditor(); + const ccl::rslang::ExpressionType* type{ nullptr }; + const auto typeOK = analyser->CheckType(str, ccl::rslang::Syntax::MATH); + if (typeOK) { + type = &analyser->GetType(); + } + + const auto rstype = parent.editor->GetRS(parent.activeUID).type; + const auto typeConsistent = typeOK + && (!ccl::semantic::IsBaseSet(rstype) || expressionCtrl.Text().IsEmpty()) + && ccl::semantic::Schema::CheckTypeConstistency(analyser->GetType(), rstype); + if (!typeConsistent) { + UpdateStatus(ParsingStatus::INCORRECT, ValueClass::invalid); + } else { + if (!analyser->CheckValue()) { + UpdateStatus(ParsingStatus::VERIFIED, ValueClass::invalid); + } else { + UpdateStatus(ParsingStatus::VERIFIED, analyser->GetValueClass()); + } + } + + if (!empty(analyser->Errors().All())) { + auto errorPosition = std::max(analyser->Errors().FirstErrorPos() - basePos, 0L); + auto* re = reinterpret_cast(GetDlgItem(IXTRC_EXPRESSION)); + re->SetFocus(); + re->SetSel(errorPosition, errorPosition); + } + + typificationCtrl.SetWindowTextW(info::Label(type)); + auto log = info::DescriptionOf(*analyser, XTROptions::ParseRSL().showAST); + if (typeOK && !typeConsistent) { + log = mfc::LoadSID(IXTRS_TYPE_INCONSISTENT) + log; + } + logCtrl.SetWindowTextW(log); +} + +void CstDataPage::OnCalculate() { + if (ccl::semantic::IsBaseNotion(parent.editor->GetRS(parent.activeUID).type)) { + return; + } + if (parseStatus != ParsingStatus::VERIFIED) { + OnAnalyse(); + return; + } + if (!OnApply()) { + return; + } + BeginWaitCursor(); + + auto[str, basePos] = GetAnalyseExpr(); + ccl::rslang::Interpreter calculator{ + parent.editor->Core().RSLang(), + parent.editor->Core().RSLang().ASTContext(), + parent.editor->Model().Calculations().Context() + }; + const auto calcResult = calculator.Evaluate(str, ccl::rslang::Syntax::MATH); + if (!calcResult.has_value()) { + auto errorPosition = std::max(calculator.Errors().FirstErrorPos() - basePos, 0L); + auto* re = reinterpret_cast(GetDlgItem(IXTRC_EXPRESSION)); + re->SetFocus(); + re->SetSel(errorPosition, errorPosition); + } + + parent.editor->EditModel().Calculations().Calculate(parent.activeUID); + + EndWaitCursor(); + + UpdateData(FALSE); + logCtrl.SetWindowTextW(info::DescriptionOf(calculator, calcResult, XTROptions::ParseRSL().showAST)); +} + +void CstDataPage::OnSimpleSyntax() { + auto [expr, basePos] = GetAnalyseExpr(); + const auto asciiExpr = ccl::rslang::ConvertTo(expr, ccl::rslang::Syntax::ASCII); + logCtrl.SetWindowTextW(mfc::ToMFC(asciiExpr)); +} + +void CstDataPage::SetModified(BOOL bChanged) { + isModified = bChanged; + CPropertyPage::SetModified(bChanged); +} + +BOOL CstDataPage::IsModified() const noexcept { + return isModified; +} + +std::tuple CstDataPage::GetAnalyseExpr() const { + const auto& cst = parent.editor->GetRS(parent.activeUID); + const auto expr = mfc::ToSTL(expressionCtrl.Text()); + const auto fullExpr = ccl::rslang::Generator::GlobalDefinition(cst.alias, expr, + cst.type == CstType::structured); + return { fullExpr, static_cast(ssize(fullExpr) - ssize(expr)) }; +} + +void CstDataPage::UpdateStatus(const ParsingStatus status, const ValueClass vclass) { + parseStatus = status; + valueStatus = vclass; + UpdateStatusBar(); +} + +void CstDataPage::UpdateStatusBar() { + auto color = design::clrBlack; + const auto isCalculable = ccl::semantic::IsCalculable(parent.editor->GetRS(parent.activeUID).type); + evaluateBtn.EnableWindow(isCalculable && parseStatus == ParsingStatus::VERIFIED); + if (parseStatus != ParsingStatus::VERIFIED) { + color = design::Color(parseStatus); + } else if (!isCalculable || !parent.editor->IsModel()) { + color = design::Color(valueStatus); + } else if (isModified) { + color = design::clrYellow; + } else { + color = design::Color(parent.editor->Model().Calculations()(parent.activeUID)); + } + + auto* statusRE = reinterpret_cast(GetDlgItem(IXTRC_EXP_STATUS)); + statusRE->SetBackgroundColor(FALSE, color); +} + +void CstDataPage::ClearSyntaxWindow() { + logCtrl.SetWindowTextW({}); +} + +void CstDataPage::RunAutocheck() { + if (parseStatus != ParsingStatus::VERIFIED && XTROptions::ParseRSL().autoCheck) { + Analyse(); + } +} + +void CstDataPage::UpdateFormat() { + expressionCtrl.UpdateFormat(); + typificationCtrl.UpdateFormat(); + definitionCtrl.UpdateFormat(); + termCtrl.UpdateFormat(); +} + +void CstDataPage::InitCstNameList() { + namePicker.SetRedraw(FALSE); + + const auto sel = namePicker.GetCurSel(); + namePicker.ResetContent(); + + for (const auto uid : parent.editor->List()) { + const auto& cst = parent.editor->GetText(uid); + auto str = mfc::ToMFC(cst.alias); + str += LR"( - )"; + if (!std::empty(cst.term.Nominal())) { + str += mfc::ToMFC(cst.term.Nominal()); + } else { + str += mfc::ToMFC(cst.definition.Str()); + } + str.Replace(L"\n", L" "); + namePicker.AddString(str); + } + namePicker.SetCurSel(sel); + namePicker.SetRedraw(TRUE); +} + +void CstDataPage::Analyse() { + auto[str, basePos] = GetAnalyseExpr(); + auto analyser = parent.editor->Core().RSLang().MakeAuditor(); + if (!analyser->CheckType(str, ccl::rslang::Syntax::MATH)) { + UpdateStatus(ParsingStatus::INCORRECT, ValueClass::invalid); + } else if (!analyser->CheckValue()) { + UpdateStatus(ParsingStatus::VERIFIED, ValueClass::invalid); + } else { + UpdateStatus(ParsingStatus::VERIFIED, analyser->GetValueClass()); + } + logCtrl.SetWindowTextW(CString{}); +} + +} // namespace xtr::dialog \ No newline at end of file diff --git a/src/dialog/CstRenameDialog.cpp b/src/dialog/CstRenameDialog.cpp new file mode 100644 index 0000000..4fccbb7 --- /dev/null +++ b/src/dialog/CstRenameDialog.cpp @@ -0,0 +1,57 @@ +#include "stdafx.h" + +#include "xtr/dialog/CstRenameDialog.h" + +#include "resource.h" + +namespace xtr::dialog { + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(CstRename, CDialog) + ON_CBN_SELCHANGE(IXTRC_NAME_CB, &ThisClass::OnCbnSelchangeNameCb) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +CstRename::CstRename(const ccl::semantic::RSCore& core, const EntityUID target, CWnd* pParent) + : CDialog(IXTRD_CST_RENAME, pParent), target{ target }, oldName{ mfc::ToMFC(core.GetRS(target).alias) }, core{ core } {} + +BOOL CstRename::OnInitDialog() { + CDialog::OnInitDialog(); + + InitCstNameList(); + UpdateData(FALSE); + return TRUE; +} + +void CstRename::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + + ::DDX_Control(pDX, IXTRC_NAME_CB, nameCtrl); + + ::DDX_Text(pDX, IXTRC_NAME, newName); + ::DDX_CBString(pDX, IXTRC_NAME_CB, oldName); + ::DDX_Check(pDX, IXTRC_CHANGE_EXPR, doUpdateExpr); +} + +void CstRename::OnCbnSelchangeNameCb() { + UpdateData(TRUE); + newName = oldName; + UpdateData(FALSE); +} + +void CstRename::InitCstNameList() { + auto sel = nameCtrl.GetCurSel(); + if (sel == CB_ERR) { + sel = 0; + } + nameCtrl.ResetContent(); + for (const auto uid : core.List()) { + nameCtrl.AddString(mfc::ToMFC(core.GetRS(uid).alias)); + } + nameCtrl.SetCurSel(sel); +} + +} // namespace xtr::dialog \ No newline at end of file diff --git a/src/dialog/EditConstituenta.cpp b/src/dialog/EditConstituenta.cpp new file mode 100644 index 0000000..db215cf --- /dev/null +++ b/src/dialog/EditConstituenta.cpp @@ -0,0 +1,178 @@ +#include "stdafx.h" + +#include "xtr/dialog/EditConstituenta.h" + +#include "resource.h" + +#include "xtr/Exteor.h" + +#include "xtr/ui/UIHelper.h" + +namespace xtr::dialog { + +using ui::Keyboard; + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(EditConstituentaDlg, CPropertySheet) + ON_WM_INITMENUPOPUP() + + ON_COMMAND_EX(IXTRC_INSERT_BASE_SET, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_CONST_SET, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_RS, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_AXIOM, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_TERM, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_THEOREMA, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_FUNCTION, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_PREDICATE, &ThisClass::OnInsertCst) + + XTR_COMMAND_UPD(IXTRC_AUTOCHECK) + XTR_COMMAND_UPD(IXTRC_EDITREF) + XTR_COMMAND_UPD(IXTRC_RSNAVIGATOR) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +EditConstituentaDlg::EditConstituentaDlg(doc::RSFacade& editor, const EntityUID activeUID, CWnd* pParentWnd) + : CPropertySheet(IXTRS_EDITING_CST, pParentWnd), activeUID{ activeUID }, editor{ &editor } { + m_CstPage = std::make_unique(*this); + m_ModelPage = std::make_unique(*this); + AddPage(m_CstPage.get()); + if (editor.IsModel()) { + AddPage(m_ModelPage.get()); + } +} + +EditConstituentaDlg::~EditConstituentaDlg() = default; + +BOOL EditConstituentaDlg::OnInitDialog() { + CPropertySheet::OnInitDialog(); + + CreateMenu(); + FixWindowSize(); + return TRUE; +} + +void EditConstituentaDlg::CreateMenu() { + m_Menu = std::make_unique(); + m_Menu->LoadMenuW(IXTRAD_MENU_CST); + SetMenu(m_Menu.get()); +} + +void EditConstituentaDlg::FixWindowSize() { + auto rect = ui::WindowRect(*this); + rect.bottom += GetSystemMetrics(SM_CYMENU); + MoveWindow(rect); +} + +void EditConstituentaDlg::StepNext() { + auto iter = editor->List().Find(activeUID); + assert(iter != std::end(editor->List())); + + ++iter; + if (iter != std::end(editor->List())) { + activeUID = *iter; + } +} + +void EditConstituentaDlg::StepPrev() { + auto iter = editor->List().Find(activeUID); + assert(iter != std::end(editor->List())); + + if (iter != std::begin(editor->List())) { + --iter; + activeUID = *iter; + } +} + +BOOL EditConstituentaDlg::PreTranslateMessage(MSG* pMsg) { + if (pMsg->message == WM_KEYDOWN) { + const auto key = pMsg->wParam; + if (IsControlAndSPressed(key)) { + if (!GetActivePage()->OnApply()) { + editor->Document().DoFileSave(); + } + return TRUE; + } + if (IsControlAndEnterPressed(key)) { + GetActivePage()->OnOK(); + EndDialog(IDOK); + return TRUE; + } + } + return CPropertySheet::PreTranslateMessage(pMsg); +} + +BOOL EditConstituentaDlg::IsControlAndSPressed(const WPARAM& key) noexcept { + return key == 'S' && + Keyboard::IsPressed(VK_CONTROL) && + !Keyboard::IsPressed(VK_SHIFT); +} + +BOOL EditConstituentaDlg::IsControlAndEnterPressed(const WPARAM& key) noexcept { + return key == VK_RETURN && + Keyboard::IsPressed(VK_CONTROL) && + !Keyboard::IsPressed(VK_SHIFT); +} + +void EditConstituentaDlg::OnInitMenuPopup(CMenu* pMenu, uint32_t /*nIndex*/, BOOL bSysMenu) { + if (!bSysMenu) { + UpdateMenuState(*pMenu); + } +} + +void EditConstituentaDlg::UpdateMenuState(CMenu& menu) { + static constexpr auto VALID_MENU_LIMIT = 0xF000; + CCmdUI state{}; + state.m_pMenu = &menu; + state.m_nIndexMax = menu.GetMenuItemCount(); + for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax; ++state.m_nIndex) { + state.m_nID = menu.GetMenuItemID(state.m_nIndex); + if (state.m_nID != 0) { + state.m_pSubMenu = nullptr; + state.DoUpdate(this, state.m_nID < VALID_MENU_LIMIT); + } + } +} + +#pragma warning( push ) +#pragma warning( disable : 26440) // Note: ignore noexcept suggestion for macro used MFC function + +BOOL EditConstituentaDlg::OnCommandRun(const uint32_t command) { // NOLINT(readability-convert-member-functions-to-static) + switch (command) { + default: return TRUE; + case IXTRC_AUTOCHECK: { + XTROptions::ParseRSL().autoCheck = !XTROptions::ParseRSL().autoCheck; + break; + } + case IXTRC_EDITREF: { + XTROptions::Text().editReference = !XTROptions::Text().editReference; + break; + } + case IXTRC_RSNAVIGATOR: { + XTROptions::ParseRSL().enableNavigator = !XTROptions::ParseRSL().enableNavigator; + break; + } + } + return TRUE; +} + +#pragma warning( pop ) + +BOOL EditConstituentaDlg::OnInsertCst(const uint32_t /*command*/) { + UpdateData(); + return FALSE; +} + +void EditConstituentaDlg::OnUpdateCommandUI(CCmdUI* pCmdUI) { // NOLINT(readability-convert-member-functions-to-static) + pCmdUI->Enable(); + switch(pCmdUI->m_nID) { + default: break; + case IXTRC_AUTOCHECK: pCmdUI->SetCheck(XTROptions::ParseRSL().autoCheck); break; + case IXTRC_EDITREF: pCmdUI->SetCheck(XTROptions::Text().editReference); break; + case IXTRC_RSNAVIGATOR: pCmdUI->SetCheck(XTROptions::ParseRSL().enableNavigator); break; + } +} + +} // namespace xtr::dialog \ No newline at end of file diff --git a/src/dialog/ExportCstGraphDlg.cpp b/src/dialog/ExportCstGraphDlg.cpp new file mode 100644 index 0000000..00bee8d --- /dev/null +++ b/src/dialog/ExportCstGraphDlg.cpp @@ -0,0 +1,55 @@ +#include "stdafx.h" + +#include "xtr/dialog/ExportCstGraphDlg.h" + +#include "resource.h" + +namespace xtr::dialog { + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(ExportCstGraphDlg, CDialog) // NOLINT + +END_MESSAGE_MAP() + +#pragma warning( pop ) + +ExportCstGraphDlg::ExportCstGraphDlg(CWnd* pParent) + : CDialog(IXTRD_EXPORT_CSTGRAPH, pParent) {} + +void ExportCstGraphDlg::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + + int32_t linkType{}; + if (!pDX->m_bSaveAndValidate) { + linkType = GetLinkType(); + } + + ::DDX_Radio(pDX, IXTRC_FORMULA, linkType); + ::DDX_Check(pDX, IXTRC_TRIPLET_CB, options.triplets); + ::DDX_Check(pDX, IXTRC_EXPORT_CSV_CB, exportCSV); + + if (pDX->m_bSaveAndValidate) { + SetLinkType(linkType); + exportType = exportCSV ? FileType::csv : FileType::txt; + } +} + +int32_t ExportCstGraphDlg::GetLinkType() const noexcept { // NOLINT(bugprone-exception-escape) + if (!options.linkage.has_value()) { + return static_cast(io::LinkType::lexTerm) + 1; + } else { + return static_cast(options.linkage.value()); + } +} + +void ExportCstGraphDlg::SetLinkType(const int32_t type) noexcept { + if (type > static_cast(io::LinkType::lexTerm)) { + options.linkage = std::nullopt; + } else { + options.linkage = static_cast(type); + } +} + +} // namespace xtr::dialog \ No newline at end of file diff --git a/src/dialog/ExportModel.cpp b/src/dialog/ExportModel.cpp new file mode 100644 index 0000000..f3eecec --- /dev/null +++ b/src/dialog/ExportModel.cpp @@ -0,0 +1,34 @@ +#include "stdafx.h" + +#include "xtr/dialog/ExportModel.h" + +#include "resource.h" + +namespace xtr::dialog { + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(ExportModel, CDialog) // NOLINT(clang-diagnostic-unused-local-typedef) + +END_MESSAGE_MAP() + +#pragma warning( pop ) + +ExportModel::ExportModel(CWnd* pParent) + : CDialog(IXTRD_EXPORT_MODEL, pParent) {} + +void ExportModel::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + + ::DDX_Radio (pDX, IXTRC_FILE_XLSX, typeRadio); + + if (pDX->m_bSaveAndValidate) { + switch (typeRadio) { + default: exportType = FileType::xlsx; break; + case 1: exportType = FileType::json; break; + } + } +} + +} // namespace xtr::dialog \ No newline at end of file diff --git a/src/dialog/ExportSchema.cpp b/src/dialog/ExportSchema.cpp new file mode 100644 index 0000000..4e6a3b5 --- /dev/null +++ b/src/dialog/ExportSchema.cpp @@ -0,0 +1,46 @@ +#include "stdafx.h" + +#include "xtr/dialog/ExportSchema.h" + +#include "resource.h" + +#include "xtr/ExteorOptions.h" + +namespace xtr::dialog { + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(ExportSchema, CDialog) // NOLINT + +END_MESSAGE_MAP() + +#pragma warning( pop ) + +ExportSchema::ExportSchema(CWnd* pParent) + : CDialog(IXTRD_EXPORT_SCHEMA, pParent), options{ XTROptions::RS().exportOptions } {} + +ExportSchema::~ExportSchema() { + XTROptions::RS().exportOptions = options; +} + +void ExportSchema::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + + ::DDX_Radio (pDX, IXTRC_FILE_DOCX, typeRadio); + ::DDX_Check(pDX, IXTRC_CBTYPIFICATION, options.bTyping); + ::DDX_Check(pDX, IXTRC_CBCOMMENT, options.bComment); + ::DDX_Check(pDX, IXTRC_CBTERMIN, options.bTerm); + ::DDX_Check(pDX, IXTRC_CBFORMEXPR, options.bRSDef); + ::DDX_Check(pDX, IXTRC_CBINTERPRET, options.bTextDef); + + if (pDX->m_bSaveAndValidate) { + switch (typeRadio) { + default: exportType = FileType::docx; break; + case 1: exportType = FileType::csv; break; + case 2: exportType = FileType::json; break; + } + } +} + +} // namespace xtr::dialog \ No newline at end of file diff --git a/src/dialog/Function2Term.cpp b/src/dialog/Function2Term.cpp new file mode 100644 index 0000000..aa5c238 --- /dev/null +++ b/src/dialog/Function2Term.cpp @@ -0,0 +1,309 @@ +#include "stdafx.h" + +#include "xtr/dialog/Function2Term.h" + +#include "resource.h" + +#include "xtr/ExteorOptions.h" +#include "xtr/cclDescriptor.h" + +#include "xtr/ui/HelpHandler.h" +#include "xtr/ui/KeyboardHandler.h" +#include "xtr/ui/UIHelper.h" + +#include "ccl/rslang/RSGenerator.h" +#include "ccl/semantic/CstFilters.hpp" + +namespace xtr::dialog { + +using ui::Keyboard; +using ccl::semantic::CstType; +using ccl::rslang::Generator; + +struct Func2Term::ArgsHeader : ui::Header { + enum Columns : uint8_t { + POS_NAME = 0, + POS_VAL, + POS_TYPE, + count + }; + + static constexpr auto widthName = 50; + static constexpr auto widthTypification = 190; + + ArgsHeader() { + AddColumn({ IXTRS_HEADER_ARGUMENT, Alignment::left, widthName }); + AddColumn({ IXTRS_HEADER_VALUE, Alignment::left, widthName }); + AddColumn({ IXTRS_HEADER_TYPE, Alignment::left, widthTypification }); + } +}; + +struct Func2Term::ValuesHeader : ui::Header { + enum Columns : uint8_t { + POS_VAL = 0, + POS_TERM, + count + }; + + static constexpr auto widthName = 50; + static constexpr auto widthTerm = 290; + + ValuesHeader() { + AddColumn({ IXTRS_HEADER_VALUE, Alignment::left, widthName }); + AddColumn({ IXTRS_HEADER_TERM, Alignment::left, widthTerm }); + } +}; + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(Func2Term, CDialog) + ON_CBN_SELCHANGE(IXTRC_FUNC_CB, &ThisClass::OnChangeFunction) + ON_BN_CLICKED(IXTRC_UPDATE_EXP, &ThisClass::OnBnClickedUpdateExp) + ON_BN_CLICKED(IXTRC_LEFT, &ThisClass::OnBnClickedLeft) + ON_BN_CLICKED(IXTRC_APPLY, &ThisClass::OnBnClickedApply) + + ON_NOTIFY(NM_DBLCLK, IXTRC_ARG_LIST, &ThisClass::OnDblClickArgument) + ON_NOTIFY(LVN_ITEMCHANGED, IXTRC_GLOBAL_LIST, &ThisClass::OnSelectArg) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +Func2Term::Func2Term(doc::RSFacade& editor, const EntityUID startID, CWnd* pParent) + : CDialog(IXTRD_GENERATE_TERM, pParent), editor{ editor }, activeUID{ startID } { + doInline = XTROptions::RS().inlineFunctionOnGenerate; + if (const auto& cst = editor.GetRS(activeUID); ccl::semantic::IsCallable(cst.type)) { + activeName = mfc::ToMFC(cst.alias); + inputExpr = mfc::ToMFC(cst.definition); + } +} + +Func2Term::~Func2Term() { + XTROptions::RS().inlineFunctionOnGenerate = doInline; +} + +BOOL Func2Term::OnInitDialog() { + CDialog::OnInitDialog(); + + InitControls(); + InitCstNameList(); + InitHeaders(); + + UpdateData(FALSE); + return TRUE; +} + +void Func2Term::InitControls() { + inputCtrl.InitRE(Keyboard::Layout::ENG, TRUE, TRUE); + expressionCtrl.InitRE(Keyboard::Layout::MATH, TRUE, TRUE); + definitionCtrl.InitRE(Keyboard::Layout::RUS); + definitionCtrl.SetFont(&XTROptions::App().fontText); +} + +void Func2Term::InitCstNameList() { + const auto selection = namesCB.GetCurSel(); + namesCB.ResetContent(); + const auto callables = ccl::semantic::FilterCst(editor.Core(), + [&editor = this->editor](const auto uid) { return ccl::semantic::IsCallable(editor.GetRS(uid).type); }); + for (const auto uid : callables) { + namesCB.AddString(mfc::ToMFC(editor.GetRS(uid).alias)); + } + namesCB.SetCurSel(selection); +} + +void Func2Term::InitHeaders() { + static const ArgsHeader globalsHead{}; + static const ValuesHeader argsHead{}; + + ui::InitHeaderFor(argsCtrl, globalsHead); + ui::InitHeaderFor(valuesCtrl, argsHead); +} + +void Func2Term::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + + ::DDX_Control(pDX, IXTRC_FUNC_CB, namesCB); + ::DDX_Control(pDX, IXTRC_EXPR_INPUT, inputCtrl); + ::DDX_Control(pDX, IXTRC_EXPR_OUTPUT, expressionCtrl); + ::DDX_Control(pDX, IXTRC_INTER, definitionCtrl); + ::DDX_Control(pDX, IXTRC_GLOBAL_LIST, argsCtrl); + ::DDX_Control(pDX, IXTRC_ARG_LIST, valuesCtrl); + + ::DDX_Text(pDX, IXTRC_EXPR_INPUT, inputExpr); + ::DDX_Text(pDX, IXTRC_EXPR_OUTPUT, expression); + ::DDX_Text(pDX, IXTRC_INTER, textRef); + ::DDX_CBString(pDX, IXTRC_FUNC_CB, activeName); + ::DDX_Check(pDX, IXTRC_FULL_EXPR, doInline); + + if (pDX->m_bSaveAndValidate) { + activeUID = editor.Core().FindAlias(mfc::ToSTL(activeName)).value(); + } else { + UpdateUI(); + } +} + +BOOL Func2Term::PreTranslateMessage(MSG* pMsg) { + if (pMsg->message == WM_KEYDOWN) { + if (pMsg->wParam == VK_F1) { + ui::HelpHandler::RunHelp(ui::HelpID::generateCst); + return TRUE; + } + } + return CDialog::PreTranslateMessage(pMsg); +} + +void Func2Term::OnChangeFunction() { + UpdateData(TRUE); + inputExpr = mfc::ToMFC(editor.GetRS(activeUID).definition); + UpdateData(FALSE); +} + +void Func2Term::OnDblClickArgument(NMHDR* /*pNMHDR*/, LRESULT* pResult) { + OnBnClickedLeft(); + *pResult = TRUE; +} + +void Func2Term::OnSelectArg(NMHDR* pNMHDR, LRESULT* pResult) { + const auto* pNMListView = reinterpret_cast(pNMHDR); + if ((pNMListView->uChanged & LVIF_STATE) && (pNMListView->uNewState & LVNI_SELECTED)) { + UpdateValueList(); + } + *pResult = TRUE; +} + +void Func2Term::OnBnClickedUpdateExp() { + UpdateData(TRUE); + + std::vector args{}; + for (auto i = 0; i < argsCtrl.GetItemCount(); ++i) { + if (const auto name = argsCtrl.GetItemText(i, ArgsHeader::POS_VAL); !name.IsEmpty()) { + args.emplace_back(mfc::ToSTL(name)); + } else { + ::AfxMessageBox(IXTRE_NO_VAL, MB_ICONEXCLAMATION); + return; + } + } + + if (doInline) { + const Generator generator{ editor.Core().RSLang() }; + expression = mfc::ToMFC(generator.TermFromFunction(mfc::ToSTL(activeName), + editor.GetRS(activeUID).definition, + args)); + } else { + expression = mfc::ToMFC(Generator::CreateCall(mfc::ToSTL(activeName), args)); + } + expressionCtrl.SetWindowTextW(expression); +} + +void Func2Term::OnOK() { + if (AddTerm().has_value()) { + CDialog::OnOK(); + } +} + +void Func2Term::OnBnClickedApply() { + if (const auto uid = AddTerm(); uid.has_value()) { + ::AfxMessageBox(mfc::FormatSID(IXTRS_TERM_CREATE_SUCCESS, + mfc::ToMFC(editor.GetRS(uid.value()).alias).GetString()), MB_OK | MB_ICONINFORMATION); + } +} + +void Func2Term::OnBnClickedLeft() { + const auto destLine = argsCtrl.GetSelectedIndex(); + const auto sourceLine = valuesCtrl.GetSelectedIndex(); + if (destLine != mfc::noItems && sourceLine != mfc::noItems) { + auto name = valuesCtrl.GetItemText(sourceLine, ValuesHeader::POS_VAL); + argsCtrl.SetItemText(destLine, ArgsHeader::POS_VAL, name); + } +} + +void Func2Term::UpdateValueList() { + valuesCtrl.DeleteAllItems(); + const auto selected = argsCtrl.GetSelectedIndex(); + if (selected == mfc::noItems) { + return; + } + const auto curArg = argsCtrl.GetItemText(selected, ArgsHeader::POS_NAME); + const auto& args = editor.GetParse(activeUID).arguments; + if (args.has_value()) { + const auto argName = mfc::ToSTL(curArg); + for (const auto& typeID : args.value()) { + if (typeID.name == argName) { + const auto cstList = ccl::semantic::FilterCst(editor.Core(), ccl::rslang::ExpressionType{ typeID.type }); + if (std::empty(cstList)) { + return; + } + auto line = 0; + for (const auto uid : cstList) { + if (const auto cst = editor.GetRS(uid); !ccl::semantic::IsCallable(cst.type)) { + valuesCtrl.InsertItem(line, mfc::ToMFC(cst.alias)); + valuesCtrl.SetItemText(line, 1, mfc::ToMFC(editor.GetText(uid).term.Nominal())); + ++line; + } + } + break; + } + } + } + const auto curVal = argsCtrl.GetItemText(selected, ArgsHeader::POS_VAL); + if (!curVal.IsEmpty()) { + LVFINDINFO info{}; + info.flags = LVFI_STRING; + info.psz = curVal; + + if (const auto findItem = valuesCtrl.FindItem(&info); findItem != mfc::noItems) { + valuesCtrl.SetItemState(mfc::noItems, 0, LVIS_SELECTED | LVIS_FOCUSED); + valuesCtrl.SetItemState(findItem, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); + valuesCtrl.EnsureVisible(findItem, FALSE); + } + } +} + +std::optional Func2Term::AddTerm() { + UpdateData(TRUE); + + if (expression.IsEmpty()) { + ::AfxMessageBox(IXTRE_FUNC2TERM, MB_OK | MB_ICONEXCLAMATION); + expressionCtrl.SetActiveWindow(); + return std::nullopt; + } else { + const auto convention = mfc::ToSTL(mfc::FormatSID(IXTRS_TERM_FROM_TERMFUNC, activeName.GetString())); + const auto uid = editor.Emplace(CstType::term, mfc::ToSTL(expressionCtrl.Text())); + editor.SetDefinitionFor(uid, mfc::ToSTL(definitionCtrl.Text())); + editor.SetConventionFor(uid, convention); + addedCst.emplace_back(uid); + + expression.Empty(); + textRef.Empty(); + UpdateData(FALSE); + + return uid; + } +} + +void Func2Term::UpdateUI() { + inputCtrl.Init(editor.Core(), activeUID); + Clear(); + InputArgs(); + inputCtrl.UpdateFormat(); +} + +void Func2Term::Clear() { + argsCtrl.DeleteAllItems(); + valuesCtrl.DeleteAllItems(); +} + +void Func2Term::InputArgs() { + const auto* args = editor.Core().RSLang().FunctionArgsFor(mfc::ToSTL(activeName)); + if (args == nullptr) { + return; + } + for (auto i = 0; i < ssize(*args); ++i) { + const auto name = mfc::ToMFC(args->at(i).name); + const auto type = mfc::ToMFC(args->at(i).type.ToString()); + argsCtrl.InsertItem(i, name); + argsCtrl.SetItemText(i, ArgsHeader::POS_TYPE, type); + } +} + +} // namespace xtr::dialog \ No newline at end of file diff --git a/src/dialog/GenerateStructure.cpp b/src/dialog/GenerateStructure.cpp new file mode 100644 index 0000000..e6076ee --- /dev/null +++ b/src/dialog/GenerateStructure.cpp @@ -0,0 +1,270 @@ +#include "stdafx.h" + +#include "xtr/dialog/GenerateStructure.h" + +#include "resource.h" + +#include "xtr/cclDescriptor.h" +#include "xtr/ExteorOptions.h" + +#include "xtr/ui/HelpHandler.h" +#include "xtr/ui/KeyboardHandler.h" +#include "xtr/ui/UIHelper.h" + +#include "ccl/rslang/RSGenerator.h" + +namespace xtr::dialog { + +using ccl::semantic::CstType; +using ui::Keyboard; + +struct Structure2Terms::GlobalsHeader : ui::Header { + enum Columns : uint8_t { + POS_EXPR = 0, + POS_TYPE, + count + }; + + static constexpr uint32_t widthExpression = 190; + static constexpr uint32_t widthTypification = 130; + + GlobalsHeader() { + AddColumn({ IXTRS_HEADER_EXPRESSION, Alignment::left, widthExpression }); + AddColumn({ IXTRS_HEADER_TYPE, Alignment::left, widthTypification }); + } +}; + +struct Structure2Terms::ArgsHeader : ui::Header { + enum Columns : uint8_t { + POS_EXPR = 0, + POS_TYPE, + POS_TEXT, + count + }; + + static constexpr auto widthExpression = 190; + static constexpr auto widthTypification = 130; + static constexpr auto widthText = 233; + + ArgsHeader() { + AddColumn({ IXTRS_HEADER_EXPRESSION, Alignment::left, widthExpression }); + AddColumn({ IXTRS_HEADER_TYPE, Alignment::left, widthTypification }); + AddColumn({ IXTRS_HEADER_TERM, Alignment::left, widthText }); + } +}; + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(Structure2Terms, CDialog) + ON_CBN_SELCHANGE(IXTRC_TERM_CB, &ThisClass::OnSelchangeTermCb) + ON_BN_CLICKED(IXTRC_RIGHT, &ThisClass::OnBnClickedRight) + ON_BN_CLICKED(IXTRC_LEFT, &ThisClass::OnBnClickedLeft) + ON_BN_CLICKED(IXTRC_APPLY, &ThisClass::OnBnClickedApply) + + ON_NOTIFY(NM_DBLCLK, IXTRC_GLOBAL_LIST, &ThisClass::OnDblClickList) + ON_NOTIFY(LVN_ITEMACTIVATE, IXTRC_ARG_LIST, &ThisClass::OnItemActivateArgList) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +Structure2Terms::Structure2Terms(doc::RSFacade& editor, const EntityUID startID, CWnd* pParent) + : CDialog(IXTRD_GENERATE_TERM_STRUC, pParent), editor{ editor }, activeUID{ startID } {} + +BOOL Structure2Terms::OnInitDialog() { + CDialog::OnInitDialog(); + + InitControls(); + InitCstNameList(); + InitHeaders(); + + UpdateData(FALSE); + return TRUE; +} + +void Structure2Terms::InitControls() { + inputCtrl.InitRE(Keyboard::Layout::ENG, TRUE, TRUE); + textCtrl.SetFont(&XTROptions::App().fontText); +} + +void Structure2Terms::InitHeaders() { + static const GlobalsHeader globalsHead{}; + static const ArgsHeader argsHead{}; + + ui::InitHeaderFor(globalsCtrl, globalsHead); + ui::InitHeaderFor(argsCtrl, argsHead); +} + +void Structure2Terms::InitCstNameList() { + const auto selection = nameCtrl.GetCurSel(); + nameCtrl.ResetContent(); + for (const auto uid : editor.List()) { + const auto& cst = editor.GetRS(uid); + if (cst.type == CstType::term || cst.type == CstType::structured) { + nameCtrl.AddString(mfc::ToMFC(cst.alias)); + } + } + nameCtrl.SetCurSel(selection); +} + +void Structure2Terms::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + + ::DDX_Control(pDX, IXTRC_TERM_CB, nameCtrl); + ::DDX_Control(pDX, IXTRC_EXPR_INPUT, inputCtrl); + ::DDX_Control(pDX, IXTRC_INTERP, textCtrl); + ::DDX_Control(pDX, IXTRC_GLOBAL_LIST, globalsCtrl); + ::DDX_Control(pDX, IXTRC_ARG_LIST, argsCtrl); + + if (!pDX->m_bSaveAndValidate) { + const auto& cst = editor.GetText(activeUID); + activeName = mfc::ToMFC(cst.alias); + inputExpr = info::Label(editor.GetParse(activeUID).TypePtr()); + m_Interp = mfc::ToMFC(cst.definition.Str()); + } + + ::DDX_Text(pDX, IXTRC_EXPR_INPUT, inputExpr); + ::DDX_Text(pDX, IXTRC_INTERP, m_Interp); + ::DDX_CBString(pDX, IXTRC_TERM_CB, activeName); + + if (pDX->m_bSaveAndValidate) { + activeUID = editor.Core().FindAlias(mfc::ToSTL(activeName)).value(); + } else { + UpdateUI(); + } +} + +BOOL Structure2Terms::PreTranslateMessage(MSG* pMsg) { + if (pMsg->message == WM_KEYDOWN) { + if (pMsg->wParam == VK_F1) { + ui::HelpHandler::RunHelp(ui::HelpID::generateCst); + return TRUE; + } + } + return CDialog::PreTranslateMessage(pMsg); +} + +void Structure2Terms::OnSelchangeTermCb() { + UpdateData(TRUE); + UpdateData(FALSE); +} + +void Structure2Terms::OnOK() { + AddTerms(); + CDialog::OnOK(); +} + +void Structure2Terms::OnBnClickedApply() { + if (AddTerms() != 0) { + ::AfxMessageBox(IXTRS_GENERATE_TERM, MB_OK | MB_ICONINFORMATION); + } +} + +void Structure2Terms::OnBnClickedRight() { + globalsCtrl.MoveSelectedItemsTo(argsCtrl, ArgsHeader::count); +} + +void Structure2Terms::OnBnClickedLeft() { + argsCtrl.MoveSelectedItemsTo(globalsCtrl, GlobalsHeader::count); +} + +void Structure2Terms::OnItemActivateArgList(NMHDR *pNMHDR, LRESULT *pResult) { + const auto* activePtr = reinterpret_cast(pNMHDR); + *pResult = FALSE; + + if (const auto item = activePtr->iItem; item >= 0 && item < argsCtrl.GetItemCount()) { + GetInterpDialog dialog{ argsCtrl.GetItemText(item, ArgsHeader::Columns::POS_TEXT) }; + if (dialog.DoModal() == IDOK) { + argsCtrl.SetItemText(item, ArgsHeader::Columns::POS_TEXT, dialog.textDef); + } + } +} + +void Structure2Terms::OnDblClickList(NMHDR* /*pNMHDR*/, LRESULT* pResult) { + OnBnClickedRight(); + *pResult = TRUE; +} + +int Structure2Terms::AddTerms() { + UpdateData(TRUE); + + auto count = 0; + for (auto i = 0; i < argsCtrl.GetItemCount(); ++i) { + if (const auto expr = mfc::ToSTL(argsCtrl.GetItemText(i, ArgsHeader::Columns::POS_EXPR)); + !editor.RSLang().FindExpr(expr).has_value()) { + const auto termText = mfc::ToSTL(argsCtrl.GetItemText(i, ArgsHeader::Columns::POS_TEXT)); + const auto termID = editor.Emplace(CstType::term); + editor.SetExpressionFor(termID, expr); + editor.SetTermFor(termID, termText); + addedCst.emplace_back(termID); + ++count; + } + } + + argsCtrl.DeleteAllItems(); + UpdateUI(); + return count; +} + +void Structure2Terms::UpdateUI() { + inputCtrl.Init(editor.Core(), activeUID); + Clear(); + InputArguments(); + inputCtrl.UpdateFormat(); +} + +void Structure2Terms::InputArguments() { + using ccl::rslang::Generator; + const auto* type = editor.GetParse(activeUID).Typification(); + if (type == nullptr) { + return; + } + + const auto structure = Generator::StructureFor(mfc::ToSTL(activeName), *type); + auto line = 0; + for (auto i = 0; i < ssize(structure); ++i) { + const auto& expr = structure.at(i).first; + const auto& copy = editor.RSLang().FindExpr(expr); + auto typification = structure.at(i).second.ToString(); + if (!copy.has_value()) { + line = globalsCtrl.GetItemCount(); + globalsCtrl.InsertItem(line, mfc::ToMFC(expr)); + globalsCtrl.SetItemText(line, GlobalsHeader::Columns::POS_TYPE, mfc::ToMFC(typification)); + } else { + line = argsCtrl.GetItemCount(); + argsCtrl.InsertItem(line, mfc::ToMFC(editor.GetRS(copy.value()).definition)); + argsCtrl.SetItemText(line, ArgsHeader::Columns::POS_TYPE, mfc::ToMFC(typification)); + auto termtext = mfc::ToMFC(editor.GetText(copy.value()).term.Nominal()); + if (termtext.IsEmpty()) { + termtext = mfc::ToMFC(editor.GetText(copy.value()).definition.Str()); + } + argsCtrl.SetItemText(line, ArgsHeader::Columns::POS_TEXT, termtext); + } + } +} + +void Structure2Terms::Clear() { + globalsCtrl.DeleteAllItems(); + argsCtrl.DeleteAllItems(); +} + +GetInterpDialog::GetInterpDialog(const CString text, CWnd* pParent) + : CDialog(IXTRD_EDIT_TERM, pParent), textDef{ text } {} + +BOOL GetInterpDialog::OnInitDialog() { + CDialog::OnInitDialog(); + + Keyboard::Instance().SetLayout(Keyboard::Layout::RUS); + input.InitRE(Keyboard::Layout::RUS); + input.SetFont(&XTROptions::App().fontText); + return TRUE; +} + +void GetInterpDialog::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + + ::DDX_Control(pDX, IXTRC_INTER, input); + ::DDX_Text(pDX, IXTRC_INTER, textDef); +} + +} // namespace xtr::dialog \ No newline at end of file diff --git a/src/dialog/ImportWSDialog.cpp b/src/dialog/ImportWSDialog.cpp new file mode 100644 index 0000000..c1ab6c5 --- /dev/null +++ b/src/dialog/ImportWSDialog.cpp @@ -0,0 +1,42 @@ +#include "stdafx.h" + +#include "xtr/dialog/ImportWSDialog.h" + +#include "resource.h" + +namespace xtr::dialog { + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(ImportWSDialog, CDialog) + ON_BN_CLICKED(IDOK, &ThisClass::OnBnClickedOk) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +ImportWSDialog::ImportWSDialog(std::vector wsList, CWnd* pParent) + : CDialog(IXTRD_WORKSHEET, pParent), m_List(std::move(wsList)) {} + +void ImportWSDialog::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + ::DDX_Control(pDX, IXTRC_WSLIST, m_ListControl); +} + +BOOL ImportWSDialog::OnInitDialog() { + CDialog::OnInitDialog(); + + m_ListControl.ResetContent(); + for (const auto& label : m_List) { + m_ListControl.AddString(label); + } + return TRUE; +} + +void ImportWSDialog::OnBnClickedOk() { + UpdateData(); + selection = m_ListControl.GetCurSel(); + CDialog::OnOK(); +} + +} // namespace xtr::dialog \ No newline at end of file diff --git a/src/dialog/InsertCstDlg.cpp b/src/dialog/InsertCstDlg.cpp new file mode 100644 index 0000000..9cd7834 --- /dev/null +++ b/src/dialog/InsertCstDlg.cpp @@ -0,0 +1,178 @@ +#include "stdafx.h" + +#include "xtr/dialog/InsertCstDlg.h" + +#include "resource.h" + +#include "xtr/ExteorOptions.h" +#include "xtr/cclDescriptor.h" + +#include "ccl/semantic/CstFilters.hpp" + +namespace xtr::dialog { + +using ccl::semantic::RSCore; + +InsertCstDlg::InsertCstDlg(const RSCore& context, const CPoint pos, + const CString hint, CWnd* pParent) + : CDialog(IXTRD_AUTOCOMPLETE, pParent), + context{ context }, position{ pos }, hint{ hint } {} + +void InsertCstDlg::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + ::DDX_Control(pDX, IXTRC_AC_LIST1, pickerControl); +} + +BOOL InsertCstDlg::OnInitDialog() { + CDialog::OnInitDialog(); + + if (!hint.IsEmpty()) { + UpdateContextNameList(); + } + if (std::empty(typifications)) { + UpdateTypingNameList(); + } else { + state = DS_CSTS; + } + pickerControl.SetFont(&XTROptions::App().fontMathTT); + pickerControl.SetCurSel(0); + + FitDialogSize(); + return TRUE; +} + +BOOL InsertCstDlg::PreTranslateMessage(MSG* pMsg) { + if (pMsg->hwnd == pickerControl.GetSafeHwnd()) { + switch (state) { + case DS_DEFAULT: + if (pMsg->message == WM_LBUTTONDBLCLK || + (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)) { + OnSelectTyping(); return TRUE; + } + break; + + case DS_CSTS: + if (pMsg->message == WM_LBUTTONDBLCLK || + (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)) { + OnSelectCst(); return TRUE; + } + break; + } + } + return CDialog::PreTranslateMessage(pMsg); +} + +void InsertCstDlg::OnSelectTyping() { + const auto selected = pickerControl.GetCurSel(); + choice = typifications.at(selected); + VectorOfEntities filteredIDs{}; + if (selected == 0) { + std::copy(std::begin(context.List()), std::end(context.List()), std::back_inserter(filteredIDs)); + } else { + const auto filter = [&typeStr = this->choice, &schema = this->context] (const auto uid) + -> std::optional { + const auto* cstType = schema.GetParse(uid).TypePtr(); + if (cstType != nullptr && typeStr == info::Label(cstType)) { + return uid; + } else { + return std::nullopt; + } + }; + filteredIDs = ccl::semantic::FilterCst(context, filter); + } + + typifications.clear(); + pickerControl.ResetContent(); + + CString listItem{}; + for (const auto uid : filteredIDs) { + const auto& rsCst = context.GetRS(uid); + typifications.emplace_back(mfc::ToMFC(rsCst.alias)); + + listItem = mfc::ToMFC(rsCst.alias); + listItem += LR"(: )"; + listItem += mfc::ToMFC(context.GetText(uid).term.Nominal()); + pickerControl.AddString(listItem); + } + + pickerControl.SetCurSel(0); + pickerControl.SetFocus(); + + FitDialogSize(); + state = DS_CSTS; +} + +void InsertCstDlg::OnSelectCst() { + cstName = typifications.at(pickerControl.GetCurSel()); + OnOK(); +} + +void InsertCstDlg::FitDialogSize() { + static constexpr auto MAX_WIDTH = 600; + + auto h = 0; + auto width1 = 0; + CString str{}; + CSize sz{}; + + auto* pDC1 = pickerControl.GetDC(); + pDC1->SelectObject(pickerControl.GetFont()); + + for (auto i = 0; i < pickerControl.GetCount(); ++i) { + if (i < 10) { + h += pickerControl.GetItemHeight(i); + } + pickerControl.GetText(i, str); + sz = pDC1->GetTextExtent(str); + if (sz.cx > width1) { + width1 = sz.cx; + } + } + pickerControl.ReleaseDC(pDC1); + + width1 = std::min(width1 + 5, MAX_WIDTH) + GetSystemMetrics(SM_CXVSCROLL); + h += 4; + SetWindowPos(nullptr, position.x, position.y, width1, h, SWP_SHOWWINDOW); + pickerControl.SetWindowPos(&wndTop, 0, 0, width1, h, SWP_SHOWWINDOW); + pickerControl.SetColumnWidth(width1); +} + +void InsertCstDlg::UpdateTypingNameList() { + static auto selectAll = mfc::LoadSID(IXTRS_SELECT_ALL); + + pickerControl.ResetContent(); + typifications.clear(); + typifications.emplace_back(selectAll); + pickerControl.AddString(selectAll); + + std::set steps{}; + for (const auto uid : context.List()) { + steps.insert(info::Label(context.GetParse(uid).TypePtr())); + } + + for (const auto& aName : steps) { + typifications.emplace_back(aName); + pickerControl.AddString(aName); + } +} + +void InsertCstDlg::UpdateContextNameList() { + pickerControl.ResetContent(); + typifications.clear(); + + const auto inputs = context.Texts().Context().MatchingTerms(mfc::ToSTL(hint)); + CString listItem{}; + for (const auto uid : context.List()) { + const auto& alias = context.GetText(uid).alias; + if (inputs.contains(alias)) { + const auto& title = inputs.at(alias); + typifications.emplace_back(mfc::ToMFC(alias)); + listItem = mfc::ToMFC(alias); + listItem += LR"(: )"; + listItem += mfc::ToMFC(title); + pickerControl.AddString(listItem); + } + } +} + +} // namespace xtr::dialog \ No newline at end of file diff --git a/src/dialog/NewDocument.cpp b/src/dialog/NewDocument.cpp new file mode 100644 index 0000000..2133aa8 --- /dev/null +++ b/src/dialog/NewDocument.cpp @@ -0,0 +1,187 @@ +#include "stdafx.h" + +#include "xtr/dialog/NewDocument.h" + +#include "resource.h" + +#include "xtr/Exteor.h" + +namespace xtr::dialog { + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(NewDocument, CDialog) + ON_BN_CLICKED(IXTRC_OSS, &ThisClass::OnOSS) + ON_BN_CLICKED(IXTRC_RSFORM, &ThisClass::OnRSForm) + ON_BN_CLICKED(IXTRC_RSMODEL, &ThisClass::OnRSModel) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +NewDocument::NewDocument() + : CDialog(IXTRD_NEW_FILE) {} + +void NewDocument::OnOSS() { + if (ExteorApplication::Docs().NewOSSDoc() != nullptr) { + OnOK(); + } + OnCancel(); +} + +void NewDocument::OnRSModel() { + if (ExteorApplication::Docs().NewRSModelDoc() != nullptr) { + OnOK(); + } + OnCancel(); +} + +void NewDocument::OnRSForm() { + if (ExteorApplication::Docs().NewRSFormDoc() != nullptr) { + OnOK(); + } + OnCancel(); +} + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(NewRSForm, CDialog) + ON_CBN_EDITCHANGE(IXTRC_RS_TITLE, &ThisClass::OnChange) + ON_CBN_EDITCHANGE(IXTRC_RS_ALIAS, &ThisClass::OnChange) + ON_CBN_SELCHANGE(IXTRC_RS_TITLE, &ThisClass::OnChange) + ON_CBN_SELCHANGE(IXTRC_RS_ALIAS, &ThisClass::OnChange) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +NewRSForm::NewRSForm(const CString title, CWnd* pParent) + : CDialog(IXTRD_NEW_TRSDOC, pParent), title{ title } {} + +BOOL NewRSForm::OnInitDialog() { + CDialog::OnInitDialog(); + titleCB.Init(ui::CstPicker::Mode::TITLE, title); + aliasCB.Init(ui::CstPicker::Mode::ALIAS, title); + return TRUE; +} + +void NewRSForm::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + + ::DDX_Control(pDX, IXTRC_RS_ALIAS, aliasCB); + ::DDX_Control(pDX, IXTRC_RS_TITLE, titleCB); + + ::DDX_CBString(pDX, IXTRC_RS_TITLE, newTitle); + ::DDX_CBString(pDX, IXTRC_RS_ALIAS, newAlias); + + DDV_Names(); +} + +void NewRSForm::OnChange() { + UpdateData(); +} + +void NewRSForm::DDV_Names() { + GetDlgItem(LOWORD(GetDefID()))->EnableWindow(titleCB.IsValid() && aliasCB.IsValid()); +} + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(NewOSS, CDialog) + ON_BN_CLICKED(IXTRC_BROWSE, &ThisClass::OnBrowse) + ON_BN_CLICKED(IDOK, &ThisClass::OnAccept) + ON_EN_CHANGE(IXTRC_OSS_NAME, &ThisClass::OnChangeOssName) + ON_EN_CHANGE(IXTRC_OSS_PATH, &ThisClass::OnChangeOssPath) + ON_BN_CLICKED(IDCANCEL, &ThisClass::OnBnClickedCancel) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +NewOSS::NewOSS(CWnd* pParent) + : CDialog(IXTRD_NEW_OSSDOC, pParent) { + if (XTROptions::App().pathSaveAs.Right(1) != '\\') { + XTROptions::App().pathSaveAs += '\\'; + } + fullPath = XTROptions::App().pathSaveAs; +} + +void NewOSS::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + + ::DDX_Text(pDX, IXTRC_OSS_NAME, ossName); + ::DDX_Text(pDX, IXTRC_OSS_PATH, fullPath); +} + +void NewOSS::OnBrowse() { + UpdateData(); + ShowBrowseDlg(); + UpdateData(FALSE); + pathModified = FALSE; +} + +void NewOSS::ShowBrowseDlg() { + if (::_wchdir(fullPath) != 0) { + TRACE0("Cannot setup browse default folder"); + } + IFileDialog* fileDlg{ nullptr }; + if (SUCCEEDED(::CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&fileDlg)))) { + FILEOPENDIALOGOPTIONS dwOptions{}; + if (SUCCEEDED(fileDlg->GetOptions(&dwOptions))) { + fileDlg->SetOptions(dwOptions | FOS_PICKFOLDERS); + fileDlg->SetTitle(mfc::LoadSID(IXTRS_BROWSE_TITLE)); + } + + if (SUCCEEDED(fileDlg->Show(nullptr))) { + IShellItem *selectedItem{ nullptr }; + if (SUCCEEDED(fileDlg->GetResult(&selectedItem))) { + LPWSTR pName{}; + if (!SUCCEEDED(selectedItem->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING, &pName))) { + ::AfxMessageBox(IXTRE_BROWSE_DLG, MB_ICONERROR); + } else { + fullPath = pName; + } + selectedItem->Release(); + } + } + fileDlg->Release(); + } +} + +void NewOSS::OnAccept() { + UpdateData(); + + pathModified = TRUE; + if (_wmkdir(fullPath) == 0) { + CDialog::OnOK(); + } else { + CString msg{}; + switch (errno) { + case EEXIST: CDialog::OnOK(); return; + case EACCES: msg = mfc::FormatSID(IXTRE_OSS_DIR_EXISTS, fullPath.GetString()); break; + case ENOENT: msg = mfc::FormatSID(IXTRE_OSS_DIR_NOT_FOUND, fullPath.GetString()); break; + default: msg = mfc::FormatSID(IXTRE_FOLDER_CREATE_FAIL, fullPath.GetString()); break; + } + ::AfxMessageBox(msg, MB_ICONERROR); + } +} + +void NewOSS::OnChangeOssName() { + UpdateData(); + GetDlgItem(IDOK)->EnableWindow(!ossName.IsEmpty()); + if (pathModified) { + fullPath = XTROptions::App().pathSaveAs + ossName; + UpdateData(FALSE); + } +} + +void NewOSS::OnChangeOssPath() { + pathModified = FALSE; +} + +void NewOSS::OnBnClickedCancel() { + OnCancel(); + pathModified = TRUE; +} + +} // namespace xtr::dialog \ No newline at end of file diff --git a/src/dialog/OpSyntGUI.cpp b/src/dialog/OpSyntGUI.cpp new file mode 100644 index 0000000..b717b89 --- /dev/null +++ b/src/dialog/OpSyntGUI.cpp @@ -0,0 +1,571 @@ +#include "stdafx.h" + +#include "xtr/dialog/OpSyntGUI.h" + +#include "resource.h" + +#include "xtr/Exteor.h" +#include "xtr/cclDescriptor.h" +#include "xtr/doc/RSFormDoc.h" + +#include "xtr/ui/HelpHandler.h" +#include "xtr/ui/UIHelper.h" + +#include "xtr/dialog/BasicDlg.h" + +namespace xtr::dialog { + +using ccl::ops::Equation; +using ccl::semantic::CstType; + +SynthesUI::SynthesUI(const ccl::ops::Type type, const BOOL fromOSS, CWnd* pWndParent) + : CPropertySheet(IXTRS_PROPSHT_CAPTION, pWndParent), ossModeOn{ fromOSS }, opType{ type } { + operandsPage = std::make_unique(*this); + optionsPage = std::make_unique(*this); + confirmationPage = std::make_unique(*this); + + if (!fromOSS) { + AddPage(operandsPage.get()); + } + if (opType == ccl::ops::Type::rsSynt) { + AddPage(optionsPage.get()); + } + AddPage(confirmationPage.get()); + SetWizardMode(); +} + +BOOL SynthesUI::IsCorrect() const { + if (operand1 == nullptr || operand2 == nullptr) { + return FALSE; + } else { + return ccl::ops::BinarySynthes(*operand1, *operand2, equations).IsCorrectlyDefined(); + } +} + +BOOL SynthesUI::PreTranslateMessage(MSG* pMsg) { + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_F1) { + ui::HelpHandler::RunHelp(ui::HelpID::synthes); + return TRUE; + } + return CPropertySheet::PreTranslateMessage(pMsg); +} + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(SynthesUI::OperandsPage, CPropertyPage) + ON_NOTIFY(LVN_ITEMCHANGING, IXTRC_SYNT_OP1, &ThisClass::OnChangeOperands) + ON_NOTIFY(LVN_ITEMCHANGING, IXTRC_SYNT_OP2, &ThisClass::OnChangeOperands) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +struct SynthesUI::OperandsPage::OperandsHeader + : ui::Header { + enum Columns : uint8_t { + POS_FULLNAME = 0, + POS_SHORTNAME, + POS_TITLE, + POS_PATH, + count + }; + + static constexpr auto widthFull = 290; + static constexpr auto widthShort = 80; + static constexpr auto widthFile = 100; + static constexpr auto widthPath = 300; + + OperandsHeader() { + AddColumn({ IXTRS_HEADER_RS_FULL, Alignment::left, widthFull }); + AddColumn({ IXTRS_HEADER_SHORTNAME, Alignment::left, widthShort }); + AddColumn({ IXTRS_HEADER_FILENAME, Alignment::left, widthFile }); + AddColumn({ IXTRS_HEADER_PATH, Alignment::left, widthPath }); + } +}; + +SynthesUI::OperandsPage::OperandsPage(SynthesUI& parent) + : CPropertyPage(IXTRD_SYNT_OPERANDS), parentSht{ parent } {} + +void SynthesUI::OperandsPage::DoDataExchange(CDataExchange* pDX) { + CPropertyPage::DoDataExchange(pDX); + + ::DDX_Control(pDX, IXTRC_SYNT_OP1, firstOperandList); + ::DDX_Control(pDX, IXTRC_SYNT_OP2, secondOperandList); + + int32_t operation{}; + if (!pDX->m_bSaveAndValidate) { + operation = TypeToRadio(parentSht.opType); + } + const auto nItem1 = firstOperandList.GetSelectedIndex(); + const auto nItem2 = secondOperandList.GetSelectedIndex(); + if (nItem1 != mfc::noItems && nItem2 != mfc::noItems) { + firstOperand = firstOperandList.GetItemText(nItem1, OperandsHeader::Columns::POS_SHORTNAME); + secondOperand = secondOperandList.GetItemText(nItem2, OperandsHeader::Columns::POS_SHORTNAME); + + DDVNextBtn(nItem1, nItem2); + } + + ::DDX_Radio(pDX, IXTRC_SYNT_MERGE, operation); + ::DDX_Text(pDX, IXTRC_SHEMA1_NAME, firstOperand); + ::DDX_Text(pDX, IXTRC_SHEMA2_NAME, secondOperand); + + if (pDX->m_bSaveAndValidate) { + parentSht.opType = RadioToType(operation); + } +} + +BOOL SynthesUI::OperandsPage::OnInitDialog() { + CPropertyPage::OnInitDialog(); + + InitControls(); + InitHeaders(); + InputData(); + + UpdateData(FALSE); + return TRUE; +} + +void SynthesUI::OperandsPage::InputData() { + if (!parentSht.ossModeOn) { + UpdateDocList(firstOperandList); + UpdateDocList(secondOperandList); + secondOperandList.SetSelection(1); + } +} + +void SynthesUI::OperandsPage::InitControls() { + if (parentSht.ossModeOn) { + GetDlgItem(IXTRC_SYNT_MERGE)->EnableWindow(FALSE); + GetDlgItem(IXTRC_SYNT_ABSTRACT)->EnableWindow(FALSE); + } +} + +void SynthesUI::OperandsPage::InitHeaders() { + static const OperandsHeader header{}; + ui::InitHeaderFor(firstOperandList, header); + ui::InitHeaderFor(secondOperandList, header); +} + +BOOL SynthesUI::OperandsPage::OnSetActive() { + parentSht.SetWizardButtons(PSWIZB_NEXT); + UpdateData(FALSE); + return CPropertyPage::OnSetActive(); +} + +void SynthesUI::OperandsPage::OnChangeOperands(NMHDR* pNMHDR, LRESULT* pResult) { + if (firstOperandList.GetItemCount() != 0) { + const auto* pNMListView = reinterpret_cast(pNMHDR); + int32_t nItem1{}; + int32_t nItem2{}; + if (pNMHDR->hwndFrom == firstOperandList.GetSafeHwnd()) { + nItem1 = pNMListView->iItem; + nItem2 = secondOperandList.GetFocusIndex(); + } else { + nItem1 = firstOperandList.GetFocusIndex(); + nItem2 = pNMListView->iItem; + } + DDVNextBtn(nItem1, nItem2); + *pResult = 0; + } +} + +LRESULT SynthesUI::OperandsPage::OnWizardNext() { + UpdateData(TRUE); + if (parentSht.ossModeOn) { + return CPropertyPage::OnWizardNext(); + } + parentSht.operand1 = &GetTRSDocFromCList(firstOperandList)->Schema(); + parentSht.operand2 = &GetTRSDocFromCList(secondOperandList)->Schema(); + return CPropertyPage::OnWizardNext(); +} + +void SynthesUI::OperandsPage::DDVNextBtn(int32_t nItem1, int32_t nItem2) { + firstOperand = firstOperandList.GetItemText(nItem1, 1); + secondOperand = secondOperandList.GetItemText(nItem2, 1); + + if (nItem1 != nItem2) { + parentSht.SetWizardButtons(PSWIZB_NEXT); + } else { + parentSht.SetWizardButtons(0); + } +} + +doc::RSFormDoc* SynthesUI::OperandsPage::GetTRSDocFromCList(const ui::RSListCtrl& lc) { + if (const auto nItem = lc.GetFocusIndex(); nItem == mfc::noItems) { + return nullptr; + } else { + const auto path = lc.GetItemText(nItem, OperandsHeader::Columns::POS_PATH); + return ExteorApplication::Docs().FindRSDocByPath(path); + } +} + +void SynthesUI::OperandsPage::UpdateDocList(ui::RSListCtrl& lc, const doc::RSFormDoc* docExclude) { + if (!lc.DeleteAllItems()) { + ::AfxMessageBox(IXTRE_LIST_CLEAR, MB_ICONERROR); + } + auto nItem = 0; + for (const auto& rsDoc : ExteorApplication::Docs().RSFormDocList()) { + if (rsDoc != docExclude) { + if (!rsDoc->GetTitle().IsEmpty()) { +#pragma warning( push ) +#pragma warning( disable : 6387 ) + lc.InsertItem(LVIF_TEXT | LVIF_STATE, nItem, {}, 0, 0, 0, 0); +#pragma warning( pop ) + lc.SetItemText(nItem, OperandsHeader::Columns::POS_FULLNAME, mfc::ToMFC(rsDoc->Schema().title)); + lc.SetItemText(nItem, OperandsHeader::Columns::POS_SHORTNAME, mfc::ToMFC(rsDoc->Schema().alias)); + lc.SetItemText(nItem, OperandsHeader::Columns::POS_TITLE, rsDoc->GetTitle()); + lc.SetItemText(nItem, OperandsHeader::Columns::POS_PATH, rsDoc->GetPathName()); + ++nItem; + } + } + } + lc.SetSelection(0); +} + +int32_t SynthesUI::OperandsPage::TypeToRadio(ccl::ops::Type _type) noexcept { + switch(_type) { + default: return 0; + case ccl::ops::Type::rsMerge: return 0; + case ccl::ops::Type::rsSynt: return 1; + } +} + +ccl::ops::Type SynthesUI::OperandsPage::RadioToType(int32_t radio) noexcept { + switch(radio) { + case 0: return ccl::ops::Type::rsMerge; + case 1: return ccl::ops::Type::rsSynt; + } + return ccl::ops::Type::tba; +} + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(SynthesUI::OptionsPage, CPropertyPage) + ON_BN_CLICKED(IXTRC_IN1, &ThisClass::OnIn1) + ON_BN_CLICKED(IXTRC_IN2, &ThisClass::OnIn2) + ON_BN_CLICKED(IXTRC_IN3, &ThisClass::OnIn3) + ON_NOTIFY(NM_DBLCLK, IXTRC_SYNT_FLAG_CTABLE, &ThisClass::OnDblClickList) + + ON_BN_CLICKED(IXTRC_FLAG_BM, &ThisClass::OnChange) + ON_BN_CLICKED(IXTRC_FLAG_RS, &ThisClass::OnChange) + ON_BN_CLICKED(IXTRC_FLAG_TERM, &ThisClass::OnChange) + ON_BN_CLICKED(IXTRC_FLAG_BM2, &ThisClass::OnChange) + ON_BN_CLICKED(IXTRC_FLAG_RS2, &ThisClass::OnChange) + ON_BN_CLICKED(IXTRC_FLAG_TERM2, &ThisClass::OnChange) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +struct SynthesUI::OptionsPage::ArgHeader : ui::Header { + enum Columns : uint8_t { + POS_INTERP = 0, + POS_NAME, + count + }; + + static constexpr auto widthName = 50; + + explicit ArgHeader(int32_t controlWidth) { + const auto textWidth = controlWidth - widthName - ui::s_ScrollWidth; + assert(textWidth > 0); + AddColumn({ IXTRS_HEADER_NAME, Alignment::left, widthName }); + AddColumn({ IXTRS_HEADER_TERM, Alignment::left, textWidth }); + } +}; + +SynthesUI::OptionsPage::OptionsPage(SynthesUI& parent) + : CPropertyPage(IXTRD_SYNT_MAPTABLE), parentSht(parent) {} + +BOOL SynthesUI::OptionsPage::OnInitDialog() { + CPropertyPage::OnInitDialog(); + + InitHeaders(); + UpdateData(FALSE); + return TRUE; +} + +void SynthesUI::OptionsPage::InitHeaders() { + const ArgHeader header1{ ui::WindowRect(operand1List).Width() }; + const ArgHeader header2{ ui::WindowRect(operand2List).Width() }; + + ui::InitReversedHeaderFor(operand1List, header1); + ui::InitHeaderFor(operand2List, header2); + + equationsCtrl.InitHeader(); +} + +void SynthesUI::OptionsPage::DoDataExchange(CDataExchange* pDX) { + CPropertyPage::DoDataExchange(pDX); + + ::DDX_Control(pDX, IXTRC_IN1, operand1Btn); + ::DDX_Control(pDX, IXTRC_IN2, operand2Btn); + ::DDX_Control(pDX, IXTRC_IN3, equalsBtn); + ::DDX_Control(pDX, IXTRC_SYNT_FLAG_CTABLE, equationsCtrl.control); + ::DDX_Control(pDX, IXTRC_BM_OP2, operand2List); + ::DDX_Control(pDX, IXTRC_BM_OP1, operand1List); + + ::DDX_Check(pDX, IXTRC_FLAG_BM2, basic2Flag); + ::DDX_Check(pDX, IXTRC_FLAG_BM, basic1Flag); + ::DDX_Check(pDX, IXTRC_FLAG_RS, structure1Flag); + ::DDX_Check(pDX, IXTRC_FLAG_TERM, term1Flag); + ::DDX_Check(pDX, IXTRC_FLAG_RS2, structure2Flag); + ::DDX_Check(pDX, IXTRC_FLAG_TERM2, term2Flag); + + if (pDX->m_bSaveAndValidate) { + UpdateCstLists(); + } + DDV_Buttons(); +} + +void SynthesUI::OptionsPage::DDV_Buttons() { + const auto inReady = operand1List.GetItemCount() != 0 && operand2List.GetItemCount() != 0; + operand1Btn.EnableWindow(inReady); + operand2Btn.EnableWindow(inReady); + equalsBtn.EnableWindow(inReady); + + DWORD backBtn = PSWIZB_BACK; + if (parentSht.ossModeOn && parentSht.opType != ccl::ops::Type::rsSynt) { + backBtn = 0; + } + const auto next = parentSht.opType == ccl::ops::Type::rsMerge || equationsCtrl.control.GetItemCount() != 0; + if (next) { + parentSht.SetWizardButtons(PSWIZB_NEXT | backBtn); + } else { + parentSht.SetWizardButtons(backBtn); + } +} + +void SynthesUI::OptionsPage::OnDblClickList(NMHDR* /*pNMHDR*/, LRESULT* pResult) { + RemovePair(); + *pResult = 1; +} + +void SynthesUI::OptionsPage::OnIn1() { + AddPair(Equation::Mode::keepDel); +} + +void SynthesUI::OptionsPage::OnIn2() { + AddPair(Equation::Mode::keepHier); +} + +void SynthesUI::OptionsPage::OnIn3() { + AddPair(Equation::Mode::createNew); +} + +void SynthesUI::OptionsPage::OnChange() { + UpdateData(); +} + +void SynthesUI::OptionsPage::AddPair(const Equation::Mode type) { + UpdateData(TRUE); + + const auto nSelOp1 = operand1List.GetFocusIndex(); + const auto nSelOp2 = operand2List.GetFocusIndex(); + assert(nSelOp1 != mfc::noItems && nSelOp2 != mfc::noItems); + + const auto name1 = operand1List.GetItemText(nSelOp1, ArgHeader::Columns::POS_NAME); + auto termin1 = operand1List.GetItemText(nSelOp1, ArgHeader::Columns::POS_INTERP); + const auto name2 = operand2List.GetItemText(nSelOp2, ArgHeader::Columns::POS_INTERP); + auto termin2 = operand2List.GetItemText(nSelOp2, ArgHeader::Columns::POS_NAME); + + if (type == Equation::Mode::createNew) { + termin2 = AskForTerm(termin1 + LR"( ~ )" + termin2); + termin1 = mfc::LoadSID(IXTRS_OP_NEW_TERM); + } + + const auto nInsertPos = equationsCtrl.InsertItem({ name1, name2, termin1, termin2, type }); + + operand1List.DeleteItem(nSelOp1); + operand2List.DeleteItem(nSelOp2); + equationsCtrl.control.SetSelection(nInsertPos); + operand1List.SetSelection(0); + operand2List.SetSelection(0); + + DDV_Buttons(); +} + +BOOL SynthesUI::OptionsPage::OnSetActive() { + if (!parentSht.ossModeOn || parentSht.opType == ccl::ops::Type::rsSynt) { + parentSht.SetWizardButtons(PSWIZB_NEXT | PSWIZB_BACK); + } else { + parentSht.SetWizardButtons(PSWIZB_NEXT); + } + if (equationsCtrl.control.m_hWnd == nullptr) { + return CPropertyPage::OnSetActive(); + } else { + equationsCtrl.control.DeleteAllItems(); + equationsCtrl.LoadTableSynth(parentSht.equations, *parentSht.operand1, *parentSht.operand2); + + UpdateCstLists(); + UpdateData(FALSE); + return CPropertyPage::OnSetActive(); + } +} + +LRESULT SynthesUI::OptionsPage::OnWizardNext() { + static constexpr auto dontChangePage = -1; + if (auto newEqs = equationsCtrl.CreateEquations(*parentSht.operand1, *parentSht.operand2); + newEqs.has_value()) { + if (parentSht.equations = newEqs.value(); parentSht.IsCorrect()) { + return CPropertyPage::OnWizardNext(); + } + } + ::AfxMessageBox(IXTRE_SYNT_INCORRECT, MB_ICONERROR); + return dontChangePage; +} + +void SynthesUI::OptionsPage::RemovePair() { + if (equationsCtrl.control.GetItemCount() != 0) { + equationsCtrl.control.DeleteItem(equationsCtrl.control.GetFocusIndex()); + equationsCtrl.control.SetSelection(0); + + UpdateCstLists(); + DDV_Buttons(); + } +} + +CString SynthesUI::OptionsPage::AskForTerm(const CString initial) { + EditString dlg(initial, mfc::LoadSID(IXTRS_CAPTION_TERM)); + if (dlg.DoModal() == IDOK) { + return dlg.resultStr; + } else { + return{}; + } +} + +static constexpr auto OPERAND_1 = 1; +static constexpr auto OPERAND_2 = 2; + +void SynthesUI::OptionsPage::UpdateCstLists() { + const auto nSelOp1 = operand1List.GetFocusIndex(); + const auto nSelOp2 = operand2List.GetFocusIndex(); + + operand1List.DeleteAllItems(); + operand2List.DeleteAllItems(); + + if (parentSht.opType != ccl::ops::Type::rsMerge) { + auto list1 = equationsCtrl.Inputs(*parentSht.operand1); + auto list2 = equationsCtrl.Outputs(*parentSht.operand2); + + if (basic2Flag) { + FillCstOfType(OPERAND_2, CstType::base, list2); + } + if (structure2Flag) { + FillCstOfType(OPERAND_2, CstType::structured, list2); + } + if (term2Flag) { + FillCstOfType(OPERAND_2, CstType::term, list2); + } + if (basic1Flag) { + FillCstOfType(OPERAND_1, CstType::base, list1); + } + if (structure1Flag) { + FillCstOfType(OPERAND_1, CstType::structured, list1); + } + if (term1Flag) { + FillCstOfType(OPERAND_1, CstType::term, list1); + } + operand1List.SetSelection(nSelOp1 >= operand1List.GetItemCount() ? 0 : nSelOp1); + operand2List.SetSelection(nSelOp2 >= operand2List.GetItemCount() ? 0 : nSelOp2); + } +} + +void SynthesUI::OptionsPage::FillCstInCL(ui::RSListCtrl& lc, const ccl::semantic::RSForm& schema, + int32_t nameCol, int32_t termCol, + const CstType type, const SetOfEntities& ignoreList) { + for (const auto uid : schema.List()) { + const auto& rsCst = schema.GetRS(uid); + if (rsCst.type == type && !ignoreList.contains(uid)) { +#pragma warning( push ) +#pragma warning( disable : 6387 ) + const auto nItem = lc.InsertItem(LVIF_TEXT | LVIF_STATE, lc.GetItemCount(), {}, 0, 0, 0, 0); +#pragma warning( pop ) + lc.SetItemText(nItem, nameCol, mfc::ToMFC(rsCst.alias)); + lc.SetItemText(nItem, termCol, mfc::ToMFC(schema.GetText(uid).term.Nominal())); + } + } + lc.SetSelection(0); +} + +void SynthesUI::OptionsPage::FillCstOfType(int32_t list1Or2, const CstType type, const SetOfEntities& ignoreList) { + if (list1Or2 == OPERAND_1) { + FillCstInCL(operand1List, *parentSht.operand1, ArgHeader::Columns::POS_NAME, ArgHeader::Columns::POS_INTERP, type, ignoreList); + } else { + FillCstInCL(operand2List, *parentSht.operand2, ArgHeader::Columns::POS_INTERP, ArgHeader::Columns::POS_NAME, type, ignoreList); + } +} + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(SynthesUI::ConfirmPage, CPropertyPage) + ON_CBN_SELENDOK(IXTRC_RESULT_TITLE, &ThisClass::OnComboChanged) + ON_CBN_SELENDOK(IXTRC_RESULT_ALIAS, &ThisClass::OnComboChanged) + ON_CBN_EDITCHANGE(IXTRC_RESULT_TITLE, &ThisClass::OnChange) + ON_CBN_EDITCHANGE(IXTRC_RESULT_ALIAS, &ThisClass::OnChange) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +SynthesUI::ConfirmPage::ConfirmPage(SynthesUI& parent) + : CPropertyPage(IXTRD_SYNT_NAMES), + operation{ mfc::LoadSID(IXTRS_OPLABEL_SYNT) }, parentSht{ parent } {} + +void SynthesUI::ConfirmPage::DoDataExchange(CDataExchange* pDX) { + CPropertyPage::DoDataExchange(pDX); + + ::DDX_Control(pDX, IXTRC_SYNT_FLAG_CTABLE, equationsCtrl.control); + ::DDX_Control(pDX, IXTRC_RESULT_ALIAS, shortNameCtrl); + ::DDX_Control(pDX, IXTRC_RESULT_TITLE, fullNameCtrl); + + ::DDX_Text(pDX, IXTRC_FIRST_OP, firstOperand); + ::DDX_Text(pDX, IXTRC_OP_NAME, operation); + ::DDX_Text(pDX, IXTRC_SECOND_OP, secondOperand); + ::DDX_Text(pDX, IXTRC_RESULT_TITLE, parentSht.title); + ::DDX_Text(pDX, IXTRC_RESULT_ALIAS, parentSht.alias); + + DDV_Names(); +} + +BOOL SynthesUI::ConfirmPage::OnInitDialog() { + CPropertyPage::OnInitDialog(); + + InitControls(); + equationsCtrl.InitHeader(); + UpdateData(FALSE); + return TRUE; +} + +void SynthesUI::ConfirmPage::InitControls() { + fullNameCtrl.Init(ui::CstPicker::Mode::TITLE, parentSht.title); + shortNameCtrl.Init(ui::CstPicker::Mode::ALIAS, parentSht.alias); +} + +void SynthesUI::ConfirmPage::OnChange() { + UpdateData(TRUE); +} + +void SynthesUI::ConfirmPage::OnComboChanged() { + parentSht.SetWizardButtons(PSWIZB_DISABLEDFINISH | PSWIZB_BACK); +} + +BOOL SynthesUI::ConfirmPage::OnSetActive() { + firstOperand = mfc::ToMFC(parentSht.operand1->title); + secondOperand = mfc::ToMFC(parentSht.operand2->title); + operation = info::Label(parentSht.opType); + equationsCtrl.LoadTableSynth(parentSht.equations, *parentSht.operand1, *parentSht.operand2); + UpdateData(FALSE); + OnChange(); + return CPropertyPage::OnSetActive(); +} + +void SynthesUI::ConfirmPage::DDV_Names() { + if (!fullNameCtrl.IsValid() || !shortNameCtrl.IsValid()) { + parentSht.SetWizardButtons(PSWIZB_DISABLEDFINISH | PSWIZB_BACK); + } else { + parentSht.SetWizardButtons(PSWIZB_FINISH | PSWIZB_BACK); + } +} + +} // namespace xtr::dialog \ No newline at end of file diff --git a/src/dialog/OptionsDialog.cpp b/src/dialog/OptionsDialog.cpp new file mode 100644 index 0000000..40af75e --- /dev/null +++ b/src/dialog/OptionsDialog.cpp @@ -0,0 +1,193 @@ +#include "stdafx.h" + +#include "xtr/dialog/OptionsDialog.h" + +#include "resource.h" + +#include "xtr/ExteorOptions.h" +#include "xtr/ui/HelpHandler.h" + +namespace xtr::dialog { + +ExteorOptionsSheet::ExteorOptionsSheet(CWnd* pWndParent) + : CPropertySheet(IXTRS_APP_PROPERTIES, pWndParent) { + AddPage(&m_App); + AddPage(&m_OSS); + AddPage(&parsing); + AddPage(&m_RSModel); +} + +BOOL ExteorOptionsSheet::PreTranslateMessage(MSG* pMsg) { + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_F1) { + ui::HelpHandler::RunHelp(ui::HelpID::options); + return TRUE; + } else { + return CPropertySheet::PreTranslateMessage(pMsg); + } +} + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(GeneralPage, CDialog) + ON_BN_CLICKED(IXTRC_FILE_VERSION_PROMT, &ThisClass::OnChange) + ON_BN_CLICKED(IXTRC_START_PAGE, &ThisClass::OnChange) + ON_BN_CLICKED(IXTRC_LOAD_PYTHON, &ThisClass::OnChange) + ON_EN_CHANGE(IXTRC_PYTHONPATH, &ThisClass::OnChange) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +GeneralPage::GeneralPage() + : CPropertyPage(IXTRD_OPTION_APPLICATION) { + promptVersion = XTROptions::App().promptVersion; + showStartPage = XTROptions::App().showStartPage; + disableAutoKeyboard = XTROptions::App().disableAutoKeyboard; + enablePython = XTROptions::App().enablePython; + pythonPath = XTROptions::App().pythonPath; +} + +void GeneralPage::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + + ::DDX_Check(pDX, IXTRC_FILE_VERSION_PROMT, promptVersion); + ::DDX_Check(pDX, IXTRC_START_PAGE, showStartPage); + ::DDX_Check(pDX, IXTRC_LOAD_PYTHON, enablePython); + ::DDX_Check(pDX, IXTRC_DISABLE_AUTOLANG, disableAutoKeyboard); + ::DDX_Text(pDX, IXTRC_PYTHONPATH, pythonPath); +} + +void GeneralPage::OnOK() { + XTROptions::App().promptVersion = promptVersion; + XTROptions::App().showStartPage = showStartPage; + XTROptions::App().enablePython = enablePython; + XTROptions::App().disableAutoKeyboard = disableAutoKeyboard; + XTROptions::App().pythonPath = pythonPath; + + CPropertyPage::OnOK(); +} + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(OSSPage, CDialog) + ON_BN_CLICKED(IXTRC_OSS_RUN_AFTER_CLK_OK, &ThisClass::OnChange) + ON_EN_CHANGE(IXTRC_ZOOM_INT, &ThisClass::OnChange) + ON_EN_CHANGE(IXTRC_OSS_GRID_ENABLED, &ThisClass::OnChange) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +OSSPage::OSSPage() : CPropertyPage(IXTRD_OPTION_OSS) { + m_RunOperation = XTROptions::OSS().runOpAfterEdit; + zoom = XTROptions::OSS().zoom; + m_EnableGrid = XTROptions::OSS().showGrid; +} + +void OSSPage::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + + ::DDX_Check(pDX, IXTRC_OSS_RUN_AFTER_CLK_OK, m_RunOperation); + ::DDX_Check(pDX, IXTRC_OSS_GRID_ENABLED, m_EnableGrid); + + ::DDX_Text(pDX, IXTRC_ZOOM_INT, zoom); + + ::DDV_MinMaxUInt(pDX, zoom, ossOptions::zoomMin, ossOptions::zoomMax); +} + +BOOL OSSPage::OnInitDialog() { + CPropertyPage::OnInitDialog(); + return TRUE; +} + +void OSSPage::OnOK() { + XTROptions::OSS().runOpAfterEdit = m_RunOperation; + XTROptions::OSS().zoom = zoom; + XTROptions::OSS().showGrid = m_EnableGrid; + + CPropertyPage::OnOK(); +} + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(ParsingPage, CDialog) + ON_BN_CLICKED(IXTRC_SA_AUTOCHECK, &ThisClass::OnChange) + + ON_BN_CLICKED(IXTRC_INDEXCST0, &ThisClass::OnChange) + ON_BN_CLICKED(IXTRC_INDEXCST1, &ThisClass::OnChange) + ON_BN_CLICKED(IXTRC_INDEXCST2, &ThisClass::OnChange) + ON_BN_CLICKED(IXTRC_INDEXLOCAL0, &ThisClass::OnChange) + ON_BN_CLICKED(IXTRC_INDEXLOCAL1, &ThisClass::OnChange) + ON_BN_CLICKED(IXTRC_INDEXLOCAL2, &ThisClass::OnChange) + ON_BN_CLICKED(IXTRC_INDEXPR0, &ThisClass::OnChange) + ON_BN_CLICKED(IXTRC_INDEXPR1, &ThisClass::OnChange) + ON_BN_CLICKED(IXTRC_INDEXPR2, &ThisClass::OnChange) + + ON_BN_CLICKED(IXTRC_SA_COLOR_PAR, &ThisClass::OnChange) + ON_BN_CLICKED(IXTRC_SA_AST, &ThisClass::OnChange) + ON_BN_CLICKED(IXTRC_SA_RSNAVIGATOR, &ThisClass::OnChange) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +ParsingPage::ParsingPage() : CPropertyPage(IXTRD_OPTION_ANALYZER) { + autoCheck = XTROptions::ParseRSL().autoCheck; + colorBrackets = XTROptions::ParseRSL().colorBrackets; + showAST = XTROptions::ParseRSL().showAST; + enableNavigator = XTROptions::ParseRSL().enableNavigator; + m_IndexCst = static_cast(XTROptions::ParseRSL().indexing.global); + m_IndexLocal = static_cast(XTROptions::ParseRSL().indexing.local); + m_IndexPr = static_cast(XTROptions::ParseRSL().indexing.operators); +} + +void ParsingPage::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + + ::DDX_Check(pDX, IXTRC_SA_AUTOCHECK, autoCheck); + ::DDX_Check(pDX, IXTRC_SA_COLOR_PAR, colorBrackets); + ::DDX_Check(pDX, IXTRC_SA_AST, showAST); + ::DDX_Check(pDX, IXTRC_SA_RSNAVIGATOR, enableNavigator); + + ::DDX_Radio(pDX, IXTRC_INDEXCST0, m_IndexCst); + ::DDX_Radio(pDX, IXTRC_INDEXLOCAL0, m_IndexLocal); + ::DDX_Radio(pDX, IXTRC_INDEXPR0, m_IndexPr); +} + +void ParsingPage::OnOK() { + XTROptions::ParseRSL().autoCheck = autoCheck; + XTROptions::ParseRSL().colorBrackets = colorBrackets; + XTROptions::ParseRSL().showAST = showAST; + XTROptions::ParseRSL().enableNavigator = enableNavigator; + XTROptions::ParseRSL().indexing.global = static_cast(m_IndexCst); + XTROptions::ParseRSL().indexing.local = static_cast(m_IndexLocal); + XTROptions::ParseRSL().indexing.operators = static_cast(m_IndexPr); + + CPropertyPage::OnOK(); +} + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(ModelPage, CDialog) + ON_BN_CLICKED(IXTRC_DATAMODE, &ThisClass::OnChange) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +ModelPage::ModelPage() + : CPropertyPage(IXTRD_OPTION_MODEL) { + m_DataMode = XTROptions::Model().m_DataMode; +} + +void ModelPage::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + ::DDX_Check(pDX, IXTRC_DATAMODE, m_DataMode); +} + +void ModelPage::OnOK() { + XTROptions::Model().m_DataMode = m_DataMode; + CPropertyPage::OnOK(); +} + +} // namespace xtr::dialog \ No newline at end of file diff --git a/src/dialog/PickOperation.cpp b/src/dialog/PickOperation.cpp new file mode 100644 index 0000000..4565f50 --- /dev/null +++ b/src/dialog/PickOperation.cpp @@ -0,0 +1,83 @@ +#include "stdafx.h" + +#include "xtr/dialog/PickOperation.h" + +#include "resource.h" +#include "xtr/ui/HelpHandler.h" +#include "xtr/ExteorOptions.h" +#include "xtr/cclDescriptor.h" + +namespace xtr::dialog { + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(PickOperationDlg, CDialog) + ON_COMMAND(IXTRC_XTR_HELP, &ThisClass::OpenHelp) + + ON_LBN_DBLCLK(IXTRC_OSS_SINT_DEF_LC, &CDialog::OnOK) + ON_BN_CLICKED(IXTRC_OSS_RUN_AFTER_CLK_OK, &ThisClass::OnChange) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +PickOperationDlg::PickOperationDlg(ccl::oss::OSSchema& schema, + const ccl::oss::PictID pid, CWnd* pParent) + : CDialog(IXTRD_OSS_OPERATIONS, pParent), oss{ schema }, activePID{ pid } { + for (const auto opID : oss.Ops().VariantsFor(pid)) { + operations.push_back(opID); + } + autorun = XTROptions::OSS().runOpAfterEdit; +} + +void PickOperationDlg::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + + ::DDX_Control(pDX, IXTRC_OSS_SINT_DEF_LC, m_OperationList); + + ::DDX_Check(pDX, IXTRC_OSS_RUN_AFTER_CLK_OK, autorun); + + if (pDX->m_bSaveAndValidate) { + type = m_OperationList.GetCurSel(); + XTROptions::OSS().runOpAfterEdit = autorun; + } +} + +BOOL PickOperationDlg::OnInitDialog() { + CDialog::OnInitDialog(); + for (auto& iter : operations) { + m_OperationList.AddString(info::Label(iter)); + } + m_OperationList.SetCurSel(Operation2ID(oss.Ops()(activePID)->type)); + return TRUE; +} + +void PickOperationDlg::OnChange() { // NOLINT(readability-convert-member-functions-to-static) + UpdateData(TRUE); +} + +void PickOperationDlg::OpenHelp() { // NOLINT(readability-convert-member-functions-to-static) + ui::HelpHandler::RunHelp(ui::HelpID::operations); +} + +ccl::ops::Type PickOperationDlg::ID2Operation(int32_t selectedID) const { + if (selectedID < 0 || selectedID >= ssize(operations)) { + return ccl::ops::Type::tba; + } else { + return operations.at(selectedID); + } +} + +int32_t PickOperationDlg::Operation2ID(ccl::ops::Type operationType) const noexcept { + auto i = 0; + for (const auto operation : operations) { + if (operationType == operation) { + return i; + } else { + ++i; + } + } + return -1; +} + +} // namespace xtr::dialog \ No newline at end of file diff --git a/src/dialog/RSModelPage.cpp b/src/dialog/RSModelPage.cpp new file mode 100644 index 0000000..92d7901 --- /dev/null +++ b/src/dialog/RSModelPage.cpp @@ -0,0 +1,252 @@ +#include "stdafx.h" + +#include "xtr/dialog/RSModelPage.h" + +#include "resource.h" + +#include "xtr/cclDescriptor.h" +#include "xtr/xtrProcedures.h" +#include "xtr/ExteorOptions.h" +#include "xtr/doc/RSModelDoc.h" + +#include "xtr/ui/KeyboardHandler.h" +#include "xtr/ui/HelpHandler.h" + +#include "xtr/dialog/EditConstituenta.h" + +namespace xtr::dialog { + +using ui::Keyboard; + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(RSModelPage, CPropertyPage) + ON_CBN_SELCHANGE(IXTRC_NAME_CB, &ThisClass::OnSelchangeName) + ON_CBN_KILLFOCUS(IXTRC_EDIT_DATA, &ThisClass::OnCbnKillfocusEditData) + ON_BN_CLICKED(IXTRC_FILL_INTERP, &ThisClass::OnBnClickedFillInterp) + ON_BN_CLICKED(IXTRC_ERASE_DATA, &ThisClass::OnEraseData) + ON_BN_CLICKED(IXTRC_EXPORT_DATA, &ThisClass::OnExportData) + ON_BN_CLICKED(IXTRC_IMPORT_CSTDATA, &ThisClass::OnImportData) + + ON_BN_CLICKED(IXTRC_PREV, &ThisClass::OnPrev) + ON_BN_CLICKED(IXTRC_NEXT, &ThisClass::OnNext) + + ON_NOTIFY(LVN_ITEMCHANGED, IXTRC_DATA_TABLE, &ThisClass::OnDataChange) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +RSModelPage::RSModelPage(EditConstituentaDlg& parent) + : CPropertyPage(IXTRD_CST_EDIT_MODEL), parent{ parent } {} + +BOOL RSModelPage::OnInitDialog() { + CPropertyPage::OnInitDialog(); + + InitControls(); + InitCstNameList(); + UpdateData(FALSE); + + return TRUE; +} + +void RSModelPage::InitControls() { + static constexpr UINT PROPERTI_DROPPED_WIDTH = 820; + + exprCtrl.InitRE(Keyboard::Layout::MATH, TRUE, TRUE); + textCtr.InitRE(Keyboard::Layout::RUS); + nameCtrl.SetDroppedWidth(PROPERTI_DROPPED_WIDTH); + nameCtrl.SetFont(&XTROptions::App().fontText); + textCtr.SetFont(&XTROptions::App().fontText); + textBtn.SetCheck(XTROptions::Model().m_DataMode); + dataCtrl.Init(&dataEditCtrl, textBtn.GetCheck(), dynamic_cast(parent.editor->Document())); + dataEditCtrl.ShowWindow(SW_HIDE); +} + +void RSModelPage::InitCstNameList() { + nameCtrl.SetRedraw(FALSE); + + const auto sel = nameCtrl.GetCurSel(); + nameCtrl.ResetContent(); + for (const auto uid : parent.editor->List()) { + const auto& cst = parent.editor->GetText(uid); + auto str = mfc::ToMFC(cst.alias); + str += LR"( - )" + mfc::ToMFC(cst.definition.Str()); + str.Replace(L"\n", L" "); + nameCtrl.AddString(str); + } + nameCtrl.SetCurSel(sel); + + nameCtrl.SetRedraw(TRUE); +} + +void RSModelPage::DoDataExchange(CDataExchange* pDX) { + CPropertyPage::DoDataExchange(pDX); + + ::DDX_Control(pDX, IXTRC_NAME_CB, nameCtrl); + ::DDX_Control(pDX, IXTRC_TYPIFICATION, exprCtrl); + ::DDX_Control(pDX, IXTRC_INTERPRETATION, textCtr); + ::DDX_Control(pDX, IXTRC_DATA_TABLE, dataCtrl); + ::DDX_Control(pDX, IXTRC_EDIT_DATA, dataEditCtrl); + ::DDX_Control(pDX, IXTRC_FILL_INTERP, textBtn); + + if (!pDX->m_bSaveAndValidate) { + typification = info::Label(parent.editor->GetParse(parent.activeUID).TypePtr()); + textDef = mfc::ToMFC(parent.editor->GetText(parent.activeUID).definition.Str()); + if (dataCtrl.IsInit()) { + dataCtrl.SetActive(parent.activeUID); + } + } + + auto sellectedName = mfc::ToMFC(parent.editor->GetText(parent.activeUID).alias); + ::DDX_Text(pDX, IXTRC_TYPIFICATION, typification); + ::DDX_Text(pDX, IXTRC_INTERPRETATION, textDef); + ::DDX_CBString(pDX, IXTRC_NAME_CB, sellectedName); + + if (pDX->m_bSaveAndValidate) { + dataCtrl.SaveData(); + parent.editor->Document().UpdateAllViews(nullptr); + } else { + UpdateFormat(); + } +} + +void RSModelPage::UpdateFormat() { + exprCtrl.UpdateFormat(); +} + +BOOL RSModelPage::PreTranslateMessage(MSG* pMsg) { + if (pMsg->message == WM_KEYDOWN) { + if (pMsg->wParam == VK_ESCAPE) { + if (dataEditCtrl.IsWindowVisible()) { + CancelEdit(); + } else { + OnCancel(); + } + return TRUE; + } + if (pMsg->wParam == VK_RETURN) { + if (dataEditCtrl.IsWindowVisible()) { + UpdateCellText(); + } + return TRUE; + } + if (pMsg->wParam == VK_F1) { + ui::HelpHandler::RunHelp(ui::HelpID::editData); + return TRUE; + } + } + return CPropertyPage::PreTranslateMessage(pMsg); +} + +void RSModelPage::CancelEdit() { + canceled = TRUE; + dataEditCtrl.ShowWindow(SW_HIDE); + dataCtrl.SetFocus(); + canceled = FALSE; +} + +void RSModelPage::SetModified(BOOL bChanged) { + isModified = bChanged; + CPropertyPage::SetModified(bChanged); +} + +BOOL RSModelPage::IsModified() const noexcept { + return isModified; +} + +void RSModelPage::OnCbnKillfocusEditData() { + if (!canceled) { + UpdateCellText(); + } +} + +BOOL RSModelPage::OnApply() { + if (!CPropertyPage::OnApply()) { + return FALSE; + } else if (parent.GetActivePage() != this) { + return TRUE; + } else { + UpdateData(FALSE); + return TRUE; + } +} + +void RSModelPage::OnCancel() { + CPropertyPage::OnCancel(); + EndDialog(IDCANCEL); +} + +void RSModelPage::OnOK() { + if (parent.GetActivePage() == this) { + UpdateData(); + SetModified(FALSE); + CPropertyPage::OnOK(); + } +} + +void RSModelPage::OnConfirm() { + UpdateData(); +} + +void RSModelPage::OnSelchangeName() { + const auto index = nameCtrl.GetCurSel(); + assert(index != mfc::noItems); + + OnApply(); + + CString name{}; + nameCtrl.GetLBText(index, name); + name = mfc::FirstWordOf(name); + + parent.activeUID = parent.editor->Core().FindAlias(mfc::ToSTL(name)).value(); + UpdateData(FALSE); +} + +void RSModelPage::OnBnClickedFillInterp() { + XTROptions::Model().m_DataMode = textBtn.GetCheck(); + dataCtrl.SetTextFlag(textBtn.GetCheck()); +} + +void RSModelPage::OnImportData() { + UpdateData(TRUE); + proc::ImportCstDataFromExcel(parent.editor->EditModel(), parent.activeUID); + UpdateData(FALSE); +} + +void RSModelPage::OnDataChange(NMHDR* /*pNMHDR*/, LRESULT* pResult) { + if (GetFocus() != nullptr && GetFocus() == GetDlgItem(IXTRC_DATA_TABLE)) { + SetModified(TRUE); + } + *pResult = 1; +} + +void RSModelPage::OnExportData() { // NOLINT(readability-make-member-function-const) + proc::ExportCstDataToExcel(parent.editor->Model(), parent.activeUID); +} + +void RSModelPage::OnEraseData() { + proc::EraseCstData(parent.editor->EditModel(), parent.activeUID); + UpdateData(FALSE); +} + +void RSModelPage::UpdateCellText() { + canceled = TRUE; + dataCtrl.UpdateSelectedCellText(); + dataCtrl.SetFocus(); + canceled = FALSE; +} + +void RSModelPage::OnPrev() { + UpdateData(TRUE); + parent.StepPrev(); + UpdateData(FALSE); +} + +void RSModelPage::OnNext() { + UpdateData(TRUE); + parent.StepNext(); + UpdateData(FALSE); +} + +} // namespace xtr::dialog \ No newline at end of file diff --git a/src/dialog/StartPage.cpp b/src/dialog/StartPage.cpp new file mode 100644 index 0000000..77cb694 --- /dev/null +++ b/src/dialog/StartPage.cpp @@ -0,0 +1,123 @@ +#include "stdafx.h" + +#include "xtr/dialog/StartPage.h" + +#include "resource.h" + +#include "xtr/Exteor.h" + +#include "xtr/ui/HelpHandler.h" +#include "xtr/ui/UIHelper.h" + +namespace xtr::dialog { + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(ExtStartPage, CDialog) + ON_BN_CLICKED(IXTRC_NEW_DOCUMENT, &ThisClass::OnNewDoc) + ON_BN_CLICKED(IXTRC_OPEN_DOC, &ThisClass::OnOpenDoc) + ON_BN_CLICKED(IXTRC_START_HELP, &ThisClass::OnOpenHelp) + ON_BN_CLICKED(IXTRC_SAMPLES, &ThisClass::OnSamples) + ON_BN_CLICKED(IXTRC_MEMO, &ThisClass::OnMemo) + + ON_BN_CLICKED(IXTRC_DONT_PROMT, &ThisClass::OnPromt) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +ExtStartPage::~ExtStartPage() { + ::DestroyIcon(xtrIcon); +} + +BOOL ExtStartPage::OnInitDialog() { + CDialog::OnInitDialog(); + + InitTitle(); + LoadExteorIcon(); + InitControls(); + + UpdateWindow(); + return TRUE; +} + +void ExtStartPage::LoadExteorIcon() { + xtrIcon = static_cast(LoadImageW(AfxGetResourceHandle(), + MAKEINTRESOURCE(IXTRAD_MENU_MAINFRAME), + IMAGE_ICON, 0, 0, 0)); + SetIcon(xtrIcon, TRUE); +} + +void ExtStartPage::InitControls() { + releaseLog.SetFont(&XTROptions::App().fontTooltip); + releaseLog.SetWindowTextW(LoadLog()); + promtBtn.SetCheck(XTROptions::App().showStartPage); +} + +void ExtStartPage::InitTitle() { + auto title = ui::WindowText(*this); + title += g_Exteor.version.id; + SetWindowTextW(title); +} + +CString ExtStartPage::LoadLog() { + const auto fileName = g_Exteor.GetModuleFolder() + mfc::LoadSID(IXTRS_FILE_UPDATELOG); + FILE* fStream{}; + if (_wfopen_s(&fStream, fileName, LR"(r, ccs=UTF-8)") != 0) { + return mfc::LoadSID(IXTRE_LOG_NOT_FOUND); + } else { + CStdioFile logFile{ fStream }; + CString line{}; + CString text = line; + + logFile.SeekToBegin(); + while (logFile.ReadString(line)) { + text += line; + text += L"\r\n"; + } + logFile.Close(); + return text; + } +} + +void ExtStartPage::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + + ::DDX_Control(pDX, IXTRC_NEW_DOCUMENT, newDocBtn); + ::DDX_Control(pDX, IXTRC_OPEN_DOC, openDocBtn); + ::DDX_Control(pDX, IXTRC_START_HELP, helpBtn); + ::DDX_Control(pDX, IXTRC_CHANGE_LOG, releaseLog); + ::DDX_Control(pDX, IXTRC_DONT_PROMT, promtBtn); + ::DDX_Control(pDX, IXTRC_SAMPLES, examplesBtn); +} + +void ExtStartPage::OnNewDoc() { // NOLINT(readability-convert-member-functions-to-static) + EndDialog(IDOK); + g_Exteor.OnFileNew(); +} + +void ExtStartPage::OnOpenDoc() { // NOLINT(readability-convert-member-functions-to-static) + EndDialog(IDOK); + g_Exteor.OnFileOpen(); +} + +void ExtStartPage::OnOpenHelp() { // NOLINT(readability-convert-member-functions-to-static) + ui::HelpHandler::RunHelp(); +} + +void ExtStartPage::OnMemo() { // NOLINT(readability-convert-member-functions-to-static) + ::ShellExecuteW(nullptr, L"open", g_Exteor.GetModuleFolder() + mfc::LoadSID(IXTRS_FILE_FAQ), + nullptr, nullptr, SW_SHOWNORMAL); +} + +void ExtStartPage::OnSamples() { // NOLINT(readability-convert-member-functions-to-static) + EndDialog(IDOK); + CString path = g_Exteor.GetModuleFolder() + mfc::LoadSID(IXTRS_FOLDER_SAMPLES); + ::ShellExecuteW(nullptr, L"open", path, nullptr, nullptr, SW_SHOWNORMAL); +} + +void ExtStartPage::OnPromt() { // NOLINT(readability-convert-member-functions-to-static) + XTROptions::App().showStartPage = promtBtn.GetCheck(); +} + +} // namespace xtr::dialog \ No newline at end of file diff --git a/src/dialog/Term2Function.cpp b/src/dialog/Term2Function.cpp new file mode 100644 index 0000000..a88e524 --- /dev/null +++ b/src/dialog/Term2Function.cpp @@ -0,0 +1,244 @@ +#include "stdafx.h" + +#include "xtr/dialog/Term2Function.h" + +#include "resource.h" + +#include "xtr/ExteorOptions.h" +#include "xtr/cclDescriptor.h" + +#include "xtr/ui/HelpHandler.h" +#include "xtr/ui/KeyboardHandler.h" +#include "xtr/ui/UIHelper.h" + +#include "ccl/semantic/CstFilters.hpp" +#include "ccl/rslang/RSGenerator.h" +#include "ccl/rslang/RSExpr.h" + +namespace xtr::dialog { + +using ccl::semantic::CstType; + +struct Term2Function::Header : xtr::ui::Header { + enum Columns : uint8_t { + POS_NAME = 0, + POS_TYPE, + COLOUMN_COUNT + }; + + static constexpr auto widthName = 60; + static constexpr auto widthTypification = 250; + + Header() { + AddColumn({ IXTRS_HEADER_NAME, Alignment::left, widthName }); + AddColumn({ IXTRS_HEADER_TYPE, Alignment::left, widthTypification }); + } +}; + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(Term2Function, CDialog) + ON_CBN_SELCHANGE(IXTRC_TERM_CB, &ThisClass::OnSelchangeTermCb) + ON_BN_CLICKED(IXTRC_UPDATE_EXP, &ThisClass::OnBnClickedUpdateExp) + ON_BN_CLICKED(IXTRC_RIGHT, &ThisClass::OnBnClickedRight) + ON_BN_CLICKED(IXTRC_LEFT, &ThisClass::OnBnClickedLeft) + ON_BN_CLICKED(IXTRC_ADDFUNC, &ThisClass::OnBnClickedApply) + + ON_NOTIFY(NM_DBLCLK, IXTRC_GLOBAL_LIST, &ThisClass::OnDblClickGlobal) + ON_NOTIFY(NM_DBLCLK, IXTRC_ARG_LIST, &ThisClass::OnDblClickArg) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +Term2Function::Term2Function(doc::RSFacade& editor, const EntityUID startID, CWnd* pParent) + : CDialog(IXTRD_GENERATE_FUNC, pParent), editor{ editor } { + if (const auto& cst = editor.GetRS(startID); cst.type == CstType::term) { + cstName = mfc::ToMFC(cst.alias); + inputExpr = mfc::ToMFC(cst.definition); + } +} + +BOOL Term2Function::OnInitDialog() { + CDialog::OnInitDialog(); + + InitControls(); + InitHeaders(); + InitCstNameList(); + + UpdateData(FALSE); + return TRUE; +} + +void Term2Function::InitControls() { + inputCtrl.InitRE(ui::Keyboard::Layout::MATH, TRUE, TRUE); + expressionCtrl.InitRE(ui::Keyboard::Layout::MATH, TRUE, TRUE); + definitionCtrl.InitRE(ui::Keyboard::Layout::RUS); + definitionCtrl.SetFont(&XTROptions::App().fontText); +} + +void Term2Function::InitCstNameList() { + const auto selection = cstPicker.GetCurSel(); + cstPicker.ResetContent(); + for (const auto uid : ccl::semantic::FilterCst(editor.Core(), CstType::term)) { + cstPicker.AddString(mfc::ToMFC(editor.GetRS(uid).alias)); + } + cstPicker.SetCurSel(selection); +} + +void Term2Function::InitHeaders() { + static const Header listHeader{}; + ui::InitHeaderFor(globalsCtrl, listHeader); + ui::InitHeaderFor(argsCtrl, listHeader); +} + +void Term2Function::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + + ::DDX_Control(pDX, IXTRC_TERM_CB, cstPicker); + ::DDX_Control(pDX, IXTRC_EXPR_INPUT, inputCtrl); + ::DDX_Control(pDX, IXTRC_EXPR_OUTPUT, expressionCtrl); + ::DDX_Control(pDX, IXTRC_INTER, definitionCtrl); + ::DDX_Control(pDX, IXTRC_GLOBAL_LIST, globalsCtrl); + ::DDX_Control(pDX, IXTRC_ARG_LIST, argsCtrl); + + ::DDX_Text(pDX, IXTRC_EXPR_INPUT, inputExpr); + ::DDX_Text(pDX, IXTRC_EXPR_OUTPUT, expression); + ::DDX_Text(pDX, IXTRC_INTER, textRef); + ::DDX_CBString(pDX, IXTRC_TERM_CB, cstName); + + if (!pDX->m_bSaveAndValidate) { + UpdateUI(); + } +} + +BOOL Term2Function::PreTranslateMessage(MSG* pMsg) { + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_F1) { + ui::HelpHandler::RunHelp(ui::HelpID::generateCst); + return TRUE; + } + return CDialog::PreTranslateMessage(pMsg); +} + +void Term2Function::OnSelchangeTermCb() { + UpdateData(TRUE); + const auto uid = editor.Core().FindAlias(mfc::ToSTL(cstName)).value(); + inputExpr = mfc::ToMFC(editor.GetRS(uid).definition); + UpdateData(FALSE); +} + +void Term2Function::OnBnClickedUpdateExp() { + using ccl::rslang::Generator; + + UpdateData(TRUE); + if (argsCtrl.GetItemCount() == 0) { + ::AfxMessageBox(IXTRE_NO_ARGS, MB_ICONEXCLAMATION); + return; + } + std::vector args{}; + args.reserve(argsCtrl.GetItemCount()); + for (auto i = 0; i < argsCtrl.GetItemCount(); ++i) { + args.emplace_back(mfc::ToSTL(argsCtrl.GetItemText(i, Header::POS_NAME))); + } + expression = mfc::ToMFC(Generator(editor.Core().RSLang()).FunctionFromExpr(args, mfc::ToSTL(inputExpr))); + expressionCtrl.SetWindowTextW(expression); +} + +void Term2Function::OnOK() { + if (AddFunction().has_value()) { + CDialog::OnOK(); + } +} + +void Term2Function::OnBnClickedApply() { + if (const auto uid = AddFunction(); uid.has_value()) { + ::AfxMessageBox(mfc::FormatSID(IXTRS_TERMFUNC_SUCCESS, editor.GetRS(uid.value()).alias.c_str()), MB_OK | MB_ICONINFORMATION); + } +} + +void Term2Function::OnBnClickedRight() { + globalsCtrl.MoveSelectedItemsTo(argsCtrl, Header::COLOUMN_COUNT); +} + +void Term2Function::OnBnClickedLeft() { + argsCtrl.MoveSelectedItemsTo(globalsCtrl, Header::COLOUMN_COUNT); +} + +void Term2Function::OnDblClickGlobal(NMHDR* /*pNMHDR*/, LRESULT* pResult) { + OnBnClickedRight(); + *pResult = TRUE; +} + +void Term2Function::OnDblClickArg(NMHDR* /*pNMHDR*/, LRESULT* pResult) { + OnBnClickedLeft(); + *pResult = TRUE; +} + +std::optional Term2Function::AddFunction() { + UpdateData(TRUE); + if (expression.IsEmpty()) { + ::AfxMessageBox(IXTRE_FUNC2TERM, MB_OK | MB_ICONEXCLAMATION); + expressionCtrl.SetActiveWindow(); + return std::nullopt; + } + + const auto convention = mfc::ToSTL(mfc::FormatSID(IXTRS_TERMFUNC_FROM_TERM, cstName.GetString())); + const auto uid = editor.Emplace(CstType::function, mfc::ToSTL(expressionCtrl.Text())); + editor.SetDefinitionFor(uid, mfc::ToSTL(definitionCtrl.Text())); + editor.SetConventionFor(uid, convention); + addedCst.emplace_back(uid); + + textRef.Empty(); + expression.Empty(); + argsCtrl.DeleteAllItems(); + + UpdateData(FALSE); + return uid; +} + +void Term2Function::UpdateUI() { + InputGlobals(); + UpdateArgs(); + inputCtrl.UpdateFormat(); +} + +void Term2Function::InputGlobals() { + globalsCtrl.DeleteAllItems(); + const auto cstFromExpr = ccl::rslang::ExtractUGlobals(mfc::ToSTL(inputExpr)); + SetOfEntities entities{}; + entities.reserve(size(cstFromExpr)); + for (const auto& name : cstFromExpr) { + if (auto uid = editor.Core().FindAlias(name); uid.has_value()) { + entities.emplace(uid.value()); + } + } + const auto sortedCst = editor.List().SortSubset(entities); + auto line = 0; + for (const auto uid : sortedCst) { + const auto& cst = editor.GetRS(uid); + if (const auto type = cst.type; type == CstType::structured || type == CstType::term) { + auto typification = mfc::ToSTL(info::Label(editor.GetParse(uid).TypePtr())); + globalsCtrl.InsertItem(line, mfc::ToMFC(cst.alias)); + globalsCtrl.SetItemText(line, Header::POS_TYPE, mfc::ToMFC(typification)); + ++line; + } + } +} + +void Term2Function::UpdateArgs() { + LVFINDINFOW info{}; + info.flags = LVFI_STRING; + for (auto i = 0; i < argsCtrl.GetItemCount(); ++i) { + auto name = argsCtrl.GetItemText(i, 0); + info.psz = name; + + if (const auto findItem = globalsCtrl.FindItem(&info); findItem == mfc::noItems) { + argsCtrl.DeleteItem(i); + i = i == 0 ? i : i - 1; + } else { + globalsCtrl.DeleteItem(findItem); + } + } +} + +} // namespace xtr::dialog \ No newline at end of file diff --git a/src/dialog/TerminRefDlg.cpp b/src/dialog/TerminRefDlg.cpp new file mode 100644 index 0000000..ebea896 --- /dev/null +++ b/src/dialog/TerminRefDlg.cpp @@ -0,0 +1,320 @@ +#include "stdafx.h" + +#include "xtr/dialog/TerminRefDlg.h" + +#include "resource.h" + +#include "xtr/ExteorOptions.h" +#include "xtr/cclDescriptor.h" + +#include "xtr/ui/UIHelper.h" + +namespace xtr::dialog { + +using ccl::lang::Morphology; +using ccl::lang::Grammem; +using ccl::lang::Reference; +using ccl::lang::EntityRef; + +TerminRefDlg::TerminRefDlg(doc::RSFacade& editor, CPoint position, + const CString selection, CWnd* pParent) + : CDialog(IXTRD_AUTOCOMPLETE, pParent), + position{ position }, initialText{ selection }, editor{ editor } {} + +void TerminRefDlg::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + + ::DDX_Control(pDX, IXTRC_AC_LIST1, singForms); + ::DDX_Control(pDX, IXTRC_AC_LIST2, plurForms); + ::DDX_Control(pDX, IXTRC_AC_LABELSLIST, captionList); +} + +BOOL TerminRefDlg::OnInitDialog() { + CDialog::OnInitDialog(); + + UpdateContextNameList(); + + singForms.SetFont(&XTROptions::App().fontText); + plurForms.SetFont(&XTROptions::App().fontText); + captionList.SetFont(&XTROptions::App().fontText); + + if (singForms.GetCount() == 0) { + ::AfxMessageBox(IXRE_EMPTY_TERMS, MB_ICONERROR); + OnCancel(); + } else { + singForms.SetCurSel(0); + SetPositionAndSize(); + state = ACS_TERMS; + } + return TRUE; +} + +void TerminRefDlg::UpdateContextNameList() { + singForms.ResetContent(); + entities.clear(); + const auto inputs = editor.Texts().Context().MatchingTerms(mfc::ToSTL(initialText)); + CString listItem{}; + for (const auto uid : editor.Core().List()) { + const auto& alias = editor.Core().GetText(uid).alias; + if (inputs.contains(alias)) { + const auto& title = inputs.at(alias); + entities.emplace_back(alias); + listItem = mfc::ToMFC(alias); + listItem += L": "; + listItem += mfc::ToMFC(title); + singForms.AddString(listItem); + } + } +} + +BOOL TerminRefDlg::PreTranslateMessage(MSG* pMsg) { + if (pMsg->hwnd != singForms.GetSafeHwnd() && pMsg->hwnd != plurForms.GetSafeHwnd()) { + return CDialog::PreTranslateMessage(pMsg); + } + + const auto selectedSing = pMsg->hwnd == singForms.GetSafeHwnd() ? TRUE : FALSE; + const auto selection = selectedSing ? singForms.GetCurSel() : plurForms.GetCurSel(); + const auto plurality = selectedSing ? Grammem::sing : Grammem::plur; + + CListBox* selectedCListBox = selectedSing ? &singForms : &plurForms; + CListBox* unselectedCListBox = selectedSing ? &plurForms : &singForms; + + switch (state) { + case ACS_TERMS: { + if (pMsg->message == WM_LBUTTONDBLCLK || + (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)) { + SelectTermRef(); + return TRUE; + } + break; + } + case ACS_WORDFORMS: { + if (pMsg->message == WM_LBUTTONDOWN) { + unselectedCListBox->SetCurSel(mfc::noItems); + } + if (pMsg->message == WM_LBUTTONDBLCLK) { + SelectTermForm(selection, plurality); + return TRUE; + } else if (pMsg->message != WM_KEYDOWN) { + return CDialog::PreTranslateMessage(pMsg); + } + + switch (pMsg->wParam) { + case VK_RETURN: + SelectTermForm(selection, plurality); + [[fallthrough]]; + case VK_TAB: + return TRUE; + + case VK_F2: + ChangeTermForm(selectedCListBox, plurality); + return TRUE; + + case VK_LEFT: case VK_RIGHT: { + const auto selectedLeftKey = pMsg->wParam == VK_LEFT ? TRUE : FALSE; + if ((selectedSing && !selectedLeftKey) || (!selectedSing && selectedLeftKey)) { + selectedCListBox->SetCurSel(mfc::noItems); + unselectedCListBox->SetFocus(); + unselectedCListBox->SetCurSel(selection); + } + return TRUE; + } + + case '1': case '2': case '3': case '4': case '5': case '6': { + const auto number = static_cast(pMsg->wParam - '1'); + selectedCListBox->SetCurSel(number); + break; + } + } + } + } + return CDialog::PreTranslateMessage(pMsg); +} + +void TerminRefDlg::SelectTermRef() { + cstName = entities.at(singForms.GetCurSel()); + const auto* chosenTermin = editor.Texts().Context().At(cstName); + if (chosenTermin == nullptr) { + ::AfxMessageBox(IXTRE_TERMIN_INDEX, MB_ICONEXCLAMATION); + return; + } + singForms.ResetContent(); + plurForms.ResetContent(); + captionList.ResetContent(); + + for (uint8_t i = 0; i < ssize(ccl::lang::ALL_CASES); ++i) { + const auto rcase = ccl::lang::ALL_CASES.at(i); + singForms.AddString(mfc::ToMFC(chosenTermin->GetForm(Morphology{ Grammem::sing, rcase }))); + plurForms.AddString(mfc::ToMFC(chosenTermin->GetForm(Morphology{ Grammem::plur, rcase }))); + captionList.AddString(info::DescriptionOf(rcase)); + } + + singForms.SetCurSel(0); + singForms.SetFocus(); + + SetPositionAndSize(TRUE); + state = ACS_WORDFORMS; +} + +void TerminRefDlg::SelectTermForm(const int32_t selection, const Grammem plurality) { + termForm = Morphology{ ccl::lang::ALL_CASES.at(selection), plurality }; + OnOK(); +} + +void TerminRefDlg::ChangeTermForm(CListBox* selectedCListBox, const Grammem plurality) { + const auto* termin = editor.Texts().Context().At(cstName); + if (termin == nullptr) { + ::AfxMessageBox(IXTRE_TERMIN_INDEX, MB_ICONERROR); + return; + } + const auto curSel = selectedCListBox->GetCurSel(); + const auto rcase = ccl::lang::ALL_CASES.at(curSel); + const auto form = Morphology{ plurality, rcase }; + const auto& curCstTermForm = termin->GetForm(form); + + const auto listRect = ui::WindowRect(*selectedCListBox); + CRect dlgRect{}; + selectedCListBox->GetItemRect(curSel, &dlgRect); + dlgRect.left += listRect.left; + dlgRect.right += listRect.left; + dlgRect.top += listRect.top; + dlgRect.bottom += listRect.top + 4; // 2bx border from both sides + + TermFormDlg renameDlg{ mfc::ToMFC(curCstTermForm), dlgRect }; + if (renameDlg.DoModal() != IDOK) { + return; + } + auto newCstTermForm = mfc::ToSTL(renameDlg.termFormText); + if (curCstTermForm == newCstTermForm) { + return; + } + + const auto uid = editor.Core().FindAlias(cstName).value(); + editor.SetTermFormFor(uid, newCstTermForm, form); + if (curSel != 0) { + selectedCListBox->DeleteString(curSel); + selectedCListBox->InsertString(curSel, mfc::ToMFC(termin->GetForm(form))); + } else { + selectedCListBox->ResetContent(); + for (auto i = 0; i < ssize(ccl::lang::ALL_CASES); ++i) { + selectedCListBox->AddString(mfc::ToMFC(termin->GetForm(Morphology{ plurality, ccl::lang::ALL_CASES.at(i) }))); + } + } + selectedCListBox->SetCurSel(curSel); + SetPositionAndSize(TRUE); +} + +void TerminRefDlg::SetPositionAndSize(BOOL fitBoth) { + static constexpr auto widthMax = 250; + static constexpr auto TEXT_BORDER = 5; + + auto h = 0; + auto width1 = 0; + auto width2 = 0; + auto width3 = 0; + CString str{}; + CSize sz{}; + + auto* pDC1 = singForms.GetDC(); + pDC1->SelectObject(singForms.GetFont()); + + auto* pDC2 = plurForms.GetDC(); + pDC2->SelectObject(plurForms.GetFont()); + + auto* pDC3 = captionList.GetDC(); + pDC3->SelectObject(captionList.GetFont()); + + for (auto i = 0; i < singForms.GetCount(); ++i) { + if (i < 10) { + h += singForms.GetItemHeight(i); + } + + singForms.GetText(i, str); + sz = pDC1->GetTextExtent(str); + if (sz.cx > width1) { + width1 = sz.cx; + } + if (fitBoth) { + plurForms.GetText(i, str); + sz = pDC2->GetTextExtent(str); + if (sz.cx > width2) { + width2 = sz.cx; + } + captionList.GetText(i, str); + sz = pDC3->GetTextExtent(str); + if (sz.cx > width3) { + width3 = sz.cx; + } + } + } + singForms.ReleaseDC(pDC1); + plurForms.ReleaseDC(pDC2); + + width1 = std::min(width1 + TEXT_BORDER, widthMax) + GetSystemMetrics(SM_CXVSCROLL); + width2 = std::min(width2 + TEXT_BORDER, widthMax) + GetSystemMetrics(SM_CXVSCROLL); + width3 = std::min(width3 + TEXT_BORDER, widthMax) + GetSystemMetrics(SM_CXVSCROLL); + + h += 4; // 2px border from both sides + + if (!fitBoth) { + SetWindowPos(nullptr, position.x, position.y, width1, h, SWP_SHOWWINDOW); + singForms.SetWindowPos(&wndTop, 0, 0, width1, h, SWP_SHOWWINDOW); + singForms.SetColumnWidth(width1); + plurForms.SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_HIDEWINDOW); + captionList.SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_HIDEWINDOW); + } else { + SetWindowPos(nullptr, position.x, position.y, width1 + width2 + width3 - 2, h, SWP_SHOWWINDOW); + singForms.SetWindowPos(&wndTop, 0, 0, width1, h, SWP_SHOWWINDOW); + singForms.SetColumnWidth(width1); + plurForms.SetWindowPos(&wndTop, width1 - 2, 0, width2, h, SWP_SHOWWINDOW); + plurForms.SetColumnWidth(width2); + captionList.SetWindowPos(&wndTop, width1 + width2 - 2, 0, width3, h, SWP_SHOWWINDOW); + } +} + +Reference TerminRefDlg::CreateRef() const { + return Reference{ EntityRef{ cstName, termForm } }; +} + +TermFormDlg::TermFormDlg(const CString initText, RECT position, CWnd* pParent) + : CDialog(IXTRD_CST_CHANGE_TERM_FORM, pParent), termFormText{ initText }, position{ position } {} + +BOOL TermFormDlg::OnInitDialog() { + CDialog::OnInitDialog(); + + textControl.SetSel(0, 1); + SetPositionAndSize(); + return TRUE; +} + +void TermFormDlg::DoDataExchange(CDataExchange* pDX) { + CDialog::DoDataExchange(pDX); + + ::DDX_Control(pDX, IXTRC_CST_TERM_FORM_EDIT, textControl); + ::DDX_Text(pDX, IXTRC_CST_TERM_FORM_EDIT, termFormText); +} + +BOOL TermFormDlg::PreTranslateMessage(MSG* pMsg) { + if (pMsg->message == WM_KEYDOWN && + pMsg->hwnd == textControl.GetSafeHwnd() && + pMsg->wParam == VK_RETURN) { + OnOK(); + return TRUE; + } else { + return CDialog::PreTranslateMessage(pMsg); + } +} + +void TermFormDlg::SetPositionAndSize() { + SetWindowPos(nullptr, position.left, position.top, + position.right - position.left, + position.bottom - position.top, + SWP_SHOWWINDOW); + + textControl.SetWindowPos(&wndTop, 0, 0, + position.right - position.left, + position.bottom - position.top, + SWP_SHOWWINDOW); +} + +} // namespace xtr::dialog \ No newline at end of file diff --git a/src/dialog/WordRefDlg.cpp b/src/dialog/WordRefDlg.cpp new file mode 100644 index 0000000..1d2efeb --- /dev/null +++ b/src/dialog/WordRefDlg.cpp @@ -0,0 +1,128 @@ +#include "stdafx.h" + +#include "xtr/dialog/WordRefDlg.h" + +#include "resource.h" + +#include "xtr/Exteor.h" + +namespace xtr::dialog { + +using ccl::lang::CollaborationRef; +using ccl::lang::Reference; + +WordRefDlg::WordRefDlg(RECT position, const CString selection, CWnd* pParent) + : CDialog(IXTRD_CST_SET_CHANGING_WORD_TEXT, pParent), + position{ position }, dependantWord{ selection } {} + +BOOL WordRefDlg::OnInitDialog() { + CDialog::OnInitDialog(); + + SetPositionAndSize(); + if (!dependantWord.IsEmpty()) { + SelectOffset(); + } + return TRUE; +} + +void WordRefDlg::DoDataExchange(CDataExchange* pDX) { + ::DDX_Control(pDX, IXTRC_SET_WORDREF_EDIT, textControl); + ::DDX_Text(pDX, IXTRC_SET_WORDREF_EDIT, dependantWord); +} + +BOOL WordRefDlg::PreTranslateMessage(MSG* pMsg) { + if (pMsg->message == WM_KEYDOWN) { + if (pMsg->hwnd == textControl.GetSafeHwnd() && pMsg->wParam == VK_RETURN) { + UpdateData(TRUE); + if (dependantWord.IsEmpty()) { + ::AfxMessageBox(IXTRS_INPUT_WORD, MB_ICONEXCLAMATION); + } else { + SelectOffset(); + } + return TRUE; + } + } + return CDialog::PreTranslateMessage(pMsg); +} + +Reference WordRefDlg::CreateRef() const { + return Reference{ CollaborationRef{ mfc::ToSTL(dependantWord), offset } }; +} + +void WordRefDlg::SetPositionAndSize() { + SetWindowPos(nullptr, position.left, position.top, position.right - position.left, position.bottom - position.top, SWP_SHOWWINDOW); + textControl.SetWindowPos(&wndTop, 0, 0, position.right - position.left, position.bottom - position.top, SWP_SHOWWINDOW); +} + +void WordRefDlg::SelectOffset() { + constexpr auto DEFAULT_POSITION_OFFSET = 50; + const auto oldPosition = position; + + position.right = position.left + DEFAULT_POSITION_OFFSET; + SetPositionAndSize(); + + RefOffsetDlg shiftDlg{ position }; + const auto result = shiftDlg.DoModal(); + + position = oldPosition; + SetPositionAndSize(); + + if (result == IDOK) { + offset = shiftDlg.offset; + OnOK(); + } +} + +RefOffsetDlg::RefOffsetDlg(RECT position, CWnd* pParent) + : CDialog(IXTRD_CST_SET_CHANGING_WORD_REF, pParent), position{ position } {} + +BOOL RefOffsetDlg::OnInitDialog() { + CDialog::OnInitDialog(); + + SetPositionAndSize(); + return TRUE; +} + +void RefOffsetDlg::SetPositionAndSize() { + SetWindowPos(nullptr, position.left, position.top, position.right - position.left, position.bottom - position.top, SWP_SHOWWINDOW); + textControl.SetWindowPos(&wndTop, 0, 0, position.right - position.left, position.bottom - position.top, 0); +} + +void RefOffsetDlg::DoDataExchange(CDataExchange* pDX) { + ::DDX_Control(pDX, IXTRC_WORDREF_CONTROL, textControl); + ::DDX_Text(pDX, IXTRC_WORDREF_CONTROL, offsetText); +} + +BOOL RefOffsetDlg::PreTranslateMessage(MSG* pMsg) { + if (pMsg->message != WM_KEYDOWN) { + return CDialog::PreTranslateMessage(pMsg); + } else if (pMsg->wParam == VK_RETURN) { + OnOK(); + return TRUE; + } else if (pMsg->wParam != VK_RIGHT && pMsg->wParam != VK_LEFT){ + return CDialog::PreTranslateMessage(pMsg); + } else { + UpdateOffset(pMsg->wParam == VK_LEFT); + return TRUE; + } +} + +void RefOffsetDlg::UpdateOffset(const BOOL decrease) { + if (decrease) { + offset = offset == 1 ? -1 : offset - 1; + } else { + offset = offset == -1 ? 1 : offset + 1; + } + offsetText.Format(LR"(%d)", offset); + UpdateData(FALSE); +} + +void RefOffsetDlg::OnOK() { + if (offset == 0) { + ::AfxMessageBox(IXTRS_PICK_REF, MB_ICONINFORMATION); + } else { + CDialog::OnOK(); + } +} + +} // namespace xtr::dialog \ No newline at end of file diff --git a/src/doc/DocumentManager.cpp b/src/doc/DocumentManager.cpp new file mode 100644 index 0000000..dbd6a8f --- /dev/null +++ b/src/doc/DocumentManager.cpp @@ -0,0 +1,177 @@ +#include "stdafx.h" + +#include "xtr/doc/DocumentManager.h" + +#include "resource.h" + +#include "xtr/Exteor.h" +#include "xtr/doc/OSSDoc.h" +#include "xtr/doc/RSFormDoc.h" +#include "xtr/doc/RSModelDoc.h" + +#include "xtr/ui/SplitterFrame.h" + +#include "xtr/view/RSFormView.h" +#include "xtr/view/RSModelView.h" +#include "xtr/view/OSSView.h" + +#include "xtr/dialog/NewDocument.h" + +namespace xtr::doc { + +using ccl::semantic::RSForm; +using ccl::semantic::RSModel; + +BOOL DocumentManager::Initialize() { + m_RSFormTemplate = new CMultiDocTemplate( // NOLINT(cppcoreguidelines-owning-memory) + IXTRAD_MENU_RSFORM, + RUNTIME_CLASS(doc::RSFormDoc), + RUNTIME_CLASS(ui::RSFormFrame), + RUNTIME_CLASS(view::RSFormView)); + assert(m_RSFormTemplate); + exteor.AddDocTemplate(m_RSFormTemplate); + + m_RSModelTemplate = new CMultiDocTemplate( // NOLINT(cppcoreguidelines-owning-memory) + IXTRAD_MENU_RSMODEL, + RUNTIME_CLASS(doc::RSModelDoc), + RUNTIME_CLASS(ui::RSModelFrame), + RUNTIME_CLASS(view::RSModelView)); + assert(m_RSModelTemplate); + exteor.AddDocTemplate(m_RSModelTemplate); + + m_OSSTemplate = new CMultiDocTemplate( // NOLINT(cppcoreguidelines-owning-memory) + IXTRAD_MENU_OSS, + RUNTIME_CLASS(doc::OSSDoc), + RUNTIME_CLASS(ui::OSSFrame), + RUNTIME_CLASS(view::OSSView)); + assert(m_OSSTemplate); + exteor.AddDocTemplate(m_OSSTemplate); + + return TRUE; +} + +std::vector DocumentManager::RSFormList() const { + std::vector result{}; + auto* pos = m_RSFormTemplate->GetFirstDocPosition(); + while(pos != nullptr) { + auto* doc = dynamic_cast(m_RSFormTemplate->GetNextDoc(pos)); + if (doc != nullptr) { + result.emplace_back(&doc->Schema()); + } + } + return result; +} + +std::vector DocumentManager::RSModelList() const { + std::vector result{}; + auto* pos = m_RSModelTemplate->GetFirstDocPosition(); + while(pos != nullptr) { + auto* doc = dynamic_cast(m_RSModelTemplate->GetNextDoc(pos)); + if (doc != nullptr) { + result.emplace_back(&doc->Model()); + } + } + return result; +} + +std::vector DocumentManager::RSFormDocList() const { + std::vector result{}; + auto* pos = m_RSFormTemplate->GetFirstDocPosition(); + while(pos != nullptr) { + const auto* doc = dynamic_cast(m_RSFormTemplate->GetNextDoc(pos)); + if (doc != nullptr) { + result.emplace_back(doc); + } + } + return result; +} + +doc::RSFormDoc* DocumentManager::FindRSDocByPath(const CString path) { + auto* pos = m_RSFormTemplate->GetFirstDocPosition(); + while(pos != nullptr) { + auto* doc = dynamic_cast(m_RSFormTemplate->GetNextDoc(pos)); + if (doc->GetPathName().CompareNoCase(path) == 0) { + return doc; + } + } + return nullptr; +} + +void DocumentManager::ShowDocument(doc::XTRDocument& doc) { + auto* pos = doc.GetFirstViewPosition(); + if (const auto* view = doc.GetNextView(pos); view != nullptr) { + doc.UpdateAllViews(nullptr); + view->GetParentFrame()->ActivateFrame(SW_RESTORE); + } else if (CreateViewFor(doc)) { + ShowDocument(doc); + } +} + +BOOL DocumentManager::CreateViewFor(doc::XTRDocument& doc) { + if (const auto* rsDoc = dynamic_cast(&doc); rsDoc == nullptr) { + return false; + } else if (auto* frame = m_RSFormTemplate->CreateNewFrame(&doc, nullptr); frame == nullptr) { + ::AfxMessageBox(IXTRE_DOC_FRAME, MB_ICONERROR); + return false; + } else { + m_RSFormTemplate->InitialUpdateFrame(frame, &doc); + return true; + } +} + +doc::RSFormDoc* DocumentManager::NewRSFormDoc(const RSForm& schema, BOOL noView) { + auto* result = NewRSFormDoc(noView); + if (result != nullptr) { + const std::string newFull = result->Schema().title; + const std::string newShort = result->Schema().alias; + const std::string newComment = result->Schema().comment; + + result->Schema() = schema; + if (!std::empty(newFull) || !std::empty(newShort) || !std::empty(newComment)) { + result->Schema().title = newFull; + result->Schema().alias = newShort; + result->Schema().comment = newComment; + } + result->UpdateAllViews(nullptr); + } + return result; +} + +doc::RSFormDoc* DocumentManager::NewRSFormDoc(BOOL noView) { + return dynamic_cast(NewDoc(*m_RSFormTemplate, noView)); +} + +doc::RSModelDoc* DocumentManager::NewRSModelDoc(BOOL noView) { + return dynamic_cast(NewDoc(*m_RSModelTemplate, noView)); +} + +doc::OSSDoc* DocumentManager::NewOSSDoc(BOOL noView) { + return dynamic_cast(NewDoc(*m_OSSTemplate, noView)); +} + +CDocument* DocumentManager::NewDoc(CMultiDocTemplate& templ, BOOL noView) { + if (noView) { + return templ.CreateNewDocument(); + } else { + return templ.OpenDocumentFile({}); + } +} + +doc::RSFormDoc* DocumentManager::OpenRSFormDoc(const CString path, BOOL noView /*= FALSE*/) { + return dynamic_cast(OpenDoc(*m_RSFormTemplate, path, noView)); +} + +CDocument* DocumentManager::OpenDoc(CMultiDocTemplate& templ, const CString path, BOOL noView) { + if (!noView) { + return templ.OpenDocumentFile(path); + } else { + std::unique_ptr result{ templ.CreateNewDocument() }; + if (result->OnOpenDocument(path)) { + return result.release(); + } else { + return nullptr; + } + } +} + +} // namespace xtr::doc \ No newline at end of file diff --git a/src/doc/Documents.cpp b/src/doc/Documents.cpp new file mode 100644 index 0000000..e89fb60 --- /dev/null +++ b/src/doc/Documents.cpp @@ -0,0 +1,20 @@ +#include "stdafx.h" + +#include "xtr/doc/Documents.h" + +namespace xtr::doc { + +void XTRDocument::SetModifiedFlag(const BOOL modified) { + if (IsModified() != modified) { + CDocument::SetModifiedFlag(modified); + + const auto& curTitle = GetTitle(); + if (modified) { + SetTitle(curTitle + "*"); + } else { + SetTitle(curTitle.Left(curTitle.GetLength() - 1)); + } + } +} + +} // namespace xtr::doc \ No newline at end of file diff --git a/src/doc/FileTypes.cpp b/src/doc/FileTypes.cpp new file mode 100644 index 0000000..bcd3e1f --- /dev/null +++ b/src/doc/FileTypes.cpp @@ -0,0 +1,20 @@ +#include "stdafx.h" + +#include "xtr/doc/FileTypes.h" + +namespace xtr { + +CString ExtensionFor(const FileType type) { + static const std::unordered_map extension = { + { FileType::trs, LR"(.trs)" }, { FileType::rsm, LR"(.rsm)" }, { FileType::oss, LR"(.oss)" }, + { FileType::json, LR"(.json)" }, { FileType::docx, LR"(.docx)" }, { FileType::csv, LR"(.csv)" }, + { FileType::txt, LR"(.txt)" }, { FileType::xlsx, LR"(.xlsx)" }, { FileType::png, LR"(.png)" }, + }; + if (!extension.contains(type)) { + return {}; + } else { + return extension.at(type); + } +} + +} // namespace xtr \ No newline at end of file diff --git a/src/doc/OSSDoc.cpp b/src/doc/OSSDoc.cpp new file mode 100644 index 0000000..e877963 --- /dev/null +++ b/src/doc/OSSDoc.cpp @@ -0,0 +1,179 @@ +#include "stdafx.h" + +#include "xtr/doc/OSSDoc.h" + +#include "resource.h" + +#include "xtr/Exteor.h" +#include "xtr/io/OSSLegacyLoader.h" +#include "xtr/doc/RSFormDoc.h" + +#include "xtr/dialog/NewDocument.h" + +using ccl::oss::PictID; +using ccl::oss::OSSchema; + +namespace xtr::doc { + +#pragma warning( push ) +#pragma warning( disable : 26440 26443 ) + +IMPLEMENT_DYNCREATE(OSSDoc, CDocument) + +BEGIN_MESSAGE_MAP(OSSDoc, CDocument) + ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_AS, &ThisClass::OnUpdateFileSaveAs) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +OSSDoc::OSSDoc() { + oss = std::make_unique(); + oss->AddObserver(*this); +} + +OSSDoc::~OSSDoc() { + oss->RemoveObserver(*this); +} + +void OSSDoc::OnObserve(const ccl::types::Message& change) { + if (const auto* erasePtr = dynamic_cast(&change); erasePtr != nullptr) { + if (erasePtr->pid == selection) { + if (!std::empty(*oss)) { + selection = std::begin(*oss)->uid; + } + } + SetModifiedFlag(TRUE); + } else if (const auto* srcChange = dynamic_cast(&change); srcChange != nullptr) { + SetModifiedFlag(TRUE); + } else if (const auto* srcStatus = dynamic_cast(&change); srcStatus != nullptr) { + const auto* mainWindow = ::AfxGetMainWnd(); + if (mainWindow != nullptr && mainWindow->IsWindowVisible()) { // Note: do not call UpdateViews on closed application + UpdateAllViews(nullptr); + } + } else { + SetModifiedFlag(TRUE); + } +} + +BOOL OSSDoc::OnNewDocument() { + dialog::NewOSS dialog{}; + if (dialog.DoModal() == IDOK) { + oss->title = mfc::ToSTL(dialog.ossName); + selection = oss->InsertBase()->uid; + oss->InsertBase(); + if (CDocument::OnNewDocument()) { + auto path = dialog.fullPath + + (dialog.fullPath[dialog.fullPath.GetLength() - 1] == '\\' ? "" : "\\"); + path += mfc::ToMFC(std::filesystem::path(mfc::ToUTF8(dialog.ossName)).replace_extension(ExtensionFor(FileType::oss).GetString()).u8string()); + + SetPathName(path, FALSE); + if (DoFileSave()) { + oss->Src().ossDomain = std::filesystem::path(mfc::ToUTF8(GetPathName())).parent_path().u8string(); + return TRUE; + } else { + ::AfxMessageBox(IXTRE_OSS_NOTSAVED, MB_ICONEXCLAMATION); + } + } + } + return FALSE; +} + +BOOL OSSDoc::OnOpenDocument(LPCTSTR path) { + if (CString(path).Right(4).MakeLower() != ExtensionFor(FileType::oss)) { + return FALSE; + } + if (!LoadJSON(mfc::ToUTF8(path)) + && !CDocument::OnOpenDocument(path)) { + return FALSE; + } + SetPathName(path, FALSE); + oss->Src().ossDomain = std::filesystem::path(mfc::ToUTF8(GetPathName())).parent_path().u8string(); + return TRUE; +} + +BOOL OSSDoc::OnSaveDocument(LPCTSTR path) { + SaveAllDocs(); + if (!SaveJSON(mfc::ToUTF8(path))) { + return FALSE; + } + SetPathName(path, FALSE); + SetModifiedFlag(FALSE); + return TRUE; +} + + +void OSSDoc::OnUpdateFileSaveAs(CCmdUI *pCmdUI) { // NOLINT(readability-convert-member-functions-to-static) + pCmdUI->Enable(FALSE); +} + +void OSSDoc::Serialize(CArchive& ar) { + MFCSerializable::Serialize(ar); +} + +BOOL OSSDoc::CanCloseFrame(CFrameWnd* pFrame) { + if (!CDocument::CanCloseFrame(pFrame)) { + return FALSE; + } + + if (::_wchdir(mfc::ToMFC(oss->Src().ossDomain)) != 0) { + TRACE(LR"(Unable to set browse directory!)"); + } + for (const auto& pict : *oss) { + auto* src = dynamic_cast(oss->Src()(pict.uid)->src); + if (src == nullptr || !src->IsModified() || std::empty(*oss->Src()(pict.uid))) { + continue; + } + switch (::AfxMessageBox(mfc::FormatSID(IXTRE_OSS_SAVE_PICT, mfc::ToMFC(pict.title).GetString()), + MB_YESNOCANCEL | MB_ICONQUESTION | MB_DEFBUTTON1)) { + case IDYES: { + src->DoFileSave(); + SetModifiedFlag(TRUE); + break; + } + case IDNO: continue; + case IDCANCEL: return FALSE; + } + } + return TRUE; +} + +void OSSDoc::SaveAllDocs() { + for (const auto& pict : *oss) { + if (auto* doc = dynamic_cast(oss->Src().ActiveSrc(pict.uid)); + doc != nullptr && doc->IsModified()) { + doc->DoFileSave(); + } + } +} + +JSON OSSDoc::ExtractData() const { + auto result = JSON(*oss); + result["selection"] = selection; + return result; +} + +bool OSSDoc::LoadData(const JSON& object) { + [[maybe_unused]] const auto noObserving = DndGuard(); + object.get_to(*oss); + object.at("selection").get_to(selection); + if (!OSS().Contains(selection)) { + selection = std::begin(OSS())->uid; + } + oss->Src().ReconnectAll(); + return true; +} + +bool OSSDoc::LegacyLoad(io::CArchiveAdapter& archive) { + [[maybe_unused]] const auto noObserving = DndGuard(); + auto loader = io::OSSLegacyLoader{ archive, *oss }; + loader.LoadVersion(); + loader.DoLoad(); + selection = loader.selection; + if (!OSS().Contains(selection)) { + selection = std::begin(OSS())->uid; + } + oss->Src().ReconnectAll(); + return true; +} + +} // namespace xtr::doc \ No newline at end of file diff --git a/src/doc/RSFacade.cpp b/src/doc/RSFacade.cpp new file mode 100644 index 0000000..91f24a7 --- /dev/null +++ b/src/doc/RSFacade.cpp @@ -0,0 +1,197 @@ +#include "stdafx.h" + +#include "xtr/doc/RSFacade.h" + +namespace xtr::doc { + +using ccl::semantic::RSCore; +using ccl::semantic::RSForm; +using ccl::semantic::RSModel; +using ccl::semantic::ConceptRecord; +using ccl::semantic::RSConcept; +using ccl::semantic::TextConcept; +using ccl::semantic::ParsingInfo; +using ccl::semantic::ListIterator; +using ccl::semantic::CstType; + +SelectableDoc& RSFacade::Document() noexcept { + if (isModel) { + return *modelDoc; + } else { + return *schemaDoc; + } +} + +const RSCore& RSFacade::Core() const noexcept { + if (isModel) { + return modelDoc->Model().Core(); + } else { + return schemaDoc->Schema().Core(); + } +} + +RSForm& RSFacade::EditSchema() noexcept { + assert(!isModel); + return schemaDoc->Schema(); +} + +const RSForm& RSFacade::Schema() const noexcept { + assert(!isModel); + return schemaDoc->Schema(); +} + +RSModel& RSFacade::EditModel() noexcept { + assert(isModel); + return modelDoc->Model(); +} + +const RSModel& RSFacade::Model() const noexcept { + assert(isModel); + return modelDoc->Model(); +} + +const ccl::semantic::Thesaurus& RSFacade::Texts() const noexcept { + if (isModel) { + return modelDoc->Model().Texts(); + } else { + return schemaDoc->Schema().Texts(); + } +} + +const ccl::semantic::Schema& RSFacade::RSLang() const noexcept { + if (isModel) { + return modelDoc->Model().RSLang(); + } else { + return schemaDoc->Schema().RSLang(); + } +} + +const ccl::semantic::CstList& RSFacade::List() const noexcept { + if (isModel) { + return modelDoc->Model().List(); + } else { + return schemaDoc->Schema().List(); + } +} + +bool RSFacade::Contains(const EntityUID entity) const { + if (isModel) { + return modelDoc->Model().Contains(entity); + } else { + return schemaDoc->Schema().Contains(entity); + } +} + +const RSConcept& RSFacade::GetRS(const EntityUID entity) const { + if (isModel) { + return modelDoc->Model().GetRS(entity); + } else { + return schemaDoc->Schema().GetRS(entity); + } +} + +const TextConcept& RSFacade::GetText(const EntityUID entity) const { + if (isModel) { + return modelDoc->Model().GetText(entity); + } else { + return schemaDoc->Schema().GetText(entity); + } +} + +const ParsingInfo& RSFacade::GetParse(const EntityUID entity) const { + if (isModel) { + return modelDoc->Model().GetParse(entity); + } else { + return schemaDoc->Schema().GetParse(entity); + } +} + +void RSFacade::SetComment(const std::string& newComment) { + if (isModel) { + modelDoc->Model().comment = newComment; + } else { + schemaDoc->Schema().comment = newComment; + } +} + +bool RSFacade::SetExpressionFor(const EntityUID target, const std::string& expression) { + if (isModel) { + return modelDoc->Model().SetExpressionFor(target, expression); + } else { + return schemaDoc->Schema().SetExpressionFor(target, expression); + } +} + +bool RSFacade::SetTermFor(const EntityUID target, const std::string& termRef) { + if (isModel) { + return modelDoc->Model().SetTermFor(target, termRef); + } else { + return schemaDoc->Schema().SetTermFor(target, termRef); + } +} + +bool RSFacade::SetTermFormFor(const EntityUID target, const std::string& termRef, const ccl::lang::Morphology& form) { + if (isModel) { + return modelDoc->Model().SetTermFormFor(target, termRef, form); + } else { + return schemaDoc->Schema().SetTermFormFor(target, termRef, form); + } +} + +bool RSFacade::SetDefinitionFor(const EntityUID target, const std::string& textDef) { + if (isModel) { + return modelDoc->Model().SetDefinitionFor(target, textDef); + } else { + return schemaDoc->Schema().SetDefinitionFor(target, textDef); + } +} + +bool RSFacade::SetConventionFor(const EntityUID target, const std::string& convention) { + if (isModel) { + return modelDoc->Model().SetConventionFor(target, convention); + } else { + return schemaDoc->Schema().SetConventionFor(target, convention); + } +} + +bool RSFacade::SetAliasFor(const EntityUID target, const std::string& newName, const bool substitue) { + if (isModel) { + return modelDoc->Model().SetAliasFor(target, newName, substitue); + } else { + return schemaDoc->Schema().SetAliasFor(target, newName, substitue); + } +} + +void RSFacade::ResetAliases() { + if (isModel) { + return modelDoc->Model().ResetAliases(); + } else { + return schemaDoc->Schema().ResetAliases(); + } +} + +EntityUID RSFacade::Emplace(const CstType type, const std::string& definition) { + if (isModel) { + return modelDoc->Model().Emplace(type, definition); + } else { + return schemaDoc->Schema().Emplace(type, definition); + } +} + +VectorOfEntities RSFacade::InsertCopy(const std::vector& input) { + if (isModel) { + return modelDoc->Model().InsertCopy(input); + } else { + return schemaDoc->Schema().InsertCopy(input); + } +} + +bool RSFacade::MoveBefore(const EntityUID what, const ListIterator iWhere) { + if (isModel) { + return modelDoc->Model().MoveBefore(what, iWhere); + } else { + return schemaDoc->Schema().MoveBefore(what, iWhere); + } +} + +} // namespace xtr::doc \ No newline at end of file diff --git a/src/doc/RSFormDoc.cpp b/src/doc/RSFormDoc.cpp new file mode 100644 index 0000000..dffa913 --- /dev/null +++ b/src/doc/RSFormDoc.cpp @@ -0,0 +1,142 @@ +#include "stdafx.h" + +#include "xtr/doc/RSFormDoc.h" + +#include "resource.h" + +#include "xtr/ExteorOptions.h" +#include "xtr/doc/RSModelDoc.h" +#include "xtr/io/TRSLegacyLoader.h" +#include "xtr/dialog/NewDocument.h" + +namespace xtr::doc { + +using ccl::semantic::RSForm; +using ccl::src::DataStream; + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +IMPLEMENT_DYNCREATE(RSFormDoc, SelectableDoc) + +#pragma warning( pop ) + +RSFormDoc::RSFormDoc() { + schema.AddObserver(*this); +} + +RSFormDoc::~RSFormDoc() { + schema.RemoveObserver(*this); +} + +bool RSFormDoc::WriteData(ccl::meta::UniqueCPPtr data) { + if (data == nullptr) { + return false; + } + + try { + schema = dynamic_cast(*data); + selection.clear(); + return true; + } catch (std::bad_cast& /*e*/) { + return false; + } +} + +DataStream* RSFormDoc::AccessData() { + SetModifiedFlag(TRUE); + return &schema; +} + +void RSFormDoc::OnObserve(const ccl::types::Message& change) { + if (const auto* changePtr = dynamic_cast(&change); changePtr != nullptr) { + SetModifiedFlag(TRUE); + } +} + +void RSFormDoc::Serialize(CArchive& ar) { + MFCSerializable::Serialize(ar); +} + +BOOL RSFormDoc::OnNewDocument() { + if (!CDocument::OnNewDocument()) { + return FALSE; + } else if (XTROptions::App().IsSilent()) { + return TRUE; + } else if (dialog::NewRSForm dialog(this->GetTitle()); dialog.DoModal() != IDOK) { + return FALSE; + } else { + schema.title = mfc::ToSTL(dialog.newTitle); + schema.alias = mfc::ToSTL(dialog.newAlias); + return TRUE; + } +} + +BOOL RSFormDoc::OnOpenDocument(LPCTSTR path) { + if (CString(path).Right(4).MakeLower() != ExtensionFor(FileType::trs)) { + return FALSE; + } + if (!LoadJSON(mfc::ToUTF8(path)) + && !CDocument::OnOpenDocument(path)) { + return FALSE; + } + SetPathName(path, FALSE); + ccl::Environment::Sources().OnSourceOpen(*this); + return XTROptions::App().IsSilent() || !IsClaimed() || + ccl::Environment::Sources().QuerySrcUse(*this) || + ::AfxMessageBox(IXTRS_OPEN_CLAIMED, MB_YESNO | MB_ICONQUESTION) == IDYES; +} + +BOOL RSFormDoc::OnSaveDocument(LPCTSTR path) { + if (path != GetPathName() && !GetPathName().IsEmpty()) { + ccl::Environment::Sources().OnSourceClose(*this); + } + const auto changed = IsModified(); + + if (!SaveJSON(mfc::ToUTF8(path))) { + return FALSE; + } + + SetPathName(path, FALSE); + if (changed) { + ccl::Environment::Sources().OnSourceChange(*this); + } + SetModifiedFlag(FALSE); + return TRUE; +} + +void RSFormDoc::OnCloseDocument() { + ccl::Environment::Sources().OnSourceClose(*this); + CDocument::OnCloseDocument(); +} + +JSON RSFormDoc::ExtractData() const { + auto result = JSON(schema); + result["claimed"] = IsClaimed(); + result["selection"] = selection; + return result; +} + +bool RSFormDoc::LoadData(const JSON& object) { + [[maybe_unused]] const auto noObserving = DndGuard(); + object.get_to(schema); + SetSelection(object.at("selection").get()); + if (object.at("claimed").get()) { + Claim(); + } + return true; +} + +bool RSFormDoc::LegacyLoad(io::CArchiveAdapter& archive) { + [[maybe_unused]] const auto noObserving = DndGuard(); + auto loader = io::TRSLegacyLoader{ archive, schema }; + loader.LoadVersion(); + loader.DoLoad(); + SetSelection(loader.selection); + if (loader.isClaimed) { + Claim(); + } + return true; +} + +} // namespace xtr::doc \ No newline at end of file diff --git a/src/doc/RSModelDoc.cpp b/src/doc/RSModelDoc.cpp new file mode 100644 index 0000000..e7d2e71 --- /dev/null +++ b/src/doc/RSModelDoc.cpp @@ -0,0 +1,92 @@ +#include "stdafx.h" + +#include "xtr/ExteorOptions.h" +#include "xtr/doc/RSModelDoc.h" +#include "xtr/io/RSMLegacyLoader.h" +#include "xtr/dialog/NewDocument.h" + +using ccl::semantic::RSModel; + +namespace xtr::doc { + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +IMPLEMENT_DYNCREATE(RSModelDoc, SelectableDoc) + +#pragma warning( pop ) + +RSModelDoc::RSModelDoc() { + model.AddObserver(*this); +} + +RSModelDoc::~RSModelDoc() { + model.RemoveObserver(*this); +} + +void RSModelDoc::Serialize(CArchive& ar) { + MFCSerializable::Serialize(ar); +} + +void RSModelDoc::OnObserve(const ccl::types::Message& change) { + if (const auto* changePtr = dynamic_cast(&change); changePtr != nullptr) { + SetModifiedFlag(TRUE); + } +} + +BOOL RSModelDoc::OnNewDocument() { + if (XTROptions::App().IsSilent()) { + return CDocument::OnNewDocument(); + } else if (dialog::NewRSForm dialog(this->GetTitle()); dialog.DoModal() != IDOK) { + return FALSE; + } else { + model.title = mfc::ToSTL(dialog.newAlias); + model.alias = mfc::ToSTL(dialog.newTitle); + return TRUE; + } +} + +BOOL RSModelDoc::OnOpenDocument(LPCTSTR path) { + if (CString(path).Right(4).MakeLower() != ExtensionFor(FileType::rsm)) { + return FALSE; + } + if (!LoadJSON(mfc::ToUTF8(path)) + && !CDocument::OnOpenDocument(path)) { + return FALSE; + } + SetPathName(path, FALSE); + return TRUE; +} + +BOOL RSModelDoc::OnSaveDocument(LPCTSTR path) { + if (!SaveJSON(mfc::ToUTF8(path))) { + return FALSE; + } + SetPathName(path, FALSE); + SetModifiedFlag(FALSE); + return TRUE; +} + +JSON RSModelDoc::ExtractData() const { + auto result = JSON(model); + result["selection"] = selection; + return result; +} + +bool RSModelDoc::LoadData(const JSON& object) { + [[maybe_unused]] const auto noObserving = DndGuard(); + object.get_to(model); + SetSelection(object.at("selection").get()); + return true; +} + +bool RSModelDoc::LegacyLoad(io::CArchiveAdapter& archive) { + const auto guard = DndGuard(); + auto loader = io::RSMLegacyLoader{ archive, model }; + loader.LoadVersion(); + loader.DoLoad(); + SetSelection(loader.selection); + return true; +} + +} // namespace xtr::doc \ No newline at end of file diff --git a/src/io/CstGraphExporter.cpp b/src/io/CstGraphExporter.cpp new file mode 100644 index 0000000..532c122 --- /dev/null +++ b/src/io/CstGraphExporter.cpp @@ -0,0 +1,50 @@ +#include "stdafx.h" + +#include "xtr/io/CstGraphExporter.h" + +namespace xtr::io { + +BOOL CstGraphExporter::Export(const CstGraphOptions& exportParams, const CString fileName, const FileType type) { + options = exportParams; + std::ofstream file(fileName); + if (!file.is_open()) { + return FALSE; + } + if (type == FileType::csv) { + const auto linePutter = [&file, &triplets = this->options.triplets](const Triplet& data) { + if (triplets) { + file << data.from << ';' << static_cast(data.type) << ';' << data.to << '\n'; + } else { + file << data.from << ';' << data.to << '\n'; + } + }; + + if (options.linkage.has_value()) { + OutputLinks(options.linkage.value(), linePutter); + } else { + OutputLinks(LinkType::formula, linePutter); + OutputLinks(LinkType::lexDef, linePutter); + OutputLinks(LinkType::lexTerm, linePutter); + } + } else { + const auto linePutter = [&file, &triplets = this->options.triplets](const Triplet& data) { + if (triplets) { + file << data.from << '\t' << static_cast(data.type) << '\t' << data.to << '\n'; + } else { + file << data.from << '\t' << data.to << '\n'; + } + }; + if (options.linkage.has_value()) { + OutputLinks(options.linkage.value(), linePutter); + } else { + OutputLinks(LinkType::formula, linePutter); + OutputLinks(LinkType::lexDef, linePutter); + OutputLinks(LinkType::lexTerm, linePutter); + } + } + + file.close(); + return TRUE; +} + +} // namespace xtr::io \ No newline at end of file diff --git a/src/io/ModelDataExchange.cpp b/src/io/ModelDataExchange.cpp new file mode 100644 index 0000000..07bbe45 --- /dev/null +++ b/src/io/ModelDataExchange.cpp @@ -0,0 +1,54 @@ +#include "stdafx.h" + +#include "xtr/io/ModelDataExchange.h" + +#include "xtr/io/RSExcelIOManager.h" + +#include "office/ExcelWrapper.h" + +namespace xtr::io { + +using ccl::semantic::RSModel; + +RSMDataX& RSMDataX::Instance() { + static RSMDataX instance; + return instance; +} + +BOOL RSMDataX::ExportModel(const RSModel& model) { + RSExcelIOManager manager{ model }; + try { + return manager.ExportModel(); + } catch (_com_error& /*er*/) { + return FALSE; + } +} + +BOOL RSMDataX::ExportDataFor(EntityUID target, const RSModel& model) { + RSExcelIOManager manager{ model }; + try { + return manager.ExportDataFor(target); + } catch (_com_error& /*er*/) { + return FALSE; + } +} + +std::optional RSMDataX::ImportText(const RSModel& model) { + RSExcelIOManager manager{ model }; + try { + return manager.ImportText(); + } catch (_com_error& /*er*/) { + return std::nullopt; + } +} + +std::optional RSMDataX::ImportStructured(const RSModel& model, const ccl::rslang::Typification& structure) { + RSExcelIOManager manager{ model }; + try { + return manager.ImportStructured(structure); + } catch (_com_error& /*er*/) { + return std::nullopt; + } +} + +} // namespace xtr::io \ No newline at end of file diff --git a/src/io/ModelExporter.cpp b/src/io/ModelExporter.cpp new file mode 100644 index 0000000..d3ced8f --- /dev/null +++ b/src/io/ModelExporter.cpp @@ -0,0 +1,29 @@ +#include "stdafx.h" + +#include "xtr/io/ModelExporter.h" + +#include "xtr/io/ModelDataExchange.h" + +#include "ccl/tools/JSON.h" + +namespace xtr::io { + +BOOL ModelExporter::Export(const CString fileName, const FileType type) { + switch (type) { + default: return FALSE; + + case FileType::xlsx: return io::RSMDataX::ExportModel(target); + case FileType::json: { + std::ofstream file(fileName); + if (!file.is_open()) { + return FALSE; + } else { + file << std::setw(4) << nlohmann::ordered_json(target); + file.close(); + return TRUE; + } + } + } +} + +} // namespace xtr::io \ No newline at end of file diff --git a/src/io/OSSExporter.cpp b/src/io/OSSExporter.cpp new file mode 100644 index 0000000..a7ba9a8 --- /dev/null +++ b/src/io/OSSExporter.cpp @@ -0,0 +1,26 @@ +#include "stdafx.h" + +#include "xtr/io/OSSExporter.h" + +#include "ccl/tools/JSON.h" + +namespace xtr::io { + +BOOL OSSExporter::Export(const CString fileName, const FileType type) { + switch (type) { + default: return FALSE; + + case FileType::json: { + std::ofstream file(fileName); + if (!file.is_open()) { + return FALSE; + } else { + file << std::setw(4) << nlohmann::ordered_json(target); + file.close(); + return TRUE; + } + } + } +} + +} // namespace xtr::io \ No newline at end of file diff --git a/src/io/OSSLegacyLoader.cpp b/src/io/OSSLegacyLoader.cpp new file mode 100644 index 0000000..44176c8 --- /dev/null +++ b/src/io/OSSLegacyLoader.cpp @@ -0,0 +1,312 @@ +#include "stdafx.h" + +#include "xtr/io/OSSLegacyLoader.h" + +using ccl::oss::GridIndex; +using ccl::oss::GridPosition; +using ccl::oss::Pict; +using ccl::ops::EquationOptions; +using ccl::ops::Equation; +using ccl::meta::UniqueCPPtr; + +namespace xtr::io { + +void OSSLegacyLoader::LoadVersion() { + const auto versionIntro = ar.Load(); + if (versionIntro != LR"(__@OSS_VERSION@__)") { + oss.comment = mfc::ToSTL(versionIntro); + version = OSSVersion::old; + } else { + version = OSSVersion{ OSSVersion::VersionID{ ar.Load() } }; + ar.Skip(); + } +} + +void OSSLegacyLoader::DoLoad() { + if (version.v == OSSVersion::old) { + LoadFirstGen(); + } else if (version.v < OSSVersion::r1800) { + LoadSecondGen(); + } else { + LoadThirdGen(); + } +} + +void OSSLegacyLoader::LoadFirstGen() { + oss.title = ar.Load(); + auto pictCount = ar.Load(); + while (pictCount--) { + LoadPictGen1(); + } +} + +void OSSLegacyLoader::LoadPictGen1() { + GridPosition pos{}; + pos.row = GridIndex{ ar.Load() - 1 }; + pos.column = GridIndex{ ar.Load() - 1 }; + ar.Skip(); + ar.Skip(); + + ccl::src::Handle srcHandle{}; + const auto scrPath = ar.Load(); + if (!scrPath.IsEmpty()) { + srcHandle.desc = ccl::src::Descriptor{ ccl::src::SrcType::rsDoc, mfc::ToUTF8(scrPath) }; + } + + Pict pict{ 0 }; + pict.alias = ar.Load(); + pict.title = ar.Load(); + + const auto isActive = ar.Load(); + + GridPosition posParent1{}; + posParent1.row = GridIndex{ ar.Load() - 1 }; + posParent1.column = GridIndex{ ar.Load() - 1 }; + const auto parent1 = oss.Grid()(posParent1); + + GridPosition posParent2{}; + posParent2.row = GridIndex{ ar.Load() - 1 }; + posParent2.column = GridIndex{ ar.Load() - 1 }; + const auto parent2 = oss.Grid()(posParent2); + + const auto countMapItems = ar.Load(); + if (countMapItems != 0) { + CMapStringToString* loadMap{}; + ar >> loadMap; + delete loadMap; // NOLINT(cppcoreguidelines-owning-memory) + } + + ar.Skip(); + ar.Skip(); + + const auto status = LoadPictStatus(ar.Load()); + const auto operationType = LoadOperationType(ar.Load()); + auto operation = std::unique_ptr{ nullptr }; + if (status >= static_cast(ccl::ops::Status::undefined)) { + operation = std::make_unique(); + operation->type = operationType; + } + + const auto& loaded = oss.LoadPict(std::move(pict), pos, srcHandle, std::move(operation)); + if (parent1.has_value()) { + oss.Graph().LoadParent(loaded.uid, parent1.value()); + } + if (parent2.has_value()) { + oss.Graph().LoadParent(loaded.uid, parent2.value()); + } + if (isActive) { + selection = loaded.uid; + } +} + +uint32_t OSSLegacyLoader::LoadPictStatus(const uint32_t code) noexcept { + switch (code) { + default: case 0: return 0; // NOLINT + case 1: case 2: return 1; // NOLINT + case 3: case 5: return 2; // NOLINT + case 4: return 3; // NOLINT + case 6: return 4; // NOLINT + case 7: return 5; // NOLINT + case 8: return 6; // NOLINT + } +} + +ccl::ops::Type OSSLegacyLoader::LoadOperationType(const uint32_t code) noexcept { + if (code >= 5 && code <= 7) { + return ccl::ops::Type::rsSynt; + } else { + return ccl::ops::Type{ code }; + } +} + +void OSSLegacyLoader::LoadSecondGen() { + oss.comment = ar.Load(); + oss.title = ar.Load(); + auto pictCount = ar.Load(); + ar.Skip(); + while (pictCount--) { + LoadPictGen2(); + } + ar.Skip(); + + const auto activeID = ccl::oss::PictID{ ar.Load() }; + selection = oss(activeID) != nullptr ? activeID : std::begin(oss)->uid; + LoadDependencies(); +} + +void OSSLegacyLoader::LoadPictGen2() { + Pict pict{}; + GridPosition pos{}; + ccl::src::Handle srcHandle{}; + auto operHandle = std::make_unique(); + + pict.uid = ar.Load(); + pos.row = GridIndex{ ar.Load() - 1 }; + pos.column = GridIndex{ ar.Load() - 1 }; + srcHandle.coreHash = ar.Load(); + srcHandle.fullHash = ar.Load(); + ar.Skip(); + const auto status = ccl::ops::Status{ ar.Load() }; + srcHandle.desc = ccl::src::Descriptor{ ccl::src::SrcType::rsDoc, mfc::ToUTF8(ar.Load()) }; + pict.lnk.address = ar.Load(); + pict.lnk.subAddr = ar.Load(); + pict.comment = ar.Load(); + operHandle->type = LoadOperationType(ar.Load()); + pict.alias = ar.Load(); + pict.title = ar.Load(); + + operHandle->options = LoadOptionsGen2(); + operHandle->translations = LoadTranslationsGen2(); + operHandle->outdated = status == ccl::ops::Status::outdated; + if (status < ccl::ops::Status::undefined) { + operHandle = nullptr; + } + + oss.LoadPict(std::move(pict), pos, srcHandle, std::move(operHandle)); +} + +UniqueCPPtr OSSLegacyLoader::LoadOptionsGen2() { + auto equations = std::make_unique(); + auto countMapItems = ar.Load(); + while (countMapItems--) { + const auto key = EntityUID{ ar.Load() }; + const auto value = EntityUID{ ar.Load() }; + Equation::Mode type{}; + if (version.v < OSSVersion::r1483) { + type = Equation::Mode::keepHier; + } else { + type = static_cast(ar.Load()); + if (type == Equation::Mode::keepHier) { + type = Equation::Mode::keepDel; + } else if (type == Equation::Mode::keepDel) { + type = Equation::Mode::keepHier; + } + } + if (version.v >= OSSVersion::r1553) { + ar.Skip(); + } + equations->Insert(key, value, Equation{ type, ""}); + } + return UniqueCPPtr{ std::move(equations) }; +} + +UniqueCPPtr OSSLegacyLoader::LoadTranslationsGen2() { + auto opCount = ar.Load(); + if (opCount == 0) { + return nullptr; + } + + UniqueCPPtr result = std::make_unique(); + while (opCount--) { + auto elementCount = ar.Load(); + ccl::EntityTranslation element{}; + while (elementCount--) { + const auto key = EntityUID{ ar.Load() }; + const auto value = EntityUID{ ar.Load() }; + element.Insert(key, value); + if (version.v >= OSSVersion::r1483) { + ar.Skip(); + } + if (version.v >= OSSVersion::r1553) { + ar.Skip(); + } + } + result->emplace_back(element); + } + return result; +} + +void OSSLegacyLoader::LoadDependencies() { + auto edgeCount = ar.Load(); + while (edgeCount--) { + const auto child = ar.Load(); + const auto parent = ar.Load(); + oss.Graph().LoadParent(child, parent); + } +} + +void OSSLegacyLoader::LoadThirdGen() { + oss.title = ar.Load(); + oss.comment = ar.Load(); + + auto pictCount = ar.Load(); + while (pictCount--) { + LoadPictGen3(); + } + + LoadDependencies(); + selection = ccl::oss::PictID{ ar.Load() }; +} + +void OSSLegacyLoader::LoadPictGen3() { + Pict pict{}; + pict.uid = ccl::oss::PictID{ ar.Load() }; + pict.dataType = ccl::src::DataType{ ar.Load() }; + pict.title = ar.Load(); + pict.alias = ar.Load(); + pict.comment = ar.Load(); + pict.lnk.address = ar.Load(); + pict.lnk.subAddr = ar.Load(); + + GridPosition pos{}; + pos.row = GridIndex{ ar.Load() }; + pos.column = GridIndex{ ar.Load() }; + + ccl::src::Handle srcHandle{}; + srcHandle.desc.name = mfc::ToUTF8(ar.Load()); + srcHandle.desc.type = ccl::src::SrcType{ ar.Load() }; + srcHandle.coreHash = ar.Load(); + srcHandle.fullHash = ar.Load(); + + std::unique_ptr opHandle{ nullptr }; + if (ar.Load()) { + opHandle = std::make_unique(); + opHandle->type = ccl::ops::Type{ ar.Load() }; + if (ar.Load()) { + opHandle->options = LoadOptionsGen3(); + } + if (ar.Load()) { + opHandle->translations = LoadTranslationsGen3(); + } + opHandle->broken = ar.Load(); + opHandle->outdated = ar.Load(); + } + + oss.LoadPict(std::move(pict), pos, srcHandle, std::move(opHandle)); +} + +UniqueCPPtr OSSLegacyLoader::LoadOptionsGen3() { + auto equations = std::make_unique(); + auto countMapItems = ar.Load(); + while (countMapItems--) { + const auto key = EntityUID{ ar.Load() }; + const auto value = EntityUID{ ar.Load() }; + Equation options{}; + auto mode = ar.Load(); + if (mode == 0) { + mode = 1; + } + options.mode = static_cast(mode); + options.arg = ar.Load(); + equations->Insert(key, value, options); + } + return UniqueCPPtr{ std::move(equations) }; +} + +UniqueCPPtr OSSLegacyLoader::LoadTranslationsGen3() { + UniqueCPPtr result = std::make_unique(); + auto equationCount = ar.Load(); + while (equationCount--) { + ccl::EntityTranslation element{}; + auto elementCount = ar.Load(); + while (elementCount--) { + const auto key = EntityUID{ ar.Load() }; + const auto value = EntityUID{ ar.Load() }; + element.Insert(key, value); + } + result->emplace_back(element); + } + return result; +} + +} // namespace xtr::io \ No newline at end of file diff --git a/src/io/RSExcelIOManager.cpp b/src/io/RSExcelIOManager.cpp new file mode 100644 index 0000000..335f49b --- /dev/null +++ b/src/io/RSExcelIOManager.cpp @@ -0,0 +1,314 @@ +#include "stdafx.h" + +#include "xtr/io/RSExcelIOManager.h" + +#include "resource.h" + +#include "xtr/Exteor.h" +#include "xtr/cclDescriptor.h" + +#include "xtr/dialog/ImportWSDialog.h" + +namespace xtr::io { + +using ccl::semantic::TextInterpretation; +using ccl::object::SDCompact; +using ccl::rslang::Typification; +using MSO::Excel::EXLWorksheet; +using MSO::SizeT; + +static constexpr MSO::SizeT HEADER_ROWS{ 1 }; +static constexpr auto EXCEL_DATA_START = MSO::FIRST_INDEX + HEADER_ROWS; +static constexpr MSO::SizeT TEXT_COLUMNS{ 2 }; + +RSExcelIOManager::~RSExcelIOManager() { + try { + workingWb.ReleaseDispatch(); + workingWs.ReleaseDispatch(); + xlWrapper.ReleaseDocument(); + } catch (...) { + ; // TODO: manage exceptions correctly + } +} + +BOOL RSExcelIOManager::ExportModel() { + if (!PrepareNewWorkbook()) { + return FALSE; + } + auto rsFormSheet = InitModelWorksheet(mfc::ToMFC(model.alias)); + auto outputRange = rsFormSheet.get_Cells(); + + auto nRow = MSO::FIRST_INDEX + HEADER_ROWS; + for (const auto uid : model.List()) { + const auto& cst = model.GetRS(uid); + ExportCstProperties(uid, rsFormSheet, nRow); + if (ccl::semantic::IsRSObject(cst.type)) { + if (!ExportCstDataInternal(uid)) { + return FALSE; + } + } + ++nRow; + } + outputRange.get_Columns().AutoFit(); + rsFormSheet.Activate(); + return TRUE; +} + +BOOL RSExcelIOManager::ExportDataFor(const EntityUID target) { + if (!PrepareNewWorkbook()) { + return FALSE; + } else { + return ExportCstDataInternal(target); + } +} + + +std::optional RSExcelIOManager::ImportText() { + if (PrepareInputWorksheet()) { + auto result = ImportTextInternal(); + xlWrapper.ReleaseDocument(); + return result; + } else { + return std::nullopt; + } +} + +std::optional RSExcelIOManager::ImportStructured(const Typification& structure) { + if (PrepareInputWorksheet()) { + auto result = ImportStructuredInternal(structure); + xlWrapper.ReleaseDocument(); + return result; + } else { + return std::nullopt; + } +} + +BOOL RSExcelIOManager::PrepareNewWorkbook() { + const auto pathToTemplate = g_Exteor.GetModuleFolder() + mfc::LoadSID(IXTRS_HEADER_CONSTITUENTA); + if (workingWb = xlWrapper.NewDocument(pathToTemplate); workingWb == nullptr) { + ::AfxMessageBox(IXTRE_EXCEL_OPENWB, MB_ICONERROR); + return FALSE; + } else { + return true; + } +} + +EXLWorksheet RSExcelIOManager::InitModelWorksheet(const CString label) { + auto rsFormSheet = workingWb.get_Worksheets()[1]; + rsFormSheet.put_Name(label); + + auto rsRange = rsFormSheet.get_Cells(); + rsRange.put_Item(MSO::FIRST_INDEX, static_cast(OutputColumn::id), T2VT(mfc::LoadSID(IXTRS_HEADER_ID))); + rsRange.put_Item(MSO::FIRST_INDEX, static_cast(OutputColumn::constituenta), T2VT(mfc::LoadSID(IXTRS_HEADER_CONSTITUENTA))); + rsRange.put_Item(MSO::FIRST_INDEX, static_cast(OutputColumn::expression), T2VT(mfc::LoadSID(IXTRS_HEADER_EXPRESSION))); + rsRange.put_Item(MSO::FIRST_INDEX, static_cast(OutputColumn::type), T2VT(mfc::LoadSID(IXTRS_HEADER_TYPE))); + rsRange.put_Item(MSO::FIRST_INDEX, static_cast(OutputColumn::term), T2VT(mfc::LoadSID(IXTRS_HEADER_TERM))); + rsRange.put_Item(MSO::FIRST_INDEX, static_cast(OutputColumn::interpretation), T2VT(mfc::LoadSID(IXTRS_HEADER_INTERPRETATION))); + rsRange.put_Item(MSO::FIRST_INDEX, static_cast(OutputColumn::convention), T2VT(mfc::LoadSID(IXTRS_HEADER_CONVENTION))); + + return rsFormSheet; +} + +void RSExcelIOManager::ExportCstProperties(const EntityUID target, + EXLWorksheet rsFormSheet, const MSO::SizeT nRow) { + const auto& rsCst = model.GetRS(target); + const auto& textCst = model.GetText(target); + auto range = rsFormSheet.get_Cells(); + range.put_Item(nRow, static_cast(OutputColumn::id), T2VT(static_cast(target))); + range.put_Item(nRow, static_cast(OutputColumn::constituenta), T2VT(mfc::ToMFC(rsCst.alias))); + range.put_Item(nRow, static_cast(OutputColumn::expression), T2VT(mfc::ToMFC(rsCst.definition))); + range.put_Item(nRow, static_cast(OutputColumn::type), T2VT(info::Label(model.GetParse(target).TypePtr()))); + range.put_Item(nRow, static_cast(OutputColumn::term), T2VT(mfc::ToMFC(textCst.term.Nominal()))); + range.put_Item(nRow, static_cast(OutputColumn::interpretation), T2VT(mfc::ToMFC(textCst.definition.Str()))); + range.put_Item(nRow, static_cast(OutputColumn::convention), T2VT(mfc::ToMFC(rsCst.convention))); +} + +BOOL RSExcelIOManager::ExportCstDataInternal(const EntityUID target) { + const auto& rsCst = model.GetRS(target); + if (workingWs = CreateOutputSheet(mfc::ToMFC(rsCst.alias)); workingWs == nullptr) { + return FALSE; + } else if (!ccl::semantic::IsBaseSet(rsCst.type)) { + return ExportStructuredData(target); + } else { + ExportNamedData(target); + return TRUE; + } +} + +EXLWorksheet RSExcelIOManager::CreateOutputSheet(const CString label) { + auto worksheets = workingWb.get_Worksheets(); + auto lastWorksheet = worksheets[worksheets.get_Count()]; + auto result = worksheets.Add({}, lastWorksheet, vtMissing, vtMissing); + if (result != nullptr) { + result.put_Name(label); + } + return result; +} + +void RSExcelIOManager::ExportNamedData(const EntityUID target) { + workingWs.get_Cells().put_Item(1, 1, T2VT(mfc::ToMFC(model.GetRS(target).alias))); + workingWs.get_Cells().put_Item(1, 2, T2VT(mfc::LoadSID(IXTRS_HEADER_INTERPRETATION))); + + const auto& interp = *model.Values().TextFor(target); + auto nRow = EXCEL_DATA_START; + for (const auto& [id, text] : interp) { + const auto interpretant = mfc::ToMFC(text); + CString index{}; + index.AppendFormat(LR"(%ld)", id); + workingWs.get_Cells().put_Item(nRow, 1, T2VT(index)); + workingWs.get_Cells().put_Item(nRow, 2, T2VT(interpretant)); + ++nRow; + } +} + +BOOL RSExcelIOManager::ExportStructuredData(const EntityUID target) { + const auto* typif = model.GetParse(target).Typification(); + if (typif == nullptr) { + ::AfxMessageBox(IXTRE_EXPORT_TYPIF, MB_ICONERROR); + return FALSE; + } + if (auto structured = model.Values().SDataFor(target); structured.has_value()) { + const auto compact = SDCompact::FromSData(structured.value(), *typif); + InitCstDataHeader(compact.header); + for (auto nRow = 0; nRow < ssize(compact.data); ++nRow) { + for (auto nCol = 1; nCol < ssize(compact.data.at(nRow)); ++nCol) { + const auto dataIndex = compact.data.at(nRow).at(nCol); + workingWs.get_Cells().put_Item(nRow + EXCEL_DATA_START, nCol - 1 + MSO::FIRST_INDEX, T2VT(dataIndex)); + } + } + } + return TRUE; +} + +void RSExcelIOManager::InitCstDataHeader(const std::vector& header) { + static constexpr auto skipFirst = 1; + for (auto i = skipFirst; i < ssize(header); ++i) { + workingWs.get_Cells().put_Item(1, i - 1 + MSO::FIRST_INDEX, T2VT(mfc::ToMFC(header.at(i)))); + } +} + +BOOL RSExcelIOManager::PrepareInputWorksheet() { + if (auto path = MSO::Excel::ExcelWrapper::PromptUserForPath(mfc::LoadSID(IXTRS_FILTER_EXCEL)); path.IsEmpty()) { + return FALSE; + } else if (workingWb = xlWrapper.OpenDocument(path, TRUE, TRUE, TRUE, FALSE); workingWb == nullptr) { + ::AfxMessageBox(mfc::FormatSID(IXTRE_IMPORT_DOC_FAIL, path.GetString()), MB_ICONERROR); + return FALSE; + } else { + return DetermineWorksheet(); + } +} + +BOOL RSExcelIOManager::DetermineWorksheet() { + auto worksheets = workingWb.get_Worksheets(); + std::vector labels{}; + labels.reserve(worksheets.get_Count()); + for (auto i = 0; i < worksheets.get_Count(); ++i) { + labels.emplace_back(worksheets[MSO::FIRST_INDEX + i].get_Name()); + } + auto selectedIndex = 0; + if (ssize(labels) > 1) { + dialog::ImportWSDialog wsDialog(labels); + if (wsDialog.DoModal() != IDOK) { + return FALSE; + } + selectedIndex = wsDialog.selection; + } + workingWs = worksheets[MSO::FIRST_INDEX + selectedIndex]; + return TRUE; +} + +std::optional RSExcelIOManager::ImportTextInternal() { + auto rawData = ExtractRawData(TEXT_COLUMNS); + auto result = RSExcelIOManager::DataToTextInterpretation(rawData); + if (!result.has_value()) { + ::AfxMessageBox(IXTRE_DATA2EXCEL_FORMAT, MB_ICONERROR); + } + return result; +} + +std::optional RSExcelIOManager::ImportStructuredInternal(const Typification& structure) { + if (auto headers = SDCompact::CreateHeader(structure); !CheckHeaders(headers)) { + return std::nullopt; + } else { + auto rawData = ExtractRawData(static_cast(ssize(headers))); + auto data = RSExcelIOManager::DataToRSI(rawData); + if (!data.has_value()) { + ::AfxMessageBox(IXTRE_IMPORT_EXCEL_INVALID_DATA, MB_ICONERROR); + return std::nullopt; + } else { + return SDCompact{ headers, data.value() }; + } + } +} + +BOOL RSExcelIOManager::CheckHeaders(const std::vector& headers) { + if (std::empty(headers)) { + return FALSE; + } else { + for (MSO::SizeT nCol = 1; nCol < ssize(headers); ++nCol) { + CString cellHead = workingWs.get_Cells()(MSO::FIRST_INDEX, nCol + MSO::FIRST_INDEX - 1).get_Value(); + if (cellHead != mfc::ToMFC(headers.at(nCol))) { + ::AfxMessageBox(IXTRE_IMPORT_TYPIF, MB_ICONEXCLAMATION); + return FALSE; + } else { + ++nCol; + } + } + return TRUE; + } +} + +RSExcelIOManager::RawStringData RSExcelIOManager::ExtractRawData(const MSO::SizeT columnCount) { + auto range = workingWs.get_UsedRange(); + const auto rowCount = range.get_Rows().get_Count(); + + RawStringData strData{}; + strData.reserve(static_cast(rowCount) - HEADER_ROWS); + for (auto nRow = HEADER_ROWS; nRow < rowCount; ++nRow) { + for (auto nCol = 0; nCol < columnCount; ++nCol) { + auto cell = range.get_Cells()(nRow + MSO::FIRST_INDEX, nCol + MSO::FIRST_INDEX); + const CString text{ cell.get_Value() }; + if (nCol == 0) { + if (text.IsEmpty()) { + return strData; + } else { + strData.push_back({}); + } + } + strData.at(static_cast(nRow) - HEADER_ROWS).emplace_back(text); + } + } + return strData; +} + +std::optional RSExcelIOManager::DataToTextInterpretation(const RawStringData& data) { + TextInterpretation result{}; + for (const auto& aRow : data) { + const auto& index = aRow.at(0); + const auto& text = aRow.at(1); + if (index.IsEmpty() || index.SpanIncluding(L"0123456789") != index) { + return std::nullopt; + } + result.SetInterpretantFor(_wtoi(index), mfc::ToSTL(text)); + } + return result; +} + +std::optional RSExcelIOManager::DataToRSI(const RawStringData& data) { + SDCompact::Data result{ std::size(data) }; + auto resultRow = std::begin(result); + for (const auto& aRow : data) { + resultRow->emplace_back(SDCompact::unknownCount); + for (const auto& text : aRow) { + if (text.SpanIncluding(L"0123456789") != text) { + return std::nullopt; + } else if (!text.IsEmpty()) { + resultRow->emplace_back(_wtoi(text)); + } + } + ++resultRow; + } + return result; +} + +} // namespace xtr::io \ No newline at end of file diff --git a/src/io/RSForm2DOCX.cpp b/src/io/RSForm2DOCX.cpp new file mode 100644 index 0000000..8c93679 --- /dev/null +++ b/src/io/RSForm2DOCX.cpp @@ -0,0 +1,171 @@ +#include "stdafx.h" + +#include "xtr/io/RSForm2DOCX.h" + +#include "resource.h" + +#include "xtr/Exteor.h" +#include "xtr/cclDescriptor.h" + +namespace xtr::io { + +namespace { + +struct WordHeader { + enum Columns : uint8_t { + POS_NAME = 1, + POS_EXPR, + POS_TYPIFICATION, + POS_TERM, + POS_INTERP + }; +}; + +void ApplyParamsTo(MSO::Word::WTable& outTable, const SchemaOptions& params) { + static constexpr float PREFERED_WIDHT = 100; + if (!params.bTextDef) { + outTable.get_Columns()[WordHeader::POS_INTERP].Delete(); + } + if (!params.bTerm) { + outTable.get_Columns()[WordHeader::POS_TERM].Delete(); + } + if (!params.bTyping) { + outTable.get_Columns()[WordHeader::POS_TYPIFICATION].Delete(); + } + if (!params.bRSDef) { + outTable.get_Columns()[WordHeader::POS_EXPR].Delete(); + } + outTable.put_PreferredWidth(PREFERED_WIDHT); +} + +} // anonymous namespace + +BOOL RSForm2DOCX::Export(const SchemaOptions& exportParams, const CString fileName) { + params = exportParams; + try { + if (!LoadApplication() || + !CreateDocument() || + !WriteContent()) { + return FALSE; + } else { + if (!fileName.IsEmpty()) { + SaveFile(fileName); + } + return TRUE; + } + } catch (_com_error& /*er*/) { + return FALSE; + } +} + +BOOL RSForm2DOCX::LoadApplication() { + if (!wordApplication.CreateDispatch(LR"(Word.Application)")) { + ::AfxMessageBox(IXTRE_WORD_APPL, MB_ICONERROR); + return FALSE; + } else { + wordApplication.put_Visible(TRUE); + wordApplication.Activate(); + docs = MSO::Word::WDocuments{ wordApplication.get_Documents() }; + return TRUE; + } +} + +BOOL RSForm2DOCX::CreateDocument() { + if (const auto maybePath = GetPathToTemplate(); maybePath.has_value()) { + COleVariant temapltePath{ maybePath.value() }; + workingDocument = docs.Add(&temapltePath, &MSO::ovOptional, &MSO::ovOptional, &MSO::ovTrue); + return TRUE; + } else { + return FALSE; + } +} + +std::optional RSForm2DOCX::GetPathToTemplate() { + const auto pathToTemplate = g_Exteor.GetModuleFolder() + mfc::LoadSID(IXTRS_PATH_RSDOC_TEMPLATE); + if (!::PathFileExistsW(pathToTemplate)) { + ::AfxMessageBox(mfc::FormatSID(IXTRE_TEMPLATE_NOT_FOUND, pathToTemplate.GetString()), MB_ICONERROR); + return std::nullopt; + } else { + return pathToTemplate; + } +} + +BOOL RSForm2DOCX::WriteContent() { + static constexpr auto rowStart = 2; + if (!WriteHeaderFooter()) { + return FALSE; + } else { + auto outTable = workingDocument.get_Tables()[1]; + auto nRow = rowStart; + for (const auto uid : source.List()) { + outTable.get_Rows().Add(&vtMissing); + WriteConstituenta(uid, outTable, nRow); + ++nRow; + } + outTable.get_Rows()[outTable.get_Rows().get_Count()].Delete(); + ApplyParamsTo(outTable, params); + return TRUE; + } +} + +BOOL RSForm2DOCX::WriteHeaderFooter() { + return PutTextIntoBookmark(L"ToName", mfc::ToMFC(source.title)) + && PutTextIntoBookmark(L"ToShortName", mfc::ToMFC(source.alias)); +} + +BOOL RSForm2DOCX::PutTextIntoBookmark(const CString bookmarkName, const CString text) { + auto bookmarks = workingDocument.get_Bookmarks(); + try { + auto namedRange = bookmarks[bookmarkName].get_Range(); + namedRange.put_Text(text); + return TRUE; + } + catch (_com_error& /*er*/) { + ::AfxMessageBox(mfc::FormatSID(IXTRE_WORD_BOOKMARK_MISSING, bookmarkName.GetString()), MB_ICONEXCLAMATION); + return FALSE; + } +} + +void RSForm2DOCX::WriteConstituenta(const EntityUID target, + MSO::Word::WTable& outTable, const long nRow) { + const auto& rsCst = source.GetRS(target); + const auto& textCst = source.GetText(target); + + const auto cstname = mfc::ToMFC(rsCst.alias); + const auto expression = mfc::ToMFC(rsCst.definition); + const auto typification = info::Label(source.GetParse(target).TypePtr()); + const auto convention = mfc::ToMFC(rsCst.convention); + const auto interpret = mfc::ToMFC(textCst.definition.Str()); + const auto term = mfc::ToMFC(textCst.term.Nominal()); + + outTable.Cell(nRow, WordHeader::POS_NAME).get_Range().InsertAfter(cstname); + outTable.Cell(nRow, WordHeader::POS_EXPR).get_Range().InsertAfter(expression); + outTable.Cell(nRow, WordHeader::POS_TYPIFICATION).get_Range().InsertAfter(typification); + outTable.Cell(nRow, WordHeader::POS_TERM).get_Range().InsertAfter(term); + if (!interpret.IsEmpty() && params.bTextDef) { + outTable.Cell(nRow, WordHeader::POS_INTERP).get_Range().InsertAfter(interpret); + } + if (!convention.IsEmpty() && params.bComment) { + if (ccl::semantic::IsBaseNotion(rsCst.type)) { + if (!interpret.IsEmpty()) { + outTable.Cell(nRow, WordHeader::POS_INTERP).get_Range().InsertAfter(L"\n"); + } + outTable.Cell(nRow, WordHeader::POS_INTERP).get_Range().InsertAfter(L": "); + outTable.Cell(nRow, WordHeader::POS_INTERP).get_Range().InsertAfter(convention); + } else { + auto nameCellRange = outTable.Cell(nRow, WordHeader::POS_NAME).get_Range(); + nameCellRange.get_Comments().Add(nameCellRange, COleVariant{ convention }); + } + } +} + +void RSForm2DOCX::SaveFile(const CString fileName) { + COleVariant vFile{ fileName }; + workingDocument.SaveAs(&vFile, &vtMissing, &vtMissing, + &vtMissing, &vtMissing, &vtMissing, &vtMissing, + &vtMissing, &vtMissing, &vtMissing, + &vtMissing, &vtMissing, &MSO::ovTrue, + &vtMissing, &vtMissing, &vtMissing); +} + +} // namespace xtr::io \ No newline at end of file diff --git a/src/io/RSMLegacyLoader.cpp b/src/io/RSMLegacyLoader.cpp new file mode 100644 index 0000000..6467d2e --- /dev/null +++ b/src/io/RSMLegacyLoader.cpp @@ -0,0 +1,288 @@ +#include "stdafx.h" + +#include "xtr/io/RSMLegacyLoader.h" + +#include "xtr/io/TRSLegacyLoader.h" + +using ccl::rslang::Typification; +using ccl::object::StructuredData; +using ccl::object::Factory; +using ccl::object::SDCompact; +using ccl::semantic::TextInterpretation; +using ccl::semantic::ConceptRecord; +using ccl::semantic::CstType; +using ccl::semantic::EvalStatus; + +namespace xtr::io { + +namespace { + +class LegacyUnpacker { +public: + explicit LegacyUnpacker(const RSMLegacyLoader::LegacyData& data) noexcept + : data{ data } {} + +private: + const RSMLegacyLoader::LegacyData& data; + + uint32_t pos_x{ 0 }; + uint32_t pos_y{ 0 }; + +public: + std::optional UnpackFor(const Typification& type) { + if (size(data) > pos_x && size(data.at(pos_x)) > pos_y) { + switch (type.Structure()) { + case ccl::rslang::StructureType::basic: + return UnpackBasic(); + case ccl::rslang::StructureType::collection: + return UnpackBool(type); + case ccl::rslang::StructureType::tuple: + return UnpackTuple(type); + } + } + return std::nullopt; + } + +protected: + [[nodiscard]] StructuredData UnpackBasic() { + auto result = Factory::Val(data.at(pos_x).at(pos_y)); + ++pos_y; + return result; + } + + [[nodiscard]] std::optional UnpackBool(const Typification& type) { + auto result = Factory::EmptySet(); + const auto bool_y = pos_y; + const auto element_y = bool_y + 1; + const auto base_x = pos_x; + while (size(data) > pos_x) { + if (size(data.at(pos_x)) < element_y || + FirstElementsAreNotEqual(base_x, pos_x, element_y)) { + --pos_x; + return result; + } else { + pos_y = element_y; + + if (auto element = UnpackFor(type.B().Base()); !element.has_value()) { + return result; + } else if (!result.ModifyB().AddElement(element.value())) { + --pos_x; + return result; + } else { + ++pos_x; + } + } + } + return result; + } + + [[nodiscard]] std::optional UnpackTuple(const Typification& type) { + std::vector factorsData{}; + const auto arity = type.T().Arity(); + for (ccl::rslang::Index i = 0; i < arity; ++i) { + const auto& factor = type.T().Component(i + 1); + auto factorVal = UnpackFor(factor); + if (!factorVal.has_value()) { + return std::nullopt; + } + factorsData.emplace_back(factorVal.value()); + } + return Factory::Tuple(factorsData); + } + + [[nodiscard]] bool FirstElementsAreNotEqual(const uint32_t row1, const uint32_t row2, const uint32_t ymax) const { + for (auto y = 0U; y < ymax; ++y) { + if (data.at(row1).at(y) != data.at(row2).at(y)) { + return true; + } + } + return false; + } +}; + +} // namespace + +void RSMLegacyLoader::LoadVersion() { + const auto intro = ar.Load(); + if (intro != LR"(__@VERSION@__)") { + version = RSMVersion::old; + } else { + version = static_cast(ar.Load()); + ar.Skip(); + } +} + +void RSMLegacyLoader::DoLoad() { + const auto bFirstGen = version.v < RSMVersion::r1800; + LoadModelProperties(bFirstGen); + if (bFirstGen) { + LoadFirstGen(); + } else { + LoadSecondGen(); + } + model.Calculations().LoadCalulated(calculated); +} + +void RSMLegacyLoader::LoadFirstGen() { + auto countCst = ar.Load(); + ar.Skip(); + while (countCst--) { + LoadCst(); + } + + model.UpdateState(); + auto countData = ar.Load(); + while (countData--) { + LoadCstData(); + } +} + +void RSMLegacyLoader::LoadModelProperties(const BOOL loadModelName) { + model.title = ar.Load(); + model.alias = ar.Load(); + if (loadModelName) { + const auto modelName = ar.Load(); + if (empty(model.title)) { + model.title = modelName; + } + } + model.comment = ar.Load(); +} + +void RSMLegacyLoader::LoadCst() { + LegacyCstLoader cstLoader(ar); + if (version.v < RSMVersion::r1092) { + cstLoader.InitOldEncoding(); + } + cstLoader.LoadBasicProperties(); + cstLoader.LoadTerms(version.v >= RSMVersion::r1092, version.v >= RSMVersion::r1438); + cstLoader.LoadInterpretation(version.v >= RSMVersion::r1438); + + const auto bActive = ar.Load(); + ar.Skip(); + + cstLoader.LoadID(); + + ConceptRecord loadedCst = cstLoader.GetResult(); + const auto newCst = model.Load(std::move(loadedCst)); + if (bActive) { + selection.emplace(newCst); + } +} + +void RSMLegacyLoader::LoadCstData() { + const auto name = ar.Load(); + const auto status = static_cast(ar.Load()); + const auto skipData = + status == EvalStatus::UNKNOWN + || status == EvalStatus::NEVER_CALCULATED + || status == EvalStatus::INCALCULABLE; + + const auto uid = model.Core().FindAlias(name).value(); + if (status != EvalStatus::UNKNOWN && status != EvalStatus::NEVER_CALCULATED) { + calculated.insert(uid); + } + + const auto type = model.GetRS(uid).type; + if (ccl::semantic::IsCallable(type)) { + return; + } + + if (ccl::semantic::IsRSObject(type)) { + const auto structuredData = LoadRSITable(); + const auto textData = std::empty(structuredData) ? TextInterpretation{} : LoadTextData(FALSE); + if (!skipData) { + if (ccl::semantic::IsBaseSet(model.GetRS(uid).type)) { + model.Values().LoadData(uid, textData); + } else if (const auto* typification = model.GetParse(uid).Typification(); typification != nullptr) { + LegacyUnpacker unpacker(structuredData); + if (const auto val = unpacker.UnpackFor(*typification); val.has_value()) { + model.Values().LoadData(uid, val.value()); + } + } + } + } else { + const auto value = static_cast(ar.Load()); + if (!skipData) { + model.Values().LoadData(uid, value); + } + } +} + +SDCompact::Data RSMLegacyLoader::LoadRSITable() { + auto nRows = ar.Load(); + SDCompact::Data data(nRows); + for (size_t i = 0; nRows--; ++i) { + auto nCols = ar.Load(); + while (nCols--) { + data.at(i).emplace_back(ar.Load()); + } + } + return data; +} + +TextInterpretation RSMLegacyLoader::LoadTextData(const BOOL skipIndex) { + TextInterpretation data{}; + auto namesCount = ar.Load(); + while (namesCount--) { + if (skipIndex) { + ar.Skip(); + } + data.PushBack(ar.Load()); + } + return data; +} + +void RSMLegacyLoader::LoadSecondGen() { + ar.SkipN(3); + LegacyCoreLoader{ ar }.DoLoad(model.LoadCore()); + model.FinalizeLoadingCore(); + + ar.Skip(); + const auto modelName = ar.Load(); + if (empty(model.title)) { + model.title = modelName; + } + + auto calculatedCount = ar.Load(); + while (calculatedCount--) { + const auto uid = EntityUID{ ar.Load() }; + if (ar.Load()) { + calculated.insert(uid); + } + LoadDataFor(uid); + } + + auto selectedCount = ar.Load(); + while (selectedCount--) { + selection.emplace(EntityUID{ ar.Load() }); + } +} + +void RSMLegacyLoader::LoadDataFor(const EntityUID uid) { + const auto type = model.GetRS(uid).type; + if (ccl::semantic::IsCallable(type)) { + return; + } + if (ccl::semantic::IsRSObject(type)) { + if (ar.Load()) { + const auto compactedData = LoadRSITable(); + const auto* typification = model.GetParse(uid).Typification(); + if (typification != nullptr) { + const auto val = ccl::object::SDCompact::Unpack(compactedData, *typification); + if (val.has_value()) { + model.Values().LoadData(uid, val.value()); + } + } + } + if (ar.Load()) { + model.Values().LoadData(uid, LoadTextData(TRUE)); + } + } else { + if (ar.Load()) { + model.Values().LoadData(uid, ar.Load()); + } + } +} + +} // namespace xtr::io \ No newline at end of file diff --git a/src/io/SchemaExporter.cpp b/src/io/SchemaExporter.cpp new file mode 100644 index 0000000..315e171 --- /dev/null +++ b/src/io/SchemaExporter.cpp @@ -0,0 +1,59 @@ +#include "stdafx.h" + +#include "xtr/io/SchemaExporter.h" + +#include "xtr/cclDescriptor.h" +#include "xtr/io/RSForm2DOCX.h" + +#include "ccl/tools/JSON.h" + +namespace xtr::io { + +namespace { + +void OutputSchemaToCSV(std::ofstream& out, const ccl::semantic::RSForm& target) { + // TODO: extract CSV writer and escape quotes in fields + for (const auto uid : target.List()) { + const auto& rsCst = target.GetRS(uid); + const auto& textCst = target.GetText(uid); + out << uid << ';'; + out << rsCst.alias << ';'; + out << '"' << mfc::ToSTL(info::Label(target.GetParse(uid).TypePtr())) << '"' << ';'; + out << '"' << rsCst.definition << '"' << ';'; + out << '"' << textCst.term.Nominal() << '"' << ';'; + out << '"' << textCst.definition.Str() << '"' << ';'; + out << '"' << rsCst.convention << '"' << ';'; + out << '\n'; + } +} + +} // namespace + +BOOL SchemaExporter::Export(const SchemaOptions& params, const CString fileName, const FileType type) { + switch (type) { + default: return FALSE; + case FileType::docx: return io::RSForm2DOCX(target).Export(params, fileName); + case FileType::csv: { + std::ofstream file(fileName); + if (!file.is_open()) { + return FALSE; + } else { + OutputSchemaToCSV(file, target); + file.close(); + return TRUE; + } + } + case FileType::json: { + std::ofstream file(fileName); + if (!file.is_open()) { + return FALSE; + } else { + file << std::setw(4) << nlohmann::ordered_json(target); + file.close(); + return TRUE; + } + } + } +} + +} // namespace xtr::io \ No newline at end of file diff --git a/src/io/TRSLegacyLoader.cpp b/src/io/TRSLegacyLoader.cpp new file mode 100644 index 0000000..7825d2c --- /dev/null +++ b/src/io/TRSLegacyLoader.cpp @@ -0,0 +1,255 @@ +#include "stdafx.h" + +#include "xtr/io/TRSLegacyLoader.h" + +#include "xtr/core/Encoder.h" + +using ccl::semantic::ConceptRecord; +using ccl::semantic::CstType; +using ccl::lang::ManagedText; +using ccl::lang::LexicalTerm; + +namespace xtr::io { + +void LegacyCstLoader::LoadBasicProperties(BOOL oldType) { + const auto sName = ar.Load(); + auto sComment = ar.Load(); + const auto type = ar.Load(); + auto sExpression = ar.Load(); + + index::FixLegacy(sExpression); + index::FixLegacy(sComment); + if (sComment == sExpression) { + sComment.Empty(); + } + if (needEncoding) { + encode::EncodeToUnicode(sExpression); + encode::EncodeToUnicode(sComment); + } + + cst = std::make_unique(); + cst->type = oldType ? LoadV0CstType(type) : static_cast(type); + cst->alias = mfc::ToSTL(sName); + cst->rs = mfc::ToSTL(sExpression); + cst->convention = mfc::ToSTL(sComment); +} + +CstType LegacyCstLoader::LoadV0CstType(const int32_t code) noexcept { + switch (code) { + case 0x01: return CstType::base; // NOLINT + case 0x02: return CstType::constant; // NOLINT + case 0x03: return CstType::term; // NOLINT + case 0x04: return CstType::structured; // NOLINT + case 0x05: return CstType::axiom; // NOLINT + case 0x06: return CstType::term; // NOLINT + case 0x07: return CstType::axiom; // NOLINT + case 0x08: return CstType::term; // NOLINT + case 0x09: return CstType::term; // NOLINT + case 0x0A: return CstType::theorem; // NOLINT + case 0x0B: return CstType::function; // NOLINT + } + return CstType::base; +} + +void LegacyCstLoader::LoadTerms(const BOOL hasTerms, const BOOL multipleTerms) { + using ccl::lang::TERM_FORMS; + const int32_t terminCount = multipleTerms ? ar.Load() : 1; + std::vector terms(terminCount, CString{}); + std::vector termRefs(terminCount, CString{}); + std::vector> termForms(terminCount); + for (auto i = 0; i < terminCount; ++i) { + termForms.at(i).resize(size(TERM_FORMS), CString{}); + } + if (multipleTerms) { + for (auto i = 0; i < terminCount; ++i) { + terms.at(i) = ar.Load(); + termRefs.at(i) = ar.Load(); + for (auto j = 0; j < ssize(TERM_FORMS); ++j) { + termForms.at(i).at(j) = ar.Load(); + } + } + } else if (hasTerms) { + terms.at(0) = ar.Load();; + termRefs.at(0) = terms.at(0); + } + + cst->term = LexicalTerm{ mfc::ToSTL(termRefs.at(0)), mfc::ToSTL(terms.at(0)) }; + for (uint8_t j = 0; j < size(TERM_FORMS); ++j) { + cst->term.SetForm(TERM_FORMS.at(j), mfc::ToSTL(termForms.at(0).at(j))); + } +} + +void LegacyCstLoader::LoadInterpretation(const BOOL loadWithRef) { + auto sInterpretation = ar.Load(); + CString sInterpretationRef = sInterpretation; + if (loadWithRef) { + sInterpretationRef = ar.Load(); + } + if (needEncoding) { + encode::EncodeToUnicode(sInterpretation); + } + cst->definition = ManagedText{ mfc::ToSTL(sInterpretationRef), mfc::ToSTL(sInterpretation) }; +} + +void LegacyCstLoader::LoadID() { + cst->uid = ar.Load(); +} + +void LegacyCoreLoader::DoLoad(ccl::semantic::RSCore& core) { + auto cstCount = ar.Load(); + while (cstCount--) { + ccl::semantic::ConceptRecord cst{}; + cst.uid = ar.Load(); + cst.alias = ar.Load(); + cst.type = static_cast(ar.Load()); + cst.convention = ar.Load(); + cst.rs = ar.Load(); + cst.definition = LoadText(); + + auto count = ar.Load() - 1; + cst.term = LoadTerm(); + while (count--) { + [[maybe_unused]] const auto discardTerm = LoadTerm(); + } + core.Load(std::move(cst)); + } + core.UpdateState(); +} + +ccl::lang::ManagedText LegacyCoreLoader::LoadText() { + const auto rawText = ar.Load(); + const auto cache = ar.Load(); + return ccl::lang::ManagedText{ rawText, cache }; +} + +ccl::lang::LexicalTerm LegacyCoreLoader::LoadTerm() { + using ccl::lang::TERM_FORMS; + ccl::lang::LexicalTerm term{ LoadText() }; + for (uint8_t j = 0; j < size(TERM_FORMS); ++j) { + const auto manualForm = ar.Load(); + if (!std::empty(manualForm)) { + term.SetForm(TERM_FORMS.at(j), manualForm); + } + } + return term; +} + +void TRSLegacyLoader::LoadVersion() { + const auto versionIntro = ar.Load(); + if (versionIntro != LR"(__@VERSION@__)") { + schema.title = mfc::ToSTL(versionIntro); + version = TRSVersion::old; + } else { + auto versionID = ar.Load(); + versionID = versionID < TRSVersion::old ? versionID + TRSVersion::old : versionID; + version = static_cast(versionID); + ar.Skip(); + } +} + +void TRSLegacyLoader::DoLoad() { + LoadSchemaProperties(version.v != TRSVersion::old); + if (version.v < xtr::TRSVersion::r1800) { + LoadFirstGen(); + } else { + LoadSecondGen(); + } + schema.UpdateState(); +} + +void TRSLegacyLoader::LoadSchemaProperties(const BOOL loadFullName) { + if (loadFullName) { + schema.title = ar.Load(); + } + schema.alias = ar.Load(); + schema.comment = ar.Load(); +} + +void TRSLegacyLoader::LoadFirstGen() { + static constexpr auto CCONSTITUENTA_CLASS_PREFIX_LEN = 19; + auto countCst = ar.Load(); + if (version.v != TRSVersion::old) { + ar.Skip(); + } else if (countCst > 0) { + ar.SkipN(CCONSTITUENTA_CLASS_PREFIX_LEN); + } + while (countCst--) { + LoadCst(); + } +} + +void TRSLegacyLoader::LoadCst() { + LegacyCstLoader cstLoader{ ar }; + if (version.v < TRSVersion::r1092) { + cstLoader.InitOldEncoding(); + } + cstLoader.LoadBasicProperties(version.v == TRSVersion::old); + cstLoader.LoadTerms(version.v >= TRSVersion::r1092, version.v >= TRSVersion::r1438); + cstLoader.LoadInterpretation(version.v >= TRSVersion::r1438); + + const auto bActive = ar.Load(); + uint16_t inheritStats{ 0 }; + if (version.v != TRSVersion::old) { + inheritStats = ar.Load(); + cstLoader.LoadID(); + } else { + ar.SkipN(2); + try { + ar.SkipN(2); // in some older versions delimiter is not useCount for last element + } catch (...) {} + } + + ConceptRecord loadedCst = cstLoader.GetResult(); + const auto newCst = schema.Load(std::move(loadedCst)); + schema.MoveBefore(newCst, std::end(schema.List())); + + if (bActive) { + selection.emplace(newCst); + } + if (version.v >= TRSVersion::r1092) { + LoadInheritanceDataFromOldFlag(newCst, inheritStats); + } +} + +void TRSLegacyLoader::LoadInheritanceDataFromOldFlag(const EntityUID uid, const uint16_t loadedStatus) { + static constexpr int8_t CSO_INHERITED = 0x01; + static constexpr int8_t CSO_UNCHECKED = 0x02; + static constexpr int8_t CSO_TEXT_OWN = 0x08; + if ((loadedStatus & CSO_INHERITED) != 0) { + ccl::semantic::TrackingFlags mode{}; + if (((loadedStatus & CSO_UNCHECKED) != 0) || (loadedStatus & CSO_TEXT_OWN) != 0) { + mode.allowEdit = true; + mode.term = true; + mode.definition = true; + mode.convention = true; + } + schema.Mods().Track(uid, mode); + } +} + +void TRSLegacyLoader::LoadSecondGen() { + ar.SkipN(3); + LegacyCoreLoader{ ar }.DoLoad(schema.LoadCore()); + LoadInheritance(); + + isClaimed = ar.Load(); + auto count = ar.Load(); + while (count--) { + selection.emplace(ar.Load()); + } +} + +void TRSLegacyLoader::LoadInheritance() { + auto modCount = ar.Load(); + while (modCount--) { + const auto uid = ar.Load(); + ccl::semantic::TrackingFlags props{}; + props.allowEdit = ar.Load(); + props.term = ar.Load(); + props.definition = ar.Load(); + props.convention = ar.Load(); + schema.Mods().Track(EntityUID{ uid }, props); + } +} + +} // namespace xtr::io \ No newline at end of file diff --git a/src/mfcHelper.cpp b/src/mfcHelper.cpp new file mode 100644 index 0000000..6c233fa --- /dev/null +++ b/src/mfcHelper.cpp @@ -0,0 +1,119 @@ +#include "stdafx.h" + +namespace xtr::mfc { + +static constexpr auto MAX_PATH_LENGHT = 1024; + +#pragma warning( push ) +#pragma warning( disable : 26446 ) // Note: ignore gsl::at + +CString ToMFC(const std::string_view str) { + if (empty(str)) { + return {}; + } + const auto size_input = static_cast(ssize(str)); + const auto size_needed = ::MultiByteToWideChar(CP_UTF8, 0, &str[0], size_input, nullptr, 0); + CString result{}; + auto* buffer = result.GetBuffer(size_needed); + const auto realSize = ::MultiByteToWideChar(CP_UTF8, 0, &str[0], size_input, buffer, size_needed); + result.ReleaseBuffer(realSize); + return result; +} + +CString ToMFC(const std::u8string_view str) { + std::string intermediary(reinterpret_cast(str.data()), ssize(str)); + return ToMFC(intermediary); +} + +std::string ToSTL(const CString str) { + if (str.IsEmpty()) { + return {}; + } + const auto size_needed = ::WideCharToMultiByte(CP_UTF8, 0, str.GetString(), str.GetLength(), nullptr, 0, nullptr, nullptr); + std::string result(size_needed, 0); + ::WideCharToMultiByte(CP_UTF8, 0, str.GetString(), str.GetLength(), &result[0], size_needed, nullptr, nullptr); + return result; +} + +std::u8string ToUTF8(const CString str) { + auto result = ToSTL(str); + return std::u8string{ begin(result), end(result) }; +} + +#pragma warning( pop ) + +CString LoadSID(const uint32_t sid) { + CString result{}; + if (!result.LoadStringW(sid)) { + throw std::runtime_error(std::format("Failed loading string from table. ID: {}", sid)); + } else { + return result; + } +} + +std::optional FileStatus(const CFile& file) { + CFileStatus status; + if (!file.GetStatus(status)) { + return std::nullopt; + } else { + return status; + } +} + +CString FirstWordOf(const CString str) { + auto strPos = 0; + CString word = str.Tokenize(L" \n\r", strPos).Trim(); + if (word.IsEmpty()) { + word = str; + } + return word; +} + +std::optional FindBracketEndOrStart(const CString inputText, + const BracketSearchParams& searchParams, + bool findStart) { + const auto inputLen = inputText.GetLength(); + if (searchParams.initialPosition > inputLen || + searchParams.initialPosition < 0 || inputLen < 0) { + return std::nullopt; + } else { + auto currentLevel = findStart ? -1 : 1; + auto pos = searchParams.initialPosition; + if (findStart) { + if (pos == 0) { + return std::nullopt; + } + --pos; + } + for (; (findStart && pos >= 0) || (!findStart && pos <= inputLen); + pos += (findStart ? -1 : 1)) { + if (inputText[pos] == searchParams.closeBracket) { + --currentLevel; + } else if (inputText[pos] == searchParams.openBracket) { + ++currentLevel; + } + if (currentLevel == 0) { + return pos; + } + } + return std::nullopt; + } +} + +std::optional FindOpeningParanthesis(const CString text, const int startPos) { + return FindBracketBlockStart(text, { '(', ')', startPos }); +} + +std::optional FindClosingParanthesis(const CString text, const int startPos) { + return FindBracketBlockEnd(text, { '(', ')', startPos }); +} + +std::optional FindBracketBlockStart(const CString inputText, const BracketSearchParams& searchParams) { + return FindBracketEndOrStart(inputText, searchParams, true); +} + +std::optional FindBracketBlockEnd(const CString inputText, const BracketSearchParams& searchParams) { + return FindBracketEndOrStart(inputText, searchParams, false); +} + +} // namespace xtr::mfc diff --git a/src/mfcMessageManager.cpp b/src/mfcMessageManager.cpp new file mode 100644 index 0000000..906944f --- /dev/null +++ b/src/mfcMessageManager.cpp @@ -0,0 +1,18 @@ +#include "stdafx.h" + +#include "xtr/mfcMessageManager.h" + +#include "afxwin.h" + +namespace xtr { + +uint32_t mfcMessageManager::ShowMessage(const CString text, const uint32_t type) { + return static_cast(::AfxMessageBox(text, static_cast(type))); +} + +uint32_t mfcMessageManager::ShowMessage(uint32_t messageID, const uint32_t type) { + return static_cast(::AfxMessageBox(static_cast(messageID), static_cast(type))); +} + + +} // namespace xtr \ No newline at end of file diff --git a/src/pch/stdafx.cpp b/src/pch/stdafx.cpp new file mode 100644 index 0000000..7715608 --- /dev/null +++ b/src/pch/stdafx.cpp @@ -0,0 +1,6 @@ +// stdafx.cpp : source file that includes just the standard includes +// stdafx.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled opType information + +#include "stdafx.h" + diff --git a/src/pch/stdafx.h b/src/pch/stdafx.h new file mode 100644 index 0000000..7a23827 --- /dev/null +++ b/src/pch/stdafx.h @@ -0,0 +1,70 @@ +#pragma once + +#define _WIN32_WINNT _WIN32_WINNT_WIN7 + +#pragma warning( disable : 4290 ) +#define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING // NOLINT + +// MFC +#define _AFX_ALL_WARNINGS // NOLINT + +#pragma warning( push ) +#pragma warning( disable : 4302 4311 ) + +#include "afxwin.h" +#include "afxcontrolbars.h" + +#undef min +#undef max +#undef IN + +#pragma warning( pop ) + +// STL +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// POCO +#ifdef _MSC_VER + #pragma warning( push ) + #pragma warning( disable : 4244 ) + #pragma warning( disable : 5054 ) +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER + #pragma warning( pop ) +#endif + +// OfficeOLE +#include "office/Office.h" + +// CCL +#include "ccl/env/cclEnvironment.h" +#include "ccl/semantic/RSCore.h" +#include "ccl/semantic/RSForm.h" +#include "ccl/semantic/RSModel.h" +#include "ccl/oss/OSSchema.h" + +using ccl::StrPos; +using ccl::StrRange; +using ccl::EntityUID; +using ccl::VectorOfEntities; +using ccl::SetOfEntities; + +// xtrCore +#include "xtr/mfcHelper.h" \ No newline at end of file diff --git a/src/ui/BuffRichEdit.cpp b/src/ui/BuffRichEdit.cpp new file mode 100644 index 0000000..3192e32 --- /dev/null +++ b/src/ui/BuffRichEdit.cpp @@ -0,0 +1,407 @@ +#include "stdafx.h" + +#include "xtr/ui/BuffRichEdit.h" + +#include "xtr/core/Encoder.h" +#include "xtr/ExteorOptions.h" + +#include "xtr/ui/KeyboardHandler.h" +#include "xtr/ui/UIHelper.h" + +#include "richole.h" + +#include "resource.h" + +namespace xtr::ui { + +static constexpr BOOL REDIT_CAN_UNDO = TRUE; + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(BuffRichEdit, CRichEditCtrl) + ON_WM_KEYDOWN() + ON_WM_KEYUP() + ON_WM_SETCURSOR() + ON_WM_SETFOCUS() + ON_WM_KILLFOCUS() + + ON_CONTROL_REFLECT_EX(EN_CHANGE, &ThisClass::OnTextChange) + ON_NOTIFY_REFLECT_EX(EN_SELCHANGE, &ThisClass::OnSelChange) + ON_NOTIFY_REFLECT_EX(EN_LINK, &ThisClass::OnEnLink) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +CString BuffRichEdit::Text() const { + auto text = WindowText(*this); + text.Replace(L"\r\n", L"\n"); + return text; +} + +void BuffRichEdit::InitRE(const Keyboard::Layout kl, const BOOL _enableFormat, const BOOL _enableTooltip) { + enableFormat = _enableFormat; + enableTooltip = _enableTooltip; + defaultKL = kl; + + SetEventMask(GetEventMask() | ENM_CHANGE | ENM_SELCHANGE | ENM_LINK); + InitToolTips(); + UpdateFormat(); +} + +CPoint BuffRichEdit::GetSubscriptDialogPosition() const { + const auto rect = WindowRect(*this); + + const auto x = rect.left + GetCaretPos().x; + auto y = rect.top + GetCaretPos().y; + + const auto metrics = TextMetricsOf(*this); + y += metrics.tmHeight + metrics.tmExternalLeading; + return { x, y }; +} + +CString BuffRichEdit::FixSelection() { + if (auto selection = GetSelectionRange(); selection.length() == 0) { + selection = ExpandRange(selection); + SelectRange(selection); + } + return GetSelText(); +} + +StrRange BuffRichEdit::GetSelectionRange() const { + long nSelStart{}; + long nSelEnd{}; + GetSel(nSelStart, nSelEnd); + if (nSelEnd > GetTextLength()) { + nSelEnd = std::max(nSelStart, GetTextLength()); + } + return StrRange{ static_cast(nSelStart), static_cast(nSelEnd) }; +} + +void BuffRichEdit::SelectRange(const StrRange range) { + SetSel(range.start, range.finish); +} + +void BuffRichEdit::SelectChar(const StrPos position) { + SetSel(position, position + 1); +} + +void BuffRichEdit::SelectAll() { + SetSel(0, mfc::noItems); +} + +void BuffRichEdit::MoveCaretTo(const StrPos position) { + SetSel(position, position); +} + +void BuffRichEdit::SetReadOnly(const BOOL readOnlyFlag) { + readOnly = readOnlyFlag; + CRichEditCtrl::SetReadOnly(readOnlyFlag); + UpdateBackground(); +} + +void BuffRichEdit::LockInput() { + if (!readOnly) { + CRichEditCtrl::SetReadOnly(TRUE); + UpdateBackground(); + } +} + +void BuffRichEdit::UnlockInput() { + if (!readOnly) { + CRichEditCtrl::SetReadOnly(FALSE); + UpdateBackground(); + } +} + +void BuffRichEdit::InitToolTips() { + if (!tooltips.Create(this)) { + TRACE(L"Unable to create the ToolTip!"); + } else { + tooltips.SetMaxTipWidth(s_TooltipWidth); + tooltips.AddTool(this, defaultToolTipText); + tooltips.SetFont(&XTROptions::App().fontTooltip); + + tooltips.Activate(enableTooltip); + } +} + +void BuffRichEdit::UpdateFormat(BOOL ignoreSelection) { + if (alreadyUpdating) { + return; + } else if (UpdateBackground(); !enableFormat) { + return; + } else if (const auto selection = GetSelectionRange(); + !ignoreSelection && + (selection.start != selection.finish || + (selection.start == cursorFormatPos && selection.start != 0))) { + return; + } else { + alreadyUpdating = TRUE; + cursorFormatPos = selection.start; + + FreezeUI(); + + ResetFormatting(); + UpdateFormatItems(); // Note: overridable + ApplyFormatTokens(); + + MoveCaretTo(cursorFormatPos); + AdditionalFormat(); // Note: overridable + + SelectAndFormat(StrRange{ cursorFormatPos, cursorFormatPos }, DefaultFormat()); + + UnFreezeUI(); + + alreadyUpdating = FALSE; + } +} + +void BuffRichEdit::ResetFormatting() { + auto defaultFormat = DefaultFormat(); + SelectAll(); + SetSelectionCharFormat(defaultFormat); +} + +void BuffRichEdit::UpdateBackground() { + if ((GetStyle() & ES_READONLY) != 0) { + SetBackgroundColor(FALSE, GetSysColor(COLOR_3DFACE)); + } else { + SetBackgroundColor(FALSE, GetSysColor(COLOR_WINDOW)); + } +} + +void BuffRichEdit::ApplyFormatTokens() { + for (auto& item : formatItems) { + SetSel(item.cr.start, item.cr.finish); + SetSelectionCharFormat(item.format); + } +} + +BOOL BuffRichEdit::PreTranslateMessage(MSG* pMsg) { + if (tooltips.m_hWnd != nullptr) { + tooltips.RelayEvent(pMsg); + } + if (pMsg->message == WM_KEYDOWN) { + if ((GetStyle() & ES_MULTILINE) != 0 && + pMsg->wParam == VK_RETURN && + !Keyboard::IsPressed(VK_CONTROL)) { + InsertChar(VK_RETURN); + return TRUE; + } + } + return CRichEditCtrl::PreTranslateMessage(pMsg); +} + +void BuffRichEdit::OnSetFocus(CWnd* pOldWnd) { + CRichEditCtrl::OnSetFocus(pOldWnd); + Keyboard::Instance().SetLayout(defaultKL); +} + +void BuffRichEdit::OnKillFocus(CWnd* pOldWnd) { + CRichEditCtrl::OnKillFocus(pOldWnd); + UpdateFormat(TRUE); + defaultKL = Keyboard::Instance().GetLayout(); +} + +BOOL BuffRichEdit::OnTextChange() { + UpdateFormat(); + return FALSE; +} + +BOOL BuffRichEdit::OnSelChange(NMHDR* /*pNotifyStruct*/, LRESULT* /*result*/) { + UpdateFormat(); + return FALSE; +} + +BOOL BuffRichEdit::OnSetCursor(CWnd* pWnd, uint32_t nHitTest, uint32_t message) { + if (enableTooltip && GetSelText().GetLength() != 0) { + tooltips.UpdateTipText(GenerateToolTipText(), this); + } + return CRichEditCtrl::OnSetCursor(pWnd, nHitTest, message); +} + +void BuffRichEdit::OnKeyDown(uint32_t nChar, uint32_t nRepCnt, uint32_t nFlags) { + switchLayoutOnCtrl = nChar == VK_CONTROL; + + if (nChar == 'C' && Keyboard::IsPressed(VK_CONTROL)) { + DeepCopy(); + return; + } + + CRichEditCtrl::OnKeyDown(nChar, nRepCnt, nFlags); +} + +void BuffRichEdit::DeepCopy() { + if (!OpenClipboard()) { + ::AfxMessageBox(IXTRE_CLIPBOARD_OPEN, MB_ICONERROR); + } else if (!EmptyClipboard()) { + ::AfxMessageBox(IXTRE_CLIPBOARD_CLEAR, MB_ICONERROR); + } else { + if (auto cpyStr = GetSelText(); !cpyStr.IsEmpty()) { + if (auto* hGlob = GlobalAlloc(GMEM_FIXED, (wcslen(cpyStr) + 1) * sizeof(wchar_t)); + hGlob != nullptr) { + wcscpy_s(static_cast(hGlob), wcslen(cpyStr) + 1, cpyStr); + if (::SetClipboardData(CF_UNICODETEXT, hGlob) == nullptr) { + ::AfxMessageBox(IXTRE_CLIPBOARD_COPY, MB_ICONERROR); + GlobalFree(hGlob); + } + } + } + ::CloseClipboard(); + } +} + +void BuffRichEdit::OnKeyUp(uint32_t nChar, uint32_t nRepCnt, uint32_t nFlags) { + if (nChar != VK_CONTROL || !switchLayoutOnCtrl) { + CRichEditCtrl::OnKeyUp(nChar, nRepCnt, nFlags); + } else { + switchLayoutOnCtrl = FALSE; + CRichEditCtrl::OnKeyUp(nChar, nRepCnt, nFlags); + Keyboard::Instance().RotateLayout(); + } +} + +BOOL BuffRichEdit::OnEnLink(NMHDR *pNMHDR, LRESULT *pResult) { + const auto* pEnLink = reinterpret_cast(pNMHDR); + *pResult = FALSE; + if (pEnLink == nullptr || pEnLink->msg != WM_LBUTTONDOWN) { + return FALSE; + } + + CString strUrl{}; + GetTextRange(pEnLink->chrg.cpMin, pEnLink->chrg.cpMax, strUrl); + ::ShellExecuteW(nullptr, nullptr, strUrl, nullptr, nullptr, SW_SHOW); + return TRUE; +} + +void BuffRichEdit::InsertChar(const uint32_t ch) { + if ((GetStyle() & ES_READONLY) == 0) { + CString str{}; + str.AppendChar(static_cast(ch)); + ReplaceSel(str, REDIT_CAN_UNDO); + UpdateFormat(); + } +} + +void BuffRichEdit::InsertString(const CString str) { + if ((GetStyle() & ES_READONLY) == 0) { + ReplaceSel(str, REDIT_CAN_UNDO); + UpdateFormat(); + } +} + +CHARFORMAT2W BuffRichEdit::GetSelectionFormat() const { + CHARFORMAT2W format{}; + GetSelectionCharFormat(format); + return format; +} + +CHARFORMAT2W BuffRichEdit::DefaultFormat() const { + CHARFORMAT2W format{}; + GetDefaultCharFormat(format); + return format; +} + +void BuffRichEdit::SelectAndFormat(const StrRange range, CHARFORMAT2W format) { + SelectRange(range); + SetSelectionCharFormat(format); +} + +StrRange BuffRichEdit::ExpandRange(StrRange cr) const { + auto start = cr.start; + auto end = cr.finish; + const auto text = Text(); + while (start != end && encode::IsAlphaNumber(text[start])) { + ++start; + } + while (start != end && encode::IsAlphaNumber(text[end])) { + --end; + } + while (start > 0 && encode::IsAlphaNumber(text[start - 1])) { + --start; + } + while (end < text.GetLength() && encode::IsAlphaNumber(text[end])) { + ++end; + } + return StrRange{ start, end }; +} + +//TOM интерфейс ITextDocument +EXTERN_C const GUID CDECL IID_ITextDocument = { + 0x8CC497C0, 0xA1DF, 0x11CE, { 0x80, 0x98, 0x00, 0xAA, 0x00, 0x47, 0xBE, 0x5D } +}; + +ITextDocument* BuffRichEdit::GetFixedTextDocumentInterface() const { + ITextDocument* tdi{}; + IUnknown *tr_code = GetIRichEditOle(); + tr_code->QueryInterface(IID_ITextDocument, reinterpret_cast(&tdi)); + return tdi; +} + +void BuffRichEdit::FreezeUI() { + static constexpr auto UI_FREEZE_TIME_MS = 1000; + if (textInterface != nullptr) { + ++freezeCount; + return; + } else { + textInterface = GetFixedTextDocumentInterface(); + +#pragma warning( push ) +#pragma warning( disable : 6387 ) + // 2nd parameter of Undo can be nullptr according to documentation + textInterface->Undo(tomSuspend, nullptr); +#pragma warning( pop ) + + freezeUID = std::make_unique(UI_FREEZE_TIME_MS); + textInterface->Freeze(freezeUID.get()); + + eventOptions = GetEventMask(); + SetEventMask(0); + + HideCaret(); + HideSelection(TRUE, FALSE); + + storedSelection = GetSelectionRange(); + freezeCount = 1; + } +} + +void BuffRichEdit::UnFreezeUI() { + if (freezeUID == nullptr || textInterface == nullptr) { + return; + } else if (--freezeCount; freezeCount > 0) { + return; + } else { + SelectRange(storedSelection); + + ShowCaret(); + HideSelection(FALSE, FALSE); + + SetEventMask(eventOptions); + + textInterface->Unfreeze(freezeUID.get()); + +#pragma warning( push ) +#pragma warning( disable : 6387 ) + // 2nd parameter of Undo can be nullptr according to documentation + textInterface->Undo(tomResume, nullptr); +#pragma warning( pop ) + + textInterface->Release(); + + textInterface = nullptr; + freezeUID = nullptr; + storedSelection = {}; + freezeCount = 0; + } +} + +void BuffRichEdit::UnFreezeUI(StrRange newSelection) { + if (freezeCount == 1) { + storedSelection = newSelection; + } + UnFreezeUI(); +} + +} // namespace xtr::ui \ No newline at end of file diff --git a/src/ui/ComHelper.cpp b/src/ui/ComHelper.cpp new file mode 100644 index 0000000..6b71b9b --- /dev/null +++ b/src/ui/ComHelper.cpp @@ -0,0 +1,21 @@ +#include "stdafx.h" + +#include "xtr/ui/ComHelper.h" + +namespace xtr::ui { + +ComInitializer::ComInitializer() { + const auto result = ::CoInitializeEx(nullptr, COINIT_MULTITHREADED); + needClose = result == S_OK; + if (needClose) { + assert(SUCCEEDED(result)); + } +} + +ComInitializer::~ComInitializer() { + if (needClose) { + CoUninitialize(); + } +} + +} // namespace xtr::ui diff --git a/src/ui/DataGridCtrl.cpp b/src/ui/DataGridCtrl.cpp new file mode 100644 index 0000000..c155871 --- /dev/null +++ b/src/ui/DataGridCtrl.cpp @@ -0,0 +1,663 @@ +#include "stdafx.h" + +#include "xtr/ui/DataGridCtrl.h" + +#include "resource.h" + +#include "xtr/ExteorOptions.h" +#include "xtr/doc/RSModelDoc.h" + +#include "xtr/ui/KeyboardHandler.h" +#include "xtr/ui/UIHelper.h" + +namespace xtr::ui { + +using ccl::semantic::TextInterpretation; +using ccl::object::SDCompact; + +static constexpr auto DATA_TABLE_WIDTH_BOOL = 30; +static constexpr auto DATA_TABLE_WIDTH_BSET = 60; +static constexpr auto DATA_TABLE_WIDTH_TEXT = 140; + +static constexpr auto NO_SELECTION = -2; + +static constexpr auto ENSURE_ARROW = 2; +static constexpr auto ENSURE_NUMBER = 1; +static constexpr auto ENSURE_NONE = 0; + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(DataGridCtrl, CListCtrl) + ON_WM_MOUSEMOVE() + ON_WM_SETFOCUS() + ON_WM_PAINT() + + ON_NOTIFY_REFLECT(NM_CLICK, &ThisClass::OnClick) + ON_NOTIFY_REFLECT(NM_DBLCLK, &ThisClass::OnDbClick) + ON_NOTIFY_REFLECT(LVN_KEYDOWN, &ThisClass::OnKeydown) + ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &ThisClass::OnCustomDraw) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +DataGridCtrl::DataGridCtrl() + : ensureVisible{ ENSURE_NONE }, selectedRow{ NO_SELECTION }, selectedColumn{ NO_SELECTION } {} + +void DataGridCtrl::Init(CComboBox* box, BOOL textFlag, doc::RSModelDoc& _doc) { + m_Doc = &_doc; + model = &m_Doc->Model(); + editCtrl = box; + showText = textFlag; + + SetFont(&XTROptions::App().fontData); + SetExtendedStyle(GetExtendedStyle() | LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT); + + InitToolTips(); +} + +void DataGridCtrl::InitToolTips() { + static constexpr auto widthTooltip = 350; + + if (tooltips.Create(this)) { + tooltips.SetMaxTipWidth(widthTooltip); + tooltips.AddTool(this, mfc::LoadSID(IXTRS_DEFAULT_TOOLTIP_DATA)); + tooltips.SetFont(&XTROptions::App().fontData); + tooltips.Activate(TRUE); + } else { + TRACE(L"Unable to create the ToolTip!"); + } +} + +void DataGridCtrl::SetTextFlag(BOOL flag) { + if (flag != showText) { + showText = flag; + Invalidate(); + } +} + +void DataGridCtrl::SetActive(const EntityUID activeUID) { + const auto cstType = model->GetRS(activeUID).type; + activeCst = activeUID; + isEditable = ccl::semantic::IsBaseNotion(cstType); + isBasic = ccl::semantic::IsBaseSet(cstType); + typification = model->Core().GetParse(activeCst).Typification(); + isModified = FALSE; + + ReloadData(); + UpdateData(FALSE); + isModified = FALSE; +} + +void DataGridCtrl::ReloadData() { + SetRedraw(FALSE); + Clear(); + if (typification != nullptr) { + if (isBasic) { + LoadBasicData(); + } else { + LoadSData(); + } + } + SetRedraw(TRUE); +} + +void DataGridCtrl::Clear() { + DeleteAllItems(); + while (DeleteColumn(0)) { ; } + headerIDs.clear(); + columnCount = 0; + selectedRow = selectedColumn = NO_SELECTION; + Invalidate(); +} + +void DataGridCtrl::LoadBasicData() { + CreateBasicHeader(mfc::ToMFC(model->GetRS(activeCst).alias)); + if (const auto* interp = model->Values().TextFor(activeCst); interp != nullptr) { + InputTextData(*interp); + } +} + +void DataGridCtrl::LoadSData() { + const auto data = model->Values().SDataFor(activeCst); + CreateHeader(); + if (data.has_value()) { + const auto compact = SDCompact::FromSData(data.value(), *typification); + InputStructuredtData(compact.data); + } +} + +void DataGridCtrl::UpdateSelectedCellText() { + Invalidate(); + + editCtrl->ShowWindow(SW_HIDE); + + auto ctxt = WindowText(*editCtrl); + auto oldTxt = mfc::ToSTL(ctxt); + if (!isBasic && showText && headerIDs.at(selectedColumn).has_value() && !std::empty(oldTxt)) { + const auto headID = *headerIDs.at(selectedColumn); + const auto* interp = model->Values().TextFor(headID); + auto id = interp->GetInterpreteeOf(oldTxt); + if (!id.has_value()) { + if (::AfxMessageBox(mfc::FormatSID(IXTRS_DATA_ADD_BASE_ELEMENT, + ctxt.GetString(), + mfc::ToMFC(model->GetRS(headID).alias).GetString()), + MB_YESNO | MB_DEFBUTTON1) == IDYES) { + id = model->Values().AddBasicElement(headID, oldTxt); + } else { + return; + } + } + ctxt.Empty(); + ctxt.AppendFormat(LR"(%ld)", *id); + } + SetTableItem(selectedRow, selectedColumn, ctxt); +} + +void DataGridCtrl::SaveData() { + if (!isEditable || !isModified || typification == nullptr) { + return; + } + + if (isBasic) { + TextInterpretation newInterp{}; + for (auto i = 0; i < GetItemCount(); ++i) { + if (auto text = mfc::ToSTL(GetItemText(i, 1)); !std::empty(text)) { + newInterp.PushBack(text); + } + } + model->Values().SetBasicText(activeCst, newInterp); + } else { + const auto idTable = GetIDTable(); + auto data = SDCompact::Unpack(idTable, *typification); + if (!data.has_value()) { + if (typification->IsCollection()) { + model->Values().ResetDataFor(activeCst); + } + } else { + model->Values().SetStructureData(activeCst, data.value()); + } + isModified = FALSE; + } +} + +SDCompact::Data DataGridCtrl::GetIDTable() const { + SDCompact::Data result{}; + const auto itemCount = GetItemCount(); + for (auto i = 0; i < itemCount; ++i) { + if (!GetItemText(i, 0).IsEmpty()) { + SDCompact::Data::value_type row{}; + if (typification->IsCollection()) { + row.emplace_back(SDCompact::unknownCount); + } + for (auto j = 0; j < columnCount; ++j) { + if (const auto str = GetItemText(i, j); !str.IsEmpty()) { + row.emplace_back(_wtoi(str)); + } else { + break; + } + } + result.emplace_back(row); + } + } + return result; +} + +void DataGridCtrl::InputTextData(const TextInterpretation& input) { + auto nItem = 0; + for (const auto& it : input) { + auto index = it.first; + auto inrepretantName = mfc::ToMFC(input.GetInterpretantFor(index)); + CString inrepretantIndex{}; + inrepretantIndex.AppendFormat(LR"(%ld)", index); + + InsertItem(nItem, CString{}); + SetItemText(nItem, 0, inrepretantIndex); + SetItemText(nItem, 1, inrepretantName); + ++nItem; + } +} + +void DataGridCtrl::InputStructuredtData(const SDCompact::Data& data) { + CString str{}; + const auto indexStart = typification->IsCollection() ? 1 : 0; + for (auto i = 0; i < ssize(data); ++i) { + InsertItem(i, CString{}); + for (auto j = indexStart; j < ssize(data.at(i)); ++j) { + str.Empty(); + str.AppendFormat(LR"(%ld)", data.at(i).at(j)); + SetItemText(i, j - indexStart, str); + } + } +} + +void DataGridCtrl::CreateBasicHeader(const CString basicName) { + InsertColumn(columnCount++, basicName, LVCFMT_CENTER, DATA_TABLE_WIDTH_BSET); + InsertColumn(columnCount++, mfc::LoadSID(IXTRS_HEADER_INTERPRETATION), LVCFMT_CENTER, DATA_TABLE_WIDTH_TEXT); +} + +void DataGridCtrl::CreateHeader() { + const auto dataHeader = SDCompact::CreateHeader(*typification); + auto header = begin(dataHeader); + if (typification->IsCollection()) { + ++header; + } + for ( ; header != end(dataHeader); ++header) { + const auto width = *header == "B" ? DATA_TABLE_WIDTH_BOOL : DATA_TABLE_WIDTH_BSET; + headerIDs.emplace_back(model->Core().FindAlias(*header)); + InsertColumn(columnCount++, mfc::ToMFC(*header), LVCFMT_CENTER, width); + } +} + +BOOL DataGridCtrl::PreTranslateMessage(MSG* pMsg) { + if (tooltips.m_hWnd != nullptr) { + tooltips.RelayEvent(pMsg); + } + if (pMsg->message == WM_KEYDOWN) { + if (pMsg->wParam == VK_RETURN) { + ShowEditWindowAtCell(selectedRow, selectedColumn); + return TRUE; + } else if (pMsg->wParam == VK_F5 && !editCtrl->IsWindowVisible()) { + SortData(); + return TRUE; + } + } + return CListCtrl::PreTranslateMessage(pMsg); +} + +void DataGridCtrl::ShowEditWindowAtCell(int32_t row, int32_t col) { + static constexpr auto CELL_EDIT_XOFFSET = 5; + static constexpr auto CELL_EDIT_YOFFSET = 5; + static constexpr auto CELL_EDIT_WIDTHOFFSET = 3; + if (row < 0 || col < 0) { + return; + } else if (!isEditable || editCtrl == nullptr) { + return; + } else if (isBasic && col == 0) { + return; + } + + editCtrl->ResetContent(); + auto str = GetItemText(row, col); + if (!isBasic && showText && headerIDs.at(col).has_value()) { + auto headID = *headerIDs.at(col); + const auto id = _wtoi(str); + const auto& interp = *model->Values().TextFor(headID); + if (interp.HasInterpretantFor(id)) { + str = mfc::ToMFC(interp.GetInterpretantFor(id)); + } + for (const auto& it : interp) { + auto dataName = mfc::ToMFC(it.second); + editCtrl->AddString(dataName); + } + } + + CRect cell{}; + GetSubItemRect(row, col, LVIR_BOUNDS, cell); + + const auto dataRect = WindowRect(*this); + const auto dialogRect = WindowRect(*GetParent()); + const auto x = cell.left + dataRect.left - dialogRect.left; + const auto y = cell.top + dataRect.top - dialogRect.top; + + editCtrl->SetWindowPos(&wndTop, x + CELL_EDIT_XOFFSET, y + CELL_EDIT_YOFFSET, + cell.Width() + CELL_EDIT_WIDTHOFFSET, cell.Height(), SWP_SHOWWINDOW); + editCtrl->SetFocus(); + editCtrl->SetWindowTextW(str); + editCtrl->RedrawWindow(); +} + +void DataGridCtrl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult) { + auto& drawer = reinterpret_cast< NMLVCUSTOMDRAW&>(*pNMHDR); + const auto stage = drawer.nmcd.dwDrawStage; + *pResult = [&] { + switch (stage) { + default: return CDRF_DODEFAULT; + case CDDS_PREPAINT: return CDRF_NOTIFYITEMDRAW; + case CDDS_ITEMPREPAINT: return CDRF_NOTIFYSUBITEMDRAW; + case CDDS_SUBITEM | CDDS_ITEMPREPAINT: return CDRF_SKIPDEFAULT; + } + }(); + + if (stage == CDDS_PREPAINT) { + OnFirstDraw(); + } else if (stage == (CDDS_SUBITEM | CDDS_ITEMPREPAINT)) { + OnDrawItem(drawer); + } +} + +void DataGridCtrl::OnFirstDraw() { + if (isBasic) { + if (isEditable && (GetItemCount() == 0 || !GetItemText(GetItemCount() - 1, 1).IsEmpty())) { + AddBaseRow(); + } + } else if (GetItemCount() == 0 || (isEditable && !GetItemText(GetItemCount() - 1, 0).IsEmpty())) { + InsertItem(GetItemCount(), CString{}); + } +} + +void DataGridCtrl::OnDrawItem(NMLVCUSTOMDRAW& drawer) { + static constexpr auto CELL_TEXT_OFFSET = 0U; + static constexpr auto SELECTION_COLOR_FOCUS = RGB(150, 180, 255); + static constexpr auto SELECTION_COLOR_NOFOCUS = RGB(180, 180, 180); + + const auto row = static_cast(drawer.nmcd.dwItemSpec); + const auto col = drawer.iSubItem; + + auto str = GetItemText(row, col); + const auto id = _wtoi(str); + + if (!isBasic && showText && id > 0 + && ssize(headerIDs) > col + && headerIDs.at(col).has_value()) { + if (const auto* const interp = model->Values().TextFor(*headerIDs.at(col)); + interp != nullptr && interp->HasInterpretantFor(id)) { + str = mfc::ToMFC(interp->GetInterpretantFor(id)); + } + } + CRect rect{}; + if (col > 0) { + GetSubItemRect(row, col, LVIR_BOUNDS, rect); + } else { + GetItemRect(row, &rect, LVIR_LABEL); + } + + auto *pDC = CDC::FromHandle(drawer.nmcd.hdc); + if (row == selectedRow && col == selectedColumn) { + const auto color = GetFocus() == this ? SELECTION_COLOR_FOCUS : SELECTION_COLOR_NOFOCUS; + CBrush brush{ color }; + pDC->FillRect(&rect, &brush); + } else { + CBrush brush{ RGB(255, 255, 255) }; + pDC->FillRect(&rect, &brush); + } + + rect.OffsetRect(CELL_TEXT_OFFSET, 0); + pDC->DrawTextW(str, &rect, DT_END_ELLIPSIS | DT_CENTER); +} + +int32_t DataGridCtrl::AddBaseRow() { + if (isBasic) { + CString msg{}; + msg.AppendFormat(LR"(%d)", GetMaxIndex() + 1); + return InsertItem(GetItemCount(), msg); + } else { + return -1; + } +} + +int32_t DataGridCtrl::GetMaxIndex() const { + int32_t result{ 0 }; + for (auto nRow = 0; nRow < GetItemCount(); ++nRow) { + auto index = _wtoi(GetItemText(nRow, 0)); + result = std::max(result, index); + } + return result; +} + +void DataGridCtrl::OnSetFocus(CWnd* pOldWnd) { + Keyboard::Instance().SetLayout(Keyboard::Layout::RUS); + CListCtrl::OnSetFocus(pOldWnd); +} + +void DataGridCtrl::OnClick(NMHDR* pNMHDR, LRESULT* pResult) { + const auto* activeItem = reinterpret_cast(pNMHDR); + InvalidateCell(selectedRow, selectedColumn); + selectedRow = activeItem->iItem; + selectedColumn = activeItem->iSubItem; + InvalidateCell(selectedRow, selectedColumn); + *pResult = 0; +} + +void DataGridCtrl::OnKeydown(NMHDR* pNMHDR, LRESULT* pResult) { + static constexpr auto CODE_PLUS_SIGN = 0xBB; + static constexpr auto CODE_MINUS_SIGN = 0x8D; + const auto* keyDown = reinterpret_cast(pNMHDR); + switch(keyDown->wVKey) { + case VK_LEFT: { + selectedColumn = selectedColumn == 0 ? 0 : selectedColumn - 1; + InvalidateCell(selectedRow, selectedColumn + 1); + InvalidateCell(selectedRow, selectedColumn); + ensureVisible = ENSURE_ARROW; + topIndex = GetTopIndex(); + break; + } + case VK_RIGHT: { + selectedColumn = selectedColumn + 1 >= columnCount ? selectedColumn : selectedColumn + 1; + InvalidateCell(selectedRow, selectedColumn - 1); + InvalidateCell(selectedRow, selectedColumn); + ensureVisible = ENSURE_ARROW; + topIndex = GetTopIndex(); + break; + } + case VK_UP: { + selectedRow = selectedRow == 0 ? 0 : selectedRow - 1; + InvalidateCell(selectedRow + 1, selectedColumn); + InvalidateCell(selectedRow, selectedColumn); + ensureVisible = ENSURE_ARROW; + topIndex = GetTopIndex(); + break; + } + case VK_DOWN: { + selectedRow = selectedRow + 1 >= GetItemCount() ? selectedRow : selectedRow + 1; + InvalidateCell(selectedRow - 1, selectedColumn); + InvalidateCell(selectedRow, selectedColumn); + ensureVisible = ENSURE_ARROW; + topIndex = GetTopIndex() + 1; + break; + } + case VK_DELETE: { + SetTableItem(selectedRow, selectedColumn, CString{}); + break; + } + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': { + auto str = GetItemText(selectedRow, selectedColumn); + str.AppendChar(keyDown->wVKey); + SetTableItem(selectedRow, selectedColumn, str); + ensureVisible = ENSURE_NUMBER; + topIndex = GetTopIndex(); + break; + } + case VK_NUMPAD0: case VK_NUMPAD1: case VK_NUMPAD2: + case VK_NUMPAD3: case VK_NUMPAD4: case VK_NUMPAD5: + case VK_NUMPAD6: case VK_NUMPAD7: case VK_NUMPAD8: + case VK_NUMPAD9: { + auto str = GetItemText(selectedRow, selectedColumn); + str.AppendChar(keyDown->wVKey + '0' - VK_NUMPAD0); + SetTableItem(selectedRow, selectedColumn, str); + ensureVisible = ENSURE_NUMBER; + topIndex = GetTopIndex(); + break; + } + case VK_ADD: + case CODE_PLUS_SIGN: { // Shift + = + CopyCurrentRow(); + break; + } + case VK_SUBTRACT: + case CODE_MINUS_SIGN: { // дефис + DeleteCurrentRow(); + break; + } + } + *pResult = 0; +} + +void DataGridCtrl::CopyCurrentRow() { + if (selectedRow >= 0 && isEditable) { + SetRedraw(FALSE); + Invalidate(); + if (!isBasic) { + InsertItem(selectedRow, CString{}); + for (auto i = 0; i < columnCount; ++i) { + SetItemText(selectedRow, i, GetItemText(selectedRow + 1, i)); + } + ++selectedRow; + } else { + SetItemText(GetItemCount() - 1, 1, GetItemText(selectedRow, 1)); + selectedRow = GetItemCount() - 1; + } + + isModified = TRUE; + SetRedraw(TRUE); + } +} + +void DataGridCtrl::DeleteCurrentRow() { + if (selectedRow >= 0 && isEditable) { + if (DeleteItem(selectedRow)) { + isModified = TRUE; + } + if (selectedRow == GetItemCount() - 1) { + --selectedRow; + } + } +} + +void DataGridCtrl::OnDbClick(NMHDR* pNMHDR, LRESULT* pResult) { + const auto* activeItem = reinterpret_cast(pNMHDR); + *pResult = 0; + if (activeItem != nullptr) { + ShowEditWindowAtCell(activeItem->iItem, activeItem->iSubItem); + } +} + +void DataGridCtrl::OnPaint() { + switch (ensureVisible) { + case ENSURE_ARROW: { + ensureVisible = ENSURE_NONE; + CListCtrl::OnPaint(); + EnsureVisible(selectedRow, FALSE); + EnsureVisible(topIndex, FALSE); + break; + } + case ENSURE_NUMBER: { + ensureVisible = ENSURE_NONE; + CListCtrl::OnPaint(); + EnsureVisible(GetItemCount() -1, FALSE); + EnsureVisible(topIndex, FALSE); + break; + } + case ENSURE_NONE: { + CListCtrl::OnPaint(); + break; + } + } +} + +void DataGridCtrl::OnMouseMove(const uint32_t nFlags, const CPoint point) { + if (tooltips.m_hWnd != nullptr) { + LVHITTESTINFO lvhti{}; + lvhti.pt = point; + SubItemHitTest(&lvhti); + UpdateToolTipText(lvhti.iItem, lvhti.iSubItem); + } + CListCtrl::OnMouseMove(nFlags, point); +} + +void DataGridCtrl::UpdateToolTipText(const int32_t row, const int32_t col) { + CString old{}; + tooltips.GetText(old, this); + + CString msg{}; + if (row < 0 || col < 0 || ssize(headerIDs) <= col) { + msg = mfc::LoadSID(IXTRS_DEFAULT_TOOLTIP_DATA); + } else { + msg = GetItemText(row, col); + if (!isBasic && headerIDs.at(col).has_value()) { + const auto headID = *headerIDs.at(col); + const auto id = _wtoi(msg); + if (const auto* interp = model->Values().TextFor(headID); + interp != nullptr && interp->HasInterpretantFor(id)) { + msg = mfc::ToMFC(interp->GetInterpretantFor(id)); + } + } + } + + if (msg != old) { + tooltips.UpdateTipText(msg, this); + tooltips.Update(); + } +} + +void DataGridCtrl::InvalidateCell(const int32_t row, const int32_t col) { + if (col != NO_SELECTION && row != NO_SELECTION) { + CRect rect{}; + if (col == 0) { + GetItemRect(row, &rect, LVIR_LABEL); + } else { + GetSubItemRect(row, col, LVIR_BOUNDS, rect); + } + InvalidateRect(&rect); + } +} + +void DataGridCtrl::SetTableItem(const int32_t row, const int32_t col, const CString text) { + if (row >= 0 && col >= 0 && GetItemText(row, col) != text && isEditable && (!isBasic || col != 0)) { + SetItemText(selectedRow, selectedColumn, text); + isModified = TRUE; + } +} + +enum CompareSign { + COMPARE_LESS, + COMPARE_EQUAL, + COMPARE_GREATER, +}; + +void DataGridCtrl::SortData() { + auto flag = TRUE; + const auto count = GetItemCount(); + for (auto k = 0; k < count - 1; ++k) { + flag = FALSE; + for (auto i = 0; i < count - 1 - k; ++i) { + if (CompareItems(i, i + 1) == COMPARE_GREATER) { + flag = TRUE; + SwapItems(i, i + 1); + } + } + if (!flag) { + break; + } + } +} + +int32_t DataGridCtrl::CompareItems(const int32_t item1, const int32_t item2) const { + if (item1 < 0 || item2 < 0 || item1 >= GetItemCount() || item2 >= GetItemCount()) { + return 0; + } + for (auto j = 0; j < columnCount; ++j) { + auto str1 = GetItemText(item1, j); + auto str2 = GetItemText(item2, j); + if (j == 0 && (str1.IsEmpty() || str2.IsEmpty())) { + return COMPARE_EQUAL; + } else { + const auto n1 = _wtoi(str1); + const auto n2 = _wtoi(str2); + + if (n1 != 0 && n2 != 0) { + if (n1 > n2) { + return COMPARE_GREATER; + } else if (n2 > n1) { + return COMPARE_LESS; + } + } else if (const auto comp = str1.Compare(str2); comp > 0) { + return COMPARE_GREATER; + } else if (comp < 0) { + return COMPARE_LESS; + } + } + } + return COMPARE_EQUAL; +} + +void DataGridCtrl::SwapItems(const int32_t item1, const int32_t item2) { + for (auto j = 0; j < columnCount; ++j) { + const auto tmp = GetItemText(item1, j); + SetItemText(item1, j, GetItemText(item2, j)); + SetItemText(item2, j, tmp); + } +} + +} // namespace xtr::ui \ No newline at end of file diff --git a/src/ui/ElementShell.cpp b/src/ui/ElementShell.cpp new file mode 100644 index 0000000..c8a16f3 --- /dev/null +++ b/src/ui/ElementShell.cpp @@ -0,0 +1,203 @@ +#include "stdafx.h" + +#include "xtr/ui/ElementShell.h" + +#include "resource.h" + +#include "xtr/Exteor.h" +#include "xtr/ui/UIHelper.h" + +namespace xtr::ui { + +using ccl::semantic::RSForm; +using ccl::ops::EquationOptions; +using ccl::ops::Equation; + +struct EquationsRSLC::EquationsHeader : Header { + enum Columns : uint8_t { + OP1_TERM = 0, + OP1_NAME, + OP_TYPE, + OP2_NAME, + OP2_TERM, + count + }; + + static constexpr auto widthName = 50; + static constexpr auto widthTypification = 50; + + explicit EquationsHeader(const int32_t rectWidth) { + const auto widthText = (rectWidth - widthTypification - s_ScrollWidth - 2 * widthName) / 2; + + AddColumn({ IXTRS_HEADER_TERM, Alignment::left, widthText }); + AddColumn({ IXTRS_HEADER_NAME, Alignment::right, widthName }); + AddColumn({ IXTRS_HEADER_TYPE, Alignment::center, widthTypification }); + AddColumn({ IXTRS_HEADER_NAME, Alignment::left, widthName }); + AddColumn({ IXTRS_HEADER_TERM, Alignment::right, widthText }); + } +}; + +void EquationsRSLC::InitHeader() { + EquationsHeader header{ WindowRect(control).Width() }; + InitHeaderFor(control, header); +} + +EquationsRSLC::Index EquationsRSLC::InsertItem(const Item& input) { +#pragma warning( push ) +#pragma warning( disable : 6387 ) + const auto nInsertPos = control.InsertItem(LVIF_TEXT | LVIF_STATE, control.GetItemCount(), {}, 0, 0, 0, 0); +#pragma warning( pop ) + control.SetItemText(nInsertPos, EquationsHeader::OP1_NAME, input.name1); + control.SetItemText(nInsertPos, EquationsHeader::OP1_TERM, input.term1); + control.SetItemText(nInsertPos, EquationsHeader::OP_TYPE, Type2Str(input.type)); + control.SetItemText(nInsertPos, EquationsHeader::OP2_NAME, input.name2); + control.SetItemText(nInsertPos, EquationsHeader::OP2_TERM, input.term2); + + return nInsertPos; +} + +std::optional EquationsRSLC::GetItem(Index nItem) const { + if (control.GetItemCount() == 0 || nItem == mfc::noItems) { + return std::nullopt; + } else { + Item result{}; + result.name1 = control.GetItemText(nItem, EquationsHeader::OP1_NAME); + result.term1 = control.GetItemText(nItem, EquationsHeader::OP1_TERM); + result.name2 = control.GetItemText(nItem, EquationsHeader::OP2_NAME); + result.term2 = control.GetItemText(nItem, EquationsHeader::OP2_TERM); + result.type = Str2Type(control.GetItemText(nItem, EquationsHeader::OP_TYPE)); + return result; + } +} + +std::optional EquationsRSLC::GetSelectedItem() const { + return GetItem(control.GetFocusIndex()); +} + +void EquationsRSLC::LoadTableSynth(const ccl::ops::EquationOptions& aMap, + const RSForm& ks1, const RSForm& ks2) { + static const CString ERROR_CST_NAME{ L"ERROR" }; + + control.DeleteAllItems(); + + CString termin1; + CString termin2; + CString name1; + CString name2; + for (const auto& [key, value] : aMap) { + const auto& props = aMap.PropsFor(key); + if (!ks1.Contains(key)) { + termin1.Empty(); + name1 = ERROR_CST_NAME; + } else { + const auto& cst1 = ks1.GetText(key); + name1 = mfc::ToMFC(cst1.alias); + termin1 = props.mode == Equation::Mode::createNew ? mfc::LoadSID(IXTRS_OP_NEW_TERM) : mfc::ToMFC(cst1.term.Nominal()); + } + + if (!ks2.Contains(value)) { + termin2.Empty(); + name2 = ERROR_CST_NAME; + } else { + const auto& cst2 = ks2.GetText(value); + name2 = mfc::ToMFC(cst2.alias); + termin2 = props.mode == Equation::Mode::createNew ? mfc::ToMFC(props.arg) : mfc::ToMFC(cst2.term.Nominal()); + } + + InsertItem({ name1, name2, termin1, termin2, props.mode }); + } +} + +std::optional EquationsRSLC::CreateEquations(const RSForm& schema1, const RSForm& schema2) const { + EquationOptions synthTable{}; + for (auto i = 0; i < control.GetItemCount(); ++i) { + const auto name1 = mfc::ToSTL(control.GetItemText(i, EquationsHeader::OP1_NAME)); + const auto name2 = mfc::ToSTL(control.GetItemText(i, EquationsHeader::OP2_NAME)); + const auto type = Str2Type(control.GetItemText(i, EquationsHeader::OP_TYPE)); + const auto termin = type == Equation::Mode::createNew ? mfc::ToSTL(control.GetItemText(i, EquationsHeader::OP2_TERM)) : ""; + const auto uid1 = schema1.Core().FindAlias(name1); + const auto uid2 = schema2.Core().FindAlias(name2); + if (!uid1.has_value() || !uid2.has_value()) { + return std::nullopt; + } else { + synthTable.Insert(uid1.value(), uid2.value(), ccl::ops::Equation{ type, termin }); + } + } + return synthTable; +} + +SetOfEntities EquationsRSLC::Inputs(const RSForm& ks1) const { + SetOfEntities result{}; + for (auto i = 0; i < control.GetItemCount(); ++i) { + const auto name1 = mfc::ToSTL(control.GetItemText(i, EquationsHeader::OP1_NAME)); + if (const auto uid = ks1.Core().FindAlias(name1); uid.has_value()) { + result.insert(uid.value()); + } + } + return result; +} + +SetOfEntities EquationsRSLC::Outputs(const RSForm& ks2) const { + SetOfEntities result{}; + for (auto i = 0; i < control.GetItemCount(); ++i) { + const auto name2 = mfc::ToSTL(control.GetItemText(i, EquationsHeader::OP2_NAME)); + if (const auto uid = ks2.Core().FindAlias(name2); uid.has_value()) { + result.insert(uid.value()); + } + } + return result; +} + +Equation::Mode EquationsRSLC::Str2Type(const CString str) noexcept { + if (str == LR"(<-)") { + return Equation::Mode::keepHier; + } else if (str == LR"(->)") { + return Equation::Mode::keepDel; + } else { + return Equation::Mode::createNew; + } +} + +CString EquationsRSLC::Type2Str(Equation::Mode type) { + switch(type) { + default: + case Equation::Mode::keepHier: return LR"(<-)"; + case Equation::Mode::keepDel: return LR"(->)"; + case Equation::Mode::createNew: return LR"(~)"; + } +} + +uint32_t CstPicker::Init(const Mode mode, const CString exclude) { + menuMode = mode; + m_Exclude = exclude; + ModifyStyle(0, CBS_SORT); + UpdateList(); + return GetCount(); +} + +BOOL CstPicker::IsValid() const { + if (const auto text = WindowText(*this); text.IsEmpty()) { + return FALSE; + } else { + return FindStringExact(mfc::noItems, text) == CB_ERR; + } +} + +void CstPicker::UpdateList() { + ResetContent(); + if (menuMode != Mode::DEFAULT) { + for (const auto& iterList : ExteorApplication::Docs().RSFormList()) { + CString item{}; + if (menuMode == Mode::TITLE) { + item = mfc::ToMFC(iterList->title); + } else { + item = mfc::ToMFC(iterList->alias); + } + if (m_Exclude.Compare(item) != 0 && !item.IsEmpty()) { + AddString(item); + } + } + } +} + +} // namespace xtr::ui \ No newline at end of file diff --git a/src/ui/ExteorFrame.cpp b/src/ui/ExteorFrame.cpp new file mode 100644 index 0000000..e737b1e --- /dev/null +++ b/src/ui/ExteorFrame.cpp @@ -0,0 +1,229 @@ +#include "stdafx.h" + +#include "xtr/ui/ExteorFrame.h" + +#include "resource.h" + +#include "xtr/Exteor.h" +#include "xtr/doc/OSSDoc.h" +#include "xtr/doc/RSModelDoc.h" +#include "xtr/doc/RSFormDoc.h" +#include "xtr/doc/OSSDoc.h" + +#include "xtr/ui/KeyboardHandler.h" + +namespace xtr::ui { + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(ExteorFrame, CMDIFrameWndEx) + ON_WM_DROPFILES() + ON_WM_CREATE() + ON_WM_COPYDATA() + ON_WM_ACTIVATEAPP() +END_MESSAGE_MAP() + +#pragma warning( pop ) + +static constexpr UINT BASED_CODE buttons[] = { + ID_FILE_NEW, + ID_FILE_OPEN, + ID_FILE_SAVE, + ID_SEPARATOR, + IXTRC_BUG_REPORT, + ID_SEPARATOR, + ID_EDIT_COPY, + ID_EDIT_PASTE, + ID_SEPARATOR, + ID_WINDOW_TILE_HORZ, + ID_WINDOW_TILE_VERT, + ID_WINDOW_CASCADE, +}; + +static constexpr UINT BASED_CODE indicators[] = { + ID_SEPARATOR, + IXTRC_INDICATOR_CAPS, + IXTRC_INDICATOR_NUM, + IXTRC_INDICATOR_SCRL, + IXTRC_INDICATOR_LANGUAGE, +}; + +static constexpr UINT BASED_CODE insbuttons[] = { + IXTRC_INSERT_BASE_SET, + IXTRC_INSERT_CONST_SET, + ID_SEPARATOR, + IXTRC_INSERT_RS, + IXTRC_INSERT_AXIOM, + IXTRC_INSERT_TERM, + IXTRC_INSERT_FUNCTION, + IXTRC_INSERT_PREDICATE, + IXTRC_INSERT_THEOREMA, + ID_SEPARATOR, + IXTRC_INSERT_FREE, + ID_SEPARATOR, + IXTRC_DELETE_CST, +}; + +static constexpr UINT BASED_CODE ossbuttons[] = { + IXTRC_OSS_ENABLE_GRID, + IXTRC_OSS_ENABLE_LEGEND, + ID_SEPARATOR, + IXTRC_OSS_SHIFT_LEFT, + IXTRC_OSS_SHIFT_RIGHT, + ID_SEPARATOR, + IXTRC_OSS_ADD, + IXTRC_OSS_DEL, + IXTRC_OSS_EDIT_DOC, + IXTRC_OSS_ASSIGN_DOC, + ID_SEPARATOR, + IXTRC_OSS_OP_NEW, + IXTRC_OSS_OP_EDIT, + ID_SEPARATOR, + IXTRC_OSS_OP_RUN_SINGLE, + IXTRC_OSS_OP_RUN_ALL, + ID_SEPARATOR, + IXTRC_OSS_ZOOM_OUT, + IXTRC_OSS_ZOOM_IN, +}; + +void ExteorFrame::SetLangStatusText(const CString text) { + const auto index = statusbar.CommandToIndex(IXTRC_INDICATOR_LANGUAGE); + statusbar.SetPaneText(index, text, TRUE); +} + +BOOL ExteorFrame::PreCreateWindow(CREATESTRUCT& cs) { + if (!CMDIFrameWndEx::PreCreateWindow(cs)) { + return FALSE; + } + + LPCTSTR pszClassName = L"Exteor"; + WNDCLASS wndcls{}; + if (!::GetClassInfoW(AfxGetInstanceHandle(), pszClassName, &wndcls)) { + // Get the current requested window class + VERIFY(GetClassInfoW(AfxGetInstanceHandle(), cs.lpszClass, &wndcls)); + wndcls.lpszClassName = pszClassName; + + // Need to preset the icon otherwise the function GetIconWndClass calling us will overwrite our class. + LPCTSTR pszIcon = MAKEINTRESOURCEW(IXTRAD_MENU_MAINFRAME); + HINSTANCE hInst = AfxFindResourceHandle(pszIcon, ATL_RT_GROUP_ICON); + _ASSERTE(hInst != NULL); + wndcls.hIcon = ::LoadIconW(hInst, pszIcon); + + // Register class + if (!::RegisterClassW(&wndcls)) { + return FALSE; + } + } + + cs.lpszClass = pszClassName; + return TRUE; +} + +BOOL ExteorFrame::OnCopyData(CWnd* /*pWnd*/, COPYDATASTRUCT* pCDS) { // NOLINT(readability-convert-member-functions-to-static) + if (const auto* commandLine = static_cast(pCDS->lpData); commandLine != nullptr) { + ::AfxGetApp()->OpenDocumentFile(commandLine); + } + return TRUE; +} + +void ExteorFrame::OnActivateApp(BOOL bActive, DWORD dwThreadID) { + CMDIFrameWndEx::OnActivateApp(bActive, dwThreadID); + if (bActive) { + Keyboard::Instance().ResetSystemLayout(); + UpdateUI(); + } +} + +int32_t ExteorFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { + static constexpr auto errorCode = -1; + static constexpr auto successCode = 0; + if (CMDIFrameWndEx::OnCreate(lpCreateStruct) == errorCode) { + return errorCode; + } + + InitVisualStyle(); + + if (!CreateControls()) { + TRACE0("Failed to create frame controls\n"); + return errorCode; + } + InitControls(); + + RecalcLayout(); + + Keyboard::Instance().ImportSystemLayout(); + return successCode; +} + +void ExteorFrame::InitVisualStyle() { + CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2007)); + CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_Silver); +} + +#pragma warning( push ) +#pragma warning( disable : 26485 ) // do not warn about indicators array + +BOOL ExteorFrame::CreateControls() { + static constexpr auto barStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS; + return + statusbar.Create(this) && + statusbar.SetIndicators(static_cast(indicators), sizeof(indicators) / sizeof(UINT)) && + mainTool.CreateEx(this, TBSTYLE_FLAT, barStyle, CRect{}, IXTRAD_MENU_MAINFRAME) && + mainTool.LoadBitmapW(IXTRR_TOOLBAR_MAINFRAME) && + mainTool.SetButtons(static_cast(buttons), sizeof(buttons) / sizeof(UINT)) && + rsTool.CreateEx(this, TBSTYLE_FLAT, barStyle, CRect{}, IXTRAD_MENU_RSFORM) && + rsTool.LoadBitmapW(IXTRR_TOOLBAR_RSFORM) && + rsTool.SetButtons(static_cast(insbuttons), sizeof(insbuttons) / sizeof(UINT)) && + ossTool.CreateEx(this, TBSTYLE_FLAT, barStyle, CRect{}, IXTRAD_MENU_OSS) && + ossTool.LoadBitmapW(IXTRR_TOOLBAR_OSS) && + ossTool.SetButtons(static_cast(ossbuttons), sizeof(ossbuttons) / sizeof(UINT)); +} + +#pragma warning( pop ) + +void ExteorFrame::InitControls() { + mainTool.SetWindowTextW(mfc::LoadSID(IXTRS_TITLE_TOOLBAR)); + rsTool.SetWindowTextW(mfc::LoadSID(IXTRS_TITLE_INSTOOL)); + ossTool.SetWindowTextW(mfc::LoadSID(IXTRS_TITLE_OSS)); + + mainTool.EnableDocking(CBRS_ALIGN_TOP); + rsTool.EnableDocking(CBRS_ALIGN_TOP); + ossTool.EnableDocking(CBRS_ALIGN_TOP); + this->EnableDocking(CBRS_ALIGN_TOP); + + DockPane(&ossTool); + DockPaneLeftOf(&rsTool, &ossTool); + DockPaneLeftOf(&mainTool, &rsTool); + + ossTool.ShowPane(TRUE, 0, FALSE); + rsTool.ShowPane(TRUE, 0, FALSE); + mainTool.ShowPane(TRUE, 0, FALSE); + + CDockingManager::SetDockingMode(DT_SMART); +} + +void ExteorFrame::UpdateUI() { + RecalcLayout(); +} + +#pragma warning( push ) +#pragma warning( disable : 26485 ) // ignore array to pointer decay + +void ExteorFrame::OnDropFiles(HDROP hDropInfo) { + const auto bufferSize = ::DragQueryFileW(hDropInfo, 0, nullptr, 0) + 1; + CString filename{}; + ::DragQueryFileW(hDropInfo, 0, filename.GetBuffer(bufferSize), bufferSize); + filename.ReleaseBuffer(); + + const CString extension = CString(::PathFindExtensionW(filename)).MakeLower(); + if (extension == ".rsm" || extension == ".oss" || extension == ".trs") { + CMDIFrameWndEx::OnDropFiles(hDropInfo); + } else { + ::AfxMessageBox(mfc::FormatSID(IXTRE_UNKNOWN_EXTENSION, filename.GetString()), MB_ICONERROR); + } +} + +#pragma warning( pop ) + +} // namespace xtr::ui \ No newline at end of file diff --git a/src/ui/HelpHandler.cpp b/src/ui/HelpHandler.cpp new file mode 100644 index 0000000..8874556 --- /dev/null +++ b/src/ui/HelpHandler.cpp @@ -0,0 +1,43 @@ +#include "stdafx.h" + +#include "xtr/ui/HelpHandler.h" + +#include "resource.h" + +namespace xtr::ui { + +HelpHandler::HelpHandler() { + helpBase[HelpID::viewRSForm] = LR"(::/html/050702.htm)"; + helpBase[HelpID::viewRSModel] = LR"(::/html/050902.htm)"; + helpBase[HelpID::viewRSOSS] = LR"(::/html/050802.htm)"; + + helpBase[HelpID::editCst] = LR"(::/html/050703.htm)"; + helpBase[HelpID::synthes] = LR"(::/html/050704.htm)"; + helpBase[HelpID::generateCst] = LR"(::/html/050705.htm)"; + helpBase[HelpID::exportRSForm] = LR"(::/html/050710.htm)"; + helpBase[HelpID::options] = LR"(::/html/051000.htm)"; + helpBase[HelpID::operations] = LR"(::/html/050804.htm)"; + helpBase[HelpID::editData] = LR"(::/html/050903.htm)"; + + helpBase[HelpID::rslanguage] = LR"(::/html/050711.htm)"; +} + +void HelpHandler::RunHelp(const HelpID targetPage) { + CString moduleFolder; + ::GetModuleFileNameW(::AfxGetApp()->m_hInstance, moduleFolder.GetBuffer(_MAX_PATH + 1), _MAX_PATH + 1); + moduleFolder.ReleaseBuffer(); + moduleFolder = moduleFolder.Mid(0, moduleFolder.ReverseFind('\\') + 1); + + ::HtmlHelpW(nullptr, moduleFolder + mfc::LoadSID(IXTRS_FILE_HELP) + HID2CStr(targetPage), HH_DISPLAY_TOPIC, 0); +} + +HelpHandler& HelpHandler::Instance() { + static HelpHandler instance{}; + return instance; +} + +CString HelpHandler::HID2CStr(const HelpID pageID) { + return Instance().helpBase[pageID]; +} + +} // namespace xtr::ui \ No newline at end of file diff --git a/src/ui/KeyboardHandler.cpp b/src/ui/KeyboardHandler.cpp new file mode 100644 index 0000000..e835ebd --- /dev/null +++ b/src/ui/KeyboardHandler.cpp @@ -0,0 +1,122 @@ +#include "stdafx.h" + +#include "xtr/ui/KeyboardHandler.h" + +#include "resource.h" + +#include "xtr/Exteor.h" + +namespace xtr::ui { + +Keyboard::Keyboard() { + russianHKL = /*(HKL)0x0419;*/ LoadKeyboardLayoutW(L"00000419", 0); + englishHKL = /*(HKL)0x0409;*/ LoadKeyboardLayoutW(L"00000409", 0); +} + +Keyboard& Keyboard::Instance() { + static Keyboard instance{}; + return instance; +} + +void Keyboard::SetLayout(const Layout newLang) { + if (XTROptions::App().disableAutoKeyboard && + (currentLayout == Layout::RUS || newLang == Layout::RUS)) { + return; + } + + if (currentLayout != newLang) { + SetInternalLayout(newLang); + } + if (newLang == Layout::RUS) { + SetSystemLayout(russianHKL); + } else { + SetSystemLayout(englishHKL); + } +} + +void Keyboard::ResetSystemLayout() { + systemLayout = GetKeybLang(); + SetSystemLayout(currentLayout != Layout::RUS ? englishHKL : russianHKL); + UpdateIndicators(); +} + +Keyboard::Layout Keyboard::GetLayout() const noexcept { + return currentLayout; +} + +void Keyboard::RotateLayout() { + if (!XTROptions::App().disableAutoKeyboard) { + switch (currentLayout) { + case Layout::RUS: SetLayout(Layout::MATH); break; + case Layout::ENG: SetLayout(Layout::RUS); break; + case Layout::MATH: SetLayout(Layout::ENG); break; + } + } else { + ImportSystemLayout(); + switch (currentLayout) { + case Layout::RUS: break; + case Layout::ENG: SetLayout(Layout::MATH); break; + case Layout::MATH: SetLayout(Layout::ENG); break; + } + } +} + +void Keyboard::RegisterIndicator(CWnd* wnd) { + indicators.insert(wnd); + UpdateIndicators(); +} + +void Keyboard::UnregisterIndicator(CWnd* wnd) { + indicators.erase(wnd); +} + +void Keyboard::ImportSystemLayout() { + const auto currentSystemLayout = GetKeybLang(); + auto exteorLayout = currentLayout; + if (exteorLayout == Layout::MATH) { + exteorLayout = Layout::ENG; + } + if (currentSystemLayout != exteorLayout) { + SetInternalLayout(currentSystemLayout); + } +} + +void Keyboard::UpdateIndicators() { + CString indicatorText; + switch(currentLayout) { + case Layout::MATH: indicatorText = mfc::LoadSID(IXTRC_INDICATOR_GOTHIC); break; + case Layout::RUS: indicatorText = mfc::LoadSID(IXTRC_INDICATOR_RUSSIAN); break; + case Layout::ENG: indicatorText = mfc::LoadSID(IXTRC_INDICATOR_ENGLISH); break; + } + + ExteorApplication::MainFrame().SetLangStatusText(indicatorText); + for (const auto& wnd : indicators) { + if (wnd->m_hWnd != nullptr) { + wnd->SetWindowTextW(indicatorText); + } + } +} + +Keyboard::Layout Keyboard::GetKeybLang() { + CString sLayout{}; + GetKeyboardLayoutNameW(sLayout.GetBuffer(KL_NAMELENGTH + 1)); + sLayout.ReleaseBuffer(); + if (sLayout == L"00000419") { + return Keyboard::Layout::RUS; + } else { + return Keyboard::Layout::ENG; + } +} + +void Keyboard::SetSystemLayout(HKL newLayout) noexcept { + if (!XTROptions::App().disableAutoKeyboard) { + ActivateKeyboardLayout(newLayout, KLF_REORDER); + } +} + +void Keyboard::SetInternalLayout(const Layout newLang) { + currentLayout = newLang; + UpdateIndicators(); +} + +} // namespace xtr::ui \ No newline at end of file diff --git a/src/ui/RSEdit.cpp b/src/ui/RSEdit.cpp new file mode 100644 index 0000000..b50c502 --- /dev/null +++ b/src/ui/RSEdit.cpp @@ -0,0 +1,550 @@ +#include "stdafx.h" + +#include "xtr/ui/RSEdit.h" + +#include "resource.h" + +#include "xtr/core/Encoder.h" +#include "xtr/ExteorOptions.h" +#include "xtr/xtrDesign.h" +#include "xtr/cclDescriptor.h" + +#include "xtr/ui/KeyboardHandler.h" +#include "xtr/ui/UIHelper.h" + +#include "xtr/dialog/InsertCstDlg.h" + +#include "ccl/rslang/RSGenerator.h" + +namespace xtr::ui { + +using ccl::rslang::TokenID; +using ccl::rslang::Token; +using ccl::rslang::Generator; +using ccl::semantic::RSCore; +using ccl::semantic::CstType; +using index::Digits; + +namespace { +[[nodiscard]] CString DefaultInputFor(const TokenID token) { + auto baseStr = mfc::ToMFC(Token::Str(token)); + switch (token) { + default: { + return baseStr; + } + case TokenID::DECLARATIVE: { + return baseStr + '{' + mfc::ToMFC(Token::Str(TokenID::IN)) + LR"( | })"; + } + case TokenID::IMPERATIVE: { + return baseStr + LR"({ | )" + mfc::ToMFC(Token::Str(TokenID::ITERATE)) + LR"(; := })"; + } + case TokenID::RECURSIVE: { + return baseStr + LR"({ := | | })"; + } + case TokenID::BOOLEAN: + case TokenID::CARD: + case TokenID::BOOL: + case TokenID::REDUCE: + case TokenID::DEBOOL: { + return baseStr + L"()"; + } + case TokenID::BIGPR: + case TokenID::SMALLPR: { + return baseStr + L"1()"; + } + + case TokenID::FILTER: { + return baseStr + LR"(1[]())"; + } + } +} +} // anonymous namespace + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(RSEdit, BuffRichEdit) + ON_WM_CHAR() + ON_WM_KEYDOWN() + ON_WM_SYSCHAR() +END_MESSAGE_MAP() + +#pragma warning( pop ) + +RSEdit::RSEdit() { + defaultToolTipText = mfc::LoadSID(IXTRS_EXP_TOOLTIP_DEFAULT); +} + +void RSEdit::InputBrackets() { + if ((GetStyle() & ES_READONLY) == 0 && IsWindowEnabled()) { + const auto sel = GetSelectionRange(); + InsertRSText(LR"([])", sel); + RedrawWindow(); + SetFocus(); + } +} + +void RSEdit::InputParenthesis() { + if ((GetStyle() & ES_READONLY) == 0 && IsWindowEnabled()) { + const auto sel = GetSelectionRange(); + InsertRSText(L"()", sel); + RedrawWindow(); + SetFocus(); + } +} + +void RSEdit::InputToken(const TokenID token) { + if ((GetStyle() & ES_READONLY) != 0 || !IsWindowEnabled()) { + return; + } + const auto sel = GetSelectionRange(); + if (token == TokenID::BOOLEAN) { + auto selTxt = GetSelText(); + auto pos = 0; + while (selTxt.GetLength() > pos + 1 + && selTxt.Mid(pos, 1) == mfc::ToMFC(Token::Str(TokenID::BOOLEAN))) { + ++pos; + } + if (pos != 0 && selTxt[pos] == '(' + && mfc::FindClosingParanthesis(selTxt, pos + 1).value_or(0) == selTxt.GetLength() - 1) { + SetSel(sel.start, sel.start); + InsertString(mfc::ToMFC(Token::Str(TokenID::BOOLEAN))); + SetSel(sel.start, sel.finish + 1); + return; + } + } + + InsertRSText(DefaultInputFor(token), sel); + RedrawWindow(); + SetFocus(); +} + +void RSEdit::InsertRSText(const CString text, const StrRange sel) { + if (text.Right(2) != L"()" && text.Right(2) != L"[]") { + InsertString(text); + } else if (const auto strLen = text.GetLength(); sel.start == sel.finish) { + InsertString(text); + SetSel(sel.finish + strLen - 1, sel.finish + strLen - 1); + } else { + SetSel(sel.start, sel.start); + InsertString(text.Left(strLen - 1)); + + const auto newPos = sel.finish + strLen - 1; + SetSel(newPos, newPos); + InsertString(text.Right(1)); + SetSel(newPos, newPos); + } +} + +void RSEdit::Init(const RSCore& cntxt, const EntityUID active) { + context = &cntxt; + activeUID = active; + astText.Empty(); + prefixLen = static_cast(cntxt.GetRS(activeUID).alias.length() + 3); + navigatorEnabled = FALSE; + activeNode = std::nullopt; + checker = cntxt.RSLang().MakeAuditor(); +} + +BOOL RSEdit::PreTranslateMessage(MSG* pMsg) { + if (pMsg->message == WM_KEYDOWN) { + if (Keyboard::IsPressed(VK_CONTROL) && + pMsg->wParam == VK_SPACE && + context != nullptr && + (GetStyle() & ES_READONLY) == 0) { + AddReference(); + return TRUE; + } else if (Keyboard::IsPressed(VK_CONTROL) && + Keyboard::IsPressed(VK_SHIFT)) { + auto updateNeeded = FALSE; + switch (pMsg->wParam) { + default: return BuffRichEdit::PreTranslateMessage(pMsg); + case 'W': NavigatorOn(); updateNeeded = MoveUp(); break; + case 'S': NavigatorOn(); updateNeeded = MoveDown(); break; + case 'D': NavigatorOn(); updateNeeded = MoveRight(); break; + case 'A': NavigatorOn(); updateNeeded = MoveLeft(); break; + case 'Q': { + updateNeeded = TRUE; + navigatorEnabled = FALSE; + activeNode = std::nullopt; + break; + } + } + if (updateNeeded) { + UpdateFormat(TRUE); + } + return TRUE; + } + } + return BuffRichEdit::PreTranslateMessage(pMsg); +} + +void RSEdit::PreSubclassWindow() { + BuffRichEdit::PreSubclassWindow(); + SetFont(&XTROptions::App().fontMath); +} + +void RSEdit::OnChar(uint32_t nChar, uint32_t nRepCnt, uint32_t nFlags) { + if (Keyboard::IsPressed(VK_CONTROL) || + Keyboard::Instance().GetLayout() != Keyboard::Layout::MATH) { + BuffRichEdit::OnChar(nChar, nRepCnt, nFlags); + return; + } + switch (nChar) { + default: BuffRichEdit::OnChar(nChar, nRepCnt, nFlags); return; + case 'a': InsertChar(encode::US_A); return; + case 'b': InsertChar(encode::US_B); return; + case 'g': InsertChar(encode::US_G); return; + case 'd': InsertChar(encode::US_D); return; + case 'e': InsertChar(encode::US_E); return; + case 'z': InsertChar(encode::US_Z); return; + case 'n': InsertChar(encode::US_H); return; + case 'v': InsertChar(encode::US_V); return; + case 'h': InsertChar(encode::US_L); return; + case 'm': InsertChar(encode::US_M); return; + case 'x': InsertChar(encode::US_X); return; + case 'y': InsertChar(encode::US_P); return; + case 'r': InsertChar(encode::US_R); return; + case 's': InsertChar(encode::US_S); return; + case 't': InsertChar(encode::US_T); return; + case 'f': InsertChar(encode::US_F); return; + case 'c': InsertChar(encode::US_J); return; + case 'w': InsertChar(encode::US_W); return; + + case '~': InsertChar(encode::US_LOGIC_EXISTS); return; + case '`': InsertChar(encode::US_LOGIC_FORALL); return; + + case 'B': InsertChar(encode::US_BOOL); return; + case '*': InsertChar(encode::US_CARTH); return; + } +} + +void RSEdit::OnKeyDown(const uint32_t nChar, const uint32_t nRepCnt, const uint32_t nFlags) { + BuffRichEdit::OnKeyDown(nChar, nRepCnt, nFlags); + if (Keyboard::IsPressed(VK_CONTROL) && nChar == VK_F3) { + SelectPairedBracket(GetSelectionRange().start); + } +} + +void RSEdit::SelectPairedBracket(const StrPos caretPos) { + if (const auto bracketPair = GetBracketPair(caretPos, '(', ')'); bracketPair.has_value()) { + if (bracketPair->left.value() == caretPos - 1) { + MoveCaretTo(bracketPair->right.value()); + } else { + MoveCaretTo(bracketPair->left.value() + 1); + } + if (Keyboard::IsPressed(VK_SHIFT)) { + SetSel(bracketPair->left.value() + 1, bracketPair->right.value()); + } + } +} + +std::optional RSEdit::GetBracketPair(const StrPos pos, + const TCHAR leftBracket, + const TCHAR rightBracket) const { + const auto wholeText = Text(); + const auto left = mfc::FindBracketBlockStart(wholeText, { leftBracket, rightBracket, pos }); + const auto right = mfc::FindBracketBlockEnd(wholeText, { leftBracket, rightBracket, pos }); + if (!left.has_value() && !right.has_value()) { + return std::nullopt; + } else { + return BracketPair{ left, right }; + } +} + +void RSEdit::OnSysChar(const uint32_t nChar, const uint32_t nRepCnt, const uint32_t nFlags) { + switch(nChar) { + default: BuffRichEdit::OnSysChar(nChar, nRepCnt, nFlags); return; + case 'e': InputToken(TokenID::BOOLEAN); return; + case 'E': InputToken(TokenID::DECART); return; + case 'c': InputToken(TokenID::CARD); return; + case 'b': InputToken(TokenID::BOOL); return; + case 'v': InputToken(TokenID::DEBOOL); return; + case 'r': InputToken(TokenID::REDUCE); return; + case 'q': InputToken(TokenID::BIGPR); return; + case 'w': InputToken(TokenID::SMALLPR); return; + case 'f': InputToken(TokenID::FILTER); return; + case 'a': InsertChar(encode::US_SET_INTERSECTION); return; + case 's': InsertChar(encode::US_SET_UNION); return; + case 'x': InsertChar(encode::US_EMPTYSET); return; + case 'z': InsertChar('Z'); return; + + case 't': InputToken(TokenID::NT_RECURSIVE_FULL); return; + case 'd': InputToken(TokenID::NT_DECLARATIVE_EXPR); return; + case 'g': InputToken(TokenID::NT_IMPERATIVE_EXPR); return; + + case '`': InsertChar(encode::US_LOGIC_NOT); return; + case '~': InsertChar(encode::US_NOTEQUAL); return; + + case '1': InsertChar(encode::US_ELEMENT); return; + case '!': InsertChar(encode::US_NOTELEMENT); return; + case '2': InsertChar(encode::US_SUBSET_OR_EQ); return; + case '@': InsertChar(encode::US_NOTSUBSET); return; + case '3': InsertChar('&'); return; + case '#': InsertChar(encode::US_LOGIC_OR); return; + case '4': InsertChar(encode::US_IMPLICATION); return; + case '$': InsertChar(encode::US_LOGIC_EQUAL); return; + case '5': InsertChar('\\'); return; + case '%': InsertChar(encode::US_SET_SYMMINUS); return; + case '6': InputToken(TokenID::ITERATE); return; + case '^': InputToken(TokenID::ASSIGN); return; + case '7': InsertChar(encode::US_SUBSET); return; + case '8': InsertChar('*'); return; + } +} + +void RSEdit::UpdateFormatItems() { + formatItems.clear(); + + const auto text = Text(); + const auto rsText = mfc::ToSTL(text); + std::string str{}; + auto parlevel = 0; + auto tokenStream = parser.Lex(rsText, ccl::rslang::Syntax::MATH); + for (auto token = tokenStream(); token.id != TokenID::END; token = tokenStream()) { + switch (token.id) { + default: break; + case TokenID::PUNC_PL: { + ++parlevel; + if (XTROptions::ParseRSL().colorBrackets) { + FormatBracket(parlevel, token.pos); + } + break; + } + case TokenID::PUNC_PR: { + if (XTROptions::ParseRSL().colorBrackets) { + FormatBracket(parlevel, token.pos); + } + --parlevel; + break; + } + case TokenID::BOOL: + case TokenID::REDUCE: + case TokenID::DEBOOL: + case TokenID::CARD: { + FormatIdentifier(token.id, token.pos); + break; + } + + case TokenID::ID_GLOBAL: + case TokenID::ID_RADICAL: + case TokenID::ID_FUNCTION: + case TokenID::ID_PREDICATE: { + const auto pos = token.pos; + assert(pos.finish <= text.GetLength()); + auto prefixEnd = pos.finish - 1; + for (prefixEnd; std::isdigit(text.GetAt(prefixEnd)); --prefixEnd) { + ; + } + FormatIndex(token.id, pos, prefixEnd + 1 - pos.start, + XTROptions::ParseRSL().indexing.global == Digits::subText); + break; + } + case TokenID::ID_LOCAL: { + const auto pos = token.pos; + assert(pos.finish <= text.GetLength()); + auto prefixEnd = pos.finish - 1; + for (prefixEnd; std::isdigit(text.GetAt(prefixEnd)); --prefixEnd) { + ; + } + FormatIndex(token.id, pos, prefixEnd + 1 - pos.start, + XTROptions::ParseRSL().indexing.local == Digits::subText); + break; + } + case TokenID::BIGPR: + case TokenID::FILTER: + case TokenID::SMALLPR: { + assert(token.pos.finish <= text.GetLength()); + FormatIndex(token.id, token.pos, 2, + XTROptions::ParseRSL().indexing.operators == Digits::subText); + break; + } + } + } +} + +void RSEdit::FormatIndex(const TokenID tid, const StrRange pos, const StrPos prefix, const BOOL subscript) { + auto format = design::CharFormatRE(); + format.dwMask = CFM_COLOR; + format.crTextColor = design::Color(tid); + formatItems.emplace_back(FormatItem{ StrRange::FromLength(pos.start, prefix), format }); + + if (subscript) { + format.dwMask |= CFM_SUBSCRIPT; + format.dwEffects |= CFE_SUBSCRIPT; + } + formatItems.emplace_back(FormatItem{ StrRange{ pos.start + prefix, pos.finish }, format }); +} + +void RSEdit::AdditionalFormat() { + const auto selection = GetSelectionRange(); + FormatBracketsAround(selection.start); + FormatSelectedBlock(selection); +} + +void RSEdit::FormatBracketsAround(const StrPos caretPos) { + std::vector brackets{}; + + if (const auto parens = GetBracketPair(caretPos, '(', ')'); parens.has_value()) { + brackets.emplace_back(parens.value()); + } + if (const auto curly = GetBracketPair(caretPos, '{', '}'); curly.has_value()) { + brackets.emplace_back(curly.value()); + } + if (const auto square = GetBracketPair(caretPos, '[', ']'); square.has_value()) { + brackets.emplace_back(square.value()); + } + auto format = design::CharFormatRE(); + format.dwMask = CFM_BOLD; + format.dwEffects = CFE_BOLD; + format.crTextColor = design::BracketsColor(-1); + for (const auto& bracketPair : brackets) { + if (bracketPair.IsCorrect()) { + SelectChar(bracketPair.left.value()); + SetSelectionCharFormat(format); + + SelectChar(bracketPair.right.value()); + SetSelectionCharFormat(format); + } else if (!bracketPair.IsNull()) { + format.dwMask |= CFM_COLOR; + if (bracketPair.left.has_value()) { + SelectChar(bracketPair.left.value()); + } else { + SelectChar(bracketPair.right.value()); + } + SetSelectionCharFormat(format); + format.dwMask &= ~CFM_COLOR; + } + } +} + +BOOL RSEdit::UpdateAST() { + if (const auto text = Text(); text == astText) { + return TRUE; + } else if (!context->Contains(activeUID) || checker == nullptr) { + return FALSE; + } else { + const auto& cst = context->GetRS(activeUID); + const auto expression = Generator::GlobalDefinition(cst.alias, mfc::ToSTL(text), cst.type == CstType::structured); + checker->CheckType(expression, ccl::rslang::Syntax::MATH); + astText = text; + navigatorEnabled = FALSE; + activeNode = std::nullopt; + return TRUE; + } +} + +void RSEdit::FormatSelectedBlock(const StrRange selection) { + static constexpr COLORREF clrBg{ RGB(235, 235, 235) }; + static constexpr COLORREF clrReadOnlyBg{ RGB(255, 255, 211) }; + + if (XTROptions::ParseRSL().enableNavigator && + GetFocus()->GetSafeHwnd() == m_hWnd && + context != nullptr && UpdateAST() && checker->isParsed) { + auto selectedNode = activeNode; + if (!navigatorEnabled) { + const auto clientRange = StrRange{ selection.start + prefixLen, selection.finish + prefixLen }; + selectedNode = ccl::rslang::FindMinimalNode(checker->parser.AST().Root(), clientRange); + } + if (selectedNode.has_value()) { + const auto start = std::max(selectedNode.value()->pos.start - prefixLen, 0); + const auto end = std::min(selectedNode.value()->pos.finish - prefixLen, astText.GetLength()); + + auto format = design::CharFormatRE(); + format.dwMask = CFM_BACKCOLOR; + format.crBackColor = (GetStyle() & ES_READONLY) == 0 ? clrBg : clrReadOnlyBg; + SetSel(start, end); + SetSelectionCharFormat(format); + } + } +} + +void RSEdit::FormatIdentifier(const ccl::rslang::TokenID tid, const StrRange pos) { + auto format = design::CharFormatRE(); + format.dwMask = CFM_COLOR; + format.crTextColor = design::Color(tid); + formatItems.emplace_back(FormatItem{ pos, format }); +} + +void RSEdit::FormatBracket(const int32_t level, const StrRange pos) { + auto format = design::CharFormatRE(); + format.dwMask = CFM_COLOR; + format.crTextColor = design::BracketsColor(level); + formatItems.emplace_back(FormatItem{ pos, format }); +} + +CString RSEdit::GenerateToolTipText() { + if (context == nullptr) { + return defaultToolTipText; + } + + const auto uid = context->FindAlias(mfc::ToSTL(GetSelText())); + if (!uid.has_value()) { + return defaultToolTipText; + } + + const auto& cst = context->GetText(uid.value()); + auto result = info::Label(context->GetParse(uid.value()).TypePtr()); + if (!std::empty(cst.term.Nominal())) { + result += '\n'; + } + result += mfc::ToMFC(cst.term.Nominal()); + + if (!std::empty(cst.definition)) { + result += '\n'; + } + result += mfc::ToMFC(cst.definition.Str()); + return result; +} + +void RSEdit::AddReference() { + const auto pos = GetSubscriptDialogPosition(); + dialog::InsertCstDlg dialog(*context, pos, GetSelText()); + if (dialog.DoModal() == IDOK && !dialog.cstName.IsEmpty()) { + InsertString(dialog.cstName); + } +} + +BOOL RSEdit::NavigatorOn() { + using ccl::rslang::FindMinimalNode; + + if (navigatorEnabled) { + return TRUE; + } else if (!checker->isParsed) { + activeNode = std::nullopt; + MessageBeep(MB_ICONERROR); + return FALSE; + } else { + navigatorEnabled = TRUE; + const auto sel = GetSelectionRange(); + activeNode = FindMinimalNode(checker->parser.AST().Root(), + StrRange{ sel.start + prefixLen, sel.finish + prefixLen }); + return TRUE; + } +} + +BOOL RSEdit::MoveUp() noexcept { + return activeNode.has_value() && activeNode->MoveToParent(); +} + +BOOL RSEdit::MoveDown() { + if (!activeNode.has_value() || activeNode->ChildrenCount() == 0) { + return false; + } else if (activeNode->IsRoot()) { + activeNode->MoveToChild(1); // Note: Для корневого узла перывым потомком является сама конституента + return true; + } else { + activeNode->MoveToChild(0); + return true; + } +} + +BOOL RSEdit::MoveRight() { + return activeNode.has_value() && activeNode->MoveToNextSibling(); +} + +BOOL RSEdit::MoveLeft() { + return activeNode.has_value() && activeNode->MoveToPrevSibling(); +} + +} // namespace xtr::ui \ No newline at end of file diff --git a/src/ui/RSListCtrl.cpp b/src/ui/RSListCtrl.cpp new file mode 100644 index 0000000..313040c --- /dev/null +++ b/src/ui/RSListCtrl.cpp @@ -0,0 +1,75 @@ +#include "stdafx.h" + +#include "xtr/ui/RSListCtrl.h" + +#include "xtr/Exteor.h" + +namespace xtr::ui { + +int32_t RSListCtrl::GetColumnCount() const { + const auto* pHeader = GetHeaderCtrl(); + return pHeader == nullptr ? 0 : pHeader->GetItemCount(); +} + +int32_t RSListCtrl::GetFocusIndex() const { + return GetNextItem(mfc::noItems, LVIS_FOCUSED); +} + +int32_t RSListCtrl::GetSelectedIndex() const { + return GetNextItem(mfc::noItems, LVIS_SELECTED); +} + +void RSListCtrl::SetSelection(const int32_t nIndex) { + if (nIndex < GetItemCount()) { + SetItemState(nIndex, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED); + } +} + +void RSListCtrl::ClearSelection() { + SetItemState(mfc::noItems, 0, LVIS_DROPHILITED | LVIS_SELECTED | LVIS_FOCUSED); +} + +void RSListCtrl::MoveSelectedItemsTo(RSListCtrl& dest, const int32_t coloumns) { + if (coloumns != 0) { + dest.SetItemState(mfc::noItems, 0, LVIS_SELECTED | LVIS_FOCUSED); + auto item{ mfc::noItems }; + while ((item = GetNextItem(mfc::noItems, LVNI_SELECTED)) != mfc::noItems) { + const auto line = dest.GetItemCount(); + dest.InsertItem(line, GetItemText(item, 0)); + dest.SetItemState(line, LVIS_SELECTED, LVIS_SELECTED); + for (auto i = 1; i < coloumns; ++i) { + dest.SetItemText(line, i, GetItemText(item, i)); + } + DeleteItem(item); + } + } +} + +BOOL RSListCtrl::PreTranslateMessage(MSG* pMsg) { + static constexpr auto startingIndex = 0; + if (pMsg->message == WM_KEYDOWN && + pMsg->wParam == 'A' && + Keyboard::IsPressed(VK_CONTROL) && + (GetStyle() & LVS_SINGLESEL) == 0) { + if (IsItemSelected(startingIndex) && IsItemSelected(GetItemCount() - 1)) { + SetItemState(mfc::noItems, 0, LVIS_SELECTED | LVIS_FOCUSED); + } else { + SetItemState(mfc::noItems, LVIS_SELECTED, LVIS_SELECTED); + } + } + return CListCtrl::PreTranslateMessage(pMsg); +} + +void RSListCtrl::PreSubclassWindow() { + CListCtrl::PreSubclassWindow(); + SetExtendedStyle(GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP | LVS_EX_DOUBLEBUFFER); + SetFont(&XTROptions::App().fontTable); +} + +BOOL RSListCtrl::IsItemSelected(const int32_t item) { + return + item < GetItemCount() && + GetItemState(item, LVIS_SELECTED) != 0; +} + +} // namespace xtr::ui \ No newline at end of file diff --git a/src/ui/RSTableCtrl.cpp b/src/ui/RSTableCtrl.cpp new file mode 100644 index 0000000..6ad6f6b --- /dev/null +++ b/src/ui/RSTableCtrl.cpp @@ -0,0 +1,554 @@ +#include "stdafx.h" + +#include "xtr/ui/RSTableCtrl.h" + +#include "resource.h" + +#include "xtr/Exteor.h" +#include "xtr/cclDescriptor.h" +#include "xtr/doc/RSModelDoc.h" +#include "xtr/xtrDesign.h" +#include "xtr/xtrProcedures.h" + +#include "xtr/ui/UIHelper.h" + +namespace xtr::ui { + +using ccl::SetOfEntities; + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(RSTableCtrl, RSListCtrl) + ON_WM_DESTROY() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONUP() + + ON_NOTIFY_REFLECT_EX(LVN_BEGINDRAG, &ThisClass::OnBegindragConstituenta) + + ON_NOTIFY_REFLECT_EX(NM_CUSTOMDRAW, &ThisClass::OnNMCustomdraw) + ON_NOTIFY_REFLECT_EX(LVN_ITEMACTIVATE, &ThisClass::OnDblclkConstituenta) + ON_NOTIFY_REFLECT_EX(LVN_ITEMCHANGED, &ThisClass::OnSelectChange) + + ON_COMMAND_EX(ID_EDIT_COPY, &ThisClass::RunCommand) + ON_COMMAND_EX(ID_EDIT_PASTE, &ThisClass::RunCommand) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +struct RSTableCtrl::SchemaHeader : xtr::ui::Header { + enum Columns : uint8_t { + POS_NAME = 0, + POS_TYPE, + POS_RSDEF, + POS_TERM, + POS_TEXTDEF, + POS_COMMENT, + count + }; + + SchemaHeader() { + AddColumn({ IXTRS_HEADER_NAME, Alignment::left, XTROptions::RS().nameWidth }); + AddColumn({ IXTRS_HEADER_TYPE, Alignment::left, XTROptions::RS().typeWidth }); + AddColumn({ IXTRS_HEADER_RSDEF, Alignment::left, XTROptions::RS().expWidth }); + AddColumn({ IXTRS_HEADER_TERM, Alignment::left, XTROptions::RS().termWidth }); + AddColumn({ IXTRS_HEADER_TEXTDEF, Alignment::left, XTROptions::RS().interWidth }); + AddColumn({ IXTRS_HEADER_CONVENTION, Alignment::left, XTROptions::RS().conventionWidth }); + } +}; + +struct RSTableCtrl::ModelHeader : xtr::ui::Header { + enum Columns : uint8_t { + POS_NAME = 0, + POS_TYPE, + POS_RSDEF, + POS_VAL, + POS_TERM, + POS_TEXTDEF, + POS_COMMENT, + count + }; + + ModelHeader() { + AddColumn({ IXTRS_HEADER_NAME, Alignment::left, XTROptions::Model().nameWidth }); + AddColumn({ IXTRS_HEADER_TYPE, Alignment::left, XTROptions::Model().typeWidth }); + AddColumn({ IXTRS_HEADER_RSDEF, Alignment::left, XTROptions::Model().expWidth }); + AddColumn({ IXTRS_HEADER_CARD, Alignment::left, XTROptions::Model().valWidth }); + AddColumn({ IXTRS_HEADER_TERM, Alignment::left, XTROptions::Model().termWidth }); + AddColumn({ IXTRS_HEADER_TEXTDEF, Alignment::left, XTROptions::Model().interWidth }); + AddColumn({ IXTRS_HEADER_CONVENTION, Alignment::left, XTROptions::Model().conventionWidth }); + } +}; + + +void RSTableCtrl::Init(doc::RSFacade& doc) { + editor = &doc; + InitHeaders(); + InitToolTips(); + Update(TRUE); +} + +void RSTableCtrl::InitHeaders() { + if (editor->IsModel()) { + InitHeaderFor(*this, ModelHeader{}); + } else { + InitHeaderFor(*this, SchemaHeader{}); + } +} + +void RSTableCtrl::InitToolTips() { + if (tooltips.Create(this, TTS_ALWAYSTIP)) { + tooltips.SetMaxTipWidth(s_TooltipWidth); + tooltips.AddTool(this, mfc::LoadSID(IXTRS_TRSV_TOOLTIP_DEFAULT)); + tooltips.SetFont(&XTROptions::App().fontTooltip); + tooltips.Activate(TRUE); + } else { + TRACE(L"Unable to create the ToolTip!"); + } +} + +void RSTableCtrl::Update(const BOOL updateSelection) { + const auto& selList = updateSelection ? editor->Document().Selection() : selection; + const auto topIndex = GetTopIndex(); + + SetRedraw(FALSE); + DeleteAllItems(); + if (!std::empty(editor->Core())) { + for (const auto uid : editor->List()) { + InsertCst(uid); + } + EnsureVisible(GetItemCount() - 1, FALSE); + EnsureVisible(topIndex, TRUE); + SelectMultiple(selList); + } + SetRedraw(TRUE); +} + +std::optional RSTableCtrl::UIDForIndex(const int nItem) const { + if (nItem < GetItemCount() && nItem >= 0) { + const auto name = mfc::ToSTL(GetItemText(nItem, SchemaHeader::Columns::POS_NAME)); + return editor->Core().FindAlias(name); + } + return std::nullopt; +} + +std::optional RSTableCtrl::IndexForUID(const EntityUID uid) const { + const auto name = mfc::ToMFC(editor->GetRS(uid).alias); + for (auto i = 0; i < GetItemCount(); ++i) { + if (name == GetItemText(i, SchemaHeader::Columns::POS_NAME)) { + return i; + } + } + return std::nullopt; +} + +void RSTableCtrl::EnsureVisibleCst(const EntityUID uid) { + const auto nIndex = IndexForUID(uid); + assert(nIndex.has_value()); + + SCROLLINFO info{}; + GetScrollInfo(SB_VERT, &info); + + CPoint pos; + GetItemPosition(nIndex.value(), &pos); + + CPoint scrol; + GetItemPosition(info.nPos, &scrol); + + const auto rect = WindowRect(*this); + if (pos.y > scrol.y + rect.bottom - rect.top || static_cast(nIndex.value()) < info.nPos) { + EnsureVisible(nIndex.value(), TRUE); + } +} + +void RSTableCtrl::ResetColumns() { + if (editor->IsModel()) { + XTROptions::Model().ResetTableWidth(); + SetColumnWidth(ModelHeader::Columns::POS_NAME, XTROptions::Model().nameWidth); + SetColumnWidth(ModelHeader::Columns::POS_TYPE, XTROptions::Model().typeWidth); + SetColumnWidth(ModelHeader::Columns::POS_RSDEF, XTROptions::Model().expWidth); + SetColumnWidth(ModelHeader::Columns::POS_VAL, XTROptions::Model().valWidth); + SetColumnWidth(ModelHeader::Columns::POS_TERM, XTROptions::Model().termWidth); + SetColumnWidth(ModelHeader::Columns::POS_TEXTDEF, XTROptions::Model().interWidth); + SetColumnWidth(ModelHeader::Columns::POS_COMMENT, XTROptions::Model().conventionWidth); + } else { + XTROptions::RS().ResetTableWidth(); + SetColumnWidth(SchemaHeader::Columns::POS_NAME, XTROptions::RS().nameWidth); + SetColumnWidth(SchemaHeader::Columns::POS_TYPE, XTROptions::RS().typeWidth); + SetColumnWidth(SchemaHeader::Columns::POS_RSDEF, XTROptions::RS().expWidth); + SetColumnWidth(SchemaHeader::Columns::POS_TERM, XTROptions::RS().termWidth); + SetColumnWidth(SchemaHeader::Columns::POS_TEXTDEF, XTROptions::RS().interWidth); + SetColumnWidth(SchemaHeader::Columns::POS_COMMENT, XTROptions::RS().conventionWidth); + } + RedrawWindow(); +} + +void RSTableCtrl::Select(const EntityUID uid, const BOOL bClearSelection) { + if (bClearSelection) { + ClearSelection(); + } + const auto nIndex = IndexForUID(uid); + if (nIndex.has_value()) { + SetSelection(nIndex.value()); + } +} + +void RSTableCtrl::SelectMultiple(const SetOfEntities& selList) { + disableReentrance = TRUE; + + ClearSelection(); + for (const auto uid : selList) { + Select(uid, FALSE); + } + if (!empty(selList)) { + EnsureVisibleCst(*begin(selList)); + } + + disableReentrance = FALSE; + UpdateSelList(); +} + +BOOL RSTableCtrl::PreTranslateMessage(MSG* pMsg) { + if (tooltips.m_hWnd != nullptr) { + tooltips.RelayEvent(pMsg); + } + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN) { + ActivateCst(); + return TRUE; + } + return RSListCtrl::PreTranslateMessage(pMsg); +} + +void RSTableCtrl::OnDestroy() { + if (editor->IsModel()) { + XTROptions::Model().nameWidth = GetColumnWidth(ModelHeader::Columns::POS_NAME); + XTROptions::Model().typeWidth = GetColumnWidth(ModelHeader::Columns::POS_TYPE); + XTROptions::Model().expWidth = GetColumnWidth(ModelHeader::Columns::POS_RSDEF); + XTROptions::Model().valWidth = GetColumnWidth(ModelHeader::Columns::POS_VAL); + XTROptions::Model().termWidth = GetColumnWidth(ModelHeader::Columns::POS_TERM); + XTROptions::Model().interWidth = GetColumnWidth(ModelHeader::Columns::POS_TEXTDEF); + XTROptions::Model().conventionWidth = GetColumnWidth(ModelHeader::Columns::POS_COMMENT); + } else { + XTROptions::RS().nameWidth = GetColumnWidth(SchemaHeader::Columns::POS_NAME); + XTROptions::RS().typeWidth = GetColumnWidth(SchemaHeader::Columns::POS_TYPE); + XTROptions::RS().expWidth = GetColumnWidth(SchemaHeader::Columns::POS_RSDEF); + XTROptions::RS().termWidth = GetColumnWidth(SchemaHeader::Columns::POS_TERM); + XTROptions::RS().interWidth = GetColumnWidth(SchemaHeader::Columns::POS_TEXTDEF); + XTROptions::RS().conventionWidth = GetColumnWidth(SchemaHeader::Columns::POS_COMMENT); + } + RSListCtrl::OnDestroy(); +} + +BOOL RSTableCtrl::IsCommandActive(const uint32_t command) const noexcept { + switch (command) { + case IXTRC_MOVE_UP: + case IXTRC_MOVE_DOWN: + return size(selection) == 1; + case IXTRC_SELECT_BASIS: + case IXTRC_SELECT_DEPENDENT: + return !empty(selection); + default: + return TRUE; + } +} + +BOOL RSTableCtrl::RunCommand(const uint32_t command) { + if (IsCommandActive(command)) { + UpdateData(); + const auto& core = editor->Core(); + switch (command) { + default: break; + case IXTRC_SELECT_BASIS: { + SelectMultiple(core.RSLang().Graph().ExpandInputs(selection)); + break; + } + case IXTRC_SELECT_DEPENDENT: { + SelectMultiple(core.RSLang().Graph().ExpandOutputs(selection)); + break; + } + case ID_EDIT_COPY: { + g_Exteor.cstClipboard.clear(); + const auto sorted = core.List().SortSubset(selection); + for (const auto uid : sorted) { + g_Exteor.cstClipboard.emplace_back(core.AsRecord(uid)); + } + break; + } + case ID_EDIT_PASTE: PasteFromClipboard(); break; + case IXTRC_MOVE_UP: MoveUp(); break; + case IXTRC_MOVE_DOWN: MoveDown(); break; + } + } + return TRUE; +} + +BOOL RSTableCtrl::OnDblclkConstituenta(NMHDR* /*pNMHDR*/, LRESULT* result) { + ActivateCst(); + *result = FALSE; + return TRUE; +} + +BOOL RSTableCtrl::OnSelectChange(NMHDR* pNMHDR, LRESULT* result) { + *result = FALSE; + if (!disableReentrance) { + const auto* listView = reinterpret_cast(pNMHDR); + const auto selected = (listView->uOldState & LVNI_SELECTED) && !(listView->uNewState & LVNI_SELECTED); + const auto deselected = listView->uNewState & LVNI_SELECTED; + const auto changed = listView->uChanged & LVIF_STATE; + if (changed && (selected || deselected)) { + UpdateSelList(); + } + } + return TRUE; +} + +BOOL RSTableCtrl::OnNMCustomdraw(NMHDR* pNMHDR, LRESULT* result) { + *result = CDRF_DODEFAULT; + auto* device = reinterpret_cast(pNMHDR); + if (ProcessDrawStages(device, result)) { + return TRUE; + } else { + DrawSingleCell(device); + return FALSE; + } +} + +BOOL RSTableCtrl::ProcessDrawStages(const NMLVCUSTOMDRAW* device, LRESULT* result) noexcept { + if (device->nmcd.dwDrawStage == CDDS_PREPAINT) { + *result = CDRF_NOTIFYITEMDRAW; + return TRUE; + } else if (device->nmcd.dwDrawStage == CDDS_ITEMPREPAINT) { + *result = CDRF_NOTIFYSUBITEMDRAW; + return TRUE; + } else if (device->nmcd.dwDrawStage == (CDDS_ITEMPREPAINT | CDDS_SUBITEM)) { + *result = CDRF_DODEFAULT; + return FALSE; + } else { + return TRUE; + } +} + +void RSTableCtrl::DrawSingleCell(NMLVCUSTOMDRAW* device) { + if (const auto uid = UIDForIndex(static_cast(device->nmcd.dwItemSpec)); uid.has_value()) { + if (editor->IsModel()) { + device->clrText = design::TextColor(editor->Model(), uid.value()); + device->clrTextBk = design::BackgroundColor(editor->Model(), uid.value()); + } else { + device->clrText = design::TextColor(editor->Schema(), uid.value()); + device->clrTextBk = design::BackgroundColor(editor->Schema(), uid.value()); + } + } +} + +BOOL RSTableCtrl::OnBegindragConstituenta(NMHDR *pNMHDR, LRESULT* result) { + const auto* listView = reinterpret_cast(pNMHDR); + dnd.dragFrom = listView->iItem; + dnd.active = TRUE; + dnd.dragTo = std::nullopt; + dnd.source = this; + dnd.destination = this; + + SetCapture(); // Capture all mouse messages + + *result = FALSE; + return TRUE; +} + +void RSTableCtrl::OnMouseMove(const uint32_t nFlags, CPoint point) { + if (!dnd.active || m_hWnd == nullptr) { + RSListCtrl::OnMouseMove(nFlags, point); + return; + } + ClientToScreen(&point); + + auto* dropWnd = WindowFromPoint(point); + if (dropWnd != dnd.destination && dnd.destination == this) { + ResetHighlightScroll(); + } + dnd.destination = dropWnd; + if (dropWnd == this) { + UpdateHighlightScroll(point); + } +} + +void RSTableCtrl::ResetHighlightScroll() { + if (!dnd.dragTo.has_value()) { + return; + } + auto& dest = dynamic_cast(*dnd.destination); + dest.SetItemState(dnd.dragTo.value(), 0, LVIS_DROPHILITED); + dest.RedrawItems(dnd.dragTo.value(), dnd.dragTo.value()); + dest.UpdateWindow(); + dnd.dragTo = std::nullopt; +} + +void RSTableCtrl::UpdateHighlightScroll(CPoint cursorPos) { + static constexpr auto scrollDelay = 3; + static auto delay = 0; + + auto& dest = dynamic_cast(*dnd.destination); + if (dnd.dragTo.has_value()) { + dest.SetItemState(dnd.dragTo.value(), 0, LVIS_DROPHILITED); + dest.RedrawItems(dnd.dragTo.value(), dnd.dragTo.value()); + } + + dnd.destination->ScreenToClient(&cursorPos); + + auto uFlags = 0U; + dnd.dragTo = dest.HitTest(cursorPos, &uFlags); + if (dnd.dragTo.value() == mfc::noItems) { + dnd.dragTo = std::nullopt; + } + if (dnd.dragTo.has_value()) { + dest.SetItemState(dnd.dragTo.value(), LVIS_DROPHILITED, LVIS_DROPHILITED); + + if (delay <= 0) { + delay = scrollDelay; + if (dnd.dragTo.value() + 1 < dest.GetItemCount()) { + dest.EnsureVisible(dnd.dragTo.value() + 1, TRUE); + } + if (dnd.dragTo.value() - 1 >= 0) { + dest.EnsureVisible(dnd.dragTo.value() - 1, TRUE); + } + } else { + --delay; + } + + dest.RedrawItems(dnd.dragTo.value(), dnd.dragTo.value()); + dest.UpdateWindow(); + } +} + +void RSTableCtrl::OnLButtonUp(const uint32_t nFlags, CPoint point) { + if (!dnd.active || m_hWnd == nullptr) { + RSListCtrl::OnLButtonUp(nFlags, point); + return; + } + ReleaseCapture(); + + dnd.active = FALSE; + + ClientToScreen(&point); + auto* dropWnd = WindowFromPoint(point); + if (dropWnd == this) { + if (dnd.dragTo.has_value()) { + auto& dropCtrl = dynamic_cast(*dropWnd); + dropCtrl.SetItemState(dnd.dragTo.value(), 0, LVIS_DROPHILITED); + } + dnd.destination = dropWnd; + if (dnd.dragTo.has_value()) { + MoveSelectedBefore(dnd.dragTo.value()); + } + } +} + +void RSTableCtrl::UpdateSelList() { + selection.clear(); + auto nItem = mfc::noItems; + while ((nItem = GetNextItem(nItem, LVNI_SELECTED)) != mfc::noItems) { + selection.emplace(UIDForIndex(nItem).value()); + } +} + +void RSTableCtrl::PasteFromClipboard() { + const auto inserted = InsertClipboard(); + if (empty(inserted)) { + return; + } + + if (dynamic_cast(GetParent()) != nullptr) { + dynamic_cast(GetParent())->UpdateData(FALSE); + } else { + Update(); + } + SelectMultiple({ begin(inserted), end(inserted) }); +} + +ccl::VectorOfEntities RSTableCtrl::InsertClipboard() { + if (empty(g_Exteor.cstClipboard)) { + return {}; + } else if (empty(selection)) { + return editor->InsertCopy(g_Exteor.cstClipboard); + } else { + const auto selected = editor->List().SortSubset(selection); + const auto position = std::next(editor->List().Find(selected.back())); + bool isLast = position == editor->List().end(); + auto inserted = editor->InsertCopy(g_Exteor.cstClipboard); + for (const auto uid : inserted) { + editor->MoveBefore(uid, isLast ? editor->List().end() : position); + } + return inserted; + } +} + +void RSTableCtrl::MoveUp() { + if (const auto nItem = GetNextItem(mfc::noItems, LVNI_SELECTED); nItem > 0) { + MoveSelectedBefore(nItem - 1); + } +} + +void RSTableCtrl::MoveDown() { + if (const auto nItem = GetNextItem(mfc::noItems, LVNI_SELECTED); nItem != mfc::noItems) { + MoveSelectedBefore(nItem + 2); + } +} + +void RSTableCtrl::MoveSelectedBefore(const int32_t index) { + auto posWhere = std::end(editor->List()); + if (index < GetItemCount()) { + posWhere = editor->List().Find(UIDForIndex(index).value()); + } + proc::MoveCstBefore(*editor, selection, posWhere); +} + +void RSTableCtrl::ActivateCst() { + GetParent()->UpdateData(TRUE); + if (const auto nItem = GetFocusIndex(); nItem != mfc::noItems) { + proc::EditConstituenta(*editor, UIDForIndex(nItem).value()); + } +} + +void RSTableCtrl::InsertCst(const EntityUID target) { + const auto nItem = InsertItem(LVIF_TEXT | LVIF_STATE, GetItemCount(), mfc::ToMFC(editor->GetRS(target).alias), 0, 0, 0, 0); + if (nItem != mfc::noItems) { + InputCstData(nItem, target); + } else { + ::AfxMessageBox(IXTRE_CST_INSERT, MB_ICONERROR); + } +} + +void RSTableCtrl::InputCstData(const int32_t nItem, const EntityUID target) { + const auto& rsCst = editor->GetRS(target); + const auto& textCst = editor->GetText(target); + auto name = mfc::ToMFC(rsCst.alias); + auto expr = mfc::ToMFC(rsCst.definition); + auto comment = mfc::ToMFC(rsCst.convention); + auto inter = mfc::ToMFC(textCst.definition.Str()); + auto term = mfc::ToMFC(textCst.term.Nominal()); + auto type = info::Label(editor->Core().GetParse(target).TypePtr()); + + expr.Replace(L"\n", L" "); + inter.Replace(L"\n", L" "); + term.Replace(L"\n", L" "); + comment.Replace(L"\n", L" "); + + if (editor->IsModel()) { + const auto val = info::ValueStatus(target, editor->Model()); + SetItemText(nItem, ModelHeader::Columns::POS_NAME, name); + SetItemText(nItem, ModelHeader::Columns::POS_TYPE, type); + SetItemText(nItem, ModelHeader::Columns::POS_RSDEF, expr); + SetItemText(nItem, ModelHeader::Columns::POS_VAL, val); + SetItemText(nItem, ModelHeader::Columns::POS_TEXTDEF, inter); + SetItemText(nItem, ModelHeader::Columns::POS_TERM, term); + SetItemText(nItem, ModelHeader::Columns::POS_COMMENT, comment); + } else { + SetItemText(nItem, SchemaHeader::Columns::POS_NAME, name); + SetItemText(nItem, SchemaHeader::Columns::POS_TYPE, type); + SetItemText(nItem, SchemaHeader::Columns::POS_RSDEF, expr); + SetItemText(nItem, SchemaHeader::Columns::POS_TEXTDEF, inter); + SetItemText(nItem, SchemaHeader::Columns::POS_TERM, term); + SetItemText(nItem, SchemaHeader::Columns::POS_COMMENT, comment); + } +} + +} // namespace xtr::ui \ No newline at end of file diff --git a/src/ui/SplitterFrame.cpp b/src/ui/SplitterFrame.cpp new file mode 100644 index 0000000..1694a12 --- /dev/null +++ b/src/ui/SplitterFrame.cpp @@ -0,0 +1,118 @@ +#include "stdafx.h" + +#include "xtr/ui/SplitterFrame.h" + +#include "resource.h" + +#include "xtr/Exteor.h" + +#include "xtr/ui/UIHelper.h" + +#include "xtr/view/TermTreeView.h" +#include "xtr/view/OSSView.h" +#include "xtr/view/PictView.h" + +namespace xtr::ui { + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(Split2ViewFrame, CMDIChildWndEx) + ON_WM_GETMINMAXINFO() + ON_WM_DESTROY() + ON_WM_MDIACTIVATE() +END_MESSAGE_MAP() + +#pragma warning( pop ) + +Split2ViewFrame::Split2ViewFrame(const uint32_t registryID, const SIZE minSize, const uint32_t minPane2Width, int& splitterTracker) + : registryName{ mfc::LoadSID(registryID) }, minSize{ minSize }, minPane2Width{ minPane2Width }, secondViewWidth{ splitterTracker } {} + +BOOL Split2ViewFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, CCreateContext* pContext) { + XTROptions::LoadWindowPlacement(*this, registryName); + + const auto area = xtr::ui::ClientRect(*this); + auto width1 = area.Width() - secondViewWidth; + width1 = width1 <= 0 ? area.Width() : width1; + const auto width2 = area.Width() - width1; + + if (!splitterWnd.CreateStatic(this, 1, 2, WS_CHILD | WS_VISIBLE | WS_BORDER) || + !splitterWnd.CreateView(0, 0, pContext->m_pNewViewClass, { width1, area.Height() }, pContext) || + !splitterWnd.CreateView(0, 1, SecondViewClass(), { width2, area.Height() }, pContext)) { + TRACE(L"Failed to create Splitter\n"); + return FALSE; + } else { + splitterWnd.SetColumnInfo(0, width1, 0); + splitterWnd.SetColumnInfo(1, width2, minPane2Width); + splitterWnd.RecalcLayout(); + PostCreateSetup(splitterWnd.GetPane(0, 0), splitterWnd.GetPane(0, 1)); + return TRUE; + } +} + +void Split2ViewFrame::OnGetMinMaxInfo(MINMAXINFO* lpMMI) { // NOLINT(readability-make-member-function-const) + lpMMI->ptMinTrackSize.x = minSize.cx; + lpMMI->ptMinTrackSize.y = minSize.cy; +} + +void Split2ViewFrame::OnDestroy() { + if ((GetStyle() & (WS_MAXIMIZE | WS_MINIMIZE)) == 0) { + XTROptions::SaveWindowPlacement(*this, registryName); + int32_t pos{}; + int32_t minimal{}; + splitterWnd.GetColumnInfo(1, pos, minimal); + secondViewWidth = pos; + } +} + +void Split2ViewFrame::OnMDIActivate(BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd) { + ExteorApplication::MainFrame().UpdateUI(); + CMDIChildWndEx::OnMDIActivate(bActivate, pActivateWnd, pDeactivateWnd); +} + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +IMPLEMENT_DYNCREATE(RSFormFrame, Split2ViewFrame) + +#pragma warning( pop ) + +RSFormFrame::RSFormFrame() + : Split2ViewFrame(IXTRO_SECTION_TRSVIEW, { 500, 300 }, 150, XTROptions::RS().splitterPos) {} // NOLINT + +CRuntimeClass* RSFormFrame::SecondViewClass() { + return RUNTIME_CLASS(view::TermTreeView); +} + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +IMPLEMENT_DYNCREATE(RSModelFrame, Split2ViewFrame) + +RSModelFrame::RSModelFrame() + : Split2ViewFrame(IXTRO_SECTION_MODEL, { 500, 350 }, 150, XTROptions::Model().splitterPos) {} // NOLINT + +CRuntimeClass* RSModelFrame::SecondViewClass() { + return RUNTIME_CLASS(view::TermTreeView); +} + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +IMPLEMENT_DYNCREATE(OSSFrame, Split2ViewFrame) + +#pragma warning( pop ) + +OSSFrame::OSSFrame() + : Split2ViewFrame(IXTRO_SECTION_OSS, { 800, 500 }, 350, XTROptions::OSS().splitterPos) {} // NOLINT + +CRuntimeClass* OSSFrame::SecondViewClass() { + return RUNTIME_CLASS(view::PictView); +} + +void OSSFrame::PostCreateSetup(CWnd* firstView, CWnd* /*secondView*/) { + auto* ossView = dynamic_cast(firstView); + ossView->SetScrollSizes(MM_TEXT, SIZE{}); // Note: need to init scroll before any draw +} + +} // namespace xtr::ui \ No newline at end of file diff --git a/src/ui/TextEdit.cpp b/src/ui/TextEdit.cpp new file mode 100644 index 0000000..15fb9fc --- /dev/null +++ b/src/ui/TextEdit.cpp @@ -0,0 +1,405 @@ +#include "stdafx.h" + +#include "xtr/ui/TextEdit.h" + +#include "resource.h" + +#include "xtr/ExteorOptions.h" +#include "xtr/cclDescriptor.h" +#include "xtr/xtrDesign.h" + +#include "xtr/ui/UIHelper.h" +#include "xtr/ui/KeyboardHandler.h" + +#include "xtr/dialog/TerminRefDlg.h" +#include "xtr/dialog/WordRefDlg.h" + +namespace xtr::ui { + +using viewmodel::HighlightItem; + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +BEGIN_MESSAGE_MAP(TextEdit, BuffRichEdit) + ON_WM_KEYDOWN() + + ON_CONTROL_REFLECT_EX(EN_CHANGE, &ThisClass::OnTextChange) + ON_NOTIFY_REFLECT_EX(EN_SELCHANGE, &ThisClass::OnSelChange) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +TextEdit::TextEdit() : + presenter{ *this } { + BuffRichEdit::defaultToolTipText = mfc::LoadSID(IXTRS_TEXT_TOOLTIP_DEFAULT); +} + +void TextEdit::Initialize(const CString refStr, + doc::RSFacade& targetEditor, + BOOL advancedRefs, const BOOL wantReturn) { + resolveRefs = advancedRefs; + ignoreReturn = !wantReturn; + editor = &targetEditor; + presenter.Initialize(editor->Texts().Context()); + SetRefStr(refStr); +} + +void TextEdit::PreSubclassWindow() { + BuffRichEdit::PreSubclassWindow(); + SetFont(&XTROptions::App().fontText); +} + +void TextEdit::SetRefStr(const CString refStr) { + if (resolveRefs) { + presenter.SetRefStr(refStr); + } else { + SetWindowTextW(refStr); + } +} + +CString TextEdit::GetRefStr() { + if (resolveRefs) { + return presenter.GetRefStr(); + } else { + return GetText(); + } +} + +BOOL TextEdit::PreTranslateMessage(MSG* pMsg) { + if (pMsg->message != WM_KEYDOWN) { + return BuffRichEdit::PreTranslateMessage(pMsg); + } else if (const auto key = pMsg->wParam; + key != VK_SPACE || !Keyboard::IsPressed(VK_CONTROL)) { + return BuffRichEdit::PreTranslateMessage(pMsg); + } else { + switchLayoutOnCtrl = FALSE; + const auto cr = ShrinkSelection(); + const auto borderCheck = !IsBorderHL(cr.start) && !IsBorderHL(cr.finish); + if (borderCheck) { + if (Keyboard::IsPressed(VK_SHIFT)) { + RunAddDependWord(); + } else { + RunAddTerminRef(); + } + } + return TRUE; + } +} + +void TextEdit::OnKeyDown(const uint32_t key, const uint32_t nRepCnt, const uint32_t nFlags) { + if (ProcessKeyDown(key, nRepCnt, nFlags)) { + switchLayoutOnCtrl = FALSE; + } else { + BuffRichEdit::OnKeyDown(key, nRepCnt, nFlags); + } +} + +BOOL TextEdit::ProcessKeyDown(const uint32_t key, const uint32_t nRepCnt, const uint32_t nFlags) { + if (PreProcessKey(key)) { + return TRUE; + } else if (!resolveRefs) { + return FALSE; + } else if (ProcessKeyConst(key)) { + return TRUE; + } else if ((GetStyle() & ES_READONLY) != 0) { + return FALSE; + } else if (ProcessKeyEdit(key)) { + return TRUE; + } else if (Keyboard::IsPressed(VK_CONTROL) && key == 'V') { + const auto start = GetSelectionRange().start; + BuffRichEdit::OnKeyDown(key, nRepCnt, nFlags); + ResetHighlight(StrRange{ start, GetSelectionRange().finish }); + return TRUE; + } else { + return FALSE; + } +} + +BOOL TextEdit::PreProcessKey(const uint32_t key) { + switch (key) { + default: return FALSE; + case VK_RETURN: { + return ignoreReturn; + } + case 'T': { + if (Keyboard::IsPressed(VK_CONTROL) && Keyboard::IsPressed(VK_SHIFT)) { + resolveRefs = !resolveRefs; + if (!resolveRefs) { + SetWindowTextW(presenter.GetRefStr()); + } else { + presenter.SetRefStr(GetText()); + } + return TRUE; + } else { + return FALSE; + } + } + } +} + +BOOL TextEdit::ProcessKeyConst(const uint32_t key) { + switch (key) { + default: return FALSE; + case 'C': { + if (Keyboard::IsPressed(VK_CONTROL) && Keyboard::IsPressed(VK_SHIFT)) { + CopyWithReferences(GetSelectionRange()); + return TRUE; + } else { + return FALSE; + } + } + } +} + +BOOL TextEdit::ProcessKeyEdit(const uint32_t key) { + switch (key) { + default: return FALSE; + case VK_BACK: + case VK_DELETE: { + presenter.OnEraseText(GetSelectionRange(), key == VK_BACK); + return TRUE; + } + } +} + +void TextEdit::CopyWithReferences(const StrRange range) { + if (!OpenClipboard()) { + ::AfxMessageBox(IXTRE_CLIPBOARD_OPEN, MB_ICONERROR); + } else if (!EmptyClipboard()) { + ::AfxMessageBox(IXTRE_CLIPBOARD_CLEAR, MB_ICONERROR); + } else { + if (auto cpyStr = presenter.GetRefSubstr(range); !cpyStr.IsEmpty()) { + if (auto* hGlob = GlobalAlloc(GMEM_FIXED, (wcslen(cpyStr) + 1) * sizeof(wchar_t)); hGlob != nullptr) { + wcscpy_s(static_cast(hGlob), wcslen(cpyStr) + 1, cpyStr); + if (::SetClipboardData(CF_UNICODETEXT, hGlob) == nullptr) { + ::AfxMessageBox(IXTRE_CLIPBOARD_COPY, MB_ICONERROR); + GlobalFree(hGlob); + } + } + } + CloseClipboard(); + } +} + +BOOL TextEdit::OnTextChange() { + if (resolveRefs) { + presenter.Invalidate(); + } + if (const auto sel = GetSelectionRange(); std::empty(sel) && sel.start > 0) { + ResetHighlight(StrRange{ sel.start - 1, sel.start }); + } + const auto result = BuffRichEdit::OnTextChange(); + UpdateLock(); + return result; +} + +BOOL TextEdit::OnSelChange(NMHDR* pNotifyStruct, LRESULT* result) { + UpdateLock(); + return BuffRichEdit::OnSelChange(pNotifyStruct, result); +} + +void TextEdit::UpdateLock() { + if (!readOnly) { + const auto selection = GetSelectionRange(); + BOOL blockUserInput = FALSE; + if (selection.empty()) { + blockUserInput = IsBorderHL(selection.start) && !IsBorderHL(selection.start, TRUE); + } else { + const auto format = GetSelectionFormat(); + blockUserInput = !(format.dwMask & CFM_BACKCOLOR) || design::IsReference(format.crBackColor); + } + if (blockUserInput) { + LockInput(); + } else { + UnlockInput(); + } + } +} + +BOOL TextEdit::RunAddTerminRef() { + const auto pos = GetSubscriptDialogPosition(); + const auto selection = FixSelection(); + dialog::TerminRefDlg dialog(*editor, pos, selection); + if (dialog.DoModal() != IDOK) { + return FALSE; + } else { + presenter.OnInsertRef(GetSelectionRange(), dialog.CreateRef()); + return TRUE; + } +} + +BOOL TextEdit::RunAddDependWord() { + const auto pos = GetWordDlgPos(); + const auto selection = FixSelection(); + dialog::WordRefDlg companionDlg(pos, selection); + + FreezeUI(); + const auto result = companionDlg.DoModal(); + UnFreezeUI(); + + if (result != IDOK) { + return FALSE; + } else { + presenter.OnInsertRef(GetSelectionRange(), companionDlg.CreateRef()); + return TRUE; + } +} + +RECT TextEdit::GetWordDlgPos() { + static constexpr auto HORIZONTAL_OFFSET = 150; + const auto rect = WindowRect(*this); + const auto x = rect.left + GetCaretPos().x + 5; + const auto y = rect.top + GetCaretPos().y + 5; + + const auto metrics = TextMetricsOf(*this); + const auto lineHeight = metrics.tmHeight + metrics.tmExternalLeading; + + RECT dlgRect{}; + dlgRect.left = x; + dlgRect.right = x + HORIZONTAL_OFFSET; + dlgRect.top = y; + dlgRect.bottom = y + lineHeight; + return dlgRect; +} + +CString TextEdit::GenerateToolTipText() { + if (!resolveRefs) { + return defaultToolTipText; + } else if (const auto* ref = presenter.RepresentativeOf(GetSelectionRange()); + ref == nullptr) { + return defaultToolTipText; + } else { + return info::DescriptionOf(*ref); + } +} + +BOOL TextEdit::IsBorderHL(const StrPos position, const BOOL oneSide) { + if (position < 0 || position > Text().GetLength()) { + return FALSE; + } else { + FreezeUI(); + + auto leftResult = FALSE; + auto rightResult = FALSE; + if (position != 0) { + SelectChar(position - 1); + if (const auto color = GetSelectionFormat().crBackColor; design::IsReference(color)) { + leftResult = TRUE; + } + } + if (position != Text().GetLength()) { + SelectChar(position); + if (const auto color = GetSelectionFormat().crBackColor; design::IsReference(color)) { + rightResult = TRUE; + } + } + + UnFreezeUI(); + return oneSide ? leftResult != rightResult : leftResult || rightResult; + } +} + +StrRange TextEdit::ShrinkSelection(){ + FreezeUI(); + + auto selection = GetSelectionRange(); + while (TRUE) { + if (selection.start == selection.finish || GetSelText()[0] != ' ') { + break; + } else { + ++selection.start; + SelectRange(selection); + } + } + while (TRUE) { + if (selection.start == selection.finish) { + break; + } else if (const auto txt = GetSelText(); txt[txt.GetLength() - 1] != ' ') { + break; + } else { + --selection.finish; + SelectRange(selection); + } + } + + BuffRichEdit::UnFreezeUI(selection); + return selection; +} + +CString TextEdit::GetText() const { + return Text(); +} + +void TextEdit::SetText(const CString text) { + FreezeUI(); + SetWindowTextW(text); + UnFreezeUI(); +} + +void TextEdit::UnFreezeUI() { + BuffRichEdit::UnFreezeUI(); + if (!IsFrozen()) { + UpdateLock(); + } +} + +std::optional TextEdit::NextHighlighted(const StrPos start) { + FreezeUI(); + const auto result = ScanHighlight(start); + UnFreezeUI(); + return result; +} + +std::optional TextEdit::ScanHighlight(const StrPos start) { + const auto maxLen = Text().GetLength(); + std::optional hlColor{}; + auto l = -1; + auto r = -1; + for (auto curPos = start; curPos < maxLen; ++curPos) { + SelectChar(curPos); + const auto color = GetSelectionFormat().crBackColor; + if (hlColor.has_value() && + (color == RGB(255, 255, 255) || color != hlColor)) { + return HighlightItem{ StrRange{ l, r }, hlColor.value() }; + } else { + r = curPos + 1; + if (!hlColor.has_value()) { + hlColor = color; + l = curPos; + } + } + } + if (!hlColor.has_value()) { + return std::nullopt; + } else { + return HighlightItem{ StrRange{ l, r }, hlColor.value() }; + } +} + +void TextEdit::ReplaceRange(const StrRange range, const CString replacement) { + FreezeUI(); + + SelectRange(range); + ReplaceSel(replacement, FALSE); + + BuffRichEdit::UnFreezeUI(StrRange::FromLength(range.start + replacement.GetLength(), 0)); +} + +void TextEdit::Highlight(const HighlightItem item) { + auto format = design::CharFormatRE(); + format.dwMask = CFM_BACKCOLOR; + format.crBackColor = item.color; + + FreezeUI(); + SelectAndFormat(item.rng, format); + UnFreezeUI(); +} + +void TextEdit::ResetHighlight(const StrRange hlRange) { + FreezeUI(); + SelectAndFormat(hlRange, DefaultFormat()); + UnFreezeUI(); +} + +} // namespace xtr::ui \ No newline at end of file diff --git a/src/ui/UIHelper.cpp b/src/ui/UIHelper.cpp new file mode 100644 index 0000000..3d0d092 --- /dev/null +++ b/src/ui/UIHelper.cpp @@ -0,0 +1,88 @@ +#include "stdafx.h" + +#include "xtr/ui/UIHelper.h" + +#include "resource.h" +#include "xtr/ExteorOptions.h" + +namespace xtr::ui { + +CRect WindowRect(const CWnd& wndCtrl) { + CRect rect{}; + GetWindowRect(wndCtrl, &rect); + return rect; +} + +CRect ClientRect(const CWnd& wndCtrl) { + CRect rect{}; + GetClientRect(wndCtrl, &rect); + return rect; +} + +CString WindowText(const CWnd& wndCtrl) { + CString text{}; + wndCtrl.GetWindowTextW(text); + return text; +} + +CString TrimText(CString text) { + text.Trim(L" -\n\r"); + return text; +} + +CRect LocalCoordinatesFor(const CWnd& wndCtrl) { + auto rect = WindowRect(wndCtrl); + MapWindowPoints(HWND_DESKTOP, GetParent(wndCtrl), reinterpret_cast(&rect), 2); + return rect; +} + +TEXTMETRIC GlobalTextMetrics() { + CDC pDC{}; + pDC.CreateCompatibleDC(nullptr); + + TEXTMETRIC metrics{}; + if (!pDC.GetTextMetricsW(&metrics)) { + ::AfxMessageBox(IXTRE_TEXT_METRICS, MB_ICONERROR); + } + return metrics; +} + +TEXTMETRIC TextMetricsOf(const CWnd& wndCtrl) { + CDC pDC{}; + pDC.Attach(::GetDC(nullptr)); + pDC.SelectObject(wndCtrl.GetFont()); + + TEXTMETRIC metrics{}; + if (!pDC.GetTextMetricsW(&metrics)) { + ::AfxMessageBox(IXTRE_TEXT_METRICS, MB_ICONERROR); + } + return metrics; +} + +void InitHeaderFor(CListCtrl& listCtr, const Header& header) { + static constexpr auto autoWidth = -1; + + listCtr.DeleteAllItems(); + auto nCol = 0; + for (const auto& column : header.columns) { + listCtr.InsertColumn( + nCol++, + column.label, + column.alignment, + column.width.value_or(autoWidth)); + } +} + +void InitReversedHeaderFor(CListCtrl& listCtr, const Header& header) { + static constexpr auto autoWidth = -1; + auto nCol = 0; + for (auto iter = header.columns.rbegin(); iter != header.columns.rend(); ++iter) { + listCtr.InsertColumn( + ++nCol, + iter->label, + iter->alignment, + iter->width.value_or(autoWidth)); + } +} + +} // namespace xtr::ui \ No newline at end of file diff --git a/src/view/OSSLayout.cpp b/src/view/OSSLayout.cpp new file mode 100644 index 0000000..1d6f49e --- /dev/null +++ b/src/view/OSSLayout.cpp @@ -0,0 +1,401 @@ +#include "stdafx.h" + +#include "xtr/view/OSSLayout.h" + +#include "resource.h" + +#include "xtr/Exteor.h" +#include "xtr/cclDescriptor.h" +#include "xtr/xtrDesign.h" + +#include "xtr/ui/UIHelper.h" + +#include "xtr/view/OSSView.h" + +namespace xtr::view { + +using ccl::oss::Pict; +using ccl::oss::PictID; +using ccl::oss::PictPtr; +using ccl::oss::GridPosition; + +static constexpr auto AREA_BORDER_SIZE = 2; +static constexpr auto ICON_SIZE = 16; + +static constexpr auto CELL_WIDTH = 135; +static constexpr auto CELL_HEIGHT = 135; +static constexpr auto PICT_WIDTH = 90; +static constexpr auto PICT_HEIGHT = 45; + +OSSLayout::OSSLayout(const ccl::oss::OSSchema& oss) + : oss(&oss) { + zoom = static_cast(XTROptions::OSS().zoom); + + const auto metrics = ui::GlobalTextMetrics(); + charHeight = metrics.tmHeight; + charWidth = metrics.tmMaxCharWidth; + + cellWidth = CELL_WIDTH; + cellHeight = CELL_HEIGHT; + + pictWidth = PICT_WIDTH; + pictHeight = PICT_HEIGHT; +} + +void OSSLayout::InitImageList() { + if (!icons.Create(ICON_SIZE, ICON_SIZE, ILC_MASK, 2, 2)) { + ::AfxMessageBox(IXTRS_OSS_CANT_CREATE_ICON_LIST, MB_ICONERROR); + } + + icons.Add(::AfxGetApp()->LoadIconW(IXTRR_PICT_BASIS)); + icons.Add(::AfxGetApp()->LoadIconW(IXTRR_PICT_UNDEFINED)); + icons.Add(::AfxGetApp()->LoadIconW(IXTRR_PICT_DEFINED)); + icons.Add(::AfxGetApp()->LoadIconW(IXTRR_PICT_DONE)); + icons.Add(::AfxGetApp()->LoadIconW(IXTRR_PICT_REDO)); + icons.Add(::AfxGetApp()->LoadIconW(IXTRR_PICT_BROKEN)); + icons.Add(::AfxGetApp()->LoadIconW(IXTRR_PICT_HASFILE)); + + icons.SetBkColor(design::clrWhite); +} + +int32_t OSSLayout::GetClientWidth() const { + static constexpr double AREA_X_MIN = 4; + static constexpr auto BORDER_GAP = 1.5; + const auto visibleWidth = std::accumulate(std::begin(*oss), std::end(*oss), AREA_X_MIN, + [&grid = oss->Grid()](double maxEff, const Pict& pict) { + if (grid(pict.uid).has_value()) { + return std::max(grid(pict.uid)->EffectiveColumn(), maxEff); + } else { + return maxEff; + } + }); + return static_cast((visibleWidth + BORDER_GAP) * cellWidth / zoom) + AREA_BORDER_SIZE; +} + +int32_t OSSLayout::GetClientHeight() const { + static constexpr auto AREA_Y_MIN = 4; + const auto maxYCell = std::max(oss->Grid().CountRows(), AREA_Y_MIN); + return static_cast(maxYCell * cellHeight / zoom) + AREA_BORDER_SIZE; +} + +CRect OSSLayout::PictRect(const PictID pid, const float scale) const { + if (scale <= 0) { + return CRect{}; + } + auto pos = oss->Grid()(pid); + + CPoint leftTop{}; + leftTop.x = static_cast(cellWidth * scale * pos->EffectiveColumn()); + leftTop.y = static_cast(pos->row * cellHeight * scale); + + SIZE size{}; + size.cx = static_cast(pictWidth * scale); + size.cy = static_cast(pictHeight * scale); + CRect result{ leftTop, size }; + + CPoint offset{}; + offset.x = static_cast((cellWidth - pictWidth) / 2.0F * scale); + offset.y = static_cast((cellHeight - pictHeight) / 2.0F * scale); + result.OffsetRect(offset); + return result; +} + +CRect OSSLayout::CellRect(const GridPosition pos, const float scale) const noexcept { + CPoint leftTop{}; + leftTop.x = static_cast(cellWidth * scale * pos.EffectiveColumn()); + leftTop.y = static_cast(pos.row * cellHeight * scale); + + SIZE size{}; + size.cx = static_cast(cellWidth * scale); + size.cy = static_cast(cellHeight * scale); + return CRect{ leftTop, size }; +} + +PictPtr OSSLayout::PictFromPoint(CPoint point) const { + if (const auto cell = PositionFromPoint(point); !cell.has_value()) { + return nullptr; + } else if (const auto pict = oss->Grid()(cell.value()); !pict.has_value()) { + return nullptr; + } else if (!PictRect(pict.value(), 1 / zoom).PtInRect(point)) { + return nullptr; + } else { + return (*oss)(pict.value()); + } +} + +std::optional OSSLayout::PositionFromPoint(CPoint point) const noexcept { + const auto rowApprox = zoom * point.y / cellHeight; + assert(rowApprox >= 0); + const auto columnApprox = zoom * point.x / cellWidth - rowApprox / 2.0; + if (columnApprox < 0) { + return std::nullopt; + } else { + GridPosition result{}; + result.row = static_cast(zoom * point.y / cellHeight); + result.column = static_cast(columnApprox); + return result; + } +} + +void OSSLayout::Draw(CDC* pDC, const std::optional active) { + static constexpr float IMAGE_MOD_ZOOM = 1; + const auto drawZoom = saveImage ? IMAGE_MOD_ZOOM : zoom; + drawScale = 1 / drawZoom; + drawDC = pDC; + + const auto clientArea = DetermineDrawArea(); + PrepareBuffer(pDC, clientArea); + + DrawBackground(clientArea); + DrawGrid(); + for (const auto& pict : *oss) { + DrawPictConnections(pict); + } + for (const auto& pict : *oss) { + DrawPict(pict, active.has_value() && pict.uid == active.value()); + } + DrawLegend(); + + if (buffer == nullptr) { + throw std::runtime_error("Layout buffer unexpected error!"); + } else { + LoadFromBuffer(pDC); + } +} + +CImage OSSLayout::GetImage() { + CBitmap bitmap{}; + if (!bitmap.CreateBitmap(1, 1, 1, 32, nullptr)) { // NOLINT + TRACE("Cannot create bitmap"); + } + auto* memDC = ::CreateCompatibleDC(nullptr); + auto* cdc = CDC::FromHandle(memDC); + cdc->SelectObject(bitmap); + + saveImage = TRUE; + Draw(cdc); + saveImage = FALSE; + ::DeleteDC(memDC); + + CImage image{}; + image.Attach(buffer->bmp); + return image; +} + +void OSSLayout::LoadFromBuffer(CDC* pDC) { + pDC->SetViewportOrg(0, 0); + pDC->SetWindowOrg(0, 0); + pDC->SetMapMode(MM_TEXT); + + drawDC->SetViewportOrg(0, 0); + drawDC->SetWindowOrg(0, 0); + drawDC->SetMapMode(MM_TEXT); + + pDC->BitBlt(buffer->rect.left, buffer->rect.top, buffer->rect.Width(), buffer->rect.Height(), drawDC, 0, 0, SRCCOPY); + drawDC->SelectObject(buffer->oldBitmap); +} + +void OSSLayout::PrepareBuffer(CDC* pDC, const CRect clientArea) { + static constexpr auto BRUSH_RADIX = 8; + buffer = std::make_unique(); + buffer->rect = clientArea; + pDC->LPtoDP(buffer->rect); + buffer->rect.NormalizeRect(); + if (!buffer->context.CreateCompatibleDC(pDC)) { + return; + } else if (!buffer->bmp.CreateCompatibleBitmap(pDC, buffer->rect.Width(), buffer->rect.Height())) { + return; + } else { + if (auto* view = dynamic_cast(pDC->GetWindow()); view != nullptr) { + view->OnPrepareDC(&buffer->context, nullptr); + } + drawDC = &buffer->context; + buffer->context.OffsetViewportOrg(-buffer->rect.left, -buffer->rect.top); + buffer->oldBitmap = buffer->context.SelectObject(&buffer->bmp); + buffer->context.SetBrushOrg(buffer->rect.left % BRUSH_RADIX, buffer->rect.top % BRUSH_RADIX); + buffer->context.IntersectClipRect(clientArea); + } +} + +CRect OSSLayout::DetermineDrawArea() { + CRect clientArea{}; + if (!saveImage) { + drawDC->GetClipBox(clientArea); + } else { + clientArea = CRect{ CPoint{ 0, 0 }, + CSize{ static_cast(GetClientWidth() * zoom * drawScale), + static_cast(GetClientHeight() * zoom * drawScale) } }; + } + return clientArea; +} + +void OSSLayout::DrawBackground(CRect bgRect) { + if (CBrush brush{}; brush.CreateSolidBrush(design::clrWhite)) { + brush.UnrealizeObject(); + drawDC->FillRect(bgRect, &brush); + } +} + +void OSSLayout::DrawGrid() { + if (XTROptions::OSS().showGrid) { + auto sizeX = 0; + const auto sizeY = oss->Grid().CountRows(); + for (auto row = 0; row < sizeY; ++row) { + sizeX = std::max(sizeX == 0 ? 0 : sizeX - 1, oss->Grid().MaxColumnIn(row)); + for (auto column = 0; column <= sizeX; ++column) { + DrawCell({ row, column }); + } + } + } +} + +void OSSLayout::DrawCell(GridPosition pos) { + static constexpr auto GRID_THICKNESS = 1; + static constexpr auto GRID_LINESTYLE = PS_DASH; + if (CPen pen{}; pen.CreatePen(GRID_LINESTYLE, GRID_THICKNESS, design::clrGray200)) { + auto* oldPen = drawDC->SelectObject(&pen); + + auto cellRect = CellRect(pos, drawScale); + ++cellRect.right; // Note: grid rectangles overlap to form single width grid lines + ++cellRect.bottom; + drawDC->Rectangle(cellRect); + + drawDC->SelectObject(oldPen); + } +} + +void OSSLayout::DrawPictConnections(const Pict& pict) { + const auto rect = PictRect(pict.uid, drawScale); + const auto parents = oss->Graph().ParentsOf(pict.uid); + for (const auto parent : parents) { + const auto rectParent = PictRect(parent, drawScale); + drawDC->MoveTo(static_cast(rectParent.CenterPoint().x), + static_cast(rectParent.bottom)); + drawDC->LineTo(rect.CenterPoint().x, rect.top); + } +} + +void OSSLayout::DrawPict(const Pict& pict, bool isActive) { + const auto oldClrTxt = drawDC->GetTextColor(); + const auto oldClrTxtBg = drawDC->GetBkColor(); + + const auto rect = PictRect(pict.uid, drawScale); + if (isActive) { + DrawActiveRect(rect); + } else { + DrawInactiveRect(rect); + } + DrawPictStatus(rect, pict.uid); + DrawPictText(rect, pict); + + drawDC->SetTextColor(oldClrTxt); + drawDC->SetBkColor(oldClrTxtBg); +} + +void OSSLayout::DrawActiveRect(CRect rect) { + static constexpr auto ACTIVE_PICT_THICKNESS = 2; + + if (CPen pen{}; pen.CreatePen(PS_SOLID, ACTIVE_PICT_THICKNESS, design::clrRed)) { + auto* oldPen = drawDC->SelectObject(&pen); + drawDC->Rectangle(rect); + drawDC->SelectObject(oldPen); + } +} + +void OSSLayout::DrawInactiveRect(CRect rect) { + static constexpr auto INACTIVE_PICT_THICKNESS = 1; + if (CPen pen{}; pen.CreatePen(PS_SOLID, INACTIVE_PICT_THICKNESS, design::clrBlack)) { + auto* oldPen = drawDC->SelectObject(&pen); + drawDC->Rectangle(rect); + drawDC->SelectObject(oldPen); + } +} + +void OSSLayout::DrawPictStatus(CRect rect, const PictID pid) { + static constexpr auto ICON_OFFSET_X = 3; + static constexpr auto ICON_OFFSET_Y = 5; + if (drawScale >= 1) { + CPoint iconShift{}; + iconShift.x = ICON_OFFSET_X; + iconShift.y = charHeight + ICON_OFFSET_Y; + DrawStatusIcon(rect.TopLeft() + iconShift, pid); + } +} + +void OSSLayout::DrawStatusIcon(CPoint topLeft, const PictID pid) const { + static constexpr auto ICON_SHIFT = 50; + const auto iconID = GetIconID(pid); + icons.Draw(drawDC, static_cast(iconID), topLeft, ILD_TRANSPARENT); + if (!std::empty(*oss->Src()(pid)) && !saveImage) { + topLeft.x = topLeft.x + ICON_SIZE + ICON_SHIFT; + icons.Draw(drawDC, static_cast(IconID::OSSI_PICT_HASFILE), topLeft, ILD_TRANSPARENT); + } +} + +void OSSLayout::DrawPictText(CRect rect, const Pict& pict) { + static constexpr auto TEXT_OFFSET_X = 1; + static constexpr auto TEXT_OFFSET_Y = 1; + + const CString text = [&alias = pict.alias] { + if (!std::empty(alias)) { + return mfc::ToMFC(alias); + } else { + return CString{ LR"(N/A)" }; + } + }(); + + drawDC->SetTextColor(design::clrBlack); + if (saveImage) { + drawDC->SetBkColor(design::clrWhite); + } else { + drawDC->SetBkColor(design::BackgroundColor(*oss, pict.uid)); + } + drawDC->ExtTextOutW(rect.left + TEXT_OFFSET_X, rect.top + TEXT_OFFSET_Y, ETO_CLIPPED, rect, text, nullptr); +} + +void OSSLayout::DrawLegend() { + if (drawScale < 1 || !XTROptions::OSS().showLegend) { + return; + } + const auto bottom = GetClientHeight() - AREA_BORDER_SIZE; + const auto top = bottom - 2 * cellHeight; + + drawDC->Rectangle(0, bottom, cellWidth, top); + legendYBase = top + 2; + + DrawLegendItem(IconID::OSSI_PICT_BASIS, mfc::LoadSID(IXTRS_DRAW_BASE)); + DrawLegendItem(IconID::OSSI_PICT_UNDEFINED, info::DrawableLabel(ccl::ops::Status::undefined)); + DrawLegendItem(IconID::OSSI_PICT_DEFINED, info::DrawableLabel(ccl::ops::Status::defined)); + DrawLegendItem(IconID::OSSI_PICT_DONE, info::DrawableLabel(ccl::ops::Status::done)); + DrawLegendItem(IconID::OSSI_PICT_REDO, info::DrawableLabel(ccl::ops::Status::outdated)); + DrawLegendItem(IconID::OSSI_PICT_BROKEN, info::DrawableLabel(ccl::ops::Status::broken)); + DrawLegendItem(IconID::OSSI_PICT_HASFILE, mfc::LoadSID(IXTRS_DRAW_HAS_FILE)); +} + +void OSSLayout::DrawLegendItem(const IconID icon, const CString text) { + static constexpr auto LEGEND_SHIFT = 5; + static constexpr auto TEXT_POS = ICON_SIZE + 2 * LEGEND_SHIFT; + static constexpr auto TEXT_OFFSET = 20; + + const auto yPos = legendYBase + static_cast(icon) * (2 * charHeight + LEGEND_SHIFT); + CRect textRect{ TEXT_POS, yPos, cellWidth - TEXT_POS + TEXT_OFFSET, yPos + 2 * charHeight }; + icons.Draw(drawDC, static_cast(icon), { LEGEND_SHIFT, yPos + charHeight / 2 }, ILD_TRANSPARENT); + drawDC->DrawTextW(text, textRect, 0); +} + +OSSLayout::IconID OSSLayout::GetIconID(const PictID pid) const { + if (!oss->Ops().HasOperation(pid)) { + return IconID::OSSI_PICT_BASIS; + } else { + switch (oss->Ops().StatusOf(pid)) { + default: return IconID::OSSI_PICT_BASIS; + case ccl::ops::Status::undefined: return IconID::OSSI_PICT_UNDEFINED; + case ccl::ops::Status::defined: return IconID::OSSI_PICT_DEFINED; + case ccl::ops::Status::done: return IconID::OSSI_PICT_DONE; + case ccl::ops::Status::outdated: return IconID::OSSI_PICT_REDO; + case ccl::ops::Status::broken: return IconID::OSSI_PICT_BROKEN; + } + } +} + +} // namespace xtr::view \ No newline at end of file diff --git a/src/view/OSSView.cpp b/src/view/OSSView.cpp new file mode 100644 index 0000000..4fc4f38 --- /dev/null +++ b/src/view/OSSView.cpp @@ -0,0 +1,524 @@ +#include "stdafx.h" + +#include "xtr/view/OSSView.h" + +#include "resource.h" + +#include "xtr/cclDescriptor.h" +#include "xtr/xtrProcedures.h" +#include "xtr/ExteorOptions.h" + +#include "xtr/ui/HelpHandler.h" +#include "xtr/ui/UIHelper.h" + +namespace xtr::view { + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +IMPLEMENT_DYNCREATE(OSSView, CScrollView) + +BEGIN_MESSAGE_MAP(OSSView, CScrollView) + ON_WM_LBUTTONUP() + ON_WM_RBUTTONUP() + ON_WM_MOUSEMOVE() + ON_WM_LBUTTONDBLCLK() + ON_WM_MOUSEHOVER() + ON_WM_CONTEXTMENU() + ON_WM_MOUSEWHEEL() + ON_WM_SETCURSOR() + ON_WM_SETFOCUS() + + XTR_COMMAND(IXTRC_XTR_HELP) + + XTR_COMMAND_UPD(IXTRC_BACKUP) + XTR_COMMAND_UPD(IXTRC_EXPORT_OSS) + XTR_COMMAND_UPD(IXTRC_SAVE_IMAGE) + XTR_COMMAND_UPD(IXTRC_OSS_ADD) + XTR_COMMAND_UPD(IXTRC_OSS_DEL) + XTR_COMMAND_UPD(IXTRC_OSS_ASSIGN_DOC) + XTR_COMMAND_UPD(IXTRC_OSS_EDIT_DOC) + XTR_COMMAND_UPD(IXTRC_OSS_DISCARD_DOC) + XTR_COMMAND_UPD(IXTRC_EDIT_HLINK) + XTR_COMMAND_UPD(IXTRC_FOLLOW_HLINK) + XTR_COMMAND_UPD(IXTRC_OSS_OP_NEW) + XTR_COMMAND_UPD(IXTRC_OSS_OP_EDIT) + XTR_COMMAND_UPD(IXTRC_OSS_OP_RUN_SINGLE) + XTR_COMMAND_UPD(IXTRC_OSS_OP_RUN_ALL) + XTR_COMMAND_UPD(IXTRC_OSS_OP_CHECK) + XTR_COMMAND_UPD(IXTRC_OSS_ENABLE_GRID) + XTR_COMMAND_UPD(IXTRC_OSS_ENABLE_LEGEND) + XTR_COMMAND_UPD(IXTRC_OSS_ZOOM_IN) + XTR_COMMAND_UPD(IXTRC_OSS_ZOOM_OUT) + XTR_COMMAND_UPD(IXTRC_OSS_SHIFT_LEFT) + XTR_COMMAND_UPD(IXTRC_OSS_SHIFT_RIGHT) + END_MESSAGE_MAP() + +#pragma warning( pop ) + +void OSSView::OnInitialUpdate() { + CScrollView::OnInitialUpdate(); + + document = dynamic_cast(m_pDocument); + oss = &document->OSS(); + + SetFont(&XTROptions::App().fontText); + + layout = std::make_unique(*oss); + layout->InitImageList(); + + UpdateScrollSize(); + ShowScrollBar(SB_BOTH); + + InitCursor(); + InitTooltips(); +} + +void OSSView::InitCursor() { + cursorMarkOperation = ::AfxGetApp()->LoadCursorW(IXTRR_CREATE_OPERATION); + cursorHyperlink = ::AfxGetApp()->LoadCursorW(IXTRR_HYPERLINK); + if (cursorMarkOperation == nullptr || cursorHyperlink == nullptr) { + TRACE(L"Cannot load cursor"); + } +} + +void OSSView::InitTooltips() { + static constexpr auto TOOLTIP_DELAY_DEFAULT = 1000; + + if (!tooltips.Create(this, WS_POPUP)) { + TRACE(L"Unable to create the ToolTip!"); + } else { + tooltips.SetMaxTipWidth(ui::s_TooltipWidth); + tooltips.AddTool(this, CString{}); + tooltips.SetFont(&XTROptions::App().fontTooltip); + tooltips.SetDelayTime(TOOLTIP_DELAY_DEFAULT); + } +} + +void OSSView::DoDataExchange(CDataExchange* pDX){ + CScrollView::DoDataExchange(pDX); + if (!pDX->m_bSaveAndValidate) { + UpdateScrollSize(); + ScrollToSelected(); + } +} + +BOOL OSSView::PreTranslateMessage(MSG* pMsg) { + if (tooltips.m_hWnd != nullptr) { + tooltips.RelayEvent(pMsg); + } + return CScrollView::PreTranslateMessage(pMsg); +} + +BOOL OSSView::OnScrollBy(CSize sizeScroll, BOOL bDoScroll) { + if (!CScrollView::OnScrollBy(sizeScroll, bDoScroll)) { + return FALSE; + } else { + if (bDoScroll) { + UpdateWindow(); + } + return TRUE; + } +} + +BOOL OSSView::OnMouseWheel(uint32_t fFlags, short zDelta, CPoint /*point*/) { + if (fFlags & MK_CONTROL) { // Если зажат контрол - зумим + const auto doUpdate = + (zDelta > 0 && layout->zoom > ossOptions::zoomMin) || + (zDelta < 0 && layout->zoom < ossOptions::zoomMax); + if (zDelta > 0 && layout->zoom > ossOptions::zoomMin) { + --layout->zoom; + } + if (zDelta < 0 && layout->zoom < ossOptions::zoomMax) { + ++layout->zoom; + } + if (doUpdate) { + Invalidate(); + UpdateWindow(); + } + return doUpdate; + } else { + BOOL bHasVertBar{}; + BOOL bHasHorzBar{}; + CheckScrollBars(bHasHorzBar, bHasVertBar); + if (!bHasVertBar && !bHasHorzBar) { + return FALSE; + } else { + auto bResult = FALSE; + auto uWheelScrollLines = 3; + ::SystemParametersInfoW(SPI_GETWHEELSCROLLLINES, 0, &uWheelScrollLines, 0); + + const auto nToScroll = ::MulDiv(-zDelta, uWheelScrollLines, WHEEL_DELTA); + + auto nDisplacement = 0; + if (bHasVertBar && !(fFlags & MK_SHIFT)) { + if (uWheelScrollLines == WHEEL_PAGESCROLL) { + nDisplacement = m_pageDev.cy; + if (zDelta > 0) { + nDisplacement = -nDisplacement; + } + } else { + nDisplacement = nToScroll * m_lineDev.cy; + nDisplacement = std::min(static_cast(nDisplacement), m_pageDev.cy); + } + bResult = OnScrollBy(CSize(0, nDisplacement), TRUE); + } else if (bHasHorzBar) { + if (uWheelScrollLines == WHEEL_PAGESCROLL) { + nDisplacement = m_pageDev.cx; + if (zDelta > 0) { + nDisplacement = -nDisplacement; + } + } else { + nDisplacement = nToScroll * m_lineDev.cx; + nDisplacement = std::min(static_cast(nDisplacement), m_pageDev.cx); + } + bResult = OnScrollBy(CSize(nDisplacement, 0), TRUE); + } + if (bResult) { + UpdateWindow(); + } + return bResult; + } + } +} + +BOOL OSSView::OnSetCursor(CWnd* /*pWnd*/, uint32_t /*nHitTest*/, uint32_t /*message*/) { // NOLINT(readability-convert-member-functions-to-static) + return FALSE; +} + +void OSSView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { + CScrollView::OnUpdate(pSender, lHint, pHint); + if (oss != nullptr && pSender != this) { + UpdateData(FALSE); + } +} + +void OSSView::OnLButtonUp(uint32_t nFlags, CPoint point) { + CScrollView::OnLButtonUp(nFlags, point); + + ClientToDoc(point); + const auto* currentSelection = (*oss)(document->selection); + if (const auto* newSelection = layout->PictFromPoint(point); newSelection != nullptr) { + if (newOperationMode) { + if (currentSelection != newSelection) { + newSelection = oss->InsertOperation(currentSelection->uid, newSelection->uid); + } else { + ::AfxMessageBox(IXTRE_UNARY_OP, MB_ICONEXCLAMATION); + } + assert(newSelection != nullptr); + newOperationMode = FALSE; + UpdateCursor(newSelection); + } + document->selection = newSelection->uid; + document->UpdateAllViews(nullptr); + } +} + +void OSSView::OnRButtonUp(uint32_t nFlags, CPoint point) { + if (newOperationMode) { + newOperationMode = FALSE; + UpdateCursor(); + } else { + ClientToDoc(point); + const auto* const pict = layout->PictFromPoint(point); + if (pict != nullptr) { + document->selection = pict->uid; + document->UpdateAllViews(nullptr); + } + UpdateCursor(pict); + } + CScrollView::OnRButtonUp(nFlags, point); +} + +void OSSView::OnMouseMove(uint32_t nFlags, CPoint point) { + CScrollView::OnMouseMove(nFlags, point); + + ClientToDoc(point); + const auto* const pict = layout->PictFromPoint(point); + UpdateCursor(pict); + if (pict == nullptr) { + pictUnderCursor = std::nullopt; + tooltips.ShowWindow(FALSE); + } else if (pictUnderCursor.has_value()) { + tooltips.Popup(); + tooltips.Update(); + } else { + StartHoverTimer(); + } +} + +void OSSView::StartHoverTimer() noexcept { + static constexpr auto TOOLTIP_DEALY = 500; + TRACKMOUSEEVENT csTME{}; + csTME.cbSize = sizeof(csTME); + csTME.dwFlags = TME_HOVER; + csTME.hwndTrack = m_hWnd; + csTME.dwHoverTime = TOOLTIP_DEALY; + ::TrackMouseEvent(&csTME); +} + +void OSSView::OnMouseHover(uint32_t /*nFlags*/, CPoint point) { + ClientToDoc(point); + if (const auto* const pict = layout->PictFromPoint(point); pict != nullptr) { + if (pictUnderCursor.has_value() && pictUnderCursor.value() == pict->uid) { + tooltips.Popup(); + } else { + pictUnderCursor = pict->uid; + auto text = mfc::ToMFC(pict->title); + if (text.IsEmpty()) { + text = mfc::LoadSID(IXTRS_PICT_NONAME); + } + + text += "\n\n"; + text += info::BasicDescriptionOf(pict->uid, document->OSS()); + + tooltips.UpdateTipText(text, this); + tooltips.Update(); + tooltips.ShowWindow(TRUE); + tooltips.Popup(); + } + } +} + +void OSSView::OnSetFocus(CWnd* pOldWnd) { + CScrollView::OnSetFocus(pOldWnd); + RedrawWindow(); +} + +void OSSView::OnLButtonDblClk(uint32_t nFlags, CPoint point) { + ClientToDoc(point); + if (const auto* const pict = layout->PictFromPoint(point); pict != nullptr) { + auto const pid = pict->uid; + document->selection = pid; + document->UpdateAllViews(nullptr); + proc::DoAction(*document); + } + CScrollView::OnLButtonDblClk(nFlags, point); +} + +void OSSView::OnContextMenu(CWnd* /*pWnd*/, CPoint point) { + auto clinePt = point; + ScreenToClient(&clinePt); + ClientToDoc(clinePt); + + if (const auto* pict = layout->PictFromPoint(clinePt); pict != nullptr) { + CMenu popup{}; + popup.LoadMenuW(IXTRAD_OSS_POPUP); + auto *item0 = popup.GetSubMenu(0); + for (auto i = 0; i < item0->GetMenuItemCount(); ++i) { + if (const auto command = item0->GetMenuItemID(i); command != 0) { + if (command == IXTRC_FOLLOW_HLINK) { + auto msg = mfc::LoadSID(IXTRS_FOLLOW_HYPERLINK); + if (!std::empty(pict->lnk)) { + msg += LR"(: )"; + msg += mfc::ToMFC(pict->lnk.address); + } + item0->ModifyMenuW(command, MF_BYCOMMAND | MF_STRING | MF_POPUP, command, msg); + } + + if (!IsCommandActive(command)) { + item0->EnableMenuItem(command, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } else { + item0->EnableMenuItem(command, MF_BYCOMMAND | MF_ENABLED); + } + } + } + item0->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); + } +} + +void OSSView::OnUpdateCommandUI(CCmdUI* pCmdUI) { + pCmdUI->Enable(IsCommandActive(pCmdUI->m_nID)); + + if (pCmdUI->m_nID == IXTRC_OSS_OP_NEW) { + pCmdUI->SetCheck(newOperationMode); + } else if (pCmdUI->m_nID == IXTRC_OSS_ENABLE_GRID) { + pCmdUI->SetCheck(XTROptions::OSS().showGrid); + } else if (pCmdUI->m_nID == IXTRC_OSS_ENABLE_LEGEND) { + pCmdUI->SetCheck(XTROptions::OSS().showLegend); + } +} + +BOOL OSSView::IsCommandActive(const uint32_t command) const { + switch (command) { + default: break; + case IXTRC_BACKUP: + case IXTRC_SAVE_IMAGE: + case IXTRC_EXPORT_OSS: + case IXTRC_OSS_OP_NEW: + case IXTRC_OSS_OP_RUN_ALL: + case IXTRC_EDIT_HLINK: + case IXTRC_OSS_ENABLE_GRID: + case IXTRC_OSS_ENABLE_LEGEND: + case IXTRC_OSS_SHIFT_RIGHT: + return TRUE; + } + + const auto* operation = oss->Ops()(document->selection); + switch (command) { + default: return FALSE; + case IXTRC_OSS_ADD: + case IXTRC_OSS_DEL: return !newOperationMode; + + case IXTRC_OSS_ASSIGN_DOC: return operation == nullptr; + case IXTRC_OSS_DISCARD_DOC: + return !std::empty(*oss->Src()(document->selection)); + case IXTRC_OSS_EDIT_DOC: + return operation == nullptr || !std::empty(*oss->Src()(document->selection)); + + case IXTRC_OSS_OP_EDIT: + case IXTRC_OSS_OP_CHECK: return operation != nullptr; + + case IXTRC_OSS_OP_RUN_SINGLE: + return operation != nullptr && + operation->type != ccl::ops::Type::tba && + !operation->broken; + + case IXTRC_FOLLOW_HLINK: return !std::empty((*oss)(document->selection)->lnk); + + case IXTRC_OSS_ZOOM_IN: return layout->zoom > ossOptions::zoomMin; + case IXTRC_OSS_ZOOM_OUT: return layout->zoom < ossOptions::zoomMax; + case IXTRC_OSS_SHIFT_LEFT: return oss->Grid()(document->selection)->column > 0; + } +} + +BOOL OSSView::OnCommandRun(const uint32_t command) { + if (!IsCommandActive(command)) { + return TRUE; + } else { + if (command != IXTRC_OSS_OP_NEW) { + newOperationMode = FALSE; + } + auto needUpdate = TRUE; + const auto pid = document->selection; + switch (command) { + case IXTRC_XTR_HELP: ui::HelpHandler::RunHelp(ui::HelpID::viewRSOSS); return TRUE; + + case IXTRC_BACKUP: proc::BackupOSS(*document); return TRUE; + case IXTRC_SAVE_IMAGE: proc::ExportOSSGraph(*document, *layout); return TRUE; + case IXTRC_EXPORT_OSS: proc::ExportOSS(*document); return TRUE; + + case IXTRC_OSS_ADD: document->selection = oss->InsertBase()->uid; break; + case IXTRC_OSS_DEL: proc::EraseSelected(*document); return TRUE; + + case IXTRC_OSS_ASSIGN_DOC: proc::AttachSourceToSelected(*document); return TRUE; + case IXTRC_OSS_DISCARD_DOC: proc::DiscardSelectedSource(*document); return TRUE; + case IXTRC_OSS_EDIT_DOC: proc::OpenSelectedSource(*document); return TRUE; + + case IXTRC_OSS_OP_NEW: newOperationMode = !newOperationMode; break; + case IXTRC_OSS_OP_EDIT: proc::EditSelectedOperation(*document); return TRUE; + case IXTRC_OSS_OP_CHECK: { + ::AfxMessageBox(info::DescriptionOf(oss->Ops(), pid), MB_ICONINFORMATION); + return TRUE; + } + case IXTRC_OSS_OP_RUN_SINGLE: proc::RunSelectedOperation(*document); return TRUE; + case IXTRC_OSS_OP_RUN_ALL: proc::RerunAllOperations(*document); return TRUE; + + case IXTRC_EDIT_HLINK: proc::EditSelectedHyperlink(*document); return TRUE; + case IXTRC_FOLLOW_HLINK: { + const auto& link = (*oss)(document->selection)->lnk; + proc::FollowHyperlink(mfc::ToMFC(link.address), mfc::ToMFC(link.subAddr)); + return TRUE; + } + + case IXTRC_OSS_ENABLE_GRID: XTROptions::OSS().showGrid = !XTROptions::OSS().showGrid; break; + case IXTRC_OSS_ENABLE_LEGEND: XTROptions::OSS().showLegend = !XTROptions::OSS().showLegend; break; + case IXTRC_OSS_ZOOM_IN: --layout->zoom; break; + case IXTRC_OSS_ZOOM_OUT: ++layout->zoom; break; + case IXTRC_OSS_SHIFT_LEFT: needUpdate = oss->Grid().ShiftPict(pid, -1); break; + case IXTRC_OSS_SHIFT_RIGHT: needUpdate = oss->Grid().ShiftPict(pid, 1); break; + } + if (needUpdate) { + document->UpdateAllViews(nullptr); + } + return TRUE; + } +} + +void OSSView::UpdateCursor(ccl::oss::PictPtr pict) const { + if (newOperationMode) { + ::SetCursor(cursorMarkOperation); + } else if (pict != nullptr && !std::empty(pict->lnk)) { + ::SetCursor(cursorHyperlink); + } else { + ::SetCursor(::AfxGetApp()->LoadStandardCursor(IDC_ARROW)); + } +} + +void OSSView::ScrollToSelected() { + const auto pos = oss->Grid()(document->selection); + assert(pos.has_value()); + + // Check if scrolling is needed + auto rect = layout->PictRect(document->selection, 1 / layout->zoom); + DocToClient(rect); + auto visibleRect = ui::WindowRect(*this); + ScreenToClient(visibleRect); + + if (!visibleRect.PtInRect(rect.TopLeft()) + || !visibleRect.PtInRect(rect.BottomRight())) { + + auto row = pos->row; + if (row > 1) { + --row; + } + const auto visionWidth = visibleRect.Width(); + const auto visionHeight = visibleRect.Height(); + const auto clientSize = GetTotalSize(); + const auto cellRect = layout->CellRect(pos.value(), 1 / layout->zoom); + + // Prevent cursor from leaving bounds + POINT pt{}; + pt.x = clientSize.cx >= cellRect.left + visionWidth ? cellRect.left : clientSize.cx - visionWidth; + pt.y = clientSize.cy >= cellRect.top + visionHeight ? cellRect.top : clientSize.cy - visionHeight; + if (pt.x < 0) { + pt.x = 0; + } + if (pt.y < 0) { + pt.y = 0; + } + ScrollToPosition(pt); + } +} + +void OSSView::UpdateScrollSize() { + CSize sizeTotal{}; + sizeTotal.cx = layout->GetClientWidth(); + sizeTotal.cy = layout->GetClientHeight(); + SetScrollSizes(MM_TEXT, sizeTotal); +} + +void OSSView::ClientToDoc(CPoint& point) { + CClientDC dc{ this }; + OnPrepareDC(&dc, nullptr); + dc.DPtoLP(&point); +} + +void OSSView::ClientToDoc(CRect& rect) { + CClientDC dc{ this }; + OnPrepareDC(&dc, nullptr); + dc.DPtoLP(rect); + assert(rect.left <= rect.right); + assert(rect.bottom <= rect.top); +} + +void OSSView::DocToClient(CPoint& point) { + CClientDC dc{ this }; + OnPrepareDC(&dc, nullptr); + dc.LPtoDP(&point); +} + +void OSSView::DocToClient(CRect& rect) { + CClientDC dc{ this }; + OnPrepareDC(&dc, nullptr); + dc.LPtoDP(rect); + rect.NormalizeRect(); +} + +void OSSView::OnDraw(CDC* pDC) { + if (layout != nullptr) { + layout->Draw(pDC, document->selection); + } +} + +} // namespace xtr::view \ No newline at end of file diff --git a/src/view/PictView.cpp b/src/view/PictView.cpp new file mode 100644 index 0000000..5d0030e --- /dev/null +++ b/src/view/PictView.cpp @@ -0,0 +1,267 @@ +#include "stdafx.h" + +#include "xtr/view/PictView.h" + +#include "resource.h" + +#include "xtr/cclDescriptor.h" +#include "xtr/xtrProcedures.h" +#include "xtr/ExteorOptions.h" + +#include "xtr/ui/HelpHandler.h" +#include "xtr/ui/UIHelper.h" + +namespace xtr::view { + +using ccl::semantic::RSForm; +using ccl::ops::EquationOptions; +using ccl::oss::PictID; + +struct PictView::TableHeader : ui::Header { + enum Columns : uint8_t { + COL_NUMBER = 0, + COL_1_NAME, + COL_1_TERM, + COL_2_NAME, + COL_2_TERM, + count + }; + + static constexpr auto widthNumber = 30; + static constexpr auto widthName = 40; + static constexpr auto widthTerm = 105; + + TableHeader() { + AddColumn({ IXTRS_HEADER_NO, Alignment::center, widthNumber }); + AddColumn({ IXTRS_HEADER_NAME, Alignment::center, widthName }); + AddColumn({ IXTRS_HEADER_TERM, Alignment::center, widthTerm }); + AddColumn({ IXTRS_HEADER_NAME, Alignment::center, widthName }); + AddColumn({ IXTRS_HEADER_TERM, Alignment::center, widthTerm }); + } +}; + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +IMPLEMENT_DYNCREATE(PictView, CFormView) + +BEGIN_MESSAGE_MAP(PictView, CFormView) + ON_COMMAND(IXTRC_XTR_HELP, &ThisClass::OpenHelp) + + ON_EN_CHANGE(IXTRC_TITLE, &ThisClass::OnChange) + ON_EN_CHANGE(IXTRC_ALIAS, &ThisClass::OnChange) + ON_EN_CHANGE(IXTRC_COMMENT, &ThisClass::OnChange) + ON_EN_CHANGE(IXTRC_VIEW_OSS_NAME, &ThisClass::OnChange) + + ON_BN_CLICKED(IXTRC_OSS_COMMENT, &ThisClass::OnOSSComment) + ON_BN_CLICKED(IXTRC_PICT_LINK, &ThisClass::OnPictLink) + ON_BN_CLICKED(IXTRC_OSS_FILE, &ThisClass::OnOSSFileName) + ON_BN_CLICKED(IXTRC_FILE_NAME, &ThisClass::OnPictFileName) + ON_BN_CLICKED(IXTRC_OPEN_FOLDER, &ThisClass::OnOpenOSSFolder) + ON_BN_CLICKED(IXTRC_BACKUP, &ThisClass::OnBackup) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +PictView::PictView() + : CFormView(IXTRD_VIEW_PICT) {} + +doc::OSSDoc& PictView::Document() noexcept { + return dynamic_cast(*m_pDocument); +} + +void PictView::OnInitialUpdate() { + oss = &Document().OSS(); + + CFormView::OnInitialUpdate(); + + InitMapCtrl(); + InitCommentCtrl(); +} + +void PictView::InitMapCtrl() { + static const TableHeader head{}; + optionsCtrl.SetExtendedStyle(optionsCtrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); + ui::InitHeaderFor(optionsCtrl, head); +} + +void PictView::InitCommentCtrl() { + commentCtrl.SetAutoURLDetect(); + commentCtrl.SetWindowTextW(CString{}); + commentCtrl.SetWindowTextW(comment); + commentCtrl.InitRE(ui::Keyboard::Layout::RUS); + commentCtrl.SetFont(&XTROptions::App().fontData); +} + +void PictView::DoDataExchange(CDataExchange* pDX) { + CFormView::DoDataExchange(pDX); + + ::DDX_Control(pDX, IXTRC_STATUS, opStatusCtrl); + ::DDX_Control(pDX, IXTRC_OPERATION, operationCtrl); + ::DDX_Control(pDX, IXTRC_ALIAS, fullNameCtrl); + ::DDX_Control(pDX, IXTRC_TITLE, shortNameCtrl); + ::DDX_Control(pDX, IXTRC_COMMENT, commentCtrl); + ::DDX_Control(pDX, IXTRC_VIEW_OSS_NAME, ossNameCtrl); + ::DDX_Control(pDX, IXTRC_OTOGDESWLENYA, optionsCtrl); + ::DDX_Control(pDX, IXTRC_FILE_NAME, changeFileBtn); + + if (!pDX->m_bSaveAndValidate) { + LoadData(); + } + ::DDX_Text(pDX, IXTRC_ALIAS, pictAlias); + ::DDX_Text(pDX, IXTRC_TITLE, pictTitle); + ::DDX_Text(pDX, IXTRC_COMMENT, comment); + ::DDX_Text(pDX, IXTRC_OPERAND1, operand1); + ::DDX_Text(pDX, IXTRC_OPERAND2, operand2); + ::DDX_Text(pDX, IXTRC_VIEW_OSS_NAME, ossTitle); + ::DDX_Text(pDX, IXTRC_STATUS, status); + ::DDX_Text(pDX, IXTRC_OPERATION, opType); + ::DDX_Text(pDX, IXTRC_SRC_TYPE, dataType); + + if (pDX->m_bSaveAndValidate) { + SaveData(); + } else { + UpdateUI(); + } +} + +void PictView::LoadData() { + const auto& pict = *(*oss)(Document().selection); + + pictAlias = mfc::ToMFC(pict.alias); + pictTitle = mfc::ToMFC(pict.title); + ossTitle = mfc::ToMFC(oss->title); + comment = mfc::ToMFC(pict.comment); + + dataType = info::Label(oss->Src()(Document().selection)->desc.type); + + LoadOperation(); +} + +void PictView::LoadOperation() { + const auto selectedPict = Document().selection; + if (const auto* operation = oss->Ops()(selectedPict); operation != nullptr) { + status = info::Label(oss->Ops().StatusOf(selectedPict)); + opType = info::Label(operation->type); + + const auto parents = oss->Graph().ParentsOf(selectedPict); + if (ssize(parents) == 2) { + operand1 = mfc::ToMFC((*oss)(parents.at(0))->title); + operand2 = mfc::ToMFC((*oss)(parents.at(1))->title); + } else { + operand1.Empty(); + operand2.Empty(); + } + } else { + status = mfc::LoadSID(IXTRS_PICT_BASIC); + opType.Empty(); + } +} + +void PictView::SaveData() { + auto& doc = Document(); + const auto selectedPict = doc.selection; + oss->SetPictAlias(selectedPict, mfc::ToSTL(pictAlias)); + oss->SetPictTitle(selectedPict, mfc::ToSTL(pictTitle)); + oss->SetPictComment(selectedPict, mfc::ToSTL(comment)); + oss->title = mfc::ToSTL(ossTitle); + doc.UpdateAllViews(this); +} + +void PictView::UpdateUI() { + const auto* src = dynamic_cast(oss->Src()(Document().selection)->src); + const auto hasOpenedDoc = src != nullptr && src->GetFirstViewPosition() != nullptr; + + fullNameCtrl.EnableWindow(!hasOpenedDoc); + shortNameCtrl.EnableWindow(!hasOpenedDoc); + commentCtrl.EnableWindow(!hasOpenedDoc); + changeFileBtn.EnableWindow(!hasOpenedDoc && !std::empty(*oss->Src()(Document().selection))); + + UpdateMapCtrl(Document().selection); +} + +void PictView::UpdateMapCtrl(const PictID pid) { + static const CString errorStr{ L"TBA" }; + + optionsCtrl.DeleteAllItems(); + if (const auto* handle = oss->Ops()(pid); handle == nullptr || handle->options == nullptr) { + return; + } else if (const auto* equations = dynamic_cast(handle->options.get()); equations == nullptr) { + return; + } else if (const auto parents = oss->Graph().ParentsOf(pid); std::empty(parents)) { + return; + } else { + assert(ssize(parents) == 2); + const auto* schema1 = ccl::src::CastData(oss->Src().DataFor(parents.at(0))); + const auto* schema2 = ccl::src::CastData(oss->Src().DataFor(parents.at(1))); + for (const auto& [key, value] : *equations) { +#pragma warning( push ) +#pragma warning( disable : 6387 ) + const auto item = optionsCtrl.InsertItem(LVIF_TEXT | LVIF_STATE, optionsCtrl.GetItemCount(), {}, 0, 0, 0, 0); +#pragma warning( pop ) + + CString number{}; + number.AppendFormat(LR"(%d)", item + 1); + optionsCtrl.SetItemText(item, TableHeader::COL_NUMBER, number); + if (schema1 != nullptr && schema1->Contains(key)) { + const auto& cst1 = schema1->GetText(key); + optionsCtrl.SetItemText(item, TableHeader::COL_1_NAME, mfc::ToMFC(cst1.alias)); + optionsCtrl.SetItemText(item, TableHeader::COL_1_TERM, mfc::ToMFC(cst1.term.Nominal())); + } else { + optionsCtrl.SetItemText(item, TableHeader::COL_1_NAME, errorStr); + optionsCtrl.SetItemText(item, TableHeader::COL_1_TERM, errorStr); + } + if (schema2 != nullptr && schema2->Contains(value)) { + const auto& cst2 = schema2->GetText(value); + optionsCtrl.SetItemText(item, TableHeader::COL_2_NAME, mfc::ToMFC(cst2.alias)); + optionsCtrl.SetItemText(item, TableHeader::COL_2_TERM, mfc::ToMFC(cst2.term.Nominal())); + } else { + optionsCtrl.SetItemText(item, TableHeader::COL_2_NAME, errorStr); + optionsCtrl.SetItemText(item, TableHeader::COL_2_TERM, errorStr); + } + } + } +} + +void PictView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { + CScrollView::OnUpdate(pSender, lHint, pHint); + if (oss != nullptr && pSender != this) { + UpdateData(FALSE); + } +} + +void PictView::OnChange() { // NOLINT(readability-convert-member-functions-to-static) + UpdateData(TRUE); +} + +void PictView::OpenHelp() { // NOLINT(readability-convert-member-functions-to-static) + ui::HelpHandler::RunHelp(ui::HelpID::viewRSOSS); +} + +void PictView::OnOSSComment() { // NOLINT(readability-convert-member-functions-to-static) + proc::EditComment(Document()); +} + +void PictView::OnPictLink() { // NOLINT(readability-convert-member-functions-to-static) + proc::EditSelectedHyperlink(Document()); +} + +void PictView::OnOSSFileName() { // NOLINT(readability-convert-member-functions-to-static) + proc::EditOSSFilename(Document()); +} + +void PictView::OnPictFileName() { // NOLINT(readability-convert-member-functions-to-static) + proc::EditActiveFilename(Document()); +} + +void PictView::OnOpenOSSFolder() { // NOLINT(readability-convert-member-functions-to-static) + ::ShellExecuteW(nullptr, L"open", + mfc::ToMFC(Document().OSS().Src().ossDomain), + nullptr, nullptr, SW_SHOW); +} + +void PictView::OnBackup() { // NOLINT(readability-convert-member-functions-to-static) + proc::BackupOSS(Document()); +} + +} // namespace xtr::view \ No newline at end of file diff --git a/src/view/RSFormView.cpp b/src/view/RSFormView.cpp new file mode 100644 index 0000000..007feea --- /dev/null +++ b/src/view/RSFormView.cpp @@ -0,0 +1,428 @@ +#include "stdafx.h" + +#include "xtr/view/RSFormView.h" + +#include "resource.h" + +#include "xtr/Exteor.h" +#include "xtr/cclDescriptor.h" +#include "xtr/xtrDesign.h" +#include "xtr/xtrProcedures.h" +#include "xtr/doc/RSModelDoc.h" + +#include "xtr/ui/HelpHandler.h" +#include "xtr/ui/KeyboardHandler.h" +#include "xtr/ui/UIHelper.h" + +#include "ccl/semantic/CstFilters.hpp" + +namespace xtr::view { + +using ccl::semantic::CstType; +using ui::Keyboard; + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +IMPLEMENT_DYNCREATE(RSFormView, CFormView) + +BEGIN_MESSAGE_MAP(RSFormView, CFormView) + ON_WM_CONTEXTMENU() + + ON_COMMAND(IXTRC_XTR_HELP, &ThisClass::OpenHelp) + ON_BN_CLICKED(IXTRC_TRS_SEARCH, &ThisClass::OnSearch) + ON_BN_CLICKED(IXTRC_COMMENT_B, &ThisClass::OnEditComment) + ON_BN_CLICKED(IXTRC_TRS_UPDATE_STATUS, &ThisClass::OnUpdateStatus) + + ON_COMMAND_EX(ID_EDIT_COPY, &ThisClass::OnCopy) + ON_COMMAND_EX(ID_EDIT_PASTE, &ThisClass::OnPaste) + ON_EN_CHANGE(IXTRC_ALIAS, &ThisClass::OnChange) + ON_EN_CHANGE(IXTRC_TITLE, &ThisClass::OnChange) + + XTR_COMMAND_UPD(IXTRC_MOVE_UP) + XTR_COMMAND_UPD(IXTRC_MOVE_DOWN) + XTR_COMMAND_UPD(IXTRC_SELECT_BASIS) + XTR_COMMAND_UPD(IXTRC_SELECT_DEPENDENT) + XTR_COMMAND_UPD(IXTRC_DELETE_CST) + XTR_COMMAND_UPD(IXTRC_RENAME) + XTR_COMMAND_UPD(IXTRC_TERM_TO_FUNC) + XTR_COMMAND_UPD(IXTRC_FUNC_TO_TERM) + XTR_COMMAND_UPD(IXTRC_STRUCTURE_TO_TERMS) + XTR_COMMAND_UPD(IXTRC_RESET_NAMES) + XTR_COMMAND_UPD(IXTRC_RESET_OSSFLAG) + XTR_COMMAND_UPD(IXTRC_RESET_COLUMNS) + + ON_COMMAND_EX(IXTRC_INSERT_BASE_SET, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_CONST_SET, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_RS, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_AXIOM, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_TERM, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_THEOREMA, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_FUNCTION, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_PREDICATE, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_FREE, &ThisClass::OnInsertCst) + + ON_COMMAND(IXTRC_OP_MAX_PART, &ThisClass::OnOpMaxPart) + ON_COMMAND(IXTRC_OP_SELECT_BASIS, &ThisClass::OnOpExtractBasis) + ON_COMMAND_EX(IXTRC_CONVERT_TO_RSFORM, &ThisClass::OnOperation) + ON_COMMAND_EX(IXTRC_EXPORT_SCHEMA, &ThisClass::OnOperation) + ON_COMMAND_EX(IXTRC_EXPORT_GRAPH, &ThisClass::OnOperation) + ON_COMMAND_EX(IXTRC_SYNTHES, &ThisClass::OnOperation) + ON_COMMAND_EX(IXTRC_OP_MERGE, &ThisClass::OnOperation) + ON_COMMAND_EX(IXTRC_RELATION, &ThisClass::OnOperation) + ON_COMMAND_EX(IXTRC_CST_MERGING, &ThisClass::OnOperation) + ON_COMMAND_EX(IXTRC_RESET_COLUMNS, &ThisClass::OnOperation) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +RSFormView::RSFormView() + : CFormView(IXTRD_VIEW_RSFORM) {} + +void RSFormView::OnInitialUpdate() { + editor = doc::RSFacade{ dynamic_cast(*m_pDocument) }; + schema = &editor.EditSchema(); + + CFormView::OnInitialUpdate(); + + InitControls(); + InitTooltips(); +} + +void RSFormView::InitControls() { + titleCtrl.InitRE(Keyboard::Layout::RUS); + titleCtrl.SetFont(&XTROptions::App().fontMath); + + aliasCtrl.InitRE(Keyboard::Layout::RUS); + aliasCtrl.SetFont(&XTROptions::App().fontMath); + + searchCtrl.InitRE(Keyboard::Layout::RUS); + searchCtrl.SetFont(&XTROptions::App().fontMath); + + cstTable.SetFont(&XTROptions::App().fontMath); + cstTable.Init(editor); + + rsformStatusCtrl.SetFont(&XTROptions::App().fontMath); +} + +void RSFormView::InitTooltips() { + if (!tooltips.Create(this)) { + TRACE(L"Unable to create the ToolTip!"); + } else { + tooltips.SetMaxTipWidth(ui::s_TooltipWidth); + tooltips.SetFont(&XTROptions::App().fontTooltip); + tooltips.Activate(TRUE); + + tooltips.AddTool(&rsformStatusCtrl); + } +} + +void RSFormView::DoDataExchange(CDataExchange* pDX) { + CFormView::DoDataExchange(pDX); + + ::DDX_Control(pDX, IXTRC_TITLE, titleCtrl); + ::DDX_Control(pDX, IXTRC_ALIAS, aliasCtrl); + ::DDX_Control(pDX, IXTRC_RSFORM_SEARCH, searchCtrl); + ::DDX_Control(pDX, IXTRC_RSFORM_LIST, cstTable); + ::DDX_Control(pDX, IXTRC_RSFORM_STATUS, rsformStatusCtrl); + + if (!pDX->m_bSaveAndValidate) { + title = mfc::ToMFC(schema->title); + alias = mfc::ToMFC(schema->alias); + if (cstTable.IsInit()) { + cstTable.Update(TRUE); + } + } + + ::DDX_Text(pDX, IXTRC_ALIAS, alias); + ::DDX_Text(pDX, IXTRC_TITLE, title); + + if (pDX->m_bSaveAndValidate) { + schema->title = mfc::ToSTL(title); + schema->alias = mfc::ToSTL(alias); + editor.Document().SetSelection(cstTable.Selection()); + editor.Document().UpdateAllViews(this); + } + UpdateStatusBar(); +} + +BOOL RSFormView::PreTranslateMessage(MSG* pMsg) { + if (tooltips.m_hWnd != nullptr) { + tooltips.RelayEvent(pMsg); + } + if (pMsg->message == WM_KEYDOWN) { + if (pMsg->hwnd == cstTable.GetSafeHwnd() && pMsg->wParam == VK_DELETE) { + OnCommandRun(IXTRC_DELETE_CST); return TRUE; + } + if (pMsg->hwnd == searchCtrl.GetSafeHwnd() && pMsg->wParam == VK_RETURN) { + OnSearch(); + return TRUE; + } + } + return CFormView::PreTranslateMessage(pMsg); +} + +void RSFormView::OnSearch() { + if (const auto searchStr = mfc::ToSTL(searchCtrl.Text()); !std::empty(searchStr)) { + if (const auto foundItems = ccl::semantic::FilterCst(schema->Core(), searchStr); + !std::empty(foundItems)) { + cstTable.SelectMultiple({ std::begin(foundItems), std::end(foundItems) }); + cstTable.SetFocus(); + } else { + ::AfxMessageBox(IXTRS_SEARCH_NO_MATCH, MB_ICONINFORMATION); + } + } +} + +void RSFormView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { + CView::OnUpdate(pSender, lHint, pHint); + if (pSender != this) { + UpdateData(FALSE); + } +} + +BOOL RSFormView::OnCmdMsg(uint32_t nID, int32_t nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) { + if (GetFocus() == &cstTable && + cstTable.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)) { + return TRUE; + } else { + return CFormView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); + } +} + +void RSFormView::OnChange() { + UpdateData(); +} + +BOOL RSFormView::OnCopy(const uint32_t /*msgID*/) { // NOLINT(readability-convert-member-functions-to-static) + if (auto* active = dynamic_cast(GetFocus()); active != nullptr) { + active->Copy(); + } + return TRUE; +} + +BOOL RSFormView::OnPaste(const uint32_t /*msgID*/) { // NOLINT(readability-convert-member-functions-to-static) + if (auto* active = dynamic_cast(GetFocus()); active != nullptr) { + active->Paste(); + } + return TRUE; +} + +void RSFormView::OpenHelp() { // NOLINT(readability-convert-member-functions-to-static) + ui::HelpHandler::RunHelp(ui::HelpID::viewRSForm); +} + +void RSFormView::OnOpMaxPart() { + UpdateData(); + if (const auto res = ccl::ops::OpMaxPart(*schema, Selection()).Execute(); res != nullptr) { + ExteorApplication::Docs().NewRSFormDoc(*res); + } else { + ::AfxMessageBox(IXTRE_OP_APPLICABLE, MB_ICONEXCLAMATION); + } +} + +void RSFormView::OnOpExtractBasis() { + UpdateData(); + if (const auto res = ccl::ops::OpExtractBasis(*schema, Selection()).Execute(); res != nullptr) { + ExteorApplication::Docs().NewRSFormDoc(*res); + } else { + ::AfxMessageBox(IXTRE_OP_SELECT_BASIS, MB_ICONEXCLAMATION); + } +} + +void RSFormView::OnUpdateStatus() { + BeginWaitCursor(); + + schema->UpdateState(); + UpdateData(FALSE); + const auto message = info::DescriptionOf(schema->Core()); + + EndWaitCursor(); + + RedrawWindow(); + ::AfxMessageBox(message, MB_ICONINFORMATION); +} + +void RSFormView::OnEditComment() { + proc::EditComment(editor); +} + +void RSFormView::OnContextMenu(CWnd* pWnd, CPoint point) { + static constexpr auto separator = 0; + if (pWnd == &cstTable) { + CMenu popup{}; + popup.LoadMenuW(IXTRAD_RSVIEW_POPUP); + popup.DeleteMenu(IXTRC_CALCULATE, MF_BYCOMMAND); // Удаляем пункты, относящиеся к РС-модели + + auto *item0 = popup.GetSubMenu(0); + for (auto i = 0; i < item0->GetMenuItemCount(); ++i) { + if (const auto command = item0->GetMenuItemID(i); command != separator) { + if (!IsContextActive(command)) { + item0->EnableMenuItem(command, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } else { + item0->EnableMenuItem(command, MF_BYCOMMAND | MF_ENABLED); + } + } + } + item0->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); + } +} + +void RSFormView::OnUpdateCommandUI(CCmdUI* pCmdUI) { + pCmdUI->Enable(IsCommandActive(pCmdUI->m_nID)); +} + +BOOL RSFormView::IsCommandActive(uint32_t command) const { + const auto& selected = Selection(); + switch (command) { + case IXTRC_RESET_NAMES: + case IXTRC_RESET_OSSFLAG: + case IXTRC_RESET_COLUMNS: + default: + return TRUE; + + case IXTRC_MOVE_UP: + case IXTRC_MOVE_DOWN: + case IXTRC_SELECT_BASIS: + case IXTRC_SELECT_DEPENDENT: + return cstTable.IsCommandActive(command); + + case IXTRC_STRUCTURE_TO_TERMS: + case IXTRC_TERM_TO_FUNC: + case IXTRC_FUNC_TO_TERM: + case IXTRC_RENAME: return ssize(selected) == 1; + case IXTRC_DELETE_CST: { + for (const auto uid : selected) { + if (schema->Mods().IsTracking(uid)) { + return FALSE; + } + } + return !std::empty(selected); + } + } +} + +BOOL RSFormView::OnCommandRun(const uint32_t command) { + if (!IsCommandActive(command)) { + return TRUE; + } + + UpdateData(); + switch (command) { + case IXTRC_MOVE_UP: + case IXTRC_MOVE_DOWN: + case IXTRC_SELECT_BASIS: + case IXTRC_SELECT_DEPENDENT: + return cstTable.RunCommand(command); + + case IXTRC_RESET_NAMES: proc::ResetNames(editor); break; + case IXTRC_RESET_OSSFLAG: proc::ResetClaims(dynamic_cast(*m_pDocument)); break; + case IXTRC_RESET_COLUMNS: cstTable.ResetColumns(); break; + case IXTRC_RENAME: proc::RenameCst(editor); break; + case IXTRC_DELETE_CST: proc::EraseSelected(dynamic_cast(*m_pDocument)); break; + + case IXTRC_TERM_TO_FUNC: proc::Term2Function(editor); break; + case IXTRC_FUNC_TO_TERM: proc::Function2Term(editor); break; + case IXTRC_STRUCTURE_TO_TERMS: proc::Structure2Terms(editor); break; + } + return TRUE; +} + +BOOL RSFormView::OnInsertCst(const uint32_t command) { + const auto nWhere = cstTable.GetNextItem(mfc::noItems, LVNI_FOCUSED); + switch(command) { + case IXTRC_INSERT_BASE_SET: InsertNew(CstType::base); break; + case IXTRC_INSERT_CONST_SET: InsertNew(CstType::constant); break; + case IXTRC_INSERT_RS: InsertNew(CstType::structured, nWhere); break; + case IXTRC_INSERT_AXIOM: InsertNew(CstType::axiom, nWhere); break; + case IXTRC_INSERT_TERM: InsertNew(CstType::term, nWhere); break; + case IXTRC_INSERT_THEOREMA: InsertNew(CstType::theorem, nWhere); break; + case IXTRC_INSERT_FUNCTION: InsertNew(CstType::function, nWhere); break; + case IXTRC_INSERT_PREDICATE: InsertNew(CstType::predicate, nWhere); break; + case IXTRC_INSERT_FREE: InsertFree(); break; + } + return TRUE; +} + +void RSFormView::InsertNew(const CstType cstType, const int32_t nWhere) { + UpdateData(); + const auto idWhere = cstTable.UIDForIndex(nWhere); + const auto newUID = schema->Emplace(cstType); + if (idWhere.has_value()) { + schema->MoveBefore(newUID, std::next(schema->List().Find(idWhere.value()))); + } + editor.Document().ResetSelection(); + editor.Document().Select(newUID); + editor.Document().UpdateAllViews(nullptr); +} + +void RSFormView::InsertFree() { + if (std::empty(schema->Core())) { + InsertNew(CstType::base); + } else { + if (const auto nItem = cstTable.GetNextItem(mfc::noItems, LVNI_FOCUSED); nItem != mfc::noItems) { + const auto& cst = schema->GetRS(cstTable.UIDForIndex(nItem).value()); + InsertNew(cst.type, nItem); + } + } +} + +BOOL RSFormView::OnOperation(uint32_t command) { + UpdateData(); + switch(command) { + case IXTRC_EXPORT_SCHEMA: proc::ExportSchema(editor.Schema(), m_pDocument->GetPathName()); break; + case IXTRC_EXPORT_GRAPH: proc::ExportCstGraph(editor.Core(), m_pDocument->GetPathName()); break; + case IXTRC_CONVERT_TO_RSFORM: proc::SpawnModelDocument(*schema); break; + case IXTRC_SYNTHES: proc::StandaloneSynthes(ccl::ops::Type::rsSynt); break; + case IXTRC_OP_MERGE: proc::StandaloneSynthes(ccl::ops::Type::rsMerge); break; + case IXTRC_RELATION: RunRelation(); break; + case IXTRC_CST_MERGING: proc::StandaloneEquation(dynamic_cast(*m_pDocument)); break; + } + return TRUE; +} + +const SetOfEntities& RSFormView::Selection() const noexcept { + return cstTable.Selection(); +} + +BOOL RSFormView::IsContextActive(uint32_t command) const { + const auto& selected = Selection(); + if (ssize(selected) != 1 + && (command == IXTRC_TERM_TO_FUNC + || command == IXTRC_FUNC_TO_TERM + || command == IXTRC_STRUCTURE_TO_TERMS)) { + return FALSE; + } + switch (command) { + default: return IsCommandActive(command); + case ID_EDIT_PASTE: return !std::empty(g_Exteor.cstClipboard); + case IXTRC_TERM_TO_FUNC: { + const auto selType = schema->GetRS(*std::begin(selected)).type; + return selType == CstType::term; + } + case IXTRC_FUNC_TO_TERM: { + const auto selType = schema->GetRS(*std::begin(selected)).type; + return ccl::semantic::IsCallable(selType); + } + case IXTRC_STRUCTURE_TO_TERMS: { + const auto selType = schema->GetRS(*std::begin(selected)).type; + return ccl::semantic::IsRSObject(selType) && !ccl::semantic::IsBaseSet(selType); + } + } +} + +void RSFormView::UpdateStatusBar() { + rsformStatusCtrl.SetBackgroundColor(FALSE, design::Color(info::StatusOf(schema->Core()))); + rsformStatusCtrl.SetWindowTextW(info::IndicatorFor(schema->Core())); +} + +void RSFormView::RunRelation() { + const auto& selected = Selection(); + if (ssize(selected) != 1) { + ::AfxMessageBox(IXTRE_RELATE_RS, MB_ICONERROR); + return; + } + proc::ExecuteRelation(*schema, *std::begin(selected)); +} + +} // namespace xtr::view \ No newline at end of file diff --git a/src/view/RSModelView.cpp b/src/view/RSModelView.cpp new file mode 100644 index 0000000..60bcafa --- /dev/null +++ b/src/view/RSModelView.cpp @@ -0,0 +1,394 @@ +#include "stdafx.h" + +#include "xtr/view/RSModelView.h" + +#include "resource.h" + +#include "xtr/Exteor.h" +#include "xtr/ExteorOptions.h" +#include "xtr/cclDescriptor.h" +#include "xtr/xtrDesign.h" +#include "xtr/xtrProcedures.h" + +#include "xtr/ui/KeyboardHandler.h" +#include "xtr/ui/HelpHandler.h" +#include "xtr/ui/UIHelper.h" + +#include "ccl/semantic/CstFilters.hpp" + +namespace xtr::view { + +using ccl::semantic::CstType; + +using doc::RSModelDoc; +using ui::Keyboard; + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +IMPLEMENT_DYNCREATE(RSModelView, CFormView) + +BEGIN_MESSAGE_MAP(RSModelView, CFormView) + ON_WM_CONTEXTMENU() + + ON_COMMAND(IXTRC_XTR_HELP, &ThisClass::OpenHelp) + ON_BN_CLICKED(IXTRC_MODEL_SEARCH, &ThisClass::OnSearch) + ON_BN_CLICKED(IXTRC_COMMENT_B, &ThisClass::OnEditComment) + ON_BN_CLICKED(IXTRC_TRS_UPDATE_STATUS, &ThisClass::OnUpdateStatus) + ON_BN_CLICKED(IXTRC_MODEL_CALCULATE, &ThisClass::OnCalculateAll) + + ON_COMMAND_EX(ID_EDIT_COPY, &ThisClass::OnCopy) + ON_COMMAND_EX(ID_EDIT_PASTE, &ThisClass::OnPaste) + ON_EN_CHANGE(IXTRC_ALIAS, &ThisClass::OnChange) + ON_EN_CHANGE(IXTRC_TITLE, &ThisClass::OnChange) + + XTR_COMMAND_UPD(IXTRC_MOVE_UP) + XTR_COMMAND_UPD(IXTRC_MOVE_DOWN) + XTR_COMMAND_UPD(IXTRC_SELECT_BASIS) + XTR_COMMAND_UPD(IXTRC_SELECT_DEPENDENT) + XTR_COMMAND_UPD(IXTRC_DELETE_CST) + XTR_COMMAND_UPD(IXTRC_RENAME) + XTR_COMMAND_UPD(IXTRC_TERM_TO_FUNC) + XTR_COMMAND_UPD(IXTRC_FUNC_TO_TERM) + XTR_COMMAND_UPD(IXTRC_STRUCTURE_TO_TERMS) + XTR_COMMAND_UPD(IXTRC_RESET_NAMES) + XTR_COMMAND_UPD(IXTRC_CALCULATE) + XTR_COMMAND_UPD(IXTRC_MODEL_CALCULATE) + + ON_COMMAND_EX(IXTRC_INSERT_BASE_SET, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_CONST_SET, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_RS, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_AXIOM, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_TERM, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_THEOREMA, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_FUNCTION, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_PREDICATE, &ThisClass::OnInsertCst) + ON_COMMAND_EX(IXTRC_INSERT_FREE, &ThisClass::OnInsertCst) + + ON_COMMAND_EX(IXTRC_CONVERT_TO_RSFORM, &ThisClass::OnOperation) + ON_COMMAND_EX(IXTRC_EXPORT_SCHEMA, &ThisClass::OnOperation) + ON_COMMAND_EX(IXTRC_EXPORT_GRAPH, &ThisClass::OnOperation) + ON_COMMAND_EX(IXTRC_EXPORT_MODEL, &ThisClass::OnOperation) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +RSModelView::RSModelView() + : CFormView(IXTRD_VIEW_RSMODEL) {} + +void RSModelView::OnInitialUpdate() { + editor = doc::RSFacade{ dynamic_cast(*m_pDocument) }; + model = &editor.EditModel(); + + CFormView::OnInitialUpdate(); + + InitControls(); + InitTooltips(); +} + +void RSModelView::InitControls() { + titleCtrl.InitRE(Keyboard::Layout::RUS); + aliasCtrl.InitRE(Keyboard::Layout::RUS); + searchCtrl.InitRE(Keyboard::Layout::RUS); + + titleCtrl.SetFont(&XTROptions::App().fontMath); + aliasCtrl.SetFont(&XTROptions::App().fontMath); + cstTable.SetFont(&XTROptions::App().fontMath); + searchCtrl.SetFont(&XTROptions::App().fontMath); + cstTable.Init(editor); + + rsformStatusCtrl.SetFont(&XTROptions::App().fontMath); + rsModelStatusCtrl.SetFont(&XTROptions::App().fontMath); +} + +void RSModelView::InitTooltips() { + if (!tooltips.Create(this)) { + TRACE(L"Unable to create the ToolTip!"); + } else { + tooltips.SetMaxTipWidth(ui::s_TooltipWidth); + tooltips.SetFont(&XTROptions::App().fontTooltip); + tooltips.Activate(TRUE); + + tooltips.AddTool(&rsformStatusCtrl, CString{}); + tooltips.AddTool(&rsModelStatusCtrl, CString{}); + } +} + +void RSModelView::DoDataExchange(CDataExchange* pDX) { + CFormView::DoDataExchange(pDX); + + ::DDX_Control(pDX, IXTRC_TITLE, titleCtrl); + ::DDX_Control(pDX, IXTRC_ALIAS, aliasCtrl); + ::DDX_Control(pDX, IXTRC_RSFORM_LIST, cstTable); + ::DDX_Control(pDX, IXTRC_RSFORM_STATUS, rsformStatusCtrl); + ::DDX_Control(pDX, IXTRC_MODEL_STATUS, rsModelStatusCtrl); + ::DDX_Control(pDX, IXTRC_RSMODEL_SEARCH_TEXT, searchCtrl); + + if (!pDX->m_bSaveAndValidate) { + title = mfc::ToMFC(model->title); + alias = mfc::ToMFC(model->alias); + if (cstTable.IsInit()) { + cstTable.Update(TRUE); + } + } + + ::DDX_Text(pDX, IXTRC_ALIAS, alias); + ::DDX_Text(pDX, IXTRC_TITLE, title); + + if (pDX->m_bSaveAndValidate) { + model->title = mfc::ToSTL(title); + model->alias = mfc::ToSTL(alias); + editor.Document().SetSelection(cstTable.Selection()); + editor.Document().UpdateAllViews(this); + } + UpdateStatusBar(); +} + +BOOL RSModelView::PreTranslateMessage(MSG* pMsg) { + if (tooltips.m_hWnd != nullptr) { + tooltips.RelayEvent(pMsg); + } + if (pMsg->message == WM_KEYDOWN) { + if (pMsg->hwnd == cstTable.GetSafeHwnd() && pMsg->wParam == VK_DELETE) { + OnCommandRun(IXTRC_DELETE_CST); + return TRUE; + } + if (pMsg->hwnd == searchCtrl.GetSafeHwnd() && pMsg->wParam == VK_RETURN) { + OnSearch(); + return TRUE; + } + } + return CFormView::PreTranslateMessage(pMsg); +} + +void RSModelView::OnSearch() { + if (const auto searchStr = mfc::ToSTL(searchCtrl.Text()); !std::empty(searchStr)) { + if (const auto foundItems = ccl::semantic::FilterCst(model->Core(), searchStr); !std::empty(foundItems)) { + cstTable.SelectMultiple({ std::begin(foundItems), std::end(foundItems) }); + cstTable.SetFocus(); + } else { + ::AfxMessageBox(IXTRS_SEARCH_NO_MATCH, MB_ICONINFORMATION); + } + } +} + +void RSModelView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { + CView::OnUpdate(pSender, lHint, pHint); + if (pSender != this) { + UpdateData(FALSE); + } +} + +BOOL RSModelView::OnCmdMsg(uint32_t nID, int32_t nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) { + if (GetFocus() == &cstTable && + cstTable.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)) { + return TRUE; + } else { + return CFormView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); + } +} + +void RSModelView::OnChange() { + UpdateData(TRUE); +} + +BOOL RSModelView::OnCopy(uint32_t /*msgID*/) { // NOLINT(readability-convert-member-functions-to-static) + if (auto* active = dynamic_cast(GetFocus()); active != nullptr) { + active->Copy(); + } + return TRUE; +} + +BOOL RSModelView::OnPaste(uint32_t /*msgID*/) { // NOLINT(readability-convert-member-functions-to-static) + if (auto* active = dynamic_cast(GetFocus()); active != nullptr) { + active->Paste(); + } + return TRUE; +} + +void RSModelView::OpenHelp() { // NOLINT(readability-convert-member-functions-to-static) + ui::HelpHandler::RunHelp(ui::HelpID::viewRSModel); +} + +void RSModelView::OnUpdateCommandUI(CCmdUI *pCmdUI) { + pCmdUI->Enable(IsCommandActive(pCmdUI->m_nID)); +} + +BOOL RSModelView::IsCommandActive(uint32_t command) const noexcept { + const auto selSize = ssize(Selection()); + switch (command) { + case IXTRC_MODEL_CALCULATE: + case IXTRC_RESET_NAMES: + default: return TRUE; + + case IXTRC_MOVE_UP: + case IXTRC_MOVE_DOWN: + case IXTRC_SELECT_BASIS: + case IXTRC_SELECT_DEPENDENT: return cstTable.IsCommandActive(command); + + case IXTRC_DELETE_CST: + case IXTRC_CALCULATE: return selSize != 0; + + case IXTRC_TERM_TO_FUNC: + case IXTRC_FUNC_TO_TERM: + case IXTRC_STRUCTURE_TO_TERMS: + case IXTRC_RENAME: return selSize == 1; + } +} + +BOOL RSModelView::OnCommandRun(uint32_t command) { + if (!IsCommandActive(command)) { + return TRUE; + } + + UpdateData(); + switch (command) { + case IXTRC_MOVE_UP: + case IXTRC_MOVE_DOWN: + case IXTRC_SELECT_BASIS: + case IXTRC_SELECT_DEPENDENT: + return cstTable.RunCommand(command); + + case IXTRC_RESET_NAMES: proc::ResetNames(editor); break; + case IXTRC_CALCULATE: proc::CalculateSelected(dynamic_cast(*m_pDocument)); break; + case IXTRC_MODEL_CALCULATE: proc::CalculateAll(dynamic_cast(*m_pDocument)); break; + + case IXTRC_RENAME: proc::RenameCst(editor); break; + case IXTRC_DELETE_CST: proc::EraseSelected(dynamic_cast(*m_pDocument)); break; + + case IXTRC_TERM_TO_FUNC: proc::Term2Function(editor); break; + case IXTRC_FUNC_TO_TERM: proc::Function2Term(editor); break; + case IXTRC_STRUCTURE_TO_TERMS: proc::Structure2Terms(editor); break; + } + return TRUE; +} + +BOOL RSModelView::OnInsertCst(uint32_t command) { + const auto nWhere = cstTable.GetNextItem(mfc::noItems, LVNI_FOCUSED); + switch(command) { + default: return TRUE; + case IXTRC_INSERT_BASE_SET: InsertNew(CstType::base); break; + case IXTRC_INSERT_CONST_SET: InsertNew(CstType::constant); break; + case IXTRC_INSERT_RS: InsertNew(CstType::structured, nWhere); break; + case IXTRC_INSERT_AXIOM: InsertNew(CstType::axiom, nWhere); break; + case IXTRC_INSERT_TERM: InsertNew(CstType::term, nWhere); break; + case IXTRC_INSERT_THEOREMA: InsertNew(CstType::theorem, nWhere); break; + case IXTRC_INSERT_FUNCTION: InsertNew(CstType::function, nWhere); break; + case IXTRC_INSERT_PREDICATE: InsertNew(CstType::predicate, nWhere); break; + case IXTRC_INSERT_FREE: InsertFree(); break; + } + return TRUE; +} + +void RSModelView::InsertNew(const CstType cstType, int32_t nWhere) { + UpdateData(); + const auto idWhere = cstTable.UIDForIndex(nWhere); + const auto newUID = model->Emplace(cstType); + if (idWhere.has_value()) { + model->MoveBefore(newUID, std::next(model->List().Find(idWhere.value()))); + } + editor.Document().ResetSelection(); + editor.Document().Select(newUID); + editor.Document().UpdateAllViews(nullptr); +} + +void RSModelView::InsertFree() { + if (std::empty(model->Core())) { + InsertNew(CstType::base); + } else if (const auto nItem = cstTable.GetNextItem(mfc::noItems, LVNI_FOCUSED); + nItem != mfc::noItems) { + const auto& cst = model->GetRS(cstTable.UIDForIndex(nItem).value()); + InsertNew(cst.type, nItem); + } +} + +void RSModelView::OnUpdateStatus() { + BeginWaitCursor(); + + model->UpdateState(); + UpdateData(FALSE); + const auto message = info::DescriptionOf(model->Core()); + + EndWaitCursor(); + + RedrawWindow(); + ::AfxMessageBox(message, MB_ICONINFORMATION); +} + +void RSModelView::OnCalculateAll() { + OnCommandRun(IXTRC_MODEL_CALCULATE); +} + +void RSModelView::OnEditComment() { + proc::EditComment(editor); +} + +void RSModelView::OnContextMenu(CWnd* pWnd, const CPoint point) { + static constexpr auto separator = 0; + if (pWnd == &cstTable) { + CMenu popup{}; + popup.LoadMenuW(IXTRAD_RSVIEW_POPUP); + + auto* item0 = popup.GetSubMenu(0); + for (auto i = 0; i < item0->GetMenuItemCount(); ++i) { + if (const auto command = item0->GetMenuItemID(i); command != separator) { + if (!IsContextActive(command)) { + item0->EnableMenuItem(command, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); + } else { + item0->EnableMenuItem(command, MF_BYCOMMAND | MF_ENABLED); + } + } + } + item0->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); + } +} + +BOOL RSModelView::OnOperation(uint32_t command) { + switch(command) { + case IXTRC_EXPORT_SCHEMA: proc::ExportModelSchema(editor.Model(), m_pDocument->GetPathName()); break; + case IXTRC_EXPORT_GRAPH: proc::ExportCstGraph(editor.Core(), m_pDocument->GetPathName()); break; + case IXTRC_EXPORT_MODEL: proc::ExportModel(dynamic_cast(*m_pDocument)); break; + case IXTRC_CONVERT_TO_RSFORM: proc::SpawnSchemaDocument(*model); break; + } + return TRUE; +} + +const SetOfEntities& RSModelView::Selection() const noexcept { + return cstTable.Selection(); +} + +BOOL RSModelView::IsContextActive(uint32_t command) const { + const auto& selected = Selection(); + if (ssize(selected) != 1 && + (command == IXTRC_TERM_TO_FUNC + || command == IXTRC_FUNC_TO_TERM + || command == IXTRC_STRUCTURE_TO_TERMS)) { + return FALSE; + } + switch (command) { + default: return IsCommandActive(command); + case ID_EDIT_PASTE: return !std::empty(g_Exteor.cstClipboard); + case IXTRC_TERM_TO_FUNC: { + const auto selType = model->GetRS(*std::begin(selected)).type; + return selType == CstType::term; + } + case IXTRC_FUNC_TO_TERM: { + const auto selType = model->GetRS(*std::begin(selected)).type; + return ccl::semantic::IsCallable(selType); + } + case IXTRC_STRUCTURE_TO_TERMS: { + const auto selType = model->GetRS(*std::begin(selected)).type; + return ccl::semantic::IsRSObject(selType) && !ccl::semantic::IsBaseSet(selType); + } + } +} + +void RSModelView::UpdateStatusBar() { + rsformStatusCtrl.SetBackgroundColor(FALSE, design::Color(info::StatusOf(model->Core()))); + rsformStatusCtrl.SetWindowTextW(info::IndicatorFor(model->Core())); + + rsModelStatusCtrl.SetBackgroundColor(FALSE, design::Color(info::StatusOf(*model))); + rsModelStatusCtrl.SetWindowTextW(info::IndicatorFor(*model)); +} + +} // namespace xtr::view \ No newline at end of file diff --git a/src/view/TermTreeView.cpp b/src/view/TermTreeView.cpp new file mode 100644 index 0000000..02f9ace --- /dev/null +++ b/src/view/TermTreeView.cpp @@ -0,0 +1,129 @@ +#include "stdafx.h" + +#include "xtr/view/TermTreeView.h" +#include "xtr/doc/RSFormDoc.h" +#include "xtr/doc/RSModelDoc.h" + +#include "resource.h" + +#include "xtr/ui/HelpHandler.h" + +namespace xtr::view { + +#pragma warning( push ) +#pragma warning( disable : 26440 26436 26454 ) + +IMPLEMENT_DYNCREATE(TermTreeView, CFormView) + +BEGIN_MESSAGE_MAP(TermTreeView, CFormView) + ON_NOTIFY(NM_DBLCLK, IXTRC_TERM_TREE, &ThisClass::OnDblclkTermTree) + ON_COMMAND(IXTRC_XTR_HELP, &ThisClass::OpenHelp) +END_MESSAGE_MAP() + +#pragma warning( pop ) + +TermTreeView::TermTreeView() + : CFormView(IXTRD_VIEW_TERMTREE) {} + +void TermTreeView::OnInitialUpdate() { + document = dynamic_cast(m_pDocument); + if (const auto* modelDoc = dynamic_cast(document); modelDoc != nullptr) { + core = &modelDoc->Model().Core(); + } else if (document != nullptr) { + core = &dynamic_cast(document)->Schema().Core(); + } + + CFormView::OnInitialUpdate(); +} + +void TermTreeView::DoDataExchange(CDataExchange* pDX) { + CFormView::DoDataExchange(pDX); + + ::DDX_Control(pDX, IXTRC_TERM_TREE, termTreeCtrl); + + if (!pDX->m_bSaveAndValidate) { + BuildTree(); + } +} + +BOOL TermTreeView::BuildTree() { + termTreeCtrl.SetRedraw(FALSE); + termTreeCtrl.DeleteAllItems(); + for (const auto uid : core->List()) { + const auto& cst = core->GetRS(uid); + auto* root = termTreeCtrl.InsertItem(mfc::ToMFC(cst.alias)); + const auto connections = core->RSLang().Graph().InputsFor(cst.uid); + const auto sorted = core->List().SortSubset(connections); + for (const auto child : sorted) { + auto sNextName = mfc::ToMFC(core->GetRS(child).alias); + auto* const current = termTreeCtrl.InsertItem(sNextName, root); + InsertSubTree(&termTreeCtrl, current, sNextName); + } + + if (document->IsSelected(cst.uid)) { + termTreeCtrl.Expand(root, TVE_EXPAND); + termTreeCtrl.SelectItem(root); + } + } + termTreeCtrl.SetRedraw(TRUE); + termTreeCtrl.RedrawWindow(); + return TRUE; +} + +void TermTreeView::OpenHelp() { // NOLINT(readability-convert-member-functions-to-static) + ui::HelpHandler::RunHelp(ui::HelpID::viewRSForm); +} + +void TermTreeView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { + CView::OnUpdate(pSender, lHint, pHint); + if (document != nullptr && pSender != this) { + UpdateData(FALSE); + } +} + +void TermTreeView::OnBuild() { + BuildTree(); +} + +void TermTreeView::OnDblclkTermTree(NMHDR* /*pNMHDR*/, LRESULT* pResult) { + auto* const hItem = termTreeCtrl.GetSelectedItem(); + const auto sName = termTreeCtrl.GetItemText(hItem); + InsertSubTree(&termTreeCtrl, hItem, sName); + *pResult = FALSE; +} + +int32_t TermTreeView::InsertSubTree(CTreeCtrl* termTree, HTREEITEM current, const CString sName) { + auto result = 0; + auto* item = FindItemInTree(termTree, sName); + if (termTree->GetNextItem(current, TVGN_CHILD) != nullptr) { + return 0; + } else { + auto* child = termTree->GetNextItem(item, TVGN_CHILD); + while (child != nullptr) { + auto sSubName = termTree->GetItemText(child); + termTree->InsertItem(sSubName, current); + ++result; + child = termTree->GetNextItem(child, TVGN_NEXT); + } + return result; + } +} + +HTREEITEM TermTreeView::FindItemInTree(const CTreeCtrl* termTree, const CString sFindName) { + auto* root = termTree->GetRootItem(); + if (root == nullptr) { + return root; + } + + auto* item = termTree->GetNextItem(root, TVGN_ROOT); + while (item != nullptr) { + if (sFindName == termTree->GetItemText(item)) { + return item; + } else { + item = termTree->GetNextItem(item, TVGN_NEXT); + } + } + return nullptr; +} + +} // namespace xtr::view \ No newline at end of file diff --git a/src/viewmodel/vmTextEdit.cpp b/src/viewmodel/vmTextEdit.cpp new file mode 100644 index 0000000..d12e716 --- /dev/null +++ b/src/viewmodel/vmTextEdit.cpp @@ -0,0 +1,126 @@ +#include "stdafx.h" + +#include "xtr/viewmodel/vmTextEdit.h" + +#include "resource.h" + +#include "xtr/xtrServices.h" +#include "xtr/xtrDesign.h" + +namespace xtr::viewmodel { + +using ccl::lang::EntityTermContext; +using ccl::lang::Reference; + +void vmTextEdit::Initialize(const EntityTermContext& cntxt) noexcept { + context = &cntxt; + references.SetContext(*context); +} + +void vmTextEdit::UpdateData() { + if (!outdated) { + return; + } else if (empty(references.get())) { + return; + } + + const auto positionIterator = [&textControl = this->control] + (const auto& prev) -> std::optional { + auto next = textControl.NextHighlighted(prev.finish); + for (; next.has_value() && !design::IsReference(next->color); next = textControl.NextHighlighted(next->rng.finish)) { + ; + } + if (next.has_value()) { + return next->rng; + } else { + return std::nullopt; + } + }; + + if (!references.UpdatePositions(positionIterator)) { + throw std::runtime_error("References were corrupted!"); // TODO: consider exception mech + } else { + outdated = false; + } +} + +void vmTextEdit::SetRefStr(const CString refStr) { + const auto text = mfc::ToSTL(refStr); + control.SetText(mfc::ToMFC(references.Resolve(text))); + for (const auto& ref : references.get()) { + control.Highlight(HighlightItem{ ref.position, design::Color(ref.GetType()) }); + } +} + +CString vmTextEdit::GetRefStr() { + UpdateData(); + return mfc::ToMFC(references.OutputRefs(mfc::ToSTL(control.GetText()))); +} + +CString vmTextEdit::GetRefSubstr(StrRange cr) { + if (cr.finish == cr.start) { + return CString{}; + } else { + const auto text = control.GetText(); + cr.finish = std::min(cr.finish, text.GetLength()); + UpdateData(); + return mfc::ToMFC(references.OutputRefs(mfc::ToSTL(text), cr)); + } +} + +void vmTextEdit::OnEraseText(StrRange range, const BOOL lookBehind) { + UpdateData(); + const auto text = control.GetText(); + std::optional erasedRange{}; + const auto wasEmpty = std::empty(range); + if (wasEmpty) { + if (lookBehind) { + if (range.start == 0) { + return; + } else { + --range.start; + } + } else { + if (range.finish == text.GetLength()) { + return; + } else { + ++range.finish; + } + } + } + erasedRange = references.EraseIn(range, wasEmpty); + if (erasedRange.has_value()) { + control.ReplaceRange(erasedRange.value(), L""); + } +} + +void vmTextEdit::OnInsertRef(const StrRange rWhere, Reference data) { + UpdateData(); + + const auto text = control.GetText(); + const auto erasedRng = references.EraseIn(rWhere); + if (!erasedRng.has_value()) { + Global::Msg().ShowMessage(IXTRE_REF_CANNOT_ADD, MB_ICONERROR); + return; + } + + const auto* newRef = references.Insert(std::move(data), rWhere.start); + if (newRef == nullptr) { + Global::Msg().ShowMessage(IXTRE_REF_CANNOT_ADD, MB_ICONERROR); + return; + } + const auto refColor = design::Color(newRef->GetType()); + const auto resolvedText = mfc::ToMFC(newRef->resolvedText); + + StrRange controlRange = erasedRng.value(); + control.ReplaceRange(controlRange, resolvedText); + controlRange.SetLength(resolvedText.GetLength()); + control.Highlight(HighlightItem{ controlRange, refColor }); +} + +const Reference* vmTextEdit::RepresentativeOf(const StrRange range) { + UpdateData(); + return references.FirstIn(range); +} + +} // namespace xtr::viewmodel \ No newline at end of file diff --git a/src/xtrDesign.cpp b/src/xtrDesign.cpp new file mode 100644 index 0000000..881e4f1 --- /dev/null +++ b/src/xtrDesign.cpp @@ -0,0 +1,198 @@ +#include "stdafx.h" + +#include "xtr/xtrDesign.h" + +using ccl::semantic::RSForm; +using ccl::semantic::RSModel; +using ccl::rslang::TokenID; +using ccl::rslang::ValueClass; +using ccl::semantic::ParsingStatus; +using ccl::semantic::EvalStatus; +using ccl::oss::PictID; +using ccl::oss::OSSchema; +using ccl::lang::ReferenceType; + +namespace xtr::design { + +static constexpr auto clrMidBlue = RGB(0, 111, 255); +static constexpr auto clrBrown = RGB(150, 70, 0); + +CHARFORMAT2W CharFormatRE() noexcept { + CHARFORMAT2W cf{}; + memset(&cf, 0, sizeof(cf)); + cf.cbSize = sizeof(cf); + return cf; +} + +COLORREF Color(ccl::semantic::ParsingStatus status) noexcept { + switch (status) { + case ParsingStatus::INCORRECT: return clrRed; + case ParsingStatus::UNKNOWN: return clrMidBlue; + default: + case ParsingStatus::VERIFIED: return clrGreen; + } +} + +COLORREF Color(const TokenID token) noexcept { + switch (token) { + default: + return clrBlack; + + case TokenID::ID_RADICAL: + return clrJade; + + case TokenID::ID_GLOBAL: + case TokenID::ID_FUNCTION: + case TokenID::ID_PREDICATE: + return clrPurple; + + case TokenID::BOOL: + case TokenID::REDUCE: + case TokenID::DEBOOL: + case TokenID::BIGPR: + case TokenID::CARD: + case TokenID::SMALLPR: + case TokenID::FILTER: + return clrBlue; + } +} + +COLORREF Color(const info::CoreStatus status) noexcept { + switch (status) { + case info::CoreStatus::CORRECT: return clrGreen; + case info::CoreStatus::WARNING: return clrYellow; + default: + case info::CoreStatus::INCORRECT: return clrRed; + } +} + +COLORREF Color(const info::ModelStatus status) noexcept { + switch (status) { + case info::ModelStatus::CORRECT: return clrGreen; + case info::ModelStatus::WARNING: return clrYellow; + default: + case info::ModelStatus::INCORRECT: return clrRed; + } +} + +COLORREF Color(const EvalStatus status) noexcept { + static constexpr auto clrIncalc = RGB(138, 8, 8); + switch (status) { + default: + case EvalStatus::UNKNOWN: + case EvalStatus::NEVER_CALCULATED: return clrYellow; + case EvalStatus::INCALCULABLE: return clrIncalc; + case EvalStatus::AXIOM_FAIL: + case EvalStatus::EMPTY: + case EvalStatus::HAS_DATA: return clrGreen; + } +} + +COLORREF Color(const ValueClass status) noexcept { + switch (status) { + default: + case ValueClass::invalid: return clrBrown; + case ValueClass::props: return clrTeal; + case ValueClass::value: return clrGreen; + } +} + +COLORREF Color(const ReferenceType type) noexcept { + switch (type) { + default: + case ReferenceType::invalid: return clrYellow; + case ReferenceType::entity: return clrYellow; + case ReferenceType::collaboration: return clrGray200; + } +} + +COLORREF TextColor(const RSForm& schema, const EntityUID target) { + const auto status = schema.GetParse(target).status; + if (status == ParsingStatus::UNKNOWN) { + return clrMidBlue; + } else if (status == ParsingStatus::INCORRECT) { + return clrRed; + } else { + switch (schema.GetParse(target).valueClass) { + default: + case ValueClass::value: return clrBlack; + case ValueClass::props: return clrTeal; + case ValueClass::invalid: return clrBrown; + } + } +} + +COLORREF TextColor(const RSModel& model, const EntityUID target) { + static constexpr auto COLOR_INCALC = RGB(255, 102, 0); + static constexpr auto COLOR_TBA = RGB(57, 30, 174); + static constexpr auto COLOR_EMPTY = RGB(0, 180, 8); + static constexpr auto COLOR_FALSE = RGB(255, 0, 102); + + const auto status = model.GetParse(target).status; + if (status == ParsingStatus::UNKNOWN) { + return clrMidBlue; + } else if (status == ParsingStatus::INCORRECT) { + return clrRed; + } else if (ccl::semantic::IsCallable(model.GetRS(target).type)) { + return clrBlack; + } else { + switch (model.Calculations()(target)) { + default: return clrBlack; + case EvalStatus::INCALCULABLE: return COLOR_INCALC; + case EvalStatus::NEVER_CALCULATED: return COLOR_TBA; + case EvalStatus::EMPTY: return COLOR_EMPTY; + case EvalStatus::AXIOM_FAIL: return COLOR_FALSE; + } + } +} + +COLORREF BackgroundColor(const RSForm& schema, const EntityUID target) { + if (!schema.Mods().IsTracking(target)) { + return clrWhite; + } else if (schema.Mods()(target)->allowEdit) { + return clrGray233; + } else { + return clrGray211; + } +} + +COLORREF BackgroundColor(const ccl::semantic::RSModel& /*model*/, const EntityUID /*target*/) noexcept { + return clrWhite; +} + +COLORREF BackgroundColor(const OSSchema& oss, const PictID target) { + static constexpr auto clrPictGreen = RGB(100, 255, 100); + if (!oss.Ops().HasOperation(target)) { + return !std::empty(*oss.Src()(target)) ? clrPictGreen : clrRed; + } else { + switch (oss.Ops().StatusOf(target)) { + default: return clrPictGreen; + case ccl::ops::Status::undefined: + case ccl::ops::Status::broken: + case ccl::ops::Status::defined: + return clrRed; + + case ccl::ops::Status::outdated: + return clrYellow; + } + } +} + +COLORREF BracketsColor(int32_t level) { + static const auto parColors = std::vector{ + RGB(238,50, 216), + RGB(24, 159,17), + clrBlack, + RGB(0, 176,240), + RGB(247,150,70), + RGB(38, 71, 236) + }; + + if (level < 0) { + return clrRed; + } else { + return parColors.at(level % std::size(parColors)); + } +} + +} // namespace xtr::design \ No newline at end of file diff --git a/src/xtrProcedures.cpp b/src/xtrProcedures.cpp new file mode 100644 index 0000000..6c2c011 --- /dev/null +++ b/src/xtrProcedures.cpp @@ -0,0 +1,902 @@ +#include "stdafx.h" + +#include "xtr/xtrProcedures.h" + +#include "resource.h" + +#include "xtr/Exteor.h" +#include "xtr/ExteorOptions.h" +#include "xtr/cclDescriptor.h" + +#include "xtr/doc/Documents.h" +#include "xtr/doc/RSFacade.h" +#include "xtr/doc/OSSDoc.h" + +#include "xtr/io/SchemaExporter.h" +#include "xtr/io/CstGraphExporter.h" +#include "xtr/io/ModelDataExchange.h" +#include "xtr/io/OSSExporter.h" +#include "xtr/io/ModelExporter.h" + +#include "xtr/dialog/BasicDlg.h" +#include "xtr/dialog/ExportSchema.h" +#include "xtr/dialog/ExportModel.h" +#include "xtr/dialog/ExportCstGraphDlg.h" +#include "xtr/dialog/OpSyntGUI.h" +#include "xtr/dialog/CstRenameDialog.h" +#include "xtr/dialog/Term2Function.h" +#include "xtr/dialog/Function2Term.h" +#include "xtr/dialog/GenerateStructure.h" +#include "xtr/dialog/PickOperation.h" +#include "xtr/dialog/EditConstituenta.h" + +#include "xtr/view/OSSLayout.h" + +#include "ccl/semantic/CstFilters.hpp" +#include "ccl/rslang/RSExpr.h" + +namespace xtr::proc { + +using ccl::semantic::CstType; +using ccl::semantic::RSForm; +using ccl::semantic::RSCore; +using ccl::semantic::RSModel; +using ccl::oss::OSSchema; +using xtr::doc::RSFormDoc; +using xtr::doc::RSModelDoc; +using xtr::doc::OSSDoc; +using xtr::dialog::EditConstituentaDlg; + +namespace { + +using ccl::ops::EquationOptions; +using ccl::oss::PictID; + +CString PathForExport(const CString sourcePath, const CString suffix, const FileType type) { + const auto source = std::filesystem::path(sourcePath.GetString()); + assert(std::filesystem::exists(source)); + + const auto directory = source.parent_path() / L"export"; + if (!std::filesystem::exists(directory)) { + std::filesystem::create_directory(directory); + } + auto exportPath = directory / source.filename().replace_extension(); + if (!suffix.IsEmpty()) { + exportPath += L"_" + suffix; + } + exportPath += L"_" + CTime::GetCurrentTime().Format(LR"(%Y%m%d_%H%M)") + ExtensionFor(type); + return exportPath.c_str(); +} + +BOOL ConfirmURL(CString url) { + return (url.Right(4).CompareNoCase(LR"(.exe)") != 0 && url.Right(4).CompareNoCase(LR"(.bat)") != 0) + || ::AfxMessageBox(mfc::FormatSID(IXTRS_URL_CONFIRM, url.GetString()), MB_YESNO | MB_ICONQUESTION) == IDYES; +} + +BOOL ImportStructured(ccl::semantic::RSModel& model, const EntityUID target) { + const auto* typif = model.GetParse(target).Typification(); + if (typif == nullptr) { + ::AfxMessageBox(IXTRE_RSMODEL_TYPIFICATION, MB_ICONERROR); + return FALSE; + } + + const auto result = io::RSMDataX::ImportStructured(model, *typif); + if (!result.has_value()) { + return FALSE; + } + + const auto newData = result->Unpack(*typif); + if (!newData.has_value()) { + ::AfxMessageBox(IXTRE_RSMODEL_DATA, MB_ICONERROR); + return FALSE; + } + + const auto oldData = model.Values().SDataFor(target); + const auto merge = typif->IsCollection() && oldData.has_value() && !oldData->B().IsEmpty() + && ::AfxMessageBox(IXTRS_PROMT_MERGE_DATA, MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2) == IDYES; + model.Values().SetStructureData(target, merge ? oldData->B().Union(newData->B()) : newData.value()); + return TRUE; +} + +BOOL ImportNamed(ccl::semantic::RSModel& model, const EntityUID target) { + if (const auto result = io::RSMDataX::ImportText(model); result.has_value()) { + model.Values().SetBasicText(target, result.value()); + return TRUE; + } else { + return FALSE; + } +} + +std::pair> +RequestOperationOpts(OSSchema& oss, const PictID pid, const ccl::ops::Type operation) { + static constexpr BOOL runFromOSS = TRUE; + + if (operation == ccl::ops::Type::tba) { + return { false, nullptr }; + } + const auto parents = oss.Graph().ParentsOf(pid); + const auto* operand1 = ccl::src::CastData(oss.Src().DataFor(parents.at(0))); + const auto* operand2 = ccl::src::CastData(oss.Src().DataFor(parents.at(1))); + if (operand1 == nullptr || operand2 == nullptr) { + ::AfxMessageBox(IXTRE_EDIT_OPT_NO_ARG, MB_ICONEXCLAMATION); + return { false, nullptr }; + } + + const auto& pict = *(oss)(pid); + const auto* oldEquations = dynamic_cast(oss.Ops()(pid)->options.get()); + + dialog::SynthesUI dlgSynt(operation, runFromOSS); + dlgSynt.operand1 = operand1; + dlgSynt.operand2 = operand2; + dlgSynt.title = mfc::ToMFC(pict.title); + dlgSynt.alias = mfc::ToMFC(pict.alias); + if (oldEquations != nullptr && ccl::ops::HasOptions(operation)) { + dlgSynt.equations = *oldEquations; + } + + if (dlgSynt.DoModal() == IDCANCEL) { + return { false, nullptr }; + } + + oss.SetPictTitle(pid, mfc::ToSTL(dlgSynt.title)); + oss.SetPictAlias(pid, mfc::ToSTL(dlgSynt.alias)); + if (!ccl::ops::HasOptions(operation)) { + return { true, nullptr }; + } else { + return { true, std::make_unique(dlgSynt.equations) }; + } +} + +std::optional CreateOssArchive(const OSSDoc& document) { + const auto basePath = std::filesystem::path(document.OSS().Src().ossDomain); + auto savePath = basePath / mfc::ToUTF8(CTime::GetCurrentTime().Format(LR"(%Y%m%d_%H%M)")); + if (std::filesystem::exists(savePath) || !std::filesystem::create_directory(savePath)) { + ::AfxMessageBox(mfc::FormatSID(IXTRE_FOLDER_CREATE_FAIL, mfc::ToMFC(savePath.u8string()).GetString()), MB_ICONINFORMATION); + return std::nullopt; + } + + const auto ossFileName = std::filesystem::path(mfc::ToUTF8(document.GetPathName())).filename(); + const auto ossOldPath = basePath / ossFileName; + const auto ossArchPath = savePath / ossFileName; + std::filesystem::copy_file(ossOldPath, ossArchPath); + + for (const auto& pict : document.OSS()) { + const auto* handle = document.OSS().Src()(pict.uid); + if (!std::empty(*handle)) { + const auto oldPath = basePath / handle->desc.name; + const auto archPath = savePath / handle->desc.name; + if (std::filesystem::exists(oldPath)) { + std::filesystem::copy_file(oldPath, archPath); + } + } + } + + return mfc::ToMFC(savePath.u8string()); +} + +BOOL RunOperation(OSSchema& oss, const PictID opid, const BOOL showResult = TRUE) { + if (!oss.Ops().Execute(opid)) { + ::AfxMessageBox(IXTRS_EXECUTION_FAILED, MB_ICONEXCLAMATION); + return FALSE; + } + + if (auto* doc = dynamic_cast(oss.Src().OpenSrc(opid)); + doc == nullptr) { + return FALSE; + } else { + if (showResult) { + ExteorApplication::Docs().ShowDocument(*doc); + } + return TRUE; + } +} + +CString PromptForSourceFile(const CString folder) { + CFileDialog dialog(TRUE, LR"(*.trs)", LR"(*.trs)", OFN_HIDEREADONLY | OFN_EXPLORER, mfc::LoadSID(IXTRS_FILTER_OSS_PROMPT)); + const auto title = mfc::LoadSID(IXTRS_PICT_NAME_AT); + dialog.m_ofn.lpstrInitialDir = folder; + dialog.m_ofn.lpstrTitle = title; + if (dialog.DoModal() == IDOK) { + return dialog.GetPathName(); + } else { + return CString{}; + } +} + +BOOL CheckLocalCstUse(const RSCore& core, const SetOfEntities& target) { + const auto dependant = core.RSLang().Graph().ExpandOutputs(target); + SetOfEntities difference{}; + std::copy_if(dependant.begin(), dependant.end(), + std::inserter(difference, begin(difference)), + [&target](const auto needle) { return target.find(needle) == target.end(); }); + if (std::empty(difference)) { + return true; + } + CString cstList{}; + for (const auto entity : core.List().SortSubset(difference)) { + cstList += mfc::ToMFC(core.GetRS(entity).alias); + cstList += ' '; + } + return ::AfxMessageBox(mfc::FormatSID(IXTRS_DEL_CST_LOCAL_USE, cstList.GetString()), + MB_YESNO | MB_DEFBUTTON2 | MB_ICONEXCLAMATION) == IDYES; +} + +BOOL CheckCstUseInOSS(const RSFormDoc& document, const SetOfEntities& target) { + for (const auto entity : target) { + switch (ccl::Environment::Sources().QueryEntityUse(document, entity)) { + case ccl::change::Usage::asElement: { + auto msg = mfc::FormatSID(IXTRS_DELCST_USED_IN_OSS, mfc::ToMFC(document.Schema().GetRS(entity).alias).GetString()); + if (::AfxMessageBox(msg, MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION) != IDYES) { + return FALSE; + } else { + break; + } + } + case ccl::change::Usage::asOption: { + auto msg = mfc::FormatSID(IXTRS_DELCST_USED_IN_OPS, mfc::ToMFC(document.Schema().GetRS(entity).alias).GetString()); + ::AfxMessageBox(msg, MB_ICONEXCLAMATION); + return FALSE; + } + case ccl::change::Usage::notUsed:; + } + } + return TRUE; +} + +std::vector ParseArguments(const CString args) { + std::vector result{}; + int pos = 0; + while (true) { + auto token = args.Tokenize(LR"(<>)", pos); + if (token.IsEmpty()) { + return result; + } + if (token.GetLength() > 1) { + result.push_back(token); + } + } +} + +} // anonymous namespace + +// ======================================================== + +void ExportCstGraph(const RSCore& source, const CString path) { + dialog::ExportCstGraphDlg dlg{}; + if (dlg.DoModal() != IDOK) { + return; + } + const auto exportPath = PathForExport(path, L"Graph", dlg.exportType); + const auto success = io::CstGraphExporter(source).Export(dlg.options, exportPath, dlg.exportType); + if (!success) { + ::AfxMessageBox(mfc::FormatSID(IXTRE_FILE_UNAVAILABLE, exportPath.GetString()), MB_ICONERROR); + } else { + ::ShellExecuteW(nullptr, L"open", exportPath, nullptr, nullptr, SW_SHOW); + ::AfxMessageBox(mfc::FormatSID(IXTRS_EXPORT_SUCCESS, exportPath.GetString()), MB_ICONINFORMATION); + } +} + +void ExportSchema(const RSForm& schema, const CString path) { + dialog::ExportSchema dlg{}; + if (dlg.DoModal() != IDOK) { + return; + } + const auto exportPath = PathForExport(path, L"Schema", dlg.exportType); + const auto success = io::SchemaExporter(schema).Export(dlg.options, exportPath, dlg.exportType); + if (!success) { + if (dlg.exportType == FileType::docx) { + ::AfxMessageBox(IXTRE_EXPORT_WORD, MB_ICONERROR); + } else { + ::AfxMessageBox(mfc::FormatSID(IXTRE_FILE_UNAVAILABLE, exportPath.GetString()), MB_ICONINFORMATION); + } + } else { + if (dlg.exportType == FileType::docx) { + ::AfxMessageBox(IXTRS_EXPORT_WORD_OK, MB_ICONINFORMATION); + } else { + ::ShellExecuteW(nullptr, L"open", exportPath, nullptr, nullptr, SW_SHOW); + ::AfxMessageBox(mfc::FormatSID(IXTRS_EXPORT_SUCCESS, exportPath.GetString()), MB_ICONINFORMATION); + } + } +} + +void ExportModelSchema(const RSModel& model, const CString path) { + RSForm schema{}; + schema.LoadCore() = model.Core(); + schema.title = model.title; + schema.alias = model.alias; + schema.comment = model.comment; + ExportSchema(schema, path); +} + +void ExportOSS(const doc::OSSDoc& document) { + const auto exportPath = PathForExport(document.GetPathName(), L"OSS", FileType::json); + const auto success = io::OSSExporter(document.OSS()).Export(exportPath, FileType::json); + if (!success) { + ::AfxMessageBox(mfc::FormatSID(IXTRE_FILE_UNAVAILABLE, exportPath.GetString()), MB_ICONERROR); + } else { + ::ShellExecuteW(nullptr, L"open", exportPath, nullptr, nullptr, SW_SHOW); + ::AfxMessageBox(mfc::FormatSID(IXTRS_EXPORT_SUCCESS, exportPath.GetString()), MB_ICONINFORMATION); + } +} + +void ExportOSSGraph(const OSSDoc& document, view::OSSLayout& layout) { + const auto exportPath = PathForExport(document.GetPathName(), L"OSSGraph", FileType::png); + const auto image = layout.GetImage(); + if (image.Save(exportPath) != S_OK) { + ::AfxMessageBox(IXTRE_OSS_PNG_FAIL, MB_ICONEXCLAMATION); + } else { + ::ShellExecuteW(nullptr, L"open", exportPath, nullptr, nullptr, SW_SHOW); + ::AfxMessageBox(mfc::FormatSID(IXTRS_EXPORT_SUCCESS, exportPath.GetString()), MB_ICONINFORMATION); + } +} + +void ExportModel(const doc::RSModelDoc& document) { + dialog::ExportModel dlg{}; + if (dlg.DoModal() != IDOK) { + return; + } + const auto exportPath = PathForExport(document.GetPathName(), L"Model", dlg.exportType); + const auto success = io::ModelExporter(document.Model()).Export(exportPath, dlg.exportType); + if (!success) { + if (dlg.exportType == FileType::xlsx) { + ::AfxMessageBox(IXTRS_EXPORTXL_FAIL, MB_ICONERROR); + } else { + ::AfxMessageBox(mfc::FormatSID(IXTRE_FILE_UNAVAILABLE, exportPath.GetString()), MB_ICONERROR); + } + } else { + ::ShellExecuteW(nullptr, L"open", exportPath, nullptr, nullptr, SW_SHOW); + if (dlg.exportType == FileType::xlsx) { + ::AfxMessageBox(IXTRS_EXPORTXL_SUCCESS, MB_ICONINFORMATION); + } else { + ::AfxMessageBox(mfc::FormatSID(IXTRS_EXPORT_SUCCESS, exportPath.GetString()), MB_ICONINFORMATION); + } + } +} + +void ExportCstDataToExcel(const ccl::semantic::RSModel& model, EntityUID target) { + if (!io::RSMDataX::ExportDataFor(target, model)) { + ::AfxMessageBox(IXTRS_EXPORTXL_FAIL, MB_ICONERROR); + } +} + +void EraseCstData(ccl::semantic::RSModel& model, const EntityUID target) { + const auto type = model.GetRS(target).type; + if (!ccl::semantic::IsBaseNotion(type)) { + return; + } else if (::AfxMessageBox(IXTRS_PROMT_ERASE_DATA, MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2) == IDYES) { + model.Values().ResetDataFor(target); + } +} + +void ImportCstDataFromExcel(ccl::semantic::RSModel& model, EntityUID target) { + if (ccl::semantic::IsBaseSet(model.GetRS(target).type) ? + ImportNamed(model, target) : ImportStructured(model, target)) { + ::AfxMessageBox(IXTRS_RSMODEL_DATA_IMPORT_SUCCESS, MB_ICONINFORMATION); + } else { + ::AfxMessageBox(IXTRS_RSMODEL_DATA_IMPORT_FAIL, MB_ICONERROR); + } +} + +void EditConstituenta(doc::RSFacade& editor, const EntityUID target) { + EditConstituentaDlg(editor, target).DoModal(); + editor.Document().UpdateAllViews(nullptr); +} + +void RenameCst(doc::RSFacade& editor) { + auto dlg = dialog::CstRename(editor.Core(), *std::begin(editor.Document().Selection())); + if (dlg.DoModal() != IDOK) { + return; + } + if (dlg.newName == dlg.oldName) { + ::AfxMessageBox(IXTRE_RENAME_NOOP, MB_ICONEXCLAMATION); + return; + } + + const auto target = editor.Core().FindAlias(mfc::ToSTL(dlg.oldName)).value(); + if (!editor.SetAliasFor(target, mfc::ToSTL(dlg.newName), dlg.doUpdateExpr)) { + ::AfxMessageBox(IXTRE_RENAME_FAIL, MB_ICONEXCLAMATION); + } else { + editor.Document().UpdateAllViews(nullptr); + ::AfxMessageBox(IXTRS_RENAME_SUCCESS, MB_ICONINFORMATION); + } +} + +void Term2Function(doc::RSFacade& editor) { + dialog::Term2Function dlg(editor, *std::begin(editor.Document().Selection())); + dlg.DoModal(); + if (!empty(dlg.addedCst)) { + editor.Document().SetSelection({ std::begin(dlg.addedCst), std::end(dlg.addedCst) }); + editor.Document().UpdateAllViews(nullptr); + } +} + +void Function2Term(doc::RSFacade& editor) { + dialog::Func2Term dlg(editor, *std::begin(editor.Document().Selection())); + dlg.DoModal(); + if (!empty(dlg.addedCst)) { + editor.Document().SetSelection({ std::begin(dlg.addedCst), std::end(dlg.addedCst) }); + editor.Document().UpdateAllViews(nullptr); + } +} + +void Structure2Terms(doc::RSFacade& editor) { + dialog::Structure2Terms dlg(editor, *std::begin(editor.Document().Selection())); + dlg.DoModal(); + if (!empty(dlg.addedCst)) { + editor.Document().SetSelection({ std::begin(dlg.addedCst), std::end(dlg.addedCst) }); + editor.Document().UpdateAllViews(nullptr); + } +} + +void MoveCstBefore(doc::RSFacade& editor, const SetOfEntities& what, const ccl::semantic::ListIterator pos) { + for (const auto entity : editor.List().SortSubset(what)) { + if (!editor.MoveBefore(entity, pos)) { + ::AfxMessageBox(IXTRS_ERR_MOVE_CST, MB_ICONERROR); + break; + } + } + editor.Document().SetSelection(what); + editor.Document().UpdateAllViews(nullptr); +} + +void EditComment(doc::RSFacade& editor) { + const std::string oldComment = editor.IsModel() ? editor.Model().comment : editor.Schema().comment; + dialog::EditComment editDlg(mfc::ToMFC(oldComment), mfc::LoadSID(IXTRS_COMMENT)); + if (editDlg.DoModal() != IDOK) { + return; + } + if (const auto newComment = mfc::ToSTL(editDlg.comment); oldComment != newComment) { + editor.SetComment(newComment); + editor.Document().SetModifiedFlag(TRUE); + editor.Document().UpdateAllViews(nullptr); + } +} + +void ResetNames(doc::RSFacade& editor) { + editor.ResetAliases(); + editor.Document().UpdateAllViews(nullptr); +} + +void StandaloneEquation(RSFormDoc& document) { + dialog::EditString dlg(LR"(X1>X2)", mfc::LoadSID(IXTRS_CAPTION_EQUATE)); + if (dlg.DoModal() != IDOK) { + return; + } + + const auto mergeList = ParseArguments(dlg.resultStr); + if (ssize(mergeList) != 2) { + ::AfxMessageBox(IXTRE_EQUATION_ARGS, MB_ICONERROR); + return; + } + + auto& schema = document.Schema(); + const auto id1 = schema.Core().FindAlias(mfc::ToSTL(mergeList.at(0))); + const auto id2 = schema.Core().FindAlias(mfc::ToSTL(mergeList.at(1))); + if (!id1.has_value() || !id2.has_value()) { + ::AfxMessageBox(IXTRE_EQUATION_UNKNOWN, MB_ICONERROR); + return; + } + + const auto equationMode = [&]() noexcept { + if (dlg.resultStr.Find(L"<") != mfc::noItems) { + return ccl::ops::Equation::Mode::keepHier; + } else { + return ccl::ops::Equation::Mode::keepDel; + } + }(); + + ccl::ops::EquationOptions equations{}; + equations.Insert(id1.value(), id2.value(), ccl::ops::Equation{ equationMode, std::string{} }); + if (!schema.Ops().IsEquatable(equations)) { + ::AfxMessageBox(IXTRE_EQUATION_INVALID, MB_ICONERROR); + } else if (schema.Ops().Equate(equations).has_value()) { + document.ResetSelection(); + document.UpdateAllViews(nullptr); + } +} + +void ResetClaims(RSFormDoc& document) { + if (::AfxMessageBox(IXTRS_PROMT_RESET_FLAGS, MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2) == IDYES) { + document.ReleaseClaim(); + document.Schema().Mods().ResetAll(); + document.UpdateAllViews(nullptr); + } +} + +void EraseSelected(RSFormDoc& document) { + const auto& target = document.Selection(); + for (const auto entity : target) { + if (document.Schema().Mods().IsTracking(entity)) { + ::AfxMessageBox(IXTRE_DELETE_CST_PARTIAL, MB_ICONERROR); + return; + } + } + + if (!CheckLocalCstUse(document.Schema().Core(), target) || + !CheckCstUseInOSS(document, target)) { + return; + } + + for (const auto entity : target) { + document.Schema().Erase(entity); + } + document.ResetSelection(); + document.UpdateAllViews(nullptr); +} + +void EraseSelected(RSModelDoc& document) { + const auto& target = document.Selection(); + if (!CheckLocalCstUse(document.Model().Core(), target)) { + return; + } + for (const auto entity : target) { + document.Model().Erase(entity); + } + document.ResetSelection(); + document.UpdateAllViews(nullptr); +} + +void CalculateSelected(RSModelDoc& document) { + const auto& selection = document.Selection(); + g_Exteor.BeginWaitCursor(); + for (const auto entity : document.Model().List().SortSubset(selection)) { + document.Model().Calculations().Calculate(entity); + } + g_Exteor.EndWaitCursor(); + ::AfxMessageBox(IXTRS_CALCULATION_SUCCESS, MB_ICONASTERISK); + document.UpdateAllViews(nullptr); +} + +void CalculateAll(RSModelDoc& document) { + document.DoFileSave(); + + g_Exteor.BeginWaitCursor(); + + const auto start = clock(); + document.Model().Calculations().RecalculateAll(); + const auto duration = clock() - start; + + g_Exteor.EndWaitCursor(); + + std::stringstream ss{}; + ss << std::setprecision(4) << static_cast(duration) / CLOCKS_PER_SEC; + ::AfxMessageBox(mfc::FormatSID(IXTRS_CALC_TIME, mfc::ToMFC(ss.str()).GetString()), MB_ICONASTERISK); + + document.UpdateAllViews(nullptr); +} + +void DoAction(OSSDoc& document) { + auto& oss = document.OSS(); + const auto active = document.selection; + if (!std::empty(*oss.Src()(active)) || !oss.Ops().HasOperation(active)) { + proc::OpenSelectedSource(document); + return; + } + + switch (oss.Ops().StatusOf(active)) { + case ccl::ops::Status::outdated: + case ccl::ops::Status::done: proc::OpenSelectedSource(document); break; + case ccl::ops::Status::undefined: proc::EditSelectedOperation(document); break; + case ccl::ops::Status::defined: { + const auto msg = mfc::FormatSID(IXTRS_OSS_SINTEZ_GO, info::Label(oss.Ops()(active)->type).GetString()); + if (::AfxMessageBox(msg, MB_YESNO | MB_ICONQUESTION) == IDYES) { + proc::RunSelectedOperation(document); + } else { + proc::OpenSelectedSource(document); + } + break; + } + case ccl::ops::Status::broken: { + if (::AfxMessageBox(IXTRS_BROKEN_OP, MB_YESNO | MB_ICONQUESTION) == IDYES) { + proc::EditSelectedOperation(document); + } else { + proc::OpenSelectedSource(document); + } + break; + } + } +} + +void EditSelectedOperation(OSSDoc& document) { + auto& oss = document.OSS(); + const auto active = document.selection; + if (!std::empty(*oss.Src()(active)) && + ::AfxMessageBox(IXTRS_CHANGE_OPTS_CAUTION, MB_YESNO | MB_ICONEXCLAMATION) != IDYES) { + return; + } + + dialog::PickOperationDlg operationTypeDlg(oss, active); + if (operationTypeDlg.DoModal() != IDOK) { + return; + } + + const auto operation = operationTypeDlg.GetSelectedOperation(); + auto [flag, options] = RequestOperationOpts(oss, active, operation); + if (!flag) { + return; + } + + if (!oss.Ops().InitFor(active, operation, std::move(options))) { + ::AfxMessageBox(IXTRS_CCL_INIT_OP_FAIL, MB_ICONERROR); + } else { + if (operation != ccl::ops::Type::tba) { + if (oss.Ops()(active)->broken) { + ::AfxMessageBox(IXTRS_OPTS_BROKEN, MB_ICONEXCLAMATION); + } else if (operationTypeDlg.autorun && !RunOperation(oss, active, FALSE)) { + ::AfxMessageBox(IXTRS_EXECUTE_OP_FAIL, MB_ICONEXCLAMATION); + } + } + document.UpdateAllViews(nullptr); + } +} + +void EditSelectedHyperlink(OSSDoc& document) { + const auto& pict = *document.OSS()(document.selection); + if (dialog::EditHyperlink editDlg(pict.lnk); editDlg.DoModal() == IDOK) { + document.OSS().SetPictLink(pict.uid, { mfc::ToSTL(editDlg.address), mfc::ToSTL(editDlg.subAddr) }); + document.UpdateAllViews(nullptr); + } +} + +void EditActiveFilename(OSSDoc& document) { + const auto pid = document.selection; + auto& sources = document.OSS().Src(); + if (auto* doc = dynamic_cast(sources.OpenSrc(pid)); doc != nullptr) { + doc->DoFileSave(); + doc->OnCloseDocument(); + } + if (const auto* handle = sources(pid); handle == nullptr) { + ::AfxMessageBox(IXTRE_PICT_NO_SRC, MB_ICONEXCLAMATION); + } else if (handle->src != nullptr) { + ::AfxMessageBox(IXTRE_PICT_RENAME_OPENED, MB_ICONEXCLAMATION); + } else { + dialog::EditString editDlg{ mfc::ToMFC(std::filesystem::path(handle->desc.name).replace_extension("").u8string()) }; + if (editDlg.DoModal() == IDOK) { + auto newName = std::filesystem::path(mfc::ToUTF8(editDlg.resultStr)); + newName.replace_extension(mfc::ToUTF8(ExtensionFor(FileType::trs))); + sources.Rename(pid, newName.u8string()); + } + } +} + +void OpenSelectedSource(OSSDoc& document) { + const auto active = document.selection; + auto& oss = document.OSS(); + if (auto* openedDoc = dynamic_cast(oss.Src().OpenSrc(active)); + openedDoc != nullptr) { + ExteorApplication::Docs().ShowDocument(*openedDoc); + document.UpdateAllViews(nullptr); + return; + } + + if (const auto& srcName = oss.Src()(active)->desc.name; !empty(srcName)) { + const auto msg = mfc::FormatSID(IXTRE_OSS_SOURCE_UNACCESSIBLE, mfc::ToMFC(srcName).GetString()); + if (::AfxMessageBox(msg, MB_YESNO | MB_ICONEXCLAMATION) == IDYES) { + oss.Src().Discard(active); + document.UpdateAllViews(nullptr); + } + return; + } + + if (oss.Ops().HasOperation(active)) { + return; + } + + if (::AfxMessageBox(IXTRS_OSS_CREATE_NEW_FILE, MB_YESNO | MB_ICONQUESTION) == IDYES) { + const auto silence = XTROptions::App().GuardSilence(); + if (auto* newDoc = ExteorApplication::Docs().NewRSFormDoc(); + newDoc != nullptr && newDoc->DoFileSave()) { + oss.Src().ConnectSrc2Pict(active, *newDoc); + newDoc->UpdateAllViews(nullptr); + } + document.UpdateAllViews(nullptr); + } +} + +void EraseSelected(OSSDoc& document) { + const auto active = document.selection; + auto& oss = document.OSS(); + if (!std::empty(oss.Graph().ChildrenOf(active))) { + ::AfxMessageBox(IXTRS_ERASE_PICT_FAIL, MB_ICONEXCLAMATION); + return; + } + if (std::empty(*oss.Src()(active)) || + ::AfxMessageBox(IXTRS_ERASE_SRC_CONFIRM, MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2) == IDYES) { + if (oss.Erase(active)) { + document.UpdateAllViews(nullptr); + } + } +} + +void DiscardSelectedSource(OSSDoc& document) { + if (::AfxMessageBox(IXTRS_DISCARD_SRC_CONFIRM, MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2) != IDYES) { + return; + } + document.OSS().Src().Discard(document.selection); + document.UpdateAllViews(nullptr); +} + +void RunSelectedOperation(OSSDoc& document) { + if (document.DoFileSave() + && RunOperation(document.OSS(), document.selection)) { + document.UpdateAllViews(nullptr); + } +} + +void AttachSourceToSelected(OSSDoc& document) { + static constexpr auto noView = FALSE; + const auto active = document.selection; + auto& sources = document.OSS().Src(); + + if (!std::empty(*sources(active)) && + ::AfxMessageBox(IXTRS_IS_CHANGE_TRS_NAME, MB_YESNOCANCEL | MB_ICONQUESTION | MB_DEFBUTTON2) != IDYES) { + return; + } + + const auto srcPath = std::filesystem::path(mfc::ToUTF8(PromptForSourceFile(mfc::ToMFC(sources.ossDomain)))); + if (srcPath.empty()) { + return; + } + const auto newPath = std::filesystem::path(sources.ossDomain) / srcPath.filename(); + if (srcPath != newPath && !std::filesystem::copy_file(srcPath, newPath)) { + ::AfxMessageBox(IXTRE_FILE_MOVE, MB_ICONERROR); + return; + } + + const auto silence = XTROptions::App().GuardSilence(); + const auto mfcPath = mfc::ToMFC(newPath.u8string()); + if (auto* newDoc = ExteorApplication::Docs().OpenRSFormDoc(mfcPath, noView); + newDoc != nullptr) { + if (sources.ConnectPict2Src(active, *newDoc)) { + newDoc->OnSaveDocument(mfcPath); + ExteorApplication::Docs().ShowDocument(*newDoc); + } else { + ::AfxMessageBox(IXTRE_OSS_ASSOSIATION, MB_ICONERROR); + newDoc->OnCloseDocument(); + } + } + document.UpdateAllViews(nullptr); +} + +void EditOSSFilename(OSSDoc& document) { + const auto oldPath = std::filesystem::path(mfc::ToUTF8(document.GetPathName())); + const auto oldName = oldPath.filename(); + dialog::EditString editDlg{ mfc::ToMFC(oldPath.filename().replace_extension("").u8string()) }; + if (editDlg.DoModal() != IDOK) { + return; + } + auto newName = std::filesystem::path(mfc::ToUTF8(editDlg.resultStr)).filename(); + newName.replace_extension(mfc::ToUTF8(ExtensionFor(FileType::oss))); + if (newName == oldName) { + return; + } + const auto newPath = std::filesystem::path(document.OSS().Src().ossDomain) / newName; + + const auto newMfcPath = mfc::ToMFC(newPath.u8string()); + const auto oldMfcPath = mfc::ToMFC(oldPath.u8string()); + document.OnSaveDocument(oldMfcPath); + g_Exteor.RemoveMRUItem(oldMfcPath); + + std::filesystem::rename(oldPath, newPath); + + document.SetPathName(newMfcPath); + document.UpdateAllViews(nullptr); +} + +void EditComment(OSSDoc& document) { + dialog::EditComment editDlg(mfc::ToMFC(document.OSS().comment), mfc::LoadSID(IXTRS_COMMENT)); + if (editDlg.DoModal() == IDOK) { + document.OSS().comment = mfc::ToSTL(editDlg.comment); + document.UpdateAllViews(nullptr); + } +} + +void RerunAllOperations(OSSDoc& document) { + if (!document.DoFileSave()) { + return; + } + const auto userChoice = ::AfxMessageBox(mfc::LoadSID(IXTRS_OSS_RUNALL_PROMPT), + MB_YESNOCANCEL | MB_ICONQUESTION | MB_DEFBUTTON1); + if (userChoice == IDCANCEL) { + return; + } else if (userChoice == IDYES && !CreateOssArchive(document).has_value()) { + return; + } + document.OSS().Ops().ExecuteAll(); + document.DoFileSave(); + document.UpdateAllViews(nullptr); + ::AfxMessageBox(IXTRS_OSS_RUNALL_SUCCESS, MB_ICONINFORMATION); +} + +void BackupOSS(const OSSDoc& document) { + if (const auto path = CreateOssArchive(document); path.has_value()) { + ::AfxMessageBox(mfc::FormatSID(IXTRS_OSS_ARCH_SUCCESS, path.value().GetString()), MB_ICONEXCLAMATION); + ::ShellExecuteW(nullptr, L"open", path.value(), nullptr, nullptr, SW_SHOW); + } +} + +void StandaloneSynthes(const ccl::ops::Type type) { + dialog::SynthesUI opSheet(type); + if (opSheet.DoModal() != IDCANCEL) { + ccl::ops::BinarySynthes operation(*opSheet.operand1, *opSheet.operand2, opSheet.equations); + const auto silence = XTROptions::App().GuardSilence(); + if (auto result = operation.Execute(); result == nullptr) { + ::AfxMessageBox(IXTRE_SYNT, MB_ICONERROR); + } else { + auto* newDoc = ExteorApplication::Docs().NewRSFormDoc(*result); + newDoc->Schema().title = mfc::ToSTL(opSheet.title); + newDoc->Schema().alias = mfc::ToSTL(opSheet.alias); + newDoc->UpdateAllViews(nullptr); + } + } +} + +void ExecuteRelation(const ccl::semantic::RSForm& schema, const EntityUID target) { + using ccl::ops::OpRelativation; + + const auto basicNames = [&] { + std::string names{}; + for (const auto entity : ccl::semantic::FilterCst(schema.Core(), CstType::base)) { + if (entity != target) { + names = names + ' ' + schema.GetRS(entity).alias + ','; + } + } + return names; + }(); + dialog::EditString dlg(mfc::ToMFC(basicNames), mfc::LoadSID(IXTRS_LABEL_IGNORE_RELATION)); + if (dlg.DoModal() != IDOK) { + return; + } + const auto cstFromExpr = ccl::rslang::ExtractUGlobals(mfc::ToSTL(dlg.resultStr)); + SetOfEntities ignore{}; + ignore.reserve(size(cstFromExpr)); + for (const auto& name : cstFromExpr) { + if (auto uid = schema.Core().FindAlias(name); uid.has_value()) { + ignore.emplace(uid.value()); + } + } + if (!OpRelativation::IsCorrectlyDefined(schema, target, ignore)) { + ::AfxMessageBox(IXTRE_RELATE_RS, MB_ICONERROR); + } else { + OpRelativation operation(schema, target, ignore); + ExteorApplication::Docs().NewRSFormDoc(*operation.Execute()); + } +} + +void SpawnModelDocument(const RSForm& schema) { + const auto silence = XTROptions::App().GuardSilence(); + auto& newDoc = *ExteorApplication::Docs().NewRSModelDoc(); + newDoc.Model().alias = schema.alias; + newDoc.Model().title = schema.title; + newDoc.Model().comment = schema.comment; + for (const auto entity : schema.List()) { + newDoc.Model().InsertCopy(entity, schema.Core()); + } + newDoc.SetModifiedFlag(TRUE); + newDoc.UpdateAllViews(nullptr); +} + +void SpawnSchemaDocument(const RSModel& model) { + const auto silence = XTROptions::App().GuardSilence(); + auto& newDoc = *ExteorApplication::Docs().NewRSFormDoc(); + newDoc.Schema().alias = model.alias; + newDoc.Schema().title = model.title; + newDoc.Schema().comment = model.comment; + for (const auto entity : model.List()) { + newDoc.Schema().InsertCopy(entity, model.Core()); + } + newDoc.SetModifiedFlag(TRUE); + newDoc.UpdateAllViews(nullptr); +} + +void FollowHyperlink(const CString address, const CString subaddress) { + static constexpr auto EXECUTE_OK = 32ULL; + if (ConfirmURL(address)) { + if (reinterpret_cast(::ShellExecuteW(nullptr, L"open", address, subaddress, nullptr, SW_SHOW)) < EXECUTE_OK) { + // Note: see ShellExecute docs, return value should be cast to int - error return code + ::AfxMessageBox(mfc::FormatSID(IXTRE_HYPERLINK_FOLLOW, address.GetString()), MB_ICONERROR); + } + } +} + +} // namespace xtr::proc \ No newline at end of file diff --git a/src/xtrServices.cpp b/src/xtrServices.cpp new file mode 100644 index 0000000..a981be9 --- /dev/null +++ b/src/xtrServices.cpp @@ -0,0 +1,16 @@ +#include "stdafx.h" + +#include "xtr/xtrServices.h" + +namespace xtr { + +void Global::SetMessageManager(std::unique_ptr newMessager) noexcept { + messager = std::move(newMessager); +} + +Global& Global::Instance() noexcept { + static Global instance{}; + return instance; +} + +} // namespace xtr diff --git a/test/Data/FileVers/oss/r1553/Machine.oss b/test/Data/FileVers/oss/r1553/Machine.oss new file mode 100644 index 0000000..9ab7c4f Binary files /dev/null and b/test/Data/FileVers/oss/r1553/Machine.oss differ diff --git a/test/Data/FileVers/oss/r1553/МО1-2.trs b/test/Data/FileVers/oss/r1553/МО1-2.trs new file mode 100644 index 0000000..cf83f71 Binary files /dev/null and b/test/Data/FileVers/oss/r1553/МО1-2.trs differ diff --git a/test/Data/FileVers/oss/r1553/МО1-3.trs b/test/Data/FileVers/oss/r1553/МО1-3.trs new file mode 100644 index 0000000..f306c0f Binary files /dev/null and b/test/Data/FileVers/oss/r1553/МО1-3.trs differ diff --git a/test/Data/FileVers/oss/r1553/МО1.trs b/test/Data/FileVers/oss/r1553/МО1.trs new file mode 100644 index 0000000..e96eb60 Binary files /dev/null and b/test/Data/FileVers/oss/r1553/МО1.trs differ diff --git a/test/Data/FileVers/oss/r1800/Machine.oss b/test/Data/FileVers/oss/r1800/Machine.oss new file mode 100644 index 0000000..d43835f Binary files /dev/null and b/test/Data/FileVers/oss/r1800/Machine.oss differ diff --git a/test/Data/FileVers/oss/r1800/МО1-2.trs b/test/Data/FileVers/oss/r1800/МО1-2.trs new file mode 100644 index 0000000..6136276 Binary files /dev/null and b/test/Data/FileVers/oss/r1800/МО1-2.trs differ diff --git a/test/Data/FileVers/oss/r1800/МО1-3.trs b/test/Data/FileVers/oss/r1800/МО1-3.trs new file mode 100644 index 0000000..32e94ee Binary files /dev/null and b/test/Data/FileVers/oss/r1800/МО1-3.trs differ diff --git a/test/Data/FileVers/oss/r1800/МО1.trs b/test/Data/FileVers/oss/r1800/МО1.trs new file mode 100644 index 0000000..049c24d Binary files /dev/null and b/test/Data/FileVers/oss/r1800/МО1.trs differ diff --git a/test/Data/FileVers/oss/r202205/Machine.oss b/test/Data/FileVers/oss/r202205/Machine.oss new file mode 100644 index 0000000..73f631d Binary files /dev/null and b/test/Data/FileVers/oss/r202205/Machine.oss differ diff --git a/test/Data/FileVers/oss/r202205/МО1-2.trs b/test/Data/FileVers/oss/r202205/МО1-2.trs new file mode 100644 index 0000000..3567808 Binary files /dev/null and b/test/Data/FileVers/oss/r202205/МО1-2.trs differ diff --git a/test/Data/FileVers/oss/r202205/МО1-3.trs b/test/Data/FileVers/oss/r202205/МО1-3.trs new file mode 100644 index 0000000..9a4bef7 Binary files /dev/null and b/test/Data/FileVers/oss/r202205/МО1-3.trs differ diff --git a/test/Data/FileVers/oss/r202205/МО1.trs b/test/Data/FileVers/oss/r202205/МО1.trs new file mode 100644 index 0000000..034cf35 Binary files /dev/null and b/test/Data/FileVers/oss/r202205/МО1.trs differ diff --git a/test/Data/FileVers/oss/r47101200/Machine.oss b/test/Data/FileVers/oss/r47101200/Machine.oss new file mode 100644 index 0000000..e4d7cd2 Binary files /dev/null and b/test/Data/FileVers/oss/r47101200/Machine.oss differ diff --git a/test/Data/FileVers/oss/r47101200/МО1-2.trs b/test/Data/FileVers/oss/r47101200/МО1-2.trs new file mode 100644 index 0000000..c1afb91 Binary files /dev/null and b/test/Data/FileVers/oss/r47101200/МО1-2.trs differ diff --git a/test/Data/FileVers/oss/r47101200/МО1-3.trs b/test/Data/FileVers/oss/r47101200/МО1-3.trs new file mode 100644 index 0000000..ee6c17e Binary files /dev/null and b/test/Data/FileVers/oss/r47101200/МО1-3.trs differ diff --git a/test/Data/FileVers/oss/r47101200/МО1.trs b/test/Data/FileVers/oss/r47101200/МО1.trs new file mode 100644 index 0000000..37a9031 Binary files /dev/null and b/test/Data/FileVers/oss/r47101200/МО1.trs differ diff --git a/test/Data/FileVers/rsm/r1438.rsm b/test/Data/FileVers/rsm/r1438.rsm new file mode 100644 index 0000000..6055438 Binary files /dev/null and b/test/Data/FileVers/rsm/r1438.rsm differ diff --git a/test/Data/FileVers/rsm/r1800.rsm b/test/Data/FileVers/rsm/r1800.rsm new file mode 100644 index 0000000..aa627bc Binary files /dev/null and b/test/Data/FileVers/rsm/r1800.rsm differ diff --git a/test/Data/FileVers/rsm/r202205.rsm b/test/Data/FileVers/rsm/r202205.rsm new file mode 100644 index 0000000..73c4520 Binary files /dev/null and b/test/Data/FileVers/rsm/r202205.rsm differ diff --git a/test/Data/FileVers/rsm/r47101200.rsm b/test/Data/FileVers/rsm/r47101200.rsm new file mode 100644 index 0000000..c6dc227 Binary files /dev/null and b/test/Data/FileVers/rsm/r47101200.rsm differ diff --git a/test/Data/FileVers/trs/ext3-2000.trs b/test/Data/FileVers/trs/ext3-2000.trs new file mode 100644 index 0000000..ca5e0b0 Binary files /dev/null and b/test/Data/FileVers/trs/ext3-2000.trs differ diff --git a/test/Data/FileVers/trs/ext3_1997.trs b/test/Data/FileVers/trs/ext3_1997.trs new file mode 100644 index 0000000..7bf20b6 Binary files /dev/null and b/test/Data/FileVers/trs/ext3_1997.trs differ diff --git a/test/Data/FileVers/trs/ext4-2012.trs b/test/Data/FileVers/trs/ext4-2012.trs new file mode 100644 index 0000000..ec775fa Binary files /dev/null and b/test/Data/FileVers/trs/ext4-2012.trs differ diff --git a/test/Data/FileVers/trs/ext4-2012_empty.trs b/test/Data/FileVers/trs/ext4-2012_empty.trs new file mode 100644 index 0000000..3fb8018 Binary files /dev/null and b/test/Data/FileVers/trs/ext4-2012_empty.trs differ diff --git a/test/Data/FileVers/trs/r1092.trs b/test/Data/FileVers/trs/r1092.trs new file mode 100644 index 0000000..e1e9155 Binary files /dev/null and b/test/Data/FileVers/trs/r1092.trs differ diff --git a/test/Data/FileVers/trs/r1438.trs b/test/Data/FileVers/trs/r1438.trs new file mode 100644 index 0000000..d008ab0 Binary files /dev/null and b/test/Data/FileVers/trs/r1438.trs differ diff --git a/test/Data/FileVers/trs/r1800.trs b/test/Data/FileVers/trs/r1800.trs new file mode 100644 index 0000000..5bbc1ac Binary files /dev/null and b/test/Data/FileVers/trs/r1800.trs differ diff --git a/test/Data/FileVers/trs/r202205.trs b/test/Data/FileVers/trs/r202205.trs new file mode 100644 index 0000000..eef0c86 Binary files /dev/null and b/test/Data/FileVers/trs/r202205.trs differ diff --git a/test/Data/FileVers/trs/r47101200.trs b/test/Data/FileVers/trs/r47101200.trs new file mode 100644 index 0000000..c4d552f Binary files /dev/null and b/test/Data/FileVers/trs/r47101200.trs differ diff --git a/test/Data/sample_module.py b/test/Data/sample_module.py new file mode 100644 index 0000000..347a8ff --- /dev/null +++ b/test/Data/sample_module.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +state_variable: int = 42 + +def get_state() -> int: + return state_variable + +def increment(number: int) -> int: + return number + 1 + +def add_abc(text: str) -> str: + return text + 'abc' \ No newline at end of file diff --git a/test/Data/Тест_Модели/TestCalculate.rsm b/test/Data/Тест_Модели/TestCalculate.rsm new file mode 100644 index 0000000..2945315 Binary files /dev/null and b/test/Data/Тест_Модели/TestCalculate.rsm differ diff --git a/test/Mock/mockDocuments.cpp b/test/Mock/mockDocuments.cpp new file mode 100644 index 0000000..074f41b --- /dev/null +++ b/test/Mock/mockDocuments.cpp @@ -0,0 +1,202 @@ +#include "stdafx.h" + +#include "mockDocuments.h" +#include "xtr\io\TRSLegacyLoader.h" +#include "xtr\io\RSMLegacyLoader.h" +#include "xtr\io\OSSLegacyLoader.h" + +using RSForm = ccl::semantic::RSForm; +using RSModel = ccl::semantic::RSModel; +using OSSchema = ccl::oss::OSSchema; + +std::vector GetFilesIn(const CString directory) { + auto dir = xtr::mfc::ToSTL(LocalPathToGlobal(directory)); + std::vector files{}; + for (const auto& file : std::filesystem::directory_iterator(dir)) { + files.emplace_back(xtr::mfc::ToMFC(file.path().u8string())); + } + return files; +} + +CString LocalPathToGlobal(const CString local) { + CString currentDir{}; + ::GetCurrentDirectory(MAX_PATH, currentDir.GetBuffer(MAX_PATH)); + currentDir.ReleaseBuffer(); + auto endPos = currentDir.Find(L"\\test"); + currentDir = currentDir.Left(endPos + 5); + currentDir.Append(L"\\"); + currentDir.Append(local); + return currentDir; +} + +MockArchive::~MockArchive() { + CloseFile(); +} + +xtr::io::CArchiveAdapter MockArchive::GenerateAdapter() noexcept { + return xtr::io::CArchiveAdapter{ *archive }; +} + +bool MockArchive::LoadFile(const CString path, const bool toEdit) { + CloseFile(); + file = std::make_unique(); + const UINT fileFlags = toEdit ? CFile::modeCreate | CFile::modeWrite | CFile::shareExclusive : CFile::modeRead | CFile::shareDenyWrite; + if (!file->Open(path, fileFlags)) { + file = nullptr; + return false; + } + const UINT archiveFlags = toEdit ? CArchive::store : CArchive::load; + archive = std::make_unique(file.get(), archiveFlags); + return true; +} + +void MockArchive::CloseFile() { + if (file == nullptr) { + return; + } + archive->Close(); + file->Close(); + archive = nullptr; + file = nullptr; +} + +bool MockRSFormDoc::LoadFrom(const CString path) { + MockArchive archive{}; + if (archive.LoadFile(path)) { + auto adapter = archive.GenerateAdapter(); + if (LegacyLoad(adapter)) { + return true; + } + archive.CloseFile(); + } + return LoadJSON(xtr::mfc::ToUTF8(path)); +} + +bool MockRSFormDoc::SaveTo(const CString path) { + return SaveJSON(xtr::mfc::ToUTF8(path)); +} + +JSON MockRSFormDoc::ExtractData() const { + auto result = JSON(*schema); + result["claimed"] = isClaimed; + result["selection"] = selection; + return result; +} + +bool MockRSFormDoc::LoadData(const JSON& object) { + schema = std::make_unique(); + selection.clear(); + object.get_to(*schema); + object.at("selection").get_to(selection); + object.at("claimed").get_to(isClaimed); + version = static_cast(object.at("version").get()); + return true; +} + +bool MockRSFormDoc::LegacyLoad(xtr::io::CArchiveAdapter& archive) { + schema = std::make_unique(); + selection.clear(); + xtr::io::TRSLegacyLoader loader(archive, *schema); + try { + loader.LoadVersion(); + version = loader.version; + loader.DoLoad(); + selection = loader.selection; + isClaimed = loader.isClaimed; + } catch (...) { + return false; + } + return true; +} + +bool MockRSModelDoc::LoadFrom(const CString path) { + MockArchive archive{}; + if (archive.LoadFile(path)) { + auto adapter = archive.GenerateAdapter(); + if (LegacyLoad(adapter)) { + return true; + } + archive.CloseFile(); + } + return LoadJSON(xtr::mfc::ToUTF8(path)); +} + +bool MockRSModelDoc::SaveTo(const CString path) { + return SaveJSON(xtr::mfc::ToUTF8(path)); +} + +JSON MockRSModelDoc::ExtractData() const { + auto result = JSON(*model); + result["selection"] = selection; + return result; +} + +bool MockRSModelDoc::LoadData(const JSON& object) { + model = std::make_unique(); + selection.clear(); + object.get_to(*model); + object.at("selection").get_to(selection); + version = static_cast(object.at("version").get()); + return true; +} + +bool MockRSModelDoc::LegacyLoad(xtr::io::CArchiveAdapter& archive) { + model = std::make_unique(); + selection.clear(); + xtr::io::RSMLegacyLoader loader(archive, *model); + try { + loader.LoadVersion(); + version = loader.version; + loader.DoLoad(); + selection = loader.selection; + } catch (...) { + return false; + } + return true; +} + +bool MockOSSDoc::LoadFrom(const CString path) { + MockArchive archive{}; + if (archive.LoadFile(path)) { + auto adapter = archive.GenerateAdapter(); + if (LegacyLoad(adapter)) { + return true; + } + archive.CloseFile(); + } + return LoadJSON(xtr::mfc::ToUTF8(path)); +} + +bool MockOSSDoc::SaveTo(const CString path) { + return SaveJSON(xtr::mfc::ToUTF8(path)); +} + +JSON MockOSSDoc::ExtractData() const { + auto result = JSON(*oss); + result["selection"] = selection; + return result; +} + +bool MockOSSDoc::LoadData(const JSON& object) { + oss = std::make_unique(); + selection = 0; + object.get_to(*oss); + object.at("selection").get_to(selection); + version = static_cast(object.at("version").get()); + return true; +} + +bool MockOSSDoc::LegacyLoad(xtr::io::CArchiveAdapter& archive) { + oss = std::make_unique(); + selection = 0; + xtr::io::OSSLegacyLoader loader(archive, *oss); + try { + loader.LoadVersion(); + version = loader.version; + loader.DoLoad(); + selection = loader.selection; + } catch (...) { + return false; + } + return true; +} \ No newline at end of file diff --git a/test/Mock/mockDocuments.h b/test/Mock/mockDocuments.h new file mode 100644 index 0000000..7c66385 --- /dev/null +++ b/test/Mock/mockDocuments.h @@ -0,0 +1,70 @@ +#pragma once + +#include "xtr\core\SelectableSet.h" +#include "xtr\doc\FileVersions.hpp" +#include "xtr\io\SerializationManager.hpp" + +#include "ccl\semantic\RSForm.h" + +std::vector GetFilesIn(const CString directory); +CString LocalPathToGlobal(CString local); + +class MockArchive { + std::unique_ptr file{ nullptr }; + std::unique_ptr archive{ nullptr }; + +public: + MockArchive() = default; + ~MockArchive(); + +public: + xtr::io::CArchiveAdapter GenerateAdapter() noexcept; + bool LoadFile(CString path, bool toEdit = false); + void CloseFile(); +}; + +struct MockRSFormDoc : public xtr::io::MFCSerializable { + xtr::TRSVersion version{ xtr::TRSVersion::old }; + std::unique_ptr schema{ std::make_unique() }; + SetOfEntities selection{}; + bool isClaimed{ false }; + + MockRSFormDoc() = default; + + bool LoadFrom(CString path); + bool SaveTo(CString path); + + JSON ExtractData() const override; + bool LoadData(const JSON& object) override; + bool LegacyLoad(xtr::io::CArchiveAdapter& archive) override; +}; + +struct MockRSModelDoc : public xtr::io::MFCSerializable { + xtr::RSMVersion version{ xtr::RSMVersion::old }; + std::unique_ptr model{ std::make_unique() }; + SetOfEntities selection{}; + + MockRSModelDoc() = default; + + bool LoadFrom(CString path); + bool SaveTo(CString path); + + JSON ExtractData() const override; + bool LoadData(const JSON& object) override; + bool LegacyLoad(xtr::io::CArchiveAdapter& archive) override; +}; + +struct MockOSSDoc : public xtr::io::MFCSerializable { + xtr::OSSVersion version{ xtr::OSSVersion::old }; + std::unique_ptr oss{ std::make_unique() }; + ccl::oss::PictID selection{ 0 }; + + MockOSSDoc() = default; + + bool LoadFrom(CString path); + bool SaveTo(CString path); + + JSON ExtractData() const override; + bool LoadData(const JSON& object) override; + bool LegacyLoad(xtr::io::CArchiveAdapter& archive) override; +}; \ No newline at end of file diff --git a/test/Mock/mockMessageManager.hpp b/test/Mock/mockMessageManager.hpp new file mode 100644 index 0000000..b468298 --- /dev/null +++ b/test/Mock/mockMessageManager.hpp @@ -0,0 +1,42 @@ +#include "xtr/xtrServices.h" + +struct Message { + uint32_t type{}; + std::variant msg{ 0U }; + + bool operator==(const Message& rhs) const noexcept { + return type == rhs.type && msg == rhs.msg; + } + bool operator!=(const Message& rhs) const noexcept { + return !(*this == rhs); + } +}; + +class mockMessenger final : public xtr::MessageManager { +public: + std::vector messages; + +public: + void Clear() noexcept { messages.clear(); } + +private: + uint32_t ShowMessage(const CString text, const uint32_t type) override { + messages.emplace_back(Message{ type, text }); + return 0; + } + uint32_t ShowMessage(const uint32_t messageID, const uint32_t type) override { + messages.emplace_back(Message{ type, messageID }); + return 0; + } +}; + +void ExpectMessage(Message expected, std::function functionCall) { + xtr::Global::Instance().SetMessageManager(std::make_unique()); + + auto& msger = dynamic_cast(xtr::Global::Msg()); + functionCall(); + ASSERT_EQ(1U, size(msger.messages)); + EXPECT_EQ(expected, *begin(msger.messages)); + + xtr::Global::Instance().SetMessageManager(std::make_unique()); +} \ No newline at end of file diff --git a/test/Mock/mockTermContext.hpp b/test/Mock/mockTermContext.hpp new file mode 100644 index 0000000..fd26185 --- /dev/null +++ b/test/Mock/mockTermContext.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include "ccl/lang/LexicalTerm.h" +#include "ccl/lang/EntityTermContext.hpp" + +class MockContext : public ccl::lang::EntityTermContext { +private: + std::unordered_map terms{}; + +public: + void Clear() noexcept { terms.clear(); } + void Insert(const std::string& entity, const ccl::lang::LexicalTerm& term) { + terms.emplace(std::pair{ entity , term }); + } + + bool Contains(const std::string& entity) const override { + return terms.count(entity) > 0; + } + const ccl::lang::LexicalTerm* At(const std::string& entity) const override { + if (!Contains(entity)) { + return nullptr; + } else { + return &terms.at(entity); + } + } +}; \ No newline at end of file diff --git a/test/Mock/mockTextEdit.hpp b/test/Mock/mockTextEdit.hpp new file mode 100644 index 0000000..c2a9a06 --- /dev/null +++ b/test/Mock/mockTextEdit.hpp @@ -0,0 +1,90 @@ +#pragma once + +#include "xtr/viewmodel/vmTextEdit.h" + +#include + +class MockTextEditCtrl : public xtr::viewmodel::ITextEdit { +public: + struct rangeComparator { + constexpr bool operator()(const xtr::viewmodel::HighlightItem& rng1, + const xtr::viewmodel::HighlightItem& rng2) const noexcept { + return rng1.rng.start < rng2.rng.start; + } + }; + +public: + CString text{}; + std::set items{}; + +private: + [[nodiscard]] CString GetText() const override { + return text; + } + + void SetText(const CString newText) override { + text = newText; + items.clear(); + } + + void ReplaceRange(const StrRange range, const CString replacement) override { + CString newText{}; + if (range.start > 0) { + newText.Append(text.Left(range.start - 1)); + } + newText.Append(replacement); + if (range.finish < text.GetLength()) { + newText.Append(text.Right(text.GetLength() - range.finish)); + } + text = newText; + + std::set newItems{}; + const auto shift = replacement.GetLength() - range.length(); + for (auto refIt = begin(items); refIt != end(items); ++refIt) { + const auto& refPosition = refIt->rng; + if (refPosition.Meets(range) || refPosition.IsBefore(range)) { + newItems.emplace(*refIt); + } else if (range.Meets(refPosition) || refPosition.IsAfter(range)) { + auto newRef = *refIt; + newRef.rng.Shift(shift); + newItems.emplace(newRef); + } else if (range.Contains(refPosition)) { + continue; + } else { + auto newRef = *refIt; + if (refPosition.start < range.start) { + newRef.rng.SetLength(refPosition.length() - refPosition.Intersect(range)->length()); + } else { + newRef.rng = StrRange::FromLength(range.start, std::max(0, + refPosition.length() - refPosition.Intersect(range)->length())); + } + newItems.emplace(newRef); + } + } + items = newItems; + } + + void Highlight(xtr::viewmodel::HighlightItem item) override { + items.insert(item); + } + + [[nodiscard]] std::optional NextHighlighted(const StrPos start) override { + if (start == 0) { + if (empty(items)) { + return std::nullopt; + } else { + return *begin(items); + } + } + + if (auto it = std::find_if(begin(items), end(items), + [&](const xtr::viewmodel::HighlightItem& item) { return item.rng.start == start; }); + it == end(items)) { + return std::nullopt; + } else if (++it; it == end(items)) { + return std::nullopt; + } else { + return *it; + } + } +}; \ No newline at end of file diff --git a/test/XTRCoreTest.vcxproj b/test/XTRCoreTest.vcxproj new file mode 100644 index 0000000..4a46958 --- /dev/null +++ b/test/XTRCoreTest.vcxproj @@ -0,0 +1,285 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {576d16b8-96bf-4b5a-8b09-e1916375e34f} + Win32Proj + 10.0 + Application + v143 + Unicode + + + + false + true + false + + + false + true + false + + + false + true + false + + + false + true + false + + + + + + + + + + + + + + + + + + + + + + build\x86\$(Configuration)\ + build\x86\$(Configuration)\ + false + + + build\x64\$(Configuration)\ + build\x64\$(Configuration)\ + false + + + build\x86\$(Configuration)\ + build\x86\$(Configuration)\ + false + + + build\x64\$(Configuration)\ + build\x64\$(Configuration)\ + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + {1cbf9ff9-2fa7-495b-bb7d-b6ee85aaab48} + + + + + + + Use + stdafx.h + Disabled + POCO_STATIC;_TESTING;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + true + $(IntDir)obj\ + Mock;./;..\include;..\import\include;..\..\ConceptCore\output\include;..\..\OfficeOLE\include;C:\Program Files (x86)\Python312-32\include;%(AdditionalIncludeDirectories) + stdcpplatest + false + + + DebugFull + Console + ConceptCoreLibraryd.lib;RSlangd.lib;cclGraphd.lib;cclLangd.lib;iphlpapi.lib;%(AdditionalDependencies) + false + C:\Program Files (x86)\Python312-32\libs;..\..\ConceptCore\output\lib\x86;..\..\OfficeOLE\output\lib\x86;%(AdditionalLibraryDirectories) + /ignore:4099 %(AdditionalOptions) + + + xcopy /y /s /q /i "..\import\cctext" "$(OutDir)\cctext\" +copy "Data\sample_module.py" "$(OutDir)sample_module.py" +copy "C:\Program Files (x86)\Python312-32\Python312_d.dll" "$(OutDir)" +copy "C:\Program Files (x86)\Python312-32\Python312_d.pdb" "$(OutDir)" + + + + + Use + stdafx.h + Disabled + POCO_STATIC;_TESTING;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level4 + true + $(IntDir)obj\ + Mock;./;..\include;..\header;..\import\include;..\..\ConceptCore\output\include;..\..\OfficeOLE\include;C:\Program Files\Python312\include;%(AdditionalIncludeDirectories) + stdcpplatest + false + + + DebugFull + Console + ConceptCoreLibraryd.lib;RSlangd.lib;cclGraphd.lib;cclLangd.lib;iphlpapi.lib;%(AdditionalDependencies) + false + C:\Program Files\Python312\libs;..\..\ConceptCore\output\lib\x64;..\..\OfficeOLE\output\lib\x64;%(AdditionalLibraryDirectories) + /ignore:4099 %(AdditionalOptions) + + + xcopy /y /s /q /i "..\import\cctext" "$(OutDir)\cctext\" +copy "Data\sample_module.py" "$(OutDir)sample_module.py" + + + + + Use + stdafx.h + POCO_STATIC;_TESTING;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level4 + ProgramDatabase + false + true + $(IntDir)obj\ + Mock;./;..\include;..\header;..\import\include;..\import\include;..\..\ConceptCore\output\include;..\..\OfficeOLE\include;C:\Program Files (x86)\Python312-32\include;%(AdditionalIncludeDirectories) + stdcpplatest + false + + + DebugFull + Console + true + true + ConceptCoreLibrary.lib;RSlang.lib;cclGraph.lib;cclLang.lib;iphlpapi.lib;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + C:\Program Files (x86)\Python312-32\libs;..\..\ConceptCore\output\lib\x86;..\..\OfficeOLE\output\lib\x86;%(AdditionalLibraryDirectories) + /ignore:4099 %(AdditionalOptions) + + + xcopy /y /s /q /i "..\import\cctext" "$(OutDir)\cctext\" +copy "Data\sample_module.py" "$(OutDir)sample_module.py" +copy "C:\Program Files (x86)\Python312-32\Python312.dll" "$(OutDir)" +copy "C:\Program Files (x86)\Python312-32\Python312.pdb" "$(OutDir)" + + + + + Use + stdafx.h + POCO_STATIC;_TESTING;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level4 + ProgramDatabase + false + true + $(IntDir)obj\ + Mock;./;..\include;..\header;..\import\include;..\import\include;..\..\ConceptCore\output\include;..\..\OfficeOLE\include;C:\Program Files\Python312\include;%(AdditionalIncludeDirectories) + stdcpplatest + false + + + DebugFull + Console + true + true + ConceptCoreLibrary.lib;RSlang.lib;cclGraph.lib;cclLang.lib;iphlpapi.lib;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + false + C:\Program Files\Python312\libs;..\..\ConceptCore\output\lib\x64;..\..\OfficeOLE\output\lib\x64;%(AdditionalLibraryDirectories) + /ignore:4099 %(AdditionalOptions) + + + xcopy /y /s /q /i "..\import\cctext" "$(OutDir)\cctext\" +copy "Data\sample_module.py" "$(OutDir)sample_module.py" + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/XTRCoreTest.vcxproj.filters b/test/XTRCoreTest.vcxproj.filters new file mode 100644 index 0000000..9335856 --- /dev/null +++ b/test/XTRCoreTest.vcxproj.filters @@ -0,0 +1,141 @@ + + + + + core + + + core + + + + core + + + viewmodel + + + common + + + common + + + common + + + common + + + src + + + src + + + src + + + src + + + core + + + doc + + + io + + + mock + + + io + + + io + + + src + + + + + + mock + + + mock + + + mock + + + core + + + viewmodel + + + core + + + doc + + + doc + + + io + + + io + + + mock + + + io + + + io + + + core + + + io + + + core + + + + + + + + + {d6ebd37d-fdec-47d0-87a2-fe26fa20b543} + + + {9798f5bb-d07b-4b31-82d3-68c81986beea} + + + {a6b4db05-1be2-49e7-9ff5-1454e116962a} + + + {e9ca4125-8546-45f0-82a1-a96148f47b8e} + + + {9f1c5ce8-c44b-4246-b7fa-34083c8e889a} + + + {8de04716-0d7c-479c-93c8-eb1bcbf02904} + + + {82a4cf9f-6aff-4611-aee6-ef76d9802efb} + + + \ No newline at end of file diff --git a/test/packages.config b/test/packages.config new file mode 100644 index 0000000..9d10007 --- /dev/null +++ b/test/packages.config @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/src/testDocuments.cpp b/test/src/testDocuments.cpp new file mode 100644 index 0000000..94931d3 --- /dev/null +++ b/test/src/testDocuments.cpp @@ -0,0 +1,185 @@ +#include "stdafx.h" + +#include "mockDocuments.h" +#include "xtr\mfcHelper.h" + +class UTDocuments : public ::testing::Test { +protected: + void SetUp() override {} + + void TearDown() override {} +}; + +TEST_F(UTDocuments, RSFormSaveLoad) { + const auto filePath = ::LocalPathToGlobal(LR"(Data\.trs)"); + + MockRSFormDoc rsdoc{}; + auto& schema = *rsdoc.schema; + schema.title = "SaveLoad and some other text"; + schema.alias = "short"; + schema.comment = "comment"; + const auto x1 = schema.Emplace(ccl::semantic::CstType::base); + schema.SetExpressionFor(x1, "test"); + schema.Mods().Track(x1); + ASSERT_TRUE(rsdoc.SaveTo(filePath)); + + MockRSFormDoc loadedDoc{}; + ASSERT_TRUE(loadedDoc.LoadFrom(filePath)); + std::filesystem::remove(xtr::mfc::ToUTF8(filePath)); + + const auto& loadedSchema = *loadedDoc.schema; + EXPECT_EQ(schema.title, loadedSchema.title); + EXPECT_EQ(schema.alias, loadedSchema.alias); + EXPECT_EQ(schema.comment, loadedSchema.comment); + + EXPECT_TRUE(loadedSchema.Contains(x1)); + EXPECT_EQ(schema.GetRS(x1).alias, loadedSchema.GetRS(x1).alias); + EXPECT_EQ(schema.GetRS(x1).definition, loadedSchema.GetRS(x1).definition); + EXPECT_EQ(schema.Mods().IsTracking(x1), loadedSchema.Mods().IsTracking(x1)); + EXPECT_EQ(schema.GetParse(x1).status, loadedSchema.GetParse(x1).status); +} + +TEST_F(UTDocuments, RSFormLoad) { + using xtr::TRSVersion; + static const std::unordered_map fileNames{ + { "ext3_1997.trs", TRSVersion::old }, + { "ext3-2000.trs", TRSVersion::old }, + { "ext4-2012.trs", TRSVersion::old }, + { "ext4-2012_empty.trs", TRSVersion::old }, + { "r1092.trs", TRSVersion::r1092 }, + { "r1438.trs", TRSVersion::r1438 }, + { "r1800.trs", TRSVersion::r1800 }, + { "r47101200.trs", TRSVersion::r47101200 }, + { "r202205.trs", TRSVersion::r202205 } + }; + + MockRSFormDoc document{}; + for (const auto& [name, version] : fileNames) { + const CString filePath = ::LocalPathToGlobal(LR"(Data\FileVers\trs\)" + xtr::mfc::ToMFC(name)); + ASSERT_TRUE(document.LoadFrom(filePath)) << "Reading from " << name; + EXPECT_EQ(version, document.version) << "Version check for " << name; + } +} + +TEST_F(UTDocuments, RSModelLoad) { + using xtr::RSMVersion; + static const std::unordered_map fileNames{ + { "r1438.rsm", RSMVersion::r1438 }, + { "r1800.rsm", RSMVersion::r1800 }, + { "r47101200.rsm", RSMVersion::r47101200 }, + { "r202205.rsm", RSMVersion::r202205 } + }; + + MockRSModelDoc document{}; + for (const auto& [name, version] : fileNames) { + const CString filePath = ::LocalPathToGlobal(LR"(Data\FileVers\rsm\)" + xtr::mfc::ToMFC(name)); + ASSERT_TRUE(document.LoadFrom(filePath)) << "Reading from " << name; + EXPECT_EQ(version, document.version) << "Version check for " << name; + } +} + +TEST_F(UTDocuments, OSSLoad) { + using xtr::OSSVersion; + static const std::unordered_map fileNames{ + { "r1553\\Machine.oss", OSSVersion::r1553 }, + { "r1800\\Machine.oss", OSSVersion::r1800 }, + { "r47101200\\Machine.oss", OSSVersion::r47101200 }, + { "r202205\\Machine.oss", OSSVersion::r202205 } + }; + + MockOSSDoc document{}; + for (const auto& [name, version] : fileNames) { + const CString filePath = ::LocalPathToGlobal(LR"(Data\FileVers\oss\)" + xtr::mfc::ToMFC(name)); + ASSERT_TRUE(document.LoadFrom(filePath)) << "Reading from " << name; + EXPECT_EQ(version, document.version) << "Version check for " << name; + } +} + +TEST_F(UTDocuments, RSModelSaveLoad) { + using ccl::semantic::CstType; + using ccl::semantic::EvalStatus; + const auto filePath = ::LocalPathToGlobal(LR"(Data\.rsm)"); + + MockRSModelDoc rsdoc{}; + auto& model = *rsdoc.model; + + model.title = "SaveLoad and some other text"; + model.alias = "short"; + model.comment = "comment"; + + const auto x1 = model.Emplace(CstType::base); + const auto x2 = model.Emplace(CstType::base); + const auto s1 = model.Emplace(CstType::structured, "\xE2\x84\xAC(X1)"); + const auto d1 = model.Emplace(CstType::term, R"(X1\X1)"); + const auto a1 = model.Emplace(CstType::axiom, "1=1"); + const auto a2 = model.Emplace(CstType::axiom, "1=2"); + + model.Values().AddBasicElement(x1, "1"); + model.Values().SetStructureData(s1, model.Values().SDataFor(x1).value()); + model.Calculations().RecalculateAll(); + const auto a3 = model.Emplace(CstType::axiom); + + ASSERT_TRUE(rsdoc.SaveTo(filePath)); + + MockRSModelDoc loadedDoc{}; + ASSERT_TRUE(loadedDoc.LoadFrom(filePath)); + std::filesystem::remove(xtr::mfc::ToUTF8(filePath)); + + const auto& loadedModel = *loadedDoc.model; + EXPECT_EQ(model.title, loadedModel.title); + EXPECT_EQ(model.alias, loadedModel.alias); + EXPECT_EQ(model.comment, loadedModel.comment); + + EXPECT_TRUE(loadedModel.Contains(x1)); + EXPECT_EQ(model.GetRS(x1).alias, loadedModel.GetRS(x1).alias); + EXPECT_EQ(model.GetRS(x1).definition, loadedModel.GetRS(x1).definition); + + EXPECT_EQ(loadedModel.Calculations()(x1), EvalStatus::HAS_DATA); + EXPECT_EQ(loadedModel.Calculations()(x2), EvalStatus::EMPTY); + EXPECT_EQ(loadedModel.Calculations()(s1), EvalStatus::HAS_DATA); + EXPECT_EQ(loadedModel.Calculations()(d1), EvalStatus::EMPTY); + EXPECT_EQ(loadedModel.Calculations()(a1), EvalStatus::HAS_DATA); + EXPECT_EQ(loadedModel.Calculations()(a2), EvalStatus::AXIOM_FAIL); + EXPECT_EQ(loadedModel.Calculations()(a3), EvalStatus::NEVER_CALCULATED); + + EXPECT_EQ(std::ssize(model.Core()), std::ssize(loadedModel.Core())); + EXPECT_TRUE(loadedModel.Values().SDataFor(x2)->B().IsEmpty()); + EXPECT_FALSE(loadedModel.Values().SDataFor(x1)->B().IsEmpty()); + EXPECT_TRUE(loadedModel.Values().StatementFor(a1).value()); + EXPECT_FALSE(loadedModel.Values().StatementFor(a2).value()); + EXPECT_FALSE(loadedModel.Values().StatementFor(a3).has_value()); +} + +TEST_F(UTDocuments, RSModelCalculate) { + MockRSModelDoc document{}; + const auto filePath = ::LocalPathToGlobal(LR"(Data\_\TestCalculate.rsm)"); + ASSERT_TRUE(document.LoadFrom(filePath)); + document.model->Calculations().RecalculateAll(); + EXPECT_EQ(document.model->Calculations().Count(ccl::semantic::EvalStatus::AXIOM_FAIL), 0U); + EXPECT_EQ(document.model->Calculations().Count(ccl::semantic::EvalStatus::INCALCULABLE), 0U); + EXPECT_EQ(document.model->Calculations().Count(ccl::semantic::EvalStatus::NEVER_CALCULATED), 0U); +} + +TEST_F(UTDocuments, OSSSaveLoad) { + const auto filePath = ::LocalPathToGlobal(LR"(Data\.oss)"); + MockOSSDoc ossdoc{}; + auto& initial = *ossdoc.oss; + + initial.title = "SaveLoad and some other text"; + initial.comment = "comment"; + const auto pid1 = initial.InsertBase()->uid; + initial.SetPictAlias(pid1, "Alias1"); + + ASSERT_TRUE(ossdoc.SaveTo(filePath)); + + MockOSSDoc loadedDoc{}; + ASSERT_TRUE(loadedDoc.LoadFrom(filePath)); + std::filesystem::remove(xtr::mfc::ToUTF8(filePath)); + + const auto& loaded = *loadedDoc.oss; + EXPECT_EQ(loaded.title, initial.title); + EXPECT_EQ(loaded.comment, initial.comment); + EXPECT_EQ(loaded.size(), initial.size()); + ASSERT_TRUE(loaded.Contains(pid1)); + EXPECT_EQ(loaded(pid1)->alias, initial(pid1)->alias); +} \ No newline at end of file diff --git a/test/src/testPyCore.cpp b/test/src/testPyCore.cpp new file mode 100644 index 0000000..065560c --- /dev/null +++ b/test/src/testPyCore.cpp @@ -0,0 +1,107 @@ +#include "stdafx.h" + +#include "xtr/core/PyCore.h" + +#pragma warning( push ) +#pragma warning( disable : 4100 ) +#include "Python.h" +#pragma warning( pop ) + +using cxxpython::PyCore; +using cxxpython::Object; + +class UTPyCore : public ::testing::Test { +protected: + inline static const std::string sampleModule = "sample_module"; + inline static const std::string moduleKey = "sample"; + + PyCore& python{ PyCore::Instance() }; + + void SetUp() override { + python.Start(); + } + + void TearDown() override { + python.Stop(); + } +}; + +TEST_F(UTPyCore, Start) { + python.Stop(); + EXPECT_FALSE(python.IsRunning()); + ASSERT_TRUE(python.Start()); + EXPECT_FALSE(python.Start()); + EXPECT_TRUE(python.IsRunning()); + python.Stop(); +} + +TEST_F(UTPyCore, Stop) { + python.Stop(); + EXPECT_FALSE(python.IsRunning()); + + EXPECT_NO_THROW(python.Stop()); +} + +TEST_F(UTPyCore, ObjectNullptr) { + EXPECT_TRUE(Object(nullptr) == nullptr); + EXPECT_TRUE(Object::FromNew(nullptr) == nullptr); + EXPECT_TRUE(Object::FromBorrowed(nullptr) == nullptr); +} + +TEST_F(UTPyCore, ObjectHandles) { + auto newTuple = Object::FromNew(PyTuple_New(1)); + ASSERT_TRUE(newTuple != nullptr); + EXPECT_EQ(Py_REFCNT(newTuple.get()), 1); + + const auto borrowed = Object::FromBorrowed(newTuple.get()); + EXPECT_EQ(Py_REFCNT(borrowed.get()), 2); + + newTuple = nullptr; + EXPECT_EQ(Py_REFCNT(borrowed.get()), 1); + + auto copy = borrowed; + EXPECT_EQ(Py_REFCNT(copy.get()), 2); +} + +TEST_F(UTPyCore, ObjectTypes) { + const auto boolObj = Object::FromNew(PyBool_FromLong(0)); + const auto longObj = Object::FromNew(PyLong_FromLong(42)); + const auto strObj = Object::FromNew(PyUnicode_FromString("test")); + const auto tupleObj = Object::FromNew(Py_BuildValue("(i, u)", 43, L"second")); + + EXPECT_FALSE(cxxpython::ToBool(boolObj)); + EXPECT_EQ(cxxpython::ToLong(longObj), 42); + EXPECT_EQ(cxxpython::ToString(strObj), "test"); + EXPECT_EQ(cxxpython::ToLong(tupleObj.at(0)), 43); + EXPECT_EQ(cxxpython::ToString(tupleObj.at(1)), "second"); +} + +TEST_F(UTPyCore, LoadModule) { + EXPECT_TRUE(python.LoadModule(moduleKey, sampleModule)); + EXPECT_TRUE(python.LoadModule(moduleKey, sampleModule)); + + EXPECT_FALSE(python.LoadModule({}, {})); + EXPECT_FALSE(python.LoadModule("42", "42")); + EXPECT_TRUE(python.LoadModule(moduleKey + "42", sampleModule)); + EXPECT_FALSE(python.LoadModule({}, sampleModule)); +} + +TEST_F(UTPyCore, PyFunction) { + EXPECT_TRUE(python.PyFunction({}, {}) == nullptr); + EXPECT_TRUE(python.PyFunction(moduleKey, {}) == nullptr); + + python.LoadModule(moduleKey, sampleModule); + EXPECT_TRUE(python.PyFunction(moduleKey, "invalid_func") == nullptr); + EXPECT_FALSE(python.PyFunction(moduleKey, "get_state") == nullptr); +} + +TEST_F(UTPyCore, CallFunction) { + python.LoadModule(moduleKey, sampleModule); + const auto get_state = python.PyFunction(moduleKey, "get_state"); + const auto increment = python.PyFunction(moduleKey, "increment"); + const auto add_abc = python.PyFunction(moduleKey, "add_abc"); + + EXPECT_EQ(cxxpython::ToLong(get_state()), 42); + EXPECT_EQ(cxxpython::ToLong(increment("(i)", 42)), 43); + EXPECT_EQ(cxxpython::ToString(add_abc("(s)", "123")), "123abc"); +} \ No newline at end of file diff --git a/test/src/testSelectableSet.cpp b/test/src/testSelectableSet.cpp new file mode 100644 index 0000000..5ae82f3 --- /dev/null +++ b/test/src/testSelectableSet.cpp @@ -0,0 +1,63 @@ +#include "stdafx.h" + +#include "xtr/core/SelectableSet.h" + +class UTSelectableSet : public ::testing::Test { +protected: + xtr::core::SelectableSet selection{}; + + static constexpr EntityUID uid1{ 42U }; + static constexpr EntityUID uid2{ 1337U }; +}; + +TEST_F(UTSelectableSet, Select) { + EXPECT_EQ(size(selection.Selection()), 0U); + EXPECT_FALSE(selection.IsSelected(uid1)); + + selection.Select(uid1); + EXPECT_EQ(size(selection.Selection()), 1U); + EXPECT_TRUE(selection.IsSelected(uid1)); + EXPECT_FALSE(selection.IsSelected(uid2)); + + selection.Select(uid1); + EXPECT_EQ(size(selection.Selection()), 1U); + EXPECT_TRUE(selection.IsSelected(uid1)); + EXPECT_FALSE(selection.IsSelected(uid2)); + + selection.Select(uid2); + EXPECT_EQ(size(selection.Selection()), 2U); + EXPECT_TRUE(selection.IsSelected(uid1)); + EXPECT_TRUE(selection.IsSelected(uid2)); +} + +TEST_F(UTSelectableSet, SelectMultiple) { + EXPECT_EQ(size(selection.Selection()), 0U); + EXPECT_FALSE(selection.IsSelected(uid1)); + + selection.SetSelection({ uid1, uid2 }); + EXPECT_EQ(size(selection.Selection()), 2U); + EXPECT_TRUE(selection.IsSelected(uid1)); + EXPECT_TRUE(selection.IsSelected(uid2)); + + selection.SetSelection({ uid1 }); + EXPECT_EQ(size(selection.Selection()), 1U); + EXPECT_TRUE(selection.IsSelected(uid1)); + EXPECT_FALSE(selection.IsSelected(uid2)); + + selection.SetSelection({}); + EXPECT_FALSE(selection.IsSelected(uid1)); + EXPECT_FALSE(selection.IsSelected(uid2)); +} + +TEST_F(UTSelectableSet, ResetSelection) { + EXPECT_EQ(size(selection.Selection()), 0U); + selection.ResetSelection(); + EXPECT_EQ(size(selection.Selection()), 0U); + + selection.SetSelection({ uid1, uid2 }); + EXPECT_EQ(size(selection.Selection()), 2U); + selection.ResetSelection(); + EXPECT_EQ(size(selection.Selection()), 0U); + EXPECT_FALSE(selection.IsSelected(uid1)); + EXPECT_FALSE(selection.IsSelected(uid2)); +} \ No newline at end of file diff --git a/test/src/testTextEdit.cpp b/test/src/testTextEdit.cpp new file mode 100644 index 0000000..e70b60e --- /dev/null +++ b/test/src/testTextEdit.cpp @@ -0,0 +1,82 @@ +#include "stdafx.h" + +#include "ccl/lang/Literals.h" + +#include "xtr/viewmodel/vmTextEdit.h" + +#include "xtr/xtrDesign.h" +#include "resource.h" + +#include "mockTextEdit.hpp" +#include "mockTermContext.hpp" +#include "mockMessageManager.hpp" + +using ccl::lang::operator""_form; +using ccl::lang::operator""_ref; + +class UTPyTextEdit : public ::testing::Test { +protected: + using Reference = ccl::lang::Reference; + using EntityRef = ccl::lang::EntityRef; + using LexicalTerm = ccl::lang::LexicalTerm; + using Morphology = ccl::lang::Morphology; + +protected: + MockTextEditCtrl control{}; + xtr::viewmodel::vmTextEdit model{ control }; + MockContext context{}; +}; + +TEST_F(UTPyTextEdit, Unintialized) { + EXPECT_TRUE(model.GetRefStr().IsEmpty()); + EXPECT_TRUE(model.GetRefSubstr(StrRange{ 0, 42 }).IsEmpty()); + ASSERT_NO_THROW(model.Invalidate()); + ASSERT_NO_THROW(model.OnEraseText(StrRange{ 0, 0 }, TRUE)); + EXPECT_EQ(model.RepresentativeOf(StrRange{ 0, 42 }), nullptr); +} + +TEST_F(UTPyTextEdit, Initialize) { + model.Initialize(context); + EXPECT_EQ(&model.Context(), &context); + + MockContext context2{}; + model.Initialize(context2); + EXPECT_EQ(&model.Context(), &context2); +} + +TEST_F(UTPyTextEdit, SetRefStr) { + using ccl::operator""_c17; + static const EntityRef x1Ref{ "X1", Morphology{ "nomn,sing" } }; + + model.Initialize(context); + model.SetRefStr(""); + EXPECT_TRUE(control.text.IsEmpty()); + ASSERT_EQ(size(control.items), 0U); + + context.Insert("X1", LexicalTerm{ u8"\u212C42"_c17 }); + model.SetRefStr(xtr::mfc::ToMFC(x1Ref.ToString())); + EXPECT_EQ(control.text, L"\u212C42"); + ASSERT_EQ(size(control.items), 1U); + EXPECT_EQ(begin(control.items)->rng, StrRange(0, 3)); + + model.SetRefStr(""); + EXPECT_EQ(xtr::mfc::ToSTL(control.text), ""); + ASSERT_EQ(size(control.items), 0U); + + context.Clear(); +} + +TEST_F(UTPyTextEdit, OnInsertRefErrors) { + static const auto x1Ref = "@{X1|nomn,sing}"_ref; + + context.Insert("X1", LexicalTerm{ "42" }); + model.Initialize(context); + model.SetRefStr(xtr::mfc::ToMFC(x1Ref.ToString())); + + auto insertMid = [&callModel = this->model] { + callModel.OnInsertRef(StrRange{1, 2}, x1Ref); + }; + ExpectMessage(Message{ .type = MB_ICONERROR, .msg = static_cast(IXTRE_REF_CANNOT_ADD) }, insertMid); + + context.Clear(); +} \ No newline at end of file diff --git a/test/src/testTextProcessor.cpp b/test/src/testTextProcessor.cpp new file mode 100644 index 0000000..692f83e --- /dev/null +++ b/test/src/testTextProcessor.cpp @@ -0,0 +1,62 @@ +#include "stdafx.h" + +#include "ccl/lang/Literals.h" + +#include "xtr/core/PyCore.h" +#include "xtr/core/PyTextProcessor.h" + +using ccl::operator""_c17; +using ccl::lang::operator""_form; + +class UTPyTextProcessor : public ::testing::Test { +protected: + using PyCore = cxxpython::PyCore; + using PyTextProcessor = xtr::core::PyTextProcessor; + + using Morphology = ccl::lang::Morphology; + +protected: + PyCore& python{ PyCore::Instance() }; + std::unique_ptr processor{ nullptr }; + + void SetUp() override { + ASSERT_TRUE(python.Start()); + python.LoadModule("cctext", "cctext"); + processor = std::make_unique(); + processor->InitModule("cctext"); + } + + void TearDown() override { + processor = nullptr; + python.Stop(); + } +}; + +TEST_F(UTPyTextProcessor, Inflect) { + EXPECT_EQ(processor->Inflect("", Morphology{}), ""); + EXPECT_EQ(processor->Inflect("", "sing,datv"_form), ""); + EXPECT_EQ(processor->Inflect(u8""_c17, Morphology{}), u8""_c17); + EXPECT_EQ(processor->Inflect(u8""_c17, "sing,datv"_form), u8""_c17); + EXPECT_EQ(processor->Inflect(u8" "_c17, "plur,datv"_form), u8" "_c17); + EXPECT_EQ(processor->Inflect(u8" "_c17, "ADJF,pres,datv"_form), u8" "_c17); + EXPECT_EQ(processor->Inflect(u8" "_c17, "past,masc"_form), u8" "_c17); + EXPECT_EQ(processor->Inflect(u8" "_c17, "past,masc"_form), u8" "_c17); +} + +TEST_F(UTPyTextProcessor, InflectDependant) { + EXPECT_EQ(processor->InflectDependant("", ""), ""); + EXPECT_EQ(processor->InflectDependant("", "invalid"), ""); + EXPECT_EQ(processor->InflectDependant("invalid", ""), "invalid"); + EXPECT_EQ(processor->InflectDependant("", u8""_c17), ""); + EXPECT_EQ(processor->InflectDependant(u8""_c17, ""), u8""_c17); + EXPECT_EQ(processor->InflectDependant(u8""_c17, u8""_c17), u8""_c17); + EXPECT_EQ(processor->InflectDependant(u8" "_c17, u8" "_c17), u8" "_c17); +} + +TEST_F(UTPyTextProcessor, IsSubstr) { + EXPECT_TRUE(processor->IsSubstr("", "")); + EXPECT_TRUE(processor->IsSubstr("", "123")); + EXPECT_FALSE(processor->IsSubstr("4", "123")); + EXPECT_TRUE(processor->IsSubstr(u8""_c17, u8""_c17)); + EXPECT_TRUE(processor->IsSubstr(u8" "_c17, u8" "_c17)); +} diff --git a/test/stdafx.cpp b/test/stdafx.cpp new file mode 100644 index 0000000..2689f56 --- /dev/null +++ b/test/stdafx.cpp @@ -0,0 +1,17 @@ +#include "stdafx.h" + +// Main function for test setup +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + + // Get a checkpoint of the memory after Google Test has been initialized. + _CrtMemState memoryState = { 0 }; + _CrtMemCheckpoint(&memoryState); + + const auto retval = RUN_ALL_TESTS(); + + // Check for leaks after tests have run + _CrtMemDumpAllObjectsSince(&memoryState); + + return retval; +} \ No newline at end of file diff --git a/test/stdafx.h b/test/stdafx.h new file mode 100644 index 0000000..5d5f921 --- /dev/null +++ b/test/stdafx.h @@ -0,0 +1,68 @@ +#pragma once + +#define GTEST_LANG_CXX11 1 +#include "gtest/gtest.h" + +#define _AFXDLL +#define _WIN32_WINNT _WIN32_WINNT_WIN7 + +// MFC +#pragma warning( push ) +#pragma warning( disable : 4302 4311 ) + + +#define _AFX_ALL_WARNINGS // NOLINT + +#include "afxwin.h" +#include "afxcontrolbars.h" + +#undef min +#undef max +#undef IN + +#pragma warning( pop ) + +// STL +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// POCO +#ifdef _MSC_VER + #pragma warning( push ) + #pragma warning( disable : 4244 ) + #pragma warning( disable : 5054 ) +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER + #pragma warning( pop ) +#endif + +// CCL +#include "ccl/env/cclEnvironment.h" +#include "ccl/semantic/RSCore.h" +#include "ccl/semantic/RSForm.h" +#include "ccl/semantic/RSModel.h" +#include "ccl/oss/OSSchema.h" + +using ccl::StrPos; +using ccl::StrRange; +using ccl::EntityUID; +using ccl::VectorOfEntities; +using ccl::SetOfEntities; + +#include "xtr/mfcHelper.h" \ No newline at end of file