From 0012d3e8a1fb896645c86fa214da1ae2145edb98 Mon Sep 17 00:00:00 2001 From: nikzori Date: Fri, 24 Jan 2025 17:54:04 +0300 Subject: [PATCH] added baudrate configuration --- Datasheet.Designer.cs | 76 +++++++++++++++++++++++++++--------------- Datasheet.cs | 74 +++++++++++++++++++++++++++++++--------- Main.Designer.cs | 44 ++++++++++++++++++------ Main.cs | 37 ++++++++++++-------- Model.cs | 2 +- screenshot-1.png | Bin 0 -> 11915 bytes 6 files changed, 168 insertions(+), 65 deletions(-) create mode 100644 screenshot-1.png diff --git a/Datasheet.Designer.cs b/Datasheet.Designer.cs index f35620c..f28d8ea 100644 --- a/Datasheet.Designer.cs +++ b/Datasheet.Designer.cs @@ -46,13 +46,15 @@ this.label7 = new System.Windows.Forms.Label(); this.labelAlarm = new System.Windows.Forms.Label(); this.label5 = new System.Windows.Forms.Label(); - this.button2 = new System.Windows.Forms.Button(); this.buttonAlarm = new System.Windows.Forms.Button(); this.buttonValve = new System.Windows.Forms.Button(); this.labelValve = new System.Windows.Forms.Label(); this.label4 = new System.Windows.Forms.Label(); this.sensorPanel = new System.Windows.Forms.FlowLayoutPanel(); this.label9 = new System.Windows.Forms.Label(); + this.button1 = new System.Windows.Forms.Button(); + this.label8 = new System.Windows.Forms.Label(); + this.cBoxSpeed = new System.Windows.Forms.ComboBox(); this.groupBox1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.nudModbusID)).BeginInit(); this.groupBox2.SuspendLayout(); @@ -60,6 +62,9 @@ // // groupBox1 // + this.groupBox1.Controls.Add(this.cBoxSpeed); + this.groupBox1.Controls.Add(this.button1); + this.groupBox1.Controls.Add(this.label8); this.groupBox1.Controls.Add(this.labelBattery); this.groupBox1.Controls.Add(this.label6); this.groupBox1.Controls.Add(this.buttonPoll); @@ -70,9 +75,9 @@ this.groupBox1.Controls.Add(this.label3); this.groupBox1.Controls.Add(this.label2); this.groupBox1.Controls.Add(this.label1); - this.groupBox1.Location = new System.Drawing.Point(304, 12); + this.groupBox1.Location = new System.Drawing.Point(291, 12); this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(221, 101); + this.groupBox1.Size = new System.Drawing.Size(234, 126); this.groupBox1.TabIndex = 0; this.groupBox1.TabStop = false; this.groupBox1.Text = "Инфо"; @@ -98,7 +103,7 @@ // buttonPoll // this.buttonPoll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.buttonPoll.Location = new System.Drawing.Point(140, 43); + this.buttonPoll.Location = new System.Drawing.Point(153, 43); this.buttonPoll.Name = "buttonPoll"; this.buttonPoll.Size = new System.Drawing.Size(75, 23); this.buttonPoll.TabIndex = 7; @@ -108,7 +113,7 @@ // // buttonSetID // - this.buttonSetID.Location = new System.Drawing.Point(140, 68); + this.buttonSetID.Location = new System.Drawing.Point(153, 68); this.buttonSetID.Name = "buttonSetID"; this.buttonSetID.Size = new System.Drawing.Size(75, 23); this.buttonSetID.TabIndex = 6; @@ -138,7 +143,7 @@ // this.nudModbusID.Location = new System.Drawing.Point(74, 71); this.nudModbusID.Name = "nudModbusID"; - this.nudModbusID.Size = new System.Drawing.Size(50, 20); + this.nudModbusID.Size = new System.Drawing.Size(49, 20); this.nudModbusID.TabIndex = 3; // // label3 @@ -175,14 +180,13 @@ this.groupBox2.Controls.Add(this.label7); this.groupBox2.Controls.Add(this.labelAlarm); this.groupBox2.Controls.Add(this.label5); - this.groupBox2.Controls.Add(this.button2); this.groupBox2.Controls.Add(this.buttonAlarm); this.groupBox2.Controls.Add(this.buttonValve); this.groupBox2.Controls.Add(this.labelValve); this.groupBox2.Controls.Add(this.label4); this.groupBox2.Location = new System.Drawing.Point(13, 12); this.groupBox2.Name = "groupBox2"; - this.groupBox2.Size = new System.Drawing.Size(285, 100); + this.groupBox2.Size = new System.Drawing.Size(272, 126); this.groupBox2.TabIndex = 1; this.groupBox2.TabStop = false; this.groupBox2.Text = "Общее"; @@ -200,7 +204,7 @@ // this.buttonCleaning.Location = new System.Drawing.Point(125, 72); this.buttonCleaning.Name = "buttonCleaning"; - this.buttonCleaning.Size = new System.Drawing.Size(73, 23); + this.buttonCleaning.Size = new System.Drawing.Size(140, 23); this.buttonCleaning.TabIndex = 8; this.buttonCleaning.Text = "Включить"; this.buttonCleaning.UseVisualStyleBackColor = true; @@ -233,20 +237,11 @@ this.label5.TabIndex = 5; this.label5.Text = "Протечка:"; // - // button2 - // - this.button2.Location = new System.Drawing.Point(204, 14); - this.button2.Name = "button2"; - this.button2.Size = new System.Drawing.Size(73, 52); - this.button2.TabIndex = 4; - this.button2.Text = "Аварийное открытие"; - this.button2.UseVisualStyleBackColor = true; - // // buttonAlarm // this.buttonAlarm.Location = new System.Drawing.Point(125, 43); this.buttonAlarm.Name = "buttonAlarm"; - this.buttonAlarm.Size = new System.Drawing.Size(73, 23); + this.buttonAlarm.Size = new System.Drawing.Size(140, 23); this.buttonAlarm.TabIndex = 3; this.buttonAlarm.Text = "Авария"; this.buttonAlarm.UseVisualStyleBackColor = true; @@ -256,7 +251,7 @@ // this.buttonValve.Location = new System.Drawing.Point(125, 14); this.buttonValve.Name = "buttonValve"; - this.buttonValve.Size = new System.Drawing.Size(73, 23); + this.buttonValve.Size = new System.Drawing.Size(140, 23); this.buttonValve.TabIndex = 2; this.buttonValve.Text = "Закрыть"; this.buttonValve.UseVisualStyleBackColor = true; @@ -287,26 +282,53 @@ this.sensorPanel.AutoScroll = true; this.sensorPanel.BackColor = System.Drawing.Color.Gainsboro; this.sensorPanel.FlowDirection = System.Windows.Forms.FlowDirection.TopDown; - this.sensorPanel.Location = new System.Drawing.Point(13, 135); + this.sensorPanel.Location = new System.Drawing.Point(13, 168); this.sensorPanel.Name = "sensorPanel"; - this.sensorPanel.Size = new System.Drawing.Size(512, 175); + this.sensorPanel.Size = new System.Drawing.Size(512, 248); this.sensorPanel.TabIndex = 4; this.sensorPanel.WrapContents = false; // // label9 // this.label9.AutoSize = true; - this.label9.Location = new System.Drawing.Point(10, 119); + this.label9.Location = new System.Drawing.Point(10, 152); this.label9.Name = "label9"; this.label9.Size = new System.Drawing.Size(50, 13); this.label9.TabIndex = 5; this.label9.Text = "Датчики"; // + // button1 + // + this.button1.Location = new System.Drawing.Point(153, 94); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(75, 23); + this.button1.TabIndex = 12; + this.button1.Text = "Изменить"; + this.button1.UseVisualStyleBackColor = true; + // + // label8 + // + this.label8.AutoSize = true; + this.label8.Location = new System.Drawing.Point(6, 99); + this.label8.Name = "label8"; + this.label8.Size = new System.Drawing.Size(58, 13); + this.label8.TabIndex = 10; + this.label8.Text = "Скорость:"; + // + // cBoxSpeed + // + this.cBoxSpeed.FormattingEnabled = true; + this.cBoxSpeed.Location = new System.Drawing.Point(74, 97); + this.cBoxSpeed.Name = "cBoxSpeed"; + this.cBoxSpeed.Size = new System.Drawing.Size(73, 21); + this.cBoxSpeed.TabIndex = 13; + this.cBoxSpeed.Text = "9600"; + // // Datasheet // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(537, 322); + this.ClientSize = new System.Drawing.Size(537, 428); this.Controls.Add(this.label9); this.Controls.Add(this.sensorPanel); this.Controls.Add(this.groupBox2); @@ -315,7 +337,7 @@ this.MaximizeBox = false; this.Name = "Datasheet"; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; - this.Text = "Datasheet"; + this.Text = "Config"; this.groupBox1.ResumeLayout(false); this.groupBox1.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.nudModbusID)).EndInit(); @@ -342,7 +364,6 @@ private System.Windows.Forms.Label label4; private System.Windows.Forms.Button buttonValve; private System.Windows.Forms.Label label5; - private System.Windows.Forms.Button button2; private System.Windows.Forms.Button buttonAlarm; private System.Windows.Forms.Label labelCleaning; private System.Windows.Forms.Button buttonCleaning; @@ -352,5 +373,8 @@ private System.Windows.Forms.Label label9; private System.Windows.Forms.Label label6; private System.Windows.Forms.Label labelBattery; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Label label8; + private System.Windows.Forms.ComboBox cBoxSpeed; } } \ No newline at end of file diff --git a/Datasheet.cs b/Datasheet.cs index 7dfc99d..83654e6 100644 --- a/Datasheet.cs +++ b/Datasheet.cs @@ -40,6 +40,17 @@ namespace Gidrolock_Modbus_Scanner this.modbusID = modbusID; this.device = device; + cBoxSpeed.Items.Add("1200"); + cBoxSpeed.Items.Add("2400"); + cBoxSpeed.Items.Add("4800"); + cBoxSpeed.Items.Add("9600"); + cBoxSpeed.Items.Add("14400"); + cBoxSpeed.Items.Add("19200"); + cBoxSpeed.Items.Add("38400"); + cBoxSpeed.Items.Add("57600"); + cBoxSpeed.Items.Add("115200"); + cBoxSpeed.Text = port.BaudRate.ToString(); + labelModel.Text = device.name; labelFirmware.Text = "v???"; @@ -67,10 +78,10 @@ namespace Gidrolock_Modbus_Scanner sensorPanel.Controls.Add(scenSen); scenSen.Visible = true; } - if (device.wiredSensors < device.sensorsAlarm.length) + if (device.wiredSensors < device.sensorAlarm.length) { wirelessSensors = new List(); - int wsrIndex = device.sensorsAlarm.length - device.wiredSensors - (device.hasScenarioSensor ? 1 : 0); + int wsrIndex = device.sensorAlarm.length - device.wiredSensors - (device.hasScenarioSensor ? 1 : 0); for (int i = 0; i < wsrIndex; i++) { WirelessSensor wsr = new WirelessSensor(i) { Width = 495, Height = 24 }; @@ -175,18 +186,50 @@ namespace Gidrolock_Modbus_Scanner } } - res = await PollEntry(device.sensorsAlarm); + res = await PollEntry(device.sensorAlarm); if (res) { BitArray bArray = new BitArray(latestMessage.Data); bool[] bools = new bool[bArray.Length]; bArray.CopyTo(bools, 0); - for (int i = 0; i < device.sensorsAlarm.length; i++) + for (int i = 0; i < sensorPanel.Controls.Count; i++) { Sensor snsr = sensorPanel.Controls[i] as Sensor; snsr.labelLeak.Text = bools[i] ? "Протечка!" : "нет"; } } + + res = await PollEntry(device.radioStatus); + if (res) + { + List values = new List(latestMessage.Data.Length / 2); + for (int i = 1; i < latestMessage.Data.Length; i += 2) + values.Add(latestMessage.Data[i]); + int add = device.wiredSensors + (device.hasScenarioSensor ? 1 : 0); + for (int i = 0; i < sensorPanel.Controls.Count; i++) + { + + WirelessSensor snsr = sensorPanel.Controls[i + add] as WirelessSensor; + string txt = "нет"; + switch (values[i]) + { + case 1: + txt = "норма"; + break; + case 2: + txt = "протечка"; + break; + case 3: + txt = "разряжен"; + break; + case 4: + txt = "потеря"; + break; + } + snsr.labelStatus.Text = txt; + } + } + } catch (Exception err) { MessageBox.Show(err.Message); } } @@ -316,8 +359,8 @@ namespace Gidrolock_Modbus_Scanner public Label labelBreakFluff = new Label() { Width = 45, Height = 24 }; public Label labelBreak = new Label() { Width = 55, Height = 24 }; // обрыв линии для WSP+ - public Label labelWSPPlusFluff = new Label() { Width = 45, Height = 24 }; - public CheckBox wspPlusCheckbox = new CheckBox() { Width = 20, Height = 20 }; + //public Label labelWSPPlusFluff = new Label() { Width = 45, Height = 24 }; + //public CheckBox wspPlusCheckbox = new CheckBox() { Width = 20, Height = 14 }; public WiredSensor(int count) { this.Margin = Padding.Empty; @@ -334,8 +377,8 @@ namespace Gidrolock_Modbus_Scanner this.Controls.Add(labelLeakFluff); this.Controls.Add(labelLeak); - this.Controls.Add(labelWSPPlusFluff); - this.Controls.Add(wspPlusCheckbox); + //this.Controls.Add(labelWSPPlusFluff); + //this.Controls.Add(wspPlusCheckbox); labelName.Text = "WSP " + (count + 1); @@ -345,15 +388,16 @@ namespace Gidrolock_Modbus_Scanner labelBreakFluff.Text = "Обрыв:"; labelBreak.Text = "неизвестно"; - labelWSPPlusFluff.Text = "WSP+:"; + //labelWSPPlusFluff.Text = "WSP+:"; + //wspPlusCheckbox.Margin = Padding.Empty; } } public class WirelessSensor : Sensor { - public Label labelBatteryFluff = new Label() { Width = 55, Height = 24 }; - public Label labelBattery = new Label() { Width = 45, Height = 24 }; + public Label labelStatusFluff = new Label() { Width = 45, Height = 24 }; + public Label labelStatus = new Label() { Width = 55, Height = 24 }; public WirelessSensor(int count) { @@ -364,8 +408,8 @@ namespace Gidrolock_Modbus_Scanner this.WrapContents = false; this.Controls.Add(labelName); - this.Controls.Add(labelBatteryFluff); - this.Controls.Add(labelBattery); + this.Controls.Add(labelStatusFluff); + this.Controls.Add(labelStatus); this.Controls.Add(labelLeakFluff); this.Controls.Add(labelLeak); @@ -374,8 +418,8 @@ namespace Gidrolock_Modbus_Scanner labelLeakFluff.Text = "Протечка:"; labelLeak.Text = "неизвестно"; - labelBatteryFluff.Text = "Батарея:"; - labelBattery.Text = "???%"; + labelStatusFluff.Text = "Статус:"; + labelStatus.Text = "неизвестно"; } } diff --git a/Main.Designer.cs b/Main.Designer.cs index 3518854..4db9d5e 100644 --- a/Main.Designer.cs +++ b/Main.Designer.cs @@ -32,12 +32,14 @@ this.TextBox_Log = new System.Windows.Forms.TextBox(); this.UpDown_ModbusID = new System.Windows.Forms.NumericUpDown(); this.label2 = new System.Windows.Forms.Label(); - this.CBox_Ports = new System.Windows.Forms.ComboBox(); + this.cBoxPorts = new System.Windows.Forms.ComboBox(); this.label1 = new System.Windows.Forms.Label(); this.button1 = new System.Windows.Forms.Button(); this.cBoxDevice = new System.Windows.Forms.ComboBox(); this.label3 = new System.Windows.Forms.Label(); this.checkboxID = new System.Windows.Forms.CheckBox(); + this.cBoxSpeed = new System.Windows.Forms.ComboBox(); + this.label4 = new System.Windows.Forms.Label(); ((System.ComponentModel.ISupportInitialize)(this.UpDown_ModbusID)).BeginInit(); this.SuspendLayout(); // @@ -67,14 +69,14 @@ this.label2.TabIndex = 0; this.label2.Text = "Modbus ID"; // - // CBox_Ports + // cBoxPorts // - this.CBox_Ports.FormattingEnabled = true; - this.CBox_Ports.Location = new System.Drawing.Point(139, 24); - this.CBox_Ports.Name = "CBox_Ports"; - this.CBox_Ports.Size = new System.Drawing.Size(65, 21); - this.CBox_Ports.TabIndex = 1; - this.CBox_Ports.Text = "COM1"; + this.cBoxPorts.FormattingEnabled = true; + this.cBoxPorts.Location = new System.Drawing.Point(139, 24); + this.cBoxPorts.Name = "cBoxPorts"; + this.cBoxPorts.Size = new System.Drawing.Size(65, 21); + this.cBoxPorts.TabIndex = 1; + this.cBoxPorts.Text = "COM1"; // // label1 // @@ -123,16 +125,36 @@ this.checkboxID.UseVisualStyleBackColor = true; this.checkboxID.CheckedChanged += new System.EventHandler(this.checkboxID_CheckedChanged); // + // cBoxSpeed + // + this.cBoxSpeed.FormattingEnabled = true; + this.cBoxSpeed.Location = new System.Drawing.Point(210, 24); + this.cBoxSpeed.Name = "cBoxSpeed"; + this.cBoxSpeed.Size = new System.Drawing.Size(78, 21); + this.cBoxSpeed.TabIndex = 7; + this.cBoxSpeed.Text = "9600"; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(207, 7); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(55, 13); + this.label4.TabIndex = 6; + this.label4.Text = "Скорость"; + // // App // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(518, 226); + this.Controls.Add(this.cBoxSpeed); + this.Controls.Add(this.label4); this.Controls.Add(this.checkboxID); this.Controls.Add(this.label3); this.Controls.Add(this.cBoxDevice); this.Controls.Add(this.button1); - this.Controls.Add(this.CBox_Ports); + this.Controls.Add(this.cBoxPorts); this.Controls.Add(this.label1); this.Controls.Add(this.UpDown_ModbusID); this.Controls.Add(this.TextBox_Log); @@ -155,12 +177,14 @@ private System.Windows.Forms.TextBox TextBox_Log; private System.Windows.Forms.NumericUpDown UpDown_ModbusID; private System.Windows.Forms.Label label2; - private System.Windows.Forms.ComboBox CBox_Ports; + private System.Windows.Forms.ComboBox cBoxPorts; private System.Windows.Forms.Label label1; private System.Windows.Forms.Button button1; private System.Windows.Forms.Label label3; private System.Windows.Forms.CheckBox checkboxID; private System.Windows.Forms.ComboBox cBoxDevice; + private System.Windows.Forms.ComboBox cBoxSpeed; + private System.Windows.Forms.Label label4; } } diff --git a/Main.cs b/Main.cs index e8479bb..cc42e96 100644 --- a/Main.cs +++ b/Main.cs @@ -1,11 +1,8 @@ using System; using System.Collections.Generic; -using System.ComponentModel; -using System.Data; using System.Threading.Tasks; using System.Windows.Forms; using System.IO.Ports; -using Newtonsoft.Json; namespace Gidrolock_Modbus_Scanner { @@ -33,6 +30,17 @@ namespace Gidrolock_Modbus_Scanner this.UpDown_ModbusID.Value = 0; TextBox_Log.Text = "Приложение готово к работе."; + cBoxSpeed.Items.Add("1200"); + cBoxSpeed.Items.Add("2400"); + cBoxSpeed.Items.Add("4800"); + cBoxSpeed.Items.Add("9600"); + cBoxSpeed.Items.Add("14400"); + cBoxSpeed.Items.Add("19200"); + cBoxSpeed.Items.Add("38400"); + cBoxSpeed.Items.Add("57600"); + cBoxSpeed.Items.Add("115200"); + cBoxSpeed.SelectedIndex = 3; + cBoxDevice.Items.Add("Standard"); cBoxDevice.Items.Add("Premium Plus"); //cBoxDevice.Items.Add("Inteli"); @@ -70,15 +78,15 @@ namespace Gidrolock_Modbus_Scanner void Form1_Load(object sender, EventArgs e) { - CBox_Ports.Items.AddRange(SerialPort.GetPortNames()); - if (CBox_Ports.Items.Count > 0) - CBox_Ports.SelectedIndex = 0; + cBoxPorts.Items.AddRange(SerialPort.GetPortNames()); + if (cBoxPorts.Items.Count > 0) + cBoxPorts.SelectedIndex = 0; } #endregion private async void ButtonConnect_Click(object sender, EventArgs e) { - if (CBox_Ports.SelectedItem.ToString() == "COM1") + if (cBoxPorts.SelectedItem.ToString() == "COM1") { DialogResult res = MessageBox.Show("Выбран серийный порт COM1, который обычно является портом PS/2 или RS-232, не подключенным к Modbus устройству. Продолжить?", "Внимание", MessageBoxButtons.OKCancel); if (res == DialogResult.Cancel) @@ -98,8 +106,8 @@ namespace Gidrolock_Modbus_Scanner port.Close(); port.Handshake = Handshake.None; - port.PortName = CBox_Ports.Text; - port.BaudRate = 9600; + port.PortName = cBoxPorts.Text; + port.BaudRate = Int32.Parse(cBoxSpeed.Items[cBoxSpeed.SelectedIndex].ToString()); port.Parity = Parity.None; port.DataBits = 8; port.StopBits = StopBits.One; @@ -211,8 +219,8 @@ namespace Gidrolock_Modbus_Scanner void CBox_Ports_Click(object sender, EventArgs e) { - CBox_Ports.Items.Clear(); - CBox_Ports.Items.AddRange(SerialPort.GetPortNames()); + cBoxPorts.Items.Clear(); + cBoxPorts.Items.AddRange(SerialPort.GetPortNames()); } void OnResponseReceived(object sender, ModbusResponseEventArgs e) @@ -358,7 +366,7 @@ namespace Gidrolock_Modbus_Scanner d.wiredSensors = 2; d.hasScenarioSensor = true; - d.sensorsAlarm = new Entry(RegisterType.Discrete, 1343, 24); + d.sensorAlarm = new Entry(RegisterType.Discrete, 1343, 24); d.radioStatus = new Entry(RegisterType.Input, 1215, 21); @@ -382,7 +390,8 @@ namespace Gidrolock_Modbus_Scanner d.wiredSensors = 7; d.hasScenarioSensor = true; - d.sensorsAlarm = new Entry(RegisterType.Discrete, 1343, 29); + d.sensorAlarm = new Entry(RegisterType.Discrete, 1343, 29); + d.radioStatus = new Entry(RegisterType.Input, 1215, 21); break; case DeviceType.Premium: d.modelName = "Premium"; @@ -398,4 +407,6 @@ namespace Gidrolock_Modbus_Scanner public enum FunctionCode { ReadCoil = 1, ReadDiscrete = 2, ReadHolding = 3, ReadInput = 4, WriteCoil = 5, WriteRegister = 6, WriteMultCoils = 15, WriteMultRegisters = 16 }; //public enum SelectedPath { File, Folder }; + + public enum DeviceType { Standard, PremiumPlus, Inteli, Premium }; diff --git a/Model.cs b/Model.cs index 189d86f..03890ce 100644 --- a/Model.cs +++ b/Model.cs @@ -21,7 +21,7 @@ namespace Gidrolock_Modbus_Scanner public int wiredSensors; public bool hasScenarioSensor; - public Entry sensorsAlarm; + public Entry sensorAlarm; public List wiredLineBreak; diff --git a/screenshot-1.png b/screenshot-1.png new file mode 100644 index 0000000000000000000000000000000000000000..364f186b9f0bfa33f3968a23afcd56f91d59eec2 GIT binary patch literal 11915 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 O%J7M%6zzZM% literal 0 HcmV?d00001