* (Add) Pixel Editor: Erase drawing edits while hold Control (#63)
* (Add) Pixel Editor: When using diameters larger than 1px and when possible the cursor will show the associated drawing preview (#63)
* (Fix) Pixel Editor: Area px<sup>2</sup> to Diameter px (#63)
This commit is contained in:
Tiago Conceição
2020-09-19 01:56:02 +01:00
parent 1796a33925
commit f4e2ad4daa
5 changed files with 177 additions and 58 deletions
+4 -1
View File
@@ -1,8 +1,11 @@
# Changelog
## /09/2020 - v0.8.2.3
## 19/09/2020 - v0.8.2.3
* (Add) Tooltip for next and previous layer buttons with associated shortcut (#61)
* (Add) Pixel Editor: Erase drawing edits while hold Control (#63)
* (Add) Pixel Editor: When using diameters larger than 1px and when possible the cursor will show the associated drawing preview (#63)
* (Fix) Pixel Editor: Area px<sup>2</sup> to Diameter px (#63)
* (Fix) LGS: Some plugins and slicers use XY resolution information, while others are swapped, a auto swap will be performed when required (#59)
* (Fix) Global hotkeys prevent user from typing that key on controls (#62)
@@ -30,5 +30,10 @@ namespace UVtools.Core.Extensions
{
return size.Width * size.Height;
}
public static int GetMaximum(this Size size)
{
return Math.Max(size.Width, size.Height);
}
}
}
+47 -47
View File
@@ -61,6 +61,7 @@ namespace UVtools.GUI
this.statusBar = new System.Windows.Forms.StatusStrip();
this.mainTable = new System.Windows.Forms.TableLayoutPanel();
this.scCenter = new System.Windows.Forms.SplitContainer();
this.lbLayerImageTooltipOverlay = new UVtools.GUI.Controls.TransparentLabel();
this.pbLayer = new Cyotek.Windows.Forms.ImageBox();
this.tsLayer = new System.Windows.Forms.ToolStrip();
this.btnLayerImageExport = new System.Windows.Forms.ToolStripSplitButton();
@@ -248,6 +249,7 @@ namespace UVtools.GUI
this.panelLayerNavigation = new System.Windows.Forms.Panel();
this.pbTrackerIssues = new System.Windows.Forms.PictureBox();
this.lbActualLayer = new System.Windows.Forms.Label();
this.tbLayer = new UVtools.GUI.Controls.TrackBarEx();
this.lbInitialLayer = new System.Windows.Forms.Label();
this.panel2 = new System.Windows.Forms.Panel();
this.btnFindLayer = new System.Windows.Forms.Button();
@@ -258,8 +260,6 @@ namespace UVtools.GUI
this.toolTipInformation = new System.Windows.Forms.ToolTip(this.components);
this.layerScrollTimer = new System.Windows.Forms.Timer(this.components);
this.mouseHoldTimer = new System.Windows.Forms.Timer(this.components);
this.lbLayerImageTooltipOverlay = new UVtools.GUI.Controls.TransparentLabel();
this.tbLayer = new UVtools.GUI.Controls.TrackBarEx();
this.menu.SuspendLayout();
this.mainTable.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.scCenter)).BeginInit();
@@ -318,8 +318,8 @@ namespace UVtools.GUI
this.tlRight.SuspendLayout();
this.panelLayerNavigation.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pbTrackerIssues)).BeginInit();
this.panel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.tbLayer)).BeginInit();
this.panel2.SuspendLayout();
this.SuspendLayout();
//
// menu
@@ -608,6 +608,23 @@ namespace UVtools.GUI
this.scCenter.SplitterDistance = 730;
this.scCenter.TabIndex = 4;
//
// lbLayerImageTooltipOverlay
//
this.lbLayerImageTooltipOverlay.AutoSize = true;
this.lbLayerImageTooltipOverlay.BackColor = System.Drawing.Color.Transparent;
this.lbLayerImageTooltipOverlay.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.lbLayerImageTooltipOverlay.CausesValidation = false;
this.lbLayerImageTooltipOverlay.Location = new System.Drawing.Point(13, 37);
this.lbLayerImageTooltipOverlay.Name = "lbLayerImageTooltipOverlay";
this.lbLayerImageTooltipOverlay.Opacity = ((byte)(210));
this.lbLayerImageTooltipOverlay.Padding = new System.Windows.Forms.Padding(10);
this.lbLayerImageTooltipOverlay.Size = new System.Drawing.Size(80, 40);
this.lbLayerImageTooltipOverlay.TabIndex = 8;
this.lbLayerImageTooltipOverlay.Text = "Overlay";
this.lbLayerImageTooltipOverlay.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.lbLayerImageTooltipOverlay.TransparentBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
this.lbLayerImageTooltipOverlay.Visible = false;
//
// pbLayer
//
this.pbLayer.AllowDoubleClick = true;
@@ -1813,7 +1830,7 @@ namespace UVtools.GUI
//
this.nmPixelEditorDrawingThickness.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.nmPixelEditorDrawingThickness.Location = new System.Drawing.Point(108, 160);
this.nmPixelEditorDrawingThickness.Location = new System.Drawing.Point(125, 160);
this.nmPixelEditorDrawingThickness.Maximum = new decimal(new int[] {
200,
0,
@@ -1825,7 +1842,7 @@ namespace UVtools.GUI
0,
-2147483648});
this.nmPixelEditorDrawingThickness.Name = "nmPixelEditorDrawingThickness";
this.nmPixelEditorDrawingThickness.Size = new System.Drawing.Size(224, 24);
this.nmPixelEditorDrawingThickness.Size = new System.Drawing.Size(207, 24);
this.nmPixelEditorDrawingThickness.TabIndex = 32;
this.nmPixelEditorDrawingThickness.Value = new decimal(new int[] {
1,
@@ -1848,9 +1865,9 @@ namespace UVtools.GUI
| System.Windows.Forms.AnchorStyles.Right)));
this.cbPixelEditorDrawingLineType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cbPixelEditorDrawingLineType.FormattingEnabled = true;
this.cbPixelEditorDrawingLineType.Location = new System.Drawing.Point(108, 66);
this.cbPixelEditorDrawingLineType.Location = new System.Drawing.Point(125, 66);
this.cbPixelEditorDrawingLineType.Name = "cbPixelEditorDrawingLineType";
this.cbPixelEditorDrawingLineType.Size = new System.Drawing.Size(258, 26);
this.cbPixelEditorDrawingLineType.Size = new System.Drawing.Size(241, 26);
this.cbPixelEditorDrawingLineType.TabIndex = 30;
//
// label17
@@ -1879,7 +1896,7 @@ namespace UVtools.GUI
// label16
//
this.label16.AutoSize = true;
this.label16.Location = new System.Drawing.Point(114, 217);
this.label16.Location = new System.Drawing.Point(131, 217);
this.label16.Name = "label16";
this.label16.Size = new System.Drawing.Size(49, 18);
this.label16.TabIndex = 9;
@@ -1889,7 +1906,7 @@ namespace UVtools.GUI
//
this.nmPixelEditorDrawingLayersBelow.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.nmPixelEditorDrawingLayersBelow.Location = new System.Drawing.Point(108, 190);
this.nmPixelEditorDrawingLayersBelow.Location = new System.Drawing.Point(125, 190);
this.nmPixelEditorDrawingLayersBelow.Maximum = new decimal(new int[] {
65535,
0,
@@ -1914,15 +1931,15 @@ namespace UVtools.GUI
this.label6.AutoSize = true;
this.label6.Location = new System.Drawing.Point(338, 133);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(28, 18);
this.label6.Size = new System.Drawing.Size(23, 18);
this.label6.TabIndex = 6;
this.label6.Text = "px²";
this.label6.Text = "px";
//
// nmPixelEditorDrawingBrushSize
//
this.nmPixelEditorDrawingBrushSize.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.nmPixelEditorDrawingBrushSize.Location = new System.Drawing.Point(108, 130);
this.nmPixelEditorDrawingBrushSize.Location = new System.Drawing.Point(125, 130);
this.nmPixelEditorDrawingBrushSize.Maximum = new decimal(new int[] {
200,
0,
@@ -1934,7 +1951,7 @@ namespace UVtools.GUI
0,
0});
this.nmPixelEditorDrawingBrushSize.Name = "nmPixelEditorDrawingBrushSize";
this.nmPixelEditorDrawingBrushSize.Size = new System.Drawing.Size(224, 24);
this.nmPixelEditorDrawingBrushSize.Size = new System.Drawing.Size(207, 24);
this.nmPixelEditorDrawingBrushSize.TabIndex = 5;
this.nmPixelEditorDrawingBrushSize.Value = new decimal(new int[] {
1,
@@ -1947,9 +1964,9 @@ namespace UVtools.GUI
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(7, 133);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(84, 18);
this.label3.Size = new System.Drawing.Size(112, 18);
this.label3.TabIndex = 4;
this.label3.Text = "Brush area:";
this.label3.Text = "Brush diameter:";
//
// panel3
//
@@ -1986,9 +2003,9 @@ namespace UVtools.GUI
| System.Windows.Forms.AnchorStyles.Right)));
this.cbPixelEditorDrawingBrushShape.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cbPixelEditorDrawingBrushShape.FormattingEnabled = true;
this.cbPixelEditorDrawingBrushShape.Location = new System.Drawing.Point(108, 98);
this.cbPixelEditorDrawingBrushShape.Location = new System.Drawing.Point(125, 98);
this.cbPixelEditorDrawingBrushShape.Name = "cbPixelEditorDrawingBrushShape";
this.cbPixelEditorDrawingBrushShape.Size = new System.Drawing.Size(258, 26);
this.cbPixelEditorDrawingBrushShape.Size = new System.Drawing.Size(241, 26);
this.cbPixelEditorDrawingBrushShape.TabIndex = 0;
this.cbPixelEditorDrawingBrushShape.SelectedIndexChanged += new System.EventHandler(this.EventSelectedIndexChanged);
//
@@ -2755,6 +2772,18 @@ namespace UVtools.GUI
this.lbActualLayer.TabIndex = 9;
this.lbActualLayer.Text = "?";
//
// tbLayer
//
this.tbLayer.Dock = System.Windows.Forms.DockStyle.Right;
this.tbLayer.Location = new System.Drawing.Point(93, 0);
this.tbLayer.Margin = new System.Windows.Forms.Padding(0);
this.tbLayer.Name = "tbLayer";
this.tbLayer.Orientation = System.Windows.Forms.Orientation.Vertical;
this.tbLayer.Size = new System.Drawing.Size(45, 557);
this.tbLayer.TabIndex = 8;
this.tbLayer.TickStyle = System.Windows.Forms.TickStyle.TopLeft;
this.tbLayer.ValueChanged += new System.EventHandler(this.ValueChanged);
//
// lbInitialLayer
//
this.lbInitialLayer.Dock = System.Windows.Forms.DockStyle.Fill;
@@ -2845,35 +2874,6 @@ namespace UVtools.GUI
this.mouseHoldTimer.Interval = 1000;
this.mouseHoldTimer.Tick += new System.EventHandler(this.EventTimerTick);
//
// lbLayerImageTooltipOverlay
//
this.lbLayerImageTooltipOverlay.AutoSize = true;
this.lbLayerImageTooltipOverlay.BackColor = System.Drawing.Color.Transparent;
this.lbLayerImageTooltipOverlay.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.lbLayerImageTooltipOverlay.CausesValidation = false;
this.lbLayerImageTooltipOverlay.Location = new System.Drawing.Point(13, 37);
this.lbLayerImageTooltipOverlay.Name = "lbLayerImageTooltipOverlay";
this.lbLayerImageTooltipOverlay.Opacity = ((byte)(210));
this.lbLayerImageTooltipOverlay.Padding = new System.Windows.Forms.Padding(10);
this.lbLayerImageTooltipOverlay.Size = new System.Drawing.Size(80, 40);
this.lbLayerImageTooltipOverlay.TabIndex = 8;
this.lbLayerImageTooltipOverlay.Text = "Overlay";
this.lbLayerImageTooltipOverlay.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.lbLayerImageTooltipOverlay.TransparentBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
this.lbLayerImageTooltipOverlay.Visible = false;
//
// tbLayer
//
this.tbLayer.Dock = System.Windows.Forms.DockStyle.Right;
this.tbLayer.Location = new System.Drawing.Point(93, 0);
this.tbLayer.Margin = new System.Windows.Forms.Padding(0);
this.tbLayer.Name = "tbLayer";
this.tbLayer.Orientation = System.Windows.Forms.Orientation.Vertical;
this.tbLayer.Size = new System.Drawing.Size(45, 557);
this.tbLayer.TabIndex = 8;
this.tbLayer.TickStyle = System.Windows.Forms.TickStyle.TopLeft;
this.tbLayer.ValueChanged += new System.EventHandler(this.ValueChanged);
//
// FrmMain
//
this.AllowDrop = true;
@@ -2980,8 +2980,8 @@ namespace UVtools.GUI
this.panelLayerNavigation.ResumeLayout(false);
this.panelLayerNavigation.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pbTrackerIssues)).EndInit();
this.panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.tbLayer)).EndInit();
this.panel2.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
+120 -9
View File
@@ -11,6 +11,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
@@ -1490,7 +1491,7 @@ namespace UVtools.GUI
btnLayerROI.Enabled = !roi.IsEmpty;
}
private void pbLayer_Zoomed(object sender, Cyotek.Windows.Forms.ImageBoxZoomEventArgs e)
private void pbLayer_Zoomed(object sender, ImageBoxZoomEventArgs e)
{
if (SupressLayerZoomEvent) return;
AddLogVerbose($"Zoomed from {e.OldZoom} to {e.NewZoom}");
@@ -1506,6 +1507,11 @@ namespace UVtools.GUI
tsLayerImageZoomLock.Visible = false;
}
if (pbLayer.Cursor.Tag is string str || ReferenceEquals(pbLayer.Cursor, pixelEditCursor))
{
UpdatePixelEditorCursor();
}
// Refresh the layer to properly render the crosshair at various zoom transitions
if (btnLayerImageShowCrosshairs.Checked &&
!ReferenceEquals(Issues, null) &&
@@ -1557,14 +1563,16 @@ namespace UVtools.GUI
}
if ((ModifierKeys & Keys.Shift) == 0) return;
if (_lastPixelMouseLocation == e.Location) return;
_lastPixelMouseLocation = e.Location;
if (_lastPixelMouseLocation == location) return;
_lastPixelMouseLocation = location;
// Bail here if we're not in a draw operation, if the mouse button is not either
// left or right, or if the location of the mouse pointer is not within the image.
if (tabControlPixelEditor.SelectedIndex != (int) PixelOperation.PixelOperationType.Drawing) return;
if (!btnLayerImagePixelEdit.Checked || (e.Button & MouseButtons.Middle) != 0) return;
if (!pbLayer.IsPointInImage(e.Location)) return;
//if (!pbLayer.IsPointInImage(e.Location)) return;
if (e.Button == MouseButtons.Right)
{
@@ -2814,8 +2822,8 @@ namespace UVtools.GUI
{
// This event repeats for as long as the key is pressed, so if we've
// already set the cursor from a previous key down event, just return.
if (pbLayer.Cursor == pixelEditCursor || pbLayer.Cursor == Cursors.Cross
|| pbLayer.Cursor == Cursors.Hand || pbLayer.SelectionMode == ImageBoxSelectionMode.Rectangle) return;
if (!ReferenceEquals(pbLayer.Cursor.Tag, null) || pbLayer.Cursor == pixelEditCursor || pbLayer.Cursor == Cursors.Cross
|| pbLayer.Cursor == Cursors.Hand || pbLayer.SelectionMode == ImageBoxSelectionMode.Rectangle) return;
// Pixel Edit is active, Shift is down, and the cursor is over the image region.
if (pbLayer.ClientRectangle.Contains(pbLayer.PointToClient(MousePosition)))
@@ -2824,10 +2832,12 @@ namespace UVtools.GUI
{
if (btnLayerImagePixelEdit.Checked)
{
pbLayer.Cursor = pixelEditCursor;
pbLayer.PanMode = ImageBoxPanMode.None;
lbLayerImageTooltipOverlay.Text = "Pixel editing is on:\n" +
"» Click over a pixel to draw";
"» Click over a pixel to draw\n" +
"» Hold CTRL to clear pixels";
UpdatePixelEditorCursor();
}
else
{
@@ -2868,7 +2878,7 @@ namespace UVtools.GUI
// of which form has focus when shift is released.
if (ReferenceEquals(sender, this))
{
if (e.KeyCode == Keys.ShiftKey || e.KeyCode == Keys.ControlKey)
if (e.KeyCode == Keys.ShiftKey || ((ModifierKeys & Keys.Shift) == 0 && e.KeyCode == Keys.ControlKey))
{
pbLayer.Cursor = Cursors.Default;
pbLayer.PanMode = ImageBoxPanMode.Left;
@@ -3346,6 +3356,19 @@ namespace UVtools.GUI
//var point = pbLayer.PointToImage(location);
Point realLocation = GetTransposedPoint(location);
if ((ModifierKeys & Keys.Control) != 0)
{
var removedItems = PixelHistory.Items.RemoveAll(item =>
{
Rectangle rect = new Rectangle(item.Location, item.Size);
rect.X -= item.Size.Width / 2;
rect.Y -= item.Size.Height / 2;
return rect.Contains(realLocation);
});
if(removedItems > 0) ShowLayer();
return;
}
PixelOperation operation = null;
Bitmap bmp = pbLayer.Image as Bitmap;
@@ -4306,6 +4329,94 @@ namespace UVtools.GUI
return true;
}
readonly SolidBrush _pixelEditorCursorBrush = new SolidBrush(Color.FromArgb(150, 120, 255, 255));
const byte _pixelEditorCursorMinDiamater = 10;
public void UpdatePixelEditorCursor()
{
Bitmap bitmap = null;
if (tabControlPixelEditor.SelectedIndex == (byte)PixelOperation.PixelOperationType.Drawing)
{
PixelDrawing.BrushShapeType shapeType =
(PixelDrawing.BrushShapeType)cbPixelEditorDrawingBrushShape.SelectedIndex;
ushort brushSize = (ushort)nmPixelEditorDrawingBrushSize.Value;
short thickness = (short)(nmPixelEditorDrawingThickness.Value == 0
? 1
: nmPixelEditorDrawingThickness.Value);
int diameter = (brushSize * pbLayer.Zoom / 100);
if (brushSize > 1 && diameter >= _pixelEditorCursorMinDiamater)
{
bitmap = new Bitmap(diameter, diameter, PixelFormat.Format32bppArgb);
using (Graphics gr = Graphics.FromImage(bitmap))
{
gr.SmoothingMode = SmoothingMode.AntiAlias;
gr.CompositingMode = CompositingMode.SourceCopy;
switch (shapeType)
{
case PixelDrawing.BrushShapeType.Rectangle:
if (thickness >= 1)
{
gr.DrawRectangle(new Pen(_pixelEditorCursorBrush, thickness), 0, 0, diameter, diameter);
}
else
{
gr.FillRectangle(_pixelEditorCursorBrush, 0, 0, diameter, diameter);
}
break;
case PixelDrawing.BrushShapeType.Circle:
if (thickness >= 1)
{
gr.DrawEllipse(new Pen(_pixelEditorCursorBrush, thickness), 0, 0, diameter, diameter);
}
else
{
gr.FillEllipse(_pixelEditorCursorBrush, 0, 0, diameter, diameter);
}
break;
}
}
}
}
/*else if (tabControlPixelEditor.SelectedIndex == (byte)PixelOperation.PixelOperationType.Text)
{
var text = tbPixelEditorTextText.Text;
if (string.IsNullOrEmpty(text) || nmPixelEditorTextFontScale.Value < 0.2m) return;
LineType lineType = (LineType)cbPixelEditorTextLineType.SelectedItem;
FontFace fontFace = (FontFace)cbPixelEditorTextFontFace.SelectedItem;
double scale = (double) nmPixelEditorTextFontScale.Value * pbLayer.Zoom / 100;
int thickness = (int) nmPixelEditorTextThickness.Value;
int baseLine = 0;
var size = CvInvoke.GetTextSize(text, fontFace, scale, thickness, ref baseLine);
mat = new Mat(size, DepthType.Cv8U, 4);
CvInvoke.PutText(mat, text, new Point(0,0), fontFace, scale, new MCvScalar(255,100,255, 255), thickness, lineType, cbPixelEditorTextMirror.Checked);
}*/
else if (tabControlPixelEditor.SelectedIndex == (byte)PixelOperation.PixelOperationType.Supports || tabControlPixelEditor.SelectedIndex == (byte)PixelOperation.PixelOperationType.DrainHole)
{
var diameter = (int)(
(tabControlPixelEditor.SelectedIndex == (byte)PixelOperation.PixelOperationType.Supports ?
nmPixelEditorSupportsTipDiameter.Value : nmPixelEditorDrainHoleDiameter.Value)
* pbLayer.Zoom / 100);
if (diameter >= _pixelEditorCursorMinDiamater)
{
bitmap = new Bitmap(diameter, diameter, PixelFormat.Format32bppArgb);
using (Graphics gr = Graphics.FromImage(bitmap))
{
gr.SmoothingMode = SmoothingMode.AntiAlias;
gr.CompositingMode = CompositingMode.SourceCopy;
gr.FillEllipse(_pixelEditorCursorBrush, 0, 0, diameter, diameter);
}
}
}
pbLayer.Cursor = bitmap is null ? pixelEditCursor : new Cursor(bitmap.GetHicon()) { Tag = "Custom" };
}
public bool CanGlobalHotKey
=> !(ActiveControl is TextBox
|| ActiveControl is ComboBox
+1 -1
View File
@@ -174,7 +174,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABk
FAAAAk1TRnQBSQFMAgEBBgEAARABDAEQAQwBEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
FAAAAk1TRnQBSQFMAgEBBgEAARgBDAEYAQwBEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
AwABIAMAAQEBAAEgBgABIC4AAxgBIgMwAUsDMAFMAzIBUDMAAQEDJAE2AysBQqwAAyIBMQNWAbkDXQHi
AwAB/wMAAf8BKgEtASgB/gNTAawDTQGVAwABARgAAwkBDAMzAVIDUAGdA1cB6AMAAf4DKwH8Ay8BSqQA
AyEBMANZAewBKwEuASkB+gNRAfcDUgH0A1MB8QNIAfYDQQH5AwAB/wNPAZsDAAEBCAADFQEdAz8BbgNV