commit 2e46747ba9698b65f1bd28e7b25a78cf4d43a468 Author: 17860779768 <3219079380@qq.com> Date: Mon Aug 25 16:33:58 2025 +0800 视觉修改 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9491a2f --- /dev/null +++ b/.gitignore @@ -0,0 +1,363 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd \ No newline at end of file diff --git a/Check.Main/Camera/CameraManager.cs b/Check.Main/Camera/CameraManager.cs new file mode 100644 index 0000000..3762048 --- /dev/null +++ b/Check.Main/Camera/CameraManager.cs @@ -0,0 +1,838 @@ +using Check.Main.Common; +using Check.Main.Infer; +using Check.Main.Result; +using Check.Main.UI; +using OpenCvSharp; +using SkiaSharp; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; +using System.Timers; +using System.Windows.Forms; + +namespace Check.Main.Camera +{ + /// + /// 静态全局相机管理器,负责所有相机的生命周期、配置应用和多相机同步 + /// + public static class CameraManager + { + // 活动的相机实例字典,键为相机名称 + public static Dictionary ActiveCameras { get; } = new Dictionary(); + + // 相机对应的图像显示窗口字典 + //public static Dictionary CameraDisplays { get; } = new Dictionary(); + + public static Dictionary OriginalImageDisplays { get; } = new Dictionary(); + public static Dictionary ResultImageDisplays { get; } = new Dictionary(); + + // --- 多相机同步逻辑 --- + // 产品检测队列 + private static readonly Queue ProductQueue = new Queue(); + // 队列锁,保证线程安全 + private static readonly object QueueLock = new object(); + // 当前启用的相机数量,用于判断产品是否检测完毕 + private static int EnabledCameraCount = 0; + + //public static event EventHandler OnDetectionCompleted; + // public static bool IsDetectionRunning { get; private set; } = false; + + // 产品ID计数器 + private static long _productCounter = 0; + // 用于同步计数器访问的锁,虽然long的自增是原子操作,但为清晰和未来扩展,使用锁是好习惯 + private static readonly object _counterLock = new object(); + + // --- 新增:硬触发模拟器 --- + private static readonly System.Timers.Timer _hardwareTriggerSimulator; + + /// + /// 获取或设置模拟硬触发的间隔时间(毫秒)。 + /// + public static double TriggerInterval { get; set; } = 1000; // 默认1秒触发一次 + + /// + /// 获取一个值,该值指示硬件触发模拟器当前是否正在运行。 + /// + public static bool IsHardwareTriggerSimulating { get; private set; } = false; + + /// + /// 静态构造函数,用于一次性初始化静态资源。 + /// + static CameraManager() + { + //初始化硬触发模拟器 + _hardwareTriggerSimulator = new System.Timers.Timer(); + _hardwareTriggerSimulator.Elapsed += OnHardwareTriggerTimerElapsed; + _hardwareTriggerSimulator.AutoReset = true; // 确保定时器持续触发 + _hardwareTriggerSimulator.Enabled = false; // 默认不启动 + } + + + //// 事件:用于向UI发送日志消息 + //public static event Action OnLogMessage; + //// 用于写入日志文件的 StreamWriter + //private static StreamWriter _logFileWriter; + + ////私有的、静态的、只读的对象,专门用作线程同步的“锁”。 + //private static readonly object _logLock = new object(); + + /// + /// 初始化文件日志记录器。应在程序启动时调用一次。 + /// + //public static void InitializeLogger() + //{ + // try + // { + // string logDirectory = Path.Combine(Application.StartupPath, "Logs"); + // Directory.CreateDirectory(logDirectory); // 确保Logs文件夹存在 + + // string logFileName = $"Log_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.txt"; + // string logFilePath = Path.Combine(logDirectory, logFileName); + + // // 创建StreamWriter,设置为追加模式和自动刷新 + // _logFileWriter = new StreamWriter(logFilePath, append: true, encoding: System.Text.Encoding.UTF8) + // { + // AutoFlush = true + // }; + + // Log("文件日志记录器已初始化。"); + // } + // catch (Exception ex) + // { + // // 如果文件日志初始化失败,在UI上报告错误 + // OnLogMessage?.Invoke($"[CRITICAL] 文件日志初始化失败: {ex.Message}"); + // } + //} + + /// + /// 【新增】一个完整的业务流程方法: + /// 1. 根据配置初始化所有相机并显示它们的窗口。 + /// 2. 在所有窗口都显示后,命令所有相机开始采集。 + /// 这个方法是响应“开启设备”或“应用配置并启动”按钮的理想入口点。 + /// + /// 要应用的相机配置列表。 + /// 主窗体,用于停靠显示窗口。 + //public static void ApplyConfigurationAndStartGrabbing(List settingsList, FrmMain mainForm) + //{ + // ThreadSafeLogger.Log("开始执行“开启设备”流程..."); + + // // 步骤 1: 初始化所有相机和UI窗口 + // // Initialize 方法会负责 Shutdown 旧实例、创建新实例、打开硬件、显示窗口等。 + // // 因为 Initialize 方法中的 displayForm.Show() 是非阻塞的,它会立即返回, + // // 窗体的创建和显示过程会被调度到UI线程的消息队列中。 + // Initialize(settingsList, mainForm); + + // // 检查是否有任何相机成功初始化 + // if (ActiveCameras.Count == 0) + // { + // ThreadSafeLogger.Log("“开启设备”流程中止,因为没有相机被成功初始化。"); + // return; + // } + + // // 步骤 2: 在 Initialize 完成后(意味着所有窗口都已创建并 Show),开始采集 + // // 这个调用会紧接着 Initialize 执行,此时窗体可能还在绘制过程中,但这没关系。 + // // StartAll() 会启动后台线程开始拉取图像,一旦图像到达,就会通过事件推送到已经存在的窗体上。 + // ThreadSafeLogger.Log("所有相机窗口已创建,现在开始采集图像..."); + // StartAll(); + + // ThreadSafeLogger.Log("“开启设备”流程已完成。相机正在采集中。"); + //} + + ///// + ///// 根据配置列表初始化或更新所有相机 + ///// + //public static void Initialize(List settingsList, FrmMain mainForm) + //{ + + // // 先停止并释放所有旧的相机 + // Shutdown(); + // ThreadSafeLogger.Log("开始应用新的相机配置..."); + + // EnabledCameraCount = settingsList.Count(s => s.IsEnabled); + // if (EnabledCameraCount == 0) + // { + // ThreadSafeLogger.Log("没有启用的相机。"); + // return; + // } + + // var deviceList = new HikvisionCamera().FindDevices(); + // if (deviceList.Count == 0) + // { + // ThreadSafeLogger.Log("错误:未找到任何相机设备!"); + // return; + // } + + // int deviceIndex = 0; + // foreach (var setting in settingsList) + // { + // if (!setting.IsEnabled) continue; + + // if (deviceIndex >= deviceList.Count) + // { + // ThreadSafeLogger.Log($"警告:相机配置'{setting.Name}'无法分配物理设备,因为设备数量不足。"); + // continue; + // } + + // // --- 创建相机实例 --- + // var cam = new HikvisionCamera { Name = setting.Name }; + // cam.TriggerMode = setting.TriggerMode; + // if (!cam.Open(setting)) + // { + // ThreadSafeLogger.Log($"错误:打开相机'{setting.Name}'失败。"); + // cam.Dispose(); + // continue; + // } + // // --- 设置触发模式 --- + // switch (setting.TriggerMode) + // { + // case TriggerModeType.Continuous: + // cam.SetContinuousMode(); + // break; + // case TriggerModeType.Software: + // cam.SetTriggerMode(true); + // break; + // case TriggerModeType.Hardware: + // cam.SetTriggerMode(false); + // break; + // } + + // // --- 订阅事件 --- + // cam.ImageAcquired += OnCameraImageAcquired; + // cam.CameraMessage += (sender, msg, err) => ThreadSafeLogger.Log($"{(sender as HikvisionCamera).Name}: {msg}"); + + // // --- 创建显示窗口 --- + // var displayForm = new FormImageDisplay { Text = setting.Name, CameraName = setting.Name }; + // displayForm.OnDisplayEvent += ThreadSafeLogger.Log; + // displayForm.Show(mainForm.MainDockPanel, WeifenLuo.WinFormsUI.Docking.DockState.Document); + + + // ActiveCameras.Add(setting.Name, cam); + // CameraDisplays.Add(setting.Name, displayForm); + // mainForm.AddCameraToStatusStrip(setting.Name); + // ThreadSafeLogger.Log($"相机'{setting.Name}'初始化成功,分配到物理设备 {deviceIndex}。"); + // deviceIndex++; + // } + //} + + + /// + /// 准备所有相机硬件、UI窗口和后台处理器,但不开始采集。 + /// 这是“启动设备”的第一阶段。 + /// + public static void PrepareAll(ProcessConfig config, FrmMain mainForm) + { + // 1. 清理旧资源和UI + mainForm.ClearStatusStrip(); + Shutdown(); + ThreadSafeLogger.Log("开始准备设备和模型..."); + + // 2. 初始化检测协调器和AI模型 + // 注意:YoloModelManager 的 Initialize 现在也应在这里被调用,以确保逻辑集中 + YoloModelManager.Initialize(config.ModelSettings); + DetectionCoordinator.Initialize(config.CameraSettings, config.ModelSettings); + + // 3. 创建相机硬件实例和UI窗口 + var deviceList = new HikvisionCamera().FindDevices(); + if (deviceList.Count == 0) + { + ThreadSafeLogger.Log("错误:未找到任何相机设备!"); + return; + } + + foreach (var setting in config.CameraSettings.Where(s => s.IsEnabled)) + { + var cam = new HikvisionCamera { Name = setting.Name, CameraIndex = setting.CameraIndex }; + cam.TriggerMode = setting.TriggerMode; + if (!cam.Open(setting)) + { + ThreadSafeLogger.Log($"错误:打开相机'{setting.Name}'失败。"); + cam.Dispose(); + continue; + } + // --- 设置触发模式 --- + switch (setting.TriggerMode) + { + case TriggerModeType.Continuous: + cam.SetContinuousMode(); + break; + case TriggerModeType.Software: + cam.SetTriggerMode(true); + break; + case TriggerModeType.Hardware: + cam.SetTriggerMode(false); + break; + } + + // --- 订阅事件 --- + cam.ImageAcquired += OnCameraImageAcquired; + var processor = DetectionCoordinator.GetProcessor(cam.CameraIndex); + if (processor != null) { processor.OnProcessingCompleted += Processor_OnProcessingCompleted; } + + // --- 创建【但不显示】图像的UI窗口 --- + var originalDisplay = new FormImageDisplay { Text = $"{setting.Name} - 原图", CameraName = setting.Name }; + var resultDisplay = new FormImageDisplay { Text = $"{setting.Name} - 结果", CameraName = setting.Name }; + originalDisplay.Show(mainForm.MainDockPanel, WeifenLuo.WinFormsUI.Docking.DockState.Document); + resultDisplay.Show(mainForm.MainDockPanel, WeifenLuo.WinFormsUI.Docking.DockState.Document); + + // --- 保存引用 --- + ActiveCameras.Add(setting.Name, cam); + OriginalImageDisplays.Add(setting.Name, originalDisplay); + ResultImageDisplays.Add(setting.Name, resultDisplay); + mainForm.AddCameraToStatusStrip(setting.Name); + } + ThreadSafeLogger.Log("所有设备和模型已准备就绪。"); + } + + + /// + /// 根据配置列表初始化或更新所有相机 + /// + public static void Initialize(ProcessConfig config, FrmMain mainForm) + { + mainForm?.ClearStatusStrip(); + + // 先停止并释放所有旧的相机 + Shutdown(); + ThreadSafeLogger.Log("开始应用新的相机配置..."); + // 2. 初始化新的检测协调器 + DetectionCoordinator.Initialize(config.CameraSettings, config.ModelSettings); + + var deviceList = new HikvisionCamera().FindDevices(); + if (deviceList.Count == 0) + { + ThreadSafeLogger.Log("错误:未找到任何相机设备!"); + return; + } + int deviceIndex = 0; + foreach (var device in config.ModelSettings.Where(s => s.IsEnabled)) + { + if (!device.IsEnabled) continue; + mainForm.AddCameraToStatusStrip(device.Name); + } + foreach (var setting in config.CameraSettings.Where(s => s.IsEnabled)) + { + if (!setting.IsEnabled) continue; + + if (deviceIndex >= deviceList.Count) + { + ThreadSafeLogger.Log($"警告:相机配置'{setting.Name}'无法分配物理设备,因为设备数量不足。"); + continue; + } + // --- 创建相机实例 --- + var cam = new HikvisionCamera { Name = setting.Name, CameraIndex = setting.CameraIndex }; + cam.TriggerMode = setting.TriggerMode; + if (!cam.Open(setting)) + { + ThreadSafeLogger.Log($"错误:打开相机'{setting.Name}'失败。"); + cam.Dispose(); + continue; + } + // --- 设置触发模式 --- + switch (setting.TriggerMode) + { + case TriggerModeType.Continuous: + cam.SetContinuousMode(); + break; + case TriggerModeType.Software: + cam.SetTriggerMode(true); + break; + case TriggerModeType.Hardware: + cam.SetTriggerMode(false); + break; + } + + // --- 订阅事件 --- + cam.ImageAcquired += OnCameraImageAcquired; + cam.CameraMessage += (sender, msg, err) => ThreadSafeLogger.Log($"{(sender as HikvisionCamera).Name}: {msg}"); + ActiveCameras.Add(setting.Name, cam); + // --- 创建显示窗口 --- + var displayForm = new FormImageDisplay { Text = $"{setting.Name} - 原图", CameraName = setting.Name }; + var checkFrm = new FormImageDisplay { Text = $"{setting.Name} - 结果", CameraName = setting.Name }; + displayForm.OnDisplayEvent += ThreadSafeLogger.Log; + displayForm.Show(mainForm.MainDockPanel, WeifenLuo.WinFormsUI.Docking.DockState.Document); + checkFrm.Show(mainForm.MainDockPanel, WeifenLuo.WinFormsUI.Docking.DockState.Document); + + OriginalImageDisplays.Add(setting.Name, displayForm); + ResultImageDisplays.Add(setting.Name, checkFrm); + mainForm.AddCameraToStatusStrip(setting.Name); + var processor = DetectionCoordinator.GetProcessor(cam.CameraIndex); + if (processor != null) + { + processor.OnProcessingCompleted += Processor_OnProcessingCompleted; + } + ThreadSafeLogger.Log($"相机'{setting.Name}'初始化成功,分配到物理设备 {deviceIndex}。"); + deviceIndex++; + } + } + + /// + /// 启动硬件触发模拟器。 + /// + public static void StartHardwareTriggerSimulator() + { + if (IsHardwareTriggerSimulating) return; + + _hardwareTriggerSimulator.Interval = TriggerInterval; + _hardwareTriggerSimulator.Start(); + IsHardwareTriggerSimulating = true; + ThreadSafeLogger.Log($"硬件触发模拟器已启动,触发间隔: {TriggerInterval} ms。"); + } + + /// + /// 停止硬件触发模拟器。 + /// + public static void StopHardwareTriggerSimulator() + { + if (!IsHardwareTriggerSimulating) return; + + _hardwareTriggerSimulator.Stop(); + IsHardwareTriggerSimulating = false; + ThreadSafeLogger.Log("硬件触发模拟器已停止。"); + } + + /// + /// 定时器触发事件。 + /// + private static void OnHardwareTriggerTimerElapsed(object sender, ElapsedEventArgs e) + { + // 遍历所有活动的相机 + foreach (var cam in ActiveCameras.Values) + { + // 仅对配置为“硬件触发”模式的相机执行操作 + // 重要:我们使用软触发命令(SoftwareTrigger)来“模拟”一个外部硬件信号的到达。 + if (cam.TriggerMode == TriggerModeType.Software && cam.IsGrabbing) + { + // ThreadSafeLogger.Log($"模拟硬触发信号,触发相机: {cam.Name}"); // 如果需要详细日志可以取消注释 + cam.SoftwareTrigger(); + } + } + } + + + /// + /// 所有启用的相机开始采集 + /// + public static void StartAll() + { + foreach (var cam in ActiveCameras.Values) + { + cam.StartGrabbing(); + } + ThreadSafeLogger.Log("所有相机已开始采集。"); + } + + //public static void StartDetection() + //{ + // if (!IsDetectionRunning) + // { + // IsDetectionRunning = true; + // ThreadSafeLogger.Log("检测已启动,开始统计数据。"); + // } + //} + //public static void StopDetection() + //{ + // if (IsDetectionRunning) + // { + // IsDetectionRunning = false; + // ThreadSafeLogger.Log("检测已停止。"); + // } + //} + + /// + /// 所有启用的相机停止采集 + /// + public static void StopAll() + { + foreach (var cam in ActiveCameras.Values) + { + cam.StopGrabbing(); + } + ThreadSafeLogger.Log("所有相机已停止采集。"); + } + + ///// + ///// 停止并释放所有相机资源 + ///// + //public static void Shutdown() + //{ + // // --- 新增:确保在关闭时停止模拟器并释放资源 --- + // StopHardwareTriggerSimulator(); + // //_hardwareTriggerSimulator?.Dispose(); + + // StopAll(); + // foreach (var cam in ActiveCameras.Values) + // { + // cam.Dispose(); + // } + // foreach (var display in CameraDisplays.Values) + // { + // display.Close(); + // } + // lock (QueueLock) + // { + // while (ProductQueue.Count > 0) + // { + // ProductQueue.Dequeue()?.Dispose(); + // } + // } + // ResetProductCounter(); + // ActiveCameras.Clear(); + // CameraDisplays.Clear(); + // ThreadSafeLogger.Log("正在关闭文件日志记录器..."); + // ThreadSafeLogger.Log("所有相机资源已释放。"); + + //} + + // Shutdown 方法也简化 + public static void Shutdown() + { + // 1. 停止硬件和模拟器 + StopAll(); + StopHardwareTriggerSimulator(); + // 2. 关闭相机实例和窗口 + foreach (var cam in ActiveCameras.Values) { cam.Dispose(); } + foreach (var display in OriginalImageDisplays.Values) { display.Close(); } + foreach (var display in ResultImageDisplays.Values) { display.Close(); } + ActiveCameras.Clear(); + OriginalImageDisplays.Clear(); + ResultImageDisplays.Clear(); + // 3. 关闭检测协调器,它会负责清理所有后台线程和队列 + DetectionCoordinator.Shutdown(); + + YoloModelManager.Shutdown(); + + ThreadSafeLogger.Log("所有相机及协调器资源已释放。"); + } + + /// + /// 重置产品计数器的公共方法 + /// + public static void ResetProductCounter() + { + lock (_counterLock) + { + _productCounter = 0; + } + ThreadSafeLogger.Log("产品计数器已重置。"); + } + + /// + /// 接收到相机图像时的核心处理逻辑 + /// + //private static void OnCameraImageAcquired(HikvisionCamera sender, Bitmap bmp) + //{ + + // Bitmap bmpForDisplay =null; + // Bitmap bmpForQueue = null; + // try + // { + // bmpForDisplay?.Dispose(); + // bmpForQueue?.Dispose(); + // // 1. 为“显示”和“处理队列”创建独立的深克隆副本 + // bmpForDisplay = DeepCloneBitmap(bmp, "Display"); + // bmpForQueue = DeepCloneBitmap(bmp, "Queue"); + // } + // finally + // { + // // 【关键】无论克隆成功与否,都必须立即释放事件传递过来的原始bmp。 + // // 这是保证没有泄漏的第一道防线。 + // bmp?.Dispose(); + // } + // // --- 现在我们使用完全独立的副本进行后续操作 --- + + // // 4. 将显示副本传递给UI + // if (bmpForDisplay != null && CameraDisplays.TryGetValue(sender.Name, out var display)) + // { + // display.UpdateImage(bmpForDisplay); + // } + // else + // { + // // 如果不需要显示,或者显示失败,必须释放掉为它创建的副本 + // bmpForDisplay?.Dispose(); + // } + // // 5. 将队列副本添加到产品中 + // if (bmpForQueue != null) + // { + // lock (QueueLock) + // { + // ProductResult currentProduct; + // bool isNewProductCycle = ProductQueue.Count == 0 || ProductQueue.Last().CapturedImages.ContainsKey(sender.Name); + // if (isNewProductCycle) + // { + // if (ProductQueue.Count > 0 && !ProductQueue.Peek().IsComplete(EnabledCameraCount)) + // { + // var orphanedProduct = ProductQueue.Dequeue(); // 从队列头部移除这个不完整的产品 + // ThreadSafeLogger.Log($"[警告] 产品 #{orphanedProduct.ProductID} 未能集齐所有相机图像而被丢弃,以防止内存泄漏。"); + // orphanedProduct.Dispose(); // 确保释放其占用的所有资源 + // } + // long newProductId; + // lock (_counterLock) + // { + // _productCounter++; + // newProductId = _productCounter; + // } + // currentProduct = new ProductResult(newProductId); + // ProductQueue.Enqueue(currentProduct); + // } + // else + // { + // currentProduct = ProductQueue.Last(); + // } + + // currentProduct.AddImage(sender.Name, bmpForQueue); // bmpForQueue的所有权转移给了产品队列 + + // while (ProductQueue.Count > 0 && ProductQueue.Peek().IsComplete(EnabledCameraCount)) + // { + // // Peek() 查看队头元素但不移除它 + // var finishedProduct = ProductQueue.Dequeue(); // Dequeue() 移除队头元素 + // ThreadSafeLogger.Log($"产品 #{finishedProduct.ProductID} 已完整,出队处理。"); + + // // --- 这是您已有的处理逻辑 --- + // bool isOk = new Random().NextDouble() > 0.1; + // string finalResult = isOk ? "OK" : "NG"; + // ThreadSafeLogger.Log($"产品 #{finishedProduct.ProductID} 检测结果: {finalResult}"); + + // if (IsDetectionRunning) + // { + // OnDetectionCompleted?.Invoke(null, new DetectionResultEventArgs(isOk)); + // } + + // try + // { + // // 确保完成的产品被完全释放 + // finishedProduct.Dispose(); + // } + // catch (Exception ex) + // { + // ThreadSafeLogger.Log($"[ERROR] 释放产品 #{finishedProduct.ProductID} 资源时出错: {ex.Message}"); + // } + // } + // } + // } + //} + + // 图像回调方法现在极其简单 + private static void OnCameraImageAcquired(HikvisionCamera sender, Bitmap bmp) + { + Bitmap bmpForDisplay = null; + Bitmap bmpForProcessing = null; + + try + { + // 1. 为“显示”和“处理”创建两个完全独立的深克隆副本 + bmpForDisplay = DeepCloneBitmap(bmp, "Display"); + bmpForProcessing = DeepCloneBitmap(bmp, "Processing"); + } + finally + { + // 2.无论克隆成功与否,都必须立即释放事件传递过来的原始bmp,防止泄漏。 + bmp?.Dispose(); + } + // 分支 A: 将用于显示的副本发送到对应的UI窗口 + if (bmpForDisplay != null && OriginalImageDisplays.TryGetValue(sender.Name, out var displayWindow)) + { + // displayWindow.UpdateImage 会处理线程安全问题 + displayWindow.UpdateImage(bmpForDisplay); + } + else + { + // 如果没有对应的显示窗口,或克隆失败,必须释放为显示创建的副本 + bmpForDisplay?.Dispose(); + } + // 分支 B: 将用于处理的副本发送到检测协调器的后台队列 + if (bmpForProcessing != null) + { + // bmpForProcessing 的所有权在这里被转移给了协调器 + DetectionCoordinator.EnqueueImage(sender.CameraIndex, bmpForProcessing); + } + //// 深度克隆图像以确保线程安全 + //Bitmap bmpForProcessing = DeepCloneBitmap(bmp, "Processing"); + //bmp?.Dispose(); // 立即释放原始图 + + //// 直接将图像和相机编号交给协调器,无需任何本地处理 + //DetectionCoordinator.EnqueueImage(sender.CameraIndex, bmpForProcessing); + } + // 事件处理器 + private static void Processor_OnProcessingCompleted(object sender, ProcessingCompletedEventArgs e) + { + + // 1. 找到与此相机匹配的相机名称 + var cameraEntry = ActiveCameras.FirstOrDefault(kvp => kvp.Value.CameraIndex == e.CameraIndex); + if (cameraEntry.Key == null) + { + e.Dispose(); // 如果找不到接收者,必须释放事件参数中的图像 + return; + } + // 2. 找到此相机的结果显示窗口 + if (ResultImageDisplays.TryGetValue(cameraEntry.Key, out var resultDisplay)) + { + var bmp = ConvertSKImageToBitmap(e.ResultImage); + if (bmp != null) + { + // UpdateImage 会负责克隆并显示,所以这里传递 bmp 即可 + resultDisplay.UpdateImage(bmp); + } + } + else + { + // 如果找到了相机但没有对应的结果窗口,也要释放图像 + e.Dispose(); + } + + } + + /// + /// 【将 SkiaSharp.SKImage 安全地转换为 System.Drawing.Bitmap。 + /// + private static Bitmap ConvertSKImageToBitmap(SKImage skImage) + { + if (skImage == null) return null; + + try + { + // SKImage -> SKBitmap -> System.Drawing.Bitmap + using (var skBitmap = SKBitmap.FromImage(skImage)) + { + // SKBitmap.ToBitmap() 会创建一个新的 Bitmap 对象 + return SKBitmapToGdiBitmapFast(skBitmap); + } + } + catch (Exception ex) + { + ThreadSafeLogger.Log($"[错误] SKImage to Bitmap 转换失败: {ex.Message}"); + return null; + } + } + public static Bitmap SKBitmapToGdiBitmapFast(SKBitmap skBitmap) + { + if (skBitmap == null) throw new ArgumentNullException(nameof(skBitmap)); + if (skBitmap.ColorType != SKColorType.Bgra8888 || skBitmap.AlphaType != SKAlphaType.Premul) + throw new ArgumentException("skBitmap must be Bgra8888 + Premul for the fast path."); + + int w = skBitmap.Width; + int h = skBitmap.Height; + + Bitmap bmp = new Bitmap(w, h, PixelFormat.Format32bppArgb); + var rect = new Rectangle(0, 0, w, h); + var bmpData = bmp.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); + try + { + IntPtr srcPtr = skBitmap.GetPixels(); + int srcRowBytes = skBitmap.RowBytes; + int dstRowBytes = bmpData.Stride; + int copyBytesPerRow = Math.Min(srcRowBytes, dstRowBytes); + + byte[] row = new byte[copyBytesPerRow]; // 复用同一行缓冲区,避免每行分配 + for (int y = 0; y < h; y++) + { + IntPtr s = IntPtr.Add(srcPtr, y * srcRowBytes); + IntPtr d = IntPtr.Add(bmpData.Scan0, y * dstRowBytes); + + Marshal.Copy(s, row, 0, copyBytesPerRow); + Marshal.Copy(row, 0, d, copyBytesPerRow); + } + } + finally + { + bmp.UnlockBits(bmpData); + } + + return bmp; + } + /// + /// 对Bitmap进行真正的深度克隆,确保内存完全独立。 + /// 这是解决跨线程GDI+问题的最可靠方法。 + /// + /// 源Bitmap对象。 + /// 一个与源图像在内存上完全独立的全新Bitmap对象。 + private static Bitmap DeepCloneBitmap(Bitmap source, string cloneFor) + { + if (source == null) return null; + + // 创建一个新的Bitmap对象,具有与源相同的尺寸和像素格式 + Bitmap clone = new Bitmap(source.Width, source.Height, source.PixelFormat); + + // 如果有调色板,复制调色板 + if (source.Palette.Entries.Length > 0) + { + clone.Palette = source.Palette; + } + + // 锁定源和目标Bitmap的内存区域 + var rect = new Rectangle(0, 0, source.Width, source.Height); + BitmapData sourceData = null; //source.LockBits(rect, ImageLockMode.ReadOnly, source.PixelFormat); + BitmapData cloneData = null;//clone.LockBits(rect, ImageLockMode.WriteOnly, clone.PixelFormat); + + try + { + sourceData = source.LockBits(rect, ImageLockMode.ReadOnly, source.PixelFormat); + cloneData = clone.LockBits(rect, ImageLockMode.WriteOnly, clone.PixelFormat); + // 计算需要拷贝的字节数 + int byteCount = Math.Abs(sourceData.Stride) * source.Height; + byte[] buffer = new byte[byteCount]; + + // 从源图像拷贝数据到字节数组 + Marshal.Copy(sourceData.Scan0, buffer, 0, byteCount); + + // 从字节数组拷贝数据到目标图像 + Marshal.Copy(buffer, 0, cloneData.Scan0, byteCount); + } + catch (Exception ex) + { + ThreadSafeLogger.Log($"[克隆错误] 在 DeepCloneBitmap ({cloneFor}) 中发生异常: {ex.Message}"); + // 如果发生错误,确保返回null,并且释放可能已经创建的clone对象 + clone?.Dispose(); + return null; + } + finally + { + // 确保即使在发生错误时也能尝试解锁 + if (sourceData != null) + { + source.UnlockBits(sourceData); + } + if (cloneData != null) + { + clone.UnlockBits(cloneData); + } + //ThreadSafeLogger.Log($"[克隆完成] 解锁并完成克隆 ({cloneFor})."); + } + + return clone; + } + + // 触发日志事件的辅助方法 + //public static void Log(string message) + //{ + // string formattedMessage = $"[{DateTime.Now:HH:mm:ss.fff}] {message}"; + + // // 1. 触发事件,更新UI + // OnLogMessage?.Invoke(formattedMessage); + + // // 2. 【关键修改】在写入文件前,先获取锁。 + // // lock 语句块确保了花括号内的代码在同一时间只能被一个线程执行。 + // // 如果另一个线程也想执行这段代码,它必须等待前一个线程执行完毕并释放锁。 + // lock (_logLock) + // { + // try + // { + // _logFileWriter?.WriteLine(formattedMessage); + // } + // catch (Exception) + // { + // // 即使有锁,也保留try-catch以防万一(如磁盘满了等IO问题)。 + // // 可以在这里决定是否要在UI上显示警告。 + // } + // } + //} + + } + +} diff --git a/Check.Main/Camera/CameraProcessor.cs b/Check.Main/Camera/CameraProcessor.cs new file mode 100644 index 0000000..2386223 --- /dev/null +++ b/Check.Main/Camera/CameraProcessor.cs @@ -0,0 +1,211 @@ +using Check.Main.Common; +using Check.Main.Infer; +using SkiaSharp; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Drawing.Imaging; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using YoloDotNet.Extensions; + +namespace Check.Main.Camera +{ + public class CameraProcessor : IDisposable + { + private readonly int _cameraIndex; + private readonly int _modeId; + // private readonly ModelSettings _model; + private readonly BlockingCollection _imageQueue = new BlockingCollection(); + private readonly Thread _workerThread; + private volatile bool _isRunning = false; + private long _imageCounter = 0; + private readonly object _counterLock = new object(); // 用于线程安全地重置计数器 + + public event EventHandler OnProcessingCompleted; + + + public CameraProcessor(int cameraIndex, int modelId)//, ModelSettings model + { + _cameraIndex = cameraIndex; + _modeId = modelId; + //_model = model; + _workerThread = new Thread(ProcessQueue) { IsBackground = true, Name = $"Cam_{_cameraIndex}_Processor" }; + } + + public void Start() + { + _isRunning = true; + _workerThread.Start(); + } + + public void EnqueueImage(Bitmap bmp) + { + if (!_isRunning) + { + bmp?.Dispose(); + return; + } + _imageCounter++; + _imageQueue.Add(new ImageData(_imageCounter, _cameraIndex, bmp)); + } + + private void ProcessQueue() + { + // 从模型管理器获取此线程专属的YOLO模型 + var yoloModel = YoloModelManager.GetModel(_modeId); + if (yoloModel == null) + { + ThreadSafeLogger.Log($"[错误] 相机 #{_modeId} 无法获取对应的YOLO模型,处理线程已中止。"); + return; // 如果没有模型,此线程无法工作 + } + while (_isRunning) + { + try + { + // 阻塞式地从队列中取出图像,如果队列为空则等待 + ImageData data = _imageQueue.Take(); + using (data) + { + //SKImage resultSkImage = null; // 用于存储最终绘制好结果的图像 + + using (var skImage = ConvertBitmapToSKImage(data.Image)) // 转换图像格式并管理其生命周期 + { + if (skImage == null) continue; + var predictions = yoloModel.RunObjectDetection(skImage); + // 模拟模型处理 + //Thread.Sleep(50); // 模拟耗时 + //bool isOk = new Random().NextDouble() > 0.1; + //string result = isOk ? "OK" : "NG"; + + string result = predictions.Any() ? "NG" : "OK"; + ThreadSafeLogger.Log($"相机 #{_cameraIndex} 处理产品 #{data.ProductId},检测到 {predictions.Count} 个目标,结果: {result}"); + // 将处理结果交给协调器进行组装 + DetectionCoordinator.AssembleProduct(data, result); + + if (OnProcessingCompleted != null) + { + using (var resultSkImage = skImage.Draw(predictions)) + { + // 4. 触发事件,将绘制好的 resultSkImage 传递出去 + // 所有权在这里被转移 + OnProcessingCompleted?.Invoke(this, new ProcessingCompletedEventArgs( + _cameraIndex, + data.ProductId, + resultSkImage + )); + } + } + } + + } + } + catch (InvalidOperationException) + { + // 当调用 Stop 时,会 CompleteAdding 队列,Take 会抛出此异常,是正常退出流程 + break; + } + catch (Exception ex) + { + ThreadSafeLogger.Log($"[ERROR] 相机 #{_cameraIndex} 处理线程异常: {ex.Message}"); + } + } + } + /// + /// 将 System.Drawing.Bitmap 安全地转换为 SkiaSharp.SKImage。 + /// + private SKImage ConvertBitmapToSKImage(Bitmap bitmap) + { + if (bitmap == null) return null; + try + { + // 使用 using 确保 SKBitmap 被正确释放 + using (var skBitmap = ToSKBitmapFast(bitmap)) + { + return SKImage.FromBitmap(skBitmap); + } + } + catch (Exception ex) + { + ThreadSafeLogger.Log($"[错误] Bitmap to SKImage 转换失败: {ex.Message}"); + return null; + } + } + public static SKBitmap ToSKBitmapFast(Bitmap bitmap) + { + // 确保是 32bppArgb(BGRA 内存布局) + Bitmap src = bitmap; + if (bitmap.PixelFormat != PixelFormat.Format32bppArgb) + { + src = new Bitmap(bitmap.Width, bitmap.Height, PixelFormat.Format32bppArgb); + using (Graphics g = Graphics.FromImage(src)) + { + g.DrawImage(bitmap, 0, 0, bitmap.Width, bitmap.Height); + } + } + + var rect = new Rectangle(0, 0, src.Width, src.Height); + var bmpData = src.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); + try + { + var info = new SKImageInfo(src.Width, src.Height, SKColorType.Bgra8888, SKAlphaType.Premul); + var skBitmap = new SKBitmap(info); + + IntPtr destPtr = skBitmap.GetPixels(); // 目标内存 + IntPtr srcRowPtr = bmpData.Scan0; // 源行首 + int srcStride = bmpData.Stride; + int destRowBytes = skBitmap.RowBytes; + int copyBytesPerRow = Math.Min(srcStride, destRowBytes); + + // 使用一次分配的缓冲区并用 Marshal.Copy 行拷贝(不分配每行) + byte[] row = new byte[copyBytesPerRow]; + for (int y = 0; y < src.Height; y++) + { + IntPtr s = IntPtr.Add(bmpData.Scan0, y * srcStride); + IntPtr d = IntPtr.Add(destPtr, y * destRowBytes); + + Marshal.Copy(s, row, 0, copyBytesPerRow); + Marshal.Copy(row, 0, d, copyBytesPerRow); + } + + return skBitmap; + } + finally + { + src.UnlockBits(bmpData); + if (!ReferenceEquals(src, bitmap)) + { + src.Dispose(); + } + } + } + public void Stop() + { + _isRunning = false; + // 解除阻塞,让线程可以检查 _isRunning 标志并退出 + _imageQueue.CompleteAdding(); + _workerThread.Join(500); // 等待线程结束 + } + /// + /// 线程安全地重置该相机的图像计数器。 + /// + public void ResetCounter() + { + lock (_counterLock) + { + _imageCounter = 0; + } + } + // 别忘了在 DetectionCoordinator 中添加一个辅助方法来获取处理器 + + + public void Dispose() + { + Stop(); + _imageQueue.Dispose(); + } + } + +} diff --git a/Check.Main/Camera/CameraSettings.cs b/Check.Main/Camera/CameraSettings.cs new file mode 100644 index 0000000..054a4f0 --- /dev/null +++ b/Check.Main/Camera/CameraSettings.cs @@ -0,0 +1,182 @@ +using Check.Main.Common; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing.Design; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms.Design; + +namespace Check.Main.Camera +{ + // 相机触发方式枚举 + public enum TriggerModeType + { + [Description("连续采集")] + Continuous, + [Description("软件触发")] + Software, + [Description("硬件触发")] + Hardware + } + public enum CheckType + { + [Description("传统算法")] + Traditional, + [Description("深度学习")] + DeepLearning + } + + /// + /// 相机配置信息类,用于PropertyGrid显示和编辑 + /// + public class CameraSettings : INotifyPropertyChanged, ICloneable + { + // 1. 实现 INotifyPropertyChanged 接口所要求的事件 + public event PropertyChangedEventHandler PropertyChanged; + + private int _cameraIndex = 0; + private string _name = "Camera-1"; + private string _ipAddress = "192.168.1.100"; + private string _ipDeviceAddress = "192.168.1.101"; + private TriggerModeType _triggerMode = TriggerModeType.Continuous; + private bool _isEnabled = true; + private CheckType _checkType = CheckType.DeepLearning; + private int _modelID = 0; + + [Category("基本信息"), DisplayName("相机编号"), Description("相机的唯一标识符,用于与模型编号对应。")] + public int CameraIndex + { + get => _cameraIndex; + set + { + if (_cameraIndex != value) + { + _cameraIndex = value; + OnPropertyChanged(); + } + } + } + [Category("基本信息"), DisplayName("相机名称"), Description("给相机起一个唯一的别名")] + public string Name + { + get => _name; + set + { + // 2. 在setter中检查值是否真的改变了 + if (_name != value) + { + _name = value; + // 3. 如果改变了,就调用通知方法,广播“Name”属性已变更的消息 + OnPropertyChanged(); + } + } + } + + [Category("网络信息"), DisplayName("相机IP地址"), Description("相机的IP地址(GigE相机需要)")] + public string IPAddress + { + get => _ipAddress; + set + { + if (_ipAddress != value) + { + _ipAddress = value; + OnPropertyChanged(); + } + } + } + + [Category("网络信息"), DisplayName("上位机IP地址"), Description("相机对应的上位机的IP地址(GigE相机需要)")] + public string IPDeviceAddress + { + get => _ipDeviceAddress; + set + { + if (_ipDeviceAddress != value) + { + _ipDeviceAddress = value; + OnPropertyChanged(); + } + } + } + + [Category("采集控制"), DisplayName("触发模式"), Description("设置相机的图像采集触发方式")] + [TypeConverter(typeof(EnumDescriptionTypeConverter))] + public TriggerModeType TriggerMode + { + get => _triggerMode; + set + { + if (_triggerMode != value) + { + _triggerMode = value; + OnPropertyChanged(); + } + } + } + + [Category("采集控制"), DisplayName("是否启用"), Description("是否在程序启动时初始化并使用此相机")] + public bool IsEnabled + { + get => _isEnabled; + set + { + if (_isEnabled != value) + { + _isEnabled = value; + OnPropertyChanged(); + } + } + } + + [Category("检测配置"), DisplayName("检测类型"), Description("使用传统算法或深度学习")] + [TypeConverter(typeof(EnumDescriptionTypeConverter))] + public CheckType CheckType + { + get => _checkType; + set + { + if (_checkType != value) + { + _checkType = value; + OnPropertyChanged(); + } + } + } + + [Category("基本信息"), DisplayName("模型编号"), Description("相机调用的模型编号")] + [TypeConverter(typeof(ModelSelectionConverter))] + public int ModelID + { + get => _modelID; + set + { + if (_modelID != value) + { + _modelID = value; + OnPropertyChanged(); + } + } + } + + /// + /// 4. 触发 PropertyChanged 事件的辅助方法 + /// [CallerMemberName] 特性是一个“语法糖”,它会自动获取调用此方法的属性的名称。 + /// 例如,在Name属性的setter中调用OnPropertyChanged(),C#编译器会自动传入"Name"作为参数。 + /// + protected void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + public object Clone() + { + // MemberwiseClone() 会创建一个新对象,并将当前对象的所有非静态字段的值 + // 复制到新对象中。对于值类型,这是值的拷贝;对于引用类型,这是引用的拷贝。 + // 在本类中,这已经足够了。 + return this.MemberwiseClone(); + } + } +} diff --git a/Check.Main/Camera/HikvisionCamera.cs b/Check.Main/Camera/HikvisionCamera.cs new file mode 100644 index 0000000..79e7779 --- /dev/null +++ b/Check.Main/Camera/HikvisionCamera.cs @@ -0,0 +1,502 @@ +using MvCamCtrl.NET; +using Sunny.UI; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Check.Main.Camera +{ + public class HikvisionCamera : IDisposable + { + [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)] + private static extern void CopyMemory(IntPtr dest, IntPtr src, uint count); + // 事件委托 + public delegate void ImageAcquiredEventHandler(HikvisionCamera sender, Bitmap bmp); + // public delegate void ImageAcquiredEventHandler(object sender, Bitmap bmp); + public delegate void CameraMessageEventHandler(object sender, string message, int errorCode = 0); + + // 事件 + public event ImageAcquiredEventHandler ImageAcquired; + public event CameraMessageEventHandler CameraMessage; + + // 私有成员变量 + private MyCamera m_MyCamera; + private MyCamera.MV_CC_DEVICE_INFO_LIST m_stDeviceList; + private bool m_bGrabbing = false; + private Thread m_hReceiveThread = null; + + private Bitmap m_bitmap = null; + private IntPtr m_ConvertDstBuf = IntPtr.Zero; + private uint m_nConvertDstBufLen = 0; + public string Name { get; set; } + + /// + /// 由外部逻辑分配的、唯一的相机软件编号。 + /// 主要用作图像路由和与逻辑处理器匹配的键。 + /// + public int CameraIndex { get; set; } + + /// + /// 相机是否已经打开 + /// + public bool IsOpen { get; private set; } = false; + + public TriggerModeType TriggerMode { get; internal set; } // internal set 保证只有 CameraManager 能设置它 + + + /// + /// 相机是否正在采集 + /// + public bool IsGrabbing => m_bGrabbing; + + public HikvisionCamera() + { + // 初始化SDK + MyCamera.MV_CC_Initialize_NET(); + } + + /// + /// 查找所有可用的相机设备 + /// + /// 设备名称列表 + public List FindDevices() + { + var deviceList = new List(); + m_stDeviceList = new MyCamera.MV_CC_DEVICE_INFO_LIST(); + int nRet = MyCamera.MV_CC_EnumDevices_NET(MyCamera.MV_GIGE_DEVICE | MyCamera.MV_USB_DEVICE, ref m_stDeviceList); + if (nRet != MyCamera.MV_OK) + { + OnCameraMessage("设备枚举失败!", nRet); + return deviceList; + } + + for (int i = 0; i < m_stDeviceList.nDeviceNum; i++) + { + var device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_stDeviceList.pDeviceInfo[i], typeof(MyCamera.MV_CC_DEVICE_INFO)); + if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE) + { + var gigeInfo = (MyCamera.MV_GIGE_DEVICE_INFO_EX)MyCamera.ByteToStruct(device.SpecialInfo.stGigEInfo, typeof(MyCamera.MV_GIGE_DEVICE_INFO_EX)); + if (!string.IsNullOrEmpty(Encoding.Default.GetString(gigeInfo.chUserDefinedName).TrimEnd('\0'))) + deviceList.Add("GEV: " + gigeInfo.chUserDefinedName + " (" + gigeInfo.chSerialNumber + ")"); + else + deviceList.Add("GEV: " + gigeInfo.chManufacturerName + " " + gigeInfo.chModelName + " (" + gigeInfo.chSerialNumber + ")"); + } + else if (device.nTLayerType == MyCamera.MV_USB_DEVICE) + { + var usbInfo = (MyCamera.MV_USB3_DEVICE_INFO_EX)MyCamera.ByteToStruct(device.SpecialInfo.stUsb3VInfo, typeof(MyCamera.MV_USB3_DEVICE_INFO_EX)); + if (!string.IsNullOrEmpty(Encoding.Default.GetString(usbInfo.chUserDefinedName).TrimEnd('\0'))) + deviceList.Add("U3V: " + usbInfo.chUserDefinedName + " (" + usbInfo.chSerialNumber + ")"); + else + deviceList.Add("U3V: " + usbInfo.chManufacturerName + " " + usbInfo.chModelName + " (" + usbInfo.chSerialNumber + ")"); + } + } + return deviceList; + } + + /// + /// 根据索引打开相机 + /// + /// 设备索引 + /// 成功返回true,否则返回false + public bool Open(CameraSettings camConfig) + { + string ipCam = ""; + string ipDevice = ""; + FindDevices(); + if (camConfig.IsEnabled == true) + { + ipCam = camConfig.IPAddress; + ipDevice = camConfig.IPDeviceAddress; + } + try + { + if (m_stDeviceList.nDeviceNum == 0 || string.IsNullOrEmpty(camConfig.IPAddress)) + { + OnCameraMessage("没有找到设备或索引无效。", -1); + return false; + } + + if (IsOpen) + { + OnCameraMessage("相机已经打开。", 0); + return true; + } + MyCamera.MV_CC_DEVICE_INFO device = new MyCamera.MV_CC_DEVICE_INFO(); + device.nTLayerType = MyCamera.MV_GIGE_DEVICE; + MyCamera.MV_GIGE_DEVICE_INFO stGigEDev = new MyCamera.MV_GIGE_DEVICE_INFO(); + var parts = ipCam.Split('.'); + int nIp1 = Convert.ToInt32(parts[0]); + int nIp2 = Convert.ToInt32(parts[1]); + int nIp3 = Convert.ToInt32(parts[2]); + int nIp4 = Convert.ToInt32(parts[3]); + stGigEDev.nCurrentIp = (uint)((nIp1 << 24) | (nIp2 << 16) | (nIp3 << 8) | nIp4); + + parts = ipDevice.Split('.'); + nIp1 = Convert.ToInt32(parts[0]); + nIp2 = Convert.ToInt32(parts[1]); + nIp3 = Convert.ToInt32(parts[2]); + nIp4 = Convert.ToInt32(parts[3]); + stGigEDev.nNetExport = (uint)((nIp1 << 24) | (nIp2 << 16) | (nIp3 << 8) | nIp4); + IntPtr stGigeInfoPtr = Marshal.AllocHGlobal(216); + Marshal.StructureToPtr(stGigEDev, stGigeInfoPtr, false); + device.SpecialInfo.stGigEInfo = new Byte[540]; + Marshal.Copy(stGigeInfoPtr, device.SpecialInfo.stGigEInfo, 0, 540); + //释放内存空间 + Marshal.FreeHGlobal(stGigeInfoPtr); + + //var device = (MyCamera.MV_CC_DEVICE_INFO)Marshal.PtrToStructure(m_stDeviceList.pDeviceInfo[index], typeof(MyCamera.MV_CC_DEVICE_INFO)); + m_MyCamera = new MyCamera(); + int nRet = m_MyCamera.MV_CC_CreateDevice_NET(ref device); + if (nRet != MyCamera.MV_OK) + { + OnCameraMessage("创建设备句柄失败!", nRet); + return false; + } + + nRet = m_MyCamera.MV_CC_OpenDevice_NET(); + if (nRet != MyCamera.MV_OK) + { + OnCameraMessage("打开设备失败!", nRet); + m_MyCamera.MV_CC_DestroyDevice_NET(); + return false; + } + + // 探测网络最佳包大小(只对GigE相机有效) + if (device.nTLayerType == MyCamera.MV_GIGE_DEVICE) + { + int nPacketSize = m_MyCamera.MV_CC_GetOptimalPacketSize_NET(); + if (nPacketSize > 0) + { + m_MyCamera.MV_CC_SetIntValueEx_NET("GevSCPSPacketSize", nPacketSize); + } + } + + // 默认设置为连续模式 + SetContinuousMode(); + + IsOpen = true; + OnCameraMessage("相机打开成功。", 0); + return true; + } + catch (Exception ex) + { + OnCameraMessage("相机打开失败。"+ ex.ToString(), 0); + return false; + } + + } + + /// + /// 关闭相机 + /// + public void Close() + { + if (!IsOpen) return; + + if (m_bGrabbing) + { + StopGrabbing(); + } + + m_MyCamera.MV_CC_CloseDevice_NET(); + m_MyCamera.MV_CC_DestroyDevice_NET(); + + IsOpen = false; + m_MyCamera = null; + OnCameraMessage("相机已关闭。", 0); + } + + /// + /// 开始采集图像 + /// + /// 成功返回true + public bool StartGrabbing() + { + if (!IsOpen || m_bGrabbing) + { + OnCameraMessage(m_bGrabbing ? "已经在采集中。" : "相机未打开。", -1); + return false; + } + + // 取图前的必要操作 + if (NecessaryOperBeforeGrab() != MyCamera.MV_OK) + { + return false; + } + + int nRet = m_MyCamera.MV_CC_StartGrabbing_NET(); + if (nRet != MyCamera.MV_OK) + { + OnCameraMessage("开始采集失败!", nRet); + return false; + } + + m_bGrabbing = true; + m_hReceiveThread = new Thread(ReceiveThreadProcess); + m_hReceiveThread.IsBackground = true; + m_hReceiveThread.Start(); + + OnCameraMessage("开始采集。", 0); + return true; + } + + /// + /// 停止采集图像 + /// + public void StopGrabbing() + { + if (!m_bGrabbing) return; + + m_bGrabbing = false; + if (m_hReceiveThread != null && m_hReceiveThread.IsAlive) + { + m_hReceiveThread.Join(1000); // 等待线程退出 + } + + int nRet = m_MyCamera.MV_CC_StopGrabbing_NET(); + if (nRet != MyCamera.MV_OK) + { + OnCameraMessage("停止采集失败!", nRet); + } + + OnCameraMessage("停止采集。", 0); + } + + /// + /// 设置为连续采集模式 + /// + public void SetContinuousMode() + { + if (!IsOpen) return; + m_MyCamera.MV_CC_SetEnumValue_NET("AcquisitionMode", (uint)MyCamera.MV_CAM_ACQUISITION_MODE.MV_ACQ_MODE_CONTINUOUS); + m_MyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_OFF); + OnCameraMessage("已设置为连续模式。", 0); + } + + /// + /// 设置为触发模式 + /// + /// true为软触发, false为硬触发(Line0) + public void SetTriggerMode(bool isSoftwareTrigger) + { + if (!IsOpen) return; + + m_MyCamera.MV_CC_SetEnumValue_NET("AcquisitionMode", (uint)MyCamera.MV_CAM_ACQUISITION_MODE.MV_ACQ_MODE_CONTINUOUS); // 触发模式也需要在Continuous模式下 + m_MyCamera.MV_CC_SetEnumValue_NET("TriggerMode", (uint)MyCamera.MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON); + + if (isSoftwareTrigger) + { + m_MyCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE); + OnCameraMessage("已设置为软触发模式。", 0); + } + else + { + m_MyCamera.MV_CC_SetEnumValue_NET("TriggerSource", (uint)MyCamera.MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_LINE0); + OnCameraMessage("已设置为硬触发(Line0)模式。", 0); + } + } + + /// + /// 执行一次软触发 + /// + /// 成功返回true + public bool SoftwareTrigger() + { + if (!IsOpen || !m_bGrabbing) + { + OnCameraMessage("请先打开相机并开始采集。", -1); + return false; + } + + int nRet = m_MyCamera.MV_CC_SetCommandValue_NET("TriggerSoftware"); + if (nRet != MyCamera.MV_OK) + { + OnCameraMessage("软触发失败!", nRet); + return false; + } + return true; + } + + /// + /// 图像接收线程 + /// + private void ReceiveThreadProcess() + { + MyCamera.MV_FRAME_OUT stFrameInfo = new MyCamera.MV_FRAME_OUT(); + var stConvertParam = new MyCamera.MV_PIXEL_CONVERT_PARAM(); + + while (m_bGrabbing) + { + int nRet = m_MyCamera.MV_CC_GetImageBuffer_NET(ref stFrameInfo, 1000); + if (nRet == MyCamera.MV_OK) + { + Bitmap bmpForEvent = null; // 在 try 外部声明 + try + { + // 初始化转换参数 + stConvertParam.nWidth = stFrameInfo.stFrameInfo.nWidth; + stConvertParam.nHeight = stFrameInfo.stFrameInfo.nHeight; + stConvertParam.pSrcData = stFrameInfo.pBufAddr; + stConvertParam.nSrcDataLen = stFrameInfo.stFrameInfo.nFrameLen; + stConvertParam.enSrcPixelType = stFrameInfo.stFrameInfo.enPixelType; + stConvertParam.pDstBuffer = m_ConvertDstBuf; + stConvertParam.nDstBufferSize = m_nConvertDstBufLen; + + // 创建用于事件的Bitmap,它的格式与类成员m_bitmap一致 + bmpForEvent = new Bitmap((int)stConvertParam.nWidth, (int)stConvertParam.nHeight, m_bitmap.PixelFormat); + + // 判断并设置目标像素格式 + if (bmpForEvent.PixelFormat == PixelFormat.Format8bppIndexed) + { + stConvertParam.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8; + } + else + { + stConvertParam.enDstPixelType = MyCamera.MvGvspPixelType.PixelType_Gvsp_BGR8_Packed; + } + + // 执行像素格式转换 + nRet = m_MyCamera.MV_CC_ConvertPixelType_NET(ref stConvertParam); + if (nRet == MyCamera.MV_OK) + { + // 转换成功,锁定位图内存并拷贝数据 + BitmapData bmpData = bmpForEvent.LockBits(new Rectangle(0, 0, stConvertParam.nWidth, stConvertParam.nHeight), ImageLockMode.WriteOnly, bmpForEvent.PixelFormat); + + // 使用更健壮的逐行拷贝 + int pixelSize = (bmpForEvent.PixelFormat == PixelFormat.Format8bppIndexed) ? 1 : 3; + for (int i = 0; i < bmpData.Height; ++i) + { + IntPtr pDst = new IntPtr(bmpData.Scan0.ToInt64() + i * bmpData.Stride); + IntPtr pSrc = new IntPtr(m_ConvertDstBuf.ToInt64() + i * stConvertParam.nWidth * pixelSize); + CopyMemory(pDst, pSrc, (uint)(stConvertParam.nWidth * pixelSize)); + } + bmpForEvent.UnlockBits(bmpData); + + // 触发图像采集事件,转移 bmpForEvent 的所有权 + ImageAcquired?.Invoke(this, bmpForEvent); + + // 【关键】所有权已转移,将本地引用设为null,防止它在finally块中被错误地释放 + bmpForEvent = null; + } + // 如果转换失败,不执行任何操作,让 finally 块来处理 bmpForEvent 的释放 + } + finally + { + // 【关键】如果 bmpForEvent 不为 null,意味着它被成功创建, + // 但没有被成功传递给事件处理器(可能因为转换失败或发生其他异常), + // 在这里必须将其释放。 + bmpForEvent?.Dispose(); + + // 无论成功与否,都必须释放相机SDK的内部图像缓存 + m_MyCamera.MV_CC_FreeImageBuffer_NET(ref stFrameInfo); + } + } + else + { + // 超时,继续等待 + Thread.Sleep(5); + } + } + } + + /// + /// 取图前的内存和参数准备 + /// + private int NecessaryOperBeforeGrab() + { + var stWidth = new MyCamera.MVCC_INTVALUE_EX(); + int nRet = m_MyCamera.MV_CC_GetIntValueEx_NET("Width", ref stWidth); + if (nRet != MyCamera.MV_OK) { OnCameraMessage("获取宽度失败!", nRet); return nRet; } + + var stHeight = new MyCamera.MVCC_INTVALUE_EX(); + nRet = m_MyCamera.MV_CC_GetIntValueEx_NET("Height", ref stHeight); + if (nRet != MyCamera.MV_OK) { OnCameraMessage("获取高度失败!", nRet); return nRet; } + + var stPixelFormat = new MyCamera.MVCC_ENUMVALUE(); + nRet = m_MyCamera.MV_CC_GetEnumValue_NET("PixelFormat", ref stPixelFormat); + if (nRet != MyCamera.MV_OK) { OnCameraMessage("获取像素格式失败!", nRet); return nRet; } + + PixelFormat bitmapPixelFormat; + // 判断当前像素格式是否为Mono + bool isMono = IsMono(stPixelFormat.nCurValue); + + if (isMono) + { + bitmapPixelFormat = PixelFormat.Format8bppIndexed; + m_nConvertDstBufLen = (uint)(stWidth.nCurValue * stHeight.nCurValue); + } + else + { + bitmapPixelFormat = PixelFormat.Format24bppRgb; + m_nConvertDstBufLen = (uint)(stWidth.nCurValue * stHeight.nCurValue * 3); + } + + // 分配转换后的图像数据缓存 + if (m_ConvertDstBuf != IntPtr.Zero) Marshal.FreeHGlobal(m_ConvertDstBuf); + m_ConvertDstBuf = Marshal.AllocHGlobal((int)m_nConvertDstBufLen); + + // 创建Bitmap对象 + if (m_bitmap != null) m_bitmap.Dispose(); + m_bitmap = new Bitmap((int)stWidth.nCurValue, (int)stHeight.nCurValue, bitmapPixelFormat); + + // 如果是Mono8格式,设置调色板 + if (isMono) + { + ColorPalette palette = m_bitmap.Palette; + for (int i = 0; i < 256; i++) palette.Entries[i] = Color.FromArgb(i, i, i); + m_bitmap.Palette = palette; + } + + return MyCamera.MV_OK; + } + + private bool IsMono(uint enPixelType) + { + switch (enPixelType) + { + case (uint)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono8: + case (uint)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10: + case (uint)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono10_Packed: + case (uint)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12: + case (uint)MyCamera.MvGvspPixelType.PixelType_Gvsp_Mono12_Packed: + return true; + default: + return false; + } + } + + /// + /// 触发相机消息事件 + /// + private void OnCameraMessage(string message, int errorCode = 0) + { + CameraMessage?.Invoke(this, message, errorCode); + } + + /// + /// 释放资源 + /// + public void Dispose() + { + Close(); + if (m_ConvertDstBuf != IntPtr.Zero) + { + Marshal.FreeHGlobal(m_ConvertDstBuf); + m_ConvertDstBuf = IntPtr.Zero; + } + if (m_bitmap != null) + { + m_bitmap.Dispose(); + m_bitmap = null; + } + MyCamera.MV_CC_Finalize_NET(); + } + } +} diff --git a/Check.Main/Check.Main.csproj b/Check.Main/Check.Main.csproj new file mode 100644 index 0000000..d210470 --- /dev/null +++ b/Check.Main/Check.Main.csproj @@ -0,0 +1,37 @@ + + + + WinExe + net8.0-windows + enable + true + enable + + + false + false + + + + + + + + + + + + + + + + + + ..\..\..\HslCommunication-master\HslCommunication.dll + + + C:\Program Files (x86)\MVS\Development\DotNet\win64\MvCameraControl.Net.dll + + + + \ No newline at end of file diff --git a/Check.Main/Common/ConfigurationManager.cs b/Check.Main/Common/ConfigurationManager.cs new file mode 100644 index 0000000..173346a --- /dev/null +++ b/Check.Main/Common/ConfigurationManager.cs @@ -0,0 +1,124 @@ +using Check.Main.Camera; +using Check.Main.Dispatch; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Serialization; + +namespace Check.Main.Common +{ + /// + /// 静态全局配置管理器,作为配置数据的“单一数据源”。 + /// 负责加载、保存和通知配置变更。 + /// + public static class ConfigurationManager + { + // private static readonly string _configFilePath = Path.Combine(Application.StartupPath, "main_config.xml"); + // private static ProcessConfig _currentConfig; + // private static readonly object _lock = new object(); + + // /// + // /// 当配置通过 SaveChanges() 方法保存后触发。 + // /// 其他模块(如 FormControlPanel)可以订阅此事件以响应配置变更。 + // /// + // public static event Action OnConfigurationChanged; + + // /// + // /// 静态构造函数在类首次被访问时自动执行,确保配置只被加载一次。 + // /// + // static ConfigurationManager() + // { + // Load(); + // } + + // /// + // /// 获取对当前配置对象的直接引用。 + // /// PropertyGrid 可以直接绑定到这个对象进行编辑。 + // /// + // /// 当前的 ProcessConfig 实例。 + // public static ProcessConfig GetCurrentConfig() + // { + // return _currentConfig; + // } + + // /// + // /// 从 XML 文件加载配置。如果文件不存在或加载失败,则创建一个新的默认配置。 + // /// + // private static void Load() + // { + // lock (_lock) + // { + // if (File.Exists(_configFilePath)) + // { + // try + // { + // XmlSerializer serializer = new XmlSerializer(typeof(ProcessConfig)); + // using (var fs = new FileStream(_configFilePath, FileMode.Open, FileAccess.Read)) + // { + // _currentConfig = (ProcessConfig)serializer.Deserialize(fs); + // ThreadSafeLogger.Log("主配置文件加载成功。"); + // } + // } + // catch (Exception ex) + // { + // ThreadSafeLogger.Log("加载主配置失败: " + ex.Message + " 将使用默认配置。"); + // _currentConfig = new ProcessConfig(); + // } + // } + // else + // { + // ThreadSafeLogger.Log("未找到主配置文件,将创建新的默认配置。"); + // _currentConfig = new ProcessConfig(); + // } + // } + // } + + // /// + // /// 将当前配置保存到文件,并通知所有监听者配置已更改。 + // /// 这是响应UI变化的推荐方法。 + // /// + // public static void SaveChanges() + // { + // lock (_lock) + // { + // try + // { + // XmlSerializer serializer = new XmlSerializer(typeof(ProcessConfig)); + // using (var fs = new FileStream(_configFilePath, FileMode.Create, FileAccess.Write)) + // { + // serializer.Serialize(fs, _currentConfig); + // } + // } + // catch (Exception ex) + // { + // ThreadSafeLogger.Log("保存主配置失败: " + ex.Message); + // } + // } + + // // 在锁之外触发事件,以避免监听者中的代码导致死锁 + // ThreadSafeLogger.Log("配置已保存,正在触发 OnConfigurationChanged 事件..."); + // OnConfigurationChanged?.Invoke(); + // } + // 不再自己管理配置,而是直接从 ProductManager 获取 + public static ProcessConfig GetCurrentConfig() + { + return ProductManager.CurrentConfig; + } + + public static void SaveChanges() + { + ProductManager.SaveCurrentProductConfig(); + } + + // OnConfigurationChanged 事件现在由 ProductManager.OnProductChanged 替代 + // 如果其他地方还依赖这个事件,可以做一个桥接: + public static event Action OnConfigurationChanged + { + add { ProductManager.OnProductChanged += value; } + remove { ProductManager.OnProductChanged -= value; } + } + } + +} diff --git a/Check.Main/Common/EasyE5Options.cs b/Check.Main/Common/EasyE5Options.cs new file mode 100644 index 0000000..59fb256 --- /dev/null +++ b/Check.Main/Common/EasyE5Options.cs @@ -0,0 +1,236 @@ +using NPOI.SS.Formula.Functions; +using Sunny.UI; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Sockets; +using System.Runtime.CompilerServices; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace Check.Main.Common +{ + /// + /// 汇川 Easy 系列 PLC 客户端 (Modbus TCP) + /// 支持 D/M/X/Y 地址读写,整数、浮点数、字符串 + /// + public class EasyPlcClient : IDisposable + { + private readonly TcpClient _tcpClient = new(); + private NetworkStream _stream; + private ushort _transactionId = 0; + private readonly SemaphoreSlim _lock = new(1, 1); + + private readonly string _ip; + private readonly int _port; + private readonly byte _slaveId; + + public EasyPlcClient(string ip, int port = 502, byte slaveId = 1) + { + _ip = ip; + _port = port; + _slaveId = slaveId; + } + + public async Task ConnectAsync() + { + await _tcpClient.ConnectAsync(_ip, _port); + _stream = _tcpClient.GetStream(); + } + + #region ---- 基础 Modbus ---- + private ushort GetTransactionId() => + unchecked((ushort)Interlocked.Increment(ref Unsafe.As(ref _transactionId))); + + private async Task SendAndReceiveAsync(byte[] pdu, ushort startAddr, ushort length = 1) + { + ushort tid = GetTransactionId(); + ushort lengthField = (ushort)(pdu.Length + 1); + byte[] mbap = { + (byte)(tid >> 8), (byte)tid, + 0x00, 0x00, // Protocol = 0 + (byte)(lengthField >> 8), (byte)lengthField, + _slaveId + }; + + byte[] adu = new byte[mbap.Length + pdu.Length]; + Buffer.BlockCopy(mbap, 0, adu, 0, mbap.Length); + Buffer.BlockCopy(pdu, 0, adu, mbap.Length, pdu.Length); + + await _lock.WaitAsync(); + try + { + await _stream.WriteAsync(adu, 0, adu.Length); + + byte[] header = new byte[7]; + await _stream.ReadAsync(header, 0, 7); + int respLength = (header[4] << 8) + header[5]; + byte[] resp = new byte[respLength - 1]; + await _stream.ReadAsync(resp, 0, resp.Length); + + return resp; + } + finally { _lock.Release(); } + } + #endregion + + #region ---- 地址解析 ---- + private void ParseAddress(string address, out string area, out ushort offset) + { + var letters = Regex.Match(address, @"^[A-Za-z]+").Value.ToUpper(); + var digits = Regex.Match(address, @"\d+").Value; + + if (string.IsNullOrEmpty(letters) || string.IsNullOrEmpty(digits)) + throw new ArgumentException($"地址 {address} 无效"); + + area = letters; + offset = (ushort)(ushort.Parse(digits) - 1); + + // 👉 注意:这里的偏移需根据你的 PLC Modbus 地址表调整 + // 例如 D 区可能是 40001 起,M 区可能是 00001 起 + // 目前假设 D -> Holding Register, M/Y -> Coil, X -> Discrete Input + } + #endregion + + #region ---- 整数读写 ---- + public async Task WriteAsync(string address, int value) + { + ParseAddress(address, out string area, out ushort offset); + + switch (area) + { + case "D": // 写寄存器 + byte[] pdu = { + 0x06, + (byte)(offset >> 8), (byte)offset, + (byte)(value >> 8), (byte)value + }; + await SendAndReceiveAsync(pdu, offset); + break; + + case "M": + case "Y": // 写单线圈 + byte[] coil = { + 0x05, + (byte)(offset >> 8), (byte)offset, + (byte)(value != 0 ? 0xFF : 0x00), 0x00 + }; + await SendAndReceiveAsync(coil, offset); + break; + + default: + throw new NotSupportedException($"写 {area} 区未支持"); + } + } + + public async Task ReadAsync(string address) + { + ParseAddress(address, out string area, out ushort offset); + + switch (area) + { + case "D": // Holding Register + byte[] pdu = { 0x03, (byte)(offset >> 8), (byte)offset, 0x00, 0x01 }; + var resp = await SendAndReceiveAsync(pdu, offset); + return (resp[1] << 8) + resp[2]; + + case "M": + case "Y": // Coils + byte[] pdu1 = { 0x01, (byte)(offset >> 8), (byte)offset, 0x00, 0x01 }; + var resp1 = await SendAndReceiveAsync(pdu1, offset); + return (resp1[2] & 0x01) != 0 ? 1 : 0; + + case "X": // Inputs + byte[] pdu2 = { 0x02, (byte)(offset >> 8), (byte)offset, 0x00, 0x01 }; + var resp2 = await SendAndReceiveAsync(pdu2, offset); + return (resp2[2] & 0x01) != 0 ? 1 : 0; + + default: + throw new NotSupportedException($"读 {area} 区未支持"); + } + } + #endregion + + #region ---- 浮点读写 (2寄存器) ---- + public async Task WriteFloatAsync(string address, float value) + { + ParseAddress(address, out string area, out ushort offset); + if (area != "D") throw new NotSupportedException("浮点仅支持 D 区"); + + byte[] bytes = BitConverter.GetBytes(value); + if (BitConverter.IsLittleEndian) Array.Reverse(bytes); + + byte[] pdu = { + 0x10, + (byte)(offset >> 8), (byte)offset, + 0x00, 0x02, + 0x04, + bytes[0], bytes[1], bytes[2], bytes[3] + }; + await SendAndReceiveAsync(pdu, offset, 2); + } + + public async Task ReadFloatAsync(string address) + { + ParseAddress(address, out string area, out ushort offset); + if (area != "D") throw new NotSupportedException("浮点仅支持 D 区"); + + byte[] pdu = { 0x03, (byte)(offset >> 8), (byte)offset, 0x00, 0x02 }; + var resp = await SendAndReceiveAsync(pdu, offset, 2); + + byte[] data = { resp[1], resp[2], resp[3], resp[4] }; + if (BitConverter.IsLittleEndian) Array.Reverse(data); + + return BitConverter.ToSingle(data, 0); + } + #endregion + + #region ---- 字符串读写 ---- + public async Task WriteStringAsync(string address, string value, int maxLength) + { + ParseAddress(address, out string area, out ushort offset); + if (area != "D") throw new NotSupportedException("字符串仅支持 D 区"); + + byte[] strBytes = Encoding.ASCII.GetBytes(value); + if (strBytes.Length > maxLength) Array.Resize(ref strBytes, maxLength); + + // 每寄存器2字节 + int regCount = (strBytes.Length + 1) / 2; + byte[] data = new byte[regCount * 2]; + Array.Copy(strBytes, data, strBytes.Length); + + byte[] pdu = new byte[7 + data.Length]; + pdu[0] = 0x10; + pdu[1] = (byte)(offset >> 8); pdu[2] = (byte)offset; + pdu[3] = (byte)(regCount >> 8); pdu[4] = (byte)regCount; + pdu[5] = (byte)(data.Length); + Buffer.BlockCopy(data, 0, pdu, 6, data.Length); + + await SendAndReceiveAsync(pdu, offset, (ushort)regCount); + } + + public async Task ReadStringAsync(string address, int length) + { + ParseAddress(address, out string area, out ushort offset); + if (area != "D") throw new NotSupportedException("字符串仅支持 D 区"); + + int regCount = (length + 1) / 2; + byte[] pdu = { 0x03, (byte)(offset >> 8), (byte)offset, (byte)(regCount >> 8), (byte)regCount }; + var resp = await SendAndReceiveAsync(pdu, offset, (ushort)regCount); + + byte[] data = new byte[resp[0]]; + Array.Copy(resp, 1, data, 0, data.Length); + + return Encoding.ASCII.GetString(data).TrimEnd('\0'); + } + #endregion + + public void Dispose() + { + _stream?.Dispose(); + _tcpClient?.Close(); + _lock?.Dispose(); + } + } +} diff --git a/Check.Main/Common/ImageData.cs b/Check.Main/Common/ImageData.cs new file mode 100644 index 0000000..ea5f904 --- /dev/null +++ b/Check.Main/Common/ImageData.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Check.Main.Common +{ + public class ImageData : IDisposable + { + public long ProductId { get; } + public int CameraIndex { get; } + public Bitmap Image { get; } + + public ImageData(long productId, int cameraIndex, Bitmap image) + { + ProductId = productId; + CameraIndex = cameraIndex; + Image = image; + } + public void Dispose() => Image?.Dispose(); + } + + // ProductAssembly.cs - 用于组装一个完整的产品 + public class ProductAssembly : IDisposable + { + public long ProductId { get; } + private readonly int _expectedCameraCount; + // 使用 ConcurrentDictionary 保证线程安全 + private readonly ConcurrentDictionary _results = new ConcurrentDictionary(); + + public ProductAssembly(long productId, int expectedCameraCount) + { + ProductId = productId; + _expectedCameraCount = expectedCameraCount; + } + + // 添加一个相机的检测结果 + public bool AddResult(int cameraIndex, string result) + { + _results.TryAdd(cameraIndex, result); + return _results.Count == _expectedCameraCount; + } + + // 获取最终的聚合结果 + public string GetFinalResult() + { + // 如果任何一个结果包含 "NG",则最终结果为 "NG" + return _results.Values.Any(r => r.Contains("NG")) ? "NG" : "OK"; + } + + public void Dispose() + { + // 目前只持有结果字符串,无需释放资源 + } + } +} diff --git a/Check.Main/Common/ModelSelectionConverter.cs b/Check.Main/Common/ModelSelectionConverter.cs new file mode 100644 index 0000000..ed5845b --- /dev/null +++ b/Check.Main/Common/ModelSelectionConverter.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static System.ComponentModel.TypeConverter; + +namespace Check.Main.Common +{ + /// + /// 一个自定义的 TypeConverter,用于在 PropertyGrid 中为模型选择提供一个下拉列表。 + /// + public class ModelSelectionConverter : Int32Converter // 我们转换的是整数 (ModelId) + { + // 告诉 PropertyGrid,我们支持从一个标准值集合中进行选择 + public override bool GetStandardValuesSupported(ITypeDescriptorContext context) + { + return true; + } + + // 告诉 PropertyGrid,我们只允许用户从列表中选择,不允许手动输入 + public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) + { + return true; + } + + // 这是最核心的方法:提供标准值的列表 + public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) + { + try + { + // 从中央配置管理器获取所有已配置的模型 + var modelSettings = ConfigurationManager.GetCurrentConfig().ModelSettings; + + if (modelSettings == null || modelSettings.Count == 0) + { + // 如果没有模型,返回一个包含默认值 "0"(代表“无”)的列表 + return new StandardValuesCollection(new[] { 0 }); + } + + // 使用LINQ从模型列表中提取所有模型的ID + // .Prepend(0) 在列表开头添加一个 "0",代表“未选择”的选项 + var modelIds = modelSettings.Select(m => m.Id).Prepend(0).ToArray(); + + return new StandardValuesCollection(modelIds); + } + catch + { + // 如果在获取过程中发生任何异常,返回一个安全的默认值 + return new StandardValuesCollection(new[] { 0 }); + } + } + + // --- 为了让下拉列表显示模型名称而不是ID,我们还需要重写以下方法 --- + + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); + } + + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + return destinationType == typeof(string) || base.CanConvertTo(context, destinationType); + } + + // 将模型ID转换为其对应的名称字符串,以便在UI上显示 + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (destinationType == typeof(string) && value is int modelId) + { + if (modelId == 0) + { + return "未选择"; // 对ID为0的特殊处理 + } + + // 查找ID对应的模型名称 + var model = ConfigurationManager.GetCurrentConfig() + .ModelSettings? + .FirstOrDefault(m => m.Id == modelId); + + // 返回 "名称 (ID)" 的格式,更清晰 + return model != null ? $"{model.Name} (ID: {model.Id})" : "未知模型"; + } + return base.ConvertTo(context, culture, value, destinationType); + } + + // 将用户在UI上选择的名称字符串,转换回其对应的模型ID,以便保存 + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value is string displayString) + { + if (displayString == "未选择") + { + return 0; + } + + // 从 "名称 (ID: X)" 格式中解析出ID + if (displayString.Contains("(ID: ") && displayString.EndsWith(")")) + { + var startIndex = displayString.IndexOf("(ID: ") + 5; + var endIndex = displayString.Length - 1; + var idString = displayString.Substring(startIndex, endIndex - startIndex); + if (int.TryParse(idString, out int modelId)) + { + return modelId; + } + } + } + return base.ConvertFrom(context, culture, value); + } + } +} diff --git a/Check.Main/Common/ProcessConfig.cs b/Check.Main/Common/ProcessConfig.cs new file mode 100644 index 0000000..e6c9a1a --- /dev/null +++ b/Check.Main/Common/ProcessConfig.cs @@ -0,0 +1,161 @@ +using Check.Main.Camera; +using Check.Main.Infer; +using Check.Main.UI; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing.Design; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms.Design; + +namespace Check.Main.Common +{ + public class ProcessConfig + { + private string _logPath = Path.Combine(Application.StartupPath, "Logs"); + private List _cameraSettings = new List(); + private List _modelaSettings = new List(); + + + [Category("常规设置"), DisplayName("日志路径"), Description("设置日志文件的保存目录。")] + [Editor(typeof(FolderNameEditor), typeof(UITypeEditor))] // 使用内置的文件夹选择器 + public string LogPath + { + get => _logPath; + set => _logPath = value; + } + + [Category("核心配置"), DisplayName("相机配置"), Description("点击 '...' 按钮来配置所有相机。")] + [Editor(typeof(CameraConfigEditor), typeof(UITypeEditor))] // 【关键】指定使用我们自定义的编辑器 + [TypeConverter(typeof(CameraConfigConverter))] // 【关键】指定使用我们自定义的类型转换器来显示文本 + public List CameraSettings + { + get => _cameraSettings; + set => _cameraSettings = value; + } + + [Category("核心配置"), DisplayName("模型配置"), Description("点击 '...' 按钮来配置所有模型。")] + [Editor(typeof(ModelConfigEditor), typeof(UITypeEditor))] // 【关键】指定使用我们自定义的编辑器 + [TypeConverter(typeof(ModelConfigConverter))] // 【关键】指定使用我们自定义的类型转换器来显示文本 + public List ModelSettings + { + get => _modelaSettings; + set => _modelaSettings = value; + } + } + /// + /// 自定义TypeConverter,用于在PropertyGrid中自定义显示相机列表的文本。 + /// + public class CameraConfigConverter : TypeConverter + { + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + // 声明可以将值转换为字符串 + return destinationType == typeof(string) || base.CanConvertTo(context, destinationType); + } + + public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) + { + // 如果目标类型是字符串,并且值是相机设置列表 + if (destinationType == typeof(string) && value is List list) + { + // 返回自定义的描述性文本 + return $"已配置 {list.Count} 个相机"; + } + return base.ConvertTo(context, culture, value, destinationType); + } + } + + /// + /// 自定义TypeConverter,用于在PropertyGrid中自定义显示相机列表的文本。 + /// + public class ModelConfigConverter : TypeConverter + { + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + // 声明可以将值转换为字符串 + return destinationType == typeof(string) || base.CanConvertTo(context, destinationType); + } + + public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) + { + // 如果目标类型是字符串,并且值是相机设置列表 + if (destinationType == typeof(string) && value is List list) + { + // 返回自定义的描述性文本 + return $"已配置 {list.Count} 个模型"; + } + return base.ConvertTo(context, culture, value, destinationType); + } + } + + + /// + /// 自定义UITypeEditor,用于在点击 "..." 时打开相机配置窗体。 + /// + public class CameraConfigEditor : UITypeEditor + { + // 1. 设置编辑样式为模态对话框 + public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) + { + return UITypeEditorEditStyle.Modal; + } + + // 2. 重写编辑方法 + public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) + { + // 'value' 就是当前属性的值,即 List + var settingsList = value as List; + + // 使用 FrmCamConfig 作为对话框进行编辑 + // 我们需要给 FrmCamConfig 添加一个新的构造函数 + using (var camConfigForm = new FrmCamConfig(settingsList)) + { + // 以对话框形式显示窗体 + if (camConfigForm.ShowDialog() == DialogResult.OK) + { + // 如果用户点击了“确定”,返回修改后的新列表 + return camConfigForm._settingsList; + } + } + + // 如果用户点击了“取消”或直接关闭了窗口,返回原始值,不做任何更改 + return value; + } + } + /// + /// 【新增】自定义UITypeEditor,用于在点击 "..." 时打开模型配置窗体。 + /// + public class ModelConfigEditor : UITypeEditor + { + // 1. 设置编辑样式为模态对话框 + public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) + { + return UITypeEditorEditStyle.Modal; + } + + // 2. 重写编辑方法 + public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) + { + // 'value' 就是当前属性的值,即 List + var settingsList = value as List; + + // 使用ModelEditor 作为对话框进行编辑 + // 我们需要给 FrmCamConfig 添加一个新的构造函数 + using (var modelConfigForm = new ModelListEditor(settingsList)) + { + // 以对话框形式显示窗体 + if (modelConfigForm.ShowDialog() == DialogResult.OK) + { + // 如果用户点击了“确定”,返回修改后的新列表 + return modelConfigForm._settingsList; + } + } + + // 如果用户点击了“取消”或直接关闭了窗口,返回原始值,不做任何更改 + return value; + } + } +} diff --git a/Check.Main/Common/ProcessingCompletedEventArgs.cs b/Check.Main/Common/ProcessingCompletedEventArgs.cs new file mode 100644 index 0000000..ddae0d8 --- /dev/null +++ b/Check.Main/Common/ProcessingCompletedEventArgs.cs @@ -0,0 +1,29 @@ +using SkiaSharp; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Check.Main.Common +{ + public class ProcessingCompletedEventArgs : EventArgs, IDisposable + { + public int CameraIndex { get; } + public long ProductId { get; } + public SKImage ResultImage { get; } // 【修改】携带已绘制好结果的SKImage + + public ProcessingCompletedEventArgs(int cameraIndex, long productId, SKImage resultImage) + { + CameraIndex = cameraIndex; + ProductId = productId; + ResultImage = resultImage; + } + + // 实现 IDisposable 以确保SKImage资源被释放 + public void Dispose() + { + ResultImage?.Dispose(); + } + } +} diff --git a/Check.Main/Common/StaticMethod.cs b/Check.Main/Common/StaticMethod.cs new file mode 100644 index 0000000..bcf6167 --- /dev/null +++ b/Check.Main/Common/StaticMethod.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace Check.Main.Common +{ + /// + /// 一个自定义的类型转换器,用于让PropertyGrid等控件显示枚举成员的Description特性,而不是成员名。 + /// + public class EnumDescriptionTypeConverter : EnumConverter + { + /// + /// 构造函数,传入枚举类型。 + /// + /// 要进行转换的枚举类型。 + public EnumDescriptionTypeConverter(Type type) : base(type) + { + } + + /// + /// 重写此方法,将枚举值转换为其描述文本。 + /// 这是从 "数据" -> "UI显示" 的过程。 + /// + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + // 如果目标类型是字符串,并且我们有一个有效的枚举值 + if (destinationType == typeof(string) && value != null) + { + // 获取枚举值的字段信息 + FieldInfo fi = value.GetType().GetField(value.ToString()); + if (fi != null) + { + // 查找该字段上的DescriptionAttribute + var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); + + // 如果找到了Description特性,就返回它的描述文本;否则,返回基类的默认行为(即成员名) + return ((attributes.Length > 0) && (!String.IsNullOrEmpty(attributes[0].Description))) + ? attributes[0].Description + : value.ToString(); + } + } + + // 对于其他所有情况,使用基类的默认转换逻辑 + return base.ConvertTo(context, culture, value, destinationType); + } + + /// + /// 重写此方法,将描述文本转换回其对应的枚举值。 + /// 这是从 "UI显示" -> "数据" 的过程。 + /// + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + // 如果传入的值是字符串 + if (value is string) + { + // 遍历枚举类型的所有成员 + foreach (FieldInfo fi in EnumType.GetFields()) + { + // 查找该成员上的DescriptionAttribute + var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); + + // 如果找到了Description,并且它的描述文本与传入的字符串匹配 + if ((attributes.Length > 0) && (attributes[0].Description == (string)value)) + { + // 返回这个字段(成员)对应的枚举值 + return Enum.Parse(EnumType, fi.Name); + } + } + } + + // 如果没有找到匹配的描述,或者传入的不是字符串,使用基类的默认转换逻辑 + return base.ConvertFrom(context, culture, value); + } + } +} diff --git a/Check.Main/Common/StatisticsData.cs b/Check.Main/Common/StatisticsData.cs new file mode 100644 index 0000000..fa75e09 --- /dev/null +++ b/Check.Main/Common/StatisticsData.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Check.Main.Common +{ + /// + /// 封装了所有生产统计数据的模型。 + /// 实现了INotifyPropertyChanged,未来可用于数据绑定。 + /// + public class StatisticsData : INotifyPropertyChanged + { + private int _goodCount; + private int _ngCount; + + public int GoodCount + { + get => _goodCount; + private set { _goodCount = value; OnPropertyChanged(nameof(GoodCount)); OnPropertyChanged(nameof(TotalCount)); OnPropertyChanged(nameof(YieldRate)); } + } + + public int NgCount + { + get => _ngCount; + private set { _ngCount = value; OnPropertyChanged(nameof(NgCount)); OnPropertyChanged(nameof(TotalCount)); OnPropertyChanged(nameof(YieldRate)); } + } + + public int TotalCount => GoodCount + NgCount; + + public double YieldRate => TotalCount == 0 ? 0 : (double)GoodCount / TotalCount; + + /// + /// 根据检测结果更新统计数据。 + /// + public void UpdateWithResult(bool isOk) + { + if (isOk) GoodCount++; + else NgCount++; + } + + /// + /// 重置所有统计数据。 + /// + public void Reset() + { + GoodCount = 0; + NgCount = 0; + } + + public event PropertyChangedEventHandler PropertyChanged; + protected void OnPropertyChanged(string propertyName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } + + /// + /// 用于在检测完成事件中传递结果的事件参数。 + /// + public class DetectionResultEventArgs : EventArgs + { + public bool IsOK { get; } + public DetectionResultEventArgs(bool isOk) + { + IsOK = isOk; + } + } +} diff --git a/Check.Main/Common/StatisticsExporter.cs b/Check.Main/Common/StatisticsExporter.cs new file mode 100644 index 0000000..1bc3954 --- /dev/null +++ b/Check.Main/Common/StatisticsExporter.cs @@ -0,0 +1,82 @@ +using Check.Main.Camera; +using NPOI.SS.UserModel; +using NPOI.XSSF.UserModel; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Check.Main.Common +{ + public static class StatisticsExporter + { + /// + /// 将给定的统计数据导出到指定的Excel文件路径。 + /// + /// 要导出的统计数据对象。 + /// 自定义的文件名部分(如 "Reset" 或 "Shutdown")。 + public static void ExportToExcel(StatisticsData data, string customFileName) + { + if (data.TotalCount == 0) return; // 如果没有数据,则不导出 + + try + { + string directory = Path.Combine(Application.StartupPath, "Statistics"); + Directory.CreateDirectory(directory); // 确保文件夹存在 + + string fileName = $"Statistics_{customFileName}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.xlsx"; + string filePath = Path.Combine(directory, fileName); + + // 创建工作簿和工作表 + IWorkbook workbook = new XSSFWorkbook(); + ISheet sheet = workbook.CreateSheet("生产统计"); + + // --- 创建样式 (可选,但能让表格更好看) --- + IFont boldFont = workbook.CreateFont(); + boldFont.IsBold = true; + ICellStyle headerStyle = workbook.CreateCellStyle(); + headerStyle.SetFont(boldFont); + + // --- 创建表头 --- + IRow headerRow = sheet.CreateRow(0); + headerRow.CreateCell(0).SetCellValue("项目"); + headerRow.CreateCell(1).SetCellValue("数值"); + headerRow.GetCell(0).CellStyle = headerStyle; + headerRow.GetCell(1).CellStyle = headerStyle; + + // --- 填充数据 --- + sheet.CreateRow(1).CreateCell(0).SetCellValue("良品数 (OK)"); + sheet.GetRow(1).CreateCell(1).SetCellValue(data.GoodCount); + + sheet.CreateRow(2).CreateCell(0).SetCellValue("不良品数 (NG)"); + sheet.GetRow(2).CreateCell(1).SetCellValue(data.NgCount); + + sheet.CreateRow(3).CreateCell(0).SetCellValue("产品总数"); + sheet.GetRow(3).CreateCell(1).SetCellValue(data.TotalCount); + + sheet.CreateRow(4).CreateCell(0).SetCellValue("良率 (Yield)"); + sheet.GetRow(4).CreateCell(1).SetCellValue(data.YieldRate.ToString("P2")); + + // 自动调整列宽 + sheet.AutoSizeColumn(0); + sheet.AutoSizeColumn(1); + + // --- 写入文件 --- + using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write)) + { + workbook.Write(fs); + } + + ThreadSafeLogger.Log($"统计数据已成功导出到: {filePath}"); + } + catch (Exception ex) + { + ThreadSafeLogger.Log($"[ERROR] 导出统计数据失败: {ex.Message}"); + MessageBox.Show($"导出统计数据失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } +} diff --git a/Check.Main/Common/ThreadSafeLogger.cs b/Check.Main/Common/ThreadSafeLogger.cs new file mode 100644 index 0000000..2d22f5b --- /dev/null +++ b/Check.Main/Common/ThreadSafeLogger.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Check.Main.Common +{ + /// + /// 一个线程安全的、基于队列的日志记录器。 + /// 使用一个独立的后台线程来处理文件写入,避免业务线程阻塞。 + /// + public static class ThreadSafeLogger + { + // 使用线程安全的队列作为日志消息的缓冲区 + private static readonly BlockingCollection _logQueue = new BlockingCollection(); + + // 日志写入线程 + private static Thread _logWriterThread; + + private static StreamWriter _logFileWriter; + + // 事件,用于将格式化后的日志消息广播给UI等监听者 + public static event Action OnLogMessage; + + /// + /// 初始化日志记录器,启动后台写入线程。 + /// + public static void Initialize() + { + try + { + string logDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs"); + Directory.CreateDirectory(logDirectory); + + string logFileName = $"Log_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.txt"; + string logFilePath = Path.Combine(logDirectory, logFileName); + + _logFileWriter = new StreamWriter(logFilePath, append: true, encoding: Encoding.UTF8) { AutoFlush = true }; + + // 创建并启动后台线程 + _logWriterThread = new Thread(ProcessLogQueue) + { + IsBackground = true, // 设置为后台线程,这样主程序退出时它会自动终止 + Name = "LogWriterThread" + }; + _logWriterThread.Start(); + + Log("日志系统已初始化。"); + } + catch (Exception ex) + { + // 如果初始化失败,尝试通过事件通知UI + OnLogMessage?.Invoke($"[CRITICAL] 日志系统初始化失败: {ex.Message}"); + } + } + + /// + /// 将一条日志消息添加到队列中。这个方法是线程安全的,且执行速度非常快。 + /// + /// 原始日志消息。 + public static void Log(string message) + { + string formattedMessage = $"[{DateTime.Now:HH:mm:ss.fff}] {message}"; + _logQueue.Add(formattedMessage); + } + + /// + /// 后台线程的工作方法。它会持续不断地从队列中取出消息并处理。 + /// + private static void ProcessLogQueue() + { + // GetConsumingEnumerable会阻塞等待,直到有新的项加入队列或队列被标记为已完成 + foreach (string message in _logQueue.GetConsumingEnumerable()) + { + try + { + // 1. 写入文件 + _logFileWriter?.WriteLine(message); + + // 2. 触发事件,通知UI + OnLogMessage?.Invoke(message); + } + catch + { + // 忽略在日志线程本身发生的写入错误 + } + } + } + + /// + /// 关闭日志记录器,释放资源。 + /// + public static void Shutdown() + { + Log("日志系统正在关闭..."); + + // 标记队列不再接受新的项目。这会让ProcessLogQueue中的循环在处理完所有剩余项后自然结束。 + _logQueue.CompleteAdding(); + + // 等待日志线程处理完所有剩余的日志,最多等待2秒 + _logWriterThread?.Join(2000); + + // 关闭文件流 + _logFileWriter?.Close(); + _logFileWriter?.Dispose(); + } + } +} diff --git a/Check.Main/Dispatch/ProductManager.cs b/Check.Main/Dispatch/ProductManager.cs new file mode 100644 index 0000000..262094b --- /dev/null +++ b/Check.Main/Dispatch/ProductManager.cs @@ -0,0 +1,243 @@ +using Check.Main.Common; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Xml; +using System.Xml.Serialization; + +namespace Check.Main.Dispatch +{ + public static class ProductManager + { + private static readonly string _productRootPath = Path.Combine(Application.StartupPath, "Product"); + private static readonly string _productListFilePath = Path.Combine(Application.StartupPath, "products.json"); + + // --- 公共属性和事件 --- + public static List ProductList { get; private set; } = new List(); + public static string CurrentProductName { get; private set; } + public static ProcessConfig CurrentConfig { get; private set; } + + /// + /// 当产品切换或配置加载后触发。 + /// + public static event Action OnProductChanged; + + /// + /// 静态构造函数,在程序启动时自动执行。 + /// + static ProductManager() + { + Directory.CreateDirectory(_productRootPath); // 确保Product文件夹存在 + LoadProductList(); + // 默认加载列表中的第一个产品,或者创建一个默认的 + SwitchToProduct(ProductList.FirstOrDefault() ?? "DefaultProduct"); + } + + /// + /// 切换到指定的产品,并加载其配置。 + /// + public static bool SwitchToProduct(string productName) + { + if (string.IsNullOrWhiteSpace(productName)) return false; + + ThreadSafeLogger.Log($"正在切换到产品: {productName}"); + var config = LoadConfigForProduct(productName); + if (config == null) + { + // 如果加载失败(例如新创建的产品还没有配置文件),则创建一个新的 + config = new ProcessConfig(); + } + + CurrentProductName = productName; + CurrentConfig = config; + + // 广播产品已变更的通知 + OnProductChanged?.Invoke(); + return true; + } + + /// + /// 添加一个新产品。 + /// + public static bool AddNewProduct(string newProductName) + { + if (string.IsNullOrWhiteSpace(newProductName) || ProductList.Contains(newProductName)) + { + return false; // 名称无效或已存在 + } + + // 创建一个全新的、空的配置 + var newConfig = new ProcessConfig(); + + // 保存这个新产品的空配置,这也会创建文件夹 + if (SaveConfigForProduct(newProductName, newConfig)) + { + ProductList.Add(newProductName); + SaveProductList(); // 更新产品列表文件 + SwitchToProduct(newProductName); // 创建后立即切换到新产品 + return true; + } + return false; + } + + /// + /// 删除指定的产品及其所有相关配置。 + /// + /// 要删除的产品名称。 + /// 成功删除返回 true,否则返回 false。 + public static bool DeleteProduct(string productNameToDelete) + { + if (string.IsNullOrWhiteSpace(productNameToDelete) || !ProductList.Contains(productNameToDelete)) + { + ThreadSafeLogger.Log($"[警告] 尝试删除一个不存在的产品: {productNameToDelete}"); + return false; // 产品不存在 + } + + ThreadSafeLogger.Log($"正在删除产品: {productNameToDelete}..."); + try + { + // 1. 从产品列表中移除 + ProductList.Remove(productNameToDelete); + SaveProductList(); // 更新列表文件 + + // 2. 删除对应的配置文件夹 + var safeFolderName = GetSafeFolderName(productNameToDelete); + var productDir = Path.Combine(_productRootPath, safeFolderName); + if (Directory.Exists(productDir)) + { + Directory.Delete(productDir, true); // true 表示递归删除所有子文件和子文件夹 + } + + ThreadSafeLogger.Log($"产品 '{productNameToDelete}' 已成功删除。"); + + // 3. 如果被删除的是当前活动产品,则需要切换到一个新的有效产品 + if (CurrentProductName == productNameToDelete) + { + // 切换到列表中的第一个产品,或者如果列表为空,则创建一个默认产品 + string nextProduct = ProductList.FirstOrDefault() ?? "DefaultProduct"; + SwitchToProduct(nextProduct); + } + else + { + // 如果删除的不是当前产品,我们仍然需要触发一次事件, + // 以便UI(主要是下拉列表)能够刷新它的数据源。 + OnProductChanged?.Invoke(); + } + return true; + } + catch (Exception ex) + { + ThreadSafeLogger.Log($"[错误] 删除产品 '{productNameToDelete}' 失败: {ex.Message}"); + // 如果出错,最好把刚删除的项加回来,保持状态一致性 + if (!ProductList.Contains(productNameToDelete)) + { + ProductList.Add(productNameToDelete); + } + return false; + } + } + + /// + /// 为当前产品保存更改。 + /// + public static void SaveCurrentProductConfig() + { + if (CurrentConfig != null && !string.IsNullOrWhiteSpace(CurrentProductName)) + { + SaveConfigForProduct(CurrentProductName, CurrentConfig); + } + } + + #region 文件操作辅助方法 + + private static void LoadProductList() + { + try + { + if (File.Exists(_productListFilePath)) + { + var json = File.ReadAllText(_productListFilePath); + ProductList = JsonConvert.DeserializeObject>(json) ?? new List(); + } + } + catch (Exception ex) + { + ThreadSafeLogger.Log($"[错误] 加载产品列表失败: {ex.Message}"); + ProductList = new List(); + } + } + + private static void SaveProductList() + { + try + { + var json = JsonConvert.SerializeObject(ProductList, Newtonsoft.Json.Formatting.Indented); + File.WriteAllText(_productListFilePath, json); + } + catch (Exception ex) + { + ThreadSafeLogger.Log($"[错误] 保存产品列表失败: {ex.Message}"); + } + } + + private static ProcessConfig LoadConfigForProduct(string productName) + { + var safeFolderName = GetSafeFolderName(productName); + var configPath = Path.Combine(_productRootPath, safeFolderName, "config.xml"); + + if (!File.Exists(configPath)) return null; + + try + { + XmlSerializer serializer = new XmlSerializer(typeof(ProcessConfig)); + using (var fs = new FileStream(configPath, FileMode.Open, FileAccess.Read)) + { + return (ProcessConfig)serializer.Deserialize(fs); + } + } + catch (Exception ex) + { + ThreadSafeLogger.Log($"[错误] 加载产品 '{productName}' 的配置失败: {ex.Message}"); + return null; + } + } + + private static bool SaveConfigForProduct(string productName, ProcessConfig config) + { + try + { + var safeFolderName = GetSafeFolderName(productName); + var productDir = Path.Combine(_productRootPath, safeFolderName); + Directory.CreateDirectory(productDir); // 确保文件夹存在 + + var configPath = Path.Combine(productDir, "config.xml"); + + XmlSerializer serializer = new XmlSerializer(typeof(ProcessConfig)); + using (var fs = new FileStream(configPath, FileMode.Create, FileAccess.Write)) + { + serializer.Serialize(fs, config); + } + return true; + } + catch (Exception ex) + { + ThreadSafeLogger.Log($"[错误] 保存产品 '{productName}' 的配置失败: {ex.Message}"); + return false; + } + } + + private static string GetSafeFolderName(string productName) + { + // 移除所有不适合做文件夹名称的字符 + string invalidChars = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars()); + Regex r = new Regex(string.Format("[{0}]", Regex.Escape(invalidChars))); + return r.Replace(productName, ""); + } + + #endregion + } +} diff --git a/Check.Main/FrmMain.Designer.cs b/Check.Main/FrmMain.Designer.cs new file mode 100644 index 0000000..a3333d6 --- /dev/null +++ b/Check.Main/FrmMain.Designer.cs @@ -0,0 +1,180 @@ +namespace Check.Main +{ + partial class FrmMain + { + /// + /// 必需的设计器变量。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 清理所有正在使用的资源。 + /// + /// 如果应释放托管资源,为 true;否则为 false。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows 窗体设计器生成的代码 + + /// + /// 设计器支持所需的方法 - 不要修改 + /// 使用代码编辑器修改此方法的内容。 + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmMain)); + menuStrip1 = new MenuStrip(); + 文件ToolStripMenuItem = new ToolStripMenuItem(); + 退出ToolStripMenuItem = new ToolStripMenuItem(); + ToolStripMenuSaveLayou = new ToolStripMenuItem(); + 视图ToolStripMenuItem = new ToolStripMenuItem(); + 配置ToolStripMenuItem = new ToolStripMenuItem(); + 日志ToolStripMenuItem = new ToolStripMenuItem(); + 控制面板ToolStripMenuItem = new ToolStripMenuItem(); + statusStrip1 = new StatusStrip(); + uiTableLayoutPanel1 = new Sunny.UI.UITableLayoutPanel(); + dockPanel1 = new WeifenLuo.WinFormsUI.Docking.DockPanel(); + menuStrip1.SuspendLayout(); + uiTableLayoutPanel1.SuspendLayout(); + SuspendLayout(); + // + // menuStrip1 + // + menuStrip1.Items.AddRange(new ToolStripItem[] { 文件ToolStripMenuItem, 视图ToolStripMenuItem, 控制面板ToolStripMenuItem }); + menuStrip1.Location = new Point(0, 0); + menuStrip1.Name = "menuStrip1"; + menuStrip1.Padding = new Padding(7, 3, 0, 3); + menuStrip1.Size = new Size(933, 27); + menuStrip1.TabIndex = 0; + menuStrip1.Text = "MainMenu"; + // + // 文件ToolStripMenuItem + // + 文件ToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { 退出ToolStripMenuItem, ToolStripMenuSaveLayou }); + 文件ToolStripMenuItem.Name = "文件ToolStripMenuItem"; + 文件ToolStripMenuItem.Size = new Size(44, 21); + 文件ToolStripMenuItem.Text = "文件"; + // + // 退出ToolStripMenuItem + // + 退出ToolStripMenuItem.Name = "退出ToolStripMenuItem"; + 退出ToolStripMenuItem.Size = new Size(124, 22); + 退出ToolStripMenuItem.Text = "退出"; + // + // ToolStripMenuSaveLayou + // + ToolStripMenuSaveLayou.Name = "ToolStripMenuSaveLayou"; + ToolStripMenuSaveLayou.Size = new Size(124, 22); + ToolStripMenuSaveLayou.Text = "保存布局"; + ToolStripMenuSaveLayou.Click += ToolStripMenuSaveLayou_Click; + // + // 视图ToolStripMenuItem + // + 视图ToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { 配置ToolStripMenuItem, 日志ToolStripMenuItem }); + 视图ToolStripMenuItem.Name = "视图ToolStripMenuItem"; + 视图ToolStripMenuItem.Size = new Size(44, 21); + 视图ToolStripMenuItem.Text = "视图"; + // + // 配置ToolStripMenuItem + // + 配置ToolStripMenuItem.Name = "配置ToolStripMenuItem"; + 配置ToolStripMenuItem.Size = new Size(180, 22); + 配置ToolStripMenuItem.Text = "配置"; + 配置ToolStripMenuItem.Click += 配置ToolStripMenuItem_Click; + // + // 日志ToolStripMenuItem + // + 日志ToolStripMenuItem.Name = "日志ToolStripMenuItem"; + 日志ToolStripMenuItem.Size = new Size(180, 22); + 日志ToolStripMenuItem.Text = "日志"; + 日志ToolStripMenuItem.Click += 日志ToolStripMenuItem_Click; + // + // 控制面板ToolStripMenuItem + // + 控制面板ToolStripMenuItem.Name = "控制面板ToolStripMenuItem"; + 控制面板ToolStripMenuItem.Size = new Size(68, 21); + 控制面板ToolStripMenuItem.Text = "控制面板"; + 控制面板ToolStripMenuItem.Click += 控制面板ToolStripMenuItem_Click; + // + // statusStrip1 + // + statusStrip1.Location = new Point(0, 616); + statusStrip1.Name = "statusStrip1"; + statusStrip1.Padding = new Padding(1, 0, 16, 0); + statusStrip1.Size = new Size(933, 22); + statusStrip1.TabIndex = 2; + statusStrip1.Text = "statusStrip1"; + // + // uiTableLayoutPanel1 + // + uiTableLayoutPanel1.ColumnCount = 2; + uiTableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 76F)); + uiTableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 24F)); + uiTableLayoutPanel1.Controls.Add(dockPanel1, 0, 0); + uiTableLayoutPanel1.Dock = DockStyle.Fill; + uiTableLayoutPanel1.Location = new Point(0, 27); + uiTableLayoutPanel1.Margin = new Padding(4); + uiTableLayoutPanel1.Name = "uiTableLayoutPanel1"; + uiTableLayoutPanel1.RowCount = 1; + uiTableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 50F)); + uiTableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 50F)); + uiTableLayoutPanel1.Size = new Size(933, 589); + uiTableLayoutPanel1.TabIndex = 3; + uiTableLayoutPanel1.TagString = null; + // + // dockPanel1 + // + uiTableLayoutPanel1.SetColumnSpan(dockPanel1, 2); + dockPanel1.Dock = DockStyle.Fill; + dockPanel1.Location = new Point(4, 4); + dockPanel1.Margin = new Padding(4); + dockPanel1.Name = "dockPanel1"; + dockPanel1.Size = new Size(925, 581); + dockPanel1.TabIndex = 0; + // + // FrmMain + // + AutoScaleDimensions = new SizeF(7F, 17F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(933, 638); + Controls.Add(uiTableLayoutPanel1); + Controls.Add(statusStrip1); + Controls.Add(menuStrip1); + Icon = (Icon)resources.GetObject("$this.Icon"); + MainMenuStrip = menuStrip1; + Margin = new Padding(4); + Name = "FrmMain"; + Text = "星科瑞升视觉检测设备"; + WindowState = FormWindowState.Maximized; + FormClosing += FrmMain_FormClosing; + Load += FrmMain_Load; + menuStrip1.ResumeLayout(false); + menuStrip1.PerformLayout(); + uiTableLayoutPanel1.ResumeLayout(false); + ResumeLayout(false); + PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.StatusStrip statusStrip1; + private System.Windows.Forms.ToolStripMenuItem 文件ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 退出ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 视图ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 配置ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem 日志ToolStripMenuItem; + private Sunny.UI.UITableLayoutPanel uiTableLayoutPanel1; + private WeifenLuo.WinFormsUI.Docking.DockPanel dockPanel1; + private System.Windows.Forms.ToolStripMenuItem 控制面板ToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem ToolStripMenuSaveLayou; + } +} + diff --git a/Check.Main/FrmMain.cs b/Check.Main/FrmMain.cs new file mode 100644 index 0000000..8a5f002 --- /dev/null +++ b/Check.Main/FrmMain.cs @@ -0,0 +1,297 @@ +using Check.Main.Camera; +using Check.Main.Common; +using Check.Main.UI; +using HslCommunication; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; + +namespace Check.Main +{ + public partial class FrmMain : Form + { + // private FrmCamConfig _formCameraConfig; + private FrmConfig _frmConfig; + private FrmLog _formLog; + private ThemeBase _theme = new VS2015BlueTheme(); // 外观主题 + public DockPanel MainDockPanel => this.dockPanel1; + + private FormControlPanel _formControlPanel; + + private FormStatistics _formStatistics; + + private readonly string _layoutConfigFile = Path.Combine(Application.StartupPath, "layout.xml"); + //用于反序列化时创建窗体的委托 + private DeserializeDockContent _deserializeDockContent; + + public FrmMain() + { + InitializeComponent(); + dockPanel1.Theme = _theme; + IsMdiContainer = true; + _deserializeDockContent = new DeserializeDockContent(GetContentFromPersistString); + } + + private void FrmMain_Load(object sender, EventArgs e) + { + EasyPlcClient easyPlcClient = new EasyPlcClient("127.0.0.1", 502, 1); + easyPlcClient.ConnectAsync(); + + _frmConfig = new FrmConfig { Text = "主程序配置" }; + _formLog = new FrmLog { Text = "运行日志" }; + _formStatistics = new FormStatistics { Text = "生产统计" }; + _formControlPanel = new FormControlPanel { Text = "控制面板" }; + // 为每个子窗体订阅 FormClosing 事件 + _frmConfig.FormClosing += DockContent_FormClosing; + _formLog.FormClosing += DockContent_FormClosing; + _formStatistics.FormClosing += DockContent_FormClosing; + _formControlPanel.FormClosing += DockContent_FormClosing; + + ThreadSafeLogger.Initialize(); + ThreadSafeLogger.OnLogMessage += (msg) => { _formLog.AddLog(msg); }; + + // 2. 尝试加载布局文件 + if (File.Exists(_layoutConfigFile)) + { + try + { + // 使用委托加载布局 + dockPanel1.LoadFromXml(_layoutConfigFile, _deserializeDockContent); + ThreadSafeLogger.Log("成功加载用户布局。"); + } + catch (Exception ex) + { + ThreadSafeLogger.Log($"加载布局失败: {ex.Message}。将使用默认布局。"); + // 如果加载失败,则使用默认布局 + ShowDefaultLayout(); + } + } + else + { + // 3. 如果布局文件不存在,则显示默认布局 + ThreadSafeLogger.Log("未找到布局文件,使用默认布局。"); + ShowDefaultLayout(); + } + } + /// + /// 将相机名称添加到状态栏 + /// + public void AddCameraToStatusStrip(string name) + { + if (statusStrip1.InvokeRequired) + { + statusStrip1.Invoke(new Action(() => AddCameraToStatusStrip(name))); + return; + } + var label = new ToolStripStatusLabel(name) + { + Name = "status_" + name, + BorderSides = ToolStripStatusLabelBorderSides.All, + Spring = false, + }; + label.Click += StatusLabel_Click; + statusStrip1.Items.Add(label); + } + private void 控制面板ToolStripMenuItem_Click(object sender, EventArgs e) + { + if (_formControlPanel == null || _formControlPanel.IsDisposed) + { + _formControlPanel = new FormControlPanel { Text = "控制面板" }; + _formControlPanel.FormClosing += DockContent_FormClosing; + } + _formControlPanel.Show(this.dockPanel1); + } + /// + /// 清空状态栏中的相机名称 + /// + public void ClearStatusStrip() + { + if (statusStrip1.InvokeRequired) + { + statusStrip1.Invoke(new Action(ClearStatusStrip)); + return; + } + // 从后往前删,避免索引问题 + for (int i = statusStrip1.Items.Count - 1; i >= 0; i--) + { + if (statusStrip1.Items[i] is ToolStripStatusLabel && statusStrip1.Items[i].Name.StartsWith("status_")) + { + statusStrip1.Items.RemoveAt(i); + } + } + } + + private void StatusLabel_Click(object sender, EventArgs e) + { + if (sender is ToolStripStatusLabel label) + { + string cameraName = label.Text; + ThreadSafeLogger.Log($"用户点击状态栏标签: {cameraName}"); + + bool foundOriginal = false; + bool foundResult = false; + + // 1. 尝试重新显示“原图”窗口 + if (CameraManager.OriginalImageDisplays.TryGetValue(cameraName, out var originalDisplayForm)) + { + // 使用 Show() 方法来重新激活或显示隐藏的窗口 + // 传入 DockPanel 确保它知道在哪里显示 + originalDisplayForm.Show(this.dockPanel1); + originalDisplayForm.Activate(); // 调用 Activate() 确保它成为当前焦点窗口 + foundOriginal = true; + } + + // 2. 尝试重新显示“结果”窗口 + if (CameraManager.ResultImageDisplays.TryGetValue(cameraName, out var resultDisplayForm)) + { + resultDisplayForm.Show(this.dockPanel1); + resultDisplayForm.Activate(); + foundResult = true; + } + + // 3. 提供反馈 + if (foundOriginal || foundResult) + { + ThreadSafeLogger.Log($"已重新激活相机 '{cameraName}' 的显示窗口。"); + } + else + { + ThreadSafeLogger.Log($"[警告] 未能找到相机 '{cameraName}' 对应的活动显示窗口。可能设备已关闭。"); + } + } + } + + /// + /// 根据持久化字符串创建或返回对应的窗体实例。 + /// 这是DockPanel Suite反序列化布局时需要的回调方法。 + /// + /// 在XML中代表一个窗体的唯一字符串(通常是其类型名)。 + /// 对应的窗体实例。 + private IDockContent GetContentFromPersistString(string persistString) + { + if (persistString == typeof(FormControlPanel).ToString()) + return _formControlPanel; + if (persistString == typeof(FrmConfig).ToString()) + return _frmConfig; + if (persistString == typeof(FrmLog).ToString()) + return _formLog; + if (persistString == typeof(FormStatistics).ToString()) + return _formStatistics; + + // 对于图像显示窗口,由于它们是动态创建的,情况会更复杂。 + // 在当前设计中,我们不保存图像窗口的布局,它们会在应用相机配置时重新创建。 + // 如果需要保存它们,需要在CameraManager中管理它们的持久化字符串。 + // 目前的设计下,返回null是安全的。 + return null; + } + + /// + /// 显示程序的默认窗口布局。 + /// + private void ShowDefaultLayout() + { + // 确保所有窗体都未被意外关闭 + if (_formControlPanel.IsDisposed) _formControlPanel = new FormControlPanel(); + if (_frmConfig.IsDisposed) _frmConfig = new FrmConfig(); + if (_formLog.IsDisposed) _formLog = new FrmLog(); + if (_formStatistics.IsDisposed) _formStatistics = new FormStatistics(); + + // 显示默认窗口 + _frmConfig.Show(dockPanel1, DockState.DockLeft); + _formLog.Show(dockPanel1, DockState.DockBottom); + _formControlPanel.Show(dockPanel1, DockState.DockRight); + _formStatistics.Show(dockPanel1, DockState.DockTop); + } + + /// + /// 【新增】保存当前窗口布局到XML文件。 + /// + private void SaveLayout() + { + try + { + // 将当前DockPanel的布局保存到指定文件 + dockPanel1.SaveAsXml(_layoutConfigFile); + ThreadSafeLogger.Log("布局已成功保存!"); + //MessageBox.Show("布局已成功保存!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + catch (Exception ex) + { + ThreadSafeLogger.Log("保存布局失败: " + ex.Message); + //MessageBox.Show("保存布局失败: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + private void FrmMain_FormClosing(object sender, FormClosingEventArgs e) + { + if (_formStatistics != null && !_formStatistics.IsDisposed) + { + StatisticsExporter.ExportToExcel(_formStatistics.CurrentStatistics, "Shutdown"); + } + + CameraManager.Shutdown(); + ThreadSafeLogger.Shutdown(); + } + + private void ToolStripMenuSaveLayou_Click(object sender, EventArgs e) + { + SaveLayout(); + } + + private void 配置ToolStripMenuItem_Click(object sender, EventArgs e) + { + //_frmConfig.Show(); + // 如果窗体因意外被销毁,则重新创建它 + if (_frmConfig == null || _frmConfig.IsDisposed) + { + _frmConfig = new FrmConfig() { Text = "主程序配置" }; + _frmConfig.FormClosing += DockContent_FormClosing; + } + // 调用 Show() 会自动处理隐藏和显示逻辑 + _frmConfig.Show(this.dockPanel1); + } + private void 日志ToolStripMenuItem_Click(object sender, EventArgs e) + { + if (_formLog == null || _formLog.IsDisposed) + { + _formLog = new FrmLog { Text = "运行日志" }; + _formLog.FormClosing += DockContent_FormClosing; + } + _formLog.Show(this.dockPanel1); + } + + /// + /// 处理所有可停靠子窗体关闭事件的通用方法。 + /// 通过取消关闭并隐藏窗口,来实现“假关闭”,以便后续能重新显示。 + /// + private void DockContent_FormClosing(object sender, FormClosingEventArgs e) + { + // 检查关闭原因是否为用户点击了关闭按钮 + if (e.CloseReason == CloseReason.UserClosing) + { + // 1. 取消真正的关闭(Dispose)操作,防止窗体被销毁 + e.Cancel = true; + + // 2. 将窗口隐藏起来 + // 我们需要将 sender 转换为 DockContent 类型来访问 Hide() 方法 + if (sender is DockContent dockContent) + { + if (dockContent is FormImageDisplay imageDisplay) + { + ThreadSafeLogger.Log($"用户关闭了窗口 '{imageDisplay.Text}',已将其隐藏。"); + } + dockContent.Hide(); + } + } + } + + + } +} diff --git a/Check.Main/FrmMain.resx b/Check.Main/FrmMain.resx new file mode 100644 index 0000000..3e6d304 --- /dev/null +++ b/Check.Main/FrmMain.resx @@ -0,0 +1,3244 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 250, 17 + + + + + AAABAAkAEBAAAAEAIABoBAAAlgAAABgYAAABACAAiAkAAP4EAAAgIAAAAQAgAKgQAACGDgAAMDAAAAEA + IACoJQAALh8AAEBAAAABACAAKEIAANZEAABISAAAAQAgAIhUAAD+hgAAYGAAAAEAIAColAAAhtsAAICA + AAABACAAKAgBAC5wAQAAAAAAAQAgACphAABWeAIAKAAAABAAAAAgAAAAAQAgAAAAAAAABAAAIy4AACMu + AAAAAAAAAAAAAI1CAACNQgBJjUIA6I1CAPONQgDujUIAUo1CAACOQQAAAAAAAI1CAACNQgAHjUIArI1C + APSNQgDqjUIASY1CAACNQgAAjUIAC41CALKNQgD/jUIA/41CAJGMQwAAjkIAAAAAAACNQgAAjUIAHY1C + ANyNQgD/jUIA241CAB2NQgAAjUIAAI1CAACNQgBNjUIA9o1CAP+NQgDMjUIAEo1CAACNQgAAjUIAAI1C + AESNQgD2jUIA/41CAKaNQgADjUIAAI9EAACNQgAAjUIAEI1CAMeNQgD/jUIA741CADWNQgAAjUIAAI1C + AACNQgBvjUIA/41CAP+NQgBwjUIAAI1CAACNQgAAjUIAAI1CAACNQgCEjUIA/41CAP6NQgB1jUIAKI1C + ABGMQwAAjUIAlY1CAP+NQgD1jUIAQI1CAACLQgAAjUIAAIxCAACNQgBNjUIApo1CAPWNQgD/jUIAwY1C + ANaNQgDLjUIAio1CAMyNQgD/jUIA4o1CACKNQgAAAAAAAI1CAACNQgAcjUIAmY1CAH6NQgDbjUIA/41C + ANKNQgDVjUIA/41CAP+NQgD/jUIA/41CAMyNQgAOjUIAAI1CAACMQgAAjUIAG41CAA+NQgAFjUIAtY1C + AP+NQgDcjUIAUY1CAJGNQgDmjUIA/41CAP+NQgDjjUIAQY1CAACNQgAAjUAAAY1CAFGNQgAKjUIAAI1C + AI6NQgD/jUIA7Y1CAC6NQgAAjUIANI1CAK6NQgD8jUIA/41CAN2NQgA9jUIAAI1CADiNQgCrjUIARoM+ + AACNQgBpjUIA/41CAPiNQgBIjUIAAI1CAACNQgANjUIAjo1CAPyNQgD/jUIAyY1CACCNQgA6jUIAx41C + AKWNQgAKjUIATI1CAPyNQgD+jUIAWo1CAACNQgAAjUIAAI1CAA2NQgCxjUIA/41CAP+NQgCKkEEAAI1C + AF2NQgCcjUIAl41CAFWNQgDbjUIA/41CAGWNQgAAiD0AAI1CAACNQgAAjUIAYI1CAP+NQgD/jUIA4I1C + AAGNQgAPjUIAGY1CAKqNQgDfjUIAso1CAKuNQgBOjUIAAI1CAACNQgAAjUIACY1CAI+NQgD/jUIA/41C + APeNQgAAjUIAAI1CAACNQgASjUIAio1CAO+NQgDtjUIAwY1CAJqNQgCBjUIAhY1CALmNQgD3jUIA/41C + AP+NQgDPAAAAAI5CAACNQgAAjUIAAI5CAAONQgBFjUIAsY1CAPKNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgDgjUIATwAAAAAAAAAAi0IAAI1CAACNQgAAjUIAAI1CAAuNQgBEjUIAkI1CAMyNQgDsjUIA9Y1C + AOONQgCnjUIAPolDAAAAgAAAAIAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAIAAAADAAAAAKAAAABgAAAAwAAAAAQAgAAAAAAAACQAAIy4AACMuAAAAAAAAAAAAAI1C + AACNRAABjUIAgY1CAOyNQgDqjUIA6Y1CAOyNQgC7jUIAEY1CAACAgAAAAAAAAAAAAAAAAAAAjkAAAI1C + AACNQgAmjUIA0Y1CAOiNQgDmjUIA6Y1CAHaNQgAAjUMAAI9AAACNQgAAjUIALI1CAN6NQgD/jUIA/41C + AP+NQgDvjUIAN41CAACPQAAAAAAAAAAAAAAAAAAAiUEAAI1CAACNQgBRjUIA+41CAP+NQgD/jUIA9I1C + AEONQgAAjkEAAItGAACNQQAAjEIAAI1CAHqNQgD/jUIA/41CAP+NQgD/jUIAdI1CAACHSgAAAAAAAAAA + AAAAAAAAjEEAAI1DAACNQgCGjUIA/41CAP+NQgD/jUIAyo1CABGNQgAAAAAAAAAAAACNQQAAjUIAAI1C + ACKNQgDajUIA/41CAP+NQgD/jUIAs45CAAeOQgAAAAAAAAAAAAAAAAAAjUIAAI1CAAmNQgC5jUIA/41C + AP+NQgD/jUIAkZBBAACLQwAAAAAAAAAAAACPRAAAjkIAAIpDAACNQgCNjUIA/41CAP+NQgD/jUIA4Y1C + ACONQgAAAAAAAAAAAAAAAAAAjUIAAI1CACCNQgDfjUIA/41CAP+NQgD8jUIAWo1CAACMQgAAAAAAAAAA + AAAAAAAAjkIAAI1CAACNQgA/jUIA8o1CAP+NQgD/jUIA+Y1CAE+NQgAAjUIAAI5DAACLQAAAjUIAAI1C + AD6NQgD0jUIA/41CAP+NQgDpjUIALY1CAACNQgAAAAAAAAAAAAAAAAAAjUIAAI1CAACNQgAOjUIAxY1C + AP+NQgD/jUIA/41CAISMQgADhDMAAI1CAACNQgAAjUIAAI1CAGCNQgD+jUIA/41CAP+NQgDHjUIAD41C + AAAAAAAAAAAAAAAAAACOQwAAjUIAAI1CAACNQgAbjUIAl41CAP+NQgD/jUIA/41CALqNQgCHjUIAmo1C + AGSNQgAsj0IABI1CAISNQgD/jUIA/41CAP+NQgChjkIAAY1CAAAAAAAAAAAAAAAAAACMQQAAjUIAAI1C + ADiNQgDIjUIAoo1CAPWNQgD/jUIA/41CANmNQgCvjUIA/41CAP6NQgDnjUIAq41CAMqNQgD/jUIA/41C + AP+NQgB9jEIAAI9BAAAAAAAAAAAAAAAAAACNQgAAjUIAGo1CAL2NQgDejUIAho1CAN6NQgD/jUIA/41C + AO6NQgCgjUIA/o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP2NQgBdjUIAAItDAAAAAAAAAAAAAI5C + AACNQgAAjUIAMI1CAFGNQgAcjUIAEY1CALuNQgD/jUIA/41CAPuNQgCJjUIAv41CAPeNQgD/jUIA/41C + AP+NQgD/jUIA/41CAPmNQgBLjUIAAI9CAACLQQAAAAAAAI1CAACNQgAFjUIAH41CAACNQgAAjUIAAI1C + AI6NQgD/jUIA/41CAP+NQgB9jUIAD41CAE+NQgCwjUIA9o1CAP+NQgD/jUIA/41CAP+NQgC8jUIAKY1C + AACPRQAAjkEAAI1CAACNQgAVjUIAbI5CAASOQwAAjUIAAI1CAGeNQgD/jUIA/41CAP+NQgCdkUIAAI1C + AACNQgAKjUIAVo1CAM2NQgD/jUIA/41CAP+NQgD/jUIAx41CACiNQgAAjUIAAI1CAACNQgAkjUIAoY1D + AAiNQgAAjUIAAI1CAEWNQgD2jUIA/41CAP+NQgC6jUIACI1CAACNQgAAjUIAAI1CAB+NQgCejUIA/I1C + AP+NQgD/jUIA/41CALmNQgAXjUIAAI1CADaNQgCIjUIA4I1CAGqNQgAijUIAAI1CACmNQgDnjUIA/41C + AP+NQgDOjUIAE41CAACNQwAAizgAAI1CAACNQgAMjUIAk41CAP6NQgD/jUIA/41CAP+NQgCHjEIAAo1C + ADyNQgCOjUIA/I1CAMONQgArjUIAAI1CABiNQgDWjUIA/41CAP+NQgDdjUIAHY1CAAAAAAAAlEMAAIxC + AACNQgAAjUIAEY1CALSNQgD/jUIA/41CAP+NQgDmjUIAOY1CAACNQgAjjUIAwY1CANCNQgCBjUIADo1D + AAmNQgDGjUIA/41CAP+NQgDmjUIAJY1CAAAAAAAAAAAAAI1CAACNQQAAjUIAAI1CAEeNQgD0jUIA/41C + AP+NQgD/jUIAl41CAACNQgAWjUIAbI1CAFiNQgDsjUIAs41CAD2NQgCPjUIA8o1CAP+NQgDsjUIAKo1C + AAAAAAAAAAAAAAAAAACNQwAAjUIAAI1CAB2NQgDejUIA/41CAP+NQgD/jUIA3Y1CAACNQgAGjUIAII1B + AAKNQgBrjUIA9Y1CAOyNQgCljUIAg41CAKGNQgDAjUIAJI1CAACNQgAAjUIAAI1CAACNQgAAjUIAAI1C + AD6NQgDujUIA/41CAP+NQgD/jUIA9IxBAACMQQAAjEEAAI1CAACOQgADjUIAY41CAOeNQgD/jUIA7I1C + ALiNQgCEjUIAPo1CABqNQgAMjUIABo1CAAeNQgAVjUIAS41CAMiNQgD/jUIA/41CAP+NQgD/jUIA5ZlN + AACaTQAAnU8AAI1CAACNQgAAjUQAAI1CAD6NQgC/jUIA/41CAP+NQgD+jUIA741CANqNQgDFjUIAs41C + ALWNQgDSjUIA9Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIAogAAAAAAAAAAAAAAAAAAAACNQQAAjUEAAI1C + AACOQgAVjUIAd41CANuNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgDSjUIALgAAAAAAAAAAAAAAAAAAAAAAAAAAjkIAAI1CAACNQgAAjkEAAI1CACSNQgB3jUIAxI1C + APCNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA+I1CAMGNQgA6jUIAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACNQwAAjEMAAI1CAACNQgAAjUIAEo1CAEWNQgCFjUIAuo1CANuNQgDtjUIA7o1C + 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 + AAyNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQgAAjUIAAI1CAE+NQgCwjUIAbo1CAD2NQgAhjUIAwo1C + AP+NQgD/jUIA/41CAP+NQgCvjUIAp41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgCkjT8AAo1BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAItEAACLRAABjUIAIY1CAA6NQgAAjUIAAIpD + AACNQgCVjUIA/41CAP+NQgD/jUIA/41CAMiNQgA8jUIAio1CANSNQgD9jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CALKNQgAPjUIAAI5CAACCQAAAAAAAAAAAAAAAAAAAjUIAAI1CABSNQgAojUIAAJo8 + AACRQAAAjUIAAI1CAGeNQgD/jUIA/41CAP+NQgD/jUIA4I1CAB+NQAAAjUIAHI1CAGuNQgDNjUIA/o1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA+41CAKKMQwAYjUIAAI1CAACMQgAAAAAAAP8AAACNQgAAjUIAOI1C + AHGNQgAAj0MAAIxDAACNQgAAjUIARI1CAPWNQgD/jUIA/41CAP+NQgDwjUIAOI1CAACNQgAAjUIAAI1C + ABuNQgB9jUIA5o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAKyNQgAYjUIAAI1CAACIRAAAjEIAAI1C + AACNQgBXjUIAm45DAAOOQwAAkkkAAI1CAACNQgAmjUIA5Y1CAP+NQgD/jUIA/41CAPqNQgBVjUIAAItD + AAD/SwAAjUIAAJg4AACNQgA7jUIAu41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAKCNQgAOjUIAAI1B + AACNQgAAjEIAAI1CAHeNQgDBjkIACY1CAACNQgAAjUIAAI1CABONQgDMjUIA/41CAP+NQgD/jUIA/41C + AHCNQgAAjUIAAAAAAACNQgAAjUIAAI1CAACOQgAWjUIAmY1CAPyNQgD/jUIA/41CAP+NQgD/jUIA/I1C + AH2OQAACjUEAAI1CADyNQgBzjUIA0Y1CAPCNQgCOjUIAT41CABCNQgAAjUIABY1CALCNQgD/jUIA/41C + AP+NQgD/jUIAh41DAACNQQAAAAAAAAAAAACPQgAAjEIAAI1CAACNQgAOjUIAmo1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA641CAECNQgAAjUIARY1CAICNQgDXjUIA/41CANiNQgBcjEIAEIxCAACiOgAAjUIAlo1C + AP+NQgD/jUIA/41CAP+NQgCcjUEAAY1CAAAAAAAAAAAAAAAAAAAAAAAAjUIAAI1CAACNQgAWjUIAuY1C + AP+NQgD/jUIA/41CAP+NQgD/jUIArI5CAAqNQgAAjEIAAI1CAHaNQgD3jUIA6I1CAHCMQwAGjUIAAI1B + AACNQgB9jUIA/41CAP+NQgD/jUIA/41CAKyOQgACjkEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjUEAAI1C + AACNQgBBjUIA7o1CAP+NQgD/jUIA/41CAP+NQgDujUIAR4tBAACNQgAAjUIAWI1CAKaNQgCfjUIA+Y1C + AJSNQgAbjUIAAI1CAGeNQgD/jUIA/41CAP+NQgD/jUIAtY5CAAWOQgAAAAAAAAAAAAAAAAAAAAAAAAAA + AACMQgAAjUIAAI1CAAqNQgC6jUIA/41CAP+NQgD/jUIA/41CAP+NQgCc/wAAAI1CAACNQgA7jUIAcI1C + AByNQgDCjUIA/41CAMiNQgBQjUIAQI1CAMiNQgD8jUIA/41CAP+NQgC5j0IACI9BAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJI9AACPPgAAdHMAAI1CAJyNQgD/jUIA/41CAP+NQgD/jUIA/41CANgAAAAAjUIAAI1C + ABeNQgAujUIAAI1CADCNQgDQjUIA/41CAPWNQgCwjUIAaY1CAHONQgCvjUIA7I1CALiPQQAIj0EAAJI9 + AAAAAAAAAAAAAAAAAACMQwAAi0EAAI1CAACNQgAMjUIAvI1CAP+NQgD/jUIA/41CAP+NQgD/jUIA8AAA + AACCNQAAgjYAAIQ5AACSRQAAjUIAAI1CADSNQgDJjUIA/41CAP+NQgD0jUIAvY1CAHaNQgBdjUIAUpE+ + AAKNQgAAjUIAAI1CAACNQgAAjUIAAI1CAACNQgAAjUIACI1CAHSNQgD2jUIA/41CAP+NQgD/jUIA/41C + AP+NQgDqAAAAAJpNAACaTgAAnk8AAJBEAACPQgAAjUIAAI1CACWNQgCrjUIA/I1CAP+NQgD/jUIA/o1C + AN+NQgCtjUIAe41CAFaNQgA5jUIAKI1CAB6NQgAfjUIAMI1CAF6NQgCsjUIA9o1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAMQAAAAAAAAAAAAAAAAAAAAAAAAAAI5CAAC7VAAAjUIAAI1CAA+NQgB2jUIA5Y1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA+41CAPKNQgDmjUIA2o1CANyNQgDsjUIA/I1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD6jUIAcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKRRAACMQgAAjUIAAORW + AACOQgA4jUIAqo1CAPSNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CALSNQgAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACOQgAAjkIAAI1CAACNQgAJjUIATY1CALCNQgDujUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDFjUIAK41CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACQQQAAi0MAAI1CAACNQgAAjUIACY1CADqNQgCDjUIAxY1CAOyNQgD9jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPuNQgDcjUIAjY1CACGNQgAAizoAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjkIAAI1CAACNQwAAjUIAAIxEAACNQQASjUIAPo1C + AHaNQgCljUIAyI1CAN+NQgDpjUIA541CANSNQgCsjUIAbo1CACmNRQACjUIAAIlBAACNQgAAgAfwAYAH + 8AGAA/ABwAPwA8AD4APgA+AD4AHgB/AA4AfwAAAH4AAAB8AAAA/AAAAPgAAAD4AAAA+AAAADgAAAAQAA + AAAAAAAAAABAAAAAYAAAAHgAAAB8AAAAfAAAAHwAgAA4AIAAAACAAAAA+AAAAPwAAAD/AAAA/4AAAP/g + AAAoAAAAMAAAAGAAAAABACAAAAAAAAAkAAAjLgAAIy4AAAAAAAAAAAAAAAAAAAAAAACPQAAAcVYAAI1C + AGeNQgDOjUIAzY1CAM2NQgDNjUIAzY1CAM2NQgDNjUIAzY1CAM2NQgDPjUIAc449AAGNQQAAAAAAAAAA + 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 + AFmNQgAyjUIAFo5EAAKNQgAAjUIAAJBCAACOQQAAjkIAH41CANeNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIAZo1CAACOQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACSSQAAjUEAAI1CAACNQQAHjEIATo1CAESNQgDRjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AJeNQgB1jUIA/41CAPmNQgDsjUIAyo1CAJqNQgBYjkEAIpFCAAONQgAAjUIAOI1CAO2NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgDyjUIARo1CAACHSgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI5DAACNQgAAjEIAAI1CABGNQgCLjUIA8Y1CAH2NQgCdjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAL2NQgBbjUIA9I1CAP+NQgD/jUIA/41CAP+NQgD5jUIA2Y1CAJuNQgBFjUIAWY1C + APiNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDijkIAKo5CAACZMwAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIlEAACOQgAAj0EADI1CAJKNQgD8jUIA/41CAKeNQgByjUIA/I1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAOCNQQBSjUIA3o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgDyjUIA3Y1CAP2NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDRjkEAE45BAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIlEAAB9TwAAjUIAcI1CAPmNQgD/jUIA/41C + ANuNQgBXjUIA6o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPeNQgBYjUIAxI1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgC1jUIACY1C + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjkEAAI1DAACMQgAyjUIA441C + AP6NQgDijUIAv41CAJqNQgA2jUIAzo1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP2NQgB1jUIAoY1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgCXjUEAA41CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjkEAAI5B + AASNQgCIjUIAtY1CAGONQgAqjkIADoFFAAGOQAAGjUIApI1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgCUjUIAdY1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgB5jUUAAI1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjEMAAIxDAA+NQgA+jUIADY1CAACNQgAAjkIAAI5BAACKQwAAjUIAdo1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgCyjkMAKI1CAIaNQgDQjUIA+I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgB0jUIAAI1DAACNQQAAgIAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAkEYAAI1DAAaJRwAAjUIAAI5BAAAAAAAAAAAAAJBBAACNQgAAjUIASI1C + APONQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDNjkIAF4tFAACNQwAbjUIAWY1CALGNQgDxjUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDbjUIAVYpHAAKMQgAAjkMAAIBA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOQQAAiEIAAI1CAFeNQgAljkMAAJBDAAAAAAAAAAAAAAAA + AACNQgAAjUIAJI1CAOSNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDmjUIAKI1CAACNQgAAjEIAAI5C + AAyNQgBJjUIArI1CAPSNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA641C + AGqLRQAFjUMAAI5CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQQQAAkUAAAo1CAJyNQgBJjUIAAJFE + AAAAAAAAAAAAAAAAAACNQgAAjUIAFI1CAMeNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD0jUIAP41C + AACRRAAAoU0AAI1DAACNQgAAjEEADI1CAFeNQgDEjUIA/Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAPGNQgBxjUAABI1BAACMQgAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQQAAjUEAD41C + AL+NQgBljEIAAI5DAAAAAAAAAAAAAAAAAACNQQAAjEAABo1CAKeNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD6jUIAXo1CAAAAAAAAAAAAAIhEAACgOgAAjEIAAI9BAACMQwAajUIAhI1CAOqNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDxjUIAaIlCAAGMQwAAjUQAAAAAAAAAAAAAAAAAAAAA + AACMQgAAjEIAIY1CANqNQgCEij8AAIpFAAAAAAAAAAAAAAAAAACQQAAAjEIAAI1CAIaNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIAfo1CAACPRQAAAAAAAAAAAAAAAAAAi0QAAIlFAACMQgAAjEMAA41C + AEeNQgDHjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA6Y1CAFONPwAAkEMAAP8A + AAAAAAAAAAAAAI1BAACNQgAAjkIAM41CAPKNQgCjk0EAAZxHAACSSQAAAAAAAAAAAACQQQAAjUIAAI1C + AGSNQgD7jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAmo1AAACNQgAAAAAAAAAAAAAAAAAAAAAAAI5E + AACLQQAAjUIAAIxBAACOQgAijUIAp41CAP6NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + ANiNQgAzi0QAAIJJAAAAAAAAjUIAAI5AAACRQAACjUIAYY1CAP2NQgDJjkIAHKlqAACNQgAAjUIAAI5C + AAAAAAAAjUIAAI1CAECNQgDzjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAro1BAAiNQgAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAj0MAAJVDAACMQwAAjEIAFY1CAJ2NQgD+jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgCzjUIAEo1CAACOQwAAjUIARI1CAH2NQgCvjUIA4o1CAP+NQgD5jUIAyo1C + AJ2NQgBljUIAIIxCAAAAAAAAjUIAAI1CACaNQgDnjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAwI1B + ABKNQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJI/AACKQwAAjUIAAI1CABWNQgCojUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD6jUIAbog/AACOQwAAjUIAUo1CAJONQgDBjUIA7Y1C + AP+NQgD/jUIA9I1CALCNQgB0jEIAJIxCAAAAAAAAjEIAAIxCABuNQgDTjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA0o1CABqNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMQwAAjkEAAI1B + AACNQQAijUIAxY1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA1I1CACKNQgAAjEMAAHsr + AACOQwAKjUIAa41CAPuNQgD/jUIA8I1CAGSKOwABjUIAAI1CAACLRgAAjUMAAIxDABGNQgC/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA341CACGNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjEMAAIxCAACNQgAAjEIARY1CAOqNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/Y1C + AHSJRwAAmU0AAP++AACNQgAAjUIAMo1CAO+NQgDrjUIA941CAO6NQgBxjEMACI1CAACeQQAAjUMAAI1E + AAeNQgCrjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA6o1CACeNQgAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxCAACNQwAAjEQABY1CAJyNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAMaNQwAYAAAAAAAAAACOQgAAjkIAIo1CANqNQgCSjUIAmo1CAP+NQgD2jUIAko1C + ABqLQgAAjUIAAI4/AACNQgCYjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA741CAC+NQgAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQgAAjUIAAI1CAEqNQgD0jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPKNQgBVAAAAAAAAAACNQgAAjUIAEY1CAMKNQgBjjUIAHo1C + AMeNQgD/jUIA/o1CAL6NQgBDi0IAA41CAACNQgCBjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA8I1C + ADaNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjUIAAI1C + ACCNQgDdjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgCcAAAAAAAAAACLQgAAi0IAA41C + AKCNQgBHjUIAAI1CAD+NQgDdjUIA/41CAP+NQgDpjUIAiY1BACWNQgAzjUIArY1CAPKNQgD/jUIA/41C + AP+NQgD/jUIA8Y5CADiNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjUEAAI1BABqNQgDTjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDLAAAAAAAA + AACLQwAAikAAAI1CAGCNQgAojUIAAIxFAACNQgBUjUIA6I1CAP+NQgD/jUIA/41CANiNQgB6jUIANI1C + AE6NQgCbjUIA3Y1CAPyNQgD/jUIA8o5CADiNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACNQQAAjUIAAI1CAC+NQgDojUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgDkAAAAAAAAAAAAAAAAi0IAAI9FAAmQRQADkEYAAI5CAACQQgACjUIAXI1CAOeNQgD/jUIA/41C + AP+NQgD+jUIA2o1CAIeNQgA9jUIAL41CAGWNQgCxjUIA2I5CADaNQgAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA/wAAAIhEAACNQQAAjj0AA41CAIaNQgD+jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgDoAAAAAAAAAAAAAAAAi0IAAI5EAACPRAAAj0QAAI5CAACOQgAAkT8AAY1C + AFaNQgDfjUIA/41CAP+NQgD/jUIA/41CAP+NQgDpjUIAqo1CAFyNQgAsjEEAMY1BAA6NQgAAjUIAAI1C + AACRRAAAZRMAAJlNAAAAAAAAgFUAAJE5AACLQwAAjUEAAIxCAACNQgAJjUIAa41CAO6NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACOQgAAjkIAAH0sAACNQgA+jUIAxo1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPqNQgDXjUIAn41C + AGiNQgA6jUIAJI1CABKRRAAEjEEAAI5CAACNQgAAjUMAAI1BAACKQwAEjUEAHI1CAE6NQgCljUIA9I1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgCwAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjkMAAI5DAACNQwAAjUIAIo1CAJyNQgD1jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP2NQgDyjUIA3I1CAMONQgCujUIAmY1CAIONQgB2jUIAdo1CAImNQgCrjUIA0o1C + APaNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPmNQgBvAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJFDAACWSgAAjkIAAIxCAAmNQgBkjUIA141C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD+jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + ANCMQwAjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACLQgAAjUIAAI1C + AACJQQAAjkIAKo1CAJyNQgDvjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA941CAGWQPgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJBDAACRQwAAjUIAAI9BAAeNQgBHjUIAsI1CAPONQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD+jUIAl41BAAuMQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEIAAI5CAACOQgAAjUMADY1CAE+NQgCsjUIA641C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPuNQgCdjUIAFo1BAACOQQAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIpFAACRQAAAjUMAAI1C + AACMQwAJjUIAOY1CAISNQgDHjUIA8Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD9jUIA2o1CAHONQwAPjUMAAI1CAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAiUUAAJI/AACMQwAAjUIAAI4+AACOQQAVjUEAQY1CAICNQgC2jUIA4Y1CAPONQgD8jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD5jUIA6Y1CALqNQgBujUIAJa5EAACNQwAAjUIAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjUEAAIc7AACMQgAAkEYAAY1CAIqNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIAxI1CACyNQgCJjUIAqY1CAIGNQgBajUIAM41CABuNQgAGjUEAAI1BAACUPQAAjkMAAACa + AACOQgAAjkEACY1CAJ2NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAfIpD + AACQQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjUIAAIxCAACNQwAAjEIAJoxCADiNQgBUjUIA+I1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAOmNQgA8jUIAlo1CAP+NQgD+jUIA/I1CAO2NQgDHjUIAmY1C + AGONQQAnkj8ABopBAACMQwAAjkIAAI1CABONQgDBjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA9Y1CAFyNQgAAiUoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAi0UAAI5CAACLQgAEjUIAT41CAM2NQgCzjUIAPo1C + ANeNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD9jkIAVY1CAG6NQgD+jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD3jUIA3I1CAKqOQgBijkIAJqJKAAGNQwAYjUIA3I1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAOaOQgA+jkIAAJkzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAikQAAIxEAACSRAADjUIAaI1C + AOiNQgD/jUIA541CADaNQgCvjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AISNQQBPjUIA7o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA+41CANSNQgCOjUIAXY1C + AOWNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDZjkEAIo9BAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiEQAAI9B + AACWPgABjkIAXo1CAOmNQgD/jUIA/41CAPmMQgBajUIAfo1CAP2NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgC2jUEAMI1CANyNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAPGNQgD8jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAyJBB + AAuSQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJNBAACOQgAAjUIAPY1CAN6NQgD/jUIA/41CAP+NQgD/jUIAlI1CAEiNQgDxjUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA2I5CACaNQgDEjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAKuNQQAEi0MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5DAACMQwAAi0MAFY1CALSNQgD/jUIA/41CAP+NQgD/jUIA/41C + ALSMQgAqjUIA3o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAOeNQgA/jUIAn41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgCMjEIAAo1CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMQQAAkEkAAI1CAGeNQgD7jUIA9o1C + ANiNQgCkjUIAcI1CAFCNQQAvjUIAEo1CALSNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD1jUIAXo1CAHWNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD+jUIAbotHAACNQQAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjUIAAI5B + ABmNQgC7jUIAr41CAF+MQgAgjkEABYQ8AACNQQAAjUEAAJA9AAKNQgCEjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAHyNQwBIjUIA+I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/I1B + AE+NRAAAjT8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAIxDAACMQwAxjUIAUY1CABCNQgAAjEMAAI1BAACOQgAAjEMAAJk8AACLQwAAjkIAWI1C + APmNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgCajkQAGI1CAHyNQgDNjUIA9I1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAPiNQgA/jUIAAItCAACNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1DAACNQwAAiUgAApA6AACNQgAAh0gAAIxDAAAAAAAAAAAAAAAA + AACKRAAAjUIAAI1CADWNQgDgjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAt45D + ABOMRAAAjkEAG41CAFmNQgCijUIA5o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD+jUIAnI5CABqMQwAAi0sAAICAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQwAAjUMACo1DAByNQgADjUIAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1CAACNQgAVjUIAxI1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CANKNQgAhjUIAAI5CAACNPgAAjkMACo5DADSNQgCOjUIA2o1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPyNQgC1jEMAL487 + AACKSQAAjkMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACVQAAAjUIAAI1C + AC6NQgCIjkMAD45DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQPwAAkT4AAY1CAKmNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDsjUIALo1CAACPRgAAjVEAAI5DAACNQQAAlDsAAo1C + AC+NQgCHjUIA4o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAMaMQwA4kj4AAI9BAACZMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAlkAAAI1CAACOQgBCjUIAzY1CABmNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj0AAAI1C + AACNQgCFjUIA/o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA+o1CAEWNQgAAAAAAAAAA + AAAAAAAAkj0AAJE+AACOQQAAikAAA41CADiNQgChjUIA741CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA0I1CAD2KRwAAkD4AAI1CAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1BAACMQwAAjUIAXo1CAOyOQgAqjUIAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACNQwAAjUEAX41CAPmNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + APyNQgBljkIAAAAAAAAAAAAAAAAAAAAAAACIRAAAb1MAAIxBAACNQgAAikQAC4xCAFSNQgDHjUIA/o1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDNjUIAOI5C + AACMQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQQAAjD0AAY1CAICNQgD0jkIASI1C + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjUIAAI1CADqNQgDzjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jEIAhoRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEQAAIxE + AACNRAAAjUMAIo1CAJCNQgDtjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAMWMQgApjEMAAI9EAACNRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEIAAItC + AAWNQgCijUIA+o1CAGeNQgAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1BAACNQQAhjUIA4o1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAKaMQgACjEAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAIBAAACPQgAAikIAAI5DAACMQgAIjUIAV41CANKNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAsI5CAByNQQAAfkQAAP8AAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJQ/AACQQQAJjUIAw41CAP+NQgCGjEMAAINJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACNQQAAjEEAFY1CAMGNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDCjUEACIxB + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIBAAACQQwAAjUIAAIg7AACOQgAvjUIAtY1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgCRjEMACIpD + AACIQwAAAAAAAAAAAACKQgAAjEMAAIxDAACOQgAAj0IAGo1CANmNQgD/jUIApQDJAACPQgAAjUIAAI1C + AACHPwAAiUAAAAAAAAAAAAAAjUIAAI1CAAqNQgCgjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIAz41CABiNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJJJ + AAAeLwAAiUUAAI1CACGNQgCmjUIA/I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA8Y5CAGaROgACjkAAAAAAAAAAAAAAjkIAAItFAAKMRAALjkIAG41CAG6NQgDwjUIA/41C + ANeNQgBMjkQAFo1CAAmFUgAAjkIAAIpBAAAAAAAAAAAAAI5CAACCQAAAjUIAf41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CANqNQQAqjUEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA2RYAAJk7AACNQgAAjEMAGY1CAKiNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDZjEIAL41CAACOQwAAAAAAAI1CAEmNQgCEjUMAtY1C + AN2NQgD0jUIA/41CAP+NQgD+jUIA741CANiNQgCrjUIAeI1CADSTRQAAAAAAAAAAAACbWQAAjEEAAI1C + AGaNQgD9jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDkjUIAO41CAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi0QAAIxDAACMQwAgjUIAtY1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAJuOQwAJjkMAAIxE + AACOQgBZjUIAoo1CANGNQgDqjUIA+o1CAP+NQgD/jUIA/41CAP6NQgDmjUIAwY1CAI6MQgA7nUkAAAAA + AAAAAAAAkkkAAI1CAACNQgBTjUIA8o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA7o1C + AEyNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1C + AACNQgAAjUIAAIxBADCNQgDRjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgDrjUIASY5BAACKRgAAAKkAAI1CAAiPRAASjkIAMY1CAIaNQgDzjUIA/41CAP+NQgD3jUIAd41B + AA+KQgADkkMAAI5CAAAAAAAAAAAAAAAAAACNQgAAjUIAQI1CAOeNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAPaNQgBajUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1CAACLRAAAjEIAUo1CAOuNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAKWOQwAMjUMAAI9BAACNQgAAjkMAAI1CAACNQgAbjUIA2Y1C + AP+NQgD/jUIA/41CAOGNQgBcjEMABIxCAACMQgAAi0YAAAAAAAAAAAAAjUMAAI1DAC2NQgDbjUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD9jUIAZY1CAACZMwAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQgAAjEMAAIxDAAeNQgCUjUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDsjkIAPo1DAAAAAAAAAAAAAAAA + AACTPgAAkEAACY1CAMONQgD/jUIA341CAPKNQgD/jUIA641CAHCMQgAKjUIAAIpFAACMQwAAAAAAAI1D + AACNQwAajUIA0Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAHCMQwAAmjYAAAAA + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAG9SAACOQAAAmzYAAY1C + AGmNQgD2jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA2gAA + AAAAAAAAAAAAAAAAAACZTQAAmU0AAJ5PAAC+XgAAqlUAAAAAAACOQgAAjkIAAI5CAACOQQAMjUIAeo1C + AO2NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/I1CANqNQgCcjUIATo1CABqLQAATjEAAEItD + AACPQAAAjUIAAI1BAACNQgAAlEYAAIAsAACZTQAAAAAAAAAAAAAAAAAAgFUAAAD/AACLQwAAjkAAAI1D + AACKRAAAjUEAC41CAGaNQgDljUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAMIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACOQQAAjkIAAI5EAAaNQgBbjUIA241CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + APeNQgDLjUIAj41CAF2OQQAsj0EADI1CAAWNPwACjEEAAIxBAACNQgAAjUEAAI1CAACNQwAAjkEAAI1C + AACNQgAAjkEAAI89AAKNQwAPjUIARY1CAJ6NQgDyjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgCZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjkIAAI5EAACOQwAAAAAAAI5BADyNQgC7jUIA/Y1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD1jUIA4Y1CAMuNQgCpjUIAhY1CAGSOQgBLjUIAO41B + AC+NQgAmjUMAIY5BACGNQgApjUMANo1CAFKNQQCFjUIAxI1CAOuNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD3jUIAYwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEAAAIs/AACNQgAAjEIAHI1C + AImNQgDtjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/Y1CAPGNQgDgjUIA041CAMuNQgDLjUIA141CAOmNQgD9jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA0IxC + ACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAmEAAAI5CAACMQgAGjUIAVY1CAMaNQgD9jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/oxDAIOETQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhEAACYPgAAjUIAAIlAAACOQgAgjkIAiY1CAOeNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAMuNQgAkjUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJBDAACTRAAAjkIAAJJB + AAWNQgA/jUIApY1CAPCNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAOqNQQBRiUIAAI5BAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjkIAAJZAAACPQgAAjkMAAI1DAAyNQwBOjUIAso1CAO+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPKNQgBxikEABYtB + AACNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEAAAI9IAACNQgAAjkEAAI1DAA2NQgBRjUIApY1C + AOiNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AOuNQgBxjUEACYxBAACLQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjkIAAIpF + AACNQwAAkEEAAIxDAAuNQgA3jUIAgo1CAMaNQgDtjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA+41CAMaNQgBSjkUABY1CAACNQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAiUUAAIRIAACMQwAAjUMAAKcAAACMQgAUjUEASo1CAIaNQgDEjUIA8I1C + APuNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgDyjUIAvo1CAG+OQgAehkYAAI9BAACOQwAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5HAACINgAAjUIAAI1C + AACROwACjUEAFo5CADeNQgBvjUIApo1CAMmNQgDgjUIA8o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD7jUIA4o1CAMSNQgCTjUIARY1DABSQOAAAjkEAAHhNAAD/AAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJI9AAC9GwAAjkAAAI1CAACNQgAAjEEAAIc9AAOMQgAejUIAPY1DAFWNQgBvjUIAkY1C + AKyNQgDAjUIAzI1CAM2NQgDNjUIAw41CAKmNQgCNjUIAaI1DAD+MQgAYi0IAAY1CAACNQgAAjEQAAI85 + AACAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAH//+AAD+AAAf//wAAP8AAA///AAA/wAAD//8AAH/gA + AH//wAAf+AAAf//AAB/8AAB//8AAP/4AAH//gAA//gAAf/+AAD//AAA//4AAf/+AAD//gAB//4AAH/+A + AH//gAAf/wAAf//AAB//AAD//8AAH/8AAP//wAAf/wAA///gAA/+AAH//+AAA/4AAf//8AAADgAB///A + AAAAAAH//4AAAAAAAf/+AAAAAAAB//4AAAAAAAP//AAAAAAAA//8AAAAAAAD//gAAAAAAAP/+AAAAAAA + A//4AAAAAAAD//gAAAAAAAH/8BwAAAAAAP/wfgAAAAAAf+B+AAAAAAA/4H4AA4AAAB/gfwADwAAAH+B/ + AAP4AAAH4D8AAfgAAAPgPwAB/gAAAwADAAH/gAADAAMAAf/AAAEAAwAB//AAAAADAAH/8AAAAAOAAf/8 + AAAAAYAA//wAAOAAgAD//gAA4AAAAP//AADgAAAA//8AAOAAAAD//wAA4AAAAP//AADgAAAA//8AAPAA + AAD//gAA8EAAAP/4AADwQAAAA4AAAP/wAAAAAAAA//AAAAAAAAD//AAAAAAAAP//AAAAAAAA//8AAAAA + AAD//8AAAAAAAP//4AAAAAAA///4AAAAAAH///4AAAAAA////4AAAAAH////8AAAAA/////8AAAAHygA + AABIAAAAkAAAAAEAIAAAAAAAAFEAACMuAAAjLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj0AAAH5X + AACNQgBQjUIAq41CAK+NQgCvjUIAr41CAK+NQgCvjUIAr41CAK+NQgCvjUIAr41CAK+NQgCvjUIAr41C + AK+NQgCvjUIApI5BADWNRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjkQAAI5D + AAyNQgCCjUIApY1CAKONQgCjjUIAo41CAKONQgCjjUIAo41CAKONQgCjjUIAo41CAKONQgCmjUIAh41C + ABWNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj0AAAIxDAACMQwAnjUIAyY1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/Y1C + AIyCUQAApyEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAjkIAAI1CADeNQgDljUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAqoxFAAeLRgAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI4+AACPPgAAjEMAVY1CAPGNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAMOMRAATjEQAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2TwAAi0MAAI1CAGmNQgD2jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD4jUIAWo1FAACLRgAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAItGAACNQgAAjEIADI1CAJ2NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAOSNQwBCjUMAAIw/AAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACSPwAAnTcAAo1CAJaNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgDUjUIAHo1BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACIPwAAjkMAAI1CADmNQgDajUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP2NQgB0kEgAAIs9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACNQgAAjUIAGo1CALyNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgCMjEEAB41CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACKQAAAjz8AAJQ6AAKNQgB8jUIA+o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgCqjEEAEYxBAACAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5AAACMQgAAjEIAOY1C + AOGNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAO2NQgBMjUEAAItF + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEMAAI1C + AACNQgAgjUIAz41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgDfjEMALI1BAACAfQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5AAACMQwAAjUIAXI1CAPyNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAMSOQgAgjkIAAIxDAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI9FAACdXQAAjUMAcI1C + APuNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD7jUIAW45F + AACNQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1CAACOQwAGjUIAjY1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAJefTgACk0YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + AP+NQgDpjkMAKY1BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACOQwAAjkMAEI1CAKmNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CANWNQQAqjUEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjUQAAI1D + ABGNQgDKjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD5jEIAWJBB + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACNQQAAjUEAII1CAMeNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + ALeOQAAIjkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEIAAIxBAAONQgCKjUIA/o1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD9jUIAjI1CAAGGPgAAhFsAAIVP + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKM4AACNQgAAjUIALo1C + AOSNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/Y1CAImPOAAAjUEAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEAAAI5DAACNQgBDjUIA9Y1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAvYlGAAiXSQAAjkAAAI1CAACNQgAAjUEAAIlA + AACKQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAItCAACOQgAAjUIARI1CAPqNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA941CAFyOQgAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACKQgAAiUIAAI1CAACNQgAcjUIAxo1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA2YxCACqMQQAzjUIAXo1CAEiMQgAwjUEAFXAyAACNQgAAjUIAAI1C + AACNQQAAjz8AAH5JAAD/AAAAAAAAAI5CAACXPwABjkIAao1CAP6NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA8I1CADCNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1B + AACMQQAAj0EAAIpCAASNQgAKjUIAj41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA7Y1CAFONQgBZjUIA9I1CAOmNQgDUjUIAvY1CAJuNQgBrjUIAN45DABGMQAAEjEMAAI1C + AACQQgAAeFAAAI1CAACNQQAFjUIAkY1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA2o5BABiNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgEAAAIpBAACMRAAAjEIAJ4xC + AIuNQgBLjUIAX41CAPaNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AHuOQwArjUIA741CAP+NQgD/jUIA/41CAP+NQgD3jUIA641CAMqNQgCGjUEAR45CAB+WQgADi0QAAJJC + AACNQgAJjUIAuI1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAto1B + ABCNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAACKQwAAjUAAAHxAAAGNQgBHjUIAxY1CAP6NQgCXjUEAOI1C + ANqNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAJ+OQQAhjUIA041C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA841CAMSNQgCIjUIAQZFDAAqNQwALjUIAzY1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAlI9CAAiOQgAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAIhFAACNRAAAzkUAAI1CAFSNQgDcjUIA/41CAP+NQgDKjEMAH41CALqNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAMSMQQAujUEAp41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA5Y1CALONQgBtjUIA2o1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAdJw0AAGPQAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiEQAAI9B + AACERwAAjkIASI1CANuNQgD/jUIA/41CAP+NQgDljEIAPY1CAIaNQgD9jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAOmNQQA7jUIAe41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD6jUIA/Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD9jUIAV4tCAACUQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj0IAAI5DAACOQwAnjUIAyY1C + AP+NQgD/jUIA/41CAP+NQgD5jUIAboxCAE2NQgDzjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP2NQgBSjUIAV41CAPyNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgDrjUIAQo1CAACUQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMQAAAi0MAAIpEAAyNQgCajUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIAmIxCACaNQgDkjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgB5jUEAQo1CAOeNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDWjUIAMY1C + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACMQAAAjkYAAI1CAFSNQgDujUIA/41CAP+NQgDqjUIAvY1CAJ6NQgCJjUIATI1C + ABSNQgC+jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgChjUIAMY1C + AMyNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDCjUIAII1CAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACNQgAAjUEAE41CALSNQgDyjUIAv41CAHONQgA7jkEAG45EAAmSQQAAjUIAAI1AAAaNQgCNjUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDJjkIAH41CALKNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgCvjkAAD45AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQwAAjUIAQ41C + AKmNQgBNjEMADolFAAGNQgAAjkIAAI5DAACIQgAAkEAAAIhFAACOQgBcjUIA/Y1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDkjkMAHo1CAG6NQgDsjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgCZ46gAAIg8AACOQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACLQwABjEMAKY1DABiNQgAAjUIAAIxD + AACMQgAAjEIAAAAAAAAAAAAAAP8AAIxDAACNQgA7jUIA541CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgDtjkMAPI9DAA2NQgBMjUIAkY1CANiNQgD6jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgChj0UAB41DAACOQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1DAACNQwAAjUEAAI1DAACNQwAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA/wAAAI1CAACMQwAhjUIAw41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD0jkIAXY5CAACMQwAAjkEAB41EACOOQwBjjUIAto1CAO2NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDujUIAgI1C + ABOMRAAAjjoAAICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI1DAACNQwAejUIAJo1BAAGNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5B + AACPQAAIjUIAoY1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD7jUIAfY1C + AACRPgAAjUIAAI1BAACIOAAAj0MADo1DAFCNQgCmjUIA6o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA+o1CAJ2MRAAgjjwAAIdQ + AACIQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlUAAAI1C + AACNQgBcjUMAhI5DAAaOQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI9AAACMQwAAjUIAhI1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAm45DAACIPAAAAAAAAAAA + AACRRAAAkUMAAItFAACOQQAPjUIARo1CAKuNQgDzjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPyNQgCtjEMAJZBBAACgHwAAmTMAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmUAAAIxCAACOQgB8jUIAwY1C + AAqNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI9AAACNQgAAjUIAY41CAPSNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAs45CAAqOQgAAAAAAAAAAAAAAAAAAkj0AAK4h + AACOQQAAjkIAAIxBAA+NQgBYjUIAv41CAPmNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD+jUIAuoxCACiIRwAAhlIAAIBAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjkEAAI8/AASNQgCWjUIA4I5CABSOQwAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQQAAjUEARI1CAOeNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIAxY1CAB6NQgAAAAAAAAAAAAAAAAAAAAAAAAAAAACMQgAAikIAAI1B + AACNQgAAi0QAHIxCAHmNQgDfjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/o1CALSNQgAmj0IAAIlBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjUEAAI1BABONQgCwjUIA6o5DAC+OQwAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACMQQAAjEEAI41CANqNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA14xCADSMQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACnQQAAjUMAAIxB + AASNQwA8jUIAtI1CAPeNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP2NQgCujEIAG45BAACOQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD/AAAAjEEAAIxBACONQgDKjUIA8Y1CAE2NQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACTQAAAkEEACY1CAMeNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA6oxC + AEmMQgAAjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQAAAkUMAAIxCAACNQQAAjEIAFI1C + AHeNQgDjjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD9jUIAmI5BABOOQQAAjkMAAIhEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+UAAAjUIAAI1C + ADKNQgDkjUIA+I1CAGqOQgAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACVQAAAjUAAA41B + AKeNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA+41CAF6NQgAAijwAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhCAACPQgAAjUIAAJFCAAWOQgBKjUIAyo1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA941C + AHuMRQAGj0IAAJU/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACbPwAAi0IAAI5CAEWNQgD5jUIA/41C + AIiJRQAAWWIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEIAAo1CAICNQgD9jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAHWNQgAAjUIAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj0IAAI9BAACHQQAAjkEALY1CALCNQgD+jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAOuNQgBXc0wAAJBB + AAAAAAAAAAAAAAAAAACJQgAAjEMAAIxDAACMQwAAiUMAAI1CAGWNQgD/jUIA/41CAKWSQQAEjUEAAI1C + AACNQgAAikEAAItBAAAAAAAAAAAAAAAAAAAAAAAAiUMAAI1CAFuNQgD6jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAImMQgAFjUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAItCAACORAAAjEIAAIxCACKNQgCnjUIA/o1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDRjUEALo1AAACMPwAAAAAAAAAA + AACPQgAAi0QABYxDABGNQgAhjUIAR41CAL6NQgD/jUIA/41CAN6NQgBrjkMAK41CABeOQwAJkUQAAI1C + AACNQgAAAAAAAAAAAAAAAAAAjEIAAI1CADeNQgD2jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAJ2NQQAMjUEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjEIAAI1CAACNQgAfjUIAro1CAP6NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAnItDAAuMQwAAjkMAAAAAAACNQgBMjUIAiI1C + ALWNQgDhjUIA9o1CAP6NQgD/jUIA/41CAP+NQgD6jUIA7Y1CAMeNQgCZjUIAZI1CABqNQgAAAAAAAAAA + AAAAAAAAjEIAAIxCACWNQgDnjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + ALGNQQATjUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjEMAAIxDAACMQwAAjEMAJo1CALmNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA7Y1CAFiFOwAAjkMAAAAAAACOQgBbjUIAqI1CANWNQgDzjUIA+o1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA9Y1CAN6NQgCzjEIAdYxCABuMQgAAAAAAAAAAAAAAAAAAjEIAAIxC + AB2NQgDRjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAMWNQgAZjUIAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1C + AACMQwAAjUIAAIxBADiNQgDYjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CALuNQgAWjUIAAAAAAACZPAABjUIADY1DABqOQwA1jUIAaY1CANGNQgD/jUIA/41C + AP+NQgD8jUIAi41BACCNQgAQhEIAApJDAACTQwAAAAAAAAAAAAAAAAAAjUIAAIxCABaNQgC6jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CANWNQgAfjUIAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjUIAAIhI + AACMQgBZjUIA7I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + APeNQwBbjj4AAI9AAACQQQAAjUIAAI1CAACMQQAAi0UAAI1CAGmNQgD/jUIA/41CAP+NQgD/jUIA3I1B + AFKNPQADjEEAAHc/AACAQAAAAAAAAAAAAAAAAAAAjEMAAIxDAA6NQgCkjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAOONQgAjjUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjkIAAIxCAACLQwAKjUIAk41C + AP6NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgC5j0AAEI9A + AAAAAAAAAAAAAAAAAACTOQAAjEMAAI1BAESNQgD5jUIA/o1CAPmNQgD+jUIA/41CAOONQgBli0MAB41D + AACPQAAAi0YAAAAAAAAAAAAAjUMAAI1EAAeNQgCPjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAPCNQgAojUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxDAACMQwAAjUMAM41CAN6NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDrjUIAS45AAAAAAAAAAAAAAAAA + AABzTAAAjUIAAI5CADONQgDkjUIA941CAKKNQgDMjUIA/41CAP+NQgDvjUIAfI1EABSOQQAAikkAAHpP + AAD/AAAAjUMAAI84AACNQgB5jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + APeOQgAvjEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACJSQAAjEUABI1DAJqNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAkYdKAAQAAAAAAAAAAAAAAAD/AAAAjkIAAI5D + ACWNQgDNjUIA8Y1CAFCOQgBXjUIA7o1CAP+NQgD/jUIA9Y1CAKSNQgAoiUAAAItDAACgYAAAi0YAAI1B + AACNQgBnjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPeNQgA3jUIAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACMRAAAjEQAAI1BAE6NQgD4jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIAy41CACoAAAAAAAAAAAAAAAAAAAAAjUIAAI1BABaNQgC0jUIA6o1C + AC+MQQAGjUIAio1CAPuNQgD/jUIA/41CAP+NQgDLjkIAUY5AAAqOQgAAf0AAAI1CAACNQgBXjUIA9Y1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPiOQgBAjEIAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjUIAAI1CACWNQgDijUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA9o1DAFYAAAAAAAAAAAAAAAAAAAAAjEMAAIpEAAeNQgCbjUIA3oxDABOOQgAAjEIAG41C + ALKNQgD/jUIA/41CAP+NQgD/jUIA7I1CAJONQgApnkUAAIxBAACMQQA9jUIA3o1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPiOQgBDi0MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjkIAAI5C + ABuNQgDJjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AIsAAAAAAAAAAAAAAAAAAAAAij8AAI9DAACNQgCCjUIAv41BAAmLQAAAkUQAAI1CAC6NQgDHjUIA/41C + AP+NQgD/jUIA/41CAP6NQgDMjEIAbY9AABeNQgAKjUIASo1CAK+NQgDwjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAPiOQgBDi0MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjUEAAI1BABuNQgDMjUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CALUAAAAAAAAAAAAA + AAAAAAAAikAAAI1CAACNQgBkjUIAjY1CAAaNQgAAiz8AAIpEAACNQgA8jUIA2I1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA+I1CAMSNQgBejUEAHI1GAA2NQgBMjUIAqY1CANuNQgD8jUIA/41CAP+NQgD/jUIA/41C + APiOQgBDi0MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjUIAAI1CACqNQgDmjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CANEAAAAAAAAAAAAAAAAAAAAAAAAAAI1D + AACNQwAmjkMAMY9EAAKORAAAjkEAAI5CAACRQgABjkIAUI1CANuNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD2jUIAv41CAG2MQwAeikQACYxBADWNQgBwjUIAt41CAPCNQgD+jUIA/41CAPqOQgBDi0MAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJI9AACTOgAAkj0AAI1DAGaNQgD7jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CANwAAAAAAAAAAAAAAAAAAAAAAAAAAHs0AAB8NAAAgjsAAIZA + AACEPQAAAAAAAI5CAACOQgAAj0IAAo5CAEyNQgDZjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + APeNQgDPjUMAgI1DAC2ORAAMj0EAEY5CAD6NQgCHjUIAzo1CAOaOQQBBikMAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi0YAAJFB + AACJRQAAjEEAJY1CAMuNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CANkAAAAAAAAAAAAAAAAAAAAAAAAAAJlNAACZTQAAoFAAAP+EAACqVQAAAAAAAAAA + AACOQgAAjkIAAJ83AACOQgBIjUIA1I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/o1C + AOaNQgChjUIAVoxCAB6IQgADjEEAFIxBAEuNQQAdiUIAAJM7AACSPQAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi0YAAJI4AACMRAAAjkIAAJA9AACNQgAhjUIAqY1C + AP2NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AMYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjkIAAI5C + AACQQgABjUIAPI1CAL+NQgD+jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA8o1C + AMeNQgCNjUEAQ4tBABONQQAGYVsAAIxDAACNQgAAjUEAAI1CAACRQwAAm1AAAJlNAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI88AACGSgAAjEEAAI5BAACPPwAAkUAACI1BAD+MQgC4jUIA+41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAKUAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5CAACOQwAAjD4AAIxB + ACCNQQCfjUIA9Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD+jUIA741C + ANWNQgCfjkIAZY1CAEGNQgAujUEAH41CAA6fRwACi0AAAI1CAACNQQAAjUIAAI1DAACOQQAAjUIAAI1C + AACSPAAAjEEADY5BACiNQgBUjUIAoY1CAOaNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/o1CAHMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACORAAAj0UAAIxAAACQQgASjUIAdY1C + AOONQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + APaNQgDcjUIAwY1CAKaNQgCSjUIAf41CAGyNQQBZjUIATY1DAESOQQBEjUIAUY1CAGKNQgCAjUIApI1C + ANGNQgD5jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA5o1BAEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqlUAAIo+AACOQgAAiEMABI1CAEKNQgC+jUIA/I1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAPmNQgDwjUIA6o1CAOWNQgDljUIA7I1CAPWNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIArYxDABUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACLQgAAjEIAAJBCAACOQgAfjUIAho1CAOONQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDxjEMAW41C + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAj0EAAJs/AACOQgAAkUMABY5CAEiNQgC5jUIA+Y1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgCpjEMAEIxDAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACPQgAAj0IAAI5CAACPQgAXjUIAbY1CAM6NQgD6jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CANaNQQAxjEIAAIxDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjkIAAI5CAACNQgAARQAAAI1CACONQgB8jUIA1Y1CAP6NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA5I1CAFV/NwABi0EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACMQAAAll0AAI1DAACHSQACjUIALY1CAICNQgDXjUIA+I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDnjUIAYY1E + AAaMQwAAi0EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAItE + AACLRAAAjkIAAI9DAAOMQwAgjUIAbo1CALeNQgDpjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAM+NQwBSjkEAA41DAACNQwAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQwAAjEQAAI5C + AACNQQAAh0oAAI1BABSMQgBJjUIAhY1CAMiNQgD1jUIA/Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP6NQgDqjUIAlY1BAC9/XAABjEQAAI1CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACZMwAA7gAAAI1C + AACMQQAAi0IABI5BABqOQQBDjUIAh41CAMWNQgDijUIA9o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDyjUIAzo1C + AIaNQgA4jUQACYlEAACNSAAAi0YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5HAACSUwAAjEIAAI1B + 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 + APqNQgD6jUIA+o1CAPqNQgD6jUIA+o1CAPqNQgD6jUIA+o1CAPqNQgD8jUIA3Y5BAFuOQQAAi0YAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjkQAAI5EACiNQgDXjUIA+41CAPmNQgD5jUIA+Y1CAPmNQgD5jUIA+Y1CAPmNQgD5jUIA+Y1C + APmNQgD5jUIA+Y1CAPmNQgD5jUIA+Y1CAPmNQgBqgF0AAYtGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAItFAACZLAAAjUIAVo1CAOeNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA+Y1CAJWPPgAAikcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAjkIAAI1CAF6NQgDpjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CANONQgA/jUIAAItG + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAItG + AACLRAAAikUAEI1CAIqNQgD+jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAL6MRQAXjEQAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABOZgAAhUcAAI1C + AJKNQgD1jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAJmMQQAWjEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACLRAAAjUIAAI1CADiNQgDGjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + ANmOQgBLjkIAAIk7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACZOwAAnzcABI1CAL+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA9I1CAGKKPgAAkkkAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAikAAAHAv + AAGNQgBujUIA8o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPONQwCAj0UAAIU2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOQQAAjkEAKo1CANiNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAwI1B + ADKNQQAAkkkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAikAAAI1CAACNQgAijUIAq41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgCuiz0ADIw/ + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACNQgAAjUIAXI1CAOaNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIAiotEAAmMQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMQAAACJRwAAjUIAV41C + AOGNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgDOjEEAPIxCAACAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5AAACNQgAAjEIAjo1CAPSNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDnjUIAWI1CAACMQwAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJkzAACOQAAAjUAAEY1CAJyNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDsjEIAbo0+AACZBgAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI4/AACPPAAEjUIAuo1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgC7jkEALY5BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQQAAjUMAAI1DAE6NQgDbjUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIAnItGAASMQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI5CAACOQgAojUIA041CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgCTk0YACZBEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAj0QAAJFGAAyNQgCajUIA/I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAwY1BACyNQQAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1CAACNQgBZjUIA441CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAO+NQgBoiT8AAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj0QAAI5CAACOQgBIjUIA141CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA445C + AFyOQgAAj0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiUAAAIxB + AACNQQCJjUIA841CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAMqMQgA8jEIAAKpVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJBB + AACSQAAIjUIAnI1CAPyNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/o5CAItmcwAAj0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAiD8AAH87AAONQQCzjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAKWKRAARi0MAAAAAAAAAAAAAAAAAAAAA + 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 + AAAAAAAAAAAAAAAAAACNQgAAjUEAI41CAMWNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD0jUIAfZBDAABtPAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlUAAAI5BAACNQQAyjUIA1o1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDjjEIAVYxC + AACJOwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQQAAjUEARo1CANaNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDcjEEAU4xB + AACAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI4/ + AACPPAADjkIAqI1CAPuNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIAeZNNAACJOwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACNQwAAjUMAZ41CAOaNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgDDjkMAKo5DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + AACNQQBSjUIA241CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CALGRPgAFjkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjkcAAI5GAAGNQgCWjUIA9o1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAMCMQgAxjEIAAIBV + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAiEQAAI1BAACNQQBujUIA7I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA9Y1CAImNQgAAj0AAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxB + AACMQQBQjUIA6Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAOWOQQBMj0AAAIVAAACFSwAAdPAAAICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhkUAAI5CAACNQgCKjUIA/I1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA5I1C + AGGNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxAAACMQAASjUIA041CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgBqnTIAAH8vAAGUOQAAjUAAAI1C + AACMQgAAjkEAAItAAACKQAAAikAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAi0MAAIdEAASNQgCjjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA1YxCADyMQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxAAACNQgACjUIAmY1C + APeNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgCPi0EAEYs/ABuMQwAyjUMAK41CACGMQgAYjkEADog+AAKOQgAAjkIAAIxBAACPRAAAj0QAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj0EAAI9BACCNQgC3jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAxY1EABeNRAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACKQgAAikIAAIxCAACLQgAAjUMAUo1CAO6NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgC3jUIAJo1BAFGNQgDbjUIA5Y1CAMCNQgCejUIAfI1C + AFKNQgA1jkIAJIxBABSRRgADjUIAAI1BAACMQQAAAP8AAP8AAAAAAAAAAAAAAAAAAAAAAAAAjkIAAI5C + ADuNQgDLjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIAr4NPAACbMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1BAACNQQAAhUIAA4xCACeNQwAWjkEAHo1CAOCNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDejUIAP41E + ACiNQgDPjUIA/41CAP+NQgD/jUIA/41CAP+NQgDqjkIAvY1CAI6NQgBcjUIAOI1BAB6LQAAHiEQAAI5C + AACPQgAAV2MAAP8AAAAAAAAAjUEAAI1BAFeNQgDfjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD2jUIAkI1CAACZMwAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQAAAoEUAAI1CAACNQQAQjEIAU4xC + ALqNQgBsjUIAEI1CALaNQgD7jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD9jUIAWZlGAAaNQgC8jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA441BAKaNQQBsjkEAP45CACGRQwAGiEUAAI9DAACYQwAAjUIAAI1CAHKNQgDyjUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDqjUEAb41C + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJJJ + AACNgwAAkEMAAI1CACGNQgB+jUIA6I1CAP+NQgCxjUIAGY1BAHqNQgD1jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAe6A+AASNQgCejUIA+41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA5I1CAKqNQgBvjkIAPI5E + ABOFQQAAjUMAAI1DAIGNQgD9jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgDfjkMAT45DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA/wAAAF5MAACLPgAAjUIAKY1CAKGNQgD3jUIA/41CAP+NQgDljUIAJoxD + AD6NQgDwjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIAooxCABqMQQB1jUIA7Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA1o1CAJGOQgBXjkMAIY1CAIuNQgD9jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDVjkAAMI5BAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgUoAAIhGAACPQgAljUIAp41C + APqNQgD/jUIA/41CAP+NQgD9jEIASoxEABeNQgDajUIA/o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAyYxBAC6OQQBNjUIA4I1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDvjUIAsI1C + AMmNQgD9jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgDLkT8AE5BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACOQwAAj0IAAJBBAByOQgCZjUIA9o1CAP+NQgD/jUIA/41CAP+NQgD9jEIAhIxCABONQgCmjUIA+o1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA741B + AESNQQAkjUIA041CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgC6RUwAAJdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhEAACNQwAAj0QAC41CAH6NQgDxjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD+jUIAv41CABiMQgBpjUIA9o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAGCQQAAJjUIAwY1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPmNQQCejkEAAJVA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAINFAACTQQAAjUIAVI1C + AN6NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA7o1DACmMQQAzjUIA8o1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAIGQQQALjUEAoo1C + APqNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAPCNQgCBjUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjEAAAIxDAACLQwAnjUIAso1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA841D + AECLQQAWjUIA241CAP6NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAKKMQwAajUEAfY1CAPCNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAOmMQgBljEIAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEAAAIo5AAONQgB0jUIA9Y1CAP+NQgD/jUIA/41C + APKNQgDCjUIAlo1CAHqNQgBijUEAT41DABiNQgAMjUEArY1CAPyNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAMSNQgApjUIAWI1CAOaNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AOGNQQBJjUEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACPQAAAjUIAAI1C + ADKNQgDBjUIA/41CAPWNQgC/jUIAe41CAEuOQQAtjUIAF49FAAmYQgAAjkEAAI1DAACNQQAHjUEAeY1C + APmNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AOWNQgA3jkMAMY1CANyNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CANmOQAAujkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACPQAAAmDcAAo1CAHSNQgDrjUIAoI1CAE2MQwAni0MADI5CAACOQQAAjUIAAI5E + AACIQgAAej4AAJFBAACPQQADjkEARI1CAPaNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+OQgBJjUkACo1CAMiNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CANGKPQASiz4AAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMQwAAjEMAJo1DAHiNQgBdjUIAF3tU + AACMQwAAjEMAAIxCAACMQgAAAAAAAAAAAAAAAAAAAAAAAJo7AAClNgAAkUAAHI1CAOiNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQwBki0oABY5D + AE+NQgC/jUIA+o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAMT//wAAhDoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACMRAAAjEQADoxEAByNQwAGjUIAAIxDAACMQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE9n + AACHRgAAjkEAEI1CAL2NQgD9jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQwCCjkMAEJBDAAaNQgAhjkEASY1CAJWNQgDhjUIA/Y1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAM+ORAAZjkQAAI5CAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACJTQAAiUwAAJknAACNQwAAjUMAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAACNQgAAjEMAC4xDAIqNQgD8jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+OQwCgjkMAGo5DAACNQgAAkT4AA41C + ABONRAApjkMAZY1CALeNQgD3jUIA/o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + APeNQgCsjkIAKpFCAACNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1DAACNQwABjUMAA41C + AAGNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOQQAAjkEABY1C + AFeNQgD6jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgC9jUEAJI1BAACPQAAAj0AAAI1BAACPMAAAj0QACI1CABmOQwBHjUMAqY1CAPKNQgD8jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD6jUIAxI1CAEiYNAAAkC0AAICAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI1DAACNQwArjUMAbY1CACuNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACPQAAAkD8AAY5BAC2NQgD4jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDajUIALo1CAACMQAAAAAAAAH6GAACLVgAAj0QAAIpB + AACQRAAEjkIAE45BAD6NQgCijUIA7o1CAPyNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/o1C + ANOMQwBZgm8AAZRGAAB/VQAAgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlUAAAI1CAACNQgBDjUIAt45DAFSOQwAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACPQAAAjUIAAI1CABqNQgDhjUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD2jUIAOY1C + AACMQAAAAAAAAAAAAAAAAAAAkUQAAJJEAACQQwAAh0oAAJA/AAOMQwAOjEIAPI1CAKuNQgDzjUIA/Y1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDbjEIAZIZPAAWSTAAAfzwAAJkzAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkAAAI1C + AACOQgBSjkIA541CAHGNQgAAkEMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACPQAAAjUIAAI1CABSNQgC9jUIA/o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIATYs7AAGNQQAAAAAAAAAAAAAAAAAAAAAAAAAAAACSPQAAlToAAI1B + AACbOwAAjEEAAotCABGNQgBWjUIAxY1CAPeNQgD+jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA4o1C + AGyEQAAGhkYAAKwAAACAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAkkAAAHlJAACOQgBkjUIA/41CAImMQgAAkEMAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjUEAAI1BAA+NQQCXjUIA/Y1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jkIAao9DAAmOQwAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhEAAB+SgAAikIAAIdCAACOQAACjEQAG4xDAHeNQgDYjUIA+o1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAOKNQgBnkTwABZJAAACeRQAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjUEAAIxAAAyNQgB/jUIA/41C + AJyTRAAGj0MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjUEAAI1B + AAmNQQBxjUIA/Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jEIAh4xCABGMQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACLRAAAjUUAAH5DAAKMQgA0jUIAqI1CAPGNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDgjUIAYYlB + AAWLQgAAjEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjkEAAI5BABqNQgCbjUIA/41CAK+OQwAcjkMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAi0EAAItBAASMQQBMjUIA/I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jEIApoxCABqMQgAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgEAAAJlEAACQRwAAjkQAEY1CAHKNQgDVjUIA+o1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA141CAFOIQgACjUIAAI5BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEEAAIxBACiMQgC2jUIA/41CAMGOQgAxjkIAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlUAAAGJMAACPQQAqjUIA941C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jEIAw4xC + ACKMQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACORAAAfj8AAKFFAACNQgA3jUIAqo1CAPGNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAMeNQgBBlTwAAY5C + AACNRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAjEIAAIxC + ADaNQgDSjUIA/41CANONQwBGjUMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAlUAAAI1BAACNQQAdjUEA3I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA4Y1CACqNQgAAjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgEAAAKBFAACOQgAAkEIAE41CAICNQgDejUIA/o1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgC2jkIAL44yAACLRQAAiEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAA5egAAi0MAAI1CAEONQgDujUIA/41CAOWNQgBcjkIAAP8AAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1BAACNQQAXjUEAt41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA+o1CADWOQwAAjD8AAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACPQgAAkEUAAKZmAAGNQgBZjUIAyY1CAP2NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAmoxDABqSQQAAlzUAAP8A + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACbPwAAgUUAAI5CAFSNQgD/jUIA/41C + APeMQwBxikQAAFBnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxC + AACMQgAQjUIAk41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAEqNQgACjUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkkkAAKFFAAB+SwAAjUIAP41CALyNQgD8jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA941CAHaQQQAMh0UAAHtLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlUAAAJo/ + AACPQQAAkUMABo5CAG6NQgD/jUIA/41CAP+NQgCHhEUAAJFEAACUTAAAkkkAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5CAACOQgAKjkIAcI1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAF+NQwAHjUMAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A + AABUYwAAjUIAAIxCADSNQgCyjUIA+41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAOKOQQBQjzwABI1BAACLRgAAAAAAAAAA + AAAAAAAAikIAAItCAACNQwAAjEMAAItDAACyLwABjUIAL41CAKiNQgD/jUIA/41CAP+NQgC2jUIANJVL + AAaLPwAAjUIAAI5DAACMQgAAiD8AAIlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5BAACOQQAEjUIASo1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41B + AHWMQQAMjEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEIAAIxCAACMQwArjUIAtI1CAP2NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgC8jEIAJ447AACKTAAAAAAAAAAAAAAAAAAAjkIAAIlCAAqNQwAljEMAQYxDAF6NQgB8jUIArY1C + APCNQgD/jUIA/41CAP+NQgDxjUIAuY5DAISNQgBljUIAR45DACmLQQAMkUQAAIxCAACNQgAAAAAAAAAA + AAAAAAAAAAAAAJNMAACHOgAAjUMAL41CAPiNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAIqNQQARjUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxD + AACMQwAAjUIAMo1CALyNQgD+jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD+jEIAeYtBAAyMQgAAjkMAAAAAAAAAAAAAjUIAUY1C + AJONQgC0jUIA041CAPKNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD4jUIA2o1C + ALmNQgCZjUIAY41CABCNQgAAAAAAAAAAAAAAAAAAAAAAAJJJAACNQgAAjEIAJY1CAOWNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAJ+NQQAVjUEAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQgAAjkEAAIxDADuNQgDMjUIA/o1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA3o1C + AD2QRQACjkMAAAAAAAAAAAAAjkIAW41CALKNQgDUjUIA8o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA8o1CANONQgCxjEIAbIxCABGMQgAAAAAAAAAAAAAAAAAAAAAAAAAA + AACNQgAAjEIAII1CAM2NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CALWNQQAajUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEMAAIyB + AACMQQBRjUIA441CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAJuNQgATjUMAAIxEAAAAAAAAmT4ABI5BACONQgA/jUMAW45D + AHmNQgCbjUIAyo1CAPyNQgD/jUIA/41CAP+NQgD/jUIA/41CAMyNQgB+jkEAWY1CAD6LQgAffkAAA5pE + AACpRgAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQgAAjEIAGo1CALWNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAMiNQgAfjUIAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIZZAACOPQAGjUIAb41CAPSNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAOyMQwA/ikYAAoxE + AAAAAAAAkkAAAI5BAACNQgAAjEIAAP+2AACOQgAWjUIARo1CALiNQgD/jUIA/41CAP+NQgD/jUIA/41C + ANaNQQBKkUQAAI1BAACLQgAAiEEAAHE9AACAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMQwAAjEMAFY1C + AJ6NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + ANaNQgAijUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI46AABviAAAjEIAEoxC + AJyNQgD+jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgCYjkMAEI5CAACPQAAAAAAAAAAAAACZTQAAoFMAAJNHAACNQgAAikIABY1C + AHGNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDMjUEATY08AAWNQQAAjEMAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACNQwAAjEMAEI1DAIWNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAOWNQgAljUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAIxCAACMQgAAi0UAAY1DAC+NQgDajUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDqjkEAN5E+AAKPQAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACSOQAAiUgAAI1BAFONQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA141C + AF2LRAAJjEMAAIxCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQwAAjUMACo1DAG6NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPSNQgAojUIAAJkz + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMQwAAjEMAAI1DAAiNQwB4jUIA/o1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIAg41BAAyNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeegAAjEMAAI5CAESNQgDujUIA/41C + AOqNQgDJjUIA5o1CAP+NQgD/jUIA/41CAOGMQgBwjEIADoxDAABtcwAAi0YAAAAAAAAAAAAAAAAAAAAA + AACNQwAAjUQABY1CAFiNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP2OQQAtiUcAAJkxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjEUAAIhKAACNQwApjUMA3o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD+jUIA1YtFABqcLAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD/AAAAjUMAAI1DADeNQgDUjUIA/41CANWMQgBfjkIAkY1CAPyNQgD/jUIA/41CAP+NQgDqjUMAko1E + ABySOgAAi0UAAIxDAAAAAAAAAAAAAAAAAACMRAAAc4IAAI1DAEGNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+OQwA1cSsAAJNHAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEQAAI1DAACNQgAQjUIAlI1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA94xD + AFCLRAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjkIAAI5CACqNQgC6jUIA/41CAMKNQgAxjkIAKY1C + ALuNQgD/jUIA/41CAP+NQgD/jUIA9I1CALmMQwA4jEMABItDAABbYQAA/wAAAAAAAACKRwAAjUEAAI1C + ADKNQgD4jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+MQgA9h0AAAYtBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI4/ + AACPPgAEjUEAS41CAP6NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/Y5CAJ+OQgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjUEAAI1B + AByNQgCgjUIA/41CALCOQQAdi0QAAIxCAFWNQgDZjUIA/41CAP+NQgD/jUIA/41CAPuNQgDYjkMAY5U/ + AAudNwAAhkQAAIpCAACLRgAAjUIAAI1CACuNQgDkjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+OQwBGj0UAA45DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJA7AACMRAAAjUIAKI1CAOiNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/o1CAOGLRQAaAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjEMAAIxEAA+NQgCFjUIA/41CAJyKSAAGjEMAAIZBAAWNQgCAjUIA8I1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA641CAKaLQgAsjEIABYhBAACAQAAAjEEAAIxBACWMQQDOjUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+OQgBKkkEABJBB + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI89AACOQgAAjkIAHo5C + AMiNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAPWNQwBJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAikEAAIQ+AAONQgBsjUIA/4xC + AIaMQQAAiEcAAI5BAACLQQATjUIAnI1CAPiNQgD/jUIA/41CAP+NQgD/jUIA/41CAPiNQgDajUIAbIpC + ABCNQQADiUQAAI1CABSNQgCOjUIA9o1CAPyNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+OQgBLkkAABJBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACNQQAAjUEAG41BALiNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPmNQgB6AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAikAAAI1CAACNQgBXjUIA7I1BAG2NQQAAiUUAAIg/AACTRAAAjkEAH41CALCNQgD8jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD+jUIA8YxCAL6NQQBQkz4ADY1BAASOQQAQjkIASo1DAK+NQgDxjUIA+41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+OQgBLkkAABJBBAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1DAACNQQAAjUEAHo1BAMaNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + APuNQgCiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAikAAAI1CAACNQgBIjUIAwY1CAFWNQgAAAAAAAIpA + AACNQQAAiEIAAI1BAC6NQgDBjUIA/o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPyNQgDvjUIAsI1B + AEKNQgAOjUEAB41FABCNQwBKjUIAsY1CAOyNQgD2jUIA/Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+OQgBLkkAABJBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1D + AACNQgAAjUIAJo1CAOCNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPyOQgC9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxC + AACMQgAyjEIAgo1DADaNQwAAAAAAAAAAAACOQQAAjUEAAJpQAACOQgBCjUIAzY1CAP6NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/I1CAO6NQgCsjUIASYxGABONQwAIikQACoxCADKMQQCBjUIAy41C + AO2NQgD4jUIA/41CAP+NQgD/jUIA/41CAP+OQgBLkkAABJBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAi0AAAI1DAACNRAAEjUIAUI1CAP2NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP2NQgDNAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJVJAACVSQAFlkoACptMAAOaSwAAAAAAAAAAAAAAAAAAAAAAAI5C + AACOQgAAjkIAR41CAM6NQgD+jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD9jUIA8o1C + ALiNQgBVjEUAGo1DAAuIQQADjUUAD41DAEeNQgCejUIA2Y1CAO6NQgD7jUIA/41CAP+OQgBLkkAABJBB + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACSPQAAjj4AAJNFAACNQgAXjUMAo41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP2NQgDQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJlNAACZTQAAnE4AAK5X + AACqVQAAAAAAAAAAAAAAAAAAAAAAAAAAAACOQgAAjkIAAI5CAEKNQgDLjUIA/Y1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD3jUIAx41DAGyMQwAsjkIAEo5CAAM+cAAAjkEAH41C + AGSNQgCwjUIA241CAO6OQQBIkUAABJBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAItG + AACMRQAAh0kAAI4/AAiMQQBejUIA941CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPyOQgDKAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjkIAAI5C + AACOQQA+jUIAyI1CAPyNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgDhjUIAko1CAEWOQQAfi0IACpJCAADARgAAjEEAK4xBAHKNQQArkEAAA49AAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAA/wAAAKA2AACOPwAAjUQAB45BAEqNQgDejUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + APyNQgC3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5BAACOSQAAjkIAOI1CALmNQgD3jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPSNQgC8jUIAcI1CADmOQQAciz8ABo1C + AACNQQAAjkIAAJE/AACTPAAAkj0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAItGAACLRgAAjEIAAINIAACNQQAVjEMAWY1C + ANyNQgD+jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPqOQwCaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOQgAAjj0AAI5E + ACCNQgCdjUIA7I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAOeNQgCnjUEAaIxCAECNQQApjkIAFJs2AAKMQwAAjUIAAI1BAACNQQAAjEMAAJFC + AACZTgAAmU0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgFUAAHtdAACLQgAAjUEAAI5B + AABqhQAAjUIAF45BADqNQgCMjEIA741CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPiNQQBuAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjkQAAJRKAACJPQANjUEAfo1CANyNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/4xCAO+NQgDAjUIAjo5B + AGKNQgBKjUIAOo1BACyNQQAdjEMAD5ZBAAWFOwAAjUIAAI1CAACNQQAAjEIAAI1CAACNQwAAjkEAAI1B + AACNQgAAjUMAAJE8AACKQgAGjUEAGo5BADWNQgBZjUIAlY1CAN+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAPONQgA7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIc8AACEOgAAnEoABI5B + AFqNQgDCjUIA+41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD4jUIA241BAL+NQgCijUIAho5CAHGOQwBejUIAUY1C + AEaNQQA7jEIAM41DAC6NQwApjkEAKI5BADCNQgA3jUIAQo1DAFWNQgBzjUIAm41BANGNQgD9jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/o1CANKPPwAVAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAKpVAAD9kAAAkkQAAKs7AACMQgAvjkIAm41CAOiNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA+I1CAOaNQgDTjUIAxo1CAL6NQgC1jUIAtI1BAMCNQgDNjUIA4I1C + APyNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/Y1C + AIWMQgALAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi0IAAIpCAACPQQAAikMAD41C + AG2NQgDOjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA64xDADaKRQACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAIhEAACARwAAjEIAAJFCAAOOQgBBjUIAno1CAOiNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jEMAmoxDAA2MQwAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjkIAAI9CAACLQQAAj0IAFY5C + AGaNQgDEjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgDZjUIANItEAAKMQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJBDAACSRAAAjkIAAI5CAAOPQgA2jkIAio1CANyNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPeNQgBpjkIAB41CAACMQwAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjkIAAI9CAACKQwAAjkIAD41C + AEiNQgCVjUIA541CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41BAJaNQAAVikMAAJU6 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJVAAAC0OAAAjkEAAI5FAACNQwAVjEMAUY1CAKKNQgDujUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIAroxCACd+PQABjEEAAI9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEAAAIs9AACMQwAA/wAAAI5D + AByNQgBSjUIAo41CAPCNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgCyjUIAMo5HAAKMQgAAi0EAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACKRQAAiEYAAI1DAACJTAABjkIAHIxDAEmNQgCQjUMA4I1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAKSNQgAvjD0AAo1C + AACNQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1DAACNQwAAjkIAANQP + AACNQgAUjkIAM41CAHGMQgC7jUIA9o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgDpjUIAgI1EACCURwABjUIAAI1BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAiUUAAIhGAACNQgAAiUgAAI1CAAuMQgAgjUMAPo1BAIGOQQDJjUIA+o1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA9I1CAKyOQgBHj0EADpsvAACNRAAAjkMAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACZMwAAnC8AAI1C + AACMQgAAk2AAAIxBAA6OQQAgjkEAP41BAH+NQgDDjUIA9o1CAP2NQgD+jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD+jUIA/Y1CAOCNQgCVjUIARY1FABeRQQADh0YAAJFG + AACLRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACORwAAjkYAAIxBAACNQgAAlDoAAo1BAA2NQgAajkEAMY5D + AGaNQgCijUIA2o1CAPmNQgD6jUIA/I1CAP2NQgD+jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP6NQgD8jUIA+41CAPCNQgC7jUIAZYxD + ACaNQgAQjEMAA448AACPRAAAek4AAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJI9 + AACSPQAAkD4AAI1BAACNRAAAkjwAAY9EAAiNQgAQjEEAG4xBADeNQgBmjUEAkY1CALONQgDTjUIA7Y1C + APaNQgD3jUIA+Y1CAPqNQgD7jUIA+41CAPuNQgD7jUIA+41CAPuNQgD6jUIA+Y1CAPiNQgD2jUIA741C + AMeOQwCSjEIAXI1CACuNQgATjUMACKcSAACNQwAAjUMAAJQdAACAgAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI45AACNMQAAj0AAAI5DAACNQgAAlUsAAIlA + AAKMQgAHjUEADI1DABCNQgATjUQAHoxCADqMQgBejUIAeY1CAI+NQgCjjUIAsI1CALKNQgCyjUIAso1C + ALGNQgCdjEMAgoxCAGaOQQBJkEIAJY1CABKOQwAMjEIABotCAAGNQgAAjUIAAIpIAACLRgAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AAAAH/////AAAB//AAAAD// + ///AAAB//gAAAD////+AAAB//gAAAD////+AAAD//wAAAB////+AAAD//4AAAB////+AAAD//4AAAB// + //+AAAH//8AAAA////8AAAH//8AAAA////8AAAP//+AAAA////8AAAP///AAAA////8AAAP///AAAAf/ + //4AAAP///gAAAf///4AAAf///gAAAf///4AAAf///wAAAP///4AAAf///wAAAP///wAAA////wAAAP/ + //wAAA////4AAAP///wAAA////4AAAH///wAAA////8AAAH///wAAB////8AAAH///gAAB////+AAAH/ + //gAAB////+AAAD///gAAB////+AAAD///gAAD/////AAAD///gAAD/////AAAB///AAAD/////gAAAP + //AAAH/////gAAAAf/AAAH/////gAAAAD/AAAH////+AAAAAAPAAAH////8AAAAAABAAAH////wAAAAA + AAAAAP////gAAAAAAAAAAP////AAAAAAAAAAAP////AAAAAAAAAAAP///+AAAAAAAAAAAP///8AAAAAA + AAAAAP///8AAAAAAAAAAAf///4AAAAAAAAAAAf///4AAAAAAAAAAAf///wAAAAAAAAAAAf///wAAAAAA + AAAAAf///wA8AAAAAAAAAf///wH8AAAAAAAAAP///wf8AAAAAAAAAH///g/+AAAAAAAAAB///g/+AAAE + AAAAAAf//A/+AAAHAAAAAAP//Af+AAAHwAAAAAH//Af/AAAH8AAAAAH//Af/AAAH/wAAAAD//Af/AAAH + /4AAAAB//Af/AAAH/+AAAAA/+Af/AAAD//AAAAAf+AP/gAAD//wAAAAP+AP/gAAD//4AAAAP4AD/gAAD + //8AAAAHAAAPgAAD///AAAAHAAAHgAAD///gAAADAAAHgAAD///wAAADAAAHwAAD///4AAABAAAHwAAD + ///8AAABAAAHwAAD///8AAAAwAAfwAAD///8AAAA+AAPwAAB///+AAAA+AADwAAB////AAAA+AABwAAB + ////AAAA/AAAQAAB////gAAA/AAAAAAB////gAAA/AAAAAAB////gAAA/AAAAAAB////wAAA/AAAAAAB + ////gAAA/AgAAAAB////gAAA/gwAAAAB////AAAA/g8AAAAB///+AAAA/g+AAAAB///8AAAA///AAAAB + ///4AAAA///gAAAAf//gAAAA///wAAAAAf4AAAAA///4AAAAAAAAAAAA///8AAAAAAAAAAAA///8AAAA + AAAAAAAA////AAAAAAAAAAAA////gAAAAAAAAAAA////4AAAAAAAAAAA////8AAAAAAAAAAA/////AAA + AAAAAAAB/////gAAAAAAAAAB/////4AAAAAAAAAD/////+AAAAAAAAAH//////gAAAAAAAAP//////4A + AAAAAAAf//////+AAAAAAAA////////wAAAAAAB////////8AAAAAAH/////////gAAAAA//KAAAAIAA + AAAAAQAAAQAgAAAAAAAAAAEAIy4AACMuAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAj0AAAI9AAACQPwAIjkIASo5CAIuNQgCJjUIAiY1CAImNQgCJjUIAiY1CAImNQgCJjUIAiY1C + AImNQgCJjUIAiY1CAImNQgCJjUIAiY1CAImNQgCJjUIAiY1CAImNQgCJjUIAiY1CAImNQgCJjUIAiY1C + AImNQgCJjUIAio1CAImOQwBwjUEAIIs+AASMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACORAAAjUEAAI1BABSNQQBfjUIAdY1CAHmNQgB5jUIAeY1C + AHmNQgB5jUIAeY1CAHmNQgB5jUIAeY1CAHmNQgB5jUIAeY1CAHmNQgB5jUIAeY1CAHmNQgB5jUIAeY1C + AHmNQgB5jUIAeY1CAHaOQQBAjkEAEo5BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACPQAAAj0AAAHhaAACNQwBIjUIAqo1C + ANaNQgDYjUIA141CANeNQgDXjUIA141CANeNQgDXjUIA141CANeNQgDXjUIA141CANeNQgDXjUIA141C + ANeNQgDXjUIA141CANeNQgDXjUIA141CANeNQgDXjUIA141CANeNQgDYjUIA2Y1CAMOOQQBnjkEAGI5B + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5E + AACPRwAGjUMAP41CAMCNQgDTjUIA0o1CANKNQgDSjUIA0o1CANKNQgDSjUIA0o1CANKNQgDSjUIA0o1C + ANKNQgDSjUIA0o1CANKNQgDSjUIA0o1CANKNQgDSjUIA0o1CANKNQgDTjUIAy41CAEyMRQAIjEQAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI9AAACPQAAAjEMAAIxEACWMQwCDjUIA9I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA+I1CALCOQQAvjUIAAItGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjUMAAI1DABmNQgBxjUIA+Y1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgDdjUMAQpUzAACLRwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACKSAAAjz0AAI1D + ADKNQgC4jUIA9Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD8jUIA3o1C + AESPPgAAikcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8A + AACNQgAAjUIAMY1CAJqNQgD3jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA741CAJ6NQgAmjUIAAItG + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAItGAACLQwAAi0QAD4xDAFCNQgDajUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD5jUMAY4pIAAuMRQAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAIxCAACNQgBGjUIAwY1CAPqNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgDhjEEAXYxBABKMQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi0YAAItF + AADjAAAAjEMAGY1CAJuNQgDpjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + APyNQgCOjkIAKo5CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A + AAD/AAAAhUcAAI5CAFuNQgDojUIA/Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAMyNQwAmj0UAAo5D + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi0QAAIxCAACNQQAFjEIAQo1CALyNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/Y1CALqNQwBLjUIAAIk7AACJOwAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkEAAAJBAAACUPQAHjUIAdY1CAPyNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgDrjUIAm45DABCLPwAAqWcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAiD8AAIg+AAGHPgAHjUIAfY1CAOSNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD+jUIA5I1CAGySSwAAhjcAAIY3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACNQgAAjUIAAI5BACONQgCSjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAMyNQQBcjUEACY1C + AACSSQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACKQAAAjUIAAI1CAACNQgA4jUIAoY1C + APyNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAjIo8AAuLPgABiz4AAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1CAACNQgAAjUIARY1CALGNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIArIxDACSMQwAEjEMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAIpAAACPPgAAjz4AAJoyAAONQgBbjUIA341CAPyNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgCsjUEANY1BAAONQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjEIAAIxCAACMQgBmjUIAz41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAO+NQgCHi0QAA4tE + AACMQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHNjAABzYwAAikUAAI1B + ACmNQgCPjUIA9Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAMqMQgBijEEABYxC + AACAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5AAACNQgAAjkAAAI1CAIiNQgDtjUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIAyY5BAF6NQgAAjUIAAIxDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAmTMAAJkzAACOQAAAjUAACI1CAEaNQgDZjUIA/I1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA6Y1CAJCKTAAGjjsAAJwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjj8AAI4+AAGOPwANjUIApI1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+OQgCgj0EANY5C + AACOQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1B + AACNQwAAjUMAGo1DAJuNQgDsjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAt4xF + ABWIUgABjEYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOQgAAjkEABY5CAC2NQgC6jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/Y5CAHuRRAASkEQAAJBEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI9EAACPRAAKj0QARI1CAMyNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDOjUEAPo1AAAmNQAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI5DAACOQwAKjkMAV41CAMyNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP2NQgDrjkIAWoM7 + AACfTQAAn00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAj0QAAJpPAACOQwAQjUIAmI1CAOyNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AN6NQgByjUIAE41CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEEAAIxBAA+MQQCAjUIA3o1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA+IxBAL2MQQBAi0AAAP+uAAD/rgAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACPRAAAjkIAAI1AAAKOQgBNjUIAvo1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA745CAKiOQgAdjkIAAI9AAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAIlAAACMQQAAjUEAE41BAKmNQgDwjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD0jEIAi4xC + ACeMQgAAqlUAAKpVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACPQQAAj0EAAZBAABKNQgCJjUIA941CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD8jkIA1I5CADCKRgAAj0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiD8AAJRFAACMQQAgjUEAy41C + AP6NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAO+MQwBai0QAEIxDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI9BAACPQQAAjUIAAI1C + AFiNQgDMjUIA/o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDujkEAUZA/AAuPQAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACKQQAAiEEAB4tCADyNQgDgjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA3oxC + ADObPAAAiEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAj0EAAI9BAACNQQAAjUEAKI1CAIuNQgD6jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAPOOQQCCjkEAI45BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxDAACMQwAWjEMAZ41C + AOeNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPKNQgCyjUIAIY5CAACIRAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJBD + AACXRQAEjkIAUo1CAOaNQgD9jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA+I5CALOOQgA7jkIAAItG + AACLRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjkMAAI5DACWOQwCSjUIA7o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA5I1C + AIWNQgAXjUIAAIhEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaikAAIk/AACOQgAtjUIAq41CAPONQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD8jUIA4o1CAFWPPwAAiUkAAIlJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAItGAACNQwAAjUIAM41C + AL2NQgD2jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDXjUIAWY1CAA6NQgAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACqVQAAjkEAAI1BABONQQBfjUIA441CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD+jUIAco1E + AAmNQwAAjUMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAikcAAI0/AACMQgBFjEIA441CAPyNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AMmNQwAwjUMABo1DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACUQAAAWFEAAI9BACONQgDHjUIA/I1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgCTjkIAKI5CAACOQgAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMRQAAiUgABo1D + AF2NQgD5jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAtohBABC0SAAAgkAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJlAAACKQwAAjUMAEYxDAIuNQgDjjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + ALONQwBJjUMAAI1DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1BAACNQQAejUIAfY1CAPuNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AOuNQgCUi0IACI9CAAB7PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlUAAAI1CAACMQgAIjUIASY1C + AMeNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA1IxCAGmMQQAAi0EAAIk7AAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjUEAAI1B + ADONQQCajUIA/I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA0oxBAG6NQQAFjEEAAIBAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjj8AAI8/AAKOPwAXjUIApY1CAP2NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgDzjEIAioEqAAGCLAAAhzcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQgAAjUIAR41CALWNQgD9jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgC5jUIASY1CAAONQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOQAAAjkIAAI5A + AACOQgB5jUIA4I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgCmij4AEoo+AAKLPgAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACSSQAAkkkAAI1D + AACNQwBbjUMA0I1CAP2NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAKCPRQAkj0QAAo9EAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5AAACNQwAAjUMAAI1DAEaNQgCyjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CALqMQQA5jEEABoxBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJJJAACSSQAAjEEAAI1CAHCNQgDrjUIA/o1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIAh4tKAASMRQAAjEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxE + AACMRAAAjEUAFI1CAIONQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAz45CAGKOQgAKjkIAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkkoAAJJK + AACtcAABjUIAhI1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/o1DAOaNQwBtjkEAAIlHAACJRwAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAikgAAIpIAACUOQAAjUMAXI1CAOGNQgD8jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgDkjkIAjY5CAA2OQgAAkkkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQRAAAkEQAAZBFABaNQgCXjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD9jUIAxI1DAFKNQwAAi0YAAItGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACLRgAAi0YAAI5DAACOQwA8jkIAsI1CAPmNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPeOQgC1j0MAFYs/ + AACVTQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI9D + AACPQwACj0MAMI1CAKiNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPyNQgCfjUIAN41CAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjUEAAI1BACCNQgB7jUIA9I1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CANSORAAnllAAAo9GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjkMAAI5DAASOQwBJjUIAuY1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA+41CAHuNQQAcjUEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACORAAAjkgABY1DAEiNQgDsjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA34xC + AE+MQgAOjEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACNQQAAjUEABY1BAGKNQgDKjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD3jUIAWZE8AASOQAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI9KAACMPwAAjUMALI1C + AMWNQgD3jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDnjEIAeIxCABqMQgAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1BAACNQQAGjUEAfI1CANuNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA+41CANyNQgBCjEMAAJBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjkcAAI1CAACNQgAcjUIAkI1CAOmNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + APCNQQChjUEAJ41CAACAVQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACIRAAAjUIAAI1BAAaNQQCVjUIA7Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD1jUIAuI1CADKNQgAAj0AAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEEAAIxB + AA6MQQBVjUIA2Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA+I5BAMqOQgA0jz8AAINGAACHPQAAhFcAAHfZ + AACAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIZFAACQQQAAi0MACo1CAK2NQgD8jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAO+NQgCTjUIAJY1CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMQAAAiz4AAoxBACCNQgDFjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA7YxDAEWXNAAAkgAAAIc9AAGEWQAAAP8AAIpRAACNQgAAjEIAAI1BAACNQQAAiUAAAIpA + AACKQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAikMAAINGAAGLQwAYjUIAwY1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA6YxCAHGMQgAZjEIAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxA + AACNQwAAjUEADY1CAJ2NQgDujUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD3jEIAY4lBAA6ENwAChjwACgD/ + AACPNQAAjUMAAI1CAACMQgAAjUEAAI1BAACJQAAAikAAAIpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACPQQAAj0EAB45BADWNQgDLjUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgDjjUMAToxEAA2NQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEAAAI1CAACNQwAGjUMAa41CANGNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAPqNQgCHjEIAI4xAABaNQQBdjUIAiI1CAIGNQgBrjUIAVoxCAEKNQQAujUAAFQAA + AACNQgAAjkIAAI1BAACNQgAAj0QAAI9EAACPRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI5CAACPQgANjkIAVI1CANWNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CANuOQgAtlEIAAo9C + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACKQgAAikIAAIlC + AACMQgAAjEIAAI1CAAKNQwA6jUIAtI1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA+41CAKuNQgA6jUEAHY1C + AIiNQgDujUIA841CANqNQgDDjUIArI1CAJaNQgB7jUIAYI1CAEqOQgA5jUEAJ4xBABSUSQADjUIAAI1B + AACMQQAAjEAAAPoDAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjkIAAI5CABSOQgBzjUIA3o1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD+jUIAyo5AABmKRgAApSIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjUEAAI1BAACNQQAAh0IAAotCAA6MQgAXjUMAC45AABWNQgCYjUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD9jUIAzo1CAFONRAAOjUMAYI1CAOaNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD3jUIA3I5CALWNQgCNjUIAYo5DADqNQgAhjUEAFoxBAAyMQAAEf0kAAIxDAACPQgAAkEIAACGD + AAD/AAAA/wAAAAAAAACNQQAAjUEAGo1BAJGNQgDojUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPONQgCvjUIAFY1C + AACZMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQQAAjkEAAI1B + AAKKQgAUjEIAXIxCAJCNQwBAjUMACo1CAHqNQgDyjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP6NQgDvjUIAa6th + AAGOQwA8jUIA341CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP6NQgD7jUIA941CAPKNQgDtjUIA4o1C + AMONQQCNjEEAU4xAACKdOAAFkUAAA41DAAKQQgABIYMAAP8AAAD/AAAAAAAAAI1CAACNQgAgjUIAr41C + APGNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA5o1BAJKNQQARjUEAAJkzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACAQAAAlUMAAI1BAACNPgACjUEANY1CAI6NQgDXjUIA141CAHeNQgAVjUEAWo1C + AM+NQgD+jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgCDn0YABpBBACGNQgDRjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA+I1CAOWNQgDSjUIAuo1BAJiOQgBojkMAOJFC + AA+DSAAAjEMAAJFDAACZQwAAjUMAAI1DACaNQwDLjUIA+o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDajkIAdo5C + AA6OQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACSSQAAkkkAAJBRAACQQwAAjEIAEI1C + AFKNQgChjUIA541CAP+NQgDzjUIAqo1CACONQQA5jUIAqY1CAP6NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AJqPQgAej0AAFo1CALaNQgD2jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA8o1CAM6NQgCrjUIAhI5CAFqNQwAwk0QACYdBAACNQwAAjUIAJo1D + ANeNQgD9jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAM6OQgBbjkIAC45CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA/wAAAAFiAACxHgAAijwAAIxCABONQgBYjUIAwI1CAPmNQgD/jUIA/41CAPqNQgDUjUIAM4tC + ABuNQgCDjUIA/o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAso1CAD+MQQAUjEEAlI1CAOeNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD5jUIA1Y1DAJaOQgBbjkIAN41DABiOQwA0jUIA2Y1CAP2NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAwo5B + AEGOQQAHjkEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAhEsAAJw9AAGRRQAKjUIAZI1C + AM2NQgD7jUIA/41CAP+NQgD/jUIA/41CAPGNQgBMiEYACI1DAF+NQgD5jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgDKjEIAYI1BABCNQQByjUIA2I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP6NQgD9jUIA+o1CAPONQgDJjUIAgo5D + AGuNQgDgjUIA/Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgC3j0AAKI9AAASPQAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAD/AAB/SwAAoTcABI5CAGGNQgDDjUIA+o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA9o1C + AHOLRAAVjUIARI1CANuNQgD7jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAOKNQQCBjkEADY5BAFCNQgDJjUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPiNQgDpjUIA5I1CAPmNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AKySQAAPlD8AAZJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOQwAAjkIAAI9BAAqPQgBOjUIAu41C + APaNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD5jEIAnYxCAC2MQgAvjUIAsI1CAPWNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA+Y1CAKGQPgALjEEALY1CALuNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD+jUEAm5dAAANWSQAAl0AAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACIRAAAiEQAAI1DAACQRQAEjkIAM41CAK6NQgDyjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + APuNQgDHjUIASYxCABuMQgCCjUIA7o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAuY9BABiMQQATjUIAqo1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AO6NQQCImj8AAI5BAACVQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIVFAACFRQAAkUIAAI1DACONQgB/jUIA8o1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/o5CAOyOQgBljEEADI1BAFeNQgDojUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgDGjkMAM5k9AAeNQgCVjUIA+o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA3I1CAHWNQgAAjUIAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAiUQAAIlEAACCRwAEjUIAX41CAOONQgD8jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAICLRQANi0AAMo1CAN+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CANGMQgBRjUIADI1B + AHyNQgDkjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgDLjUIAYo1CAACNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxAAACMQQAAjEIAAIxDAECMQgCpjUIA/Y1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQQD5jUIAho1FABWMQQAfjUIAxo1C + APuNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA241DAHCNQwARjUIAY41CAM+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CALqMQgBQjEIAAIxCAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjD8AAIw/AAGMPwAMjUIAhY1CAOiNQgD/jUIA/41CAP+NQgD/jUIA/41CAOqNQgDLjUIAsI1C + AJ2NQgCOjUIAf41BAHKNQgA+jUYACo1CABaNQgCjjUIA7Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDmjUIAj41C + ABeNQgBKjUIAuY1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIAqo1CAD2NQgAAjUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI9AAACNQQAAjEEABY1BAD2NQgC+jUIA/41C + AP+NQgD2jUIA4o1CAM2NQgCzjUIAjo5BAGOOQgA/jkQAJY9FABL/WgAAkEIAAIxCAACNQgAAjUEAEY1B + AHuNQgDdjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPGNQgCujUIAHI1CADGNQgCjjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgCZjkEAK45BAACOQQAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAj0AAAIxDAACNQgARjUIAj41CAOGNQgD3jUIA5I1CAL+MQwCDjEMARIxCABaNQgAFjkEAA41C + AAKOQwABjkQAAYRBAAB6PgAAgEAAAI1BAACNQQALjUEAVI1CAM6NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA+41C + AMuNQgAikEQAFo1CAIqNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAImOPwAZjkAAAI5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACPQAAAkT4ABI5BACyNQgDNjUIA4o1C + AJyMQwBJjUIAIoxDABSMQwAJi0IAAo1CAACOQQAAjUIAAI5DAACORAAAhEEAAHo+AACAQAAAj0EAAI9B + AAWPQQAsjUIAvo1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA4o9CAC2PGgAAjUMAa41CAPaNQgD+jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUEAeIQ3AAaJPQAAiT0AAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAIxDAACMQwAXjEMAXo1CAJGNQgBnjUIAK4tEAAqNQgAAjEMAAIxDAACMQgAAjEIAAIxC + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACWPgAAoTkAAZU+AA6NQgCqjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgDpjUMAQ4lRAAONQwAvjUIAjo1CANeNQgD9jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/o1CAPyNQgBokkYAAIE3AACBNwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEMAAIxDABSMQwBIjUMANo1E + AA2NQgAAjEMAAIxDAACMQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADl0 + AACDSAAAsysAAo1CAI+NQgDvjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAOyNQwBdjkQAEZJEAAaOQwArjUIAao1C + AJaNQgC6jUIA3Y1CAPqNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD+jUIA+41CAG57IAAAjkIAAI5C + AACOQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACLRwAAi0cAAotHAAZ6YgAAjEQAAI1DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAI1CAACMQwACjUIAb41CANWNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA745DAHeOQwAejkMAAI5CAACLRAAAkD8AD41CAD+NQgB/jUIAt41CANaNQgDpjUIA+I1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIAnY5DADWOQgAKEk4AAI1CAACNQgAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAItGAACLRgAAi0YAAYtG + AACLRgAAjUMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAD/AAAAjEMAAIxDAAGMQwBPjUIAu41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDyjkMAkI5DACmOQwAAj0EAAI9A + AACPQAABjkEABYxGAAqNRwAXjkQARo1CAIeNQgDJjUIA9I1CAPqNQgD+jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD0jUIAro5C + AECOQgAMiUIAAI1CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACNQwAAjUMAAI1DAACNQgAAjUIAAI1CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQgAAjUIAAY1CAC6NQgCgjUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAPWNQQCqjUEANI1BAACPQAAAj0AAAI9AAACNQwAAjj4AAI8VAACPRQALjUIAHI5C + ADaOQwBljUMAro1CAO2NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDyjUIAwo1CAGSNQgAVjUMAAJQaAACAgAAAgIAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1DAACNQwAijUMAQo1C + ACqNQgAHjUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI5BAACOQQAAj0AAEY1CAIiNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA+I1CAMONQgA/jUIAAAAA + AAAAAAAAAAAAAICAAACbEwAAjE8AAI9EAACOQgAAfzwAAI9EABKNQwA/jUIAbo1CAKONQgDYjUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD7jUIAyYxDAHKLRQAijjkAAIdFAAAA/wAAgFUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjUMAAI1DAEuNQwCSjUIAZY5CABKNQgAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj0AAAI9AAACCTQAAjUIAdI1C + AP6NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD7jUIA3I1CAEqNQgAAjEAAAIxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJFE + AACTRAAAj0MAAIxEAACfMAADjkEAM41CAHSNQgCvjUIA2I1CAPiNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA1IxDAHqLRAAjAP8AAJA7 + AAAndwAAgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlUAAAJVAAACNQgAAjUIAXo1C + AL+OQwCSjkMAG45DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACPQAAAj0AAAI1CAACNQgBjjUIA641CAP2NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP6NQgDzjUIAVY1C + AACMQAAAjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACSPQAAkj0AAJM8AACUPgAAhkUABItC + AB6NQQBxjUIAwo1CAO2NQgD5jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA3YxCAIiLRQAeiEYABJRIAACAOAAAmTMAAJkzAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACVQAAAlUAAAI5CAACOQgBtjkIA4Y1CALWNQgAijUIAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI9AAACPQAAAjUIAAI1C + AFONQgDRjUIA/I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP2NQgBliDcAAoxAAACMQAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAJI9AACSPQAAkzwAAIxCAACYPAAAi0IAA41BABCLQgAtjUIAdo5CAMuNQgD7jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD9jUIA4o5C + AJiMQgAivkoAAIBCAACZMwAAmTMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJdAAACXQAAAdkcAAI5C + AHuNQgD8jUIA1I1CACeNQgAAkEMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQQAAjUEAQ41CALWNQgD6jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AHiQQwASj0MAAI9DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiEQAAIBJ + AACLQgAAjUEAAIBCAAKOQgAbjUIASIxDAIWMQwDUjUIA+41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD9jUIA441CAI+NQQAqiEgAAIE7AACBPAAAgEAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjkEAAI5BAAGPQAAOjUIAi41CAP+NQgDmjkIAMolBAACQQwAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1B + AACNQQAyjUEAmo1CAPmNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAi41DACSNQgAAjUIAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIpCAACKQgAAiUIAAI1DAAB4UwABi0QAIoxD + AGONQgCmjUIA4I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA441CAIaNQQAqlEMAAJRDAACVQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQQAAjUEAAY1B + ACWNQgCcjUIA/41CAO2OQgBGkkQABo9DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjUEAAI1BACKNQQCAjUIA941CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgCfjEIANoxCAACMQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAi0QAAIlEAACORAAAnUcAAI1CADONQgCHjUIA041CAPONQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA4Y1CAIaMQgAdjEIAAYxC + AACMQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5BAACOQQACjkEAPI1CAK2NQgD/jUIA745CAF+OQwASjkMAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACLQQAAi0EAEoxCAGWNQgD1jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/4xCALOMQgBIjEIAAIxCAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgEAAAHw/ + AAB7PwAAjEAAAo5EABSNQwBMjUIAuY1CAOuNQgD8jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA2o1CAICNQgATkkIAAIxCAACOQQAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEEAAIxB + AAOMQQBSjUIAvo1CAP+NQgDyjkIAd45CAB6OQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJBBAACeOQACjkIASo1CAPONQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jEIAx4xCAFqMQgAAjEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQAAAfD8AAHs/AACNQwAAk0wAAY1DAAyMQgAsjUIAd41C + AM2NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD9jUIA1YxC + AGeMQgAVjEIAAI5BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMQgAAjEIAA4xCAGqNQgDPjUIA/41CAPSNQgCPjUMAKY1D + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAmUAAAIlCAACOQQA5jUEA5Y1CAP6NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDajUIAbI1CAACNQgAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI5EAACNRAAAj0MAAJVDAACNQgAejUIAWY1CAKeNQgDxjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD6jUIAyY1CAFePQAAQjkIAAI1EAACNRAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAI1C + AACMQgAEjEIAgY1CAOCNQgD/jUIA9o1CAKeOQwA1jUMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACVQAAAjUEAAI1BAC+NQQDMjUIA+I1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAO6NQgB+jUIAAIxBAACMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIBAAAC4SQAAh0EAAI1C + AACSQgAHjkIAPI1CAJmNQgDajUIA+o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIAtI1CAEuNSAAFbkAAAItEAACIRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAi0MAAJBAAAWNQgCXjUIA8Y1CAP+NQgD5jkIAv45C + AEGOQgAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACNQQAAjUEAJ41BAK2NQgDxjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAI+PRgAAjD8AAIxA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj0IAAJJJAACgXgABj0UAGY1CAH6NQgDQjUIA+I1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD+jUIAoI1DADCJRAADmT8AAItB + AAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANEd + AAB/SgAAmzoABo1CAKyNQgD/jUIA/41CAPuMQwDXjEMATYxDAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxCAACMQgAfjEIAkI1C + AOqNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIAnIxAAAuMQAABjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACPQgAAkUYAAIsWAACUQwADkz8AEI1CAF2NQgC+jUIA/o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgDqjUIAlIpDABOIRAABh0UAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAk0MAAJhEAAKSQwAXjUIAu41CAP+NQgD/jUIA/Y1C + AO+NQgBZhkYAAADFAAAAxQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjUMAAI1DABeNQwBzjUIA5I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgCmjkQAG45E + AAKORAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACSSQAAuEkAAIlIAACBSQAAjkIAEY1C + AFKNQgCxjUIA/I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDXjkIAc5NA + ABCFRgAAZlYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACVQAAAlUAAAJlA + AACPQQAAj0IABI5CAC+NQgDFjUIA/41CAP+NQgD/jUIA/Y1CAGlbTAAAj0QAAJFHAACTSwAAkkkAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACOQgAAjkIAD45C + AFaNQgDdjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAK+NQgArjUIABI1CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAD/AAAANXUAAPUGAACNQgAAi0IAD4xCAEyNQgCujUIA8o1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPmNQgDKjUEARo0/AAuNQQAAi0YAAItGAAAAAAAAAAAAAAAA + AAAAAAAAikIAAIpCAACMQwAAjUMAAIxDAACMQwAAhkQAAJU9AAKNQQAbjUIAZY1CANaNQgD/jUIA/41C + AP+NQgD/jUIAk41CAC6QRQALp2UAAYtAAACNQgAAjUIAAI5DAACLQQAAiD8AAIlAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1BAACOQAAHjUEAOI1CANaNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAuIxB + ADyMQQAFjEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxC + AACMQwAAjEQACYxDAEONQgC2jUIA9I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + APWNQgCcjEIAMI47AACKSgAAikoAAAAAAAAAAAAAAAAAAAAAAACOQgAAiUIAAoxDAAWNQwAIjEMADIxD + ABCPQgAYjkEALo1CAGKNQwDAjUIA8o1CAP+NQgD/jUIA/41CAP+MQQDZjUIAko9EAEiPRAAkjkMAFI1C + AA6NQgAKjkMAB4tBAAOGPgABi0EAAI1CAACNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkUgAAP// + AACPRQAdjUIAzY1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDBjUEATY1BAAaNQQAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxDAACPQAAAjUIACI1CAEyNQgC3jUIA/I1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/Y1CAO2NQgBoikUADIxEAACNQwAAjkMAAAAA + AAAAAAAAAAAAAI5CAACJQgAQjEMAMI1DAFaMQwB7jEMAoY1CAMONQgDXjUIA441CAPWNQgD9jUIA/41C + AP+NQgD/jUIA/41CAPmNQgDsjUIA3Y1CANONQgC3jUIAko1CAGqOQwBEi0EAHYY+AAWLQQAAjUIAAI1C + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACTSwAAi0AAAI1DABGMQgDAjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AMqNQgBdjUIACI1CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjEMAAI1CAACRPgAAjUIACoxDAFSNQgC5jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/YxCALWMQQBLjEEAAI1DAACOQwAAAAAAAAAAAAAAAAAAjUIAYY1CAJaNQgC+jUIAzI1C + AN2NQgDujUIA/Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + APiNQgDnjUIA1Y1CAMSNQgCzjUIAh41CAD2NQgAAjUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJJJ + AACNQgAAjEIADo1CAK+NQgD3jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA041BAG2NQQAJjUEAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjUIAAI1CAACNQgAAi0QAEYxC + AF6NQgDPjUIA+41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA8I1CAI+OQwAYjkMAAo5D + AAAAAAAAAAAAAAAAAACNQgBmjUIAqI1CANeNQgDkjUIA9Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPqNQgDpjUIA141CAMSNQgCPjUIAPo1C + AACNQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1CAACNQgAMjUIAnI1CAO2NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgDcjUEAfo1BAAqNQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxDAACMQgAAjEAAGYxBAHONQgDfjUIA/o1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIAyI1CAFeOQgAGjUMAAIxEAAAAAAAAAAAAAJVAAAqPQQAyjUEAX41C + AIONQwCojUIAyY1CANmNQgDijUIA7I1CAPuNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA+o1C + AOSNQgDRjUIAtI5BAI+MQgBni0IAPYhCABVqPAABfUAAAH1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjEIAAIxCAAuMQgCKjUIA4o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAOWNQgCOjUIAC41CAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI43 + AACLTwAAjUAAG41CAJqNQgDnjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDwjUIApYxD + ABWTNwAAjEQAAAAAAAAAAAAAlUAAAY9BAAWNQQAJjUIADY1DABGQRQAajkMANo1CAFyNQQCPjUIA3o1C + APqNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDojUEAfIxBAC6MQQARjkEADoxCAAqLQgAGiEIAAms8 + AAB9QAAAfUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQgAAjUIACo1CAHiNQgDYjUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA641CAJqNQgAMjUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjjgAAIxFAACNQQAFjEIAKYxCAK2NQgD5jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDVjEMARYxEAAuMRAAAAAAAAAAAAACUQAAAj0EAAI1B + AACNQgAAjEIAAH82AACRRgAGjkIAEI1CACqOQgB4jUIA3I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + APaNQgDBjEEAQoI1AAKNQQAAjEIAAItCAACJQgAAdj4AAIBAAACAQAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAIxDAACMQwAIjEMAZo1CAM+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDxjUIApY1CAA2NQgAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACOOQAAjD8AAINPAACLQgAGjEMAVo1CAMCNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AO2OQgCVjkIAII5CAACPQAAAAAAAAAAAAAAAAAAAAAAAAJlNAACZTQAAmk4AAI9EAACNQgAAjEQAA41C + ADONQgDGjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPWNQgCsjUEATY0+AAuMRAAAjEIAAIxD + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEMAAIxDAAeMQwBTjUIAxI1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAPeNQgCwjUIADo1CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMQgAAjEMAAIxBAACMRAAUjUIAfI1C + AO2NQgD+jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA+41CANiOQQBDlDoAA49AAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIo/AACIOwABiz8AFo1CALqNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAPyNQgC0jUEAUoxDABOKSQABjEIAAIxCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACNQwAAjUMABY1DAEGNQgC6jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/Y1CALuNQgAPjUIAAJkz + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACMQwAAjEMAAI1CAACNQgBAjUIAtI1CAPuNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA+I1CAHeOQQAcjUIAAIBVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzxoAAIBK + AACaOgAGjUIArI1CAP+NQgD/jUIA/o1CAPmNQgD3jUIA+o1CAP+NQgD/jUIA/41CAP6NQgDKjEMAWoxC + ABaLQQABjEIAAIpHAACLRgAAi0YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1DAACNQwAEjUMAMI1C + ALGNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIAxo1CABCNQwAAmTIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEQAAIxF + ABONQwBmjUIA8Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD6jUIAtI1CAEKOQAAAfFsAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAjEMAAJFAAAWOQgCYjUIA8Y1CAP+NQgD6jUIA0IxC + AL2NQgDWjUIA/41CAP+NQgD/jUIA/41CAPmNQgDWjEIAcYxCAB2MQgAAikcAAItGAACLRgAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjUMAAI1DAAONQwAejUIAqI1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDMjz8AFIhJ + AACZMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMRAAAj0EAAI1DADaNQwDMjUIA+I1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP2NQgDrjUMAZpouAACAVQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8A + AACOQgAAjUMABI1DAIKNQgDijUIA/41CAPeNQgCujEIAYI1CAIaOQgD2jUIA/o1CAP+NQgD/jUIA/41C + AP2NQgDWjUMAjI1DADiUNAAAjUIAAItEAACMQwAAAAAAAAAAAAAAAAAAAAAAAAAAAACMRAAAjEQAAYxF + AA2NQgCejUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAM+QQwAaeDYAAJRGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxE + AACNQwAAjUMAHY1DAI2NQgDqjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgCOi0QAHItE + AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1DAACNQwADjUMAbY1CANKNQgD/jUIA9IxC + AJOMQwApjkIAOY5CALKNQgD5jUIA/41CAP+NQgD/jUIA/41CAP+NQgDljUIAoI1CAEyMQwAQlEAAAI9C + AABuVgAA/wAAAP8AAAAAAAAAAAAAAIpHAACKRwAAfl8AAY1CAJSNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA0I1D + ACCPTAABjUQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1BAACNQQANjUEATY1CANuNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CALmNQgBLj0AAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjkIAAI5CAAOOQgBXjUIAwo1CAP+NQgDyjUIAeo1CAB2PQAAKjUEAT41CANeNQgD8jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD3jUIAxI1CAFmNQwAfkkIABYVHAACJQgAAjEEAAIpCAAAAAAAAi0YAAIxD + AACNQgAAjUIAiI1CAPqNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDSjEEAJ4lAAAOLQQAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAjz0AAJUuAAGOPwAgjUIAyo1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA4Y5C + AHyISgADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQQAAjUEAAo1BAEKNQgCyjUIA/41C + AO+NQgBhjkEAE4xCAACMQgAZjEIAfo1CAOCNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD6jUIA445D + AISPQgAvnDgABItCAAKHQwAAikIAAAAAAACLRgAAjUIAAI1CAACNQgB7jUIA641CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + ANOOQwAukEUABY9EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACPPQAAjUMAAI1CAA+NQgCxjUIA+I1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAoodLAAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAIxDAACMQwABjEMALI1CAKGNQgD/jUIA7Y1DAEaMRgAGjEMAAIlCAAOLQgAjjUIApo1C + APKNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD+jUIA5o1CALaNQgBoikIAFWZCAACLQgAAnkUAAIBA + AACMQQAAjEEAAIxBAG+NQgDejUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA1I9CADKSQQAGkEIAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI89AACOQgAAjkIADI5CAJiNQgDqjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgC5jkMAMgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi0MAAItDAAGLQwAWjUIAko1C + AP+MQgDjjEMAMY89AACHSAAAkEIAAH8/AAGMQgBHjUIAso1CAPuNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA941CAM+NQgCNjUIARYxCAA2PQgAAjUEAAKA2AACNQQAAjEEAUI1CAL6NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgDVj0EAM5JAAAaQQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5BAACOQQALjkEAh41C + AOGNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAMiNQgBbAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACKPwAAij8AAIM7AASNQgCDjUIA/oxCAM6MQgAmjEIAAIpFAACGPwAAjD4AAIM7 + AASNQgBYjUIAw41CAPyNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPSNQgCujEIAZIxC + AC+OQAAPgEoAAItDAACNQgAkjUIAbo1CALyNQgDcjUIA+I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CANSPQQAzkkAABpBBAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjUEAAI1BAAuNQQCGjUIA4I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA1I1CAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIpAAACKQAAAjUIAAI1C + AHSNQgDqjUEAsY1BACCNQQAAAAAAAIpAAACKQAAAj0EAAI5BAA6NQgBbjUIA2o1CAPuNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP2MQgDpjEIAqI1BAFSQQAAcj0AACopCAAKQPwAIjkEALI1D + AHiNQgDDjUIA6o1CAPaNQgD+jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA1I9BADOSQAAGkEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI1DAACNQQAAjUEADI1B + AJSNQgDojUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDfjUIAnwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAikAAAIpAAACNQgAAjUIAZY1CAMqNQgCUjUIAG41CAAAAAAAAikAAAIpA + AACNQQAAh0QAAI1BABmNQQBmjUIA4o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP2NQgD1jUIA341CAK2NQQBUjUEAF6swAACOQQAGjUMAEY1EACqNQwBnjUIAt41CAPKNQgD9jUIA/o1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDUj0EAM5JAAAaQQQAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjUMAAI1CAACNQgAOjUIAqY1CAPONQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAOaOQgC0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxC + AACMQgBUjEIApo1DAHSNQwAVjUMAAAAAAAAAAAAAAAAAAI5BAACNQQAAjD4AAo1BAB6NQgCCjUIA4I1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA8I1CAM+NQgChjUIAZo1B + ACeSKwAAjjQAAI1DABWNQgA3jEIAXI1CAIqNQQC9jUIA641CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CANSPQQAzkkAABpBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQwAAjUQAAo1D + ACSNQgDHjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA641CAMQAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjUMAAI1DACuNQwBSjkMAN45EAAqORAAAAAAAAAAA + AAAAAAAAAAAAAI1BAACOQgAAj0MAAo5CACmNQgCLjUIA4I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPaNQgDOjUIAl41DAGWNQgA2jEQADJE9AAD/KAAAjUEAJIxB + AE+MQgB6jUIAoY1CAMSNQgDqjUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA1I9BADOSQAAGkEEAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAi0AAAI1CAACNRAAOjUMAVo1CAN6NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgDujUIAzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACiVAAAoVQAAqZXAAT/zQAAAAAAAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5CAACOQgAAjkIAAI5C + AC2NQgCKjUIA5I1CAP6NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA5I1CAKKNQgBejEQAL45DABmKRgAFj0EAAJS1AACNRQAdjUIAVo1CAJWNQgDBjUIA2o1C + AOqNQgD6jUIA/41CAP+NQgDVj0EAM5JAAAaQQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkj0AAJI9AACOPgAAlEoAAI1C + ACqNQwChjUIA7o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAO6NQgDMAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJlNAACZTQAAm04AAKhUAACtVgAAqlUAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5CAACOQgAApkIAAI5CACiOQgCAjUIA6Y1CAP6NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD9jUIA+o1CAO2NQgDFjkMAfIxD + ADaLQwATjkIACIxDAAaPQQAGlj0ACY5BACSNQgBWjUIAlY1CANGNQgDtjUIA/Y1CANCPQQAykkAABpBB + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAItGAACSPgAAkzsAAINFAACLQAASjEEAYY1CAOuNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA7I5CAMgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAmU0AAJlNAACbTgAAqFQAAK1WAACqVQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjkIAAI5C + AACOQgAAj0MAA45CACaOQQB7jUIA4o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPeNQgDljUIA045CAKaOQgBojEMAKvALAAGERwAAkj8AAo1C + AA6NQgAejEIALoxCAFaMQQCRjEEAmY5BACqQQAAGj0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi0YAAI9CAACHSwAAnTMABI1B + AFaNQgDIjUIA+41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDojUIAugAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5CAACOQQAAjz8AA45BACSNQgB9jUIA1o1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA8Y1CANGNQgCrjUIAgY1CAFWMQgAmekIAA41CAACPQgAAikAACoxBACuMQQA2jkAAEJBA + AAKPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA/wAAAHVPAACPQQAAjzsAAItIAAuNQgBajUIAuY1CAPiNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAOGOQwCnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI5BAACOQQAAjT0AAI5CACGNQgB0jUIAyo1CAPiNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDvjUIAwo1C + AI+MQgBjjUIAQY5BACaMQAAMkUQAAIxBAACNQQAAjkIAAI9BAACTPAAAkj0AAJI9AAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACLRgAAikcAAItFAACNQgAAiEUAAJU6AASNQQAljEMAYY1C + AMGNQgD4jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA2I5C + AIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5CAACOQgAAjkQAAI5F + ABCNQwBXjUIAxI1CAO+NQgD+jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAPKNQgDHjkEAi41BAFSLQQAvjEIAHY1B + ABWOQgANkEAABqMsAAGNQgAAjUIAAI1BAACNQQAAjUEAAIxDAACPQgAAk0QAAJtQAACZTQAAmU0AAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAVQAAcmwAAIZLAACMQQAAjUEAAI1C + AACRPAAAikcAAo1CAAuQQQAVjkEAOY1BAISMQgDgjUIA/I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDMjUEAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAjkIAAI5CAACOQwAAk0oAAYtAAAuMQAA3jUEAqY1CAOuNQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/o1CAPmNQgDxjUIA7I1CANqMQgC3jUEAiI5CAFqPQQAukT4AEI1CAAWNQgAEjUEABI1B + AAONQQACjEMAAY9CAAGTRAAAm1AAAJlNAACZTQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAIBVAABybAAAhksAAIxBAAGNQQACjkAAAoxEAAeMRQAbjUIAT41CAJWNQgDQjUIA8I1C + APyNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AL+NQgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5E + AACMQgAAlkoAAIo+AAeOQgAwjkEAhY1CANeNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + APSNQgDkjUIA041CAMWNQgC2jUIAo41CAIuNQQBzjUEAW41BAEOMQwAsj0EAGphGAAh7MQAAjUIAAI1C + AACNQQAAjUEAAIxCAACNQgAAjUMAAI1CAACNQgAAjkEAAI1BAACNQwAAjUMAAJA9AAAA/wAAi0EAGo1B + ADqOQQBjjkEAkY1CALiNQgDQjUIA6I1CAPuNQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAqo9AABYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIc8AACLPgAAhjwAAIE5AACPQQAnjUIAbY1C + ALqNQgD1jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD6jUIA6I1C + ANaNQgDFjUIAs41CAKGNQgCUjkIAh41CAHuNQgBxjUIAZo1BAFqMQQBPjEIAR41CAEONQwA+jUMAN45B + ADeOQQA+jUEARY1DAE2NQwBZjUIAaY1CAH6NQgCTjUIArI1CAMuNQgDsjUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AOuNQQCIlzUAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAKpVAAANAAAAoE4AAI1CAACJQgAOjEIASY5CAKqNQgDfjUIA+o1CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + APaNQgDmjUIA1Y1CAMSMQgC4jUIAsY1DAKqNQgChjUIAoI5BAKqNQQC2jUIAwY1CANONQgDqjUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIAxI1BAFiMQwABAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi0IAAIxA + AACJQwAFi0MAHY1CAICNQgDSjUIA+Y1CAP6NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/o1CAP6NQgD9jUIA/I1CAPyNQgD7jUIA+41C + APuNQgD7jUIA+41CAPuNQgD8jUIA/Y1CAP6NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+MQgCVi0QAI4tEAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACLQgAAiUMAAJJAAACIRAADjUIAFY5CAFGNQgCpjUIA9I1C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD9jEMA5YxDAGZlbgAAi0QAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACIRAAAgEcAAIpDAACNQgAAj0IADo5CADmNQgB4jUIAw41CAPeNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + APyMQwCcjEMAMoxDAACLRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjkIAAI5CAACPQgAAiEAAAJBD + ABOOQgBajUIAo41CAN6NQgD+jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD7jUIA2Y1CAFCLRAALjEMAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJBDAACSRAAAjkIAAI5CAACOQgAojkIAfY5CAMyNQgDqjUIA+41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AOaNQgCKjUIAHY1CAACMQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkEMAAJJE + AACOQgAAjkIAAI1CAASRQQAOjkIAN41CAIqNQgDbjUIA+I1CAP2NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD3jUEAuI5BACaPQQAEjkEAAIxDAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5CAACOQgAAj0IAAIdEAACQQQAHjUIAIY1C + AEWNQgCJjUIA041CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AMCMQQBOjUAACIlDAACSPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACVQAAApzsAAI9BAACNQgAAehoAAI1DACeNQwBfjUIAmo1CANGNQgD6jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDMjUIAaIpBAA6HQgABjEEAAI9AAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjEAAAIxA + AACMQAAAjEMAAH1PAAKMRAAkjkIAbI1CAKyNQgDWjUIA8I1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD9jUIA2I1C + AG+NRAAbjEIAAItBAACLQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACKRQAAiEYAAIxEAAGOQgAEjUMAG45C + AF2OQgCtjUIA441CAPGNQgD5jUIA/o1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA+41CANuNQQBtjUEAHI1AAACNQwAAjUMAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAIpFAACIRgAAjEQAAI5CAACNRAADjkIADY1DACCMQwBDjUIAho1DAM2NQgD2jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP6NQgDLjkMAXY1C + ABmMPgACjUIAAI1DAACNQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACNQwAAjUMAAI1D + AACNQwAAkz8AAIhGAAeNQgAkjUIAQ41CAG6NQgChjEIA0Y1CAPmNQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgDrjUIApI1DAE+OQwAUlUwAAY1CAACNQQAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIlFAACHRgAAi0QAAI1CAACJSAAAjz8ADY1C + ADeMQgBkjUIAjY1CALCNQgDQjUIA7Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgDujUIAwI1BAIaNQQA6hlAABY9C + AACNRAAAjkMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAACZMwAAmTMAAOEAAACOQQAAjUIAAItAAACPSwAGjEIAL41BAGiOQQCejUIAyI1C + ANyNQgDpjUIA9Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + APSNQgDmjUIAzo1CAJ+NQwBNkkEAD4BKAACUQgAAi0YAAItGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJkzAACZMwAA4QAAAI5B + AACNRQAAj0kAAI5IAAGMQgAEjUEACI9AAA+QPwAhjUEAUI1CAIiNQgC+jUIA6o1CAPWNQgD4jUIA+o1C + AP2NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD+jUIA+41CAPeNQgDqjUMAuY1CAHeNQgA4jEkADo1EAAaRQAABeFAAAMsg + AACLRgAAi0YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI5HAACORwAAjkgAAIxCAACNQQAAjUIAAJ0y + AAGOQAAOjUIAHY1CAC2NQQBBjkMAZo1CAI+NQgC6jUIA4Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAO+NQgDAjUIAg41D + AEqNQwAsjUIAGI1CAAiPOAAAjUEAAJFCAAB2UAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJI9AACTPAAAkj0AAI5BAACNQQAAjUQAAIlSAACQRAASjkMAK41C + AEWNQgBfjUIAeY1CAJKNQgCqjUIAwI1CANONQgDkjUIA9Y1CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + AP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41CAP+NQgD/jUIA/41C + APWNQgDcjUIAwI1CAKSNQgCIjUIAao1CAEmNQgAkiE0AA45BAACNQgAAjUIAAHmkAAB6nwAAgIAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAI45AACNMQAAjj0AAI9EAACOQwAAjUIAAI9EAAB7MQAEi0MAHY1CADqNQQBVjUIAa41D + AH+NQgCTjUIApI1CALKNQgC8jUIAxo1CAM2NQgDTjUIA2Y1CAN6NQgDijUIA441CAOONQgDjjUIA441C + AOONQgDhjUIA2o1CANONQgDLjUIAw41CALuNQgCujUIAlY5DAHWOQwBUjEIAM4xCABGQQgAAjUIAAI1C + AACLRQAAikcAAItGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AACHPAAAhjsAAIc9AACLQgABjUIAAY1BAAKNQgACjUMAAo1BAAKORgAJjUQAG4tBADiMQgBVjUIAa41C + AHyNQgCOjUIAnY1CAKiNQgCrjUIAq41CAKuNQgCrjUIArI1CAKSNQgCRjEMAe4xCAGSNQgBOj0EANJJD + ABaRQwAGi0IAAo5DAAKMQgABjEIAAIxCAACMQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAA////// + /wAAAAP//wAAAAAP//////8AAAAD//8AAAAAB///////AAAAA///wAAAAAf//////AAAAAP//8AAAAAH + //////wAAAAH///AAAAAB//////8AAAAB///4AAAAAH//////AAAAAf///AAAAAB//////wAAAAH///w + AAAAAf/////8AAAAD///8AAAAAH//////AAAAA////gAAAAA//////gAAAAP///4AAAAAP/////4AAAA + H////gAAAAD/////+AAAAB////8AAAAA//////gAAAAf////AAAAAP/////4AAAAH////wAAAAB///// + 8AAAAB////+AAAAAf/////AAAAB/////gAAAAH/////wAAAAf////4AAAAB/////8AAAAH/////gAAAA + H/////AAAAB/////4AAAAB/////gAAAA/////+AAAAAf////4AAAAP/////wAAAAH////+AAAAD///// + 8AAAAB/////gAAAA//////AAAAAP////4AAAAP/////4AAAAD////+AAAAH/////+AAAAA////+AAAAB + //////gAAAAP////gAAAAf/////8AAAAD////4AAAAH//////AAAAAf///+AAAAB//////wAAAAH//// + gAAAB///////AAAAB////4AAAAf//////wAAAAf///+AAAAH//////8AAAAH////gAAAB///////AAAA + A////wAAAAf//////4AAAAA///8AAAAP//////+AAAAAAH//AAAAD///////gAAAAAB//wAAAA////// + /4AAAAAAA/8AAAAP//////wAAAAAAAAfAAAAD//////4AAAAAAAAAQAAAA//////+AAAAAAAAAEAAAAP + /////+AAAAAAAAAAAAAAH/////+AAAAAAAAAAAAAAB//////AAAAAAAAAAAAAAAf/////wAAAAAAAAAA + AAAAH/////8AAAAAAAAAAAAAAB/////+AAAAAAAAAAAAAAAf////+AAAAAAAAAAAAAAAH/////gAAAAA + AAAAAAAAAD/////4AAAAAAAAAAAAAAA/////8AAAAAAAAAAAAAAAP/////AAAAAAAAAAAAAAAD/////g + AAAAAAAAAAAAAAA/////4AAAAAAAAAAAAAAAP////+AAAAAAAAAAAAAAAD/////gAPwAAAAAAAAAAAA/ + ////4A/8AAAAAAAAAAAAH////+B//AAAAAAAAAAAAA/////gf/wAAAAAAAAAAAAP////wP/+AAAAAAAA + AAAAAf///8D//gAAADgAAAAAAAD////A//4AAAAPgAAAAAAAf///AP/+AAAAD+AAAAAAAB///wD//gAA + AA/gAAAAAAAf//8Af/+AAAAP/AAAAAAAD///AH//gAAAD/8AAAAAAA///wB//4AAAA//4AAAAAAH//8A + f/+AAAAP//AAAAAAA///AH//gAAAD//wAAAAAAP//wB//4AAAA///gAAAAAA//4Af/+AAAAH//8AAAAA + AH/+AB//wAAAB///4AAAAAA//gAf/8AAAAf//+AAAAAAP/4AH//AAAAH///wAAAAAD/wAAf/wAAAB/// + +AAAAAAPAAAAP8AAAAf///8AAAAADwAAAA/AAAAH////gAAAAAcAAAAPwAAAB////4AAAAAHAAAAD8AA + AAf////AAAAABwAAAA/gAAAH////8AAAAAMAAAAP4AAAB/////gAAAADAAAAD+AAAAf////4AAAAAwAA + AA/gAAAH////+AAAAAHgAAB/4AAAB/////wAAAAB/gAAP+AAAAP////+AAAAAP4AAAfgAAAD/////4AA + AAD+AAAH4AAAA/////+AAAAA/gAAA+AAAAP/////gAAAAP8AAABgAAAD/////8AAAAD/AAAAIAAAA/// + ///AAAAA/wAAACAAAAP/////wAAAAP8AAAAAAAAD/////8AAAAD/AAAAAAAAA//////gAAAA/wAAAAAA + AAP/////4AAAAP8AgAAAAAAD/////8AAAAD/AIAAAAAAA//////AAAAA/8DgAAAAAAP/////wAAAAP/A + 8AAAAAAD/////4AAAAD/wPgAAAAAA/////4AAAAA/8D8AAAAAAP////8AAAAAP/A/AAAAAAD/////AAA + AAD///8AAAAAA/////AAAAAA////gAAAAAB///+AAAAAAP///8AAAAAAAD/wAAAAAAD////AAAAAAAA/ + 8AAAAAAA////8AAAAAAAAAAAAAAAAP////gAAAAAAAAAAAAAAAD////8AAAAAAAAAAAAAAAA/////4AA + AAAAAAAAAAAAAP////+AAAAAAAAAAAAAAAD/////wAAAAAAAAAAAAAAA//////AAAAAAAAAAAAAAAf// + ///8AAAAAAAAAAAAAAH//////AAAAAAAAAAAAAAB//////8AAAAAAAAAAAAAA///////wAAAAAAAAAAA + AAP///////AAAAAAAAAAAAAH///////+AAAAAAAAAAAAD////////gAAAAAAAAAAAA////////+AAAAA + AAAAAAA/////////8AAAAAAAAAAAf/////////wAAAAAAAAAAP/////////8AAAAAAAAAAD///////// + /8AAAAAAAAAD///////////8AAAAAAAAD////////////8AAAAAAAP/////////////+AAAAAA///4lQ + TkcNChoKAAAADUlIRFIAAAEAAAABAAgGAAAAXHKoZgAAAAFvck5UAc+id5oAAGDkSURBVHja7b15lCX5 + Vd/5uRFvy5d7Vmbte3dVL+pFau0CoVZ3Ix0E2DPjwXjGnsU2Nvaxh2MWA2MPnsYeGyEhyWgQBm/MscE+ + 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 + + + \ No newline at end of file diff --git a/Check.Main/Infer/DetectionCoordinator.cs b/Check.Main/Infer/DetectionCoordinator.cs new file mode 100644 index 0000000..e472ece --- /dev/null +++ b/Check.Main/Infer/DetectionCoordinator.cs @@ -0,0 +1,149 @@ +using Check.Main.Camera; +using Check.Main.Common; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Check.Main.Infer +{ + public static class DetectionCoordinator + { + /// + /// 定义存储所有相机处理器的字典 + /// 键是相机的唯一编号 (CameraIndex),值是对应的处理器实例。 + /// + private static ConcurrentDictionary _processors = new ConcurrentDictionary(); + /// + /// 用于在产品组装时进行同步,确保线程安全 + /// + private static ConcurrentDictionary _productAssemblies = new ConcurrentDictionary(); + /// + /// 可用的相机数量 + /// + private static int _enabledCameraCount = 0; + + public static event EventHandler OnDetectionCompleted; + public static bool IsDetectionRunning { get; private set; } = false; + + // OnDetectionCompleted 事件现在也属于这里 + //public static event EventHandler OnDetectionCompleted; + + public static void StartDetection() + { + if (!IsDetectionRunning) + { + IsDetectionRunning = true; + ThreadSafeLogger.Log("检测统计已启动。"); + } + } + + public static void StopDetection() + { + if (IsDetectionRunning) + { + IsDetectionRunning = false; + ThreadSafeLogger.Log("检测统计已停止。"); + } + } + public static void Initialize(List cameraSettings, List modelSettings) + { + Shutdown(); // 先关闭旧的 + var enabledCameras = cameraSettings.Where(c => c.IsEnabled).ToList(); + _enabledCameraCount = enabledCameras.Count; + if (_enabledCameraCount == 0) return; + + foreach (var camSetting in enabledCameras) + { + // 找到与相机编号匹配的模型 + var model = modelSettings.FirstOrDefault(m => m.Id == camSetting.ModelID); + if (model == null) + { + ThreadSafeLogger.Log($"[警告] 找不到与相机 #{camSetting.CameraIndex} 匹配的模型,该相机将无法处理图像。"); + continue; + } + + var processor = new CameraProcessor(camSetting.CameraIndex,camSetting.ModelID); + _processors.TryAdd(camSetting.CameraIndex, processor); + processor.Start(); + } + ThreadSafeLogger.Log($"检测协调器已初始化,启动了 {_processors.Count} 个相机处理线程。"); + } + + public static void EnqueueImage(int cameraIndex, Bitmap bmp) + { + if (_processors.TryGetValue(cameraIndex, out var processor)) + { + processor.EnqueueImage(bmp); + } + else + { + // 如果找不到处理器,必须释放Bitmap防止泄漏 + bmp?.Dispose(); + } + } + + // 供 CameraProcessor 回调,用以组装产品 + public static void AssembleProduct(ImageData data, string result) + { + var assembly = _productAssemblies.GetOrAdd(data.ProductId, (id) => new ProductAssembly(id, _enabledCameraCount)); + + if (assembly.AddResult(data.CameraIndex, result)) + { + string finalResult = assembly.GetFinalResult(); + ThreadSafeLogger.Log($"产品 #{assembly.ProductId} 已检测完毕,最终结果: {finalResult}"); + + // 只有在检测运行时,才触发事件 + if (IsDetectionRunning) + { + OnDetectionCompleted?.Invoke(null, new DetectionResultEventArgs(finalResult == "OK")); + } + + if (_productAssemblies.TryRemove(assembly.ProductId, out var finishedAssembly)) + { + finishedAssembly.Dispose(); + } + } + } + /// + /// 命令所有活动的相机处理器重置它们的内部计数器。 + /// + public static void ResetAllCounters() + { + foreach (var processor in _processors.Values) + { + processor.ResetCounter(); + } + ThreadSafeLogger.Log("所有相机处理器的产品计数器已重置。"); + } + + public static CameraProcessor GetProcessor(int cameraIndex) + { + _processors.TryGetValue(cameraIndex, out var p); + return p; + } + public static IEnumerable GetAllProcessors() + { + return _processors.Values; + } + + + public static void Shutdown() + { + foreach (var processor in _processors.Values) + { + processor.Dispose(); + } + _processors.Clear(); + + foreach (var assembly in _productAssemblies.Values) + { + assembly.Dispose(); + } + _productAssemblies.Clear(); + ThreadSafeLogger.Log("检测协调器已关闭。"); + } + } +} diff --git a/Check.Main/Infer/ModelSettings.cs b/Check.Main/Infer/ModelSettings.cs new file mode 100644 index 0000000..cf05f07 --- /dev/null +++ b/Check.Main/Infer/ModelSettings.cs @@ -0,0 +1,131 @@ +using Check.Main.Common; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +namespace Check.Main.Infer +{ + public enum DetectDevice + { + [Description("CPU")] + CPU = 0, + + [Description("GPU")] + GPU, + + [Description("VPU")] + VPU, + } + public enum ModelVersion + { + [Description("v8")] + V8 = 0, + + [Description("v11")] + V11, + } + public enum CheckModelType + { + [Description("分类")] + Classification, + + [Description("检测")] + ObjectDetection, + + [Description("OBB")] + ObbDetection, + + [Description("分割")] + Segmentation, + + [Description("位姿")] + PoseEstimation + } + + [Serializable] // 确保可被XML序列化 + public class ModelSettings : INotifyPropertyChanged, ICloneable + { + public event PropertyChangedEventHandler PropertyChanged; + + private int _id; + private string _name = "New Model"; + private string _path = ""; + private DetectDevice _checkDevice=DetectDevice.CPU; + private ModelVersion _mVersion=ModelVersion.V8; + private CheckModelType _mType = CheckModelType.Classification; + private bool _isEnabled = true; + + [Category("基本信息"), DisplayName("模型编号"), Description("模型的唯一标识符,用于与相机编号对应。")] + public int Id + { + get => _id; + set { if (_id != value) { _id = value; OnPropertyChanged(); } } + } + + [Category("基本信息"), DisplayName("模型名称"), Description("给模型起一个易于识别的别名。")] + public string Name + { + get => _name; + set { if (_name != value) { _name = value; OnPropertyChanged(); } } + } + [Category("基本信息"), DisplayName("推理设备"), Description("推理模型的设备。")] + [TypeConverter(typeof(EnumDescriptionTypeConverter))] + public DetectDevice CheckDevice + { + get => _checkDevice; + set { if (_checkDevice != value) { _checkDevice = value; OnPropertyChanged(); } } + } + + [Category("基本信息"), DisplayName("模型版本"), Description("推理模型的版本。")] + [TypeConverter(typeof(EnumDescriptionTypeConverter))] + public ModelVersion MVersion + { + get => _mVersion; + set { if (_mVersion != value) { _mVersion = value; OnPropertyChanged(); } } + } + [Category("基本信息"), DisplayName("模型类型"), Description("推理模型的类型。")] + [TypeConverter(typeof(EnumDescriptionTypeConverter))] + public CheckModelType MType + { + get => _mType; + set { if (_mType != value) { _mType = value; OnPropertyChanged(); } } + } + + [Category("基本信息"), DisplayName("是否启用"), Description("是否在程序启动时是否启用模型")] + public bool IsEnabled + { + get => _isEnabled; + set + { + if (_isEnabled != value) + { + _isEnabled = value; + OnPropertyChanged(); + } + } + } + + [Category("文件"), DisplayName("模型路径"), Description("选择模型文件(.onnx, .bin, etc., .pt)。")] + [Editor(typeof(System.Windows.Forms.Design.FileNameEditor), typeof(System.Drawing.Design.UITypeEditor))] + public string Path + { + get => _path; + set { if (_path != value) { _path = value; OnPropertyChanged(); } } + } + + protected void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + public object Clone() + { + return this.MemberwiseClone(); // 浅克隆对于这个类足够了 + } + } +} diff --git a/Check.Main/Infer/YoloModelManager.cs b/Check.Main/Infer/YoloModelManager.cs new file mode 100644 index 0000000..927da00 --- /dev/null +++ b/Check.Main/Infer/YoloModelManager.cs @@ -0,0 +1,102 @@ +using Check.Main.Common; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using YoloDotNet; +using YoloDotNet.Models; + +namespace Check.Main.Infer +{ + /// + /// 静态全局YOLO模型管理器。 + /// 负责在程序启动时加载所有模型,并在关闭时释放资源。 + /// + public static class YoloModelManager + { + // 使用 ConcurrentDictionary 保证线程安全 + private static readonly ConcurrentDictionary _loadedModels = new ConcurrentDictionary(); + + /// + /// 根据模型配置列表初始化所有YOLO模型实例。 + /// 应在程序启动时调用一次。 + /// + /// 模型配置列表。 + public static void Initialize(List modelSettings) + { + Shutdown(); // 先确保清理掉旧实例 + + if (modelSettings == null) return; + + ThreadSafeLogger.Log("开始加载YOLO模型..."); + foreach (var setting in modelSettings) + { + bool gpuUse = false; + if (setting.CheckDevice == DetectDevice.GPU) + { + gpuUse = true; + } + + if (string.IsNullOrEmpty(setting.Path) || !File.Exists(setting.Path)) + { + ThreadSafeLogger.Log($"[警告] 模型 '{setting.Name}' (ID: {setting.Id}) 路径无效或文件不存在,已跳过加载。"); + continue; + } + + try + { + // 创建YOLO实例 + var yolo = new Yolo(new YoloOptions + { + OnnxModel = setting.Path, + // 您可以根据需要从配置中读取这些值 + ModelType = (YoloDotNet.Enums.ModelType)setting.MType, + Cuda = gpuUse, // 推荐使用GPU + PrimeGpu = false + }); + + if (_loadedModels.TryAdd(setting.Id, yolo)) + { + ThreadSafeLogger.Log($"成功加载模型 '{setting.Name}' (ID: {setting.Id})。"); + } + } + catch (Exception ex) + { + ThreadSafeLogger.Log($"[错误] 加载模型 '{setting.Name}' (ID: {setting.Id}) 失败: {ex.Message}"); + } + } + ThreadSafeLogger.Log($"YOLO模型加载完成,共成功加载 {_loadedModels.Count} 个模型。"); + } + + /// + /// 获取指定ID的已加载YOLO模型。 + /// + /// 模型编号。 + /// Yolo实例,如果未找到则返回null。 + public static Yolo GetModel(int modelId) + { + _loadedModels.TryGetValue(modelId, out var yolo); + return yolo; + } + + /// + /// 释放所有已加载的YOLO模型资源。 + /// 应在程序关闭时调用。 + /// + public static void Shutdown() + { + if (_loadedModels.Count > 0) + { + ThreadSafeLogger.Log("正在释放所有YOLO模型..."); + foreach (var yolo in _loadedModels.Values) + { + yolo?.Dispose(); + } + _loadedModels.Clear(); + ThreadSafeLogger.Log("所有YOLO模型已释放。"); + } + } + } +} diff --git a/Check.Main/Program.cs b/Check.Main/Program.cs new file mode 100644 index 0000000..0354e6b --- /dev/null +++ b/Check.Main/Program.cs @@ -0,0 +1,28 @@ +using System.Diagnostics; + +namespace Check.Main +{ + internal static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + var current = Process.GetCurrentProcess(); + var others = Process.GetProcessesByName(current.ProcessName) + .Where(p => p.Id != current.Id); + if (others.Any()) + { + MessageBox.Show("ѾУظ", "ʾ", + MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + } + // To customize application configuration such as set high DPI settings or default font, + // see https://aka.ms/applicationconfiguration. + ApplicationConfiguration.Initialize(); + Application.Run(new FrmMain()); + } + } +} \ No newline at end of file diff --git a/Check.Main/Result/ProductResult.cs b/Check.Main/Result/ProductResult.cs new file mode 100644 index 0000000..d5be058 --- /dev/null +++ b/Check.Main/Result/ProductResult.cs @@ -0,0 +1,74 @@ +using Check.Main.Common; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Check.Main.Result +{ + /// + /// 代表一个待检测产品的类,存储来自多个相机的图像 + /// + public class ProductResult + { + /// + /// 产品唯一ID,可以是时间戳或触发计数 + /// + public long ProductID { get; } + + /// + /// 存储每个相机名称和其拍摄到的图像 + /// + public Dictionary CapturedImages { get; } + + public ProductResult(long productID) + { + ProductID = productID; + CapturedImages = new Dictionary(); + } + + /// + /// 添加一张某个相机拍摄的图像 + /// + /// 相机名称 + /// 拍摄的图像 + public void AddImage(string cameraName, Bitmap image) + { + if (!CapturedImages.ContainsKey(cameraName)) + { + CapturedImages.Add(cameraName, image); + } + else + { + // 如果这个键已经存在,说明发生了逻辑错误。 + // 我们不应该持有这个新的 image 对象,必须释放它以防泄漏。 + ThreadSafeLogger.Log($"[警告] 相机 {cameraName} 为产品 #{this.ProductID} 发送了重复的图像。多余的图像将被丢弃。"); + image?.Dispose(); + } + } + + /// + /// 检查是否所有预期的相机都已完成拍摄 + /// + /// 预期的相机数量 + /// + public bool IsComplete(int expectedCameraCount) + { + return CapturedImages.Count == expectedCameraCount; + } + + /// + /// 释放所有图像资源,防止内存泄漏 + /// + public void Dispose() + { + foreach (var image in CapturedImages.Values) + { + image?.Dispose(); + } + CapturedImages.Clear(); + } + } +} diff --git a/Check.Main/UI/FormControlPanel.Designer.cs b/Check.Main/UI/FormControlPanel.Designer.cs new file mode 100644 index 0000000..3e0283e --- /dev/null +++ b/Check.Main/UI/FormControlPanel.Designer.cs @@ -0,0 +1,113 @@ +namespace Check.Main.UI +{ + partial class FormControlPanel + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.uiTableLayoutPanel1 = new Sunny.UI.UITableLayoutPanel(); + this.btnStartDevice = new Sunny.UI.UIButton(); + this.btnStartCheck = new Sunny.UI.UIButton(); + this.uiTableLayoutPanel1.SuspendLayout(); + this.SuspendLayout(); + // + // uiTableLayoutPanel1 + // + this.uiTableLayoutPanel1.ColumnCount = 2; + this.uiTableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.uiTableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.uiTableLayoutPanel1.Controls.Add(this.btnStartDevice, 0, 1); + this.uiTableLayoutPanel1.Controls.Add(this.btnStartCheck, 0, 3); + this.uiTableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.uiTableLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.uiTableLayoutPanel1.Name = "uiTableLayoutPanel1"; + this.uiTableLayoutPanel1.RowCount = 5; + this.uiTableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 11.38585F)); + this.uiTableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 35.35353F)); + this.uiTableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 7.575758F)); + this.uiTableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.83838F)); + this.uiTableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 11.38585F)); + this.uiTableLayoutPanel1.Size = new System.Drawing.Size(230, 198); + this.uiTableLayoutPanel1.TabIndex = 0; + this.uiTableLayoutPanel1.TagString = null; + // + // btnStartDevice + // + this.uiTableLayoutPanel1.SetColumnSpan(this.btnStartDevice, 2); + this.btnStartDevice.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnStartDevice.Dock = System.Windows.Forms.DockStyle.Fill; + this.btnStartDevice.FillPressColor = System.Drawing.Color.LimeGreen; + this.btnStartDevice.FillSelectedColor = System.Drawing.Color.LimeGreen; + this.btnStartDevice.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.btnStartDevice.Location = new System.Drawing.Point(3, 25); + this.btnStartDevice.MinimumSize = new System.Drawing.Size(1, 1); + this.btnStartDevice.Name = "btnStartDevice"; + this.btnStartDevice.Size = new System.Drawing.Size(224, 64); + this.btnStartDevice.TabIndex = 0; + this.btnStartDevice.Text = "启动设备"; + this.btnStartDevice.TipsFont = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.btnStartDevice.Click += new System.EventHandler(this.btnStartDevice_Click); + // + // btnStartCheck + // + this.uiTableLayoutPanel1.SetColumnSpan(this.btnStartCheck, 2); + this.btnStartCheck.Cursor = System.Windows.Forms.Cursors.Hand; + this.btnStartCheck.Dock = System.Windows.Forms.DockStyle.Fill; + this.btnStartCheck.FillPressColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(192)))), ((int)(((byte)(0))))); + this.btnStartCheck.FillSelectedColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(192)))), ((int)(((byte)(0))))); + this.btnStartCheck.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.btnStartCheck.Location = new System.Drawing.Point(3, 110); + this.btnStartCheck.MinimumSize = new System.Drawing.Size(1, 1); + this.btnStartCheck.Name = "btnStartCheck"; + this.btnStartCheck.Size = new System.Drawing.Size(224, 61); + this.btnStartCheck.TabIndex = 1; + this.btnStartCheck.Text = "开始检测"; + this.btnStartCheck.TipsFont = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.btnStartCheck.Click += new System.EventHandler(this.btnStartCheck_Click); + // + // FormControlPanel + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(230, 198); + this.ControlBox = false; + this.Controls.Add(this.uiTableLayoutPanel1); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "FormControlPanel"; + this.Text = "启动管理"; + this.uiTableLayoutPanel1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private Sunny.UI.UITableLayoutPanel uiTableLayoutPanel1; + private Sunny.UI.UIButton btnStartDevice; + private Sunny.UI.UIButton btnStartCheck; + } +} \ No newline at end of file diff --git a/Check.Main/UI/FormControlPanel.cs b/Check.Main/UI/FormControlPanel.cs new file mode 100644 index 0000000..578b166 --- /dev/null +++ b/Check.Main/UI/FormControlPanel.cs @@ -0,0 +1,264 @@ +using Check.Main.Camera; +using Check.Main.Common; +using Check.Main.Infer; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; + +namespace Check.Main.UI +{ + public partial class FormControlPanel : DockContent + { + + private bool _isDeviceReady = false; // 新的状态:设备是否已准备好 + private bool _isDetecting = false; // 新的状态:是否正在检测中 + + // 用于跟踪设备运行状态的私有标志 + private bool _isDeviceRunning = false; + public FormControlPanel() + { + InitializeComponent(); + + ConfigurationManager.OnConfigurationChanged += HandleConfigurationChanged; + UpdateUI(); + + } + /// + /// 处理全局配置在其他地方(如 FrmConfig)被更改的事件 + /// + private void HandleConfigurationChanged() + { + // 这是一个安全措施。如果设备正在运行时配置发生了变化, + // 最安全的做法是停止设备,以防止出现不可预知的行为。 + if (_isDeviceRunning) + { + // 使用 Invoke 确保UI更新在正确的线程上执行 + this.Invoke((Action)(() => + { + ThreadSafeLogger.Log("相机配置已在运行时发生更改,设备将自动停止。请重新启动设备以应用新配置。"); + //MessageBox.Show("相机配置已在运行时发生更改,设备将自动停止。请重新启动设备以应用新配置。", + // "配置变更", MessageBoxButtons.OK, MessageBoxIcon.Information); + // 触发与点击“关闭设备”按钮相同的逻辑 + btnStartDevice_Click(this, EventArgs.Empty); + })); + } + } + private void btnStartDevice_Click(object sender, EventArgs e) + { + if (_isDeviceReady)//_isDeviceRunning + { + // --- 关闭流程 --- + ThreadSafeLogger.Log("用户点击“关闭设备”,开始完整关闭流程..."); + // 如果正在检测,先停止它 + if (_isDetecting) + { + btnStartCheck_Click(this, EventArgs.Empty); // 调用停止检测的逻辑 + } + var mainForm = this.DockPanel.FindForm() as FrmMain; + CameraManager.Shutdown(); + _isDeviceReady = false; + + //// 1. 停止硬触发模拟器 + //CameraManager.StopHardwareTriggerSimulator(); + + //// 2. 如果检测正在运行,则停止 + //if (DetectionCoordinator.IsDetectionRunning) + //{ + // DetectionCoordinator.StopDetection(); + // UpdateDetectionButtonUI(); + //} + + // 3. 执行完整的系统关闭(包括相机硬件和检测协调器) + //CameraManager.Shutdown(); + //YoloModelManager.Shutdown(); + //_isDeviceRunning = false; + } + else + { + // --- 启动流程 --- + ThreadSafeLogger.Log("用户点击“启动设备”,开始新的启动流程..."); + + // 1. 从单一数据源获取完整的配置对象 + var config = ConfigurationManager.GetCurrentConfig(); + // 2. 验证相机配置的有效性 + if (config.CameraSettings == null || !config.CameraSettings.Any(c => c.IsEnabled)) + { + ThreadSafeLogger.Log("没有已启用的相机配置,启动中止。"); + return; + } + // 3. 获取主窗体引用 + var mainForm = this.DockPanel.FindForm() as FrmMain; + if (mainForm == null) + { + ThreadSafeLogger.Log("无法找到主窗体,启动中止。"); + return; + } + // 4. 执行新的启动流程: + // 第一步:初始化系统。这会准备好相机硬件、UI窗口和所有后台处理线程。 + CameraManager.PrepareAll(config, mainForm); + _isDeviceReady = true; + + + //YoloModelManager.Initialize(config.ModelSettings); + //CameraManager.Initialize(config, mainForm); + //// 第二步:命令所有相机开始采集图像。 + //CameraManager.StartAll(); + + //// 5. 如果有任何相机配置为软触发模式,我们启动模拟器来模拟触发信号 + //if (config.CameraSettings.Any(c => c.IsEnabled && c.TriggerMode == TriggerModeType.Software)) + //{ + // ThreadSafeLogger.Log("检测到软触发相机,启动触发模拟器。"); + // CameraManager.TriggerInterval = 100; // 根据需要设置间隔 + // CameraManager.StartHardwareTriggerSimulator(); + //} + + //_isDeviceRunning = true; + } + UpdateUI();//UpdateDeviceButtonUI(); + } + + private void btnStartCheck_Click(object sender, EventArgs e) + { + if (_isDetecting) + { + // --- 停止检测 --- + ThreadSafeLogger.Log("用户点击“停止检测”,暂停数据流..."); + // 停止硬触发模拟器 + CameraManager.StopHardwareTriggerSimulator(); + // 停止相机采集 + CameraManager.StopAll(); + + // 停止统计 + DetectionCoordinator.StopDetection(); + + _isDetecting = false; + } + else + { + // --- 开始检测 --- + ThreadSafeLogger.Log("用户点击“开始检测”,启动数据流..."); + + // 命令相机开始采集 + CameraManager.StartAll(); + + // 启动硬触发模拟器(如果需要) + var config = ConfigurationManager.GetCurrentConfig(); + if (config.CameraSettings.Any(c => c.IsEnabled && c.TriggerMode == TriggerModeType.Software)) + { + CameraManager.TriggerInterval = 100; + CameraManager.StartHardwareTriggerSimulator(); + } + + // 开始统计 + DetectionCoordinator.StartDetection(); + + _isDetecting = true; + } + UpdateUI(); + + //if (!_isDeviceRunning && !DetectionCoordinator.IsDetectionRunning) + //{ + // ThreadSafeLogger.Log("设备未启动,无法开始检测。"); + // return; + //} + + //// 现在调用 DetectionCoordinator 中的方法 + //if (DetectionCoordinator.IsDetectionRunning) + //{ + // DetectionCoordinator.StopDetection(); + //} + //else + //{ + // DetectionCoordinator.StartDetection(); + //} + //UpdateDetectionButtonUI(); + } + + #region UI 更新辅助方法 + + /// + /// 根据设备运行状态更新“设备”按钮的UI(文本和颜色)。 + /// + private void UpdateDeviceButtonUI() + { + if (_isDeviceRunning) + { + btnStartDevice.Text = "关闭设备"; + btnStartDevice.BackColor = Color.Salmon; + } + else + { + btnStartDevice.Text = "启动设备"; + btnStartDevice.BackColor = SystemColors.Control; + } + } + // 统一的UI更新方法 + private void UpdateUI() + { + // --- 更新“设备”按钮 --- + if (_isDeviceReady) + { + btnStartDevice.Text = "关闭设备"; + btnStartDevice.BackColor = Color.Salmon; + btnStartCheck.Enabled = true; // 设备就绪后,检测按钮才可用 + } + else + { + btnStartDevice.Text = "启动设备"; + btnStartDevice.BackColor = SystemColors.Control; + btnStartCheck.Enabled = false; // 设备未就绪,检测按钮不可用 + } + + // --- 更新“检测”按钮 --- + if (_isDetecting) + { + btnStartCheck.Text = "停止检测"; + btnStartCheck.BackColor = Color.LightGreen; + btnStartDevice.Enabled = false; // 正在检测时,不允许关闭设备 + } + else + { + btnStartCheck.Text = "开始检测"; + btnStartCheck.BackColor = SystemColors.Control; + if (_isDeviceReady) btnStartDevice.Enabled = true; // 停止检测后,允许关闭设备 + } + } + + /// + /// 根据检测运行状态更新“检测”按钮的UI(文本和颜色)。 + /// + private void UpdateDetectionButtonUI() + { + //if (CameraManager.IsDetectionRunning) + //{ + // btnStartCheck.Text = "停止检测"; + // btnStartCheck.BackColor = Color.LightGreen; + //} + //else + //{ + // btnStartCheck.Text = "启动检测"; + // btnStartCheck.BackColor = SystemColors.Control; + //} + if (DetectionCoordinator.IsDetectionRunning) + { + btnStartCheck.Text = "停止检测"; + btnStartCheck.BackColor = Color.LightGreen; + } + else + { + btnStartCheck.Text = "启动检测"; + btnStartCheck.BackColor = SystemColors.Control; + } + + } + + #endregion + } +} diff --git a/Check.Main/UI/FormControlPanel.resx b/Check.Main/UI/FormControlPanel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Check.Main/UI/FormControlPanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Check.Main/UI/FormImageDisplay.Designer.cs b/Check.Main/UI/FormImageDisplay.Designer.cs new file mode 100644 index 0000000..3e9a70e --- /dev/null +++ b/Check.Main/UI/FormImageDisplay.Designer.cs @@ -0,0 +1,46 @@ +namespace Check.Main.UI +{ + partial class FormImageDisplay + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.SuspendLayout(); + // + // FormImageDisplay + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(508, 290); + this.Name = "FormImageDisplay"; + this.Text = "FormImageDisplay"; + this.ResumeLayout(false); + + } + + #endregion + } +} \ No newline at end of file diff --git a/Check.Main/UI/FormImageDisplay.cs b/Check.Main/UI/FormImageDisplay.cs new file mode 100644 index 0000000..a1bdc8a --- /dev/null +++ b/Check.Main/UI/FormImageDisplay.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; + +namespace Check.Main.UI +{ + public partial class FormImageDisplay : DockContent + { + /// + /// 相机名称 + /// + public string CameraName { get; set; } + + /// + /// 当此显示窗口发生特定事件时(如ROI裁剪),触发此事件以通知外部(如日志系统) + /// + public event Action OnDisplayEvent; + + // 使用我们全新的自定义控件 + private ZoomPictureBox zoomPictureBox; + public FormImageDisplay() + { + InitializeComponent(); + + // 实例化新的控件 + zoomPictureBox = new ZoomPictureBox + { + Dock = DockStyle.Fill, + // 其他属性可以在这里设置,例如 + // RectangleColor = Color.LawnGreen, + // BackgroundFillColor = Color.FromArgb(45, 45, 48) + }; + this.Controls.Add(zoomPictureBox); + + // 订阅自定义控件的ROI裁剪完成事件 + zoomPictureBox.CroppingEnabled = false; + //zoomPictureBox.Cropped += ZoomPictureBox_Cropped; + } + /// + /// 更新显示的图像(线程安全)。 + /// 此方法现在将图像设置到 ZoomPictureBox1 控件中。 + /// + /// 从相机事件传来的原始Bitmap + public void UpdateImage(Bitmap image) + { + if (zoomPictureBox != null && !zoomPictureBox.IsDisposed) + { + zoomPictureBox.SetImageThreadSafe(image); + } + else + { + // 如果PictureBox已经被释放,那么我们也应该释放这个多余的图像 + image?.Dispose(); + } + } + // 重写 Close 方法,确保在窗口关闭时,内部的控件和资源也能被妥善处理 + public new void Close() + { + // 取消事件订阅,防止内存泄漏 + if (zoomPictureBox != null) + { + //zoomPictureBox.Cropped -= ZoomPictureBox_Cropped; + } + base.Close(); + } + } +} diff --git a/Check.Main/UI/FormImageDisplay.resx b/Check.Main/UI/FormImageDisplay.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Check.Main/UI/FormImageDisplay.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Check.Main/UI/FormStatistics.Designer.cs b/Check.Main/UI/FormStatistics.Designer.cs new file mode 100644 index 0000000..3d2679a --- /dev/null +++ b/Check.Main/UI/FormStatistics.Designer.cs @@ -0,0 +1,245 @@ +namespace Check.Main.UI +{ + partial class FormStatistics + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormStatistics)); + this.uiTableLayoutPanel1 = new Sunny.UI.UITableLayoutPanel(); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.uiLabel1 = new Sunny.UI.UILabel(); + this.uiLabel2 = new Sunny.UI.UILabel(); + this.uiLabel3 = new Sunny.UI.UILabel(); + this.uiLabel4 = new Sunny.UI.UILabel(); + this.txtOKNum = new Sunny.UI.UITextBox(); + this.txtNGNum = new Sunny.UI.UITextBox(); + this.txtTotal = new Sunny.UI.UITextBox(); + this.txtYieldRate = new Sunny.UI.UITextBox(); + this.toolStripButtonRest = new System.Windows.Forms.ToolStripButton(); + this.uiTableLayoutPanel1.SuspendLayout(); + this.toolStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // uiTableLayoutPanel1 + // + this.uiTableLayoutPanel1.ColumnCount = 2; + this.uiTableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 45.88745F)); + this.uiTableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 54.11255F)); + this.uiTableLayoutPanel1.Controls.Add(this.txtYieldRate, 1, 3); + this.uiTableLayoutPanel1.Controls.Add(this.txtTotal, 1, 2); + this.uiTableLayoutPanel1.Controls.Add(this.txtNGNum, 1, 1); + this.uiTableLayoutPanel1.Controls.Add(this.toolStrip1, 0, 4); + this.uiTableLayoutPanel1.Controls.Add(this.uiLabel1, 0, 0); + this.uiTableLayoutPanel1.Controls.Add(this.uiLabel2, 0, 1); + this.uiTableLayoutPanel1.Controls.Add(this.uiLabel3, 0, 2); + this.uiTableLayoutPanel1.Controls.Add(this.uiLabel4, 0, 3); + this.uiTableLayoutPanel1.Controls.Add(this.txtOKNum, 1, 0); + this.uiTableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.uiTableLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.uiTableLayoutPanel1.Name = "uiTableLayoutPanel1"; + this.uiTableLayoutPanel1.RowCount = 5; + this.uiTableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F)); + this.uiTableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F)); + this.uiTableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F)); + this.uiTableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F)); + this.uiTableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20F)); + this.uiTableLayoutPanel1.Size = new System.Drawing.Size(231, 228); + this.uiTableLayoutPanel1.TabIndex = 0; + this.uiTableLayoutPanel1.TagString = null; + // + // toolStrip1 + // + this.uiTableLayoutPanel1.SetColumnSpan(this.toolStrip1, 2); + this.toolStrip1.Dock = System.Windows.Forms.DockStyle.Fill; + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripButtonRest}); + this.toolStrip1.Location = new System.Drawing.Point(0, 180); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(231, 48); + this.toolStrip1.TabIndex = 0; + this.toolStrip1.Text = "toolStrip1"; + // + // uiLabel1 + // + this.uiLabel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.uiLabel1.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.uiLabel1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48))))); + this.uiLabel1.Location = new System.Drawing.Point(3, 0); + this.uiLabel1.Name = "uiLabel1"; + this.uiLabel1.Size = new System.Drawing.Size(100, 45); + this.uiLabel1.TabIndex = 1; + this.uiLabel1.Text = "良品数"; + this.uiLabel1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // uiLabel2 + // + this.uiLabel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.uiLabel2.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.uiLabel2.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48))))); + this.uiLabel2.Location = new System.Drawing.Point(3, 45); + this.uiLabel2.Name = "uiLabel2"; + this.uiLabel2.Size = new System.Drawing.Size(100, 45); + this.uiLabel2.TabIndex = 2; + this.uiLabel2.Text = "不良品数量"; + this.uiLabel2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // uiLabel3 + // + this.uiLabel3.Dock = System.Windows.Forms.DockStyle.Fill; + this.uiLabel3.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.uiLabel3.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48))))); + this.uiLabel3.Location = new System.Drawing.Point(3, 90); + this.uiLabel3.Name = "uiLabel3"; + this.uiLabel3.Size = new System.Drawing.Size(100, 45); + this.uiLabel3.TabIndex = 3; + this.uiLabel3.Text = "总数"; + this.uiLabel3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // uiLabel4 + // + this.uiLabel4.Dock = System.Windows.Forms.DockStyle.Fill; + this.uiLabel4.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.uiLabel4.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(48)))), ((int)(((byte)(48))))); + this.uiLabel4.Location = new System.Drawing.Point(3, 135); + this.uiLabel4.Name = "uiLabel4"; + this.uiLabel4.Size = new System.Drawing.Size(100, 45); + this.uiLabel4.TabIndex = 4; + this.uiLabel4.Text = "良品率"; + this.uiLabel4.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // txtOKNum + // + this.txtOKNum.Cursor = System.Windows.Forms.Cursors.IBeam; + this.txtOKNum.Dock = System.Windows.Forms.DockStyle.Fill; + this.txtOKNum.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.txtOKNum.Location = new System.Drawing.Point(110, 5); + this.txtOKNum.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.txtOKNum.MinimumSize = new System.Drawing.Size(1, 16); + this.txtOKNum.Name = "txtOKNum"; + this.txtOKNum.Padding = new System.Windows.Forms.Padding(5); + this.txtOKNum.ShowText = false; + this.txtOKNum.Size = new System.Drawing.Size(117, 35); + this.txtOKNum.TabIndex = 5; + this.txtOKNum.Text = "0"; + this.txtOKNum.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter; + this.txtOKNum.Watermark = ""; + // + // txtNGNum + // + this.txtNGNum.Cursor = System.Windows.Forms.Cursors.IBeam; + this.txtNGNum.Dock = System.Windows.Forms.DockStyle.Fill; + this.txtNGNum.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.txtNGNum.Location = new System.Drawing.Point(110, 50); + this.txtNGNum.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.txtNGNum.MinimumSize = new System.Drawing.Size(1, 16); + this.txtNGNum.Name = "txtNGNum"; + this.txtNGNum.Padding = new System.Windows.Forms.Padding(5); + this.txtNGNum.ShowText = false; + this.txtNGNum.Size = new System.Drawing.Size(117, 35); + this.txtNGNum.TabIndex = 6; + this.txtNGNum.Text = "0"; + this.txtNGNum.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter; + this.txtNGNum.Watermark = ""; + // + // txtTotal + // + this.txtTotal.Cursor = System.Windows.Forms.Cursors.IBeam; + this.txtTotal.Dock = System.Windows.Forms.DockStyle.Fill; + this.txtTotal.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.txtTotal.Location = new System.Drawing.Point(110, 95); + this.txtTotal.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.txtTotal.MinimumSize = new System.Drawing.Size(1, 16); + this.txtTotal.Name = "txtTotal"; + this.txtTotal.Padding = new System.Windows.Forms.Padding(5); + this.txtTotal.ShowText = false; + this.txtTotal.Size = new System.Drawing.Size(117, 35); + this.txtTotal.TabIndex = 7; + this.txtTotal.Text = "0"; + this.txtTotal.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter; + this.txtTotal.Watermark = ""; + // + // txtYieldRate + // + this.txtYieldRate.Cursor = System.Windows.Forms.Cursors.IBeam; + this.txtYieldRate.Dock = System.Windows.Forms.DockStyle.Fill; + this.txtYieldRate.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.txtYieldRate.Location = new System.Drawing.Point(110, 140); + this.txtYieldRate.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.txtYieldRate.MinimumSize = new System.Drawing.Size(1, 16); + this.txtYieldRate.Name = "txtYieldRate"; + this.txtYieldRate.Padding = new System.Windows.Forms.Padding(5); + this.txtYieldRate.ShowText = false; + this.txtYieldRate.Size = new System.Drawing.Size(117, 35); + this.txtYieldRate.TabIndex = 8; + this.txtYieldRate.Text = "0"; + this.txtYieldRate.TextAlignment = System.Drawing.ContentAlignment.MiddleCenter; + this.txtYieldRate.Watermark = ""; + // + // toolStripButtonRest + // + this.toolStripButtonRest.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.toolStripButtonRest.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButtonRest.Image"))); + this.toolStripButtonRest.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonRest.Name = "toolStripButtonRest"; + this.toolStripButtonRest.Size = new System.Drawing.Size(60, 45); + this.toolStripButtonRest.Text = "重置计数"; + this.toolStripButtonRest.Click += new System.EventHandler(this.toolStripButtonRest_Click); + // + // FormStatistics + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(231, 228); + this.ControlBox = false; + this.Controls.Add(this.uiTableLayoutPanel1); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "FormStatistics"; + this.Text = "统计"; + this.uiTableLayoutPanel1.ResumeLayout(false); + this.uiTableLayoutPanel1.PerformLayout(); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private Sunny.UI.UITableLayoutPanel uiTableLayoutPanel1; + private System.Windows.Forms.ToolStrip toolStrip1; + private Sunny.UI.UITextBox txtYieldRate; + private Sunny.UI.UITextBox txtTotal; + private Sunny.UI.UITextBox txtNGNum; + private System.Windows.Forms.ToolStripButton toolStripButtonRest; + private Sunny.UI.UILabel uiLabel1; + private Sunny.UI.UILabel uiLabel2; + private Sunny.UI.UILabel uiLabel3; + private Sunny.UI.UILabel uiLabel4; + private Sunny.UI.UITextBox txtOKNum; + } +} \ No newline at end of file diff --git a/Check.Main/UI/FormStatistics.cs b/Check.Main/UI/FormStatistics.cs new file mode 100644 index 0000000..bb927a2 --- /dev/null +++ b/Check.Main/UI/FormStatistics.cs @@ -0,0 +1,89 @@ +using Check.Main.Camera; +using Check.Main.Common; +using Check.Main.Infer; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; + +namespace Check.Main.UI +{ + public partial class FormStatistics : DockContent + { + private readonly StatisticsData _statisticsData; + + /// + /// 将私有字段通过公共属性暴露,以便外部(如FormMain)访问。 + /// + public StatisticsData CurrentStatistics => _statisticsData; + public FormStatistics() + { + InitializeComponent(); + _statisticsData = new StatisticsData(); + + // 订阅CameraManager的检测完成事件 + DetectionCoordinator.OnDetectionCompleted += CameraManager_OnDetectionCompleted; + // 初始化UI显示 + UpdateUI(); + } + // 当CameraManager发布检测结果时,此方法被调用 + private void CameraManager_OnDetectionCompleted(object sender, DetectionResultEventArgs e) + { + // 更新统计数据 + _statisticsData.UpdateWithResult(e.IsOK); + + // 在UI线程上更新界面显示 + UpdateUI(); + } + // 更新所有标签的文本 + private void UpdateUI() + { + // 使用Invoke确保线程安全 + if (this.InvokeRequired) + { + this.Invoke(new Action(UpdateUI)); + return; + } + + txtOKNum.Text = _statisticsData.GoodCount.ToString(); + txtNGNum.Text = _statisticsData.NgCount.ToString(); + txtTotal.Text = _statisticsData.TotalCount.ToString(); + // 将良率格式化为百分比 + txtYieldRate.Text = _statisticsData.YieldRate.ToString("P2", CultureInfo.InvariantCulture); + + // 根据良率改变颜色以示提醒 + if (_statisticsData.YieldRate < 0.9 && _statisticsData.TotalCount > 10) + { + txtYieldRate.ForeColor = Color.Red; + } + else + { + txtYieldRate.ForeColor = Color.ForestGreen; + } + } + + private void toolStripButtonRest_Click(object sender, EventArgs e) + { + StatisticsExporter.ExportToExcel(CurrentStatistics, "Reset"); + + _statisticsData.Reset(); + // 同时重置产品ID计数器 + DetectionCoordinator.ResetAllCounters(); + UpdateUI(); + ThreadSafeLogger.Log("统计数据已重置。"); + } + // 窗体关闭时,取消事件订阅,防止内存泄漏 + protected override void OnFormClosing(FormClosingEventArgs e) + { + DetectionCoordinator.OnDetectionCompleted -= CameraManager_OnDetectionCompleted; + base.OnFormClosing(e); + } + } +} diff --git a/Check.Main/UI/FormStatistics.resx b/Check.Main/UI/FormStatistics.resx new file mode 100644 index 0000000..013a61e --- /dev/null +++ b/Check.Main/UI/FormStatistics.resx @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG + YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 + 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw + bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc + VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 + c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 + Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo + mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ + kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D + TgDQASA1MVpwzwAAAABJRU5ErkJggg== + + + \ No newline at end of file diff --git a/Check.Main/UI/FrmCamConfig.Designer.cs b/Check.Main/UI/FrmCamConfig.Designer.cs new file mode 100644 index 0000000..4a75ee7 --- /dev/null +++ b/Check.Main/UI/FrmCamConfig.Designer.cs @@ -0,0 +1,175 @@ +namespace Check.Main.UI +{ + partial class FrmCamConfig + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmCamConfig)); + tableLayoutPanel1 = new TableLayoutPanel(); + toolStrip1 = new ToolStrip(); + toolBtnAdd = new ToolStripButton(); + toolBtnRemove = new ToolStripButton(); + toolBtnSet = new ToolStripButton(); + splitContainer1 = new SplitContainer(); + listBoxCameras = new ListBox(); + propertyGrid1 = new PropertyGrid(); + tableLayoutPanel1.SuspendLayout(); + toolStrip1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit(); + splitContainer1.Panel1.SuspendLayout(); + splitContainer1.Panel2.SuspendLayout(); + splitContainer1.SuspendLayout(); + SuspendLayout(); + // + // tableLayoutPanel1 + // + tableLayoutPanel1.ColumnCount = 1; + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F)); + tableLayoutPanel1.Controls.Add(toolStrip1, 0, 0); + tableLayoutPanel1.Controls.Add(splitContainer1, 0, 1); + tableLayoutPanel1.Dock = DockStyle.Fill; + tableLayoutPanel1.Location = new Point(0, 0); + tableLayoutPanel1.Margin = new Padding(4, 4, 4, 4); + tableLayoutPanel1.Name = "tableLayoutPanel1"; + tableLayoutPanel1.RowCount = 2; + tableLayoutPanel1.RowStyles.Add(new RowStyle()); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F)); + tableLayoutPanel1.Size = new Size(632, 560); + tableLayoutPanel1.TabIndex = 0; + // + // toolStrip1 + // + toolStrip1.Items.AddRange(new ToolStripItem[] { toolBtnAdd, toolBtnRemove, toolBtnSet }); + toolStrip1.Location = new Point(0, 0); + toolStrip1.Name = "toolStrip1"; + toolStrip1.Size = new Size(632, 25); + toolStrip1.TabIndex = 0; + toolStrip1.Text = "toolStrip1"; + // + // toolBtnAdd + // + toolBtnAdd.DisplayStyle = ToolStripItemDisplayStyle.Text; + toolBtnAdd.Image = (Image)resources.GetObject("toolBtnAdd.Image"); + toolBtnAdd.ImageTransparentColor = Color.Magenta; + toolBtnAdd.Name = "toolBtnAdd"; + toolBtnAdd.Size = new Size(36, 22); + toolBtnAdd.Text = "添加"; + toolBtnAdd.Click += toolBtnAdd_Click; + // + // toolBtnRemove + // + toolBtnRemove.DisplayStyle = ToolStripItemDisplayStyle.Text; + toolBtnRemove.Image = (Image)resources.GetObject("toolBtnRemove.Image"); + toolBtnRemove.ImageTransparentColor = Color.Magenta; + toolBtnRemove.Name = "toolBtnRemove"; + toolBtnRemove.Size = new Size(36, 22); + toolBtnRemove.Text = "移除"; + toolBtnRemove.Click += toolBtnRemove_Click; + // + // toolBtnSet + // + toolBtnSet.DisplayStyle = ToolStripItemDisplayStyle.Text; + toolBtnSet.Image = (Image)resources.GetObject("toolBtnSet.Image"); + toolBtnSet.ImageTransparentColor = Color.Magenta; + toolBtnSet.Name = "toolBtnSet"; + toolBtnSet.Size = new Size(60, 22); + toolBtnSet.Text = "应用配置"; + toolBtnSet.Click += toolBtnSet_Click; + // + // splitContainer1 + // + splitContainer1.Dock = DockStyle.Fill; + splitContainer1.Location = new Point(4, 29); + splitContainer1.Margin = new Padding(4, 4, 4, 4); + splitContainer1.Name = "splitContainer1"; + // + // splitContainer1.Panel1 + // + splitContainer1.Panel1.Controls.Add(listBoxCameras); + // + // splitContainer1.Panel2 + // + splitContainer1.Panel2.Controls.Add(propertyGrid1); + splitContainer1.Size = new Size(624, 527); + splitContainer1.SplitterDistance = 210; + splitContainer1.SplitterWidth = 5; + splitContainer1.TabIndex = 1; + // + // listBoxCameras + // + listBoxCameras.Dock = DockStyle.Fill; + listBoxCameras.FormattingEnabled = true; + listBoxCameras.ItemHeight = 17; + listBoxCameras.Location = new Point(0, 0); + listBoxCameras.Margin = new Padding(4, 4, 4, 4); + listBoxCameras.Name = "listBoxCameras"; + listBoxCameras.Size = new Size(210, 527); + listBoxCameras.TabIndex = 0; + listBoxCameras.SelectedIndexChanged += listBoxCameras_SelectedIndexChanged; + // + // propertyGrid1 + // + propertyGrid1.Dock = DockStyle.Fill; + propertyGrid1.Location = new Point(0, 0); + propertyGrid1.Margin = new Padding(4, 4, 4, 4); + propertyGrid1.Name = "propertyGrid1"; + propertyGrid1.Size = new Size(409, 527); + propertyGrid1.TabIndex = 0; + // + // FrmCamConfig + // + AutoScaleDimensions = new SizeF(7F, 17F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(632, 560); + Controls.Add(tableLayoutPanel1); + Margin = new Padding(4, 4, 4, 4); + Name = "FrmCamConfig"; + Text = "属性配置"; + tableLayoutPanel1.ResumeLayout(false); + tableLayoutPanel1.PerformLayout(); + toolStrip1.ResumeLayout(false); + toolStrip1.PerformLayout(); + splitContainer1.Panel1.ResumeLayout(false); + splitContainer1.Panel2.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)splitContainer1).EndInit(); + splitContainer1.ResumeLayout(false); + ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.ToolStrip toolStrip1; + private System.Windows.Forms.SplitContainer splitContainer1; + private System.Windows.Forms.ListBox listBoxCameras; + private System.Windows.Forms.PropertyGrid propertyGrid1; + private System.Windows.Forms.ToolStripButton toolBtnAdd; + private System.Windows.Forms.ToolStripButton toolBtnRemove; + private System.Windows.Forms.ToolStripButton toolBtnSet; + } +} \ No newline at end of file diff --git a/Check.Main/UI/FrmCamConfig.cs b/Check.Main/UI/FrmCamConfig.cs new file mode 100644 index 0000000..becaf95 --- /dev/null +++ b/Check.Main/UI/FrmCamConfig.cs @@ -0,0 +1,193 @@ +using Check.Main.Camera; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.Xml.Serialization; +using WeifenLuo.WinFormsUI.Docking; + +namespace Check.Main.UI +{ + public partial class FrmCamConfig : DockContent + { + // public List _settingsList = new List(); + public List _settingsList { get; private set; } + private readonly string _configFilePath = Path.Combine(Application.StartupPath, "cameras.xml"); + public FrmCamConfig() + { + InitializeComponent(); + _settingsList = new List(); + LoadSettings(); + RefreshListBox(); + AdaptForDialogMode(); // 调整UI为对话框模式 + } + + /// + /// 用于从外部接收一个设置列表进行编辑。 + /// + /// 要编辑的相机设置列表 + public FrmCamConfig(List settingsToEdit) + { + InitializeComponent(); + + // 创建一个现有列表的副本进行编辑,这样如果用户点“取消”,原始列表不会被影响 + _settingsList = settingsToEdit != null + ? settingsToEdit.Select(s => s.Clone() as CameraSettings).ToList() // 深度克隆更好,这里为简化用浅克隆 + : new List(); + + // 别忘了为列表中的每个对象重新订阅事件 + foreach (var setting in _settingsList) + { + setting.PropertyChanged += Setting_PropertyChanged; + } + + RefreshListBox(); + AdaptForDialogMode(); // 调整UI为对话框模式 + } + + /// + /// 【新增的方法】 + /// 调整UI,使其更像一个对话框。 + /// + private void AdaptForDialogMode() + { + // 将“应用配置”按钮改为“确定” + toolBtnSet.Text = "确定"; + toolBtnSet.ToolTipText = "保存更改并关闭窗口"; + + // 新增一个“取消”按钮 + var toolBtnCancel = new ToolStripButton("取消") + { + DisplayStyle = ToolStripItemDisplayStyle.Text, + Alignment = ToolStripItemAlignment.Right // 靠右对齐 + }; + toolBtnCancel.Click += (sender, e) => { + this.DialogResult = DialogResult.Cancel; + this.Close(); + }; + toolStrip1.Items.Add(toolBtnCancel); + } + + /// + /// 【新增的事件处理方法】 + /// 当PropertyGrid中的属性值被用户修改后触发此事件。 + /// + + // 刷新左侧的相机列表 + private void RefreshListBox() + { + listBoxCameras.Items.Clear(); + foreach (var setting in _settingsList) + { + listBoxCameras.Items.Add(setting.Name); + } + } + /// + /// 【全新的事件处理方法】 + /// 监听单个CameraSettings对象的属性变更通知。 + /// + private void Setting_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + // 检查是不是“Name”属性发生了变化 + if (e.PropertyName == nameof(CameraSettings.Name)) + { + // 'sender' 就是那个属性发生了变化的 CameraSettings 对象 + var changedSetting = sender as CameraSettings; + if (changedSetting == null) return; + + // 在 _settingsList 中找到这个对象的索引 + int index = _settingsList.IndexOf(changedSetting); + + // 如果找到了,就更新ListBox中对应项的显示文本 + if (index >= 0) + { + // 使用Invoke确保线程安全,虽然在此场景下通常不是问题,但这是个好习惯 + this.Invoke(new Action(() => { + listBoxCameras.Items[index] = changedSetting.Name; + })); + } + } + } + + private void listBoxCameras_SelectedIndexChanged(object sender, EventArgs e) + { + if (listBoxCameras.SelectedIndex >= 0) + { + propertyGrid1.SelectedObject = _settingsList[listBoxCameras.SelectedIndex]; + } + else + { + propertyGrid1.SelectedObject = null; + } + } + + private void toolBtnAdd_Click(object sender, EventArgs e) + { + var newSetting = new CameraSettings { Name = $"Camera-{_settingsList.Count + 1}" }; + _settingsList.Add(newSetting); + newSetting.PropertyChanged += Setting_PropertyChanged; + RefreshListBox(); + listBoxCameras.SelectedIndex = listBoxCameras.Items.Count - 1; + } + + private void toolBtnRemove_Click(object sender, EventArgs e) + { + if (listBoxCameras.SelectedIndex >= 0) + { + _settingsList.RemoveAt(listBoxCameras.SelectedIndex); + propertyGrid1.SelectedObject = null; + RefreshListBox(); + } + } + + private void toolBtnSet_Click(object sender, EventArgs e) + { + this.DialogResult = DialogResult.OK; + this.Close(); + } + // 加载XML配置文件 + private void LoadSettings() + { + if (!File.Exists(_configFilePath)) return; + try + { + XmlSerializer serializer = new XmlSerializer(typeof(List)); + using (FileStream fs = new FileStream(_configFilePath, FileMode.Open)) + { + _settingsList = (List)serializer.Deserialize(fs); + } + } + catch (Exception ex) + { + MessageBox.Show("加载相机配置失败: " + ex.Message); + } + foreach (var setting in _settingsList) + { + setting.PropertyChanged += Setting_PropertyChanged; + } + } + + // 保存配置到XML文件 + private void SaveSettings() + { + try + { + XmlSerializer serializer = new XmlSerializer(typeof(List)); + using (FileStream fs = new FileStream(_configFilePath, FileMode.Create)) + { + serializer.Serialize(fs, _settingsList); + } + } + catch (Exception ex) + { + MessageBox.Show("保存相机配置失败: " + ex.Message); + } + } + } +} diff --git a/Check.Main/UI/FrmCamConfig.resx b/Check.Main/UI/FrmCamConfig.resx new file mode 100644 index 0000000..8782d2a --- /dev/null +++ b/Check.Main/UI/FrmCamConfig.resx @@ -0,0 +1,169 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG + YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 + 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw + bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc + VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 + c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 + Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo + mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ + kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D + TgDQASA1MVpwzwAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG + YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 + 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw + bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc + VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 + c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 + Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo + mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ + kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D + TgDQASA1MVpwzwAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG + YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 + 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw + bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc + VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 + c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 + Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo + mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ + kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D + TgDQASA1MVpwzwAAAABJRU5ErkJggg== + + + \ No newline at end of file diff --git a/Check.Main/UI/FrmConfig.Designer.cs b/Check.Main/UI/FrmConfig.Designer.cs new file mode 100644 index 0000000..9b13c1f --- /dev/null +++ b/Check.Main/UI/FrmConfig.Designer.cs @@ -0,0 +1,171 @@ +namespace Check.Main.UI +{ + partial class FrmConfig + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmConfig)); + propertyGrid1 = new PropertyGrid(); + toolStrip1 = new ToolStrip(); + toolBtnApply = new ToolStripButton(); + toolBtnAddProduct = new ToolStripButton(); + tableLayoutPanel1 = new TableLayoutPanel(); + uiLabel1 = new Sunny.UI.UILabel(); + cmbProducts = new Sunny.UI.UIComboBox(); + toolBtnDeleteProduct = new ToolStripButton(); + toolStrip1.SuspendLayout(); + tableLayoutPanel1.SuspendLayout(); + SuspendLayout(); + // + // propertyGrid1 + // + tableLayoutPanel1.SetColumnSpan(propertyGrid1, 2); + propertyGrid1.Dock = DockStyle.Fill; + propertyGrid1.Location = new Point(3, 70); + propertyGrid1.Name = "propertyGrid1"; + propertyGrid1.Size = new Size(417, 345); + propertyGrid1.TabIndex = 0; + // + // toolStrip1 + // + tableLayoutPanel1.SetColumnSpan(toolStrip1, 2); + toolStrip1.Dock = DockStyle.Fill; + toolStrip1.Items.AddRange(new ToolStripItem[] { toolBtnApply, toolBtnAddProduct, toolBtnDeleteProduct }); + toolStrip1.Location = new Point(0, 0); + toolStrip1.Name = "toolStrip1"; + toolStrip1.Size = new Size(423, 28); + toolStrip1.TabIndex = 1; + toolStrip1.Text = "toolStrip1"; + // + // toolBtnApply + // + toolBtnApply.DisplayStyle = ToolStripItemDisplayStyle.Text; + toolBtnApply.Image = (Image)resources.GetObject("toolBtnApply.Image"); + toolBtnApply.ImageTransparentColor = Color.Magenta; + toolBtnApply.Name = "toolBtnApply"; + toolBtnApply.Size = new Size(60, 25); + toolBtnApply.Text = "应用配置"; + toolBtnApply.Click += toolBtnApply_Click; + // + // toolBtnAddProduct + // + toolBtnAddProduct.DisplayStyle = ToolStripItemDisplayStyle.Text; + toolBtnAddProduct.Image = (Image)resources.GetObject("toolBtnAddProduct.Image"); + toolBtnAddProduct.ImageTransparentColor = Color.Magenta; + toolBtnAddProduct.Name = "toolBtnAddProduct"; + toolBtnAddProduct.Size = new Size(60, 25); + toolBtnAddProduct.Text = "添加产品"; + toolBtnAddProduct.Click += toolBtnAddProduct_Click; + // + // tableLayoutPanel1 + // + tableLayoutPanel1.ColumnCount = 2; + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 23.4042549F)); + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 76.59574F)); + tableLayoutPanel1.Controls.Add(propertyGrid1, 0, 2); + tableLayoutPanel1.Controls.Add(toolStrip1, 0, 0); + tableLayoutPanel1.Controls.Add(uiLabel1, 0, 1); + tableLayoutPanel1.Controls.Add(cmbProducts, 1, 1); + tableLayoutPanel1.Dock = DockStyle.Fill; + tableLayoutPanel1.Location = new Point(0, 0); + tableLayoutPanel1.Name = "tableLayoutPanel1"; + tableLayoutPanel1.RowCount = 3; + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 6.69856453F)); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 9.330144F)); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 83.97129F)); + tableLayoutPanel1.Size = new Size(423, 418); + tableLayoutPanel1.TabIndex = 2; + // + // uiLabel1 + // + uiLabel1.Dock = DockStyle.Fill; + uiLabel1.Font = new Font("宋体", 12F, FontStyle.Regular, GraphicsUnit.Point, 134); + uiLabel1.ForeColor = Color.FromArgb(48, 48, 48); + uiLabel1.Location = new Point(3, 28); + uiLabel1.Name = "uiLabel1"; + uiLabel1.Size = new Size(93, 39); + uiLabel1.TabIndex = 2; + uiLabel1.Text = "当前产品"; + uiLabel1.TextAlign = ContentAlignment.MiddleCenter; + // + // cmbProducts + // + cmbProducts.DataSource = null; + cmbProducts.Dock = DockStyle.Left; + cmbProducts.FillColor = Color.White; + cmbProducts.Font = new Font("宋体", 12F, FontStyle.Regular, GraphicsUnit.Point, 134); + cmbProducts.ItemHoverColor = Color.FromArgb(155, 200, 255); + cmbProducts.ItemSelectForeColor = Color.FromArgb(235, 243, 255); + cmbProducts.Location = new Point(103, 33); + cmbProducts.Margin = new Padding(4, 5, 4, 5); + cmbProducts.MinimumSize = new Size(63, 0); + cmbProducts.Name = "cmbProducts"; + cmbProducts.Padding = new Padding(0, 0, 30, 2); + cmbProducts.Size = new Size(225, 29); + cmbProducts.SymbolSize = 24; + cmbProducts.TabIndex = 3; + cmbProducts.TextAlignment = ContentAlignment.MiddleLeft; + cmbProducts.Watermark = ""; + cmbProducts.SelectedIndexChanged += cmbProducts_SelectedIndexChanged; + // + // toolBtnDeleteProduct + // + toolBtnDeleteProduct.DisplayStyle = ToolStripItemDisplayStyle.Text; + toolBtnDeleteProduct.Image = (Image)resources.GetObject("toolBtnDeleteProduct.Image"); + toolBtnDeleteProduct.ImageTransparentColor = Color.Magenta; + toolBtnDeleteProduct.Name = "toolBtnDeleteProduct"; + toolBtnDeleteProduct.Size = new Size(60, 25); + toolBtnDeleteProduct.Text = "删除产品"; + toolBtnDeleteProduct.Click += toolBtnDeleteProduct_Click; + // + // FrmConfig + // + AutoScaleDimensions = new SizeF(7F, 17F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(423, 418); + Controls.Add(tableLayoutPanel1); + Name = "FrmConfig"; + Text = "属性配置"; + toolStrip1.ResumeLayout(false); + toolStrip1.PerformLayout(); + tableLayoutPanel1.ResumeLayout(false); + tableLayoutPanel1.PerformLayout(); + ResumeLayout(false); + } + + #endregion + + private PropertyGrid propertyGrid1; + private ToolStrip toolStrip1; + private ToolStripButton toolBtnApply; + private TableLayoutPanel tableLayoutPanel1; + private ToolStripButton toolBtnAddProduct; + private Sunny.UI.UILabel uiLabel1; + private Sunny.UI.UIComboBox cmbProducts; + private ToolStripButton toolBtnDeleteProduct; + } +} \ No newline at end of file diff --git a/Check.Main/UI/FrmConfig.cs b/Check.Main/UI/FrmConfig.cs new file mode 100644 index 0000000..f68d61a --- /dev/null +++ b/Check.Main/UI/FrmConfig.cs @@ -0,0 +1,163 @@ +using Check.Main.Camera; +using Check.Main.Common; +using Check.Main.Dispatch; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.Xml.Serialization; +using WeifenLuo.WinFormsUI.Docking; + +namespace Check.Main.UI +{ + public partial class FrmConfig : DockContent + { + //private ProcessConfig _mainSettings=new ProcessConfig(); + //private readonly string _configFilePath = Path.Combine(Application.StartupPath, "main_config.xml"); + public FrmConfig() + { + InitializeComponent(); + ProductManager.OnProductChanged += UpdateUIForNewProduct; + // 初始化UI + InitializeProductComboBox(); + //LoadSettings(); // 窗体加载时,读取主配置文件 + propertyGrid1.SelectedObject = ProductManager.CurrentConfig; //_mainSettings; // 将配置对象绑定到属性网格 + propertyGrid1.PropertyValueChanged += (s, e) => { ProductManager.SaveCurrentProductConfig(); }; // 任何属性改变后自动保存 + } + // 【新增】初始化产品下拉列表 + private void InitializeProductComboBox() + { + cmbProducts.DataSource = null; // 先清空数据源 + cmbProducts.DataSource = ProductManager.ProductList; + cmbProducts.SelectedItem = ProductManager.CurrentProductName; + } + // 【新增】当产品管理器中的产品切换后,此方法被调用以更新整个UI + private void UpdateUIForNewProduct() + { + // 使用Invoke确保线程安全 + if (this.InvokeRequired) + { + this.Invoke(new Action(UpdateUIForNewProduct)); + return; + } + + ThreadSafeLogger.Log($"UI正在更新以显示产品 '{ProductManager.CurrentProductName}' 的配置。"); + // 更新下拉列表的显示(如果产品列表也变了) + InitializeProductComboBox(); + + // 【关键】将PropertyGrid重新绑定到新产品的配置对象上 + propertyGrid1.SelectedObject = ProductManager.CurrentConfig; + propertyGrid1.Refresh(); // 强制刷新UI + } + private void toolBtnApply_Click(object sender, EventArgs e) + { + ThreadSafeLogger.Log("用户点击“应用”按钮..."); + + // 1. 确保在应用前,任何可能未触发 PropertyValueChanged 的更改都被保存。 + ConfigurationManager.SaveChanges(); + + // 2. 获取主窗体引用 + var mainForm = this.DockPanel.FindForm() as FrmMain; + mainForm?.ClearStatusStrip(); // 清理UI状态 + + // 3. 从 ConfigurationManager 获取最新的相机配置列表 + var cameraSettings = ConfigurationManager.GetCurrentConfig();//.CameraSettings; + + if (cameraSettings != null) + { + // 使用全局配置来初始化或重新初始化相机。 + // CameraManager.Initialize 内部会首先调用 Shutdown,所以这是个完整的重启流程。 + CameraManager.Initialize(cameraSettings, mainForm); + } + + ThreadSafeLogger.Log("中央配置已成功应用到相机系统。"); + //MessageBox.Show("主配置已应用!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void cmbProducts_SelectedIndexChanged(object sender, EventArgs e) + { + if (cmbProducts.SelectedItem is string selectedProduct && selectedProduct != ProductManager.CurrentProductName) + { + ProductManager.SwitchToProduct(selectedProduct); + } + } + + private void toolBtnAddProduct_Click(object sender, EventArgs e) + { + // 使用一个简单的输入框来获取新产品名称 + string newName = ShowInputDialog("请输入新产品名称:"); + if (!string.IsNullOrWhiteSpace(newName)) + { + if (ProductManager.AddNewProduct(newName)) + { + ThreadSafeLogger.Log($"成功添加新产品: {newName}"); + } + else + { + MessageBox.Show("产品名称无效或已存在!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + } + // 一个简单的输入对话框辅助方法 + public static string ShowInputDialog(string text) + { + Form prompt = new Form() + { + Width = 300, + Height = 150, + FormBorderStyle = FormBorderStyle.FixedDialog, + Text = text, + StartPosition = FormStartPosition.CenterScreen + }; + Label textLabel = new Label() { Left = 50, Top = 20, Text = "产品名称:" }; + TextBox textBox = new TextBox() { Left = 50, Top = 50, Width = 200 }; + Button confirmation = new Button() { Text = "确定", Left = 150, Width = 100, Top = 80, DialogResult = DialogResult.OK }; + confirmation.Click += (sender, e) => { prompt.Close(); }; + prompt.Controls.Add(textBox); + prompt.Controls.Add(confirmation); + prompt.Controls.Add(textLabel); + prompt.AcceptButton = confirmation; + + return prompt.ShowDialog() == DialogResult.OK ? textBox.Text : ""; + } + + private void toolBtnDeleteProduct_Click(object sender, EventArgs e) + { + // 1. 获取当前选中的产品 + string productToDelete = ProductManager.CurrentProductName; + + if (string.IsNullOrWhiteSpace(productToDelete) || productToDelete == "DefaultProduct") + { + MessageBox.Show("不能删除默认产品或无效产品!", "操作无效", MessageBoxButtons.OK, MessageBoxIcon.Warning); + return; + } + + // 2. 弹出安全确认对话框 + var confirmResult = MessageBox.Show($"您确定要永久删除产品 '{productToDelete}' 吗?\n\n此操作不可恢复,将删除其所有相关配置!", + "确认删除", + MessageBoxButtons.YesNo, + MessageBoxIcon.Warning); + + if (confirmResult == DialogResult.Yes) + { + // 3. 调用核心删除逻辑 + if (ProductManager.DeleteProduct(productToDelete)) + { + ThreadSafeLogger.Log($"用户成功删除了产品 '{productToDelete}'。"); + // 无需在这里手动更新UI,因为DeleteProduct方法内部会触发 OnProductChanged 事件, + // 而我们的 UpdateUIForNewProduct 方法会自动响应这个事件并刷新整个界面。 + } + else + { + MessageBox.Show($"删除产品 '{productToDelete}' 失败,请查看日志获取详细信息。", "删除失败", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + } +} diff --git a/Check.Main/UI/FrmConfig.resx b/Check.Main/UI/FrmConfig.resx new file mode 100644 index 0000000..b813d1d --- /dev/null +++ b/Check.Main/UI/FrmConfig.resx @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACRSURBVDhPY/j27dt/SjDYACcnJ7IwigEf3n8kCZNswPNb + J/+f6DYF0yA+yQac6Db5f6hWCmwIiE+mC0wIu2DS2Vf/F1x6DefjwlgNyNr34r/0wkdgTMgQDAOQNRNj + CIoBOg0rMTTDMLIhIHbriZeYBmDTiIxBGkEYxge5liQDsGGQqykyAISpZwAlmIEywMAAAAc1/Jwvt6sN + AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACRSURBVDhPY/j27dt/SjDYACcnJ7IwigEf3n8kCZNswPNb + J/+f6DYF0yA+yQac6Db5f6hWCmwIiE+mC0wIu2DS2Vf/F1x6DefjwlgNyNr34r/0wkdgTMgQDAOQNRNj + CIoBOg0rMTTDMLIhIHbriZeYBmDTiIxBGkEYxge5liQDsGGQqykyAISpZwAlmIEywMAAAAc1/Jwvt6sN + AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACRSURBVDhPY/j27dt/SjDYACcnJ7IwigEf3n8kCZNswPNb + J/+f6DYF0yA+yQac6Db5f6hWCmwIiE+mC0wIu2DS2Vf/F1x6DefjwlgNyNr34r/0wkdgTMgQDAOQNRNj + CIoBOg0rMTTDMLIhIHbriZeYBmDTiIxBGkEYxge5liQDsGGQqykyAISpZwAlmIEywMAAAAc1/Jwvt6sN + AAAAAElFTkSuQmCC + + + \ No newline at end of file diff --git a/Check.Main/UI/FrmLog.Designer.cs b/Check.Main/UI/FrmLog.Designer.cs new file mode 100644 index 0000000..734d162 --- /dev/null +++ b/Check.Main/UI/FrmLog.Designer.cs @@ -0,0 +1,66 @@ +namespace Check.Main.UI +{ + partial class FrmLog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.txtLog = new Sunny.UI.UIRichTextBox(); + this.SuspendLayout(); + // + // txtLog + // + this.txtLog.Dock = System.Windows.Forms.DockStyle.Fill; + this.txtLog.FillColor = System.Drawing.Color.White; + this.txtLog.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); + this.txtLog.Location = new System.Drawing.Point(0, 0); + this.txtLog.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + this.txtLog.MinimumSize = new System.Drawing.Size(1, 1); + this.txtLog.Name = "txtLog"; + this.txtLog.Padding = new System.Windows.Forms.Padding(2); + this.txtLog.ReadOnly = true; + this.txtLog.ShowText = false; + this.txtLog.Size = new System.Drawing.Size(399, 299); + this.txtLog.TabIndex = 0; + this.txtLog.TextAlignment = System.Drawing.ContentAlignment.MiddleLeft; + // + // FrmLog + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(399, 299); + this.Controls.Add(this.txtLog); + this.Name = "FrmLog"; + this.Text = "FrmLog"; + this.ResumeLayout(false); + + } + + #endregion + + private Sunny.UI.UIRichTextBox txtLog; + } +} \ No newline at end of file diff --git a/Check.Main/UI/FrmLog.cs b/Check.Main/UI/FrmLog.cs new file mode 100644 index 0000000..a4c0bd3 --- /dev/null +++ b/Check.Main/UI/FrmLog.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using WeifenLuo.WinFormsUI.Docking; + +namespace Check.Main.UI +{ + public partial class FrmLog : DockContent + { + public FrmLog() + { + InitializeComponent(); + } + public void AddLog(string message) + { + if (txtLog.InvokeRequired) + { + txtLog.BeginInvoke(new Action(() => AddLog(message))); + return; + } + if (txtLog.Lines.Length > 500) + { + txtLog.Clear(); + } + txtLog.AppendText(message + Environment.NewLine); + txtLog.ScrollToCaret(); + } + } +} diff --git a/Check.Main/UI/FrmLog.resx b/Check.Main/UI/FrmLog.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Check.Main/UI/FrmLog.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Check.Main/UI/ModelListEditor.Designer.cs b/Check.Main/UI/ModelListEditor.Designer.cs new file mode 100644 index 0000000..c89c245 --- /dev/null +++ b/Check.Main/UI/ModelListEditor.Designer.cs @@ -0,0 +1,145 @@ +namespace Check.Main.UI +{ + partial class ModelListEditor + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ModelListEditor)); + propertyGrid1 = new PropertyGrid(); + listBoxModels = new ListBox(); + toolStrip1 = new ToolStrip(); + toolBtnAdd = new ToolStripButton(); + toolBtnRemove = new ToolStripButton(); + toolBtnSet = new ToolStripButton(); + tableLayoutPanel1 = new TableLayoutPanel(); + toolStrip1.SuspendLayout(); + tableLayoutPanel1.SuspendLayout(); + SuspendLayout(); + // + // propertyGrid1 + // + propertyGrid1.Dock = DockStyle.Fill; + propertyGrid1.Location = new Point(245, 4); + propertyGrid1.Margin = new Padding(4); + propertyGrid1.Name = "propertyGrid1"; + propertyGrid1.Size = new Size(316, 400); + propertyGrid1.TabIndex = 1; + // + // listBoxModels + // + listBoxModels.Dock = DockStyle.Fill; + listBoxModels.FormattingEnabled = true; + listBoxModels.ItemHeight = 17; + listBoxModels.Location = new Point(4, 4); + listBoxModels.Margin = new Padding(4); + listBoxModels.Name = "listBoxModels"; + listBoxModels.Size = new Size(233, 400); + listBoxModels.TabIndex = 2; + listBoxModels.SelectedIndexChanged += listBoxModels_SelectedIndexChanged; + // + // toolStrip1 + // + toolStrip1.Items.AddRange(new ToolStripItem[] { toolBtnAdd, toolBtnRemove, toolBtnSet }); + toolStrip1.Location = new Point(0, 0); + toolStrip1.Name = "toolStrip1"; + toolStrip1.Size = new Size(565, 25); + toolStrip1.TabIndex = 3; + toolStrip1.Text = "toolStrip1"; + // + // toolBtnAdd + // + toolBtnAdd.DisplayStyle = ToolStripItemDisplayStyle.Text; + toolBtnAdd.Image = (Image)resources.GetObject("toolBtnAdd.Image"); + toolBtnAdd.ImageTransparentColor = Color.Magenta; + toolBtnAdd.Name = "toolBtnAdd"; + toolBtnAdd.Size = new Size(36, 22); + toolBtnAdd.Text = "添加"; + toolBtnAdd.Click += toolBtnAdd_Click; + // + // toolBtnRemove + // + toolBtnRemove.DisplayStyle = ToolStripItemDisplayStyle.Text; + toolBtnRemove.Image = (Image)resources.GetObject("toolBtnRemove.Image"); + toolBtnRemove.ImageTransparentColor = Color.Magenta; + toolBtnRemove.Name = "toolBtnRemove"; + toolBtnRemove.Size = new Size(36, 22); + toolBtnRemove.Text = "移除"; + toolBtnRemove.Click += toolBtnRemove_Click; + // + // toolBtnSet + // + toolBtnSet.DisplayStyle = ToolStripItemDisplayStyle.Text; + toolBtnSet.Image = (Image)resources.GetObject("toolBtnSet.Image"); + toolBtnSet.ImageTransparentColor = Color.Magenta; + toolBtnSet.Name = "toolBtnSet"; + toolBtnSet.Size = new Size(60, 22); + toolBtnSet.Text = "应用配置"; + toolBtnSet.Click += toolBtnSet_Click; + // + // tableLayoutPanel1 + // + tableLayoutPanel1.ColumnCount = 2; + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 42.65487F)); + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 57.34513F)); + tableLayoutPanel1.Controls.Add(listBoxModels, 0, 0); + tableLayoutPanel1.Controls.Add(propertyGrid1, 1, 0); + tableLayoutPanel1.Dock = DockStyle.Fill; + tableLayoutPanel1.Location = new Point(0, 25); + tableLayoutPanel1.Name = "tableLayoutPanel1"; + tableLayoutPanel1.RowCount = 1; + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 50F)); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 50F)); + tableLayoutPanel1.Size = new Size(565, 408); + tableLayoutPanel1.TabIndex = 4; + // + // ModelListEditor + // + AutoScaleDimensions = new SizeF(7F, 17F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(565, 433); + Controls.Add(tableLayoutPanel1); + Controls.Add(toolStrip1); + Name = "ModelListEditor"; + Text = "模型配置"; + toolStrip1.ResumeLayout(false); + toolStrip1.PerformLayout(); + tableLayoutPanel1.ResumeLayout(false); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private PropertyGrid propertyGrid1; + private ListBox listBoxModels; + private ToolStrip toolStrip1; + private ToolStripButton toolBtnAdd; + private ToolStripButton toolBtnRemove; + private ToolStripButton toolBtnSet; + private TableLayoutPanel tableLayoutPanel1; + } +} \ No newline at end of file diff --git a/Check.Main/UI/ModelListEditor.cs b/Check.Main/UI/ModelListEditor.cs new file mode 100644 index 0000000..453fc04 --- /dev/null +++ b/Check.Main/UI/ModelListEditor.cs @@ -0,0 +1,175 @@ +using Check.Main.Camera; +using Check.Main.Infer; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.Xml.Serialization; +using WeifenLuo.WinFormsUI.Docking; + +namespace Check.Main.UI +{ + public partial class ModelListEditor : DockContent + { + public List _settingsList { get; private set; } + private readonly string _configFilePath = Path.Combine(Application.StartupPath, "model.xml"); + public ModelListEditor() + { + InitializeComponent(); + _settingsList = new List(); + LoadSettings(); + RefreshListBox(); + AdaptForDialogMode(); // 调整UI为对话框模式 + } + /// + /// 用于从外部接收一个设置列表进行编辑。 + /// + /// 要编辑的相机设置列表 + public ModelListEditor(List settingsToEdit) + { + InitializeComponent(); + + // 创建一个现有列表的副本进行编辑,这样如果用户点“取消”,原始列表不会被影响 + _settingsList = settingsToEdit != null + ? settingsToEdit.Select(s => s.Clone() as ModelSettings).ToList() // 深度克隆更好,这里为简化用浅克隆 + : new List(); + + // 别忘了为列表中的每个对象重新订阅事件 + foreach (var setting in _settingsList) + { + setting.PropertyChanged += Setting_PropertyChanged; + } + + RefreshListBox(); + AdaptForDialogMode(); // 调整UI为对话框模式 + } + /// + /// 【新增的方法】 + /// 调整UI,使其更像一个对话框。 + /// + private void AdaptForDialogMode() + { + // 将“应用配置”按钮改为“确定” + toolBtnSet.Text = "确定"; + toolBtnSet.ToolTipText = "保存更改并关闭窗口"; + + // 新增一个“取消”按钮 + var toolBtnCancel = new ToolStripButton("取消") + { + DisplayStyle = ToolStripItemDisplayStyle.Text, + Alignment = ToolStripItemAlignment.Right // 靠右对齐 + }; + toolBtnCancel.Click += (sender, e) => + { + this.DialogResult = DialogResult.Cancel; + this.Close(); + }; + toolStrip1.Items.Add(toolBtnCancel); + } + + /// + /// 【新增的事件处理方法】 + /// 当PropertyGrid中的属性值被用户修改后触发此事件。 + /// + + // 刷新左侧的相机列表 + private void RefreshListBox() + { + listBoxModels.Items.Clear(); + foreach (var setting in _settingsList) + { + listBoxModels.Items.Add(setting.Name); + } + } + /// + /// 【全新的事件处理方法】 + /// 监听单个CameraSettings对象的属性变更通知。 + /// + private void Setting_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + // 检查是不是“Name”属性发生了变化 + if (e.PropertyName == nameof(CameraSettings.Name)) + { + // 'sender' 就是那个属性发生了变化的 CameraSettings 对象 + var changedSetting = sender as ModelSettings; + if (changedSetting == null) return; + + // 在 _settingsList 中找到这个对象的索引 + int index = _settingsList.IndexOf(changedSetting); + + // 如果找到了,就更新ListBox中对应项的显示文本 + if (index >= 0) + { + // 使用Invoke确保线程安全,虽然在此场景下通常不是问题,但这是个好习惯 + this.Invoke(new Action(() => + { + listBoxModels.Items[index] = changedSetting.Name; + })); + } + } + } + + private void listBoxModels_SelectedIndexChanged(object sender, EventArgs e) + { + if (listBoxModels.SelectedIndex >= 0) + { + propertyGrid1.SelectedObject = _settingsList[listBoxModels.SelectedIndex]; + } + else + { + propertyGrid1.SelectedObject = null; + } + } + + private void toolBtnAdd_Click(object sender, EventArgs e) + { + var newSetting = new ModelSettings { Name = $"model-{_settingsList.Count + 1}" }; + _settingsList.Add(newSetting); + newSetting.PropertyChanged += Setting_PropertyChanged; + RefreshListBox(); + listBoxModels.SelectedIndex = listBoxModels.Items.Count - 1; + } + + private void toolBtnRemove_Click(object sender, EventArgs e) + { + if (listBoxModels.SelectedIndex >= 0) + { + _settingsList.RemoveAt(listBoxModels.SelectedIndex); + propertyGrid1.SelectedObject = null; + RefreshListBox(); + } + } + + private void toolBtnSet_Click(object sender, EventArgs e) + { + this.DialogResult = DialogResult.OK; + this.Close(); + } + // 加载XML配置文件 + private void LoadSettings() + { + if (!File.Exists(_configFilePath)) return; + try + { + XmlSerializer serializer = new XmlSerializer(typeof(List)); + using (FileStream fs = new FileStream(_configFilePath, FileMode.Open)) + { + _settingsList = (List)serializer.Deserialize(fs); + } + } + catch (Exception ex) + { + MessageBox.Show("加载相机配置失败: " + ex.Message); + } + foreach (var setting in _settingsList) + { + setting.PropertyChanged += Setting_PropertyChanged; + } + } + } +} diff --git a/Check.Main/UI/ModelListEditor.resx b/Check.Main/UI/ModelListEditor.resx new file mode 100644 index 0000000..7046689 --- /dev/null +++ b/Check.Main/UI/ModelListEditor.resx @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG + YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 + 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw + bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc + VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 + c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 + Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo + mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ + kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D + TgDQASA1MVpwzwAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG + YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 + 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw + bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc + VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 + c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 + Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo + mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ + kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D + TgDQASA1MVpwzwAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG + YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 + 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw + bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc + VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 + c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 + Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo + mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ + kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D + TgDQASA1MVpwzwAAAABJRU5ErkJggg== + + + + 37 + + \ No newline at end of file diff --git a/Check.Main/UI/ZoomPictureBox.cs b/Check.Main/UI/ZoomPictureBox.cs new file mode 100644 index 0000000..262a663 --- /dev/null +++ b/Check.Main/UI/ZoomPictureBox.cs @@ -0,0 +1,381 @@ +using OpenCvSharp; +using OpenCvSharp.Extensions; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Check.Main.UI +{ + public class ZoomPictureBox : PictureBox, IDisposable + { + private float zoom = 1.0f; + private System.Drawing.Point imageLocation; + private Image image; + private bool dragging = false; + private System.Drawing.Point mouseDownPos; + private System.Drawing.Point imageLocationOnMouseDown; + + // 矩形绘制相关 + private bool isDrawingRect = false; // 绘制状态 + private Rectangle currentRect; // 当前绘制矩形 + private Rectangle storedRect; // 上次绘制并固定的矩形 + private bool hasStoredRect = false; // 是否存在固定矩形 + private System.Drawing.Point rectStartPoint; + + // 一个私有的锁对象,专门用于保护对 'image' 字段的访问。 + private readonly object imageLock = new object(); + + private bool croppingEnabled = true; + //private bool croppingEnabled = true; + [Category("Behavior")] + [Description("是否允许通过右键绘制矩形裁剪区域。设置为 false 则不再响应右键并清除已有矩形。")] + public bool CroppingEnabled + { + get => croppingEnabled; + set + { + croppingEnabled = value; + // 禁用裁剪时清除所有矩形和裁剪结果 + if (!croppingEnabled) + { + isDrawingRect = false; + hasStoredRect = false; + LastCroppedMat?.Dispose(); + LastCroppedMat = null; + } + Invalidate(); + } + } + + // 裁剪完成事件,外部可订阅以接收 Mat + public event Action Cropped; + + public Mat LastCroppedMat { get; private set; } + + private Color backgroundFillColor = Color.LightSteelBlue; + private Color rectangleColor = Color.Red; + private int rectangleThickness = 2; + + [Category("Appearance")] + [Description("指定控件背景的填充颜色。使用 BackColor 属性同步更新。")] + public Color BackgroundFillColor + { + get => backgroundFillColor; + set + { + backgroundFillColor = value; + base.BackColor = value; // 同步 WinForms BackColor + Invalidate(); + } + } + + + [Category("Appearance")] + [Description("绘制矩形框的颜色。")] + public Color RectangleColor { get => rectangleColor; set { rectangleColor = value; Invalidate(); } } + + [Category("Appearance")] + [Description("绘制矩形框的线宽。")] + public int RectangleThickness { get => rectangleThickness; set { rectangleThickness = Math.Max(1, value); Invalidate(); } } + + public ZoomPictureBox() + { + DoubleBuffered = true; + ResizeRedraw = true; + base.BackColor = backgroundFillColor; + SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true); + MouseWheel += ZoomPictureBox_MouseWheel; + MouseDown += ZoomPictureBox_MouseDown; + MouseMove += ZoomPictureBox_MouseMove; + MouseUp += ZoomPictureBox_MouseUp; + DoubleClick += ZoomPictureBox_DoubleClick; + } + // 重写背景绘制,使用自定义背景色 + protected override void OnPaintBackground(PaintEventArgs e) + { + e.Graphics.Clear(backgroundFillColor); + } + //[Browsable(false)] + //public new Image Image + //{ + // get => image; + // set + // { + // image = value; + // zoom = 1.0f; + // LastCroppedMat?.Dispose(); + // LastCroppedMat = null; + // isDrawingRect = false; + // hasStoredRect = false; + // FitImage(); + // Invalidate(); + // } + //} + // 【关键优化】 + // 2. 重写 Control.Dispose 方法来释放我们自己的资源 + protected override void Dispose(bool disposing) + { + if (disposing) + { + // 在这里释放托管和非托管资源 + // 清理事件订阅 (虽然在这个类里没有,但这是个好习惯) + + // 释放我们持有的最后一个图像资源 + lock (imageLock) + { + this.image?.Dispose(); + this.image = null; + } + + // 释放我们持有的最后一个裁剪结果资源 + this.LastCroppedMat?.Dispose(); + this.LastCroppedMat = null; + } + + // 调用基类的 Dispose 方法来完成标准清理 + base.Dispose(disposing); + } + + // 重写 Image 属性,但不做任何额外操作,因为我们将通过一个新方法来更新它。 + [Browsable(false)] + public new Image Image + { + get + { + // 在访问时也加锁,确保读取的是一个完整的对象 + lock (imageLock) + { + return image; + } + } + // set 访问器可以保持原样,但我们不再直接使用它来更新图像 + private set + { + lock (imageLock) + { + image = value; + } + } + } + + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + var g = e.Graphics; + //在绘制前获取锁,确保在绘制期间,image对象不会被其他线程替换或释放 + lock (imageLock) + { + if (image != null) + { + try + { + int w = (int)(image.Width * zoom); + int h = (int)(image.Height * zoom); + g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; + g.DrawImage(image, new Rectangle(imageLocation, new System.Drawing.Size(w, h))); + } + catch (Exception) + { + + // 如果在绘制时仍然发生罕见的GDI+错误,静默忽略,避免程序崩溃。 + // 这通常意味着图像状态仍然存在问题,但UI不会因此卡死。 + } + } + } + //if (image != null) + //{ + // int w = (int)(image.Width * zoom); + // int h = (int)(image.Height * zoom); + // g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; + // g.DrawImage(image, new Rectangle(imageLocation, new System.Drawing.Size(w, h))); + //} + // 仅当允许裁剪时才绘制矩形 + if (croppingEnabled) + { + using (var pen = new Pen(rectangleColor, rectangleThickness)) + { + if (hasStoredRect) g.DrawRectangle(pen, storedRect); + else if (isDrawingRect) g.DrawRectangle(pen, currentRect); + } + } + } + + /// + /// 一个线程安全的、用于更新显示图像的公共方法。 + /// 这个方法将替换掉直接的 pictureBox.Image = ... 赋值。 + /// + /// 要显示的新图像。此方法会接管该对象的所有权。 + public void SetImageThreadSafe(Image newImage) + { + Image oldImage = null; + + lock (imageLock) + { + // 1. 保存旧图像的引用,以便在锁外部释放它 + oldImage = this.image; + // 2. 将新图像赋值给成员字段 + this.image = newImage; + } + // 3. 【关键】在锁的外部释放旧图像,避免长时间持有锁 + oldImage?.Dispose(); + + // 4. 计算自适应并触发重绘 + FitImage(); + Invalidate(); + } + + private void FitImage() + { + //if (image == null) return; + //float sx = (float)ClientSize.Width / image.Width; + //float sy = (float)ClientSize.Height / image.Height; + //zoom = Math.Min(sx, sy); + //CenterImage(); + //在访问image属性前获取锁 + lock (imageLock) + { + if (image == null) return; + + try + { + float sx = (float)ClientSize.Width / image.Width; + float sy = (float)ClientSize.Height / image.Height; + zoom = Math.Min(sx, sy); + CenterImage(); + } + catch (Exception) + { + + // 忽略错误,同 OnPaint + } + } + } + + private void CenterImage() + { + if (image == null) return; + int w = (int)(image.Width * zoom); + int h = (int)(image.Height * zoom); + imageLocation = new System.Drawing.Point((ClientSize.Width - w) / 2, (ClientSize.Height - h) / 2); + } + + private void ZoomPictureBox_MouseWheel(object sender, MouseEventArgs e) + { + if (image == null) return; + float oldZoom = zoom; + zoom *= e.Delta > 0 ? 1.1f : 1 / 1.1f; + zoom = Math.Max(0.1f, Math.Min(zoom, 100f)); + var m = e.Location; + float ix = (m.X - imageLocation.X) / oldZoom; + float iy = (m.Y - imageLocation.Y) / oldZoom; + imageLocation = new System.Drawing.Point((int)(m.X - ix * zoom), (int)(m.Y - iy * zoom)); + Invalidate(); + } + + private void ZoomPictureBox_MouseDown(object sender, MouseEventArgs e) + { + if (image == null) return; + if (e.Button == MouseButtons.Left) + { + hasStoredRect = false; + LastCroppedMat?.Dispose(); + LastCroppedMat = null; + + dragging = true; + mouseDownPos = e.Location; + imageLocationOnMouseDown = imageLocation; + Cursor = Cursors.Hand; + } + else if (e.Button == MouseButtons.Right && croppingEnabled) + { + // 清除上次固定矩形和裁剪 + hasStoredRect = false; + LastCroppedMat?.Dispose(); + LastCroppedMat = null; + + // 开始新绘制 + isDrawingRect = true; + rectStartPoint = e.Location; + currentRect = new Rectangle(e.Location, System.Drawing.Size.Empty); + Invalidate(); + } + } + + private void ZoomPictureBox_MouseMove(object sender, MouseEventArgs e) + { + if (dragging) + { + var delta = new System.Drawing.Point(e.X - mouseDownPos.X, e.Y - mouseDownPos.Y); + imageLocation = new System.Drawing.Point(imageLocationOnMouseDown.X + delta.X, imageLocationOnMouseDown.Y + delta.Y); + Invalidate(); + } + else if (isDrawingRect) + { + int x = Math.Min(rectStartPoint.X, e.X); + int y = Math.Min(rectStartPoint.Y, e.Y); + int w = Math.Abs(e.X - rectStartPoint.X); + int h = Math.Abs(e.Y - rectStartPoint.Y); + currentRect = new Rectangle(x, y, w, h); + Invalidate(); + } + } + + private void ZoomPictureBox_MouseUp(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Left && dragging) + { + dragging = false; + Cursor = Cursors.Default; + } + else if (e.Button == MouseButtons.Right && isDrawingRect) + { + isDrawingRect = false; + // 固定当前矩形框 + storedRect = currentRect; + hasStoredRect = true; + if (croppingEnabled && image is Bitmap bmp) + { + this.LastCroppedMat?.Dispose(); + this.LastCroppedMat = null; + Mat srcMat = null; + try + { + int ix = (int)((storedRect.X - imageLocation.X) / zoom); + int iy = (int)((storedRect.Y - imageLocation.Y) / zoom); + int iw = (int)(storedRect.Width / zoom); + int ih = (int)(storedRect.Height / zoom); + ix = Math.Max(0, ix); + iy = Math.Max(0, iy); + if (ix + iw > bmp.Width) iw = bmp.Width - ix; + if (iy + ih > bmp.Height) ih = bmp.Height - iy; + if (iw > 0 && ih > 0) + { + srcMat = BitmapConverter.ToMat(bmp); + var roi = new Rect(ix, iy, iw, ih); + LastCroppedMat = new Mat(srcMat, roi); + Cropped?.Invoke(LastCroppedMat); + bmp.Dispose(); + } + } + finally + { + // 5.确保从Bitmap转换来的 srcMat 被释放 + srcMat?.Dispose(); + } + } + Invalidate(); + } + } + private void ZoomPictureBox_DoubleClick(object sender, EventArgs e) + { + if (image == null) return; + FitImage(); + Invalidate(); + } + } +} diff --git a/CheckDevice.sln b/CheckDevice.sln new file mode 100644 index 0000000..ab65da3 --- /dev/null +++ b/CheckDevice.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36310.24 d17.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Check.Main", "Check.Main\Check.Main.csproj", "{3AEFC44E-BD2D-48A9-8C0D-BF4D429E1166}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3AEFC44E-BD2D-48A9-8C0D-BF4D429E1166}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3AEFC44E-BD2D-48A9-8C0D-BF4D429E1166}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3AEFC44E-BD2D-48A9-8C0D-BF4D429E1166}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3AEFC44E-BD2D-48A9-8C0D-BF4D429E1166}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {53CBAFF8-60D2-4B61-B76A-2C11D7DA949E} + EndGlobalSection +EndGlobal