diff --git a/Duplicati/Scheduler/Monitor.SQL/BackupsDataSetSupport.cs b/Duplicati/Scheduler/Monitor.SQL/BackupsDataSetSupport.cs
new file mode 100644
index 000000000..4f4974ec3
--- /dev/null
+++ b/Duplicati/Scheduler/Monitor.SQL/BackupsDataSetSupport.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Duplicati.Scheduler.Monitor.SQL
+{
+ ///
+ /// Support for the remote database
+ ///
+ ///
+ /// The goal here was to hit the server as little as possible.
+ /// So, the data is not parsed from its XML and only the changes are sent.
+ ///
+ public partial class SQLHistoryDataSet
+ {
+ ///
+ /// Get the time that the last update was done for this user/machine/entryType
+ ///
+ /// Kind to search for
+ /// Last time or Time.Min if never
+ public static DateTime Latest(EntryKind aEntryKind)
+ {
+ SQLHistoryDataSetTableAdapters.HistoryTableAdapter TableAdapter = new SQLHistoryDataSetTableAdapters.HistoryTableAdapter();
+ DateTime? re = TableAdapter.LatestQuery(Duplicati.Scheduler.Utility.User.UserName, Environment.MachineName, aEntryKind.ToString());
+ if (re == null) return DateTime.MinValue;
+ return (DateTime)re;
+ }
+ ///
+ /// Update a record
+ ///
+ /// Domain/User
+ /// Yeah
+ /// Kind of entry to update
+ /// Entry time
+ /// XML to send
+ public static void Update(string aUserName, string aMachineName, EntryKind aEntryType, DateTime aModificationDate, string aContent)
+ {
+ SQLHistoryDataSetTableAdapters.HistoryTableAdapter TableAdapter = new SQLHistoryDataSetTableAdapters.HistoryTableAdapter();
+ SQLHistoryDataSet.HistoryDataTable Table = TableAdapter.GetDataBy(aUserName, aMachineName, aEntryType.ToString(), aModificationDate);
+ HistoryRow Row = null;
+ if (Table.Count == 0)
+ Row = Table.AddHistoryRow(aUserName, aMachineName, aEntryType.ToString(), aModificationDate, aContent);
+ else
+ Row = ((HistoryRow)Table.Rows[0]);
+ Row.XmlContent = aContent;
+ TableAdapter.Update(Table);
+ //Console.WriteLine(Row.EntryType + ":" + Row.XmlContent);
+ }
+ ///
+ /// Entry may be one of these, note that Schedule includes Settings
+ ///
+ public enum EntryKind
+ {
+ Schedule,
+ History,
+ Log,
+ None
+ };
+ ///
+ /// Row tools
+ ///
+ public partial class HistoryRow
+ {
+ ///
+ /// Convert string to EntryKind
+ ///
+ public EntryKind ToEntryKind(string aType)
+ {
+ if (System.Enum.IsDefined(typeof(EntryKind), aType)) return EntryKind.None;
+ return (EntryKind)System.Enum.Parse(typeof(EntryKind), aType);
+ }
+ ///
+ /// Sets Entry Type
+ ///
+ public EntryKind Entry
+ {
+ get { return ToEntryKind(this.EntryType); }
+ set { this.EntryType = value.ToString(); }
+ }
+ }
+ }
+}
diff --git a/Duplicati/Scheduler/Monitor.SQL/Duplicati.Scheduler.Monitor.SQL.csproj b/Duplicati/Scheduler/Monitor.SQL/Duplicati.Scheduler.Monitor.SQL.csproj
new file mode 100644
index 000000000..c000f5bb4
--- /dev/null
+++ b/Duplicati/Scheduler/Monitor.SQL/Duplicati.Scheduler.Monitor.SQL.csproj
@@ -0,0 +1,120 @@
+
+
+
+ Debug
+ AnyCPU
+ 9.0.30729
+ 2.0
+ {ECA674A3-CC59-4C75-90E3-5AACA591EC5D}
+ Library
+ Properties
+ Duplicati.Scheduler.Monitor.SQL
+ Duplicati.Scheduler.Monitor.SQL
+ v3.5
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+ 3.5
+
+
+ 3.5
+
+
+
+
+ 3.5
+
+
+ 3.5
+
+
+
+
+
+
+ Component
+
+
+ Form
+
+
+ SQLConnectionDialog.cs
+
+
+
+ True
+ True
+ Settings.settings
+
+
+
+ True
+ True
+ SQLHistoryDataSet.xsd
+
+
+
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ SQLHistoryDataSet.xsd
+
+
+ Designer
+ MSDataSetGenerator
+ SQLHistoryDataSet.Designer.cs
+
+
+ SQLHistoryDataSet.xsd
+
+
+
+
+ {C8F0DD19-E242-4E9C-A707-2FFADE8D7970}
+ Duplicati.Scheduler.Data
+
+
+ {0E3DF716-5657-4B51-9BF2-3791880930E1}
+ Duplicati.Scheduler.Utility
+
+
+
+
+
+ SQLConnectionDialog.cs
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Duplicati/Scheduler/Monitor.SQL/Plugin.cs b/Duplicati/Scheduler/Monitor.SQL/Plugin.cs
new file mode 100644
index 000000000..8eaca64c0
--- /dev/null
+++ b/Duplicati/Scheduler/Monitor.SQL/Plugin.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Duplicati.Scheduler.Monitor.SQL
+{
+ ///
+ /// Maintains the server data
+ ///
+ public class Plugin : Duplicati.Scheduler.Data.IMonitorPlugin
+ {
+ public string Name { get { return "Monitor.SQL"; } }
+ ///
+ /// Update a log entry
+ ///
+ /// Date
+ /// XML content
+ public void UpdateLog(DateTime aLogDate, string aLogContent)
+ {
+ SQLHistoryDataSet.Update(Duplicati.Scheduler.Utility.User.UserName, Environment.MachineName, SQLHistoryDataSet.EntryKind.Log,
+ aLogDate, aLogContent);
+ }
+ ///
+ /// Update the scheduler record
+ ///
+ public void Scheduler()
+ {
+ UpdateScheduler(Duplicati.Scheduler.Data.SchedulerDataSet.DefaultPath());
+ }
+ ///
+ /// Update the scheduler record
+ ///
+ /// XML file to load
+ public void UpdateScheduler(string aScheduler)
+ {
+ DateTime LastUpdate = SQLHistoryDataSet.Latest(SQLHistoryDataSet.EntryKind.Schedule);
+ DateTime LastWrite = System.IO.File.GetLastWriteTime(aScheduler);
+ if (LastUpdate < LastWrite)
+ SQLHistoryDataSet.Update(Duplicati.Scheduler.Utility.User.UserName, Environment.MachineName, SQLHistoryDataSet.EntryKind.Schedule,
+ LastWrite, System.IO.File.ReadAllText(aScheduler));
+ }
+ ///
+ /// Update History
+ ///
+ public void UpdateHistory(string aHistory)
+ {
+ using (Duplicati.Scheduler.Data.HistoryDataSet hds = new Duplicati.Scheduler.Data.HistoryDataSet())
+ {
+ hds.Load();
+ History(System.IO.File.GetLastWriteTime(aHistory), hds.History);
+ }
+ }
+ ///
+ /// Update History
+ ///
+ /// Date
+ /// XML file name
+ public void History(DateTime aLastWrite, Duplicati.Scheduler.Data.HistoryDataSet.HistoryDataTable aHistoryTable)
+ {
+ DateTime LastUpdate = SQLHistoryDataSet.Latest(SQLHistoryDataSet.EntryKind.Schedule);
+ Duplicati.Scheduler.Data.HistoryDataSet.HistoryDataTable Changes = new Duplicati.Scheduler.Data.HistoryDataSet.HistoryDataTable();
+ foreach (Duplicati.Scheduler.Data.HistoryDataSet.HistoryRow Row in
+ from Duplicati.Scheduler.Data.HistoryDataSet.HistoryRow qR in aHistoryTable
+ where qR.ActionDate > LastUpdate
+ select qR)
+ Changes.ImportRow(Row);
+ StringBuilder b = new StringBuilder();
+ Changes.WriteXml(new System.IO.StringWriter(b));
+ SQLHistoryDataSet.Update(Duplicati.Scheduler.Utility.User.UserName, Environment.MachineName, SQLHistoryDataSet.EntryKind.History,
+ aLastWrite, b.ToString());
+ }
+ public System.Windows.Forms.DialogResult Configure()
+ {
+ return new SQLConnectionDialog(Properties.Settings.MonitorConnection).ShowDialog();
+ }
+ }
+}
diff --git a/Duplicati/Scheduler/Monitor.SQL/Properties/AssemblyInfo.cs b/Duplicati/Scheduler/Monitor.SQL/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..918827b72
--- /dev/null
+++ b/Duplicati/Scheduler/Monitor.SQL/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Duplicati.Scheduler.Monitor.SQL")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("Duplicati.Scheduler.Monitor.SQL")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("ee6179d4-89dc-496a-a26e-ead63f35770d")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Duplicati/Scheduler/Monitor.SQL/Properties/Settings.Designer.cs b/Duplicati/Scheduler/Monitor.SQL/Properties/Settings.Designer.cs
new file mode 100644
index 000000000..05dcd3046
--- /dev/null
+++ b/Duplicati/Scheduler/Monitor.SQL/Properties/Settings.Designer.cs
@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.4961
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace Duplicati.Scheduler.Monitor.SQL.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default {
+ get {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/Duplicati/Scheduler/Monitor.SQL/Properties/Settings.settings b/Duplicati/Scheduler/Monitor.SQL/Properties/Settings.settings
new file mode 100644
index 000000000..2bd17f050
--- /dev/null
+++ b/Duplicati/Scheduler/Monitor.SQL/Properties/Settings.settings
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Duplicati/Scheduler/Monitor.SQL/SQLConnectionDialog.Designer.cs b/Duplicati/Scheduler/Monitor.SQL/SQLConnectionDialog.Designer.cs
new file mode 100644
index 000000000..01de61267
--- /dev/null
+++ b/Duplicati/Scheduler/Monitor.SQL/SQLConnectionDialog.Designer.cs
@@ -0,0 +1,228 @@
+namespace Duplicati.Scheduler.Monitor.SQL
+{
+ partial class SQLConnectionDialog
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.Windows.Forms.Label dataSourceLabel;
+ System.Windows.Forms.Label passwordLabel;
+ System.Windows.Forms.Label userIDLabel;
+ System.Windows.Forms.Label label1;
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SQLConnectionDialog));
+ this.integratedSecurityCheckBox = new System.Windows.Forms.CheckBox();
+ this.passwordTextBox = new System.Windows.Forms.TextBox();
+ this.userIDTextBox = new System.Windows.Forms.TextBox();
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.SavePwCheckBox = new System.Windows.Forms.CheckBox();
+ this.CanButton = new System.Windows.Forms.Button();
+ this.OKButton = new System.Windows.Forms.Button();
+ this.TestButton = new System.Windows.Forms.Button();
+ this.CatalogTextBox = new System.Windows.Forms.TextBox();
+ this.DataSourceComboBox = new System.Windows.Forms.ComboBox();
+ dataSourceLabel = new System.Windows.Forms.Label();
+ passwordLabel = new System.Windows.Forms.Label();
+ userIDLabel = new System.Windows.Forms.Label();
+ label1 = new System.Windows.Forms.Label();
+ this.groupBox1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // dataSourceLabel
+ //
+ dataSourceLabel.AutoSize = true;
+ dataSourceLabel.Location = new System.Drawing.Point(9, 13);
+ dataSourceLabel.Name = "dataSourceLabel";
+ dataSourceLabel.Size = new System.Drawing.Size(110, 13);
+ dataSourceLabel.TabIndex = 3;
+ dataSourceLabel.Text = "Data Source (Server):";
+ //
+ // passwordLabel
+ //
+ passwordLabel.AutoSize = true;
+ passwordLabel.Location = new System.Drawing.Point(13, 48);
+ passwordLabel.Name = "passwordLabel";
+ passwordLabel.Size = new System.Drawing.Size(56, 13);
+ passwordLabel.TabIndex = 17;
+ passwordLabel.Text = "Password:";
+ //
+ // userIDLabel
+ //
+ userIDLabel.AutoSize = true;
+ userIDLabel.Location = new System.Drawing.Point(23, 22);
+ userIDLabel.Name = "userIDLabel";
+ userIDLabel.Size = new System.Drawing.Size(46, 13);
+ userIDLabel.TabIndex = 23;
+ userIDLabel.Text = "User ID:";
+ //
+ // integratedSecurityCheckBox
+ //
+ this.integratedSecurityCheckBox.Location = new System.Drawing.Point(12, 75);
+ this.integratedSecurityCheckBox.Name = "integratedSecurityCheckBox";
+ this.integratedSecurityCheckBox.Size = new System.Drawing.Size(133, 24);
+ this.integratedSecurityCheckBox.TabIndex = 8;
+ this.integratedSecurityCheckBox.Text = "Integrated security";
+ this.integratedSecurityCheckBox.UseVisualStyleBackColor = true;
+ this.integratedSecurityCheckBox.CheckedChanged += new System.EventHandler(this.integratedSecurityCheckBox_CheckedChanged);
+ //
+ // passwordTextBox
+ //
+ this.passwordTextBox.Location = new System.Drawing.Point(75, 45);
+ this.passwordTextBox.Name = "passwordTextBox";
+ this.passwordTextBox.Size = new System.Drawing.Size(163, 20);
+ this.passwordTextBox.TabIndex = 18;
+ this.passwordTextBox.UseSystemPasswordChar = true;
+ //
+ // userIDTextBox
+ //
+ this.userIDTextBox.Location = new System.Drawing.Point(75, 19);
+ this.userIDTextBox.Name = "userIDTextBox";
+ this.userIDTextBox.Size = new System.Drawing.Size(163, 20);
+ this.userIDTextBox.TabIndex = 24;
+ //
+ // groupBox1
+ //
+ this.groupBox1.Controls.Add(this.SavePwCheckBox);
+ this.groupBox1.Controls.Add(this.userIDTextBox);
+ this.groupBox1.Controls.Add(userIDLabel);
+ this.groupBox1.Controls.Add(this.passwordTextBox);
+ this.groupBox1.Controls.Add(passwordLabel);
+ this.groupBox1.Location = new System.Drawing.Point(35, 93);
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.Size = new System.Drawing.Size(255, 100);
+ this.groupBox1.TabIndex = 25;
+ this.groupBox1.TabStop = false;
+ //
+ // SavePwCheckBox
+ //
+ this.SavePwCheckBox.AutoSize = true;
+ this.SavePwCheckBox.Location = new System.Drawing.Point(75, 72);
+ this.SavePwCheckBox.Name = "SavePwCheckBox";
+ this.SavePwCheckBox.Size = new System.Drawing.Size(99, 17);
+ this.SavePwCheckBox.TabIndex = 25;
+ this.SavePwCheckBox.Text = "Save password";
+ this.SavePwCheckBox.UseVisualStyleBackColor = true;
+ //
+ // CanButton
+ //
+ this.CanButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.CanButton.CausesValidation = false;
+ this.CanButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.CanButton.Location = new System.Drawing.Point(247, 241);
+ this.CanButton.Name = "CanButton";
+ this.CanButton.Size = new System.Drawing.Size(75, 23);
+ this.CanButton.TabIndex = 27;
+ this.CanButton.Text = "Cancel";
+ this.CanButton.UseVisualStyleBackColor = true;
+ this.CanButton.Click += new System.EventHandler(this.CanButton_Click);
+ //
+ // OKButton
+ //
+ this.OKButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.OKButton.CausesValidation = false;
+ this.OKButton.Location = new System.Drawing.Point(166, 241);
+ this.OKButton.Name = "OKButton";
+ this.OKButton.Size = new System.Drawing.Size(75, 23);
+ this.OKButton.TabIndex = 28;
+ this.OKButton.Text = "OK";
+ this.OKButton.UseVisualStyleBackColor = true;
+ this.OKButton.Click += new System.EventHandler(this.OKButton_Click);
+ //
+ // TestButton
+ //
+ this.TestButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+ this.TestButton.CausesValidation = false;
+ this.TestButton.Location = new System.Drawing.Point(12, 241);
+ this.TestButton.Name = "TestButton";
+ this.TestButton.Size = new System.Drawing.Size(75, 23);
+ this.TestButton.TabIndex = 29;
+ this.TestButton.Text = "Test";
+ this.TestButton.UseVisualStyleBackColor = true;
+ this.TestButton.Click += new System.EventHandler(this.TestButton_Click);
+ //
+ // label1
+ //
+ label1.AutoSize = true;
+ label1.Location = new System.Drawing.Point(73, 39);
+ label1.Name = "label1";
+ label1.Size = new System.Drawing.Size(46, 13);
+ label1.TabIndex = 30;
+ label1.Text = "Catalog:";
+ //
+ // CatalogTextBox
+ //
+ this.CatalogTextBox.Location = new System.Drawing.Point(125, 36);
+ this.CatalogTextBox.Name = "CatalogTextBox";
+ this.CatalogTextBox.Size = new System.Drawing.Size(197, 20);
+ this.CatalogTextBox.TabIndex = 31;
+ //
+ // DataSourceComboBox
+ //
+ this.DataSourceComboBox.FormattingEnabled = true;
+ this.DataSourceComboBox.Location = new System.Drawing.Point(125, 10);
+ this.DataSourceComboBox.Name = "DataSourceComboBox";
+ this.DataSourceComboBox.Size = new System.Drawing.Size(197, 21);
+ this.DataSourceComboBox.TabIndex = 32;
+ //
+ // SQLConnectionDialog
+ //
+ this.AcceptButton = this.OKButton;
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.CanButton;
+ this.ClientSize = new System.Drawing.Size(334, 276);
+ this.Controls.Add(this.DataSourceComboBox);
+ this.Controls.Add(label1);
+ this.Controls.Add(this.CatalogTextBox);
+ this.Controls.Add(this.TestButton);
+ this.Controls.Add(this.OKButton);
+ this.Controls.Add(this.CanButton);
+ this.Controls.Add(this.groupBox1);
+ this.Controls.Add(this.integratedSecurityCheckBox);
+ this.Controls.Add(dataSourceLabel);
+ this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+ this.Name = "SQLConnectionDialog";
+ this.Text = "SQL Connection";
+ this.groupBox1.ResumeLayout(false);
+ this.groupBox1.PerformLayout();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.CheckBox integratedSecurityCheckBox;
+ private System.Windows.Forms.TextBox passwordTextBox;
+ private System.Windows.Forms.TextBox userIDTextBox;
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.Button CanButton;
+ private System.Windows.Forms.Button OKButton;
+ private System.Windows.Forms.Button TestButton;
+ private System.Windows.Forms.CheckBox SavePwCheckBox;
+ private System.Windows.Forms.TextBox CatalogTextBox;
+ private System.Windows.Forms.ComboBox DataSourceComboBox;
+ }
+}
\ No newline at end of file
diff --git a/Duplicati/Scheduler/Monitor.SQL/SQLConnectionDialog.cs b/Duplicati/Scheduler/Monitor.SQL/SQLConnectionDialog.cs
new file mode 100644
index 000000000..8844580a2
--- /dev/null
+++ b/Duplicati/Scheduler/Monitor.SQL/SQLConnectionDialog.cs
@@ -0,0 +1,149 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+
+namespace Duplicati.Scheduler.Monitor.SQL
+{
+ ///
+ /// Provides a form to edit the SQL connection string
+ ///
+ public partial class SQLConnectionDialog : Form
+ {
+ ///
+ /// Encrypted connection string in an XML file
+ ///
+ public string HomeConnectionXMLFile { get; set; }
+ ///
+ /// Resulting connection string
+ ///
+ public string ConnectionString { get; private set; }
+ ///
+ /// Builder used to parse/set the string
+ ///
+ private System.Data.SqlClient.SqlConnectionStringBuilder ConnectionStringBuilder;
+ ///
+ /// Creator
+ ///
+ /// Name of XML file to load/save
+ public SQLConnectionDialog(string aHomeConnectionXMLFile)
+ {
+ InitializeComponent();
+ // Save the file nae, load the connectin string
+ this.HomeConnectionXMLFile = aHomeConnectionXMLFile;
+ this.DataSourceComboBox.Items.Add(Environment.MachineName + @"\SQLEXPRESS");
+ this.ConnectionString = new Duplicati.Scheduler.Data.ConnectionFromXML().ConnectionString(aHomeConnectionXMLFile);
+ }
+ ///
+ /// Form loaded, populate the controls
+ ///
+ protected override void OnLoad(EventArgs e)
+ {
+ base.OnLoad(e);
+ try
+ {
+ // Parse the string
+ this.ConnectionStringBuilder = new System.Data.SqlClient.SqlConnectionStringBuilder(this.ConnectionString);
+ }
+ catch (Exception Ex)
+ {
+ // If error, say it, and clear the connection string
+ MessageBox.Show(Ex.Message);
+ this.ConnectionStringBuilder = new System.Data.SqlClient.SqlConnectionStringBuilder();
+ }
+ // Set the controls
+ this.DataSourceComboBox.Text = this.ConnectionStringBuilder.DataSource;
+ this.integratedSecurityCheckBox.Checked = this.ConnectionStringBuilder.IntegratedSecurity;
+ this.userIDTextBox.Text = this.ConnectionStringBuilder.UserID;
+ this.passwordTextBox.Text = this.ConnectionStringBuilder.Password;
+ this.SavePwCheckBox.Checked = this.ConnectionStringBuilder.PersistSecurityInfo;
+ this.CatalogTextBox.Text = this.ConnectionStringBuilder.InitialCatalog;
+ }
+ ///
+ /// Integrated checkbox pressed, enable/disable the login stuff
+ ///
+ private void integratedSecurityCheckBox_CheckedChanged(object sender, EventArgs e)
+ {
+ this.groupBox1.Enabled = !this.integratedSecurityCheckBox.Checked;
+ }
+ ///
+ /// OK pressed, get the string from the controls and close
+ ///
+ private void OKButton_Click(object sender, EventArgs e)
+ {
+ // Check if all OK, also loads the string builder from the controls
+ if (!Parse()) return;
+ this.ConnectionString = this.ConnectionStringBuilder.ConnectionString;
+ try
+ {
+ // Save the result
+ new Duplicati.Scheduler.Data.ConnectionFromXML().SaveConnection(this.HomeConnectionXMLFile,
+ this.ConnectionString);
+ }
+ catch (Exception Ex)
+ {
+ MessageBox.Show("Error saving connection string: " + this.HomeConnectionXMLFile + ": " + Ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return;
+ }
+ this.DialogResult = DialogResult.OK;
+ Close();
+ }
+ ///
+ /// Gets the connection string builder from the controls
+ ///
+ /// True if no errors
+ private bool Parse()
+ {
+ bool Result = false;
+ try
+ {
+ this.ConnectionStringBuilder.DataSource = this.DataSourceComboBox.Text;
+ this.ConnectionStringBuilder.InitialCatalog = this.CatalogTextBox.Text;
+ this.ConnectionStringBuilder.IntegratedSecurity = this.integratedSecurityCheckBox.Checked;
+ if (!this.integratedSecurityCheckBox.Checked)
+ {
+ this.ConnectionStringBuilder.UserID = this.userIDTextBox.Text;
+ this.ConnectionStringBuilder.Password = this.passwordTextBox.Text;
+ this.ConnectionStringBuilder.PersistSecurityInfo = this.SavePwCheckBox.Checked;
+ }
+ Result = true;
+ }
+ catch (Exception Ex)
+ {
+ MessageBox.Show(Ex.Message);
+ }
+ return Result;
+ }
+ ///
+ /// Test pressed, test the connection
+ ///
+ private void TestButton_Click(object sender, EventArgs e)
+ {
+ // Get the builder
+ if (!Parse()) return;
+ try
+ {
+ // Open a connection
+ using (System.Data.SqlClient.SqlConnection oc = new System.Data.SqlClient.SqlConnection(
+ this.ConnectionStringBuilder.ConnectionString))
+ oc.Open();
+ MessageBox.Show("Connection succeeded", "SUCCESS", MessageBoxButtons.OK, MessageBoxIcon.Information);
+ }
+ catch (Exception Ex)
+ {
+ MessageBox.Show("Error connecting: " + Ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ }
+ ///
+ /// Cancel pressed, close
+ ///
+ private void CanButton_Click(object sender, EventArgs e)
+ {
+ this.DialogResult = DialogResult.Cancel;
+ Close();
+ }
+ }
+}
diff --git a/Duplicati/Scheduler/Monitor.SQL/SQLConnectionDialog.resx b/Duplicati/Scheduler/Monitor.SQL/SQLConnectionDialog.resx
new file mode 100644
index 000000000..36bfafbd8
--- /dev/null
+++ b/Duplicati/Scheduler/Monitor.SQL/SQLConnectionDialog.resx
@@ -0,0 +1,636 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+ False
+
+
+
+
+ AAABAAwAMDAQAAEABABoBgAAxgAAACAgEAABAAQA6AIAAC4HAAAYGBAAAQAEAOgBAAAWCgAAEBAQAAEA
+ BAAoAQAA/gsAADAwAAABAAgAqA4AACYNAAAgIAAAAQAIAKgIAADOGwAAGBgAAAEACADIBgAAdiQAABAQ
+ AAABAAgAaAUAAD4rAAAwMAAAAQAgAKglAACmMAAAICAAAAEAIACoEAAATlYAABgYAAABACAAiAkAAPZm
+ AAAQEAAAAQAgAGgEAAB+cAAAKAAAADAAAABgAAAAAQAEAAAAAACABAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAIAAAIAAAACAgACAAAAAgACAAICAAACAgIAAwMDAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP//
+ /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4d3d3d3d3
+ d3d3d3d3d3d3d3cAAAAAAIeIiPj4+Pj4+Pj4+Pj4+Pj4+Ph4AAAACHh3JyNiNiNiNiNiNiNiNiNiNniH
+ cAAACIcnInI2I2I2I2I2I2I2I2I2MiN/cAAAh4JyemJjanJ6cnpyenJ6cnpyY2poiAAAiHIqNjOmMjYj
+ ajY2JycjajYnpycnhwAAiCcnImJyemOoeHh4eHh4eHh4dyMniAAAh3KnJ6cqNjY4////////////h6an
+ hwAAiCciejJyY6Jn/4+PiPiI+I+P9ycj9wAAiCJ6JyajYnJ4+P+P+Pj4j4iPh6cmiAAAiHo2NqNjp6Ko
+ /4+Pj4+PiPiP9yJ69wAAiCYno2NiYnJ3//j4iIiIiIj492OniAAAiCOmJjpjo2p4+PiIiIiIiIiPh6Yy
+ 9wAAiHJzeHd4d3d3//j/j/j4+Ij49yemiAAAiCpqiP/4///4//+P+Pj4j4+Ph6Yz+AAAiHI3j4j4+IiI
+ +PiIiPiIiIiP9yNqiAAA96emf/j4+Pj3//j4+Ij4+IiPh6aniAAAiHI6j4+PiPiI+P+P/4//j/iP92On
+ iAAA9yp2iPj4j4iI/4iIj4j4+Pj496cm+AAAiHp6j4+IiIiI//j4j4j//4iPh6ajiAAA+CcjiPiIiIiI
+ +P//+Pj4+Pj/9yen+AAAiCp6j////4+I/4iIj4j4+PiPh6ei9wAAiHpjiIiIiIiI//iIj4iIiIj/96Y2
+ +AAA+Cenj/+IiPiIj4//////+Pj492p6iAAAiKeniPj/j4iI//+Pj4+Pj4+Ph6en+AAAiHp6j/+IiPj4
+ +P///////4iIiHp6iAAA+Cd3j4+I+PiI/4+Pj4+Pj4iIhqh3+AAAiKeoj/j/j4+I////////+I+Id3p6
+ iAAAiHeniP+I+PiI/4+Pj4+Pj4iIp6in9wAAiKeKj/j4iPj4////////+IiGiod6+AAAiDqHj/+P+P+I
+ +Pj4+Pj4/4eoqKiniAAAiGioj4/4/4/4iIiIiIiIeH53d3qK9wAAiKeKj/j/j/j///iPiH6neoqKioh6
+ 9wAAiHqIj/+P+P+Pj4iIiIeKiKiHeKin9wAAh6h3j4/4/4//+Pj4iKiod4qKioiKiAAA93d3j///j/j4
+ /4j4joeHd4eHiKin9wAAiKh4j4+P////j/iId3eoeoqKh4eKiAAAiDioj///j4+P+PiOuKiIeIiIqKh6
+ 9wAA92eIiIiIiIiIiIh4qIiod6ioiId3iAAAiHqKh4eHiHiHjod4iKiIeIiHd3eohwAAD3eoioeKh4qH
+ h3h3eIioioeHh6eHgAAACIh3p6p6emp6qqqqqqenp6qqp3h4cAAAAIiHh4eHh4h4eIiIh4eHeHh4h4eI
+ AAAAAACIiIiIiIiIiIiIiIiIiIiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAD///////8AAP///////wAA/AAAAAA/AADwAAAAAA8AAOAAAAAABwAA4AAAAAAH
+ AADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAA
+ AAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAAD
+ AADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAA
+ AAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAAD
+ AADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADgAAAAAAcAAOAA
+ AAAABwAA8AAAAAAPAAD8AAAAAD8AAP///////wAA////////AAAoAAAAIAAAAEAAAAABAAQAAAAAAAAC
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAICAgADAwMAAAAD/AAD/
+ AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAAAAAAAAAId3d3d3d3d3d3d3eAAAAAeIiHiI
+ eIh4iHiIeIhwAACHciJyInIiciJyInInhwAIgicnononpypypyejYniACHcqcnI2d3d3d3d3d3oocAhy
+ ciKnInj///////hyeHAIenJ6cnp4+Pj4iIj/aihwCHJ6cmOmP/+Pj/j4j3NogAh6NiOmMn+IiIiIiI9q
+ OHAIgmeIiIh///+PiI+PcmiACHOn+PiPiPiI+IiIj2OocAiCd/j4+I//j4j/+P96eIAIemf4+IiPj4j4
+ +PiPY6hwCIKo+IiIiPj4+P+I/2pogAh3p//4+I/4+PiP+PhzqHAIinf4iIiPj4j4iIj/aniACHp3/4/4
+ j//////4+HeocAiHqPiIj4j4+Pj4+Ih6eIAIenj//4+P/////4j3eniACIeo+Ij4j4+Pj4+IioeocAh6
+ iI/4/4//////iH6oqIAIh6j/j4+IiIiHeOeod4hwCHqI//////iIjqioiop4cAh4ePj4+Pj4+HiKh3h4
+ qIAIeoj/////+Ih6iHioqIhwCHio+I+I+IiOiKh4h4eocAiKiIiIiOiId3iHeoeHqIAAh3qKinqKioqK
+ ioiop4gAAAiHd3eHd3d3d3d3d4hwAAAAiIiIiIiIiIiIiIiIAAAAAAAAAAAAAAAAAAAAAAAA//////AA
+ AA/gAAAHwAAAA4AAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAA
+ AAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAcAAAAPgAAAH8AAAD///
+ //8oAAAAGAAAADAAAAABAAQAAAAAACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAA
+ AACAAIAAgIAAAICAgADAwMAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AAAAAAAAAAAAAAAAAACI
+ iIiIiIiIiIh4AAh3IiIiIiIiIid4gAhycnNnNnNnNjIngAgiNiY2iIiIiPgigAh6Y6On////j4hjgAgj
+ anYn/4iI+IimgAhqdzd3+Pj4iPgjgAg2j4+I/4+IiIhqgAgjj4+I+Pj/+PgngAh6j4iI+I+I+PimgAin
+ j4+I//j/iPgjgAh6j4iI+I+I+Pim8Ainj4+I////+Ih6gAh3j4+I/4+PiIengAinj4j4////+IqK8Ah3
+ j//4iIiIiGh3gAioj4+P+PiKioqKgAh4j///+IjoeHiogAioj/j4+IioqKiKgAh4iIiIiHiIiIeHgAiK
+ enp6eoqnp6iogACIiIiIiIiIiIiIAAAAAAAAAAAAAAAAAP///wDAAAMAgAABAIAAAQCAAAEAgAABAIAA
+ AQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAA
+ AQDAAAMA////ACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACA
+ AAAAgIAAgAAAAIAAgACAgAAAgICAAMDAwAAAAP8AAP8AAAD//wD/AAAA/wD/AP//AAD///8AAAAAAAAA
+ AAAId3d3d3d3gAcioqenp6JwB6cnj4+P93AHInKI+IiGcAd4iI+Pj/KACn+Pj4+I9jAHeIiPj/j3oAev
+ +P+Pj4eAB4j4j//4ioAHf4+P+PiGgAeI//iId6igCo/4+Iioh4AIiIiIh4d4oAh6h3qKioeAAAAAAAAA
+ AAD//wAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB
+ AAD//wAAKAAAADAAAABgAAAAAQAIAAAAAAAACQAAAAAAAAAAAAAAAQAAAAEAAAAAAAAvkS8AL5YvAC+a
+ LwAvnS8ANYk1ADWMNQA/hj8AN484ADiPOAAwkTAAMJUwADaRNgA2lTYAMJgwADCeMAA3kzgAOJQ4ADiZ
+ OAA5nTkAMKMwADigNwAwqzAAOqE6ADumOwA8ojwAPaY8ADyrPAAxsDEAPbQ9AECLQABdi10AQK9BAEK0
+ QgBDu0QATb5NAFukXABZvlkAYY1hAGGQYgBrkGkAdJJyAHWUcwB2lnQAd5h0AHicdgB8n3oAYaphAH6i
+ fAB7sXkARMREAEjASABUwlQAW8ZbAF/KXwBjxWMAY8xjAGrMagBr0WsAbNpsAHPUcwB22HYAe9V7AHzZ
+ fACAk30AgaJ/AIDXfwCLi4sAi4uMAI2NjgCFkYEAg5eDAIaShQCIlIQAiZWIAI+PkACRkZIAlJaQAJSU
+ lQCWmZMAl5qUAJiblQCZnJYAl5eYAJiYmQCbnpgAnJ6YAJqanACdnZ0AhKSFAI+jjwCGsIQAi7OJAJC1
+ jwCYoZkAnaCaAJq6mACjp58An5+gAKGhogCjpKAApaaiAKOjpACkpKYAqqamAKOooAClqaEApqikAKio
+ pACnp6gAp66oAKioqQCrrKgAqqqsAKysrgCyrq0AqrSoALOwrwCurrAAsLCyALWxsQC2tbIAs7O0ALa2
+ tgC8tbIAtby1ALq5tQC5uLkAvbq6AL2+ugC+vLwAwreyAMK4swDBubYAxbq2AMG8uQDGvbkAwb+/AMW/
+ vADIv7wAgt2CAIrdigCSwpEAmcSXAJ7AnQCF4IUAi+KLAJPkkwClwaIAqcOnAK/HrQCzzrEAvsy8AMPA
+ vgDIwb4AwM2+AMHBwADFwsEAxcXCAMPDxADGxcYAy8PAAMrEwQDMxcIAyMbFAM3HxADCzcAAzcjGAMnJ
+ yADNysgAy8zJAM3OywDNzc4A2s3HAN3MxgDSzcoA2M7JAN7OyADP0M0A1dDOAN7QygDa0s0A3tHNAM/P
+ 0ADR0dEA1tLQANPT1ADV1dUA29XSAN7Y1QDX19gA2dnZANvb3ADc3N0A4dHKAODTzQDk08wA4tTPAOXV
+ zgDr1s4A7NfOAOzYzwDh1tIA5tfQAOjX0ADm2NIA4drWAOXa1QDo2dMA7drSAO3c0wDp2tQA7tvUAOnc
+ 1gDu3dUA4tzZAOXd2gDh390A5d/cAOne2QDt39gA8N/XAOXg3QDr4d0A8OHaAPDi3ADx5N4A4+LhAOrk
+ 4ADs5eEA6ubkAOzn5ADu6OUA6urpAOvs6wDv7+0A8ubgAPLo4gDx6eYA9OrmAPTs5wDw6+gA8u3qAPXu
+ 6gDz7uwA9O/tAPbw7QD48u8A8vLxAPn08QD5+PcA+fn4AAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUU1NERERERERERERERERERERERERERERERERE
+ RERERERERFMAAAAAAAAAAAAAZ2dUiauruLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLjAuHJEVAAA
+ AAAAAAByZ2duHwcFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUHJ324S1QAAAAAAACeZ0cFCgoK
+ AQoBAQEKAQEKAQEKAQEKAQEKAQEKAQoBAQoBAQoKCgVauFMAAAAAAH9tVAUKCgoKCgoKCgoKCgoKCgoK
+ CgoKCgoKCgoKCgoKCgoKCgoKCgoJfXpTAAAAALhnHwELAQEKAQoBAQEKAQEKCgkSCQkJEgkJCRIJCQkS
+ CQkJEgkKCgoBJ8BTAAAAALhUHgEKAQEKAQoBAQEKAQESSmFfX19fX19fVVVVVVVVUVVRUVEoAQoBHsBV
+ AAAAAKtUCRICAhIBAhIBAhIBAhISYfv7+/v7+/v7+/v7+/r6+vr7++kpChICCr5TAAAAALdUEQECAgIC
+ AgICAgICAgESYfvw8Ozs7Ozd3d3d3cnd3cnd3ekpAgICCbhUAAAAALhUCQ8PAQICAgICAgICAgIVavvw
+ 7Ozs3d3d3d3HycnHx8fH7OkpAgICCcBUAAAAALhnEQIPAgIPAgIPAgIPAg8Vavvw8PDs7Ozs3d3d3cfJ
+ x8fH3ekpAhUCEr5nAAAAALhnChICDwIUAhQCDw8PAg8Vavvw8N3OzsXFtraxsbGurq7H7OksAg8CEr5n
+ AAAAALhnEg8PDxQUFQ8PDw8PDw8Xavv38KShoaGIiIiGhoaGg4PH7OkpDw8PEr9nAAAAALhnEg8PFUBH
+ R0dHR0dGRkZHaPv28PDn593n3dvb3c7dxczd7OksDw8PE79nAAAAALhyEhQUF2fp6enp6enp6enncvv2
+ 9vDw6e3w8N3n293O3d3M7OksFBQPE8BuAAAAALhyEhQVF2Hw59vb293O3c7Fc/v28KSkpaHavaSkiIiI
+ hobd8OksFBQUE8ByAAAAAMByFw8WF2rp3dvdxc7HxcWxc/v29trazs7wvbbn3efd2ojb8OksFBUPF8By
+ AAAAALhyFxYWGmr43d7a293FzsfFc/v29vD38/P3vbbw8PDw7Yjd8OksFhYWF8ByAAAAAMByFxYVGmrr
+ 593Oxb22xa6uc/v28LOvr6fnvb329vDw8Ijp8OktFBQWF8B2AAAAAL92FxYWGmrr6dqIf4Z8fHx8c/v2
+ 9raztq/tvb3w9vfw8KHt8OktFhYWF8B6AAAAAL92GhwWHXDr593Avb22tranc/v39vb28Pbwvb3w9vf3
+ 8J7w9+ktFhYWGsF2AAAAAMB2GhwWHWfr5+fd593j3d7devv38L29vb3pva/n3ePn3Z7w9ukuHBYcGsF6
+ AAAAAMB2GhwcHXDp6d2eiYl/3q+Ic/v28K+ppKTd2qukqaSkpKTw+ekuHBwcGsF6AAAAAMB2HSIdIXL2
+ 596vr6+n3amkevv29vDw8/D28PDw8PDw8PDw8OkuIiIiHcB6AAAAAL92HSMjJXr26fDn6fDp6a+zfvv3
+ 9vf39/P58Pn58/fw59ra4+MuIyMjIMB2AAAAAL9yITQ0NXz48Oe2s7Oz3bi9ifv59/f39/n5+ff5+fnw
+ r56IqKtBNDQ0IcB2AAAAAL5yHTQlN3746eevr6+p6ba4ofv59/f39/f39/f38/nnc6ief2gxNDQ0IcB2
+ AAAAALh2ITU1OH/48Onw6fDp8L29nvv59/f59/f59/f5+fPngOnZiVs1NTU1IcByAAAAAMByHTg1OYH4
+ 8Ona2trO6b24qfv5+fn5+fn5+fn3+fnnf9mJXDg2NTg1IsByAAAAALhyHTg4OZ748Omvr6un3cCvnvv7
+ +fv5+/n7+fn5+fnwiaBdOTg4ODg4IsBuAAAAALhnIjk6PIn48PDp6fDp6fDnpPj4+Pj4+Pj4+Pj4+Pjp
+ e2A5OTo6Ojo6IsBnAAAAALhnIjo6PKT49unw8PDw8Onwr6urpKSknqSedpSUlJSUjzw6Ojo6Ojo6IsBn
+ AAAAALhnIjw8PqT66fbw8Pjw+PD48PDw6b2vqbezXTw8PD08PDw8PDw8PDw8M71jAAAAALhhIj09Qqv4
+ 9vD48Pjw8Pjw+PD424CeiYl6jj09PT09PT09PT09PT09M75jAAAAALdUIj1CQqv49vbw+PD4+PD48Pjw
+ 457p2aiQPUI9jD2MPYw9jD2MPYw9I7hjAAAAALdUM4yMkqv4+Pjw+Pj48Pjw+PD446jZt5RCjIyMQoxC
+ QoyMjEKMjIyMI75UAAAAALhUMoyMkrP4+Pj4+Pj3+Pj4+Pj456i3lY2MkYySjJKMkpKMkoySjIyMMrhU
+ AAAAAMBUIZKSk7L4+Pn4+Pj4+Pj3+Pn46YmWjZKSkpKSkpKSkpKSkpKSkpKRI7hjAAAAAMBULzuSk5um
+ pqampqSmpJukm6Sbm5eTjZKSk5KSkpKSkpKSkpKSkpI7L6RUAAAAAH9/SjKSk5OTk5OTk5OTk5OTkpOS
+ k5OTk5OTk5OTk5OTkpOSk5KTk5IylGNjAAAAAADjUykyPJOTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OT
+ k5OTk5OTOzJZbW0AAAAAAAB6uFNKJCIyMzMzMzIyMzIyMzI0MjIjMjMzMjMyMzIzMjMyNDIzL15fbm0A
+ AAAAAAAAesB6U0tMTExNTFFMTUxRTExMTExMTExMTExMTExMTUxNSkxTU2OfcgAAAAAAAAAAAAB6uMCr
+ pKCgpJ+goKCkn6CboKCfoKCgoKCgoKCgoKCgoKC3t30AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAD///////8AAP///////wAA/AAAAAA/AADwAAAAAA8AAOAAAAAABwAA4AAAAAAH
+ AADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAA
+ AAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAAD
+ AADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAA
+ AAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAAD
+ AADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADAAAAAAAMAAMAAAAAAAwAAwAAAAAADAADgAAAAAAcAAOAA
+ AAAABwAA8AAAAAAPAAD8AAAAAD8AAP///////wAA////////AAAoAAAAIAAAAEAAAAABAAgAAAAAAAAE
+ AAAAAAAAAAAAAAABAAAAAQAAAAAAADCPMAAwkTAAMJYwADCaMAAwnTAAMaIxADGlMQAxqjEAMa0xADKw
+ MgA1sjUARItEAEWMRQBGlkUATJJLAFWaVABWnlUAXZNcAF6VXABemF0AYJteAGCeXgBGu0YAS79LAEy9
+ TABVu1YAYaJfAHmXdwBzm3EAc5p0AHSadAB9kH4Ae5R8AH2XfgB6mHgAfJp6AH6cewB+nXwAYqVgAG+q
+ bQB0r3IAfaJ+AFHCUQBVx1UAVshWAFrHWgBfw18AWstaAFzMXABnx2YAYcthAGHPYQBoz2gAb8tuAGXS
+ ZQBo02gAa9ZrAG/TbwBu124AbNpsAHbXdgBy2nIAeNJ4AH3bfQB94H0AhoaGAI2NjQCBlIIAhJKEAIeU
+ hwCAmoEAgp2DAISYhQCQkJEAk5OUAJWVlgCXl5gAmZmaAJubnACenp8AgaWCAIWghgCDp4QAhqaEAIao
+ hQCIqoYAiayHAIejiACJpooAiamJAIuqjACMq40Ai6yMAIysjQCZopoAmqiaAJe3lQCetp4AnrybAKOn
+ nwCgsp4An7egAKGhogClpaYApa2iAKavpACmpqgAqamqAKqqrACtra4AprKmAKiwpQCjvKQApL6kAKm4
+ pwCsuakAqr6rALixrgCvr7AAr7uwALGxsQC1t7MAs7O0ALW1tQC7trQAsr+yALy4twC5ubkAvrq5ALu7
+ vAC+vb0Awru3AMa6tQDDvLkAxL+9AMi9uQCOzo0AhN6EAJPDkgCSx5EAlMiSAJXRlACd1J0Ant6eAKDf
+ nwCK4YoAkeSRAJrgmgCiwKAApsKlAKPIowCmyqYAp8OoAKnGqQCpyqoArsqtALLNsQC6w7oAt9G1ALrU
+ uQDGwL4AysG9AM3BvAC/v8AAwcHBAMXCwgDDw8QAxcXGAMjCwADNxMEAz8fEAMjIxgDHx8gAycnJAM3K
+ yQDNzMsAzMzMANDFwQDRyMUA1MvHANHNywDUzcoA0s7NANXPzADW0M4A2NHOANXU1ADY09AA2tTRANzW
+ 0wDa1dQA3djVANrZ2QDf29gA3d3dAODSzQDl1M0A7NfOAOzYzwDi1tEA5tfQAOfZ0wDg2dYA5NrVAOrZ
+ 0gDs2dEA6dvVAO7b1ADu3dYA4drYAOLd2gDl3tsA6t7YAO/f2ADl4N0A6uDbAO7h2wDp4t0A7uPdAO/k
+ 3wDw4doA8ePcAPHk3gDj4uEA5OPiAOTk4wDl5eQA6OLgAOrk4ADt5eEA6OfmAOzn5ADu6OQA6urpAO3q
+ 6QDt7OoA7u7sAPDm4QDx6eUA9OnkAPXs5wDw6+gA8u3qAPXu6QDy7uwA8vDuAPbw7QD48u8A8/HwAPXz
+ 8QD09PIA+PPwAPj08gAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHlK
+ QkJCQkJCQkJCQkJCQkJCQkJCQkJDbQAAAAAAAABQbW9iYmJiYmJiYmJiYmJiYmJiYmJiZnilSgAAAAAA
+ bWANAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ2eUAAAAK5tDQECAgICAgICAgICAgICAgICAgICAgICAg2l
+ eQAApEYBAQICAgICAgIOJSUlJSUlJSUlJRwlHA8CAn5NAACkHAIEAgQCBAIEAhDg/f39+Pj29vb29vbs
+ EgIEcUoAAKQcAgQEBAQCBAQEEODw7u7W1tbGxsbGxvYSBAKWUAAApEcEBAQEBAQEBAQQ4Pju7u7W1tbO
+ xsbG6RIEBHFQAAClRwQEBAQEBgQEBhHg+MSysrKIiIiIiMbsFAQGllAAAKVYBgYdb29qb2pqZOD48PDm
+ 3Nzczs7OzuwUBgSZZwAArVgGBlTs5tzc1Nyr4PjCvLjmuLS0qqrW7BUGBplnAAClWwYGVezWzMzJybLg
+ +Obm1Pa08ObctNzsFQYGm2sAAK5bCAZV7NzMyMm6iOD31MK+6br29PC07vYWCAiZbQAArlsICFfs1KmH
+ hIR24P3cwszpxPb097rw7BsICJttAACuWwgIV+zm5tzc1rTg9+bUwva45vDmuPD2GwgIm20AAK5bCwtV
+ 7NyppKm6fef4wsLE5r6+usS6+OwnCwubbQAArlsXGGHs6dTm5r6l5vj49vb3+Pb29tTm4CgYGJttAACu
+ WxgrY/jmvK68wq7s+Pf39/f39/fCh32eKSsYm20AAK1bKy6W7Ozg5uDCuOz99/399/39977CwmYvLiub
+ bQAApVssM5b46cLCwsK47P399/399/33wrxzMjMzLJtnAAClVy43mf3swtTg8Lzg/f39/f39/f3CczY1
+ NTUum2cAAKVVNDqb/fb29vb25sK8vK6upYuNjYs/Ojo6OjeYZwAApVE3PZ347Pbw9vb29vaqpap5PT09
+ PT0/PT0/N5hQAACkKjlAn/329vbw9vbw9q7srYlAQEBAQEBAQEA7mEoAAKQqO4qg/fb2+Pj29vj2uK6O
+ ioqKioqKioqKij2YTQAApUY5kqDg4Obg4ODg4OCuj5KSkpKSkpKSkpKSPJZQAACuahqSlJGRkZGRkZGR
+ kZSTk5OTk5OTk5OTk5IreXkAAACtRho9QUFBQUFBQUFBQUFBQUFBQUFBQUE7K2BnAAAAAAClZxwdHh4e
+ HR4dHh0eHR0dHR0dHR0dHUZndwAAAAAAAACupYB5gHmAeYB5gHmAeYB5gHmAeYB7gK0AAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////8AAAD+AAAAfAAAADgAAAAYAAAAGAAAABgAAAAYAA
+ AAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAA
+ AAGAAAABgAAAAYAAAAGAAAABwAAAA+AAAAfwAAAP/////ygAAAAYAAAAMAAAAAEACAAAAAAAQAIAAAAA
+ AAAAAAAAAAEAAAABAAAAAAAAL5EvAC+WLwAvmi8AMowyADWLNQAwkTAAMZQxADSSNAAwmjAAMZ4xADSZ
+ NAA1nzUAMKEwADClMAA1ojUANqY2ADCpMAAwrTAANqk2ADetNgA7rzsAObM5ADyxPABWklYAW5ZaAFuY
+ WQBcmFoAX5pfAEi4SABNvE0AZ5tlAG6ibABmtmcAabppAG2/bQBRwFEAVsBWAFbFVgBYxlgAXsZeAF3J
+ XQBizGIAZcxlAGvRawBs0WwAbdVtAHDRbwB11nUAedZ5AH/bfwB+3H4AhKGBAIK0gACRvY8Al6iVAJuh
+ nACcpJ0AoaGiAKenqACpqaoArq6uAKu7qQCvvq4AsL+uAK+vsACwsLAAsbaxALW1tgC+t7QAvrm3ALe3
+ uAC4uLkAvLy9AIPJggCC24IAid+JAJfBlQCH4IcAjeONAJDjkACjyaIArM6rALDArgCl2KQAqdmoALHC
+ sACyxLEAysC7AM3DvwC/v8AAwcHCAMPDxADFxMUAycLAAMrFwgDPx8MAycbGAM3HxQDIycYAx8fIAMnJ
+ yADOy8oAy8zIAM3MygDPz88A1cfBANHKxgDVycQA18zHANjLxgDVzswA2c7JAMnXxwDN1ssAy9rKANrQ
+ ywDa0c0Az8/QANbS0ADV1NIA1tbVANrV0QDc1dEA2tbUANnZ1wDe2NUA3NrZANvc2gDe3NsA3t7dAOXS
+ ygDl08wA5dXOAOfY0gDi2tYA6NnTAO3Z0QDp3NYA7t3WAOHb2ADi3NoA5N3ZAOXf3ADq39oA4OHfAOfg
+ 3QDr4NsA6OHeAPDg2QDw4twA4uLhAOnj4ADq5OEA7OXiAO/p5QDv6ugA8ebhAPHq5gDy7eoA9u7qAPPv
+ 7AD17+wA9vHuAPjy7gD08vEA+PTyAPn29AD6+PYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABJOkE9PT09PT09PT09PT09
+ PUI7QgAAAGQ4GQUFBQUFBQUFBQUFBQUFBQUcREkAAEIZAQEBAQEBAQcHBwcHBwcHBwcBHD0AAEcFBwcB
+ AQEBH2dnZ2dnYWddYTcBB0kAAEILCQEDAwMDIKSdlpWLi4mJiz8LB0kAAEkHCwMDCwMDIKadk4uGhYWF
+ iz8DB0kAAEkLDRwaHBoZNKaTenVwbmpqi1MNC1oAAEkND2eYmJiYYaaZfo6GdXBullMNDV0AAF0PEGeT
+ hoaFWKaemZ56np11nVYND10AAF0NFWeTZm5YRaaOb4Z6pKB6nlYSDWcAAF0VEmeZmH6GXaaemZt6np56
+ oFYSFWQAAF0VF2eZYWF1RaaZjpiOjn5+pFYXF10AAF0dJXmejo6OZ6ampKCmoKB6eT4kHV0AAF0eKHmb
+ jn+OZ6ampKampqBdYTUnHl0AAEkkK36cenqOZ6impqampqBkNisrJF0AAEkkL3+cnJygf5F/f39yc3JN
+ LCwsJF0AAEkpMZGkoJymoKB6ZWFKLzAvMS8wKkkAAEIrS5GcppygnKR5f1FLMzMzMzMzK0gAAEkrTJil
+ pqWmpaV5UkxOTk5OTk5OK0gAAEghTFVVVVVVVVVUUFBQUFBQUFBMIzwAAHY4IiwuLi4uLiwsLC4sLi4u
+ LiwiOFsAAAByR0E9PDw8PDxBPTw9PTw9PT1DZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AMAA
+ AwCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAA
+ AQCAAAEAgAABAIAAAQCAAAEAgAABAMAAAwD///8AKAAAABAAAAAgAAAAAQAIAAAAAAAAAQAAAAAAAAAA
+ AAAAAQAAAAEAAAAAAAAwkjAAMJYwADeSNgAwmzAAR5VGAEeZRgBInUcASZVIAFWUUwBWllUAWJtZAEii
+ RwBJp0gAVqBVAFSvUwBcp1sAW6FcAF2mXQBcq1sAXqtfAGiWaQBynnIAZ6NnAGmqagBqrmsAZLFlAGe0
+ ZgBgv2AAbLJsAGy2bABuuW4AeaZ6AHupewByu3MAdb11AHqzegB5tHoAeL14AGTNZAB0wXUAe8F6AHnG
+ eQB8xnwActVyAH7RfQCcvpsAp6moAKusqwCrr6wAt7q3AIbBhwCByoEAhsmFAIXOhgCF0IQAgN2AAIXZ
+ hACK0IoAncGcAJHQkQCS35IAnNecAJvemwChw58AjeKNAL3AuwC52rkAx8e/AMnGxgDIycIAyszFAM7O
+ ygDZycMA28zGANbOygDE08MA1NHPAN3QygDY0s8A39TPANbS0ADZ09AA2tTRANrW1QDe2NYA3dvaAN/d
+ 2wDj1c4A4NbRAOPZ1QDl2dQA4NvYAOLc2QDk3dkA4d7cAOjf2wDC4sEA5eDeAOjh3gDt4dwA8ePdAPHk
+ 3wDt5eEA6+bkAO3o5QDy5+IA8ermAPTq5QDx7OkA9e7qAPPw7gD08O0A+PLvAPXy8AD29PEA+PPwAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAADAWFxcXFxcXFxcXFyAvAAAVAQEBAQgKCgoKCgoB
+ IQAACgECAQIubmxqZmZqCBgAAAsCBAIEO2pZTkpKZAYYAAARDkdHREhsXGBOTmQHHQAAERNnW1hZZ1xi
+ bFtnDR0AABMTZ1lITW5cXG5cbw0fAAAaG21NWU1uZGdqXG0PKAAAHSttVFZWb3Nzb01CHCsAAB81bVxi
+ VnNzc3NIKyc1AAAiPHNubmpNR0A3LSwsNQAAIj5zbW9vX0w5OTg4ODoAACU+YWFhYUM9QUFBQUEzAAAy
+ JSYmJiYmJiYrIiYlMAAAAAAAAAAAAAAAAAAAAAAA//8AAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB
+ AACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAA//8AACgAAAAwAAAAYAAAAAEAIAAAAAAAgCUAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB9fX4GeHh5Onp6
+ emmAgIF8gYGCf4GBgn+BgYJ/gYGCf4GBgn+BgYJ/gYGCf4GBgn+BgYJ/gYGCf4GBgn+BgYJ/gYGCf4GB
+ gn+BgYJ/gYGCf4GBgn+BgYJ/gYGCf4GBgn+BgYJ/gYGCf4GBgn+BgYJ/gYGCf4GBgn+BgYJ/gYGCf39/
+ gHx4eHlpdnZ3Onp6ewYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhISFBnl5
+ enSOjo7klpaX/pKSk/6Ojo7/i4uM/ouLi/+Li4v+i4uM/ouLjP6Li4v/i4uL/ouLi/6Li4v/i4uL/ouL
+ i/6Li4v/i4uL/ouLi/6Li4z/i4uL/ouLi/6Li4z/i4uM/ouLi/6Li4v/i4uL/ouLjP+Li4z+i4uM/ouL
+ i/+Li4z+i4uL/oyMjP+Ojo/+jY2O/oWFhuR1dXZ0enp7BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AACHh4gVjIyNxqSkpf+ZmZr/wMDB/87Ozv/Pz8//0NDQ/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR
+ 0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR
+ 0f/R0dH/0dHR/9HR0f/R0dH/0dHR/9HR0v/Y2Nn/1tbW/62trf+Pj4//fn5/xnh4eRYAAAAAAAAAAAAA
+ AAAAAAAAAAAAAJOTkwaUlJXGpqan/qSkpf6nrqj/X4tf/j+GP/42iDb/NYk1/jWJNf81iTX+NYk1/jWJ
+ Nf41iTX/NYk1/jWJNf41iTX/NYk1/jWJNf41iTX/NYk1/jWJNf41iTX/NYk1/jWJNf41iTX/NYk1/jWJ
+ Nf41iTX/NYk1/jWJNf81iTX+NYk1/jWJNf81iTX+NYk1/jaINv8/hj/+YY1h/rW8tf/U1NT+jIyM/oCA
+ gMZ9fX4GAAAAAAAAAAAAAAAAAAAAAImJinTFxcX/n5+g/oOXg/41izX/L5Av/i+QL/4wkDD/L5Av/jCQ
+ MP8vkC/+L5Av/i+QL/4wkDD/L5Av/i+QL/4wkDD/L5Av/i+QL/4wkDD/L5Av/i+QL/4wkDD/L5Av/i+Q
+ L/4wkDD/L5Av/i+QL/4wkDD/L5Av/jCQMP8vkC/+L5Av/jCQMP8vkC/+L5Av/jCQMP8vkC/+L5Av/jWM
+ Nf+Po4/+1NTV/pKSk/96ent0AAAAAAAAAAAAAAAAmpqbB7CwsOSnp6j/maCa/zWNNf8wkTD/MJEw/zCR
+ MP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCR
+ MP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCR
+ MP8wkTD/MJEw/zCRMP81jTX/tby1/7Ozs/+Li4zkg4OEBwAAAAAAAAAAl5eYO9PT1P6fn5//XItc/i+S
+ L/4wkjD/L5Iv/i+SL/4wkjD/L5Iv/jCSMP8vki/+L5Iv/i+SL/4wkjD/L5Iv/i+SL/4wkjD/N5Q3/jmU
+ Of45lTn/OZQ5/jmUOf45lDn/OZQ5/jmUOf45lDn/OZQ5/jmUOf45lDn/OZQ5/jmUOf85lDn+OZQ5/jmU
+ Of85lDn+OZQ5/jmUOf80kzT+L5Iv/jCSMP8vki/+YZBi/tra2v+VlZb+gICBOwAAAAAAAAAAnJydatPT
+ 0/6cnJ3/QItA/i+TL/4wkzD/L5Mv/i+TL/4wkzD/L5Mv/jCTMP8vky/+L5Mv/i+TL/4wkzD/L5Mv/i+T
+ L/42ljb/i5eI/p6hm/6eoZv/naCa/p2fmf6cn5n/nJ6Y/puemP6bnZf/mp2X/pmclv6ZnJb/mZuV/pib
+ lf+Ym5X+l5qU/pealP+XmZP+lpmT/pSWkP9rkGn+L5Mv/jCTMP8vky/+QItB/tvb2/+ZmZn+g4OEagAA
+ AAAAAAAAq6urfc3Nzv+ZmZr/N484/zCVMP8wlTD/MJUw/zCVMP8wlTD/MJUw/zCVMP8wlTD/MJUw/zCV
+ MP8wlTD/MJUw/zCVMP85mDj/o6ef//n6+f/6+vj/+fn4//n5+P/5+fj/+fn3//n59//5+fj/+fn3//n4
+ 9//5+Pf/+fj3//n49//5+Pf/+fn3//n49//5+Pf/+fn3/+nq6f90knL/MJUw/zCVMP8wlTD/OI84/9XV
+ 1v+YmJn/jIyNfQAAAAAAAAAAr6+wf87Ozv6bm5z/N5E3/i+WL/4wljD/L5Yv/i+WL/4wljD/L5Yv/jCW
+ MP8vli/+L5Yv/i+WL/4wljD/L5Yv/i+WL/45mjj/o6ig/vn5+P706+b/8+ji/vLm4P7y5d//8ePd/vDi
+ 2/7w4Nr/79/Y/u/e1/7u3dX/7tzU/u3c0//t29P+7tvT/u3b0//t29P+8eXf/urq6f90knL+L5Yv/jCW
+ MP8vli/+N5E3/tXV1v+ampv+j4+QfwAAAAAAAAAAsbGyf8/Pz/+dnZ7/N5M4/zCYMP8wmDD/MJgw/zCY
+ MP8wmDD/MJgw/zCYMP8wmDD/MJgw/zCYMP8wmDD/MJgw/zCYMP85mzj/pKmh//n5+P/06+b/8+fi//Lm
+ 4P/y5N7/8eLb//Dg2f/w39f/7t3V/+7b1P/t2tL/7dnR/+zYz//s187/7NfO/+zXzv/s187/8OLc/+rq
+ 6f91k3L/MJgw/zCYMP8wmDD/N5M4/9bW1/+dnZ7/kZGSfwAAAAAAAAAAs7Ozf9DQ0f6fn6D/OJQ4/i+Z
+ L/4wmTD/L5kv/i+ZL/4wmTD/L5kv/jCZMP8vmS/+L5kv/i+ZL/4wmTD/L5kv/i+ZL/45nDj/pamh/vn5
+ +P717en/9Orl/vPp4/7z5+H/8uXf/vHj3f7x4tv/8ODZ/u/e1/7u3NX/7tvT/u3Z0f/s2ND+7NfP/uzX
+ zv/r1s3+8OLc/urq6f91lHP+L5kv/jCZMP8vmS/+OJQ4/tfX1/+fn6D+lJSVfwAAAAAAAAAAtLS1f9HR
+ 0v6hoaL/OJY4/i+bL/4wmzD/L5sv/i+bL/4wmzD/L5sv/jCbMP8vmy/+L5sv/i+bL/4wmzD/L5sv/i+b
+ L/45njj/paqi/vn6+f727+v/9ezn/ufe2v7l29f/5NrV/uLX0/7i1tH/4dTP/uDTzf7f0cz/39DK/t7O
+ yP/dzcf+3czG/t/Nxv/s187+8OPd/urq6v91lHP+L5sv/jCbMP8vmy/+OJY4/tjY2P+hoaP+lpaXfwAA
+ AAAAAAAAtra2f9LS0/6jo6T/OJg4/i+dL/4wnTD/L50v/jGdMf4xnjH/MZ4x/jGeMf8xnjH+MZ4x/jGe
+ Mf4xnjH/MZ4x/jGeMf46oDr/pqqi/vn6+P738O3/8erm/s3Gw/7MxMH/y8PA/sjAvf7Hv7v/xr26/sa8
+ uf7Fu7f/xbq2/sO5tf/CuLP+wrey/sO3sv/r18/+8ePd/urq6v92lXP+L50v/jCdMP8vnS/+OJg4/tnZ
+ 2f+kpKX+mJiZfwAAAAAAAAAAt7e4f9PT1P+lpaf/OZo5/zCfMP8wnzD/OKA3/4CTff+IlIX/iJSE/4eT
+ hP+Gk4P/hpOD/4WSgv+EkYH/hJGB/4SQgP+GkYL/qqem//n6+f/38e3/9u/r//Dp5f/u5+P/7ubh/+3k
+ 3//s497/6+Hc/+vf2v/q3tj/6dzW/+ja1P/o2dP/59fR/+jX0P/t29P/8eXf/+rr6v92lnT/MJ8w/zCf
+ MP8wnzD/OZo5/9nZ2v+mpqf/mpqbfwAAAAAAAAAAuLi5f9TU1f6np6j/Opw6/jCgMP4xoDH/PKI8/qOk
+ oP7r7Ov/6+vq/uvr6v/r6+r+6+vq/uvr6v7r6+r/6uvq/urr6v7n5+b/sa6u/vn6+P738e3/9u/r/vLr
+ 6P7x6ub/8enl/vDo5P716+f/8+nk/u7k3/7u4t3/7ODb/uzf2f/r3df+6tvV/uvb1P/u3dX+8ubg/urr
+ 6v93l3T+MKAw/jGgMf8woDD+Opw6/tra2/+oqKn+nJydfwAAAAAAAAAAubm6f9XV1v6pqar/Op06/jCi
+ MP4xojH/PaM8/qSmov7v7+3/6uLd/urg2//p3tr+6N3Y/ujc1v7n29X/5trU/ubZ0v7j1c//sq2s/vn6
+ +P738e3/8uvn/s/Jx/7Nx8X/zcfE/sjCv/7o4d3/39jU/szFwv7Lw8D/x7+8/se+uv/Gvbn+xby4/sa8
+ uP/u3tf+8uji/urr6v93mHT+MKIw/jGiMf8wojD+Op06/tvb2/+qqqv+np6ffwAAAAAAAAAAurq7f9bW
+ 1/+rq6z/Op86/zGkMf8xpDH/PaU8/6Wmov/v7+3/6uDb/+nd1//o29b/59nU/+fY0v/m19D/5dXO/+TT
+ zP/h0Mn/sq6t//n6+f/38e3/9e/r/+Xe2//j3Nn/49zZ/+Ha1//z7Oj/3dfT/9jSzv/u5uL/7eTg/+3j
+ 3v/s4tz/6t7Z/8W8uP/u4Nr/8+nl/+rr6v93mXX/MaQx/zGkMf8xpDH/Op86/9vb3P+srK3/n5+hfwAA
+ AAAAAAAAu7u8f9fX2P6srK7/OqE7/jCmMP4xpjH/Pac8/qano/7v7+3/6+Ld/urf2v/p3tj+6dzX/uja
+ 1f7n2dP/5tfR/uXWz/7i08v/sq6t/vn6+f738e3/9u/r/vbv6/738Oz/9u/r/vbv6/738Oz/3dfU/tvV
+ 0f727ur/9e3p/vXs5//06uX+8ufi/sa+uv/v493+9Ovn/urr6v94mnX+MKYw/jGmMf8wpjD+OqE7/tzc
+ 3P+tra/+oaGifwAAAAAAAAAAvLy9f9jY2P6tra//O6M7/jCoMP4xqDH/Pak8/qaopP7v7+7/7OTg/uvi
+ 3f/i2dT+4NfS/t/V0P7e087/3tHN/t3Qy/7azcf/s6+u/vr6+f738e3/9O3p/tXPzf7Tzcr/0szJ/s/I
+ xv7t5uL/3tfV/tvV0v738Oz/9+/r/vbu6v/27ej+8+nl/si/vP/x5uH+9e3p/uvr6v94m3b+MKgw/jGo
+ Mf8wqDD+O6M7/tzc3f+vr7D+oqKjfwAAAAAAAAAAvb2+f9jY2f+urrD/O6U7/zGqMf8xqjH/Pas8/6eo
+ pP/v7+7/7ebi/+Xd2f/Cvbr/wry5/8C6t/++uLT/vbaz/721sf+8tLD/sa2s//n6+f/38e3/9O3p/9rT
+ 0f/X0c7/1tDO/9PNyv/v6OT/3dfU/9vV0v/38Oz/9/Ds//fv6//27+v/9Ozn/8jBvv/y6OP/9u/r/+vr
+ 6v95nHb/Maox/zGqMf8xqjH/O6U7/93d3f+wsLH/o6OlfwAAAAAAAAAAvb2+f9jY2f6vr7H/O6c7/jCs
+ MP4xrDH/Pa08/qiopP7v7+7/7ebi/uzk4P/f2dX+3tfT/t3W0v7c1ND/29PO/tvRzP7Yzsn/s7Cv/vn6
+ +f738e3/9u/r/vbv6/738Oz/9u/r/vbv6/738Oz/3dfU/tvV0v738Oz/9u/r/vfw7P/38Oz+9O3p/sjC
+ v//z6ub+9/Ht/uvr6v95nXb+MKww/jGsMf8wrDD+O6c7/t3d3f+wsLL+pKSlfwAAAAAAAAAAvr6+f9nZ
+ 2f6wsLH/O6g7/jCuMP4xrjH/Pa49/qippf7v7+7/7ebi/u3m4v/s5eH+6+Tg/uvj3/7q4t7/6+Ld/urg
+ 2/7m29b/tbGw/vn6+f738e3/9e7q/uDa1/7e2NX/3tfV/tzV0v7x6ub/3dfU/tfRz/7r5eH/6uTg/urk
+ 4P/r5OD+6eLf/sjCv//z7Oj+9/Lv/uvr6v96nnf+MK4w/jGuMf8wrjD+O6g7/t3d3f+xsbP+pKSmfwAA
+ AAAAAAAAvr6+f9nZ2f+wsLH/O6o8/zGwMf8xsDH/PbA9/6mppf/v7+7/7ebi/+fg3P/Gwb//xcC+/8S/
+ vf/AvLn/49vX/9TNyv/Dvbr/s6+v//n6+f/38e3/8+zo/9HLyf/Pycf/zsjG/8rEwf/q5OD/4tzZ/8/J
+ x//OyMb/y8XC/8rEwv/LxML/ysTB/83Gw//17ur/+PPw/+vr6v96n3j/MbAx/zGwMf8xsDH/O6o8/93d
+ 3f+xsbP/paWmfwAAAAAAAAAAvr6+f9nZ2f6vr7H/Pq0+/kG3Qf49tj3/RrVG/qusqP7v7+7/7ebi/urj
+ 3//Uzsv+083K/tLNyv7Qy8j/6OHd/s/Kxv7MxsP/tbGx/vn6+f738e3/9u/r/vXu6v717ur/9O7q/vTt
+ 6v738Oz/9u/r/vTu6v707er/9O3p/vTt6f/07en+8uvn/vHr5//z7Oj+9PDt/urq6f9+onz+P7c//kK4
+ Qv9GuUb+P60//t3d3f+xsbL+pKSmfwAAAAAAAAAAvb2+f9jY2f6vr7D/P68//k6+Tv5Ovk7/Wb5Z/ra2
+ sv7x8fD/7+nm/u/p5f/v6OX+7+jl/u7o5P7u6OT/7ujk/tPOy/7Uz8z/u7e3/vr6+f738u7/9/Dt/vfw
+ 7f738O3/9/Dt/vfw7f738e3/9/Dt/vfx7f738e3/9/Ht/vfx7f/07uv+7Obj/ubg3f/l39z+5+Ph/uLi
+ 4f9+n3z+Tr5O/k6+Tv9Ovk7+QK9B/t3d3f+wsLL+o6OlfwAAAAAAAAAAvb2+f9jY2f+urq//QLFA/1LB
+ Uv9SwVL/XcFd/7i4tf/y8vH/8Orn/+3n5P/Y09H/19LQ/9bRz//U0M3/6+Xi/9fT0f/Z1NL/wr+///v7
+ +v/48/D/+PLv//jy7//48u//+PLv//jy7//48u//+PLv//jy7//48u//+PLv//jy7//x7On/0s3L/8bB
+ v//FwL7/yMXE/8rJyP+Bon//UsFS/1LBUv9SwVL/QbFB/9zc3f+vr7D/o6OkfwAAAAAAAAAAvLy9f9fX
+ 2P6tra7/QLJA/lfEV/5XxFf/YcRh/rq7t/7y8vH/8Ovn/uvm4//Szsz+0c3L/tHMy/7Oy8j/6eTh/tjU
+ 0f7Z1dP/xMHA/vv7+v749PD/+PLv/vjy7/748+//+PLv/vjy7/748+//+PLv/vjy7/748+//+PLv/vjy
+ 7//s5uP+s6+v/sjGx//FxMT+v729/qqmpv97sXn+V8RX/lfEV/9XxFf+QrNC/tzc3f+urq/+oaGjfwAA
+ AAAAAAAAu7u8f9bW1/6rq63/QLRB/lvHW/5bx1v/Zcdl/ry9uf7y8vH/8evo/vDr6P/w6uf+8Orn/vDq
+ 5/7w6uf/8Orn/tnV0/7a1tT/xsPC/vv7+v759PH/+PLv/vjy7/758/D/+PLv/vjy7/758/D/+PLv/vjy
+ 7/758/D/+PLv/vjy7//s5+T+vbq6/urq6v/g39/+vry8/oawhP9cx1z+W8db/lvHW/9bx1v+QrRC/tvb
+ 3P+srK7+oKChfwAAAAAAAAAAurq7f9bW1v+qqqv/QbVB/1/KX/9fyl//acpp/76/u//y8/H/8ezp/+/q
+ 5//j39z/497b/+Ld2//h3dr/7+nm/9rW1P/a1tT/x8XE//v7+v/59PH/+fPw//nz8P/58/D/+fPw//nz
+ 8P/58/D/+fPw//nz8P/58/D/+fPw//jz7//t6OX/vru7/+Hh4f/BwL//i7OJ/2HKYf9fyl//X8pf/1/K
+ X/9fyl//Q7ZD/9vb2/+qqqz/np6gfwAAAAAAAAAAubm6f9XV1f6oqKn/QbdB/mTNZP5kzWT/bc1t/sDB
+ vv7z8/L/8ezp/uzn5P/Szs3+0s7N/tHOzP7Oy8j/6eTh/t3Z1/7Rzsz/x8XE/vv7+v769/X/+vf0/vr3
+ 9P769/T/+vf0/vr39P769/T/+vf0/vr39P769/T/+vf0/vr39P/w7ev+vbu7/sXDw/+RtY/+Zsxm/mTN
+ ZP9kzWT+ZM1k/mTNZP9kzWT+Q7hE/tra2/+oqKr+nZ2efwAAAAAAAAAAt7e4f9TU1P+mpqf/QbhC/2nQ
+ af9p0Gn/ctBy/8LDwP/z8/L/8u3q//Hs6f/u6eb/7ejm/+3o5f/t6OX/8ezp//Dr6P/r5uT/ycbG//Hx
+ 8P/y8vH/8fHx//Hx8f/x8fH/8fHx//Hx8P/x8vH/8fHw//Hx8P/x8fD/8fHw//Hx8P/q6un/t7Sz/5q6
+ mP9qz2r/adBp/2nQaf9p0Gn/adBp/2nQaf9p0Gn/RLlF/9ra2v+np6j/m5ucfwAAAAAAAAAAtra3f9LS
+ 0/6kpKX/QrpC/m3Tbf5t023/dtJ2/sTGwv7z9PP/8u3q/vLt6v/x7er+8u3q/vLt6v7y7er/8e3q/vHt
+ 6v7w7On/0s7N/s3Kyf7Oysn/zMnH/snGxf7HxMP/x8PC/sfExP7FwsL/rLWp/qbCo/6mw6T/psOk/qXB
+ o/+jwKH+mcSX/nHScf9t023+bdNt/m3Tbf9t023+bdNt/m3Tbf9t023+RbtF/tnZ2f+kpKb+mZmafwAA
+ AAAAAAAAtbW1f9HR0v6ioqP/Q7tD/nPVc/5z1XP/e9V7/sfIxf709PT/8+7r/vPu6//z7uv+8+7r/vPu
+ 6/7z7uv/8+7r/vPu6/7z7uv/8+7r/vPu6/7z7ev/7ejm/tnV0/7RzMr/0MvK/tTR0P7R0ND/kLWP/nPV
+ c/5z1XP/c9Vz/nPVc/9z1XP+c9Vz/nPVc/9z1XP+c9Vz/nPVc/9z1XP+c9Vz/nPVc/9z1XP+RrxG/tjY
+ 2P+ioqP+l5eYfwAAAAAAAAAAs7O0f9DQ0f+goKH/Q7xD/3fYd/932Hf/gNd//8nKxv/09fT/8+7s//Pu
+ 7P/z7uv/8+7s//Pu7P/z7uz/8+7r//Pu6//z7uz/8+7r//Pu6//z7uv/5eHf/7u5uf/GxMT/xMLC/8G/
+ v/+1srL/ksKR/3fYd/932Hf/d9h3/3fYd/932Hf/d9h3/3fYd/932Hf/d9h3/3fYd/932Hf/d9h3/3fY
+ d/932Hf/R71H/9fX2P+goKH/lJSWfwAAAAAAAAAAsrKyf8/P0P6dnZ7/Q75D/nzafP582nz/hNqE/svM
+ yf709fT/8+/s/vPv7P/z7uz+8+/s/vPv7P7z7+z/8+7s/vPu7P7z7+z/8+7s/vPu7P7z7uz/5eHf/sfG
+ xv7o6Oj/4eHh/sjHxv6ewJ3/fdl9/nzafP582nz/fNp8/nzafP982nz+fNp8/nzafP982nz+fNp8/nza
+ fP982nz+fNp8/nzafP982nz+SL9I/tbW1/+dnZ7+kpKTfwAAAAAAAAAAsLCxf87Oz/6bm5z/RL9E/oDd
+ gP6B3YH/iNyI/s3Oy/719fT/9PDt/vTv7f/z7+z+9O/t/vTv7f707+3/8+/s/vPv7P707+3/8+/s/vPv
+ 7P7z7+3/5+Lg/snHx/7i4uL/y8rK/qTCov6C3IL/gN2A/oDdgP6B3YH/gN2A/oHdgf+A3YD+gN2A/oHd
+ gf+A3YD+gN2A/oHdgf+A3YD+gN2A/oHdgf+A3YD+ScFJ/tXV1f+bm5z+kJCRfwAAAAAAAAAArKytfdHR
+ 0f+ZmZr/RL9E/4TfhP+F34X/jN6M/8/Qzf/19vX/9fLv//Xx7//18e//9fHv//Xx7//18e//9fHv//Xx
+ 7//18e//9fHv//Xx7//08e//6ebl/8jGxv/Ozc3/qcOn/4fdh/+F34X/hd+F/4Xfhf+F34X/hd+F/4Xf
+ hf+F34X/hd+F/4Xfhf+F34X/hd+F/4Xfhf+F34X/hd+F/4Xfhf+F34X/SMBI/9PT1P+ampz/jY2OfQAA
+ AAAAAAAAnp6fatvb2/6YmJn/RbVG/oXghf6J4Yn/keCQ/tDRzv7z9PP/8/Pz/vP08//z8/P+8/Tz/vPz
+ 8/7z8/P/8/Pz/vPz8/7z8/P/8/Pz/vPz8/7z8/P/6urq/sLAwP6vx63/i9+L/onhif6J4Yn/ieGJ/onh
+ if6J4Yn/ieGJ/onhif+J4Yn+ieGJ/onhif+J4Yn+ieGJ/onhif+J4Yn+ieGJ/onhif+F4IX+R7ZH/tLS
+ 0v+cnJ3+hYWGagAAAAAAAAAAm5ubO9vb2/6cnJz/XKVc/nDbcP6O447/kuKS/r7PvP7Cz8D/ws/A/sLP
+ wP/Cz8D+ws/A/sLOv/7Bzr//wc6//sHNv/7Bzb//wM2+/sDNvv6/zL3/vcq7/rPOsf6R4pH/juOO/o7j
+ jv6O447/juOO/o7jjv6O447/juOO/o7jjv+O447+juOO/o7jjv+O447+juOO/o7jjv+O447+juOO/o7j
+ jv9s2mz+Yaph/sbGxv+enp/+hISFOwAAAAAAAAAAoKCgB7GxsuS3t7f/iJSJ/0XGRf+K44r/kuSS/5Lk
+ kv+T5JP/k+ST/5Pkk/+T5JP/k+ST/5Pkk/+T5JP/k+ST/5Pkk/+T5JP/k+ST/5Pkk/+T5JP/k+ST/5Lk
+ kv+S5JL/kuSS/5Lkkv+S5JL/kuSS/5Lkkv+S5JL/kuSS/5Lkkv+S5JL/kuSS/5Lkkv+S5JL/kuSS/5Lk
+ kv+S5JL/kuSS/4Xhhf9AxUD/qLSo/6Cgof+UlJXkioqKBwAAAAAAAAAAAAAAAI+PkHTg4OD/kpKS/naV
+ dv5Fx0b/dd51/pHkkf6V5pX/luaW/pbmlv+W5pb+luaW/pbmlv6W5pb/luaW/pbmlv6W5pb/luaW/pbm
+ lv6W5pb/luaW/pbmlv6W5pb/luaW/pbmlv6W5pb/luaW/pbmlv6W5pb/luaW/pbmlv+W5pb+luaW/pbm
+ lv+W5pb+luaW/pXmlf+P5I/+cN1w/kDGQP+EpIX+pqan/qenqP9/f4B0AAAAAAAAAAAAAAAAAAAAAKCg
+ oAaenp/G1tbX/pCQkf6GkYf/WqNb/kS2Rf5Fw0X/RcRF/kXERf9FxEX+RcRF/kXERf5FxEX/RcRF/kXE
+ Rf5FxEX/RcRF/kXERf5FxEX/RcRF/kXERf5FxEX/RcRF/kXERf5FxEX/RcRF/kXERf5FxEX/RcRF/kXE
+ Rf9FxEX+RcRF/kXERf9FxEX+RcRF/kXDRf9EtkT+XKRd/pijmf+enp/+p6eo/o+Pj8aKiosGAAAAAAAA
+ AAAAAAAAAAAAAAAAAACampoVnZ2dxd/f3/+zs7T/lJSV/4+PkP+Ojo//jo6P/46Oj/+Ojo//jo6P/46O
+ j/+Ojo//jo6P/46Oj/+Ojo//jo6P/46Oj/+Ojo//jo6P/46Oj/+Ojo//jo6P/46Oj/+Ojo//jo6P/46O
+ j/+Ojo//jo6P/46Oj/+Ojo//jo6P/46Oj/+Ojo//jo6P/4+PkP+UlJX/mJiZ/6Ojo//Dw8T/k5OUxYmJ
+ ihUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAn5+fBoyMjHSurq7k19fY/tjY2P7MzMz/x8fH/sbG
+ x//Gxsf+xsbH/sbGx/7Gxsf/xsbH/sbGx/7Gxsf/xsbH/sbGx/7Gxsf/xsbH/sbGx/7Gxsf/xsbH/sbG
+ x/7Gxsf/xsbH/sbGx/7Gxsf/xsbH/sbGx//Gxsf+xsbH/sbGx//Gxsf+xsbH/sjIyP/Pz9D+0NDQ/qys
+ rOOHh4d0lZWVBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgoKAGl5eXOpaW
+ l2ihoaJ8pKSkf6SkpH+kpKR/pKSkf6SkpH+kpKR/pKSkf6SkpH+kpKR/pKSkf6SkpH+kpKR/pKSkf6Sk
+ pH+kpKR/pKSkf6SkpH+kpKR/pKSkf6SkpH+kpKR/pKSkf6SkpH+kpKR/pKSkf6SkpH+kpKR/pKSkf6Gh
+ oXyVlZZolpaWOp6engYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////8AAPwA
+ AAAAPwAA8AAAAAAPAADgAAAAAAcAAMAAAAAAAwAAwAAAAAADAACAAAAAAAEAAIAAAAAAAQAAgAAAAAAB
+ AACAAAAAAAEAAIAAAAAAAQAAgAAAAAABAACAAAAAAAEAAIAAAAAAAQAAgAAAAAABAACAAAAAAAEAAIAA
+ AAAAAQAAgAAAAAABAACAAAAAAAEAAIAAAAAAAQAAgAAAAAABAACAAAAAAAEAAIAAAAAAAQAAgAAAAAAB
+ AACAAAAAAAEAAIAAAAAAAQAAgAAAAAABAACAAAAAAAEAAIAAAAAAAQAAgAAAAAABAACAAAAAAAEAAIAA
+ AAAAAQAAgAAAAAABAACAAAAAAAEAAIAAAAAAAQAAgAAAAAABAACAAAAAAAEAAIAAAAAAAQAAgAAAAAAB
+ AACAAAAAAAEAAIAAAAAAAQAAgAAAAAABAADAAAAAAAMAAMAAAAAAAwAA4AAAAAAHAADwAAAAAA8AAPwA
+ AAAAPwAA////////AAAoAAAAIAAAAEAAAAABACAAAAAAAIAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAB9fX02ioqKqoaGh+mHh4f9hoaH/4aGh/+Ghof/hoaH/4aGh/+Ghof/hoaH/4aG
+ h/+Ghof/hoaH/4aGh/+Ghof/hoaH/4aGh/+Ghof/hoaH/4aGh/+Ghof/hoaG/YODg+mCgoOqd3d4NgAA
+ AAAAAAAAAAAAAAAAAAAAAAAAjIyNap2dnvytra7/prKm/561nv+ftp//n7ef/5+3n/+ft5//n7ef/5+3
+ n/+ft5//n7ef/5+3n/+ft5//n7ef/5+3n/+ft5//n7ef/5+3n/+ft5//n7ef/5+3n/+ft6D/r7uw/8HB
+ wf+VlZX8e3t8agAAAAAAAAAAAAAAAI+Pjzavr6/8maKa/0SLRP8wjzD/MI8w/zCPMP8wjzD/MI8w/zCP
+ MP8wjzD/MI8w/zCPMP8wjzD/MI8w/zCPMP8wjzD/MI8w/zCPMP8wjzD/MI8w/zCPMP8wjzD/MI8w/zCP
+ MP8wjzD/RYxG/7rDuv+Xl5j8fHx9NgAAAAAAAAAAr6+vq6enqP9EjET/MJEw/zCRMP8wkTD/MJEw/zCR
+ MP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCRMP8wkTD/MJEw/zCR
+ MP8wkTD/MJEw/zCRMP8wkTD/Ro5G/8XFxf+JiYqrAAAAAAAAAAC5ubnph5SH/zCTMP8wkzD/MJMw/zCT
+ MP8wkzD/MJMw/zCTMP8wkzD/MJMw/0aWRf99m3v/f559/3+dfP9+nHz/fpx7/32be/98mnr/fJp6/3ya
+ ef97mXn/e5l5/3qYeP95l3f/TJJL/zCTMP8wkzD/sr+y/42NjukAAAAAAAAAALu7vP57lHz/MJUw/zCV
+ MP8wlTD/MJUw/zCVMP8wlTD/MJUw/zCVMP8wlTD/VZlU/+Pi4f/49fP/9/Tx//fz8P/38u//9/Lv//bx
+ 7v/28O3/9fDt//bw7f/28O3/9vDt/+7u7P9dk1z/MJUw/zCVMP+jvKT/k5OU/gAAAAAAAAAAvb2+/32X
+ fv8wlzD/MJcw/zCXMP8wlzD/MJcw/zCXMP8wlzD/MJcw/zCXMP9Wm1T/4+Ph//Tp5P/y5d//8ePc//Dg
+ 2f/v3tb/7tvT/+3Z0f/s2M//7NfO/+zXzv/s187/7evp/16UXP8wlzD/MJcw/6S+pP+Xl5j/AAAAAAAA
+ AAC/v8D/gJqB/zCaMP8wmjD/MJow/zCaMP8wmjD/MJow/zCaMP8wmjD/MJow/1adVf/k4+L/9e3o//Tp
+ 5P/y5+H/8eTe//Di2//v39j/7t3V/+3a0v/s2ND/7NfO/+zXzv/t6+n/XpZc/zCaMP8wmjD/pb+l/5qa
+ m/8AAAAAAAAAAMHBwv+CnYP/MJww/zCcMP8wnTD/MZ0x/zGdMf8xnTH/MZ0x/zGdMf8xnTH/V59W/+Tj
+ 4//38Oz/29TQ/8/HxP/NxMH/y8K+/8rAvP/Jvrr/yLy4/8a7tv/HurX/7NjQ/+7r6v9emF3/MJww/zCc
+ MP+mwab/np6f/wAAAAAAAAAAw8PE/4Wghv8wnzD/MJ8w/3Obcf+osKX/p6+l/6avpP+mrqP/pa6j/6Wt
+ ov+jp5//5OTj//fw7f/07On/8enl//Dn4//v5eD/7uPd/+3g2//r3tj/6tvV/+rZ0v/u29T/7uzq/1+Z
+ Xf8wnzD/MJ8w/6fDqP+hoaL/AAAAAAAAAADFxcb/h6OI/zGiMf8xojH/hqWE/+7s6v/s5eL/6+Tg/+rj
+ 3//q4t3/6eDc/9HKxv/k5OP/9/Dt/+Hb2P/X0c//1M7L/+7m4v/Xz8z/1MvH/9HIxP/RxsL/0MXA/+7e
+ 1//u7Ov/YJte/zGiMf8xojH/qMSp/6Skpf8AAAAAAAAAAMfHx/+Jpor/MaQx/zGkMf+Gp4T/7ero/+ne
+ 2f/o29b/59nT/+bX0P/l1M3/zsG8/+Xk4//38O3/7ujk/+nj3//o4t7/8uvn/9XPy//x6OT/8Obh/+/k
+ 3//SyMT/7+Lb/+7t6/9gnV7/MaQx/zGkMf+pxqn/pqao/wAAAAAAAAAAyMjJ/4qoi/8xpzH/Macx/4eo
+ hf/u6+n/6+Ld/+Ta1f/j19P/4dXQ/+DSzf/Mwbz/5eXk//fw7f/n4N3/39jV/93W0//v6OX/19DO//fv
+ 6//27un/9ezn/9XMyP/x5uD/7+7s/2CfX/8xpzH/Macx/6rHqv+oqKr/AAAAAAAAAADJycr/i6qM/zGq
+ Mf8xqjH/iKqG/+7s6v/o4d3/x8K//8bAvf/DvLn/wru3/7ixrv/l5eT/9/Dt/+ni3//i29j/4NnW//Dp
+ 5f/X0M7/9/Ds//fv6//27+v/1s7L//Pq5f/v7u3/YaFf/zGqMf8xqjH/qsmr/6qqq/8AAAAAAAAAAMrK
+ yv+Mq43/Ma0x/zGtMf+Iq4b/7uzq/+3m4v/s5eH/6+Pf/+ri3f/q4Nv/0snG/+Xl5P/38O3/7OXi/+bg
+ 3f/l3tv/8erm/9XPzP/v6OT/7ujk/+/o5P/Uzcr/9O3o/+/v7f9ho1//Ma0x/zGtMf+ryqv/q6ut/wAA
+ AAAAAAAAysrK/4ysjf8ysTL/MbAx/4msh//u7Or/6eLe/8XAvv/Ev73/yMPA/9vU0P+7trT/5uXk//fw
+ 7f/j3dr/29XS/9jSz//w6eX/3NbT/9nT0P/Y0c7/2NHO/9jSz//27+v/8O/t/2KlYP8zsTP/NbI1/6vL
+ q/+rq63/AAAAAAAAAADJycr/jKyN/0a7Rv9MvUz/l7eV//Du7P/u6OT/6+Xh/+vk4f/r5eH/29XS/8jC
+ wP/n5uX/9/Ht//fw7P/38Oz/9/Ds//fw7f/38Oz/9/Dt//fw7f/z7en/6uTh/+nj4P/n5uX/b6pt/029
+ Tf9Hu0f/q8ur/6qqrP8AAAAAAAAAAMjIyf+LrIz/S79L/1PCU/+evJv/8e/u/+3n5P/Uz83/087N/9bS
+ z//g2tj/z8vJ/+rq6f/48/D/+PLv//jy7//48u//+PLv//jy7//48u//+PLv/+Pe2/++urn/vLi3/7+8
+ vP90r3L/U8JT/0y/TP+qy6v/qamq/wAAAAAAAAAAx8fI/4mriv9Qw1D/Wsda/6LAoP/x8O7/8Orn/+ji
+ 4P/n4t//6eTh/+Hc2f/Rzcv/6+vq//nz8P/48/D/+PPw//jz8P/58/D/+PPw//jz8P/48u//2NPR/93d
+ 3f/a2tr/oLKe/1/DX/9ax1r/UcNR/6nLqv+np6j/AAAAAAAAAADFxcb/iKqI/1XHVf9hy2H/psOk//Lw
+ 7//v6eb/3dnW/9zY1v/f29j/4t3b/8/Lyv/s7Ov/+fTx//nz8P/58/D/+fPw//nz8P/58/D/+fPw//nz
+ 8P/a1tT/1dTU/6m4p/9nx2b/Ycth/2HLYf9WyFb/qcup/6Skpv8AAAAAAAAAAMTExf+FqYb/Wsta/2jP
+ aP+qx6j/8/Hw//Dr6P/l4N7/5ODd/+bi3//t6OX/2NTS/+jn5v/19PP/9PTz//T08//09PP/9PTz//T0
+ 8//09PL/9PTy/9vZ2f+suan/b8tu/2jPaP9oz2j/aM9o/1zMXP+oy6j/oqKj/wAAAAAAAAAAwsLC/4On
+ hP9gz2D/b9Nv/67Krf/z8vD/8u3q//Lt6v/y7ev/8u3q//Lt6v/s5+X/2tbU/9rV1P/Tz87/zcnI/87L
+ yv/DwcH/k8OS/5XJk/+UyJL/kseR/3jReP9v02//b9Nv/2/Tb/9v02//Ys9i/6fKp/+enp//AAAAAAAA
+ AADAwMD/gaWC/2XSZf9213b/ss2x//Tz8f/z7uv/8+7r//Pu6//z7uv/8+7r//Pu6//z7uv/8u3q/8zJ
+ yP/Gw8P/xMLC/7W3s/9403j/dtd2/3bXdv9213b/dtd2/3bXdv9213b/dtd2/3bXdv9o02j/psqm/5ub
+ nP8AAAAAAAAAAL6+vv9+o3//a9Zr/33bff+30bX/9PPy//Pv7P/z7+z/8+/s//Pv7P/z7+z/8+/s//Pv
+ 7P/y7uv/zszL/+Xl5f/Iycb/js6N/33bff99233/fdt9/33bff99233/fdt9/33bff99233/fdt9/27X
+ bv+lyqX/l5eY/wAAAAAAAAAAvb29/nyhff9v2W//hN6E/7rUuf/19PP/9PHu//Tx7v/08e7/9PHu//Tx
+ 7v/08e7/9PHu//Pw7v/Qzs3/zc3L/5XRlP+E3oT/hN6E/4TehP+E3oT/hN6E/4TehP+E3oT/hN6E/4Te
+ hP+E3oT/ctpy/6PIo/+UlJX+AAAAAAAAAAC+vr/phJiF/2nZaf+K4Yr/u9S6/+bl5f/m5eX/5uXl/+bl
+ 5f/l5eX/5eXk/+Xl5P/l5OT/5eTk/8jIx/+d1J3/iuGK/4rhiv+K4Yr/iuGK/4rhiv+K4Yr/iuGK/4rh
+ iv+K4Yr/iuGK/4rhiv9o2Wj/qr6r/5GRkekAAAAAAAAAALOzs6unp6f/VrtX/43jjf+a4Zr/oN+f/6Df
+ n/+g35//n9+f/5/fn/+f35//n9+e/5/fnv+e3p7/m+Ca/5Hkkf+R5JH/keSR/5Hkkf+R5JH/keSR/5Hk
+ kf+R5JH/keSR/5Hkkf+R5JH/i+OL/1W9Vf+ysrL/kpKSqwAAAAAAAAAAlpaXNsbGx/yEkoT/V7tX/2/d
+ b/994H3/feB9/33gff994H3/feB9/33gff994H3/feB9/33gff994H3/feB9/33gff994H3/feB9/33g
+ ff994H3/feB9/33gff994H3/feB9/27dbv9UvFX/mqia/5+foPyFhYU2AAAAAAAAAAAAAAAAnJydacXF
+ xvyjo6P/fZB+/3SadP9zmnT/c5p0/3OadP9zmnT/c5p0/3OadP9zmnT/c5p0/3OadP9zmnT/c5p0/3Oa
+ dP9zmnT/c5p0/3OadP9zmnT/c5p0/3OadP90mnT/gZSC/6Ojo/+tra78jY2OaQAAAAAAAAAAAAAAAAAA
+ AAAAAAAAlZWVNq+vr6q5ubnotbW1/bOztP+zs7T/s7O0/7OztP+zs7T/s7O0/7OztP+zs7T/s7O0/7Oz
+ tP+zs7T/s7O0/7OztP+zs7T/s7O0/7OztP+zs7T/s7O0/7OztP2zs7PorKysqpCQkTYAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAP/////gAAAHwAAAA4AAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAA
+ AAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAA
+ AAGAAAABwAAAA+AAAAf/////KAAAABgAAAAwAAAAAQAgAAAAAABgCQAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAGNjYxBsbGw5cHBxP3FxcT9xcXE/cXFxP3FxcT9xcXE/cXFxP3FxcT9xcXE/cXFxP3Fx
+ cT9xcXE/cXFxP3BwcT9ra2w5Y2NjEAAAAAAAAAAAAAAAAAAAAABubm8Fi4uMj5+foPivr7D/rq6u/q6u
+ rv+urq7/rq6u/q6urv+urq7/rq6u/66urv6urq7/rq6u/q6urv+urq7/rq6u/q6urv+xsbH/paWm+H9/
+ gI9ra2wFAAAAAAAAAACdnZ6Qm6Cc/luVW/41izX+Mowy/jKMMv4yjDL+Mowy/jKMMv4yjDL+Mowy/jKM
+ Mv4yjDL+Mowy/jKMMv4yjDL+Mowy/jKMMv41izX+X5lf/rG2sf6CgoOQAAAAAHh4eBCysrP4VpJW/jCR
+ MP8wkTD/L5Ev/jCRMP8wkTD/L5Ev/jGSMf80kzT/NJM0/zSTNP40kzT/NJI0/jSTNP80kjT/NJI0/jSS
+ NP8zkjP/L5Ev/l+bX/+rq6z4dnZ3EImJiTm1tbb/NpA2/jCUMP8wlDD/L5Qv/jCUMP8wlDD/L5Qv/meb
+ Zf/Mzcr/y8zJ/8vMyP7Ky8f/ycrH/snKxv/Iysb/yMnF/sjJxf+XqJX/L5Qv/jaRNv+4uLn/g4OEOZWV
+ lj+1tbb+M5Qz/i+XL/4vly/+L5cv/i+XL/4vly/+L5cv/m6hbP738u/+8+fh/vHj3f7w4Nn+793W/u3b
+ 0/7t2dH+7dnQ/u/e1/6vvq7+L5cv/jOUM/65ubn+jY2OP5iYmT+4uLn/NJg0/jCaMP8wmjD/L5ov/jCa
+ MP8wmjD/L5ov/m+jbf/49PH/8efi/+vg2/7q3Nf/6NnT/ubWz//l08z/5dLK/u7d1f+wv67/L5ov/jSY
+ NP+8vL3/kZGTP5ubnD+8vLz/NJs0/jKeMv9bmVn/XJlb/lyYWv9bmFn/W5dZ/oShgf/49fP/6eLe/9zV
+ 0f7a0c3/2c7K/tfMx//VycT/1cfB/u/e1/+wwK7/MJ4w/jSbNP+/v8D/lpaXP56enz++vr/+NZ81/jai
+ Nv7Iycb+6ubj/urk4v7p4+D+6OLe/svGxP749fP+6uTg/t/Y1f7l3dr+49vW/tvRzf7Zzsn+2MvG/vDi
+ 3P6xwa/+MKEw/jWfNf7CwsP+mpqbP6CgoT/BwcL/NaM1/jemNv/Ky8j/6t/a/ujc1v/n2NL/5dXO/srA
+ u//49fP/8uvn/+3m4v7w6eb/29XS/vLq5f/x5+L/2tDL/vHm4f+xwrD/MKUw/jWjNv/ExMX/nZ2eP6Ki
+ oz/Dw8T/NqY2/jepNv/LzMn/6uLe/tHKxv/Px8P/zcO//r63tP/49fP/5t/c/9XOzP7f2db/3NbT/vfv
+ 6//27ur/3dXR/vPr5v+yw7D/MKkw/jamNv/Gxsf/n5+hP6Ojoz/ExMX/Nqo2/jetNv/LzMn/7Obi/uXe
+ 2v/k3Nj/49nV/snCwP/49fP/8erm/+rk4P7v6OT/29XS/vHq5v/x6ub/29XR/vXu6/+yxLD/MK0w/jaq
+ Nv/Hx8j/oaGiP6OjpD/ExMX+O687/jyzPP7Mzcr+6uTg/s3Hxf7KxcL+29XR/r65t/749fP+7OXi/uLb
+ 2P7o4d7+5+Dd/uDa1/7f2dX+3tjV/vXv7P6zxbL+ObM5/jywPP7Hx8j+oaGiP6Kioz/Dw8T/SLhI/lbA
+ Vv/U1NL/7+nm/uPd2v/i3Nn/4dvY/svGxf/59vT/9/Hu//fx7v748e7/9/Hu/vfx7v/17+z/2tXT/tbS
+ 0P+ru6n/UMBQ/km4Sf/Gxsf/oKChP6CgoT/BwcL+TbxN/l7GXv7W19X+7+rm/uHc2v7g29j+497b/s/M
+ yv769/X++PLv/vjy7/748+/++PLv/vjy7/7y7On+yMbH/snHx/6CtID+WcZZ/k29Tv7ExMX+nZ2fP56e
+ nz+/v8D/UcFR/mbMZv/Z2df/7+rn/trW1P/Z1dL/5N/d/s7Lyv/6+Pb/+fXy//n18v759fL/+fXy/vn1
+ 8v/08O3/yMfG/pG9j/9izGL/Ysxi/lLBUv/CwsP/mpqcP5ycnT+8vL3/VsVW/nDRb//b3Nr/8u3q/u/r
+ 6P/v6uj/8ezp/t7a2P/f3t3/3tzb/9za2v7c2tr/zdbL/svayv/J18f/l8GV/mzRbP9r0Wv/a9Fr/ljG
+ WP+/v8D/l5eYP5mZmj+5ubr+XMlc/nnWef7e393+8+7r/vPu6/7z7uv+8+7r/vPu6/7z7uv+2tbU/srH
+ x/7HxcT+g8mC/nXWdf511nX+ddZ1/nXWdf511nX+ddZ1/l7JXv68vL3+kpKTP5aWlj+1tbb/Yc1h/oLb
+ gv/g4d//8+/s/vPv7P/z7+z/8+/s/vPv7P/z7+z/19TT/97d3f6jyaL/f9t//n7cfv9+3H7/ftx+/n7c
+ fv9+3H7/ftx+/mPOY/+5ubr/jo6PP4uLizm3t7j/Zc1l/ovfi//i4uH/9PLx/vTy8f/08vH/9PLx/vTy
+ 8f/08vH/19bV/6zOq/6I34j/h+CH/ofgh/+H4If/h+CH/ofgh/+H4If/h+CH/mbNZv+3t7j/hYWGOXx8
+ fBC4uLj4ZrZn/o/jj/6p2qj+qtqp/qraqf6q2an+qtmp/qrZqf6p2Kj+pdik/pDjkP6Q45D+kOOQ/pDj
+ kP6Q45D+kOOQ/pDjkP6Q45D+jOOM/m2/bf6mpqf4e3t8EAAAAACrq6yQm6Oc/me2Z/9s0Wz/bdVt/m3V
+ bf9t1W3/bdVt/m3Vbf9t1W3/bdVt/23Vbf5t1W3/bdVt/m3Vbf9t1W3/bdVt/m3Vbf9r0Wv/abpp/pyk
+ nf+QkJGQAAAAAAAAAACAgIAFqqqqj7OztPiwsLH/qqqr/qqqq/+qqqv/qqqr/qqqq/+qqqv/qqqr/6qq
+ q/6qqqv/qqqr/qqqq/+qqqv/qqqr/qqqq/+vr6//rq6u+J2dnY99fX4FAAAAAAAAAAAAAAAAAAAAAIKC
+ gxCRkZI5m5ucP5ycnD+cnJw/nJycP5ycnD+cnJw/nJycP5ycnD+cnJw/nJycP5ycnD+cnJw/nJycP5ub
+ nD+SkpI5hISEEAAAAAAAAAAAAAAAAOAABwCAAAEAgAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAQCAAAEA4AAHACgA
+ AAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS0tMDXR0dGR5eXp/eXl6f3l5
+ en95eXp/eXl6f3l5en95eXp/eXl6f3l5en95eXl/cXFyZExMTA0AAAAAU1NUDZyendhynnL/Z6Nn/2ej
+ Z/9no2f/Z6Nn/2ejZ/9no2f/Z6Nn/2ejZ/9no2f/Z6Nn/3mmev+YmpnYU1NTDZWVlWVolmn/MJIw/zCS
+ MP8wkjD/MJIw/0mVSP9Xl1b/V5dW/1aWVf9WlVT/VZVU/1WUU/83kjb/e6l7/4KCg2Wmpqd/VpZW/zCW
+ MP8wljD/MJYw/zCWMP+cvpv/9e7q//Tq5f/y5+L/8eTf//Hj3f/v6OT/R5VG/2mqav+QkJF/rKysf1ib
+ Wf8wmzD/MJsw/zCbMP8wmzD/ncGc/+/m4v/g1tH/3dDL/9vMxv/ZycP/7eHc/0eZRv9qrmv/l5eZf6+v
+ sH9boVz/VqBV/8rMxf/IycL/x8e//8/Oy//x6ub/49zY/+jf2//f1M//3dDK/+7k4P9InUf/bLJs/56e
+ n3+zs7N/XaZd/1ynW//s5eL/5dnU/+PVzv/Z09D/8erm/+Pd2f/j3dn/8+vn/+PZ1f/v6OX/SKJH/222
+ bf+jo6R/tLS1f16rX/9cq1v/7Ojl/9nSz//Wzsr/1dHP//Hq5v/j3dn/493Z//Ps6P/k3dn/8e3q/0mn
+ SP9tum7/pqanf7W1tX9ksWX/Z7Rm/+3p5v/Y0s//2tTR/9TRz//y7Oj/6OLe/+7o5P/o4d7/493a/+3q
+ 5/9Ur1P/dMF1/6amqH+zs7R/bLZs/3vBev/w7Or/3tjW/+Db2P/d29r/+PPw//jy7//48u//+PLv/9bS
+ 0P+9wLv/YL9g/3zGfP+jo6V/sLCxf2+5b/+GyYX/8e7r/+Hc2v/l4N7/393b//f08v/29PH/9vTx//bz
+ 8f/Nz8r/ecZ5/2TNZP+ByoH/np6gf6ysrX9yu3P/kdCR//Pw7v/y7ev/8u3r/+vm5P/a1tX/ycbG/6HD
+ n/+F0IT/ftF9/3LVcv9y1XL/hc6G/5iYmX+oqKh/db11/5zXnP/08vD/9PDt//Tw7f/08O3/4d7c/8TT
+ w/+F2YT/gN2A/4DdgP+A3YD/gN2A/4rQiv+RkZJ/mZmZZXq1e/+b3pv/w+LC/8Piwv/C4sL/wuLB/7na
+ uf+S35L/juOO/47jjv+O447/juOO/4zijP+GwYf/h4eIZVtbXA2rrqvYerN6/3i9eP94vXj/eL14/3i9
+ eP94vXj/eL14/3i9eP94vXj/eL14/3i9eP95tHr/naGe2FxcXA0AAAAAXl5eDZycnWSpqap/qqqqf6qq
+ qn+qqqp/qqqqf6qqqn+qqqp/qqqqf6qqqn+pqal/m5ubZGBgYA0AAAAAgAEAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAEAAA==
+
+
+
\ No newline at end of file
diff --git a/Duplicati/Scheduler/Monitor.SQL/SQLHistoryDataSet.Designer.cs b/Duplicati/Scheduler/Monitor.SQL/SQLHistoryDataSet.Designer.cs
new file mode 100644
index 000000000..1c4850bc6
--- /dev/null
+++ b/Duplicati/Scheduler/Monitor.SQL/SQLHistoryDataSet.Designer.cs
@@ -0,0 +1,1561 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.4961
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+#pragma warning disable 1591
+
+namespace Duplicati.Scheduler.Monitor.SQL {
+
+
+ ///
+ ///Represents a strongly typed in-memory cache of data.
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "2.0.0.0")]
+ [global::System.Serializable()]
+ [global::System.ComponentModel.DesignerCategoryAttribute("code")]
+ [global::System.ComponentModel.ToolboxItem(true)]
+ [global::System.Xml.Serialization.XmlSchemaProviderAttribute("GetTypedDataSetSchema")]
+ [global::System.Xml.Serialization.XmlRootAttribute("SQLHistoryDataSet")]
+ [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.DataSet")]
+ public partial class SQLHistoryDataSet : global::System.Data.DataSet {
+
+ private HistoryDataTable tableHistory;
+
+ private global::System.Data.SchemaSerializationMode _schemaSerializationMode = global::System.Data.SchemaSerializationMode.IncludeSchema;
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public SQLHistoryDataSet() {
+ this.BeginInit();
+ this.InitClass();
+ global::System.ComponentModel.CollectionChangeEventHandler schemaChangedHandler = new global::System.ComponentModel.CollectionChangeEventHandler(this.SchemaChanged);
+ base.Tables.CollectionChanged += schemaChangedHandler;
+ base.Relations.CollectionChanged += schemaChangedHandler;
+ this.EndInit();
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected SQLHistoryDataSet(global::System.Runtime.Serialization.SerializationInfo info, global::System.Runtime.Serialization.StreamingContext context) :
+ base(info, context, false) {
+ if ((this.IsBinarySerialized(info, context) == true)) {
+ this.InitVars(false);
+ global::System.ComponentModel.CollectionChangeEventHandler schemaChangedHandler1 = new global::System.ComponentModel.CollectionChangeEventHandler(this.SchemaChanged);
+ this.Tables.CollectionChanged += schemaChangedHandler1;
+ this.Relations.CollectionChanged += schemaChangedHandler1;
+ return;
+ }
+ string strSchema = ((string)(info.GetValue("XmlSchema", typeof(string))));
+ if ((this.DetermineSchemaSerializationMode(info, context) == global::System.Data.SchemaSerializationMode.IncludeSchema)) {
+ global::System.Data.DataSet ds = new global::System.Data.DataSet();
+ ds.ReadXmlSchema(new global::System.Xml.XmlTextReader(new global::System.IO.StringReader(strSchema)));
+ if ((ds.Tables["History"] != null)) {
+ base.Tables.Add(new HistoryDataTable(ds.Tables["History"]));
+ }
+ this.DataSetName = ds.DataSetName;
+ this.Prefix = ds.Prefix;
+ this.Namespace = ds.Namespace;
+ this.Locale = ds.Locale;
+ this.CaseSensitive = ds.CaseSensitive;
+ this.EnforceConstraints = ds.EnforceConstraints;
+ this.Merge(ds, false, global::System.Data.MissingSchemaAction.Add);
+ this.InitVars();
+ }
+ else {
+ this.ReadXmlSchema(new global::System.Xml.XmlTextReader(new global::System.IO.StringReader(strSchema)));
+ }
+ this.GetSerializationData(info, context);
+ global::System.ComponentModel.CollectionChangeEventHandler schemaChangedHandler = new global::System.ComponentModel.CollectionChangeEventHandler(this.SchemaChanged);
+ base.Tables.CollectionChanged += schemaChangedHandler;
+ this.Relations.CollectionChanged += schemaChangedHandler;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.Browsable(false)]
+ [global::System.ComponentModel.DesignerSerializationVisibility(global::System.ComponentModel.DesignerSerializationVisibility.Content)]
+ public HistoryDataTable History {
+ get {
+ return this.tableHistory;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.BrowsableAttribute(true)]
+ [global::System.ComponentModel.DesignerSerializationVisibilityAttribute(global::System.ComponentModel.DesignerSerializationVisibility.Visible)]
+ public override global::System.Data.SchemaSerializationMode SchemaSerializationMode {
+ get {
+ return this._schemaSerializationMode;
+ }
+ set {
+ this._schemaSerializationMode = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.DesignerSerializationVisibilityAttribute(global::System.ComponentModel.DesignerSerializationVisibility.Hidden)]
+ public new global::System.Data.DataTableCollection Tables {
+ get {
+ return base.Tables;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.DesignerSerializationVisibilityAttribute(global::System.ComponentModel.DesignerSerializationVisibility.Hidden)]
+ public new global::System.Data.DataRelationCollection Relations {
+ get {
+ return base.Relations;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override void InitializeDerivedDataSet() {
+ this.BeginInit();
+ this.InitClass();
+ this.EndInit();
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public override global::System.Data.DataSet Clone() {
+ SQLHistoryDataSet cln = ((SQLHistoryDataSet)(base.Clone()));
+ cln.InitVars();
+ cln.SchemaSerializationMode = this.SchemaSerializationMode;
+ return cln;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override bool ShouldSerializeTables() {
+ return false;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override bool ShouldSerializeRelations() {
+ return false;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override void ReadXmlSerializable(global::System.Xml.XmlReader reader) {
+ if ((this.DetermineSchemaSerializationMode(reader) == global::System.Data.SchemaSerializationMode.IncludeSchema)) {
+ this.Reset();
+ global::System.Data.DataSet ds = new global::System.Data.DataSet();
+ ds.ReadXml(reader);
+ if ((ds.Tables["History"] != null)) {
+ base.Tables.Add(new HistoryDataTable(ds.Tables["History"]));
+ }
+ this.DataSetName = ds.DataSetName;
+ this.Prefix = ds.Prefix;
+ this.Namespace = ds.Namespace;
+ this.Locale = ds.Locale;
+ this.CaseSensitive = ds.CaseSensitive;
+ this.EnforceConstraints = ds.EnforceConstraints;
+ this.Merge(ds, false, global::System.Data.MissingSchemaAction.Add);
+ this.InitVars();
+ }
+ else {
+ this.ReadXml(reader);
+ this.InitVars();
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override global::System.Xml.Schema.XmlSchema GetSchemaSerializable() {
+ global::System.IO.MemoryStream stream = new global::System.IO.MemoryStream();
+ this.WriteXmlSchema(new global::System.Xml.XmlTextWriter(stream, null));
+ stream.Position = 0;
+ return global::System.Xml.Schema.XmlSchema.Read(new global::System.Xml.XmlTextReader(stream), null);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ internal void InitVars() {
+ this.InitVars(true);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ internal void InitVars(bool initTable) {
+ this.tableHistory = ((HistoryDataTable)(base.Tables["History"]));
+ if ((initTable == true)) {
+ if ((this.tableHistory != null)) {
+ this.tableHistory.InitVars();
+ }
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ private void InitClass() {
+ this.DataSetName = "SQLHistoryDataSet";
+ this.Prefix = "";
+ this.Namespace = "http://tempuri.org/SQLHistoryDataSet.xsd";
+ this.EnforceConstraints = true;
+ this.SchemaSerializationMode = global::System.Data.SchemaSerializationMode.IncludeSchema;
+ this.tableHistory = new HistoryDataTable();
+ base.Tables.Add(this.tableHistory);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ private bool ShouldSerializeHistory() {
+ return false;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ private void SchemaChanged(object sender, global::System.ComponentModel.CollectionChangeEventArgs e) {
+ if ((e.Action == global::System.ComponentModel.CollectionChangeAction.Remove)) {
+ this.InitVars();
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public static global::System.Xml.Schema.XmlSchemaComplexType GetTypedDataSetSchema(global::System.Xml.Schema.XmlSchemaSet xs) {
+ SQLHistoryDataSet ds = new SQLHistoryDataSet();
+ global::System.Xml.Schema.XmlSchemaComplexType type = new global::System.Xml.Schema.XmlSchemaComplexType();
+ global::System.Xml.Schema.XmlSchemaSequence sequence = new global::System.Xml.Schema.XmlSchemaSequence();
+ global::System.Xml.Schema.XmlSchemaAny any = new global::System.Xml.Schema.XmlSchemaAny();
+ any.Namespace = ds.Namespace;
+ sequence.Items.Add(any);
+ type.Particle = sequence;
+ global::System.Xml.Schema.XmlSchema dsSchema = ds.GetSchemaSerializable();
+ if (xs.Contains(dsSchema.TargetNamespace)) {
+ global::System.IO.MemoryStream s1 = new global::System.IO.MemoryStream();
+ global::System.IO.MemoryStream s2 = new global::System.IO.MemoryStream();
+ try {
+ global::System.Xml.Schema.XmlSchema schema = null;
+ dsSchema.Write(s1);
+ for (global::System.Collections.IEnumerator schemas = xs.Schemas(dsSchema.TargetNamespace).GetEnumerator(); schemas.MoveNext(); ) {
+ schema = ((global::System.Xml.Schema.XmlSchema)(schemas.Current));
+ s2.SetLength(0);
+ schema.Write(s2);
+ if ((s1.Length == s2.Length)) {
+ s1.Position = 0;
+ s2.Position = 0;
+ for (; ((s1.Position != s1.Length)
+ && (s1.ReadByte() == s2.ReadByte())); ) {
+ ;
+ }
+ if ((s1.Position == s1.Length)) {
+ return type;
+ }
+ }
+ }
+ }
+ finally {
+ if ((s1 != null)) {
+ s1.Close();
+ }
+ if ((s2 != null)) {
+ s2.Close();
+ }
+ }
+ }
+ xs.Add(dsSchema);
+ return type;
+ }
+
+ public delegate void HistoryRowChangeEventHandler(object sender, HistoryRowChangeEvent e);
+
+ ///
+ ///Represents the strongly named DataTable class.
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "2.0.0.0")]
+ [global::System.Serializable()]
+ [global::System.Xml.Serialization.XmlSchemaProviderAttribute("GetTypedTableSchema")]
+ public partial class HistoryDataTable : global::System.Data.TypedTableBase {
+
+ private global::System.Data.DataColumn columnUserName;
+
+ private global::System.Data.DataColumn columnMachineName;
+
+ private global::System.Data.DataColumn columnEntryType;
+
+ private global::System.Data.DataColumn columnModificationDate;
+
+ private global::System.Data.DataColumn columnXmlContent;
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public HistoryDataTable() {
+ this.TableName = "History";
+ this.BeginInit();
+ this.InitClass();
+ this.EndInit();
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ internal HistoryDataTable(global::System.Data.DataTable table) {
+ this.TableName = table.TableName;
+ if ((table.CaseSensitive != table.DataSet.CaseSensitive)) {
+ this.CaseSensitive = table.CaseSensitive;
+ }
+ if ((table.Locale.ToString() != table.DataSet.Locale.ToString())) {
+ this.Locale = table.Locale;
+ }
+ if ((table.Namespace != table.DataSet.Namespace)) {
+ this.Namespace = table.Namespace;
+ }
+ this.Prefix = table.Prefix;
+ this.MinimumCapacity = table.MinimumCapacity;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected HistoryDataTable(global::System.Runtime.Serialization.SerializationInfo info, global::System.Runtime.Serialization.StreamingContext context) :
+ base(info, context) {
+ this.InitVars();
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public global::System.Data.DataColumn UserNameColumn {
+ get {
+ return this.columnUserName;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public global::System.Data.DataColumn MachineNameColumn {
+ get {
+ return this.columnMachineName;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public global::System.Data.DataColumn EntryTypeColumn {
+ get {
+ return this.columnEntryType;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public global::System.Data.DataColumn ModificationDateColumn {
+ get {
+ return this.columnModificationDate;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public global::System.Data.DataColumn XmlContentColumn {
+ get {
+ return this.columnXmlContent;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.Browsable(false)]
+ public int Count {
+ get {
+ return this.Rows.Count;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public HistoryRow this[int index] {
+ get {
+ return ((HistoryRow)(this.Rows[index]));
+ }
+ }
+
+ public event HistoryRowChangeEventHandler HistoryRowChanging;
+
+ public event HistoryRowChangeEventHandler HistoryRowChanged;
+
+ public event HistoryRowChangeEventHandler HistoryRowDeleting;
+
+ public event HistoryRowChangeEventHandler HistoryRowDeleted;
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public void AddHistoryRow(HistoryRow row) {
+ this.Rows.Add(row);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public HistoryRow AddHistoryRow(string UserName, string MachineName, string EntryType, System.DateTime ModificationDate, string XmlContent) {
+ HistoryRow rowHistoryRow = ((HistoryRow)(this.NewRow()));
+ object[] columnValuesArray = new object[] {
+ UserName,
+ MachineName,
+ EntryType,
+ ModificationDate,
+ XmlContent};
+ rowHistoryRow.ItemArray = columnValuesArray;
+ this.Rows.Add(rowHistoryRow);
+ return rowHistoryRow;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public HistoryRow FindByUserNameMachineNameEntryTypeModificationDate(string UserName, string MachineName, string EntryType, System.DateTime ModificationDate) {
+ return ((HistoryRow)(this.Rows.Find(new object[] {
+ UserName,
+ MachineName,
+ EntryType,
+ ModificationDate})));
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public override global::System.Data.DataTable Clone() {
+ HistoryDataTable cln = ((HistoryDataTable)(base.Clone()));
+ cln.InitVars();
+ return cln;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override global::System.Data.DataTable CreateInstance() {
+ return new HistoryDataTable();
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ internal void InitVars() {
+ this.columnUserName = base.Columns["UserName"];
+ this.columnMachineName = base.Columns["MachineName"];
+ this.columnEntryType = base.Columns["EntryType"];
+ this.columnModificationDate = base.Columns["ModificationDate"];
+ this.columnXmlContent = base.Columns["XmlContent"];
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ private void InitClass() {
+ this.columnUserName = new global::System.Data.DataColumn("UserName", typeof(string), null, global::System.Data.MappingType.Element);
+ base.Columns.Add(this.columnUserName);
+ this.columnMachineName = new global::System.Data.DataColumn("MachineName", typeof(string), null, global::System.Data.MappingType.Element);
+ base.Columns.Add(this.columnMachineName);
+ this.columnEntryType = new global::System.Data.DataColumn("EntryType", typeof(string), null, global::System.Data.MappingType.Element);
+ base.Columns.Add(this.columnEntryType);
+ this.columnModificationDate = new global::System.Data.DataColumn("ModificationDate", typeof(global::System.DateTime), null, global::System.Data.MappingType.Element);
+ base.Columns.Add(this.columnModificationDate);
+ this.columnXmlContent = new global::System.Data.DataColumn("XmlContent", typeof(string), null, global::System.Data.MappingType.Element);
+ base.Columns.Add(this.columnXmlContent);
+ this.Constraints.Add(new global::System.Data.UniqueConstraint("Constraint1", new global::System.Data.DataColumn[] {
+ this.columnUserName,
+ this.columnMachineName,
+ this.columnEntryType,
+ this.columnModificationDate}, true));
+ this.columnUserName.AllowDBNull = false;
+ this.columnUserName.MaxLength = 50;
+ this.columnMachineName.AllowDBNull = false;
+ this.columnMachineName.MaxLength = 50;
+ this.columnEntryType.AllowDBNull = false;
+ this.columnEntryType.MaxLength = 50;
+ this.columnModificationDate.AllowDBNull = false;
+ this.columnXmlContent.MaxLength = 2147483647;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public HistoryRow NewHistoryRow() {
+ return ((HistoryRow)(this.NewRow()));
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override global::System.Data.DataRow NewRowFromBuilder(global::System.Data.DataRowBuilder builder) {
+ return new HistoryRow(builder);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override global::System.Type GetRowType() {
+ return typeof(HistoryRow);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override void OnRowChanged(global::System.Data.DataRowChangeEventArgs e) {
+ base.OnRowChanged(e);
+ if ((this.HistoryRowChanged != null)) {
+ this.HistoryRowChanged(this, new HistoryRowChangeEvent(((HistoryRow)(e.Row)), e.Action));
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override void OnRowChanging(global::System.Data.DataRowChangeEventArgs e) {
+ base.OnRowChanging(e);
+ if ((this.HistoryRowChanging != null)) {
+ this.HistoryRowChanging(this, new HistoryRowChangeEvent(((HistoryRow)(e.Row)), e.Action));
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override void OnRowDeleted(global::System.Data.DataRowChangeEventArgs e) {
+ base.OnRowDeleted(e);
+ if ((this.HistoryRowDeleted != null)) {
+ this.HistoryRowDeleted(this, new HistoryRowChangeEvent(((HistoryRow)(e.Row)), e.Action));
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override void OnRowDeleting(global::System.Data.DataRowChangeEventArgs e) {
+ base.OnRowDeleting(e);
+ if ((this.HistoryRowDeleting != null)) {
+ this.HistoryRowDeleting(this, new HistoryRowChangeEvent(((HistoryRow)(e.Row)), e.Action));
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public void RemoveHistoryRow(HistoryRow row) {
+ this.Rows.Remove(row);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public static global::System.Xml.Schema.XmlSchemaComplexType GetTypedTableSchema(global::System.Xml.Schema.XmlSchemaSet xs) {
+ global::System.Xml.Schema.XmlSchemaComplexType type = new global::System.Xml.Schema.XmlSchemaComplexType();
+ global::System.Xml.Schema.XmlSchemaSequence sequence = new global::System.Xml.Schema.XmlSchemaSequence();
+ SQLHistoryDataSet ds = new SQLHistoryDataSet();
+ global::System.Xml.Schema.XmlSchemaAny any1 = new global::System.Xml.Schema.XmlSchemaAny();
+ any1.Namespace = "http://www.w3.org/2001/XMLSchema";
+ any1.MinOccurs = new decimal(0);
+ any1.MaxOccurs = decimal.MaxValue;
+ any1.ProcessContents = global::System.Xml.Schema.XmlSchemaContentProcessing.Lax;
+ sequence.Items.Add(any1);
+ global::System.Xml.Schema.XmlSchemaAny any2 = new global::System.Xml.Schema.XmlSchemaAny();
+ any2.Namespace = "urn:schemas-microsoft-com:xml-diffgram-v1";
+ any2.MinOccurs = new decimal(1);
+ any2.ProcessContents = global::System.Xml.Schema.XmlSchemaContentProcessing.Lax;
+ sequence.Items.Add(any2);
+ global::System.Xml.Schema.XmlSchemaAttribute attribute1 = new global::System.Xml.Schema.XmlSchemaAttribute();
+ attribute1.Name = "namespace";
+ attribute1.FixedValue = ds.Namespace;
+ type.Attributes.Add(attribute1);
+ global::System.Xml.Schema.XmlSchemaAttribute attribute2 = new global::System.Xml.Schema.XmlSchemaAttribute();
+ attribute2.Name = "tableTypeName";
+ attribute2.FixedValue = "HistoryDataTable";
+ type.Attributes.Add(attribute2);
+ type.Particle = sequence;
+ global::System.Xml.Schema.XmlSchema dsSchema = ds.GetSchemaSerializable();
+ if (xs.Contains(dsSchema.TargetNamespace)) {
+ global::System.IO.MemoryStream s1 = new global::System.IO.MemoryStream();
+ global::System.IO.MemoryStream s2 = new global::System.IO.MemoryStream();
+ try {
+ global::System.Xml.Schema.XmlSchema schema = null;
+ dsSchema.Write(s1);
+ for (global::System.Collections.IEnumerator schemas = xs.Schemas(dsSchema.TargetNamespace).GetEnumerator(); schemas.MoveNext(); ) {
+ schema = ((global::System.Xml.Schema.XmlSchema)(schemas.Current));
+ s2.SetLength(0);
+ schema.Write(s2);
+ if ((s1.Length == s2.Length)) {
+ s1.Position = 0;
+ s2.Position = 0;
+ for (; ((s1.Position != s1.Length)
+ && (s1.ReadByte() == s2.ReadByte())); ) {
+ ;
+ }
+ if ((s1.Position == s1.Length)) {
+ return type;
+ }
+ }
+ }
+ }
+ finally {
+ if ((s1 != null)) {
+ s1.Close();
+ }
+ if ((s2 != null)) {
+ s2.Close();
+ }
+ }
+ }
+ xs.Add(dsSchema);
+ return type;
+ }
+ }
+
+ ///
+ ///Represents strongly named DataRow class.
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "2.0.0.0")]
+ public partial class HistoryRow : global::System.Data.DataRow {
+
+ private HistoryDataTable tableHistory;
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ internal HistoryRow(global::System.Data.DataRowBuilder rb) :
+ base(rb) {
+ this.tableHistory = ((HistoryDataTable)(this.Table));
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public string UserName {
+ get {
+ return ((string)(this[this.tableHistory.UserNameColumn]));
+ }
+ set {
+ this[this.tableHistory.UserNameColumn] = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public string MachineName {
+ get {
+ return ((string)(this[this.tableHistory.MachineNameColumn]));
+ }
+ set {
+ this[this.tableHistory.MachineNameColumn] = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public string EntryType {
+ get {
+ return ((string)(this[this.tableHistory.EntryTypeColumn]));
+ }
+ set {
+ this[this.tableHistory.EntryTypeColumn] = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public System.DateTime ModificationDate {
+ get {
+ return ((global::System.DateTime)(this[this.tableHistory.ModificationDateColumn]));
+ }
+ set {
+ this[this.tableHistory.ModificationDateColumn] = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public string XmlContent {
+ get {
+ try {
+ return ((string)(this[this.tableHistory.XmlContentColumn]));
+ }
+ catch (global::System.InvalidCastException e) {
+ throw new global::System.Data.StrongTypingException("The value for column \'XmlContent\' in table \'History\' is DBNull.", e);
+ }
+ }
+ set {
+ this[this.tableHistory.XmlContentColumn] = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public bool IsXmlContentNull() {
+ return this.IsNull(this.tableHistory.XmlContentColumn);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public void SetXmlContentNull() {
+ this[this.tableHistory.XmlContentColumn] = global::System.Convert.DBNull;
+ }
+ }
+
+ ///
+ ///Row event argument class
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "2.0.0.0")]
+ public class HistoryRowChangeEvent : global::System.EventArgs {
+
+ private HistoryRow eventRow;
+
+ private global::System.Data.DataRowAction eventAction;
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public HistoryRowChangeEvent(HistoryRow row, global::System.Data.DataRowAction action) {
+ this.eventRow = row;
+ this.eventAction = action;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public HistoryRow Row {
+ get {
+ return this.eventRow;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public global::System.Data.DataRowAction Action {
+ get {
+ return this.eventAction;
+ }
+ }
+ }
+ }
+}
+namespace Duplicati.Scheduler.Monitor.SQL.SQLHistoryDataSetTableAdapters {
+
+
+ ///
+ ///Represents the connection and commands used to retrieve and save data.
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "2.0.0.0")]
+ [global::System.ComponentModel.DesignerCategoryAttribute("code")]
+ [global::System.ComponentModel.ToolboxItem(true)]
+ [global::System.ComponentModel.DataObjectAttribute(true)]
+ [global::System.ComponentModel.DesignerAttribute("Microsoft.VSDesigner.DataSource.Design.TableAdapterDesigner, Microsoft.VSDesigner" +
+ ", Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
+ [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")]
+ public partial class HistoryTableAdapter : global::System.ComponentModel.Component {
+
+ private global::System.Data.SqlClient.SqlDataAdapter _adapter;
+
+ private global::System.Data.SqlClient.SqlConnection _connection;
+
+ private global::System.Data.SqlClient.SqlTransaction _transaction;
+
+ private global::System.Data.SqlClient.SqlCommand[] _commandCollection;
+
+ private bool _clearBeforeFill;
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public HistoryTableAdapter() {
+ this.ClearBeforeFill = true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected internal global::System.Data.SqlClient.SqlDataAdapter Adapter {
+ get {
+ if ((this._adapter == null)) {
+ this.InitAdapter();
+ }
+ return this._adapter;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ internal global::System.Data.SqlClient.SqlConnection Connection {
+ get {
+ if ((this._connection == null)) {
+ this.InitConnection();
+ }
+ return this._connection;
+ }
+ set {
+ this._connection = value;
+ if ((this.Adapter.InsertCommand != null)) {
+ this.Adapter.InsertCommand.Connection = value;
+ }
+ if ((this.Adapter.DeleteCommand != null)) {
+ this.Adapter.DeleteCommand.Connection = value;
+ }
+ if ((this.Adapter.UpdateCommand != null)) {
+ this.Adapter.UpdateCommand.Connection = value;
+ }
+ for (int i = 0; (i < this.CommandCollection.Length); i = (i + 1)) {
+ if ((this.CommandCollection[i] != null)) {
+ ((global::System.Data.SqlClient.SqlCommand)(this.CommandCollection[i])).Connection = value;
+ }
+ }
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ internal global::System.Data.SqlClient.SqlTransaction Transaction {
+ get {
+ return this._transaction;
+ }
+ set {
+ this._transaction = value;
+ for (int i = 0; (i < this.CommandCollection.Length); i = (i + 1)) {
+ this.CommandCollection[i].Transaction = this._transaction;
+ }
+ if (((this.Adapter != null)
+ && (this.Adapter.DeleteCommand != null))) {
+ this.Adapter.DeleteCommand.Transaction = this._transaction;
+ }
+ if (((this.Adapter != null)
+ && (this.Adapter.InsertCommand != null))) {
+ this.Adapter.InsertCommand.Transaction = this._transaction;
+ }
+ if (((this.Adapter != null)
+ && (this.Adapter.UpdateCommand != null))) {
+ this.Adapter.UpdateCommand.Transaction = this._transaction;
+ }
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected global::System.Data.SqlClient.SqlCommand[] CommandCollection {
+ get {
+ if ((this._commandCollection == null)) {
+ this.InitCommandCollection();
+ }
+ return this._commandCollection;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public bool ClearBeforeFill {
+ get {
+ return this._clearBeforeFill;
+ }
+ set {
+ this._clearBeforeFill = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ private void InitAdapter() {
+ this._adapter = new global::System.Data.SqlClient.SqlDataAdapter();
+ global::System.Data.Common.DataTableMapping tableMapping = new global::System.Data.Common.DataTableMapping();
+ tableMapping.SourceTable = "Table";
+ tableMapping.DataSetTable = "History";
+ tableMapping.ColumnMappings.Add("UserName", "UserName");
+ tableMapping.ColumnMappings.Add("MachineName", "MachineName");
+ tableMapping.ColumnMappings.Add("EntryType", "EntryType");
+ tableMapping.ColumnMappings.Add("ModificationDate", "ModificationDate");
+ tableMapping.ColumnMappings.Add("XmlContent", "XmlContent");
+ this._adapter.TableMappings.Add(tableMapping);
+ this._adapter.DeleteCommand = new global::System.Data.SqlClient.SqlCommand();
+ this._adapter.DeleteCommand.Connection = this.Connection;
+ this._adapter.DeleteCommand.CommandText = "DELETE FROM [dbo].[History] WHERE (([UserName] = @Original_UserName) AND ([Machin" +
+ "eName] = @Original_MachineName) AND ([EntryType] = @Original_EntryType) AND ([Mo" +
+ "dificationDate] = @Original_ModificationDate))";
+ this._adapter.DeleteCommand.CommandType = global::System.Data.CommandType.Text;
+ this._adapter.DeleteCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@Original_UserName", global::System.Data.SqlDbType.VarChar, 0, global::System.Data.ParameterDirection.Input, 0, 0, "UserName", global::System.Data.DataRowVersion.Original, false, null, "", "", ""));
+ this._adapter.DeleteCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@Original_MachineName", global::System.Data.SqlDbType.VarChar, 0, global::System.Data.ParameterDirection.Input, 0, 0, "MachineName", global::System.Data.DataRowVersion.Original, false, null, "", "", ""));
+ this._adapter.DeleteCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@Original_EntryType", global::System.Data.SqlDbType.VarChar, 0, global::System.Data.ParameterDirection.Input, 0, 0, "EntryType", global::System.Data.DataRowVersion.Original, false, null, "", "", ""));
+ this._adapter.DeleteCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@Original_ModificationDate", global::System.Data.SqlDbType.DateTime, 0, global::System.Data.ParameterDirection.Input, 0, 0, "ModificationDate", global::System.Data.DataRowVersion.Original, false, null, "", "", ""));
+ this._adapter.InsertCommand = new global::System.Data.SqlClient.SqlCommand();
+ this._adapter.InsertCommand.Connection = this.Connection;
+ this._adapter.InsertCommand.CommandText = @"INSERT INTO [dbo].[History] ([UserName], [MachineName], [EntryType], [ModificationDate], [XmlContent]) VALUES (@UserName, @MachineName, @EntryType, @ModificationDate, @XmlContent);
+SELECT UserName, MachineName, EntryType, ModificationDate, XmlContent FROM History WHERE (EntryType = @EntryType) AND (MachineName = @MachineName) AND (ModificationDate = @ModificationDate) AND (UserName = @UserName)";
+ this._adapter.InsertCommand.CommandType = global::System.Data.CommandType.Text;
+ this._adapter.InsertCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@UserName", global::System.Data.SqlDbType.VarChar, 0, global::System.Data.ParameterDirection.Input, 0, 0, "UserName", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
+ this._adapter.InsertCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@MachineName", global::System.Data.SqlDbType.VarChar, 0, global::System.Data.ParameterDirection.Input, 0, 0, "MachineName", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
+ this._adapter.InsertCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@EntryType", global::System.Data.SqlDbType.VarChar, 0, global::System.Data.ParameterDirection.Input, 0, 0, "EntryType", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
+ this._adapter.InsertCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@ModificationDate", global::System.Data.SqlDbType.DateTime, 0, global::System.Data.ParameterDirection.Input, 0, 0, "ModificationDate", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
+ this._adapter.InsertCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@XmlContent", global::System.Data.SqlDbType.Xml, 0, global::System.Data.ParameterDirection.Input, 0, 0, "XmlContent", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
+ this._adapter.UpdateCommand = new global::System.Data.SqlClient.SqlCommand();
+ this._adapter.UpdateCommand.Connection = this.Connection;
+ this._adapter.UpdateCommand.CommandText = @"UPDATE [dbo].[History] SET [UserName] = @UserName, [MachineName] = @MachineName, [EntryType] = @EntryType, [ModificationDate] = @ModificationDate, [XmlContent] = @XmlContent WHERE (([UserName] = @Original_UserName) AND ([MachineName] = @Original_MachineName) AND ([EntryType] = @Original_EntryType) AND ([ModificationDate] = @Original_ModificationDate));
+SELECT UserName, MachineName, EntryType, ModificationDate, XmlContent FROM History WHERE (EntryType = @EntryType) AND (MachineName = @MachineName) AND (ModificationDate = @ModificationDate) AND (UserName = @UserName)";
+ this._adapter.UpdateCommand.CommandType = global::System.Data.CommandType.Text;
+ this._adapter.UpdateCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@UserName", global::System.Data.SqlDbType.VarChar, 0, global::System.Data.ParameterDirection.Input, 0, 0, "UserName", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
+ this._adapter.UpdateCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@MachineName", global::System.Data.SqlDbType.VarChar, 0, global::System.Data.ParameterDirection.Input, 0, 0, "MachineName", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
+ this._adapter.UpdateCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@EntryType", global::System.Data.SqlDbType.VarChar, 0, global::System.Data.ParameterDirection.Input, 0, 0, "EntryType", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
+ this._adapter.UpdateCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@ModificationDate", global::System.Data.SqlDbType.DateTime, 0, global::System.Data.ParameterDirection.Input, 0, 0, "ModificationDate", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
+ this._adapter.UpdateCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@XmlContent", global::System.Data.SqlDbType.Xml, 0, global::System.Data.ParameterDirection.Input, 0, 0, "XmlContent", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
+ this._adapter.UpdateCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@Original_UserName", global::System.Data.SqlDbType.VarChar, 0, global::System.Data.ParameterDirection.Input, 0, 0, "UserName", global::System.Data.DataRowVersion.Original, false, null, "", "", ""));
+ this._adapter.UpdateCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@Original_MachineName", global::System.Data.SqlDbType.VarChar, 0, global::System.Data.ParameterDirection.Input, 0, 0, "MachineName", global::System.Data.DataRowVersion.Original, false, null, "", "", ""));
+ this._adapter.UpdateCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@Original_EntryType", global::System.Data.SqlDbType.VarChar, 0, global::System.Data.ParameterDirection.Input, 0, 0, "EntryType", global::System.Data.DataRowVersion.Original, false, null, "", "", ""));
+ this._adapter.UpdateCommand.Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@Original_ModificationDate", global::System.Data.SqlDbType.DateTime, 0, global::System.Data.ParameterDirection.Input, 0, 0, "ModificationDate", global::System.Data.DataRowVersion.Original, false, null, "", "", ""));
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ private void InitConnection() {
+ this._connection = new global::System.Data.SqlClient.SqlConnection();
+ this._connection.ConnectionString = global::Duplicati.Scheduler.Monitor.SQL.Properties.Settings.Default.BackupsConnectionString;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ private void InitCommandCollection() {
+ this._commandCollection = new global::System.Data.SqlClient.SqlCommand[3];
+ this._commandCollection[0] = new global::System.Data.SqlClient.SqlCommand();
+ this._commandCollection[0].Connection = this.Connection;
+ this._commandCollection[0].CommandText = "SELECT UserName, MachineName, EntryType, ModificationDate, XmlContent FROM dbo.Hi" +
+ "story";
+ this._commandCollection[0].CommandType = global::System.Data.CommandType.Text;
+ this._commandCollection[1] = new global::System.Data.SqlClient.SqlCommand();
+ this._commandCollection[1].Connection = this.Connection;
+ this._commandCollection[1].CommandText = "SELECT UserName, MachineName, EntryType, ModificationDate, XmlContent FROM dbo.Hi" +
+ "story\r\nWHERE (UserName = @aUserName) AND (MachineName = @aMachineName) AN" +
+ "D (EntryType = @aEntryType) AND (ModificationDate = @aModificationDate)";
+ this._commandCollection[1].CommandType = global::System.Data.CommandType.Text;
+ this._commandCollection[1].Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@aUserName", global::System.Data.SqlDbType.VarChar, 50, global::System.Data.ParameterDirection.Input, 0, 0, "UserName", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
+ this._commandCollection[1].Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@aMachineName", global::System.Data.SqlDbType.VarChar, 50, global::System.Data.ParameterDirection.Input, 0, 0, "MachineName", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
+ this._commandCollection[1].Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@aEntryType", global::System.Data.SqlDbType.VarChar, 50, global::System.Data.ParameterDirection.Input, 0, 0, "EntryType", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
+ this._commandCollection[1].Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@aModificationDate", global::System.Data.SqlDbType.DateTime, 8, global::System.Data.ParameterDirection.Input, 0, 0, "ModificationDate", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
+ this._commandCollection[2] = new global::System.Data.SqlClient.SqlCommand();
+ this._commandCollection[2].Connection = this.Connection;
+ this._commandCollection[2].CommandText = "SELECT MAX(ModificationDate) FROM History\r\nWHERE (UserName = @aUserName) A" +
+ "ND (MachineName = @aMachineName) AND (EntryType = @aEntryType)";
+ this._commandCollection[2].CommandType = global::System.Data.CommandType.Text;
+ this._commandCollection[2].Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@aUserName", global::System.Data.SqlDbType.VarChar, 50, global::System.Data.ParameterDirection.Input, 0, 0, "UserName", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
+ this._commandCollection[2].Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@aMachineName", global::System.Data.SqlDbType.VarChar, 50, global::System.Data.ParameterDirection.Input, 0, 0, "MachineName", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
+ this._commandCollection[2].Parameters.Add(new global::System.Data.SqlClient.SqlParameter("@aEntryType", global::System.Data.SqlDbType.VarChar, 50, global::System.Data.ParameterDirection.Input, 0, 0, "EntryType", global::System.Data.DataRowVersion.Current, false, null, "", "", ""));
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")]
+ [global::System.ComponentModel.DataObjectMethodAttribute(global::System.ComponentModel.DataObjectMethodType.Fill, true)]
+ public virtual int Fill(SQLHistoryDataSet.HistoryDataTable dataTable) {
+ this.Adapter.SelectCommand = this.CommandCollection[0];
+ if ((this.ClearBeforeFill == true)) {
+ dataTable.Clear();
+ }
+ int returnValue = this.Adapter.Fill(dataTable);
+ return returnValue;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")]
+ [global::System.ComponentModel.DataObjectMethodAttribute(global::System.ComponentModel.DataObjectMethodType.Select, true)]
+ public virtual SQLHistoryDataSet.HistoryDataTable GetData() {
+ this.Adapter.SelectCommand = this.CommandCollection[0];
+ SQLHistoryDataSet.HistoryDataTable dataTable = new SQLHistoryDataSet.HistoryDataTable();
+ this.Adapter.Fill(dataTable);
+ return dataTable;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")]
+ [global::System.ComponentModel.DataObjectMethodAttribute(global::System.ComponentModel.DataObjectMethodType.Fill, false)]
+ public virtual int FillBy(SQLHistoryDataSet.HistoryDataTable dataTable, string aUserName, string aMachineName, string aEntryType, System.DateTime aModificationDate) {
+ this.Adapter.SelectCommand = this.CommandCollection[1];
+ if ((aUserName == null)) {
+ throw new global::System.ArgumentNullException("aUserName");
+ }
+ else {
+ this.Adapter.SelectCommand.Parameters[0].Value = ((string)(aUserName));
+ }
+ if ((aMachineName == null)) {
+ throw new global::System.ArgumentNullException("aMachineName");
+ }
+ else {
+ this.Adapter.SelectCommand.Parameters[1].Value = ((string)(aMachineName));
+ }
+ if ((aEntryType == null)) {
+ throw new global::System.ArgumentNullException("aEntryType");
+ }
+ else {
+ this.Adapter.SelectCommand.Parameters[2].Value = ((string)(aEntryType));
+ }
+ this.Adapter.SelectCommand.Parameters[3].Value = ((System.DateTime)(aModificationDate));
+ if ((this.ClearBeforeFill == true)) {
+ dataTable.Clear();
+ }
+ int returnValue = this.Adapter.Fill(dataTable);
+ return returnValue;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")]
+ [global::System.ComponentModel.DataObjectMethodAttribute(global::System.ComponentModel.DataObjectMethodType.Select, false)]
+ public virtual SQLHistoryDataSet.HistoryDataTable GetDataBy(string aUserName, string aMachineName, string aEntryType, System.DateTime aModificationDate) {
+ this.Adapter.SelectCommand = this.CommandCollection[1];
+ if ((aUserName == null)) {
+ throw new global::System.ArgumentNullException("aUserName");
+ }
+ else {
+ this.Adapter.SelectCommand.Parameters[0].Value = ((string)(aUserName));
+ }
+ if ((aMachineName == null)) {
+ throw new global::System.ArgumentNullException("aMachineName");
+ }
+ else {
+ this.Adapter.SelectCommand.Parameters[1].Value = ((string)(aMachineName));
+ }
+ if ((aEntryType == null)) {
+ throw new global::System.ArgumentNullException("aEntryType");
+ }
+ else {
+ this.Adapter.SelectCommand.Parameters[2].Value = ((string)(aEntryType));
+ }
+ this.Adapter.SelectCommand.Parameters[3].Value = ((System.DateTime)(aModificationDate));
+ SQLHistoryDataSet.HistoryDataTable dataTable = new SQLHistoryDataSet.HistoryDataTable();
+ this.Adapter.Fill(dataTable);
+ return dataTable;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")]
+ public virtual int Update(SQLHistoryDataSet.HistoryDataTable dataTable) {
+ return this.Adapter.Update(dataTable);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")]
+ public virtual int Update(SQLHistoryDataSet dataSet) {
+ return this.Adapter.Update(dataSet, "History");
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")]
+ public virtual int Update(global::System.Data.DataRow dataRow) {
+ return this.Adapter.Update(new global::System.Data.DataRow[] {
+ dataRow});
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")]
+ public virtual int Update(global::System.Data.DataRow[] dataRows) {
+ return this.Adapter.Update(dataRows);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")]
+ [global::System.ComponentModel.DataObjectMethodAttribute(global::System.ComponentModel.DataObjectMethodType.Delete, true)]
+ public virtual int Delete(string Original_UserName, string Original_MachineName, string Original_EntryType, System.DateTime Original_ModificationDate) {
+ if ((Original_UserName == null)) {
+ throw new global::System.ArgumentNullException("Original_UserName");
+ }
+ else {
+ this.Adapter.DeleteCommand.Parameters[0].Value = ((string)(Original_UserName));
+ }
+ if ((Original_MachineName == null)) {
+ throw new global::System.ArgumentNullException("Original_MachineName");
+ }
+ else {
+ this.Adapter.DeleteCommand.Parameters[1].Value = ((string)(Original_MachineName));
+ }
+ if ((Original_EntryType == null)) {
+ throw new global::System.ArgumentNullException("Original_EntryType");
+ }
+ else {
+ this.Adapter.DeleteCommand.Parameters[2].Value = ((string)(Original_EntryType));
+ }
+ this.Adapter.DeleteCommand.Parameters[3].Value = ((System.DateTime)(Original_ModificationDate));
+ global::System.Data.ConnectionState previousConnectionState = this.Adapter.DeleteCommand.Connection.State;
+ if (((this.Adapter.DeleteCommand.Connection.State & global::System.Data.ConnectionState.Open)
+ != global::System.Data.ConnectionState.Open)) {
+ this.Adapter.DeleteCommand.Connection.Open();
+ }
+ try {
+ int returnValue = this.Adapter.DeleteCommand.ExecuteNonQuery();
+ return returnValue;
+ }
+ finally {
+ if ((previousConnectionState == global::System.Data.ConnectionState.Closed)) {
+ this.Adapter.DeleteCommand.Connection.Close();
+ }
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")]
+ [global::System.ComponentModel.DataObjectMethodAttribute(global::System.ComponentModel.DataObjectMethodType.Insert, true)]
+ public virtual int Insert(string UserName, string MachineName, string EntryType, System.DateTime ModificationDate, object XmlContent) {
+ if ((UserName == null)) {
+ throw new global::System.ArgumentNullException("UserName");
+ }
+ else {
+ this.Adapter.InsertCommand.Parameters[0].Value = ((string)(UserName));
+ }
+ if ((MachineName == null)) {
+ throw new global::System.ArgumentNullException("MachineName");
+ }
+ else {
+ this.Adapter.InsertCommand.Parameters[1].Value = ((string)(MachineName));
+ }
+ if ((EntryType == null)) {
+ throw new global::System.ArgumentNullException("EntryType");
+ }
+ else {
+ this.Adapter.InsertCommand.Parameters[2].Value = ((string)(EntryType));
+ }
+ this.Adapter.InsertCommand.Parameters[3].Value = ((System.DateTime)(ModificationDate));
+ if ((XmlContent == null)) {
+ this.Adapter.InsertCommand.Parameters[4].Value = global::System.DBNull.Value;
+ }
+ else {
+ this.Adapter.InsertCommand.Parameters[4].Value = ((object)(XmlContent));
+ }
+ global::System.Data.ConnectionState previousConnectionState = this.Adapter.InsertCommand.Connection.State;
+ if (((this.Adapter.InsertCommand.Connection.State & global::System.Data.ConnectionState.Open)
+ != global::System.Data.ConnectionState.Open)) {
+ this.Adapter.InsertCommand.Connection.Open();
+ }
+ try {
+ int returnValue = this.Adapter.InsertCommand.ExecuteNonQuery();
+ return returnValue;
+ }
+ finally {
+ if ((previousConnectionState == global::System.Data.ConnectionState.Closed)) {
+ this.Adapter.InsertCommand.Connection.Close();
+ }
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")]
+ [global::System.ComponentModel.DataObjectMethodAttribute(global::System.ComponentModel.DataObjectMethodType.Update, true)]
+ public virtual int Update(string UserName, string MachineName, string EntryType, System.DateTime ModificationDate, object XmlContent, string Original_UserName, string Original_MachineName, string Original_EntryType, System.DateTime Original_ModificationDate) {
+ if ((UserName == null)) {
+ throw new global::System.ArgumentNullException("UserName");
+ }
+ else {
+ this.Adapter.UpdateCommand.Parameters[0].Value = ((string)(UserName));
+ }
+ if ((MachineName == null)) {
+ throw new global::System.ArgumentNullException("MachineName");
+ }
+ else {
+ this.Adapter.UpdateCommand.Parameters[1].Value = ((string)(MachineName));
+ }
+ if ((EntryType == null)) {
+ throw new global::System.ArgumentNullException("EntryType");
+ }
+ else {
+ this.Adapter.UpdateCommand.Parameters[2].Value = ((string)(EntryType));
+ }
+ this.Adapter.UpdateCommand.Parameters[3].Value = ((System.DateTime)(ModificationDate));
+ if ((XmlContent == null)) {
+ this.Adapter.UpdateCommand.Parameters[4].Value = global::System.DBNull.Value;
+ }
+ else {
+ this.Adapter.UpdateCommand.Parameters[4].Value = ((object)(XmlContent));
+ }
+ if ((Original_UserName == null)) {
+ throw new global::System.ArgumentNullException("Original_UserName");
+ }
+ else {
+ this.Adapter.UpdateCommand.Parameters[5].Value = ((string)(Original_UserName));
+ }
+ if ((Original_MachineName == null)) {
+ throw new global::System.ArgumentNullException("Original_MachineName");
+ }
+ else {
+ this.Adapter.UpdateCommand.Parameters[6].Value = ((string)(Original_MachineName));
+ }
+ if ((Original_EntryType == null)) {
+ throw new global::System.ArgumentNullException("Original_EntryType");
+ }
+ else {
+ this.Adapter.UpdateCommand.Parameters[7].Value = ((string)(Original_EntryType));
+ }
+ this.Adapter.UpdateCommand.Parameters[8].Value = ((System.DateTime)(Original_ModificationDate));
+ global::System.Data.ConnectionState previousConnectionState = this.Adapter.UpdateCommand.Connection.State;
+ if (((this.Adapter.UpdateCommand.Connection.State & global::System.Data.ConnectionState.Open)
+ != global::System.Data.ConnectionState.Open)) {
+ this.Adapter.UpdateCommand.Connection.Open();
+ }
+ try {
+ int returnValue = this.Adapter.UpdateCommand.ExecuteNonQuery();
+ return returnValue;
+ }
+ finally {
+ if ((previousConnectionState == global::System.Data.ConnectionState.Closed)) {
+ this.Adapter.UpdateCommand.Connection.Close();
+ }
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")]
+ [global::System.ComponentModel.DataObjectMethodAttribute(global::System.ComponentModel.DataObjectMethodType.Update, true)]
+ public virtual int Update(object XmlContent, string Original_UserName, string Original_MachineName, string Original_EntryType, System.DateTime Original_ModificationDate) {
+ return this.Update(Original_UserName, Original_MachineName, Original_EntryType, Original_ModificationDate, XmlContent, Original_UserName, Original_MachineName, Original_EntryType, Original_ModificationDate);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapter")]
+ public virtual global::System.Nullable LatestQuery(string aUserName, string aMachineName, string aEntryType) {
+ global::System.Data.SqlClient.SqlCommand command = this.CommandCollection[2];
+ if ((aUserName == null)) {
+ throw new global::System.ArgumentNullException("aUserName");
+ }
+ else {
+ command.Parameters[0].Value = ((string)(aUserName));
+ }
+ if ((aMachineName == null)) {
+ throw new global::System.ArgumentNullException("aMachineName");
+ }
+ else {
+ command.Parameters[1].Value = ((string)(aMachineName));
+ }
+ if ((aEntryType == null)) {
+ throw new global::System.ArgumentNullException("aEntryType");
+ }
+ else {
+ command.Parameters[2].Value = ((string)(aEntryType));
+ }
+ global::System.Data.ConnectionState previousConnectionState = command.Connection.State;
+ if (((command.Connection.State & global::System.Data.ConnectionState.Open)
+ != global::System.Data.ConnectionState.Open)) {
+ command.Connection.Open();
+ }
+ object returnValue;
+ try {
+ returnValue = command.ExecuteScalar();
+ }
+ finally {
+ if ((previousConnectionState == global::System.Data.ConnectionState.Closed)) {
+ command.Connection.Close();
+ }
+ }
+ if (((returnValue == null)
+ || (returnValue.GetType() == typeof(global::System.DBNull)))) {
+ return new global::System.Nullable();
+ }
+ else {
+ return new global::System.Nullable(((global::System.DateTime)(returnValue)));
+ }
+ }
+ }
+
+ ///
+ ///TableAdapterManager is used to coordinate TableAdapters in the dataset to enable Hierarchical Update scenarios
+ ///
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "2.0.0.0")]
+ [global::System.ComponentModel.DesignerCategoryAttribute("code")]
+ [global::System.ComponentModel.ToolboxItem(true)]
+ [global::System.ComponentModel.DesignerAttribute("Microsoft.VSDesigner.DataSource.Design.TableAdapterManagerDesigner, Microsoft.VSD" +
+ "esigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
+ [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.TableAdapterManager")]
+ public partial class TableAdapterManager : global::System.ComponentModel.Component {
+
+ private UpdateOrderOption _updateOrder;
+
+ private HistoryTableAdapter _historyTableAdapter;
+
+ private bool _backupDataSetBeforeUpdate;
+
+ private global::System.Data.IDbConnection _connection;
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public UpdateOrderOption UpdateOrder {
+ get {
+ return this._updateOrder;
+ }
+ set {
+ this._updateOrder = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.EditorAttribute("Microsoft.VSDesigner.DataSource.Design.TableAdapterManagerPropertyEditor, Microso" +
+ "ft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" +
+ "", "System.Drawing.Design.UITypeEditor")]
+ public HistoryTableAdapter HistoryTableAdapter {
+ get {
+ return this._historyTableAdapter;
+ }
+ set {
+ this._historyTableAdapter = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public bool BackupDataSetBeforeUpdate {
+ get {
+ return this._backupDataSetBeforeUpdate;
+ }
+ set {
+ this._backupDataSetBeforeUpdate = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.Browsable(false)]
+ public global::System.Data.IDbConnection Connection {
+ get {
+ if ((this._connection != null)) {
+ return this._connection;
+ }
+ if (((this._historyTableAdapter != null)
+ && (this._historyTableAdapter.Connection != null))) {
+ return this._historyTableAdapter.Connection;
+ }
+ return null;
+ }
+ set {
+ this._connection = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.Browsable(false)]
+ public int TableAdapterInstanceCount {
+ get {
+ int count = 0;
+ if ((this._historyTableAdapter != null)) {
+ count = (count + 1);
+ }
+ return count;
+ }
+ }
+
+ ///
+ ///Update rows in top-down order.
+ ///
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ private int UpdateUpdatedRows(SQLHistoryDataSet dataSet, global::System.Collections.Generic.List allChangedRows, global::System.Collections.Generic.List allAddedRows) {
+ int result = 0;
+ if ((this._historyTableAdapter != null)) {
+ global::System.Data.DataRow[] updatedRows = dataSet.History.Select(null, null, global::System.Data.DataViewRowState.ModifiedCurrent);
+ updatedRows = this.GetRealUpdatedRows(updatedRows, allAddedRows);
+ if (((updatedRows != null)
+ && (0 < updatedRows.Length))) {
+ result = (result + this._historyTableAdapter.Update(updatedRows));
+ allChangedRows.AddRange(updatedRows);
+ }
+ }
+ return result;
+ }
+
+ ///
+ ///Insert rows in top-down order.
+ ///
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ private int UpdateInsertedRows(SQLHistoryDataSet dataSet, global::System.Collections.Generic.List allAddedRows) {
+ int result = 0;
+ if ((this._historyTableAdapter != null)) {
+ global::System.Data.DataRow[] addedRows = dataSet.History.Select(null, null, global::System.Data.DataViewRowState.Added);
+ if (((addedRows != null)
+ && (0 < addedRows.Length))) {
+ result = (result + this._historyTableAdapter.Update(addedRows));
+ allAddedRows.AddRange(addedRows);
+ }
+ }
+ return result;
+ }
+
+ ///
+ ///Delete rows in bottom-up order.
+ ///
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ private int UpdateDeletedRows(SQLHistoryDataSet dataSet, global::System.Collections.Generic.List allChangedRows) {
+ int result = 0;
+ if ((this._historyTableAdapter != null)) {
+ global::System.Data.DataRow[] deletedRows = dataSet.History.Select(null, null, global::System.Data.DataViewRowState.Deleted);
+ if (((deletedRows != null)
+ && (0 < deletedRows.Length))) {
+ result = (result + this._historyTableAdapter.Update(deletedRows));
+ allChangedRows.AddRange(deletedRows);
+ }
+ }
+ return result;
+ }
+
+ ///
+ ///Remove inserted rows that become updated rows after calling TableAdapter.Update(inserted rows) first
+ ///
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ private global::System.Data.DataRow[] GetRealUpdatedRows(global::System.Data.DataRow[] updatedRows, global::System.Collections.Generic.List allAddedRows) {
+ if (((updatedRows == null)
+ || (updatedRows.Length < 1))) {
+ return updatedRows;
+ }
+ if (((allAddedRows == null)
+ || (allAddedRows.Count < 1))) {
+ return updatedRows;
+ }
+ global::System.Collections.Generic.List realUpdatedRows = new global::System.Collections.Generic.List();
+ for (int i = 0; (i < updatedRows.Length); i = (i + 1)) {
+ global::System.Data.DataRow row = updatedRows[i];
+ if ((allAddedRows.Contains(row) == false)) {
+ realUpdatedRows.Add(row);
+ }
+ }
+ return realUpdatedRows.ToArray();
+ }
+
+ ///
+ ///Update all changes to the dataset.
+ ///
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public virtual int UpdateAll(SQLHistoryDataSet dataSet) {
+ if ((dataSet == null)) {
+ throw new global::System.ArgumentNullException("dataSet");
+ }
+ if ((dataSet.HasChanges() == false)) {
+ return 0;
+ }
+ if (((this._historyTableAdapter != null)
+ && (this.MatchTableAdapterConnection(this._historyTableAdapter.Connection) == false))) {
+ throw new global::System.ArgumentException("All TableAdapters managed by a TableAdapterManager must use the same connection s" +
+ "tring.");
+ }
+ global::System.Data.IDbConnection workConnection = this.Connection;
+ if ((workConnection == null)) {
+ throw new global::System.ApplicationException("TableAdapterManager contains no connection information. Set each TableAdapterMana" +
+ "ger TableAdapter property to a valid TableAdapter instance.");
+ }
+ bool workConnOpened = false;
+ if (((workConnection.State & global::System.Data.ConnectionState.Broken)
+ == global::System.Data.ConnectionState.Broken)) {
+ workConnection.Close();
+ }
+ if ((workConnection.State == global::System.Data.ConnectionState.Closed)) {
+ workConnection.Open();
+ workConnOpened = true;
+ }
+ global::System.Data.IDbTransaction workTransaction = workConnection.BeginTransaction();
+ if ((workTransaction == null)) {
+ throw new global::System.ApplicationException("The transaction cannot begin. The current data connection does not support transa" +
+ "ctions or the current state is not allowing the transaction to begin.");
+ }
+ global::System.Collections.Generic.List allChangedRows = new global::System.Collections.Generic.List();
+ global::System.Collections.Generic.List allAddedRows = new global::System.Collections.Generic.List();
+ global::System.Collections.Generic.List adaptersWithAcceptChangesDuringUpdate = new global::System.Collections.Generic.List();
+ global::System.Collections.Generic.Dictionary