[
  {
    "path": ".github/FUNDING.yml",
    "content": "github: [fasteddy516]\n"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n##\n## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\nbld/\n[Bb]in/\n[Oo]bj/\n[Ll]og/\n\n# Visual Studio 2015/2017 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# Visual Studio 2017 auto generated files\nGenerated\\ Files/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# Benchmark Results\nBenchmarkDotNet.Artifacts/\n\n# .NET Core\nproject.lock.json\nproject.fragment.lock.json\nartifacts/\n**/Properties/launchSettings.json\n\n# StyleCop\nStyleCopReport.xml\n\n# Files built by Visual Studio\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.iobj\n*.pch\n*.pdb\n*.ipdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n*.VC.VC.opendb\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# Visual Studio Trace Files\n*.e2e\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding add-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# AxoCover is a Code Coverage Tool\n.axoCover/*\n!.axoCover/settings.json\n\n# Visual Studio code coverage results\n*.coverage\n*.coveragexml\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# Note: Comment the next line if you want to checkin your web deploy settings,\n# but database connection strings (with potential passwords) will be unencrypted\n*.pubxml\n*.publishproj\n\n# Microsoft Azure Web App publish settings. Comment the next line if you want to\n# checkin your Azure Web App publish settings, but sensitive information contained\n# in these scripts will be unencrypted\nPublishScripts/\n\n# NuGet Packages\n*.nupkg\n# The packages folder can be ignored because of Package Restore\n**/[Pp]ackages/*\n# except build/, which is used as an MSBuild target.\n!**/[Pp]ackages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/[Pp]ackages/repositories.config\n# NuGet v3's project.json files produces more ignorable files\n*.nuget.props\n*.nuget.targets\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directories and files\nAppPackages/\nBundleArtifacts/\nPackage.StoreAssociation.xml\n_pkginfo.txt\n*.appx\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!*.[Cc]ache/\n\n# Others\nClientBin/\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.jfm\n*.pfx\n*.publishsettings\norleans.codegen.cs\n\n# Including strong name files can present a security risk \n# (https://github.com/github/gitignore/pull/2483#issue-259490424)\n#*.snk\n\n# Since there are multiple workflows, uncomment next line to ignore bower_components\n# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)\n#bower_components/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\nServiceFabricBackup/\n*.rptproj.bak\n\n# SQL Server files\n*.mdf\n*.ldf\n*.ndf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n*.rptproj.rsuser\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\nnode_modules/\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)\n*.vbw\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# Paket dependency manager\n.paket/paket.exe\npaket-files/\n\n# FAKE - F# Make\n.fake/\n\n# JetBrains Rider\n.idea/\n*.sln.iml\n\n# CodeRush\n.cr/\n\n# Python Tools for Visual Studio (PTVS)\n__pycache__/\n*.pyc\n\n# Cake - Uncomment if you are using it\n# tools/**\n# !tools/packages.config\n\n# Tabs Studio\n*.tss\n\n# Telerik's JustMock configuration file\n*.jmconfig\n\n# BizTalk build output\n*.btp.cs\n*.btm.cs\n*.odx.cs\n*.xsd.cs\n\n# OpenCover UI analysis results\nOpenCover/\n\n# Azure Stream Analytics local run output \nASALocalRun/\n\n# MSBuild Binary and Structured Log\n*.binlog\n\n# NVidia Nsight GPU debugger configuration file\n*.nvuser\n\n# MFractors (Xamarin productivity tool) working folder \n.mfractor/\n\n### AdvancedInstaller ###\n# Advanced Installer caches and default build output\n*.back.aip\n*-cache/\n*-SetupFiles/\nPrerequisites/\n"
  },
  {
    "path": "Installer/Installer.aip",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<DOCUMENT Type=\"Advanced Installer\" CreateVersion=\"16.0\" version=\"22.5\" Modules=\"simple\" RootPath=\".\" Language=\"en\" Id=\"{813739C4-1EBF-4720-9196-4AC91588D7AC}\">\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiPropsComponent\">\n    <ROW Property=\"AI_BITMAP_DISPLAY_MODE\" Value=\"0\"/>\n    <ROW Property=\"AI_PREDEF_LCONDS_PROPS\" Value=\"AI_DETECTED_DOTNET_VERSION\"/>\n    <ROW Property=\"AI_PROPPATH_DIR_PERBUILD_Newtonsoft.Json.dll\" Value=\"..\\SimplySerial\\packages\\Newtonsoft.Json.13.0.3\\lib\\net45\"/>\n    <ROW Property=\"AI_PROPPATH_DIR_PERBUILD_boards.json\" Value=\"..\\SimplySerial\\bin\\Release\"/>\n    <ROW Property=\"AI_PROPPATH_DIR_PERBUILD_ss.exe\" Value=\"..\\SimplySerial\\bin\\Release\"/>\n    <ROW Property=\"AI_PROPPATH_DIR_PERBUILD_ss.exe.config\" Value=\"..\\SimplySerial\\bin\\Release\"/>\n    <ROW Property=\"AI_PROPPATH_FILENAME_PERBUILD_Newtonsoft.Json.dll\" Value=\"Newtonsoft.Json.dll\"/>\n    <ROW Property=\"AI_PROPPATH_FILENAME_PERBUILD_boards.json\" Value=\"boards.json\"/>\n    <ROW Property=\"AI_PROPPATH_FILENAME_PERBUILD_ss.exe\" Value=\"ss.exe\"/>\n    <ROW Property=\"AI_PROPPATH_FILENAME_PERBUILD_ss.exe.config\" Value=\"ss.exe.config\"/>\n    <ROW Property=\"AI_REQUIRED_DOTNET_DISPLAY\" MultiBuildValue=\"DefaultBuild:4.5\" ValueLocId=\"-\"/>\n    <ROW Property=\"AI_REQUIRED_DOTNET_VERSION\" MultiBuildValue=\"DefaultBuild:4.5\" ValueLocId=\"-\"/>\n    <ROW Property=\"AI_RUN_AS_ADMIN\" Value=\"0\"/>\n    <ROW Property=\"ALLUSERS\" Value=\"1\" MultiBuildValue=\"DefaultBuild:\"/>\n    <ROW Property=\"ARPCOMMENTS\" Value=\"This installer database contains the logic and data required to install [|ProductName].\" ValueLocId=\"*\"/>\n    <ROW Property=\"ARPHELPLINK\" Value=\"https://github.com/fasteddy516/SimplySerial/issues\"/>\n    <ROW Property=\"ARPURLINFOABOUT\" Value=\"https://github.com/fasteddy516/SimplySerial\"/>\n    <ROW Property=\"ARPURLUPDATEINFO\" Value=\"https://github.com/fasteddy516/SimplySerial/releases\"/>\n    <ROW Property=\"Manufacturer\" Value=\"fasteddy516\"/>\n    <ROW Property=\"ProductCode\" Value=\"1033:{CC4A5805-ED2B-4478-A54E-359EAD15820D} \" Type=\"16\"/>\n    <ROW Property=\"ProductLanguage\" Value=\"1033\"/>\n    <ROW Property=\"ProductName\" Value=\"SimplySerial\"/>\n    <ROW Property=\"ProductVersion\" Value=\"0.9.0\" Options=\"32\"/>\n    <ROW Property=\"REBOOT\" MultiBuildValue=\"DefaultBuild:ReallySuppress\"/>\n    <ROW Property=\"SecureCustomProperties\" Value=\"OLDPRODUCTS;AI_NEWERPRODUCTFOUND\"/>\n    <ROW Property=\"UpgradeCode\" Value=\"{64061592-EDD5-474E-B846-4CA070788BBE}\"/>\n    <ROW Property=\"WindowsType9X\" MultiBuildValue=\"DefaultBuild:Windows 9x/ME\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsType9XDisplay\" MultiBuildValue=\"DefaultBuild:Windows 9x/ME\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsTypeNT40\" MultiBuildValue=\"DefaultBuild:Windows NT 4.0\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsTypeNT40Display\" MultiBuildValue=\"DefaultBuild:Windows NT 4.0\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsTypeNT50\" MultiBuildValue=\"DefaultBuild:Windows 2000\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsTypeNT50Display\" MultiBuildValue=\"DefaultBuild:Windows 2000\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsTypeNT5X\" MultiBuildValue=\"DefaultBuild:Windows XP/2003\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsTypeNT5XDisplay\" MultiBuildValue=\"DefaultBuild:Windows XP/2003\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsTypeNT60\" MultiBuildValue=\"DefaultBuild:Windows Vista/Server 2008\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsTypeNT60Display\" MultiBuildValue=\"DefaultBuild:Windows Vista/Server 2008\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsTypeNT64\" MultiBuildValue=\"DefaultBuild:Windows Server 2008 R2 x64, Windows Server 2012 x64, Windows Server 2012 R2 x64, Windows Server x64\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsTypeNT64Display\" MultiBuildValue=\"DefaultBuild:Windows Server 2008 R2 x64, Windows Server 2012 x64, Windows Server 2012 R2 x64, Windows Server x64\" ValueLocId=\"-\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiDirsComponent\">\n    <ROW Directory=\"APPDIR\" Directory_Parent=\"TARGETDIR\" DefaultDir=\"APPDIR:.\" IsPseudoRoot=\"1\"/>\n    <ROW Directory=\"TARGETDIR\" DefaultDir=\"SourceDir\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiCompsComponent\">\n    <ROW Component=\"AI_PROPPATH_FILENAME_PERBUILD_ss.exe\" ComponentId=\"{D328E50B-745A-44B1-A52A-AA88CF0D4B5B}\" Directory_=\"APPDIR\" Attributes=\"0\" KeyPath=\"ss.exe\"/>\n    <ROW Component=\"APPDIR\" ComponentId=\"{1B2EDF24-19CA-4CC3-8AD5-EDA96FB119C1}\" Directory_=\"APPDIR\" Attributes=\"0\"/>\n    <ROW Component=\"LICENSE\" ComponentId=\"{10A5105B-3C39-43BC-8A5F-1F31FD20C306}\" Directory_=\"APPDIR\" Attributes=\"0\" KeyPath=\"LICENSE\" Type=\"0\"/>\n    <ROW Component=\"ProductInformation\" ComponentId=\"{E25AA39B-E31D-4953-B138-D9AC744188A9}\" Directory_=\"APPDIR\" Attributes=\"4\" KeyPath=\"Version\"/>\n    <ROW Component=\"SimplySerial_References\" ComponentId=\"{EF67D85E-9894-44C7-9684-BF3DDD42D0F4}\" Directory_=\"APPDIR\" Attributes=\"0\" KeyPath=\"Newtonsoft.Json.dll\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiFeatsComponent\">\n    <ROW Feature=\"MainFeature\" Title=\"MainFeature\" Description=\"Description\" Display=\"1\" Level=\"1\" Directory_=\"APPDIR\" Attributes=\"0\"/>\n    <ATTRIBUTE name=\"CurrentFeature\" value=\"MainFeature\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiFilesComponent\">\n    <ROW File=\"LICENSE\" Component_=\"LICENSE\" FileName=\"LICENSE\" Attributes=\"0\" SourcePath=\"..\\LICENSE\" SelfReg=\"false\"/>\n    <ROW File=\"README.md\" Component_=\"LICENSE\" FileName=\"README.md\" Attributes=\"0\" SourcePath=\"..\\README.md\" SelfReg=\"false\"/>\n    <ROW File=\"ss.exe\" Component_=\"AI_PROPPATH_FILENAME_PERBUILD_ss.exe\" FileName=\"[|AI_PROPPATH_FILENAME_PERBUILD_ss.exe]\" Attributes=\"0\" SourcePath=\"&lt;AI_APPPATH_PERBUILD_ss.exe&gt;\" SelfReg=\"false\" DigSign=\"true\"/>\n    <ROW File=\"ss.exe.config\" Component_=\"LICENSE\" FileName=\"SSEXE~1.CON|[|AI_PROPPATH_FILENAME_PERBUILD_ss.exe.config]\" Attributes=\"0\" SourcePath=\"&lt;AI_APPPATH_PERBUILD_ss.exe.config&gt;\" SelfReg=\"false\"/>\n    <ROW File=\"boards.json\" Component_=\"LICENSE\" FileName=\"BOARDS~1.JSO|[|AI_PROPPATH_FILENAME_PERBUILD_boards.json]\" Attributes=\"0\" SourcePath=\"&lt;AI_APPPATH_PERBUILD_boards.json&gt;\" SelfReg=\"false\"/>\n    <ROW File=\"Newtonsoft.Json.dll\" Component_=\"SimplySerial_References\" FileName=\"NEWTON~2.DLL|[|AI_PROPPATH_FILENAME_PERBUILD_Newtonsoft.Json.dll]\" Attributes=\"0\" SourcePath=\"&lt;AI_APPPATH_PERBUILD_Newtonsoft.Json.dll&gt;\" SelfReg=\"false\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.AppPathsComponent\">\n    <ROW Name=\"AI_APPPATH_PERBUILD_Newtonsoft.Json.dll\" Path=\"[|AI_PROPPATH_DIR_PERBUILD_Newtonsoft.Json.dll]\\[|AI_PROPPATH_FILENAME_PERBUILD_Newtonsoft.Json.dll]\" Type=\"2\" Content=\"0\"/>\n    <ROW Name=\"AI_APPPATH_PERBUILD_boards.json\" Path=\"[|AI_PROPPATH_DIR_PERBUILD_boards.json]\\[|AI_PROPPATH_FILENAME_PERBUILD_boards.json]\" Type=\"2\" Content=\"0\"/>\n    <ROW Name=\"AI_APPPATH_PERBUILD_ss.exe\" Path=\"[|AI_PROPPATH_DIR_PERBUILD_ss.exe]\\[|AI_PROPPATH_FILENAME_PERBUILD_ss.exe]\" Type=\"2\" Content=\"0\"/>\n    <ROW Name=\"AI_APPPATH_PERBUILD_ss.exe.config\" Path=\"[|AI_PROPPATH_DIR_PERBUILD_ss.exe.config]\\[|AI_PROPPATH_FILENAME_PERBUILD_ss.exe.config]\" Type=\"2\" Content=\"0\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.BootstrOptComponent\">\n    <ROW BootstrOptKey=\"GlobalOptions\" DownloadFolder=\"[AppDataFolder][|Manufacturer]\\[|ProductName]\\prerequisites\" Options=\"2\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.BootstrapperUISequenceComponent\">\n    <ROW Action=\"AI_DetectSoftware\" Sequence=\"101\"/>\n    <ROW Action=\"AI_BACKUP_AI_SETUPEXEPATH\" Sequence=\"249\"/>\n    <ROW Action=\"AI_RESTORE_AI_SETUPEXEPATH\" Condition=\"AI_SETUPEXEPATH_ORIGINAL\" Sequence=\"251\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.BuildComponent\">\n    <ROW BuildKey=\"DefaultBuild\" BuildName=\"DefaultBuild\" BuildOrder=\"1\" BuildType=\"0\" PackageFolder=\"..\\SimplySerial\\bin\\x86\\Release\" PackageFileName=\"SimplySerial_[|ProductVersion]_user_setup\" Languages=\"en\" InstallationType=\"4\" UseLargeSchema=\"true\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.DictionaryComponent\">\n    <ROW Path=\"&lt;AI_DICTS&gt;ui.ail\"/>\n    <ROW Path=\"&lt;AI_DICTS&gt;ui_en.ail\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.FragmentComponent\">\n    <ROW Fragment=\"CommonUI.aip\" Path=\"&lt;AI_FRAGS&gt;CommonUI.aip\"/>\n    <ROW Fragment=\"LicenseAgreementDlg.aip\" Path=\"&lt;AI_THEMES&gt;classic\\fragments\\LicenseAgreementDlg.aip\"/>\n    <ROW Fragment=\"MaintenanceTypeDlg.aip\" Path=\"&lt;AI_THEMES&gt;classic\\fragments\\MaintenanceTypeDlg.aip\"/>\n    <ROW Fragment=\"MaintenanceWelcomeDlg.aip\" Path=\"&lt;AI_THEMES&gt;classic\\fragments\\MaintenanceWelcomeDlg.aip\"/>\n    <ROW Fragment=\"SequenceDialogs.aip\" Path=\"&lt;AI_THEMES&gt;classic\\fragments\\SequenceDialogs.aip\"/>\n    <ROW Fragment=\"Sequences.aip\" Path=\"&lt;AI_FRAGS&gt;Sequences.aip\"/>\n    <ROW Fragment=\"StaticUIStrings.aip\" Path=\"&lt;AI_FRAGS&gt;StaticUIStrings.aip\"/>\n    <ROW Fragment=\"Themes.aip\" Path=\"&lt;AI_FRAGS&gt;Themes.aip\"/>\n    <ROW Fragment=\"UI.aip\" Path=\"&lt;AI_THEMES&gt;classic\\fragments\\UI.aip\"/>\n    <ROW Fragment=\"Validation.aip\" Path=\"&lt;AI_FRAGS&gt;Validation.aip\"/>\n    <ROW Fragment=\"VerifyRemoveDlg.aip\" Path=\"&lt;AI_THEMES&gt;classic\\fragments\\VerifyRemoveDlg.aip\"/>\n    <ROW Fragment=\"VerifyRepairDlg.aip\" Path=\"&lt;AI_THEMES&gt;classic\\fragments\\VerifyRepairDlg.aip\"/>\n    <ROW Fragment=\"WelcomeDlg.aip\" Path=\"&lt;AI_THEMES&gt;classic\\fragments\\WelcomeDlg.aip\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiActionTextComponent\">\n    <ROW Action=\"AI_DeleteLzma\" Description=\"Deleting files extracted from archive\" DescriptionLocId=\"ActionText.Description.AI_DeleteLzma\" TemplateLocId=\"-\"/>\n    <ROW Action=\"AI_DeleteRLzma\" Description=\"Deleting files extracted from archive\" DescriptionLocId=\"ActionText.Description.AI_DeleteLzma\" TemplateLocId=\"-\"/>\n    <ROW Action=\"AI_ExtractLzma\" Description=\"Extracting files from archive\" DescriptionLocId=\"ActionText.Description.AI_ExtractLzma\" TemplateLocId=\"-\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiBinaryComponent\">\n    <ROW Name=\"SoftwareDetector.dll\" SourcePath=\"&lt;AI_CUSTACTS&gt;SoftwareDetector.dll\"/>\n    <ROW Name=\"aicustact.dll\" SourcePath=\"&lt;AI_CUSTACTS&gt;aicustact.dll\"/>\n    <ROW Name=\"lzmaextractor.dll\" SourcePath=\"&lt;AI_CUSTACTS&gt;lzmaextractor.dll\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiControlComponent\">\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control=\"LicenseAgreementDlgDialogInitializer\" Type=\"DialogInitializer\" X=\"0\" Y=\"0\" Width=\"0\" Height=\"0\" Attributes=\"0\" Order=\"-1\" TextLocId=\"-\" HelpLocId=\"-\" ExtDataLocId=\"-\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control=\"AgreementText\" Type=\"ScrollableText\" X=\"20\" Y=\"60\" Width=\"330\" Height=\"120\" Attributes=\"7\" Text=\"..\\LICENSE.rtf\" Order=\"400\" TextLocId=\"Control.Text.LicenseAgreementDlg#AgreementText_2\" MsiKey=\"LicenseAgreementDlg#AgreementText\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiControlEventComponent\">\n    <ROW Dialog_=\"WelcomeDlg\" Control_=\"Next\" Event=\"NewDialog\" Argument=\"LicenseAgreementDlg\" Condition=\"AI_INSTALL\" Ordering=\"1\"/>\n    <ROW Dialog_=\"MaintenanceWelcomeDlg\" Control_=\"Next\" Event=\"NewDialog\" Argument=\"MaintenanceTypeDlg\" Condition=\"AI_MAINT\" Ordering=\"99\"/>\n    <ROW Dialog_=\"VerifyReadyDlg\" Control_=\"Install\" Event=\"EndDialog\" Argument=\"Return\" Condition=\"AI_MAINT\" Ordering=\"198\"/>\n    <ROW Dialog_=\"VerifyReadyDlg\" Control_=\"Back\" Event=\"NewDialog\" Argument=\"CustomizeDlg\" Condition=\"AI_MAINT\" Ordering=\"202\"/>\n    <ROW Dialog_=\"CustomizeDlg\" Control_=\"Next\" Event=\"NewDialog\" Argument=\"VerifyReadyDlg\" Condition=\"AI_MAINT\" Ordering=\"101\"/>\n    <ROW Dialog_=\"CustomizeDlg\" Control_=\"Back\" Event=\"NewDialog\" Argument=\"MaintenanceTypeDlg\" Condition=\"AI_MAINT\" Ordering=\"1\"/>\n    <ROW Dialog_=\"MaintenanceTypeDlg\" Control_=\"ChangeButton\" Event=\"NewDialog\" Argument=\"CustomizeDlg\" Condition=\"AI_MAINT\" Ordering=\"501\"/>\n    <ROW Dialog_=\"MaintenanceTypeDlg\" Control_=\"Back\" Event=\"NewDialog\" Argument=\"MaintenanceWelcomeDlg\" Condition=\"AI_MAINT\" Ordering=\"1\"/>\n    <ROW Dialog_=\"MaintenanceTypeDlg\" Control_=\"RemoveButton\" Event=\"NewDialog\" Argument=\"VerifyRemoveDlg\" Condition=\"AI_MAINT AND InstallMode=&quot;Remove&quot;\" Ordering=\"601\"/>\n    <ROW Dialog_=\"VerifyRemoveDlg\" Control_=\"Back\" Event=\"NewDialog\" Argument=\"MaintenanceTypeDlg\" Condition=\"AI_MAINT AND InstallMode=&quot;Remove&quot;\" Ordering=\"1\"/>\n    <ROW Dialog_=\"MaintenanceTypeDlg\" Control_=\"RepairButton\" Event=\"NewDialog\" Argument=\"VerifyRepairDlg\" Condition=\"AI_MAINT AND InstallMode=&quot;Repair&quot;\" Ordering=\"601\"/>\n    <ROW Dialog_=\"VerifyRepairDlg\" Control_=\"Back\" Event=\"NewDialog\" Argument=\"MaintenanceTypeDlg\" Condition=\"AI_MAINT AND InstallMode=&quot;Repair&quot;\" Ordering=\"1\"/>\n    <ROW Dialog_=\"VerifyRepairDlg\" Control_=\"Repair\" Event=\"EndDialog\" Argument=\"Return\" Condition=\"AI_MAINT AND InstallMode=&quot;Repair&quot;\" Ordering=\"399\" Options=\"1\"/>\n    <ROW Dialog_=\"VerifyRemoveDlg\" Control_=\"Remove\" Event=\"EndDialog\" Argument=\"Return\" Condition=\"AI_MAINT AND InstallMode=&quot;Remove&quot;\" Ordering=\"299\" Options=\"1\"/>\n    <ROW Dialog_=\"PatchWelcomeDlg\" Control_=\"Next\" Event=\"NewDialog\" Argument=\"VerifyReadyDlg\" Condition=\"AI_PATCH\" Ordering=\"201\"/>\n    <ROW Dialog_=\"ResumeDlg\" Control_=\"Install\" Event=\"EndDialog\" Argument=\"Return\" Condition=\"AI_RESUME\" Ordering=\"299\"/>\n    <ROW Dialog_=\"VerifyReadyDlg\" Control_=\"Install\" Event=\"EndDialog\" Argument=\"Return\" Condition=\"AI_PATCH\" Ordering=\"199\"/>\n    <ROW Dialog_=\"VerifyReadyDlg\" Control_=\"Back\" Event=\"NewDialog\" Argument=\"PatchWelcomeDlg\" Condition=\"AI_PATCH\" Ordering=\"203\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"Next\" Event=\"EndDialog\" Argument=\"Return\" Condition=\"AI_INSTALL\" Ordering=\"1\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"Back\" Event=\"NewDialog\" Argument=\"WelcomeDlg\" Condition=\"AI_INSTALL\" Ordering=\"1\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"Next\" Event=\"SpawnDialog\" Argument=\"OutOfRbDiskDlg\" Condition=\"AI_INSTALL AND OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST=&quot;P&quot; OR NOT PROMPTROLLBACKCOST)\" Ordering=\"2\" Options=\"2\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"Next\" Event=\"EnableRollback\" Argument=\"False\" Condition=\"AI_INSTALL AND OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST=&quot;D&quot;\" Ordering=\"3\" Options=\"2\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"Next\" Event=\"SpawnDialog\" Argument=\"OutOfDiskDlg\" Condition=\"AI_INSTALL AND ( (OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST=&quot;F&quot;) )\" Ordering=\"4\" Options=\"2\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"LicenseAgreementDlgDialogInitializer\" Event=\"[AI_ButtonText_Next_Orig]\" Argument=\"[ButtonText_Next]\" Condition=\"AI_INSTALL\" Ordering=\"0\" Options=\"2\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"LicenseAgreementDlgDialogInitializer\" Event=\"[ButtonText_Next]\" Argument=\"[[AI_CommitButton]]\" Condition=\"AI_INSTALL\" Ordering=\"1\" Options=\"2\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"LicenseAgreementDlgDialogInitializer\" Event=\"[AI_Text_Next_Orig]\" Argument=\"[Text_Next]\" Condition=\"AI_INSTALL\" Ordering=\"2\" Options=\"2\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"LicenseAgreementDlgDialogInitializer\" Event=\"[Text_Next]\" Argument=\"[Text_Install]\" Condition=\"AI_INSTALL\" Ordering=\"3\" Options=\"2\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"Back\" Event=\"[ButtonText_Next]\" Argument=\"[AI_ButtonText_Next_Orig]\" Condition=\"AI_INSTALL\" Ordering=\"2\" Options=\"2\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"Back\" Event=\"[Text_Next]\" Argument=\"[AI_Text_Next_Orig]\" Condition=\"AI_INSTALL\" Ordering=\"3\" Options=\"2\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiCreateFolderComponent\">\n    <ROW Directory_=\"APPDIR\" Component_=\"APPDIR\" ManualDelete=\"true\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiCustActComponent\">\n    <ROW Action=\"AI_BACKUP_AI_SETUPEXEPATH\" Type=\"51\" Source=\"AI_SETUPEXEPATH_ORIGINAL\" Target=\"[AI_SETUPEXEPATH]\"/>\n    <ROW Action=\"AI_DOWNGRADE\" Type=\"19\" Target=\"4010\"/>\n    <ROW Action=\"AI_DeleteCadLzma\" Type=\"51\" Source=\"AI_DeleteLzma\" Target=\"[AI_SETUPEXEPATH]\"/>\n    <ROW Action=\"AI_DeleteLzma\" Type=\"1025\" Source=\"lzmaextractor.dll\" Target=\"DeleteLZMAFiles\"/>\n    <ROW Action=\"AI_DeleteRCadLzma\" Type=\"51\" Source=\"AI_DeleteRLzma\" Target=\"[AI_SETUPEXEPATH]\"/>\n    <ROW Action=\"AI_DeleteRLzma\" Type=\"1281\" Source=\"lzmaextractor.dll\" Target=\"DeleteLZMAFiles\"/>\n    <ROW Action=\"AI_DetectSoftware\" Type=\"257\" Source=\"SoftwareDetector.dll\" Target=\"OnDetectSoftware\"/>\n    <ROW Action=\"AI_DpiContentScale\" Type=\"1\" Source=\"aicustact.dll\" Target=\"DpiContentScale\"/>\n    <ROW Action=\"AI_EnableDebugLog\" Type=\"321\" Source=\"aicustact.dll\" Target=\"EnableDebugLog\"/>\n    <ROW Action=\"AI_ExtractCadLzma\" Type=\"51\" Source=\"AI_ExtractLzma\" Target=\"[AI_SETUPEXEPATH]\"/>\n    <ROW Action=\"AI_ExtractLzma\" Type=\"1025\" Source=\"lzmaextractor.dll\" Target=\"ExtractLZMAFiles\"/>\n    <ROW Action=\"AI_FindExeLzma\" Type=\"1\" Source=\"lzmaextractor.dll\" Target=\"FindEXE\"/>\n    <ROW Action=\"AI_InstallModeCheck\" Type=\"1\" Source=\"aicustact.dll\" Target=\"UpdateInstallMode\" WithoutSeq=\"true\"/>\n    <ROW Action=\"AI_PREPARE_UPGRADE\" Type=\"65\" Source=\"aicustact.dll\" Target=\"PrepareUpgrade\"/>\n    <ROW Action=\"AI_PRESERVE_INSTALL_TYPE\" Type=\"65\" Source=\"aicustact.dll\" Target=\"PreserveInstallType\"/>\n    <ROW Action=\"AI_RESTORE_AI_SETUPEXEPATH\" Type=\"51\" Source=\"AI_SETUPEXEPATH\" Target=\"[AI_SETUPEXEPATH_ORIGINAL]\"/>\n    <ROW Action=\"AI_RESTORE_LOCATION\" Type=\"65\" Source=\"aicustact.dll\" Target=\"RestoreLocation\"/>\n    <ROW Action=\"AI_ResolveKnownFolders\" Type=\"1\" Source=\"aicustact.dll\" Target=\"AI_ResolveKnownFolders\"/>\n    <ROW Action=\"AI_SHOW_LOG\" Type=\"65\" Source=\"aicustact.dll\" Target=\"LaunchLogFile\" WithoutSeq=\"true\"/>\n    <ROW Action=\"AI_STORE_LOCATION\" Type=\"51\" Source=\"ARPINSTALLLOCATION\" Target=\"[APPDIR]\"/>\n    <ROW Action=\"SET_APPDIR\" Type=\"307\" Source=\"APPDIR\" Target=\"[ProgramFilesFolder][Manufacturer]\\[ProductName]\" MultiBuildTarget=\"DefaultBuild:[AppDataFolder][ProductName]\"/>\n    <ROW Action=\"SET_SHORTCUTDIR\" Type=\"307\" Source=\"SHORTCUTDIR\" Target=\"[ProgramMenuFolder][ProductName]\"/>\n    <ROW Action=\"SET_TARGETDIR_TO_APPDIR\" Type=\"51\" Source=\"TARGETDIR\" Target=\"[APPDIR]\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiEnvComponent\">\n    <ROW Environment=\"Path\" Name=\"=-Path\" Value=\"[~];[APPDIR]\" Component_=\"ProductInformation\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiFeatCompsComponent\">\n    <ROW Feature_=\"MainFeature\" Component_=\"ProductInformation\"/>\n    <ROW Feature_=\"MainFeature\" Component_=\"LICENSE\"/>\n    <ROW Feature_=\"MainFeature\" Component_=\"APPDIR\"/>\n    <ROW Feature_=\"MainFeature\" Component_=\"AI_PROPPATH_FILENAME_PERBUILD_ss.exe\"/>\n    <ROW Feature_=\"MainFeature\" Component_=\"SimplySerial_References\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiInstExSeqComponent\">\n    <ROW Action=\"AI_DOWNGRADE\" Condition=\"AI_NEWERPRODUCTFOUND AND (UILevel &lt;&gt; 5)\" Sequence=\"210\"/>\n    <ROW Action=\"AI_RESTORE_LOCATION\" Condition=\"APPDIR=&quot;&quot;\" Sequence=\"749\"/>\n    <ROW Action=\"AI_STORE_LOCATION\" Condition=\"(Not Installed) OR REINSTALL\" Sequence=\"1501\"/>\n    <ROW Action=\"AI_PREPARE_UPGRADE\" Condition=\"AI_UPGRADE=&quot;No&quot; AND (Not Installed)\" Sequence=\"1399\"/>\n    <ROW Action=\"AI_ResolveKnownFolders\" Sequence=\"52\"/>\n    <ROW Action=\"AI_EnableDebugLog\" Sequence=\"51\"/>\n    <ROW Action=\"AI_DetectSoftware\" Sequence=\"102\"/>\n    <ROW Action=\"AI_BACKUP_AI_SETUPEXEPATH\" Sequence=\"99\" Builds=\"DefaultBuild\"/>\n    <ROW Action=\"AI_RESTORE_AI_SETUPEXEPATH\" Condition=\"AI_SETUPEXEPATH_ORIGINAL\" Sequence=\"101\" Builds=\"DefaultBuild\"/>\n    <ROW Action=\"AI_DeleteCadLzma\" Condition=\"SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)\" Sequence=\"199\" Builds=\"DefaultBuild\"/>\n    <ROW Action=\"AI_DeleteRCadLzma\" Condition=\"SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)\" Sequence=\"198\" Builds=\"DefaultBuild\"/>\n    <ROW Action=\"AI_ExtractCadLzma\" Condition=\"SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)\" Sequence=\"197\" Builds=\"DefaultBuild\"/>\n    <ROW Action=\"AI_FindExeLzma\" Condition=\"SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)\" Sequence=\"196\" Builds=\"DefaultBuild\"/>\n    <ROW Action=\"AI_ExtractLzma\" Condition=\"SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)\" Sequence=\"1549\" Builds=\"DefaultBuild\"/>\n    <ROW Action=\"AI_DeleteRLzma\" Condition=\"SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)\" Sequence=\"1548\" Builds=\"DefaultBuild\"/>\n    <ROW Action=\"AI_DeleteLzma\" Condition=\"SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)\" Sequence=\"6599\" Builds=\"DefaultBuild\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiInstallUISequenceComponent\">\n    <ROW Action=\"AI_RESTORE_LOCATION\" Condition=\"APPDIR=&quot;&quot;\" Sequence=\"749\"/>\n    <ROW Action=\"AI_ResolveKnownFolders\" Sequence=\"53\"/>\n    <ROW Action=\"AI_DpiContentScale\" Sequence=\"52\"/>\n    <ROW Action=\"AI_EnableDebugLog\" Sequence=\"51\"/>\n    <ROW Action=\"AI_DetectSoftware\" Sequence=\"102\"/>\n    <ROW Action=\"AI_PRESERVE_INSTALL_TYPE\" Sequence=\"199\"/>\n    <ROW Action=\"AI_BACKUP_AI_SETUPEXEPATH\" Sequence=\"99\"/>\n    <ROW Action=\"AI_RESTORE_AI_SETUPEXEPATH\" Condition=\"AI_SETUPEXEPATH_ORIGINAL\" Sequence=\"101\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiLaunchConditionsComponent\">\n    <ROW Condition=\"( Version9X OR ( NOT VersionNT64 ) OR ( VersionNT64 AND ((VersionNT64 &lt;&gt; 601) OR (MsiNTProductType = 1)) AND ((VersionNT64 &lt;&gt; 602) OR (MsiNTProductType = 1)) AND ((VersionNT64 &lt;&gt; 603) OR (MsiNTProductType = 1)) AND ((VersionNT64 &lt;&gt; 1000 AND VersionNT64 &lt;&gt; 1100) OR (MsiNTProductType = 1)) ) )\" Description=\"[ProductName] cannot be installed on the following Windows versions: [WindowsTypeNT64Display].\" DescriptionLocId=\"AI.LaunchCondition.NoSpecificNT64\" IsPredefined=\"true\" Builds=\"DefaultBuild\"/>\n    <ROW Condition=\"((VersionNT &lt;&gt; 501) AND (VersionNT &lt;&gt; 502))\" Description=\"[ProductName] cannot be installed on [WindowsTypeNT5XDisplay].\" DescriptionLocId=\"AI.LaunchCondition.NoNT5X\" IsPredefined=\"true\" Builds=\"DefaultBuild\"/>\n    <ROW Condition=\"(VersionNT &lt;&gt; 400)\" Description=\"[ProductName] cannot be installed on [WindowsTypeNT40Display].\" DescriptionLocId=\"AI.LaunchCondition.NoNT40\" IsPredefined=\"true\" Builds=\"DefaultBuild\"/>\n    <ROW Condition=\"(VersionNT &lt;&gt; 500)\" Description=\"[ProductName] cannot be installed on [WindowsTypeNT50Display].\" DescriptionLocId=\"AI.LaunchCondition.NoNT50\" IsPredefined=\"true\" Builds=\"DefaultBuild\"/>\n    <ROW Condition=\"(VersionNT &lt;&gt; 600)\" Description=\"[ProductName] cannot be installed on [WindowsTypeNT60Display].\" DescriptionLocId=\"AI.LaunchCondition.NoNT60\" IsPredefined=\"true\" Builds=\"DefaultBuild\"/>\n    <ROW Condition=\"AI_DETECTED_DOTNET_VERSION &gt;= AI_REQUIRED_DOTNET_VERSION\" Description=\"[ProductName] cannot be installed on systems with .NET Framework version lower than [AI_REQUIRED_DOTNET_DISPLAY].\" DescriptionLocId=\"AI.LaunchCondition.DotNET\" IsPredefined=\"true\" Builds=\"DefaultBuild\"/>\n    <ROW Condition=\"VersionNT\" Description=\"[ProductName] cannot be installed on [WindowsType9XDisplay].\" DescriptionLocId=\"AI.LaunchCondition.No9X\" IsPredefined=\"true\" Builds=\"DefaultBuild\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiRegsComponent\">\n    <ROW Registry=\"Manufacturer\" Root=\"-1\" Key=\"Software\\[Manufacturer]\" Name=\"\\\"/>\n    <ROW Registry=\"Path\" Root=\"-1\" Key=\"Software\\[Manufacturer]\\[ProductName]\" Name=\"Path\" Value=\"[APPDIR]\" Component_=\"ProductInformation\"/>\n    <ROW Registry=\"ProductName\" Root=\"-1\" Key=\"Software\\[Manufacturer]\\[ProductName]\" Name=\"\\\"/>\n    <ROW Registry=\"Software\" Root=\"-1\" Key=\"Software\" Name=\"\\\"/>\n    <ROW Registry=\"Version\" Root=\"-1\" Key=\"Software\\[Manufacturer]\\[ProductName]\" Name=\"Version\" Value=\"[ProductVersion]\" Component_=\"ProductInformation\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiThemeComponent\">\n    <ATTRIBUTE name=\"UsedTheme\" value=\"classic\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiUpgradeComponent\">\n    <ROW UpgradeCode=\"[|UpgradeCode]\" VersionMin=\"0.0.1\" VersionMax=\"[|ProductVersion]\" Attributes=\"257\" ActionProperty=\"OLDPRODUCTS\"/>\n    <ROW UpgradeCode=\"[|UpgradeCode]\" VersionMin=\"[|ProductVersion]\" Attributes=\"2\" ActionProperty=\"AI_NEWERPRODUCTFOUND\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.VsProjectComponent\">\n    <ROW ProjectId=\"{3c7db929-519c-44a3-a68f-2646cc595cae}\" ProjectName=\"SimplySerial\" OutputGroup=\"PrimaryOutput\" OutputFile=\"ss.exe\"/>\n    <ROW ProjectId=\"{3c7db929-519c-44a3-a68f-2646cc595cae}\" ProjectName=\"SimplySerial\" OutputGroup=\"PrimaryOutput\" OutputFile=\"ss.exe.config\"/>\n    <ROW ProjectId=\"{3c7db929-519c-44a3-a68f-2646cc595cae}\" ProjectName=\"SimplySerial\" OutputGroup=\"ContentOutput\" OutputFile=\"boards.json\"/>\n    <ROW ProjectId=\"{3c7db929-519c-44a3-a68f-2646cc595cae}\" ProjectName=\"SimplySerial\" OutputGroup=\"References\" OutputFile=\"Newtonsoft.Json.dll\"/>\n  </COMPONENT>\n</DOCUMENT>\n"
  },
  {
    "path": "Installer/Installer.aiproj",
    "content": "﻿<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">All</Configuration>\n    <SchemaVersion>2.0</SchemaVersion>\n    <ProjectGuid>dcc10c6b-b172-4172-9961-e6d643df6bcf</ProjectGuid>\n    <OutputType>msi</OutputType>\n    <ProjectHome>.</ProjectHome>\n    <StartupFile>Installer.aip</StartupFile>\n    <SearchPath>\n    </SearchPath>\n    <WorkingDirectory>.</WorkingDirectory>\n    <IsWindowsApplication>True</IsWindowsApplication>\n    <AssemblyName>Installer</AssemblyName>\n    <Name>Installer</Name>\n    <RootNamespace>Installer</RootNamespace>\n    <LoadFromTemplate>\n    </LoadFromTemplate>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)' == 'DefaultBuild' \" />\n  <ItemGroup>\n    <Compile Include=\"Installer.aip\">\n      <SubType>Code</SubType>\n    </Compile>\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\SimplySerial\\SimplySerial.csproj\">\n      <Name>SimplySerial</Name>\n      <Project>{3c7db929-519c-44a3-a68f-2646cc595cae}</Project>\n      <Private>True</Private>\n      <CreateShortcut>False</CreateShortcut>\n      <OutputsToImport>PrimaryOutput;References;ContentOutput</OutputsToImport>\n    </ProjectReference>\n  </ItemGroup>\n  <Target Name=\"Build\">\n    <Error Text=\"This project requires Advanced Installer tool. Please download it from https://www.advancedinstaller.com/download.html\" />\n  </Target>\n  <Target Name=\"Rebuild\">\n    <Error Text=\"This project requires Advanced Installer tool. Please download it from https://www.advancedinstaller.com/download.html\" />\n  </Target>\n  <Target Name=\"Clean\">\n  </Target>\n  <Target Name=\"ResolveAssemblyReferences\">\n  </Target>\n  <Import Condition=\"'$(AdvancedInstallerMSBuildTargets)' != ''\" Project=\"$(AdvancedInstallerMSBuildTargets)\\AdvInstExtTasks.Targets\" />\n  <Import Condition=\"('$(AdvancedInstallerMSBuildTargets)' == '') And (Exists('$(MSBuildExtensionsPath32)\\Caphyon\\Advanced Installer\\AdvInstExtTasks.Targets'))\" Project=\"$(MSBuildExtensionsPath32)\\Caphyon\\Advanced Installer\\AdvInstExtTasks.Targets\" />\n</Project>"
  },
  {
    "path": "Installer-System/Installer-System.aip",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<DOCUMENT Type=\"Advanced Installer\" CreateVersion=\"16.0\" version=\"22.5\" Modules=\"simple\" RootPath=\".\" Language=\"en\" Id=\"{9BAEE6C8-7726-40BA-ADC1-9001E7BBCAF9}\">\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiPropsComponent\">\n    <ROW Property=\"AI_BITMAP_DISPLAY_MODE\" Value=\"0\"/>\n    <ROW Property=\"AI_PREDEF_LCONDS_PROPS\" Value=\"AI_DETECTED_DOTNET_VERSION\"/>\n    <ROW Property=\"AI_PROPPATH_DIR_PERBUILD_Newtonsoft.Json.dll\" Value=\"..\\SimplySerial\\packages\\Newtonsoft.Json.13.0.3\\lib\\net45\"/>\n    <ROW Property=\"AI_PROPPATH_DIR_PERBUILD_boards.json_1\" Value=\"..\\SimplySerial\\bin\\Release\"/>\n    <ROW Property=\"AI_PROPPATH_DIR_PERBUILD_ss.exe.config\" Value=\"..\\SimplySerial\\bin\\Release\"/>\n    <ROW Property=\"AI_PROPPATH_DIR_PERBUILD_ss.exe_1\" Value=\"..\\SimplySerial\\bin\\Release\"/>\n    <ROW Property=\"AI_PROPPATH_FILENAME_PERBUILD_Newtonsoft.Json.dll\" Value=\"Newtonsoft.Json.dll\"/>\n    <ROW Property=\"AI_PROPPATH_FILENAME_PERBUILD_boards.json_1\" Value=\"boards.json\"/>\n    <ROW Property=\"AI_PROPPATH_FILENAME_PERBUILD_ss.exe.config\" Value=\"ss.exe.config\"/>\n    <ROW Property=\"AI_PROPPATH_FILENAME_PERBUILD_ss.exe_1\" Value=\"ss.exe\"/>\n    <ROW Property=\"AI_REQUIRED_DOTNET_DISPLAY\" MultiBuildValue=\"DefaultBuild:4.5\" ValueLocId=\"-\"/>\n    <ROW Property=\"AI_REQUIRED_DOTNET_VERSION\" MultiBuildValue=\"DefaultBuild:4.5\" ValueLocId=\"-\"/>\n    <ROW Property=\"AI_RUN_AS_ADMIN\" Value=\"0\"/>\n    <ROW Property=\"ALLUSERS\" Value=\"1\"/>\n    <ROW Property=\"ARPCOMMENTS\" Value=\"This installer database contains the logic and data required to install [|ProductName].\" ValueLocId=\"*\"/>\n    <ROW Property=\"ARPHELPLINK\" Value=\"https://github.com/fasteddy516/SimplySerial/issues\"/>\n    <ROW Property=\"ARPURLINFOABOUT\" Value=\"https://github.com/fasteddy516/SimplySerial\"/>\n    <ROW Property=\"ARPURLUPDATEINFO\" Value=\"https://github.com/fasteddy516/SimplySerial/releases\"/>\n    <ROW Property=\"Manufacturer\" Value=\"fasteddy516\"/>\n    <ROW Property=\"ProductCode\" Value=\"1033:{820DED12-18FF-4E2F-8F19-96C94573660A} \" Type=\"16\"/>\n    <ROW Property=\"ProductLanguage\" Value=\"1033\"/>\n    <ROW Property=\"ProductName\" Value=\"SimplySerial\"/>\n    <ROW Property=\"ProductVersion\" Value=\"0.9.0\" Options=\"32\"/>\n    <ROW Property=\"SecureCustomProperties\" Value=\"OLDPRODUCTS;AI_NEWERPRODUCTFOUND\"/>\n    <ROW Property=\"UpgradeCode\" Value=\"{6A3965D3-95B6-4145-8B3C-6F55E2A16C31}\"/>\n    <ROW Property=\"WindowsType9X\" MultiBuildValue=\"DefaultBuild:Windows 9x/ME\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsType9XDisplay\" MultiBuildValue=\"DefaultBuild:Windows 9x/ME\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsTypeNT40\" MultiBuildValue=\"DefaultBuild:Windows NT 4.0\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsTypeNT40Display\" MultiBuildValue=\"DefaultBuild:Windows NT 4.0\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsTypeNT50\" MultiBuildValue=\"DefaultBuild:Windows 2000\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsTypeNT50Display\" MultiBuildValue=\"DefaultBuild:Windows 2000\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsTypeNT5X\" MultiBuildValue=\"DefaultBuild:Windows XP/2003\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsTypeNT5XDisplay\" MultiBuildValue=\"DefaultBuild:Windows XP/2003\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsTypeNT60\" MultiBuildValue=\"DefaultBuild:Windows Vista/Server 2008\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsTypeNT60Display\" MultiBuildValue=\"DefaultBuild:Windows Vista/Server 2008\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsTypeNT64\" MultiBuildValue=\"DefaultBuild:Windows Server 2008 R2 x64, Windows Server 2012 x64, Windows Server 2012 R2 x64, Windows Server x64\" ValueLocId=\"-\"/>\n    <ROW Property=\"WindowsTypeNT64Display\" MultiBuildValue=\"DefaultBuild:Windows Server 2008 R2 x64, Windows Server 2012 x64, Windows Server 2012 R2 x64, Windows Server x64\" ValueLocId=\"-\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiDirsComponent\">\n    <ROW Directory=\"APPDIR\" Directory_Parent=\"TARGETDIR\" DefaultDir=\"APPDIR:.\" IsPseudoRoot=\"1\"/>\n    <ROW Directory=\"TARGETDIR\" DefaultDir=\"SourceDir\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiCompsComponent\">\n    <ROW Component=\"AI_PROPPATH_FILENAME_PERBUILD_ss.exe_1\" ComponentId=\"{A3F9DBB9-858A-4666-AF0E-A38907550884}\" Directory_=\"APPDIR\" Attributes=\"0\" KeyPath=\"ss.exe_1\"/>\n    <ROW Component=\"APPDIR\" ComponentId=\"{58FE101B-6573-4CBF-8C41-D0AB47C7986F}\" Directory_=\"APPDIR\" Attributes=\"0\"/>\n    <ROW Component=\"LICENSE\" ComponentId=\"{11EC7A29-8BF9-4760-B5F2-6F1F2DA679AC}\" Directory_=\"APPDIR\" Attributes=\"0\" KeyPath=\"LICENSE\" Type=\"0\"/>\n    <ROW Component=\"ProductInformation\" ComponentId=\"{A18E84B6-BAD1-4AE3-B5BD-1266FC789D8C}\" Directory_=\"APPDIR\" Attributes=\"4\" KeyPath=\"Version\"/>\n    <ROW Component=\"SimplySerial_References\" ComponentId=\"{160A4EC8-8112-4882-839B-DE97D46FED5B}\" Directory_=\"APPDIR\" Attributes=\"0\" KeyPath=\"Newtonsoft.Json.dll\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiFeatsComponent\">\n    <ROW Feature=\"MainFeature\" Title=\"MainFeature\" Description=\"Description\" Display=\"1\" Level=\"1\" Directory_=\"APPDIR\" Attributes=\"0\"/>\n    <ATTRIBUTE name=\"CurrentFeature\" value=\"MainFeature\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiFilesComponent\">\n    <ROW File=\"LICENSE\" Component_=\"LICENSE\" FileName=\"LICENSE\" Attributes=\"0\" SourcePath=\"..\\LICENSE\" SelfReg=\"false\"/>\n    <ROW File=\"README.md\" Component_=\"LICENSE\" FileName=\"README.md\" Attributes=\"0\" SourcePath=\"..\\README.md\" SelfReg=\"false\"/>\n    <ROW File=\"ss.exe_1\" Component_=\"AI_PROPPATH_FILENAME_PERBUILD_ss.exe_1\" FileName=\"[|AI_PROPPATH_FILENAME_PERBUILD_ss.exe_1]\" Attributes=\"0\" SourcePath=\"&lt;AI_APPPATH_PERBUILD_ss.exe_1&gt;\" SelfReg=\"false\" DigSign=\"true\"/>\n    <ROW File=\"ss.exe.config\" Component_=\"LICENSE\" FileName=\"SSEXE~1.CON|[|AI_PROPPATH_FILENAME_PERBUILD_ss.exe.config]\" Attributes=\"0\" SourcePath=\"&lt;AI_APPPATH_PERBUILD_ss.exe.config&gt;\" SelfReg=\"false\"/>\n    <ROW File=\"boards.json_1\" Component_=\"LICENSE\" FileName=\"BOARDS~1.JSO|[|AI_PROPPATH_FILENAME_PERBUILD_boards.json_1]\" Attributes=\"0\" SourcePath=\"&lt;AI_APPPATH_PERBUILD_boards.json_1&gt;\" SelfReg=\"false\"/>\n    <ROW File=\"Newtonsoft.Json.dll\" Component_=\"SimplySerial_References\" FileName=\"NEWTON~2.DLL|[|AI_PROPPATH_FILENAME_PERBUILD_Newtonsoft.Json.dll]\" Attributes=\"0\" SourcePath=\"&lt;AI_APPPATH_PERBUILD_Newtonsoft.Json.dll&gt;\" SelfReg=\"false\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.AppPathsComponent\">\n    <ROW Name=\"AI_APPPATH_PERBUILD_Newtonsoft.Json.dll\" Path=\"[|AI_PROPPATH_DIR_PERBUILD_Newtonsoft.Json.dll]\\[|AI_PROPPATH_FILENAME_PERBUILD_Newtonsoft.Json.dll]\" Type=\"2\" Content=\"0\"/>\n    <ROW Name=\"AI_APPPATH_PERBUILD_boards.json_1\" Path=\"[|AI_PROPPATH_DIR_PERBUILD_boards.json_1]\\[|AI_PROPPATH_FILENAME_PERBUILD_boards.json_1]\" Type=\"2\" Content=\"0\"/>\n    <ROW Name=\"AI_APPPATH_PERBUILD_ss.exe.config\" Path=\"[|AI_PROPPATH_DIR_PERBUILD_ss.exe.config]\\[|AI_PROPPATH_FILENAME_PERBUILD_ss.exe.config]\" Type=\"2\" Content=\"0\"/>\n    <ROW Name=\"AI_APPPATH_PERBUILD_ss.exe_1\" Path=\"[|AI_PROPPATH_DIR_PERBUILD_ss.exe_1]\\[|AI_PROPPATH_FILENAME_PERBUILD_ss.exe_1]\" Type=\"2\" Content=\"0\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.BootstrOptComponent\">\n    <ROW BootstrOptKey=\"GlobalOptions\" DownloadFolder=\"[AppDataFolder][|Manufacturer]\\[|ProductName]\\prerequisites\" Options=\"2\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.BootstrapperUISequenceComponent\">\n    <ROW Action=\"AI_DetectSoftware\" Sequence=\"101\"/>\n    <ROW Action=\"AI_BACKUP_AI_SETUPEXEPATH\" Sequence=\"249\"/>\n    <ROW Action=\"AI_RESTORE_AI_SETUPEXEPATH\" Condition=\"AI_SETUPEXEPATH_ORIGINAL\" Sequence=\"251\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.BuildComponent\">\n    <ROW BuildKey=\"DefaultBuild\" BuildName=\"DefaultBuild\" BuildOrder=\"1\" BuildType=\"0\" PackageFolder=\"..\\SimplySerial\\bin\\x86\\Release\" PackageFileName=\"SimplySerial_[|ProductVersion]_system_setup\" Languages=\"en\" InstallationType=\"4\" UseLargeSchema=\"true\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.DictionaryComponent\">\n    <ROW Path=\"&lt;AI_DICTS&gt;ui.ail\"/>\n    <ROW Path=\"&lt;AI_DICTS&gt;ui_en.ail\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.FragmentComponent\">\n    <ROW Fragment=\"CommonUI.aip\" Path=\"&lt;AI_FRAGS&gt;CommonUI.aip\"/>\n    <ROW Fragment=\"LicenseAgreementDlg.aip\" Path=\"&lt;AI_THEMES&gt;classic\\fragments\\LicenseAgreementDlg.aip\"/>\n    <ROW Fragment=\"MaintenanceTypeDlg.aip\" Path=\"&lt;AI_THEMES&gt;classic\\fragments\\MaintenanceTypeDlg.aip\"/>\n    <ROW Fragment=\"MaintenanceWelcomeDlg.aip\" Path=\"&lt;AI_THEMES&gt;classic\\fragments\\MaintenanceWelcomeDlg.aip\"/>\n    <ROW Fragment=\"SequenceDialogs.aip\" Path=\"&lt;AI_THEMES&gt;classic\\fragments\\SequenceDialogs.aip\"/>\n    <ROW Fragment=\"Sequences.aip\" Path=\"&lt;AI_FRAGS&gt;Sequences.aip\"/>\n    <ROW Fragment=\"StaticUIStrings.aip\" Path=\"&lt;AI_FRAGS&gt;StaticUIStrings.aip\"/>\n    <ROW Fragment=\"Themes.aip\" Path=\"&lt;AI_FRAGS&gt;Themes.aip\"/>\n    <ROW Fragment=\"UI.aip\" Path=\"&lt;AI_THEMES&gt;classic\\fragments\\UI.aip\"/>\n    <ROW Fragment=\"Validation.aip\" Path=\"&lt;AI_FRAGS&gt;Validation.aip\"/>\n    <ROW Fragment=\"VerifyRemoveDlg.aip\" Path=\"&lt;AI_THEMES&gt;classic\\fragments\\VerifyRemoveDlg.aip\"/>\n    <ROW Fragment=\"VerifyRepairDlg.aip\" Path=\"&lt;AI_THEMES&gt;classic\\fragments\\VerifyRepairDlg.aip\"/>\n    <ROW Fragment=\"WelcomeDlg.aip\" Path=\"&lt;AI_THEMES&gt;classic\\fragments\\WelcomeDlg.aip\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiActionTextComponent\">\n    <ROW Action=\"AI_DeleteLzma\" Description=\"Deleting files extracted from archive\" DescriptionLocId=\"ActionText.Description.AI_DeleteLzma\" TemplateLocId=\"-\"/>\n    <ROW Action=\"AI_DeleteRLzma\" Description=\"Deleting files extracted from archive\" DescriptionLocId=\"ActionText.Description.AI_DeleteLzma\" TemplateLocId=\"-\"/>\n    <ROW Action=\"AI_ExtractLzma\" Description=\"Extracting files from archive\" DescriptionLocId=\"ActionText.Description.AI_ExtractLzma\" TemplateLocId=\"-\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiBinaryComponent\">\n    <ROW Name=\"SoftwareDetector.dll\" SourcePath=\"&lt;AI_CUSTACTS&gt;SoftwareDetector.dll\"/>\n    <ROW Name=\"aicustact.dll\" SourcePath=\"&lt;AI_CUSTACTS&gt;aicustact.dll\"/>\n    <ROW Name=\"lzmaextractor.dll\" SourcePath=\"&lt;AI_CUSTACTS&gt;lzmaextractor.dll\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiControlComponent\">\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control=\"LicenseAgreementDlgDialogInitializer\" Type=\"DialogInitializer\" X=\"0\" Y=\"0\" Width=\"0\" Height=\"0\" Attributes=\"0\" Order=\"-1\" TextLocId=\"-\" HelpLocId=\"-\" ExtDataLocId=\"-\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control=\"AgreementText\" Type=\"ScrollableText\" X=\"20\" Y=\"60\" Width=\"330\" Height=\"120\" Attributes=\"7\" Text=\"..\\LICENSE.rtf\" Order=\"400\" TextLocId=\"Control.Text.LicenseAgreementDlg#AgreementText\" MsiKey=\"LicenseAgreementDlg#AgreementText\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiControlEventComponent\">\n    <ROW Dialog_=\"WelcomeDlg\" Control_=\"Next\" Event=\"NewDialog\" Argument=\"LicenseAgreementDlg\" Condition=\"AI_INSTALL\" Ordering=\"1\"/>\n    <ROW Dialog_=\"MaintenanceWelcomeDlg\" Control_=\"Next\" Event=\"NewDialog\" Argument=\"MaintenanceTypeDlg\" Condition=\"AI_MAINT\" Ordering=\"99\"/>\n    <ROW Dialog_=\"VerifyReadyDlg\" Control_=\"Install\" Event=\"EndDialog\" Argument=\"Return\" Condition=\"AI_MAINT\" Ordering=\"198\"/>\n    <ROW Dialog_=\"VerifyReadyDlg\" Control_=\"Back\" Event=\"NewDialog\" Argument=\"CustomizeDlg\" Condition=\"AI_MAINT\" Ordering=\"202\"/>\n    <ROW Dialog_=\"CustomizeDlg\" Control_=\"Next\" Event=\"NewDialog\" Argument=\"VerifyReadyDlg\" Condition=\"AI_MAINT\" Ordering=\"101\"/>\n    <ROW Dialog_=\"CustomizeDlg\" Control_=\"Back\" Event=\"NewDialog\" Argument=\"MaintenanceTypeDlg\" Condition=\"AI_MAINT\" Ordering=\"1\"/>\n    <ROW Dialog_=\"MaintenanceTypeDlg\" Control_=\"ChangeButton\" Event=\"NewDialog\" Argument=\"CustomizeDlg\" Condition=\"AI_MAINT\" Ordering=\"501\"/>\n    <ROW Dialog_=\"MaintenanceTypeDlg\" Control_=\"Back\" Event=\"NewDialog\" Argument=\"MaintenanceWelcomeDlg\" Condition=\"AI_MAINT\" Ordering=\"1\"/>\n    <ROW Dialog_=\"MaintenanceTypeDlg\" Control_=\"RemoveButton\" Event=\"NewDialog\" Argument=\"VerifyRemoveDlg\" Condition=\"AI_MAINT AND InstallMode=&quot;Remove&quot;\" Ordering=\"601\"/>\n    <ROW Dialog_=\"VerifyRemoveDlg\" Control_=\"Back\" Event=\"NewDialog\" Argument=\"MaintenanceTypeDlg\" Condition=\"AI_MAINT AND InstallMode=&quot;Remove&quot;\" Ordering=\"1\"/>\n    <ROW Dialog_=\"MaintenanceTypeDlg\" Control_=\"RepairButton\" Event=\"NewDialog\" Argument=\"VerifyRepairDlg\" Condition=\"AI_MAINT AND InstallMode=&quot;Repair&quot;\" Ordering=\"601\"/>\n    <ROW Dialog_=\"VerifyRepairDlg\" Control_=\"Back\" Event=\"NewDialog\" Argument=\"MaintenanceTypeDlg\" Condition=\"AI_MAINT AND InstallMode=&quot;Repair&quot;\" Ordering=\"1\"/>\n    <ROW Dialog_=\"VerifyRepairDlg\" Control_=\"Repair\" Event=\"EndDialog\" Argument=\"Return\" Condition=\"AI_MAINT AND InstallMode=&quot;Repair&quot;\" Ordering=\"399\" Options=\"1\"/>\n    <ROW Dialog_=\"VerifyRemoveDlg\" Control_=\"Remove\" Event=\"EndDialog\" Argument=\"Return\" Condition=\"AI_MAINT AND InstallMode=&quot;Remove&quot;\" Ordering=\"299\" Options=\"1\"/>\n    <ROW Dialog_=\"PatchWelcomeDlg\" Control_=\"Next\" Event=\"NewDialog\" Argument=\"VerifyReadyDlg\" Condition=\"AI_PATCH\" Ordering=\"201\"/>\n    <ROW Dialog_=\"ResumeDlg\" Control_=\"Install\" Event=\"EndDialog\" Argument=\"Return\" Condition=\"AI_RESUME\" Ordering=\"299\"/>\n    <ROW Dialog_=\"VerifyReadyDlg\" Control_=\"Install\" Event=\"EndDialog\" Argument=\"Return\" Condition=\"AI_PATCH\" Ordering=\"199\"/>\n    <ROW Dialog_=\"VerifyReadyDlg\" Control_=\"Back\" Event=\"NewDialog\" Argument=\"PatchWelcomeDlg\" Condition=\"AI_PATCH\" Ordering=\"203\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"Next\" Event=\"EndDialog\" Argument=\"Return\" Condition=\"AI_INSTALL\" Ordering=\"1\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"Back\" Event=\"NewDialog\" Argument=\"WelcomeDlg\" Condition=\"AI_INSTALL\" Ordering=\"1\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"Next\" Event=\"SpawnDialog\" Argument=\"OutOfRbDiskDlg\" Condition=\"AI_INSTALL AND OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST=&quot;P&quot; OR NOT PROMPTROLLBACKCOST)\" Ordering=\"2\" Options=\"2\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"Next\" Event=\"EnableRollback\" Argument=\"False\" Condition=\"AI_INSTALL AND OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST=&quot;D&quot;\" Ordering=\"3\" Options=\"2\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"Next\" Event=\"SpawnDialog\" Argument=\"OutOfDiskDlg\" Condition=\"AI_INSTALL AND ( (OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST=&quot;F&quot;) )\" Ordering=\"4\" Options=\"2\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"LicenseAgreementDlgDialogInitializer\" Event=\"[AI_ButtonText_Next_Orig]\" Argument=\"[ButtonText_Next]\" Condition=\"AI_INSTALL\" Ordering=\"0\" Options=\"2\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"LicenseAgreementDlgDialogInitializer\" Event=\"[ButtonText_Next]\" Argument=\"[[AI_CommitButton]]\" Condition=\"AI_INSTALL\" Ordering=\"1\" Options=\"2\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"LicenseAgreementDlgDialogInitializer\" Event=\"[AI_Text_Next_Orig]\" Argument=\"[Text_Next]\" Condition=\"AI_INSTALL\" Ordering=\"2\" Options=\"2\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"LicenseAgreementDlgDialogInitializer\" Event=\"[Text_Next]\" Argument=\"[Text_Install]\" Condition=\"AI_INSTALL\" Ordering=\"3\" Options=\"2\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"Back\" Event=\"[ButtonText_Next]\" Argument=\"[AI_ButtonText_Next_Orig]\" Condition=\"AI_INSTALL\" Ordering=\"2\" Options=\"2\"/>\n    <ROW Dialog_=\"LicenseAgreementDlg\" Control_=\"Back\" Event=\"[Text_Next]\" Argument=\"[AI_Text_Next_Orig]\" Condition=\"AI_INSTALL\" Ordering=\"3\" Options=\"2\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiCreateFolderComponent\">\n    <ROW Directory_=\"APPDIR\" Component_=\"APPDIR\" ManualDelete=\"true\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiCustActComponent\">\n    <ROW Action=\"AI_BACKUP_AI_SETUPEXEPATH\" Type=\"51\" Source=\"AI_SETUPEXEPATH_ORIGINAL\" Target=\"[AI_SETUPEXEPATH]\"/>\n    <ROW Action=\"AI_DOWNGRADE\" Type=\"19\" Target=\"4010\"/>\n    <ROW Action=\"AI_DeleteCadLzma\" Type=\"51\" Source=\"AI_DeleteLzma\" Target=\"[AI_SETUPEXEPATH]\"/>\n    <ROW Action=\"AI_DeleteLzma\" Type=\"1025\" Source=\"lzmaextractor.dll\" Target=\"DeleteLZMAFiles\"/>\n    <ROW Action=\"AI_DeleteRCadLzma\" Type=\"51\" Source=\"AI_DeleteRLzma\" Target=\"[AI_SETUPEXEPATH]\"/>\n    <ROW Action=\"AI_DeleteRLzma\" Type=\"1281\" Source=\"lzmaextractor.dll\" Target=\"DeleteLZMAFiles\"/>\n    <ROW Action=\"AI_DetectSoftware\" Type=\"257\" Source=\"SoftwareDetector.dll\" Target=\"OnDetectSoftware\"/>\n    <ROW Action=\"AI_DpiContentScale\" Type=\"1\" Source=\"aicustact.dll\" Target=\"DpiContentScale\"/>\n    <ROW Action=\"AI_EnableDebugLog\" Type=\"321\" Source=\"aicustact.dll\" Target=\"EnableDebugLog\"/>\n    <ROW Action=\"AI_ExtractCadLzma\" Type=\"51\" Source=\"AI_ExtractLzma\" Target=\"[AI_SETUPEXEPATH]\"/>\n    <ROW Action=\"AI_ExtractLzma\" Type=\"1025\" Source=\"lzmaextractor.dll\" Target=\"ExtractLZMAFiles\"/>\n    <ROW Action=\"AI_FindExeLzma\" Type=\"1\" Source=\"lzmaextractor.dll\" Target=\"FindEXE\"/>\n    <ROW Action=\"AI_InstallModeCheck\" Type=\"1\" Source=\"aicustact.dll\" Target=\"UpdateInstallMode\" WithoutSeq=\"true\"/>\n    <ROW Action=\"AI_PREPARE_UPGRADE\" Type=\"65\" Source=\"aicustact.dll\" Target=\"PrepareUpgrade\"/>\n    <ROW Action=\"AI_PRESERVE_INSTALL_TYPE\" Type=\"65\" Source=\"aicustact.dll\" Target=\"PreserveInstallType\"/>\n    <ROW Action=\"AI_RESTORE_AI_SETUPEXEPATH\" Type=\"51\" Source=\"AI_SETUPEXEPATH\" Target=\"[AI_SETUPEXEPATH_ORIGINAL]\"/>\n    <ROW Action=\"AI_RESTORE_LOCATION\" Type=\"65\" Source=\"aicustact.dll\" Target=\"RestoreLocation\"/>\n    <ROW Action=\"AI_ResolveKnownFolders\" Type=\"1\" Source=\"aicustact.dll\" Target=\"AI_ResolveKnownFolders\"/>\n    <ROW Action=\"AI_SHOW_LOG\" Type=\"65\" Source=\"aicustact.dll\" Target=\"LaunchLogFile\" WithoutSeq=\"true\"/>\n    <ROW Action=\"AI_STORE_LOCATION\" Type=\"51\" Source=\"ARPINSTALLLOCATION\" Target=\"[APPDIR]\"/>\n    <ROW Action=\"SET_APPDIR\" Type=\"307\" Source=\"APPDIR\" Target=\"[ProgramFilesFolder][Manufacturer]\\[ProductName]\" MultiBuildTarget=\"DefaultBuild:[ProgramFilesFolder][ProductName]\"/>\n    <ROW Action=\"SET_SHORTCUTDIR\" Type=\"307\" Source=\"SHORTCUTDIR\" Target=\"[ProgramMenuFolder][ProductName]\"/>\n    <ROW Action=\"SET_TARGETDIR_TO_APPDIR\" Type=\"51\" Source=\"TARGETDIR\" Target=\"[APPDIR]\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiEnvComponent\">\n    <ROW Environment=\"Path\" Name=\"=-*Path\" Value=\"[~];[APPDIR]\" Component_=\"ProductInformation\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiFeatCompsComponent\">\n    <ROW Feature_=\"MainFeature\" Component_=\"ProductInformation\"/>\n    <ROW Feature_=\"MainFeature\" Component_=\"LICENSE\"/>\n    <ROW Feature_=\"MainFeature\" Component_=\"APPDIR\"/>\n    <ROW Feature_=\"MainFeature\" Component_=\"AI_PROPPATH_FILENAME_PERBUILD_ss.exe_1\"/>\n    <ROW Feature_=\"MainFeature\" Component_=\"SimplySerial_References\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiInstExSeqComponent\">\n    <ROW Action=\"AI_DOWNGRADE\" Condition=\"AI_NEWERPRODUCTFOUND AND (UILevel &lt;&gt; 5)\" Sequence=\"210\"/>\n    <ROW Action=\"AI_RESTORE_LOCATION\" Condition=\"APPDIR=&quot;&quot;\" Sequence=\"749\"/>\n    <ROW Action=\"AI_STORE_LOCATION\" Condition=\"(Not Installed) OR REINSTALL\" Sequence=\"1501\"/>\n    <ROW Action=\"AI_PREPARE_UPGRADE\" Condition=\"AI_UPGRADE=&quot;No&quot; AND (Not Installed)\" Sequence=\"1399\"/>\n    <ROW Action=\"AI_ResolveKnownFolders\" Sequence=\"52\"/>\n    <ROW Action=\"AI_EnableDebugLog\" Sequence=\"51\"/>\n    <ROW Action=\"AI_DetectSoftware\" Sequence=\"102\"/>\n    <ROW Action=\"AI_BACKUP_AI_SETUPEXEPATH\" Sequence=\"99\" Builds=\"DefaultBuild\"/>\n    <ROW Action=\"AI_RESTORE_AI_SETUPEXEPATH\" Condition=\"AI_SETUPEXEPATH_ORIGINAL\" Sequence=\"101\" Builds=\"DefaultBuild\"/>\n    <ROW Action=\"AI_DeleteCadLzma\" Condition=\"SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)\" Sequence=\"199\" Builds=\"DefaultBuild\"/>\n    <ROW Action=\"AI_DeleteRCadLzma\" Condition=\"SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)\" Sequence=\"198\" Builds=\"DefaultBuild\"/>\n    <ROW Action=\"AI_ExtractCadLzma\" Condition=\"SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)\" Sequence=\"197\" Builds=\"DefaultBuild\"/>\n    <ROW Action=\"AI_FindExeLzma\" Condition=\"SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)\" Sequence=\"196\" Builds=\"DefaultBuild\"/>\n    <ROW Action=\"AI_ExtractLzma\" Condition=\"SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)\" Sequence=\"1549\" Builds=\"DefaultBuild\"/>\n    <ROW Action=\"AI_DeleteRLzma\" Condition=\"SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)\" Sequence=\"1548\" Builds=\"DefaultBuild\"/>\n    <ROW Action=\"AI_DeleteLzma\" Condition=\"SETUPEXEDIR=&quot;&quot; AND Installed AND (REMOVE&lt;&gt;&quot;ALL&quot;) AND (AI_INSTALL_MODE&lt;&gt;&quot;Remove&quot;) AND (NOT PATCH)\" Sequence=\"6599\" Builds=\"DefaultBuild\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiInstallUISequenceComponent\">\n    <ROW Action=\"AI_RESTORE_LOCATION\" Condition=\"APPDIR=&quot;&quot;\" Sequence=\"749\"/>\n    <ROW Action=\"AI_ResolveKnownFolders\" Sequence=\"53\"/>\n    <ROW Action=\"AI_DpiContentScale\" Sequence=\"52\"/>\n    <ROW Action=\"AI_EnableDebugLog\" Sequence=\"51\"/>\n    <ROW Action=\"AI_DetectSoftware\" Sequence=\"102\"/>\n    <ROW Action=\"AI_PRESERVE_INSTALL_TYPE\" Sequence=\"199\"/>\n    <ROW Action=\"AI_BACKUP_AI_SETUPEXEPATH\" Sequence=\"99\"/>\n    <ROW Action=\"AI_RESTORE_AI_SETUPEXEPATH\" Condition=\"AI_SETUPEXEPATH_ORIGINAL\" Sequence=\"101\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiLaunchConditionsComponent\">\n    <ROW Condition=\"( Version9X OR ( NOT VersionNT64 ) OR ( VersionNT64 AND ((VersionNT64 &lt;&gt; 601) OR (MsiNTProductType = 1)) AND ((VersionNT64 &lt;&gt; 602) OR (MsiNTProductType = 1)) AND ((VersionNT64 &lt;&gt; 603) OR (MsiNTProductType = 1)) AND ((VersionNT64 &lt;&gt; 1000 AND VersionNT64 &lt;&gt; 1100) OR (MsiNTProductType = 1)) ) )\" Description=\"[ProductName] cannot be installed on the following Windows versions: [WindowsTypeNT64Display].\" DescriptionLocId=\"AI.LaunchCondition.NoSpecificNT64\" IsPredefined=\"true\" Builds=\"DefaultBuild\"/>\n    <ROW Condition=\"((VersionNT &lt;&gt; 501) AND (VersionNT &lt;&gt; 502))\" Description=\"[ProductName] cannot be installed on [WindowsTypeNT5XDisplay].\" DescriptionLocId=\"AI.LaunchCondition.NoNT5X\" IsPredefined=\"true\" Builds=\"DefaultBuild\"/>\n    <ROW Condition=\"(VersionNT &lt;&gt; 400)\" Description=\"[ProductName] cannot be installed on [WindowsTypeNT40Display].\" DescriptionLocId=\"AI.LaunchCondition.NoNT40\" IsPredefined=\"true\" Builds=\"DefaultBuild\"/>\n    <ROW Condition=\"(VersionNT &lt;&gt; 500)\" Description=\"[ProductName] cannot be installed on [WindowsTypeNT50Display].\" DescriptionLocId=\"AI.LaunchCondition.NoNT50\" IsPredefined=\"true\" Builds=\"DefaultBuild\"/>\n    <ROW Condition=\"(VersionNT &lt;&gt; 600)\" Description=\"[ProductName] cannot be installed on [WindowsTypeNT60Display].\" DescriptionLocId=\"AI.LaunchCondition.NoNT60\" IsPredefined=\"true\" Builds=\"DefaultBuild\"/>\n    <ROW Condition=\"AI_DETECTED_DOTNET_VERSION &gt;= AI_REQUIRED_DOTNET_VERSION\" Description=\"[ProductName] cannot be installed on systems with .NET Framework version lower than [AI_REQUIRED_DOTNET_DISPLAY].\" DescriptionLocId=\"AI.LaunchCondition.DotNET\" IsPredefined=\"true\" Builds=\"DefaultBuild\"/>\n    <ROW Condition=\"VersionNT\" Description=\"[ProductName] cannot be installed on [WindowsType9XDisplay].\" DescriptionLocId=\"AI.LaunchCondition.No9X\" IsPredefined=\"true\" Builds=\"DefaultBuild\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiRegsComponent\">\n    <ROW Registry=\"Manufacturer\" Root=\"-1\" Key=\"Software\\[Manufacturer]\" Name=\"\\\"/>\n    <ROW Registry=\"Path\" Root=\"-1\" Key=\"Software\\[Manufacturer]\\[ProductName]\" Name=\"Path\" Value=\"[APPDIR]\" Component_=\"ProductInformation\"/>\n    <ROW Registry=\"ProductName\" Root=\"-1\" Key=\"Software\\[Manufacturer]\\[ProductName]\" Name=\"\\\"/>\n    <ROW Registry=\"Software\" Root=\"-1\" Key=\"Software\" Name=\"\\\"/>\n    <ROW Registry=\"Version\" Root=\"-1\" Key=\"Software\\[Manufacturer]\\[ProductName]\" Name=\"Version\" Value=\"[ProductVersion]\" Component_=\"ProductInformation\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiThemeComponent\">\n    <ATTRIBUTE name=\"UsedTheme\" value=\"classic\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.MsiUpgradeComponent\">\n    <ROW UpgradeCode=\"[|UpgradeCode]\" VersionMin=\"0.0.1\" VersionMax=\"[|ProductVersion]\" Attributes=\"257\" ActionProperty=\"OLDPRODUCTS\"/>\n    <ROW UpgradeCode=\"[|UpgradeCode]\" VersionMin=\"[|ProductVersion]\" Attributes=\"2\" ActionProperty=\"AI_NEWERPRODUCTFOUND\"/>\n  </COMPONENT>\n  <COMPONENT cid=\"caphyon.advinst.msicomp.VsProjectComponent\">\n    <ROW ProjectId=\"{3c7db929-519c-44a3-a68f-2646cc595cae}\" ProjectName=\"SimplySerial\" OutputGroup=\"PrimaryOutput\" OutputFile=\"ss.exe_1\"/>\n    <ROW ProjectId=\"{3c7db929-519c-44a3-a68f-2646cc595cae}\" ProjectName=\"SimplySerial\" OutputGroup=\"PrimaryOutput\" OutputFile=\"ss.exe.config\"/>\n    <ROW ProjectId=\"{3c7db929-519c-44a3-a68f-2646cc595cae}\" ProjectName=\"SimplySerial\" OutputGroup=\"ContentOutput\" OutputFile=\"boards.json_1\"/>\n    <ROW ProjectId=\"{3c7db929-519c-44a3-a68f-2646cc595cae}\" ProjectName=\"SimplySerial\" OutputGroup=\"References\" OutputFile=\"Newtonsoft.Json.dll\"/>\n  </COMPONENT>\n</DOCUMENT>\n"
  },
  {
    "path": "Installer-System/Installer-System.aiproj",
    "content": "﻿<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">All</Configuration>\n    <SchemaVersion>2.0</SchemaVersion>\n    <ProjectGuid>d9a5e8d5-c2ff-450d-96e1-d82db339b186</ProjectGuid>\n    <OutputType>msi</OutputType>\n    <ProjectHome>.</ProjectHome>\n    <StartupFile>Installer-System.aip</StartupFile>\n    <SearchPath>\n    </SearchPath>\n    <WorkingDirectory>.</WorkingDirectory>\n    <IsWindowsApplication>True</IsWindowsApplication>\n    <AssemblyName>Installer-System</AssemblyName>\n    <Name>Installer-System</Name>\n    <RootNamespace>Installer-System</RootNamespace>\n    <LoadFromTemplate>\n    </LoadFromTemplate>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)' == 'DefaultBuild' \" />\n  <ItemGroup>\n    <Compile Include=\"Installer-System.aip\">\n      <SubType>Code</SubType>\n    </Compile>\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\SimplySerial\\SimplySerial.csproj\">\n      <Name>SimplySerial</Name>\n      <Project>{3c7db929-519c-44a3-a68f-2646cc595cae}</Project>\n      <Private>True</Private>\n      <CreateShortcut>False</CreateShortcut>\n      <OutputsToImport>PrimaryOutput;References;ContentOutput</OutputsToImport>\n    </ProjectReference>\n  </ItemGroup>\n  <Target Name=\"Build\">\n    <Error Text=\"This project requires Advanced Installer tool. Please download it from https://www.advancedinstaller.com/download.html\" />\n  </Target>\n  <Target Name=\"Rebuild\">\n    <Error Text=\"This project requires Advanced Installer tool. Please download it from https://www.advancedinstaller.com/download.html\" />\n  </Target>\n  <Target Name=\"Clean\">\n  </Target>\n  <Target Name=\"ResolveAssemblyReferences\">\n  </Target>\n  <Import Condition=\"'$(AdvancedInstallerMSBuildTargets)' != ''\" Project=\"$(AdvancedInstallerMSBuildTargets)\\AdvInstExtTasks.Targets\" />\n  <Import Condition=\"('$(AdvancedInstallerMSBuildTargets)' == '') And (Exists('$(MSBuildExtensionsPath32)\\Caphyon\\Advanced Installer\\AdvInstExtTasks.Targets'))\" Project=\"$(MSBuildExtensionsPath32)\\Caphyon\\Advanced Installer\\AdvInstExtTasks.Targets\" />\n</Project>"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2021 Edward Wright (fasteddy516)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "LICENSE.rtf",
    "content": "{\\rtf1\\adeflang1025\\ansi\\ansicpg1252\\uc1\\adeff0\\deff0\\stshfdbch0\\stshfloch31506\\stshfhich31506\\stshfbi31506\\deflang1033\\deflangfe1033\\themelang1033\\themelangfe0\\themelangcs0{\\fonttbl{\\f0\\fbidi \\froman\\fcharset0\\fprq2{\\*\\panose 02020603050405020304}Times New Roman;}{\\f2\\fbidi \\fmodern\\fcharset0\\fprq1{\\*\\panose 02070309020205020404}Courier New;}\n{\\f34\\fbidi \\froman\\fcharset0\\fprq2{\\*\\panose 02040503050406030204}Cambria Math;}{\\f43\\fbidi \\fmodern\\fcharset0\\fprq1{\\*\\panose 00000000000000000000}Consolas;}{\\flomajor\\f31500\\fbidi \\froman\\fcharset0\\fprq2{\\*\\panose 02020603050405020304}Times New Roman;}\n{\\fdbmajor\\f31501\\fbidi \\froman\\fcharset0\\fprq2{\\*\\panose 02020603050405020304}Times New Roman;}{\\fhimajor\\f31502\\fbidi \\fswiss\\fcharset0\\fprq2{\\*\\panose 020f0302020204030204}Calibri Light;}\n{\\fbimajor\\f31503\\fbidi \\froman\\fcharset0\\fprq2{\\*\\panose 02020603050405020304}Times New Roman;}{\\flominor\\f31504\\fbidi \\froman\\fcharset0\\fprq2{\\*\\panose 02020603050405020304}Times New Roman;}\n{\\fdbminor\\f31505\\fbidi \\froman\\fcharset0\\fprq2{\\*\\panose 02020603050405020304}Times New Roman;}{\\fhiminor\\f31506\\fbidi \\fswiss\\fcharset0\\fprq2{\\*\\panose 020f0502020204030204}Calibri;}\n{\\fbiminor\\f31507\\fbidi \\froman\\fcharset0\\fprq2{\\*\\panose 02020603050405020304}Times New Roman;}{\\f44\\fbidi \\froman\\fcharset238\\fprq2 Times New Roman CE;}{\\f45\\fbidi \\froman\\fcharset204\\fprq2 Times New Roman Cyr;}\n{\\f47\\fbidi \\froman\\fcharset161\\fprq2 Times New Roman Greek;}{\\f48\\fbidi \\froman\\fcharset162\\fprq2 Times New Roman Tur;}{\\f49\\fbidi \\froman\\fcharset177\\fprq2 Times New Roman (Hebrew);}{\\f50\\fbidi \\froman\\fcharset178\\fprq2 Times New Roman (Arabic);}\n{\\f51\\fbidi \\froman\\fcharset186\\fprq2 Times New Roman Baltic;}{\\f52\\fbidi \\froman\\fcharset163\\fprq2 Times New Roman (Vietnamese);}{\\f64\\fbidi \\fmodern\\fcharset238\\fprq1 Courier New CE;}{\\f65\\fbidi \\fmodern\\fcharset204\\fprq1 Courier New Cyr;}\n{\\f67\\fbidi \\fmodern\\fcharset161\\fprq1 Courier New Greek;}{\\f68\\fbidi \\fmodern\\fcharset162\\fprq1 Courier New Tur;}{\\f69\\fbidi \\fmodern\\fcharset177\\fprq1 Courier New (Hebrew);}{\\f70\\fbidi \\fmodern\\fcharset178\\fprq1 Courier New (Arabic);}\n{\\f71\\fbidi \\fmodern\\fcharset186\\fprq1 Courier New Baltic;}{\\f72\\fbidi \\fmodern\\fcharset163\\fprq1 Courier New (Vietnamese);}{\\f474\\fbidi \\fmodern\\fcharset238\\fprq1 Consolas CE;}{\\f475\\fbidi \\fmodern\\fcharset204\\fprq1 Consolas Cyr;}\n{\\f477\\fbidi \\fmodern\\fcharset161\\fprq1 Consolas Greek;}{\\f478\\fbidi \\fmodern\\fcharset162\\fprq1 Consolas Tur;}{\\f481\\fbidi \\fmodern\\fcharset186\\fprq1 Consolas Baltic;}{\\f482\\fbidi \\fmodern\\fcharset163\\fprq1 Consolas (Vietnamese);}\n{\\flomajor\\f31508\\fbidi \\froman\\fcharset238\\fprq2 Times New Roman CE;}{\\flomajor\\f31509\\fbidi \\froman\\fcharset204\\fprq2 Times New Roman Cyr;}{\\flomajor\\f31511\\fbidi \\froman\\fcharset161\\fprq2 Times New Roman Greek;}\n{\\flomajor\\f31512\\fbidi \\froman\\fcharset162\\fprq2 Times New Roman Tur;}{\\flomajor\\f31513\\fbidi \\froman\\fcharset177\\fprq2 Times New Roman (Hebrew);}{\\flomajor\\f31514\\fbidi \\froman\\fcharset178\\fprq2 Times New Roman (Arabic);}\n{\\flomajor\\f31515\\fbidi \\froman\\fcharset186\\fprq2 Times New Roman Baltic;}{\\flomajor\\f31516\\fbidi \\froman\\fcharset163\\fprq2 Times New Roman (Vietnamese);}{\\fdbmajor\\f31518\\fbidi \\froman\\fcharset238\\fprq2 Times New Roman CE;}\n{\\fdbmajor\\f31519\\fbidi \\froman\\fcharset204\\fprq2 Times New Roman Cyr;}{\\fdbmajor\\f31521\\fbidi \\froman\\fcharset161\\fprq2 Times New Roman Greek;}{\\fdbmajor\\f31522\\fbidi \\froman\\fcharset162\\fprq2 Times New Roman Tur;}\n{\\fdbmajor\\f31523\\fbidi \\froman\\fcharset177\\fprq2 Times New Roman (Hebrew);}{\\fdbmajor\\f31524\\fbidi \\froman\\fcharset178\\fprq2 Times New Roman (Arabic);}{\\fdbmajor\\f31525\\fbidi \\froman\\fcharset186\\fprq2 Times New Roman Baltic;}\n{\\fdbmajor\\f31526\\fbidi \\froman\\fcharset163\\fprq2 Times New Roman (Vietnamese);}{\\fhimajor\\f31528\\fbidi \\fswiss\\fcharset238\\fprq2 Calibri Light CE;}{\\fhimajor\\f31529\\fbidi \\fswiss\\fcharset204\\fprq2 Calibri Light Cyr;}\n{\\fhimajor\\f31531\\fbidi \\fswiss\\fcharset161\\fprq2 Calibri Light Greek;}{\\fhimajor\\f31532\\fbidi \\fswiss\\fcharset162\\fprq2 Calibri Light Tur;}{\\fhimajor\\f31533\\fbidi \\fswiss\\fcharset177\\fprq2 Calibri Light (Hebrew);}\n{\\fhimajor\\f31534\\fbidi \\fswiss\\fcharset178\\fprq2 Calibri Light (Arabic);}{\\fhimajor\\f31535\\fbidi \\fswiss\\fcharset186\\fprq2 Calibri Light Baltic;}{\\fhimajor\\f31536\\fbidi \\fswiss\\fcharset163\\fprq2 Calibri Light (Vietnamese);}\n{\\fbimajor\\f31538\\fbidi \\froman\\fcharset238\\fprq2 Times New Roman CE;}{\\fbimajor\\f31539\\fbidi \\froman\\fcharset204\\fprq2 Times New Roman Cyr;}{\\fbimajor\\f31541\\fbidi \\froman\\fcharset161\\fprq2 Times New Roman Greek;}\n{\\fbimajor\\f31542\\fbidi \\froman\\fcharset162\\fprq2 Times New Roman Tur;}{\\fbimajor\\f31543\\fbidi \\froman\\fcharset177\\fprq2 Times New Roman (Hebrew);}{\\fbimajor\\f31544\\fbidi \\froman\\fcharset178\\fprq2 Times New Roman (Arabic);}\n{\\fbimajor\\f31545\\fbidi \\froman\\fcharset186\\fprq2 Times New Roman Baltic;}{\\fbimajor\\f31546\\fbidi \\froman\\fcharset163\\fprq2 Times New Roman (Vietnamese);}{\\flominor\\f31548\\fbidi \\froman\\fcharset238\\fprq2 Times New Roman CE;}\n{\\flominor\\f31549\\fbidi \\froman\\fcharset204\\fprq2 Times New Roman Cyr;}{\\flominor\\f31551\\fbidi \\froman\\fcharset161\\fprq2 Times New Roman Greek;}{\\flominor\\f31552\\fbidi \\froman\\fcharset162\\fprq2 Times New Roman Tur;}\n{\\flominor\\f31553\\fbidi \\froman\\fcharset177\\fprq2 Times New Roman (Hebrew);}{\\flominor\\f31554\\fbidi \\froman\\fcharset178\\fprq2 Times New Roman (Arabic);}{\\flominor\\f31555\\fbidi \\froman\\fcharset186\\fprq2 Times New Roman Baltic;}\n{\\flominor\\f31556\\fbidi \\froman\\fcharset163\\fprq2 Times New Roman (Vietnamese);}{\\fdbminor\\f31558\\fbidi \\froman\\fcharset238\\fprq2 Times New Roman CE;}{\\fdbminor\\f31559\\fbidi \\froman\\fcharset204\\fprq2 Times New Roman Cyr;}\n{\\fdbminor\\f31561\\fbidi \\froman\\fcharset161\\fprq2 Times New Roman Greek;}{\\fdbminor\\f31562\\fbidi \\froman\\fcharset162\\fprq2 Times New Roman Tur;}{\\fdbminor\\f31563\\fbidi \\froman\\fcharset177\\fprq2 Times New Roman (Hebrew);}\n{\\fdbminor\\f31564\\fbidi \\froman\\fcharset178\\fprq2 Times New Roman (Arabic);}{\\fdbminor\\f31565\\fbidi \\froman\\fcharset186\\fprq2 Times New Roman Baltic;}{\\fdbminor\\f31566\\fbidi \\froman\\fcharset163\\fprq2 Times New Roman (Vietnamese);}\n{\\fhiminor\\f31568\\fbidi \\fswiss\\fcharset238\\fprq2 Calibri CE;}{\\fhiminor\\f31569\\fbidi \\fswiss\\fcharset204\\fprq2 Calibri Cyr;}{\\fhiminor\\f31571\\fbidi \\fswiss\\fcharset161\\fprq2 Calibri Greek;}{\\fhiminor\\f31572\\fbidi \\fswiss\\fcharset162\\fprq2 Calibri Tur;}\n{\\fhiminor\\f31573\\fbidi \\fswiss\\fcharset177\\fprq2 Calibri (Hebrew);}{\\fhiminor\\f31574\\fbidi \\fswiss\\fcharset178\\fprq2 Calibri (Arabic);}{\\fhiminor\\f31575\\fbidi \\fswiss\\fcharset186\\fprq2 Calibri Baltic;}\n{\\fhiminor\\f31576\\fbidi \\fswiss\\fcharset163\\fprq2 Calibri (Vietnamese);}{\\fbiminor\\f31578\\fbidi \\froman\\fcharset238\\fprq2 Times New Roman CE;}{\\fbiminor\\f31579\\fbidi \\froman\\fcharset204\\fprq2 Times New Roman Cyr;}\n{\\fbiminor\\f31581\\fbidi \\froman\\fcharset161\\fprq2 Times New Roman Greek;}{\\fbiminor\\f31582\\fbidi \\froman\\fcharset162\\fprq2 Times New Roman Tur;}{\\fbiminor\\f31583\\fbidi \\froman\\fcharset177\\fprq2 Times New Roman (Hebrew);}\n{\\fbiminor\\f31584\\fbidi \\froman\\fcharset178\\fprq2 Times New Roman (Arabic);}{\\fbiminor\\f31585\\fbidi \\froman\\fcharset186\\fprq2 Times New Roman Baltic;}{\\fbiminor\\f31586\\fbidi \\froman\\fcharset163\\fprq2 Times New Roman (Vietnamese);}}\n{\\colortbl;\\red0\\green0\\blue0;\\red0\\green0\\blue255;\\red0\\green255\\blue255;\\red0\\green255\\blue0;\\red255\\green0\\blue255;\\red255\\green0\\blue0;\\red255\\green255\\blue0;\\red255\\green255\\blue255;\\red0\\green0\\blue128;\\red0\\green128\\blue128;\\red0\\green128\\blue0;\n\\red128\\green0\\blue128;\\red128\\green0\\blue0;\\red128\\green128\\blue0;\\red128\\green128\\blue128;\\red192\\green192\\blue192;\\red0\\green0\\blue0;\\red0\\green0\\blue0;}{\\*\\defchp \\f31506\\fs22 }{\\*\\defpap \\ql \\li0\\ri0\\sa160\\sl259\\slmult1\n\\widctlpar\\wrapdefault\\aspalpha\\aspnum\\faauto\\adjustright\\rin0\\lin0\\itap0 }\\noqfpromote {\\stylesheet{\\ql \\li0\\ri0\\sa160\\sl259\\slmult1\\widctlpar\\wrapdefault\\aspalpha\\aspnum\\faauto\\adjustright\\rin0\\lin0\\itap0 \\rtlch\\fcs1 \\af0\\afs22\\alang1025 \\ltrch\\fcs0 \n\\f31506\\fs22\\lang1033\\langfe1033\\cgrid\\langnp1033\\langfenp1033 \\snext0 \\sqformat \\spriority0 Normal;}{\\*\\cs10 \\additive \\ssemihidden \\sunhideused \\spriority1 Default Paragraph Font;}{\\*\n\\ts11\\tsrowd\\trftsWidthB3\\trpaddl108\\trpaddr108\\trpaddfl3\\trpaddft3\\trpaddfb3\\trpaddfr3\\trcbpat1\\trcfpat1\\tblind0\\tblindtype3\\tsvertalt\\tsbrdrt\\tsbrdrl\\tsbrdrb\\tsbrdrr\\tsbrdrdgl\\tsbrdrdgr\\tsbrdrh\\tsbrdrv \\ql \\li0\\ri0\\sa160\\sl259\\slmult1\n\\widctlpar\\wrapdefault\\aspalpha\\aspnum\\faauto\\adjustright\\rin0\\lin0\\itap0 \\rtlch\\fcs1 \\af31506\\afs22\\alang1025 \\ltrch\\fcs0 \\f31506\\fs22\\lang1033\\langfe1033\\cgrid\\langnp1033\\langfenp1033 \\snext11 \\ssemihidden \\sunhideused Normal Table;}{\n\\s15\\ql \\li0\\ri0\\widctlpar\\wrapdefault\\aspalpha\\aspnum\\faauto\\adjustright\\rin0\\lin0\\itap0 \\rtlch\\fcs1 \\af0\\afs21\\alang1025 \\ltrch\\fcs0 \\f43\\fs21\\lang1033\\langfe1033\\cgrid\\langnp1033\\langfenp1033 \\sbasedon0 \\snext15 \\slink16 \\sunhideused Plain Text;}{\\*\n\\cs16 \\additive \\rtlch\\fcs1 \\af0\\afs21 \\ltrch\\fcs0 \\f43\\fs21 \\sbasedon10 \\slink15 \\slocked Plain Text Char;}}{\\*\\rsidtbl \\rsid2819995\\rsid4285308}{\\mmathPr\\mmathFont34\\mbrkBin0\\mbrkBinSub0\\msmallFrac0\\mdispDef1\\mlMargin0\\mrMargin0\\mdefJc1\\mwrapIndent1440\n\\mintLim0\\mnaryLim1}{\\info{\\author word}{\\operator Edward Wright}{\\creatim\\yr2019\\mo6\\dy10\\hr18\\min30}{\\revtim\\yr2021\\mo5\\dy9\\hr20\\min41}{\\version3}{\\edmins0}{\\nofpages1}{\\nofwords161}{\\nofchars923}{\\nofcharsws1082}{\\vern23}}{\\*\\xmlnstbl {\\xmlns1 http://s\nchemas.microsoft.com/office/word/2003/wordml}}\\paperw12240\\paperh15840\\margl1501\\margr1502\\margt1440\\margb1440\\gutter0\\ltrsect \n\\widowctrl\\ftnbj\\aenddoc\\trackmoves0\\trackformatting1\\donotembedsysfont1\\relyonvml0\\donotembedlingdata0\\grfdocevents0\\validatexml1\\showplaceholdtext0\\ignoremixedcontent0\\saveinvalidxml0\\showxmlerrors1\\noxlattoyen\n\\expshrtn\\noultrlspc\\dntblnsbdb\\nospaceforul\\formshade\\horzdoc\\dgmargin\\dghspace180\\dgvspace180\\dghorigin1501\\dgvorigin1440\\dghshow1\\dgvshow1\n\\jexpand\\viewkind1\\viewscale100\\pgbrdrhead\\pgbrdrfoot\\splytwnine\\ftnlytwnine\\htmautsp\\nolnhtadjtbl\\useltbaln\\alntblind\\lytcalctblwd\\lyttblrtgr\\lnbrkrule\\nobrkwrptbl\\snaptogridincell\\allowfieldendsel\\wrppunct\n\\asianbrkrule\\rsidroot2819995\\newtblstyruls\\nogrowautofit\\usenormstyforlist\\noindnmbrts\\felnbrelev\\nocxsptable\\indrlsweleven\\noafcnsttbl\\afelev\\utinl\\hwelev\\spltpgpar\\notcvasp\\notbrkcnstfrctbl\\notvatxbx\\krnprsnet\\cachedcolbal \\nouicompat \\fet0\n{\\*\\wgrffmtfilter 2450}\\nofeaturethrottle1\\ilfomacatclnup0\\ltrpar \\sectd \\ltrsect\\linex0\\endnhere\\sectlinegrid360\\sectdefaultcl\\sftnbj {\\*\\pnseclvl1\\pnucrm\\pnstart1\\pnindent720\\pnhang {\\pntxta .}}{\\*\\pnseclvl2\\pnucltr\\pnstart1\\pnindent720\\pnhang \n{\\pntxta .}}{\\*\\pnseclvl3\\pndec\\pnstart1\\pnindent720\\pnhang {\\pntxta .}}{\\*\\pnseclvl4\\pnlcltr\\pnstart1\\pnindent720\\pnhang {\\pntxta )}}{\\*\\pnseclvl5\\pndec\\pnstart1\\pnindent720\\pnhang {\\pntxtb (}{\\pntxta )}}{\\*\\pnseclvl6\\pnlcltr\\pnstart1\\pnindent720\\pnhang \n{\\pntxtb (}{\\pntxta )}}{\\*\\pnseclvl7\\pnlcrm\\pnstart1\\pnindent720\\pnhang {\\pntxtb (}{\\pntxta )}}{\\*\\pnseclvl8\\pnlcltr\\pnstart1\\pnindent720\\pnhang {\\pntxtb (}{\\pntxta )}}{\\*\\pnseclvl9\\pnlcrm\\pnstart1\\pnindent720\\pnhang {\\pntxtb (}{\\pntxta )}}\n\\pard\\plain \\ltrpar\\s15\\ql \\li0\\ri0\\widctlpar\\wrapdefault\\aspalpha\\aspnum\\faauto\\adjustright\\rin0\\lin0\\itap0 \\rtlch\\fcs1 \\af0\\afs21\\alang1025 \\ltrch\\fcs0 \\f43\\fs21\\lang1033\\langfe1033\\cgrid\\langnp1033\\langfenp1033 {\\rtlch\\fcs1 \\af2 \\ltrch\\fcs0 \n\\f2\\insrsid4285308 MIT License\n\\par \n\\par Copyright (c) 20}{\\rtlch\\fcs1 \\af2 \\ltrch\\fcs0 \\f2\\insrsid2819995 21}{\\rtlch\\fcs1 \\af2 \\ltrch\\fcs0 \\f2\\insrsid4285308  Edward Wright (fasteddy516)\n\\par \n\\par Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, m\nerge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\\par \n\\par The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\\par \n\\par THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN N\nO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.}\n{\\rtlch\\fcs1 \\af2 \\ltrch\\fcs0 \\f2\\insrsid4285308 \n\\par }{\\*\\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a\n9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad\n5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6\nb01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0\n0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6\na7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f\nc7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512\n0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462\na1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865\n6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b\n4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b\n4757e8d3f729e245eb2b260a0238fd010000ffff0300504b03041400060008000000210007b740aaca0600008f1a0000160000007468656d652f7468656d652f\n7468656d65312e786d6cec595b8bdb46147e2ff43f08bd3bbe49be2cf1065bb69336bb49889d943cceda636bb2238dd18c776342a0244f7d2914d2d28706fad6\n87521a68a0a12ffd310b1bdaf447f4cc489667ec71f6420aa1640d8b34face996fce39face48ba7aed51449d239c70c2e2965bbe52721d1c8fd898c4d3967b6f\nd82f345c870b148f1165316eb90bccdd6bbb9f7e7215ed881047d801fb98efa0961b0a31db2916f9088611bfc26638866b13964448c069322d8e13740c7e235a\nac944ab5628448ec3a318ac0ededc9848cb033942edddda5f31e85d358703930a2c940bac68685c28e0fcb12c1173ca089738468cb8579c6ec78881f09d7a188\n0bb8d0724beacf2dee5e2da29dcc888a2db69a5d5ffd657699c1f8b0a2e64ca607f9a49ee77bb576ee5f01a8d8c4f5eabd5aaf96fb5300341ac14a532eba4fbf\nd3ec74fd0cab81d2438bef6ebd5b2d1b78cd7f758373db973f03af40a97f6f03dfef07104503af4029dedfc07b5ebd1278065e81527c6d035f2fb5bb5eddc02b\n5048497cb8812ef9b56ab05c6d0e99307ac30a6ffa5ebf5ec99caf50500d7975c929262c16db6a2d420f59d2078004522448ec88c50c4fd008aa3840941c24c4\nd923d3100a6f8662c661b85429f54b55f82f7f9e3a5211413b1869d6921730e11b43928fc34709998996fb39787535c8e9ebd7274f5f9d3cfdfde4d9b393a7bf\n66732b5786dd0d144f75bbb73f7df3cf8b2f9dbf7ffbf1edf36fd3a9d7f15cc7bff9e5ab377ffcf92ef7b0e255284ebf7bf9e6d5cbd3efbffeebe7e716efed04\n1de8f0218930776ee163e72e8b608116fef820b998c5304444b768c7538e622467b1f8ef89d040df5a208a2cb80e36e3783f01a9b101afcf1f1a8407613217c4\ne2f1661819c07dc6688725d628dc947369611ecee3a97df264aee3ee2274649b3b40b191e5de7c061a4b6c2e83101b34ef50140b34c531168ebcc60e31b6acee\n0121465cf7c928619c4d84f380381d44ac21199203a39a56463748047959d80842be8dd8ecdf773a8cda56ddc5472612ee0d442de487981a61bc8ee602453697\n4314513de07b48843692834532d2713d2e20d3534c99d31b63ce6d36b71358af96f49b2033f6b4efd345642213410e6d3ef710633ab2cb0e831045331b7640e2\n50c77ec60fa144917387091b7c9f9977883c873ca0786bbaef136ca4fb6c35b8070aab535a1588bc324f2cb9bc8e9951bf83059d20aca4061a80a1eb1189cf14\nf93579f7ff3b7907113dfde1856545ef47d2ed8e8d7c5c50ccdb09b1de4d37d6247c1b6e5db803968cc987afdb5d348fef60b855369bd747d9fe28dbeeff5eb6\nb7ddcfef5fac57fa0cd22db7ade9765d6ddea3ad7bf709a174201614ef71b57de7d095c67d189476eab915e7cf72b3100ee59d0c1318b86982948d9330f10511\ne1204433d8e3975de964ca33d753eecc1887adbf1ab6fa96783a8ff6d9387d642d97e5e3692a1e1c89d578c9cfc7e17143a4e85a7df51896bb576ca7ea717949\n40da5e8484369949a26a21515f0eca20a98773089a85845ad97b61d1b4b06848f7cb546db0006a795660dbe4c066abe5fa1e9880113c55218ac7324f69aa97d9\n55c97c9f99de164ca302600fb1ac8055a69b92ebd6e5c9d5a5a5768e4c1b24b4723349a8c8a81ec64334c65975cad1f3d0b868ae9bab941af46428d47c505a2b\n1af5c6bb585c36d760b7ae0d34d69582c6ce71cbad557d2899119ab5dc093cfac3613483dae172bb8be814de9f8d4492def097519659c24517f1300db8129d54\n0d222270e25012b55cb9fc3c0d34561aa2b8952b20081f2cb926c8ca87460e926e26194f267824f4b46b2332d2e929287caa15d6abcafcf26069c9e690ee4138\n3e760ee83cb98ba0c4fc7a5906704c38bc012aa7d11c1378a5990bd9aafed61a5326bbfa3b455543e938a2b310651d4517f314aea43ca7a3cef2186867d99a21\na05a48b2467830950d560faad14df3ae9172d8da75cf369291d34473d5330d55915dd3ae62c60ccb36b016cbcb35798dd532c4a0697a874fa57b5d729b4bad5b\ndb27e45d02029ec7cfd275cfd110346aabc90c6a92f1a60c4bcdce46cddeb15ce019d4ced32434d5af2dddaec52def11d6e960f0529d1fecd6ab168626cb7da5\n8ab4faf6a17f9e60070f413cbaf022784e0557a9848f0f09820dd140ed4952d9805be491c86e0d3872e60969b98f4b7edb0b2a7e502835fc5ec1ab7aa542c36f\n570b6ddfaf967b7eb9d4ed549e4063116154f6d3ef2e7d780d4517d9d71735bef105265abe69bb32625191a92f2c45455c7d812957b67f81710888cee35aa5df\nac363bb542b3daee17bc6ea7516806b54ea15b0beadd7e37f01bcdfe13d7395260af5d0dbc5aaf51a89583a0e0d54a927ea359a87b954adbabb71b3daffd24db\nc6c0ca53f9c86201e155bc76ff050000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f7468656d652f5f72\n656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f2451eced0dae2c08\n2e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e3198720e274a939cd0\n8a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d9850528a2c6cce0239baa\n4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100e9de0fbfff0000001c0200001300000000000000000000000000000000005b436f\n6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b00000000000000000000000000300100005f72\n656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c00000000000000000000000000190200007468656d652f746865\n6d652f7468656d654d616e616765722e786d6c504b01022d001400060008000000210007b740aaca0600008f1a00001600000000000000000000000000d60200\n007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b01000027000000000000000000000000\n00d40900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000cf0a00000000}\n{\\*\\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d\n617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169\n6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363\n656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e}\n{\\*\\latentstyles\\lsdstimax376\\lsdlockeddef0\\lsdsemihiddendef0\\lsdunhideuseddef0\\lsdqformatdef0\\lsdprioritydef99{\\lsdlockedexcept \\lsdqformat1 \\lsdpriority0 \\lsdlocked0 Normal;\\lsdqformat1 \\lsdpriority9 \\lsdlocked0 heading 1;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdqformat1 \\lsdpriority9 \\lsdlocked0 heading 2;\\lsdsemihidden1 \\lsdunhideused1 \\lsdqformat1 \\lsdpriority9 \\lsdlocked0 heading 3;\\lsdsemihidden1 \\lsdunhideused1 \\lsdqformat1 \\lsdpriority9 \\lsdlocked0 heading 4;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdqformat1 \\lsdpriority9 \\lsdlocked0 heading 5;\\lsdsemihidden1 \\lsdunhideused1 \\lsdqformat1 \\lsdpriority9 \\lsdlocked0 heading 6;\\lsdsemihidden1 \\lsdunhideused1 \\lsdqformat1 \\lsdpriority9 \\lsdlocked0 heading 7;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdqformat1 \\lsdpriority9 \\lsdlocked0 heading 8;\\lsdsemihidden1 \\lsdunhideused1 \\lsdqformat1 \\lsdpriority9 \\lsdlocked0 heading 9;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 index 1;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 index 2;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 index 3;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 index 4;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 index 5;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 index 6;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 index 7;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 index 8;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 index 9;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdpriority39 \\lsdlocked0 toc 1;\\lsdsemihidden1 \\lsdunhideused1 \\lsdpriority39 \\lsdlocked0 toc 2;\\lsdsemihidden1 \\lsdunhideused1 \\lsdpriority39 \\lsdlocked0 toc 3;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdpriority39 \\lsdlocked0 toc 4;\\lsdsemihidden1 \\lsdunhideused1 \\lsdpriority39 \\lsdlocked0 toc 5;\\lsdsemihidden1 \\lsdunhideused1 \\lsdpriority39 \\lsdlocked0 toc 6;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdpriority39 \\lsdlocked0 toc 7;\\lsdsemihidden1 \\lsdunhideused1 \\lsdpriority39 \\lsdlocked0 toc 8;\\lsdsemihidden1 \\lsdunhideused1 \\lsdpriority39 \\lsdlocked0 toc 9;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Normal Indent;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 footnote text;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 annotation text;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 header;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 footer;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 index heading;\\lsdsemihidden1 \\lsdunhideused1 \\lsdqformat1 \\lsdpriority35 \\lsdlocked0 caption;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 table of figures;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 envelope address;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 envelope return;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 footnote reference;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 annotation reference;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 line number;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 page number;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 endnote reference;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 endnote text;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 table of authorities;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 macro;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 toa heading;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 List;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 List Bullet;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 List Number;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 List 2;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 List 3;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 List 4;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 List 5;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 List Bullet 2;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 List Bullet 3;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 List Bullet 4;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 List Bullet 5;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 List Number 2;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 List Number 3;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 List Number 4;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 List Number 5;\\lsdqformat1 \\lsdpriority10 \\lsdlocked0 Title;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Closing;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Signature;\\lsdsemihidden1 \\lsdunhideused1 \\lsdpriority1 \\lsdlocked0 Default Paragraph Font;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Body Text;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Body Text Indent;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 List Continue;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 List Continue 2;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 List Continue 3;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 List Continue 4;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 List Continue 5;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Message Header;\\lsdqformat1 \\lsdpriority11 \\lsdlocked0 Subtitle;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Salutation;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Date;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Body Text First Indent;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Body Text First Indent 2;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Note Heading;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Body Text 2;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Body Text 3;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Body Text Indent 2;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Body Text Indent 3;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Block Text;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Hyperlink;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 FollowedHyperlink;\\lsdqformat1 \\lsdpriority22 \\lsdlocked0 Strong;\n\\lsdqformat1 \\lsdpriority20 \\lsdlocked0 Emphasis;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Document Map;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Plain Text;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 E-mail Signature;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 HTML Top of Form;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 HTML Bottom of Form;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Normal (Web);\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 HTML Acronym;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 HTML Address;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 HTML Cite;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 HTML Code;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 HTML Definition;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 HTML Keyboard;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 HTML Preformatted;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 HTML Sample;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 HTML Typewriter;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 HTML Variable;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 annotation subject;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 No List;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Outline List 1;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Outline List 2;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Outline List 3;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Balloon Text;\\lsdpriority39 \\lsdlocked0 Table Grid;\n\\lsdsemihidden1 \\lsdlocked0 Placeholder Text;\\lsdqformat1 \\lsdpriority1 \\lsdlocked0 No Spacing;\\lsdpriority60 \\lsdlocked0 Light Shading;\\lsdpriority61 \\lsdlocked0 Light List;\\lsdpriority62 \\lsdlocked0 Light Grid;\n\\lsdpriority63 \\lsdlocked0 Medium Shading 1;\\lsdpriority64 \\lsdlocked0 Medium Shading 2;\\lsdpriority65 \\lsdlocked0 Medium List 1;\\lsdpriority66 \\lsdlocked0 Medium List 2;\\lsdpriority67 \\lsdlocked0 Medium Grid 1;\\lsdpriority68 \\lsdlocked0 Medium Grid 2;\n\\lsdpriority69 \\lsdlocked0 Medium Grid 3;\\lsdpriority70 \\lsdlocked0 Dark List;\\lsdpriority71 \\lsdlocked0 Colorful Shading;\\lsdpriority72 \\lsdlocked0 Colorful List;\\lsdpriority73 \\lsdlocked0 Colorful Grid;\\lsdpriority60 \\lsdlocked0 Light Shading Accent 1;\n\\lsdpriority61 \\lsdlocked0 Light List Accent 1;\\lsdpriority62 \\lsdlocked0 Light Grid Accent 1;\\lsdpriority63 \\lsdlocked0 Medium Shading 1 Accent 1;\\lsdpriority64 \\lsdlocked0 Medium Shading 2 Accent 1;\\lsdpriority65 \\lsdlocked0 Medium List 1 Accent 1;\n\\lsdsemihidden1 \\lsdlocked0 Revision;\\lsdqformat1 \\lsdpriority34 \\lsdlocked0 List Paragraph;\\lsdqformat1 \\lsdpriority29 \\lsdlocked0 Quote;\\lsdqformat1 \\lsdpriority30 \\lsdlocked0 Intense Quote;\\lsdpriority66 \\lsdlocked0 Medium List 2 Accent 1;\n\\lsdpriority67 \\lsdlocked0 Medium Grid 1 Accent 1;\\lsdpriority68 \\lsdlocked0 Medium Grid 2 Accent 1;\\lsdpriority69 \\lsdlocked0 Medium Grid 3 Accent 1;\\lsdpriority70 \\lsdlocked0 Dark List Accent 1;\\lsdpriority71 \\lsdlocked0 Colorful Shading Accent 1;\n\\lsdpriority72 \\lsdlocked0 Colorful List Accent 1;\\lsdpriority73 \\lsdlocked0 Colorful Grid Accent 1;\\lsdpriority60 \\lsdlocked0 Light Shading Accent 2;\\lsdpriority61 \\lsdlocked0 Light List Accent 2;\\lsdpriority62 \\lsdlocked0 Light Grid Accent 2;\n\\lsdpriority63 \\lsdlocked0 Medium Shading 1 Accent 2;\\lsdpriority64 \\lsdlocked0 Medium Shading 2 Accent 2;\\lsdpriority65 \\lsdlocked0 Medium List 1 Accent 2;\\lsdpriority66 \\lsdlocked0 Medium List 2 Accent 2;\n\\lsdpriority67 \\lsdlocked0 Medium Grid 1 Accent 2;\\lsdpriority68 \\lsdlocked0 Medium Grid 2 Accent 2;\\lsdpriority69 \\lsdlocked0 Medium Grid 3 Accent 2;\\lsdpriority70 \\lsdlocked0 Dark List Accent 2;\\lsdpriority71 \\lsdlocked0 Colorful Shading Accent 2;\n\\lsdpriority72 \\lsdlocked0 Colorful List Accent 2;\\lsdpriority73 \\lsdlocked0 Colorful Grid Accent 2;\\lsdpriority60 \\lsdlocked0 Light Shading Accent 3;\\lsdpriority61 \\lsdlocked0 Light List Accent 3;\\lsdpriority62 \\lsdlocked0 Light Grid Accent 3;\n\\lsdpriority63 \\lsdlocked0 Medium Shading 1 Accent 3;\\lsdpriority64 \\lsdlocked0 Medium Shading 2 Accent 3;\\lsdpriority65 \\lsdlocked0 Medium List 1 Accent 3;\\lsdpriority66 \\lsdlocked0 Medium List 2 Accent 3;\n\\lsdpriority67 \\lsdlocked0 Medium Grid 1 Accent 3;\\lsdpriority68 \\lsdlocked0 Medium Grid 2 Accent 3;\\lsdpriority69 \\lsdlocked0 Medium Grid 3 Accent 3;\\lsdpriority70 \\lsdlocked0 Dark List Accent 3;\\lsdpriority71 \\lsdlocked0 Colorful Shading Accent 3;\n\\lsdpriority72 \\lsdlocked0 Colorful List Accent 3;\\lsdpriority73 \\lsdlocked0 Colorful Grid Accent 3;\\lsdpriority60 \\lsdlocked0 Light Shading Accent 4;\\lsdpriority61 \\lsdlocked0 Light List Accent 4;\\lsdpriority62 \\lsdlocked0 Light Grid Accent 4;\n\\lsdpriority63 \\lsdlocked0 Medium Shading 1 Accent 4;\\lsdpriority64 \\lsdlocked0 Medium Shading 2 Accent 4;\\lsdpriority65 \\lsdlocked0 Medium List 1 Accent 4;\\lsdpriority66 \\lsdlocked0 Medium List 2 Accent 4;\n\\lsdpriority67 \\lsdlocked0 Medium Grid 1 Accent 4;\\lsdpriority68 \\lsdlocked0 Medium Grid 2 Accent 4;\\lsdpriority69 \\lsdlocked0 Medium Grid 3 Accent 4;\\lsdpriority70 \\lsdlocked0 Dark List Accent 4;\\lsdpriority71 \\lsdlocked0 Colorful Shading Accent 4;\n\\lsdpriority72 \\lsdlocked0 Colorful List Accent 4;\\lsdpriority73 \\lsdlocked0 Colorful Grid Accent 4;\\lsdpriority60 \\lsdlocked0 Light Shading Accent 5;\\lsdpriority61 \\lsdlocked0 Light List Accent 5;\\lsdpriority62 \\lsdlocked0 Light Grid Accent 5;\n\\lsdpriority63 \\lsdlocked0 Medium Shading 1 Accent 5;\\lsdpriority64 \\lsdlocked0 Medium Shading 2 Accent 5;\\lsdpriority65 \\lsdlocked0 Medium List 1 Accent 5;\\lsdpriority66 \\lsdlocked0 Medium List 2 Accent 5;\n\\lsdpriority67 \\lsdlocked0 Medium Grid 1 Accent 5;\\lsdpriority68 \\lsdlocked0 Medium Grid 2 Accent 5;\\lsdpriority69 \\lsdlocked0 Medium Grid 3 Accent 5;\\lsdpriority70 \\lsdlocked0 Dark List Accent 5;\\lsdpriority71 \\lsdlocked0 Colorful Shading Accent 5;\n\\lsdpriority72 \\lsdlocked0 Colorful List Accent 5;\\lsdpriority73 \\lsdlocked0 Colorful Grid Accent 5;\\lsdpriority60 \\lsdlocked0 Light Shading Accent 6;\\lsdpriority61 \\lsdlocked0 Light List Accent 6;\\lsdpriority62 \\lsdlocked0 Light Grid Accent 6;\n\\lsdpriority63 \\lsdlocked0 Medium Shading 1 Accent 6;\\lsdpriority64 \\lsdlocked0 Medium Shading 2 Accent 6;\\lsdpriority65 \\lsdlocked0 Medium List 1 Accent 6;\\lsdpriority66 \\lsdlocked0 Medium List 2 Accent 6;\n\\lsdpriority67 \\lsdlocked0 Medium Grid 1 Accent 6;\\lsdpriority68 \\lsdlocked0 Medium Grid 2 Accent 6;\\lsdpriority69 \\lsdlocked0 Medium Grid 3 Accent 6;\\lsdpriority70 \\lsdlocked0 Dark List Accent 6;\\lsdpriority71 \\lsdlocked0 Colorful Shading Accent 6;\n\\lsdpriority72 \\lsdlocked0 Colorful List Accent 6;\\lsdpriority73 \\lsdlocked0 Colorful Grid Accent 6;\\lsdqformat1 \\lsdpriority19 \\lsdlocked0 Subtle Emphasis;\\lsdqformat1 \\lsdpriority21 \\lsdlocked0 Intense Emphasis;\n\\lsdqformat1 \\lsdpriority31 \\lsdlocked0 Subtle Reference;\\lsdqformat1 \\lsdpriority32 \\lsdlocked0 Intense Reference;\\lsdqformat1 \\lsdpriority33 \\lsdlocked0 Book Title;\\lsdsemihidden1 \\lsdunhideused1 \\lsdpriority37 \\lsdlocked0 Bibliography;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdqformat1 \\lsdpriority39 \\lsdlocked0 TOC Heading;\\lsdpriority41 \\lsdlocked0 Plain Table 1;\\lsdpriority42 \\lsdlocked0 Plain Table 2;\\lsdpriority43 \\lsdlocked0 Plain Table 3;\\lsdpriority44 \\lsdlocked0 Plain Table 4;\n\\lsdpriority45 \\lsdlocked0 Plain Table 5;\\lsdpriority40 \\lsdlocked0 Grid Table Light;\\lsdpriority46 \\lsdlocked0 Grid Table 1 Light;\\lsdpriority47 \\lsdlocked0 Grid Table 2;\\lsdpriority48 \\lsdlocked0 Grid Table 3;\\lsdpriority49 \\lsdlocked0 Grid Table 4;\n\\lsdpriority50 \\lsdlocked0 Grid Table 5 Dark;\\lsdpriority51 \\lsdlocked0 Grid Table 6 Colorful;\\lsdpriority52 \\lsdlocked0 Grid Table 7 Colorful;\\lsdpriority46 \\lsdlocked0 Grid Table 1 Light Accent 1;\\lsdpriority47 \\lsdlocked0 Grid Table 2 Accent 1;\n\\lsdpriority48 \\lsdlocked0 Grid Table 3 Accent 1;\\lsdpriority49 \\lsdlocked0 Grid Table 4 Accent 1;\\lsdpriority50 \\lsdlocked0 Grid Table 5 Dark Accent 1;\\lsdpriority51 \\lsdlocked0 Grid Table 6 Colorful Accent 1;\n\\lsdpriority52 \\lsdlocked0 Grid Table 7 Colorful Accent 1;\\lsdpriority46 \\lsdlocked0 Grid Table 1 Light Accent 2;\\lsdpriority47 \\lsdlocked0 Grid Table 2 Accent 2;\\lsdpriority48 \\lsdlocked0 Grid Table 3 Accent 2;\n\\lsdpriority49 \\lsdlocked0 Grid Table 4 Accent 2;\\lsdpriority50 \\lsdlocked0 Grid Table 5 Dark Accent 2;\\lsdpriority51 \\lsdlocked0 Grid Table 6 Colorful Accent 2;\\lsdpriority52 \\lsdlocked0 Grid Table 7 Colorful Accent 2;\n\\lsdpriority46 \\lsdlocked0 Grid Table 1 Light Accent 3;\\lsdpriority47 \\lsdlocked0 Grid Table 2 Accent 3;\\lsdpriority48 \\lsdlocked0 Grid Table 3 Accent 3;\\lsdpriority49 \\lsdlocked0 Grid Table 4 Accent 3;\n\\lsdpriority50 \\lsdlocked0 Grid Table 5 Dark Accent 3;\\lsdpriority51 \\lsdlocked0 Grid Table 6 Colorful Accent 3;\\lsdpriority52 \\lsdlocked0 Grid Table 7 Colorful Accent 3;\\lsdpriority46 \\lsdlocked0 Grid Table 1 Light Accent 4;\n\\lsdpriority47 \\lsdlocked0 Grid Table 2 Accent 4;\\lsdpriority48 \\lsdlocked0 Grid Table 3 Accent 4;\\lsdpriority49 \\lsdlocked0 Grid Table 4 Accent 4;\\lsdpriority50 \\lsdlocked0 Grid Table 5 Dark Accent 4;\n\\lsdpriority51 \\lsdlocked0 Grid Table 6 Colorful Accent 4;\\lsdpriority52 \\lsdlocked0 Grid Table 7 Colorful Accent 4;\\lsdpriority46 \\lsdlocked0 Grid Table 1 Light Accent 5;\\lsdpriority47 \\lsdlocked0 Grid Table 2 Accent 5;\n\\lsdpriority48 \\lsdlocked0 Grid Table 3 Accent 5;\\lsdpriority49 \\lsdlocked0 Grid Table 4 Accent 5;\\lsdpriority50 \\lsdlocked0 Grid Table 5 Dark Accent 5;\\lsdpriority51 \\lsdlocked0 Grid Table 6 Colorful Accent 5;\n\\lsdpriority52 \\lsdlocked0 Grid Table 7 Colorful Accent 5;\\lsdpriority46 \\lsdlocked0 Grid Table 1 Light Accent 6;\\lsdpriority47 \\lsdlocked0 Grid Table 2 Accent 6;\\lsdpriority48 \\lsdlocked0 Grid Table 3 Accent 6;\n\\lsdpriority49 \\lsdlocked0 Grid Table 4 Accent 6;\\lsdpriority50 \\lsdlocked0 Grid Table 5 Dark Accent 6;\\lsdpriority51 \\lsdlocked0 Grid Table 6 Colorful Accent 6;\\lsdpriority52 \\lsdlocked0 Grid Table 7 Colorful Accent 6;\n\\lsdpriority46 \\lsdlocked0 List Table 1 Light;\\lsdpriority47 \\lsdlocked0 List Table 2;\\lsdpriority48 \\lsdlocked0 List Table 3;\\lsdpriority49 \\lsdlocked0 List Table 4;\\lsdpriority50 \\lsdlocked0 List Table 5 Dark;\n\\lsdpriority51 \\lsdlocked0 List Table 6 Colorful;\\lsdpriority52 \\lsdlocked0 List Table 7 Colorful;\\lsdpriority46 \\lsdlocked0 List Table 1 Light Accent 1;\\lsdpriority47 \\lsdlocked0 List Table 2 Accent 1;\\lsdpriority48 \\lsdlocked0 List Table 3 Accent 1;\n\\lsdpriority49 \\lsdlocked0 List Table 4 Accent 1;\\lsdpriority50 \\lsdlocked0 List Table 5 Dark Accent 1;\\lsdpriority51 \\lsdlocked0 List Table 6 Colorful Accent 1;\\lsdpriority52 \\lsdlocked0 List Table 7 Colorful Accent 1;\n\\lsdpriority46 \\lsdlocked0 List Table 1 Light Accent 2;\\lsdpriority47 \\lsdlocked0 List Table 2 Accent 2;\\lsdpriority48 \\lsdlocked0 List Table 3 Accent 2;\\lsdpriority49 \\lsdlocked0 List Table 4 Accent 2;\n\\lsdpriority50 \\lsdlocked0 List Table 5 Dark Accent 2;\\lsdpriority51 \\lsdlocked0 List Table 6 Colorful Accent 2;\\lsdpriority52 \\lsdlocked0 List Table 7 Colorful Accent 2;\\lsdpriority46 \\lsdlocked0 List Table 1 Light Accent 3;\n\\lsdpriority47 \\lsdlocked0 List Table 2 Accent 3;\\lsdpriority48 \\lsdlocked0 List Table 3 Accent 3;\\lsdpriority49 \\lsdlocked0 List Table 4 Accent 3;\\lsdpriority50 \\lsdlocked0 List Table 5 Dark Accent 3;\n\\lsdpriority51 \\lsdlocked0 List Table 6 Colorful Accent 3;\\lsdpriority52 \\lsdlocked0 List Table 7 Colorful Accent 3;\\lsdpriority46 \\lsdlocked0 List Table 1 Light Accent 4;\\lsdpriority47 \\lsdlocked0 List Table 2 Accent 4;\n\\lsdpriority48 \\lsdlocked0 List Table 3 Accent 4;\\lsdpriority49 \\lsdlocked0 List Table 4 Accent 4;\\lsdpriority50 \\lsdlocked0 List Table 5 Dark Accent 4;\\lsdpriority51 \\lsdlocked0 List Table 6 Colorful Accent 4;\n\\lsdpriority52 \\lsdlocked0 List Table 7 Colorful Accent 4;\\lsdpriority46 \\lsdlocked0 List Table 1 Light Accent 5;\\lsdpriority47 \\lsdlocked0 List Table 2 Accent 5;\\lsdpriority48 \\lsdlocked0 List Table 3 Accent 5;\n\\lsdpriority49 \\lsdlocked0 List Table 4 Accent 5;\\lsdpriority50 \\lsdlocked0 List Table 5 Dark Accent 5;\\lsdpriority51 \\lsdlocked0 List Table 6 Colorful Accent 5;\\lsdpriority52 \\lsdlocked0 List Table 7 Colorful Accent 5;\n\\lsdpriority46 \\lsdlocked0 List Table 1 Light Accent 6;\\lsdpriority47 \\lsdlocked0 List Table 2 Accent 6;\\lsdpriority48 \\lsdlocked0 List Table 3 Accent 6;\\lsdpriority49 \\lsdlocked0 List Table 4 Accent 6;\n\\lsdpriority50 \\lsdlocked0 List Table 5 Dark Accent 6;\\lsdpriority51 \\lsdlocked0 List Table 6 Colorful Accent 6;\\lsdpriority52 \\lsdlocked0 List Table 7 Colorful Accent 6;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Mention;\n\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Smart Hyperlink;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Hashtag;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Unresolved Mention;\\lsdsemihidden1 \\lsdunhideused1 \\lsdlocked0 Smart Link;}}{\\*\\datastore 01050000\n02000000180000004d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000\nd0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nfffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\nffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e50000000000000000000000004059\n98433545d701feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000\n00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000\n000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000\n0000000000000000000000000000000000000000000000000105000000000000}}"
  },
  {
    "path": "README.md",
    "content": "# SimplySerial\n\n  ###### A serial terminal that runs as a Windows console application.\n  \n  Written by [Edward Wright](mailto:fasteddy@thewrightspace.net) (fasteddy516).\n\n  Available at https://github.com/fasteddy516/SimplySerial\n\n\n# Description\n\n  SimplySerial is a basic serial terminal that runs as a Windows console application.  It provides a quick way to connect to - and communicate with - serial devices through Command Prompt or PowerShell.  SimplySerial can be used directly from Command Prompt/PowerShell and should work with most devices that appear in Device Manager as \"COMx\".  It was, however, written specifically for use within a \"terminal\" window in [Visual Studio Code](https://code.visualstudio.com/) to provide serial communications with devices running [CircuitPython](https://circuitpython.org/).  Most of the testing and development of this application was done with this use case in mind.  \n\n\n# Requirements\n\n  * Windows 10 or 11 _(Version [0.6.0](https://github.com/fasteddy516/SimplySerial/releases/tag/v0.6.0) and older will also run on Windows 7, 8 and 8.1)_\n\n  * .NET Framework 4.8 or newer\n\n  _The required version of .NET framework is already included in supported Windows versions.  If it is missing on your machine, you can download and install it from Microsoft at https://dotnet.microsoft.com/download/dotnet-framework._\n\n\n# Installation\n\n  Download the [latest release](https://github.com/fasteddy516/SimplySerial/releases/latest) of this application in one of three formats:\n\n  `SimplySerial_x.x.x_user_setup.msi` is a windows installer package that puts everything where it needs to go and adds the location of the SimplySerial executable to your `PATH` environment variable, which makes it easily accessible from Command Prompt, PowerShell and Visual Studio Code.  Installation is per-user, and does not require Administrative rights to install.  **This is the preferred installation method,** _and works well with the \"user setup\" version of VSCode_.\n\n  `SimplySerial_x.x.x_system_setup.msi` is similar to `user_setup.msi` except that the installation is system-wide (for all users), and **requires administrative rights to install.**  _This version will work with both the \"user setup\" and \"system setup\" versions of VSCode_.\n\n  **_If you are unsure which version of VSCode you have installed, load it up and go to `Help > About` - beside the version number it will say either `user` or `system` setup._**\n\n  **_The installer versions are unsigned, and may trigger a \"Windows Defender SmartScreen\" warning. To install you have to press \"More Info\" followed by \"Run Anyway\"._**\n\n  `SimplySerial_x.x.x_standalone.zip` is a standard compressed archive containing SimplySerial's program files and some documentation.  You can unzip it wherever you like, and add that location to your `PATH` or not.  **Advanced users may prefer this format/process.**\n\n  The standalone version can also be installed with [scoop](https://scoop.sh/).  Assuming you have scoop installed, you can install SimplySerial using the following commands:\n\n  ```powershell\n  > scoop bucket add extras\n  > scoop install simplyserial\n  ```\n\n  After SimplySerial is installed through scoop, you can update it when new versions become available using the following commands:\n\n  ```powershell\n  > scoop update\n  > scoop update simplyserial\n  ```\n\n\n# Using SimplySerial\n\n  For CircuitPython users, type `ss` in a Command Prompt, PowerShell or VSCode Terminal Window and press `enter`.  That's it!\n\n  By default, SimplySerial will attempt to identify and connect to a CircuitPython-capable board at 115200 baud, no parity, 8 data bits and 1 stop bit.  If no known boards are detected, it will default to the first available serial (COM) port at 9600 baud.  If there are no COM ports available, it will wait until one shows up, then connect to it. \n\n  Once you're connected, you should see messages from the device on COMx appear on screen, and anything you type into Command Prompt/PowerShell will be sent to the device.  CircuitPython users can access the REPL using `CTRL-C` and exit the REPL using `CTRL-D`.\n\n  You can exit SimplySerial any time by pressing `CTRL-X`.  \n\n  If you have multiple COM ports, multiple CircuitPython devices connected, or need to use different communications settings, you will need to use the appropriate command-line arguments listed below:\n\n  `-help` displays a list of valid command-line arguments\n\n  `-version` displays version and installation information\n\n  `-list` displays a list of available COM ports.\n\n  `-list:all` displays a list of all available COM ports including those that have been excluded using device filters.\n\n  `-list:settings` displays a list of all command-line arguments that have been loaded from configuration files.\n\n  `-list:boards` displays a list of all recognized serial devices.\n\n  `-list:filters` displays a list of all device filters.\n\n  `-com` sets the desired COM port (ex. `-c:1` for COM1, `-com:22` for COM22)\n\n  `-baud` sets the baud rate (ex. `-b:9600`, `-baud:115200`)\n\n  `-parity` sets the parity option (ex. `-p:none`, `-parity:even`) \n  \n  `-databits` sets the number of data bits to use (ex. `-d:8`, `-databits:7`)\n\n  `-stopbits` sets the number of stop bits to use (ex. `-s:1`, `-stopbits:1.5`)\n\n  `-autoconnect` sets the desired auto-(re)connect behaviour (ex. `-a:NONE`, `-autoconnect:ANY`)\n  \n  `-log` logs all output to the specified file  (ex. `-l:ss.log`, `-l:\"C:\\Users\\My Name\\my log.txt\"`)\n            \n  `-logmode` instructs SimplySerial to either `APPEND` to an existing log file, or `OVERWRITE` an existing log file.  In either case, if the specified log file does not exist, it will be created.  If neither option is specified, `OVERWRITE` is assumed.  (ex. `-logmode:APPEND`)\n\n  `-quiet` prevents any application messages (connection banner, error messages, etc.) from printing out to the console\n\n  `-forcenewline` replaces carriage returns with linefeeds in received data. (ex. `-forcenewline:on`)\n\n  `-encoding` sets the encoding to use when outputting to the terminal and log files.  Defaults to `UTF8`, can also be set to `ASCII` (the default in SimplySerial versions prior to 0.8.0) or `RAW`. In `RAW` mode, all non-printable characters are displayed as `[xx]` where `xx` is the hexadecimal byte value of the character.\n\n  `-clearscreen` enable/disable clearing of the terminal screen on connection (ex. `-clearscreen:off`)\n\n  `-status` enable/disable status/title updates generated by virtual terminal sequences (such as the CircuitPython status bar introduced in CP version 8.0.0) (ex. `-status:off`)\n\n  `-title` sets the console window title.  Surround with quotation marks if your title has spaces.  (ex. `-title:\"My SimplySerial Window\"`)\n\n  `-bulksend` enables or disables bulk send mode (sending all characters typed/pasted at once) (ex. `-bulksend:on`)\n\n  `-config` loads a set of command-line arguments from the specified file.  (One command per line.) (ex. `-config:commands.cfg`)\n\n  `-echo` enables or disables printing typed characters locally (ex. `-echo:on`)\n\n  `-exitkey` specifies the key to use along with CTRL for exiting the program (default is 'X'). (ex. `-exitkey:Z` means you now quit SimplySerial by pressing `CTRL-Z`)\n\n  -`txonenter` determines what character(s) will be sent when the enter key is pressed.  Valid options are `CR`, `LF`, `CRLF`, `CUSTOM=\"Custom String\"` and `BYTES=\"custom sequence of bytes\"`.  Byte sequences must be expressed as 2-digit hexadecimal values with or without leading `0x` and separated by spaces or not.  (ex. `-txonenter:BYTES=\"0x31 0x32 0x33 0x0D\"` or `-txonenter:BYTES=\"3132330D\"`, etc.)\n\n  `-updateboards` searches for - and optionally installs - updates to the `boards.json` data file used for serial device recognition.\n\n  If you wanted to connect to a device on COM17 at 115200 baud, you would use the command `ss -c:17 -b:115200`, or if you really enjoy typing `ss --com:17 --baud:115200`.\n\n  _Note that SimplySerial is very forgiving when it comes to command-line arguments.  You can start each argument with a single dash `-`, double-dash `--` or no dashes at all.  You can shorten commands and parameters - `ss --list:settings` and `ss l:s` are both valid and do exactly the same thing.  In cases where commands start with the same letter(s), specific commands have been given priority, i.e. `ss -l` will get you `ss -list`, not `ss -log`._\n\n\n# Auto-(re)connect functionality\n\n  SimplySerial's `autoconnect` option can be used to determine if and how to connect/reconnect to a device.  These options function as follows:\n  \n  `-autoconnect:ONE` is the default mode of operation.  If a COM port was specified using the `-com` option, SimplySerial will attempt to connect to the specified port, otherwise it will connect to the first available COM port (giving preference to devices known to be CircuitPython-capable).  In either case, the program will wait until the/a COM port is available, and connect to it when it is.  If the device becomes unavailable at any point (because it was disconnected, etc.), SimplySerial will wait until that specific COM port becomes available again, regardless of any other COM ports that may or may not be available.\n  \n  `-autoconnect:ANY` is similar to `ONE`, except that when the connected port becomes unavailable, SimplySerial will attempt to connect to any other available port.  This option is useful if you only ever have one COM port available at a time, but can be problematic if you have multiple COM ports connected, or if you have a built-in COM port that is always available.\n  \n  `-autoconnect:NONE` prevents SimplySerial from waiting for devices and automatically re-connecting.\n\n\n# Customizing Settings and Behaviour\n\n  SimplySerial allows you to modify its default behaviour through global settings, project settings and - if specified on the command-line - user settings.\n\n  ### Global Settings\n\n  When SimplySerial starts, it looks for a file called `settings.cfg` in its application folder (the same location as the `ss.exe` program file.)  If the file exists, command-line arguments are read from the file and applied.  If the contents of `settings.cfg` were as follows:\n  ```\n  encoding:ASCII\n  bulksend:ON\n  clearscreen:OFF\n  ```\n  then every time SimplySerial starts up, the specified `encoding`, `bulksend` and `clearscreen` options will be applied automatically without having to enter them on the command-line.  All command-line options are valid, although commands that force SimplySerial to exit (i.e. `-list`, `-help`, `-version`, etc.) will be ignored.  As on the command-line, you can prefix each line with single, double or no dashes - whatever you prefer.\n\n  ### Project Settings\n\n  SimplySerial will also look for a `settings.cfg` file in a `.simplyserial` subfolder of your current working folder.  For example, if you are working with CircuitPython you can create a `.simplyserial` folder on the `CIRCUITPY` drive, place a `settings.cfg` file in that folder, and if you run `ss.exe` from the root of your `CIRCUITPY` drive it will automatically pull in the settings you've specified here.  \n  \n  ### User Settings\n\n  You can also tell SimplySerial to load settings from a specific file of your choosing by using the `-config` command-line option.  (ex. `ss.exe -config:my_custom_config.cfg`).\n\n  ### Altogether Now!\n\n  You can use all, none or any combination of the above configuration file options.  SimplySerial will load and apply Global settings first, then Project settings, then User settings, and finally settings entered on the command-line itself.  If the same command is present in multiple files, the last one to be applied takes precedence.  \n\n\n# Customizing Device Recognition\n\n  SimplySerial uses the `boards.json` file located in the same folder as `ss.exe` to apply useful manufacturer/model names to serial devices.  (ex. you see `Raspberry Pi Pico 2 W` instead of `VID:239A PID:8162`.)  You can add your own devices by placing a `custom_boards.json` file in the SimplySerial application folder using the same format as the existing `boards.json` file.  Note that devices in `custom_boards.json` with the same VID and PID as devices in the default `boards.json` file will take precedence.\n\n  You can also place a `custom_boards.json` file in the `.simplyserial` Project Settings subfolder (_see above_), and it will be applied when SimplySerial is started from your project's root folder.\n\n\n# Filtering out unwanted COM ports\n\n  Sometimes there are COM devices that you just want SimplySerial to ignore - bluetooth COM ports, weird COM ports built into asset management systems on laptops, old-school 9-pin serial ports built into some desktop PCs, etc.  You can tell SimplySerial to ignore these ports by creating a `filters.json` file in the application folder (where `ss.exe` is located), or you can create project-level device filters by placing `filters.json` in the `.simplyserial` project folder.  The format is as follows:\n\n  ```json\n  [\n    {\n        \"Type\": \"INCLUDE\",\n        \"Match\": \"STRICT\",\n        \"Port\": \"*\",\n        \"VID\": \"239A\",\n        \"PID\": \"*\",\n        \"Description\": \"*\",\n        \"Device\": \"*\"\n    },\n    {\n        \"Type\": \"EXCLUDE\",\n        \"Match\": \"LOOSE\",\n        \"Description\": \"bluetooth\",\n    },\n        {\n        \"Type\": \"EXCLUDE\",\n        \"Match\": \"CIRCUITPYTHON\"\n    }\n  ]\n  ```\n\n\n  `Type` is required, and can either be `\"INCLUDE\"` or `\"EXCLUDE\"`.  If you use `INCLUDE` filters, *only devices matching the filters you've defined will be used by SimplySerial.*  If you don't define any `INCLUDE` filters, then all ports are included by default unless they match an `EXCLUDE` filter.  If you combine both types, only those devices that *do* match the `INCLUDE` filters and *don't* match the `EXCLUDE` filters will be used.\n\n  `Match` is required, and can either be `\"STRICT\"` or `\"LOOSE\"`.  `STRICT` means any parameters you've defined must exactly match for the filter to be applied.  `LOOSE` means any parameters you've defined must be contained within the corresponding value of the COM device for the filter to match.  `LOOSE` comparisons are also case-insensive.\n\n  `Port`, `VID`, `PID`, `Description` and `Device` all correspond to the identically named columns in the table printed out with the `-list` command.  Set parameters that you don't want to use in your filter to `\"*\"`, or just leave the parameter out altogether.\n\n  The example above can be broken down as follows:\n  - The first filter ensures that SimplySerial will only use COM devices with a VID of `239A`.\n  - The second filter will exclude any device that contains the word `bluetooth` in its description.\n  - The third filter is a special case - setting `Match` to `CIRCUITPYTHON` in an `EXCLUDE` filter tells SimplySerial to stop prioritizing CircuitPython devices over other COM devices.\n\n\n# Using SimplySerial in Visual Studio Code (VSCode)\n\n  In a standard installation of VSCode, opening a \"terminal\" gets you a Command Prompt or PowerShell window embedded in the VSCode interface.  SimplySerial works exactly the same within this embedded window as it does in a normal Command Prompt or PowerShell, which means using SimplySerial within VSCode is as easy as opening a terminal window via the menu bar (`Terminal > New Terminal`) or shortcut key, typing `ss` and pressing enter.\n\n  If you want to make things even simpler, or if you need to use a bunch of command-line arguments and don't want to enter them every time (**and you don't use the terminal window in Visual Studio Code for anything else**) you can have VSCode launch SimplySerial directly whenever you open a terminal window by changing the `terminal.integrated.shell.windows` setting to point to `ss.exe` + any arguments you need to add.  This works well, but will prevent you from having multiple VSCode terminal windows open, as only one application can connect to any given serial port at a given time.\n\n\n# Using SimplySerial with Windows Terminal\n\n  [Windows Terminal](https://docs.microsoft.com/en-us/windows/terminal/) is a tabbed alternative to the command shell that Microsoft has developed as an open source project.  It is easy to setup SimplySerial as a new terminal profile; you just need to create a new profile in the settings GUI and specify the ss command line.  If you have problems, make sure that the SimplySerial executable is in your system path.\n\n  If you're directly editing the settings.json, the profile section will look like the code below, but with your specific command-line parameters.\n\n    {\n        \"commandline\": \"ss -com:4 -baud:115200\",\n        \"name\": \"COM4\"\n    }\n\n\n# Contributing\n\n  If you have questions, problems, feature requests, etc. please post them to the [Issues section on GitHub](https://github.com/fasteddy516/SimplySerial/issues).  If you would like to contribute, please let me know.  I have already put some \"enhancement requests\" in the GitHub Issues section with some ideas for improvements, most of which were either beyond my limited C#/Windows programming knowledge, or required more time than I had available! \n\n\n# Acknowledgements\n\n  The code used to obtain extra details about connected serial devices (VID, PID, etc.) is a modified version of [serial-reader](https://github.com/freakone/serial-reader) and its [associated examples](http://blog.gorski.pm/serial-port-details-in-c-sharp) by Kamil Górski (@freakone).  Some modifications were made based on [this stackoverflow thread](https://stackoverflow.com/questions/11458835/finding-information-about-all-serial-devices-connected-through-usb-in-c-sharp).\n\n  The code implemented in v0.6.0 to enable virtual terminal processing is based on Tamás Deme's (@tomzorz) gist about [Enabling VT100 terminal emulation in the current console window](https://gist.github.com/tomzorz/6142d69852f831fb5393654c90a1f22e).\n\n  The improved detection of CircuitPython boards in version 0.7.0 is based on Simon Mourier's answer on [this stackoverflow thread](https://stackoverflow.com/questions/69362886/get-devpkey-device-busreporteddevicedesc-from-win32-pnpentity-in-c-sharp) regarding the retrieval of a device's hardware bus description through WMI, with some pointers taken from Adafruit's [adafruit_board_toolkit](https://github.com/adafruit/Adafruit_Board_Toolkit/blob/main/adafruit_board_toolkit).\n\n\n"
  },
  {
    "path": "SimplySerial/App.config",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n    <startup> \n        \n    <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.8\"/></startup>\n</configuration>\n"
  },
  {
    "path": "SimplySerial/Arguments.cs",
    "content": "﻿using System;\n\nnamespace SimplySerial\n{\n    public class ArgumentData\n    {\n        public string Name { get; }\n        public string Value { get; }\n        public string Type { get; }\n\n        public ArgumentData(string[] argument, string type = \"\")\n        {\n            Name = argument[0];\n            Value = (argument.Length > 1) ? argument[1] : string.Empty;\n            Type = type;\n        }\n    }\n\n    public class CommandLineArgument : IComparable<CommandLineArgument>\n    {\n        public string Name { get { return Names[0]; } }\n\n        public string[] Names { get; }\n\n        public int Priority { get; }\n\n        public Action<string> Handler { get; }\n\n        public bool Immediate { get; }\n\n        public string RawValue { get; set; }\n\n        public string SetBy { get; set; }\n\n        public bool Active { get; set; }\n\n        public CommandLineArgument(string name, Action<string> handler, int priority = 99, bool immediate = false) : this(new[] { name }, handler, priority, immediate)\n        {\n        }\n\n        public CommandLineArgument(string[] names, Action<string> handler, int priority = 99, bool immediate = false)\n        {\n            Names = names;\n            Handler = handler;\n            Priority = Math.Min(priority, 99);\n            Immediate = immediate;\n            RawValue = string.Empty;\n            SetBy = string.Empty;\n            Active = false;\n        }\n\n        public int CompareTo(CommandLineArgument other)\n        {\n            if (other == null) return 1; // Treat null as having the lowest priority\n            return Priority.CompareTo(other.Priority);\n        }\n\n        public string Match(string arg)\n        {\n            arg = arg.TrimStart('/', '-').ToLower();\n            foreach (string name in Names)\n            {\n                if (name.StartsWith(arg))\n                    return Name;\n            }\n            return null;\n        }\n\n        public void Handle()\n        {\n            try\n            {\n                Handler(RawValue);\n            }\n            catch (Exception)\n            {\n                string setby = SetBy.Length > 0 ? $\" in {SetBy} Config\" : \"\";\n                string message;\n\n                if (RawValue.Length > 0)\n                    message = $\"Invalid '{Name}' value <{RawValue}> specified\";\n                else\n                    message = $\"No value specified for '{Name}'\";\n                throw new ArgumentException($\"{message}{setby}\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "SimplySerial/Boards.cs",
    "content": "﻿using Newtonsoft.Json;\nusing Newtonsoft.Json.Linq;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Net;\n\nnamespace SimplySerial\n{\n    /// <summary>\n    /// Represents a vendor with a vendor ID and make.\n    /// </summary>\n    public class Vendor\n    {\n        /// <summary>\n        /// Vendor ID.\n        /// </summary>\n        public string vid = \"----\";\n\n        /// <summary>\n        /// Vendor make.\n        /// </summary>\n        public string make = \"VID\";\n    }\n\n\n    /// <summary>\n    /// Represents a development board with USB PID/VID, make and model.\n    /// </summary>\n    public class Board\n    {\n        /// <summary>\n        /// Vendor ID.\n        /// </summary>\n        public string vid;\n\n        /// <summary>\n        /// Product ID.\n        /// </summary>\n        public string pid;\n\n        /// <summary>\n        /// Make of the board.\n        /// </summary>\n        public string make;\n\n        /// <summary>\n        /// Model of the board.\n        /// </summary>\n        public string model;\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"Board\"/> class.\n        /// </summary>\n        /// <param name=\"vid\">Vendor ID.</param>\n        /// <param name=\"pid\">Product ID.</param>\n        /// <param name=\"make\">Make of the board.</param>\n        /// <param name=\"model\">Model of the board.</param>\n        public Board(string vid = \"----\", string pid = \"----\", string make = \"\", string model = \"\")\n        {\n            this.vid = vid.ToUpper();\n            this.pid = pid.ToUpper();\n\n            if (make != \"\")\n                this.make = make;\n            else\n                this.make = $\"VID:{this.vid}\";\n\n            if (model != \"\")\n                this.model = model;\n            else\n                this.model = $\"PID:{this.pid}\";\n        }\n\n        public override string ToString()\n        {\n            return $\"[{vid}:{pid}] {make} {model}\";\n        }\n    }\n\n    /// <summary>\n    /// Represents the board list data structure.\n    /// </summary>\n    public class BoardData\n    {\n        [JsonProperty(\"version\")]\n        public string Version { get; set; } = \"\";\n\n        [JsonProperty(\"vendors\")]\n        public List<Vendor> Vendors { get; set; } = new List<Vendor>();\n\n        [JsonProperty(\"boards\")]\n        public List<Board> Boards { get; set; } = new List<Board>();\n\n    }\n\n\n    /// <summary>\n    /// Manages a collection of vendors and boards, and provides methods to load and match boards based on USB PID and VID.\n    /// </summary>\n    public static class BoardManager\n    {\n        /// <summary>\n        /// Gets the version of the board file.\n        /// </summary>\n        public static string Version => BoardManager._boardData.Version;\n\n        /// <summary>\n        /// Gets the list of vendors.\n        /// </summary>\n        public static List<Vendor> Vendors => BoardManager._boardData.Vendors;\n\n        /// <summary>\n        /// Gets the list of boards.\n        /// </summary>\n        public static List<Board> Boards => BoardManager._boardData.Boards;\n\n        private static BoardData _boardData = new BoardData();\n        private static string _boardFile = SimplySerial.AppFolder + \"boards.json\";\n\n        /// <summary>\n        /// Loads the board data from a JSON file.\n        /// </summary>\n        /// <param name=\"file\">Optional file path to load the board data from.</param>\n        /// <param name=\"merge\">Optional file path to merge with previously loaded data.</param>\n        /// <returns>True if the data was loaded successfully, otherwise false.</returns>\n        public static void Load(string file = \"\", string merge = \"\")\n        {\n            string newFile;\n            BoardData newData = new BoardData();\n\n            if (!String.IsNullOrEmpty(file))\n            {\n                _boardFile = file;\n                newFile = file;\n                merge = \"\";\n            }\n            else if (!String.IsNullOrEmpty(merge))\n            {\n                newFile = merge;\n            }\n            else\n            {\n                newFile = _boardFile;\n            }\n            try\n            {\n                using (StreamReader r = new StreamReader(newFile))\n                {\n                    newData = JsonConvert.DeserializeObject<BoardData>(r.ReadToEnd());\n                }\n            }\n            catch (Exception)\n            {\n                newData.Vendors = new List<Vendor>();\n                newData.Boards = new List<Board>();\n                newData.Version = \"(board file is missing or invalid)\";\n            }\n\n            if (!String.IsNullOrEmpty(merge))\n            {\n                foreach (Vendor vendor in newData.Vendors)\n                {\n                    if (vendor == null)\n                        continue;\n                    _boardData.Vendors.RemoveAll(v => v.vid == vendor.vid);\n                    _boardData.Vendors.Add(vendor);\n                }\n                foreach (Board board in newData.Boards)\n                {\n                    if (board == null)\n                        continue;\n                    _boardData.Boards.RemoveAll(b => b.vid == board.vid && b.pid == board.pid);\n                    _boardData.Boards.Add(board);\n                }\n            }\n            else\n            {\n                _boardData = newData;\n            }\n        }\n\n\n        /// <summary>\n        /// Matches to a known development board based on VID and PID.\n        /// </summary>\n        /// <param name=\"vid\">VID of the board.</param>\n        /// <param name=\"pid\">PID of the board.</param>\n        /// <returns>A <see cref=\"Board\"/> structure containing information about the matched board, or generic values otherwise.</returns>\n        public static Board Match(string vid, string pid)\n        {\n            Board mBoard = null;\n            if (Boards != null)\n                mBoard = Boards.Find(b => (b.vid == vid) && (b.pid == pid));\n\n            if (mBoard == null)\n            {\n                mBoard = new Board(vid: vid, pid: pid);\n\n                Vendor mVendor = null;\n                if (Vendors != null)\n                    mVendor = Vendors.Find(v => v.vid == vid);\n                if (mVendor != null)\n                    mBoard.make = mVendor.make;\n            }\n\n            return mBoard;\n        }\n\n        /// <summary>\n        /// Updates the board data file from the official GitHub repository.\n        /// </summary>\n        /// <returns></returns>\n        public static bool Update()\n        {\n            const string RepoOwner = \"fasteddy516\";\n            const string RepoName = \"SimplySerial-Boards\";\n\n            Console.WriteLine(\"SimplySerial boards.json updater\");\n            Console.WriteLine($\"  Installed: {BoardManager.Version}\");\n\n            try\n            {\n                using (WebClient client = new WebClient())\n                {\n                    client.Headers.Add(\"User-Agent\", \"SimplySerial-Boards-Updater\");\n\n                    // Get latest release info\n                    string apiUrl = $\"https://api.github.com/repos/{RepoOwner}/{RepoName}/releases/latest\";\n                    string responseBody = client.DownloadString(apiUrl);\n\n                    JObject releaseData = JObject.Parse(responseBody);\n                    string availableVersion = releaseData[\"tag_name\"]?.ToString();\n                    string releaseNotes = releaseData[\"body\"]?.ToString();\n                    string boardsJsonUrl = null;\n\n                    // Find the correct asset URL\n                    foreach (JToken asset in releaseData[\"assets\"] ?? new JArray())\n                    {\n                        string assetName = asset[\"name\"]?.ToString();\n                        if (string.Equals(assetName, \"boards.json\", StringComparison.OrdinalIgnoreCase))\n                        {\n                            boardsJsonUrl = asset[\"browser_download_url\"]?.ToString();\n                            break;\n                        }\n                    }\n\n                    if (boardsJsonUrl == null)\n                    {\n                        Console.WriteLine(\"No boards.json found in the latest release.\");\n                        return false;\n                    }\n\n                    Console.WriteLine($\"  Available: {availableVersion}\\n\");\n\n                    if (Version == availableVersion)\n                    {\n                        Console.WriteLine(\"* boards.json is already up to date\\n\");\n                        return false;\n                    }\n\n                    // Prompt user for action\n                    while (true)\n                    {\n                        Console.Write(\"* An update is available.  Install it (Y/N) or view the release notes (R)?\");\n                        ConsoleKey key = Console.ReadKey(true).Key; // Reads key without displaying it\n                        Console.WriteLine();\n\n                        if (key == ConsoleKey.Y)\n                        {\n                            break; // Proceed with update\n                        }\n                        else if (key == ConsoleKey.R)\n                        {\n                            Console.WriteLine(\"\\n--[ RELEASE NOTES ]-----------------------------------------\\n\");\n                            Console.WriteLine(releaseNotes.TrimEnd());\n                            Console.WriteLine(\"\\n----------------------------------[ END OF RELEASE NOTES ]--\\n\");\n                        }\n                        else\n                        {\n                            Console.WriteLine(\"\\nUpdate canceled.\\n\");\n                            return false;\n                        }\n                    }\n\n                    // Download and replace boards.json\n                    Console.Write(\"\\n+ Downloading new boards.json...\");\n                    try\n                    {\n                        client.DownloadFile(boardsJsonUrl, _boardFile);\n                        Console.WriteLine(\"DONE\");\n                        Console.WriteLine(\"\\nUpdate complete.\\n\");\n                        return true; // Indicate update was applied\n                    }\n                    catch (Exception ex)\n                    {\n                        if (ex.InnerException is UnauthorizedAccessException)\n                        {\n                            Console.WriteLine(\"ERROR: Permission denied. Try running the application as an administrator.\");\n                        }\n                        else\n                        {\n                            Console.WriteLine($\"ERROR: {ex.Message}\");\n                        }\n                        Console.WriteLine(\"\\nUpdate failed.\\n\");\n                        return false;\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                Console.WriteLine($\"\\n! Error checking for update: {ex.Message}\\n\");\n            }\n\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "SimplySerial/ComPorts.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Management;\nusing System.Text.RegularExpressions;\n\nnamespace SimplySerial\n{\n    /// <summary>\n    /// Custom structure containing the name, VID, PID and description of a serial (COM) port\n    /// Modified from the example written by Kamil Górski (freakone) available at\n    /// http://blog.gorski.pm/serial-port-details-in-c-sharp\n    /// https://github.com/freakone/serial-reader\n    /// </summary>\n    public class ComPort // custom struct with our desired values\n    {\n        public string name;\n        public int num = -1;\n        public string vid = \"----\";\n        public string pid = \"----\";\n        public string description;\n        public string busDescription;\n        public Board board;\n        public bool isCircuitPython = false;\n    }\n\n\n    public class ComPortList\n    {\n        public List<ComPort> Available = new List<ComPort>();\n        public List<ComPort> Excluded = new List<ComPort>();\n    }\n\n\n    public static class ComPortManager\n    {\n        public static FilterSet Filters = new FilterSet();\n\n        /// <summary>\n        /// Returns a list of available serial ports with their associated PID, VID and descriptions \n        /// Modified from the example written by Kamil Górski (freakone) available at\n        /// http://blog.gorski.pm/serial-port-details-in-c-sharp\n        /// https://github.com/freakone/serial-reader\n        /// Some modifications were based on this stackoverflow thread:\n        /// https://stackoverflow.com/questions/11458835/finding-information-about-all-serial-devices-connected-through-usb-in-c-sharp\n        /// Hardware Bus Description through WMI is based on Simon Mourier's answer on this stackoverflow thread:\n        /// https://stackoverflow.com/questions/69362886/get-devpkey-device-busreporteddevicedesc-from-win32-pnpentity-in-c-sharp\n        /// </summary>\n        /// <returns>List of available serial ports</returns>\n        public static ComPortList GetPorts()\n        {\n            const string vidPattern = @\"VID_([0-9A-F]{4})\";\n            const string pidPattern = @\"PID_([0-9A-F]{4})\";\n            const string namePattern = @\"(?<=\\()COM[0-9]{1,3}(?=\\)$)\";\n            const string query = \"SELECT * FROM Win32_PnPEntity WHERE ClassGuid=\\\"{4d36e978-e325-11ce-bfc1-08002be10318}\\\"\";\n\n            // as per INTERFACE_PREFIXES in adafruit_board_toolkit\n            // (see https://github.com/adafruit/Adafruit_Board_Toolkit/blob/main/adafruit_board_toolkit)\n            string[] cpb_descriptions = new string[] { \"CircuitPython CDC \", \"Sol CDC \", \"StringCarM0Ex CDC \" };\n\n            if (Filters.All == null)\n            {\n                Filters.All = Filter.AddFrom(SimplySerial.AppFolder + SimplySerial.FilterFile);\n                if (SimplySerial.AppFolder != SimplySerial.WorkingFolder)\n                {\n                    Filters.All = Filter.AddFrom(SimplySerial.WorkingFolder + SimplySerial.FilterFile, existing: Filters.All);\n                }\n            }\n\n            List<ComPort> detectedPorts = new List<ComPort>();\n\n            foreach (var p in new ManagementObjectSearcher(\"root\\\\CIMV2\", query).Get().OfType<ManagementObject>())\n            {\n                ComPort c = new ComPort();\n\n                // extract and clean up port name and number\n                c.name = p.GetPropertyValue(\"Name\").ToString();\n                Match mName = Regex.Match(c.name, namePattern);\n                if (mName.Success)\n                {\n                    c.name = mName.Value;\n                    c.num = int.Parse(c.name.Substring(3));\n                }\n\n                // if the port name or number cannot be determined, skip this port and move on\n                if (c.num < 1)\n                    continue;\n\n                // get the device's VID and PID\n                string pidvid = p.GetPropertyValue(\"PNPDeviceID\").ToString();\n\n                // extract and clean up device's VID\n                Match mVID = Regex.Match(pidvid, vidPattern, RegexOptions.IgnoreCase);\n                if (mVID.Success)\n                    c.vid = mVID.Groups[1].Value.Substring(0, Math.Min(4, c.vid.Length));\n\n                // extract and clean up device's PID\n                Match mPID = Regex.Match(pidvid, pidPattern, RegexOptions.IgnoreCase);\n                if (mPID.Success)\n                    c.pid = mPID.Groups[1].Value.Substring(0, Math.Min(4, c.pid.Length));\n\n                // extract the device's friendly description (caption)\n                c.description = p.GetPropertyValue(\"Caption\").ToString();\n\n                // attempt to match this device with a known board\n                c.board = BoardManager.Match(c.vid, c.pid);\n\n                // extract the device's hardware bus description\n                c.busDescription = \"\";\n                var inParams = new object[] { new string[] { \"DEVPKEY_Device_BusReportedDeviceDesc\" }, null };\n                p.InvokeMethod(\"GetDeviceProperties\", inParams);\n                var outParams = (ManagementBaseObject[])inParams[1];\n                if (outParams.Length > 0)\n                {\n                    var data = outParams[0].Properties.OfType<PropertyData>().FirstOrDefault(d => d.Name == \"Data\");\n                    if (data != null)\n                    {\n                        c.busDescription = data.Value.ToString();\n                    }\n                }\n\n                // we can determine if this is a CircuitPython board by its bus description\n                foreach (string prefix in cpb_descriptions)\n                {\n                    if (c.busDescription.StartsWith(prefix))\n                        c.isCircuitPython = true;\n                }\n\n                detectedPorts.Add(c);\n            }\n\n            // apply filters to determine if this port should be included or excluded in autodetection\n            ComPortList ports = new ComPortList();\n\n            // if there are *any* include filters than we can *only* include matches, and anything that doesn't match gets excluded\n            if (Filters.Include.Count > 0)\n            {\n                foreach (ComPort p in detectedPorts)\n                {\n                    bool matched = false;\n\n                    foreach (Filter f in Filters.Include)\n                    {\n                        if (Filter.MatchFilter(f, p))\n                        {\n                            ports.Available.Add(p);\n                            matched = true;\n                            break;\n                        }\n                    }\n                    if (!matched)\n                    {\n                        ports.Excluded.Add(p);\n                    }\n                }\n            }\n            else\n            {\n                // if there are *no* include filters, then we start out including everything\n                ports.Available = detectedPorts;\n            }\n\n            // once we have our initial include list, we apply our exclude filters to remove any ports that match and add them to the exclude list\n            foreach (ComPort p in ports.Available.ToList())\n            {\n                foreach (Filter f in Filters.Exclude.Concat(Filters.Block))\n                {\n                    if (Filter.MatchFilter(f, p))\n                    {\n                        ports.Available.Remove(p);\n                        ports.Excluded.Add(p);\n                    }\n                }\n            }\n\n            ports.Available = ports.Available.Distinct().OrderBy(p => p.num).ToList();\n            ports.Excluded = ports.Excluded.Distinct().OrderBy(p => p.num).ToList();\n\n            if (ports.Available.Count == 0 && Filters.Block.Count > 0)\n            {\n                Filters.All.RemoveAll(f => f.Type == FilterType.BLOCK);\n            }\n\n            return ports;\n        }\n    }\n}\n"
  },
  {
    "path": "SimplySerial/DataClasses.cs",
    "content": "﻿namespace SimplySerial\n{\n    public enum AutoConnect { NONE, ONE, ANY };\n}\n"
  },
  {
    "path": "SimplySerial/Filters.cs",
    "content": "﻿\nusing Newtonsoft.Json.Converters;\nusing Newtonsoft.Json;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection;\nusing System.Security.Cryptography;\n\nnamespace SimplySerial\n{\n    /// <summary>\n    /// The type of filter to apply.\n    /// </summary>\n    [JsonConverter(typeof(StringEnumConverter))]\n    public enum FilterType\n    {\n        INCLUDE,\n        EXCLUDE,\n        BLOCK,\n    }\n\n    /// <summary>\n    /// The type of match to apply.\n    /// </summary>\n    [JsonConverter(typeof(StringEnumConverter))]\n    public enum FilterMatch\n    {\n        STRICT,\n        LOOSE,\n        CIRCUITPYTHON,\n    }\n\n    public class FilterSet\n    {\n        public List<Filter> Include => All.Where(f => f.Type == FilterType.INCLUDE).ToList();\n        public List<Filter> Exclude => All.Where(f => f.Type == FilterType.EXCLUDE).ToList();\n        public List<Filter> Block => All.Where(f => f.Type == FilterType.BLOCK).ToList();\n        public List<Filter> All;\n    }\n\n    /// <summary>\n    /// A filter to apply to serial devices.\n    /// </summary>\n    public class Filter\n    {\n        public FilterType Type { get; set; } = FilterType.EXCLUDE;\n        public FilterMatch Match { get; set; } = FilterMatch.STRICT;\n        public string Port { get; set; } = \"*\";\n        public string VID { get; set; } = \"*\";\n        public string PID { get; set; } = \"*\";\n        public string Description { get; set; } = \"*\";\n        public string Device { get; set; } = \"*\";\n\n        public override string ToString()\n        {\n            return $\"[{Type}:{Match}] Port[{Port}] VID[{VID}] PID[{PID}] Description[{Description}] Device[{Device}]\";\n        }\n\n\n        /// <summary>\n        /// Load filters from a JSON file, adding to an existing list if supplied\n        /// </summary>\n        /// <param name=\"path\">Path of the file to add.</param>\n        /// <param name=\"existing\">Existing list of filters.</param>\n        /// <returns></returns>\n        public static List<Filter> AddFrom(string path, List<Filter> existing = null)\n        {\n            List<Filter> filters = new List<Filter>();\n\n            try\n            {\n                filters = JsonConvert.DeserializeObject<List<Filter>>(File.ReadAllText(path));\n                foreach (Filter f in filters)\n                {\n                    if (f.Port == \"\") f.Port = \"*\";\n                    if (f.VID == \"\" || f.VID == \"----\") f.VID = \"*\";\n                    if (f.PID == \"\" || f.PID == \"----\") f.PID = \"*\";\n                    if (f.Description == \"\") f.Description = \"*\";\n                    if (f.Device == \"\") f.Device = \"*\";\n                }\n                filters.RemoveAll(f => f.Port == \"*\" && f.VID == \"*\" && f.PID == \"*\" && f.Description == \"*\" && f.Device == \"*\" && f.Match != FilterMatch.CIRCUITPYTHON);\n            }\n            catch\n            {\n                filters = new List<Filter>();\n            }\n\n            if (existing != null)\n            {\n                filters.AddRange(existing);\n            }\n\n            return filters.OrderBy(f => f.Type).ToList();\n        }\n\n        public static bool MatchFilter(Filter filter, ComPort port)\n        {\n            string description = (port.isCircuitPython) ? (port.board.make + \" \" + port.board.model) : port.description;\n\n            if (filter.Match == FilterMatch.STRICT)\n            {\n                if (filter.Port != \"*\" && filter.Port.ToLower() != port.name.ToLower()) return false;\n                if (filter.VID != \"*\" && filter.VID.ToLower() != port.vid.ToLower()) return false;\n                if (filter.PID != \"*\" && filter.PID.ToLower() != port.pid.ToLower()) return false;\n                if (filter.Description != \"*\" && filter.Description != description) return false;\n                if (filter.Device != \"*\" && filter.Device != port.busDescription) return false;\n                return true;\n            }\n            else if (filter.Match == FilterMatch.LOOSE)\n            {\n                if (filter.Port != \"*\" && !port.name.ToLower().Contains(filter.Port.ToLower())) return false;\n                if (filter.VID != \"*\" && !port.vid.ToLower().Contains(filter.VID.ToLower())) return false;\n                if (filter.PID != \"*\" && !port.pid.ToLower().Contains(filter.PID.ToLower())) return false;\n                if (filter.Description != \"*\" && !description.ToLower().Contains(filter.Description.ToLower())) return false;\n                if (filter.Device != \"*\" && !port.busDescription.ToLower().Contains(filter.Device.ToLower())) return false;\n                return true;\n            }\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "SimplySerial/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following\n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"SimplySerial\")]\n[assembly: AssemblyDescription(\"A Windows console application for serial communications\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"fasteddy516\")]\n[assembly: AssemblyProduct(\"SimplySerial\")]\n[assembly: AssemblyCopyright(\"Copyright © 2023 Edward Wright (fasteddy516)\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible\n// to COM components.  If you need to access a type in this assembly from\n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"3c7db929-519c-44a3-a68f-2646cc595cae\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version\n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers\n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "SimplySerial/SimplySerial.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.IO.Ports;\nusing System.Linq;\nusing System.Runtime.InteropServices;\nusing System.Text;\nusing System.Text.RegularExpressions;\nusing System.Threading;\n\nnamespace SimplySerial\n{\n    class SimplySerial\n    {\n        const string version = \"0.9.0\";\n\n        const string ConfigFile = \"settings.cfg\";\n        const string CustomBoardFile = \"custom_boards.json\";\n        public const string FilterFile = \"filters.json\";\n\n        private const int STD_OUTPUT_HANDLE = -11;\n        private const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;\n\n        [DllImport(\"kernel32.dll\")]\n        private static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);\n\n        [DllImport(\"kernel32.dll\")]\n        private static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);\n\n        [DllImport(\"kernel32.dll\", SetLastError = true)]\n        private static extern IntPtr GetStdHandle(int nStdHandle);\n\n        [DllImport(\"kernel32.dll\")]\n        public static extern uint GetLastError();\n\n        public static string AppFolder = AppDomain.CurrentDomain.BaseDirectory.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar;\n        public static string WorkingFolder = Directory.GetCurrentDirectory().TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar + \".simplyserial\" + Path.DirectorySeparatorChar;\n\n        static string globalConfig = AppFolder + ConfigFile;\n        static string localConfig = WorkingFolder + ConfigFile;\n        static string userConfig = \"noUserConfig\";\n\n        private static Dictionary<string, CommandLineArgument> CommandLineArguments = new Dictionary<string, CommandLineArgument>();\n\n        static ComPortList Ports;\n        static SerialPort serialPort;\n\n        // default comspec values and application settings set here will be overridden by values passed through command-line arguments\n        static bool Quiet = false;\n        static AutoConnect autoConnect = AutoConnect.ONE;\n        static ComPort port = new ComPort();\n        static bool lockToPort = false;\n        static int baud = -1;\n        static Parity parity = Parity.None;\n        static int dataBits = 8;\n        static StopBits stopBits = StopBits.One;\n        static bool logging = false;\n        static FileMode logMode = FileMode.Create;\n        static string logFile = string.Empty;\n        static string logData = string.Empty;\n        static int bufferSize = 102400;\n        static DateTime lastFlush = DateTime.Now;\n        static bool forceNewline = false;\n        static Encoding encoding = Encoding.UTF8;\n        static bool convertToPrintable = false;\n        static bool clearScreen = true;\n        static bool noStatus = false;\n        static ConsoleKey exitKey = ConsoleKey.X;\n        static bool localEcho = false;\n        static bool bulkSend = false;\n\n        // dictionary of \"special\" keys with the corresponding string to send out when they are pressed\n        static Dictionary<ConsoleKey, String> specialKeys = new Dictionary<ConsoleKey, String>\n        {\n            { ConsoleKey.UpArrow, \"\\x1B[A\" },\n            { ConsoleKey.DownArrow, \"\\x1B[B\" },\n            { ConsoleKey.RightArrow, \"\\x1B[C\" },\n            { ConsoleKey.LeftArrow, \"\\x1B[D\" },\n            { ConsoleKey.Home, \"\\x1B[H\" },\n            { ConsoleKey.End, \"\\x1B[F\" },\n            { ConsoleKey.Insert, \"\\x1B[2~\" },\n            { ConsoleKey.Delete, \"\\x1B[3~\" },\n            { ConsoleKey.PageUp, \"\\x1B[5~\" },\n            { ConsoleKey.PageDown, \"\\x1B[6~\" },\n            { ConsoleKey.F1, \"\\x1B[11~\" },\n            { ConsoleKey.F2, \"\\x1B[12~\" },\n            { ConsoleKey.F3, \"\\x1B[13~\" },\n            { ConsoleKey.F4, \"\\x1B[14~\" },\n            { ConsoleKey.F5, \"\\x1B[15~\" },\n            { ConsoleKey.F6, \"\\x1B[17~\" },\n            { ConsoleKey.F7, \"\\x1B[18~\" },\n            { ConsoleKey.F8, \"\\x1B[19~\" },\n            { ConsoleKey.F9, \"\\x1B[20~\" },\n            { ConsoleKey.F10, \"\\x1B[21~\" },\n            { ConsoleKey.F11, \"\\x1B[23~\" },\n            { ConsoleKey.F12, \"\\x1B[24~\" },\n            { ConsoleKey.Enter, \"\\r\" }\n        };\n\n        static void Main(string[] args)\n        {\n            // initialize port name\n            port.name = String.Empty;\n\n            // load and parse data in global, local and user board data files\n            BoardManager.Load();\n            BoardManager.Load(merge: AppFolder + CustomBoardFile);\n            BoardManager.Load(merge: WorkingFolder + CustomBoardFile);\n\n            // process all command-line arguments\n            ProcessArguments(args);\n\n            if (clearScreen)\n            {\n                Console.Clear();\n            }\n\n            if (autoConnect == AutoConnect.ANY)\n            {\n                UpdateTitle(\"SimplySerial: Searching...\");\n                Output($\"<<< Attemping to connect to any available COM port.  Use CTRL-{exitKey} to cancel >>>\");\n            }\n            else if (autoConnect == AutoConnect.ONE)\n            {\n                if (clearScreen)\n                {\n                    Console.Clear();\n                }\n                if (port.name == String.Empty)\n                {\n                    UpdateTitle(\"SimplySerial: Searching...\");\n                    Output($\"<<< Attempting to connect to first available COM port.  Use CTRL-{exitKey} to cancel >>>\");\n                }\n                else\n                {\n                    UpdateTitle($\"{port.name}: Searching...\");\n                    Output(\"<<< Attempting to connect to \" + port.name + $\".  Use CTRL-{exitKey} to cancel >>>\");\n                }\n            }\n\n            // attempt to enable virtual terminal escape sequence processing\n            if (!convertToPrintable)\n            {\n                try\n                {\n                    var iStdOut = GetStdHandle(STD_OUTPUT_HANDLE);\n                    GetConsoleMode(iStdOut, out uint outConsoleMode);\n                    outConsoleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;\n                    SetConsoleMode(iStdOut, outConsoleMode);\n                }\n                catch\n                {\n                    // if the above fails, it doesn't really matter - it just means escape sequences won't process nicely\n                }\n            }\n\n            Console.OutputEncoding = encoding;\n\n            // verify log-related settings\n            if (logging)\n            {\n                try\n                {\n                    FileStream stream = new FileStream(logFile, logMode, FileAccess.Write);\n                    using (StreamWriter writer = new StreamWriter(stream, encoding))\n                    {\n                        writer.WriteLine($\"\\n----- LOGGING STARTED ({DateTime.Now}) ------------------------------------\");\n                    }\n                }\n                catch (Exception e)\n                {\n                    logging = false;\n                    ExitProgram($\"* Error accessing log file '{logFile}'\\n  > {e.GetType()}: {e.Message}\", exitCode: -1);\n                }\n            }\n\n            // set up keyboard input for program control / relay to serial port\n            ConsoleKeyInfo keyInfo = new ConsoleKeyInfo();\n            Console.TreatControlCAsInput = true; // we need to use CTRL-C to activate the REPL in CircuitPython, so it can't be used to exit the application\n\n            // this is where data read from the serial port will be temporarily stored\n            string received = string.Empty;\n\n            //main loop - keep this up until user presses CTRL-[exitKey] or an exception takes us down\n            do\n            {\n                // first things first, check for (and respect) a request to exit the program via CTRL-[exitKey]\n                if (Console.KeyAvailable)\n                {\n                    keyInfo = Console.ReadKey(intercept: true);\n                    if ((keyInfo.Key == exitKey) && (keyInfo.Modifiers == ConsoleModifiers.Control))\n                    {\n                        Output($\"\\n<<< SimplySerial session terminated via CTRL-{exitKey} >>>\");\n                        ExitProgram(silent: true);\n                    }\n                }\n\n                // get a list of available ports\n                Ports = ComPortManager.GetPorts();\n\n                // if no port was specified/selected, pick one automatically\n                if (port.name == String.Empty)\n                {\n                    // if there are com ports available, pick one\n                    if (Ports.Available.Count() > 0)\n                    {\n                        // first, try to default to something that we assume is running CircuitPython unless this behaviour has been disabled by a filter\n                        if (ComPortManager.Filters.Exclude.Find(f => f.Match == FilterMatch.CIRCUITPYTHON) == null)\n                        {\n                            port = Ports.Available.Find(p => p.isCircuitPython == true);\n                        }\n                        else\n                        {\n                            port = null;\n                        }\n\n                        // if that doesn't work out, just default to the first available COM port\n                        if (port == null)\n                            port = Ports.Available[0];\n                    }\n\n                    // if there are no com ports available, exit or try again depending on autoconnect setting \n                    else\n                    {\n                        if (autoConnect == AutoConnect.NONE)\n                            ExitProgram(\"No COM ports detected.\", exitCode: -1);\n                        else\n                        {\n                            Thread.Sleep(1000); // putting a delay here to avoid gobbling tons of resources thruogh constant high-speed re-connect attempts\n                            continue;\n                        }\n                    }\n                }\n\n                // if a specific port has been selected, try to match it with one that actually exists\n                else\n                {\n                    bool portMatched = false;\n\n                    foreach (ComPort p in Ports.Available.Concat(Ports.Excluded))\n                    {\n                        if (p.name == port.name)\n                        {\n                            portMatched = true;\n                            port = p;\n                            break;\n                        }\n                    }\n\n                    // if the specified port is not available, exit or try again depending on autoconnect setting\n                    if (!portMatched)\n                    {\n                        if (autoConnect == AutoConnect.NONE)\n                            ExitProgram((\"Invalid port specified <\" + port.name + \">\"), exitCode: -1);\n                        else\n                        {\n                            Thread.Sleep(1000); // putting a delay here to avoid gobbling tons of resources thruogh constant high-speed re-connect attempts                            \n                            continue;\n                        }\n                    }\n                }\n\n                // if we get this far, it should be safe to set up the specified/selected serial port\n                serialPort = new SerialPort(port.name)\n                {\n                    Handshake = Handshake.None, // we don't need to support any handshaking at this point \n                    ReadTimeout = 1, // minimal timeout - we don't want to wait forever for data that may not be coming!\n                    WriteTimeout = 250, // small delay - if we go too small on this it causes System.IO semaphore timeout exceptions\n                    DtrEnable = true, // without this we don't ever receive any data\n                    RtsEnable = true, // without this we don't ever receive any data\n                    Encoding = encoding\n                };\n\n                // attempt to set the baud rate, fail if the specified value is not supported by the hardware\n                try\n                {\n                    if (baud < 0)\n                    {\n                        if (port.isCircuitPython)\n                            baud = 115200;\n                        else\n                            baud = 9600;\n                    }\n\n                    serialPort.BaudRate = baud;\n                }\n                catch (ArgumentOutOfRangeException)\n                {\n                    ExitProgram((\"The specified baud rate (\" + baud + \") is not supported.\"), exitCode: -2);\n                }\n\n                // set other port parameters (which have already been validated)\n                serialPort.Parity = parity;\n                serialPort.DataBits = dataBits;\n                serialPort.StopBits = stopBits;\n\n                // attempt to open the serial port, deal with failures\n                try\n                {\n                    serialPort.Open();\n                }\n                catch (Exception e)\n                {\n                    // if auto-connect is disabled than any exception should result in program termination\n                    if (autoConnect == AutoConnect.NONE)\n                    {\n                        if (e is UnauthorizedAccessException)\n                            ExitProgram((e.GetType() + \" occurred while attempting to open \" + port.name + \".  Is this port already in use in another application?\"), exitCode: -1);\n                        else\n                            ExitProgram((e.GetType() + \" occurred while attempting to open \" + port.name + \".\"), exitCode: -1);\n                    }\n                    else\n                    {\n                        ComPortManager.Filters.All.Add(new Filter { Type = FilterType.BLOCK, Match = FilterMatch.STRICT, Port = port.name });\n                    }\n\n                    // if auto-connect is enabled, prepare to try again\n                    serialPort.Dispose();\n                    if (!lockToPort)\n                        port.name = String.Empty;\n                    continue;\n                }\n\n                if (autoConnect == AutoConnect.ONE)\n                    lockToPort = true;\n\n                UpdateTitle($\"{port.name}: {port.board.make} {port.board.model}\");\n\n                // if we get this far, clear the screen and send the connection message if not in 'quiet' mode\n                if (clearScreen)\n                {\n                    Console.Clear();\n                }\n                else\n                {\n                    Output(\"\");\n                }\n                Output(String.Format(\"<<< SimplySerial v{0} connected via {1} >>>\\n\" +\n                    \"Settings  : {2} baud, {3} parity, {4} data bits, {5} stop bit{6}, {7} encoding, auto-connect {8}, echo {9}{10}\\n\" +\n                    \"Device    : {11} {12}{13}\\n{14}\" +\n                    \"---\\n\\nUse CTRL-{15} to exit.\\n\",\n                    version,\n                    port.name,\n                    baud,\n                    (parity == Parity.None) ? \"no\" : (parity.ToString()).ToLower(),\n                    dataBits,\n                    (stopBits == StopBits.None) ? \"0\" : (stopBits == StopBits.One) ? \"1\" : (stopBits == StopBits.OnePointFive) ? \"1.5\" : \"2\", (stopBits == StopBits.One) ? \"\" : \"s\",\n                    (encoding.ToString() == \"System.Text.UTF8Encoding\") ? \"UTF-8\" : (convertToPrintable) ? \"RAW\" : \"ASCII\",\n                    (autoConnect == AutoConnect.ONE) ? \"on\" : (autoConnect == AutoConnect.ANY) ? \"any\" : \"off\",\n                    (localEcho) ? \"on\" : \"off\",\n                    (bulkSend) ? \", bulk send enabled\" : \"\",\n                    port.board.make,\n                    port.board.model,\n                    (port.isCircuitPython) ? \" (CircuitPython-capable)\" : \"\",\n                    (logging == true) ? ($\"Logfile   : {logFile} (Mode = \" + ((logMode == FileMode.Create) ? \"OVERWRITE\" : \"APPEND\") + \")\\n\") : \"\",\n                    exitKey\n                ), flush: true); ;\n\n                lastFlush = DateTime.Now;\n                DateTime start = DateTime.Now;\n                TimeSpan timeSinceRX = new TimeSpan();\n                TimeSpan timeSinceFlush = new TimeSpan();\n\n                // this is the core functionality - loop while the serial port is open\n                while (serialPort.IsOpen)\n                {\n                    try\n                    {\n                        // process keypresses for transmission through the serial port\n                        while (Console.KeyAvailable)\n                        {\n                            // determine what key is pressed (including modifiers)\n                            keyInfo = Console.ReadKey(intercept: true);\n\n                            // exit the program if CTRL-[exitKey] was pressed\n                            if ((keyInfo.Key == exitKey) && (keyInfo.Modifiers == ConsoleModifiers.Control))\n                            {\n                                Output($\"\\n<<< SimplySerial session terminated via CTRL-{exitKey} >>>\");\n                                ExitProgram(silent: true);\n                            }\n\n                            // check for keys that require special processing (cursor keys, etc.)\n                            else if (specialKeys.ContainsKey(keyInfo.Key))\n                            {\n                                serialPort.Write(specialKeys[keyInfo.Key]);\n                                if (localEcho)\n                                    Output(specialKeys[keyInfo.Key], force: true, newline: false);\n                            }\n\n                            // everything else just gets sent right on through\n                            else\n                            {\n                                string outstring = keyInfo.KeyChar.ToString();\n                                serialPort.Write(outstring);\n                                if (localEcho)\n                                    Output(outstring, force: true, newline: false);\n                            }\n                            if (!bulkSend)\n                                break;\n                        }\n\n                        // process data coming in from the serial port\n                        received = serialPort.ReadExisting();\n\n                        // if anything was received, process it\n                        if (received.Length > 0)\n                        {\n                            // if we're trying to filter out title/status updates in received data, try to ensure we've got the whole string\n                            if (noStatus && received.Contains(\"\\x1b\"))\n                            {\n                                Thread.Sleep(100);\n                                received += serialPort.ReadExisting();\n                            }\n\n                            if (forceNewline)\n                                received = received.Replace(\"\\r\", \"\\n\");\n\n                            // write what was received to console\n                            Output(received, force: true, newline: false);\n                            start = DateTime.Now;\n                        }\n                        else\n                            Thread.Sleep(1);\n\n                        if (logging)\n                        {\n                            timeSinceRX = DateTime.Now - start;\n                            timeSinceFlush = DateTime.Now - lastFlush;\n                            if ((timeSinceRX.TotalSeconds >= 2) || (timeSinceFlush.TotalSeconds >= 10))\n                            {\n                                if (logData.Length > 0)\n                                    Output(\"\", force: true, newline: false, flush: true);\n                                start = DateTime.Now;\n                                lastFlush = DateTime.Now;\n                            }\n                        }\n\n                        // if the serial port is unexpectedly closed, throw an exception\n                        if (!serialPort.IsOpen)\n                            throw new IOException();\n                    }\n                    catch (Exception e)\n                    {\n                        if (autoConnect == AutoConnect.NONE)\n                            ExitProgram((e.GetType() + \" occurred while attempting to read/write to/from \" + port.name + \".\"), exitCode: -1);\n                        else\n                        {\n                            UpdateTitle($\"{port.name}: (disconnected)\");\n                            Output(\"\\n<<< Communications Interrupted >>>\\n\");\n                        }\n                        try\n                        {\n                            serialPort.Dispose();\n                        }\n                        catch\n                        {\n                            //nothing to do here, other than prevent execution from stopping if dispose() throws an exception\n                        }\n                        Thread.Sleep(2000); // sort-of arbitrary delay - should be long enough to read the \"interrupted\" message\n                        if (autoConnect == AutoConnect.ANY)\n                        {\n                            UpdateTitle(\"SimplySerial: Searching...\");\n                            port.name = String.Empty;\n                            Output($\"<<< Attemping to connect to any available COM port.  Use CTRL-{exitKey} to cancel >>>\");\n                        }\n                        else if (autoConnect == AutoConnect.ONE)\n                        {\n                            UpdateTitle($\"{port.name}: Searching...\");\n                            Output(\"<<< Attempting to re-connect to \" + port.name + $\".  Use CTRL-{exitKey} to cancel >>>\");\n                        }\n                        break;\n                    }\n                }\n            } while (autoConnect > AutoConnect.NONE);\n\n            // if we get to this point, we should be exiting gracefully\n            ExitProgram(\"<<< SimplySerial session terminated >>>\", exitCode: 0);\n        }\n\n        static bool ArgProcessor_OnOff(string value)\n        {\n            value = value.ToLower();\n            if (value == \"\" || value.StartsWith(\"on\"))\n                return true;\n            else if (value.StartsWith(\"off\"))\n                return false;\n            throw new ArgumentException();\n        }\n\n        static void ArgHandler_Help(string value)\n        {\n            ShowHelp();\n            ExitProgram(silent: true);\n        }\n\n        static void ArgHandler_Version(string value)\n        {\n            ShowVersion();\n            ExitProgram(silent: true);\n        }\n\n        static void ArgHandler_List(string value)\n        {\n            // get a list of all available ports\n            ComPortList ports = ComPortManager.GetPorts();\n\n            if (value.Length > 0 && \"settings\".StartsWith(value.ToLower()))\n            {\n                Console.WriteLine(\"\");\n                ShowArguments($\"{globalConfig}\", \"Default Arguments\");\n                ShowArguments($\"{localConfig}\", \"Local Argument Overrides\");\n                ShowArguments($\"{userConfig}\", \"User Argument Overrides\");\n            }\n            else if (value.Length > 0 && \"filters\".StartsWith(value.ToLower()))\n            {\n                foreach (Filter f in ComPortManager.Filters.All)\n                {\n                    Console.WriteLine(f.ToString());\n                }\n                Console.WriteLine(\"\");\n            }\n            else if (value.Length > 0 && \"boards\".StartsWith(value.ToLower()))\n            {\n                foreach (Board b in BoardManager.Boards)\n                {\n                    Console.WriteLine(b.ToString());\n                }\n                Console.WriteLine(\"\");\n            }\n            else\n            {\n                // determine if excluded ports should be listed\n                bool showExcluded = value.Length > 0 && \"all\".StartsWith(value.ToLower());\n\n\n                if (ports.Available.Count > 0 || (showExcluded == true && ports.Excluded.Count > 0))\n                {\n                    Console.WriteLine(\"\\nPORT\\tVID\\tPID\\tDESCRIPTION [DEVICE]\");\n                    Console.WriteLine(\"----------------------------------------------------------------------\");\n\n                    if (ports.Available.Count > 0)\n                    {\n                        foreach (ComPort p in ports.Available)\n                        {\n                            Console.WriteLine(\"{0}\\t{1}\\t{2}\\t{3} {4}\",\n                                p.name,\n                                p.vid,\n                                p.pid,\n                                (p.isCircuitPython) ? (p.board.make + \" \" + p.board.model) : p.description,\n                                ((p.busDescription.Length > 0) && !p.description.StartsWith(p.busDescription)) ? (\"[\" + p.busDescription + \"]\") : \"\"\n                            );\n                        }\n                    }\n                    if (showExcluded == true && ports.Excluded.Count > 0)\n                    {\n                        Console.WriteLine(\"\\nThe following ports are excluded from automatic connection:\\n\");\n                        foreach (ComPort p in ports.Excluded)\n                        {\n                            Console.WriteLine(\"{0}\\t{1}\\t{2}\\t{3} {4}\",\n                                p.name,\n                                p.vid,\n                                p.pid,\n                                (p.isCircuitPython) ? (p.board.make + \" \" + p.board.model) : p.description,\n                                ((p.busDescription.Length > 0) && !p.description.StartsWith(p.busDescription)) ? (\"[\" + p.busDescription + \"]\") : \"\"\n                            );\n                        }\n                    }\n                    Console.WriteLine(\"\");\n                }\n                else\n                {\n                    Console.Write(\"\\nNo COM ports detected. \");\n                    if (ports.Excluded.Count > 0)\n                        Console.WriteLine(\" (Try 'ss.exe -list:all' to list excluded ports.)\\n\");\n                    else\n                        Console.WriteLine(\"\\n\");\n                }\n            }\n\n            ExitProgram(silent: true);\n        }\n\n        static void ArgHandler_Quiet(string value)\n        {\n            Quiet = ArgProcessor_OnOff(value);\n        }\n\n        static void ArgHandler_ForceNewLine(string value)\n        {\n            forceNewline = ArgProcessor_OnOff(value);\n        }\n\n        static void ArgHandler_ClearScreen(string value)\n        {\n            clearScreen = ArgProcessor_OnOff(value);\n        }\n\n        static void ArgHandler_Status(string value)\n        {\n            noStatus = ArgProcessor_OnOff(value);\n        }\n\n        static void ArgHandler_Com(string value)\n        {\n            string newPort = value.ToUpper();\n\n            if (String.IsNullOrEmpty(value))\n                throw new ArgumentException();\n            if (!value.StartsWith(\"COM\"))\n                newPort = \"COM\" + value;\n            port.name = newPort;\n            if (autoConnect == AutoConnect.ANY)\n                autoConnect = AutoConnect.ONE;\n            if (autoConnect == AutoConnect.ONE)\n                lockToPort = true;\n        }\n\n        static void ArgHandler_Baud(string value)\n        {\n            baud = Convert.ToInt32(value);\n        }\n\n        static void ArgHandler_Parity(string value)\n        {\n            value = value.ToLower();\n\n            if (value.StartsWith(\"e\"))\n                parity = Parity.Even;\n            else if (value.StartsWith(\"m\"))\n                parity = Parity.Mark;\n            else if (value.StartsWith(\"n\"))\n                parity = Parity.None;\n            else if (value.StartsWith(\"o\"))\n                parity = Parity.Odd;\n            else if (value.StartsWith(\"s\"))\n                parity = Parity.Space;\n            else\n                throw new ArgumentException();\n        }\n\n        static void ArgHandler_DataBits(string value)\n        {\n            int newDataBits = Convert.ToInt32(value);\n\n            if ((newDataBits > 3) && (newDataBits < 9))\n                dataBits = newDataBits;\n            else\n                throw new ArgumentException();\n        }\n\n        static void ArgHandler_StopBits(string value)\n        {\n            if (value == \"0\")\n                stopBits = StopBits.None;\n            else if (value == \"1\")\n                stopBits = StopBits.One;\n            else if (value == \"1.5\")\n                stopBits = StopBits.OnePointFive;\n            else if (value == \"2\")\n                stopBits = StopBits.Two;\n            else\n                ExitProgram((\"Invalid stop bits specified <\" + value + \">\"), exitCode: -1);\n        }\n\n        static void ArgHandler_Encoding(string value)\n        {\n            value = value.ToLower();\n\n            if (value.StartsWith(\"a\"))\n            {\n                encoding = Encoding.ASCII;\n                convertToPrintable = false;\n            }\n            else if (value.StartsWith(\"r\"))\n            {\n                encoding = Encoding.GetEncoding(1252);\n                convertToPrintable = true;\n            }\n            else if (value.StartsWith(\"u\"))\n            {\n                encoding = Encoding.UTF8;\n                convertToPrintable = false;\n            }\n            else\n                throw new ArgumentException();\n        }\n\n        static void ArgHandler_Echo(string value)\n        {\n            localEcho = ArgProcessor_OnOff(value);\n        }\n\n        static void ArgHandler_AutoConnect(string value)\n        {\n            value = value.ToLower();\n            if (value.StartsWith(\"n\"))\n                autoConnect = AutoConnect.NONE;\n            else if (value.StartsWith(\"o\"))\n                autoConnect = AutoConnect.ONE;\n            else if (value.StartsWith(\"a\"))\n                autoConnect = AutoConnect.ANY;\n            else\n                throw new ArgumentException();\n        }\n\n        static void ArgHandler_Log(string value)\n        {\n            if (String.IsNullOrEmpty(value))\n                throw new ArgumentException();\n            logging = true;\n            logFile = value;\n        }\n\n        static void ArgHandler_LogMode(string value)\n        {\n            value = value.ToLower();\n            if (value.StartsWith(\"o\"))\n                logMode = FileMode.Create;\n            else if (value.StartsWith(\"a\"))\n                logMode = FileMode.Append;\n            else\n                throw new ArgumentException();\n        }\n\n        static void ArgHandler_Title(string value)\n        {\n            if (String.IsNullOrEmpty(value))\n                throw new ArgumentException();\n            noStatus = true;\n            UpdateTitle(value, force: true);\n        }\n\n        static void ArgHandler_ExitKey(string value)\n        {\n            string keyArg = value.ToUpper();\n            if (Enum.TryParse($\"Oem{keyArg}\", out ConsoleKey parsedKey) || Enum.TryParse(keyArg, out parsedKey))\n            {\n                exitKey = parsedKey;\n            }\n            else\n            {\n                throw new ArgumentException();\n            }\n        }\n\n        static void ArgHandler_BulkSend(string value)\n        {\n            bulkSend = ArgProcessor_OnOff(value);\n        }\n\n        static void ArgHandler_UpdateBoards(string value)\n        {\n            BoardManager.Update();\n            ExitProgram(silent: true);\n        }\n\n        static void ArgHandler_TXOnEnter(string value)\n        {\n            value = value.ToLower();\n\n            if (value.Equals(\"cr\"))\n            {\n                specialKeys[ConsoleKey.Enter] = \"\\r\";\n            }\n            else if (value.Equals(\"lf\"))\n            {\n                specialKeys[ConsoleKey.Enter] = \"\\n\";\n            }\n            else if (value.Equals(\"crlf\"))\n            {\n                specialKeys[ConsoleKey.Enter] = \"\\r\\n\";\n            }\n            else if (value.StartsWith(\"custom=\") && (value.Length > 7))\n            {\n                specialKeys[ConsoleKey.Enter] = value.Substring(7);\n            }\n            else if (value.StartsWith(\"bytes=\") && (value.Length > 6))\n            {\n                string temp = value.Substring(6).Replace(\" \", \"\").Replace(\"\\\"\", \"\").Replace(\"0x\", \"\");\n\n                if (temp.Length % 2 != 0)\n                {\n                    throw new ArgumentException();\n                }\n                else\n                {\n                    string plaintext = string.Empty;\n\n                    for (int read_index = 0; read_index <= (temp.Length - 2); read_index += 2)\n                    {\n                        try\n                        {\n                            plaintext += Convert.ToChar(Convert.ToByte(temp.Substring(read_index, 2), 16));\n                        }\n                        catch\n                        {\n                            throw new ArgumentException();\n                        }\n\n                    }\n                    specialKeys[ConsoleKey.Enter] = plaintext;\n                }\n            }\n            else\n            {\n                throw new ArgumentException();\n            }\n        }\n\n        static List<ArgumentData> ParseArguments(string[] args, bool noImmediate = false, string source = \"\")\n        {\n            List<ArgumentData> receivedArguments = new List<ArgumentData>();\n            string sourceType = \"\";\n\n            if (source == globalConfig)\n                sourceType = \"Global\";\n            else if (source == localConfig)\n                sourceType = \"Local\";\n            else if (source == userConfig)\n                sourceType = \"User\";\n\n            // iterate through command-line arguments\n            foreach (string arg in args)\n            {\n                // split argument into components based on 'key:value' formatting and switch argument name to lower case\n                string[] argument = arg.Split(new[] { ':' }, 2);\n                string matchedName = null;\n\n                foreach (CommandLineArgument validArg in CommandLineArguments.Values)\n                {\n                    matchedName = validArg.Match(argument[0]);\n                    if (!String.IsNullOrEmpty(matchedName))\n                    {\n                        argument[0] = matchedName;\n                        if (!noImmediate || !validArg.Immediate)\n                        {\n                            receivedArguments.Add(new ArgumentData(argument, sourceType));\n                        }\n                        break;\n                    }\n                }\n\n                if (String.IsNullOrEmpty(matchedName))\n                {\n                    if (source.Length > 0)\n                        source = $\" in [{source}]\";\n                    ExitProgram($\"Invalid argument '{arg}'{source}\\nTry 'ss.exe help' to see a list of valid arguments\", exitCode: -1);\n                }\n            }\n            return receivedArguments;\n        }\n\n        static string[] LoadConfig(string file, bool failOnError = true)\n        {\n            string[] args = new string[] { };\n            try\n            {\n                args = File.ReadAllLines(file);\n            }\n            catch (Exception e)\n            {\n                if (failOnError)\n                {\n                    ExitProgram($\"Error reading configuration file '{file}'\\n> {e.GetType()}: {e.Message}\", exitCode: -1);\n                }\n            }\n            return args;\n        }\n\n        /// <summary>\n        /// Validates and processes any command-line arguments that were passed in.  Invalid arguments will halt program execution.\n        /// </summary>\n        /// <param name=\"args\">Command-line arguments</param>\n        static void ProcessArguments(string[] args)\n        {\n            // Add all command-line arguments to the dictionary.  Things to note:\n            //\n            // 1. Arguments are processed in ascending order based on priority, which is specified for commands\n            //    that *need* to run before others, or in cases where multiple commands start with the same letter(s)\n            //    and we want a short form to map to a specific command.  Default priority is 99.\n            //\n            //    In general, DON'T MESS WITH PRIORITY NUMBERS!  They are set up the way they are for a reason.\n            //\n            // 2. Arguments flagged as immediate are used to trigger actions that display to console and exit\n            //    the program (i.e. help, version, list, etc.).  They are flagged so that they can be ignored\n            //    if they are present in a configuration file.\n            //\n            // 3. Some arguments have multiple names that can be used to trigger them.  This is to allow for\n            //    aliases (i.e. help and ?) as well as backwards compatability (i.e. clearscreen and noclear).\n            //\n            CommandLineArguments.Add(\"help\", new CommandLineArgument(new[] { \"help\", \"?\" }, handler: ArgHandler_Help, priority: 0, immediate: true)); // always process help first\n            CommandLineArguments.Add(\"version\", new CommandLineArgument(\"version\", handler: ArgHandler_Version, priority: 1, immediate: true)); // always process version second\n            CommandLineArguments.Add(\"list\", new CommandLineArgument(\"list\", handler: ArgHandler_List, priority: 2, immediate: true)); // always process list third\n            CommandLineArguments.Add(\"updateboards\", new CommandLineArgument(\"updateboards\", handler: ArgHandler_UpdateBoards, priority: 3, immediate: true)); // always process updateboards fourth\n            CommandLineArguments.Add(\"quiet\", new CommandLineArgument(\"quiet\", handler: ArgHandler_Quiet, priority: 4)); // process quiet before anything else\n            CommandLineArguments.Add(\"stopbits\", new CommandLineArgument(\"stopbits\", handler: ArgHandler_StopBits, priority: 5)); //process stop bits before any other 's' commands\n            CommandLineArguments.Add(\"status\", new CommandLineArgument(new[] { \"status\", \"nostatus\" }, handler: ArgHandler_Status, priority: 6)); // process status before ttle\n            CommandLineArguments.Add(\"autoconnect\", new CommandLineArgument(\"autoconnect\", handler: ArgHandler_AutoConnect, priority: 7)); //process autoconnect before com\n            CommandLineArguments.Add(\"com\", new CommandLineArgument(\"com\", handler: ArgHandler_Com, priority: 8)); // process com before any other 'c' commands\n            CommandLineArguments.Add(\"log\", new CommandLineArgument(\"log\", handler: ArgHandler_Log, priority: 9)); // process log before any other 'l' commands\n            CommandLineArguments.Add(\"baud\", new CommandLineArgument(\"baud\", handler: ArgHandler_Baud, priority: 10)); // process baud before any other 'b' commands\n            CommandLineArguments.Add(\"encoding\", new CommandLineArgument(\"encoding\", handler: ArgHandler_Encoding, priority: 11)); // process encoding before any other 'e' commands\n            CommandLineArguments.Add(\"title\", new CommandLineArgument(\"title\", handler: ArgHandler_Title, priority: 12));\n            CommandLineArguments.Add(\"bulksend\", new CommandLineArgument(\"bulksend\", handler: ArgHandler_BulkSend));\n            CommandLineArguments.Add(\"clearscreen\", new CommandLineArgument(new[] { \"clearscreen\", \"noclear\" }, handler: ArgHandler_ClearScreen));\n            CommandLineArguments.Add(\"config\", new CommandLineArgument(new[] { \"config\", \"input\" }, handler: null));\n            CommandLineArguments.Add(\"databits\", new CommandLineArgument(\"databits\", handler: ArgHandler_DataBits));\n            CommandLineArguments.Add(\"echo\", new CommandLineArgument(\"echo\", handler: ArgHandler_Echo));\n            CommandLineArguments.Add(\"exitkey\", new CommandLineArgument(\"exitkey\", handler: ArgHandler_ExitKey));\n            CommandLineArguments.Add(\"forcenewline\", new CommandLineArgument(\"forcenewline\", handler: ArgHandler_ForceNewLine));\n            CommandLineArguments.Add(\"logmode\", new CommandLineArgument(\"logmode\", handler: ArgHandler_LogMode));\n            CommandLineArguments.Add(\"parity\", new CommandLineArgument(\"parity\", handler: ArgHandler_Parity));\n            CommandLineArguments.Add(\"txonenter\", new CommandLineArgument(\"txonenter\", handler: ArgHandler_TXOnEnter));\n\n            // Create a list of command-line arguments sorted by priority for processing\n            List<CommandLineArgument> argumentsByPriority = CommandLineArguments.Values.OrderBy(a => a.Priority).ToList();\n\n            // Parse command-line arguments and add them to the arguments list\n            List<ArgumentData> arguments = ParseArguments(args);\n\n            // Check for a user-specified configuration file and process it if specified\n            ArgumentData userConfigFile = arguments.Find(item => item.Value != \"\" && item.Name == \"config\");\n            if (userConfigFile != null)\n            {\n                userConfig = userConfigFile.Value;\n                arguments.InsertRange(0, ParseArguments(LoadConfig(userConfig, failOnError: true), noImmediate: true, source: userConfig));\n            }\n\n            // Check for local and global configuration files and process them if they exist\n            arguments.InsertRange(0, ParseArguments(LoadConfig($\"{localConfig}\", failOnError: false), noImmediate: true, source: localConfig));\n            arguments.InsertRange(0, ParseArguments(LoadConfig($\"{globalConfig}\", failOnError: false), noImmediate: true, source: globalConfig));\n\n            // Remove any 'config' arguments from the list of arguments to process (they've already been processed)\n            arguments.RemoveAll(item => item.Name == \"config\");\n\n\n            // Run through the list of received arguments.  Note that they were inserted into the arguments list\n            // such that Global commands are processed first, followed by Local commands, then User commands, and\n            // finally Command-Line arguments.  This ensures that the argument \"closest\" to the user is the one that\n            // takes precedence.\n            foreach (ArgumentData argument in arguments)\n            {\n                CommandLineArguments[argument.Name].RawValue = argument.Value;\n                CommandLineArguments[argument.Name].SetBy = argument.Type;\n                CommandLineArguments[argument.Name].Active = true;\n            }\n\n            // Process all arguments in order of priority\n            foreach (CommandLineArgument argument in argumentsByPriority)\n            {\n                if (argument.Active)\n                {\n                    try\n                    {\n                        argument.Handle();\n                    }\n                    catch (Exception e)\n                    {\n                        ExitProgram($\"{e.Message}\", exitCode: -1);\n                    }\n                }\n            }\n        }\n\n        /// <summary>\n        /// Updates the title of the console window\n        /// </summary>\n        /// <param name=\"title\">New console window title</param>\n        /// <param name=\"force\">When true, forces the update even when a manual title has been set</param>\n        static void UpdateTitle(string title, bool force = false)\n        {\n            if (force || !noStatus)\n                Console.Title = title;\n        }\n\n        /// <summary>\n        /// Writes messages using Console.WriteLine() as long as the 'Quiet' option hasn't been enabled\n        /// </summary>\n        /// <param name=\"message\">Message to output (assuming 'Quiet' is false)</param>\n        static void Output(string message, bool force = false, bool newline = true, bool flush = false)\n        {\n            if (!SimplySerial.Quiet || force)\n            {\n                if (newline)\n                    message += \"\\n\";\n\n                if (message.Length > 0)\n                {\n                    if (noStatus)\n                    {\n                        Regex r = new Regex(@\"\\x1b\\][02];.*\\x1b\\\\\");\n                        message = r.Replace(message, string.Empty);\n                    }\n\n                    if (convertToPrintable)\n                    {\n                        string newMessage = \"\";\n                        foreach (byte c in message)\n                        {\n                            if ((c > 31 && c < 128) || (c == 8) || (c == 9) || (c == 10) || (c == 13))\n                                newMessage += (char)c;\n                            else\n                                newMessage += $\"[{c:X2}]\";\n                        }\n                        message = newMessage;\n                    }\n                    Console.Write(message);\n                }\n\n                if (logging)\n                {\n                    logData += message;\n                    if ((logData.Length >= bufferSize) || flush)\n                    {\n                        try\n                        {\n                            FileStream stream = new FileStream(logFile, FileMode.Append, FileAccess.Write);\n                            using (StreamWriter writer = new StreamWriter(stream, encoding))\n                            {\n                                writer.Write(logData);\n                            }\n                        }\n                        catch\n                        {\n                            Console.WriteLine($\"({DateTime.Now}) Error accessing log file '{logFile}'\");\n                        }\n                        logData = string.Empty;\n                    }\n                }\n            }\n        }\n\n\n        /// <summary>\n        /// Displays help information about this application and its command-line arguments\n        /// </summary>\n        static void ShowHelp()\n        {\n            Console.WriteLine(\"Usage: ss.exe [-com:PORT] [-baud:RATE] [-parity:PARITY] [-databits:VAL]\");\n            Console.WriteLine(\"              [-stopbits:VAL] [-autoconnect:VAL] [-log:LOGFILE] [-logmode:MODE]\");\n            Console.WriteLine(\"              [-quiet]\\n\");\n            Console.WriteLine(\"A basic serial terminal for IoT device programming in general, and working with\");\n            Console.WriteLine(\"CircuitPython devices specifically.  With no command-line arguments specified,\");\n            Console.WriteLine(\"SimplySerial will attempt to identify and connect to a CircuitPython-capable board\");\n            Console.WriteLine(\"at 115200 baud, no parity, 8 data bits and 1 stop bit.  If no known boards are\");\n            Console.WriteLine(\"detected, it will default to the first available serial (COM) port at 9600 baud.\\n\");\n            Console.WriteLine(\"Optional arguments:\");\n            Console.WriteLine(\"  -help             Display this help message\");\n            Console.WriteLine(\"  -version          Display version and installation information\");\n            Console.WriteLine(\"  -list[:val]       Display a list of available serial (COM) ports\");\n            Console.WriteLine(\"                    Use `-list:all` to show ports excluded by filters.\");\n            Console.WriteLine(\"                    Use `-list:settings` to show command line arguments loaded from files.\");\n            Console.WriteLine(\"                    Use `-list:filters` to show applied device recognition filters.\");\n            Console.WriteLine(\"                    Use `-list:boards` to show all recognized boards.\");\n            Console.WriteLine(\"  -updateboards     Update the list of known USB serial devices.\");\n            Console.WriteLine(\"  -com:PORT         COM port number (i.e. 1 for COM1, 22 for COM22, etc.)\");\n            Console.WriteLine(\"  -baud:RATE        1200 | 2400 | 4800 | 7200 | 9600 | 14400 | 19200 | 38400 |\");\n            Console.WriteLine(\"                    57600 | 115200 | (Any valid baud rate for the specified port.)\");\n            Console.WriteLine(\"  -parity:PARITY    NONE | EVEN | ODD | MARK | SPACE\");\n            Console.WriteLine(\"  -databits:VAL     4 | 5 | 6 | 7 | 8\");\n            Console.WriteLine(\"  -stopbits:VAL     0 | 1 | 1.5 | 2\");\n            Console.WriteLine(\"  -autoconnect:VAL  NONE| ONE | ANY, enable/disable auto-(re)connection when\");\n            Console.WriteLine(\"                    a device is disconnected / reconnected.\");\n            Console.WriteLine(\"  -echo:VAL         ON | OFF enable or disable printing typed characters locally\");\n            Console.WriteLine(\"  -log:LOGFILE      Logs all output to the specified file.\");\n            Console.WriteLine(\"  -logmode:MODE     APPEND | OVERWRITE, default is OVERWRITE\");\n            Console.WriteLine(\"  -quiet:VAL        ON | OFF when enabled, don't print any application messages/errors to console\");\n            Console.WriteLine(\"  -forcenewline:VAL ON | OFF enable/disable forcing of linefeeds (newline) in place of carriage returns in received data.\");\n            Console.WriteLine(\"  -encoding:ENC     UTF8 | ASCII | RAW\");\n            Console.WriteLine(\"  -clearscreen:VAL  ON | OFF enable/disable clearing of the terminal screen on connection.\");\n            Console.WriteLine(\"  -status:VAL       ON | OFF enable/disable status/title updates from virtual terminal sequences.\");\n            Console.WriteLine(\"  -exitkey:KEY      Specify a key to use along with CTRL for exiting the program (default is 'X').\");\n            Console.WriteLine(\"  -title:\\\"TITLE\\\"  Set the console window title.  Surround with quotation marks if your title has spaces.\");\n            Console.WriteLine(\"  -bulksend:VAL     ON | OFF enable or disable bulk send mode (send all characters typed/pasted at once).\");\n            Console.WriteLine(\"  -txonenter:VAL    CR | LF | CRLF | CUSTOM=\\\"CustomString\\\" | BYTES=\\\"custom sequence of bytes\\\", each byte must be expressed by 2 chars.\");\n            Console.WriteLine(\"                    Bytes sequence must be a hexadecimal value with or without leading 0x and separated or not by spaces.\");\n            Console.WriteLine(\"                    Determines what character(s) will be sent when the enter key is pressed.\");\n            Console.WriteLine(\"  -config:FILE      Load command-line arguments from the specified configuration file. (One command per line.)\");\n            Console.WriteLine($\"\\nPress CTRL-{exitKey} to exit a running instance of SimplySerial.\\n\");\n        }\n\n        /// <summary>\n        /// Displays the contents of the specified configuration file (if it exists) to the console\n        /// </summary>\n        /// <param name=\"file\">Full path to the configuration file</param>\n        /// <param name=\"label\">The label to apply to this set of configuration data</param>\n        static void ShowArguments(string file, string label)\n        {\n            if (File.Exists(file))\n            {\n                Console.WriteLine($\"{label} [{file}]:\");\n                foreach (string line in File.ReadLines(file))\n                {\n                    string lineOut = line.Trim();\n                    if (lineOut.Length > 0)\n                        Console.WriteLine($\"  {lineOut}\");\n                }\n                Console.WriteLine(\"\");\n            }\n        }\n\n        /// <summary>\n        /// Displays version and installation information about this application\n        /// </summary>\n        static void ShowVersion()\n        {\n            string installType;\n\n            // determine installation type (scoop/user/system/standalone)\n            if (AppFolder.ToLower().Contains(\"scoop\"))\n            {\n                installType = \"Scoop\";\n            }\n            else if (AppFolder.ToLower().Contains(\"appdata\\\\roaming\"))\n            {\n                installType = \"User\";\n            }\n            else if (AppFolder.ToLower().Contains(\"program files\"))\n            {\n                installType = \"System\";\n            }\n            else\n            {\n                installType = \"Standalone/Manual\";\n            }\n\n            Console.WriteLine($\"SimplySerial version {version}\");\n            Console.WriteLine($\"  Installation Type : {installType}\");\n            Console.WriteLine($\"  Installation Path : {AppFolder}\");\n            Console.WriteLine($\"  Board Data File   : {BoardManager.Version}\\n\");\n        }\n\n\n        /// <summary>\n        /// Writes the specified exit message to the console, then waits for user to press a key before halting program execution.\n        /// </summary>\n        /// <param name=\"message\">Message to display - should indicate the reason why the program is terminating.</param>\n        /// <param name=\"exitCode\">Code to return to parent process.  Should be &lt;0 if an error occurred, &gt;=0 if program is terminating normally.</param>\n        /// <param name=\"silent\">Exits without displaying a message or asking for a key press when set to 'true'</param>\n        static void ExitProgram(string message = \"\", int exitCode = 0, bool silent = false)\n        {\n            // the serial port should be closed before exiting\n            if (serialPort != null && serialPort.IsOpen)\n                serialPort.Close();\n            if (!silent)\n                Output(\"\\n\" + message, flush: true);\n            else if (logging)\n                Output(\"\", force: true, newline: false, flush: true);\n#if DEBUG\n            Console.WriteLine(\"\\n>> Press any key to exit <<\");\n            Console.ReadKey();\n#endif\n            Environment.Exit(exitCode);\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "SimplySerial/SimplySerial.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{3C7DB929-519C-44A3-A68F-2646CC595CAE}</ProjectGuid>\n    <OutputType>Exe</OutputType>\n    <RootNamespace>SimplySerial</RootNamespace>\n    <AssemblyName>ss</AssemblyName>\n    <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>\n    <Deterministic>true</Deterministic>\n    <IsWebBootstrapper>false</IsWebBootstrapper>\n    <TargetFrameworkProfile />\n    <PublishUrl>publish\\</PublishUrl>\n    <Install>true</Install>\n    <InstallFrom>Disk</InstallFrom>\n    <UpdateEnabled>false</UpdateEnabled>\n    <UpdateMode>Foreground</UpdateMode>\n    <UpdateInterval>7</UpdateInterval>\n    <UpdateIntervalUnits>Days</UpdateIntervalUnits>\n    <UpdatePeriodically>false</UpdatePeriodically>\n    <UpdateRequired>false</UpdateRequired>\n    <MapFileExtensions>true</MapFileExtensions>\n    <ApplicationRevision>0</ApplicationRevision>\n    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>\n    <UseApplicationTrust>false</UseApplicationTrust>\n    <BootstrapperEnabled>true</BootstrapperEnabled>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n    <RunCodeAnalysis>false</RunCodeAnalysis>\n    <CodeAnalysisIgnoreGeneratedCode>false</CodeAnalysisIgnoreGeneratedCode>\n    <Prefer32Bit>false</Prefer32Bit>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n    <Prefer32Bit>false</Prefer32Bit>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Debug|x86'\">\n    <DebugSymbols>true</DebugSymbols>\n    <OutputPath>bin\\x86\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <DebugType>full</DebugType>\n    <PlatformTarget>x86</PlatformTarget>\n    <ErrorReport>prompt</ErrorReport>\n    <CodeAnalysisIgnoreGeneratedCode>false</CodeAnalysisIgnoreGeneratedCode>\n    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>\n    <Prefer32Bit>true</Prefer32Bit>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)' == 'Release|x86'\">\n    <OutputPath>bin\\x86\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <Optimize>true</Optimize>\n    <DebugType>pdbonly</DebugType>\n    <PlatformTarget>x86</PlatformTarget>\n    <ErrorReport>prompt</ErrorReport>\n    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>\n    <Prefer32Bit>true</Prefer32Bit>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL\">\n      <HintPath>packages\\Newtonsoft.Json.13.0.3\\lib\\net45\\Newtonsoft.Json.dll</HintPath>\n    </Reference>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Management\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Arguments.cs\" />\n    <Compile Include=\"Boards.cs\" />\n    <Compile Include=\"ComPorts.cs\" />\n    <Compile Include=\"DataClasses.cs\" />\n    <Compile Include=\"Filters.cs\" />\n    <Compile Include=\"SimplySerial.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"App.config\" />\n    <None Include=\"boards.json\">\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\n    </None>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <BootstrapperPackage Include=\".NETFramework,Version=v4.6.1\">\n      <Visible>False</Visible>\n      <ProductName>Microsoft .NET Framework 4.6.1 %28x86 and x64%29</ProductName>\n      <Install>true</Install>\n    </BootstrapperPackage>\n    <BootstrapperPackage Include=\"Microsoft.Net.Framework.3.5.SP1\">\n      <Visible>False</Visible>\n      <ProductName>.NET Framework 3.5 SP1</ProductName>\n      <Install>false</Install>\n    </BootstrapperPackage>\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <PropertyGroup>\n    <PostBuildEvent>powershell Compress-Archive -Path '$(TargetDir)\\ss.exe', '$(ProjectDir)\\..\\LICENSE', '$(ProjectDir)\\..\\README.md', '$(TargetDir)\\boards.json', '$(TargetDir)\\ss.exe.config', '$(TargetDir)\\Newtonsoft.Json.dll' -DestinationPath '$(TargetDir)\\SimplySerial_standalone.zip' -Force</PostBuildEvent>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "SimplySerial/SimplySerial.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.28922.388\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"SimplySerial\", \"SimplySerial.csproj\", \"{3C7DB929-519C-44A3-A68F-2646CC595CAE}\"\nEndProject\nProject(\"{840C416C-B8F3-42BC-B0DD-F6BB14C9F8CB}\") = \"Installer\", \"..\\Installer\\Installer.aiproj\", \"{DCC10C6B-B172-4172-9961-E6D643DF6BCF}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{3C7DB929-519C-44A3-A68F-2646CC595CAE} = {3C7DB929-519C-44A3-A68F-2646CC595CAE}\n\tEndProjectSection\nEndProject\nProject(\"{840C416C-B8F3-42BC-B0DD-F6BB14C9F8CB}\") = \"Installer-System\", \"..\\Installer-System\\Installer-System.aiproj\", \"{D9A5E8D5-C2FF-450D-96E1-D82DB339B186}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{3C7DB929-519C-44A3-A68F-2646CC595CAE} = {3C7DB929-519C-44A3-A68F-2646CC595CAE}\n\tEndProjectSection\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tAll|Any CPU = All|Any CPU\n\t\tAll|x86 = All|x86\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tDebug|x86 = Debug|x86\n\t\tDefaultBuild|Any CPU = DefaultBuild|Any CPU\n\t\tDefaultBuild|x86 = DefaultBuild|x86\n\t\tRelease|Any CPU = Release|Any CPU\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{3C7DB929-519C-44A3-A68F-2646CC595CAE}.All|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{3C7DB929-519C-44A3-A68F-2646CC595CAE}.All|Any CPU.Build.0 = Release|Any CPU\n\t\t{3C7DB929-519C-44A3-A68F-2646CC595CAE}.All|x86.ActiveCfg = Release|x86\n\t\t{3C7DB929-519C-44A3-A68F-2646CC595CAE}.All|x86.Build.0 = Release|x86\n\t\t{3C7DB929-519C-44A3-A68F-2646CC595CAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{3C7DB929-519C-44A3-A68F-2646CC595CAE}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{3C7DB929-519C-44A3-A68F-2646CC595CAE}.Debug|x86.ActiveCfg = Debug|x86\n\t\t{3C7DB929-519C-44A3-A68F-2646CC595CAE}.Debug|x86.Build.0 = Debug|x86\n\t\t{3C7DB929-519C-44A3-A68F-2646CC595CAE}.DefaultBuild|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{3C7DB929-519C-44A3-A68F-2646CC595CAE}.DefaultBuild|Any CPU.Build.0 = Debug|Any CPU\n\t\t{3C7DB929-519C-44A3-A68F-2646CC595CAE}.DefaultBuild|x86.ActiveCfg = Debug|x86\n\t\t{3C7DB929-519C-44A3-A68F-2646CC595CAE}.DefaultBuild|x86.Build.0 = Debug|x86\n\t\t{3C7DB929-519C-44A3-A68F-2646CC595CAE}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{3C7DB929-519C-44A3-A68F-2646CC595CAE}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{3C7DB929-519C-44A3-A68F-2646CC595CAE}.Release|x86.ActiveCfg = Release|x86\n\t\t{3C7DB929-519C-44A3-A68F-2646CC595CAE}.Release|x86.Build.0 = Release|x86\n\t\t{DCC10C6B-B172-4172-9961-E6D643DF6BCF}.All|Any CPU.ActiveCfg = DefaultBuild\n\t\t{DCC10C6B-B172-4172-9961-E6D643DF6BCF}.All|Any CPU.Build.0 = DefaultBuild\n\t\t{DCC10C6B-B172-4172-9961-E6D643DF6BCF}.All|x86.ActiveCfg = DefaultBuild\n\t\t{DCC10C6B-B172-4172-9961-E6D643DF6BCF}.All|x86.Build.0 = DefaultBuild\n\t\t{DCC10C6B-B172-4172-9961-E6D643DF6BCF}.Debug|Any CPU.ActiveCfg = DefaultBuild\n\t\t{DCC10C6B-B172-4172-9961-E6D643DF6BCF}.Debug|Any CPU.Build.0 = DefaultBuild\n\t\t{DCC10C6B-B172-4172-9961-E6D643DF6BCF}.Debug|x86.ActiveCfg = DefaultBuild\n\t\t{DCC10C6B-B172-4172-9961-E6D643DF6BCF}.Debug|x86.Build.0 = DefaultBuild\n\t\t{DCC10C6B-B172-4172-9961-E6D643DF6BCF}.DefaultBuild|Any CPU.ActiveCfg = DefaultBuild\n\t\t{DCC10C6B-B172-4172-9961-E6D643DF6BCF}.DefaultBuild|Any CPU.Build.0 = DefaultBuild\n\t\t{DCC10C6B-B172-4172-9961-E6D643DF6BCF}.DefaultBuild|x86.ActiveCfg = DefaultBuild\n\t\t{DCC10C6B-B172-4172-9961-E6D643DF6BCF}.DefaultBuild|x86.Build.0 = DefaultBuild\n\t\t{DCC10C6B-B172-4172-9961-E6D643DF6BCF}.Release|Any CPU.ActiveCfg = DefaultBuild\n\t\t{DCC10C6B-B172-4172-9961-E6D643DF6BCF}.Release|Any CPU.Build.0 = DefaultBuild\n\t\t{DCC10C6B-B172-4172-9961-E6D643DF6BCF}.Release|x86.ActiveCfg = DefaultBuild\n\t\t{DCC10C6B-B172-4172-9961-E6D643DF6BCF}.Release|x86.Build.0 = DefaultBuild\n\t\t{D9A5E8D5-C2FF-450D-96E1-D82DB339B186}.All|Any CPU.ActiveCfg = DefaultBuild\n\t\t{D9A5E8D5-C2FF-450D-96E1-D82DB339B186}.All|Any CPU.Build.0 = DefaultBuild\n\t\t{D9A5E8D5-C2FF-450D-96E1-D82DB339B186}.All|x86.ActiveCfg = DefaultBuild\n\t\t{D9A5E8D5-C2FF-450D-96E1-D82DB339B186}.All|x86.Build.0 = DefaultBuild\n\t\t{D9A5E8D5-C2FF-450D-96E1-D82DB339B186}.Debug|Any CPU.ActiveCfg = DefaultBuild\n\t\t{D9A5E8D5-C2FF-450D-96E1-D82DB339B186}.Debug|Any CPU.Build.0 = DefaultBuild\n\t\t{D9A5E8D5-C2FF-450D-96E1-D82DB339B186}.Debug|x86.ActiveCfg = DefaultBuild\n\t\t{D9A5E8D5-C2FF-450D-96E1-D82DB339B186}.Debug|x86.Build.0 = DefaultBuild\n\t\t{D9A5E8D5-C2FF-450D-96E1-D82DB339B186}.DefaultBuild|Any CPU.ActiveCfg = DefaultBuild\n\t\t{D9A5E8D5-C2FF-450D-96E1-D82DB339B186}.DefaultBuild|Any CPU.Build.0 = DefaultBuild\n\t\t{D9A5E8D5-C2FF-450D-96E1-D82DB339B186}.DefaultBuild|x86.ActiveCfg = DefaultBuild\n\t\t{D9A5E8D5-C2FF-450D-96E1-D82DB339B186}.DefaultBuild|x86.Build.0 = DefaultBuild\n\t\t{D9A5E8D5-C2FF-450D-96E1-D82DB339B186}.Release|Any CPU.ActiveCfg = DefaultBuild\n\t\t{D9A5E8D5-C2FF-450D-96E1-D82DB339B186}.Release|Any CPU.Build.0 = DefaultBuild\n\t\t{D9A5E8D5-C2FF-450D-96E1-D82DB339B186}.Release|x86.ActiveCfg = DefaultBuild\n\t\t{D9A5E8D5-C2FF-450D-96E1-D82DB339B186}.Release|x86.Build.0 = DefaultBuild\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {253902E3-B5BC-46E5-AA45-F17A6C84A16C}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "SimplySerial/boards.json",
    "content": "{\n    \"version\": \"2025-03-04T20-57-17.992214\",\n    \"vendors\": [\n        {\n            \"vid\": \"04D8\",\n            \"make\": \"Microchip Technology\"\n        },\n        {\n            \"vid\": \"054C\",\n            \"make\": \"Sony\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"make\": \"Generic\"\n        },\n        {\n            \"vid\": \"1915\",\n            \"make\": \"Nordic Semiconductor\"\n        },\n        {\n            \"vid\": \"1B4F\",\n            \"make\": \"Sparkfun\"\n        },\n        {\n            \"vid\": \"2341\",\n            \"make\": \"Arduino\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"make\": \"Adafruit\"\n        },\n        {\n            \"vid\": \"2786\",\n            \"make\": \"Switch Science, Inc.\"\n        },\n        {\n            \"vid\": \"2886\",\n            \"make\": \"Seeed\"\n        },\n        {\n            \"vid\": \"2B04\",\n            \"make\": \"Spark Labs, Inc.\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"make\": \"Raspberry Pi\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"make\": \"Espressif\"\n        },\n        {\n            \"vid\": \"30A4\",\n            \"make\": \"Blues Wireless\"\n        },\n        {\n            \"vid\": \"3171\",\n            \"make\": \"8086 Consultancy\"\n        },\n        {\n            \"vid\": \"31E2\",\n            \"make\": \"BDMICRO\"\n        },\n        {\n            \"vid\": \"32BD\",\n            \"make\": \"Alorium Technology, LLC\"\n        }\n    ],\n    \"boards\": [\n        {\n            \"vid\": \"0483\",\n            \"pid\": \"572A\",\n            \"make\": \"STMicroelectronics\",\n            \"model\": \"NUCLEO-F446RE - CPy\"\n        },\n        {\n            \"vid\": \"04D8\",\n            \"pid\": \"EA2A\",\n            \"make\": \"BHDynamics\",\n            \"model\": \"DynaLoRa_USB\"\n        },\n        {\n            \"vid\": \"04D8\",\n            \"pid\": \"EAD1\",\n            \"make\": \"BHDynamics\",\n            \"model\": \"DynOSSAT-EDU-EPS-v1.0\"\n        },\n        {\n            \"vid\": \"04D8\",\n            \"pid\": \"EAD2\",\n            \"make\": \"BHDynamics\",\n            \"model\": \"DynOSSAT-EDU-OBC-v1.0\"\n        },\n        {\n            \"vid\": \"04D8\",\n            \"pid\": \"EC44\",\n            \"make\": \"maholli\",\n            \"model\": \"PyCubed\"\n        },\n        {\n            \"vid\": \"04D8\",\n            \"pid\": \"EC63\",\n            \"make\": \"Kevin Neubauer\",\n            \"model\": \"CircuitBrains Basic\"\n        },\n        {\n            \"vid\": \"04D8\",\n            \"pid\": \"EC64\",\n            \"make\": \"Kevin Neubauer\",\n            \"model\": \"CircuitBrains Deluxe\"\n        },\n        {\n            \"vid\": \"04D8\",\n            \"pid\": \"EC72\",\n            \"make\": \"XinaBox\",\n            \"model\": \"XinaBox CC03\"\n        },\n        {\n            \"vid\": \"04D8\",\n            \"pid\": \"EC75\",\n            \"make\": \"XinaBox\",\n            \"model\": \"XinaBox CS11\"\n        },\n        {\n            \"vid\": \"04D8\",\n            \"pid\": \"ED5F\",\n            \"make\": \"Itaca Innovation\",\n            \"model\": \"uChip CircuitPython\"\n        },\n        {\n            \"vid\": \"04D8\",\n            \"pid\": \"ED94\",\n            \"make\": \"maholli\",\n            \"model\": \"kicksat-sprite\"\n        },\n        {\n            \"vid\": \"04D8\",\n            \"pid\": \"EDB3\",\n            \"make\": \"Capable Robot Components\",\n            \"model\": \"Programmable USB Hub\"\n        },\n        {\n            \"vid\": \"04D8\",\n            \"pid\": \"EDBE\",\n            \"make\": \"maholli\",\n            \"model\": \"SAM32\"\n        },\n        {\n            \"vid\": \"04D8\",\n            \"pid\": \"EE8C\",\n            \"make\": \"J&J Studios\",\n            \"model\": \"datum-Distance\"\n        },\n        {\n            \"vid\": \"04D8\",\n            \"pid\": \"EE8D\",\n            \"make\": \"J&J Studios\",\n            \"model\": \"datum-IMU\"\n        },\n        {\n            \"vid\": \"04D8\",\n            \"pid\": \"EE8E\",\n            \"make\": \"J&J Studios\",\n            \"model\": \"datum-Light\"\n        },\n        {\n            \"vid\": \"04D8\",\n            \"pid\": \"EE8F\",\n            \"make\": \"J&J Studios\",\n            \"model\": \"datum-Weather\"\n        },\n        {\n            \"vid\": \"04D8\",\n            \"pid\": \"EF67\",\n            \"make\": \"senseBox\",\n            \"model\": \"senseBox MCU\"\n        },\n        {\n            \"vid\": \"04E9\",\n            \"pid\": \"80FF\",\n            \"make\": \"PCTEL\",\n            \"model\": \"WSC-1450\"\n        },\n        {\n            \"vid\": \"054C\",\n            \"pid\": \"0BC2\",\n            \"make\": \"Sony\",\n            \"model\": \"Spresense\"\n        },\n        {\n            \"vid\": \"0B6A\",\n            \"pid\": \"003C\",\n            \"make\": \"Analog Devices\",\n            \"model\": \"MAX32690 APARD\"\n        },\n        {\n            \"vid\": \"0B6A\",\n            \"pid\": \"003D\",\n            \"make\": \"Analog Devices\",\n            \"model\": \"MAX32690 EvKit\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"0001\",\n            \"make\": \"Solder Party\",\n            \"model\": \"ESP32-P4 Stamp XL\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"2017\",\n            \"make\": \"Benjamin Shockley\",\n            \"model\": \"Mini SAM M4\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"2023\",\n            \"make\": \"Lilygo\",\n            \"model\": \"T-Display\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"2031\",\n            \"make\": \"Czech maker\",\n            \"model\": \"ES3ink\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"3141\",\n            \"make\": \"CrumpSpace\",\n            \"model\": \"CrumpS2\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"3252\",\n            \"make\": \"Targett\",\n            \"model\": \"Targett Module Clip w/Wroom\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"3253\",\n            \"make\": \"Targett\",\n            \"model\": \"Targett Module Clip w/Wrover\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"4203\",\n            \"make\": \"42. Keebs\",\n            \"model\": \"Frood\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"4D43\",\n            \"make\": \"Robotics Masters\",\n            \"model\": \"Robo HAT MM1 M4\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"4DDD\",\n            \"make\": \"Oak Dev Tech\",\n            \"model\": \"CP Sapling\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"4DDE\",\n            \"make\": \"Oak Dev Tech\",\n            \"model\": \"CP Sapling M0 w/ SPI Flash\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"4DDF\",\n            \"make\": \"Oak Dev Tech\",\n            \"model\": \"CP Sapling Rev B\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"4DF0\",\n            \"make\": \"Oak Dev Tech\",\n            \"model\": \"Pixelwing ESP32S2\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"4DF1\",\n            \"make\": \"Oak Dev Tech\",\n            \"model\": \"BREAD2040\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"4DF2\",\n            \"make\": \"Oak Dev Tech\",\n            \"model\": \"CAST AWAY RP2040\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"4DF6\",\n            \"make\": \"Oak Dev Tech\",\n            \"model\": \"RPGA Feather\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"5687\",\n            \"make\": \"Brad\\u00e1n Lane STUDIO\",\n            \"model\": \"Coin M0\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"5A52\",\n            \"make\": \"ZRichard\",\n            \"model\": \"RP2.65-F\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"5BF0\",\n            \"make\": \"Foosn\",\n            \"model\": \"Fomu\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"6036\",\n            \"make\": \"Weekin\",\n            \"model\": \"WK-50\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"7150\",\n            \"make\": \"Electronic Cats\",\n            \"model\": \"Hunter Cat NFC\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"7382\",\n            \"make\": \"Invector Labs AB\",\n            \"model\": \"iLabs Challenger 840\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"805A\",\n            \"make\": \"Electronic Cats\",\n            \"model\": \"BastBLE\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"8CAE\",\n            \"make\": \"takayoshiotake\",\n            \"model\": \"Octave RP2040\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"9000\",\n            \"make\": \"Hack Club\",\n            \"model\": \"Sprig\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"A182\",\n            \"make\": \"Solder Party\",\n            \"model\": \"RP2040 Stamp\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"A183\",\n            \"make\": \"Solder Party\",\n            \"model\": \"RP2350 Stamp\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"A184\",\n            \"make\": \"Solder Party\",\n            \"model\": \"RP2350 Stamp XL\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"ADF0\",\n            \"make\": \"ICBbuy\",\n            \"model\": \"SuperMini NRF52840\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"B182\",\n            \"make\": \"Solder Party\",\n            \"model\": \"BBQ20 Keyboard\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"BAB0\",\n            \"make\": \"Electronic Cats\",\n            \"model\": \"Bast WiFi\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"BAB1\",\n            \"make\": \"Electronic Cats\",\n            \"model\": \"Meow Meow\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"BAB2\",\n            \"make\": \"Electronic Cats\",\n            \"model\": \"CatWAN USBStick\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"BAB3\",\n            \"make\": \"Electronic Cats\",\n            \"model\": \"Bast Pro Mini M0\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"BAB6\",\n            \"make\": \"Electronic Cats\",\n            \"model\": \"Escornabot Makech\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"BAB8\",\n            \"make\": \"Electronic Cats\",\n            \"model\": \"NFC Copy Cat\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"C051\",\n            \"make\": \"Betrusted\",\n            \"model\": \"Simmel\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"CB65\",\n            \"make\": \"0xCB\",\n            \"model\": \"Gemini\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"CB74\",\n            \"make\": \"0xCB\",\n            \"model\": \"Helios\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"D10D\",\n            \"make\": \"Diodes Delight\",\n            \"model\": \"Piunora\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"D1B5\",\n            \"make\": \"Radomir Dopieralski\",\n            \"model\": \"PewPew LCD\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"D1B6\",\n            \"make\": \"Radomir Dopieralski\",\n            \"model\": \"uGame22\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"E3E3\",\n            \"make\": \"StackRduino\",\n            \"model\": \"StackRduino M0 PRO\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"EF00\",\n            \"make\": \"2231puppy\",\n            \"model\": \"E-Fidget\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"F123\",\n            \"make\": \"Electrolama\",\n            \"model\": \"minik\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"F500\",\n            \"make\": \"Silicognition\",\n            \"model\": \"M4-Shim\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"F502\",\n            \"make\": \"Silicognition\",\n            \"model\": \"RP2040-Shim\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"FD42\",\n            \"make\": \"HXR.DK\",\n            \"model\": \"SAO Digital Multimeter\"\n        },\n        {\n            \"vid\": \"1209\",\n            \"pid\": \"FF40\",\n            \"make\": \"RF.Guru\",\n            \"model\": \"RF.Guru RP2040\"\n        },\n        {\n            \"vid\": \"1354\",\n            \"pid\": \"4004\",\n            \"make\": \"FACTS Engineering\",\n            \"model\": \"P1AM-200 CircuitPython\"\n        },\n        {\n            \"vid\": \"16D0\",\n            \"pid\": \"07F2\",\n            \"make\": \"Autosport Labs\",\n            \"model\": \"Autosport Labs ESP32-CAN-X2\"\n        },\n        {\n            \"vid\": \"16D0\",\n            \"pid\": \"08C6\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Keybow 2040\"\n        },\n        {\n            \"vid\": \"16D0\",\n            \"pid\": \"08C7\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Tiny 2040 (8MB)\"\n        },\n        {\n            \"vid\": \"16D0\",\n            \"pid\": \"08C8\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"PicoSystem\"\n        },\n        {\n            \"vid\": \"16D0\",\n            \"pid\": \"10ED\",\n            \"make\": \"Mechwild\",\n            \"model\": \"PillBug\"\n        },\n        {\n            \"vid\": \"1915\",\n            \"pid\": \"B001\",\n            \"make\": \"Makerdiary\",\n            \"model\": \"Pitaya Go\"\n        },\n        {\n            \"vid\": \"192F\",\n            \"pid\": \"B1B2\",\n            \"make\": \"WarmBit\",\n            \"model\": \"WarmBit BluePixel nRF52840\"\n        },\n        {\n            \"vid\": \"1B4F\",\n            \"pid\": \"0015\",\n            \"make\": \"SparkFun\",\n            \"model\": \"RedBoard Turbo Board\"\n        },\n        {\n            \"vid\": \"1B4F\",\n            \"pid\": \"0016\",\n            \"make\": \"SparkFun\",\n            \"model\": \"SparkFun  SAMD51 Thing+\"\n        },\n        {\n            \"vid\": \"1B4F\",\n            \"pid\": \"0017\",\n            \"make\": \"SparkFun\",\n            \"model\": \"LUMIDrive Board\"\n        },\n        {\n            \"vid\": \"1B4F\",\n            \"pid\": \"0020\",\n            \"make\": \"SparkFun\",\n            \"model\": \"SparkFun MicroMod SAMD51 Processor\"\n        },\n        {\n            \"vid\": \"1B4F\",\n            \"pid\": \"0021\",\n            \"make\": \"SparkFun\",\n            \"model\": \"SparkFun MicroMod nRF52840 Processor\"\n        },\n        {\n            \"vid\": \"1B4F\",\n            \"pid\": \"0024\",\n            \"make\": \"SparkFun\",\n            \"model\": \"SparkFun MicroMod RP2040 Processor\"\n        },\n        {\n            \"vid\": \"1B4F\",\n            \"pid\": \"0025\",\n            \"make\": \"SparkFun\",\n            \"model\": \"Thing Plus RP2040\"\n        },\n        {\n            \"vid\": \"1B4F\",\n            \"pid\": \"0026\",\n            \"make\": \"SparkFun\",\n            \"model\": \"Pro Micro RP2040\"\n        },\n        {\n            \"vid\": \"1B4F\",\n            \"pid\": \"0027\",\n            \"make\": \"SparkFun\",\n            \"model\": \"SparkFun STM32 MicroMod Processor\"\n        },\n        {\n            \"vid\": \"1B4F\",\n            \"pid\": \"0028\",\n            \"make\": \"SparkFun\",\n            \"model\": \"Thing Plus - STM32\"\n        },\n        {\n            \"vid\": \"1B4F\",\n            \"pid\": \"002E\",\n            \"make\": \"SparkFun\",\n            \"model\": \"Teensy MicroMod\"\n        },\n        {\n            \"vid\": \"1B4F\",\n            \"pid\": \"0038\",\n            \"make\": \"SparkFun\",\n            \"model\": \"Thing Plus RP2350\"\n        },\n        {\n            \"vid\": \"1B4F\",\n            \"pid\": \"0039\",\n            \"make\": \"SparkFun\",\n            \"model\": \"Pro Micro RP2350\"\n        },\n        {\n            \"vid\": \"1B4F\",\n            \"pid\": \"5289\",\n            \"make\": \"SparkFun\",\n            \"model\": \"SFE_nRF52840_Mini\"\n        },\n        {\n            \"vid\": \"1B4F\",\n            \"pid\": \"8D22\",\n            \"make\": \"SparkFun\",\n            \"model\": \"SparkFun SAMD21 Mini Breakout\"\n        },\n        {\n            \"vid\": \"1B4F\",\n            \"pid\": \"8D23\",\n            \"make\": \"SparkFun\",\n            \"model\": \"SparkFun SAMD21 Dev Breakout\"\n        },\n        {\n            \"vid\": \"1B4F\",\n            \"pid\": \"8D24\",\n            \"make\": \"SparkFun\",\n            \"model\": \"SparkFun Qwiic Micro\"\n        },\n        {\n            \"vid\": \"1D50\",\n            \"pid\": \"60E8\",\n            \"make\": \"Radomir Dopieralski\",\n            \"model\": \"PewPew M4\"\n        },\n        {\n            \"vid\": \"1D50\",\n            \"pid\": \"6152\",\n            \"make\": \"JPConstantineau\",\n            \"model\": \"BlueMicro833\"\n        },\n        {\n            \"vid\": \"1D50\",\n            \"pid\": \"6153\",\n            \"make\": \"JPConstantineau\",\n            \"model\": \"PyKey44\"\n        },\n        {\n            \"vid\": \"1D50\",\n            \"pid\": \"6154\",\n            \"make\": \"JPConstantineau\",\n            \"model\": \"EncoderPad RP2040\"\n        },\n        {\n            \"vid\": \"1D50\",\n            \"pid\": \"6161\",\n            \"make\": \"JPConstantineau\",\n            \"model\": \"BlueMicro840\"\n        },\n        {\n            \"vid\": \"2019\",\n            \"pid\": \"7103\",\n            \"make\": \"Benjamin Shockley\",\n            \"model\": \"Fig Pi\"\n        },\n        {\n            \"vid\": \"2341\",\n            \"pid\": \"056B\",\n            \"make\": \"Arduino\",\n            \"model\": \"Arduino Nano ESP32\"\n        },\n        {\n            \"vid\": \"2341\",\n            \"pid\": \"8053\",\n            \"make\": \"Arduino\",\n            \"model\": \"Arduino MKR1300\"\n        },\n        {\n            \"vid\": \"2341\",\n            \"pid\": \"8057\",\n            \"make\": \"Arduino\",\n            \"model\": \"Arduino Nano 33 IoT\"\n        },\n        {\n            \"vid\": \"2341\",\n            \"pid\": \"805A\",\n            \"make\": \"Arduino\",\n            \"model\": \"Arduino_Nano_33_BLE\"\n        },\n        {\n            \"vid\": \"2341\",\n            \"pid\": \"824D\",\n            \"make\": \"Arduino\",\n            \"model\": \"Arduino Zero\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"006A\",\n            \"make\": \"WeAct\",\n            \"model\": \"stm32f411ce blackpill with flash\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"00CC\",\n            \"make\": \"Adafruit\",\n            \"model\": \"QT Py M0 Haxpress\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"00CF\",\n            \"make\": \"Arduino\",\n            \"model\": \"Arduino Nano RP2040 Connect\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"0145\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Metro ESP32-S3\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"102E\",\n            \"make\": \"WeAct Studio\",\n            \"model\": \"Pico\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"2030\",\n            \"make\": \"Czech maker\",\n            \"model\": \"Maker badge\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"6005\",\n            \"make\": \"Winterbloom\",\n            \"model\": \"Big Honking Button\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8009\",\n            \"make\": \"ATMegaZero\",\n            \"model\": \"ATMegaZero ESP32-S2\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8012\",\n            \"make\": \"Adafruit\",\n            \"model\": \"ItsyBitsy M0 Express\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8014\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Metro M0 Express\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8015\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather M0\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8019\",\n            \"make\": \"Adafruit\",\n            \"model\": \"CircuitPlayground Express\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"801D\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Gemma M0\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"801F\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Trinket M0\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8021\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Metro M4 Express\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8023\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather M0 Express\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8026\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather M4 Express\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"802A\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather nRF52840 Express\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"802C\",\n            \"make\": \"Adafruit\",\n            \"model\": \"ItsyBitsy M4 Express\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8030\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Trellis M4 Express\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8032\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Grand Central M4 Express\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8034\",\n            \"make\": \"Adafruit\",\n            \"model\": \"PyBadge\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8036\",\n            \"make\": \"Adafruit\",\n            \"model\": \"PyPortal\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8038\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Metro M4 Airlift Lite\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"803C\",\n            \"make\": \"Electronut Labs\",\n            \"model\": \"Papyr\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"803E\",\n            \"make\": \"Adafruit\",\n            \"model\": \"PyGamer\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8040\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Metro nRF52840 Express\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8046\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Circuit Playground Bluefruit\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8048\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Monster M4SK\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"804A\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Hallowing M4 Express\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"804C\",\n            \"make\": \"Adafruit\",\n            \"model\": \"PyRuler\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"804E\",\n            \"make\": \"keithp.com\",\n            \"model\": \"snekboard\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8050\",\n            \"make\": \"Arduino\",\n            \"model\": \"Arduino MKRZero\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8052\",\n            \"make\": \"Adafruit\",\n            \"model\": \"ItsyBitsy nRF52840 Express\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8054\",\n            \"make\": \"Adafruit\",\n            \"model\": \"PyPortal Titano\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8056\",\n            \"make\": \"STMicroelectronics\",\n            \"model\": \"STM32F412ZG Discovery Board - CPy\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8058\",\n            \"make\": \"arturo182\",\n            \"model\": \"Serpente\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"805A\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather STM32F405 Express\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"805C\",\n            \"make\": \"George Robotic\",\n            \"model\": \"Pyboard Version 1.1\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"805E\",\n            \"make\": \"STMicroelectronics\",\n            \"model\": \"STM32F411VE Discovery Board - CPy\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8060\",\n            \"make\": \"Cedar Grove Studios\",\n            \"model\": \"StringCar M0 Express\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8062\",\n            \"make\": \"Winterbloom\",\n            \"model\": \"Sol\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8066\",\n            \"make\": \"ndGarage\",\n            \"model\": \"Bit6\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8068\",\n            \"make\": \"MicroPython Chinese Community\",\n            \"model\": \"PYB LR Nano V2\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8069\",\n            \"make\": \"Jeremy Gillick\",\n            \"model\": \"Thunderpack STM32F411\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"806A\",\n            \"make\": \"WeAct\",\n            \"model\": \"stm32f411ce blackpill\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"806C\",\n            \"make\": \"@sarfata\",\n            \"model\": \"shIRtty\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8070\",\n            \"make\": \"Teknikio\",\n            \"model\": \"Bluebird\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8071\",\n            \"make\": \"Jeremy Gillick\",\n            \"model\": \"Thunderpack STM32F411\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8072\",\n            \"make\": \"Adafruit\",\n            \"model\": \"CLUE nRF52840 Express\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8074\",\n            \"make\": \"arturo182\",\n            \"model\": \"Feather MIMXRT1011\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8076\",\n            \"make\": \"arturo182\",\n            \"model\": \"Feather MIMXRT1062\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8078\",\n            \"make\": \"NXP\",\n            \"model\": \"IMXRT1010-EVK\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"807A\",\n            \"make\": \"ARAMCON Badge Team\",\n            \"model\": \"ARAMCON Badge 2019\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"807C\",\n            \"make\": \"ARAMCON Badge Team\",\n            \"model\": \"ARAMCON2 Badge\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"807E\",\n            \"make\": \"Oddly Specific Objects\",\n            \"model\": \"The Open Book Feather\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8080\",\n            \"make\": \"OSHWA\",\n            \"model\": \"OHS2020 Badge\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8082\",\n            \"make\": \"NXP\",\n            \"model\": \"iMX RT 1020 EVK\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8084\",\n            \"make\": \"NXP\",\n            \"model\": \"iMX RT 1060 EVK\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8086\",\n            \"make\": \"PJRC\",\n            \"model\": \"Teensy 4.0\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8088\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather Bluefruit Sense\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"808A\",\n            \"make\": \"STMicroelectronics\",\n            \"model\": \"STM32F407VG Discovery Board - CPy\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"808E\",\n            \"make\": \"Espruino\",\n            \"model\": \"Espruino Pico\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8090\",\n            \"make\": \"Espruino\",\n            \"model\": \"Espruino Wifi\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8092\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather M7 1011\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8094\",\n            \"make\": \"IkigaiSense Technologies\",\n            \"model\": \"IkigaiSense Vita nRF52840\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8096\",\n            \"make\": \"Szymon Klause\",\n            \"model\": \"UARTLogger II\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8098\",\n            \"make\": \"STMicroelectronics\",\n            \"model\": \"Nucleo H743ZI - CPy\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"809A\",\n            \"make\": \"STMicroelectronics\",\n            \"model\": \"Nucleo F767ZI - CPy\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"809C\",\n            \"make\": \"STMicroelectronics\",\n            \"model\": \"ST STM32F746G Discovery - CPy\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"809E\",\n            \"make\": \"STMicroelectronics\",\n            \"model\": \"Nucleo F746zg - CPy\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80A0\",\n            \"make\": \"AtelierDuMaker\",\n            \"model\": \"ADM_B_NRF52840_1\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80A4\",\n            \"make\": \"OpenMV\",\n            \"model\": \"OpenMV-H7 R1\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80A6\",\n            \"make\": \"Espressif\",\n            \"model\": \"Saola 1 w/WROVER\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80A8\",\n            \"make\": \"Espressif\",\n            \"model\": \"Saola 1 w/WROOM\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80AC\",\n            \"make\": \"UnexpectedMaker\",\n            \"model\": \"FeatherS2\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80AE\",\n            \"make\": \"PJRC\",\n            \"model\": \"Teensy 4.1\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80AF\",\n            \"make\": \"Radomir Dopieralski\",\n            \"model\": \"uGame10\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80B0\",\n            \"make\": \"Radomir Dopieralski\",\n            \"model\": \"Fluff M0\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80B2\",\n            \"make\": \"HiiBot\",\n            \"model\": \"HiiBot BlueFi\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80B4\",\n            \"make\": \"Nice Keyboards\",\n            \"model\": \"nice!nano\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80B6\",\n            \"make\": \"Microchip\",\n            \"model\": \"SAM E54 Xplained Pro\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80B8\",\n            \"make\": \"Zoomax\",\n            \"model\": \"LoC BeR M4 base board\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80B9\",\n            \"make\": \"ndGarage\",\n            \"model\": \"Bit6\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80BC\",\n            \"make\": \"Raytac Corporation\",\n            \"model\": \"MDBT50Q-DB-40\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80BE\",\n            \"make\": \"TinkeringTech\",\n            \"model\": \"TinkeringTech ScoutMakes Azul\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80C0\",\n            \"make\": \"Adafruit\",\n            \"model\": \"BLM Badge\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80C2\",\n            \"make\": \"bleeptrack\",\n            \"model\": \"PicoPlanet\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80C6\",\n            \"make\": \"MicroDev\",\n            \"model\": \"microS2\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80C8\",\n            \"make\": \"Espressif\",\n            \"model\": \"Kaluga 1\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80CA\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Matrix Portal M4\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80CC\",\n            \"make\": \"Adafruit\",\n            \"model\": \"QT Py M0\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80CE\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather M4 CAN\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80CF\",\n            \"make\": \"Kittenbot\",\n            \"model\": \"Meowbit\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80D1\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather M0 Express\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80D2\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather M0 RFM69\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80D3\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather M0 Adalogger\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80D4\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather M0 RFM9x\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80D5\",\n            \"make\": \"Radomir Dopieralski\",\n            \"model\": \"PewPew 10.2\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80D7\",\n            \"make\": \"Electronut Labs\",\n            \"model\": \"Blip\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80D8\",\n            \"make\": \"Nordic Semiconductor\",\n            \"model\": \"PCA10100\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80D9\",\n            \"make\": \"Nordic Semiconductor\",\n            \"model\": \"PCA10059\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80DA\",\n            \"make\": \"Nordic Semiconductor\",\n            \"model\": \"PCA10056\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80DB\",\n            \"make\": \"TG-Techie\",\n            \"model\": \"TG-Watch\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80DC\",\n            \"make\": \"makerdiary\",\n            \"model\": \"nRF52840-MDK\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80DD\",\n            \"make\": \"makerdiary\",\n            \"model\": \"nRF52840-MDK-Dongle\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80DE\",\n            \"make\": \"Muselab\",\n            \"model\": \"nanoESP32-S2 w/Wroom\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80E0\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Metro ESP32S2\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80E2\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Metro M7 iMX RT1011 AirLift\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80E6\",\n            \"make\": \"Adafruit\",\n            \"model\": \"MagTag\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80EC\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Adafruit Feather ESP32S2\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80EE\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather ESP32-S2 Reverse TFT\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80F0\",\n            \"make\": \"Adafruit\",\n            \"model\": \"NeoPixel Trinkey M0\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80F2\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather RP2040\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80F4\",\n            \"make\": \"Raspberry Pi\",\n            \"model\": \"Pico\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80F8\",\n            \"make\": \"Adafruit\",\n            \"model\": \"QT Py RP2040\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80FA\",\n            \"make\": \"Adafruit\",\n            \"model\": \"FunHouse\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80FC\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Rotary Trinkey M0\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"80FE\",\n            \"make\": \"Adafruit\",\n            \"model\": \"ItsyBitsy RP2040\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8100\",\n            \"make\": \"Adafruit\",\n            \"model\": \"NeoKey Trinkey M0\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8102\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Slide Trinkey M0\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8104\",\n            \"make\": \"Adafruit\",\n            \"model\": \"ProxLight Trinkey M0\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8106\",\n            \"make\": \"Adafruit\",\n            \"model\": \"KB2040\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8108\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Macropad RP2040\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"810A\",\n            \"make\": \"Adafruit\",\n            \"model\": \"QT2040 Trinkey\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"810C\",\n            \"make\": \"Raytac Corporation\",\n            \"model\": \"MDBT50Q-RX Dongle\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"810E\",\n            \"make\": \"Adafruit\",\n            \"model\": \"nRF52840 LED Glasses Driver\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8110\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather ESP32-S2 TFT\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8112\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Adafruit QT Py ESP32S2\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8114\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather ESP32S3 No PSRAM\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8118\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Camera\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"811A\",\n            \"make\": \"Adafruit\",\n            \"model\": \"QT Py ESP32S3 no psram\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"811C\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Adafruit Feather ESP32S3 4MB Flash 2MB PSRAM\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"811E\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather ESP32-S3 TFT\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8120\",\n            \"make\": \"Raspberry Pi\",\n            \"model\": \"Pico W\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8122\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather RP2040 Scorpio\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8124\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather ESP32-S3 Reverse TFT\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8126\",\n            \"make\": \"Adafruit\",\n            \"model\": \"MatrixPortal S3\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8128\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather RP2040 DVI\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"812A\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather RP2040 USB Host\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"812C\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather RP2040 ThinkInk\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"812E\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather RP2040 RFM\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8130\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather RP2040 CAN\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8132\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather RP2040 Prop-Maker\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8134\",\n            \"make\": \"NXP\",\n            \"model\": \"iMX RT 1050 EVKB\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8136\",\n            \"make\": \"NXP\",\n            \"model\": \"iMX RT 1040 EVK\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8138\",\n            \"make\": \"NXP\",\n            \"model\": \"IMXRT1015-EVK\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"813C\",\n            \"make\": \"NXP\",\n            \"model\": \"iMX RT 1060 EVKB\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"813E\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Metro RP2040\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8142\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Metro M7 iMX RT1011 SD\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8144\",\n            \"make\": \"Adafruit\",\n            \"model\": \"QT Py ESP32S3 4MB Flash 2MB PSRAM\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8148\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Qualia-S3-RGB666\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"814C\",\n            \"make\": \"Espressif\",\n            \"model\": \"ESP32-S3-EV-LCD-Board\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"814E\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Metro RP2350\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8150\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather RP2350\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8152\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Floppsy RP2040\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8154\",\n            \"make\": \"Adafruit\",\n            \"model\": \"SHT4x Trinkey M0\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8156\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Pixel Trinkey M0\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8158\",\n            \"make\": \"Adafruit\",\n            \"model\": \"TRRS Trinkey M0\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"815E\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Feather RP2040 Adalogger\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8160\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Adafruit Vindie S2\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"8162\",\n            \"make\": \"Raspberry Pi\",\n            \"model\": \"Pico 2 W\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"816C\",\n            \"make\": \"Adafruit\",\n            \"model\": \"Fruit Jam\"\n        },\n        {\n            \"vid\": \"239A\",\n            \"pid\": \"D1ED\",\n            \"make\": \"Adafruit\",\n            \"model\": \"HalloWing M0 Express\"\n        },\n        {\n            \"vid\": \"2786\",\n            \"pid\": \"9207\",\n            \"make\": \"Switch Science\",\n            \"model\": \"BLE-SS dev board Multi Sensor\"\n        },\n        {\n            \"vid\": \"2786\",\n            \"pid\": \"920D\",\n            \"make\": \"Switch Science\",\n            \"model\": \"SSCI ISP1807 Dev Board\"\n        },\n        {\n            \"vid\": \"2786\",\n            \"pid\": \"920F\",\n            \"make\": \"Switch Science\",\n            \"model\": \"SSCI ISP1807 Micro Board\"\n        },\n        {\n            \"vid\": \"2886\",\n            \"pid\": \"002F\",\n            \"make\": \"Seeed\",\n            \"model\": \"Seeeduino XIAO\"\n        },\n        {\n            \"vid\": \"2886\",\n            \"pid\": \"0042\",\n            \"make\": \"Seeed\",\n            \"model\": \"Seeeduino XIAO RP2040\"\n        },\n        {\n            \"vid\": \"2886\",\n            \"pid\": \"0045\",\n            \"make\": \"Seeed\",\n            \"model\": \"Seeed XIAO nRF52840 Sense\"\n        },\n        {\n            \"vid\": \"2886\",\n            \"pid\": \"0058\",\n            \"make\": \"Seeed\",\n            \"model\": \"Seeeduino XIAO RP2350\"\n        },\n        {\n            \"vid\": \"2886\",\n            \"pid\": \"802D\",\n            \"make\": \"Seeed\",\n            \"model\": \"Seeeduino Wio Terminal\"\n        },\n        {\n            \"vid\": \"2886\",\n            \"pid\": \"802F\",\n            \"make\": \"Seeed\",\n            \"model\": \"Seeeduino XIAO KB\"\n        },\n        {\n            \"vid\": \"2886\",\n            \"pid\": \"8056\",\n            \"make\": \"Seeed Studio\",\n            \"model\": \"Seeed Xiao ESP32-S3 Sense\"\n        },\n        {\n            \"vid\": \"2886\",\n            \"pid\": \"F001\",\n            \"make\": \"Makerdiary\",\n            \"model\": \"nRF52840 M.2 Developer Kit\"\n        },\n        {\n            \"vid\": \"2886\",\n            \"pid\": \"F002\",\n            \"make\": \"Makerdiary\",\n            \"model\": \"M60 Keyboard\"\n        },\n        {\n            \"vid\": \"2886\",\n            \"pid\": \"F003\",\n            \"make\": \"Makerdiary\",\n            \"model\": \"Makerdiary nRF52840 Connect Kit\"\n        },\n        {\n            \"vid\": \"2886\",\n            \"pid\": \"F004\",\n            \"make\": \"Makerdiary\",\n            \"model\": \"iMX RT1011 Nano Kit\"\n        },\n        {\n            \"vid\": \"2B04\",\n            \"pid\": \"C00C\",\n            \"make\": \"Particle\",\n            \"model\": \"Argon\"\n        },\n        {\n            \"vid\": \"2B04\",\n            \"pid\": \"C00D\",\n            \"make\": \"Particle\",\n            \"model\": \"Boron\"\n        },\n        {\n            \"vid\": \"2B04\",\n            \"pid\": \"C00E\",\n            \"make\": \"Particle\",\n            \"model\": \"Xenon\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"000B\",\n            \"make\": \"Raspberry Pi\",\n            \"model\": \"Pico 2\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1000\",\n            \"make\": \"Cytron\",\n            \"model\": \"Maker Pi RP2040\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1002\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Pimoroni Pico LiPo (4MB)\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1003\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Pimoroni Pico LiPo (16MB)\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1005\",\n            \"make\": \"Melopero\",\n            \"model\": \"Shake RP2040\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1006\",\n            \"make\": \"Invector Labs\",\n            \"model\": \"Challenger RP2040 WiFi\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1008\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"PGA2040\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1009\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Interstate 75\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"100A\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Plasma 2040\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"100B\",\n            \"make\": \"Invector Labs\",\n            \"model\": \"Challenger RP2040 LTE\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"100D\",\n            \"make\": \"Invector Labs\",\n            \"model\": \"Challenger NB RP2040 WiFi\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"100E\",\n            \"make\": \"Raspberry Pi\",\n            \"model\": \"Zero\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"100F\",\n            \"make\": \"Cytron\",\n            \"model\": \"Maker Nano RP2040\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1012\",\n            \"make\": \"Raspberry Pi\",\n            \"model\": \"Compute Module 4 IO Board\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1013\",\n            \"make\": \"Raspberry Pi\",\n            \"model\": \"Raspberry Pi 4B\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1014\",\n            \"make\": \"Raspberry Pi\",\n            \"model\": \"Compute Module 4\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1015\",\n            \"make\": \"Raspberry Pi\",\n            \"model\": \"Raspberry Pi Zero 2W\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1016\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Tiny 2040 (2MB)\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1018\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Inky Frame 5.7\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1019\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Motor 2040\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"101A\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Servo 2040\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"101B\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Badger 2040\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"101E\",\n            \"make\": \"Raspberry Pi\",\n            \"model\": \"Zero W\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"101F\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"RP2040-Zero\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1020\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"RP2040-Plus (4MB)\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1021\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"Waveshare RP2040-LCD-0.96\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1023\",\n            \"make\": \"Invector Labs\",\n            \"model\": \"Challenger RP2040 LoRa\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1026\",\n            \"make\": \"ELECFREAKS\",\n            \"model\": \"Pico:ed\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1027\",\n            \"make\": \"WIZnet\",\n            \"model\": \"W5100S-EVB-Pico\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1028\",\n            \"make\": \"WIZnet\",\n            \"model\": \"WizFi360-EVB-Pico\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1029\",\n            \"make\": \"WIZnet\",\n            \"model\": \"W5500-EVB-Pico\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"102C\",\n            \"make\": \"Invector Labs\",\n            \"model\": \"Challenger RP2040 WiFi/BLE\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"102D\",\n            \"make\": \"Invector Labs\",\n            \"model\": \"Challenger RP2040 SD/RTC\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"102E\",\n            \"make\": \"VCC-GND Studio\",\n            \"model\": \"YD-RP2040\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1032\",\n            \"make\": \"Invector Labs\",\n            \"model\": \"Challenger RP2040 SubGHz\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1039\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"Waveshare RP2040-LCD-1.28\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"103A\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"RP2040-One\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1043\",\n            \"make\": \"NEWSAN\",\n            \"model\": \"ARCHI\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1046\",\n            \"make\": \"WIZnet\",\n            \"model\": \"W6100-EVB-Pico\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1048\",\n            \"make\": \"nullbits\",\n            \"model\": \"Bit-C PRO\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"104A\",\n            \"make\": \"Boardsource\",\n            \"model\": \"BLOK\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"104B\",\n            \"make\": \"Datanoise\",\n            \"model\": \"PicoADK\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"104C\",\n            \"make\": \"Raspberry Pi\",\n            \"model\": \"COSMO-Pico\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"104F\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Badger 2040 W\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1056\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"RP2040-GEEK\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1057\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"Waveshare RP2040-TOUCH-LCD-1.28\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1058\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Plasma 2040 W\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1059\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Pimoroni Pico DV Demo Base for Pico\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"105A\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Pimoroni Pico DV Demo Base for Pico W\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"105E\",\n            \"make\": \"Breadstick Innovations\",\n            \"model\": \"Raspberry Breadstick\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1060\",\n            \"make\": \"splitkb.com\",\n            \"model\": \"Liatris\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1063\",\n            \"make\": \"Pajenicko s.r.o\",\n            \"model\": \"PicoPad\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1067\",\n            \"make\": \"WisdPi\",\n            \"model\": \"Ardu2040M\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"106A\",\n            \"make\": \"WisdPi\",\n            \"model\": \"Tiny RP2040\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1071\",\n            \"make\": \"Cytron\",\n            \"model\": \"Maker Uno RP2040\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1072\",\n            \"make\": \"Maple Computing\",\n            \"model\": \"Elite-Pi\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1073\",\n            \"make\": \"Brad\\u00e1n Lane STUDIO\",\n            \"model\": \"Explorer Badge\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1074\",\n            \"make\": \"Cytron\",\n            \"model\": \"Cytron EDU PICO for Pico W\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"107D\",\n            \"make\": \"HEIA-FR\",\n            \"model\": \"Picomo V2\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1081\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Inky Frame 7.3\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1083\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"RP2040-PiZero\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1084\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"RP2040-Tiny\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1093\",\n            \"make\": \"Cytron\",\n            \"model\": \"IRIV IO Controller\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"1096\",\n            \"make\": \"Cytron\",\n            \"model\": \"MOTION 2350 Pro\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"109A\",\n            \"make\": \"Invector Labs\",\n            \"model\": \"Challenger+ RP2350 WiFi6/BLE5\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"109B\",\n            \"make\": \"Invector Labs\",\n            \"model\": \"Challenger+ RP2350 BConnect\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"109E\",\n            \"make\": \"WIZnet\",\n            \"model\": \"W5100S-EVB-Pico2\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"109F\",\n            \"make\": \"WIZnet\",\n            \"model\": \"W5500-EVB-Pico2\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"10A0\",\n            \"make\": \"WIZnet\",\n            \"model\": \"W6100-EVB-Pico2\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"10A2\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Tiny FX\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"10A3\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Pico Plus 2\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"10A4\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Tiny 2350\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"10A5\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Plasma 2350\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"10A6\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"PGA2350\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"10AE\",\n            \"make\": \"Datanoise\",\n            \"model\": \"PicoADK V2\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"10B0\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"RP2350-Zero\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"10B1\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"RP2350-Plus\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"10B2\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"RP2350-Tiny\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"10B3\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"Waveshare RP2350-LCD-1.28\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"10B4\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"Waveshare RP2350-TOUCH-LCD-1.28\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"10B5\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"RP2350-One\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"10B6\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"RP2350-GEEK\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"10B7\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"Waveshare RP2350-LCD-0.96\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"10BD\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Pico Plus 2 W\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"10BF\",\n            \"make\": \"Pimoroni\",\n            \"model\": \"Plasma 2350 W\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"10C1\",\n            \"make\": \"Music Thing Modular\",\n            \"model\": \"Workshop Computer\"\n        },\n        {\n            \"vid\": \"2E8A\",\n            \"pid\": \"10C4\",\n            \"make\": \"HEIA-FR\",\n            \"model\": \"Picomo V3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"7001\",\n            \"make\": \"Espressif\",\n            \"model\": \"ESP32-S2-HMI-DevKit-1\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"7003\",\n            \"make\": \"Espressif\",\n            \"model\": \"ESP32-S3-DevKitC-1-N8R8\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"7005\",\n            \"make\": \"Espressif\",\n            \"model\": \"ESP32-S3-Box-2.5\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"7007\",\n            \"make\": \"Espressif\",\n            \"model\": \"ESP32-S3-DevKitM-1-N8\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"7009\",\n            \"make\": \"Espressif\",\n            \"model\": \"ESP32-S2-DevKitC-1-N4R2\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"700B\",\n            \"make\": \"Espressif\",\n            \"model\": \"ESP32-S3-USB-OTG-N8\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"700D\",\n            \"make\": \"Espressif\",\n            \"model\": \"ESP32-S3-Box-Lite\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"700F\",\n            \"make\": \"Espressif\",\n            \"model\": \"ESP32-S3-EYE\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"7011\",\n            \"make\": \"Espressif\",\n            \"model\": \"ESP32-S3-EV-LCD-Board_v1.5\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"7013\",\n            \"make\": \"Espressif\",\n            \"model\": \"ESP32-P4-Function-EV\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"8002\",\n            \"make\": \"UnexpectedMaker\",\n            \"model\": \"TinyS2\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"8007\",\n            \"make\": \"LILYGO\",\n            \"model\": \"TTGO T8 ESP32-S2\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"800D\",\n            \"make\": \"Gravitech\",\n            \"model\": \"Cucumber RS\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80A1\",\n            \"make\": \"Gravitech\",\n            \"model\": \"Cucumber R\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80A4\",\n            \"make\": \"Gravitech\",\n            \"model\": \"Cucumber M\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80A7\",\n            \"make\": \"Gravitech\",\n            \"model\": \"Cucumber MS\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80AA\",\n            \"make\": \"Espressif\",\n            \"model\": \"Franzininho WIFI w/Wroom\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80AD\",\n            \"make\": \"Espressif\",\n            \"model\": \"Franzininho WIFI w/Wrover\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80AF\",\n            \"make\": \"Artisense\",\n            \"model\": \"Reference Design RD00\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80B2\",\n            \"make\": \"Muselab\",\n            \"model\": \"nanoESP32-S2  w/Wrover\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80B5\",\n            \"make\": \"UnexpectedMaker\",\n            \"model\": \"FeatherS2 Neo\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80B7\",\n            \"make\": \"MORPHEANS\",\n            \"model\": \"MORPHESP-240\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80C3\",\n            \"make\": \"Lolin\",\n            \"model\": \"S2 Mini\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80C6\",\n            \"make\": \"Lolin\",\n            \"model\": \"S2 Pico\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80C8\",\n            \"make\": \"BrainBoardz\",\n            \"model\": \"Neuron\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80D1\",\n            \"make\": \"UnexpectedMaker\",\n            \"model\": \"TinyS3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80D4\",\n            \"make\": \"UnexpectedMaker\",\n            \"model\": \"ProS3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80D7\",\n            \"make\": \"UnexpectedMaker\",\n            \"model\": \"FeatherS3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80D9\",\n            \"make\": \"FutureKeys\",\n            \"model\": \"HexKy_S2\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80DD\",\n            \"make\": \"CircuitArt\",\n            \"model\": \"ZeroS3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80E0\",\n            \"make\": \"BananaPi\",\n            \"model\": \"BPI-Leaf-S3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80E6\",\n            \"make\": \"BananaPi\",\n            \"model\": \"BPI-Bit-S2\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80E8\",\n            \"make\": \"HiiBot\",\n            \"model\": \"HiiBot IoTs2\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80EA\",\n            \"make\": \"LILYGO\",\n            \"model\": \"TTGO T8 ESP32-S2-WROOM\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80ED\",\n            \"make\": \"LILYGO\",\n            \"model\": \"TTGO T8 ESP32-S2\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80F9\",\n            \"make\": \"Cytron\",\n            \"model\": \"Cytron Maker Feather AIoT S3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80FC\",\n            \"make\": \"Espressif\",\n            \"model\": \"MixGo CE\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"80FD\",\n            \"make\": \"Espressif\",\n            \"model\": \"MixGo CE\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"810A\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"ESP32-S2-Pico\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"810C\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"ESP32-S2-Pico-LCD\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"8111\",\n            \"make\": \"Smart Bee Designs\",\n            \"model\": \"Bee-S3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"8114\",\n            \"make\": \"Smart Bee Designs\",\n            \"model\": \"Bee-Motion-S3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"8117\",\n            \"make\": \"WEMOS\",\n            \"model\": \"LOLIN S3 16MB Flash 8MB PSRAM\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"811A\",\n            \"make\": \"M5Stack\",\n            \"model\": \"M5Stack Core S3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"8120\",\n            \"make\": \"M5Stack\",\n            \"model\": \"M5Stack AtomS3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"812C\",\n            \"make\": \"BananaPi\",\n            \"model\": \"BPI-PicoW-S3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"813F\",\n            \"make\": \"LILYGO\",\n            \"model\": \"T-Display S3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"8142\",\n            \"make\": \"Turkish Technology Team Foundation\",\n            \"model\": \"Deneyap Mini\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"8145\",\n            \"make\": \"Turkish Technology Team Foundation\",\n            \"model\": \"Deneyap Mini v2\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"8148\",\n            \"make\": \"Turkish Technology Team Foundation\",\n            \"model\": \"Deneyap Kart 1A v2\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"8151\",\n            \"make\": \"LILYGO\",\n            \"model\": \"TEMBED ESP32S3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"815D\",\n            \"make\": \"Smart Bee Designs\",\n            \"model\": \"Bee-Data-Logger\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"815F\",\n            \"make\": \"M5Stack\",\n            \"model\": \"M5Stack AtomS3 Lite\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"8162\",\n            \"make\": \"WEMOS\",\n            \"model\": \"LOLIN S3 PRO 16MB Flash 8MB PSRAM\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"8166\",\n            \"make\": \"VCC-GND\",\n            \"model\": \"YD-ESP32-S3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"8168\",\n            \"make\": \"WEMOS\",\n            \"model\": \"LOLIN S3 MINI 4MB Flash 2MB PSRAM\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"816B\",\n            \"make\": \"M5STACK\",\n            \"model\": \"M5Stack StampS3 - CircuitPython\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"817A\",\n            \"make\": \"UnexpectedMaker\",\n            \"model\": \"NanoS3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"817D\",\n            \"make\": \"UnexpectedMaker\",\n            \"model\": \"BlizzardS3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"8180\",\n            \"make\": \"UnexpectedMaker\",\n            \"model\": \"BLING!\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"8187\",\n            \"make\": \"M5Stack\",\n            \"model\": \"M5Stack AtomS3U\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"81A3\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"ESP32-S3-Pico\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"81AA\",\n            \"make\": \"MakerM0\",\n            \"model\": \"MagiClick S3 n4r2\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"81B1\",\n            \"make\": \"UnexpectedMaker\",\n            \"model\": \"TinyWATCH S3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"81B4\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"Waveshare ESP32-S3-Zero\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"81B6\",\n            \"make\": \"LILYGO\",\n            \"model\": \"T-Deck (Plus)\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"81B9\",\n            \"make\": \"Espressif\",\n            \"model\": \"senseBox MCU-S2 ESP32S2\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"81BF\",\n            \"make\": \"MakerFabs\",\n            \"model\": \"MakerFabs-ESP32-S3-Parallel-TFT-With-Touch-7inch\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"81CF\",\n            \"make\": \"Flipper Devices\",\n            \"model\": \"Flipper Zero Wi-Fi Dev\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"81D0\",\n            \"make\": \"Double Take Labs\",\n            \"model\": \"COLUMBIA-DSL-SENSOR-BOARD-V1\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"81DA\",\n            \"make\": \"M5STACK\",\n            \"model\": \"M5Stack Cardputer - CircuitPython\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"81DD\",\n            \"make\": \"M5Stack\",\n            \"model\": \"M5stack - Dial\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"81EA\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"ESP32-S3-GEEK\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"81F8\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"ESP32-S3-Tiny\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"81FC\",\n            \"make\": \"UnexpectedMaker\",\n            \"model\": \"FeatherS3 Neo\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"81FF\",\n            \"make\": \"UnexpectedMaker\",\n            \"model\": \"RGB Touch Mini\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"8204\",\n            \"make\": \"ThingPulse\",\n            \"model\": \"ThingPulse Pendrive S3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"8211\",\n            \"make\": \"LILYGO\",\n            \"model\": \"T-Display S3 Pro\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"8217\",\n            \"make\": \"WEMOS\",\n            \"model\": \"LOLIN S3 MINI PRO 4MB Flash 2MB PSRAM\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"821C\",\n            \"make\": \"LILYGO\",\n            \"model\": \"T-Watch-S3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"8225\",\n            \"make\": \"UnexpectedMaker\",\n            \"model\": \"OMGS3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"8244\",\n            \"make\": \"Fablab Barcelona\",\n            \"model\": \"Barduino 4.0.2\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"826E\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"Waveshare ESP32-S3-Matrix\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"82A7\",\n            \"make\": \"Waveshare Electronics\",\n            \"model\": \"ESP32-S3-ETH\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"82C2\",\n            \"make\": \"LILYGO\",\n            \"model\": \"T-Dongle S3\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"82C4\",\n            \"make\": \"Unknown\",\n            \"model\": \"ESP32-S2-WROOM\"\n        },\n        {\n            \"vid\": \"303A\",\n            \"pid\": \"82C9\",\n            \"make\": \"Heltec\",\n            \"model\": \"Vision Master E290\"\n        },\n        {\n            \"vid\": \"30A4\",\n            \"pid\": \"0002\",\n            \"make\": \"Blues Wireless\",\n            \"model\": \"Swan R5\"\n        },\n        {\n            \"vid\": \"3171\",\n            \"pid\": \"0101\",\n            \"make\": \"8086 Consultancy\",\n            \"model\": \"Commander\"\n        },\n        {\n            \"vid\": \"3171\",\n            \"pid\": \"010C\",\n            \"make\": \"8086 Consultancy\",\n            \"model\": \"USB Interposer\"\n        },\n        {\n            \"vid\": \"3171\",\n            \"pid\": \"010D\",\n            \"make\": \"8086 Consultancy\",\n            \"model\": \"RP2040 Interfacer\"\n        },\n        {\n            \"vid\": \"31E2\",\n            \"pid\": \"2011\",\n            \"make\": \"BDMICRO\",\n            \"model\": \"VINA-D51\"\n        },\n        {\n            \"vid\": \"31E2\",\n            \"pid\": \"2021\",\n            \"make\": \"BDMICRO\",\n            \"model\": \"VINA-D51\"\n        },\n        {\n            \"vid\": \"32BD\",\n            \"pid\": \"3001\",\n            \"make\": \"Alorium Technology\",\n            \"model\": \"AloriumTech Evo M51\"\n        },\n        {\n            \"vid\": \"3343\",\n            \"pid\": \"83CF\",\n            \"make\": \"DFRobot\",\n            \"model\": \"Firebeetle 2 ESP32-S3\"\n        },\n        {\n            \"vid\": \"4097\",\n            \"pid\": \"0001\",\n            \"make\": \"TG-Boards\",\n            \"model\": \"Datalore IP M4\"\n        },\n        {\n            \"vid\": \"612B\",\n            \"pid\": \"80A7\",\n            \"make\": \"Ai-Thinker\",\n            \"model\": \"ESP 12k NodeMCU\"\n        }\n    ]\n}"
  },
  {
    "path": "SimplySerial/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Newtonsoft.Json\" version=\"13.0.3\" targetFramework=\"net48\" />\n</packages>"
  }
]