From 1219755e85954897360242cdc0810c820a7c798e Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Fri, 2 Aug 2019 12:48:12 -0700 Subject: [PATCH] Remove WinForms code --- CommonWinForms/CommonWinForms.csproj | 49 - CommonWinForms/NativeMethods.cs | 83 - CommonWinForms/Properties/AssemblyInfo.cs | 36 - CommonWinForms/WinFormsExtensions.cs | 141 - MakeDistWF/App.config | 6 - MakeDistWF/CopyProgress.Designer.cs | 103 - MakeDistWF/CopyProgress.cs | 134 - MakeDistWF/CopyProgress.resx | 123 - MakeDistWF/FileCopier.cs | 316 -- MakeDistWF/MakeDist.Designer.cs | 162 - MakeDistWF/MakeDist.cs | 47 - MakeDistWF/MakeDist.resx | 120 - MakeDistWF/MakeDistWF.csproj | 100 - MakeDistWF/Program.cs | 31 - MakeDistWF/Properties/AssemblyInfo.cs | 36 - MakeDistWF/Properties/Resources.Designer.cs | 63 - MakeDistWF/Properties/Resources.resx | 117 - MakeDistWF/Properties/Settings.Designer.cs | 26 - MakeDistWF/Properties/Settings.settings | 7 - SourceGen/RuntimeData/AboutImage.png | Bin 539507 -> 0 bytes SourceGen/RuntimeData/Logo.png | Bin 350770 -> 0 bytes SourceGenWF/AddressMap.cs | 296 - SourceGenWF/Anattrib.cs | 355 -- SourceGenWF/App.config | 6 - SourceGenWF/AppForms/AboutBox.Designer.cs | 187 - SourceGenWF/AppForms/AboutBox.cs | 51 - SourceGenWF/AppForms/AboutBox.resx | 120 - .../AppForms/DataFileLoadIssue.Designer.cs | 143 - SourceGenWF/AppForms/DataFileLoadIssue.cs | 44 - SourceGenWF/AppForms/DataFileLoadIssue.resx | 120 - .../AppForms/DiscardChanges.Designer.cs | 119 - SourceGenWF/AppForms/DiscardChanges.cs | 48 - SourceGenWF/AppForms/DiscardChanges.resx | 120 - SourceGenWF/AppForms/EditAddress.Designer.cs | 142 - SourceGenWF/AppForms/EditAddress.cs | 78 - SourceGenWF/AppForms/EditAddress.resx | 123 - .../AppForms/EditAppSettings.Designer.cs | 1660 ------ SourceGenWF/AppForms/EditAppSettings.cs | 745 --- SourceGenWF/AppForms/EditAppSettings.resx | 120 - SourceGenWF/AppForms/EditComment.Designer.cs | 153 - SourceGenWF/AppForms/EditComment.cs | 75 - SourceGenWF/AppForms/EditComment.resx | 120 - SourceGenWF/AppForms/EditData.Designer.cs | 559 -- SourceGenWF/AppForms/EditData.cs | 953 ---- SourceGenWF/AppForms/EditData.resx | 120 - .../AppForms/EditDefSymbol.Designer.cs | 265 - SourceGenWF/AppForms/EditDefSymbol.cs | 132 - SourceGenWF/AppForms/EditDefSymbol.resx | 120 - SourceGenWF/AppForms/EditLabel.Designer.cs | 225 - SourceGenWF/AppForms/EditLabel.cs | 152 - SourceGenWF/AppForms/EditLabel.resx | 120 - .../AppForms/EditLongComment.Designer.cs | 201 - SourceGenWF/AppForms/EditLongComment.cs | 130 - SourceGenWF/AppForms/EditLongComment.resx | 120 - SourceGenWF/AppForms/EditNote.Designer.cs | 221 - SourceGenWF/AppForms/EditNote.cs | 104 - SourceGenWF/AppForms/EditNote.resx | 120 - SourceGenWF/AppForms/EditOperand.Designer.cs | 382 -- SourceGenWF/AppForms/EditOperand.cs | 541 -- SourceGenWF/AppForms/EditOperand.resx | 120 - .../EditProjectProperties.Designer.cs | 676 --- SourceGenWF/AppForms/EditProjectProperties.cs | 646 --- .../AppForms/EditProjectProperties.resx | 120 - .../AppForms/EditStatusFlags.Designer.cs | 883 --- SourceGenWF/AppForms/EditStatusFlags.cs | 143 - SourceGenWF/AppForms/EditStatusFlags.resx | 120 - SourceGenWF/AppForms/FindBox.Designer.cs | 89 - SourceGenWF/AppForms/FindBox.cs | 53 - SourceGenWF/AppForms/FindBox.resx | 120 - .../AppForms/FormatSplitAddress.Designer.cs | 495 -- SourceGenWF/AppForms/FormatSplitAddress.cs | 434 -- SourceGenWF/AppForms/FormatSplitAddress.resx | 120 - SourceGenWF/AppForms/GotoBox.Designer.cs | 181 - SourceGenWF/AppForms/GotoBox.cs | 119 - SourceGenWF/AppForms/GotoBox.resx | 120 - .../AppForms/ProjectLoadIssues.Designer.cs | 134 - SourceGenWF/AppForms/ProjectLoadIssues.cs | 64 - SourceGenWF/AppForms/ProjectLoadIssues.resx | 120 - SourceGenWF/AppForms/ProjectView.Designer.cs | 1652 ------ SourceGenWF/AppForms/ProjectView.cs | 4755 ----------------- SourceGenWF/AppForms/ProjectView.resx | 319 -- SourceGenWF/AppSettings.cs | 355 -- SourceGenWF/AsmGen/AsmCc65.cs | 869 --- SourceGenWF/AsmGen/AsmMerlin32.cs | 790 --- SourceGenWF/AsmGen/AsmTass64.cs | 778 --- SourceGenWF/AsmGen/AssemblerConfig.cs | 114 - SourceGenWF/AsmGen/AssemblerInfo.cs | 170 - .../AsmGen/AssemblerProgress.Designer.cs | 113 - SourceGenWF/AsmGen/AssemblerProgress.cs | 124 - SourceGenWF/AsmGen/AssemblerProgress.resx | 123 - SourceGenWF/AsmGen/AssemblerVersion.cs | 104 - SourceGenWF/AsmGen/GenAndAsm.Designer.cs | 298 -- SourceGenWF/AsmGen/GenAndAsm.cs | 402 -- SourceGenWF/AsmGen/GenAndAsm.resx | 120 - SourceGenWF/AsmGen/GenCommon.cs | 371 -- .../AsmGen/GeneratorProgress.Designer.cs | 114 - SourceGenWF/AsmGen/GeneratorProgress.cs | 124 - SourceGenWF/AsmGen/GeneratorProgress.resx | 123 - SourceGenWF/AsmGen/IAssembler.cs | 82 - SourceGenWF/AsmGen/IGenerator.cs | 192 - SourceGenWF/AsmGen/LabelLocalizer.cs | 386 -- SourceGenWF/AsmGen/StringGather.cs | 227 - SourceGenWF/AutoLabel.cs | 164 - SourceGenWF/ChangeSet.cs | 109 - SourceGenWF/CodeAnalysis.cs | 1070 ---- SourceGenWF/DataAnalysis.cs | 1139 ---- SourceGenWF/DefSymbol.cs | 104 - SourceGenWF/DisasmProject.cs | 1767 ------ SourceGenWF/DisplayList.cs | 1224 ----- SourceGenWF/ExternalFile.cs | 264 - SourceGenWF/FormatDescriptor.cs | 423 -- SourceGenWF/HelpAccess.cs | 90 - SourceGenWF/MultiLineComment.cs | 276 - SourceGenWF/NavStack.cs | 157 - SourceGenWF/PlatformSymbols.cs | 252 - SourceGenWF/Program.cs | 42 - SourceGenWF/ProjectFile.cs | 734 --- SourceGenWF/ProjectProperties.cs | 134 - SourceGenWF/Properties/AssemblyInfo.cs | 36 - SourceGenWF/Properties/Resources.Designer.cs | 1044 ---- SourceGenWF/Properties/Resources.resx | 447 -- SourceGenWF/Properties/Settings.Designer.cs | 26 - SourceGenWF/Properties/Settings.settings | 7 - SourceGenWF/PseudoOp.cs | 897 ---- SourceGenWF/RuntimeDataAccess.cs | 117 - SourceGenWF/Sandbox/DomainManager.cs | 255 - SourceGenWF/Sandbox/PluginDllCache.cs | 237 - SourceGenWF/Sandbox/ScriptManager.cs | 226 - SourceGenWF/Sandbox/Sponsor.cs | 177 - SourceGenWF/Setup/NewProject.Designer.cs | 160 - SourceGenWF/Setup/NewProject.cs | 211 - SourceGenWF/Setup/NewProject.resx | 405 -- SourceGenWF/Setup/SystemDefaults.cs | 140 - SourceGenWF/Setup/SystemDefs.cs | 213 - SourceGenWF/SourceGenIcon.ico | Bin 142787 -> 0 bytes SourceGenWF/SourceGenWF.csproj | 414 -- SourceGenWF/Symbol.cs | 155 - SourceGenWF/SymbolTable.cs | 215 - SourceGenWF/SymbolTableSubset.cs | 277 - SourceGenWF/Tests/GenTest.cs | 620 --- SourceGenWF/Tests/GenTestRunner.Designer.cs | 161 - SourceGenWF/Tests/GenTestRunner.cs | 204 - SourceGenWF/Tests/GenTestRunner.resx | 123 - SourceGenWF/Tests/ProgressMessage.cs | 36 - SourceGenWF/Tools/AsciiChart.Designer.cs | 98 - SourceGenWF/Tools/AsciiChart.cs | 112 - SourceGenWF/Tools/AsciiChart.resx | 156 - SourceGenWF/Tools/HexDumpViewer.Designer.cs | 150 - SourceGenWF/Tools/HexDumpViewer.cs | 276 - SourceGenWF/Tools/HexDumpViewer.resx | 120 - SourceGenWF/Tools/ShowText.Designer.cs | 80 - SourceGenWF/Tools/ShowText.cs | 78 - SourceGenWF/Tools/ShowText.resx | 120 - SourceGenWF/UndoableChange.cs | 460 -- SourceGenWF/VirtualListViewSelection.cs | 145 - SourceGenWF/WeakSymbolRef.cs | 94 - SourceGenWF/XrefSet.cs | 139 - WorkBench.sln | 21 - 158 files changed, 45253 deletions(-) delete mode 100644 CommonWinForms/CommonWinForms.csproj delete mode 100644 CommonWinForms/NativeMethods.cs delete mode 100644 CommonWinForms/Properties/AssemblyInfo.cs delete mode 100644 CommonWinForms/WinFormsExtensions.cs delete mode 100644 MakeDistWF/App.config delete mode 100644 MakeDistWF/CopyProgress.Designer.cs delete mode 100644 MakeDistWF/CopyProgress.cs delete mode 100644 MakeDistWF/CopyProgress.resx delete mode 100644 MakeDistWF/FileCopier.cs delete mode 100644 MakeDistWF/MakeDist.Designer.cs delete mode 100644 MakeDistWF/MakeDist.cs delete mode 100644 MakeDistWF/MakeDist.resx delete mode 100644 MakeDistWF/MakeDistWF.csproj delete mode 100644 MakeDistWF/Program.cs delete mode 100644 MakeDistWF/Properties/AssemblyInfo.cs delete mode 100644 MakeDistWF/Properties/Resources.Designer.cs delete mode 100644 MakeDistWF/Properties/Resources.resx delete mode 100644 MakeDistWF/Properties/Settings.Designer.cs delete mode 100644 MakeDistWF/Properties/Settings.settings delete mode 100644 SourceGen/RuntimeData/AboutImage.png delete mode 100644 SourceGen/RuntimeData/Logo.png delete mode 100644 SourceGenWF/AddressMap.cs delete mode 100644 SourceGenWF/Anattrib.cs delete mode 100644 SourceGenWF/App.config delete mode 100644 SourceGenWF/AppForms/AboutBox.Designer.cs delete mode 100644 SourceGenWF/AppForms/AboutBox.cs delete mode 100644 SourceGenWF/AppForms/AboutBox.resx delete mode 100644 SourceGenWF/AppForms/DataFileLoadIssue.Designer.cs delete mode 100644 SourceGenWF/AppForms/DataFileLoadIssue.cs delete mode 100644 SourceGenWF/AppForms/DataFileLoadIssue.resx delete mode 100644 SourceGenWF/AppForms/DiscardChanges.Designer.cs delete mode 100644 SourceGenWF/AppForms/DiscardChanges.cs delete mode 100644 SourceGenWF/AppForms/DiscardChanges.resx delete mode 100644 SourceGenWF/AppForms/EditAddress.Designer.cs delete mode 100644 SourceGenWF/AppForms/EditAddress.cs delete mode 100644 SourceGenWF/AppForms/EditAddress.resx delete mode 100644 SourceGenWF/AppForms/EditAppSettings.Designer.cs delete mode 100644 SourceGenWF/AppForms/EditAppSettings.cs delete mode 100644 SourceGenWF/AppForms/EditAppSettings.resx delete mode 100644 SourceGenWF/AppForms/EditComment.Designer.cs delete mode 100644 SourceGenWF/AppForms/EditComment.cs delete mode 100644 SourceGenWF/AppForms/EditComment.resx delete mode 100644 SourceGenWF/AppForms/EditData.Designer.cs delete mode 100644 SourceGenWF/AppForms/EditData.cs delete mode 100644 SourceGenWF/AppForms/EditData.resx delete mode 100644 SourceGenWF/AppForms/EditDefSymbol.Designer.cs delete mode 100644 SourceGenWF/AppForms/EditDefSymbol.cs delete mode 100644 SourceGenWF/AppForms/EditDefSymbol.resx delete mode 100644 SourceGenWF/AppForms/EditLabel.Designer.cs delete mode 100644 SourceGenWF/AppForms/EditLabel.cs delete mode 100644 SourceGenWF/AppForms/EditLabel.resx delete mode 100644 SourceGenWF/AppForms/EditLongComment.Designer.cs delete mode 100644 SourceGenWF/AppForms/EditLongComment.cs delete mode 100644 SourceGenWF/AppForms/EditLongComment.resx delete mode 100644 SourceGenWF/AppForms/EditNote.Designer.cs delete mode 100644 SourceGenWF/AppForms/EditNote.cs delete mode 100644 SourceGenWF/AppForms/EditNote.resx delete mode 100644 SourceGenWF/AppForms/EditOperand.Designer.cs delete mode 100644 SourceGenWF/AppForms/EditOperand.cs delete mode 100644 SourceGenWF/AppForms/EditOperand.resx delete mode 100644 SourceGenWF/AppForms/EditProjectProperties.Designer.cs delete mode 100644 SourceGenWF/AppForms/EditProjectProperties.cs delete mode 100644 SourceGenWF/AppForms/EditProjectProperties.resx delete mode 100644 SourceGenWF/AppForms/EditStatusFlags.Designer.cs delete mode 100644 SourceGenWF/AppForms/EditStatusFlags.cs delete mode 100644 SourceGenWF/AppForms/EditStatusFlags.resx delete mode 100644 SourceGenWF/AppForms/FindBox.Designer.cs delete mode 100644 SourceGenWF/AppForms/FindBox.cs delete mode 100644 SourceGenWF/AppForms/FindBox.resx delete mode 100644 SourceGenWF/AppForms/FormatSplitAddress.Designer.cs delete mode 100644 SourceGenWF/AppForms/FormatSplitAddress.cs delete mode 100644 SourceGenWF/AppForms/FormatSplitAddress.resx delete mode 100644 SourceGenWF/AppForms/GotoBox.Designer.cs delete mode 100644 SourceGenWF/AppForms/GotoBox.cs delete mode 100644 SourceGenWF/AppForms/GotoBox.resx delete mode 100644 SourceGenWF/AppForms/ProjectLoadIssues.Designer.cs delete mode 100644 SourceGenWF/AppForms/ProjectLoadIssues.cs delete mode 100644 SourceGenWF/AppForms/ProjectLoadIssues.resx delete mode 100644 SourceGenWF/AppForms/ProjectView.Designer.cs delete mode 100644 SourceGenWF/AppForms/ProjectView.cs delete mode 100644 SourceGenWF/AppForms/ProjectView.resx delete mode 100644 SourceGenWF/AppSettings.cs delete mode 100644 SourceGenWF/AsmGen/AsmCc65.cs delete mode 100644 SourceGenWF/AsmGen/AsmMerlin32.cs delete mode 100644 SourceGenWF/AsmGen/AsmTass64.cs delete mode 100644 SourceGenWF/AsmGen/AssemblerConfig.cs delete mode 100644 SourceGenWF/AsmGen/AssemblerInfo.cs delete mode 100644 SourceGenWF/AsmGen/AssemblerProgress.Designer.cs delete mode 100644 SourceGenWF/AsmGen/AssemblerProgress.cs delete mode 100644 SourceGenWF/AsmGen/AssemblerProgress.resx delete mode 100644 SourceGenWF/AsmGen/AssemblerVersion.cs delete mode 100644 SourceGenWF/AsmGen/GenAndAsm.Designer.cs delete mode 100644 SourceGenWF/AsmGen/GenAndAsm.cs delete mode 100644 SourceGenWF/AsmGen/GenAndAsm.resx delete mode 100644 SourceGenWF/AsmGen/GenCommon.cs delete mode 100644 SourceGenWF/AsmGen/GeneratorProgress.Designer.cs delete mode 100644 SourceGenWF/AsmGen/GeneratorProgress.cs delete mode 100644 SourceGenWF/AsmGen/GeneratorProgress.resx delete mode 100644 SourceGenWF/AsmGen/IAssembler.cs delete mode 100644 SourceGenWF/AsmGen/IGenerator.cs delete mode 100644 SourceGenWF/AsmGen/LabelLocalizer.cs delete mode 100644 SourceGenWF/AsmGen/StringGather.cs delete mode 100644 SourceGenWF/AutoLabel.cs delete mode 100644 SourceGenWF/ChangeSet.cs delete mode 100644 SourceGenWF/CodeAnalysis.cs delete mode 100644 SourceGenWF/DataAnalysis.cs delete mode 100644 SourceGenWF/DefSymbol.cs delete mode 100644 SourceGenWF/DisasmProject.cs delete mode 100644 SourceGenWF/DisplayList.cs delete mode 100644 SourceGenWF/ExternalFile.cs delete mode 100644 SourceGenWF/FormatDescriptor.cs delete mode 100644 SourceGenWF/HelpAccess.cs delete mode 100644 SourceGenWF/MultiLineComment.cs delete mode 100644 SourceGenWF/NavStack.cs delete mode 100644 SourceGenWF/PlatformSymbols.cs delete mode 100644 SourceGenWF/Program.cs delete mode 100644 SourceGenWF/ProjectFile.cs delete mode 100644 SourceGenWF/ProjectProperties.cs delete mode 100644 SourceGenWF/Properties/AssemblyInfo.cs delete mode 100644 SourceGenWF/Properties/Resources.Designer.cs delete mode 100644 SourceGenWF/Properties/Resources.resx delete mode 100644 SourceGenWF/Properties/Settings.Designer.cs delete mode 100644 SourceGenWF/Properties/Settings.settings delete mode 100644 SourceGenWF/PseudoOp.cs delete mode 100644 SourceGenWF/RuntimeDataAccess.cs delete mode 100644 SourceGenWF/Sandbox/DomainManager.cs delete mode 100644 SourceGenWF/Sandbox/PluginDllCache.cs delete mode 100644 SourceGenWF/Sandbox/ScriptManager.cs delete mode 100644 SourceGenWF/Sandbox/Sponsor.cs delete mode 100644 SourceGenWF/Setup/NewProject.Designer.cs delete mode 100644 SourceGenWF/Setup/NewProject.cs delete mode 100644 SourceGenWF/Setup/NewProject.resx delete mode 100644 SourceGenWF/Setup/SystemDefaults.cs delete mode 100644 SourceGenWF/Setup/SystemDefs.cs delete mode 100644 SourceGenWF/SourceGenIcon.ico delete mode 100644 SourceGenWF/SourceGenWF.csproj delete mode 100644 SourceGenWF/Symbol.cs delete mode 100644 SourceGenWF/SymbolTable.cs delete mode 100644 SourceGenWF/SymbolTableSubset.cs delete mode 100644 SourceGenWF/Tests/GenTest.cs delete mode 100644 SourceGenWF/Tests/GenTestRunner.Designer.cs delete mode 100644 SourceGenWF/Tests/GenTestRunner.cs delete mode 100644 SourceGenWF/Tests/GenTestRunner.resx delete mode 100644 SourceGenWF/Tests/ProgressMessage.cs delete mode 100644 SourceGenWF/Tools/AsciiChart.Designer.cs delete mode 100644 SourceGenWF/Tools/AsciiChart.cs delete mode 100644 SourceGenWF/Tools/AsciiChart.resx delete mode 100644 SourceGenWF/Tools/HexDumpViewer.Designer.cs delete mode 100644 SourceGenWF/Tools/HexDumpViewer.cs delete mode 100644 SourceGenWF/Tools/HexDumpViewer.resx delete mode 100644 SourceGenWF/Tools/ShowText.Designer.cs delete mode 100644 SourceGenWF/Tools/ShowText.cs delete mode 100644 SourceGenWF/Tools/ShowText.resx delete mode 100644 SourceGenWF/UndoableChange.cs delete mode 100644 SourceGenWF/VirtualListViewSelection.cs delete mode 100644 SourceGenWF/WeakSymbolRef.cs delete mode 100644 SourceGenWF/XrefSet.cs diff --git a/CommonWinForms/CommonWinForms.csproj b/CommonWinForms/CommonWinForms.csproj deleted file mode 100644 index 10e868e..0000000 --- a/CommonWinForms/CommonWinForms.csproj +++ /dev/null @@ -1,49 +0,0 @@ - - - - - Debug - AnyCPU - {08EC328D-078E-4236-B574-BE6B3FD85915} - Library - Properties - CommonWinForms - CommonWinForms - v4.6.1 - 512 - true - - - true - full - false - bin\Debug\ - TRACE;DEBUG - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/CommonWinForms/NativeMethods.cs b/CommonWinForms/NativeMethods.cs deleted file mode 100644 index 90700a5..0000000 --- a/CommonWinForms/NativeMethods.cs +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Runtime.InteropServices; -using System.Windows.Forms; - -namespace CommonWinForms { - // From https://stackoverflow.com/questions/1019388/ - - /// - /// Unpleasant hackery to make "select all" faster. With 500K items it takes about 24 - /// seconds to select everything individually, and there isn't a better way. With this - /// it only takes a few milliseconds. - /// - public class NativeMethods { - private const int LVM_FIRST = 0x1000; - private const int LVM_SETITEMSTATE = LVM_FIRST + 43; - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] - public struct LVITEM { - public int mask; - public int iItem; - public int iSubItem; - public int state; - public int stateMask; - [MarshalAs(UnmanagedType.LPTStr)] - public string pszText; - public int cchTextMax; - public int iImage; - public IntPtr lParam; - public int iIndent; - public int iGroupId; - public int cColumns; - public IntPtr puColumns; - }; - - [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] - public static extern IntPtr SendMessageLVItem(IntPtr hWnd, int msg, int wParam, ref LVITEM lvi); - - /// - /// Select all rows on the given listview - /// - /// The listview whose items are to be selected - public static void SelectAllItems(ListView list) { - NativeMethods.SetItemState(list, -1, 2, 2); - } - - /// - /// Deselect all rows on the given listview - /// - /// The listview whose items are to be deselected - public static void DeselectAllItems(ListView list) { - NativeMethods.SetItemState(list, -1, 2, 0); - } - - /// - /// Set the item state on the given item - /// - /// The listview whose item's state is to be changed - /// The index of the item to be changed - /// Which bits of the value are to be set? - /// The value to be set - public static void SetItemState(ListView list, int itemIndex, int mask, int value) { - LVITEM lvItem = new LVITEM(); - lvItem.stateMask = mask; - lvItem.state = value; - SendMessageLVItem(list.Handle, LVM_SETITEMSTATE, itemIndex, ref lvItem); - } - } -} diff --git a/CommonWinForms/Properties/AssemblyInfo.cs b/CommonWinForms/Properties/AssemblyInfo.cs deleted file mode 100644 index 5306502..0000000 --- a/CommonWinForms/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("CommonWinForms")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("CommonWinForms")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("08ec328d-078e-4236-b574-be6b3fd85915")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/CommonWinForms/WinFormsExtensions.cs b/CommonWinForms/WinFormsExtensions.cs deleted file mode 100644 index 662e08b..0000000 --- a/CommonWinForms/WinFormsExtensions.cs +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Drawing; -using System.Windows.Forms; - -namespace CommonWinForms { - /// - /// Overload RichTextBox.AppendText() with a version that takes a color as an argument. - /// - /// From https://stackoverflow.com/a/1926822/294248 - /// - public static class RichTextBoxExtensions { - public static void AppendText(this RichTextBox box, string text, Color color) { - box.SelectionStart = box.TextLength; - box.SelectionLength = 0; - box.SelectionColor = color; - box.AppendText(text); - box.SelectionColor = box.ForeColor; - } - } - - /// - /// Add functions to select and deselect all items. - /// - public static class ListViewExtensions { - // I don't know if NativeMethods is going to work on other platforms, but I assume - // not. I'm not sure how expensive the runtime check is, so cache the result. - private enum DNY { Dunno = 0, No, Yes }; - private static DNY IsPlatformWindows; - private static bool IsWindows { - get { - if (IsPlatformWindows == DNY.Dunno) { - // This is the .NET framework 4.6 way. Later versions (4.7, netcommon) - // prefer the RuntimeInformation.IsOSPlatform() approach. - OperatingSystem os = Environment.OSVersion; - if (os.Platform == PlatformID.Win32NT) { - IsPlatformWindows = DNY.Yes; - } else { - IsPlatformWindows = DNY.No; - } - } - return (IsPlatformWindows == DNY.Yes); - } - } - - /// - /// Selects all items in the list view. - /// - public static void SelectAll(this ListView listView) { - // Neither I nor the Internet can figure out how to do this efficiently for - // large lists without P/Invoke interop. With 554253 lines, it takes 24.3 seconds - // to select each item individually, but only 4 milliseconds to do it through an - // LVITEM. The latter causes a single VirtualItemsSelectionRangeChanged event - // instead of 554K ItemSelectionChanged events. - // - // https://stackoverflow.com/questions/9039989/ - // https://stackoverflow.com/questions/1019388/ - - if (IsWindows) { - NativeMethods.SelectAllItems(listView); - } else { - try { - Application.UseWaitCursor = true; - Cursor.Current = Cursors.WaitCursor; - listView.BeginUpdate(); - int max = listView.VirtualListSize; - for (int i = 0; i < max; i++) { - //codeListView.Items[i].Selected = true; - listView.SelectedIndices.Add(i); - } - } finally { - listView.EndUpdate(); - Application.UseWaitCursor = false; - } - } - } - - /// - /// Deselects all items in the list view. - /// - public static void DeselectAll(this ListView listView) { - // This is as fast as the native DeselectAllItems(), so just use it. - listView.SelectedIndices.Clear(); - } - - /// - /// Sets the double-buffered status of the list view. - /// - public static void SetDoubleBuffered(this ListView listView, bool enable) { - WinFormsUtil.SetDoubleBuffered(listView, enable); - } - - /// - /// Determines whether the specified item is visible in the list view. - /// - public static bool IsItemVisible(this ListView listView, ListViewItem item) { - Rectangle lvBounds = listView.ClientRectangle; - if (listView.HeaderStyle != ColumnHeaderStyle.None) { - // Need to factor the header height out. There's no easy way to do that, - // but the header should be (almost) the same height as an item. - // https://stackoverflow.com/q/538906/294248 - int headerHeight = item.Bounds.Height + 5; // 5 is magic, will probably break - lvBounds = new Rectangle(lvBounds.X, lvBounds.Y + headerHeight, - lvBounds.Width, lvBounds.Height - headerHeight); - } - //Console.WriteLine("IsVis LV: " + lvBounds + " IT: " + - // item.GetBounds(ItemBoundsPortion.Entire)); - return lvBounds.IntersectsWith(item.GetBounds(ItemBoundsPortion.Entire)); - } - } - - public static class WinFormsUtil { - /// - /// Sets the "DoubleBuffered" property on a Control. For some reason the - /// property is defined as "protected", but I don't want to subclass a ListView - /// just so I can enable double-buffering. - /// - /// Control to update. - /// New state. - public static void SetDoubleBuffered(Control ctrl, bool enable) { - System.Reflection.PropertyInfo prop = ctrl.GetType().GetProperty("DoubleBuffered", - System.Reflection.BindingFlags.Instance | - System.Reflection.BindingFlags.NonPublic); - prop.SetValue(ctrl, enable, null); - } - } -} diff --git a/MakeDistWF/App.config b/MakeDistWF/App.config deleted file mode 100644 index 731f6de..0000000 --- a/MakeDistWF/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/MakeDistWF/CopyProgress.Designer.cs b/MakeDistWF/CopyProgress.Designer.cs deleted file mode 100644 index ebfd24a..0000000 --- a/MakeDistWF/CopyProgress.Designer.cs +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace MakeDistWF { - partial class CopyProgress { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.progressRichTextBox = new System.Windows.Forms.RichTextBox(); - this.cancelButton = new System.Windows.Forms.Button(); - this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); - this.SuspendLayout(); - // - // progressRichTextBox - // - this.progressRichTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.progressRichTextBox.Location = new System.Drawing.Point(13, 13); - this.progressRichTextBox.Name = "progressRichTextBox"; - this.progressRichTextBox.ReadOnly = true; - this.progressRichTextBox.Size = new System.Drawing.Size(459, 507); - this.progressRichTextBox.TabIndex = 0; - this.progressRichTextBox.Text = ""; - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.Location = new System.Drawing.Point(397, 526); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 23); - this.cancelButton.TabIndex = 1; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click); - // - // backgroundWorker1 - // - this.backgroundWorker1.WorkerReportsProgress = true; - this.backgroundWorker1.WorkerSupportsCancellation = true; - this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); - this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); - this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); - // - // CopyProgress - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(484, 561); - this.Controls.Add(this.cancelButton); - this.Controls.Add(this.progressRichTextBox); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "CopyProgress"; - this.ShowInTaskbar = false; - this.Text = "CopyDistFiles"; - this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.CopyProgress_FormClosing); - this.Load += new System.EventHandler(this.CopyProgress_Load); - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.RichTextBox progressRichTextBox; - private System.Windows.Forms.Button cancelButton; - private System.ComponentModel.BackgroundWorker backgroundWorker1; - } -} \ No newline at end of file diff --git a/MakeDistWF/CopyProgress.cs b/MakeDistWF/CopyProgress.cs deleted file mode 100644 index ab96308..0000000 --- a/MakeDistWF/CopyProgress.cs +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.ComponentModel; -using System.Diagnostics; -using System.Drawing; -using System.Windows.Forms; - -using CommonWinForms; - -namespace MakeDistWF { - public partial class CopyProgress : Form { - /// - /// Progress message, with colorful text. This is generated by the worker thread and - /// passed to the UI thread. - /// - public class ProgressMessage { - public string Text { get; private set; } - public Color Color { get; private set; } - public bool HasColor { get { return Color.A != 0; } } - - public ProgressMessage(string msg) : this(msg, Color.FromArgb(0, 0, 0, 0)) { } - - public ProgressMessage(string msg, Color color) { - Text = msg; - Color = color; - } - } - - private bool mClosedWhileRunning; - - // Copy parameters. - private FileCopier.BuildType mBuildType; - private bool mCopyTestFiles; - - - public CopyProgress(FileCopier.BuildType buildType, bool copyTestFiles) { - InitializeComponent(); - - this.Size = new Size(1200, 600); - - mBuildType = buildType; - mCopyTestFiles = copyTestFiles; - } - - private void CopyProgress_Load(object sender, EventArgs e) { - backgroundWorker1.RunWorkerAsync(); - } - - private void CopyProgress_FormClosing(object sender, FormClosingEventArgs e) { - if (backgroundWorker1.IsBusy) { - backgroundWorker1.CancelAsync(); - DialogResult = DialogResult.Cancel; - - // First close attempt is converted to a cancel. - if (!mClosedWhileRunning) { - e.Cancel = true; - mClosedWhileRunning = true; - } - } else { - DialogResult = DialogResult.OK; - } - } - - private void cancelButton_Click(object sender, EventArgs e) { - if (backgroundWorker1.IsBusy) { - backgroundWorker1.CancelAsync(); - } else { - Close(); - } - } - - private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { - BackgroundWorker worker = sender as BackgroundWorker; - - FileCopier copier = new FileCopier(mBuildType, mCopyTestFiles); - e.Result = copier.CopyAllFiles(worker); - } - - private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { - if (e.UserState is ProgressMessage) { - ProgressMessage msg = e.UserState as ProgressMessage; - if (msg.HasColor) { - progressRichTextBox.AppendText(msg.Text, msg.Color); - } else { - // plain foreground text color - progressRichTextBox.AppendText(msg.Text); - } - progressRichTextBox.SelectionStart = progressRichTextBox.Text.Length; - progressRichTextBox.ScrollToCaret(); - } else { - if (!string.IsNullOrEmpty((string)e.UserState)) { - Debug.WriteLine("Weird progress: " + e.UserState); - } - } - } - - private void backgroundWorker1_RunWorkerCompleted(object sender, - RunWorkerCompletedEventArgs e) { - if (e.Cancelled) { - Debug.WriteLine("Test halted -- user cancellation"); - } else if (e.Error != null) { - // test harness shouldn't be throwing errors like this - Debug.WriteLine("Test failed: " + e.Error.ToString()); - progressRichTextBox.AppendText("\r\n"); - progressRichTextBox.AppendText(e.Error.ToString()); - progressRichTextBox.SelectionStart = progressRichTextBox.Text.Length; - progressRichTextBox.ScrollToCaret(); - } else { - bool ok = (bool)e.Result; - Debug.WriteLine("Tests complete, success=" + ok); - } - - if (mClosedWhileRunning) { - Close(); - } - - cancelButton.Text = "Close"; - } - } -} diff --git a/MakeDistWF/CopyProgress.resx b/MakeDistWF/CopyProgress.resx deleted file mode 100644 index 59099f2..0000000 --- a/MakeDistWF/CopyProgress.resx +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - \ No newline at end of file diff --git a/MakeDistWF/FileCopier.cs b/MakeDistWF/FileCopier.cs deleted file mode 100644 index 29d86d1..0000000 --- a/MakeDistWF/FileCopier.cs +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Drawing; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; - -namespace MakeDistWF { - public class FileCopier { - private const string SOURCEGEN_DIRNAME = "SourceGen"; - - /// - /// Type of build to gather files for. - /// - public enum BuildType { Unknown, Release, Debug }; - - private enum SourceFileSpec { - Unknown = 0, - All, - List, - RegressionTests, - AsmSources, - NotBins, - } - - private class CopySpec { - public string SourceDir { get; private set; } - public string DestDir { get; private set; } - public SourceFileSpec FileSpec { get; private set; } - public bool IsRecursive { get; private set; } - public string[] FileList { get; private set; } - - public CopySpec(string srcDir, string dstDir, SourceFileSpec spec, bool recursive, - string[] fileList) { - SourceDir = srcDir; - DestDir = dstDir; - FileSpec = spec; - IsRecursive = recursive; - FileList = fileList; - } - } - - private static CopySpec[] sMainSpec = { - new CopySpec(".", ".", - SourceFileSpec.List, false, new string[] { "README.md" }), - new CopySpec("Asm65/bin/{BUILD_TYPE}/netstandard2.0/", ".", - SourceFileSpec.List, false, new string[] { "Asm65.dll" }), - new CopySpec("CommonUtil/bin/{BUILD_TYPE}/netstandard2.0/", ".", - SourceFileSpec.List, false, new string[] { "CommonUtil.dll" }), - new CopySpec("CommonWinForms/bin/{BUILD_TYPE}/", ".", - SourceFileSpec.List, false, new string[] { "CommonWinForms.dll" }), - new CopySpec("PluginCommon/bin/{BUILD_TYPE}/netstandard2.0/", ".", - SourceFileSpec.List, false, new string[] { "PluginCommon.dll" }), - new CopySpec("SourceGen/bin/{BUILD_TYPE}/", ".", - SourceFileSpec.List, false, new string[] { "SourceGen.exe" }), - new CopySpec("SourceGen/RuntimeData", "RuntimeData", - SourceFileSpec.NotBins, true, null), - new CopySpec("SourceGen/Examples", "Examples", - SourceFileSpec.All, true, null), - }; - private static CopySpec[] sTestSpec = { - new CopySpec("SourceGen/SGTestData", "SGTestData", - SourceFileSpec.RegressionTests, false, null), - new CopySpec("SourceGen/SGTestData", "SGTestData", - SourceFileSpec.List, false, new string[] { "README.md" }), - new CopySpec("SourceGen/SGTestData/Expected", "SGTestData/Expected", - SourceFileSpec.AsmSources, false, null), - new CopySpec("SourceGen/SGTestData/Source", "SGTestData/Source", - SourceFileSpec.AsmSources, false, null), - new CopySpec("SourceGen/SGTestData/FunkyProjects", "SGTestData/FunkyProjects", - SourceFileSpec.All, false, null), - }; - - private static string sBasePath; - - // We want all of the regression test binaries, plus the .sym65, .dis65, and .cs, - // but nothing with an underscore in the part before the extension. - private const string TestCasePattern = @"^\d\d\d\d-[A-Za-z0-9-]+(\..*)?$"; - private static Regex sTestCaseRegex = new Regex(TestCasePattern); - - - private BuildType mBuildType; - private bool mCopyTestFiles; - private BackgroundWorker mWorker; - - - public FileCopier(BuildType buildType, bool copyTestFiles) { - mBuildType = buildType; - mCopyTestFiles = copyTestFiles; - } - - private void ReportProgress(string msg) { - mWorker.ReportProgress(0, new CopyProgress.ProgressMessage(msg + "\r\n")); - } - - private void ReportProgress(string msg, Color color) { - mWorker.ReportProgress(0, new CopyProgress.ProgressMessage(msg + "\r\n", color)); - } - - private void ReportErrMsg(string msg) { - ReportProgress(msg, Color.Red); - } - - /// - /// Main entry point. - /// - /// Background task interface object. - /// True on success. - public bool CopyAllFiles(BackgroundWorker worker) { - mWorker = worker; - - ReportProgress("Preparing... build type is " + mBuildType + ", test files are " + - (mCopyTestFiles ? "" : "NOT ") + "included."); - - string buildStr = mBuildType.ToString(); - string basePath = FindBasePath(); - Debug.Assert(basePath != null); - string distPath = Path.Combine(basePath, "DIST_" + buildStr); - - // TODO(maybe): recursively delete distPath - - if (!CopySpecList(sMainSpec, basePath, distPath, buildStr)) { - return false; - } - if (mCopyTestFiles) { - if (!CopySpecList(sTestSpec, basePath, distPath, buildStr)) { - return false; - } - } - return true; - } - - private bool CopySpecList(CopySpec[] specList, string basePath, string distPath, - string buildStr) { - foreach (CopySpec cs in specList) { - string srcDir = Path.GetFullPath(Path.Combine(basePath, - cs.SourceDir.Replace("{BUILD_TYPE}", buildStr))); - string dstDir = Path.GetFullPath(Path.Combine(distPath, cs.DestDir)); - - ReportProgress("Scanning [" + cs.FileSpec + "] " + srcDir); - - if (!CopyBySpec(srcDir, dstDir, cs.FileSpec, cs.FileList, cs.IsRecursive)) { - return false; - } - } - - return true; - } - - private bool CopyBySpec(string srcDir, string dstDir, SourceFileSpec sfspec, - string[] specFileList, bool isRecursive) { - if (!EnsureDirectoryExists(dstDir)) { - return false; - } - - string[] fileList; - if (sfspec == SourceFileSpec.List) { - fileList = specFileList; - } else { - fileList = Directory.GetFiles(srcDir); - } - - foreach (string str in fileList) { - // Spec list is filenames, GetFiles is paths; convert to simple filename. - string fileName = Path.GetFileName(str); - - switch (sfspec) { - case SourceFileSpec.All: - case SourceFileSpec.List: - // keep all - break; - case SourceFileSpec.NotBins: - // Mostly this means "skip obj and bin dirs", which happens later. - // Rather than specify everything we do want, just omit this one thing. - if (fileName == "RuntimeData.csproj") { - continue; - } - break; - case SourceFileSpec.AsmSources: - if (!fileName.ToUpperInvariant().EndsWith(".S")) { - continue; - } - break; - case SourceFileSpec.RegressionTests: - MatchCollection matches = sTestCaseRegex.Matches(fileName); - if (matches.Count != 1) { - continue; - } - // Could probably do this with regex... but why. - if (fileName.StartsWith("1") && fileName.EndsWith(".dis65")) { - continue; - } - break; - default: - throw new Exception("Unsupported spec " + sfspec); - } - - string srcPath = Path.Combine(srcDir, fileName); - string dstPath = Path.Combine(dstDir, fileName); - if (!CopyFile(srcPath, dstPath)) { - return false; - } - } - - if (isRecursive) { - string[] dirList = Directory.GetDirectories(srcDir); - - foreach (string str in dirList) { - string dirFileName = Path.GetFileName(str); - if (sfspec == SourceFileSpec.NotBins && - (dirFileName == "obj" || dirFileName == "bin")) { - continue; - } - - if (!CopyBySpec(Path.Combine(srcDir, dirFileName), - Path.Combine(dstDir, dirFileName), - sfspec, specFileList, isRecursive)) { - return false; - } - } - } - - return true; - } - - private bool EnsureDirectoryExists(string dirPath) { - if (Directory.Exists(dirPath)) { - return true; - } - if (File.Exists(dirPath)) { - ReportErrMsg("File exists and is not directory: " + dirPath); - return false; - } - try { - Directory.CreateDirectory(dirPath); - ReportProgress(" Created " + dirPath); - } catch (Exception ex) { - ReportErrMsg("Failed creating directory " + dirPath + ": " + ex.Message); - return false; - } - return true; - } - - private bool CopyFile(string srcPath, string dstPath) { - // Poll cancel button. - if (mWorker.CancellationPending) { - ReportErrMsg("Cancel\r\n"); - return false; - } - - ReportProgress(" Copy " + srcPath + " --> " + dstPath); - - try { - File.Copy(srcPath, dstPath, true); - } catch (Exception ex) { - ReportErrMsg("Failed: " + ex.Message); - return false; - } - return true; - } - - /// - /// Returns the base directory of the 6502bench installation. - /// - /// - private static string FindBasePath() { - if (sBasePath != null) { - return sBasePath; - } - - string exeName = Process.GetCurrentProcess().MainModule.FileName; - string baseDir = Path.GetDirectoryName(exeName); - if (string.IsNullOrEmpty(baseDir)) { - return null; - } - - string tryPath; - - // Use the SourceGen directory as a sentinel. - tryPath = Path.Combine(baseDir, SOURCEGEN_DIRNAME); - if (Directory.Exists(tryPath)) { - sBasePath = Path.GetFullPath(tryPath); - return sBasePath; - } - - string upThree = Path.GetDirectoryName( - Path.GetDirectoryName(Path.GetDirectoryName(baseDir))); - tryPath = Path.Combine(upThree, SOURCEGEN_DIRNAME); - if (Directory.Exists(tryPath)) { - sBasePath = Path.GetFullPath(upThree); - return sBasePath; - } - - Debug.WriteLine("Unable to find RuntimeData dir near " + exeName); - return null; - } - } -} diff --git a/MakeDistWF/MakeDist.Designer.cs b/MakeDistWF/MakeDist.Designer.cs deleted file mode 100644 index 5bf3734..0000000 --- a/MakeDistWF/MakeDist.Designer.cs +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace MakeDistWF { - partial class MakeDist { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.descriptionLabel = new System.Windows.Forms.Label(); - this.distributionTypeGroupBox = new System.Windows.Forms.GroupBox(); - this.releaseDistRadio = new System.Windows.Forms.RadioButton(); - this.debugDistRadio = new System.Windows.Forms.RadioButton(); - this.includeTestsCheckBox = new System.Windows.Forms.CheckBox(); - this.goButton = new System.Windows.Forms.Button(); - this.cancelButton = new System.Windows.Forms.Button(); - this.distributionTypeGroupBox.SuspendLayout(); - this.SuspendLayout(); - // - // descriptionLabel - // - this.descriptionLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.descriptionLabel.Location = new System.Drawing.Point(13, 13); - this.descriptionLabel.Name = "descriptionLabel"; - this.descriptionLabel.Size = new System.Drawing.Size(371, 35); - this.descriptionLabel.TabIndex = 0; - this.descriptionLabel.Text = "This program gathers up all the files needed for a 6502bench distribution. A full" + - " debug or release build should be performed before running this."; - // - // distributionTypeGroupBox - // - this.distributionTypeGroupBox.Controls.Add(this.releaseDistRadio); - this.distributionTypeGroupBox.Controls.Add(this.debugDistRadio); - this.distributionTypeGroupBox.Location = new System.Drawing.Point(16, 51); - this.distributionTypeGroupBox.Name = "distributionTypeGroupBox"; - this.distributionTypeGroupBox.Size = new System.Drawing.Size(120, 67); - this.distributionTypeGroupBox.TabIndex = 1; - this.distributionTypeGroupBox.TabStop = false; - this.distributionTypeGroupBox.Text = "Distribution Type"; - // - // releaseDistRadio - // - this.releaseDistRadio.AutoSize = true; - this.releaseDistRadio.Location = new System.Drawing.Point(7, 20); - this.releaseDistRadio.Name = "releaseDistRadio"; - this.releaseDistRadio.Size = new System.Drawing.Size(64, 17); - this.releaseDistRadio.TabIndex = 0; - this.releaseDistRadio.TabStop = true; - this.releaseDistRadio.Text = "Release"; - this.releaseDistRadio.UseVisualStyleBackColor = true; - // - // debugDistRadio - // - this.debugDistRadio.AutoSize = true; - this.debugDistRadio.Location = new System.Drawing.Point(7, 43); - this.debugDistRadio.Name = "debugDistRadio"; - this.debugDistRadio.Size = new System.Drawing.Size(57, 17); - this.debugDistRadio.TabIndex = 1; - this.debugDistRadio.TabStop = true; - this.debugDistRadio.Text = "Debug"; - this.debugDistRadio.UseVisualStyleBackColor = true; - // - // includeTestsCheckBox - // - this.includeTestsCheckBox.AutoSize = true; - this.includeTestsCheckBox.Location = new System.Drawing.Point(16, 125); - this.includeTestsCheckBox.Name = "includeTestsCheckBox"; - this.includeTestsCheckBox.Size = new System.Drawing.Size(153, 17); - this.includeTestsCheckBox.TabIndex = 2; - this.includeTestsCheckBox.Text = "Include regression test files"; - this.includeTestsCheckBox.UseVisualStyleBackColor = true; - // - // goButton - // - this.goButton.Location = new System.Drawing.Point(192, 59); - this.goButton.Name = "goButton"; - this.goButton.Size = new System.Drawing.Size(88, 47); - this.goButton.TabIndex = 3; - this.goButton.Text = "BUILD"; - this.goButton.UseVisualStyleBackColor = true; - this.goButton.Click += new System.EventHandler(this.goButton_Click); - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.Location = new System.Drawing.Point(309, 120); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 23); - this.cancelButton.TabIndex = 4; - this.cancelButton.Text = "Close"; - this.cancelButton.UseVisualStyleBackColor = true; - this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click); - // - // MakeDist - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(396, 155); - this.Controls.Add(this.cancelButton); - this.Controls.Add(this.goButton); - this.Controls.Add(this.includeTestsCheckBox); - this.Controls.Add(this.distributionTypeGroupBox); - this.Controls.Add(this.descriptionLabel); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "MakeDist"; - this.Text = "6502bench Distribution Maker"; - this.Load += new System.EventHandler(this.MakeDist_Load); - this.distributionTypeGroupBox.ResumeLayout(false); - this.distributionTypeGroupBox.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label descriptionLabel; - private System.Windows.Forms.GroupBox distributionTypeGroupBox; - private System.Windows.Forms.RadioButton releaseDistRadio; - private System.Windows.Forms.RadioButton debugDistRadio; - private System.Windows.Forms.CheckBox includeTestsCheckBox; - private System.Windows.Forms.Button goButton; - private System.Windows.Forms.Button cancelButton; - } -} - diff --git a/MakeDistWF/MakeDist.cs b/MakeDistWF/MakeDist.cs deleted file mode 100644 index 0b478cd..0000000 --- a/MakeDistWF/MakeDist.cs +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Windows.Forms; - -namespace MakeDistWF { - public partial class MakeDist : Form { - public MakeDist() { - InitializeComponent(); - } - - private void MakeDist_Load(object sender, EventArgs e) { - releaseDistRadio.Checked = true; - } - - private void goButton_Click(object sender, EventArgs e) { - FileCopier.BuildType buildType; - if (releaseDistRadio.Checked) { - buildType = FileCopier.BuildType.Release; - } else { - buildType = FileCopier.BuildType.Debug; - } - bool copyTestFiles = includeTestsCheckBox.Checked; - - CopyProgress dlg = new CopyProgress(buildType, copyTestFiles); - dlg.ShowDialog(); - dlg.Dispose(); - } - - private void cancelButton_Click(object sender, EventArgs e) { - Close(); - } - } -} diff --git a/MakeDistWF/MakeDist.resx b/MakeDistWF/MakeDist.resx deleted file mode 100644 index 1af7de1..0000000 --- a/MakeDistWF/MakeDist.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/MakeDistWF/MakeDistWF.csproj b/MakeDistWF/MakeDistWF.csproj deleted file mode 100644 index aad43a5..0000000 --- a/MakeDistWF/MakeDistWF.csproj +++ /dev/null @@ -1,100 +0,0 @@ - - - - - Debug - AnyCPU - {2415F337-2CE2-42E0-A8A7-4127FEEC94C4} - WinExe - MakeDistWF - MakeDistWF - v4.6.1 - 512 - true - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - Form - - - CopyProgress.cs - - - - Form - - - MakeDist.cs - - - - - CopyProgress.cs - - - MakeDist.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - True - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - - - - - {08ec328d-078e-4236-b574-be6b3fd85915} - CommonWinForms - - - - \ No newline at end of file diff --git a/MakeDistWF/Program.cs b/MakeDistWF/Program.cs deleted file mode 100644 index 1190d86..0000000 --- a/MakeDistWF/Program.cs +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Windows.Forms; - -namespace MakeDistWF { - static class Program { - /// - /// The main entry point for the application. - /// - [STAThread] - static void Main() { - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new MakeDist()); - } - } -} diff --git a/MakeDistWF/Properties/AssemblyInfo.cs b/MakeDistWF/Properties/AssemblyInfo.cs deleted file mode 100644 index 52e423e..0000000 --- a/MakeDistWF/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("MakeDist")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("MakeDist")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("2415f337-2ce2-42e0-a8a7-4127feec94c4")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/MakeDistWF/Properties/Resources.Designer.cs b/MakeDistWF/Properties/Resources.Designer.cs deleted file mode 100644 index 1dc3aac..0000000 --- a/MakeDistWF/Properties/Resources.Designer.cs +++ /dev/null @@ -1,63 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace MakeDistWF.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MakeDistWF.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} diff --git a/MakeDistWF/Properties/Resources.resx b/MakeDistWF/Properties/Resources.resx deleted file mode 100644 index af7dbeb..0000000 --- a/MakeDistWF/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/MakeDistWF/Properties/Settings.Designer.cs b/MakeDistWF/Properties/Settings.Designer.cs deleted file mode 100644 index 981076f..0000000 --- a/MakeDistWF/Properties/Settings.Designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace MakeDistWF.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - } -} diff --git a/MakeDistWF/Properties/Settings.settings b/MakeDistWF/Properties/Settings.settings deleted file mode 100644 index 3964565..0000000 --- a/MakeDistWF/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/SourceGen/RuntimeData/AboutImage.png b/SourceGen/RuntimeData/AboutImage.png deleted file mode 100644 index 90af29cc5b084e81babd5a0d63f346069c8ab9d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 539507 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�su2bM0c;d!rTx6 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 z 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

TlY&)caOJ4 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

~ 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�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

FN|=k5ZwTwH&d)wMQX#c>ew@I0 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

6*N-1;De}9aYq@uQhmI<(GeGAm; zU%*JE4#x5~{7_N!_%@j;5VkE9E%7*0tm$fhue*u2s-JI$htK zSy-m(q>Pau6BD{8K;LCFb(bnMT{(Jf0~}_893e4!gBtcs$UKBYJk z>KV~LaAS_#2z8oz`h~@ChRzZGsMb0&U&-n-SDCzou<0W{Oi6Hc@;@mQN{?pYaPD%F zNmny_G{<9&gu50kBm7Da+QuGIDCrn@y?c{r!8-e7*f)O=w!Qi@Bn8GP!h=y_khoj5 z?fG+%mYqzJ$-W1dE51UA7d70~y4tziIykrs1ZVNPFZRe)7LzS(h2-l%9xb~Zu%St+ zThyM-l#X0o?-iN(d3s+^!#nx2Q}lYI5nZ}0cH1_A<)+0-_hHF%CSAdzb@?+-wqg(AIV0Xla^KgNcP)oc(v->bg|fUdiEpoFg08<3Mbgs z5dJ%;j&3n!P!SaP`^CsiYF^5tQpnK!IqG_W1Vab*r(1#U z2rabM!3}$VP`JWiw9c_A@6t_SR|3u04O4EjO9=y4{Rm~vcZ*`jY2uX3^mwE@S7q<8 z%F@p`=VL(2wa*&R>|s%wUDN8m`%^mhMbgXH+ii?9bR-oLyq1}gd2x#5{VlOJdBx&e zJ{@fw>>508i%g0m?tGlTjbT#EfZf(LYgoK;QS$AOx-FWAO0?@)e7jPkv0d*|{|b0A zb>H{z?H6RVMkepu$(FS_rgTKPtBYjp9FeaRt=Z2H?&Rqz8LP?Ne#3C*_r)m(lw{9G z26$?N2%A?XDBelRvs3!VhaXLDD$v_dsen%lU!NT9oJa3QXa8Zfio%3DX~{`;@Y&Z8|P| z`rx>{uI$-ixqnvbh4tLKRKgpwLs#Pw>*Tz`RkbT+R0W%`U7tVs3EK_EQHBfY_HeOX%G@zh?%*l z9Z;@r**3fB%qR)G>^*YwJ-am23Iz?r-r1*7FYLgThN})(b+`7muY+3G_4iP^Z~XVx z9BF>knKsn^)Tj~)k$j;<>Q*5s8YI8BYi>&mepEuFXJvpM_cMy}#c*z7U?v`=7?R03FzznLq3f!Qy_@sR)_u#|5r zWVK?MBQ`((0;(JV+yQf|xxG|%t99~BDG1VkQ z(1p9YKg>IwC=Do|{kn3!@pgIHqj?x<0#*6QJJgm?#`qcbRD_gKF(bn#U-PG7QL|+p zK#+P!wuyGn1yT9rs;P6osOjboQC`ZObRrco6h_U|Ir0mamTRp=#8*$)A5(*mH}bje z%&Bd1;Z-L0w6&+`seDAAfWT+~2zE=L*`vLFDAO z9(swq5ocO%KCCZ**}KjCks*ynXFbl%N9oYKS6chS@Yl(HeYk=7nkFh%IchK`V>d1Y z)7)Tyj>U_m`EPGzX2=y0&&AF!bOI4q%e|Yun}*y+PJvd@L9@`&#b4?*8ddJ5d3@Ny zdbXjN3xoZT{9XE@qr^VJs?DQYC#-+A@n2Is4}5RXNcG~2MGMpDwLJKI^v+BuLP-P= z`;81@Bh5`6Lvv8b)Op)a&PBM(@Vc`~0>kv2nJm@)E&OCP*~f?9 z7w*`=8;Y>k5!FKtnbQy^o>e3g#0Nm~L`}^soUdrPho;}A{b;Ul&S$wXa7U9}^u9CVnxwPU9SQ!^y}Ytx%5U6IU0ZX#wX*|#U+D27=;-6r@;?9MHq==W zpEoJl!x5L~G$Ta_jzcQ*57jp{%1+Nd>wU%-$}V;Pe#%LKUA=SX1(oHfg3dLSZlQE_ z>1YxCQ^t|W4L{lRXXM#=lRqSUb$O)RH7q54ycoiJ)clw%b;UmmZ|9dbo-ZH$yL{~w za5xs|b#%Gx?su!CfoE;_x-%vt={Ym=H^D<9JF}}lRmGX+D8V3;loCs<(4bRa-p)9j4X4h^%%kW!(>(}PG`GlTuP09TK*Em3l=4q2x@O-(2= zBsrNs=tP79(BV3gvn}Wel;}fbbRNe%?HC`qjUDw3JNsgM9Kv= zK8SwuK2>9_zrX(x3^v7bu{G4U>J#WJmw6LYC^?0F);n17QWT9Hb<%cTSuv?dXNpUX zOMVEY`24{%6Jqij`CQQZc6uhh?qai9NJ06qGT_p0UD~dX1Z?9t-r(Jhq zicdx0z|~2cZ*$&@BpbVxBaV&i2?LimCup|&!i%0&&Z{mZ5-~bj9>4z+bUKD%RbMRG z$rp~kRMpIF^gUb=7Ag%q`B-~(G;#eb|4!}f^HS)S!Z~-W!D5z74#xYZ-76y z{oR$Ljmx*cA~h?+i77=;8>-5bgSwJ;((Zi;DvFcaRnjb?h%Lac|9+?3e>*@*DbSN^ z6u@!r<)zb^Z*`YK*~aW4FB21Hv}9Ag8~XK2SIs@eLQK|w`K~E?_drJO#s`1HO6Lj) z;lOgXirpe{J0WMmul0u|FL->u<{Pu5K-#*HVdk0zdFktZRcxfbV#kE`EGiS_09e{5 z>f9v*Gsz4!dukOVq%FHLhlb0nSk=VY?w zCJ4=eI~sEENT!bk1jeoA-cvgyhtJj=uZ0SVhycW1zXciPMyN88w2gbIlB>px1~JJ! zy@r(ln3B}GGd<7#-VL%VREe;96)N8*rrjk#L``t7=9cbn7i(+q=SmUp+osy2{+HtV zso~wqkko9xY*o+)r4MgEGyZY%;>i_@U0*m&LLAJVJn-^toJcbXxIP=hzZx!sc%n^U z_kg6CtqZ?ZM{PS(cu=zW|AuEPw6;k4D?Basv`jQrA;%7!_Mr+xleKR}KfGb2`#~9Y zxc;yPsSo=`Wv}2c3B8)7wSmi@#t(hON=2JI&aD_PxhJ%d=G^tbjh?ao5UAA0>khRx z%_2uP?uPUM{l|X)STTGF1OauCZ`IYLzYa;Irz53>m;oq}yfeYu`tPjXG6qeUn3$ei zy)NTs^_U?Bv{}2~kuxBxdnR=N8zhb;j0^wriX z>sryEd3K=BE_JtP=dbRkC6Ijgr~$*zu%2Et3v`MjL^oIU1(8s_C@&uxdSOoqnbVZQ zB-RN4K9397frVGE%5d^+up;Po_=3AkJ8S3Aa91>L+G9raB>+v4k>n?8gbhlAe}G4T zmQ((#l5K$lk~B=Ua5&fq|D8C&mv0OI*c*S3k@qy&dah;-l?`RAd#jRa>l^k&d_ThA zD^J1N^)mj{+hxf?D;N+LiWT&Un8hmk5+O6_nhX<(65qHJf&C0f;V+e@trhN3zB%Bm zkN2U1bT0CK0$c78%AW#lCi%i^9`;qtnXtYEk&XuR6qROe*2zA82>a}9Q@3rZz5?Ag z&K+f0wbfJacM~^YDQagdEfI1{NZ|g|=kX2-^!$<=z@3it*En2l*1}h_sGY zqC8MX$Ef{hg6!9DFMc*fjx3UoeJUF^<3QG++sf*8M#Q*7=$Btym+fa~BWIrvXU0nB zZogrvllP4Fe?ToOC;O1;cct4~9WnnfIf`A5(sPi#9pi4ph=6pm3G=4pttULRt^Fs; z{vGkIdzl-SisY{&(VTJmj%pg(Y7liM@<@M%AVJC^SZ)HU3;XQcw$~#>7EBVPN{4Il z75$!?iz<(dl(1WqXqDBP>b(-t-j)K8fA1j#2U{g3Jk*sy)5%3{%{BUHeLxGYq_((E zomHy1K;SL`0oXYc;W}$0KWc`PlS2{SEH;DBQ&kMJzPtXQT=nbI5h~bNMGOd66@5 zQ*r6`dNIiF>ThdVPNlV`nr@20)>jx;1DtO52Z)T+eC~|r7)eX18D;+<7&9^qYa9tE5P%4e6#dpEGph=Yz$Zu8Lx4HvlI7^5Gxd`A#@dfH?y>IEd4leS|BM9Hu;=(m-I2#p?p z{wfp;-}3D?!b_OQ)>YemZzyQ=@lMjtm*}XktroU|xX*IXzv|YAii=ZXsS~7cnVFvU z-W3u$krXN^mG>JtvBko)yMH@(!s6JK&7F3_kNkGe35r<$`TH${JH2^4j^@||pVUE- zjJ$;{2br|VBnwem>}bE2Ic0w|C>l&S#0dn`v^;;T;^%_#+;5rigRLx5W7EydG#7_I zwpmn_#y?PK+RXkWy^4j~Z(lB|H()q_h*qTD3?xM27 zNYwl#KwnSPP6&n=v5;+6>6mReDIvPVDX{+eX|8`_ZY;>kS zncEjv9;7i}tSvu$T6BEsoss+J@L?}) z!ZQYj7%k=Z=2HPf8$;Hx1iOzr8nl2go40ct%44|-4yp(_3YJZ7F5*z&}@^ zWTN1X*3w4!*1>-G`Fs4HaHf`C-BSLrs0HQi#EbxvSpgn$Mn5BRQUe)$VH{Rp$q8sJ z!`1ayf#X$+N>ZHZ4~d#40gab`N~Qqgep2s{GYnJN~gk7%U4@5Pc}p*BO@aC}_K1I%kbN zSvsd*SEQ)Jf{MB}Vcb~7j|DdBReakL(q`j9R&1j_KFa0p;h&zc zi!CJi486+=-SD-fWXvReE<&a^mFhfHQQD#l;FYJaOY)KMK5wR8S*o4yn z{q=v6`wOwS{$X25(VlDZkjR2Zb%VcQf=QS@j6_Br4lM))wF;jSoJ&g%%5o|S3cUhY zB^>?lSvdr^m{-m?55zs2@Y?_9qOZ65A<)ApZhNwFD!WBTiJ-<0_nTIi#>*;Zh1}lGb{Z!xPCfp4M#0w@Fn7Z+~B{&gON08q6y?UfeJ_Q{i75}v>BZf-8mOdn1! z<=zG4Rk&Ye!q7^3*z5%ne9%3mF6nZs;(L}+u1NIu%2xf{PMwo#Au1jXs^NHm7A)J{ zfKvolR=`s?j*RURg-f7HyVFNUv(BD?`N{1OjA*uP{V3vajPlj-R;Kf0_{hS!-|_E5 zkgal25j8GCzcV=5Ea0>|=6Yu?@S>=xrmjKRsiUbwDikx?DVTWM{|PXZ8nf=gnu>_> z|2JFnLkU`B59IrcNM2N8CzQ-Jp505%QYVf%NJ5rO9AkIvlA91dM}8%wx9<(r+E7)U z-(zw?lF&9DF5smEH3aj*rW3M1?CPO^g1K2tLaH6rZs8JK!J;5Lt!Q0TN?l_w5C$(& zo60xSnu;33Rj7YtowyjM0~*oXrzTlK!2)Y~ARL{H4{aaLL0llJ1g&tZlzUJC;MTNA z-&e7Ry7o}=XPeaRkhY6hy-8EYQb~W7W1-XMG71627ct{Tk`jQe=-!U8u;kH*stJh0IhILnG zH~W&ic_?;Y(RT^C(kQ@BITs8TA9uI8CiC^9Wr^QWCMWK?(5ElQ*tK@qhvM;$GfZjGxw~Mr}bervTV$NPI;^N$) zx6Fq9(jDtu_vU}JD=3uU3O9>-b^bi?U}El~I}jD^W!B_-i7rhKIQ(TPHh=cAFITg3 z-yzTm5N%|9iFdY9*{F@Kf57F$#2uPcblcTRN94_ODN3C=e-EQ{VvJ*axc`aa$>o%n zsKiA!uQ1Ulj~$dO?)vHY+N@2{ux>kIFLdF#f(+-)ZNN{=+V0|WofrmuNEC7wEMwYH zWt7Qee{U-7La_alwj4Go6*3oLw-Q*29H>+5Y~A^rTFf8IR-5Ueh8-=51j>Bn1@dgf-{$$ai!e>% z5V>EG`QLgiHL|xJ0Q;;Cf!TlOds(r+e!X#CcBeQus&gV55%(zw|5HjUpHW6J7MA)$ zHx!@|$LKfi0M}L8lAMC|F6{qWs+e*d=7W-$yG6(54b?||Y3P;q@@Eje10vyZZ&6Cs z{$VhYy3Mtdu8okXtL9|T$sNXfN@|rW9TCJIQ?TAw+>!yv$feC{7~SP2Mj3^<}+B((~Qfa!hp`2Ez!^i5D6B@%*7$QwLr zsnQY@P0-bU$|@F6+{z7&ec~OFUc~T#d+hvQ!sI}Ii^{C>J+wlv+|a#Sh8vxT9mb#( zl~wg_;GeJL_KKl6S%(wDxtqf(=Z?9n<4B7p-&%iFYfvt0LCKW7-Q5Z#?SKj0xtD2b z6T8yZpIc!~mw)&Ex!)ea+|?Ac`*8FBEWkUXH<+!<6?dtev&6-9$kVvJ6WJlm%MU{$ zP4&|m+n$Sd@(K!OIyB7&k;RMJKrW)BvbW`E?(E;e!h+cKj#i<;2;V_7x=IG@^iKB}z$-ejE zFqo5o@;L=L*`!ILnqx-wkLp^uAjivrjZ}0VSP0bSl>X`snA^tIz`na9N)?lWnB4Vx zz@>1}V(V~PU037d@ngCvF7WKEwW&)(5X;IcssYMdsowVzJHF}(CVi5v*&jcDvli2I zaKPpM z1Za>eu1>@$s{CP8j{6%DVvARmq?H!H{e+q9Ra*)hZo%smQV}{a;ieYJEC9T;uO}Um zXs943-K~aZ<*Ez(Wq${?d8xSTTbONgl}8m~ZDbjB(YslCeP9MHmbL{tRM1({fTKGX zMf&K-YNkSGCWb2VoJF*gkgH?GxZd-$7Eou>Mm|A2$Kt$BS( z+;<;hYLY<2V?LYYmja)WQ2TeAq;H$%-i}B%olfYk@Q*wnizq&++&$q*hkcK|&qIZa zZT6kprhLt4|R}Pi@8N3-2}B>4OSn=BTVms;`QR|x#<_Lo{Jx~0Y-I` z(JH5ZR}T7a78I0L8M-|cZblMIodeHwt|jBX0AL}5<8Yp^A@AEviZ7MKVr}C!pQlVB zzbDhu(T!+Axj2cc==R18J%1SjmvOu9jEI1S_O{r&1X*`E?-OsY54+D9iD!NuDVR5i zx6)$~Zy*kT44H1Vj1jl!)Po|1+`{RDWztOv)}FH&+OIrQ5fZTUOKLgXBKOnNGKjyx%KkXrh{D@HQlx`82cGLPJ^f@usG5G{RF^;laD?2X zKb>j2ua!KE3G>hiE9k$^XBZ*Yp!mElj*SFbbh3apyKKTf!}(pT9Mx+^r@^2_A3jin zas$?;zFZDa3Eix{n!DJy&A41*Xbe2r*%!K==ZsDSKcm{tebkw`nf1~}Co1ucpVTJiSl6o=)Lk%#tGGb6_Jw!o<0==``eQPI` z#BKi|+>uY2wNo#OxJ=A(S{tm-L8X4&t!J=E=@?CXwkVsXZBC68Fb)oWFrL8veAUeq zFi}7%AuU=`=!wkDt8CB)F`#)o)BXb|%I5zr&Pa>IqQWm;fkZfC?9_g5(&Fm+NyvC$ zM;1>O(Wo-+tpDIENwEd%^Wzs1Z+0c8yh`Wne9^Q?U7CoL1_qr@UQ(&uvCoumL4VdB z-P$slGb2gEirIgMVONOe0d(lMrHHla~Jyqx_){FadP3bQ=tg{_}ZW<-hRQMBLUeP8tQ9kk+$a zF+T8?5&OL2&aMIVY()LUTwI;4y91hGMXX(*w7`G+dg))PbTj17Pko!NM{ant3Al3G zst)z+7MpTuLgb5(1lT)YY=-?}iT#LAs&dqrkkf2~kKQ0|OS|(GIWGj)depmHJ?~{g zT=BZ8Nh_>OPevJ+d6C3nA`tScOB0Fu=UHY6;_D5YGJJvt`cQaryj2wNZgR4*dLf2$ zcdjzmX3O&XWLSnun~ydKIw0uj0qtH8>4SR6YDq6MTEc7w)FDH%%kf{TvF<)Nq~nF= z45Lmb6QerFap$h3>~jU*ixo#f5xgEqRvRK_^DD$S6bZQ`wv$ISGg}GP`z>SHvlrX#eEE|B zx{ox-B*iJZW${RFsjp)!lDj)|mD~~I?G;PkKW(vRdw{hU$NyeWO6b`$4<(^;Bcwaj zrwOeFg8hgGlON|tBSnZpy08e>#CJIZ^QDbQ+I9R7kLmgXDQ*OV%=f+<&(%e#wy>(VMUQMdo4%H zLV;KKk!5jKR4N88NWqx4DE-KHG^fJAN&K3u^|1r{W7na2ro7K5v1-)64E)~avMbzZxeRv_LVb#>jMyRNv*6}jW7neq?R@Vjrm_NyvtxeT0xITL?>)r8XB8Z6^}Glj_a@yWCK zbIwflGjmoN(Ju<`no*6Jdz+yKzIg!(=;gm&tiNlc;aW?PKvfp*zS*g^kd%Wm-Q5g|Tt~$!c_t)3 zHfh-k_+H$)k6qSRD1P!k-H2*dW$I3247D)v;p`$W8q?d^olVOyGZZgRwO2dr{`>@l zee?d1$$K{q5w$g;wRnp}$kh1r+($h!QHl`w5-V+R%I$Fp`6uWvP?C|JE%@EJ_C_u^ zp5WWLvwwY$DSTUg`HodaUdU}ZPVGcV@l{=H3b9cj;HBHgzsFOfuShE314IWN!oGGITraY&_ko_N#h zc3a6eSFvCDt-SGw^okNPPXHrHh&Utdm~x^Li$;$wMcS)ldzrU*Rd*>_@CAy7Nv3b9 zVd-`_JuSgGY-p&yuG+7@;iyr-pc+2o5N@p&@QfrQbWE6IC~Ug|85TnaAVoF%cyxJvw%Q# zfx~)$Vw9^|q22TtNYz(_jBUP_v!_r%{DKve0$e7hJ_M19*3D}Wu%8Y~;$DtC?9 zfdTV@S07K-y#fo^6+(xaE}R>x{o&mLurX@OHmx=N&tFz_;d*anOQ|LuArR=?jpPTT zCOktFQXnYz$P^oaNJWT*7;nTUrXEhV|A8$6m{=>YB_n*Q<&=NbG&s+9r1~foHF??w z*S_0G=a0U-19EH|Sd+qb;g=^Od&`|?XCq;Ri7rX9WUJ0C=<-z;tR=;CeZ>;tf!JT! zu0p=e@uneMyu59im&|C-r2N*=QIq;K0GZS*bpV*}OK-N(E zP-bXV^m{feg*gu;*Ev4mVq=-mX_u_wq=u7l@N$f5=_`O+n&y`G(QDgmoG*mLm~xNH z3RYElZKowCE}w5@@A}3KUbBGyUaS$_HAps52}u~4g7j{)*w=EEqCQemks^#hc!Xj1 zNyK-j$G!w<7ZXW#J@{P@&e^Kd#z z*fw!Y`m3O)^fKRaAm3fy=c|$z7m{;~irttIWc9k+xk-i|Y-jhcQxmlA>Uh&f))Snd z3p>b!QjiNIBL`I8?@G00dHs$7i}@>)g=A|w{LKl{U8uI=Jelosr+O-83@X1Ihj3~3}e5Ok+;6zo!r93zG zZ`&;;0mT&jCG`*rhn1=74Y{y~{hIlDsHSx~p0;SRoRNArb_asPbZ^BY}FN0IT)qiE(^~zxPG=ZxzZ3nh^}Aoc%(~{lWv$Fbg+|Q z*19nRI}i}u^pb?J?NUWA2dO&@4erlT%)HCX{V-{~HeJ$ZXZkijm$j@V9qq|jq}~^+ ztDOgWslb-5x9*O?R4XZ4-MwSTM2VSNR+}v5V+ST%AtqP$2b@4ppTPI7C1@TdXkZ#1 zuzt2u#w*xg8k2J)Kk;pYD2wT6UgT0~2~Sc!s=$!hU!IH#c3$^)oto{ha^sd}um6(Y z7P^G`FLHly0enCT2-f5#FkdE@N@!^qe^Gy1SCuIq=sNn2#6fX@3+fr(+vqf4fPd2T zycNU20U0e(6`gSrd+_UFYc<6FEBksS-}?=grol71wxy0v*Z%LR>D^YqCkcqhbZugzQ8JznO{dL5j$#TY7#?2oYrwji zL)t^9tMAz=!@rVI#O|Cp=i~25JdXoEw`v9_d+Ns$-WF^V3@?TmH=jHEn(ka(2Nfyx zqQ2r}g7lSs%w+wukZD=t=Io7X5uY%od0E+rROjaIUD*d&qSs39T2xi9Hhu=vLgI5B zop<6?jed9lg99X(M*;k#W4PO0S&b`zoZ}SzX+|b-YU}n4`u9HctI6MrrH(1gM)No} zBenC!W8(M@kwkGVr-&P~UghIPq5M)VY6a@|$$ij=hdn#bgky>=W_}0omPI{ycc;2E zC&l=&Qc5NW;#bqak%E+5$LNU+9~N?J9j};7@Ax!Kfh@arVw#tBO#mGJpRm1hFFiNK z!yPSr9J1fg@;yxFcRsv2I(cKOOr*OaN2KbgZzHW~y3N3Gu)EV_mWM3^h7lIe-rKrQ zWI&$$XGd*ZV*RN(bid$w+jU4da>vO3D$@S$`?`Nk6{@f{2?Fk7Wj{#dKWc&wk7?)W zGCq{s#vP1J)K3HHs-ubx-pEfenD?T&+JK*EpfBK2Xj+oA31LO6-or>q!%!DOp~ z$ht=2J1|00mI6xu4pGio+?3Zs+BR84>?B`!u~WCb)n%9l1E$s;>5myXopCiGgjL2+ zeA}DZki9KIwy+fk)>(h5_J!Orow8I78fanc^Jltl@5rt`4{A92hY+ZJiP{&?qX&sv z;rFBcy?X!oNwf()%Q>vN|9kgZX4-#) zj{fV{Sk=9dA+?5YSHb%9X`HlZGj;gdJvU?9SEJ>x^P;{k^l61N5W&syXbsqUHnIDJ zzurHV5WM8&zs}9KhPUfap9ripRaEdHVjeHg2@()2rsKxYS3Y3Vq~R_3rhju9$QF9G zI(>udr+WML+DukTe^B*jzgsc|MNSCZ@oq0a-&qXB>|OX%{qw7rOch^O{913$#zwwI z%Jo9Z1fp!zG`+6=^tFlCyrcJXUxGu&KX(i!bbZ-vL&hqW&{#sleR`-HXy^9r^QPTm5y?2Sv-58#z>hDcb& zvtUuHH)fdGWNe!C`v@dg+?`K|$0G%|m}<~j>reTl9wE=H<4b->&~fPE{^ePhN3h$% z=LJ_B4tE;|X}pyj%Nf)8#HV4%wx@spwYtku;X3;pC&1toQI%Ww`e{_>RySqRqjIz2 zPXLmm;Ay%=Ft${~(z;e%u_U#Cu<$5A2T~Ryo_U9GY-m)Rb*PB>&;UB2KjlwD5+kJ< zUge}uSSZTjg9Qd*_&|YV;%-=VDcLf!Ecw3tppl3F#j)XjA3et>2e*+CQ|5S`gi_`B zaKf;35yvOkZTgA*N)25R3)~}wcXR<{#={6P|>%q_dB#wOkBw1H>A;sOafM;c8EBVQ-C0q|| zZQN!$2MZ4BnFf_^3Nb>c2~8t@p8gB?lYU*qB!afze9KN_XKTDF3aGbpa@-UVp{lBi zd+=Bmr;$|m^E`U#VtKVJKjeDYwI!)ao@NFNA8K#Y! zn@dj*^Kx=%03&=P4MOP#3YAVt>mTLrPm!4uasDZrpFgb7xZ}1+2zJFpU-WogP(ARm zTZd%;NxU{zN(~i?XSDwNoT^7N`k#C8XzDnzoakNRCD5aWQuiOUV(W$o4S;*oLd6s) zaNShRKj2X~p~q*8HnHVVQf6ueX#deGQ+e^9b}x|!x)O={@3AJ z1|i;&X-?u8k7}Ej(of@1*e1iD7*4y-pmcPbm|i{&WXq)<#7+Ai z^qlZg4r8uYao=oQ7EMGd>~rFVS9Vy03~1`rRacVFZx3JkeC)7(e~58~@O1lj<6~|f z81+@-v2%mE$QoGgS(u|H8lgPV_)+Lx5tRNF{>6J*Foy)2Ttcnqyi4GXz@kZhWY-1$ zCiG@Bl+ARyFSB0L!CfPFJrW?^7NYKvnw6Q3jr)5O_?YlzzjZJ2$3H%8-yJuD4MO-qzLD!1ZqDDim6=PVxZ@)0GST&QEeC zKi-*=aG6bpSbjw-n{%oxG2_9BKYv*6^OBJwNHF@$6W@&>!a3lV>o)2Qws>aRX&Z2V znGHPrqD4CR?5@4@LN15ivx`x;?D`K3YP}{EKz0(;;d8Gm{=U_bcuz;k_fzC4*^)kt zk9`IA$7J1QuL47l%x;!aE_V$}B1yhK5-79jiy78l}8Q}IcnwgyUpQDfKUp)EH@ zL~Scx+#4!N41%XDtRBmeHitgnr`+f;=V3H2)+~ zHg!YE7lD?aqR1!@Ba8ujZrgX|_a3Y8uf=FWk)QtE4|=^L2=zV6x!{{u+hf&K3BENl zR|3D|YC@04W?MpL#>!e~1j<%w*`j7#)Azl6Z>oMe0&wn-A0f%j%FK=o791P`9Kq%u zR6mzzLDK`9e}lx2k~P{^eC%$6PbVZM9pib?t|fo1XZjZ|Q%n9yuw_94Tt5#j2U8+# zUlQyt#9g^XS)#yc%$AwDF2y;r*WJSv)Uuc2p~n?Cg1%Gn46hd$Ym= z0)C++sX#``_Z#i^O{bM@K1L|@Vs<{0eY1^FFby6_n=yL)q+0T;?dLn|9rs<(Jbq!F zOMRm*Xl_o4TR7|=1J(Y&fQgCgZI1Q7=c5_7EKothdd=I#&TC`+Tc4~y(NJOw>^0aM|GbcenQ|oRTRxWWWUwn@c~D55>uaD@ar?5@PIm6Fe{wWR zpBwa(C`LF6Bv4cLd?)_nGaY`9BbDEF%9}=R^q&w~aML+lt1*$sCWM*iRVp8=<(<5G zf}*`XOOlvFIaB3RO&ph$$1{uSj^t7HPUbR9>j-2$EMjDvgwSRh>fXJ5?4UX9<$w6+ zWM_V@n;%xcVw{#6C@te<8olV+G;d=xgU-(0IFyliSep%$SBNXSb+Xu(Qc}suKb4Ff zzmrLV;gzIZ)bT#*HrjZYz17E@P*}O-x&m{2zseIGq-CjX@KW@5HLYiIQB0G3 z9A#hZMHMy6XC|HmmbJWd5y)Nn?mUtF;GJf9_jcpe+Vl9^CaRLin0R490Ok)4rJLyq@00jcGTXKc8AME&`h zgS5=G;myL$p6u1-`b);vM+XwV!RWH>5Q5Zxs?@*p|870Z%& z6J_cF4yJ3!65UcS)7!&k$4FNvgmXggZjZ7pKD*KV$ z4r*i2)a%yd1F2T^zgp5dI}v)E`O^_1nyJBPmCaq@_*9BfZxp=BH#)B2R220zrG~4f ziiE5^WFMoxBX;L(ucGU6No(u#Li^d;)937C+sF>`-qiJ;P4^U zZC*o)#aryB?IG zxpl&UHEQt@>Eo{>2mwR3kjyfEW1?4zVr|ZD?yPqDXPbn#Z$mGyLJtqk$W9y`|3fHg zIZe7tbBtHZ%ChDMA^A$Sq+}_(I-V_E9tsXi-#YDTZgbcr8n0a`RLs*3tqNFa;5g2_CkjU-ymt4HR{pS`TxEZ)Y8p$e1k~-Lg;Ljwx^#y}CZL3V zzH`G{#;>U?6fq#epMP6lJzqwCasE`~aldth_4l_i#tr{vI-)`X8+A!5j@#$YK!@)9 z<*K)}){~C6&|$HSzk#IqCjXOo+@$mHZW|VK8@@KZvx^Qs4|H8Vkn>u5 zd*Ib0b`S>>SVf!jkp=~OBGC0c2Y~mh0!e%-nQEBL6P}mVAj5ZM7=FXFiZ1UQPyFVX zOP7ymeZF*M@NmtAg=}R^LFfaccs zB#J{k*z3B|cbixXt5Exoujnul)9*M+{L#rsn$`q9yW>q)A@Yq`Uj`8z-G zw{_F?*w!6vc%nLe0A&$2HL8GR(-8Y$;I)4G;u)MCyGu*dtB3;cq2&P%mA^H6H>zTk zj9fl0JW*C;iKU}c_|qGas`+=h@TG7m$P%ECJz&`YQ-Gko>k7-K#Hk4RrUIUtaC(~( z)3ENN*+4|$Qe)sWK`=k>N!ZUhSkuX_Z0M8QsLeB-PKle5o1;~~llgqY?ossH_Wk_p zGo72`n?3!j(CebmqggZAPm})09>*SJA0_J0LP%^a6>*RkA*Y=Rpa_S;o#GSW2;(Eu zd`r17O)KHlshp2MB_sXCnZ%T3=@R5uFH_k-5BJZ$;m)mzZ~&7Bw@9OSDMvFRw2B(ZKP>*jvfwiVI$~v6Nt*%So%ckf)}%7FQQtQxBf`%Bc3lS(aZa))j0U4BY$dUX z>sp=D{3Y}io7w4t+0C{cj02eRk;;W1sZ6AZ1D9ly(DvY0Q$&aqR96UEkJJKt6El(E zGHI-OA~Fb7y`bOv10H`zJEGEiJj+xQW+w;FaGT{?x~U}!3CdF+%;XS8L7$(%#e7z1L;P6Q6#c!Lz}jUg%O=zFsaAV2W=5;^%lFv(Kwvxkwo9PsC>5+X zQ&-WDivF%rbDe4t3O9y_gsy_WakcLCV{C%2A zmZrH76yp8|MHm*;fl!JakM3n+qdvBpd?%K3AAHei`ZJn`x^td7>elwC>|le=$V92x zn4UNf-?qfku3Ky<>?ytC0CPkxL*nWA{-Qg5^ZvkH1O!Q~#Qap5648f>bYb_g#7RFS z?@+cqD^5kcyZGq2b}(!v346m=z~Jq^VxJe8Ia2z2KOCJbutnDn#lj5fKTEzy0HeB6 zkVJm3M28PkZnF(~NmMrq=~8vvw>m^#mPQ5EW{jKcE7^}%>p0pT?z(6} zuPpvv6#DW};2j|B7WV~^sly@?JxMqR)F@&UTV3XkmEBl%X~Pl@-&g!4=3uw4LU}{U z1nxdDHp^23TkS#OBU_)^8&kp}fK6{q=^}cW=HCgV_+ogm@#zap%ocV?C>i7w>28OL zTt@l<@}N{yF|Wx00>a9su9f@V3lgrve>W|CJZ>8)eV2CU<6nQ?i;Iv1ufQ9fhhdB+ z=gZ-q+OOqMP&EjAs8X+B3yumDH&drxa+h%*K_7+)0R~zsD`stjsSqzra^hSU#oLyi zyl(S>foKPL=mGaZ?|!Qo;`L-A%HT(q_bXw+yTX@QX6G7RrPsZo zgr&=ntLPgmBP!0*Hn!y@zjd?gi>}k@kh7($lA483>>RVfsur7#;jb4q1X!C%VfY?2RYB#KIZ7JeH2-egKRcv_SH!k^aC8U;t$PK#Jm zv&yI?j!9h(T}^)8@>EB;%cUcf<)X4c^;j&3Kt+{T-IUnxAQJ)fWG#D@DMQDphJA+& zJ(?o#5H&kJX}Q9>7S2tSwz+g--nI8M~If zA+2(+lJEZTuvzF&iY%q8Ladyk;lH$sA18#b{74iWa25+xp|seRx4?xr0E`ay!v)*% zY0E@zoua6j9_OKirmM3b{;~*>{*{`Br2A{tU*(yUTYpD;en*3`>`V(%wA<$oIL?w_ z(epJmON)KxiFc%AIwxHkgO?&VtnPtNYlG=jUebJ31*k)!fkSmeFbXiXnu>PSJxIKo z$Wt4-*c==q!+Jj@;Z zR|q7M3ADoUxA5L`?ohGTFUVjVHf?*XU`@mu$^P{*d7!@j>&NZ&hIx0uLU(|ha1m@G zZvudd3+Y}W@q`vmuLLQ<*wvr?_MY&q``(+iDaF`c>w;c?JWrng5o-GxXM{IVhn2pU zvx?AChcuADP1BK__eB}t|c7*_wj zdBLTf%~Ggh!K1~9F>dQl%xwcJx}Kr+Qw4Kwx-sKjtG|_Lk#&ni|LFzQ%C`7!HOojy z80}Ub>zhIqCmt2_no|-{P0_AcRpwUwc)X%8v#n`<{^v*@`>6p-D%01RP1L)5_31yR ztX!f2pyv>Z#t!YiS@i(yh7DsYx*h;MwoteY=1BvZOpEfsN#~C_Zy9NWv9S^Zgz^n*G)VOSuCwYegN2N`NSp>Z12^SV0$%2(CyNtEd!!1HiE2kjZgtb1=U zQ0hNg9v-}pkH7oD#-+!EN~2UTdke^^Q`1fRb*kts3mOYuwf8O{@o=-PZ4yUBwJdkf zJQhD0!wED9co|7B&Molu0)Su@e0zF3#@6cM3?sq*iPt-J6I)euc%1#^*8WMy<6Q-N z8fn{WJDSRo>aCmM9si1*;a0V{1|c5%{QX#GsiOL7tLxJ2a=OcN>$mJrdYUKkn)f%w z*1ImGx~}XxZ__Bv#JC$)0U2Z=9QNH-i={r(r53`Y-0U+7>B0sG*W7voya|5**P2 z=Qve}N{_lag>W6E>-L~dm(bancmn>HF?#m^2Qy7qMM3DT3v_&_| zMg29`^Idyv!Fxl7HzzfsIyWDp=(FvXak4kJe}IJKX*t_@L8wpikIleD4%`1IS9p;W zVf!y)6)7XrQ4+#`Q2l;su^iYF{PqI{bttNzD9ptE!GM+K`&0yFw+0ue7A?=nM=IFB zd@exh8WeK9Elsu4eE;+l@yd{at$Sq!0Bg&Y&$iAT|ENEg#HFS#UhMOrYB3H| z6_c6S7Ay2@*aChE0U}SFzfcs?gJetk2}2luZdJ%+yOC#Sck^ses%Mo82%GSq2P4Qp zlXs0Fq(6-}5oM%P^U@x7nVvensEB*qtgwf>&=4pkLtI zX5i7XCAnfUq9#lQY7ls2%5OU{U(?z7_N^qN%_}G_6WIP89ao4!9@e2xfz5O#9$a6( zw^lyZH!xuwXy$#y&S1IdJT+=riCq~=GQH~JpQKwibyko70dyzt%zP&__EQEOQA2+ie_Z}mar1x!a+i4Rd3BWV z8oJ1L(G&b7y@(-W2IN}=uT#_YP_Ex8B#GLLr^Gb`nT=$b9x{b z=ZGoPUp>Id#TJ;7x$Y@Qd6bmUw)0{VX`!mHZ)sK3z*kRMg4n}S!6p1L;wf27n(Z9H z-z21m5*q{x6VO;XQva=%)J1G6(bc7Sw zOT>VyKSzB?P0gLXd8=_cC+30skVgzmDlmxPA}0W27Z!M`6`-Dco7qs3eizJW!iea4 z6_bClnecm?T=05t8s)^Jt|>8ZSjXA?CQjC$+@-VmbYOw)>>FEf1MTZHE#BpBha!`Paxtxmdweg z?U@xNmR8z=IhZw~=*(_gk1A^|%){+e#=j=z#qR=@ZOBhtgjj}!|xaQvI3idfJ|Ld(hO2k@`%K0A&ORBs}aM0LZnst zvLN<9Po8qG`%H6icEiB5mIcLeF%o0900-WD@Gltw;bFXE#rdT(8~6lEM=i=6@>h)B zlhgos88hwL5$&7baplc^ClR*7U;0!*Y3aiK9al+j(v_65wTfUY5Vrd26|D0z4#R-< zc9zNmfLryTMF+g-qva)A?}B#0doqr ze4diS70IU~iLK|U(HcDTCjO{D$N@GAMBC~QV~wv^hL-xyYDa8l0`$=sNO0)3^x36@ z8g-Z~O4KsH4SHfq4{k2liji~Frz>HR9C#1Sn8<2soZo>1dS5Sj`?yVGO1FH%hJ6|o ziaN{TW=YRVJ#IJfT5+YvCy9~evFx(?(s4`t)#lJ|=M)Zi5(BegA za_YOe=XLzWsU~~O#7T1tjd_}i1;MU$&=Q1qQAU-48b$v^1FgR7Yt`CAWsL@L7mBs*@RgnujC z>7vKORBzJjX5*}gnuFB*t`Lpq+{v9J@5OuAXdhpET81U8$+oYusp8nDBMJS)Dhz6r znz+(E+`q;m0+Srd6ssr^4fkX~Wa>Rq>elGfCHuDj9H;>LT_b*C+aai(@dovQCPy#e zRek0^=Xv!iSAK5pi1l@+_XBr%-j01i>y+L4|LPb1-inyegZrQd5oi#j-ZVWJ-%5O& ztEw4y)v+VIQFw%-sZ}#wl+4V3r#0^lAuErqo=^I(5A782n_Xa zVSsy-drkP+#aP4M2-P0<2z%ui8I5wM0E1yUT7(4FjvJR-*EOSRactP|H;H`G6KBJt zJNY^*9$6Pu!1DrXsE|OASMTZItfO#6PT#j}pOg+*M&0*5^QgZ;+JpXW3su8~f5P5u zRn>!|HdgX4RIhZqjttpC36FE)CRW0;v$NJlq%u7CWB+W=CKp!GrIQD$>l8N4ucpg$ zD#PnKGIr7QvbE7|W@l+#w5*|!HqT5Plcg^H44ARM;r^!GAVc~8shgV zw)64JmrL^VjjQb&(>TiCSPQ6Zt4QW&V^dY`D2ru;{zV*ap|*`RxGOYx|9JA!^~$v? z&ja*=bTO+yT<}+$Q}~Y5R+LZc3^mRctFNhOt?5eMbEf*8(uA?1du9;|;snfgv;Q#osTO3Yj<34rruzZbNC?p=3zCt6(t)U z5p*j3rneGp>HKmq+_jDL^Cv}qzb&}tQf>%MG8PetvWo(XrHHHN+)W^vJiQYlOH+a4{~yF>d(qz#RFA(VOAg$ zILD%|^YzQ=_b@}u%mY(!Nz0#UGbO!ZAe6?6S;%HUQwYKdrBO(XWHp*Kc34LNvxhA^ zLkI5G{8Ix^(cU^BLtFmB?YV|9lu)Sol~6Gn2}%*x?ey{T_4MZ}v9~>}MbU)a896+Y zp`}46GPhc^If2)GJI@1Aaqh3kQS7A+6xUv5ezMz*h`mvliz`890{3ya4x}7|0tIUt zZzeXW$J7bboT}p}zS*{J%sE@1Tn?@%g5a8G%)ky`v?qyIcNwtwM{=#!Gz;@?RyPU7 zJOLK9-0|ZcFqZ|yh)8Dob#Q=!l4TLWwbg+6Xu?ZAsc6-vPR_Ugu()Gr8&|whG_I3HF0vG;UZEKxATTH3)H!s@V$%5E$B& z?z8^oGWUG+xMyb%Kw%f%j|~|5Z&+BxOn*Yjq29!cs;O;s)#F9}nAV=H_grIJs|!v? zM|CKCkcI=tI9gv;HsdRM-ow^!do#XrF;!yPwGaNvJ5{aztTzaXCsUEb&W#>a8ZjGB zz+-RQWh;Pxtf9JE3%R)up;q&F)(MCdhFwbhS zm$%zRWHe!kt9N16le4kehe(lUEKe1StZgl~_Wm2ZG4Jy^?>7I;* zkI#E_ETU#=tJn+vL%*T@U1X)0sd&EDLt%mY0{Zc+l4(ntuxl6>~~`P_DsF8e2yvzAJq3@@ybtqm{*- zii!56`wIOgYgQZ&YWON#DL81fvURb)z^UK$Irp(o%NHMZ%fJg2^;lb(owkrr$-CG# zpTyPnxvuyy>R~P`j{8he7L$!(NqJ+(f7lHt;(QnL#E-pN$szvhm|1Dcj_-4=a;=pS zf6?ne6cl$pc>N1x=ALTeB4BX!omj41BT5xnbF=sC=8uk+%e7xp=CaY8wz$5$G$=)N zu}~FG0+kVVqG*paKFp-0Xn5cb&l<%zYxoB|)cxtwqZR zUA=CXP#aH5mc6!eWnKvQ9W8rZ=lSNPJ{Y7c8Ewr(Aba!?U2AIh&uHBL?X*fX-R{+& zG3dDi)@1rY>q{|fc|EbiYU)q3p=X9S$yE89ty*BB_m)BkC%m+sN7Ed~Yerh`C;G&w zl0=WsZw+!vp6Y2gQftnPgg;m$DBQ*w{JO@jcanBfE8M(jcR@m>-ek}dfvozE_k}2X zTMnZVF{S&94?j}Pg2KWnBN>k0LB(SF;XiU2ZM8?ovHqsj^PN`X6@S|7#*Zp$pAP8a zC@DZtqEdfs@$CpOu_s5-l>0O%2N12Y-IP7mu3 zFJdDH`d3eyell-x^R4{lL2BWJvkY;X; zW;;I#e6kNpK@1t?c%DE`7vj^D@DD2NP=}rK9q#z^-&OOjUB|5M45qA=51=(-ZK$0u zE?5t+johD>g;Bt(VDI5h8+1a>uQP6hI5prWS3uZ0g6c{r3)dlAZJOF@`%uU2Ni$Xk`YZB)~Y% zQ7}(h8x_5r!Km|kK7C~Dxi2_RYGd?kn+pP7*s{EM-jRiF(f)84FVzoO4kjN<*|A`^e;K69^w0 zWO~Qnw99lcQ&c7))kO1gtv+@mi81AH&u)dGR!qaPdVl9U2OKy4P8|8X2II*2`}iuQ zY0)7V1$jESV?H-((+%RtKrm$5AQ=hx9GAzQd|S50>X3+NW*~Qc7E@GDo3DhW_q8J6 zcsZ!(^MA1P`tro-3taPrCpN1oI4Hz&KAxyFI6pegvpeBhTyaIxtxUm>o(dGJg&Mx8*RVNvP!|2m2af8nRXX`g33y&n|VvXB+h z^{k5bm(u#>Q9#EM^UsW6kdM?e`UL)$Ak^x^boi&oA+<5%nMSXUx_g#SvXe)DkI%+B z%snlBx&6*=&iir0itgp#?y{~u>g&Mt1wa$1=y6zF?YMSt_4_4Ay!a2a=Lv5K4iW`S z`=PMpiN&C0o zkDG8h+6t6uw1Ui`oi6Zh1-l`;)V>O|2QB1!m z7-J%)CE|FAl;>Nl5u0BQazj4_XC8{(0f1qQ$0p~g5-V1$e144ZO74l-?(TYW>Jf91 zQkwlV#3SG9I*jGx4vnvMcyfa&Siet`{}t|I-)LLa;j4|4pdt+|+TUv-?N&DHnpfFE*0T-E}w^;47LrXv13GFrNL?90hm>a<|~IV-O8pXHY; zIh$HXUtsv6tWQNriqYi57g^4`U5p6{zKilC@+66%VxI;`scs1{Cx+7`mtO(!Z!f!n zd%ZXIo}#-yfi<>}#N^tn>)(9tKI9JPx~ki{v?Z_p*+S@XWF{OSPzq9z4!n$jzC;9w z@b*!cY4OJLQ0Fmkk2P*x{^(di9gL?;_?uRVJH2p@09LGeMEq7OK{rsiw>C+HUKf|& zQ~v%urP|rsh(aI5zYnyuldj=`SgAXp>RqZF*raDR=Knhqjc}Isq?5 zdl9)YnZWf2~<9fQ#)L%MFiNlm2HI( zjVOH}nmVtmmXP0#UI=)yw#~=w{9ujQGvcY1IAM_j-0qDMp|#w8VMFB9ZcRx80IxrP zUEdjMrqN>WSo$}h>CH&?XaHBs^IPKnIVFqx-~bjBjU$=M{GjN?&CWqj?^gchJ9*qj zQ68PJA2##w>qTeasoUo$=~b{EL7!q5wQxTO7ZjPJ=)$ zZ1Pq6I4`YQmNop!(Ttn@@aD}@BaOL@K#*o+Vk4f2mey*T+N{HOefA398qyS6HMffx z`7fKBB7{&RI9PUgm|{onyQ}%Xt)jzjuZ&mYuSnfqW4qfQYYO!lG<7P{w5>X z+7BUpz;NMf9@*o$>Fw+DVKd9WS>`;{Y_#$moTTM(_4O%m#;Hs-U9e?n2u+6_dKJ_> zWjbAw3N!+|1^lie)^wKAQ~Iqy3fJaXi_lqW^*_fUfdWbmO+g7Sp5sl?)ZN%pF;hcm zI&ljFq{m;`DcDf#KA8Y1;<@t$&~oA@ELr^OGve3WN+|_&yHR1(NH?uVh;nK7*(;8p z>M~|Eo-g*n%oHa_gpY|PN4CZpzk|&j=!09a`dk~os~1d8(TLFqr#C2v8~cN!!4m4I zC;g+S$Wd-@OKxL&=%Dhda^V5cmR%x=`%2kSwUYK#c=wN{o45}?(d zRR*NM5~VUv1Lgc{65tvGwWQ;aQ(t7VB$b1$*L_kzf}=<`gh_ePRbPoQ6gug``;mLXIA)I6bh^a|Fk6M*xeWDP37ByiQ51*}sN> zOi-HYf9MPdZS^JXGMiyCq3be>u+A*q>ZcESy-jmpNI5uOt(D36@2u^(25rVsFWtP? zptk}*MU9!(W8y#^O#F--=YDQiel60zx5Q=hGU=yOkHs}~HpT(~w#yMegwv^OLYNMaXctb=$&&NC~itD1yBK^{yo*0*?L zx92*S&e51w%s;g@C)xernsQ7Xd!BSK21ao9b@$mk%p8@+`RS%10C-IlM*c zn!bZiRq8<>ql?{#3Ld+*9UsXo%8p!G`cJIKk5j%4_{d?UiJruEFSN>B%!NM`GmTj0 zTIqiM{oLNwc1$3guy|DT+On7h+AUODL1O7vBt{Ah_tpfwqO&-90*mXV`9Ptj$uoaY zsA&sWWEhRuB8g-+a9R)e3(pV{J5QjoI_dVoplPw0*!UuIxOdxqRbr1v4km`m<0gHIfhD-puE; z2{J2mJqWAO*7h0ZQsAI#!guaE+bLLM?Av@crV>p&xUD)vR(x!g6gwpY6N6Nz*3e%1 zEX)h)19>lk(WCJaeLzcQsb2ZPFb7ld`y_uxrDr-FZRb}v`zE4IkfeS)bN4Zc3W2zv zsX7ci_@D`@H+^U359Ii4W>fWJ!M%yJLe?MoG~F)XyNR#M&qLNL%VQ7ByWYLMnOM5~ zH=lvOni_~FD=`sDOrmKG`HoSCh#S*_*HO@M=ccTe?(r1wPzW9BlAU-rE`&Kd|EfpKEt_vv0!%fY5b4#Ofn&Lt@ zbiJ4&(X!$+crkmYtIgBdO%A;JnWddcTE6q*&q7nz;fcH&&+uC{n>%y}1O3@IJjL&y z8{hSwrk07U{l!|yW+r6#uK=C3OfI-6?eF8zxMgozz^QG3- z;k{x%5a>l?J1;?9SKl-4d|V6tT^6FJKTSBXBTzBqpZ$HD;C3+9b-wHxdOds~mH&_~ zP2fW!l!^$BLBXPq`tSKDcaw)PTm4a0mFrbD(%6eag7y=8?Ai4Zs7UTPpv ze>MGajfCPBO^lkCkxyHDt18yM*l}j;NPrY)x-NBGTwapI953LEa?nq=)F{Eqj8%94 zqs%I|teshUCvJkQ<98j!P$b}*XT9n^sXI{)zmg=Jsm$9g;QY$szU@xI6wQCSijBSl zCsBL@hX47~mouH0Th+1*<%9sh9S3u9WBIua;YKxL$eCR-gojYBeXNu(K5C~m%i#E3 z_rH#Qw)T8Wz6S1y6aw1`E}j8i5?9K5kIQ9ADr8*>59N4fbMVS@@j<6t_Px%NHA^Al z_eeb>V=EDMkC0Xw7AZa^;aeAxNMYZxQ_l*In4cWUw~b(Zaa@b}10q^GMgCK_qi-MU z$#saA_sl~A8sUmull#95v^Hl`csTuHDLf6l({dN2IwyDL3S4yo2!`M;mhn8RLM=wV zVsqbg5XqnGZg*MADQ{Tca!)4w%ZgN9Z5`0QMNC*#L3_Aa7)R3w@1-E z!)V%fT}+6Z>_36?xM3UZ&rMyb0E|F;N4TVcA9vb@tj_-v6}M>{V% zH4<2&7pVWrQ8Y_aFyFMZlPC1=>e+(Au~fn@!OOk``ivaGp#6@eAiT%s#wZ z_mylo@>{@|i8Rr-ioENY%CWQ4)xe!Ap2WJJLjgI$tcx9+p0N~jcI#GcCT=br3WdNz z29(C{Uugv*{haD)CIjP}n7xiJ@52p_`i1)S_loZ*r-|UD?%VfaVC&+I7b_;BX^$x_ zw8hxvw4rMw#VD``j=i^)-(_c7<*;YHLgU+I?HlsYeVyQ?YH{lPnwyWZhx^BTH-}5- zLxDU!ZFY~HqSd-(4%dD!wfqX)n_a5p9xaAwm`-}92}}E3`gNGVqdGRdx~h@(uEvvL zYD+ie87F2JADnLf#!=(gq%SUR4)ZTQnqBpD-ArD;VQf<}H9h$qKA{3p;z+mpGui7R zsLD4$98*XAiEicKq3l6X*>EG?V4)|PzXU|Gj(Y06b9*Zq8F>9|M8bEGWg*z&YTHN^ zTtW$(c$8yNXlhu<B=i8eN@`9Otsp zvJ4@+EkS|8qv+7&%8P+m`!BL;;KB#e86EX-dF71}b27V+7O@^gOfNR4zX>d(HuRy#cL?|qs;+veHek@ogwgu{0JK0$zf#85w00QUgb_32LLyHDysEr$ z#i=wkW=t|!qc@SrT*1hkG(Y`%YBsT z&6@Jot(!ml6F*r`_a_WK@h5-ew;xUa_HTdj^8fu?dqtSc_M?xC^OQhJZbKkWLWp6o zF~-THvBr+1Kht(Z#5l_-Ypr8WIXLfKib)6#M8^10)PXQ+pfdp{WZrw9Qz0cM=2JA* za?UBkX!P?j^u`1;q~v2pXAB|U-JksUo3FidX`X)Y+^nA;D!jW`e0#I?TyrjbN%2dXE7xc;9GB> zkB}Zokzxj7%F=PLQfkF+1*`Cb;^|%ADuHu`hHK(44e+V3ofT@t+Ctf{r{h*JNwlvz0SkF z)_TXi_cxxos=B(ms=Av^Hc64qQIteF5@mS^B*=~v#fbsgL6WNkh=2gO%0*xxzHkCK zjuXL7WY`)YS&l5(mMk$6B~i3Y$`a?HySl5py5_1geB&P8X{}s*#ry*Y2m4^3{SME1 zevh7lR@0NiD@O;Guo*RC^uq^dKuS1QRh?2KrSIRm6;keFaK1j7&kp7jZ%huu;r>(s zeBza(j~q3h|IVYo@z;Mi-Mjb4fA-E-?wx=A-Noa!ySH2@ZBowYDi~L=d|D#Y{$3ge z2oX|L&NuVfyyVsC0tv`!(k6!pEY_Kn%dQ$wJIg~)M8;|~PB}Mh+bi$+z}dY!UAt7u zvom`aSj@iq>&gvXtF(fg z_fAee{L)LBtMkW?yq4#$oE%ToU->J4VXW|Te{}ou%QvSrcB|Fv-+uGm)2`cYq0P6ZAw`OEDu5_bLQKXe zEQJA0Rh1BS9~f;tAZQ`&CY$pInE?rf2!NF)5FnO%R2>@q@M6Wrw*3~62&v?<%Oauo zUa7Y2kasmtU`V^s`1#q%k9_9 zUw!l5owu%EZT?_=^!Z==`Mt?zbkQzy9Sv;TTIP^GipovkL}PT%IlekvImh4ssTNlG4%9@x^kXP^B11Ybb@Z z$uYY9`LJARrN~qz4rPaBX&1s!H}(5peDN>6a&z(SqaS~5I{V-!wwFKqhhI9qak%{K zk9;Pa-MjzxoBz+R{L5p#y>xZ&7x<;$`3L_{Z@!C2`_pA_P**jPN!~f!&U%vHopa0H-uYIHN)>8OZJ^I$~{(BQnnRz~)6#_(+Li7p}!RmBD zL?5`Z|B?56ghd@(Iy^Zze(}nlI(jY?SK^?AA3uHc^yx(p_0v0V6_#KB>bJ_%H*+b9 z2)OJ`>gCXr_09P3#tX01CpUr_Ke-s5e&cs8AC!L6Hq-qO(ld(?xv-E`fE4>+t>y2j zFeN1rvD&1Ztu@TB`v7aA-NFWB2dare2_aZ#P=H7QBLFf87k19D!0u^l!BUE`hK$*) zH^QauwnGeDm{1Vm#(UrQW6xdx$o?>%0v*n(=dZn`Uitl>|Mgehq8q~NkJpb@i`6zY zBTvSD`Q67Rbu3~Kj!*WDX%yMU!ud8#jJ)=-mpZez;|>e6(V7dh6l09iYRLSZx7+UC z>yoq43TZl#-DMP_Sc54;$$$#v*;zk2Cn-WHfCxr|0Hn05;6PGPvW!L;BE$gvtZN&s zML>=L&G^GV`d5Ga)1O%0e=^xS4tDSB=kd3G@qbcJ-`xFpREl7~`M`m5 zbu&6SI{xsB$A9gk(_j8G^S6HHr`xx_aqHW6zW67%9-Kbi4k5&+!bh;QFZM>;xe&QyLYf1P~JlpjN0IhnB4aVNNmU zY_wKL1wl&s-nbWuFpwrqk_!N+oQ>A?bh^G+_N73{kP89Yx*@AMgwXc_RQldbr_eNI zn`W0@d}Uf+s@;_V!Dk3Z~A0Et?=W7tjT#Cq$`)<2z+wO&HH$VK+i?zsfcJ1Wq<@djQ zW4Ub}J$ewj^YQ%h_{#OW?>>0@Tc49*c=;Oq&;R0!=j$bJ*1!zkqtL);P#P4%w%fJs zfwiPHwjHMo)&YX#EW4KT6hRRhBPoMcNCYvG(o%{5g15qe%(SaWEy*434XX~AF@|R( zrc!QHhb~Brpy&N5lH|z0#ufIrPfcJN^`nmLUid z^O2mo0lET9z+5q8iUQAvs1v-VrdTc zy|VM;>*r?=wJbI;{NgvxzW7Ujf20OsjyYd{?n*P=E6e}{iZ+|Jlro#n`!E0j5n5}! zgzx)vKm5+^M-Sh*-3{HSu24h-hcHx4Jq)36GNf3*JC{o-B_nBtpae?ckdv>f6oWFF z8HAY-0mT?oSd`%V_u%c`tu}2;$rz0QrLZtJzTR|OrL-o+IT2DALYvcOwMK>Ac3Zj8 zfBXX{?reh%#ZsajlFx{_kAe&1IY_V{9Z z{_w2;zx{7Mr-p|qBtE&GUrf4SSe+^jVXl~ zcQB%LHm3sLGtm_gGaIc_NygX^LQVk@v?4&EQ_4-_5tT5v zZ3`t6X;LcWwCy^BNC=C~ir^XQ1t2e+9R1z@=BI|^_uqb8?%!L)^^%8+zwxoTdg%jx zT;2c5chAlr{Lxzv@2<<||Ls?7_aNsyt?m5yghUI=OD{kF@c!od<>F3mWCpF3FcdDv zn4Lt42!izOJInT+TeK^g(qY83Cqogn?MaBphG)8GH!i4eV0nsW1KUTi<*em!UdabZ4uL_gYE#`1k+N zum0J)UwixQv&Cvi;G5B^4G$hZ7*ZB~hEJm+XWb5I)1h%8Q>n~dXFthtl7f%hLJ5V97KNGr5E;R+#V z$OW`QO-R_xn(@5hrr~}7qW}Q8^;7mZqxqNZs|N?MtV zvvU!)-YRQZAV*F>_T>-Im8-IUR7TVmh-Lr)AOJ~3K~$5sPt*OOtWd4$>2kEcIehL` zD_^^F|Jw`xxj((=Z~XzK0Yu0eB7&01nlLaF5D*Sgd55G(A%Gw=DguCKntGA?x$7|m zh!I4fszoU^s-+JoOj?7rba(>ohH5V%0vFO6iC|}Amx9JfVPFQM+0_b#Q$hhQ8CXb> z8r7tfc3yeMq1Vn!VP!OF16)uWK&-~29Fv{YcOE=_>!N=rP0qF#8);Xl&Pu%f=&ieF z51*{h*Ujh=PX6iN|EIEfol7C3>$+)NQ`PlqyA3fO92{)BUMWRNYg>n-8|l&uUA6!A zMV9AoK3FBbboCpLw%hUOb}@I>;cJh}mu_D?`J;ccS>K%<9lZR3SGrD!lrcsjDc^*l z-)&rWE%z)e0ww1@)4e+v>$8VDsl^(ztGt$yLkvwb&N&;cjPb%;I2-E)1h_cwaw&u= zmvVgRFlLclxG*48-U^@;Dau=RqqG z7GYHKZWr(M+BIXC%m*F%X9$I~x;_bi`%*Ej>hNOW{?$Uxfq zTrz0gFS~K$nG^}Ekxz96<9VJRKMD5E>3X&9HtW@sm>;amGU|Ja^>T9XtH1MQckxEa zsquDiZ(P@tYCI{dNIR>ILadyvD`%WzBqAk@B1nV+l6S>z09q*`)LL`NCs+2mF72wq zcWQvz@nR{0>}o?vn5{J;f(5n0I3yPK-XRJR3IjgVRb_{RIb{Hmb3!CRP+A$KhQ9OG zf&iDK6#3fclH1sS^rW@&{jdXWg7U;e(54|KQd={p5AT zVzr)3s=A)e|r07|%GacBH8u@w)S>~LaU_|$QiYgRDfC44IoI2P*`bIQpWE!)AD%!(I5Kst4Dh(tERcBFI^jRM^g6o z8|c%;#iIlv3IFQv{K>`LKPf4foDjiOwe$Yu_~g;UhtB)iWMZxDyG|<|VzAD&+fCPX zZP!-5de6r`Qcd;`%xGTwrmiNVL-LjjY}-K**0q0f`gqxH?hW|+|LPZ1S^*2=uGQX9 zHI~)60E^Oqh@~iJL75T;AVgA-GFPEX+0?XNI`Q**7ITb`iDXb@xcC!+OgV{bJ zG~=<=CdZUR)W#^SQiyHWYVZ24gOqRFytzrSm`Pvs`L_4u6zFQyWR_e48oTb=)oR&3 zzNh0uDTSH_fh8B_Le@&oC1vHUAVJsdp2OwqHy%A%b1AfX3f4$203u3ZOy{%Z#UhbGJ@?jIW1TZO33D0x z4Iq+Ml9tw}VF=@Kt+hqO*=T&eT+T;hQ&mYYbL=)-i{QqM^W%_V)qzvExVSjF`oiN! zr?rKgVotdatRoh}v#K;B7VaF&E27v)Uc^jJAT zKrTp{V*sL^3?p?d>kSg_*6FASl`36Ngo215ECPy90E#GY0kGr*xuCIVG;cSk&17%h z_k)zo%0T9_Z4tpuo3QQFY$72+2suV1WM*wF2)aof)@{|)%#Z{plfAavIz+2=($;9r zDUxxeZxy7r-72ldbv+-={b-cB?c>E_GM%osTOv$d|Kjz_c6z*6T(EZc?>qouGJYon zaN(+UC1j&AmQwFeyt8ME3#WC8MFSrk9*z$W7EjNB3p0D~hY-kU1ky%%XWH$MN}f%d z<*FM`M!6J)m{Y1pb=N16JoLkK)O152Bx6ue4gFAgDmLf%rHQxCU z2WE*eJ5Ao({Hz!WN-jt!1v2Md2*_v?V?=>n);9FrF!X)9RZ4RVWNP;NWNQ&FyyFKr z41@Q^7B1l|g@7P#R6C`ll=1v%+qT_yljATNPc`SrFsX3w+H>a{K&|gTT4~axZ841k z8#%hvS(KdmP1n_Bp$L_xab4|A_hL?@Oes*9t#vskLxh@(2qTulN;?rrF%rx1m7~+M zmGdSSK`w%rVj!g%K$w+MDJDWxL`0A~Z&aK0^_* zT3CoM7b&}`TrNZkmEL8?v~bE)C)_7EES2D39)Qq(;rSneS{pRbM zBN63NcDJrbdox5}7Ssv^AZJhnN+XdB18BV?V<5)exjV2x?J=a?wjFop)PSHA0ZPfJ z6f2E6gA^z-x_qg9{73{qD<<&-sXwNcjEs)}7Noa5+ZcJtLs<7Vu9 zK_5eCMtkJOv2@$8?E7%>&g*pkj)+uF4>8yCJpw@n2FNjLqsPrCr8FLmka^p8#8Lpd zt`jJP`qFckNvl5URgn33Mnq4SJvj%=tnO~!G(DLIKiHEvQnl&({C#Q;jUgrKb1JKl>i zFP~hf$%y-)tj^tlM$>4LQ^39lXCWmZQqJbgJ6qD#b&6$v<+xq105M!FAv2N6IqY2M z>hKVtg!6@naN*|osI*<~TIZXOee7eezkRpcTzKn;6mm$@$z-$Hj3*N?X1zG~Rpp#> z-lw5kUMxX)GMi7Q^X+O~d%w58S7PFv%Mgo5Jsz#LoAqWhYHDPd&1P9)DSUBp-t`@z zl#+|EH~twJo6@%JV%w9q%*;}N83j;l&Itij({L%05+F*>V3by-(|2 zCKqE1hE!7E-icUW~`n?RLX4jQ97vcXe&vdGoIIt`tdqC&Ee_syq*aXahMZ=coJg zv%B|zfRtepZ+%J6N^uJ_$}W*6NJvT(shAU#vODkRBF&@;F^e&IxAYl?9fwIs0%8>9 z!XQGf2J1?%o&UH{eXZ-P)#PG@0?aC1|r2pNGawlsN*nbql_`b5S+E7bsPdI zB{?Fg5R-GZWEN)Uoz{B2*;s42@GuO+wsTr%fFk+wIY%OLy-*m^Pll z#uP|_vaZC8$Sg<%{kBtD0mx|Fa43->#*kuYtPzIs#CHJ>rrM4tuAZK)+U3(z?+pmH zo3(Z>r>K-hfl}C3zVEgupbS+;KX-Ix-EI*mMlj*E1Ck2~Z+ zIitl`6GAXbr;@p3Z44szL)fL>Ku|04#sZaGcKm@zDafRqL8KfaGXoZFO&oe8RA>wt zRG2dtW@AhYfrv_qh_p*ajBaZEn0!(CtPIjdjAjYlGkA!#7cGedlhvc&v>krLrW2 z8UPhleg|5EHkh+&YULcK2!&Au5UZp8yx9UXDuqfR0OW*)&A8cBq!6MoD__Yllo&`W zQUuH-0*cbMJGpkb-E_9Dfk6}Q5M#;tS-D**z(U5BlYyHmaY5Aa0+|0&U`0D%Kzj*S5V+ehZ06B&fLM~}rj z_6i9>Mo0TRMC%L>QA(m*K!gxLDH4&CBnCnvMS0tyNZ4+LId?r4CP443Fr(HG6B#l} zaW3Au-QX_@U%LAI{NV8IckYFDDF99Ft8jYUbx!3F+kRofH zCY6WaeYJyBQizrJAq)i2^@G)V+qHZ1@z95Z{aMpABWJelx^PB7F3DR@AhX$?BE4C! zop&g#lp2lel8aH~Dr=oCiTz}fyWUscj~Wh9Sp&I@M>VHBn@zMfxnxd75s+5M+*D3j zpcF_MrI69ctgSIt8M9+B5lYe8Xm3hL$OTxGu(bwCQ2#a3LQnp%iDcto+q<{K& zG#QnUtk=6c@2=|zKwHfr0<-l_Ar$5^gmLYRh7z;YsyjbbA|pV``T6TN7muFSCr88i zc@6`lbouCDd9kqCIBPgYO-h8VHl>u8NXCJ-u&{s}aCKYL-x~hdm5jkf|Ke(#mp@)*{>7k=U zT8*45A^W2}q49mxh6qYP{FRa48C~wp2nw#Clxkn0ebGB8H%p@PPMt(eMLP!dchtODqWVF_hixif^(^1oJd&o&4NzO{?VF)Ok zL$pRuM|HbtrIa`Xh?x+fq!bdzq?LkPv{t$AggK{FSH2V(`slR@!=MNeIHydCNU1Um zT#`aHbbakyj){OI=8`iB4E{AQGV14jn}8kmIdaM2?=h8ZtQCWP)NDtA;vz07>1MM!=uZWQcP6J8}Hn8 z&3L=KsOws3Jv}}iy3NIt$BdLh@Yb5z8}C+&RSG=|5F%QW`yPRq00FI5%q4F7=5Ss( z#ce>P2!V4J7BFT!8iyED*AtO;j$>rbm9Gm+2m>Nb4(6MSg``-|=9PEHd(-c{`8KC4 z2+F7&lW~q&tTkZ>%9t_?s5K~MtZ|ycwns(6=&hhPZd-c)i|eq>?fVG<6L| z@6YFFPtHQ$-?(=9bh$nlH?QdaV>d4?m;L{HZ?nv$jS*4hFj!+mKshtto2||lld94L z&O4T~k#hmmv(KOy)G7PA(R!s&ZO$J(?>wCZ=fOH#;~Sx^9>MYd7lxK!}Aj z=WIw5QOU`AOCVsBCgh^MMXjJ?>f4R57)@TQ&88J)SkO0>LEfK^IOmbTfBN2o7hXPk z{CN4VUq5|1Kq(v%t*Hvocx1Z-T2qSo;P4=ZkW*<1=QR!ai(jbny>7+(3lAAEG{E56d}<;GZJNVh}0_WYIQx?Qd}2S&Fa5|jzxs{ezkM%o5i~>J8?6$9QMz%) z*Ito|A!wtps-8Z4YMqa{_-3!`+S+;)4q+`Rh?Eio3cI=qoRNVv0U$7s#ubMS0E|&Y z$~w<6+j^WsFGRkob54EVktRT@>T2k=NSe5az`84w#%W}+o`)gk0wA?_sYF63Tz2~& zVIU$=CU*l8p?0N2h3IOX1BX6vW^@V=ymG*-wd;p2^xaPP%Smcq$I$1J5P$`&F+*q( zRT@H{3o{sF*V~Q|t%3d7c-19L<@#tW!{)ruoo(Nx&Z`QMNYP%yOLyG9`^I=Q5@m@n z#UUp)PT6{#3XDbu2uG7k+o5MgkKek}Z&!%utWvNOyOFgGL$XGv5K3l6G-^DdG714O zm1K5-1H|jI$=z6(DYl`c!C523xk%1TN(s_4r-%@^RCS$G%&AywLkfTdh*F9oj42!I zV~Dg<91t^Sr8NtJa83!hfU1jJCqgjMgCM01YqRLdt*rO5O_|Oe%jsb~F*->WS z8_GiO-L@azdep_cZvzMs0iZTkL~@Quh-PofIU#AVnvfu6ZEYR~7T%r68(+os3YD7e zPqyn82(@u31Q6kzbv1$5leI&;v2{~IKvW=wj8RIZzLQeO8W7kS7}H79Zu{AMv^ZZO zk+C)nVdu@olqzRL#Q1vb?df_;EFaiYpSym7Usk=Fp&$LKU|w%cu=rn6>paH-ECB3`SfcivuaLtR-eX*!uN7UyXE z5WA}O91DYJt$=9T4W!8!y;^Szb5mEl(>7N*DZ(g5>BJ?KWJp;}0O+dPSyQB}mzyGF zoekZ9iZGW;&s~0W@1e2UjOr8vfda{wFP)rSY`S(k@m?EyzPw-rL2Q~4r;LC~t9}^B zSglRluC4dpdTUG=!ol&;X1#9Li>9g>psJe^qxE$^bfi@&#Tp$$Rz&0J927z+hVx(e z;I+^GrJo`K@ivAup3hf{rEn&ss&XQLni6M1<&dnl zZAgTw3tQ*??jP&yHBXQrGoR z7&TSRWazhAYXIe(AHtxtCQ><-^=e^_u9{Kk`bmRli=pzq0E2+FmUHaePPEOL*XyOV zelrB;{PWMB+#9Y`_J`912jGBs!-Jz?-s3ArI9J-E3 zS54iv?PNTXQV0b|hd4N+rw9A@Uw_LVjGe2wM9maArxT%sOpAG8Ny(VMI=*a1iY zg$n_)Fp4OxbxFryFr&?g7=d=~h^ z8@Ipu^)D%Atp$-oh)v^aU!iu!j&wCbW1rc(g`eTPrC94q;Wr<*%eUU}Mro}@u!x+m zmQ=FRx~d$WJh$I<5eSD^Y+ZARN^4_v9D*{=RleP9lvX7~rBwmZTBno<0D!8I&+QW^n}$Qc2eMoKv^i5|T2MLNZza5^OcjsZWtD4>w4^fOhPbF&MwwD zXJc*UO-bU6A(UYlK$O-rnT+jx`tQt&9dD1o7Hz z+wR4euBB}V>*e46@BeEveh)dNff(T*{QN&(EN%k=GaGA_QZdA)uKQs?*fFRCrNkk4 z=Vx>G^sJ9z@YC6_UJ#MyYP3poT zAYr@uSnbBf{qE`F==fl<=~(~>Qw$}h{rR}xY~QQPOZ&~ZMnV`h)#vZWd*IVBD3*iJ z{@6>k8JjP^)qcHG0l;Wen61{pGM-c*l2e+@W}3)3_woq-`hWIc7987g14Sa}zw@*I zi2Fw(QaJAh^NiL^V2pOo#+dss^y{tBhO9;)rFY|@dfJRLm*r+{6p~WHX*Ap0Zr0Yi z-Mk;C#2}`s2|#4GALB}!z8^>_rF4|crC8_U5Uq1a6v6-k&e)t&r44G@#)w2IX8@?2 zNtu-*1c)(dtwRV(kA(GtJ{e}8%)<)pXpzj{`{iF%?Va6B9qrt607TK+ zI_I|SRw)GxMT$}ykxEXa^e#z^A}J(ayPO#bxg@2vHl~yU0=Xn>UCBi$E%5BhlZY%) z*L6gswFV+mDyGED&N+VednRLS*{ROYXc>hFyYfq;)sVA@>?mlZ)DGr(_RxSxDK4de z5PT2DMcgrTN-1XE1=a{q2(z#NaN&_Lg*nE=z`ORtAq2^6olPNd$;w#avXeijD1Y+@ z-gB|{8ucyJbrM2zSJeOjAOJ~3K~(cAU;LBxyI)}dqjkx-9y!#8Q147}((2hdVt3R) z7(z5!-+J1$@4Q1&v^J;|7jD~aPBE9%ry)VnhbK2yeP6g#AzJU-?WS%^V!e`(kjHH2@8ucS}841rh5nL)z(?tcl~TWFS(Q$ zlTw#nxYlpl-MbBl+pcZKqa0Jpt@9p8qtc`eGZWBk-oy}6&ef>SiM<Q!Q74!;u3Xiv?92!|%T2xBS&CH}}<{3ha1mO)U`PQ|g z8!ui5M8s&{p|f9n?t&I5MQtsbyDy&@ni!s$?S1|E*&u~Xv`(}!CWMeA%DNzgZgSCC z&R0*3&)Gt?)^nj2=a*Kj7?)W+o7&NCpF#r8QA*`wB<6hxQc5CbLvYRtE-2%S*iy$Q zX_91#kD)m$~g|&$k-MkP&Xcm9_t=BY~ zW3BNq;I*RPZJ#^$?+-jN-(x_C(I<(#b6mXZ-EZh_xTZkaXfK>SapKRu@E?#QWod`% z`uE=dTG`rs|5JOve&2mnQ4adVS0?JCpLma`uQ~lMKP>XIHK5W|);h%*SE8!Sa4LWE zWB1fXLG%)h6x!dR%M}y-?c)Btd(S{ zDDC{*;zA`}Tqs4NVnAC}7~_bi>&IcsT?#xlXZkBz!k6ITS$6lo0*h65X(*tB%)q!iKz&xl8ijBzA3 zC=wvzAw;DlItKuQ`_ zoFj0?`^M$wl?oqYOq!&5nG4R*xRs2QlBfD*;5^0{La^2kS!oW36#0Gix z2tXJI6}|xi1Y#@%@2yu-iU0!#`QUIFq=DZaIrEik_e&v}00xK==)Z1D=Di0ZA#@0l zaft-ZST1;T^@g6Sjnw(Md7BN1=Bi8G(n;e>j3BeLH@`5pYAS>ngC`;;1cfk|KWtg? zG!a7N9y_PcQE*(d;9b@3I%8JV)iOfQP?okTYx%;`a)_ZYCQH(Ow;K`4Jm;J#J!mPB zJ_aVZcg|EsFkY8Q8Dm+Mg7YFT8^f*A7FuUa@w8T}%2Gs>jHiO-dF7p#oXc9xcKfwR z7(zqUT@1?s5Sh+uuBrgA)oK~*jdKA(3gwJJfXU65H^){=p>0*kT0LzIsm5q*FNO$2 zg8>bRI3r=LGu9~~kR>5jMNx(jgjQoyahVm zDMl_7W5O9*76s>=7%Q#uJ}9k3h|9}u@0=16A@=fOQ>Izbp3(@UfXRi*FGS3j+9S<+ zQI-_qMUq}~%SD`U@1b*hm+ADuGg=6q=unkcjU@p5`6X*&5RB)x^vEtA7FVwx-gmBd zq6dRHYp{=WrJdR^J{iU@PO9ybBU-CgBQ5*=Wj6GWKYl_;J|*e(*RHEce)QD&z4Lh5 zL|ay^(N?e1D~o=uRx@RV922Eu2;SK&&Ds~13sNJTHPXh&_{gl&(+iy>(WS8=MnFI$ zYiw4}23b1qog~H>H$^FQGWghuAu>+JmO@H^L7x^3+Cn(7R;$$<8$NyX1QLtxmCkd3 z$Qk3cdZ*iW)&M}7B;I>MEV{ivc+ZV1##ZuHBZ$oPJH2yffAY|?51d`@b(T4zBKXLw zH(r0sopIx(mb9NeeeBuYpS$-#-5OqKFMi-%cWqg}_TPuBPGe17nkPCUR7GJ+BNFX>BreeUBJYjJ z36-WrQ7}SB*l5-AvXTN?iJV+_g=~#|x3@7YyN#)ZbFv(FU=?|a`zKX~2F4R3m#`_9jPkU$L9%GRYq)o!}&tv`Ndk1gAT1cYlE zEtYK%X_K$tHQvVF(GyxJ$(grKY5_J3@i4UUvaeNZzV&;bppqUb#Hj{+P&??<4+)hR?1l~giu;_7M6*C5JPY$7kjfs98PP5 z3{jow=T37Bo|GsUw`+jd~^Gnx%^At__ydvBC=&U%GsOl zx{-}-{kO;W9eeRfhz^kp$&D#FmoWm1{(X0B<&(Sg=y=&#=JjT8Vd2SVU;OEFFQEYM zosRgn^?c)wt7AGq(sC>{(K&D2PzYQ5|9^>#dIoFDKHcu zkPrbPkkZO~Z%oA)2gIs0OfbP^2%e;7jFn}{7%?I)1?Pm$LqzXA7b3&}F%m_hR{+ic zh!HqvF-Au8whfK(EgOmJ2!U}mx6pg+@W}&bra5EISLImOrkPF7FwE!pt2ShF<0QLeM zJa8`N%N}AC7fna-lC zB+BuDNsTu3b~qId}T3Ass2)am&qbe*4?5*tP4Kr*<0x$yiP6 zOp1^F>W6pS^!k3Uy3p$e?+4Ya!Mh|;&PMC#gCF_r&DY+ZZhLjy_S)ICH$O8g7f$RM z%d+45_&pnM{YAg!)mL19rL0OTIA@Fxs`p+2 zTE!S+WSq4ZmJktXz>W)uOiE>{iWmtljj06Z-g^X8Qm`1_{@!0pR`2@y$>ziRy^VO}eK&DA%J zPVE?5vwindk1{2_a}ndN^(%MX^iGt+`wpI8?oBfaX_C~llrvI-6T^`#x#{*_{L{}q z^Np|F`{*Mt{rm^_9eU_Hl6s~ne&z04r>=VIAN<`T4}9wzue$oGi!a@|=Y>6mtp#rp{`JWXh`EsO{f>Tu<#(ldJYm`|tnfi`C3Sh;dLsBZMGM@xQRS1Jr;@ z(?OJH(EI@agy_5tA!wnP5X8_sPn-=B6yCcKdBi=#Ls@T{j#e! zZ@T1X4?GZ|5`y1-`)%p?Dy7vUdk$gjv*5k+H(k7D$1QhbHgw;!XM1O!tx8*(yq;)p ztaFY5PGredH~+$?|N7o${y6ygv23B!y`Tlpz)&>0?1p{I!<*Nx z-m>Z9hYp>!of*#gAXF-a7!({uq*IH%i!Z*M3t1BX!8DwI?E8cr&iLTm!N721jI~zl zWB@ISF)+qs3{q(rG{g@05kxWgfe6ePaVew}Ap%D5J_d*ofsi30;}iyLjS%1Xs*BaO z*F6gBpFO8$&FHQjJ6Dgbo2kOm!g)@t9^rj=Y+l^{=I@mGc_z&o$m5jNd) zf4S!F{!uRb<2UqE^KVPeDijljU796nvqBN z|9OxBB0zAS3vuW|cWiQv&RTik_nk5qo_h@40y6T>4W1t%L>$EU82S)7XN;J0o){UA zhY!z%#j`{(XqdQlM7-yhuB`8T_o_>-%f;I5Q;pWDb+faJ{8PX2UfWrG>WMu+KQuR8 zfsavY^`5(~nQZ98`%XP}e9roS5EW;s&>#K9TU)_DHv;DXm`X=UB2 zwJSgV#+xRZ^=znFDIIwBxBv8&Q90dU{-f`F_vF;%?78!2UwZkzJ*RY|X1(K_+sf8! zi7^HsrirW!MgSp21niyOxBK99{kn_S57qaz{g;3Aow0RW&!5_d@QQd4VoZ|68b?G$ zo=;3o_B%cBUI#TjQmZio!v`*FQNB~H_vJkkJ(BTJpayjzTt+~zGM9}`wq@uU_@FefLIl!P?9szHQ@@xNmMhKmOAf>s;s41p7*jWv&JCN_=*)mB#R|~^glim`qKv< z&ff8!kKT6WMXNVob^e7%`rYCUx82;~Q~&D^zF?N_PZIsLe|UV`|N86gyKa7J|4Xfj zm7(5fm+sT5QC6_ z+My)#w!D1X)*cRL^N$o{rQ)@^IQ;Z~Ui9YoZQFIzk-a~WOxh6pUey_0yM6nEKR=|E zYzcbRwU-@PVyhZ)!^F_>le}5ii6ucyjtpDt7(!N0(76V`V99GON?xmF$f8-DrE=Ad z;!N2ZPPh=JDDs(oH(!6{p@TnTq2hvb#_}Q$5VTf=z!>A4dFTAni5DOF!i$ftEX%Ie zORCxGw%bxkfau%+15CsQf?t$c2j{%^oDGC!0K~l0OA-}gAkOn{S8GiOh{U-pt0GO) z5TdaLffz?bw9XF-c47!I#Is%BIr2jlmKJ8|OJDf>NAG!m+FC(L8oaso>dmLa(D|o7 zo5D$8_~bJ`-ZI%(vv#}V!y%uoXUf@1jW=xMK2_cMy?? zIcEn3-GP_NIO8K6FS7&p{ZkUBk=TEnYkcxoKYHy|*FL)Y*_8TMU3)o=ZvNW6CwfnO zp?UZ1SKn~U+O0R7ed2fw!C4oa_xN9ZLPN;xQvS4xE#q*T@#M1uda??Mbd1|MEoLXXtzow5W#W1JA&Mk|$s5T%sHT0$J8 zszQjt`^d$T<@bN)c6_4h>f zky~zg&5mndI(UfXbIx1OWH4bvGpmhnGACykag5>8vAShL_13UdOW~DjI7g9Ui~~Gh zh@R>6$7kGQ-~6^TM_zs`+qm}P_ucmDt9IS|*kj*u{obyd*FRou{Mq+^#>?|J@3{2( z>#lul&CcZ`4+FwrbIe}pWC3Fw_)zxRU;n|k8{=DIbF_E(r0}Psl8h1OY+zrJ4@eQBb^iI&i*fd(vjq_`V&0nV>n2aB9ksS8y*qx+T)VQixju4i%O&(<`RZd^ z-+tr!KYr(B8!}Gb`(*Xn$&EKPH{ZEy*EO~(TlE?t4v!As_?qihU3&ZERd1M`n?HT- z93!yS#ppQ~F+|Dv_RDS<+ji@P(VPC{+4>*;*#7swefrdVUby(-U;TAHb@OLlYMomB zs%zi(>(^esWpSa6h*GfO;RZkegkD~il_8=e(ON1Z5*(lZ-ar23r@!^5UwriM|LLF0 z(@&p0@_h7uU|tC!AOIjXM_UnMlIVV?>w`}cU6v*1d|+*e0M2?uB4Pu3o-vj&vep`7 z0TBS5cU5Ty&IE`NiHtRXNW_*q&~Eo5FeJgaVp26)!y$z6RU^)`AAR|=C-3{KpZ&}4 zeC~gLdVbk%yYBU6QE1L@z5N~Ss{Z8nKJSix%N+gA!(aWoGMSjX=$a%^(Ys(hup~0Q z?b7Y3kZF<$r7zvQr7=F`xQ@VL2qE}dn$*&SA|z6IXR}ndrdB`x%%NiL;UPRUQd<;M zjkFrOu6fP5^NX`jeO`3;{O8v{S2(eG>rO=AQVPL`hliyU3@O!m#l(bUJj=2{LONn( z;cPyApX)sBT@}0ogb+i~@5KNyhG4xZtKglKx>l=8tr+L^R(*iP8{E4wzS7Vvm12y= z5Rx>LN&~>4$u-32tV1Hk7(^(m5)ioHK7<%S2~m{=AxOcisuVgsa(G(%1#h~V_m4dC zjgS|jF*?+$wVJifSKfAErYEYWg_MLup?m6uM>k%yUWoL<^lWsrT!glXS6qITWDH`c ziu~fu+i7xwX~v`+d>;^E@XnZ0XPO8YOPq5;*2+$2v^ktI!D7?`iD=K!B^POZ>c)d< zP_bxnxnB*`5k>?dFk(Uo0F+$R(u@lxm5edylqopw?eXPaCrQ#;EgJ}TgYjAt8?=fB z=bbSC(OC-sucRgroO8yMO6xcN zLuanP`8L7pQpgp}Y+~E1zxbce3g(;j7C{7vN@|(t7@{-A8C!u+sl0w_YNNzWBCN69 zVG2sgw9!PUdFKJZ_6tImC^oWwm5-@loFRGZ(lpUR#^7U&oHNduN;Km<#)`3XwOTKP z0d$TH@Pbj0HbHKL#PCsZ4WZ#5>P9=bSrd28$1Cj1UY6 zoOei+q%|%$F^a^Aaf;xbQA#5c&L0icf)`qF))d57T{$yXinzdq7+9qiPdueN7glcA zj4={`b>0}?@0HiC8vzfIm0|}Ez0f(dn-g)-BE(C!OwF6DI`sm;GBRZ3 zXU-px!LQqTMeqR$ov|@Z0O_Jt8zP7hBZs(Y<8Z;7dG3_bK-^h7z&wNyopsh)4;Y-! z%SwbffGD6ieeCIK=J|1*GSM2Al&#)*X36W~xT5yKeNTzGmoD14-a5}X_udbN-J)OG zvXDwfMm~gKyGv)EEe<{C>>=wdA`I%5Lx`L+?>#X#Fp)_qiBXJEDtUfB;F%K;2COPD zRqmYEjVx07;;HF_$IhHQy63|5tS>{oKFWXeXP65?IT60PI;(myM5lJDrVAWE4sF`XZdwEVV zdT;7!Qk8~5sXIUK@BO*voDuilA%ai}iM)@*h!EQgi$VzS)_aG=3T`cU`eXQRVl1n8G z!z@kH=EV7z_X|eW*{XM;yLe&U+O@SknT;_?li+<;uM;C%RgHQp_+X6@LK)+-EKym~ zpUIU{!3SrnfrgBL#3)UZs;UO2M1aT!wVD9^UJnt7xc5H#h=_m?0Wd%a5s;j9jPn>{ zk|lXRk1GOPMAjZ(XgS>-BW?x~=C=?rSEpw^Yt`x;wXRZt7MAW~A;X zrq=)QU;pS+AHK_0K?)8CI!PF3?M^36lDwZ6WiC0pac#1GPWtHec=M&D{6d6!qxQt3 zKfn2^>wf!Vzf@h=lWn~02Tz=+7LH0Kv`}0Nuns9&BCSQ4J0Cq8%)yLt49+>mImFQG zb&@n?L}gVbN;~IvV*a);rF~l*X48MpLgf@44p#aqc-Lc)IqI-P3;h>7R4P7?O2V2~vrYa@dqT zRB`KU;fv>`X7J%m&5h3PUq~d?JE{TqddNkx~qfjG#a&byHn*k z1XYuc>%N5m03ZNKL_t(SbB=;}XIxRf=Uq4U7DlpGE5z`_J*QrJ`gs;j+H69cOLS6( zTncH5w#$tmAsLfO8E=P2M!MZDVl>9Y5MzwCG|t*or=0O#p4YRQHx)%7L?4{BMhd}* z234UEUV$|-#;SfHl$1gek`KOCt95(5Bu$o=mz0#jhqRG;?-A?(9JKMGOAqaPnK)vE z=)IIl@HP^8XV%MPb0VxMQUQ10w5hF{Ck`GB!H%V>3bho17CZ!uM2r{*7+p2mTyy!- zfycE{NptMQwi~n6_N`lf_}EI{IlivJ+0>2)PPT6y@l&-rG8tWo$OalFA_gCnlz@DF z-9Or>N15>Q6hk`v^6rZ+y@s{Mq1gYurw;wfmRsMlbJYShFTZ5sT;H8Ia3UdwMArKx z(cby0Fc3nbG-DV6bdvet0i)#Hdk=t&Aw$;9`%(zbx%Dp5vdAmM$ha72(YCA*qbmxY zB}z!^eT>l>tF<0nCxiqcB1BFsA_gCbk+%-KV?qbxeF)va{EO?rx!5UV$OmxZ{~K zIgVM5UCqt}H99wYLr#*~%cm zAX0T=E}uDeln{|vnhHcLArPZeZ8tXC-}l_XUT@!zAHV)B zTh@&Z4YzrBq&1?4H!gGS8u>^gs|sU`8C|z!<;qotcz1arN%*Ph^Og6lMx7y9ABYBP zZ?(8EUo9L}oFG^wd1XuEQ(|d;X3x5Yl6WM^+m;Kd)gV_FVknAobZ8hLLJaFxuk97N zbJiN8l!!hmEtFK=hXL3+66z%J&ZVg;D}#cAF+?b}Hl|WiARZR;16Zp_bOZ>dWXO;p1dvKO=c}rWh|W1; zXpLo@5f9D;oeJm47KVgiQW0lLC5+R$O;aCz$4yJ8j!bU4INNyLPj=7GpLmJTG}C13 zjumG*jB#PDOSFzLw)-Y<)iataIW)0iu}q$R=toyw@&1)-Hk~-V?}i=Qmf2{v{4#Sl zNFIew(77Z+QdZ40y-=C@P>ThC;J4p!^`_U}Xo4qV<@1M+f9W$rtt=}SsG94JZ0{Y@?V&bm+qhzPMYGSOXJ>X+8LkSIlrj5WHhx}Clap`m#2)&rE@MA$xfl05C!bQ4k+AekW2DrcXq+^oSGym+}%Z5|DF7OI^A^3Q@?? zSe0l_Xv$t%AIGWjeC1nHB*1v#r%&;CDs2q~Q&k==O!vCocBndOqn_4vv?UX=Fx&&y z>J4IY?NIIhUK{L%Yj^B?;L-Cd)~r8Kq%J>$zFOBBetNmLy58J1mNpbcA0Ak!&iCzT zBdgW*^DzE{!yyrDerBn2R`E_hNzpr-ai~J54GmZQz81U`oKzyX>6Zl;ah?Vu;xc~qNHUw)xC(0NH5r}w*Ap$bai@ZV# zLP+NWFyNd;L}K)co0Xvt4!tABvY{3-DyvEeNg)u@z^mZ{5X6W~W@(j|oCHu5D1viB z>)<2jLUI;dlrFw^=jCVj&uZ|OZJSscyZnJiXSrJp2*CNUV!)LG6#*5o^Bo)W9DxzB z0G2aW&(ae|p1A!r*RR=r(hCrMlAVZ3rhY-B?$OsX9X_G7s(RVE_on63SLUe%WoaIt5#u;Z%onE@< z@};-kedY0!GY#9Nv9-n|GYe;Vur`95JAT4ld;<{=)(a_PQGDZv_uqNvH5ad0ed^_d zg|}Dl+S%{ZgZoe1v8@R)W|?-K-T*4e841Q+1T6uV(dnPh`ycwy zn-4$!@Y<_xX$((3^x_Hcy)`z5pp&GY)e|MNp@v|r*Xi1-^Z=YO&IDi_YPRyC5K?&O z00}T!XX{z5+wB38s|;gocw%LLY5tW)st_Us&IBM>YdNv9C=#7{AIhp?j47q8^QJ5n zF)1Wt3=lYz-a8-tAclvCoOlIRFakm!BQTUIK?E*j(d|JDT;Yd)@kS`xB(++(-B>!Z z=OI%$p0!3MC(F(WooWw}A^^ZdoklYuI1_1_Xgz=Y*pI&d{oneHk6yig#ZUHiw`|%J zqWa;tKezMazcQ?qhuAk&ow0SU7lk-g`NI3)W7@2%TDIw}pC}P(K|K1k|KPnv@6FVz zvHS_}k?I`4Syz~azTuK1dO`#rZC(JxP*o~Pq3{T@-7eCs*6Z|?6h1^K3l}2;#yLU^ zB-M1UTRF#KM509a-1RagmwP2F*o3n|6?S1OMqDe-81J5H6KCG^r4T;&A}?Fb-h8_w z1TU=#J|tQvjJ3PHddC-e0Wq4Y&zTaUVh9Mxya7a6Yo*t`1Fm#H=p3~l|NO%F)44Yz z^`wASBI(rebN&88)*PwIlIQaX*qNIev6rzZ^JldhO(hPSbf-|K(r%3M?Lv*7`UT z{KCS_{1^V{eQspx1OL}I*tz|G_{SgKdBe8vJeVCg^juc2^?H3Fc>dx63?2bSn$4wN zE(Eha24{)0s^3#uJ0NGBkD(}wG)Ze|(yvTujkPBF&}_9_kpr>uRjX&uowvr6oo;Qk zMFGDPy`#a}t1=LLEvuETw7r}$5>g@Ytd=obF-}XEe&TPA&OCGf z+Ns)~|H(afz3J-5AOG&2XC49P+v_;j~>zBN3CNN;@i^$sG{^znU1G7Ui{ zm+f3Ty;SrobL*XVJoxYbcF~3ve{}z0b8a6Wn%H^O*r)$yp{UP%@C#o~^5r~jeCgg3 zbD#gs`jG1P?Kkdy^575tr(?G2_X&v$Ue;3YAjyNu#m2u#mP|5x`lSsHC%Wp*1vK7F{0$XUMn;kvUT#Mj%2ioby%Qms;yA z894lm^UY?RA(MhH%rB%_q9rdX(^+WOYf@y5sx(}%GOr|OJ~youBW0eeTCKm_@!n!Y z!T64G?FmB&Pq~qTCO4v;aK**i{PmL$db2RTWxVQ{O)JM=K0J#vd$UB@y#I%{z1Ml) zXw@Hl=7kX~Fn(aoc;l-N{`AA|yzS0c?fA2=|Lu+Mzxs?-dw=|0_S$#1w0z;v1$p+d zyC>_nzG~`ZF2DTXu?sFLB>&5I>E`g6ZnpI7b0#-QlKjdqZbvSC@J~MQ;J zm39N)xKeF3JXyKMY~hTlf;uv780416qTM&jpIP*( z+pnxwO1J>d1wKFy$G|yb%y7;Flp!Ev%o-;o(+aF{fFOhjJ_HDwso2U#)t&qdEQ?+ zF?w!xsW3f&P)}sO(2;_i3;j-4s3b-oB34CLN!97~lvcH*wy->(Cb}r9dcD@~6;g1S zrbR!m)$85G<>rpN&swaP-9!u4?c(`kXXfX&?zmAXJ-&K!{@lV`-fIqxDNYw%x+5gD z+1bT&%ZsVt>o>0M|Lcqm@rpa%@cjoqdFyL#tAdx*m0C=$-*EcOY^{NR^znC(uDlGY z_E*37e}1xmZq@pAAu@_ojrM`^yVFJd_(kJG#ckm zokkYQvQ$|;#;BAG-h%g4X@pY7JMTi8W-<7Ij30d{^KMeB5sAuLsdca0k%ZnkiV<}J z)?E-hh5(Ej&1QRHvC(L@7Z+-o>bMvQopX#)1RMmry>k3O}3u7VIlM3v}9 zA_OKFDh|cu=y=gys;yX=PE!P^r!r0D`ICpPzv;%w>NzpA`LQ2AuR@6k(MHK>#r8|4 zFMC%=lEoma?F;LU-X~nq>n(lmo6qX@cd9BU!c2*(f=y#e4qwu32R8EqPUi9Ne0KXM z|7gR`Tc1C103b*KQgiQ^mKvf4AI*ZP#G{G1Xm3YAC4or8S{qs62pr`Nqrg-z)-txM)zxUMa@kW-G#*EbT)wjQX z|Fb`>N)x=FT)81eID2NkF+LnkUUb?W-$`0yKmNh}@4e>(fBa{kWK$QPnSQ8QZ+aUS zy%jtu%j(1L{#e@B9%9m-dw6(wOxJ;=9B=Yt^~{yMbf|%ztjT)-z0P98*ITWo=B^1L zPMHNn zTMZvWs&()J5NkD+G-O%DBPjm-xBe=1hfRb({?!j}xpcz^Kk{o|`NChG>o}1x<9(wx z6vu}W$+Jc(hNqkhWhB*1nkoTGAlPXu7w6AxnY`?`KJ>mNvE_Kr$9&!y+l5LBUK?q= z>wo_~uWy|qF>z1-6TkcSBmINDeh=$Lj;^XTn|v4&;wv{@a`xECWNc(bE&b?kT-nRE zf9$g_^q=|q``>u|>+Zb$zrFpffAK$`Ni<_z5mAiMmaaK8=A1=fdEQHF5`u^{u*&Ed zjpvxAX?>(MH@oP4#kfLrAy!otBoBlr6guOA_bH2t*;GqY^+fPVA}ZTQ7r2&XZ$6PC z*qk$At*xu1-R%iUF*jLF*`mT22~6qzADz?(KKHPci+}jOJ2$Q#{>a_0`qzJcoH=6x zm8Ygx)U=P5N{7VPjKo}K(Fa!c1Qbk(rr>8{a^%>7?Q3p+oMqRpVLv@v)n}jK^x9P_ zfHU>t{HH#2TNt|{8(#ImZ2zDC^dEdRtLq3{LVcy1o2~?L!bCR&6NRG_GsnTZ#z?Ds zVJVH%dRWQ221f0^Yg{;&m-#|f5-};1GZqPA1g&&st@nWu<6KxSLUeWzz>$bh zmW7lG83iAlue45V@I(aB7gfPHN68V8i0wUp`q0dUi`QN{G15Bt65lt=7WW+HxwBCw zH|)B&-WpoBaoy5^!>d=UXw*{yc7Cb9{ra0rqE-Wqg z%w)=LS~XHrVs5c`dZ|2hVQ!=~j4U~`;?_fzmrOpq_mNYbpN%&86`Lo|yY#*z_NEPd z^OftjJVP&^?gYX7eA`+ZLrl^vuL|#72vG^%NV56)cBk9bNm|*G5fQTBU2Axh7+X4W zOb}C2MTnh#S1UbB=zV0wh|pV?CepaT7%R#=078sOng$mZW~K#Eo_85Br&H@)gcyAY z5R0xyV%C`~tDCCwWv{fX>Mj5g0cT*A=FbNgqE7PuqSA>Znq0sBL#HN^49+fO<`rMYl0LR`hbM8-0&0#f4T8Wj{B^X4~5)$3FJK zH`nT|Fa6{|ud1vI?c55fN;R~1^o|Lka+%)mUclthK@aFld#BGl@;Bah(^?v3XfH3f zmzNpCRLS7t@Yq<=s2_as6ca#e;HHj+GG*_LcsmX4&O>FA8_{O-M=s=;X{1O|Y1?M^>NV@Vh&b;v8e%bqLA6Lm zvH^RRe5V@ zSaynPEv=tD=Qhs3BF@@rzdV>$a_z?PfHuXkAiByg7t6Y-Q~}V%m<6FAR#lCF<8m<8 z<&^5G0?_$l(bo0Q4}vD=?CP2kQ%vi1-Ard`KA&yOa)@j!7V*Z`TTRN*T1#wz$yPO} zmXevNG?gW++UYn(S_#`h*SEHE3=Ft2sR2!escL-a`rVW6m6yLF`GaT9o`q^Fuzl|G zmA7Ab_}veE)6vbZT)VP+(Q3W14XTHWF^X73VsOqvj-P(~kAC0>zRzymc|EsBFJ8tm zmi~Ad?E2}oMuh&!2txt+(I# z((bDdpYlcFxf{XbK+Md9WRQ5?_f6X#9xsrPh?xj97cnr5ImT51rfFuPI+;z4HQjvf zd}RnyE~)^kgt$0b0unnY8`9`ykfn?1`N#kL*>gYsw%6bPE6s(2#Z@yNMyZ;1tzRG!m(&^5VeDSn zKbcG>{qm&b1QxJqKlAyoefxLb_rQC%;x2R#_uU!Is(pZ@I4@BOZa*0$GV z?H*h_ZPXge%i|slid z$_7d^+xhq>KJmAH@;(3LC%(VhHZQ;IrY^hL)PP+?l z-4_n`*wtcO34tL|*PX1jt*`1*pv%~Yp{Z+NN5rqq`>s@X-gW-Z|Jm=%BCp)KcH!)W z5OdBM>-xX{yFc;g|Mvg*9Y6N>KkyTO`*7KTl)7qCgkSiXpZ(>(_ji8jr+)P55B*{a ziy!_=e*vKRCqMnae*9nk-6x-XDv1B)Z~yiQ3W7?>zVgTz(kMA2D1v(DhA{Nq$!yws z$G)nZwbSXOs;kBPXmNbFx`jfJaag4Z$Pl)ZI!i_n1p&mWc15z3OrR^m85v4xV9PPY zTnZavXNnZ(9U@xi*cj`4$_WsN2|xj{s<(;^8VT@H@la9-^g=^ zm;c?r{f%D-*Iaz)TUy_~@U<`ZLkF4-K{J_-DekOK+UfM*BzEJHt;yq4H_Sk2~ z!fOwHFlO_}$NmEo<*^%Z~yrJ^rJuh_kQ@V99{bO-qB$yr63*Oe7R|y z5)EVQL+C=TCrwqm&B~?_Pp>y|h+qBMb0Mb`L$fyR=EsYZIU-EgXU6)mk5%QXs`8d& z2>pCvoh?$>+GRJ2l$EI_jpM{sVKI+G$f>Lva;jQ2&GKYnj5W;Na#>0NL{!ZwH+92o zfWTPWcXLzOu^*7gSi@}UrY0g}Dy4)Fiz*TiDG7ogE|*IoQ#n73!$3++H3}|Dxq5J| zAI9084~_sqWs#zQ-goDH&BTmH^E)@UVsT%&QC__A3NSAgT{WvS@kc-M2i=gy!vmm`YsqRFr{8)f)#zEgL2pyS}6%V=Q9?!PG~IrEc59TPNd54^f8W zMOX~O$+$dRvPT%RG?~b}pe(@=1=*NHJCm!VTJ%8alyK3#T zk34S|``yj`GKQ1g{dlsV0>iS0Ay6vgQCE{;0S73tSU~B=waF}vxj$K?#ke?Fa8k;} zsbb7B^q2)w=2a~;WhoNJkjEe)NlLNr39yXWRy8SY)&>n_YD!OiXsS&nzF4Tt;x#RtE&Znwf1-@M~^>wKB6f92)9 zFph>z%&{dwHXr@OA2LR&)^>IJ;g5e-a1@oX2wTnyy1ezuWB+{j(?92~{2S||omR%S zM+eKhPHh_N+h%figOgL+gVOl?v)AT}S=(}2wrg9JGgAkWdSs(+(^${e<)Y1cW4zBr z3P2y1);R?rYgW@=DN4?eF|MtMDdiGVLBv(=nGub5F=hl}3sA|3Ob(@p!e(iH#{MSGC#IO8g{m=h^^#DX58^h`*6%mp#Z&`C2ci(oBaJ;_1 zELw(>ht}N2`P*7Y51d;sRU3gFn?A(nubhN~0{{j6(^y%~#;~zWM8;atvMN~_V-z&! zOawVck(|P?Dl(*$a8=RFk%>}>QVIdVpF*PuNs1UI13Aq1we$dDtTD~j`L=EW^veDm z*>0}2B0#zO)So!TStuHR-G!EVR=GMu{f)KmD8XQ&t03ZNK zL_t)(UpZ17yIgX+HtQChAqry;s!ZH>OJ;(S59i0uxtMd^)L}7B+sV9JT5Ds9Z_VTB+TXXaKHj>y)^28UFTV72Ii6ROCiJ62 z#1LKOkFVaGZcIzbm3K1clmdh_Szn)@%oAuoUt%0RAt0#&>Q<8*Swmc6y*U|F@( zw7+PGL5p;wWwezmi-DYrU2jHj5c=c8W;z-BzN);5kqJXg?Q~s_ht@aY@MOY305D>X zv6M_~LKxR4vv81LIAv}9C!hM_+RayU9&Mbz@R*nH`mb-iaARvY7`o$6e)N$Ke8;za z>$~1Duz(VDHw=Pu)14AL$cce)i38 zxa%MOzSuV`v}<~DP}Op>#m zu=T#g1k8#icHL~f?)yD=ewK4liNGeuG@EXuID`eE8|=5ouH#U<~Z~(T>8?+?eDyMP5hR@{^sLfeeP}d z-}w`N{d;MA&DQO(arSrrFPHYYO5G0~$7V41=$y#60v1 zL&7stq(Nfqo0wxeoA$$4igVTjQBH|Li7>{nD&~k}28>}SMV$3OEGgoSXX8Q)Olyb= zge8|%;)6{iS~23(0L1R@3dVE3q|r?Iwf%))n#=jyeK9-!cR%{kzx3Ds{<+<7L z>dW8t4R;T?{pl-m=Mx|Du$VZqAV>XhmQ&8%%TIlF`@U~_W?#SY)+d{`==?b4@nYDo zT$j1TA&|G!T9hUBB`oHX9rFYCY^^oe#NF@s=JR3p#?Rl#Z@vCGgZb9gYa4ey_;#4T z6oxlWY+-lp`gq&oGL#eJjEt%42Sk)C#(7Bv1WUlP_cmAut^ZE5~GHUOwNn_er zt4R{&Fv)X^gJz{dUw!`aTW;^}*x7i2@E1Sy$she2?>$q}rqWW&j?-#w=W2Jj_oc%Y z=A;V1Wn8wPd&l$VUVL%q^|$X1WAoC>vBVVPsC`@4W9nn*n!24f_9O-!2db;XMYomn ze|4e#BkOcLdiUGU9&S8*tMJbCD=7NX&D}Gn%lp3Z?VtSRNAAB+@6p*yyP;fr&Xg3F zos5C4NiiW|=rR$GT~D?`q8w8xscD;>a#Uqz648|bV8)ITf#KK4x4I!C{ca5_MI>hvq7cWgF>+N)!aW5;3?;;ARh>V7{_1O2zWJfo z)sBa2do5`U;pQS8EqZZWhG8)b8?*K0e34bErjn3`VYF3!mqn&Wflxj!olZ&S4xHXTlIT zYmHUYwxOFlPcj_O@@U9e?}p{Rsp>QaB(l~JsicrJPbO`c->lj;BQ>-2>-*6R#}A*c zZ|ol9u$SXdwd-509j`tA%oiP_ttZVFYha_z4@MdL&48~>^CpYG-f`!cIz09 z)@eW8I@;~>!wT^3Ef8v!H?mzUl+ZZv%V2zU^zIGs| z1q9jIsv3u-_f-nrw4D_>BT6Bq$z+mq5z$gIpgQY_SXHZPl5^~qOXG|+2DA`hDFW7s zD1hdiy?6aERNfgwxxjp}XeW(#t{VquT}&B30Z9N5fRK@J7{*m^7!m5aMF2u{vwGy+ z+urj~3c?1%V(bjn+i=&r9tMEtuRQTi`{%arJ@Z%oDco}zJ`QtnO%==SF z2RXjF7`NYimm~h#{`Cv(doEpl?CjgWX;{n`)3r-SFU}r%NC4}~l`JJ^DP>L78@KD5 z(+|J%^u4bqlv8VK+h9KS&;EHc?*87RACn6|a{u@I%_gT8V*RiG?Pu(CXkYhWGi~iK z2 zQ~*lMOiU}TAc$KL{t#7UW!052P*tmBPNj$>B>^QMP*g1`Wk&qv&)>Xq*jHy>m!(J% z%jOTh_Sz1=4KLmu^9GRl@W+4eYW{)OKlEPqZn@|m|IbHaYLe*6rW4bLyTk_P1X9EjndJ^Cm=6R27ZWsy|uOlQze= z2%$2jvPJ=8D!pjkR3R47VyuZVSvH!*7|Mo|kFIh4QM8JoiSQ{@y4z1c)&e# z^Kkot?JR9FMQ4+>H@%hP)s>cDOo0)ZS#r62IKS(xx$6z>U;AHvZf16e$sNz|xkn#) za{bM-y7|Umd+f0vx#NK!{>$HS_zt&qae6@Q6Ic7wZ`?v!BSOj1I9GB8MFO;z`(bpI z1q5OSgcK4p=af~^S}Lh9BNJ!fuS*w*vWSRy!&yXCa?XvfQYoNy!O`ck!+s+jrf&eOGn-CJ(cw`G5ZKky(YC z+Z#iV#>{e2nN3_(0irb&Q}$JbDq1E8;_8|4%{_PQoV(}lSD(LBRSp1BNUrjPoKjI# z>#7u!^Hz!=q9I;cIC4(DszMB?DoAk*0^p3pmA?v65m)SDRh5!OC6sIp$1zOmc0ONj zu5XMnI_FXe0JLJqFx%w(Q_noNaqk@)+vm%vn=$DzwFaEM{o;kQ+mCA#i+dEG^ceTCi^)dI4zwm0eefyJ_AFu9yyD06gU%Z^r z+;%4wAm%D(V_hyq0QT+rqt}|3Lda*{h^jp@D3HQupZVhQ?CV~C$J?vzcR%~u{L_E@ zYiymd7Zjz~5|{*Vuj^`88CL;9?xSJ_L7CTX9F29owkn|?%+ZiTqLOpW*;REI#;UIS zqY*@WwLxP6ioYeXx7E#9VpzPyg=^A4Jo3{jwh)fA&Ma{;7lR+M^pAJ{%wa z&7b-g!+fvC8;fqND{F`s{m?ic#~z8l^5Xx_^__LqAlnpk*ByrArywmQ#it&>JU#yo z_RY1Mule+pscb2E=sM?|D3W2xDTY*emvTzuP&G{s(Kl^MFXYq_J469RHnwV7G$!Pi z)3Re`1zlg8g<&vEV;uVsP!%M5>wVP-lr#hYFxD;lUQ$t1=X@APO}VOlNg39Df0kP=pK;Q5s{4qpKPP)KUN?=2%assKCs9-`CD3fJMxJXjH4V zSsWg@#FaF8T{x^T) z$6x>Ex8>Qn7jMQ7|H8+IXMgJjoHL*T9ERVYufONkm%f_EgQq|L^mF>)AO7yAZri@K z`|7QqflnUaac1x7OGgK0xl$6@KTJ~Ww zYjQ4x$b1;a5dfq}Rn>stomId~mv4UQuA?WOcpipV41sg@@n^2zoP6$?`MJe2H_=s} zed;4mT9pL?Z^gCRtsoCjxp&WQ>4JALllfznLj_GQ?)aSg9tx@=$lq|#DL zQ5^s0U;TIQe%H63z3*MOqIvY=*W;Hz+Y)MUDP=>}GKUzgVPhCUa>{6ofG<)IP)b3? z6eANUfT&K_W+Y5VNPvbFMS~J3WhBxl*?R|#?fbqn#$KG&Og3->1&UE@c&t91W@B0t^_7km2=9uRIZLWI_D5^mC0fO| zC_r7;ImJ~yoQV-|l~o}!A(yI|blqH$YUe@--nlT2xfDc3qH!D*z*y^?8;3|lF^)u} z5^C=dVX+vkae&mcbqF!W7*Z*ct+h;i`mPV|-+Y?l&6HzKG3L^2-e)K07S|smDbDbi zcHZ$_fAQ?S7cRfJ_oV?E9OdIb`UozcNW-#fo7gYwjfY}7H1R4E4;@f_o6{>p>=7C1 zBEf#q!6Gddb5UL2+?+3#Ym7Wr?6A=bVxN z__krDaJ*>NW+_Bw2Gkf+RaH4>Rq@t_VXUgk_$rq?hOw@j45}sPRBG>1OsgLyBE?cl ziKtXcE{g0ZrQ)p_V{q1qs;!z7dq7AzuWxR~F~$@Tsb~QJQT1 z%g)*Dn>Tm8bz{oTm@!7l*;qEjC1e31MD`Vyl%ujVLpogB+KR(~ghZ56T!plmSye@{ z2$r0UbtOe>oHuqd^(VVW&YB!TJFTnP`q8ah&2$?2ZnCj9&U@ob$XR3AUh^>{Rq%m6OO3d}N3PUugY-riVs;*OtDdp``8{KkXq9Wq08)NFn zerwWVmT+ms;W9@uz-+M>iTWeLcTQ1wlr0bWJ^W!kE^EqY9?CZMkI_q62C8b2f zDJAFZaxu5wTi1kfs2Z0-EHTwhopUkPG3nyy$T(w+T}7(c*bt(WQah)jeHZ{?2$9)9 zN%h9sJf>;W42#}YUSe!#v%`~PRjsNjr&M|0kHIhlQ;Myz8r`6h$rI*UGpgg8)!c20{iXN&K`eN!W1LFH1^Lat3JXT0n^qfT0K^1Tx4~ zk)=SKOxmFzLrlbEo2rye<+G_jYT#N`n+zqyG+Eo6A0CXu(6p7YE{zcg5IM(@P(^`_ zK`G3(+;+KwTI&>L%*SA;i+p#T))td!*HI*x&vQa>=8`|sFz_CTax z0)XaZt;sPVb5TK2P?K^bg4Rz$A!bofYsnJ!DLTNNQ(LzVyPP6wHr8ab38x+&4tsn2 zy!U%j(u#tqggJTxNhJ8DqH41{Iz*C^GP6OdN?Z^MGFtY_enB9Py)|z0)H+jrw2=TMQ&MT|89Ci~N75Re^KwYWF%cSKB#0qRPF_<#N3 zXFm7L-lsqETVd~cLM5X6zVpWq!s6)Be>3(2oq5X}-u=NZf9}`$)|ILEr{Di$FMah7 z_0^}W;mX^77{J)p`{R>E-A>GH?;j4HIcvJTgWVtss*IQg-P!j){Aa(T^7gU+^pUXp z*{Up7aEZ#;vF`!N85hGiSzk*ju8sypWR;D|MN~vpv?#68;Z;2>=YY^uwMYpeAR!q` zh_&@GjASjLQAsN&Wl=HK5|Jvfp%infCdq}EopGAGZ+Y|Gk34fV3gn!b7?|qD_x-Y|XN!}0-A;`)W9YFMV=9mysn>(|sFJEQrj4>rf>wPL&QdYtoL)*?y7W1}g#=bv)+l9m3eFSpe zcYW`jMdCCJWR0yVW=b(g&fZnIBxBqVMq{l4fI=Pv8#2Zk%OzztX6!prold7*RT@(m zlVw`;%Vs)DIT>r6wW;rNhzfuRDJ9oTa?T}7J!|KO$F`{f)iqTqB`gP5SE8U&6m&%; zLj|%7h^ds-!7mPDE~Rc;!)Docm8)`!RpnjNiqg0|Ng)v<2^0_jW#ST33CVkhhL{Kd zp(vt$ePJLvXG<<3LICx262ge6C1=1D|5j9SGMj41Zn7a^K`~X+mJOvC;~2-2h4Z!u zZLG}}$NOA6XPj%-W0Ei~ga}Kzu)Xox;ZYwVAZSW{HtD+&6o@FNT-6qo?zr>(&Fi<8 zC!!M?<;M7>Wm+T9*HVv48fVZ?z(mP z#ZzZa9UdHcU#Wl^M!*tAS2bA*Kmm4`OV;8i6F|%<=WcF%C8D(I^AVMltGZ4pS?|Np z5fD35vW{VF+E%jUl8O{48dI{)r4W%ZhR{x@5>wVw{q(#>OQ4QLU`-q`}Y zau%-g%cqiVBDh{V-`O5g5n7 z#%yfNj_1pgbLDJ548C$8;G8K*y`>nlD(sycZ`Ae1WHPC%op$Z%%P*}>t3H>Q5-}Mj z1$5Rr>%Fy-Ga`;dU$u?3CZ{YpTWbW2VeW>Lrd<<-H1;Y)jEJB_aR>-t4CO4=P)1YN z^%#d7;)U&vTZePRGL~YQ+1eCS?HnkMIT0a&B4CKgkYURq7Xl(C6(yp|asdoEmJo9; z3IL$Sa8VQiV;E612W00AD<~1?5OWqnqPEc?fEHDVAsI)2pd!vY5gq!3q_*~qSaM`G z<2V{1)iRk(yI2TIN=b8OLRU8+IjiO|t*}tcOh5^M6jwOL2QF@&RQ1)%x2SD236U@= z5P>Q)=2QT2jG?kNrL;<_qiBjk26N7g$kxSJBugs6l4Ul4#WBNmQu;i*`gwVB^OX!S-*_6ZqjNl2oL{- z?fkN#F!WvOdTb{Q3W^FP%#ZzKeT-qYwmyy_#(sM;O#-UA?EAB)H&J14zJOdn)f#J< z$hurgZQam!P1}-cEXi35uFWA@Lv>rFm_i6_3@ZX4sKl5+bww1bnyPlb8wUhXfsk|C zwk72v(X$y-@>PWhIcCr@ZD%p1oFkzrl4~YngNz{rP^y}07(*_JnGwMtXDunDma^nNU^1wk;wu;;>vY6DSBFdryeN@rj76pE@n7Br=({M@PpJf)G@7 zJ1$O)_hB57xT@-`S(Au}p|6KMA&v^@+Xet6WK}??7)!l2OXH|XxUI&MMNDD3wcVdA zEgNK-thfDf=ckRe9J;=s=9rpETVl3ED&l>;7&;uI@t(Yq5S{l-!L*F~*aU5;kq!`p7=R&R~5FjclC1nX?lv1^I>IPR;F+?s|rT9sU zN-A13#W7lI4Rgwg0Ian!hK==&zVD5pGz`Xj0g{r7C;*n2TxG0tQ1WEDwtuj1tVQPa z?d|b!pNYpYC}8EhA`l6(RW*RXObRmgJsWbB7b(+??Te?TMatzDZ=xzd-q~5-JL;oPg#4;_1!CRAZnKVrDI*H90W6U7v~|aa-E3{TnD@?m0?iq| z?mOVMILs}BmQqBTwuxatQ-P>;ww~2`G+etr&#Am=+XB*lA8(+!HSgKgT(`U3GQ^;z zxT+drP|)?sY`$24DihIaw8R8RL)WJeHrCdxb3^Exrkx+2)NQ2#pwJDAjY->BKdl;5 zP@<$Thmuas+C{g#|I~D;`N(jeazkcP*UP@&+-i@GGlCdK$)zYdSLM(v5PKK;0dgKn zS#PSXwPrq)MF^5pTYE{`bt5sarmluC7v0|8o-gKO-<{gtmI4RI$82o*`hINsek`IX zCFdP8@Fw6iLauiSk5EVfX(NaWWSxEb_c*;g*V!pw@ODu6_YqOu|nB7iEaw6Wf~5My1{DW)O?k)#wvDkWQI zQ%FUMHI5l_F3wq13^5@BC?ev@_32&J4P7aUsBDOEB~4l>uvk?IVU>0UPz6jevL!DdA)$gwzHMh?Z@HW{?ZMGW79mCFT}o*MNHfHm3lhlc zgho_~wBAZl$pNef07=my7cHlEwo}PPa)`NOB4`Oz5Rd?4 z2yBgl0;)I0TGKD)OlBB{s;<4W*4UKt=KA{4{3NEVF?`_rLT;LC000fONklW1XCKx_?pBzclFl3^@hAN&V!;e78D&(7oznZwfL%uX#gTr z)m)0m&Y6w<{W*Y6H@Bq7IKv$qxrQ9*KPXS2o0NiL;rDndFr>Dx&Ks<~wE93aJNs5wRe@pV1MWUXDnasfd~an9wGa!AAo%)Xs=M<-P~ z$t7yZ2!KeFrtO9v0Y!?j#;{q2(Hc93s0!AyA<9WoN-LjLPQh1g41Gauw`Tp`2_cPP zOgSR5ubdQh#tg$)Bm)35g^(36=ftZn3ZgZ(jKLUUYqSr3)(T+ENmQrJq?9ZwwyHoh z#9$CbbZv8MTr7!MM2*2*#2GV;!8s9CFOQu9=K=7F3zAA45(# zhA?R-mUJ?i=`d`i@xF6AGfS0KK(n>x9(?=TzH*~{>e6L3!*n{U+UjUN8p7C*Y}pW5 zHmPKTL`(t{b4EhRg$;u$Dlk(w4%QkXMg%5PVlc*plpNcvMN2Wp#3G*A7!Dy4vjFxn z8%9Ec)dm5mDpgYrLtw&~5)iTKN=5_ z;4C}uwFrLQEJTtMr~t?+eVK|VfVDh?XqZ637)rT75h6eU=Y7#qa#kcm6jM?_W-7T5 zu}E1-FPyO=Wfit7l87jdfekbB>I%nMle2&nXDFo%sFH;&t7uVC5CRlcEozvED1~UP z%d4k@uS7IK#tmjHU%Lm36>SiiVO1$XlCo20~;cL=|1l8kvnE6_u6ak&#Lf z=bSYhbIMr^WVW?oB<7g1wFXqjA&g<%zWAmRy0PC^ks@L(s|qon-kJUXE!|72ZAnrG z@QBEWe5|$4+2>VttG!jU7BrUVKoD`ziXwso5fuCg?U!-lz_AEDQWScupbkX@ZAE-w zm7>tz;$H7L_nf`g%6Ei=U0-0$a%B?v&;Re;yO+K8H7#2%*Gszm!frl$ovx4lyubPK zKj$3lvb5I6>^_ECDgXcxI9?7*+p|pt1XE+@rdo^#ANa^`4 zrafaGoxuAgB)L+%IB9YrDe~>5fB(oI+J_a8`Z@rev!t6aE%+b{hjm*XXIUWz7u;+Zdxq15V=!Mnj{{Ftyx}8q|R%&O@ z!MWDw`T0Xw7u^e|ph!N%ecOl}?PpyN&Ibf*wW%tS>m{>@lgqT6`_$9R%W`#CQ@Xjj zA{|NM_kQDdKDnO1_*=i??I(Wlr$6}QCiJwN-u=(-egFGzN$1|qbt3?FLd@jc7$bf_i%G0z;!$S>KEVo^xI#g+j}p8 z8JA@NNq_yd{rwMr_~n26U68ac;r;)5_+5YnNXpTS^j&8E5FxAXSuqr0I{%P9L<=kC)rII=zg3|U66 z%pPncp8&OwVbfyptq&0~&{_&OcQ~xI)ZV8dl2IRuL_Ya3h8bMaAq%5pkBE%uoI~dQ zw7K9BVXA%n$;0V1w)2Ucj$RIjwd_Si+L)fDO&h+QH<>}ChDX`l#z2tcM2*ukYi?D9_6Gf!0}*L!tn zy>=hH4?gc%5eX5Hgue-&3ZwS6uFD)F1g}7IbjOSY7uHaFMVv1qQn-@PXpEh(p_F4(?;dpp@ zIj5M$9O4iG&)a^zE-c;$0mA3go&vKY1DZNSJWI$qs{sOth!@T!FL51n5aLvAqoug$ zR6=TPuy9;sYkiJ^VC=*Y+w4P4oYXchGY#>gV~(igeJlg*D}U+xIf|UA%m9jHh9gmgj9R zwcp*{K0du)mX(OiQOk9jvSZIQR4?FCu0_1BwTNeAS8@?zn@WggW<;a+!@A~Dys%C~ zLNo295;-t%jAKqSFjGgo<^Aq>Q)^2xmDW;>y;VX)mRxp1+|GLtUQ!x!fZFOKpq);q znoC+%$DH#iI5{4Vz4n+Qd%urXOA9f!t*qh>hr^HFzgIH=^%9tQ-?!V_+jH5xc$->s z4k^`Az@hiibk5ct;f3L9t>sZmZKIU+aELyTNE^E6ZAnYcMVQhWrdlo8`*=Q`oiKAi zfH`}~8#+X#Pe1?m+c$4(&IH)^5>g7ugW>7lK%v^FtaSk1r zF>;&3d*4R8KHiSeb!v*i3`#2^a=f`iN4-=h{_*k22RYu}^;*uS^OBMiYOOCZUCQ~$ zaZ}CP`TpT<-!mILpI*eFkBL|mshrO+=4apessH}!Uwd!P`^!D?EVY)5&iN%F(x~}z za0Us8aC3D7bF9d}{c}J0Ge7@JU+34~``usrvp@cuU;oW7{^0ljk=YFmU8 zU<4RqC|gFf5K`-XJ;YXKA1&`Wt;?JSv(f8g7aI~R1Z?12Q z(8d(+XKlST1O$gu6^Ybzj_JTc@TJtWEUjw@Qd=9NIp@$h&s=hAH4_ja0K2^J$J?8H zI)xBhYh!8%9+8~cP*pV+CPFZ(Y?>#_(P^2im3lf?E3n3Ik z7f`B{pme1~j3FY@L0>#7AOaN2~anBcFo`nO-OD>};^|IbT zQxX`=-%yza5mSD?e3x@?Kfntvy$_?06fKGFMSGT!#ugsYqsVQ5%;R{L9upgOG{*}Y zzHgKd*r%zFoY)vRegl}E0G5592*JmtXjQo=Jq=0w-BB_l_?BMA7q*hut;Iu5e z)fNf^+|5s;{Mr9{U-05b6%Fg+D@3!8`OS)^qjE;0P}?|ptLFiKr0pVi3m$UAx8*VF zf&D@M;Ta?GM*fxhM(y8T?`Ss+Z$LD}0a9Ea!|9R2Qlz_DJIv@go`FGz$R zd@Rv{mCe3|7{Zx|ndB1e26?e81-gma`(=gu+`a!^er?T7p4|tJ=h`qe*9{e{>k2>FPz;rN@`ne##O|%!#iE8VGSw=E5VxDKPkmD*vOZ`4KtPR2>41z9LBn67;4GO(Yu*tl<%EY1vzAKas zyrQRT$aq1UT5eGzRG0Ykh1(CiACiHW+5nt-#B%e;Jck#;*~I18aowob;3q8aoXk{! z>6nY%AAifMh~9`JcIEgoMS?alX1#gKV4HJVvDIKS2&`I>DhKB8(bvrim0$-$>N9y> zGP-NeW{SKNZA~%EsvflCW4(0?cGo2P{3p>13EwMnUs%0Rs;o0-yIWGDIb}H|>2Yoc zY^v{BG4grz2Ov;dRj?%WhQ4)q(YWxBcR#>?RSqw(#=me)gQW|^mF@->{xoOY8=F_EWFcw_=Li4SE>B?1=ORE6JP|Bv=~40G-vfP{RUGfD-@*RZXSs~> zz2oxW0;Ui*cxq z1kVokPM>cDx+T%(wmL%HOz29-6>~#32_>mm35XYjcC7@u040e%|ET|f+h5(*WKq}q zY8hndTBmvWb(`zVlE3+^{+p5vynf$26o<7|y!ZFs{a5*oHZMXEeui7MJPscXlkt7# zsH%IFf%i5NCz|9fzv{#9!S%x4`KSJ2Su^01{($|i_su*-@<{TLr0YFQo!LWV>r~K` z{!iPVDx7)>IF@k>_o^nJ$MH>47gAD6jGBx}jh=q;yC5a};__#v9~*z=51kK#4%IAW zEX^!CeqNncn*Oh@aeBQbtY&N4Xliy^e`>K-VJd2Ba*9|RQoA&%?Vj(B@m%%z^;xBU zE0D`8eMo4t_!&HjGEc_b98nZkw0^ufDKuV8o*@63{4`NFp<20fuc(3cqNI+bcZAt} z$z?fUYEb@8kMeTVHSt{U^Q_UD2Y+F>z?(rQL08&#+Tz<3!u!L`!xO@3;d_7C52a5e zPJ|Chhe%dcRtPH#E1s3exs@p0%hzk4c#_!oH0`NNnvy_}poYAa0+-yVviHpnPhBNH zWm~riC;t&X*H7}M3JYH0UpbWCDI3G;VVC8TMudl1*4sytWXAdL@av|srd~GTnS5T* z`{ZFdYC zA-ZZ|aD1@p`d{+bZrfjxUk)x_#2FVFrw&zy^>6QQU!pv1{n_e&pK4#_%|S#EN!}JA z_95vJ@kdPDQQV~l&j&EowU6p3I%AI<$PUm(uEv=sk9LiArF{D4#@hQL#*@DDt|4gw zOV(q`Uy0KppT-t_5|*T5nqo3fl};}+pcv-S>*!kTfv%j`D4mz(EIQLV+;Jmux4JbT zzJ^YNyP56VoRssFkc7B#^f>LsUQb$YZbFo3Iy?9IM)nv1XI^vA=T3B+)5o}6mPRNE zIs~O73J|v|!YeOS@>Ud8Iu3*mWDgj+;$5u!9a1K-ynR6ft}B%*Mc=D09!k%*`l@$p zzEJsg2wk}qmU=^)Y*XB^zt8jGO7Rr~p3lj!WSL|-{6#VA=-&x+6~VZ=<;muaP2N&A zA2y$7^iQ%BGl|x#IoC9df=w4o)eF9tT4epX*TsMDd};MzHMy$e&Uw?hvRx^St0WDk zysUh`dxl^f`;k0BVOu`w-SE4VcQ1#E^Jw>#uAJk!`B3j`>f81YieJa3(0z!v4)TR7 zxya|+SCv)w3`_k><$Ro4zy2{Dy7nh(yVD^S)ouUTuH5c*vr}Ld<Xz2RnWmSy$1u;R^5G}SKkLdvZV%1SLyYUZ%Bl3!F> z+&6J`rlQ87S1uakjsG)R@>%!p*v}cU&T)*Ieb)5w_3(=)V^+gf-^kRtd7`kS^^GxE z(K(T~qyRQogOBNXYI(oj-*vV&C#JqOert>py#Lky;avjZXH<~Uj^R^l(+Ip94L3W} z9@gIYYwOFTRkfuxYR|jTi9QnEc{s{inV1rl9|b=WQPNl5jTt#?YrS1r+qBUe{VjSU z7RwYhl0GsbQz-Kg?_2*e=#NuR_s~*k%;ZA zQ`DnYA*U!+z-TZSwPi>JM7~o!&nhUi})<8G0-)cR}su zzx#iWCmV|#YdXK2PHaA;2Y&f`VlCL{=8*T^JSJdShU#_No*%-i&`N(p|4%DF`p1F5 z->uE+G_$g3rajE|ksm`M^=z0Fb2YRu1pvaY0sv?X0C0F#LjM2&g5&^zpH2XPYCZsP z(YLtGT>b0@tBbJ#0&x1jqnuRz{H((6YiJt)0EqPb?_}^E57Im#vFx3h-;ZXC|1ntlw*M8$=UhrHOrd%R35DBNKmPQJvTHmtJ{&tN-n@13 zBeVdf!LjM>riwL`or=W{dq^)bEc+@%G*m#XH%S%yG5(M7_`cuN$`{HN`jO@c zQi@Q^(8k+L9^)?iw>G5puXoR}Ge-6F+Yx=#%yE5Z7~<;Wlj413o={K5Gq=4fNU z(P7ExYkJht+8nX0%(1L-#{PT@VNo{?PZV=;>qB7O$exaOw*7<_75iVh)m_z@YHChL zV;?(V(y%1Y^ww+(&kMPrUURMxItc=8*;`EB+F1*Vn2R~y*`fH1*?r9*<*WbzPyt88 z12;gIbe%8&0Ainy1uo1BgBSqALf~Nl82phW{!9&^0&Tqvg;umP%r9}F-B{6kMX?!l zFc>hLR*>Aq-p%0jDjQNE2x?OUq+b&v28U>C1404-z9D^EAuF|+zy;3ae%bEslM}lT zgbn$HV5rCd z?0ZuF`a`Rh#(cu&&jE9nv~|*6Lmm8)LMm+YD4OIwq$*maNR@5OBk#0$)h)EI*v#$8 zN-&39`|E9pMX$*I?l@dd|M!p8TKro^)dM%r1#m2YBUAsblnRt_`AAij5g^tAhpM9M zAr-CSacZE7&Vi5Er(lZsZnUVnC`8dAXzz^_c6>MsxG2unuh*Vos1FV4jd-AT-frd% zGb|ZshGb=PE?7@a&SDq5f-Q8P%&csG8gV-_Y7UOA^%Fy+!3x`eA(L0k2K+DrAalZh zp?Jb{zpmv@i#N80a7xsQgjescHNAr0pneA$Mv~^E!=jJI@+gjujYkfh8jj&1%C0>@ zw;i?0Mu&v9O@@cuJ@5*CRL-pMouMG{T*^>YJ1xR5BxDR;I(nXQx&ihfUtA2LZPZFW zhlXJm+iMvrgjOPeOdKTnKaI zQqS)hN7tKL@?AC~8IJ${6@dYw^`~1Cr-yX~BsM_Q{ewN&w%@=~()fVr@yN=_spj^Q z`rMI1SIY{}389U67onK06*1PY!V?N)03Z+u5IR3#6xcQVC+6fRrsGMGc*iu!y>r3a zuxa_8$I04^qn1`=+rF1=u4{|}b^S(<)Fb||u;>PYMpXFhZd565v9L~N=*dqg2C%I- zgR=947y-9-cC6hrn>%uP7c8e4C=U;}4ta(BmWIrH%+vWbzrDHU z5;BsG^3ds%qIk{W!qOqxl|lrZz*JiC?n*vxBY1A%0$@P~1Nc!DJXu=ZLVGCd^&cB- zuVFLS;;yAaKxZRJfe9TCdshd0UH}1r;rU+&{qA5kyVAr_n%4`|Knww)vLtg$Eye_3 zL2HPxkLW`S%VZS{zzN#ZGko78OEUd&9R~n_y9z_M7r+7HJmr-{QU!J=eb*Xhz>L)% zmX5clf4jjq6?&6@fUYVGLGHjW@6S|kQ=1dI^xxC1p@<5B$qp|F#=Wqa2G9lk z!q<9yx~&U9lf%GqR-w^G<&DzNat;j&c-}MU7d{PaY)^0T|UC7_u1v{4I3*_hEXqGQ?V?~}Z; z=&&1A4xSnwNJ1Xb&eO`14K1Yrxi355{;7OqzOgYcJAlf9o_eLmH%-h-jmw!Zs@+yk zE@%F{=^?YO{z(gh5g3Uqr9^3=sKD|%2(x8SLPLov)OF!J^l4uD$q!OI1LJD3o#)`+ z*jEcB;C3~}^7y6CpR`>&WtIkJpH|4{?vs8mcYW=YeTo1AhSkfD4Qi>R)Io!9La*KL zr(pkTjB52fng71>HYR@I^lDf1>B{Nh3B5tPZnxbg2%)QJc}wD5M(R@8T|_utyrk_& z-4svlpzHK493+W$M9+QN-udGnMxxE(g{yLA=42@IZNgPFgNU&9<3k#u=y{))mc!DG zqt9&xa8iet+hUu2gPNG5PXv2x#i}|eg84k~Kg7q&Cn1~KZ_lO7f-}zzBW}%0$ zyu5cQlM}pPAo;td8z2eo5kdl?9(RCZ$^o~flOnq%BIR_|s&`h6HOaQetKP;UZ?yij(?hPPQbse4-jSr7Bm?}ubWM< zwL}_iXN!(bYMpL~o_-tJJN?ru`tR@G4QkWBg_UdTDil5h@Qu=lyUPo2x4MdG27nD7(3RK=Ca-gSF0DzGUXqrxM&{NozC z-;^%DptW3lR;w^WcNPG>{7-3BTUy-=dCu?Su`1A4`)zIE8{LE0}i0a$NO2FpsZxJVoRdG5UIW{hn!g> zoRI%5T?^#**Xjq|FQN0uMZaR{6R!d!UaenSybzno!rp&9UJeXa_#lb9EG(TnU^2ase7h!LBNhV#GESmv-%FH2<$Y#EPFYL{9ThpPOka9{8%daBG$>(U{|p z!qb4PUDDqML=%00)||2V^WebJKBH2E0QwxX|&xK zknd*l9IGW}nokEDJ1%q)^QhFIqqUhCPpQ+DnX*#~(J|)uATQ=<$nhU#OzULnbgNNz zZP!uj-^?3F2L}i5x!|wfRZT-{9$X$)MiJ3b|5Y_NusWfMq$x7d|H+Q;wE!)Y4OPQ*@1_LPq!NRU~ZHM+&^wzW`A>{nC-IE_9yDPqX-od}tI&zom zc14K$%8HC6y;*Px=GUg%9ZX$_?}I%q?tbISO9h;xKbh47uj<|gd%A*C$4RYNEHb%zvNdlf%~-*XF|tSd2Z zp5sjRB-$-}ALPSF9sYgbhUNE`sbWeyq%U)p=daL_OteP2*(tf(`=Zx%=;CjR>L`ciVDAy;_R$`*+jv-s!H{ z>EE3p(K3)s*x8FGu!2EK+sR=o@Ro;~Ln7N&(4N|NP((0nOaJzSiz zZRz$sF9*K7U%eB7XVsar!~Y&r=yD z|8qP*>?rlg$ep1`%@KG)bx^Fgqlidu@t5VHNj>Y6KMNsaV`E&nP4hE-W|t?%HICxV z6_DtESr^L$&b0`)W{*wCSiwq>XXnkQB`^ZL&B9@K+)mCW!;0`JuDG$h^J4Zyl9Ei- zE^e@oagvWooB=1vr1Ad!Jg6qSO?Zb^qt)3#tNQD0V%W!XtNjKw4J-7La1{pfquXPQ zJ(0sl9YumXw?P3J@LTM29k5gk;7qM>?CK))b^Ny%BT{OK{jmkDbxJgXlELo?4`vB~ zZuuLm;jq%ByNCw@*#ZhhY6`q7<EAFQ7f28BvMXVq9dZe?p02O3sq&u8LoI7`EmGp zw+q`JdCl2T@l)h!PL!9M?~@2TXV$$4DZ=Ij@Qpl9A=5Y0nx?IU?ziE!L5ds0kwVi` zs11CuTgQSok&16me|=^^FeBJN?1nY=QIBr|0p&Q&Po=GDE$ywGzcUocz?0FDbQ4_w zP+OFvvw(LCn5VHo#;Fj2UmwQx=1AV(_GSy zqU99C2Lwdd4?0gLmrl2~ zoOnA7Nt~GVMpYsJ@G5o9t}G^oZd%F3ZXGoM7yyl0z1l`0XW)2+(4hIn zT7HQNp|BJPi){ew@1R26%wb(jkBOlU0y83wk*kwdAd>a33UXMbyxAKK8$k~u0!D{a zWvYKIno%!RFlP;H_huv0{A~H%_`qN;$Z){b?#VVea}$_8J47xZEw+Fn#oN_p;>|Dd zQlJ2yfW?~U7bJ(;<`!1~*|;D^X$-L@N6i|<==Y1eUOt4cva&v%|NeMVNnue@2UWzj zCGXh?y6MiMT9NJO$AthR7ddXUsruqak zq)?4bq$4q+c~W`=zHQ$oODd^Ah5!$C*FrL$m|FAcw1#^}GF8$cI;r z+s!QE-ebh7ruIfH*e>x3GPisX&;`2sdDcTPpq1*dla;(`t(d*Fr0vO-L#!cBJhtX6 zC|!s2Rni))+88Ei;pZXg9lmqQVyk?+Cp8Abeia_l>dZrLEYO2G^Bi4S2M#YV4CWJE z1m-<&1~wI8X$_vm*m*Ihe2Z0UPIN%`P^FBTyxs>8R$L^z) zhx{*uC|c2{Y`VknXjy+? z6+Zlp7JQFt=T4Zjs;{dSYNGb8%(hp7uCR#Z=YD0!Yvep_m$hRe;6|JvDkdwWpnp=4J^keVNe7eG1U&`c_%kiqX(70VYt!>|2wL7 zdr1AUB`)@8ai{E!AYc&t7!8-u4mWTM!F{EFX9A-ektvW@NKMlKYqc}4^TfGO*m?A$ zFgc9pMc60trML*|0Ak3a!ndA$Gn1~S~Hx_Cu?tvU(m6d7rQTuz#l{{X^tYHAcyjt}0K zuB+b)v*Bkx`ZiQ85m-3cE05pKcFB*Ep3FwtSQs%Tn^S52Va*P6e$HDfyZzW%6m{A% z4_<O;T;P9|7Dp#nopmfZbk87Bx)qTi#aR{OV0u)SS z3xA%{O<_$pc~(&*{sQ5r%X9SwLq+mnmu;xFEPKzeT-#lQTe=hv6e>4F2QsgV@#SMf z$Hjjb0u6gVJq9QlU1L;G3&rZRbJbN%iv;NEx`<$9*9BZ2lQJ%`FY6%URN4v{p9Nnw z$}dn8IA31}R6ttCYj19{#{U%mK5M#QHpI8uk%fW#tDsm0K=EYU0%`{Ia=L>ypl%97 zSf}z}YfyAcPbuJddqFFZH48P{HcTJ{mF}%bF5YUfz^SZi zOT1l7ig}wG-oBt>1gs#5RMki^#79V7=?^41u;r;V6|AV_J`9VBa9v+KiWaIX+0@uO zT&NzAxrEJXb;1NCG>C)D8Qj(N1+x4myt%`_XFz7b`aiDBLx2C8ah%tPk=+o`>gK zdyU-vmUJ#BZF7B@N9zodf*a~%SqDuwpnrT-4Q_`S4Y?ou+r9{fm)+6M_t#8ErNZ|! zI*(tilIjJUP_~8$-PP`i0U^_;z{%{TlQA^9?i_mfy-)koOMr2YE8lU!ts?jc>(2Y! zA+ixS1C+0U5dd9;K06-kK%}m7=7D=Iw*~o+I1ueIl@LX4)D&=_I0Nq0&ujqJ!$>^09N| zG9pAdw}>;WAYp)f^?Sp)kj+nQ@Usv~JFU`U(a|Cx0Pw(tol)DP&>}d=y%3;+Lm*)N zpFcj;rY$5YbkQ*;L?I@K^rQq7o+$ZeZDXtH zj(79$|Bw`Pa(JK+R}yd)BbA7583lI-q>!d% z%g9}sdWMjepQ@CwPk1t)Yr69%ooT(*hou7M7~rPpJs=Mze(>!uRh}23z&MdT*>*=S zN1|WA)d@z-hQ90Tf*UZ)(Gb#5q>)J)GuNPQ{FZRC&r1N+2>oMmWX$Z5a$}V|gdun3 zvAtf(W@&X`w2k@G{B90*?AK|D*Gj_2Z-TE>^eFkI}y z!2|f=Y!AIX+}ey=b^}>NlJ1iq+LC!&@Y}zZbtF;*xN^8Y>x^WEmaY?r*0v&NGxYLJ zcNE8lCs@i?#?K>K$V#S2{DmwbvA*#L*{Zabvh@QR%`}eVSyn>ETPEE*&+DM*+C&i1 zD;1V&p$iJRTv8v;&C)Ohg^uve&paIA={P+;7=oW3aL3pLphQJ;cV2BuzO990DsNJ` zxHf+u2TPH}vo@BE{g#v^e&T5cEbT|E5R+*Y!NTF_sBvb zmlDF*7jQN41uLi5u*S=m9x6Y#?s|;qmyl8`4Mjg3MPVNDMe~9opI|Qq7`uzBv)^KV z`$iuh|J~o;fBkZ!z0q+5HdgI!JO1X`eWDER@6eobNDZM@P=TrY&Gdj-21(gdpIM4B zaY=y|!GM6O?=mhM;1Oxev#*q8j$YJ}!(}-EO+g_uxZybOK9#@|a#Ou4Fy*e1F}2Cd zz^gafJ!Dl!e#EbkN8V=AeboI^dc!7WFg8K2o)a|laFfKlC3fzfrHf?Ml*M+oQLTH* zQFFYjP%$K+J_i(mhxMP?o1Z0urf2eqCnzTQqEk82eT0d7}Pn)H0n%2@~!xW z(T-pkD(nIPKvH5egk)QQ%BNWY1U|RAs&iln`)9cwQ)Do)OTOjB)9Qv`~LTr_Ysd|33>*Y$5+{V8F6nQ?qzJs)QmSK^eyAK11?--x^vx zQh(@tt_S1fHkln@1UKR+uAYkE)&WF*`Z#>13^g^&)nGUQR}SGX%0P^%a=tT%J5P5mCB_FD=H-UTDfDZs} z8ueN&652J@OFg})>PcdxX1;hr^Xk2Y_T7`_B!OLgwgdS6j8d}!m$_%qZ;wwBG)Z(5 ztv&eBRf993`Jm*H(1hr6@yy~Zw$0)k0K+#FEf!uYlk#gI%cAZ64Q!1Y>*l(F)UZln zntyheKWb*>O95SOZW!m@w&0B?EQVXlRIL`r9PG+e1!lj!u{~3r6tjQ0e=>Rax^$E( z9p;<`LK>P2gKZbobUsHh@5qR zFWZ251a>$(nGh05Oo>$$^UZ88;Xvmb;8Oycae&btK4u0&#^LOQl{!y z!MY+7+En{?M(uhp2MX%C0{eN8H_;RmL9es&NQTwf!j0%MxGxdPmdY*L>vZueeZy(+ zYlu1m&z4y3@DxY>XZj|)n7-R3Tdw4;VsP@6v+tW~>g)E=09Ix2zvGP!l~284L3^k< zIqFj#G3>8e%jtl_LI$_qE|ZhLh?x|+SjJ%y@xCKcCauS1&`^>>T?m0HYJ#Xg%4jTdK- z9UL78nyr-s#v2HhfY7k$voU|C*yx>KDsnjfI!|T|S8tNXXqbv3tJ@QTyLG@! z1GcL#q_W$OW21cMMh|{xPf+~9y4Mnz9e|U{sk{R}Z=Uwep9I@hH+5RPmsF$J@@Yvw zyK6cvRGYz|&q@uP&_|e()rws3NvhqkvXx+V{_b4#ToEN`72tc91uEomg|~{&xK=vb zMICPp{4S^dWONuIaAkAH$%S1&4=63g?558a#0jtS@Vun^s_J%%0lWgJ0N3RypnP3G zxF8?C^qND&!G8_FD1kx-nE=3Qs6(E&Jp6cIf#tXz6;>i7X!iH6X=%B`NFv>B!i5KR)w)@(Bz6dGu z?$&x(0U;#0dzf9@(%#<1*D~49259fq@`W{L0P>jLTkE;^Jte*keKdc;kdGDx3NU0|K=05h6VWUi%b;w_k1UrWU)4!4_6IUo(rlsa9yXh)!X`bEJn}>_Yik2 z!L@5nJOSb^3M{(Nt-atBruMKxi+Y(vx#0}ge4VoeBoQawEeQ?6$!NJgz%tZ7TR$zV zG^4U6*v0RivvnZapKn^kb>7>q6nBQb@T@LDKq%33d!ac6%Pf^ton)ZP2MN@| zziVgxCN*I7pI9!+xE5~KYXl!<6`UKyH8 zVUK`K8#S-eEu7=enln3qGTA15ji=xb23^%GAW^NpHXq?guFV-8zSZ8R()Ouah7)N? z*P#3Wkb)fUAU`D+*iF+O8%|C0MJ{EW;W}BK)T+ns7qa#$*M%H!5NFSrofK&zzUFAB zS=`?p2dLWdk@dmvdC3x^ln2NsHKZbkW>PKmGj-=2LO4>^vfF1(lH^l$sb^?s_TJv? zF6#CJwNK`k!HyYr3dm_HZ5^=w+N+&Gy|aVIIONP2{ksV;@FDEczGRIvWRN*@Mm+F_ zp;N(g8Q#%fn;U{PcD*;Xedb004#c^kow%OP4pPpdvCoL&T3}Q3!XB*Lo%NO)`x)ee zuT|ZA*oZIOSZhlijBaXZ6ZI;;##U1WMtVI>-X*1}c#@bxV~9S%(`2>OCr6*@NDU|Y zmrksPAC?kIyzH5UJ()J7iq^RFXhFOLLqNCI-QkWmFS4~Z-vt;qb$#KJFnB7gci;e2L z4AWg#-;nu{b)JvMjy`KYde;v z1|Jm(L$o%!T55h>{EUTe`f@owYtRO%Y#{Vt)}BRlQrP=O54pXy@^#RKtfTw*pC_xa zFeNta9@qEoX{_SkeshS6y+4}T)H7a}PrMitBH69t+C4I#<|=`>$;+Q!VXu`&sI|gC2MF0ht^2 zKE5U&1*;)+>vMpv={~Y~AQn*g88p({&ko?JsO38Bqm7Qs-Trz$t7{>IsgCq(El`sw zHkdT;t?t%jB+PF?RUO616BGx6o16`vW)1i<^Kk!nn$&I?k<>1F0qbW29jC8o_jdL| zkzAB8{k_Sza^J!V1f5f|K-KEv;M)=s)3EVZqDdCDUyn={G}H2_)J{**8YOJ^mvE#SeKYvl-0px*l8Km|MpZ&g@oQzK|A?D}Aqp*B+DV8ODRu z+H9px-dO<-QP#p$UhTIW=8s$5|CJv%{t;FQJ(QnRK0U*A?}BoNYdK-AiI*)H_fqv+|Erk>L_>O*8MB z?<#1W=8B!BDUQtUY(l*Tme^Zpj?~<>BKI9h#BYw?ZVMd&3$(4LavXl|fwdY!*N*{-^4;I($PGXO2YX*z}(*Rt|W1A>RF>?{7XzQ9U1;{lFhDs z`O&u%C81w?lk~2b_`4xepM@AySdmvGLh~*g=qf7cUJ|00J8O<=UB2eNe5At`;&>C9 z7Jm`ZwDTF({`8H~_P553l1zy~F}I`*zouqaqcu(S7}=jY9L-^bPBUti-JeO^e)~7y*2?mxf+H0APQJdr5D0Mo&E(t9a4H%CiUsOvzAyr^!F}{Zb0I z(<92(Yso(=Bi<((;wB36Cjad2RuVQz)L{buL)d4?QO3Q?Ge4ixs|JL+q)k6hS=@oJ zA|K|O{rRXDE1KGO3YL}Y?<@OJM%mt&TXRo8P?VACn^afxUp$(O6sgY@coz4R^hb{2 zX~;}VKR1Aatz)tQI)gsy{wC}S#O-ZvDGy^}D%d$<@6o`Vq8S6-WDw`)k~3#yTM8Zy zmyJ0&G0Us2e)!3-#pL;3AiNBjCRLqB$+M{AE{$6{ zt5Jxw8UoYuPPotffZ{YF-?lHkvgyX!;{gX0FL>ofeEjrf(JHaK)TkwH z&8V8HX|jha<1Env6%*5b$9=XrzP*V&;AiE5pO2ZR&v;QQs3&*dC2iIvma6_&kG-U2 z$jpi*8B?FQxsJ%~%ah)5xjJ~+vjEzGVudMtFZMKDc3c4Hr$=bEr-%iISwo?`i917z zvO{C^Mz#L?AAuW3-BuktOZ zlOe2$jJ!ixTUGa>u1Cu0J-kw}jHE;B(j{56euv7AnK2rrk0XnF0t-fTP!-1A6!hn@ z?bXT**j?W-S+mv0t;5|(Qq`Hq{-{!i8;OP6s}?|5+v-U7pFl38gTttyoJI)?L>kHV zC!ln6yRnn>@8IAd=3r+=ixdr)eWVSg+zNY~K5G7Z<^AW;-Ce(<=%X(P#11V(EB)k* z&Mi!@cc#|4u%08MkXdiWta8{ivp}4GAMK8U^PPQHC07;GYW28<)dmfwCZ5!=K>Ewf zG!!Zs0NdVTJJ@;Ow5Pp1!@4OGVKuLMOjcWlS}<85SHBmtDfWD821H2*K6&y70DGxY z0aR5o_i$wuE*LHQ7U-{t$SxC#-+C#ckCW>Q$DD28)rHP~yK_Uu|8~q`4*fMNQPr81$EXn1Unv zP#=ov6422juLYMhs7pC1NKUTT%7bceYDcvXGl?iUqgbK$jUbft6@lI;pZNk# zXN`2Pg?|4>k0pmSWZne^r?Wob10wI7ao8kf`hCwQSf`rautu!{X}R195BaH!X5OW^ z?D;EZpTj8c$37lGYWoB%=->5}5{l*P!|4O=icUlEOvkr5x}1wHj63 zVKrG5UX3ez(`JBmx|=o72q_m2Ot?QJqc>U=AKm_K7p{?tC|^JD<=kS?{atspZmx|pdZUAWy^WSs z&~XyV4GR-R(Fo0F8p!LhRqub!iNhA@J-QI9&xMGeB)aG47fe`=3>C&r>b{bprQJihd9rXaf+MR9nEIDoP(|!$*c(0R zXpo+`^~r(F6!$Bs5UNd=zWynNx##D7r%gaji2=V2!k&W^f<$&X%*H3rlf zb@0Km9sS367V_rB67J~VXqQ0DGE(m56ln+p#Br%r z$1()37rXdwZXCcrXrmvHFO8WQQ|&)u?`vF-d-HKau{xW)v#DN^_dzZ14kp2&~D2hQ5(tk<^?#&_}_mLipM8XL_3`+tuEQU3m$vP;ni zj;F_z&d9J5JrU&IvNiTKkUNH1!T7&3pwmy|(~=MUl-_w#geINt!`3!}+n=U32VSKk zrU$+l?MQJse0|+|{d^7hyWVF;0q%|3(RFiMcRqK?#RK*mrM+aXPzwVwHRYJ@L-C93T&T;1-y~pHs|g5! z6bR@#zzn{VIP2n?lNTF}%y(;%Go|&i8bK-{MGmXg>f=lrP5b3sR9ANC`arDu4I^;; z&!{s!(c*3y%;pNr*Y^xnf|8Ib1WuYXpGfNlyi{_gFX$`_qt*@mG0 z^a%CJyfXy;XhA>(8%z;s3%_LOC14H~HBwQgc;WromDPsva)WXZ8C&V717p}_^C~-4 zMLppsy6eIv+RZb7G6r+o9~B?iUI!3z=lG;M9+ehBEbi(YFI@yzWX-YJL2MWLVT9*n z{bsh$Q4ijDc|Gu2;Wmm7&)XY;A8mGM6f3~Amb?*1KWvwWk~$)^;zO#{ElumQOKv4u z^95JNKM->Nizi)84^oD`wCC;tWRyy{VGDsN?^RUq>fPk9>F(JEVNd*nn~MM>40^{f zQf;oT@|IARKPI3)Hy6}9gh1diSA*;6qL)4|CWJr?;Eyt;oHhNa$lb2ZSNc41!L1nh zV9D>!!<~~Ugxs;cn467rpMndP5&l?whXxnTg6`%y+Zh9yV9mISxXYmn)i^TDlV z@OukcuR=n#ipN7;KCo$M7T%96pwHDGu3C2SJ^g|Zt;2%Y1qk$7A8!)^(}5b}@Z7d( zN2sH|sT`AhM!ReUZwi*p3%%I?U!J?K=5nHr&ofvLGt+U3!44!;(C_rhF9Y`|TG8kH+%8D0Xf{Uei{qsg`@? z#?dXfu=+9Y6o{J?xXI3UBg2M=&6($iN5Pd~{s>NiMA4Yjvg*YZYn>KDg7Ck?hyobT z`5b!dgzCRv4|K@MbEe?M73C3dS;f*KYB^7I4`aQwj9kGc=kYu=0Y~ynJnhx+uzUod zFJ&pE9@n1QDO%7 zvT{Wet`;NT6XIAYa-i*S8#f#LkD@UG#cMd1guvF9_PkA2l}F$vBNV#me@a7;SY#|K zu@B_bkK7DvIy6Nuc#+Mdnb#KKA72)83_>i=EPlGB43ctuWN9B z5uW`XGLtb+bboF$%l1j0h_wm1 zJx{uZFvNkmbKO?P zJy7fSKzElb@N{@+qRyl8G4Bs`@=+dPWF`m*yj1Y)!#hkA<*?JWNa2UUeJ5_IX~&2j zE{YhzhhtgGyeeXYoLRcmfl_=m#&ylgNILbJ$VzCD`ID|oL*A_z%i+VN?N(fdF`fbZ zuTu7U9#X4nMS%Ut{`@oaD-oj%(U?}buFj5wo&8P9Y?o&7a_$hFIyN@s0ac){1_$*F zAgZn51(-91`Az?o`jKp&%-t9`uhAzlOuj88O7f%OLj<4QnjkaxIyg2ZBSE=*Cv8;_ zF*W>8`ma_JpcfkBv_?XBjyKm{U*%YZyL@L3-Lymq`=8bM0>x72^#q&5anzQ z_46EES>U&h$1;qb1rz*Uq)-om2?Z?26TrSo7f$hEWRS zv*6gxGR!9{hkru~>k~Fe9%fWtJ{|ot=Y243Z&FZS!vx%#M9Y;Vlvg{5V#H6L)TJTN=YEr9oHzA;Th>e#*c4Aht!zliydU<}l^vAS#t`=oL! z)JpHf2^)RDyiv^k`+s%k0k$E0-?+^HZ*PfpV&^Umz0``j-|-aDJ(i_uo!XE?j;0o- zR5p7)Saj1?f3tm$T}HHW?3(owf0VhE z!abX`V`Equ!F)J6*tkLiyObB~#;J6lfmaFFk=y(zC*Mlm>lp4#I+*M_Ak7|+n$yH1 zP!fOuanjJu(bx`+!l)%gxI#tQ_VcW0IJ;kUfVP%fxl9t&a_B=XRkn8K9DqoK|0BP> z28=H#8lf=I=-i5{9KcbBTeQPwESXDjrg`lrzf{2{EItvacQ-S+fO2^Fvv?#|TznEE zh1d@|j8xagM0b=d4b;TqVL&wOojLNp5s{OYr*CJM?J-@P&sZid=w2uebnS(*ny$3CA@mMa_NJcn0MZ;oB}=XHD3ZCx2AXB2B9Kp!>#j;!o+EpBvCD&E*k+!9=N=KWbk9|43RT(wVOfH z$7}6y%6e|mr2Z*`Z=x<1kG&4pnuUZm*R_v!>oUgW%Kzz|`D#)TnzgXCbUi-ozfv0t z>T@tp{OHItSK0bB zEFp%My=1aW(_HjyHMO02p8U*o>C|M`sc~vCA2GeI+4`hXtLzZT3%zW@@zI$!Vrd!A z>BFr!(s-JmtC(%aVZfqi+(z&ejDzQE`aGgz^a<+OqJ)eQUkRh9)ikiaEB39T`PkRY zt~wGibZ{(I5SG;&uQC91@0=mWStO&~PQ6by9xBlkL5?43LwIbMiUXu47H3mUxmfjKQj*Ircz>AOOAKjQf4V zZfT!Net(&`XIcZfqIWqNyRETAZW;fL5xK>ED@q&S#trB$6sR3nUDEI>mJ`(jW#^+7 zH72HDeYcMr`+IK3jjOBmJ_vWjRSdx?o#M&Tp@b^$)4JviYojFNR5l(FB{s7$n;ll1 z#shSCGfJ~uG903)WnnssAGe#6R+8bRFLr@btn8k7ZXH|^oV9Xz|4! zksCabIGAcY`1={$Hq`4x@jZTJC6CX^NzQuz$jpi%aAaITE|H{M=6Bn~+o-B6NB-ur z9n1{!;EnfSh0N0kNkbmx8;Hu;3JM(S=VdN?Huz6jL29^fSv}6ZoisuvVn2SdGk`%o+>IoG1V?kmM3o8`lq(+XzpqT|h@su+d%(Gfk>#*7 z9`_Lu8kmdW_Md5P(DTN-=Fpp2*~jGROW4|K%vAH?(<5P=xH8AI?@2us-Xg-76aOAv zp(`vKT!Fa>UYv8y)wn52_^cf}J)5!5`n>S=88VF-&i-;OTs-$TIeMY4Iw=}!J1*G6 zHJNb}pzjXTr@b40II$tgr!+3XnP&M$Qh4ZRkk5s!t;RJr9;bg!ulXO2Upx8>4<^%p z+Q$a};JW3n7MZjc_r%RwfO6@Th@lA$d7JMv+xYV^uP18;6I=t%gl@V`tzo5T9 z6?JJwLe4sh-a}i8R4+EYA(vAc;0%*V?yfDrsaKT!`Svj6BVlo-S=@Bc)BSlC)Z>I1 zm`Hp^@7W`0_P+sOahS#wF{hBC#3gT+9S833Fz0^@dtdR<6iQaUM{RN|j=VR}TxEPA z7SSf!RFGeJ)|z(X4O4j|KYz{0Z@P7RN*z#3_4kwpZ&~&X^9aCrHl7||x?#9D4BcPL z9b#3Q$E2=xzP8WnNuLlFbnMP5jo{-!d1;#rZ>$|^3DciHUMt?Z4uGFA-QE9i zklS^zgp1kV|EO_eXm53OZ}aaLKO@9#;iXVVwEX4(vpxQ>WyXH{@Tj!OkP|-0{k(i= zRr!qpwt=Z|Om{_cOGX-HiA^U*7Ce54Kt`=={CJ|e)M3_G4Gu{QD!M|OzG?Zdds0>D zb+G)vQ&j1@EBz>LX#a-yqj~6K*v5_B7S_$AY$so?cAJMrXd|Eui zq7g@%2Qdyp%7G}n%J~;P(IsFR+DeQ=2_0INRU*Aepp1Fv2lEgz=>&5y0cx_4n|p>4 zUXTmkcb}~g4B3L4L7zh_HrBpDZ})y>j(w>7H|7ofhUiYSM)9qM7LC4XiYl=53bZHm zjIm^yf}NcjWpfpRb}X7E%P>o9L7S(atp;bZ|$671Djn#`q${uXpUy|J_! zTu|XX$UnIy{jn~wG-B22g}T>5>9)V1*lXTE{z#fz+Cl|TZx9S=M7u#@U&d~F3njV&wY7#0p+&Gqw-Wh$KtCI?bO#V zKLu-dVzXWaZ_58qoD>RcQl(%RiSd9HchKiK)OQCsKb8Sro;&o;_r?CYN>N;VA0U$$ z*foQvV>g<`Yu}5Pg?pY?#ZF&8^BOxapU}QW9YFGf*PFuD-NH%X!AFNtD({%h5%Z4tYPWqG}2Qo{7eAv8uRdIVEag1n@sGV^gCXN zJ#NTGFYFGi9kKQ*Rv2C);V(JT!rJS>j{#~K?$a<4MrJA}yEsxI>`9TBM~$@MDIGGq zz_WZ=KziO3H)q;hA#dd|yZv9C^M1zncSfoyk|}LHYf2Xmxf^);m%SSPl>I679~1jy zdf|eG-Sgyu^9FrM5_s(&U{9^9-ro@QwUXbvuSsRT?-NW~dg|Sfyh$`ITd^@S02rN- z#BVU0v1Nx$@!9%;4K$ibIwZpUscX&t()VDASRB|x z(F`It_ULpjJ>_NaR-&MLj8?I&$LZDBc5`rHg}22i8-`W(4on5r@EYq8tIfgOGJU5hWXx7%qW3^&?8nX2^PARdlL|w5Vc!n zf_g2Bs|a;us|MmtNWs~*zn{*A>KdtKFNxX*iiYBS#2US_5g>YIo9CTyjatW8pVi*CpyS17npk*pI6N7>fcA3Oa=WM zOu09Z8Xc|7wqEw$H~_2k+MdcIJ$FC)ah=>i>^o6yEq}Vk>tFGw-d7ha3!+2;&E({o zmC755yFvJjJQMEqPJeJeaj(*LyzlR|34l7fL(wGwmqm{iJ+1!tv@VT$EC}?EXP0 zTQ>NLWnD#lyoho_m_p9=4H9ek1%!hGn+b}bGBe0xx^sGLULk`kg8e#H4DYw}4^o}LY-XjPR&ngD)v}@O za66c15W!V@huCuGTzuE@0{`iC@qoB2>m8);RNNC>SJ!c*0)s(XqlwS5%%8b!bqt3o zo#KzGf4@)pVDbDsMX2!wP(LxV@2-&c)wSOplqohbQK8EpM{;1n+@7_6P+3b4{RIt- z_&1loTP5#>=iP>xbN%@}`uL7?^G{|VMU7?<`9w2Wn*(U8-TqyBENl_~v}Z1^x+FxJ z@6GA*KhG#ce8dlr;i@<47#x4SG_{325foQ)d21A@`P>dC7jh%azC2j8>HKAN6Kx0l z3~hFH*0-jqiKb2FnG5e)TlzT!F&sfEXeAPb8`XkI&3iy%7+q_8D*pZUJ%4W%{-{BZ`fHR@#j!l!d33QbT-@?xFpcj|N2h;`L_XH-+W z`0f|!CD33H&x^si@!_H0hB8<7@}3Di|9UkT8?Ga5g#Y;RcMDHp`QHwDM$0y)QL<&O zHTgwbI|R8mlT~(G{U0`lAxCfi2WQD1qBC3qZaP9Rp)mz8RA}%here~&SB#30!y;Cu&~fZ#);F! z#kFH2DeE|rvN@^qq&RFbMyu+Nj@AC65%_1zRsI&L{u%QI+5q=!c8R=QLGuYQohypA zn_^lEe{|kC2X^ze0ZLNR9)3%DfG-V^wudNN1Cj(jT@{w>O&;<3Yq-?V43qMZ=5m)* zH*Q29be3FHqrH6TDB|p)eJ0i@a_ga!lyJAUGH5v-;xCo?L5=qOv|h2!XhWH;lBETV zXEDa5xe0X*^n^)lVR7QF(A@DRaW@=N+S@ijH&&s#!3mRIN0Yt?qNeHxLkt;Dj?r}!QcZD4|Orh;Gl|Br`9Sw~73F=H$9CI1>hPFN%q;QVP6;7c~M)mIsed?MKb}_~9E>n}6K(x!u=U-2l$Q(NC3kMK7o}j9LijS2itSZqu`ZS1)P*a@p11I-T}1 zf)?{pwQT$%dGeCp0jrbPHB+;KCT(}t4I^ipr!o%Jq9_`ar!t}#Vk?+Xa;DQ!k-zS_2Ka$DFED^vUQIB9I5W;#JK%V~@UFVWd>js};r%*;n?W20;rSpB@v}ew zMs<-H3$b0U@>f0AhTSj7c;Z87&TPTMq&DJIx%bWYsR1G`dzKF*)|=2s9UY}Sz)QsmFDy$`HZqEX2#S1-@mpNCPj^w!4r)%T%;hs`Fr zK*!KIDu znrY31K)TJ6H?*Fr{%<4UCyv(6`lr7n)p3;?VpDR<6 z3a08CUGmG4I9-JLav!KA`7xg8v1`_^t44;p_sdWs&GJ1z)id|Fx?zSgn~_md(%{oq z)TeHUdE$Z;wfWk)p!1No9|{zO+eFKntvCVbdYRHko@oPUvGeb&0xr0pUbo7b^wBI< zphnF$zh--%QULlX5sTV1Zm}@+A1sVc+vxOPMA@3IA&Pc_TR__D5huO;{zX^btlwVo z)C1}rjA)ZNzC?G4V*_t>``y<2_rxK(ohD*%ymKVa{iF>Semg_{MB?I1xG2LN4F*5V zc5yU?yZA!?d=WQIZ7`w9u`=9fweXu#yy$dUa7}ORR0|Dz(M_Ogn#SaWIby*B)bIc~ z=hhnG2e+c5yG}iD*L0BXExiY*oVLYYe|?eT_;7y|Mq~!L;y#Ec9{uF^%&Eg}7yk@Z zD%HLD(Ngdq`;>)F!qYm~J2wLSf~M>8^U_M$BH(&Zf5RY#zLjzjR0-( z>})-Y%;Y=o!YlDgzt5_275{i1#Lm~;Xpgdjar!^G{}`T@z(@r^jcA&tBT#{7#U*c` z!SO)-yNbmc2y2#?h}tpv!&lNWj>(+m*$Qt@-LdA+%-|+9FDoalgjgU3`Q}KI3gEJ= zUJY}^AhWqh;c@U{xraY?jX94ANS|Ee7G&wg28~vIzT5jOxGQ)PqqyRKIM8Co+tzQN zP5E;eJG-+GJL~wEf}{@1HEmO)E@Yyq=TA9O{API{INJ$fu?^f(_`}`1V?>b`;W=n( zHl~L4@SYOqNYYLoy{*oa!+L_5uvWjvSxU|I~A>1&)>R5lWl0DmC65!+$ zMi7q%W5vqG@8R5UeVU4{Dr;_A8*oXD&n92|dw5vxRqcaXx^{w?k2_RM)U7z!2ug;+~PUklX1Y(g2Eh+S@h7-4~MHI)~w-tOBpP3 z5ZVvIoGGoXzV*+-HVNT%p|s8TWJg3oIWGWWsQ3kOA}JG2U_Dy3F9-AE6-yO&xmWM5 zugD9Q0Iwh_7;l=|12sAg;UKP;>QnTB-Q$Gx0PnNh&BOq1r^Wm>HUzI;h%p{D?9YF{ z?g1U?|D&&Ho4kl&Z^#{LJ%yWc`iG<9ah!(K<_e93K}CBfix-N?S#q!5|0QLPjhl$9 z{uFfQVH@rUVHpT8!EP#^GRe@#7Y>0n_y}_Q+$9OV#Ve9#W6FbUg$(dj%HjKO$$~Lk zqtPXCF5Ew|S|e1rORt=JQuKIT!zJ0u;B1HZ&4rHPMewq5h7(WG3R}C~B@Qi5v8FYA zlXuaV(Msr(Y3EcE6!`9G=lo~Mf?vk&Ta<=;`mpqa{nq}kXDJVsLu>?ex`Vii=`YuN zcnaeLRnUAsPaB#O=e{odWE&lcJ)1d@8eA!~_2y$T=-W69DIBYFnf5Y}JCuDDs^+Hn zeNlh$adwVy12DQ@toO2PKb-t`+EKSJ>e*eX9*2mq` zzm^&#arQ;kR8ST%(#Z^MeTMNPirYIN-GFzcbA6%dPvOKIbKpD%p3o#1T2~`9idSKG zOK^ZD-gP{ubT5dIj4^BaDEpvdY221|Kv#Zf71GnVQ+h9?MJ)O3!N!7nC^L%??VZhZ zxqd?G;Tm3rZ0aXx{&BpGco-|Xc!(wq)(%7g?gwyuL=gRv@Y+-3R_FBsrGiC2LsKDqU&X#!n=m_*fo?p*KO96xR_5(5 z?X7_H{{`LU@Wnn5)QfyS3uJAXk142WopX0hSV~mngY{yLmqr@bmy};+>XUhb;-`9s ztu3mB-GG_y3PU#o`(K6lH&L=2XbaE%SOTxESmcc*P`HrPBLVoO+$(^<(WkwUa(o1u zd$Hblw750pjpY_00|@ZPy?zU&>{$2nie_e%4%5ezDzbdBthRv7>Icjf|1{XAgICtV zM{OTtm(>l$vf{v>n`L*|VM!~f!#n=yDUeUenvYpW|HosWvi!KvfZ4KTa}((KiVx*eD#xKCC+@=)A6{0$}5+Xb-LKCN0@F4 z7ZVhdkhm-$=8=rLR=ajh%g6&VmZyZ%>NxJ-e}BXTpp35|v!WBKc&^XhWwtgo_z4Hj z#AbaQ9(>|8sNRO}k4!gSJeb32^2KoIordr@VF%y1J-q(S=$4P**M}Cr1S}xWF2)yG zJm&J}sg(Ro+K%mHseG70C}BxX+H4 z?>*Vx-ZmX`Zr*!P?aR+fSY5=@HW4~}j43NI=zAS? zEM3MElGrmEzSyF|`m}@@+-J>->nUK8>Q_)MfYWxhz){y&$kHd14!*lylz;fIfz%9x zDa)U4=!>G;WNiV51h)hqp$;V-DYw<$KVPe=^4|W6Y|vsRChuk>=%`wrF}*OFbrWq@ zeAm{UoBM9G2rrIZN~U($%=lBuMY#2OT1Vw`!7@hH=G_sWs#2fK_Oz&T0=hc1>3cim z8a6CRm(1%?6~Wg7dBGyiT}Zf?Grr|2;D226B6HF3fxSHxqFv z`=8O;h6>=Cr;5i%)Je+5G;SjLprxp3gI>MubMtwAa}Clngd^0GAd%Z^<^g85ZIcBc zEDUM>#+k0;{WDQ^j@xARsRcDcjjNq@(bfMdjal@gbdWB6$C?AdtDbwc|P% zQy8eyb&pd$U4N;p*PgAm$-fKE*jdmxJ{sVscK4N>g}3=parFu^M*Qysd^3U+A*Q~E z&9g-VAEOWmJ{jl2fE3Cu+Mb)K&Q{-)jp$|9HfeU}_PW(np zcz~74`=wLA*ebB!&;2~^)<+5J2j*`tg)0&JLrKj8^fZVlrFC(7DzCuG)+KklLtY^N zdX2RS&2P3@>v~Zv4L%02HDj_L!S(JTdg++j0d4DXa)k$KSbTO8vy8y|2RqPFxv9RMbL}1l`4z zOD#m>EB}&I8_hkhYhTS#;*qGhTvGTvKQpk;s~okl5d+$N1^;SbU~L8n#MlM8u&Jl3 z8lt>B@tGg;97Gn>_}J}6eD%uvLFHq&xCndRe$Pf0Z50K${LczqJ)DMy5KhttbB;d+ z1TfZ`TDF#k&akEj>WqtbmJT*F3I}>NH+F&9hLr7~#aBk+?rCApl$=Ms_W=@yPtrZt z=NC5SH7)+wgMXRne}U{{8Y7;gApNaeg-$C_M=|{?OE)+|3FaB;{E^O&xgQ>NV}9g` zLF;A&lDCJb86HcXE+3*5u z+Lku2uE3r*CM)!C9`p%hV`4Rd38^^`sT_M{ZGy1CaLOVwfUc}rk9%!p; zny}W=?5KVwsRmF{D>5R0a}PB59}`%ee=eFYO)|3YK}m?C<{7hY#oL4Tu4fL{^1x{9 z{lGtAlFw}h(b{n_dz({^>=ZXMm~xi};uU`B*amO1iUG z@l#XgPp#~n6VJu~nt>TB);@YV0W_T9SiDN>m@#=V4zo zpj7c!!|AaB3=oY#1_4Y{am;?@6a9Clj_3=!l^4LryG-rJ2W^8DNyugGMNu5mZaMG2 zm*rWWXg5!0CnwFtm1c(>DyXB1_P*QSa2Y{|tmB5%je1wZXE%ic6sRi;OCGL+>JN#_ ze>WmQEzF_VqVu9Cl)&R+(l6V!wz{~3T|U0n|M<2A;+Q)!?ol(iv+ox*nsT)XQ;{0= zWF{aU5+#pt%*FXJ57(N|E+*dC8$+ANM+@k#V`i~NUQ!{Q>E{?ABkd2KA#QgD_(T;o zEheHy7MzHiXzin)IOqJU!Eeuj%QQX(KEAI?L`Ex3|PQTvt<; zCHR-gT=1BMZO3*!WjiO1EtonCXC588&*nf2#N2`O!*KT;BA3$1w4Qd*?+HgjYm*Qh zl)x71oV%d$NuyGfcyBTcDfW1fMfN2%gBF+z^P`q-OI-&$Bv1kho=OQbzod4GM%s_m z@F!vAR@JDrKnSN>Q7)AI8rT_Io)=w@^V6>Lon=Hd``r-Os6ISu8w1H)5WZYZY8J3c z70@ISO=Klu|H4HnZL}-aIccbYATy&vCE%Fof9#-PQvyV)q4LkrVfglF^ftK$e5Q0D z3vRrz7ugT=zFVWY#PjCQuop&y*c z7?#J>Lb@Q+cK9@)w`10yCD7LnAyC4~vV43m56iCk%x$QTdmId8SP<+;WIOHiYmcbO- z(fQZ4a~jta$CWQRJb0PP1t zIAU4@WVeE6UCH6JziVrq0S3Cw-oJE>p*b=SPb&mO@JMFcG|LzsZ-#fx;7FYtAd(+D z9LB-!S+Fn`)s*6NtC1AzzI+joZ+(;9Qy_bQ{>zA=HN4^tw1D`Vt{a{Z`Bv z$jX+$(xAdoaOYr$5TQ(@-j`UuuiyUGHl^ztg3F1*0!bi8DnK={o(#8u%&F{4s8c;W z?fj5DfL#o8JJY&@pc>-tBQiX_&n-Dl#D@UZJA4K&j=rd_cqGcHzD7EPgs8Kh}k z`+VQT>O8zu7wqPXykT!|A|GP%sHD6AF64R6qXeY)uTu7kgPX(9kLX$4?Z)A&;(B>t zA>Y9es(o;5jE0MUdqWl`ziL7~|CA}1(24@F6WA=dbzyi$uX@A}r9b{3_&h~}bwcN& zd{;(G<21xfEj)!fxEgDmdtbSA)V)|z8e8)qO|5`olmwi(&#+z63D8Ws?-=6msSy2eyT{e;df9M{ zQ{fB0Y^{CjVQkSPb!bh4Ko}Ii@$ULN8;41#0U=>dO?;k={DMD;pjbOi17e$QyJcp)?IvjtzCq>Y!ELIhJ zJu4v~DRmG^HID!$$A^4_h<9MA2W9knm~uc3nTcTyi@I+Nop>-1q-g3}npInkZDM5# zrQM6)`k}eN!19B$N@|#R#?-*@+iL8Ksi30PED-yV_VMI#Lmvud`qdW<@OL)p9tkb; z1G}y>kT;a~JLSs{KG3dg?(7GPK28H^l4%j=Tm84K^yZGcGzBets*~F-L|)S(87b z&iJs_g~uE4IGR{&tu6U`y1KfuNDDjEdR*AaWu$X1<{6!jMR%VeA{}#IS*Of*(#TJ~ zA+8T~`pZ!8ES)|c5prt7wJY{IL>}Cg6?SLiUUS^xlB3?RYV`VMY+>qEdS3q(&`Vg$IlHixCKOd709NAR=6n#sdXD`|?TK)RNVhhf(6+dh!H zOVn~iJ8{Z!q%09=Ba`$%7HWX@2mi7e6Z-}Ae^-54HN_Yzqx1qCnao_f=XOnR@#$s5Gj`Po@~2V9F~(n`b;1gh1 z8&O5s&)2T`d;%0v?#R_Pv#y-D8}fvh(mj97I5aY|8h6IWX^hD0T`u{NBHmQasvoqA z&^DV38r{)KUZrseWMPl6+|5Sfw~yOm`l9ZYy7t5=VHS|clt749IoAl(Tbn^V2KWK{ zC90MF`S#bb>4+=mO(K2m4AAM^nuH5aIit4-?VyEU`-!KLfF>E9>xd%Goz39mqa!}T zHaQV7b1%P$rGxqrgn_^mK`_%hE9@!duN$T#HM9G|v z4inV+NQoQ7Tp3wVj(6I8P~?U?~3;1OKkwd7QU5E$2gEXkBsO0%SM{ z===G-{KoV`{cq?RTR!W4+rMTeUhspYIUw^Hj(Af-6`P z@6&nGs+K9#rpQuLf!Meo?xkcrdF_alSvj9(t8bfdO)bj7_Bgs09q zrDmc8KEd8d{2pM2+j> z$}JRre)mhjg_|ErO-hT16v!r|##Rb$2Ui<@FeawmoS|1{x=_ ziV6YvpVE{m8-6j$SE*`i6KKXc{ks#?j^(~>pY;Bg8UKAHhZ}Ph?@ri+5IEmssS5~h zc*fV;aiRl)u5Uy7G&XL*Gi8R|?^+V=vFT`sKgid%>x1$7}ktmR$-t&zKUd+Bw8wpWnW2*W`)q3|fICrxA>J zaL5P%*g#R-X)8W-yQkEWtO;TDCp6VO^W89I@BHjF?q9WPBn!XDYpt9BrW{RqifW2bVWXsgL@})MX?fj5RTPdRCcSw|TD^rDbU&3Azf~W03iiQgW2B`b`N=h_bhWF}1u2dq z|2@&-Oi0kGTnwGa3DK&1kp!7T5G`$Gsi5(Jm4xoS(tFm}rq>CL5obARdL~$OKGkIa z5Pv1Oi4Wk{`30N#M}<>LRcuyUYy49*R-DqqdD%=>Zce~{+${Oa#PMLof~20O^KNwl z%wA>5#<9!iv*2to7eHBfOs=O^tL36|$!Umz=V~9C-Uq51>E=Qd<$~gqd*1P>r(47{ zFSGM4H>#>48n%sdy?~0zsj+u9nwiyydjRce6pnCzDWqTlxRY zd$pcVMU`shJy(3q3H#?_!zrNTihUN6u)=C@=@ZA0{UpaXjZ$=}Vj z+!?l~3Q?R~%G{z7zuRg7FRhi~v<;0B`vnRHnbzYb)&LiWNpdJ&gOGF0x#pkwz0cox zb4NV`@($B4!Q;j0o<`~%$$vyUWJ!mw313(670PbyjrkS8*Zp<`0jUVddc-;8kma|3 zs)L^m^6ri7oQ`eohuGh*3+d!Bkcad5(~D__xF!w``b%qJY)$2>L?GHFH_R#r$3zBK zh74X-lKGm#{U6V(F#GGg6bbi#D=cRwp)XBllB}CW>qgUHY;DGB92^frFlo|emB%Dw&<}RzM=B;>q`S6WWfsQBLpVlB1WVT1nBUU zEggEG8i)@OuRei%NmoNR)=W%2ryCD*)`k5^;EDgKmA%>@=EKE`j6 zx5*Hg=apB#s9XIdIU$`sN`XqZTs{+6aw_l=F`3aBaYcwWx;KZ30D1BC@YYRD=){RJ zl&|%vp~}(J>ch5bkQ377(01IxubRkJ^(}~xPf95Q^O(vmT4Zzy*2u^Eo9w-RqMoQu zx1vrsNPA{VmRL;e(Vs}lSlO}*)gV#N)PO>4?hS+zfE_Iz_06GT!KbhHw78K$no&T) z#7WlyMVdYA(nl@fb7~PpVSP2nlgVyTg_9rT(F;$^WdC3)bRitH27ZT}B_HQReI6s< zvOdVJkDZIq*;b!)@Pz8JnALsn?>x3?kaUOxm0qrUnb2AVe%+9z^eHUOqL0ujcn&l~8bK`^NuUKUlPcj#t}M$^c*VR6or<8~u@YS+KVykn-Q6iF6@Xgw^Kgn6D~ z%Rj}E^=Y5JD&@m@kG&gF1f_tfO7W*I=USsKVBQY*aVM{3V7q1OHag#BXzdN_W;ft}ZvajJc>9*kL2w>ah6{`b!1&BE2QS zP3zJ`NYUg*txErW?}NRC_P64_Zoyl`{zwc3C=A2$v#ZsmLY%N8A+T|Wt1314TjizA zr4za_n2Hx~(??N#A9v)--8L5@wMg5CEDd2~+uZG-QppDcVJf3>u^qS3k9~)St0`g2 zA2jMi(sX4Bx4GmK1IJCjnGoF5bT#H3i~B)+th48!kY*(!gpBO{Kbp?{k;(u4<8uf} znnSf}ITf`+mXtZisE{&;auzvcAr=|tP}E2kIgA$NRA_`|kz-+KCdEdp@y=l+M#C_N z@BR7VyT5?#e!cGNdS2J_@pPyUHcbB>bDKN~j1-LaAW22FU~}G?z${7>H~GMTgR%;^ zjRt)*(x`225KWst>}|HB+S8m8iKO$9Ctw<2^K7C9O{M~_}AcWe;@y|2Mt<>=o%%e4`-n#q!|O=@&_KE zXDPce>6ZP`%O=j6R z5}A1@N;JUx=>_ft1rGB+oX{%`VD!d48w@lwKa+APSQ!(v zmY@9)_WWDQrn}B^xyy@SYsQGJoCP`J+X{DjOF`H0zn4h9s5EFb@9Zm%5Nw{Nue`u2 z!zdNNO3$AmOX`Xvl5|Qz006lMQ60p^+C4HS2Wt$`I~U#`F;OBE-gsP?U+i-CwWR+K zI4X73YnvUP0MN`S2pd1Is?391cSJ$$}A>-^&ulBJD zJs=lg7KI!FpwQ2f&K!{X9y8Il9dUA$saImAsXOBBcFo_4*M1)DVQZ-+ad+C3G0yU8 zU0yqA8+xgSa!%4t1ZAg$L;q?@L?Dl96evh@J6{ryD?;awBj1igLvKW*@^cI9s$E<6?@A56!P1HDAWVk3?S_T6s`A$d}>xg zn&ot4{gg20#T6Lg{Jg^CbU*)ReS`}W@fDn*_dXBT#t6YxQjCk@7Kj z!sD(iF)KA|gp8U@T-h3-cD=Ys_cXgL%WnJKLv01hB$*bf( z#9hz}eRc7K7#CmZ1P1n05u&W8A3zuO@)yM=#~jbI{18es=Y5afyj?vodilg@1?ht+ zVq$gdday2WeN2h_pOI`)U4d-EMdZ(+X!F*I4WoYb0PrRF!9GqD`U0P58PuymCX^@ z$z6{Rf+9|f?VH0L&m$5~5S2T=hhOj|9vryCc*5+jOBCZ7MSHo8_eeO*lKXa^Zv_$} zM#4x8(mNwgA#3Q*P!r$x=~MaL_Aw^aBX!EO5!Z2e)%enwzV(B=Py~qYb}!x$|GfD;_$K4R--x6HmVGmyvNCWB^~@SZ|0$G$xXx-sdt|$q zOBEBC(PlUI$=`7H3Fln7+2=Sh6fKu=06YNk_4x8Ow=V5+1|y(6i(rWt-%TpSx-<1ojFWMTY@a=66a~ zB}Kk2?>?rj#j}|e=Bd?nM!<)cac;TnTY9x872*~kFN|_8GCL~Ulscv8Bg5xs_(CE; zYF*PHD`kZ}hA*-dz+s;ILGPK?E{>Onm=T9xSY{!c35aA*x851Q(VQ$A1Tt_x^x6x% zKM5SHsioCelgN8l3#n&yt-$2bc)deSkb6jBPPj5I6qIUK3-;@P_5`%v-}Nb$6p&U< zm5YTSIndpxn%aF1#}UtO;q^0SWpA9Zh8-|#1B?Dsk_k$l`47xf{Kz-b9wiz4&I}W55gVVYg_bwM(N2 zki|(LOtUEjotBXtzrD#K`t;s%$t5XB@CL{+?bErG3H6-J*gL{a|FSRnzS5^o-P5_R zumWV>tAH*c&pUcB!#|SY$(!|BvqcqxT)+=HlC#;8=K{O+E5|)E-wOF?>?^nQHZ}NH zxb=S(5$u(xqD7;jZYR`p-&fgKt0L*@S~fco(H(wXQxeCy@<-P3pP=T)Z7!*cd?-~E z+bxodyOEP1GGKUT`fIUUj=aOcB3S38>l-s#d|#P6AyX$+B_tPSu0?K5#$BWIaO~g& zyV?4BW=c2q(X@!W?LddQwCY3P6&7Pu0P8y7or^m70th9=^ouig&i-6iaDZXc!d|d! zqr(|o5;DSdM|cnJu4xZ7E@bD=pF?&k^R=34wVHn6*%ocYB7wjLiT5blcdfcq80wi_JelY6G??dshp3A<$Y&jXeU;&Sr$_5iO;d5vPR8L znX-8n_5vluSnH*VzrvfwqxH^nd6H46?9UKP>8 zDuyGR{Z)Mqns=~<;3~TM3F9ubmq6+Td3jvl@;$S+!~g5CylTM+=l6(cVHO&!@ zgxI0mG));IaLEo1+O~$Wb*UgcB&VifVBPoQ~;_qUZetv6+oyd#NJ;QmjJ=oTt^}(F^se+-+(QR&gyl~z5bTp5Oo5M|H zr38BH*F#4f%x=S856_Qa(}^(gpMqwlG(!^UzZDg)4KP&7J;mhO+Z#0rTse!EJy8zm zVnCK7e<>Ut4R~MhW?tBP6t{Fh){YKD{9I7pTweAIsSDUMPhvBdqm)DjVoY7`D>bLC zaD3Ak!ttmsB1s_kph5yEqwi&s&@b@qm8C|I$=Re7zXkm&jMv${H-^A>>Jjh`=8yUi z!uT4{1a|MlPe*v{EKYrh2gGQ#fd$S3oZ9}WSwohXuKDaN+gPmxVtoBD&SzzdW(sUL z_XDz<`RTwe?__w_#&^Uch&jH{tX#40Hk(QM#IDywl&A93ldGAgRkMicpxwI}0)?g= z_aHL-D3>I5u0J2)saqG};iR7Q0T5&#>d{E|#oSrTF>iX`2z4Vqi zoXhDP5{sQL5M>y0%{xYPQ!m^hnqeHbu^hnb8jEAuWWKS)7o0>rw_`ia%( zQ_oz6ByjHi@k;%6KL~b6xOl|MWTbFqB?p|V*fzGjY=Td(t9Zb#pyJ}8$B2`eW%AX8 z|Bg&SVrCJ3`xp%`1(=h%at}_ViZ~G+g%BGU{CC9A%-e26zX$`BTA^bj)9u5>mXh%L z567B!!5N|L!N8mjZuw^rTLPKNkL}6J3%7poX5!yg6z~|7zBg&Yh-}tt(}5GCP~5F% zYQphNy{5c#04sbrd>Aj93u}Zp#2k=piSY*HCt& z9Ol@cX2YRe7Hizdr`P|4+No1ic%V+*o%9g|I>1c>HG0MDk?L=OG7oqT{#!G`q{CnD z6kI~sE5oexKI7+t80XQxzhfLDTyoBfiCeo6XO7{NngoFACGiC3maQc*aehi=GHO&% zxdP*z5p!}0FDI9h()sSW>PdsH=M;Q)s$-NvD?L(ob$*!fLfK`qS*r@G3GGMn%PR~P z=uiipci63$f*=Ef@_&tFO1(Vh(2=NW5M&_n+|`INk!tQcf&WX5nO?M9nY#dG4`TDWfP|_tPS!ZY6Ae^aQ%zs9` zR_z&nW(VI6X%yuYAxnRt8;F}woE@?a9!cG@)fC}|P&XGBZ4m{uJOIGOx)Oe3655XC zZM;opV1dbb4%nPASxtDqo$`ldUH~MFk0TBb719qoaoz2(N`pZLY&{>(`n?z^nZRsM ztax=#wbb5CyTL;X7~TvVfxm_XF4U6A&P&HnD14%XetZMAPn%hbrE3jCvsT(M2M}S# zbeS>pHqJ*pu*tsBqqWGHbjNo=CZPIUhg9HKsbQu&kMly%kN& z@yqLNSKsfGe=1rg(J4t!;w~pU(>IOAcR?v>!aC}hdR%3K@92Kj2&ItOEhAYBkmFu!Eco9b^qHiZ4B>G_-V^A99q{&%{olnLA>m7L6W@2|u4As^;w9H2Tu=r20$UucxTwiLqt@e$-Uy&!Uj# z`&GY?tEd#iMRhaUA!m&5Jfmb_w!|-|;JZ(?Hg%<`j^#K=V;ft7c-vc>hBYhJb>$rj8ta7}`!`?Ncsog=awR(=%O6{a0>drL4F3iN7rc~CGzK=IK z4q=Jjk2r49x3oHoThl8izTKK2`Q5+tH6{N9{@or=r(<@{@+_m+A(R3ePf#1;Wjh1w zAj16`0}v+@9}oxuF1@b3XHsZHIVlB0qMgs{1v-HOyT3l6#69 z(f5vgYxm#gO1#C028_weF;hzv{yQTBCNMWU1~!BRmuMDc3r_`oh+LFOHBa3{I2NSsHLi zJ8I;M0oP2pyA`I@0Nab7+bFIWJM~=V1v`MVirok7u`J&x>oDSTo9`XX@)b|Oc@f6N zb?sB&SS~dB?(}ZbXFnH4v;lFUQU_0epB3wwi_xA;;w+!%Anv@Im=qF}zhoZcMJ~y5 z9xt@~3aVB(mI84Ng^N2m3^AHcl>%RsYEfwxM^ZOe-L$_l%LxBf2&{8`JfQO|wFAs* zqAyEFkGc|I@&ieCjR^tPSg*(UBuL65!Rq+t_-rn+Qnu)86XHDR(A~YT{)icfW^dQjz|NYA#xabo?o4_f*tkyr4#Mw-s{fx~#k7QH z@jIVIIto##0+TKsNgde)OWy@dr*{zlataJ|{lvh7S^D?yO;x*m0qo&HwA7$5@m?#0+ zaDHoxRCuuc>ZE2yrZWJ!;o8ql=#CgAB*y! zF6&=`A1TV+jP&FNv$y{g&^6V%vSKQgNcpuh1n#m?ey#g8-8xinga>T09Q@q)3-oTV^$@g^gc3t4x6#qtz?}*z86?FWs#*Y#OB_1+?I+-Bp zY`K`2IwsXenwB%VQetCnSNoosgNa^Q2X^9=+ou_EvKsMQ`A8YC1KlbVLvj?w2uX z>w3X`GRxG|l!^k#z8&jbsoazzoC7!x(2w^HR0CQAebpGOs8hWpHtoXcJ|;qA0I)@W;kUFEsp_q_PL4 zt2?pySg=Y_1=hdf0At88F$0+msc(A0%Jb2m-K!5Fa(5+zr--Ua#G*%fh|k^at$3ZO z=p6;8b859*F!W&d%}e-1ypjKB#BaJ0O{Y!q`;fMVY=*nSJt*zq_r1ojPJrO-^|sxF zcN#Y@8$D8eXm%46c<0G_*w5XU6_FiC zo1Ucee=Vcb)y^m!y+Wsir(Gl4EQNWXVUKijqe^zF^fx@cJ`^;EAy=mNSHBi9 za+`z{ToZ2g7lH#B5ftqp@*Z*X64UMVTd5sJ5q+>AeW(7)CwdvTQcS8b+eikDE>2&|CWLjS!|8l{$8Bpb_f|eq@gzd^?DI5 z8h;K8xp>Gzk@2G|b4EVm9qCJT_3M)$i?JUcA!#EKe>NlOh_6rcOiVcKV~zQBGdzLN zwd#u~q1N7M>bP2kc^V5l$5ygva@_^Le+g4lbkP=wDE|1%$}7HZUrHW$#49{haGiAxDs)%vf_@GjwV?-s5jvJmS?ZYGWuW+NGc~J!WKXGfPe&hHA2b8CgZ;Aq{CQ;dc0!6+x$kcU$Yb4}POvSIwaQHCu@)5Vkbnd+1NUI^u7=-z)Yy z3uEhVW*c;x8*Ow&s^qwOu+knEl*T8mhnaOCyyls!lm>t6SA;~>tz~|0p4Mm1u}2F= z)pdQ$iVM@A@QWfD1^v(Rs()}eqg~fqO-xfB92%&q)Jp!JkE7~GPAdD*6g0s*Nc+vM zjP2F6TM{@evuLA!)ITokyZUPLy>l)psrgzS$h*sS@IhzcU-%?|=PTG)h%lj|Vk`br zRU*u~o@g~`ecH{J&6p;%ZspJJh`h7jb8vjo$WQC{S67cBUoDM;z9m_kS^I}f_CW@J zAeSpHBlA`pwWp#yxM5H)!iAm@y(JrGse#}`&{+Rjxn5UFJ*szn5m;bRGob0{j;5vr zS(g)J{cSqp8&cOdf|@tlU&S;!;DKu}J@O0OKx`!M5T${`7!8l z{9_YQAPsCPv;8fz{wBE``5{N`8_8GO12dJ?27is%X7S=boOaIv!fxGkBk;z3a5TDk z56?mF4zNV&@#(B(7I7Vl))Mpf**jNU4MSdpx=YS+FI5|NL4e#aI3`r<&Kt_%(x%_) z^ru&ctd!}FZWe8j`*|kHSMHVS)>KcUY$;5=vN!X9f7{0g3Bjn{fBebnc}Sk4)9EYs z$4S54>nK~1rm>fW_go&PK}2}PC68y3&DUIkOMHgTB7f*ZH7!K?nF_`_~u*i88 zY1Pwwl4u!-h|xG|HY~7UitZ3U4oe27*V4duVXAWtB@m~H&CSa!(KbCRnODpl^9go+ zDE0DgpYCQYq^FIUMRSnytWo6wIt(xKkTt?`SbTrY$WD6X#HeyOgs;3$Nle zr4Tzg9P=@L@7pJ9O$MM9M1P%HEo^H`=oKO|kK0`2Uc=weI*bXs#O43-ed1pM@F$Zg zXOhDU$W%&>=e2V$0URp&q|kk8so;E{Ypb6HyphK z_3agP@RluXwG*{1{Xp#d+}vMTF+$E_3R_#Yb!y02Tx|B-DveUdM5jx8H{bJjMXwKQ z-MQ1Z0L3gdlpPcW(jes_#U^YE)^U2OI`!K0?hvFA*kw4S9d@PicJuu~}io@SvzyShmREMbN;`mpcWgzA<@b#xhyS}o`l6+0C{->V~Ry%O>B?*Hb zcdB8GR4XASQC&82``Z5oj}F+jKfTjnc_pl>;qH@$-nlI<>(mZl{X@+dt?<3Ben*9O zFu*+bA_QCv>j`q$+E~7o0HDYKz4MJR+QZwnU8;bkcUyG_@-5~)XJ`!jqHC4UuX{4W zJ@XERijg!w=Pp~b%_Eq82@{U!W9itF=!X$ZBp@!6aIHVj*;q%V5)KN8tmj|Po_5oqK7$G%3h$+iK((4f$lQ8VSZW>o0mFQXYma4lpd+a`6ux0aWO zxL}>5LCvZ@Ue(hRKiJBq+o=28h_!#Hua3+7ShfGgvB0+8c%({gK30nzeNL=Z5yP-~ z&#ZSu*#*BhXq3FvNRa~rNN7N=my@BnSFFT3>mDg%emt%(^KW)>&<~Cj3#1&mU$J>a zJ>qg|MRa&NF+We))vN!Q8sNqqsAfLB#c<)?X&=OT%Atp7L9li#< zBPvC&_qc3XDR(G(j6ZV-@?GH=m%K>%4zSN^5f~SF1I?31bWM13d@ge$PhlQBC9Qm60<(+6n4{CK25= zUuI$==Xle_w?~@wRFe=^OE%PI{daZ$UU!v)qGtTV%N8Y)fdt zO7om>d~ui>{G_JzOq-Q5yTG`1gC+>wY^>KBt-os+=_KTBk1AtkM!K+`zG=a1_shE6 zY1|U06(>9kELs7uh*YIk(am^v{rj687q_?Ogx{7|gI=yid3rCcE&uOR9l!Y)AC0b< zdOQ!l|8}o_37O=zXU~33p_O;SMe*&$QInRrd;LeY$EyqPZxps}>rJVF{5Sa3g|wDx zbxa@en{%&|A!vf+g^bseRqe#%8jz*jf9-2T=$CUf^v>{(sm zYSd``2kw&T_9`=Gb1{x*5w{)vUT^R8VpHsS;o{;xQ8836mi@&w(FOtQ!AbI5&!-qWXHgrj`<}yW4b;U||e75gL)a>^o{ML%w2uvt;%U zJ}E)MncV~b+wk;}gW9)IiwOVx>a}6DhvdI%kwdz76f^8;n{n|4+_=AFN^NMZGn&O_ zH&c`p0D_8?lvE8t_50JnQC+nHLL~v{gw*8mzu1j)mg264omnX@xF#IV*y*oOAfWLT zoy>pKtDSb}!KD9?kW-U?*|-1tXDJJ5IYrQUN1GD_E{6SB)8gM_=Md_+(QN%O$wsi8 zZ%z>V`S@bkzdq+v+gfe7zV>L>F)D;-{Y*h{)1Zr z5|j0?zpdMgC)GJr9|?-!Vu?Q?Kse{6T+38EfSzNYWuY>je(Ns;W(^@^L8!9wHrNCI z8C#GjR{Ab`ZtX+d#;Rv^kazm&k^0>`tN7s#GU-p`21g&<4UE= zu_l7x&++k1j}!&CLYv+exjM|x7@lpxMbA(gu#wnS4fS=|B}aVFEp9<5++pUgR9xyf zMMBWv*SuG(Z;pog$|^{~rm}F+<0(c7*MZ*ZgKa3=nmj%iCoo+cXA9Si&U!-s@H$#{>6b_cVGf#ez6 zPc_br8JbW_$M{E}=g!Iyp$0kxyDM;X-Z0?>&J$+~*R8BR{v#WesZJFx(s=PxSsW9N z+#H|3DE-4PA1xPV4VeD^(&WtbSN_cjg@y4Od(ERv0GyM^h~MS7j_L;dfq}2@s4H8G z=aI#FV#nF_%ti)Z|E&4Xl@|vvwiWA}n*d>CL(j78I&bf8WGASA@cNBDBr%T}JJ+^3 zdkS`_Ey6=Eeq0@XL&kkYRH~U!xnj&UjoT7Mo;%2N9XP|A+>DH3#r(Vnwn3D?sfMH+ zu+11Yvyj5AWXeO-7W+-()78mTcy51^T#6V_$0RMZZd_?44`keWJ7lTMbwC2$uldov zyAmN`qxX(1vHlL=r?Kdb?EB%z4EVN#f0f?g7DDSl5pqEj;`io1jqJmgLLJ zjo~NejgPBSO{_1Scx>TV2ehoFEx?#N>5Sj~idK97#!#Wtsa7wKPgxht=;tQ0!^)~#7UWt&I@jORVB(#R9P;f!WrzL%qE z4)tAI%)*#=xXzNE5slu6i0Iz|BtFx@yO$e)I63t${YP(7LdAV1IJ7V*{;ONRI$7PO z%l#zx47V4Sm(M@X&4RcLp`@_=-c};$S^QP&H9nygb&2CSTnjBauo{6+z+Bed4etUE zo=KW^ne|6sMw0<;F^qn|cOkDJH3#+8P}jv9B+(H&q&xXDI-uz6dYEa4Vv1w%W4Y{y zjDfD4y42{#*Z4F2lo$Nt&#ABMPO5*ZV`>Fsb{~~hecM24cR}+BgcQ6*n$aW3aoxp} zktaZ(fGF{povI+8%H{D*+>&;M&CzD_N8h;Bk1BAnG0!n%N;>X2Ci_tE>DC-LHDDRw_9IO?#j!u&SC4P4P$8W-~tu=)+YW>MW+$+jF_Vq0{ zOQ-D8I3rOaUiH524PxGOX_JFng;mB~tsNhJrT=hEA5hGhwm+*Pn%v;;9fJFycrpnO zTu7icD5__Q_Vwhjf?WGEQttB}Ib%q-NEzq-mO|88kbGW0KrskmPfeIPjR;;K(wM$< zwJ$wY>H!zz35d40g!GPr*r^4Jd%!(6W-!jgC?E@2BO8{H3zwI$xI z0<;oaz#8hH(|x3r@cjPvbL)834Sqoh$*odY@AW!hM|Vpo2;%dT;Kticw^F`V$!-~P z?lZIWNozi<^AR8pE%zb>Kjgr9<}$N9`e85YU!jsJ6Ir`ol`KV>xE1>UpgFpf-u7k! zfoj2{j}iA26Liw_!nIF@LPbFzWQO6_Xkk$r`H9BLSHwJg8I&%FR2C)`{xg)iV7_f% z`NDiP+Qj`-aZs6t_Jx}OjD7R%YfKek9D*BUg1k@q(GkCj6wF7g$$eh_PW++42xCF8 za`BGzg5cjT9|Xr_BzZ_(relD#yDxqYv|NE5UFyz@T(0+O7aq?fAp+z?bdTQjfj7(v zu>}Gul@oK(ekwd076x`n(x*w&9VUm*xg7NMo&tm)Ingm!M&hI3lW03Lm82{Tug-Jm z5!de|)SL(S{No4}U0MD7JRgH<{;*)=5G|@8H@++pyK=+ZZNx29$;c!(CKywFq|EGM z$8>0Ej09s=R9E)z;BsUH=nWOtgG{{bcx7V^BKXb@+f*pA2pD-m2PZ& zYri_Ili65Ns#smw()`P`RVisKSY5Xo0cdazQWPp&16~-gX}Iu(`Hl3ODu~^VLI;DN z;Y*>H`yN@4mr2jOo{@L!dKJQTVaG-1*(>_3^_zjsa~T^~keWkvAT))fY<=(&h(3GJp#k_W5B*?OkbP`dpUUnyMCcf-*A`9>_@wS27l zzS2bLij{V0ljBYHl=KXo+Y;Q`VnWzlpzyJtcHyaTD_LRv6NG7NOSm<|9jBV*18sgy z?D~tOtE#*Tcrx$DKXe9s2qG_80z;E$lxPM&f(IUnB)f5s3{}wg|JVE&7jR@zoCR8w)h5_J=X+G;(>LRv)HaCsQ6oGRm za`wvAW&M_4e*O&v#IrcqIxutUd|Qkm?N1zTGHFt(^nnT9f5+_g(=X><9otr2Kjz6@ zqmDmw>~oa+N?F~gt=2lK=p?@M;U6*cnofK1b<6Fw1R`Xo@yU-JY862TQMV~Qt`l{X z)@n1K^*OK6Q4Y|3Z|LQ`AY7=V+-AF)C!w{jSS~>F;9UDiU5_Glu8H9hPN={n=EMOJ zQ)L24muMyHD_i)tvkf$i?ni{W$-<45_So4E1%;+vUuk9m9=w)py#U*praw?$(@6Wx z#c`Tf{6-=OT7)klbG`bl`21=49U70a-nxT&H)0->Kb!WO}^gONCBA5EVd;{;$^O6Ms>3 z6*@DmW^poQ-rfbC*a9w_9m5-{ewuKG<@5Uopiw*Midl4U`FS?CC@DbsNCOPI^?_IfU-_R8wlk+hN=Ue+3Uv8Q7~AOy z*rr!$kETEQ$+hRxaFwF6-^e}Z7G7s55r7^^86ADGu=?AStA=?8JiuWQ84(MN?DJU$!XGK^`wFBhta45N&5<+DU1zBIR{M9su zhM7uW(*Jz2&Gt0~RGw2Q;7hC^@@taJ-{ExTbHL)~kP0{f{n*i=^J9_;1G66HD#Us=UszISNw+1tDj3@HXS~<q1)uc3iYoAZ zGqWopYnN&t1sa{@5N`6*IrZL>Z6FBU*PS84%rt3ag~B>2nE(>@wv(lg)HSqQugSU; z)LNVVHWe0u4^znk%5h zxB-;#22eFpy!IZSB!cOkacO5PLxi#k94j$16%8?#@Q$~`Aq+Ad?swJV%vEpMveYur z($>n>a#WdOM9Lns*b3eCY22H@vDMgu<%*=?!!I=(nK!4pRcSiwOY&~H2@qnR3FJ=S zEgL@>@vrJEKJxpz(Sfj~u7rO6&7)50N9~s-Wo$)0)Y~Q1?J2wSf|dV`yYxHbsiUXW zb*peaZ}0i$m@#i}C0|au1u}>nN{tEb<9%r@)Q-;943f~Nfy9wn>hsS)x}gmu)R&}D zllg64{Pq=%Kf$ZPxS=n(eSsmFDg^H(joWGG@lqOUX-&bFIR)1|0OidApQNd_1u`@t zGwUbK@xuD@>i|g5wfc*$;*pvd5NDJV)I8-H_#yOT`RRc-rz9PFvFV7IBW4*lyrqaJ z*V=lLLwbSo)#};EpH2G*N;~cvUpc1x!R=uN)76V`%42qOF1Ru1-lfVRq}-j$DS*Co zSTw;FZKt*(^_b+#(|t5}K@ub$lc+TaUWhGF+m#rjZ2K3PtN0ABkNy1drjFATN+Y0?Nek&+rb#@l>rIhujDDaeUWBxV;=!l-@ zAD63YsIN6{El9xoU;Hq2G#S1g*jzFgbh!D8`+Th4kS9BEwBt?(B5h{GeH@)43Z1RB)t)^S4fBpnWX$QW4)Y=3H$LfH zf_G-EjO(Y1rL5rkXDmV2)dWIDM@TUsU`eTR70p+-HYL?oIOb9ubXgWirY)WQ>IB(2 zPZR|6GjIB{#tvtUgLy+V|MWS92B&<6byP>zqPosCAwLzszyBh2vT(J z91KaVjt-dlbWAN3m~|Ik)2bPaOmr>$WoCgd`hzM{)J<4B6j+hibbtUCcagWah~Q?S ztgi)UJeUqQ6HyCcpLM-Av`sc(NUMl*NXI6`REk?jFru^u!O;oN(vtwi?R5yy(J;-iu@bbUa_T6PYw0BzS*{b}U6oRp$|I z^cPm+L|Js}ucl{F8Mpg#q@I1g6_z$Lex7Hy@sA_;MF%bNXJ_M}1U?C!<1QLD3s5tN z-v`4PH+80<%>mUO`b%)f%U!WG>KSy+&abYQRr?y~cfVlM7)Z3X9$r17I>uPKE-0|nE0$AC=1?^ITT~Y>QXNKqDCL#n_hOb(z zA7w)t)1KZfPj~`v(@dUzs|WHfp(N#XU9YI4v}8X?F}iroQa@?75tuT?GXH3#;=bTy z?y1~{af!yy8YpLJjufETA^aArD}TZ2Nd#h7R#qa147h5d*?L_+9j4mQcHoo@OT|3L zzHD>kQdp}1esjj%fhj6>j2jHU?4l6~jY03u0JT>(H|$H`tguOS6Y>^;&2wx!WWhXO zJ%CAn^kwf7o(tqTwC9lRzctP1R@f8>Pa&Aa>ZP zACtxP>9J~fAs#Q#b8feA6Hqx=*P!b?f_G(h_k+r*mQYqiDcB~BqG!c`-#-Di@-bf$ zUg@+fUx|#5Azcwig7(j1x5sRx3(M9Ob5kr*F*2ZRJqH=;=2cwAp!JxPkQq2$Vm z(eFw4z>}T!^4l_0AT`TDyYw%cvkj}wLw^is@OZp}^@-M_mZMID%vyXJN6a2g&T>aD z|I2@h%)v|e?|p&k0Lyt-0qrKsl~dMw-x_ZzJ{Y^YWOPOMyE-}IDw>>l@Zfu(9{05~ zC;F;9ZSC~V!N7+GxcQ${-vmmL%%fsXmR(d$XpitXA&M{Fol7)UKK8P2=09Um3H+O~ zj1QFho7wK5vBoM=-Iw&BVE?mSHf>O#xt39_=d7|f&vqfpz-w#)LD{rrbCwzkuc_Ev zoqM4W8p8>7`-y_BMHwFdzF2=aR5&*tCH(M+ZVDv9r;EP9+F&1#Zg0*-j_S0>-8_$t zX?@T>Hyj8ss{kDzMGM2Q;66;)6?O89)_SUbIsC#-J>r4~3bhySJH;qS_a zoC)J!DJuZR{t}!y+c+oWuWblITgmD&8nup-anJ(yR-U1x#Dn77X~Q%;z1CmZ!m+;T z3n{I=&9%8Jzw|a8`jo-lnXvIGz{?G0@_Dh%PR%DBosyWH8N-Vi>E4;=9oL(cwNkrQ zELIj|1?;6L9y!R2%&vW60wBKQw)p~IQ{e7SN+IA{mHH7=`E^B9F*7&U!+C1$FmG#nRk9jok|(wMaDxg)-g~z1*`%+O?{4!Pby~~E zVGm|16jDP_O8ND>tSDv#T?s?BhFR*VkSSo*J5h!q5+81^E%iJO)U`-Z&oprHB&G!Uf#LQD} z^_+Gvzx!exDkjo4CKS5aj(i^zdvvy|X0PsSu~?BvnIiaWb`6;#uK==hK@uIbVUz(( z8eBck!6{D+ui}#i19uYtI9clHPzNwD^)jtoj?lB$xt=4W31fJli=Ps|>b`5EXXMAg z)B{47AU)41#foaKzts#E-h9c#kgI&}XQ4tr)07e$1T){a{&Rshw~mJPyE=I`I@q5V z7r(pjq==GmUcW|t*I=y7bRey#H?n<~3x=3O))DXaO1^c<^hRWqQkAj>CNOX#FPkMWUEo-f`7#*HKf> z`B#*O5>nC3e0@zhhcBuOIO+1#@R4&Vs`tIxY?wJVp?&o9TH}8HFai94p6w8xWEqNE z0)%P-zY&$DQB)mN)(IfB^&`!L$X$@j?Y5gUsP9mIT>(Oaid89UZK~1?vkSV^>4-bW zwLK1miC64Ora!%tE@y75s-HB}pk)SnNoCJ1#%7VWlx~W?dYv%rR6P)r1`~JI+u@V} z2^>9Vrjj1yodAUASp0Tn=VMGGU809rpIVm7G^#og=srZev678?^3sQbpg%Iz{j|De z4V%HYx7}u+;gMNX(ry`0y{|BIdvP&tLLl7YjmG_T+gMy|$$g)@y2++_{w5IIF2!bT zY;MjC|D(-C8rH{euR4dPBZWBt9BG>nzll#XZNW`|i3>m=Es!=e*K)z?`8rTx@j|lf zT@X(-Z;?|{??r_IBNW`yyjUq*LM@HcmIZP{yTO`=ns0L>st{_J;Qea%d!e|#^GOsY z^b^)Z%?lx0LA37U~LZ7qSa?5kFx~9v1Tw3aw3Z$Ij+K-ZrmbJqe+uL_Rob8%KQ)HYBhgqwd6(iNv^f#lAGPcbKmZx0aj#)7V0>Z!Zn9#){AO4id59prR8*wH1E2t{T( z_!NyCQ_b(LpTl3BrA*$Q&A!G}GqyrybSHwTT3)QZ`V(2r{-oNb-yEAf4ESnVSij%f z24n~=LqBT%yv(I#OXdnp4OBvOJoE6ShMPA0j`ZSUR0%OWwf_CY>DNul=bRoxtr@jt z_@lC?8V(ph!%Zfpd%0 zC>}5?9pTE>6l9+COymtQug+fw+|?E;xF-i!kRANdsaWssIt!B+SPqNVt<&1C>z&ka z^!1rv`_U^~D^?Ty{%lP2$I;e;ep05zTT;jerg;LyWjB3)5v~KmBxL|HGHw)iv8n>0 z;cyuS9HHTR$FwS4dT#YO)&G+pWk&vGL%;hv*z_ho5Xs7l-TE2*G5An)mBPhTI9E}B ziDNxt!r{c>aH3{*4IL$FjsAG31s(PPrb=t8i2iGMr1u*tHUHK5R9MMHf7^}7Rxyyu zyx$?rhd_ruRBBl*^89Y8YNi;iVV_7vxBXf13o0(!*fhjL+J$otPgLjqfd41}G~TMf zJiNmUMA1`=j*mIytJdy*vhkMw(YPQ4|F7n z^zSjL;IS`JO;UHEuT*3S-Uiyq`Vs__>O!(B?G6Tp)QupMQrxW_Q6wAJ&=?qo?AyA3 ze}?G0W0yq_UcZ^HiVu>8Clh^Ke|Jif)!lk8PKYdfO9Ww>i?rorWQaY4@9+SbjFh~Q znw@q}&()D{hh*FxKY65&B9oRvBO#FXE|@OJfLYGZ^asFS*B=cJOM~n5Bk=kNREI2-Hfigpy*4q5hZ zKym{hPV4BlV0)P=VCV3SlRhA=dy1sJeP!0&%%uG1o$j&hfMnYhE!Nq=ERg=g%6j8m zxQ1kav>VQ|HO^$Ke|vVjg>h2;@x}BR=YK$bMr@A1<^hZHtTZ@Xkl}7(z>;?Ybtlde zp;Ei$M0UFIwzLm;OTT(jUWQ+7nd43)y3F1Wu0wZhLWD< zeRa(34IXtv!^;|yq-gT@pe796hhY5S4?kQj5=uWIQ+!_-t6*RAQa-?tx?f-v4sLJr zUCXJq8&xw~1FSK7C&wIXDLCp5bycsi{66ng3ds9Qc^`19W|PfeNdUL^yrqc90KsDf z1AkY#3w%V<>#?ZlLD8V}OGC_)k~C0QZ{8v9 zmH3}rCiH%Rr^7eZmK?d@`_=M*Mww1I11@Y1fr*(NGUlc|qz3PI@qOYu z8ldd3Po6;u3I*<6WsF^hiGlp-PPmXjz1IqyWdUabaviQxL2Im8h7 zYQ3c7LoiXvG1XQ>h)dSC?IPM|FFCI{Z};2td5Vhf6uzF1z`@@R01#0k^hm|`w|7+y zDLQz$Qv+_&v}BC4ZzQ2>CCxA$kgO!e5y6e&3~ zGZX*(^>eMY6!tBZQkeL0ojE2E>7%EVb4sn%+IvaKRnW)2wKiNmPgWdgu_ggBQO^0SH82eo5KAfc-tV{j zSua9lVlV@8THd-Hdrn1Eet!NUA~2Y;e9pAS8f$F1Fq0X2G@2K?YIcR-mFQIBuNj`!_54Mh>X0ds=KFqdN4BpS9VDVKtAzD@Q3n^4}9bcgd&8HLJF|N zECK9r=jxfht1>e(BHY~$RX(VhM^x{E`7qO6T^ZqShaR7P`svN_e6ordGn<_;R`YqD zHp3_?(=rdCw;3bb?Pgh)5W@L9jYH4QnchXt4KK-=os&{xO8w9?((CaUym!taQZ6Ot z=-4eO8wKHJHvrMF85OXOf{Nf)*MZSCWZ*@aOZ{IzvL}jD;v7j}Q09 zq#3DtCIA-(B zS&DIsT+0(9PIoA--Ih@wh}R&W&+M70-LQY3U>T@D~O{Q!W+ zWyw-jpkqnVvjYShsbiB*tfOXL7HEuZCdwvRSxI zazrLLsVbg*D!DeXh~!cP6jUvyv8&~YyRMt&nVGE})xc7cZ$yjp$kVQHlrnmrt zW!RosLe&GXQO<9QkT&a`Zp=p1JR?7X*3G&nz}s&%)H zvAx@Ee|Ub`^g}EOL;=AuEjf4WO@b@uQdD{$6d;xCiRPHBfQqP|eIIe;EPs1%W*>ryGF)0x>>3yOIrRUP_HRIEkSx)H2}6jY~W z*>ATm=Mw;!U-8~gOPrVUwjW=osdH{Kbkh<=m5>0S55aoOb1t28bBw2XBESOLIhRTq z`(ZN-xd@UTPt(}Ux$r_;$Xmn=xAqKYzhJpmRKDaAP-yi27NDa#W3VK`4` zyVQtKM0dk5EvfIiX_|_tBLajaB|sRv0a3K}ahA<6q?CrPe?A`Ujt3tQ!2}=;PCU=E zW51dv->REPlyVBrdFPfCRlqYVC?afzF-v(lo_imbyo|$GM9$MWIPZM0Mq!JtP{9+6 z3KBWynDZ2u`^_dxv70NZDJN@Yb3}-siq^8(aS((hE%UMj?~QM~#F$HFc1a4T64E#h zhvTbZiG2u0)F(s)wjQbw!s&dDIjL%v()qCI2UR&Q3nAM1$tBxJsCk|gpbMSN8?d;< zJLeq7n80!dti^jHvL?wYVDlnX!TA583JOfPq%?M6N)ZumHp3jVSx!6NMN~z6@XH*D z@I24Xxjy(J+ByGpdiBmNDOur(J&(Jw>-%Yn<2cwry7PJ3?RGIP0JPg}tS?AW2{7dh z3P5TE-M;I^v<#QH-|x<+X&i@Ar%abs#>7Tj0|DM`H-K0`ym!C;^%tS{o6Q)Pbi2Pj zo=%(1=IQ073&9G6oe^BSZZnQ4S$k|hPg9E=Wr@o$j4{QMv-5tL=iPRDJWh!C&0oI% zhd=(shL)||U#m+yB9V)wUQ${;imD=@jV4wEZI{!kcWd*UsxlJ+5mCz7gmKqkf z8+_Qp74!ID{}l<>|77tXHbw&=+RzUh-AAL8J>>?RiCTop7tj;8A8v>wep$9?@hU|+8anpzGI2_LB z6jK)PjKD+yu@qDiErh6w<`+vTL>SmfdvUeVgZ61eOqx?2iBLpLx4|$~W(wX<^U~HZ zTep&k#GD9`5bH7$s}@3FU^fe^s-`cq9XHc5@5asXd}gAUlOi%wF4;6s>|y$@OQ}*EO?f=!WKkv&d1e62 zT99a&sX-6{%N1VM!Sg13N%KLKHwEQE|l1xoMtEV=_2jN=Z^u&i%^g2Vg)| zao$PMB_|7@JLeT4rsRk^?>pZ;pALki0GobT;sQv3kW)%hdLJ06XdUX1N=5+hTrAmM znTS=@7Bd@*&{vfx6E6d8z>K1IB%&4^AtE4xir66soKrHF=p8X}DkT+Z7+W2pAR?V( zQSr_#DHkb@*_81WQHz+}3(lvKO&`jPKo!4Di5(HLs16~3Lht=4Ez1&%h-XH`A@t|@ zYy**U&c&LbN=5|*@$AVEvQmi9sDG{|{g_Mk>a zsss?a5MwfZ2D3|Kd+iK1!;-Vv2L(l>;9RyZ&6$~kqsPbl?afUA1tsU4b8N#hV~kxF zj>jVr5tEbxgxT+wy|ZW(^*ya`#nC~ z>=bm0(R=^ylQ+ZIJwEJXE}`qZV^KIwXU9xPNEA~X`vD1GUJpa)$ukI)oI(hyaGKA9 z?-aBTVOrwQ_pisJQRx`@o3Fn8%lA*m(<^Ar-Kt!Is$q!=;0RJtlY?SnMUkRLAO}SS zwJovUI|a4NP#I-R)`fxuxu^}xG}63x2*5EXtY-*|$?K^yArY#efZE&;6;TDk`iuf< z*VascB0~F<+P0;L1hO^&0oKV7&8=cPyVpOKLs$1EYOz9*!f1kb?f2V3vv+LHy8g+U zPunnBG9g(8X&k}zqyF(HJ7V*<0*dW_i71uKh7TZRDFkS7jKwrI zDHj24`+o9{j@bUSl%hsitAT@&pJAodsolrAzhn_f9iPi=W^w&|01eDT=uUA~MN#Rz zlLCqYN^8uqK8AgTg(HSQAR;5Ks$<5Xs4YFrrkYguh{2STO=ZC`gJNk@f-k$duBX=5 zw4+wvP=Od#>XQg4HT^SVpcFMV3#|g#WLzyyC3|*Diey7siE=T?Ei_tY5dqO+N_1`U z+ghoeM4MP*fsqw%lN39h7QEUw+Oe^HR|GO$B0#QZ9*TA~xHXlrz`CAZn9y>SUf8#X`&b(Qc!4 zkY_1Y{;2jBkQlVUb;xV$fB>S(%u9-lT(qpC)@t1o!Fr8spB2C}uU`$QOl)luFH~D1c0Djpjz4oEGmd-Z2#bW%!!eJP)rp| zR6rdu5jkS--0O5QYh&YL>itqJQtTMmnh;Sv28fn>S>7TdCWup17_BRwjUi|}XOk(l zGMSC%TcQjzLvLiYlmh=cZ+`36jf_9&hjZuK)1i>GtmS!_%`U1ji{w z1mwG$tpY45dCy(fg+7d9=bTfO5ISpq==)BPij*P(sKYqA%GJca>)G=X6A^V?a9sc- z01crtMNQ`&v74twvb?+=rO0|SjXJNW0J!Zt&$OgeMKqz7FjaxftAV*gGC$ISdMc$^ zC^6YAPz7fbsM@4J1TaLPb=_gTnTW*5=oAceyxJ{91Qh!_)Q&!y0Y^e42MA;zQd$DX zNJM1efL%YkDXYsw00cD_=p~Itiw2}QTzez3)XFSE6*TzR`a^wRH7jFHw3d_Mn#6-z zwhgK_ox`53W$+)l@Ku_`%mE=Ns6`L;RwJ$L@Xd78aKR**E-84m9n}#U57R!x7z7tT zjm`Vj#YaQbe_{bIYt?*`JwGC*l8BiQN-^%e4I$PwoYMBQepHP!YG9;wkF{wbJR}9>K`kFV0IZ0Y;pxCh-zR?QUK9*s#b(-O7kL-P}rU|=nRpsQ{AD7L5(o~d*Z))+t(4I_b~YU*gB(#~OXg@mi34cI2y zXc|=jB}Bu13-}qI3Bkq)8+KwPgVk@* zYC{dJL1?9s%lfyKBxy?q2<@UlE#WI>6)<&EyN0%IgjtG;RZy3a zC;}A(K?M+?sDh~2znH#%$FtgECRk7gna zRkE{hRom*D)lvnqff+u2)NkDpoeSiH?>g6y z-EKQ7l-t|=*mp?Shi=@Aj!;V3Y{uPg^xhSfo9z}*3F-dsHW%rKe%y_!61uS44Z~)* z+3z+t8)s(DIoEex@S*RyA412SbH4N8<@oAD$T@Wm9`<(xc%COh7&e0x8Tx*XixeEY z-c^uIyKw}d^E8*3H^Ug?5<=$?%W1N(rJCj%YoI70>N!TwaV zF3glmQIo4i0DzLk;$Lhg${daYdL(7YMIBL%qY**D7~)2S#u*u1E9fK^-c;SkrifIv`@gLR9kOnbWH-xlGT{r?0C~3 zF_T4rifDnG{T`aCHi5kk0STBXX-OPF6{SQ}l{GC`eI*lGDyucEmAamQqQyB!0795@ zHam-iRxGhcZ1+J4v8bY2Sb%DVOlx?eDuiofjiRCegy5M|$qL}uiHH?|4ShAcP>tf{ z+L~#=HEpZFLtcSI1Q6Q^%Y-c9wu3={K&Yy&zBM5M6RBuXAhIrg06}0AFRg2hfHmnt zK!BXG?GGX}!-Zz@TUchfQVp{RYS_j|xfDh+!JumI0Th%JEJUzSWsOBt?b#540CVNs zn=m(2d|%~a|h8TBM#j6KcpRARuJ39xtb~w4smo zjn?RFsgZ#6-e)Na!j5v$^@Z%NA)0GM(K@=KZj;uNFCsRK0ve=b0Jyz~0+2<4=DpWM z6R=ncSW6E=^&Xk~S!ZV{@tWqMfKUrnRmGOq?mgRot$wARYC`J0@137gN~NSy3~XSB zAdpc-KvW2;Ef7R4Qo|RbQZIhJbjFy~s|c8z^P^gW1)D^qHSR&9!mi7SU=?ny#zCP0 z;|-=kRI$UUgjl3l0EG7IXla28lv)RAK}mfKK*a_{n5v&DkV4i1qN-3WnOa-|@DU!i z#=FLNS{<-W`m2$43t?CK2v+hSn64QiUc+@YRaNmM9V#RTAPZnn!3rQ|S#yZc)a^`2i}kKND#;J(|3&Zm?&n++nBTvANAk<Ts zvh4a{)AjfJeL&o8Hc-kC0;Kfqhl90>ulR|O?)bBDSj%q{{SA?3HX&^$pDyIAliqZG06!lu4_)1?Jl62gC?TRxoS-n5YXG~AOsaP4xNAk7{kUswnDXb0)eX3 z9N_vc^*lKy(|G5YX(hsG^!MRQ+r#{VIUN6@7($ z-%BY=&ZQI!!HEHsV#@2iR#mJ>Z^MM_MF1QAbP2QU;tMDP>H2Ps%u!QlLy-qcOAN6F;dot0LWDl>?XJ7Kz0E*2K#7^Q+l}|ZM0c$* z6aj`|ASPxG!S%z?b;D3AnrXA!j^oJ8h#Eq0jzLw5+}-VSDchS}=YsQYv)P0Yct38J zR3&eQ&A7SgQPsPEh>qRqeD==SyOok{^M;|%ix8uTJlx$*rv(w?Jm25koQ|guTo;0h zI3`huF?#1wnYU@aLMTn6jxpBDD6MqB_4 zBeMHxNk*;Iw!dR$-VvFh)W-Cwf1&;*L%UZ12|CZHn2V?=5sMaU@G=ml>AS)jO4s<- z@ahKqt~bLDK&_2kgH#r!?3o3mb3T@=g7w=hL9;DUZC+{3A=TEZM#P|sH4s5mBxFP@FNt32U`W8^4F0P2 z7pn-1@g3~t3CPYk)&$P1f4evUV1kF1yNePdAbox_ddG7rW_*c=8FQAd^U!ch`(&z@ zMVs+KbEI}ooHLpVm;{}yxJWbcsv10tLQ!cMfc+h{D2fPju{k2m1lLEeV+1QV?Gho? zXwJ&F?XOp4-a=u62N0^eAz%Qw`sHgBTGwnw){~H)-V?GMg!&j8t=R zBtR%qu;si0x^gSlwPllyyRNpZTu5t#01FMN9S2*KS{t!5My)iCNMlEzKHP+1*grgq z>VALgyO5#s9{O#cN@1cf^z6O8?RK~8HzN{mwwsvJ&3-2;%Cy~Y5zqy%s^f0MU5F*# zy}3ieEZKXn42~T;M=`~sY7G{iySQXWBUi)mUwu5 z-E20e)A>BjsbuH;l2Xd4ABGQ4PseHUKD?ez$JgVx?_cI+sRmwK;Y*u^wHg3YO-%?L z5h02g{!=X_0ZA)6SsBT=e*{!OQH|7Ubx+QXY+~7lB3L=9NE@`8*|u7KAV3XF!FfV!DZz$4T}oNzT~w;&SZlGCfD+Qh^MNASQ`Mxf)aLFQ>O1Bv zrMlbdHmm8OHh(}ttqN#2(3~Y9G9zfcnPxhzvQn-h(^h4qX5OJlO*2G*3kNkYGD}G<4`S^A`k!qIA&us*ixFU!Fn{%<{=aT zQ41MVwWch=yCMZZJMW5EZd&ISBU(L7rG+4E$hOIaDiBER+(88m!8K^sLTP)5N;JDv zF9E!-@jwmgD}dODQAM=1kay0dB1C8oN~3oLcLE7FpI@Su0bl=2kT# zt1LOjn)oRIk<}|(;spT6TrZu4&zAa_pp{`iEkHt1F@^#Ws9X|DI}(oBFv*pY?i?CI z&&*JX?WmPzWxs+&f!h30g?d?V#coY`Sfo-6Rvffa$}f(*Qr@cN2cu}>N~J(RGChnc zGH;rFjoh#%;&71aSE=18W@06>q4MUmHYcbLq2O>JDb{ zP(f6Uk$P2nfZn?=fA+T94BdW19LSLsbO3>whH+e$1(}DNF_-Mfg`p!yug6n2^uss+ zYUn#+78BBA?8m_c*Y%yM6i`qolG!^Y9fpyZc<&jD)YC^#tS{aoAfr&*nQ%<0mMo!`SBW-bCk-yJ<7FuP6#$`?`+8~HFh(L0kwUpx^Q(of znd=3~0R!b~c?{|?N2B+c`Bza@uF;~d2z_wQHor(IwcE0S3C#i5d~_x0sDgI{2xdg> zo*SdxGLCAh5JVaZjTdUfYNai{LjY@7Yz+1a>C{vJKvjG1ViqD$gupD#QQ2Q$z|}OH zWaY|YwO6n~j{qP=kwE3bXR8OBpyH*5)>RkQFyw~UsR{xi1J%hHKn!w)yfqlM;>l~x zs#P=BXRZOJN#Lpq5jjU9>e$)PU4w~Q1$SlkU+y`WV_FkMyWXoC(>kTEl+45eAc}!$ zt(LEKT&m_14apDzLJ&|X)`(){ASFiQwE-AOwVlU$5tNC!t%k+v^$-HE(MA+H=ddz; zjL!_9z|OjE*rZ;TBC%-8!wiTv1hxmL@1+&mjVa3fElQ zkZ4o{GJk11$&5zXYvcoq4yE-U!KGvc;FyYNgF4nA#Q0_P;xJjPZjWv)H4XuyMQ5Po#Q z*V4~NltY6A=u&0AI;Aa%XTln#5neYQ>^9+c8!{1heZLt}iks~wE+$RoUS1BHVFb|N zeJ*7f`;xPBZeEtRZy!zSImSGWgYSZZ^uu6sC~;Xr*V&vUDKeeUG3MQFyUYvs-YvPR z`-|Bu=Vpo9aV)7g&jmCVNu|V;1q2Y!%c6ki^K?!zrNqvir#Y9hq?n~3@)RQxE22@B zW6n%;K21Nof6loSt7X<7T5Ef&N3j3vJonDeF^Q(v!EphodRmxmhAQ>(yPcnht%P*L}GSW_vvy1RP!2+{Ny*K^jG`Y5W7*vf2` z=1R@S*bowiTr9SRH69UyA~KZPcLSj6Od3={3lM`!6{!YPk(!DMfM?qDUX0!a6(*tPMcOk^F+NP~ zxiE|uRlo-S)_PFmm##&in&zx{c%|uEs8j3Y04NG%8UNa?TbgBCu@kMOWpgd<0JMgI z8Yx;>L859BXqJqMTw6oDtUpwg2oZ_2?u8nrr>NlBrBaa4lM_`VMH^JGCPPewfLThz zI;?VE5z&>5wHDE?PmX!IdReUNmn?~_19kvNYi+20BUVpPp;XHNYJmtUJ+(6S%v{u% z;^Jd!cb0|et!!we98nPkMvzMWM-u=6&{`CyOA`~d=4ezPf(t9qppMm9*2iw83I$XB zElq*Nq8tk+SFCmY#kQUneke4AbX{9J@YGVqipo|WZvj1C`$)ae(N?^=R&eZ^O8XVX z)*rzH|EOD!2#3x+-fqV2hKCW5Y+6z1g7?mQU!;W2JIBkiAb|J5d6!b!?RHP^pG9)# zedt1r(Lg35Oevxx?|q7q9LJbK@ZH!;DLEHH;>|E%B~qjJOhjSmZf|y-^S8IVoRcY% z1m}Ek+wB;0@QKSxmL&E7iJI5gec34t*|8%esGb`u# zqq6W?FmK&ab4qriuK6I>`IBBi#j8qnt5>WUk0YX$!_ZRF3u_BdzzFepDUE0)AzFos z2$`^IS5&J~;gMCE=eo&J8ro$QQ?AWh+Ok+M796&4a>aXFQ%sFFE46P2MawQddH{`iyjFuQ5DK{!m|4-k*4qHE7U63{2-P0GHC?;P;IBvo zmqtZnR5`>oT(AeAHHL3~ZC&BI%VdyX4P~H(sCDIPd3eP$=|U<%yaE;I(wt+W5MWOt z2(*@g8za=(A=($!1htjNt*BEe$9lo%0BksIEdyaqixk(kf)(h{&bgdRHjEouXJzC5 zT+35{URJ)*;qbcmX2mL-C2Y-6Yuit4>bc@cL9L)OUNJ;O*59aX10=J9)L1Ii;G2tE zB9hu$By!zz2z9e+gt!JZ71jdc0VMzxEm}i?6|&aGG&j#@f&c~@8Tz5B zL(+ag}w^;87J|BCT!?6rfn2c#BCySDt=#c$U02nC&VQu30#=?ju;o zkC;+VQE}BFBeYD@4}tD|$BbzXq>T?YuE3ptmY-R^ukhY+0il1kV0)*%gOY*@5eK+bV3 z`sPARCM{k{aqO&fly5de){=8URQ5cK{U>i9oYL)fGYmZwZib;_zTNG{u1j-#xV=qF zyx-qwF598M*=|aT`^|yoTwzIKeQS;$A> zg8~!A*DBCQ)5E-jDk>(-{pcH7o~4)G^X^-*d4TIHaby33zSO`FzK zLz@w7IkD18567PtA=Vlj0A6=wYBOyOfc@wu{6x@TO(|;bUVsR45yXl^UVIpcA-${U zfnFLnQPqYbe8zqBrk)RI$a2>exhKCMKdHCno2LfH(;kNAzN$y-m$Pvl@k zSIVw}f?H1Cuq?Fxm3kcKc-1q&^_c^5y{4fln66bld8HssWA~AXI zrHBt66mm}eI7pG4aw+Pai!ph2NWgsvR{I@>K6vjuJK~4^Eh5A?Ki=If^X!=S+wF%B zAKpAXoKMG_?JlPjLg>4$#C*5kp_1uE1?HR022?@i%g;V5F%Eqvxr{!X53fJI9Oik> zxoWboV;?-AX%#vX+VSMb)aqweceGX= zY;W$(VE_Oi07*naRE%({@6OH`gQ>dUrJa!+vvY{V#5O!n8*!}u{L6?3bZ8lp2A zIb70_l^lDW7OziQRRZ7=KCKqOZqPqwcwYTFH3EXd$9MxETr_ITX z#DE1q5>dgcp2+J?v&%}h+`83nRIb?UP5VRF9zUs6yZ_>f{g-sm^dDs`#s@dM#7K(& zL^!@5!)Nav{4n^w4_z-=%+SyCqN;>^e0@cw&;^G!)(uih&ri=LgIBUh5eFz)rsK(x zi*w9#w6X0_pe#8!K0X~)gakc%=N-jK5H-e#*g+~e=V_id+flN7`0%tD`kc$l;qY*G z_u=VzyBSZX^LDdIIiC*4-OcuNnw)dXltS=`m~t^eljqk%5@A8-xa6V=CCfMrDHT<{ zy%`=JcBzmLemXB*--#3^Mj$PD?1!}>=c{jiI3ADJY9_&RDFwl#ZLD-m!zO(4a6k0B zm=hotk!6|Lc?9*$3I&i$$s!PA`tis2d2K-l07S=FL>Wm1fIvis&fV{K6hao!0!6h8 zK|s?IiMiwqfPLS0UHA0ihv(6MUxm=H@z z3d-a{=MnIDI=&vJlyj*ho0WkH2*d=b)FRq;?Cx)Oo}Co+!Ou&am)SX|iV9RD0}~Js z(Bb(t#t7F<9-!PrFzuRulaZ%Ay#D@@LN;!31*CaVW0M65LJe}oATLJMOx$#FSI=fX}ZdX>x`isj@W`I(XXeHr_c! z0yLd{lhG*5-eTpNe;|MO@T@APEwXZnKGL@XWx~zi`hM(&5fP+_%^f7hIH!IbP<39S zcV0ve$J0_L($t8}&Y zRhjshrg)Va;_cXj_sneLtebk7IA#J|aTIxRKWV3eG@E)-Q$ z`#YVYW( zN^(-ulTiW+T{xf5){FoDlWVF16S61s<0a=xo~|^1QdMkp=3I*DLRcKK%n?pAb-RK^ zM9#}R<6>r9OX>RV^m; zxZCciKuH+}|NVz=T}~20h%x1oN+|{OcwSHr%d+%iAjijP&bd(H!|`m^WEh6SadM7* zKb+^Z#Kk*5&2uWb3%;0w^StnqM2d56nx^?Q=OW|Kr9(8Evfb?d=F2Z0@7}x|&xll1 zUymo}Ju@vig3x9Np4Fk7<~YyOvXr$z)e*6Cxrlc>$2_IX3^&{Hzxnc0bltew9M2~K zl%gr8;QVGBVw{&HZN{;b@(+Ld_Ha0*^RabRgC`$!*<6Urg_$f zTgk--$3!vbB_;E+U%b0NozwsI_kZ~D>Bp5C<%k@@CUpC;KQ8gd!^xK7^M~7Ceev1h zxS;bf#WH4qJ4Eoo+n4S(gOrTmfA{qdzyI@}q2x<1IjAElAPQiDL`<|B{D1xBC!+W~ z_eAWxH)Rv=ymxFRm@WiW_|tbkrmXXPZZahn2AU`~HZ~}Xga4O5|720X5Cr*jnw$O&PAn*?s38_q)#@AG2acSW+rdR0IHn z_e;volOx`a!(mGQVOmb7<5eaBHd4dj`_?FIj%X8@h&%7*l#uW|=Ot&ybU*rEeELRRX9WcjC4l2J z_g(P3_r4=S@4WB2zyJFES6}@Rr*lz(EBFKvuEpQBqyPNvUANs9@CZ z?@N+l7_#K&n>y!*&c|4m#D|yn25nlQq485LrayST-wcm$-(_Y5nCB(!vU8MkRsidDwIE4> zF&v-YKZD4c6kWTJ^`E!B`{MIANP`BKN&+PnQPHBxj9uvGX<~BB{LS|tUJfcbUdKZS zO`@SG72kC9W*ctbJ%YbkvgE8bfUo2nx&R8O(udA7z0B$NfBuGI6e*VQd8S+hKaLj$ z$2YEg@!6ZjZ-97NA_DmkRP{8SopUPMd*_|Y3V-*fua|T{$yYqA%5~D(psWC}b>Uxp z`Du1xi7Ca@55t@yGBGkRi{{{h^Bi3N$8Vp$`SxqdE2h3esdNp?b&Q{E19mqBFy`c) zv+*pV>YQKVvKa?N>igmS>+7Gt{SM{QENiomJ`xjE7(8uz-i+g-gmrX0+9aH|M8Hg& z5VFEIqUC&ot6t1&^`BM})_w1W(Is(!URAm-h~y$_VusLruIrZNX&i?oEh^%JQ_&QqNa=z{qT@LtV9Ez3 z@}5(M!|UmEDnxXirkua;hu$IMG%rO8GoQ~(7{W3~E#NvwBJnVdV?WPx7rLDD*!MBP z%j**{*=#drM@;3Em~e^3`Efd*OP*8(sl+8RJApE8x8J``Nn}Y007c5poBjXrum5H@ z-W1gzUtW`qvtXK*IP}9(%H3}48JFjmKYa7_mv4W#j!KG(Cs)Trfe?YJj>GWRUwr!6 z!<+qf``ydyoZ|g{e>_iGzZ7~O7ucKqz& z!F&IFI56S!;W%za=lp)Rd2@RUQoMKh@cRD4i}MuA`k4@jnJAmE1Db>#co%;C_Wm5@ z%W=Hh-JIq{RT*I%$CC1ouO~|}zI?ogBu~$$c?DHS2WF#yDrmG`3PeQs=kIQY@n(Sl z!E0-eTVi78OitPne)4ehfBxo=zlkFHgDNnCs%*SN0PlEOQbNkAh%l%0>!02K^3CIB z|M1<*F-vhSJRJ_Zu^)P$a`8k1(x-R(|NXbW|LX4kG@q^VNeIEQss<)dD5^^q07$t! z?05g|FF%hi^j#O1?A({9^PG!xT`P-^Xb-Ceht) zdz_{rbg$FIgehlcdc4{Fcfa^zdv~A0SVZTPUSE&5`96IWT)D_uDO~ z`#1mLw}<0Y&S{-fR6AQtwyjDFk@N1qdi(J3=56*vKlIPf2LedBbl#7>&qdFtiGjPm z`|aJ+|MvgVx0* zp%4E1!}2o8Kb#g!b(AbOI!i8k#k@mB`Q^jD-|eE(6jSi73!#*Rh{1P`Ik*6-Q%)bI z{N0BjX+f+iUBNjKNmqp|s}tXJ?(xmd&E1^>EK8i1csQQB-~jP{e+w!ONmTxB$$h_> z^8rvn#Cw->G0{E)ldVpiqzs|^)!T=Dvm@8fIR_uk)5Oe3oKgzTjh)+#!*?&IbNM>Q ztT|eDU*}yeB5GrMT6-HHqyE*WZ+CZZV^#oMV!XY%d44&J+s)I**2qOc;YsgrZ|7<8-mAnI z^Rkp+Y*-}dDCgoFm$>xK3f||ON-4+J&^cl zD6fZ8j-o<8J{<|5sGjGXOG&+Ygwb~?7vJ@GIsu4HlK}wsEF#YPSR@rO8MqL_*H4GL z`^T6vfOZ)W@pzs#!=_`_0^mtYJWgjLQ`!96KKRaYk;24|IHqh3nF7!;eKzzH!V>j# zo`UnlupP%`iDTdAqOa%Wo2T>h>pA93>_nnb4F>NCc_}%ol&davMLrzQ8*s0uNkGr@ zaOfocg%?5ob%2Rlk@KNcvi%iauN9alZRjIce>pb1)Glb63%nZ z1hCtV&U-BI_I^7k{=46Q-FKU1o`^wJ=bVx7!|Qp!8JQTMD8TVN_5Jp*KKO4jtjU{p~l$r#^&n=t?frG!H&7;^3Kxd+%+`*5F-_ z_^*EPa}iO%S!9_PVp1*p&6fT6^zxiz{`&%*={g~Tl8A2l?z}_*`0?ch5rbz{o|fnt zKfT@GKE55gA;z?%Z0g*=OEHtNXA&_Ws0GV?{4=0^7EhH z?)T59Gu%H|3YA5=;NKr!<4qROyWP$2zWXqS{@^^7#9RqAM4YqWmAHQa_-8+R_xa7{ z%P)S}-+vlo$%3)u80Y8n{Nu}e?0D$H=tE9Vj7ZLrI7gVZ1m~<757k(NsH#ce@&574 z`?te5jGIjc9La6B#Yphq3daltmP5)K`(BfJB;G?LZVb_|I-P zVHjRBj3G?(^0*sSHRfVS&%4Km4=+zIKc1juli0L4!x580Q6NCUsxfOFb3cFc$eqKI z9dlMWolkeW?XK^ZoPw6kI4&{9jLckOCL)!B>_l`N`?zFKEmE$^8QAyz7q`2D!S_8e zJLXgHL}bI&MWOFlM8^8@;psJsJl@_M z8#y86c)QQ;qxRmm^-TvQy`tgt7AA=7_c%GJ1Tsr5GFgU-& zGUwPi|N9?bUk=CZW;4ZeTF2quZ5?5Ke3eSezHA%xSC|Ls3~{naV@KYjxM zHbQjH`R(m3s?MS>hu6)}GvL=Bo`UBwc%y~}B4ii35L505WjZSmfR>E^>+gQ(!izXt z=Q551B0vEv`NTN)A$Y{!|L_A7Z??O*%*-~H4Qv);??a!Wje!-^-+cA{`NRcq%Gt0l z03`(HIL6t9Af;^k;ZHxlq%`lhn-p`(`IE;xRt12czxxbO|KGoSwPZOQPwd?vzJ7Xo zI#WNQV{7L<&1Xxj5x_eSh<(>R9ge5-`Ll=HjhA8Q-@m+wXaU`h!*Pj%;Jqj3w3O}k z=70Ik@B7fF>vb~jCD zD~74a>3l9K|HmJ`+w7;mdw-ng*?Esh#5~Va=YtmMod@JB^6l{;xeUWNFOvmrOG!iM zzWm}BuP-l4&X4yGr)fT&&(G)lZ~o(NAK%Pox=!b5=(}A0Kc?PnN46!&4s$p2aSsuZ zd4@aGy*06$WDjgg6i7%A1PGA6M34GMeS#h|yhx(DTg~pO>Z*G(Ghz=un3=mCJkJHs zQzB0wGGg!T?qANCJB`6v*6*GyqCjiqEHabVeQYjDtH(kA>p$G% zm#Xl0EX_N2f9$QbWuE33psSGw`TN(0hziDOYlj9B!Jt-^t4P1D6LBRHrMh+QKmPIc z|GWR6F~+VGi8SfKI|Sg?Q?A_Px~^yb$G7cxUSfdf{eIV=D$yJxah-x49tFA9LCyKQ zKRoUSeEw&euYYjH-Oqx?l#)-PEg!*JVuG&jxn8_0*9-QE^Wlso766q>y-tQ&LqO+U zsl1W?-+%wpvI)U!M=T`7zt>6^qUc@gqNJ_!{JYotdF+!l9VSriJ=sk|SG`DUGDsP^ zi9|pD?StO_@t+95I$v4-ROHM3K2Ni1Vi49Z_mt~f=8|hL#w}~j2>}qnq0P)A%tU$v zKo)igfBTZUVU0;?b3YDi@GT#O?$X=ydNFuD&a_PPUh=xeF1AS%k>1;7nv$h4tt_>) z)_ZRn^ikx0`G5ZLwp?P2S_3g7m=VV|;N{61)bP_|FEw4(WwNGJ>KXz-DJ4#JFyKng zs;lTsH}QY_r+d{~bgf@f=}N3|`+j&pu+Caz4Q$70tjAHDArcXn zYMuMt>nkF@Ptdhi8a{viI1+80v)gtk6-p^0tTiG+Dh~jtmArS4#}kpFzwj#t2%)7?(Jm=V=T$7h;SlrNQl-rs?r`#25i!+qOX~eZ6l8 z=&b$j^XIqMx7Jz=G1WYjK?bxPsj$SxxiAOk{p0a4#)wEQMIjnvq7Nd1)@ZGSrHky3 zJ8BfF(=@f#q%~rSJ^)}BDO`_~jB}UeVuJ6zS0ZBSO$BF1MG)t?)H?WE?ueq{(S2(#~#>vjFYvlx7N5G+i{-T6k{ctted9! zZF?9*gSe-3S(g1gTnNMx=ef5gt<_qcwF7RRLO9Pf^5@>!zs79)HplST_i^)X%k}mC z5}dD0kA3&fU6z%FS^Bap0C2zGl~yrEBI*FdY!LtQU;p{KtpD%d{{7?ec)YwSX7Ajm z=MRr#m;P?0QEDCez=&||Mv4``MZDm!5LAk+W*b$+4Vs--W0gADXkFWbP?4ax96qkE6NY`j8>9v{(_#mEZgO z$M4Vm_1@lly`Hbv^YMHf)FW10ifYrkI6bu-c5>0*$HE7H0AHHVLod zh0gjDEA^C!=@#0L&YPG?Ov!7Er@*~x47R`M!us#UMa$oRb0R?J!pjc)BThR}Kiq2A z?W-)r1@^{PTit5OEY}V56l;)m8FtF+Ptf0wx0;P~{9 zY|Z}t`S{77s)7PEehe(U%53k08ool0U%hgi(sRL^;s~Px&nhO-F`Q+C`|E8ILBCYD zG+%P};7;Av8$>O*q1(+9K3(-z2a+8A)5Q&cC6e)jovL_P)ra8yH8iRp5x@RxtR)DT zBD{Vr(tJ)`HP_M+Weo>Co4qF>Kzl%}P*&ZM(*#W*Fk9`wZ0yb&y{tYw(^)w)z{fb7 z#a3LrO%5QZ&h2k4evtaJ`%6pZczzx45q?2SPX9C5&XTIO__-#Jn4tGzE`U~5>ttCy z1q7FG4@Yrg3&P!9aIyUtqqM8ZneZjo`qv0WqlRJApZ~3eD|vvVMu`tOcffrUUs8qfE2^{_e;P(Q zZ+s2sb8RHG5);iVqBDA+X8kt`V}nMgzWqn!0-p-X5~jc~=B+m1ZpHxRjJ!BcQgAEN zL0_21t*x=5p+5Tcy=ypYotg2?D6x^TnE$v`9nW&ckIZo2ly4zj_BEIugA1d*snE;X zfWUxKK!JV#~Obd zr5%P49(cRs$P@>@C^xU58N|zpSS3+j8G83%?FJOf*}G)CtITS$daSeBwO!X0{h5o( zbI$k61JnmdDx{|oz$!fljmcMJX}(FN0L5&B4_$vIvOCL+sRo57P1?jBTNIuPT#1R* z%Ob1zQe!z6*vB&u4yUF+WGoejEQFu&=yDx`*i@;pH~4a>rF znRlkS(__c(*9=yhVnms*E$YGouWHz+xZ!ims5*yq+x~z6Q&{QMk9jCK|5I%&`Mba1 z{MPb+|3Tv*0U7Yw_`j=uZH`OO%PIuM?)KvOACD}_uqv&ZbM%DHzrVNXt+5SxIJGuy zPtSz6MhI4YrS#~c6LRgU z0}=~q)2~-ib&k&NoSDtZWeT z4aYd~k(|@QgD&7G%iFn42j>>1{@@zyWACyRx+ruBGul`XwzNKnxn8%oQko^?Mynp> zb)S69Wk~7M{T_*n<$;TWz#p_5?snv%g(WLz=&m>c{XQ9 zS6E2JXrUQyU8C`#N>sLUqigSD*$QiU&*03*1%o{81_!*+X=#YTYUKEo?=X3SFc6LD zMeAIWlKp=!z`#vBT*FuU%h)1pBDBNk+CsQHRn)B=&OGGvu7W7!fg@WkplT`c)0X|2 zZ}RUBE0Nv+%;JsHVwK)ma(b+#=s>FNx)26`EcwpacP~Ov8*{FV59K^ad1sd5VgKguz>%5N4rTd>#d^vVcO|AxB=4-a_(tfm z#`dtg{qCLe_CNNafZK(eka((VdbP0ED@W?3W^W9q3+9myfFtHl z(^Q>TfO8rxA6>$wK}q4na*HS2yHZFjII8e3svH`!MRIiR@ihCkk0yDL@r)DVk0X$D z9^ar6{*`#>e`Rt=5`hv}#M)nbxxd!hwX29{OTFFNeON8`E;uHP!G9u#&7_NYkt-;g z3@Mzc-@$&pDoO+szOMZdwPCzJk-bxt%tf((o#PKFy3KbfI3lb3M9v(mVR@Q%b|v&o^2D3P6pF)wArEEiFqu2vIE-`|?u)nM`g)59r;} z^IbNKD)aYVGM(#md%0-PvhaqpQ!shS%ZzlNJG@gCzyEla8fPjDTZGY+Cs8S(9I&QqEndu2K!X*NcTkR{+nHsU;s_*z8F2?|N^ zc9SGiEMBKG+dS7zNlrN7IRiD8kz3+%;(v9#=hY4)BqpWqW7ZT?tJ zHrC!6fy*?_$x8A;-P$YER*KJ8bt4fSZjSakOA`+{?9U|r5lyPZec}e_3h|vOcP?m? z^zxH@2U>hyPZps2jbdUsJkMGs&L^NhFNNowZk_2%_7$YIS5QfMT)Ned zlE-o)MQ(lnNxi%gbhb78l;crIj4$?qQd)|!fgy!CQao}%W4)=t2L*hZFP)7&VkCg? zi~g3*|DiHoja!1}|0r`l(9BA_;|D13i zpLw3+^DW`)g_+B@2TgY}c8W^YzZ-tApu?2O_?mTztN#uOhz_?OlI0(gB)AuN54*<; zpn5v%1>UHtKuQr8)^qXv5S*LhDw&RO(gxbp)odQW&ML|@O|G;%C^PRY47q=#$2^eg z`an}yc(bt;DzhAGPpl6?g+mS;xML1UUfOE^`{iknJ99OpSn#;r6eb%&l4!m&-6F<& zrW_6$ayT;x6%?`LbSRE0+#4f8NxZKBis5`p@CS64v;E>Q#(A#@5K8yrEqu zqWXtFSqfrmd5lb<0MW)yCocciEFQ=)x>#BUUC>4184Fyj%AKWrED&6 zXA|*lanbQ(>BzMidiFC|WVfE;$xRlVZsnyB0)Mxf30e03K)zieq4az$Te8$<8Yp1|3+X*|UDC zl=1geu9lCN4Ge)p!wRCEm!gfcm^Xqnl|E7c&yt=&crUX9A5nAySO0yl9qhW`zJK>_ z?R}8tL~;x#1f`H~&~Eu8f|uCK)+0GW)TLk%KBQfYb3XG1`2&U>?=jzx%oBr%KSjUS zO#P$V3YCBS%v3G{xJcf_wlZ`kt`vWNlyc?k&Dq4r4s{6l4}SZ6luup?SA@uu=?to%w%?TPB*+M)W0FS!XZGjz29%DM_#JZiZyxbZ?oQ+D zf6q)u`oU>v6bBqu{@n=ns6mo-?4&Y5&qZUyli1RR)`sz5{gbzXOV4=*TGxlS*EMDp zp5(D4Gu!%7FK{QJh*>7Q)^V(13|eo%%*Q?Ik1xS!rr)IPO7RS* z^_8^j$?)jt_$L5ED|7wsxGlLghkCa}C%smMrOFFn)QV9H)^RsyoN!`=;A^k1d*8Yd zT7g$ZKBnmp$#9+I5pDI%<%1=$gZeZgL<7>?tE%4>g2Sh zkV<32G*lHLsthPWZcf$*fTyz zsnlL8kh@EvH4JR;v21U>?KCh<)V1dojzw8JsRU#+g6q~yU`%_1NumH#pZqMrlEz&> zEAI1?+UHkN2zlo+c>{Ea)}P$@M7>u?8$I3Tg1sp#+NV84`!rWF8uN-LeQTXHwBVR! zgvJ?)-Go3z`=Hd5SpHzchSGE=T$p+ zuAaLH+y@v_rUe_!0(58toaO!w2)PTkaOiYk{h7SYWdRo>`fNvRxC?uMc^oQLAZ{u@`$#zbp?6@h&_?A_}1_~S2jo% zVv-p;Di!oO+`ThA9s0#8??w>Z3RXf6!J%tiH-C%D>Rx7Yzsw2+tv{7 zqolRL!?gnqJAV+Y9&@|Cws~lI|I%`_pja$UKEAZT^nkQr()BxzwT!85zFLPGN7m<% z(pEOf5v9`#40lFqY}YA%%$|*Bwk!-x8>Uo;@0acGByw95W2j}$I78dl@Jhn>66yb? znX+b#co;H8ugJ(Crp-3*6*qI=U z(aiRh&(ubKGJbU>L{!d+RqZH0>LzUhxodrT8v7aPr)m3I`>;{NfZ5=BQ!{g{2>JD` z;cy{${2IxN_*8pug14CxQF{K2m7Kg6%I^{WnB08T00@@#T$*hd@FFYJy4A7RpapNm z2Qdr|Kydg%R>-&mWNoc%qKA*$6G`IbcV^?5Tb1ca>Hnams-^t}jK)zQD1~8(Sx-(u ze$eNsW7TBJf?Zn!`|IvX`)QcgVXfB|0&-R3v5_?1`xXN_IFinL30})FH%K$SVMF~r z3MUyT59mL3LLFuV(h+pu%n_8d2{yC&j!p^;4Z~-A?zl{3A!vy9Ibt1>1|^G|?yu2h zhloqMnN8S#uFyZ2;{4TVh;yrC1z-7#Qn4K5puBCt5%}X~v|s6$f0~qrUu2#uXNPXh zKOH(t#8K;2TA7&X%^4}J&o)9*6WdMdd<>b(bmorlAF+3BVx47X(4VF0R&u=lq%b-8 z@_F$bOTW?6^gEe1+#1tg2Of}?#%00>4D@j$UpAVS&?KE8a`Q!Z#Kmg(D;eto{HlR1 zhl+0i^iFU5x&>f3hSzVnEjOUZ4u@HD_GI}l^=*S=M@zn!OpBe?8D9{auqTR%XUKi| zwm1E1!EaCXq_~Q>R+X!Hkji^TySSGRSP6cxTC4^@8*(uo6Oc3AG)MyIjgy#>;xdIU z@prL_Mel>J|D*{%=C&MtXu&QiB2zBc-h}|+)(FcWMxl2x6%O`zyB&#t4q>fdo#q*S zX8OdksLJn0-eqqYqA0TfQxf^&OEuEg*7kDKXoWL24-K^K84!;U)}qfLb@2%Ncg*Xb z*lF!=URuR@The!m^lMC^$AbGWTcg#+3hp_(B zxxK0?pCf|eg!|0cpWRRu@&~cxb&}*AFLB5lS9Q|3LK!_|6D|k&3DD*Wkumo2SNkUi zQj4$xs2XS$+P@~+EuT3h784^Y_NynYs$eJI-piBxtDvkaS|+XeqDiiq;$(T=ot&~g zF9JF*{o#Es=t149rO3L=-iv6H>MdRq(D^ZHKJ+W9BU?k)N0nEwQM-{LK9*L+y3USf zm#R+!9nI#04CixyL0&}L*ZA3>g7C~I&6UN)tmV))U1Zp5fbp$acVgpvA%Pc%p;sOP zdMtE}@-RI_#0@nW<0Q*BC-EiW2i6`;Y?V2W`|-2)WX4mVBa-24IcOb@`{A)z0z3JR zfF=n-VD>oW2O5Nh{pEn^N4_|2ye#J;W1&%(GU`hf4VmSFfyA4J4>UgL(uB#ax$D7~ zWgOB$V7e&fg(wNQ*C0yI0NS-K<`Ef4Yes(?_*x{qP|od6%?bkT8hrBNIX{!4foRWi zU>f>!_lMl2-Z>I5pS``Bo9vspOyvURb?uxTgCT)`Z~?V1MgasafIQJL9D|cb6xa^Q z`jbb}7IYstyP={5e>DbO{=QPrc01+cC8r%#${I2idGY4ZIm7b40&)e>rhi z_V3HY-K*%C@_5m@@mo5jmqp%@ziJNQpWGpe4w_hl7|4aD!VxE`8}g%chH@ zkdk-4H00@2wg!?{YRi0hlhAC<3zo#Uop0S)(M46Fwl}fDPsTB1cv4}gIacZjq<-D( z{YbR-xq@7-g% z4QfL&z)^~r#hd&u^*AzoJw%2Aga|nMY}K)*3cnt&t&L=_gq$AebSQ`a$iP=qG+(y{ zX4*^EP^?1M7+gS>&TOB`TCie;$gCUOET4<#d~a`nu|klG#5B9mpEnOxjY3`X6-fr$ z9Mh|*a+wDT%?Rgex$hlt%N#kI&<=NdMs*{1^)mF(t8^zU$X7tur4x91^v?Ghr8G8N zU7P$i%)FLJ&SZpIU82v>WGcvK37il539?uX5LTmtt>Oru5+0Ip@jagy zpS0(qjYt-c3Ev-{e!sj?{R4N&naoLyv2h|YNvrDHd+e-94NBE|7%HC-9sAHoLtIKr zvWja&i>kOiVvu#4tiup#$o#!p{}`_4Q#d;#L+gH+PLcEpsJ#(+-0T@@G!_=^CP^CK z`(=^@KNHtFZO0LQgKt2eaxBlLw=}4TPhcMUy5%dBFxpo>l{K^yo4&`FR-zoz^G2~l zQo1Y&g=2}Q_#!za=#qz}Wo1_-%nupb9y?M%ysnTWDSnPuqxP}+ry;FH3A3NffF0+; zP#fQsA2U_cIydfkaj2%Mr22u-+0&RBC~Iy7tR>^%fiT_=@0H7yoQDhR4;j*G>iAKQ z|JAn6tA^ifU~FksO>b;(zTq;B5_fy$+wzqM2c>>aXP2Fx-cv) zh3+NY?0IdMB5L@cOs6s9*hmzP+UP5ML=9XaX_}K=^Ri4MvNGD#X#p*_~pd%|4}-^9A}lXXN?CgbZ4&AKK`U*E`G7 zBGp-+U0za_FkS-i2hq;R6y+PW0s`rbHmE|LUfe(++sX=gH&afY^S+TYX3#amVeSOX z>hMB{;KmH%UOE6h)*aHKHfAvFA+Jo4m(mWd)c)Yq79W?u%yOeR`XBd$9}w1%%mPnm zbELvzq4LRhT3zeVYM?(OT{ckmbat#jH*|e_yM1s#U}$P|o=kQ~b9j~*Ze{~}$-esa?HP9go53GY560xK|4Uk9a&}gU z3gyg>SA*-@m%6q#ruUu;=VMZ%wEYE~YDCUYG4H*3Wa0hy_#nCSee8i-na?#G12g)UGE(n8UmAt(ftw%zNaojOD;i$ zn8(J_d0Kq=bMST^<`@CU-+^0ufKw0Ie&f5No>7qeSNs7cW_N^%FW{&*(lB@F=Rd?%)g7}J1tdF19a7J=~$BFJkJ^?qs>)J~1N_b)au1*Ju%M~0gnS`*SH<^|- z@Lq>C-9qOIo#^Q3lVhpZ`Htp9y2qR^pWXmm>IPH&!xC((G}6Rq)_S45!qyeI@TF!| ze62UMUzXl2k3IU6kzuA~yUw0gk&nSq?vH@O)wd%1ztN9c)l;HmI$l}9vrc{ucN2$` zv}n3fePk}o2KjqCqRU-9@82^m0FlxwZ-v1&Tv1WfTvD*E@Kz>=Be|hnv)uUc%%Ew7 z2fDsS*#RA@>(v~msEUi~>$RrNy+OtXx0V#6x~fi%oSBO{WA3RFe0btU%|?4Yd1HFR zPiX(jR5Y=6L#sr75b4v8%CztWr^cbQW}xWbL!5d%^YOn4ry;Mb?A4v+;&y*N2lRAF z_C$B4`;jNF8O|N2VnLj||2=tQjxR5i>WWu4JCHt@;oG?mKyxIiC(6CSPW$szyE|jO znbFDwFXBPS&o?F^)gc!)0%FH8{El#qEzorPT_jnkxW9KWq*UzHHEF%=_}RSsItF}!OB?}`Z*Bh1Oa=~dF=@lkJu>)tAmu6r#J z;)Iy(x8nA-7Q6mF?aFT$3Ntb^ETQvAA#aN%{fK4EHmTy(oc*AW9*4Va zhab?m&hIV`+VqU6v!*YzA5&R%@%8z>&;;D2+k zgbsff-OJMvPjQQjtmR88XuZkWExeJq;x(P$fBj*43~rza^#s5u_dO3FtFbYmrb)oG z1dA=f+1WfDUz>Nu{$U%pVLpV&4G5}jgaJ!Q! z=Q4{d)oSaeHc@vmCV~YM3CXBohc~Gh}$d>YT zzWS1S>ei!H(baEI6>x{B)kcn=85FpTa66=!>yGN&jM!%~bfZhui`dyDO=rbGK<gy?>;+drCw98E8xg~8 z`Ieb}wWFn>4$suT%9+ffugK=rd{-t_=u{GuBfAelO7J!$U-E_ZU89@T;cNHk3-9ZB z9#sDe=H#BzlJmKHtdS}B_`U?A3qHJ>wC-TB1Hk-5{XTN1Sh_KB%^9ZoXwZ=jo-0;nBBf z!;Z)X9T?^G@;Kz#M)Wx^slg*i6D)npFp%y|b&$`A`1)E!=grJ)+#i!(>Lu-SPOT+7 z0c{3u>X?{da`rGRiy!z4?(Jc;54iqU1>yPPK@usAhp-AdHgVtX|_QKFjZ z0wS2E;Iwpz5QAg3nQauz#_v4kblK*~%x$#0PhNxFsQZc`Hj?X@(;Xj$O%xOE?iA%Z zPC0`L#>=}41qJW#ilfM2&c(hwk3QA-EP zrkH-e`Y#xEgba7(y5&bw6i!@YGStmc_I>(%WXm-i)Kg2j+Oq+r=j6?BxKk{WJ8Q9BRXs}H z&$^jkTtx22&R?T>Uc+8LA4X595$zcd8fH5=J?U^bj8TB@I337uSHusyI~Zdg3i$p& zsqr1LLcC<_{WChZ%U<~S>^X+VW9|7@1KN$`gAWue1@2wpKdRCD+qSi8-N3mJX(qJO zf+KH+@y>Z@4cdP_hhaZ&>?2h((S1pUmVKlQXkDWZfT7(U$LLGQ%6}nR!)(X2-yQYb zWM)T`Egr*_NKR1k;H)tyR-24ooOCD#D5HhXRL3ehFq2nc)<`!T@7xnEg@S>E)7=Ms21ARUTBzShiDhH0 zcp(T@P}dgC$pr-?i9|TE1HRp(rFkxem)fK3iJJ>=>R$uz1_ultrt>>_5v!b1sq3{H zA*2V(n>mcRPQ1-+tHSl+gt#|`nYo#T6O$*E=XB*q^t%{i9ikm@lBD*7!YZh<@?(Qr zFEKqyx?*RdjQMYJ9@ab)&+PV`svv5ilHq?u^b5X}aKTG|kV21QM`GOZ$4}Viug^qX2r@uwu#4~}IX<3Na{j1Fk1ojpB22~$- zCH&55-UyT3pSzyOfw!M$11G07KKx{e#3i1!x`u=K;M7KZ+cXM3V~)t(-7)Vqj@uzS zu2_7K!a=g*F8av^wz4}r16oU3beeW6`3_Kju20PG-+fegZZ0EYwTG0NNmw#7YzU8vh3MM0gQ28XK@wjE?=$ zt9{mx%xx^&WOi*2c1N6+Ee(3_Mc!*N%p#cjEh(!e|2A$u2JhY3Gb+YN9tO&M+TDV# z+Q0@e`O z(o!OY1T@xzi~dna5~jz)VMEf)LeUvJoAwx!81oivs@_ugbqf93bc4oPEif*GYKD3Xu+l1;D5n&V&a5WX|o&Y>Ry;WL|R+h?d7 z%*@x;$aEf$LFcQpV;Jd*wCGY=v7lT<*xxcHfW}MGc#mAn-sgPrEa=qw*oYA=jA^xWI zw|0o^9?YfDgsgSqmpQhSR|B%g7K^02U^PcdbALZb_d%W2v^@rw_IdEQikr|}_##CL z^_2VP1v72AM(5(B7u~6X>uI5Jp!i$8+(}h09YP_pcl1GUt;+HH(vl_er`}$~8`A}| z^lPUCYT&-FF2R9_iL3k-k$;CkDYEzM{dME`tu>u8YZu&0wx)bpC>bPX9Z|Aq6L@`E z@H}!NmVtP1M!u)4<*0a$j=3K=AemhvT;&Ks2G_zm4stdoJ1>i0cQf3K7wndb%~u`m zFT7XBMAF(z%nl^^6+ck&N%`!aztL#ugv6DE9u+@e0@7i-w&o8V2&g|<+y*=alvDnF zuW*Q1Xny$GdlY-!fPP#yYNXI$g??Qb{!4GD_dfrj7xAShH~~S*QO2uEt#>j{!Zoe? z?A9{h+o{}mm|+U3M&>=z0YE}P+Sb^o;12)1e-W29mr)a7@_PissO1oE1tHI$xrKf- z`Y7cFCwaCzkKesfeLb2;0vrUTR7po~`jw&oIR{KhfXYI9C#_aF@8Z)_IG^@V<;br1MsTQm370--QzX~`- z&!{+ZmBwNSM-23mwM^%Mp!)WWZG+Yn{BqrPirhLb#y{zx6N>UCKHQ1K^KV()A5Nwn zGL=6gfUyXAPRgJ1CnutlBzY^+4n6X%{m(70NPKnHWBu8OjcV)X|Cn6y{^L{+8x~Rgy1t1K|0i%?Jt#3Og}7qYk!3D;^YhJ=Z}{ zc-X-ngYu&szDK$(%a?R!`yQlGR{z=$vu6aTeG`E4{$~F?uX4Gix!jHklEd{j0Hv{` zUiIYuNXozdZr|e-s2TQbD?wBA_@3RJAMH#6fFPk!>Z#T4O8<<@!Y1ZLkj^M@PJ$yi zfECgKwth;{nU}=H9K#0@>pnaY3{W-7+jyxw@Cz&VJE{gwZ zZ=fmR_%)?lfMy3Y81fXErS(9Ggk+U)6G~Yamye|1{4#MrQMIn9I$_17+=GHsH?P62 zd(@;(`MU%Ve?^zt_fs5bQ8h&y>LlV4B4w^~5~J`az}RAH7(L_Z1otPKdR!2;>yd?@+mc%j1n? zeUl>PHIN`If|W_{s1!M-($9pDOaWsr$&ry3q)sko8Er{cta5cxm^o(RgzKeRzZH!L zUM*xHCXNz0?~bER?2auQs{wj%iOV>R!L?cK2JDO4ilQf_` z%otTVsNsm|DnM@D$#g`0T=*1gi!d}a@FNSvN}7R>G!d1-1jt0yWgaPfkTXafpE_o* zSCa3INZi^!R&D`*%WdH+pUdC_)egP?>IPAB&TEm*>S}a5v&{rx8U?vt5=wgPf#%nEZ%D8=h31YeKiW=dqcJ_&`YHH(Lc6E%yMSo>SI5@tie z5=kI&WxL|~5F9$giIs6gE>w;8Ocen~8Bir{FrBeUzt%gyVx-tXt4dLeK&cm?xB_7ILxVD-@4l zt&QTxolc?%%P5gM)50ObVR@80uQr)JTM3ka%y1Z}PT2pGHr?K#P}LmxG{3#&J5@IA zd8_(?iri#wnQ^=gEMUjzlN{|C;q3WSMd3tzkA~nq*aJq);6wiqOAa|d7EVMvJ_TxG znyeQr1}?qdjpB%3A0D=QgjS~gc};#X(SMQ)w^|4*KEd-!_9`wwNXBl! zbbd696vjBPAoETn884!kk8ajP9RI$&N(ObPRDFAYT*Wv|EK|og(l37dPvbxHt|sqA;*cdjUYj@jI~|f(v|uWPwz?pD4f}g$1l&Zlkc#^}m~$W(*-^Q`>f=w&em(Vd z_Y}H+F>aL-Dh4~ph)%ER;zsX4U4oAGx~(jA0vAOt3xpI^#&#l~{_|xytljlAs;@^^ zkHvF^?I!>B?M!GN8l|{c^5^{Gz`zj}k(ha4Zwxcy^?IcECVL@R&OE^SB{?_w5{n5k zS%|-Adcmf@9cZ6Ibepc*-E$|07gy$LLG0|cNtSfa&)kxTSAbLPVy=>6e~+vLPbm!~ z!`+%?zU`#uUPE8xoey?=9g2A!427FlN@PtTfgQPs_6TBi95Fv zciK;-iS7iFw|cUTTbN=Y8cPGyt=_~KR>Z5x06asu2b7HWEL*+(>{skh=1qm4qn#B8 z6C5`B^=53)C^(IXXO{%Vg1SnBNuYUjy2X!tZ+&7#ZmH|fqNtmRYFlfblwF8P;b%XWu=`YVgfKv9i>x+Lm9VA_#li=^D^>Fxd=X~RKFZNqHOt=Qf7gDQ?g=LDy8M? zsMDpXuf$k34H_DM1i5W)w{*S$jgy-)QH7CyBwqs782^eYr96x37&%8XDaHwSN*#)k zjG!gqNJ1$3tvEVonwD7;3(AXLTV`E|m!l{+D#-k$15r?6<+O zGjSOp5AoVbYy&%>=mgmsRWA^L2AabF@n5=Gp0B_`JDy=)J2kB#1S9pFI_sHR zHgNEQn5Ejf_N~e3+lR_W(C&}_tytm-;k&K~?GtE&120En*1i%e zJtdTy$H}cBGCadO8kzWp<4F}F-%8|W*e73-^U?RTNXG*XS9(_DA$*83Dh|JWGuw&k z>l#kD)_6<(~qXBvMR`x5kJQ-`a34O0^O$nEHFQsMuSmz?k0rgOk4z(SC%|5j6 zho17NQ8#&v&6$HK2QljWdPG|pNGWPl2oz5=;^avCv-dL^Qfcc(Yk{#4lgA%v=> zaMNL_P=6e|C9}uQ|E3@wl`aTr&drGQkkKtb#cyq=Hl*2RXQSuFdK5k!a|y}_mrK## z#7M<=TJ}+AOWY6ztSb756!J4j+%_s5LU-@)8t*O`|J^Fv2gS?F^fLFEm~iGT25Vp$ zyrq9at6#yXf#W&3MW}s$pYNE<4W);la_viLebKV^X!PL&SfQLP|GIVU70{3!iuDDW zBgB+Yuz{v=^tCTK7?pcnJHO70$mfN2%sdE@sn4tSdmHT*M3Mk@=0*6+Hv(6JWnvGh zi-VaWH(-jaq@&Ip82Drvud|0x|32Js4~6AfJtMAVo_#bKBRltZ*EWGFOV@B>&PR0Q zD2SVA(7Ya*OPew^7^z7spZYYy5hbPqz_x}{jYG`@!l&63w9gYLg$HK*$F(jOl5=Ae zVA#IaY(tvBJ6K8k;A7D9?3`3cv%{3g&fC531zm^X0^Q3&W|hvU0|#Z7qVJ^G*6J)C zkO2ZnIrklG=ZH;hDZgLz)ez*x>@(1okoitfZ4lUsW@`%(zRbxat-ESIUlN$p$W(BC z7Yd^l2K&VRVmMnz%UosXRy{RJ0?aM1-G7WkLhik3P?=aJxMl!Gf7U}cyF-$?F-?(q z7_|CM!f(vqm98yzYj_YjF*bez%}F~y9GJ1Z^{a+U(>*VEC*vWrfLSPZKg$%^)__yL zBG8y|ggtZ6X9ap$2m~`z#k9+<7McU}`P9WPqbhPn{xcF$U=8a(Mr8Jg#W__XD*r5R zr8-<>ebyF&DRyt^X5H7&dx!E%6NQn|#+KLVwmrH(7-|E9`s|FL4lH^9&$d0sfMn;7 zAWEls&TJCwS=K5g=)2TIoa_C}SkyxvpH41Q5rzEIws)U^36-`3Qkl4R^|l^MES|AF{*DW^^!ERTCjlScw=Jf zTm&Y=KY|^3-@e&kFH=9>5^F_VCmicWTr=^`xF+WuWE9nZn&&54C8WaQR)vA)HL0)3 zUc@aieJmU_TQ$g%NST`PT=|Fjx{+Yj9-!YXrgR?3j~8rQrI+H>$sr7SH;sUT$-2AS z4E(;?wf#}n{gx%H&7tmiz>w0n^^JiO?{&qhpSMi8C}<-mPq#9}0%0kaAFWRM%^>2<(z`L_VX2)3wob)(>=4JkX+)1Tc(S7b zELzy~-`#}|YPgIfy2SE_ioeEWhm2o8SLZ|98ZId=YG&^wIN>TB>RV?{rRS!&A64b) z^<6O-f)t`KOWuZA8=nv+KGfFD$i(fZA7hUyXQ07+-W!jKl1+Hlb@Os@FmvfOtNUW8 zem|K$mDF@l2#iRZDuysYy@9@LsK}W&6uxo|ng-3(qZXIRfG6n#26$Q?K?q8H9ck|(q!j$>GB&OQ5>sBPxHc{Vc>$UtaqftMjyd z#|Wj~8ZX#X??HMqd2H4SR%y{Ory-FLPiR9U@iba0KR_0e>;^OifYS zSFev`HTD$?t@kDt5WH+wgYQearoVjo5(43EMx$X8g`wr?avxXW560p`nNMc0L>d!Q zlZQ`-RpjFPAd&k#2W7F3(5Sgif|(PMsekVoO!tV)Hx)5_`w98HT)cdXLx1F#6iWVW z3wgP*sj|`+=IrSfQtm+$_KfdFoovFNW%eZ`0hJSBT;4Lr5Ma_MsOUeTK9d>a|--j znMc=Vl8WQXO)rjpf12=XZcI~+{XMY4$NcVT*?{3d$iPxno>LuZxS`qK9o>s zNpd}xYPih*OX~*cP<8yq<~UIkMSL*t37)#~KV5#(L&9hhD4H&+V)#C=G#`o}j+v*4 zb#iU9ZRMh9PC_|0E^{VbUv;w_#GFviJD`H5bqw!fn2RII)B$lEmx0&6{vO|F&Stcm zoV_W4wNlxOaET@JhMYeCK3eQo?&eX-4Y?Fbk3lBE=_qf)pT8h!>1qHoE8e9Q)G%e5 zIgD%eLuXs0lZH`|w51SrouLI}+$7VPZH2nw^7KbFVRydc1Ww}6?-7>(wE9?7)oh6k z3+->?EWb+UF+qAY>PI3<@O|}M;Hk+0;3RgS2?X>omn9_1G=Vc7H6N6`n>U!*3*#|k z7&;*ZB6~T&+Aq9SpLci~gSrMuCh#Du-CbmgI3k zUAwj0+R36>&=zj(sU&cXmb@ltwwYCi#89b=X!p{x&44P4Brz`;bJ{20G{XAikxf zKjDO9Pmnwu(;Y%6&JCtL zB`{Y4_b*kZ1kxLtmoi$J{%TdxUNROBCQ)O0mXLoAcpn<5sqDy)CSq_4VTpR1Oj7~P z-cxj&@0a`g(uPm+(efOL>n|rKnK9|5x`|W@;|(EnCQ=NE8c9ACqSf>oPESKk1#L&v=IER zkT5DDX&TJPXpuYXl@9>TxvVV*OLzp~|7be*f2RNcjn5&37^$Y57Ro40lp!>7n4Cu5 zHK($?!&=VdtQ^xEn`1-8NGvHMGV-Q5)yip#3^^<+{p$oip~$?OZ6&HWHhHfFmQEn1dZP+3$=nR?&%%CQt-tK zUB-eiP<8*m7d|-Ne>L}~Fky3m`4zar=(|h`vp>AmwXfhgIK5~jc76$lEIJJj*`)CF z2R}XtWw}@20xu0pbxo`p9Z(hPZRwWV`{}qlrzaiQ{4r%EV$uk!KJQ!HjAs*ML@tQw z(;Hc+K1x2PRr7v@A{w<6_p|z~8VCQ`XfP%H0<`2z8gGM$ZuJVBTRUDTAXwlQ+K+x} zu)ugv^SHwKReH~+UG2UG*<<1N?+}4Ek>9jn`_ciE!;=Dx-F^6A<<_6oUPM727Z*oK z;tP_AegpyVh=r}G*YS&kTi;2lx9xBTQl3!;&mteI#Qf*z-H~XH`{3Dbe?JQY3o5JL zF{EElhuOH+%=s$R^si^7;PN+{aky^P^I5c}h;Jveb2UU+DO}U|qBLi*>y5Yb;mivw zokedIidhGSmcJ0gS-85Uo+@4mWEy)%fDQw_Lj<+}ezNQC z=W6B-D_qRn&&_jJT>6pp52}G-8hr6jcS zOTZW=iVJISkhX&z8q7AHO&&W(e>0u$S_%)T>TuzYUrWPquHn<2ZLi|oWHXs$*YN;B zbI$2Ij*qEPB_aJcKC6CEJN@&AeRpKSyHDwc##aRRwypg2vi48iQ;0SpsEF~M$nDL4 z%-(?caa>x3D^(79O`$Hb{gp$jDc%@@MP9?_o4g=3jBz;gGc(d=J9mZOkTT#+YgP*t zlL)y)*?o_Jb+#@O*k6j!qbZXb`Jw)8?!KVuWpPX3f>Wd$r`YJq*eF8dsm#qLuNcaJ z{#yuegO^h_Idboe)nqf&O8LLVFhTH*>~uJaOrcs9Tgy!}6ry8pK61CKg$rX{#hy@? zlLBdHn4;M9si+PEx*u_KqGS7`{#StP`d3fKtgX$1{uOn)5k6cKq>Cm)>{={-{Ag88 zenz$-H{r8?^AHcY|L+Cx(p4wQ(ayb+gae;dx{rd0rGFh91D9fA^k%cVf{b+ZOFuuh zzd#2ghW+dtksn-g8pdA?(iJ?K5L2+fKA5O`O=9n-1MqOOd{yH5pTp zqj1mgTPGqWK3atCxl#%ThED+`VRmJ{b+T#gh_cx)K)o}9tg>l`g|vxFVj);fHNSo zr~&YQhFP>o%&YTersR^baPlvE)O}`e%MInH<_)(eX1gjR${6*`t>sd=FY;Sy2|Q`< z_P9(q*bZ1QlX%x|Y0Arx^WL?f119;`U&2m`zq|(~&w*o68#5tp=)pg{*@4#v5z<+q zrhaFxynTU7zZ+_UU~Oebs~$nGm==bZmY0Ug&f}*HZ)WH{Q9+}iB1dBTQi4z9UnjX! z%9L~vzBMEGDS5UV$5jvCVv&yO_brphN?NANnA^x9r<*9VP$sRENh}^@cHYJ5|lU`f`z=C#&VX* zrodlVH6i7uv90+3`8nO_8#5lbHQH;P+?1kaE{x1D3Q|Io(ri(_t2@kN`;DF-xH_B+ zu28(qd7eMy#`n6)#uP7oNda*u^>nOi&=1_kMIE14f^^4k^{_N6IDfjjEH2fo(~myX zuscl>xH(xJOJlWft+p^d>`JRP45gsG7xvTmo#O!AcIeUcH0=@lE2Ik{^hVjRCs>zJ z6;+j_!LFmiTGm-=-}SR4ACD@acX!`@g6%UV48AS;qbrF_G!StX7vQwpM}!Ryt6BzK zxH4G|HD(r(LYEFChSG6?YEtE&*yW}6@Dzy45-`}G&6*tS%?)9cc81eLxaCSp$n-6T zb4@vDj|F+>b?-$UZ5jdn|;leSP?@IhpYf!`6*~RU@ z(Q(5lMb?^?SzGfs8mJ|sf7Sa4-1mWBe)TY8%eOdA>|KlVc+WdTX3?NV%hJ~DY?quAwgno(`8k0duk?XGYOH9S8nHSj))?YN<1E^%BnDe*z${nNpb_hm7QnR|`yh@^&3H#EDID1FWzB(%Yt=GPE z2+t(*-9?V#KGc2T#sT%=pZ7wQVpTZdHR|-$KdbiyeZ;8+kb~??Fhthuz`$!@PmCZ4 zwTQ;tY*7>V<`=5)g4rK^EN$j|uX<_Zco8o|oKfn?o=Vslj5kZcLs^hz zAUnAj=0i~IxlopBwz*xZS5l{l28%xCIab!MWes z#yAI@aq`>k8>qOOGSd=KB?(mi|;C2`$J#q)kMOqV-sg18Dan8uuchchr9y zu5(&VPYri1HZJuP272ccH7?pX!w~W@R}VY%HIwqu5A*ikd++`+@hfQ#=eqG*PvzV>Da1<@D30WtST?Z@_p9NgWhrOLzOel5T2y}*0@}S1cA~`RQn3MZYVsW46iE-DM4IV> z@OL$$S`hnoF^yHIdm8jB&#!9j zLpHKP9RPJ8M9QTDK&!`sM4*}dYT4&^k7 z-51uYRm5eIaim89P)_2wyX&10z4d3w9hMSw7;eRmt2rcWb9dGdtz{q<#5iw8TV*C% z*le`23~#o$W%dW0cKWsTr12^FI4)C&kn|Bz7{Y$v%!OIicVNZ5N_Au24aT0jAnA8N?#V(3L6fp<7u zb<}U@6`aibjhVXw37gBqQ@d+sZ?IhR{1bV)MxbkrPh3WO9+Nl!Y@Qw)#~czAITJuZ zF_714sKmO;Uo<<*r_!y{+}UJvb@kJ-`9zGZ-~%s*YBzWMD1{X-jp;3RHk9m9!u+=k@PYj!e5ch!p@)IM(E@v9TrR<7ckB4O8;jRNZ--|I)?heM zkb2IjtZ)?hFM7lC#ps;**8urn>b~V-=x>v3%*pjNM`if+OLUZ@kV}HGnIZ{hSqcn>{fd_(uS32o)V4a1+Q5uVUIQCCn(Nut7p^LF2QV-uB8h;Y1 zguOwK0K@m;K1BTLF8Zi`h5@-b5QauwttgE|J@1qnX)3kbm>ISn+zL$CMp`M!J#Bis zpr3hgl6>c65hWc)WoZx8Frz*H$*VsBWUH(F8RWlURIS*(wX;`Z>a(8MX}uemJ(%JP z=)?1MjnAnHyDB}ZLFtGT*K&tyU;Q-cF5M8i4m+jtn^l7Y-bv6FCwxN9?Tqv6{&m+7 z)6=hc!8`}CTa>HDb0q%kHBu>iBg7Oa4L_)w*Qb3`DyX^Z%3Ed8{5LLjnOU+FgPR`^ z)tUW(4s{540Smrs=eD>S;pm;>Ob23~~lD-h>?t?-!KPP{n21yat{1q^PEySFI_kv6#WFbX1 zh|&U=n5iB>=e@)N2=YB(+EB)7J!|V)npI~tsoGx_RJukQh%((W7Jo4mQ|d!nAg`kX z<_S~l_O^AD6gk9Av=$?(uUG-FCjHL}f7j+aLt|0z#GFA@cG-uSoHKndu~G`Q9l!l!%w=EKbiBQ;T;8Lj9)v7FyE&Xj$ zG&^FcMFwAkq(&7n;}U3|nM0H_0(Xk(9ec0MhK6qyh-wQT(I6v1yAKKV)n(E9k&?7vd|?l#xcsp7hJzFUeLjuDj>Ke2utLW-p7Q!bw-n5M8q=|%kOuMQh_ zSVxoF@S@IenQQVl`+XiFv(hoJKMF={ncqR8fd0A=H%)LZ$UQ@c=#X>5tV{7NH*jfD z3S)7{dU8XRd@2pktH*_E>svV`#Gzn?--IhYzIz5_$dY*u{%eoCV?Q~^Z>=9lxf2x+ z(D|nMkb0szy9gkLicYyp!z+maTz)oSzN{)MAU9{o%5&7_HDT_xoF;i}NFNG@U2VnJ z0J-{oM*dC4<=R&M7-HHFWu5H8;5<~Yz+#;A_Q0npF2jJ8nFEksWS8nj(HQJh)A?>! z)N-l7ER@_i&WzUfRX8P1fE^eABNRz5Q&K{h6Mk>Z-$x&o%RJdYD|niD!h0(BLH2zo z6uQ5w1tSi+wdDYk8GmPX-b6O_bn?6ClY!^3+ij z&~&;)F(om)JKEbl$Ix1*a~p>g%t7)p>Zt9AI2^4o&z*zrXKr1ifYc7QIsY{I#7ZMc z%-(uA5}xm_MGz8wLA^~Kq@^{kr}1X5rE;Qqov&GqLz&@>ugh8E0fhJStF4I6_cA7^ zt9C++mgx~K6&dyC(Pn&SO~jSjOn*w0@{8tUH`~Ik3`@p;M*OOd+7BCL5k`cgeo(Ty zRLE)%n|NM{D)pA>Pe$p8IS-_`X)-22b6=uRI>z1qqMbeKeb4Y8?%qT~6nkKzEFh-#o$260o%5k6P0=hv$Dcy>KOrA`ZG*yl>&%ZWOwX z@E=5u%9H09MW72zSsCHpPiF_7T|c5TgwU1~+WT#9$pd zbM33ZH-DC)e@Kem`D&ynnT}Qg`;CZB#V9W2gdP?wjl7|}5BR@|Z`;&7dtfVXUyGp_ z$nVDz-d#{Bh~{c#!dxi-^Y2K239m8FnbGH&d-GF!j(eZX_LiIXHYuaM0gG-vlBh5Mu&rlLSQ~$9 zMQ;4VA`=V!|G-nH?O>H&G8IzEx^#s!7gTaIhA)3_>#o#yu(AG>*(r z00}!i_-^9BX}^jO>4S>g{h}!f?!7CBFtuhPTKMd!47hAm5Heb!{vr)qBWWP}K zdEl4L%NByu3EL06SLmj3e?0;&%i2+r6q)!^I!w6Z)IjSCn-oiui}j_x;#GV}dJXK7 z`@_&yZVAR1C|ZHjF)-6q-r@&LMU|EIJL4X68{xa=YvunVEC>H$Vm4(RX8$(5fObc6 ztPcy?!IG%6hSA(mN_WAW!aBB|a)3!Err$;5_9gRTPY?o8DZze}yvY}9Rrzv)4znK& z0mhIYr7@VX9~9DhlYlI0pR?Y7H?%1<#zIYL9>ep}>; z?%9oBo<9io!$rWC;F)s~vQ_pXBkE}N^%9b?RC8h8{w3E5#RC?wT&cRbr}t@OKCKnz-!JG4z*51;-j+rTfODi4q5GngdVur8q)JWQVb*fSnQ@h| z5!BvPMLs*OvhYt#4E7n(AXYO=n!7KZIqtpvGn^;8s?mXXn zeT_47meFEq+aQSPYhuDC3PXnIU~-WLhO(-^~#d3Wearo)HCE_y5D71g1IdW6VnM*u)`W)Lpbs&1Fq2kjfPRS{bup z>dLAd$wRXLxd6BGo!>K1y6yqh;yzL1TNCs`sco(OGMOSGp#K@11Acq~E&Sg;;X9(s8;4^pZkvO1tnA@$9@W(REEUzxx+orZ zIWJG$f4M4}E5Ez9^;O73$;B1@9)jy@AxXbtv?gBBnN@p<`oI^md&>A=>x}&aP%+VfXK=c7+&$-Uf3Ab?d+D7A0?d zuloHoUy#v0#65)JQqGxwAp09vdI%It!xjRFEa`F|gpbF$e**S^1_}>P@rMQv6$yi4 z_PX(t>%)3{G-Cju9#KZoJ)JKm)~Ej&MOsJUGtbDlgmWN)Lh8{!aSHj zM|P;SMhnTYx(iW5l)LxS5ZY~+1+Vl!+7x#Vbx^%!?#~WTh2-r`&Fe-#rxLn??l^iJ zqR8zu`$68YxU`3FMIgu7_d-pxhnLqqI6Aw(KE-dp@`A-^8jQT}>Knrf`SFE_S0xZi3V5O^ z_f2CH6Ze|l=2g$;r36P9dZVr`T-E&QUM)u3YI+Z$HVEb-(~ZJ@sH70!LC{K9vl!m; z-p&pe%Rt#!o-#0IGuQyEX$0>_iAjRc;BFF2G_$NyWP%8;?~PAmDwEsug8XID+0I^l zK9B6wvAxmLu|5CEj++(=wW5qHx8-U6RjV}bo@hOaC4w=$*U{}UNqfnzt zshyAmVm-lXLyFYRnJwjHB0Sl*%>N}qGAT4mSTW4PkWC$epGeIKF(oCmn`}(yLdg@3 zvto(Ex-35arOg3-W9trg(<#j)yW07P4xQm|(bcI2^Oqz(ka)wqGxD7js_EYg z(x6GHf|YXs@4GHf9FaGkeygTMjobC=)UqLH5R#PM7COAhP9=O)^N zJ3&|Q?;%NvtDe=Ey+1cQqFcBLo3qLR_OwHcE0p>8j^PDlP;d#m>+Mj0&7!^zD~9_} z_7wojHOoGD^OBA22R%LF7-skTKOOzBaz}RD6!z(<_o*JbbiynBZJw!yx~=~VEs%EL zUpbG;qDJSrY9Jhk;qW#>Fb;50I^z5x3@!kvJjL9?g&fXuW?W!KH#rdh)S>*vh&+7mx0Ua+ZHYY!abL`yG9*N*`uN5s_6 z&%M2mg+2dQ3}@jIiCb#tT4u1V7Cj{FNeQc0^~{aF+i6nyL^~TmLPE#Kd15tti$+Bt zBW{M+{$4qke!xLkkgUyOWkkPr{&ln&_uCRn61nuH! z?E&N`{GsQUtN2!Abv?DXLh0*})Xpz_E^9|8VW-d=>D7#%;=Pjw7qxM`|4-|I@& z6qF3;X2I!EWqfQsl`We&D17P1=b8(JXf(>0f=AUbuaLvVl)$3+fLfdwK|;?bIzbE? z6X@L@dr{cu-oa<}>!#z^m8zs@R4V~Mt)WBgw{vEj0+SkeKu->N8g@iI`P!|cJ!Y|+ zM08bpLs1^j%cdB;K66bnR1;;#mU?b$fr46H%n^p7#X;{NyDPgpOYsjq7SPcgLC)T0 zbH~o`8bf&RWXJ9q5c|#g zWJ(4w_AUy_k}mfw-T()Ko_mG>gVo3#Jm3otvi z7r4hy*wFzFuoCav=kB%@WPm8^=zg7qztDw0)%D)V(<8qR?ikLGxLb?Jy|KxL3l`+X za6ML}mCaaVmu>S=8PL!EwZc=RuXZ)Tf3vyPZZ+LSwm^nj^#03pv_)gE&j3-<(w zcwq{np5Z`y0J28CTHnEi5Uh|o9*w#i(n&H-x3>6tG>O{#)es1ZRP!#1Z>-I8OzhKm zVR{hWWB>pFJE=v!#M|yET#M}3qunTaSpBOB^8MARw9tFO(C%>B;D2H= zF6m52o)(`)7(%&hMqca9&jWmGfwTH#u)kEo)VW0MH-5D8f?|P_4wB&r$*=6fdY5)4jal6o~}mx+VV%} z48$sEvm2GOeqi7iDV8wlTvu3%gqz*hrOqz||}CVOwJ7b;!@D3#3ASg(Y2w>YV6W{Dh~2`uzHoX~*AhUbp#c>qncH z;$t?P;dap{OUMt`x8OyW(ZtR4g{aB`U{!x1SwXP#v$1*qC?c{WuvbM`^mFr0FPX|} zB%;KA{E{yBt^`{x692>l1Vm^{-p?6x@Ke4BsOy@Yf43~svh!62M5H(+&7V}tr(A{#ACLLEobV;i`b+ltZgYXvWy8d~N(3|pH3+EY z~8~8F|UHyL#ZF zm^1n?Y8lY_+VPKM(VCuiN~zGoApswP@V`$VJNvbE=g@u_ z;F&!_Y0T5hS3r6!+<)`ot=UTphqWahZ>c>`zj0Kw7iD|M#iJ@k!L--h?lKA?RZYl4 zj=0(RbCyvxY77*DI#d;vp+3bo)?2_nqcx2ivQ6iQG?8XH5>Xu*sB`(>V%*0@OQ7B6 zgVg|MbJIP2S^4%`$3-58<{B}zKKsR8G~@aZS{W|*Qce{VKoP~oN!}<~hZkV{{R{0< zv(kSg8Giz361ASlabmnal);YLT&hoCB_i0cWg&2te*kqq z?BK_LQNfJt*()dkOIY_(ymIQ@AuW>ocovwA`oW?7 zxllbu&TC@cbld1*J0(Ims|Vc}ea%hdj~j}ryfsT&D|=JV90v<7W>c5lA z&EcaM%0yh*3E1Dou%95Y9GBZGcM_=R&Y0uPU~O+P8LS4GEN53E`u-Euhk$6SrvM;} zcM-qT%8rMYI$n1wSw3_;AK*7=lR6hjqgGmE>TyB2&W`oCo08`e=7=cDtYH<=Fa&y| z=HmWAfl4%B+_5yOy3rVKZU$luAnPOWc-^M(znhy#X(7RGlEbhUH=_^GyqA+SGRRj@5tG8J=>ADkCIH?TH3Vl#);6#Cb=Ajpi|Cv0l2wY=m)OPnOR>FMvnNA(U&OHF5_BzQI)9E#WRqbhx=4P z7&~^VdBbGSdyl;ryz^(HBQCnQ$A3!kxJLmZ|4*2yC!-qJ(*qO7feWbnHqE_P(mSsV z2OLYiAIdWFtMLxh*=j$~74{|xP8X>1-Pl~SO9K#y2(sZ(7o4$~_wG)|Cfn-KN72rx z)4o%YbA)>;v6AqUBA-D4eI%Z1e>Q;$_M~JsmgqmHQ2Z$rgLFfw+190oIp$G;ubuSvYFvhiiEQ?EsOEnv{51B62cQ4uZkCnw-}^-P zE6syPKd0HOc=-%$Ye0-oOIU~~ir^aEww7Z!fu9C|)cXZBxLS0iWY;y~Zy-!~kFRK? zLPQgD2n`-M?Lz_qHH;SDGHeFfAoW>g-RUtm&-4n#qhX8|ctLQ}(xY4q>cR${6aNqT zeNjAbpnMc9tt@==-UE-t9anzbqqMscFH$OR^nj5z&ZxT}p1uT>6e(8*`kY@-98sl|CbRo2;mk&aG|{}QxYG}J#0e-nt`{ayWe z;@l1`-m_knB7(??S)lsmkVt@H?=z@iuTR1N!7T{{HP^7ixicoz0j)woi2p^0WVotk z#cIl9RNV}IrwM=`Px2>^stc=jwiu+2cZ;6Blpa3O6D(p5Y=!_x`h#rcpUp#U0=o43 z#o9ng83gO{VeePM-_Xu!PIP&Xt>z&#DRpseZSA^gZl39DI5Vm~^6)N8v5U8bJkR)#R?1RI^$Y>)cA4*sK^k@VJ1Khs62qvUYtW+89-dc7d<|7WwPmf zm1X9e9G|1NQ1ZY%d5X5f(8vd{2?%8{7$MQA8iAACXBf&reFRd2lll&HzrKrNcV#a& zqUjJMb1o0Z&Eqkh_rr+hAUc5W1vZSIT0rLgwz$mnqz06Ywk2bKPA2^*7NwOJN|y%= zt*fjtmd3d;hz0Cgn1IkV|CEr+`9y`Ucy}#DRZKI69V`wLwD@s;!NXmP+D*!*dagW@ zsON7f@dn~zTIx-^x7sQ7-mgQcY9&p1&G{Kf%~0i&0bIn*7s=12!rrN^#BHnS`;DB} z4{_qJ7nSQ;-oVsia386vQ`ujP0qS;PRN0e==T|b%CR;wI*wND|-;B2xIfcyVUKssL z42R;W&Bjmk`WB&@#u)=2QqtjcNG26D8RbYkFa#q8!tYe(?G2BO?QOp`3$AIJBomF- zyP|%0%0CQcz^85lqAFpKJi-DJ0U#O?wP^$@V)w;F8g?ul3yF=7Mgor$K3`Q_JH#RV z?>V!rs8i&Fif`w0~jF=M0{C4 z0D|4Vr_iHK2hT=%)lmmtZEI|eU`%do5@0pJPGFQ7O_|p(j}C;L5dY5=oicsDkN;3w zSoqfoaApwq9VvYMB2CCvQ39ZI>=f^$y- zdEns4+t0E_vWpuSwNMMzrU zC>EkOh@kOki%x7hhU39`9A4wA-_+#gJ^;H~Tdw2C$5(9g-Hsi%f%erQWgG$-g{;=W zk~2zZ%@)Jxz!>WrKq}ud&|dRUC`#R(916SloA@wq$Y#kxgSO6G2>!$B$#chd>8`R^ z0G4Bq=e_qNQsI{_WD8`yS{7w1H>Bq?(5fkgZVzU^FX=mMjB%Pjp z#oj239aZJ5){q4tMao9~9-=f6@Eej)a@&@U9-WiUyAxA+aC2JbE^~&u1{T~e+p!_9oBXWOoZ(K%Hvi5Hfzi&P z7quuvw@%R`LQwA?a6j6pN6zbkMU$+GzlR;Ia_)8+XW8s*0zvvhh>+m7Z2OR9>}QNw zd3gwI`}gIia{u`q#Qr)^G+oh{OO3*c+9`z@1ujh7(-4=H@nOw z$^pjbH#P_}Gg=&tMnu#2^dE7NG=AKa=V~Djkqi<;J@;2AjpP|RGt}9nGiN2cqOPJD z@U z`J(xGxmfcwnF!dO-q+A74)d&!8lT=s0TTp*pP;kMQlEg{>1Rr#pH8=!C~b4_hmbaN zN%C)|)65LnI-COnISuFlQImVkz@GGE%dgJ@PPPtDSwMr@uUI3%0}=PAx)@vq^x|lS z{Q&(hrfK`YKq`q}25(?Bk3@4$RX0v@>0izTvfA6*q$0jF?*MLTG^C4Ji%yN$Puw{# zDRev;(9qVqTI4FhiqV_{ci{}X7pCt;AhcoByqnjgObDYU8InAm(8jU@AoYP;?ObCO z4h7zcc-5sCST^;o`2dIrPJXXRt(LPk4!@)O2Ue^@e?|rB9kE_x28BRPNfd;Po;u%Q zfSKas%_1yMwJ0#odzT?I;PmD|mL^$>3%e1l&=bhxw*l2c7|o4&juttiiHYu84kGOT z@t8W^^wH17{X7Yf`mt=Dze1{xcZXCG{=gILrOv4O%2U)-hz}#pSeqS+T3ifUhXY1R zHgF0gQ9rTSvxYyY+rj%w+b;@I_>a&SEk(4UPW41<0Ga6ex%22wk7KzS`73bLNF&hC zlrHjZUtnsX7XyBIjlGoyMAsHy#+6GAf{mC2UaeVRI>qfzsuE+3MWM=lwt5$*ysf80 zJ!ftM)1&9id@AdBKxt%3vx#~W?RL-rQJhj(I9qY1Dbs+zMKjQ~`ZPTEw7mMO#!^=< z3Qt|$EvjCOxJCJ|iK}RI^E;1Y7pRib${O?6mE6#`2RVf_G4(95z~<_DD)<6yCl=v? zj!vIhj75CAOK`6UMJ0YV-d>%J(VTG?I`W?h15_$9hN|f->QdClR$hkV4?FPs_U+kh zStLu5^D)Nf&yYt+5~~i91I)LsXuFF$4HE5hYAGO)tTT5@O7R3rOXy`+PN>Kakf*J4 zbRkLA{PtwEO|NgXZaUl&qgHbx<9GUCQCeMg*dKr_ylVE$68Q5N>)7g?&Gc7Vx~I;fu@=n{J!pTWC=gxAg64>%*_QAr!@wX%Nlg z6QaEE;Or$>)LT5aZ0a};Dx4@KhWeT3L$I}RcBj%un1G$_Y(5%C4m_I-sVGl{FT{Es z2AGQNUIhcK6n*Cr44dds?ILz}TS+n)DAJsGY{7xieZA5d8kH)Qrw?f{udt;`>W?Q< zEouzNVN>TAkQV1ae!eP7J#dW5zfI{QUQB=UA`*6Ekuut<7{j0tV@&}{(#G@r5Z1vr zav%!=&k*2>%UaA4>|p%3F?0*WVIa@0?3a1dwP@;-E?r4Z>n6DOgm$tR?D$P#WVK}^ zDpCV+h5^7sS@lq1?mEOGER8RUCFq?^m+FK}G-clQ02NgM>cr4!FX9OK@bu`Vf~cp!l>Oz<@l4ukIj52 zAC0Y-J^$DjqG1Azv>=3c7WQPDL~&!UkPvVSKpaUwCA_C{09ak>{Q}hduoq;Z5f6a= zzvL96ZQvbv4*gl?G3it_svi@8az@#%1LnI?djMco2j2vS*)SuSUg9NFvKv`W=oakJqgbNya@l+Wt=K^vxD z!TR(=_tE7WO+OCD|Dvr0dSMyG3U%kV;YFSMyzKz za+TR8U3!5KTzn$W8U>3JXS`((?*q$E>%{*#bNWlGGG$~uM*HG1yvU`hK#EJ6O?X%{n3f1C95{#tpT&+kG49PdV3Z7w5ruZQzL1Nt zb-4gdhST3BDl8uU^!vhO9#UyprPxpNs_p&6mQml5Cy_s|6-2dr)tl}8eP|Z9TSwKS zcgw+y=fjK;Y!)qQHpx-FnpE>cP3PYaDR8wjjiFvRPu!EoU!zJo+GC%9r_c|m7KFu> zGysa5Jud$KEcnu+c$p!0A}a(o(QwA{UbZ_{VJCN|QrF)ReYOfH~qJExbn9KPZN) zJ_i1-N1%>my+f4K?@Iw1Ja9$aom@_mxT~61oYXFvm<2+d{LgH;=k71~=V^~C_}G=o ziALs8Umpk8=(>rWkoLb|?LxbLf2AsBiCkVZ49yhl91G7!JIor|4>#f2!+-v4-g_4f z;0EOG{e6g$XP3g6<1>a*6_+WV;xgFez~!e-c?NXE7;1?I4LjmdpD&@)kFWa2D5^w-jZ{%C#vnR$5oFnL}F*2{DpKVVmiCow<|EH0E$PAGZp=wVYN!j`&9g$>gbFjFa5Unr#{DoRkZITtZLu_GKva0Jci0W7 z1Fd;On62&A)wTKlWE-ep8194j&Vr8DSd3(+U!40GL=`CfQWsW6i$i1gCiy_55ZQ05 zspwJ}>VcZa-b&8qOBn?*WUiTI@j{|wqJ+|W8tkAx{rs(d$R;>(W;eq5-QhYU8>m?Z(Czpcq|^$}u1ATRt@vMtxdmIsVuLJ)IE-N}w@UhCxEvhp4l|8Y51>!LpuKXI+6kTVuVl6g|_GZsQ0 z^vjfNp1cr9>(b3iUKNKo4lVbb$d7I_phAzUgfKGUtNt-KMoae8o>R!~=H~HaD|*O_ z1InL6)ei;ZeKKf~6njST<3~NgA9$y_RlVpK2}%#-M>`P>us@&Y3*7G61wQ4?&FD#{ zN56hn`Wv7h^hxvKd)4>upE;YQioXO4#VhrQlxB<*T~23$S75%d`Q>ldmf||3yTC3a z_D1|vat`JgSNZ-EIGHru&gGd1g{8(qPS7DLPPZ%qC!^}~>i}IGorU)A{F26PuccKJ zb3^G-8H1RC;>RBgrSER1ka)g`r8Ex3PJO>u9HQJ7?~1#aIIw{{ql=Zyya^cYbhqC$ z6d;{il_#Sf8QV11r(9Au^Dax5TWIqx@Sivvup4sPZIO9wK0id9(mx+!Bu_~jL|dJ( zc10_(K6O2-ME(N6+rJE@;MHhU-+NJS++-Gwx)2w;wR)m*1XDvfj_qmhArgsmG%LLt zi)vRL+4bSJ8TU5TYVYLb5^Jdq?5W(v_awTl&F;+Gn-1XX{nT8NZ71wi){9GIvU7&! zDzgN5=Cj1Qu7x^C=B|FF7GO%GX8=3ILD0@54~RNgq$ZLcL>=8-*$AxpdW==GRW)Vm}YcxqjTh*xE!CtD# z7eGP3%^)S$k9~Xa^D0uqkL-g&!72>qP3rmKFPn(Ks+MX)#?^}T8fuZf913}{L-a;B za?Z>#@MsKIN*R6pN-aF&rwARA)82MDm2jtJqT$HBCJ8V1(-bl!Uk_#ty7mt3pq*M2 z(qF@jz%T}40i|%MYl}azyx?z2vV%7!Nko=NiG2 zTgw~|uxP?Pm4IStT{GYO2)wdwAvB7y&wd^4VA;io1Boa`%N$ywk@*;h_p>WRDb>v* z6}L>KENTu#tL{iG`U+!PaY8McZ9hub*>X&HPS}{t$M|K-BB$>K(-Ai% zuWC_=KP}`)h3Haazn=yecbtG_?f=nq?%_=T?;js2k{FRWl%|vsHRn;(sF+iY&`>dQ zSaX_Va!8nb=8)z*R5lV*%E&p%B$-o2hAD?Rv5D1qQh-Hqs?4CT+JvFX zwA;SAZr_r}7m#K@!ZTgjm`OCf!mzck{{B`u=`R#G7oaDn0IsENG`M9W(6Ii0{Q+zB zP=42$>3@aFkJUwH-9r||AAP*}%khFr#3>cW>WISkhD9d%zOUa_;lm$17+P;&B$FoI zs2U&W=6ibD`f4^AJ(uL)Xrb9+HKS;kJ>-p3`}~{{S##S<`IBBq^ZF<@!R_5QrA%VA z_rE`zL2r#qZ>ppRD0+R#?a(|g5FNpd8)Jn*uK*&X8!0UE!Dtnod?CpO*NRxIS0FYI zJ@PLnQ$N1+%K2aB&|*OW;#aUdqq4K^aw(>iP+oOFNJ~=SE=;MN2Gr6_uwheV#6;hk zprTRi2|eO9jJJ}8CgTB(EGo8mA2*+?Nl*K-U*<6z8);&E@}-!I{2898hRJt~+5B@y7yS3EvQ0zS97Ux!8;E)bC>&Zs^41`tKO? z%Wh~tiR65MkQ0Ez%L{(>D!jB0YGT#Czf0yM^q}$87+sdkWY)6_)V05>tAX<6kp!V? zHd$jeI1X|E|3uXmcdTvsggY#(=z&c94YT%Ct$?=K|MvpW*SFqT49uld##;1xZ(Ta4 z2`AIpA~#S{z=SDz{Ij^+{9}kYENMLS12+FOYa@cI7vPqKJ&NMLq?W#r?Ig@^uEZaG zXkmWEQArBQPYE%MU77jreHd!FqL;GolHlC|j-~2ko;~Uo7AaCADe#T)56}t(nx4Do zuIvIT6=;OG)Ka(3V5ffidC|jFp4bs^Iex3L7~L2bRJ~Oda2n#FmHhT@r9$F+FpdE*gdCmE<*iOpRsitcP&4b)KXKlTXy8pBKfk>& zIk|9QIlqk2pc}88?)qhKR=Vjr`q=0ekY{?;F$a9zQ;8oK46|2D$Y{iwOB19_Gz!nD zI0Q9bO1T@%g1F+3$z(Wr!@kp97l%BBZT5X^&Jn%%*^}`CazinA3jG&fN9n3OCW-V@ z2k~KwNrwt8aci9`nm>#@qwjdb0Kb4na*Mw_=q%5q_f#4kR-9j>w=^yom9)Jpvft}${u~1sllI?aN(e9@$h&riU1EVzdZ731Q#|{!APUC zpeYjIPT-LV#bKj=)rt~?7**(Zw!+{N*7LIT9ldFg(iscV(?iP(GaFHRby1sJ9A{Kd zxbbH^N0c{h8aImYApQKAf+-byqEU$@RZMt6YQO-uE24qY1^nra8##B$!Z1|x-bmAC z0WGfzZ>=OlBf;GUUQ|s5=+6@i^#{X&`Dj`Ccg)(gv;N7zL5RGU@Lf!#C0ZmL2b*+4 z)6-==PwVXq*0T>6GVH{xdri@==?zY|8bN4;G{~RrJu|_gBuLor_G5`3j_(hi>M`H1c4J;l0 zo9;-5<>Z@-KO7_7GC13pinCNYLP-0TjQTqKHS9JRFi!=%FcWc+p2-DL)?me{ir7KS zdrUQ3=#~Lq9Jo?FJte;a)dD3daxfZJe~RJrNxWxpjj1LFDnoyBl|f_rpgQugYPGTMtSZ z3vE_S5XHZCHYj*8<&U+|L(hil+c4=TRcRZJA5Qa}&Kp{J$E7Igi2jNrXco$0X6QP+7Et{(juxx^Q zHW>x>ONXE8Tj#wgAWK$yeSz_5F!iqe1|dA?L9D0nQG?&j;@YW))N4fGtQARDhoWq! z!4|y_VExswe41qUBfxHHs)V(GhVmlRe<+WHE3~yEGR=?AhZ+{7qvsyzUNygLRy9A8 zTfO3G*ciT2nxYW7@+?ImAE2r<0ExgAr(?uKy`bV8rjK4Vzy*uz^H zY35(eP}w$D1wd8va_x=~>{g@@)KurAj4^Z6@Zv!jp&j};YBl$cCe+LH3s{DyB&~E) zPJ?U2Ifk&_ubXRWRly$0*D6nz~a`a zY4`_k?a9@JnOk0#Pxzp*@%Gp?oRm0Sn+cKLxm(twGWi{|IB2xHZ@NAtcXEK$6P#7>4xE?>=4%%3GD#J8xfN@VOw)oC|W4CK*{Dl(Q3y`h>wrNw$A)7 zBr@lo^ryAW*9=3;mEz2ElBO0rl(e*7Kk?^l`Pi@8JT$1*&O7Hczc|p(M-&cXXck|y z{nb-9#t_oz#G#?*YR5cRMNYJ!%~98|SCRx~vzuhM7(&5Jd0rzUKohu&it8JV*bC z*SIBK?@2TezV+3@FJUOULNpJ$0<9YLz_z(iArmh0&)4Sl)Op2{{7Qa#nKtUJ(~k&O z`A;<~NdqYX@Jx)8p5C8iXW?6p#8RI88J`a3z<3b6_B zYUoEBeDp%3QwTs24*sNNrL{gzay0n8B|6BxaB;qkuOZ4j6zcWZ7^JWLaJA#YzPAx| zN5Y{z6#<2B5W*=ZKx4*@;EYXJAJ8Z>Xq*T%1D)yu?4P1u+@*)G{#7X~j@E~V-W6}^ z`HB(og4}PvsdAa?Nym@qmab`7ug^#3WFBx{(+IC%sv=XD;b+m@m)g{yVzhXH!qZ+^}O&^k#1KPQb^%~%QOLI zw6XN_fn)j@!?rZg^dMgnJZgLOiTwT8W?N);KIyL_$n?Zi=D@&8y~TK_9@mkk{5i-V zU~a213iGCEYx9>4i#~}y_+r4jod#GQ?8AZT*fU)iCdy83QI4A+sjZOBJ7JR)b6@~0 z1WO`|G>f#Gd@0~Y%cj!J|?IGUSY*B9WPksWaXky{uysoxj6g4RJ6tfsw0SlP8`?sqOD^c zi?Y+Eyy?Z06ZLYxFNI3yaO1&U#e~({LQv|doA}o>#&H`7QZYmyx%9KM&jzp{T)utc zQn0+>k$OPZJ>q0&WMu3svJ71J_@^ub38)IRhTNb{3q?KAF^O3ot*ts8|E0zjvzPVD z9EiC@LB~m`H2*DHb3a@bjnz<Q9@_H{KztuNPA1BxAFuXceV>-}7%;^bj3g|gG}T5raXZ$(jGY&B%0-WtESf%V-} zu<;$jd1Z`*%{To0XW{W-otXsZsc^Dyrk4lY4Ed47i?5p2IeH>Cc5^>h^vStsaFRgG zQFQKs?D#a!P4|J+beU{%|HX?unZNY|Q?2^q;6?P;FC;nMg_hfMdwV;2y!s085o}o> zO8Ck|awmd0sJALsEEu3(L!bPrn<+`!txreLndfLq4d~FS18PVDiar@s=ud@<(?4I;dOr9HaYR zovT+;F&QW>Tgl4p2|hE@ZF+ zZ%Ey@L=EbM=*bI7naJ_8Ayq>d&SDW+6ZCH^Pb@R+E)4XXI=q-{_^;nr%QtNKw@lcK z-V$Xca>z`{5lc10R44JxB`JX%Jk*X^3S4Sshd6uG+P+&)_Ag>6nq47P%xw{gf^;ch za`PLw@=S82Mn`QG(;JVDPJ6AuL?>!9i60@?%CJU4(CInzsIrR z&EJQG{SF@za|XA;g<+X^O-$#Ugm(tI+(#4Da3Sx`#S6cSp>a!Z&l+=^YMSaAA5MRP zaE37fPn1MjzGL=-8AoTG#HTxQ%D-O_Z5b3Z4COhs4msuq_#|MmDQFzs#T@aTJ?-yG zJ_;)39CzlP?HF3$nR4Q;X;}$^^!fQeE{9SBMO<+8Vl+E?WoT~CH50Y|Zn3D%!l*K; zFk(&sW%EN{>URm9?rj^{gZ(|(az zH$l(IIj_#={c)+bM`@g9x{%=Y&t9!Y+zF_u|0y+W**8^{nEs^}5Ie76??WE&kX8rf zrpRX65A=SkD!N82Z|~>HJDS5Y&|qK|E8A4+{E!)#J78 zG|OU>ptrQJWz~6-y`F06iEz2TAZFy+EDfE=VCr$LPtxs$_F%Eoq{GmFyLt2Cj^DCx zr&RW05*MTX${g_?sj^)e6r-#ViCbVSH)xgr@|%=Zbcd`aQ(vJH?Ypp0$qxLcC`u=k z%bo3n#)A1jfF4O5w3vQeI8zOJ%hcnM(Ym_2H5p_3TE%2MoCgk?o%7I-?T#)6YuZU~ zhZ!z1y{b8JkZ8i};VCo_{1&D=pMi%15ebBH;9_+<;#IJ;dz&^rA%l$(Ju-Fq`_9Yi z>QD#O6m?9nYUyJzmIQ$WvlxdUA#G3gEs~O8=ois!1(XUnI$`mF!u-71lg8QA0aFX? zgM|x?h{n*si@`eaV>Y|9oedQil_nuiiLaK_{{ozAdxA+aO9jn%Z zq({9DbAut&qlt(+cbq%tkf%#7#yw7Yu{2*xFRNe$Q{F?6SPRFUqgHgVoT875=GP+m zfuND3lNaeFg2uiA_H9`8*084Bq5o*^ey zdiu+{Z{2IaqJW!PHen3JI0~g|7iILy+Mr$ODZUB?)@MqzN45fB(AWwEtCcdwkNRi) z;M|_Co=0pXkeEX9cclTZ9H#$SnhM{LteQ6Vx0aE`&fA)FGKDEicN2m0G*J5O)<{#VRuD)JWQIkfXuoEWqzdf}>=fk& zEia4pF^szofW-QIbi)*)2?5`{Xq)AS;P-O{ndUI-f(xgU+TZz52<(5|A*Jgdf1K&! zh6mN!qbD)PxrU>ZaefpF1STxtulZBc=GOY9?7kt0l8naHydp1Q_+6aVgZ@(m62h?w z)J?N6^Ac#GpmFQa51(6hoFLFAOuFWSMH`l}QFmN-P+rgJObgQxP(@fKp-A=vW2F1= z`1u>9Vz-{55sOK^0^vuHTFej8WA!~nn!!Qk@ZiBk>1u!Gep69-z54MEEUvBP25dii zBCyB&so-wsPF}xkP3Xq#O_x_xx523(mn3r~zK^o+eN(=Yn62rZ&(K| zjLpC^@Z;a=c@3)}k1LsBdH9zofeX&SGZ|&sEnlQ8C zr(@1o$bqEgh1r15Sn;@xM_ppj^Eh$E{bT9q7-O6zjLu*t!cN1eJt{?~^ahwhu$flr z3K(6+BMDw2sY4a`*zcoYbAa_!o2G^947(#vj7&vOp<`3o-n?Tn&6V&>6!iA%laiiI zW#>VoPnV`khz<-k{b$>vQN)9w;gCGA;zWJyG}aPvi1l-%A}vx5Ync%)w40iOA1qG!JT8#~y98_aroq}WvnUcBDOepzXUx{>N- zlqALj=Epo&I#f1!J-Iirzh3co4p#Ts%Q>9J$KXgvNnwhaM$LA9ql1MWiq=IGc9U!?vaE zxt0|$WRoz|uA2X&%Pi67-{u;Q?O>I?@0=13O$C7!saXVX3Lnq*nKA=H)2;Tx3V>WE zNgHGN7sDRhK5DW$+D1n3O6~>BY)o%PK3CB?_B=v}e?ki&ix_hwwwuG@>F(Kdxb*yu zE8ZjE-0-zzO)K5PRHTQRUt~nkvjEIMko*A<2#UjP?IeG$!N@Q_a2~3K8ChyoI@o90 z_>{Q-2$&heEk8pu*jrZ*i?3!ecSXv25FREOguhUdG56NizrQ`THBSG*i?nq_cj_ry z7RuNS})lV-GEfY6CCYpxgJDn3A=7O$9)H zN&ybhxuUmPym6KnlW*Le z!r=pPU-&YD;6p&_!$6AAyBzbQ{9g`TUW}sOST?SzZjCBArD2QS1e3{tvL)vcW3ecG z!jK0PQqTjePwCPCTb7dE7MW?!oKliQp%r9})k{ zYD$+Rjx>^U(B)Dv+rc1b(hXdzj0c4Vo;en`&m49~7=kfae87RSS$|=zSx4CVqSz}J z-jqt5Upv`6F@>iyd{_igw&&do>E4y1$Er9uHh+Tb<8#yc5AM%$Y;ku^ z(vjTaQQ9B|SUHc?9CPtovuQooA8kJSZm2@T6e@6!i#!f1Q0;(Mw=enVUB>s2MEC=@09FEqH*BXmR8AO`!BaS~0!rzUnLo5| zow+RZxvH%6x(4q)-3;z=7B;!#qnkWls}?a(Fn}of9@0>8)vSbZ|I2h#J$JsyKLOy; z8m|V*HZJYQ>i=Fxqrk2lyV^psQ!R@P>>BV3Bu#NR;=>*V5C3)M)|Jb-);ne75`Z)q zhqQC)Zm+cr6ni^6`#Y!V$3PMp_y)t{SP~+W9K$$vp3Px-@A&DP!F+vvP@M=KlT+ox z4hB68vQkx}Ik4vg_0P@CqN&z0de;rrim24DlQGVJ4bwokOvTaPVAbqPmta?f_&dj{ z@NV|!2ER1uCOv}}W#qV4R$)o1Fz*uN6RX^?Y+~aZ8h{x7caHi^X_69`RvdOf)Oo<^+79%cKM3HT2-5+Bcx=8qHtm|5ePV^cU=Wnk+_6j|eFzWnpwUYnD(9_;c zWLL>6T263X+KNw;0qL>rS6Zd|%CcV|>uGK5Q_9sY8zz>)>WyX19 zY;|9%T=Z}fe&q0WnH8uzkaFB=eZtxb(TAygKN6Pzw7)`b<_VBIFf=^EZ8Esntt$*F z^3NH#B9x6geaEpReV-sS;A?ft@t%NdxOs~2;WsIQs5sM-hfD0>t6n+JTC?=AXbboi z*(af5OR5d-}gbG2q- zBt*yof}OD4zMe=>2SMtxhD@brDJSio_v8?Sdiu7MABh)@1m<|aVtaF_NyY=`R^-hq zm>Fp*uErFmID}hY82R4z^X_215q{K6FE}?Jgwv5*D~DEpmB;i^1kT~&MbrCr0(Yzj|82+?KSeq^v#}b z-FW|UsEiM&AoGgZ>b!)YU0;${GZCan}+3zh9V#B#(9 zK@zD3iv#%g%tM`A0car6*pbO|c<3l6R(({i1Qg^5gZ}-_zP6Db+GKd=iiy zW3^HX8t3l*ZDVx1uA=wV=^tOP5~C16e|!FuhB1Mk(4!8JP;6hP%?{j&d{J5M;5kJx z{~s&T)69NkVDp|N3=ItkKZ13)Ijcy>d=Qz-#)kwwcAIZOa726p6k8 zsU%aD!APqo0q~?{@C89-h9AuHn~;1$UAB1zo0548m*-j;VJ+xGI~?78)f~p?RsTm8 zb{#=#4c(8-WtNat;`p1f?WkJ^fF_nqiHCnq#T|wkhOa79$u|5is9@;TprUUid9Xi+?E;yBe?){Y_5@+UgnJ}MtSMX^Yk{!g5X(A9F0H7^5z5Ni zPa#Uw&gRX_vDJ`}uUdcEy;>Td{Rk2G$^)#V8B^q?NhR8ZOVbKGR3UhrO4eXXp0&$n zzFmBj;RRSuPk_u!F54QEeW>k(SQeVb#1)Z|q%Hpkgs3yIp?U?%U1qRWiYD&&TP}BG znl~ z$gtNBAz>O0%XcC+0_5A~MqFkEF&~DFh84uZadl}OK9qnGptJ33xCsdMzbFL*?oAx= z-&f?EQAu#8Z<FXkB2qt zr;yX6RPl|d68UK6zCrJ$r~Ceml@~c*Ci5>W0*xca3)$HtBMN#8tvc}0E3FN|t=Gl) zLcgP_)WfbXFaXjq?AjGh<07&Ai~t|@_vS1h8?8U`Pj;y8gkd4rs{j%6M(y0DQ-H#o)>XT9%0Wd6c_EeTa1 zu#hnir8i#K6tQQ~Li?fAOYFDKtNKYV$T6C!=+xLZipPVu*h8~AxbTxyaN6itkyqQJ zL*VZ|h`cWJ*Q}L34kw61AyE9s9y({vmCmt5?6(RfB`VnQ7_(0|G~Af4I=3hi#|pYS z$^>K_`;|(Iq=JI*1GFrr*U;kM;th+3L`lF*x^tdN0RlyC=jbj6oNU26GT^0zu7V34 z+J``!EpmU6wM^7)(etHK$(fYl_QRw9RIa8 zk~_XUO_7Ti#T|la98fAY+HPKtT%OEC-BP%)oW^wda8X{?&#iN#TW+Q2J&&Xf``j%S z!Xu9UO>pq`XAzjNZx&z=??M9e5d#=^+@UPim1iKQMqkLyygvl{TeS|LSQT|XXP74{ z+1P6ER)4kkUDK@=$vU&W`O`1t!E+=XJ-e{FwEaU_=jZ0`zy(4yL#YJUa}zoH)1m~Ux5lFE-qGsu>)%#Wu%zv zTV9a1x$&Fab<7hd;TOVmhB22%0R#XBdN%V;WVY%9h2vIYOb1x(dgOGt(&V!_&iJk$ z=AP(M=T7bqycB$ZU%nC@VHC(@W})buDOVKiii%G$`N_*$1eX)u*xVHu5At~IF3F4$ zIF!X=qiJNZl^+gr#)HoDH99HW@UG(Xzk_>+9KQDVFaKN}Yp_QudZ4q~y6&8v(>W%} z>l=A@)_GtOlgFv`dbr$7Y`d1?2J9sXe>6Bp{x{KQZM41Q$lcoIRa@uBT&KYK&Ub10 z4K5aqbaV5%YL2o(f$=@9(wlw|OsNQRZu75Xqf66Qm@;!)kKPv0jw-p60{6!mZT|F# z`KjxB4~JLV?`VTAqR4oxXsFU2en{{dz{|C{+_I0E!MQhuZcNV4t6hv#W?VBzDSm&J z`ta?}vfp4z_>y??%n^7$sC-80 zPC^R7pD=_+zshkQb>(xltj4gF`19{$fmfVODqZ`;FbN(%r6ehGRKCc+R{!_n@#AFj z_elm56}0iB3jdysg0=Z;F+FJn_0g?sDaX}10vJXUhnUOyL43HVZ>8IO75JOF(5Hmj@PV&R(0R~fyn9fio<$$>XB2Z}=~9nt~MC8WooC3$MN-Exm`V!P*sU zR3{Ro9QvZ(FnoJrxwEsww=wLDOfe|1#Qipp6^ukF?6dpE2xJ1=rzMXV{KUj7rjG`J z!A4F1rWyciZZ2B%nVigFLJs0wElzwsFT&fPRw~}XwWs@O_UXZBWeijao|D{$HFX)$ zfgJ`Jog>g`ila_k+cHEk8n7Po!t7A#X>>R*>?m4?T7LY08=qsTXkj?bb^y;{dIHGW zfx6`m`!~7@3Hx7DHLlV}^LRB-HoCGmC7F2cPJ_NhUE&wL;uF7QABy~Z%h?C4tD)Q7 zfOn14^2}P0`piPTa>;S4Gq0Z>j!-~KfM{;e$!@XFaT5G**)QgROi8Anx{qkv){0j? zPa$ge);_~GxwK?IlARo^Kd$|WY1o)kuhH&y-5Z7D0V>oVL)%xIRaqN)B>qd$LNI_y z*!2n1(JfXpF}@3NU2UdOT&?mLoGA=WDSgLZ8haF(dU6!<%>2Orj!=p{Y;r`8k7x^E z4R71y%Gm4;wa;%io>R%_o*cTJ)5rnz@%3;%FyTJMpQ*5zlE)~<^Fhz^q^qqTCN^*F zL@KzxI_%iG_dnoAG{y8CVi;OY* z_VDdJ`@Nq9y90YOcXpQgtoQzO?XF(q?yyn}w|;XJA|Sc7bxmCe?rnwLR->&xqs`@% zz3ug=)k5x0vWFk0{szBzru#;V!tU6c-9n??$6ZZZf=%lUVxv)!i+xpPprwMHwy52o zYrBQgUA}G0#Dd7J>ZY~!H_nkOf8<8})*OwiHU&;B9$!c&yTJ=}bZbKNfH3rUJR#Ta z^~C+k{DH}-*+jx6c0fDw_5Yxa%|KL7Bw^^~eA`yv#hqXr{_71?P+&610`1=MY7c30jK3DQ9rbBMt9-Ecw!Qp_A!1 zH`0rzX595tAI_uAU^a>5CmhSiy$5jg1QEGMcmn}3tC-(!V$Z$GD;Y`6S?zlaVyN3L|%E zSMM`1y*H24sWinkEHRbEQQkQ(6ig3Xv-c-G5ojRmAWu~yli=D{(;qPPnhf%oE~~J# zL%-j0h~Uf7=&$(XSEotNfzITAN3a&bJM|J#2g~_IdSDs2i!I z!cIo?a*nT_M}PC_e3HFT;s$aA$19^`2-g%UR^|1MD4qnAg6_v5f- zRUMvL6ER2-&q4@f<|ojNImAcV=l4Im_xi{E9wNZkDAW1uAOVo^4<6zhRXKW4G4nU& zaCUS-^=rv=bG-5o?2=#-`3!DEw!%QL&X z$u=+7!CH|~ogy3bb#mevQuWWP&{h~ZlWz{(7=k%>tx|NDQp)&_2~b-d-Va_0 z7`3iL3orK;`44XkleC$mQJcRzTP_Ov`E($T$aRFhAwS$*EfMp%?Tm8>@Hw36K1pel zB>HgiOd12?2hTY9^5`D>VO(gD%jkUZ^_@)VeKp`?^?$&6`c z6l^AK5gZVd{PAQ$l6PG3N|@}muK%}&+v)e~ z1^%#s>eL*xhH1M@X#%ihU%JAQ)f71itn$ZJmaA&Gk!bRKCcbs-oDhyn$Y4wz;x(~+5bf+pvwvE`=4tac-UI8mcmrA60|DabmNnEM8SFORS8l!8# zmE0`-Mt>x4I@*<#C>SS0-GLc^Qf5cPa^Cwx;%3>6oVBjwch*q9+o047zUov7n~PnJ zC7A>7$cnt}sZHfd+kb!km1EytT_j#Mo!;_?w6TKG35|1lkFcBh`HIXe_LASA9G%!$ z*I0{bI5|`dQjgVQ3cbkVP|1b@I1&8N{(aI9Nz1dLdFC_v=5sQ$oD9qpm+;|5bG15u zdv9?x*fi#T0;MAB*Lh%_6Dx91Ko5(0opt1x9}V5K*4*}HaWVC0NYossbbYiY%sHXK zU^QYOze{zkjc`3h0kyp3XTl1vJ} zAPzwXf_gA1EqaHIzh>vF+mHJ!%Vp1_)KREUXEHEyxQ}{*#{19ovk`xDX>wy}Ak=|jyfTTo$_10;Pv-0ODeL;xi^ZVgCSBZZ;2@Z-h6k(3>{4?$F^>Tgp1}3oH0@PEnu~SeF16K<6w?B z9NdjLypwAF6s6Cbri(is+q^8~LRxP29hIZSrUIBng7NRVNZeHDJVk8Jm(u4`n1i$?FgpfwD6FaKJXJa)Uz|Qc!4T~bwt1I;}{%$Y#fggjeBk%jz zAbY-l^?YAz3Fj4X8G^|wJV8f7sq{05%A$1FSNyHJ`ipEI2V$$4EXH$5QXdS> zcY8Xc+(|tj9_wr6F?eC4N!XGgAQ~`hV87mAInc2vdeh|;g_;q2vumm}DZfD{ztL6* z?3Ky0+7*qyHMWW{v}mM~JFmM4SmbUW?7`-sOkJ$J=7WA#= zGv!N%@+GbNcer_|5@;yQT`eiJzJ}}%Im8B!cdwC_(VDzVpTVM_kLK;G*BY*~LFJ;? z08>FnC3_UX`WGpmAlby7FQN9!5c0b^YLBP1L2OvPjD)ru2xTP~HK zdL3CaChpjpD3#O`Xs9{#5ApzaP}MYRZR{dGA60^C2ct`9i*=22K-DAO=A{UIx;`p+ zr$UE$DPc4iMtcERJhYjYKvf;>A0gwe*OAI40ttz0KOZV~JZ$~?=ndxp#kwyvq?T*_ z48R4sk*sP+Ey}U44$I(_`dS!8Ss$WXD))gF$KTQIjR@3N+uPdP zsWvE$T-_)(+G~|IiVBOWZ8EwztWdQ4Ow8zCh|$($ZFxt_F-2KC#u!(&9@&&Dy0tUF zeVCNscK#?b0C_Fo#8LQU>iSj$E9{nZX{U!m!`@=lTHHCc$q!|kJSQ`HGaIwuV0d?(ZVuC zkaNxnF9i8I-gy_|N=}@hCLE4S#o(lkP2s%zWOXUAt&4nIgy7hP$@<*jGVSIX#>hMM z|M{?kP6=IYs!`*WalamZ@}kM7wC6x{Cgw88&lKheP%EX+%kd2LVATJ9PWb_bSt;0! z7YsI9@#S?1ISlP!vZm-hzbs~j9SNS1Q|xkTPcx(52ZuddEJ1KBYn4QQ_05MNuNil0m%**j=Ua_Ev<|Jo`<73Ec$ErntEvS zBmbgUAj_jP2s%(^dsrs@tT~;yGuoEma9QY=RO+2BOev$W0kF<(Dz^nQkO2 z<}NQPpehXStvf!Mg}YLJ_G6t>qF6qE_P@W<{l%_UeU-QbPSrt}IZSM&*Rc+t3m%K% zTGoO2J%$~QAO#MRPuwko(f78+cBlJyM(V$TF5QnTIn|jko$yUhj`$Sf+b~}S2MzD{ zND3NV+j(1NPHOi4?{HF2Y-VR%l&;6rdahfkj4x}yhOnDu;&Hskc^UO>r zo6v*uj}FT}7zI4$Xp&duB+?!55X7*J7RuK!^>~_#UsySzqK4s4fsW;b85>xyjBZ#{#|QY&+FRd?CnPV`|&0+y_h}!?7V`AKKe_LyEj7lr6r;Sh-=#Mp#dcmc;}MBeoS3WBMXtzXVS1W;-g!@ z>(hAV2y=gVR~S`(*f}J`@CGsE`l;+M(+Dr1oO8Rjt` zZk^8$Dh(Z0Q0~=u^IvZcVboDIHua+nuWh^nn%t6VK0`kY9UUEQj9ke99tJ3c4`(PS z0^6y41YKEm@{)v$5|RX`k^l5B56Xt?8C{qmHEB0Tv zl0rXr|4&n-oU51@eL5R;7eu4N?{S%lW~G7GSiD{V=K2?2wLWhn!|`zcN7k=He8yb2JL8deLLSkQ(-SWR1Vtt z`lfXG04mUBRPzsmdhhp4Ar@7FLP%`YU;@=$KH-ImL&6MQ`ehtgmj~gY6MPqryEdO0 z(1jHNqv6Z%fx^2CoYuN-mK_Pxgkl~P&d;X z=KVhwc2}bZm7iMJ#AWqqS$^E;Tpn|B8h&6@;FEj}^oSw4^HKI0^4p3=GFF67;QL<6 zH&sIW`ij>`RclC!-8^sL7VhHTmgUgl;UU?%a2zS3lDk1};2y2M@gq5-S!>;qo&NIM zda>ZU+3u@nK8HezF{<+~U9I3(_%2nyhCC@9eRbAkMg7y;ixjIbIjMhEtPOW(=j=PC zjP_U_x+y+Fotsk&hD8o?5|H=g`Z8P#J0$PuJB9dude$Mel=f%W>|?aqvUO!0fNN)N z;Emin>8^Zt6Q=BykC4Y%nmPh3IXj#|ymIUypmfGaHgB0bjXKDF@e{3#Jc^Y6D=2zl zN)q{@rj|Jr3+B0J7ajcY!D!?lj28r}>5lyG0y&qHpkfx`y2+oKP5tgo+Q^Jrwg-NJ zIq)%%7?fh|VIseoKdAiir-Zz*Q+3jU>y}qB*#h=BnzB-hmp<}_9KkiB9DfyKnS6@Q z0DY+;jZfDbo5UZ+Y1_3r?fz5P88zB!;qEB_(BAnoO%G9b#EFG=Xm2T zdvyi7tiHCCsEy9t%s017;%OOkEftHz6%BJ}#jnU}F(^oINKg)623O+w11nxzJ3h_> zcn&p<-^BR7lznx7yqk$BLYo;I9pp^4jeQrcnwf0hHeO$jdA*~z#?H?~WTpii-^?!$ zWU4HmZV>wjVFZLb*ZwiN7c zOQThogMj)m^&<>0LQd_D2HW9wI_Lh6rgINx^8f$1YHAK;PMK1yB14$-DKe4fJQB-! zA?H(0Ii{hQ^wAt*NX&Uk%=r*9r;L(0<&?unPOY2|zx(^g?{C-T+IHRd`|x@m9`~^$ z=B)45S35fHqS!vw2Cg)$eH~Wxr9It_@S%8}O|<|T!k{Bw>c6*%2>-aKET}x!4?x^MTF(DKi6iLk^7E8o*G8-pds+PO-0^+cEF%SygC;IG- z(xM@_zAIjCE#iY_e;EhDtkQ~15>tN7R^PQnS&z>157d5S`ciU_KJ+(L&lZf^(z6<9^8miiAMT!^HHL8Dx zp6Clx%T9ByZ)iw>U%YzT2u!K+{fwoLKw?5#~83yCbJzeNK*Hd!NMP*{P>XkwL=O&bO&gd_$eHb-=3Yvyl+&4^C{p;!?{15VR=7M+5|WG%?!(+5jzA z#Q98q2vU&o8a!Ef*z1&suscY`w`R>-0xA(e(RW_tH@( zI^hhW)82N}{+Z)lt;6fbTdu7;Rk=}rmapfg%`kQkcJ}@>`ZWJ@)!JRwozBYy&-vJB z?aYtZx76J%n3;~6qfGBDb-X_}q^vAsz?m$pDT2FnE*Q!W@8r@7IqvBw8_Cspa=5A3 zvE$ylpV)f%d&^g4N@ED6D_j)X4z6wZiU#PZ31*%8zGAGww08+;W8?-gg;nT6Dc%(4 zhkt5dW{}QYavw@u8@vl4prJ4lpTNnW*Y$+J?6xvRv1U!&2z zAm@5Q!mnRau!8gRSXt^k#tA>+$QN_bgG6vheiT?$&Oxenx&}&yCm%v|3J74}*(LBi zVpnQFP|K;GT=V>-_dcnZ12Gf;DIOX`i{)cw&>L&q25)X-H({1|^8{q^kcJUc@ZL4j zz7dOGy@Ox)sh#VQsqkS!fPd zsREEV$~2F=-Ms{Tm*GhZl{=mHtH~VgM`bU~a{LTDgSSS&Be$_e`4=vB^t{1Hz5_Xp z;?X69?WfPkHG~?k)Q4PK9fM1#(GeMMLYhf#OMwLxo928%>(NAwZQ14D@s-2;SF?aY zJ3I6e&QzLWX(5pS=j|1LUH>!Y`MB6kJdXbM-_7ZlsAEYl2R6&~l z%QTCDY)vszxTzmbP~YbF3Kj}}a!p3C!NT=d8lr`bB=1RbdRH;+*k_xXN9{jDx#F>8 z%CONFx23Rk4OrdR{>jN3-5YBwiW!6ipdh7e*65yl#Gj=X)@REHJ;+0HT$8dg1~hB8 z!|8**C{5Wvf43g1@wRK!=iExP8ZSvzE;u?aI{>2;T$InjEgLAkv)5Zvg2Vh~|8I}*Z7`7X zZb#zCTr!5t7~D3MUyNadbNw(wUhsexp}IFvA${T-8_O<2+1tLis2PC0pCge1<;BU8 z3a$-SoDZqnHhKUQL7caEUTlfq0EXiD2kYDts$#-dNPISDlISFhl^Y+DQ!Q0pRt~*| z09Y!mesl)r!kYN0!Y8%Kokp#LC9T8P zTAIZ4V`f*>;m=OnKx#P$fJjjkZrY@}4)`=#H_O+*RTj3rl(zA6ODS%n?P7B4_AD@J z-(L)#4&8UJ-8~crK=ZR98b&a+bouu?hsx7WR{o6$uL0+dNtb<}qrJI~&6fuTZypN!AYUzb@U zN@=P)9FCWOawSwh(Bc}`1;Lgt_SS0*xZ-7z^AAp(0&Rmur$TXN;Jo3pe7Nx%MS4sF z3%3w<-exM>80|ZA3y zv*;aDxA*8TzThDXWBFVxs`Kvl-TI9ElzYakQrr`Mb4`-qJj_LMGnen<=<7Q-TV4+K zyPT?)Lv?osDZgJC++G3ra4h*^u`0xu;CrZ8J|g5BWwJ?%o@v2uC63@M z>ZHU%xVjQ6g=s4`>=L40!2F$UH(#$bqpHf%*Djy}dLkJzj-z9wcdDgG56KF7e-}1i za$hiS2gBQH=fI;S1i8`0#=@Heywo~EL7)NKoFQ}tMZ=}kxXBhGiZK6KN-(;`IS?K4 zj@IdZLS~(a-9r~fc04O;q`I%6osi05htdPj+gte72zEi75*#V#HQIEh7l`SBq6B|x zL!mY(pdF=~=(Ej8a(gWAV?e1nfc}}E3(C+_WNR#Q^4;OUcsYIP4E4XtuWy-6|>qci6 z1YJ&I7ek|5Z1cJ3Verq7HG%BtE29Y>{F@nsp7!o_`*4aC2kS>-p9)??^bY?p8bVFs zSTg>OQFY~qJ!e|4kJps2W*5GO_}jT`L@f}ffOV^`ob+(z_aGOLtFswW2=2NH3$Z>g zjMRT2;-6Dw_2=f9T(p43RX(T=g^)PeVtHG(MfH+oDeMmN&H0njp_)H(p9i4$uTlXT zW();1yMOpo#hR$mc^nG#x)a>nzVqFp8Tle53!e^+5Xp$o3ZGwBg;`3l>8JQCYUicHD9C|yl*|Uu$ z1k6aPsf6JAIKb1X@YuNQZ9x5zPt+cI4nd<+G59J|P013|7;G=|qXq7S6KAey`aZ{; z5Qw*2aZZ+w2Irv+P~vk!==(I)xdU|{%_Ebe9^uul#N)$(sIB3?tO=hM<2I5Iq_R=oVf^f%zazhHX|Ehe~`-lRBF;1`s>Hg8EzgMBBS2z!i{_I&M?ka2a zzSa|*Z9n}iN^OT`(-^N_Z(qJzKuS=B;Vw+#pd<*o6fIYmJ80Aa*OrwPaD~89+dMx`Q7de^6gQkXHafKY zcjlMeLO79z=aH^EFTvo$UIBI3s-_Axxn@9+lBLBK#@2>r?0&&&?-Km)($$TvdY8j< zWMQ;W>Z2Q!^{}>1NtK?6jXUhic6s|?G1#59+i`Co5~9w%b&xBh50jn_ELDQapRzzI z!m_|9yNrTa8Cw3LdOZVLg%TYZR$&M_gRe3!Ie%B@GJt?NM-o6-8&tw(leDx7z>NBW zXWDQ$2#doAmBAI#nxT7~yzSt~x(OgU5V*G11fkyd=>L`Ge5hnNpFpU;_!ZOK zq;84KHW~VAO0)X1JJI|I&hPlBJ&oY6D^3z3@)CKGsJr+|f)i((>PG3SnE-HGSUiLq zAJouOe~aU+bYhkt?)#tn)8P@76R~{zHNmt8uHv)4+jl_n$UIAJcpKO(;Uf9*5Clmd z&SAU=&}P#qZvO>+_;sczmhCd>b8F^ea08Yg-#cDIhI;KeVqDx6XyqgwtfHp z{W9PUkG{%QFfBS_;eLblNn|n5B5u`l9%~BE@&o-66Df*sIkWURvbJ`r69N*zrOZU! z2!zHt+ive)n!}sdOss}KNBc%gvq_6Mv(#81_4Bh54{5QcsIk8tk&UDb3p~rI?>~++ z$b?rFUND=}v){u0I&Z`Tz+#yv#*G-xX*Rx8KzjKY6D?4)ZZssla;3l!?%$3~0KM+K zAp5;G>F7@D@pj}~b8xQ7^6^e$t5TPGtrWjAIcsiraA}d!*FRFr><5&hmX*i*i*tAE zH5zXUt&4Zcm@u3XP2W1guW+u{GzuRNclBuqst==eBnH-B)-rY#26T#A_NT&*M_PA# zcEkTL1$mvwMygz1=>{+O1ur5$z)r*ONn4}tviVKvOq_rg02;k8UXjSQ;yF?c17XR5 zFXa*>kWhPj8?+b-4#KW@J$DmQ0#BMmI3P-Jf7{}rH67s120i8NHhK^>h9w;Le=)tU)^zX*kt7LwLLT8M7_LmGE{#K7kAHo!9A;Y)}YnVRpIT!qi7o@-L zEl)>_Rf*vIjkljyVmwMf`Gl(*Zj4YT{NyDrj0ZGLy6?Nfp08RLR9G|o6Ih-e3nd4` z1(3zTl`|)=7&3$eYKpZHyoJ;`6MSg=Y{ncdw{C6#|29#DV4#fBYZ5OpLuf*f8IxZ;5D#;n$*w*=znV4nfp4*bRn3i`|;c)FU;e5Dy-P{OLWJ11L%F%VT1pj=5{Tc~zx zNY*^aN!~o%*0lQKuX1U>#h%;-wr0Rd(5pLXzP*<<>pTmd?EP`cbj8WGe^x)9-^5mB zLUno;oND9KzU7~}|Fv--N3%*A>R~cu?OT~KtTwT23+9G3RRlcg^!BcHA*e7uJ(ZQ= zfW$OZT*W;qvGn*9iZ-RtBi1{n>lz#Laa)rjDkDkfk)M8sVipg*x$Zj(Uo8Reor+;r z3a173lQ0Ys?udc)3USiIFXN9QrYjx@#PmEXJ0s)cvsaUdI5)?_y8G&4HXDdg&XPBgdeDIZj=k53+Wg}w`{is zb1@5W(Ur#wojGP{Xk*cf*tas>Dt)5q7?zN;EfTcd&5-cb&8s*wd{30)Uh7UV7e+ZLYS%_3J%TguX79YdUHAw;e*w(#eT@~ATUQb;U;bLARoqSkSD|0r!iUO<=JE58!V&MF` zD==KLA4Lx=9jh_GOZpPV)i`w+bf3LicgG5VZ;qY>I*=a@ zo-jih^o)#*5YSYWPiF6hH5BN#27Ll+(*869UF_i$u98K}c@HPB(U1zm&gj|bs1G22 zSGIVNfyWr7KU5uqD1m;#e5=&};oe`i;s5Z`6a~Jk3Wr^`w?j=<+sb4u_N*l5YKBSQ z3kXmbHtAx1)F-j)rEC(1@)IYMHTSwngO4Yxr3O9xX@1g{*tnKPb)h}S;(7wwF6%UgN9fA(OOOzyu+OWq(f^%x0dl@rdZ8N_fGcaxrN-fr05Ni$ zx%(qHLaTbkJ&EEqgo8lyaVZ$URt>!eeya`n=rP{n1!oLtJQ&STGY~wb=%V`wvzRdW zF>|oH_!)M)sc}%V1KzU5 zj#T)l37?AoOZWx@=^@&e!gJ#MK(8K1TLXgIo?Jl_rd2A@f*t$g*J8w)%-RB&X(1XG2+{H*pX3gZei^4h^CwSEqBJw8^Cv`=wfKy~5;_eNz z5=~vb(du&Px&+A1*`SFV`q^w^g8X>D=l>yEFxxBXwPLu?oY`>9*XHlbA!@e2x8sNM zydHEf?Lom}_*bFU2IOeeH0RamI$v^`V$!#%MhkywUEjh2wHy=RpbWmEvd0p-n8Cvd z9WQ(V(}y(_zUlu~djknF*Vu{}QfMsW(2kw|NdNQG_W_E8LjykTVoO6`-*b+J;4#jt zU+%*K{Bo|}NVV+mo0uS6Z7=>_npz5uh2Ulog=k69x-i8ug-%)z_zfWYhXQvxiX#q~krd2niBU zgSs}ci9=I~|4i+9iCl+;ggt70U*zv7rn)d^WB)|*`)MkDFsne0s}+XJMxqtAkug zbiy~LLYw@hKRp!s%;A_7{sZ$Rf?iBjF*hLBf4cT|y@6k%eeMxC6r5dWDW&nqhk}qpCsZXue>~{d+&$aAr!q<+?4-=l5dhZg< zr7>`;05;j41Cb(A3K;uBpf~!zq%b&uukASAPB3?0lx2Tzkgis{%m9C2~-g z_WrcTj|P&@ItJz#v`hm}4;iOig?Oc6ZRoLxICn}L(2GSP znkQ(6(5#1+I+h(C(B$Na(=L1pR+OVCHC{Xdxie*A zEAe}GJ?b;t33thZ&=|MgN;*>ZnFxKsTP8M!T^`vDM0EWl;iRRApr(cy%J-yinmETL zcpms__p?vG?)hqxU96h|rKwGVXJYQsLJ`1V4v==C(FA)B*n2Bk{I^=+)}UZb4j6I+ z=%SUtOU6Rr*BL^ej!54%cZ{_B+XniYD)c0W6_Tpb0wOiC0miUbDv?9_vaS6MD$Asm z$2f^C$8ok5VafyOXJ7@}IXu6JM(~c(y0;kr zG5l4-%Qaa^OgmKI@e{cm^vN(oFYw3db!29-CSlr?dG)$(!!cepZT?#>kl_& zS~Q4Uiy;Qwg#;)Ang_exE8Z^70FS7=efn(lEdkv^VN2sY(4|4e>b^G6+r=+Zxj8$4 zd+wIy^!Ch6+oZdysy-;%MmZRuVRGxC*-cHKzMW97y`;QR?nq20lF-p{(J7jxsq%4% z7phzl>%@R5x(&L2P8PEw63HF#Ydi>1=J2Btd>yI3X#c-`gcRfN5Im-u+{yPt@@?|4Odrp`Jlt z*nSK`O7$xK)|?3A&wSe{?NCIVKJ5R!03+w7L)Sa>lyN*BUj3b+QCtbLNP{;hJGx?# zg$D_$Gd+%Zz>xsYHomi-&39#sH%P zS>$AQ9$a7Dz>T!>dHQ>XNFo>wwX1SXVe!ZWsQF``1*tOYJX;(j!?~CVi1%>Y6E|bm zDlhH#D~()ms-}O(n0D4L_Pe|`kBjpsi{l)UQjzBlRmk$GMaWWOrn5zH&oF`q&~tK=MP_KTezqDNYO)=-%-dMjdVal+BPh?0Tpd3lu3pH zaF#_-he^Wnv$8VupXx7jvLbjV0Q?@a{}|6*?cp2wYg|uu4QQ}XTgMs#aE#B+yva zw|exXbq;;}_w~T>?;Uv&!2CaQTF{lQ8dE*4qBuBFtZxdfvD{?&Y1}2R;*p|E8V= zxhS6I{fUh}IOj>nCQ#Ll1*Lw^J`=>=X8VdFul#BfKvMbIIE9hmDV^_Qccv*f!YKZy zK6N*JL0lKTjpyby6zl>!B4fDlXbX?$e$dl+$q$+mdR5k}bA1h-T}S)V5y!qc>7inT zyKsj$?76X!0E1mk;)#o*cvB#sCXrE0k$@YJ(I{U9656s6B@Gcnu+mgN=mx;)s_=(j z1hK!H2I^nxLW1n91Khsy$waB0U8RTgShcJ~^6UoBZ&vV}Ny^ zO^ojWLy(G>U%C12Z?NXUM*npmmE2^d?4nZ=y88M(=aJo$neuVUNmnB))ZJ$U7UB`TkP02G0*EXO%F8I{Xccd8oc*gk=VR_(E8V3vUz+Ow8Wz%44i`L~v6!p3ekr_tPMAnkor&6%Q9hgAFCxKn-y- zj*EE5+i=l3o|0>W?c$^iQ#fB9faeo0!sjIrAmncZITAm^$#$e=y}vB4-$khHI_KXv z7;aaMk&n`nELv=xFc9+YL=a}#%}!Q~u1*sy1!Fn0!l@aG=a0&$8T~3-5$OS#FGw~; z+Jenu=sUaw$^0&bK$M%if*Vx0VKoCdf&zM`)EQDA*4(9Gphrg9`4;}O@3w(OnEVeU zzb9BIeLjn>^N0OGzLc{n^`A1(yIA`|(-Ysc(te$$lZR%$l zA>GPmRJ38lw0y6>G*IP1xQ~@ZmQ^KJQ~*wZ-hLG+j-5Wac4(atrervyZ!)rV!ib5N zz1+x+CCcypWWG-x+Ut9tbGYLwe7ur-7@lLi@))H`TC$b0*97d7Spuy)!|8y#NJ}f{ zT+y5Xa%ph8DD-ChUZ1P7a1`@zQ53U}0oW>mK%Y2CAA;$BqLRy16}tI{B;U8Z)8vsA zYF$7e(OcF9^OC%Y!Cqzeu_EcO%!7LJ(X)6DvM8?F_6)Vl*}6hnCLQR7xeIRwrZyg& zKtQRK)DC?naDmDazl`^P0Y@9cu7IdrXm)Cy7sf%IMN$ZR1sA^lPZUL@0c@H2dSn90bMVOp4dMUfy4dPPLsE5scVWi!;ezq9k1jD6Ez+Ha+s zbMM}F$Vo_JTurhnH$E0pp9VpGxholqioJu|&J$L{`;vk8 zQdU^_cI744Y_H$$nq%JRM=#POL)lfLr-0V~ew;J{l&C#uY&=N<7UI3oiC>&x}- zE@yY((+JJML=K!;&v3{Y=O?#)dq`$aDyf+3(5nP|$4vHh+&l)@80v?r3sRI1HcdfmxK{rT8K0de>(F=mUCiNT;8fnjXOr$>ynda=IN`~3LX*=U#i{9 z16CS7mG!8+1|Cf;o+KiUgTow`0LD63oBwIaftD3i3BEGaS{zFe2`PK;5*vQdB!%u_ z?%ozZ?GG6R#m*!Pw;p}n*9u`I)kggpYTaYz9{yaIU0bWNAN{A2wfuFsbGwC^b9Qsi zM3X`j!QpLRc3o||jjEis3t8W*XdbtJIkyC~P5X4MuFl>y!Vi)Mln8=O#7ih>P;)rt~r}~}ac~HWK`|3`wSQiz@>USCX zhk=Xoqv|~#%-w9y;6cHgZ~j2^MqdPU)->l%P{(V@&rl~7nz`|^Q`Fbe!mm&4(wPcg zaej(5^Gn3or7nd5G&}xP<>I36NbMz|K)C2O?nIk*R2-tEp-C;<80tuV+{^uFoF%;k z?577Pio|CeC2m=KZ6v%UmbUUyFs@_yyK*-3T$%!2{?Ydnh3qfycukzluY1Rym!^83tlBeKpe6zdKCn-wg50T=P}qHuOi;S&EIWEG|>?E9vpGcq9xQ7<@wh!?! z>t{J7iC}AMvQAr2c$^&^lzCponVklwcFl2P9w^r;&yB9uTx5g;gCa}ByNtI9dDJ0= z{>j;w4trFO_m>8W2y)SHSsC`4hYiC?$=WD>Ck5JCP-7-9mEg}V_mKQpH*o1mTd1^X zI!}`f6!Bz0^#mJQA5nCT@TaXK@U=s@My{zYFqB>m-=L27%R1nbDhX!M?VrT$P-9#j z4Ev}g*`N4SG-J1%vIYAc+}JqxACKC5U|^FVFv43#bN9*K@0BbQ&HaPN%;DM2>qDENWW~kj z5-;0=ZSSy&63Y8hq^kU4+4@}jhcT+G;9fxQaPydZ{Ao%vO=y2(Y zLG>0>hMLhg^m_!b;xLB|V|Xe?5GEa$Vlbo-F=4&FS7VO48MY}@AcE|5wlyQqVBZpe zcLFvWnUh)vVeH}&PWbpG)j41%c1uM|hX?~BlZBM`GVcjIeeN`7Jx^14p%V`AQWb_G z2WOZ*m%aehuuX-L=Dk~+TYe~`NJLs$C9EmLFFn96Ef#W8T9+J{KfJ;vQw#|oEOqqs zoPQvYb-i)6ZBPmGJ9w_f=UPYlL|*D2_Yr%~z12aV_?NHu#yeIrJN|X9xywsvch#sH z$;Sq2hyfqo0}eP-Wm&*5I8xO$x=6k^m5+aT(#3-qJ1oh#QV5z!CI)mq%5l}NXkR~h z?+jMs9G094`2sai?f9j>*bROPOmbg7bCz;-xOQ4tJiqUwXRSH|*m4&@h+w#=2-9&# zD)tqUN@TxwNrg-ER@T`D4?-oH<8h<`twV*z3~il&!{hyMQHD1}(|#x=&7*z2o5_?T zI#(p4Z4JZmZ_G6}@?gQ0vAgkeB#QSS)4iSbaHC`W;J`;q^WuQ7BK60Q$sjLf&SwaZ z=Z-l8{CU^8ggXgMwf0(JK`KUcz1D_k_h6igjd6Y7VPgpPimus_O?7%bgYuJp|+meLkea{4>G#< z(AxyC`;lE7@ro$3^&ebM_U-~P zF4Bt5e^f)@(a$DUc@2?ik4R11z!&sa%OwHLJYZPF29#Tr#N2wuHC08wJAWl5x(SN&d!5mdFvNQ-xGnZjC(8gx%`0OAbRix z3TD1z552Fe0A;K+fZ3_o@Ki%yBL!`o^bI8mO$urd#hpxs$IZl; zsAd~qx7sTpG}J7_7)Wysm6$b{^@plqaqhY)0liiufe2g%8jQG4F!)Kd|Gg#SlHH^M7k|N5OVigtTBj~UL`d2?-1}}cq97roV;A%OZU2qAo zp-%>d1u*5P8-G_!7#%~uuj3OD93;?vPP5yctfIGl>o4fYt~DriLV>W_JG7^7>(Q?< zr{5R3q={9mdCqqDDxC?h+QylPp(Q^d!90STa8rr|=`-{NLIMUC#V2Cqilox62*z(4 zlON?U`c)PQ7bZj2!J^UiV$f$jMPGmUs?{2q1GJ@7^nDNGq0cH=>0>IAvC)1a`icdF zltiY68_9u-OlZ%zmHM9|-Ak|uv_>??jJJwF-$y9+)|r!n>42#Z?+7cruQzJiu-2hSRNtQ;&v_Cc{kHWZ>F z2_4_zH^haXAuWcCYVTulKlk zn)B32DfAU1^t{pa-yhmJ?1|n~c&@v+3=Yfvfj=OVX~8VlXPM z&^(OC224jSTLyI(wLBa-4Jjc%8n$ffV!p8W7TA#Oy4`5I60CJtj5BSQW-zQ*yIc5b2TTF7URk5b35f}pT$JHZT9NqK3W!?81i z@UG_?0dD{2k%D^9{qjJ^M@6}jDmjt+cUlqeB@1j!-6qE9PURF9KJkSRO@46#({kDc zcWK1nfhcBO&=oH)-l?XXl(p)jKnv(qb(P7PtYMG{Xm&PLED+GtQ3lh9+rW9D&gS>H zW)yO{dQ8X!*hFsJI=LXNSI`_Kv+^Wd<6VM^00rpdu#|AU zMNyd8^{xdvn&FqQA~;jS$3>EQ^ic@XT*Q}lko7>J>~O$798P-tzr!Fv zQBXvjMw(s3^5D3Uc%JSL6RT4{G@`bB)7i^cE}&x)q|>XC-INT-!_bTVC!;4-*u^e0 z68|@hyamh9Xl#a4at6|eGx}xUVJ0va&?#s(=?A5WJnu--WCu*CU*XUt7y;d`Y5>1# zBPgoMDC@|XDGH_-2TJ209jpJ&Vhy)1X=lh`IKE@TCe8Jlw^#Yo9Kx*^`(@KGyz>ww zYH<8EIY?4vU9CSBLL_|`X?||D_-q>%vYw@1*X&%Q@znCyWc)s8`NKqDb`Z_(!m!Yv z)yM(WtbPplPl9vzbY!1brG#i}vnn2AG`Dedq`8%-C^m^2%^$)8@It$i z44zxFL`OppZJ229k_x`Bp?ajHVkJ4bi+~L~QY@Eru705{_i+6b@DTlKN>(+=@=Dyf z=%GHTxOR&0P5c|cZqnO%(dE}doM2d?_>lyRAc@7)z$;gP1m$fP^wF_c(LhpOggN2S zV3yJKEkQX35$) z&{1gb=z8lW@A|>AzfHgD0<_6v`@LSgLx$$%b&nfJFk|wU=ljN>fUoF$%v4h((>J`_ z6w8hu?CNtvY-wD?_D9yLW3p_q9e5L zm??%V39fiu`u3yLY3^^dU<#d~T&ua0@$+!AZNC_&;khm7fVlA~)}01*H1rKHWe~D_ z9qe4BZzq1Es6YvFoH{GO5A9E*@KK8)av+&HPM8&=U|}eB33yy}xsupG@sj!_tP4Tgm_--GjmB{zyZiiK!kv)tybK->TV8)| zoWTwH7!-Rwbsp(4X?J$wWQGG8@e|JhgJMO~nN5$gy(_^M9;atwLK*)fb=7!=_6qvD zy?P@2Zr;Wt8|$qtfzv-BOEp8rI^zAKI$M)iACl8_OQ4}u_x!FW0RW`nfOwD!{)N1&e%~A3B zja459GElNSNDu+fWthKCl8_#s8|u0RCgHj9=Co!@iW99qSsSdG#gAG}l_uHP+D>X| zHid7>bplKuX-y5yMf5dSK^Fe%iar;4Zv3-t(*(r1VY$B%od3(_?f#E05J+?FMvzvk z&%(qfQ%}P6q<22j_E#gzVm~R|>Vd<_C|w;bDZm9Vk5`To%zJDn123{+anyL+aR1M6 z*+@E&l7ktV-T?lCiyZweMrlq@R$Ao_w1^PP2VYpcEQb4z5f?>0ceZZgGD?d#6$N{c z#^aEvF{LpOFV0L?JY-sfKw=?rUe$Pcs))1Y#Y&j)xN`-`t{)F~yA@7@W6PK0J;?Cu zSX*hwKtJ@tanDuPRKt%;$?aJ7lwVlis<>EA@)zE2MuDtIU{L ztbK+tB@_MTzEqD%t)SpZ2#pswsFx_PEKhHfv5aN`WHkrnP1894H`*oB1VRdrC9sY1 zAdQ*Mjbo1+242NEdR~g_h?J>wAVBcJ@f}=R$Haimjh#oU38wcjwR)jCpwCdC{`p{&5)1C!3`(SqX`( z$ZEQG{Qn~IC^G#`40mV2+dq>d@9k~0!U6-sg4L`U7Za2Uzi+keuRdxpV#t==ta-BxFGdKTJ(Tbj#uq5d?Z?@|TPg!sH#s>-_g)0N4Vp@01QKRpBDEXqgir@;Y^XK1l5JYz-roBaF`8u9^R}M zO2XA1pPbL|KV{%X9$1lr%1{)PB}%POl~NvYLgwK|zsEc|Z;9b>Gn=m&X*@9$G%+#l znvYs6AteQkdVv_nW1l0abz_E&cE^cY2a~PGf6B&oGH&K0@BW9jM2U5$J5PBR`mFz^ zC?s9fhsDm2(Zi;-ra+CpNbGmaMXdkTZpf1y84_Rn=wP7esqZn|2{0TVNC4sNahCC} z*%u&*p16gbQ)NK(ps&SD|4yxMHwH;AH?+`;@*QYyjgttZ@(?v_dP#%uZMd9d*%pGT zTyH=p68?nOa~?v>3;y1<9dzr5nxix?Cj$k(^(m!k-!gLh@t+?(JL-lAl~O3g2he+N zu@Lv;F16ZAMQ9N!AJ&sGGg++*TFAhnP!f!rd|(9r5C}*SDL-$MMYVGnV^4DB@g32o zonRS{GU?}#lXLIdP6p73@+&s4!(*YT-vAPqGg;BOxEKXQV`0>j3&EPl|Mr=oN@b9C zl}14 z@ZYeAD0ocx66zm#pd7VPjl1@&(TL1rEfb{r2*4gov1>+Joc}LXR`r3(4 zRwLgOUIl!yzH27OQVLk+j-nzWBEkY6#q=8gN-*Q}vrB6|8k@e4t0+W##=(scu^B7? zJy;O+v<2uVizmuI)N{Lv2Ifw7D?=ZBsS@o7y>64w4kQbYi0ZKQUAYxw`!v;}&#D8g z72Eqzb8V7!FPm8LJ5JX8J+Ho{aLrnpXj`4%H8jmjYy9+6lON*iEwM6G0*Jvsd|Laq z3BMf*?)~iU-?J$Ad^H9*Ekf68Uw{AkI7gH*q+)4d^So%cUDYSXQ2Mq9`UJsmFt_;$ zOl4KA8FRe0hH%+{0V!p$*LIpxZ-bhlOhpYJ*1}J3VfFAoC%ilX^IxLhCgLQKKD_W7 zYZq=4fhSc+r(sAu^r8&dZ7WYJuj1!cjJ&tb6jK)e|By43!QP6V%_$a|^$pU$ z7&chH^Vj8y5!*OCn+tA{Gq)*xnHY~zVbr}{-~B^pN|I#QnW(Ho+>10a^i_xLMR3VA6-H^1AiMgPJ94{<&74(622#2Zmm7* z%@Ma&`dw1O1bZHzZ7Wi`IkBQ(#^6kQMDO)3q}!nz{a8ByNWDs-`Lr|vnJISXYWibZ zf7Fg{h60x$>hAs`BsPK zbF3?BeBcrm;!u#QrS{>5p>@v3!zT_Eso3 ze!5*iN6Rf{wdH6iV)IrDaQiZ93nKLbnWwpxKK)9erl1{u+52o{TiB=+#ZwEn+;I)A ziTR{3k1=dm^>0VYb7W#F?sHa%KB|Fh2x%ZqwD2j>-X#l=HFcG{w4e; z0dPM?#<5bZ*H|SaPn6($>*4fZIa-D==*wiFfUD1`-PZd>J%ab zZA=4D^-F6k8S=XV(6KfF$!m|GDaojg$*M5_wQJGI*mIF;7eo@| zam&t7ZhPD*{6F~w?xy-?_q@4uehOzE4&&Upj2oEy^U`#^dwEn4-$O_mP`C#Kuk6vQ zmqdJeL?&%yq!ri`K~nkmr3j?bEemKa>75`}*P8E`1gU(uK7A%s(dX(o;-5L-*qC*u zH7`zq#W>HX+ekIJTIb1hreF|oMlMiMTdPR5l5j)-wqbH54k(S$Ooi`qOXDW%yrfNt zhOola7I~&RyJB^k4`Im_Zupt%Iv08QRT*Kx^1dU@Nc)1tiI^et?)(G&aFSwG^u%3$aIHWos_EJ9!>w*{m zn4B-ze`b_!%DAsVrxn+YvnBFCpSLu69jsF8`X0*8i=V$k1J9-2zH>I^SUXakY1M@j zjW##YrKCE`(Hq>94|NbZrTe6e=mfjLfQxz82u3cjn3r~um|P-C8?To>lbI>Z4Akq! zP5d;Fd;>3AmL&W}Reb_HS-z@wIJ7O>eKa_pmY8`E$J}qmqi{vT8M(^|m30r<)>Wc(CQ8I9-mf1{1@u|6P^!)hb#` z!(45tM2Tateg3yZW=>gYaV|1plcg-YO zMy}{Aet&UexvXV>X?8aEVHb*i(}s8l;EpLJX2x{l34a$m)|@6L`m2 zD1c18$2E=~B&T7`@i^h!m*{{YO=L8V9KgufEN+3_$}Cs2kxrIH8I^!$c7_CpNaX?*sIUVAgXI zM%VS?mm=lK%|b>7m1GH2Fto>d(_{|YBX)aDi^>hW&%ms}4PGj?i*ZGEpQsA!?JBky zTEbl&@S9Qk(BuL*ji}W6qVtD~&e?3 z9AHj3-TL6GJVg^+uWChmq>s=a`pD&Eh=MIe%21eVjxD#ZEt5@FeW$lB&VT#yIc;Zf zL~TmBaHHZ{!=(QkA^ix1uuGzKOzoVo zIZJN%9RAuhr2c^`2T1nDx4LrwTW%-@;t_EG_*@=uX7e_*ySVuTUVG%MnAP{$?bbxx zDRnQn5d#S*Ht+PZBX+Z7ro*jKE`O|PH}Kn)hEre$6u-749dD2RlqOFwa&@+FnBMC5 z*le(|X4il`$)lYe*BEcH&OYMwAOq$+bgje9Xu z;#i;&YfVi_CSh4_(nj~pFpi)|U8#%S3?!UWfOURSqt2~6KSKeTCscsKiRm_ipcNg_FUnIINgF!0$2|#UoFk9r=QZvh0dKdyFPDU zxq*22G<~q4pJDKwT~hu3S!6ggwTUR5{NB6a!FNP%ddoL}aT0$QB%}1GHK4`7WOg06Eiz;mZ6}>CrG3U&8Rl?jtBP=HKKoen` zp!n+yc@Xl>yeJjT?IzE`YBC?UlsX^O0#u5NQRQ`(7;ffXvh4h^&(8nQzr}4;aIx>{r2Y1Tt8_}TZ}#FI`cAt(+LCC{)zO5&IQ>>P#93wK{2Za0NwKP zsuJS7G-g%{4j1AlF5sC#F?7)lcXw}tlSSp6-5d#Q5cUmj??(FvOu{9_1P}wEbsyzb){f&L8e+=$koR_tJwBGH60SiqmhB%~6eued| zx9!7$kZn+SjzdyUOiV)`GBE9Cd%91?=yQ|m`a!A5GaIVGU7lgJ!3tT8TSQ<3#P@Cl z$L&6uYtZ8%ajLctn_YF6YthenNKQ@zGKT8Vur4e#;e>h z5)4b?pNBHj2ipRyC?E44ZI^Xy(Q@(ReQ45jh8y- z-e8>u@V9~ClHJ5#LGljqvp)5UTKMLi19932r5pdkX7LRw8aZ{wq=!!+a^{7cIH3#B z5lB|Zw7DJYK>0Bu-)#v?5VJ1^!Nm~ylH21=jQ5On&)X$RS8uZ=b_2=Tr$#x{ouUD72oZHWUs8NxvkbPETW@op% zU=L_7vDGSedj3O6=-43ntP%2`f)Db{M_t!ra#K#Jc0k!|kjgMt&1CPWm2WTLT7Z#3*SGQJpN>>8$WF=z6dD*2M_v}#0S z#E+`#k(weYG{IQ%xs|k!tMpmZ{@yy;yYn#>2;6f)6+)72W1X5>J(NOX)i!s>I`GHGI@UE~9ycjeJ? z&miws>b9@rs}J-ro>o#tV1fNFysc3C{1kV6-bgPzvRWtXN(_vJfTOe`b=yxw3+|Q1 zCj)B?wW`swxa5d&6)$2k1dFh|hhk#UxX&b?ses#z$Cg6U>8bS;VNx>YFDvHYVCRBK zBzC-LM4=t*77qkRA;<9iCcpfIH1dg-t`=*YPP*LCx%ZcQJ_z;%B^kXy9eYUdEc_4Z zkwAvz*vBKiA+Fgt3+y|; zK`|^co&Ek)+3@F+LHJ0Q4ibPO2Hd=zy)TS2;3j$i7m_ayp>9u-q&(Q=7Pw&Il4lI; zLoSxSXRo`MOT6!Uk1Bd^&Zs+m>Ff>t*IT(+_aE3*e7T(dRUhz2E6yn3-O_CC*%O^W zu33V|hR>V0%NE=$(0I=v-)!$v5Kjj)@fh6C;gWRz>yBDr5I}=A$!K0qb-d1nDMWFi zb&92}7UhLR2@1=M!lTNFecqP9hya_BW1b;C))Fr|gkL`{!dJFuNbh zgb%#UHx2o(BD5rsJOKYm*X1x}q52g(xF%-cO zOObYeWoH@~E;yQV$Y5R7M1zHhH}uas!Wn(Y62_C8!me(_x))bxq~Y2t6zPH0kJUf9Lw^_g%%X#{od}*?-3r2?(3tXfXhb}sdhMCtnY^O> zk5Kt&7fhk!v3i4B-m$NG6sRQc5jTdj+!C0UMHa)>3$OqbZ1dlamA2E-aArSh(a(o!lwuJ6gB01*5o_+w3rJ5 z(UE%i!_28khGM6u|C@7eSZO&-4M=zU+Xzui-RLG5wBA25of2o!+047G&&yMNrq(^c zv&-$RU+L^%)+hH69fbbG05l%8w8spN;dA*SO+d|mbN`42cZ;zq!t622Hy6z?vJ9hp z+>-Rt0{J)onff|j4R6AC0lzq4RUAF{qy3Md#tr5%L3m(DoC4bjDBVG>T>Yr{TJ8&0 zfof!DliF7c^eILLi*Oohk0}8Y*4?52<#BiOurzg_7bxMzuayp{qBy#4#Z2BvWQ$ya zv?5rk%W#6;(Bh384pEI(DDS~cl@bc2lG4I#Hf9(0c(FIyD z4bBxKkGe>oS00^0L_^2{MsKa3!R*f8m7t7_uVX=Vq<8tI7)3U!m6ocG&`Kx#;%>z` z>*3A4!M5PpWOV zR=oi;fW!!6#P4im)?#n(C~&q^%c*|Q_G5N&B%SVfTDX2lX=^8-#mA@i9ad2UsXYZG z6Q}(~#`+Xw0UiW12;XPla^xAHRwm_gycFkpdfjKWaTG%zQ4#utn?_7JcS~F$G9ZsC zWzivGTSHe1x}Yb!=wJMu^x$Xapa2^%*n`^4YTt}Fh&Wtw5=lIo^@!M9ZTuK1bCdjJ z`}^$Qj=4XNzd4ul#w*9jcK$7H@aZ6;jHPzQVq(hr7boX-9=AvAPqZBM^|u`LHmm`D zZe15RbPo#A7KvDAj3>+Kh_M_m#SAD@NuNOaJAg9^;;?ZB{|V}*dYQn7e_|~}YjCu# z8G2;d*RuQiXz?KCuFx@|cd1kj&)D1-rRU$O-C6aG;p5l4?|Ki2VII8BIjrvg>;fzz zp!kU!bw8A8*b`l%oF1za=Mvqv)J67tg=7*eHF!7$h@K{0@?CCSFYLZIwnH_7#sm2X z$}|(8kZ^4N(Y2qXjK0CHIodxCSrll*;ZG_%F$uLG5^>bf;Cw4Vqv4zao{N5=`7`l! zk5ryCC+omvr1;=0%L?%vfRy4`E{Lqv0%stDZw1yF!!4sf<8nr|kmI@+Wz`GgEn#@# z%TXB{60Y>j9^~DYG^e3N76Zlj{cG1hTZWWue%C#`O7Q#ehQG4Alw=mx=v3}EOJOYf ztkUH1hwzUoKkmIejL-h$KOqe8o#KYL! z1T*jG=4BTxGB+_>LM@E?z)hFi%(d|8<$tgHKK+4LDT^0uB+2?-6!?alh}~&$W|8ws z#(Z`fuMx{9Z%B6Mnu-XJaFX6PtL&XZIt0;HA_WtZ`IL1ylqJFv(kqfp7>VWW*b4Rwp3AyaB$8+8?&(lXcqM!0DH5{tg zVq;gp+R(}M<4z9po3E2p+n~aDKxKxD>Nua*V8Cr`e4Q&VF57w<=LA>{BPr?C4Q>z4 z#6Y=N#BvN$GR4m7o*$C~MCHLBqg455P|cWj#Isnd5g6!Zdn|V%iXY7}BimmyIy&UP zy=*%L6Tx;t=Wt82o}MGhP5})Uom2{9y=L_=(j}GH*yPJsKPtCm`g5rxf(MfnAB|o=g9i>M5RKTW=U-hD zTrS4wyW6><8+jQxJ*41M@^e8VwzZ@2{4zfBJ-r&Zmr$bRC*yj^a%iZ_GoEz2F3VFd zjKnx=cqTSBHqzKr?z@M!hk&6KNYr{@Xh42}wBqkdghj)tq|*>R*XKY>o4#DX=9r50 zx4sK5Am!pr3`oX8p)`54KT|$1bI?V;K>sy~G_sTKFv08A**82Z8NEG5l{xB+*eg?O zst@wC`dF} z5=|_3+Urx>9!Sb=IsA2S(EW8`!e#%4+w&P_j6Ia2r{X*jY5K))yfYRuo{-79bqoA@ zE%Z|Tl%hCrcXQtL9u2sTgrd{!RMwkPms}d=NUH^X2Y=?n9-rjWi}hOF^>oa7jX`1f z&|%b?n1kuVeG4KM?OeLBGO5wEJvsTuBYbl$ARwSsYy&8TvY+>6H5fN|{7@%~W z5f-%ddv(@VDGT_xkt$mIx!r#>&wI3A77<>5jn%0f$w$Is3MnIz<_(*ZNZ+v1jStfc zJVY#h#l9v)C9BcrpAS=^3gBGQ>#f9FZy1lFT!(Q2pF-oVezgf$uAiFvM#5%PSxF5; z9%FSR>dFa{Xw?(UuK_kq`(vZFP9Rp;b&6vIxRrU5W~xzP$-3G8I4cDM!&eXaX9H48 zdaBoIlt;kRb1ys`ESNzCFSyGys}U63%hTDYXepPw{va^wG3|lc|KOnBOyDJ8aGfgn zN&witB4dtBMH7tZ=z;q^iM6Si%oYKs|IY$^v%9kKT`v|@K#)}WbtY|xY@!YBfZ{O? z&Qi~zyUp)j$=v{JgTv+AQ~gx44O{mn{cFyf+_NV)%%}!!MB9aC%Rpa~MK#51i|EW= zE$0LyzbPpSJ`SbLynio-4-If{Ms928vqLDRVEDfg^ae@F4MA=S5B}S3mg>hx=3~T6 zM@t1DBW*R{9}m6IY8ae z8lwYoX}-z22$0xS{=w5W0+mv5P$#s^ToquvKU_TTdP&;UwKS#XB)2Ir z{}tVS1jAc-G6OTCJ)+?hQ&|bhy=Up)hlkBDg`{AYFnbmlpz9a6n_c12k;Xj+)T;e* z=*JCj&S$vOf!D|K9OlQ;r*MFUc87*Iq4~SlLMB0e?va4W`Q7m5Pgn^C7lWQ!aqV8Q zBASD(L8X_c%9_6gGnFQVUCkSA3ddt5JHGL2^nKJuSWB-}jon!P@%lr(10{dZJ6i_y zT+Z0l`LgbHK{VyfT~zBxi1rwew5F1y4YIP@Q>;_(P5&JF^Q(zP{$?{By0I||WE#nk zcSGaBc_dlJ4S!dT-v~Zapx_FWh!YN==w$RILvcONQ!l)OBb2zWmIe$hp_yE#8pFdY z$MgcIaz&5nR~Nob$#A#!i5;T=F=`qBrt_2%2MLNa&hL+HxPf)SsD2@70$}hPbWX`t zVEIxrf7Y*1ybTC;XwPTgz8yn@TZ2ZodMmCy;&=~;g)I1bhG#!_jrS^1Ny;>bQ^dFt z{yDN?CJfH-9$XrvCAmgim++ zZd12@h=?Pq0@+QCZB{%&VZsCJ!F-!ib)IOt;^%^WyekIJ7I zJyv|nVoz==*;RBZ}D%ixfK7 zzi+6LJ^UeZpep%cLNB=@_3!HBgqK_}TlQm;ZSz&IwXJoK$LN~lG%q~Ryxdxv zb9S!1-TfC93}h*%J*HKZ8>Abvl${ce3trc9E}#Y9TeW@t6sk@=!Q1|-e!v8>QfK!O6b6p?z)sR|=tjR# zYi)8{%u}Q;kagZ1Djg}J{7aC4BjB8KLDqY@Wn4DjzNG^6B}`#l#s{t|g!5Oof&qK* zVSAZsV~fJk;zDnG)ueCK%=a5PCI)9mai;~px@|${hAk1be(nvEH~;Bsl*Sa{ip_)N z3x*T%7!<=fgD782mnIl+V_j(yDT7Q8L8o zZg~v*#|G4DZ5loL2M30h!q+@5PyMCA13&gJrVy}5iV-}gMsVkGKX!MOJ|@Fmhifla zpS?A4PKM$6RfN+K_MaB75%z>o+vg3`^G9z({C$Q#ivbY=6?FRPY@eUX2@wB*=THQk zko+b8A5cPr<=c-?ZbqN)!z?q5Jd&Q=cK_sA3J>Mo&Bt#0U)kaNOJm`qwcf1W&~j$y zOqj2q0X&a}o%mw*eJ5ieu3UVOn}sN$_gP!Gy6w$-UEpG^cnGW3 zUjFjF(t7lIFTcaD2I;ht6dUO@|BTJ4(+o*;U!Cz=MmmyVg~apB{aRd-T*%MwLGVQi zt2df;7W7q3vwco1KbZgmjY#xa{GjMn(jq{?#1%naC#x)IA{pr=%S5m&GZhE4DE^X% z8n68$1oULc!mdY?EjwxboriyqP#ZQasg65g(><;$^mg4_7OM)Ax3j+9CjZB$IIko3 z&Mgt#%6le~NBDP?Ezgh1h=iOc&{Pg?16f^Tjkx*b@AKKKZji2qEBMLNA?tkTa z&RNIsk?GnHdc^=U9|{LGl$S~VY%HdH8L6%)XG-9qc_Vv4*-p1<^-O?rdJ?AKMDyYL zZ$64;CFs~QFguG(gxDvW1pRy8=}t6g-q_j6TCdz~-2S{bN+41b5yDvQ9+@CH#33A! zu4eC_I6nFwnS{Ej-;P)rXWZ|Ft-(WeLC%>YA!VetSO^BA30C)98~It`Y7;THq1CY6 zkh4E{pPE2Zcta1_-Yy?lQahSc3$B<5TNAd8`2BkzB=^gW3_Bc!@sphOsk|S8S!vrA@z7*jCnAwpreLbDlFZx3S?m|ixQ<73t zB+Ecz$|yLnLu^5i1Bnk4nIz^%gtrk?6eDoNkKoHpsFNP74>4@60Wx8d{}dmT+KKw~ zKm|mOQ~s@Yc%Y-WF#JxAVOk+OntAa(y$u+!6dW02y2X7i*4)OwpQsYFY9w}cbqlLq z`3RuaifCSxDY_)1AjLbK#s6~)ego^`29NA@M*;4gOXy^5#fYRU&XPsu;5>_u!dd`_ zmT$1v-UaEh%$T6Y!{x;%CHkQCIaP`R@d}qiH+Ue`%_l)nHo*kMjHxsSbj;n(U)kV1h0QaMWo}2SF5_&;Y7*`9f>$qFHyE zQIGmdAA*r~u9oBdMSsLXcm^_;Q42NUkhzE8)9yT3Y&L3Y=140a(Py|U`#0Ry{#pl# zbRwqR0xt6wiHkr>2>V;x+j79nLI9IE(z{V120mqQtJi<5JFk6s*2UQ3$v}^GoSC?g z+c15&s937CIWYJPD0Jg_TB8pn&$17r>_#v77Y)XnjwTG&yEY8kT|X-F$}T}YpQF-G zpe)&d8o|dsYm0ebq(|I9A`t~4mXw1)dZk_ttvjTbKF$36cNFx(3=|hWLVH0Zk(=;; zpMC3MaItAJPOa0y8+1!oymhQJ;|EzL#4g!q0-!>7DTc6#exz3bYP?*~0-_0d)~1N7 zx}K+r(1JulwxK=tZJap{xU$ihdoW;M`n9XN;p^ten}ZK074eZy6m*>1q#$3MPpZ#q zWIv*ACM{kot{ZpS+s5}aW#dL4`Hxq2Xq=y!+ur2smEn@bOed#TLkIZ@s0#iG8$}U3 zkJjyH5G?M2YYOlch&qU)Bfs=vZ26b}_|WtcXe+rgYNHjI2vTR!)}*Oc=PxQQK(63b z76eTOwJlNviI%pddr$e^kz8C$0#J)&Z(_6O8x1gaM3e<->;CgX9%uf_7)KUgUcd?` z@cB)dH=b%eDFWhTD(iXbavcYODVU%9-)yV1Zk{)h40KFT{C43ZkUgMwcH)-pvjK|r z#`ot9HQ}tRfQao%-tfP(RFMdOkw?E7@c}tjo3G`I9rv=zTJq=zzYh;;Y(h3@7Pg_w z38TSj(e|98Ia%Z?v#nx7k%+&)eMtKed$xyEx618I+wg1ZfqM%L|6_vW07h_T&D?95 zOU=7&v|F}&JxLLVtv7g>8AV0V1-0$fnyIj@ERnF^KV{S!*^DrQf#7~vFCv5mSfU1~ z=_wf~^@#0|>HY8flE)SLef0R?Dm-(@mG;U-uR7)XPOx0YlGYF)LpfnRlrRMLmR`n! z)JOdhonG0w z$18HQQl=XC`^P{yR3@O|q+#|aobBq~T_G0lCAEvB@ZTL*C@a9yd7uJjw_sf6J5Pz9#H`n3GZ*?ZdNxJ-UKMHQ7B+Pd&iu=w51gU_dpDP#bM`%d=K zJ;j8zFJ1L^h~Bu5=i3!!h~F@#RB>@;J!I}iBBZTy$i!*oiJn?wLJ4p@)MQ!nlyA3G z`9WGC`wD#|tVpC_I;g!@V)$;>1C4>ZEc%Bw&;ieJ9(5Eh-Em z|KQB$Zop`cW@h>qPjMkW0?@^B!doxw#3Yj|;bm+#R^UaEL@6tcQ#3JPgqE}<(w87CZ)utsr2B$qjlc)9mXcrEaVp6m`9y60wthtbP z7xEl>b2$O>?wV|`1@nzjhPMN$G_Ck@nDdf0I8k(w_?&bGpi^$6Jqjtlt^Gr$W@ax= zJazhI!qPDN19i{_oi+3`n1zjAStQ+=;tg2{jT=*^f&%ZfLvWKQVc;V86-ZaHP9p z(#5r^BR2X6HOK&Eujddqq;PJ?Bj~r0o~xy@Qw|J>#*+AZBt{rdc?vA`wN22cQsoNL zIn*Ih7dX1sRO};tdVtb272!qIsu3jxJHdfM?W+Jc7t3Egut>qmnG5j8C2lTnI0Cn~ zPZJUFe;NNlt$pK3kvB(zPJ`4TJ@wLWGISAcPYhl{v>~rj^tkiM=DlKhn&4cz(rx8x z1{%DVD}=^*7#*uIJYyTQ)6uzi__Jf`ykEr_7!$G4eLxa;%6;5(Z83r8Wo6cExvmvX8#&StiS%Ta<8WUT-JVH``X>4{^8oA z)_|6Skz(6}y)9KT^?!N{RV9_ikhN`!kj?fq5InhbJLngS@A6DzaqWjGUHBtfQ-J>D z1-CQg0BGAJl10j>7K6(Btu#_O)BK;DP$c{ZlhPl;b(OjbSx@M`0P@Xpn6fZk$3@}1 za&7ar&bPE^$XUi!?SG?u*XEJb^%No7uNO)H_xtvQ6ICtZ=$1(6=1xpbc!lcMU(s-d z2NuWfBzu1Za~m}IY`IT=6m8l5zIL*BVRSltZL9eYee!X(N*%etT1-+TYNTGm7ffL` zSn8LlY=xSPj!u4b7K}6;GJR2`IcAdB`kV(2C-~Sm0Sl^F4o+NQ^@>B>!f|Lp?l%!+ zD-c`ICEmfj!JcQd?is~ZGI!otJaN%QP|}G*_hWA|a5TTV)W!ht+hS`U+Au7cMqbQLi;QFnt6{!|~Z#c1$oyK?5fmjuq& z2IgpIxxzON+ruo6VZX59V#{T%ny*{8S#3Cd*maG8gU>a<+F1Ib2-{kZ8+4yrdReIh zEUO7-Vx9vbkM!h%QW#}KkytMES`RMTMjD7)bIy+Br9Xij8wqB8n{B;A90)c<8EXf5 za2F7<>@bsF?~-fI4>6^=fF_YfFDb&hU$eW)${JK!{0RMLN+UMzViu(0M?JZ63$gHZ zm{xhtUI*;#7=`>!qypm;NWJI&3DM&-8WR4Wu*=`c$CJ+_rHY?)?JneXmep2NcBaw| z`kO%@!e^O)G)1S-$=7||J5Tv=zGpdggl|d3^PNKNKu;&%;!Hw~jGU9dL*zr}Kl+Ey z8y@a|ghJQ8-cZmd$>Q~oA-Qr)R>%Fb&w@nrwEkOeU_c)KkIohx2AHgDDSmytd= z^7Wsvpp6-l3m%9FT{`x-X`}Tt2&uMl`=T=H=SFOY@~n~Z`NV{w_w-8}MC9RJcJrTYm#vwf ziNY za8^}Du8}UIzbZwE+Elq+5hl*$FBSm0FRkZ|LZcu&&$4@~#1O-t zK&(V*f&RPEXC`K+Egfut(1sq<*jWIi$6o7O}PV(2wWOMp`!Y-C=P~OTb1) z9%tL1;EjFSP;YVX^d4ivc5kJuWh=8kVz=0~U!yGH)w}wz#>39(gWGeTbAYq9zoAGl zHQH-FQYK?HwB2@Ba#dSXJLm}L=cO2w6}qJOM0(0NQ%NUB_yU^?)Z#U3z=$o zm8uEBv3mB#{>&O1zy$KE(9n}2_0=iw1_A6)O;}k%bC7S~-1_6X`mmBUEI)_~-#Ge`G>>tv4 zK?)wDy&K3xs6EKrxh=GCQw!|u3Q~u@)S4if=mZ@AwfBc7sU=_LxpTqCSk@RoR?ReF zjs zjy<#XVUw3j)JHt6=`7?w{RV9F5`Bj%bw0_}` zsi36L_|-b)xuxPGcx=_6*1Q2C3L-#sy1fS>%3DuPHG~a4o2s#)C;=*2BvS6|OFnMTlHv7fwqep+ouNG1djNCfJK< z@(G(bo>6L93wbCes{^qYYOE>!Y$^(Lpjy)han4a7BOIOp6^q!Wd1P8PUu|ixuR7`X1#;2>F#U?g?He-TH@=<<{1ub z&vS(B<8DWVIPO+Q<_W$YZUTurucvk>FRJ&zF7z!aagB#>RovPr2nH7t$mPMyGJ_}j z58gWHVVpVPdDj>paHTYJ2p;q_p!wSa4iLwD@k%1Utp00AB+C38nfn++@q}l(c0iM4 z`~v2Ba0&TJUSm}zeT0!tekFV2iV7md`wU#26OSPdmb&eQ|HpZS0KQ5xLhQKIePf^0 zOZG`zJB8K}l_tqpnlUWVAGQ#hYDI;5mNDgbIXlw9aGp|K`CdQhIEaCuj z&m(+!`RKdaUYTmx@AaY4HSUw<7?=}QhwmZJ z%M4b!!)R6ONxj&a&~)+ETKdiCw+Ye6D?FL?UL$5^3t^(rh|P|JwIX5d3Q4(%QZEB2oj|ZzD?2*GV) zqg@@*o^ItHP_IIhGFr($Tv-f984*DIo#O8VfdX^vjdEbfOGUjo013 z9q4&fH$lBC?sPP9wAL=P`fWdIdWUhe8*wnPrMCNU%xpTCwPC-hwm%`lmg(m`V?Mpd ztjV_8U`HHwZ2oKyZxJ}QsAn5A`@F_Bf?k?=v}1d)<6k4pa7*N~-(T{fPVcR8-`NVctN@IF}Gh;c4*?bZCX ztD|ID!rM~U6t71icvHmNk#xY5T9$mC)4~R zG!~W6?pvO7xYVg;UHwiVbg;BAb0hd?qqT2e_s;}gwVf)riMwfO?ImY;Z}ExF?LVT| z`zRE_Z5nQ!g>V+^(*xL!3vGGZudDJ*b`MncZJCiq0YsCP%U0>SwWB$4u% zgvM&8`Qn(01R#1i?#YA`(6Nwr^i=*=-dLQFjLns0NTg4q9o9V$Q>-i*d-35m?rw>lz<6ii<*I5~? zefy#hyg%+5n~72&R~!ZHzsdJGwoLRd{axzmgaDlAKsEtVQB>l$;Pwd@k6aqRNl|fr zj*{NFPkcf8JMS5^_8W5SDPm%)r}IhHt&xIsBFeVyTYIIk6-)|?DT7tQ)IoN7iW+Yd ztgoB1CN6>UF^6K0MEEa1ylMXPDYB_{eC4hqd3u#m1oXI@Z@{u!{7zox1jWMnfK0gC zWa648_oZPTIiB3chY$1+k)AaZW@cR8sb-WfRyN-u==7H|lz&F+Q+Z@{BE1M+JkRWw zn(!ng76&I$7Hr2eh06n~mISf{11PmQ(c-f`p(hAlu|Jt(31zBB-*?=dvZVZPAr=6? z)>RNZ8jMcAV|o8o^K^jQgD*)7!^2SPWaiL~p89j>ZBoR>fH-fq%7xBsqxzMt^ch`* z-gb$6?t1r5kQh+A7kg;Bwy+ro;Wyzybzwf?o{{keTpIUL%{kgkO|cFI1443vJ5xp) ztWByQeOJ&=Yd?2+eX+O9>Yud^GhV)o0zUMwye&9bnmC|8>8b5vX@-87EK_Zvwg2S{ zeMA!28vF+qO6S8{J-CNLjiABEXg@K?zvKacnfc`|FUJK|VJbfwitZ8>rX}(kMh874 zS+XC=iTNI zG?R^Q>K$i%RAe_&3Bpb>UQ6TEHzFR%=UlkRuh;wT@Xt^ubT-JGB-a{fZMGK zuXp!38kkF4of>CvPI#qPzA1hE|5<<-_`lPbH|W5Pjt6|ncP;iJ4h@^tq_$XUM|J@l zReZm)ENmJx`ueAiYEw(j{mS%cy1KM5z5n;%&-Zt!-=}CpWsTcQC8nd*n4P0JnTVU%AyvbeuL zsXV8$5)I$J&u#N*SkbA?(o>c4Fo7n?!9he_j>Vv9$Ye#l#Y7hAEFsqD#D8gDU86;x zIBu-mYT0eQn=@7Kr(r(a{qxPu&He8#gNxle!{Rw%s_S85uB6#_uC;b98A(Y=a-co? zYNjVcvE9#%*6^tO8wkUvu6FR_aJYk#?ax#|zrR_%TrY@6St~5Z(UqxssB-2aY3ral z)q7;krThjXPy}mWJ!$W)=Kscnm?o#6Yj0e%R3Smi}HksQVkSB|Djx~m)@4(G{Nb@o3!u{@8Ylx!Rrw_F$*#^SKOMs#lFgV9 zr^-w=$V?sdK_lsVcC5jUAQDapJ?b?`2t;%l^NU_f*Wm z#@bsX>?g3kVp^C+>zuu2Tz79!KiF(!2iitY6WxW>?1f>}F+udny>y~i$Ami#Pq_RP zLa-j{fSM!%iLEG!&IfuJRJo`#CZy^=GYN|JGWi+l?9&gW%g`%VKHk3vhOx#JCgiQ9 zyZXF1VWjxC{EVg!u3EkxV7aly@{2df*8(i;1o5HE52iFl%^_I>kcxp zrr#Y8l#jVCyr=P5rS2&NU%mdn6xT=Sur{8!T%QOxHKRCHviI!IE8ypDn46h-8GsR1 zeKCe2yla6~s!uW=K~Ez7jeP5T-i?RgS&8E#h!W@}ba|2y2BG6jw-S2tzuHc!1HG~+!hdYtw0F*UG*lf-l3t-ctkmge}c@%f0R1^A5G^T&-DBL zaiJP1BV`W7@*zvu9AXlgl9t5CVL30va?UBInmNRj7#5Qp<`AP|&W9uuGUYHLhjJLn z`IPhT{r%(T5C3cr^Vs&j-}il8uj~0dPyg>E5Rugzt{@?}ngg1Sa{Z0j`!(%Qx5!5z znJ(^?-0k=uBUGX6%BWp_A{Y1Qj?Zh0&MCFqF-IkcJ{_}Bb=}sS(tx@FyDjwCCe;Kz z^Fg6TZ~~ByZi8zpUri%v^0YkS0}n1<&^e+s=O@xW)hKF^`;azLM@f>i?*2?#DOwk2 zYdpKQW@sKNo*x<6mFI%q@*KmF5>$C{I7OWKy1Ek>S?;%W0+0RGq!Gq3|IQn4_zmgO1s+=Z^HDz zqW6^yC}8ZRmpVbX+vndNOdma1)&K+`$u~IQCytPzO0fbVmlEUliU;g>VS|ujBb6cl*;8OyyGE zvwmmjoW7Mi-#YTl(^AEs4}tWBhYX=iwE0v3 zmRrYTn1$8jqWXcj@wbQ7CbShrZ-MkcLg&bOS~gN&-3@@MxwEXk08)-~F}n|Y($5%n z%21tIE&m}i5Ry$@EfJCB#r^DX!MIZm7WI$(xLizMN0<`y(U1uhGX@Lk3WF9tY!)Jb z&XJ&BG`u9wC=Oq@)vX!2Aa&juo*&jUFm#$16O2hM;Um85vqbZ$5}(A2Hfk#$>;4$? z5uzwO;>+SGS`u;q0nJ~t4&-rtptAt*V*fW)#qhVC=7Q!E>^ixu@pEripxP37lLCxjt2jx?#=C-T1FGw?EXA(EE@h%tF&6C&|8X2shWO zM?j*#L-Wb`)J#80B2|^wp$4l@#2DpXaE_j&MuDfP`~`}xCIpegf!28nj~y=1hCIwz z1l2i76!_3*F&T>5ZAIEwu7BfZanLA8ujklFLZH5&kU4rjI_&z^>gMZs=p;4sJsCmz z*51st;)Fc``F12Qz#?D5t&~o)krMFj3!7VTR@Wc2JiHS`UVMr&Cz%~ zT30LD>KXc8i`eiT9wvn_YsqMD=dqh1I9q{5EMtaTLI z2S2Jgh|dapwDoU)V;096ROlXo8twmW>5eX5tt<*(+SC2_@B2bo#7gIzorsOLv519* z)dL{8wg+T2!Vff>_NRxv9xAuZhi4F;!FE@rLKln6n$~sq+wH^FesI(cC$#%=Rz|ma z#6Ltke2tRt__=cAl`mFtpra5>P~q2;hA21k;%#Blj-*>DPOl4AQeQddlb#CX2Ln?c zZ>MbpCZ2rr_YlHKqKKer0bsWG2#70(==3Nw^x_=zL6nfSns3d6&DBRf!Tya6+y9zd z;z#z~tC|k}EeAAZ_5EDj)cHJ>Q|ISv1V?IVS(jN5zIT`9-_hA4U$cC&LVhojE2vk5 zn-~1EeW8-}lCd=#!}Nj_JN}tq?EL5iSRUnK4@&M)P~_XDS)T#YIaYuV}oG z3funYRJYjRhl&Lh%|3`I2yj_Mn+zs8r`!4l+bY`EhXgjVe`Wi;md}ReTNk6voqy9A z&k#_X*ju60qnxl=c`2#0){8)c?(Sn}w0@k5JLx7;fnKIyhCIZj54t^KVsuRwCBU?r z$m|(HO8NOJnV`k=1b*k2y5a%*wRzJHQ{hgG85n zL#C~wC9jaj!|z1Xj*9QtVy7Ek_f<)eh$Cj=sH-3X)s+q=BBIGExoUZXm5SHC1*aVv zCq+R*LDZD%7lGgk31^JtkbR9_3S-|1%3di>fIa+>oSW+-c}@1YU|L3LjZb~JFT+d+ zD^-7I2aumBr&Mw?l#&PMPM%>N4m6=mLQv*P1iW|%3pm{A9Vzs}7{V>BL%FV55Jn?Yt z!(7L$m`hrp$(WzVuQXSiQ*c{~c*M1g_5Y>HsW_vA@0_$WmUSGTs{r@EpADCX_ZmwU z_qqEBI4iC1MfOujSeHZTY#@ZXWHGffif6}43kAIQB{dw z4&MOw$1hcXmFQ96C{nqH9U95h`c8UeV-U&v8h8Cv0 zAHC#nrgnyF65HYSnvS^LnZb_y3zbM7){p-1qrVvP zAsF|X8H>*8h<}R*b)Dh+b@sa|&Gl}RF8=@G1$B6lTwEZ7v4f2PE5&Zs!tR{ZJ`e}{ zQ$EsiN1n<0k=)W>tbFBQKk|GUF5=za#;uJx-GhI#K=V(@Fnn{p%w`@afi0Jnv9hdG zLnjgjumXvc%5*`^MqC^_}4(E&OOB3@Te9hpGNk`Vc5BCfh3jxhCJ%x=j>kF#fg(I;}t%W=Hp%PwJy(+R!Fk8y9eSnb zj{xQmUsW0rAd{YdA`}hI7a1r{dCweL={f5TE3j?_XXG!Bwvj8tn(Qt%2og;^NP^IO zlNlGXigEk;p^r7cHx<|UK#s$eTu;!k0P{=$%FD$IZbwJs2Z3GKB-xb?cokwOVMpE- z&z0ik340}_fOT$t5-0FV#Xve}GsQB6-J+RKKJ3aMm-pBX>v4I$&ICj)9it&0M!E@m za1bkR9GDUj{&XKx?*CjE>tp(45GVygm@4L;_dRT3eMpdF2QrcuTEXsTJp3~h!^Ne> zJbh^~?cchHem33|ow-@u>P}@=dY0bw1__b$jv(87z1)O3|_xRozn&MkGr8S5}>lbW|Ess@EG{XqzQ?{}j{?gX*>Tu>s+KnfQ(yDgNe zhc1#{Dbv5eU%L@5a5 z2syGXaGwNLVag@qt-H$4LE0c4@>jjjq6(c8gi0^G#B7Y-UcIOQBN`%1(el~gtE^zq zOH+%h)>91*HC7uF-xwaq0~n3EIhCQccnn#T`XThQzu8IB9Que9jCTEK?6SXimDKk7 zwlv55)-$1IqS5MScsnvJN=pk~lb7Q1+3r|E!R>NYp^hn1P3 zth@PXYid8Yd!fyN?gx1~7Pi@yKYy-dKP_T4cQ5y-rrVr=-hJwH#L{rnI*=9HUk+?q z1$qJZGFn=icH6ylwwDH)-$ptsW-QDG{G1PL+F6*hkKklV9qi`5Sd0+P3HcxU!~QYy zka!qB+LVYeIJ|WW*^4bZ-Dx{kAW{P+V-i)lfO5*wMa^P(wDVV7!(44^$tjs@mxud3 zdezVh=$oMT_~GBC9mtbtOa}{@h5p%RmJK~P;N&+cJ2J zYDzA!2Fs*8boc&E1aFdsG2r6~Wau@IM=}zLWe@O=@I;`0kWTJ~L*l1Ys-8i4uM^M)HGyt%_`!gXq3Lx4s?kvUE z8AzC2^dhT>62K`4apBPfs%Z;o*D(YTv3c+M4^2$TYS$1Wg4a$B^sJWp77Tz=dW@EDo@6dt&&J{iP9zWtcLoOx#9=)D)EW&am!3bg>oR!SPZ(jG#-}6D@W7kZt05@$n@JA+yR528C{Pl zaVRU~9s8yfk{^dgU*e zz^MH9Q4B``8;Efvapn#lTwHTh!Lu^gKnPaF?JkHa`#u*xjaRQvy-Q7j>Odgp0L@v!_?3c+tFn6S)ssQU%pkE*mC#moL2MYrt))>_wgWtCia*6Sa8A3e)w#GlOx8N>hU18yL`k0Cc`=m?1EizbXBZAsLkyw=;7uL7-xG| zc_c)KX?3?>?fGU?&^5kRa6jWSfEd~KaUi*ZK%c-ltxoSp7R`)e-{ikN#w1|mG+l|? z5NTq3zC=EPrdAw0wn7z3kfA z(mSSIuhmqI<$Cna#%rhH(x1O;4<(O+#!FlhlMx2@^y3GN*sNgURo!*!s_W?xEh8D` zzwJEkCm8;dm~^h>*NjWf&qgb{;2R#jC@vdsb~**4djkB#y0~;!{ughqwZfc@*?@;a zU1_OvxfQ)Wo?1TTdy0g-a=BcIN~O+6hrhR3*wp8J;(iGp@x#1R1F#ORRbNkpKSSYAC=O&^(o&@jGJ!RE>tmw5sv)GzJ` zmq4Pkzpe0pT1xM2ry#^nzZZlKNN6_iG!CHoOranlZb+_=INeW)Sn78FuE*wObeYF6 zls7RMe77d>9`41Z49D~f)=$Z1Xp$di#P_?FE2Eq_R9XZW(?67!>UT_(R4{aoB>J@m zE8+<^b=SC_34ZuKcLp!l?Ot<}6|4fyRjLJkd{uh~3C=zmQv@>{ij?FXZv=fn1WGrwq^rU3$_Mx2c!`yMMS?34#7vnbBt{tV`0x#r$JMCNanR}d^YNPDX>_x|GT zvem}m!CtX*=VW5uc8J%;y?tGG^DQhX`WpHJ6q3|+tL2HuN74Pu`-1z&YL^m}A6~t5 z^^GF`{qpwGg|`bO9k6KCzYR^nE3FdNo>SM)$p}3=DRzECqa={->cgz;J#y}zNd6Zh zx(EbiFu*c{l_^P>_jRj7AmbVq=dSm!uqQP;RU;B(b_&pfV>)jF$Nveyq%r#kdUD&T zYVqI)<-p-rK2nCqfQU%PKXox}54s6#c40iHf`;!boq{v@1pZ9*r zBL^N!lVPyxae5_S5o&{ET?u}yc@~LNx&~|Q`W4>v!`9wT2mTpn1oMN+%OxG7{YNAF zy&qd+kkhKXJeD#VvzUnK4`N3l^Kc`*3N@B-%L8gFMU6Q6voQs=P*n%eFuji7C7v#y zq@d7bu(aqse4VidQ8OD^khId)ty_Ir@(4{o4&Wvi3;WuM($#Z$4Q&CE<+$N>GMN`Q zvR-H*E$D!{M@Qr3p-0Oq$tZ;|Y^t#vS9}&5DY8;5T4vYq__q9W*h!KouC}x#RUhf|Oeuu3B+v!pddL@*1b$0h_vSBC{CpLjfP@l1#(r}@rsF{113Z-mVioCR zOmw(B<7zh8${mW}E9P~zLBI4xBiL8~v;u+>XY{KF7ak3qxpM=r*k{cnIsCXFCER~? z+Nnwz;3OXg-Xc37g6;@uuKfY)s)58H@&?^cVX%0RT!zn2>c78+)jDN?&{Pki)ScZ zdx1SkZL>n5f%#esRDDC!WySIrcHTZA5o6ep$6*PGvlX>hB!!^xkE(#(_C%XL3C1hv zOaS^R%P!PZe_0|NZlF#CEkk_`_~d|G9b)Pnk;`}*i~sUUn)g<*gKyo)sMKPLxi??r zioaC7f56|Ep+CV_@U%Ot!Bsy>*=j@-3CWqSKmyic?#F)F?>n$_)Ta7stAYLySE>v| zwZjBYG=+Deeg;5dz)p1a0wSn(aN&*QWg?daMDd#OGoQxchY1L%0SffaxrgUe;X@4> zIn5M|`>M{=PhX{(Gp3UF&98zEQH2-&b67i+Yc}9d^)o`i===NOe7e6)Uf$$O#i*c~ zXf7Wg{=nWtJ5r~}*)`$*;or91L%zGy84a6%_e4%Q|Ht`V&tNTV?o9l8!x%M^(Ufpp z0oaScMeLA?rdi>^Oct_FoLu8T)U&@U7!_)*VC()mI>9FzjDpWsC^3i-Gz^ws+6z!F z-U=T2dyn`oapFw{+cx&41IGQr;k7})K=~-_0*t0D;6PT6{r@aL%P;RIVL6jI#~{z$1e^li&H!|>Dz=O+RXz<$(=NfD#$P6A}bZtymr#z!-6SQf6b*vleCc6E|!Q>yT_gO#I$Cq(JpFRNr zA{pk4Q{86s<{mJ~4L5*vjOTqA^UKR248%Tcx66XN}t4Ht{?BY0fIu+&Xth0pO4H2NujL1 z4h6PoCNL&3-@_xGiECvp_>oq9Q&A^cDlV$ZB?!Bh?5wqLl$b5c5S$Ci3eN|H{3`8* zO?7FeVtnaraemMgq`*fX{t`2KWEi4?^+kq+jYwtqydi$-iU9mE{0O$|r-6<6W$^3l~lJO_fmV+*LhtW}j;FiYH} zFt5x-wH>d6&WQc?kj2$~m8l07tK~r7;b6OIZ^u4tIU{IW?z&gP(-uus3TDVX0Tu~)yK z>DO9B$^f|ZRa#>0SS-Cz&2|)93OerKm8>h zW!dR6A!DN>tv2X(st;XV?mv#e)hxDqdlcrA7yzBNxurn-2JC0u{vLHOV6)Nf6buP0 zL*@SioLs7~Ai2?UyTWX{iozo1*CDy_&$xEm-UI3+cK7as?aa3cK4nnIEv6Eg+af(2J+*M|o- zIjc@xFLVz6cFoVb*_xs6l$OPW|9#X3yTQ9PZdvXN{RQooJ;o9(cc+0-2qMVh7#f2{ zxX>m8hCr|aA1iu8V?FTAOS{fD3%JdEm{DNpk!x_kqQv`B4z)D3|2s&#kBwo$@`r{7 zkCT5DEduRk1k`z89T+KW@zy%q;J5k#Y-8!#e9Se|ndE3RJtfe3MSA^fr?p`_^hIn<2k?^f|bz#>D362%{DsJf8Z*sP|_*TTXld!&0V5FJY9`rTf` zWZBg%TmSKPLM0cy7DpQw@+L|AQ1@c!5!W-N9=5DeB}C9Q!!dtS59Td6r|*N(4bsZU zUINfP94}FzI~f@l;ELNRKZc_mLtl3fcb&kI{jjN9m!-l&LpD!qsC5_gr&}EJuJwaK zvinORgEwtCVTMScn4(8l58{6ke;j*S`e9{nv{TRAS?J&T5Qmpl7ViD%%As*9TYRLU zCR7BsGMnsLwy?0kI&TDb{n_?KY^PIqZ??Rkd*Mz%fRd(6)JF=a8UB{+(98!lyzqT9 zUHBqzh;P`|mTT5-V8pstKyPKn#_j1XmnBiYRk8l^kYi)G?68R9Ko8&xf?H>NDTEwn*o0yx8;2G z%ORzBV9M?b@X2j>cZ*5IAU>PiT5T2#Yl0|H#;GUvzPU#>0yu%`Qy(C``5my`vQUGNX;uT$QeHT zh)D~8tUeG0PGK_`&eo3#_@Fckf)5}H<*wxUSmWIx;rZ>Xy$~VYQ~vE++HPIbKaQ)^ zfIpOo#fjxUx%%mN-FQst+>WOtvmZiw=~wD_5%L09-7DDCo*yMP-bA5u)eQC!kJNDR z9r@Y39P$>#Q77FAAeCbJP?Z*KjukA=f@dbRB?>qJnGyy+vibWZ;ulQ~HWR`}BOscQ zpXBq2?h^zK=7Ku}Dp#HQ7FBT6y~dpD<|WdtBAVJq`-l+NVg~mJIN(a6VRqltaJuq0 zT%d%1%^BDy!BHvxb?!y;A2D`Dr2j;bu4s9^>Kuz(hr2|B!srYOccUUTqDium^iQDQ zTL2`rpvAT@S;TqPb&u=#d1`-cF7c}5$+s!ZDJSFz#(4ST(?km*8T{l=%nd}IJk1D( znjduP(pI*#w1msk8F^%o4Efv8A5DQwGRP72<3lN9x={kik{FP{kMvR7*L~k(Bf*a$ zw@<2cuMPqqk613VgiE6hl0wx9J&3e;yV-o$(ic|bghCg=2D)|jHB+=DctqTAC7A8{ z(oT1DI}vOyWh{HV--O=)g!_5(N&>)gJ^2Z?CmONaE0}eKc`X1vf2r=h6k73xk}}8t zI!M{2VbJ!RIbKO8dPW9H5nlNoBPGeHA*11=9#yO%48N>e{)5cDwd5CCba|SKI^z5T zBgtsJn|vwBBtMFTt*xCEuFVmIpicV@_&ac)Bj%B7#xuGerKhn?I$$)6@94uzR6k8a zAC@>OE}n8y#+>gu_&ZvGW`@SVfadQr2Ou?MdhaF5sn55gkTLI)jDHF~mR&K4f(MK$ z6tU)#@L}FAsTYXal7fUea9C{irTZne^lYM%i%0eAw3?hDZ!?sX@p%Kcf;y@bNeD=B zSB%=*+xa#hPGgJjF6G)8b5yf~Y>zwNZ)&nib%p@yaXdpklrh$|`U=qj2^`IdMt4c4 zN|P8EkOpCSE3_2(G|vV<4M0= zAl7GVce~bXyP_2OxpbheYe8FzArdoj2zn6!Jdmk0GLnYP5cxA{TOuzfsxQs^Lcf4` zK|R|bMMQUhEq4*P^cDe~1E+gzXCPvud;f2N?%v-YDk2yog9UaxaYd}4p%JK)DIhTwwCVcEp* zZdD@-m7Wa7X{L3N$BY`>3rB(;eka7m^{DE{=;(;8ogEP@5$-Kuf~F(TU%>hufJ2d< zVgtdG`v~v*wa~NmrM$QqOqlN;uNHyi2V#_((a8PcOp5=Bs%W2K&q|0RNhtf`HHB); ztmnsZxcPwcsGN0YTd`bX;<$_}03}1CAZ|r`a=bF~V*gPbNLu|K%$M-9827@PFr^LA zg5DyLrJ(}q2jO$60#@U8c!R+|yCc6u%;JzZBJdBYupYE@XX#Wbt&NORZ8Jv%GO%cU zP1+503CBRcsYPqz*$5KGS@{Mm2-Unv)bKh2B(%E7YKV7JR=T{gFD^N?NVm^%0k}mf@ zeP5V7a;I^pC8I8b&5u)~6`BY7McjZ5J~ubg^DeE>kvuW+jmKM&skRRAM3Q=BqyU$StD`a9ozL7C;Az{oQWW4XdLM47^Y$f%{rA!^@Y8{9H}cw zN;;XJ!jG`Cvm@-}r=rD9QFkCmu6$H{N5-Oy=zGmE-ER84qn0Ebnur;9ofe70pks$y zM!pG(?p)#g1d388AIoRUj)pL;$BwUln5IhH|B3BK%aHV!$SNI!v)UXRUJm7rg{j9@ z`?`A2w_k4#VTA8f`JkQk(nMhV?^8cGN$^m18zT&UE*!b=al-jE4=w^jCacl(=62?rCFWA!yPbq!5z z$6>G(b58JcfX4S)yS7nRifg=a_^(tCihQxNL#%)|D~&d%C5kErXVT%Vp$D_;v!U9` zE`I@VX{@8V0_xu*9l%qv7jP`)L{(s5U014~u~~MXlMqm}XNCXNaJsxRj00J8?S}1rH%}{Bh zZf|7IcEFz#ykEJdH2GOR1v5##T!f|%h^C?Wp{JZH?oNj0Q5;a3&N`2w*A=(gdkgf( zlB01Q?^aaM6+KY7cRVJjt65%!LWD!Zr_DaFgpEMihf~J)oGc6fm7a>4L@Sjuh+z5E z4CYNVGK0|@rkLXQT&Sj@VQdjV(L$16Ec-?vlwH5juGEBopq#px&(-koc$Gz6_&Wf7 z6f*Kuum-qc=|RMB7#RC;5qbSAY7+q&249BKArp{u_KIK5Y7A6auSXk(w5oz+_J4qtl9H)WUGNTy__ z|L&QrU~3ncZ0;j#Q5F)&2O3b&pN7=RIyFhMX%n*`#iv9J?bO96NUmEtN+4`Zx2Bc^ z;~CCl0E7bG0j#Vj`yT6Gu+E(c0HK&?0VU3B`lC$^{9tpnV8V{46-loe+Q%#%Gm`nF z8P(@@#tDq79oGjPPH`I~Cxww@MKx`N(R^|cC{sRL1V_g2l^yK92;V5zC8cm>Ve#|0 zC4@XoKW^lkf)d6U-0g=@ntMzBkDPbhMc}S*`l`|vcVI3zeM~l$lhBtYiHMV zX(}-%&99zPph*)E`RHdDw1P+7$eZZUB?`FxIvO@DU-O1Y9dL#i#PR@Ko(Zo7FI6T6 zmG@udb)XyyzYT-Qnz7J^XzSQ)scpz_mvSLe3dX}bZ8-CVsdwrvx8p*n3QXFtt>OF0 zPrPY_tTgApF^LoI7Ic3ApMnL}7#>L<)#t=FHWDJ14`7FGh~tRHzZ0E|#nOkc^l_EB z9VKAmGzrB7idyZA3$R~ymiLlZn(tndkNR&dGQQkm{M5&(l}!!PLAgVLJS%@)ROhQA z^B&BEY|pQs>|=Rt-XbE5ZX=x;7KC?T?jvt`9cd!xs_zPX{g|XmTWjAJ8XTj65kZT# z9*jN${4_A_9ypx9xHQlKJBgAe=|2aZoReI-tu>-&XnnICxXsciMDj&V}&z!N*<>b%|c%gkDN4EHv!W;{{J_$h=L1{)q%-)dl$=i*AEOjF9M6a6G z+?yso+~mVThB;CGP=M?&k}2~=L9&CBwIzwKMPSHYux%osJOwSz!J(-iDCbDzl%%Y% zrAExkeh@+O>?bRq(vRPWLm!kdz?4ww)U2@+WssjI zPO%j-^O6p{-Z49P?HP^Yaw;FX&;)yPePh9b|EbSC_9?;(APvO{K5b((QC$+BG=x;v z9QFu+9j4co&N=ZHUaHnoJ(39to_VY^Sbq_FL26fx#J((*la!>&-=B@hcawy0cz;Ek z6ihj#Ze}%#;!5ZhSUx7En5vq)R$mfUhSk4%sTmXlp(U}0boamC8T~nWj;J-#3N}+5 zr#n|r^t*G!_p2mpDA=4ELUIxybtCZyO4k4b4}=IE{-=9Z#n3$m-Xm zhoS-xVm^T6I7CK*R``0WD2<%GC|YhjVS;a=Xf77`{3bUSKdib;K?8eHKBek${eiKOu@-QvRW4)u z$BXb#&8$1Cd>Ayvfu=?s&=h4}=3GP#T2~EwcCWqy=cHI*vZEoc%#yGHFQyyfh~s}B zJ6b8i^?d;$n%w7=iSmbEz$z_hi3m==SP)14SMmFTU{40ndyCN`%xJVcs%i3t!qH}N zFxuu>-4==oL8F&_R99J*`5C(tDRuB`_K`cI{_*OO>`Q>zIst$jA-d=K1Tk(f-utg^ zDaMXloE4wU43yG6@cwhd0QRY{KNYh!daT*Z*!#CC`vUAqBSQJuCq`n>`DEUJi)X=%>XxO*O6H)zvJIK2Q%jfb{cv*YLGGsWH>;mryp-#edWvDQAy@!xMz;o|1FcUm3rQmeyhXHP82-@G#e*LQ&f59 zYADKW%-?(94vgD@q`FXF*Z6o+|ECwQ*9)}qHh2ZhGre>=2a)1L3BP4fnYTUYWMQ+= zk4L!$@)+ZLu2K=d^$lqzXs0;ndDh_aqa5<1+IU1NHl{R!%Rv|mm@1*I|5cBZqK~r0 zUk}j8Id@&120bbnQ1g}Y&8*R%KO2HWR)3^Vb9 zJFgJu%vw~Dar1eNzBgi#h_g-v8(mu7K$y`@7^76K^#Mv#v3NDRlE3V=uN>fzma?_6 zT0GQnj^}0u#eKbvE~mZ{G5^6NO$YyG*?2L7V)FJV||e#sK6*HO$a^s2w~X7tt)XZMtzR` zpEUjOhM3IPpyH^Xo|QU5g{Q$JGgO*?GvqQS-;JMzBO!AkI3j}DV4~mYe!(44AOa*0 zD?7yIcAl!BK#DZ}_5_BvGx3?`Pi4onr(G-16e5_T%>?EKY*vXIKc$# zKJt7*MH%Uu^*bQFHr$&XV0)fuHE^o&5xlc&t_SGCVL2aVMzQNqIO`5)BDYh4lE~Mb z?Om|A)3lqcd(h<-QB@M}f0~g`?nBeandL;=f8l)ARPOmIq%EQg$Y z?1Xv=Lp-Laj|5g?KwQm?TfRkX9@W(&vf5fcd$x9u|1$SXfvvL+jXm2g1v7ZfVyEO+Ah0Kx+sM8!^Hu0pHHc^zPM*QPr2v z0@3+ZYEOUvscR_=wrxS?CUM-^*7v!$S?KagMwe#r;?urJ@e42>axocW+KbAZR`q;v z>6X5g_xHet7o$UWi%#@EwsV0Jt#7l$_{GI=WQ1ra5Zwlt5R9Nj6p2nAN*{M(Fn6Q@ z=J7wU6N#{j`4f=tUW8u8@B^nZxhSiyw-rFUn~kX+2V|#k+9QTR>``Az;KJ|Uzqfr4 zTy?j82{vu+b?%i)M6YUR1gCt+pyxu48Q3?3dyqnQHa5CO_8zwA?oJm23Hna^(B&xr zJ-@p(w!Z@8wxpW={pqwUv)fy-Yzp35!S|^^AK9kO2i(J4<5g|W^y{pB@_5#1@L?5A zJ7@(50%a$jqnY2jqI@j-D^?#I-4>^6ES7?nn0uq^E2%|aAFdn5-Ya^gs`GrJbwTBt zR|8MPzLN!9*u4m@cPGmRSn^dtjICG0ciTs3mp? z-JFF?Bf!HC+IxGo%}{w5jx!Tt3i4rmm7gGY&GBs7cnditq0gQ;T8CZI{scSzMHr`R z2&Fi%2fKhqxL;hu0>k3C1}PB;b=ml`F}h$^ag2=`31eKHL+SBU^)YzmAd)OtsvPkT z7}?YgUz^;14B4L0PQ!rRiQqVp%zxA7cxPf}!cD}P?t->~0Y)Ww!bLR&Q^G)Z1b+Av zc}=Xo8`(l{VE?HvqmgZtl*_O%V4TG)_L(XFGXuP0&?O`eek7GtH_ito3KP7)*03wb z<~64nsSqbTh*3Fomyhq}GA8cW*$3C&oIypZ@NUu(s4qZ8)btjh>3Mq%*QF*u6hVYozlZC0JKoIz-8~t{#H$x)OtQ%=h4-O90 zlvw@v;-I_A=rgkV89bX}7Cq{$;h1*F&K#cr#^SSya5TQS;V%Y_c3TV^@E`W+u|0Yt zg?j74D^mlpDN+^(uv+TR&S^fU`oX4nIy2&jEnx#IzPibywmj`;ZKt@>{u zPSMBqRhk&=j|1*CrAiyC?r#hNe-@xe%@}Apl7$JTay3gZ zE!UJpVq$*@%8)*(tsJio!LcB~=W7gKhI$r!=W^P~JT3?rUPfN@I@&qiBswTgsTu2h z#vc26{=bt#lKsHGTs{}`<=}TWpp)C5)~!tUYp<@vs^Ttw{)RmU`-E)*S_s!b&#?Et zx>KWmc*E|(7b11bj>(7&p`46NxVd(jKnR$@kc+BdZ-fc99D=3zv)bMe-w=n!#j+dFmd3Y!OEI9Kr!QoW)3G9BV~ht zd}sGq#B}}6Oys5o(CDEg0%4L&)>V@Ww7-`mQ0;ra&i=N6aekDbL3DM48K)-BH{;}6 z9pAO^bQm3D6fjH&w8sIvNt)SVjW^SKc2{qi+tSWB>uB)s2;vPgp6l+Ke=1yZYTbO}lNDfo=A?+nr+# zHCw>a0uZ%!*E==Fb~pMv>w0&8_s>~YX*7kb|FN_WLzZnwMXa_ihwlFgv>!WrVl!r9 zpv*pNdiB@7=ieP0G|Ue6%2xp4jS}NfS1s`LSd|W%WOOs+m<~p|$*>fyC;}(}>3;eH zP!iBxQz6|%^T`mK4M>T{maD0ZKhcg47>}?VD#sZn8>v2`$#WG@ENA*PET9#?*?gZp z!8L|-rLWa1G0Z_vE_0NWl^X&v9X^tXPqh0STaf7m>w8gtsseqPn+*2i|- z-Y|+jLUUANa_*^JXfEUYH)zv?fGi6X@agsdzr^~0Q&xx`gdumRhOepl(b_cNgm znl}p%I|Y^f4>bd&zqw!JtZv{ts*vfMO-2I`&@4DtT1l$YsKErB+o_8s2m^Boy&!)V z$s5(st8$l_Uq(j`1L1`t%C`fcq_1cukWCBgk3b}^QKU5l zt+d`fM+K{MEmngwQ(u%-HYA~AgWr2CxMrEXO$onzVlSYH7o}ui2)q78pEv59q>~7W zaO-qwHqw>!EqM+YTY3NM$3z>w!UqDPQB|aP4CHB(xN)G(JT8)qS*T$0US1rxbE2O@ zX)X#K5yd})`P&}t#Tq909+6Nw)_fB9sOg`?p&bABp6$q1iad=q{9cOHxdN=?9Ly~i zqP3r5gDy}Dy|LY>;W9-npoA{{PdO{~oSR`|YsZ??O3?2>5}zPuV?5KD059@;#A?~W zl!k`JYCW(&R6<@if&<8s0kR({d*BR{S9<|jfWec1DMjDsFhDN=z;gJW5HF7)IiOZ3 zbEKk`H#-_s5g7I5@SU1NONofnesV-s=hvD+V~O@)Ac7?g*rsiZ@4~{W>%17i7@)ci zF?((&+dkpPVxY|>sgSK{6JCbbeY^Z5lEd`4MSfFJRvDumy({jk{r~8~% z<}G#4DWkuEAyV4ee}VlwTbwZKq{!J#cD;jB8V$iK%JQP0;ptLW4&cBookort7sFu# zLH%8tXqeuh7l@A)w$%MvCn^{!HyNZQY?LQ*l|PK*Sx8Ql1R5&Af!b%I5<6>iESh$f zZ;aJ9L`h^L^;oX^C(y!8~3iW1m!D6!3KXV3s~C&!s3%f|#HQi+(A z0x50#5A2@z(oJLS7i+_%pR*BX}mya4=6uV&|Go^)aTF?huEm)LB)14U}h@=_O_ zGcOoZ6TduP-=R-Q*85%3nn;@p3hcxhd-|^;2a!i_7~V_uD}vFI%)ZL%OZ{k_y1sOl zO9a#5Y`g6y9^E+op|lvR5`Fb7=x>+R<>N9a5A|p;|Ir8{SbGOMXRN^Cag~%LL0$Vy z@Ck?$Ig-#dAQgsqKr?MAx<44b^M5p*`y*42|HoG@&3&Yrd#jWwm${T%(v%p9k(gU7 za>@OcyBNC6CC#no79(kt%q2#W2^qOeS%$aENGy%q`JT@Y-+y5{=XG9}=kxh!buGAw zlx4q{Jm^V6TqRSUln_oNo9enc|8BN)xGQxmmFqo!NC%URCJ+#csLII`qq5k8h?r)n zTfTgUNq1C6TBJ>+N-fM5Vr)@4SvtA8XOLea^NS2)kpl1N2byNx*OCUaTXX-uL!&phR1}A!+oWxR ztrJHvoBCS3#T}(w62;C}neXJe z?@8_^-RAu!NDMjXB&;Y&F;TZhTcP--JJfYJ?!s@a4~UKMt4V3H>KPbgLteU6`**%J z=5H%w^y`k8Phe}5^e6I7IB(0ck01Fe{D_SNAuP5_O24ol-Q!I}!9}#+;)!gj>MzBy zpYrN2ZhY7Mh?w*jNk0P#*tRr`t2@aXR$xh?UL<0xdt2^L@4r_$9BP14ClPL+fL2J3 zX~|$~XHZI(2%aLjg9XQ$$G2}(hrEU#O97Yg9!8tDgHPiA8h1M-o}dB@GxA#rIO(g; zam|5<0t&#n4^~NB$vcrL0%D2`zLS(daX|9_Kpr0(>$5@tv1!SG92t!Q!{BA_awHCR zmJx$2rG6?S!LQC+c#-+A!nyPy0AF;5@HrDxg`kalI{M_N^hMt&irpLuNNvr1+!nR{ zZ?^A&yRfAqmW;-rB3%{~bL(3U~qFvw~Bn%>!E_qHDtOp@4b>2oBcC&9)< z;4qQ^1XT4Gwx&uO7WJdOQQb@9OW|XJ^b6A|)?0he?gsb=sGnv4T5R zgH9q~e92W0sNoygDgbcTk-MkaEfXB-x@t;R7QpkopcZ2M@U|01X3G$FTzB7fZ@W#f zUiN>`pH&y|1Bgo>KuD@p^>pqEs-=Arc!YkPJ%`tz0UU6Yck_6)C*OZDrupdbOEr`n z$-|$%=tYFBJ-q$9w1#xz=fCDBk@+DgLtN|Pn~0-`4%=y_V5n4bFFUHHJ^mI?nf%Cx$bMPf)6*Uq}{(eY1U z6Op8<7+~1bVLJs%*~}27*yV1}6c!MgsYn1-0@9YUVgO(-K!TqR7#~=Vh*&qCFm97U zLaX73Q>a&yi6L<=b9Pk>ler~Z zvpL@k1ZFSj5`5h%+e!xMrR`hMoLVy7eC%(#@o@=@1xAzD#Qt$!1@}96a_=YI^>#N4 z0^x~6HX&~ixWoOt-L6{=EvqTvV8J+v_C}t@2Mh}pF+~MrV zLNy~*^0(*vrslT(rcl%f8l}=Sm-lI4T~~41!uPtF2Qm31W&N_i%JJ)L;kbNgsaPST zHou&x@yRr}9onmC4s*9utf*E<5a-uB)ETPpr-TJC>A^kI>OPfDtABzat%<6>xUu(V zZjd96HOE$7HNA}BpFZOC78#fb`#j+!oQOaw!FcV)uWk2cag*2-JF-^0PT47FD%9UX z;Ge1bSI|jp8Anhu)b;V6LBK=)k5FJ3r1R?gI8WC z@!XO9`YQYDm1o^$)ICpCCAZ^$wnnOYzCxGRe(W|LJ>&YUdCa!_>I`-H?ndiGs+H$& zwXUEmoI`E|alL-c(Bo7g*jwBi3QbbVgYb6jSAXlKDx2s72ZC4s7e0uo%9M!BGt{B; z`Hbi#AUtJLhJv(F%gv5++7%DKp6XFr*qsYUnSNQA8|vy;L;oRi=fZu@#fee0+mlC5 ze>OF}q5F)Lk=juofNp8c(PbCKZ}-&)JUn~l-Z{l#FA*vnmJ(z;Scj3iOTG*UMuwvI zSGXBT6w*zVo4$QrnT~RGepWW9hbmP4LjUd4jT@_*Hk`K>-2T?>A6#z88M!q+N)AEe z`Oo!9`Q>Hg*RHUOa+YXt)%9vV6(G7cN*%cUbo3UM)e9bGqoVP!Ll zZ!qnAvl#I`aZm#Qm_5=J=*hHvbX6v6cQot~%>5Nh2R|_R*nAy27nu$#-myO`hrHj| z%qg(PR*ycJY&rZlM%P?bUS1v!BWo+Xq|~qP1%6<*Y;Ses<}&$Qe_MW7Z$%zP8u1`a zebq&taYd9rDzTSIv z|5(`XogL#BRkaWK>Q1X}IQ`YZBRZXeQ45^CfAM>{3UQ4~+eJHnbJf_#$k%;u`tpzi ztC7Me!TH@PG0w_epUQYt*sB|A{aI!x@2{25R0%Qrv$?z&@=foxDW;k+o>K27UEfPF zzA!exdiO_}ggI(a1)wDzAc~DH)pNEN0u5YMlitBe9uBy! z@ZW_6u9juq!w4N&jGt-8Q-JM>_*GmtCXEL+&C7C8oFutoV@tkL3>4d2J41}%q^I)e z&BlUtXD^6lsIdXKc`?kq44MBsp~hf|dcagwwD%MA8B#!1wV_IEs!`sDjMs#Jj^8NS z`(3lQ)6nmD8YCCBblulksD4Wd=`|l!#BQpO zqTa(xz&_80A3-|#H+VcZemJDHEvtCU=%M!M@`o2>T@KjGf)-G4)T?*E(j|I=DwEbJ zo7gUzDAbZ2V+y^IV_r?RHX#vU0Fchcvhhj>S=J7;fAZIIMsX4A(YL>g>lq9{QplaE zX9efyV`##<}*fP_7thnpBdyFz$AyMqr#DyM-nd_I+zPDA)sU2-d;9Q zUkqQBfc@QOS z;Up25)_kwQCPaw@gmwB@)_jWXsf4`#Pi_#?)0Fc`s;#AEV^UfIDkB{JeaD}YgH$Hh z5gsyG)VqX1%QqB0=2Pzzb(bz)JiGfrdc|~wG*hGb4_(clem`fWY`QzGX1v$ z+>!jBwzM1}3jw68Wg=w`BZpB&9N>3`BxWA$)$it8wt;)Va~aA&h6uzrwRcUq@fBGR zVC)U(51%IeOf1FmbAS+OuG31{)lqEG)(y2oB>n@`T3F1U3}Iu(xBQGe$|^q+4*mYxww=Q?2f;j zL=YmCo!5C&CHa!adjKnlk@h`wY-eJp)78*bjp@hZ_50>{8cr8u{*I;uX9w-={M8aR z?k3egW&#AF(yvf+FNNO&m?TkvR+LvTVRq(1Lx1=~xbr&mb}B3Ss{lwzao~8amS`!$ zGeUlxw?q9i;orCjql^H*iv~Yx%0>wu zyi=Jh^lsc=$J#(Ob#$d;Q8r7Rj#4RoH=wUrrWr-dg}g+U6UIPLMZ^23d;+^)Br>hFK|LE~^QGfvb=*td+9|tI8f~&b5>h1cASG zzCt$jX^@}@`mtdrKY2}*qD;o((aLWu`LQMImwhWwu?@0;R5WU*J=S9E3-sh{%ZSgL zY;@y$7s_>0J-t#IKA*n_yD+V!~DD7V9Te&SISeg2vbL4yWTG{tiBXDcVlK za-9y$*eih_O}|(w!Kn2)=0K2NolW3V8&4w4p>DX=;(f&OeS>>U!!#`Ip*7vc^3wih zzcColYF2XfJE3qz@svbYLBNE#V60A)6;aU@%(;eKly$eC_2l~cbLNk&!J-2s zNvKW~Gu&4zk+bRhvh359LEFC{-ZbTeIgkhgC7O@VVDWD1Nr<@^>I~6Xu<2-(h^Pgt zC6ad@{RcXv(KpKUD?Hr;J@#_MC+!=mDE$mqcuie|~_R+1*(HzoIONaf+qK%!MM0)J87KXI6m8CdzE@@)j z8GN9ijruh3~wBGe+VjI=r_-6#P8QsRLS1We+ z-)>vXmKVVqSxz7jsOyVsf1hw#8K`Bt9K%@E0ek>wg)-51syQ~#`$Gw{nECfMdGe<{ z*XEB-{@f!gpkDhmYtvHyC=0v&R*T~b>Ej!iaa5NI?>S<_n7bLGA_xj}VpZBGEd=>b zqwF6}+T9a$>m2XRzq^Mx#&ACDTj1B(20r)WE5jI``L^v@wfMEAQPjhqp!Wlak$$hG zBo4JfVPFs~{g|q6eu-$5zw~vUtdRu2052$ zhf*{GFT65uX>M-zlQGg9+kp6x=Qk1=VA7XExoAOE9qg-B#8`3u-}?qzlRj{qM4hC$ zYU}P+Ri1=r)s*0)psj%YziRr5O_Jix&6JxLG-0_MfhBX-fLf)Feqd_17&@z_kc z6UwZ=ZW`GjPa=@d)AG2>d&`C-oN4W?oa>cjWBfPh$)+ozFSCO4+00h44ukJO6VBwT z%17Mq5N3%4^t8@0YZl{G@r*L9l`JV$;?;lk!*N*I0k2ZuN&cMk~Kzkdl?r` z1DuSbgJxfU@O9~2>&vC&tkQM69#jCQtlz|I?&t411z%QDq?V3Uj68lKfCR6$a`dr3 zD|Eh>JX1~1qjew3xK(QRD}H;I6Za2rjO=w&8ZRVV8Z*cE!gyhyb-s6PduXI+eCTXU zHHGRI1q>W#dBA%!aEp+)l|0OIcL)@OUtVs)zKJwX4R-tq8hDUg@w3PD+z>p?`JVC;~6E?JO_m_KIMd+nS@}BKZ^0%2*=e zDasR=X3hJO-nqtZ{0TPPhL`|LOd{8tD6b$Ng34V=In^KLumT`UwC9^fizf1)o_7{6YbOE8i8V zsezoq;_e3WInx@+gc!i~TGdzIG&mM?v2ij`-My~8gAiiv6Z@mO;9GO5ejA68*XKuJ z4E}Q6TL^GZCyRScCfK0he#eiRy=GlqmS!)J*nO^!@0n09`JmzG=y7X~9tgy>4J z4s}o{EfRb=uq16xxbOK(9zb=zQ0vFlajm{vD*PY)9UvzVfY--Hx5VRhv(cs;)FK*1 zUR!!`fgb(&E=w-MHI}ghy4Lkbhlh}FMsUe~!)RNk#Lq7VAG7Jl)KZ%>mkM-Ixam4tZz%P4GPdW;5FhEAMhW)5AWW*^^}~vvmC|e-+xa{Q z;?IK%yWSE020FcYhwuOyh5qzXIjv?^iKQ4k3T%D;PVwCC-Gm!X9~akNH#Gpr_bYiESFu>A4XNWIXy zYgq)%iq+le-T3X5O>Xbi+Px1ErFB4l!%dWG@6O&zoiLBbYHe!o9LkS%6(oV}X*zKy z9?DPGJwgoX0gCHw(bTE8=@ru_lI=&W!HBeQ*)++o(veO_t7b+y6NW$K`g46x?f~do z=Y;#@!klMqj#E^dOY3vy785;>i6lX}a^Zw3`G9g)92cnQ0afCBE(Emg+O6(&^bQ%ME1Bk?n4a4eaW{-TDB`S(trN{kB{MUqy!- zGs48dukTQV6Jxw-T%Y5tN{Yxb&#y3jRsZJywE%El1sg+Ep_Kc8fkh=_U95?aXY=r~ z12?8g9mU5+Rp#dAt_QF-C#}6wdraDYFfRn)t-Gd!m<>P{@^zCJsi}v~hE--Gj=D#Q z_=s7X2HBVQZF1M1o0AI42$&=c3Wy^8qLcIrD^z(ug2~zgen8kbiQ=g*!wqh0sWRAC}C%&^D&Hp4rjZPm&qD5 z6j}Ec%3HNlNgLprR#JNS*u-f;5m0%M2F90kO@D?6$70OLS~b&tiGqW&jb{0$7TWgrO&ncp-jm9=#8Xs4wdg9GIe?0ce2NBrl z(&L-WA$y@Zzx}WIwPYrOHi%`JI{%Dj(-A4aw_7fCD%R1U+i|2g-Yt*A}+fWLD@U4aw|A#IBms0HNn5qw;&3_ZMlc{?k zfm(4u0}9S?j(~?3Y5^pY@b*?(P@l*1a)vbOX?ErSZ1xSVhhj>qBQ!}m8P8z!NYm;& zf#c^nrA+K&FOE3!cDy$^|IIK8MN(~u73$vnKBXNXo3Rxno6%Jol5P%olZVvt9dAYd z?KOIJv%guIc&iX*0yr7ZtcSepIRVR}L+VPTn7|kPqZdPws<|p`v}5G}86gKMh(JDM z0*QxMVX)b?rm#MRHfn~)T@@BifPMj*}z8wSDvX9*l_N|OqoH<1}G&dsu+ zCs7P>kwkx{NKr3;nvrXcu}awba^Li{&UZg16g#BzUuM(g0ILJi$nTDaEWLY@L#BWM ztP}c9XVwV^iTl?VQL*;W&cQb{$%m}#>Vikqhz}vlh^R`V4`Qtmz?+fVyScI_KV$&< z=*0s(78q}%=M3fYvTQi%9M>uM8@e!HbSP?m!1<3@#ZcS+uIv6UX29OUbOwSn{eb|) zhXcFalNZWove2uDp9&l_fJXi%idp2YeQNqx@GitZV`^pZ@>w~X1E5l2BTW-cRriM- zI={E$?2joJe|cxj!4*$i2|f)zO;Cat(eL);Wxgal{_i8uwdF=W5G86>QF6vGGB#xe zK;z_n|IrpiK0P%o-&HjiGuAtM?$yV-2aK_yp(k>wdC1C}W+mAeb|+uFlNiR_&zm0-EO+BCe|`>r*J`+Qjq_g5mDkj3I~IMfJu1-fUs0O2`6 z8#|y^tQl2!mj*=5Z3g?32p9@Ose7T!#=>i1Cg$Q<51LyR+6*4^=b`nzf#@?E6m^bFpPn%&&mSZVtpqkY zsb)Q~)zEr77K)7d(CS-T3$xN18QC z++7xb^}zGV+F1*|>$BP8V(U1Xn?FlV6=Ntm$r{_Sek(5g}T0hy2L`km0Tr|PW4PZwNXDIm=#S4 zmZysXx7S@>m5tILos-Vu)ehsM< zIb%j)_)YluVb0Pv>I2AjvY}Hw#e}(#VE-Dj4JuIWi&O-wAiYAtFqR)x)4(+7r>-*r zwGlj(B@OZ-6>!%pZ2Yoq&ZnI`b1wTQ#t#JJC#{Z8B^)&bedGt#bPr8|cH6FDM(i#b z7?fol_%M0U;WkED^$I?&(6e2akxo93gol27x4&@zCv^zrsGkBMNW!mqz11Bxt0AX# z{0VL{rMGVW>d56x_#q^E!Z~;b7jT(c)7{g=@gxlNa8_@mEF6Y`zY^hKLv_PZfavtW z$n)UWWpy+c|6EHjNtmtL7)<9IaS^UMD>%MfBu3V>$^L_%6o;{0MQv z@(}1Pfa;al>CyYBk&X^lee~Hq`oMxTsKTVnRQr)O>g2a&K{$71VKDoy($wD?0Q6v{X}X`kcQPo z5kT_eWAUIv%vMLNF*qDrTzdSF5)4Q+g_mm4GR>C<#8Qnp1JXEX>?+f` zIUG}&=gwo#-uy6L9(0O8byDT93=9knHYNo~4Sw%wbnZ;-Ir3+MFFB%Oy55i3YMg|5 z&Rtf&;nc&rE!#CcWdyfD|7Izahh02}NKtFufV4!%#GD#f5%&SLN1kq)beFC`*RH!s zo4|0ApCTvpJ@5h~_s3kV2#{<-sn$7Co(BDgv~p10c^EE$6~EF^pA5dZKWe=Wae+9b{c|fSU*|tFSKY-C>;2_dkRcV8Q zLs@_Z*lqYjHC$0&7~^Xz%JI)YxR-y@5r$o*Nx7)Jir-sE^USlWk>cr5Yj9NV_UZ!* z8Seb5s@WfM-QR25>9|xpEy6Pl_@P_GX!CZL10NhT{XC=56AYB=s|`mIKN$<-Gz6WM zDhY+Tn+vm7&AvHKX9aAlWPb*?n-p1>CqG1FSwh(zw_Tq-RAT;2-)u!(Mg4HowL;1- zb7blwG6EtRgj5H3A93VdfH)@Ti4TJU3%avFy7f{(7)i;9i{hy=M#_bNX1F<{Bbwc1=L(SWCpmt^jrZlZTwZdC!!Z@@NOR^k7xFsKtbns5f9^ zJdD)w0r)RMh}^)Q^BgPE zWh1dm3S?SAd}O=m*IdF^eb@>e)FTZeBIe~5VRsUWvy4zHdrP~!dKFIQzLg`y7a{Tq z$DfE$Ug^NESQs25u2~lIU^N&&l|n%%`%1n`7{6@mto z*}-SKJe*U+quN;2L~c6A(GU69qtG14SA_HBP?6vU{r#cLv~Qyi0gK}tIx5w}Au7p9 z=CumOubDa8krjfO%NLhMmk|%tWu9<9LIJ3qq3c*-wuYMhDLoGMF)oyxCZ;;OGd12! z&@A_4{i7N;FtRMMt7OX1%0p|NULZjeN1$jcdOSqT#zaKi5D+Jdb$pZ(Li`t49AQ6q z6}()^CYJV8*QfZON_d^d`nUA}yZCm2OJKOb9rl5KxA?9{QE-X10Dy<6}Z?~BKQ(;;wdj+k#6fnxoRNEvVi zpOxg0_Kaj3JAejDpZ+K{?tK5^Nz*epWDVjNX~s=jCLyDw{&ZQR|Ap?(TO5`@osCXo zG%!`zwvO89p!S;F#pVbOs=IA}yr?~u1*j=nBHWoaB|^}I)8*9@x84O3|PWKYsl6pRFxVKH{wv=H(oEt z84ZF;w;cU+=6#U8x!UYB;N^>*sW5Pmu7Wol#C(4OxYog>`o- zj(s=c`L0Y;52te@B>8BIeu3oxC~Dm>ZxnY&i4qRN9a&|?3ct#gPgz;mlq$Y_==1PR zuNu%{Sh@FWK5T_Sscf;_sCMqHlR2?{sZV4udMFNvd$2(67SIE>j#r6=84rRy(?k$PXI?NT3|sT(ng~em8}R-P z5Fwb3?#91&dVKRkeR;O*n^{8NQ0-DW8m(V>DJayOj8P_y1hj5P$)@y%VF?$1jt6YZ zyUWr_C{g1PB*_Pbj&67dKcA{ZA!5G}{b_(++Vt*jWyCL}(FmXNnM|<@H*8cCXYsP} zNH4PXti24B46q)`-QF7Vqh4v(6B2Wvw$>_KLGpEOD3ztOP-#c+tPco~m&aw2vh!@J zJ)~*GkW_ga6e3vlUD6A769waI%x7UCE^;b0^1$HJqf$0ygdCzS+beB&jGuEObvkU~ z4FXtpnyNn1_@q-&P$vrQaPYZG9$2I&T9bwwT-%DsBWP!TM+?QWot>DQ=xOvqh6L=V zYRO!>W)FA?L_P0C4WSv|i~d46U-UTR5kfqKgr_<=B`+h>bvdwubp%v*_JAdvZ~oHu zuNTnLj01iIlB5@TSmXNPg_$L01SpW|5@fhQJv8r1jUEzk!*4>t3*bBmF%`;cjRYff zIl(Bo1hk2i%$tJLm3mH|=2a;hBm={H7^U3v%5Dtv0{aqxkelci1mp%m5!vMW$CGD! zz5sd`Pv-h!{RJ7Yjo=LU{oO)Pe7-zXmdbd<7;A8ii47aY95Ah+(1|BW%vf|r+{-H8wj~EAm+qiW{vLg4EYs(oU`Y2aJ zwUW>d1(K|V9~GeCK>iD}y~p zJ4G^(Wo+~)D+8zV!FExu*5xEtbdLb$J)@P_4-_87(z+aKWfz zQ@h(@id|W~+@+{yKcJwwq^j6Ib1TiT_2>Pn+G_z01z}f*dWAwWovcs;<`F;q(GM+O zWxX8H>wl*G?}Hz5aw{cl5KhWikAQAKuu+ZiIz|1k4TfWCx_=A0>bA!0tLzgv{InM# zzkFdfX78j7&U#EHbUq1q@a{B&LV=7(3qb)ncT2hF+-8Udo8Sn;;U;UCryH#>q$~1rn>M0EOHAfG9qwM~WoNva_1<+klzAdLX6 zO2R5Z!zg-vqx^CeIfx!z!H}l&mEf!&7b1{bI>KlwNuZ1^%8YyRgX_=ra(nYNHPVv4{V&)inNenIw@7e7 zge7tp*HGX-%K7`w%#w!xK8$BR!+-s?7>>o0vaSKP8y#%uCs`%V@QXdECX_XnqU2AgHd1{ zkuJ+Zg7JevvgYuOa=4-lq{kk9Rp3F=XKz^wqAY^b;m35j>_zSydV>QaXhhN8gVa$5 zl!U2@d~SLM&s8>@EuEEyZ^UaWO44|+p^lm3_+OK{er zWcU|}%zrARmL=xgcyj{>ST%|#`LW$TALZVfh}{NeE>%NnOd>IpdYD!kgGuVy<^EOsP@|%QetMMR1fz zTrHBM0Ew=@vx)Jxs22oqBV}2MLB7|SwB zV4gk`##So(!#a@gO|RT^>+DOsMB>o^PHa+n*(cQe=B#e+r{qaMfu?g8NC`Ibodxv$ zYpe$nmOr#C-mLRmVdN+(+PnX~2*A==*J$(G4FS5-|2@=Y!pD~K<@4Rx)G;6Kh?G~y{@YVm?CS3v&_F?tdZfIpnRV) z>C|@w9B=z#{Zz63=REV>l?8#wUe}h`s=9Op#6*BZdU`O7dA>>{-O<;Vd=m)65|j?? zLBr|M^hSaY&{GWQsSP{;Ogf?n**U&5T25ewnI9mmU;|m)Vu;zyEQu4jdYCFoH)(S9 zdzVtv7cwwH?`#9*aDSsi0k2KS>}%q`E_k_kI{$~hy0F&BSZczi2bmG(kZJR<{%niR zyJMJK3PalFKf;I|C;b|XPx0L6JLE9`R7>^d3)wFTc=*feo9e8nMcfQ=#qg6|86(O- zKKDm!eDpPe*d~_GqM=E`a;#CcEaRsR)|lsug1%*X1~?c3;eTKWLcwj1<8qvWm37XQ z6DSxNBh=H76!Ix7KJ-)a$M1LAbv&<63Lgd$7`h&^&j2I};P;-MQc7-Q`I{^a2v_edJ>82(H-x$#t7+MWLuX2Dxl ztwDxVH|*rA>q-Y@qE8RxOO7ty^bW&_!99+-ck8l;1*B3Bcwb(uHJ};@sq$m%&YN@- zgnDwHUUv=lB>WTIta#NFDVwwoC@sggoiy#-xLN{mI1Cs>KI%(`!MH9Pez*N5qD zOuAc;DPtNiY8b@nH!~$LC9)6;bj&;%bKbR#6T^~Eu>=5Qq)~!>%!*#M0g_^;$=bFB zA{~D^*!>%$S8i^7IM--RyOwYMH2Bl;=zA{u354K?>KruCDI0!vLO%qw0xt@Q5+%0a z%lZyEd^JZy|L#aSn(DBTV79X#sLY%Wui(~MOlO9ywDTDGW@`d;>WuqFJRffZ4m}%I z^o=GZSd1_Z5~E>GMw=bHNP{9jZcb_Sv$lt(yvT|LzvC3}mr1}1Vd~^D+2RR*nFs!< z?UAWnSE|<5hU zt$kMLE{HHRG-x5Z240I})<-^9=Q~^l1flWVCNBA37@M4{VZ6qr!_`qiM%VSc$#Zs6 zcklOzg@3#*Ay1&#wPYI$zgjm&T+FIThBSu^xYhsL-)!5FC))in7w_&j86J+{!3rsJMN zvW4-|JG~CglXLX?xfw-qpK%Fe%Iuw%@d130o?HZ{ z-{hnOw4$S(?=u%`KNC=Jig7nzz8HNwFH3STI`w=DTBrmM`2;?U@&P81f-FBK{`|B$ z7_MsQ*L3ei$kh3~=Zp_0?l08D zPqze=xvCvg1l+^q5zF~qy}jnP&G+#;Qy%hc?vfx#E%&`7NDs0hr)DK*L;mGX ztZY}_VC~l=jih=*KH7bbN^YW=x8X*+C|-lUVQ?LOroHpF3e46#`E$OV4EtP*WkZut z$&7|Q6W9-s2+Nic^Jhjdx&Y3LB$1>&%B1NuI|uaE7T56~P=sBjch-IdjYm%ibW>y* z+H7DKau*+@`cfa_gC)AjvkfeX-^QbH|Gi9~IF#|N|9t4$bmzCAFy?JauX02%?Z`vy*(_Mv+Z;{9)NWdh3Q*XH|>3#=M*b! zePdf)B-u?lebN7H{4Mcr`MKOR2_!THmYeuZ5Qn}42CG7`u+F>_M-v!heflVu>{*~L z9E#$sudgefhHY{;J!EOD=!Z`c@-{e@FF7xNH2D13OA3GgYP)^zr`zWSB?yGk-XjYU zN1lJr&>Y04+;7$vtphEK}tQ`OK^_$oJc48-fcx7dM_kRrGGvht= zgWtpG?S+(GzLvF5LOcg|4(vSoU2yNCP||V5!4p45?nKF|+C14FUy<#O>*MbH+WMuox0O5Ozuvic0rev9Nyz!m z`wqG7(2`TMjTWc#3ar=-5Y`$6M>f_cMv3XB(_9DsUkf0CR7Y-mUwV%41m#UaPs%Pu z4E;7Xg^MHE-s>@OFL5Fr36PYGqnW`W-M5ci0SD2-n+qi03~z<%i6lKJH%5XLL%BIN zjHp9m?V}2XkP$7y(_VcIMy8 zt)l+BsLJzE1I8e;XYca{&8ziD#3u+7fhpo{f85ry3NGK_PtX^%c0hFBqwVWar@>p2 zccSD}nJN6DY{zm5Cyt8;bfr5XIDZ{&w_aF5~UWWNp!NJyV^O_O-zE=9?fULd_I$O6vu zYwF)WPv@gn-zW_72w^a_;tafO@~7?-@CvJ~HTuZQioBg)yIjxlg_vb3g~fLlhfYKs zJ5hE8QqF4*7u}|!QGu;w8LM!+yCLwvz(Z>QtM_jnr5<()ng;*rHenK|pH&`SoKW%e$Z+Ww&j1VB&MX>3XI{c>WHThGNpx)owb06Ds(4PwTW1{GA z87#w35en5lM*~ai(H?4`lz!BU2;LW`!T7y8nZ!~;6g&DF;!0&%i2PyUc^9mOiU*~B ztzPxT`O~vTa5K0M8BStz9Z*v(xyT$lG6nh+gYvyt{!=_^yZcN(`*5i+JqwD3PDFCV zKT$6zA#5=jo`Eb%dKm%nd2CEwxUpn-tZjdbhjeak*fFAAN^_MJOs6)aWKNza*Al_f zz2&>|N-2)?&HDxk4+fwjm%)H9I>vc)anUys;emH|C(kBkqun1S9E#rFA`7uF7er5X zTv1L&{6iqcdpf31p0EeZm|R2|;qoL2Dnt`U4(R}%pKd@Y{lf0?aRbqg7u(xm&e4m= zKVgms5E+mY1QbjOt4Oi~yskNd|JAdiaRXYy3Wf4D8KaCJ?ZPk|+VR@O+&8#iK&t*B z6436K|4G_YloIsy*81j7X2vUXdlC?jac zfJESqp=VSPRgq`ptLJlFX$14cu$Xl@>l=W#f*_kCqXve>ZaW$A+)=R%v63<|F)?7De$XmV3d@S5LG58mCF=J*@tu;B!7;Hq zdhFJdk#KVCA8=Tywk%ux6G~}_W zOL3^cm&(DeloBTTckO@a17#5Om&oVGCGE|d-vIJA;iL>0`?OszN27 zQ*b~O2YzU^!FB(+MvDGXv`^)mhNh!d<6_%@{)-{&en4mlg5}oJ7 zh-OBaEB1H1s#7Jcx~w-}EIx%4Hstk{W2^1S6<4&?1wjU_rY%HiM9VX4+5xV1igcE?H}uJ4|7N|<9A1Yk-F<|b;)5tHF?q|)5|Fr8qU z-Y@VP;R%rD78R1m5!ENndUIi?0ZdN@?7`N!r$8r+)h4W+hM3$HfLX2Xua8&w?oNQ6>W2z+~-9xWy+gc~S6 zL~pur`D~}uL_K-z= zST;Hx2BG;>k`hFo8>|1+J=A{u`)P~mwJX6!{bcY5p7LU29B#os|B_8u=yEG$zXM|B^CRA8JUA=}()@G#hUeZ6-q;nDudFb7=C@a4Xl<7WS~hq@`mCuP>m8PCo9$Ml>*1)cr*d6q)4Ll z=_#~Oazgl@2))uL*XN-Zmuj8x=kW;Bjbx}JkLQbicqc)LB=wL0pFjTW{iXds6Z--C?4m6~OBnH8-Tf&x5(V;( z^7!%mA5G`t&h-EP{|L=_qKrgK$|~AY898K18aa%}oGppvoSYA_=rD)3Cd!1ELmCxx zKIG7ZtOKSThQwkql2gL(`T1Sf_YdfDY4&(eO{xV5vp;GneGAP_Pj$ViAN8UTz-a4~DdtNGD8_W!jLfNX1`(v$0Fd zq8)j;AehtnmAJX9WofwSk<)LVnn2KZLv-SarrzJ!X$5k-ofYo7xdii8e*_OMLO<{U z3z8MY{rMK^qx=;z3jS^;>P*7ckNMlLhm-ntdt4`TDT4zm91rt2J72od50Mv@cU;$S zEm^zaKMXat|IW7rEDLR;-YZgYUr(DMuJ1sDL0bmcpc(v5tK_Sw5`kz|L+ougQP7i1d;^MMdQ2oi+LaE^TI0R2gjkRx%X8 zN4w8yCR=sG5^nRTS_CD%1Bj_svH^PSN#4cwEU%hj*={7JY&lfBCg9VnR#Y3FN0S?o z33JH6kwN4Whd^~e6PApEUOSwXAaq~yZik4XEZWZ@4`;m`o=s?JXclNq)&j-6mvfNl z?Mlm+!-?)4kU_Qw88Ad_L1KVn*5I@kfzGD{TR^XqT_5-8Suo^yzuaR3T6b1b+;$tE zhh0KsE(_+`A`h;Bb?3PBcPFKkrS&Q+tg?k=n&ypH=2g0vcOD2R4(uNa=(h8cX*2OA z1Au~ZZf@j7lQPa(&zr$^K`{=#zEeRiF?{XVpN+Ar6NqUivqgg2+4$v=XUSAWPKiWTr>Oo~Mcx73H|2^mymzyUBciKhSkr zgnf5cBx;maQ+H2NjK<7-hhS<0F+=Mhf`NNa-3`A{x$1vfjX2AH9qaZoY^WWfirfT^?UR&Kq|WCcKi662gkU6Y^Q}iT2L_(*5t7YxMFw zu*B~~yc~FuQBKD(v0ZhCK_2uSY-ee6+2myiNB2k_1Pn}@f-S_I9rsX!S;gKS6#ZO_ zl2!hWN>s6>LGb-3aueacOs}Uv-rKyo(a#oz zW8YJ7rIM;bWojns9XBW@`{Cr5Aqgn#QTnY9_k$19{vC;31Bt5>xPWszb)>rOKKrH&q5UF$zK4fyNV)Mz==ruoM`8x zbn!s>pOjs6h?;@OJ0aSsBCE)q9AU2ByQ-VR=oD0ZT1GM(B1_U$r39B!%n|neROtfL zaJ^`kC>)yGXX4L3*-aYP@%*|?4gQ#^r6xz{P)|63zGmUktHvD~Iwge_B}2n9JuK3Y z^G&F3tR`;ef6%-MR;|;^T&}mXHXmN_Bx5%{sLt;fM%uyd=CkUbi_HgzIB z5lXX#ERXu-;v^6QY;{%Y5_IP$m0#6!(n)s5iq4;$e_5G**Y|8ph0=}W% z^cVUny_#1>#2~A#vz9tw?GPgUaY%y1vHU+#Iy;4tVTLJ$i%pEfuwXdSgh+QRU+Lpuz7tEr2ylS-X=kkzgED;IB!vdh{(N7xfl z*kLGsEZXmKr=w31rf6#eMg8zp1;7xS)`% zv-N|&x!1O*d^k}Z4k^Y}*}_fG5-zUJ^8M-c0pVRz}T|%gB>u!JsqRZU^iLT zS$xs0vGww5qmz?_+@q{V))Aw};pZV;>KiK)J5}ZWc}@`c`_9uR_Wy@-Gskt)9*2xp z*;%pA@TdD`J_xIP2>5zgjhnmmv!~BFp$$tfN0&907u~Twwr8xFa2T5zjyZ3Hxsk{Dqbe)X(y1o@}LIgwxv@P~# z^+gD(8*`6QV_y>ry8q(bm%s%{ayZ=vdzmsgI0#Ni_oee|Qbd`gS}3HA&iE{0wY~!t zjpUoRTM;M8MyIAyw^~1P3=Q4m9sOzAyeNbkO%6kf-gR4_kO&o&IMI4ld@Nq0k^(r! zYAuvlQHzZ6rckUxK1?+p6^}o!iRQ-RunKUweFe0MQ0>mHpCJrsu34$CvoZ>cT*rM9yZp*YtQH2&R;~Yj_NW{$8y#UsUW8e; zU&Yc$Z}S_ft6z#!EPZ>v`0Ps*aF>XE7OdOU0lH05-D;0X zy1S_$h);$dK2+49PN&1;slY%`f06FXNp5$`>BASN&AT=YRo}H1*{}HO@=-*c9K)^^ zZH4z>!QZ9-&fd^QF+qLfE~-2Ohn-4Skj4F`zJYouUCeqA-0fFUZshY8vH{sTKAVuu zL~!fN#aqoqQ&4_Q0)25-Y`hw&pMz>mP-qG@{L2~MULFHQz|n)blX+>A~GQ(X#sPNQI03GfkmKDWCK{vgZ^Bs~+f@Kn90sP%`S(achjo&cg0$9mCW|OZgeM^_1^it#UY0>qe@F`KQ>k8hV1( ze+*<(D}()zA}*)^)25Au7|vW!dEJjRLAjH~R1_RGna#^~*{2kTo*b7Fo+)C-qw>KC z`$Xntgg0I5`b|d4(k+L~!O#k5E3ZC<`6^Yz6!8CL;h)|nGEl!f16alG>a@m~<)dMI zCv-)b^^0nsDiOmA=C4?_CP+jk1&r^^XD~t1cw;uUy5%r#_C|AhfA*=`20WHS5JMBljyrXWSeR(wz;m}Ktuc% z@!#K>e_QM8o+63Rf?MD0Fz-DbC^*_R`F2kSy#EqXaLyTvs0(04Z$ISA#A_4XpIFdf zKw<(n(YQhmTn5KSRT7rov}{Mb_j=U=Dy1WJ{RVCNsq~Vc!ytPoFA3OqyCPhJ;*T>v zGlfswJ%z2a-Tqz?n|v1F%A6v~vKa?X?l#9o-2eEFlGkB>$up;tW7c)YQD_KWaI113 zS_rOk@GcZLjSE6h(!7V3?JRrlBE{}luUSbZuykb2qZhCUGV}vogn$89KwguzkHh1o zH*x;kjZTGWWuqd1K}@@nf9Q~bo3Bb@=`x-ui8@Hu#cYJHHo8DOQJuXGSO>Bw;f=2y zRv^6@>}4e8m0>Z_jk}>hR5-drOVCH-G=7BDKIb-{8di8=g=NQ6x}38td!35jNPIV7CYo-0q@2_a^-UOrc=R&_HQ*R{^Mhx&3STmkI*k zo8RTjf?<=K0J<;34sz%05Ptb&ZsxsNrRLFJmut*wJX6z-9X7_NFFz5H$*J4xfSL`3;*W2tOuh>M++*W45F}a_>R~ zxjO~FpJkfx8p;}mz>qDR|6HDGWB%CJ#;GXXgG>(K)v(Xb?w4(J&`!0vhZ>wUF3~W9 zTVK?+*Y2rrJlFC+M0iPLuwD>m`$z89()Q-qWR7YG97qcs->UXyZ}hye!s1v4hurp{z`ZkbDvGgh`<=?>=iJSy*bb6g zzm6xQfG>E}WM(*fm_4+#{=~Yd5cDc}xJ&U%RGZ_p<(Sw=J>}Km>9v$>hoMqgu}q1kD;S6;I49kx9GeT)h*Kf%Ssub7;O{t3 z*?6%_NZt8W7#u#OXVFvNEU~Sgl<+F;i;lc;A;q0!9QCBPh8gIOHEY zEEugLpv>FBOo^WQ|LFw8Tb*6^$Nnx*aU&adBlh&4os4oAwA-lGxaUTeDG?9&VUHb5 zcekn^n?u3D^K|lB&NjIDJKgKWFTjqf1q)nHwnPvxB6KiSx%SE+DlDw=CGXT_OH0df z|D-D=8IQ3?)dq*oVH5W~v)!F_e*74z6y{U1%B(X*sFHBzd70(6+aZCiwEiOFBdvxqrNPn0*=qXhfz6jBJ#m)l6Q!ak9kWuYUVzr$E9a zk&Zce2Q>=;WuP*wqIzXiScEN305&Mm-afgrut|EOeJ09;BwE_Iib@>9oByW;Sl6uR z#ThQS613RX0d+j-B47QGKcy{eJaz2`ceHQ4kcMe8E3NiTxOaz=?h!Pia=XD9`|ZL< z#Id?U!Tfh}HiBYCzI$A5^P+f{5d*}Yx*s5mcUbFozcANihPMe;hp}5>F>HX=N))A$ z$n86R9EPG53dXlzaTJ7A5(GVlXKr~=jsH7)>r}M%Tfx10zbFB>5|2TDJsnp>&|n3j zl||$)ywSB4pVg*GBdwM7iIS&!6fg3?G_6ahk^=Ay-$|mhFX~FW&+8 zN1o3msvM*unsksFCl7g zvG~(nB?5#mjsT9Xwl*+VHZWAy-l`KD8vU01@7vfv0BgGg2;#?ROlWXdgLiXX^K;5L zhws{?P&_knYdxSD6qw4hX{4ByF5bp)Lr;A^r}g`-(CEm>=qb=vxlvk6G3g!vQ*SzL zr9L;bj8VIadnj!LQ4=;R?V#S#y^Oq2TfkwU;3oWnaS8H~x(><%cEq!3*QSlVvbXD~ zarf8}3CtmiEK@zB>NqG!f9e)Jb(SPUtEyq?6hpS{x4-8inaUrl?cUx1XI_C9jk&9| z$M*K2b&or_M?h>qBD3c??I?Y&D7@0K(-e_|#j~$K$_sy(|8VlrVBO6M?ov3^$97D4 zvU@19;kY>Xyt>r;tp?dx$V4T`(s6ljK%irA=#YHDXDF5jXf;s*Zf|Frn6Rod*`q#m z`l`2*0wFG16n?3cBDdqmZ&rQ^fNAu+>wK@%qjq)!7a?X`@R^JYFj0p>b@HZ39rxB? zNT!K&rYAt`V(f_-Y1=>f+rPHgXUjVKCc*EgDso%E+_WtDWPSNCl1yW>kE;EtHMGJG zhBP!cC(2&IcIh@`Pp4NdDS!A1vZZhAe!l_wM#hzbTL>MXA?|*Cm5b);WCDw&Q$V6s z1;ffb!XH0ltM#%N{N>4Df)RC(DV3j}?iPgbaI-+?2&R9s4{Aba815 z*G%E~>I4+xh-UaP#)^qd5k<;G7BgY6E3T>ilx!Qemy;C!G?F)aH{Uc$BDZN%V#E>j zh{Gh@pB-6aUlR$FHHMJha1 z=$`^_!tvh7-~%K|+Wrzjo#Al=e9R%%25Y_$2sDZeGz(5Yr$$}& zQCtB4=x|TH7$SoLf$!71cQ8Q#%W~@K2@+7-+Z~vH+y-c0E+LHePTh4JRLuGSFK{4U z!Mdmv+uQGYu}3@I)w13C5}kC7yjw}eq;?-%s!uLTDM^6fL_CAnr-BA{)JDJqgz@3R zX_uf33>j;dU*!D@5Ij%t1pf=>DHRD38hx|nPBIVB@V8Y>jWiWtU^&^;8AI z*!I6A%EMKT126g-`4$Q9A1{uqYi*s2s-xEUCO;EhpXa&mH1u}15Bm{8+`kOPbiW2@ z=L15=N~0v2LYP0Ng8pZNuy45Y>yl_PoPzVfS`j7qWp+L_+0o=oPk|aii6;}&9Q@sw z#Bfdq_<;!SDB9RP?acK$ClZAo(jQqC0!vJ^(hSkI#PeX2d)wam)!28sHf>L5y0(-t zp0VV~i_6QWql9*80Yy$1<%`ov=GxYPe*Pa2@${&UYkWcP|AN&B*mVJh>h__teR1l% zm+8B$$|zRw^Zxpo={Ov2I$eao>Y19J#Unx-?AckpIOCp7m2mveS68CN^`MeI}%1RkuZ=7pZ8X5NJ^{P_>xy=u69a7toc03%vJ z*24Q-fLKn-+0543#2abJVW9D5U3GEy^;>`Q8*PS0oc1@x<{xa7bN$d@>Dr`2m&e{X z>L8Y12teKTb>hIoO$jy!d!E0u^~*6X_J@C*XkP!z3mqGA9xbGvbNhtXGHDfw(#>VM zzdUWc;#)Jub+Y7YasOreH^YI8vmaT7ukke&k|k$`Z2s&yKna5B>++4Bilf}jBmDLVV4U(*b}gD!l-0TSp#w@D#ESvr*0 z5cpX)LPQxu;A4;>KcXT)IBLQS@*kE7k;PaOf74RprLJcs!ad*Khh<*Niw=F`|splMC>dO1r;PRO1C02^-9G(lyW>DvJ6%x zljwsa^}|-x4^Y*&%jn^Jye~srb~NQO8}f0z!lig!}R>#yVAwI@0@(R zNO+=SJDtW^99Rrv7*?^9t=YPKeVUNc{r$^E-U!c&(b|0EEalDibj#MG0lWzU-VrVx z*He?*=-Xs$W-@oWLtRMaL!9UeE1$EB{E?1ovr?DAe4V?^Sm~7JTVJH@WeFdKu%r-N zDBHQIUN|AivmNipDKf-vN_b{i~ zs|~!Nvp2$@!Vg)QeS6uY>oR~lxAz7k123YbP7A_|=jle# z?M8J1xd?+I=J}3M1KWxD*=e}ueh=08U0=dka8l{_5faoiz8dJhxJ$zD4xOE_e^)@3#^C|a{6 zp|+081~+I?61-|fdd3eYF#3QLzzUpr*9TJ~%W|L{3Q3wThKC*bO}0T99W zCiJ5;xbv&wxwkhiLyWRWa=QosXRSJDhdL-3V&d=t!7M3k6LKUvL-5(2&XN9dviwbS z3gt^U6<>h~z(8b2)FpqaVb{!Lk1&~8eKSJMo0f)~hnR6PELzHSC=Mf!%CD+<7JQQ~ z+BG&ZdVnM|%cu%hwmw3;PPzoydT8l-qRbeU&lV7XoYzvj!k0V~H@1;8#xw^xd>Uqf zio@!JjhzJxBY=2hJl^z^-skJB#)R3tV31%{wwzs8!-EhIRrHk|y^Xd%-CFyQMd=w( z(i?ff=Rn2@sH%GiI3H`=@ObN$!3Y9XiwxM4vGuj;qzCYW{f@joq{SqpXbZhpyLZ}_)KEr~@xU-vCvScLIs*uZ+@uNcW!=ITU=*zZ25F?Nh6MS+c z^Lv6krs~1gnsjV#NmoRTUv}Kvt6c>Oy0Zd*uV4?8tT2U8Qks!8%7iYN4`WR+PS;+P zYTuE4kSyF9u;iS!`*9yk^=cXHNX_7ey}g#&S``pYr2`bDVf}*pFbiQ=w*Uf8^3JAv zWO9Q$e`Ss}x<<#;*Ww}(y=Qk-4|5!Obhe$NEamcKqn|kW;CL+_A0E7|_;i68NO6K7 zz#+e|FZ`0u&0&%I*8QK8l9Ij*qsf%QFp}bT1{osu}heZJKsqCi^I^*r7G$%GL zI0f<_Y*H^7V`}Phj8+qJ1uv$Fpy9J&ec%t#gp|(ap)JVPL|@*|rH>q4KAPKIQe6DV zuFb*l;|8Tb?%>o9f)CJVC$&mkhkUl|%L@KBcN@jEBSK!UPB(dxS5ty55XGLO%+>=! z#eB5%P%ipuSU+Zt)Lfl8IL4j{sDYL9re8MB=yqj#juz zln&t(yVhi_Mfb;j3#=D+Ulv3?z&W|^4_;2^b zuE+kH$pt@lgY#D}g;h85V!RD@83OX3(m_9aDs!~-f=Je2`%qUM551%#c|DJO$JHDw z`YAQNZ(wnuO=KoS$((!+7I!-zvnGy9LEZk!ceAZ_D5H7&nG#6^2^a@1jFzB44XyCw zSFwxxv}m^!r+Xb#;&%%Iz0DPLVKH?)D9)-!#}V+7P$uz6IC|>TWdbXF^bGdBUh4L= zA-Kz}wrooa!LK&!a5F=mB>wM1dHCit;i9BTe!vGYgrMcx)>e$e33BiQQLlI;j<_$e zHBx%NT>L}Wr1-l`5XSZT5E#ILC7iuZb;qFP`}7!2fIp7{lu27GJmb^kHF_^R1JBB= zR5(>|dV2s}#zCcrVDxnci#7f-?`0;=U*K z`fX3UZdJBK$G!nh$IEIAj*kZA!GLc(idCDsE|`S|J7>X(xD3jL+=AAUAgoNzEu3a)Rcm!USmg1Zo%S-7s{m6d70jDZ_3 z2xomgCpP&(XIBf}yV612On^qxYE^iM=*KH?h4R^oo)W4;CxkzsK@53ZPBvdia|&hB zx)$>+@S=g>e==Gu(OY6P$PIHNg#x8zsm}-0GEyCm?Zhwk^?e&k26Tn_rezKdC*;o8 zSCh+ohWx9+@MG`B3fw`E-ZQFF31)8eIMa>S9G>Tf&_jcp&pDBVKfI0XLHn~^PsAr~ z>c4}mreHMT^76lD3Fe5Rcu`-7a4xP~vk>RlE$kP>*c+Gdc6ojBuKs@R{?-SMB zw{(-Qf1Lxh>Huc2CRt16AJ^ZohU4n$9KAW$Fy6FU{^MxIReAV86=Yz9rc-Rs2Ob>GKUp0-k$7ZgD2tl4BTCYv8i^r{{#q z3GpiRfWzP^kZ*hR$Gll7ejjVC+JSzVE;(^K1YJY{AMI{z%;ZLkz~t-fGGf@UdVbsy zgPhzzerCvj26L`-LXQE?3`$()S?V%NRd=1VI2BZFK>aA+FXQDTwzc-}W#J!= zWqV;p?QwCn#(p^)wn3TmY;O(NMtPz>%xsB~&^uYa~0r9a(OGl1?*kK|cZn5YMWNedRdv;a07SS$u6 z#710b8Lbk)vnU%d>tF7#Iea^0#0Hbc_R;2hV9)&kO09-TrKqTwh}r#SU4Rh8@@5br zG9ic5YS?WJmdL%BHmf+Cu4P|6J<}6T!OY7F+LAswowUj^Lo|iR3%1>}@kxYp8*`=4 zIm^U*gKrs-@0kjB|H<7R7(;XM;7IPRL`1;gDs66LxuBXcu!U?@Q2UVec}P+d)!=QR zCcgf=j~dE2-T(Q92=?C6{Pf?y4TP9`{{>5(evazY&W&ml9gW}k(Ps(HtwaQ`Ua=rq z0bfB0gm(zpt0{WJ+f-EccNuqTaYBF*;Udopv$zkaF^4G>J0OVtO|iMK zA7+wwhGCcAfSyvqd5}}CfBj|W^Q3s@jmA?mthaHF)?+jHJ*AZm{DxUbIFGRx`>l6k zZSq8O?aO0OkpupcliD|=9CD%~43^nDRHUKhcpv}$=Nl;CNiR14W`D^0K_+#jPYT|@ z&w~Qff2(-#?oGyY`Z?u<-*N6R4{SsDZFoN}S-}U-oP1u4RQp?)tdkoF z?`uWb57q?p(+bNeNI}(N&@ru!=mA_U$@ce%GD$zh9F$1&1NKpO$^nUKm-m5pd`#5? zd5`e};8($U_aXIja(59@HjG&VNsyWS02gsr3y<%^8fm{++B%Dt5IQ_jFB+oe_V3Q; zoh1xBZ!$0ko+)+Cvc;lc^&^cW1dCIeMC*Y4R$v&BpLH8f~sc}s)?(m}nT?h7_+biaf zk)bd#zxwR@YK};cmT=#3jrQZJ-#LGRS6q18Ehn!3$=Olz zyIpp=UPoA@t_V<;Fd^cH!3vW|kRa#@Y5(LDpHm;zPQZhRSWxxNW36Zgd7q|EF;#bf z2D>xa$J?quZfy7%7j&6|G{2!V51JI10` zXD^dqKYHiVV`Q5 zit^Gp3sz_!ge^s_ad&dfASNg&MD*{!TV951-&_8E+yV;Q*e1nn+&Rfn4o4kfWB$TM z=n<}`y=-uBN>?Jy^@NEKkK2ErTv9dh9Sh}x3lb!s@|@Bg8LF!+!@ON%wQ{j!xyj&T(j-!IxZE}q z7uTV5eprW#L=h;7u#ne&y!n+|lksCK&XCuBW?k<9^Lvs)!xchV zk>tgx2w@n8z9){)e43Or*txWx?H`jQv$dWY`=@ieRpnnp%f>A7GQXI|IQ1ieYwkuS zm}{a*X}EOj7a9LfZ2kKf6a0-E81{DoC6p`pc8qZ3&-GAHb$WjKyl86{sN3?Kiz&;R zw2{ypw*INw@%qQO`j_Guba6-BC){ZguKVqNV+M*zUk#sKIbj`$Ryf!7&rQ>nOn- z<~iJ)30$R22el5r+XEqBD*f}*DoyUdm#pZE_tyC5OwVaZ!ixY{08ZN2h~!eGmFEv- z`rhqp2VMF6p`$c1?)jCP`E1H=hDex2$>I;H`}f_r4#>a*q)B|RCR!-d#Za#!>s%-y z8LZKU3MmW*HK_aoQsk09`4dtS0bsnRT5l6AJ12pc>3y0^{z)fCZ(4`kJ|9L^IS=gx z)W*RQi&1E)h`76Z+t$MC1Rorv{V0$|Oj8kXaAqI$rBQ7AeKeZplbS6N>oDO-kT1Ao z{&{1(@!_J{;5np0uBGAMRxV->fB!G#@ruo;IyO$-og5e+V7#^-F=IQ3Z--c~;NV$_ zfm)HKm%uCf8r5%OYYBvZ>*;;SllQl|+cU1)C$@Plq6k@Xr@PRg4$WNjijPGd(!{Er z`R%DV;pVShwT3k6Pw{7{Ag1vHY$)Ip{#H1MEfH6~_6SB$lM_lobID7d&h$`H+V)!N z_Al+04PQ;Qzga=ISw)n;7Qvd>UhGkl4B^+rz|I&Wd}X2x?a;fh;KuM~7orA)p%Sx| z&=W+b)3OvXrPt`Uu-=MXytql2Lq+HMFAVxa--(!&M=k5i6$FTD^ah+M)WP^T*0eFl zZ(f93nVhLCrqCJAgL4~FP#=|lOH;GaShY^MV9k4JfmwL^Sk%8bWIb4W8yyXFW`8tT z|I^;r={uGfbB^&%i>SJd}(P^QD1kJ}qP zNqfWJNR)|_0*R}ZSZ#@RPv@NA68Mfxvr?=EoMgmv;q?TSLM)?GQAMP-&$hIbsm4Qd?=8k*UH%}*PaE`Ruj7k{CoSvq?Jag~gkcJisy&(Yz&y%GSIXpciB zetgB4_W1Oop}eOU6jCt}5iuX&(@sC~wpX-UoGZ-0{a)`fNF{;LYZNw6u^0qS;}`4c zl-KR24w3*&qAn5NB^>9wFc-jbcd-i+*Z?dX<~QE*(TtJmJ!|6!?ksZb$)UvUzcpjJ z#A;tHmK7^0Mo7=wSR?b)%H;e_UrE(Nv=4|WDiRa$uuW(uk{zjngWdY5P(}mwW{Qw3 z0;pP`AJq4dr9n_Fhv{8&*67gm4=RCFM5Vb6Mn6PBF&Hd&(g=GcXuh7+3B_1p&z~jNeBz*!;1- z6`hzBBZF65?(eM4Qg|wrYFw-Kl|J#^!2)-Bq)30mH;mo&oKu zV*%xvMJI1+sCi#Xu_Q=wRhIMaEW&I zu1vk3c)#~;qKA1s@2&fe&^~V}JU9*nf!}H>tVG1^B#z}^1;%$yq%O@Y1VlETWvLAo zhjiK&Qfyd%wlDUy!?f~#x_`ZQus>~HH!H%rd%DRyzkT6M-&_MaY^QD%sJ@}h@m9#E7UzsA?y{OyxZcIz%gvNQ�?>Gs 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 z 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 - /// Map file offsets to 65xx addresses and vice-versa. Useful for sources with - /// multiple ORG directives. - /// - /// It's possible to generate code that would overlap once relocated at run time, - /// which means a given address could map to multiple offsets. For this reason - /// it's useful to know the offset of the referring code when evaluating a - /// reference, so that a "local" match can take priority. - /// - public class AddressMap : IEnumerable { - ///

- /// Code starting at the specified offset will have the specified address. - /// - /// The entries are held in the list in order, sorted by offset, with no gaps. - /// This makes the "length" field redundant, as it can be computed by - /// (entry[N+1].mOffset - entry[N].mOffset), with a special case for the last - /// entry in the list. It's convenient to maintain it explicitly however, as - /// the list is read far more often than it is updated. - /// - /// Entries are mutable, but must only be altered by AddressMap. Don't retain - /// instances of this across other activity. - /// - public class AddressMapEntry { - public int Offset { get; set; } - public int Addr { get; set; } - public int Length { get; set; } - - public AddressMapEntry(int offset, int addr, int len) { - Offset = offset; - Addr = addr; - Length = len; - } - } - - /// - /// Total length, in bytes, spanned by this map. - /// - private int mTotalLength; - - /// - /// List of definitions, in sorted order. - /// - private List mAddrList = new List(); - - /// - /// Constructor. - /// - /// Total length, in bytes, spanned by this map. - public AddressMap(int length) { - /// There must always be at least one entry, defining the target address - /// for file offset 0. This can be changed, but can't be removed. - mTotalLength = length; - mAddrList.Add(new AddressMapEntry(0, 0, length)); - } - - // IEnumerable - public IEnumerator GetEnumerator() { - return ((IEnumerable)mAddrList).GetEnumerator(); - } - - // IEnumerable - IEnumerator IEnumerable.GetEnumerator() { - return ((IEnumerable)mAddrList).GetEnumerator(); - } - - /// - /// Returns the Nth entry in the address map. - /// - public AddressMapEntry this[int i] { - get { return mAddrList[i]; } - } - - /// - /// Number of entries in the address map. - /// - public int Count { get { return mAddrList.Count; } } - - /// - /// Returns the Address value of the address map entry associated with the specified - /// offset, or -1 if there is no address map entry there. The offset must match exactly. - /// - public int Get(int offset) { - foreach (AddressMapEntry ad in mAddrList) { - if (ad.Offset == offset) { - return ad.Addr; - } - } - return -1; - } - - /// - /// Returns the index of the address map entry that contains the given offset. - /// We assume the offset is valid. - /// - private int IndexForOffset(int offset) { - for (int i = 1; i < mAddrList.Count; i++) { - if (mAddrList[i].Offset > offset) { - return i - 1; - } - } - - return mAddrList.Count - 1; - } - - /// - /// Adds, updates, or removes a map entry. - /// - /// File offset at which the address changes. - /// 24-bit address. - public void Set(int offset, int addr) { - Debug.Assert(offset >= 0); - if (addr == -1) { - if (offset != 0) { // ignore attempts to remove entry at offset zero - Remove(offset); - } - return; - } - Debug.Assert(addr >= 0 && addr < 0x01000000); // 24-bit address space - - int i; - for (i = 0; i < mAddrList.Count; i++) { - AddressMapEntry ad = mAddrList[i]; - if (ad.Offset == offset) { - // update existing - ad.Addr = addr; - mAddrList[i] = ad; - return; - } else if (ad.Offset > offset) { - // The i'th entry is one past the interesting part. - break; - } - } - - // Carve a chunk out of the previous entry. - AddressMapEntry prev = mAddrList[i - 1]; - int prevOldLen = prev.Length; - int prevNewLen = offset - prev.Offset; - prev.Length = prevNewLen; - mAddrList[i - 1] = prev; - - mAddrList.Insert(i, - new AddressMapEntry(offset, addr, prevOldLen - prevNewLen)); - - DebugValidate(); - } - - /// - /// Removes an entry from the set. - /// - /// The initial offset of the mapping to remove. This - /// must be the initial value, not a mid-range value. - /// True if something was removed. - public bool Remove(int offset) { - if (offset == 0) { - throw new Exception("Not allowed to remove entry 0"); - } - - for (int i = 1; i < mAddrList.Count; i++) { - if (mAddrList[i].Offset == offset) { - // Add the length to the previous entry. - AddressMapEntry prev = mAddrList[i - 1]; - prev.Length += mAddrList[i].Length; - mAddrList[i - 1] = prev; - - mAddrList.RemoveAt(i); - DebugValidate(); - return true; - } - } - return false; - } - - /// - /// Returns true if the given address falls into the range spanned by the - /// address map entry. - /// - /// Address map entry index. - /// Address to check. - /// - private bool IndexContainsAddress(int index, int addr) { - return addr >= mAddrList[index].Addr && - addr < mAddrList[index].Addr + mAddrList[index].Length; - } - - /// - /// Determines the file offset that best contains the specified target address. - /// - /// Offset of the address reference. - /// Address to look up. - /// The file offset, or -1 if the address falls outside the file. - public int AddressToOffset(int srcOffset, int targetAddr) { - if (mAddrList.Count == 1) { - // Trivial case. - if (IndexContainsAddress(0, targetAddr)) { - Debug.Assert(targetAddr >= mAddrList[0].Addr); - return targetAddr - mAddrList[0].Addr; - } else { - return -1; - } - } - - // We have multiple, potentially overlapping address ranges. Start by - // looking for a match in the srcOffset range; if that fails, scan - // forward from the start. - int srcOffIndex = IndexForOffset(srcOffset); - if (IndexContainsAddress(srcOffIndex, targetAddr)) { - Debug.Assert(targetAddr >= mAddrList[srcOffIndex].Addr); - return (targetAddr - mAddrList[srcOffIndex].Addr) + mAddrList[srcOffIndex].Offset; - } - - for (int i = 0; i < mAddrList.Count; i++) { - if (i == srcOffIndex) { - // optimization -- we already checked this one - continue; - } - if (IndexContainsAddress(i, targetAddr)) { - Debug.Assert(targetAddr >= mAddrList[i].Addr); - return (targetAddr - mAddrList[i].Addr) + mAddrList[i].Offset; - } - } - - return -1; - } - - /// - /// Converts a file offset to an address. - /// - /// File offset. - /// 24-bit address. - public int OffsetToAddress(int offset) { - int srcOffIndex = IndexForOffset(offset); - return mAddrList[srcOffIndex].Addr + (offset - mAddrList[srcOffIndex].Offset); - } - - - /// - /// Internal consistency checks. - /// - private void DebugValidate() { - if (mAddrList.Count < 1) { - throw new Exception("AddressMap: empty"); - } - if (mAddrList[0].Offset != 0) { - throw new Exception("AddressMap: bad offset 0"); - } - - if (mAddrList.Count == 1) { - if (mAddrList[0].Length != mTotalLength) { - throw new Exception("AddressMap: single entry len bad"); - } - } else { - int totalLen = 0; - for (int i = 0; i < mAddrList.Count; i++) { - AddressMapEntry ent = mAddrList[i]; - if (i != 0) { - if (ent.Offset != mAddrList[i - 1].Offset + mAddrList[i - 1].Length) { - throw new Exception("Bad offset step to " + i); - } - } - - totalLen += ent.Length; - } - - if (totalLen != mTotalLength) { - throw new Exception("AddressMap: bad length sum (" + totalLen + " vs " + - mTotalLength + ")"); - } - } - } - - public override string ToString() { - return "[AddressMap: " + mAddrList.Count + " entries]"; - } - } -} diff --git a/SourceGenWF/Anattrib.cs b/SourceGenWF/Anattrib.cs deleted file mode 100644 index 2bba39b..0000000 --- a/SourceGenWF/Anattrib.cs +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Diagnostics; -using System.Text; - -using Asm65; - -namespace SourceGenWF { - /// - /// Analyzer attribute holder. Contains the output of the instruction and data analyzers. - /// Every byte in the input file has one of these associated with it. - /// - /// (Yes, it's a mutable struct. Yes, that fact has bitten me a few times. The array - /// of these may have millions of elements, so the reduction in overhead seems worthwhile.) - /// - public struct Anattrib { - [FlagsAttribute] - private enum AttribFlags { - InstrStart = 1 << 0, // byte is first of an instruction - Instruction = 1 << 1, // byte is part of an instruction or inline data - InlineData = 1 << 2, // byte is inline data - Data = 1 << 3, // byte is data - - EntryPoint = 1 << 8, // external code branches here - BranchTarget = 1 << 9, // internal code branches here - ExternalBranch = 1 << 10, // this abs/rel branch lands outside input file - - NoContinue = 1 << 12, // execution does not continue to following instruction - - Visited = 1 << 16, // has the analyzer visited this byte? - Changed = 1 << 17, // set/cleared as the analyzer works - - Hinted = 1 << 18, // was this byte affected by a type hint? - } - - // Flags indicating what type of data is here. Use the following Is* properties - // to set/clear. - private AttribFlags mAttribFlags; - - public bool IsInstructionStart { - get { - return (mAttribFlags & AttribFlags.InstrStart) != 0; - } - set { - IsInstruction = value; - if (value) { - mAttribFlags |= AttribFlags.InstrStart; - } else { - mAttribFlags &= ~AttribFlags.InstrStart; - } - } - } - public bool IsInstruction { - get { - return (mAttribFlags & AttribFlags.Instruction) != 0; - } - set { - Debug.Assert(value == false || - (mAttribFlags & (AttribFlags.InlineData | AttribFlags.Data)) == 0); - if (value) { - mAttribFlags |= AttribFlags.Instruction; - } else { - mAttribFlags &= ~AttribFlags.Instruction; - } - } - } - public bool IsInlineData { - get { - return (mAttribFlags & AttribFlags.InlineData) != 0; - } - set { - Debug.Assert(value == false || - (mAttribFlags & (AttribFlags.Instruction | AttribFlags.Data)) == 0); - if (value) { - mAttribFlags |= AttribFlags.InlineData; - } else { - mAttribFlags &= ~AttribFlags.InlineData; - } - } - } - public bool IsData { - get { - return (mAttribFlags & AttribFlags.Data) != 0; - } - set { - Debug.Assert(value == false || - (mAttribFlags & (AttribFlags.InlineData | AttribFlags.Instruction)) == 0); - if (value) { - mAttribFlags |= AttribFlags.Data; - } else { - mAttribFlags &= ~AttribFlags.Data; - } - } - } - public bool IsStart { - get { - return IsInstructionStart || IsDataStart || IsInlineDataStart; - } - } - public bool IsEntryPoint { - get { - return (mAttribFlags & AttribFlags.EntryPoint) != 0; - } - set { - if (value) { - mAttribFlags |= AttribFlags.EntryPoint; - } else { - mAttribFlags &= ~AttribFlags.EntryPoint; - } - } - } - public bool IsBranchTarget { - get { - return (mAttribFlags & AttribFlags.BranchTarget) != 0; - } - set { - if (value) { - mAttribFlags |= AttribFlags.BranchTarget; - } else { - mAttribFlags &= ~AttribFlags.BranchTarget; - } - } - } - public bool IsExternalBranch { - get { - return (mAttribFlags & AttribFlags.ExternalBranch) != 0; - } - set { - if (value) { - mAttribFlags |= AttribFlags.ExternalBranch; - } else { - mAttribFlags &= ~AttribFlags.ExternalBranch; - } - } - } - public bool DoesNotContinue { - get { - return (mAttribFlags & AttribFlags.NoContinue) != 0; - } - set { - if (value) { - mAttribFlags |= AttribFlags.NoContinue; - } else { - mAttribFlags &= ~AttribFlags.NoContinue; - } - } - } - public bool DoesNotBranch { - get { - return (BranchTaken == OpDef.BranchTaken.Never); - } - } - public bool IsVisited { - get { - return (mAttribFlags & AttribFlags.Visited) != 0; - } - set { - if (value) { - mAttribFlags |= AttribFlags.Visited; - } else { - mAttribFlags &= ~AttribFlags.Visited; - } - } - } - public bool IsChanged { - get { - return (mAttribFlags & AttribFlags.Changed) != 0; - } - set { - if (value) { - mAttribFlags |= AttribFlags.Changed; - } else { - mAttribFlags &= ~AttribFlags.Changed; - } - } - } - public bool IsHinted { - get { - return (mAttribFlags & AttribFlags.Hinted) != 0; - } - set { - if (value) { - mAttribFlags |= AttribFlags.Hinted; - } else { - mAttribFlags &= ~AttribFlags.Hinted; - } - } - } - - public bool IsDataStart { - get { - return IsData && DataDescriptor != null; - } - } - public bool IsInlineDataStart { - get { - return IsInlineData && DataDescriptor != null; - } - } - - /// - /// Get the target memory address for this byte. - /// - public int Address { get; set; } - - /// - /// Instructions: length of the instruction (for InstrStart). If a FormatDescriptor - /// is assigned, the length must match. - /// Inline data: FormatDescriptor length, or zero if no descriptor is defined. - /// Data: FormatDescriptor length, or zero if no descriptor is defined. - /// - /// This field should only be set by CodeAnalysis methods, although the "get" value - /// can be changed for data/inline-data by setting the DataDescriptor field. - /// - public int Length { - get { - // For data we don't even use the field; this ensures that we're always - // using the FormatDescriptor's length. - if (IsData || IsInlineData) { - Debug.Assert(mLength == 0); - if (DataDescriptor != null) { - return DataDescriptor.Length; - } else { - return 0; - } - } - return mLength; - } - set { - Debug.Assert(!IsData); - mLength = value; - } - } - private int mLength; - - /// - /// Instructions only: processor status flags. - /// - /// Note this returns a copy of a struct, so modifications to the returned value - /// (including calls to Merge and Apply) are not permanent. - /// - public StatusFlags StatusFlags { - get { return mStatusFlags; } - set { mStatusFlags = value; } - } - private StatusFlags mStatusFlags; - - public void MergeStatusFlags(StatusFlags other) { - mStatusFlags.Merge(other); - } - public void ApplyStatusFlags(StatusFlags other) { - mStatusFlags.Apply(other); - } - - /// - /// Branch instructions only: outcome of branch. - /// - public OpDef.BranchTaken BranchTaken { get; set; } - - /// - /// Instructions only: decoded operand address value. Will be -1 if not - /// yet computed or not applicable. For a relative branch instruction, - /// this will have the absolute branch target address. On the 65816, this - /// will be a 24-bit address. - /// - public int OperandAddress { - get { return mOperandAddressSet ? mOperandAddress : -1; } - set { - Debug.Assert(mOperandAddress >= -1); - mOperandAddress = value; - mOperandAddressSet = (value >= 0); - } - } - private int mOperandAddress; - private bool mOperandAddressSet; - - /// - /// Instructions only: offset referenced by OperandAddress. Will be -1 if not - /// yet computed, not applicable, or if OperandAddress refers to a location - /// outside the scope of the file. - /// - public int OperandOffset { - get { return mOperandOffsetSet ? mOperandOffset : -1; } - set { - Debug.Assert(mOperandOffset >= -1); - mOperandOffset = value; - mOperandOffsetSet = (value >= 0); - } - } - private int mOperandOffset; - private bool mOperandOffsetSet; - - /// - /// Instructions only: is OperandOffset a direct target offset? (This is used when - /// tracing jump instructions, to know if we should add the offset to the scan list. - /// It's determined by the opcode, e.g. "JMP addr" -> true, "JMP (addr,X)" -> false.) - /// - public bool IsOperandOffsetDirect { get; set; } - - /// - /// Symbol defined as the label for this offset. All offsets that are instruction - /// or data target offsets will have one of these defined. Users can define additional - /// symbols as well. - /// - /// Will be null if no label is defined for this offset. - /// - public Symbol Symbol { get; set; } - - /// - /// Format descriptor for operands and data items. Will be null if no descriptor - /// is defined for this offset. - /// - public FormatDescriptor DataDescriptor { get; set; } - - /// - /// Is this an instruction with an operand (i.e. not impl/acc)? - /// - public bool IsInstructionWithOperand { - get { - if (!IsInstructionStart) { - return false; - } - return Length != 1; - } - } - - /// - /// Returns a fixed-width string with indicators for items of interest. - /// - public string ToAttrString() { - StringBuilder sb = new StringBuilder(5); - char blank = '.'; - sb.Append(IsEntryPoint ? '@' : blank); - sb.Append(IsHinted ? 'H' : blank); - sb.Append(DoesNotBranch ? '!' : blank); - sb.Append(DoesNotContinue ? '#' : blank); - sb.Append(IsBranchTarget ? '>' : blank); - return sb.ToString(); - } - } -} diff --git a/SourceGenWF/App.config b/SourceGenWF/App.config deleted file mode 100644 index 731f6de..0000000 --- a/SourceGenWF/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/SourceGenWF/AppForms/AboutBox.Designer.cs b/SourceGenWF/AppForms/AboutBox.Designer.cs deleted file mode 100644 index 380aaeb..0000000 --- a/SourceGenWF/AppForms/AboutBox.Designer.cs +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AppForms { - partial class AboutBox { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.boardPictureBox = new System.Windows.Forms.PictureBox(); - this.sourceGenLabel = new System.Windows.Forms.Label(); - this.versionLabel = new System.Windows.Forms.Label(); - this.createdLabel = new System.Windows.Forms.Label(); - this.okButton = new System.Windows.Forms.Button(); - this.legalStuffTextBox = new System.Windows.Forms.TextBox(); - this.label1 = new System.Windows.Forms.Label(); - this.osPlatformLabel = new System.Windows.Forms.Label(); - this.debugEnabledLabel = new System.Windows.Forms.Label(); - ((System.ComponentModel.ISupportInitialize)(this.boardPictureBox)).BeginInit(); - this.SuspendLayout(); - // - // boardPictureBox - // - this.boardPictureBox.Location = new System.Drawing.Point(13, 13); - this.boardPictureBox.Name = "boardPictureBox"; - this.boardPictureBox.Size = new System.Drawing.Size(320, 236); - this.boardPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; - this.boardPictureBox.TabIndex = 0; - this.boardPictureBox.TabStop = false; - // - // sourceGenLabel - // - this.sourceGenLabel.AutoSize = true; - this.sourceGenLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.sourceGenLabel.Location = new System.Drawing.Point(340, 13); - this.sourceGenLabel.Name = "sourceGenLabel"; - this.sourceGenLabel.Size = new System.Drawing.Size(346, 37); - this.sourceGenLabel.TabIndex = 1; - this.sourceGenLabel.Text = "6502bench SourceGen"; - // - // versionLabel - // - this.versionLabel.AutoSize = true; - this.versionLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 20.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.versionLabel.Location = new System.Drawing.Point(340, 60); - this.versionLabel.Name = "versionLabel"; - this.versionLabel.Size = new System.Drawing.Size(273, 31); - this.versionLabel.TabIndex = 2; - this.versionLabel.Text = "Version X.Y.Z Alpha1"; - // - // createdLabel - // - this.createdLabel.AutoSize = true; - this.createdLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.createdLabel.Location = new System.Drawing.Point(407, 142); - this.createdLabel.Name = "createdLabel"; - this.createdLabel.Size = new System.Drawing.Size(206, 40); - this.createdLabel.TabIndex = 3; - this.createdLabel.Text = "Copyright 2018 faddenSoft\r\nCreated by Andy McFadden\r\n"; - // - // okButton - // - this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.okButton.Location = new System.Drawing.Point(617, 526); - this.okButton.Name = "okButton"; - this.okButton.Size = new System.Drawing.Size(75, 23); - this.okButton.TabIndex = 0; - this.okButton.Text = "OK"; - this.okButton.UseVisualStyleBackColor = true; - // - // legalStuffTextBox - // - this.legalStuffTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.legalStuffTextBox.Location = new System.Drawing.Point(12, 305); - this.legalStuffTextBox.MaxLength = 0; - this.legalStuffTextBox.Multiline = true; - this.legalStuffTextBox.Name = "legalStuffTextBox"; - this.legalStuffTextBox.ReadOnly = true; - this.legalStuffTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.legalStuffTextBox.Size = new System.Drawing.Size(680, 215); - this.legalStuffTextBox.TabIndex = 4; - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(12, 289); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(59, 13); - this.label1.TabIndex = 5; - this.label1.Text = "Legal stuff:"; - // - // osPlatformLabel - // - this.osPlatformLabel.AutoSize = true; - this.osPlatformLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.osPlatformLabel.Location = new System.Drawing.Point(12, 263); - this.osPlatformLabel.Name = "osPlatformLabel"; - this.osPlatformLabel.Size = new System.Drawing.Size(86, 16); - this.osPlatformLabel.TabIndex = 6; - this.osPlatformLabel.Text = "[OS platform]"; - // - // debugEnabledLabel - // - this.debugEnabledLabel.AutoSize = true; - this.debugEnabledLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.debugEnabledLabel.Location = new System.Drawing.Point(340, 233); - this.debugEnabledLabel.Name = "debugEnabledLabel"; - this.debugEnabledLabel.Size = new System.Drawing.Size(293, 16); - this.debugEnabledLabel.TabIndex = 7; - this.debugEnabledLabel.Text = "Assertions and extended validation are enabled"; - this.debugEnabledLabel.Visible = false; - // - // AboutBox - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(704, 561); - this.Controls.Add(this.debugEnabledLabel); - this.Controls.Add(this.osPlatformLabel); - this.Controls.Add(this.label1); - this.Controls.Add(this.legalStuffTextBox); - this.Controls.Add(this.okButton); - this.Controls.Add(this.createdLabel); - this.Controls.Add(this.versionLabel); - this.Controls.Add(this.sourceGenLabel); - this.Controls.Add(this.boardPictureBox); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "AboutBox"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "About SourceGen"; - this.Load += new System.EventHandler(this.AboutBox_Load); - ((System.ComponentModel.ISupportInitialize)(this.boardPictureBox)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.PictureBox boardPictureBox; - private System.Windows.Forms.Label sourceGenLabel; - private System.Windows.Forms.Label versionLabel; - private System.Windows.Forms.Label createdLabel; - private System.Windows.Forms.Button okButton; - private System.Windows.Forms.TextBox legalStuffTextBox; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.Label osPlatformLabel; - private System.Windows.Forms.Label debugEnabledLabel; - } -} \ No newline at end of file diff --git a/SourceGenWF/AppForms/AboutBox.cs b/SourceGenWF/AppForms/AboutBox.cs deleted file mode 100644 index af4cd89..0000000 --- a/SourceGenWF/AppForms/AboutBox.cs +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.IO; -using System.Windows.Forms; - -namespace SourceGenWF.AppForms { - public partial class AboutBox : Form { - private const string IMAGE_FILE_NAME = "AboutImage.png"; - private const string LEGAL_STUFF_FILE_NAME = "LegalStuff.txt"; - - public AboutBox() { - InitializeComponent(); - - boardPictureBox.ImageLocation = RuntimeDataAccess.GetPathName(IMAGE_FILE_NAME); - versionLabel.Text = string.Format(Properties.Resources.VERSION_FMT, - Program.ProgramVersion); - - osPlatformLabel.Text = "OS: " + - System.Runtime.InteropServices.RuntimeInformation.OSDescription; -#if DEBUG - debugEnabledLabel.Visible = true; -#endif - } - - private void AboutBox_Load(object sender, EventArgs e) { - string text; - string pathName = RuntimeDataAccess.GetPathName(LEGAL_STUFF_FILE_NAME); - try { - text = File.ReadAllText(pathName); - } catch (Exception ex) { - text = ex.ToString(); - } - - legalStuffTextBox.Text = text; - } - } -} diff --git a/SourceGenWF/AppForms/AboutBox.resx b/SourceGenWF/AppForms/AboutBox.resx deleted file mode 100644 index 1af7de1..0000000 --- a/SourceGenWF/AppForms/AboutBox.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SourceGenWF/AppForms/DataFileLoadIssue.Designer.cs b/SourceGenWF/AppForms/DataFileLoadIssue.Designer.cs deleted file mode 100644 index 725131a..0000000 --- a/SourceGenWF/AppForms/DataFileLoadIssue.Designer.cs +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AppForms { - partial class DataFileLoadIssue { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.problemWithFileLabel = new System.Windows.Forms.Label(); - this.pathNameTextBox = new System.Windows.Forms.TextBox(); - this.problemLabel = new System.Windows.Forms.Label(); - this.cancelButton = new System.Windows.Forms.Button(); - this.okButton = new System.Windows.Forms.Button(); - this.doYouWantLabel = new System.Windows.Forms.Label(); - this.SuspendLayout(); - // - // problemWithFileLabel - // - this.problemWithFileLabel.AutoSize = true; - this.problemWithFileLabel.Location = new System.Drawing.Point(13, 13); - this.problemWithFileLabel.Name = "problemWithFileLabel"; - this.problemWithFileLabel.Size = new System.Drawing.Size(221, 13); - this.problemWithFileLabel.TabIndex = 2; - this.problemWithFileLabel.Text = "There was an error while loading the data file:"; - // - // pathNameTextBox - // - this.pathNameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.pathNameTextBox.Location = new System.Drawing.Point(13, 39); - this.pathNameTextBox.Name = "pathNameTextBox"; - this.pathNameTextBox.ReadOnly = true; - this.pathNameTextBox.Size = new System.Drawing.Size(488, 20); - this.pathNameTextBox.TabIndex = 3; - // - // problemLabel - // - this.problemLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.problemLabel.Location = new System.Drawing.Point(13, 73); - this.problemLabel.Name = "problemLabel"; - this.problemLabel.Size = new System.Drawing.Size(488, 31); - this.problemLabel.TabIndex = 4; - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.Location = new System.Drawing.Point(428, 113); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 23); - this.cancelButton.TabIndex = 1; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - // - // okButton - // - this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.okButton.Location = new System.Drawing.Point(347, 113); - this.okButton.Name = "okButton"; - this.okButton.Size = new System.Drawing.Size(75, 23); - this.okButton.TabIndex = 0; - this.okButton.Text = "OK"; - this.okButton.UseVisualStyleBackColor = true; - // - // doYouWantLabel - // - this.doYouWantLabel.AutoSize = true; - this.doYouWantLabel.Location = new System.Drawing.Point(13, 117); - this.doYouWantLabel.Name = "doYouWantLabel"; - this.doYouWantLabel.Size = new System.Drawing.Size(175, 13); - this.doYouWantLabel.TabIndex = 5; - this.doYouWantLabel.Text = "Do you want to locate the data file?\r\n"; - // - // DataFileLoadIssue - // - this.AcceptButton = this.okButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(515, 148); - this.Controls.Add(this.doYouWantLabel); - this.Controls.Add(this.okButton); - this.Controls.Add(this.cancelButton); - this.Controls.Add(this.problemLabel); - this.Controls.Add(this.pathNameTextBox); - this.Controls.Add(this.problemWithFileLabel); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "DataFileLoadIssue"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Data File Load Issue"; - this.Load += new System.EventHandler(this.DataFileLoadIssue_Load); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label problemWithFileLabel; - private System.Windows.Forms.TextBox pathNameTextBox; - private System.Windows.Forms.Label problemLabel; - private System.Windows.Forms.Button cancelButton; - private System.Windows.Forms.Button okButton; - private System.Windows.Forms.Label doYouWantLabel; - } -} \ No newline at end of file diff --git a/SourceGenWF/AppForms/DataFileLoadIssue.cs b/SourceGenWF/AppForms/DataFileLoadIssue.cs deleted file mode 100644 index 19565d6..0000000 --- a/SourceGenWF/AppForms/DataFileLoadIssue.cs +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Windows.Forms; - -namespace SourceGenWF.AppForms { - public partial class DataFileLoadIssue : Form { - /// - /// Path name of problematic file. - /// - private string mPathName; - - /// - /// Message to show in the dialog. - /// - private string mMessage; - - - public DataFileLoadIssue(string pathName, string message) { - InitializeComponent(); - - mPathName = pathName; - mMessage = message; - } - - private void DataFileLoadIssue_Load(object sender, EventArgs e) { - pathNameTextBox.Text = mPathName; - problemLabel.Text = mMessage; - } - } -} diff --git a/SourceGenWF/AppForms/DataFileLoadIssue.resx b/SourceGenWF/AppForms/DataFileLoadIssue.resx deleted file mode 100644 index 1af7de1..0000000 --- a/SourceGenWF/AppForms/DataFileLoadIssue.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SourceGenWF/AppForms/DiscardChanges.Designer.cs b/SourceGenWF/AppForms/DiscardChanges.Designer.cs deleted file mode 100644 index 0880acb..0000000 --- a/SourceGenWF/AppForms/DiscardChanges.Designer.cs +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AppForms { - partial class DiscardChanges { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.cancelButton = new System.Windows.Forms.Button(); - this.dontSaveButton = new System.Windows.Forms.Button(); - this.saveButton = new System.Windows.Forms.Button(); - this.warningLabel = new System.Windows.Forms.Label(); - this.SuspendLayout(); - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.Location = new System.Drawing.Point(243, 74); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(110, 23); - this.cancelButton.TabIndex = 3; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - // - // dontSaveButton - // - this.dontSaveButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.dontSaveButton.Location = new System.Drawing.Point(127, 74); - this.dontSaveButton.Name = "dontSaveButton"; - this.dontSaveButton.Size = new System.Drawing.Size(110, 23); - this.dontSaveButton.TabIndex = 2; - this.dontSaveButton.Text = "&Discard && Continue"; - this.dontSaveButton.UseVisualStyleBackColor = true; - this.dontSaveButton.Click += new System.EventHandler(this.dontSaveButton_Click); - // - // saveButton - // - this.saveButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.saveButton.Location = new System.Drawing.Point(11, 74); - this.saveButton.Name = "saveButton"; - this.saveButton.Size = new System.Drawing.Size(110, 23); - this.saveButton.TabIndex = 1; - this.saveButton.Text = "&Save && Continue"; - this.saveButton.UseVisualStyleBackColor = true; - this.saveButton.Click += new System.EventHandler(this.saveButton_Click); - // - // warningLabel - // - this.warningLabel.AutoSize = true; - this.warningLabel.Location = new System.Drawing.Point(13, 13); - this.warningLabel.Name = "warningLabel"; - this.warningLabel.Size = new System.Drawing.Size(288, 39); - this.warningLabel.TabIndex = 0; - this.warningLabel.Text = "You have unsaved changes that will be lost if you continue.\r\n\r\nHow do you wish to" + - " proceed?"; - // - // DiscardChanges - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(365, 109); - this.Controls.Add(this.warningLabel); - this.Controls.Add(this.saveButton); - this.Controls.Add(this.dontSaveButton); - this.Controls.Add(this.cancelButton); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "DiscardChanges"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Discard Changes?"; - this.Load += new System.EventHandler(this.DiscardChanges_Load); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Button cancelButton; - private System.Windows.Forms.Button dontSaveButton; - private System.Windows.Forms.Button saveButton; - private System.Windows.Forms.Label warningLabel; - } -} \ No newline at end of file diff --git a/SourceGenWF/AppForms/DiscardChanges.cs b/SourceGenWF/AppForms/DiscardChanges.cs deleted file mode 100644 index d28c632..0000000 --- a/SourceGenWF/AppForms/DiscardChanges.cs +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Windows.Forms; - -namespace SourceGenWF.AppForms { - /// - /// Prompt the user before discarding changes. - /// - /// Dialog result will be: - /// DialogResult.Yes: save before continuing - /// DialogResult.No: don't save before continuing - /// DialogResult.Cancel: don't continue - /// - public partial class DiscardChanges : Form { - public DiscardChanges() { - InitializeComponent(); - } - - private void DiscardChanges_Load(object sender, EventArgs e) { - // Make this the default. - cancelButton.Select(); - } - - private void saveButton_Click(object sender, EventArgs e) { - DialogResult = DialogResult.Yes; - Close(); - } - - private void dontSaveButton_Click(object sender, EventArgs e) { - DialogResult = DialogResult.No; - Close(); - } - } -} diff --git a/SourceGenWF/AppForms/DiscardChanges.resx b/SourceGenWF/AppForms/DiscardChanges.resx deleted file mode 100644 index 1af7de1..0000000 --- a/SourceGenWF/AppForms/DiscardChanges.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditAddress.Designer.cs b/SourceGenWF/AppForms/EditAddress.Designer.cs deleted file mode 100644 index 1c59cd2..0000000 --- a/SourceGenWF/AppForms/EditAddress.Designer.cs +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AppForms { - partial class EditAddress { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - System.Windows.Forms.Label addressLabel; - this.okButton = new System.Windows.Forms.Button(); - this.cancelButton = new System.Windows.Forms.Button(); - this.addressTextBox = new System.Windows.Forms.TextBox(); - this.instructionLabel1 = new System.Windows.Forms.Label(); - this.instructionLabel2 = new System.Windows.Forms.Label(); - addressLabel = new System.Windows.Forms.Label(); - this.SuspendLayout(); - // - // addressLabel - // - addressLabel.AutoSize = true; - addressLabel.Location = new System.Drawing.Point(12, 16); - addressLabel.Name = "addressLabel"; - addressLabel.Size = new System.Drawing.Size(48, 13); - addressLabel.TabIndex = 1; - addressLabel.Text = "Address:"; - // - // okButton - // - this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.okButton.Location = new System.Drawing.Point(190, 91); - this.okButton.Name = "okButton"; - this.okButton.Size = new System.Drawing.Size(75, 23); - this.okButton.TabIndex = 3; - this.okButton.Text = "OK"; - this.okButton.UseVisualStyleBackColor = true; - this.okButton.Click += new System.EventHandler(this.okButton_Click); - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.Location = new System.Drawing.Point(271, 91); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 23); - this.cancelButton.TabIndex = 4; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - // - // addressTextBox - // - this.addressTextBox.Location = new System.Drawing.Point(68, 13); - this.addressTextBox.Name = "addressTextBox"; - this.addressTextBox.Size = new System.Drawing.Size(275, 20); - this.addressTextBox.TabIndex = 0; - this.addressTextBox.TextChanged += new System.EventHandler(this.addressTextBox_TextChanged); - // - // instructionLabel1 - // - this.instructionLabel1.AutoSize = true; - this.instructionLabel1.Location = new System.Drawing.Point(12, 36); - this.instructionLabel1.Name = "instructionLabel1"; - this.instructionLabel1.Size = new System.Drawing.Size(331, 13); - this.instructionLabel1.TabIndex = 2; - this.instructionLabel1.Text = "Enter 16-bit or 24-bit address in hexadecimal, e.g. $1000 or 00/be00.\r\n"; - // - // instructionLabel2 - // - this.instructionLabel2.AutoSize = true; - this.instructionLabel2.Location = new System.Drawing.Point(12, 58); - this.instructionLabel2.Name = "instructionLabel2"; - this.instructionLabel2.Size = new System.Drawing.Size(258, 13); - this.instructionLabel2.TabIndex = 5; - this.instructionLabel2.Text = "Leave the field blank to remove the address override."; - // - // EditAddress - // - this.AcceptButton = this.okButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(358, 126); - this.Controls.Add(this.instructionLabel2); - this.Controls.Add(this.instructionLabel1); - this.Controls.Add(this.addressTextBox); - this.Controls.Add(addressLabel); - this.Controls.Add(this.cancelButton); - this.Controls.Add(this.okButton); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "EditAddress"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Edit Address"; - this.Load += new System.EventHandler(this.EditAddress_Load); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Button okButton; - private System.Windows.Forms.Button cancelButton; - private System.Windows.Forms.TextBox addressTextBox; - private System.Windows.Forms.Label instructionLabel1; - private System.Windows.Forms.Label instructionLabel2; - } -} \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditAddress.cs b/SourceGenWF/AppForms/EditAddress.cs deleted file mode 100644 index 868a573..0000000 --- a/SourceGenWF/AppForms/EditAddress.cs +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Diagnostics; -using System.Windows.Forms; - -namespace SourceGenWF.AppForms { - public partial class EditAddress : Form { - - /// - /// Address typed by user. Only valid after the dialog returns OK. Will be set to -1 - /// if the user is attempting to delete the address. - /// - public int Address { get; private set; } - - /// - /// Maximum allowed address value. - /// - private int mMaxAddressValue; - - - public EditAddress(int initialAddr, int maxAddressValue) { - InitializeComponent(); - - Address = -2; - mMaxAddressValue = maxAddressValue; - addressTextBox.Text = Asm65.Address.AddressToString(initialAddr, false); - } - - private void EditAddress_Load(object sender, EventArgs e) { - addressTextBox.SelectAll(); - } - - /// - /// Handles a click on the OK button by setting the Address property to the - /// decoded value from the text field. - /// - private void okButton_Click(object sender, EventArgs e) { - if (addressTextBox.Text.Length == 0) { - Address = -1; - } else { - Asm65.Address.ParseAddress(addressTextBox.Text, mMaxAddressValue, out int addr); - Address = addr; - } - } - - /// - /// Updates the OK button whenever the text changes. This works for all change sources, - /// including programmatic. - /// - private void addressTextBox_TextChanged(object sender, EventArgs e) { - UpdateOkEnabled(); - } - - /// - /// Enables or disables the OK button depending on whether the current input is - /// valid. We allow valid addresses and an empty box. - /// - private void UpdateOkEnabled() { - string text = addressTextBox.Text; - okButton.Enabled = (text.Length == 0) || - Asm65.Address.ParseAddress(text, mMaxAddressValue, out int unused); - } - } -} diff --git a/SourceGenWF/AppForms/EditAddress.resx b/SourceGenWF/AppForms/EditAddress.resx deleted file mode 100644 index e38ed36..0000000 --- a/SourceGenWF/AppForms/EditAddress.resx +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - False - - \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditAppSettings.Designer.cs b/SourceGenWF/AppForms/EditAppSettings.Designer.cs deleted file mode 100644 index e755692..0000000 --- a/SourceGenWF/AppForms/EditAppSettings.Designer.cs +++ /dev/null @@ -1,1660 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AppForms { - partial class EditAppSettings { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.cancelButton = new System.Windows.Forms.Button(); - this.okButton = new System.Windows.Forms.Button(); - this.applyButton = new System.Windows.Forms.Button(); - this.settingsTabControl = new System.Windows.Forms.TabControl(); - this.codeViewTabPage = new System.Windows.Forms.TabPage(); - this.codeViewMiscGroupBox = new System.Windows.Forms.GroupBox(); - this.spacesBetweenBytesCheckBox = new System.Windows.Forms.CheckBox(); - this.clipboardGroupBox = new System.Windows.Forms.GroupBox(); - this.clipboardFormatLabel = new System.Windows.Forms.Label(); - this.clipboardFormatComboBox = new System.Windows.Forms.ComboBox(); - this.enableDebugCheckBox = new System.Windows.Forms.CheckBox(); - this.upperCaseGroupBox = new System.Windows.Forms.GroupBox(); - this.upperAllUpperButton = new System.Windows.Forms.Button(); - this.upperAllLowerButton = new System.Windows.Forms.Button(); - this.upperXYCheckBox = new System.Windows.Forms.CheckBox(); - this.upperSCheckBox = new System.Windows.Forms.CheckBox(); - this.upperACheckBox = new System.Windows.Forms.CheckBox(); - this.upperPseudoOpCheckBox = new System.Windows.Forms.CheckBox(); - this.upperOpcodeCheckBox = new System.Windows.Forms.CheckBox(); - this.upperHexCheckBox = new System.Windows.Forms.CheckBox(); - this.codeViewFontGroupBox = new System.Windows.Forms.GroupBox(); - this.currentFontLabel = new System.Windows.Forms.Label(); - this.selectFontButton = new System.Windows.Forms.Button(); - this.currentFontDisplayLabel = new System.Windows.Forms.Label(); - this.columnVisGroup = new System.Windows.Forms.GroupBox(); - this.showCol0 = new System.Windows.Forms.Button(); - this.showCol8 = new System.Windows.Forms.Button(); - this.showCol1 = new System.Windows.Forms.Button(); - this.showCol7 = new System.Windows.Forms.Button(); - this.showCol2 = new System.Windows.Forms.Button(); - this.showCol6 = new System.Windows.Forms.Button(); - this.showCol3 = new System.Windows.Forms.Button(); - this.showCol5 = new System.Windows.Forms.Button(); - this.showCol4 = new System.Windows.Forms.Button(); - this.asmConfigTabPage = new System.Windows.Forms.TabPage(); - this.configureAsmGroupBox = new System.Windows.Forms.GroupBox(); - this.asmColWidthIdLabel = new System.Windows.Forms.Label(); - this.asmConfigAssemblerLabel = new System.Windows.Forms.Label(); - this.asmCommentColWidthTextBox = new System.Windows.Forms.TextBox(); - this.asmOperandColWidthTextBox = new System.Windows.Forms.TextBox(); - this.asmOpcodeColWidthTextBox = new System.Windows.Forms.TextBox(); - this.asmLabelColWidthTextBox = new System.Windows.Forms.TextBox(); - this.asmColWidthLabel = new System.Windows.Forms.Label(); - this.asmExeLabel = new System.Windows.Forms.Label(); - this.asmConfigComboBox = new System.Windows.Forms.ComboBox(); - this.asmExePathTextBox = new System.Windows.Forms.TextBox(); - this.asmExeBrowseButton = new System.Windows.Forms.Button(); - this.showCycleCountsCheckBox = new System.Windows.Forms.CheckBox(); - this.configAsmGenLabel = new System.Windows.Forms.Label(); - this.longLabelNewLineCheckBox = new System.Windows.Forms.CheckBox(); - this.showAsmIdentCheckBox = new System.Windows.Forms.CheckBox(); - this.disableLabelLocalizationCheckBox = new System.Windows.Forms.CheckBox(); - this.displayFormatTabPage = new System.Windows.Forms.TabPage(); - this.expressionStyleComboBox = new System.Windows.Forms.ComboBox(); - this.expressionStyleLabel = new System.Windows.Forms.Label(); - this.fmtExplanationLabel = new System.Windows.Forms.Label(); - this.quickDisplayFormatGroup = new System.Windows.Forms.GroupBox(); - this.displayFmtQuickComboBox = new System.Windows.Forms.ComboBox(); - this.displayFmtSetButton = new System.Windows.Forms.Button(); - this.quickFmtDefaultButton = new System.Windows.Forms.Button(); - this.operandWidthGroupBox = new System.Windows.Forms.GroupBox(); - this.disambPrefix24TextBox = new System.Windows.Forms.TextBox(); - this.disambPrefix16TextBox = new System.Windows.Forms.TextBox(); - this.disambPrefix24Label = new System.Windows.Forms.Label(); - this.disambPrefix16Label = new System.Windows.Forms.Label(); - this.disambOperandPrefixLabel = new System.Windows.Forms.Label(); - this.disambSuffix24Label = new System.Windows.Forms.Label(); - this.disambSuffix16Label = new System.Windows.Forms.Label(); - this.disambOpcodeSuffixLabel = new System.Windows.Forms.Label(); - this.disambSuffix24TextBox = new System.Windows.Forms.TextBox(); - this.disambSuffix16TextBox = new System.Windows.Forms.TextBox(); - this.pseudoOpTabPage = new System.Windows.Forms.TabPage(); - this.quickPseudoSetGroup = new System.Windows.Forms.GroupBox(); - this.pseudoOpSetButton = new System.Windows.Forms.Button(); - this.pseudoOpQuickComboBox = new System.Windows.Forms.ComboBox(); - this.quickPseudoDefaultButton = new System.Windows.Forms.Button(); - this.strDciHiTextBox = new System.Windows.Forms.TextBox(); - this.strDciHiLabel = new System.Windows.Forms.Label(); - this.strDciTextBox = new System.Windows.Forms.TextBox(); - this.strDciLabel = new System.Windows.Forms.Label(); - this.strLen16HiTextBox = new System.Windows.Forms.TextBox(); - this.strLen16HiLabel = new System.Windows.Forms.Label(); - this.strLen16TextBox = new System.Windows.Forms.TextBox(); - this.strLen16Label = new System.Windows.Forms.Label(); - this.strReverseHiTextBox = new System.Windows.Forms.TextBox(); - this.strReverseHiLabel = new System.Windows.Forms.Label(); - this.strReverseTextBox = new System.Windows.Forms.TextBox(); - this.strReverseLabel = new System.Windows.Forms.Label(); - this.strNullTermHiTextBox = new System.Windows.Forms.TextBox(); - this.strNullTermHiLabel = new System.Windows.Forms.Label(); - this.strNullTermTextBox = new System.Windows.Forms.TextBox(); - this.strNullTermLabel = new System.Windows.Forms.Label(); - this.strLen8HiTextBox = new System.Windows.Forms.TextBox(); - this.strLen8HiLabel = new System.Windows.Forms.Label(); - this.strLen8TextBox = new System.Windows.Forms.TextBox(); - this.strLen8Label = new System.Windows.Forms.Label(); - this.strGenericHiTextBox = new System.Windows.Forms.TextBox(); - this.strGenericHiLabel = new System.Windows.Forms.Label(); - this.strGenericTextBox = new System.Windows.Forms.TextBox(); - this.strGenericLabel = new System.Windows.Forms.Label(); - this.popExplanationLabel = new System.Windows.Forms.Label(); - this.denseTextBox = new System.Windows.Forms.TextBox(); - this.denseLabel = new System.Windows.Forms.Label(); - this.fillTextBox = new System.Windows.Forms.TextBox(); - this.fillLabel = new System.Windows.Forms.Label(); - this.defineBigData2TextBox = new System.Windows.Forms.TextBox(); - this.defineBigData2Label = new System.Windows.Forms.Label(); - this.defineData4TextBox = new System.Windows.Forms.TextBox(); - this.defineData4Label = new System.Windows.Forms.Label(); - this.defineData3TextBox = new System.Windows.Forms.TextBox(); - this.defineData3Label = new System.Windows.Forms.Label(); - this.defineData2TextBox = new System.Windows.Forms.TextBox(); - this.defineData2Label = new System.Windows.Forms.Label(); - this.regWidthDirectiveTextBox = new System.Windows.Forms.TextBox(); - this.regWidthDirectiveLabel = new System.Windows.Forms.Label(); - this.orgDirectiveTextBox = new System.Windows.Forms.TextBox(); - this.orgDirectiveLabel = new System.Windows.Forms.Label(); - this.defineData1TextBox = new System.Windows.Forms.TextBox(); - this.defineData1Label = new System.Windows.Forms.Label(); - this.equDirectiveTextBox = new System.Windows.Forms.TextBox(); - this.equDirectiveLabel = new System.Windows.Forms.Label(); - this.settingsTabControl.SuspendLayout(); - this.codeViewTabPage.SuspendLayout(); - this.codeViewMiscGroupBox.SuspendLayout(); - this.clipboardGroupBox.SuspendLayout(); - this.upperCaseGroupBox.SuspendLayout(); - this.codeViewFontGroupBox.SuspendLayout(); - this.columnVisGroup.SuspendLayout(); - this.asmConfigTabPage.SuspendLayout(); - this.configureAsmGroupBox.SuspendLayout(); - this.displayFormatTabPage.SuspendLayout(); - this.quickDisplayFormatGroup.SuspendLayout(); - this.operandWidthGroupBox.SuspendLayout(); - this.pseudoOpTabPage.SuspendLayout(); - this.quickPseudoSetGroup.SuspendLayout(); - this.SuspendLayout(); - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.Location = new System.Drawing.Point(537, 406); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 23); - this.cancelButton.TabIndex = 0; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - // - // okButton - // - this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.okButton.Location = new System.Drawing.Point(456, 406); - this.okButton.Name = "okButton"; - this.okButton.Size = new System.Drawing.Size(75, 23); - this.okButton.TabIndex = 3; - this.okButton.Text = "OK"; - this.okButton.UseVisualStyleBackColor = true; - this.okButton.Click += new System.EventHandler(this.okButton_Click); - // - // applyButton - // - this.applyButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.applyButton.Location = new System.Drawing.Point(354, 406); - this.applyButton.Name = "applyButton"; - this.applyButton.Size = new System.Drawing.Size(75, 23); - this.applyButton.TabIndex = 2; - this.applyButton.Text = "Apply"; - this.applyButton.UseVisualStyleBackColor = true; - this.applyButton.Click += new System.EventHandler(this.applyButton_Click); - // - // settingsTabControl - // - this.settingsTabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.settingsTabControl.Controls.Add(this.codeViewTabPage); - this.settingsTabControl.Controls.Add(this.asmConfigTabPage); - this.settingsTabControl.Controls.Add(this.displayFormatTabPage); - this.settingsTabControl.Controls.Add(this.pseudoOpTabPage); - this.settingsTabControl.Location = new System.Drawing.Point(2, 2); - this.settingsTabControl.Name = "settingsTabControl"; - this.settingsTabControl.SelectedIndex = 0; - this.settingsTabControl.Size = new System.Drawing.Size(622, 398); - this.settingsTabControl.TabIndex = 1; - // - // codeViewTabPage - // - this.codeViewTabPage.Controls.Add(this.codeViewMiscGroupBox); - this.codeViewTabPage.Controls.Add(this.clipboardGroupBox); - this.codeViewTabPage.Controls.Add(this.enableDebugCheckBox); - this.codeViewTabPage.Controls.Add(this.upperCaseGroupBox); - this.codeViewTabPage.Controls.Add(this.codeViewFontGroupBox); - this.codeViewTabPage.Controls.Add(this.columnVisGroup); - this.codeViewTabPage.Location = new System.Drawing.Point(4, 22); - this.codeViewTabPage.Name = "codeViewTabPage"; - this.codeViewTabPage.Padding = new System.Windows.Forms.Padding(3); - this.codeViewTabPage.Size = new System.Drawing.Size(614, 372); - this.codeViewTabPage.TabIndex = 0; - this.codeViewTabPage.Text = "Code View"; - this.codeViewTabPage.UseVisualStyleBackColor = true; - // - // codeViewMiscGroupBox - // - this.codeViewMiscGroupBox.Controls.Add(this.spacesBetweenBytesCheckBox); - this.codeViewMiscGroupBox.Location = new System.Drawing.Point(406, 101); - this.codeViewMiscGroupBox.Name = "codeViewMiscGroupBox"; - this.codeViewMiscGroupBox.Size = new System.Drawing.Size(200, 47); - this.codeViewMiscGroupBox.TabIndex = 5; - this.codeViewMiscGroupBox.TabStop = false; - this.codeViewMiscGroupBox.Text = "Miscellaneous"; - // - // spacesBetweenBytesCheckBox - // - this.spacesBetweenBytesCheckBox.AutoSize = true; - this.spacesBetweenBytesCheckBox.Location = new System.Drawing.Point(7, 20); - this.spacesBetweenBytesCheckBox.Name = "spacesBetweenBytesCheckBox"; - this.spacesBetweenBytesCheckBox.Size = new System.Drawing.Size(158, 17); - this.spacesBetweenBytesCheckBox.TabIndex = 0; - this.spacesBetweenBytesCheckBox.Text = "Add spaces in bytes column"; - this.spacesBetweenBytesCheckBox.UseVisualStyleBackColor = true; - this.spacesBetweenBytesCheckBox.CheckedChanged += new System.EventHandler(this.spacesBetweenBytesCheckBox_CheckedChanged); - // - // clipboardGroupBox - // - this.clipboardGroupBox.Controls.Add(this.clipboardFormatLabel); - this.clipboardGroupBox.Controls.Add(this.clipboardFormatComboBox); - this.clipboardGroupBox.Location = new System.Drawing.Point(406, 6); - this.clipboardGroupBox.Name = "clipboardGroupBox"; - this.clipboardGroupBox.Size = new System.Drawing.Size(200, 89); - this.clipboardGroupBox.TabIndex = 4; - this.clipboardGroupBox.TabStop = false; - this.clipboardGroupBox.Text = "Clipboard"; - // - // clipboardFormatLabel - // - this.clipboardFormatLabel.AutoSize = true; - this.clipboardFormatLabel.Location = new System.Drawing.Point(6, 22); - this.clipboardFormatLabel.Name = "clipboardFormatLabel"; - this.clipboardFormatLabel.Size = new System.Drawing.Size(174, 13); - this.clipboardFormatLabel.TabIndex = 1; - this.clipboardFormatLabel.Text = "Format for lines copied to clipboard:"; - // - // clipboardFormatComboBox - // - this.clipboardFormatComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.clipboardFormatComboBox.FormattingEnabled = true; - this.clipboardFormatComboBox.Items.AddRange(new object[] { - "Assembler Source", - "Disassembly"}); - this.clipboardFormatComboBox.Location = new System.Drawing.Point(6, 49); - this.clipboardFormatComboBox.Name = "clipboardFormatComboBox"; - this.clipboardFormatComboBox.Size = new System.Drawing.Size(188, 21); - this.clipboardFormatComboBox.TabIndex = 0; - this.clipboardFormatComboBox.SelectedIndexChanged += new System.EventHandler(this.clipboardFormatComboBox_SelectedIndexChanged); - // - // enableDebugCheckBox - // - this.enableDebugCheckBox.AutoSize = true; - this.enableDebugCheckBox.Location = new System.Drawing.Point(12, 349); - this.enableDebugCheckBox.Name = "enableDebugCheckBox"; - this.enableDebugCheckBox.Size = new System.Drawing.Size(129, 17); - this.enableDebugCheckBox.TabIndex = 3; - this.enableDebugCheckBox.Text = "Enable DEBUG menu"; - this.enableDebugCheckBox.UseVisualStyleBackColor = true; - this.enableDebugCheckBox.CheckedChanged += new System.EventHandler(this.enableDebugCheckBox_CheckedChanged); - // - // upperCaseGroupBox - // - this.upperCaseGroupBox.Controls.Add(this.upperAllUpperButton); - this.upperCaseGroupBox.Controls.Add(this.upperAllLowerButton); - this.upperCaseGroupBox.Controls.Add(this.upperXYCheckBox); - this.upperCaseGroupBox.Controls.Add(this.upperSCheckBox); - this.upperCaseGroupBox.Controls.Add(this.upperACheckBox); - this.upperCaseGroupBox.Controls.Add(this.upperPseudoOpCheckBox); - this.upperCaseGroupBox.Controls.Add(this.upperOpcodeCheckBox); - this.upperCaseGroupBox.Controls.Add(this.upperHexCheckBox); - this.upperCaseGroupBox.Location = new System.Drawing.Point(162, 101); - this.upperCaseGroupBox.Name = "upperCaseGroupBox"; - this.upperCaseGroupBox.Size = new System.Drawing.Size(224, 197); - this.upperCaseGroupBox.TabIndex = 0; - this.upperCaseGroupBox.TabStop = false; - this.upperCaseGroupBox.Text = "Upper Case Display"; - // - // upperAllUpperButton - // - this.upperAllUpperButton.Location = new System.Drawing.Point(88, 164); - this.upperAllUpperButton.Name = "upperAllUpperButton"; - this.upperAllUpperButton.Size = new System.Drawing.Size(75, 23); - this.upperAllUpperButton.TabIndex = 7; - this.upperAllUpperButton.Text = "All Upper"; - this.upperAllUpperButton.UseVisualStyleBackColor = true; - this.upperAllUpperButton.Click += new System.EventHandler(this.upperAllUpperButton_Click); - // - // upperAllLowerButton - // - this.upperAllLowerButton.Location = new System.Drawing.Point(7, 164); - this.upperAllLowerButton.Name = "upperAllLowerButton"; - this.upperAllLowerButton.Size = new System.Drawing.Size(75, 23); - this.upperAllLowerButton.TabIndex = 6; - this.upperAllLowerButton.Text = "All Lower"; - this.upperAllLowerButton.UseVisualStyleBackColor = true; - this.upperAllLowerButton.Click += new System.EventHandler(this.upperAllLowerButton_Click); - // - // upperXYCheckBox - // - this.upperXYCheckBox.AutoSize = true; - this.upperXYCheckBox.Location = new System.Drawing.Point(8, 139); - this.upperXYCheckBox.Name = "upperXYCheckBox"; - this.upperXYCheckBox.Size = new System.Drawing.Size(89, 17); - this.upperXYCheckBox.TabIndex = 5; - this.upperXYCheckBox.Text = "Operand X/Y"; - this.upperXYCheckBox.UseVisualStyleBackColor = true; - this.upperXYCheckBox.CheckedChanged += new System.EventHandler(this.upperXYCheckBox_CheckedChanged); - // - // upperSCheckBox - // - this.upperSCheckBox.AutoSize = true; - this.upperSCheckBox.Location = new System.Drawing.Point(8, 115); - this.upperSCheckBox.Name = "upperSCheckBox"; - this.upperSCheckBox.Size = new System.Drawing.Size(77, 17); - this.upperSCheckBox.TabIndex = 4; - this.upperSCheckBox.Text = "Operand S"; - this.upperSCheckBox.UseVisualStyleBackColor = true; - this.upperSCheckBox.CheckedChanged += new System.EventHandler(this.upperSCheckBox_CheckedChanged); - // - // upperACheckBox - // - this.upperACheckBox.AutoSize = true; - this.upperACheckBox.Location = new System.Drawing.Point(8, 91); - this.upperACheckBox.Name = "upperACheckBox"; - this.upperACheckBox.Size = new System.Drawing.Size(77, 17); - this.upperACheckBox.TabIndex = 3; - this.upperACheckBox.Text = "Operand A"; - this.upperACheckBox.UseVisualStyleBackColor = true; - this.upperACheckBox.CheckedChanged += new System.EventHandler(this.upperACheckBox_CheckedChanged); - // - // upperPseudoOpCheckBox - // - this.upperPseudoOpCheckBox.AutoSize = true; - this.upperPseudoOpCheckBox.Location = new System.Drawing.Point(8, 67); - this.upperPseudoOpCheckBox.Name = "upperPseudoOpCheckBox"; - this.upperPseudoOpCheckBox.Size = new System.Drawing.Size(106, 17); - this.upperPseudoOpCheckBox.TabIndex = 2; - this.upperPseudoOpCheckBox.Text = "Pseudo-opcodes"; - this.upperPseudoOpCheckBox.UseVisualStyleBackColor = true; - this.upperPseudoOpCheckBox.CheckedChanged += new System.EventHandler(this.upperPseudoOpCheckBox_CheckedChanged); - // - // upperOpcodeCheckBox - // - this.upperOpcodeCheckBox.AutoSize = true; - this.upperOpcodeCheckBox.Location = new System.Drawing.Point(8, 44); - this.upperOpcodeCheckBox.Name = "upperOpcodeCheckBox"; - this.upperOpcodeCheckBox.Size = new System.Drawing.Size(69, 17); - this.upperOpcodeCheckBox.TabIndex = 1; - this.upperOpcodeCheckBox.Text = "Opcodes"; - this.upperOpcodeCheckBox.UseVisualStyleBackColor = true; - this.upperOpcodeCheckBox.CheckedChanged += new System.EventHandler(this.upperOpcodeCheckBox_CheckedChanged); - // - // upperHexCheckBox - // - this.upperHexCheckBox.AutoSize = true; - this.upperHexCheckBox.Location = new System.Drawing.Point(8, 20); - this.upperHexCheckBox.Name = "upperHexCheckBox"; - this.upperHexCheckBox.Size = new System.Drawing.Size(121, 17); - this.upperHexCheckBox.TabIndex = 0; - this.upperHexCheckBox.Text = "Hexadecimal values"; - this.upperHexCheckBox.UseVisualStyleBackColor = true; - this.upperHexCheckBox.CheckedChanged += new System.EventHandler(this.upperHexCheckBox_CheckedChanged); - // - // codeViewFontGroupBox - // - this.codeViewFontGroupBox.Controls.Add(this.currentFontLabel); - this.codeViewFontGroupBox.Controls.Add(this.selectFontButton); - this.codeViewFontGroupBox.Controls.Add(this.currentFontDisplayLabel); - this.codeViewFontGroupBox.Location = new System.Drawing.Point(162, 6); - this.codeViewFontGroupBox.Name = "codeViewFontGroupBox"; - this.codeViewFontGroupBox.Size = new System.Drawing.Size(224, 89); - this.codeViewFontGroupBox.TabIndex = 2; - this.codeViewFontGroupBox.TabStop = false; - this.codeViewFontGroupBox.Text = "Code List Font"; - // - // currentFontLabel - // - this.currentFontLabel.AutoSize = true; - this.currentFontLabel.Location = new System.Drawing.Point(7, 18); - this.currentFontLabel.Name = "currentFontLabel"; - this.currentFontLabel.Size = new System.Drawing.Size(65, 13); - this.currentFontLabel.TabIndex = 0; - this.currentFontLabel.Text = "Current font:"; - // - // selectFontButton - // - this.selectFontButton.Location = new System.Drawing.Point(6, 58); - this.selectFontButton.Name = "selectFontButton"; - this.selectFontButton.Size = new System.Drawing.Size(125, 23); - this.selectFontButton.TabIndex = 2; - this.selectFontButton.Text = "Select Font..."; - this.selectFontButton.UseVisualStyleBackColor = true; - this.selectFontButton.Click += new System.EventHandler(this.selectFontButton_Click); - // - // currentFontDisplayLabel - // - this.currentFontDisplayLabel.AutoSize = true; - this.currentFontDisplayLabel.Location = new System.Drawing.Point(7, 33); - this.currentFontDisplayLabel.Name = "currentFontDisplayLabel"; - this.currentFontDisplayLabel.Size = new System.Drawing.Size(181, 13); - this.currentFontDisplayLabel.TabIndex = 1; - this.currentFontDisplayLabel.Text = "Constantia, 14.25pt, style=Bold, Italic"; - // - // columnVisGroup - // - this.columnVisGroup.Controls.Add(this.showCol0); - this.columnVisGroup.Controls.Add(this.showCol8); - this.columnVisGroup.Controls.Add(this.showCol1); - this.columnVisGroup.Controls.Add(this.showCol7); - this.columnVisGroup.Controls.Add(this.showCol2); - this.columnVisGroup.Controls.Add(this.showCol6); - this.columnVisGroup.Controls.Add(this.showCol3); - this.columnVisGroup.Controls.Add(this.showCol5); - this.columnVisGroup.Controls.Add(this.showCol4); - this.columnVisGroup.Location = new System.Drawing.Point(6, 6); - this.columnVisGroup.Name = "columnVisGroup"; - this.columnVisGroup.Size = new System.Drawing.Size(122, 292); - this.columnVisGroup.TabIndex = 0; - this.columnVisGroup.TabStop = false; - this.columnVisGroup.Text = "Column Visibility"; - // - // showCol0 - // - this.showCol0.Location = new System.Drawing.Point(6, 19); - this.showCol0.Name = "showCol0"; - this.showCol0.Size = new System.Drawing.Size(110, 23); - this.showCol0.TabIndex = 0; - this.showCol0.Text = "{0} Offset"; - this.showCol0.UseVisualStyleBackColor = true; - // - // showCol8 - // - this.showCol8.Location = new System.Drawing.Point(6, 259); - this.showCol8.Name = "showCol8"; - this.showCol8.Size = new System.Drawing.Size(110, 23); - this.showCol8.TabIndex = 8; - this.showCol8.Text = "{0} Comment"; - this.showCol8.UseVisualStyleBackColor = true; - // - // showCol1 - // - this.showCol1.Location = new System.Drawing.Point(6, 49); - this.showCol1.Name = "showCol1"; - this.showCol1.Size = new System.Drawing.Size(110, 23); - this.showCol1.TabIndex = 1; - this.showCol1.Text = "{0} Address"; - this.showCol1.UseVisualStyleBackColor = true; - // - // showCol7 - // - this.showCol7.Location = new System.Drawing.Point(6, 229); - this.showCol7.Name = "showCol7"; - this.showCol7.Size = new System.Drawing.Size(110, 23); - this.showCol7.TabIndex = 7; - this.showCol7.Text = "{0} Operand"; - this.showCol7.UseVisualStyleBackColor = true; - // - // showCol2 - // - this.showCol2.Location = new System.Drawing.Point(6, 79); - this.showCol2.Name = "showCol2"; - this.showCol2.Size = new System.Drawing.Size(110, 23); - this.showCol2.TabIndex = 2; - this.showCol2.Text = "{0} Bytes"; - this.showCol2.UseVisualStyleBackColor = true; - // - // showCol6 - // - this.showCol6.Location = new System.Drawing.Point(6, 199); - this.showCol6.Name = "showCol6"; - this.showCol6.Size = new System.Drawing.Size(110, 23); - this.showCol6.TabIndex = 6; - this.showCol6.Text = "{0} Opcode"; - this.showCol6.UseVisualStyleBackColor = true; - // - // showCol3 - // - this.showCol3.Location = new System.Drawing.Point(6, 109); - this.showCol3.Name = "showCol3"; - this.showCol3.Size = new System.Drawing.Size(110, 23); - this.showCol3.TabIndex = 3; - this.showCol3.Text = "{0} Flags"; - this.showCol3.UseVisualStyleBackColor = true; - // - // showCol5 - // - this.showCol5.Location = new System.Drawing.Point(6, 169); - this.showCol5.Name = "showCol5"; - this.showCol5.Size = new System.Drawing.Size(110, 23); - this.showCol5.TabIndex = 5; - this.showCol5.Text = "{0} Label"; - this.showCol5.UseVisualStyleBackColor = true; - // - // showCol4 - // - this.showCol4.Location = new System.Drawing.Point(6, 139); - this.showCol4.Name = "showCol4"; - this.showCol4.Size = new System.Drawing.Size(110, 23); - this.showCol4.TabIndex = 4; - this.showCol4.Text = "{0} Attributes"; - this.showCol4.UseVisualStyleBackColor = true; - // - // asmConfigTabPage - // - this.asmConfigTabPage.Controls.Add(this.configureAsmGroupBox); - this.asmConfigTabPage.Controls.Add(this.showCycleCountsCheckBox); - this.asmConfigTabPage.Controls.Add(this.configAsmGenLabel); - this.asmConfigTabPage.Controls.Add(this.longLabelNewLineCheckBox); - this.asmConfigTabPage.Controls.Add(this.showAsmIdentCheckBox); - this.asmConfigTabPage.Controls.Add(this.disableLabelLocalizationCheckBox); - this.asmConfigTabPage.Location = new System.Drawing.Point(4, 22); - this.asmConfigTabPage.Name = "asmConfigTabPage"; - this.asmConfigTabPage.Padding = new System.Windows.Forms.Padding(3); - this.asmConfigTabPage.Size = new System.Drawing.Size(614, 372); - this.asmConfigTabPage.TabIndex = 1; - this.asmConfigTabPage.Text = "Asm Config"; - this.asmConfigTabPage.UseVisualStyleBackColor = true; - // - // configureAsmGroupBox - // - this.configureAsmGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.configureAsmGroupBox.Controls.Add(this.asmColWidthIdLabel); - this.configureAsmGroupBox.Controls.Add(this.asmConfigAssemblerLabel); - this.configureAsmGroupBox.Controls.Add(this.asmCommentColWidthTextBox); - this.configureAsmGroupBox.Controls.Add(this.asmOperandColWidthTextBox); - this.configureAsmGroupBox.Controls.Add(this.asmOpcodeColWidthTextBox); - this.configureAsmGroupBox.Controls.Add(this.asmLabelColWidthTextBox); - this.configureAsmGroupBox.Controls.Add(this.asmColWidthLabel); - this.configureAsmGroupBox.Controls.Add(this.asmExeLabel); - this.configureAsmGroupBox.Controls.Add(this.asmConfigComboBox); - this.configureAsmGroupBox.Controls.Add(this.asmExePathTextBox); - this.configureAsmGroupBox.Controls.Add(this.asmExeBrowseButton); - this.configureAsmGroupBox.Location = new System.Drawing.Point(6, 6); - this.configureAsmGroupBox.Name = "configureAsmGroupBox"; - this.configureAsmGroupBox.Size = new System.Drawing.Size(602, 121); - this.configureAsmGroupBox.TabIndex = 0; - this.configureAsmGroupBox.TabStop = false; - this.configureAsmGroupBox.Text = "Assembler Configuration"; - // - // asmColWidthIdLabel - // - this.asmColWidthIdLabel.AutoSize = true; - this.asmColWidthIdLabel.Location = new System.Drawing.Point(371, 88); - this.asmColWidthIdLabel.Name = "asmColWidthIdLabel"; - this.asmColWidthIdLabel.Size = new System.Drawing.Size(171, 13); - this.asmColWidthIdLabel.TabIndex = 10; - this.asmColWidthIdLabel.Text = "(label, opcode, operand, comment)"; - // - // asmConfigAssemblerLabel - // - this.asmConfigAssemblerLabel.AutoSize = true; - this.asmConfigAssemblerLabel.Location = new System.Drawing.Point(27, 22); - this.asmConfigAssemblerLabel.Name = "asmConfigAssemblerLabel"; - this.asmConfigAssemblerLabel.Size = new System.Drawing.Size(58, 13); - this.asmConfigAssemblerLabel.TabIndex = 0; - this.asmConfigAssemblerLabel.Text = "Assembler:"; - // - // asmCommentColWidthTextBox - // - this.asmCommentColWidthTextBox.Location = new System.Drawing.Point(301, 85); - this.asmCommentColWidthTextBox.Name = "asmCommentColWidthTextBox"; - this.asmCommentColWidthTextBox.Size = new System.Drawing.Size(64, 20); - this.asmCommentColWidthTextBox.TabIndex = 9; - this.asmCommentColWidthTextBox.TextChanged += new System.EventHandler(this.AsmConfig_TextChanged); - // - // asmOperandColWidthTextBox - // - this.asmOperandColWidthTextBox.Location = new System.Drawing.Point(231, 85); - this.asmOperandColWidthTextBox.Name = "asmOperandColWidthTextBox"; - this.asmOperandColWidthTextBox.Size = new System.Drawing.Size(64, 20); - this.asmOperandColWidthTextBox.TabIndex = 8; - this.asmOperandColWidthTextBox.TextChanged += new System.EventHandler(this.AsmConfig_TextChanged); - // - // asmOpcodeColWidthTextBox - // - this.asmOpcodeColWidthTextBox.Location = new System.Drawing.Point(161, 85); - this.asmOpcodeColWidthTextBox.Name = "asmOpcodeColWidthTextBox"; - this.asmOpcodeColWidthTextBox.Size = new System.Drawing.Size(64, 20); - this.asmOpcodeColWidthTextBox.TabIndex = 7; - this.asmOpcodeColWidthTextBox.TextChanged += new System.EventHandler(this.AsmConfig_TextChanged); - // - // asmLabelColWidthTextBox - // - this.asmLabelColWidthTextBox.Location = new System.Drawing.Point(91, 85); - this.asmLabelColWidthTextBox.Name = "asmLabelColWidthTextBox"; - this.asmLabelColWidthTextBox.Size = new System.Drawing.Size(64, 20); - this.asmLabelColWidthTextBox.TabIndex = 6; - this.asmLabelColWidthTextBox.TextChanged += new System.EventHandler(this.AsmConfig_TextChanged); - // - // asmColWidthLabel - // - this.asmColWidthLabel.AutoSize = true; - this.asmColWidthLabel.Location = new System.Drawing.Point(7, 88); - this.asmColWidthLabel.Name = "asmColWidthLabel"; - this.asmColWidthLabel.Size = new System.Drawing.Size(78, 13); - this.asmColWidthLabel.TabIndex = 5; - this.asmColWidthLabel.Text = "Column widths:"; - // - // asmExeLabel - // - this.asmExeLabel.AutoSize = true; - this.asmExeLabel.Location = new System.Drawing.Point(22, 61); - this.asmExeLabel.Name = "asmExeLabel"; - this.asmExeLabel.Size = new System.Drawing.Size(63, 13); - this.asmExeLabel.TabIndex = 2; - this.asmExeLabel.Text = "Executable:"; - // - // asmConfigComboBox - // - this.asmConfigComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.asmConfigComboBox.FormattingEnabled = true; - this.asmConfigComboBox.Location = new System.Drawing.Point(91, 19); - this.asmConfigComboBox.Name = "asmConfigComboBox"; - this.asmConfigComboBox.Size = new System.Drawing.Size(154, 21); - this.asmConfigComboBox.TabIndex = 1; - this.asmConfigComboBox.SelectedIndexChanged += new System.EventHandler(this.asmConfigComboBox_SelectedIndexChanged); - // - // asmExePathTextBox - // - this.asmExePathTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.asmExePathTextBox.Location = new System.Drawing.Point(91, 58); - this.asmExePathTextBox.Name = "asmExePathTextBox"; - this.asmExePathTextBox.Size = new System.Drawing.Size(424, 20); - this.asmExePathTextBox.TabIndex = 3; - this.asmExePathTextBox.Text = "C:\\something"; - this.asmExePathTextBox.TextChanged += new System.EventHandler(this.AsmConfig_TextChanged); - // - // asmExeBrowseButton - // - this.asmExeBrowseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.asmExeBrowseButton.Location = new System.Drawing.Point(521, 56); - this.asmExeBrowseButton.Name = "asmExeBrowseButton"; - this.asmExeBrowseButton.Size = new System.Drawing.Size(75, 23); - this.asmExeBrowseButton.TabIndex = 4; - this.asmExeBrowseButton.Text = "Browse..."; - this.asmExeBrowseButton.UseVisualStyleBackColor = true; - this.asmExeBrowseButton.Click += new System.EventHandler(this.asmExeBrowseButton_Click); - // - // showCycleCountsCheckBox - // - this.showCycleCountsCheckBox.AutoSize = true; - this.showCycleCountsCheckBox.Location = new System.Drawing.Point(6, 162); - this.showCycleCountsCheckBox.Name = "showCycleCountsCheckBox"; - this.showCycleCountsCheckBox.Size = new System.Drawing.Size(116, 17); - this.showCycleCountsCheckBox.TabIndex = 2; - this.showCycleCountsCheckBox.Text = "Show cycle counts"; - this.showCycleCountsCheckBox.UseVisualStyleBackColor = true; - this.showCycleCountsCheckBox.CheckedChanged += new System.EventHandler(this.showCycleCountsCheckBox_CheckedChanged); - // - // configAsmGenLabel - // - this.configAsmGenLabel.AutoSize = true; - this.configAsmGenLabel.Location = new System.Drawing.Point(3, 143); - this.configAsmGenLabel.Name = "configAsmGenLabel"; - this.configAsmGenLabel.Size = new System.Drawing.Size(127, 13); - this.configAsmGenLabel.TabIndex = 1; - this.configAsmGenLabel.Text = "General code generation:"; - // - // longLabelNewLineCheckBox - // - this.longLabelNewLineCheckBox.AutoSize = true; - this.longLabelNewLineCheckBox.Location = new System.Drawing.Point(6, 185); - this.longLabelNewLineCheckBox.Name = "longLabelNewLineCheckBox"; - this.longLabelNewLineCheckBox.Size = new System.Drawing.Size(173, 17); - this.longLabelNewLineCheckBox.TabIndex = 3; - this.longLabelNewLineCheckBox.Text = "Put long labels on separate line"; - this.longLabelNewLineCheckBox.UseVisualStyleBackColor = true; - // - // showAsmIdentCheckBox - // - this.showAsmIdentCheckBox.AutoSize = true; - this.showAsmIdentCheckBox.Location = new System.Drawing.Point(6, 208); - this.showAsmIdentCheckBox.Name = "showAsmIdentCheckBox"; - this.showAsmIdentCheckBox.Size = new System.Drawing.Size(154, 17); - this.showAsmIdentCheckBox.TabIndex = 4; - this.showAsmIdentCheckBox.Text = "Identify assembler in output"; - this.showAsmIdentCheckBox.UseVisualStyleBackColor = true; - this.showAsmIdentCheckBox.CheckedChanged += new System.EventHandler(this.showAsmIdentCheckBox_CheckedChanged); - // - // disableLabelLocalizationCheckBox - // - this.disableLabelLocalizationCheckBox.AutoSize = true; - this.disableLabelLocalizationCheckBox.Location = new System.Drawing.Point(6, 231); - this.disableLabelLocalizationCheckBox.Name = "disableLabelLocalizationCheckBox"; - this.disableLabelLocalizationCheckBox.Size = new System.Drawing.Size(141, 17); - this.disableLabelLocalizationCheckBox.TabIndex = 5; - this.disableLabelLocalizationCheckBox.Text = "Disable label localization"; - this.disableLabelLocalizationCheckBox.UseVisualStyleBackColor = true; - this.disableLabelLocalizationCheckBox.CheckedChanged += new System.EventHandler(this.disableLabelLocalizationCheckBox_CheckedChanged); - // - // displayFormatTabPage - // - this.displayFormatTabPage.Controls.Add(this.expressionStyleComboBox); - this.displayFormatTabPage.Controls.Add(this.expressionStyleLabel); - this.displayFormatTabPage.Controls.Add(this.fmtExplanationLabel); - this.displayFormatTabPage.Controls.Add(this.quickDisplayFormatGroup); - this.displayFormatTabPage.Controls.Add(this.operandWidthGroupBox); - this.displayFormatTabPage.Location = new System.Drawing.Point(4, 22); - this.displayFormatTabPage.Name = "displayFormatTabPage"; - this.displayFormatTabPage.Padding = new System.Windows.Forms.Padding(3); - this.displayFormatTabPage.Size = new System.Drawing.Size(614, 372); - this.displayFormatTabPage.TabIndex = 3; - this.displayFormatTabPage.Text = "Display Format"; - this.displayFormatTabPage.UseVisualStyleBackColor = true; - // - // expressionStyleComboBox - // - this.expressionStyleComboBox.FormattingEnabled = true; - this.expressionStyleComboBox.Location = new System.Drawing.Point(98, 153); - this.expressionStyleComboBox.Name = "expressionStyleComboBox"; - this.expressionStyleComboBox.Size = new System.Drawing.Size(121, 21); - this.expressionStyleComboBox.TabIndex = 5; - this.expressionStyleComboBox.SelectedIndexChanged += new System.EventHandler(this.expressionStyleComboBox_SelectedIndexChanged); - // - // expressionStyleLabel - // - this.expressionStyleLabel.AutoSize = true; - this.expressionStyleLabel.Location = new System.Drawing.Point(7, 156); - this.expressionStyleLabel.Name = "expressionStyleLabel"; - this.expressionStyleLabel.Size = new System.Drawing.Size(85, 13); - this.expressionStyleLabel.TabIndex = 4; - this.expressionStyleLabel.Text = "Expression style:"; - // - // fmtExplanationLabel - // - this.fmtExplanationLabel.AutoSize = true; - this.fmtExplanationLabel.Location = new System.Drawing.Point(7, 7); - this.fmtExplanationLabel.Name = "fmtExplanationLabel"; - this.fmtExplanationLabel.Size = new System.Drawing.Size(374, 13); - this.fmtExplanationLabel.TabIndex = 0; - this.fmtExplanationLabel.Text = "Configure display format options. This does not affect source code generation."; - // - // quickDisplayFormatGroup - // - this.quickDisplayFormatGroup.Controls.Add(this.displayFmtQuickComboBox); - this.quickDisplayFormatGroup.Controls.Add(this.displayFmtSetButton); - this.quickDisplayFormatGroup.Controls.Add(this.quickFmtDefaultButton); - this.quickDisplayFormatGroup.Location = new System.Drawing.Point(215, 291); - this.quickDisplayFormatGroup.Name = "quickDisplayFormatGroup"; - this.quickDisplayFormatGroup.Size = new System.Drawing.Size(391, 75); - this.quickDisplayFormatGroup.TabIndex = 3; - this.quickDisplayFormatGroup.TabStop = false; - this.quickDisplayFormatGroup.Text = "Quick Set"; - // - // displayFmtQuickComboBox - // - this.displayFmtQuickComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.displayFmtQuickComboBox.FormattingEnabled = true; - this.displayFmtQuickComboBox.Items.AddRange(new object[] { - "MegaAsm"}); - this.displayFmtQuickComboBox.Location = new System.Drawing.Point(136, 32); - this.displayFmtQuickComboBox.Name = "displayFmtQuickComboBox"; - this.displayFmtQuickComboBox.Size = new System.Drawing.Size(168, 21); - this.displayFmtQuickComboBox.TabIndex = 1; - // - // displayFmtSetButton - // - this.displayFmtSetButton.Location = new System.Drawing.Point(310, 30); - this.displayFmtSetButton.Name = "displayFmtSetButton"; - this.displayFmtSetButton.Size = new System.Drawing.Size(75, 23); - this.displayFmtSetButton.TabIndex = 2; - this.displayFmtSetButton.Text = "Set"; - this.displayFmtSetButton.UseVisualStyleBackColor = true; - this.displayFmtSetButton.Click += new System.EventHandler(this.displayFmtSetButton_Click); - // - // quickFmtDefaultButton - // - this.quickFmtDefaultButton.Location = new System.Drawing.Point(11, 30); - this.quickFmtDefaultButton.Name = "quickFmtDefaultButton"; - this.quickFmtDefaultButton.Size = new System.Drawing.Size(75, 23); - this.quickFmtDefaultButton.TabIndex = 0; - this.quickFmtDefaultButton.Text = "Default"; - this.quickFmtDefaultButton.UseVisualStyleBackColor = true; - this.quickFmtDefaultButton.Click += new System.EventHandler(this.quickFmtDefaultButton_Click); - // - // operandWidthGroupBox - // - this.operandWidthGroupBox.Controls.Add(this.disambPrefix24TextBox); - this.operandWidthGroupBox.Controls.Add(this.disambPrefix16TextBox); - this.operandWidthGroupBox.Controls.Add(this.disambPrefix24Label); - this.operandWidthGroupBox.Controls.Add(this.disambPrefix16Label); - this.operandWidthGroupBox.Controls.Add(this.disambOperandPrefixLabel); - this.operandWidthGroupBox.Controls.Add(this.disambSuffix24Label); - this.operandWidthGroupBox.Controls.Add(this.disambSuffix16Label); - this.operandWidthGroupBox.Controls.Add(this.disambOpcodeSuffixLabel); - this.operandWidthGroupBox.Controls.Add(this.disambSuffix24TextBox); - this.operandWidthGroupBox.Controls.Add(this.disambSuffix16TextBox); - this.operandWidthGroupBox.Location = new System.Drawing.Point(6, 40); - this.operandWidthGroupBox.Name = "operandWidthGroupBox"; - this.operandWidthGroupBox.Size = new System.Drawing.Size(295, 98); - this.operandWidthGroupBox.TabIndex = 1; - this.operandWidthGroupBox.TabStop = false; - this.operandWidthGroupBox.Text = "Operand Width Disambiguator"; - // - // disambPrefix24TextBox - // - this.disambPrefix24TextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.disambPrefix24TextBox.Location = new System.Drawing.Point(220, 66); - this.disambPrefix24TextBox.MaxLength = 8; - this.disambPrefix24TextBox.Name = "disambPrefix24TextBox"; - this.disambPrefix24TextBox.Size = new System.Drawing.Size(62, 20); - this.disambPrefix24TextBox.TabIndex = 9; - this.disambPrefix24TextBox.Text = ".placeho"; - this.disambPrefix24TextBox.TextChanged += new System.EventHandler(this.WidthDisamControlChanged); - // - // disambPrefix16TextBox - // - this.disambPrefix16TextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.disambPrefix16TextBox.Location = new System.Drawing.Point(220, 40); - this.disambPrefix16TextBox.MaxLength = 8; - this.disambPrefix16TextBox.Name = "disambPrefix16TextBox"; - this.disambPrefix16TextBox.Size = new System.Drawing.Size(62, 20); - this.disambPrefix16TextBox.TabIndex = 7; - this.disambPrefix16TextBox.Text = ".placeho"; - this.disambPrefix16TextBox.TextChanged += new System.EventHandler(this.WidthDisamControlChanged); - // - // disambPrefix24Label - // - this.disambPrefix24Label.AutoSize = true; - this.disambPrefix24Label.Location = new System.Drawing.Point(171, 68); - this.disambPrefix24Label.Name = "disambPrefix24Label"; - this.disambPrefix24Label.Size = new System.Drawing.Size(36, 13); - this.disambPrefix24Label.TabIndex = 8; - this.disambPrefix24Label.Text = "24 bit:"; - // - // disambPrefix16Label - // - this.disambPrefix16Label.AutoSize = true; - this.disambPrefix16Label.Location = new System.Drawing.Point(171, 42); - this.disambPrefix16Label.Name = "disambPrefix16Label"; - this.disambPrefix16Label.Size = new System.Drawing.Size(36, 13); - this.disambPrefix16Label.TabIndex = 6; - this.disambPrefix16Label.Text = "16 bit:"; - // - // disambOperandPrefixLabel - // - this.disambOperandPrefixLabel.AutoSize = true; - this.disambOperandPrefixLabel.Location = new System.Drawing.Point(171, 20); - this.disambOperandPrefixLabel.Name = "disambOperandPrefixLabel"; - this.disambOperandPrefixLabel.Size = new System.Drawing.Size(79, 13); - this.disambOperandPrefixLabel.TabIndex = 5; - this.disambOperandPrefixLabel.Text = "Operand prefix:"; - // - // disambSuffix24Label - // - this.disambSuffix24Label.AutoSize = true; - this.disambSuffix24Label.Location = new System.Drawing.Point(10, 68); - this.disambSuffix24Label.Name = "disambSuffix24Label"; - this.disambSuffix24Label.Size = new System.Drawing.Size(36, 13); - this.disambSuffix24Label.TabIndex = 3; - this.disambSuffix24Label.Text = "24 bit:"; - // - // disambSuffix16Label - // - this.disambSuffix16Label.AutoSize = true; - this.disambSuffix16Label.Location = new System.Drawing.Point(10, 42); - this.disambSuffix16Label.Name = "disambSuffix16Label"; - this.disambSuffix16Label.Size = new System.Drawing.Size(36, 13); - this.disambSuffix16Label.TabIndex = 1; - this.disambSuffix16Label.Text = "16 bit:"; - // - // disambOpcodeSuffixLabel - // - this.disambOpcodeSuffixLabel.AutoSize = true; - this.disambOpcodeSuffixLabel.Location = new System.Drawing.Point(7, 20); - this.disambOpcodeSuffixLabel.Name = "disambOpcodeSuffixLabel"; - this.disambOpcodeSuffixLabel.Size = new System.Drawing.Size(75, 13); - this.disambOpcodeSuffixLabel.TabIndex = 0; - this.disambOpcodeSuffixLabel.Text = "Opcode suffix:"; - // - // disambSuffix24TextBox - // - this.disambSuffix24TextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.disambSuffix24TextBox.Location = new System.Drawing.Point(62, 66); - this.disambSuffix24TextBox.MaxLength = 8; - this.disambSuffix24TextBox.Name = "disambSuffix24TextBox"; - this.disambSuffix24TextBox.Size = new System.Drawing.Size(62, 20); - this.disambSuffix24TextBox.TabIndex = 4; - this.disambSuffix24TextBox.Text = ".placeho"; - this.disambSuffix24TextBox.TextChanged += new System.EventHandler(this.WidthDisamControlChanged); - // - // disambSuffix16TextBox - // - this.disambSuffix16TextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.disambSuffix16TextBox.Location = new System.Drawing.Point(62, 40); - this.disambSuffix16TextBox.MaxLength = 8; - this.disambSuffix16TextBox.Name = "disambSuffix16TextBox"; - this.disambSuffix16TextBox.Size = new System.Drawing.Size(62, 20); - this.disambSuffix16TextBox.TabIndex = 2; - this.disambSuffix16TextBox.Text = ".placeho"; - this.disambSuffix16TextBox.TextChanged += new System.EventHandler(this.WidthDisamControlChanged); - // - // pseudoOpTabPage - // - this.pseudoOpTabPage.Controls.Add(this.quickPseudoSetGroup); - this.pseudoOpTabPage.Controls.Add(this.strDciHiTextBox); - this.pseudoOpTabPage.Controls.Add(this.strDciHiLabel); - this.pseudoOpTabPage.Controls.Add(this.strDciTextBox); - this.pseudoOpTabPage.Controls.Add(this.strDciLabel); - this.pseudoOpTabPage.Controls.Add(this.strLen16HiTextBox); - this.pseudoOpTabPage.Controls.Add(this.strLen16HiLabel); - this.pseudoOpTabPage.Controls.Add(this.strLen16TextBox); - this.pseudoOpTabPage.Controls.Add(this.strLen16Label); - this.pseudoOpTabPage.Controls.Add(this.strReverseHiTextBox); - this.pseudoOpTabPage.Controls.Add(this.strReverseHiLabel); - this.pseudoOpTabPage.Controls.Add(this.strReverseTextBox); - this.pseudoOpTabPage.Controls.Add(this.strReverseLabel); - this.pseudoOpTabPage.Controls.Add(this.strNullTermHiTextBox); - this.pseudoOpTabPage.Controls.Add(this.strNullTermHiLabel); - this.pseudoOpTabPage.Controls.Add(this.strNullTermTextBox); - this.pseudoOpTabPage.Controls.Add(this.strNullTermLabel); - this.pseudoOpTabPage.Controls.Add(this.strLen8HiTextBox); - this.pseudoOpTabPage.Controls.Add(this.strLen8HiLabel); - this.pseudoOpTabPage.Controls.Add(this.strLen8TextBox); - this.pseudoOpTabPage.Controls.Add(this.strLen8Label); - this.pseudoOpTabPage.Controls.Add(this.strGenericHiTextBox); - this.pseudoOpTabPage.Controls.Add(this.strGenericHiLabel); - this.pseudoOpTabPage.Controls.Add(this.strGenericTextBox); - this.pseudoOpTabPage.Controls.Add(this.strGenericLabel); - this.pseudoOpTabPage.Controls.Add(this.popExplanationLabel); - this.pseudoOpTabPage.Controls.Add(this.denseTextBox); - this.pseudoOpTabPage.Controls.Add(this.denseLabel); - this.pseudoOpTabPage.Controls.Add(this.fillTextBox); - this.pseudoOpTabPage.Controls.Add(this.fillLabel); - this.pseudoOpTabPage.Controls.Add(this.defineBigData2TextBox); - this.pseudoOpTabPage.Controls.Add(this.defineBigData2Label); - this.pseudoOpTabPage.Controls.Add(this.defineData4TextBox); - this.pseudoOpTabPage.Controls.Add(this.defineData4Label); - this.pseudoOpTabPage.Controls.Add(this.defineData3TextBox); - this.pseudoOpTabPage.Controls.Add(this.defineData3Label); - this.pseudoOpTabPage.Controls.Add(this.defineData2TextBox); - this.pseudoOpTabPage.Controls.Add(this.defineData2Label); - this.pseudoOpTabPage.Controls.Add(this.regWidthDirectiveTextBox); - this.pseudoOpTabPage.Controls.Add(this.regWidthDirectiveLabel); - this.pseudoOpTabPage.Controls.Add(this.orgDirectiveTextBox); - this.pseudoOpTabPage.Controls.Add(this.orgDirectiveLabel); - this.pseudoOpTabPage.Controls.Add(this.defineData1TextBox); - this.pseudoOpTabPage.Controls.Add(this.defineData1Label); - this.pseudoOpTabPage.Controls.Add(this.equDirectiveTextBox); - this.pseudoOpTabPage.Controls.Add(this.equDirectiveLabel); - this.pseudoOpTabPage.Location = new System.Drawing.Point(4, 22); - this.pseudoOpTabPage.Name = "pseudoOpTabPage"; - this.pseudoOpTabPage.Padding = new System.Windows.Forms.Padding(3); - this.pseudoOpTabPage.Size = new System.Drawing.Size(614, 372); - this.pseudoOpTabPage.TabIndex = 2; - this.pseudoOpTabPage.Text = "Pseudo-Op"; - this.pseudoOpTabPage.UseVisualStyleBackColor = true; - // - // quickPseudoSetGroup - // - this.quickPseudoSetGroup.Controls.Add(this.pseudoOpSetButton); - this.quickPseudoSetGroup.Controls.Add(this.pseudoOpQuickComboBox); - this.quickPseudoSetGroup.Controls.Add(this.quickPseudoDefaultButton); - this.quickPseudoSetGroup.Location = new System.Drawing.Point(215, 291); - this.quickPseudoSetGroup.Name = "quickPseudoSetGroup"; - this.quickPseudoSetGroup.Size = new System.Drawing.Size(391, 75); - this.quickPseudoSetGroup.TabIndex = 45; - this.quickPseudoSetGroup.TabStop = false; - this.quickPseudoSetGroup.Text = "Quick Set"; - // - // pseudoOpSetButton - // - this.pseudoOpSetButton.Location = new System.Drawing.Point(310, 30); - this.pseudoOpSetButton.Name = "pseudoOpSetButton"; - this.pseudoOpSetButton.Size = new System.Drawing.Size(75, 23); - this.pseudoOpSetButton.TabIndex = 2; - this.pseudoOpSetButton.Text = "Set"; - this.pseudoOpSetButton.UseVisualStyleBackColor = true; - this.pseudoOpSetButton.Click += new System.EventHandler(this.pseudoOpSetButton_Click); - // - // pseudoOpQuickComboBox - // - this.pseudoOpQuickComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.pseudoOpQuickComboBox.FormattingEnabled = true; - this.pseudoOpQuickComboBox.Location = new System.Drawing.Point(136, 32); - this.pseudoOpQuickComboBox.Name = "pseudoOpQuickComboBox"; - this.pseudoOpQuickComboBox.Size = new System.Drawing.Size(168, 21); - this.pseudoOpQuickComboBox.TabIndex = 1; - // - // quickPseudoDefaultButton - // - this.quickPseudoDefaultButton.Location = new System.Drawing.Point(11, 30); - this.quickPseudoDefaultButton.Name = "quickPseudoDefaultButton"; - this.quickPseudoDefaultButton.Size = new System.Drawing.Size(75, 23); - this.quickPseudoDefaultButton.TabIndex = 0; - this.quickPseudoDefaultButton.Text = "Default"; - this.quickPseudoDefaultButton.UseVisualStyleBackColor = true; - this.quickPseudoDefaultButton.Click += new System.EventHandler(this.quickPseudoDefaultButton_Click); - // - // strDciHiTextBox - // - this.strDciHiTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.strDciHiTextBox.Location = new System.Drawing.Point(546, 230); - this.strDciHiTextBox.MaxLength = 8; - this.strDciHiTextBox.Name = "strDciHiTextBox"; - this.strDciHiTextBox.Size = new System.Drawing.Size(62, 20); - this.strDciHiTextBox.TabIndex = 44; - this.strDciHiTextBox.Text = ".placeho"; - this.strDciHiTextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // strDciHiLabel - // - this.strDciHiLabel.Location = new System.Drawing.Point(463, 232); - this.strDciHiLabel.Name = "strDciHiLabel"; - this.strDciHiLabel.Size = new System.Drawing.Size(79, 23); - this.strDciHiLabel.TabIndex = 43; - this.strDciHiLabel.Text = "DCI/hi:"; - this.strDciHiLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // strDciTextBox - // - this.strDciTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.strDciTextBox.Location = new System.Drawing.Point(394, 230); - this.strDciTextBox.MaxLength = 8; - this.strDciTextBox.Name = "strDciTextBox"; - this.strDciTextBox.Size = new System.Drawing.Size(62, 20); - this.strDciTextBox.TabIndex = 42; - this.strDciTextBox.Text = ".placeho"; - this.strDciTextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // strDciLabel - // - this.strDciLabel.Location = new System.Drawing.Point(309, 232); - this.strDciLabel.Name = "strDciLabel"; - this.strDciLabel.Size = new System.Drawing.Size(82, 23); - this.strDciLabel.TabIndex = 41; - this.strDciLabel.Text = "DCI:"; - this.strDciLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // strLen16HiTextBox - // - this.strLen16HiTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.strLen16HiTextBox.Location = new System.Drawing.Point(546, 192); - this.strLen16HiTextBox.MaxLength = 8; - this.strLen16HiTextBox.Name = "strLen16HiTextBox"; - this.strLen16HiTextBox.Size = new System.Drawing.Size(62, 20); - this.strLen16HiTextBox.TabIndex = 36; - this.strLen16HiTextBox.Text = ".placeho"; - this.strLen16HiTextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // strLen16HiLabel - // - this.strLen16HiLabel.Location = new System.Drawing.Point(463, 194); - this.strLen16HiLabel.Name = "strLen16HiLabel"; - this.strLen16HiLabel.Size = new System.Drawing.Size(79, 23); - this.strLen16HiLabel.TabIndex = 35; - this.strLen16HiLabel.Text = "2-byte len/hi:"; - this.strLen16HiLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // strLen16TextBox - // - this.strLen16TextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.strLen16TextBox.Location = new System.Drawing.Point(394, 192); - this.strLen16TextBox.MaxLength = 8; - this.strLen16TextBox.Name = "strLen16TextBox"; - this.strLen16TextBox.Size = new System.Drawing.Size(62, 20); - this.strLen16TextBox.TabIndex = 34; - this.strLen16TextBox.Text = ".placeho"; - this.strLen16TextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // strLen16Label - // - this.strLen16Label.Location = new System.Drawing.Point(309, 194); - this.strLen16Label.Name = "strLen16Label"; - this.strLen16Label.Size = new System.Drawing.Size(82, 23); - this.strLen16Label.TabIndex = 33; - this.strLen16Label.Text = "2-byte len:"; - this.strLen16Label.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // strReverseHiTextBox - // - this.strReverseHiTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.strReverseHiTextBox.Location = new System.Drawing.Point(546, 154); - this.strReverseHiTextBox.MaxLength = 8; - this.strReverseHiTextBox.Name = "strReverseHiTextBox"; - this.strReverseHiTextBox.Size = new System.Drawing.Size(62, 20); - this.strReverseHiTextBox.TabIndex = 28; - this.strReverseHiTextBox.Text = ".placeho"; - this.strReverseHiTextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // strReverseHiLabel - // - this.strReverseHiLabel.Location = new System.Drawing.Point(463, 156); - this.strReverseHiLabel.Name = "strReverseHiLabel"; - this.strReverseHiLabel.Size = new System.Drawing.Size(79, 23); - this.strReverseHiLabel.TabIndex = 27; - this.strReverseHiLabel.Text = "Reverse/hi:"; - this.strReverseHiLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // strReverseTextBox - // - this.strReverseTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.strReverseTextBox.Location = new System.Drawing.Point(394, 154); - this.strReverseTextBox.MaxLength = 8; - this.strReverseTextBox.Name = "strReverseTextBox"; - this.strReverseTextBox.Size = new System.Drawing.Size(62, 20); - this.strReverseTextBox.TabIndex = 26; - this.strReverseTextBox.Text = ".placeho"; - this.strReverseTextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // strReverseLabel - // - this.strReverseLabel.Location = new System.Drawing.Point(309, 156); - this.strReverseLabel.Name = "strReverseLabel"; - this.strReverseLabel.Size = new System.Drawing.Size(82, 23); - this.strReverseLabel.TabIndex = 25; - this.strReverseLabel.Text = "Reverse:"; - this.strReverseLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // strNullTermHiTextBox - // - this.strNullTermHiTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.strNullTermHiTextBox.Location = new System.Drawing.Point(244, 230); - this.strNullTermHiTextBox.MaxLength = 8; - this.strNullTermHiTextBox.Name = "strNullTermHiTextBox"; - this.strNullTermHiTextBox.Size = new System.Drawing.Size(62, 20); - this.strNullTermHiTextBox.TabIndex = 40; - this.strNullTermHiTextBox.Text = ".placeho"; - this.strNullTermHiTextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // strNullTermHiLabel - // - this.strNullTermHiLabel.Location = new System.Drawing.Point(160, 232); - this.strNullTermHiLabel.Name = "strNullTermHiLabel"; - this.strNullTermHiLabel.Size = new System.Drawing.Size(80, 23); - this.strNullTermHiLabel.TabIndex = 39; - this.strNullTermHiLabel.Text = "Null term/hi:"; - this.strNullTermHiLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // strNullTermTextBox - // - this.strNullTermTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.strNullTermTextBox.Location = new System.Drawing.Point(92, 230); - this.strNullTermTextBox.MaxLength = 8; - this.strNullTermTextBox.Name = "strNullTermTextBox"; - this.strNullTermTextBox.Size = new System.Drawing.Size(62, 20); - this.strNullTermTextBox.TabIndex = 38; - this.strNullTermTextBox.Text = ".placeho"; - this.strNullTermTextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // strNullTermLabel - // - this.strNullTermLabel.Location = new System.Drawing.Point(3, 232); - this.strNullTermLabel.Name = "strNullTermLabel"; - this.strNullTermLabel.Size = new System.Drawing.Size(85, 23); - this.strNullTermLabel.TabIndex = 37; - this.strNullTermLabel.Text = "Null term string:"; - this.strNullTermLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // strLen8HiTextBox - // - this.strLen8HiTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.strLen8HiTextBox.Location = new System.Drawing.Point(244, 192); - this.strLen8HiTextBox.MaxLength = 8; - this.strLen8HiTextBox.Name = "strLen8HiTextBox"; - this.strLen8HiTextBox.Size = new System.Drawing.Size(62, 20); - this.strLen8HiTextBox.TabIndex = 32; - this.strLen8HiTextBox.Text = ".placeho"; - this.strLen8HiTextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // strLen8HiLabel - // - this.strLen8HiLabel.Location = new System.Drawing.Point(160, 194); - this.strLen8HiLabel.Name = "strLen8HiLabel"; - this.strLen8HiLabel.Size = new System.Drawing.Size(80, 23); - this.strLen8HiLabel.TabIndex = 31; - this.strLen8HiLabel.Text = "1-byte len/hi:"; - this.strLen8HiLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // strLen8TextBox - // - this.strLen8TextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.strLen8TextBox.Location = new System.Drawing.Point(92, 192); - this.strLen8TextBox.MaxLength = 8; - this.strLen8TextBox.Name = "strLen8TextBox"; - this.strLen8TextBox.Size = new System.Drawing.Size(62, 20); - this.strLen8TextBox.TabIndex = 30; - this.strLen8TextBox.Text = ".placeho"; - this.strLen8TextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // strLen8Label - // - this.strLen8Label.Location = new System.Drawing.Point(7, 194); - this.strLen8Label.Name = "strLen8Label"; - this.strLen8Label.Size = new System.Drawing.Size(81, 23); - this.strLen8Label.TabIndex = 29; - this.strLen8Label.Text = "1-byte len:"; - this.strLen8Label.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // strGenericHiTextBox - // - this.strGenericHiTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.strGenericHiTextBox.Location = new System.Drawing.Point(244, 154); - this.strGenericHiTextBox.MaxLength = 8; - this.strGenericHiTextBox.Name = "strGenericHiTextBox"; - this.strGenericHiTextBox.Size = new System.Drawing.Size(62, 20); - this.strGenericHiTextBox.TabIndex = 24; - this.strGenericHiTextBox.Text = ".placeho"; - this.strGenericHiTextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // strGenericHiLabel - // - this.strGenericHiLabel.Location = new System.Drawing.Point(160, 156); - this.strGenericHiLabel.Name = "strGenericHiLabel"; - this.strGenericHiLabel.Size = new System.Drawing.Size(80, 23); - this.strGenericHiLabel.TabIndex = 23; - this.strGenericHiLabel.Text = "Generic/hi:"; - this.strGenericHiLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // strGenericTextBox - // - this.strGenericTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.strGenericTextBox.Location = new System.Drawing.Point(92, 154); - this.strGenericTextBox.MaxLength = 8; - this.strGenericTextBox.Name = "strGenericTextBox"; - this.strGenericTextBox.Size = new System.Drawing.Size(62, 20); - this.strGenericTextBox.TabIndex = 22; - this.strGenericTextBox.Text = ".placeho"; - this.strGenericTextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // strGenericLabel - // - this.strGenericLabel.Location = new System.Drawing.Point(3, 156); - this.strGenericLabel.Name = "strGenericLabel"; - this.strGenericLabel.Size = new System.Drawing.Size(85, 23); - this.strGenericLabel.TabIndex = 21; - this.strGenericLabel.Text = "Generic string:"; - this.strGenericLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // popExplanationLabel - // - this.popExplanationLabel.AutoSize = true; - this.popExplanationLabel.Location = new System.Drawing.Point(7, 7); - this.popExplanationLabel.Name = "popExplanationLabel"; - this.popExplanationLabel.Size = new System.Drawing.Size(550, 13); - this.popExplanationLabel.TabIndex = 0; - this.popExplanationLabel.Text = "Select pseudo-op names for display. This does not affect source code generation. " + - "Blank entries get a default value."; - // - // denseTextBox - // - this.denseTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.denseTextBox.Location = new System.Drawing.Point(546, 116); - this.denseTextBox.MaxLength = 8; - this.denseTextBox.Name = "denseTextBox"; - this.denseTextBox.Size = new System.Drawing.Size(62, 20); - this.denseTextBox.TabIndex = 20; - this.denseTextBox.Text = ".placeho"; - this.denseTextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // denseLabel - // - this.denseLabel.Location = new System.Drawing.Point(460, 118); - this.denseLabel.Name = "denseLabel"; - this.denseLabel.Size = new System.Drawing.Size(82, 23); - this.denseLabel.TabIndex = 19; - this.denseLabel.Text = "Bulk data:"; - this.denseLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // fillTextBox - // - this.fillTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.fillTextBox.Location = new System.Drawing.Point(395, 116); - this.fillTextBox.MaxLength = 8; - this.fillTextBox.Name = "fillTextBox"; - this.fillTextBox.Size = new System.Drawing.Size(62, 20); - this.fillTextBox.TabIndex = 18; - this.fillTextBox.Text = ".placeho"; - this.fillTextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // fillLabel - // - this.fillLabel.Location = new System.Drawing.Point(309, 118); - this.fillLabel.Name = "fillLabel"; - this.fillLabel.Size = new System.Drawing.Size(82, 23); - this.fillLabel.TabIndex = 17; - this.fillLabel.Text = "Fill:"; - this.fillLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // defineBigData2TextBox - // - this.defineBigData2TextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.defineBigData2TextBox.Location = new System.Drawing.Point(92, 116); - this.defineBigData2TextBox.MaxLength = 8; - this.defineBigData2TextBox.Name = "defineBigData2TextBox"; - this.defineBigData2TextBox.Size = new System.Drawing.Size(62, 20); - this.defineBigData2TextBox.TabIndex = 16; - this.defineBigData2TextBox.Text = ".placeho"; - this.defineBigData2TextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // defineBigData2Label - // - this.defineBigData2Label.Location = new System.Drawing.Point(3, 113); - this.defineBigData2Label.Name = "defineBigData2Label"; - this.defineBigData2Label.Size = new System.Drawing.Size(85, 32); - this.defineBigData2Label.TabIndex = 15; - this.defineBigData2Label.Text = "Big-endian data, two bytes:"; - this.defineBigData2Label.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // defineData4TextBox - // - this.defineData4TextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.defineData4TextBox.Location = new System.Drawing.Point(546, 78); - this.defineData4TextBox.MaxLength = 8; - this.defineData4TextBox.Name = "defineData4TextBox"; - this.defineData4TextBox.Size = new System.Drawing.Size(62, 20); - this.defineData4TextBox.TabIndex = 14; - this.defineData4TextBox.Text = ".placeho"; - this.defineData4TextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // defineData4Label - // - this.defineData4Label.Location = new System.Drawing.Point(463, 80); - this.defineData4Label.Name = "defineData4Label"; - this.defineData4Label.Size = new System.Drawing.Size(79, 23); - this.defineData4Label.TabIndex = 13; - this.defineData4Label.Text = "Four bytes:"; - this.defineData4Label.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // defineData3TextBox - // - this.defineData3TextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.defineData3TextBox.Location = new System.Drawing.Point(395, 78); - this.defineData3TextBox.MaxLength = 8; - this.defineData3TextBox.Name = "defineData3TextBox"; - this.defineData3TextBox.Size = new System.Drawing.Size(62, 20); - this.defineData3TextBox.TabIndex = 12; - this.defineData3TextBox.Text = ".placeho"; - this.defineData3TextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // defineData3Label - // - this.defineData3Label.Location = new System.Drawing.Point(309, 80); - this.defineData3Label.Name = "defineData3Label"; - this.defineData3Label.Size = new System.Drawing.Size(82, 23); - this.defineData3Label.TabIndex = 11; - this.defineData3Label.Text = "Three bytes:"; - this.defineData3Label.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // defineData2TextBox - // - this.defineData2TextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.defineData2TextBox.Location = new System.Drawing.Point(244, 78); - this.defineData2TextBox.MaxLength = 8; - this.defineData2TextBox.Name = "defineData2TextBox"; - this.defineData2TextBox.Size = new System.Drawing.Size(62, 20); - this.defineData2TextBox.TabIndex = 10; - this.defineData2TextBox.Text = ".placeho"; - this.defineData2TextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // defineData2Label - // - this.defineData2Label.Location = new System.Drawing.Point(160, 80); - this.defineData2Label.Name = "defineData2Label"; - this.defineData2Label.Size = new System.Drawing.Size(80, 23); - this.defineData2Label.TabIndex = 9; - this.defineData2Label.Text = "Two bytes:"; - this.defineData2Label.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // regWidthDirectiveTextBox - // - this.regWidthDirectiveTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.regWidthDirectiveTextBox.Location = new System.Drawing.Point(395, 40); - this.regWidthDirectiveTextBox.MaxLength = 8; - this.regWidthDirectiveTextBox.Name = "regWidthDirectiveTextBox"; - this.regWidthDirectiveTextBox.Size = new System.Drawing.Size(62, 20); - this.regWidthDirectiveTextBox.TabIndex = 6; - this.regWidthDirectiveTextBox.Text = ".placeho"; - this.regWidthDirectiveTextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // regWidthDirectiveLabel - // - this.regWidthDirectiveLabel.Location = new System.Drawing.Point(312, 42); - this.regWidthDirectiveLabel.Name = "regWidthDirectiveLabel"; - this.regWidthDirectiveLabel.Size = new System.Drawing.Size(79, 23); - this.regWidthDirectiveLabel.TabIndex = 5; - this.regWidthDirectiveLabel.Text = "Reg width:"; - this.regWidthDirectiveLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // orgDirectiveTextBox - // - this.orgDirectiveTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.orgDirectiveTextBox.Location = new System.Drawing.Point(244, 40); - this.orgDirectiveTextBox.MaxLength = 8; - this.orgDirectiveTextBox.Name = "orgDirectiveTextBox"; - this.orgDirectiveTextBox.Size = new System.Drawing.Size(62, 20); - this.orgDirectiveTextBox.TabIndex = 4; - this.orgDirectiveTextBox.Text = ".placeho"; - this.orgDirectiveTextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // orgDirectiveLabel - // - this.orgDirectiveLabel.Location = new System.Drawing.Point(160, 42); - this.orgDirectiveLabel.Name = "orgDirectiveLabel"; - this.orgDirectiveLabel.Size = new System.Drawing.Size(80, 23); - this.orgDirectiveLabel.TabIndex = 3; - this.orgDirectiveLabel.Text = "Origin:"; - this.orgDirectiveLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // defineData1TextBox - // - this.defineData1TextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.defineData1TextBox.Location = new System.Drawing.Point(92, 78); - this.defineData1TextBox.MaxLength = 8; - this.defineData1TextBox.Name = "defineData1TextBox"; - this.defineData1TextBox.Size = new System.Drawing.Size(62, 20); - this.defineData1TextBox.TabIndex = 8; - this.defineData1TextBox.Text = ".placeho"; - this.defineData1TextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // defineData1Label - // - this.defineData1Label.Location = new System.Drawing.Point(3, 74); - this.defineData1Label.Name = "defineData1Label"; - this.defineData1Label.Size = new System.Drawing.Size(85, 32); - this.defineData1Label.TabIndex = 7; - this.defineData1Label.Text = "Little-endian data, one byte:"; - this.defineData1Label.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // equDirectiveTextBox - // - this.equDirectiveTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.equDirectiveTextBox.Location = new System.Drawing.Point(92, 40); - this.equDirectiveTextBox.MaxLength = 8; - this.equDirectiveTextBox.Name = "equDirectiveTextBox"; - this.equDirectiveTextBox.Size = new System.Drawing.Size(62, 20); - this.equDirectiveTextBox.TabIndex = 2; - this.equDirectiveTextBox.Text = ".placeho"; - this.equDirectiveTextBox.TextChanged += new System.EventHandler(this.PseudoOpTextChanged); - // - // equDirectiveLabel - // - this.equDirectiveLabel.Location = new System.Drawing.Point(3, 42); - this.equDirectiveLabel.Name = "equDirectiveLabel"; - this.equDirectiveLabel.Size = new System.Drawing.Size(85, 23); - this.equDirectiveLabel.TabIndex = 1; - this.equDirectiveLabel.Text = "Equate:"; - this.equDirectiveLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // EditAppSettings - // - this.AcceptButton = this.okButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(624, 441); - this.Controls.Add(this.settingsTabControl); - this.Controls.Add(this.applyButton); - this.Controls.Add(this.okButton); - this.Controls.Add(this.cancelButton); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "EditAppSettings"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Edit Settings"; - this.Load += new System.EventHandler(this.EditAppSettings_Load); - this.settingsTabControl.ResumeLayout(false); - this.codeViewTabPage.ResumeLayout(false); - this.codeViewTabPage.PerformLayout(); - this.codeViewMiscGroupBox.ResumeLayout(false); - this.codeViewMiscGroupBox.PerformLayout(); - this.clipboardGroupBox.ResumeLayout(false); - this.clipboardGroupBox.PerformLayout(); - this.upperCaseGroupBox.ResumeLayout(false); - this.upperCaseGroupBox.PerformLayout(); - this.codeViewFontGroupBox.ResumeLayout(false); - this.codeViewFontGroupBox.PerformLayout(); - this.columnVisGroup.ResumeLayout(false); - this.asmConfigTabPage.ResumeLayout(false); - this.asmConfigTabPage.PerformLayout(); - this.configureAsmGroupBox.ResumeLayout(false); - this.configureAsmGroupBox.PerformLayout(); - this.displayFormatTabPage.ResumeLayout(false); - this.displayFormatTabPage.PerformLayout(); - this.quickDisplayFormatGroup.ResumeLayout(false); - this.operandWidthGroupBox.ResumeLayout(false); - this.operandWidthGroupBox.PerformLayout(); - this.pseudoOpTabPage.ResumeLayout(false); - this.pseudoOpTabPage.PerformLayout(); - this.quickPseudoSetGroup.ResumeLayout(false); - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.Button cancelButton; - private System.Windows.Forms.Button okButton; - private System.Windows.Forms.Button applyButton; - private System.Windows.Forms.TabControl settingsTabControl; - private System.Windows.Forms.TabPage codeViewTabPage; - private System.Windows.Forms.TabPage asmConfigTabPage; - private System.Windows.Forms.TabPage pseudoOpTabPage; - private System.Windows.Forms.GroupBox columnVisGroup; - private System.Windows.Forms.Button showCol0; - private System.Windows.Forms.Button showCol8; - private System.Windows.Forms.Button showCol1; - private System.Windows.Forms.Button showCol7; - private System.Windows.Forms.Button showCol2; - private System.Windows.Forms.Button showCol6; - private System.Windows.Forms.Button showCol3; - private System.Windows.Forms.Button showCol5; - private System.Windows.Forms.Button showCol4; - private System.Windows.Forms.TextBox defineData1TextBox; - private System.Windows.Forms.Label defineData1Label; - private System.Windows.Forms.TextBox equDirectiveTextBox; - private System.Windows.Forms.Label equDirectiveLabel; - private System.Windows.Forms.TextBox denseTextBox; - private System.Windows.Forms.Label denseLabel; - private System.Windows.Forms.TextBox fillTextBox; - private System.Windows.Forms.Label fillLabel; - private System.Windows.Forms.TextBox defineBigData2TextBox; - private System.Windows.Forms.Label defineBigData2Label; - private System.Windows.Forms.TextBox defineData4TextBox; - private System.Windows.Forms.Label defineData4Label; - private System.Windows.Forms.TextBox defineData3TextBox; - private System.Windows.Forms.Label defineData3Label; - private System.Windows.Forms.TextBox defineData2TextBox; - private System.Windows.Forms.Label defineData2Label; - private System.Windows.Forms.TextBox regWidthDirectiveTextBox; - private System.Windows.Forms.Label regWidthDirectiveLabel; - private System.Windows.Forms.TextBox orgDirectiveTextBox; - private System.Windows.Forms.Label orgDirectiveLabel; - private System.Windows.Forms.Label popExplanationLabel; - private System.Windows.Forms.TextBox strLen8HiTextBox; - private System.Windows.Forms.Label strLen8HiLabel; - private System.Windows.Forms.TextBox strLen8TextBox; - private System.Windows.Forms.Label strLen8Label; - private System.Windows.Forms.TextBox strGenericHiTextBox; - private System.Windows.Forms.Label strGenericHiLabel; - private System.Windows.Forms.TextBox strGenericTextBox; - private System.Windows.Forms.Label strGenericLabel; - private System.Windows.Forms.TextBox strNullTermHiTextBox; - private System.Windows.Forms.Label strNullTermHiLabel; - private System.Windows.Forms.TextBox strNullTermTextBox; - private System.Windows.Forms.Label strNullTermLabel; - private System.Windows.Forms.TextBox strDciHiTextBox; - private System.Windows.Forms.Label strDciHiLabel; - private System.Windows.Forms.TextBox strDciTextBox; - private System.Windows.Forms.Label strDciLabel; - private System.Windows.Forms.TextBox strLen16HiTextBox; - private System.Windows.Forms.Label strLen16HiLabel; - private System.Windows.Forms.TextBox strLen16TextBox; - private System.Windows.Forms.Label strLen16Label; - private System.Windows.Forms.TextBox strReverseHiTextBox; - private System.Windows.Forms.Label strReverseHiLabel; - private System.Windows.Forms.TextBox strReverseTextBox; - private System.Windows.Forms.Label strReverseLabel; - private System.Windows.Forms.TextBox asmExePathTextBox; - private System.Windows.Forms.Button asmExeBrowseButton; - private System.Windows.Forms.GroupBox codeViewFontGroupBox; - private System.Windows.Forms.Label currentFontLabel; - private System.Windows.Forms.Button selectFontButton; - private System.Windows.Forms.Label currentFontDisplayLabel; - private System.Windows.Forms.GroupBox quickPseudoSetGroup; - private System.Windows.Forms.Button quickPseudoDefaultButton; - private System.Windows.Forms.GroupBox upperCaseGroupBox; - private System.Windows.Forms.CheckBox upperOpcodeCheckBox; - private System.Windows.Forms.CheckBox upperHexCheckBox; - private System.Windows.Forms.Button upperAllUpperButton; - private System.Windows.Forms.Button upperAllLowerButton; - private System.Windows.Forms.CheckBox upperXYCheckBox; - private System.Windows.Forms.CheckBox upperSCheckBox; - private System.Windows.Forms.CheckBox upperACheckBox; - private System.Windows.Forms.CheckBox upperPseudoOpCheckBox; - private System.Windows.Forms.CheckBox disableLabelLocalizationCheckBox; - private System.Windows.Forms.CheckBox enableDebugCheckBox; - private System.Windows.Forms.CheckBox showAsmIdentCheckBox; - private System.Windows.Forms.TabPage displayFormatTabPage; - private System.Windows.Forms.GroupBox operandWidthGroupBox; - private System.Windows.Forms.TextBox disambPrefix24TextBox; - private System.Windows.Forms.TextBox disambPrefix16TextBox; - private System.Windows.Forms.Label disambPrefix24Label; - private System.Windows.Forms.Label disambPrefix16Label; - private System.Windows.Forms.Label disambOperandPrefixLabel; - private System.Windows.Forms.Label disambSuffix24Label; - private System.Windows.Forms.Label disambSuffix16Label; - private System.Windows.Forms.Label disambOpcodeSuffixLabel; - private System.Windows.Forms.TextBox disambSuffix24TextBox; - private System.Windows.Forms.TextBox disambSuffix16TextBox; - private System.Windows.Forms.GroupBox quickDisplayFormatGroup; - private System.Windows.Forms.Button quickFmtDefaultButton; - private System.Windows.Forms.Label configAsmGenLabel; - private System.Windows.Forms.CheckBox longLabelNewLineCheckBox; - private System.Windows.Forms.Label fmtExplanationLabel; - private System.Windows.Forms.CheckBox showCycleCountsCheckBox; - private System.Windows.Forms.GroupBox clipboardGroupBox; - private System.Windows.Forms.ComboBox clipboardFormatComboBox; - private System.Windows.Forms.Label clipboardFormatLabel; - private System.Windows.Forms.ComboBox asmConfigComboBox; - private System.Windows.Forms.GroupBox configureAsmGroupBox; - private System.Windows.Forms.Label asmExeLabel; - private System.Windows.Forms.Label asmColWidthLabel; - private System.Windows.Forms.TextBox asmCommentColWidthTextBox; - private System.Windows.Forms.TextBox asmOperandColWidthTextBox; - private System.Windows.Forms.TextBox asmOpcodeColWidthTextBox; - private System.Windows.Forms.TextBox asmLabelColWidthTextBox; - private System.Windows.Forms.Label asmConfigAssemblerLabel; - private System.Windows.Forms.Label asmColWidthIdLabel; - private System.Windows.Forms.Button pseudoOpSetButton; - private System.Windows.Forms.ComboBox pseudoOpQuickComboBox; - private System.Windows.Forms.Button displayFmtSetButton; - private System.Windows.Forms.ComboBox displayFmtQuickComboBox; - private System.Windows.Forms.GroupBox codeViewMiscGroupBox; - private System.Windows.Forms.CheckBox spacesBetweenBytesCheckBox; - private System.Windows.Forms.ComboBox expressionStyleComboBox; - private System.Windows.Forms.Label expressionStyleLabel; - } -} \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditAppSettings.cs b/SourceGenWF/AppForms/EditAppSettings.cs deleted file mode 100644 index 4de6541..0000000 --- a/SourceGenWF/AppForms/EditAppSettings.cs +++ /dev/null @@ -1,745 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Drawing; -using System.Reflection; -using System.Windows.Forms; - -using AssemblerInfo = SourceGenWF.AsmGen.AssemblerInfo; -using AssemblerConfig = SourceGenWF.AsmGen.AssemblerConfig; -using ExpressionMode = Asm65.Formatter.FormatConfig.ExpressionMode; - -namespace SourceGenWF.AppForms { - public partial class EditAppSettings : Form { - /// - /// Tab page enumeration. Numbers must match page indices in designer. - /// - public enum Tab { - Unknown = -1, - CodeView = 0, - AsmConfig = 1, - DisplayFOrmat = 2, - PseudoOp = 3 - } - - /// - /// Clipboard format enumeration. Numbers must match order of items in combo box. - /// - public enum ClipLineFormat { - Unknown = -1, - AssemblerSource = 0, - Disassembly = 1 - } - - /// - /// ProjectView reference. When the user hits Apply, the object's ApplyAppSettings - /// method will be invoked. - /// - private ProjectView mProjectView; - - /// - /// Copy of settings that we make changes to. On "Apply" or "OK", this is pushed - /// into the global settings object, and applied to the ProjectView. - /// - private AppSettings mSettings; - - /// - /// Dirty flag, set when anything in mSettings changes. Don't modify this directly. Use - /// the SetDirty() call so that the Apply button's enabled status gets updated. - /// - private bool mDirty; - - /// - /// Tab to show when dialog is first opened. - /// - private Tab mInitialTab; - - /// - /// Assembler to initially select in combo boxes. - /// - private AssemblerInfo.Id mInitialAsmId; - - // Map buttons to column show/hide buttons. - private const int NUM_COLUMNS = ProjectView.CodeListColumnWidths.NUM_COLUMNS; - private string[] mColumnFormats = new string[NUM_COLUMNS]; - private Button[] mColButtons; - - /// - /// Map pseudo-op text entry fields to PseudoOpName properties. - /// - private struct TextBoxPropertyMap { - public TextBox TextBox { get; private set; } - public PropertyInfo PropInfo { get; private set; } - - public TextBoxPropertyMap(TextBox textBox, string propName) { - TextBox = textBox; - PropInfo = typeof(PseudoOp.PseudoOpNames).GetProperty(propName); - } - } - private TextBoxPropertyMap[] mPseudoNameMap; - - /// - /// Holds an item for the assembler-selection combox box. - /// - private class AsmComboItem { - // Enumerated ID. - public AssemblerInfo.Id AssemblerId { get; private set; } - - // Human-readable name for display. - public string Name { get; private set; } - - public AsmComboItem(AssemblerInfo info) { - AssemblerId = info.AssemblerId; - Name = info.Name; - } - } - - /// - /// Holds an item for the expression style selection combo box. - /// - private struct ExpressionStyleItem { - // Enumerated mode. - public ExpressionMode ExpMode { get; private set; } - - // Human-readable name for display. - public string Name { get; private set; } - - public ExpressionStyleItem(ExpressionMode expMode, string name) { - ExpMode = expMode; - Name = name; - } - } - private static ExpressionStyleItem[] sExpStyleItems = new ExpressionStyleItem[] { - new ExpressionStyleItem(ExpressionMode.Common, "Common"), - new ExpressionStyleItem(ExpressionMode.Cc65, "cc65"), - new ExpressionStyleItem(ExpressionMode.Merlin, "Merlin"), - }; - - - public EditAppSettings(ProjectView projectView, Tab initialTab, - AssemblerInfo.Id initialAsmId) { - InitializeComponent(); - - mProjectView = projectView; - mInitialTab = initialTab; - mInitialAsmId = initialAsmId; - - // Make a work copy, so we can discard changes if the user cancels out of the dialog. - projectView.SerializeCodeListColumnWidths(); - mSettings = AppSettings.Global.GetCopy(); - - // Put column-width buttons in an array. - mColButtons = new Button[] { - showCol0, showCol1, showCol2, showCol3, showCol4, - showCol5, showCol6, showCol7, showCol8 }; - Debug.Assert(NUM_COLUMNS == 9); - - // Extract format strings from column-width button labels. - for (int i = 0; i < NUM_COLUMNS; i++) { - mColButtons[i].Click += ColumnVisibilityButtonClick; - mColumnFormats[i] = mColButtons[i].Text; - } - - // Map text boxes to PseudoOpName fields. - mPseudoNameMap = new TextBoxPropertyMap[] { - new TextBoxPropertyMap(equDirectiveTextBox, "EquDirective"), - new TextBoxPropertyMap(orgDirectiveTextBox, "OrgDirective"), - new TextBoxPropertyMap(regWidthDirectiveTextBox, "RegWidthDirective"), - new TextBoxPropertyMap(defineData1TextBox, "DefineData1"), - new TextBoxPropertyMap(defineData2TextBox, "DefineData2"), - new TextBoxPropertyMap(defineData3TextBox, "DefineData3"), - new TextBoxPropertyMap(defineData4TextBox, "DefineData4"), - new TextBoxPropertyMap(defineBigData2TextBox, "DefineBigData2"), - new TextBoxPropertyMap(fillTextBox, "Fill"), - new TextBoxPropertyMap(denseTextBox, "Dense"), - new TextBoxPropertyMap(strGenericTextBox, "StrGeneric"), - new TextBoxPropertyMap(strGenericHiTextBox, "StrGenericHi"), - new TextBoxPropertyMap(strReverseTextBox, "StrReverse"), - new TextBoxPropertyMap(strReverseHiTextBox, "StrReverseHi"), - new TextBoxPropertyMap(strLen8TextBox, "StrLen8"), - new TextBoxPropertyMap(strLen8HiTextBox, "StrLen8Hi"), - new TextBoxPropertyMap(strLen16TextBox, "StrLen16"), - new TextBoxPropertyMap(strLen16HiTextBox, "StrLen16Hi"), - new TextBoxPropertyMap(strNullTermTextBox, "StrNullTerm"), - new TextBoxPropertyMap(strNullTermHiTextBox, "StrNullTermHi"), - new TextBoxPropertyMap(strDciTextBox, "StrDci"), - new TextBoxPropertyMap(strDciHiTextBox, "StrDciHi"), - }; - - ConfigureComboBox(asmConfigComboBox); - ConfigureComboBox(displayFmtQuickComboBox); - ConfigureComboBox(pseudoOpQuickComboBox); - - expressionStyleComboBox.DisplayMember = "Name"; - foreach (ExpressionStyleItem esi in sExpStyleItems) { - expressionStyleComboBox.Items.Add(esi); - } - } - - private void ConfigureComboBox(ComboBox cb) { - // Show the Name field. - cb.DisplayMember = "Name"; - - cb.Items.Clear(); - IEnumerator iter = AssemblerInfo.GetInfoEnumerator(); - bool foundMatch = false; - while (iter.MoveNext()) { - AssemblerInfo info = iter.Current; - AsmComboItem item = new AsmComboItem(info); - cb.Items.Add(item); - if (item.AssemblerId == mInitialAsmId) { - cb.SelectedItem = item; - foundMatch = true; - } - } - if (!foundMatch) { - // Need to do this or box will show empty. - cb.SelectedIndex = 0; - } - } - - private void EditAppSettings_Load(object sender, EventArgs e) { - // Column widths. We called SaveCodeListColumnWidths() earlier, so this - // should always be a valid serialized string. - string widthStr = mSettings.GetString(AppSettings.CDLV_COL_WIDTHS, null); - Debug.Assert(!string.IsNullOrEmpty(widthStr)); - ProjectView.CodeListColumnWidths widths = - ProjectView.CodeListColumnWidths.Deserialize(widthStr); - Debug.Assert(widths != null); - for (int i = 0; i < NUM_COLUMNS; i++) { - SetShowHideButton(i, widths.Width[i]); - } - - // Display localized font string. - FontConverter cvt = new FontConverter(); - currentFontDisplayLabel.Text = cvt.ConvertToString(mProjectView.CodeListViewFont); - - // Upper-case formatting. - upperHexCheckBox.Checked = mSettings.GetBool(AppSettings.FMT_UPPER_HEX_DIGITS, false); - upperOpcodeCheckBox.Checked = mSettings.GetBool( - AppSettings.FMT_UPPER_OP_MNEMONIC, false); - upperPseudoOpCheckBox.Checked = mSettings.GetBool( - AppSettings.FMT_UPPER_PSEUDO_OP_MNEMONIC, false); - upperACheckBox.Checked = mSettings.GetBool(AppSettings.FMT_UPPER_OPERAND_A, false); - upperSCheckBox.Checked = mSettings.GetBool(AppSettings.FMT_UPPER_OPERAND_S, false); - upperXYCheckBox.Checked = mSettings.GetBool(AppSettings.FMT_UPPER_OPERAND_XY, false); - - int clipIndex = mSettings.GetEnum(AppSettings.CLIP_LINE_FORMAT, - typeof(ClipLineFormat), 0); - if (clipIndex >= 0 && clipIndex < clipboardFormatComboBox.Items.Count) { - clipboardFormatComboBox.SelectedIndex = clipIndex; - } - - spacesBetweenBytesCheckBox.Checked = - mSettings.GetBool(AppSettings.FMT_SPACES_BETWEEN_BYTES, false); - enableDebugCheckBox.Checked = mSettings.GetBool(AppSettings.DEBUG_MENU_ENABLED, false); - - // Assemblers. - PopulateAsmConfigItems(); - showAsmIdentCheckBox.Checked = - mSettings.GetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false); - disableLabelLocalizationCheckBox.Checked = - mSettings.GetBool(AppSettings.SRCGEN_DISABLE_LABEL_LOCALIZATION, false); - longLabelNewLineCheckBox.Checked = - mSettings.GetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, false); - showCycleCountsCheckBox.Checked = - mSettings.GetBool(AppSettings.SRCGEN_SHOW_CYCLE_COUNTS, false); - - // Pseudo ops. - string opStrCereal = mSettings.GetString(AppSettings.FMT_PSEUDO_OP_NAMES, null); - if (!string.IsNullOrEmpty(opStrCereal)) { - PseudoOp.PseudoOpNames opNames = PseudoOp.PseudoOpNames.Deserialize(opStrCereal); - ImportPseudoOpNames(opNames); - } else { - // no data available, populate with blanks - //PseudoOp.PseudoOpNames opNames = PseudoOp.sDefaultPseudoOpNames; - ImportPseudoOpNames(new PseudoOp.PseudoOpNames()); - } - - PopulateWidthDisamSettings(); - - string exprMode = mSettings.GetString(AppSettings.FMT_EXPRESSION_MODE, string.Empty); - ExpressionMode mode; - if (!Enum.TryParse(exprMode, out mode)) { - mode = ExpressionMode.Common; - } - SetExpressionStyle(mode); - - if (mInitialTab != Tab.Unknown) { - settingsTabControl.SelectTab((int)mInitialTab); - } - - mDirty = false; - UpdateControls(); - } - - /// - /// Updates controls. - /// - private void UpdateControls() { - applyButton.Enabled = mDirty; - } - - /// - /// Sets the dirty flag and updates the controls. - /// - /// New value for dirty flag. - private void SetDirty(bool dirty) { - mDirty = dirty; - UpdateControls(); - } - - private void okButton_Click(object sender, EventArgs e) { - ApplySettings(); - } - - private void applyButton_Click(object sender, EventArgs e) { - ApplySettings(); - } - - private void ApplySettings() { - PseudoOp.PseudoOpNames opNames = ExportPseudoOpNames(); - string pseudoCereal = opNames.Serialize(); - mSettings.SetString(AppSettings.FMT_PSEUDO_OP_NAMES, pseudoCereal); - - mProjectView.SetAppSettings(mSettings); - AsmGen.AssemblerVersionCache.QueryVersions(); - SetDirty(false); - } - - - #region Code View - - /// - /// Updates the text on a show/hide column button. - /// - /// Column index. - /// New width. - private void SetShowHideButton(int index, int width) { - Button button = mColButtons[index]; - string fmt = mColumnFormats[index]; - string show = Properties.Resources.SHOW_COL; - string hide = Properties.Resources.HIDE_COL; - button.Text = string.Format(fmt, (width == 0) ? show : hide); - } - - /// - /// Handler for all show/hide column buttons. - /// - /// Identifies the button that was clicked. - /// Stuff. - private void ColumnVisibilityButtonClick(object sender, EventArgs e) { - int index = -1; - for (int i = 0; i < mColButtons.Length; i++) { - if (sender == mColButtons[i]) { - index = i; - break; - } - } - Debug.Assert(index != -1); - - string widthStr = mSettings.GetString(AppSettings.CDLV_COL_WIDTHS, null); - Debug.Assert(!string.IsNullOrEmpty(widthStr)); - ProjectView.CodeListColumnWidths widths = - ProjectView.CodeListColumnWidths.Deserialize(widthStr); - if (widths.Width[index] == 0) { - // Expand to default width. The default width changes when the font - // changes, so it's best to just reacquire the default width set as needed. - ProjectView.CodeListColumnWidths defaultWidths = - mProjectView.GetDefaultCodeListColumnWidths(); - widths.Width[index] = defaultWidths.Width[index]; - } else { - widths.Width[index] = 0; - } - widthStr = widths.Serialize(); - mSettings.SetString(AppSettings.CDLV_COL_WIDTHS, widthStr); - SetShowHideButton(index, widths.Width[index]); - - SetDirty(true); - } - - private void selectFontButton_Click(object sender, EventArgs e) { - FontDialog dlg = new FontDialog(); - dlg.Font = mProjectView.CodeListViewFont; - dlg.ShowEffects = false; - Debug.WriteLine("Showing font dialog..."); - if (dlg.ShowDialog() != DialogResult.Cancel) { - FontConverter cvt = new FontConverter(); - // Store invariant string, display localized string. - mSettings.SetString(AppSettings.CDLV_FONT, cvt.ConvertToInvariantString(dlg.Font)); - currentFontDisplayLabel.Text = cvt.ConvertToString(dlg.Font); - SetDirty(true); - } - Debug.WriteLine("Font dialog done..."); - dlg.Dispose(); - } - - private void upperHexCheckBox_CheckedChanged(object sender, EventArgs e) { - mSettings.SetBool(AppSettings.FMT_UPPER_HEX_DIGITS, upperHexCheckBox.Checked); - SetDirty(true); - } - private void upperOpcodeCheckBox_CheckedChanged(object sender, EventArgs e) { - mSettings.SetBool(AppSettings.FMT_UPPER_OP_MNEMONIC, upperOpcodeCheckBox.Checked); - SetDirty(true); - } - private void upperPseudoOpCheckBox_CheckedChanged(object sender, EventArgs e) { - mSettings.SetBool(AppSettings.FMT_UPPER_PSEUDO_OP_MNEMONIC, - upperPseudoOpCheckBox.Checked); - SetDirty(true); - } - private void upperACheckBox_CheckedChanged(object sender, EventArgs e) { - mSettings.SetBool(AppSettings.FMT_UPPER_OPERAND_A, upperACheckBox.Checked); - SetDirty(true); - } - private void upperSCheckBox_CheckedChanged(object sender, EventArgs e) { - mSettings.SetBool(AppSettings.FMT_UPPER_OPERAND_S, upperSCheckBox.Checked); - SetDirty(true); - } - private void upperXYCheckBox_CheckedChanged(object sender, EventArgs e) { - mSettings.SetBool(AppSettings.FMT_UPPER_OPERAND_XY, upperXYCheckBox.Checked); - SetDirty(true); - } - private void upperAllLowerButton_Click(object sender, EventArgs e) { - upperHexCheckBox.Checked = - upperOpcodeCheckBox.Checked = - upperPseudoOpCheckBox.Checked = - upperACheckBox.Checked = - upperSCheckBox.Checked = - upperXYCheckBox.Checked = false; - } - private void upperAllUpperButton_Click(object sender, EventArgs e) { - upperHexCheckBox.Checked = - upperOpcodeCheckBox.Checked = - upperPseudoOpCheckBox.Checked = - upperACheckBox.Checked = - upperSCheckBox.Checked = - upperXYCheckBox.Checked = true; - } - - private void clipboardFormatComboBox_SelectedIndexChanged(object sender, EventArgs e) { - mSettings.SetEnum(AppSettings.CLIP_LINE_FORMAT, typeof(ClipLineFormat), - clipboardFormatComboBox.SelectedIndex); - SetDirty(true); - } - - private void spacesBetweenBytesCheckBox_CheckedChanged(object sender, EventArgs e) { - mSettings.SetBool(AppSettings.FMT_SPACES_BETWEEN_BYTES, - spacesBetweenBytesCheckBox.Checked); - SetDirty(true); - } - - private void enableDebugCheckBox_CheckedChanged(object sender, EventArgs e) { - mSettings.SetBool(AppSettings.DEBUG_MENU_ENABLED, enableDebugCheckBox.Checked); - SetDirty(true); - } - - #endregion Code View - - - #region Asm Config - - /// - /// Populates the UI elements from the asm config item in the settings. If that doesn't - /// exist, use the default config. - /// - private void PopulateAsmConfigItems() { - AsmComboItem item = (AsmComboItem) asmConfigComboBox.SelectedItem; - AssemblerInfo.Id asmId = item.AssemblerId; - - AssemblerConfig config = AssemblerConfig.GetConfig(mSettings, asmId); - if (config == null) { - AsmGen.IAssembler asm = AssemblerInfo.GetAssembler(asmId); - config = asm.GetDefaultConfig(); - } - - asmExePathTextBox.Text = config.ExecutablePath; - asmLabelColWidthTextBox.Text = config.ColumnWidths[0].ToString(); - asmOpcodeColWidthTextBox.Text = config.ColumnWidths[1].ToString(); - asmOperandColWidthTextBox.Text = config.ColumnWidths[2].ToString(); - asmCommentColWidthTextBox.Text = config.ColumnWidths[3].ToString(); - } - - private AssemblerConfig GetAsmConfigFromUi() { - const int MIN_WIDTH = 1; - const int MAX_WIDTH = 200; - - int[] widths = new int[4]; - for (int i = 0; i < widths.Length; i++) { - widths[i] = MIN_WIDTH; - } - - int result; - if (int.TryParse(asmLabelColWidthTextBox.Text, out result) && result >= MIN_WIDTH && - result <= MAX_WIDTH) { - widths[0] = result; - } - if (int.TryParse(asmOpcodeColWidthTextBox.Text, out result) && result >= MIN_WIDTH && - result <= MAX_WIDTH) { - widths[1] = result; - } - if (int.TryParse(asmOperandColWidthTextBox.Text, out result) && result >= MIN_WIDTH && - result <= MAX_WIDTH) { - widths[2] = result; - } - if (int.TryParse(asmCommentColWidthTextBox.Text, out result) && result >= MIN_WIDTH && - result <= MAX_WIDTH) { - widths[3] = result; - } - - return new AssemblerConfig(asmExePathTextBox.Text, widths); - } - - private void asmConfigComboBox_SelectedIndexChanged(object sender, EventArgs e) { - // They're switching to a different asm config. Changing the boxes will cause - // the dirty flag to be raised, which isn't right, so we save/restore it. - bool oldDirty = mDirty; - PopulateAsmConfigItems(); - SetDirty(oldDirty); - } - - private void asmExeBrowseButton_Click(object sender, EventArgs e) { - AsmComboItem item = (AsmComboItem)asmConfigComboBox.SelectedItem; - AssemblerInfo.Id asmId = item.AssemblerId; - - // Figure out what we're looking for. For example, cc65 needs "cl65". - AsmGen.IAssembler asm = AssemblerInfo.GetAssembler(asmId); - asm.GetExeIdentifiers(out string humanName, out string exeName); - - // Ask the user to find it. - string pathName = BrowseForExecutable(humanName, exeName); - if (pathName != null) { - asmExePathTextBox.Text = pathName; - AssemblerConfig.SetConfig(mSettings, asmId, GetAsmConfigFromUi()); - SetDirty(true); - } - } - - /// - /// Handles a text-changed event in the executable and column width text boxes. - /// - private void AsmConfig_TextChanged(object sender, EventArgs e) { - AsmComboItem item = (AsmComboItem)asmConfigComboBox.SelectedItem; - AssemblerConfig.SetConfig(mSettings, item.AssemblerId, GetAsmConfigFromUi()); - SetDirty(true); - } - - /// - /// Creates a file dialog to search for a specific executable. - /// - /// Human-readable filter string for UI. - /// Filename of executable. - /// Path of executable, or null if dialog was canceled. - private string BrowseForExecutable(string prefix, string name) { - string pathName = null; - - if (Environment.OSVersion.Platform == PlatformID.Win32NT) { - name += ".exe"; - } - - OpenFileDialog dlg = new OpenFileDialog() { - FileName = name, - Filter = prefix + "|" + name, - RestoreDirectory = true - }; - if (dlg.ShowDialog() != DialogResult.Cancel) { - pathName = dlg.FileName; - } - dlg.Dispose(); - - return pathName; - } - - private void showCycleCountsCheckBox_CheckedChanged(object sender, EventArgs e) { - mSettings.SetBool(AppSettings.SRCGEN_SHOW_CYCLE_COUNTS, - showCycleCountsCheckBox.Checked); - SetDirty(true); - } - - private void longLabelNewLineCheckBox_CheckedChanged(object sender, EventArgs e) { - mSettings.SetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, - longLabelNewLineCheckBox.Checked); - SetDirty(true); - } - - private void showAsmIdentCheckBox_CheckedChanged(object sender, EventArgs e) { - mSettings.SetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, showAsmIdentCheckBox.Checked); - SetDirty(true); - } - - private void disableLabelLocalizationCheckBox_CheckedChanged(object sender, EventArgs e) { - mSettings.SetBool(AppSettings.SRCGEN_DISABLE_LABEL_LOCALIZATION, - disableLabelLocalizationCheckBox.Checked); - SetDirty(true); - } - - #endregion Asm Config - - - #region Display Format - - /// - /// Populates the width disambiguation text boxes. - /// - private void PopulateWidthDisamSettings() { - // Operand width disambiguation. This is a little tricky -- we have to query all - // settings then set all controls, or the field-updated callback may interfere - // with us by changing AppSettings. - string opcSuffixAbs = mSettings.GetString(AppSettings.FMT_OPCODE_SUFFIX_ABS, - string.Empty); - string opcSuffixLong = mSettings.GetString(AppSettings.FMT_OPCODE_SUFFIX_LONG, - string.Empty); - string opPrefixAbs = mSettings.GetString(AppSettings.FMT_OPERAND_PREFIX_ABS, - string.Empty); - string opPrefixLong = mSettings.GetString(AppSettings.FMT_OPERAND_PREFIX_LONG, - string.Empty); - - disambSuffix16TextBox.Text = opcSuffixAbs; - disambSuffix24TextBox.Text = opcSuffixLong; - disambPrefix16TextBox.Text = opPrefixAbs; - disambPrefix24TextBox.Text = opPrefixLong; - } - - /// - /// Sets all of the width disambiguation settings. - /// - private void SetWidthDisamSettings(string opcodeSuffixAbs, string opcodeSuffixLong, - string operandPrefixAbs, string operandPrefixLong) { - mSettings.SetString(AppSettings.FMT_OPCODE_SUFFIX_ABS, opcodeSuffixAbs); - mSettings.SetString(AppSettings.FMT_OPCODE_SUFFIX_LONG, opcodeSuffixLong); - mSettings.SetString(AppSettings.FMT_OPERAND_PREFIX_ABS, operandPrefixAbs); - mSettings.SetString(AppSettings.FMT_OPERAND_PREFIX_LONG, operandPrefixLong); - PopulateWidthDisamSettings(); - } - - // Called when text is typed. - private void WidthDisamControlChanged(object sender, EventArgs e) { - ExportWidthDisamSettings(); - } - - /// - /// Exports the current state of the width controls to the settings object. - /// - private void ExportWidthDisamSettings() { - mSettings.SetString(AppSettings.FMT_OPCODE_SUFFIX_ABS, disambSuffix16TextBox.Text); - mSettings.SetString(AppSettings.FMT_OPCODE_SUFFIX_LONG, disambSuffix24TextBox.Text); - mSettings.SetString(AppSettings.FMT_OPERAND_PREFIX_ABS, disambPrefix16TextBox.Text); - mSettings.SetString(AppSettings.FMT_OPERAND_PREFIX_LONG, disambPrefix24TextBox.Text); - SetDirty(true); - - //Debug.WriteLine("disam: '" + - // mSettings.GetString(AppSettings.FMT_OPCODE_SUFFIX_ABS, string.Empty) + "' '" + - // mSettings.GetString(AppSettings.FMT_OPCODE_SUFFIX_LONG, string.Empty) + "' '" + - // mSettings.GetString(AppSettings.FMT_OPERAND_PREFIX_ABS, string.Empty) + "' '" + - // mSettings.GetString(AppSettings.FMT_OPERAND_PREFIX_LONG, string.Empty) + "'"); - } - - private void SetExpressionStyle(ExpressionMode mode) { - foreach (ExpressionStyleItem esi in expressionStyleComboBox.Items) { - if (esi.ExpMode == mode) { - expressionStyleComboBox.SelectedItem = esi; - return; - } - } - Debug.Assert(false, "Expression mode " + mode + " not found"); - expressionStyleComboBox.SelectedIndex = 0; - } - - private void expressionStyleComboBox_SelectedIndexChanged(object sender, EventArgs e) { - ExpressionStyleItem esi = (ExpressionStyleItem)expressionStyleComboBox.SelectedItem; - mSettings.SetString(AppSettings.FMT_EXPRESSION_MODE, esi.ExpMode.ToString()); - SetDirty(true); - } - - private void displayFmtSetButton_Click(object sender, EventArgs e) { - AsmComboItem item = (AsmComboItem)displayFmtQuickComboBox.SelectedItem; - AssemblerInfo.Id asmId = item.AssemblerId; - AsmGen.IGenerator gen = AssemblerInfo.GetGenerator(asmId); - - PseudoOp.PseudoOpNames opNames; - Asm65.Formatter.FormatConfig formatConfig; - gen.GetDefaultDisplayFormat(out opNames, out formatConfig); - - SetWidthDisamSettings(formatConfig.mForceAbsOpcodeSuffix, - formatConfig.mForceLongOpcodeSuffix, - formatConfig.mForceAbsOperandPrefix, - formatConfig.mForceLongOperandPrefix); - SetExpressionStyle(formatConfig.mExpressionMode); - // dirty flag set by change watchers if one or more fields have changed - } - - private void quickFmtDefaultButton_Click(object sender, EventArgs e) { - SetWidthDisamSettings(null, "l", "a:", "f:"); - SetExpressionStyle(ExpressionMode.Common); - // dirty flag set by change watchers if one or more fields have changed - } - - #endregion Display Format - - - #region Pseudo-Op - - /// - /// Imports values from PseudoOpNames struct into text fields. - /// - private void ImportPseudoOpNames(PseudoOp.PseudoOpNames opNames) { - for (int i = 0; i < mPseudoNameMap.Length; i++) { - string str = (string)mPseudoNameMap[i].PropInfo.GetValue(opNames); - mPseudoNameMap[i].TextBox.Text = (str == null) ? string.Empty : str; - } - } - - /// - /// Exports values from text fields to a PseudoOpNames object. - /// - private PseudoOp.PseudoOpNames ExportPseudoOpNames() { - PseudoOp.PseudoOpNames opNames = new PseudoOp.PseudoOpNames(); - for (int i = 0; i < mPseudoNameMap.Length; i++) { - // NOTE: PseudoOpNames must be a class (not a struct) or this will fail. - // SetValue() would be invoked on a boxed copy that is discarded afterward. - mPseudoNameMap[i].PropInfo.SetValue(opNames, mPseudoNameMap[i].TextBox.Text); - } - return opNames; - } - - // Invoked when text is changed in any pseudo-op text box. - private void PseudoOpTextChanged(object sender, EventArgs e) { - // Just set the dirty flag. The (somewhat expensive) export will happen - // on Apply/OK. - SetDirty(true); - } - - private void quickPseudoDefaultButton_Click(object sender, EventArgs e) { - ImportPseudoOpNames(new PseudoOp.PseudoOpNames()); - } - - private void pseudoOpSetButton_Click(object sender, EventArgs e) { - AsmComboItem item = (AsmComboItem)pseudoOpQuickComboBox.SelectedItem; - AssemblerInfo.Id asmId = item.AssemblerId; - AsmGen.IGenerator gen = AssemblerInfo.GetGenerator(asmId); - - PseudoOp.PseudoOpNames opNames; - Asm65.Formatter.FormatConfig formatConfig; - gen.GetDefaultDisplayFormat(out opNames, out formatConfig); - ImportPseudoOpNames(opNames); - - // dirty flag set by change watchers if one or more fields have changed - } - - #endregion Pseudo-Op - } -} diff --git a/SourceGenWF/AppForms/EditAppSettings.resx b/SourceGenWF/AppForms/EditAppSettings.resx deleted file mode 100644 index 1af7de1..0000000 --- a/SourceGenWF/AppForms/EditAppSettings.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditComment.Designer.cs b/SourceGenWF/AppForms/EditComment.Designer.cs deleted file mode 100644 index 68744eb..0000000 --- a/SourceGenWF/AppForms/EditComment.Designer.cs +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AppForms { - partial class EditComment { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.cancelButton = new System.Windows.Forms.Button(); - this.okButton = new System.Windows.Forms.Button(); - this.instructionLabel = new System.Windows.Forms.Label(); - this.commentTextBox = new System.Windows.Forms.TextBox(); - this.asciiOnlyLabel = new System.Windows.Forms.Label(); - this.maxLengthLabel = new System.Windows.Forms.Label(); - this.numCharsLabel = new System.Windows.Forms.Label(); - this.SuspendLayout(); - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.Location = new System.Drawing.Point(426, 105); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 23); - this.cancelButton.TabIndex = 6; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - // - // okButton - // - this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.okButton.Location = new System.Drawing.Point(345, 105); - this.okButton.Name = "okButton"; - this.okButton.Size = new System.Drawing.Size(75, 23); - this.okButton.TabIndex = 5; - this.okButton.Text = "OK"; - this.okButton.UseVisualStyleBackColor = true; - this.okButton.Click += new System.EventHandler(this.okButton_Click); - // - // instructionLabel - // - this.instructionLabel.AutoSize = true; - this.instructionLabel.Location = new System.Drawing.Point(13, 13); - this.instructionLabel.Name = "instructionLabel"; - this.instructionLabel.Size = new System.Drawing.Size(81, 13); - this.instructionLabel.TabIndex = 0; - this.instructionLabel.Text = "Enter comment:"; - // - // textBox1 - // - this.commentTextBox.Location = new System.Drawing.Point(13, 30); - this.commentTextBox.Name = "textBox1"; - this.commentTextBox.Size = new System.Drawing.Size(488, 20); - this.commentTextBox.TabIndex = 1; - this.commentTextBox.TextChanged += new System.EventHandler(this.commentTextBox_TextChanged); - // - // asciiOnlyLabel - // - this.asciiOnlyLabel.AutoSize = true; - this.asciiOnlyLabel.Location = new System.Drawing.Point(13, 57); - this.asciiOnlyLabel.Name = "asciiOnlyLabel"; - this.asciiOnlyLabel.Size = new System.Drawing.Size(145, 13); - this.asciiOnlyLabel.TabIndex = 2; - this.asciiOnlyLabel.Text = "• ASCII-only is recommended"; - // - // maxLengthLabel - // - this.maxLengthLabel.AutoSize = true; - this.maxLengthLabel.Location = new System.Drawing.Point(13, 74); - this.maxLengthLabel.Name = "maxLengthLabel"; - this.maxLengthLabel.Size = new System.Drawing.Size(281, 13); - this.maxLengthLabel.TabIndex = 3; - this.maxLengthLabel.Text = "• Limit to 52 or fewer characters for nice 80-column output"; - // - // numCharsLabel - // - this.numCharsLabel.Location = new System.Drawing.Point(386, 53); - this.numCharsLabel.Name = "numCharsLabel"; - this.numCharsLabel.Size = new System.Drawing.Size(115, 23); - this.numCharsLabel.TabIndex = 4; - this.numCharsLabel.Text = "{0} characters"; - this.numCharsLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // EditComment - // - this.AcceptButton = this.okButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(513, 140); - this.Controls.Add(this.numCharsLabel); - this.Controls.Add(this.maxLengthLabel); - this.Controls.Add(this.asciiOnlyLabel); - this.Controls.Add(this.commentTextBox); - this.Controls.Add(this.instructionLabel); - this.Controls.Add(this.okButton); - this.Controls.Add(this.cancelButton); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "EditComment"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Edit Comment"; - this.Load += new System.EventHandler(this.EditComment_Load); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Button cancelButton; - private System.Windows.Forms.Button okButton; - private System.Windows.Forms.Label instructionLabel; - private System.Windows.Forms.TextBox commentTextBox; - private System.Windows.Forms.Label asciiOnlyLabel; - private System.Windows.Forms.Label maxLengthLabel; - private System.Windows.Forms.Label numCharsLabel; - } -} \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditComment.cs b/SourceGenWF/AppForms/EditComment.cs deleted file mode 100644 index debd6a8..0000000 --- a/SourceGenWF/AppForms/EditComment.cs +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Diagnostics; -using System.Drawing; -using System.Windows.Forms; - -namespace SourceGenWF.AppForms { - public partial class EditComment : Form { - /// - /// Edited comment string. Will be empty if the comment is to be deleted. - /// - public string Comment { get; private set; } - - private string mNumCharsFormat; - - private Color mDefaultLabelColor; - - private const int RECOMMENDED_MAX_LENGTH = 52; - - - public EditComment(string comment) { - InitializeComponent(); - - // The initial label string is used as the format arg. - mNumCharsFormat = numCharsLabel.Text; - - // Remember the default color. - mDefaultLabelColor = asciiOnlyLabel.ForeColor; - - Debug.Assert(comment != null); - commentTextBox.Text = comment; - } - - private void EditComment_Load(object sender, EventArgs e) { - UpdateLengthLabel(); - } - - private void UpdateLengthLabel() { - numCharsLabel.Text = string.Format(mNumCharsFormat, commentTextBox.Text.Length); - } - - private void commentTextBox_TextChanged(object sender, EventArgs e) { - UpdateLengthLabel(); - - if (!CommonUtil.TextUtil.IsPrintableAscii(commentTextBox.Text)) { - asciiOnlyLabel.ForeColor = Color.Red; - } else { - asciiOnlyLabel.ForeColor = mDefaultLabelColor; - } - if (commentTextBox.Text.Length > RECOMMENDED_MAX_LENGTH) { - maxLengthLabel.ForeColor = Color.Red; - } else { - maxLengthLabel.ForeColor = mDefaultLabelColor; - } - } - - private void okButton_Click(object sender, EventArgs e) { - Comment = commentTextBox.Text; - } - } -} diff --git a/SourceGenWF/AppForms/EditComment.resx b/SourceGenWF/AppForms/EditComment.resx deleted file mode 100644 index 1af7de1..0000000 --- a/SourceGenWF/AppForms/EditComment.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditData.Designer.cs b/SourceGenWF/AppForms/EditData.Designer.cs deleted file mode 100644 index 152cfad..0000000 --- a/SourceGenWF/AppForms/EditData.Designer.cs +++ /dev/null @@ -1,559 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AppForms { - partial class EditData { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.cancelButton = new System.Windows.Forms.Button(); - this.okButton = new System.Windows.Forms.Button(); - this.selectFormatLabel = new System.Windows.Forms.Label(); - this.rawDataSectionLabel = new System.Windows.Forms.Label(); - this.radioSingleBytes = new System.Windows.Forms.RadioButton(); - this.radio16BitBig = new System.Windows.Forms.RadioButton(); - this.radio16BitLittle = new System.Windows.Forms.RadioButton(); - this.radio24BitLittle = new System.Windows.Forms.RadioButton(); - this.radio32BitLittle = new System.Windows.Forms.RadioButton(); - this.radioSimpleDataBinary = new System.Windows.Forms.RadioButton(); - this.radioSimpleDataDecimal = new System.Windows.Forms.RadioButton(); - this.radioSimpleDataHex = new System.Windows.Forms.RadioButton(); - this.radioDenseHex = new System.Windows.Forms.RadioButton(); - this.radioFill = new System.Windows.Forms.RadioButton(); - this.horizontalLine1 = new System.Windows.Forms.Label(); - this.horizontalLine2 = new System.Windows.Forms.Label(); - this.stringSectionLabel = new System.Windows.Forms.Label(); - this.horizontalLine3 = new System.Windows.Forms.Label(); - this.radioStringMixed = new System.Windows.Forms.RadioButton(); - this.radioStringMixedReverse = new System.Windows.Forms.RadioButton(); - this.radioStringNullTerm = new System.Windows.Forms.RadioButton(); - this.radioStringLen8 = new System.Windows.Forms.RadioButton(); - this.radioStringLen16 = new System.Windows.Forms.RadioButton(); - this.radioStringDci = new System.Windows.Forms.RadioButton(); - this.symbolEntryTextBox = new System.Windows.Forms.TextBox(); - this.symbolPartPanel = new System.Windows.Forms.Panel(); - this.radioSymbolPartBank = new System.Windows.Forms.RadioButton(); - this.radioSymbolPartHigh = new System.Windows.Forms.RadioButton(); - this.radioSymbolPartLow = new System.Windows.Forms.RadioButton(); - this.radioSimpleDataAscii = new System.Windows.Forms.RadioButton(); - this.radioDefaultFormat = new System.Windows.Forms.RadioButton(); - this.simpleDisplayAsGroupBox = new System.Windows.Forms.GroupBox(); - this.radioSimpleDataAddress = new System.Windows.Forms.RadioButton(); - this.radioSimpleDataSymbolic = new System.Windows.Forms.RadioButton(); - this.label1 = new System.Windows.Forms.Label(); - this.symbolPartPanel.SuspendLayout(); - this.simpleDisplayAsGroupBox.SuspendLayout(); - this.SuspendLayout(); - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.Location = new System.Drawing.Point(438, 461); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 23); - this.cancelButton.TabIndex = 23; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - // - // okButton - // - this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.okButton.Location = new System.Drawing.Point(357, 461); - this.okButton.Name = "okButton"; - this.okButton.Size = new System.Drawing.Size(75, 23); - this.okButton.TabIndex = 22; - this.okButton.Text = "OK"; - this.okButton.UseVisualStyleBackColor = true; - this.okButton.Click += new System.EventHandler(this.okButton_Click); - // - // selectFormatLabel - // - this.selectFormatLabel.AutoSize = true; - this.selectFormatLabel.Location = new System.Drawing.Point(12, 9); - this.selectFormatLabel.Name = "selectFormatLabel"; - this.selectFormatLabel.Size = new System.Drawing.Size(253, 13); - this.selectFormatLabel.TabIndex = 0; - this.selectFormatLabel.Text = "Select data format ({0} bytes selected in {1} groups):"; - // - // rawDataSectionLabel - // - this.rawDataSectionLabel.AutoSize = true; - this.rawDataSectionLabel.Location = new System.Drawing.Point(12, 63); - this.rawDataSectionLabel.Name = "rawDataSectionLabel"; - this.rawDataSectionLabel.Size = new System.Drawing.Size(64, 13); - this.rawDataSectionLabel.TabIndex = 2; - this.rawDataSectionLabel.Text = "Simple Data"; - // - // radioSingleBytes - // - this.radioSingleBytes.AutoSize = true; - this.radioSingleBytes.Location = new System.Drawing.Point(14, 89); - this.radioSingleBytes.Name = "radioSingleBytes"; - this.radioSingleBytes.Size = new System.Drawing.Size(82, 17); - this.radioSingleBytes.TabIndex = 4; - this.radioSingleBytes.TabStop = true; - this.radioSingleBytes.Text = "Single &bytes"; - this.radioSingleBytes.UseVisualStyleBackColor = true; - this.radioSingleBytes.CheckedChanged += new System.EventHandler(this.MainGroup_CheckedChanged); - // - // radio16BitBig - // - this.radio16BitBig.AutoSize = true; - this.radio16BitBig.Location = new System.Drawing.Point(14, 135); - this.radio16BitBig.Name = "radio16BitBig"; - this.radio16BitBig.Size = new System.Drawing.Size(137, 17); - this.radio16BitBig.TabIndex = 6; - this.radio16BitBig.TabStop = true; - this.radio16BitBig.Text = "16-bit words, big-endian"; - this.radio16BitBig.UseVisualStyleBackColor = true; - this.radio16BitBig.CheckedChanged += new System.EventHandler(this.MainGroup_CheckedChanged); - // - // radio16BitLittle - // - this.radio16BitLittle.AutoSize = true; - this.radio16BitLittle.Location = new System.Drawing.Point(14, 112); - this.radio16BitLittle.Name = "radio16BitLittle"; - this.radio16BitLittle.Size = new System.Drawing.Size(141, 17); - this.radio16BitLittle.TabIndex = 5; - this.radio16BitLittle.TabStop = true; - this.radio16BitLittle.Text = "16-bit words, little-endian"; - this.radio16BitLittle.UseVisualStyleBackColor = true; - this.radio16BitLittle.CheckedChanged += new System.EventHandler(this.MainGroup_CheckedChanged); - // - // radio24BitLittle - // - this.radio24BitLittle.AutoSize = true; - this.radio24BitLittle.Location = new System.Drawing.Point(14, 158); - this.radio24BitLittle.Name = "radio24BitLittle"; - this.radio24BitLittle.Size = new System.Drawing.Size(141, 17); - this.radio24BitLittle.TabIndex = 7; - this.radio24BitLittle.TabStop = true; - this.radio24BitLittle.Text = "24-bit words, little-endian"; - this.radio24BitLittle.UseVisualStyleBackColor = true; - this.radio24BitLittle.CheckedChanged += new System.EventHandler(this.MainGroup_CheckedChanged); - // - // radio32BitLittle - // - this.radio32BitLittle.AutoSize = true; - this.radio32BitLittle.Location = new System.Drawing.Point(14, 181); - this.radio32BitLittle.Name = "radio32BitLittle"; - this.radio32BitLittle.Size = new System.Drawing.Size(141, 17); - this.radio32BitLittle.TabIndex = 8; - this.radio32BitLittle.TabStop = true; - this.radio32BitLittle.Text = "32-bit words, little-endian"; - this.radio32BitLittle.UseVisualStyleBackColor = true; - this.radio32BitLittle.CheckedChanged += new System.EventHandler(this.MainGroup_CheckedChanged); - // - // radioSimpleDataBinary - // - this.radioSimpleDataBinary.AutoSize = true; - this.radioSimpleDataBinary.Location = new System.Drawing.Point(6, 64); - this.radioSimpleDataBinary.Name = "radioSimpleDataBinary"; - this.radioSimpleDataBinary.Size = new System.Drawing.Size(54, 17); - this.radioSimpleDataBinary.TabIndex = 4; - this.radioSimpleDataBinary.TabStop = true; - this.radioSimpleDataBinary.Text = "Binary"; - this.radioSimpleDataBinary.UseVisualStyleBackColor = true; - this.radioSimpleDataBinary.CheckedChanged += new System.EventHandler(this.SimpleDisplay_CheckedChanged); - // - // radioSimpleDataDecimal - // - this.radioSimpleDataDecimal.AutoSize = true; - this.radioSimpleDataDecimal.Location = new System.Drawing.Point(6, 41); - this.radioSimpleDataDecimal.Name = "radioSimpleDataDecimal"; - this.radioSimpleDataDecimal.Size = new System.Drawing.Size(63, 17); - this.radioSimpleDataDecimal.TabIndex = 3; - this.radioSimpleDataDecimal.TabStop = true; - this.radioSimpleDataDecimal.Text = "Decimal"; - this.radioSimpleDataDecimal.UseVisualStyleBackColor = true; - this.radioSimpleDataDecimal.CheckedChanged += new System.EventHandler(this.SimpleDisplay_CheckedChanged); - // - // radioSimpleDataHex - // - this.radioSimpleDataHex.AutoSize = true; - this.radioSimpleDataHex.Location = new System.Drawing.Point(6, 18); - this.radioSimpleDataHex.Name = "radioSimpleDataHex"; - this.radioSimpleDataHex.Size = new System.Drawing.Size(44, 17); - this.radioSimpleDataHex.TabIndex = 2; - this.radioSimpleDataHex.TabStop = true; - this.radioSimpleDataHex.Text = "Hex"; - this.radioSimpleDataHex.UseVisualStyleBackColor = true; - this.radioSimpleDataHex.CheckedChanged += new System.EventHandler(this.SimpleDisplay_CheckedChanged); - // - // radioDenseHex - // - this.radioDenseHex.AutoSize = true; - this.radioDenseHex.Location = new System.Drawing.Point(14, 247); - this.radioDenseHex.Name = "radioDenseHex"; - this.radioDenseHex.Size = new System.Drawing.Size(130, 17); - this.radioDenseHex.TabIndex = 11; - this.radioDenseHex.TabStop = true; - this.radioDenseHex.Text = "Densely-&packed bytes"; - this.radioDenseHex.UseVisualStyleBackColor = true; - this.radioDenseHex.CheckedChanged += new System.EventHandler(this.MainGroup_CheckedChanged); - // - // radioFill - // - this.radioFill.AutoSize = true; - this.radioFill.Location = new System.Drawing.Point(14, 270); - this.radioFill.Name = "radioFill"; - this.radioFill.Size = new System.Drawing.Size(88, 17); - this.radioFill.TabIndex = 12; - this.radioFill.TabStop = true; - this.radioFill.Text = "&Fill with value"; - this.radioFill.UseVisualStyleBackColor = true; - this.radioFill.CheckedChanged += new System.EventHandler(this.MainGroup_CheckedChanged); - // - // horizontalLine1 - // - this.horizontalLine1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; - this.horizontalLine1.Location = new System.Drawing.Point(12, 81); - this.horizontalLine1.Name = "horizontalLine1"; - this.horizontalLine1.Size = new System.Drawing.Size(500, 2); - this.horizontalLine1.TabIndex = 3; - // - // horizontalLine2 - // - this.horizontalLine2.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; - this.horizontalLine2.Location = new System.Drawing.Point(12, 239); - this.horizontalLine2.Name = "horizontalLine2"; - this.horizontalLine2.Size = new System.Drawing.Size(320, 2); - this.horizontalLine2.TabIndex = 10; - // - // stringSectionLabel - // - this.stringSectionLabel.AutoSize = true; - this.stringSectionLabel.Location = new System.Drawing.Point(12, 308); - this.stringSectionLabel.Name = "stringSectionLabel"; - this.stringSectionLabel.Size = new System.Drawing.Size(34, 13); - this.stringSectionLabel.TabIndex = 13; - this.stringSectionLabel.Text = "String"; - // - // horizontalLine3 - // - this.horizontalLine3.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; - this.horizontalLine3.Location = new System.Drawing.Point(12, 326); - this.horizontalLine3.Name = "horizontalLine3"; - this.horizontalLine3.Size = new System.Drawing.Size(320, 2); - this.horizontalLine3.TabIndex = 14; - // - // radioStringMixed - // - this.radioStringMixed.AutoSize = true; - this.radioStringMixed.Location = new System.Drawing.Point(14, 334); - this.radioStringMixed.Name = "radioStringMixed"; - this.radioStringMixed.Size = new System.Drawing.Size(257, 17); - this.radioStringMixed.TabIndex = 15; - this.radioStringMixed.TabStop = true; - this.radioStringMixed.Text = "Mixed ASCII ({0} bytes) and non-ASCII ({1} bytes)"; - this.radioStringMixed.UseVisualStyleBackColor = true; - this.radioStringMixed.CheckedChanged += new System.EventHandler(this.MainGroup_CheckedChanged); - // - // radioStringMixedReverse - // - this.radioStringMixedReverse.AutoSize = true; - this.radioStringMixedReverse.Location = new System.Drawing.Point(14, 357); - this.radioStringMixedReverse.Name = "radioStringMixedReverse"; - this.radioStringMixedReverse.Size = new System.Drawing.Size(275, 17); - this.radioStringMixedReverse.TabIndex = 16; - this.radioStringMixedReverse.TabStop = true; - this.radioStringMixedReverse.Text = "Reversed ASCII ({0} bytes) and non-ASCII ({1} bytes)"; - this.radioStringMixedReverse.UseVisualStyleBackColor = true; - this.radioStringMixedReverse.CheckedChanged += new System.EventHandler(this.MainGroup_CheckedChanged); - // - // radioStringNullTerm - // - this.radioStringNullTerm.AutoSize = true; - this.radioStringNullTerm.Location = new System.Drawing.Point(14, 381); - this.radioStringNullTerm.Name = "radioStringNullTerm"; - this.radioStringNullTerm.Size = new System.Drawing.Size(151, 17); - this.radioStringNullTerm.TabIndex = 17; - this.radioStringNullTerm.TabStop = true; - this.radioStringNullTerm.Text = "Null-terminated strings ({0})"; - this.radioStringNullTerm.UseVisualStyleBackColor = true; - this.radioStringNullTerm.CheckedChanged += new System.EventHandler(this.MainGroup_CheckedChanged); - // - // radioStringLen8 - // - this.radioStringLen8.AutoSize = true; - this.radioStringLen8.Location = new System.Drawing.Point(14, 405); - this.radioStringLen8.Name = "radioStringLen8"; - this.radioStringLen8.Size = new System.Drawing.Size(197, 17); - this.radioStringLen8.TabIndex = 18; - this.radioStringLen8.TabStop = true; - this.radioStringLen8.Text = "Strings prefixed with 8-bit length ({0})"; - this.radioStringLen8.UseVisualStyleBackColor = true; - this.radioStringLen8.CheckedChanged += new System.EventHandler(this.MainGroup_CheckedChanged); - // - // radioStringLen16 - // - this.radioStringLen16.AutoSize = true; - this.radioStringLen16.Location = new System.Drawing.Point(14, 429); - this.radioStringLen16.Name = "radioStringLen16"; - this.radioStringLen16.Size = new System.Drawing.Size(203, 17); - this.radioStringLen16.TabIndex = 19; - this.radioStringLen16.TabStop = true; - this.radioStringLen16.Text = "Strings prefixed with 16-bit length ({0})"; - this.radioStringLen16.UseVisualStyleBackColor = true; - this.radioStringLen16.CheckedChanged += new System.EventHandler(this.MainGroup_CheckedChanged); - // - // radioStringDci - // - this.radioStringDci.AutoSize = true; - this.radioStringDci.Location = new System.Drawing.Point(14, 453); - this.radioStringDci.Name = "radioStringDci"; - this.radioStringDci.Size = new System.Drawing.Size(170, 17); - this.radioStringDci.TabIndex = 20; - this.radioStringDci.TabStop = true; - this.radioStringDci.Text = "Dextral character inverted ({0})"; - this.radioStringDci.UseVisualStyleBackColor = true; - this.radioStringDci.CheckedChanged += new System.EventHandler(this.MainGroup_CheckedChanged); - // - // symbolEntryTextBox - // - this.symbolEntryTextBox.Location = new System.Drawing.Point(108, 62); - this.symbolEntryTextBox.Name = "symbolEntryTextBox"; - this.symbolEntryTextBox.Size = new System.Drawing.Size(200, 20); - this.symbolEntryTextBox.TabIndex = 1; - this.symbolEntryTextBox.TextChanged += new System.EventHandler(this.symbolEntryTextBox_TextChanged); - // - // symbolPartPanel - // - this.symbolPartPanel.Controls.Add(this.radioSymbolPartBank); - this.symbolPartPanel.Controls.Add(this.radioSymbolPartHigh); - this.symbolPartPanel.Controls.Add(this.radioSymbolPartLow); - this.symbolPartPanel.Location = new System.Drawing.Point(108, 86); - this.symbolPartPanel.Name = "symbolPartPanel"; - this.symbolPartPanel.Size = new System.Drawing.Size(200, 20); - this.symbolPartPanel.TabIndex = 27; - // - // radioSymbolPartBank - // - this.radioSymbolPartBank.AutoSize = true; - this.radioSymbolPartBank.Location = new System.Drawing.Point(103, 1); - this.radioSymbolPartBank.Name = "radioSymbolPartBank"; - this.radioSymbolPartBank.Size = new System.Drawing.Size(50, 17); - this.radioSymbolPartBank.TabIndex = 2; - this.radioSymbolPartBank.TabStop = true; - this.radioSymbolPartBank.Text = "Bank"; - this.radioSymbolPartBank.UseVisualStyleBackColor = true; - this.radioSymbolPartBank.CheckedChanged += new System.EventHandler(this.PartGroup_CheckedChanged); - // - // radioSymbolPartHigh - // - this.radioSymbolPartHigh.AutoSize = true; - this.radioSymbolPartHigh.Location = new System.Drawing.Point(52, 1); - this.radioSymbolPartHigh.Name = "radioSymbolPartHigh"; - this.radioSymbolPartHigh.Size = new System.Drawing.Size(47, 17); - this.radioSymbolPartHigh.TabIndex = 1; - this.radioSymbolPartHigh.TabStop = true; - this.radioSymbolPartHigh.Text = "High"; - this.radioSymbolPartHigh.UseVisualStyleBackColor = true; - this.radioSymbolPartHigh.CheckedChanged += new System.EventHandler(this.PartGroup_CheckedChanged); - // - // radioSymbolPartLow - // - this.radioSymbolPartLow.AutoSize = true; - this.radioSymbolPartLow.Location = new System.Drawing.Point(4, 1); - this.radioSymbolPartLow.Name = "radioSymbolPartLow"; - this.radioSymbolPartLow.Size = new System.Drawing.Size(45, 17); - this.radioSymbolPartLow.TabIndex = 0; - this.radioSymbolPartLow.TabStop = true; - this.radioSymbolPartLow.Text = "Low"; - this.radioSymbolPartLow.UseVisualStyleBackColor = true; - this.radioSymbolPartLow.CheckedChanged += new System.EventHandler(this.PartGroup_CheckedChanged); - // - // radioSimpleDataAscii - // - this.radioSimpleDataAscii.AutoSize = true; - this.radioSimpleDataAscii.Location = new System.Drawing.Point(6, 87); - this.radioSimpleDataAscii.Name = "radioSimpleDataAscii"; - this.radioSimpleDataAscii.Size = new System.Drawing.Size(52, 17); - this.radioSimpleDataAscii.TabIndex = 5; - this.radioSimpleDataAscii.TabStop = true; - this.radioSimpleDataAscii.Text = "ASCII"; - this.radioSimpleDataAscii.UseVisualStyleBackColor = true; - this.radioSimpleDataAscii.CheckedChanged += new System.EventHandler(this.SimpleDisplay_CheckedChanged); - // - // radioDefaultFormat - // - this.radioDefaultFormat.AutoSize = true; - this.radioDefaultFormat.Location = new System.Drawing.Point(14, 30); - this.radioDefaultFormat.Name = "radioDefaultFormat"; - this.radioDefaultFormat.Size = new System.Drawing.Size(59, 17); - this.radioDefaultFormat.TabIndex = 1; - this.radioDefaultFormat.TabStop = true; - this.radioDefaultFormat.Text = "&Default"; - this.radioDefaultFormat.UseVisualStyleBackColor = true; - this.radioDefaultFormat.CheckedChanged += new System.EventHandler(this.MainGroup_CheckedChanged); - // - // simpleDisplayAsGroupBox - // - this.simpleDisplayAsGroupBox.Controls.Add(this.radioSimpleDataAddress); - this.simpleDisplayAsGroupBox.Controls.Add(this.radioSimpleDataSymbolic); - this.simpleDisplayAsGroupBox.Controls.Add(this.radioSimpleDataAscii); - this.simpleDisplayAsGroupBox.Controls.Add(this.radioSimpleDataHex); - this.simpleDisplayAsGroupBox.Controls.Add(this.symbolPartPanel); - this.simpleDisplayAsGroupBox.Controls.Add(this.radioSimpleDataBinary); - this.simpleDisplayAsGroupBox.Controls.Add(this.symbolEntryTextBox); - this.simpleDisplayAsGroupBox.Controls.Add(this.radioSimpleDataDecimal); - this.simpleDisplayAsGroupBox.Location = new System.Drawing.Point(190, 84); - this.simpleDisplayAsGroupBox.Name = "simpleDisplayAsGroupBox"; - this.simpleDisplayAsGroupBox.Size = new System.Drawing.Size(320, 114); - this.simpleDisplayAsGroupBox.TabIndex = 24; - this.simpleDisplayAsGroupBox.TabStop = false; - this.simpleDisplayAsGroupBox.Text = "Display As..."; - // - // radioSimpleDataAddress - // - this.radioSimpleDataAddress.AutoSize = true; - this.radioSimpleDataAddress.Location = new System.Drawing.Point(89, 18); - this.radioSimpleDataAddress.Name = "radioSimpleDataAddress"; - this.radioSimpleDataAddress.Size = new System.Drawing.Size(63, 17); - this.radioSimpleDataAddress.TabIndex = 6; - this.radioSimpleDataAddress.TabStop = true; - this.radioSimpleDataAddress.Text = "&Address"; - this.radioSimpleDataAddress.UseVisualStyleBackColor = true; - // - // radioSimpleDataSymbolic - // - this.radioSimpleDataSymbolic.AutoSize = true; - this.radioSimpleDataSymbolic.Location = new System.Drawing.Point(89, 41); - this.radioSimpleDataSymbolic.Name = "radioSimpleDataSymbolic"; - this.radioSimpleDataSymbolic.Size = new System.Drawing.Size(115, 17); - this.radioSimpleDataSymbolic.TabIndex = 7; - this.radioSimpleDataSymbolic.TabStop = true; - this.radioSimpleDataSymbolic.Text = "&Symbolic reference"; - this.radioSimpleDataSymbolic.UseVisualStyleBackColor = true; - this.radioSimpleDataSymbolic.CheckedChanged += new System.EventHandler(this.SimpleDisplay_CheckedChanged); - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(12, 221); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(54, 13); - this.label1.TabIndex = 9; - this.label1.Text = "Bulk Data"; - // - // EditData - // - this.AcceptButton = this.okButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(525, 496); - this.Controls.Add(this.label1); - this.Controls.Add(this.simpleDisplayAsGroupBox); - this.Controls.Add(this.radioDefaultFormat); - this.Controls.Add(this.radioStringDci); - this.Controls.Add(this.radioStringLen16); - this.Controls.Add(this.radioStringLen8); - this.Controls.Add(this.radioStringNullTerm); - this.Controls.Add(this.radioStringMixedReverse); - this.Controls.Add(this.radioStringMixed); - this.Controls.Add(this.stringSectionLabel); - this.Controls.Add(this.horizontalLine1); - this.Controls.Add(this.horizontalLine2); - this.Controls.Add(this.horizontalLine3); - this.Controls.Add(this.radioFill); - this.Controls.Add(this.radioDenseHex); - this.Controls.Add(this.radio32BitLittle); - this.Controls.Add(this.radio24BitLittle); - this.Controls.Add(this.radio16BitLittle); - this.Controls.Add(this.radio16BitBig); - this.Controls.Add(this.radioSingleBytes); - this.Controls.Add(this.rawDataSectionLabel); - this.Controls.Add(this.selectFormatLabel); - this.Controls.Add(this.okButton); - this.Controls.Add(this.cancelButton); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "EditData"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Edit Data Format"; - this.Load += new System.EventHandler(this.EditData_Load); - this.Shown += new System.EventHandler(this.EditData_Shown); - this.symbolPartPanel.ResumeLayout(false); - this.symbolPartPanel.PerformLayout(); - this.simpleDisplayAsGroupBox.ResumeLayout(false); - this.simpleDisplayAsGroupBox.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Button cancelButton; - private System.Windows.Forms.Button okButton; - private System.Windows.Forms.Label selectFormatLabel; - private System.Windows.Forms.Label rawDataSectionLabel; - private System.Windows.Forms.RadioButton radioSingleBytes; - private System.Windows.Forms.RadioButton radio16BitBig; - private System.Windows.Forms.RadioButton radio16BitLittle; - private System.Windows.Forms.RadioButton radio24BitLittle; - private System.Windows.Forms.RadioButton radio32BitLittle; - private System.Windows.Forms.RadioButton radioSimpleDataBinary; - private System.Windows.Forms.RadioButton radioSimpleDataDecimal; - private System.Windows.Forms.RadioButton radioSimpleDataHex; - private System.Windows.Forms.RadioButton radioDenseHex; - private System.Windows.Forms.RadioButton radioFill; - private System.Windows.Forms.Label horizontalLine1; - private System.Windows.Forms.Label horizontalLine2; - private System.Windows.Forms.Label stringSectionLabel; - private System.Windows.Forms.Label horizontalLine3; - private System.Windows.Forms.RadioButton radioStringMixed; - private System.Windows.Forms.RadioButton radioStringMixedReverse; - private System.Windows.Forms.RadioButton radioStringNullTerm; - private System.Windows.Forms.RadioButton radioStringLen8; - private System.Windows.Forms.RadioButton radioStringLen16; - private System.Windows.Forms.RadioButton radioStringDci; - private System.Windows.Forms.TextBox symbolEntryTextBox; - private System.Windows.Forms.Panel symbolPartPanel; - private System.Windows.Forms.RadioButton radioSymbolPartBank; - private System.Windows.Forms.RadioButton radioSymbolPartHigh; - private System.Windows.Forms.RadioButton radioSymbolPartLow; - private System.Windows.Forms.RadioButton radioSimpleDataAscii; - private System.Windows.Forms.RadioButton radioDefaultFormat; - private System.Windows.Forms.GroupBox simpleDisplayAsGroupBox; - private System.Windows.Forms.RadioButton radioSimpleDataSymbolic; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.RadioButton radioSimpleDataAddress; - } -} \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditData.cs b/SourceGenWF/AppForms/EditData.cs deleted file mode 100644 index 07224e1..0000000 --- a/SourceGenWF/AppForms/EditData.cs +++ /dev/null @@ -1,953 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Windows.Forms; - -using CommonUtil; - -namespace SourceGenWF.AppForms { - public partial class EditData : Form { - /// - /// Result set that describes the formatting to perform. Not all regions will have - /// the same format, e.g. the "mixed ASCII" mode will alternate strings and bytes - /// (rather than a dedicated "mixed ASCII" format type). - /// - public SortedList Results { get; private set; } - - /// - /// Selected offsets. An otherwise contiguous range of offsets can be broken up - /// by user-specified labels and address discontinuities, so this needs to be - /// processed by range. - /// - public TypedRangeSet Selection { private get; set; } - - /// - /// FormatDescriptor from the first offset. May be null if the offset doesn't - /// have a format descriptor specified. This will be used to configure the - /// dialog controls if the format is suited to the selection. The goal is to - /// make single-item editing work as expected. - /// - public FormatDescriptor FirstFormatDescriptor { private get; set; } - - /// - /// Raw file data. - /// - private byte[] mFileData; - - /// - /// Symbol table to use when resolving symbolic values. - /// - private SymbolTable mSymbolTable; - - /// - /// Formatter to use when displaying addresses and hex values. - /// - private Asm65.Formatter mFormatter; - - /// - /// Set this during initial control configuration, so we know to ignore the CheckedChanged - /// events. - /// - private bool mIsInitialSetup; - - /// - /// Set to true if, during the initial setup, the format defined by FirstFormatDescriptor - /// was unavailable. - /// - private bool mPreferredFormatUnavailable; - - - public EditData(byte[] fileData, SymbolTable symbolTable, Asm65.Formatter formatter) { - InitializeComponent(); - - mFileData = fileData; - mSymbolTable = symbolTable; - mFormatter = formatter; - - //Results = new List(); - } - - private void EditData_Load(object sender, EventArgs e) { - DateTime startWhen = DateTime.Now; - - mIsInitialSetup = true; - - // Determine which of the various options is suitable for the selected offsets. - // Disable any radio buttons that won't work. - AnalyzeRanges(); - - // Configure the dialog from the FormatDescriptor, if one is available. - Debug.WriteLine("First FD: " + FirstFormatDescriptor); - SetControlsFromDescriptor(FirstFormatDescriptor); - - if (mPreferredFormatUnavailable) { - // This can happen when e.g. a bunch of stuff is formatted as null-terminated - // strings. We don't recognize a lone zero as a string, but we allow it if - // it's next to a bunch of others. If you come back later and try to format - // just that one byte, you end up here. - // TODO(maybe): make it more obvious what's going on? - Debug.WriteLine("NOTE: preferred format unavailable"); - } - - mIsInitialSetup = false; - UpdateControls(); - - Debug.WriteLine("EditData dialog load time: " + - (DateTime.Now - startWhen).TotalMilliseconds + " ms"); - } - - private void EditData_Shown(object sender, EventArgs e) { - // Start with the focus in the text box if the initial format allows for a - // symbolic reference. This way they can start typing immediately. - if (simpleDisplayAsGroupBox.Enabled) { - symbolEntryTextBox.Focus(); - } - } - - /// - /// Handles CheckedChanged event for all radio buttons in main group. This will - /// fire twice when a radio button is clicked (once to un-check the old, once - /// to check the new). - /// - private void MainGroup_CheckedChanged(object sender, EventArgs e) { - // Enable/disable the style group and the low/high/bank radio group. - // Update preview window. - UpdateControls(); - } - - /// - /// Handles CheckedChanged event for radio buttons in the simple-data "display as" - /// group box. - /// - private void SimpleDisplay_CheckedChanged(object sender, EventArgs e) { - // Enable/disable the low/high/bank radio group. - UpdateControls(); - } - - /// - /// Handles CheckedChanged event for all radio buttons in symbol-part group. - /// - private void PartGroup_CheckedChanged(object sender, EventArgs e) { - // not currently using a preview window; could add one for single items? - } - - private void symbolEntryTextBox_TextChanged(object sender, EventArgs e) { - // Make sure Symbol is checked if they're typing text in. - Debug.Assert(radioSimpleDataSymbolic.Enabled); - radioSimpleDataSymbolic.Checked = true; - // Update OK button based on symbol validity. - UpdateControls(); - } - - private void okButton_Click(object sender, EventArgs e) { - CreateDescriptorListFromControls(); - FormatDescriptor.DebugDumpSortedList(Results); - } - - /// - /// Updates all of the controls to reflect the current internal state. - /// - private void UpdateControls() { - if (mIsInitialSetup) { - return; - } - - // Configure the simple data "display as" style box. - bool wantStyle = false; - int simpleWidth = -1; - bool isBigEndian = false; - if (radioSingleBytes.Checked) { - wantStyle = true; - simpleWidth = 1; - } else if (radio16BitLittle.Checked) { - wantStyle = true; - simpleWidth = 2; - } else if (radio16BitBig.Checked) { - wantStyle = true; - simpleWidth = 2; - isBigEndian = true; - } else if (radio24BitLittle.Checked) { - wantStyle = true; - simpleWidth = 3; - } else if (radio32BitLittle.Checked) { - wantStyle = true; - simpleWidth = 4; - } - bool focusOnSymbol = !simpleDisplayAsGroupBox.Enabled && wantStyle; - simpleDisplayAsGroupBox.Enabled = wantStyle; - if (wantStyle) { - // TODO(soon): compute on first need and save results; this is getting called - // 2x as radio buttons are hit, and might be slow on large data sets - radioSimpleDataAscii.Enabled = IsRawAsciiCompatible(simpleWidth, isBigEndian); - } - - // Enable the symbolic reference entry box if the "display as" group is enabled. - // That way instead of "click 16-bit", "click symbol", "enter symbol", the user - // can skip the second step. - symbolEntryTextBox.Enabled = simpleDisplayAsGroupBox.Enabled; - symbolPartPanel.Enabled = radioSimpleDataSymbolic.Checked; - - // If we just enabled the group box, set the focus on the symbol entry box. This - // removes another click from the steps, though it's a bit aggressive if you're - // trying to arrow your way through the items. - if (focusOnSymbol) { - symbolEntryTextBox.Focus(); - } - - bool isOk = true; - if (radioSimpleDataSymbolic.Checked) { - // Just check for correct format. References to non-existent labels are allowed. - isOk = Asm65.Label.ValidateLabel(symbolEntryTextBox.Text); - - // Actually, let's discourage references to auto-labels. - if (isOk && mSymbolTable.TryGetValue(symbolEntryTextBox.Text, out Symbol sym)) { - isOk = sym.SymbolSource != Symbol.Source.Auto; - } - } - okButton.Enabled = isOk; - } - - /// - /// Analyzes the selection to see which data formatting options are suitable. - /// Disables radio buttons and updates labels. - /// - /// Call this once, when the dialog is first loaded. - /// - private void AnalyzeRanges() { - Debug.Assert(Selection.Count != 0); - - string fmt = (Selection.RangeCount == 1) ? - Properties.Resources.FMT_FORMAT_SINGLE_GROUP : - Properties.Resources.FMT_FORMAT_MULTIPLE_GROUPS; - selectFormatLabel.Text = string.Format(fmt, Selection.Count, Selection.RangeCount); - - IEnumerator iter = Selection.RangeListIterator; - - int mixedAsciiOkCount = 0; - int mixedAsciiNotCount = 0; - int nullTermStringCount = 0; - int len8StringCount = 0; - int len16StringCount = 0; - int dciStringCount = 0; - //int revDciStringCount = 0; - - // For each range, check to see if the data within qualifies for the various - // options. If any of them fail to meet the criteria, the option is disabled - // for all ranges. - while (iter.MoveNext()) { - TypedRangeSet.TypedRange rng = iter.Current; - Debug.WriteLine("Testing [" + rng.Low + ", " + rng.High + "]"); - - // Start with the easy ones. Single-byte and dense are always enabled. - - int count = rng.High - rng.Low + 1; - Debug.Assert(count > 0); - if ((count & 0x01) != 0) { - // not divisible by 2, disallow 16-bit entries - radio16BitLittle.Enabled = false; - radio16BitBig.Enabled = false; - } - if ((count & 0x03) != 0) { - // not divisible by 4, disallow 32-bit entries - radio32BitLittle.Enabled = false; - } - if ((count / 3) * 3 != count) { - // not divisible by 3, disallow 24-bit entries - radio24BitLittle.Enabled = false; - } - - - // Check for run of bytes (2 or more of the same thing). Remember that - // we check this one region at a time, and each region could have different - // bytes, but so long as the bytes are all the same within a region we're good. - if (radioFill.Enabled && count > 1 && - DataAnalysis.RecognizeRun(mFileData, rng.Low, rng.High) == count) { - // LGTM - } else { - radioFill.Enabled = false; - } - - // See if there's enough string data to make it worthwhile. We use an - // arbitrary threshold of 2+ ASCII characters, and require twice as many - // ASCII as non-ASCII. We arbitrarily require the strings to be either - // high or low ASCII, and treat the other as non-ASCII. (We could relax - // this -- we generate separate items for each string and non-ASCII chunk -- - // but I'm trying to hide the option when the buffer doesn't really seem - // to be holding strings. Could replace with some sort of minimum string - // length requirement?) - if (radioStringMixed.Enabled) { - int asciiCount; - DataAnalysis.CountAsciiBytes(mFileData, rng.Low, rng.High, - out int lowAscii, out int highAscii, out int nonAscii); - if (highAscii > lowAscii) { - asciiCount = highAscii; - nonAscii += lowAscii; - } else { - asciiCount = lowAscii; - nonAscii += highAscii; - } - - if (asciiCount >= 2 && asciiCount >= nonAscii * 2) { - // Looks good - mixedAsciiOkCount += asciiCount; - mixedAsciiNotCount += nonAscii; - } else { - // Fail - radioStringMixed.Enabled = false; - radioStringMixedReverse.Enabled = false; - mixedAsciiOkCount = mixedAsciiNotCount = -1; - } - } - - // Check for null-terminated strings. Zero-length strings are allowed, but - // not counted -- we want to have some actual character data. Individual - // strings need to be entirely high-ASCII or low-ASCII, but not all strings - // in a region have to be the same. - if (radioStringNullTerm.Enabled) { - int strCount = DataAnalysis.RecognizeNullTerminatedStrings(mFileData, - rng.Low, rng.High); - if (strCount > 0) { - nullTermStringCount += strCount; - } else { - radioStringNullTerm.Enabled = false; - nullTermStringCount = -1; - } - } - - // Check for strings prefixed with an 8-bit length. - if (radioStringLen8.Enabled) { - int strCount = DataAnalysis.RecognizeLen8Strings(mFileData, rng.Low, rng.High); - if (strCount > 0) { - len8StringCount += strCount; - } else { - radioStringLen8.Enabled = false; - len8StringCount = -1; - } - } - - // Check for strings prefixed with a 16-bit length. - if (radioStringLen16.Enabled) { - int strCount = DataAnalysis.RecognizeLen16Strings(mFileData, rng.Low, rng.High); - if (strCount > 0) { - len16StringCount += strCount; - } else { - radioStringLen16.Enabled = false; - len16StringCount = -1; - } - } - - // Check for DCI strings. All strings within a single range must have the - // same "polarity", e.g. low ASCII terminated by high ASCII. - if (radioStringDci.Enabled) { - int strCount = DataAnalysis.RecognizeDciStrings(mFileData, rng.Low, rng.High); - if (strCount > 0) { - dciStringCount += strCount; - } else { - radioStringDci.Enabled = false; - dciStringCount = -1; - } - } - - //// Check for reverse DCI strings. All strings within a single range must have the - //// same "polarity", e.g. low ASCII terminated by high ASCII. - //if (radioStringDciReverse.Enabled) { - // int strCount = DataAnalysis.RecognizeReverseDciStrings(mFileData, - // rng.Low, rng.High); - // if (strCount > 0) { - // revDciStringCount += strCount; - // } else { - // radioStringDciReverse.Enabled = false; - // revDciStringCount = -1; - // } - //} - } - - // Update the dialog with string and character counts, summed across all regions. - - if (mixedAsciiOkCount > 0) { - Debug.Assert(radioStringMixed.Enabled); - radioStringMixed.Text = string.Format(radioStringMixed.Text, - mixedAsciiOkCount, mixedAsciiNotCount); - radioStringMixedReverse.Text = string.Format(radioStringMixedReverse.Text, - mixedAsciiOkCount, mixedAsciiNotCount); - } else { - Debug.Assert(!radioStringMixed.Enabled); - radioStringMixed.Text = string.Format(radioStringMixed.Text, "xx", "xx"); - radioStringMixedReverse.Text = string.Format(radioStringMixedReverse.Text, - "xx", "xx"); - } - - if (nullTermStringCount > 0) { - Debug.Assert(radioStringNullTerm.Enabled); - radioStringNullTerm.Text = string.Format(radioStringNullTerm.Text, nullTermStringCount); - } else { - Debug.Assert(!radioStringNullTerm.Enabled); - radioStringNullTerm.Text = string.Format(radioStringNullTerm.Text, "xx"); - } - - if (len8StringCount > 0) { - Debug.Assert(radioStringLen8.Enabled); - radioStringLen8.Text = string.Format(radioStringLen8.Text, len8StringCount); - } else { - Debug.Assert(!radioStringLen8.Enabled); - radioStringLen8.Text = string.Format(radioStringLen8.Text, "xx"); - } - - if (len16StringCount > 0) { - Debug.Assert(radioStringLen16.Enabled); - radioStringLen16.Text = string.Format(radioStringLen16.Text, len16StringCount); - } else { - Debug.Assert(!radioStringLen16.Enabled); - radioStringLen16.Text = string.Format(radioStringLen16.Text, "xx"); - } - - if (dciStringCount > 0) { - Debug.Assert(radioStringDci.Enabled); - radioStringDci.Text = string.Format(radioStringDci.Text, dciStringCount); - } else { - Debug.Assert(!radioStringDci.Enabled); - radioStringDci.Text = string.Format(radioStringDci.Text, "xx"); - } - - //if (revDciStringCount > 0) { - // Debug.Assert(radioStringDciReverse.Enabled); - // radioStringDciReverse.Text = - // string.Format(radioStringDciReverse.Text, revDciStringCount); - //} else { - // Debug.Assert(!radioStringDciReverse.Enabled); - // radioStringDciReverse.Text = string.Format(radioStringDciReverse.Text, "xx"); - //} - } - - /// - /// Determines whether the data in the buffer can be represented as ASCII values. - /// Using ".DD1 'A'" for 0x41 is obvious, but we also allow ".DD2 'A'" for - /// 0x41 0x00. 16-bit character constants are more likely as intermediate - /// operands, but could be found in data areas. - /// - /// High and low ASCII are allowed, and may be freely mixed. - /// - /// Testing explicitly is probably excessive, and possibly counter-productive if - /// the user is trying to flag an area that is a mix of ASCII and non-ASCII and - /// just wants hex for the rest, but we'll give it a try. - /// - /// Number of bytes per character. - /// Word endian-ness. - /// True if data in all regions can be represented as high or low ASCII. - private bool IsRawAsciiCompatible(int wordWidth, bool isBigEndian) { - IEnumerator iter = Selection.RangeListIterator; - while (iter.MoveNext()) { - TypedRangeSet.TypedRange rng = iter.Current; - Debug.Assert(((rng.High - rng.Low + 1) / wordWidth) * wordWidth == - rng.High - rng.Low + 1); - for (int i = rng.Low; i <= rng.High; i += wordWidth) { - int val = RawData.GetWord(mFileData, rng.Low, wordWidth, isBigEndian); - if (val < 0x20 || (val >= 0x7f && val < 0xa0) || val >= 0xff) { - // bad value, fail - return false; - } - } - } - return true; - } - - /// - /// Configures the dialog controls based on the provided format descriptor. If - /// the desired options are unavailable, a suitable default is selected instead. - /// - /// FormatDescriptor to use. - private void SetControlsFromDescriptor(FormatDescriptor dfd) { - Debug.Assert(mIsInitialSetup); - radioSimpleDataHex.Checked = true; - radioSymbolPartLow.Checked = true; - - if (dfd == null) { - radioDefaultFormat.Checked = true; - return; - } - - RadioButton preferredFormat; - - switch (dfd.FormatType) { - case FormatDescriptor.Type.NumericLE: - case FormatDescriptor.Type.NumericBE: - switch (dfd.Length) { - case 1: - preferredFormat = radioSingleBytes; - break; - case 2: - preferredFormat = - (dfd.FormatType == FormatDescriptor.Type.NumericLE ? - radio16BitLittle : radio16BitBig); - break; - case 3: - preferredFormat = radio24BitLittle; - break; - case 4: - preferredFormat = radio32BitLittle; - break; - default: - Debug.Assert(false); - preferredFormat = radioDefaultFormat; - break; - } - if (preferredFormat.Enabled) { - switch (dfd.FormatSubType) { - case FormatDescriptor.SubType.None: - case FormatDescriptor.SubType.Hex: - radioSimpleDataHex.Checked = true; - break; - case FormatDescriptor.SubType.Decimal: - radioSimpleDataDecimal.Checked = true; - break; - case FormatDescriptor.SubType.Binary: - radioSimpleDataBinary.Checked = true; - break; - case FormatDescriptor.SubType.Ascii: - radioSimpleDataAscii.Checked = true; - break; - case FormatDescriptor.SubType.Address: - radioSimpleDataAddress.Checked = true; - break; - case FormatDescriptor.SubType.Symbol: - radioSimpleDataSymbolic.Checked = true; - switch (dfd.SymbolRef.ValuePart) { - case WeakSymbolRef.Part.Low: - radioSymbolPartLow.Checked = true; - break; - case WeakSymbolRef.Part.High: - radioSymbolPartHigh.Checked = true; - break; - case WeakSymbolRef.Part.Bank: - radioSymbolPartBank.Checked = true; - break; - default: - Debug.Assert(false); - break; - } - Debug.Assert(dfd.HasSymbol); - symbolEntryTextBox.Text = dfd.SymbolRef.Label; - break; - default: - Debug.Assert(false); - break; - } - } else { - // preferred format not enabled; leave Hex/Low checked - } - break; - case FormatDescriptor.Type.String: - switch (dfd.FormatSubType) { - case FormatDescriptor.SubType.None: - preferredFormat = radioStringMixed; - break; - case FormatDescriptor.SubType.Reverse: - preferredFormat = radioStringMixedReverse; - break; - case FormatDescriptor.SubType.CString: - preferredFormat = radioStringNullTerm; - break; - case FormatDescriptor.SubType.L8String: - preferredFormat = radioStringLen8; - break; - case FormatDescriptor.SubType.L16String: - preferredFormat = radioStringLen16; - break; - case FormatDescriptor.SubType.Dci: - preferredFormat = radioStringDci; - break; - case FormatDescriptor.SubType.DciReverse: - preferredFormat = radioDefaultFormat; - break; - default: - Debug.Assert(false); - preferredFormat = radioDefaultFormat; - break; - } - break; - case FormatDescriptor.Type.Dense: - preferredFormat = radioDenseHex; - break; - case FormatDescriptor.Type.Fill: - preferredFormat = radioFill; - break; - default: - // Should not be here. - Debug.Assert(false); - preferredFormat = radioDefaultFormat; - break; - } - - if (preferredFormat.Enabled) { - preferredFormat.Checked = true; - } else { - mPreferredFormatUnavailable = true; - radioDefaultFormat.Checked = true; - } - } - - /// - /// Creates a list of FormatDescriptors, based on the current control configuration. - /// - /// The entries in the list are guaranteed to be sorted by start address and not - /// overlap. - /// - /// We assume that whatever the control gives us is correct, e.g. it's not going - /// to tell us to put a buffer full of zeroes into a DCI string. - /// - /// Result list. - private void CreateDescriptorListFromControls() { - FormatDescriptor.Type type = FormatDescriptor.Type.Default; - FormatDescriptor.SubType subType = FormatDescriptor.SubType.None; - WeakSymbolRef symbolRef = null; - int chunkLength = -1; - - // Decode the "display as" panel, if it's relevant. - if (radioSimpleDataHex.Enabled) { - if (radioSimpleDataHex.Checked) { - subType = FormatDescriptor.SubType.Hex; - } else if (radioSimpleDataDecimal.Checked) { - subType = FormatDescriptor.SubType.Decimal; - } else if (radioSimpleDataBinary.Checked) { - subType = FormatDescriptor.SubType.Binary; - } else if (radioSimpleDataAscii.Checked) { - subType = FormatDescriptor.SubType.Ascii; - } else if (radioSimpleDataAddress.Checked) { - subType = FormatDescriptor.SubType.Address; - } else if (radioSimpleDataSymbolic.Checked) { - WeakSymbolRef.Part part; - if (radioSymbolPartLow.Checked) { - part = WeakSymbolRef.Part.Low; - } else if (radioSymbolPartHigh.Checked) { - part = WeakSymbolRef.Part.High; - } else if (radioSymbolPartBank.Checked) { - part = WeakSymbolRef.Part.Bank; - } else { - Debug.Assert(false); - part = WeakSymbolRef.Part.Low; - } - subType = FormatDescriptor.SubType.Symbol; - symbolRef = new WeakSymbolRef(symbolEntryTextBox.Text, part); - } else { - Debug.Assert(false); - } - } else { - subType = 0; // set later, or doesn't matter - } - - // Decode the main format. - if (radioDefaultFormat.Checked) { - // Default/None; note this would create a multi-byte Default format, which isn't - // really allowed. What we actually want to do is remove the explicit formatting - // from all spanned offsets, so we use a dedicated type for that. - type = FormatDescriptor.Type.REMOVE; - } else if (radioSingleBytes.Checked) { - type = FormatDescriptor.Type.NumericLE; - chunkLength = 1; - } else if (radio16BitLittle.Checked) { - type = FormatDescriptor.Type.NumericLE; - chunkLength = 2; - } else if (radio16BitBig.Checked) { - type = FormatDescriptor.Type.NumericBE; - chunkLength = 2; - } else if (radio24BitLittle.Checked) { - type = FormatDescriptor.Type.NumericLE; - chunkLength = 3; - } else if (radio32BitLittle.Checked) { - type = FormatDescriptor.Type.NumericLE; - chunkLength = 4; - } else if (radioDenseHex.Checked) { - type = FormatDescriptor.Type.Dense; - } else if (radioFill.Checked) { - type = FormatDescriptor.Type.Fill; - } else if (radioStringMixed.Checked) { - type = FormatDescriptor.Type.String; - } else if (radioStringMixedReverse.Checked) { - type = FormatDescriptor.Type.String; - subType = FormatDescriptor.SubType.Reverse; - } else if (radioStringNullTerm.Checked) { - type = FormatDescriptor.Type.String; - subType = FormatDescriptor.SubType.CString; - } else if (radioStringLen8.Checked) { - type = FormatDescriptor.Type.String; - subType = FormatDescriptor.SubType.L8String; - } else if (radioStringLen16.Checked) { - type = FormatDescriptor.Type.String; - subType = FormatDescriptor.SubType.L16String; - } else if (radioStringDci.Checked) { - type = FormatDescriptor.Type.String; - subType = FormatDescriptor.SubType.Dci; - //} else if (radioStringDciReverse.Checked) { - // type = FormatDescriptor.Type.String; - // subType = FormatDescriptor.SubType.DciReverse; - } else { - Debug.Assert(false); - // default/none - } - - - Results = new SortedList(); - - IEnumerator iter = Selection.RangeListIterator; - while (iter.MoveNext()) { - TypedRangeSet.TypedRange rng = iter.Current; - - if (type == FormatDescriptor.Type.String) { - // We want to create one FormatDescriptor object per string. That way - // each string gets its own line. - if ((subType == FormatDescriptor.SubType.None || - subType == FormatDescriptor.SubType.Reverse)) { - CreateMixedStringEntries(rng.Low, rng.High, subType); - } else if (subType == FormatDescriptor.SubType.CString) { - CreateCStringEntries(rng.Low, rng.High, subType); - } else if (subType == FormatDescriptor.SubType.L8String || - subType == FormatDescriptor.SubType.L16String) { - CreateLengthStringEntries(rng.Low, rng.High, subType); - } else if (subType == FormatDescriptor.SubType.Dci || - subType == FormatDescriptor.SubType.DciReverse) { - CreateDciStringEntries(rng.Low, rng.High, subType); - } else { - Debug.Assert(false); - CreateMixedStringEntries(rng.Low, rng.High, subType); // shrug - } - } else { - CreateSimpleEntries(type, subType, chunkLength, symbolRef, rng.Low, rng.High); - } - } - } - - /// - /// Creates one or more FormatDescriptor entries for the specified range, adding them - /// to the Results list. - /// - /// This will either create one entry that spans the entire range (for e.g. strings - /// and bulk data), or create equal-sized chunks. - /// - /// Region data type. - /// Region data sub-type. - /// Length of a chunk, or -1 for full buffer. - /// Symbol reference, or null if not applicable. - /// Offset of first byte in range. - /// Offset of last byte in range. - private void CreateSimpleEntries(FormatDescriptor.Type type, - FormatDescriptor.SubType subType, int chunkLength, - WeakSymbolRef symbolRef, int low, int high) { - - if (chunkLength == -1) { - chunkLength = (high - low) + 1; - } - Debug.Assert(((high - low + 1) / chunkLength) * chunkLength == high - low + 1); - - // Either we have one chunk, or we have multiple chunks with the same type and - // length. Either way, we only need to create the descriptor once. (This is - // safe because FormatDescriptor instances are immutable.) - // - // Because certain details, like the fill byte and high-vs-low ASCII, are pulled - // out of the data stream at format time, we don't have to dig for them now. - FormatDescriptor dfd; - if (subType == FormatDescriptor.SubType.Symbol) { - dfd = FormatDescriptor.Create(chunkLength, symbolRef, - type == FormatDescriptor.Type.NumericBE); - } else { - dfd = FormatDescriptor.Create(chunkLength, type, subType); - } - - while (low <= high) { - Results.Add(low, dfd); - low += chunkLength; - } - } - - /// - /// Creates one or more FormatDescriptor entries for the specified range, adding them - /// to the Results list. - /// - /// Offset of first byte in range. - /// Offset of last byte in range. - /// String sub-type. - private void CreateMixedStringEntries(int low, int high, - FormatDescriptor.SubType subType) { - int stringStart = -1; - int highBit = 0; - int cur; - for (cur = low; cur <= high; cur++) { - byte val = mFileData[cur]; - if (CommonUtil.TextUtil.IsHiLoAscii(val)) { - // is ASCII - if (stringStart >= 0) { - // was in a string - if (highBit != (val & 0x80)) { - // end of string due to high bit flip, output - CreateStringOrByte(stringStart, cur - stringStart, subType); - // start a new string - stringStart = cur; - } else { - // still in string, keep going - } - } else { - // wasn't in a string, start one - stringStart = cur; - } - highBit = val & 0x80; - } else { - // not ASCII - if (stringStart >= 0) { - // was in a string, output it - CreateStringOrByte(stringStart, cur - stringStart, subType); - stringStart = -1; - } - // output as single byte - CreateByteFD(cur, FormatDescriptor.SubType.Hex); - } - } - if (stringStart >= 0) { - // close out the string - CreateStringOrByte(stringStart, cur - stringStart, subType); - } - } - - /// - /// Creates a format descriptor for ASCII data. If the data is only one byte long, - /// a single-byte ASCII char item is emitted instead. - /// - /// Offset of first byte. - /// Length of string. - /// String sub-type. - private void CreateStringOrByte(int offset, int length, - FormatDescriptor.SubType subType) { - Debug.Assert(length > 0); - if (length == 1) { - // single byte, output as single ASCII char rather than 1-byte string - CreateByteFD(offset, FormatDescriptor.SubType.Ascii); - } else { - FormatDescriptor dfd; - dfd = FormatDescriptor.Create(length, - FormatDescriptor.Type.String, subType); - Results.Add(offset, dfd); - } - } - - /// - /// Creates a format descriptor for a single-byte numeric value. - /// - /// File offset. - /// How to format the item. - private void CreateByteFD(int offset, FormatDescriptor.SubType subType) { - FormatDescriptor dfd = FormatDescriptor.Create(1, - FormatDescriptor.Type.NumericLE, subType); - Results.Add(offset, dfd); - } - - /// - /// Creates one or more FormatDescriptor entries for the specified range, adding them - /// to the Results list. - /// - /// Offset of first byte in range. - /// Offset of last byte in range. - /// String sub-type. - private void CreateCStringEntries(int low, int high, - FormatDescriptor.SubType subType) { - int startOffset = low; - for (int i = low; i <= high; i++) { - if (mFileData[i] == 0x00) { - // End of string. Zero-length strings are allowed. - FormatDescriptor dfd = FormatDescriptor.Create( - i - startOffset + 1, FormatDescriptor.Type.String, subType); - Results.Add(startOffset, dfd); - startOffset = i + 1; - } else { - // keep going - } - } - - // Earlier analysis guaranteed that the last byte in the buffer is 0x00. - Debug.Assert(startOffset == high + 1); - } - - /// - /// Creates one or more FormatDescriptor entries for the specified range, adding them - /// to the Results list. - /// - /// Offset of first byte in range. - /// Offset of last byte in range. - /// String sub-type. - private void CreateLengthStringEntries(int low, int high, - FormatDescriptor.SubType subType) { - int i; - for (i = low; i <= high;) { - int length = mFileData[i]; - if (subType == FormatDescriptor.SubType.L16String) { - length |= mFileData[i + 1] << 8; - length += 2; - } else { - length++; - } - // Zero-length strings are allowed. - FormatDescriptor dfd = FormatDescriptor.Create(length, - FormatDescriptor.Type.String, subType); - Results.Add(i, dfd); - i += length; - } - - Debug.Assert(i == high + 1); - } - - /// - /// Creates one or more FormatDescriptor entries for the specified range, adding them - /// to the Results list. - /// - /// Offset of first byte in range. - /// Offset of last byte in range. - /// String sub-type. - private void CreateDciStringEntries(int low, int high, - FormatDescriptor.SubType subType) { - int start, end, adj, endMask; - if (subType == FormatDescriptor.SubType.Dci) { - start = low; - end = high + 1; - adj = 1; - } else if (subType == FormatDescriptor.SubType.DciReverse) { - start = high; - end = low - 1; - adj = -1; - } else { - Debug.Assert(false); - return; - } - - // Zero-length strings aren't a thing for DCI. The analyzer requires that all - // strings in a region have the same polarity, so just grab the last byte. - endMask = mFileData[end - 1] & 0x80; - - int stringStart = start; - for (int i = start; i != end; i += adj) { - byte val = mFileData[i]; - if ((val & 0x80) == endMask) { - // found the end of a string - int length = (i - stringStart) * adj + 1; - FormatDescriptor dfd = FormatDescriptor.Create(length, - FormatDescriptor.Type.String, subType); - Results.Add(stringStart < i ? stringStart : i, dfd); - stringStart = i + adj; - } - } - - Debug.Assert(stringStart == end); - } - } -} diff --git a/SourceGenWF/AppForms/EditData.resx b/SourceGenWF/AppForms/EditData.resx deleted file mode 100644 index 1af7de1..0000000 --- a/SourceGenWF/AppForms/EditData.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditDefSymbol.Designer.cs b/SourceGenWF/AppForms/EditDefSymbol.Designer.cs deleted file mode 100644 index e6c9556..0000000 --- a/SourceGenWF/AppForms/EditDefSymbol.Designer.cs +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AppForms { - partial class EditDefSymbol { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.cancelButton = new System.Windows.Forms.Button(); - this.okButton = new System.Windows.Forms.Button(); - this.labelLabel = new System.Windows.Forms.Label(); - this.labelTextBox = new System.Windows.Forms.TextBox(); - this.valueTextBox = new System.Windows.Forms.TextBox(); - this.labelNotesLabel = new System.Windows.Forms.Label(); - this.valueLabel = new System.Windows.Forms.Label(); - this.valueNotesLabel = new System.Windows.Forms.Label(); - this.commentLabel = new System.Windows.Forms.Label(); - this.commentTextBox = new System.Windows.Forms.TextBox(); - this.commentNotesLabel = new System.Windows.Forms.Label(); - this.symbolTypeGroupBox = new System.Windows.Forms.GroupBox(); - this.constantRadioButton = new System.Windows.Forms.RadioButton(); - this.addressRadioButton = new System.Windows.Forms.RadioButton(); - this.labelUniqueLabel = new System.Windows.Forms.Label(); - this.symbolTypeGroupBox.SuspendLayout(); - this.SuspendLayout(); - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.Location = new System.Drawing.Point(203, 253); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 23); - this.cancelButton.TabIndex = 5; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - // - // okButton - // - this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.okButton.Location = new System.Drawing.Point(122, 253); - this.okButton.Name = "okButton"; - this.okButton.Size = new System.Drawing.Size(75, 23); - this.okButton.TabIndex = 4; - this.okButton.Text = "OK"; - this.okButton.UseVisualStyleBackColor = true; - this.okButton.Click += new System.EventHandler(this.okButton_Click); - // - // labelLabel - // - this.labelLabel.AutoSize = true; - this.labelLabel.Location = new System.Drawing.Point(14, 16); - this.labelLabel.Name = "labelLabel"; - this.labelLabel.Size = new System.Drawing.Size(36, 13); - this.labelLabel.TabIndex = 6; - this.labelLabel.Text = "Label:"; - // - // labelTextBox - // - this.labelTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.labelTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.labelTextBox.Location = new System.Drawing.Point(77, 14); - this.labelTextBox.Name = "labelTextBox"; - this.labelTextBox.Size = new System.Drawing.Size(200, 20); - this.labelTextBox.TabIndex = 0; - this.labelTextBox.TextChanged += new System.EventHandler(this.labelTextBox_TextChanged); - // - // valueTextBox - // - this.valueTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.valueTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.valueTextBox.Location = new System.Drawing.Point(77, 81); - this.valueTextBox.Name = "valueTextBox"; - this.valueTextBox.Size = new System.Drawing.Size(200, 20); - this.valueTextBox.TabIndex = 1; - this.valueTextBox.TextChanged += new System.EventHandler(this.valueTextBox_TextChanged); - // - // labelNotesLabel - // - this.labelNotesLabel.AutoSize = true; - this.labelNotesLabel.Location = new System.Drawing.Point(74, 37); - this.labelNotesLabel.Name = "labelNotesLabel"; - this.labelNotesLabel.Size = new System.Drawing.Size(187, 13); - this.labelNotesLabel.TabIndex = 9; - this.labelNotesLabel.Text = "• 2+ alphanumerics, starting with letter"; - // - // valueLabel - // - this.valueLabel.AutoSize = true; - this.valueLabel.Location = new System.Drawing.Point(14, 83); - this.valueLabel.Name = "valueLabel"; - this.valueLabel.Size = new System.Drawing.Size(37, 13); - this.valueLabel.TabIndex = 7; - this.valueLabel.Text = "Value:"; - // - // valueNotesLabel - // - this.valueNotesLabel.AutoSize = true; - this.valueNotesLabel.Location = new System.Drawing.Point(74, 104); - this.valueNotesLabel.Name = "valueNotesLabel"; - this.valueNotesLabel.Size = new System.Drawing.Size(155, 13); - this.valueNotesLabel.TabIndex = 11; - this.valueNotesLabel.Text = "• Decimal, hex ($), or binary (%)"; - // - // commentLabel - // - this.commentLabel.AutoSize = true; - this.commentLabel.Location = new System.Drawing.Point(17, 137); - this.commentLabel.Name = "commentLabel"; - this.commentLabel.Size = new System.Drawing.Size(54, 13); - this.commentLabel.TabIndex = 8; - this.commentLabel.Text = "Comment:"; - // - // commentTextBox - // - this.commentTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.commentTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.commentTextBox.Location = new System.Drawing.Point(77, 134); - this.commentTextBox.Name = "commentTextBox"; - this.commentTextBox.Size = new System.Drawing.Size(200, 20); - this.commentTextBox.TabIndex = 2; - // - // commentNotesLabel - // - this.commentNotesLabel.AutoSize = true; - this.commentNotesLabel.Location = new System.Drawing.Point(74, 157); - this.commentNotesLabel.Name = "commentNotesLabel"; - this.commentNotesLabel.Size = new System.Drawing.Size(55, 13); - this.commentNotesLabel.TabIndex = 12; - this.commentNotesLabel.Text = "• Optional"; - // - // symbolTypeGroupBox - // - this.symbolTypeGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.symbolTypeGroupBox.Controls.Add(this.constantRadioButton); - this.symbolTypeGroupBox.Controls.Add(this.addressRadioButton); - this.symbolTypeGroupBox.Location = new System.Drawing.Point(13, 190); - this.symbolTypeGroupBox.Name = "symbolTypeGroupBox"; - this.symbolTypeGroupBox.Size = new System.Drawing.Size(264, 48); - this.symbolTypeGroupBox.TabIndex = 3; - this.symbolTypeGroupBox.TabStop = false; - this.symbolTypeGroupBox.Text = "Symbol Type"; - // - // constantRadioButton - // - this.constantRadioButton.AutoSize = true; - this.constantRadioButton.Location = new System.Drawing.Point(99, 20); - this.constantRadioButton.Name = "constantRadioButton"; - this.constantRadioButton.Size = new System.Drawing.Size(67, 17); - this.constantRadioButton.TabIndex = 1; - this.constantRadioButton.TabStop = true; - this.constantRadioButton.Text = "Constant"; - this.constantRadioButton.UseVisualStyleBackColor = true; - // - // addressRadioButton - // - this.addressRadioButton.AutoSize = true; - this.addressRadioButton.Location = new System.Drawing.Point(6, 20); - this.addressRadioButton.Name = "addressRadioButton"; - this.addressRadioButton.Size = new System.Drawing.Size(63, 17); - this.addressRadioButton.TabIndex = 0; - this.addressRadioButton.TabStop = true; - this.addressRadioButton.Text = "Address"; - this.addressRadioButton.UseVisualStyleBackColor = true; - // - // labelUniqueLabel - // - this.labelUniqueLabel.AutoSize = true; - this.labelUniqueLabel.Location = new System.Drawing.Point(74, 53); - this.labelUniqueLabel.Name = "labelUniqueLabel"; - this.labelUniqueLabel.Size = new System.Drawing.Size(160, 13); - this.labelUniqueLabel.TabIndex = 10; - this.labelUniqueLabel.Text = "• Unique among project symbols"; - // - // EditDefSymbol - // - this.AcceptButton = this.okButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(290, 288); - this.Controls.Add(this.labelUniqueLabel); - this.Controls.Add(this.symbolTypeGroupBox); - this.Controls.Add(this.commentNotesLabel); - this.Controls.Add(this.commentTextBox); - this.Controls.Add(this.commentLabel); - this.Controls.Add(this.valueNotesLabel); - this.Controls.Add(this.valueLabel); - this.Controls.Add(this.labelNotesLabel); - this.Controls.Add(this.valueTextBox); - this.Controls.Add(this.labelTextBox); - this.Controls.Add(this.labelLabel); - this.Controls.Add(this.okButton); - this.Controls.Add(this.cancelButton); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "EditDefSymbol"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Edit Symbol"; - this.Load += new System.EventHandler(this.EditDefSymbol_Load); - this.symbolTypeGroupBox.ResumeLayout(false); - this.symbolTypeGroupBox.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Button cancelButton; - private System.Windows.Forms.Button okButton; - private System.Windows.Forms.Label labelLabel; - private System.Windows.Forms.TextBox labelTextBox; - private System.Windows.Forms.TextBox valueTextBox; - private System.Windows.Forms.Label labelNotesLabel; - private System.Windows.Forms.Label valueLabel; - private System.Windows.Forms.Label valueNotesLabel; - private System.Windows.Forms.Label commentLabel; - private System.Windows.Forms.TextBox commentTextBox; - private System.Windows.Forms.Label commentNotesLabel; - private System.Windows.Forms.GroupBox symbolTypeGroupBox; - private System.Windows.Forms.RadioButton constantRadioButton; - private System.Windows.Forms.RadioButton addressRadioButton; - private System.Windows.Forms.Label labelUniqueLabel; - } -} \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditDefSymbol.cs b/SourceGenWF/AppForms/EditDefSymbol.cs deleted file mode 100644 index c56bf9f..0000000 --- a/SourceGenWF/AppForms/EditDefSymbol.cs +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Drawing; -using System.Windows.Forms; - -using Asm65; - -namespace SourceGenWF.AppForms { - public partial class EditDefSymbol : Form { - /// - /// Set to previous value before calling; may be null if creating a new symbol. - /// Will be set to new value on OK result. - /// - public DefSymbol DefSym { get; set; } - - /// - /// Format object to use when formatting addresses and constants. - /// - private Formatter mNumFormatter; - - /// - /// List of existing symbols, for uniqueness check. The list will not be modified. - /// - private SortedList mDefSymbolList; - - // Saved off at dialog load time. - private Color mDefaultLabelColor; - - - public EditDefSymbol(Formatter formatter, SortedList defList) { - InitializeComponent(); - - mNumFormatter = formatter; - mDefSymbolList = defList; - } - - private void EditDefSymbol_Load(object sender, EventArgs e) { - mDefaultLabelColor = labelNotesLabel.ForeColor; - - if (DefSym != null) { - labelTextBox.Text = DefSym.Label; - valueTextBox.Text = mNumFormatter.FormatValueInBase(DefSym.Value, - DefSym.DataDescriptor.NumBase); - commentTextBox.Text = DefSym.Comment; - - if (DefSym.SymbolType == Symbol.Type.Constant) { - constantRadioButton.Checked = true; - } else { - addressRadioButton.Checked = true; - } - } else { - addressRadioButton.Checked = true; - } - - UpdateControls(); - } - - private void UpdateControls() { - bool labelValid, labelUnique, valueValid; - - // Label must be valid and not already exist in project symbol list. (It's okay - // if it exists elsewhere.) - labelValid = Asm65.Label.ValidateLabel(labelTextBox.Text); - - if (mDefSymbolList.TryGetValue(labelTextBox.Text, out DefSymbol existing)) { - // It's okay if it's the same object. - labelUnique = (existing == DefSym); - } else { - labelUnique = true; - } - - // Value must be blank, meaning "erase any earlier definition", or valid value. - // (Hmm... don't currently have a way to specify "no symbol" in DefSymbol.) - //if (!string.IsNullOrEmpty(valueTextBox.Text)) { - valueValid = ParseValue(out int unused1, out int unused2); - //} else { - // valueValid = true; - //} - - labelNotesLabel.ForeColor = labelValid ? mDefaultLabelColor : Color.Red; - labelUniqueLabel.ForeColor = labelUnique ? mDefaultLabelColor : Color.Red; - valueNotesLabel.ForeColor = valueValid ? mDefaultLabelColor : Color.Red; - - okButton.Enabled = labelValid && labelUnique && valueValid; - } - - private bool ParseValue(out int value, out int numBase) { - string str = valueTextBox.Text; - if (str.IndexOf('/') >= 0) { - // treat as address - numBase = 16; - return Asm65.Address.ParseAddress(str, (1 << 24) - 1, out value); - } else { - return Asm65.Number.TryParseInt(str, out value, out numBase); - } - } - - private void okButton_Click(object sender, EventArgs e) { - bool isConstant = constantRadioButton.Checked; - - ParseValue(out int value, out int numBase); - FormatDescriptor.SubType subType = FormatDescriptor.GetSubTypeForBase(numBase); - DefSym = new DefSymbol(labelTextBox.Text, value, Symbol.Source.Project, - isConstant ? Symbol.Type.Constant : Symbol.Type.ExternalAddr, - subType, commentTextBox.Text, string.Empty); - } - - private void labelTextBox_TextChanged(object sender, EventArgs e) { - UpdateControls(); - } - - private void valueTextBox_TextChanged(object sender, EventArgs e) { - UpdateControls(); - } - } -} diff --git a/SourceGenWF/AppForms/EditDefSymbol.resx b/SourceGenWF/AppForms/EditDefSymbol.resx deleted file mode 100644 index 1af7de1..0000000 --- a/SourceGenWF/AppForms/EditDefSymbol.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditLabel.Designer.cs b/SourceGenWF/AppForms/EditLabel.Designer.cs deleted file mode 100644 index 48b0b30..0000000 --- a/SourceGenWF/AppForms/EditLabel.Designer.cs +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AppForms { - partial class EditLabel { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.cancelButton = new System.Windows.Forms.Button(); - this.okButton = new System.Windows.Forms.Button(); - this.instructionLabel = new System.Windows.Forms.Label(); - this.labelTextBox = new System.Windows.Forms.TextBox(); - this.maxLengthLabel = new System.Windows.Forms.Label(); - this.firstLetterLabel = new System.Windows.Forms.Label(); - this.validCharsLabel = new System.Windows.Forms.Label(); - this.notDuplicateLabel = new System.Windows.Forms.Label(); - this.labelTypeGroupBox = new System.Windows.Forms.GroupBox(); - this.radioButtonExport = new System.Windows.Forms.RadioButton(); - this.radioButtonGlobal = new System.Windows.Forms.RadioButton(); - this.radioButtonLocal = new System.Windows.Forms.RadioButton(); - this.labelTypeGroupBox.SuspendLayout(); - this.SuspendLayout(); - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.Location = new System.Drawing.Point(267, 202); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 23); - this.cancelButton.TabIndex = 8; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - // - // okButton - // - this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.okButton.Location = new System.Drawing.Point(186, 202); - this.okButton.Name = "okButton"; - this.okButton.Size = new System.Drawing.Size(75, 23); - this.okButton.TabIndex = 7; - this.okButton.Text = "OK"; - this.okButton.UseVisualStyleBackColor = true; - this.okButton.Click += new System.EventHandler(this.okButton_Click); - // - // instructionLabel - // - this.instructionLabel.AutoSize = true; - this.instructionLabel.Location = new System.Drawing.Point(13, 13); - this.instructionLabel.Name = "instructionLabel"; - this.instructionLabel.Size = new System.Drawing.Size(60, 13); - this.instructionLabel.TabIndex = 0; - this.instructionLabel.Text = "Enter label:"; - // - // labelTextBox - // - this.labelTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.labelTextBox.Location = new System.Drawing.Point(13, 30); - this.labelTextBox.Name = "labelTextBox"; - this.labelTextBox.Size = new System.Drawing.Size(325, 20); - this.labelTextBox.TabIndex = 1; - this.labelTextBox.TextChanged += new System.EventHandler(this.labelTextBox_TextChanged); - // - // maxLengthLabel - // - this.maxLengthLabel.AutoSize = true; - this.maxLengthLabel.Location = new System.Drawing.Point(13, 57); - this.maxLengthLabel.Name = "maxLengthLabel"; - this.maxLengthLabel.Size = new System.Drawing.Size(251, 13); - this.maxLengthLabel.TabIndex = 2; - this.maxLengthLabel.Text = "• Must be 2-32 characters long (or blank to remove)"; - // - // firstLetterLabel - // - this.firstLetterLabel.AutoSize = true; - this.firstLetterLabel.Location = new System.Drawing.Point(12, 73); - this.firstLetterLabel.Name = "firstLetterLabel"; - this.firstLetterLabel.Size = new System.Drawing.Size(187, 13); - this.firstLetterLabel.TabIndex = 3; - this.firstLetterLabel.Text = "• Must start with a letter or underscore"; - // - // validCharsLabel - // - this.validCharsLabel.AutoSize = true; - this.validCharsLabel.Location = new System.Drawing.Point(12, 89); - this.validCharsLabel.Name = "validCharsLabel"; - this.validCharsLabel.Size = new System.Drawing.Size(297, 13); - this.validCharsLabel.TabIndex = 4; - this.validCharsLabel.Text = "• Valid characters are ASCII letters, numbers, and underscore"; - // - // notDuplicateLabel - // - this.notDuplicateLabel.AutoSize = true; - this.notDuplicateLabel.Location = new System.Drawing.Point(13, 105); - this.notDuplicateLabel.Name = "notDuplicateLabel"; - this.notDuplicateLabel.Size = new System.Drawing.Size(217, 13); - this.notDuplicateLabel.TabIndex = 5; - this.notDuplicateLabel.Text = "• Must not be a duplicate of an existing label"; - // - // labelTypeGroupBox - // - this.labelTypeGroupBox.Controls.Add(this.radioButtonExport); - this.labelTypeGroupBox.Controls.Add(this.radioButtonGlobal); - this.labelTypeGroupBox.Controls.Add(this.radioButtonLocal); - this.labelTypeGroupBox.Location = new System.Drawing.Point(13, 132); - this.labelTypeGroupBox.Name = "labelTypeGroupBox"; - this.labelTypeGroupBox.Size = new System.Drawing.Size(137, 93); - this.labelTypeGroupBox.TabIndex = 6; - this.labelTypeGroupBox.TabStop = false; - this.labelTypeGroupBox.Text = "Label Type"; - // - // radioButtonExport - // - this.radioButtonExport.AutoSize = true; - this.radioButtonExport.Location = new System.Drawing.Point(7, 67); - this.radioButtonExport.Name = "radioButtonExport"; - this.radioButtonExport.Size = new System.Drawing.Size(120, 17); - this.radioButtonExport.TabIndex = 2; - this.radioButtonExport.TabStop = true; - this.radioButtonExport.Text = "Global and &exported"; - this.radioButtonExport.UseVisualStyleBackColor = true; - // - // radioButtonGlobal - // - this.radioButtonGlobal.AutoSize = true; - this.radioButtonGlobal.Location = new System.Drawing.Point(7, 43); - this.radioButtonGlobal.Name = "radioButtonGlobal"; - this.radioButtonGlobal.Size = new System.Drawing.Size(55, 17); - this.radioButtonGlobal.TabIndex = 1; - this.radioButtonGlobal.TabStop = true; - this.radioButtonGlobal.Text = "&Global"; - this.radioButtonGlobal.UseVisualStyleBackColor = true; - // - // radioButtonLocal - // - this.radioButtonLocal.AutoSize = true; - this.radioButtonLocal.Location = new System.Drawing.Point(7, 20); - this.radioButtonLocal.Name = "radioButtonLocal"; - this.radioButtonLocal.Size = new System.Drawing.Size(106, 17); - this.radioButtonLocal.TabIndex = 0; - this.radioButtonLocal.TabStop = true; - this.radioButtonLocal.Text = "&Local (if possible)"; - this.radioButtonLocal.UseVisualStyleBackColor = true; - // - // EditLabel - // - this.AcceptButton = this.okButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(354, 237); - this.Controls.Add(this.labelTypeGroupBox); - this.Controls.Add(this.notDuplicateLabel); - this.Controls.Add(this.validCharsLabel); - this.Controls.Add(this.firstLetterLabel); - this.Controls.Add(this.maxLengthLabel); - this.Controls.Add(this.labelTextBox); - this.Controls.Add(this.instructionLabel); - this.Controls.Add(this.okButton); - this.Controls.Add(this.cancelButton); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "EditLabel"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Edit Label"; - this.Load += new System.EventHandler(this.EditLabel_Load); - this.labelTypeGroupBox.ResumeLayout(false); - this.labelTypeGroupBox.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Button cancelButton; - private System.Windows.Forms.Button okButton; - private System.Windows.Forms.Label instructionLabel; - private System.Windows.Forms.TextBox labelTextBox; - private System.Windows.Forms.Label maxLengthLabel; - private System.Windows.Forms.Label firstLetterLabel; - private System.Windows.Forms.Label validCharsLabel; - private System.Windows.Forms.Label notDuplicateLabel; - private System.Windows.Forms.GroupBox labelTypeGroupBox; - private System.Windows.Forms.RadioButton radioButtonLocal; - private System.Windows.Forms.RadioButton radioButtonGlobal; - private System.Windows.Forms.RadioButton radioButtonExport; - } -} \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditLabel.cs b/SourceGenWF/AppForms/EditLabel.cs deleted file mode 100644 index d497ac9..0000000 --- a/SourceGenWF/AppForms/EditLabel.cs +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Diagnostics; -using System.Drawing; -using System.Windows.Forms; - -namespace SourceGenWF.AppForms { - public partial class EditLabel : Form { - /// - /// Symbol object. When the dialog completes successfully, - /// this will have the new symbol, or null if the user deleted the label. - /// - public Symbol LabelSym { get; private set; } - - /// - /// Address we are editing the label for. - /// - private int mAddress; - - /// - /// Reference to DisasmProject's SymbolTable. - /// - private SymbolTable mSymbolTable; - - // Dialog label text color, saved off at dialog load time. - private Color mDefaultLabelColor; - - - public EditLabel(Symbol origSym, int address, SymbolTable symbolTable) { - InitializeComponent(); - - LabelSym = origSym; - mAddress = address; - mSymbolTable = symbolTable; - } - - private void EditLabel_Load(object sender, EventArgs e) { - mDefaultLabelColor = maxLengthLabel.ForeColor; - - if (LabelSym == null) { - labelTextBox.Text = string.Empty; - radioButtonLocal.Checked = true; - } else { - labelTextBox.Text = LabelSym.Label; - switch (LabelSym.SymbolType) { - case Symbol.Type.LocalOrGlobalAddr: - radioButtonLocal.Checked = true; - break; - case Symbol.Type.GlobalAddr: - radioButtonGlobal.Checked = true; - break; - case Symbol.Type.GlobalAddrExport: - radioButtonExport.Checked = true; - break; - default: - Debug.Assert(false); // WTF - radioButtonLocal.Checked = true; - break; - } - } - } - - private void labelTextBox_TextChanged(object sender, EventArgs e) { - string str = labelTextBox.Text; - bool valid = true; - - if (str.Length == 1 || str.Length > Asm65.Label.MAX_LABEL_LEN) { - valid = false; - maxLengthLabel.ForeColor = Color.Red; - } else { - maxLengthLabel.ForeColor = mDefaultLabelColor; - } - - // Regex never matches on strings of length 0 or 1, but we don't want - // to complain about that since we're already doing that above. - // TODO(maybe): Ideally this wouldn't light up if the only problem was a - // non-alpha first character, since the next test will call that out. - if (str.Length > 1) { - if (!Asm65.Label.ValidateLabel(str)) { - valid = false; - validCharsLabel.ForeColor = Color.Red; - } else { - validCharsLabel.ForeColor = mDefaultLabelColor; - } - } else { - validCharsLabel.ForeColor = mDefaultLabelColor; - } - - if (str.Length > 0 && - !((str[0] >= 'A' && str[0] <= 'Z') || (str[0] >= 'a' && str[0] <= 'z') || - str[0] == '_')) { - // This should have been caught by the regex. We just want to set the - // color on the "first character must be" instruction text. - Debug.Assert(!valid); - firstLetterLabel.ForeColor = Color.Red; - } else { - firstLetterLabel.ForeColor = mDefaultLabelColor; - } - - // Refuse to continue if the label already exists. The only exception is if - // it's the same symbol, and it's user-defined. (If they're trying to edit an - // auto label, we want to force them to change the name.) - // - // NOTE: if label matching is case-insensitive, we want to allow a situation - // where a label is being renamed from "FOO" to "Foo". We should be able to - // test for object equality on the Symbol to determine if we're renaming a - // symbol to itself. - if (valid && mSymbolTable.TryGetValue(str, out Symbol sym) && - (sym != LabelSym || LabelSym.SymbolSource != Symbol.Source.User)) { - valid = false; - notDuplicateLabel.ForeColor = Color.Red; - } else { - notDuplicateLabel.ForeColor = mDefaultLabelColor; - } - - okButton.Enabled = valid; - } - - private void okButton_Click(object sender, EventArgs e) { - if (string.IsNullOrEmpty(labelTextBox.Text)) { - LabelSym = null; - } else { - Symbol.Type symbolType; - if (radioButtonLocal.Checked) { - symbolType = Symbol.Type.LocalOrGlobalAddr; - } else if (radioButtonGlobal.Checked) { - symbolType = Symbol.Type.GlobalAddr; - } else if (radioButtonExport.Checked) { - symbolType = Symbol.Type.GlobalAddrExport; - } else { - Debug.Assert(false); // WTF - symbolType = Symbol.Type.LocalOrGlobalAddr; - } - LabelSym = new Symbol(labelTextBox.Text, mAddress, Symbol.Source.User, symbolType); - } - } - } -} diff --git a/SourceGenWF/AppForms/EditLabel.resx b/SourceGenWF/AppForms/EditLabel.resx deleted file mode 100644 index 1af7de1..0000000 --- a/SourceGenWF/AppForms/EditLabel.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditLongComment.Designer.cs b/SourceGenWF/AppForms/EditLongComment.Designer.cs deleted file mode 100644 index 57d3d9e..0000000 --- a/SourceGenWF/AppForms/EditLongComment.Designer.cs +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AppForms { - partial class EditLongComment { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.entryTextBox = new System.Windows.Forms.TextBox(); - this.textEntryLabel = new System.Windows.Forms.Label(); - this.sampleOutputLabel = new System.Windows.Forms.Label(); - this.displayTextBox = new System.Windows.Forms.TextBox(); - this.okButton = new System.Windows.Forms.Button(); - this.cancelButton = new System.Windows.Forms.Button(); - this.maximumWidthLabel = new System.Windows.Forms.Label(); - this.maxWidthComboBox = new System.Windows.Forms.ComboBox(); - this.boxModeCheckBox = new System.Windows.Forms.CheckBox(); - this.SuspendLayout(); - // - // entryTextBox - // - this.entryTextBox.AcceptsReturn = true; - this.entryTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.entryTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.entryTextBox.Location = new System.Drawing.Point(12, 29); - this.entryTextBox.Multiline = true; - this.entryTextBox.Name = "entryTextBox"; - this.entryTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.entryTextBox.Size = new System.Drawing.Size(509, 150); - this.entryTextBox.TabIndex = 0; - this.entryTextBox.Text = "01234567890123456789012345678901234567890123456789012345678901234567890123456789"; - this.entryTextBox.TextChanged += new System.EventHandler(this.entryTextBox_TextChanged); - // - // textEntryLabel - // - this.textEntryLabel.AutoSize = true; - this.textEntryLabel.Location = new System.Drawing.Point(13, 12); - this.textEntryLabel.Name = "textEntryLabel"; - this.textEntryLabel.Size = new System.Drawing.Size(101, 13); - this.textEntryLabel.TabIndex = 1; - this.textEntryLabel.Text = "Enter comment text:"; - // - // sampleOutputLabel - // - this.sampleOutputLabel.AutoSize = true; - this.sampleOutputLabel.Location = new System.Drawing.Point(12, 240); - this.sampleOutputLabel.Name = "sampleOutputLabel"; - this.sampleOutputLabel.Size = new System.Drawing.Size(88, 13); - this.sampleOutputLabel.TabIndex = 5; - this.sampleOutputLabel.Text = "Expected output:"; - // - // displayTextBox - // - this.displayTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.displayTextBox.BackColor = System.Drawing.SystemColors.Window; - this.displayTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.displayTextBox.Location = new System.Drawing.Point(12, 258); - this.displayTextBox.Multiline = true; - this.displayTextBox.Name = "displayTextBox"; - this.displayTextBox.ReadOnly = true; - this.displayTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.displayTextBox.Size = new System.Drawing.Size(509, 163); - this.displayTextBox.TabIndex = 6; - this.displayTextBox.Text = "01234567890123456789012345678901234567890123456789012345678901234567890123456789"; - // - // okButton - // - this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.okButton.Location = new System.Drawing.Point(365, 438); - this.okButton.Name = "okButton"; - this.okButton.Size = new System.Drawing.Size(75, 23); - this.okButton.TabIndex = 7; - this.okButton.Text = "OK"; - this.okButton.UseVisualStyleBackColor = true; - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.Location = new System.Drawing.Point(446, 438); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 23); - this.cancelButton.TabIndex = 8; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - // - // maximumWidthLabel - // - this.maximumWidthLabel.AutoSize = true; - this.maximumWidthLabel.Location = new System.Drawing.Point(12, 198); - this.maximumWidthLabel.Name = "maximumWidthLabel"; - this.maximumWidthLabel.Size = new System.Drawing.Size(101, 13); - this.maximumWidthLabel.TabIndex = 2; - this.maximumWidthLabel.Text = "Maximum line width:"; - // - // maxWidthComboBox - // - this.maxWidthComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.maxWidthComboBox.FormattingEnabled = true; - this.maxWidthComboBox.Items.AddRange(new object[] { - "30", - "40", - "64", - "80"}); - this.maxWidthComboBox.Location = new System.Drawing.Point(119, 195); - this.maxWidthComboBox.Name = "maxWidthComboBox"; - this.maxWidthComboBox.Size = new System.Drawing.Size(74, 21); - this.maxWidthComboBox.TabIndex = 3; - this.maxWidthComboBox.SelectedIndexChanged += new System.EventHandler(this.maxWidthComboBox_SelectedIndexChanged); - // - // boxModeCheckBox - // - this.boxModeCheckBox.AutoSize = true; - this.boxModeCheckBox.Location = new System.Drawing.Point(264, 197); - this.boxModeCheckBox.Name = "boxModeCheckBox"; - this.boxModeCheckBox.Size = new System.Drawing.Size(92, 17); - this.boxModeCheckBox.TabIndex = 4; - this.boxModeCheckBox.Text = "Render in box"; - this.boxModeCheckBox.UseVisualStyleBackColor = true; - this.boxModeCheckBox.CheckedChanged += new System.EventHandler(this.boxModeCheckBox_CheckedChanged); - // - // EditLongComment - // - this.AcceptButton = this.okButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(534, 473); - this.Controls.Add(this.boxModeCheckBox); - this.Controls.Add(this.maxWidthComboBox); - this.Controls.Add(this.maximumWidthLabel); - this.Controls.Add(this.cancelButton); - this.Controls.Add(this.okButton); - this.Controls.Add(this.displayTextBox); - this.Controls.Add(this.sampleOutputLabel); - this.Controls.Add(this.textEntryLabel); - this.Controls.Add(this.entryTextBox); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.MinimumSize = new System.Drawing.Size(550, 512); - this.Name = "EditLongComment"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Edit Long Comment"; - this.HelpButtonClicked += new System.ComponentModel.CancelEventHandler(this.EditLongComment_HelpButtonClicked); - this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.EditLongComment_FormClosing); - this.Load += new System.EventHandler(this.EditLongComment_Load); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.TextBox entryTextBox; - private System.Windows.Forms.Label textEntryLabel; - private System.Windows.Forms.Label sampleOutputLabel; - private System.Windows.Forms.TextBox displayTextBox; - private System.Windows.Forms.Button okButton; - private System.Windows.Forms.Button cancelButton; - private System.Windows.Forms.Label maximumWidthLabel; - private System.Windows.Forms.ComboBox maxWidthComboBox; - private System.Windows.Forms.CheckBox boxModeCheckBox; - } -} \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditLongComment.cs b/SourceGenWF/AppForms/EditLongComment.cs deleted file mode 100644 index a3cd1f9..0000000 --- a/SourceGenWF/AppForms/EditLongComment.cs +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Windows.Forms; - -namespace SourceGenWF.AppForms { - public partial class EditLongComment : Form { - /// - /// Get or set the multi-line comment object. On exit, will be set to null if - /// the user wants to delete the comment. - /// - public MultiLineComment LongComment { get; set; } - - private Asm65.Formatter mFormatter; - - - public EditLongComment(Asm65.Formatter formatter) { - InitializeComponent(); - - mFormatter = formatter; - LongComment = new MultiLineComment(string.Empty); - } - - private void EditLongComment_Load(object sender, EventArgs e) { - Debug.Assert(LongComment != null); - entryTextBox.Text = LongComment.Text; - boxModeCheckBox.Checked = LongComment.BoxMode; - - maxWidthComboBox.SelectedIndex = 0; - for (int i = 0; i < maxWidthComboBox.Items.Count; i++) { - string item = (string) maxWidthComboBox.Items[i]; - if (int.Parse(item) == LongComment.MaxWidth) { - maxWidthComboBox.SelectedIndex = i; - break; - } - } - - FormatInput(); - } - - // Handle Ctrl+Enter. - protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { - if (keyData == (Keys.Control | Keys.Enter)) { - DialogResult = DialogResult.OK; - Close(); - return true; - } - return base.ProcessCmdKey(ref msg, keyData); - } - - private void EditLongComment_FormClosing(object sender, FormClosingEventArgs e) { - if (string.IsNullOrEmpty(entryTextBox.Text)) { - LongComment = null; - } else { - LongComment = CreateMLC(); - } - } - - private void entryTextBox_TextChanged(object sender, EventArgs e) { - FormatInput(); - } - - private void maxWidthComboBox_SelectedIndexChanged(object sender, EventArgs e) { - FormatInput(); - } - - private void boxModeCheckBox_CheckedChanged(object sender, EventArgs e) { - FormatInput(); - } - - /// - /// Creates a MultiLineComment from the current state of the dialog. - /// - /// New MultiLineComment object. Returns null if the dialog is still - /// in the process of initializing. - private MultiLineComment CreateMLC() { - if (maxWidthComboBox.SelectedItem == null) { - return null; // still initializing - } - return new MultiLineComment(entryTextBox.Text, boxModeCheckBox.Checked, - int.Parse((string)maxWidthComboBox.SelectedItem)); - } - - /// - /// Formats entryTextBox.Text into displayTextBox.Text. - /// - private void FormatInput() { - MultiLineComment mlc = CreateMLC(); - if (mlc == null) { - return; - } - List lines = mlc.FormatText(mFormatter, string.Empty); - - StringBuilder sb = new StringBuilder(entryTextBox.Text.Length + lines.Count * 2); - //sb.AppendFormat("### got {0} lines\r\n", lines.Count); - bool first = true; - foreach (string line in lines) { - if (first) { - first = false; - } else { - sb.Append("\r\n"); - } - sb.Append(line); - } - - displayTextBox.Text = sb.ToString(); - } - - private void EditLongComment_HelpButtonClicked(object sender, System.ComponentModel.CancelEventArgs e) { - HelpAccess.ShowHelp(HelpAccess.Topic.EditLongComment); - } - } -} diff --git a/SourceGenWF/AppForms/EditLongComment.resx b/SourceGenWF/AppForms/EditLongComment.resx deleted file mode 100644 index 1af7de1..0000000 --- a/SourceGenWF/AppForms/EditLongComment.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditNote.Designer.cs b/SourceGenWF/AppForms/EditNote.Designer.cs deleted file mode 100644 index 4abdbb6..0000000 --- a/SourceGenWF/AppForms/EditNote.Designer.cs +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AppForms { - partial class EditNote { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.cancelButton = new System.Windows.Forms.Button(); - this.okButton = new System.Windows.Forms.Button(); - this.headerLabel = new System.Windows.Forms.Label(); - this.noteTextBox = new System.Windows.Forms.TextBox(); - this.colorGroupBox = new System.Windows.Forms.GroupBox(); - this.colorOrangeRadio = new System.Windows.Forms.RadioButton(); - this.colorPinkRadio = new System.Windows.Forms.RadioButton(); - this.colorYellowRadio = new System.Windows.Forms.RadioButton(); - this.colorBlueRadio = new System.Windows.Forms.RadioButton(); - this.colorGreenRadio = new System.Windows.Forms.RadioButton(); - this.colorDefaultRadio = new System.Windows.Forms.RadioButton(); - this.colorGroupBox.SuspendLayout(); - this.SuspendLayout(); - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.Location = new System.Drawing.Point(552, 225); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 23); - this.cancelButton.TabIndex = 3; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - // - // okButton - // - this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.okButton.Location = new System.Drawing.Point(471, 225); - this.okButton.Name = "okButton"; - this.okButton.Size = new System.Drawing.Size(75, 23); - this.okButton.TabIndex = 2; - this.okButton.Text = "OK"; - this.okButton.UseVisualStyleBackColor = true; - // - // headerLabel - // - this.headerLabel.AutoSize = true; - this.headerLabel.Location = new System.Drawing.Point(13, 13); - this.headerLabel.Name = "headerLabel"; - this.headerLabel.Size = new System.Drawing.Size(59, 13); - this.headerLabel.TabIndex = 0; - this.headerLabel.Text = "Enter note:"; - // - // noteTextBox - // - this.noteTextBox.AcceptsReturn = true; - this.noteTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.noteTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.noteTextBox.Location = new System.Drawing.Point(13, 33); - this.noteTextBox.Multiline = true; - this.noteTextBox.Name = "noteTextBox"; - this.noteTextBox.Size = new System.Drawing.Size(614, 113); - this.noteTextBox.TabIndex = 1; - // - // colorGroupBox - // - this.colorGroupBox.Controls.Add(this.colorOrangeRadio); - this.colorGroupBox.Controls.Add(this.colorPinkRadio); - this.colorGroupBox.Controls.Add(this.colorYellowRadio); - this.colorGroupBox.Controls.Add(this.colorBlueRadio); - this.colorGroupBox.Controls.Add(this.colorGreenRadio); - this.colorGroupBox.Controls.Add(this.colorDefaultRadio); - this.colorGroupBox.Location = new System.Drawing.Point(13, 153); - this.colorGroupBox.Name = "colorGroupBox"; - this.colorGroupBox.Size = new System.Drawing.Size(182, 95); - this.colorGroupBox.TabIndex = 4; - this.colorGroupBox.TabStop = false; - this.colorGroupBox.Text = "Select Highlight Color"; - // - // colorOrangeRadio - // - this.colorOrangeRadio.AutoSize = true; - this.colorOrangeRadio.Location = new System.Drawing.Point(98, 68); - this.colorOrangeRadio.Name = "colorOrangeRadio"; - this.colorOrangeRadio.Size = new System.Drawing.Size(60, 17); - this.colorOrangeRadio.TabIndex = 5; - this.colorOrangeRadio.TabStop = true; - this.colorOrangeRadio.Text = "&Orange"; - this.colorOrangeRadio.UseVisualStyleBackColor = true; - // - // colorPinkRadio - // - this.colorPinkRadio.AutoSize = true; - this.colorPinkRadio.Location = new System.Drawing.Point(98, 44); - this.colorPinkRadio.Name = "colorPinkRadio"; - this.colorPinkRadio.Size = new System.Drawing.Size(46, 17); - this.colorPinkRadio.TabIndex = 4; - this.colorPinkRadio.TabStop = true; - this.colorPinkRadio.Text = "&Pink"; - this.colorPinkRadio.UseVisualStyleBackColor = true; - // - // colorYellowRadio - // - this.colorYellowRadio.AutoSize = true; - this.colorYellowRadio.Location = new System.Drawing.Point(98, 20); - this.colorYellowRadio.Name = "colorYellowRadio"; - this.colorYellowRadio.Size = new System.Drawing.Size(56, 17); - this.colorYellowRadio.TabIndex = 3; - this.colorYellowRadio.TabStop = true; - this.colorYellowRadio.Text = "&Yellow"; - this.colorYellowRadio.UseVisualStyleBackColor = true; - // - // colorBlueRadio - // - this.colorBlueRadio.AutoSize = true; - this.colorBlueRadio.Location = new System.Drawing.Point(7, 68); - this.colorBlueRadio.Name = "colorBlueRadio"; - this.colorBlueRadio.Size = new System.Drawing.Size(46, 17); - this.colorBlueRadio.TabIndex = 2; - this.colorBlueRadio.TabStop = true; - this.colorBlueRadio.Text = "&Blue"; - this.colorBlueRadio.UseVisualStyleBackColor = true; - // - // colorGreenRadio - // - this.colorGreenRadio.AutoSize = true; - this.colorGreenRadio.Location = new System.Drawing.Point(7, 44); - this.colorGreenRadio.Name = "colorGreenRadio"; - this.colorGreenRadio.Size = new System.Drawing.Size(54, 17); - this.colorGreenRadio.TabIndex = 1; - this.colorGreenRadio.TabStop = true; - this.colorGreenRadio.Text = "&Green"; - this.colorGreenRadio.UseVisualStyleBackColor = true; - // - // colorDefaultRadio - // - this.colorDefaultRadio.AutoSize = true; - this.colorDefaultRadio.Location = new System.Drawing.Point(7, 20); - this.colorDefaultRadio.Name = "colorDefaultRadio"; - this.colorDefaultRadio.Size = new System.Drawing.Size(51, 17); - this.colorDefaultRadio.TabIndex = 0; - this.colorDefaultRadio.TabStop = true; - this.colorDefaultRadio.Text = "&None"; - this.colorDefaultRadio.UseVisualStyleBackColor = true; - // - // EditNote - // - this.AcceptButton = this.okButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(639, 260); - this.Controls.Add(this.colorGroupBox); - this.Controls.Add(this.noteTextBox); - this.Controls.Add(this.headerLabel); - this.Controls.Add(this.okButton); - this.Controls.Add(this.cancelButton); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "EditNote"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Edit Note"; - this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.EditNote_FormClosing); - this.Load += new System.EventHandler(this.EditNote_Load); - this.colorGroupBox.ResumeLayout(false); - this.colorGroupBox.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Button cancelButton; - private System.Windows.Forms.Button okButton; - private System.Windows.Forms.Label headerLabel; - private System.Windows.Forms.TextBox noteTextBox; - private System.Windows.Forms.GroupBox colorGroupBox; - private System.Windows.Forms.RadioButton colorOrangeRadio; - private System.Windows.Forms.RadioButton colorPinkRadio; - private System.Windows.Forms.RadioButton colorYellowRadio; - private System.Windows.Forms.RadioButton colorBlueRadio; - private System.Windows.Forms.RadioButton colorGreenRadio; - private System.Windows.Forms.RadioButton colorDefaultRadio; - } -} \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditNote.cs b/SourceGenWF/AppForms/EditNote.cs deleted file mode 100644 index ed20652..0000000 --- a/SourceGenWF/AppForms/EditNote.cs +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Diagnostics; -using System.Drawing; -using System.Windows.Forms; - -namespace SourceGenWF.AppForms { - public partial class EditNote : Form { - /// - /// Get or set the note object. On exit, will be set to null if the user wants - /// to delete the note. - /// - public MultiLineComment Note { get; set; } - - // Highlight color palette. Unless the user has funky theme, the color will be - // replacing a white background, and will be overlaid with black text, so should - // be on the lighter end of the spectrum. - private enum ColorList { - None = 0, Green, Blue, Yellow, Pink, Orange - } - private static Color[] sColors = new Color[] { - Color.FromArgb(0), // None - Color.LightGreen, - Color.LightBlue, - Color.Yellow, //LightGoldenrodYellow, - Color.LightPink, - Color.Orange - }; - private RadioButton[] mColorButtons; - - - public EditNote() { - InitializeComponent(); - Note = new MultiLineComment(string.Empty); - } - - private void EditNote_Load(object sender, EventArgs e) { - noteTextBox.Text = Note.Text; - - mColorButtons = new RadioButton[] { - colorDefaultRadio, - colorGreenRadio, - colorBlueRadio, - colorYellowRadio, - colorPinkRadio, - colorOrangeRadio - }; - Debug.Assert(mColorButtons.Length == sColors.Length); - - // Configure radio buttons. - colorDefaultRadio.Checked = true; - if (Note != null) { - Color curColor = Note.BackgroundColor; - for (int i = 0; i < sColors.Length; i++) { - // Can't just compare colors, because the sColors entries are "known" and - // have some additional properties set. Comparing the RGB values works. - if (sColors[i].ToArgb() == curColor.ToArgb()) { - mColorButtons[i].Checked = true; - break; - } - } - } - } - - // Handle Ctrl+Enter. - protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { - if (keyData == (Keys.Control | Keys.Enter)) { - DialogResult = DialogResult.OK; - Close(); - return true; - } - return base.ProcessCmdKey(ref msg, keyData); - } - - private void EditNote_FormClosing(object sender, FormClosingEventArgs e) { - if (string.IsNullOrEmpty(noteTextBox.Text)) { - Note = null; - } else { - Color bkgndColor = Color.Fuchsia; - for (int i = 0; i < mColorButtons.Length; i++) { - if (mColorButtons[i].Checked) { - bkgndColor = sColors[i]; - break; - } - } - Note = new MultiLineComment(noteTextBox.Text, bkgndColor); - } - } - } -} diff --git a/SourceGenWF/AppForms/EditNote.resx b/SourceGenWF/AppForms/EditNote.resx deleted file mode 100644 index 1af7de1..0000000 --- a/SourceGenWF/AppForms/EditNote.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditOperand.Designer.cs b/SourceGenWF/AppForms/EditOperand.Designer.cs deleted file mode 100644 index fba790f..0000000 --- a/SourceGenWF/AppForms/EditOperand.Designer.cs +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AppForms { - partial class EditOperand { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.cancelButton = new System.Windows.Forms.Button(); - this.okButton = new System.Windows.Forms.Button(); - this.mainRadioPanel = new System.Windows.Forms.Panel(); - this.symbolPartPanel = new System.Windows.Forms.Panel(); - this.radioButtonBank = new System.Windows.Forms.RadioButton(); - this.radioButtonHigh = new System.Windows.Forms.RadioButton(); - this.radioButtonLow = new System.Windows.Forms.RadioButton(); - this.symbolTextBox = new System.Windows.Forms.TextBox(); - this.radioButtonSymbol = new System.Windows.Forms.RadioButton(); - this.radioButtonAscii = new System.Windows.Forms.RadioButton(); - this.radioButtonBinary = new System.Windows.Forms.RadioButton(); - this.radioButtonDecimal = new System.Windows.Forms.RadioButton(); - this.radioButtonHex = new System.Windows.Forms.RadioButton(); - this.radioButtonDefault = new System.Windows.Forms.RadioButton(); - this.selectFormatLabel = new System.Windows.Forms.Label(); - this.previewLabel = new System.Windows.Forms.Label(); - this.previewTextBox = new System.Windows.Forms.TextBox(); - this.symbolShortcutsGroupBox = new System.Windows.Forms.GroupBox(); - this.operandAndProjRadioButton = new System.Windows.Forms.RadioButton(); - this.operandAndLabelRadioButton = new System.Windows.Forms.RadioButton(); - this.labelInsteadRadioButton = new System.Windows.Forms.RadioButton(); - this.operandOnlyRadioButton = new System.Windows.Forms.RadioButton(); - this.mainRadioPanel.SuspendLayout(); - this.symbolPartPanel.SuspendLayout(); - this.symbolShortcutsGroupBox.SuspendLayout(); - this.SuspendLayout(); - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.Location = new System.Drawing.Point(199, 377); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 23); - this.cancelButton.TabIndex = 4; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - // - // okButton - // - this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.okButton.Location = new System.Drawing.Point(118, 377); - this.okButton.Name = "okButton"; - this.okButton.Size = new System.Drawing.Size(75, 23); - this.okButton.TabIndex = 3; - this.okButton.Text = "OK"; - this.okButton.UseVisualStyleBackColor = true; - this.okButton.Click += new System.EventHandler(this.okButton_Click); - // - // mainRadioPanel - // - this.mainRadioPanel.Controls.Add(this.symbolPartPanel); - this.mainRadioPanel.Controls.Add(this.symbolTextBox); - this.mainRadioPanel.Controls.Add(this.radioButtonSymbol); - this.mainRadioPanel.Controls.Add(this.radioButtonAscii); - this.mainRadioPanel.Controls.Add(this.radioButtonBinary); - this.mainRadioPanel.Controls.Add(this.radioButtonDecimal); - this.mainRadioPanel.Controls.Add(this.radioButtonHex); - this.mainRadioPanel.Controls.Add(this.radioButtonDefault); - this.mainRadioPanel.Location = new System.Drawing.Point(12, 29); - this.mainRadioPanel.Name = "mainRadioPanel"; - this.mainRadioPanel.Size = new System.Drawing.Size(261, 173); - this.mainRadioPanel.TabIndex = 0; - // - // symbolPartPanel - // - this.symbolPartPanel.Controls.Add(this.radioButtonBank); - this.symbolPartPanel.Controls.Add(this.radioButtonHigh); - this.symbolPartPanel.Controls.Add(this.radioButtonLow); - this.symbolPartPanel.Location = new System.Drawing.Point(69, 150); - this.symbolPartPanel.Name = "symbolPartPanel"; - this.symbolPartPanel.Size = new System.Drawing.Size(154, 18); - this.symbolPartPanel.TabIndex = 7; - // - // radioButtonBank - // - this.radioButtonBank.AutoSize = true; - this.radioButtonBank.Location = new System.Drawing.Point(100, 0); - this.radioButtonBank.Name = "radioButtonBank"; - this.radioButtonBank.Size = new System.Drawing.Size(50, 17); - this.radioButtonBank.TabIndex = 2; - this.radioButtonBank.TabStop = true; - this.radioButtonBank.Text = "&Bank"; - this.radioButtonBank.UseVisualStyleBackColor = true; - this.radioButtonBank.CheckedChanged += new System.EventHandler(this.PartGroup_CheckedChanged); - // - // radioButtonHigh - // - this.radioButtonHigh.AutoSize = true; - this.radioButtonHigh.Location = new System.Drawing.Point(50, 0); - this.radioButtonHigh.Name = "radioButtonHigh"; - this.radioButtonHigh.Size = new System.Drawing.Size(47, 17); - this.radioButtonHigh.TabIndex = 1; - this.radioButtonHigh.TabStop = true; - this.radioButtonHigh.Text = "&High"; - this.radioButtonHigh.UseVisualStyleBackColor = true; - this.radioButtonHigh.CheckedChanged += new System.EventHandler(this.PartGroup_CheckedChanged); - // - // radioButtonLow - // - this.radioButtonLow.AutoSize = true; - this.radioButtonLow.Location = new System.Drawing.Point(0, 0); - this.radioButtonLow.Name = "radioButtonLow"; - this.radioButtonLow.Size = new System.Drawing.Size(45, 17); - this.radioButtonLow.TabIndex = 0; - this.radioButtonLow.TabStop = true; - this.radioButtonLow.Text = "&Low"; - this.radioButtonLow.UseVisualStyleBackColor = true; - this.radioButtonLow.CheckedChanged += new System.EventHandler(this.PartGroup_CheckedChanged); - // - // symbolTextBox - // - this.symbolTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.symbolTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.symbolTextBox.Location = new System.Drawing.Point(69, 124); - this.symbolTextBox.MaxLength = 128; - this.symbolTextBox.Name = "symbolTextBox"; - this.symbolTextBox.Size = new System.Drawing.Size(179, 20); - this.symbolTextBox.TabIndex = 6; - this.symbolTextBox.TextChanged += new System.EventHandler(this.symbolTextBox_TextChanged); - // - // radioButtonSymbol - // - this.radioButtonSymbol.AutoSize = true; - this.radioButtonSymbol.Location = new System.Drawing.Point(4, 124); - this.radioButtonSymbol.Name = "radioButtonSymbol"; - this.radioButtonSymbol.Size = new System.Drawing.Size(59, 17); - this.radioButtonSymbol.TabIndex = 5; - this.radioButtonSymbol.TabStop = true; - this.radioButtonSymbol.Text = "&Symbol"; - this.radioButtonSymbol.UseVisualStyleBackColor = true; - this.radioButtonSymbol.CheckedChanged += new System.EventHandler(this.MainGroup_CheckedChanged); - // - // radioButtonAscii - // - this.radioButtonAscii.AutoSize = true; - this.radioButtonAscii.Location = new System.Drawing.Point(4, 100); - this.radioButtonAscii.Name = "radioButtonAscii"; - this.radioButtonAscii.Size = new System.Drawing.Size(100, 17); - this.radioButtonAscii.TabIndex = 4; - this.radioButtonAscii.TabStop = true; - this.radioButtonAscii.Text = "&ASCII character"; - this.radioButtonAscii.UseVisualStyleBackColor = true; - this.radioButtonAscii.CheckedChanged += new System.EventHandler(this.MainGroup_CheckedChanged); - // - // radioButtonBinary - // - this.radioButtonBinary.AutoSize = true; - this.radioButtonBinary.Location = new System.Drawing.Point(4, 76); - this.radioButtonBinary.Name = "radioButtonBinary"; - this.radioButtonBinary.Size = new System.Drawing.Size(54, 17); - this.radioButtonBinary.TabIndex = 3; - this.radioButtonBinary.TabStop = true; - this.radioButtonBinary.Text = "&Binary"; - this.radioButtonBinary.UseVisualStyleBackColor = true; - this.radioButtonBinary.CheckedChanged += new System.EventHandler(this.MainGroup_CheckedChanged); - // - // radioButtonDecimal - // - this.radioButtonDecimal.AutoSize = true; - this.radioButtonDecimal.Location = new System.Drawing.Point(4, 52); - this.radioButtonDecimal.Name = "radioButtonDecimal"; - this.radioButtonDecimal.Size = new System.Drawing.Size(63, 17); - this.radioButtonDecimal.TabIndex = 2; - this.radioButtonDecimal.TabStop = true; - this.radioButtonDecimal.Text = "&Decimal"; - this.radioButtonDecimal.UseVisualStyleBackColor = true; - this.radioButtonDecimal.CheckedChanged += new System.EventHandler(this.MainGroup_CheckedChanged); - // - // radioButtonHex - // - this.radioButtonHex.AutoSize = true; - this.radioButtonHex.Location = new System.Drawing.Point(4, 28); - this.radioButtonHex.Name = "radioButtonHex"; - this.radioButtonHex.Size = new System.Drawing.Size(86, 17); - this.radioButtonHex.TabIndex = 1; - this.radioButtonHex.TabStop = true; - this.radioButtonHex.Text = "&Hexadecimal"; - this.radioButtonHex.UseVisualStyleBackColor = true; - this.radioButtonHex.CheckedChanged += new System.EventHandler(this.MainGroup_CheckedChanged); - // - // radioButtonDefault - // - this.radioButtonDefault.AutoSize = true; - this.radioButtonDefault.Location = new System.Drawing.Point(4, 4); - this.radioButtonDefault.Name = "radioButtonDefault"; - this.radioButtonDefault.Size = new System.Drawing.Size(59, 17); - this.radioButtonDefault.TabIndex = 0; - this.radioButtonDefault.TabStop = true; - this.radioButtonDefault.Text = "&Default"; - this.radioButtonDefault.UseVisualStyleBackColor = true; - this.radioButtonDefault.CheckedChanged += new System.EventHandler(this.MainGroup_CheckedChanged); - // - // selectFormatLabel - // - this.selectFormatLabel.AutoSize = true; - this.selectFormatLabel.Location = new System.Drawing.Point(13, 13); - this.selectFormatLabel.Name = "selectFormatLabel"; - this.selectFormatLabel.Size = new System.Drawing.Size(114, 13); - this.selectFormatLabel.TabIndex = 0; - this.selectFormatLabel.Text = "Select operand format:"; - // - // previewLabel - // - this.previewLabel.AutoSize = true; - this.previewLabel.Location = new System.Drawing.Point(11, 210); - this.previewLabel.Name = "previewLabel"; - this.previewLabel.Size = new System.Drawing.Size(48, 13); - this.previewLabel.TabIndex = 1; - this.previewLabel.Text = "Preview:"; - // - // previewTextBox - // - this.previewTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.previewTextBox.Enabled = false; - this.previewTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.previewTextBox.Location = new System.Drawing.Point(66, 208); - this.previewTextBox.Name = "previewTextBox"; - this.previewTextBox.Size = new System.Drawing.Size(207, 20); - this.previewTextBox.TabIndex = 2; - // - // symbolShortcutsGroupBox - // - this.symbolShortcutsGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.symbolShortcutsGroupBox.Controls.Add(this.operandAndProjRadioButton); - this.symbolShortcutsGroupBox.Controls.Add(this.operandAndLabelRadioButton); - this.symbolShortcutsGroupBox.Controls.Add(this.labelInsteadRadioButton); - this.symbolShortcutsGroupBox.Controls.Add(this.operandOnlyRadioButton); - this.symbolShortcutsGroupBox.Location = new System.Drawing.Point(13, 248); - this.symbolShortcutsGroupBox.Name = "symbolShortcutsGroupBox"; - this.symbolShortcutsGroupBox.Size = new System.Drawing.Size(261, 118); - this.symbolShortcutsGroupBox.TabIndex = 5; - this.symbolShortcutsGroupBox.TabStop = false; - this.symbolShortcutsGroupBox.Text = "Symbol Shortcuts"; - // - // operandAndProjRadioButton - // - this.operandAndProjRadioButton.AutoSize = true; - this.operandAndProjRadioButton.Location = new System.Drawing.Point(7, 92); - this.operandAndProjRadioButton.Name = "operandAndProjRadioButton"; - this.operandAndProjRadioButton.Size = new System.Drawing.Size(212, 17); - this.operandAndProjRadioButton.TabIndex = 3; - this.operandAndProjRadioButton.TabStop = true; - this.operandAndProjRadioButton.Text = "Set operand AND create &project symbol"; - this.operandAndProjRadioButton.UseVisualStyleBackColor = true; - // - // operandAndLabelRadioButton - // - this.operandAndLabelRadioButton.AutoSize = true; - this.operandAndLabelRadioButton.Location = new System.Drawing.Point(7, 68); - this.operandAndLabelRadioButton.Name = "operandAndLabelRadioButton"; - this.operandAndLabelRadioButton.Size = new System.Drawing.Size(249, 17); - this.operandAndLabelRadioButton.TabIndex = 2; - this.operandAndLabelRadioButton.TabStop = true; - this.operandAndLabelRadioButton.Text = "Set &operand AND create label at target address"; - this.operandAndLabelRadioButton.UseVisualStyleBackColor = true; - // - // labelInsteadRadioButton - // - this.labelInsteadRadioButton.AutoSize = true; - this.labelInsteadRadioButton.Location = new System.Drawing.Point(7, 44); - this.labelInsteadRadioButton.Name = "labelInsteadRadioButton"; - this.labelInsteadRadioButton.Size = new System.Drawing.Size(200, 17); - this.labelInsteadRadioButton.TabIndex = 1; - this.labelInsteadRadioButton.TabStop = true; - this.labelInsteadRadioButton.Text = "&Create label at target address instead"; - this.labelInsteadRadioButton.UseVisualStyleBackColor = true; - // - // operandOnlyRadioButton - // - this.operandOnlyRadioButton.AutoSize = true; - this.operandOnlyRadioButton.Location = new System.Drawing.Point(7, 20); - this.operandOnlyRadioButton.Name = "operandOnlyRadioButton"; - this.operandOnlyRadioButton.Size = new System.Drawing.Size(162, 17); - this.operandOnlyRadioButton.TabIndex = 0; - this.operandOnlyRadioButton.TabStop = true; - this.operandOnlyRadioButton.Text = "&Just set the operand (default)"; - this.operandOnlyRadioButton.UseVisualStyleBackColor = true; - // - // EditOperand - // - this.AcceptButton = this.okButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(286, 412); - this.Controls.Add(this.symbolShortcutsGroupBox); - this.Controls.Add(this.previewTextBox); - this.Controls.Add(this.previewLabel); - this.Controls.Add(this.selectFormatLabel); - this.Controls.Add(this.mainRadioPanel); - this.Controls.Add(this.okButton); - this.Controls.Add(this.cancelButton); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "EditOperand"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Edit Instruction Operand"; - this.Load += new System.EventHandler(this.EditOperand_Load); - this.Shown += new System.EventHandler(this.EditOperand_Shown); - this.mainRadioPanel.ResumeLayout(false); - this.mainRadioPanel.PerformLayout(); - this.symbolPartPanel.ResumeLayout(false); - this.symbolPartPanel.PerformLayout(); - this.symbolShortcutsGroupBox.ResumeLayout(false); - this.symbolShortcutsGroupBox.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Button cancelButton; - private System.Windows.Forms.Button okButton; - private System.Windows.Forms.Panel mainRadioPanel; - private System.Windows.Forms.TextBox symbolTextBox; - private System.Windows.Forms.RadioButton radioButtonSymbol; - private System.Windows.Forms.RadioButton radioButtonAscii; - private System.Windows.Forms.RadioButton radioButtonBinary; - private System.Windows.Forms.RadioButton radioButtonDecimal; - private System.Windows.Forms.RadioButton radioButtonHex; - private System.Windows.Forms.RadioButton radioButtonDefault; - private System.Windows.Forms.Label selectFormatLabel; - private System.Windows.Forms.Label previewLabel; - private System.Windows.Forms.TextBox previewTextBox; - private System.Windows.Forms.Panel symbolPartPanel; - private System.Windows.Forms.RadioButton radioButtonBank; - private System.Windows.Forms.RadioButton radioButtonHigh; - private System.Windows.Forms.RadioButton radioButtonLow; - private System.Windows.Forms.GroupBox symbolShortcutsGroupBox; - private System.Windows.Forms.RadioButton operandAndProjRadioButton; - private System.Windows.Forms.RadioButton operandAndLabelRadioButton; - private System.Windows.Forms.RadioButton labelInsteadRadioButton; - private System.Windows.Forms.RadioButton operandOnlyRadioButton; - } -} \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditOperand.cs b/SourceGenWF/AppForms/EditOperand.cs deleted file mode 100644 index 2800c02..0000000 --- a/SourceGenWF/AppForms/EditOperand.cs +++ /dev/null @@ -1,541 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Diagnostics; -using System.Text; -using System.Windows.Forms; - -using Asm65; - -namespace SourceGenWF.AppForms { - public partial class EditOperand : Form { - /// - /// In/out. May be null on entry if the offset doesn't have a format descriptor - /// specified. Will be null on exit if "default" is selected. - /// - public FormatDescriptor FormatDescriptor { get; set; } - - public enum SymbolShortcutAction { - None = 0, CreateLabelInstead, CreateLabelAlso, CreateProjectSymbolAlso - } - - /// - /// Remember the last option we used. - /// - private static SymbolShortcutAction sLastAction = SymbolShortcutAction.None; - - /// - /// On OK dialog exit, specifies that an additional action should be taken. - /// - public SymbolShortcutAction ShortcutAction { get; private set; } - - /// - /// Additional argument, meaning dependent on ShortcutAction. This will either be - /// the target label offset or the project symbol value. - /// - public int ShortcutArg { get; private set; } - - /// - /// Width of full instruction, including opcode. - /// - private int mInstructionLength; - - /// - /// Number of hexadecimal digits to show in the preview. Sometimes you want - /// to force this to be longer or shorter than InstructionLength would indicate, - /// e.g. "BRA $1000" has a 1-byte operand. - /// - private int mPreviewHexDigits; - - /// - /// Operand value, extracted from file data. For a relative branch, this will be - /// an address instead. Only used for preview window. - /// - private int mOperandValue; - - /// - /// Is the operand an immediate value? If so, we enable the symbol part selection. - /// - private bool mIsExtendedImmediate; - - /// - /// Is the operand a PC relative offset? - /// - private bool mIsPcRelative; - - /// - /// Special handling for block move instructions (MVN/MVP). - /// - private bool mIsBlockMove; - - /// - /// If set, show a '#' in the preview indow. - /// - private bool mShowHashPrefix; - - ///// - ///// Symbol table to use when resolving symbolic values. - ///// - //private SymbolTable SymbolTable { get; set; } - - /// - /// Project reference. - /// - private DisasmProject mProject; - - /// - /// Formatter to use when displaying addresses and hex values. - /// - private Formatter mFormatter; - - /// - /// Copy of operand Anattribs. - /// - private Anattrib mAttr; - - /// - /// Set this during initial control configuration, so we know to ignore the CheckedChanged - /// events. - /// - private bool mIsInitialSetup; - - /// - /// Set to true if the user has entered a symbol that matches an auto-generated symbol. - /// - private bool mIsSymbolAuto; - - - public EditOperand(int offset, DisasmProject project, Asm65.Formatter formatter) { - InitializeComponent(); - - mProject = project; - mFormatter = formatter; - - // Configure the appearance. - mAttr = mProject.GetAnattrib(offset); - OpDef op = mProject.CpuDef.GetOpDef(mProject.FileData[offset]); - mInstructionLength = mAttr.Length; - mPreviewHexDigits = (mAttr.Length - 1) * 2; - if (mAttr.OperandAddress >= 0) { - // Use this as the operand value when available. This lets us present - // relative branch instructions in the expected form. - mOperandValue = mAttr.OperandAddress; - - if (op.AddrMode == OpDef.AddressMode.PCRel) { - mPreviewHexDigits = 4; - mIsPcRelative = true; - } else if (op.AddrMode == OpDef.AddressMode.PCRelLong || - op.AddrMode == OpDef.AddressMode.StackPCRelLong) { - mIsPcRelative = true; - } - } else { - int opVal = op.GetOperand(mProject.FileData, offset, mAttr.StatusFlags); - mOperandValue = opVal; - if (op.AddrMode == OpDef.AddressMode.BlockMove) { - // MVN and MVP screw things up by having two operands in one instruction. - // We deal with this by passing in the value from the second byte - // (source bank) as the value, and applying the chosen format to both bytes. - mIsBlockMove = true; - mOperandValue = opVal >> 8; - mPreviewHexDigits = 2; - } - } - mIsExtendedImmediate = op.IsExtendedImmediate; // Imm, PEA, MVN/MVP - mShowHashPrefix = op.IsImmediate; // just Imm - } - - private void EditOperand_Load(object sender, EventArgs e) { - mIsInitialSetup = true; - - // Can this be represented as high or low ASCII? - radioButtonAscii.Enabled = CommonUtil.TextUtil.IsHiLoAscii(mOperandValue); - - // Configure the dialog from the FormatDescriptor, if one is available. - SetControlsFromDescriptor(FormatDescriptor); - - // Do this whether or not symbol is checked -- want to have this set when the - // dialog is initially in default format. - switch (sLastAction) { - case SymbolShortcutAction.CreateLabelInstead: - labelInsteadRadioButton.Checked = true; - break; - case SymbolShortcutAction.CreateLabelAlso: - operandAndLabelRadioButton.Checked = true; - break; - case SymbolShortcutAction.CreateProjectSymbolAlso: - operandAndProjRadioButton.Checked = true; - break; - default: - operandOnlyRadioButton.Checked = true; - break; - } - - mIsInitialSetup = false; - UpdateControls(); - } - - private void EditOperand_Shown(object sender, EventArgs e) { - // Start with the focus in the text box. This way they can start typing - // immediately. - symbolTextBox.Focus(); - } - - private void symbolTextBox_TextChanged(object sender, EventArgs e) { - // Make sure Symbol is checked if they're typing text in. - radioButtonSymbol.Checked = true; - UpdateControls(); - } - - /// - /// Handles CheckedChanged event for all radio buttons in main group. - /// - private void MainGroup_CheckedChanged(object sender, EventArgs e) { - // Enable/disable the low/high/bank radio group. - // Update preview window. - UpdateControls(); - } - - /// - /// Handles CheckedChanged event for all radio buttons in symbol-part group. - /// - private void PartGroup_CheckedChanged(object sender, EventArgs e) { - // Update preview window. - UpdateControls(); - } - - private void okButton_Click(object sender, EventArgs e) { - FormatDescriptor = CreateDescriptorFromControls(); - - // - // Extract the current shortcut action. For dialog configuration purposes we - // want to capture the current state. For the caller, we force it to "none" - // if we're not using a symbol format. - // - SymbolShortcutAction action = SymbolShortcutAction.None; - if (labelInsteadRadioButton.Checked) { - action = SymbolShortcutAction.CreateLabelInstead; - } else if (operandAndLabelRadioButton.Checked) { - action = SymbolShortcutAction.CreateLabelAlso; - } else if (operandAndProjRadioButton.Checked) { - action = SymbolShortcutAction.CreateProjectSymbolAlso; - } else if (operandOnlyRadioButton.Checked) { - action = SymbolShortcutAction.None; - } else { - Debug.Assert(false); - action = SymbolShortcutAction.None; - } - sLastAction = action; - - if (radioButtonSymbol.Checked && FormatDescriptor != null) { - // Only report a shortcut action if they've entered a symbol. If they - // checked symbol but left the field blank, they're just trying to delete - // the format. - ShortcutAction = action; - } else { - ShortcutAction = SymbolShortcutAction.None; - } - } - - /// - /// Updates all of the controls to reflect the current internal state. - /// - private void UpdateControls() { - if (mIsInitialSetup) { - return; - } - symbolPartPanel.Enabled = radioButtonSymbol.Checked && mIsExtendedImmediate; - symbolShortcutsGroupBox.Enabled = radioButtonSymbol.Checked; - - SetPreviewText(); - - bool isOk = true; - if (radioButtonSymbol.Checked) { - // Just check for correct format. References to non-existent labels are allowed. - // - // We try to block references to auto labels, but it's possible to get around it - // (replace auto label with user label, reference non-existent auto label, - // remove user label). We could try harder, but currently not necessary. - isOk = !mIsSymbolAuto && Asm65.Label.ValidateLabel(symbolTextBox.Text); - - // Allow empty strings as a way to delete the label and return to "default". - if (string.IsNullOrEmpty(symbolTextBox.Text)) { - isOk = true; - } - - ConfigureSymbolShortcuts(); - } - okButton.Enabled = isOk; - } - - /// - /// Sets the text displayed in the "preview" text box. - /// - private void SetPreviewText() { - //symbolValueLabel.Text = string.Empty; - mIsSymbolAuto = false; - - FormatDescriptor dfd = CreateDescriptorFromControls(); - if (dfd == null) { - // Default format. We can't actually know what this look like, so just - // clear the box. - previewTextBox.Text = string.Empty; - return; - } - - if (dfd.FormatSubType == FormatDescriptor.SubType.Symbol && - string.IsNullOrEmpty(dfd.SymbolRef.Label)) { - // no label yet, nothing to show - previewTextBox.Text = string.Empty; - return; - } - - StringBuilder preview = new StringBuilder(); - if (mShowHashPrefix) { - preview.Append('#'); - } - - switch (dfd.FormatSubType) { - case FormatDescriptor.SubType.Hex: - preview.Append(mFormatter.FormatHexValue(mOperandValue, mPreviewHexDigits)); - break; - case FormatDescriptor.SubType.Decimal: - preview.Append(mFormatter.FormatDecimalValue(mOperandValue)); - break; - case FormatDescriptor.SubType.Binary: - preview.Append(mFormatter.FormatBinaryValue(mOperandValue, 8)); - break; - case FormatDescriptor.SubType.Ascii: - preview.Append(mFormatter.FormatAsciiOrHex(mOperandValue)); - break; - case FormatDescriptor.SubType.Symbol: - if (mProject.SymbolTable.TryGetValue(dfd.SymbolRef.Label, out Symbol sym)) { - if (mIsBlockMove) { - // For a 24-bit symbol, we grab the high byte. This is the - // expected behavior, according to Eyes & Lichty; see the - // explanation of the MVP instruction. For an 8-bit symbol - // the assembler just takes the value. - // TODO(someday): allow a different symbol for each part of the - // operand. - if (sym.Value > 0xff) { - radioButtonBank.Checked = true; - } else { - radioButtonLow.Checked = true; - } - dfd = CreateDescriptorFromControls(); - } - - // Hack to make relative branches look right in the preview window. - // Otherwise they show up like " - /// Configures the buttons in the "symbol shortcuts" group box. The entire box is - /// disabled unless "symbol" is selected. Other options are selectively enabled or - /// disabled as appropriate for the current input. If we disable the selection option, - /// the selection will be reset to default. - /// - private void ConfigureSymbolShortcuts() { - // operandOnlyRadioButton: always enabled - // labelInsteadRadioButton: symbol is unknown and operand address has no label - // operandAndLabelRadioButton: same as labelInstead - // operandAndProjRadioButton: symbol is unknown and operand address is outside project - - string labelStr = symbolTextBox.Text; - ShortcutArg = -1; - - // Is this a known symbol? If so, disable most options and bail. - if (mProject.SymbolTable.TryGetValue(labelStr, out Symbol sym)) { - labelInsteadRadioButton.Enabled = operandAndLabelRadioButton.Enabled = - operandAndProjRadioButton.Enabled = false; - operandOnlyRadioButton.Checked = true; - return; - } - - if (mAttr.OperandOffset >= 0) { - // Operand target is inside the file. Does the target offset already have a label? - int targetOffset = - DataAnalysis.GetBaseOperandOffset(mProject, mAttr.OperandOffset); - bool hasLabel = mProject.UserLabels.ContainsKey(targetOffset); - labelInsteadRadioButton.Enabled = operandAndLabelRadioButton.Enabled = - !hasLabel; - operandAndProjRadioButton.Enabled = false; - ShortcutArg = targetOffset; - } else if (mAttr.OperandAddress >= 0) { - // Operand target is outside the file. - labelInsteadRadioButton.Enabled = operandAndLabelRadioButton.Enabled = false; - operandAndProjRadioButton.Enabled = true; - ShortcutArg = mAttr.OperandAddress; - } else { - // Probably an immediate operand. - labelInsteadRadioButton.Enabled = operandAndLabelRadioButton.Enabled = - operandAndProjRadioButton.Enabled = false; - } - - // Select the default option if the currently-selected option is no longer available. - if ((labelInsteadRadioButton.Checked && !labelInsteadRadioButton.Enabled) || - (operandAndLabelRadioButton.Checked && !operandAndLabelRadioButton.Enabled) || - (operandAndProjRadioButton.Checked && !operandAndProjRadioButton.Enabled)) { - operandOnlyRadioButton.Checked = true; - } - } - - /// - /// Configures the dialog controls based on the provided format descriptor. - /// - /// FormatDescriptor to use. - private void SetControlsFromDescriptor(FormatDescriptor dfd) { - Debug.Assert(mIsInitialSetup); - radioButtonLow.Checked = true; - - if (dfd == null) { - radioButtonDefault.Checked = true; - return; - } - - // NOTE: it's entirely possible to have a weird format (e.g. string) if the - // instruction used to be hinted as data. Handle it gracefully. - switch (dfd.FormatType) { - case FormatDescriptor.Type.NumericLE: - switch (dfd.FormatSubType) { - case FormatDescriptor.SubType.Hex: - radioButtonHex.Checked = true; - break; - case FormatDescriptor.SubType.Decimal: - radioButtonDecimal.Checked = true; - break; - case FormatDescriptor.SubType.Binary: - radioButtonBinary.Checked = true; - break; - case FormatDescriptor.SubType.Ascii: - radioButtonAscii.Checked = true; - break; - case FormatDescriptor.SubType.Symbol: - Debug.Assert(dfd.HasSymbol); - radioButtonSymbol.Checked = true; - switch (dfd.SymbolRef.ValuePart) { - case WeakSymbolRef.Part.Low: - radioButtonLow.Checked = true; - break; - case WeakSymbolRef.Part.High: - radioButtonHigh.Checked = true; - break; - case WeakSymbolRef.Part.Bank: - radioButtonBank.Checked = true; - break; - default: - Debug.Assert(false); - break; - } - symbolTextBox.Text = dfd.SymbolRef.Label; - break; - case FormatDescriptor.SubType.None: - default: - // Unexpected; call it hex. - radioButtonHex.Checked = true; - break; - } - break; - case FormatDescriptor.Type.NumericBE: - case FormatDescriptor.Type.String: - case FormatDescriptor.Type.Fill: - default: - // Unexpected; used to be data? - radioButtonDefault.Checked = true; - break; - } - } - - /// - /// Creates a FormatDescriptor from the current state of the dialog controls. - /// - /// New FormatDescriptor. - private FormatDescriptor CreateDescriptorFromControls() { - if (radioButtonSymbol.Checked) { - if (string.IsNullOrEmpty(symbolTextBox.Text)) { - // empty symbol --> default format (intuitive way to delete label reference) - return null; - } - WeakSymbolRef.Part part; - if (radioButtonLow.Checked) { - part = WeakSymbolRef.Part.Low; - } else if (radioButtonHigh.Checked) { - part = WeakSymbolRef.Part.High; - } else if (radioButtonBank.Checked) { - part = WeakSymbolRef.Part.Bank; - } else { - Debug.Assert(false); - part = WeakSymbolRef.Part.Low; - } - return FormatDescriptor.Create(mInstructionLength, - new WeakSymbolRef(symbolTextBox.Text, part), false); - } - - FormatDescriptor.SubType subType; - if (radioButtonDefault.Checked) { - return null; - } else if (radioButtonHex.Checked) { - subType = FormatDescriptor.SubType.Hex; - } else if (radioButtonDecimal.Checked) { - subType = FormatDescriptor.SubType.Decimal; - } else if (radioButtonBinary.Checked) { - subType = FormatDescriptor.SubType.Binary; - } else if (radioButtonAscii.Checked) { - subType = FormatDescriptor.SubType.Ascii; - } else if (radioButtonSymbol.Checked) { - subType = FormatDescriptor.SubType.Symbol; - } else { - Debug.Assert(false); - subType = FormatDescriptor.SubType.None; - } - - return FormatDescriptor.Create(mInstructionLength, - FormatDescriptor.Type.NumericLE, subType); - } - } -} diff --git a/SourceGenWF/AppForms/EditOperand.resx b/SourceGenWF/AppForms/EditOperand.resx deleted file mode 100644 index 1af7de1..0000000 --- a/SourceGenWF/AppForms/EditOperand.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditProjectProperties.Designer.cs b/SourceGenWF/AppForms/EditProjectProperties.Designer.cs deleted file mode 100644 index 15e6568..0000000 --- a/SourceGenWF/AppForms/EditProjectProperties.Designer.cs +++ /dev/null @@ -1,676 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AppForms { - partial class EditProjectProperties { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - System.Windows.Forms.ListViewItem listViewItem1 = new System.Windows.Forms.ListViewItem(new string[] { - "0123456789AB", - "%00000000", - "Const", - "This is a test to gauge column widths"}, -1); - this.tabControl1 = new System.Windows.Forms.TabControl(); - this.generalTab = new System.Windows.Forms.TabPage(); - this.miscGroupBox = new System.Windows.Forms.GroupBox(); - this.autoLabelStyleComboBox = new System.Windows.Forms.ComboBox(); - this.autoLabelStyleLabel = new System.Windows.Forms.Label(); - this.analysisGroupBox = new System.Windows.Forms.GroupBox(); - this.seekAltTargetCheckBox = new System.Windows.Forms.CheckBox(); - this.minStringCharsComboBox = new System.Windows.Forms.ComboBox(); - this.minCharsForStringLabel = new System.Windows.Forms.Label(); - this.analyzeUncategorizedCheckBox = new System.Windows.Forms.CheckBox(); - this.entryFlagsGroupBox = new System.Windows.Forms.GroupBox(); - this.flagsLabel = new System.Windows.Forms.Label(); - this.currentFlagsLabel = new System.Windows.Forms.Label(); - this.changeFlagButton = new System.Windows.Forms.Button(); - this.cpuGroupBox = new System.Windows.Forms.GroupBox(); - this.undocInstrCheckBox = new System.Windows.Forms.CheckBox(); - this.cpuComboBox = new System.Windows.Forms.ComboBox(); - this.symbolsTab = new System.Windows.Forms.TabPage(); - this.importSymbolsButton = new System.Windows.Forms.Button(); - this.editSymbolButton = new System.Windows.Forms.Button(); - this.removeSymbolButton = new System.Windows.Forms.Button(); - this.newSymbolButton = new System.Windows.Forms.Button(); - this.symbolsDefinedLabel = new System.Windows.Forms.Label(); - this.projectSymbolsListView = new System.Windows.Forms.ListView(); - this.nameColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.valueColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.typeColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.commentColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.symbolFilesTab = new System.Windows.Forms.TabPage(); - this.symbolFileDownButton = new System.Windows.Forms.Button(); - this.symbolFileUpButton = new System.Windows.Forms.Button(); - this.addSymbolFilesButton = new System.Windows.Forms.Button(); - this.symbolFileRemoveButton = new System.Windows.Forms.Button(); - this.symbolFilesListBox = new System.Windows.Forms.ListBox(); - this.configuredFilesLabel = new System.Windows.Forms.Label(); - this.extensionScriptsTab = new System.Windows.Forms.TabPage(); - this.extensionScriptRemoveButton = new System.Windows.Forms.Button(); - this.addExtensionScriptsButton = new System.Windows.Forms.Button(); - this.extensionScriptsListBox = new System.Windows.Forms.ListBox(); - this.configuredScriptsLabel = new System.Windows.Forms.Label(); - this.labelUndoRedoNote = new System.Windows.Forms.Label(); - this.cancelButton = new System.Windows.Forms.Button(); - this.okButton = new System.Windows.Forms.Button(); - this.applyButton = new System.Windows.Forms.Button(); - this.tabControl1.SuspendLayout(); - this.generalTab.SuspendLayout(); - this.miscGroupBox.SuspendLayout(); - this.analysisGroupBox.SuspendLayout(); - this.entryFlagsGroupBox.SuspendLayout(); - this.cpuGroupBox.SuspendLayout(); - this.symbolsTab.SuspendLayout(); - this.symbolFilesTab.SuspendLayout(); - this.extensionScriptsTab.SuspendLayout(); - this.SuspendLayout(); - // - // tabControl1 - // - this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.tabControl1.Controls.Add(this.generalTab); - this.tabControl1.Controls.Add(this.symbolsTab); - this.tabControl1.Controls.Add(this.symbolFilesTab); - this.tabControl1.Controls.Add(this.extensionScriptsTab); - this.tabControl1.Location = new System.Drawing.Point(2, 2); - this.tabControl1.Multiline = true; - this.tabControl1.Name = "tabControl1"; - this.tabControl1.SelectedIndex = 0; - this.tabControl1.Size = new System.Drawing.Size(622, 318); - this.tabControl1.TabIndex = 0; - // - // generalTab - // - this.generalTab.Controls.Add(this.miscGroupBox); - this.generalTab.Controls.Add(this.analysisGroupBox); - this.generalTab.Controls.Add(this.entryFlagsGroupBox); - this.generalTab.Controls.Add(this.cpuGroupBox); - this.generalTab.Location = new System.Drawing.Point(4, 22); - this.generalTab.Name = "generalTab"; - this.generalTab.Padding = new System.Windows.Forms.Padding(3); - this.generalTab.Size = new System.Drawing.Size(614, 292); - this.generalTab.TabIndex = 0; - this.generalTab.Text = "General"; - this.generalTab.UseVisualStyleBackColor = true; - // - // miscGroupBox - // - this.miscGroupBox.Controls.Add(this.autoLabelStyleComboBox); - this.miscGroupBox.Controls.Add(this.autoLabelStyleLabel); - this.miscGroupBox.Location = new System.Drawing.Point(7, 177); - this.miscGroupBox.Name = "miscGroupBox"; - this.miscGroupBox.Size = new System.Drawing.Size(422, 100); - this.miscGroupBox.TabIndex = 3; - this.miscGroupBox.TabStop = false; - this.miscGroupBox.Text = "Miscellaneous"; - // - // autoLabelStyleComboBox - // - this.autoLabelStyleComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.autoLabelStyleComboBox.FormattingEnabled = true; - this.autoLabelStyleComboBox.Items.AddRange(new object[] { - "Simple (\"L1234\")", - "Annotated (\"W_1234\")", - "Fully Annotated (\"DWR_1234\")"}); - this.autoLabelStyleComboBox.Location = new System.Drawing.Point(98, 19); - this.autoLabelStyleComboBox.Name = "autoLabelStyleComboBox"; - this.autoLabelStyleComboBox.Size = new System.Drawing.Size(318, 21); - this.autoLabelStyleComboBox.TabIndex = 1; - this.autoLabelStyleComboBox.SelectedIndexChanged += new System.EventHandler(this.autoLabelStyleComboBox_SelectedIndexChanged); - // - // autoLabelStyleLabel - // - this.autoLabelStyleLabel.AutoSize = true; - this.autoLabelStyleLabel.Location = new System.Drawing.Point(6, 22); - this.autoLabelStyleLabel.Name = "autoLabelStyleLabel"; - this.autoLabelStyleLabel.Size = new System.Drawing.Size(81, 13); - this.autoLabelStyleLabel.TabIndex = 0; - this.autoLabelStyleLabel.Text = "Auto-label style:"; - // - // analysisGroupBox - // - this.analysisGroupBox.Controls.Add(this.seekAltTargetCheckBox); - this.analysisGroupBox.Controls.Add(this.minStringCharsComboBox); - this.analysisGroupBox.Controls.Add(this.minCharsForStringLabel); - this.analysisGroupBox.Controls.Add(this.analyzeUncategorizedCheckBox); - this.analysisGroupBox.Location = new System.Drawing.Point(225, 7); - this.analysisGroupBox.Name = "analysisGroupBox"; - this.analysisGroupBox.Size = new System.Drawing.Size(204, 163); - this.analysisGroupBox.TabIndex = 2; - this.analysisGroupBox.TabStop = false; - this.analysisGroupBox.Text = "Analysis Parameters"; - // - // seekAltTargetCheckBox - // - this.seekAltTargetCheckBox.AutoSize = true; - this.seekAltTargetCheckBox.Location = new System.Drawing.Point(7, 45); - this.seekAltTargetCheckBox.Name = "seekAltTargetCheckBox"; - this.seekAltTargetCheckBox.Size = new System.Drawing.Size(121, 17); - this.seekAltTargetCheckBox.TabIndex = 3; - this.seekAltTargetCheckBox.Text = "Seek nearby targets"; - this.seekAltTargetCheckBox.UseVisualStyleBackColor = true; - this.seekAltTargetCheckBox.CheckedChanged += new System.EventHandler(this.seekAltTargetCheckBox_CheckedChanged); - // - // minStringCharsComboBox - // - this.minStringCharsComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.minStringCharsComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.minStringCharsComboBox.FormattingEnabled = true; - this.minStringCharsComboBox.Items.AddRange(new object[] { - "None (disabled)", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "10"}); - this.minStringCharsComboBox.Location = new System.Drawing.Point(7, 88); - this.minStringCharsComboBox.Name = "minStringCharsComboBox"; - this.minStringCharsComboBox.Size = new System.Drawing.Size(191, 21); - this.minStringCharsComboBox.TabIndex = 2; - this.minStringCharsComboBox.SelectedIndexChanged += new System.EventHandler(this.minStringCharsComboBox_SelectedIndexChanged); - // - // minCharsForStringLabel - // - this.minCharsForStringLabel.AutoSize = true; - this.minCharsForStringLabel.Location = new System.Drawing.Point(7, 71); - this.minCharsForStringLabel.Name = "minCharsForStringLabel"; - this.minCharsForStringLabel.Size = new System.Drawing.Size(147, 13); - this.minCharsForStringLabel.TabIndex = 1; - this.minCharsForStringLabel.Text = "Minimum characters for string:"; - // - // analyzeUncategorizedCheckBox - // - this.analyzeUncategorizedCheckBox.AutoSize = true; - this.analyzeUncategorizedCheckBox.Location = new System.Drawing.Point(7, 21); - this.analyzeUncategorizedCheckBox.Name = "analyzeUncategorizedCheckBox"; - this.analyzeUncategorizedCheckBox.Size = new System.Drawing.Size(157, 17); - this.analyzeUncategorizedCheckBox.TabIndex = 0; - this.analyzeUncategorizedCheckBox.Text = "Analyze uncategorized data"; - this.analyzeUncategorizedCheckBox.UseVisualStyleBackColor = true; - this.analyzeUncategorizedCheckBox.CheckedChanged += new System.EventHandler(this.analyzeUncategorizedCheckBox_CheckedChanged); - // - // entryFlagsGroupBox - // - this.entryFlagsGroupBox.Controls.Add(this.flagsLabel); - this.entryFlagsGroupBox.Controls.Add(this.currentFlagsLabel); - this.entryFlagsGroupBox.Controls.Add(this.changeFlagButton); - this.entryFlagsGroupBox.Location = new System.Drawing.Point(7, 92); - this.entryFlagsGroupBox.Name = "entryFlagsGroupBox"; - this.entryFlagsGroupBox.Size = new System.Drawing.Size(204, 78); - this.entryFlagsGroupBox.TabIndex = 1; - this.entryFlagsGroupBox.TabStop = false; - this.entryFlagsGroupBox.Text = "Entry Flags"; - // - // flagsLabel - // - this.flagsLabel.AutoSize = true; - this.flagsLabel.Location = new System.Drawing.Point(7, 20); - this.flagsLabel.Name = "flagsLabel"; - this.flagsLabel.Size = new System.Drawing.Size(35, 13); - this.flagsLabel.TabIndex = 0; - this.flagsLabel.Text = "Flags:"; - // - // currentFlagsLabel - // - this.currentFlagsLabel.AutoSize = true; - this.currentFlagsLabel.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.currentFlagsLabel.Location = new System.Drawing.Point(38, 21); - this.currentFlagsLabel.Name = "currentFlagsLabel"; - this.currentFlagsLabel.Size = new System.Drawing.Size(163, 13); - this.currentFlagsLabel.TabIndex = 1; - this.currentFlagsLabel.Text = "N- V- M- X- D- I- Z- C- E-"; - // - // changeFlagButton - // - this.changeFlagButton.Location = new System.Drawing.Point(10, 42); - this.changeFlagButton.Name = "changeFlagButton"; - this.changeFlagButton.Size = new System.Drawing.Size(91, 23); - this.changeFlagButton.TabIndex = 2; - this.changeFlagButton.Text = "Change"; - this.changeFlagButton.UseVisualStyleBackColor = true; - this.changeFlagButton.Click += new System.EventHandler(this.changeFlagButton_Click); - // - // cpuGroupBox - // - this.cpuGroupBox.Controls.Add(this.undocInstrCheckBox); - this.cpuGroupBox.Controls.Add(this.cpuComboBox); - this.cpuGroupBox.Location = new System.Drawing.Point(7, 7); - this.cpuGroupBox.Name = "cpuGroupBox"; - this.cpuGroupBox.Size = new System.Drawing.Size(204, 78); - this.cpuGroupBox.TabIndex = 0; - this.cpuGroupBox.TabStop = false; - this.cpuGroupBox.Text = "CPU"; - // - // undocInstrCheckBox - // - this.undocInstrCheckBox.AutoSize = true; - this.undocInstrCheckBox.Location = new System.Drawing.Point(7, 47); - this.undocInstrCheckBox.Name = "undocInstrCheckBox"; - this.undocInstrCheckBox.Size = new System.Drawing.Size(189, 17); - this.undocInstrCheckBox.TabIndex = 1; - this.undocInstrCheckBox.Text = "Enable undocumented instructions"; - this.undocInstrCheckBox.UseVisualStyleBackColor = true; - this.undocInstrCheckBox.CheckedChanged += new System.EventHandler(this.undocInstrCheckBox_CheckedChanged); - // - // cpuComboBox - // - this.cpuComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.cpuComboBox.FormattingEnabled = true; - this.cpuComboBox.Items.AddRange(new object[] { - "MOS 6502", - "WDC W65C02S", - "WDC W65C816S"}); - this.cpuComboBox.Location = new System.Drawing.Point(6, 19); - this.cpuComboBox.Name = "cpuComboBox"; - this.cpuComboBox.Size = new System.Drawing.Size(190, 21); - this.cpuComboBox.TabIndex = 0; - this.cpuComboBox.SelectedIndexChanged += new System.EventHandler(this.cpuComboBox_SelectedIndexChanged); - // - // symbolsTab - // - this.symbolsTab.Controls.Add(this.importSymbolsButton); - this.symbolsTab.Controls.Add(this.editSymbolButton); - this.symbolsTab.Controls.Add(this.removeSymbolButton); - this.symbolsTab.Controls.Add(this.newSymbolButton); - this.symbolsTab.Controls.Add(this.symbolsDefinedLabel); - this.symbolsTab.Controls.Add(this.projectSymbolsListView); - this.symbolsTab.Location = new System.Drawing.Point(4, 22); - this.symbolsTab.Name = "symbolsTab"; - this.symbolsTab.Padding = new System.Windows.Forms.Padding(3); - this.symbolsTab.Size = new System.Drawing.Size(614, 292); - this.symbolsTab.TabIndex = 1; - this.symbolsTab.Text = "Project Symbols"; - this.symbolsTab.UseVisualStyleBackColor = true; - // - // importSymbolsButton - // - this.importSymbolsButton.Location = new System.Drawing.Point(506, 158); - this.importSymbolsButton.Name = "importSymbolsButton"; - this.importSymbolsButton.Size = new System.Drawing.Size(102, 23); - this.importSymbolsButton.TabIndex = 5; - this.importSymbolsButton.Text = "&Import..."; - this.importSymbolsButton.UseVisualStyleBackColor = true; - this.importSymbolsButton.Click += new System.EventHandler(this.importSymbolsButton_Click); - // - // editSymbolButton - // - this.editSymbolButton.Location = new System.Drawing.Point(506, 52); - this.editSymbolButton.Name = "editSymbolButton"; - this.editSymbolButton.Size = new System.Drawing.Size(102, 23); - this.editSymbolButton.TabIndex = 3; - this.editSymbolButton.Text = "&Edit Symbol..."; - this.editSymbolButton.UseVisualStyleBackColor = true; - this.editSymbolButton.Click += new System.EventHandler(this.editSymbolButton_Click); - // - // removeSymbolButton - // - this.removeSymbolButton.Location = new System.Drawing.Point(506, 81); - this.removeSymbolButton.Name = "removeSymbolButton"; - this.removeSymbolButton.Size = new System.Drawing.Size(102, 23); - this.removeSymbolButton.TabIndex = 4; - this.removeSymbolButton.Text = "&Remove"; - this.removeSymbolButton.UseVisualStyleBackColor = true; - this.removeSymbolButton.Click += new System.EventHandler(this.removeSymbolButton_Click); - // - // newSymbolButton - // - this.newSymbolButton.Location = new System.Drawing.Point(506, 23); - this.newSymbolButton.Name = "newSymbolButton"; - this.newSymbolButton.Size = new System.Drawing.Size(102, 23); - this.newSymbolButton.TabIndex = 2; - this.newSymbolButton.Text = "&New Symbol..."; - this.newSymbolButton.UseVisualStyleBackColor = true; - this.newSymbolButton.Click += new System.EventHandler(this.newSymbolButton_Click); - // - // symbolsDefinedLabel - // - this.symbolsDefinedLabel.AutoSize = true; - this.symbolsDefinedLabel.Location = new System.Drawing.Point(7, 7); - this.symbolsDefinedLabel.Name = "symbolsDefinedLabel"; - this.symbolsDefinedLabel.Size = new System.Drawing.Size(133, 13); - this.symbolsDefinedLabel.TabIndex = 0; - this.symbolsDefinedLabel.Text = "Symbols defined in project:"; - // - // projectSymbolsListView - // - this.projectSymbolsListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.nameColumnHeader, - this.valueColumnHeader, - this.typeColumnHeader, - this.commentColumnHeader}); - this.projectSymbolsListView.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.projectSymbolsListView.FullRowSelect = true; - this.projectSymbolsListView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; - this.projectSymbolsListView.HideSelection = false; - this.projectSymbolsListView.Items.AddRange(new System.Windows.Forms.ListViewItem[] { - listViewItem1}); - this.projectSymbolsListView.Location = new System.Drawing.Point(11, 23); - this.projectSymbolsListView.MultiSelect = false; - this.projectSymbolsListView.Name = "projectSymbolsListView"; - this.projectSymbolsListView.Size = new System.Drawing.Size(489, 259); - this.projectSymbolsListView.TabIndex = 1; - this.projectSymbolsListView.UseCompatibleStateImageBehavior = false; - this.projectSymbolsListView.View = System.Windows.Forms.View.Details; - this.projectSymbolsListView.SelectedIndexChanged += new System.EventHandler(this.projectSymbolsListView_SelectedIndexChanged); - this.projectSymbolsListView.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.projectSymbolsListView_MouseDoubleClick); - // - // nameColumnHeader - // - this.nameColumnHeader.Text = "Name"; - this.nameColumnHeader.Width = 109; - // - // valueColumnHeader - // - this.valueColumnHeader.Text = "Value"; - this.valueColumnHeader.Width = 69; - // - // typeColumnHeader - // - this.typeColumnHeader.Text = "Type"; - this.typeColumnHeader.Width = 42; - // - // commentColumnHeader - // - this.commentColumnHeader.Text = "Comment"; - this.commentColumnHeader.Width = 264; - // - // symbolFilesTab - // - this.symbolFilesTab.Controls.Add(this.symbolFileDownButton); - this.symbolFilesTab.Controls.Add(this.symbolFileUpButton); - this.symbolFilesTab.Controls.Add(this.addSymbolFilesButton); - this.symbolFilesTab.Controls.Add(this.symbolFileRemoveButton); - this.symbolFilesTab.Controls.Add(this.symbolFilesListBox); - this.symbolFilesTab.Controls.Add(this.configuredFilesLabel); - this.symbolFilesTab.Location = new System.Drawing.Point(4, 22); - this.symbolFilesTab.Name = "symbolFilesTab"; - this.symbolFilesTab.Padding = new System.Windows.Forms.Padding(3); - this.symbolFilesTab.Size = new System.Drawing.Size(614, 292); - this.symbolFilesTab.TabIndex = 2; - this.symbolFilesTab.Text = "Symbol Files"; - this.symbolFilesTab.UseVisualStyleBackColor = true; - // - // symbolFileDownButton - // - this.symbolFileDownButton.Location = new System.Drawing.Point(319, 57); - this.symbolFileDownButton.Name = "symbolFileDownButton"; - this.symbolFileDownButton.Size = new System.Drawing.Size(75, 23); - this.symbolFileDownButton.TabIndex = 4; - this.symbolFileDownButton.Text = "Down"; - this.symbolFileDownButton.UseVisualStyleBackColor = true; - this.symbolFileDownButton.Click += new System.EventHandler(this.symbolFileDownButton_Click); - // - // symbolFileUpButton - // - this.symbolFileUpButton.Location = new System.Drawing.Point(319, 28); - this.symbolFileUpButton.Name = "symbolFileUpButton"; - this.symbolFileUpButton.Size = new System.Drawing.Size(75, 23); - this.symbolFileUpButton.TabIndex = 3; - this.symbolFileUpButton.Text = "Up"; - this.symbolFileUpButton.UseVisualStyleBackColor = true; - this.symbolFileUpButton.Click += new System.EventHandler(this.symbolFileUpButton_Click); - // - // addSymbolFilesButton - // - this.addSymbolFilesButton.Location = new System.Drawing.Point(8, 249); - this.addSymbolFilesButton.Name = "addSymbolFilesButton"; - this.addSymbolFilesButton.Size = new System.Drawing.Size(134, 23); - this.addSymbolFilesButton.TabIndex = 2; - this.addSymbolFilesButton.Text = "Add Symbol Files..."; - this.addSymbolFilesButton.UseVisualStyleBackColor = true; - this.addSymbolFilesButton.Click += new System.EventHandler(this.addSymbolFilesButton_Click); - // - // symbolFileRemoveButton - // - this.symbolFileRemoveButton.Location = new System.Drawing.Point(319, 97); - this.symbolFileRemoveButton.Name = "symbolFileRemoveButton"; - this.symbolFileRemoveButton.Size = new System.Drawing.Size(75, 23); - this.symbolFileRemoveButton.TabIndex = 5; - this.symbolFileRemoveButton.Text = "Remove"; - this.symbolFileRemoveButton.UseVisualStyleBackColor = true; - this.symbolFileRemoveButton.Click += new System.EventHandler(this.symbolFileRemoveButton_Click); - // - // symbolFilesListBox - // - this.symbolFilesListBox.FormattingEnabled = true; - this.symbolFilesListBox.Location = new System.Drawing.Point(8, 28); - this.symbolFilesListBox.Name = "symbolFilesListBox"; - this.symbolFilesListBox.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; - this.symbolFilesListBox.Size = new System.Drawing.Size(305, 212); - this.symbolFilesListBox.TabIndex = 1; - this.symbolFilesListBox.SelectedIndexChanged += new System.EventHandler(this.symbolFilesListBox_SelectedIndexChanged); - // - // configuredFilesLabel - // - this.configuredFilesLabel.AutoSize = true; - this.configuredFilesLabel.Location = new System.Drawing.Point(7, 7); - this.configuredFilesLabel.Name = "configuredFilesLabel"; - this.configuredFilesLabel.Size = new System.Drawing.Size(160, 13); - this.configuredFilesLabel.TabIndex = 0; - this.configuredFilesLabel.Text = "Currently configured symbol files:"; - // - // extensionScriptsTab - // - this.extensionScriptsTab.Controls.Add(this.extensionScriptRemoveButton); - this.extensionScriptsTab.Controls.Add(this.addExtensionScriptsButton); - this.extensionScriptsTab.Controls.Add(this.extensionScriptsListBox); - this.extensionScriptsTab.Controls.Add(this.configuredScriptsLabel); - this.extensionScriptsTab.Location = new System.Drawing.Point(4, 22); - this.extensionScriptsTab.Name = "extensionScriptsTab"; - this.extensionScriptsTab.Padding = new System.Windows.Forms.Padding(3); - this.extensionScriptsTab.Size = new System.Drawing.Size(614, 292); - this.extensionScriptsTab.TabIndex = 3; - this.extensionScriptsTab.Text = "Extension Scripts"; - this.extensionScriptsTab.UseVisualStyleBackColor = true; - // - // extensionScriptRemoveButton - // - this.extensionScriptRemoveButton.Location = new System.Drawing.Point(320, 28); - this.extensionScriptRemoveButton.Name = "extensionScriptRemoveButton"; - this.extensionScriptRemoveButton.Size = new System.Drawing.Size(75, 23); - this.extensionScriptRemoveButton.TabIndex = 3; - this.extensionScriptRemoveButton.Text = "Remove"; - this.extensionScriptRemoveButton.UseVisualStyleBackColor = true; - this.extensionScriptRemoveButton.Click += new System.EventHandler(this.extensionScriptRemoveButton_Click); - // - // addExtensionScriptsButton - // - this.addExtensionScriptsButton.Location = new System.Drawing.Point(8, 249); - this.addExtensionScriptsButton.Name = "addExtensionScriptsButton"; - this.addExtensionScriptsButton.Size = new System.Drawing.Size(134, 23); - this.addExtensionScriptsButton.TabIndex = 2; - this.addExtensionScriptsButton.Text = "Add Scripts..."; - this.addExtensionScriptsButton.UseVisualStyleBackColor = true; - this.addExtensionScriptsButton.Click += new System.EventHandler(this.addExtensionScriptsButton_Click); - // - // extensionScriptsListBox - // - this.extensionScriptsListBox.FormattingEnabled = true; - this.extensionScriptsListBox.Location = new System.Drawing.Point(8, 28); - this.extensionScriptsListBox.Name = "extensionScriptsListBox"; - this.extensionScriptsListBox.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; - this.extensionScriptsListBox.Size = new System.Drawing.Size(305, 212); - this.extensionScriptsListBox.TabIndex = 1; - this.extensionScriptsListBox.SelectedIndexChanged += new System.EventHandler(this.extensionScriptsListBox_SelectedIndexChanged); - // - // configuredScriptsLabel - // - this.configuredScriptsLabel.AutoSize = true; - this.configuredScriptsLabel.Location = new System.Drawing.Point(7, 7); - this.configuredScriptsLabel.Name = "configuredScriptsLabel"; - this.configuredScriptsLabel.Size = new System.Drawing.Size(185, 13); - this.configuredScriptsLabel.TabIndex = 0; - this.configuredScriptsLabel.Text = "Currently configured extension scripts:"; - // - // labelUndoRedoNote - // - this.labelUndoRedoNote.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.labelUndoRedoNote.AutoSize = true; - this.labelUndoRedoNote.Location = new System.Drawing.Point(12, 331); - this.labelUndoRedoNote.Name = "labelUndoRedoNote"; - this.labelUndoRedoNote.Size = new System.Drawing.Size(248, 13); - this.labelUndoRedoNote.TabIndex = 1; - this.labelUndoRedoNote.Text = "NOTE: changes are added to the undo/redo buffer"; - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.Location = new System.Drawing.Point(537, 326); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 23); - this.cancelButton.TabIndex = 4; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - // - // okButton - // - this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.okButton.Location = new System.Drawing.Point(456, 326); - this.okButton.Name = "okButton"; - this.okButton.Size = new System.Drawing.Size(75, 23); - this.okButton.TabIndex = 3; - this.okButton.Text = "OK"; - this.okButton.UseVisualStyleBackColor = true; - this.okButton.Click += new System.EventHandler(this.okButton_Click); - // - // applyButton - // - this.applyButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.applyButton.Location = new System.Drawing.Point(354, 326); - this.applyButton.Name = "applyButton"; - this.applyButton.Size = new System.Drawing.Size(75, 23); - this.applyButton.TabIndex = 2; - this.applyButton.Text = "Apply"; - this.applyButton.UseVisualStyleBackColor = true; - this.applyButton.Click += new System.EventHandler(this.applyButton_Click); - // - // EditProjectProperties - // - this.AcceptButton = this.okButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(624, 361); - this.Controls.Add(this.applyButton); - this.Controls.Add(this.okButton); - this.Controls.Add(this.cancelButton); - this.Controls.Add(this.labelUndoRedoNote); - this.Controls.Add(this.tabControl1); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "EditProjectProperties"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Edit Project Properties"; - this.Load += new System.EventHandler(this.EditProperties_Load); - this.tabControl1.ResumeLayout(false); - this.generalTab.ResumeLayout(false); - this.miscGroupBox.ResumeLayout(false); - this.miscGroupBox.PerformLayout(); - this.analysisGroupBox.ResumeLayout(false); - this.analysisGroupBox.PerformLayout(); - this.entryFlagsGroupBox.ResumeLayout(false); - this.entryFlagsGroupBox.PerformLayout(); - this.cpuGroupBox.ResumeLayout(false); - this.cpuGroupBox.PerformLayout(); - this.symbolsTab.ResumeLayout(false); - this.symbolsTab.PerformLayout(); - this.symbolFilesTab.ResumeLayout(false); - this.symbolFilesTab.PerformLayout(); - this.extensionScriptsTab.ResumeLayout(false); - this.extensionScriptsTab.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.TabControl tabControl1; - private System.Windows.Forms.TabPage generalTab; - private System.Windows.Forms.ComboBox cpuComboBox; - private System.Windows.Forms.TabPage symbolsTab; - private System.Windows.Forms.Label labelUndoRedoNote; - private System.Windows.Forms.Button cancelButton; - private System.Windows.Forms.Button okButton; - private System.Windows.Forms.Button applyButton; - private System.Windows.Forms.Label currentFlagsLabel; - private System.Windows.Forms.Button changeFlagButton; - private System.Windows.Forms.Label symbolsDefinedLabel; - private System.Windows.Forms.ListView projectSymbolsListView; - private System.Windows.Forms.ColumnHeader nameColumnHeader; - private System.Windows.Forms.ColumnHeader valueColumnHeader; - private System.Windows.Forms.ColumnHeader typeColumnHeader; - private System.Windows.Forms.TabPage symbolFilesTab; - private System.Windows.Forms.Button addSymbolFilesButton; - private System.Windows.Forms.Button symbolFileRemoveButton; - private System.Windows.Forms.ListBox symbolFilesListBox; - private System.Windows.Forms.Label configuredFilesLabel; - private System.Windows.Forms.Button removeSymbolButton; - private System.Windows.Forms.Button newSymbolButton; - private System.Windows.Forms.ColumnHeader commentColumnHeader; - private System.Windows.Forms.GroupBox entryFlagsGroupBox; - private System.Windows.Forms.Label flagsLabel; - private System.Windows.Forms.GroupBox cpuGroupBox; - private System.Windows.Forms.CheckBox undocInstrCheckBox; - private System.Windows.Forms.Button editSymbolButton; - private System.Windows.Forms.Button symbolFileDownButton; - private System.Windows.Forms.Button symbolFileUpButton; - private System.Windows.Forms.GroupBox analysisGroupBox; - private System.Windows.Forms.ComboBox minStringCharsComboBox; - private System.Windows.Forms.Label minCharsForStringLabel; - private System.Windows.Forms.CheckBox analyzeUncategorizedCheckBox; - private System.Windows.Forms.TabPage extensionScriptsTab; - private System.Windows.Forms.Button extensionScriptRemoveButton; - private System.Windows.Forms.Button addExtensionScriptsButton; - private System.Windows.Forms.ListBox extensionScriptsListBox; - private System.Windows.Forms.Label configuredScriptsLabel; - private System.Windows.Forms.Button importSymbolsButton; - private System.Windows.Forms.CheckBox seekAltTargetCheckBox; - private System.Windows.Forms.GroupBox miscGroupBox; - private System.Windows.Forms.ComboBox autoLabelStyleComboBox; - private System.Windows.Forms.Label autoLabelStyleLabel; - } -} \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditProjectProperties.cs b/SourceGenWF/AppForms/EditProjectProperties.cs deleted file mode 100644 index 4c31be1..0000000 --- a/SourceGenWF/AppForms/EditProjectProperties.cs +++ /dev/null @@ -1,646 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Text; -using System.Windows.Forms; - -using Asm65; -using CommonUtil; - -namespace SourceGenWF.AppForms { - /// - /// Edit project properties. - /// - /// Changes are made locally, and pushed to NewProps when OK or Apply is clicked. When - /// the dialog exits, if NewProps is non-null, the caller should apply those changes - /// regardless of the dialog's return value. - /// - public partial class EditProjectProperties : Form { - /// - /// New set. Updated when Apply or OK is hit. This will be null if no changes have - /// been applied. - /// - public ProjectProperties NewProps { get; private set; } - - /// - /// Format object to use when formatting addresses and constants. - /// - private Formatter mFormatter { get; set; } - - /// - /// Working set. Used internally to hold state. - /// - private ProjectProperties mWorkProps; - - /// - /// Dirty flag. Ideally this would just be "WorkProps != OldProps", but it doesn't - /// seem worthwhile to maintain an equality operator. - /// - private bool mDirty; - - /// - /// Project directory, if one has been established; otherwise empty. - /// - private string mProjectDir; - - - /// - /// Constructor. Initial state is configured from an existing ProjectProperties object. - /// - /// Property holder to clone. - /// Project directory, if known. - /// Text formatter. - public EditProjectProperties(ProjectProperties props, string projectDir, - Formatter formatter) { - InitializeComponent(); - - mWorkProps = new ProjectProperties(props); - mProjectDir = projectDir; - mFormatter = formatter; - } - - private void EditProperties_Load(object sender, EventArgs e) { - // Configure CPU chooser. This must match the order of strings in the designer. - switch (mWorkProps.CpuType) { - case CpuDef.CpuType.Cpu6502: - cpuComboBox.SelectedIndex = 0; - break; - case CpuDef.CpuType.Cpu65C02: - cpuComboBox.SelectedIndex = 1; - break; - case CpuDef.CpuType.Cpu65816: - cpuComboBox.SelectedIndex = 2; - break; - default: - Debug.Assert(false); - cpuComboBox.SelectedIndex = 0; - break; - } - - undocInstrCheckBox.Checked = mWorkProps.IncludeUndocumentedInstr; - analyzeUncategorizedCheckBox.Checked = - mWorkProps.AnalysisParams.AnalyzeUncategorizedData; - seekAltTargetCheckBox.Checked = - mWorkProps.AnalysisParams.SeekNearbyTargets; - - int matchLen = mWorkProps.AnalysisParams.MinCharsForString; - int selIndex; - if (matchLen == DataAnalysis.MIN_CHARS_FOR_STRING_DISABLED) { - selIndex = 0; // disabled - } else { - selIndex = matchLen - 2; - } - if (selIndex < 0 || selIndex >= minStringCharsComboBox.Items.Count) { - Debug.Assert(false, "bad MinCharsForString " + matchLen); - selIndex = 0; - } - minStringCharsComboBox.SelectedIndex = selIndex; - - selIndex = (int) mWorkProps.AutoLabelStyle; - if (selIndex < 0 || selIndex >= autoLabelStyleComboBox.Items.Count) { - Debug.Assert(false, "bad AutoLabelStyle " + mWorkProps.AutoLabelStyle); - selIndex = 0; - } - autoLabelStyleComboBox.SelectedIndex = selIndex; - - LoadProjectSymbols(); - LoadPlatformSymbolFiles(); - LoadExtensionScriptNames(); - - // Various callbacks will have fired while configuring controls. Reset to "clean". - mDirty = false; - UpdateControls(); - } - - private void okButton_Click(object sender, EventArgs e) { - NewProps = new ProjectProperties(mWorkProps); - } - - private void applyButton_Click(object sender, EventArgs e) { - NewProps = new ProjectProperties(mWorkProps); - mDirty = false; - UpdateControls(); - } - - private void UpdateControls() { - // - // General tab - // - applyButton.Enabled = mDirty; - - const string FLAGS = "CZIDXMVNE"; // flags, in order low to high, plus emu bit - const string VALUES = "-?01"; - StringBuilder sb = new StringBuilder(27); - StatusFlags flags = mWorkProps.EntryFlags; - for (int i = 0; i < 9; i++) { - // Want to show P reg flags (first 8) in conventional high-to-low order. - int idx = (7 - i) + (i == 8 ? 9 : 0); - int val = flags.GetBit((StatusFlags.FlagBits)idx); - sb.Append(FLAGS[idx]); - sb.Append(VALUES[val + 2]); - sb.Append(' '); - } - - currentFlagsLabel.Text = sb.ToString(); - - // - // Project symbols tab - // - int symSelCount = projectSymbolsListView.SelectedIndices.Count; - removeSymbolButton.Enabled = (symSelCount == 1); - editSymbolButton.Enabled = (symSelCount == 1); - - // - // Platform symbol files tab - // - int fileSelCount = symbolFilesListBox.SelectedIndices.Count; - symbolFileRemoveButton.Enabled = (fileSelCount != 0); - symbolFileUpButton.Enabled = (fileSelCount == 1 && - symbolFilesListBox.SelectedIndices[0] != 0); - symbolFileDownButton.Enabled = (fileSelCount == 1 && - symbolFilesListBox.SelectedIndices[0] != symbolFilesListBox.Items.Count - 1); - - // - // Extension Scripts tab - // - fileSelCount = extensionScriptsListBox.SelectedIndices.Count; - extensionScriptRemoveButton.Enabled = (fileSelCount != 0); - } - - - #region General - - /// - /// Converts the CPU combo box selection to a CpuType enum value. - /// - /// Selection index. - /// CPU type. - private CpuDef.CpuType CpuSelectionToCpuType(int sel) { - switch (sel) { - case 0: return CpuDef.CpuType.Cpu6502; - case 1: return CpuDef.CpuType.Cpu65C02; - case 2: return CpuDef.CpuType.Cpu65816; - default: - Debug.Assert(false); - return CpuDef.CpuType.Cpu6502; - } - } - - private void cpuComboBox_SelectedIndexChanged(object sender, EventArgs e) { - CpuDef.CpuType cpuType = CpuSelectionToCpuType(cpuComboBox.SelectedIndex); - if (mWorkProps.CpuType != cpuType) { - mWorkProps.CpuType = cpuType; - mDirty = true; - UpdateControls(); - } - } - - private void undocInstrCheckBox_CheckedChanged(object sender, EventArgs e) { - if (mWorkProps.IncludeUndocumentedInstr != undocInstrCheckBox.Checked) { - mWorkProps.IncludeUndocumentedInstr = undocInstrCheckBox.Checked; - mDirty = true; - UpdateControls(); - } - } - - private void changeFlagButton_Click(object sender, EventArgs e) { - CpuDef cpuDef = CpuDef.GetBestMatch(mWorkProps.CpuType, - mWorkProps.IncludeUndocumentedInstr); - EditStatusFlags dlg = new EditStatusFlags(mWorkProps.EntryFlags, cpuDef.HasEmuFlag); - - dlg.ShowDialog(); - if (dlg.DialogResult == DialogResult.OK) { - if (mWorkProps.EntryFlags != dlg.FlagValue) { - // Flags changed. - mWorkProps.EntryFlags = dlg.FlagValue; - mDirty = true; - UpdateControls(); - } - } - - dlg.Dispose(); - } - - private void analyzeUncategorizedCheckBox_CheckedChanged(object sender, EventArgs e) { - mWorkProps.AnalysisParams.AnalyzeUncategorizedData = - analyzeUncategorizedCheckBox.Checked; - mDirty = true; - UpdateControls(); - } - - private void seekAltTargetCheckBox_CheckedChanged(object sender, EventArgs e) { - mWorkProps.AnalysisParams.SeekNearbyTargets = - seekAltTargetCheckBox.Checked; - mDirty = true; - UpdateControls(); - } - - private void minStringCharsComboBox_SelectedIndexChanged(object sender, EventArgs e) { - // ComboBox must be the value 0, then N+2 in each subsequent entry (3, 4, 5, ...). - int index = minStringCharsComboBox.SelectedIndex; - int newVal; - if (index == 0) { - newVal = DataAnalysis.MIN_CHARS_FOR_STRING_DISABLED; - } else { - newVal = index + 2; - } - - if (newVal != mWorkProps.AnalysisParams.MinCharsForString) { - mWorkProps.AnalysisParams.MinCharsForString = newVal; - mDirty = true; - UpdateControls(); - } - } - - private void autoLabelStyleComboBox_SelectedIndexChanged(object sender, EventArgs e) { - AutoLabel.Style newStyle = (AutoLabel.Style)autoLabelStyleComboBox.SelectedIndex; - if (newStyle != mWorkProps.AutoLabelStyle) { - mWorkProps.AutoLabelStyle = newStyle; - mDirty = true; - UpdateControls(); - } - } - - #endregion General - - - #region Project Symbols - - private ListViewItem.ListViewSubItem[] mSymbolSubArray = - new ListViewItem.ListViewSubItem[3]; - - /// - /// Loads the project symbols into the ListView. - /// - private void LoadProjectSymbols() { - // The set should be small enough that we don't need to worry about updating - // the item list incrementally. - //Debug.WriteLine("LPS loading " + WorkProps.ProjectSyms.Count + " project symbols"); - projectSymbolsListView.BeginUpdate(); - projectSymbolsListView.Items.Clear(); - foreach (KeyValuePair kvp in mWorkProps.ProjectSyms) { - DefSymbol defSym = kvp.Value; - string typeStr; - if (defSym.SymbolType == Symbol.Type.Constant) { - typeStr = Properties.Resources.ABBREV_CONSTANT; - } else { - typeStr = Properties.Resources.ABBREV_ADDRESS; - } - - ListViewItem lvi = new ListViewItem(); - lvi.Text = defSym.Label; - mSymbolSubArray[0] = new ListViewItem.ListViewSubItem(lvi, - mFormatter.FormatValueInBase(defSym.Value, defSym.DataDescriptor.NumBase)); - mSymbolSubArray[1] = new ListViewItem.ListViewSubItem(lvi, typeStr); - mSymbolSubArray[2] = new ListViewItem.ListViewSubItem(lvi, defSym.Comment); - lvi.SubItems.AddRange(mSymbolSubArray); - - projectSymbolsListView.Items.Add(lvi); - } - projectSymbolsListView.EndUpdate(); - } - - - private void projectSymbolsListView_SelectedIndexChanged(object sender, EventArgs e) { - // Need to enable/disable the edit+remove buttons depending on the number of - // selected items. - UpdateControls(); - } - - private void newSymbolButton_Click(object sender, EventArgs e) { - EditDefSymbol dlg = new EditDefSymbol(mFormatter, mWorkProps.ProjectSyms); - dlg.ShowDialog(); - if (dlg.DialogResult == DialogResult.OK) { - Debug.WriteLine("ADD: " + dlg.DefSym); - mWorkProps.ProjectSyms[dlg.DefSym.Label] = dlg.DefSym; - mDirty = true; - LoadProjectSymbols(); - UpdateControls(); - } - dlg.Dispose(); - } - - private void editSymbolButton_Click(object sender, EventArgs e) { - // Single-select list view, button dimmed when no selection. - Debug.Assert(projectSymbolsListView.SelectedItems.Count == 1); - ListViewItem item = projectSymbolsListView.SelectedItems[0]; - DefSymbol defSym = mWorkProps.ProjectSyms[item.Text]; - DoEditSymbol(defSym); - } - - private void projectSymbolsListView_MouseDoubleClick(object sender, MouseEventArgs e) { - ListViewHitTestInfo info = projectSymbolsListView.HitTest(e.X, e.Y); - DefSymbol defSym = mWorkProps.ProjectSyms[info.Item.Text]; - DoEditSymbol(defSym); - } - - private void DoEditSymbol(DefSymbol defSym) { - EditDefSymbol dlg = new EditDefSymbol(mFormatter, mWorkProps.ProjectSyms); - dlg.DefSym = defSym; - dlg.ShowDialog(); - if (dlg.DialogResult == DialogResult.OK) { - // Label might have changed, so remove old before adding new. - mWorkProps.ProjectSyms.Remove(defSym.Label); - mWorkProps.ProjectSyms[dlg.DefSym.Label] = dlg.DefSym; - mDirty = true; - LoadProjectSymbols(); - UpdateControls(); - } - dlg.Dispose(); - } - - private void removeSymbolButton_Click(object sender, EventArgs e) { - // Single-select list view, button dimmed when no selection. - Debug.Assert(projectSymbolsListView.SelectedItems.Count == 1); - - int selectionIndex = projectSymbolsListView.SelectedIndices[0]; - ListViewItem item = projectSymbolsListView.SelectedItems[0]; - DefSymbol defSym = mWorkProps.ProjectSyms[item.Text]; - mWorkProps.ProjectSyms.Remove(defSym.Label); - mDirty = true; - LoadProjectSymbols(); - UpdateControls(); - - // Restore selection, so you can hit "Remove" repeatedly to delete - // multiple items. - int newCount = projectSymbolsListView.Items.Count; - if (selectionIndex >= newCount) { - selectionIndex = newCount - 1; - } - if (selectionIndex >= 0) { - projectSymbolsListView.SelectedIndices.Add(selectionIndex); - removeSymbolButton.Focus(); - } - } - - #endregion Project Symbols - - - #region Platform symbol files - - /// - /// Loads the platform symbol file names into the list control. - /// - private void LoadPlatformSymbolFiles() { - symbolFilesListBox.BeginUpdate(); - symbolFilesListBox.Items.Clear(); - - foreach (string fileName in mWorkProps.PlatformSymbolFileIdentifiers) { - symbolFilesListBox.Items.Add(fileName); - } - - symbolFilesListBox.EndUpdate(); - } - - private void symbolFilesListBox_SelectedIndexChanged(object sender, EventArgs e) { - // Enable/disable buttons as the selection changes. - UpdateControls(); - } - - private void addSymbolFilesButton_Click(object sender, EventArgs e) { - OpenFileDialog fileDlg = new OpenFileDialog() { - Filter = PlatformSymbols.FILENAME_FILTER, - Multiselect = true, - InitialDirectory = RuntimeDataAccess.GetDirectory(), - RestoreDirectory = true // doesn't seem to work? - }; - if (fileDlg.ShowDialog() != DialogResult.OK) { - return; - } - - foreach (string pathName in fileDlg.FileNames) { - // I'm assuming the full names got the Path.GetFullPath() canonicalization and - // don't need further processing. Also, I'm assuming that all files live in - // the same directory, so if one is in an invalid location then they all are. - ExternalFile ef = ExternalFile.CreateFromPath(pathName, mProjectDir); - if (ef == null) { - // Files not found in runtime or project directory. - string projDir = mProjectDir; - if (string.IsNullOrEmpty(projDir)) { - projDir = Properties.Resources.UNSET; - } - string msg = string.Format(Properties.Resources.EXTERNAL_FILE_BAD_DIR, - RuntimeDataAccess.GetDirectory(), projDir, pathName); - MessageBox.Show(this, msg, Properties.Resources.EXTERNAL_FILE_BAD_DIR_CAPTION, - MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - - string ident = ef.Identifier; - - if (mWorkProps.PlatformSymbolFileIdentifiers.Contains(ident)) { - Debug.WriteLine("Already present: " + ident); - continue; - } - - Debug.WriteLine("Adding symbol file: " + ident); - mWorkProps.PlatformSymbolFileIdentifiers.Add(ident); - mDirty = true; - } - - if (mDirty) { - LoadPlatformSymbolFiles(); - UpdateControls(); - } - } - - private void symbolFileUpButton_Click(object sender, EventArgs e) { - Debug.Assert(symbolFilesListBox.SelectedIndices.Count == 1); - int selIndex = symbolFilesListBox.SelectedIndices[0]; - Debug.Assert(selIndex > 0); - - MoveSingleItem(selIndex, symbolFilesListBox.SelectedItem, -1); - } - - private void symbolFileDownButton_Click(object sender, EventArgs e) { - Debug.Assert(symbolFilesListBox.SelectedIndices.Count == 1); - int selIndex = symbolFilesListBox.SelectedIndices[0]; - Debug.Assert(selIndex < symbolFilesListBox.Items.Count - 1); - - MoveSingleItem(selIndex, symbolFilesListBox.SelectedItem, +1); - } - - private void MoveSingleItem(int selIndex, object selectedItem, int adj) { - object selected = symbolFilesListBox.SelectedItem; - symbolFilesListBox.Items.Remove(selected); - symbolFilesListBox.Items.Insert(selIndex + adj, selected); - symbolFilesListBox.SetSelected(selIndex + adj, true); - - // do the same operation in the file name list - string str = mWorkProps.PlatformSymbolFileIdentifiers[selIndex]; - mWorkProps.PlatformSymbolFileIdentifiers.RemoveAt(selIndex); - mWorkProps.PlatformSymbolFileIdentifiers.Insert(selIndex + adj, str); - - mDirty = true; - UpdateControls(); - } - - private void symbolFileRemoveButton_Click(object sender, EventArgs e) { - Debug.Assert(symbolFilesListBox.SelectedIndices.Count > 0); - for (int i = symbolFilesListBox.SelectedIndices.Count - 1; i >= 0; i--) { - int index = symbolFilesListBox.SelectedIndices[i]; - symbolFilesListBox.Items.RemoveAt(index); - mWorkProps.PlatformSymbolFileIdentifiers.RemoveAt(index); - } - - mDirty = true; - UpdateControls(); - } - - private void importSymbolsButton_Click(object sender, EventArgs e) { - OpenFileDialog fileDlg = new OpenFileDialog() { - Filter = ProjectFile.FILENAME_FILTER + "|" + Properties.Resources.FILE_FILTER_ALL, - FilterIndex = 1 - }; - if (fileDlg.ShowDialog() != DialogResult.OK) { - return; - } - string projPathName = Path.GetFullPath(fileDlg.FileName); - - DisasmProject newProject = new DisasmProject(); - if (!ProjectFile.DeserializeFromFile(projPathName, newProject, - out FileLoadReport report)) { - // Unable to open project file. Report error and bail. - ProjectLoadIssues dlg = new ProjectLoadIssues(report.Format(), - ProjectLoadIssues.Buttons.Cancel); - dlg.ShowDialog(); - // ignore dlg.DialogResult - dlg.Dispose(); - return; - } - - // Import all user labels that were marked as "global export". These become - // external-address project symbols. - int foundCount = 0; - foreach (KeyValuePair kvp in newProject.UserLabels) { - if (kvp.Value.SymbolType == Symbol.Type.GlobalAddrExport) { - Symbol sym = kvp.Value; - DefSymbol defSym = new DefSymbol(sym.Label, sym.Value, Symbol.Source.Project, - Symbol.Type.ExternalAddr, FormatDescriptor.SubType.None, - string.Empty, string.Empty); - mWorkProps.ProjectSyms[defSym.Label] = defSym; - foundCount++; - } - } - if (foundCount != 0) { - mDirty = true; - LoadProjectSymbols(); - UpdateControls(); - } - - newProject.Cleanup(); - - // Tell the user we did something. Might be nice to tell them how many weren't - // already present. - string msg; - if (foundCount == 0) { - msg = Properties.Resources.SYMBOL_IMPORT_NONE; - } else { - msg = string.Format(Properties.Resources.SYMBOL_IMPORT_GOOD, foundCount); - } - MessageBox.Show(this, msg, Properties.Resources.SYMBOL_IMPORT_CAPTION, - MessageBoxButtons.OK, MessageBoxIcon.Information); - } - - #endregion Platform symbol files - - - #region Extension scripts - - /// - /// Loads the extension script file names into the list control. - /// - private void LoadExtensionScriptNames() { - extensionScriptsListBox.BeginUpdate(); - extensionScriptsListBox.Items.Clear(); - - foreach (string fileName in mWorkProps.ExtensionScriptFileIdentifiers) { - extensionScriptsListBox.Items.Add(fileName); - } - - extensionScriptsListBox.EndUpdate(); - } - - private void extensionScriptsListBox_SelectedIndexChanged(object sender, EventArgs e) { - // Enable/disable buttons as the selection changes. - UpdateControls(); - } - - private void addExtensionScriptsButton_Click(object sender, EventArgs e) { - OpenFileDialog fileDlg = new OpenFileDialog() { - Filter = Sandbox.ScriptManager.FILENAME_FILTER, - Multiselect = true, - InitialDirectory = RuntimeDataAccess.GetDirectory(), - RestoreDirectory = true // doesn't seem to work? - }; - if (fileDlg.ShowDialog() != DialogResult.OK) { - return; - } - - foreach (string pathName in fileDlg.FileNames) { - // I'm assuming the full names got the Path.GetFullPath() canonicalization and - // don't need further processing. Also, I'm assuming that all files live in - // the same directory, so if one is in an invalid location then they all are. - ExternalFile ef = ExternalFile.CreateFromPath(pathName, mProjectDir); - if (ef == null) { - // Files not found in runtime or project directory. - string projDir = mProjectDir; - if (string.IsNullOrEmpty(projDir)) { - projDir = Properties.Resources.UNSET; - } - string msg = string.Format(Properties.Resources.EXTERNAL_FILE_BAD_DIR, - RuntimeDataAccess.GetDirectory(), projDir, pathName); - MessageBox.Show(this, msg, Properties.Resources.EXTERNAL_FILE_BAD_DIR_CAPTION, - MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - - string ident = ef.Identifier; - - if (mWorkProps.ExtensionScriptFileIdentifiers.Contains(ident)) { - Debug.WriteLine("Already present: " + ident); - continue; - } - - Debug.WriteLine("Adding extension script: " + ident); - mWorkProps.ExtensionScriptFileIdentifiers.Add(ident); - mDirty = true; - } - - if (mDirty) { - LoadExtensionScriptNames(); - UpdateControls(); - } - } - - private void extensionScriptRemoveButton_Click(object sender, EventArgs e) { - Debug.Assert(extensionScriptsListBox.SelectedIndices.Count > 0); - for (int i = extensionScriptsListBox.SelectedIndices.Count - 1; i >= 0; i--) { - int index = extensionScriptsListBox.SelectedIndices[i]; - extensionScriptsListBox.Items.RemoveAt(index); - mWorkProps.ExtensionScriptFileIdentifiers.RemoveAt(index); - } - - mDirty = true; - UpdateControls(); - } - - #endregion Extension scripts - } -} diff --git a/SourceGenWF/AppForms/EditProjectProperties.resx b/SourceGenWF/AppForms/EditProjectProperties.resx deleted file mode 100644 index 1af7de1..0000000 --- a/SourceGenWF/AppForms/EditProjectProperties.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SourceGenWF/AppForms/EditStatusFlags.Designer.cs b/SourceGenWF/AppForms/EditStatusFlags.Designer.cs deleted file mode 100644 index fa91ea0..0000000 --- a/SourceGenWF/AppForms/EditStatusFlags.Designer.cs +++ /dev/null @@ -1,883 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AppForms { - partial class EditStatusFlags { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.defaultLabel = new System.Windows.Forms.Label(); - this.zeroLabel = new System.Windows.Forms.Label(); - this.oneLabel = new System.Windows.Forms.Label(); - this.indeterminateLabel = new System.Windows.Forms.Label(); - this.panelN = new System.Windows.Forms.Panel(); - this.flagNLabel = new System.Windows.Forms.Label(); - this.radioNIndeterminate = new System.Windows.Forms.RadioButton(); - this.radioNOne = new System.Windows.Forms.RadioButton(); - this.radioNZero = new System.Windows.Forms.RadioButton(); - this.radioNDefault = new System.Windows.Forms.RadioButton(); - this.panelV = new System.Windows.Forms.Panel(); - this.flagVLabel = new System.Windows.Forms.Label(); - this.radioVIndeterminate = new System.Windows.Forms.RadioButton(); - this.radioVOne = new System.Windows.Forms.RadioButton(); - this.radioVZero = new System.Windows.Forms.RadioButton(); - this.radioVDefault = new System.Windows.Forms.RadioButton(); - this.okButton = new System.Windows.Forms.Button(); - this.cancelButton = new System.Windows.Forms.Button(); - this.panelM = new System.Windows.Forms.Panel(); - this.flagMLabel = new System.Windows.Forms.Label(); - this.radioMIndeterminate = new System.Windows.Forms.RadioButton(); - this.radioMOne = new System.Windows.Forms.RadioButton(); - this.radioMZero = new System.Windows.Forms.RadioButton(); - this.radioMDefault = new System.Windows.Forms.RadioButton(); - this.panelX = new System.Windows.Forms.Panel(); - this.flagXLabel = new System.Windows.Forms.Label(); - this.radioXIndeterminate = new System.Windows.Forms.RadioButton(); - this.radioXOne = new System.Windows.Forms.RadioButton(); - this.radioXZero = new System.Windows.Forms.RadioButton(); - this.radioXDefault = new System.Windows.Forms.RadioButton(); - this.panelD = new System.Windows.Forms.Panel(); - this.flagDLabel = new System.Windows.Forms.Label(); - this.radioDIndeterminate = new System.Windows.Forms.RadioButton(); - this.radioDOne = new System.Windows.Forms.RadioButton(); - this.radioDZero = new System.Windows.Forms.RadioButton(); - this.radioDDefault = new System.Windows.Forms.RadioButton(); - this.panelI = new System.Windows.Forms.Panel(); - this.flagILabel = new System.Windows.Forms.Label(); - this.radioIIndeterminate = new System.Windows.Forms.RadioButton(); - this.radioIOne = new System.Windows.Forms.RadioButton(); - this.radioIZero = new System.Windows.Forms.RadioButton(); - this.radioIDefault = new System.Windows.Forms.RadioButton(); - this.panelZ = new System.Windows.Forms.Panel(); - this.flagZLabel = new System.Windows.Forms.Label(); - this.radioZIndeterminate = new System.Windows.Forms.RadioButton(); - this.radioZOne = new System.Windows.Forms.RadioButton(); - this.radioZZero = new System.Windows.Forms.RadioButton(); - this.radioZDefault = new System.Windows.Forms.RadioButton(); - this.panelC = new System.Windows.Forms.Panel(); - this.flagCLabel = new System.Windows.Forms.Label(); - this.radioCIndeterminate = new System.Windows.Forms.RadioButton(); - this.radioCOne = new System.Windows.Forms.RadioButton(); - this.radioCZero = new System.Windows.Forms.RadioButton(); - this.radioCDefault = new System.Windows.Forms.RadioButton(); - this.panelE = new System.Windows.Forms.Panel(); - this.flagELabel = new System.Windows.Forms.Label(); - this.radioEIndeterminate = new System.Windows.Forms.RadioButton(); - this.radioEOne = new System.Windows.Forms.RadioButton(); - this.radioEZero = new System.Windows.Forms.RadioButton(); - this.radioEDefault = new System.Windows.Forms.RadioButton(); - this.instructionLabel = new System.Windows.Forms.Label(); - this.labelLongRegsNote = new System.Windows.Forms.Label(); - this.resetButton = new System.Windows.Forms.Button(); - this.panelN.SuspendLayout(); - this.panelV.SuspendLayout(); - this.panelM.SuspendLayout(); - this.panelX.SuspendLayout(); - this.panelD.SuspendLayout(); - this.panelI.SuspendLayout(); - this.panelZ.SuspendLayout(); - this.panelC.SuspendLayout(); - this.panelE.SuspendLayout(); - this.SuspendLayout(); - // - // defaultLabel - // - this.defaultLabel.Location = new System.Drawing.Point(12, 70); - this.defaultLabel.Name = "defaultLabel"; - this.defaultLabel.Size = new System.Drawing.Size(90, 20); - this.defaultLabel.TabIndex = 4; - this.defaultLabel.Text = "Default"; - this.defaultLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // zeroLabel - // - this.zeroLabel.Location = new System.Drawing.Point(12, 90); - this.zeroLabel.Name = "zeroLabel"; - this.zeroLabel.Size = new System.Drawing.Size(90, 20); - this.zeroLabel.TabIndex = 5; - this.zeroLabel.Text = "Zero"; - this.zeroLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // oneLabel - // - this.oneLabel.Location = new System.Drawing.Point(12, 110); - this.oneLabel.Name = "oneLabel"; - this.oneLabel.Size = new System.Drawing.Size(90, 20); - this.oneLabel.TabIndex = 6; - this.oneLabel.Text = "One"; - this.oneLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // indeterminateLabel - // - this.indeterminateLabel.Location = new System.Drawing.Point(12, 130); - this.indeterminateLabel.Name = "indeterminateLabel"; - this.indeterminateLabel.Size = new System.Drawing.Size(90, 20); - this.indeterminateLabel.TabIndex = 7; - this.indeterminateLabel.Text = "Indeterminate"; - this.indeterminateLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // panelN - // - this.panelN.Controls.Add(this.flagNLabel); - this.panelN.Controls.Add(this.radioNIndeterminate); - this.panelN.Controls.Add(this.radioNOne); - this.panelN.Controls.Add(this.radioNZero); - this.panelN.Controls.Add(this.radioNDefault); - this.panelN.Location = new System.Drawing.Point(108, 47); - this.panelN.Name = "panelN"; - this.panelN.Size = new System.Drawing.Size(26, 110); - this.panelN.TabIndex = 9; - // - // flagNLabel - // - this.flagNLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.flagNLabel.Location = new System.Drawing.Point(3, 0); - this.flagNLabel.Name = "flagNLabel"; - this.flagNLabel.Size = new System.Drawing.Size(20, 20); - this.flagNLabel.TabIndex = 0; - this.flagNLabel.Text = "N"; - this.flagNLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter; - // - // radioNIndeterminate - // - this.radioNIndeterminate.AutoSize = true; - this.radioNIndeterminate.Location = new System.Drawing.Point(6, 83); - this.radioNIndeterminate.Name = "radioNIndeterminate"; - this.radioNIndeterminate.Size = new System.Drawing.Size(14, 13); - this.radioNIndeterminate.TabIndex = 4; - this.radioNIndeterminate.TabStop = true; - this.radioNIndeterminate.UseVisualStyleBackColor = true; - // - // radioNOne - // - this.radioNOne.AutoSize = true; - this.radioNOne.Location = new System.Drawing.Point(6, 63); - this.radioNOne.Name = "radioNOne"; - this.radioNOne.Size = new System.Drawing.Size(14, 13); - this.radioNOne.TabIndex = 3; - this.radioNOne.TabStop = true; - this.radioNOne.UseVisualStyleBackColor = true; - // - // radioNZero - // - this.radioNZero.AutoSize = true; - this.radioNZero.Location = new System.Drawing.Point(6, 43); - this.radioNZero.Name = "radioNZero"; - this.radioNZero.Size = new System.Drawing.Size(14, 13); - this.radioNZero.TabIndex = 2; - this.radioNZero.TabStop = true; - this.radioNZero.UseVisualStyleBackColor = true; - // - // radioNDefault - // - this.radioNDefault.AutoSize = true; - this.radioNDefault.Location = new System.Drawing.Point(6, 23); - this.radioNDefault.Name = "radioNDefault"; - this.radioNDefault.Size = new System.Drawing.Size(14, 13); - this.radioNDefault.TabIndex = 1; - this.radioNDefault.TabStop = true; - this.radioNDefault.UseVisualStyleBackColor = true; - // - // panelV - // - this.panelV.Controls.Add(this.flagVLabel); - this.panelV.Controls.Add(this.radioVIndeterminate); - this.panelV.Controls.Add(this.radioVOne); - this.panelV.Controls.Add(this.radioVZero); - this.panelV.Controls.Add(this.radioVDefault); - this.panelV.Location = new System.Drawing.Point(140, 47); - this.panelV.Name = "panelV"; - this.panelV.Size = new System.Drawing.Size(26, 110); - this.panelV.TabIndex = 14; - // - // flagVLabel - // - this.flagVLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.flagVLabel.Location = new System.Drawing.Point(3, 0); - this.flagVLabel.Name = "flagVLabel"; - this.flagVLabel.Size = new System.Drawing.Size(20, 20); - this.flagVLabel.TabIndex = 0; - this.flagVLabel.Text = "V"; - this.flagVLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter; - // - // radioVIndeterminate - // - this.radioVIndeterminate.AutoSize = true; - this.radioVIndeterminate.Location = new System.Drawing.Point(6, 83); - this.radioVIndeterminate.Name = "radioVIndeterminate"; - this.radioVIndeterminate.Size = new System.Drawing.Size(14, 13); - this.radioVIndeterminate.TabIndex = 4; - this.radioVIndeterminate.TabStop = true; - this.radioVIndeterminate.UseVisualStyleBackColor = true; - // - // radioVOne - // - this.radioVOne.AutoSize = true; - this.radioVOne.Location = new System.Drawing.Point(6, 63); - this.radioVOne.Name = "radioVOne"; - this.radioVOne.Size = new System.Drawing.Size(14, 13); - this.radioVOne.TabIndex = 3; - this.radioVOne.TabStop = true; - this.radioVOne.UseVisualStyleBackColor = true; - // - // radioVZero - // - this.radioVZero.AutoSize = true; - this.radioVZero.Location = new System.Drawing.Point(6, 43); - this.radioVZero.Name = "radioVZero"; - this.radioVZero.Size = new System.Drawing.Size(14, 13); - this.radioVZero.TabIndex = 2; - this.radioVZero.TabStop = true; - this.radioVZero.UseVisualStyleBackColor = true; - // - // radioVDefault - // - this.radioVDefault.AutoSize = true; - this.radioVDefault.Location = new System.Drawing.Point(6, 23); - this.radioVDefault.Name = "radioVDefault"; - this.radioVDefault.Size = new System.Drawing.Size(14, 13); - this.radioVDefault.TabIndex = 1; - this.radioVDefault.TabStop = true; - this.radioVDefault.UseVisualStyleBackColor = true; - // - // okButton - // - this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.okButton.Location = new System.Drawing.Point(281, 205); - this.okButton.Name = "okButton"; - this.okButton.Size = new System.Drawing.Size(75, 23); - this.okButton.TabIndex = 0; - this.okButton.Text = "OK"; - this.okButton.UseVisualStyleBackColor = true; - this.okButton.Click += new System.EventHandler(this.okButton_Click); - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.Location = new System.Drawing.Point(362, 205); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 23); - this.cancelButton.TabIndex = 1; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - // - // panelM - // - this.panelM.Controls.Add(this.flagMLabel); - this.panelM.Controls.Add(this.radioMIndeterminate); - this.panelM.Controls.Add(this.radioMOne); - this.panelM.Controls.Add(this.radioMZero); - this.panelM.Controls.Add(this.radioMDefault); - this.panelM.Location = new System.Drawing.Point(172, 47); - this.panelM.Name = "panelM"; - this.panelM.Size = new System.Drawing.Size(26, 110); - this.panelM.TabIndex = 15; - // - // flagMLabel - // - this.flagMLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.flagMLabel.Location = new System.Drawing.Point(3, 0); - this.flagMLabel.Name = "flagMLabel"; - this.flagMLabel.Size = new System.Drawing.Size(20, 20); - this.flagMLabel.TabIndex = 0; - this.flagMLabel.Text = "M"; - this.flagMLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter; - // - // radioMIndeterminate - // - this.radioMIndeterminate.AutoSize = true; - this.radioMIndeterminate.Location = new System.Drawing.Point(6, 83); - this.radioMIndeterminate.Name = "radioMIndeterminate"; - this.radioMIndeterminate.Size = new System.Drawing.Size(14, 13); - this.radioMIndeterminate.TabIndex = 4; - this.radioMIndeterminate.TabStop = true; - this.radioMIndeterminate.UseVisualStyleBackColor = true; - // - // radioMOne - // - this.radioMOne.AutoSize = true; - this.radioMOne.Location = new System.Drawing.Point(6, 63); - this.radioMOne.Name = "radioMOne"; - this.radioMOne.Size = new System.Drawing.Size(14, 13); - this.radioMOne.TabIndex = 3; - this.radioMOne.TabStop = true; - this.radioMOne.UseVisualStyleBackColor = true; - // - // radioMZero - // - this.radioMZero.AutoSize = true; - this.radioMZero.Location = new System.Drawing.Point(6, 43); - this.radioMZero.Name = "radioMZero"; - this.radioMZero.Size = new System.Drawing.Size(14, 13); - this.radioMZero.TabIndex = 2; - this.radioMZero.TabStop = true; - this.radioMZero.UseVisualStyleBackColor = true; - // - // radioMDefault - // - this.radioMDefault.AutoSize = true; - this.radioMDefault.Location = new System.Drawing.Point(6, 23); - this.radioMDefault.Name = "radioMDefault"; - this.radioMDefault.Size = new System.Drawing.Size(14, 13); - this.radioMDefault.TabIndex = 1; - this.radioMDefault.TabStop = true; - this.radioMDefault.UseVisualStyleBackColor = true; - // - // panelX - // - this.panelX.Controls.Add(this.flagXLabel); - this.panelX.Controls.Add(this.radioXIndeterminate); - this.panelX.Controls.Add(this.radioXOne); - this.panelX.Controls.Add(this.radioXZero); - this.panelX.Controls.Add(this.radioXDefault); - this.panelX.Location = new System.Drawing.Point(204, 47); - this.panelX.Name = "panelX"; - this.panelX.Size = new System.Drawing.Size(26, 110); - this.panelX.TabIndex = 16; - // - // flagXLabel - // - this.flagXLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.flagXLabel.Location = new System.Drawing.Point(3, 0); - this.flagXLabel.Name = "flagXLabel"; - this.flagXLabel.Size = new System.Drawing.Size(20, 20); - this.flagXLabel.TabIndex = 0; - this.flagXLabel.Text = "X"; - this.flagXLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter; - // - // radioXIndeterminate - // - this.radioXIndeterminate.AutoSize = true; - this.radioXIndeterminate.Location = new System.Drawing.Point(6, 83); - this.radioXIndeterminate.Name = "radioXIndeterminate"; - this.radioXIndeterminate.Size = new System.Drawing.Size(14, 13); - this.radioXIndeterminate.TabIndex = 4; - this.radioXIndeterminate.TabStop = true; - this.radioXIndeterminate.UseVisualStyleBackColor = true; - // - // radioXOne - // - this.radioXOne.AutoSize = true; - this.radioXOne.Location = new System.Drawing.Point(6, 63); - this.radioXOne.Name = "radioXOne"; - this.radioXOne.Size = new System.Drawing.Size(14, 13); - this.radioXOne.TabIndex = 3; - this.radioXOne.TabStop = true; - this.radioXOne.UseVisualStyleBackColor = true; - // - // radioXZero - // - this.radioXZero.AutoSize = true; - this.radioXZero.Location = new System.Drawing.Point(6, 43); - this.radioXZero.Name = "radioXZero"; - this.radioXZero.Size = new System.Drawing.Size(14, 13); - this.radioXZero.TabIndex = 2; - this.radioXZero.TabStop = true; - this.radioXZero.UseVisualStyleBackColor = true; - // - // radioXDefault - // - this.radioXDefault.AutoSize = true; - this.radioXDefault.Location = new System.Drawing.Point(6, 23); - this.radioXDefault.Name = "radioXDefault"; - this.radioXDefault.Size = new System.Drawing.Size(14, 13); - this.radioXDefault.TabIndex = 1; - this.radioXDefault.TabStop = true; - this.radioXDefault.UseVisualStyleBackColor = true; - // - // panelD - // - this.panelD.Controls.Add(this.flagDLabel); - this.panelD.Controls.Add(this.radioDIndeterminate); - this.panelD.Controls.Add(this.radioDOne); - this.panelD.Controls.Add(this.radioDZero); - this.panelD.Controls.Add(this.radioDDefault); - this.panelD.Location = new System.Drawing.Point(236, 47); - this.panelD.Name = "panelD"; - this.panelD.Size = new System.Drawing.Size(26, 110); - this.panelD.TabIndex = 17; - // - // flagDLabel - // - this.flagDLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.flagDLabel.Location = new System.Drawing.Point(3, 0); - this.flagDLabel.Name = "flagDLabel"; - this.flagDLabel.Size = new System.Drawing.Size(20, 20); - this.flagDLabel.TabIndex = 0; - this.flagDLabel.Text = "D"; - this.flagDLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter; - // - // radioDIndeterminate - // - this.radioDIndeterminate.AutoSize = true; - this.radioDIndeterminate.Location = new System.Drawing.Point(6, 83); - this.radioDIndeterminate.Name = "radioDIndeterminate"; - this.radioDIndeterminate.Size = new System.Drawing.Size(14, 13); - this.radioDIndeterminate.TabIndex = 4; - this.radioDIndeterminate.TabStop = true; - this.radioDIndeterminate.UseVisualStyleBackColor = true; - // - // radioDOne - // - this.radioDOne.AutoSize = true; - this.radioDOne.Location = new System.Drawing.Point(6, 63); - this.radioDOne.Name = "radioDOne"; - this.radioDOne.Size = new System.Drawing.Size(14, 13); - this.radioDOne.TabIndex = 3; - this.radioDOne.TabStop = true; - this.radioDOne.UseVisualStyleBackColor = true; - // - // radioDZero - // - this.radioDZero.AutoSize = true; - this.radioDZero.Location = new System.Drawing.Point(6, 43); - this.radioDZero.Name = "radioDZero"; - this.radioDZero.Size = new System.Drawing.Size(14, 13); - this.radioDZero.TabIndex = 2; - this.radioDZero.TabStop = true; - this.radioDZero.UseVisualStyleBackColor = true; - // - // radioDDefault - // - this.radioDDefault.AutoSize = true; - this.radioDDefault.Location = new System.Drawing.Point(6, 23); - this.radioDDefault.Name = "radioDDefault"; - this.radioDDefault.Size = new System.Drawing.Size(14, 13); - this.radioDDefault.TabIndex = 1; - this.radioDDefault.TabStop = true; - this.radioDDefault.UseVisualStyleBackColor = true; - // - // panelI - // - this.panelI.Controls.Add(this.flagILabel); - this.panelI.Controls.Add(this.radioIIndeterminate); - this.panelI.Controls.Add(this.radioIOne); - this.panelI.Controls.Add(this.radioIZero); - this.panelI.Controls.Add(this.radioIDefault); - this.panelI.Location = new System.Drawing.Point(268, 47); - this.panelI.Name = "panelI"; - this.panelI.Size = new System.Drawing.Size(26, 110); - this.panelI.TabIndex = 18; - // - // flagILabel - // - this.flagILabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.flagILabel.Location = new System.Drawing.Point(3, 0); - this.flagILabel.Name = "flagILabel"; - this.flagILabel.Size = new System.Drawing.Size(20, 20); - this.flagILabel.TabIndex = 0; - this.flagILabel.Text = "I"; - this.flagILabel.TextAlign = System.Drawing.ContentAlignment.TopCenter; - // - // radioIIndeterminate - // - this.radioIIndeterminate.AutoSize = true; - this.radioIIndeterminate.Location = new System.Drawing.Point(6, 83); - this.radioIIndeterminate.Name = "radioIIndeterminate"; - this.radioIIndeterminate.Size = new System.Drawing.Size(14, 13); - this.radioIIndeterminate.TabIndex = 4; - this.radioIIndeterminate.TabStop = true; - this.radioIIndeterminate.UseVisualStyleBackColor = true; - // - // radioIOne - // - this.radioIOne.AutoSize = true; - this.radioIOne.Location = new System.Drawing.Point(6, 63); - this.radioIOne.Name = "radioIOne"; - this.radioIOne.Size = new System.Drawing.Size(14, 13); - this.radioIOne.TabIndex = 3; - this.radioIOne.TabStop = true; - this.radioIOne.UseVisualStyleBackColor = true; - // - // radioIZero - // - this.radioIZero.AutoSize = true; - this.radioIZero.Location = new System.Drawing.Point(6, 43); - this.radioIZero.Name = "radioIZero"; - this.radioIZero.Size = new System.Drawing.Size(14, 13); - this.radioIZero.TabIndex = 2; - this.radioIZero.TabStop = true; - this.radioIZero.UseVisualStyleBackColor = true; - // - // radioIDefault - // - this.radioIDefault.AutoSize = true; - this.radioIDefault.Location = new System.Drawing.Point(6, 23); - this.radioIDefault.Name = "radioIDefault"; - this.radioIDefault.Size = new System.Drawing.Size(14, 13); - this.radioIDefault.TabIndex = 1; - this.radioIDefault.TabStop = true; - this.radioIDefault.UseVisualStyleBackColor = true; - // - // panelZ - // - this.panelZ.Controls.Add(this.flagZLabel); - this.panelZ.Controls.Add(this.radioZIndeterminate); - this.panelZ.Controls.Add(this.radioZOne); - this.panelZ.Controls.Add(this.radioZZero); - this.panelZ.Controls.Add(this.radioZDefault); - this.panelZ.Location = new System.Drawing.Point(300, 47); - this.panelZ.Name = "panelZ"; - this.panelZ.Size = new System.Drawing.Size(26, 110); - this.panelZ.TabIndex = 19; - // - // flagZLabel - // - this.flagZLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.flagZLabel.Location = new System.Drawing.Point(3, 0); - this.flagZLabel.Name = "flagZLabel"; - this.flagZLabel.Size = new System.Drawing.Size(20, 20); - this.flagZLabel.TabIndex = 0; - this.flagZLabel.Text = "Z"; - this.flagZLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter; - // - // radioZIndeterminate - // - this.radioZIndeterminate.AutoSize = true; - this.radioZIndeterminate.Location = new System.Drawing.Point(6, 83); - this.radioZIndeterminate.Name = "radioZIndeterminate"; - this.radioZIndeterminate.Size = new System.Drawing.Size(14, 13); - this.radioZIndeterminate.TabIndex = 4; - this.radioZIndeterminate.TabStop = true; - this.radioZIndeterminate.UseVisualStyleBackColor = true; - // - // radioZOne - // - this.radioZOne.AutoSize = true; - this.radioZOne.Location = new System.Drawing.Point(6, 63); - this.radioZOne.Name = "radioZOne"; - this.radioZOne.Size = new System.Drawing.Size(14, 13); - this.radioZOne.TabIndex = 3; - this.radioZOne.TabStop = true; - this.radioZOne.UseVisualStyleBackColor = true; - // - // radioZZero - // - this.radioZZero.AutoSize = true; - this.radioZZero.Location = new System.Drawing.Point(6, 43); - this.radioZZero.Name = "radioZZero"; - this.radioZZero.Size = new System.Drawing.Size(14, 13); - this.radioZZero.TabIndex = 2; - this.radioZZero.TabStop = true; - this.radioZZero.UseVisualStyleBackColor = true; - // - // radioZDefault - // - this.radioZDefault.AutoSize = true; - this.radioZDefault.Location = new System.Drawing.Point(6, 23); - this.radioZDefault.Name = "radioZDefault"; - this.radioZDefault.Size = new System.Drawing.Size(14, 13); - this.radioZDefault.TabIndex = 1; - this.radioZDefault.TabStop = true; - this.radioZDefault.UseVisualStyleBackColor = true; - // - // panelC - // - this.panelC.Controls.Add(this.flagCLabel); - this.panelC.Controls.Add(this.radioCIndeterminate); - this.panelC.Controls.Add(this.radioCOne); - this.panelC.Controls.Add(this.radioCZero); - this.panelC.Controls.Add(this.radioCDefault); - this.panelC.Location = new System.Drawing.Point(332, 47); - this.panelC.Name = "panelC"; - this.panelC.Size = new System.Drawing.Size(26, 110); - this.panelC.TabIndex = 20; - // - // flagCLabel - // - this.flagCLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.flagCLabel.Location = new System.Drawing.Point(3, 0); - this.flagCLabel.Name = "flagCLabel"; - this.flagCLabel.Size = new System.Drawing.Size(20, 20); - this.flagCLabel.TabIndex = 0; - this.flagCLabel.Text = "C"; - this.flagCLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter; - // - // radioCIndeterminate - // - this.radioCIndeterminate.AutoSize = true; - this.radioCIndeterminate.Location = new System.Drawing.Point(6, 83); - this.radioCIndeterminate.Name = "radioCIndeterminate"; - this.radioCIndeterminate.Size = new System.Drawing.Size(14, 13); - this.radioCIndeterminate.TabIndex = 4; - this.radioCIndeterminate.TabStop = true; - this.radioCIndeterminate.UseVisualStyleBackColor = true; - // - // radioCOne - // - this.radioCOne.AutoSize = true; - this.radioCOne.Location = new System.Drawing.Point(6, 63); - this.radioCOne.Name = "radioCOne"; - this.radioCOne.Size = new System.Drawing.Size(14, 13); - this.radioCOne.TabIndex = 3; - this.radioCOne.TabStop = true; - this.radioCOne.UseVisualStyleBackColor = true; - // - // radioCZero - // - this.radioCZero.AutoSize = true; - this.radioCZero.Location = new System.Drawing.Point(6, 43); - this.radioCZero.Name = "radioCZero"; - this.radioCZero.Size = new System.Drawing.Size(14, 13); - this.radioCZero.TabIndex = 2; - this.radioCZero.TabStop = true; - this.radioCZero.UseVisualStyleBackColor = true; - // - // radioCDefault - // - this.radioCDefault.AutoSize = true; - this.radioCDefault.Location = new System.Drawing.Point(6, 23); - this.radioCDefault.Name = "radioCDefault"; - this.radioCDefault.Size = new System.Drawing.Size(14, 13); - this.radioCDefault.TabIndex = 1; - this.radioCDefault.TabStop = true; - this.radioCDefault.UseVisualStyleBackColor = true; - // - // panelE - // - this.panelE.Controls.Add(this.flagELabel); - this.panelE.Controls.Add(this.radioEIndeterminate); - this.panelE.Controls.Add(this.radioEOne); - this.panelE.Controls.Add(this.radioEZero); - this.panelE.Controls.Add(this.radioEDefault); - this.panelE.Location = new System.Drawing.Point(381, 47); - this.panelE.Name = "panelE"; - this.panelE.Size = new System.Drawing.Size(26, 110); - this.panelE.TabIndex = 21; - // - // flagELabel - // - this.flagELabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.flagELabel.Location = new System.Drawing.Point(3, 0); - this.flagELabel.Name = "flagELabel"; - this.flagELabel.Size = new System.Drawing.Size(20, 20); - this.flagELabel.TabIndex = 0; - this.flagELabel.Text = "E"; - this.flagELabel.TextAlign = System.Drawing.ContentAlignment.TopCenter; - // - // radioEIndeterminate - // - this.radioEIndeterminate.AutoSize = true; - this.radioEIndeterminate.Location = new System.Drawing.Point(6, 83); - this.radioEIndeterminate.Name = "radioEIndeterminate"; - this.radioEIndeterminate.Size = new System.Drawing.Size(14, 13); - this.radioEIndeterminate.TabIndex = 4; - this.radioEIndeterminate.TabStop = true; - this.radioEIndeterminate.UseVisualStyleBackColor = true; - // - // radioEOne - // - this.radioEOne.AutoSize = true; - this.radioEOne.Location = new System.Drawing.Point(6, 63); - this.radioEOne.Name = "radioEOne"; - this.radioEOne.Size = new System.Drawing.Size(14, 13); - this.radioEOne.TabIndex = 3; - this.radioEOne.TabStop = true; - this.radioEOne.UseVisualStyleBackColor = true; - // - // radioEZero - // - this.radioEZero.AutoSize = true; - this.radioEZero.Location = new System.Drawing.Point(6, 43); - this.radioEZero.Name = "radioEZero"; - this.radioEZero.Size = new System.Drawing.Size(14, 13); - this.radioEZero.TabIndex = 2; - this.radioEZero.TabStop = true; - this.radioEZero.UseVisualStyleBackColor = true; - // - // radioEDefault - // - this.radioEDefault.AutoSize = true; - this.radioEDefault.Location = new System.Drawing.Point(6, 23); - this.radioEDefault.Name = "radioEDefault"; - this.radioEDefault.Size = new System.Drawing.Size(14, 13); - this.radioEDefault.TabIndex = 1; - this.radioEDefault.TabStop = true; - this.radioEDefault.UseVisualStyleBackColor = true; - // - // instructionLabel - // - this.instructionLabel.AutoSize = true; - this.instructionLabel.Location = new System.Drawing.Point(12, 9); - this.instructionLabel.Name = "instructionLabel"; - this.instructionLabel.Size = new System.Drawing.Size(297, 13); - this.instructionLabel.TabIndex = 3; - this.instructionLabel.Text = "Override processor state values determined by code analyzer:"; - // - // labelLongRegsNote - // - this.labelLongRegsNote.AutoSize = true; - this.labelLongRegsNote.Location = new System.Drawing.Point(13, 169); - this.labelLongRegsNote.Name = "labelLongRegsNote"; - this.labelLongRegsNote.Size = new System.Drawing.Size(341, 13); - this.labelLongRegsNote.TabIndex = 8; - this.labelLongRegsNote.Text = "Tip: to configure 16-bit registers on 65802/65816, set M, X, and E to 0."; - // - // resetButton - // - this.resetButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.resetButton.Location = new System.Drawing.Point(12, 205); - this.resetButton.Name = "resetButton"; - this.resetButton.Size = new System.Drawing.Size(112, 23); - this.resetButton.TabIndex = 2; - this.resetButton.Text = "Reset to Default"; - this.resetButton.UseVisualStyleBackColor = true; - this.resetButton.Click += new System.EventHandler(this.resetButton_Click); - // - // EditStatusFlags - // - this.AcceptButton = this.okButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(449, 240); - this.Controls.Add(this.resetButton); - this.Controls.Add(this.labelLongRegsNote); - this.Controls.Add(this.instructionLabel); - this.Controls.Add(this.panelE); - this.Controls.Add(this.panelC); - this.Controls.Add(this.panelZ); - this.Controls.Add(this.panelI); - this.Controls.Add(this.panelD); - this.Controls.Add(this.panelX); - this.Controls.Add(this.panelM); - this.Controls.Add(this.cancelButton); - this.Controls.Add(this.okButton); - this.Controls.Add(this.panelV); - this.Controls.Add(this.panelN); - this.Controls.Add(this.indeterminateLabel); - this.Controls.Add(this.oneLabel); - this.Controls.Add(this.zeroLabel); - this.Controls.Add(this.defaultLabel); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "EditStatusFlags"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Edit Status Flag Override"; - this.Load += new System.EventHandler(this.EditStatusFlags_Load); - this.panelN.ResumeLayout(false); - this.panelN.PerformLayout(); - this.panelV.ResumeLayout(false); - this.panelV.PerformLayout(); - this.panelM.ResumeLayout(false); - this.panelM.PerformLayout(); - this.panelX.ResumeLayout(false); - this.panelX.PerformLayout(); - this.panelD.ResumeLayout(false); - this.panelD.PerformLayout(); - this.panelI.ResumeLayout(false); - this.panelI.PerformLayout(); - this.panelZ.ResumeLayout(false); - this.panelZ.PerformLayout(); - this.panelC.ResumeLayout(false); - this.panelC.PerformLayout(); - this.panelE.ResumeLayout(false); - this.panelE.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label defaultLabel; - private System.Windows.Forms.Label zeroLabel; - private System.Windows.Forms.Label oneLabel; - private System.Windows.Forms.Label indeterminateLabel; - private System.Windows.Forms.Panel panelN; - private System.Windows.Forms.Label flagNLabel; - private System.Windows.Forms.RadioButton radioNIndeterminate; - private System.Windows.Forms.RadioButton radioNOne; - private System.Windows.Forms.RadioButton radioNZero; - private System.Windows.Forms.RadioButton radioNDefault; - private System.Windows.Forms.Panel panelV; - private System.Windows.Forms.Label flagVLabel; - private System.Windows.Forms.RadioButton radioVIndeterminate; - private System.Windows.Forms.RadioButton radioVOne; - private System.Windows.Forms.RadioButton radioVZero; - private System.Windows.Forms.RadioButton radioVDefault; - private System.Windows.Forms.Button okButton; - private System.Windows.Forms.Button cancelButton; - private System.Windows.Forms.Panel panelM; - private System.Windows.Forms.Label flagMLabel; - private System.Windows.Forms.RadioButton radioMIndeterminate; - private System.Windows.Forms.RadioButton radioMOne; - private System.Windows.Forms.RadioButton radioMZero; - private System.Windows.Forms.RadioButton radioMDefault; - private System.Windows.Forms.Panel panelX; - private System.Windows.Forms.Label flagXLabel; - private System.Windows.Forms.RadioButton radioXIndeterminate; - private System.Windows.Forms.RadioButton radioXOne; - private System.Windows.Forms.RadioButton radioXZero; - private System.Windows.Forms.RadioButton radioXDefault; - private System.Windows.Forms.Panel panelD; - private System.Windows.Forms.Label flagDLabel; - private System.Windows.Forms.RadioButton radioDIndeterminate; - private System.Windows.Forms.RadioButton radioDOne; - private System.Windows.Forms.RadioButton radioDZero; - private System.Windows.Forms.RadioButton radioDDefault; - private System.Windows.Forms.Panel panelI; - private System.Windows.Forms.Label flagILabel; - private System.Windows.Forms.RadioButton radioIIndeterminate; - private System.Windows.Forms.RadioButton radioIOne; - private System.Windows.Forms.RadioButton radioIZero; - private System.Windows.Forms.RadioButton radioIDefault; - private System.Windows.Forms.Panel panelZ; - private System.Windows.Forms.Label flagZLabel; - private System.Windows.Forms.RadioButton radioZIndeterminate; - private System.Windows.Forms.RadioButton radioZOne; - private System.Windows.Forms.RadioButton radioZZero; - private System.Windows.Forms.RadioButton radioZDefault; - private System.Windows.Forms.Panel panelC; - private System.Windows.Forms.Label flagCLabel; - private System.Windows.Forms.RadioButton radioCIndeterminate; - private System.Windows.Forms.RadioButton radioCOne; - private System.Windows.Forms.RadioButton radioCZero; - private System.Windows.Forms.RadioButton radioCDefault; - private System.Windows.Forms.Panel panelE; - private System.Windows.Forms.Label flagELabel; - private System.Windows.Forms.RadioButton radioEIndeterminate; - private System.Windows.Forms.RadioButton radioEOne; - private System.Windows.Forms.RadioButton radioEZero; - private System.Windows.Forms.RadioButton radioEDefault; - private System.Windows.Forms.Label instructionLabel; - private System.Windows.Forms.Label labelLongRegsNote; - private System.Windows.Forms.Button resetButton; - } -} diff --git a/SourceGenWF/AppForms/EditStatusFlags.cs b/SourceGenWF/AppForms/EditStatusFlags.cs deleted file mode 100644 index 0438c45..0000000 --- a/SourceGenWF/AppForms/EditStatusFlags.cs +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Diagnostics; -using System.Windows.Forms; - -using Asm65; - -namespace SourceGenWF.AppForms { - public partial class EditStatusFlags : Form { - /// - /// In/out status flag value. - /// - public StatusFlags FlagValue { get; private set; } - - /// - /// Set this if the CPU has an emulation flag (65802/65816). If this isn't - /// set, the M, X, and E flag buttons will be disabled. - /// - private bool mHasEmuFlag; - - - public EditStatusFlags(StatusFlags flagValue, bool hasEmuFlag) { - InitializeComponent(); - - FlagValue = flagValue; - mHasEmuFlag = hasEmuFlag; - } - - private void EditStatusFlags_Load(object sender, EventArgs e) { - if (!mHasEmuFlag) { - panelM.Enabled = false; - panelX.Enabled = false; - panelE.Enabled = false; - - // I'm not going to force the M/X/E flags to have a particular value based - // on the CPU definition. The flags aren't used for non-65802/65816, so - // the values are irrelevant. If somebody is switching between CPUs I think - // it'd be weird to force the values during editing but leave any non-edited - // values alone. If they want to switch to 65816, set M/X/E, and then switch - // back, they're welcome to do so. - } - - SetCheckedButtons(); - } - - /// - /// Calls SetChecked() for each flag. - /// - private void SetCheckedButtons() { - SetChecked(FlagValue.N, radioNDefault, radioNZero, radioNOne, radioNIndeterminate); - SetChecked(FlagValue.V, radioVDefault, radioVZero, radioVOne, radioVIndeterminate); - SetChecked(FlagValue.M, radioMDefault, radioMZero, radioMOne, radioMIndeterminate); - SetChecked(FlagValue.X, radioXDefault, radioXZero, radioXOne, radioXIndeterminate); - SetChecked(FlagValue.D, radioDDefault, radioDZero, radioDOne, radioDIndeterminate); - SetChecked(FlagValue.I, radioIDefault, radioIZero, radioIOne, radioIIndeterminate); - SetChecked(FlagValue.Z, radioZDefault, radioZZero, radioZOne, radioZIndeterminate); - SetChecked(FlagValue.C, radioCDefault, radioCZero, radioCOne, radioCIndeterminate); - SetChecked(FlagValue.E, radioEDefault, radioEZero, radioEOne, radioEIndeterminate); - } - - /// - /// Sets the "checked" flag on the appropriate radio button. - /// - private void SetChecked(int value, RadioButton def, RadioButton zero, RadioButton one, - RadioButton indeterminate) { - switch (value) { - case TriState16.UNSPECIFIED: - def.Checked = true; - break; - case TriState16.INDETERMINATE: - indeterminate.Checked = true; - break; - case 0: - zero.Checked = true; - break; - case 1: - one.Checked = true; - break; - default: - throw new Exception("Unexpected value " + value); - } - } - - private void okButton_Click(object sender, EventArgs e) { - StatusFlags flags = new StatusFlags(); - - flags.N = GetChecked(radioNDefault, radioNZero, radioNOne, radioNIndeterminate); - flags.V = GetChecked(radioVDefault, radioVZero, radioVOne, radioVIndeterminate); - flags.M = GetChecked(radioMDefault, radioMZero, radioMOne, radioMIndeterminate); - flags.X = GetChecked(radioXDefault, radioXZero, radioXOne, radioXIndeterminate); - flags.D = GetChecked(radioDDefault, radioDZero, radioDOne, radioDIndeterminate); - flags.I = GetChecked(radioIDefault, radioIZero, radioIOne, radioIIndeterminate); - flags.Z = GetChecked(radioZDefault, radioZZero, radioZOne, radioZIndeterminate); - flags.C = GetChecked(radioCDefault, radioCZero, radioCOne, radioCIndeterminate); - flags.E = GetChecked(radioEDefault, radioEZero, radioEOne, radioEIndeterminate); - - //// If they're setting emulation mode, also set M/X to 1. This is implicitly - //// true, but things are a bit clearer if we make it explicit. - //if (flags.E == 1) { - // flags.M = flags.X = 1; - //} - - FlagValue = flags; - } - - /// - /// Identifies the checked radio button and returns the appropriate TriState16 value. - /// - private int GetChecked(RadioButton def, RadioButton zero, RadioButton one, - RadioButton indeterminate) { - if (zero.Checked) { - return 0; - } else if (one.Checked) { - return 1; - } else if (indeterminate.Checked) { - return TriState16.INDETERMINATE; - } else if (def.Checked) { - return TriState16.UNSPECIFIED; - } else { - throw new Exception("No radio button selected"); - } - } - - private void resetButton_Click(object sender, EventArgs e) { - FlagValue = new StatusFlags(); - SetCheckedButtons(); - } - } -} diff --git a/SourceGenWF/AppForms/EditStatusFlags.resx b/SourceGenWF/AppForms/EditStatusFlags.resx deleted file mode 100644 index 1af7de1..0000000 --- a/SourceGenWF/AppForms/EditStatusFlags.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SourceGenWF/AppForms/FindBox.Designer.cs b/SourceGenWF/AppForms/FindBox.Designer.cs deleted file mode 100644 index 9a6a98a..0000000 --- a/SourceGenWF/AppForms/FindBox.Designer.cs +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AppForms { - partial class FindBox { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.okButton = new System.Windows.Forms.Button(); - this.findTextBox = new System.Windows.Forms.TextBox(); - this.SuspendLayout(); - // - // okButton - // - this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.okButton.Location = new System.Drawing.Point(222, 13); - this.okButton.Name = "okButton"; - this.okButton.Size = new System.Drawing.Size(75, 23); - this.okButton.TabIndex = 1; - this.okButton.Text = "Find"; - this.okButton.UseVisualStyleBackColor = true; - this.okButton.Click += new System.EventHandler(this.okButton_Click); - // - // findTextBox - // - this.findTextBox.Location = new System.Drawing.Point(12, 15); - this.findTextBox.Name = "findTextBox"; - this.findTextBox.Size = new System.Drawing.Size(197, 20); - this.findTextBox.TabIndex = 0; - // - // FindBox - // - this.AcceptButton = this.okButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(309, 48); - this.Controls.Add(this.findTextBox); - this.Controls.Add(this.okButton); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "FindBox"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Find..."; - this.Load += new System.EventHandler(this.FindBox_Load); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - private System.Windows.Forms.Button okButton; - private System.Windows.Forms.TextBox findTextBox; - } -} \ No newline at end of file diff --git a/SourceGenWF/AppForms/FindBox.cs b/SourceGenWF/AppForms/FindBox.cs deleted file mode 100644 index e3b1710..0000000 --- a/SourceGenWF/AppForms/FindBox.cs +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Windows.Forms; - -namespace SourceGenWF.AppForms { - public partial class FindBox : Form { - /// - /// Text to find. On success, holds the string searched for. - /// - public string TextToFind { get; private set; } - - - public FindBox(string findStr) { - InitializeComponent(); - - TextToFind = findStr; - } - - private void FindBox_Load(object sender, EventArgs e) { - if (!string.IsNullOrEmpty(TextToFind)) { - findTextBox.Text = TextToFind; - findTextBox.SelectAll(); - } - } - - // Without a "cancel" button, the escape key does nothing. - protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { - if (keyData == Keys.Escape) { - Close(); - return true; - } - return base.ProcessCmdKey(ref msg, keyData); - } - - private void okButton_Click(object sender, EventArgs e) { - TextToFind = findTextBox.Text; - } - } -} diff --git a/SourceGenWF/AppForms/FindBox.resx b/SourceGenWF/AppForms/FindBox.resx deleted file mode 100644 index 1af7de1..0000000 --- a/SourceGenWF/AppForms/FindBox.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SourceGenWF/AppForms/FormatSplitAddress.Designer.cs b/SourceGenWF/AppForms/FormatSplitAddress.Designer.cs deleted file mode 100644 index e635091..0000000 --- a/SourceGenWF/AppForms/FormatSplitAddress.Designer.cs +++ /dev/null @@ -1,495 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AppForms { - partial class FormatSplitAddress { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - System.Windows.Forms.ListViewItem listViewItem8 = new System.Windows.Forms.ListViewItem(new string[] { - "12/3456", - "+123456", - "(+) T_123456"}, -1); - this.cancelButton = new System.Windows.Forms.Button(); - this.okButton = new System.Windows.Forms.Button(); - this.selectionInfoLabel = new System.Windows.Forms.Label(); - this.addressCharacteristicsGroup = new System.Windows.Forms.GroupBox(); - this.pushRtsCheckBox = new System.Windows.Forms.CheckBox(); - this.width24Radio = new System.Windows.Forms.RadioButton(); - this.width16Radio = new System.Windows.Forms.RadioButton(); - this.lowByteGroupBox = new System.Windows.Forms.GroupBox(); - this.lowThirdPartRadio = new System.Windows.Forms.RadioButton(); - this.lowSecondPartRadio = new System.Windows.Forms.RadioButton(); - this.lowFirstPartRadio = new System.Windows.Forms.RadioButton(); - this.highByteGroupBox = new System.Windows.Forms.GroupBox(); - this.highConstantTextBox = new System.Windows.Forms.TextBox(); - this.highConstantRadio = new System.Windows.Forms.RadioButton(); - this.highThirdPartRadio = new System.Windows.Forms.RadioButton(); - this.highSecondPartRadio = new System.Windows.Forms.RadioButton(); - this.highFirstPartRadio = new System.Windows.Forms.RadioButton(); - this.bankByteGroupBox = new System.Windows.Forms.GroupBox(); - this.bankConstantTextBox = new System.Windows.Forms.TextBox(); - this.bankNthPartRadio = new System.Windows.Forms.RadioButton(); - this.bankConstantRadio = new System.Windows.Forms.RadioButton(); - this.outputPreviewListView = new System.Windows.Forms.ListView(); - this.addrColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.symbolColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.outputPreviewGroupBox = new System.Windows.Forms.GroupBox(); - this.invalidConstantLabel = new System.Windows.Forms.Label(); - this.incompatibleSelectionLabel = new System.Windows.Forms.Label(); - this.addCodeHintCheckBox = new System.Windows.Forms.CheckBox(); - this.optionsGroupBox = new System.Windows.Forms.GroupBox(); - this.offsetColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.addressCharacteristicsGroup.SuspendLayout(); - this.lowByteGroupBox.SuspendLayout(); - this.highByteGroupBox.SuspendLayout(); - this.bankByteGroupBox.SuspendLayout(); - this.outputPreviewGroupBox.SuspendLayout(); - this.optionsGroupBox.SuspendLayout(); - this.SuspendLayout(); - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.Location = new System.Drawing.Point(461, 461); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 23); - this.cancelButton.TabIndex = 8; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - // - // okButton - // - this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.okButton.Location = new System.Drawing.Point(380, 461); - this.okButton.Name = "okButton"; - this.okButton.Size = new System.Drawing.Size(75, 23); - this.okButton.TabIndex = 7; - this.okButton.Text = "OK"; - this.okButton.UseVisualStyleBackColor = true; - this.okButton.Click += new System.EventHandler(this.okButton_Click); - // - // selectionInfoLabel - // - this.selectionInfoLabel.AutoSize = true; - this.selectionInfoLabel.Location = new System.Drawing.Point(13, 13); - this.selectionInfoLabel.Name = "selectionInfoLabel"; - this.selectionInfoLabel.Size = new System.Drawing.Size(213, 13); - this.selectionInfoLabel.TabIndex = 0; - this.selectionInfoLabel.Text = "There are {0} bytes selected, in {1} group(s)"; - // - // addressCharacteristicsGroup - // - this.addressCharacteristicsGroup.Controls.Add(this.pushRtsCheckBox); - this.addressCharacteristicsGroup.Controls.Add(this.width24Radio); - this.addressCharacteristicsGroup.Controls.Add(this.width16Radio); - this.addressCharacteristicsGroup.Location = new System.Drawing.Point(16, 40); - this.addressCharacteristicsGroup.Name = "addressCharacteristicsGroup"; - this.addressCharacteristicsGroup.Size = new System.Drawing.Size(204, 90); - this.addressCharacteristicsGroup.TabIndex = 1; - this.addressCharacteristicsGroup.TabStop = false; - this.addressCharacteristicsGroup.Text = "Address Characteristics"; - // - // pushRtsCheckBox - // - this.pushRtsCheckBox.AutoSize = true; - this.pushRtsCheckBox.Location = new System.Drawing.Point(7, 68); - this.pushRtsCheckBox.Name = "pushRtsCheckBox"; - this.pushRtsCheckBox.Size = new System.Drawing.Size(184, 17); - this.pushRtsCheckBox.TabIndex = 2; - this.pushRtsCheckBox.Text = "Adjusted for RTS/RTL (target - 1)"; - this.pushRtsCheckBox.UseVisualStyleBackColor = true; - this.pushRtsCheckBox.CheckedChanged += new System.EventHandler(this.pushRtsCheckBox_CheckedChanged); - // - // width24Radio - // - this.width24Radio.AutoSize = true; - this.width24Radio.Location = new System.Drawing.Point(7, 44); - this.width24Radio.Name = "width24Radio"; - this.width24Radio.Size = new System.Drawing.Size(51, 17); - this.width24Radio.TabIndex = 1; - this.width24Radio.TabStop = true; - this.width24Radio.Text = "24-bit"; - this.width24Radio.UseVisualStyleBackColor = true; - this.width24Radio.CheckedChanged += new System.EventHandler(this.widthRadio_CheckedChanged); - // - // width16Radio - // - this.width16Radio.AutoSize = true; - this.width16Radio.Location = new System.Drawing.Point(7, 20); - this.width16Radio.Name = "width16Radio"; - this.width16Radio.Size = new System.Drawing.Size(51, 17); - this.width16Radio.TabIndex = 0; - this.width16Radio.TabStop = true; - this.width16Radio.Text = "16-bit"; - this.width16Radio.UseVisualStyleBackColor = true; - this.width16Radio.CheckedChanged += new System.EventHandler(this.widthRadio_CheckedChanged); - // - // lowByteGroupBox - // - this.lowByteGroupBox.Controls.Add(this.lowThirdPartRadio); - this.lowByteGroupBox.Controls.Add(this.lowSecondPartRadio); - this.lowByteGroupBox.Controls.Add(this.lowFirstPartRadio); - this.lowByteGroupBox.Location = new System.Drawing.Point(13, 136); - this.lowByteGroupBox.Name = "lowByteGroupBox"; - this.lowByteGroupBox.Size = new System.Drawing.Size(207, 94); - this.lowByteGroupBox.TabIndex = 2; - this.lowByteGroupBox.TabStop = false; - this.lowByteGroupBox.Text = "Low Bytes"; - // - // lowThirdPartRadio - // - this.lowThirdPartRadio.AutoSize = true; - this.lowThirdPartRadio.Location = new System.Drawing.Point(10, 68); - this.lowThirdPartRadio.Name = "lowThirdPartRadio"; - this.lowThirdPartRadio.Size = new System.Drawing.Size(127, 17); - this.lowThirdPartRadio.TabIndex = 2; - this.lowThirdPartRadio.TabStop = true; - this.lowThirdPartRadio.Text = "Third part of selection"; - this.lowThirdPartRadio.UseVisualStyleBackColor = true; - this.lowThirdPartRadio.CheckedChanged += new System.EventHandler(this.lowByte_CheckedChanged); - // - // lowSecondPartRadio - // - this.lowSecondPartRadio.AutoSize = true; - this.lowSecondPartRadio.Location = new System.Drawing.Point(10, 44); - this.lowSecondPartRadio.Name = "lowSecondPartRadio"; - this.lowSecondPartRadio.Size = new System.Drawing.Size(140, 17); - this.lowSecondPartRadio.TabIndex = 1; - this.lowSecondPartRadio.TabStop = true; - this.lowSecondPartRadio.Text = "Second part of selection"; - this.lowSecondPartRadio.UseVisualStyleBackColor = true; - this.lowSecondPartRadio.CheckedChanged += new System.EventHandler(this.lowByte_CheckedChanged); - // - // lowFirstPartRadio - // - this.lowFirstPartRadio.AutoSize = true; - this.lowFirstPartRadio.Location = new System.Drawing.Point(10, 20); - this.lowFirstPartRadio.Name = "lowFirstPartRadio"; - this.lowFirstPartRadio.Size = new System.Drawing.Size(122, 17); - this.lowFirstPartRadio.TabIndex = 0; - this.lowFirstPartRadio.TabStop = true; - this.lowFirstPartRadio.Text = "First part of selection"; - this.lowFirstPartRadio.UseVisualStyleBackColor = true; - this.lowFirstPartRadio.CheckedChanged += new System.EventHandler(this.lowByte_CheckedChanged); - // - // highByteGroupBox - // - this.highByteGroupBox.Controls.Add(this.highConstantTextBox); - this.highByteGroupBox.Controls.Add(this.highConstantRadio); - this.highByteGroupBox.Controls.Add(this.highThirdPartRadio); - this.highByteGroupBox.Controls.Add(this.highSecondPartRadio); - this.highByteGroupBox.Controls.Add(this.highFirstPartRadio); - this.highByteGroupBox.Location = new System.Drawing.Point(13, 236); - this.highByteGroupBox.Name = "highByteGroupBox"; - this.highByteGroupBox.Size = new System.Drawing.Size(207, 120); - this.highByteGroupBox.TabIndex = 3; - this.highByteGroupBox.TabStop = false; - this.highByteGroupBox.Text = "High Bytes"; - // - // highConstantTextBox - // - this.highConstantTextBox.Location = new System.Drawing.Point(87, 91); - this.highConstantTextBox.MaxLength = 10; - this.highConstantTextBox.Name = "highConstantTextBox"; - this.highConstantTextBox.Size = new System.Drawing.Size(93, 20); - this.highConstantTextBox.TabIndex = 4; - this.highConstantTextBox.TextChanged += new System.EventHandler(this.highConstantTextBox_TextChanged); - // - // highConstantRadio - // - this.highConstantRadio.AutoSize = true; - this.highConstantRadio.Location = new System.Drawing.Point(10, 92); - this.highConstantRadio.Name = "highConstantRadio"; - this.highConstantRadio.Size = new System.Drawing.Size(70, 17); - this.highConstantRadio.TabIndex = 3; - this.highConstantRadio.TabStop = true; - this.highConstantRadio.Text = "Constant:"; - this.highConstantRadio.UseVisualStyleBackColor = true; - this.highConstantRadio.CheckedChanged += new System.EventHandler(this.highByte_CheckedChanged); - // - // highThirdPartRadio - // - this.highThirdPartRadio.AutoSize = true; - this.highThirdPartRadio.Location = new System.Drawing.Point(10, 68); - this.highThirdPartRadio.Name = "highThirdPartRadio"; - this.highThirdPartRadio.Size = new System.Drawing.Size(127, 17); - this.highThirdPartRadio.TabIndex = 2; - this.highThirdPartRadio.TabStop = true; - this.highThirdPartRadio.Text = "Third part of selection"; - this.highThirdPartRadio.UseVisualStyleBackColor = true; - this.highThirdPartRadio.CheckedChanged += new System.EventHandler(this.highByte_CheckedChanged); - // - // highSecondPartRadio - // - this.highSecondPartRadio.AutoSize = true; - this.highSecondPartRadio.Location = new System.Drawing.Point(10, 44); - this.highSecondPartRadio.Name = "highSecondPartRadio"; - this.highSecondPartRadio.Size = new System.Drawing.Size(140, 17); - this.highSecondPartRadio.TabIndex = 1; - this.highSecondPartRadio.TabStop = true; - this.highSecondPartRadio.Text = "Second part of selection"; - this.highSecondPartRadio.UseVisualStyleBackColor = true; - this.highSecondPartRadio.CheckedChanged += new System.EventHandler(this.highByte_CheckedChanged); - // - // highFirstPartRadio - // - this.highFirstPartRadio.AutoSize = true; - this.highFirstPartRadio.Location = new System.Drawing.Point(10, 20); - this.highFirstPartRadio.Name = "highFirstPartRadio"; - this.highFirstPartRadio.Size = new System.Drawing.Size(122, 17); - this.highFirstPartRadio.TabIndex = 0; - this.highFirstPartRadio.TabStop = true; - this.highFirstPartRadio.Text = "First part of selection"; - this.highFirstPartRadio.UseVisualStyleBackColor = true; - this.highFirstPartRadio.CheckedChanged += new System.EventHandler(this.highByte_CheckedChanged); - // - // bankByteGroupBox - // - this.bankByteGroupBox.Controls.Add(this.bankConstantTextBox); - this.bankByteGroupBox.Controls.Add(this.bankNthPartRadio); - this.bankByteGroupBox.Controls.Add(this.bankConstantRadio); - this.bankByteGroupBox.Location = new System.Drawing.Point(13, 362); - this.bankByteGroupBox.Name = "bankByteGroupBox"; - this.bankByteGroupBox.Size = new System.Drawing.Size(207, 70); - this.bankByteGroupBox.TabIndex = 4; - this.bankByteGroupBox.TabStop = false; - this.bankByteGroupBox.Text = "Bank Bytes"; - // - // bankConstantTextBox - // - this.bankConstantTextBox.Location = new System.Drawing.Point(87, 41); - this.bankConstantTextBox.MaxLength = 10; - this.bankConstantTextBox.Name = "bankConstantTextBox"; - this.bankConstantTextBox.Size = new System.Drawing.Size(93, 20); - this.bankConstantTextBox.TabIndex = 2; - this.bankConstantTextBox.TextChanged += new System.EventHandler(this.bankConstantTextBox_TextChanged); - // - // bankNthPartRadio - // - this.bankNthPartRadio.AutoSize = true; - this.bankNthPartRadio.Location = new System.Drawing.Point(10, 19); - this.bankNthPartRadio.Name = "bankNthPartRadio"; - this.bankNthPartRadio.Size = new System.Drawing.Size(120, 17); - this.bankNthPartRadio.TabIndex = 0; - this.bankNthPartRadio.TabStop = true; - this.bankNthPartRadio.Text = "Nth part of selection"; - this.bankNthPartRadio.UseVisualStyleBackColor = true; - this.bankNthPartRadio.CheckedChanged += new System.EventHandler(this.bankByte_CheckedChanged); - // - // bankConstantRadio - // - this.bankConstantRadio.AutoSize = true; - this.bankConstantRadio.Location = new System.Drawing.Point(10, 42); - this.bankConstantRadio.Name = "bankConstantRadio"; - this.bankConstantRadio.Size = new System.Drawing.Size(70, 17); - this.bankConstantRadio.TabIndex = 1; - this.bankConstantRadio.TabStop = true; - this.bankConstantRadio.Text = "Constant:"; - this.bankConstantRadio.UseVisualStyleBackColor = true; - this.bankConstantRadio.CheckedChanged += new System.EventHandler(this.bankByte_CheckedChanged); - // - // outputPreviewListView - // - this.outputPreviewListView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.outputPreviewListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.addrColumnHeader, - this.offsetColumnHeader, - this.symbolColumnHeader}); - this.outputPreviewListView.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.outputPreviewListView.FullRowSelect = true; - this.outputPreviewListView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; - this.outputPreviewListView.Items.AddRange(new System.Windows.Forms.ListViewItem[] { - listViewItem8}); - this.outputPreviewListView.Location = new System.Drawing.Point(6, 19); - this.outputPreviewListView.MultiSelect = false; - this.outputPreviewListView.Name = "outputPreviewListView"; - this.outputPreviewListView.Size = new System.Drawing.Size(290, 369); - this.outputPreviewListView.TabIndex = 0; - this.outputPreviewListView.UseCompatibleStateImageBehavior = false; - this.outputPreviewListView.View = System.Windows.Forms.View.Details; - // - // addrColumnHeader - // - this.addrColumnHeader.Text = "Addr"; - this.addrColumnHeader.Width = 52; - // - // symbolColumnHeader - // - this.symbolColumnHeader.Text = "Symbol"; - this.symbolColumnHeader.Width = 174; - // - // outputPreviewGroupBox - // - this.outputPreviewGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.outputPreviewGroupBox.Controls.Add(this.invalidConstantLabel); - this.outputPreviewGroupBox.Controls.Add(this.incompatibleSelectionLabel); - this.outputPreviewGroupBox.Controls.Add(this.outputPreviewListView); - this.outputPreviewGroupBox.Location = new System.Drawing.Point(234, 40); - this.outputPreviewGroupBox.Name = "outputPreviewGroupBox"; - this.outputPreviewGroupBox.Size = new System.Drawing.Size(302, 393); - this.outputPreviewGroupBox.TabIndex = 6; - this.outputPreviewGroupBox.TabStop = false; - this.outputPreviewGroupBox.Text = "Generated Addresses"; - // - // invalidConstantLabel - // - this.invalidConstantLabel.AutoSize = true; - this.invalidConstantLabel.BackColor = System.Drawing.SystemColors.Window; - this.invalidConstantLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.invalidConstantLabel.ForeColor = System.Drawing.Color.Red; - this.invalidConstantLabel.Location = new System.Drawing.Point(101, 200); - this.invalidConstantLabel.Name = "invalidConstantLabel"; - this.invalidConstantLabel.Size = new System.Drawing.Size(100, 16); - this.invalidConstantLabel.TabIndex = 2; - this.invalidConstantLabel.Text = "Invalid constant"; - // - // incompatibleSelectionLabel - // - this.incompatibleSelectionLabel.AutoSize = true; - this.incompatibleSelectionLabel.BackColor = System.Drawing.SystemColors.Window; - this.incompatibleSelectionLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.incompatibleSelectionLabel.ForeColor = System.Drawing.Color.Red; - this.incompatibleSelectionLabel.Location = new System.Drawing.Point(43, 177); - this.incompatibleSelectionLabel.Name = "incompatibleSelectionLabel"; - this.incompatibleSelectionLabel.Size = new System.Drawing.Size(216, 16); - this.incompatibleSelectionLabel.TabIndex = 1; - this.incompatibleSelectionLabel.Text = "Options incompatible with selection"; - // - // addCodeHintCheckBox - // - this.addCodeHintCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left))); - this.addCodeHintCheckBox.AutoSize = true; - this.addCodeHintCheckBox.Location = new System.Drawing.Point(10, 19); - this.addCodeHintCheckBox.Name = "addCodeHintCheckBox"; - this.addCodeHintCheckBox.Size = new System.Drawing.Size(165, 17); - this.addCodeHintCheckBox.TabIndex = 0; - this.addCodeHintCheckBox.Text = "Add code entry hint if needed"; - this.addCodeHintCheckBox.UseVisualStyleBackColor = true; - // - // optionsGroupBox - // - this.optionsGroupBox.Controls.Add(this.addCodeHintCheckBox); - this.optionsGroupBox.Location = new System.Drawing.Point(13, 439); - this.optionsGroupBox.Name = "optionsGroupBox"; - this.optionsGroupBox.Size = new System.Drawing.Size(207, 43); - this.optionsGroupBox.TabIndex = 5; - this.optionsGroupBox.TabStop = false; - this.optionsGroupBox.Text = "Options"; - // - // offsetColumnHeader - // - this.offsetColumnHeader.Text = "Offset"; - this.offsetColumnHeader.Width = 55; - // - // FormatSplitAddress - // - this.AcceptButton = this.okButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(548, 496); - this.Controls.Add(this.optionsGroupBox); - this.Controls.Add(this.outputPreviewGroupBox); - this.Controls.Add(this.bankByteGroupBox); - this.Controls.Add(this.highByteGroupBox); - this.Controls.Add(this.lowByteGroupBox); - this.Controls.Add(this.addressCharacteristicsGroup); - this.Controls.Add(this.selectionInfoLabel); - this.Controls.Add(this.okButton); - this.Controls.Add(this.cancelButton); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "FormatSplitAddress"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Format Split-Address Table"; - this.Load += new System.EventHandler(this.FormatSplitAddress_Load); - this.addressCharacteristicsGroup.ResumeLayout(false); - this.addressCharacteristicsGroup.PerformLayout(); - this.lowByteGroupBox.ResumeLayout(false); - this.lowByteGroupBox.PerformLayout(); - this.highByteGroupBox.ResumeLayout(false); - this.highByteGroupBox.PerformLayout(); - this.bankByteGroupBox.ResumeLayout(false); - this.bankByteGroupBox.PerformLayout(); - this.outputPreviewGroupBox.ResumeLayout(false); - this.outputPreviewGroupBox.PerformLayout(); - this.optionsGroupBox.ResumeLayout(false); - this.optionsGroupBox.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Button cancelButton; - private System.Windows.Forms.Button okButton; - private System.Windows.Forms.Label selectionInfoLabel; - private System.Windows.Forms.GroupBox addressCharacteristicsGroup; - private System.Windows.Forms.RadioButton width16Radio; - private System.Windows.Forms.RadioButton width24Radio; - private System.Windows.Forms.CheckBox pushRtsCheckBox; - private System.Windows.Forms.GroupBox lowByteGroupBox; - private System.Windows.Forms.RadioButton lowFirstPartRadio; - private System.Windows.Forms.RadioButton lowSecondPartRadio; - private System.Windows.Forms.RadioButton lowThirdPartRadio; - private System.Windows.Forms.GroupBox highByteGroupBox; - private System.Windows.Forms.RadioButton highFirstPartRadio; - private System.Windows.Forms.RadioButton highSecondPartRadio; - private System.Windows.Forms.RadioButton highThirdPartRadio; - private System.Windows.Forms.RadioButton highConstantRadio; - private System.Windows.Forms.TextBox highConstantTextBox; - private System.Windows.Forms.GroupBox bankByteGroupBox; - private System.Windows.Forms.ListView outputPreviewListView; - private System.Windows.Forms.ColumnHeader addrColumnHeader; - private System.Windows.Forms.ColumnHeader symbolColumnHeader; - private System.Windows.Forms.RadioButton bankConstantRadio; - private System.Windows.Forms.RadioButton bankNthPartRadio; - private System.Windows.Forms.TextBox bankConstantTextBox; - private System.Windows.Forms.GroupBox outputPreviewGroupBox; - private System.Windows.Forms.CheckBox addCodeHintCheckBox; - private System.Windows.Forms.GroupBox optionsGroupBox; - private System.Windows.Forms.Label incompatibleSelectionLabel; - private System.Windows.Forms.Label invalidConstantLabel; - private System.Windows.Forms.ColumnHeader offsetColumnHeader; - } -} \ No newline at end of file diff --git a/SourceGenWF/AppForms/FormatSplitAddress.cs b/SourceGenWF/AppForms/FormatSplitAddress.cs deleted file mode 100644 index 5f01c64..0000000 --- a/SourceGenWF/AppForms/FormatSplitAddress.cs +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Windows.Forms; - -using Asm65; -using CommonUtil; -using CommonWinForms; - -namespace SourceGenWF.AppForms { - public partial class FormatSplitAddress : Form { - /// - /// Format descriptors to apply. - /// - public SortedList NewFormatDescriptors { get; private set; } - - /// - /// User labels to apply. - /// - public Dictionary NewUserLabels { get; private set; } - - /// - /// All target offsets found. The list may contain redundant entries. - /// - public List AllTargetOffsets { get; private set; } - - public bool WantCodeHints { - get { - return addCodeHintCheckBox.Checked; - } - } - - /// - /// Selected offsets. An otherwise contiguous range of offsets can be broken up - /// by user-specified labels and address discontinuities, so this needs to be - /// processed by range. - /// - private TypedRangeSet mSelection; - - /// - /// Project reference. - /// - private DisasmProject mProject; - - /// - /// Formatter to use when displaying addresses and hex values. - /// - private Formatter mFormatter; - - /// - /// Set to prevent controls from going nuts while initializing. - /// - private bool mInitializing; - - /// - /// Set to true when valid output is available. - /// - private bool mOutputReady; - - - public FormatSplitAddress(DisasmProject project, TypedRangeSet selection, - Formatter formatter) { - InitializeComponent(); - - mProject = project; - mFormatter = formatter; - mSelection = selection; - - mOutputReady = false; - } - - private void FormatSplitAddress_Load(object sender, EventArgs e) { - mInitializing = true; - - string fmt = selectionInfoLabel.Text; - selectionInfoLabel.Text = string.Format(fmt, mSelection.Count, mSelection.RangeCount); - - width16Radio.Checked = true; - lowFirstPartRadio.Checked = true; - highSecondPartRadio.Checked = true; - bankNthPartRadio.Checked = true; - - incompatibleSelectionLabel.Visible = invalidConstantLabel.Visible = false; - - if (mProject.CpuDef.HasAddr16) { - // Disable the 24-bit option. Having 16-bit selected will disable the rest. - width24Radio.Enabled = false; - } - - outputPreviewListView.SetDoubleBuffered(true); - - mInitializing = false; - UpdateControls(); - } - - private void okButton_Click(object sender, EventArgs e) { } - - private void UpdateControls() { - if (mInitializing) { - return; - } - mInitializing = true; // no re-entry - - lowThirdPartRadio.Enabled = width24Radio.Checked; - highThirdPartRadio.Enabled = width24Radio.Checked; - bankByteGroupBox.Enabled = width24Radio.Checked; - - lowSecondPartRadio.Enabled = true; - - // If the user selects "constant" for high byte or bank byte, then there is no - // 3rd part available for low/high, so we need to turn those back off. - if (width24Radio.Checked) { - bool haveThree = !(highConstantRadio.Checked || bankConstantRadio.Checked); - lowThirdPartRadio.Enabled = haveThree; - highThirdPartRadio.Enabled = haveThree; - - // If "constant" is selected for high byte *and* bank byte, then there's no - // 2nd part available for low. - if (highConstantRadio.Checked && bankConstantRadio.Checked) { - lowSecondPartRadio.Enabled = false; - } - } else { - // For 16-bit address, if high byte is constant, then there's no second - // part for the low byte. - if (highConstantRadio.Checked) { - lowSecondPartRadio.Enabled = false; - } - } - - // Was a now-invalidated radio button selected before? - if (!lowThirdPartRadio.Enabled && lowThirdPartRadio.Checked) { - // low now invalid, switch to whatever high isn't using - if (highFirstPartRadio.Checked) { - lowSecondPartRadio.Checked = true; - } else { - lowFirstPartRadio.Checked = true; - } - } - if (!highThirdPartRadio.Enabled && highThirdPartRadio.Checked) { - // high now invalid, switch to whatever low isn't using - if (lowFirstPartRadio.Checked) { - highSecondPartRadio.Checked = true; - } else { - highFirstPartRadio.Checked = true; - } - } - if (!lowSecondPartRadio.Enabled && lowSecondPartRadio.Checked) { - // Should only happen when high part is constant. - Debug.Assert(highFirstPartRadio.Checked == false); - lowFirstPartRadio.Checked = true; - } - - mInitializing = false; - UpdatePreview(); - - okButton.Enabled = mOutputReady; - } - - private void widthRadio_CheckedChanged(object sender, EventArgs e) { - UpdateControls(); - } - - private void pushRtsCheckBox_CheckedChanged(object sender, EventArgs e) { - UpdateControls(); - } - - private void lowByte_CheckedChanged(object sender, EventArgs e) { - // If we conflict with the high byte, change the high byte. - if (lowFirstPartRadio.Checked && highFirstPartRadio.Checked) { - highSecondPartRadio.Checked = true; - } else if (lowSecondPartRadio.Checked && highSecondPartRadio.Checked) { - highFirstPartRadio.Checked = true; - } else if (lowThirdPartRadio.Checked && highThirdPartRadio.Checked) { - highFirstPartRadio.Checked = true; - } - UpdateControls(); - } - - private void highByte_CheckedChanged(object sender, EventArgs e) { - // If we conflict with the low byte, change the low byte. - if (lowFirstPartRadio.Checked && highFirstPartRadio.Checked) { - lowSecondPartRadio.Checked = true; - } else if (lowSecondPartRadio.Checked && highSecondPartRadio.Checked) { - lowFirstPartRadio.Checked = true; - } else if (lowThirdPartRadio.Checked && highThirdPartRadio.Checked) { - lowFirstPartRadio.Checked = true; - } - UpdateControls(); - } - - private void bankByte_CheckedChanged(object sender, EventArgs e) { - UpdateControls(); - } - - private void highConstantTextBox_TextChanged(object sender, EventArgs e) { - highConstantRadio.Checked = true; - UpdateControls(); - } - - private void bankConstantTextBox_TextChanged(object sender, EventArgs e) { - bankConstantRadio.Checked = true; - UpdateControls(); - } - - private void UpdatePreview() { - mOutputReady = false; - - int minDiv; - - if (width16Radio.Checked) { - if (highConstantRadio.Checked) { - minDiv = 1; - } else { - minDiv = 2; - } - } else { - if (highConstantRadio.Checked) { - if (bankConstantRadio.Checked) { - minDiv = 1; - } else { - minDiv = 2; - } - } else { - if (bankConstantRadio.Checked) { - minDiv = 2; - } else { - minDiv = 3; - } - } - } - - incompatibleSelectionLabel.Visible = invalidConstantLabel.Visible = false; - - try { - // Start by clearing the previous contents of the list. If something goes - // wrong, we want to show the error messages on an empty list. - outputPreviewListView.BeginUpdate(); - outputPreviewListView.Items.Clear(); - - if ((mSelection.Count % minDiv) != 0) { - incompatibleSelectionLabel.Visible = true; - return; - } - - int highConstant = -1; - if (highConstantRadio.Checked) { - if (!Number.TryParseInt(highConstantTextBox.Text, out highConstant, - out int unused) || (highConstant != (byte) highConstant)) { - invalidConstantLabel.Visible = true; - return; - } - } - - int bankConstant = -1; - if (bankConstantRadio.Enabled && bankConstantRadio.Checked) { - if (!Number.TryParseInt(bankConstantTextBox.Text, out bankConstant, - out int unused) || (bankConstant != (byte) bankConstant)) { - invalidConstantLabel.Visible = true; - return; - } - } - - // Looks valid, generate format list. - GenerateFormats(minDiv, highConstant, bankConstant); - } finally { - outputPreviewListView.EndUpdate(); - } - } - - private void GenerateFormats(int div, int highConst, int bankConst) { - SortedList newDfds = new SortedList(); - Dictionary newLabels = new Dictionary(); - List targetOffsets = new List(); - - // Identify the offset where each set of data starts. - int span = mSelection.Count / div; - int lowOff, highOff, bankOff; - - if (lowFirstPartRadio.Checked) { - lowOff = 0; - } else if (lowSecondPartRadio.Checked) { - lowOff = span; - } else if (lowThirdPartRadio.Checked) { - lowOff = span * 2; - } else { - Debug.Assert(false); - lowOff = -1; - } - if (highFirstPartRadio.Checked) { - highOff = 0; - } else if (highSecondPartRadio.Checked) { - highOff = span; - } else if (highThirdPartRadio.Checked) { - highOff = span * 2; - } else { - highOff = -1; // use constant - } - if (width24Radio.Checked) { - if (bankNthPartRadio.Checked) { - // Use whichever part isn't being used by the other two. - if (lowOff != 0 && highOff != 0) { - bankOff = 0; - } else if (lowOff != span && highOff != span) { - bankOff = span; - } else { - Debug.Assert(lowOff != span * 2 && highOff != span * 2); - bankOff = span * 2; - } - } else { - bankOff = -1; // use constant - } - } else { - bankOff = -1; // use constant - bankConst = 0; // always bank 0 - } - - Debug.WriteLine("Extract from low=" + lowOff + " high=" + highOff + - " bank=" + bankOff); - - // The TypedRangeSet doesn't have an index operation, so copy the values into - // an array. - int[] offsets = new int[mSelection.Count]; - int index = 0; - foreach (TypedRangeSet.Tuple tup in mSelection) { - offsets[index++] = tup.Value; - } - - int adj = 0; - if (pushRtsCheckBox.Checked) { - adj = 1; - } - - // Walk through the file data, generating addresses as we go. - byte[] fileData = mProject.FileData; - for (int i = 0; i < span; i++) { - byte low, high, bank; - - low = fileData[offsets[lowOff + i]]; - if (highOff >= 0) { - high = fileData[offsets[highOff + i]]; - } else { - high = (byte) highConst; - } - if (bankOff >= 0) { - bank = fileData[offsets[bankOff + i]]; - } else { - bank = (byte) bankConst; - } - - int addr = ((bank << 16) | (high << 8) | low) + adj; - - int targetOffset = mProject.AddrMap.AddressToOffset(offsets[0], addr); - if (targetOffset < 0) { - // Address not within file bounds. - // TODO(maybe): look for matching platform/project symbols - AddPreviewItem(addr, -1, Properties.Resources.INVALID_ADDRESS); - } else { - // Note the same target offset may appear more than once. - targetOffsets.Add(targetOffset); - - // If there's a user-defined label there already, use it. Otherwise, we'll - // need to generate one. - string targetLabel; - if (mProject.UserLabels.TryGetValue(targetOffset, out Symbol sym)) { - targetLabel = sym.Label; - AddPreviewItem(addr, targetOffset, targetLabel); - } else { - // Generate a symbol that's unique vs. the symbol table. We don't need - // it to be unique vs. the labels we're generating here, because we - // won't generate identical labels for different addresses, and we do - // want to generate a single label if more than one table entry refers - // to the same target. - Symbol tmpSym = AutoLabel.GenerateUniqueForAddress(addr, - mProject.SymbolTable, "T"); - // tmpSym was returned as an auto-label, make it a user label instead - tmpSym = new Symbol(tmpSym.Label, tmpSym.Value, Symbol.Source.User, - Symbol.Type.LocalOrGlobalAddr); - newLabels[targetOffset] = tmpSym; // overwrites previous - targetLabel = tmpSym.Label; - AddPreviewItem(addr, targetOffset, "(+) " + targetLabel); - } - - // Now we need to create format descriptors for the addresses where we - // extracted the low, high, and bank values. - newDfds.Add(offsets[lowOff + i], FormatDescriptor.Create(1, - new WeakSymbolRef(targetLabel, WeakSymbolRef.Part.Low), false)); - if (highOff >= 0) { - newDfds.Add(offsets[highOff + i], FormatDescriptor.Create(1, - new WeakSymbolRef(targetLabel, WeakSymbolRef.Part.High), false)); - } - if (bankOff >= 0) { - newDfds.Add(offsets[bankOff + i], FormatDescriptor.Create(1, - new WeakSymbolRef(targetLabel, WeakSymbolRef.Part.Bank), false)); - } - } - } - - NewFormatDescriptors = newDfds; - NewUserLabels = newLabels; - AllTargetOffsets = targetOffsets; - - // Don't show ready if all addresses are invalid. - mOutputReady = (AllTargetOffsets.Count > 0); - } - - private void AddPreviewItem(int addr, int offset, string label) { - ListViewItem lvi = new ListViewItem(mFormatter.FormatAddress(addr, - !mProject.CpuDef.HasAddr16)); - if (offset >= 0) { - lvi.SubItems.Add(new ListViewItem.ListViewSubItem(lvi, - mFormatter.FormatOffset24(offset))); - } else { - lvi.SubItems.Add(new ListViewItem.ListViewSubItem(lvi, "---")); - } - lvi.SubItems.Add(new ListViewItem.ListViewSubItem(lvi, label)); - outputPreviewListView.Items.Add(lvi); - } - } -} diff --git a/SourceGenWF/AppForms/FormatSplitAddress.resx b/SourceGenWF/AppForms/FormatSplitAddress.resx deleted file mode 100644 index 1af7de1..0000000 --- a/SourceGenWF/AppForms/FormatSplitAddress.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SourceGenWF/AppForms/GotoBox.Designer.cs b/SourceGenWF/AppForms/GotoBox.Designer.cs deleted file mode 100644 index b061e7c..0000000 --- a/SourceGenWF/AppForms/GotoBox.Designer.cs +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AppForms { - partial class GotoBox { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.instructionLabel = new System.Windows.Forms.Label(); - this.targetTextBox = new System.Windows.Forms.TextBox(); - this.okButton = new System.Windows.Forms.Button(); - this.offsetLabel = new System.Windows.Forms.Label(); - this.addressLabel = new System.Windows.Forms.Label(); - this.labelLabel = new System.Windows.Forms.Label(); - this.addressValueLabel = new System.Windows.Forms.Label(); - this.offsetValueLabel = new System.Windows.Forms.Label(); - this.labelValueLabel = new System.Windows.Forms.Label(); - this.SuspendLayout(); - // - // instructionLabel - // - this.instructionLabel.AutoSize = true; - this.instructionLabel.Location = new System.Drawing.Point(13, 13); - this.instructionLabel.Name = "instructionLabel"; - this.instructionLabel.Size = new System.Drawing.Size(215, 52); - this.instructionLabel.TabIndex = 0; - this.instructionLabel.Text = "Enter target location as one of:\r\n • Hex file offset (with \'+\', e.g. +500)\r\n • He" + - "x address (e.g. 1000, $1000, 00/1000)\r\n • Label (case-sensitive)\r\n"; - // - // targetTextBox - // - this.targetTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.targetTextBox.Location = new System.Drawing.Point(13, 78); - this.targetTextBox.Name = "targetTextBox"; - this.targetTextBox.Size = new System.Drawing.Size(215, 20); - this.targetTextBox.TabIndex = 1; - this.targetTextBox.TextChanged += new System.EventHandler(this.targetTextBox_TextChanged); - // - // okButton - // - this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.okButton.Location = new System.Drawing.Point(240, 76); - this.okButton.Name = "okButton"; - this.okButton.Size = new System.Drawing.Size(75, 23); - this.okButton.TabIndex = 2; - this.okButton.Text = "Go"; - this.okButton.UseVisualStyleBackColor = true; - this.okButton.Click += new System.EventHandler(this.okButton_Click); - // - // offsetLabel - // - this.offsetLabel.AutoSize = true; - this.offsetLabel.Location = new System.Drawing.Point(13, 111); - this.offsetLabel.Name = "offsetLabel"; - this.offsetLabel.Size = new System.Drawing.Size(38, 13); - this.offsetLabel.TabIndex = 3; - this.offsetLabel.Text = "Offset:"; - // - // addressLabel - // - this.addressLabel.AutoSize = true; - this.addressLabel.Location = new System.Drawing.Point(12, 129); - this.addressLabel.Name = "addressLabel"; - this.addressLabel.Size = new System.Drawing.Size(48, 13); - this.addressLabel.TabIndex = 4; - this.addressLabel.Text = "Address:"; - // - // labelLabel - // - this.labelLabel.AutoSize = true; - this.labelLabel.Location = new System.Drawing.Point(12, 147); - this.labelLabel.Name = "labelLabel"; - this.labelLabel.Size = new System.Drawing.Size(36, 13); - this.labelLabel.TabIndex = 5; - this.labelLabel.Text = "Label:"; - // - // addressValueLabel - // - this.addressValueLabel.AutoSize = true; - this.addressValueLabel.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.addressValueLabel.Location = new System.Drawing.Point(66, 129); - this.addressValueLabel.Name = "addressValueLabel"; - this.addressValueLabel.Size = new System.Drawing.Size(49, 13); - this.addressValueLabel.TabIndex = 6; - this.addressValueLabel.Text = "01/2345"; - // - // offsetValueLabel - // - this.offsetValueLabel.AutoSize = true; - this.offsetValueLabel.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.offsetValueLabel.Location = new System.Drawing.Point(66, 111); - this.offsetValueLabel.Name = "offsetValueLabel"; - this.offsetValueLabel.Size = new System.Drawing.Size(37, 13); - this.offsetValueLabel.TabIndex = 7; - this.offsetValueLabel.Text = "+1234"; - // - // labelValueLabel - // - this.labelValueLabel.AutoSize = true; - this.labelValueLabel.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.labelValueLabel.Location = new System.Drawing.Point(66, 147); - this.labelValueLabel.Name = "labelValueLabel"; - this.labelValueLabel.Size = new System.Drawing.Size(37, 13); - this.labelValueLabel.TabIndex = 8; - this.labelValueLabel.Text = "FUBAR"; - // - // GotoBox - // - this.AcceptButton = this.okButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(327, 171); - this.Controls.Add(this.labelValueLabel); - this.Controls.Add(this.offsetValueLabel); - this.Controls.Add(this.addressValueLabel); - this.Controls.Add(this.labelLabel); - this.Controls.Add(this.addressLabel); - this.Controls.Add(this.offsetLabel); - this.Controls.Add(this.okButton); - this.Controls.Add(this.targetTextBox); - this.Controls.Add(this.instructionLabel); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "GotoBox"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Go To Line"; - this.Load += new System.EventHandler(this.GotoBox_Load); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label instructionLabel; - private System.Windows.Forms.TextBox targetTextBox; - private System.Windows.Forms.Button okButton; - private System.Windows.Forms.Label offsetLabel; - private System.Windows.Forms.Label addressLabel; - private System.Windows.Forms.Label labelLabel; - private System.Windows.Forms.Label addressValueLabel; - private System.Windows.Forms.Label offsetValueLabel; - private System.Windows.Forms.Label labelValueLabel; - } -} \ No newline at end of file diff --git a/SourceGenWF/AppForms/GotoBox.cs b/SourceGenWF/AppForms/GotoBox.cs deleted file mode 100644 index f1ecf32..0000000 --- a/SourceGenWF/AppForms/GotoBox.cs +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Windows.Forms; - -using Asm65; - -namespace SourceGenWF.AppForms { - public partial class GotoBox : Form { - /// - /// On success, this will hold the target offset. - /// - public int TargetOffset { get; private set; } - - /// - /// Reference to project. - /// - private DisasmProject mProject; - - /// - /// Reference to formatter. This determines how values are displayed. - /// - private Formatter mFormatter; - - - public GotoBox(DisasmProject proj, Formatter formatter) { - InitializeComponent(); - - mProject = proj; - mFormatter = formatter; - TargetOffset = -1; - } - - private void GotoBox_Load(object sender, EventArgs e) { - UpdateDisplay(); - } - - // Without a "cancel" button, the escape key does nothing. - protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { - if (keyData == Keys.Escape) { - Close(); - return true; - } - return base.ProcessCmdKey(ref msg, keyData); - } - - private void okButton_Click(object sender, EventArgs e) { - } - - private void targetTextBox_TextChanged(object sender, EventArgs e) { - ProcessInput(); - UpdateDisplay(); - okButton.Enabled = (TargetOffset >= 0); - } - - private void ProcessInput() { - TargetOffset = -1; - - string input = targetTextBox.Text.Trim(); - if (string.IsNullOrEmpty(input)) { - return; - } - if (input[0] == '+') { - // this can only be an offset; convert as hexadecimal number - try { - TargetOffset = Convert.ToInt32(input.Substring(1), 16); - } catch (Exception) { - } - return; - } - - // Try it as a label. If they give the label a hex name (e.g. "A001") they - // can prefix it with '$' to disambiguate the address. - int labelOffset = mProject.FindLabelOffsetByName(input); - if (labelOffset >= 0) { - TargetOffset = labelOffset; - } else if (Address.ParseAddress(input, 1<<24, out int addr)) { - // could be a valid address - int offset = mProject.AddrMap.AddressToOffset(0, addr); - if (offset >= 0) { - TargetOffset = offset; - } - } - } - - private void UpdateDisplay() { - string offsetStr = string.Empty; - string addressStr = string.Empty; - string labelStr = string.Empty; - - if (TargetOffset >= 0) { - offsetStr = mFormatter.FormatOffset24(TargetOffset); - int addr = mProject.GetAnattrib(TargetOffset).Address; - addressStr = mFormatter.FormatAddress(addr, addr > 0xffff); - Symbol sym = mProject.GetAnattrib(TargetOffset).Symbol; - if (sym != null) { - labelStr = sym.Label; - } - } - - offsetValueLabel.Text = offsetStr; - addressValueLabel.Text = addressStr; - labelValueLabel.Text = labelStr; - } - } -} diff --git a/SourceGenWF/AppForms/GotoBox.resx b/SourceGenWF/AppForms/GotoBox.resx deleted file mode 100644 index 1af7de1..0000000 --- a/SourceGenWF/AppForms/GotoBox.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SourceGenWF/AppForms/ProjectLoadIssues.Designer.cs b/SourceGenWF/AppForms/ProjectLoadIssues.Designer.cs deleted file mode 100644 index 3030df2..0000000 --- a/SourceGenWF/AppForms/ProjectLoadIssues.Designer.cs +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AppForms { - partial class ProjectLoadIssues { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.cancelButton = new System.Windows.Forms.Button(); - this.okButton = new System.Windows.Forms.Button(); - this.labelSomeIssues = new System.Windows.Forms.Label(); - this.messageTextBox = new System.Windows.Forms.TextBox(); - this.invalidDiscardLabel = new System.Windows.Forms.Label(); - this.SuspendLayout(); - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.Location = new System.Drawing.Point(469, 184); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 23); - this.cancelButton.TabIndex = 1; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - // - // okButton - // - this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.okButton.Location = new System.Drawing.Point(388, 184); - this.okButton.Name = "okButton"; - this.okButton.Size = new System.Drawing.Size(75, 23); - this.okButton.TabIndex = 0; - this.okButton.Text = "Continue"; - this.okButton.UseVisualStyleBackColor = true; - // - // labelSomeIssues - // - this.labelSomeIssues.AutoSize = true; - this.labelSomeIssues.Location = new System.Drawing.Point(13, 13); - this.labelSomeIssues.Name = "labelSomeIssues"; - this.labelSomeIssues.Size = new System.Drawing.Size(257, 13); - this.labelSomeIssues.TabIndex = 2; - this.labelSomeIssues.Text = "Problems were detected while loading the project file:"; - // - // messageTextBox - // - this.messageTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.messageTextBox.BackColor = System.Drawing.SystemColors.Window; - this.messageTextBox.Location = new System.Drawing.Point(12, 37); - this.messageTextBox.Multiline = true; - this.messageTextBox.Name = "messageTextBox"; - this.messageTextBox.ReadOnly = true; - this.messageTextBox.Size = new System.Drawing.Size(533, 113); - this.messageTextBox.TabIndex = 3; - // - // invalidDiscardLabel - // - this.invalidDiscardLabel.AutoSize = true; - this.invalidDiscardLabel.ForeColor = System.Drawing.Color.Red; - this.invalidDiscardLabel.Location = new System.Drawing.Point(13, 158); - this.invalidDiscardLabel.Name = "invalidDiscardLabel"; - this.invalidDiscardLabel.Size = new System.Drawing.Size(301, 13); - this.invalidDiscardLabel.TabIndex = 4; - this.invalidDiscardLabel.Text = "Invalid data items will be discarded when you save the project."; - // - // ProjectLoadIssues - // - this.AcceptButton = this.okButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(556, 219); - this.Controls.Add(this.invalidDiscardLabel); - this.Controls.Add(this.messageTextBox); - this.Controls.Add(this.labelSomeIssues); - this.Controls.Add(this.okButton); - this.Controls.Add(this.cancelButton); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "ProjectLoadIssues"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Project Load Issues"; - this.Load += new System.EventHandler(this.ProjectLoadIssues_Load); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Button cancelButton; - private System.Windows.Forms.Button okButton; - private System.Windows.Forms.Label labelSomeIssues; - private System.Windows.Forms.TextBox messageTextBox; - private System.Windows.Forms.Label invalidDiscardLabel; - } -} \ No newline at end of file diff --git a/SourceGenWF/AppForms/ProjectLoadIssues.cs b/SourceGenWF/AppForms/ProjectLoadIssues.cs deleted file mode 100644 index c4bd5b0..0000000 --- a/SourceGenWF/AppForms/ProjectLoadIssues.cs +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Windows.Forms; - -namespace SourceGenWF.AppForms { - /// - /// Display errors and warnings generated while attempting to open a project. - /// - public partial class ProjectLoadIssues : Form { - /// - /// Multi-line message for text box. - /// - private string mMessages; - - /// - /// Which buttons are enabled. - /// - private Buttons mAllowedButtons; - public enum Buttons { - Unknown = 0, Continue, Cancel, ContinueOrCancel - } - - - public ProjectLoadIssues(string msgs, Buttons allowedButtons) { - InitializeComponent(); - - mMessages = msgs; - mAllowedButtons = allowedButtons; - } - - private void ProjectLoadIssues_Load(object sender, EventArgs e) { - messageTextBox.Text = mMessages; - - if (mAllowedButtons == Buttons.Cancel) { - // Continue not allowed - okButton.Enabled = false; - - // No point warning them about invalid data if they can't continue. - invalidDiscardLabel.Visible = false; - } - if (mAllowedButtons == Buttons.Continue) { - // Cancel not allowed. - cancelButton.Enabled = false; - - // They're stuck with the problem. - invalidDiscardLabel.Visible = false; - } - } - } -} diff --git a/SourceGenWF/AppForms/ProjectLoadIssues.resx b/SourceGenWF/AppForms/ProjectLoadIssues.resx deleted file mode 100644 index 1af7de1..0000000 --- a/SourceGenWF/AppForms/ProjectLoadIssues.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SourceGenWF/AppForms/ProjectView.Designer.cs b/SourceGenWF/AppForms/ProjectView.Designer.cs deleted file mode 100644 index c1f7181..0000000 --- a/SourceGenWF/AppForms/ProjectView.Designer.cs +++ /dev/null @@ -1,1652 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AppForms -{ - partial class ProjectView - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProjectView)); - this.mainMenuStrip = new System.Windows.Forms.MenuStrip(); - this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.newToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.saveAsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripSeparator(); - this.assembleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.printToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator(); - this.recentProjectsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.noRecentsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripMenuItem10 = new System.Windows.Forms.ToolStripSeparator(); - this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.undoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.redoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); - this.copyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator(); - this.selectAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.findToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.findNextToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.gotoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator(); - this.editHeaderCommentToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.projectPropertiesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toggleDataScanToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripMenuItem7 = new System.Windows.Forms.ToolStripSeparator(); - this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.actionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.setAddressToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.overrideStatusFlagsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.editLabelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.editOperandToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.editCommentToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.editLongCommentToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.editNoteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.editProjectSymbolToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.actionsMenuSeparator1 = new System.Windows.Forms.ToolStripSeparator(); - this.hintAsCodeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.hintAsDataToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.hintAsInlineDataToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.removeHintToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripMenuItem11 = new System.Windows.Forms.ToolStripSeparator(); - this.formatSplitAddressTableToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toggleSingleBytesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.formatAsWordToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.deleteNoteCommentToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripMenuItem9 = new System.Windows.Forms.ToolStripSeparator(); - this.showHexDumpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.hexDumpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.aSCIIChartToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.contentsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.dEBUGToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.reanalyzeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.showUndoRedoHistoryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.showAnalyzerOutputToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.showAnalysisTimersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.extensionScriptInfoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripMenuItem6 = new System.Windows.Forms.ToolStripSeparator(); - this.toggleOwnerDrawToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toggleCommentRulersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.useKeepAliveHackToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripMenuItem8 = new System.Windows.Forms.ToolStripSeparator(); - this.sourceGenTestsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.mainStatusStrip = new System.Windows.Forms.StatusStrip(); - this.toolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel(); - this.mainToolStrip = new System.Windows.Forms.ToolStrip(); - this.navigateBackToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.navigateFwdToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); - this.newToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.openToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.saveToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.printToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.toolStripSeparator = new System.Windows.Forms.ToolStripSeparator(); - this.cutToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.copyToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.pasteToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); - this.helpToolStripButton = new System.Windows.Forms.ToolStripButton(); - this.mainSplitterLeft = new System.Windows.Forms.SplitContainer(); - this.leftPanelSplitter = new System.Windows.Forms.SplitContainer(); - this.referencesGroupBox = new System.Windows.Forms.GroupBox(); - this.referencesListView = new System.Windows.Forms.ListView(); - this.offsetColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.addressColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.typeColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.notesGroupBox = new System.Windows.Forms.GroupBox(); - this.notesListView = new System.Windows.Forms.ListView(); - this.notesOffsetColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.notesNoteColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.mainSplitterRight = new System.Windows.Forms.SplitContainer(); - this.noProjectPanel = new System.Windows.Forms.Panel(); - this.debugModeEnabledLabel = new System.Windows.Forms.Label(); - this.recentProjectsLabel = new System.Windows.Forms.Label(); - this.recentProjectLabel2 = new System.Windows.Forms.LinkLabel(); - this.versionLabel = new System.Windows.Forms.Label(); - this.sourceGenLabel = new System.Windows.Forms.Label(); - this.logoPictureBox = new System.Windows.Forms.PictureBox(); - this.recentProjectLabel1 = new System.Windows.Forms.LinkLabel(); - this.openExistingLabel = new System.Windows.Forms.LinkLabel(); - this.newProjectLink = new System.Windows.Forms.LinkLabel(); - this.codeListView = new System.Windows.Forms.ListView(); - this.columnOffset = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.columnAddr = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.columnBytes = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.columnFlags = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.columnAttr = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.columnLabel = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.columnOpcode = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.columnOperand = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.columnComment = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.rightPanelSplitter = new System.Windows.Forms.SplitContainer(); - this.symbolsGroupBox = new System.Windows.Forms.GroupBox(); - this.symbolUserCheckBox = new System.Windows.Forms.CheckBox(); - this.symbolProjectCheckBox = new System.Windows.Forms.CheckBox(); - this.symbolAddressCheckBox = new System.Windows.Forms.CheckBox(); - this.symbolConstantCheckBox = new System.Windows.Forms.CheckBox(); - this.symbolAutoCheckBox = new System.Windows.Forms.CheckBox(); - this.symbolPlatformCheckBox = new System.Windows.Forms.CheckBox(); - this.symbolListView = new System.Windows.Forms.ListView(); - this.symbolTypeColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.symbolValueColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.symbolNameColumnHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.infoGroupBox = new System.Windows.Forms.GroupBox(); - this.infoTextBox = new System.Windows.Forms.TextBox(); - this.mainMenuStrip.SuspendLayout(); - this.mainStatusStrip.SuspendLayout(); - this.mainToolStrip.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.mainSplitterLeft)).BeginInit(); - this.mainSplitterLeft.Panel1.SuspendLayout(); - this.mainSplitterLeft.Panel2.SuspendLayout(); - this.mainSplitterLeft.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.leftPanelSplitter)).BeginInit(); - this.leftPanelSplitter.Panel1.SuspendLayout(); - this.leftPanelSplitter.Panel2.SuspendLayout(); - this.leftPanelSplitter.SuspendLayout(); - this.referencesGroupBox.SuspendLayout(); - this.notesGroupBox.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.mainSplitterRight)).BeginInit(); - this.mainSplitterRight.Panel1.SuspendLayout(); - this.mainSplitterRight.Panel2.SuspendLayout(); - this.mainSplitterRight.SuspendLayout(); - this.noProjectPanel.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.rightPanelSplitter)).BeginInit(); - this.rightPanelSplitter.Panel1.SuspendLayout(); - this.rightPanelSplitter.Panel2.SuspendLayout(); - this.rightPanelSplitter.SuspendLayout(); - this.symbolsGroupBox.SuspendLayout(); - this.infoGroupBox.SuspendLayout(); - this.SuspendLayout(); - // - // mainMenuStrip - // - this.mainMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.fileToolStripMenuItem, - this.editToolStripMenuItem, - this.actionsToolStripMenuItem, - this.toolsToolStripMenuItem, - this.helpToolStripMenuItem, - this.dEBUGToolStripMenuItem}); - this.mainMenuStrip.Location = new System.Drawing.Point(0, 0); - this.mainMenuStrip.Name = "mainMenuStrip"; - this.mainMenuStrip.Size = new System.Drawing.Size(805, 24); - this.mainMenuStrip.TabIndex = 0; - this.mainMenuStrip.Text = "Main MenuStrip"; - // - // fileToolStripMenuItem - // - this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.newToolStripMenuItem, - this.openToolStripMenuItem, - this.saveToolStripMenuItem, - this.saveAsToolStripMenuItem, - this.closeToolStripMenuItem, - this.toolStripMenuItem4, - this.assembleToolStripMenuItem, - this.printToolStripMenuItem, - this.toolStripMenuItem5, - this.recentProjectsToolStripMenuItem, - this.toolStripMenuItem10, - this.exitToolStripMenuItem}); - this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; - this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); - this.fileToolStripMenuItem.Text = "File"; - // - // newToolStripMenuItem - // - this.newToolStripMenuItem.Name = "newToolStripMenuItem"; - this.newToolStripMenuItem.Size = new System.Drawing.Size(208, 22); - this.newToolStripMenuItem.Text = "New"; - this.newToolStripMenuItem.Click += new System.EventHandler(this.newToolStripMenuItem_Click); - // - // openToolStripMenuItem - // - this.openToolStripMenuItem.Name = "openToolStripMenuItem"; - this.openToolStripMenuItem.Size = new System.Drawing.Size(208, 22); - this.openToolStripMenuItem.Text = "Open"; - this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click); - // - // saveToolStripMenuItem - // - this.saveToolStripMenuItem.Name = "saveToolStripMenuItem"; - this.saveToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S))); - this.saveToolStripMenuItem.Size = new System.Drawing.Size(208, 22); - this.saveToolStripMenuItem.Text = "Save"; - this.saveToolStripMenuItem.Click += new System.EventHandler(this.saveToolStripMenuItem_Click); - // - // saveAsToolStripMenuItem - // - this.saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem"; - this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(208, 22); - this.saveAsToolStripMenuItem.Text = "Save As..."; - this.saveAsToolStripMenuItem.Click += new System.EventHandler(this.saveAsToolStripMenuItem_Click); - // - // closeToolStripMenuItem - // - this.closeToolStripMenuItem.Name = "closeToolStripMenuItem"; - this.closeToolStripMenuItem.Size = new System.Drawing.Size(208, 22); - this.closeToolStripMenuItem.Text = "Close"; - this.closeToolStripMenuItem.Click += new System.EventHandler(this.closeToolStripMenuItem_Click); - // - // toolStripMenuItem4 - // - this.toolStripMenuItem4.Name = "toolStripMenuItem4"; - this.toolStripMenuItem4.Size = new System.Drawing.Size(205, 6); - // - // assembleToolStripMenuItem - // - this.assembleToolStripMenuItem.Name = "assembleToolStripMenuItem"; - this.assembleToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) - | System.Windows.Forms.Keys.A))); - this.assembleToolStripMenuItem.Size = new System.Drawing.Size(208, 22); - this.assembleToolStripMenuItem.Text = "Assemble..."; - this.assembleToolStripMenuItem.Click += new System.EventHandler(this.assembleToolStripMenuItem_Click); - // - // printToolStripMenuItem - // - this.printToolStripMenuItem.Name = "printToolStripMenuItem"; - this.printToolStripMenuItem.Size = new System.Drawing.Size(208, 22); - this.printToolStripMenuItem.Text = "Print..."; - this.printToolStripMenuItem.Visible = false; - // - // toolStripMenuItem5 - // - this.toolStripMenuItem5.Name = "toolStripMenuItem5"; - this.toolStripMenuItem5.Size = new System.Drawing.Size(205, 6); - // - // recentProjectsToolStripMenuItem - // - this.recentProjectsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.noRecentsToolStripMenuItem}); - this.recentProjectsToolStripMenuItem.Name = "recentProjectsToolStripMenuItem"; - this.recentProjectsToolStripMenuItem.Size = new System.Drawing.Size(208, 22); - this.recentProjectsToolStripMenuItem.Text = "Recent Projects"; - this.recentProjectsToolStripMenuItem.DropDownOpening += new System.EventHandler(this.recentProjectsToolStripMenuItem_DropDownOpening); - // - // noRecentsToolStripMenuItem - // - this.noRecentsToolStripMenuItem.Enabled = false; - this.noRecentsToolStripMenuItem.Name = "noRecentsToolStripMenuItem"; - this.noRecentsToolStripMenuItem.Size = new System.Drawing.Size(109, 22); - this.noRecentsToolStripMenuItem.Text = "(none)"; - // - // toolStripMenuItem10 - // - this.toolStripMenuItem10.Name = "toolStripMenuItem10"; - this.toolStripMenuItem10.Size = new System.Drawing.Size(205, 6); - // - // exitToolStripMenuItem - // - this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; - this.exitToolStripMenuItem.Size = new System.Drawing.Size(208, 22); - this.exitToolStripMenuItem.Text = "Exit"; - this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); - // - // editToolStripMenuItem - // - this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.undoToolStripMenuItem, - this.redoToolStripMenuItem, - this.toolStripMenuItem1, - this.copyToolStripMenuItem, - this.toolStripMenuItem2, - this.selectAllToolStripMenuItem, - this.findToolStripMenuItem, - this.findNextToolStripMenuItem, - this.gotoToolStripMenuItem, - this.toolStripMenuItem3, - this.editHeaderCommentToolStripMenuItem, - this.projectPropertiesToolStripMenuItem, - this.toggleDataScanToolStripMenuItem, - this.toolStripMenuItem7, - this.settingsToolStripMenuItem}); - this.editToolStripMenuItem.Name = "editToolStripMenuItem"; - this.editToolStripMenuItem.Size = new System.Drawing.Size(39, 20); - this.editToolStripMenuItem.Text = "Edit"; - this.editToolStripMenuItem.DropDownOpening += new System.EventHandler(this.editToolStripMenuItem_DropDownOpening); - // - // undoToolStripMenuItem - // - this.undoToolStripMenuItem.Name = "undoToolStripMenuItem"; - this.undoToolStripMenuItem.ShortcutKeyDisplayString = ""; - this.undoToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Z))); - this.undoToolStripMenuItem.Size = new System.Drawing.Size(207, 22); - this.undoToolStripMenuItem.Text = "Undo"; - this.undoToolStripMenuItem.Click += new System.EventHandler(this.undoToolStripMenuItem_Click); - // - // redoToolStripMenuItem - // - this.redoToolStripMenuItem.Name = "redoToolStripMenuItem"; - this.redoToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Y))); - this.redoToolStripMenuItem.Size = new System.Drawing.Size(207, 22); - this.redoToolStripMenuItem.Text = "Redo"; - this.redoToolStripMenuItem.Click += new System.EventHandler(this.redoToolStripMenuItem_Click); - // - // toolStripMenuItem1 - // - this.toolStripMenuItem1.Name = "toolStripMenuItem1"; - this.toolStripMenuItem1.Size = new System.Drawing.Size(204, 6); - // - // copyToolStripMenuItem - // - this.copyToolStripMenuItem.Name = "copyToolStripMenuItem"; - this.copyToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C))); - this.copyToolStripMenuItem.Size = new System.Drawing.Size(207, 22); - this.copyToolStripMenuItem.Text = "Copy"; - this.copyToolStripMenuItem.Click += new System.EventHandler(this.copyToolStripMenuItem_Click); - // - // toolStripMenuItem2 - // - this.toolStripMenuItem2.Name = "toolStripMenuItem2"; - this.toolStripMenuItem2.Size = new System.Drawing.Size(204, 6); - // - // selectAllToolStripMenuItem - // - this.selectAllToolStripMenuItem.Name = "selectAllToolStripMenuItem"; - this.selectAllToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A))); - this.selectAllToolStripMenuItem.Size = new System.Drawing.Size(207, 22); - this.selectAllToolStripMenuItem.Text = "Select All"; - this.selectAllToolStripMenuItem.Click += new System.EventHandler(this.selectAllToolStripMenuItem_Click); - // - // findToolStripMenuItem - // - this.findToolStripMenuItem.Name = "findToolStripMenuItem"; - this.findToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F))); - this.findToolStripMenuItem.Size = new System.Drawing.Size(207, 22); - this.findToolStripMenuItem.Text = "Find..."; - this.findToolStripMenuItem.Click += new System.EventHandler(this.findToolStripMenuItem_Click); - // - // findNextToolStripMenuItem - // - this.findNextToolStripMenuItem.Name = "findNextToolStripMenuItem"; - this.findNextToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F3; - this.findNextToolStripMenuItem.Size = new System.Drawing.Size(207, 22); - this.findNextToolStripMenuItem.Text = "Find Next"; - this.findNextToolStripMenuItem.Click += new System.EventHandler(this.findNextToolStripMenuItem_Click); - // - // gotoToolStripMenuItem - // - this.gotoToolStripMenuItem.Name = "gotoToolStripMenuItem"; - this.gotoToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.G))); - this.gotoToolStripMenuItem.Size = new System.Drawing.Size(207, 22); - this.gotoToolStripMenuItem.Text = "Go To..."; - this.gotoToolStripMenuItem.Click += new System.EventHandler(this.gotoToolStripMenuItem_Click); - // - // toolStripMenuItem3 - // - this.toolStripMenuItem3.Name = "toolStripMenuItem3"; - this.toolStripMenuItem3.Size = new System.Drawing.Size(204, 6); - // - // editHeaderCommentToolStripMenuItem - // - this.editHeaderCommentToolStripMenuItem.Name = "editHeaderCommentToolStripMenuItem"; - this.editHeaderCommentToolStripMenuItem.Size = new System.Drawing.Size(207, 22); - this.editHeaderCommentToolStripMenuItem.Text = "Edit Header Comment..."; - this.editHeaderCommentToolStripMenuItem.Click += new System.EventHandler(this.editHeaderCommentToolStripMenuItem_Click); - // - // projectPropertiesToolStripMenuItem - // - this.projectPropertiesToolStripMenuItem.Name = "projectPropertiesToolStripMenuItem"; - this.projectPropertiesToolStripMenuItem.Size = new System.Drawing.Size(207, 22); - this.projectPropertiesToolStripMenuItem.Text = "Project Properties..."; - this.projectPropertiesToolStripMenuItem.Click += new System.EventHandler(this.projectPropertiesToolStripMenuItem_Click); - // - // toggleDataScanToolStripMenuItem - // - this.toggleDataScanToolStripMenuItem.Name = "toggleDataScanToolStripMenuItem"; - this.toggleDataScanToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.D))); - this.toggleDataScanToolStripMenuItem.Size = new System.Drawing.Size(207, 22); - this.toggleDataScanToolStripMenuItem.Text = "Toggle Data Scan"; - this.toggleDataScanToolStripMenuItem.Click += new System.EventHandler(this.toggleDataScanToolStripMenuItem_Click); - // - // toolStripMenuItem7 - // - this.toolStripMenuItem7.Name = "toolStripMenuItem7"; - this.toolStripMenuItem7.Size = new System.Drawing.Size(204, 6); - // - // settingsToolStripMenuItem - // - this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem"; - this.settingsToolStripMenuItem.Size = new System.Drawing.Size(207, 22); - this.settingsToolStripMenuItem.Text = "Settings..."; - this.settingsToolStripMenuItem.Click += new System.EventHandler(this.settingsToolStripMenuItem_Click); - // - // actionsToolStripMenuItem - // - this.actionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.setAddressToolStripMenuItem, - this.overrideStatusFlagsToolStripMenuItem, - this.editLabelToolStripMenuItem, - this.editOperandToolStripMenuItem, - this.editCommentToolStripMenuItem, - this.editLongCommentToolStripMenuItem, - this.editNoteToolStripMenuItem, - this.editProjectSymbolToolStripMenuItem, - this.actionsMenuSeparator1, - this.hintAsCodeToolStripMenuItem, - this.hintAsDataToolStripMenuItem, - this.hintAsInlineDataToolStripMenuItem, - this.removeHintToolStripMenuItem, - this.toolStripMenuItem11, - this.formatSplitAddressTableToolStripMenuItem, - this.toggleSingleBytesToolStripMenuItem, - this.formatAsWordToolStripMenuItem, - this.deleteNoteCommentToolStripMenuItem, - this.toolStripMenuItem9, - this.showHexDumpToolStripMenuItem}); - this.actionsToolStripMenuItem.Name = "actionsToolStripMenuItem"; - this.actionsToolStripMenuItem.Size = new System.Drawing.Size(59, 20); - this.actionsToolStripMenuItem.Text = "Actions"; - this.actionsToolStripMenuItem.DropDownOpening += new System.EventHandler(this.ActionsMenuOpening); - // - // setAddressToolStripMenuItem - // - this.setAddressToolStripMenuItem.Name = "setAddressToolStripMenuItem"; - this.setAddressToolStripMenuItem.Size = new System.Drawing.Size(289, 22); - this.setAddressToolStripMenuItem.Text = "Set Address..."; - this.setAddressToolStripMenuItem.Click += new System.EventHandler(this.EditAddress_Click); - // - // overrideStatusFlagsToolStripMenuItem - // - this.overrideStatusFlagsToolStripMenuItem.Name = "overrideStatusFlagsToolStripMenuItem"; - this.overrideStatusFlagsToolStripMenuItem.Size = new System.Drawing.Size(289, 22); - this.overrideStatusFlagsToolStripMenuItem.Text = "Override Status Flags..."; - this.overrideStatusFlagsToolStripMenuItem.Click += new System.EventHandler(this.EditStatusFlags_Click); - // - // editLabelToolStripMenuItem - // - this.editLabelToolStripMenuItem.Name = "editLabelToolStripMenuItem"; - this.editLabelToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.L))); - this.editLabelToolStripMenuItem.Size = new System.Drawing.Size(289, 22); - this.editLabelToolStripMenuItem.Text = "Edit Label..."; - this.editLabelToolStripMenuItem.Click += new System.EventHandler(this.EditLabel_Click); - // - // editOperandToolStripMenuItem - // - this.editOperandToolStripMenuItem.Name = "editOperandToolStripMenuItem"; - this.editOperandToolStripMenuItem.ShortcutKeyDisplayString = ""; - this.editOperandToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O))); - this.editOperandToolStripMenuItem.Size = new System.Drawing.Size(289, 22); - this.editOperandToolStripMenuItem.Text = "Edit Operand..."; - this.editOperandToolStripMenuItem.Click += new System.EventHandler(this.EditInstrDataOperand_Click); - // - // editCommentToolStripMenuItem - // - this.editCommentToolStripMenuItem.Name = "editCommentToolStripMenuItem"; - this.editCommentToolStripMenuItem.ShortcutKeyDisplayString = "Ctrl+;"; - this.editCommentToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Oem1))); - this.editCommentToolStripMenuItem.Size = new System.Drawing.Size(289, 22); - this.editCommentToolStripMenuItem.Text = "Edit Comment..."; - this.editCommentToolStripMenuItem.Click += new System.EventHandler(this.EditComment_Click); - // - // editLongCommentToolStripMenuItem - // - this.editLongCommentToolStripMenuItem.Name = "editLongCommentToolStripMenuItem"; - this.editLongCommentToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.M))); - this.editLongCommentToolStripMenuItem.Size = new System.Drawing.Size(289, 22); - this.editLongCommentToolStripMenuItem.Text = "Edit Long Comment..."; - this.editLongCommentToolStripMenuItem.Click += new System.EventHandler(this.EditLongComment_Click); - // - // editNoteToolStripMenuItem - // - this.editNoteToolStripMenuItem.Name = "editNoteToolStripMenuItem"; - this.editNoteToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N))); - this.editNoteToolStripMenuItem.Size = new System.Drawing.Size(289, 22); - this.editNoteToolStripMenuItem.Text = "Edit Note..."; - this.editNoteToolStripMenuItem.Click += new System.EventHandler(this.EditNote_Click); - // - // editProjectSymbolToolStripMenuItem - // - this.editProjectSymbolToolStripMenuItem.Name = "editProjectSymbolToolStripMenuItem"; - this.editProjectSymbolToolStripMenuItem.Size = new System.Drawing.Size(289, 22); - this.editProjectSymbolToolStripMenuItem.Text = "Edit Project Symbol..."; - this.editProjectSymbolToolStripMenuItem.Click += new System.EventHandler(this.EditProjectSymbol_Click); - // - // actionsMenuSeparator1 - // - this.actionsMenuSeparator1.Name = "actionsMenuSeparator1"; - this.actionsMenuSeparator1.Size = new System.Drawing.Size(286, 6); - // - // hintAsCodeToolStripMenuItem - // - this.hintAsCodeToolStripMenuItem.Name = "hintAsCodeToolStripMenuItem"; - this.hintAsCodeToolStripMenuItem.ShortcutKeyDisplayString = "Ctrl+H, Ctrl+C"; - this.hintAsCodeToolStripMenuItem.Size = new System.Drawing.Size(289, 22); - this.hintAsCodeToolStripMenuItem.Text = "Hint As Code Entry Point"; - this.hintAsCodeToolStripMenuItem.Click += new System.EventHandler(this.MarkAsCode_Click); - // - // hintAsDataToolStripMenuItem - // - this.hintAsDataToolStripMenuItem.Name = "hintAsDataToolStripMenuItem"; - this.hintAsDataToolStripMenuItem.ShortcutKeyDisplayString = "Ctrl+H, Ctrl+D"; - this.hintAsDataToolStripMenuItem.Size = new System.Drawing.Size(289, 22); - this.hintAsDataToolStripMenuItem.Text = "Hint As Data Start"; - this.hintAsDataToolStripMenuItem.Click += new System.EventHandler(this.MarkAsData_Click); - // - // hintAsInlineDataToolStripMenuItem - // - this.hintAsInlineDataToolStripMenuItem.Name = "hintAsInlineDataToolStripMenuItem"; - this.hintAsInlineDataToolStripMenuItem.ShortcutKeyDisplayString = "Ctrl+H, Ctrl+I"; - this.hintAsInlineDataToolStripMenuItem.Size = new System.Drawing.Size(289, 22); - this.hintAsInlineDataToolStripMenuItem.Text = "Hint As Inline Data"; - this.hintAsInlineDataToolStripMenuItem.Click += new System.EventHandler(this.MarkAsInlineData_Click); - // - // removeHintToolStripMenuItem - // - this.removeHintToolStripMenuItem.Name = "removeHintToolStripMenuItem"; - this.removeHintToolStripMenuItem.ShortcutKeyDisplayString = "Ctrl+H, Ctrl+R"; - this.removeHintToolStripMenuItem.Size = new System.Drawing.Size(289, 22); - this.removeHintToolStripMenuItem.Text = "Remove Hints"; - this.removeHintToolStripMenuItem.Click += new System.EventHandler(this.MarkAsNoHint_Click); - // - // toolStripMenuItem11 - // - this.toolStripMenuItem11.Name = "toolStripMenuItem11"; - this.toolStripMenuItem11.Size = new System.Drawing.Size(286, 6); - // - // formatSplitAddressTableToolStripMenuItem - // - this.formatSplitAddressTableToolStripMenuItem.Name = "formatSplitAddressTableToolStripMenuItem"; - this.formatSplitAddressTableToolStripMenuItem.Size = new System.Drawing.Size(289, 22); - this.formatSplitAddressTableToolStripMenuItem.Text = "Format Split-Address Table..."; - this.formatSplitAddressTableToolStripMenuItem.Click += new System.EventHandler(this.FormatSplitAddressTable_Click); - // - // toggleSingleBytesToolStripMenuItem - // - this.toggleSingleBytesToolStripMenuItem.Name = "toggleSingleBytesToolStripMenuItem"; - this.toggleSingleBytesToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.B))); - this.toggleSingleBytesToolStripMenuItem.Size = new System.Drawing.Size(289, 22); - this.toggleSingleBytesToolStripMenuItem.Text = "Toggle Single-Byte Format"; - this.toggleSingleBytesToolStripMenuItem.Click += new System.EventHandler(this.ToggleSingleBytes_Click); - // - // formatAsWordToolStripMenuItem - // - this.formatAsWordToolStripMenuItem.Name = "formatAsWordToolStripMenuItem"; - this.formatAsWordToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.W))); - this.formatAsWordToolStripMenuItem.Size = new System.Drawing.Size(289, 22); - this.formatAsWordToolStripMenuItem.Text = "Format As Word"; - this.formatAsWordToolStripMenuItem.Click += new System.EventHandler(this.formatAsWordToolStripMenuItem_Click); - // - // deleteNoteCommentToolStripMenuItem - // - this.deleteNoteCommentToolStripMenuItem.Name = "deleteNoteCommentToolStripMenuItem"; - this.deleteNoteCommentToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.Delete; - this.deleteNoteCommentToolStripMenuItem.Size = new System.Drawing.Size(289, 22); - this.deleteNoteCommentToolStripMenuItem.Text = "Delete Note/Long Comment"; - this.deleteNoteCommentToolStripMenuItem.Click += new System.EventHandler(this.DeleteNoteComment_Click); - // - // toolStripMenuItem9 - // - this.toolStripMenuItem9.Name = "toolStripMenuItem9"; - this.toolStripMenuItem9.Size = new System.Drawing.Size(286, 6); - // - // showHexDumpToolStripMenuItem - // - this.showHexDumpToolStripMenuItem.Name = "showHexDumpToolStripMenuItem"; - this.showHexDumpToolStripMenuItem.Size = new System.Drawing.Size(289, 22); - this.showHexDumpToolStripMenuItem.Text = "Show Hex Dump"; - this.showHexDumpToolStripMenuItem.Click += new System.EventHandler(this.ShowHexDump_Click); - // - // toolsToolStripMenuItem - // - this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.hexDumpToolStripMenuItem, - this.aSCIIChartToolStripMenuItem}); - this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem"; - this.toolsToolStripMenuItem.Size = new System.Drawing.Size(47, 20); - this.toolsToolStripMenuItem.Text = "Tools"; - // - // hexDumpToolStripMenuItem - // - this.hexDumpToolStripMenuItem.Name = "hexDumpToolStripMenuItem"; - this.hexDumpToolStripMenuItem.Size = new System.Drawing.Size(139, 22); - this.hexDumpToolStripMenuItem.Text = "Hex Dump..."; - this.hexDumpToolStripMenuItem.Click += new System.EventHandler(this.hexDumpToolStripMenuItem_Click); - // - // aSCIIChartToolStripMenuItem - // - this.aSCIIChartToolStripMenuItem.Name = "aSCIIChartToolStripMenuItem"; - this.aSCIIChartToolStripMenuItem.Size = new System.Drawing.Size(139, 22); - this.aSCIIChartToolStripMenuItem.Text = "ASCII Chart"; - this.aSCIIChartToolStripMenuItem.Click += new System.EventHandler(this.aSCIIChartToolStripMenuItem_Click); - // - // helpToolStripMenuItem - // - this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.contentsToolStripMenuItem, - this.aboutToolStripMenuItem}); - this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; - this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20); - this.helpToolStripMenuItem.Text = "Help"; - // - // contentsToolStripMenuItem - // - this.contentsToolStripMenuItem.Name = "contentsToolStripMenuItem"; - this.contentsToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F1; - this.contentsToolStripMenuItem.Size = new System.Drawing.Size(155, 22); - this.contentsToolStripMenuItem.Text = "View Help..."; - this.contentsToolStripMenuItem.Click += new System.EventHandler(this.viewHelpToolStripMenuItem_Click); - // - // aboutToolStripMenuItem - // - this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; - this.aboutToolStripMenuItem.Size = new System.Drawing.Size(155, 22); - this.aboutToolStripMenuItem.Text = "About..."; - this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click); - // - // dEBUGToolStripMenuItem - // - this.dEBUGToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.reanalyzeToolStripMenuItem, - this.showUndoRedoHistoryToolStripMenuItem, - this.showAnalyzerOutputToolStripMenuItem, - this.showAnalysisTimersToolStripMenuItem, - this.extensionScriptInfoToolStripMenuItem, - this.toolStripMenuItem6, - this.toggleOwnerDrawToolStripMenuItem, - this.toggleCommentRulersToolStripMenuItem, - this.useKeepAliveHackToolStripMenuItem, - this.toolStripMenuItem8, - this.sourceGenTestsToolStripMenuItem}); - this.dEBUGToolStripMenuItem.Name = "dEBUGToolStripMenuItem"; - this.dEBUGToolStripMenuItem.Size = new System.Drawing.Size(56, 20); - this.dEBUGToolStripMenuItem.Text = "DEBUG"; - this.dEBUGToolStripMenuItem.DropDownOpened += new System.EventHandler(this.dEBUGToolStripMenuItem_DropDownOpened); - // - // reanalyzeToolStripMenuItem - // - this.reanalyzeToolStripMenuItem.Name = "reanalyzeToolStripMenuItem"; - this.reanalyzeToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F5; - this.reanalyzeToolStripMenuItem.Size = new System.Drawing.Size(209, 22); - this.reanalyzeToolStripMenuItem.Text = "Re-analyze"; - this.reanalyzeToolStripMenuItem.Click += new System.EventHandler(this.reanalyzeToolStripMenuItem_Click); - // - // showUndoRedoHistoryToolStripMenuItem - // - this.showUndoRedoHistoryToolStripMenuItem.Name = "showUndoRedoHistoryToolStripMenuItem"; - this.showUndoRedoHistoryToolStripMenuItem.Size = new System.Drawing.Size(209, 22); - this.showUndoRedoHistoryToolStripMenuItem.Text = "Show Undo/Redo History"; - this.showUndoRedoHistoryToolStripMenuItem.Click += new System.EventHandler(this.showUndoRedoHistoryToolStripMenuItem_Click); - // - // showAnalyzerOutputToolStripMenuItem - // - this.showAnalyzerOutputToolStripMenuItem.Name = "showAnalyzerOutputToolStripMenuItem"; - this.showAnalyzerOutputToolStripMenuItem.Size = new System.Drawing.Size(209, 22); - this.showAnalyzerOutputToolStripMenuItem.Text = "Show Analyzer Output"; - this.showAnalyzerOutputToolStripMenuItem.Click += new System.EventHandler(this.showAnalyzerOutputToolStripMenuItem_Click); - // - // showAnalysisTimersToolStripMenuItem - // - this.showAnalysisTimersToolStripMenuItem.Name = "showAnalysisTimersToolStripMenuItem"; - this.showAnalysisTimersToolStripMenuItem.Size = new System.Drawing.Size(209, 22); - this.showAnalysisTimersToolStripMenuItem.Text = "Show Analysis Timers"; - this.showAnalysisTimersToolStripMenuItem.Click += new System.EventHandler(this.showAnalysisTimersToolStripMenuItem_Click); - // - // extensionScriptInfoToolStripMenuItem - // - this.extensionScriptInfoToolStripMenuItem.Name = "extensionScriptInfoToolStripMenuItem"; - this.extensionScriptInfoToolStripMenuItem.Size = new System.Drawing.Size(209, 22); - this.extensionScriptInfoToolStripMenuItem.Text = "Extension Script Info..."; - this.extensionScriptInfoToolStripMenuItem.Click += new System.EventHandler(this.extensionScriptInfoToolStripMenuItem_Click); - // - // toolStripMenuItem6 - // - this.toolStripMenuItem6.Name = "toolStripMenuItem6"; - this.toolStripMenuItem6.Size = new System.Drawing.Size(206, 6); - // - // toggleOwnerDrawToolStripMenuItem - // - this.toggleOwnerDrawToolStripMenuItem.Name = "toggleOwnerDrawToolStripMenuItem"; - this.toggleOwnerDrawToolStripMenuItem.Size = new System.Drawing.Size(209, 22); - this.toggleOwnerDrawToolStripMenuItem.Text = "Toggle OwnerDraw"; - this.toggleOwnerDrawToolStripMenuItem.Click += new System.EventHandler(this.toggleOwnerDrawToolStripMenuItem_Click); - // - // toggleCommentRulersToolStripMenuItem - // - this.toggleCommentRulersToolStripMenuItem.Name = "toggleCommentRulersToolStripMenuItem"; - this.toggleCommentRulersToolStripMenuItem.Size = new System.Drawing.Size(209, 22); - this.toggleCommentRulersToolStripMenuItem.Text = "Toggle Comment Rulers"; - this.toggleCommentRulersToolStripMenuItem.Click += new System.EventHandler(this.toggleCommentRulersToolStripMenuItem_Click); - // - // useKeepAliveHackToolStripMenuItem - // - this.useKeepAliveHackToolStripMenuItem.Name = "useKeepAliveHackToolStripMenuItem"; - this.useKeepAliveHackToolStripMenuItem.Size = new System.Drawing.Size(209, 22); - this.useKeepAliveHackToolStripMenuItem.Text = "Use Keep-Alive Hack"; - this.useKeepAliveHackToolStripMenuItem.Click += new System.EventHandler(this.useKeepAliveHackToolStripMenuItem_Click); - // - // toolStripMenuItem8 - // - this.toolStripMenuItem8.Name = "toolStripMenuItem8"; - this.toolStripMenuItem8.Size = new System.Drawing.Size(206, 6); - // - // sourceGenTestsToolStripMenuItem - // - this.sourceGenTestsToolStripMenuItem.Name = "sourceGenTestsToolStripMenuItem"; - this.sourceGenTestsToolStripMenuItem.Size = new System.Drawing.Size(209, 22); - this.sourceGenTestsToolStripMenuItem.Text = "Source Generation Tests..."; - this.sourceGenTestsToolStripMenuItem.Click += new System.EventHandler(this.sourceGenTestsToolStripMenuItem_Click); - // - // mainStatusStrip - // - this.mainStatusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.toolStripStatusLabel}); - this.mainStatusStrip.Location = new System.Drawing.Point(0, 592); - this.mainStatusStrip.Name = "mainStatusStrip"; - this.mainStatusStrip.Size = new System.Drawing.Size(805, 22); - this.mainStatusStrip.TabIndex = 1; - this.mainStatusStrip.Text = "Main StatusStrip"; - // - // toolStripStatusLabel - // - this.toolStripStatusLabel.Name = "toolStripStatusLabel"; - this.toolStripStatusLabel.Size = new System.Drawing.Size(39, 17); - this.toolStripStatusLabel.Text = "Ready"; - // - // mainToolStrip - // - this.mainToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; - this.mainToolStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.navigateBackToolStripButton, - this.navigateFwdToolStripButton, - this.toolStripSeparator2, - this.newToolStripButton, - this.openToolStripButton, - this.saveToolStripButton, - this.printToolStripButton, - this.toolStripSeparator, - this.cutToolStripButton, - this.copyToolStripButton, - this.pasteToolStripButton, - this.toolStripSeparator1, - this.helpToolStripButton}); - this.mainToolStrip.Location = new System.Drawing.Point(0, 24); - this.mainToolStrip.Name = "mainToolStrip"; - this.mainToolStrip.Size = new System.Drawing.Size(805, 25); - this.mainToolStrip.TabIndex = 2; - this.mainToolStrip.Text = "toolStrip1"; - // - // navigateBackToolStripButton - // - this.navigateBackToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.navigateBackToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("navigateBackToolStripButton.Image"))); - this.navigateBackToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.navigateBackToolStripButton.Name = "navigateBackToolStripButton"; - this.navigateBackToolStripButton.Size = new System.Drawing.Size(23, 22); - this.navigateBackToolStripButton.Text = "toolStripButton2"; - this.navigateBackToolStripButton.ToolTipText = "Navigate Backward"; - this.navigateBackToolStripButton.Click += new System.EventHandler(this.navigateBackToolStripButton_Click); - // - // navigateFwdToolStripButton - // - this.navigateFwdToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.navigateFwdToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("navigateFwdToolStripButton.Image"))); - this.navigateFwdToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.navigateFwdToolStripButton.Name = "navigateFwdToolStripButton"; - this.navigateFwdToolStripButton.Size = new System.Drawing.Size(23, 22); - this.navigateFwdToolStripButton.Text = "toolStripButton1"; - this.navigateFwdToolStripButton.ToolTipText = "Navigate Forward"; - this.navigateFwdToolStripButton.Click += new System.EventHandler(this.navigateFwdToolStripButton_Click); - // - // toolStripSeparator2 - // - this.toolStripSeparator2.Name = "toolStripSeparator2"; - this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25); - // - // newToolStripButton - // - this.newToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.newToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("newToolStripButton.Image"))); - this.newToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.newToolStripButton.Name = "newToolStripButton"; - this.newToolStripButton.Size = new System.Drawing.Size(23, 22); - this.newToolStripButton.Text = "&New"; - this.newToolStripButton.Click += new System.EventHandler(this.newToolStripButton_Click); - // - // openToolStripButton - // - this.openToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.openToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("openToolStripButton.Image"))); - this.openToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.openToolStripButton.Name = "openToolStripButton"; - this.openToolStripButton.Size = new System.Drawing.Size(23, 22); - this.openToolStripButton.Text = "&Open"; - this.openToolStripButton.Click += new System.EventHandler(this.openToolStripButton_Click); - // - // saveToolStripButton - // - this.saveToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.saveToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("saveToolStripButton.Image"))); - this.saveToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.saveToolStripButton.Name = "saveToolStripButton"; - this.saveToolStripButton.Size = new System.Drawing.Size(23, 22); - this.saveToolStripButton.Text = "&Save"; - this.saveToolStripButton.Click += new System.EventHandler(this.saveToolStripButton_Click); - // - // printToolStripButton - // - this.printToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.printToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("printToolStripButton.Image"))); - this.printToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.printToolStripButton.Name = "printToolStripButton"; - this.printToolStripButton.Size = new System.Drawing.Size(23, 22); - this.printToolStripButton.Text = "&Print"; - this.printToolStripButton.Visible = false; - // - // toolStripSeparator - // - this.toolStripSeparator.Name = "toolStripSeparator"; - this.toolStripSeparator.Size = new System.Drawing.Size(6, 25); - // - // cutToolStripButton - // - this.cutToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.cutToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("cutToolStripButton.Image"))); - this.cutToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.cutToolStripButton.Name = "cutToolStripButton"; - this.cutToolStripButton.Size = new System.Drawing.Size(23, 22); - this.cutToolStripButton.Text = "C&ut"; - this.cutToolStripButton.Visible = false; - // - // copyToolStripButton - // - this.copyToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.copyToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("copyToolStripButton.Image"))); - this.copyToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.copyToolStripButton.Name = "copyToolStripButton"; - this.copyToolStripButton.Size = new System.Drawing.Size(23, 22); - this.copyToolStripButton.Text = "&Copy"; - // - // pasteToolStripButton - // - this.pasteToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.pasteToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("pasteToolStripButton.Image"))); - this.pasteToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.pasteToolStripButton.Name = "pasteToolStripButton"; - this.pasteToolStripButton.Size = new System.Drawing.Size(23, 22); - this.pasteToolStripButton.Text = "&Paste"; - this.pasteToolStripButton.Visible = false; - // - // toolStripSeparator1 - // - this.toolStripSeparator1.Name = "toolStripSeparator1"; - this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); - // - // helpToolStripButton - // - this.helpToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.helpToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("helpToolStripButton.Image"))); - this.helpToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; - this.helpToolStripButton.Name = "helpToolStripButton"; - this.helpToolStripButton.Size = new System.Drawing.Size(23, 22); - this.helpToolStripButton.Text = "He&lp"; - this.helpToolStripButton.Click += new System.EventHandler(this.helpToolStripButton_Click); - // - // mainSplitterLeft - // - this.mainSplitterLeft.Dock = System.Windows.Forms.DockStyle.Fill; - this.mainSplitterLeft.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; - this.mainSplitterLeft.Location = new System.Drawing.Point(0, 49); - this.mainSplitterLeft.Name = "mainSplitterLeft"; - // - // mainSplitterLeft.Panel1 - // - this.mainSplitterLeft.Panel1.Controls.Add(this.leftPanelSplitter); - this.mainSplitterLeft.Panel1MinSize = 100; - // - // mainSplitterLeft.Panel2 - // - this.mainSplitterLeft.Panel2.Controls.Add(this.mainSplitterRight); - this.mainSplitterLeft.Panel2MinSize = 350; - this.mainSplitterLeft.Size = new System.Drawing.Size(805, 543); - this.mainSplitterLeft.SplitterDistance = 168; - this.mainSplitterLeft.TabIndex = 3; - // - // leftPanelSplitter - // - this.leftPanelSplitter.Dock = System.Windows.Forms.DockStyle.Fill; - this.leftPanelSplitter.Location = new System.Drawing.Point(0, 0); - this.leftPanelSplitter.Name = "leftPanelSplitter"; - this.leftPanelSplitter.Orientation = System.Windows.Forms.Orientation.Horizontal; - // - // leftPanelSplitter.Panel1 - // - this.leftPanelSplitter.Panel1.Controls.Add(this.referencesGroupBox); - this.leftPanelSplitter.Panel1MinSize = 100; - // - // leftPanelSplitter.Panel2 - // - this.leftPanelSplitter.Panel2.Controls.Add(this.notesGroupBox); - this.leftPanelSplitter.Panel2MinSize = 100; - this.leftPanelSplitter.Size = new System.Drawing.Size(168, 543); - this.leftPanelSplitter.SplitterDistance = 350; - this.leftPanelSplitter.TabIndex = 0; - this.leftPanelSplitter.SplitterMoved += new System.Windows.Forms.SplitterEventHandler(this.SidePanelSplitter_SplitterMoved); - // - // referencesGroupBox - // - this.referencesGroupBox.Controls.Add(this.referencesListView); - this.referencesGroupBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.referencesGroupBox.Location = new System.Drawing.Point(0, 0); - this.referencesGroupBox.Name = "referencesGroupBox"; - this.referencesGroupBox.Size = new System.Drawing.Size(168, 350); - this.referencesGroupBox.TabIndex = 2; - this.referencesGroupBox.TabStop = false; - this.referencesGroupBox.Text = "References"; - // - // referencesListView - // - this.referencesListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.offsetColumnHeader, - this.addressColumnHeader, - this.typeColumnHeader}); - this.referencesListView.Dock = System.Windows.Forms.DockStyle.Fill; - this.referencesListView.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.referencesListView.FullRowSelect = true; - this.referencesListView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; - this.referencesListView.Location = new System.Drawing.Point(3, 16); - this.referencesListView.MultiSelect = false; - this.referencesListView.Name = "referencesListView"; - this.referencesListView.Size = new System.Drawing.Size(162, 331); - this.referencesListView.TabIndex = 1; - this.referencesListView.UseCompatibleStateImageBehavior = false; - this.referencesListView.View = System.Windows.Forms.View.Details; - this.referencesListView.ColumnWidthChanged += new System.Windows.Forms.ColumnWidthChangedEventHandler(this.referencesListView_ColumnWidthChanged); - this.referencesListView.SizeChanged += new System.EventHandler(this.referencesListView_SizeChanged); - this.referencesListView.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.referencesListView_MouseDoubleClick); - // - // offsetColumnHeader - // - this.offsetColumnHeader.Text = "Offset"; - this.offsetColumnHeader.Width = 52; - // - // addressColumnHeader - // - this.addressColumnHeader.Text = "Addr"; - this.addressColumnHeader.Width = 54; - // - // typeColumnHeader - // - this.typeColumnHeader.Text = "Type"; - this.typeColumnHeader.Width = 116; - // - // notesGroupBox - // - this.notesGroupBox.Controls.Add(this.notesListView); - this.notesGroupBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.notesGroupBox.Location = new System.Drawing.Point(0, 0); - this.notesGroupBox.Name = "notesGroupBox"; - this.notesGroupBox.Size = new System.Drawing.Size(168, 189); - this.notesGroupBox.TabIndex = 0; - this.notesGroupBox.TabStop = false; - this.notesGroupBox.Text = "Notes"; - // - // notesListView - // - this.notesListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.notesOffsetColumnHeader, - this.notesNoteColumnHeader}); - this.notesListView.Dock = System.Windows.Forms.DockStyle.Fill; - this.notesListView.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.notesListView.FullRowSelect = true; - this.notesListView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; - this.notesListView.Location = new System.Drawing.Point(3, 16); - this.notesListView.MultiSelect = false; - this.notesListView.Name = "notesListView"; - this.notesListView.OwnerDraw = true; - this.notesListView.Size = new System.Drawing.Size(162, 170); - this.notesListView.TabIndex = 0; - this.notesListView.UseCompatibleStateImageBehavior = false; - this.notesListView.View = System.Windows.Forms.View.Details; - this.notesListView.VirtualMode = true; - this.notesListView.CacheVirtualItems += new System.Windows.Forms.CacheVirtualItemsEventHandler(this.notesListView_CacheVirtualItems); - this.notesListView.ColumnWidthChanged += new System.Windows.Forms.ColumnWidthChangedEventHandler(this.notesListView_ColumnWidthChanged); - this.notesListView.DrawColumnHeader += new System.Windows.Forms.DrawListViewColumnHeaderEventHandler(this.notesListView_DrawColumnHeader); - this.notesListView.DrawItem += new System.Windows.Forms.DrawListViewItemEventHandler(this.notesListView_DrawItem); - this.notesListView.DrawSubItem += new System.Windows.Forms.DrawListViewSubItemEventHandler(this.notesListView_DrawSubItem); - this.notesListView.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.notesListView_RetrieveVirtualItem); - this.notesListView.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.notesListView_MouseDoubleClick); - // - // notesOffsetColumnHeader - // - this.notesOffsetColumnHeader.Text = "Offset"; - this.notesOffsetColumnHeader.Width = 52; - // - // notesNoteColumnHeader - // - this.notesNoteColumnHeader.Text = "Note"; - this.notesNoteColumnHeader.Width = 400; - // - // mainSplitterRight - // - this.mainSplitterRight.Dock = System.Windows.Forms.DockStyle.Fill; - this.mainSplitterRight.FixedPanel = System.Windows.Forms.FixedPanel.Panel2; - this.mainSplitterRight.Location = new System.Drawing.Point(0, 0); - this.mainSplitterRight.Name = "mainSplitterRight"; - // - // mainSplitterRight.Panel1 - // - this.mainSplitterRight.Panel1.Controls.Add(this.noProjectPanel); - this.mainSplitterRight.Panel1.Controls.Add(this.codeListView); - this.mainSplitterRight.Panel1MinSize = 150; - // - // mainSplitterRight.Panel2 - // - this.mainSplitterRight.Panel2.Controls.Add(this.rightPanelSplitter); - this.mainSplitterRight.Panel2MinSize = 100; - this.mainSplitterRight.Size = new System.Drawing.Size(633, 543); - this.mainSplitterRight.SplitterDistance = 446; - this.mainSplitterRight.TabIndex = 0; - // - // noProjectPanel - // - this.noProjectPanel.Controls.Add(this.debugModeEnabledLabel); - this.noProjectPanel.Controls.Add(this.recentProjectsLabel); - this.noProjectPanel.Controls.Add(this.recentProjectLabel2); - this.noProjectPanel.Controls.Add(this.versionLabel); - this.noProjectPanel.Controls.Add(this.sourceGenLabel); - this.noProjectPanel.Controls.Add(this.logoPictureBox); - this.noProjectPanel.Controls.Add(this.recentProjectLabel1); - this.noProjectPanel.Controls.Add(this.openExistingLabel); - this.noProjectPanel.Controls.Add(this.newProjectLink); - this.noProjectPanel.Dock = System.Windows.Forms.DockStyle.Fill; - this.noProjectPanel.Location = new System.Drawing.Point(0, 0); - this.noProjectPanel.Name = "noProjectPanel"; - this.noProjectPanel.Size = new System.Drawing.Size(446, 543); - this.noProjectPanel.TabIndex = 1; - // - // debugModeEnabledLabel - // - this.debugModeEnabledLabel.AutoSize = true; - this.debugModeEnabledLabel.Location = new System.Drawing.Point(219, 135); - this.debugModeEnabledLabel.Name = "debugModeEnabledLabel"; - this.debugModeEnabledLabel.Size = new System.Drawing.Size(271, 13); - this.debugModeEnabledLabel.TabIndex = 8; - this.debugModeEnabledLabel.Text = "Debug mode • extended logging and validation enabled"; - this.debugModeEnabledLabel.Visible = false; - // - // recentProjectsLabel - // - this.recentProjectsLabel.AutoSize = true; - this.recentProjectsLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.recentProjectsLabel.Location = new System.Drawing.Point(25, 307); - this.recentProjectsLabel.Name = "recentProjectsLabel"; - this.recentProjectsLabel.Size = new System.Drawing.Size(157, 20); - this.recentProjectsLabel.TabIndex = 7; - this.recentProjectsLabel.Text = "Most recent projects:"; - // - // recentProjectLabel2 - // - this.recentProjectLabel2.AutoSize = true; - this.recentProjectLabel2.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.recentProjectLabel2.Location = new System.Drawing.Point(40, 427); - this.recentProjectLabel2.Name = "recentProjectLabel2"; - this.recentProjectLabel2.Size = new System.Drawing.Size(135, 20); - this.recentProjectLabel2.TabIndex = 6; - this.recentProjectLabel2.TabStop = true; - this.recentProjectLabel2.Text = "Recent project #2"; - this.recentProjectLabel2.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.recentProjectLabel2_LinkClicked); - // - // versionLabel - // - this.versionLabel.AutoSize = true; - this.versionLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 20.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.versionLabel.Location = new System.Drawing.Point(213, 90); - this.versionLabel.Name = "versionLabel"; - this.versionLabel.Size = new System.Drawing.Size(273, 31); - this.versionLabel.TabIndex = 5; - this.versionLabel.Text = "Version X.Y.Z Alpha1"; - // - // sourceGenLabel - // - this.sourceGenLabel.AutoSize = true; - this.sourceGenLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.sourceGenLabel.Location = new System.Drawing.Point(213, 32); - this.sourceGenLabel.Name = "sourceGenLabel"; - this.sourceGenLabel.Size = new System.Drawing.Size(346, 37); - this.sourceGenLabel.TabIndex = 4; - this.sourceGenLabel.Text = "6502bench SourceGen"; - // - // logoPictureBox - // - this.logoPictureBox.ImageLocation = "SourceGen\\RuntimeData\\Logo.png"; - this.logoPictureBox.Location = new System.Drawing.Point(4, 4); - this.logoPictureBox.Name = "logoPictureBox"; - this.logoPictureBox.Size = new System.Drawing.Size(203, 145); - this.logoPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; - this.logoPictureBox.TabIndex = 3; - this.logoPictureBox.TabStop = false; - // - // recentProjectLabel1 - // - this.recentProjectLabel1.AutoSize = true; - this.recentProjectLabel1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.recentProjectLabel1.Location = new System.Drawing.Point(40, 367); - this.recentProjectLabel1.Name = "recentProjectLabel1"; - this.recentProjectLabel1.Size = new System.Drawing.Size(135, 20); - this.recentProjectLabel1.TabIndex = 2; - this.recentProjectLabel1.TabStop = true; - this.recentProjectLabel1.Text = "Recent project #1"; - this.recentProjectLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.recentProjectLabel1_LinkClicked); - // - // openExistingLabel - // - this.openExistingLabel.AutoSize = true; - this.openExistingLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.openExistingLabel.Location = new System.Drawing.Point(25, 247); - this.openExistingLabel.Name = "openExistingLabel"; - this.openExistingLabel.Size = new System.Drawing.Size(157, 20); - this.openExistingLabel.TabIndex = 1; - this.openExistingLabel.TabStop = true; - this.openExistingLabel.Text = "Open existing project"; - this.openExistingLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.openExistingLabel_LinkClicked); - // - // newProjectLink - // - this.newProjectLink.AutoSize = true; - this.newProjectLink.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.newProjectLink.Location = new System.Drawing.Point(25, 187); - this.newProjectLink.Name = "newProjectLink"; - this.newProjectLink.Size = new System.Drawing.Size(129, 20); - this.newProjectLink.TabIndex = 0; - this.newProjectLink.TabStop = true; - this.newProjectLink.Text = "Start new project"; - this.newProjectLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.newFileLink_LinkClicked); - // - // codeListView - // - this.codeListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.columnOffset, - this.columnAddr, - this.columnBytes, - this.columnFlags, - this.columnAttr, - this.columnLabel, - this.columnOpcode, - this.columnOperand, - this.columnComment}); - this.codeListView.Dock = System.Windows.Forms.DockStyle.Fill; - this.codeListView.Font = new System.Drawing.Font("Consolas", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.codeListView.FullRowSelect = true; - this.codeListView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; - this.codeListView.HideSelection = false; - this.codeListView.Location = new System.Drawing.Point(0, 0); - this.codeListView.Name = "codeListView"; - this.codeListView.OwnerDraw = true; - this.codeListView.Size = new System.Drawing.Size(446, 543); - this.codeListView.TabIndex = 0; - this.codeListView.UseCompatibleStateImageBehavior = false; - this.codeListView.View = System.Windows.Forms.View.Details; - this.codeListView.VirtualMode = true; - this.codeListView.CacheVirtualItems += new System.Windows.Forms.CacheVirtualItemsEventHandler(this.codeListView_CacheVirtualItems); - this.codeListView.ColumnWidthChanged += new System.Windows.Forms.ColumnWidthChangedEventHandler(this.codeListView_ColumnWidthChanged); - this.codeListView.DrawColumnHeader += new System.Windows.Forms.DrawListViewColumnHeaderEventHandler(this.codeListView_DrawColumnHeader); - this.codeListView.DrawItem += new System.Windows.Forms.DrawListViewItemEventHandler(this.codeListView_DrawItem); - this.codeListView.DrawSubItem += new System.Windows.Forms.DrawListViewSubItemEventHandler(this.codeListView_DrawSubItem); - this.codeListView.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.codeListView_ItemSelectionChanged); - this.codeListView.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.codeListView_RetrieveVirtualItem); - this.codeListView.SelectedIndexChanged += new System.EventHandler(this.codeListView_SelectedIndexChanged); - this.codeListView.VirtualItemsSelectionRangeChanged += new System.Windows.Forms.ListViewVirtualItemsSelectionRangeChangedEventHandler(this.codeListView_VirtualItemsSelectionRangeChanged); - this.codeListView.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.codeListView_MouseDoubleClick); - this.codeListView.MouseDown += new System.Windows.Forms.MouseEventHandler(this.codeListView_MouseDown); - // - // columnOffset - // - this.columnOffset.Text = "offset"; - this.columnOffset.Width = 0; - // - // columnAddr - // - this.columnAddr.Text = "addr"; - this.columnAddr.Width = 0; - // - // columnBytes - // - this.columnBytes.Text = "bytes"; - this.columnBytes.Width = 0; - // - // columnFlags - // - this.columnFlags.Text = "flags"; - this.columnFlags.Width = 0; - // - // columnAttr - // - this.columnAttr.Text = "attr"; - this.columnAttr.Width = 0; - // - // columnLabel - // - this.columnLabel.Text = "label"; - this.columnLabel.Width = 0; - // - // columnOpcode - // - this.columnOpcode.Text = "opcode"; - this.columnOpcode.Width = 0; - // - // columnOperand - // - this.columnOperand.Text = "operand"; - this.columnOperand.Width = 0; - // - // columnComment - // - this.columnComment.Text = "comment"; - this.columnComment.Width = 0; - // - // rightPanelSplitter - // - this.rightPanelSplitter.Dock = System.Windows.Forms.DockStyle.Fill; - this.rightPanelSplitter.FixedPanel = System.Windows.Forms.FixedPanel.Panel2; - this.rightPanelSplitter.Location = new System.Drawing.Point(0, 0); - this.rightPanelSplitter.Name = "rightPanelSplitter"; - this.rightPanelSplitter.Orientation = System.Windows.Forms.Orientation.Horizontal; - // - // rightPanelSplitter.Panel1 - // - this.rightPanelSplitter.Panel1.Controls.Add(this.symbolsGroupBox); - this.rightPanelSplitter.Panel1MinSize = 200; - // - // rightPanelSplitter.Panel2 - // - this.rightPanelSplitter.Panel2.Controls.Add(this.infoGroupBox); - this.rightPanelSplitter.Panel2MinSize = 100; - this.rightPanelSplitter.Size = new System.Drawing.Size(183, 543); - this.rightPanelSplitter.SplitterDistance = 400; - this.rightPanelSplitter.TabIndex = 8; - this.rightPanelSplitter.SplitterMoved += new System.Windows.Forms.SplitterEventHandler(this.SidePanelSplitter_SplitterMoved); - // - // symbolsGroupBox - // - this.symbolsGroupBox.Controls.Add(this.symbolUserCheckBox); - this.symbolsGroupBox.Controls.Add(this.symbolProjectCheckBox); - this.symbolsGroupBox.Controls.Add(this.symbolAddressCheckBox); - this.symbolsGroupBox.Controls.Add(this.symbolConstantCheckBox); - this.symbolsGroupBox.Controls.Add(this.symbolAutoCheckBox); - this.symbolsGroupBox.Controls.Add(this.symbolPlatformCheckBox); - this.symbolsGroupBox.Controls.Add(this.symbolListView); - this.symbolsGroupBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.symbolsGroupBox.Location = new System.Drawing.Point(0, 0); - this.symbolsGroupBox.Name = "symbolsGroupBox"; - this.symbolsGroupBox.Size = new System.Drawing.Size(183, 400); - this.symbolsGroupBox.TabIndex = 2; - this.symbolsGroupBox.TabStop = false; - this.symbolsGroupBox.Text = "Symbols"; - // - // symbolUserCheckBox - // - this.symbolUserCheckBox.Appearance = System.Windows.Forms.Appearance.Button; - this.symbolUserCheckBox.FlatStyle = System.Windows.Forms.FlatStyle.System; - this.symbolUserCheckBox.Location = new System.Drawing.Point(6, 19); - this.symbolUserCheckBox.Name = "symbolUserCheckBox"; - this.symbolUserCheckBox.Size = new System.Drawing.Size(39, 23); - this.symbolUserCheckBox.TabIndex = 7; - this.symbolUserCheckBox.Text = "User"; - this.symbolUserCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - this.symbolUserCheckBox.UseVisualStyleBackColor = true; - this.symbolUserCheckBox.CheckedChanged += new System.EventHandler(this.symbolUserCheckBox_CheckedChanged); - // - // symbolProjectCheckBox - // - this.symbolProjectCheckBox.Appearance = System.Windows.Forms.Appearance.Button; - this.symbolProjectCheckBox.FlatStyle = System.Windows.Forms.FlatStyle.System; - this.symbolProjectCheckBox.Location = new System.Drawing.Point(51, 19); - this.symbolProjectCheckBox.Name = "symbolProjectCheckBox"; - this.symbolProjectCheckBox.Size = new System.Drawing.Size(39, 23); - this.symbolProjectCheckBox.TabIndex = 6; - this.symbolProjectCheckBox.Text = "Proj"; - this.symbolProjectCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - this.symbolProjectCheckBox.UseVisualStyleBackColor = true; - this.symbolProjectCheckBox.CheckedChanged += new System.EventHandler(this.symbolProjectCheckBox_CheckedChanged); - // - // symbolAddressCheckBox - // - this.symbolAddressCheckBox.Appearance = System.Windows.Forms.Appearance.Button; - this.symbolAddressCheckBox.FlatStyle = System.Windows.Forms.FlatStyle.System; - this.symbolAddressCheckBox.Location = new System.Drawing.Point(5, 48); - this.symbolAddressCheckBox.Name = "symbolAddressCheckBox"; - this.symbolAddressCheckBox.Size = new System.Drawing.Size(39, 23); - this.symbolAddressCheckBox.TabIndex = 5; - this.symbolAddressCheckBox.Text = "Addr"; - this.symbolAddressCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - this.symbolAddressCheckBox.UseVisualStyleBackColor = true; - this.symbolAddressCheckBox.CheckedChanged += new System.EventHandler(this.symbolAddrCheckBox_CheckedChanged); - // - // symbolConstantCheckBox - // - this.symbolConstantCheckBox.Appearance = System.Windows.Forms.Appearance.Button; - this.symbolConstantCheckBox.FlatStyle = System.Windows.Forms.FlatStyle.System; - this.symbolConstantCheckBox.Location = new System.Drawing.Point(51, 48); - this.symbolConstantCheckBox.Name = "symbolConstantCheckBox"; - this.symbolConstantCheckBox.Size = new System.Drawing.Size(39, 23); - this.symbolConstantCheckBox.TabIndex = 4; - this.symbolConstantCheckBox.Text = "Cnst"; - this.symbolConstantCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - this.symbolConstantCheckBox.UseVisualStyleBackColor = true; - this.symbolConstantCheckBox.CheckedChanged += new System.EventHandler(this.symbolConstantCheckBox_CheckedChanged); - // - // symbolAutoCheckBox - // - this.symbolAutoCheckBox.Appearance = System.Windows.Forms.Appearance.Button; - this.symbolAutoCheckBox.FlatStyle = System.Windows.Forms.FlatStyle.System; - this.symbolAutoCheckBox.Location = new System.Drawing.Point(141, 19); - this.symbolAutoCheckBox.Name = "symbolAutoCheckBox"; - this.symbolAutoCheckBox.Size = new System.Drawing.Size(39, 23); - this.symbolAutoCheckBox.TabIndex = 1; - this.symbolAutoCheckBox.Text = "Auto"; - this.symbolAutoCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - this.symbolAutoCheckBox.UseVisualStyleBackColor = true; - this.symbolAutoCheckBox.CheckedChanged += new System.EventHandler(this.symbolAutoCheckBox_CheckedChanged); - // - // symbolPlatformCheckBox - // - this.symbolPlatformCheckBox.Appearance = System.Windows.Forms.Appearance.Button; - this.symbolPlatformCheckBox.FlatStyle = System.Windows.Forms.FlatStyle.System; - this.symbolPlatformCheckBox.Location = new System.Drawing.Point(96, 19); - this.symbolPlatformCheckBox.Name = "symbolPlatformCheckBox"; - this.symbolPlatformCheckBox.Size = new System.Drawing.Size(39, 23); - this.symbolPlatformCheckBox.TabIndex = 3; - this.symbolPlatformCheckBox.Text = "Plat"; - this.symbolPlatformCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - this.symbolPlatformCheckBox.UseVisualStyleBackColor = true; - this.symbolPlatformCheckBox.CheckedChanged += new System.EventHandler(this.symbolPlatformCheckBox_CheckedChanged); - // - // symbolListView - // - this.symbolListView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.symbolListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.symbolTypeColumnHeader, - this.symbolValueColumnHeader, - this.symbolNameColumnHeader}); - this.symbolListView.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.symbolListView.FullRowSelect = true; - this.symbolListView.GridLines = true; - this.symbolListView.Location = new System.Drawing.Point(3, 79); - this.symbolListView.MultiSelect = false; - this.symbolListView.Name = "symbolListView"; - this.symbolListView.Size = new System.Drawing.Size(177, 318); - this.symbolListView.TabIndex = 2; - this.symbolListView.UseCompatibleStateImageBehavior = false; - this.symbolListView.View = System.Windows.Forms.View.Details; - this.symbolListView.VirtualMode = true; - this.symbolListView.CacheVirtualItems += new System.Windows.Forms.CacheVirtualItemsEventHandler(this.symbolListView_CacheVirtualItems); - this.symbolListView.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.symbolListView_ColumnClick); - this.symbolListView.ColumnWidthChanged += new System.Windows.Forms.ColumnWidthChangedEventHandler(this.symbolListView_ColumnWidthChanged); - this.symbolListView.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.symbolListView_RetrieveVirtualItem); - this.symbolListView.SizeChanged += new System.EventHandler(this.symbolListView_SizeChanged); - this.symbolListView.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.symbolListView_MouseDoubleClick); - // - // symbolTypeColumnHeader - // - this.symbolTypeColumnHeader.Text = "Type"; - this.symbolTypeColumnHeader.Width = 44; - // - // symbolValueColumnHeader - // - this.symbolValueColumnHeader.Text = "Value"; - this.symbolValueColumnHeader.Width = 54; - // - // symbolNameColumnHeader - // - this.symbolNameColumnHeader.Text = "Name"; - this.symbolNameColumnHeader.Width = 100; - // - // infoGroupBox - // - this.infoGroupBox.Controls.Add(this.infoTextBox); - this.infoGroupBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.infoGroupBox.Location = new System.Drawing.Point(0, 0); - this.infoGroupBox.Name = "infoGroupBox"; - this.infoGroupBox.Size = new System.Drawing.Size(183, 139); - this.infoGroupBox.TabIndex = 0; - this.infoGroupBox.TabStop = false; - this.infoGroupBox.Text = "Info"; - // - // infoTextBox - // - this.infoTextBox.Dock = System.Windows.Forms.DockStyle.Fill; - this.infoTextBox.Location = new System.Drawing.Point(3, 16); - this.infoTextBox.Multiline = true; - this.infoTextBox.Name = "infoTextBox"; - this.infoTextBox.ReadOnly = true; - this.infoTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.infoTextBox.Size = new System.Drawing.Size(177, 120); - this.infoTextBox.TabIndex = 0; - // - // ProjectView - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(805, 614); - this.Controls.Add(this.mainSplitterLeft); - this.Controls.Add(this.mainStatusStrip); - this.Controls.Add(this.mainToolStrip); - this.Controls.Add(this.mainMenuStrip); - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.MinimumSize = new System.Drawing.Size(800, 600); - this.Name = "ProjectView"; - this.Text = "6502bench SourceGen"; - this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.ProjectView_FormClosing); - this.Load += new System.EventHandler(this.ProjectView_Load); - this.LocationChanged += new System.EventHandler(this.ProjectView_SizeOrLocChanged); - this.SizeChanged += new System.EventHandler(this.ProjectView_SizeOrLocChanged); - this.mainMenuStrip.ResumeLayout(false); - this.mainMenuStrip.PerformLayout(); - this.mainStatusStrip.ResumeLayout(false); - this.mainStatusStrip.PerformLayout(); - this.mainToolStrip.ResumeLayout(false); - this.mainToolStrip.PerformLayout(); - this.mainSplitterLeft.Panel1.ResumeLayout(false); - this.mainSplitterLeft.Panel2.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.mainSplitterLeft)).EndInit(); - this.mainSplitterLeft.ResumeLayout(false); - this.leftPanelSplitter.Panel1.ResumeLayout(false); - this.leftPanelSplitter.Panel2.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.leftPanelSplitter)).EndInit(); - this.leftPanelSplitter.ResumeLayout(false); - this.referencesGroupBox.ResumeLayout(false); - this.notesGroupBox.ResumeLayout(false); - this.mainSplitterRight.Panel1.ResumeLayout(false); - this.mainSplitterRight.Panel2.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.mainSplitterRight)).EndInit(); - this.mainSplitterRight.ResumeLayout(false); - this.noProjectPanel.ResumeLayout(false); - this.noProjectPanel.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).EndInit(); - this.rightPanelSplitter.Panel1.ResumeLayout(false); - this.rightPanelSplitter.Panel2.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.rightPanelSplitter)).EndInit(); - this.rightPanelSplitter.ResumeLayout(false); - this.symbolsGroupBox.ResumeLayout(false); - this.infoGroupBox.ResumeLayout(false); - this.infoGroupBox.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.MenuStrip mainMenuStrip; - private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem copyToolStripMenuItem; - private System.Windows.Forms.StatusStrip mainStatusStrip; - private System.Windows.Forms.ToolStrip mainToolStrip; - private System.Windows.Forms.ToolStripButton newToolStripButton; - private System.Windows.Forms.ToolStripButton openToolStripButton; - private System.Windows.Forms.ToolStripButton saveToolStripButton; - private System.Windows.Forms.ToolStripButton printToolStripButton; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator; - private System.Windows.Forms.ToolStripButton cutToolStripButton; - private System.Windows.Forms.ToolStripButton copyToolStripButton; - private System.Windows.Forms.ToolStripButton pasteToolStripButton; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; - private System.Windows.Forms.ToolStripButton helpToolStripButton; - private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel; - private System.Windows.Forms.SplitContainer mainSplitterLeft; - private System.Windows.Forms.SplitContainer mainSplitterRight; - private System.Windows.Forms.ListView codeListView; - private System.Windows.Forms.SplitContainer leftPanelSplitter; - private System.Windows.Forms.ListView referencesListView; - private System.Windows.Forms.Panel noProjectPanel; - private System.Windows.Forms.LinkLabel newProjectLink; - private System.Windows.Forms.LinkLabel openExistingLabel; - private System.Windows.Forms.LinkLabel recentProjectLabel1; - private System.Windows.Forms.ColumnHeader columnOffset; - private System.Windows.Forms.ColumnHeader columnAddr; - private System.Windows.Forms.ColumnHeader columnBytes; - private System.Windows.Forms.ColumnHeader columnFlags; - private System.Windows.Forms.ColumnHeader columnAttr; - private System.Windows.Forms.ColumnHeader columnLabel; - private System.Windows.Forms.ColumnHeader columnOpcode; - private System.Windows.Forms.ColumnHeader columnOperand; - private System.Windows.Forms.ColumnHeader columnComment; - private System.Windows.Forms.ToolStripMenuItem undoToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem redoToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1; - private System.Windows.Forms.CheckBox symbolAutoCheckBox; - private System.Windows.Forms.GroupBox symbolsGroupBox; - private System.Windows.Forms.ListView symbolListView; - private System.Windows.Forms.ColumnHeader symbolValueColumnHeader; - private System.Windows.Forms.ColumnHeader symbolNameColumnHeader; - private System.Windows.Forms.ColumnHeader symbolTypeColumnHeader; - private System.Windows.Forms.ColumnHeader offsetColumnHeader; - private System.Windows.Forms.ColumnHeader addressColumnHeader; - private System.Windows.Forms.ColumnHeader typeColumnHeader; - private System.Windows.Forms.GroupBox referencesGroupBox; - private System.Windows.Forms.GroupBox infoGroupBox; - private System.Windows.Forms.CheckBox symbolAddressCheckBox; - private System.Windows.Forms.CheckBox symbolConstantCheckBox; - private System.Windows.Forms.CheckBox symbolPlatformCheckBox; - private System.Windows.Forms.CheckBox symbolProjectCheckBox; - private System.Windows.Forms.CheckBox symbolUserCheckBox; - private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2; - private System.Windows.Forms.ToolStripMenuItem selectAllToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem actionsToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem setAddressToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem overrideStatusFlagsToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem editLabelToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem editOperandToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem editCommentToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem editLongCommentToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem editNoteToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator actionsMenuSeparator1; - private System.Windows.Forms.ToolStripMenuItem hintAsCodeToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem hintAsDataToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem hintAsInlineDataToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem removeHintToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem dEBUGToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem toggleOwnerDrawToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3; - private System.Windows.Forms.ToolStripMenuItem editHeaderCommentToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem saveAsToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem newToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripMenuItem4; - private System.Windows.Forms.ToolStripMenuItem printToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripMenuItem5; - private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem; - private System.Windows.Forms.PictureBox logoPictureBox; - private System.Windows.Forms.Label versionLabel; - private System.Windows.Forms.Label sourceGenLabel; - private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem; - private System.Windows.Forms.LinkLabel recentProjectLabel2; - private System.Windows.Forms.SplitContainer rightPanelSplitter; - private System.Windows.Forms.GroupBox notesGroupBox; - private System.Windows.Forms.ListView notesListView; - private System.Windows.Forms.ColumnHeader notesOffsetColumnHeader; - private System.Windows.Forms.ColumnHeader notesNoteColumnHeader; - private System.Windows.Forms.TextBox infoTextBox; - private System.Windows.Forms.ToolStripMenuItem reanalyzeToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem projectPropertiesToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem settingsToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem showUndoRedoHistoryToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem showAnalysisTimersToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem assembleToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripMenuItem6; - private System.Windows.Forms.ToolStripMenuItem toggleCommentRulersToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem sourceGenTestsToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripMenuItem8; - private System.Windows.Forms.ToolStripSeparator toolStripMenuItem7; - private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem extensionScriptInfoToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem showAnalyzerOutputToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem contentsToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem hexDumpToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripMenuItem9; - private System.Windows.Forms.ToolStripMenuItem showHexDumpToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem recentProjectsToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem noRecentsToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripMenuItem10; - private System.Windows.Forms.Label recentProjectsLabel; - private System.Windows.Forms.ToolStripMenuItem useKeepAliveHackToolStripMenuItem; - private System.Windows.Forms.Label debugModeEnabledLabel; - private System.Windows.Forms.ToolStripButton navigateFwdToolStripButton; - private System.Windows.Forms.ToolStripSeparator toolStripSeparator2; - private System.Windows.Forms.ToolStripButton navigateBackToolStripButton; - private System.Windows.Forms.ToolStripMenuItem findToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem findNextToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem gotoToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem aSCIIChartToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripMenuItem11; - private System.Windows.Forms.ToolStripMenuItem toggleSingleBytesToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem editProjectSymbolToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem deleteNoteCommentToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem formatSplitAddressTableToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem toggleDataScanToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem formatAsWordToolStripMenuItem; - } -} - diff --git a/SourceGenWF/AppForms/ProjectView.cs b/SourceGenWF/AppForms/ProjectView.cs deleted file mode 100644 index 8253b7a..0000000 --- a/SourceGenWF/AppForms/ProjectView.cs +++ /dev/null @@ -1,4755 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Drawing; -using System.IO; -using System.Text; -using System.Web.Script.Serialization; -using System.Windows.Forms; - -using Asm65; -using CommonUtil; -using CommonWinForms; -using SourceGenWF.Sandbox; - -namespace SourceGenWF.AppForms { - /// - /// Main application form. This is the top-level application object. - /// - public partial class ProjectView : Form { - private const string LOGO_FILE_NAME = "Logo.png"; - private const string SETTINGS_FILE_NAME = "SourceGen-settings"; - - #region Project state - - // Currently open project, or null if none. - private DisasmProject mProject; - - // Pathname to 65xx data file. - private string mDataPathName; - - // Pathname of .dis65 file. This will be empty for a new project. - private string mProjectPathName; - - /// - /// Symbol subset, used to supply data to the symbol ListView. Initialized with - /// an empty symbol table. - /// - private SymbolTableSubset mSymbolSubset; - - /// - /// Current code list view selection. The length will match the DisplayList Count. - /// - /// A simple foreach through codeListView.SelectedIndices on a 500K-line data set - /// takes about 2.5 seconds on a fast Win10 x64 machine. Fortunately the control - /// notifies us of changes to the selection, so we can track it ourselves. - /// - private VirtualListViewSelection mCodeViewSelection = new VirtualListViewSelection(); - - /// - /// Data backing the codeListView. - /// - private DisplayList mDisplayList; - - #endregion Project state - - - /// - /// Returns the font currently in use by the code ListView. - /// - public Font CodeListViewFont { get { return codeListView.Font; } } - - /// - /// List of recently-opened projects. - /// - private List mRecentProjectPaths = new List(MAX_RECENT_PROJECTS); - private const int MAX_RECENT_PROJECTS = 6; - - /// - /// Menu items for the Actions and codeListView context menus. The menu items can - /// only be in one place at a time, so we move them around when the menu is opened. - /// - private ToolStripItem[] mActionsMenuItems; - - /// - /// Activity log generated by the code and data analyzers. Displayed in window. - /// - private DebugLog mGenerationLog; - - /// - /// Timing data generated during analysis. - /// - TaskTimer mReanalysisTimer = new TaskTimer(); - - /// - /// Base control to show when no project is open. - /// - private Control mNoProjectControl; - - /// - /// Base control to show when project is open. - /// - private Control mProjectControl; - - /// - /// Performance hack. - /// - private bool mRestoringSelection; - - /// - /// Stack for navigate forward/backward. - /// - private NavStack mNavStack = new NavStack(); - - /// - /// Output format configuration. - /// - private Formatter.FormatConfig mFormatterConfig; - - /// - /// Output format controller. - /// - /// This is shared with the DisplayList. - /// - private Formatter mOutputFormatter; - - /// - /// Pseudo-op names. - /// - /// This is shared with the DisplayList. - /// - private PseudoOp.PseudoOpNames mPseudoOpNames; - - /// - /// String we most recently searched for. - /// - private string mFindString = string.Empty; - - /// - /// Initial start point of most recent search. - /// - private int mFindStartIndex = -1; - - /// - /// Used to highlight the line that is the target of the selected line. - /// - private int mTargetHighlightIndex = -1; - - /// - /// Set to true if the last key hit was Ctrl+H. - /// - private bool mCtrlHSeen; - - /// - /// CPU definition used when the Formatter was created. If the CPU choice or - /// inclusion of undocumented opcodes changes, we need to wipe the formatter. - /// - private CpuDef mOutputFormatterCpuDef; - - /// - /// Instruction description object. Used for Info window. - /// - private OpDescription mOpDesc = OpDescription.GetOpDescription(null); - - /// - /// If true, plugins will execute in the main application's AppDomain instead of - /// the sandbox. - /// - private bool mUseMainAppDomainForPlugins = false; - - /// - /// Project hex dump viewer. This is just for viewing the project contents, so this - /// dialog is tied to the project. - /// - /// The general-purpose file dump windows are independent (currently untracked). - /// - private Tools.HexDumpViewer mHexDumpDialog; - - /// - /// Floating ASCII chart dialog. Not tied to the project. - /// - private Tools.AsciiChart mAsciiChartDialog; - - - #region Init and settings - - public ProjectView() { - InitializeComponent(); - - ScriptManager.UseKeepAliveHack = true; - -#if DEBUG - debugModeEnabledLabel.Visible = true; -#endif - } - - private void ProjectView_Load(object sender, EventArgs e) { - // It's *really* unstable right now, so actively discourage its use. - if (Type.GetType("Mono.Runtime") != null) { - MessageBox.Show(this, - "WARNING: SourceGen is currently unstable under Mono. " + - "Many features are badly broken. Proceed at your own risk.", - "Danger! Danger!", MessageBoxButtons.OK, MessageBoxIcon.Warning); - } - - if (RuntimeDataAccess.GetDirectory() == null) { - MessageBox.Show(this, Properties.Resources.RUNTIME_DIR_NOT_FOUND, - Properties.Resources.RUNTIME_DIR_NOT_FOUND_CAPTION, - MessageBoxButtons.OK, MessageBoxIcon.Error); - Application.Exit(); - return; - } - try { - PluginDllCache.PreparePluginDir(); - } catch (Exception ex) { - string pluginPath = PluginDllCache.GetPluginDirPath(); - if (pluginPath == null) { - pluginPath = ""; - } - string msg = string.Format(Properties.Resources.PLUGIN_DIR_FAIL, - pluginPath + ": " + ex.Message); - MessageBox.Show(this, msg, Properties.Resources.PLUGIN_DIR_FAIL_CAPTION, - MessageBoxButtons.OK, MessageBoxIcon.Error); - Application.Exit(); - return; - } - - logoPictureBox.ImageLocation = RuntimeDataAccess.GetPathName(LOGO_FILE_NAME); - versionLabel.Text = string.Format(Properties.Resources.VERSION_FMT, - Program.ProgramVersion); - - toolStripStatusLabel.Text = Properties.Resources.STATUS_READY; - - mProjectControl = this.codeListView; - mNoProjectControl = this.noProjectPanel; - - // Clone the menu structure from the designer. The same items are used for - // both Edit > Actions and the right-click context menu in codeListView. - mActionsMenuItems = new ToolStripItem[actionsToolStripMenuItem.DropDownItems.Count]; - for (int i = 0; i < actionsToolStripMenuItem.DropDownItems.Count; i++) { - mActionsMenuItems[i] = actionsToolStripMenuItem.DropDownItems[i]; - } - - // Load the settings from the file. Some things (like the symbol subset) need - // these. The general "apply settings" doesn't happen until a bit later, after - // the sub-windows have been initialized. - LoadAppSettings(); - - // Init primary ListView (virtual, ownerdraw) - InitCodeListView(); - - // Init Symbols ListView (virtual, non-ownerdraw) - mSymbolSubset = new SymbolTableSubset(new SymbolTable()); - symbolListView.SetDoubleBuffered(true); - InitSymbolListView(); - - // Init References ListView (non-virtual, non-ownerdraw) - referencesListView.SetDoubleBuffered(true); - - // Place the main window and apply the various settings. - SetAppWindowLocation(); - ApplyAppSettings(); - - UpdateActionMenu(); - UpdateMenuItemsAndTitle(); - UpdateRecentLinks(); - - ShowNoProject(); - - ProcessCommandLine(); - } - - private void ProcessCommandLine() { - string[] args = Environment.GetCommandLineArgs(); - if (args.Length == 2) { - DoOpenFile(Path.GetFullPath(args[1])); - } - } - - private void InitCodeListView() { - ListView cv = codeListView; - //cv.View = View.Details; - - // Create an empty place-holder for the context menu. - codeListView.ContextMenuStrip = new ContextMenuStrip(); - - // When the Actions or context menu are opened, all menu items get transferred over. - codeListView.ContextMenuStrip.Opening += codeListView_CmsOpening; - // When the context menu closes, move all the menu items back to the Actions menu, - // so that you can open it with Alt-A. - codeListView.ContextMenuStrip.Closed += ActionsMenuOpening; - - // Set default widths, in case we don't have a value for this in AppSettings. - CodeListColumnWidths widths = GetDefaultCodeListColumnWidths(); - SetCodeListHeaderWidths(widths); - - // This gets invoked when the user starts typing characters while the ListView - // has focus. Useful in a file viewer to find something by the first few - // characters. Less useful for us, though we could potentially use it as a - // shortcut to jump to an offset or label. - //codeListView.SearchForVirtualItem += - // new SearchForVirtualItemEventHandler(codeListView_SearchForVirtualItem); - - // Can't simply set this to "true", because the member is protected. - codeListView.SetDoubleBuffered(true); - } - - /// - /// Loads settings from the settings file into AppSettings.Global. Does not apply - /// them to the ProjectView. - /// - private void LoadAppSettings() { - AppSettings settings = AppSettings.Global; - - // Set some default settings for first-time use. The general rule is to set - // a default value of false, 0, or the empty string, so we only need to set - // values here when that isn't the case. The point at which the setting is - // retrieved is expected to do something reasonable by default. - - settings.SetBool(AppSettings.SYMWIN_SHOW_USER, true); - settings.SetBool(AppSettings.SYMWIN_SHOW_PROJECT, true); - settings.SetBool(AppSettings.SYMWIN_SHOW_PLATFORM, false); - settings.SetBool(AppSettings.SYMWIN_SHOW_AUTO, false); - settings.SetBool(AppSettings.SYMWIN_SHOW_CONST, true); - settings.SetBool(AppSettings.SYMWIN_SHOW_ADDR, true); - settings.SetBool(AppSettings.SYMWIN_SORT_ASCENDING, true); - settings.SetInt(AppSettings.SYMWIN_SORT_COL, (int)SymbolTableSubset.SortCol.Name); - - settings.SetBool(AppSettings.FMT_UPPER_OPERAND_A, true); - settings.SetBool(AppSettings.FMT_UPPER_OPERAND_S, true); - settings.SetBool(AppSettings.FMT_ADD_SPACE_FULL_COMMENT, true); - settings.SetString(AppSettings.FMT_OPCODE_SUFFIX_LONG, "l"); - settings.SetString(AppSettings.FMT_OPERAND_PREFIX_ABS, "a:"); - settings.SetString(AppSettings.FMT_OPERAND_PREFIX_LONG, "f:"); - - settings.SetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, true); - settings.SetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, true); - -#if DEBUG - settings.SetBool(AppSettings.DEBUG_MENU_ENABLED, true); -#else - settings.SetBool(AppSettings.DEBUG_MENU_ENABLED, false); -#endif - - // Load the settings file, and merge it into the globals. - string settingsDir = Path.GetDirectoryName(RuntimeDataAccess.GetDirectory()); - string settingsPath = Path.Combine(settingsDir, SETTINGS_FILE_NAME); - try { - string text = File.ReadAllText(settingsPath); - AppSettings fileSettings = AppSettings.Deserialize(text); - AppSettings.Global.MergeSettings(fileSettings); - Debug.WriteLine("Settings file loaded and merged"); - } catch (Exception ex) { - Debug.WriteLine("Unable to read settings file: " + ex.Message); - } - } - - /// - /// Saves AppSettings to a file. - /// - private void SaveAppSettings() { - if (!AppSettings.Global.Dirty) { - Debug.WriteLine("Settings not dirty, not saving"); - return; - } - - // Collect some window widths. Don't grab the main window size if we're - // maximized or minimized. - if (this.WindowState == FormWindowState.Normal || - this.WindowState == FormWindowState.Maximized) { - if (this.WindowState == FormWindowState.Normal) { - AppSettings.Global.SetInt(AppSettings.MAIN_WINDOW_LOC_X, this.Location.X); - AppSettings.Global.SetInt(AppSettings.MAIN_WINDOW_LOC_Y, this.Location.Y); - AppSettings.Global.SetInt(AppSettings.MAIN_WINDOW_WIDTH, this.Size.Width); - AppSettings.Global.SetInt(AppSettings.MAIN_WINDOW_HEIGHT, this.Size.Height); - } - AppSettings.Global.SetBool(AppSettings.MAIN_WINDOW_MAXIMIZED, - this.WindowState == FormWindowState.Maximized); - - // Horizontal splitters. We want to record the panel widths, rather than the - // splitter distance, because otherwise the right panel doesn't keep its size - // when the middle section changes during maximization. - AppSettings.Global.SetInt(AppSettings.MAIN_LEFT_PANEL_WIDTH, - mainSplitterLeft.SplitterDistance); - AppSettings.Global.SetInt(AppSettings.MAIN_RIGHT_PANEL_WIDTH, - this.Size.Width - (mainSplitterLeft.SplitterDistance + - mainSplitterRight.SplitterDistance)); - - // Vertical splitters. - AppSettings.Global.SetInt(AppSettings.MAIN_LEFT_SIDE_SPLITTER_DIST, - leftPanelSplitter.SplitterDistance); - AppSettings.Global.SetInt(AppSettings.MAIN_RIGHT_SIDE_SPLITTER_DIST, - rightPanelSplitter.SplitterDistance); - } else { - // VisualStudio appears to un-minimize its window before closing it. We - // could probably do that and grab the size values on the way out. - AppSettings.Global.SetBool(AppSettings.MAIN_WINDOW_MAXIMIZED, false); - } - - SerializeCodeListColumnWidths(); - SerializeReferencesColumnWidths(); - SerializeNotesColumnWidths(); - SerializeSymbolColumnWidths(); - - string settingsDir = Path.GetDirectoryName(RuntimeDataAccess.GetDirectory()); - string settingsPath = Path.Combine(settingsDir, SETTINGS_FILE_NAME); - try { - string cereal = AppSettings.Global.Serialize(); - File.WriteAllText(settingsPath, cereal); - AppSettings.Global.Dirty = false; - Debug.WriteLine("Saved settings (" + settingsPath + ")"); - } catch (Exception ex) { - Debug.WriteLine("Failed to save settings: " + ex.Message); - } - } - - /// - /// Replaces the contents of the global settings object with the new settings, - /// then applies them to the ProjectView. - /// - /// - public void SetAppSettings(AppSettings settings) { - AppSettings.Global.ReplaceSettings(settings); - ApplyAppSettings(); - - // We get called whenever Apply or OK is hit in the settings editor, so it's - // a pretty good time to save the settings out. - SaveAppSettings(); - } - - /// - /// Sets the app window's location and size. - /// - private void SetAppWindowLocation() { - const int DEFAULT_WIDTH = 1280; - const int DEFAULT_HEIGHT = 720; - const int DEFAULT_SPLIT = 250; - - AppSettings settings = AppSettings.Global; - - // Main window size. - this.Size = new Size( - settings.GetInt(AppSettings.MAIN_WINDOW_WIDTH, DEFAULT_WIDTH), - settings.GetInt(AppSettings.MAIN_WINDOW_HEIGHT, DEFAULT_HEIGHT)); - // Left splitter width is distance from left edge of window. - mainSplitterLeft.SplitterDistance = - settings.GetInt(AppSettings.MAIN_LEFT_PANEL_WIDTH, DEFAULT_SPLIT); - // Right splitter distance is distance from right edge of left splitter, i.e. - // the width of the middle section, *not* the width of the right panel. - // --> splitter_distance = main_width - (left_width + right_width) - int rightSplitWidth = settings.GetInt(AppSettings.MAIN_RIGHT_PANEL_WIDTH, - DEFAULT_SPLIT); - mainSplitterRight.SplitterDistance = - this.Size.Width - (mainSplitterLeft.SplitterDistance + rightSplitWidth); - - // Vertical splits, e.g. References vs. Notes. - leftPanelSplitter.SplitterDistance = - settings.GetInt(AppSettings.MAIN_LEFT_SIDE_SPLITTER_DIST, 350); - rightPanelSplitter.SplitterDistance = - settings.GetInt(AppSettings.MAIN_RIGHT_SIDE_SPLITTER_DIST, 400); - - // Get working area of screen the system is going to display us on. Note that, - // with multiple displays, the X/Y coordinates for the display's upper left may - // be negative. - Screen myScreen = Screen.FromControl(this); - Rectangle scrArea = myScreen.WorkingArea; - - // Upper-left corner of our window that positions us in the center. - Point centered = new Point(scrArea.X + (scrArea.Width - this.Size.Width) / 2, - scrArea.Y + (scrArea.Height - this.Size.Height) / 2); - - // Get requested location (if any). - Point loc = new Point(); - loc.X = settings.GetInt(AppSettings.MAIN_WINDOW_LOC_X, int.MinValue); - loc.Y = settings.GetInt(AppSettings.MAIN_WINDOW_LOC_Y, int.MinValue); - if (loc.X == int.MinValue || loc.Y == int.MinValue) { - // No setting exists; center it on the screen. - loc = centered; - } else { - // See if this location makes sense. As a quick sanity check we test to see - // if the top-center part of the window is visible. If not, it may not be - // possible to reposition the window because the title bar won't be visible. - // - // Win10 seems to be okay with dragging a window below the icon bar at the - // bottom, which makes it hard to get at. We offset the Y position by a few - // pixels to give us some wiggle room. - Point checkPoint = new Point(loc.X + this.Size.Width / 2, loc.Y + 8); - if (!scrArea.Contains(checkPoint)) { - Debug.WriteLine("Titlebar " + checkPoint + " not inside " + scrArea); - loc = centered; - } - } - - this.Location = loc; - - if (settings.GetBool(AppSettings.MAIN_WINDOW_MAXIMIZED, false)) { - this.WindowState = FormWindowState.Maximized; - } - - // Configure column widths. - string widthStr = settings.GetString(AppSettings.CDLV_COL_WIDTHS, null); - if (!string.IsNullOrEmpty(widthStr)) { - CodeListColumnWidths widths = CodeListColumnWidths.Deserialize(widthStr); - if (widths != null) { - SetCodeListHeaderWidths(widths); - } - } - DeserializeReferencesColumnWidths(); - DeserializeNotesColumnWidths(); - DeserializeSymbolColumnWidths(); - } - - /// - /// Applies "actionable" settings to the ProjectView, pulling them out of the global - /// settings object. If a project is open, refreshes the display list and all sub-windows. - /// - private void ApplyAppSettings() { - Debug.WriteLine("ApplyAppSettings..."); - AppSettings settings = AppSettings.Global; - - // Set up the formatter. - mFormatterConfig = new Formatter.FormatConfig(); - AsmGen.GenCommon.ConfigureFormatterFromSettings(AppSettings.Global, - ref mFormatterConfig); - mFormatterConfig.mEndOfLineCommentDelimiter = ";"; - mFormatterConfig.mFullLineCommentDelimiterBase = ";"; - mFormatterConfig.mBoxLineCommentDelimiter = string.Empty; - mFormatterConfig.mAllowHighAsciiCharConst = true; - mOutputFormatter = new Formatter(mFormatterConfig); - mOutputFormatterCpuDef = null; - - // Set pseudo-op names. Entries aren't allowed to be blank, so we start with the - // default values and merge in whatever the user has configured. - mPseudoOpNames = PseudoOp.sDefaultPseudoOpNames.GetCopy(); - string pseudoCereal = settings.GetString(AppSettings.FMT_PSEUDO_OP_NAMES, null); - if (!string.IsNullOrEmpty(pseudoCereal)) { - PseudoOp.PseudoOpNames deser = PseudoOp.PseudoOpNames.Deserialize(pseudoCereal); - if (deser != null) { - mPseudoOpNames.Merge(deser); - } - } - - // Configure the Symbols window. - symbolUserCheckBox.Checked = - settings.GetBool(AppSettings.SYMWIN_SHOW_USER, false); - symbolAutoCheckBox.Checked = - settings.GetBool(AppSettings.SYMWIN_SHOW_AUTO, false); - symbolProjectCheckBox.Checked = - settings.GetBool(AppSettings.SYMWIN_SHOW_PROJECT, false); - symbolPlatformCheckBox.Checked = - settings.GetBool(AppSettings.SYMWIN_SHOW_PLATFORM, false); - symbolConstantCheckBox.Checked = - settings.GetBool(AppSettings.SYMWIN_SHOW_CONST, false); - symbolAddressCheckBox.Checked = - settings.GetBool(AppSettings.SYMWIN_SHOW_ADDR, false); - - // Set the code list view font. - string fontStr = settings.GetString(AppSettings.CDLV_FONT, null); - if (!string.IsNullOrEmpty(fontStr)) { - FontConverter cvt = new FontConverter(); - try { - Font font = cvt.ConvertFromInvariantString(fontStr) as Font; - codeListView.Font = font; - Debug.WriteLine("Set font to " + font.ToString()); - } catch (Exception ex) { - Debug.WriteLine("Font convert failed: " + ex.Message); - } - } - - // Unpack the recent-project list. - UnpackRecentProjectList(); - - // Enable the DEBUG menu if configured. - bool showDebugMenu = AppSettings.Global.GetBool(AppSettings.DEBUG_MENU_ENABLED, false); - if (dEBUGToolStripMenuItem.Visible != showDebugMenu) { - dEBUGToolStripMenuItem.Visible = showDebugMenu; - mainMenuStrip.Refresh(); - } - - // Finally, update the display list with all the fancy settings. - if (mDisplayList != null) { - // Regenerate the display list with the latest formatter config and - // pseudo-op definition. (These are set as part of the refresh.) - UndoableChange uc = - UndoableChange.CreateDummyChange(UndoableChange.ReanalysisScope.DisplayOnly); - ApplyChanges(new ChangeSet(uc), false); - } - } - - // Make sure we pick up changes to the window size or position. We don't catch - // size-chage events for the left/right splitter widths because that should be picked - // up by events on sub-windows. - private void ProjectView_SizeOrLocChanged(object sender, EventArgs e) { - AppSettings.Global.Dirty = true; - } - - // This handles the splitters in the side panels, e.g. between References and Notes. - private void SidePanelSplitter_SplitterMoved(object sender, SplitterEventArgs e) { - AppSettings.Global.Dirty = true; - } - - public void ShowProject() { - mProjectControl.Show(); - mNoProjectControl.Hide(); - - codeListView.Focus(); - saveToolStripMenuItem.Enabled = true; - saveToolStripButton.Enabled = true; - saveAsToolStripMenuItem.Enabled = true; - closeToolStripMenuItem.Enabled = true; - assembleToolStripMenuItem.Enabled = true; - printToolStripMenuItem.Enabled = true; - copyToolStripMenuItem.Enabled = true; - copyToolStripButton.Enabled = true; - selectAllToolStripMenuItem.Enabled = true; - findToolStripMenuItem.Enabled = true; - findNextToolStripMenuItem.Enabled = true; - gotoToolStripMenuItem.Enabled = true; - editHeaderCommentToolStripMenuItem.Enabled = true; - projectPropertiesToolStripMenuItem.Enabled = true; - toggleDataScanToolStripMenuItem.Enabled = true; - - showUndoRedoHistoryToolStripMenuItem.Enabled = true; - showAnalysisTimersToolStripMenuItem.Enabled = true; - showAnalyzerOutputToolStripMenuItem.Enabled = true; - toggleOwnerDrawToolStripMenuItem.Enabled = true; - reanalyzeToolStripMenuItem.Enabled = true; - toggleCommentRulersToolStripMenuItem.Enabled = true; - extensionScriptInfoToolStripMenuItem.Enabled = true; - - mNavStack.Clear(); - UpdateMenuItemsAndTitle(); - } - - public void ShowNoProject() { - mProjectControl.Hide(); - mNoProjectControl.Show(); - - saveToolStripMenuItem.Enabled = false; - saveToolStripButton.Enabled = false; - saveAsToolStripMenuItem.Enabled = false; - closeToolStripMenuItem.Enabled = false; - assembleToolStripMenuItem.Enabled = false; - printToolStripMenuItem.Enabled = false; - copyToolStripMenuItem.Enabled = false; - copyToolStripButton.Enabled = false; - selectAllToolStripMenuItem.Enabled = false; - findToolStripMenuItem.Enabled = false; - findNextToolStripMenuItem.Enabled = false; - gotoToolStripMenuItem.Enabled = false; - editHeaderCommentToolStripMenuItem.Enabled = false; - projectPropertiesToolStripMenuItem.Enabled = false; - toggleDataScanToolStripMenuItem.Enabled = false; - - showUndoRedoHistoryToolStripMenuItem.Enabled = false; - showAnalysisTimersToolStripMenuItem.Enabled = false; - showAnalyzerOutputToolStripMenuItem.Enabled = false; - toggleOwnerDrawToolStripMenuItem.Enabled = false; - reanalyzeToolStripMenuItem.Enabled = false; - toggleCommentRulersToolStripMenuItem.Enabled = false; - extensionScriptInfoToolStripMenuItem.Enabled = false; - - UpdateMenuItemsAndTitle(); - } - - private void UnpackRecentProjectList() { - mRecentProjectPaths.Clear(); - - string cereal = AppSettings.Global.GetString( - AppSettings.PRVW_RECENT_PROJECT_LIST, null); - if (string.IsNullOrEmpty(cereal)) { - return; - } - - try { - JavaScriptSerializer ser = new JavaScriptSerializer(); - mRecentProjectPaths = ser.Deserialize>(cereal); - } catch (Exception ex) { - Debug.WriteLine("Failed deserializing recent projects: " + ex.Message); - return; - } - } - - /// - /// Ensures that the named project is at the top of the list. If it's elsewhere - /// in the list, move it to the top. Excess items are removed. - /// - /// - private void UpdateRecentProjectList(string projectPath) { - if (string.IsNullOrEmpty(projectPath)) { - // This can happen if you create a new project, then close the window - // without having saved it. - return; - } - int index = mRecentProjectPaths.IndexOf(projectPath); - if (index == 0) { - // Already in the list, nothing changes. No need to update anything else. - return; - } - if (index > 0) { - mRecentProjectPaths.RemoveAt(index); - } - mRecentProjectPaths.Insert(0, projectPath); - - // Trim the list to the max allowed. - while (mRecentProjectPaths.Count > MAX_RECENT_PROJECTS) { - Debug.WriteLine("Recent projects: dropping " + - mRecentProjectPaths[MAX_RECENT_PROJECTS]); - mRecentProjectPaths.RemoveAt(MAX_RECENT_PROJECTS); - } - - // Store updated list in app settings. JSON-in-JSON is ugly and inefficient, - // but it'll do for now. - JavaScriptSerializer ser = new JavaScriptSerializer(); - string cereal = ser.Serialize(mRecentProjectPaths); - AppSettings.Global.SetString(AppSettings.PRVW_RECENT_PROJECT_LIST, cereal); - - UpdateRecentLinks(); - } - - /// - /// Updates the links on the no-project control. - /// - private void UpdateRecentLinks() { - if (mRecentProjectPaths.Count >= 1) { - recentProjectLabel1.Visible = true; - recentProjectLabel1.Text = string.Format(Properties.Resources.RECENT_PROJECT_LINK, - 1, Path.GetFileName(mRecentProjectPaths[0])); - } else { - recentProjectLabel1.Visible = false; - } - if (mRecentProjectPaths.Count >= 2) { - recentProjectLabel2.Visible = true; - recentProjectLabel2.Text = string.Format(Properties.Resources.RECENT_PROJECT_LINK, - 2, Path.GetFileName(mRecentProjectPaths[1])); - } else { - recentProjectLabel2.Visible = false; - } - } - - private void recentProjectsToolStripMenuItem_DropDownOpening(object sender, EventArgs e) { - ToolStripItemCollection recents = recentProjectsToolStripMenuItem.DropDownItems; - - recents.Clear(); - if (mRecentProjectPaths.Count == 0) { - recents.Add(noRecentsToolStripMenuItem); - } else { - for (int i = 0; i < mRecentProjectPaths.Count; i++) { - string pathName = mRecentProjectPaths[i]; - string menuName = string.Format("{0}: {1}", i + 1, - /*Path.GetFileName(*/ pathName /*)*/); - recents.Add(new ToolStripMenuItem(menuName, null, (sendr, arg) => { - if (DoClose()) { - DoOpenFile(pathName); - } - })); - } - } - } - - #endregion Init and settings - - - #region Project management - - private bool PrepareNewProject(string dataPathName, Setup.SystemDef sysDef) { - DisasmProject proj = new DisasmProject(); - mDataPathName = dataPathName; - mProjectPathName = string.Empty; - byte[] fileData = null; - try { - fileData = LoadDataFile(dataPathName); - } catch (Exception ex) { - Debug.WriteLine("PrepareNewProject exception: " + ex); - string message = Properties.Resources.OPEN_DATA_FAIL_CAPTION; - string caption = Properties.Resources.OPEN_DATA_FAIL_MESSAGE + ": " + ex.Message; - MessageBox.Show(this, caption, message, MessageBoxButtons.OK, - MessageBoxIcon.Error); - return false; - } - proj.UseMainAppDomainForPlugins = mUseMainAppDomainForPlugins; - proj.Initialize(fileData.Length); - proj.PrepForNew(fileData, Path.GetFileName(dataPathName)); - - proj.LongComments.Add(DisplayList.Line.HEADER_COMMENT_OFFSET, - new MultiLineComment("6502bench SourceGen v" + Program.ProgramVersion)); - - // The system definition provides a set of defaults that can be overridden. - // We pull everything of interest out and then discard the object. - proj.ApplySystemDef(sysDef); - - mProject = proj; - - return true; - } - - private void FinishPrep() { - string messages = mProject.LoadExternalFiles(); - if (messages.Length != 0) { - // ProjectLoadIssues isn't quite the right dialog, but it'll do. - ProjectLoadIssues dlg = new ProjectLoadIssues(messages, - ProjectLoadIssues.Buttons.Continue); - dlg.ShowDialog(); - dlg.Dispose(); - } - - mDisplayList = new DisplayList(mProject, mOutputFormatter, mPseudoOpNames); - - // Prep the symbol table subset object. Replace the old one with a new one. - mSymbolSubset = new SymbolTableSubset(mProject.SymbolTable); - - RefreshProject(UndoableChange.ReanalysisScope.CodeAndData); - ShowProject(); - InvalidateControls(null); - - // Want to do this after ShowProject() or we see a weird glitch. - UpdateRecentProjectList(mProjectPathName); - } - - /// - /// Loads the data file, reading it entirely into memory. - /// - /// All errors are reported as exceptions. - /// - /// Full pathname. - /// Data file contents. - private byte[] LoadDataFile(string dataFileName) { - byte[] fileData; - - using (FileStream fs = File.Open(dataFileName, FileMode.Open, FileAccess.Read)) { - // Check length; should have been caught earlier. - if (fs.Length > DisasmProject.MAX_DATA_FILE_SIZE) { - throw new InvalidDataException( - string.Format(Properties.Resources.OPEN_DATA_TOO_LARGE, - fs.Length / 1024, DisasmProject.MAX_DATA_FILE_SIZE / 1024)); - } else if (fs.Length == 0) { - throw new InvalidDataException(Properties.Resources.OPEN_DATA_EMPTY); - } - fileData = new byte[fs.Length]; - int actual = fs.Read(fileData, 0, (int)fs.Length); - if (actual != fs.Length) { - // Not expected -- should be able to read the entire file in one shot. - throw new Exception(Properties.Resources.OPEN_DATA_PARTIAL_READ); - } - } - - return fileData; - } - - /// - /// Applies the changes to the project, adds them to the undo stack, and updates - /// the display. - /// - /// Set of changes to apply. - private void ApplyUndoableChanges(ChangeSet cs) { - if (cs.Count == 0) { - Debug.WriteLine("ApplyUndoableChanges: change set is empty"); - } - ApplyChanges(cs, false); - mProject.PushChangeSet(cs); - UpdateMenuItemsAndTitle(); - - // If the debug dialog is visible, update it. - if (mShowUndoRedoHistoryDialog != null) { - mShowUndoRedoHistoryDialog.BodyText = mProject.DebugGetUndoRedoHistory(); - } - } - - /// - /// Applies the changes to the project, and updates the display. - /// - /// This is called by the undo/redo commands. Don't call this directly from the - /// various UI-driven functions, as this does not add the change to the undo stack. - /// - /// Set of changes to apply. - /// If set, undo the changes instead. - private void ApplyChanges(ChangeSet cs, bool backward) { - mReanalysisTimer.Clear(); - mReanalysisTimer.StartTask("ProjectView.ApplyChanges()"); - - mReanalysisTimer.StartTask("Save selection"); - int topItem = codeListView.TopItem.Index; - int topOffset = mDisplayList[topItem].FileOffset; - DisplayList.SavedSelection savedSel = DisplayList.SavedSelection.Generate( - mDisplayList, mCodeViewSelection, topOffset); - //savedSel.DebugDump(); - mReanalysisTimer.EndTask("Save selection"); - - mReanalysisTimer.StartTask("Apply changes"); - UndoableChange.ReanalysisScope needReanalysis = mProject.ApplyChanges(cs, backward, - out RangeSet affectedOffsets); - mReanalysisTimer.EndTask("Apply changes"); - - string refreshTaskStr = "Refresh w/reanalysis=" + needReanalysis; - mReanalysisTimer.StartTask(refreshTaskStr); - if (needReanalysis != UndoableChange.ReanalysisScope.None) { - Debug.WriteLine("Refreshing project (" + needReanalysis + ")"); - RefreshProject(needReanalysis); - } else { - Debug.WriteLine("Refreshing " + affectedOffsets.Count + " offsets"); - RefreshCodeListViewEntries(affectedOffsets); - mProject.Validate(); // shouldn't matter w/o reanalysis, but do it anyway - } - mReanalysisTimer.EndTask(refreshTaskStr); - - VirtualListViewSelection newSel = savedSel.Restore(mDisplayList, out int topIndex); - //newSel.DebugDump(); - - // Refresh the various windows, and restore the selection. - mReanalysisTimer.StartTask("Invalidate controls"); - InvalidateControls(newSel); - mReanalysisTimer.EndTask("Invalidate controls"); - - // This apparently has to be done after the EndUpdate, and inside try/catch. - // See https://stackoverflow.com/questions/626315/ for notes. - try { - Debug.WriteLine("Setting TopItem to index=" + topIndex); - codeListView.TopItem = codeListView.Items[topIndex]; - } catch (NullReferenceException) { - Debug.WriteLine("Caught an NRE from TopItem"); - } - - mReanalysisTimer.EndTask("ProjectView.ApplyChanges()"); - - //mReanalysisTimer.DumpTimes("ProjectView timers:", mGenerationLog); - if (mShowAnalysisTimersDialog != null) { - string timerStr = mReanalysisTimer.DumpToString("ProjectView timers:"); - mShowAnalysisTimersDialog.BodyText = timerStr; - } - - // Lines may have moved around. Update the selection highlight. It's important - // we do it here, and not down in DoRefreshProject(), because at that point the - // ListView's selection index could be referencing a line off the end. - UpdateSelectionHighlight(); - } - - /// - /// Refreshes the project after something of substance has changed. Some - /// re-analysis will be done, followed by a complete rebuild of the DisplayList. - /// - /// Indicates whether reanalysis is required, and - /// what level. - private void RefreshProject(UndoableChange.ReanalysisScope reanalysisRequired) { - Debug.Assert(reanalysisRequired != UndoableChange.ReanalysisScope.None); - - // NOTE: my goal is to arrange things so that reanalysis (data-only, and ideally - // code+data) takes less than 100ms. With that response time there's no need for - // background processing and progress bars. Since we need to do data-only - // reanalysis after many common operations, the program becomes unpleasant to - // use if we miss this goal, and progress bars won't make it less so. - - // Changing the CPU type or whether undocumented instructions are supported - // invalidates the Formatter's mnemonic cache. We can change these values - // through undo/redo, so we need to check it here. - if (mOutputFormatterCpuDef != mProject.CpuDef) { // reference equality is fine - Debug.WriteLine("CpuDef has changed, resetting formatter (now " + - mProject.CpuDef + ")"); - mOutputFormatter = new Formatter(mFormatterConfig); - mDisplayList.SetFormatter(mOutputFormatter); - mDisplayList.SetPseudoOpNames(mPseudoOpNames); - mOutputFormatterCpuDef = mProject.CpuDef; - } - - if (mDisplayList.Count > 200000) { - string prevStatus = toolStripStatusLabel.Text; - - // The Windows stuff can take 50-100ms, potentially longer than the actual - // work, so don't bother unless the file is very large. - try { - mReanalysisTimer.StartTask("Do Windows stuff"); - Application.UseWaitCursor = true; - Cursor.Current = Cursors.WaitCursor; - toolStripStatusLabel.Text = Properties.Resources.STATUS_RECALCULATING; - Refresh(); // redraw status label - mReanalysisTimer.EndTask("Do Windows stuff"); - - DoRefreshProject(reanalysisRequired); - } finally { - Application.UseWaitCursor = false; - toolStripStatusLabel.Text = prevStatus; - } - } else { - DoRefreshProject(reanalysisRequired); - } - - if (FormatDescriptor.DebugCreateCount != 0) { - Debug.WriteLine("FormatDescriptor total=" + FormatDescriptor.DebugCreateCount + - " prefab=" + FormatDescriptor.DebugPrefabCount + " (" + - (FormatDescriptor.DebugPrefabCount * 100) / FormatDescriptor.DebugCreateCount + - "%)"); - } - } - - /// - /// Updates all of the specified ListView entries. This is called after minor changes, - /// such as editing a comment or renaming a label, that can be handled by regenerating - /// selected parts of the DisplayList. - /// - /// - private void RefreshCodeListViewEntries(RangeSet offsetSet) { - IEnumerator iter = offsetSet.RangeListIterator; - while (iter.MoveNext()) { - RangeSet.Range range = iter.Current; - mDisplayList.GenerateRange(range.Low, range.High); - } - } - - private void DoRefreshProject(UndoableChange.ReanalysisScope reanalysisRequired) { - if (reanalysisRequired != UndoableChange.ReanalysisScope.DisplayOnly) { - mGenerationLog = new CommonUtil.DebugLog(); - mGenerationLog.SetMinPriority(CommonUtil.DebugLog.Priority.Debug); - mGenerationLog.SetShowRelTime(true); - - mReanalysisTimer.StartTask("Call DisasmProject.Analyze()"); - mProject.Analyze(reanalysisRequired, mGenerationLog, mReanalysisTimer); - mReanalysisTimer.EndTask("Call DisasmProject.Analyze()"); - } - - if (mGenerationLog != null) { - //mReanalysisTimer.StartTask("Save _log"); - //mGenerationLog.WriteToFile(@"C:\Src\WorkBench\SourceGen\TestData\_log.txt"); - //mReanalysisTimer.EndTask("Save _log"); - - if (mShowAnalyzerOutputDialog != null) { - mShowAnalyzerOutputDialog.BodyText = mGenerationLog.WriteToString(); - } - } - - mReanalysisTimer.StartTask("Generate DisplayList"); - mDisplayList.GenerateAll(); - mReanalysisTimer.EndTask("Generate DisplayList"); - } - - #endregion Project management - - - #region Main window UI event handlers - - /// - /// Invalidates and forces an update on our various windows. - /// - private void InvalidateControls(VirtualListViewSelection newSel) { - codeListView.BeginUpdate(); - ClearCodeListViewCache(); - if (mDisplayList != null) { - codeListView.VirtualListSize = mDisplayList.Count; - } - - mReanalysisTimer.StartTask("Restore selection"); - mRestoringSelection = true; - if (newSel != null) { - RestoreSelection(newSel); // want to do this between Begin/EndUpdate - } else if (mDisplayList != null) { - // No selection to restore. This should only happen for the initial - // render, when nothing is yet selected. - // - // Set the length on the code view. - mCodeViewSelection.SetLength(mDisplayList.Count); - } else { - // Just closed the project, nothing to do at all. - } - - mRestoringSelection = false; - mReanalysisTimer.EndTask("Restore selection"); - - UpdateActionMenu(); - codeListView.EndUpdate(); - - InvalidateSymbolListView(); - InvalidateNotesListView(); - UpdateReferenceView(); - UpdateInfoView(); - } - - /// - /// Updates menu item enable status; necessary because that determines whether the - /// associated keyboard shortcuts are active. - /// - /// Updates the main form title to show project name and modification status. - /// - /// This does not handle items that only toggle enabledness when a project is opened - /// or closed. - /// - private void UpdateMenuItemsAndTitle() { - undoToolStripMenuItem.Enabled = (mProject != null && mProject.CanUndo); - redoToolStripMenuItem.Enabled = (mProject != null && mProject.CanRedo); - - navigateBackToolStripButton.Enabled = (mProject != null && mNavStack.HasBackward); - navigateFwdToolStripButton.Enabled = (mProject != null && mNavStack.HasForward); - - // Update main window title. - StringBuilder sb = new StringBuilder(); - sb.Append(Properties.Resources.TITLE_BASE); - if (mProject != null) { - sb.Append(" - "); - if (string.IsNullOrEmpty(mProjectPathName)) { - sb.Append(Properties.Resources.TITLE_NEW_PROJECT); - } else { - sb.Append(Path.GetFileName(mProjectPathName)); - } - - if (mProject.IsDirty) { - sb.Append(" "); - sb.Append(Properties.Resources.TITLE_MODIFIED); - } - } - Text = sb.ToString(); - } - - /// - /// Restores the ListView selection by applying a diff between the old and - /// new selection bitmaps. - /// - /// The virtual list view doesn't change the selection when we rebuild the - /// list. It would be expensive to set all the bits, so we just update the - /// entries that changed. - /// - /// Before returning, mCodeViewSelection is replaced with curSel. - /// - /// Selection bits for the current display list. - private void RestoreSelection(VirtualListViewSelection curSel) { - Debug.Assert(curSel != null); - - // We have to replace mCodeViewSelection immediately, because changing - // the selection will cause ItemSelectionChanged events to fire, invoking - // callbacks that expect the new selection object. Things will explode if - // the older list was shorter. - VirtualListViewSelection prevSel = mCodeViewSelection; - mCodeViewSelection = curSel; - - // Set everything that has changed between the two sets. - int debugNumChanged = 0; - int count = Math.Min(prevSel.Length, curSel.Length); - int i; - for (i = 0; i < count; i++) { - if (prevSel[i] != curSel[i]) { - codeListView.Items[i].Selected = curSel[i]; - debugNumChanged++; - } - } - // Set everything that wasn't there before. New entries default to unselected, - // so we only need to do this if the new value is "true". - for (; i < curSel.Length; i++) { - // An ItemSelectionChanged event will fire that will cause curSel[i] to - // be assigned. This is fine. - if (curSel[i]) { - codeListView.Items[i].Selected = curSel[i]; - debugNumChanged++; - } - } - - Debug.WriteLine("RestoreSelection: changed " + debugNumChanged + - " of " + curSel.Length + " lines"); - } - - // This gets the key events for all controls associated with the main form, - // regardless of which has focus, making it useful for keyboard shortcuts. - // Return true to indicate that we've handled the key. - protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { - // Handle the Ctrl+H sequence. - if (mCtrlHSeen) { - if (keyData == (Keys.Control | Keys.C)) { - if (hintAsCodeToolStripMenuItem.Enabled) { - MarkAsCode_Click(null, null); - } - } else if (keyData == (Keys.Control | Keys.D)) { - if (hintAsDataToolStripMenuItem.Enabled) { - MarkAsData_Click(null, null); - } - } else if (keyData == (Keys.Control | Keys.I)) { - if (hintAsInlineDataToolStripMenuItem.Enabled) { - MarkAsInlineData_Click(null, null); - } - } else if (keyData == (Keys.Control | Keys.R)) { - if (removeHintToolStripMenuItem.Enabled) { - MarkAsNoHint_Click(null, null); - } - } else { - System.Media.SystemSounds.Beep.Play(); - } - mCtrlHSeen = false; - toolStripStatusLabel.Text = Properties.Resources.STATUS_READY; - return true; - } else if (keyData == (Keys.Control | Keys.H)) { - mCtrlHSeen = true; - toolStripStatusLabel.Text = Properties.Resources.STATUS_CTRL_H_HIT; - return true; - } - - // Ctrl+Shift+Z is an alias for Redo (Ctrl+Y). - if (keyData == (Keys.Control | Keys.Shift | Keys.Z)) { - if (redoToolStripMenuItem.Enabled) { - redoToolStripMenuItem_Click(null, null); - } - return true; - } - - // Navigation keys. Alt+left/right is intuitive key binding used by Eclipse, - // Ctrl+[shift]+minus is weird Visual Studio binding. - if (keyData == (Keys.Alt | Keys.Left) || - keyData == (Keys.Control | Keys.OemMinus)) { - if (navigateBackToolStripButton.Enabled) { - navigateBackToolStripButton_Click(null, null); - } - return true; - } - if (keyData == (Keys.Alt | Keys.Right) || - keyData == (Keys.Control | Keys.Shift | Keys.OemMinus)) { - if (navigateFwdToolStripButton.Enabled) { - navigateFwdToolStripButton_Click(null, null); - } - return true; - } - - return base.ProcessCmdKey(ref msg, keyData); - } - - private void navigateBackToolStripButton_Click(object sender, EventArgs e) { - if (!mNavStack.HasBackward) { - // toolbar button should have been disabled - return; - } - int backOff = mNavStack.Pop(); - UpdateMenuItemsAndTitle(); - Debug.WriteLine("Nav back: +" + backOff.ToString("x6")); - GoToOffset(backOff, false, false); - } - - private void navigateFwdToolStripButton_Click(object sender, EventArgs e) { - if (!mNavStack.HasForward) { - // toolbar button should have been disabled - return; - } - int fwdOff = mNavStack.PushPrevious(); - UpdateMenuItemsAndTitle(); - Debug.WriteLine("Nav fwd: +" + fwdOff.ToString("x6")); - GoToOffset(fwdOff, false, false); - } - - /// - /// Determines whether any part of the specified offset is currently visible in the - /// code list view. - /// - private bool IsOffsetVisible(int offset) { - int firstLineIndex = mDisplayList.FindLineIndexByOffset(offset); - int lastLineIndex = firstLineIndex + 1; - while (lastLineIndex < mDisplayList.Count && - mDisplayList[lastLineIndex].FileOffset == offset) { - lastLineIndex++; - } - lastLineIndex--; - //Debug.WriteLine("Check vis: first=" + firstLineIndex + " last=" + lastLineIndex); - return codeListView.IsItemVisible(codeListView.Items[firstLineIndex]) || - codeListView.IsItemVisible(codeListView.Items[lastLineIndex]); - } - - // File > New (Ctrl+N) - private void newToolStripMenuItem_Click(object sender, EventArgs e) { - DoNew(); - } - private void newToolStripButton_Click(object sender, EventArgs e) { - newToolStripMenuItem_Click(sender, e); - } - - private void newFileLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { - DoNew(); - } - - private void DoNew() { - if (!DoClose()) { - return; - } - - Setup.NewProject dlg = new Setup.NewProject(); - dlg.ShowDialog(); - if (dlg.DialogResult == DialogResult.OK) { - bool ok = PrepareNewProject(Path.GetFullPath(dlg.DataFileName), dlg.SystemDef); - if (ok) { - FinishPrep(); - } - } - - dlg.Dispose(); - } - - // File > Open (Ctrl+O) - private void openToolStripMenuItem_Click(object sender, EventArgs e) { - DoOpen(); - } - private void openToolStripButton_Click(object sender, EventArgs e) { - openToolStripMenuItem_Click(sender, e); - } - - private void recentProjectLabel1_LinkClicked(object sender, - LinkLabelLinkClickedEventArgs e) { - Debug.Assert(mRecentProjectPaths.Count > 0); - if (DoClose()) { - DoOpenFile(mRecentProjectPaths[0]); - } - } - - private void recentProjectLabel2_LinkClicked(object sender, - LinkLabelLinkClickedEventArgs e) { - Debug.Assert(mRecentProjectPaths.Count > 1); - if (DoClose()) { - DoOpenFile(mRecentProjectPaths[1]); - } - } - - private void openExistingLabel_LinkClicked(object sender, - LinkLabelLinkClickedEventArgs e) { - DoOpen(); - } - - /// - /// Handles opening an existing project by letting the user select the project file. - /// - private void DoOpen() { - if (!DoClose()) { - return; - } - - OpenFileDialog fileDlg = new OpenFileDialog() { - Filter = ProjectFile.FILENAME_FILTER + "|" + Properties.Resources.FILE_FILTER_ALL, - FilterIndex = 1 - }; - if (fileDlg.ShowDialog() != DialogResult.OK) { - return; - } - - string projPathName = Path.GetFullPath(fileDlg.FileName); - DoOpenFile(projPathName); - } - - /// - /// Handles opening an existing project, given a pathname to the project file. - /// - private void DoOpenFile(string projPathName) { - Debug.WriteLine("DoOpenFile: " + projPathName); - Debug.Assert(mProject == null); - - if (!File.Exists(projPathName)) { - string msg = string.Format(Properties.Resources.ERR_FILE_NOT_FOUND, projPathName); - MessageBox.Show(this, msg, Properties.Resources.ERR_FILE_GENERIC_CAPTION, - MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - - DisasmProject newProject = new DisasmProject(); - newProject.UseMainAppDomainForPlugins = mUseMainAppDomainForPlugins; - - // Deserialize the project file. I want to do this before loading the data file - // in case we decide to store the data file name in the project (e.g. the data - // file is a disk image or zip archive, and we need to know which part(s) to - // extract). - if (!ProjectFile.DeserializeFromFile(projPathName, newProject, - out FileLoadReport report)) { - // Should probably use a less-busy dialog for something simple like - // "permission denied", but the open file dialog handles most simple - // stuff directly. - ProjectLoadIssues dlg = new ProjectLoadIssues(report.Format(), - ProjectLoadIssues.Buttons.Cancel); - dlg.ShowDialog(); - // ignore dlg.DialogResult - dlg.Dispose(); - return; - } - - // Now open the data file, generating the pathname by stripping off the ".dis65" - // extension. If we can't find the file, show a message box and offer the option to - // locate it manually, repeating the process until successful or canceled. - const string UNKNOWN_FILE = "UNKNOWN"; - string dataPathName; - if (projPathName.Length <= ProjectFile.FILENAME_EXT.Length) { - dataPathName = UNKNOWN_FILE; - } else { - dataPathName = projPathName.Substring(0, - projPathName.Length - ProjectFile.FILENAME_EXT.Length); - } - byte[] fileData; - while ((fileData = FindValidDataFile(ref dataPathName, newProject, - out bool cancel)) == null) { - if (cancel) { - // give up - Debug.WriteLine("Abandoning attempt to open project"); - return; - } - } - - // If there were warnings, notify the user and give the a chance to cancel. - if (report.Count != 0) { - ProjectLoadIssues dlg = new ProjectLoadIssues(report.Format(), - ProjectLoadIssues.Buttons.ContinueOrCancel); - dlg.ShowDialog(); - DialogResult result = dlg.DialogResult; - dlg.Dispose(); - - if (result != DialogResult.OK) { - return; - } - } - - mProject = newProject; - mProjectPathName = mProject.ProjectPathName = projPathName; - mProject.SetFileData(fileData, Path.GetFileName(dataPathName)); - FinishPrep(); - } - - /// - /// Finds and loads the specified data file. The file's length and CRC must match - /// the project's expectations. - /// - /// Full path to file. - /// Project object. - /// Returns true if we want to cancel the attempt. - /// - private byte[] FindValidDataFile(ref string dataPathName, DisasmProject proj, - out bool cancel) { - FileInfo fi = new FileInfo(dataPathName); - if (!fi.Exists) { - Debug.WriteLine("File '" + dataPathName + "' doesn't exist"); - dataPathName = ChooseDataFile(dataPathName, - string.Format(Properties.Resources.OPEN_DATA_DOESNT_EXIST, dataPathName)); - cancel = (dataPathName == null); - return null; - } - if (fi.Length != proj.FileDataLength) { - Debug.WriteLine("File '" + dataPathName + "' has length=" + fi.Length + - ", expected " + proj.FileDataLength); - dataPathName = ChooseDataFile(dataPathName, - string.Format(Properties.Resources.OPEN_DATA_WRONG_LENGTH, - fi.Length, proj.FileDataLength)); - cancel = (dataPathName == null); - return null; - } - byte[] fileData = null; - try { - fileData = LoadDataFile(dataPathName); - } catch (Exception ex) { - Debug.WriteLine("File '" + dataPathName + "' failed to load: " + ex.Message); - dataPathName = ChooseDataFile(dataPathName, - string.Format(Properties.Resources.OPEN_DATA_LOAD_FAILED, ex.Message)); - cancel = (dataPathName == null); - return null; - } - uint crc = CRC32.OnWholeBuffer(0, fileData); - if (crc != proj.FileDataCrc32) { - Debug.WriteLine("File '" + dataPathName + "' has CRC32=" + crc + - ", expected " + proj.FileDataCrc32); - // Format the CRC as signed decimal, so that interested parties can - // easily replace the value in the .dis65 file. - dataPathName = ChooseDataFile(dataPathName, - string.Format(Properties.Resources.OPEN_DATA_WRONG_CRC, - (int) crc, (int) proj.FileDataCrc32)); - cancel = (dataPathName == null); - return null; - } - - cancel = false; - return fileData; - } - - /// - /// Displays a "do you want to pick a different file" message, then (on OK) allows the - /// user to select a file. - /// - /// Pathname of original file. - /// Message to display in the message box. - /// Full path of file to open. - private string ChooseDataFile(string origPath, string errorMsg) { - DataFileLoadIssue dlg = new DataFileLoadIssue(origPath, errorMsg); - dlg.ShowDialog(); - DialogResult result = dlg.DialogResult; - dlg.Dispose(); - if (result != DialogResult.OK) { - return null; - } - - OpenFileDialog fileDlg = new OpenFileDialog() { - FileName = Path.GetFileName(origPath), - Filter = Properties.Resources.FILE_FILTER_ALL - }; - if (fileDlg.ShowDialog() != DialogResult.OK) { - return null; - } - - string newPath = Path.GetFullPath(fileDlg.FileName); - Debug.WriteLine("User selected data file " + newPath); - return newPath; - } - - // File > Save (Ctrl+S) - private void saveToolStripButton_Click(object sender, EventArgs e) { - saveToolStripMenuItem_Click(sender, e); - } - private void saveToolStripMenuItem_Click(object sender, EventArgs e) { - DoSave(); - } - // File > Save As... - private void saveAsToolStripMenuItem_Click(object sender, EventArgs e) { - DoSaveAs(); - } - - private bool DoSaveAs() { - SaveFileDialog fileDlg = new SaveFileDialog() { - Filter = ProjectFile.FILENAME_FILTER + "|" + Properties.Resources.FILE_FILTER_ALL, - FilterIndex = 1, - ValidateNames = true, - AddExtension = true, - FileName = Path.GetFileName(mDataPathName) + ProjectFile.FILENAME_EXT - }; - if (fileDlg.ShowDialog() == DialogResult.OK) { - string pathName = Path.GetFullPath(fileDlg.FileName); - Debug.WriteLine("Project save path: " + pathName); - if (DoSave(pathName)) { - // Success, record the path name. - mProjectPathName = mProject.ProjectPathName = pathName; - - // add it to the title bar - UpdateMenuItemsAndTitle(); - return true; - } - } - return false; - } - - // Save the project. If it hasn't been saved before, use save-as behavior instead. - private bool DoSave() { - if (string.IsNullOrEmpty(mProjectPathName)) { - return DoSaveAs(); - } - return DoSave(mProjectPathName); - } - - private bool DoSave(string pathName) { - Debug.WriteLine("SAVING " + pathName); - if (!ProjectFile.SerializeToFile(mProject, pathName, out string errorMessage)) { - MessageBox.Show(this, - Properties.Resources.ERR_PROJECT_SAVE_FAIL + ": " + errorMessage, - Properties.Resources.OPERATION_FAILED, - MessageBoxButtons.OK, MessageBoxIcon.Error); - return false; - } - - mProject.ResetDirtyFlag(); - // If the debug dialog is visible, update it. - if (mShowUndoRedoHistoryDialog != null) { - mShowUndoRedoHistoryDialog.BodyText = mProject.DebugGetUndoRedoHistory(); - } - UpdateMenuItemsAndTitle(); - - // Update this, in case this was a new project. - UpdateRecentProjectList(pathName); - - // Seems like a good time to save this off too. - SaveAppSettings(); - - return true; - } - - // App is closing. - private void ProjectView_FormClosing(object sender, FormClosingEventArgs e) { - Debug.WriteLine("Main app form closing (reason=" + e.CloseReason + ")"); - if (mProjectControl == null) { - // This can be null if something failed during startup, so we're exiting - // the application before the UI is fully up. - return; - } - - if (!DoClose()) { - e.Cancel = true; - return; - } - SaveAppSettings(); - } - - // File > Close - private void closeToolStripMenuItem_Click(object sender, EventArgs e) { - if (!DoClose()) { - Debug.WriteLine("Close canceled"); - } - } - - /// - /// Closes the project and associated modeless dialogs. Unsaved changes will be - /// lost, so if the project has outstanding changes the user will be given the - /// opportunity to cancel. - /// - /// True if the project was closed, false if the user chose to cancel. - private bool DoClose() { - Debug.WriteLine("ProjectView.DoClose() - dirty=" + - (mProject == null ? "N/A" : mProject.IsDirty.ToString())); - if (mProject != null && mProject.IsDirty) { - DiscardChanges dlg = new DiscardChanges(); - DialogResult result = dlg.ShowDialog(this); - if (result == DialogResult.Cancel) { - return false; - } else if (result == DialogResult.Yes) { - if (!DoSave()) { - return false; - } - } - } - - // Close modeless dialogs that depend on project. - if (mShowUndoRedoHistoryDialog != null) { - mShowUndoRedoHistoryDialog.Close(); - } - if (mShowAnalysisTimersDialog != null) { - mShowAnalysisTimersDialog.Close(); - } - if (mShowAnalyzerOutputDialog != null) { - mShowAnalyzerOutputDialog.Close(); - } - if (mHexDumpDialog != null) { - mHexDumpDialog.Close(); - } - - // Discard all project state. - if (mProject != null) { - mProject.Cleanup(); - mProject = null; - } - mDataPathName = null; - mProjectPathName = null; - mSymbolSubset = new SymbolTableSubset(new SymbolTable()); - mCodeViewSelection = new VirtualListViewSelection(); - mDisplayList = null; - codeListView.VirtualListSize = 0; - //codeListView.Items.Clear(); - ShowNoProject(); - InvalidateControls(null); - - mGenerationLog = null; - - // Not necessary, but it lets us check the memory monitor to see if we got - // rid of everything. - GC.Collect(); - - return true; - } - - // File > Assemble... - private void assembleToolStripMenuItem_Click(object sender, EventArgs e) { - if (string.IsNullOrEmpty(mProjectPathName)) { - // We need a project pathname so we know where to write the assembler - // source files, and what to call the output files. We could just pop up the - // Save As dialog, but that seems confusing unless we do a custom dialog with - // an explanation, or have some annoying click-through. - // - // This only appears for never-saved projects, not projects with unsaved data. - MessageBox.Show(this, Properties.Resources.SAVE_BEFORE_ASM_TEXT, - Properties.Resources.SAVE_BEFORE_ASM_CAPTION, - MessageBoxButtons.OK, MessageBoxIcon.Information); - return; - } - - AsmGen.GenAndAsm dlg = new AsmGen.GenAndAsm(this, mProject, mProjectPathName); - dlg.ShowDialog(); - } - - // File > Exit - private void exitToolStripMenuItem_Click(object sender, EventArgs e) { - // Unsaved-data check happens in form closing event. - Application.Exit(); - } - - // Edit > Undo, Ctrl+Z (may be called with null/null) - private void undoToolStripMenuItem_Click(object sender, EventArgs e) { - if (!mProject.CanUndo) { - Debug.WriteLine("Nothing to undo"); - return; - } - ChangeSet cs = mProject.PopUndoSet(); - ApplyChanges(cs, true); - UpdateMenuItemsAndTitle(); - - // If the debug dialog is visible, update it. - if (mShowUndoRedoHistoryDialog != null) { - mShowUndoRedoHistoryDialog.BodyText = mProject.DebugGetUndoRedoHistory(); - } - } - - // Edit > Redo, Ctrl+Y (may be called with null/null) - private void redoToolStripMenuItem_Click(object sender, EventArgs e) { - if (!mProject.CanRedo) { - Debug.WriteLine("Nothing to redo"); - return; - } - ChangeSet cs = mProject.PopRedoSet(); - ApplyChanges(cs, false); - UpdateMenuItemsAndTitle(); - - // If the debug dialog is visible, update it. - if (mShowUndoRedoHistoryDialog != null) { - mShowUndoRedoHistoryDialog.BodyText = mProject.DebugGetUndoRedoHistory(); - } - } - - // Edit > Select All (Ctrl+A) - private void selectAllToolStripMenuItem_Click(object sender, EventArgs e) { - codeListView.SelectAll(); -#if false - try { - Application.UseWaitCursor = true; - Cursor.Current = Cursors.WaitCursor; - codeListView.BeginUpdate(); - int max = codeListView.VirtualListSize; - for (int i = 0; i < max; i++) { - //codeListView.Items[i].Selected = true; - codeListView.SelectedIndices.Add(i); - if ((i % 50000) == 0) { - toolStripStatusLabel.Text = string.Format( - Properties.Resources.STATUS_SELECTING, (i * 100) / max); - //Application.DoEvents(); // <-- this is unwise - Refresh(); // <-- updates status line but not mouse - } - } - } finally { - codeListView.EndUpdate(); - Application.UseWaitCursor = false; - toolStripStatusLabel.Text = Properties.Resources.STATUS_READY; - } -#endif - } - - // Edit > Copy (Ctrl+C) - private void copyToolStripMenuItem_Click(object sender, EventArgs e) { - const bool addCsv = true; - - EditAppSettings.ClipLineFormat format = - (EditAppSettings.ClipLineFormat) AppSettings.Global.GetEnum( - AppSettings.CLIP_LINE_FORMAT, - typeof(EditAppSettings.ClipLineFormat), - (int) EditAppSettings.ClipLineFormat.AssemblerSource); - StringBuilder fullText = new StringBuilder(codeListView.SelectedIndices.Count * 50); - StringBuilder csv = new StringBuilder(codeListView.SelectedIndices.Count * 40); - StringBuilder sb = new StringBuilder(100); - - int addrAdj = mProject.CpuDef.HasAddr16 ? 6 : 9; - int disAdj = 0; - int bytesWidth = 0; - if (format == EditAppSettings.ClipLineFormat.Disassembly) { - // A limit of 8 gets us 4 bytes from dense display ("20edfd60") and 3 if spaces - // are included ("20 ed fd") with no excess. We want to increase it to 11 so - // we can always show 4 bytes. - bytesWidth = (mFormatterConfig.mSpacesBetweenBytes ? 11 : 8); - disAdj = addrAdj + bytesWidth + 2; - } - - // Walking through the selected indices can be slow for a large file, so we - // run through the full list and pick out the selected items with our parallel - // structure. (I'm assuming that "select all" will be a common precursor.) - for (int i = 0; i < mDisplayList.Count; i++) { - if (!mCodeViewSelection[i]) { - continue; - } - DisplayList.Line line = mDisplayList[i]; - DisplayList.FormattedParts parts = mDisplayList.GetFormattedParts(i); - switch (line.LineType) { - case DisplayList.Line.Type.Code: - case DisplayList.Line.Type.Data: - case DisplayList.Line.Type.EquDirective: - case DisplayList.Line.Type.RegWidthDirective: - case DisplayList.Line.Type.OrgDirective: - if (format == EditAppSettings.ClipLineFormat.Disassembly) { - if (!string.IsNullOrEmpty(parts.Addr)) { - sb.Append(parts.Addr); - sb.Append(": "); - } - - // Shorten the "...". - string bytesStr = parts.Bytes; - if (bytesStr != null && bytesStr.Length > bytesWidth) { - bytesStr = bytesStr.Substring(0, bytesWidth) + "+"; - } - TextUtil.AppendPaddedString(sb, bytesStr, disAdj); - } - TextUtil.AppendPaddedString(sb, parts.Label, disAdj + 9); - TextUtil.AppendPaddedString(sb, parts.Opcode, disAdj + 9 + 8); - TextUtil.AppendPaddedString(sb, parts.Operand, disAdj + 9 + 8 + 11); - if (string.IsNullOrEmpty(parts.Comment)) { - // Trim trailing spaces off opcode or operand. - TextUtil.TrimEnd(sb); - } else { - sb.Append(parts.Comment); - } - sb.Append("\r\n"); - break; - case DisplayList.Line.Type.LongComment: - if (format == EditAppSettings.ClipLineFormat.Disassembly) { - TextUtil.AppendPaddedString(sb, string.Empty, disAdj); - } - sb.Append(parts.Comment); - sb.Append("\r\n"); - break; - case DisplayList.Line.Type.Note: - // don't include notes - break; - case DisplayList.Line.Type.Blank: - sb.Append("\r\n"); - break; - default: - Debug.Assert(false); - break; - } - fullText.Append(sb); - - if (addCsv) { - csv.Append(TextUtil.EscapeCSV(parts.Offset)); csv.Append(','); - csv.Append(TextUtil.EscapeCSV(parts.Addr)); csv.Append(','); - csv.Append(TextUtil.EscapeCSV(parts.Bytes)); csv.Append(','); - csv.Append(TextUtil.EscapeCSV(parts.Flags)); csv.Append(','); - csv.Append(TextUtil.EscapeCSV(parts.Attr)); csv.Append(','); - csv.Append(TextUtil.EscapeCSV(parts.Label)); csv.Append(','); - csv.Append(TextUtil.EscapeCSV(parts.Opcode)); csv.Append(','); - csv.Append(TextUtil.EscapeCSV(parts.Operand)); csv.Append(','); - csv.Append(TextUtil.EscapeCSV(parts.Comment)); - csv.Append("\r\n"); - } - - sb.Clear(); - } - - // We want to have both plain text and CSV data on the clipboard. To add both - // formats we need to stream it to a DataObject. Complicating matters is Excel's - // entirely reasonable desire to have data in UTF-8 rather than UTF-16. - // - // (I'm not sure pasting assembly bits into Excel is actually useful, so this - // should probably be optional.) - // - // https://stackoverflow.com/a/369219/294248 - DataObject dataObject = new DataObject(); - dataObject.SetText(fullText.ToString()); - if (addCsv) { - byte[] csvData = Encoding.UTF8.GetBytes(csv.ToString()); - MemoryStream stream = new MemoryStream(csvData); - dataObject.SetData(DataFormats.CommaSeparatedValue, stream); - } - Clipboard.SetDataObject(dataObject, true); - } - - // Edit > Find... (Ctrl+F) - private void findToolStripMenuItem_Click(object sender, EventArgs e) { - FindBox dlg = new FindBox(mFindString); - if (dlg.ShowDialog() == DialogResult.OK) { - mFindString = dlg.TextToFind; - mFindStartIndex = -1; - FindText(); - } - dlg.Dispose(); - } - - // Edit > Find Next (F3) - private void findNextToolStripMenuItem_Click(object sender, EventArgs e) { - FindText(); - } - - private void FindText() { - if (string.IsNullOrEmpty(mFindString)) { - return; - } - - int index; - if (codeListView.SelectedIndices.Count > 0) { - index = codeListView.SelectedIndices[0]; - } else { - index = 0; - } - - // Start one past the currently-selected item. - index++; - if (index == mDisplayList.Count) { - index = 0; - } - //Debug.WriteLine("FindText index=" + index + " start=" + mFindStartIndex + - // " str=" + mFindString); - while (index != mFindStartIndex) { - if (mFindStartIndex < 0) { - // need to latch this inside the loop so the initial test doesn't fail - mFindStartIndex = index; - } - - string searchStr = mDisplayList.GetSearchString(index); - int matchPos = searchStr.IndexOf(mFindString, - StringComparison.InvariantCultureIgnoreCase); - if (matchPos >= 0) { - //Debug.WriteLine("Match " + index + ": " + searchStr); - codeListView.EnsureVisible(index); - codeListView.DeselectAll(); - codeListView.SelectedIndices.Add(index); - return; - } - - index++; - if (index == mDisplayList.Count) { - index = 0; - } - } - - // Announce that we've wrapped around, then clear the start index. - MessageBox.Show(this, Properties.Resources.FIND_REACHED_START, - Properties.Resources.FIND_REACHED_START_CAPTION, MessageBoxButtons.OK, - MessageBoxIcon.Information); - mFindStartIndex = -1; - } - - // Edit > Go To... - private void gotoToolStripMenuItem_Click(object sender, EventArgs e) { - GotoBox dlg = new GotoBox(mProject, mOutputFormatter); - if (dlg.ShowDialog() == DialogResult.OK) { - GoToOffset(dlg.TargetOffset, false, true); - } - dlg.Dispose(); - } - - // Edit > Project Properties... - private void projectPropertiesToolStripMenuItem_Click(object sender, EventArgs e) { - string projectDir = string.Empty; - if (!string.IsNullOrEmpty(mProjectPathName)) { - projectDir = Path.GetDirectoryName(mProjectPathName); - } - EditProjectProperties dlg = new EditProjectProperties(mProject.ProjectProps, - projectDir, mOutputFormatter); - dlg.ShowDialog(); - ProjectProperties newProps = dlg.NewProps; - dlg.Dispose(); - - // The dialog result doesn't matter, because the user might have hit "apply" - // before hitting "cancel". - if (newProps != null) { - UndoableChange uc = UndoableChange.CreateProjectPropertiesChange( - mProject.ProjectProps, newProps); - ApplyUndoableChanges(new ChangeSet(uc)); - } - } - - // Edit > Toggle Data Scan - private void toggleDataScanToolStripMenuItem_Click(object sender, EventArgs e) { - ProjectProperties oldProps = mProject.ProjectProps; - ProjectProperties newProps = new ProjectProperties(oldProps); - newProps.AnalysisParams.AnalyzeUncategorizedData = - !newProps.AnalysisParams.AnalyzeUncategorizedData; - UndoableChange uc = UndoableChange.CreateProjectPropertiesChange(oldProps, newProps); - ApplyUndoableChanges(new ChangeSet(uc)); - } - - // Edit > Settings... - private void settingsToolStripMenuItem_Click(object sender, EventArgs e) { - ShowAppSettings(EditAppSettings.Tab.Unknown, AsmGen.AssemblerInfo.Id.Unknown); - } - - /// - /// Opens the app settings dialog. - /// - /// Tab to present to the user. - public void ShowAppSettings(EditAppSettings.Tab initialTab, - AsmGen.AssemblerInfo.Id initialAsmId) { - EditAppSettings dlg = new EditAppSettings(this, initialTab, initialAsmId); - dlg.ShowDialog(); - dlg.Dispose(); - } - - // Help > View Help... - private void viewHelpToolStripMenuItem_Click(object sender, EventArgs e) { - HelpAccess.ShowHelp(HelpAccess.Topic.Contents); - } - private void helpToolStripButton_Click(object sender, EventArgs e) { - viewHelpToolStripMenuItem_Click(sender, e); - } - - // Help > About... - private void aboutToolStripMenuItem_Click(object sender, EventArgs e) { - AboutBox dlg = new AboutBox(); - dlg.ShowDialog(); - dlg.Dispose(); - } - - private void codeListView_MouseDown(object sender, MouseEventArgs e) { - // MouseClick only fires for certain buttons and certain locations. MouseDown - // fires for all buttons so long as the pointer is in the codeListView area. - if (e.Button == MouseButtons.XButton1 && navigateBackToolStripButton.Enabled) { - navigateBackToolStripButton_Click(sender, e); - } - } - - private void codeListView_MouseDoubleClick(object sender, MouseEventArgs e) { - ListViewHitTestInfo info = codeListView.HitTest(e.X, e.Y); - int row = info.Item.Index; - int col = info.Item.SubItems.IndexOf(info.SubItem); - // col will be -1 for e.g. blank lines [not anymore?] - string value = col < 0 ? "-" : info.Item.SubItems[col].Text; - Debug.WriteLine(string.Format("R{0}:C{1} val '{2}'", row, col, value)); - - // It's possible to select multiple lines with shift-double-click. We - // handle that by checking to see what UpdateActionMenu() decided was available. - - // Clicking on some types of lines, such as ORG directives, results in - // specific behavior regardless of which column you click in. We're just - // checking the clicked-on line to decide what action to take. If it doesn't - // make sense to do for a multi-line selection, the action will have been - // disabled. - DisplayList.Line line = mDisplayList[row]; - switch (line.LineType) { - case DisplayList.Line.Type.EquDirective: - // Currently only does something for project symbols; platform symbols - // do nothing. - if (editProjectSymbolToolStripMenuItem.Enabled) { - EditProjectSymbol_Click(sender, e); - } - break; - case DisplayList.Line.Type.OrgDirective: - if (setAddressToolStripMenuItem.Enabled) { - EditAddress_Click(sender, e); - } - break; - case DisplayList.Line.Type.RegWidthDirective: - if (overrideStatusFlagsToolStripMenuItem.Enabled) { - EditStatusFlags_Click(sender, e); - } - break; - case DisplayList.Line.Type.LongComment: - if (editLongCommentToolStripMenuItem.Enabled) { - EditLongComment_Click(sender, e); - } - break; - case DisplayList.Line.Type.Note: - if (editNoteToolStripMenuItem.Enabled) { - EditNote_Click(sender, e); - } - break; - - case DisplayList.Line.Type.Code: - case DisplayList.Line.Type.Data: - // For code and data, we have to break it down by column. - switch ((ColumnIndex)col) { - case ColumnIndex.Offset: - // does nothing - break; - case ColumnIndex.Address: - // edit address - if (setAddressToolStripMenuItem.Enabled) { - EditAddress_Click(sender, e); - } - break; - case ColumnIndex.Bytes: - if (showHexDumpToolStripMenuItem.Enabled) { - ShowHexDump_Click(sender, e); - } - break; - case ColumnIndex.Flags: - if (overrideStatusFlagsToolStripMenuItem.Enabled) { - EditStatusFlags_Click(sender, e); - } - break; - case ColumnIndex.Attributes: - // does nothing - break; - case ColumnIndex.Label: - if (editLabelToolStripMenuItem.Enabled) { - EditLabel_Click(sender, e); - } - break; - case ColumnIndex.Opcode: - // File offset should always be valid, since we excluded the EQU - // statements and header comment earlier. - if (line.FileOffset >= 0) { - Anattrib attr = mProject.GetAnattrib(line.FileOffset); - FormatDescriptor dfd = attr.DataDescriptor; - - // Does this have an operand with an in-file target offset? - // (Resolve it as a numeric reference.) - if (attr.OperandOffset >= 0) { - // Yup, find the line for that offset and jump to it. - GoToOffset(attr.OperandOffset, false, true); - } else if (dfd != null && dfd.HasSymbol) { - // Operand has a symbol, do a symbol lookup. - int labelOffset = mProject.FindLabelOffsetByName( - dfd.SymbolRef.Label); - if (labelOffset >= 0) { - GoToOffset(labelOffset, false, true); - } - } else if (attr.IsDataStart || attr.IsInlineDataStart) { - // If it's an Address or Symbol, we can try to resolve - // the value. (Symbols should have been resolved by the - // previous clause, but Address entries would not have been.) - int operandOffset = DataAnalysis.GetDataOperandOffset( - mProject, line.FileOffset); - if (operandOffset >= 0) { - GoToOffset(operandOffset, false, true); - } - } - } - break; - case ColumnIndex.Operand: - if (editOperandToolStripMenuItem.Enabled) { - EditInstrDataOperand_Click(sender, e); - } - break; - case ColumnIndex.Comment: - if (editCommentToolStripMenuItem.Enabled) { - EditComment_Click(sender, e); - } - break; - - } - break; - - default: - Debug.WriteLine("Double-click: unhandled line type " + line.LineType); - break; - } - } - - /// - /// Moves the view and selection to the specified offset. We want to select stuff - /// differently if we're jumping to a note vs. jumping to an instruction. - /// - /// Offset to jump to. - /// If set, push new offset onto navigation stack. - private void GoToOffset(int gotoOffset, bool jumpToNote, bool doPush) { - int curSelIndex = -1; - if (codeListView.SelectedIndices.Count > 0) { - curSelIndex = codeListView.SelectedIndices[0]; - } - - int topLineIndex = mDisplayList.FindLineIndexByOffset(gotoOffset); - if (topLineIndex < 0) { - Debug.Assert(false, "failed goto offset +" + gotoOffset.ToString("x6")); - return; - } - int lastLineIndex; - if (jumpToNote) { - // Select all note lines, disregard the rest. - while (mDisplayList[topLineIndex].LineType != DisplayList.Line.Type.Note) { - topLineIndex++; - Debug.Assert(mDisplayList[topLineIndex].FileOffset == gotoOffset); - } - lastLineIndex = topLineIndex + 1; - while (lastLineIndex < mDisplayList.Count && - mDisplayList[lastLineIndex].LineType == DisplayList.Line.Type.Note) { - lastLineIndex++; - } - } else if (gotoOffset < 0) { - // This is the offset of the header comment or a .EQ directive. Don't mess with it. - lastLineIndex = topLineIndex + 1; - } else { - // Advance to the code or data line. - while (mDisplayList[topLineIndex].LineType != DisplayList.Line.Type.Code && - mDisplayList[topLineIndex].LineType != DisplayList.Line.Type.Data) { - topLineIndex++; - } - lastLineIndex = topLineIndex + 1; - } - - // Make sure the item is visible. For notes, this can span multiple lines. - codeListView.EnsureVisible(lastLineIndex - 1); - codeListView.EnsureVisible(topLineIndex); - - // Update the selection. - codeListView.DeselectAll(); - for (int i = topLineIndex; i < lastLineIndex; i++) { - codeListView.Items[i].Selected = true; - } - - if (doPush) { - if (curSelIndex >= 0) { - // Update the back stack and associated controls. - mNavStack.Push(mDisplayList[curSelIndex].FileOffset, gotoOffset); - UpdateMenuItemsAndTitle(); - } else { - // This can happen when the project is first opened and nothing is selected. - Debug.WriteLine("no selection to go back to"); - } - } - } - - // Fires when the selection changes, causing the SelectionIndices list to change. - // For multi-select, this seems to be called with an empty list. - private void codeListView_SelectedIndexChanged(object sender, EventArgs e) { - // Update the "references" and "info" window contents. - UpdateReferenceView(); - UpdateInfoView(); - - UpdateSelectionHighlight(); - } - - // Virtual ListView selection tracking - private void codeListView_ItemSelectionChanged(object sender, - ListViewItemSelectionChangedEventArgs e) { - mCodeViewSelection.ItemSelectionChanged(e); - - // Don't try to call mCodeViewSelection.DebugValidateSelectionCount here. - // Events will fire during RestoreSelection() at a point where the - // SelectedIndices don't match up. - - if (!mRestoringSelection) { - UpdateActionMenu(); - } - } - - // Virtual ListView selection tracking - private void codeListView_VirtualItemsSelectionRangeChanged(object sender, - ListViewVirtualItemsSelectionRangeChangedEventArgs e) { - mCodeViewSelection.VirtualItemsSelectionRangeChanged(e); - - if (!mRestoringSelection) { - UpdateActionMenu(); - } - } - - /// - /// Enables or disables the menu items in the Actions menu. - /// - /// We want to do this whenever the selection changes so that any keyboard shortcuts - /// are enabled or disabled appropriately. This does need to be reasonably fast - /// for large files. - /// - /// The outcome of this method -- menu items being enabled or disabled -- is also - /// used by the double-click handler. - /// - private void UpdateActionMenu() { - if (mProject == null) { - // Disable all actions. - foreach (ToolStripItem item in mActionsMenuItems) { - item.Enabled = false; - } - return; - } - - // While restoring the selection, the SelectedIndices won't match up, because - // part of the restore process is setting and clearing the control to match - // what's in the mCodeViewSelection array. There's no value in repeating - // this for every event caused by the restoration, so we don't expect to be - // called at all during a restore. (Just make sure to call here after the - // restore is complete.) - Debug.Assert(!mRestoringSelection); - Debug.Assert(mCodeViewSelection.DebugValidateSelectionCount( - codeListView.SelectedIndices.Count), "selection count mismatch"); - - ListView.SelectedIndexCollection sel = codeListView.SelectedIndices; - EntityCounts entityCounts; - - bool editDataOperandEnabled = false; - bool editInstrOperandEnabled = false; - - // Use IsSingleItemSelected(), rather than just checking sel.Count, because we - // want the user to be able to e.g. EditData on a multi-line string even if all - // lines in the string are selected. - if (IsSingleItemSelected()) { - entityCounts = GatherEntityCounts(sel[0]); - - DisplayList.Line line = mDisplayList[sel[0]]; - DisplayList.Line.Type lineType = line.LineType; - - bool isCodeOrData = (lineType == DisplayList.Line.Type.Code || - lineType == DisplayList.Line.Type.Data); - - setAddressToolStripMenuItem.Enabled = - (isCodeOrData || lineType == DisplayList.Line.Type.OrgDirective); - editInstrOperandEnabled = (lineType == DisplayList.Line.Type.Code && - mProject.GetAnattrib(line.FileOffset).IsInstructionWithOperand); - editDataOperandEnabled = (lineType == DisplayList.Line.Type.Data); - editLabelToolStripMenuItem.Enabled = isCodeOrData; - editCommentToolStripMenuItem.Enabled = isCodeOrData; - editLongCommentToolStripMenuItem.Enabled = - (isCodeOrData || lineType == DisplayList.Line.Type.LongComment); - editNoteToolStripMenuItem.Enabled = - (isCodeOrData || lineType == DisplayList.Line.Type.Note); - overrideStatusFlagsToolStripMenuItem.Enabled = - (lineType == DisplayList.Line.Type.Code || - lineType == DisplayList.Line.Type.RegWidthDirective); - deleteNoteCommentToolStripMenuItem.Enabled = - (lineType == DisplayList.Line.Type.LongComment || - lineType == DisplayList.Line.Type.Note); - - if (lineType == DisplayList.Line.Type.EquDirective) { - // Only enable this for project symbols, not all EQU directives. - int symIndex = DisplayList.DefSymIndexFromOffset(line.FileOffset); - DefSymbol defSym = mProject.ActiveDefSymbolList[symIndex]; - editProjectSymbolToolStripMenuItem.Enabled = - (defSym.SymbolSource == Symbol.Source.Project); - } else { - editProjectSymbolToolStripMenuItem.Enabled = false; - } - } else { - entityCounts = GatherEntityCounts(-1); - - // Disable all single-target-only items. - setAddressToolStripMenuItem.Enabled = false; - editInstrOperandEnabled = false; - editLabelToolStripMenuItem.Enabled = false; - editCommentToolStripMenuItem.Enabled = false; - editLongCommentToolStripMenuItem.Enabled = false; - editNoteToolStripMenuItem.Enabled = false; - overrideStatusFlagsToolStripMenuItem.Enabled = false; - deleteNoteCommentToolStripMenuItem.Enabled = false; - editProjectSymbolToolStripMenuItem.Enabled = false; - - if (sel.Count == 0) { - // Disable everything else. - editDataOperandEnabled = false; - hintAsCodeToolStripMenuItem.Enabled = false; - hintAsDataToolStripMenuItem.Enabled = false; - hintAsInlineDataToolStripMenuItem.Enabled = false; - removeHintToolStripMenuItem.Enabled = false; - } else { - // Must be all data items. Blank lines are okay. Currently allowing - // control lines as well. - editDataOperandEnabled = - (entityCounts.mDataLines > 0 && entityCounts.mCodeLines == 0); - } - } - - // Enable the "edit operand" menu item if either instruction or data operand - // editing is allowed. - editOperandToolStripMenuItem.Enabled = - editDataOperandEnabled || editInstrOperandEnabled; - - formatSplitAddressTableToolStripMenuItem.Enabled = - (entityCounts.mDataLines > 0 && entityCounts.mCodeLines == 0); - toggleSingleBytesToolStripMenuItem.Enabled = - (entityCounts.mDataLines > 0 && entityCounts.mCodeLines == 0); - - // This is insufficient -- we need to know how many bytes are selected, and - // whether they're already formatted as multi-byte items. Too expensive to - // deal with here, so we'll need to show failure dialogs instead (ugh). - formatAsWordToolStripMenuItem.Enabled = - (entityCounts.mDataLines > 0 && entityCounts.mCodeLines == 0); - - - // So long as some code or data is highlighted, allow these. Don't worry about - // control lines. Disable options that would have no effect. - bool enableHints = (entityCounts.mDataLines > 0 || entityCounts.mCodeLines > 0); - hintAsCodeToolStripMenuItem.Enabled = enableHints && - (entityCounts.mDataHints != 0 || - entityCounts.mInlineDataHints != 0 || - entityCounts.mNoHints != 0); - hintAsDataToolStripMenuItem.Enabled = enableHints && - (entityCounts.mCodeHints != 0 || - entityCounts.mInlineDataHints != 0 || - entityCounts.mNoHints != 0); - hintAsInlineDataToolStripMenuItem.Enabled = enableHints && - (entityCounts.mCodeHints != 0 || - entityCounts.mDataHints != 0 || - entityCounts.mNoHints != 0); - removeHintToolStripMenuItem.Enabled = enableHints && - (entityCounts.mCodeHints != 0 || - entityCounts.mDataHints != 0 || - entityCounts.mInlineDataHints != 0); - - // Just leave this on. If they're in EQU-land or nothing is selected, it'll just - // open at the start of the file. - showHexDumpToolStripMenuItem.Enabled = true; - } - - /// - /// Entity count collection, for GatherEntityCounts. - /// - private class EntityCounts { - public int mCodeLines; - public int mDataLines; - public int mBlankLines; - public int mControlLines; - - public int mCodeHints; - public int mDataHints; - public int mInlineDataHints; - public int mNoHints; - }; - - /// - /// Gathers a count of different line types and offset hinting. - /// - /// If a single line is selected, pass the index in. - /// Otherwise, pass -1 to traverse the entire line list. - /// - private EntityCounts GatherEntityCounts(int singleLineIndex) { - //DateTime startWhen = DateTime.Now; - int codeLines, dataLines, blankLines, controlLines; - int codeHints, dataHints, inlineDataHints, noHints; - codeLines = dataLines = blankLines = controlLines = 0; - codeHints = dataHints = inlineDataHints = noHints = 0; - - int startIndex, endIndex; - if (singleLineIndex < 0) { - startIndex = 0; - endIndex = mDisplayList.Count - 1; - } else { - startIndex = endIndex = singleLineIndex; - } - - for (int i = startIndex; i <= endIndex; i++) { - if (!mCodeViewSelection[i]) { - continue; - } - DisplayList.Line line = mDisplayList[i]; - switch (line.LineType) { - case DisplayList.Line.Type.Code: - codeLines++; - break; - case DisplayList.Line.Type.Data: - dataLines++; - break; - case DisplayList.Line.Type.Blank: - // Don't generally care how many blank lines there are, but we do want - // to exclude them from the other categories: if we have nothing but - // blank lines, there's nothing to do. - blankLines++; - break; - default: - // These are only editable as single-line items. We do allow mass - // code hint selection to include them (they will be ignored). - // org, equ, rwid, long comment... - controlLines++; - break; - } - - // A single line can span multiple offsets, each of which could have a - // different hint. - for (int offset = line.FileOffset; offset < line.FileOffset + line.OffsetSpan; - offset++) { - switch (mProject.TypeHints[offset]) { - case CodeAnalysis.TypeHint.Code: - codeHints++; - break; - case CodeAnalysis.TypeHint.Data: - dataHints++; - break; - case CodeAnalysis.TypeHint.InlineData: - inlineDataHints++; - break; - case CodeAnalysis.TypeHint.NoHint: - noHints++; - break; - default: - Debug.Assert(false); - break; - } - } - } - - //Debug.WriteLine("GatherEntityCounts (len=" + mCodeViewSelection.Length + ") took " + - // (DateTime.Now - startWhen).TotalMilliseconds + " ms"); - - return new EntityCounts() { - mCodeLines = codeLines, - mDataLines = dataLines, - mBlankLines = blankLines, - mControlLines = controlLines, - mCodeHints = codeHints, - mDataHints = dataHints, - mInlineDataHints = inlineDataHints, - mNoHints = noHints - }; - } - - /// - /// Determines whether the current selection spans a single item. This could be a - /// single-line item or a multi-line item. - /// - private bool IsSingleItemSelected() { - ListView.SelectedIndexCollection sel = codeListView.SelectedIndices; - if (sel.Count == 0) { - return false; - } else if (sel.Count == 1) { - return true; - } - - // The selection is presented in sorted order, so we can just check the - // first and last entries to see if they're the same. - // - // Performance note: SelectedIndices[] appears to be dynamic. In a very - // large list (500K+ entries), requesting sel[sel.Count - 1] can take a few - // seconds. As an optimization we just give up if the selection spans - // more than a few hundred lines. (At worst, this requires clicking a single line - // of a comment/note to edit it as an individual item.) - // TODO(maybe): iterate over mCodeViewSelection instead? Would need more stuff there. - if (sel.Count >= 500) { - Debug.WriteLine("Selection very large (" + sel.Count + "), not checking for " + - "single-item span"); - return false; - } - DisplayList.Line firstItem = mDisplayList[sel[0]]; - DisplayList.Line lastItem = mDisplayList[sel[sel.Count - 1]]; - if (firstItem.FileOffset == lastItem.FileOffset && - firstItem.LineType == lastItem.LineType) { - return true; - } - return false; - } - - /// - /// Updates the selection highlight. When a code item with an operand offset is - /// selected, such as a branch, we want to highlight the address and label of the - /// target. - /// - private void UpdateSelectionHighlight() { - int targetIndex = FindSelectionHighlight(); - - if (mTargetHighlightIndex != targetIndex) { - mTargetHighlightIndex = targetIndex; - Debug.WriteLine("Selection highlight now " + targetIndex); - - // Force a redraw. - codeListView.BeginUpdate(); - //ClearCodeListViewCache(); // not necessary; only formatting has changed - codeListView.EndUpdate(); - } - } - - private int FindSelectionHighlight() { - ListView.SelectedIndexCollection sel = codeListView.SelectedIndices; - if (sel.Count != 1) { - return -1; - } - DisplayList.Line line = mDisplayList[codeListView.SelectedIndices[0]]; - if (!line.IsCodeOrData) { - return -1; - } - Debug.Assert(line.FileOffset >= 0); - - // Does this have an operand with an in-file target offset? - Anattrib attr = mProject.GetAnattrib(line.FileOffset); - if (attr.OperandOffset >= 0) { - return mDisplayList.FindCodeDataIndexByOffset(attr.OperandOffset); - } else if (attr.IsDataStart || attr.IsInlineDataStart) { - // If it's an Address or Symbol, we can try to resolve - // the value. - int operandOffset = DataAnalysis.GetDataOperandOffset(mProject, line.FileOffset); - if (operandOffset >= 0) { - return mDisplayList.FindCodeDataIndexByOffset(operandOffset); - } - } - return -1; - } - - - private void editToolStripMenuItem_DropDownOpening(object sender, EventArgs e) { - // Set the checkmark on Toggle Data Scan. - toggleDataScanToolStripMenuItem.Checked = (mProject != null) && - mProject.ProjectProps.AnalysisParams.AnalyzeUncategorizedData; - } - - /// - /// Handles an "opening" event for the codeListView's ContextMenuStrip. - /// - /// This puts all of the Actions menu items in the pop-up context menu. - /// - private void codeListView_CmsOpening(object sender, CancelEventArgs e) { - codeListView.ContextMenuStrip.Items.AddRange(mActionsMenuItems); - e.Cancel = false; - } - - /// - /// Handles an "opening" event for the ProjectView's Actions menu. - /// - /// This puts all of the Actions menu items in the Actions menu. We also want to call - /// this when the context menu closes, so that Alt-A will open the menu. - /// - private void ActionsMenuOpening(object sender, EventArgs e) { - actionsToolStripMenuItem.DropDownItems.AddRange(mActionsMenuItems); - } - - private void EditAddress_Click(Object sender, EventArgs e) { - ListView.SelectedIndexCollection sel = codeListView.SelectedIndices; - Debug.Assert(IsSingleItemSelected()); - int offset = mDisplayList[sel[0]].FileOffset; - - Anattrib attr = mProject.GetAnattrib(offset); - EditAddress dlg = new EditAddress(attr.Address, mProject.CpuDef.MaxAddressValue); - if (dlg.ShowDialog() == DialogResult.OK) { - if (offset == 0 && dlg.Address < 0) { - // Not allowed. The AddressMap will just put it back, which confuses - // the undo operation. - Debug.WriteLine("Not allowed to remove address at offset +000000"); - } else if (attr.Address != dlg.Address) { - Debug.WriteLine("Changing addr at offset +" + offset.ToString("x6") + - " to " + dlg.Address); - - AddressMap addrMap = mProject.AddrMap; - // Get the previous address map entry for this exact offset, if one - // exists. This may be different from the value used as the default - // (attr.Address), which is the address assigned to the offset, in - // the case where no previous mapping existed. - int prevAddress = addrMap.Get(offset); - UndoableChange uc = UndoableChange.CreateAddressChange(offset, - prevAddress, dlg.Address); - ChangeSet cs = new ChangeSet(uc); - ApplyUndoableChanges(cs); - } else { - Debug.WriteLine("No change to address"); - } - } - - dlg.Dispose(); - } - - // Convert generic "edit operand" request to instruction or data edit call. - private void EditInstrDataOperand_Click(object sender, EventArgs e) { - ListView.SelectedIndexCollection sel = codeListView.SelectedIndices; - if (mDisplayList[sel[0]].LineType == DisplayList.Line.Type.Code) { - EditOperand_Click(sender, e); - } else { - EditData_Click(sender, e); - } - } - - private void EditOperand_Click(Object sender, EventArgs e) { - Debug.Assert(IsSingleItemSelected()); - ListView.SelectedIndexCollection sel = codeListView.SelectedIndices; - int offset = mDisplayList[sel[0]].FileOffset; - - EditOperand dlg = new EditOperand(offset, mProject, mOutputFormatter); - - // We'd really like to pass in an indication of what the "default" format actually - // resolved to, but we don't always know. If this offset has a FormatDescriptor, - // we might not have auto-generated the label that would have been used otherwise. - - // We're editing the FormatDescriptor from OperandFormats, not Anattribs; - // the latter may have auto-generated stuff. - if (mProject.OperandFormats.TryGetValue(offset, out FormatDescriptor dfd)) { - dlg.FormatDescriptor = dfd; - } - - dlg.ShowDialog(); - if (dlg.DialogResult == DialogResult.OK) { - ChangeSet cs = new ChangeSet(1); - - if (dlg.FormatDescriptor != dfd && dlg.ShortcutAction != - EditOperand.SymbolShortcutAction.CreateLabelInstead) { - // Note EditOperand returns a null descriptor when the user selects Default. - // This is different from how EditData works, since that has to deal with - // multiple regions. - Debug.WriteLine("Changing " + dfd + " to " + dlg.FormatDescriptor); - UndoableChange uc = UndoableChange.CreateOperandFormatChange(offset, - dfd, dlg.FormatDescriptor); - cs.Add(uc); - } else if (dfd != null && dlg.ShortcutAction == - EditOperand.SymbolShortcutAction.CreateLabelInstead) { - Debug.WriteLine("Removing existing label for CreateLabelInstead"); - UndoableChange uc = UndoableChange.CreateOperandFormatChange(offset, - dfd, null); - cs.Add(uc); - } else { - Debug.WriteLine("No change to format descriptor"); - } - - switch (dlg.ShortcutAction) { - case EditOperand.SymbolShortcutAction.CreateLabelInstead: - case EditOperand.SymbolShortcutAction.CreateLabelAlso: - Debug.Assert(!mProject.UserLabels.ContainsKey(dlg.ShortcutArg)); - Anattrib targetAttr = mProject.GetAnattrib(dlg.ShortcutArg); - Symbol newLabel = new Symbol(dlg.FormatDescriptor.SymbolRef.Label, - targetAttr.Address, Symbol.Source.User, Symbol.Type.LocalOrGlobalAddr); - UndoableChange uc = UndoableChange.CreateLabelChange(dlg.ShortcutArg, - null, newLabel); - cs.Add(uc); - break; - case EditOperand.SymbolShortcutAction.CreateProjectSymbolAlso: - Debug.Assert(!mProject.ProjectProps.ProjectSyms.ContainsKey( - dlg.FormatDescriptor.SymbolRef.Label)); - DefSymbol defSym = new DefSymbol(dlg.FormatDescriptor.SymbolRef.Label, - dlg.ShortcutArg, Symbol.Source.Project, Symbol.Type.ExternalAddr, - FormatDescriptor.SubType.Hex, string.Empty, string.Empty); - ProjectProperties newProps = new ProjectProperties(mProject.ProjectProps); - newProps.ProjectSyms.Add(defSym.Label, defSym); - uc = UndoableChange.CreateProjectPropertiesChange( - mProject.ProjectProps, newProps); - cs.Add(uc); - break; - case EditOperand.SymbolShortcutAction.None: - break; - } - - if (cs.Count != 0) { - ApplyUndoableChanges(cs); - } - } - - dlg.Dispose(); - } - - private void EditData_Click(Object sender, EventArgs e) { - ListView.SelectedIndexCollection sel = codeListView.SelectedIndices; - Debug.Assert(sel.Count > 0); - - EditData dlg = new EditData(mProject.FileData, mProject.SymbolTable, mOutputFormatter); - - TypedRangeSet trs = dlg.Selection = GroupedOffsetSetFromSelected(); - if (trs.Count == 0) { - Debug.Assert(false, "EditData found nothing to edit"); // shouldn't happen - dlg.Dispose(); - return; - } - - // If the first offset has a FormatDescriptor, pass that in as a recommendation - // for the default value in the dialog. This allows single-item editing to work - // as expected. If the format can't be applied to the full selection (which - // would disable that radio button), the dialog will have to pick something - // that does work. - // - // We could pull this out of Anattribs, which would let the dialog reflect the - // auto-format that the user was just looking at. However, I think it's better - // if the dialog shows what's actually there, i.e. no formatting at all. - IEnumerator iter = - (IEnumerator) trs.GetEnumerator(); - iter.MoveNext(); - TypedRangeSet.Tuple firstOffset = iter.Current; - if (mProject.OperandFormats.TryGetValue(firstOffset.Value, out FormatDescriptor dfd)) { - dlg.FirstFormatDescriptor = dfd; - } - - dlg.ShowDialog(); - if (dlg.DialogResult == DialogResult.OK) { - // Merge the changes into the OperandFormats list. We need to remove all - // FormatDescriptors that overlap the selected region. We don't need to - // pass the selection set in, because the dlg.Results list spans the exact - // set of ranges. - // - // If nothing actually changed, don't generate an undo record. - ChangeSet cs = mProject.GenerateFormatMergeSet(dlg.Results); - if (cs.Count != 0) { - ApplyUndoableChanges(cs); - } else { - Debug.WriteLine("No change to data formats"); - } - } - - dlg.Dispose(); - } - - private void FormatSplitAddressTable_Click(object sender, EventArgs e) { - TypedRangeSet trs = GroupedOffsetSetFromSelected(); - if (trs.Count == 0) { - // shouldn't happen - Debug.Assert(false, "FormatSplitAddressTable found nothing to edit"); - return; - } - - FormatSplitAddress dlg = new FormatSplitAddress(mProject, trs, mOutputFormatter); - - dlg.ShowDialog(); - if (dlg.DialogResult == DialogResult.OK) { - // Start with the format descriptors. - ChangeSet cs = mProject.GenerateFormatMergeSet(dlg.NewFormatDescriptors); - - // Add in the user labels. - foreach (KeyValuePair kvp in dlg.NewUserLabels) { - Symbol oldUserValue = null; - if (mProject.UserLabels.ContainsKey(kvp.Key)) { - Debug.Assert(false, "should not be replacing label"); - oldUserValue = mProject.UserLabels[kvp.Key]; - } - UndoableChange uc = UndoableChange.CreateLabelChange(kvp.Key, - oldUserValue, kvp.Value); - cs.Add(uc); - } - - // Apply code hints. - if (dlg.WantCodeHints) { - TypedRangeSet newSet = new TypedRangeSet(); - TypedRangeSet undoSet = new TypedRangeSet(); - - foreach (int offset in dlg.AllTargetOffsets) { - if (!mProject.GetAnattrib(offset).IsInstruction) { - CodeAnalysis.TypeHint oldType = mProject.TypeHints[offset]; - if (oldType == CodeAnalysis.TypeHint.Code) { - continue; // already set - } - undoSet.Add(offset, (int)oldType); - newSet.Add(offset, (int)CodeAnalysis.TypeHint.Code); - } - } - if (newSet.Count != 0) { - cs.Add(UndoableChange.CreateTypeHintChange(undoSet, newSet)); - } - } - - // Finally, apply the change. - if (cs.Count != 0) { - ApplyUndoableChanges(cs); - } else { - Debug.WriteLine("No changes found"); - } - } - - dlg.Dispose(); - } - - private void ToggleSingleBytes_Click(object sender, EventArgs e) { - TypedRangeSet trs = GroupedOffsetSetFromSelected(); - if (trs.Count == 0) { - Debug.Assert(false, "nothing to edit"); // shouldn't happen - return; - } - - // Check the format descriptor of the first selected offset. - int firstOffset = -1; - foreach (TypedRangeSet.Tuple tup in trs) { - firstOffset = tup.Value; - break; - } - Debug.Assert(mProject.GetAnattrib(firstOffset).IsDataStart); - bool toDefault = false; - if (mProject.OperandFormats.TryGetValue(firstOffset, out FormatDescriptor curDfd)) { - if (curDfd.FormatType == FormatDescriptor.Type.NumericLE && - curDfd.FormatSubType == FormatDescriptor.SubType.None && - curDfd.Length == 1) { - // Currently single-byte, toggle to default. - toDefault = true; - } - } - - // Iterate through the selected regions. - SortedList newFmts = new SortedList(); - IEnumerator rngIter = trs.RangeListIterator; - while (rngIter.MoveNext()) { - TypedRangeSet.TypedRange rng = rngIter.Current; - if (toDefault) { - // Create a single REMOVE descriptor that covers the full span. - FormatDescriptor newDfd = FormatDescriptor.Create(rng.High - rng.Low + 1, - FormatDescriptor.Type.REMOVE, FormatDescriptor.SubType.None); - newFmts.Add(rng.Low, newDfd); - } else { - // Add individual single-byte format descriptors for everything. - FormatDescriptor newDfd = FormatDescriptor.Create(1, - FormatDescriptor.Type.NumericLE, FormatDescriptor.SubType.None); - for (int i = rng.Low; i <= rng.High; i++) { - newFmts.Add(i, newDfd); - } - } - } - - ChangeSet cs = mProject.GenerateFormatMergeSet(newFmts); - if (cs.Count != 0) { - ApplyUndoableChanges(cs); - } - } - - private void formatAsWordToolStripMenuItem_Click(object sender, EventArgs e) { - TypedRangeSet trs = GroupedOffsetSetFromSelected(); - if (trs.Count == 0) { - Debug.Assert(false, "nothing to edit"); // shouldn't happen - return; - } - - // If the user has only selected a single byte, we want to add the following byte - // to the selection, then proceed as usual. We can't simply modify the ListView - // selection because the following item might be an auto-detected string or fill, - // and we'd be adding multiple bytes. We have to be careful when grabbing the byte - // in case there's a region-split at that point (e.g. user label or .ORG). - // - // We could expand this to allow multiple regions, each of which is a single byte, - // but we'd need to deal with the case where the user selects two adjacent bytes that - // cross a region boundary. - if (trs.RangeCount == 1) { - // Exactly one range entry. Check its size. - IEnumerator checkIter = trs.RangeListIterator; - checkIter.MoveNext(); - TypedRangeSet.TypedRange rng = checkIter.Current; - if (rng.Low == rng.High && rng.Low < mProject.FileDataLength - 1) { - // Single byte selected. Check to see if it's okay to grab the next byte. - Anattrib thisAttr = mProject.GetAnattrib(rng.Low); - Debug.Assert(thisAttr.DataDescriptor.Length == 1); - - int nextOffset = rng.Low + 1; - Anattrib nextAttr = mProject.GetAnattrib(nextOffset); - // This must match what GroupedOffsetSetFromSelected() does. - if (!mProject.UserLabels.ContainsKey(nextOffset) && - !mProject.HasCommentOrNote(nextOffset) && - thisAttr.Address == nextAttr.Address - 1) { - // Good to go. - Debug.WriteLine("Grabbing second byte from +" + nextOffset.ToString("x6")); - trs.Add(nextOffset, rng.Type); - } - } - } - - // Confirm that every selected byte is a single-byte data item (either set by - // the user or as part of the uncategorized data scan). - foreach (TypedRangeSet.Tuple tup in trs) { - FormatDescriptor dfd = mProject.GetAnattrib(tup.Value).DataDescriptor; - if (dfd != null && dfd.Length != 1) { - Debug.WriteLine("Can't format as word: offset +" + tup.Value.ToString("x6") + - " has len=" + dfd.Length + " (must be 1)"); - string msg = string.Format(Properties.Resources.INVALID_FORMAT_WORD_SEL_NON1, - "\r\n\r\n"); - MessageBox.Show(this, msg, - Properties.Resources.INVALID_FORMAT_WORD_SEL_CAPTION, - MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - } - - // Confirm that, in each region, an even number of bytes are selected. - IEnumerator rngIter = trs.RangeListIterator; - while (rngIter.MoveNext()) { - TypedRangeSet.TypedRange rng = rngIter.Current; - int rangeLen = rng.High - rng.Low + 1; - if ((rangeLen & 0x01) != 0) { - string msg = string.Format(Properties.Resources.INVALID_FORMAT_WORD_SEL_UNEVEN, - trs.RangeCount); - MessageBox.Show(this, msg, - Properties.Resources.INVALID_FORMAT_WORD_SEL_CAPTION, - MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - } - - // Selection is good, generate changes. - SortedList newFmts = new SortedList(); - rngIter.Reset(); - FormatDescriptor newDfd = FormatDescriptor.Create(2, FormatDescriptor.Type.NumericLE, - FormatDescriptor.SubType.None); - while (rngIter.MoveNext()) { - TypedRangeSet.TypedRange rng = rngIter.Current; - for (int i = rng.Low; i <= rng.High; i += 2) { - newFmts.Add(i, newDfd); - } - } - - ChangeSet cs = mProject.GenerateFormatMergeSet(newFmts); - if (cs.Count != 0) { - ApplyUndoableChanges(cs); - } - } - - private void DeleteNoteComment_Click(object sender, EventArgs e) { - Debug.Assert(IsSingleItemSelected()); - ListView.SelectedIndexCollection sel = codeListView.SelectedIndices; - DisplayList.Line line = mDisplayList[sel[0]]; - int offset = line.FileOffset; - - UndoableChange uc; - if (line.LineType == DisplayList.Line.Type.Note) { - if (!mProject.Notes.TryGetValue(offset, out MultiLineComment oldNote)) { - Debug.Assert(false); - return; - } - uc = UndoableChange.CreateNoteChange(offset, oldNote, null); - } else if (line.LineType == DisplayList.Line.Type.LongComment) { - if (!mProject.LongComments.TryGetValue(offset, out MultiLineComment oldComment)) { - Debug.Assert(false); - return; - } - uc = UndoableChange.CreateLongCommentChange(offset, oldComment, null); - } else { - Debug.Assert(false); - return; - } - ChangeSet cs = new ChangeSet(uc); - ApplyUndoableChanges(cs); - } - - private void EditLabel_Click(Object sender, EventArgs e) { - ListView.SelectedIndexCollection sel = codeListView.SelectedIndices; - Debug.Assert(IsSingleItemSelected()); - int offset = mDisplayList[sel[0]].FileOffset; - - Anattrib attr = mProject.GetAnattrib(offset); - EditLabel dlg = new EditLabel(attr.Symbol, attr.Address, mProject.SymbolTable); - - if (dlg.ShowDialog() == DialogResult.OK) { - // NOTE: if label matching is case-insensitive, we want to allow a situation - // where a label is being renamed from "FOO" to "Foo". (We should be able to - // test for object equality on the Symbol.) - if (attr.Symbol != dlg.LabelSym) { - Debug.WriteLine("Changing label at offset +" + offset.ToString("x6")); - - // For undo/redo, we want to update the UserLabels value. This may - // be different from the Anattrib symbol, which can have an auto-generated - // value. - Symbol oldUserValue = null; - if (mProject.UserLabels.ContainsKey(offset)) { - oldUserValue = mProject.UserLabels[offset]; - } - UndoableChange uc = UndoableChange.CreateLabelChange(offset, - oldUserValue, dlg.LabelSym); - ChangeSet cs = new ChangeSet(uc); - ApplyUndoableChanges(cs); - } - } - - dlg.Dispose(); - } - - private void EditStatusFlags_Click(Object sender, EventArgs e) { - ListView.SelectedIndexCollection sel = codeListView.SelectedIndices; - Debug.Assert(IsSingleItemSelected()); - int offset = mDisplayList[sel[0]].FileOffset; - - EditStatusFlags dlg = new EditStatusFlags(mProject.StatusFlagOverrides[offset], - mProject.CpuDef.HasEmuFlag); - if (dlg.ShowDialog() == DialogResult.OK) { - if (dlg.FlagValue != mProject.StatusFlagOverrides[offset]) { - UndoableChange uc = UndoableChange.CreateStatusFlagChange(offset, - mProject.StatusFlagOverrides[offset], dlg.FlagValue); - ChangeSet cs = new ChangeSet(uc); - ApplyUndoableChanges(cs); - } - } - - dlg.Dispose(); - } - - private void EditComment_Click(Object sender, EventArgs e) { - ListView.SelectedIndexCollection sel = codeListView.SelectedIndices; - Debug.Assert(IsSingleItemSelected()); - int offset = mDisplayList[sel[0]].FileOffset; - - string oldComment = mProject.Comments[offset]; - EditComment dlg = new EditComment(oldComment); - if (dlg.ShowDialog() == DialogResult.OK) { - if (!oldComment.Equals(dlg.Comment)) { - Debug.WriteLine("Changing comment at +" + offset.ToString("x6")); - - UndoableChange uc = UndoableChange.CreateCommentChange(offset, - oldComment, dlg.Comment); - ChangeSet cs = new ChangeSet(uc); - ApplyUndoableChanges(cs); - } - } - - dlg.Dispose(); - } - - private void EditLongComment_Click(Object sender, EventArgs e) { - ListView.SelectedIndexCollection sel = codeListView.SelectedIndices; - Debug.Assert(IsSingleItemSelected()); - EditLongComment(mDisplayList[sel[0]].FileOffset); - } - - private void editHeaderCommentToolStripMenuItem_Click(object sender, EventArgs e) { - EditLongComment(DisplayList.Line.HEADER_COMMENT_OFFSET); - } - - private void EditLongComment(int offset) { - EditLongComment dlg = new EditLongComment(mOutputFormatter); - if (mProject.LongComments.TryGetValue(offset, out MultiLineComment oldComment)) { - dlg.LongComment = oldComment; - } - dlg.ShowDialog(); - - if (dlg.DialogResult == DialogResult.OK) { - MultiLineComment newComment = dlg.LongComment; - if (oldComment != newComment) { - Debug.WriteLine("Changing long comment at +" + offset.ToString("x6")); - - UndoableChange uc = UndoableChange.CreateLongCommentChange(offset, - oldComment, newComment); - ChangeSet cs = new ChangeSet(uc); - ApplyUndoableChanges(cs); - } - } - - dlg.Dispose(); - } - - private void EditNote_Click(Object sender, EventArgs e) { - ListView.SelectedIndexCollection sel = codeListView.SelectedIndices; - Debug.Assert(IsSingleItemSelected()); - int offset = mDisplayList[sel[0]].FileOffset; - - EditNote dlg = new EditNote(); - if (mProject.Notes.TryGetValue(offset, out MultiLineComment oldNote)) { - dlg.Note = oldNote; - } - dlg.ShowDialog(); - - if (dlg.DialogResult == DialogResult.OK) { - MultiLineComment newNote = dlg.Note; - if (oldNote != newNote) { - Debug.WriteLine("Changing note at +" + offset.ToString("x6")); - - UndoableChange uc = UndoableChange.CreateNoteChange(offset, - oldNote, newNote); - ChangeSet cs = new ChangeSet(uc); - ApplyUndoableChanges(cs); - } - } - - dlg.Dispose(); - } - - private void EditProjectSymbol_Click(object sender, EventArgs e) { - Debug.Assert(IsSingleItemSelected()); - ListView.SelectedIndexCollection sel = codeListView.SelectedIndices; - DisplayList.Line line = mDisplayList[sel[0]]; - int symIndex = DisplayList.DefSymIndexFromOffset(line.FileOffset); - DefSymbol origDefSym = mProject.ActiveDefSymbolList[symIndex]; - Debug.Assert(origDefSym.SymbolSource == Symbol.Source.Project); - - EditDefSymbol dlg = new EditDefSymbol(mOutputFormatter, - mProject.ProjectProps.ProjectSyms); - dlg.DefSym = origDefSym; - if (dlg.ShowDialog() == DialogResult.OK) { - ProjectProperties newProps = new ProjectProperties(mProject.ProjectProps); - newProps.ProjectSyms.Remove(origDefSym.Label); - newProps.ProjectSyms[dlg.DefSym.Label] = dlg.DefSym; - - UndoableChange uc = UndoableChange.CreateProjectPropertiesChange( - mProject.ProjectProps, newProps); - ChangeSet cs = new ChangeSet(uc); - ApplyUndoableChanges(cs); - } - dlg.Dispose(); - } - - private void MarkAsCode_Click(Object sender, EventArgs e) { - MarkAsType(CodeAnalysis.TypeHint.Code, true); - } - private void MarkAsData_Click(Object sender, EventArgs e) { - MarkAsType(CodeAnalysis.TypeHint.Data, true); - } - private void MarkAsInlineData_Click(Object sender, EventArgs e) { - MarkAsType(CodeAnalysis.TypeHint.InlineData, false); - } - private void MarkAsNoHint_Click(Object sender, EventArgs e) { - MarkAsType(CodeAnalysis.TypeHint.NoHint, false); - } - private void MarkAsType(CodeAnalysis.TypeHint hint, bool firstByteOnly) { - RangeSet sel; - - if (firstByteOnly) { - sel = new RangeSet(); - foreach (int index in codeListView.SelectedIndices) { - int offset = mDisplayList[index].FileOffset; - if (offset >= 0) { - // Not interested in the header stuff for hinting. - sel.Add(offset); - } - } - } else { - sel = OffsetSetFromSelected(); - } - - TypedRangeSet newSet = new TypedRangeSet(); - TypedRangeSet undoSet = new TypedRangeSet(); - - foreach (int offset in sel) { - if (offset < 0) { - // header comment - continue; - } - CodeAnalysis.TypeHint oldType = mProject.TypeHints[offset]; - if (oldType == hint) { - // no change, don't add to set - continue; - } - undoSet.Add(offset, (int)oldType); - newSet.Add(offset, (int)hint); - } - if (newSet.Count == 0) { - Debug.WriteLine("No changes found (" + hint + ", " + sel.Count + " offsets)"); - return; - } - - UndoableChange uc = UndoableChange.CreateTypeHintChange(undoSet, newSet); - ChangeSet cs = new ChangeSet(uc); - - ApplyUndoableChanges(cs); - } - - private void ShowHexDump_Click(object sender, EventArgs e) { - if (mHexDumpDialog == null) { - // Create and show modeless dialog. This one is "always on top" by default, - // to allow the user to click around to various points. - mHexDumpDialog = new Tools.HexDumpViewer(mProject.FileData, mOutputFormatter); - mHexDumpDialog.OnWindowClosing += (sender1, e1) => { - Debug.WriteLine("Hex dump dialog closed"); - //showHexDumpToolStripMenuItem.Checked = false; - mHexDumpDialog = null; - }; - mHexDumpDialog.TopMost = true; - mHexDumpDialog.Show(); - //showHexDumpToolStripMenuItem.Checked = true; - } - - // Bring it to the front of the window stack. This also transfers focus to the - // window. - mHexDumpDialog.BringToFront(); - - // Set the dialog's position. - ListView.SelectedIndexCollection sel = codeListView.SelectedIndices; - if (sel.Count > 0) { - int firstIndex = sel[0]; - int lastIndex = sel[sel.Count - 1]; - // offsets can be < 0 if they've selected EQU statements - int firstOffset = Math.Max(0, mDisplayList[firstIndex].FileOffset); - int lastOffset = Math.Max(firstOffset, mDisplayList[lastIndex].FileOffset + - mDisplayList[lastIndex].OffsetSpan - 1); - mHexDumpDialog.ShowOffsetRange(firstOffset, lastOffset); - } - } - - private void aSCIIChartToolStripMenuItem_Click(object sender, EventArgs e) { - // Show or hide the modeless dialog. - if (mAsciiChartDialog == null) { - Tools.AsciiChart dlg = new Tools.AsciiChart(); - dlg.OnWindowClosing += (sender1, e1) => { - Debug.WriteLine("ASCII chart closed"); - aSCIIChartToolStripMenuItem.Checked = false; - mAsciiChartDialog = null; - }; - dlg.Show(); - mAsciiChartDialog = dlg; - aSCIIChartToolStripMenuItem.Checked = true; - } else { - // Ask the dialog to close. Do the cleanup in the event. - mAsciiChartDialog.Close(); - } - - } - - /// - /// Converts the ListView's selected items into a set of offsets. If a line - /// spans multiple offsets (e.g. a 3-byte instruction), offsets for every - /// byte are included. - /// - /// Boundaries such as labels and address changes are ignored. - /// - /// RangeSet with all offsets. - private RangeSet OffsetSetFromSelected() { - RangeSet rs = new RangeSet(); - - foreach (int index in codeListView.SelectedIndices) { - int offset = mDisplayList[index].FileOffset; - - // Mark every byte of an instruction or multi-byte data item -- - // everything that is represented by the line the user selected. - int len; - if (offset >= 0) { - len = mProject.GetAnattrib(offset).Length; - } else { - // header area - len = 1; - } - Debug.Assert(len > 0); - for (int i = offset; i < offset + len; i++) { - rs.Add(i); - } - } - return rs; - } - - /// - /// Converts the ListView's selected items into a set of offsets. If a line - /// spans multiple offsets (e.g. a 3-byte instruction), offsets for every - /// byte are included. - /// - /// Contiguous regions with user labels or address changes are split into - /// independent regions by using a serial number for the range type. Same for - /// long comments and notes. - /// - /// We don't split based on existing data format items. That would make it impossible - /// to convert from (say) a collection of single bytes to a collection of double bytes - /// or a string. It should not be possible to select part of a formatted section, - /// unless the user has been playing weird games with type hints to get overlapping - /// format descriptors. - /// - /// TypedRangeSet with all offsets. - private TypedRangeSet GroupedOffsetSetFromSelected() { - TypedRangeSet rs = new TypedRangeSet(); - int groupNum = 0; - int expectedAddr = -1; - - bool thing = false; - if (thing) { - DateTime nowWhen = DateTime.Now; - int selCount = 0; - for (int i = 0; i < mDisplayList.Count; i++) { - ListViewItem lvi = codeListView.Items[i]; - selCount += lvi.Selected ? 1 : 0; - } - Debug.WriteLine("Sel count (" + selCount + ") took " + - (DateTime.Now - nowWhen).TotalMilliseconds + " ms"); - } - - DateTime startWhen = DateTime.Now; - int prevOffset = -1; - foreach (int index in codeListView.SelectedIndices) { - // Don't add an offset to the set if the only part of it that is selected - // is a directive or blank line. We only care about file offsets, so skip - // anything that isn't code or data. - if (!mDisplayList[index].IsCodeOrData) { - continue; - } - - int offset = mDisplayList[index].FileOffset; - if (offset == prevOffset) { - // This is a continuation of a multi-line item like a string. We've - // already accounted for all bytes associated with this offset. - continue; - } - Anattrib attr = mProject.GetAnattrib(offset); - - if (expectedAddr == -1) { - expectedAddr = attr.Address; - } - // Check for user labels. - if (mProject.UserLabels.ContainsKey(offset)) { - //if (mProject.GetAnattrib(offset).Symbol != null) { - // We consider auto labels when splitting regions for the data analysis, - // but I don't think we want to take them into account here. The specific - // example that threw me was loading a 16-bit value from an address table. - // The code does "LDA table,X / STA / LDA table+1,X / STA", which puts auto - // labels at the first two addresses -- splitting the region. That's good - // for the uncategorized data analyzer, but very annoying if you want to - // slap a 16-bit numeric format on all entries in a table. - groupNum++; - } else if (mProject.HasCommentOrNote(offset)) { - // Don't carry across a long comment or note. - groupNum++; - } else if (attr.Address != expectedAddr) { - // For a contiguous selection, this should only happen if there's a .ORG - // address change. For non-contiguous selection this is expected. In the - // latter case, incrementing the group number is unnecessary but harmless. - Debug.WriteLine("Address break: " + attr.Address + " vs. " + expectedAddr); - //Debug.Assert(mProject.AddrMap.Get(offset) >= 0); - - expectedAddr = attr.Address; - groupNum++; - } - - // Mark every byte of an instruction or multi-byte data item -- - // everything that is represented by the line the user selected. Control - // statements and blank lines aren't relevant here, as we only care about - // file offsets. - int len = mDisplayList[index].OffsetSpan; // attr.Length; - Debug.Assert(len > 0); - for (int i = offset; i < offset + len; i++) { - rs.Add(i, groupNum); - } - // Advance the address. - expectedAddr += len; - - prevOffset = offset; - } - Debug.WriteLine("Offset selection conv took " + - (DateTime.Now - startWhen).TotalMilliseconds + " ms"); - return rs; - } - - #endregion // Main window UI event handlers - - - #region codeListView OwnerDraw implementation - - private enum ColumnIndex { - Offset = 0, Address, Bytes, Flags, Attributes, Label, Opcode, Operand, Comment - } - - /// - /// Handy class for collecting column widths for the code list view. - /// - public class CodeListColumnWidths { - public const int NUM_COLUMNS = (int)ColumnIndex.Comment + 1; - - /// - /// Primary storage for column widths. - /// - public int[] Width { get; private set; } - - public int Offset { - get { return Width[0]; } - set { Width[0] = value; } - } - public int Address { - get { return Width[1]; } - set { Width[1] = value; } - } - public int Bytes { - get { return Width[2]; } - set { Width[2] = value; } - } - public int Flags { - get { return Width[3]; } - set { Width[3] = value; } - } - public int Attributes { - get { return Width[4]; } - set { Width[4] = value; } - } - public int Label { - get { return Width[5]; } - set { Width[5] = value; } - } - public int Opcode { - get { return Width[6]; } - set { Width[6] = value; } - } - public int Operand { - get { return Width[7]; } - set { Width[7] = value; } - } - public int Comment { - get { return Width[8]; } - set { Width[8] = value; } - } - - public CodeListColumnWidths() { - Width = new int[NUM_COLUMNS]; - } - - public string Serialize() { - StringBuilder sb = new StringBuilder(64); - sb.Append("cw"); - for (int i = 0; i < NUM_COLUMNS; i++) { - sb.Append(','); - sb.Append(Width[i]); - } - return sb.ToString(); - } - - public static CodeListColumnWidths Deserialize(string cereal) { - CodeListColumnWidths widths = new CodeListColumnWidths(); - string[] splitted = cereal.Split(','); - if (splitted.Length != NUM_COLUMNS + 1) { - Debug.WriteLine("Column width parse failed: wrong count: " + splitted.Length); - return null; - } - if (splitted[0] != "cw") { - Debug.WriteLine("Column width parse failed: bad magic: " + splitted[0]); - return null; - } - try { - for (int i = 0; i < NUM_COLUMNS; i++) { - widths.Width[i] = int.Parse(splitted[i + 1]); - } - } catch (Exception ex) { - Debug.WriteLine("Column width parse failed: " + ex.Message); - return null; - } - return widths; - } - - public override string ToString() { - return Serialize(); - } - } - - /// - /// Gets the default column widths for the code list view, based on the currently - /// configured font. - /// - /// Column width set. - public CodeListColumnWidths GetDefaultCodeListColumnWidths() { - CodeListColumnWidths widths = new CodeListColumnWidths(); - Graphics gfx = codeListView.CreateGraphics(); - widths.Offset = GetCodeListStringWidth(gfx, "X+000000"); - widths.Address = GetCodeListStringWidth(gfx, "X00/0000"); - widths.Bytes = GetCodeListStringWidth(gfx, "X00000000"); - widths.Flags = GetCodeListStringWidth(gfx, "X00000000 0"); - widths.Attributes = GetCodeListStringWidth(gfx, "X######"); - widths.Label = GetCodeListStringWidth(gfx, "XMMMMMMMMM"); - widths.Opcode = GetCodeListStringWidth(gfx, "XMMMMMMM"); - widths.Operand = GetCodeListStringWidth(gfx, "XMMMMMMMMMMMMM"); - widths.Comment = GetCodeListStringWidth(gfx, - "XMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM"); - return widths; - } - private int GetCodeListStringWidth(Graphics gfx, string str) { - SizeF size = gfx.MeasureString(str, codeListView.Font); - return (int)Math.Round(size.Width); - } - - /// - /// Saves the code list column widths into AppSettings. - /// - /// - public void SerializeCodeListColumnWidths() { - CodeListColumnWidths widths = new CodeListColumnWidths(); - for (int i = 0; i < CodeListColumnWidths.NUM_COLUMNS; i++) { - widths.Width[i] = codeListView.Columns[i].Width; - } - - string cereal = widths.Serialize(); - AppSettings.Global.SetString(AppSettings.CDLV_COL_WIDTHS, cereal); - } - - /// - /// Configures the column widths. - /// - private void SetCodeListHeaderWidths(CodeListColumnWidths widths) { - Debug.WriteLine("Setting column widths: " + widths); - for (int i = 0; i < CodeListColumnWidths.NUM_COLUMNS; i++) { - codeListView.Columns[i].Width = widths.Width[i]; - } - } - - private void codeListView_ColumnWidthChanged(object sender, - ColumnWidthChangedEventArgs e) { - AppSettings.Global.Dirty = true; - } - - private void codeListView_DrawColumnHeader(object sender, - DrawListViewColumnHeaderEventArgs e) { - ListView lv = e.Header.ListView; - string text = lv.Columns[e.ColumnIndex].Text; - - // Adjust rect to match standard control for 10pt fonts, and - // reserve a couple pixels at the far right end for the separator. - Rectangle rect = new Rectangle(e.Bounds.X + 3, e.Bounds.Y + 4, - e.Bounds.Width - 4, e.Bounds.Height - 4); - TextFormatFlags flags = TextFormatFlags.Left | TextFormatFlags.EndEllipsis | - TextFormatFlags.SingleLine; - - TextRenderer.DrawText(e.Graphics, text, lv.Font, rect, lv.ForeColor, flags); - - Pen pen = new Pen(Color.LightGray); - //Pen pen = new Pen(Color.Blue); - e.Graphics.DrawLine(pen, e.Bounds.X + e.Bounds.Width - 1, e.Bounds.Y, - e.Bounds.X + e.Bounds.Width - 1, e.Bounds.Y + e.Bounds.Height); - } - - private void codeListView_DrawItem(object sender, - DrawListViewItemEventArgs e) { - // Only draw the full-line items here. Do not draw them later. - - DisplayList.Line line = mDisplayList[e.ItemIndex]; - if (line.LineType != DisplayList.Line.Type.LongComment && - line.LineType != DisplayList.Line.Type.Note) { - return; - } - - // Column 5 is the label. We put long comments and notes there. - int leftColsWidth = 0; - for (int i = 0; i < (int)ColumnIndex.Label; i++) { - leftColsWidth += e.Item.ListView.Columns[i].Width; - } - - // No sub-items, just one long comment. - ListView lv = e.Item.ListView; - ListViewItem lvi = e.Item; - - // Set colors based on selection and focus. - if (lvi.Selected && lv.Focused) { - lvi.BackColor = SystemColors.Highlight; - lvi.ForeColor = lv.BackColor; - } else if (e.Item.Selected && !lv.Focused) { - lvi.BackColor = SystemColors.Control; - lvi.ForeColor = lv.ForeColor; - } else { - lvi.ForeColor = lv.ForeColor; - if (line.BackgroundColor.ToArgb() == 0) { - lvi.BackColor = lv.BackColor; - } else { - // Highlight the entire line. - lvi.BackColor = line.BackgroundColor; - } - } - - e.DrawBackground(); - - if ((e.State & ListViewItemStates.Selected) != 0) { - e.DrawFocusRectangle(); - } - - Rectangle rect = new Rectangle(e.Bounds.X + 3 + leftColsWidth, e.Bounds.Y + 2, - e.Bounds.Width - 3 - leftColsWidth, e.Bounds.Height - 2); - - TextFormatFlags flags = TextFormatFlags.Left | TextFormatFlags.EndEllipsis | - TextFormatFlags.SingleLine; - - Font font = lv.Font; - TextRenderer.DrawText(e.Graphics, lvi.Text, font, rect, - lvi.ForeColor, flags); - } - - private void codeListView_DrawSubItem(object sender, - DrawListViewSubItemEventArgs e) { - // Draw the multi-column items here. - - ListView lv = e.Item.ListView; - ListViewItem lvi = e.Item; - - DisplayList.Line.Type lineType = mDisplayList[e.ItemIndex].LineType; - if (lineType == DisplayList.Line.Type.LongComment || - lineType == DisplayList.Line.Type.Note) { - return; - } - - // Set colors based on selection and focus. - if (lvi.Selected && lv.Focused) { - e.SubItem.BackColor = SystemColors.Highlight; - e.SubItem.ForeColor = lv.BackColor; - } else if (lvi.Selected && !lv.Focused) { - e.SubItem.BackColor = SystemColors.Control; - e.SubItem.ForeColor = lv.ForeColor; - } else { - if (e.ItemIndex == mTargetHighlightIndex && - (e.ColumnIndex == (int)ColumnIndex.Address || - e.ColumnIndex == (int)ColumnIndex.Label) && - !string.IsNullOrEmpty(e.SubItem.Text)) { - e.SubItem.BackColor = Color.LightBlue; - } else { - e.SubItem.BackColor = lv.BackColor; - } - e.SubItem.ForeColor = lv.ForeColor; - } - - e.DrawBackground(); - - // Shift the text so it lines up with the standard control at 10pts. - // Not strictly necessary, and possibly unwise, since the behavior seems - // to change for larger fonts. - Rectangle rect = new Rectangle(e.Bounds.X + 3, e.Bounds.Y + 2, - e.Bounds.Width - 3, e.Bounds.Height - 2); - - TextFormatFlags flags = TextFormatFlags.Left | TextFormatFlags.EndEllipsis | - TextFormatFlags.SingleLine; - - Font font = lv.Font; - - TextRenderer.DrawText(e.Graphics, e.SubItem.Text, font, rect, - e.SubItem.ForeColor, flags); - - // Draw the focus rectangle. It's annoying that we have to draw it for every - // sub-item even with FullRowSelect, but DrawItem always happens first, and - // there's no equivalent at the end. (It's unclear how useful the focus rect - // actually is, but it's part of the standard dialog behavior.) - if (lv.FullRowSelect) { - e.DrawFocusRectangle(e.Item.Bounds); - } else { - e.DrawFocusRectangle(e.Bounds); - } - } - #endregion // codeListView OwnerDraw implementation - - - #region codeListView Virtual - // For a half-megabyte file, the ListViewItem creation could take 40+ seconds. - - // Internal array for holding temporary state. Avoids frequent allocations. - private ListViewItem.ListViewSubItem[] mSubArray = - new ListViewItem.ListViewSubItem[CodeListColumnWidths.NUM_COLUMNS - 1]; - - // Array of blank sub-items, for entries that span multiple columns. The - // virtual mode requires fully populating sub-items. - private static ListViewItem.ListViewSubItem[] mBlankArray = - new ListViewItem.ListViewSubItem[CodeListColumnWidths.NUM_COLUMNS - 1] { - new ListViewItem.ListViewSubItem(), - new ListViewItem.ListViewSubItem(), - new ListViewItem.ListViewSubItem(), - new ListViewItem.ListViewSubItem(), - new ListViewItem.ListViewSubItem(), - new ListViewItem.ListViewSubItem(), - new ListViewItem.ListViewSubItem(), - new ListViewItem.ListViewSubItem() - }; - - /// - /// Cache of previously-constructed ListViewItems. The ListView will request items - /// continuously as they are moused-over, so this is fairly important. - /// - private ListViewItem[] mItemCache; - private int mItemCacheFirst; - - /// - /// Clears the contents of the ListViewItem cache. Do this whenever the backing - /// store is updated. - /// - private void ClearCodeListViewCache() { - mItemCache = null; - mItemCacheFirst = -1; - } - - //private ListViewItem mDummy; - private void codeListView_RetrieveVirtualItem(object sender, - RetrieveVirtualItemEventArgs e) { - //Debug.WriteLine("Retrieve " + e.ItemIndex); - //if (mDummy == null) { - // mDummy = new ListViewItem(); - // mDummy.Text = "dummy"; - // mDummy.SubItems.AddRange(mBlankArray); - //} - //e.Item = mDummy; - //return; - - // Is item cached? - if (mItemCache != null && e.ItemIndex >= mItemCacheFirst && - e.ItemIndex < mItemCacheFirst + mItemCache.Length) { - // Yes, return existing item. - e.Item = mItemCache[e.ItemIndex - mItemCacheFirst]; - } else { - // No, create item. - e.Item = CreateCodeListViewItem(e.ItemIndex); - } - } - - private void codeListView_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs e) { - if (mItemCache != null && e.StartIndex >= mItemCacheFirst && - e.EndIndex <= mItemCacheFirst + mItemCache.Length) { - // Already have this span cached. - //Debug.WriteLine("LVICache " + e.StartIndex + " - " + e.EndIndex + - // " already cached"); - return; - } - - //Debug.WriteLine("LVICache " + e.StartIndex + " - " + e.EndIndex + " generating"); - mItemCacheFirst = e.StartIndex; - int len = e.EndIndex - e.StartIndex + 1; // end is inclusive - mItemCache = new ListViewItem[len]; - for (int i = 0; i < len; i++) { - mItemCache[i] = CreateCodeListViewItem(e.StartIndex + i); - } - } - - private ListViewItem CreateCodeListViewItem(int index) { - DisplayList.Line line = mDisplayList[index]; - DisplayList.FormattedParts parts = mDisplayList.GetFormattedParts(index); - ListViewItem lvi = new ListViewItem(); - - if (line.LineType == DisplayList.Line.Type.Blank) { - // no sub-items - lvi.Text = String.Empty; - lvi.SubItems.AddRange(mBlankArray); - } else if (line.LineType == DisplayList.Line.Type.LongComment || - line.LineType == DisplayList.Line.Type.Note) { - lvi.Text = parts.Comment.Replace("&", "&&"); - lvi.SubItems.AddRange(mBlankArray); - } else { - lvi.Text = parts.Offset; - mSubArray[0] = new ListViewItem.ListViewSubItem(lvi, parts.Addr); - mSubArray[1] = new ListViewItem.ListViewSubItem(lvi, parts.Bytes); - mSubArray[2] = new ListViewItem.ListViewSubItem(lvi, parts.Flags); - mSubArray[3] = new ListViewItem.ListViewSubItem(lvi, parts.Attr); - mSubArray[4] = new ListViewItem.ListViewSubItem(lvi, parts.Label); - mSubArray[5] = new ListViewItem.ListViewSubItem(lvi, parts.Opcode); - mSubArray[6] = new ListViewItem.ListViewSubItem(lvi, - parts.Operand.Replace("&", "&&")); - mSubArray[7] = new ListViewItem.ListViewSubItem(lvi, parts.Comment == null ? - string.Empty : parts.Comment.Replace("&", "&&")); - Debug.Assert(CodeListColumnWidths.NUM_COLUMNS - 1 == 8); - lvi.SubItems.AddRange(mSubArray); - } - return lvi; - } - - #endregion codeListView Virtual - - - #region symbolListView Virtual and UI handling - - /// - /// Cache of previously-constructed ListViewItems. The ListView will request items - /// continuously as they are moused-over, so this is fairly important. - /// - private ListViewItem[] mSymbolItemCache; - private int mSymbolItemCacheFirst; - - // Temporary array, used during ListViewItem creation. - private ListViewItem.ListViewSubItem[] mSymbolSubArray = - new ListViewItem.ListViewSubItem[2]; - - private string[] mSymbolColumnHeaderNames; - - private void InitSymbolListView() { - // Save a copy of the column header names as entered in the designer. - mSymbolColumnHeaderNames = new string[3]; - mSymbolColumnHeaderNames[0] = symbolTypeColumnHeader.Text; - mSymbolColumnHeaderNames[1] = symbolValueColumnHeader.Text; - mSymbolColumnHeaderNames[2] = symbolNameColumnHeader.Text; - SetSymbolColumnHeaders(); - } - - /// - /// Clears the contents of the ListViewItem cache. Do this whenever the backing - /// store is updated. - /// - private void ClearSymbolListViewCache() { - mSymbolItemCache = null; - mSymbolItemCacheFirst = -1; - } - - private void symbolListView_RetrieveVirtualItem(object sender, - RetrieveVirtualItemEventArgs e) { - // Is item cached? - if (mSymbolItemCache != null && e.ItemIndex >= mSymbolItemCacheFirst && - e.ItemIndex < mSymbolItemCacheFirst + mSymbolItemCache.Length) { - // Yes, return existing item. - e.Item = mSymbolItemCache[e.ItemIndex - mSymbolItemCacheFirst]; - } else { - // No, create item. - e.Item = CreateSymbolListViewItem(e.ItemIndex); - } - } - - private void symbolListView_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs e) { - if (mSymbolItemCache != null && e.StartIndex >= mSymbolItemCacheFirst && - e.EndIndex <= mSymbolItemCacheFirst + mSymbolItemCache.Length) { - // Already have this span cached. - //Debug.WriteLine("LVICache " + e.StartIndex + " - " + e.EndIndex + - // " already cached"); - return; - } - - //Debug.WriteLine("LVICache " + e.StartIndex + " - " + e.EndIndex + " generating"); - mSymbolItemCacheFirst = e.StartIndex; - int len = e.EndIndex - e.StartIndex + 1; // end is inclusive - mSymbolItemCache = new ListViewItem[len]; - for (int i = 0; i < len; i++) { - mSymbolItemCache[i] = CreateSymbolListViewItem(e.StartIndex + i); - } - } - - private ListViewItem CreateSymbolListViewItem(int index) { - Symbol sym = mSymbolSubset.GetSubsetItem(index); - ListViewItem lvi = new ListViewItem(); - - lvi.Text = sym.SourceTypeString; - mSymbolSubArray[0] = new ListViewItem.ListViewSubItem(lvi, - mOutputFormatter.FormatHexValue(sym.Value, 0)); - mSymbolSubArray[1] = new ListViewItem.ListViewSubItem(lvi, sym.Label); - lvi.SubItems.AddRange(mSymbolSubArray); - return lvi; - } - - private void InvalidateSymbolListView() { - symbolListView.BeginUpdate(); - ClearSymbolListViewCache(); - symbolListView.VirtualListSize = mSymbolSubset.GetSubsetCount(); - symbolListView.EndUpdate(); - } - - // Column header click. Update sort. - private void symbolListView_ColumnClick(object sender, ColumnClickEventArgs e) { - //Debug.WriteLine("Click on " + e.Column); - - SymbolTableSubset.SortCol prevCol = mSymbolSubset.SortColumn; - // SortCol happens to match the ListView column numbers, so just cast it - SymbolTableSubset.SortCol clickCol = (SymbolTableSubset.SortCol)e.Column; - - if (prevCol == clickCol) { - mSymbolSubset.SortAscending = !mSymbolSubset.SortAscending; - } else { - mSymbolSubset.SortColumn = clickCol; - } - - SetSymbolColumnHeaders(); - InvalidateSymbolListView(); - } - - private void symbolListView_MouseDoubleClick(object sender, MouseEventArgs e) { - ListViewHitTestInfo info = symbolListView.HitTest(e.X, e.Y); - int row = info.Item.Index; - Symbol sym = mSymbolSubset.GetSubsetItem(row); - - if (sym.IsInternalLabel) { - int offset = mProject.FindLabelOffsetByName(sym.Label); - if (offset >= 0) { - GoToOffset(offset, false, true); - codeListView.Focus(); - } else { - Debug.WriteLine("DClick symbol: " + sym + ": label not found"); - } - } else { - Debug.WriteLine("DClick symbol: " + sym + ": not label"); - } - } - - /// - /// Sets the ListView column headers, adding a glyph to show sort direction. - /// Sadly, this is significantly easier than adding a graphic. - /// - private void SetSymbolColumnHeaders() { - SymbolTableSubset.SortCol sortCol = mSymbolSubset.SortColumn; - - // Pick a pair of symbols. - string sortStr = mSymbolSubset.SortAscending ? - "\u25b2" : "\u25bc"; // BLACK UP-POINTING TRIANGLE and DOWN- - //"\u2191" : "\u2193"; // UPWARDS ARROW and DOWNWARDS ARROW - //"\u2b06" : "\u2b07"; // UPWARDS BLACK ARROW and DOWNWARDS BLACK ARROW - //"\u234d" : "\u2354"; // APL FUNCTIONAL SYMBOL QUAD DELTA and ...QUAD DEL - - symbolTypeColumnHeader.Text = - (sortCol == SymbolTableSubset.SortCol.Type ? sortStr : "") + - mSymbolColumnHeaderNames[0]; - symbolValueColumnHeader.Text = - (sortCol == SymbolTableSubset.SortCol.Value ? sortStr : "") + - mSymbolColumnHeaderNames[1]; - symbolNameColumnHeader.Text = - (sortCol == SymbolTableSubset.SortCol.Name ? sortStr : "") + - mSymbolColumnHeaderNames[2]; - } - - private void symbolListView_ColumnWidthChanged(object sender, - ColumnWidthChangedEventArgs e) { - UpdateLastSymbolColumnWidth(); - } - private void symbolListView_SizeChanged(object sender, EventArgs e) { - UpdateLastSymbolColumnWidth(); - } - private void UpdateLastSymbolColumnWidth() { -#if false - const int ADJ = 4; // fudge factor needed to prevent horizontal scrollbar - int leftWidths = symbolListView.Columns[0].Width + symbolListView.Columns[1].Width; - int lastWidth = symbolListView.Size.Width - leftWidths - ADJ; - if (lastWidth < 0) { - lastWidth = 0; - } - symbolListView.Columns[2].Width = lastWidth; -#endif - AppSettings.Global.Dirty = true; - } - - private void SerializeSymbolColumnWidths() { - int[] values = new int[] { - symbolListView.Columns[0].Width, - symbolListView.Columns[1].Width, - symbolListView.Columns[2].Width - }; - AppSettings.Global.SetString(AppSettings.SYMWIN_COL_WIDTHS, - TextUtil.SerializeIntArray(values)); - } - - private void DeserializeSymbolColumnWidths() { - string str = AppSettings.Global.GetString(AppSettings.SYMWIN_COL_WIDTHS, null); - if (!string.IsNullOrEmpty(str)) { - int[] values = TextUtil.DeserializeIntArray(str); - if (values.Length == symbolListView.Columns.Count) { - for (int i = 0; i < values.Length; i++) { - symbolListView.Columns[i].Width = values[i]; - } - } - } - // The updates should automatically trigger the last-column-width adjuster. - } - - private void symbolUserCheckBox_CheckedChanged(object sender, EventArgs e) { - mSymbolSubset.IncludeUserLabels = symbolUserCheckBox.Checked; - InvalidateSymbolListView(); - } - private void symbolProjectCheckBox_CheckedChanged(object sender, EventArgs e) { - mSymbolSubset.IncludeProjectSymbols = symbolProjectCheckBox.Checked; - InvalidateSymbolListView(); - } - private void symbolPlatformCheckBox_CheckedChanged(object sender, EventArgs e) { - mSymbolSubset.IncludePlatformSymbols = symbolPlatformCheckBox.Checked; - InvalidateSymbolListView(); - } - private void symbolAutoCheckBox_CheckedChanged(object sender, EventArgs e) { - mSymbolSubset.IncludeAutoLabels = symbolAutoCheckBox.Checked; - InvalidateSymbolListView(); - } - private void symbolAddrCheckBox_CheckedChanged(object sender, EventArgs e) { - mSymbolSubset.IncludeAddresses = symbolAddressCheckBox.Checked; - InvalidateSymbolListView(); - } - private void symbolConstantCheckBox_CheckedChanged(object sender, EventArgs e) { - mSymbolSubset.IncludeConstants = symbolConstantCheckBox.Checked; - InvalidateSymbolListView(); - } - #endregion symbolListView Virtual and UI handling - - - #region referencesListView stuff - - private ListViewItem.ListViewSubItem[] mXrefSubArray = - new ListViewItem.ListViewSubItem[2]; - - /// - /// Updates the "references" view to reflect the current selection. - /// - /// The number of references to any given address should be relatively small, and - /// won't change without a data refresh, so there's no need for virtual items - /// or output caching. - /// - private void UpdateReferenceView() { - referencesListView.BeginUpdate(); - try { - referencesListView.Items.Clear(); - - // Determine which line is selected. If it's not code, data, or an EQU - // directive, there's no data to populate. - ListView.SelectedIndexCollection sel = codeListView.SelectedIndices; - if (sel.Count != 1) { - return; - } - DisplayList.Line.Type type = mDisplayList[sel[0]].LineType; - if (type != DisplayList.Line.Type.Code && - type != DisplayList.Line.Type.Data && - type != DisplayList.Line.Type.EquDirective) { - // Code, data, and platform symbol EQUs have xrefs. - return; - } - - // Find the appropriate xref set. - int offset = mDisplayList[sel[0]].FileOffset; - XrefSet xrefs; - if (offset < 0) { - int index = DisplayList.DefSymIndexFromOffset(offset); - DefSymbol defSym = mProject.ActiveDefSymbolList[index]; - xrefs = defSym.Xrefs; - } else { - xrefs = mProject.GetXrefSet(offset); - } - if (xrefs == null || xrefs.Count == 0) { - return; - } - - // TODO(someday): localization - Asm65.Formatter formatter = mOutputFormatter; - bool showBank = !mProject.CpuDef.HasAddr16; - for (int i = 0; i < xrefs.Count; i++) { - XrefSet.Xref xr = xrefs[i]; - ListViewItem lvi = new ListViewItem(); - - string typeStr; - switch (xr.Type) { - case XrefSet.XrefType.SubCallOp: - typeStr = "call "; - break; - case XrefSet.XrefType.BranchOp: - typeStr = "branch "; - break; - case XrefSet.XrefType.RefFromData: - typeStr = "data "; - break; - case XrefSet.XrefType.MemAccessOp: - switch (xr.AccType) { - case OpDef.MemoryEffect.Read: - typeStr = "read "; - break; - case OpDef.MemoryEffect.Write: - typeStr = "write "; - break; - case OpDef.MemoryEffect.ReadModifyWrite: - typeStr = "rmw "; - break; - case OpDef.MemoryEffect.None: // e.g. LDA # - /// Cache of previously-constructed ListViewItems. The ListView will request items - /// continuously as they are moused-over, so this is fairly important. - /// - private ListViewItem[] mNotesItemCache; - private int mNotesItemCacheFirst; - - // Temporary array, used during ListViewItem creation. - private ListViewItem.ListViewSubItem[] mNotesSubArray = - new ListViewItem.ListViewSubItem[1]; - - /// - /// Clears the contents of the ListViewItem cache. Do this whenever the backing - /// store is updated. - /// - private void ClearNotesListViewCache() { - mNotesItemCache = null; - mNotesItemCacheFirst = -1; - } - - private void notesListView_RetrieveVirtualItem(object sender, - RetrieveVirtualItemEventArgs e) { - // Is item cached? - if (mNotesItemCache != null && e.ItemIndex >= mNotesItemCacheFirst && - e.ItemIndex < mNotesItemCacheFirst + mNotesItemCache.Length) { - // Yes, return existing item. - e.Item = mNotesItemCache[e.ItemIndex - mNotesItemCacheFirst]; - } else { - // No, create item. - e.Item = CreateNotesListViewItem(e.ItemIndex); - } - } - - private void notesListView_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs e) { - if (mNotesItemCache != null && e.StartIndex >= mNotesItemCacheFirst && - e.EndIndex <= mNotesItemCacheFirst + mNotesItemCache.Length) { - // Already have this span cached. - return; - } - - mNotesItemCacheFirst = e.StartIndex; - int len = e.EndIndex - e.StartIndex + 1; // end is inclusive - mNotesItemCache = new ListViewItem[len]; - for (int i = 0; i < len; i++) { - mNotesItemCache[i] = CreateNotesListViewItem(e.StartIndex + i); - } - } - - private ListViewItem CreateNotesListViewItem(int index) { - int offset = mProject.Notes.Keys[index]; - MultiLineComment mlc = mProject.Notes.Values[index]; - ListViewItem lvi = new ListViewItem(); - - lvi.Text = mOutputFormatter.FormatOffset24(offset); - lvi.Tag = mlc; - // Replace line break with bullet. If there's a single CRLF at the end, strip it. - string nocrlfStr; - if (mlc.Text.EndsWith("\r\n")) { - nocrlfStr = mlc.Text.Substring(0, mlc.Text.Length - 1).Replace("\r\n", " \u2022 "); - } else { - nocrlfStr = mlc.Text.Replace("\r\n", " \u2022 "); - } - mNotesSubArray[0] = new ListViewItem.ListViewSubItem(lvi, nocrlfStr); - lvi.SubItems.AddRange(mNotesSubArray); - return lvi; - } - - private void InvalidateNotesListView() { - notesListView.BeginUpdate(); - ClearNotesListViewCache(); - if (mProject == null) { - notesListView.VirtualListSize = 0; - } else { - notesListView.VirtualListSize = mProject.Notes.Count; - } - notesListView.EndUpdate(); - } - - private void notesListView_MouseDoubleClick(object sender, MouseEventArgs e) { - ListViewHitTestInfo info = notesListView.HitTest(e.X, e.Y); - int row = info.Item.Index; - int offset = mProject.Notes.Keys[row]; - Debug.WriteLine("DClick Notes row=" + row + " offset=+" + offset.ToString("x6")); - - // Jump to the note, and shift the focus back to the code view. - GoToOffset(offset, true, true); - codeListView.Focus(); - } - - private void notesListView_DrawColumnHeader(object sender, - DrawListViewColumnHeaderEventArgs e) { - - ListView lv = e.Header.ListView; - string text = lv.Columns[e.ColumnIndex].Text; - - // Adjust rect to match standard control for 10pt fonts, and - // reserve a couple pixels at the far right end for the separator. - Rectangle rect = new Rectangle(e.Bounds.X + 3, e.Bounds.Y + 4, - e.Bounds.Width - 4, e.Bounds.Height - 4); - TextFormatFlags flags = TextFormatFlags.Left | TextFormatFlags.EndEllipsis | - TextFormatFlags.SingleLine; - - TextRenderer.DrawText(e.Graphics, text, lv.Font, rect, lv.ForeColor, flags); - - Pen pen = new Pen(Color.LightGray); - e.Graphics.DrawLine(pen, e.Bounds.X + e.Bounds.Width - 1, e.Bounds.Y, - e.Bounds.X + e.Bounds.Width - 1, e.Bounds.Y + e.Bounds.Height); - } - - private void notesListView_DrawItem(object sender, - DrawListViewItemEventArgs e) { - // We have no full-width items. - } - - private void notesListView_DrawSubItem(object sender, - DrawListViewSubItemEventArgs e) { - // Draw the multi-column items here. - - ListView lv = e.Item.ListView; - ListViewItem lvi = e.Item; - MultiLineComment mlc = (MultiLineComment) lvi.Tag; - - // Set colors based on selection and focus. - if (lvi.Selected && lv.Focused && e.ColumnIndex == 0) { - e.SubItem.BackColor = SystemColors.Highlight; - e.SubItem.ForeColor = codeListView.BackColor; - } else { - if (e.ColumnIndex == 1 && mlc.BackgroundColor.ToArgb() != 0) { - e.SubItem.BackColor = mlc.BackgroundColor; - } else { - e.SubItem.BackColor = lv.BackColor; - } - e.SubItem.ForeColor = lv.ForeColor; - } - - e.DrawBackground(); - - // Shift the text so it lines up with the standard control at 10pts. - // Not strictly necessary, and possibly unwise, since the behavior seems - // to change for larger fonts. - Rectangle rect = new Rectangle(e.Bounds.X + 3, e.Bounds.Y + 2, - e.Bounds.Width - 3, e.Bounds.Height - 2); - - TextFormatFlags flags = TextFormatFlags.Left | TextFormatFlags.EndEllipsis | - TextFormatFlags.SingleLine; - - Font font = lv.Font; - - // TODO(maybe): consider drawing the note text with a proportional font. We - // don't need multi-line stuff to line up, and it'll let us show more of - // the text in a narrow window. - TextRenderer.DrawText(e.Graphics, e.SubItem.Text, font, rect, - e.SubItem.ForeColor, flags); - - // Draw the focus rectangle. It's annoying that we have to draw it for every - // sub-item even with FullRowSelect, but DrawItem always happens first, and - // there's no equivalent at the end. (It's unclear how useful the focus rect - // actually is, but it's part of the standard dialog behavior.) - if (lv.FullRowSelect) { - e.DrawFocusRectangle(e.Item.Bounds); - } else { - e.DrawFocusRectangle(e.Bounds); - } - } - - private void notesListView_ColumnWidthChanged(object sender, - ColumnWidthChangedEventArgs e) { - // We don't auto-adjust column widths, but we do want to make sure that the - // width adjustment causes the settings to be saved. - AppSettings.Global.Dirty = true; - } - - private void SerializeNotesColumnWidths() { - int[] values = new int[] { - notesListView.Columns[0].Width, - notesListView.Columns[1].Width - }; - AppSettings.Global.SetString(AppSettings.NOTEWIN_COL_WIDTHS, - TextUtil.SerializeIntArray(values)); - } - - private void DeserializeNotesColumnWidths() { - string str = AppSettings.Global.GetString(AppSettings.NOTEWIN_COL_WIDTHS, null); - if (!string.IsNullOrEmpty(str)) { - int[] values = TextUtil.DeserializeIntArray(str); - if (values.Length == notesListView.Columns.Count) { - for (int i = 0; i < values.Length; i++) { - notesListView.Columns[i].Width = values[i]; - } - } - } - } - - #endregion // notesListView Virtual and UI handling - - - #region Info view - - /// - /// Updates the Info window for the current selection. - /// - private void UpdateInfoView() { - // I'm seeing weird behavior where, if you do a bunch of up-arrow/down-arrow - // movement in the main window, the info window will eventually freeze. You can - // refresh individual lines by dragging across them with the mouse. Resizing - // the splitter pane leaves the window apparently blank, but moving or resizing - // the application window causes an immediate redraw. - // - // Simply calling Invalidate() didn't help, which shouldn't be too surprising - // since I expect assignment to the Text field to do something similar. Refresh() - // feels a bit heavy-handed but it gets the job done. - // - // I see similar behavior from RichTextBox. The References ListView, which is - // also updated when the selection changes, seems to work correctly though. - // - // This is on Win10 Pro x64, as of 2018/07/28. - DoUpdateInfoView(); - infoTextBox.Refresh(); - } - private void DoUpdateInfoView() { - ListView.SelectedIndexCollection sel = codeListView.SelectedIndices; - if (sel.Count != 1) { - // Nothing selected, or multiple lines selected. - // Calling here from SelectedIndexChanged events works fine for single-item - // selections, but the SelectedIndices list is always empty for multi-select. - // If we add this to other selection events it ends up getting called 3-4 - // times when you arrow around. - - //infoRichTextBox.Text = "(" + - // string.Format(Properties.Resources.FMT_LINES_SELECTED, sel.Count) + ")"; - infoTextBox.Text = string.Empty; - return; - } - int lineIndex = sel[0]; - DisplayList.Line line = mDisplayList[lineIndex]; - StringBuilder sb = new StringBuilder(250); - - // NOTE: this should be made easier to localize - string lineTypeStr; - string extraStr = string.Empty; - switch (line.LineType) { - case DisplayList.Line.Type.Code: - lineTypeStr = "code"; - break; - case DisplayList.Line.Type.Data: - if (mProject.GetAnattrib(line.FileOffset).IsInlineData) { - lineTypeStr = "inline data"; - } else { - lineTypeStr = "data"; - } - break; - case DisplayList.Line.Type.LongComment: - lineTypeStr = "comment"; - break; - case DisplayList.Line.Type.Note: - lineTypeStr = "note"; - break; - case DisplayList.Line.Type.Blank: - lineTypeStr = "blank line"; - //lineTypeStr = "blank line (+" + - // mOutputFormatter.FormatOffset24(line.FileOffset) + ")"; - break; - case DisplayList.Line.Type.OrgDirective: - lineTypeStr = "address directive"; - break; - case DisplayList.Line.Type.RegWidthDirective: - lineTypeStr = "register width directive"; - break; - case DisplayList.Line.Type.EquDirective: { - lineTypeStr = "equate"; - int symIndex = DisplayList.DefSymIndexFromOffset(line.FileOffset); - DefSymbol defSym = mProject.ActiveDefSymbolList[symIndex]; - string sourceStr; - if (defSym.SymbolSource == Symbol.Source.Project) { - sourceStr = "project symbol definition"; - } else if (defSym.SymbolSource == Symbol.Source.Platform) { - sourceStr = "platform symbol file"; - } else { - sourceStr = "???"; - } - extraStr = "Source: " + sourceStr; - } - break; - default: - lineTypeStr = "???"; - break; - } - - // For anything that isn't code or data, show something simple and bail. - if (line.OffsetSpan == 0) { - sb.AppendFormat(Properties.Resources.FMT_INFO_LINE_SUM_NON, - lineIndex, lineTypeStr); -#if DEBUG - sb.Append(" [offset=+" + line.FileOffset.ToString("x6") + "]"); -#endif - if (!string.IsNullOrEmpty(extraStr)) { - sb.Append("\r\n\r\n"); - sb.Append(extraStr); - } - infoTextBox.Text = sb.ToString(); - return; - } - Debug.Assert(line.IsCodeOrData); - - Anattrib attr = mProject.GetAnattrib(line.FileOffset); - - // Show number of bytes of code/data. - if (line.OffsetSpan == 1) { - sb.AppendFormat(Properties.Resources.FMT_INFO_LINE_SUM_SINGULAR, - lineIndex, line.OffsetSpan, lineTypeStr); - } else { - sb.AppendFormat(Properties.Resources.FMT_INFO_LINE_SUM_PLURAL, - lineIndex, line.OffsetSpan, lineTypeStr); - } - sb.Append("\r\n"); - - if (!mProject.OperandFormats.TryGetValue(line.FileOffset, out FormatDescriptor dfd)) { - // No user-specified format, but there may be a generated format. - sb.AppendFormat(Properties.Resources.FMT_INFO_FD_SUM, - Properties.Resources.DEFAULT_VALUE); - if (attr.DataDescriptor != null) { - sb.Append(" ["); - sb.Append(attr.DataDescriptor.ToUiString()); - sb.Append("]"); - } - } else { - // User-specified operand format. - // If the descriptor has a weak reference to an unknown symbol, should we - // call that out here? - sb.AppendFormat(Properties.Resources.FMT_INFO_FD_SUM, dfd.ToUiString()); - } - sb.Append("\r\n"); - - // Debug only - //sb.Append("DEBUG: opAddr=" + attr.OperandAddress.ToString("x4") + - // " opOff=" + attr.OperandOffset.ToString("x4") + "\r\n"); - - sb.Append("\u2022Attributes:"); - if (attr.IsHinted) { - sb.Append(" Hinted("); - for (int i = 0; i < line.OffsetSpan; i++) { - switch (mProject.TypeHints[line.FileOffset + i]) { - case CodeAnalysis.TypeHint.Code: - sb.Append("C"); - break; - case CodeAnalysis.TypeHint.Data: - sb.Append("D"); - break; - case CodeAnalysis.TypeHint.InlineData: - sb.Append("I"); - break; - default: - break; - } - if (i > 8) { - sb.Append("..."); - break; - } - } - sb.Append(')'); - } - if (attr.IsEntryPoint) { - sb.Append(" EntryPoint"); - } - if (attr.IsBranchTarget) { - sb.Append(" BranchTarget"); - } - if (attr.DoesNotContinue) { - sb.Append(" NoContinue"); - } - if (attr.DoesNotBranch) { - sb.Append(" NoBranch"); - } - if (mProject.StatusFlagOverrides[line.FileOffset].AsInt != 0) { - sb.Append(" StatusFlags"); - } - sb.Append("\r\n\r\n"); - - if (attr.IsInstruction) { - Asm65.OpDef op = mProject.CpuDef.GetOpDef(mProject.FileData[line.FileOffset]); - - string shortDesc = mOpDesc.GetShortDescription(op.Mnemonic); - if (!string.IsNullOrEmpty(shortDesc)) { - if (op.IsUndocumented) { - sb.Append("\u25b6[*] "); - } else { - sb.Append("\u25b6 "); - } - sb.Append(shortDesc); - string addrStr = mOpDesc.GetAddressModeDescription(op.AddrMode); - if (!string.IsNullOrEmpty(addrStr)) { - sb.Append(", "); - sb.Append(addrStr); - } - sb.Append("\r\n"); - } - - sb.Append("\u2022Cycles: "); - int cycles = op.Cycles; - Asm65.OpDef.CycleMod cycMods = op.CycleMods; - sb.Append(cycles.ToString()); - if (cycMods != 0) { - sb.Append(" ("); - int workBits = (int)cycMods; - while (workBits != 0) { - // Isolate rightmost bit. - int firstBit = (~workBits + 1) & workBits; - sb.Append(mOpDesc.GetCycleModDescription((OpDef.CycleMod)firstBit)); - // Remove from set. - workBits &= ~firstBit; - if (workBits != 0) { - // more to come - sb.Append(", "); - } - } - sb.Append(")"); - } - sb.Append("\r\n"); - - const string FLAGS = "NVMXDIZC"; - sb.Append("\u2022Flags affected: "); - Asm65.StatusFlags affectedFlags = op.FlagsAffected; - for (int i = 0; i < 8; i++) { - if (affectedFlags.GetBit((StatusFlags.FlagBits)(7 - i)) >= 0) { - sb.Append(' '); - sb.Append(FLAGS[i]); - } else { - sb.Append(" -"); - } - } - sb.Append("\r\n"); - - string longDesc = mOpDesc.GetLongDescription(op.Mnemonic); - if (!string.IsNullOrEmpty(longDesc)) { - sb.Append("\r\n"); - sb.Append(longDesc); - sb.Append("\r\n"); - } - } else { - // do we want descriptions of the pseudo-ops? - } - - - // Publish - infoTextBox.Text = sb.ToString(); - } - - #endregion // Info view - - - #region Tools items - - private void hexDumpToolStripMenuItem_Click(object sender, EventArgs e) { - OpenFileDialog fileDlg = new OpenFileDialog() { - Filter = Properties.Resources.FILE_FILTER_ALL, - FilterIndex = 1 - }; - if (fileDlg.ShowDialog() != DialogResult.OK) { - return; - } - string fileName = fileDlg.FileName; - FileInfo fi = new FileInfo(fileName); - if (fi.Length > Tools.HexDumpViewer.MAX_LENGTH) { - string msg = string.Format(Properties.Resources.ERR_FILE_TOO_LARGE, - Tools.HexDumpViewer.MAX_LENGTH); - MessageBox.Show(this, msg, Properties.Resources.OPEN_DATA_FAIL_CAPTION, - MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - byte[] data; - try { - data = File.ReadAllBytes(fileName); - } catch (Exception ex) { - MessageBox.Show(this, ex.Message); - return; - } - - // Fire and forget. - Tools.HexDumpViewer dlg = new Tools.HexDumpViewer(data, mOutputFormatter); - dlg.Text = Path.GetFileName(fileName); - dlg.Show(); - } - - #endregion Tools items - - - #region Debug menu items - - private void dEBUGToolStripMenuItem_DropDownOpened(object sender, EventArgs e) { - toggleOwnerDrawToolStripMenuItem.Checked = codeListView.OwnerDraw; - toggleCommentRulersToolStripMenuItem.Checked = MultiLineComment.DebugShowRuler; - useKeepAliveHackToolStripMenuItem.Checked = ScriptManager.UseKeepAliveHack; - } - - private void reanalyzeToolStripMenuItem_Click(object sender, EventArgs e) { - Debug.WriteLine("Reanalyzing..."); - // Call through ApplyChanges so we update the timer task output. - UndoableChange uc = - UndoableChange.CreateDummyChange(UndoableChange.ReanalysisScope.CodeAndData); - ApplyChanges(new ChangeSet(uc), false); - UpdateMenuItemsAndTitle(); // in case something changed - } - - private Tools.ShowText mShowUndoRedoHistoryDialog; - - private void showUndoRedoHistoryToolStripMenuItem_Click(object sender, EventArgs e) { - // Show or hide the modeless dialog. - if (mShowUndoRedoHistoryDialog == null) { - Tools.ShowText dlg = new Tools.ShowText(); - dlg.Title = "Undo/Redo History"; - dlg.BodyText = mProject.DebugGetUndoRedoHistory(); - dlg.OnWindowClosing += (sender1, e1) => { - Debug.WriteLine("Undo/redo dialog closed"); - showUndoRedoHistoryToolStripMenuItem.Checked = false; - mShowUndoRedoHistoryDialog = null; - }; - dlg.Show(); - mShowUndoRedoHistoryDialog = dlg; - showUndoRedoHistoryToolStripMenuItem.Checked = true; - } else { - // Ask the dialog to close. Do the cleanup in the event. - mShowUndoRedoHistoryDialog.Close(); - } - } - - private Tools.ShowText mShowAnalyzerOutputDialog; - - private void showAnalyzerOutputToolStripMenuItem_Click(object sender, EventArgs e) { - // Show or hide the modeless dialog. - if (mShowAnalyzerOutputDialog == null) { - Tools.ShowText dlg = new Tools.ShowText(); - dlg.Title = "Analyzer Output"; - if (mGenerationLog == null) { - dlg.BodyText = "(no data yet)"; - } else { - dlg.BodyText = mGenerationLog.WriteToString(); - } - dlg.OnWindowClosing += (sender1, e1) => { - Debug.WriteLine("Analyzer output dialog closed"); - showAnalyzerOutputToolStripMenuItem.Checked = false; - mShowAnalyzerOutputDialog = null; - }; - dlg.Show(); - mShowAnalyzerOutputDialog = dlg; - showAnalyzerOutputToolStripMenuItem.Checked = true; - } else { - // Ask the dialog to close. Do the cleanup in the event. - mShowAnalyzerOutputDialog.Close(); - } - } - - private Tools.ShowText mShowAnalysisTimersDialog; - - private void showAnalysisTimersToolStripMenuItem_Click(object sender, EventArgs e) { - // Show or hide the modeless dialog. - if (mShowAnalysisTimersDialog == null) { - Tools.ShowText dlg = new Tools.ShowText(); - dlg.Title = "Analysis Timers"; - dlg.BodyText = "(no data yet)"; - dlg.OnWindowClosing += (sender1, e1) => { - Debug.WriteLine("Analysis timers dialog closed"); - showAnalysisTimersToolStripMenuItem.Checked = false; - mShowAnalysisTimersDialog = null; - }; - dlg.Show(); - mShowAnalysisTimersDialog = dlg; - showAnalysisTimersToolStripMenuItem.Checked = true; - } else { - // Ask the dialog to close. Do the cleanup in the event. - mShowAnalysisTimersDialog.Close(); - } - } - - private void toggleOwnerDrawToolStripMenuItem_Click(object sender, EventArgs e) { - Debug.WriteLine("TOGGLE OWNERDRAW"); - bool newState = !codeListView.OwnerDraw; - codeListView.OwnerDraw = newState; - notesListView.OwnerDraw = newState; - } - - private void toggleCommentRulersToolStripMenuItem_Click(object sender, EventArgs e) { - MultiLineComment.DebugShowRuler = !MultiLineComment.DebugShowRuler; - // Don't need to repeat the analysis, but we do want to save/restore the - // selection and top position when the comment fields change size. - UndoableChange uc = - UndoableChange.CreateDummyChange(UndoableChange.ReanalysisScope.DataOnly); - ApplyChanges(new ChangeSet(uc), false); - } - - private void useKeepAliveHackToolStripMenuItem_Click(object sender, EventArgs e) { - ScriptManager.UseKeepAliveHack = !ScriptManager.UseKeepAliveHack; - } - - private void sourceGenTestsToolStripMenuItem_Click(object sender, EventArgs e) { - Tests.GenTestRunner dlg = new Tests.GenTestRunner(); - dlg.ShowDialog(); - dlg.Dispose(); - } - - private void extensionScriptInfoToolStripMenuItem_Click(object sender, EventArgs e) { - string info = mProject.DebugGetLoadedScriptInfo(); - - Tools.ShowText dlg = new Tools.ShowText(); - dlg.Title = "Loaded Extension Script Info"; - dlg.BodyText = info; - dlg.ShowDialog(); - } - - #endregion Debug menu items - } -} diff --git a/SourceGenWF/AppForms/ProjectView.resx b/SourceGenWF/AppForms/ProjectView.resx deleted file mode 100644 index 666c9b1..0000000 --- a/SourceGenWF/AppForms/ProjectView.resx +++ /dev/null @@ -1,319 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - - 132, 17 - - - 269, 17 - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA8SURBVDhPY8AHOGPO/ocySQcgzWQbANNMlgHImkk2YJho - JhVTbgA2V4AFSQXD2BCoEOmAYgNAgLABDAwANqCmjcoYW+kAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA5SURBVDhPYyAEOGPO/ocyyQMgAygyBGYA2YYgGzBcDUEX - JBVTbgApYCRqBgGKNIMARZpBAL9mBgYAlSmmjRN9gzIAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAERSURBVDhPrZDbSgJRGIXnpewd6jXsjSQvIrwoI0RQMChU - 0iiDPCGiE3ZCRkvR8VzTeBhnyR5/ccaZNnPhB4t9sdf6Ln5hb8QeathNJFVFKF5C8DqL4ksDVHWGDf7j - LHyPg6NjviSaFqlu5yQYR+KpupaIkrMknCxT3Y7v/NYYb0ITK1c3BarbWWhLQ7IR0cTKReyZ6lZ0XYei - ztHpK4bAc+h1FgQijzSxMptrGIxVSO0xX3AaStFki7bUMVFmaMm/eJMGfIH/MkGzLep0AXn4h/r3CJV3 - mS9gn2bY4UY/UzQ7E9TqfeTFtnuB+XAfzSHKr11kSl/uBebDiZ89ZCst3OUkdwL28sIVsE83ock+EIQV - 2Mz2wxeg6/UAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJHSURBVDhPxZBdSNNhFMb/F110ZZEVhVBgeeHNICiiuggp - olAUyyxI0oSaH1QYC3N+tKnp5ubm1JUua5uuqdNKMwr7kApFItTUkWZqVhSVYmao5Nevvy7UoYR3HXh4 - 4XCe33nOKyy3lAY7l9RWMo0O/raWXxEyo5spVYTNvOGyfIRPfW+ptOkXqaPl6T83hcRmExSdgzAz3NVm - YWyoYla/B+1M9JtxWLPpaH22JORIjI6gKAMB0jyEimIdo4OlbuaprwVMOOMovammpDADc34qppwUrmnl - 5Kni3aFlFg2j3y1z5mnRTJccnNIltQhwq0jFry+mOXNtpWZWDx1Z1NhV3C3JwGFOw25SYjVe5oYhiUKd - HKMmwQUrMWUw/CF3NnZvvYKqUh1TvUroS3fXe7HXkwidMngTS2t5KLbregSzMY2f3Wr4qKW6LJvGR1rX - 0MLor8OhKYTJBn/GHvvxrliCTBrsOqXIoOBHh5K+hmSq7FqmexTQHuUytkaKxuNMNgYyVneA4Qd7GKjc - hjLaRzxH7gIU6JIZaEvgtk1D8wsxSWecCDgNzWFMvwxm/PkhRmr3Mli1nW9lvjRdWc0Jf+/5jzRmyWmv - S+GOLQu6U6BFjPvqKOP1AYw88WOoZif9DgmfLVtxaj1RSLdwNvrkPCA3M54KqxrnvRia9MKcGrUrqFOt - 5H7qKsqT1mGO9+Lqhc2ELdw+U/r0i+gVZ8hMiCDx3DHORwZyKnQ/hw/uYt9uCTskPvh6e7Fp41rWr/Fg - g6eHO+A/lyD8ARfG3mk9fv1YAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIySURBVDhPrZLfS5NRGMfff6H7boIuuq2pMZyL1eAt11CW - DcOKsB9vpFmaLtNExco0av6CbIVLJ61Wk3BSkT/AFCkRZSpZmrmiJQ41xSaCwdfznL15XEUX0Reem5f3 - 8znnec4j/Zc8fxYGla91CS3eRTx0z6OpMYS7jmnU1X6B/VYA18snUVoyjsKCt8jLHcH5c36ouCQR2NUJ - 1Nas4G9ZXlmFKbULh1Kf8lJxSfI+WeCCyopv6q+/h+DQ/DJ2WV5Ao1FgPegRAveDOS4oLfmq/h6dn/DH - 4AJizD4UXJrCAUuzEDgbZrjgou2DiohshIcnQtgme5GTPYbkJKcQ1N8OckHW2REVi+RXuM8fxGaDG4oy - ALPZIQQ11Z+5QDk1oKJ/hjv7P2FTfCMOH3mFxMQ6IbhROYWOdrCnBI4dfwPr0V4+bRoY9UzXppMjcDdS - rC8hy3YhuFI2gTYf2A4Aza4f7N2/o/zaLB8qDYx6zszwr8P7k1thNFYIweXCMXgeAfedq2xxwjClZUeV - Jd2GtDNFETiJwfs8MBjKhMCWN8pgoLoqzE8miH1GjE7G4PsZjE7OQsm9ij2mFg7rdrug1xcJAa2l4w7W - r00Cgk/n38S7wBwC04u4UGxHrMHF4CbEJtyDLj5fCDIzhljfSxzeavRgyw4Zj9t64GvvQ0d3P3pfD2Kv - 2QqNvgFxDN6urYdWmyMElJMnevh60obRktA701PRtGlg1DOdSkXwzrisaMG/RZLWAE60OMW5fNhvAAAA - AElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIpSURBVDhPtZL/T1JRGMb5p1itrVZbbRpqZbawnBENV1I0 - jGlByTSyJTXJwq2oKZQb1KAv6JCYWSxvBrkkZUq4CeQEiRABFeLL072Xa0zRra31bO8v57zP5znnPYf1 - X+TxhWF6O7VtGYcnwbSWijKPOLzYrPSvLPwLS3huGUMlT7o9wGD9grVUBj+icdid03S9tDmgNxNwTgVQ - J+rA8XNtWwM+uuZATMwxmQVRycuJFNyzIRitDlScugKzjSgFRGJJaIwEsrk8AsHIhnSL/Ssck37UNipQ - I5DjtuYV7uksRYhr2kebhx2eP6nrycFIEh5fBA/1Nvru8q5+PDaOovK0rABwfwugWzcErfkzHhjsePL6 - E7q1VrTdNUDcrgGvSYlDZHN5XTNOnL8BVe8AJAoNDtZfLgDu9L1BPJmikzcrk81hlRwodZJwdBXziwnI - OrVoaOkiT8C8hKLHBPO7CbywOaE1jeC+bhAd6meQdvZC1KoG/5IS3MZ2HObLUHZSggvkWq3wOvbWiAqA - VpWeyStVfCUNf3AZ4zNhfHCFMEDMgye+hYr6FrDLzxQAUuVTpr0ocn74mchg5vsKRt1RcHp2Qv9+kZ78 - UcE17KkWFgHNN/uQzgBkGKLJPBZiecyGchjzrmFwPIF++xJUbDbUQzEacIArLpopSRSP4CUN1Obf1Abz - uqob5KjiXwWH/GVl5HPt5zZh37GL2H1EiF1VZ7GDI6CNW5r/TSzWbwHYL0mKJ5czAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGDSURBVDhPrZFNSwJRGIX9NYGbFoUlFElY1EJQKEYhCJsi - LaVsERnRF5iCaSZJO1toCDVGFkgoFpWQWWRR2aIvUxm1BKN1wSnHCFw4TOCzue+9nPNw4eVVnav4Izzb - QfxeGZ5TWaxT/rK3irzmC7CsusvC1G4IkbNLboIiDieF4GGUKeTeClDpppF8eeEu2PIfwfrzizSdw3Hk - EnKlFpkMzV2wH77AosOFTV8A+vkl9CiHuJeLJNNZjM8tYWB0FkTvMAwmy/8ERTR6CwjlGAi1Ccence6C - 1NsXzN4PKIxJLLgeIJ2MoXvmFraNBKK3eXZRIveJPvs7FIYniEkXZENOdE+GIZ2Ko10TwLK7tJmKmL0F - EEYarYM+NMnt0C1sQzpx/lcSEnZ2gcKY/gs0dlmZuWvmjjmpwA1qxVp2AWFIMAF/OAGBzMjMI7ZrtJCb - 4Df3o4Zfxy7QrdxDRFKol5khkpR2H4qmIOzUQNBGwrsXYxccnNOQqNbQ0KGGZ+eEPVwdeLxvqqrf4wGh - TNAAAAAASUVORK5CYII= - - - - - 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 - BQ49yaW50J7Fh0xJw3IxbM3hwo2x0ICRHZzFgveTunYERK5lgo5YMxx8WPFw5Li+U8wYm66jNz+Naov+ - Beqiao58N5NrPluoryJO0QeKU7sNGKPPazh9aRzGo/eYmVvEMk270fTlmzl2N3XW9xL/jv7iaxw7+wAH - E9ew//AVxE8OItv/9O/Cf0ck8gud2vKswuxNZgAAAABJRU5ErkJggg== - - - - - AAABAAEAICAAAAEAGACoDAAAFgAAACgAAAAgAAAAQAAAAAEAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AABKTUFQUkdxb2eDfnRbXFJnZ1xLTkFOUEJKTjtWWUhsaVxybWBraWJVVkpBRTZARTQ9QzhZV1NxbmZa - WE9UVUxESkU8QS48QDB0c29zcGdmaGB9eXBAQjY/Qjk/QjlQUk1SUk07PjU2OS81OC80Nyc2Oi13dG9S - VktqaWE4OSw/QTI+QDI8PzI9PjF3c2lcXVFLSz8/QjhISj4zNSc4OSx3dGxHS0JkZVleYlxeYlhYXlRg - YltrbGU8QDdeYVhLTUYaGBsfHCEmIiQsKS0jICQnIyknIykpKSckIygqJikuKi8wLDEuKS80MDUhHiEj - ICItKjEuKS41MDUpJCknIiguLDIgHB0bGSA5NS9RUEhPS0A2My0bFxwQDg8UExksKzIXFxsbGR8gHSUh - HiYiICctKjIqJy4YGRsdHSMnIioqJS0mIiouKTE/PEYfHCEWFhowLjgnIyslISknIisnIiksKzMgGyAm - JCwwLS80MjQzMTMoJikmIioPDRAWFBkjHyUUFBkaGR4iICgnJCshHiYrKjErKjMZGBocHSMrJi0rJy4o - JCstKTA5Nj8gHSIWFRsvLTcrKC8pJCsrJi4qJSwsLDQiHiQrJy81OC8/QzU7PzMgJR0oJS0REBMZGB0o - JygVFRobGR4hHyYlIysiICcmJCwtKzQcGh4aGiEwKzItKTAsKDAuKTI3Mz0hHiMWFRouKzMvKzMvKjMx - LTQpJCwsKjIlISYwKzMvMy04PTM2OjEhIx0pJy8SEBMdGiAsKywWFRkfHiUpJSsrKTAvLDMnJSwvLzgd - HSEbGyIyLjZAPEUpJS45NT01MjwhHyQXFxwtKjI/O0QvKzMyLTYtKDApJy8oJSorKDBER0NLUUtCSUQp - LSomJCsSERUeHCMyMTQTEhYcGyJmYm89OURFQkomIyo2NUAcHB8bGyIxLjU7OEM/PEZKR081MjskIScY - GB0yLjczMDg2Mjw5NT8uKjEpKTEoJCovLDQeIRchJRkYGxQMDwoqJi0UFBgdHCIjIiUSEhUiIScrJzA0 - Mjw9OUMnJCw7O0YcHCAeHiYqJi1IRU89O0U5N0M4NT4mIykZGB02Mzw5NTw6Nj81MToxLDUxMDkoIykw - Ljc3Mjc0LjQxKzIsJy0oJi0WFBcgHycqJSsSEhYoJy45NT0vLTY/O0clIyo6OUYfHyMjJCsrJy5GRFFA - PEhIRlE7OEImIigWFhw2Mzw3Mjw2MTo2MjstKDEyMjsnIicxLjY9Pzw8QDozNjQfISAqJy4XFRkkIysv - LjATExYtKzM3NDwsKTIlIisnJSw7O0ggHyIkJS0tKTIrJzAsKDAwLDQ7OEQoJSoXFxw3NT81MTg1MDo1 - MDkvKjMwMDgnIygwLDYaHhsjKiMjKCQVGBcpJS0ZFhofHiUlJSYQEBMoKDAnJCwnJCwnJC0lIyk7PEgf - HiInJy8uKTAwLDMwLDUyLTY7OUQqJisYGB06N0EzLjc2Mjo0LzcwLDQvLjYnIic1MTgjHyAkISEiHyAg - HCAmIikaFxwiISgjHyQZGRsbGiYcGSQlIi0nJS4eGiY1NUU8QD4dHioqJTAtKDUqJjIvKjQ6N0IuLDEc - HSQyLz00MDkrJzMwKzcrJzIsKTEuLDMoJDJgaGBQWFVNVlRDR0QbFyIfHiIUEh5HS0ouMjiOkFulpmm0 - sm47OzXFxXi8u2+anqbJyIGpqW+ko2eioHNXVkY7OTw5PDjJyHmqqmk9Ozy1s3GVl2Nsa1F6e1S6unPW - 1YBLT0W+vnOhpGw7QUDIyHlGTT+hpGk6QDw2Ozs2PUJlak/V1X99gVhjZktna1bIyajR0IyMj5TExY66 - u5Cxs6yFhoeZm4uvsYqOkp2XmaLV1IO5u4u/v57X1Yqcm5jBwnLCwaPQ0ZSrrHFaYEq9vXJITzWWml05 - QTM0OTqVlmKYmmZDSD9VV0a/v3a+vnVTWU3IyHw/RT2qq2uOkV6zs3HMy3g0ODnBwXOVl19ARj2wsW6Q - k2GFh1zGxndLT0RqbFBVWUeys3C5unNMUkfb2n6qrGiAg1A9RDZQUVJucE2ysm+urnhycGxeXlg5QD1I - UEwoLykxNzI7QThCRT0zNzQuMy8uNTFBRkhgYVplZmBARD1ITD5XWVhydFTDw3nBwnlBRUBTWlJfZl5Y - XlZ1dnRwcGZdX1ZJUEgPDAwmIyVQT1MwKzMXFBMZFRUzMTU/PT0hHiEjICIiHyAkICAdGhscGRwfHB4i - ICIkICMnJCQeGhogHB0pJSggHR0XExkWFBkdGhosKyVLS0MzMTEXExMSEREbGhtDREAzLzZIRUonKS4Q - ERo9Nz82Mj40MzskJCcrJy8mIisuKzAhHiQdGyIfGyMjICQjICkmIisuKS0rJy0kISofHSIeGyIlIiYf - HiYrKS4vLjAyNDYhICIkJTEpJi0XFyAaHRMwLTR8eWWxsWympmZJRUWwr3KzsnAqKDCjoWiurG5nZE+R - j2G3tXG0snBLR0K3tXGzsW43MzqgnWefnWZlYUyXlWEvKzKtq2onIiy3tm6trWseHSG3tnU3NTSFhlog - Ih8qJzDMyYo3OTSqqWZOSUs/PEeRkGJvbU/V1H5BPT++vHQoJDOxsG9BPT9bWEqGhGBoZU+EgmPOzXqR - jmFsalGioWkyLje6uXJdWkl6eVIeHyMICBS8u3M5NzSPj14RFA4uKjG5t32Skl9jZEVUTk7NzX9yclA4 - ODeYlmSNi2DFw3gnIzItKTXAvnVXU0vHxn2urGxoZVu1s3B0cVWOjGChoGiUkmTCwHY1MDfEw3aCglUV - Fhzg34STkWB7fFUfIhovKzJiYFe2tnCBgU9STU/V032vrmgvLTKysXChn2mEgVx1clajoWiwrm5YVEmF - glxKRkQ3Mz40MDtQTEYxLTpAPD9CPUI+OT8xLjYuKzNHSD0MDRm8unQ5ODcREhkoLCUoJSxQTVMpLjUN - EBhEQEo5NkIbHCgzNzsVFB0aGiAZGCAYFyAYGB8WFR8pKCc5OTIiISghICchICggHyYgHyYfHiYgHyYi - ICcdHCEtLjI4OzsYGiFWVUUiICsSFBopMSwoJy1VWV08QUQpLTE4Nj07O0E3PD4+REc9QkY9Q0YtLzEl - JyoxNjc6P0M6PkI5PD8zODorLzAoLS4rMDI1OjwyNjg1OTsmKSoqLC8oKywzODk1O0ItLDIgICgXGhsw - OTJFTEpkaXFBSUgfIyMICQgKDAopLjBFTkttc3xJUVEJDAkICwgLDgk2Pz4+REJKUVQrLiwVGBQNEQwn - LC02PjosNzg4PzsHCgYYGRsPERMkKCotMTAvNjAeIxoJDAcdJRVITExBR0g0Oj48Pj88PT0+Pz9AQkFR - V1hOVVU2PD9DREQ9Pj5TVVU8QT1UV1JCRkRFSElYWllJS0tJSko6REK3s7IxNzMyNTYqLS8vMjUfICI5 - Oz0uMiomKSQbHBwnLSZYWlxCRUgsMDRISU4iIiEuLS5JSkpbXl5DSEk8QkpTUVQQDw5CQUJQUlBjZmhG - TExGR0o4NzYgISJAQEI0OztxdnY1PDwtLjEKCQkdHiAjJSkuMTQ4PTsxNDMbGhsQFwdaYFhbZWJKVVM4 - Ozg3ODY0NDNLT0lxeHNXYl5NWVc0MzE5OTg3NjRtc21jbGZbZGFGS0cuLi0uLiwyNTRWYFteaWNXYlwc - HBwVFhcOEBEsMzRES0lJUkw/RT4UFBUuNDA9Pzo3OjomKiskJSEkJyMoKic8PDhLTU0xNTcpLC8qKyUj - JiEnKCJPUUs+QUA1OTosLSsiJSMnKScrLCo2ODg3OTo3OToWFxcQEhIODxAUFhYgICElKCchJCALDQw0 - NzdCRUI5Pj8sMjVNTEwdIy4iJy5PUE9KTk42PD41Oz1KTE0ZIjEsLjBUV1Y+Q0M7QUNAQkQ3PEEVHCQx - MzQ5Pj46P0A7Pj41NzkHCw8VGh0nKS0hJCYkKCcjJiQRERE2OTwuMjExNTYsMTM1OkEiMUEpOkpCQkFN - T1YzNzg3Oz5BU2ATHi46Rk9BRUQ0Ojs2Ojw3ODguQ1YfNEcsLTA2OzszOTk0ODkiJSkSITIhNkojJCYf - IiUgJSQeIiAYJzUzOUQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== - - - \ No newline at end of file diff --git a/SourceGenWF/AppSettings.cs b/SourceGenWF/AppSettings.cs deleted file mode 100644 index 1bd63c9..0000000 --- a/SourceGenWF/AppSettings.cs +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; -using System.Web.Script.Serialization; - -namespace SourceGenWF { - /// - /// Application settings registry. This holds both user-accessible settings and saved - /// values like window widths. - /// - /// Everything is stored as name/value pairs, where the value is serialized as a string. - /// Names are case-sensitive. - /// - /// We don't discard things we don't recognize. If we somehow end up reading a config - /// file from a newer version of the app, the various settings will be retained. - /// - public class AppSettings { - #region Names - - // Name constants. Having them defined here avoids collisions and misspellings, and - // makes it easy to find all uses. - - // Main window. - public const string MAIN_WINDOW_WIDTH = "main-window-width"; - public const string MAIN_WINDOW_HEIGHT = "main-window-height"; - public const string MAIN_WINDOW_LOC_X = "main-window-loc-x"; - public const string MAIN_WINDOW_LOC_Y = "main-window-loc-y"; - public const string MAIN_WINDOW_MAXIMIZED = "main-window-maximized"; - public const string MAIN_LEFT_PANEL_WIDTH = "main-left-panel-width"; - public const string MAIN_RIGHT_PANEL_WIDTH = "main-right-panel-width"; - public const string MAIN_LEFT_SIDE_SPLITTER_DIST = "main-left-side-splitter-dist"; - public const string MAIN_RIGHT_SIDE_SPLITTER_DIST = "main-right-side-splitter-dist"; - - // New project dialog. - public const string NEWP_SELECTED_SYSTEM = "newp-selected-system"; - - // Formatting choices. - public const string FMT_UPPER_HEX_DIGITS = "fmt-upper-hex-digits"; - public const string FMT_UPPER_OP_MNEMONIC = "fmt-upper-op-mnemonic"; - public const string FMT_UPPER_PSEUDO_OP_MNEMONIC = "fmt-upper-pseudo-op-mnemonic"; - public const string FMT_UPPER_OPERAND_A = "fmt-upper-operand-a"; - public const string FMT_UPPER_OPERAND_S = "fmt-upper-operand-s"; - public const string FMT_UPPER_OPERAND_XY = "fmt-upper-operand-xy"; - public const string FMT_ADD_SPACE_FULL_COMMENT = "fmt-add-space-full-comment"; - public const string FMT_SPACES_BETWEEN_BYTES = "fmt-spaces-between-bytes"; - - public const string FMT_OPCODE_SUFFIX_ABS = "fmt-opcode-suffix-abs"; - public const string FMT_OPCODE_SUFFIX_LONG = "fmt-opcode-suffix-long"; - public const string FMT_OPERAND_PREFIX_ABS = "fmt-operand-prefix-abs"; - public const string FMT_OPERAND_PREFIX_LONG = "fmt-operand-prefix-long"; - public const string FMT_EXPRESSION_MODE = "fmt-expression-mode"; - - public const string FMT_PSEUDO_OP_NAMES = "fmt-pseudo-op-names"; - - public const string CLIP_LINE_FORMAT = "clip-line-format"; - - // Symbol-list window options. - public const string SYMWIN_SHOW_USER = "symwin-show-user"; - public const string SYMWIN_SHOW_AUTO = "symwin-show-auto"; - public const string SYMWIN_SHOW_PROJECT = "symwin-show-project"; - public const string SYMWIN_SHOW_PLATFORM = "symwin-show-platform"; - public const string SYMWIN_SHOW_CONST = "symwin-show-const"; - public const string SYMWIN_SHOW_ADDR = "symwin-show-addr"; - public const string SYMWIN_SORT_ASCENDING = "symwin-sort-ascending"; - public const string SYMWIN_SORT_COL = "symwin-sort-col"; - - public const string SYMWIN_COL_WIDTHS = "symwin-col-widths"; - - // References window options. - public const string REFWIN_COL_WIDTHS = "refwin-col-widths"; - - // Notes window options. - public const string NOTEWIN_COL_WIDTHS = "notewin-col-widths"; - - // Code List View settings. - public const string CDLV_COL_WIDTHS = "cdlv-col-widths"; - public const string CDLV_FONT = "cdlv-font"; - - // Hex dump viewer settings. - public const string HEXD_ASCII_ONLY = "hexd-ascii-only"; - public const string HEXD_CHAR_CONV = "hexd-char-conv"; - - // ASCII chart viewer settings. - public const string ASCCH_MODE = "ascch-mode"; - - // Source generation settings. - public const string SRCGEN_DEFAULT_ASM = "srcgen-default-asm"; - public const string SRCGEN_ADD_IDENT_COMMENT = "srcgen-add-ident-comment"; - public const string SRCGEN_DISABLE_LABEL_LOCALIZATION = "srcgen-disable-label-localization"; - public const string SRCGEN_LONG_LABEL_NEW_LINE = "srcgen-long-label-new-line"; - public const string SRCGEN_SHOW_CYCLE_COUNTS = "srcgen-show-cycle-counts"; - - // Main project view settings. - public const string PRVW_RECENT_PROJECT_LIST = "prvw-recent-project-list"; - - // Assembler settings prefix - public const string ASM_CONFIG_PREFIX = "asm-config-"; - - // Internal debugging features. - public const string DEBUG_MENU_ENABLED = "debug-menu-enabled"; - - #endregion Names - - #region Implementation - - // App settings file header. - public const string MAGIC = "### 6502bench SourceGen settings v1.0 ###"; - - - /// - /// Single global instance of app settings. - /// - public static AppSettings Global { - get { - return sSingleton; - } - } - private static AppSettings sSingleton = new AppSettings(); - - - /// - /// Dirty flag, set to true by every "set" call. - /// - public bool Dirty { get; set; } - - /// - /// Settings storage. - /// - private Dictionary mSettings = new Dictionary(); - - - private AppSettings() { } - - /// - /// Creates a copy of this object. - /// - /// - public AppSettings GetCopy() { - AppSettings copy = new AppSettings(); - //copy.mSettings.EnsureCapacity(mSettings.Count); - foreach (KeyValuePair kvp in mSettings) { - copy.mSettings.Add(kvp.Key, kvp.Value); - } - return copy; - } - - /// - /// Replaces the existing list of settings with a new list. - /// - /// This can be used to replace the contents of the global settings object without - /// discarding the object itself, which is useful in case something has cached a - /// reference to the singleton. - /// - /// - public void ReplaceSettings(AppSettings newSettings) { - // Clone the new list, and stuff it into the old object. This way the - // objects aren't sharing lists. - mSettings = newSettings.GetCopy().mSettings; - Dirty = true; - } - - /// - /// Merges settings from another settings object into this one. - /// - /// - /// - public void MergeSettings(AppSettings newSettings) { - foreach (KeyValuePair kvp in newSettings.mSettings) { - mSettings[kvp.Key] = kvp.Value; - } - Dirty = true; - } - - /// - /// Retrieves an integer setting. - /// - /// Setting name. - /// Setting default value. - /// The value found, or the default value if no setting with the specified - /// name exists, or the stored value is not an integer. - public int GetInt(string name, int defaultValue) { - if (!mSettings.TryGetValue(name, out string valueStr)) { - return defaultValue; - } - if (!int.TryParse(valueStr, out int value)) { - Debug.WriteLine("Warning: int parse failed on " + name + "=" + valueStr); - return defaultValue; - } - return value; - } - - /// - /// Sets an integer setting. - /// - /// Setting name. - /// Setting value. - public void SetInt(string name, int value) { - mSettings[name] = value.ToString(); - Dirty = true; - } - - /// - /// Retrieves a boolean setting. - /// - /// Setting name. - /// Setting default value. - /// The value found, or the default value if no setting with the specified - /// name exists, or the stored value is not a boolean. - public bool GetBool(string name, bool defaultValue) { - if (!mSettings.TryGetValue(name, out string valueStr)) { - return defaultValue; - } - if (!bool.TryParse(valueStr, out bool value)) { - Debug.WriteLine("Warning: bool parse failed on " + name + "=" + valueStr); - return defaultValue; - } - return value; - } - - /// - /// Sets a boolean setting. - /// - /// Setting name. - /// Setting value. - public void SetBool(string name, bool value) { - mSettings[name] = value.ToString(); - Dirty = true; - } - - /// - /// Retrieves an enumerated value setting. - /// - /// Setting name. - /// Enum type that the value is part of. - /// Setting default value. - /// The value found, or the default value if no setting with the specified - /// name exists, or the stored value is not a member of the specified enumerated - /// type. - public int GetEnum(string name, Type enumType, int defaultValue) { - if (!mSettings.TryGetValue(name, out string valueStr)) { - return defaultValue; - } - try { - object o = Enum.Parse(enumType, valueStr); - return (int)o; - } catch (ArgumentException ae) { - Debug.WriteLine("Failed to parse " + valueStr + " (enum " + enumType + "): " + - ae.Message); - return defaultValue; - } - } - - /// - /// Sets an enumerated setting. - /// - /// Setting name. - /// Enum type. - /// Setting value (integer enum index). - public void SetEnum(string name, Type enumType, int value) { - mSettings[name] = Enum.GetName(enumType, value); - Dirty = true; - } - - /// - /// Retrieves a string setting. The default value will be returned if the key - /// is not found, or if the value is null. - /// - /// Setting name. - /// Setting default value. - /// The value found, or defaultValue if not value is found. - public string GetString(string name, string defaultValue) { - if (!mSettings.TryGetValue(name, out string valueStr) || valueStr == null) { - return defaultValue; - } - return valueStr; - } - - /// - /// Sets a string setting. - /// - /// Setting name. - /// Setting value. - public void SetString(string name, string value) { - if (value == null) { - mSettings.Remove(name); - } else { - mSettings[name] = value; - } - Dirty = true; - } - - /// - /// Serializes settings dictionary into a string, for saving settings to a file. - /// - /// Serialized settings. - public string Serialize() { - StringBuilder sb = new StringBuilder(1024); - sb.Append(MAGIC); // augment with version string, which will be stripped - sb.Append("\r\n"); // will be ignored by deserializer; might get converted to \n - - JavaScriptSerializer ser = new JavaScriptSerializer(); - string cereal = ser.Serialize(mSettings); - - // add some linefeeds to make it easier for humans - cereal = CommonUtil.TextUtil.NonQuoteReplace(cereal, ",\"", ",\r\n\""); - sb.Append(cereal); - - // Stick a linefeed at the end. - sb.Append("\r\n"); - return sb.ToString(); - } - - /// - /// Deserializes settings from a string, for loading settings from a file. - /// - /// Serialized settings. - /// Deserialized settings, or null if deserialization failed. - public static AppSettings Deserialize(string cereal) { - if (!cereal.StartsWith(MAGIC)) { - return null; - } - - // Skip past header. - cereal = cereal.Substring(MAGIC.Length); - - AppSettings settings = new AppSettings(); - JavaScriptSerializer ser = new JavaScriptSerializer(); - try { - settings.mSettings = ser.Deserialize>(cereal); - return settings; - } catch (Exception ex) { - Debug.WriteLine("Settings deserialization failed: " + ex.Message); - return null; - } - } - - #endregion Implementation - } -} diff --git a/SourceGenWF/AsmGen/AsmCc65.cs b/SourceGenWF/AsmGen/AsmCc65.cs deleted file mode 100644 index 3f0edef..0000000 --- a/SourceGenWF/AsmGen/AsmCc65.cs +++ /dev/null @@ -1,869 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.IO; -using System.Text; - -using Asm65; -using CommonUtil; - -namespace SourceGenWF.AsmGen { - #region IGenerator - - /// - /// Generate source code compatible with the cc65 assembler (https://github.com/cc65/cc65). - /// - public class GenCc65 : IGenerator { - private const string ASM_FILE_SUFFIX = "_cc65.S"; // must start with underscore - private const string CFG_FILE_SUFFIX = "_cc65.cfg"; // ditto - private const int MAX_OPERAND_LEN = 64; - - // IGenerator - public DisasmProject Project { get; private set; } - - // IGenerator - public Formatter SourceFormatter { get; private set; } - - // IGenerator - public AppSettings Settings { get; private set; } - - // IGenerator - public AssemblerQuirks Quirks { get; private set; } - - // IGenerator - public LabelLocalizer Localizer { get { return mLocalizer; } } - - /// - /// Working directory, i.e. where we write our output file(s). - /// - private string mWorkDirectory; - - /// - /// If set, long labels get their own line. - /// - private bool mLongLabelNewLine; - - /// - /// Output column widths. - /// - private int[] mColumnWidths; - - /// - /// Base filename. Typically the project file name without the ".dis65" extension. - /// - private string mFileNameBase; - - /// - /// StringBuilder to use when composing a line. Held here to reduce allocations. - /// - private StringBuilder mLineBuilder = new StringBuilder(100); - - /// - /// Label localization helper. - /// - private LabelLocalizer mLocalizer; - - /// - /// Stream to send the output to. - /// - private StreamWriter mOutStream; - - /// - /// The first time we output a high-ASCII string, we generate a macro for it. - /// - private bool mHighAsciiMacroOutput; - - /// - /// Holds detected version of configured assembler. - /// - private CommonUtil.Version mAsmVersion = CommonUtil.Version.NO_VERSION; - - // We test against this in a few places. - private static CommonUtil.Version V2_17 = new CommonUtil.Version(2, 17); - - - // Pseudo-op string constants. - private static PseudoOp.PseudoOpNames sDataOpNames = new PseudoOp.PseudoOpNames() { - EquDirective = "=", - OrgDirective = ".org", - //RegWidthDirective // .a8, .a16, .i8, .i16 - DefineData1 = ".byte", - DefineData2 = ".word", - DefineData3 = ".faraddr", - DefineData4 = ".dword", - DefineBigData2 = ".dbyt", - //DefineBigData3 - //DefineBigData4 - Fill = ".res", - //Dense // no equivalent, use .byte with comma-separated args - StrGeneric = ".byte", - //StrReverse - StrNullTerm = ".asciiz", - //StrLen8 // macro with .strlen? - //StrLen16 - //StrDci - //StrDciReverse - }; - - - // IGenerator - public void GetDefaultDisplayFormat(out PseudoOp.PseudoOpNames pseudoOps, - out Formatter.FormatConfig formatConfig) { - pseudoOps = new PseudoOp.PseudoOpNames() { - EquDirective = "=", - OrgDirective = ".org", - DefineData1 = ".byte", - DefineData2 = ".word", - DefineData3 = ".faraddr", - DefineData4 = ".dword", - DefineBigData2 = ".dbyt", - Fill = ".res", - StrGeneric = ".byte", - StrNullTerm = ".asciiz", - }; - - formatConfig = new Formatter.FormatConfig(); - SetFormatConfigValues(ref formatConfig); - } - - // IGenerator - public void Configure(DisasmProject project, string workDirectory, string fileNameBase, - AssemblerVersion asmVersion, AppSettings settings) { - Debug.Assert(project != null); - Debug.Assert(!string.IsNullOrEmpty(workDirectory)); - Debug.Assert(!string.IsNullOrEmpty(fileNameBase)); - - Project = project; - Quirks = new AssemblerQuirks(); - if (asmVersion != null) { - // Use the actual version. If it's > 2.17 we'll try to take advantage of - // bug fixes. - mAsmVersion = asmVersion.Version; - } else { - // No assembler installed. Use 2.17. - mAsmVersion = V2_17; - } - if (mAsmVersion <= V2_17) { - // cc65 v2.17: https://github.com/cc65/cc65/issues/717 - Quirks.BlockMoveArgsReversed = true; - // cc65 v2.17: https://github.com/cc65/cc65/issues/754 - Quirks.NoPcRelBankWrap = true; - } - Quirks.SinglePassAssembler = true; - - mWorkDirectory = workDirectory; - mFileNameBase = fileNameBase; - Settings = settings; - - mLongLabelNewLine = Settings.GetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, false); - - AssemblerConfig config = AssemblerConfig.GetConfig(settings, - AssemblerInfo.Id.Cc65); - mColumnWidths = (int[])config.ColumnWidths.Clone(); - } - - /// - /// Configures the assembler-specific format items. - /// - private void SetFormatConfigValues(ref Formatter.FormatConfig config) { - config.mForceAbsOpcodeSuffix = string.Empty; - config.mForceLongOpcodeSuffix = string.Empty; - config.mForceDirectOperandPrefix = "z:"; // zero - config.mForceAbsOperandPrefix = "a:"; // absolute - config.mForceLongOperandPrefix = "f:"; // far - config.mEndOfLineCommentDelimiter = ";"; - config.mFullLineCommentDelimiterBase = ";"; - config.mBoxLineCommentDelimiter = ";"; - config.mAllowHighAsciiCharConst = false; - config.mExpressionMode = Formatter.FormatConfig.ExpressionMode.Cc65; - } - - // IGenerator - public List GenerateSource(BackgroundWorker worker) { - List pathNames = new List(1); - - string pathName = Path.Combine(mWorkDirectory, mFileNameBase + ASM_FILE_SUFFIX); - pathNames.Add(pathName); - string cfgName = Path.Combine(mWorkDirectory, mFileNameBase + CFG_FILE_SUFFIX); - pathNames.Add(cfgName); - - Formatter.FormatConfig config = new Formatter.FormatConfig(); - GenCommon.ConfigureFormatterFromSettings(Settings, ref config); - SetFormatConfigValues(ref config); - SourceFormatter = new Formatter(config); - - string msg = string.Format(Properties.Resources.PROGRESS_GENERATING_FMT, pathName); - worker.ReportProgress(0, msg); - - mLocalizer = new LabelLocalizer(Project); - if (!Settings.GetBool(AppSettings.SRCGEN_DISABLE_LABEL_LOCALIZATION, false)) { - mLocalizer.LocalPrefix = "@"; - mLocalizer.Analyze(); - } - - // Use UTF-8 encoding, without a byte-order mark. - using (StreamWriter sw = new StreamWriter(cfgName, false, new UTF8Encoding(false))) { - GenerateLinkerScript(sw); - } - using (StreamWriter sw = new StreamWriter(pathName, false, new UTF8Encoding(false))) { - mOutStream = sw; - - if (Settings.GetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false)) { - //if (mAsmVersion.IsValid && mAsmVersion <= V2_17) { - // OutputLine(SourceFormatter.FullLineCommentDelimiter + - // string.Format(Properties.Resources.GENERATED_FOR_VERSION, - // "cc65", mAsmVersion.ToString())); - //} else { - // OutputLine(SourceFormatter.FullLineCommentDelimiter + - // string.Format(Properties.Resources.GENERATED_FOR_LATEST, "cc65")); - //} - - // Currently generating code for v2.17. - OutputLine(SourceFormatter.FullLineCommentDelimiter + - string.Format(Properties.Resources.GENERATED_FOR_VERSION, - "cc65", V2_17, - AsmCc65.OPTIONS + " -C " + Path.GetFileName(cfgName))); - } - - GenCommon.Generate(this, sw, worker); - } - mOutStream = null; - - return pathNames; - } - - private void GenerateLinkerScript(StreamWriter sw) { - sw.WriteLine("# 6502bench SourceGen generated linker script for " + mFileNameBase); - - sw.WriteLine("MEMORY {"); - sw.WriteLine(" MAIN: file=%O, start=%S, size=65536;"); - for (int i = 0; i < Project.AddrMap.Count; i++) { - AddressMap.AddressMapEntry ame = Project.AddrMap[i]; - sw.WriteLine(string.Format("# MEM{0:D3}: file=%O, start=${1:x4}, size={2};", - i, ame.Addr, ame.Length)); - } - sw.WriteLine("}"); - - sw.WriteLine("SEGMENTS {"); - sw.WriteLine(" CODE: load=MAIN, type=rw;"); - for (int i = 0; i < Project.AddrMap.Count; i++) { - sw.WriteLine(string.Format("# SEG{0:D3}: load=MEM{0:D3}, type=rw;", i)); - } - sw.WriteLine("}"); - - sw.WriteLine("FEATURES {}"); - sw.WriteLine("SYMBOLS {}"); - } - - // IGenerator - public void OutputAsmConfig() { - CpuDef cpuDef = Project.CpuDef; - string cpuStr; - if (cpuDef.Type == CpuDef.CpuType.Cpu65816) { - cpuStr = "65816"; - } else if (cpuDef.Type == CpuDef.CpuType.Cpu65C02) { - cpuStr = "65C02"; - } else if (cpuDef.Type == CpuDef.CpuType.Cpu6502 && cpuDef.HasUndocumented) { - cpuStr = "6502X"; - } else { - cpuStr = "6502"; - } - - OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(".setcpu"), - '\"' + cpuStr + '\"', string.Empty); - } - - /// - /// Map the undocumented opcodes to the cc65 mnemonics. There's almost no difference - /// vs. the Unintended Opcodes mnemonics. - /// - /// We don't include the double- and triple-byte NOPs here, as cc65 doesn't - /// appear to have a definition for them (as of 2.17). We also omit the alias - /// for SBC. These will all be output as hex. - /// - private static Dictionary sUndocMap = new Dictionary() { - { OpName.ALR, "alr" }, // imm 0x4b - { OpName.ANC, "anc" }, // imm 0x0b (and others) - { OpName.ANE, "ane" }, // imm 0x8b - { OpName.ARR, "arr" }, // imm 0x6b - { OpName.DCP, "dcp" }, // abs 0xcf - { OpName.ISC, "isc" }, // abs 0xef - { OpName.JAM, "jam" }, // abs 0x02 (and others) - { OpName.LAS, "las" }, // abs,y 0xbb - { OpName.LAX, "lax" }, // imm 0xab; abs 0xaf - { OpName.RLA, "rla" }, // abs 0x2f - { OpName.RRA, "rra" }, // abs 0x6f - { OpName.SAX, "sax" }, // abs 0x8f - { OpName.SBX, "axs" }, //* imm 0xcb - { OpName.SHA, "sha" }, // abs,y 0x9f - { OpName.SHX, "shx" }, // abs,y 0x9e - { OpName.SHY, "shy" }, // abs,x 0x9c - { OpName.SLO, "slo" }, // abs 0x0f - { OpName.SRE, "sre" }, // abs 0x4f - { OpName.TAS, "tas" }, // abs,y 0x9b - }; - - // IGenerator - public string ModifyOpcode(int offset, OpDef op) { - if ((op == OpDef.OpWDM_WDM || op == OpDef.OpBRK_StackInt) && mAsmVersion <= V2_17) { - // cc65 v2.17 doesn't support WDM, and assembles BRK to opcode $05. - // https://github.com/cc65/cc65/issues/715 - // https://github.com/cc65/cc65/issues/716 - return null; - } else if (op.IsUndocumented) { - if (sUndocMap.TryGetValue(op.Mnemonic, out string newValue)) { - if ((op.Mnemonic == OpName.ANC && op.Opcode != 0x0b) || - (op.Mnemonic == OpName.JAM && op.Opcode != 0x02)) { - // There are multiple opcodes for the same thing. cc65 outputs - // one specific thing, so we need to match that, and just do a hex - // dump for the others. - return null; - } - return newValue; - } - // Unmapped values include DOP, TOP, and the alternate SBC. Output hex. - return null; - } else { - return string.Empty; - } - } - - // IGenerator - public void GenerateShortSequence(int offset, int length, out string opcode, - out string operand) { - Debug.Assert(length >= 1 && length <= 4); - - // Use a comma-separated list of individual hex bytes. - opcode = sDataOpNames.DefineData1; - - StringBuilder sb = new StringBuilder(length * 4); - for (int i = 0; i < length; i++) { - if (i != 0) { - sb.Append(','); - } - sb.Append(SourceFormatter.FormatHexValue(Project.FileData[offset + i], 2)); - } - operand = sb.ToString(); - } - - // IGenerator - public void OutputDataOp(int offset) { - Formatter formatter = SourceFormatter; - byte[] data = Project.FileData; - Anattrib attr = Project.GetAnattrib(offset); - - string labelStr = string.Empty; - if (attr.Symbol != null) { - labelStr = mLocalizer.ConvLabel(attr.Symbol.Label); - } - - string commentStr = SourceFormatter.FormatEolComment(Project.Comments[offset]); - string opcodeStr, operandStr; - - FormatDescriptor dfd = attr.DataDescriptor; - Debug.Assert(dfd != null); - int length = dfd.Length; - Debug.Assert(length > 0); - - bool multiLine = false; - switch (dfd.FormatType) { - case FormatDescriptor.Type.Default: - if (length != 1) { - Debug.Assert(false); - length = 1; - } - opcodeStr = sDataOpNames.DefineData1; - int operand = RawData.GetWord(data, offset, length, false); - operandStr = formatter.FormatHexValue(operand, length * 2); - break; - case FormatDescriptor.Type.NumericLE: - opcodeStr = sDataOpNames.GetDefineData(length); - operand = RawData.GetWord(data, offset, length, false); - operandStr = PseudoOp.FormatNumericOperand(formatter, Project.SymbolTable, - mLocalizer.LabelMap, dfd, operand, length, - PseudoOp.FormatNumericOpFlags.None); - break; - case FormatDescriptor.Type.NumericBE: - opcodeStr = sDataOpNames.GetDefineBigData(length); - if (opcodeStr == null) { - // Nothing defined, output as comma-separated single-byte values. - GenerateShortSequence(offset, length, out opcodeStr, out operandStr); - } else { - operand = RawData.GetWord(data, offset, length, true); - operandStr = PseudoOp.FormatNumericOperand(formatter, Project.SymbolTable, - mLocalizer.LabelMap, dfd, operand, length, - PseudoOp.FormatNumericOpFlags.None); - } - break; - case FormatDescriptor.Type.Fill: - opcodeStr = sDataOpNames.Fill; - operandStr = length + "," + formatter.FormatHexValue(data[offset], 2); - break; - case FormatDescriptor.Type.Dense: - multiLine = true; - opcodeStr = operandStr = null; - OutputDenseHex(offset, length, labelStr, commentStr); - break; - case FormatDescriptor.Type.String: - multiLine = true; - opcodeStr = operandStr = null; - OutputString(offset, labelStr, commentStr); - break; - default: - opcodeStr = "???"; - operandStr = "***"; - break; - } - - if (!multiLine) { - opcodeStr = formatter.FormatPseudoOp(opcodeStr); - OutputLine(labelStr, opcodeStr, operandStr, commentStr); - } - } - - private void OutputDenseHex(int offset, int length, string labelStr, string commentStr) { - Formatter formatter = SourceFormatter; - byte[] data = Project.FileData; - StringBuilder sb = new StringBuilder(MAX_OPERAND_LEN); - - string opcodeStr = formatter.FormatPseudoOp(sDataOpNames.DefineData1); - - int maxPerLine = MAX_OPERAND_LEN / 4; - int numChunks = (length + maxPerLine - 1) / maxPerLine; - for (int chunk = 0; chunk < numChunks; chunk++) { - int chunkStart = chunk * maxPerLine; - int chunkEnd = Math.Min((chunk + 1) * maxPerLine, length); - for (int i = chunkStart; i < chunkEnd; i++) { - if (i != chunkStart) { - sb.Append(','); - } - sb.Append(formatter.FormatHexValue(data[offset + i], 2)); - } - - OutputLine(labelStr, opcodeStr, sb.ToString(), commentStr); - labelStr = commentStr = string.Empty; - sb.Clear(); - } - } - - /// - /// Outputs formatted data in an unformatted way, because the code generator couldn't - /// figure out how to do something better. - /// - private void OutputNoJoy(int offset, int length, string labelStr, string commentStr) { - byte[] data = Project.FileData; - Debug.Assert(length > 0); - Debug.Assert(offset >= 0 && offset < data.Length); - - bool singleValue = true; - byte val = data[offset]; - for (int i = 1; i < length; i++) { - if (data[offset + i] != val) { - singleValue = false; - break; - } - } - - if (singleValue) { - string opcodeStr = SourceFormatter.FormatPseudoOp(sDataOpNames.Fill); - string operandStr = length + "," + SourceFormatter.FormatHexValue(val, 2); - OutputLine(labelStr, opcodeStr, operandStr, commentStr); - } else { - OutputDenseHex(offset, length, labelStr, commentStr); - } - } - - // IGenerator - public void OutputEquDirective(string name, string valueStr, string comment) { - OutputLine(name, SourceFormatter.FormatPseudoOp(sDataOpNames.EquDirective), - valueStr, SourceFormatter.FormatEolComment(comment)); - } - - // IGenerator - public void OutputOrgDirective(int offset, int address) { - // Linear search for offset. List should be small, so this should be quick. - int index = 0; - foreach (AddressMap.AddressMapEntry ame in Project.AddrMap) { - if (ame.Offset == offset) { - break; - } - index++; - } - - mLineBuilder.Clear(); - TextUtil.AppendPaddedString(mLineBuilder, ";", mColumnWidths[0]); - TextUtil.AppendPaddedString(mLineBuilder, SourceFormatter.FormatPseudoOp(" .segment"), - mColumnWidths[1]); - mLineBuilder.AppendFormat("\"SEG{0:D3}\"", index); - OutputLine(mLineBuilder.ToString()); - - OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(sDataOpNames.OrgDirective), - SourceFormatter.FormatHexValue(address, 4), string.Empty); - } - - // IGenerator - public void OutputRegWidthDirective(int offset, int prevM, int prevX, int newM, int newX) { - if (prevM != newM) { - string mop = (newM == 0) ? ".a16" : ".a8"; - OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(mop), - string.Empty, string.Empty); - } - if (prevX != newX) { - string xop = (newX == 0) ? ".i16" : ".i8"; - OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(xop), - string.Empty, string.Empty); - } - } - - // IGenerator - public void OutputLine(string fullLine) { - mOutStream.WriteLine(fullLine); - } - - // IGenerator - public void OutputLine(string label, string opcode, string operand, string comment) { - // If a label is provided, and it doesn't start with a '.' (indicating that it's - // a directive), and this isn't an EQU directive, add a ':'. Might be easier to - // just ".feature labels_without_colons", but I'm trying to do things the way - // that cc65 users will expect. - if (!string.IsNullOrEmpty(label) && label[0] != '.' && - !string.Equals(opcode, sDataOpNames.EquDirective, - StringComparison.InvariantCultureIgnoreCase)) { - label += ':'; - - if (mLongLabelNewLine && label.Length >= mColumnWidths[0]) { - mOutStream.WriteLine(label); - label = string.Empty; - } - } - - mLineBuilder.Clear(); - TextUtil.AppendPaddedString(mLineBuilder, label, mColumnWidths[0]); - TextUtil.AppendPaddedString(mLineBuilder, opcode, mColumnWidths[0] + mColumnWidths[1]); - TextUtil.AppendPaddedString(mLineBuilder, operand, - mColumnWidths[0] + mColumnWidths[1] + mColumnWidths[2]); - if (string.IsNullOrEmpty(comment)) { - // Trim trailing spaces off of opcode or operand. If they want trailing - // spaces at the end of a comment, that's fine. - CommonUtil.TextUtil.TrimEnd(mLineBuilder); - } else { - mLineBuilder.Append(comment); - } - - mOutStream.WriteLine(mLineBuilder.ToString()); - } - - private void OutputString(int offset, string labelStr, string commentStr) { - // Normal ASCII strings are straightforward: they're just part of a .byte - // directive, and can mix with anything else in the .byte. - // - // For CString we can use .asciiz, but only if the string fits on one line - // and doesn't include delimiters. For L8String and L16String we can - // define simple macros, but their use has a similar restriction. High-ASCII - // strings also require a macro. - // - // We might be able to define a macro for DCI and Reverse as well. - // - // The limitation on strings with delimiters arises because (1) I don't see a - // way to escape them within a string, and (2) the simple macro workarounds - // only take a single argument, not a comma-separated list of stuff. - // - // Some ideas here: - // https://groups.google.com/forum/#!topic/comp.sys.apple2.programmer/5Wkw8mUPcU0 - - Formatter formatter = SourceFormatter; - byte[] data = Project.FileData; - Anattrib attr = Project.GetAnattrib(offset); - FormatDescriptor dfd = attr.DataDescriptor; - Debug.Assert(dfd != null); - Debug.Assert(dfd.FormatType == FormatDescriptor.Type.String); - Debug.Assert(dfd.Length > 0); - - bool highAscii = false; - int leadingBytes = 0; - int trailingBytes = 0; - bool showLeading = false; - bool showTrailing = false; - - switch (dfd.FormatSubType) { - case FormatDescriptor.SubType.None: - highAscii = (data[offset] & 0x80) != 0; - break; - case FormatDescriptor.SubType.Dci: - highAscii = (data[offset] & 0x80) != 0; - trailingBytes = 1; - showTrailing = true; - break; - case FormatDescriptor.SubType.Reverse: - highAscii = (data[offset] & 0x80) != 0; - break; - case FormatDescriptor.SubType.DciReverse: - highAscii = (data[offset + dfd.Length - 1] & 0x80) != 0; - leadingBytes = 1; - showLeading = true; - break; - case FormatDescriptor.SubType.CString: - highAscii = (data[offset] & 0x80) != 0; - trailingBytes = 1; - showTrailing = true; - break; - case FormatDescriptor.SubType.L8String: - if (dfd.Length > 1) { - highAscii = (data[offset + 1] & 0x80) != 0; - } - leadingBytes = 1; - showLeading = true; - break; - case FormatDescriptor.SubType.L16String: - if (dfd.Length > 2) { - highAscii = (data[offset + 2] & 0x80) != 0; - } - leadingBytes = 2; - showLeading = true; - break; - default: - Debug.Assert(false); - return; - } - - char delim = '"'; - StringGather gath = null; - - // Run the string through so we can see if it'll fit on one line. As a minor - // optimization, we skip this step for "generic" strings, which are probably - // the most common thing. - if (dfd.FormatSubType != FormatDescriptor.SubType.None || highAscii) { - gath = new StringGather(this, labelStr, "???", commentStr, delim, - delim, StringGather.ByteStyle.CommaSep, MAX_OPERAND_LEN, true); - FeedGath(gath, data, offset, dfd.Length, leadingBytes, showLeading, - trailingBytes, showTrailing); - Debug.Assert(gath.NumLinesOutput > 0); - } - - string opcodeStr = formatter.FormatPseudoOp(sDataOpNames.StrGeneric); - - switch (dfd.FormatSubType) { - case FormatDescriptor.SubType.None: - // Special case for simple short high-ASCII strings. These have no - // leading or trailing bytes. We can improve this a bit by handling - // arbitrarily long strings by simply breaking them across lines. - Debug.Assert(leadingBytes == 0); - Debug.Assert(trailingBytes == 0); - if (highAscii && gath.NumLinesOutput == 1 && !gath.HasDelimiter) { - if (!mHighAsciiMacroOutput) { - mHighAsciiMacroOutput = true; - // Output a macro for high-ASCII strings. - OutputLine(".macro", "HiAscii", "Arg", string.Empty); - OutputLine(string.Empty, ".repeat", ".strlen(Arg), I", string.Empty); - OutputLine(string.Empty, ".byte", ".strat(Arg, I) | $80", string.Empty); - OutputLine(string.Empty, ".endrep", string.Empty, string.Empty); - OutputLine(".endmacro", string.Empty, string.Empty, string.Empty); - } - opcodeStr = formatter.FormatPseudoOp("HiAscii"); - highAscii = false; - } - break; - case FormatDescriptor.SubType.Dci: - case FormatDescriptor.SubType.Reverse: - case FormatDescriptor.SubType.DciReverse: - // Full configured above. - break; - case FormatDescriptor.SubType.CString: - if (gath.NumLinesOutput == 1 && !gath.HasDelimiter) { - opcodeStr = sDataOpNames.StrNullTerm; - showTrailing = false; - } - break; - case FormatDescriptor.SubType.L8String: - case FormatDescriptor.SubType.L16String: - // Implement macros? - break; - default: - Debug.Assert(false); - return; - } - - if (highAscii) { - OutputNoJoy(offset, dfd.Length, labelStr, commentStr); - return; - } - - // Create a new StringGather, with the final opcode choice. - gath = new StringGather(this, labelStr, opcodeStr, commentStr, delim, - delim, StringGather.ByteStyle.CommaSep, MAX_OPERAND_LEN, false); - FeedGath(gath, data, offset, dfd.Length, leadingBytes, showLeading, - trailingBytes, showTrailing); - } - - /// - /// Feeds the bytes into the StringGather. - /// - private void FeedGath(StringGather gath, byte[] data, int offset, int length, - int leadingBytes, bool showLeading, int trailingBytes, bool showTrailing) { - int startOffset = offset; - int strEndOffset = offset + length - trailingBytes; - - if (showLeading) { - while (leadingBytes-- > 0) { - gath.WriteByte(data[offset++]); - } - } else { - offset += leadingBytes; - } - for (; offset < strEndOffset; offset++) { - gath.WriteChar((char)(data[offset] & 0x7f)); - } - while (showTrailing && trailingBytes-- > 0) { - gath.WriteByte(data[offset++]); - } - gath.Finish(); - } - } - - #endregion IGenerator - - - #region IAssembler - - /// - /// Cross-assembler execution interface. - /// - public class AsmCc65 : IAssembler { - // Fixed options. "--target none" is needed to neutralize the character encoding, - // which seems to default to PETSCII. - public const string OPTIONS = "--target none"; - - // Paths from generator. - private List mPathNames; - - // Directory to make current before executing assembler. - private string mWorkDirectory; - - - // IAssembler - public void GetExeIdentifiers(out string humanName, out string exeName) { - humanName = "cc65 CL"; - exeName = "cl65"; - } - - // IAssembler - public AssemblerConfig GetDefaultConfig() { - return new AssemblerConfig(string.Empty, new int[] { 9, 8, 11, 72 }); - } - - // IAssembler - public AssemblerVersion QueryVersion() { - AssemblerConfig config = - AssemblerConfig.GetConfig(AppSettings.Global, AssemblerInfo.Id.Cc65); - if (config == null || string.IsNullOrEmpty(config.ExecutablePath)) { - return null; - } - - ShellCommand cmd = new ShellCommand(config.ExecutablePath, "--version", - Directory.GetCurrentDirectory(), null); - cmd.Execute(); - if (string.IsNullOrEmpty(cmd.Stdout)) { - return null; - } - - // Windows - Stderr: "cl65.exe V2.17\r\n" - // Linux - Stderr: "cl65 V2.17 - Git N/A\n" - // Other platforms may not have the ".exe". Find first occurrence of " V". - - const string PREFIX = " V"; - string str = cmd.Stderr; - int start = str.IndexOf(PREFIX); - int end = (start < 0) ? -1 : str.IndexOfAny(new char[] { ' ', '\r', '\n' }, start + 1); - - if (start < 0 || end < 0 || start + PREFIX.Length >= end) { - Debug.WriteLine("Couldn't find version in " + str); - return null; - } - start += PREFIX.Length; - string versionStr = str.Substring(start, end - start); - CommonUtil.Version version = CommonUtil.Version.Parse(versionStr); - if (!version.IsValid) { - return null; - } - return new AssemblerVersion(versionStr, version); - } - - // IAssembler - public void Configure(List pathNames, string workDirectory) { - // Clone pathNames, in case the caller decides to modify the original. - mPathNames = new List(pathNames.Count); - foreach (string str in pathNames) { - mPathNames.Add(str); - } - - mWorkDirectory = workDirectory; - } - - // IAssembler - public AssemblerResults RunAssembler(BackgroundWorker worker) { - Debug.Assert(mPathNames.Count == 2); - string pathName = StripWorkDirectory(mPathNames[0]); - string cfgName = StripWorkDirectory(mPathNames[1]); - - AssemblerConfig config = - AssemblerConfig.GetConfig(AppSettings.Global, AssemblerInfo.Id.Cc65); - if (string.IsNullOrEmpty(config.ExecutablePath)) { - Debug.WriteLine("Assembler not configured"); - return null; - } - - string cfgOpt = " -C \"" + cfgName + "\""; - - worker.ReportProgress(0, Properties.Resources.PROGRESS_ASSEMBLING); - - // Wrap pathname in quotes in case it has spaces. - // (Do we need to shell-escape quotes in the pathName?) - ShellCommand cmd = new ShellCommand(config.ExecutablePath, - OPTIONS + cfgOpt + " \"" + pathName + "\"", mWorkDirectory, null); - cmd.Execute(); - - // Can't really do anything with a "cancel" request. - - // Output filename is the input filename without the ".S". Since the filename - // was generated by us we can be confident in the format. - string outputFile = mPathNames[0].Substring(0, mPathNames[0].Length - 2); - - return new AssemblerResults(cmd.FullCommandLine, cmd.ExitCode, cmd.Stdout, - cmd.Stderr, outputFile); - } - - /// - /// Reduce input file to a partial path if possible. This is just to make - /// what we display to the user a little easier to read. - /// - /// Full pathname of file. - /// Pathname with working directory prefix stripped off. - private string StripWorkDirectory(string pathName) { - if (pathName.StartsWith(mWorkDirectory)) { - return pathName.Remove(0, mWorkDirectory.Length + 1); - } else { - // Unexpected, but shouldn't be a problem. - Debug.WriteLine("NOTE: source file is not in work directory"); - return pathName; - } - } - } - - #endregion IAssembler -} diff --git a/SourceGenWF/AsmGen/AsmMerlin32.cs b/SourceGenWF/AsmGen/AsmMerlin32.cs deleted file mode 100644 index 8d1b332..0000000 --- a/SourceGenWF/AsmGen/AsmMerlin32.cs +++ /dev/null @@ -1,790 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.IO; -using System.Text; - -using Asm65; -using CommonUtil; - -namespace SourceGenWF.AsmGen { - #region IGenerator - - /// - /// Generate source code compatible with Brutal Deluxe's Merlin 32 assembler - /// (https://www.brutaldeluxe.fr/products/crossdevtools/merlin/). - /// - public class GenMerlin32 : IGenerator { - private const string ASM_FILE_SUFFIX = "_Merlin32.S"; // must start with underscore - private const int MAX_OPERAND_LEN = 64; - - // IGenerator - public DisasmProject Project { get; private set; } - - // IGenerator - public Formatter SourceFormatter { get; private set; } - - // IGenerator - public AppSettings Settings { get; private set; } - - // IGenerator - public AssemblerQuirks Quirks { get; private set; } - - // IGenerator - public LabelLocalizer Localizer { get { return mLocalizer; } } - - /// - /// Working directory, i.e. where we write our output file(s). - /// - private string mWorkDirectory; - - /// - /// If set, long labels get their own line. - /// - private bool mLongLabelNewLine; - - /// - /// Output column widths. - /// - private int[] mColumnWidths; - - /// - /// Base filename. Typically the project file name without the ".dis65" extension. - /// - private string mFileNameBase; - - /// - /// StringBuilder to use when composing a line. Held here to reduce allocations. - /// - private StringBuilder mLineBuilder = new StringBuilder(100); - - /// - /// Label localization helper. - /// - private LabelLocalizer mLocalizer; - - /// - /// Stream to send the output to. - /// - private StreamWriter mOutStream; - - /// - /// Holds detected version of configured assembler. - /// - private CommonUtil.Version mAsmVersion = CommonUtil.Version.NO_VERSION; - - - // Semi-convenient way to hold all the interesting string constants in one place. - // Note the actual usage of the pseudo-op may not match what the main app does, - // e.g. RegWidthDirective behaves differently from "mx". I'm just trying to avoid - // having string constants scattered all over. - private static PseudoOp.PseudoOpNames sDataOpNames = new PseudoOp.PseudoOpNames() { - EquDirective = "equ", - OrgDirective = "org", - RegWidthDirective = "mx", - DefineData1 = "dfb", - DefineData2 = "dw", - DefineData3 = "adr", - DefineData4 = "adrl", - DefineBigData2 = "ddb", - //DefineBigData3 - //DefineBigData4 - Fill = "ds", - Dense = "hex", - StrGeneric = "asc", - StrGenericHi = "asc", - StrReverse = "rev", - StrReverseHi = "rev", - //StrNullTerm - StrLen8 = "str", - StrLen8Hi = "str", - StrLen16 = "strl", - StrLen16Hi = "strl", - StrDci = "dci", - StrDciHi = "dci", - //StrDciReverse - }; - - - // IGenerator - public void GetDefaultDisplayFormat(out PseudoOp.PseudoOpNames pseudoOps, - out Formatter.FormatConfig formatConfig) { - // This is not intended to match up with the Merlin generator, which uses - // the same pseudo-op for low/high ASCII but different string delimiters. We - // don't change the delimiters for the display list, so instead we tweak the - // opcode slightly. - char hiAscii = '\u2191'; - pseudoOps = new PseudoOp.PseudoOpNames() { - EquDirective = "equ", - OrgDirective = "org", - DefineData1 = "dfb", - DefineData2 = "dw", - DefineData3 = "adr", - DefineData4 = "adrl", - DefineBigData2 = "ddb", - Fill = "ds", - Dense = "hex", - StrGeneric = "asc", - StrGenericHi = "asc" + hiAscii, - StrReverse = "rev", - StrReverseHi = "rev" + hiAscii, - StrLen8 = "str", - StrLen8Hi = "str" + hiAscii, - StrLen16 = "strl", - StrLen16Hi = "strl" + hiAscii, - StrDci = "dci", - StrDciHi = "dci" + hiAscii, - }; - - formatConfig = new Formatter.FormatConfig(); - SetFormatConfigValues(ref formatConfig); - } - - // IGenerator - public void Configure(DisasmProject project, string workDirectory, string fileNameBase, - AssemblerVersion asmVersion, AppSettings settings) { - Debug.Assert(project != null); - Debug.Assert(!string.IsNullOrEmpty(workDirectory)); - Debug.Assert(!string.IsNullOrEmpty(fileNameBase)); - - Project = project; - Quirks = new AssemblerQuirks(); - Quirks.TracksSepRepNotEmu = true; - Quirks.NoPcRelBankWrap = true; - - mWorkDirectory = workDirectory; - mFileNameBase = fileNameBase; - Settings = settings; - - mLongLabelNewLine = Settings.GetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, false); - - AssemblerConfig config = AssemblerConfig.GetConfig(settings, - AssemblerInfo.Id.Merlin32); - mColumnWidths = (int[])config.ColumnWidths.Clone(); - } - - /// - /// Configures the assembler-specific format items. - /// - private void SetFormatConfigValues(ref Formatter.FormatConfig config) { - config.mForceAbsOpcodeSuffix = ":"; - config.mForceLongOpcodeSuffix = "l"; - config.mForceDirectOperandPrefix = string.Empty; - config.mForceAbsOperandPrefix = string.Empty; - config.mForceLongOperandPrefix = string.Empty; - config.mEndOfLineCommentDelimiter = ";"; - config.mFullLineCommentDelimiterBase = ";"; - config.mBoxLineCommentDelimiter = string.Empty; - config.mAllowHighAsciiCharConst = true; - config.mExpressionMode = Formatter.FormatConfig.ExpressionMode.Merlin; - } - - // IGenerator; executes on background thread - public List GenerateSource(BackgroundWorker worker) { - List pathNames = new List(1); - - string fileName = mFileNameBase + ASM_FILE_SUFFIX; - string pathName = Path.Combine(mWorkDirectory, fileName); - pathNames.Add(pathName); - - Formatter.FormatConfig config = new Formatter.FormatConfig(); - GenCommon.ConfigureFormatterFromSettings(Settings, ref config); - SetFormatConfigValues(ref config); - SourceFormatter = new Formatter(config); - - string msg = string.Format(Properties.Resources.PROGRESS_GENERATING_FMT, pathName); - worker.ReportProgress(0, msg); - - mLocalizer = new LabelLocalizer(Project); - if (!Settings.GetBool(AppSettings.SRCGEN_DISABLE_LABEL_LOCALIZATION, false)) { - mLocalizer.LocalPrefix = ":"; - mLocalizer.Analyze(); - } - - // Use UTF-8 encoding, without a byte-order mark. - using (StreamWriter sw = new StreamWriter(pathName, false, new UTF8Encoding(false))) { - mOutStream = sw; - - if (Settings.GetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false)) { - // No version-specific stuff yet. We're generating code for v1.0. - OutputLine(SourceFormatter.FullLineCommentDelimiter + - string.Format(Properties.Resources.GENERATED_FOR_VERSION, - "Merlin 32", new CommonUtil.Version(1, 0), string.Empty)); - } - - GenCommon.Generate(this, sw, worker); - } - mOutStream = null; - - return pathNames; - } - - // IGenerator - public void OutputDataOp(int offset) { - Formatter formatter = SourceFormatter; - byte[] data = Project.FileData; - Anattrib attr = Project.GetAnattrib(offset); - - string labelStr = string.Empty; - if (attr.Symbol != null) { - labelStr = mLocalizer.ConvLabel(attr.Symbol.Label); - } - - string commentStr = SourceFormatter.FormatEolComment(Project.Comments[offset]); - string opcodeStr, operandStr; - - FormatDescriptor dfd = attr.DataDescriptor; - Debug.Assert(dfd != null); - int length = dfd.Length; - Debug.Assert(length > 0); - - bool multiLine = false; - switch (dfd.FormatType) { - case FormatDescriptor.Type.Default: - if (length != 1) { - Debug.Assert(false); - length = 1; - } - opcodeStr = sDataOpNames.DefineData1; - int operand = RawData.GetWord(data, offset, length, false); - operandStr = formatter.FormatHexValue(operand, length * 2); - break; - case FormatDescriptor.Type.NumericLE: - opcodeStr = sDataOpNames.GetDefineData(length); - operand = RawData.GetWord(data, offset, length, false); - operandStr = PseudoOp.FormatNumericOperand(formatter, Project.SymbolTable, - mLocalizer.LabelMap, dfd, operand, length, - PseudoOp.FormatNumericOpFlags.None); - break; - case FormatDescriptor.Type.NumericBE: - opcodeStr = sDataOpNames.GetDefineBigData(length); - if (opcodeStr == null) { - // Nothing defined, output as comma-separated single-byte values. - GenerateShortSequence(offset, length, out opcodeStr, out operandStr); - } else { - operand = RawData.GetWord(data, offset, length, true); - operandStr = PseudoOp.FormatNumericOperand(formatter, Project.SymbolTable, - mLocalizer.LabelMap, dfd, operand, length, - PseudoOp.FormatNumericOpFlags.None); - } - break; - case FormatDescriptor.Type.Fill: - opcodeStr = sDataOpNames.Fill; - operandStr = length + "," + formatter.FormatHexValue(data[offset], 2); - break; - case FormatDescriptor.Type.Dense: - multiLine = true; - opcodeStr = operandStr = null; - OutputDenseHex(offset, length, labelStr, commentStr); - break; - case FormatDescriptor.Type.String: - multiLine = true; - opcodeStr = operandStr = null; - OutputString(offset, labelStr, commentStr); - break; - default: - opcodeStr = "???"; - operandStr = "***"; - break; - } - - if (!multiLine) { - opcodeStr = formatter.FormatPseudoOp(opcodeStr); - OutputLine(labelStr, opcodeStr, operandStr, commentStr); - } - } - - private void OutputDenseHex(int offset, int length, string labelStr, string commentStr) { - Formatter formatter = SourceFormatter; - byte[] data = Project.FileData; - int maxPerLine = MAX_OPERAND_LEN / 2; - - string opcodeStr = formatter.FormatPseudoOp(sDataOpNames.Dense); - for (int i = 0; i < length; i += maxPerLine) { - int subLen = length - i; - if (subLen > maxPerLine) { - subLen = maxPerLine; - } - string operandStr = formatter.FormatDenseHex(data, offset + i, subLen); - - OutputLine(labelStr, opcodeStr, operandStr, commentStr); - labelStr = commentStr = string.Empty; - } - } - - // IGenerator - public string ModifyOpcode(int offset, OpDef op) { - if (op.IsUndocumented) { - return null; - } - - // The assembler works correctly if the symbol is defined as a two-digit hex - // value (e.g. "foo equ $80") but fails if it's four (e.g. "foo equ $0080"). We - // output symbols with minimal digits, but this doesn't help if the code itself - // lives on zero page. If the operand is a reference to a zero-page user label, - // we need to output the instruction as hex. - // More info: https://github.com/apple2accumulator/merlin32/issues/8 - if (op == OpDef.OpPEI_StackDPInd || - op == OpDef.OpSTY_DPIndexX || - op == OpDef.OpSTX_DPIndexY || - op.AddrMode == OpDef.AddressMode.DPIndLong || - op.AddrMode == OpDef.AddressMode.DPInd || - op.AddrMode == OpDef.AddressMode.DPIndexXInd) { - FormatDescriptor dfd = Project.GetAnattrib(offset).DataDescriptor; - if (dfd != null && dfd.HasSymbol) { - // It has a symbol. See if the symbol target is a label (auto or user). - if (Project.SymbolTable.TryGetValue(dfd.SymbolRef.Label, out Symbol sym)) { - if (sym.IsInternalLabel) { - return null; - } - } - } - } - - return string.Empty; - } - - // IGenerator - public void GenerateShortSequence(int offset, int length, out string opcode, - out string operand) { - Debug.Assert(length >= 1 && length <= 4); - - // Use a comma-separated list of individual hex bytes. - opcode = sDataOpNames.DefineData1; - - StringBuilder sb = new StringBuilder(length * 4); - for (int i = 0; i < length; i++) { - if (i != 0) { - sb.Append(','); - } - sb.Append(SourceFormatter.FormatHexValue(Project.FileData[offset + i], 2)); - } - operand = sb.ToString(); - } - - // IGenerator - public void OutputAsmConfig() { - // nothing to do - } - - // IGenerator - public void OutputEquDirective(string name, string valueStr, string comment) { - OutputLine(name, SourceFormatter.FormatPseudoOp(sDataOpNames.EquDirective), - valueStr, SourceFormatter.FormatEolComment(comment)); - } - - // IGenerator - public void OutputOrgDirective(int offset, int address) { - OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(sDataOpNames.OrgDirective), - SourceFormatter.FormatHexValue(address, 4), string.Empty); - } - - // IGenerator - public void OutputRegWidthDirective(int offset, int prevM, int prevX, int newM, int newX) { - // prevM/prevX may be ambiguous for offset 0, but otherwise everything - // should be either 0 or 1. - Debug.Assert(newM == 0 || newM == 1); - Debug.Assert(newX == 0 || newX == 1); - - if (offset == 0 && newM == 1 && newX == 1) { - // Assembler defaults to short regs, so we can skip this. - return; - } - OutputLine(string.Empty, - SourceFormatter.FormatPseudoOp(sDataOpNames.RegWidthDirective), - "%" + newM + newX, string.Empty); - } - - // IGenerator - public void OutputLine(string fullLine) { - mOutStream.WriteLine(fullLine); - } - - // IGenerator - public void OutputLine(string label, string opcode, string operand, string comment) { - // Split long label, but not on EQU directives (confuses the assembler). - if (mLongLabelNewLine && label.Length >= mColumnWidths[0] && - !string.Equals(opcode, sDataOpNames.EquDirective, - StringComparison.InvariantCultureIgnoreCase)) { - mOutStream.WriteLine(label); - label = string.Empty; - } - - mLineBuilder.Clear(); - TextUtil.AppendPaddedString(mLineBuilder, label, mColumnWidths[0]); - TextUtil.AppendPaddedString(mLineBuilder, opcode, mColumnWidths[0] + mColumnWidths[1]); - TextUtil.AppendPaddedString(mLineBuilder, operand, - mColumnWidths[0] + mColumnWidths[1] + mColumnWidths[2]); - if (string.IsNullOrEmpty(comment)) { - // Trim trailing spaces off of opcode or operand. If they want trailing - // spaces at the end of a comment, that's fine. - CommonUtil.TextUtil.TrimEnd(mLineBuilder); - } else { - mLineBuilder.Append(comment); - } - - mOutStream.WriteLine(mLineBuilder.ToString()); - } - - - private enum RevMode { Forward, Reverse, BlockReverse }; - - private void OutputString(int offset, string labelStr, string commentStr) { - // This gets complicated. - // - // For Dci, L8String, and L16String, the entire string needs to fit in the - // operand of one line. If it can't, we need to separate the length byte/word - // or inverted character out, and just dump the rest as ASCII. Computing the - // line length requires factoring delimiter character escapes. (NOTE: contrary - // to the documentation, STR and STRL do include trailing hex characters in the - // length calculation, so it's possible to escape delimiters.) - // - // For Reverse, we can span lines, but only if we emit the lines in - // backward order. Also, Merlin doesn't allow hex to be embedded in a REV - // operation, so we can't use REV if the string contains a delimiter. - // - // DciReverse is deprecated, but we can handle it as a Reverse string with a - // trailing byte on a following line. - // - // For aesthetic purposes, zero-length CString, L8String, and L16String - // should be output as DFB/DW zeroes rather than an empty string -- makes - // it easier to read. - - Formatter formatter = SourceFormatter; - byte[] data = Project.FileData; - Anattrib attr = Project.GetAnattrib(offset); - FormatDescriptor dfd = attr.DataDescriptor; - Debug.Assert(dfd != null); - Debug.Assert(dfd.FormatType == FormatDescriptor.Type.String); - Debug.Assert(dfd.Length > 0); - - bool highAscii = false; - int showZeroes = 0; - int leadingBytes = 0; - int trailingBytes = 0; - bool showLeading = false; - bool showTrailing = false; - RevMode revMode = RevMode.Forward; - - switch (dfd.FormatSubType) { - case FormatDescriptor.SubType.None: - highAscii = (data[offset] & 0x80) != 0; - break; - case FormatDescriptor.SubType.Dci: - highAscii = (data[offset] & 0x80) != 0; - break; - case FormatDescriptor.SubType.Reverse: - highAscii = (data[offset] & 0x80) != 0; - revMode = RevMode.Reverse; - break; - case FormatDescriptor.SubType.DciReverse: - highAscii = (data[offset + dfd.Length - 1] & 0x80) != 0; - revMode = RevMode.Reverse; - break; - case FormatDescriptor.SubType.CString: - highAscii = (data[offset] & 0x80) != 0; - if (dfd.Length == 1) { - showZeroes = 1; // empty null-terminated string - } - trailingBytes = 1; - showTrailing = true; - break; - case FormatDescriptor.SubType.L8String: - if (dfd.Length > 1) { - highAscii = (data[offset + 1] & 0x80) != 0; - } else { - //showZeroes = 1; - } - leadingBytes = 1; - break; - case FormatDescriptor.SubType.L16String: - if (dfd.Length > 2) { - highAscii = (data[offset + 2] & 0x80) != 0; - } else { - //showZeroes = 2; - } - leadingBytes = 2; - break; - default: - Debug.Assert(false); - return; - } - - if (showZeroes != 0) { - // Empty string. Just output the length byte(s) or null terminator. - GenerateShortSequence(offset, showZeroes, out string opcode, out string operand); - OutputLine(labelStr, opcode, operand, commentStr); - return; - } - - // Merlin 32 uses single-quote for low ASCII, double-quote for high ASCII. When - // quoting the delimiter we use a hexadecimal value. We need to bear in mind that - // we're forcing the characters to low ASCII, but the actual character being - // escaped might be in high ASCII. Hence delim vs. delimReplace. - char delim = highAscii ? '"' : '\''; - char delimReplace = highAscii ? ((char)(delim | 0x80)) : delim; - StringGather gath = null; - - // Run the string through so we can see if it'll fit on one line. As a minor - // optimization, we skip this step for "generic" strings, which are probably - // the most common thing. - if (dfd.FormatSubType != FormatDescriptor.SubType.None) { - gath = new StringGather(this, labelStr, "???", commentStr, delim, - delimReplace, StringGather.ByteStyle.DenseHex, MAX_OPERAND_LEN, true); - FeedGath(gath, data, offset, dfd.Length, revMode, leadingBytes, showLeading, - trailingBytes, showTrailing); - Debug.Assert(gath.NumLinesOutput > 0); - } - - string opcodeStr; - - switch (dfd.FormatSubType) { - case FormatDescriptor.SubType.None: - opcodeStr = highAscii ? sDataOpNames.StrGenericHi : sDataOpNames.StrGeneric; - break; - case FormatDescriptor.SubType.Dci: - if (gath.NumLinesOutput == 1) { - opcodeStr = highAscii ? sDataOpNames.StrDciHi : sDataOpNames.StrDci; - } else { - opcodeStr = highAscii ? sDataOpNames.StrGenericHi : sDataOpNames.StrGeneric; - trailingBytes = 1; - showTrailing = true; - } - break; - case FormatDescriptor.SubType.Reverse: - if (gath.HasDelimiter) { - // can't include escaped delimiters in REV - opcodeStr = highAscii ? sDataOpNames.StrGenericHi : sDataOpNames.StrGeneric; - revMode = RevMode.Forward; - } else if (gath.NumLinesOutput > 1) { - opcodeStr = highAscii ? sDataOpNames.StrReverseHi : sDataOpNames.StrReverse; - revMode = RevMode.BlockReverse; - } else { - opcodeStr = highAscii ? sDataOpNames.StrReverseHi : sDataOpNames.StrReverse; - Debug.Assert(revMode == RevMode.Reverse); - } - break; - case FormatDescriptor.SubType.DciReverse: - // Mostly punt -- output as ASCII with special handling for first byte. - opcodeStr = highAscii ? sDataOpNames.StrGenericHi : sDataOpNames.StrGeneric; - revMode = RevMode.Forward; - leadingBytes = 1; - showLeading = true; - break; - case FormatDescriptor.SubType.CString: - //opcodeStr = sDataOpNames.StrNullTerm[highAscii ? 1 : 0]; - opcodeStr = highAscii ? sDataOpNames.StrGenericHi : sDataOpNames.StrGeneric; - break; - case FormatDescriptor.SubType.L8String: - if (gath.NumLinesOutput == 1) { - opcodeStr = highAscii ? sDataOpNames.StrLen8Hi : sDataOpNames.StrLen8; - } else { - opcodeStr = highAscii ? sDataOpNames.StrGenericHi : sDataOpNames.StrGeneric; - leadingBytes = 1; - showLeading = true; - } - break; - case FormatDescriptor.SubType.L16String: - if (gath.NumLinesOutput == 1) { - opcodeStr = highAscii ? sDataOpNames.StrLen16Hi : sDataOpNames.StrLen16; - } else { - opcodeStr = highAscii ? sDataOpNames.StrGenericHi : sDataOpNames.StrGeneric; - leadingBytes = 2; - showLeading = true; - } - break; - default: - Debug.Assert(false); - return; - } - - opcodeStr = formatter.FormatPseudoOp(opcodeStr); - - // Create a new StringGather, with the final opcode choice. - gath = new StringGather(this, labelStr, opcodeStr, commentStr, delim, - delimReplace, StringGather.ByteStyle.DenseHex, MAX_OPERAND_LEN, false); - FeedGath(gath, data, offset, dfd.Length, revMode, leadingBytes, showLeading, - trailingBytes, showTrailing); - } - - /// - /// Feeds the bytes into the StringGather. - /// - private void FeedGath(StringGather gath, byte[] data, int offset, int length, - RevMode revMode, int leadingBytes, bool showLeading, - int trailingBytes, bool showTrailing) { - int startOffset = offset; - int strEndOffset = offset + length - trailingBytes; - - if (showLeading) { - while (leadingBytes-- > 0) { - gath.WriteByte(data[offset++]); - } - } else { - offset += leadingBytes; - } - if (revMode == RevMode.BlockReverse) { - const int maxPerLine = MAX_OPERAND_LEN - 2; - int numBlockLines = (length + maxPerLine - 1) / maxPerLine; - - for (int chunk = 0; chunk < numBlockLines; chunk++) { - int chunkOffset = startOffset + chunk * maxPerLine; - int endOffset = chunkOffset + maxPerLine; - if (endOffset > strEndOffset) { - endOffset = strEndOffset; - } - for (int off = endOffset - 1; off >= chunkOffset; off--) { - gath.WriteChar((char)(data[off] & 0x7f)); - } - } - } else { - for (; offset < strEndOffset; offset++) { - if (revMode == RevMode.Forward) { - gath.WriteChar((char)(data[offset] & 0x7f)); - } else if (revMode == RevMode.Reverse) { - int posn = startOffset + (strEndOffset - offset) - 1; - gath.WriteChar((char)(data[posn] & 0x7f)); - } else { - Debug.Assert(false); - } - } - } - while (showTrailing && trailingBytes-- > 0) { - gath.WriteByte(data[offset++]); - } - gath.Finish(); - } - } - - #endregion IGenerator - - - #region IAssembler - - /// - /// Cross-assembler execution interface. - /// - public class AsmMerlin32 : IAssembler { - // Paths from generator. - private List mPathNames; - - // Directory to make current before executing assembler. - private string mWorkDirectory; - - - // IAssembler - public void GetExeIdentifiers(out string humanName, out string exeName) { - humanName = "Merlin Assembler"; - exeName = "Merlin32"; - } - - // IAssembler - public AssemblerConfig GetDefaultConfig() { - return new AssemblerConfig(string.Empty, new int[] { 9, 6, 11, 74 }); - } - - // IAssembler - public AssemblerVersion QueryVersion() { - AssemblerConfig config = - AssemblerConfig.GetConfig(AppSettings.Global, AssemblerInfo.Id.Merlin32); - if (config == null || string.IsNullOrEmpty(config.ExecutablePath)) { - return null; - } - - ShellCommand cmd = new ShellCommand(config.ExecutablePath, string.Empty, - Directory.GetCurrentDirectory(), null); - cmd.Execute(); - if (string.IsNullOrEmpty(cmd.Stdout)) { - return null; - } - - // Stdout: "C:\Src\WorkBench\Merlin32.exe v 1.0, (c) Brutal Deluxe ..." - // Other platforms may not have the ".exe". Find first occurrence of " v ". - - const string PREFIX = " v "; // not expecting this to appear in the path - string str = cmd.Stdout; - int start = str.IndexOf(PREFIX); - int end = (start < 0) ? -1 : str.IndexOf(',', start); - - if (start < 0 || end < 0 || start + PREFIX.Length >= end) { - Debug.WriteLine("Couldn't find version in " + str); - return null; - } - start += PREFIX.Length; - string versionStr = str.Substring(start, end - start); - CommonUtil.Version version = CommonUtil.Version.Parse(versionStr); - if (!version.IsValid) { - return null; - } - return new AssemblerVersion(versionStr, version); - } - - // IAssembler - public void Configure(List pathNames, string workDirectory) { - // Clone pathNames, in case the caller decides to modify the original. - mPathNames = new List(pathNames.Count); - foreach (string str in pathNames) { - mPathNames.Add(str); - } - - mWorkDirectory = workDirectory; - } - - // IAssembler - public AssemblerResults RunAssembler(BackgroundWorker worker) { - // Reduce input file to a partial path if possible. This is really just to make - // what we display to the user a little easier to read. - string pathName = mPathNames[0]; - if (pathName.StartsWith(mWorkDirectory)) { - pathName = pathName.Remove(0, mWorkDirectory.Length + 1); - } else { - // Unexpected, but shouldn't be a problem. - Debug.WriteLine("NOTE: source file is not in work directory"); - } - - AssemblerConfig config = - AssemblerConfig.GetConfig(AppSettings.Global, AssemblerInfo.Id.Merlin32); - if (string.IsNullOrEmpty(config.ExecutablePath)) { - Debug.WriteLine("Assembler not configured"); - return null; - } - - worker.ReportProgress(0, Properties.Resources.PROGRESS_ASSEMBLING); - - // Wrap pathname in quotes in case it has spaces. - // (Do we need to shell-escape quotes in the pathName?) - // - // Merlin 32 has no options. The second argument is the macro include file path. - ShellCommand cmd = new ShellCommand(config.ExecutablePath, ". \"" + pathName + "\"", - mWorkDirectory, null); - cmd.Execute(); - - // Can't really do anything with a "cancel" request. - - // Output filename is the input filename without the ".S". Since the filename - // was generated by us we can be confident in the format. - string outputFile = mPathNames[0].Substring(0, mPathNames[0].Length - 2); - - return new AssemblerResults(cmd.FullCommandLine, cmd.ExitCode, cmd.Stdout, - cmd.Stderr, outputFile); - } - } - - #endregion IAssembler -} diff --git a/SourceGenWF/AsmGen/AsmTass64.cs b/SourceGenWF/AsmGen/AsmTass64.cs deleted file mode 100644 index 579bb5c..0000000 --- a/SourceGenWF/AsmGen/AsmTass64.cs +++ /dev/null @@ -1,778 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.IO; -using System.Text; - -using Asm65; -using CommonUtil; - -namespace SourceGenWF.AsmGen { - #region IGenerator - - /// - /// Generate source code compatible with the 64tass assembler - /// (https://sourceforge.net/projects/tass64/). - /// - /// The assembler is officially called "64tass", but it's sometimes written "tass64" because - /// in some cases you can't start an identifier with a number. - /// - /// We need to deal with a couple of unusual aspects: - /// (1) The prefix for a local label is '_', which is generally a legal character. So - /// if somebody creates a label with a leading '_', and it's not actually local, we have - /// to "de-local" it somehow. - /// (2) By default, labels are handled in a case-insensitive fashion, which is extremely - /// rare for programming languages. Case sensitivity can be enabled with the "-C" flag. - /// Anybody who wants to assemble the generated code will need to be aware of this. - /// - public class GenTass64 : IGenerator { - private const string ASM_FILE_SUFFIX = "_64tass.S"; // must start with underscore - private const int MAX_OPERAND_LEN = 64; - - // IGenerator - public DisasmProject Project { get; private set; } - - // IGenerator - public Formatter SourceFormatter { get; private set; } - - // IGenerator - public AppSettings Settings { get; private set; } - - // IGenerator - public AssemblerQuirks Quirks { get; private set; } - - // IGenerator - public LabelLocalizer Localizer { get { return mLocalizer; } } - - /// - /// Working directory, i.e. where we write our output file(s). - /// - private string mWorkDirectory; - - /// - /// If set, long labels get their own line. - /// - private bool mLongLabelNewLine; - - /// - /// Output column widths. - /// - private int[] mColumnWidths; - - /// - /// Base filename. Typically the project file name without the ".dis65" extension. - /// - private string mFileNameBase; - - /// - /// StringBuilder to use when composing a line. Held here to reduce allocations. - /// - private StringBuilder mLineBuilder = new StringBuilder(100); - - /// - /// Label localization helper. - /// - private LabelLocalizer mLocalizer; - - /// - /// Stream to send the output to. - /// - private StreamWriter mOutStream; - - /// - /// If we output a ".logical", we will need a ".here" eventually. - /// - private bool mNeedHereOp; - - /// - /// Holds detected version of configured assembler. - /// - private CommonUtil.Version mAsmVersion = CommonUtil.Version.NO_VERSION; - - // Version we're coded against. - private static CommonUtil.Version V1_53 = new CommonUtil.Version(1, 53, 1515); - - - // Pseudo-op string constants. - private static PseudoOp.PseudoOpNames sDataOpNames = new PseudoOp.PseudoOpNames() { - EquDirective = "=", - OrgDirective = ".logical", - //RegWidthDirective // .as, .al, .xs, .xl - DefineData1 = ".byte", - DefineData2 = ".word", - DefineData3 = ".long", - DefineData4 = ".dword", - //DefineBigData2 - //DefineBigData3 - //DefineBigData4 - Fill = ".fill", - //Dense // no equivalent, use .byte with comma-separated args - StrGeneric = ".text", - //StrReverse - StrNullTerm = ".null", - StrLen8 = ".ptext", - //StrLen16 - //StrDci - //StrDciReverse - }; - private const string HERE_PSEUDO_OP = ".here"; - - - // IGenerator - public void GetDefaultDisplayFormat(out PseudoOp.PseudoOpNames pseudoOps, - out Formatter.FormatConfig formatConfig) { - pseudoOps = sDataOpNames; - - formatConfig = new Formatter.FormatConfig(); - SetFormatConfigValues(ref formatConfig); - } - - // IGenerator - public void Configure(DisasmProject project, string workDirectory, string fileNameBase, - AssemblerVersion asmVersion, AppSettings settings) { - Debug.Assert(project != null); - Debug.Assert(!string.IsNullOrEmpty(workDirectory)); - Debug.Assert(!string.IsNullOrEmpty(fileNameBase)); - - Project = project; - Quirks = new AssemblerQuirks(); - - mWorkDirectory = workDirectory; - mFileNameBase = fileNameBase; - Settings = settings; - - mLongLabelNewLine = Settings.GetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, false); - - AssemblerConfig config = AssemblerConfig.GetConfig(settings, - AssemblerInfo.Id.Tass64); - mColumnWidths = (int[])config.ColumnWidths.Clone(); - } - - /// - /// Configures the assembler-specific format items. - /// - private void SetFormatConfigValues(ref Formatter.FormatConfig config) { - // Must be lower case when --case-sensitive is used. - config.mUpperOpcodes = false; - config.mUpperPseudoOpcodes = false; - config.mUpperOperandA = false; - config.mUpperOperandS = false; - config.mUpperOperandXY = false; - - config.mBankSelectBackQuote = true; - - config.mForceAbsOpcodeSuffix = string.Empty; - config.mForceLongOpcodeSuffix = string.Empty; - config.mForceDirectOperandPrefix = string.Empty; - config.mForceAbsOperandPrefix = "@w"; // word - config.mForceLongOperandPrefix = "@l"; // long - config.mEndOfLineCommentDelimiter = ";"; - config.mFullLineCommentDelimiterBase = ";"; - config.mBoxLineCommentDelimiter = ";"; - config.mAllowHighAsciiCharConst = false; - config.mExpressionMode = Formatter.FormatConfig.ExpressionMode.Common; - } - - // IGenerator - public List GenerateSource(BackgroundWorker worker) { - List pathNames = new List(1); - - string fileName = mFileNameBase + ASM_FILE_SUFFIX; - string pathName = Path.Combine(mWorkDirectory, fileName); - pathNames.Add(pathName); - - Formatter.FormatConfig config = new Formatter.FormatConfig(); - GenCommon.ConfigureFormatterFromSettings(Settings, ref config); - SetFormatConfigValues(ref config); - SourceFormatter = new Formatter(config); - - string msg = string.Format(Properties.Resources.PROGRESS_GENERATING_FMT, pathName); - worker.ReportProgress(0, msg); - - mLocalizer = new LabelLocalizer(Project); - if (!Settings.GetBool(AppSettings.SRCGEN_DISABLE_LABEL_LOCALIZATION, false)) { - mLocalizer.LocalPrefix = "_"; - mLocalizer.Analyze(); - } - mLocalizer.MaskLeadingUnderscores(); - - // Use UTF-8 encoding, without a byte-order mark. - using (StreamWriter sw = new StreamWriter(pathName, false, new UTF8Encoding(false))) { - mOutStream = sw; - - if (Settings.GetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false)) { - OutputLine(SourceFormatter.FullLineCommentDelimiter + - string.Format(Properties.Resources.GENERATED_FOR_VERSION, - "64tass", V1_53, AsmTass64.OPTIONS)); - } - - GenCommon.Generate(this, sw, worker); - - if (mNeedHereOp) { - OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(HERE_PSEUDO_OP), - string.Empty, string.Empty); - } - } - mOutStream = null; - - return pathNames; - } - - // IGenerator - public void OutputAsmConfig() { - CpuDef cpuDef = Project.CpuDef; - string cpuStr; - if (cpuDef.Type == CpuDef.CpuType.Cpu65816) { - cpuStr = "65816"; - } else if (cpuDef.Type == CpuDef.CpuType.Cpu65C02) { - cpuStr = "65c02"; - } else if (cpuDef.Type == CpuDef.CpuType.Cpu6502 && cpuDef.HasUndocumented) { - cpuStr = "6502i"; - } else { - cpuStr = "6502"; - } - - OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(".cpu"), - '\"' + cpuStr + '\"', string.Empty); - } - - // IGenerator - public string ModifyOpcode(int offset, OpDef op) { - if (op.IsUndocumented) { - if (Project.CpuDef.Type == CpuDef.CpuType.Cpu65C02) { - // none of the "LDD" stuff is handled - return null; - } - if ((op.Mnemonic == OpName.ANC && op.Opcode != 0x0b) || - (op.Mnemonic == OpName.JAM && op.Opcode != 0x02)) { - // There are multiple opcodes that match the mnemonic. Output the - // mnemonic for the first one and hex for the rest. - return null; - } else if (op.Mnemonic == OpName.NOP || op.Mnemonic == OpName.DOP || - op.Mnemonic == OpName.TOP) { - // the various undocumented no-ops aren't handled - return null; - } else if (op.Mnemonic == OpName.SBC) { - // this is the alternate reference to SBC - return null; - } else if (op == OpDef.OpSHA_DPIndIndexY) { - // not recognized ($93) - return null; - } - } - if (op == OpDef.OpBRK_StackInt || op == OpDef.OpCOP_StackInt || - op == OpDef.OpWDM_WDM) { - // 64tass doesn't like these to have an operand. Output as hex. - return null; - } - return string.Empty; // indicate original is fine - } - - // IGenerator - public void GenerateShortSequence(int offset, int length, out string opcode, - out string operand) { - Debug.Assert(length >= 1 && length <= 4); - - // Use a comma-separated list of individual hex bytes. - opcode = sDataOpNames.DefineData1; - - StringBuilder sb = new StringBuilder(length * 4); - for (int i = 0; i < length; i++) { - if (i != 0) { - sb.Append(','); - } - sb.Append(SourceFormatter.FormatHexValue(Project.FileData[offset + i], 2)); - } - operand = sb.ToString(); - } - - // IGenerator - public void OutputDataOp(int offset) { - Formatter formatter = SourceFormatter; - byte[] data = Project.FileData; - Anattrib attr = Project.GetAnattrib(offset); - - string labelStr = string.Empty; - if (attr.Symbol != null) { - labelStr = mLocalizer.ConvLabel(attr.Symbol.Label); - } - - string commentStr = SourceFormatter.FormatEolComment(Project.Comments[offset]); - string opcodeStr, operandStr; - - FormatDescriptor dfd = attr.DataDescriptor; - Debug.Assert(dfd != null); - int length = dfd.Length; - Debug.Assert(length > 0); - - bool multiLine = false; - switch (dfd.FormatType) { - case FormatDescriptor.Type.Default: - if (length != 1) { - Debug.Assert(false); - length = 1; - } - opcodeStr = sDataOpNames.DefineData1; - int operand = RawData.GetWord(data, offset, length, false); - operandStr = formatter.FormatHexValue(operand, length * 2); - break; - case FormatDescriptor.Type.NumericLE: - opcodeStr = sDataOpNames.GetDefineData(length); - operand = RawData.GetWord(data, offset, length, false); - operandStr = PseudoOp.FormatNumericOperand(formatter, Project.SymbolTable, - mLocalizer.LabelMap, dfd, operand, length, - PseudoOp.FormatNumericOpFlags.None); - break; - case FormatDescriptor.Type.NumericBE: - opcodeStr = sDataOpNames.GetDefineBigData(length); - if (opcodeStr == null) { - // Nothing defined, output as comma-separated single-byte values. - GenerateShortSequence(offset, length, out opcodeStr, out operandStr); - } else { - operand = RawData.GetWord(data, offset, length, true); - operandStr = PseudoOp.FormatNumericOperand(formatter, Project.SymbolTable, - mLocalizer.LabelMap, dfd, operand, length, - PseudoOp.FormatNumericOpFlags.None); - } - break; - case FormatDescriptor.Type.Fill: - opcodeStr = sDataOpNames.Fill; - operandStr = length + "," + formatter.FormatHexValue(data[offset], 2); - break; - case FormatDescriptor.Type.Dense: - multiLine = true; - opcodeStr = operandStr = null; - OutputDenseHex(offset, length, labelStr, commentStr); - break; - case FormatDescriptor.Type.String: - multiLine = true; - opcodeStr = operandStr = null; - OutputString(offset, labelStr, commentStr); - break; - default: - opcodeStr = "???"; - operandStr = "***"; - break; - } - - if (!multiLine) { - opcodeStr = formatter.FormatPseudoOp(opcodeStr); - OutputLine(labelStr, opcodeStr, operandStr, commentStr); - } - } - - private void OutputDenseHex(int offset, int length, string labelStr, string commentStr) { - Formatter formatter = SourceFormatter; - byte[] data = Project.FileData; - StringBuilder sb = new StringBuilder(MAX_OPERAND_LEN); - - string opcodeStr = formatter.FormatPseudoOp(sDataOpNames.DefineData1); - - int maxPerLine = MAX_OPERAND_LEN / 4; - int numChunks = (length + maxPerLine - 1) / maxPerLine; - for (int chunk = 0; chunk < numChunks; chunk++) { - int chunkStart = chunk * maxPerLine; - int chunkEnd = Math.Min((chunk + 1) * maxPerLine, length); - for (int i = chunkStart; i < chunkEnd; i++) { - if (i != chunkStart) { - sb.Append(','); - } - sb.Append(formatter.FormatHexValue(data[offset + i], 2)); - } - - OutputLine(labelStr, opcodeStr, sb.ToString(), commentStr); - labelStr = commentStr = string.Empty; - sb.Clear(); - } - } - - /// - /// Outputs formatted data in an unformatted way, because the code generator couldn't - /// figure out how to do something better. - /// - private void OutputNoJoy(int offset, int length, string labelStr, string commentStr) { - byte[] data = Project.FileData; - Debug.Assert(length > 0); - Debug.Assert(offset >= 0 && offset < data.Length); - - bool singleValue = true; - byte val = data[offset]; - for (int i = 1; i < length; i++) { - if (data[offset + i] != val) { - singleValue = false; - break; - } - } - - if (singleValue) { - string opcodeStr = SourceFormatter.FormatPseudoOp(sDataOpNames.Fill); - string operandStr = length + "," + SourceFormatter.FormatHexValue(val, 2); - OutputLine(labelStr, opcodeStr, operandStr, commentStr); - } else { - OutputDenseHex(offset, length, labelStr, commentStr); - } - } - - // IGenerator - public void OutputEquDirective(string name, string valueStr, string comment) { - OutputLine(name, SourceFormatter.FormatPseudoOp(sDataOpNames.EquDirective), - valueStr, SourceFormatter.FormatEolComment(comment)); - } - - // IGenerator - public void OutputOrgDirective(int offset, int address) { - // 64tass separates the "compile offset", which determines where the output fits - // into the generated binary, and "program counter", which determines the code - // the assembler generates. Since we need to explicitly specify every byte in - // the output file, the compile offset isn't very useful. We want to set it once - // before the first line of code, then leave it alone. - // - // Any subsequent ORG changes are made to the program counter, and take the form - // of a pair of ops (.logical to open, .here to end). Omitting the .here - // causes an error. - if (offset == 0) { - // Set the "compile offset" to the initial address. - OutputLine("*", "=", SourceFormatter.FormatHexValue(Project.AddrMap.Get(0), 4), - string.Empty); - } else { - if (mNeedHereOp) { - OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(HERE_PSEUDO_OP), - string.Empty, string.Empty); - } - OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(sDataOpNames.OrgDirective), - SourceFormatter.FormatHexValue(address, 4), string.Empty); - mNeedHereOp = true; - } - } - - // IGenerator - public void OutputRegWidthDirective(int offset, int prevM, int prevX, int newM, int newX) { - if (prevM != newM) { - string mop = (newM == 0) ? ".al" : ".as"; - OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(mop), - string.Empty, string.Empty); - } - if (prevX != newX) { - string xop = (newX == 0) ? ".xl" : ".xs"; - OutputLine(string.Empty, SourceFormatter.FormatPseudoOp(xop), - string.Empty, string.Empty); - } - } - - // IGenerator - public void OutputLine(string fullLine) { - mOutStream.WriteLine(fullLine); - } - - // IGenerator - public void OutputLine(string label, string opcode, string operand, string comment) { - // Break the line if the label is long and it's not a .EQ directive. - if (!string.IsNullOrEmpty(label) && - !string.Equals(opcode, sDataOpNames.EquDirective, - StringComparison.InvariantCultureIgnoreCase)) { - - if (mLongLabelNewLine && label.Length >= mColumnWidths[0]) { - mOutStream.WriteLine(label); - label = string.Empty; - } - } - - mLineBuilder.Clear(); - TextUtil.AppendPaddedString(mLineBuilder, label, mColumnWidths[0]); - TextUtil.AppendPaddedString(mLineBuilder, opcode, mColumnWidths[0] + mColumnWidths[1]); - TextUtil.AppendPaddedString(mLineBuilder, operand, - mColumnWidths[0] + mColumnWidths[1] + mColumnWidths[2]); - if (string.IsNullOrEmpty(comment)) { - // Trim trailing spaces off of opcode or operand. If they want trailing - // spaces at the end of a comment, that's fine. - CommonUtil.TextUtil.TrimEnd(mLineBuilder); - } else { - mLineBuilder.Append(comment); - } - - mOutStream.WriteLine(mLineBuilder.ToString()); - } - - private void OutputString(int offset, string labelStr, string commentStr) { - // Normal ASCII strings are handled with a simple .text directive. - // - // CString and L8String have directives (.null, .ptext), but we can only use - // them if the string fits on one line and doesn't include delimiters. - // - // We could probably do something fancy with the character encoding options to - // make high-ASCII work nicely. - // - // We might be able to define a macro for DCI and Reverse. - - Formatter formatter = SourceFormatter; - byte[] data = Project.FileData; - Anattrib attr = Project.GetAnattrib(offset); - FormatDescriptor dfd = attr.DataDescriptor; - Debug.Assert(dfd != null); - Debug.Assert(dfd.FormatType == FormatDescriptor.Type.String); - Debug.Assert(dfd.Length > 0); - - bool highAscii = false; - int leadingBytes = 0; - int trailingBytes = 0; - bool showLeading = false; - bool showTrailing = false; - - switch (dfd.FormatSubType) { - case FormatDescriptor.SubType.None: - highAscii = (data[offset] & 0x80) != 0; - break; - case FormatDescriptor.SubType.Dci: - highAscii = (data[offset] & 0x80) != 0; - trailingBytes = 1; - showTrailing = true; - break; - case FormatDescriptor.SubType.Reverse: - highAscii = (data[offset] & 0x80) != 0; - break; - case FormatDescriptor.SubType.DciReverse: - highAscii = (data[offset + dfd.Length - 1] & 0x80) != 0; - leadingBytes = 1; - showLeading = true; - break; - case FormatDescriptor.SubType.CString: - highAscii = (data[offset] & 0x80) != 0; - trailingBytes = 1; - showTrailing = true; - break; - case FormatDescriptor.SubType.L8String: - if (dfd.Length > 1) { - highAscii = (data[offset + 1] & 0x80) != 0; - } - leadingBytes = 1; - showLeading = true; - break; - case FormatDescriptor.SubType.L16String: - if (dfd.Length > 2) { - highAscii = (data[offset + 2] & 0x80) != 0; - } - leadingBytes = 2; - showLeading = true; - break; - default: - Debug.Assert(false); - return; - } - - char delim = '"'; - StringGather gath = null; - - // Run the string through so we can see if it'll fit on one line. As a minor - // optimization, we skip this step for "generic" strings, which are probably - // the most common thing. - if (dfd.FormatSubType != FormatDescriptor.SubType.None || highAscii) { - gath = new StringGather(this, labelStr, "???", commentStr, delim, - delim, StringGather.ByteStyle.CommaSep, MAX_OPERAND_LEN, true); - FeedGath(gath, data, offset, dfd.Length, leadingBytes, showLeading, - trailingBytes, showTrailing); - Debug.Assert(gath.NumLinesOutput > 0); - } - - string opcodeStr = formatter.FormatPseudoOp(sDataOpNames.StrGeneric); - - switch (dfd.FormatSubType) { - case FormatDescriptor.SubType.None: - // TODO(someday): something fancy with encodings to handle high-ASCII text? - break; - case FormatDescriptor.SubType.Dci: - case FormatDescriptor.SubType.Reverse: - case FormatDescriptor.SubType.DciReverse: - // Fully configured above. - break; - case FormatDescriptor.SubType.CString: - if (gath.NumLinesOutput == 1 && !gath.HasDelimiter) { - opcodeStr = sDataOpNames.StrNullTerm; - showTrailing = false; - } - break; - case FormatDescriptor.SubType.L8String: - if (gath.NumLinesOutput == 1 && !gath.HasDelimiter) { - opcodeStr = sDataOpNames.StrLen8; - showLeading = false; - } - break; - case FormatDescriptor.SubType.L16String: - // Implement as macro? - break; - default: - Debug.Assert(false); - return; - } - - if (highAscii) { - OutputNoJoy(offset, dfd.Length, labelStr, commentStr); - return; - } - - // Create a new StringGather, with the final opcode choice. - gath = new StringGather(this, labelStr, opcodeStr, commentStr, delim, - delim, StringGather.ByteStyle.CommaSep, MAX_OPERAND_LEN, false); - FeedGath(gath, data, offset, dfd.Length, leadingBytes, showLeading, - trailingBytes, showTrailing); - } - - /// - /// Feeds the bytes into the StringGather. - /// - private void FeedGath(StringGather gath, byte[] data, int offset, int length, - int leadingBytes, bool showLeading, int trailingBytes, bool showTrailing) { - int startOffset = offset; - int strEndOffset = offset + length - trailingBytes; - - if (showLeading) { - while (leadingBytes-- > 0) { - gath.WriteByte(data[offset++]); - } - } else { - offset += leadingBytes; - } - for (; offset < strEndOffset; offset++) { - gath.WriteChar((char)(data[offset] & 0x7f)); - } - while (showTrailing && trailingBytes-- > 0) { - gath.WriteByte(data[offset++]); - } - gath.Finish(); - } - } - - #endregion IGenerator - - - #region IAssembler - - /// - /// Cross-assembler execution interface. - /// - public class AsmTass64 : IAssembler { - public const string OPTIONS = "--case-sensitive --nostart --long-address -Wall"; - - // Paths from generator. - private List mPathNames; - - // Directory to make current before executing assembler. - private string mWorkDirectory; - - - // IAssembler - public void GetExeIdentifiers(out string humanName, out string exeName) { - humanName = "64tass Assembler"; - exeName = "64tass"; - } - - // IAssembler - public AssemblerConfig GetDefaultConfig() { - return new AssemblerConfig(string.Empty, new int[] { 8, 8, 11, 73 }); - } - - // IAssembler - public AssemblerVersion QueryVersion() { - AssemblerConfig config = - AssemblerConfig.GetConfig(AppSettings.Global, AssemblerInfo.Id.Tass64); - if (config == null || string.IsNullOrEmpty(config.ExecutablePath)) { - return null; - } - - ShellCommand cmd = new ShellCommand(config.ExecutablePath, "--version", - Directory.GetCurrentDirectory(), null); - cmd.Execute(); - if (string.IsNullOrEmpty(cmd.Stdout)) { - return null; - } - - // Windows - Stdout: "64tass Turbo Assembler Macro V1.53.1515\r\n" - // Linux - Stdout: "64tass Turbo Assembler Macro V1.53.1515?\n" - - const string PREFIX = "Macro V"; - string str = cmd.Stdout; - int start = str.IndexOf(PREFIX); - int end = (start < 0) ? -1 : str.IndexOfAny(new char[] { '?', '\r', '\n' }, start + 1); - - if (start < 0 || end < 0 || start + PREFIX.Length >= end) { - Debug.WriteLine("Couldn't find version in " + str); - return null; - } - start += PREFIX.Length; - string versionStr = str.Substring(start, end - start); - CommonUtil.Version version = CommonUtil.Version.Parse(versionStr); - if (!version.IsValid) { - return null; - } - return new AssemblerVersion(versionStr, version); - } - - // IAssembler - public void Configure(List pathNames, string workDirectory) { - // Clone pathNames, in case the caller decides to modify the original. - mPathNames = new List(pathNames.Count); - foreach (string str in pathNames) { - mPathNames.Add(str); - } - - mWorkDirectory = workDirectory; - } - - // IAssembler - public AssemblerResults RunAssembler(BackgroundWorker worker) { - // Reduce input file to a partial path if possible. This is really just to make - // what we display to the user a little easier to read. - string pathName = mPathNames[0]; - if (pathName.StartsWith(mWorkDirectory)) { - pathName = pathName.Remove(0, mWorkDirectory.Length + 1); - } else { - // Unexpected, but shouldn't be a problem. - Debug.WriteLine("NOTE: source file is not in work directory"); - } - - AssemblerConfig config = - AssemblerConfig.GetConfig(AppSettings.Global, AssemblerInfo.Id.Tass64); - if (string.IsNullOrEmpty(config.ExecutablePath)) { - Debug.WriteLine("Assembler not configured"); - return null; - } - - worker.ReportProgress(0, Properties.Resources.PROGRESS_ASSEMBLING); - - string outFileName = pathName.Substring(0, pathName.Length - 2); - - // Wrap pathname in quotes in case it has spaces. - // (Do we need to shell-escape quotes in the pathName?) - ShellCommand cmd = new ShellCommand(config.ExecutablePath, - OPTIONS + " \"" + pathName + "\"" + " -o \"" + outFileName + "\"", - mWorkDirectory, null); - cmd.Execute(); - - // Can't really do anything with a "cancel" request. - - // Output filename is the input filename without the ".S". Since the filename - // was generated by us we can be confident in the format. - string outputFile = mPathNames[0].Substring(0, mPathNames[0].Length - 2); - - return new AssemblerResults(cmd.FullCommandLine, cmd.ExitCode, cmd.Stdout, - cmd.Stderr, outputFile); - } - } - - #endregion IAssembler -} diff --git a/SourceGenWF/AsmGen/AssemblerConfig.cs b/SourceGenWF/AsmGen/AssemblerConfig.cs deleted file mode 100644 index d094fbe..0000000 --- a/SourceGenWF/AsmGen/AssemblerConfig.cs +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; -using System.Web.Script.Serialization; - -namespace SourceGenWF.AsmGen { - /// - /// Assembler configuration holder. Serializes and deserializes information held in - /// application settings. - /// - public class AssemblerConfig { - // Public fields are deserialized from JSON. Changing the names will break compatibility. - - /// - /// Path to cross-assembler executable. Will be null or empty if this assembler - /// is not configured. - /// - public string ExecutablePath { get; set; } - - /// - /// Column display widths. - /// - public int[] ColumnWidths { get; set; } - - public const int NUM_COLUMNS = 4; // label, opcode, operand, comment - - - /// - /// Nullary constructor, for serialization. - /// - public AssemblerConfig() { } - - /// - /// Constructor. - /// - /// Path to executable. May be empty. - /// Column widths. - public AssemblerConfig(string exePath, int[] widths) { - if (exePath == null) { - throw new Exception("Bad exe path"); - } - if (widths.Length != NUM_COLUMNS) { - throw new Exception("Bad widths.Length " + widths.Length); - } - ExecutablePath = exePath; - ColumnWidths = widths; - } - - private static string GetSettingName(AssemblerInfo.Id id) { - return AppSettings.ASM_CONFIG_PREFIX + id.ToString(); - } - - /// - /// Creates a populated AssemblerConfig from the app settings for the specified ID. - /// If the assembler hasn't been configured yet, the default configuration object - /// will be returned. - /// - /// Settings object to pull the values from. - /// Assembler ID. - /// The AssemblerConfig. - public static AssemblerConfig GetConfig(AppSettings settings, AssemblerInfo.Id id) { - string cereal = settings.GetString(GetSettingName(id), null); - if (string.IsNullOrEmpty(cereal)) { - IAssembler asm = AssemblerInfo.GetAssembler(id); - return asm.GetDefaultConfig(); - } - - JavaScriptSerializer ser = new JavaScriptSerializer(); - try { - AssemblerConfig config = ser.Deserialize(cereal); - if (config.ColumnWidths == null || config.ColumnWidths.Length != NUM_COLUMNS) { - throw new Exception("Bad column widths"); - } - if (config.ExecutablePath == null) { - throw new Exception("Missing exe path"); - } - return config; - } catch (Exception ex) { - Debug.WriteLine("AssemblerConfig deserialization failed: " + ex.Message); - return null; - } - } - - /// - /// Updates the assembler settings for the specified ID. - /// - /// Settings object to update. - /// Assembler ID. - /// Asm configuration. - public static void SetConfig(AppSettings settings, AssemblerInfo.Id id, - AssemblerConfig config) { - JavaScriptSerializer ser = new JavaScriptSerializer(); - string cereal = ser.Serialize(config); - - settings.SetString(GetSettingName(id), cereal); - } - } -} diff --git a/SourceGenWF/AsmGen/AssemblerInfo.cs b/SourceGenWF/AsmGen/AssemblerInfo.cs deleted file mode 100644 index 83dd561..0000000 --- a/SourceGenWF/AsmGen/AssemblerInfo.cs +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; - -namespace SourceGenWF.AsmGen { - /// - /// Static information on assemblers supported by SourceGen. This is relevant for both - /// assembly source generation and assembler execution. Nothing here is affected - /// by whether or not the assembler in question is actually installed. - /// - public class AssemblerInfo { - /// - /// Enumeration of supported assemblers. Alphabetical order looks nicest. - /// - public enum Id { - Unknown = 0, - Tass64, - Cc65, - Merlin32, - } - - /// - /// Static information for all known assemblers. - /// - /// The AsmType argument may be null. This is useful for non-cross assemblers. - /// - private static AssemblerInfo[] sInfo = new AssemblerInfo[] { - new AssemblerInfo(Id.Unknown, "???", null, null), - new AssemblerInfo(Id.Tass64, "64tass", typeof(GenTass64), typeof(AsmTass64)), - new AssemblerInfo(Id.Cc65, "cc65", typeof(GenCc65), typeof(AsmCc65)), - new AssemblerInfo(Id.Merlin32, "Merlin 32", typeof(GenMerlin32), typeof(AsmMerlin32)), - }; - - /// - /// Identifier. - /// - public Id AssemblerId { get; private set; } - - /// - /// Human-readable name. - /// - public string Name { get; private set; } - - /// - /// Type of generator class. - /// - public Type GenType { get; private set; } - - /// - /// Type of assembler class. - /// - public Type AsmType { get; private set; } - - - private AssemblerInfo(Id id, string name, Type genType, Type asmType) { - AssemblerId = id; - Name = name; - GenType = genType; - AsmType = asmType; - } - - /// - /// Returns an AssemblerInfo object for the specified id. - /// - /// Assembler identifier. - /// Reference to AssemblerInfo object. - public static AssemblerInfo GetAssemblerInfo(Id id) { - return sInfo[(int)id]; - } - - /// - /// Generator factory method. - /// - /// ID of assembler to return generator instance for. - /// New source generator object. - public static IGenerator GetGenerator(Id id) { - Type genType = sInfo[(int)id].GenType; - if (genType == null) { - Debug.Assert(false); // unexpected for generator - return null; - } else { - return (IGenerator)Activator.CreateInstance(genType); - } - } - - /// - /// Assembler factory method. - /// - /// ID of assembler to return assembler instance for. - /// New assembler interface object. - public static IAssembler GetAssembler(Id id) { - Type asmType = sInfo[(int)id].AsmType; - if (asmType == null) { - return null; - } else { - return (IAssembler)Activator.CreateInstance(asmType); - } - } - - /// - /// Provides a way to iterate through the set of known assemblers. This is probably - /// YAGNI -- we could just return the array -- but it would allow us to apply filters, - /// e.g. strip out assemblers that don't support 65816 code when that's the selected - /// CPU definition. - /// - private class AssemblerInfoIterator : IEnumerator { - private int mIndex = -1; - - public AssemblerInfo Current { - get { - if (mIndex < 0) { - // not started - return null; - } - return sInfo[mIndex]; - } - } - - object IEnumerator.Current { - get { - return Current; - } - } - - public void Dispose() { } - - public bool MoveNext() { - if (mIndex < 0) { - // skip element 0 (Unknown) - mIndex = 1; - } else { - mIndex++; - if (mIndex >= sInfo.Length) { - return false; - } - } - return true; - } - - public void Reset() { - mIndex = -1; - } - } - - public static IEnumerator GetInfoEnumerator() { - return new AssemblerInfoIterator(); - } - - - public override string ToString() { - return "Asm " + ((int)AssemblerId).ToString() + ": " + Name; - } - } -} diff --git a/SourceGenWF/AsmGen/AssemblerProgress.Designer.cs b/SourceGenWF/AsmGen/AssemblerProgress.Designer.cs deleted file mode 100644 index df112cc..0000000 --- a/SourceGenWF/AsmGen/AssemblerProgress.Designer.cs +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AsmGen { - partial class AssemblerProgress { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.progressLabel = new System.Windows.Forms.Label(); - this.progressBar1 = new System.Windows.Forms.ProgressBar(); - this.cancelButton = new System.Windows.Forms.Button(); - this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); - this.SuspendLayout(); - // - // progressLabel - // - this.progressLabel.AutoSize = true; - this.progressLabel.Location = new System.Drawing.Point(13, 13); - this.progressLabel.Name = "progressLabel"; - this.progressLabel.Size = new System.Drawing.Size(61, 13); - this.progressLabel.TabIndex = 1; - this.progressLabel.Text = "Preparing..."; - // - // progressBar1 - // - this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.progressBar1.Location = new System.Drawing.Point(12, 39); - this.progressBar1.Name = "progressBar1"; - this.progressBar1.Size = new System.Drawing.Size(600, 23); - this.progressBar1.Style = System.Windows.Forms.ProgressBarStyle.Marquee; - this.progressBar1.TabIndex = 2; - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.cancelButton.Location = new System.Drawing.Point(275, 79); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 23); - this.cancelButton.TabIndex = 0; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - // - // backgroundWorker1 - // - this.backgroundWorker1.WorkerReportsProgress = true; - this.backgroundWorker1.WorkerSupportsCancellation = true; - this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); - this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); - this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); - // - // AssemblerProgress - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(624, 114); - this.Controls.Add(this.cancelButton); - this.Controls.Add(this.progressBar1); - this.Controls.Add(this.progressLabel); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "AssemblerProgress"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Assembling Source..."; - this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.AssemblerProgress_FormClosing); - this.Load += new System.EventHandler(this.AssemblerProgress_Load); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label progressLabel; - private System.Windows.Forms.ProgressBar progressBar1; - private System.Windows.Forms.Button cancelButton; - private System.ComponentModel.BackgroundWorker backgroundWorker1; - } -} \ No newline at end of file diff --git a/SourceGenWF/AsmGen/AssemblerProgress.cs b/SourceGenWF/AsmGen/AssemblerProgress.cs deleted file mode 100644 index 213e3cd..0000000 --- a/SourceGenWF/AsmGen/AssemblerProgress.cs +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Windows.Forms; - -namespace SourceGenWF.AsmGen { - /// - /// Dialog that shows the progress of the assembler, and allows cancellation. - /// - public partial class AssemblerProgress : Form { - /// - /// On success, assembler results will be here. - /// - public AssemblerResults Results { get; private set; } - - /// - /// Assembler executor. - /// - private IAssembler mAssembler; - - - /// - /// Constructor. - /// - /// Fully-configured source generator. - public AssemblerProgress(IAssembler asm) { - InitializeComponent(); - - mAssembler = asm; - } - - private void AssemblerProgress_Load(object sender, EventArgs e) { - backgroundWorker1.RunWorkerAsync(); - } - - private void cancelButton_Click(object sender, EventArgs e) { - backgroundWorker1.CancelAsync(); - cancelButton.Enabled = false; - - // We don't have a polite way to ask a shell command to stop, so we should - // kill the process here. Need to figure out how to do that. We don't need - // to clean up partial output. - } - - private void AssemblerProgress_FormClosing(object sender, FormClosingEventArgs e) { - // Strictly speaking, we should treat this as a cancel request, and set - // e.Cancel = true to prevent the form from closing until the assembler stops. - // However, we don't currently kill runaway processes, which would leave the - // user with no way to close the dialog, potentially requiring them to kill the - // entire app with unsaved work. Better to abandon the runaway process. - // - // We call CancelAsync so that the results are discarded should the worker - // eventually finish. - if (backgroundWorker1.IsBusy) { - backgroundWorker1.CancelAsync(); - DialogResult = DialogResult.Cancel; - } - } - - // NOTE: executes on work thread. DO NOT do any UI work here. DO NOT access - // the Results property directly. - private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { - BackgroundWorker worker = sender as BackgroundWorker; - - AssemblerResults results = mAssembler.RunAssembler(worker); - if (worker.CancellationPending) { - e.Cancel = true; - } else { - e.Result = results; - } - } - - // Callback that fires when a progress update is made. - private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { - int percent = e.ProgressPercentage; - string msg = e.UserState as string; - - Debug.Assert(percent >= 0 && percent <= 100); - - if (!string.IsNullOrEmpty(msg)) { - progressLabel.Text = msg; - } - progressBar1.Value = percent; - } - - // Callback that fires when execution completes. - private void backgroundWorker1_RunWorkerCompleted(object sender, - RunWorkerCompletedEventArgs e) { - if (e.Cancelled) { - Debug.WriteLine("CANCELED"); - DialogResult = DialogResult.Cancel; - } else if (e.Error != null) { - // Unexpected -- shell command execution shouldn't throw exceptions. - MessageBox.Show(this, e.Error.ToString(), Properties.Resources.OPERATION_FAILED, - MessageBoxButtons.OK, MessageBoxIcon.Error); - DialogResult = DialogResult.Cancel; - } else { - // Make results available in properties. - Results = e.Result as AssemblerResults; - Debug.WriteLine("Asm complete, exit=" + Results.ExitCode); - DialogResult = DialogResult.OK; - } - - // Whatever the case, we're done. - this.Close(); - } - } -} diff --git a/SourceGenWF/AsmGen/AssemblerProgress.resx b/SourceGenWF/AsmGen/AssemblerProgress.resx deleted file mode 100644 index 59099f2..0000000 --- a/SourceGenWF/AsmGen/AssemblerProgress.resx +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - \ No newline at end of file diff --git a/SourceGenWF/AsmGen/AssemblerVersion.cs b/SourceGenWF/AsmGen/AssemblerVersion.cs deleted file mode 100644 index 1b4e0b8..0000000 --- a/SourceGenWF/AsmGen/AssemblerVersion.cs +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.Diagnostics; - -namespace SourceGenWF.AsmGen { - public class AssemblerVersion { - /// - /// Version string reported by the assembler. Retained mostly for debugging. - /// - public string VersionStr { get; private set; } - - /// - /// Version string converted to a Version object. For very complex version strings, - /// some information may be lost in the conversion. - /// - public CommonUtil.Version Version { get; private set; } - - //// Command pathname and modification date. Useful for caching values. - //private string ExeName { get; set; } - //private DateTime ExeModWhen { get; set; } - - public AssemblerVersion(string versionStr, CommonUtil.Version version) { - VersionStr = versionStr; - Version = version; - } - - public static AssemblerVersion GetVersion(AssemblerInfo.Id id) { - IAssembler asm = AssemblerInfo.GetAssembler(id); - if (asm == null) { - Debug.WriteLine("Assembler " + id + " not configured"); - return null; - } - return asm.QueryVersion(); - } - - public override string ToString() { - return "['" + VersionStr + "'/" + Version + "]"; - } - } - - /// - /// Maintains a cache of the versions of installed assemblers. - /// - public static class AssemblerVersionCache { - private static Dictionary sVersions = - new Dictionary(); - private static bool sQueried = false; - - /// - /// Queries the versions from all known assemblers, replacing any previously held data. - /// - public static void QueryVersions() { - IEnumerator iter = AssemblerInfo.GetInfoEnumerator(); - while (iter.MoveNext()) { - AssemblerInfo.Id id = iter.Current.AssemblerId; - if (id == AssemblerInfo.Id.Unknown) { - continue; - } - - AssemblerVersion vers = null; - IAssembler asm = AssemblerInfo.GetAssembler(id); - if (asm != null) { - vers = asm.QueryVersion(); - } - - Debug.WriteLine("Asm version query: " + id + "=" + vers); - sVersions[id] = vers; - } - - sQueried = true; - } - - /// - /// Returns the version information, or null if the query failed for this assembler. - /// - /// Assembler identifier. - /// Version info. - public static AssemblerVersion GetVersion(AssemblerInfo.Id id) { - if (!sQueried) { - QueryVersions(); - } - if (sVersions.TryGetValue(id, out AssemblerVersion vers)) { - return vers; - } else { - return null; - } - } - } -} diff --git a/SourceGenWF/AsmGen/GenAndAsm.Designer.cs b/SourceGenWF/AsmGen/GenAndAsm.Designer.cs deleted file mode 100644 index 88b11b0..0000000 --- a/SourceGenWF/AsmGen/GenAndAsm.Designer.cs +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AsmGen { - partial class GenAndAsm { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.splitContainer1 = new System.Windows.Forms.SplitContainer(); - this.assemblerSettingsButton = new System.Windows.Forms.Button(); - this.previewFileComboBox = new System.Windows.Forms.ComboBox(); - this.previewFileLabel = new System.Windows.Forms.Label(); - this.workDirectoryTextBox = new System.Windows.Forms.TextBox(); - this.outputFileLabel = new System.Windows.Forms.Label(); - this.generateButton = new System.Windows.Forms.Button(); - this.previewTextBox = new System.Windows.Forms.TextBox(); - this.assemblerComboBox = new System.Windows.Forms.ComboBox(); - this.assemblerLabel = new System.Windows.Forms.Label(); - this.configureAsmLinkLabel = new System.Windows.Forms.LinkLabel(); - this.cmdOutputTextBox = new System.Windows.Forms.TextBox(); - this.runAssemblerButton = new System.Windows.Forms.Button(); - this.basePanel = new System.Windows.Forms.Panel(); - this.closeButton = new System.Windows.Forms.Button(); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); - this.splitContainer1.Panel1.SuspendLayout(); - this.splitContainer1.Panel2.SuspendLayout(); - this.splitContainer1.SuspendLayout(); - this.basePanel.SuspendLayout(); - this.SuspendLayout(); - // - // splitContainer1 - // - this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; - this.splitContainer1.Location = new System.Drawing.Point(0, 0); - this.splitContainer1.Name = "splitContainer1"; - this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; - // - // splitContainer1.Panel1 - // - this.splitContainer1.Panel1.Controls.Add(this.assemblerSettingsButton); - this.splitContainer1.Panel1.Controls.Add(this.previewFileComboBox); - this.splitContainer1.Panel1.Controls.Add(this.previewFileLabel); - this.splitContainer1.Panel1.Controls.Add(this.workDirectoryTextBox); - this.splitContainer1.Panel1.Controls.Add(this.outputFileLabel); - this.splitContainer1.Panel1.Controls.Add(this.generateButton); - this.splitContainer1.Panel1.Controls.Add(this.previewTextBox); - this.splitContainer1.Panel1.Controls.Add(this.assemblerComboBox); - this.splitContainer1.Panel1.Controls.Add(this.assemblerLabel); - this.splitContainer1.Panel1MinSize = 150; - // - // splitContainer1.Panel2 - // - this.splitContainer1.Panel2.Controls.Add(this.configureAsmLinkLabel); - this.splitContainer1.Panel2.Controls.Add(this.cmdOutputTextBox); - this.splitContainer1.Panel2.Controls.Add(this.runAssemblerButton); - this.splitContainer1.Panel2MinSize = 100; - this.splitContainer1.Size = new System.Drawing.Size(784, 612); - this.splitContainer1.SplitterDistance = 400; - this.splitContainer1.TabIndex = 0; - // - // assemblerSettingsButton - // - this.assemblerSettingsButton.Location = new System.Drawing.Point(241, 10); - this.assemblerSettingsButton.Name = "assemblerSettingsButton"; - this.assemblerSettingsButton.Size = new System.Drawing.Size(75, 23); - this.assemblerSettingsButton.TabIndex = 3; - this.assemblerSettingsButton.Text = "Settings"; - this.assemblerSettingsButton.UseVisualStyleBackColor = true; - this.assemblerSettingsButton.Click += new System.EventHandler(this.assemblerSettingsButton_Click); - // - // previewFileComboBox - // - this.previewFileComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.previewFileComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.previewFileComboBox.FormattingEnabled = true; - this.previewFileComboBox.Items.AddRange(new object[] { - "SampleFile#031234_Merlin32.S"}); - this.previewFileComboBox.Location = new System.Drawing.Point(83, 58); - this.previewFileComboBox.Name = "previewFileComboBox"; - this.previewFileComboBox.Size = new System.Drawing.Size(262, 21); - this.previewFileComboBox.TabIndex = 5; - this.previewFileComboBox.SelectedIndexChanged += new System.EventHandler(this.previewFileComboBox_SelectedIndexChanged); - // - // previewFileLabel - // - this.previewFileLabel.AutoSize = true; - this.previewFileLabel.Location = new System.Drawing.Point(13, 61); - this.previewFileLabel.Name = "previewFileLabel"; - this.previewFileLabel.Size = new System.Drawing.Size(64, 13); - this.previewFileLabel.TabIndex = 4; - this.previewFileLabel.Text = "Preview file:"; - // - // workDirectoryTextBox - // - this.workDirectoryTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.workDirectoryTextBox.Location = new System.Drawing.Point(445, 59); - this.workDirectoryTextBox.Name = "workDirectoryTextBox"; - this.workDirectoryTextBox.ReadOnly = true; - this.workDirectoryTextBox.Size = new System.Drawing.Size(327, 20); - this.workDirectoryTextBox.TabIndex = 7; - this.workDirectoryTextBox.Text = "C:\\this\\that\\theother"; - // - // outputFileLabel - // - this.outputFileLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.outputFileLabel.AutoSize = true; - this.outputFileLabel.Location = new System.Drawing.Point(360, 62); - this.outputFileLabel.Name = "outputFileLabel"; - this.outputFileLabel.Size = new System.Drawing.Size(79, 13); - this.outputFileLabel.TabIndex = 6; - this.outputFileLabel.Text = "Work directory:"; - // - // generateButton - // - this.generateButton.Location = new System.Drawing.Point(363, 10); - this.generateButton.Name = "generateButton"; - this.generateButton.Size = new System.Drawing.Size(94, 23); - this.generateButton.TabIndex = 0; - this.generateButton.Text = "Generate"; - this.generateButton.UseVisualStyleBackColor = true; - this.generateButton.Click += new System.EventHandler(this.generateButton_Click); - // - // previewTextBox - // - this.previewTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.previewTextBox.BackColor = System.Drawing.SystemColors.Window; - this.previewTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.previewTextBox.Location = new System.Drawing.Point(13, 85); - this.previewTextBox.MaxLength = 0; - this.previewTextBox.Multiline = true; - this.previewTextBox.Name = "previewTextBox"; - this.previewTextBox.ReadOnly = true; - this.previewTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.previewTextBox.Size = new System.Drawing.Size(759, 303); - this.previewTextBox.TabIndex = 8; - // - // assemblerComboBox - // - this.assemblerComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.assemblerComboBox.FormattingEnabled = true; - this.assemblerComboBox.Items.AddRange(new object[] { - "Merlin32", - "CA65"}); - this.assemblerComboBox.Location = new System.Drawing.Point(83, 12); - this.assemblerComboBox.Name = "assemblerComboBox"; - this.assemblerComboBox.Size = new System.Drawing.Size(152, 21); - this.assemblerComboBox.TabIndex = 2; - this.assemblerComboBox.SelectedIndexChanged += new System.EventHandler(this.assemblerComboBox_SelectedIndexChanged); - // - // assemblerLabel - // - this.assemblerLabel.AutoSize = true; - this.assemblerLabel.Location = new System.Drawing.Point(13, 15); - this.assemblerLabel.Name = "assemblerLabel"; - this.assemblerLabel.Size = new System.Drawing.Size(58, 13); - this.assemblerLabel.TabIndex = 1; - this.assemblerLabel.Text = "Assembler:"; - // - // configureAsmLinkLabel - // - this.configureAsmLinkLabel.AutoSize = true; - this.configureAsmLinkLabel.Location = new System.Drawing.Point(124, 11); - this.configureAsmLinkLabel.Name = "configureAsmLinkLabel"; - this.configureAsmLinkLabel.Size = new System.Drawing.Size(126, 13); - this.configureAsmLinkLabel.TabIndex = 1; - this.configureAsmLinkLabel.TabStop = true; - this.configureAsmLinkLabel.Text = "Assembler not configured"; - this.configureAsmLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.configureAsmLinkLabel_LinkClicked); - // - // cmdOutputTextBox - // - this.cmdOutputTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.cmdOutputTextBox.BackColor = System.Drawing.SystemColors.Window; - this.cmdOutputTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.cmdOutputTextBox.Location = new System.Drawing.Point(10, 36); - this.cmdOutputTextBox.MaxLength = 0; - this.cmdOutputTextBox.Multiline = true; - this.cmdOutputTextBox.Name = "cmdOutputTextBox"; - this.cmdOutputTextBox.ReadOnly = true; - this.cmdOutputTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.cmdOutputTextBox.Size = new System.Drawing.Size(762, 169); - this.cmdOutputTextBox.TabIndex = 2; - // - // runAssemblerButton - // - this.runAssemblerButton.Location = new System.Drawing.Point(10, 6); - this.runAssemblerButton.Name = "runAssemblerButton"; - this.runAssemblerButton.Size = new System.Drawing.Size(97, 23); - this.runAssemblerButton.TabIndex = 0; - this.runAssemblerButton.Text = "Run Assembler"; - this.runAssemblerButton.UseVisualStyleBackColor = true; - this.runAssemblerButton.Click += new System.EventHandler(this.runAssemblerButton_Click); - // - // basePanel - // - this.basePanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.basePanel.Controls.Add(this.splitContainer1); - this.basePanel.Location = new System.Drawing.Point(0, 0); - this.basePanel.Name = "basePanel"; - this.basePanel.Size = new System.Drawing.Size(784, 612); - this.basePanel.TabIndex = 0; - // - // closeButton - // - this.closeButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.closeButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.closeButton.Location = new System.Drawing.Point(697, 626); - this.closeButton.Name = "closeButton"; - this.closeButton.Size = new System.Drawing.Size(75, 23); - this.closeButton.TabIndex = 0; - this.closeButton.Text = "Close"; - this.closeButton.UseVisualStyleBackColor = true; - // - // GenAndAsm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.closeButton; - this.ClientSize = new System.Drawing.Size(784, 661); - this.Controls.Add(this.closeButton); - this.Controls.Add(this.basePanel); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.MinimumSize = new System.Drawing.Size(800, 600); - this.Name = "GenAndAsm"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Generate and Assemble"; - this.Load += new System.EventHandler(this.GenAndAsm_Load); - this.splitContainer1.Panel1.ResumeLayout(false); - this.splitContainer1.Panel1.PerformLayout(); - this.splitContainer1.Panel2.ResumeLayout(false); - this.splitContainer1.Panel2.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); - this.splitContainer1.ResumeLayout(false); - this.basePanel.ResumeLayout(false); - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.SplitContainer splitContainer1; - private System.Windows.Forms.Panel basePanel; - private System.Windows.Forms.Button closeButton; - private System.Windows.Forms.Button generateButton; - private System.Windows.Forms.TextBox previewTextBox; - private System.Windows.Forms.ComboBox assemblerComboBox; - private System.Windows.Forms.Label assemblerLabel; - private System.Windows.Forms.TextBox cmdOutputTextBox; - private System.Windows.Forms.Button runAssemblerButton; - private System.Windows.Forms.TextBox workDirectoryTextBox; - private System.Windows.Forms.Label outputFileLabel; - private System.Windows.Forms.ComboBox previewFileComboBox; - private System.Windows.Forms.Label previewFileLabel; - private System.Windows.Forms.Button assemblerSettingsButton; - private System.Windows.Forms.LinkLabel configureAsmLinkLabel; - } -} \ No newline at end of file diff --git a/SourceGenWF/AsmGen/GenAndAsm.cs b/SourceGenWF/AsmGen/GenAndAsm.cs deleted file mode 100644 index 3a320d3..0000000 --- a/SourceGenWF/AsmGen/GenAndAsm.cs +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Drawing; -using System.IO; -using System.Text; -using System.Windows.Forms; - -namespace SourceGenWF.AsmGen { - public partial class GenAndAsm : Form { - private const int PREVIEW_BUF_SIZE = 64 * 1024; // 64KB should be enough for preview - private static string NO_PREVIEW_FILES = - "<" + Properties.Resources.NO_FILES_AVAILABLE + ">"; - - /// - /// Holds data for the preview combo box. - /// - private class ComboPath { - public string FileName { get; private set; } - public string PathName { get; private set; } - public ComboPath(string pathName) { - PathName = pathName; - if (string.IsNullOrEmpty(pathName)) { - FileName = NO_PREVIEW_FILES; - } else { - FileName = Path.GetFileName(pathName); - } - } - public override string ToString() { - return FileName; - } - } - - /// - /// Project view. Needed so we can pop open the assembler settings dialog. - /// - private AppForms.ProjectView mProjView; - - /// - /// Project with data. - /// - private DisasmProject mProject; - - /// - /// Directory where generated files and assembler output will go. - /// - private string mWorkDirectory; - - /// - /// Base file name. For example, if this is "GenFile", we might generate - /// "GenFile_Cc65.S". - /// - private string mBaseFileName; - - /// - /// Currently-selected assembler ID. - /// - private AssemblerInfo.Id mSelectedAssemblerId; - - /// - /// Results from last source generation. - /// - private List mGenerationResults; - - /// - /// Holds an item for the pick-your-assembler combox box. - /// - private class AsmComboItem { - public AssemblerInfo.Id AssemblerId { get; private set; } - public string Name { get; private set; } - public AssemblerVersion AsmVersion { get; private set; } - - public AsmComboItem(AssemblerInfo info, AssemblerVersion version) { - AssemblerId = info.AssemblerId; - Name = info.Name; - AsmVersion = version; - } - // This determines what the combo box shows. - public override string ToString() { - if (AsmVersion == null) { - return Name + " " + Properties.Resources.ASM_LATEST_VERSION; - } else { - return Name + " v" + AsmVersion.VersionStr; - } - } - } - - - /// - /// Constructor. - /// - /// Full path to the project file. - public GenAndAsm(AppForms.ProjectView projectView, DisasmProject project, - string projectPathName) { - InitializeComponent(); - - mProjView = projectView; - mProject = project; - mWorkDirectory = Path.GetDirectoryName(projectPathName); - mBaseFileName = Path.GetFileNameWithoutExtension(projectPathName); - - workDirectoryTextBox.Text = mWorkDirectory; - - // Make the splitter visible. This is a little tricky because the parent color - // affects the children as well. - // https://stackoverflow.com/a/22888877/294248 - this.splitContainer1.Panel1.BackColor = SystemColors.ControlDark; - this.splitContainer1.Panel2.BackColor = SystemColors.ControlDark; - this.splitContainer1.BackColor = SystemColors.ControlDark; - this.splitContainer1.Panel1.BackColor = SystemColors.Control; - this.splitContainer1.Panel2.BackColor = SystemColors.Control; - } - - private void GenAndAsm_Load(object sender, EventArgs e) { - // Try to select the previously-used asm format. - string defaultAsm = - AppSettings.Global.GetString(AppSettings.SRCGEN_DEFAULT_ASM, string.Empty); - PopulateAssemblerComboBox(defaultAsm); - - ResetElements(); - } - - /// - /// Populates the assembler combo box. Attempts to match the defaultAsm arg with - /// the entries to configure the initial value. - /// - private void PopulateAssemblerComboBox(string defaultAsm) { - //assemblerComboBox.DisplayMember = "Name"; // show this property - - assemblerComboBox.Items.Clear(); - IEnumerator iter = AssemblerInfo.GetInfoEnumerator(); - bool foundMatch = false; - while (iter.MoveNext()) { - AssemblerInfo info = iter.Current; - AssemblerVersion version = AssemblerVersionCache.GetVersion(info.AssemblerId); - AsmComboItem item = new AsmComboItem(info, version); - assemblerComboBox.Items.Add(item); - if (item.AssemblerId.ToString() == defaultAsm) { - Debug.WriteLine("matched current " + defaultAsm); - assemblerComboBox.SelectedItem = item; - foundMatch = true; - } - } - if (!foundMatch) { - // Need to do this or box will show empty. - assemblerComboBox.SelectedIndex = 0; - } - } - - private void assemblerComboBox_SelectedIndexChanged(object sender, EventArgs e) { - AsmComboItem sel = (AsmComboItem)assemblerComboBox.SelectedItem; - if (mSelectedAssemblerId != sel.AssemblerId) { - // Selection changed, discard window contents. - mSelectedAssemblerId = sel.AssemblerId; - AppSettings.Global.SetString(AppSettings.SRCGEN_DEFAULT_ASM, - mSelectedAssemblerId.ToString()); - ResetElements(); - } - } - - private void previewFileComboBox_SelectedIndexChanged(object sender, EventArgs e) { - ComboPath cpath = (ComboPath) previewFileComboBox.SelectedItem; - if (string.IsNullOrEmpty(cpath.PathName)) { - // nothing to do - return; - } - - previewTextBox.BackColor = SystemColors.Window; - previewTextBox.Enabled = true; - LoadPreviewFile(cpath.PathName); - } - - /// - /// Resets all of the active elements to the initial state, before any source code - /// was generated. - /// - private void ResetElements() { - mGenerationResults = null; - previewFileComboBox.Items.Clear(); - previewFileComboBox.Items.Add(new ComboPath(null)); - previewFileComboBox.SelectedIndex = 0; - - previewTextBox.Text = string.Empty; - previewTextBox.BackColor = SystemColors.Control; - previewTextBox.Enabled = false; - - cmdOutputTextBox.Text = string.Empty; - cmdOutputTextBox.BackColor = SystemColors.Control; - - UpdateAssemblerControls(); - } - - /// - /// Updates the controls in the lower (assembler) half of the dialog. - /// - private void UpdateAssemblerControls() { - bool asmConf = IsAssemblerConfigured(); - //Debug.WriteLine("ID=" + mSelectedAssemblerId + " asmConf=" + asmConf); - configureAsmLinkLabel.Visible = !asmConf; - if (mGenerationResults == null || !asmConf) { - runAssemblerButton.Enabled = false; - } else { - runAssemblerButton.Enabled = true; - } - } - - /// - /// Returns true if the selected cross-assembler executable has been configured. - /// - private bool IsAssemblerConfigured() { - AssemblerConfig config = - AssemblerConfig.GetConfig(AppSettings.Global, mSelectedAssemblerId); - return config != null && !string.IsNullOrEmpty(config.ExecutablePath); - } - - private void assemblerSettingsButton_Click(object sender, EventArgs e) { - DoSettings(); - } - - private void configureAsmLinkLabel_LinkClicked(object sender, - LinkLabelLinkClickedEventArgs e) { - DoSettings(); - } - - /// - /// Configures assembler-specific items, such as the installation directory of the - /// assembler binary. - /// - private void DoSettings() { - // Pop open the app settings dialog, with the appropriate tab selected. - mProjView.ShowAppSettings(AppForms.EditAppSettings.Tab.AsmConfig, - mSelectedAssemblerId); - - // Update the controls based on whether or not the assembler is now available. - UpdateAssemblerControls(); - AsmComboItem item = (AsmComboItem)assemblerComboBox.SelectedItem; - PopulateAssemblerComboBox(item.AssemblerId.ToString()); - } - - private void generateButton_Click(object sender, EventArgs e) { - IGenerator gen = AssemblerInfo.GetGenerator(mSelectedAssemblerId); - if (gen == null) { - Debug.WriteLine("Unable to get generator for " + mSelectedAssemblerId); - return; - } - gen.Configure(mProject, mWorkDirectory, mBaseFileName, - AssemblerVersionCache.GetVersion(mSelectedAssemblerId), AppSettings.Global); - - GeneratorProgress dlg = new GeneratorProgress(gen); - dlg.ShowDialog(); - Debug.WriteLine("Dialog returned: " + dlg.DialogResult); - - List pathNames = dlg.Results; - dlg.Dispose(); - - if (pathNames == null) { - // errors already reported - return; - } - - ResetElements(); - mGenerationResults = pathNames; - previewFileComboBox.Items.Clear(); - foreach (string str in pathNames) { - previewFileComboBox.Items.Add(new ComboPath(str)); - } - previewFileComboBox.SelectedIndex = 0; // should trigger update - - UpdateAssemblerControls(); - } - - private void LoadPreviewFile(string pathName) { - Debug.WriteLine("LOAD " + pathName); - - try { - using (StreamReader sr = new StreamReader(pathName, Encoding.UTF8)) { - char[] bigbuf = new char[PREVIEW_BUF_SIZE]; - int actual = sr.Read(bigbuf, 0, bigbuf.Length); - string str = CharArrayToLineNumberedString(bigbuf); - if (actual < PREVIEW_BUF_SIZE) { - previewTextBox.Text = str; - } else { - previewTextBox.Text = str + "\r\n" + - Properties.Resources.ERR_TOO_LARGE_FOR_PREVIEW; - } - } - } catch (Exception ex) { - previewTextBox.Text = ex.ToString(); - } - } - - /// - /// Converts a char[] to a string, inserting line numbers. - /// - /// - /// - private static string CharArrayToLineNumberedString(char[] data) { - StringBuilder sb = new StringBuilder(data.Length + data.Length / 40); - int lineStart = 0; - int lineNum = 0; - - for (int i = 0; i < data.Length; i++) { - if (data[i] == '\n') { - sb.AppendFormat("{0,4:D0} ", ++lineNum); - sb.Append(data, lineStart, i - lineStart + 1); - lineStart = i + 1; - } - } - - return sb.ToString(); - } - - private void runAssemblerButton_Click(object sender, EventArgs e) { - IAssembler asm = AssemblerInfo.GetAssembler(mSelectedAssemblerId); - if (asm == null) { - Debug.WriteLine("Unable to get assembler for " + mSelectedAssemblerId); - return; - } - - asm.Configure(mGenerationResults, mWorkDirectory); - AssemblerProgress dlg = new AssemblerProgress(asm); - dlg.ShowDialog(); - Debug.WriteLine("Dialog returned: " + dlg.DialogResult); - if (dlg.DialogResult != DialogResult.OK) { - // Cancelled, or failed to even run the assembler. - return; - } - - AssemblerResults results = dlg.Results; - if (results == null) { - Debug.WriteLine("Dialog returned OK, but no assembler results found"); - Debug.Assert(false); - return; - } - - StringBuilder sb = - new StringBuilder(results.Stdout.Length + results.Stderr.Length + 200); - sb.Append(results.CommandLine); - sb.Append("\r\n"); - sb.AppendFormat("ExitCode={0} - ", results.ExitCode); - if (results.ExitCode == 0) { - FileInfo fi = new FileInfo(results.OutputPathName); - if (!fi.Exists) { - MessageBox.Show(this, Properties.Resources.ASM_OUTPUT_NOT_FOUND, - Properties.Resources.ASM_MISMATCH_CAPTION, - MessageBoxButtons.OK, MessageBoxIcon.Error); - sb.Append(Properties.Resources.ASM_MATCH_FAILURE); - } else if (!CommonUtil.FileUtil.CompareBinaryFile(mProject.FileData, - results.OutputPathName, out int offset, out byte fileVal)) { - if (fi.Length != mProject.FileData.Length && - offset == fi.Length || offset == mProject.FileData.Length) { - // The files matched up to the point where one ended. - string msg = string.Format(Properties.Resources.ASM_MISMATCH_LENGTH_FMT, - fi.Length, mProject.FileData.Length); - MessageBox.Show(this, msg, Properties.Resources.ASM_MISMATCH_CAPTION, - MessageBoxButtons.OK, MessageBoxIcon.Error); - sb.Append(msg); - } else { - string msg = string.Format(Properties.Resources.ASM_MISMATCH_DATA_FMT, - offset, fileVal, mProject.FileData[offset]); - MessageBox.Show(this, msg, Properties.Resources.ASM_MISMATCH_CAPTION, - MessageBoxButtons.OK, MessageBoxIcon.Error); - sb.Append(msg); - } - } else { - sb.Append(Properties.Resources.ASM_MATCH_SUCCESS); - } - } - sb.Append("\r\n\r\n"); - - if (results.Stdout != null && results.Stdout.Length > 2) { - sb.Append("----- stdout -----\r\n"); - sb.Append(results.Stdout); - sb.Append("\r\n"); - } - if (results.Stderr != null && results.Stderr.Length > 2) { - sb.Append("----- stderr -----\r\n"); - sb.Append(results.Stderr); - sb.Append("\r\n"); - } - - cmdOutputTextBox.Text = sb.ToString(); - cmdOutputTextBox.BackColor = SystemColors.Window; - } - } -} diff --git a/SourceGenWF/AsmGen/GenAndAsm.resx b/SourceGenWF/AsmGen/GenAndAsm.resx deleted file mode 100644 index 1af7de1..0000000 --- a/SourceGenWF/AsmGen/GenAndAsm.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SourceGenWF/AsmGen/GenCommon.cs b/SourceGenWF/AsmGen/GenCommon.cs deleted file mode 100644 index 6bc8891..0000000 --- a/SourceGenWF/AsmGen/GenCommon.cs +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.IO; - -using Asm65; - -namespace SourceGenWF.AsmGen { - public class GenCommon { - /// - /// Generates assembly source. - /// - /// This code is common to all generators. - /// - /// Reference to generator object (presumably the caller). - /// Text output sink. - /// Background worker object, for progress updates and - /// cancelation requests. - public static void Generate(IGenerator gen, StreamWriter sw, BackgroundWorker worker) { - DisasmProject proj = gen.Project; - Formatter formatter = gen.SourceFormatter; - int offset = 0; - - bool doAddCycles = gen.Settings.GetBool(AppSettings.SRCGEN_SHOW_CYCLE_COUNTS, false); - - GenerateHeader(gen, sw); - - // Used for M/X flag tracking. - StatusFlags prevFlags = StatusFlags.AllIndeterminate; - - int lastProgress = 0; - - while (offset < proj.FileData.Length) { - Anattrib attr = proj.GetAnattrib(offset); - - if (attr.IsInstructionStart && offset > 0 && - proj.GetAnattrib(offset - 1).IsData) { - // Transition from data to code. (Don't add blank line for inline data.) - gen.OutputLine(string.Empty); - } - - // Long comments come first. - if (proj.LongComments.TryGetValue(offset, out MultiLineComment longComment)) { - List formatted = longComment.FormatText(formatter, string.Empty); - foreach (string str in formatted) { - gen.OutputLine(str); - } - } - - // Check for address change. - int orgAddr = proj.AddrMap.Get(offset); - if (orgAddr >= 0) { - gen.OutputOrgDirective(offset, orgAddr); - } - - if (attr.IsInstructionStart) { - // Generate M/X reg width directive, if necessary. - // NOTE: we can suppress the initial directive if we know what the - // target assembler's default assumption is. Probably want to handle - // that in the ORG output handler. - if (proj.CpuDef.HasEmuFlag) { - StatusFlags curFlags = attr.StatusFlags; - curFlags.M = attr.StatusFlags.ShortM ? 1 : 0; - curFlags.X = attr.StatusFlags.ShortX ? 1 : 0; - if (curFlags.M != prevFlags.M || curFlags.X != prevFlags.X) { - // changed, output directive - gen.OutputRegWidthDirective(offset, prevFlags.M, prevFlags.X, - curFlags.M, curFlags.X); - } - - prevFlags = curFlags; - } - - // Look for embedded instructions. - int len; - for (len = 1; len < attr.Length; len++) { - if (proj.GetAnattrib(offset + len).IsInstructionStart) { - break; - } - } - - // Output instruction. - GenerateInstruction(gen, sw, offset, len, doAddCycles); - - if (attr.DoesNotContinue) { - gen.OutputLine(string.Empty); - } - - offset += len; - } else { - gen.OutputDataOp(offset); - offset += attr.Length; - } - - // Update progress meter. We don't want to spam it, so just ping it 10x. - int curProgress = (offset * 10) / proj.FileData.Length; - if (lastProgress != curProgress) { - if (worker.CancellationPending) { - Debug.WriteLine("GenCommon got cancellation request"); - return; - } - lastProgress = curProgress; - worker.ReportProgress(curProgress * 10); - //System.Threading.Thread.Sleep(500); - } - } - } - - private static void GenerateHeader(IGenerator gen, StreamWriter sw) { - DisasmProject proj = gen.Project; - Formatter formatter = gen.SourceFormatter; - - // Check for header comment. - if (proj.LongComments.TryGetValue(DisplayList.Line.HEADER_COMMENT_OFFSET, - out MultiLineComment headerComment)) { - List formatted = headerComment.FormatText(formatter, string.Empty); - foreach (string str in formatted) { - gen.OutputLine(str); - } - } - - gen.OutputAsmConfig(); - - // Format symbols. - foreach (DefSymbol defSym in proj.ActiveDefSymbolList) { - // Use an operand length of 1 so things are shown as concisely as possible. - string valueStr = PseudoOp.FormatNumericOperand(formatter, proj.SymbolTable, - gen.Localizer.LabelMap, defSym.DataDescriptor, defSym.Value, 1, - PseudoOp.FormatNumericOpFlags.None); - gen.OutputEquDirective(defSym.Label, valueStr, defSym.Comment); - } - - // If there was at least one symbol, output a blank line. - if (proj.ActiveDefSymbolList.Count != 0) { - gen.OutputLine(string.Empty); - } - } - - private static void GenerateInstruction(IGenerator gen, StreamWriter sw, int offset, - int instrBytes, bool doAddCycles) { - DisasmProject proj = gen.Project; - Formatter formatter = gen.SourceFormatter; - byte[] data = proj.FileData; - Anattrib attr = proj.GetAnattrib(offset); - - string labelStr = string.Empty; - if (attr.Symbol != null) { - labelStr = gen.Localizer.ConvLabel(attr.Symbol.Label); - } - - OpDef op = proj.CpuDef.GetOpDef(data[offset]); - int operand = op.GetOperand(data, offset, attr.StatusFlags); - int instrLen = op.GetLength(attr.StatusFlags); - OpDef.WidthDisambiguation wdis = OpDef.WidthDisambiguation.None; - if (op.IsWidthPotentiallyAmbiguous) { - wdis = OpDef.GetWidthDisambiguation(instrLen, operand); - } - if (gen.Quirks.SinglePassAssembler && wdis == OpDef.WidthDisambiguation.None && - (op.AddrMode == OpDef.AddressMode.DP || - op.AddrMode == OpDef.AddressMode.DPIndexX) || - op.AddrMode == OpDef.AddressMode.DPIndexY) { - // Could be a forward reference to a direct-page label. - if (IsForwardLabelReference(gen, offset)) { - wdis = OpDef.WidthDisambiguation.ForceDirect; - } - } - - string opcodeStr = formatter.FormatOpcode(op, wdis); - - string formattedOperand = null; - int operandLen = instrLen - 1; - PseudoOp.FormatNumericOpFlags opFlags = PseudoOp.FormatNumericOpFlags.None; - bool isPcRelBankWrap = false; - - // Tweak branch instructions. We want to show the absolute address rather - // than the relative offset (which happens with the OperandAddress assignment - // below), and 1-byte branches should always appear as a 4-byte hex value. - if (op.AddrMode == OpDef.AddressMode.PCRel) { - Debug.Assert(attr.OperandAddress >= 0); - operandLen = 2; - opFlags = PseudoOp.FormatNumericOpFlags.IsPcRel; - } else if (op.AddrMode == OpDef.AddressMode.PCRelLong || - op.AddrMode == OpDef.AddressMode.StackPCRelLong) { - opFlags = PseudoOp.FormatNumericOpFlags.IsPcRel; - } else if (op.AddrMode == OpDef.AddressMode.Imm || - op.AddrMode == OpDef.AddressMode.ImmLongA || - op.AddrMode == OpDef.AddressMode.ImmLongXY) { - opFlags = PseudoOp.FormatNumericOpFlags.HasHashPrefix; - } - if (opFlags == PseudoOp.FormatNumericOpFlags.IsPcRel) { - int branchDist = attr.Address - attr.OperandAddress; - isPcRelBankWrap = branchDist > 32767 || branchDist < -32768; - } - - // 16-bit operands outside bank 0 need to include the bank when computing - // symbol adjustment. - int operandForSymbol = operand; - if (attr.OperandAddress >= 0) { - operandForSymbol = attr.OperandAddress; - } - - // Check Length to watch for bogus descriptors. (ApplyFormatDescriptors() should - // now be screening bad descriptors out, so we may not need the Length test.) - if (attr.DataDescriptor != null && attr.Length == attr.DataDescriptor.Length) { - // Format operand as directed. - if (op.AddrMode == OpDef.AddressMode.BlockMove) { - // Special handling for the double-operand block move. - string opstr1 = PseudoOp.FormatNumericOperand(formatter, proj.SymbolTable, - gen.Localizer.LabelMap, attr.DataDescriptor, operand >> 8, 1, - PseudoOp.FormatNumericOpFlags.None); - string opstr2 = PseudoOp.FormatNumericOperand(formatter, proj.SymbolTable, - gen.Localizer.LabelMap, attr.DataDescriptor, operand & 0xff, 1, - PseudoOp.FormatNumericOpFlags.None); - if (gen.Quirks.BlockMoveArgsReversed) { - string tmp = opstr1; - opstr1 = opstr2; - opstr2 = tmp; - } - formattedOperand = opstr1 + "," + opstr2; - } else { - formattedOperand = PseudoOp.FormatNumericOperand(formatter, proj.SymbolTable, - gen.Localizer.LabelMap, attr.DataDescriptor, - operandForSymbol, operandLen, opFlags); - } - } else { - // Show operand value in hex. - if (op.AddrMode == OpDef.AddressMode.BlockMove) { - int arg1, arg2; - if (gen.Quirks.BlockMoveArgsReversed) { - arg1 = operand & 0xff; - arg2 = operand >> 8; - } else { - arg1 = operand >> 8; - arg2 = operand & 0xff; - } - formattedOperand = formatter.FormatHexValue(arg1, 2) + "," + - formatter.FormatHexValue(arg2, 2); - } else { - if (operandLen == 2) { - // This is necessary for 16-bit operands, like "LDA abs" and "PEA val", - // when outside bank zero. The bank is included in the operand address, - // but we don't want to show it here. - operandForSymbol &= 0xffff; - } - formattedOperand = formatter.FormatHexValue(operandForSymbol, operandLen * 2); - } - } - string operandStr = formatter.FormatOperand(op, formattedOperand, wdis); - - string eolComment = proj.Comments[offset]; - if (doAddCycles) { - bool branchCross = (attr.Address & 0xff00) != (operandForSymbol & 0xff00); - int cycles = proj.CpuDef.GetCycles(op.Opcode, attr.StatusFlags, attr.BranchTaken, - branchCross); - if (cycles > 0) { - eolComment = cycles.ToString() + " " + eolComment; - } else { - eolComment = (-cycles).ToString() + "+ " + eolComment; - } - } - string commentStr = formatter.FormatEolComment(eolComment); - - string replMnemonic = gen.ModifyOpcode(offset, op); - if (attr.Length != instrBytes) { - // This instruction has another instruction inside it. Throw out what we - // computed and just output as bytes. - gen.GenerateShortSequence(offset, instrBytes, out opcodeStr, out operandStr); - } else if (isPcRelBankWrap && gen.Quirks.NoPcRelBankWrap) { - // Some assemblers have trouble generating PC-relative operands that wrap - // around the bank. Output as raw hex. - gen.GenerateShortSequence(offset, instrBytes, out opcodeStr, out operandStr); - } else if (op.AddrMode == OpDef.AddressMode.BlockMove && - gen.Quirks.BlockMoveArgsReversed) { - // On second thought, just don't even output the wrong thing. - gen.GenerateShortSequence(offset, instrBytes, out opcodeStr, out operandStr); - } else if (replMnemonic == null) { - // No mnemonic exists for this opcode. - gen.GenerateShortSequence(offset, instrBytes, out opcodeStr, out operandStr); - } else if (replMnemonic != string.Empty) { - // A replacement mnemonic has been provided. - opcodeStr = formatter.FormatMnemonic(replMnemonic, wdis); - } - gen.OutputLine(labelStr, opcodeStr, operandStr, commentStr); - - // Assemblers like Merlin32 try to be helpful and track SEP/REP, but they do the - // wrong thing if we're in emulation mode. Force flags back to short. - if (proj.CpuDef.HasEmuFlag && gen.Quirks.TracksSepRepNotEmu && op == OpDef.OpREP_Imm) { - if ((operand & 0x30) != 0 && attr.StatusFlags.E == 1) { - gen.OutputRegWidthDirective(offset, 0, 0, 1, 1); - } - } - } - - /// - /// Determines whether the instruction at the specified offset has an operand that is - /// a forward reference. This only matters for single-pass assemblers. - /// - /// Source generator reference. - /// Offset of instruction opcode. - /// True if the instruction's operand is a forward reference to a label. - private static bool IsForwardLabelReference(IGenerator gen, int offset) { - DisasmProject proj = gen.Project; - Debug.Assert(proj.GetAnattrib(offset).IsInstructionStart); - - FormatDescriptor dfd = proj.GetAnattrib(offset).DataDescriptor; - if (dfd == null || !dfd.HasSymbol) { - return false; - } - int labelOffset = proj.FindLabelOffsetByName(dfd.SymbolRef.Label); - if (labelOffset <= offset) { - // Doesn't exist, or is backward reference. - return false; - } - return true; - } - - /// - /// Configures some common format config items from the app settings. Uses a - /// passed-in settings object, rather than the global settings. - /// - /// Application settings. - /// Format config struct. - public static void ConfigureFormatterFromSettings(AppSettings settings, - ref Formatter.FormatConfig config) { - config.mUpperHexDigits = - settings.GetBool(AppSettings.FMT_UPPER_HEX_DIGITS, false); - config.mUpperOpcodes = - settings.GetBool(AppSettings.FMT_UPPER_OP_MNEMONIC, false); - config.mUpperPseudoOpcodes = - settings.GetBool(AppSettings.FMT_UPPER_PSEUDO_OP_MNEMONIC, false); - config.mUpperOperandA = - settings.GetBool(AppSettings.FMT_UPPER_OPERAND_A, false); - config.mUpperOperandS = - settings.GetBool(AppSettings.FMT_UPPER_OPERAND_S, false); - config.mUpperOperandXY = - settings.GetBool(AppSettings.FMT_UPPER_OPERAND_XY, false); - config.mSpacesBetweenBytes = - settings.GetBool(AppSettings.FMT_SPACES_BETWEEN_BYTES, false); - config.mAddSpaceLongComment = - settings.GetBool(AppSettings.FMT_ADD_SPACE_FULL_COMMENT, true); - - config.mForceAbsOpcodeSuffix = - settings.GetString(AppSettings.FMT_OPCODE_SUFFIX_ABS, string.Empty); - config.mForceLongOpcodeSuffix = - settings.GetString(AppSettings.FMT_OPCODE_SUFFIX_LONG, string.Empty); - config.mForceAbsOperandPrefix = - settings.GetString(AppSettings.FMT_OPERAND_PREFIX_ABS, string.Empty); - config.mForceLongOperandPrefix = - settings.GetString(AppSettings.FMT_OPERAND_PREFIX_LONG, string.Empty); - - string exprMode = settings.GetString(AppSettings.FMT_EXPRESSION_MODE, string.Empty); - config.mExpressionMode = Formatter.FormatConfig.ParseExpressionMode(exprMode); - } - } -} diff --git a/SourceGenWF/AsmGen/GeneratorProgress.Designer.cs b/SourceGenWF/AsmGen/GeneratorProgress.Designer.cs deleted file mode 100644 index 0ce4403..0000000 --- a/SourceGenWF/AsmGen/GeneratorProgress.Designer.cs +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.AsmGen { - partial class GeneratorProgress { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.progressLabel = new System.Windows.Forms.Label(); - this.cancelButton = new System.Windows.Forms.Button(); - this.progressBar1 = new System.Windows.Forms.ProgressBar(); - this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); - this.SuspendLayout(); - // - // progressLabel - // - this.progressLabel.AutoSize = true; - this.progressLabel.Location = new System.Drawing.Point(13, 13); - this.progressLabel.Name = "progressLabel"; - this.progressLabel.Size = new System.Drawing.Size(61, 13); - this.progressLabel.TabIndex = 1; - this.progressLabel.Text = "Preparing..."; - // - // cancelButton - // - this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.cancelButton.Location = new System.Drawing.Point(275, 79); - this.cancelButton.Name = "cancelButton"; - this.cancelButton.Size = new System.Drawing.Size(75, 23); - this.cancelButton.TabIndex = 0; - this.cancelButton.Text = "Cancel"; - this.cancelButton.UseVisualStyleBackColor = true; - this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click); - // - // progressBar1 - // - this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.progressBar1.Location = new System.Drawing.Point(12, 39); - this.progressBar1.Name = "progressBar1"; - this.progressBar1.Size = new System.Drawing.Size(600, 23); - this.progressBar1.Style = System.Windows.Forms.ProgressBarStyle.Continuous; - this.progressBar1.TabIndex = 2; - // - // backgroundWorker1 - // - this.backgroundWorker1.WorkerReportsProgress = true; - this.backgroundWorker1.WorkerSupportsCancellation = true; - this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); - this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); - this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); - // - // GeneratorProgress - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(624, 114); - this.Controls.Add(this.progressBar1); - this.Controls.Add(this.cancelButton); - this.Controls.Add(this.progressLabel); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "GeneratorProgress"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Generating Source..."; - this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.GeneratorProgress_FormClosing); - this.Load += new System.EventHandler(this.GeneratorProgress_Load); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label progressLabel; - private System.Windows.Forms.Button cancelButton; - private System.Windows.Forms.ProgressBar progressBar1; - private System.ComponentModel.BackgroundWorker backgroundWorker1; - } -} \ No newline at end of file diff --git a/SourceGenWF/AsmGen/GeneratorProgress.cs b/SourceGenWF/AsmGen/GeneratorProgress.cs deleted file mode 100644 index 8d18b69..0000000 --- a/SourceGenWF/AsmGen/GeneratorProgress.cs +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Windows.Forms; - -namespace SourceGenWF.AsmGen { - /// - /// Dialog that shows the progress of the assembler, and allows cancellation. - /// - public partial class GeneratorProgress : Form { - /// - /// Full pathnames of generated files. Will be null on error or user cancelation. - /// - public List Results { get; private set; } - - private IGenerator mGenerator; - - - /// - /// Constructor. - /// - /// Fully-configured source generator. - public GeneratorProgress(IGenerator gen) { - InitializeComponent(); - - mGenerator = gen; - } - - private void GeneratorProgress_Load(object sender, EventArgs e) { - backgroundWorker1.RunWorkerAsync(); - } - - private void cancelButton_Click(object sender, EventArgs e) { - backgroundWorker1.CancelAsync(); - cancelButton.Enabled = false; - } - - private void GeneratorProgress_FormClosing(object sender, FormClosingEventArgs e) { - // The close button will close the dialog without canceling the event. We - // cancel it here, which should cause it to stop relatively quickly, but we don't - // wait for it on the off chance that something weird is going on and it got - // stuck. If nothing else, this gives the user a chance to save their work. - if (backgroundWorker1.IsBusy) { - backgroundWorker1.CancelAsync(); - DialogResult = DialogResult.Cancel; - } - } - - // NOTE: executes on work thread. DO NOT do any UI work here. DO NOT access - // the Results property directly. - private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { - BackgroundWorker worker = sender as BackgroundWorker; - - // This will throw an I/O exception if there's a problem with the file. This - // will be caught and transferred to RunWorkerCompleted. - List fileNames = mGenerator.GenerateSource(worker); - if (worker.CancellationPending) { - e.Cancel = true; - } else { - e.Result = fileNames; - } - } - - // Callback that fires when a progress update is made. - private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { - int percent = e.ProgressPercentage; - string msg = e.UserState as string; - - Debug.Assert(percent >= 0 && percent <= 100); - - if (!string.IsNullOrEmpty(msg)) { - progressLabel.Text = msg; - } - progressBar1.Value = percent; - } - - // Callback that fires when execution completes. - private void backgroundWorker1_RunWorkerCompleted(object sender, - RunWorkerCompletedEventArgs e) { - if (e.Cancelled) { - Debug.WriteLine("CANCELED"); - DialogResult = DialogResult.Cancel; - } else if (e.Error != null) { - // This should only happen on a file I/O error, e.g. out of disk space or - // unable to overwrite an existing file. - MessageBox.Show(this, e.Error.ToString(), Properties.Resources.OPERATION_FAILED, - MessageBoxButtons.OK, MessageBoxIcon.Error); - DialogResult = DialogResult.Cancel; - } else { - // Make results available in property. - Results = e.Result as List; - - if (Results == null || Results.Count == 0) { - // Shouldn't happen -- generator should have reported error. - MessageBox.Show(this, "Internal error: no files generated", - Properties.Resources.OPERATION_FAILED, - MessageBoxButtons.OK, MessageBoxIcon.Error); - } else { - Debug.WriteLine("SUCCESS " + Results.Count); - } - DialogResult = DialogResult.OK; - } - - // Whatever the case, we're done. - this.Close(); - } - } -} diff --git a/SourceGenWF/AsmGen/GeneratorProgress.resx b/SourceGenWF/AsmGen/GeneratorProgress.resx deleted file mode 100644 index 59099f2..0000000 --- a/SourceGenWF/AsmGen/GeneratorProgress.resx +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - \ No newline at end of file diff --git a/SourceGenWF/AsmGen/IAssembler.cs b/SourceGenWF/AsmGen/IAssembler.cs deleted file mode 100644 index 2cf23ff..0000000 --- a/SourceGenWF/AsmGen/IAssembler.cs +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.ComponentModel; - -namespace SourceGenWF.AsmGen { - /// - /// Common interface for executing assemblers. - /// - public interface IAssembler { - /// - /// Gets identification strings for the executable. These are used when browsing for - /// the assembler binary. - /// - /// Human-readable name to show in the "open" dialog. - /// Name of executable to find, without ".exe". - void GetExeIdentifiers(out string humanName, out string exeName); - - /// - /// Queries the assembler for its default configuration. - /// - /// Config object with default values. - AssemblerConfig GetDefaultConfig(); - - /// - /// Queries the assembler for its version. Assembler executable paths are queried from - /// the global settings object. - /// - /// Assembler version info, or null if query failed. - AssemblerVersion QueryVersion(); - - /// - /// Configures the object. Pass in the list of pathnames returned by IGenerator.Run(), - /// and the working directory to use for the shell command. - /// - /// Assembler source pathnames. - /// Working directory for shell command. - void Configure(List pathNames, string workDirectory); - - /// - /// Executes the assembler. Must call Configure() first. Executed on background thread. - /// - /// Async work object, used to report progress updates and - /// check for cancellation. - /// Execution results, or null on internal failure. - AssemblerResults RunAssembler(BackgroundWorker worker); - } - - /// - /// Set of values returned by the assembler. - /// - public class AssemblerResults { - public string CommandLine { get; private set; } - public int ExitCode { get; private set; } - public string Stdout { get; private set; } - public string Stderr { get; private set; } - public string OutputPathName { get; private set; } - - public AssemblerResults(string commandLine, int exitCode, string stdout, string stderr, - string outputFile) { - CommandLine = commandLine; - ExitCode = exitCode; - Stdout = stdout; - Stderr = stderr; - OutputPathName = outputFile; - } - } -} diff --git a/SourceGenWF/AsmGen/IGenerator.cs b/SourceGenWF/AsmGen/IGenerator.cs deleted file mode 100644 index b3cc463..0000000 --- a/SourceGenWF/AsmGen/IGenerator.cs +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.ComponentModel; - -using Asm65; - -namespace SourceGenWF.AsmGen { - /// - /// Common interface for generating assembler-specific source code. - /// - public interface IGenerator { - /// - /// Returns some strings and format options for use in for the display list, configurable - /// through the app settings "quick set" feature. These are not used when generating - /// source code. - /// - /// This may be called on an unconfigured IGenerator. - /// - /// Table of pseudo-op names. - /// Format configuration. - void GetDefaultDisplayFormat(out PseudoOp.PseudoOpNames pseudoOps, - out Formatter.FormatConfig formatConfig); - - - /// - /// Configure generator. Must be called before calling any other method or using - /// properties, unless otherwise noted. - /// - /// Project to generate source for. - /// Directory in which to create output files. - /// Name to use as base for filenames. - /// Version of assembler to target. Pass in null - /// to target latest known version. - /// App settings object. - void Configure(DisasmProject project, string workDirectory, string fileNameBase, - AssemblerVersion asmVersion, AppSettings settings); - - /// - /// Project object with file data and Anattribs. - /// - DisasmProject Project { get; } - - /// - /// Source code formatter. - /// - Formatter SourceFormatter { get; } - - /// - /// Application settings. - /// - AppSettings Settings { get; } - - /// - /// Assembler-specific behavior. Used to handle quirky behavior for things that - /// are otherwise managed by common code. - /// - AssemblerQuirks Quirks { get; } - - /// - /// Label localization object. Behavior is assembler-specific. - /// - LabelLocalizer Localizer { get; } - - /// - /// Generates source files on a background thread. Method must not make any UI calls. - /// - /// Async work object, used to report progress updates and - /// check for cancellation. - /// List of pathnames of generated files. - List GenerateSource(BackgroundWorker worker); - - /// - /// Provides an opportunity for the assembler to replace a mnemonic with another, or - /// output an instruction as hex bytes. - /// - /// Opcode offset. - /// Opcode to replace. - /// Replacement mnemonic, an empty string if the original is fine, or - /// null if the op is unsupported or broken and should be emitted as hex. - string ModifyOpcode(int offset, OpDef op); - - /// - /// Generates an opcode/operand pair for a short sequence of bytes (1-4 bytes). - /// Does not produce any source output. - /// - /// Offset to data. - /// Number of bytes (1-4). - /// Opcode mnemonic. - /// Formatted operand. - void GenerateShortSequence(int offset, int length, out string opcode, out string operand); - - /// - /// Outputs zero or more lines of assembler configuration. This comes after the - /// header comment but before any directives. Useful for configuring the CPU type - /// and assembler options. - /// - void OutputAsmConfig(); - - /// - /// Outputs one or more lines of data for the specified offset. - /// - /// Offset to data. - void OutputDataOp(int offset); - - /// - /// Outputs an equate directive. The numeric value is already formatted. - /// - /// Symbol label. - /// Formatted value. - /// End-of-line comment. - void OutputEquDirective(string name, string valueStr, string comment); - - /// - /// Outputs a code origin directive. - /// - /// Offset of code targeted to new address. - /// 24-bit address. - void OutputOrgDirective(int offset, int address); - - /// - /// Notify the assembler of a change in register width. - /// - /// Merlin32 always sets both values (e.g. "MX %00"), cc65 sets each register - /// individually (".A16", ".I8"). We need to accommodate both styles. - /// - /// Offset of change. - /// Previous value for M flag. - /// Previous value for X flag. - /// New value for M flag. - /// New value for X flag. - void OutputRegWidthDirective(int offset, int prevM, int prevX, int newM, int newX); - - /// - /// Output a line of source code. All elements must be fully formatted, except for - /// certain assembler-specific things like ':' on labels. The items will be padded - /// with spaces to fit specific column widths. - /// - /// Optional label. - /// Opcode mnemonic. - /// Operand; may be empty. - /// Optional comment. - void OutputLine(string label, string opcode, string operand, string comment); - - /// - /// Output a line of source code. This will be output as-is. - /// - /// Full text of line to outut. - void OutputLine(string fullLine); - } - - /// - /// Enumeration of quirky or buggy behavior that GenCommon needs to handle. - /// - public class AssemblerQuirks { - /// - /// Are the arguments to MVN/MVP reversed? - /// - public bool BlockMoveArgsReversed { get; set; } - - /// - /// Does the assembler configure assembler widths based on SEP/REP, but doesn't - /// track the emulation bit? - /// - public bool TracksSepRepNotEmu { get; set; } - - /// - /// Is the assembler unable to generate relative branches that wrap around banks? - /// (Note this affects long-distance BRLs that don't appear to wrap.) - /// - public bool NoPcRelBankWrap { get; set; } - - /// - /// Is the assembler implemented as a single pass? - /// - public bool SinglePassAssembler { get; set; } - } -} \ No newline at end of file diff --git a/SourceGenWF/AsmGen/LabelLocalizer.cs b/SourceGenWF/AsmGen/LabelLocalizer.cs deleted file mode 100644 index e20e5c8..0000000 --- a/SourceGenWF/AsmGen/LabelLocalizer.cs +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; - -/* -Some assemblers support "local labels", with varying definitions of scope and features. -Generally speaking, local labels only need to be unique within a certain limited scope, and -they aren't included in end-of-assembly symbol lists. - -One popular form defines its scope as being between two global labels. So this is allowed: - - glob1 lda #$00 - :local sta $00 - glob2 lda #$01 - :local sta $01 - -but this would cause an error: - - glob1 lda #$00 - :local sta $00 - glob2 lda #$01 - bne :local - -because the local symbol table is cleared when a global symbol is encountered. - -Another common form allows backward references to labels that don't go out of scope until -they're re-used. This is useful for short loops. - -As a further limitation, assemblers seem to want the first label encountered in a program -to be global. - -The Symbol.SymbolType enum allows a label to be defined as "local or global". We can output -these with the local-symbol syntax, potentially rewriting them to have non-unique names like -"loop", but we can't promote (demote?) a label to local unless there are no references to it -that cross a global label. - -The cross-reference table we generate as part of the analysis process provides a full list of -label references, so we just need to iterate through the label list until we can't find -anything else that needs to be made global. - -Because the definition of "local label" is somewhat assembler-specific, it's best to defer -this analysis to code generation time, when the specific characteristics of the target -assembler can be taken into account. - -References to an offset can be numeric or symbolic. A purely numeric reference like "LDA $2000" -will always map to the offset associated with address $2000, but a symbolic reference might be -offset. For example, the LDA instruction could reference a label at $2008 as "LDA FOO-8". -The assembler cares about the symbolic references, not the actual offsets or addresses. For -this reason we can ignore references to an address with a label if those references don't -actually use the label. (One consequence of this is that formatting an operand as hex -eliminates it from the set of things for us to consider. Also, ORG directives have no effect -on the localizer.) - -Labels that are marked as global, but to which there are no references, could in theory be -elided. To do this we would have to omit them from the generated code, which would be -annoying and weird if (say) the user added them to label an external entry point. - - -The eventual output of our efforts is a map from the original symbol name to the local symbol -name. This must be applied to both labels and operands. -*/ - -namespace SourceGenWF.AsmGen { - public class LabelLocalizer { - /// - /// A pairing of an offset with a label string. (Essentially mAnattribs[n].Symbol - /// with all the fluff trimmed away.) - /// - /// The label string isn't actually all that useful, since we can pull it back out - /// of anattrib, but it makes life a little easier during debugging. These get - /// put into a List, so switching to a plain int offset doesn't necessarily help us - /// much because the ints get boxed. - /// - private class OffsetLabel { - public int Offset { get; private set; } - public string Label { get; private set; } - - public OffsetLabel(int offset, string label) { - Offset = offset; - Label = label; - } - - public override string ToString() { - return "+" + Offset.ToString("x6") + "(" + Label + ")"; - } - } - - /// - /// A pair of offsets. An operand (instruction or data) at the source offset - /// references a label at the destination offset. - /// - private class OffsetPair { - public int SrcOffset { get; private set; } // offset from which reference is made - public int DstOffset { get; private set; } // offset being referred to - - public OffsetPair(int src, int dst) { - SrcOffset = src; - DstOffset = dst; - } - - public override string ToString() { - return "src=+" + SrcOffset.ToString("x6") + " dst=+" + DstOffset.ToString("x6"); - } - } - - /// - /// Map from label string to local label string. This will be null until Analyze() - /// has executed. - /// - public Dictionary LabelMap { get; private set; } - - /// - /// String to prefix to local labels. Usually a single character, like ':' or '@'. - /// - public string LocalPrefix { get; set; } - - /// - /// Project reference. - /// - private DisasmProject mProject; - - // Work state. - private List mGlobalLabels = new List(); - private List mOffsetPairs = new List(); - private BitArray mGlobalFlags; - - - public LabelLocalizer(DisasmProject project) { - mProject = project; - mGlobalFlags = new BitArray(mProject.FileDataLength); - - LocalPrefix = "!?"; - } - - /// - /// Applies the LabelMap to the label. If the LabelMap is null, or does not have an - /// entry for the label, the original label is returned. - /// - /// Label to convert. - /// New label, or original label. - public string ConvLabel(string label) { - if (LabelMap != null) { - if (LabelMap.TryGetValue(label, out string newLabel)) { - label = newLabel; - } - } - return label; - } - - /// - /// Analyzes labels to identify which ones may be treated as non-global. - /// - public void Analyze() { - Debug.Assert(LocalPrefix.Length > 0); - - mGlobalFlags.SetAll(false); - - // Currently we only support the "local labels have scope that ends at a global - // label" variety. The basic idea is to start by assuming that everything not - // explicitly marked global is local, and then identify situations like this: - // - // lda :local - // global eor #$ff - // :local sta $00 - // - // The reference crosses a global label, so the "target" label must be made global. - // This can have ripple effects, so we have to iterate. Note it doesn't matter - // whether "global" is referenced anywhere. - // - // The current algorithm uses a straightforward O(n^2) approach. - - // Step 1: generate source/target pairs and global label list - GenerateLists(); - - // Step 2: walk through the list of global symbols, identifying source/target - // pairs that cross them. If a pair matches, the target label is added to the - // mGlobalLabels list, and removed from the pair list. - for (int index = 0; index < mGlobalLabels.Count; index++) { - FindIntersectingPairs(mGlobalLabels[index]); - } - - // Step 3: for each local label, add an entry to the map with the appropriate - // local-label syntax. - LabelMap = new Dictionary(); - for (int i = 0; i < mProject.FileDataLength; i++) { - if (mGlobalFlags[i]) { - continue; - } - Symbol sym = mProject.GetAnattrib(i).Symbol; - if (sym == null) { - continue; - } - - LabelMap[sym.Label] = LocalPrefix + sym.Label; - } - - // Take out the trash. - mGlobalLabels.Clear(); - mOffsetPairs.Clear(); - } - - /// - /// Generates the initial mGlobalFlags and mGlobalLabels lists, as well as the - /// full cross-reference pair list. - /// - private void GenerateLists() { - // For every offset that has a label, add an entry to the source/target pair list - // for every offset that references it. - // - // If the label isn't marked as "local or global", add it to the global-label list. - // - // The first label encountered is always treated as global. Note it may not appear - // at offset zero. - - bool first = true; - - for (int i = 0; i < mProject.FileDataLength; i++) { - Symbol sym = mProject.GetAnattrib(i).Symbol; - if (sym == null) { - // No label at this offset. - continue; - } - - if (first || sym.SymbolType != Symbol.Type.LocalOrGlobalAddr) { - first = false; - mGlobalFlags[i] = true; - mGlobalLabels.Add(new OffsetLabel(i, sym.Label)); - - // Don't add to pairs list. - continue; - } - - // If nothing actually references this label, the xref set will be empty. - XrefSet xrefs = mProject.GetXrefSet(i); - if (xrefs != null) { - foreach (XrefSet.Xref xref in xrefs) { - if (!xref.IsSymbolic) { - continue; - } - - mOffsetPairs.Add(new OffsetPair(xref.Offset, i)); - } - } - } - } - - /// - /// Identifies all label reference pairs that cross the specified global label. When - /// a matching pair is found, the pair's destination label is marked as global and - /// added to the global label list. - /// - /// Global label of interest. - private void FindIntersectingPairs(OffsetLabel glabel) { - Debug.Assert(mGlobalFlags[glabel.Offset]); - - int globOffset = glabel.Offset; - for (int i = 0; i < mOffsetPairs.Count; i++) { - OffsetPair pair = mOffsetPairs[i]; - - // If the destination was marked global earlier, remove and ignore this entry. - // Note this also means that pair.DstOffset != label.Offset. - if (mGlobalFlags[pair.DstOffset]) { - mOffsetPairs.RemoveAt(i); - i--; - continue; - } - - // Check to see if the global label falls between the source and destination - // offsets. - // - // If the reference source is itself a global label, it can reference local - // labels forward, but not backward. We need to take that into account for - // the case where label.Offset==pair.SrcOffset. - bool intersect; - if (pair.SrcOffset < pair.DstOffset) { - // Forward reference. src==glob is ok - intersect = pair.SrcOffset < globOffset && pair.DstOffset >= globOffset; - } else { - // Backward reference. src==glob is bad - intersect = pair.SrcOffset >= globOffset && pair.DstOffset <= globOffset; - } - - if (intersect) { - //Debug.WriteLine("Global " + glabel + " btwn " + pair + " (" + - // mProject.GetAnattrib(pair.DstOffset).Symbol.Label + ")"); - - // Change the destination label to global. - mGlobalFlags[pair.DstOffset] = true; - mGlobalLabels.Add(new OffsetLabel(pair.DstOffset, - mProject.GetAnattrib(pair.DstOffset).Symbol.Label)); - - // Carefully remove it from the list we're iterating through. - mOffsetPairs.RemoveAt(i); - i--; - } - } - } - - /// - /// Adjusts the label map so that only local variables start with an underscore ('_'). - /// This is necessary for assemblers like 64tass that use a leading underscore to - /// indicate that a label should be local. - /// - /// This may be called even if label localization is disabled. In that case we just - /// create an empty label map and populate as needed. - /// - /// Only call this if underscores are used to indicate local labels. - /// - public void MaskLeadingUnderscores() { - bool allGlobal = false; - if (LabelMap == null) { - allGlobal = true; - LabelMap = new Dictionary(); - } - - // Throw out the original local label generation. - LabelMap.Clear(); - - // Use this to test for uniqueness. We add all labels here as we go, not just the - // ones being remapped. For each label we either add the original or the localized - // form. - SortedList allLabels = new SortedList(); - - for (int i = 0; i < mProject.FileDataLength; i++) { - Symbol sym = mProject.GetAnattrib(i).Symbol; - if (sym == null) { - // No label at this offset. - continue; - } - - string newLabel; - if (allGlobal || mGlobalFlags[i]) { - // Global symbol. Don't let it start with '_'. - if (sym.Label.StartsWith("_")) { - // There's an underscore here that was added by the user. Stick some - // other character in front. - newLabel = "X" + sym.Label; - } else { - // No change needed. - newLabel = sym.Label; - } - } else { - // Local symbol. - if (sym.Label.StartsWith("_")) { - // The original starts with one or more underscores. Adding another - // will create a "__" label, which is reserved in 64tass. - newLabel = "_X" + sym.Label; - } else { - newLabel = "_" + sym.Label; - } - } - - // Make sure it's unique. - string uniqueLabel = newLabel; - int uval = 1; - while (allLabels.ContainsKey(uniqueLabel)) { - uniqueLabel = newLabel + uval.ToString(); - } - allLabels.Add(uniqueLabel, uniqueLabel); - - // If it's different, add it to the label map. - if (sym.Label != uniqueLabel) { - LabelMap.Add(sym.Label, uniqueLabel); - } - } - - Debug.WriteLine("UMAP: allcount=" + allLabels.Count + " mapcount=" + LabelMap.Count); - } - } -} diff --git a/SourceGenWF/AsmGen/StringGather.cs b/SourceGenWF/AsmGen/StringGather.cs deleted file mode 100644 index aa73e5b..0000000 --- a/SourceGenWF/AsmGen/StringGather.cs +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Diagnostics; - -namespace SourceGenWF.AsmGen { - /// - /// Multi-line string gatherer. Accumulates characters and raw bytes, emitting - /// them when we have a full operand's worth. - /// - /// If the delimiter character appears, it will be output inline as a raw byte. - /// The low-ASCII string ['hello'world'] will become [27,'hello',27,'world',27] - /// (or something similar). - /// - public class StringGather { - // Inputs. - public IGenerator Gen { get; private set; } - public string Label { get; private set; } - public string Opcode { get; private set; } - public string Comment { get; private set; } - public char Delimiter { get; private set; } - public char DelimiterReplacement { get; private set; } - public ByteStyle ByteStyleX { get; private set; } - public int MaxOperandLen { get; private set; } - public bool IsTestRun { get; private set; } - - public enum ByteStyle { DenseHex, CommaSep }; - - // Outputs. - public bool HasDelimiter { get; private set; } - public int NumLinesOutput { get; private set; } - - private char[] mHexChars; - - /// - public bool IsInternalLabel { - get { - // Could also check Type instead. Either works for now. - return SymbolSource == Source.User || SymbolSource == Source.Auto; - } - } - - - /// - /// Label sent to assembler. - /// - public string Label { get; private set; } - - /// - /// Symbol's numeric value. - /// - public int Value { get; private set; } - - /// - /// Symbol origin, e.g. auto-generated or entered by user. - /// - public Source SymbolSource { get; private set; } - - /// - /// Type of symbol, e.g. local or global. - /// - public Type SymbolType { get; private set; } - - /// - /// Two-character string representation of Source and Type, for display in the UI. - /// - public string SourceTypeString { get; private set; } - - - // No nullary constructor. - private Symbol() { } - - /// - /// Constructs immutable object. - /// - /// Label string. Syntax assumed valid. - /// User-defined or auto-generated? - /// Type of symbol this is. - /// user-defined. - public Symbol(string label, int value, Source source, Type type) { - Debug.Assert(!string.IsNullOrEmpty(label)); - Label = label; - Value = value; - SymbolType = type; - SymbolSource = source; - - // Generate SourceTypeString. - string sts; - switch (SymbolSource) { - case Source.Auto: sts = "A"; break; - case Source.User: sts = "U"; break; - case Source.Platform: sts = "P"; break; - case Source.Project: sts = "R"; break; - default: sts = "?"; break; - } - switch (SymbolType) { - case Type.LocalOrGlobalAddr: sts += "L"; break; - case Type.GlobalAddr: sts += "G"; break; - case Type.GlobalAddrExport: sts += "X"; break; - case Type.ExternalAddr: sts += "E"; break; - case Type.Constant: sts += "C"; break; - default: sts += "?"; break; - } - SourceTypeString = sts; - } - - public override string ToString() { - return Label + "{" + SymbolSource + "," + SymbolType + - ",val=$" + Value.ToString("x4") + "}"; - } - - public static bool operator ==(Symbol a, Symbol b) { - if (ReferenceEquals(a, b)) { - return true; // same object, or both null - } - if (ReferenceEquals(a, null) || ReferenceEquals(b, null)) { - return false; // one is null - } - // All fields must be equal. Ignore SourceTypeString, since it's generated - // from Source and Type. - return Asm65.Label.LABEL_COMPARER.Equals(a.Label, b.Label) && a.Value == b.Value && - a.SymbolSource == b.SymbolSource && a.SymbolType == b.SymbolType; - } - public static bool operator !=(Symbol a, Symbol b) { - return !(a == b); - } - public override bool Equals(object obj) { - return obj is Symbol && this == (Symbol)obj; - } - public override int GetHashCode() { - // Convert the label to upper case before computing the hash code, so that - // symbols with "foo" and "FOO" (which are equal) have the same hash code. - return Asm65.Label.ToNormal(Label).GetHashCode() ^ - Value ^ (int)SymbolType ^ (int)SymbolSource; - } - } -} diff --git a/SourceGenWF/SymbolTable.cs b/SourceGenWF/SymbolTable.cs deleted file mode 100644 index 5a271b2..0000000 --- a/SourceGenWF/SymbolTable.cs +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; - -namespace SourceGenWF { - /// - /// List of all symbols, arranged primarily by label, but also accessible by value. All - /// symbols have a unique label. - /// - public class SymbolTable : IEnumerable { - /// - /// Primary storage. Provides fast lookup by label. The StringComparer we choose - /// determines how case sensitivity and Culture is handled. - private SortedList mSymbols = - new SortedList(Asm65.Label.LABEL_COMPARER); - - /// - /// Same content, but ordered by value. Note the key and the value are the same object. - /// - private SortedList mSymbolsByValue = - new SortedList(new CompareByValue()); - - /// - /// Compare two symbols, primarily by value, secondarily by source, and tertiarily - /// by label. The primary SortedList guarantees that the label is unique, so we - /// should never have two equal Symbols in the list. - /// - /// The type comparison ensures that project symbols appear before platform symbols, - /// so that you can "overwrite" a platform symbol with the same value. - /// - private class CompareByValue : IComparer { - public int Compare(Symbol a, Symbol b) { - if (a.Value < b.Value) { - return -1; - } else if (a.Value > b.Value) { - return 1; - } - - if ((int)a.SymbolSource < (int)b.SymbolSource) { - return -1; - } else if ((int)a.SymbolSource > (int)b.SymbolSource) { - return 1; - } - - // Equal values, check string. We'll get a match on Remove or when - // replacing an entry with itself, but no two Symbols in the list - // should have the same label. - return Asm65.Label.LABEL_COMPARER.Compare(a.Label, b.Label); - } - } - - /// - /// This is incremented whenever the contents of the symbol table change. External - /// code can compare this against a previous value to see if anything has changed - /// since the last visit. - /// - /// We could theoretically miss something at the 2^32 rollover. Not worried. - /// - public int ChangeSerial { get; private set; } - - - public SymbolTable() { } - - // IEnumerable - public IEnumerator GetEnumerator() { - // .Values is documented as O(1) - return mSymbols.Values.GetEnumerator(); - } - - // IEnumerable - IEnumerator IEnumerable.GetEnumerator() { - return mSymbols.Values.GetEnumerator(); - } - - /// - /// Clears the symbol table. - /// - public void Clear() { - mSymbols.Clear(); - mSymbolsByValue.Clear(); - ChangeSerial++; - } - - /// - /// Returns the number of symbols in the table. - /// - public int Count() { - Debug.Assert(mSymbolsByValue.Count == mSymbols.Count); - return mSymbols.Count; - } - - /// - /// Adds the specified symbol to the list. Throws an exception if the symbol is - /// already present. - /// - public void Add(Symbol sym) { - // If Symbol with matching label is in list, this will throw an exception, - // and the by-value add won't happen. - mSymbols.Add(sym.Label, sym); - mSymbolsByValue.Add(sym, sym); - ChangeSerial++; - } - - /// - /// Finds the specified symbol by label. Throws an exception if it's not found. - /// - /// Adds the specified symbol to the list, or replaces it if it's already present. - /// - public Symbol this[string key] { - get { - Debug.Assert(mSymbolsByValue.Count == mSymbols.Count); - return mSymbols[key]; - } - set { - // Replacing {"foo", 1} with ("foo", 2} works correctly for mSymbols, because - // the label is the unique key. For mSymbolsByValue we have to explicitly - // remove it, because the entire Symbol is used as the key. - mSymbols.TryGetValue(key, out Symbol oldValue); - if (oldValue != null) { - mSymbolsByValue.Remove(oldValue); - } - mSymbols[key] = value; - mSymbolsByValue[value] = value; - ChangeSerial++; - } - } - - /// - /// Searches the table for symbols with matching address values. Ignores constants. - /// - /// Value to find. - /// First matching symbol found, or null if nothing matched. - public Symbol FindAddressByValue(int value) { - // Get sorted list of values. This is documented as efficient. - IList values = mSymbolsByValue.Values; - - //for (int i = 0; i < values.Count; i++) { - // if (values[i].Value == value && values[i].SymbolType != Symbol.Type.Constant) { - // return values[i]; - // } - //} - - int low = 0; - int high = values.Count - 1; - while (low <= high) { - int mid = (low + high) / 2; - Symbol midValue = values[mid]; - - if (midValue.Value == value) { - // found a match, walk back to find first match - while (mid > 0 && values[mid - 1].Value == value) { - mid--; - } - // now skip past constants - while (mid < values.Count && values[mid].SymbolType == Symbol.Type.Constant) { - //Debug.WriteLine("disregarding " + values[mid]); - mid++; - } - if (mid < values.Count && values[mid].Value == value) { - return values[mid]; - } - //Debug.WriteLine("Found value " + value + " but only constants"); - return null; - } else if (midValue.Value < value) { - // move the low end in - low = mid + 1; - } else { - // move the high end in - Debug.Assert(midValue.Value > value); - high = mid - 1; - } - } - - // not found - return null; - } - - /// - /// Gets the value associated with the key. - /// - /// Label to look up. - /// Symbol, or null if not found. - /// True if the key is present, false otherwise. - public bool TryGetValue(string key, out Symbol sym) { - return mSymbols.TryGetValue(key, out sym); - } - - /// - /// Removes the specified symbol. - /// - public void Remove(Symbol sym) { - mSymbols.Remove(sym.Label); - mSymbolsByValue.Remove(sym); - ChangeSerial++; - } - } -} diff --git a/SourceGenWF/SymbolTableSubset.cs b/SourceGenWF/SymbolTableSubset.cs deleted file mode 100644 index 4a60023..0000000 --- a/SourceGenWF/SymbolTableSubset.cs +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; - -namespace SourceGenWF { - public class SymbolTableSubset { - // Sort: which column? Note we store the int value in the app settings. - public enum SortCol { Type = 0, Value = 1, Name = 2 }; - - private SymbolTable mSymbolTable; - - // Internal dirty flag. - private bool mIsDirty = true; - - // Modification serial number, incremented on every change. - private int mLastTableSerial; - - /// - /// List of items, filtered and sorted according to user preference. This is the - /// backing store for the symbol ListView. - /// - private List mSortedSubset = new List(); - - - public SymbolTableSubset(SymbolTable table) { - mSymbolTable = table; - mLastTableSerial = mSymbolTable.ChangeSerial; - - // Configure from Settings object, which is kept up to date with the UI state. - AppSettings settings = AppSettings.Global; - IncludeUserLabels = settings.GetBool(AppSettings.SYMWIN_SHOW_USER, false); - IncludeAutoLabels = settings.GetBool(AppSettings.SYMWIN_SHOW_AUTO, false); - IncludeProjectSymbols = settings.GetBool(AppSettings.SYMWIN_SHOW_PROJECT, false); - IncludePlatformSymbols = settings.GetBool(AppSettings.SYMWIN_SHOW_PLATFORM, false); - IncludeConstants = settings.GetBool(AppSettings.SYMWIN_SHOW_CONST, false); - IncludeAddresses = settings.GetBool(AppSettings.SYMWIN_SHOW_ADDR, false); - - SortAscending = settings.GetBool(AppSettings.SYMWIN_SORT_ASCENDING, false); - int col = settings.GetInt(AppSettings.SYMWIN_SORT_COL, 0); - if (col < 0 || col > 2) { - col = 0; - } - SortColumn = (SortCol)col; - } - - // Filter: include user-generated labels? - private bool mIncludeUserLabels = true; - public bool IncludeUserLabels { - get { - return mIncludeUserLabels; - } - set { - if (mIncludeUserLabels != value) { - mIncludeUserLabels = value; - AppSettings.Global.SetBool(AppSettings.SYMWIN_SHOW_USER, value); - mIsDirty = true; - } - } - } - // Filter: include auto-generated labels? - private bool mIncludeAutoLabels = true; - public bool IncludeAutoLabels { - get { - return mIncludeAutoLabels; - } - set { - if (mIncludeAutoLabels != value) { - mIncludeAutoLabels = value; - AppSettings.Global.SetBool(AppSettings.SYMWIN_SHOW_AUTO, value); - mIsDirty = true; - } - } - } - // Filter: include symbols from project configuration file? - private bool mIncludeProjectSymbols = true; - public bool IncludeProjectSymbols { - get { - return mIncludeProjectSymbols; - } - set { - if (mIncludeProjectSymbols != value) { - mIncludeProjectSymbols = value; - AppSettings.Global.SetBool(AppSettings.SYMWIN_SHOW_PROJECT, value); - mIsDirty = true; - } - } - } - // Filter: include symbols from platform definition files? - private bool mIncludePlatformSymbols = true; - public bool IncludePlatformSymbols { - get { - return mIncludePlatformSymbols; - } - set { - if (mIncludePlatformSymbols != value) { - mIncludePlatformSymbols = value; - AppSettings.Global.SetBool(AppSettings.SYMWIN_SHOW_PLATFORM, value); - mIsDirty = true; - } - } - } - // Filter: include constants? - private bool mIncludeConstants = true; - public bool IncludeConstants { - get { - return mIncludeConstants; - } - set { - if (mIncludeConstants != value) { - mIncludeConstants = value; - AppSettings.Global.SetBool(AppSettings.SYMWIN_SHOW_CONST, value); - mIsDirty = true; - } - } - } - // Filter: include addresses? - private bool mIncludeAddresses = true; - public bool IncludeAddresses { - get { - return mIncludeAddresses; - } - set { - if (mIncludeAddresses != value) { - mIncludeAddresses = value; - AppSettings.Global.SetBool(AppSettings.SYMWIN_SHOW_ADDR, value); - mIsDirty = true; - } - } - } - // Sort: ascending? - private bool mSortAscending = true; - public bool SortAscending { - get { - return mSortAscending; - } - set { - if (mSortAscending != value) { - mSortAscending = value; - AppSettings.Global.SetBool(AppSettings.SYMWIN_SORT_ASCENDING, value); - mIsDirty = true; - } - } - } - private SortCol mSortColumn = SortCol.Name; - public SortCol SortColumn { - get { - return mSortColumn; - } - set { - if (mSortColumn != value) { - mSortColumn = value; - AppSettings.Global.SetInt(AppSettings.SYMWIN_SORT_COL, (int)value); - mIsDirty = true; - } - } - } - - - /// - /// Returns the length of the symbol subset list. As a side-effect this may - /// re-sort the list. - /// - public int GetSubsetCount() { - if (mIsDirty || mLastTableSerial != mSymbolTable.ChangeSerial) { - mLastTableSerial = mSymbolTable.ChangeSerial; - mSortedSubset.Clear(); - foreach (Symbol sym in mSymbolTable) { - if (!IncludeUserLabels && sym.SymbolSource == Symbol.Source.User) { - continue; - } - if (!IncludeProjectSymbols && sym.SymbolSource == Symbol.Source.Project) { - continue; - } - if (!IncludePlatformSymbols && sym.SymbolSource == Symbol.Source.Platform) { - continue; - } - if (!IncludeAutoLabels && sym.SymbolSource == Symbol.Source.Auto) { - continue; - } - if (!IncludeConstants && sym.SymbolType == Symbol.Type.Constant) { - continue; - } - if (!IncludeAddresses && sym.SymbolType != Symbol.Type.Constant) { - continue; - } - mSortedSubset.Add(sym); - } - - // Sort. Label is always unique, so we use it as a secondary sort. - if (SortColumn == SortCol.Type) { - if (mSortAscending) { - mSortedSubset.Sort(delegate (Symbol a, Symbol b) { - int cmp = string.Compare(a.SourceTypeString, b.SourceTypeString); - if (cmp == 0) { - cmp = string.Compare(a.Label, b.Label); - } - return cmp; - }); - } else { - mSortedSubset.Sort(delegate (Symbol a, Symbol b) { - int cmp = string.Compare(a.SourceTypeString, b.SourceTypeString); - if (cmp == 0) { - // secondary sort is always ascending, so negate - cmp = -string.Compare(a.Label, b.Label); - } - return -cmp; - }); - } - } else if (SortColumn == SortCol.Name) { - if (mSortAscending) { - mSortedSubset.Sort(delegate (Symbol a, Symbol b) { - return string.Compare(a.Label, b.Label); - }); - } else { - mSortedSubset.Sort(delegate (Symbol a, Symbol b) { - return -string.Compare(a.Label, b.Label); - }); - } - } else if (SortColumn == SortCol.Value) { - if (mSortAscending) { - mSortedSubset.Sort(delegate (Symbol a, Symbol b) { - int cmp; - if (a.Value < b.Value) { - cmp = -1; - } else if (a.Value > b.Value) { - cmp = 1; - } else { - cmp = string.Compare(a.Label, b.Label); - } - return cmp; - }); - } else { - mSortedSubset.Sort(delegate (Symbol a, Symbol b) { - int cmp; - if (a.Value < b.Value) { - cmp = -1; - } else if (a.Value > b.Value) { - cmp = 1; - } else { - cmp = -string.Compare(a.Label, b.Label); - } - return -cmp; - }); - } - } - - mIsDirty = false; - } - return mSortedSubset.Count; - } - - /// - /// Returns an item from the subset list. - /// - public Symbol GetSubsetItem(int index) { - Debug.Assert(!mIsDirty); - return mSortedSubset[index]; - } - } -} diff --git a/SourceGenWF/Tests/GenTest.cs b/SourceGenWF/Tests/GenTest.cs deleted file mode 100644 index 1ba067b..0000000 --- a/SourceGenWF/Tests/GenTest.cs +++ /dev/null @@ -1,620 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Drawing; -using System.IO; -using System.Text.RegularExpressions; - -using CommonUtil; -using SourceGenWF.AsmGen; - -namespace SourceGenWF.Tests { - /// - /// Source code generation regression test. - /// - /// The generator is tested in two ways: (1) by comparing the output to known-good - /// sources, and (2) by running it through the assembler. Assembling the sources is - /// important to ensure that we don't get bad sources in the "known-good" set. - /// - /// This does not take assembler version into account, so it will not be helpful for - /// monitoring compatibility with old versions of assemblers. - /// - public class GenTest { - private const string TEST_DIR_NAME = "SGTestData"; - private const string EXPECTED_DIR_NAME = "Expected"; - - //private static char[] sInvalidChars = new char[] { '.', '_' }; - private const string TestCasePattern = @"^\d\d\d\d-[A-Za-z0-9-]+$"; - private static Regex sTestCaseRegex = new Regex(TestCasePattern); - - /// - /// Whitelist of removable names for ScrubWorkDirectory(). - /// - private static string[] sScrubList = new string[] { - "_FileInformation.txt", // created by Merlin 32 - "error_output.txt", // created by Merlin 32 (only when errors found) - }; - - /// - /// Test result. One of these will be created for every {test-case, assembler} pair. - /// - public class GenTestResults { - public string PathName { get; private set; } - public string FileName { get; private set; } - public AssemblerInfo.Id AsmId { get; private set; } - - public FileLoadReport ProjectLoadReport { get; set; } - - public bool GenerateOkay { get; set; } - public bool AssembleOkay { get; set; } - public AssemblerResults AsmResults { get; set; } // may be null - - public TaskTimer Timer { get; set; } // may be null - - public GenTestResults(string pathName, AssemblerInfo.Id asmId) { - PathName = pathName; - AsmId = asmId; - - FileName = Path.GetFileName(pathName); - } - - // Return a string for use in the UI combo box. - public override string ToString() { - return (GenerateOkay && AssembleOkay ? "OK" : "FAIL") + " - " + - FileName + " - " + AsmId.ToString(); - } - } - - /// - /// If true, don't scrub directories. - /// - public bool RetainOutput { get; set; } - - /// - /// Directory with test cases. - /// - private string mTestDir; - - private BackgroundWorker mWorker; - - private List mResults = new List(); - - - /// - /// Runs generate/assemble test cases. Main entry point. - /// - /// Background worker object from dialog box. - public List Run(BackgroundWorker worker) { - Debug.Assert(mWorker == null); // don't re-use object - - mWorker = worker; - string runtimeDir = RuntimeDataAccess.GetDirectory(); - mTestDir = Path.Combine(Path.GetDirectoryName(runtimeDir), TEST_DIR_NAME); - - if (!Directory.Exists(mTestDir)) { - ReportErrMsg("Regression test directory not found: " + mTestDir); - ReportFailure(); - return null; - } - - List testCases = new List(); - foreach (string pathName in Directory.EnumerateFiles(mTestDir)) { - // Filter out everything that doesn't look like "1000-nifty-test". We - // want to ignore .dis65 files and assembler output (which has the name - // of the assembler following an underscore). - string fileName = Path.GetFileName(pathName); - MatchCollection matches = sTestCaseRegex.Matches(fileName); - if (matches.Count == 0) { - //ReportProgress("Ignoring " + fileName + "\r\n", Color.Gray); - continue; - } - - ReportProgress("Found " + fileName + "\r\n"); - testCases.Add(pathName); - } - - ReportProgress("Processing " + testCases.Count + " test cases...\r\n"); - DateTime startWhen = DateTime.Now; - - int successCount = 0; - foreach (string pathName in testCases) { - if (GenerateAndAssemble(pathName)) { - successCount++; - } - - if (worker.CancellationPending) { - ReportProgress("\r\nCancelled.\r\n", Color.Red); - return mResults; - } - } - - DateTime endWhen = DateTime.Now; - - if (successCount == testCases.Count) { - ReportProgress(string.Format("All " + testCases.Count + - " tests passed in {0:N3} sec\r\n", - (endWhen - startWhen).TotalSeconds), Color.Green); - } else { - ReportProgress(successCount + " of " + testCases.Count + " tests passed\r\n"); - } - - return mResults; - } - - private void ReportProgress(string msg) { - mWorker.ReportProgress(0, new ProgressMessage(msg)); - } - - private void ReportProgress(string msg, Color color) { - mWorker.ReportProgress(0, new ProgressMessage(msg, color)); - } - - private void ReportErrMsg(string msg) { - ReportProgress(" [" + msg + "] ", Color.Blue); - } - - private void ReportSuccess() { - ReportProgress(" success\r\n", Color.Green); - } - - private void ReportFailure() { - ReportProgress(" failed\r\n", Color.Red); - } - - /// - /// Extracts the test's number from the pathname. - /// - /// Full or partial path to test file. - /// Test number. - private int GetTestNum(string pathName) { - // Should always succeed if pathName matched on our regex. - string fileName = Path.GetFileName(pathName); - return int.Parse(fileName.Substring(0, 4)); - } - - /// - /// Generates source code for the specified test case, assembles it, and compares - /// the output of both steps to expected values. The process is repeated for every - /// known assembler. - /// - /// If an assembler is known but not configured, the assembly step is skipped, and - /// does not count as a failure. - /// - /// Full path to test case. - /// True if all assemblers worked as expected. - private bool GenerateAndAssemble(string pathName) { - ReportProgress(Path.GetFileName(pathName) + "...\r\n"); - - // Create DisasmProject object, either as a new project for a plain data file, - // or from a project file. - DisasmProject project = InstantiateProject(pathName, - out FileLoadReport projectLoadReport); - if (project == null) { - ReportFailure(); - return false; - } - - int testNum = GetTestNum(pathName); - - // Create a temporary directory to work in. - string workDir = CreateWorkDirectory(pathName); - if (string.IsNullOrEmpty(workDir)) { - ReportFailure(); - project.Cleanup(); - return false; - } - - AppSettings settings = CreateNormalizedSettings(); - ApplyProjectSettings(settings, project); - - // Iterate through all known assemblers. - bool didFail = false; - foreach (AssemblerInfo.Id asmId in - (AssemblerInfo.Id[])Enum.GetValues(typeof(AssemblerInfo.Id))) { - if (asmId == AssemblerInfo.Id.Unknown) { - continue; - } - - string fileName = Path.GetFileName(pathName); - TaskTimer timer = new TaskTimer(); - timer.StartTask("Full Test Duration"); - - // Create results object and add it to the list. We'll add stuff to it for - // as far as we get. - GenTestResults results = new GenTestResults(pathName, asmId); - mResults.Add(results); - results.ProjectLoadReport = projectLoadReport; - - // Generate source code. - ReportProgress(" " + asmId.ToString() + " generate..."); - IGenerator gen = AssemblerInfo.GetGenerator(asmId); - if (gen == null) { - ReportErrMsg("generator unavailable"); - ReportProgress("\r\n"); - //didFail = true; - continue; - } - timer.StartTask("Generate Source"); - gen.Configure(project, workDir, fileName, - AssemblerVersionCache.GetVersion(asmId), settings); - List genPathNames = gen.GenerateSource(mWorker); - timer.EndTask("Generate Source"); - if (mWorker.CancellationPending) { - // The generator will stop early if a cancellation is requested. If we - // don't break here, the compare function will report a failure, which - // isn't too problematic but looks funny. - break; - } - - ReportProgress(" verify..."); - timer.StartTask("Compare Source to Expected"); - bool match = CompareGeneratedToExpected(pathName, genPathNames); - timer.EndTask("Compare Source to Expected"); - if (match) { - ReportSuccess(); - results.GenerateOkay = true; - } else { - ReportFailure(); - didFail = true; - - // The fact that it doesn't match the expected sources doesn't mean it's - // invalid. Go ahead and try to build it. - //continue; - } - - // Assemble code. - ReportProgress(" " + asmId.ToString() + " assemble..."); - IAssembler asm = AssemblerInfo.GetAssembler(asmId); - if (asm == null) { - ReportErrMsg("assembler unavailable"); - ReportProgress("\r\n"); - continue; - } - - timer.StartTask("Assemble Source"); - asm.Configure(genPathNames, workDir); - AssemblerResults asmResults = asm.RunAssembler(mWorker); - timer.EndTask("Assemble Source"); - if (asmResults == null) { - ReportErrMsg("unable to run assembler"); - ReportFailure(); - didFail = true; - continue; - } - if (asmResults.ExitCode != 0) { - ReportErrMsg("assembler returned code=" + asmResults.ExitCode); - ReportFailure(); - didFail = true; - continue; - } - - results.AsmResults = asmResults; - - ReportProgress(" verify..."); - timer.StartTask("Compare Binary to Expected"); - FileInfo fi = new FileInfo(asmResults.OutputPathName); - if (fi.Length != project.FileData.Length) { - ReportErrMsg("asm output mismatch: length is " + fi.Length + ", expected " + - project.FileData.Length); - ReportFailure(); - didFail = true; - continue; - } else if (!FileUtil.CompareBinaryFile(project.FileData, asmResults.OutputPathName, - out int badOffset, out byte badFileVal)) { - ReportErrMsg("asm output mismatch: offset +" + badOffset.ToString("x6") + - " has value $" + badFileVal.ToString("x2") + ", expected $" + - project.FileData[badOffset].ToString("x2")); - ReportFailure(); - didFail = true; - continue; - } - timer.EndTask("Compare Binary to Expected"); - - // Victory! - results.AssembleOkay = true; - ReportSuccess(); - - timer.EndTask("Full Test Duration"); - results.Timer = timer; - - // We don't scrub the directory on success at this point. We could, but we'd - // need to remove only those files associated with the currently assembler. - // Otherwise, a failure followed by a success would wipe out the unsuccessful - // temporaries. - } - - // If something failed, leave the bits around for examination. Otherwise, try to - // remove the directory and all its contents. - if (!didFail && !RetainOutput) { - ScrubWorkDirectory(workDir, testNum); - RemoveWorkDirectory(workDir); - } - - project.Cleanup(); - return !didFail; - } - - /// - /// Gets a copy of the AppSettings with a standard set of formatting options (e.g. lower - /// case for everything). - /// - /// New app settings object. - private AppSettings CreateNormalizedSettings() { - AppSettings settings = AppSettings.Global.GetCopy(); - - // Override all asm formatting options. We can ignore ShiftBeforeAdjust and the - // pseudo-op names because those are set by the generators. - settings.SetBool(AppSettings.FMT_UPPER_HEX_DIGITS, false); - settings.SetBool(AppSettings.FMT_UPPER_OP_MNEMONIC, false); - settings.SetBool(AppSettings.FMT_UPPER_PSEUDO_OP_MNEMONIC, false); - settings.SetBool(AppSettings.FMT_UPPER_OPERAND_A, true); - settings.SetBool(AppSettings.FMT_UPPER_OPERAND_S, true); - settings.SetBool(AppSettings.FMT_UPPER_OPERAND_XY, false); - settings.SetBool(AppSettings.FMT_ADD_SPACE_FULL_COMMENT, false); - - // Don't show the assembler ident line. You can make a case for this being - // mandatory, since the generated code is only guaranteed to work with the - // assembler for which it was targeted, but I expect we'll quickly get to a - // place where we don't have to work around assembler bugs, and this will just - // become a nuisance. - settings.SetBool(AppSettings.SRCGEN_ADD_IDENT_COMMENT, false); - - // Don't break lines with long labels. That way we can redefine "long" - // without breaking our tests. (This is purely cosmetic.) - settings.SetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, false); - - // This could be on or off. Off seems less distracting. - settings.SetBool(AppSettings.SRCGEN_SHOW_CYCLE_COUNTS, false); - - // Disable label localization. We want to be able to play with this a bit - // without disrupting all the other tests. Use a test-only feature to enable - // it for the localization test. - settings.SetBool(AppSettings.SRCGEN_DISABLE_LABEL_LOCALIZATION, true); - - IEnumerator iter = AssemblerInfo.GetInfoEnumerator(); - while (iter.MoveNext()) { - AssemblerInfo.Id asmId = iter.Current.AssemblerId; - AssemblerConfig curConfig = - AssemblerConfig.GetConfig(settings, asmId); - AssemblerConfig defConfig = - AssemblerInfo.GetAssembler(asmId).GetDefaultConfig(); - - // Merge the two together. We want the default assembler config for most - // things, but the executable path from the current config. - defConfig.ExecutablePath = curConfig.ExecutablePath; - - // Write it into the test settings. - AssemblerConfig.SetConfig(settings, asmId, defConfig); - } - - return settings; - } - - /// - /// Applies app setting overrides that were specified in the project settings. - /// - private void ApplyProjectSettings(AppSettings settings, DisasmProject project) { - // We could probably make this a more general mechanism, but that would strain - // things a bit, since we need to know the settings name, bool/int/string, and - // desired value. Easier to just have a set of named features. - const string ENABLE_LABEL_LOCALIZATION = "__ENABLE_LABEL_LOCALIZATION"; - const string ENABLE_LABEL_NEWLINE = "__ENABLE_LABEL_NEWLINE"; - - if (project.ProjectProps.ProjectSyms.ContainsKey(ENABLE_LABEL_LOCALIZATION)) { - settings.SetBool(AppSettings.SRCGEN_DISABLE_LABEL_LOCALIZATION, false); - } - if (project.ProjectProps.ProjectSyms.ContainsKey(ENABLE_LABEL_NEWLINE)) { - settings.SetBool(AppSettings.SRCGEN_LONG_LABEL_NEW_LINE, true); - } - } - - private DisasmProject InstantiateProject(string dataPathName, - out FileLoadReport projectLoadReport) { - DisasmProject project = new DisasmProject(); - // always use AppDomain sandbox - - projectLoadReport = null; - - int testNum = GetTestNum(dataPathName); - - if (testNum < 2000) { - // create new disasm project for data file - byte[] fileData; - try { - fileData = LoadDataFile(dataPathName); - } catch (Exception ex) { - ReportErrMsg(ex.Message); - return null; - } - - project.Initialize(fileData.Length); - project.PrepForNew(fileData, Path.GetFileName(dataPathName)); - // no platform symbols to load - } else { - // deserialize project file, failing if we can't find it - string projectPathName = dataPathName + ProjectFile.FILENAME_EXT; - if (!ProjectFile.DeserializeFromFile(projectPathName, - project, out projectLoadReport)) { - ReportErrMsg(projectLoadReport.Format()); - return null; - } - - byte[] fileData; - try { - fileData = LoadDataFile(dataPathName); - } catch (Exception ex) { - ReportErrMsg(ex.Message); - return null; - } - - project.SetFileData(fileData, Path.GetFileName(dataPathName)); - project.ProjectPathName = projectPathName; - project.LoadExternalFiles(); - } - - TaskTimer genTimer = new TaskTimer(); - DebugLog genLog = new DebugLog(); - genLog.SetMinPriority(DebugLog.Priority.Silent); - project.Analyze(UndoableChange.ReanalysisScope.CodeAndData, genLog, genTimer); - - return project; - } - - /// - /// Loads the test case data file. - /// - /// Throws an exception on failure. - /// - /// Full path to test case data file. - /// File contents. - private byte[] LoadDataFile(string pathName) { - byte[] fileData; - - using (FileStream fs = File.Open(pathName, FileMode.Open, FileAccess.Read)) { - Debug.Assert(fs.Length <= DisasmProject.MAX_DATA_FILE_SIZE); - fileData = new byte[fs.Length]; - int actual = fs.Read(fileData, 0, (int)fs.Length); - if (actual != fs.Length) { - // Not expected -- should be able to read the entire file in one shot. - throw new Exception(Properties.Resources.OPEN_DATA_PARTIAL_READ); - } - } - return fileData; - } - - /// - /// Creates a work directory for the specified test case. The new directory will be - /// created in the same directory as the test, and named after it. - /// - /// If the directory already exists, the previous contents will be scrubbed. - /// - /// If the file already exists but isn't a directory, this will fail. - /// - /// Test case path name. - /// Path of work directory, or null if creation failed. - private string CreateWorkDirectory(string pathName) { - string baseDir = Path.GetDirectoryName(pathName); - int testNum = GetTestNum(pathName); - string workDirName = "tmp" + testNum.ToString(); - string workDirPath = Path.Combine(baseDir, workDirName); - if (Directory.Exists(workDirPath)) { - ScrubWorkDirectory(workDirPath, testNum); - } else if (File.Exists(workDirPath)) { - ReportErrMsg("file '" + workDirPath + "' exists, not directory"); - return null; - } else { - try { - Directory.CreateDirectory(workDirPath); - } catch (Exception ex) { - ReportErrMsg(ex.Message); - return null; - } - } - return workDirPath; - } - - /// - /// Removes the contents of a temporary work directory. Only files that we believe - /// to be products of the generator or assembler are removed. - /// - /// - /// - private void ScrubWorkDirectory(string workDir, int testNum) { - string checkString = testNum.ToString(); - if (checkString.Length != 4) { - Debug.Assert(false); - return; - } - - foreach (string pathName in Directory.EnumerateFiles(workDir)) { - bool doRemove = false; - string fileName = Path.GetFileName(pathName); - if (fileName.Contains(checkString)) { - doRemove = true; - } else { - foreach (string str in sScrubList) { - if (fileName == str) { - doRemove = true; - } - } - } - - if (!doRemove) { - ReportErrMsg("not removing '" + fileName + "'"); - continue; - } else { - try { - File.Delete(pathName); - //Debug.WriteLine("removed " + pathName); - } catch (Exception ex) { - ReportErrMsg("unable to remove '" + fileName + "': " + ex.Message); - // don't stop -- keep trying to remove things - } - } - } - } - - private void RemoveWorkDirectory(string workDir) { - try { - Directory.Delete(workDir); - } catch (Exception ex) { - ReportErrMsg("unable to remove work dir: " + ex.Message); - } - } - - /// - /// Compares each file in genFileNames to the corresponding file in Expected. - /// - /// Full pathname of test case. - /// List of file names from source generator. - /// - private bool CompareGeneratedToExpected(string pathName, List genPathNames) { - string expectedDir = Path.Combine(Path.GetDirectoryName(pathName), EXPECTED_DIR_NAME); - - foreach (string path in genPathNames) { - string fileName = Path.GetFileName(path); - string compareName = Path.Combine(expectedDir, fileName); - - if (!File.Exists(compareName)) { - // File was generated unexpectedly. - ReportErrMsg("file '" + fileName + "' not found in " + EXPECTED_DIR_NAME); - return false; - } - - // Compare the file contents as lines of text. The files may use different - // line terminators (e.g. LF vs. CRLF), so we can't use file length as a - // factor. - if (!FileUtil.CompareTextFiles(path, compareName, out int firstDiffLine, - out string line1, out string line2)) { - ReportErrMsg("file '" + fileName + "' differs on line " + firstDiffLine); - Debug.WriteLine("File #1: " + line1); - Debug.WriteLine("File #2: " + line2); - return false; - } - } - - // NOTE: to be thorough, we should check to see if a file exists in Expected - // that doesn't exist in the work directory. This is slightly more awkward since - // Expected is a big pile of everything, but we should be able to do it by - // filtering filenames with the test number. - - return true; - } - } -} diff --git a/SourceGenWF/Tests/GenTestRunner.Designer.cs b/SourceGenWF/Tests/GenTestRunner.Designer.cs deleted file mode 100644 index fb2ac3b..0000000 --- a/SourceGenWF/Tests/GenTestRunner.Designer.cs +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.Tests { - partial class GenTestRunner { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.closeButton = new System.Windows.Forms.Button(); - this.runButton = new System.Windows.Forms.Button(); - this.progressRichTextBox = new System.Windows.Forms.RichTextBox(); - this.outputSelectComboBox = new System.Windows.Forms.ComboBox(); - this.outputTextBox = new System.Windows.Forms.TextBox(); - this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); - this.retainOutputCheckBox = new System.Windows.Forms.CheckBox(); - this.SuspendLayout(); - // - // closeButton - // - this.closeButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.closeButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.closeButton.Location = new System.Drawing.Point(537, 406); - this.closeButton.Name = "closeButton"; - this.closeButton.Size = new System.Drawing.Size(75, 23); - this.closeButton.TabIndex = 4; - this.closeButton.Text = "Close"; - this.closeButton.UseVisualStyleBackColor = true; - // - // runButton - // - this.runButton.Location = new System.Drawing.Point(13, 13); - this.runButton.Name = "runButton"; - this.runButton.Size = new System.Drawing.Size(75, 23); - this.runButton.TabIndex = 0; - this.runButton.Text = "Run Test"; - this.runButton.UseVisualStyleBackColor = true; - this.runButton.Click += new System.EventHandler(this.runButton_Click); - // - // progressRichTextBox - // - this.progressRichTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.progressRichTextBox.BackColor = System.Drawing.SystemColors.Window; - this.progressRichTextBox.Location = new System.Drawing.Point(13, 43); - this.progressRichTextBox.Name = "progressRichTextBox"; - this.progressRichTextBox.ReadOnly = true; - this.progressRichTextBox.Size = new System.Drawing.Size(599, 130); - this.progressRichTextBox.TabIndex = 1; - this.progressRichTextBox.Text = ""; - // - // outputSelectComboBox - // - this.outputSelectComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.outputSelectComboBox.FormattingEnabled = true; - this.outputSelectComboBox.Location = new System.Drawing.Point(13, 201); - this.outputSelectComboBox.Name = "outputSelectComboBox"; - this.outputSelectComboBox.Size = new System.Drawing.Size(300, 21); - this.outputSelectComboBox.TabIndex = 2; - this.outputSelectComboBox.SelectedIndexChanged += new System.EventHandler(this.outputSelectComboBox_SelectedIndexChanged); - // - // outputTextBox - // - this.outputTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.outputTextBox.BackColor = System.Drawing.SystemColors.Window; - this.outputTextBox.Location = new System.Drawing.Point(13, 229); - this.outputTextBox.MaxLength = 0; - this.outputTextBox.Multiline = true; - this.outputTextBox.Name = "outputTextBox"; - this.outputTextBox.ReadOnly = true; - this.outputTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.outputTextBox.Size = new System.Drawing.Size(599, 171); - this.outputTextBox.TabIndex = 3; - // - // backgroundWorker1 - // - this.backgroundWorker1.WorkerReportsProgress = true; - this.backgroundWorker1.WorkerSupportsCancellation = true; - this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); - this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); - this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); - // - // retainOutputCheckBox - // - this.retainOutputCheckBox.AutoSize = true; - this.retainOutputCheckBox.Location = new System.Drawing.Point(116, 17); - this.retainOutputCheckBox.Name = "retainOutputCheckBox"; - this.retainOutputCheckBox.Size = new System.Drawing.Size(90, 17); - this.retainOutputCheckBox.TabIndex = 5; - this.retainOutputCheckBox.Text = "Retain output"; - this.retainOutputCheckBox.UseVisualStyleBackColor = true; - // - // GenTestRunner - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.closeButton; - this.ClientSize = new System.Drawing.Size(624, 441); - this.Controls.Add(this.retainOutputCheckBox); - this.Controls.Add(this.outputTextBox); - this.Controls.Add(this.outputSelectComboBox); - this.Controls.Add(this.progressRichTextBox); - this.Controls.Add(this.runButton); - this.Controls.Add(this.closeButton); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.MinimumSize = new System.Drawing.Size(640, 480); - this.Name = "GenTestRunner"; - this.ShowInTaskbar = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "Source Generation Test"; - this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.GenTestRunner_FormClosing); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Button closeButton; - private System.Windows.Forms.Button runButton; - private System.Windows.Forms.RichTextBox progressRichTextBox; - private System.Windows.Forms.ComboBox outputSelectComboBox; - private System.Windows.Forms.TextBox outputTextBox; - private System.ComponentModel.BackgroundWorker backgroundWorker1; - private System.Windows.Forms.CheckBox retainOutputCheckBox; - } -} \ No newline at end of file diff --git a/SourceGenWF/Tests/GenTestRunner.cs b/SourceGenWF/Tests/GenTestRunner.cs deleted file mode 100644 index d7060d5..0000000 --- a/SourceGenWF/Tests/GenTestRunner.cs +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Text; -using System.Windows.Forms; - -using CommonWinForms; - -namespace SourceGenWF.Tests { - /// - /// Source generation regression test. - /// - public partial class GenTestRunner : Form { - private List mLastResults; - - private bool mClosedWhileRunning; - - public GenTestRunner() { - InitializeComponent(); - } - - private void runButton_Click(object sender, EventArgs e) { - if (backgroundWorker1.IsBusy) { - runButton.Enabled = false; - backgroundWorker1.CancelAsync(); - } else { - ResetDialog(); - runButton.Text = "Cancel"; - backgroundWorker1.RunWorkerAsync(); - } - } - - private void GenTestRunner_FormClosing(object sender, FormClosingEventArgs e) { - if (backgroundWorker1.IsBusy) { - backgroundWorker1.CancelAsync(); - DialogResult = DialogResult.Cancel; - - // If we close now, the app crashes with a "you disposed of the - // RichTextBox" exception. So the first time they request it, refuse. - // The second time, we go ahead and close, in case something is really stuck. - if (!mClosedWhileRunning) { - e.Cancel = true; - mClosedWhileRunning = true; - } - } else { - DialogResult = DialogResult.OK; - } - } - - private void ResetDialog() { - outputSelectComboBox.Items.Clear(); - progressRichTextBox.Clear(); - outputTextBox.Clear(); - mLastResults = null; - } - - // NOTE: executes on work thread. DO NOT do any UI work here. Pass the test - // results through e.Result. - private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { - BackgroundWorker worker = sender as BackgroundWorker; - - GenTest test = new GenTest(); - test.RetainOutput = retainOutputCheckBox.Checked; // okay to do on work thread? - List results = test.Run(worker); - - if (worker.CancellationPending) { - e.Cancel = true; - } else { - e.Result = results; - } - } - - // Callback that fires when a progress update is made. - private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { - // We get progress from GenTest, and from the IAssembler/IGenerator classes. This - // is necessary to make cancellation work right, and allows us to show the - // asm/gen progress messages if we want to. - if (e.UserState is ProgressMessage) { - ProgressMessage msg = e.UserState as ProgressMessage; - if (msg.HasColor) { - progressRichTextBox.AppendText(msg.Text, msg.Color); - } else { - // plain foreground text color - progressRichTextBox.AppendText(msg.Text); - } - progressRichTextBox.SelectionStart = progressRichTextBox.Text.Length; - progressRichTextBox.ScrollToCaret(); - } else { - // Most progress updates have an e.ProgressPercentage value and a blank string. - if (!string.IsNullOrEmpty((string)e.UserState)) { - Debug.WriteLine("Sub-progress: " + e.UserState); - } - } - } - - // Callback that fires when execution completes. - private void backgroundWorker1_RunWorkerCompleted(object sender, - RunWorkerCompletedEventArgs e) { - if (e.Cancelled) { - Debug.WriteLine("Test halted -- user cancellation"); - } else if (e.Error != null) { - // test harness shouldn't be throwing errors like this - Debug.WriteLine("Test failed: " + e.Error.ToString()); - progressRichTextBox.AppendText("\r\n"); - progressRichTextBox.AppendText(e.Error.ToString()); - progressRichTextBox.SelectionStart = progressRichTextBox.Text.Length; - progressRichTextBox.ScrollToCaret(); - } else { - Debug.WriteLine("Tests complete"); - mLastResults = e.Result as List; - if (mLastResults != null) { - PopulateOutputSelect(); - } - } - - runButton.Text = "Run Test"; - runButton.Enabled = true; - - if (mClosedWhileRunning) { - Close(); - } - } - - private void PopulateOutputSelect() { - outputSelectComboBox.Items.Clear(); - if (mLastResults.Count == 0) { - return; - } - - foreach (GenTest.GenTestResults results in mLastResults) { - outputSelectComboBox.Items.Add(results); - } - - // Trigger update. - outputSelectComboBox.SelectedIndex = 0; - } - - private void outputSelectComboBox_SelectedIndexChanged(object sender, EventArgs e) { - int sel = outputSelectComboBox.SelectedIndex; - if (mLastResults == null && mLastResults.Count <= sel) { - Debug.WriteLine("SelIndexChanged to " + sel + ", not available"); - return; - } - - GenTest.GenTestResults results = mLastResults[sel]; - - StringBuilder sb = new StringBuilder(512); - sb.AppendFormat("Path: {0}\r\n", results.PathName); - sb.AppendFormat("Assembler: {0}\r\n", results.AsmId); - if (results.ProjectLoadReport != null) { - sb.AppendFormat("Project load: {0}\r\n", results.ProjectLoadReport.Format()); - } - if (results.GenerateOkay) { - sb.Append("Source gen: OK\r\n"); - } else { - sb.Append("Source gen: FAIL\r\n"); - } - if (results.AssembleOkay) { - sb.Append("Asm gen: OK\r\n"); - } else { - sb.Append("Asm gen: FAIL\r\n"); - } - if (results.AsmResults != null) { - AsmGen.AssemblerResults asmr = results.AsmResults; - sb.AppendFormat("Cmd line: {0}\r\n", asmr.CommandLine); - if (!results.AssembleOkay) { - sb.AppendFormat("Exit code: {0}\r\n", asmr.ExitCode); - } - if (asmr.Stdout != null && asmr.Stdout.Length > 2) { - sb.Append("----- stdout -----\r\n"); - sb.Append(asmr.Stdout); - sb.Append("\r\n"); - } - if (asmr.Stderr != null && asmr.Stderr.Length > 2) { - sb.Append("----- stderr -----\r\n"); - sb.Append(asmr.Stderr); - sb.Append("\r\n"); - } - } - if (results.Timer != null) { - sb.Append("\r\n----- task times -----\r\n"); - sb.Append(results.Timer.DumpToString(string.Empty)); - } - - outputTextBox.Text = sb.ToString(); - } - } -} diff --git a/SourceGenWF/Tests/GenTestRunner.resx b/SourceGenWF/Tests/GenTestRunner.resx deleted file mode 100644 index 59099f2..0000000 --- a/SourceGenWF/Tests/GenTestRunner.resx +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - \ No newline at end of file diff --git a/SourceGenWF/Tests/ProgressMessage.cs b/SourceGenWF/Tests/ProgressMessage.cs deleted file mode 100644 index 2f2f028..0000000 --- a/SourceGenWF/Tests/ProgressMessage.cs +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Drawing; - -namespace SourceGenWF.Tests { - /// - /// Progress message, with colorful text. This is generated by the worker thread and - /// passed to the UI thread. - /// - public class ProgressMessage { - public string Text { get; private set; } - public Color Color { get; private set; } - public bool HasColor { get { return Color.A != 0; } } - - public ProgressMessage(string msg) : this(msg, Color.FromArgb(0, 0, 0, 0)) { } - - public ProgressMessage(string msg, Color color) { - Text = msg; - Color = color; - } - } -} diff --git a/SourceGenWF/Tools/AsciiChart.Designer.cs b/SourceGenWF/Tools/AsciiChart.Designer.cs deleted file mode 100644 index 62a9e37..0000000 --- a/SourceGenWF/Tools/AsciiChart.Designer.cs +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.Tools { - partial class AsciiChart { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AsciiChart)); - this.chartTextBox = new System.Windows.Forms.TextBox(); - this.modeComboBox = new System.Windows.Forms.ComboBox(); - this.SuspendLayout(); - // - // chartTextBox - // - this.chartTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.chartTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.chartTextBox.Location = new System.Drawing.Point(13, 13); - this.chartTextBox.Multiline = true; - this.chartTextBox.Name = "chartTextBox"; - this.chartTextBox.ReadOnly = true; - this.chartTextBox.Size = new System.Drawing.Size(370, 450); - this.chartTextBox.TabIndex = 0; - this.chartTextBox.Text = resources.GetString("chartTextBox.Text"); - // - // modeComboBox - // - this.modeComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.modeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.modeComboBox.FormattingEnabled = true; - this.modeComboBox.Items.AddRange(new object[] { - "Standard ASCII", - "High ASCII"}); - this.modeComboBox.Location = new System.Drawing.Point(13, 474); - this.modeComboBox.Name = "modeComboBox"; - this.modeComboBox.Size = new System.Drawing.Size(167, 21); - this.modeComboBox.TabIndex = 1; - this.modeComboBox.SelectedIndexChanged += new System.EventHandler(this.modeComboBox_SelectedIndexChanged); - // - // AsciiChart - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(395, 507); - this.Controls.Add(this.modeComboBox); - this.Controls.Add(this.chartTextBox); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "AsciiChart"; - this.Text = "ASCII Chart"; - this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.AsciiChart_FormClosed); - this.Load += new System.EventHandler(this.AsciiChart_Load); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.TextBox chartTextBox; - private System.Windows.Forms.ComboBox modeComboBox; - } -} \ No newline at end of file diff --git a/SourceGenWF/Tools/AsciiChart.cs b/SourceGenWF/Tools/AsciiChart.cs deleted file mode 100644 index 12d725e..0000000 --- a/SourceGenWF/Tools/AsciiChart.cs +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Text; -using System.Windows.Forms; - -namespace SourceGenWF.Tools { - public partial class AsciiChart : Form { - /// - /// Chart mode. Must match combo box entries. - /// - private enum Mode { - Standard = 0, - High = 1 - }; - - /// - /// Subscribe to this to be notified when the dialog closes. - /// - public event WindowClosing OnWindowClosing; - public delegate void WindowClosing(object sender, EventArgs e); - - public AsciiChart() { - InitializeComponent(); - } - - private void AsciiChart_Load(object sender, EventArgs e) { - int mode = AppSettings.Global.GetInt(AppSettings.ASCCH_MODE, 0); - if (mode >= 0 && mode < modeComboBox.Items.Count) { - modeComboBox.SelectedIndex = mode; - } - - DrawContents(); - } - - private void AsciiChart_FormClosed(object sender, FormClosedEventArgs e) { - if (OnWindowClosing != null) { - OnWindowClosing(this, e); - } - } - - private void modeComboBox_SelectedIndexChanged(object sender, EventArgs e) { - AppSettings.Global.SetInt(AppSettings.ASCCH_MODE, modeComboBox.SelectedIndex); - - DrawContents(); - } - - private void DrawContents() { - const string hdr = "Dec Hex Chr"; - const string div = " | "; - const string eol = "\r\n"; - - Mode mode = (Mode) modeComboBox.SelectedIndex; - StringBuilder sb = new StringBuilder( - (hdr.Length * 4 + div.Length * 3 + eol.Length) * 32); - sb.Append(hdr); - sb.Append(div); - sb.Append(hdr); - sb.Append(div); - sb.Append(hdr); - sb.Append(div); - sb.Append(hdr); - sb.Append(eol); - for (int i = 0; i < 32; i++) { - DrawEntry(mode, i, sb); - sb.Append(div); - DrawEntry(mode, i + 32, sb); - sb.Append(div); - DrawEntry(mode, i + 64, sb); - sb.Append(div); - DrawEntry(mode, i + 96, sb); - sb.Append(eol); - } - - chartTextBox.Text = sb.ToString(); - chartTextBox.SelectionStart = sb.Length; - chartTextBox.SelectionLength = 0; - } - - private void DrawEntry(Mode mode, int val, StringBuilder sb) { - // Format is: Dec Hex Chr - int modVal = (mode == Mode.High) ? val | 0x80 : val; - sb.AppendFormat("{0,3:D} {1,3:X2} ", modVal, modVal); - if (val < 0x20) { - sb.Append('^'); - sb.Append((char)(val + 0x40)); - sb.Append(' '); - } else if (val == 0x20) { - sb.Append("' '"); - } else if (val < 0x7f) { - sb.Append(' '); - sb.Append((char)val); - sb.Append(' '); - } else { - sb.Append("DEL"); - } - } - } -} diff --git a/SourceGenWF/Tools/AsciiChart.resx b/SourceGenWF/Tools/AsciiChart.resx deleted file mode 100644 index dd72817..0000000 --- a/SourceGenWF/Tools/AsciiChart.resx +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Hex Dec Chr | Hex Dec Chr | Hex Dec Chr | Hex Dec Chr - 00 - 01 - 02 - 03 - 04 - 05 - 06 - 07 - 08 - 09 - 0a - 0b - 0c - 0d - 0e - 0f - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 1a - 1b - 1c - 1d - 1e - 1f - - - \ No newline at end of file diff --git a/SourceGenWF/Tools/HexDumpViewer.Designer.cs b/SourceGenWF/Tools/HexDumpViewer.Designer.cs deleted file mode 100644 index 8d78b4d..0000000 --- a/SourceGenWF/Tools/HexDumpViewer.Designer.cs +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.Tools { - partial class HexDumpViewer { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.hexDumpListView = new System.Windows.Forms.ListView(); - this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.charConvComboBox = new System.Windows.Forms.ComboBox(); - this.charConvLabel = new System.Windows.Forms.Label(); - this.topMostCheckBox = new System.Windows.Forms.CheckBox(); - this.asciiOnlyCheckBox = new System.Windows.Forms.CheckBox(); - this.SuspendLayout(); - // - // hexDumpListView - // - this.hexDumpListView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.hexDumpListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.columnHeader1}); - this.hexDumpListView.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.hexDumpListView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; - this.hexDumpListView.HideSelection = false; - this.hexDumpListView.Location = new System.Drawing.Point(13, 13); - this.hexDumpListView.Name = "hexDumpListView"; - this.hexDumpListView.Size = new System.Drawing.Size(477, 514); - this.hexDumpListView.TabIndex = 0; - this.hexDumpListView.UseCompatibleStateImageBehavior = false; - this.hexDumpListView.View = System.Windows.Forms.View.Details; - this.hexDumpListView.VirtualMode = true; - this.hexDumpListView.CacheVirtualItems += new System.Windows.Forms.CacheVirtualItemsEventHandler(this.hexDumpListView_CacheVirtualItems); - this.hexDumpListView.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.hexDumpListView_RetrieveVirtualItem); - // - // columnHeader1 - // - this.columnHeader1.Text = "Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F ASCII"; - this.columnHeader1.Width = 455; - // - // charConvComboBox - // - this.charConvComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.charConvComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.charConvComboBox.FormattingEnabled = true; - this.charConvComboBox.Items.AddRange(new object[] { - "Basic ASCII", - "High/Low ASCII"}); - this.charConvComboBox.Location = new System.Drawing.Point(130, 533); - this.charConvComboBox.Name = "charConvComboBox"; - this.charConvComboBox.Size = new System.Drawing.Size(136, 21); - this.charConvComboBox.TabIndex = 1; - this.charConvComboBox.SelectedIndexChanged += new System.EventHandler(this.charConvComboBox_SelectedIndexChanged); - // - // charConvLabel - // - this.charConvLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.charConvLabel.AutoSize = true; - this.charConvLabel.Location = new System.Drawing.Point(13, 536); - this.charConvLabel.Name = "charConvLabel"; - this.charConvLabel.Size = new System.Drawing.Size(111, 13); - this.charConvLabel.TabIndex = 2; - this.charConvLabel.Text = "Character conversion:"; - // - // topMostCheckBox - // - this.topMostCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.topMostCheckBox.AutoSize = true; - this.topMostCheckBox.Location = new System.Drawing.Point(398, 535); - this.topMostCheckBox.Name = "topMostCheckBox"; - this.topMostCheckBox.Size = new System.Drawing.Size(92, 17); - this.topMostCheckBox.TabIndex = 3; - this.topMostCheckBox.Text = "Always on top"; - this.topMostCheckBox.UseVisualStyleBackColor = true; - this.topMostCheckBox.CheckedChanged += new System.EventHandler(this.topMostCheckBox_CheckedChanged); - // - // asciiOnlyCheckBox - // - this.asciiOnlyCheckBox.AutoSize = true; - this.asciiOnlyCheckBox.Location = new System.Drawing.Point(284, 535); - this.asciiOnlyCheckBox.Name = "asciiOnlyCheckBox"; - this.asciiOnlyCheckBox.Size = new System.Drawing.Size(104, 17); - this.asciiOnlyCheckBox.TabIndex = 4; - this.asciiOnlyCheckBox.Text = "ASCII-only dump"; - this.asciiOnlyCheckBox.UseVisualStyleBackColor = true; - this.asciiOnlyCheckBox.CheckedChanged += new System.EventHandler(this.asciiOnlyCheckBox_CheckedChanged); - // - // HexDumpViewer - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(502, 561); - this.Controls.Add(this.asciiOnlyCheckBox); - this.Controls.Add(this.topMostCheckBox); - this.Controls.Add(this.charConvLabel); - this.Controls.Add(this.charConvComboBox); - this.Controls.Add(this.hexDumpListView); - this.MinimumSize = new System.Drawing.Size(518, 180); - this.Name = "HexDumpViewer"; - this.Text = "Hex Dump Viewer"; - this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.HexDumpViewer_FormClosed); - this.Load += new System.EventHandler(this.HexDumpViewer_Load); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.ListView hexDumpListView; - private System.Windows.Forms.ColumnHeader columnHeader1; - private System.Windows.Forms.ComboBox charConvComboBox; - private System.Windows.Forms.Label charConvLabel; - private System.Windows.Forms.CheckBox topMostCheckBox; - private System.Windows.Forms.CheckBox asciiOnlyCheckBox; - } -} \ No newline at end of file diff --git a/SourceGenWF/Tools/HexDumpViewer.cs b/SourceGenWF/Tools/HexDumpViewer.cs deleted file mode 100644 index eaf46dd..0000000 --- a/SourceGenWF/Tools/HexDumpViewer.cs +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Diagnostics; -using System.Text; -using System.Windows.Forms; - -using Asm65; -using CommonWinForms; - -namespace SourceGenWF.Tools { - /// - /// Display a hex dump. - /// - public partial class HexDumpViewer : Form { - /// - /// Maximum length of data we will display. - /// - public const int MAX_LENGTH = 1 << 24; - - /// - /// Character conversion mode. The enum must match the items in the combo box. - /// - private enum CharConvMode { - PlainAscii = 0, - HighLowAscii - } - - /// - /// Data to display. We currently require that the entire file fit in memory, - /// which is reasonable because we impose a 2^24 (16MB) limit. - /// - private byte[] mData; - - /// - /// Data formatter object. - /// - /// There's currently no way to update this after the dialog is opened, which means - /// we won't track changes to hex case preference. I'm okay with that. - /// - private Formatter mFormatter; - - /// - /// If true, don't include non-ASCII characters in text area. - /// - private bool mAsciiOnlyDump; - - /// - /// Subscribe to this to be notified when the dialog closes. - /// - public event WindowClosing OnWindowClosing; - public delegate void WindowClosing(object sender, EventArgs e); - - - public HexDumpViewer(byte[] data, Formatter formatter) { - InitializeComponent(); - - hexDumpListView.SetDoubleBuffered(true); - - Debug.Assert(data.Length <= MAX_LENGTH); - mData = data; - mFormatter = formatter; - - hexDumpListView.VirtualListSize = (mData.Length + 15) / 16; - } - - private void HexDumpViewer_Load(object sender, EventArgs e) { - topMostCheckBox.Checked = TopMost; - - // Configure ASCII-only mode. Note this causes the CheckedChange callback to - // fire, which sets the field and replaces the formatter. - bool asciiOnly = AppSettings.Global.GetBool(AppSettings.HEXD_ASCII_ONLY, false); - asciiOnlyCheckBox.Checked = asciiOnly; - - // Just save and restore the combo box index. This might come up wrong after - // an upgrade that shuffles the options, but doing it right isn't worth the effort. - int charConv = AppSettings.Global.GetInt(AppSettings.HEXD_CHAR_CONV, 0); - if (charConv >= 0 && charConv <= charConvComboBox.Items.Count) { - charConvComboBox.SelectedIndex = charConv; - } - } - - protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { - if (keyData == (Keys.Control | Keys.A)) { - hexDumpListView.SelectAll(); - return true; - } else if (keyData == (Keys.Control | Keys.C)) { - CopySelectionToClipboard(); - return true; - } - - return base.ProcessCmdKey(ref msg, keyData); - } - - private void asciiOnlyCheckBox_CheckedChanged(object sender, EventArgs e) { - mAsciiOnlyDump = asciiOnlyCheckBox.Checked; - AppSettings.Global.SetBool(AppSettings.HEXD_ASCII_ONLY, mAsciiOnlyDump); - - ReplaceFormatter(); - InvalidateListView(); - } - - private void topMostCheckBox_CheckedChanged(object sender, EventArgs e) { - TopMost = topMostCheckBox.Checked; - } - - private void charConvComboBox_SelectedIndexChanged(object sender, EventArgs e) { - Debug.WriteLine("charConvCombBox selected: " + charConvComboBox.SelectedIndex); - AppSettings.Global.SetInt(AppSettings.HEXD_CHAR_CONV, charConvComboBox.SelectedIndex); - - ReplaceFormatter(); - InvalidateListView(); - } - - private void HexDumpViewer_FormClosed(object sender, FormClosedEventArgs e) { - if (OnWindowClosing != null) { - OnWindowClosing(this, e); - } - } - - /// - /// Replaces the Formatter with a new one, using the current dialog configuration. - /// - private void ReplaceFormatter() { - Formatter.FormatConfig config = mFormatter.Config; - - config.mHexDumpAsciiOnly = mAsciiOnlyDump; - - CharConvMode mode = (CharConvMode)charConvComboBox.SelectedIndex; - switch (mode) { - case CharConvMode.PlainAscii: - config.mHexDumpCharConvMode = Formatter.FormatConfig.CharConvMode.PlainAscii; - break; - case CharConvMode.HighLowAscii: - config.mHexDumpCharConvMode = Formatter.FormatConfig.CharConvMode.HighLowAscii; - break; - case (CharConvMode)(-1): - // this happens during dialog init, before combo box is configured - break; - default: - Debug.Assert(false); - break; - } - - mFormatter = new Formatter(config); - } - - /// - /// Generates a string for every selected line, then copies the full thing to the - /// clipboard. - /// - private void CopySelectionToClipboard() { - ListView.SelectedIndexCollection indices = hexDumpListView.SelectedIndices; - if (indices.Count == 0) { - Debug.WriteLine("Nothing selected"); - return; - } - - // Try to make the initial allocation big enough to hold the full thing. - // Each line is currently 73 bytes, plus we throw in a CRLF. Doesn't have to - // be exact. With a 16MB max file size we're creating a ~75MB string for the - // clipboard, which .NET and Win10-64 seem to be able to handle. - StringBuilder sb = new StringBuilder(indices.Count * (73 + 2)); - - try { - Application.UseWaitCursor = true; - Cursor.Current = Cursors.WaitCursor; - - foreach (int index in indices) { - mFormatter.FormatHexDump(mData, index * 16, sb); - sb.Append("\r\n"); - } - } finally { - Application.UseWaitCursor = false; - Cursor.Current = Cursors.Arrow; - } - - Clipboard.SetText(sb.ToString(), TextDataFormat.Text); - } - - /// - /// Sets the scroll position to show the specified range. - /// - /// First offset to show. - /// Last offset to show. - public void ShowOffsetRange(int startOffset, int endOffset) { - Debug.WriteLine("HexDumpViewer: show +" + startOffset.ToString("x6") + " - +" + - endOffset.ToString("x6")); - int startLine = startOffset / 16; - int endLine = endOffset / 16; - - // TODO(someday): instead of selecting the lines, highlight the individual - // bytes. This requires an owner-drawn ListView. - hexDumpListView.SelectedIndices.Clear(); - for (int i = startLine; i <= endLine; i++) { - hexDumpListView.SelectedIndices.Add(i); - } - hexDumpListView.EnsureVisible(endLine); - hexDumpListView.EnsureVisible(startLine); - } - - - #region Virtual List View - // Using a virtual list view means we're allocating objects frequently when the - // list is being scrolled, but get to avoid massive trauma when opening a large file, - // and don't have to turn a 16MB file into a 74+MB string collection. - - /// - /// Cache of previously-constructed ListViewItems. The ListView will request items - /// continuously as they are moused-over, so this is fairly important. - /// - private ListViewItem[] mItemCache; - private int mItemCacheFirst; - - private void hexDumpListView_RetrieveVirtualItem(object sender, - RetrieveVirtualItemEventArgs e) { - // Is item cached? - if (mItemCache != null && e.ItemIndex >= mItemCacheFirst && - e.ItemIndex < mItemCacheFirst + mItemCache.Length) { - // Yes, return existing item. - e.Item = mItemCache[e.ItemIndex - mItemCacheFirst]; - } else { - // No, create item. - e.Item = CreateListViewItem(e.ItemIndex); - } - } - - private void hexDumpListView_CacheVirtualItems(object sender, - CacheVirtualItemsEventArgs e) { - if (mItemCache != null && e.StartIndex >= mItemCacheFirst && - e.EndIndex <= mItemCacheFirst + mItemCache.Length) { - // Already have this span cached. - return; - } - - // Discard old cache, create new one, populate it. - mItemCacheFirst = e.StartIndex; - int len = e.EndIndex - e.StartIndex + 1; // end is inclusive - mItemCache = new ListViewItem[len]; - for (int i = 0; i < len; i++) { - mItemCache[i] = CreateListViewItem(e.StartIndex + i); - } - } - - private ListViewItem CreateListViewItem(int index) { - string fmtd = mFormatter.FormatHexDump(mData, index * 16); - return new ListViewItem(fmtd); - } - - /// - /// Invalidates the contents of the list view, forcing a redraw. Useful when - /// the desired output format changes. - /// - private void InvalidateListView() { - hexDumpListView.BeginUpdate(); - mItemCache = null; - mItemCacheFirst = -1; - hexDumpListView.EndUpdate(); - } - - #endregion Virtual List View - } -} diff --git a/SourceGenWF/Tools/HexDumpViewer.resx b/SourceGenWF/Tools/HexDumpViewer.resx deleted file mode 100644 index 1af7de1..0000000 --- a/SourceGenWF/Tools/HexDumpViewer.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SourceGenWF/Tools/ShowText.Designer.cs b/SourceGenWF/Tools/ShowText.Designer.cs deleted file mode 100644 index d041b9c..0000000 --- a/SourceGenWF/Tools/ShowText.Designer.cs +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -namespace SourceGenWF.Tools { - partial class ShowText { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.textBox = new System.Windows.Forms.TextBox(); - this.SuspendLayout(); - // - // textBox - // - this.textBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.textBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBox.Location = new System.Drawing.Point(13, 13); - this.textBox.MaxLength = 0; - this.textBox.Multiline = true; - this.textBox.Name = "textBox"; - this.textBox.ReadOnly = true; - this.textBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.textBox.Size = new System.Drawing.Size(629, 431); - this.textBox.TabIndex = 0; - this.textBox.Text = "012345678901234567890123456789012345678901234567890123456789012345678901234567890" + - "1234567890123456789"; - // - // ShowText - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(654, 456); - this.Controls.Add(this.textBox); - this.Name = "ShowText"; - this.Text = "Title"; - this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.ShowText_FormClosed); - this.Load += new System.EventHandler(this.ShowText_Load); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.TextBox textBox; - } -} \ No newline at end of file diff --git a/SourceGenWF/Tools/ShowText.cs b/SourceGenWF/Tools/ShowText.cs deleted file mode 100644 index ebcddbb..0000000 --- a/SourceGenWF/Tools/ShowText.cs +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Diagnostics; -using System.Windows.Forms; - -namespace SourceGenWF.Tools { - /// - /// Simple form for showing text in a TextBox. This can be used as a modeless - /// dialog, so a "window closing" event is available. - /// - public partial class ShowText : Form { - /// - /// Window title. - /// - public string Title { - set { - Text = value; - } - } - - /// - /// Text to display. - /// - public string BodyText { - get { - return textBox.Text; - } - set { - textBox.Text = value; - textBox.SelectionStart = textBox.Text.Length; - textBox.ScrollToCaret(); - } - } - - /// - /// Subscribe to this to be notified when the dialog closes. - /// - public event WindowClosing OnWindowClosing; - public delegate void WindowClosing(object sender, EventArgs e); - - public ShowText() { - InitializeComponent(); - } - - private void ShowText_Load(object sender, EventArgs e) { - //textBox.Select(BodyText.Length, BodyText.Length); - - if (Modal) { - MaximizeBox = false; - MinimizeBox = false; - // Changing the ShowInTaskbar value kills the dialog. If we really care we - // can pass a "will be modal" parameter to the constructor and do it there. - // https://stackoverflow.com/a/20443430/294248 - //ShowInTaskbar = false; - } - } - - private void ShowText_FormClosed(object sender, FormClosedEventArgs e) { - if (OnWindowClosing != null) { - OnWindowClosing(this, e); - } - } - } -} diff --git a/SourceGenWF/Tools/ShowText.resx b/SourceGenWF/Tools/ShowText.resx deleted file mode 100644 index 1af7de1..0000000 --- a/SourceGenWF/Tools/ShowText.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/SourceGenWF/UndoableChange.cs b/SourceGenWF/UndoableChange.cs deleted file mode 100644 index b27b0cd..0000000 --- a/SourceGenWF/UndoableChange.cs +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Diagnostics; - -using Asm65; -using CommonUtil; - -/* -*** When is a full (code+data) re-analysis required? -- Adding/removing/changing an address change (ORG directive). This has a significant impact -on the code analyzer, as blocks of code may become reachable or unreachable. -- Adding/removing/changing a type hint. These can affect whether a given offset is treated -as code, which can have a dramatic effect on code analysis (consider the offset 0 code hint). -- Adding/removing/changing a status flag override. This can affect whether a branch is -always taken or never taken, and the M/X flags affect instruction interpretation. (It may -be possible to do an "incremental" code analysis here, working from the point of the change -forward, propagating changes outward, but that gets tricky when a branch changes from -ambiguously-taken to never-taken, and the destination may need to be treated as data.) - -*** When is a partial (data-only) re-analysis required? -- Adding/removing a user label. The code that tries to adjust data targets to match nearby -user labels must be re-run, possibly impacting auto-generated labels. A user label added -to the middle of a multi-byte data element will cause the element to be split, requiring -reanalysis of the pieces. -- Adding/removing/changing an operand label, e.g "LDA label". This can affect which -offsets are marked as data targets, which affects the data analyzer. (We could be smart -about this and not invoke reanalysis if the label value matches the operand, but address -operands should already have labels via offset reference, so it's unclear how valuable -this would be.) -- Adding/removing/changing a format descriptor with a symbol or Numeric/Address. This -can affect the data target analysis. - -*** When is a partial (late-data) re-analysis required? -- Adding/removing/changing the length of a formatted data item, when that item isn't subject -to conditions above (e.g. the descriptor doesn't specify a symbol). This affects which bytes -are considered "uncategorized", so the uncategorized-data analysis must be repeated. - -*** When is display-only re-analysis needed? -- When altering the way that data is formatted, it's useful to exercise the same code paths, -up to the point where the analyzer is called. We still want to go through all the steps that -update the display list and cause controls to be redrawn, but we don't want to actually change -anything in the DisasmProject. "Misc" means we do nothing but pretend there was a full update. - -*** When can we get away with only updating part of the display list (re-analysis=none)? -- Changing a user label. All lines that reference the label need to be updated in the -display, but nothing in the analysis changes. (This assumes we prevent you from renaming -a label to be the same as an existing label, e.g. auto-generated labels.) -- Adding/removing/changing cosmetic items, like comments and notes. - -NOTE: all re-analysis requirements are symmetric for undo/redo. Undoing a change requires -the same level of work as doing the change. -*/ - -namespace SourceGenWF { - /// - /// A single change. - /// - public class UndoableChange { - public enum ChangeType { - Unknown = 0, - - // Dummy change, used to force a full update. - Dummy, - - // Adds, updates, or removes an AddressMap entry. - SetAddress, - - // Changes the type hint. - SetTypeHint, - - // Adds, updates, or removes a processor status flag override. - SetStatusFlagOverride, - - // Adds, updates, or removes a user-specified label. - SetLabel, - - // Adds, updates, or removes a data or operand format. - SetOperandFormat, - - // Changes the end-of-line comment. - SetComment, - - // Changes the long comment. - SetLongComment, - - // Changes the note. - SetNote, - - // Updates project properties. - SetProjectProperties - } - - /// - /// Enum indicating what needs to be reanalyzed after a change. - /// - public enum ReanalysisScope { - None = 0, - DisplayOnly, - DataOnly, - CodeAndData - } - - /// - /// Identifies the change type. - /// - public ChangeType Type { get; private set; } - - /// - /// The "root offset". For example, changing the type hint for a 4-byte - /// instruction from code to data will actually affect 4 offsets, but we - /// only need to specify the root item. - /// - public int Offset { get; private set; } - - /// - /// Value we're changing to. - /// - public object NewValue { get; private set; } - - /// - /// Previous value, used for "undo". - /// - public object OldValue { get; private set; } - - /// - /// Indicates what amount of reanalysis is required after the change is implemented. - /// - public ReanalysisScope ReanalysisRequired { get; private set; } - - - // Don't instantiate directly. - private UndoableChange() { } - - public bool HasOffset { - get { - switch (Type) { - case ChangeType.Dummy: - case ChangeType.SetTypeHint: - case ChangeType.SetProjectProperties: - return false; - default: - return true; - } - } - } - - /// - /// Creates an UndoableChange that does nothing but force an update. - /// - /// Desired reanalysis flags. - /// Change record. - public static UndoableChange CreateDummyChange(ReanalysisScope flags) { - UndoableChange uc = new UndoableChange(); - uc.Type = ChangeType.Dummy; - uc.Offset = -1; - uc.ReanalysisRequired = flags; - return uc; - } - - /// - /// Creates an UndoableChange for an address map update. - /// - /// Affected offset. - /// Previous address map entry, or -1 if none. - /// New address map entry, or -1 if none. - /// Change record. - public static UndoableChange CreateAddressChange(int offset, int oldAddress, - int newAddress) { - if (oldAddress == newAddress) { - Debug.WriteLine("No-op address change at +" + offset.ToString("x6") + - ": " + oldAddress); - } - UndoableChange uc = new UndoableChange(); - uc.Type = ChangeType.SetAddress; - uc.Offset = offset; - uc.OldValue = oldAddress; - uc.NewValue = newAddress; - uc.ReanalysisRequired = ReanalysisScope.CodeAndData; - return uc; - } - - /// - /// Creates an UndoableChange for a type hint update. Rather than adding a - /// separate UndoableChange for each affected offset -- which could span the - /// entire file -- we use range sets to record the before/after state. - /// - /// Current values. - /// New values. - /// Change record. - public static UndoableChange CreateTypeHintChange(TypedRangeSet undoSet, - TypedRangeSet newSet) { - if (newSet.Count == 0) { - Debug.WriteLine("Empty hint change?"); - } - UndoableChange uc = new UndoableChange(); - uc.Type = ChangeType.SetTypeHint; - uc.Offset = -1; - uc.OldValue = undoSet; - uc.NewValue = newSet; - // Any hint change can affect whether something is treated as code. - // Either we're deliberately setting it as code or non-code, or we're - // setting it to "no hint", which means the code analyzer gets - // to make the decision now. This requires a full code+data re-analysis. - uc.ReanalysisRequired = ReanalysisScope.CodeAndData; - return uc; - } - - /// - /// Creates an UndoableChange for a status flag override update. - /// - /// Affected offset. - /// Current flags. - /// New flags. - /// - public static UndoableChange CreateStatusFlagChange(int offset, StatusFlags oldFlags, - StatusFlags newFlags) { - if (oldFlags == newFlags) { - Debug.WriteLine("No-op status flag change at " + offset); - } - UndoableChange uc = new UndoableChange(); - uc.Type = ChangeType.SetStatusFlagOverride; - uc.Offset = offset; - uc.OldValue = oldFlags; - uc.NewValue = newFlags; - // This can affect instruction widths (for M/X) and conditional branches. We - // don't need to re-analyze for changes to I/D, but users don't really need to - // change those anyway, so it's not worth optimizing. - uc.ReanalysisRequired = ReanalysisScope.CodeAndData; - return uc; - } - - /// - /// Creates an UndoableChange for a label update. - /// - /// Affected offset. - /// Current label. May be null. - /// New label. May be null. - /// Change record. - public static UndoableChange CreateLabelChange(int offset, Symbol oldSymbol, - Symbol newSymbol) { - if (oldSymbol == newSymbol) { - Debug.WriteLine("No-op label change at +" + offset.ToString("x6") + - ": " + oldSymbol); - } - - UndoableChange uc = new UndoableChange(); - uc.Type = ChangeType.SetLabel; - uc.Offset = offset; - uc.OldValue = oldSymbol; - uc.NewValue = newSymbol; - // Data analysis can change if we add or remove a label in a data area. Label - // selection can change as well, e.g. switching from an auto-label to a user - // label with an adjustment. So renaming a user-defined label doesn't require - // reanalysis, but adding or removing one does. - // - // Do the reanalysis if either is empty. This will cause an unnecessary - // reanalysis if we change an empty label to an empty label, but that shouldn't - // be allowed by the UI anyway. - Debug.Assert(newSymbol == null || newSymbol.SymbolSource == Symbol.Source.User); - if ((oldSymbol == null) || (newSymbol == null) /*|| - (oldSymbol.SymbolSource != newSymbol.SymbolSource)*/) { - uc.ReanalysisRequired = ReanalysisScope.DataOnly; - } else { - uc.ReanalysisRequired = ReanalysisScope.None; - } - return uc; - } - - /// - /// Creates an UndoableChange for an operand or data format update. This method - /// refuses to create a change for a no-op, returning null instead. This will - /// convert a FormatDescriptor with type REMOVE to null, with the intention of - /// removing the descriptor from the format set. - /// - /// Affected offset. - /// Current format. May be null. - /// New format. May be null. - /// Change record, or null for a no-op change. - public static UndoableChange CreateActualOperandFormatChange(int offset, - FormatDescriptor oldFormat, FormatDescriptor newFormat) { - if (newFormat != null && newFormat.FormatType == FormatDescriptor.Type.REMOVE) { - Debug.WriteLine("CreateOperandFormatChange: converting REMOVE to null"); - newFormat = null; - } - if (oldFormat == newFormat) { - Debug.WriteLine("No-op format change at +" + offset.ToString("x6") + - ": " + oldFormat); - return null; - } - - return CreateOperandFormatChange(offset, oldFormat, newFormat); - } - - /// - /// Creates an UndoableChange for an operand or data format update. - /// - /// Affected offset. - /// Current format. May be null. - /// New format. May be null. - /// Change record. - public static UndoableChange CreateOperandFormatChange(int offset, - FormatDescriptor oldFormat, FormatDescriptor newFormat) { - if (oldFormat == newFormat) { - Debug.WriteLine("No-op format change at +" + offset.ToString("x6") + - ": " + oldFormat); - } - - // We currently allow old/new formats with different lengths. There doesn't - // seem to be a reason not to, and a slight performance advantage to doing so. - // Also, if a change set has two changes at the same offset, undo requires - // enumerating the list in reverse order. - - UndoableChange uc = new UndoableChange(); - uc.Type = ChangeType.SetOperandFormat; - uc.Offset = offset; - uc.OldValue = oldFormat; - uc.NewValue = newFormat; - - // Data-only reanalysis is required if the old or new format has a label. Simply - // changing from e.g. default to decimal, or decimal to binary, doesn't matter. - // (The format editing code ensures that labels don't appear in the middle of - // a formatted region.) Adding, removing, or changing a symbol can change the - // layout of uncategorized data, affect data targets, xrefs, etc. - // - // We can't only check for a symbol, though, because Numeric/Address will - // create an auto-label if the reference is within the file. - // - // If the number of bytes covered by the format changes, or we're adding or - // removing a format, we need to redo the analysis of uncategorized data. For - // example, an auto-detected string could get larger or smaller. We don't - // currently have a separate flag for just that. Also, because we're focused - // on just one change, we can't skip reanalysis when (say) one 4-byte numeric - // is converted to two two-byte numerics. - if ((oldFormat != null && oldFormat.HasSymbolOrAddress) || - (newFormat != null && newFormat.HasSymbolOrAddress)) { - uc.ReanalysisRequired = ReanalysisScope.DataOnly; - } else if (oldFormat == null || newFormat == null || - oldFormat.Length != newFormat.Length) { - uc.ReanalysisRequired = ReanalysisScope.DataOnly; - } else { - uc.ReanalysisRequired = ReanalysisScope.None; - } - return uc; - } - - /// - /// Creates an UndoableChange for a comment update. - /// - /// Affected offset. - /// Current comment. - /// New comment. - /// Change record. - public static UndoableChange CreateCommentChange(int offset, string oldComment, - string newComment) { - if (oldComment.Equals(newComment)) { - Debug.WriteLine("No-op comment change at +" + offset.ToString("x6") + - ": " + oldComment); - } - - UndoableChange uc = new UndoableChange(); - uc.Type = ChangeType.SetComment; - uc.Offset = offset; - uc.OldValue = oldComment; - uc.NewValue = newComment; - uc.ReanalysisRequired = ReanalysisScope.None; - return uc; - } - - /// - /// Creates an UndoableChange for a long comment update. - /// - /// Affected offset. - /// Current comment. - /// New comment. - /// Change record. - public static UndoableChange CreateLongCommentChange(int offset, - MultiLineComment oldComment, MultiLineComment newComment) { - if (oldComment == newComment) { - Debug.WriteLine("No-op long comment change at +" + offset.ToString("x6") + - ": " + oldComment); - } - - UndoableChange uc = new UndoableChange(); - uc.Type = ChangeType.SetLongComment; - uc.Offset = offset; - uc.OldValue = oldComment; - uc.NewValue = newComment; - uc.ReanalysisRequired = ReanalysisScope.None; - return uc; - } - - /// - /// Creates an UndoableChange for a note update. - /// - /// Affected offset. - /// Current note. - /// New note. - /// Change record. - public static UndoableChange CreateNoteChange(int offset, - MultiLineComment oldNote, MultiLineComment newNote) { - if (oldNote == newNote) { - Debug.WriteLine("No-op note change at +" + offset.ToString("x6") + - ": " + oldNote); - } - - UndoableChange uc = new UndoableChange(); - uc.Type = ChangeType.SetNote; - uc.Offset = offset; - uc.OldValue = oldNote; - uc.NewValue = newNote; - uc.ReanalysisRequired = ReanalysisScope.None; - return uc; - } - - /// - /// Creates an UndoableChange for a change to the project properties. - /// - /// Current note. - /// New note. - /// Change record. - public static UndoableChange CreateProjectPropertiesChange(ProjectProperties oldProps, - ProjectProperties newProps) { - Debug.Assert(oldProps != null && newProps != null); - if (oldProps == newProps) { // doesn't currently work except as reference check - Debug.WriteLine("No-op property change: " + oldProps); - } - - UndoableChange uc = new UndoableChange(); - uc.Type = ChangeType.SetProjectProperties; - uc.Offset = -1; - uc.OldValue = oldProps; - uc.NewValue = newProps; - - // Project properties could change the CPU type, requiring a full code+data - // reanalysis. We could scan the objects to see what actually changed, but that - // doesn't seem worthwhile. - uc.ReanalysisRequired = ReanalysisScope.CodeAndData; - return uc; - } - - public override string ToString() { - return "[UC type=" + Type + " offset=+" + - (HasOffset ? Offset.ToString("x6") : "N/A") + "]"; - } - } -} diff --git a/SourceGenWF/VirtualListViewSelection.cs b/SourceGenWF/VirtualListViewSelection.cs deleted file mode 100644 index dadb0b8..0000000 --- a/SourceGenWF/VirtualListViewSelection.cs +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Windows.Forms; - -using CommonUtil; - -namespace SourceGenWF { - /// - /// Tracks the items selected in a list view. - /// - /// Forward the ItemSelectionChanged and VirtualItemsSelectionRangeChanged. - /// - public class VirtualListViewSelection { - private BitArray mSelection; - - /// - /// Retrieves the total number of boolean values in the set. This is NOT the - /// number of selected items. - /// - public int Length { get { return mSelection.Length; } } - - /// - /// Sets or gets the Nth element. True means the line is selected. - /// - public bool this[int key] { - get { - return mSelection[key]; - } - set { - mSelection[key] = value; - } - } - - public VirtualListViewSelection() { - mSelection = new BitArray(0); - } - - public VirtualListViewSelection(int length) { - mSelection = new BitArray(length); - } - - /// - /// Sets the length of the selection array. - /// - /// If the new length is longer, the new elements are initialized to false. If the - /// new length is shorter, the excess elements are discarded. (This matches the behavior - /// of a virtual ListView selection set.) - /// - /// New length. - public void SetLength(int length) { - //Debug.WriteLine("VirtualListViewSelection length now " + length); - mSelection.Length = length; - } - - /// - /// Handle a state change for a single item. - /// - public void ItemSelectionChanged(ListViewItemSelectionChangedEventArgs e) { - //Debug.WriteLine("ItemSelectionChanged: " + e.ItemIndex + " (" + e.IsSelected + ")"); - if (e.ItemIndex >= mSelection.Length) { - Debug.WriteLine("GLITCH: selection index " + e.ItemIndex + " out of range"); - Debug.Assert(false); - return; - } - mSelection.Set(e.ItemIndex, e.IsSelected); - } - - /// - /// Handle a state change for a range of items. - /// - public void VirtualItemsSelectionRangeChanged( - ListViewVirtualItemsSelectionRangeChangedEventArgs e) { - //Debug.WriteLine("VirtualRangeChange: " + e.StartIndex + " - " + e.EndIndex + - // " (" + e.IsSelected + ")"); - - if (e.StartIndex == 0 && e.EndIndex == mSelection.Length - 1) { - // Set all elements. The list view control seems to like to set all elements - // to false whenever working with multi-select, so this should be fast. - //Debug.WriteLine("VirtualRangeChange: set all to " + e.IsSelected); - mSelection.SetAll(e.IsSelected); - } else { - if (e.EndIndex >= mSelection.Length) { - Debug.WriteLine("GLITCH: selection end index " + e.EndIndex + " out of range"); - Debug.Assert(false); - return; - } - bool val = e.IsSelected; - for (int i = e.StartIndex; i <= e.EndIndex; i++) { - mSelection.Set(i, val); - } - } - } - - /// - /// Confirms that the selection count matches the number of set bits. Pass - /// in {ListView}.SelectedIndices.Count. - /// - /// Expected number of selected entries. - /// True if count matches. - public bool DebugValidateSelectionCount(int expected) { - int actual = 0; - foreach (bool bit in mSelection) { - if (bit) { - actual++; - } - } - if (actual != expected) { - Debug.WriteLine("SelectionCount expected " + expected + ", actual " + actual); - } - return (actual == expected); - } - - public void DebugDump() { - RangeSet rangeSet = new RangeSet(); - for (int i = 0; i < mSelection.Length; i++) { - if (mSelection[i]) { - rangeSet.Add(i); - } - } - Debug.WriteLine("VirtualListViewSelection ranges:"); - IEnumerator iter = rangeSet.RangeListIterator; - while (iter.MoveNext()) { - RangeSet.Range range = iter.Current; - Debug.WriteLine(" [" + range.Low.ToString() + "," + range.High.ToString() + "]"); - } - } - } -} diff --git a/SourceGenWF/WeakSymbolRef.cs b/SourceGenWF/WeakSymbolRef.cs deleted file mode 100644 index a36163c..0000000 --- a/SourceGenWF/WeakSymbolRef.cs +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Diagnostics; - -namespace SourceGenWF { - /// - /// Weak reference to a symbol for use in an operand or data statement. The reference - /// is by name; if the symbol disappears or changes value, the reference can be ignored. - /// This also specifies which part of the numeric value is of interest, so we can reference - /// the high or low byte of a 16-bit value in (say) LDA #imm. - /// - /// Instances are immutable. - /// - public class WeakSymbolRef { - /// - /// This identifies the part of the value that we're interested in. All values are - /// signed 32-bit integers. - /// - public enum Part { - // This indicates which byte we start with, useful for immediate operands - // and things like PEA. By popular convention, these are referred to as - // low, high, and bank. - // - // With 16-bit registers, Merlin 32 grabs the high *word*, while cc65's assembler - // grabs the high *byte*. One is a shift, the other is a byte select. We use - // low/high/bank just to mean position here. - // - // (Could make this orthogonal with a pair of bit fields, one for position and - // one for width, but there's really only three widths of interest (1, 2, 3 bytes) - // and that's defined by context.) - Unknown = 0, - Low, // LDA #label, LDA # - /// Character collection buffer. The delimiters are written into the buffer - /// because they're mixed with bytes, particularly when we have to escape the - /// delimiter character. Strings might start or end with escaped delimiters, - /// so we don't add them until we have to. - private char[] mBuffer; - - /// - /// Next available character position. - /// - private int mIndex = 0; - - /// - /// State of the buffer, based on the last thing we added. - /// - private enum State { - Unknown = 0, - StartOfLine, - InQuote, - OutQuote - } - private State mState = State.StartOfLine; - - /// - /// Constructor. - /// - /// Reference back to generator, for output function and - /// format options. - /// Line label. Appears on first output line only. - /// Opcode to use for all lines. - /// End-of-line comment. Appears on first output line - /// only. - /// String delimiter character. - /// If true, no file output is produced. - public StringGather(IGenerator gen, string label, string opcode, - string comment, char delimiter, char delimReplace, ByteStyle byteStyle, - int maxOperandLen, bool isTestRun) { - Gen = gen; - Label = label; - Opcode = opcode; - Comment = comment; - Delimiter = delimiter; - DelimiterReplacement = delimReplace; - ByteStyleX = byteStyle; - MaxOperandLen = maxOperandLen; - IsTestRun = isTestRun; - - mBuffer = new char[MaxOperandLen]; - mHexChars = Gen.SourceFormatter.HexDigits; - } - - /// - /// Write a character into the buffer. - /// - /// Character to add. - public void WriteChar(char ch) { - Debug.Assert(ch >= 0 && ch <= 0xff); - if (ch == Delimiter) { - // Must write it as a byte. - HasDelimiter = true; - WriteByte((byte)DelimiterReplacement); - return; - } - - // If we're at the start of a line, add delimiter, then new char. - // If we're inside quotes, just add the character. We must have space for - // two chars (new char, close quote). - // If we're outside quotes, add a comma and delimiter, then the character. - // We must have 4 chars remaining (comma, open quote, new char, close quote). - switch (mState) { - case State.StartOfLine: - mBuffer[mIndex++] = Delimiter; - break; - case State.InQuote: - if (mIndex + 2 > MaxOperandLen) { - Flush(); - mBuffer[mIndex++] = Delimiter; - } - break; - case State.OutQuote: - if (mIndex + 4 > MaxOperandLen) { - Flush(); - mBuffer[mIndex++] = Delimiter; - } else { - mBuffer[mIndex++] = ','; - mBuffer[mIndex++] = Delimiter; - } - break; - default: - Debug.Assert(false); - break; - } - mBuffer[mIndex++] = ch; - mState = State.InQuote; - } - - /// - /// Write a hex value into the buffer. - /// - /// Value to add. - public void WriteByte(byte val) { - // If we're at the start of a line, just output the byte. - // If we're inside quotes, emit a delimiter, comma, and the byte. We must - // have space for four (DenseHex) or five (CommaSep) chars. - // If we're outside quotes, add the byte. We must have two (DenseHex) or - // four (CommaSep) chars remaining. - switch (mState) { - case State.StartOfLine: - break; - case State.InQuote: - int minWidth = (ByteStyleX == ByteStyle.CommaSep) ? 5 : 4; - if (mIndex + minWidth > MaxOperandLen) { - Flush(); - } else { - mBuffer[mIndex++] = Delimiter; - mBuffer[mIndex++] = ','; - } - break; - case State.OutQuote: - minWidth = (ByteStyleX == ByteStyle.CommaSep) ? 4 : 2; - if (mIndex + minWidth > MaxOperandLen) { - Flush(); - } else { - if (ByteStyleX == ByteStyle.CommaSep) { - mBuffer[mIndex++] = ','; - } - } - break; - default: - Debug.Assert(false); - break; - } - - if (ByteStyleX == ByteStyle.CommaSep) { - mBuffer[mIndex++] = '$'; - } - mBuffer[mIndex++] = mHexChars[val >> 4]; - mBuffer[mIndex++] = mHexChars[val & 0x0f]; - mState = State.OutQuote; - } - - /// - /// Tells the object to flush any pending data to the output. - /// - public void Finish() { - Flush(); - } - - /// - /// Outputs the buffer of pending data. A closing delimiter will be added if needed. - /// - private void Flush() { - switch (mState) { - case State.StartOfLine: - // empty string; put out a pair of delimiters - mBuffer[mIndex++] = Delimiter; - mBuffer[mIndex++] = Delimiter; - NumLinesOutput++; - break; - case State.InQuote: - // add delimiter and finish - mBuffer[mIndex++] = Delimiter; - NumLinesOutput++; - break; - case State.OutQuote: - // just output it - NumLinesOutput++; - break; - } - if (!IsTestRun) { - Gen.OutputLine(Label, Opcode, new string(mBuffer, 0, mIndex), - Comment); - } - mIndex = 0; - - // Erase these after first use so we don't put them on every line. - Label = Comment = string.Empty; - } - } -} diff --git a/SourceGenWF/AutoLabel.cs b/SourceGenWF/AutoLabel.cs deleted file mode 100644 index 44c276c..0000000 --- a/SourceGenWF/AutoLabel.cs +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2019 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.Text; -using System.Diagnostics; - -namespace SourceGenWF { - /// - /// Functions for generation of "auto" labels. - /// - public static class AutoLabel { - /// - /// Auto-label style enumeration. Values were chosen to map directly to a combo box. - /// - public enum Style { - Unknown = -1, - Simple = 0, - Annotated = 1, - FullyAnnotated = 2 - } - - /// - /// Generates a unique address symbol. Does not add the symbol to the table. - /// - /// This does not follow any Formatter rules -- labels are always entirely upper-case. - /// - /// Address that label will be applied to. - /// Symbol table, for uniqueness check. - /// Prefix to use; must start with a letter. - /// Newly-created, unique symbol. - public static Symbol GenerateUniqueForAddress(int addr, SymbolTable symbols, - string prefix) { - // $1234 == L1234, $05/1234 == L51234. - string label = prefix + addr.ToString("X4"); // always upper-case - if (symbols.TryGetValue(label, out Symbol unused)) { - const int MAX_RENAME = 999; - string baseLabel = label; - StringBuilder sb = new StringBuilder(baseLabel.Length + 8); - int index = -1; - - do { - // This is expected to be unlikely and infrequent, so a simple linear - // probe for uniqueness is fine. Labels are based on the address, not - // the offset, so even without user-created labels there's still an - // opportunity for duplication. - index++; - sb.Clear(); - sb.Append(baseLabel); - sb.Append('_'); - sb.Append(index); - label = sb.ToString(); - } while (index <= MAX_RENAME && symbols.TryGetValue(label, out unused)); - if (index > MAX_RENAME) { - // I give up - throw new Exception("Too many identical symbols: " + label); - } - } - Symbol sym = new Symbol(label, addr, Symbol.Source.Auto, - Symbol.Type.LocalOrGlobalAddr); - return sym; - } - - /// - /// Source reference type. - /// - /// The enum is in priority order, i.e. the lowest-valued item "wins" in situations - /// where only one value is used. - /// - [Flags] - private enum RefTypes { - None = 0, - SubCall = 1 << 0, - Branch = 1 << 1, - DataRef = 1 << 2, - Write = 1 << 3, - Read = 1 << 4, - } - private static readonly char[] TAGS = { 'S', 'B', 'D', 'W', 'R' }; - - /// - /// Generates an auto-label with a prefix string based on the XrefSet. - /// - /// Address that label will be applied to. - /// Symbol table, for uniqueness check. - /// Cross-references for this location. - /// Newly-created, unique symbol. - public static Symbol GenerateAnnotatedLabel(int addr, SymbolTable symbols, - XrefSet xset, Style style) { - Debug.Assert(xset != null); - Debug.Assert(style != Style.Simple); - - RefTypes rtypes = RefTypes.None; - foreach (XrefSet.Xref xr in xset) { - switch (xr.Type) { - case XrefSet.XrefType.SubCallOp: - rtypes |= RefTypes.SubCall; - break; - case XrefSet.XrefType.BranchOp: - rtypes |= RefTypes.Branch; - break; - case XrefSet.XrefType.RefFromData: - rtypes |= RefTypes.DataRef; - break; - case XrefSet.XrefType.MemAccessOp: - switch (xr.AccType) { - case Asm65.OpDef.MemoryEffect.Read: - rtypes |= RefTypes.Read; - break; - case Asm65.OpDef.MemoryEffect.Write: - rtypes |= RefTypes.Write; - break; - case Asm65.OpDef.MemoryEffect.ReadModifyWrite: - rtypes |= RefTypes.Read; - rtypes |= RefTypes.Write; - break; - case Asm65.OpDef.MemoryEffect.None: - case Asm65.OpDef.MemoryEffect.Unknown: - break; - default: - Debug.Assert(false); - break; - } - break; - default: - Debug.Assert(false); - break; - } - } - - if (rtypes == RefTypes.None) { - // unexpected - Debug.Assert(false); - return GenerateUniqueForAddress(addr, symbols, "X_"); - } - - StringBuilder sb = new StringBuilder(8); - for (int i = 0; i < TAGS.Length; i++) { - if (((int) rtypes & (1 << i)) != 0) { - sb.Append(TAGS[i]); - - if (style == Style.Annotated) { - break; - } - } - } - sb.Append('_'); - return GenerateUniqueForAddress(addr, symbols, sb.ToString()); - } - } -} diff --git a/SourceGenWF/ChangeSet.cs b/SourceGenWF/ChangeSet.cs deleted file mode 100644 index 6dd4ef9..0000000 --- a/SourceGenWF/ChangeSet.cs +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; - -namespace SourceGenWF { - /// - /// Holds information about a set of changes. - /// - /// Does not have hooks into other data structures. This just holds the information - /// about the changes. - /// - public class ChangeSet : IEnumerable { - private List mChanges; - - /// - /// Constructs an empty ChangeSet with the specified initial capacity. - /// - /// Initial number of elements that the set can contain. - public ChangeSet(int capacity) { - mChanges = new List(capacity); - } - - /// - /// Constructs a ChangeSet with a single change. - /// - public ChangeSet(UndoableChange ac) { - mChanges = new List(1); - mChanges.Add(ac); - } - - /// - /// The number of changes in the set. - /// - public int Count { get { return mChanges.Count; } } - - /// - /// Returns the Nth change in the set. - /// - /// Change index. - public UndoableChange this[int key] { - get { - return mChanges[key]; - } - } - - /// - /// Adds a change to the change set. - /// - /// Change to add. - public void Add(UndoableChange change) { - Debug.Assert(change != null); - mChanges.Add(change); - } - - /// - /// Adds a change to the change set if the object is non-null. - /// - /// Change to add, or null. - public void AddNonNull(UndoableChange change) { - if (change != null) { - Add(change); - } - } - - /// - /// Trims unused capacity from the set. - /// - public void TrimExcess() { - mChanges.TrimExcess(); - } - - // IEnumerable, so we can use foreach syntax when going forward - public IEnumerator GetEnumerator() { - return mChanges.GetEnumerator(); - } - - // IEnumerable: generic version - IEnumerator IEnumerable.GetEnumerator() { - return mChanges.GetEnumerator(); - } - - // TODO(maybe): reverse-order enumerator? - - public override string ToString() { - string str = "[CS: count=" + mChanges.Count; - if (mChanges.Count > 0) { - str += " {0:" + mChanges[0] + "}"; - } - str += "]"; - return str; - } - } -} diff --git a/SourceGenWF/CodeAnalysis.cs b/SourceGenWF/CodeAnalysis.cs deleted file mode 100644 index 48636b7..0000000 --- a/SourceGenWF/CodeAnalysis.cs +++ /dev/null @@ -1,1070 +0,0 @@ -/* - * Copyright 2018 faddenSoft - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -using System; -using System.Collections.Generic; -using System.Diagnostics; - -using Asm65; -using CommonUtil; -using PluginCommon; -using SourceGenWF.Sandbox; - -namespace SourceGenWF { - /// - /// Instruction analyzer. - /// - /// All data held in this object is transient, and will be discarded when analysis - /// completes. All user-defined values should be held elsewhere and provided as inputs - /// to the analyzer. Any change that merits re-analysis should be handled by creating a - /// new instance of this object. - /// - /// See the comments at the top of UndoableChange for a list of things that can - /// mandate code re-analysis. - /// - public class CodeAnalysis { - /// - /// Type hints are specified by the user. The identify a region as being code - /// or data. The code analyzer will stop at data-hinted regions, and will - /// process any code-hinted regions during the dead-code pass. - /// - /// The hints are not used directly by the data analyzer, but the effects they - /// have on the Anattrib array are. - /// - public enum TypeHint : sbyte { - // No hint. Default value populated in new arrays. - NoHint = 0, - - // Byte is an instruction. If the code analyzer doesn't find this - // naturally, it will be scanned. - Code, - - // Byte is inline data. Execution continues "through" the byte. - InlineData, - - // Byte is data. Execution halts. - Data - } - - /// - /// Class for handling callbacks from extension scripts. - /// - private class ScriptSupport : MarshalByRefObject, PluginCommon.IApplication { - private CodeAnalysis mOuter; - - public ScriptSupport(CodeAnalysis ca) { - mOuter = ca; - } - - /// - /// Call this when analysis is complete, to ensure that over-active scripts - /// can't keep doing things. (This is not part of IApplication.) - /// - public void Shutdown() { - mOuter = null; - } - - public void DebugLog(string msg) { - mOuter.mDebugLog.LogI("PLUGIN: " + msg); - } - - public bool SetOperandFormat(int offset, DataSubType subType, string label) { - return mOuter.SetOperandFormat(offset, subType, label); - } - - public bool SetInlineDataFormat(int offset, int length, DataType type, - DataSubType subType, string label) { - return mOuter.SetInlineDataFormat(offset, length, type, subType, label); - } - } - - /// - /// Extension script manager. - /// - private ScriptManager mScriptManager; - - /// - /// Local object that implements the IApplication interface for plugins. - /// - private ScriptSupport mScriptSupport; - - /// - /// List of interesting plugins. If we have plugins that don't do code inlining we - /// can ignore them. (I'm using an array instead of a List<IPlugin> as a - /// micro-optimization; see https://stackoverflow.com/a/454923/294248 .) - /// - private IPlugin[] mScriptArray; - - /// - /// CPU to use when analyzing data. - /// - private CpuDef mCpuDef; - - /// - /// Map of offsets to addresses. - /// - private AddressMap mAddrMap; - - /// - /// Reference to 65xx data. - /// - private byte[] mFileData; - - /// - /// Attributes, one per byte in input file. - /// - private Anattrib[] mAnattribs; - - /// - /// Reference to type hint array, one hint per byte. - /// - private TypeHint[] mTypeHints; - - /// - /// Reference to status flag override array, one entry per byte. - /// - private StatusFlags[] mStatusFlagOverrides; - - /// - /// Initial status flags to use at entry points. - /// - private StatusFlags mEntryFlags; - - /// - /// Debug trace log. - /// - private DebugLog mDebugLog = new DebugLog(DebugLog.Priority.Silent); - - - /// - /// Constructor. - /// - /// 65xx code stream. - /// CPU definition to use when interpreting code. - /// Anattrib array. Expected to be newly allocated, all - /// entries set to default values. - /// Map of offsets to addresses. - /// Type hints, one per byte. - /// Status flag overrides for instruction-start - /// bytes. - /// Status flags to use at code entry points. - /// Extension script manager. - /// Object that receives debug log messages. - public CodeAnalysis(byte[] data, CpuDef cpuDef, Anattrib[] anattribs, - AddressMap addrMap, TypeHint[] hints, StatusFlags[] statusFlagOverrides, - StatusFlags entryFlags, ScriptManager scriptMan, DebugLog debugLog) { - mFileData = data; - mCpuDef = cpuDef; - mAnattribs = anattribs; - mAddrMap = addrMap; - mTypeHints = hints; - mStatusFlagOverrides = statusFlagOverrides; - mEntryFlags = entryFlags; - mScriptManager = scriptMan; - mDebugLog = debugLog; - - mScriptSupport = new ScriptSupport(this); - } - - // Internal log functions. If we're concerned about performance overhead due to - // call-site string concatenation, we can #ifdef these to nothing in release builds, - // which should allow the compiler to elide the concat. -#if false - private void LogV(int offset, string msg) { - if (mDebugLog.IsLoggable(DebugLog.Priority.Verbose)) { - mDebugLog.LogV("+" + offset.ToString("x6") + " " + msg); - } - } -#else - private void LogV(int offset, string msg) { } -#endif -#if true - private void LogD(int offset, string msg) { - if (mDebugLog.IsLoggable(DebugLog.Priority.Debug)) { - mDebugLog.LogD("+" + offset.ToString("x6") + " " + msg); - } - } - private void LogI(int offset, string msg) { - if (mDebugLog.IsLoggable(DebugLog.Priority.Info)) { - mDebugLog.LogI("+" + offset.ToString("x6") + " " + msg); - } - } - private void LogW(int offset, string msg) { - if (mDebugLog.IsLoggable(DebugLog.Priority.Warning)) { - mDebugLog.LogW("+" + offset.ToString("x6") + " " + msg); - } - } - private void LogE(int offset, string msg) { - if (mDebugLog.IsLoggable(DebugLog.Priority.Error)) { - mDebugLog.LogE("+" + offset.ToString("x6") + " " + msg); - } - } -#else - private void LogD(int offset, string msg) { } - private void LogI(int offset, string msg) { } - private void LogW(int offset, string msg) { } - private void LogE(int offset, string msg) { } -#endif - - /// - /// Analyze a blob of code and data, annotating all code areas. - /// - /// Also identifies data embedded in code, e.g. parameter blocks following a JSR, - /// with the help of extension scripts. - /// - /// Failing here can leave us in a strange state, so prefer to work around unexpected - /// inputs rather than bailing entirely. - /// - public void Analyze() { - List scanOffsets = new List(); - - mDebugLog.LogI("Analyzing code: " + mFileData.Length + " bytes, CPU=" + mCpuDef.Name); - - PrepareScripts(); - - SetAddresses(); - - // Set the "is data" and "is inline data" flags on anything that the user has - // flagged as being such. This tells us to stop processing or skip over bytes - // as we work. We don't need to flag code hints explicitly for analysis, but - // we want to be able to display the flags in the info window. - // - // The data recognizers may spot additional inline data offsets as we work. This - // can cause a race if it mis-identifies code that is also a branch target; - // whichever marks the code first will win. - UnpackTypeHints(); - - // Find starting place, based on type hints. - // We only set the "visited" flag on the instruction start, so if the user - // puts a code hint in the middle of an instruction, we will find it and - // treat it as an entry point. (This is useful for embedded instructions - // that are branched to by code we aren't able to detect.) - int searchStart = FindFirstUnvisitedInstruction(0); - while (searchStart >= 0) { - mAnattribs[searchStart].IsEntryPoint = true; - mAnattribs[searchStart].StatusFlags = mEntryFlags; - mAnattribs[searchStart].ApplyStatusFlags(mStatusFlagOverrides[searchStart]); - - int offset = searchStart; - while (true) { - bool embedded = (mAnattribs[offset].IsInstruction && - !mAnattribs[offset].IsVisited); - LogI(offset, "Scan chunk (vis=" + mAnattribs[offset].IsVisited + - " chg=" + mAnattribs[offset].IsChanged + - (embedded ? " embedded " : "") + ")"); - - AnalyzeSegment(offset, scanOffsets); - - // Did anything new get added? - if (scanOffsets.Count == 0) { - break; - } - - // Pop one off the end. - int lastItem = scanOffsets.Count - 1; - offset = scanOffsets[lastItem]; - scanOffsets.RemoveAt(lastItem); - } - - searchStart = FindFirstUnvisitedInstruction(searchStart); - } - - mScriptSupport.Shutdown(); - - MarkUnexecutedEmbeddedCode(); - } - - /// - /// Prepare a list of relevant extension scripts. - /// - private void PrepareScripts() { - if (mScriptManager == null) { - // Currently happens for regression tests with no external files. - mScriptArray = new IPlugin[0]; - return; - } - - // Include all scripts. - mScriptArray = mScriptManager.GetAllInstances().ToArray(); - - // Prep them. - mScriptManager.PrepareScripts(mScriptSupport); - } - - /// - /// Sets the address for every byte in the input. - /// - private void SetAddresses() { - // The AddressMap will have at least one entry, will start at offset 0, and - // will exactly span the file. - foreach (AddressMap.AddressMapEntry ent in mAddrMap) { - int addr = ent.Addr; - for (int i = ent.Offset; i < ent.Offset + ent.Length; i++) { - mAnattribs[i].Address = addr++; - } - } - } - - /// - /// Sets the "is xxxxx" flags on type-hinted entries, so that the code analyzer - /// can find them easily. - /// - private void UnpackTypeHints() { - Debug.Assert(mTypeHints.Length == mAnattribs.Length); - int offset = 0; - foreach (TypeHint hint in mTypeHints) { - switch (hint) { - case TypeHint.Code: - // Set the IsInstruction flag to prevent inline data from being - // placed here. - OpDef op = mCpuDef.GetOpDef(mFileData[offset]); - if (op == OpDef.OpInvalid) { - LogI(offset, "Ignoring code hint on illegal opcode"); - } else { - mAnattribs[offset].IsHinted = true; - mAnattribs[offset].IsInstruction = true; - } - break; - case TypeHint.Data: - // Tells the code analyzer to stop. Does not define a data analyzer - // "uncategorized data" boundary. - mAnattribs[offset].IsHinted = true; - mAnattribs[offset].IsData = true; - break; - case TypeHint.InlineData: - // Tells the code analyzer to walk across these. - mAnattribs[offset].IsHinted = true; - mAnattribs[offset].IsInlineData = true; - break; - case TypeHint.NoHint: - break; - default: - Debug.Assert(false); - break; - } - offset++; - } - } - - /// - /// Finds the first offset that is hinted as code but hasn't yet been visited. - /// - /// This might be in the middle of an already-visited instruction. - /// - /// Offset at which to start the search. - /// Offset found. - private int FindFirstUnvisitedInstruction(int start) { - for (int i = start; i < mAnattribs.Length; i++) { - if (mAnattribs[i].IsHinted && mTypeHints[i] == TypeHint.Code && - !mAnattribs[i].IsVisited) { - LogD(i, "Unvisited code hint"); - if (mAnattribs[i].IsData || mAnattribs[i].IsInlineData) { - // Maybe the user put a code hint on something that was - // later recognized as inline data? Shouldn't have been allowed. - LogW(i, "Weird: code hint on data/inline"); - continue; - } - return i; - } - } - return -1; - } - - /// - /// Finds bits of code that are part of embedded instructions but not actually - /// executed, and marks them as inline data. - /// - private void MarkUnexecutedEmbeddedCode() { - // The problem arises when you have a line like 4C 60 EA, with a branch to the - // middle byte. The formatter will print "JMP $EA60", then "

m5Ky+C6f5gYLWA_i5QJ57b>7%?KUd&%+zM?1U*r001V8BIcmAE~W0P zg1Piv-zrTr>tn}E^SpFjG`B!8*W#xl60yxo3EsYV0l)pDzy0lJ|Ifd^yVz`|lKQoDv*GmMDnK-g&5fQTd* zC@k}QTyo=tsWwUHa@;LtK3-qdK90>z*t{qPEx#IuVVI_=y&cOuw^@*|WXn}cBZ>oI zE`>=6ppRW7%C)lj`M4T}=x+Vc6FLz_k+JX9e6xz*{p8yppPhYiv%5PSk4vewzJGrj z7lsj=ugc6*E-`Y8(NNR&RdRK8b+g@Z#uNJsj>j1Y8jodMZ^mK$=<-oF^jBB!-n@C< zpm$`B08vCu4Jr&4Rf6SkQ2d)}KLC++)wHH_1=#I94F zYE==IAZFTpoVC_A`4R4!<<<4ggUgHEesAi-YP70I*ivXxF6~2Mp;C%Fh;(Y1kc1l2 z%NpNc9Q$dS565E+;_gDY8pF@O`bx8EwUR3lt%k8${o<>yLkIwbptaUg%4+Nn(^P6@ zVFPeA2}CSy(A2CBT^A9smYPz|rG^k|EoWnIfv3ZgQX)bkWX5UEQQ<^5QLL&d?b}r( zT_{z}lo*qxmPHd|G&2N?eb*+K<2cSsYQbNvb?dvXl;Y?O<)~^6A^!2lAAj@w8!fdh zEEutQ`td|Oqf#md&N-VqqA|0&5+aH8{g_im^w{+wNE`5gTDxqtRzwb`H7&;wj`Q3G zdhW1Zue(0-+z=V=-d?YndP+--T`8G4m>ClwG6LpW7@+HVRSO|Jyg0wQy#v7ZGM_(x z!^|NDJ|S-{hOneGr`*M^)|zt`;asv1n;8k`T!?5GhW&15pu{5g(*0UW2*KQlrL76u z?Hgk}fugL2(7$?n-TK;gv34QmS`oZy%UPI>-!C28*+#vuVk@V@^v#q+#eD zKio3Y?S2X|lv0R6BSk_)&KqPbVI z+p8PL2A1|F>^D;;{N$sLONDt}rg;*vQnhu7xz3CPfFU%y3OIt>iQ%ti!gRgpAAb7$ z@q?Ke+su*(--l-qQOO1G)0K(b3Hlf=JL$#;$Ge-V1_-4i2!V+Mvxra(A;zxnQG|$* z*&R~R{k;6*&DCc=`{ms)|Eg#y^*(P6v8p#Dsgh#O;D_CwUcO^+Z-AHgM=|036%0)U zdm0XhmcR%NaYeb-tI7ZHXJ4Xg7s8TD8=3%skhp4-0>Ft(XCm^ROxedS=OV-*gsR1| z{tBKGt6Go{LQJJ1At5n25}u}`fb5ZpC6&@7eWyGr)9MNZgo1$*p9rNV%Nv4eefR3^ zk{lcr{A#xgB9X(;56w*(nB8ot8ip|vetvy(JEv*R%d#}3zS(`3-ileKriMUln!Quz zqN&zoW-u?QRCUL$@4+1rL;|R~)sk~g$*cf45`uXnY7x@1EREINs!`RGZ#Bl)RsfFB z52LU!VP29O{N-Q${5uam0KgY_yI;S2#$6!hTFZW#N>fIZ@@i+lHH!s9wut4%xP5uGe_dbx{N2A? zulwJ5c6mJ=YbqhiD54Iv7DQb4eb&5RayBTYhFI0=Qc^BAhsA0wIR}YyPX%u|Yav8L z9JlLm8;&W35NfUaLsL{r$tA>4YdzH3b$!X1hzL2A{5}-Di(M*-h$Ms)k-!uH_J@Nu za4Eppce$S8XqfRtb9LXY&r?pj{b93N@AiifLT=Aysl<3c&JBAg*DdD4XFZXWxXO92EH z*4iFjKgkIJYAHx;S;u~8WJ+_tyV*0d2n!2h6Z@#EZrAHl%5k3Wm*UtDU9BaElnVXO z&r>48&A7Td9tlD9#ODn$wlJa=(%hVHDJ4XRT_kij1p^}o_c!m}Sye<#B?lHHLKH-m z(AAo2E$+xbiYMj~B5u#lrg{3{;l*ysIp>nA>C8dg3<1WmKOCkekxOL(gs$(*Y{?ZI zTD~s|2I2kgz=XB9Hl4P6&XuKQz&Ro@V#+BrWT3;?kL}=X4dv^1S4h-#A?I9cl@JN3 zDP7y#en}aCH)EgGkVs37(gl_fg@jBUz#5NiT&c>=#Sld^+sdCJ~K&zGpr&UuX4ky1jz3+X;q5t6FHkG=Yo7xP!7(V{sfq}ifJ=SXO zle_1Xmt3a2cu_PRnZ5T~>JY<3gydO$Jq%wR^pF1FFW`9FY|4ZujV=PzR(cYeYLHOe zOU*A|zYP)r(M-3S&GC3_q)8@*_dU`5Wh26b2#8FCfVWF|{q^gYZ>}lyt&mc+VUVS2 z!;Qg7eB_A0M4M6iIM#VV>`WaH9KakK)v`lecl{WLUV4#;+|{Za0RU3ft7-n?tE(5E z{xwY34MN;JsEyJ*^l?e$JsZ;0NDUE%@ICjSAm>KXM6OGuC{SW{hs@d)^ zQ7uahC2J$`#t?GRfC28~vF~xc{(ipF*cc<f(vtRj_iO$AAc~wOGp3EJ^qAR>b^j zm%h3A*#N=2Zq7AV?Lq)-ifuDT0K^L|9DGF)|BMwhCZT#N4ODfkhe(@jiqY5xr%VyobcbzOz~zIg*&% zVVb6@H5Z?z!|i@|_r>S`$shgrzxa>-?mu|;!PV`ZRV^h4k*4nHB$(TA&VT&rFN&I) z39(4i%~!ZjO=#m=dB*H;L%BdZvZSN~grPj6$ zS>`1KZaQ8Tsj2{{N2?7L3(>qRwN^FTZa1Zr)i^Fo5)p87!dh$J4=vTe%v+cLt4c_4 z4kOp^LMxI-uE41s;c)QN!jgZB1R_>7Gb~+-0P%>IE+J86_Ne%(8sQsN=bNG zmKZphwMyCHln3tabINWe1Vo&cC4}(N2M@LCeol?yT)mzWbpTT-MO8u|B4%l-`}fiA z<7&Oz?V3F`)pD`fOeu!|rKDCHnJNH@$aWZz<@RoO(z1Gsc_#$0ss^@96AQ=KP4ndL zjO?!4K7RD=?|$~>=Q$-UTC1LI*K^7z`gba6UcP?*y6^j1$_d^MU}^v`O>^_yqq~{~ z05H!vy8|g)oOJ-9v!^zdIx8wYAr5M z0ZePH7(^l>_k9GwX_*ew^z6yw7w@hd+^pOjl#qml2voJyG7j-a-}~g#pT9ViJ%9^K zDMiiHoLPDfOd{OYK-`R8A;irv&bd@AB9R#zjz^V5L`!X_P|BH+)C~;5K}3pbtgO=@x00@|856-mu_3d>nCAUok%h31axEfc7{lr8H$iTJM zd0ArU+?@bSTR4iV`Q4PFk|BG*DdlPw2)e*6J2|N$lGOr;gzzBp2TwQNKf(h2W(eA? zwi`FCUTNqRsG~42$9vL+#Lw2+Fa~zns0W;G99kozF6DQr6(dLBtRx&hWjF% zOtm%Ku1z-=k}d7j3KALv%fMUWJ&T;IdG{fMh;X730%9ZG1GE4DbvYpwUS8n|O8a!iSc3?NtUi(T)RpS=17oA#t6y&xewsaeqq z09_YKDM+=c)pIW3Kq8DyKreyW()8j_|F1v(`n&(_@BLQ2eqCy1;{W#--^|l8m6?f& z*wo&J+5Cpf59x9_1JH=%#_PQE#O`ANypo)HN^Mq zz0>gofQ;lPUc3q;02Hm@z(HCD^*qmp2;g1UueTQ=$TH2ZUcWLkAsYH_vQz4{h=dRr zW2q;lWel;Ff{5zc*ir~^I2^{!=H<-`+Q0eqtDpbp|H1FdW*b;8FD@?6E)UZ*&GV8= zNqI4kLHaHVvF2urvisB|CqyAuche?GMIt=z_YTl?5@T0N0Wi83SY2G4&HJOO*J^n= z4qd-H9EZMZQ$8ZLQs$ImA0_e+zxSOV|Mh1>*U!sQLd%3Xb#=9#!rPmyW=^SHMOBrV z=XoB-u@OB>DXNXXFJ`t{t(IlE*q*8SemaOqsbv_)v@8Z_W_QQql(MRAHe+)KAs`dE zdoHCauEr68RCS)`*2**}thuen&2if2Qo3;BGmx=+L$9KnDQe@5J9C4OB9Xeb-n6QI z^Xgp#GH|5EUS+1udTXY;!=VY>8nj%s06^Dwrj~Lo^%!F)r5f6@ET--!AY~+C0Jo~D zmQn)re#HRD!qj5z+*=y4xwXun&9Ev~8IZf6)w*uj=ls*p{s!C#QKFo0&u(`6TI(zfH~(jyJF@!E%IK(RITrOsMXy{E-|(cEn`7JNx77IstsSfdDFrnx^74*k&wC7 zQr&#DT^I8||H&66osefa=e8YhBxf@xVXew6sbm0WmQu>jrsxamR%GaLKUBr#dvGRT0iZ-~FD+oBku5IFUb8~my*{6&27ogPIv~7QS-nHvoIp%bAwaanH zIXg>_9z6#1G3I$34%3kD>JztAhI!r5KjB{_4R?dFj7p#`X#Gi zm}Wr`5liN`AGLq|Klum$)Bp7scDi-Fe`eQRNVn$~cZb`iX)=)`?2YL|+qG-s8Vxc) zGQvt^w`o&bZ4}4U;q&$uH_JOnYOG%WN!!z<(&CG_L68Z$tmDN`wwev&DmL} z@o>{TpRfBL{>4xK?EBxF3zuA#jlA96K7M%7xB$SQVxm%VPTGw#7fsL5K?eZpw#IeV z5-H^Net5uYi9$qCCZguZ0CHsj$vLxt^S0iDw!Qb>dmGHRX?yO%HC zrBZUvRX`B5^6*Zjk4T0b8IZpOsOk_`|39ZC-N8ApP6oMmhUj~s)|zwayB-nmu5O26 z3?ZlsTvz0Ci~yj}5Nqx8$B+BAMZh0_`~rl1Fd~>!QEVZA7(>QbSTaUL4Fq!U+FGFJ zrHs>5YgPNWF~&LH^_^Z4Q=IkqP!3e7MUPq}4Bnq^`cjHgsg-uQ+Vn`6b728zoO5oN z#`SuAetBWYFp>zY`gJO4jmaMk?DQmnP(Ggf zv1xr}p63}5eem7~btPD9MG0J>jyTZZ1Qt<^;W$kSHA|%kbE;W$e=aXBMYz;D9tXrF zJ5CFuInN=u4^1Dv#-cyzMfoSYya3m7toeL8M$YRXb77k>Nh`s(W4;jqm)2j6%X z^!zbI#yDlWs)H0ooUzV$0Tcv6GKi(hpML&&xVuF_KxB|oD+nmWV{x(ooS%ii@o)c~ zfBA3!=VV*!NFc8-ABCpxLf`ePzV937)?H{aB8OP!;aJ9TcQ~XP4S}_! z!UcSvwR;~gtFceK$ zo^IA%-;goJS)Jdg(a9L6yJJKHgr!tfU0HAS4-#r(ihvZ6TB@^l)pSo*tJP-Hc&DRj zb#W4)F~&5ZAtG;Ga2|<7*gG$RU;FS$js+3>zO#hKY3jPhSnGZB6`PDjlOtOj5$|ttZw4s zk~+?FDs>T(p|S}>6WS2G4{9Uz-j`Yl(HPS=oeLfTa?azN5P_F3N0r$cBO-0nFiWlM ztQ)3byFd64x~A>B7V`Y&<{E1Le_!4G;N_Qxw{IR?oISpH1b_fiYrVd^%QXXlnq2jH zVHSOQmn|HCCe-RCcnO^0qEeT_tam`nIi@0@qd5Zz&W5wi##)2cY`3?=@i0!qn36T- z^6b<&Q&Ub^HD999xhmt-IgD-+xk}Cn5$+C00a>rtr<+rB=9Aa2j>B<(JbeGf>vwOy zyjX?P&8aZ5h(WqN?524n!r;BLPLqrf(K?U!1D{&Ts$C);JBwvsOnDtSZQR zOPF}?b4q`ibt>SzyYK1>Gf#0wGNlwvF4Ogl*F0ypEL!vhG}b!jwMG*S1Ab2=256hM za#dxf7BPs(0t5ySQ_jW^A^pmCzx(FuO4o$J`%;Q#1|JWDa?SxHr;Msp5UG{*9&+9v z4~J5UH5L(vaZoI&?GOZlA$ zs8H@46SI_BP(O;;w5=wqr&JJ$&@i(lQ)&r5SZ7gC_x;^!RdUv-SLaHDzs)BGNBAcO`MLCV4aQPHU|=vzXU0?MCu z&eh6(xh(FXvM3j%l2tZquJVx-dj{ z!+bnWs;D?QSzVs4&rbSv*Y#c7G{IS;a{9gr&Ie=Y@#)4GQh_#ilt;g z@s^qpQm%81gt+QLu)$f&0zwc=ne(iDg)`)UaU94HDtYUE?3#j>CLT0IV^(oR<4U79wN@ee{-Rnb{eK1m0O=EFsqW!KAhtg?X9=1n3;C`rcWy?)qR` z=e+ZwmRc*LA>X#7XH@0)F0zGp4L}B!4IWd@YVfT^fh5+@dDjYg@0zabtpy}<=&J6e znVVqIIjj5jm?D5z;dQMQ0bjkj(bFL`9tFJj4=+#ec0<#IQx6OfYWnO)e>6RKz?FaX z+uweBy*(TTY(cfJI%!-C&UDzhRHB*u6zU;&K`V_{@0rM_1q$2nPR_PayZHil@w zKXyKxZC2%rpI*HStF}8oIW-0iQOx=3c55tkZIg07S$F-qUw3QgtybkC;;jLM!i<2q zR9*6GA$;}f-Ca~rsySb6V#z6|!i?|bXbhT@rOsdgsX2``9d|d*c?R^}zTX1s-D3<6 zyOLX4OQ|$Y;ZQ5M3 zF^Wy*?cJR*X4SXDG}ls_CJe(tF4d+44x!K;2n25Mah44X|~D%@^w z$W3Qzw{t-h>8@e_O z#{&V1NXeCqDYcR{2w)uLTy(~mOKw5{z&S;g7$Xu0hbDad=?h>$qT^xGc0&LV4Iw&f z6+Nx`UI6sgA^-@KS^;35XKjOwAs?LT#+d~XgEe!+T(UJrL$WlDC*@+yU*<6Yuy>(y zO*yM|i7Nxr2hX0~-0gs+32g*5YQz2c3%c0TEoo&IK2LU&;+=jPUcdH z$a_jzmXhM0k)%nKD&Ev*?Kn)#EXbQ~y+7;)p>G=zsq?fsS&d_~&g|!jD_d)i^V~KK z--ptt!d=^b{qcj{9Jgbf=U7T1Lr))F7=w4?yx$Fa+&#QF*|cFUbr_Sv0AeXqiiNWR z%a+?!qzmn%6G$~%GFHs?!24-BJqhm<_qbN$T+=j7(*xl=4JD@#d?{79lDQZ0A`sGF z$rA+0g^Y#8&V*IC)S?fIr3LG@K3(TIIx@x>VL<=_5*BNm(zR;k-IV|EM}OM>^oPIt zOTXm0)i~$f@sQ~3*K8}gEcl7Zx>4#WQHN7VZY07-u=Rp_B+4%w-1~1-}@&& zup#0&RA!}88(ex`oiXa{$5~&>GIun_IBPvw;cCbr8DUPPs^Jr4!R-kMA_3@T^X>JB2}+f&DfF39Gqj}RBGS! zTwyE|5pUY{*FSjLuGT-eo=x9&I$&WDL)5kX9Oq^7!?g)*+cp;IW_veGQ%t#Ux-YM8 zU)@}k%>MOoZ=ge7Z4Z=32Sw z+7y#hJ~v{F@h}Ylcz$+<1|ELpN#Czju@`(;uTEB7$085THivNr;QjI74LO6CrzdCY z_35hJteSNjR>5z&V352ut0p)@op*iX4M}jOu{4eI?l351qwyhl@4WrS^T$sw&JM>( zouk&;^OF-qY`V5<0wTsa>aI(q>d&j02l|88%GTJ+%d^AbxC~x2q649A+jrZ$T58)i zzwnKZKKk(SzyEjt`mcWH=Z7Md#Te5x4G;j4Gqzv#+wHI)kA&!~K{O%Q#s?$=BBfSq zs1(jwKrQM3n^ix}sg&%UXRa!;)oFFV>hCjNs!Fv>UKDC@f6}#0W1Ry4=R(S9vsxVv z2c)HrQLnQxRs?d))*2#1gehfM1ifgC(IvvtcGrpk+O9fd4UzLf6CjMC&@=*)a@N9` znL`L7kYjSrYgOl*6PC)X2ubGJHo=fxb!|$;AR%E)NxQ#Vt8-SD%{p;{H}-}AF_%nan&3;REa08XrIuXU(C}Z@vWhaU8quiFp#Bz&p{5Br zSAk^>uMYKl`+`_w7#2^622ZKG!+W1|SuROJO=_yl8os8}6z>B7kkR}>iwj&#>rYs( z*N8^NccE=|yM2mL&$U|k-j^w*7Gte<-dVbTwXFzGaRx!%yp~#>rHk{^CbYOz@t|Xp zIVN3UoS&WKoUL<)NKFM?xk>@VIj5qTB80kNvQ|Ut5D<^U)HY2m^=z}sm19iax=r8Y z%Ew_sfYA7-PtFcgnsQAk>s;i?!!twX?l8nT)hYn+_`&IE-(DZ*VNNO6TsRj#O!M7g zOmPy1Rq$l2dj9~>Str7=`S!ERCto>E!#t;2%Qv2$KYIL?ZoTRI6X(L~x3_WH zf>hxO0>;{+dg*&BfsQe1Eu^*`g!e3`RC$_bKn9U@aOb`M5C7Hg{^BqH@;15Mc1sA> zSO!tFjy0CKun4K&#+b}65ebhZpP9RlD|0N5&@T$cmD3bwcqWxyFdQkpNS1bI8D=Lv$jZr zkW1EBM|EGwlG!fH`r6WFy?JteQA#_&tAQ) zsM}m)jU5J^0agIm9d>G@4c<*L>MUM;r7E&0rFiePbElQL z)qnAyzWT|Z|K6Yc(f5D+2{-HCcyj*xKYPKsyt>{mVG4xDF{PZq?8aJ;xrWIvm_S+l ze>zTl?`=nrT6vCzkQlh+T#*>$!>5n_+AsY4?e)#wVSIUgr(0^3R+X6Mq4?nSR%9r+cfPoPh9y>2e_xZAp)0bty9Hj zXo9m&r#sf#aTxFGIYtEKAvTR4^K^E0I*qetRWY*^;RTgkoOPN&eD6$y_g+tZ3oVp< zgp!MM{^Vr6-R{S64k29MjeXzE(sgznrUx?(r6@k#Wag3!DZ=JJFmCscw z0I9D70KD^TrIf5+ol8a_<^n+DFzE6-r9_r;Nr*_6kg*9(sii^{5MxcLC1+9=x=xat zra^#|(&0EDQYqCKN-60?QNcJ!c(>g*-cR$4NWuHU1+AIq2+V{80^O=_`&Al-oKh(~ z&$DhK&Nr*VFsJ$EcK_h~1O(@K+8#$e1ajdg57xCpX3Qy9(qfTn9SoeQr0@t;qT~Pu7#uS`VRcUHrE9LH8&SbCHdk-t22GEbP2TLk*deHmv*g z>Di;cJ6}W$!i9Ox<#>C@cW()Sx;|HYd9&LO+nNj9e-+kUhzJmsy2KCTz5Pi|gSr>X zr37d7de+nOo^zoZV%I8OCamEn=%WCv(8#)D|2PG&Xt@~$ta-Y;aFp3vCM`r zc(3o*3bfg*zw(Xm{PM$18OJ8eKl$Ou-uiES_~Fajo9%9^VV3V7t%g1S`>o%G#{{V~lcrkGN?+exmH(h@Vdm|NZ})Qu^nsw+|dRX5q1F)*i8 z0l#V<8E@OJ$)%_suik&>Da9s)oRWURd5&GDi$E$lm-}dF5m~QRw|86boxZnJ@@9;g za;(b{Q-@*R?stbVwp}k>^X;#H?MFZRly_SIA#0tnQ;Z=j1R|Ljf;WQIR;~N8BqAyh zH~rc>mvS}+<~cdlKRtk&34bFH;& z+n7@DUI5e(QY+UQt+gd<3#EG6s#>HF{4_^cWR|sW+c?jNM96*HPIFwZx~rQzZ2_J0 z0*FM@Fs)a;0SL~=6jRC~IwT_^G9bD{1VrGXASa!oFuACYBMBn`i>!0?o_(g%#awb#kFy8}D6NUe2uS1o z5Tj;~BE}e#wFE+?%+A=#)fn3~%{b3^4{j2Xp%iP~!ax;wyWh3Jr<|ShzG-sKhuwCb zBY}`HJ_H2A+>^0o@w3tW90f##5KAe9sAzFO00!@!+V+%UK}4==4`T%8 z!#Hz^-av0VBtpiR%R-?-5``5`5EkNLI}tFweP4X1G2K zhyC5O-`X_KB~PhzM&)m%s=-?KOt7@-`lb~C4PYQcELB*%bM#k+QYxF!RfCG-5KvH5 z6bS&4B^PN78fRh=NZ9~3*0NNnAk0J_k+|@E7`!ZEYJe*0-q!?reca?P2UOk}!c^BDBUdO;?3KeRmzfY^VIe zx4(1IHg|V-AHRCFz1xlBwA&qoP&+CG2l_!6I$f)bi2Eo?=#)3bMrJ0`-4%~#G=$eL@K4!QoRquFvgsk;H@_T z48W!27-vJYKOA)P#~{p-Qbt40S?!N=u1lJVb0ueMt##IW@4aoCP?-@#FEcH4VoaO$ zIs}h|##&=YxK?3Zh~$)=wZfv)1yy>75S;f$3uHp=P*qzOV^ppCgUd_r!!*x86oQL$ z{NTe6z4!aW;GB)IFbg305LSI-h;%YBPNU9Obw#ajLPFfE)~Y{LM7xN@IRcnk3z1=7 zMo>BfpXXT_dR%HPbwLLJXzeA+e?pw&?40w?YmHxP=C6=CMAkwpl%`#o!o80UApn+2kcqLb#5 zOUn7>tE+`Q2_V9K*DIN%2@Qkfnw!vs5D=;HUX^#X@|;uUvLH=r@!mP_xN;ksR5BrU zZE)6wrmY$n1%QNvh(z8x1gwQa2-Z7Q5dz?xb1Eg3avVodXE~tSm=$rl?t(A_5uuq= z@u5k%9Cn9kn6<&Gf|WVNTryYYX-o)IYDF|xw|8;Q0A$GI$W>Sn4#)ZR-Tv;dBZ7~f zKd3B2tjEJqw+Rm}PS$Pv;`(qnPVeaudZr=4y@Qbu!8)&h-5sZ^yW43RxkRpYiurnf zBPA{I?_`vQXpJd3Psd^0-QL{1-EQyVJZK7}KI8hkP?xhV6iTT&x3k7r=g1lnK|&-W z0+vXFK!SG!RG5)#Em=3{xfDxi4SDCiHP#X$a;+kGyFaGkSV|_v%@DPQHk(aYZCY~3 z0KDYo#KLpR!@GC8-EGM;ilAWUjk8{FQ_b47v{Vn3SqDyi(|GHeuF*DNLCC?9iDa!q zf>H`Ej&&g|*2oZ&{)Dmekmg$1pa>yX(O?e*y<%W#fko6z|K6md_*g|&EOh#N9-@Mn z@{$}6rDT>`OF@PIEGlg=C>8`zSuG&D-8PjhB1*Ni#^zeN)+CT~Wfn463xDJBW$?}G zX->xc<~Kk5A6~p*Vu#LHBOr%ik=r0HFNZF-0H9xWO%sm87*o!Re~E&(waQ|KHo(kt znx~XiwC0Q{b7tk%h>%4PCTnv}C`-JT9{;MnS%R_iVRrxpLHfRWdh+PeqdKMUK70JXl;LNeeUctMK_Vpb)|UIF^1>qK zzmk1HME9q#mMjaG!x+IOSPc+`fkjHGdb}NmX-YY!tUKxVBpPE(F1ZN}YpA4A9U5Gm zuJ87!ToGevn#NLjd4y_3L=PBaB2tQJWoBc|!za&Hr%!S%-Q9!oHO|5eyX$Z+;ny7y*oWUzrMLHIU|~Wy(%duj&0jYjv&59Twq>c)6rFRqWDuw# zQft#R^E{POjm?Bs(Oq+lS<@ZL001BWNkl zm~%NlIoS_KL+G3A+?}4Rq2m59T5Gx1 zu5E6%hrVr3PFC;UU7wzAZgyK1-0gRdA3nI*?lx`r`Q4ka^pwUq5;Rx0cg*m$4?frr z`zhu(*Vm8EA9(NH-QDT%f0)N$op-jdMxc=+J4}NQzVU$!&2f$~zS(Y>t0kQ`;HGcB z`IV=izTV#MhiMuNnkrQX@&?Ho8mBnSlU^PbAm@x^HmiPr7&6CoznSL|VL^B4;6wo1 z5K_)v*B$Rubwy-O(@DR6`rs@HAf2qcV2G~gVLr}Wn58~_aK7rA*SFiSi*FFUATlMcQWF`<{(Si(^xyYOkr51uk0t>=i zML7W#QO!6`(P=1T%(`{$>E+Kp`(z<98Y2L?!Zamnz*}#Ot+6`Ox{YsIXE6lho098s%Hv_0?sn7d?dHq`q_zo&hBQ`= zjEG7TY%ZB-i7-$R1CnTtwQd*{lPQ40kWx{Xu}T6#DgpuspeR(Rh)k6a^Sqg|;ff$j z2$Bc@mQrkCcB1~(dmv?fZ#!m?!iooF1X5o2LVZvY2LK^iV|3Vn2qA=$Wgb)CRYzb` zS*-L###n2)64_cZgAta~vlCfsmuG=3FWgXq#_{s<40<>)O^G2g#Kezyg3Z^!U-U zSFb+Tp3i%)3e2W$wDcaQ$q;Qeo9%8FQ&wF7EPN`l&YYZ`?GF31(=**#DA&nY|MhQt zz2tJbKHuhBK}jXAyUrNvoHa<^JMVnVvsM-NV36gHN>~1c$dr4v6d~4J0LcL8H>1Op zQtK~%<@wFscA&_Ma@`=2=7L#kSu~ieIN#RFwUm?1YK+->e>@yjULXQQMk#$N2vkKP z0OnkBDM;qi7cYP7*Z!qc_!vtPA#36sFE20F{ic-C`H)J{p9ld&Q18z7`h{9+aIP2= zV|n}TUE6gcAeDF910n#+G|kR9MqmMJU5t@qMnk|=>+V{swRCqJ9zVLQweD~4HpZls zy|=?O(L6Itie*lz)C>Z_c_1XBVNN;a2j`~@baxoekfwRR-yL&FXwACoZnirF?E8M0 z=B^9d{XV#mYe^*=q@0sAX4Un>cdn(MpUllAF`O{f5$eEG^bzwX+mY4+RwVH%uq?GQ_@56{*={`9lpd&h3G&;H_PKSmJe+;KRz zO{-H4&6sk=7O9O3$8mJlZTkM*&E56>#u~F(ty0Q>;H}#qk6Om%nhDIsW?fMFCVce# zgFpDe4^y0w@Y&^~pMCk_;`D6V@5g!a&U@#N(?DdNKYaA&?b~1Z=GR}{>^}MOWyz)1 z+O>o+T887rDkU=B5BpHZ}pgyF=UJ}NZaEM1ar*@Qc5<)A%OScC!dc7>CNqx zMrG%m=QPhLz7rsV?LJi&YiPYXNjV{!l=DCT*~f8?XD6Fn%IB|N00QT%$1yXv>&-al zl(KpdkjNRk-EWzTO5V;k=i@Y_oQSY(J8Nh+jDP&+pIx3_Z1?+l+7eO`F-XRk#s_Bm zdb(PYAGtobeE9Ba$a&r$ZV=HryWL(XESAt9!aQdNu*QyQ&bb`M<8OWIgU?d?<)=T= zli_BczWVIcHywZ&qMQ9ZPdUXb0uL`wS8cdH9AeB>*pboOSL^jsiZP_?Noy^aT1xKP zwFtD09|x+nRsrE+4Sn$F^5Ns*)6m0yZ^)`K7YQ|S;XU5fT8j)$qc3nt@nM#xZPJ|P zm~ctH!BWaT;&5}LS+0bXtG18u==|*Uo@+^>Jlayac12_iA%M{tqynAZXGY~*D-i;w zDvp4237e*A*PRcBOuJfFG7Q9A_IciKZ+BPQm=4ZelCeL2@#;^1^m5$qH1(NF6_Hx9 zK{7}>6H>PEy@wD&2>MaHCmoksymh+isFlf}v(8#%7Hg>1!T`C*7bAT3qtEtZwwxEn zkhZ{xWQ=MW7QCb^GE5QSQk51C2xKf10lz0ng8&xcToRzk_qPKf#+-yjY7wc8^Hwwa z^b?nqs{ksfNVssBhWYa3wA@<-hGF>V(dG5k^~qPBdTW@gun2Qb@h~0{scDQgRBF7Z zU7ID>T}S|&RoRQcUxAM5rV{{jsf&q%E8M5RbLE`!dqzjwdO&>r>I(!kWW0Bahus(- zd`=k=KKk(47hk>^=gC;@L`@Y25DTjPQxJsg4tr*S<<*378o#_ge(x_{f9=s_$z@FC zv}@nqTy54H?-$FX{^HH@D_QIc?|atwd6Vzi6na9H%4kTkyf#j6`02|pDs#Kt8e@;gy?(8h5fjz1we@>$~kO0p|Zk%=IuFb51}QT=RzCE;DvSMC{jJz1qF?)}3xnZnk%JZ;Mny3f_;? zxIf(Im=AMAqJ??~ASPI9s?GD3%2v63luI&qRiqxN9O!Kr^t-pNxnieBa zb*>qwv2R0gp*=e*HS?-R#Pz!W^4)cwM*sq;0C0J_&M7}WyI^Kxopnwsi@>Yv>%;Mm ztbcNG>6`9$dutIdHz&q9=9+8SG@)|UXmb`O(7iH_^Kfx;v1z++{oM0UUtHH(A3b(%wJHL^dc&2iHKp=m+=|L}KyVvTJ>02}mhn^Ke|*N*_O@~mIfI|~AwGZV~HE&^l9 z97wH9#| zT4P)+Sx`ivDz(knm=gi&-&M5V_`uAm#IwHP{_@SMPd_@}oIU^Q$De<3x-wPV?d_M5 z`SW*&tKGZSvcz(KbmOAc0#F<*ks1(|$WAr&F)xYchHN#KYliz{ACYPm){eTe2m=C( zXtb;ZwY}*iGDV5ndmvUAXZsls7Q^skjrIwmXE+zZT=^XPX?+)MkDE#oV*E1K@ zb#s-tz+8+|gW$bMOOp{n00mT_sEft-4I&~|mgO;IEgg*ds7lE{`q`)3-H}C507O!X zT7&d`e>fa8wNU3>({UhUxWe_#R{5VH1QrH_7-QQu3;-1`MPV+vWLI>pdmrTpL=-~!E7ilY0=*x(m-lmNjb|XDMR5Sj zB|VSx@BIEB9H)d_-~UE6MV0Q|5qo#sG=}JvMh~vA3l8sh(z?^(+{V4TKC=a=g_ncjl|lpAN%-NIBQ%4<6kew%h$()}Z22 z$j}FmALYy%AnzNeNndZTZ^%$g$vgkqryq;R>3V&3x@m&{`~U9W`5*uH|EHGXEPed> zXAIniCfB+@ZuiH#v-QbGPoH#c-?wckb=|L~IezxyhlG$zLSe1GtuyDFb7w6xG_4<} z`O)P?Ddm^G`E#$X?^cbAx#SoL@X5o6P1kkZ>dl)s56@4y@-WT&;h@?mC5jk=)%x@+ z)Qs~11f93NZ+9`heEl-dBOnMcAOY~R%ZF{(=~3mK6~GX}5B}n3IZehI&7%~NN0+Co z{*=hnDj@`KZOZj0pZ+w)QM=yChf?dqv(vNn#)Kx9Vl8%|4NddKt2eo%Qi`*#aOs=C zTt9sFe4a8Q`=-ZS*T&1EVbjI3Xu5NGEt8jVt>~?poCFwTt$>n*iMnr!2@e8$#ryNs?UE6^` zt;rMq_TT(he(=+mxs)mAa=WW6T=Mz(*_*5Dn4_`_kHfw)TWeG|rxJ&pi(+$_<=L|b ztERcy?Z=c#PTq##!aW9ZDcP;H0Af=~E|+m2fki;dOh{_lZY(w-{J|&t|L%AH*Wdi8 zdl7oxZAE|(kU&I2a5@$9-czl8+dO*s;PV%6xMmO(srSkrB4fPw-dYpdy4$jF*N5Xc z)tuB~rwzvKZn!(%1Vfw6x(s_}&RjikmAdIy$7!l8M7DB4fLhs+5h8GY=GgXqjawb< zw%&(UrCVGo6QBT2wZ@#&ewyyC9zI!p{ATy|%NJiiZ@Y`f$%pwcya)1thz?W9Q0LlO zN-D)!TWT$(5MXd_0crvU=Mix(33L6`U;p-J^T}a%o5;+$K7ROUci5ku+8l>z+?SMV ziF4&z)LYIu7eK4i4n$D)i2hyt%tgr3CN1_fsm1M=$5^3J_y6aA z{7?V>Z~slRo3Ho#S}J*us2us2azX`H;j*o?WNNJ}l?e1SSIx^36(s<&a6SnL5Kvez z?csPB_S?fa8?%Uk05B+3gE@pS&vVl>wbnF8=Nuq#VO1EGn2MoV>%+%SzWO}e9gY@l zPScm~?oKwXx31(8bCM-7hSqJLx9|Sr|K|Vv5B|Y_^zZ%r^S9S;tuZD90BA#~wWgd1 z<^7j_e*xc5jm*-s@)C>m9^{0G!a{~h&H^IB2n1XX`@@urA#{$M4V78-2+rE&_5}0x@y{MV``(}YVVuUl`24enmuIJ|lk4r>JkR4a z5E%w($>i_-&d=Vx`llcMXMgY4e|b)s2q4$PaX35KIBT8LNQr8UamFdwFXt@GNR)Fq zJ6#`!<7TzqACH8vJ#0bb^z@`}y49*{U08MP80Wre$0_Q)ivo=cxt1#R^z?MK>VE#~ zU;XjNpFKEVZ;$)4&H9i3^oNK9h|Fba&o#}t)@A8<6qyrUG=M4Y6V&K{WQ;g+j6V4PC@`Owrf^bcRP{Vc<-Hy zNr2$u?9@1qVE>PQ@_lO@RCxIK^6l+@ceshm^hFS{^S19-EbK!#J8xr5h;+Bxa;ZAB zaKRHI5&6bFfAaL>k3R)uLhAc|dpQ2&i&uv5Fb?acJyfnNL}+|-b9-m4v(8>TI@=HN z-H)!VwW0A`Yuk2f-yRPG8N2FFQYwVt+7?pr#=F*BoSoh6?`q-G%}PK7(YIaBCA8~t zIttizw;2F}b6krJ`1IkU6z9Sfn7Kks>BHyG@7}!m<~P3f^5vJ-(n;S7;XK7!OGQ8s zcy`+O@Z$BG|DUNh zi`gs7&hyqQ<`-Ni8X{<2bS5%tmsNIDjvLAb|nH zw?+^k@l6yM$W0I!uxux>Az89DIFh?uJPedJ-0WhCI=6WS5KbY z0dW98O1YH04JE9f>99c8Ms{b#~xo#HQ;_X%Vm{8P(%aHL4X^ zW3u6tnY$>fJ}%ET27~wE$>~WPn$yk&=Y77Fjw(C&ft1op z#q7dC1QD$?fFM!7bt6NcK3TIBA~Z#cQQi^|W3z?y(oKlcMP(coI?hMV()|4W7U3}~DQP(U{ho2#6>lh1%6g&IR}%9z|LdEx5SU;gUXZ{NLh`_8Sl?OGR47Dq~7*c%(8bv}NU zMbU1X=ME0;KEAJ>eDu%$*+2g;|EIsb?YnK$R%MwN44J*9w8rE!E-{yC{`{z!nPUuy zlxd6kPMl*|h>Xm6sgT(eo35)0)BC{roGigwE6ki24I)xi+QB*J-OhzcWVN>1M(69Y zN+8x2k00M*h9{5i#^?|+`r*?%w|?q#UleBN{ovfWgTwpx@7=h1-B_(4Io~`tn62mvS0fA=hxd6fXpY8le6V(*Pi?2$?<$L?VQgx)4j>$WYe5GcVV+$9`4UlOx-Y~ z#H7`8`+Ljv=JT)Jh=42*T%3&OKQW&I$fT+tAD>Jnbz<4yn+%b=>4;enupUjOGo?|z zc=6o2ZL6xZ#<-AN=*IQjrO*$3Sr%1M9yHDC*IsP5o5O>Hrt1dp5JYR3%&NlH$e^_H zA!=Lp2`A-MP0A8X#^X^n>e}UKI(I28Hyc8H@$&hrFI@WQ{?TWym#C=FS}UcM;^?nk zId5$xzgPY>SUrF7;K{NbT&N23u<>ud{XU`U zylnc$*ir;vzkGgja9)@JNC1r0R8D^Dn?D{l4t7yxCY4H6nXg>D`oI0o58|Wu?k-L=DnuxaY5gz( zv4!3G!NowFUbuL^F7)Gd)4SNU!|o=9843j);tnlnC2m%*p zlhInvV*0}$-*Lq(rkEFdxo(%s3|dis)5Z`(41g%eN~zg=v{`j^S-CLyn0i0dP7!iu zQy6Gs6=MX%m>5|AV~8n<2!bTZ?Kq_{CUU*I_}szC>9%uD zA)Ff(RcWm*G?1}Y*OMT)>O<>dI6Lc>r;E_uxqXt_UO-MdKRG@w$8!*15d_M1BW7{V zWxOaNq!f)d6KjnztIa0ghzK#CFk(m{B?qZ#+5{Z|_$b@6Wz%l<>T1(Pjvb0%X+lcE z5fHUPK!}{Y_hnVduFeB_@B3^S3V@j{!y+uCwGu3>2^=~3^i+Hx%!vUCgQL+nxHgJB zSS@^rBCN6tXm2`SHS23vubN25ZJ#7@8~98#l5QPT-WsNsIKzLEu@%-8`(~pN0FFswY&ZJj-MQ2+kuM}M}ye=FyTV~mUC(i)Sc?)lcMwJOW<&)Fk# zIV@4m-vgwl_uzcIrR*u&QObY-&ejbAv4|m5TBpeQvu&-7F%^Yv+a8ImE!wuxMkCB*Dex}j+RSQBlx>&a-Gw|B$fjMk&dxV{s@Km4ON&ld9N z_#rd&Ax@`L*AJ+SfFL2^u7=1d3GA9(=g!TZJD8oWw=X<@r7#r&R7C+ml~J3fGbZ!m zVN_M|vg}VL%dVS^Cl@A@hpSa>tETOgror{&$*3yqv>LgTtX3!M&Fj}++@Bq6Hk&?q zA{9AZzx={^C2!*>v9Cvj%Iaz{`_P|Jv1gpZ;bieYp;Fx zy^ofwrL3Ahf{jR|zxu_`4K5Ip)~5HK5EGl<{q~y$&<}3jO)(G%bNoxc@TCj;2gBg& zN$rMUl!{{i;qU%&?9K@A_T$qO{oRx0FMavdU;NUSo37`WbWsqg(w2Yk|M`7cZEig} zCZbVUlF}N&FaOL>g(S{`hJp>!TW^xQ!iclkAC^*V0uoNGumeG{`ZgGdH36YIIrw-y8#3On$`O6{1?AG zOs|C)UVM21AXd{qf9K(Qzw!IzjzMrGPs;5XicllxDJ z90-7~UV8o73)hO#T$@6KnA84j^7tEfx|6#gJ8;M2$GBfy`cJ?37tHh$0~f|DmfP{T z{{N0YJUV#<5{`fY@Zn?H8J3v&QVhl#rF0YG=3Dn{3<|9>y0XQ5 zHY(~;kx^P#-jkxLEb7vnHC^vRbV(Z(Lds?l017eW=WfT`CMXI!HYTD#458U_E{w%k zSTmnYj+ZVXz4_7O(`6?hN86?rm31C~=wql5Ns+ZhN(mC@kuBz8=zK9o@^PkkZ=0OXBqC^lYCoQ>F6!Io~7m zJ(Y-*Rxu_-#0;ov(T0t;k^Qef7bW^?6*tBUyO@$J6dZkkosY`5F>YP&>KM2eW8H0?aApa2g;gt%LX3cbpO{Wr-LtUpL|El`Hq} ze4H4DzH@%Kcl1zeHS|O9UKiwp&m^`OlJ{X$me$%B`#=8Hzdl*5s>1$b>9CQr4VU2iAR!n$uCz4c}x^2N`7_HgeYB$-Sm%#w52+L-aAsBNjV7C^1lxVBYQ zE;sFRGawBi$g1lV@Ory-fm4Wo^FRM9uV1_7d^|Z>Jvv(g;TxB({{4USe^VTWzS&VD z6932l-Yeb2qWiv@e8$bvtA*cl#cmI==0!wbe;*IAozy6t*2b>ZSA%p~0Q!?Lg*GKX+ z8__q5*>tSxk?7gEJtG3%2a;5d+|X~?tpTLp?tXJjVSq~29QN6Ssp#dLDGX*-mZ0Ib$zCLBHFPh0{9P#B<| zqMa(EOKXM@#}i%eogm_Jv&<<^0R~p8ELoM-&O|F_X;Uh&Kx4U!&nROAIGK%1eJBZ1 zVr7kUt_uvxB0ha<0|@Z6EG}HWUe$+)5F!lTGZL8+AuCL?cn+3re{kVOC=N?&HQ{8R zH9$SvkSaL&T|k>z;xL&`=a*j+FhlT#E!#dATxVZu4ju|Zp`fa#qy5W@q|jCXnx?yc z{y8Yd*b)fmn}H>2#q?se8MzQ7>9R2AM%Er&tF1YhPDhh+IxD8-fwp>=kA=Lnh1R)s zm%uY3X{`VZAOazp)ixG+z$Qmx+$U$ z)(kO?Bx$7-skFPgpjH}Klt2Q>rS0964un%0)*G#j4^b=C482lXKvIfElQOm)+|X~e z(xh^#fsnu|ib*^R5$;VVz1!^>8CWS51z4CA0qT^J&&ea%MaEnTiBqj$R@U|2d^$Nq zLAR(D})1Jvg6O5$UpsDT<`*mC84m#7v}=F)3yy4L&7y0f=Z) zqzMrSRaKP;&PUe`-E!ORPi-G!=UUuP^C z|H&7xe&?+p6}Iq0*LMve=8|30HACM^l3dLst(e26A7;kb&1qRycJJJ{v_~m{DI%x* zLE5c&cUe49N~ywDRgqcHxw0m}icA(0#*}zhwq~P^Cbjd)#1zsFoR&fotr>&?P-F-` z7wL_)xdfbv|1m}+NDP+LX1xy4x6Rf&|M2nsOp6DW>%B@#Dk!zDC$D z%X62XQ>2eKeakz4VuoGpfMfuGlpOK=U3With469L<-yUY ztPr6XY>d&zfC^*elwx9_m{5@-m4yLH5oIqPv(k!?oO6XSuV1_RWVzJFY}Tu;HC?lb zA#hAat3s>!sMgAO?|bi%kO(737y6ez^TM5nkH>)1$ruQ%wSokg7=%TPHrAM;G?Phr zFq$A~MXE5yD15x$ZWRJIghB{CmLajUUfCCTbSQAms^cB1P;r5qyKvIu=2RBM!0 z#%6y@X|zvi@FAk5qKGlpvl;=sOIR4fUCF^}m69|*Mp2+FD8&GP;#~mFpQ3+DnN@@y z%EqHoSQh1wf->r0I)7kF1?*!it(n&&u-bz%x@f&eAVg)$(iWp~v>$muNSUIn2$GPX zYKGKo+wnvqbMU?%O?=$?6iTZJ$a4_TKpIHL1Vvqjkb=;pn#Fpy?KiNSHNi>ionyyM z60k-${ouk-D#Bvahd#eF1z2esA3EX2oVx0RG?LE776C*pDAuVTtwNF zWwqKi!8>b;i4VyZF}cE6=RE>ny>#jJQP-u1KBmIhm?9DM%M+u}=z8!jlLCMCwd=PR z$#3seqq^(*EQ^eNW0eLmDFej-U%E8EyG3>DPRQ4FVFY~Wm=Nl+cERU4AMbmqDkZq2U1#VQn+I%a@&Vo^CtpGD!Xxnb0H;ehpy6A zX?3ta-ye_8w(Zu3MbkH3Cn2J>WmTob0?0^8nMtL3=n7-{7+uV{D#+(aW&vSI7=@FF zF-9wKgUiL)5TXb`hH)Z>=nJp_Kt+aN*X(B~Rgh7%~@cNBQLz0uW z>y}NH<068#HVH!>@8M1TFi(uYdW*OE0}hd6}(XtPQz&b!*^zzPMG(g9E*ym46Ec;k)tR`AiydvSA?^_`07S^8Q4 zw9=7Tgn?-Hc28-SOd`p{e-~Zy5q7w82qGbPV{K_oZR~;@@!lwP^T%q2z6l&4h{-yyS8J_f^vbK2$}?eg^f|k3kw=eg|<3T&=Gwwf*~`+ zwI-tIeY6D&*JYLc^UpZ=JHs}S)|yZay$itw-)*;x)q35v+awVIM^yy~+USf&smp3M zpB!Ae^tGS;$#*~g^zN;@VF*6rxKhR#qmXIGUSUoo~`=eA`2o! z$00^xiHSiZ`WzHT5FpaI?5ma9-8ayQbGaA5(Vdc9&Q&^IrM`j zAX1yATeocn@}IIOZL#;Iuk)kB*`rv#3!2SK{%a_luyW!#KDx;N+ zHZF1N*czL_6m`vgUr;)KaLz3sT5Ws`0-%u`QVBScE+Twuc(BeMvUWibSDtt&jXgGU1Aesa*05$q?N+ z+1_)Xq{J~{T^2qv0J`N7rdStNL|lkKxHp^r@S{(=Ak1uyNt_5(?OTVbE(#Foy+;s6 z{U`6L;72o>t2i~XoY+9A&>1wTvKJ6IT zTWgW1?K%;TsJ{8uO~iXS*OOw>#+>+Qx?@DNM#l&t#&(b&-#RMBAtliW%!10Sho~O> z$QDHxVo<7Vc&HkqO^KC`6p`)u&{7h6d}g^ z9QhcG(iuIQ1u1)@aoe@M_h-xHWSr{J*n1ZxA(4QvNUiCG!_nXTrJuYbhu{6^{`Y?P zLmyT~D?rkSS;MHc4#_{`B4iK;L2x0)5NCzGXw}}~B^DjSFdA2=H6*ZA)ovEu(b2^s zwbS|Ik3O|1Klke8>o=}nzW%wSii11b&H9wnI#a0yAp1J4Ed|j#UzN5fY-J4+Au7~H zSUlrqd1{Se;i|NSJ-2Q*F{HNdC-r!2HHZ?CjYBt;2?q0CAC~_G| zE0xjuA_x+n!Id+N4-ipNOo>AhV1Qie!Hk&9#hI9R+jN^|Ny4M~d^X*mox4zy(L}1* ztTwAvaKmzOB#F2E1`!abE^8lr4&`!ULMp0}vgMb)@|9ot*)ROYZ~e}<-ufuTRM%CE zv8u|!IV6aQtu}Fo+7JL%*6hvqX4QCb-bIN%AR#0WiGV7E5K|(h67Y@&C73v|z-Uyx zdi`?W4mTej4L$(Kcr-TFGE3m7)$XGeVkE+lqER|;S-tn4fBkcBefaKs@4st|2}92* zDk27$O(xb9MNtMHfB{Jp>G5c+%IYuv{J-<{uZGRhqkr<7zx9I;KWW;2J`6ER(+^hV zZ>Qen@&%aLR^`>p7Z1kO(PF!4ySy{zB%D%Y2~Q>4F~*o6u?RrqBteQoUw`4bgM&kh zIKOqjHpTIJQnSNp& zz(NK=kaTb`zkc!D1gyv-+x!@l2gnAcCD!2G;U}NNog%2bwjU+KD>ETJv_}XFKY_{z`&4PO0g^~ zA`H&^Bp=^7y0!R|l+u-hy$7cYK+*^WM3>lVQyAU5fdNmBmf!fZ?*S4BE2U9HDJ|P4 zfKXWtUfb`CRqPO1rWOUG3MFKGRB+PYb zb^FLmG+H51WEojHI_*w|cMx{(1q3w4q;?URXI0H2E`-Q@w(j44{~bi)7+KiIsF1po z4N7?R`OA-1>(lj`MHUADrK`+ikby?gUa)#%cxLGXre5gZH;n;vu-g z+Qc#))zF`EN}AA+?m%LS>+P!4r+o2fRaH#jMgDU79K+CmZwAKV+=1|d#Q1*Yqt=QhixoXUFgI8>GS&srW^x`F&0pA zASk1}m6|9d$v96IW)@C~gF@nzT;d_bb<+(#woUI`&oPLk$f?k(EQ=vVLpUl%pL}{R z#PsUL`i+-g`uU%H#aw!^esj(3`WQ|$B+Ow#1|rCkX;hR^1lf*?h=~~y3v2WCeNAv~Fz4Mny)dlE67!IbB)_Fl)fTV0qdWz4>dW_%$ z3KC*n7RYI2OPcMOYQJlny;-H|(J(~cw=VM8;|Is9?aAtto7Iiy_rw&+6uPil6=hLu zAY&Py($W$0Ix^QjU5JrWX|&aL@8Gbg#{<|8Ke~Ok+Hwl@xEPfqBy~8Ob4+nMPn<#s zDX|EI6f-d(pd{xN)tivop$lFnbvddhM(gx+h`Wo(Wpda~j14T=7Ah%mib-~*%jtoa@pSF{C?p@0F#o%CxRcA}lhhCPXTeKZ&sE zS~7NjZ(mn+*N4x3?u}pk>UI;tkKVt1`S~lWlj9+#p&!QMvC(P>yU}ilqD#7Z@sifm z56=6<%t$KNknkzj!WhHMhK%#A0QAB8J_*Q``Jpz&-rSg@)4>M@Y1?)_oiYm{4bGLe zh>`>VK?7nI;N(m2`yYRlm*;M9C@d0v4CAUE)sw^^BFgC8P6;Uiq0u@5lAX}Og|B_} zs~_HfNJ{_87hd`o-}?T1JVtB$3)WnGk!laHxQ zJeiDGk^tpTBLbeSy2bIMh;?ZS-$dbL%d#>GSx_LcAv7*5PS1d}wZ-oA=KUlLB%Bh2 z7>7QJ$Pm)Q<7GYN+SW1hz3y&`sVwT)Zwp0pTWwsglybp;^5k?p5l)goRv{wN;uM?3 zsnV*jIwR#-_~!lNb5V!LAV^99i&18Ea%_l9h60lUPRn+{lSjssL*Ec!5=KKPWGIlesN2~4f=&XssJy|RvI4J87*+=dJd*wj@e9%V6#6%<@Rw+c( zWJ2@|km2Dh5@JBY7!na~+b$)JF^CA~3k-`x8jmX}jnb+rC*1>yug|5VbDE6d@BfG^LbCQSixVFsLW>#F#>nav^A? z4#s0p$|yY8KX*7kH1+(g`|IUm;e!7QSNAXf^w0kA&dS}r*}5Sgwn7SsP#9Yv?oIH> zbu4_^xC7U7G$N2f3|bIDlg@;%9jqdyjL3cVJ5H;V%;SA z=`Vcg?%hYnN5`AZMg*)iJ~(ZZ2_{dK&s{k8;-!mPo7Hxk*Qh)2w=ieH3sK~lqej!w zcpam2y${ZXgakQhwQ9B@rrZJsfVOQ78Dn$`F+{FPYpqpEg_t%?w<9nUX<`?gNE($E zQ2}VBs=Qd`7=sVG%(xGBzK=d_7R$$r#r|~98Vg1F<<~#+TYvn$|Lb?ZQ&~HyP1Cm4 zTAQNg6jCZ?lh-t3 z1_6vdapLob=i8`Pb=~RW7(h48h6szQ7&eYXVxr8IyT zr8ueYy?^s?z9wVpVhji@sT-VgJxNk%Y@xkRTGNA*rBAnoj8bZBtL4zflu`(oqB7;U zu7)8D&bQ9p{PdPGV`GbHIa;)vaW(1VM`_p=l{uJ?yWaKQg&6PNyO)&FrXbqk@oon0 zo3lw_OQqPD?Eswk;|C9_vyC!LnhEQ0rlaCCa6R_okX%y*s;0;e>pr>MYc)gdCn~7X6fd7Pd-tN>S8jg5LF*SOfhjfU9X8YxHF4L7I0OCRS3ptLLwv< zUT#)ewVT!Q(aFi+hdfDE1lAU7H!RzsC>z7Pdu6)t)QhTsSt-&=$ETKy6eBVNf=`i| zNgyQwz)?AJvB80e$QG7e=$#+MP>kxwXWNsLlN5bO!4T|^ZCw^2ctIA}NmCND0QeYk z1jPG*!a%CowmycJo;!E>>a{M|Pi{SEmXEA4RW(J0F2sJl6lQDfd^%gLSI&DEm=G(g zhY*}k>(%;je^PqG!ZC)3EOo90Q4)^AnLrMTasyZtMITj)wY9Z^a#TzXuf;y)mQ@mL zUF;GsA3fQe-A*R_BNH(Y6~Ri&7XPpKi8V(@W2t z|6maw{P5c$cI*fCz1AdzpFg~y#y|19pB~5N%-T$Pfsm3`eq`<5WU_3g5Z9W>YRwUd z5J9X`wJiWC>!Fne%mekOVMc51Qy{-e3|47S3Q$OCkOZ=;{6rSv@$bF$ z-fS{6WD9Gy>(2XVwKb+Vym0>W*I%d*K0ZB(49@`i;psI|m~BA{RR%Fm#^cCIIOf+k zBp}4HG|}1IB`?cDD`mB@)`Ea33jrXdLW=9ASERbZO(zr0vf8YN7yuw9zwOKC&z&ob zanU>Pm9kptvM9U{2#}a7ZDNcHWI7)8L*EaM1t`TN?%~7J8&_ZIdY64X6NOb#&iChg zv+-;?IomW{ANqb!N^4_ch)1km;)2w7{?Y6Q+&<(BRca_#zDw!`v#@g9DzVN}#ca8zBT)23Ac4oOi z#ImT5&K8PrTGcOIzwx8(kISk8fx4)zu}bwEgHMSBw4zy+7YAgG(MFY3xj(O+4{hhG zx+u#U1;=B1ZZ=tLn^iLeABd=|i%W-dN^pF1+7G^Inum995>gH$vgGv>gUGZj>aysZ z>z!M!mTl9Z(m4qPz#tN0Af#HG$*AgG@S$_ge|q}^A`Ku2ghaxLnHjh$%&01ip>-?0 z3m@OPsT5%@rxWhd5S;3&ER<5#_AZFP@#18$I(w@B!w}+qLL!{hr7{XZu}J6K(a9qs zr4$N-Lddq-#B7YNt+v{9ejp;}`qPt#Pf<8IWh+Ej7@Ci(m>4kvNISUW#Um7~tckhN zg%FdFQdMc{vfT2}I7lfyIX%jp@>8M^G@bW9oA29)LupY(tfu%FDJqJJomNqzMXe$> zt-ZCx-c=*^-Z5$fv5KO0Tf|Hh6}8*i)ZY8a_lGC{LGJs0UDtV?*ZVvUCJQ+QD~njZ z9yPH`+gc+g7vL_H0-RMP>OL5Ov(_*o-Y0E4T0AGHR_0jl0)3lBYYD@W`bei%Ge%2- z-QsE$V*Rgkn3}S!f@M6o&4oyl#Nf3h4^XU3!vk-Xs76IY8_Xi9hRNr+L*eyUflAJ{ z;ZhEbfp980kJYA0#+(121%U4v>N3>U31+0~&}557??Du4Py74xH57+FTbD2+8G&(v z?t9Q5)d4ri6;aQVFlI1vG8&f%P(U<_JC+>nd&9rTQiAP$K>`mKao=0wK2qGDg^Wef zC05q+$VODt+Tw^aF?4W@oSe5LmmTdb@y2@2?U+x{hWG7529=!45qlJ*g-o1_I#K08 zlwke3s!<&}Su{bd^*{B!8_DF+fta({C8`un3c|Ib$^A95hVim0Jq zcX-_3+WLPMcXk$?p8-O}9^vivc!2(PpP#1&T;EVG_lDFe3|ya|NW3>mSH?JKRyfMd z>&ij83k5^9X?81TMb12qRt;~x27N%`xPfHl0o7s(29G!^9;?)^&E*y~Y&TLB zH&82)1C<4Dez~;1SG$%@AGLR3ka_Cwt(E;Y;0E1mvphNOds2asSNx7CmG4b z?~^po`45E^ZB&wofJAsKF*MUs5EZhUWhHkbqwby}s6i(LNS4UVO`fR2$e^qyW-q`G z?1Od4x|2)@Z)dza_p1?H>nkE=wK!S7gMv@2+8QpCcg&f5SJwLjnoZM`p`3B)6?g_y z^^aT}IW)RslDTXKIT$?P;QJH_{&w2F?8?Nnz0DQ$CvG@!_w?agQV2)mZsZ)zC8{0RaIAze>we$&EDy3=_J`qdzLgP8HOH2O8P9%=|`MOSdxxERz|OR9HkkUTWfA}ug24z z%1cRb!&GJ~$bb@Jb;9%n>r2d+5YpQNED*8V0&t}Q7HT#1R}U4mCvQKbnjA>v0>p(; z-Cg!~nLkhU;C^-h4NU~AL#ztllRyi&qAC9xs#i&hH>f73F;rs7s$`ncqk`g9_7sfT z0eTk3=TJBbVwF;hTve-3(1tT^C&!T|CUaX_&;p*bDp@!1Gdu$(bt|GmzD8BP0(|;! zrdS6Y%Uv=8_zs4-Vl%I25-5{-ZAaktdJfFuFKk1F{^J9KOmZYcjUAj=LKu^}!%z`= za{~7Zh^a*uv6?A@5=K=oN*p4;l0P3|Adg`lU`X2MDW(97wWze-gODlq&2uCgvsv#$NuV*5I&fhC62W+?t&PBh?PZ9&Ls z^Hzca&rKjSy!qYI`t|8%&h9^Yolc6V=Nk$6LM!q?$EBSY<6Q0D@F7H zQ3B)0U!cd8(c62q_$oQ^_7CFf6l-JIT{3yn-AKjwr++P;q+yDp-G5!J#}}fDrJM_2 zh18PZz@*KcYw<(=+7{Qfz=^R+lBQ?F%YSNmyo$s~{l}iu4K4p&$8w8NS%5}Nkro91 z3V8o4I;=a4+As;H{-cfq#q%-6=!HS>(-W3iE_pc{1W7ymvDKsOnT<8FJE4FU0>|h zuZ-NO7lNIbI^IWtu(Ob&S;GDhRGI#U1SN(#irfp8X^K21>a}a|s z$S$Y43l0XdXg9jfN);Ug)Zj(O>O+kdQdB?y?}khy6tlPMxZ!$GZ^hZ}O}zIvaDJj% z%(>%g`)aathwEbU`fT_*oSrjqX4{)4ThV!=v5tj_tF#uI4STLgo)&a4cl!(JzM=Vg zefZKlxFbJe6Hixl`K>jfaX3G*hrMOrh3hRmOPIFQ# zW=PHKKmV!@>jk}a%lQ_`4iYpm607iX%RMS=dHf{z1F5Upi|p(EJndT1;;?b_i%VCN zetUL)D?Y?QmR2ih#Uxl2d$pGE5ZA~5(XeYlLa3!@9FHGcG2nUbBrM*uxY0tXs=D|3 z`bn@bq4!b8-e`jSg>&?7%@_Qmi*M2`nDc-AMKP|s`UE*UCFTG_k6aXaQvG-ks7{6I zT~SI|1arF<-@fViR@$w*yhp7RGy#YdwZ;(TW1_sp`NVeAhfiKh# zN7su}C{!VnkzAoXc}Tr+w>;&Bib_dIrifH`0zu|gmKFRfcz=qn9VPb4WE$gMg)E|n zEe#;XWXVEp*!dze8EP9?E2bBcDzIq9^3P<7tal(!XXilt{J(@8?PfUwbeqxQfV5W4 zK2^O)w^-Ptbs8Y6=eVScd~9f}0H+*`@^zXO4sN zlms0SGHs?G-{e9rIqM>@erO!JTa;Z1xsyOHCs& zU@02j>_re`vSj3e+YS_J#F9scr2T=w5uy?3@^p=-!<-D2lGxw6b?R!XLNO>wqW{~z zG>B9!=y@GZRD&n|KqKl4@>J!S>QZr?n9$Ku>KK(8RoK8#UnMMKQ0gO}LX`F|YVfEY zUN!ZF8=)}yvp__;r$&`;V>m3FF>we+|LX$(Ht2KkUQ+%I02=K&*PbUA7*r+3qoYYi zrW23*1zMOtC*~~JC9u(X>TV|>hn{^tTTbX8xh&1ho(59*l4~mp06ti9UtUG#5ApES zml4RWuC_1UOnxcEG!7AEY%2iHmG%P=X1V8@lScLS4>dlu8LnHDG4CxR)3_gOtOv2h zBlALouMQlK|8=b@rH1uILOfV1kiq--Qm%_Dle_$~ZQjz6%?^T;qp5?71?nKw&VIS$ zyV^!s8WM@S)si=Ci+)0nc(nETtLAp08AfZmnD#RC!7#^t0Xk%MZa9 z75jgig7&4q|F|2bYT~^wE49f8gm<53q3VjKBnut#_%kXxFYxsJ`lTA@BPlNi$5LLO zH(Z~OabNG|pPlW`#zzBSE7dNvqarr}*~@FowkIpw0on!)d=x+>!=p_?GehW1e8C{( zOJ+3_IqUt8p4Dbmja_8fTk~gUT$kSx<}O$Ji3Qko(PN&{&8z3iagtntdv36rC{+Dc z)!Xa#`jmP^Yo+F+fJ{YEp0mxZGp|4NU!!3PHk-1?v9h%1U)ufFzI8=IFJiFAuQNw(O-Vt&S{BOwTxZbC*5`G z2JS9Bfvs=_x?e7?HIj)^RW1|=<>BtY_M57!8)tgK^tAA^j&=Vt; zbxb*1Zs^2NdfcL^(Zu;=tx=<}F;a%};mQC}eu=|M%}A;t=i*3xFMppeA{~zuHX1&3yoX)8K(L z-5)lRDYD4?#fs9;TXga0&sKO87uu?&W3F#A9dGhtQbqW+0D(%}Ve*r(hn(R15Diw;>6J z3zZL{HL1znGYG^$RASwtJEt+m2;vY4--3~q|L%{;!Glg z=7WV*ToU?Djz#w5R1Ik+BXFatX-tBBkPi`~5-}or$~;}Yp3+CFtoEO(PC+qf$T+8~P7XSdoTi>a#k0;fJ@&g93ZgS9Xs#G|{=sKP38Sald@C zbNs$Vlv;>I=tfs#5#iLi;i>NGmQ}EIGKOeDhVozOWs9Bv*XFLeEckXn!V{Zp05_B;axi2d#&(SV#=`g{-azK+RE1q0m4G1~+4FyTL zDCJclt(_3DJmro&T=y;SO{e$PDc&r?>nHLPgpUFgKM{OBarI!OvSI^tV`w4gZQ!+umiINj z=HhQFSAZ=3eP))u{2jnMnF9zGd)Bq(FYo8nUgl&KCG(OoM2~|Qp>-F(G-;%^`wp}W zI{~FuBE420tYDYctvzS90xp{0UWA_i>w4RHN+%BKlT8?OogBUaxSFG%3+`xbbXKCZ zTCdRRxSs92?6ajuRKaen&c+OS%lRDt+Ga>ftW$x#Nyls0V1rhJSMo2p5N1y%qQF?W z;ES#4?T%woq~+i2;ppU(DgA5_ec=O$VS(a4Gvd|?3O7kp9d zPD2>-IR5L=#Ll{Dnfbi2x;lGPCW}NY_e)WBo~(yBr&p{@S754_K><4iV>o$_(08>Q z{4)LZ(C~lf?P0#&GvA-=^e?=y8LFm%;`R^w$8t9I(3Io&{x#9_rn%tl2b~Au(C&9_ z5tsPm`Rg66s{?~;9Nvq@4Qc5eIInjH0BVHwcym6D=c#MRZ^hEwo`M~hM0%6(AX+tC zPlNd_I@!`{j#m( zj{t8b!x&I;&&1MVRL_EZF1KFNBwE4?Kgw5U45lotpZRc{zeiOzn3*KhznE6$QlurV zW_-Tr(tMxO60X3VXA{ECOX^&}Br}_DOeWmk?p}YC3>C&DJTsr(Qv@{15;(tRW21w> zjR><=W2K#y7*D!y_ngqWQs7CaENwPj3bHI4q*fmnD@DsJDNp0aR!yJc zJ4`+=$b_%5o80Ttm`MJ^U}@4^vH8sq{1q`#BBa8sR2G~29qq0kj)N&bKDumf@LU@3 zUX?k*fd*}>-mRV^#^T2kbxGEnm(@T-i{T?nLf394(p-r3+bsiwkryM)u9_QIRu;UD z0U~`yL~{AFv5-|f53a5j`>@rhs=0h=eXp1KYC*U zJQUm~DV;mW&fV#^VEbrj@0X!+ld8LrqEHK6oD`fFf}axy7Glu#*4AggCw*4_RomKU z4@71v2hjRFROluxB>i~&^zcRxBR5nQhYq zT0SjwLZ(mlE)}xleCdiR99haMT0HcAi5hF!V+T+q+?xVCO~WQr(5kiZsXCK@fPFON zfz9CJ3-|z-?~ZHL`HYhR{CTptg|CN}+Dm9!F3UYlSS?gA6cA=uYqOC|uVRWw zr$&@Wrm@Kje2zJaNRRaHpf=zNmX-9JMIfGPAk$4rt0=|SAu7=!WPe3eG*3scZ#g+K zTY4j9GiYUDge}8;C^;6IO-X$xhnX>*S#u!G(_2f+YkGFLZ8xoR@A@evB1TU#F0|28 z@;`q;s5FJGv2g2B;XVnysp4Sa!Y|A5LMN6XP>l>Pq4mN2dh1s5MQUw%MWW#CKQg7; za_4#p1}Fg<>0XD){~m42#%6hqv|fp`exz`0mLUpUF ze2+rAWD~sc?xuC0AiTSqnAsn>TBPK2JXuYD3oO(lE)^Qqe?E}K$iQt2*>pijJ$KiH zDJ2<$p}>33!M+yK+=Xb~ImNosn9br;*|r8LTWHNw9}=9h-hu;-9FvWixr(Fl`xoeT z9^1RI>b#lV=qi7Du&}vxx^t2;9JHk6Y%Lw3ZQ#jD4L!ItL^OQYcJ3duXnnU*?fP(V zdNV#MRh31AWWyw~v$VGaZCTMmF=%N*nE*Hf)Y52DL+~2r++DufC^IvO%ydr|aG;qZ zP57KFw$F>>V!vfH#`2-#Tk-wOscB8Ie~2 zL63a5hN&b}nnz$WcN3-jU96c_Q)O3$FDg*SxNduQD(S6;3 zGSa(5c@iKICXcflmY4kP3hgWJKt)(%n2`%pn-(v^E*EtNtT~|f_YQ;Xei7y#Ww4WH zUSuj$=;>wRy9Up@KynucW05O44teGz7~0XV`F0XrWlT%rA#gKd4{pmvj@4Z7@C{lS zq<`((F?~hYzT_-p9HkGw&XqqLlTUN!?CnpK92%4DMc-liE^OH9)mR1~;|}{Rc$`ur z2lzqH`C5K@uIyO-r&mnkN2G1DVPqd3HO)w}uW*`4YMxx=>_*ng*16!>l z-%+8MpBtj-_quZfMF{UFdCo_gTE~G2`vGnv&6ufex*9p3!-d|2^q3SSdBGvrtJ&&@ zPE#$Mmxkk2p%$7>cED$3%0AKqj=pq&ULGNXyM@VC_IGdFUNv3sOvneG{j2ZQN<=rH z!v&p23XVT+I8tO|k_00M;+!zQbBN>$6T*X=ABReitYZ3wLN)u4GN>5gGrA`U9Ww@j9+Qjv>e; zdRq4*JfY-i0RlmE^a75YwiHSVeN;==Z+|83eoL{Tg51Izsdc*&j@~&or#PPOCw8TZCl`Lfc4KH4 zB1!JVfjr8eAIdURc*b%swn3rI$P<3zJb(Y|+v}6vlRv$;mj^vf8eDc9;@<-+`J6b! zC(_JB^ud1U7j}n>TkE0UPd^yc3E+Mc%?4=b0uKycY~}~XW>2`B@0}f7_Ff#U_tyk( z=R$ag`o+k!lP^~NCcbR_SzdhTt>rxZH0XeqieY4h8{5#34hyrN1X+2R=LMYgcRhb( ze%%kl8E6_HZ6>(^-I?#Xdz@)oahke-AKxM?az2#7zaHn)JD+@Z64A=&g7N}w(}l_e zvR{4~WB?`!V3=P%xfiD>Aw-436+Fx3eYpcDK*`w*6=EwIIe8;QA5!tmo{=-$Aveu4 z4Uh@^*M5sP1Y9+n zvyb&8G6zV3L|!z5iW+c+atD7%9l+yZ&AQdycL&f@5ZM9Ybj`1J3;kc|T1oa?}5r%bosZm)|9sKS>6cv((YM=6;8f+a3Su z3PL6s&D&+4w9j!yKeQcj99XliJ&T$!za+j5Zgsci=;^%v(0S2xb@gETdgsUS{K-Vn z*$Xb&oYEUWvH~c7u|3?KKr~i`g%yBtsTkTaEHX_CszEB4&b_rrn1R(h>|BNT)4hYm z<8IY9?w9x_|B zp^`_v^OuC+C+7?oj?I>~yp~~TF&+^At9OJ37ZU^>LudkFa(|yCG{~d9eeyqd_3oL+ zt^ZiZm^thkvI`k3CO+36$23xQZ(cDV=eFWur9zVoy}#J4h%rkkFNSFZN}R?;Uvv2* z9IzM}zT@-z>~ot5Ie5XIi<8NH(1K_@p~Y&x0t@vzLdt6>$6KRx2loF>W1jOGj9+U1 z>QjT)ALBqy6{+IvSNQEt)xO@KN>5q zdHmdn?D2H$J}-DdLNy(JLI7~c}m1Q zsG-b8CT5d`09A-1q2$5yA>0?<)5BXCB-kkjAlaJC27}g3<{<61Y+{0bo+N2ZHiO>5 zx}Sk`e3qW|>I44JWNuyVzodsiK>5^}mb5((WVY4|%N%VnI|cDR05lM7fyH}Ydovjs zi$PCySo>j6w*f`0*@Tf(>2K-5LpKf_Gz2SoQvui?sQ{0U%~)MgNw2JhlnOB@)#1WG z%iq`=Rlbz9>ioSGVlyG+bR6)c`z`_0Z&`(3QlTs;RQQd46^^cpmeN?F>7e;so_#55 z+n;=&UCDW>g|S~_mO{l^IPn#wRHHK|%X@}Q5KtwnzrX^a0TIO76DYT&{6*<>{|2vd zz$vxE(0r%A7Sz?{PuB-q9ZZ$4tLV=!Q-XDd4IE<^V`1|~`P~8lZG?Uu74qBoy{?=d za4{_)rtx-RWcl?@e~RR<9!JmX3y;a{%iRJn5rmJTZpB2wCJ;=DWoEg2H^}epZ#~Gr z*t|Y&Vx5yl98P_Ryk)LFh6gD*?JWKcyPibC}>Tla_(76KFiic-!w(G}Ruz+VZyVqA*0U~-^S95OwNx#`XkQ;M(}3 zv<+V~Nx&3+pqaF)cw!p!6o%zJraC_I@_5c~zvLD@*G%*I;wfSmnRfCYBiPL8K?wZX?9Li|8%pNRIgp5f@5;W!>+N(oKe@Zma*S_JhjK)0%szTEK z>BKgzS7BU}mpM`zq%ej%kq|z9DY&!Y`*Vi_lGe!!4${TCgqQU?yb*(xkl3~vV6_Pe zazRMFq*0x{E0+J|)_E;fP+NViky1w8%4|F$3$+n1IO3|GN)gAb2we!t@ zD2Wix?l=pd2->(MFX0?O8v*J4hmL{pC`6YB_?j&VO{R{zap(^&$;1)axB?J}bE`*2 z1g(i6O;3|{54Wq`l$A?~jD{2oW=gL6W$7nRJIl_ND#v7I+uP)Q69neYNgXpx$DHfN zfN-{}Jm($K2T*f#PX6C|FSI)m>AKNUr%5)A!Gm>oaEVqXKAMyS0|OTJt;j#t?JaYM zRSQ^mIk=)Ijva$#ASf-A`8%xKH z=ZNFL{Lxqijal`e>RgkW4C(U@L*rgwA*MI_{aBl?+KnH((Rw=3REqYf#J;dqmLH8SGC{&GhIWgtA>tPXrJ*E1{i0`+u@_#e?cz6A=e~L3&gkrID>f%# zGUnbSC{FaT7t9793O@;5<4u&bBkpC6^WIZN?m(WC{nA`m*wjDoa##|XSXmXcY)p?V zl0WjVlZ~xk&P4v}g~qgbYzHl2Cx-BMxrKq<<8gK*H}0F zdH8GvZ?AzaEjSdyskzYkaYpABmFTCmMQZ$T#3q(#Y%X(N|2k;1ycEQ*FmtDu_dP?L zWQo}0lFv`#HwRp|OfN1z^l+Vo%jdo^Q}sw=DOowc`q3D?u^q6oGaZaK+FH@prWsoO z#p+jw`|O1j0p%#uX*S2H9az1;5n&N8pK^k+Yv~#*ylTp?4d@e4!1qtc~ZMayWV z6&lXF>>Onk-7UpezU~V0n%)#QXnIhA|JRPyBUZEK3aUR+30jb)iV)MhjMtE7k{^wr?k%Mgx%eg zQoF&l;k~`wF;W+CEdP2cWA5}|EoDV3yT##QWcS47dq8veIS@k!dH9{Ek^)d^NWv${Wl_3td8pQs8!_6* zjjg=hUm;jjOVF#{IyXm96gwxuJtsvhHIqv!IitAkENtOa5cWp7@X;Z@uZM-3cKN!@ zEa1Tcn(QLLd%;gUj-HPD^aDic*@(Z6oR(0sY6 zPpHa>*}Qs_sY{5sQ@6Ws9}D@)%I|#F?pp#>o$3uOQxZLAQp|D5>Y{tp^rvSCBTwto ztx3#=R2UVur-vjiQ>IG*0EW^(dCc%RC8J-7_VhW2Xj?{)rSjP&Rk-avzZ5*8N~(%Ws|urNG(t$oZMwj4Q~yb;G?~iIVgKrPd{mb^FbIZ1ab1P~$ z;CMcEe1ZVVpvyiS7z@qG;OdAA+3Q#ptRia3rLrkn)%a(c(-fo|q-bIwx8%U4eQ4cY zhq&*4&K?CLQoazLOTourI2ak^t!rl+{E&R%a?(Mq{lv28_F~*8L*JOgd`5=nK=~ zL%dr?at7LU!>CEGXm~7qz4U5LHeHX0T(&5Qr!D0dHdYzFTnKD-+;e{o0jKR7`%*eO{DMNe_hLJE!AbsXb-m`Q z=$?5f2fecty<)r@qvHn+{Au<0z% z;f|#gEj?)W?-R6LUG|$Irh1ku9%kosy0sR?Ez)wddq_%{J61^efU&vHFs&JP z6Y}J8b+)D)NA%=G&KJJ*8tH{D^M+!r4c(=PiY=F)%WdIU^ga(riSM@MFMuM|6|2Ns z$VsB2kPLGwBb*1gJHl=$HS^hX2S^3MC|3857U+>`FEXBPka?^3wqvXEvISb_z-C&1 z)tSik8Pdg5}x3Rz&J#g(cSTM$yF|OkWw#ntSWc9 zRY+P+_xn>;PC`jW`bM6`ZVszhC_`;MA~PXb(f379DlkRT3vF(1t9QG?sn)&~(>}F% z2lqL?vF6wLLQakK zl_XAd9~zg+*su^kq4@--m1j~j8U(MN( zq7`Et+h~#F*15?SE=|B6mqFJ7@)V<_EMKNKSIEFWrF2sxcB?wva;hE>k&A?29MELn z-X&KK6~D>-cq_y1!*H)fbpL!F8)8jgFql2Mk@#*_RNP)*W%;kEB&}RY*;wZpO)xOC z{i#`+yp#sAu1v~o|E2t4Plox~sPj{2havrW7$4_Lf6?pFLrNmC$t*|QUh$0&?RA= zw!nB$g`w@mg3!K69NzFRcOB5SBMU3Hz(_JdERei7rQn!(RtA`*y zFB>1}Wz-pTO-`N9bvAp&p!g;5HtLKa3Iue8{VIU+DT2SF>pj!s5U*^ls@8hRBr{5UMXH$gHLM(JCY+Ul?ilCioaXVLe#Cd%*}DBHBA!$?&ObOIn9K#msp$a z>TRE2{Hfo4vK?3nV}Un_OTD!Hn;B5v!fwUTU|2;f&X`xN6>xydEVL1l&lhtt_87c% zyv4yUf9ny9DSeQx47;eVPDJpK)U($81&Vz*HVVTUeeXwvEi=-|+Vj{08B}LplOEGz zOYRgahzhmOTP_c{pEUyNQtrUhhIH#O-w%H=(twyILNTx*6sWKUy&%?f%RYCo5TXp= z{hMhSYe7ru;>Ny&GKdv)xL+^*?s5(8;{kO+pCh2wXrznD{g32f4E6Q{labo6X(EF4 znZz1VA5=MDKGlARQh#Fq1|LXap}eZ!!9QYAePOMi6ODk1IF*rUxm*@fK(! z2%vbL_8*_q|0V0yM!knOJNzbQv9h0;yB@9K$4bkC38Ka)Q*D^nlUaQ2rhMyj`7*xo!_j9)z}`< zZ{d#*UUYhG4+mVn4n94snQK1YS&Dh$<=fFNcTsvh*?Bz59{jK3b5y^`_% z{@j$YTcs;28~YPmd9P>uAznG#TYt{C19uKaO2p1hWznxvsk@MSo(Zs3#VI6B1RI&~+ zgzB60P%Mp5;`yme+RK;bg=i>=Z)%3{~86H9u98He{(3Y z1V!B)sXd2@FjFBTqa=S;?%%(5=D`*pj?$ZJh>&@CQ^76{>Xp6n9j6bp6I2ie+W=Hx zPwZY=SH`kMmlR999_0UR+c^kZx-0k?0Ck3|y~_R0;Z6t$y0Qy8WtT^8o0~LEOmDnC z$InYS=y1u+ak_d%3QZaoktZW*qsrR$Q7FL`OR8>ONUwm#SSqy^0b-p1a2Z2Ug@{h# z9XA^(?Gb+KXN@6c@0|3 z;A+$9z!*$x3zjx5xP8AI-)E-zkCrAv10LZZU?Xb<0$?Bk@gug&fx&HoL97fs+}tt- zJs z2C@+&_99lCMl5h7wXFus>`ws}Bm=W`ftz9q>tr9E#Dkc`%V~h1Wzql?LM|--^zYsI zz>6=b(D>BiSYCRIS?1eKD`GM~R7(*-(O;F|O&zVa{|6ca> zK^|Cv?m0Qxy{7WuP$Dg?VMYUH(3Oj|lwQc-;m6}|E9i-sh|CvUb3T_1(j+@UoRXV# zxgdG0oC<-50^zbg1rta-ojgw_@>&Yq+C-~$-T+j3x-6YJG!kP|q;WpmZxKuCA@)@e ztvBF0+?nWomZJ&b7skA^j4v2SejD8kV0(R|V-AF3f{4o;nA*#h=;kZcPedk*16c1p z+VLen0ae zg9+rH-n9aB$HZ(s;A->pbL)KC{>a&>AZ0SpRQ}}kb`*EtpWSJEBF z3tV}*`5gH!!Cz)wI`{EH_0js(EyyXC$YP_70h@1|R|0H0RFnYYpcmmh%Ky92`S^${ zZyN5_@3?pYE5f2rEd`zKTRMqIR}_4aKLW2I;n!6l^WvWwZxOFx;`O$#e)c#XhCf-M zH}~_Lni-CU_7|;0b{&dyFJS4GWs56(51{Hz0V1|vr|+P66e(T_gZqZ1iGqnGLcO0< z!upI1M846y$!&11ba+;OvWI@(k{`U_|H-Xr>rQfJ?PrJ)qdV@rM-h|g`uKFx1R?Dcbt~OE!-|a!lJCf1F&>- z(qfo%^z_E^wcYyDAmPC}@y?~AxfRoW^^>94&rARHTh{&zwQm{Gz7hI03Gj@~0rUQf zhip`vL1K-Sf{H_1_%p?)e*PS1*4Aj7dci>JUn?~*yPSsfo97(@JrWvi-rF$$NBe=D z+v|!bD=LjB6bPbPhPk|wBW-bEf$L@1h<84|tT7`)j^jk^Cz+Gf6*;=S>C&o3=jG*_ zx6-33CP|&_ovm89STxH;{?!gWseSJs(?e43TnrSwxK10)zuxRT-#M)xjM-?L7q7q1 z-OTQ>X@C6zHS00&W`ino_098ZF6f+9Qh0#UguPCkdEhoB2q0%8Z#AN9otYDg=vi}Y zHx&XzXwGHrrB>+Yo)etq?VkVpJ3vR4w})0Vj8oFB!ke3+gIC(U$%}lumi}s8PjUq> zj3{YVq#T}&wBNceO50D6kLAhCqLP;M{@4EI4fNB>irr9QRrIGu{-H7S?47<9-}#?9 zu{4)~BXhm2CU0CZTSTq*Ju*kx-l*E);Vjkh$Lr1aX@@o)k)FTal5y*rcc`-d=*eEsauM*6}_kjov+FWmOdIE$3*f-Dvucb~-mXigm zG}v$;IL5yLQ2YP}5N{DEP9o<|f6oVB94s%}s(<@Q#(w`LRaYX){wW>!+swlzQ#Ik| z0wsF3f{ySv5$&%CzBTLJpC>nUImmAV58vGI-o8`ODh`hP!DQNk!gM|&Me>!Xo_;3- zGTiu2&Wa?l+mwqw@Yh2q7dOxVhDPVRuhPQ5DuMiv#8)o^Hxl~V6%49|e&sLHbwMK; z7C=^1Kn@VFTsL%=)qSl`&uQ}lV;h(CIs*&0CuWA1Wx=?a#&#`F7JBI))scL$cC8h+ zZzb@k(B|N)SrsUd%J5tkAaWe^U53_HYKdB$5qVeOOHL(m%=9PL5qhlCu>UV>TF z3#Cd)(8qVLfxl$OgM?3oZ(e-Oep*cDSHt=9-`4KmDrqiUk0mhD4d!PExanV#FA#8X zET1G*!a!0=9d^#2=H$zsF5V}9TVnjsrb)7kc@ju?%MX6mJu83F_$$_#b>=f!C|vIY2JDl$9EO_^+?mb2NBbwsB0;ON+I%kyhe))POfq^z9B z;BaOtzQi3z8-##~};%~?5D%cwXeUZw=f*$q#j{7|?#rv`xs~Xtdm;nVaMzYWb zV(-h*x0P3K$P~s{t+2+{pc7HoJ^hE&!54oiTUKPnk@*J4+n6p7Lq(czv&X*GRT$>G z6&~9@?Ybwpg=4LRZDZ3nYQ4~)zDFpl5XNgps$wSkP3v=k>_a_!2(V z41sEGsJ&K!;5sU{ET6oSZUE`(vixZtYS6QlLXN2kAqfq(aN7Uw%x^CTiG9I=URDf? z3`a6&SUE29tzf+Br~iDst?W$?wu*)h?E3AlU*I^nW{g^lk#74N<);6<2BB&C@pC>K z?DTWA8;E6z>i9W-yMXOD@0xtM5nnC!_8_~^CHI+`RJ!X58^JA>Q3L+ zpRucn$+)3D-k&*U24di?{Kxek?WDe!YmBzyKkHc~#7p?r)Jub}%Fz`)e=nAA0#pr6 zrvL3b*({XSh-`6iwFhqFV_bsV+?KWmnO6#tSy7Yf;XMV?U!KF2b0C}?J6q}pOOyEA zv7)iDg;`g}s>45aZ$zq&d<|&z9Ffwtu2qalUew8Cim&U~#aB#cc}jRkZ&Oo!x1FQ? zTIIJ@!^xBGo|%W8-p^PWlBN65n$_i%?dXK@3kuX7C%86#M!4G zg>H?9YVX9k-Ni$1xTwN|4*K`aeU?nalwMcPJblb&rD$ovYAasx^JIZr;Yr( zPeypxw66D=v;S7|H9I`w>4=|AkfE@~ks;k`^155T(48B#PfpE8X0C(ilq$9d^4WK0;jVq|lSUVSk6 zuC+azNrgJLk!Nw{yZ?&I7{D2y3B`rK`quzVS&Dn1;MIu~|!)6%cag3eEtS3OQo53e5O$+B1H-D_rgnb^FR zq804&TbGb-N1?Rry)82Db8)2Cek*}!`<~jWWpcYlq{cZr?6<9ahOax|ElUy|ZADkD z^Hp|Ra4WNnEDIbTSi{1RZNlBzF;K-Kt^BpMbiv2(!CqOFJMEi}j;52}yZ3$1ovx4G z28jor+?TpNqCOoonjp1r@aX6*mzG7KVC;5f#FwDNLJ+-*up0vqZf`r)g@~Fp3$2`Z zX!~lMTPzQr`kM}-tdM<_(%2~6(%K>8u?7C7PF9dUs`$7WiN&N*jWp;9Q${(8@K7*I zi7S%M`-}i|b$s^#X!ifJ02uTgH0lMlqwzAV_yFI#-QiY;#w&jx$$cUqA;JoL=h`^f zkX|=f-))Gg>$l;lz5A%f(;nNde&g2aH|trUN8g_+(NY(NjXGYloUu&3CYWqR9kRXH z+#zIU-B_Fo{d9x-(54aVu$^#Daroo!eWLN(yT*%vlK%tMKq|k?n>pWIA1{v=JHV;d zG!9FNDJ@j}i>v8;QwZRASTW!#jo0C(s^NQ@e9|d_1JjUtYX=_GB*egE%aLT$cjwO`Xzka&#{( zQjpNpdH^5ZelIBrf+HWE`~D%D0TJG8HchopH3Lhn6~K|C&rtyVHZPe(M7YDYezU<=#(|nK5C>`P$74 zo3@kn+TBc>Ynx45DL}j!lA2GosH!yu==gZd%}Ud0+BI#UhNf5BZI>>ZI}4jB5CXuE zqB&`63eJE;Jm;cj#B}#)y;_XVF0S*m?_ef#_YQY&Hio!2LjqMJtP59&05zdPPq%3T-BJdwf4GEF|++V z6OuU~fxDhA$0Q3gfPnop?xM3Uwz~E8bxIPr8xp#96&R>#znM+7X>;^Z!g`Tt9Ft30 zt>(N`k)!1zE|#rnU^+cn8_D%%o2NYQ^YgQ(b)KrW#PT{6wLivlt zr04*foXx#zPr4yGC)nNDm%9SS*hy43X1vi2G7M{PN4Qi;HKUf28w# zJ>`8WXP-U2!Jqu>(!%2NFLw3gk3U&od@?Zs2317@FwojMqtU=A(7O*#KX~-$5=Gp< zcIWuc@k2)9$Wv)Qes*^L;>j*gKl<$X{Ni(KH5_UeL?SaqBxb7hAm_%u3+Z#dUeTb} z(#IP-m13&i8aS*M^24_t{@%B~xxDkp!m`%(a5a4YojVWjzx~N9@6lJjxPScY)yq%6 z{Cqp#)M_7|oev*=_Q5WUi`8<7?;MRsr)wpdtEX`|UMy#pea>^9hzQ(~5S-pPS$^m3 z$9{6J)fSlUFNSek?dO~V1LBnN#m&u6zIduFOQ&=7*RR{un(2O;;y4b&;I3KCWALVu z;<#L%O2B40=P?Z@_wPM8IZkmnJ-ru%>&@=-FP~k_8%6)YcfMt%oNxEL+RlFZ^RM1} z`0m3y*x*;6J^hF0SAmcTTdk(5t@ezU5Mqo&>|Ax#9`Sp;UY#DFydKz2)4bj9uCK0k zCAU&;`D%yv@GyDyUK*kr0BA4a!HgJ$gqieEt=Iv4l|JVQUv$%Tjy*D4m>E??U7k~HZuXmd>FgNq_o2yz2 z6L}ztWRCAXehVGd5fLRV9;{D(@H^l5&V##8UR{29wcA{s|Ln=r-8?VeOc>MU$G-tn zBqj;1mL9GQrU#ujIuf&R>z4+2vqpetH#dtiAlh!btESEDa-Nm={fGD8dE<>r_+S6w zKgn7D^3#|9>}&5Vj!rILo&V(1)61LlTHEuNmwC4ZfSdD+pT0c*=l3239?0PzKY#Jr z#hIys9i-7gxYk-*?K-qbqe*3BA#mjdPxvCk~^NRP{diI*b_|hDD4a+-x@4 z)Xf`sw}y8mue;Y;J0GKWKjsQRW9q;{ugwTiwKCBVWV@f6wyO2ubToH0cQT?@tD1qs z&E}?qBl?kAYH>tuwW)Py#d28OY&V@;U(2XkyTRf>sDdQo6Cw9ib=p zl{~jDNa?gFsKQd*n%b^R-Lgf5&5Vq|l!?p%5UQEFTWbL1ZdtWo_MP|CY6Zkni(X&r z;WY3?3JzFXF}HcHLArUViG-fG*k^2q&m6tGsv-%47j<<#s1Dr$KzeCIIL3H-db}D> zqNJ>)<${rWoK&aq3UMzzd-j6)K}3KK!lb4IWMJlftW8Y~P>Jd3+?e?HzWEr-!!d@( zN9*eT>Uz4r8a{Y%pCmln?mv5V{ue+0&C{zh#2LUlWD%jq0v`P6>efjbF$NT#=ZxA6 zsV^nHWk)ts18CK>DVk4eADk@Tdi>`5_up6@odPe-F|r`itNr$f;75+<=PwIEOhX{l z(mwm;ub+Q;E{ip2t2dXBw~=MmTx-V8YZOM2$r?Gj+pGO_vfD22Jqj`Uu*?pD&<$oa za8DxVlU1vLAj}-N55b!$Nmvepx}k=a3wH1mlC{Rd5(0@dHEXR)h5Llb5Uo{bI&1c1 zH@&f}5!FfdCcm2LmzVXE>-^&U<>hX=*iS^bNaJD%7iaUo|LL!P^yF+97vDNM8ovH0 z$Oo&Fd*dR$*x0kH?Thn^d3!}j-H6-}K&TR-;N9b;#E4E_bu(vonG5K`y1pJ# zQpC63etQr>LIxtlqxJI9$(;wwiR@s0bZ_n+@=jN`?A{^(}@#u9N{ zJbvTR!~4g(&GyB`W}nMqNW*;dXaDx!eR<<|PfvH#^sA3QzWDT0c57WffZj`c3WCD5 zRcl?RMo0jL>MEu}+`4Yn-S&qz>w2?IDQ0i(UW+zueH}u#c=SHH?8lm$8=5-^i2*>X z2w+fx7BzK*A*S6foA(PB0en{{1OoE|c9d{4Z^0b^r)k$`RY(|E5OJPMpMer#kg%_Z z6!Bb(xiNAd;HjyB_xX2Xo=PJmbSK2A=9|MWtA2HxER)(eG5T$(|k4UrZ(@(q-AzQ*qJ*pQ@;rMgt^~R zU3UTIKqwrU+1$IqMr%VtCP3z)A}mZ|HU zp>|c8_013>y>?~_v6HEr!tE7(tCb~g04OosJ6^9BCqT5zyVBYs1#nVRqyr6F6&!#7 z4Xtm-w7E7TMnDdXs)~+%I7|ctFvO^)FQ%!ggKFE)H0QHftJ%#|e|f$A$tIJ8yq}+4 zUB2936M+XoB4PnIgdP*kj^Ipa6e;$fU)3NmF!t`S->HopD|X!)F&nh2QvdqJ)dL)V zJR^iXN_00S283za=k3k;)iom?EtVmrRfrQ>DO#`2eS2x>+fuZtX{%+{rrk}3fQYsl z$6A|e`{Zg@mM_=l9L8U9%+=;xgRrX2+bxvoYT81cVh8{b1tmm4Y;FL~Lm|kX%OICb7z;Gr- z@na^!`R4iar$b5sk%($8Ju=o2=TbZb9^;tC;Owpk9zOEOMo@9MQu_JtE;IL2V#U6mQ-u`^yg2${0KOp7Eo=bff*bEcLbXDCZh|%Hg&ov z#ne&#V$NS)-kf~#V!cYG=+))RS2w$>&F1ON<@q#;2oai^iF06q7}KDw89EZjVTi-% zYJEtHL@`7tSxpf^oAz@70NfhX_VoGFzeL0%6(ie*DYp&z^mOj@x-d1UENV zA77l+rYsER+fRS}x7RlqqULOQr~7Lp?32>&Xeyxyi`Z(s!<0A zWfNimC|dV*w%el(6hNq}D{paL2WNA~jC4C)#sWyUXRA#x_t5XDvrKzAjPo=VdH zDcp(%0H6aA58^)a3A+>8OcmXMXwKy@{y}hXbSzK-0efsFBC(j+&YG*bIT9jC?+j79 z=M%8GH5FlzU~1|Wi28yPY8w}0UzE6evkF}W**_wL16;z)0aSM=;-*9tSR72v0B`>_ zza3!qP8`Wi`$uZ6C&4v9Waha{aIiK&Z=v1b`1H;+7wnEBCeQ|8jzl14)eJlGy01n* zzq$5Sd+tmR9zX|cwF{cuthhM57BA~mKyf5l=t}iaP({4+` ztrl0aS~(_1a&4}*ySYX;3?dRFL~!H4;Lu9xlH8-!$moW6y`NdYT8+xh%6v9=sjafN;nkx-Pm>a)wMIr3O?t#)yCv%NYe zx3$C&Q_i!_I|gSG5s3)M!WMs1!gVH+}Nt)9dTY#E5Q- z#VCls`SP=-ItU^2&E_UgyBHW8a-KtQynISTr4(ku!_uqQv(}9|*603&$VBcW+{NqY z*xNbcuExi%nCV5<0T0wYf2cjntZ54(J<6?%T3MtglJ?dZi2$+NEmXDR6G#HM*+KV& z%(osA05yvexi!F0(zH-BN7AitsWTr(w&&Pzw5QhaX(jNW+?x6v(^j| z0<(wU;DQumJeXy3jxjibD`1xa3v~)sD-{rdBB+tWz18Y>zxMvg$z7t9Ywhpn+uH72 zUVZrGr@QU7scNshgjVBXH_uvHYjqq)b&Dcuy5CPJrk>j9;LepXf_IV$RP&y{+a0`!VdZc?*yRM`WAdUO^mME zLRb)CBB^t(HMe=^sAVq94CZCOHTOk~V+>gsT@YlM!reQkm)oh<3hpwD+S)=W2?L`8 zJbrNJYClgIP1W5NLn4sijzle&Qkx-@qZ`H;+4b03!>sDXR7<|#^5I8Y>8BP0o&^Ni#%iG%=z%amHPqFQT}?g>WFTKks~ zhY*Hzx*U&=kAc}#BMKq+Fa-Cih`Z}E+Fhs`TU)P!P(Z_Ku-R{eHagVD-W#ymngJ{m z>6ollj?n>FC=N-$my1zS_q+py5PFFcMVi(`!fBja%dL!YsBS`1T8=R}IF-3>E~Z+y z^UM;UXWk+;)sw}--RF5G;SeMc6XHBgG4`=xK|n(fB#wk&<|xj@$cDru%!HV886@;X!Xbv-s+#vwAW`tcZVy9{ zQmX@yFcDF~J{UAaM<8S*K)_{)0JzttYS_iz-E3O*_~dwB$|?k5xh`4NSL0x2V-R!) zWOJ*kt8s|J+j*{PNVHfjYRL_!dCCxlX45MhEr!p$@zFVu7hGKA=eys zj3IUxcnH$tBed0BDd?VJR747lh>LMtE=C~+gcJiK_khtpis&{k>Vr4e7y|+I-E$0q ziJCP;>YaKk?F3g2#z6o8C^WS=qz6YUTc){8{WK#aa4)5H<3Lzxv zL!%Cp?^m9hlB2pYaYI{=}x?HZr-Fha8Fvl2bYo;c|Xh?`j#NDPc2c*D6 zn3!m;EdrI@7FkLuP;wtJ0Qz#d7RTILclzf!H__5n%dM%~Tq`r?qA7BZv77c25v7!9 zKMiRRrVy9Yej>uYZ0i&%A_7ErYHGsF-UGV1Saoow!*SVaV26CV(bh_>%VCjASssn2o9%YmUu}1)3JzV?)Dh;)fY_^8 zM8I`g&bc%lFFhR`iG~=>jR=b=AS9B+ zp;&8bfkTvFZc{G8RJ9oZ0}AuL=261H;n+`VtF5)%s)0w5dMjAgs_QhETG2)Ti2@K7 zEnQrlTQm2?5Xqsb5~B8%Xe*4AIH)xw7Vdd)5JO;MhOYLae&q*|oQs)D5H+h!-8@D) zi1yv8Y7D`e4j~d#D|K#-7^8$-4ulg4G7Ry+#+oaOARK%_%q$@QScuUK+zrgDDj+RG zLV%FMG-ZyWYFcZE(cJDa=aN$z1TaKl6zl6wAR?@$M@PrqPCx*G1;A@<;2vTi;bz|R z3ke~Y;s~zh;BTDVdF#&oxLBvOI2qDH0x`wXs_Mgg>76Mf%m!xK#*`3{`&i}l(8#K( zgwRy2DKQCgPuZ@mBElg&kx*jn)f={^7= zYHN>A!Vmly&POmoT2a#1aXMUGY@z))KP^;U}Z4T3>n zJVe}@se9GtMAYDTv1GueI%zR?hc0-L1}!Auve^)P-sIT9wJ;kQ_kOVhCv%T-5~uP?!Xn2qS{2g1f4*u$duC-@gQmY}#cj zF-1brrhpFaDa4K$L4eNxT8?2HVi*^a24Z#tB6ctU?5jNoH+O4|1fgFu4z(06?Q~2z z@0vDO3#}1R=|R_kZq6~8I~X{48W*Kik`yUT*=6?U~QO;8?<-z^?``xZqlgRGAUM+~IsUB)Tz*4ihDZ)`0 z386KW$hnl>G7<5RMnt&T>|VZnRpuOGXtmC*z+pS(Y90brRdbIql7Uq-GdCxpj@XtE zTCHGMTVKmFb}clzgivx_E*30Qa#mAt2qCI!N@J@HsVnsv03?bCJ9rSOP16ukia}x; z(-6~oy^0~2HsXMY92g9`pOPgoNz+zM4J=BGDQeT*c6Ywr%-1_6Dz%xLwH8xC_oAw9 z3=mnIh?#G;TPCipqHxI>+*+&aaoK8>5Ob|eIL|Y&h_JgWxHfh0)^rhrg9AcQH2^{% zCA!)zrjv{SvEyFZ-Ab#gVPvGma2!Oh%UMBKD=MJSUX!vRW*#KcTa#E8B4J?u&miCIkvB?Q(^u5suW z_L#;}OLw6V0syKT9e(n*pNjzqGqMDL+G}ol5Xgjx*0hJufw?f3Tmmx*_x$3WuYUjC_tuL$r8J4@}4oHFs;I&m|Atu$n8su6V5OrifxSQ$_v545D|I78KH##8gwRz^ z{lRFhxqFPER}8mWGdlQ!ZwKamUDE9Xo9+H$v#q)GKE$on+L|_PW}SfKPK3D>LJSnE znY#5Ijdb}{S56_fk~xa2dTqo6?%GtXi`QHoV~}x-Vl-)UCYI1jAvF$SU<9b%Lst>p zVoGivLx?e|DIrM=-SCNs^ISv!YP$TsRYI(#GEvWed<|DXUy32$v3|K=35^ar=Of%z4+`im@ZO?!a=Pv3lgLd(jpBh z0ZA{E4?nFP=vucSC5mvcrS(?6R8_NmnF-;mCr9_*c-JMWHWu7Z_4AjPAAj}{lzmrk zB%!Z9elU*@KK=BGeEa*qGne}O$(L1|gt)$Y=i#0EwaqWScxHgaWJJdg?+!68<5*hV z&Qo)@>wT`3g^o^FW*UZwfvHqu;>BVJ(#1_Z>YRxH`(A)@nQGG@JcQ7yDi{$*ceBRG zok(t~9QgQXRbmnm7M!LD933EQadeb$cfDGL#b(-UuWl;07}C+*dw15$(u$f9&^QjI zwl6;awA3k3OeZIIm!mnHy*P86EiuN$qj%p~$DyfSPa7e&s?+wmpI@C_hX^Sp2?Epu zb|eiW3N06l6l7S8A;uumZXc|!zAVK6;b^tm&J(xR7mx^ufXmeqIh436TBkfacoc~k z0AV*xkcPM3dTWsQ+4HCS%{Anjj!u97o8MfexSRJqVIzci_Uinnzxb&;tnNSj?mKS< z;@^Dnb!L_jmGP0e8(hB;St1Mg$Spoir#Ga@>fSsI2e19I~*4Y^eTjuJXzf({u| z(A~k+)X^Owjpf zjQ&y7T03jg-4lx=sy1|B=COl80Mn34&Yk)hLI@%B;NE`j3lISY5moP@#UZ76&cX!X z5`*i&|I1%}{_9`<_?;F0w}1SHs|WAyn(pVKu49P1V*l4a{Q8p*|K_cGi$D4P z5AK}4`QiD^Uw`8&U>1UPFIU`bZ6d`FVC)?Z@##{SpWW4R{!EZ z`J-`sbTif8$@5nqz5nO`@$dcVFOH7K|KfFj0L(@i>j>q)f$B*85<4uz_03bnF ztp1OW&R$(#`L#7`i0}vR-u;7b{_c;<;`z18fB&EVsctv_>%aNGKe{~s!5{t8|Lpy* zzJKS~3_g1Dn}7Kif3?|c7LVTfAO4F!ee-0YrU)=wTa1f8`?LS^FFyVVwS_25q-GpK zL?o7o6k{l*^vLecq%3tFhGi`^#gVC|VGu;aTyqwd7}(8nt&GG(^S%l5FphB?w6-9E z!r)FwD>Ik$gYW;|*X}*=rUw3(fB!ds|Ix>?82{wE-~G;`H=8*IO2qqGS?j+l`Qum5 zzx&Pa{-+;&EfSut7C-ys(?9>wf7ng?JCEM{@BZWuAD-NucAI&g!fHA1_W#TO`)@W^ zmkdmS<1nJT5Hs^~x$F!OVvZrE6uMRjZ_USjff|Ce)+Au7I_FGC9mvj%t#%(R4JrJ8 zOuhM&Wyf{rcb3e&_bs(AUA^xs0AeFRf&@rW5Ghil(K?zLSrL-P<8e$l!r`#}$0!^Q zd%{adc7&vnI3r7*p*7+H5dyI{&?|cHs;;iRUcLA3l6lVY5BZw*j~zf4&{ePR%{=G( z{d^e7s>~Abc}&{IICW&@*WUVt=T}Zx(x-ddKlu2=cRv2;=*qEQx$>o@g*h?sW#N#< zgX-3;8(*xhPA|;<%eTLKVrDjp?2h;U_=i9Kb5ln=Kz>86f-|B2+8u0t)9pR3{uV+ zdUiRoB{7+!{E;PQ)r^#zG_*ZCG4;erQ_ehtLE*h5yq zl)Si|I9JiSMcKA3A~_DGk{g^vIMwOUvzoYLQe!m>%t$DLF(oson>Mo^)N&PLY%nA~8BdWXC3AU>fDKwe{@? zR}L-A_h+5>q;WJ#H#gUx?yaN6URmfQ35?9#N7k>`?PACi^q=stM7a>hK0Ss=vOZ;zIyKL|M-)Yz0ZD95dQ8P zFTVQnFKoBm0l0kV7|bsH^ap>#)zf@X&Wum}c_u%%NWfGyrkERO`CjOpe@0A-j@Wyj zVkUE0r_-76M2Yg3neI4;5!?qp@<_gD9}A3xaNSe-BAm!EqH7LNbB`(qevyfj~Y<>V-!;PhLJWeev|!hi>lf#_mZk7gpwkeOD&ajpp%VDLUk0?S#y z$)GM^$T&j6$&0zuDL@2)J#(il))GA39wOF`>B_%v(Mk( zwqCKy7hZnz{q@zsV5eO^^snFkZoNJHY-4v&_P=)N$^yizYa4AFt8z-Q97fn0$CGEz z9S;8P#@dseZ2~RIGM6_ICk&~gC{)#X4+fpG%wx1B#k{6sqLe1_*PJ?H=1$ScC!-12 zK^4H9W5?7fOE3t|6H#!EiI1Lt{+F*@d9bmw*QQg)Ph6Orzy5f2cY9}BVYN!*&^deZ zl#IqdxP9-|=I+j5cVYSHKmGbQcJ~IKZ|#hYUpjm4U_4me-W8DpEccrB*5=Mef)_5F z9`BEDJXx*BqYy$-6v4Z0DA7@`)9H0PKDgjLA{0gFmLZn~-2~unlF}rn0~4`~893%i zrw~9y;Tf<3kr<)yAwvTkJ0$w**S_)gr7zvs+W%-{_vFgTv3~#h=Eh)q>$73|>CSk0 zY5CO3;m;m#|LL_GKYMt;j`8=t{p~)wzkaZOZGZgI@uQcPmVfr>aXmg*t@U2jUfUdA z-yU2zakK-)Pw(B?+udX{1T4JoxZs?3%-*y2E;v7lf-|#Y01Cl#?%5ILcwK(WsVV}& zq!DANh@fqoHLgHRo}7xPXz<>iQGdMm2*5;~F9e9D${EEvHO+<13w>u`Un&*AeY8`h40>5Vs*=MMeFttUUexBB6u z$4@q&)(1PwOLM>b)-T=OZ~yGZgBx4>UpaYfsyp-P+WHG8mVe``-+X6%_~+N}KH3|+ zcH+pPnWbyn!*=(HcdR182QdS)Ou+WeP4bKxy=%Gi1Sv&EnqY zoVDlt1n2yZC*OYv-shiY;Ta6Po6u1hDVN`#aej>%!L0P&F?r&^F8GjCnMfoNVc~r? zYZW0NQSc5euk#5IvzH>j_VT-@EQ(GiI40+O5sKgfU`7{Dd?ZA9H!;~|WKi{k2!C-Kuxj{?(h8=T5!+zuX;s^u_I?J%3?& zt}YfItZf|b>aTt6jq9}de_VUCw!MCNahkicH`Wh$ypiY0!MoCX$__FBFw1%RJjQa) z6QHSN#AYC;mU+O)MEQh~|Ag5as3{W|`FN-N=9v|pS=ikhVlGnTln>&UP9FO5^Dlg1 z3xD?R)i8MU(&^((clq=CYlGE$d%Jsez4QF?+eZ(%2UTrJb~H$C#&Zd!&uSaR0*5BdMIdvAQ9V=dHT_NfB)&+auG=8mj3HgC$8Ur`0>_(h!ml$n+5>O z$xGL@&ys|>d+47*k%%z&i4>nX3CwhI=$F`Le1s&PptOk@CKAfY-@1Ys0Afm~jvZBj z8*7grY;He_=~qu4o$XI;Z*L7B-+!>Ru~CiQx^VX1qqPTju8-@nr1bm?uM|YrHaBkE zx&L_?mJY9c{rsiRA3l!5!R;GY?-rdDfhIwRolrnV_NV|8A{N1GloZALqOsPMr6HJUifXC^{_NpX zJA?5%w{PCKakKo+FMW0P&|H6dcW--q_u3xa{A8~G{K}zgk5)hb@EzUXJaO^)D~FGK zbnD^!AH3Jr8&Kanx zr5Md1IG?AWxec2?qK=(o1GU^&Lv}ykm}Xof6X(mWhyX$vf|-d~@J_^%2^u1UNHW#w z*{M^9PJFPw_wFZG2Wt-=t{k4~O{Mw(2^PA&Pu90TzIh|9-9$ixq_KVO)QNttfBlOG z_dj_bCEYu72s26zuFAT)qEfc=f}ZUAK4X_>tL_et%}{JeVLcsFltY%=tBJ zriJ%vhR$VJqXIA^7@L7a$?q32OKqDqk)WDoTtsN92;hkkpdcn@t=hKP*)A&Qd`ih@ zE)g;U#5Ovhz?{pI-aA5MWL1kXIV4D8st!p-kx-MEDu94N6!AW!l$g*Y7p7Uom_ecd zs3JMx?g>##` z@xj&ii>+I8v%OGEeXzR!;V0MV?vMWZ;N;PTU+MRH;yRAVJHOHBjqBI8s|Wx5xf7+E zYR#(s5r8BB2gA~ZI>lO|iI8J75EbuS=|Wj{ni%WUMiEEUb3V|-n^(uAW}1|;vsghO z%X`2%>MhM~AN2MHX)qYYW}Gx1L{&w$2lf7b&7F9-AA01Aq8yB6YgqZgJ_5Ey&6+%6 zRW)g6*Q|M16o2~Boz>>v?)@7bYMmVKbUGoV{VE;QSl6RN3wH6u(g`ZcUjP1Xdi-RQ z);FEc_dYPtY_1YhFhszVBx9Y3Sm6I>XV(l15+pV?P*5`_R1;Bg%xD@MzIgon*zkuB zwl;3Q4})FL`230G7mlB(dJEV}pZUO-?%?U8a#YnO%gaaGgW=xJcDr`F9=CVi{N`7V zEiU%@Pwa`0qxkT~sMCG<#V@TqdGe>%uRXqZ8&j>E-DE0`nH}T|a9tBKBoRrPl4BAx z5CcSui9?7@B(+Yr#H0jZQIre~OhjS==MXVA5drd@$vKx(4BmT3u4$9=u2cAq1ChA5 zHzZFpyza%Zt;~Ls5+lrP!ICe*4^^ z`(NDK+*nW50p(|js6%TtB4LV>q3SxJDY56=Si#&flqAl1Q}xanf+S_{MFgG8gG~Z5 zFcT$m@{9+cxrV5~j-z5y^+h;5JMGV&I59Ilu4@sqq>Sj>wqF*V!a0rIrb+}$bBoh6 zvkNoZ(2RJ0>+!~_T{t__pAFD7=bfxL{MYKKM*=a_pR=7*kGT8ba>dB-7Es2pC=Po+u^Fn@bK}Cjfm7K8Ogj zlavgAiIOBjLV#TW7n~+FK#`8s{Cp{#&qnRwotmbYkPwM# ziA1!xa>#o(6)0#sSMu)Wle>3sTV3_1ds8l)ouB&prPJeu?!)cPtGBO@M#EzZ^XS9l z{e!jjb(cot;r86}auJH}fB4C}_cyk8_uAdn?(B>td9-tIXJ;_n-p%A~17&vkCmpk2 z*{oCej9Yg;FrlcnF{-F1$}_rA6Jt!d5?y*12$Pzqm>~g_-V?!o-Iyr?nWSD(B2xB; zwK3TTw*)uQDhmhbq`N~&WdVnR@`%!e1#x@p)^$*vJ?Q)DDYWJggXr4)k8%`#O3 zLJk=gG!k z&}&*Vi-Vy9MTG59H8-k>?2q30Y&+fFxpy;+cV*O{nd)fcMs0jD-d)?;`|6n!_Vt$* zii_QaLw6pxYfpD+IBMEjpRKEs*r*zZ5CAO2G}r4KU7k8<)7r*XN=Y^4`Bv>+jx32n zObUpmQaJalxT85wM}(u{@X^lxxYhmLA*A#y8e&ZFaBu(N)|1PZjvs#Wg)UR${6B1M z@2uYM3FBXO*4CVZfRy_BzXJD-p=;sRZU;s*gSve z{BM8hLSSylUAwckwf4{-9OSe6gvjj}0NAlc$qTLt`;R!klFiH@k#m{!2Y`??S2Hq? zIy(pm>A5otuO2_~IZj{u{8N2;2U5K%VyY^-ur)o!hH-_qW#(EQvBvQY%JP!7eWdcgLft zZqHOa3rKZ&XYwUrbcAcM(^B0zuU&xHVqMW%WfOnwvA|zr6@5b5edF9lk8eo zQ&2;Mbp7_LM~{Bzl~>vnd!6o$Pp@t74Yv0N3}|L^OH0{`vc0$8jz$`S0Zh&I3)QXh z;PB$fBi+I?$CP&W1{vY><||)5)1Ub_@BRJS{d?o_z&RcYnyGUk_fUQ5H*qJwq8N#o z9eY#Iyfp+MhsdO&issm*wjsxPijp@=1gLYRvW@~pG z+x=YwoIiQ;?MoNm`}pqdyEkNOOC`1`1?L=-f?%dWnPQ%O5l)3G-cbwy;nv!9(XKKO#!kqgd`r457#SXFIKt1)87`=rvu z1|3S0s){@rAzPDbPd+$T)ioM~!i}m?V4pN*UWa#{5Jc4xkDFRVy!QdQktiYxz|2|7 zFSn6Y!e}>sTdUAMb(T7X=2Rj0PkGWwrEg>5G5tkPy{o3_2khD z^WTOP532F^KfL+FpZ>T_(J>!BywYP=UOqRD)ek;7{pUaW+e5Rn$WAoY&8U*ELX8M2p$?9PBUOhMvjhZth2G02;YHEh2W>pAGBr!Sf`n^&O z2BUEm+rU)%V9$D=2v(^^q|$MI^VLz3YR5b8+^`-25{VV1AI6r@kJ~1bOZtUp=c~3B zwdrozG*Z_M5>0i=s3{j$2q1}8Oo4(R4BIgQ9-f}9t7!aB9mh=_*i&W$?{_Fmt*baLtZ;@61i+Mxd6 z>4xpBwN~2%z9t2+C#+IE+-tY5ei~Dl~;!;E*(35VSa`Yh=7ZJy?a`>+8z{khYfqm$b@E$Zez`@ueEL`wBL!bo z&Hi8j02YcfD=Y8cy7%DW{hjU2rfHacX4*Ly^JX!G5JG6%77@#`EJ6@&MN?H(MbUB2 z$Hs^djnuNn5D-}y$&;!ul87J@6N^ez#RSN#piES&5fcH|<8im!>2x|?lc_P$?#|BB zoozCpz6Bzav^zf7*xTc#y7TD4_Fy!>F#CJo{>JLw3oo8I=6apr-Tr8(%}@+~|7%~J zE{cyg9&fGQ;}pRRO(kLmZ>cCTId&%I{X|L0%s_dMnI>~KGcpFyOgt<*p{|-38zNGR zSquQ?RV&0`Vg0Lef$ zzZ6trl$KS&#MQBpq@osMTNWKcs}mydo(#x&0VH%9d`e9~NRFDiHZak)D0``m zqKO$}teX}bJ5{Z##<9z5wY>7p%n<|-5TAvkW`aV9z&R+Jm>39SOzcBmg=M<6K&}1YdXp=Y6-=6Wr z|NhPU!+Sd)Z*PD7*vi*0ocijei$8pDUx}Hy!*06QlNN{|#+JakMF_}y=P z@9x&<)7y7#=RvO*+JtIg1Z-4vx}uVk8KP1IPl%qmjSTtrp_#|Q>s zkVHIDOaf@7J=38BxYB{DbDnaK45(+F6jLYo5PXu<)gTH}WjTj97>&E3@ZLw&B+1l* zcWS08jO-jYZC4F~~Z0`MW^?3I~`NfHHsJZ$3p#zAXi%sl|d#6VzHwJ|5{^W-e2sGC;Q)H4HO zzh40J<}hv^G(E;yrZ-pSZk{>G)ox62d0|!&PfWS9CyofN2gjzyOhya;^cyd&T=>Qh zo-})_4^Nb1?k+4Z^pop+wl-?o;hA3jy~U8e^ip*(Y%ssG}UeNj(cUnNM=^I zu?#-XB+vkn0=qo@3eIIvcbv?|tP{MdAsP`MjBD?x2%ZdMN}BzQNKH&h(uJe5=Z+u! zqIRF&dJy91VxRxt8&ww0H6(q_LS1+Ej;r@s*d(o_^tj zJ^Ae6oum8rVR`D}(U~(Rj$E(oqgxNTe){^6giYwih7(jAS_Y%Ca~Y(a zLzzsJcLDMYvX-l=qL%6Fc|e;N`OM6Y3Z^S3Ps!BE?){wwtliu!p}czb)Y8dI5*9o; z7kp3Y#UslO5mb_@z4z|leQBry;YW?+_N z7J*vPiJ<13OEJ|=JwG>#Wk=3)2{@wrRkOEj8n6 zx2~s3PxG@$Z^k!#vcXs-n;_%8sjO~%L=Z}{Bf8SV*(oRkH z=iCe-0U;p<=aHaoqj%mj@9rIRI$?QcYH@z{=IUBKYDIN89QFHsqR9kRReHUCUDvL| z%L_9(xRH^BIUACam_atKM3KS=FeFFNnf|4-C+^%`T}x@yHkS`Ao?M*0a^duBsAH0T z(H*x{HLd~e?9nA_8X0Z<&5aws`K1?MI(OxA-SqoCkB%K*K6$vVdRCUtoj7}SZOf#& za_(4cTNPz?j>te6i3uH3HW#%qI>%~O1m~HVNmcULziA>nLIdYqN?Ld)Vr|_LVHpYm z9gat>NE6%GCIl3d98^&-L~=wimx2f<;$zF}6DtazUquQKn4)M-bL0pp6RTObERq-! zJ(woG?4tdozrZ3Lgkj%osr?KNKGk!E?ehBIz7|9HYqvBE(D1wizZT%;F#H` zXBcWnXn>BnifvM1B=3AKzZzH`GCS{^oQQU)YD@@*NpynT1_<6UQA`r0n}r!MrCwR) z<$arycN`ouk@qfVo^$D=45g~Zlu{DsG6D-ZBdN(nNdT1E#LsR^-a7&_g(gW7?G!~y zGO5;!I>%~|+25Wao3$VyA+;$cNx$*(%k#@e|M<@Shws1p+=Bc4H(&d$mrnoD+RMYw zepm)nk$$J_$Bwx&vv-5%vZR0gtKV8V_m%(i&gjFBua7?ed&YR>#PV~;&%V1G|Kx+u zboIs`zIOig=U)8ix#zB~-sEb-JFk$`Xuea7#{z_6wmTXJc1=u>qjV9Ih~`oeP6j{Y zrVY+VNx^#&A%tp}7?GJ(BOnZ$IIQDDHjLnznp*;ezr2c`Q^9YTs(GUdTHeRxkj zcxpQJI-Y|-LUJK^Lg<9DO)5xFBL2mfUy3my*xBW2 zvOZ;PI%)_-j1d$>WT`*pfgk$d*%s&LzxVRxUwPrupT7ISjn$|7`v-%Az3Hi0A}|AX zRMo@7D@%)W(+jrOQ%l4!P6XBo9^|yMNxWQ=$6p~`NDWNY5rKCy$-Y7(f+$hcu_8hfldAfRx&$y$ z1S-7OCh02omT0nwR3a4vUsk|f8T3FVmvgA4_Ph&A&@EVVJBK@OvaN$q&@ zZmXKM3`H_++Xw(vs+ri4iJBRVn&?Euw8y9dqu3IWcW7o3qa#M5x@o*~l7xv4#VOTxVKgBot?Y#yhq#|w;hKC(UZa0JDr`HDLn60_1f;iFT8T@ci#H; zPalr{{inAE_dai{r-gG0O>Vw9BG=DKZiEV3Ve8vgz3~ZH=m?O@!z@Ps+J~qFOi~oXZNsPNx8b)W#IsvgpPb z**P^4Q6kFk)HbH1rjoKtAg{M#N`aljp(J7N5W#?A+c2R52FFdCn90;~ri=)?U4Q)W z5$g1AY^~q;6P{(;8#i%(XsZ2=`|rQ`*2?jh|JR%Q zfA;qux@$j#Gz^~J>Ys6)?$%~{eB*l9xO#B5WO@-oXT46Ls!&HQfT%q=7>a>3jq?)> za5VMK?Nu!^shJ4`Mj{fmtSv`wm_WvrCznLBWStO;qR6e^oW0K`5K&dNBs$+Oe7B42 z+L-qDciO>5n<^j{^mVePjolaqNqpPvHEorIRVBu+99v#EdFJo7>2I&y-oN+0i$hd# zWsw83K`jKrp-8HbIU!YTqLj}HfTBKQm)Lp7`9P?OOo%`(5T+cbFGM6K_Db)-On8Ek z&jJ@>T3MXNUibci%F}z}(YQ%X>G|sV4zF#N3q@nRvpc%Avq!0N2ct2YSpz&hbFhBv z$B%DuS@tiz_?8N^Oyc?dM;0!{MC=w-46W>#FjOx(=$?HZd;F&W@|P+lh5k zk#js4mcAT}#$uMDfLR?AW>KgQU>Ze(_r0=c+f=oU8txt(cxF#7W~oJtRnr9L9FIg( zRn_ArF*{RT=;8Ft%=G?Xb>p$r_3?A3ilRe6`*p0Uh8T~}AD!xTKxAuwY$*ZY?84ms z?(Y4Ej}_tY=`&xsaCWdec(S=Q-XHdl9yz*r=-%DCkJdM;;eIYtfuopGV6R{r#W6kE z86TRN>GY=$%}ifDd(3+CZQHzc<-*3nK~pt*!+{a@iVhKJvXduQj?B)i4u-=f60x+= z2!adGxYK582$)PJOHihy@Z#wgh4|&=`G32)UQ4^&Ez54Fbe(HYwgahiq3?aC~d0qi40NA zI)zV3lB##k6ERX*6e1EOd7eZW+cp-ZH-nT?-oWP^?5JtPV%`?0q%sr$(6kL?)~kSO zV&~dC0ZK_GugOWb!~k*{CofW&&|p$vzyldrz)^0CATPYDi2RQ;UevRFVKpo*m2> z1pzGTB*^yMk>y7_gJD$xf+I4-M%zgn2ROGR1C#UI4L*q}VAIBaQHq(WOoT!XRgn?9 z!7~+r=!nd$EW8r_;M*jw+exV<;wYLY3Q0ta9l2aNAZD9LFLRCp znK-2h6^l9nvoB@xUvZ2S9A!)=F{*YQyV5&EYm+u9f|>!UsB_GOQMB-`iDi`Jh@EpO ziK;lq^o;MUpiGVkJ+q^n#2``CXRA}^r%knKV;Q`tdUni&U{RzM&BZ4q(v%E9%yMMU z5$8^MJ|j*F3x+!R;~Fs;7<({eR5&x+**(0}@dv`xB<+$NpPxnI(rVI8~b~_~@Y-!r9YDSD-uPT|6~6Wp2tjhm+;M z$+JSUiUL4c1T%Avkg#rA&+eIj0nLDsI)!gV+SsZH5~&ywdZyq#IiCyIB7)Bds3NAS zfoUvIkJI_7{EEUt7q(<}2Tr7!%Omo9|4|#)KZx~Mku}CQm-~y~`P#w$+2f~IV(5*B!&8O1<#|b(A)(o^LwN=YkRhy0 z6OvLCB?M7}38xnfv2EKF6LXQV@@hZ?$LD9cH(!r%i6b0dT;JP!xV!)T&+mM+kFzuP zR(jJ*eLg+aJN4Wlw=*1ROh)vTx8D9|#~1&%zkTP%#*-K3`bQ9NJ$bUZxA%B=&mErW zPxsbtJ>1>h*xB6!)w<1~BB^6+&0?EeRh?W|+&CCib=wcc_Gno6AStQAxM@r80ANs! z>b41vgY!+3n$%WJJFc6U5}5{eBI1ZzN#nW!)eyWSNhyun);l(X@%HxW*3OB=`I)Kd zErK%(i?Obs4y&z$VcSHm1v59(^%nP8Q$MkFQ?HPfkHuWcfgHa)v^_&Wdb7ai^(W5mo1a3YEk$$iUP!xCdenX;91oO$T4}xP1`!h zsyWwhhCt6etAG@OQ?-~9GL=3c5&{BY5+OjF0PZJ6AT>*(h)e{b2$@-Z+9cjhND=VN&h42*j52apvsK6_AE5w}s)`|j0hnrzs!e{Gue?A; z8AQ}a1WiIjF4HFvk_rMjCRH@hoK2lHslW(XRRXh!y2*#l0T?>U(DEb_91}nk?RYN+ zGC_Zsr~v{aX3RbjsVMZ|8Ic8(=3N6Rnn)_V%cb=)l$w={IPo4%*vRa_ET))Wto=@z zx0?otNQFaD&8T@G${dfZNViO3-NwQKFOky%( z*Tz`-kR@QPXp>?STb=+a(GfO|Fey0!oiJ$fksUx|N>LIJ{llHDBZnTHK3)F7>n{ZV z5|`yWtK(a@?v3|%*ix(2cwG6IVrnUS3R4i0AL4&AwR?MDwELe!P%shO3-W!1d1v8}0InC^*a zr!1$6GO1Ke>)08n=Wy!KQm62md$fh~%taYu6i{`}mBBS_YT6c%*l}=PQk%gP9q-!| z!Hfu1l^NSM#dZ=&Z(~D9olXEiQMh*h(TSHX|KZ!eI38Cs)4k6hJ^;qc$5u2Y4zAbl zNE3Tg-RDmn9*#$)_l(q^TKLbt^LAA?&J}mpAGe^FR+eD zUfWoGx|_i$3ZO|45e#SM`eznq9u8C0Ho+C4)9v=k!Duiu)z9n3m|`-0{=)GiQ!}@p zZf@+1s&;HKEiWycJ9@~(lBvr`SV=_8$We=&*~w_9xU>0_+YjHqbmqVL)n7LN6aLYi z+q(zb%QI7x+ZEC7lWhfAnVU6hVms6LVcs6@ipF`)ZgOz(gjsAVLlN=Gnw3_lnH%ZFh2STl@m^1-^GdE5( zA!$wnh^RuR3{to37?9c+)vQw#6GYs&Atdh|62`W*iS`Ip5)+$g8xs+f&O4@L7GosD zHl&evLyy8hokkAL0l1MB0+lYWfs8Fk@m>^*YK~mCuqR4A! z(|j?a?8^XXVscD`6PF**WbJBz>B;tLeCNOWNAoY8I?=g!c4M#pH$S_2_u9u6o72Zn zzj^l5zx>wQU>Xzu<)=4qe{nmGw*Tbaxj*=YH@|ZB470nny7xENZ?1ju#r(@xswVY2 z;k#EZf}BY)esJ^NCy%%5oej|hYAytT;RI_0m}dzzVcvo&uwybn1ji^Ux$2V{VVQ$p z$2Pmdd`{1)bj+D=^=uTW>==<$QcfXcT#T9(&WY_ZIaO0M$6hq$!d_0))=e#vh}dufUsKBf zHB}WNRI}0t&y=^+geV3?s0NZ!ZpQ=WPg>?=DS#2P3*m1*x^sB>?D?Z-7LT25#cu92 ze|q(c)qB@%v{$t)PZv)%_HOL8cXsw*cibtc1y|K}h{N}eAD=mUtkVm0XZO>aYu6us z_Wh5p{^Mfm=%HieXCGGbKU{l!jtOxbp#Wp4tPp-%wRe&f_3@97M6uL!7 zDg+dmLhx;rMpR>y*_nAAj(HxY6TN4iVla}=Onb>kXgL@+f7$7LIr8%S;VAZ~ia-3~ z$=aRw`Cx#6MDXst^_$~QSJ$e|oqf|t0zbIBeq0~2?|@lS+&HK{_~OC(`o?-1{zdro zcEii_hk^XHLH)B^j|Mm1;bu>z&5a{+Y?G3dddH%gL=8Z}@;(43lpV`+I}ue$Dy?(u zyc3cCm#H^6>7fso|C!PHo)X z@9=&3(yghuFhw9qnPhkOXdyNCB9UlW=dG0P{32V`%2|(px|J@h^V*`fFYI zSD%0VS0DfF!%zP%!n=@q?p}D~_RFt-{>AU`@W@OZ0A6_WfB5JB&G%k<;oimL|Lbpl z_4|+i4zC_TdbWQ1tq(5_7mvRBIDE12(gBSzgt^k(;6#L{?TVz#^vbc|LNfVK)1hjb zR74_3_qmID5~DPM#JNpv15=QDF!NzK0%C9C9#p~akR-LHr8WJ+TE=84&kTF`-BWe-c8*%qEk6> z!qjW>Sx9FD7^Y#dEv{?j$!KbsFoy2;a{(qdqzuvqVFAEx4H>;p30^-tBe{7Yu&So? z67{$@W)TTuHX9Zdmrwee_`LxBF8f9+k5x! zfANuzM^KGdCLj^<>3OI+16W$cn;>E<{k4PnZ@zu>;2-{;?)@e* zj>qF}?r(kg=MM*e^U+@)9(=x=ryu_KhcCVNXTY<%-k962&;R-JyI=l)|3)AGUannx z_Xj_H>pMRro__P>`1wEnBYpNCAePpej*(#rU;%&`l^ESPwjoC#Kxi=2ER94MkN|{v zn65*c@YGvo5~2_%WF>nGai#T~mOJcb+ldh=LTx`yFTB3H@!D!WE*87|Rv&#uH5`Vd zX`=bMu4^8j0wgl^8@HxguZB!a>=wF=@#t&1dIFi*so#8YK7S#QpI%F`~_S0qc-T94o-+1GNS6&jtyLW#7zy14P{`TYFDaL>KM?ZS``uXo4U*3Ciad>*U ztm_-MUw!}8myWA``pv_ur%M+ecFdyecp{NVW27z&On|T~N+Pj)u0Q_@O*=STjC-Gk zDF8O+qppOEeU9Z2W=LD4SHJoC{??1@dK{0xp~HhrK%h)?PZkDW6Cxws42kOhanm10 zxz=ziHKMWv3IzlJV=RSMH#2vyplBl8@8_#!DH0$NozG|Gykw!wAd)dgHMPVHTjCfH zVR*>Y>K3$b*zOo+b&s;$C%BEa@f|^k%$xw`X|nJVpjGfC5s66EHx^O1RBH_wRRaJNCX}w` zVT+`i+oI!eJWSJs+#o_-(;`ggvvcd$00AOe>%?+AJf-!iaI>%gq<*td*|9!m#4#3v zoVb$tGLqbH$*$ZJAmKz|!3eAm*u^P4oFQGsFGk z@y^B7i`TBdaqIc#Z@z%nUw#g^`2pOxwpVjCHQhRi8k08SVS4l0^~>WS0T|K~TI*m| z;nmz)n>qk6fMsY+|Dw_R@+%R)rxz6@Vg_w!k$RUM93B6RcGwXv+j1_CzW-Y0iI zjAKMh+#&*Ty9g0M-OP28Nmx_|74a@AnTzTlGgCywEL5atLWM9xCX19ke2n#E_LYcq zudK&-@r_qLy#4C$zq$Lxmk-9!T2*HFbiV)Kwbx#H?)leWdij+XUb_F}(O>@VqhJ2& z?;GKt{@}gm=K1r7kH2{E1lIMqF5i9s_FK1Z-Mu{CeS9%4*0h-Cu0G7IgwPd@A}p;< zk(QCQ)(=M_;;BW3={PMc$vwhch%zD4GlNA;6*3!3V${!WW)O*hZnf2eQf#<6BIK4k zoBS-*GGagP-1B64Jw+QJsE(p@t11$DM1`qMQyZ?k-j737?b>eF+pZ)S#H^~d@T++l z5sh^SanajE8W4v0G*4rUin*>Fi*mV`n`W%0b8DI48If6Cg?X_ObMBLcV`0b;S2IYE z)`&18D;F;#kjwE8f>iNvnYrt8MOv9@&A1{{keE3vRkf-UfEo$WM)|Hxz*BaUnTb&K zLlynD33H|v9uN>)=UjK&_GA*0x<311ON)-D{}mkw04%n9+TDpD0+tv}H)-nb=DoGrdj|j!x)~yOX}wEiBB2f| z);w=Fjn|V=r!X>Aq^n0@0yptWN_LxA%Df@1TbXOUWI3s3j5wkiN`}az4Q8HOuZyrK z-wD}}n>2UJ%z1xSvyBoABV;4-EGyL30Rz@DIJhF{1L`8Idn?>Yc#I(|Na!9_fo$JF zLPWII>Xao!AW~N$qV4dZl1h2FxtE{2i2T(3LN?#^O9zKRfc+WXT{`i^o4za&U2T{W(bRhd z$EkZmnpl`whZ0lmt;4-A&>Q$ivlAbA9{06>I8q%c-aOh6H^ zqJW0w+mB6En*a_#3Be*65rGj7P^Mg|8=a}zm40)-7v_s~{Oazb9Ls*5@%;H49$p7l z>m30a%Tm}HIML8gJfw{(&g20WzU!R{RlQz65t*lsh!MFgYi3Aq=eym-@nD{vsWIPw ze6gQrOmcA5^=#hlr2}HIgIb&1%}j@>W$dH_K=o&cDbj`ygzPd^^HCFnh(sijXE!mx zN!DLCN;N3VEy7Q)K@=YSgln&*mnXv6D=+-{J8#{8@ZeXUd>H|VU}l-o=IQ2*=XSgO zem`9um%9%i9DV%R58k=a+ecqNzWem)P>p5%;CpYqdGq?$kFUOdbh%z#m?}bvhp?RZ zcFHcTJf$rG6(BcCBk&{vxE`0Prb|nS#EryEGXsi-SgWG>N_G6qOjKO*VW!n@REsFWyQyC-OOxi|L^MmE`mC-myz=so z-h21n{f8fY{OK5L<+atiu(8xb&qRIdrdBw{v;CRcD529x_p)#%WJcL?!!k2T#N*kQ z1Z`@O{!BjR5$O(qXXj@+Mn9e7=DwfjVd|N+R%E2Q*Z;thk4OL^(xJi<9_8mtNZfQo zTidtM={yiYRd>5t-H=(w$Sh!W!J#msQXagbkVH5!Gr=Jnl7%;Jh~N<#-no)IwgJ9F zX67WaX|@^NgAj^)yqeC^>%LH{yL?NER8tLa1(l3Mfz62d(Jgc%SRSQx8+s2u?yh{$&H5RP>qQ6ji$0`%6x zqxVjT=7EH*@!a}xU2D8wEB~6z)uOjR=i#+@DTPlWBoezDK$Zb->b-PfCCZK3XU8^C zQFCN8wcc85?YJ!JQO20MdflR&*O$xEg<06#>h^+2BuY;fAtJR=f1V~4-;^~gFL%(b z^Yg2rW7V<;(x!Zb1dIqBgN64~--LLLcRZPgx@P8X?wcA7Q{5{wTN;-mT-6egnFzTi zPgqTB-Gq!|tfk;<(#p~nr)3sodZvf>R?#V_?p*{DfuR0tQxkP3!csJwDOd1xrdPC4 z0ut71n~=;Tj7;2^)*@F2bRoC0zatU38vWrD=gPP@lyerbB= z{!<$ZGnrZA877^?s%L`v;Gg<%rjwzhP#HgaFi-i8@P-S(?buN-+|wF<``Q zzYDdRRPzm`;6G z8%201{8$kKYV!Qzo3H=u-P?B`KmO#auh-)c=IRv?X}>=^u4_$MK78}FskeXp`u^7s z9j%C*T1;;=!*wW*5e^miFn%05Gjp&0bO-uf=3{rG#TsYO%l+|urV^} z@NE)8TWAjgCnOO!MpfNSQ$(z$#g<~CNm|_(wfL;PRqqW5%TZk>ftuje;kcW-nQ@ak zL^1%NKvdXS)D^%b;GkN`;g!@DwNQ;95)o>If$-X!xBvT}{_(5Nz4Y79zxZGOh=dxkhZ8YGjA5BsX9{F^7$J^fMd;*HSh{T@9RO4<$fQUN2sxq$9p*6Pj#yv94ZK&<5bIL@1M*jsf>qJwV z5K%o=SF9Yw%z{->lDZ;NV&yo7RByCN;u8t$C&JS$RINp|vl+2z^nn1gs>=Fu&-!$6 zJPcbQL4=#gYD&yzrfN0hYb=Ert2I+i#h_H{lqXg>QbIuGX2PgxQ0rO$SOOt<#xzal zK86+c9}yc>`v?)x+T`W|$w-}9q?zhsYZc$ZSV%AP93GId>yvpfQ?(x=>=9hG2xfSc z{-TCG<^iWB!Ocb(6ZY24m9}9mdlt_pg~=m@*)t-5wqXg_u$l)DVN|LqlBFSFZ@e|S zCnzf-MTUsDClejlrOC$YR*%L!R1Es`2^5r%x}QVg?X5kuG#? znr`lQyQxhgo`BzZ_f6eE_B=JNUa%1-Bry@mqALdUCdI>?dS@g{N2JI!b7DH1Hp~hO zuVY0bAlUH)NYm6WFR!k2y}sMcy_=awc99^^p_sYb&o}qy7l*5YG)=8sC|YW)E`69b zMgnYIF0T$ul##?-0nzH-t1io&nwWd40H~_OOhTF4f~wbpf=CGF6^?sy7N)5w5$)ULQGo<#5!2KVs8ptt z$YSc@kM2L2r*?KeuVXOr#ky=A?XV_{fPwhE55D*Fx8J4xt@CTwKl}2||M?$&sfYVM z9HpAT%!J0g?PW5F$s^5uKTRWokyJ-*wuo?+78$KK_svICV~hkabE54}NJvDysy1OF zR&yj|Lbd9i$-^rsPng^iB9M@UtJEH9B^#+Bxw{puNzE!+_CT)P01i zIT7w!w~UL!@UY|1&Md;Y@w~8v=oQ$tx&lPy^&&ANz_yihi%0--6Xp_NBfxH&uGX=o z4U`5Ffq_@kSwslk%_4*_5hJ1tSK;90*p@Crf#jxYE`+<@J(7q#)6CtpHK~bI=4R<0 zTlJO!HK_#5WTr4jD$;UMoj_V!j)&G;BG$1`GrTIfqEePC95$gm9cs#$kOUb>NX!Y4 z0L-jvNQ}gZB@Bti67C66+hsrf!61PU{h8e^Q*}goNmYoMNg@Iw=Pu9BbZy=R;3tos zK6&tvTYHAe+VA_dsqNb&%(Ck;2@_HxhB+XzPzKbpL_`oa!6Y#=ZpqSWeztE-+HqMt zvq&xpaP4fzOv9{v=m}8GoG|Tnb3<~ANXtyOXd*V$Bd^xgBh-CrU{SH7xMAWmnAsx@ z!qw^%*?@*fs|FD+8a0MWi}18m3#h$mCbTZg#i7iCO~Kto=<3NKGK9IDz9jt0i#LD% z;~RhV+mG%)xB{TV-ADg1@}(O$00APWCWSMddROy|Sacl5I9^^oy?iPnKmXAWZtiv; zee?LUZ@wL4tjFW|_3MB1_8Y6&Cl4OG1v0q>m1m_kvI#(}x)uhp7{dWsfdOjTT05?5 z`E%R?PA!6M)q0IBQkX3Aqzz#mYrVYym?e)e-2_0006B&sKgos%H z2_QW)+%038CIk#fH;3?2O#`DxA`>P#lmLX1C%2QOh zXCQHSFk)s*^8}G$Mp%xTq{y<=1A>S97(T4codC_<#+c7`b=gCLZqxXZrvMRSriDY+ znw}CM+^UF1!f*#-VoDD<#V>jW5&~d)5K)A;*22TwiX-uCG5l=i=I+vay6^h*ATBf0 z%#yH+Fj7DsmZidvL!F3PYeY202uSX28}23W3CRnT!weEjN6Or`{ahpyt~xNGM6BC& zl8^`xwR>|$LPi82p$u5o<;J{=gvE`Cag#Ebsbxg(y@t~!!ZYg5lrtYBbhjr0m#2`%q zAObRip{V4s{dPcyWd+E2>PQk9s)J5e_u;Xv=OX6bA7332V0bmkwZ9`ZWtOJ^OjNGX zxe1s2o2UV0CIZd9F}KU(;zP|WB6m|q2PE=X-Cfm6w^%UKaut^+uuqe_53_PzWh7Ar ztB@`$F&Sh{s6BHm>n0yL5y)%RA|j!xSV;-ao8}Nec#MIV83DkFfGotBnHWCC0g+e) zGRHFN9V9})Y|_RUgy_REJx^b~SwI3H=vYW3Er`4>zT@#2F%k0FG`(}{#uvm79zCh( zIgNb$bU8GYri38hKE49P+!Uoz$(@D#h5)4PnW=ZX_GYC8fJd;KCrmJpsdY7*chl8z zT}?^&@~|RaB1HX2>#&Q%2mp0om(hC5h+S`o<6)k6LOgVh@GRv;CPYvTmRW=`w-aDf zeIO#U6b%3qlMohm9u&uOj%1o@R?bdHxZM2K&qJ^jx|w)5_x%) zZmZ&%+^o{;0AM8~L^U^8M3B~L>*N4pMJB7AI-o{`Coz&Vb0^07DKX({IZV<@FjCqO zVktLHMqmV3gnJANIK?!nW?&|4dl1A3rxbG+sZ+7!W$5Om%*`|a2uLDI_ll#bnRR_@ z5C9nnfDsH7YBjkk4Z?P@AaFT8%|gv$(@~ckOjsg=5;yh}pqnqN2IPL)R~QB&3gXu3 z0#y8>uvmC%5TTt;)o>+Z(~w$n12B=WsOq+3hN#!j4Y)u^?u_K>W|r=di3yBoIyO;v zLWMk+0Ed~=(m@f>Bj6-z3wKJGT6cFLZmo?m0H9A(uYpsw{^q@Orkk*w%-qw3Cu(Fq zAe@LZOBF!@36Rq~pQPrAm=SIot?x`nLiD}^2-Q)Hqtf5ipk-Yb5oy8zpkv@keAlJb z^=jdjE3y?#ryG}ucKgZ9B0x2#x=VDeEe|sba}9tgk_g=b0kVEc1QC0mHu}=0ISgV> z_qqcS*-j|E@R<9griH=j+?)alggFq8%NicjG-Y@JXOO9hKte4ti1|3I{9UIQpL*|8 zns{bz;e%3L%DOI=o{EdCJV8 z3YirFfB?i?sW9`@Obvj8HWY-bMOXrJZ(E59rK^f(7cf*>(dqlb6HqK5%}tQDsd))a zz=>ND7Ia9%fk;@Y$rY3>+UWG<)>Ih@G1)RiBms!P-NKVuYEV#9%*<$$9EN{`hgT4< zP19S?ogvf1hmUjHWrkX;Vzw49q1PnLa&&YJDVrV5aNBG7S+gPBo+)v_f)s5%kjj}( zcOE`kFE7S2ZoYi$kKcad;ohC5~wZV}={ghZjbl}G4AoDtRIa;-*cR%1>Dp(LtVsC#BaVj?FX znJE!xmb9%f09cY#YBUiOQWE};fBvVpZrwDZYuB!s*%0n=>Y-os3|I*UjF*qt+f&=*NN;JuxWsC)2~K6)5O-l9#Nv^jj(aj^kraHcaf(v zA|gau-I_H9F5+F4?durxG?lY>`*1e%4>A#+4*L37o(+~Z$*6hjZR)!UQdKi%_EJ%_ zR!$7abl3*$I*f#hojJzX&2vWDi0z>gSjR>Utb-{t!v_*qVs1(OAd-Yd*xk&1)j`s? zX!6WPl@y-!3A>rJ=HVs#f(=mu2xvBdFv0-P-H|9GN9H6gGuI(NUm#b)>W4}!*#5N*jiI}5m|=cJ+3A>Rx_)jbEeA8d=!CaTY$iHq-1rlV5#_9mriaJ9O^ODjHfZQL@`Ls@!c5~Z42 ztzjXMn}@4MM6R|*z^Y?vJs=}onCpP82XI*zCerXO4G>iAsx}1(%Q&i8xKnGThOOJt-bgn;W9Az~48>xh`AoIXP&N+yZe z&Xz>bu{3EB@NC$FrCW#uq#6wtXnvRqk+c>_WiLWv&nQ30X>del=5F&mSKVKelES~h z#xjG9j11CU$g-O6GXO+N;#h5!H{07*naRGOQ~bJzA}US`MYIl`SqGHVNo z#iw?2YO?EX9Y(}c>4zg~o85Ygn42&GHzsnM2^tGvg`)d1w6}iVCsRjC5+MOXJ{(r* z+=S1k>*;do}ZKh3Z?h%PQET@-8HX%rCorhY4#~cVaRT!2h z6VD=m;OP@HbR1^yy#CS)w|2k&_)ccXI{xxEACK?9^~c|P_pkhuukSuQ9j8=BNoG`4 zl$lQsSJz*-`I8UcxiQVZ{rcN`PafHES=aIW%g_DMTepY#m)~9-j#m}@SE)GW)_Mbk zeCAXkBw`OEAP+m8@{WLUI`Q!ocO}dOCGAFOjfiaMM$bcVui)_9l6)hGb7M`^u~oDU zGw=<;C?f6#ClXS9wgAqj3^lW?NE)<~9_cQ4+0=atu{X@^AfZa0?Y|NZEb zPrv%o##Oa_W>(|2XD-;9&AM+-ch#2Mny$)BjHqsrnUt|v7q;NGu#;=In1HE-jzn(G zgz4dK%u+gl3e+kSb1fv-b?q#ha2(N987U%MEuM`eVzV2aoJdgTFZ>f5QfUs#omECM z=FR5@0PDJLW=+`2ekZJVbu+Obnrf+{YTRd9Bdo0mSeLc+hKR$Iptu6`tPEe)RYU-x zKwiI0H7k6KAiS=2p6B8RIY2@w?JNQkiA=Sw^9u9Xd}vI=Y%95l$5@Fa!)rrqi&aDB zZjl}qh}2qN*Q2?a``o(_3zLSK*|!&0h%on#URgtqh=#RVG!d!T?4g>O5LD~%S{adS zK>zLeiv-OSMzmCA5i_-jab?_O%UW!O^I3SRl?jhnBX4OzL!D@H%h`r#Y944 zblZkcp$fzhu^x}lEEQuNHAyPHa-~7kjRHhtjD(z8t3y8_YlUx_kSWAlnT@$FV?Xso zK>!Ftq>^RSS``sR#KY89+|@Op;r57|Um^c61*P7+};yI^}ZG`Ds-%kx<*jSN7-(vH=D zy_{?rLAVVUiKvF>h&6DHM2M`!udO7=%)@bfqwe81cDpyucQ2p6wv3Sg(j+|qQtm&! zG!KCEj3%vA6kEvq#q3B6d?*w4(jT;b{Mq)M*A{L_6ZR&j;%EXB{b#aeAPod*- z*x5Wa5jQ&y1EO8;Q!$Xs`?l1^P44 zjod3Ax0xA0eGVYPn|-BRJy4dM8dYsqNZtBSCe9=WkBkO#nw@TEV)ZBhSs!@4%*6Dp zN4Jb7t%R(xnTAg_0aMZN>yNjE+16?+JpeolaE2Kny%%8vPF71MQnd(YW^>B~WUOvO zbr53bDcu*h${$O}p({aM+gU{10C>7CwS!4SfvQxj#79iL=qTr}SYx7h-hA;pZ+w@9 z)vQnR-`;t6=i`sl7Vl}{TQ?ceScrKX2N44T30hzh5(};M`fhA*u5$QmLl$d}CW(I`2 zX_rLBqYx%_Th}!aJ<}pGa#@b0a&cEc8fJ|&Tq7}{0O@d8u9*9}4j@=94#!29B3+o& z9U#{Q2!Ifl;fcWoF&`^8L1rC~&Esn~&oosabhm*}BN_K-BAIF7W=4QbdPIyE!$L4O z;Rt}aCjcRImhx2(Qx-ww#4wFAzgTzxFw|JcAxoZtM4)DvF#Jf&+`3xrVxF$0NOwJR&j_Y6E8XTxou1Yiy%nWmvGM_PF6^MwqtmAIP;&yGfJ8N>*J23+$G>iyYtBcCWNJraPNC^pcj-h^-GnZR>8MOQL5d#t<|ii zzJ%m%(i#8^)mpqIz!*lzYWn^wueClGcjnVC?*A|U=HGq%(XVrPvY7MKECN^IFQ`yfL_`H1xO*frCSth}%st(Ng_(#s+&83G&D#@W%VpW94r5(1VJA() z5s{oB6A6bY6oChkh}4XkD&PEH{Mk?b)enAhZMU=VU2FgPmw){azxnl879d2TWj!)W zL;?m<+Bz&N5CSmE?Pl)K`$_UvFHu@E0ed)8 zuW@`iKmwhS8}b-h1>7{X$iU1l6rQa@aC<`t#$GfS&+M(`iFLG>T|#i{wFds5|Equb z#_jizo4W6&{;&Vj$A9tQpPR9Il7MW&Ow?$37NLG`kgh17$Y%^N+_q!Cm;cbR}Aa;Q~%K!9BYm@GognQNWBK|i7< z(ivy-Y^G*(HZ?URN=TIAq((+=Y|gW(MMmV5n{pP2FavsT#oTaDW=cp;cZ*%0N=Md2 znEAM_$VdR5(3yboxN6mRbub*qs4d6qa7zdQQ9bHRi3~R{vWmJ7v$8%`&havaLqd%_ z!x=%-8_%0tJ?15hMk9+phj3QO}($jgNHBaQ*Ve=eVh4UVrD^vL~^%U6^aPvrXDQ6 zP1U&@XaYD+qzhH0h7kpvqY47sIIgk5itl~))xS&lvv+QP2>7=jeIB+>0Dt*6zgpgZ z=X^H>q?u2>Z(B@{h|q}3~N+14q;!wQNWQFEmv?tsd)bbB{7()JT(vikhF1HU?DyAHn{7ckTQf zAra6sxTN_2B8?y`uRbA#7zwE{0~NQ;JeUxQLKns?Lha`D>xl^nSC_}D<7LrnBWXAF ztD`@7`s9nJ5B~b&kDgxM|7SmV>;0F0PKdY8&P4j1#}EJh&KKkAGQtut5=3}vtpcx3 zDZEh9Vt~5)Q4qUG0C@V;rlEsSNH{SdQ$1h{Fh?ZZyvsytj+lkeV&Y*|$xaq=IF9pO z$4w%IZE79`6OI7<7eD^lySKkPonNon$@lIb(XY~mxiL}XCYNPmVjQZm!4Tl)*_o=< zsGpgh=|XD8AXq*^=+ZoL83U0JQiRxU2L{n?AJzWUSm-tGFh zHPP@fhFO%7tLno(wHm~@IRLiSh`F#twGAhvBp^h~AVzaf2P~TnQt1c_M*;~gP-2`~L&DQ5Y0O*+0R>bSLXFtcmSU4(`ib`hh=6Go)fegR-0I2+ zGspUzGTnoi!nW+0E^VBA3PK#=5q0OG#tu*IP)Uk(r;$)2+1|UVR?8vMs&pPvlhI@% zh$Lc!B<8EJc=)bQ(qyQq*%o9C$OP(EmrEqT$qc<|`%Q(pJn`m^jMZ)?pxc=HTzilT zD~r|;v9r{ZjYzAmh}fAoM`9CIuiv*d@zRt5st3a632rrNazLPjY{cC9uH}no`}4E) z?&FKA!&1+A>k?l63nOMzEt)+MB}8aI#xp_IX88WYUzeU8m`fdvwcKHmj7%>lK5!Y1 zAdnEEEL`wx%Uffu)>?!EZLQR4p$DyZtFU3jNYr&jz?BFR{Dg#(F#jjqyeNck!N)T* z><|CB`dw)o32xf6aCdX0Oc7)XbM75ZW5eRyx>@-#0>Ito-ISRTCS7!dnG!%j^_WS` zPPYJ6#o-ZMWW*>dQJjM1@~*`Ij^0L<)YHuqj<3%z7sEgUe)6B-CqD>=ZJ^tJFbvp+ zTdnSvtkzhNN>WW^RdFcJNhXsyM`TPl?!D*iz1LcPSm&miPYDntgEu11*?X5(s;V;8yxd3jC&55hubdl4Urtd7)OM+^B8QNZ07B#_Dv<(5R4@Wo6Q`!NJ-MRJP!M(+7@#Y5~z5m%hM>bn*td0Na zH@3XIzoyIn#4_{&? z0~b3+q@>D3l1qruOht_YlPl#B!9a?LAJjbOrRF+S|1=gUDQF0U$f{_nAqH<-1!QJ) zxDq3ECHu3+0R3g@5pD8-a?j{6KhqPSs6&KE-O>meh@x-K(1@sHiGllRKU0#797GDa zp%GaPz%Cq}}60S@B1A4(a#~2lT6e4=f$u#>~hheKyCL zf;6leHSa@$0f<;rS76!;Ae_NVNP*2ji=Z)>#1L{Rff>j(4;FkmLDV_49I=Ro5Q`L4 zp%6rMG#V{(?ozG-vl0;%&3@EFGEw9a}2@r zUpZ^wz74;;4}ypWW)HuKYTpAh%OYS12vrCkV@6^(g8TS05UN2@2^>TW5XmGE6;-f> z*TS;`s0^yA=FqB|Y7+vX1<+Vki((~}$jlT{&W2zJl{5HlET(GO*J{nw4C*Qx zfEUnrM#JruK_I+o&~+Ud_9gq}=tvN>6eNvxtqMTkuSNCi3ii96Qi|6BnWNKo{pQBZ zv^;DfqL#uO4KU@x*e{MngoyoZ!ps8TtO95CEEg7j>9QgP@$m%;nS*Zwmxo|8v*0HJ z*DSd;wi<+PksL#5s>~!p08rHtmp~}T>G^;+#!yt5*?aGf7ct@(BLY;!E?%uiRSbbs zm2zsT8kkIkMgvnD#7a&5x)!TA8VpO8CWc(3sq0co48&oqpo}ag%wvavNy@RRtUnb) z?WS%gAi6&UOvS1gM74?`7g5u?3aXG*rRdTAaY`u=pFG_C-Y@9eFFZLK4o~ zB28V@A*3R86}2ca8=|jLO37fbHXPkOIQsPNe%H;NIBlv7WCl`73{~5v5LtT*fc0lF zzmC@Y9RJf5-6Zw2bptmKOi{GfdCj0HKQ8Epg99!TLcgT zha%$BFe0jB%}#d*h|D6{S-`|Wk=w34IXU4{CgVvJSVSKl9Le!MAd(-$i8JD$ioPZn zA8yke0D)LRyOOz-XnkUzDU{rKjU5AbeHvg%~KzX7lc39s@bn%Meyq zRyH?QDFg##4u^-+gQG*sV7W!4RC0_F7%pEv`^2f!-W?#~qxs_Ca5iffxs=(Wn{{b^ zJd=_{6e}K$h8r8JO+6%}SxU3n$>O+8-NLLVl~u7CudNk>iV*=P!$@^#h$2TId^9~d zm`-(`peRU*G0wV{E4p&=+-N)*R+XvU+dIC0_ijlk23FMqaP8u`^H(m`)er%W=8Ly( z-7Z;u9ea9njhU{WUHj%sSLeF}j!{$}9Ce?3_&!MMe$3VNmD6kMo9mmyW(bI*DgZOa z7(-3WZPymDw{P5@J$yi9MN-vN*Dhap`qC3C;|WJDq95L${`HT4g6*+;0?@3O{ll-k zc8sD4zd#`lM?)6|17auoyRYAP=P&=<(li$dfoEN-0!-)>rX55GE`m2{M-*z52HoWwjnTDo#|JVUto4GgPQUU;rX6MUe~*Iq|{Bss?D_aQYku@HiqfCovvG2DMW1c=R`>Do@!sw#fr+EW4SlikDV(MjsM zL|BFB|JqJ9gy3F6x6?DR71Dv((-@f(1qHVu&{n^uNtFey$o5KcyD8`Vb7{bG& z*#~#-zwyCG-SIKx460J(H@^Di)0^vctbEcZS}Kl%X4tl!fo8M2M@O%H_{r|wdzFE< znFbV?22G50eQ)={>Gh3a71fN1ixlSg(sNI|^3;>tU!rWn~fT115SvyUJA z-uM1$arBUhK~Yr*gSUM_j0fR!SFe2S>eH7twnc3`94S&sU0{CW=I+1z4}W5_L#o0T zuRrxG&tH!*j)$Z5^>rXRIy#ornb^N>36>NYhU^z4<{5GPYk5g z-?We@rBqV+WcT6k{p5{LZhUxtbM0UJ`Y*5SoUfaq0!Wvpi|+p6qd$7LX_McE#{v+n*E1&-~H&F5A*!U%zpFb=l=0GzZOim;P6$B!n|Lyy)D+I|IV)V!2<;|7f`R1#d zKJTo|ckb{14~MD!?9EH(Hh$+j-@0`Ayv30M#A?U{RXySmMKxBHnlZ;L@VkHY_Rs#} z_o2-G*)MtGXf#}M~ z=+ectU%Gx(;-HAsRm?>RsgB$#kR&9&xLEwk^LXpUqksLzJ3sruU+H{Wat>AauYdj3 zue|VOUO$DgZi`HsK_@z$x01Wn)$!Rg`c@p;d=GrF;q7X!{mdQM^OhQz1(cCp_2ZQp z=HLWZjscM*Co`*J6f^e(AcHA%(gB*80--B}RmJ~vNP&nvS33w{*3N+l)BsUSF;o9f zFjqOHqE>M%V!0$UUM9uBO}KqRlaV+S=>oH31p-sf+5Hx!bA={7yqi3>3Wk~fY1%L?*H&H19rx%q+2!b2Wiy`)cv*^L^r47~_qoUmSSrRuJzX8aRFK&}JD)r|1j3dhUq|SOn7gh@ z&extk^QD)b|LME$KiZ#$K)d(u9G;vsbwh~R1L!VIF;FQKIE0{p*aP0gL&d3`fr!g$ zd_>I53g#GZRVkuXU8#s~?^G2Cy&0iE{Ab_())SX5 z#lfVXjW|V5%Q6{l2=L~e`=2{|dS!E`P36YzJHuAjN1XxL7!rb5l4_yy8()608Lhe#&P@sa z-9!#B z_W758dgIm~{Ou19@88!Vpk{z6EjC6&&r}2ot>#x=y7mvg_=TN~)q1$X%}@o@C`6}u z5)tK;su(#`b6usCclqQI0wS`na?KPGpLyoeKl;iS&z(LOCY!`O%Q~tnGfAQhG@QcD znKS7Sf9sdN^x{*O>&a>>5UVDP#{d+p;!*}p{Cj84KX>86zx(MM@4o-e$>G8IozwOD z4i6_Om8z+v6oH~5ZPBf@)ylLKeQD?HQ*jFLZm(~QcH*gX z=bpH5`QLAy{{O!JJ+k(~*-L}1vvoa^k{+F$Y)wXsRBk;wxV*7)?`U>$Yp2=7oiqB> zxidew@YEmv@Q1s1KRLI(jib$uY9_AhX0on4T1$JM`t@R1#b&%329wVYPc}yNXwaP5 z+|Ew9>N<=umol5r*H*@1GD*d9PR&@6s&731>_7STtDEPZ;lXHs*4AYAXWiM=QM0yH zRJD{i8ci4Nu&yhNYwMc{!oT>fuYdXFZ`7-sTvhjX4^E8-S!^;I)j4T1=|K||iX;wo zs45MyOCb%7AOJ~3K~$&)u^!JBZ4+xlIan;tO~zGG#0J2)8KBt~ zh5z!aU;JIF-u~X7lAQd`cVB(=<*#<5tqim}7*__w98wTUPv)&DY!2%#=Uk)?tYBT2naK=ukq|;LY3gQBH{MeF#)WNZ#<%vS zmb+H+?))T6pLrBB5klu011)0oZad4IAbLuAx2-B^>p{P4Uv~bJkLa^ zKT98fq)SVXgyWM%{~GsA5C9X z$Ftz2$dV9N`ORHa5g^SF5uK|tT`Y!8<33bSMGhXfP=rXFMXShC6cGkZ0|u(1s!sNa zA(Z7y%R|MbOF>_U|)#3JHFFt0|qi(5q8>5+0abrc2wQOYRaFoit%k!G$7*qJJ{t|lNZGIgnx%Bo)~WC)0U%3s~s`quTPnEpS1aV$U>c-S-!cCK7%!@<-yYXoKwkEbP< z+1!S86C!b45r-mWI-MpF?t>)YuCM_5n=fDe&Xv{i=?hp5QV~KN4acz_4y)L8iK{qh z8Z(tVHzV!L4FQqWBl2?YKC(mqqW(O3yuApeeVP`Tq>bkPXDw47csu(fu z&f4L?B0&=Iqxsf&RK-vOtd2%VrY0)p3J_)-4u?D#{r1Z*e*Ed}m*mq|KlftXJdenx z20)>TIeBO%FxlQz?ml=V-3$O!O9-go1!6HnE8>a&UX-i7NQRNkONJgAAvczYnj#bQ zdMmZ#2?C4cSw>bE|B?K2sd_isTruj;UVG`+LGH!TZqTGJB0Ja1Dj+7>xA8eU$X+(wwr z7ETIR(efY7lMx_*SrJ2MbK(%hNscDS?B_G{wlNq0isU}+Y^GYAdQiHBPrh;~N(f?p ze{(U2En%WP^3T+HlO-o49~}1lMrM>`$mEEdQnEiQf{D;_1>HAIduA;nk>ng=R5K8P zz9>UL;9Vfi>J|qzEmE93P6(xFRYlLOxJ?WYMN+70*A1DfvF|(x5lkfITq7D-V9ruv zRjFzuBBEh%&sz5X;mDy=aZRkJf<1=b2iwfdkeSFe#wlsv&rw2D^LhjNwK#^Vl=PF= zfAQ?Im(Q)Q5Mb#91BDp;GY)|~Md{Q0lrskAzRJQ$BrGj;F-BDY)07GlnwWWPCj>{u z1~HC=0A0=l2lFBsKo)I65LZC~GLae}kb;UrRv-js>WWq|6tP?sOaieQYmqGU>HU3E zo3{&>H!r`t5Ms@niy6~1m@iy9_uF6p`v3f=f6hPv zFm5U-N|CyhcD6Qt^GmO2HGb>vqnED?m?I;#x!oR*JcTGCqb8&T)5W5cv6!J-3jB8- z0l>zqga72KpVw;j{z=-|=)w2%MNTP!shK2{`SI+_&s{rzdTTHo#kv8r!+Fa{5BCqn zY<*O%jhnsMVl*Dt&5%R*%IBWHe(~J?to!ut!`;K#qH9m@Y+OEjYIQWMt5}`=EU}hjvk=cAU8jrv7{IlXp;0r?+{y%7HO;YgLVixzmpirx9sqZP1Lzt?2QhJ+-l3 z#O90cyDwaY;l`}(#sQH719chRySM-8{_)R0_{<)BoN_wsIw|4~E{CBuO>?fU0Lgz9 zOts7TB&D5|m3q)j=jA8w+&(zi-8-Brz$=%wu3b6bGy?#;xV3iv{DrTsuZPt$T-A{X z43g4MZcYE@#_j!shb%>;%;w$gPd?DuqsPHjpS^Xes)>jQ*Z_Pk?NNABHNp_8loE&{ z03rKTvPV=PsJROW!Hr%_XmGQ_|%u0tu3O9JG!>zb)Ep#I~NbSaCURC-pI;Ib8~M#`-G0~-C4A4{di2RT166( zgTs@w=+19Wp4eX7ZJKGjkW#vo)qsHA#%QWdtlR)mA*dNrB_bS}eiy6C#9$y=hXF;3kNQA(oPes+<-4i(}~t z4}=c=j)y+GUl|Rj^F_~)wZ1A~3dm$qwD*j`G9ODEdW~+c zrv+2fs;Y8P|IpmKf&`|fCHL)KLg@b%_?ZZiv}C9I_Eq3z<-&kW6|7h3Ip7$)HLGf3 z{_q2XE+yY&^zip(KESi`?uN>eOo0%(wh*&{UB33zSDt>Z8Lwf=2!@EF#nZn6CSniv z_h-4B-`Z@d8Ua;{nXxNiV-*lpB!tSp{UJs$Ftrapz4bS5zVT}>J#*pGC2Gc1H3&o+ zV&wejXwiuxz~&0&Vs&89%0!Du@a+)UnnfnmCs+jbYUiY3)Hp``EzPPnMoUFUEXm!v$nlDzG!Mk^lfA9659X{G4!nMKR>(5^P z(o^S}!2pSvn1H|VD0tvBAk(YA|WQ~g(8xw^HziOrap)qpwdos>U#`{Q?S+?*fnv*rKp*S>t| z$)~H>Y>tLz`f$4V@UvUrxxUJw($YP?->d5RxC$X)4-Ew^83_nTz=&`>sLfDv8V?$PFjp(N5JzU} z+JpuwR#eO&r4Fj_ACVR{m7G$VOhzIl)Xl~9CJrYhG*yDljkR+Vnyjr%>vHN~e&^Ay znu+;k27`(GIm85w$*D*AXrok!MR_K6sv_c*9YM9!+<70e=zT`i?lP3?bhk{qHU z5Spn7Mr0x+7;q5p1E?UVU*(*}(B>4G1II3>@*ne8AM>&i5kX5)=gF#)87Uy3NYB-K z+y?XMhne+mHAEz`l4pm<{SDt_Hl3NN76otXs})f*4Q??*@A0E&Vv_;T-zAeNguuLL zTR(#6GT+z_Gfj&N-kE*m;Mi4M;*^M}$1fnM8Z%)ARUsl!6G@(uaNfP-eo%~6sfsn|M=;Wlk@!+4} z*2BHoVh%`Ww>JLCSHEz2ebSX&0kHO$5>c%~P$V>4bmjm4!5cq$=NF}$7b%-Nr+@A9 zpL_M0%WI>$NSQ9?8!MBih8N5ri=rxqP_+E{TOa(%&)-Z(hX_~=>Tg_s?pI&D8mj7< zQ(IM47m*j9z7jZyX_r$KV_j8Wx_W`Zu&Q^4U)n)-udv|NAJ8w zXrI12T8Cf#=F8Vshm%QFkf|9oAy!={U6-1{V8F3U`L&Ne{_y8-$l+%IaG&C>8}B#2 z`pp-wJ$;g8YjuKwU%YY_v^XJpQZb=P&N+3woZXpP5lLMas;13lD6&}OV=ar5ljFrA zoy@jYCU*|oKl<7G)AxQ@(wwVcUpUuPXFVH1M2{BbfB)-W{P?vWgoigw^69lnq?H@Q>V7Wkb#50y4s|F z{ox&b_XqjlV>MHd7%OpWn3;+MCY8d0m)KM5S!SS85&}IQ#pPU>v`FvSoy$TIiw~S# z9cXF-UhY>k6>&{{?|?GPxrk|9RXG>ehMAfes7hOM2=Qdrfon*ZnYimx>Jos(5Zx-^ zwHYayh)fj}5x9?(%2M!MGzQA4Fp`oKDW@l^E5rIEl{tW@nRSA(h@e?2hzO#^V@+Ll zkrXa+77+uLl6f%9DTxggkPx?5$Izv<6>c`S;P|8nrKG6B93*8}{@*(ELsgHCX9h%7 zM}!Rh1DTK<4(fOu>Q{IqqCh~zB5G)=5SVGnw^B0>OvF;WrVM^#3(O*A)YMEQ3iDjl zEQ|Vn7JYCDOP`&W*HufA5CZpNQviUn#4edxn-e0chtIu4<*jQeDt#-7dNeEg3!F<4 zeJp-*P`>$6(qi3|g&BPo@f5vnToL3W4hGFK_3z@ZAngcZ@Cs*2f3 z+b&Ye#3TH>T2yTjmulIf#qpDV;P76Tr^R^*93y}%rK0c{y-mx%eCpE6Skx_DK*Xwm zXik(mI-I&v#)kzSVfP;{$C{uT$K|*lz$u+R;ufdHhCs|xj0}7zNldCGWpN;kc#2Nd zOqe6P`kBB?-9qo#MWeHF;t%rak;fAfZ7}a000NKM+euQIK4g^gkb1gU#HvV z1+{Jq*?n~Q)<^FzZoWsB25JN@{5O7j@PNy&e(d+*Go`K9Yu>t;vBHTfonDgVA7Tw1OPe zfDu*U_4jXl_WoOC|I?=~oj$X`OKJ9u znS>a~H^tKf%AJ`&YTvl=<~Lq=7R(-=ELNMk>vGAthg6H~&rTx1(a}MgKE!r`h(@V> zaPtp;9Iu|+THV-Lv?+_MuS}LSQyGs2)025FIhWLSEg2|?7)`tGd|e@j&9zlRYP(z@ ziRQDD#>Q1>n*9fdM-T3Fhxdz?5W?}v@hLIaPKoKq_or|E;!VBz^K1qLzx~Z$qIz&| zZ+|cxOh%J;c4y!F!4Glo6SS8Racgb8s_Lw8_u-@Q;hjZUw5E}RsQ643oPSO>@8&9n zuo_hn5RbaWN;|dO70LHc7CYl1fML!nli^^r66)sE#>Q$zE30dWG$1G{OoYUymenHR zJV`q}o*zDt)FM%ESX<5tR!Rvm_}HnPw?1(-vp{63gb6Kgx3GHL62Ed^lftF+Ft|2~8vf78QiPSD(9Vs-jZIDysxye|mIX@`RC=(xog? ze9%gUE?sa0Q;|$S3c`val9M|;Am@T;pu`BJWI>F9<~h%&l5@&gRfHpVDdkkE7@W3I zM8!lch!g}&xj2lBh*Bxj#lp;{sa{(dpF4Ngae~r__lgrH_2h9$X$O$B_u2TZ2s8FT<8L?bjc zBXI2=d8fALVfLd84`;dYCIl+E02mO3z&Rxm?YbOY(4n@B+PifJm>AfGRn^qB8H^fI zRVh9BHgze)SPk4@3Qeq3#D@h)Xyk4RC8kpRs7sMZ%@mOl!Qfy%t0^ErQ2{m28i@HW zTl~Gk%TLE0GD{tt(Q<+ByAZDlElCW$x(H12J_tGdh0q?rIa%p>oLZI zmXr~l8BsIUqhx;EayyM^&pxN1xAGV zY#xT=jnS}_GFv2-vdF2Fj4^IbCi6v`OQ~7oxN&KLN$yUjv&CXe$bhLx$$GHpCKXo^ z=kpE#r`0YOSg|XFZ%A-k;5$E9aWgh^Yb&yVG{WGF%&RAV50o zQcf8wLoqd*b&IHrwbfyaVSR1<)RpIkqjjq4x~X?h+CO>y&F1hUigKLf3;-aeqNSLX zJcu^jSOZgH0#)LmB1C9vA@IBdRI8gvOl`8#8R8wYbsvy?$2pul%dM?Ld8j_=t z41kg97*olJSc=3dNG_%jDyR67nSvn&(xtF(P*q^i=Crc0iilanb#ud55#gfiVif`h zKwK<3@zNksaUcw0QEAhhdH@Bx-Mf@h$3V>fa*A=uA5~$FNWD9?s4#IBVWbd)7R@Ca zK#UxTBC&swZI>tn58cKXR_XyWpQJA5971gBT1Bu=8mTHeO43Ze{OpG*ig zV8--lZZ~%i-?)2wakRHK8lW!eq0WF*g`!|41q{TBA#vp30|pUMQ89g-jq-Q40aPJm z$?Dit1C;`Zk}@DW015#;W#-TP)FuQIu(FI9sd|%&wG=T$12gfhUr}WWma|gN;&4!p zI?CQ}L_JI%)QY=3z2M=>Y9J;l%8aUjfqG68Q|YfnZb0o}^N%Tdi$%+brWUKvEjk2R zfz`#gMs^V4?ayEriJX9$JDaB(8>3TR_HwQ7_I;k_=ZR9XEh&ire|Nw46NYEhDvs@<%TkE>g=a1doA~MO!O8wn z=~4*6taNP`LuhlJ3X7a{rS#%2#^QRIs7BBrRb)hFYO1Ozs)&@7 zOIDFs)&4tHRbkXrYFcxzJ}xRMdc0VyhjA{QnRTgn#;@xV0OXQlU{f2^^`qlyWNxS` zIe+|czbrb6VSPMqlURg7Rk;~{G8#O+HF*tSv1qr??7aBo(^L;O2AoO>A^!PK-nn!0 z6Y3U#DB`t#1%Oc%v!ba`Ro%Gz@Z9Fgv*)*8eExEs+Yj#^93C8Zi}`ReJX$O!i?+kl!zusU)c+_DA%r`A`#boB~b zDP~CvfIV?~XV^5RhCl(~{k!|09UQ!Rev8H{At1-FI;cN);q+ovhgB$26rfW$p3lb| z0#cE(G9Kc5W+niL9L!*AQor=fSvyT&MM~M5E!xGR8m)*3Af8=mzI5%%qftkYzJBGY zj)t?7B+?=B4?ex0?|r;A3B0n?b#2LsvxJHfV0{!Xom#I~vlJQBwZnfzwC5V5xt+d$ z5);%_Py{XJ_$@Hoo3*zO4qa=%~%AV3BXk4A=Aq!6)y2JWSwy-`Pf5DSletZF8z zRgC^Uldk{(AOJ~3K~w|~0w2%j!=@1_F4gcoZpB={>M9QE7(>WKn!vqvqliC(R8>I7 zO$BCwNt~jtw&X9FKdS*us@UdSapPt85Ta;rB2PJoz~0GpK%tq&5Znub0L)?8qeTx5 z0Aj@)nGvyO1|mQ*QUFu|F-wxc`1MEmy`Ovvcz;ZMc{I7VxAHf)j{fZ3*VD~6$;nP; zpnZcUa%HM6MAW6eQ>5gaI0Vza1-h&wKoJp_$1Ab?2E!~+Aro`FH?QmmqPe`DmFG)B&)gg%mo z2mw?C!6dti!Bk8Cvxoh&xSvNZ6>h}r!l9B229_*<5CR1x09%`kj}DIsVbD}3vjxXc zS9QB+0WcB|>bgrQr8F82Pp^$fO|`o}y?uDVh=W+o7u}*Okv++oR4m5WNd|xbtg2+l z%pnFT#hGC~1#MH8b3vk`dAqZ@`ne}AZj1(gbw;G35`gNu_H{N z?Us=WC-b|d8QgzfTs3M%0ZQ`MFM@gC78MOhscX9;qIzn5 zW7f9QMQeyvU6-~K0Q^7$zm-x-NyRzjUZnft_2=mj{q)-P^Jf497+l!d^vGeC@=NDWbtxS$IxXeTe(}lETdUX3ZNB$# z|GBfLfbfOO=f8LU+^v&+L3{1vdmAUn9J-V~ez^amci&$;xM`ZTKZI#1<>L8MmoA>U zchWt9z(i+O8ZbM%x%$G@Yp=ca*1V(`Kw>B&Hy=&UUdSry7~8AoHt+3Ue*c4aHa7-4 zD=Y8Zy8BySd*Riq&jW{CN>x<`kN~>bd~H0&K!Yj*U=^!BedpuDdmk}sRRst`X4afT z)5I9F%G>uI9^Jh|gkt*qGgnMecJ@ckFZ}!0QhWR$3!cs5cN7o5oLd`y{rPA9 zuj&5n_dj^&!8_s2+ogya#2BSpa5{`+V(=TF^V$6Val1MitWH*r=IMja9_7Q^07}gM z1asIs5vjq~U%H-3{^ah1^Xn6eP1hCa3K3|@cc;^prp872_wU@Ae)PIX+N|qlW%%Ep z`K@|oRogUcyC&9I@?ZSo#`Bjp7lL)T zH6%oUC8b<_G?-GZ0;ypxDTGj0^&*vAG64di6h*|W*#NU-@COJI5qdJt0Q(Ic`U}+% zP*h`J1rXIhNXUd}Cd?cN0St*nO|^i7{k=&QLeAp+zEi`&9B?+92aat?1Q3_r3nvrD zD*F4Ii0%Jp>dk&F$*w!SHS8S`XS#Fd%{gnx8nTK-ai%CrErH!~8&acXt0BOE{on_~ zhJp5@{~A9SHtaUk-7su4V0J@lwPuMbic}TFs$x~KGP82JH}8C=h}e4#e%Nt~0$<1% z0(s9l5qq!o`+cAJql42xpA#}MInZ2SesPu-FE%-h$728&F;E2u0#9vMA~2d|=uHp; zA~9vju0~W26~hv(>>&{XAr^0Gap@#Yg?c0+rrCgsqlH6o_mq+&sVX6qQVF;cQhCjr z_Z0f?^I_g@6bul2TH&rmkkqs86Zy`w)14Z|gg6 zzjL+WkDtESefI39PagLHTjdLi z+`4o9JFmTZ(RPRPbs^FOCNltpz#TKGnrK;An!D$Mnj(bqQ&-JmMV`93yZQ3XTiNg@ zKYOI2Ww#(Xcd2J*u*e~*stli&Fi@8y7L&7jm)i2J2f&==i$9vGa-ftl5du)r45}2b z7G@PJ-#kK5L5C93v$84!SIt^#<0>`Ba+NU^M#?J1blr6+j_NmFy90n9K0NAIeeSzU z5xpS#{%n?7d2o2#=e)Twy|z7_PHIB#Q$liLCP(*6r=ltX0wD+T;tB>r05D%HS40?? zBV%Az(R$L{zj5_%AAY)6^*1&*%z*&Lv(fK;_iO(~FCIO3STX@Q^+}|zV^dWnc=`G9 z$zr)EO}jFg$yp?)*i;a3G8ujQORs(X-kZ(F=HYyOZIi_C@xk%`{+B=c?|$_wyF1%W zUFR%fx>_$CacgJ0s^gblz5N^Syfd3^nmd?Pu}XdafBofq-+blfYd3c4y4fNEf{Wv$ z_s(Cuer0-pf48bD2bye8|Ht3@-jlDresHlmTd&U!4$A(1T=BQ>Z1}A&cgf#g^lWuO+2tXBVf-#s1!v)neI; zRw2$dW_z2{-~HCtf4aN*vxERy(z=I#``16Yxz+r}Td$m~ z`>n}n+SH3St=H@I$uT3Y5z|XIB&U;gzP4rcXv7>YE>>wi7s<>awH-R7)S)@Yz)YT` zY%~hb*32a5>(lY?{OVUWws%LPYPz{S+1Qz{)&yP!?nOR&{P5Z1&(2O>nr`h{U8O9V z^BXs>{m;MskNa+IW-;>S-VLrQa3p5W*#J)0Ywf$ZF-Av1s$+BS){TF;^=kl%h|2`? zEU;cTqo(U~9l}fdSN`R1{G;_(-;$I&NoK}?lRAbNIfmTl|NF;3?=zs=-eeSGFc+89 zryeB{l3$i(O|lyTgCVtTOKyAPYTQ&^)|3*fxe6dos|pd@l)B{w_ZI}(QC^)d7H8+9 z?X^*4CexHvKYH}(hYxOi>8+V*+!|FJLa6JP#?$SKt#S2o5}Axfr~G6G^Y`BQvdnIE z?IJMkUCHl0crjl*Mf6aSDFh~OYBw8Ea70kU5Ceyz!?OV$#iM#6BIOD@88uy!oIJ)* zp3Q_5oQW_5P6C0bs$(5VwJiRuG#Zk!8FUE{Jup`>h?)~*Z=)vH;+o`&8^SF1DVpOoW>T5!$XN#I4E3WPD{Z+q-#vXZPy0{mp5g z+MgaAAz|*iEP~`^Z>p{()DV!qP^dCc!de?0ilH zCMLxb=T6AwcvN0y#b#fk>mh`)m;t1mQX~Sx2M-=Sd->LHymhAu{P1ADXqSa9Hr^OH zSPWG$r>YE-oETyV1dQO&rNl@EKui^LA$ge@5d#AnnmM6!;9?PA;#J!Q4h|M$rA3=( zs^;Oc`mE(!NP`&y37JDqm#j@hWwEXE zT^+^X;NQG|@4?B_hlkIv>}|)o(DMAw-Mjz8Kl^7F^YhfM+jaZ>zx(OwYVBsR8WjkD zBE*1g%2S8B83Di|buZuC`K`CVe*MaIaKx%^rZcRXZPqT^s_Xy!=bu#RETz?Q8AGT- z#aZOW?(}=FfA6a=-$CX$nT60)qj3z;!PlL<_wf0PlP3pbeQ9qNIF3f+^}4SkJwJK& zv*$0q^wQlV7Kp}^8C=D!?VYd2ASssm?BcHPhP6)`MNz^rn@`irmEim{K=bF_v*>y{%iN{ zzxs+vA|$LPv5JQ2=wh+AHT&q<`SSemsAGTQ?w!4zKBXkO=+j%bwz|o^x~Z6XZ)X>o zZq7Ei-24!}^71}i1qwk_X4{+Q9++Yk0kO^b{;i#CAXz9XA*$Klq<-oCy*J4_ml0bGe(t+L_|TwVl0ko-JXme zKg%!9m$$dCp3Ik{x*v_EAx7TXD>}>L!^MC4;FDjzvHR+stAT=NdHHH3mF65dxO=f!x+ws23LwTo1m`;B zRB(uolz%&bnKF*WG%^EWP7*^bLHBa+rvaFOWoBaqm_QUtAiS_R09B-^$N_}O-2-u5 z#S)KF)e>$f;^V;NfK{jprTb(6{{QomKM^b z8x4Shn7aWWs{s;=DFT`o)Rm9w2{Q*%a~K#Xd)t%Kd1u+=^4;V^_SVZ9VQ4519jQxA z@o<9jAq$$b5;d{vMGSyL$T=6M@t`_n5*1O|p3a)44k5-WR^w?k8ozd@KYVfW$%~V6 z6SXYZ1XraPRkaGyZJ5%V$uES9UeGXER3ytQFW-6d=FP`v$EWkvda;(A&GpueYt!jy zV>~KAI7Vpu4xNagY((m+ih)Cj?j8g6lGm&C#}5uJ7K;$W;inJ(u(w}*^XC4wz0w?7 zE&Hm9b=8=fqlw6ne+?2>?`8bn`H*W3>)(P?Huk9Jm%F3IYPclDukYQG~mB*SCX$7ZEAAIWw!s(fLIa;_-a(CqMq+*}-!* z1-Fkr8ol)Lt$*^?8^CydZ|C0i+dqB$`JEg4H)B;bm?e)#lg+)Wnds(?TgzoTdGMSJ zpooo$-9;peDgpFuicLhM<*LnU``2#o?%%w0(N{?YklK0r{`((1{`~Xx@*Ld9qsApW zIuI=Tw6S?}d;gXgR52{O9udW@Tc;oY?8%>f^#1(#Nqp(X{QP{m?&~^C>T$3B{OPlQ zvuxW0_g}pmFelZ`QGL;N>)c-1-3AOL!H9%4A~|-te$hd@Ot9+p==}I>(a#rd`v3je zpEPyz^7ZQ*)A4$}Zre3`HEu#du#KjZ$LGu6|C=BE-dDf$=4kxt_Qui0`BmDfM-w$O z84(jWq?DQX>gMdT7wdofSAR2q^zk>}y49zAaeP9C=kxj5Mf>!{TvqE4dLXDLTL^Hz zTDK|fOs6U5$EVBo?@=GEPc z)p9cS@Fx4!es zZ@x;iv2-cMu;}_}UAJQ1OA}&J@3VrX$s_=Ub}cETYOHOa#|CE&A;4SONW`Uf)21{S zzLOFIVR5OEA*L*5pe_!MPU=<&)jj|K%(7H<1j6zVQ?n*SN0$Ky>j)5I7@*LS!7(r! zfMiiKCZvLiVjfaZ?y4F?2wa@1Eak-kUM`z%J{XQE05~BO)G{H0TVO^&K!YNjbO3}Z zhLrOcTnigsKV?Vigh)tIRG#j!4g@4R&|)r~2|!GUR9Zw>W(Hn}V~zkuV5+e+mB>Y0 z#C~CjC4iv`2BocH?vc5Ko{@*QQip=L|%Fsn5BN0g;$lvZz}iT;^`w_I*xozI^N6{{G2o z@$~GXUv{1?*5Tgm>(kL_-pa)~F=5FSrzFKxRl>u|UP2XBS8?!W*#7SJw`S8HfB5Oe zyd}gJj~@KTcC|SjS1|&(iMiW&GIldi%PN6bii#6~C?v^T@Wp^b#=*@T2#fU^ie$cs zS98uBV~H8(^5zCW#6C;8>sKLyI|nj%26RLb4UuJlmw{wfX%!RPB&@7%tzZ{pv2^WJ}W|GhtW@BMGx_b=VP(bSbm zGVqgCI=oolySjI}mf2*qST1Ks=Uv)pn$#x;0bXiPYU1H>- zAndxdHc5T^=-|c0!-u5=0_udgvpIcbZ{wp+K6&?($G`Q}H?Qw)S6ed`Y1@=iZhIMZ z{ly|3KY8}A&Q5>#*S_`5*I&M}F$1vNcU{UcR79xai!SxzA3ZzyqaXh0=_eni`AK?t z&-;W#uDU%NfBxd^`1ox3;t7Y~fIC~8k_3rs0O|YGE{{&nmXDtkAu{c6?MSj!UgRu1 z&1tzhxws&-gBJ%M9$$R*`qgGK>DKdpWb3}`vH}2t0o9+J%>VNJk3aqB!+vo9u7w5r z;`IFR{PdrG<7>CC-k3}#RmGOIi81vlb?SMQMHRST=f(MAb+K9=z4+IEkp8n@{_dN1 zUY0RYkdopAz|;AwJpu9@8#lr-mm8KlQSUjK@JH>WK)^9>m+(`e(~&hWt@p<9@`gBUmVZpkDi@0 zn*>Zp$v=5~a&hw9&Mz2Cb%j59aTX5FvFY7ZjGuq@uw9)8TlcHw_m2-hdicrijXSrl zUf-KGTTP7)51WxX|LsRV`|R@v|L=RV?Y%Z~=*&JkSS>&Qq`NpT3)McC7*8SES{AFT z00vo&5Cc-iUPr8}+5rl`;<7(!s#;gkz)Z}+nL{0; z17KYZ8&(9O;3*QHUllWLO=rphZq7gsi-+P7!fs9>{BkX(lRU-GZC#goX*!r=L=119B)klK}DGg z9&@s%x zbm!`o$#}D>CvU&`#&k0K*8NwC>8D< zG6EPPm*uOunObN@@4WuXG{VOZAD=GPecwBw6E;LST1Cp#Q0*g!-Dj3t+)-Y@3K;2xOGyquB4(8vNcCt^Scz(6SKOlWEx zxFi>tiy0nE44X?u9S{IVW8NP%cdy(eYVN-A=D0#;noXLjt^*Shb$y>i8)gN}ITJuV z8Wq16BAI59TvfHIbnEr};)2nch?$V7o@_OvQ8}M|{OIvtfAnE8ymjO5ttDl3UjWBY|rUs)xFa^t?QkQ4bAX(4^HMMXVu>JTQ9wK@7DgP zis#GrY&mB{Li+6S;lq#LZ`;+IufP74H(uY}-F@ZS?#AY+!1b~}IC}iu*YAGy&9?xNL)Dx8yT5tAU!3mj>~IW8HE`&Xu2<{T^2GZ^ z6(b=MQ6N%P1FAbaXb5I56mb7wlzUSBjTah{bBe%w6i4 zLwV>S;W#$#>ImzuMWi~=xE^N}aA@i}i?};876`LCy4k2|0D%glR}|>7{oxLXRVnx( zIii}yD!O}@auZ@85;bBhXybBIc}@_%!}S-Gz%Mo6EhP2dFeNlbaU_l&CTnOSjim)u&vpn{^f1E{(>Gnn_j% z*qTl^MhzHrE2*nywzWN(Z0+B=`R&)PUp#&IhwuI5`QohNII0?Th|C6VYIPmE)Qf0w zCNd!-wSAg*Yakd`^-eQ6UM^2A+LTh?byXAJyn74Ko}Vt)%XLn2xwJ;WqW3~X8+2J< zedCXxt_xI_^K7nWusNM9R!d|?KoM=~DC!iEk!p^js%BZW z4x#N+&Qe$94MnP&MMbrWv5FDVwWQUD(Xjwx7OktQPko5YNKI9xtjoTunVS%am?@Nn zte91io#6OvzA+hx7!gsk4iHUuHzy87bFFSfsOILr9qI>9k55z019R!sRinC&k%?2z1r9Yo zJ^h=O@zFVD}S*&L<1a%WtN$t+&?7#f>H)fk#6d26k{os>7 z{rewBsvRkYNB}wa0OHcS=73;et6u)aKl=4sH*Uumndta@@vr{mPuuxPXf^=Q3z#7F z1epo@zGW~ZbY!k)1Z1kBf@EO*C6a{!8My|o5Q#V#_!mwsl?)Cc1_S_UBjl1>gEV0P z03ZNKL_t)UU-kXCs`_4zPrLPe-nT2s`TF&%uf6{2e3c&^p3N6?bOS)rZ2ju>8&|eA zHm9?#+2&RcFd0vtU92A+ov&7_cD=Cmirn_EjO(Uh@DfZ#ipas-h#0`oEJhGf2QWvX z=vD&rtZo6F(V0Na)>+Jq8Os#%55r=zB1KmbY2C zWOOvpCQz4pE*@Hn;LxUisPCJBdFkebFznJe#+)-CM&@EdW99&+0A@&LPX3E2Zavgftoy=o6Wua_0gf?Xy{@p zW`+3*MW#t8UKY|MCPj7XW<(r_%w5z9fG!jq520j5ge-YnS6MY@Gq=EDP_Ht5anTnu z(c%(zBovXHa}_Ia1tbwI6Urb%0 zmsuB0D`~mY$H49` zYGz&t*kDD_2bVZW&mu?^m_!CtSox8byS?e)M-kN+Lb*JMDkGaama4Rwnv{7k48nUH z+Qvh_-_1*P$_uuWnabZB0jwx7m@iYp?pe#74hL@4fCCZLNF~t+cj|ci+SbN+8b(!B zSC!V9b7l%vWHrf>%loN{A%wB3m1}hQv{jUu%{>qsID&JCuyz{P5Y+r#GjSVGR4*yTshY*o!cdh!o^(U>36_6HPUUi8=P}S5W2SCD69f#d4K-(uK z;t&Q&rc30imp*WaM9a1Z#5z_3trW18TuxuZ&K009!D9dd4;*se6H`+)R^~AP6oQ&C zk(gWRL#zs|Ly`b`8D;l5BX9_u#Rz~9>%i-rbM}6@)UI2Qedq0aF@}`$#j>4D#*EN) z>AdY9KYj7=;3yEka_j2$%E>!Q9;12A>EQHqdpZk9Cr9(cM-K!vsg^^phy+9|>{W9^=)2C< zw`S9>Pg=HaF%S|WIXF|W!sPATLMau-h%@Il62+=@^f~o)v5~8xrmz<2y_3bP|%omH(*<^OU zlxL5Rayw_H^7ci5zC6vV*!O8VYD%}q+|4{z(alOXqpm6yEk&9V=q>pSH*hcjRMEPs zeW)F{TL~+0nMG$&B5*fzsH!NUF$5`|>Oy{FLU$z0l0%39U*t~6-AeeS^yiC*wOrkb zM%ONXMKX5@f{ z3JgUZ01#pnRaG&`2w1)(eHJetmaEv{t1o8vf{tNgb>$Fq&QwyI07zhkFB?L!y@kM8 zl$e@WwS5A!VHK@{2n@I`4%zbOKq!mPoFp(+F_x#Im5Q?{$56z21&m)bZzXBu4it#U zhkA%(;cKA28gOo3~o@qi{;c+TG(ZtW9CR91j-_lNn>j2&P1tC zOpByu3NZumY&4Ckxoyio z$PkMSuq3O2*&RaQETa8NRFmX>-A+a$1c(Zha~6p)=JPWE;JVSagUe6^_Z^rcQpJqm zh!8`N)T`vkJXGtmI#E%=6&_lNo?GfoH82yAq>P0a0MPe+j4@{c#7mv?5DJYknpy4! zC?FItTzSGG=9G&z_~!NPw_dw>e7=70^dc`-YKFse#1LpQ8ozpDfBVX{&8@wz&vj4N z_NLoU>Z2E_lpI0~?k-s_X?A3$M9h)Uz)jVJ$<);FGFF0&ftf%}3Bk=&v{d}v1ku0& zL(H0)h#hj0tg5SZ6{CnqQc0azfc1LS_emrhC;;THo{Yu-R97Pa&#QH)qN%uP zRb1{W03ez|2!mhG(G37BgdqAwc~pslnz%VR7chd@09aKqH!sYPzV8dSuH0Ho%-x+# zRe3;;D1hrF(B9lj(yas-vq%UP6P5orGymdR{Kb!bxabU^yi)aW1t|+4RY5`|lrEJ+ ziHR_Cxf-c^VLO-^7^>UwAXc;D&Lu1;iNbR*HGp9(oJAsWAnJ1h^MZdV<&J#W{3IgC z3WNrZ0hvfli&;SWYzPIHTOiUDc<{ZOf@p|Qb1J}J)$F2(Abnq;AL5SY&QvmA<-4tt zod}!)GXfDp%A#Tr6_L~wflMWtNuQb65mtR)a>?kPOrt1Rz^pL!MKddzgQIP(FghXlz#oIuj zBE{=$W{fB)1EHyF?!lDY?(J5u-MSkz=Q7s*g7f@EfxRrf%VD;d4ni?Pc!3dWCklgn z5x~WT%&l7the`o=^JFamIsyZd7>G(1WA0O*LTZ}2@UQ^P-IzjJFTq_x97gsbAXAw& zArw-vI;omCc;u)!Ad6LXm6En;Yj5LAcWRdpK9336J{93`XuB)!x~f7bCr8aWyAKRe zuE@*4q|l(LknYjU3rWWva?XWG0=fH(k3N0*+J1~&)+D02@B8J+MMM7EZ{0dPJ%9Jf zXRG_KrPPmRGxZ!fBJ=I-sT-`<-8*-0Tz~CG*R4N(_Wb7$fA-xkzj|$JT$Y1idY0VfT;@DwD%3Qioca>wZkmQT z&RdJTp0eb-7##o$JWs4~EV+z}ACaDq_Uwl|ZmgN@lnX?zi4Y0bu}B0x1`W;aMF z!{B`*Rn2+$pY}yh;F6SH;BL%(>*lq$?%jHFH2?Xt6Im<^Ji%Sd5zvgbH#T;*cQ$5Q zSq+JieP?I5+#0hg5q6=VobZKGsx;uwZ1{>u+OpFLs70dOW z0}X65!otNvf{G#sQXy4wfC6pEIfocUlp_ZUD%nuWji=OY2-*K3^R~RRk<7}n4`K`m zC=R*LWe-(s3I<+Rm0#YwO70TOvM3WGV@^48h^4S=Fia&~hhU~_s4G`D8y=D7iin{K zl9h-!pbaS$3n7#&ON;@~BXixYX(_YtWgjUJn|de}X9Ohjf^s(hqNLM6Fo#evl|&11@m`eQ zxS5+OV!?125C7N0?-K?CC0yQ{uv9wDi~|=uqKXm|0TtMnxvE>>4J$9%%i^n*XF{<6 zAm!8(l$X^oIVi6KCaOXJfQxm1HedGZm3i^KDI<()dSz$h+U`z3A}+h-f{Yo=Ji{2Z zJiOe>t7~Wgmw>yMtf~VbaEbmGV`Vv40;t)rGcyB#P}M2|j!d!dTXRPsRaZ4cU`ADE z20|=y*{Z3m#Jxla$;vV#RzAj@g$M`Lmq;Kk z;4vZyA%;-3-Kwgp%K@YjP{}QqW2vgDTOclo&nm{8v#OTMEdrV=0Fn>GeCBW|`y?|b zDv>TOzf4mhW^@oyMn?wbkWw!1W)Ul^{gSw64pqf{-N^!Dp_ z_ODc-d`)pQ8r9>tx3jZ<^ZMOa!~U};b)=HdGNIfjbWp&+IGc=KoX5%Lczbu}RPg25 zgpqquCIR*xrYs_y;S z1$Jv9Qjsr;akKG=G@s5dZd|+e?BK9b|3AO~A8BWo+&uRNv^acf?xs>zl@Y}db5;Ny zs-=jx_cz;Bx>)sn>I(C#NXZ$w;s6F}M#zl8$Q@w#Ayk#Ax_XvWl8GU5N!3Xi7&3FpvDNi_X+qR{$+4mh2 za^Mi7yXB-YvgCYzcyM}fKtQ32o3qibuIr5%AZ%_-k5133SZz0>_3|_z69RI)Sgl5* zrWtQmO>L%SjykHVRo4a%j9fQ$L=e?_QuS?CgAha8_LEUeS-L)(3`KoAJX;WQRx_)rAW{xD5JGTsQ*G*+9SyzBsfv*~tosh3U>Ufnqo|4+pvO>W z$p9D_39;;{*KIqlVnGL&JBkkPY^bUrQZ|2dS>Fe6kIY%67OW2gua5EqLjAyjoJ=6F+6@FW86g<&bGea=+~ff(FW^oxB;-BbnA z3+7psLovG#Sye=g%mh@$Fkh|-iwc2D=NJ)9rITC)vdoNt%eFPudQ{hSBS`|`y6>AR z7G$&n5K*55!Rr{nLDi}%_BodmOt}s*a^PU9aQTX{V*Lvd5k$1>5(gqAkqqV(0u;n1 z6#WkYV2m+~l(Nt$)}7?CDi#+5P!$3!b4m=Hau$^=GO8*E4BzM`KU37A^#Es33@=7R&&AM*7uG`#@*RNmMs+s=q-JksJM?d@c z=(tPLr@TAcY?=lDrqkJEGJW*up{qBe(PDlPLnxFxQ+0rPRGHXlI_cUD0XW3AZ8awv z0L2g^ZSQS8dweKa>e0As+tFyWwX=P6_@b_>Zn+9o1ov_(BqkLg#0q97()2?>EpY*dtKZ8{PEL@Xf$dZacgtD zy|ts}F){%mIRTi+^TU(pFJ3H`t4NeJUB9}2`_2tOW{!2;0Dvld|F3`e@BiYjeR;ON znAdgfOw)Qa8dU)~t1nkejzQI!DIgOPaWqi?;5zp0dTVc|gg4sxB2+PVX*Qcl>R)~B z%^&^fhvV@$!eR2O{~N$Nxxcm``32? z9RWCyo87p!x4XS{crt(V^r&C9mkt)cG>(+hGd4~A-M7DT`_7#zR?p9tp^g{rs%a2LPo6wE{QPk< z8mF9B>m@nVbZyv(wY9o$Y?z zI%95o4on%=Ha58l^Yev>q}6=?_Km!1XIq<}Jw42Qx^?e{6M}onGKy8GA~+O!A|q9Gg=R5^ zl=3i&05UXYs;j!V!II=s4l#5B;K1Wp6HzhECDEdzK!CRGVqga-JBuzSs=`o)fY9X} zm=GW^FwuF}7us&%Xs%3zqHgAd<-Isa-N9oBg@c%eqq7&IHZhrbAVzReHE<3rB8Y$v zF@&sIJgrpbf?2D`gs5VrwpfMems2q_QP(O&WCrkFBocE7s!rg9;J_wgIXNOD8hADf z6x7U2@E3&@2PlYTGaV?0y@;7krxOt^l6em74vtV_rv<_lLm-5}K}2#ci&8EVg_Ke$ zQxVvxssYhtP^u9kawy*%Cejj20xPm~Q$Z%=P}ZRYs4lLK!-WTm9aT+%pynWw0nxw_ z2#MT0cO71Cc@e3!N6b7hn!Bo0RfR;-XJke%PCugAA$yeNK`beQf7Dov5Xb~ zT+~7gR)SUp?uc%LT*%MNET%|Q(%@h^uHyb|Jey1pm#d$A_C(u-NM_07s($6p{wp_L z!yEh8)@@tvsT@KvNNjKI&gXMLiy?NouR<)l77n58c+5S-_~p0XdH(cy+jlA&tGHNP z#1PA%OjSpt5fPetpvX*Fa?>;y%kw(cs)9}i3P>p@1Q?IU@7#a$=L0lBFwS1ZJm0@PNwE_IvZ>7D)U7iX*UMc;MZFyJ*S8Y?qvn%Y!y*WI{! zbvoVpZ~u$mzPdY`G|i8H_=7+E@lXH$!DowJPS598c6LW~V`fhuKWpl`sp}X*%88M0 z-oEkt@pG}_|ME!GjK`_#98p9@8`FN>5)p^cu2)rE1qvLfUAIL-$xJFzY*_$49#2zF zs$W|Lw{=+`R_ac6J){Cr7>RbBOc z63ts%JB#H!=RBHBa!T9V+s~gpn{I5FOW~-L8(0X@)Q5?R8*c9YPyga~ZeQCbqUR?k zS2s5iakW~dEGf%)(!>xiQg?N_5o6?l7xPtQSY@5Yczkl^s`JIN88o%!2u?n%0oE?oRWD(10JliVN%&bz^ zaWt8CtIUxgr1*k3?jKwm+I z1y5vxlvNT*7rW}Rvd`DWi}rTsoZYRpJlHp~j06%nc!jLUxc8jB*ZTi|KO$pY*UoQl zFP(D$>bqvU+i~He#lm*(qmMuR)p{-#ov((ka$v_yJjim~*1T zvrk22K0kW);KA{Hz8;3F+uixqxpl7ZJ20eNL4{&&Cg$uE9^01w}KdUJktfa_X=0Gx~Qw!}<#CC-v_+qJCH&w6j$l!p5c zAHV$S#V`%aqa$F=oOkQ(^62Pjb)<;v>#GO%moG22+s(#x%|Y#51#re9Kt=zEu&p*5 z1#9isn|R|5C|I(3XH>6U8ih)V@G4@hHP)a)E(NeIjP$TLkSYvj0I1beW+|KrkgOqN zQqBj|yc{MLNJNIX6ho+Rh*FD+R)vBkxU2jLvjCUEBGNQX)vOs~6;zlN4`xvVs8ZiR zXsuC!QnD%_psx`yP!O=*ifYM)2#ZP)o_8G~#*$-B0^p5PB2HOVtu>&)IoDLMv6w{a z1h%9M09x2tgG5=_0E!4JlW}l|gLaLtA5H}{2mBPGs`IX9uwC0sV*phHhydm=b45M$ zWzkz>5FHs2Vbzoi3%5-RprsUJZT-7e4tACGmg1~KqT1}ZyE}okUYH4qrJz!c83U+w zj!UV%3F{oIXyIBO(mOZrT}PG(P*}Y)Qs??0idd6L##=7sU^+ms#@23<9#n=Z2ejk? z0776`N~I8TO+i=ai$%d|bre+~vI?v$t@n$0_w>=jdFwBS@#7cg)B09&c0`Ty%lXnA zA06jhtg$NEG`^PDXMMjsK30GjCui-^@llv20YCsE<6K)x_O`uza~V@iDHCGbv~A;! zp`2M&ELlWV!BP@)SuBr5xDE$I7!~L985gm}IBP3~<*s z{Pp&(G9#UD7R%$KM^7HCjvm~)WPHQ>b;}w(08n^YOE{x9c?k zIPc>)<(Pci)&tjSbyiANVP~uYv`s5T!ZbE*t1N`Tg-NlbG+Qh|G=yZW<(#c`P2U+Z zAgHQs*BPX)ZKr8Mq8LI+>Ah!ytm8QY(Is*>+1Fq z32uh)!xV{NQ6ty&X~SwnPnJ;oT6`NYR&vN5)tH$|)_6k5#ps^*QH~3#<0C`PJ*!WQ;L%b8&5q zEzC{dt4N8t6t1E1N z;W9s73gh+lbrCrvrc16nyE=Ge&Ulw$mcpf!yUZ{dL#1R9tq)LDQIUEwAS5nD1y#9< z_No|ISgOjNh(IvK1Om(j>w}gnV?;{M1Sni;1Ez9UYG9aiQI-mpVi72OFzPWM#v2Np ziwJYcIcF6{MJ@sW%t^S^rJkq=7ZsJFC<+Kwn_F^$`dBYqN+r_?7cMCueCnb(Clx`& zT(XJ?3kc+x3NxyxLW!xwoHX6903gCR}giEN$#03ZNKL_t&_S~7!T z4acRDQc5bEQv_5%Qf4|dHKp>cgn62#5K~E+xo9a`7zuMqsuDv~VPPqSb15HFmz3S!-u~e|x*(TtwjV z;`~5KL0n&N+O7eB5Mt)Y%-%IQrNw-aQbNR>^EeF#Oe#SI0M%KWQ#K9_Swt)`5|MN6 zop-;n-*0ZOFH=fHc@h z%%z-5$y^|(bf9;sf*wfG?%@4pW-2)y&HBr$D+c}K%U9)g`0VBWgR_-)7;;V_DI&9$ zQo^ufWkOO>Yb_$Alv0Y;+F`qI8b54ys9It{1l#z@eal?D^Eqc@4S_GISZi6dTP&vC z#yU6d_SO(uOV(D6&;Q`VZ+)}7R|5cbR_VQK8tGkb=6cs#l2+t23aWOIGNxu7%s;s}(7-M;M_Nr^clk~IV@&Qa6$3SvE#!p8K7s71Bb%@1vr z3IYZLq$=K7pjxlD0ANk;ED5MNlw{Nx^W`vvX*lWT(=eeSG{h_~KL6M?zHOTj5&)@U z97aFy>OE$6y9UKHg*2V}KhyvF$44benIe*MDAnYA9ywDYWX^MnInN=ML(a)5$1vwP zpU))6ITV@m@Wz}i$ElemXLI=O^TT(4!Crekcipb%b=@D2hc~Y9`!_BG75m1(l1~ve$0hmCz_>DX(-?G4xt8eu-|RV@3!8fDj0)*5tQ1@yF|sNUpeM0nMo? zlby#50OxJ0!B=`+TUu-d`|2M;U6ToLT&}Mw<9N#ZqPMcLu5|}%NG1hwDZFyuzQ2DM zZ^Wh0adGeG&IX6_ZMLm>(+LUw|Grg6uXP_{AGkCV*_yIg=C zCr4MGQEx{V{~Cz%JoYdb*kUPHAcI=WtR8Wmq2+OrDqMX=#(`0Xl21CZo{@upEX(PQ zt>+^&F9qVk7qc(BD%LBLu5+lVkpl*=0TA?ga8+!furd0{%0z^$tSZ0$)(<^WW=GA({CBSCTjK70%<@)adr+NLs z)}7SttvW+IUmj1216Kf$~i4qZ5UI>F3 zJPVU%&VD(hN|dXk?R0HF%a@`Fc^j^HCauU<5P8V8A7eT_GA%9Ln0dT;zVmx_7Jt6@ z64!=I^1#WF+qt~uh%VEOt3kFx++*GrgH8%r^6kwho5{k2%ECp`oMaBlV~OlO9X2UJ zTJgOL6T`foK&qltHVF-=q&&%|;GctC)#4XEU1#UUT)}pNpbQyp9C#g)s7oEuk2a$% zddGe7oVGQ^?*kRLu8O?(INM+f{In(s=N1rkfDah3eE5um zGG7tnho)yY)L@xnaFfo{-}Y&co*uYx2sQfsZ%hoEaL)5Uqr}6ZDd&Z4%vlZ5AHWFn z{kQgGwvcL=;gtjH2YU=GwsST46J1`J5))&_d|cTvO~h^q_EpW;#r7wUtSzgI)+oyd z_MCl?|Nd;f@0#a;-x&K}bty&GRp_YGOg6e^((-bM(LxAqt;oUkH{+e~EK{^8*;$43 zokxXbxx`&_!&>pVzuy54eF&d2Rch5Bp7AKCzA*VRc2_zguK*Ju&mrH=oh@3$A#SD` zU)8wbJu`|n0>p~mxxsu(x#s3`pu4=YJf?DKzXFEEWu$u&14&6`fS5Xw`_DT(^Dck7 zl@wY~{O7vLT(`5Y}+y?U5*L;Nuczr`s7X4@SYavmd15=$4 zJ?+*yucn%B7TQ(})63@e@x>wzFW0JaZ6@W^fNaOrZg1S5GP?jU(-btS*#eLalY6|h*f}HO3t(|7 z6rR(n5CE|!Gg+vmLfb^+yaXVcdf{!L%3vzj^F>|Do*=+a@2IYOiMG-NPG9%9ymHL3u6;5jAGFN6L6?2l+C6DT{W$DB6>|H&P6m9oHI$~}w9z$? z{u;f2l5|$B4ps=?9@+!DiAX|SH-(|7)@9M;`-$b{JA(<&*V=cQ(=lk;ex5amS38DX zM?DdaS5`(~y@)s|*K~~a%GxT0K!(buL&KRjp`)@fIa&x2RVa81=7H>MJ2J5UgID`nlCF-<19^pOAQKpn8%fK6HD!$gJq4&z zNKCU?`JJA?< zp3+-!l3nLSD_3cv&r%Q`xct#EJMmrpbJ0{4_R;NXODYy1b-o?**mm=1t!T|N&_kJC z?as9XU7aShe8ma2T6h}QD$`qX`0~ki0iI2H)7cPI-yw*K&tQ9BufK^i`;>|eVyG;1*kTL!g zD}6gEw4|Tm-Br_1ZFPgi5=;7tbC)D>c1qUvK)d>yOwDk^aT6sVsN0+va`jgG)6%u} zEH`O3Vara+wtwD?Hz}ZVp=R2r=XGbW-*c<`@)v(3f%hN3UYe?>J}pg%e$x^G={ZRC zmUiljv6jH_YblcJk?S2-ORT8oZ4G#fd=C69i~fX^HXckooUdjuW|XVUQvvlhYr7Vw zA=xU`*$eBvIr}heb4#yyOje7KpZ;r7V2S-KDrIrc1`x8^Fh%ly!tZq}Dk}VT;>%CG zP;dtwAYDtyHjbA)#_N)_88%|XAh`$2L9TW^S@iP{X(}iH&(O%kgvvU^DPQ3?=kJK- z*ZXo8sEl;(`jQ7p=AUl1_ck!pV@i_>iGF-XUSl(?RiXJec3{L0;I6Rb9NgZ&hvIjR5d!fWfDDT-V<*Yi4Hk z+cs`MIU*~lC@hRrrK*qDXMN)uf9Gtc>W1l(`I57cTHD=S@43pNiNe{58h3kF z4mK**wtf&$pUdLOL;0sSwO4_O;jk#~vG>|KpQHXT)CHwnuKfEF0NmrIBo}}Y^Lu=0 zs9ljQhP0n;fjhkyJNohp76u-LBCFHy?0b_C6HVqbP)-Akwz% z9j}ZUy=GN~1GgG+fz%r=;!l8RR|y@%Zpg% zlqp)&b=F%7da1OBMI?5+RCj0Cfbk4ywyk?38BWvsl=o+Vl`}gHN*FA#~IVif`3wMu*vEi<>x2wUQk` z1etC1De%R5>1dqjgp4dX-_N*;ON!Fzjy2kyA1SJU*fuY20OKS*kR@=MZyAzIIr9Gd zy=)CZ_G2av%+^ijlh;1HK0Z6dQ%)O%`{h6@?YHfToCPD+fN*x$jly0a>)Q_jEUL)v z0-bIZL!eLt`Iqsr4~3h+m6Q-#PO`my*N1 z)lzGYmG{5eA1;{Jrd7gJ)ii4H<^pWHP43Fe-|JPXWGPl;>?7OV|Ry!^($zPs04x~BJruTWB= z!uP4x^vk=lW(=A_fHE+y;~v$yZ#)DCd%zr85cRVP;2ecu7BZb`as_=|TDaLv@xl5z zC3wi?Jby0VWtsdC7$*QGB(D$7+h^J^{678TwYoTac3V2@VP4)Hq0l1wIJnYv-obQJ z*1H4D?2lBzYK8P+Sg6{X$)6ZO?VZ1cp$0);`Fi+m!-~r^6#Chi0Lgw{T)US1iCqvv zT}~%t+1yJv#3XAGlccFER#Dt3cDJ|`1&7>YD5_5N?6ZdOB4r;U!l5&u&(sC z_MMa=P$VpbXKm5GYyO7ajDqFJ=|Hjvr)n&=K=PTA{&gJS%acLSn$tOUXJw#)k}>2t zdl1pD5LjEK_Nx%mk94H>?UR3HT9PdeY z9Y11R9U@qjIEm32S~oBD0(H4iw;+tn0JZ3bPT7um?~*}3r6wpd-`7Ub8+n0>&-g~E zZF~%mnrbnU>bX>ew0Vt#!UfrKx=j*h1ZGXGA}g;xZ$va6cUm#A5eTWLHVV034Zu~A zEx3lEVXP>)_|g&G&4ZEYT46$iDQU5Uh1o+P7maDEPD|=hC;}COioW2V2Q%Be2IIRf z@t(X6f44UY!!*%!Qzcaby&U@ZP7FINmLG{E(l#oT#ED`| zX`dE9jX^Y#+C+5xjN9+5pHw_n6Ep08$}o1=ko2#RsRM;n%m{Kv()pX>okj+^3@yDb@aO{!NZSOT?&ih z+1U3!oh==`SQJ(~sifu=HjH-qov%!lj^+mM58xMbx}a7aAI=A;0Ux6mTchXy92C#? zPLEFxDtD)Y=0d+}{Akm?J%&<^uAF)`kIhjC^g{%$awwW{-auDJNx5d(a63FJ-~O@c zFuyN&i}Sv)Fy1`krx$}wN9Aq*>P0YM+Lv&4^6zW+-FTzERgt1}&%rQu6%A1Q#1XEc z6ivcO-ryHVh=;ufMYu@`n?L9}J0PvwY1^klWYU6gOz6NX@O$uT$*{GKQ4r}+H9e_u za>O3J@0K31I(4f8QiXK^0KRi)=UTbB)x3#$h#>Fj!2=eB`Dz|&s;l88hK@N6viGz0 z4_5x19vtAzCf-}Psu`qddJTQiVBB%^xXfT%RRD#ND~?;*E;ffo6{K(gX8LHO+i9Yh zB2-k_?@STxhSi6lUXx1<)RXkD%3YUBq4PN&<22H3F`cW>(me0d?yfnI($o)<&L&fW zX2{ItkJ&4X?lDtWb?N$8&^-tKzuJacn!Iz~7T8vz|1#w691hJAdUz*p9`9Dwyec#K zpWZUW_!FhS)(S-(rbSQSLZ1iiT@E=Zu@Xw->C@Z;>aqOAe3-5>>dT5!yvXY6XlqX& z@#ht@b-slITaBkr^~0IwWYn*~tNCRev<3`HqkIbc{SvD2k7e24Yy#rt(*s!n&dp@v zRH5h#)BZOW$v>tu7W{Vjs$7^58k@JyZ~y_HH_V-vY;k6tlUbYACh6c(m3IJTUNwE%YxOWJf_Sv5>Y2lpV0`NnShH9oX-y*6# zqp1*T6 z3VJ1skrF(9wv1EqfGOwxSu$5JF%nN1pP=X}wp{!@+B!#$*f(3cW6FA=^S%yHdhb4@}eWfcxgIbj~gOl&@{ zV6xO7zsgI^*PAR5re|VQ>OfhqjaZw`@>eH$pis(~8goZk3v_ za#GITd3m&Qc^7!Ln}7ViGae0uMTbQG3agOC<1j4u2QNV&J2(a{qC6o0ZJID45kB)x zd)hntEi*V4C;JO!!_VIkq#U)_Zk)(cfVc|fF)bWU$Wd4^F9D8msMsu*IC)~NCd7e1 zK14F?lPW8!4|&HV-4w{@M@+#=7~0k#De-E&IUcB&@dnoEiEvOIF7Fih@?S?}%$Y&NFu>Cvtq{D= zUm6m{#I^9G4zO@IG89uO?6Y1=l|~)r2JEnP9gU<}1+~gw@F(1R`mnU4Xvb$M*xMg1 zEP7XrV%^Xg*pnq)OWkvAtgznc?C6Bb?yj{^U(|Nj`C{|MnXuJs(Y=wXwf0U6GdLoe zRzP4FWuwGPG>^ab8Ny!WVLte;MOa-6t34rt7~qT0NNuU3l_7-X{amYp8QQIz-{~7d zLF9<55@3Q&l*W4m0&Q|X#UMVxsJVF>168}k&8H4{Eh&X z-*C7Tm^)@r_cy&n^mXJ_pdx!vgYEi|wGi)vWKzIXl zQnI7;&9XL|=F@x6NxaK$-Tb{rms-%-{}dL?q!1;$e`=~VIGCjJAMYUdXDwU1#DXQ0%kAx*i5_Ocsf{B6 zlad&($eufQS1s(GiLiAKrcb9g&~xpN419VrGOpT~%`?#$I4y)LtZFv4jwbRfZ55gh zr-cv6xpyEWtfKzvp2r05IRu}$9}w?dPVfF@0cX_q_==foFcB(N=}8+>A9$s-B4G+| zc{g#SnO9T!z)&R2b;3gk^q4vhJPRUc(bd~nAv3BQc*59iNUgfoC)lg*fyBj^7xNdV z`16F|f62jng-kj+T*J(kot-moK6!0;myEl>4)_DbfQ6RYu&cgx`tzC^}r#`TUg2+ zAmKIS<}B@EL7bJBbq&i=$v!SU{TAoR-t1vl zt-~_xo;v;j5s)0@XUAJNf5o>#Kl4j|83X4+s@7X)U8Ld)E1DV}rII|QFn@E4=Or#%gYkqNm$lmY4BTMa>bU2Zo)THNS7v8Foy^!x z1&s$DWLa(1EG?L~r%R=MF!?n2u{gZn+?ygoCM@{_I3ojJ>sS9tL*21}#~v>+by9wy z$rla52Z~CRz1oWdGR8^PB3lre8#!|3U%7|`jLSM~rzf_u6#Y4{x#G1%_AYdvN8L(W zscOVUYe?r#^EpXVhc1GqayJS+QhY5}*i-vqb<5C>1$D8$0n&`I zB$pL9YtBO9C~eVRP>8c)E={OU%{x&I>vZ!~&)35X5(<(1!+b-t6&^K|$cvHS!==NE zw~LDPyAHYM8)R7emoc+>uj(k1f^|>3*z%;WBXxXg_Ah!@XBWU$nlzImBs%2vw4drG zCVRG$lwVnRztgSi!_J)!AH~!0(%N5XT}QL4PjvehmrR7a1Euw4or-2!hIpkG_)aw}nH!7u63!-tlOA$`;8 zTAU&D-5|;>>P{BioF4(~u4*XEG6@QOFV}#&LVaG7a+Z>1Gk+ zfF-5TR>*^&?{#J2mAsL}Qub0O$0`r3m1~JLdxWUVAq5B-y!M5x8052{3%*Q{|5zTo zRN@MYr=?5y_Wvw^5<6n8yP}NSgJJ(#u0Gw=$wM=(NIs$eemqOjIt#!}KS4-xJ`FJ% zyh^1KM8$anwC~qkFut)4_wzMl(+ihduloy6GY8*&{6bYR8j; zMHZ>~Ga$yJE7xXW+lOa8sl?f2T2A!8udZ=qO%SV~6RP~}9c-~C&71r+vA%!jpH_XA zKEOW&2!Arnt8x8)T=~k%VllpFM1t|rK!i-i;J#lWFB6x-$rd4)?LbaxR@WcqGJhO1 zB%Q#eh?WVC)1c0kf5eO`RLWNj4H1(kR^NLxqJ$$o+^a+}Q?n`-a^*@OzLFU!?bz|Q zh}gtS=G{}qF^xth?e0KzJvBQ~MQ66k_1TH@fdt9z!fP_g8&4A{8tKhhBx~=&K_4wS z>)&jBOU=^6%EH2RWx3$IZ>pdxu^;{(t(|_*{;9YBnz?{?qr2jZrwuFAhJ()Pp+rc9 z^8gZ6QKe$qemEh~iUAW~QPXK@YDM(j)LaKHnp&&uX^B;8eCq<~-ZJv*VW*LBJmnnS zb&*`#>AOEg%r#Ve07yl}A+#q-Q0A)%@$sdk&Ip-UNenw)3jCOWI$UZR3F@F3W52ER z4Y!swKkL%GNTW30G~tH#c74T12(vLKnu=8j5q42YKJULhKfy3{UhGxxSe@a68(XQ| zmX}9|rF-OkX4)^eiXc>b^#H#%O>p2rFQLLE){qqz=c7;z3HI23YrS0}KaA3P@v~vw zQ$smS*sWGK_2sHe+{Aa!H!w4J9|-VW4o_Jo#@u_v5$S;&?VoeXJn2R0$Mc!NVf3wa zw%*l?HPpi)Y|ip`X`(M})XL4>ow+`1B;xEBN=^ZMcQLP9b>UeEA_ͮ(X_@bG=_ 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