From 2ec642927020ec03c91dd3c8047fd09f389250d5 Mon Sep 17 00:00:00 2001 From: Jaex Date: Mon, 24 Apr 2023 23:14:38 +0300 Subject: [PATCH] ImageBeautifierForm improvements --- .../Forms/ImageBeautifierForm.Designer.cs | 101 ++++++- ShareX.MediaLib/Forms/ImageBeautifierForm.cs | 54 +++- .../Properties/Resources.Designer.cs | 52 +++- ShareX.MediaLib/Properties/Resources.resx | 259 ++++++++++-------- ShareX.MediaLib/Resources/disk-black.png | Bin 0 -> 433 bytes ShareX.MediaLib/Resources/disks-black.png | Bin 0 -> 516 bytes ShareX.MediaLib/Resources/document-copy.png | Bin 0 -> 564 bytes ShareX.MediaLib/Resources/printer.png | Bin 0 -> 722 bytes ShareX.MediaLib/Resources/upload-cloud.png | Bin 0 -> 1541 bytes ShareX.MediaLib/ShareX.MediaLib.csproj | 15 + ShareX/TaskHelpers.cs | 11 +- 11 files changed, 359 insertions(+), 133 deletions(-) create mode 100644 ShareX.MediaLib/Resources/disk-black.png create mode 100644 ShareX.MediaLib/Resources/disks-black.png create mode 100644 ShareX.MediaLib/Resources/document-copy.png create mode 100644 ShareX.MediaLib/Resources/printer.png create mode 100644 ShareX.MediaLib/Resources/upload-cloud.png diff --git a/ShareX.MediaLib/Forms/ImageBeautifierForm.Designer.cs b/ShareX.MediaLib/Forms/ImageBeautifierForm.Designer.cs index 777e51e90..845e6ccb5 100644 --- a/ShareX.MediaLib/Forms/ImageBeautifierForm.Designer.cs +++ b/ShareX.MediaLib/Forms/ImageBeautifierForm.Designer.cs @@ -43,9 +43,14 @@ private void InitializeComponent() this.lblRoundedCornerValue = new System.Windows.Forms.Label(); this.lblShadowSizeValue = new System.Windows.Forms.Label(); this.tlpMain = new System.Windows.Forms.TableLayoutPanel(); - this.pOptions = new System.Windows.Forms.Panel(); - this.pbBackground = new System.Windows.Forms.PictureBox(); this.pbPreview = new ShareX.HelpersLib.MyPictureBox(); + this.pOptions = new System.Windows.Forms.Panel(); + this.btnPrint = new System.Windows.Forms.Button(); + this.btnSave = new System.Windows.Forms.Button(); + this.btnUpload = new System.Windows.Forms.Button(); + this.btnSaveAs = new System.Windows.Forms.Button(); + this.btnCopy = new System.Windows.Forms.Button(); + this.pbBackground = new System.Windows.Forms.PictureBox(); ((System.ComponentModel.ISupportInitialize)(this.tbMargin)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.tbPadding)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.tbRoundedCorner)).BeginInit(); @@ -216,8 +221,28 @@ private void InitializeComponent() this.tlpMain.Size = new System.Drawing.Size(1384, 761); this.tlpMain.TabIndex = 15; // + // pbPreview + // + this.pbPreview.BackColor = System.Drawing.SystemColors.Window; + this.pbPreview.Dock = System.Windows.Forms.DockStyle.Fill; + this.pbPreview.DrawCheckeredBackground = true; + this.pbPreview.EnableRightClickMenu = true; + this.pbPreview.FullscreenOnClick = true; + this.pbPreview.Location = new System.Drawing.Point(335, 0); + this.pbPreview.Margin = new System.Windows.Forms.Padding(0); + this.pbPreview.Name = "pbPreview"; + this.pbPreview.PictureBoxBackColor = System.Drawing.SystemColors.Window; + this.pbPreview.ShowImageSizeLabel = true; + this.pbPreview.Size = new System.Drawing.Size(1049, 761); + this.pbPreview.TabIndex = 12; + // // pOptions // + this.pOptions.Controls.Add(this.btnPrint); + this.pOptions.Controls.Add(this.btnSave); + this.pOptions.Controls.Add(this.btnUpload); + this.pOptions.Controls.Add(this.btnSaveAs); + this.pOptions.Controls.Add(this.btnCopy); this.pOptions.Controls.Add(this.pbBackground); this.pOptions.Controls.Add(this.lblMargin); this.pOptions.Controls.Add(this.lblShadowSizeValue); @@ -239,6 +264,60 @@ private void InitializeComponent() this.pOptions.Size = new System.Drawing.Size(329, 755); this.pOptions.TabIndex = 0; // + // btnPrint + // + this.btnPrint.Image = global::ShareX.MediaLib.Properties.Resources.printer; + this.btnPrint.Location = new System.Drawing.Point(264, 696); + this.btnPrint.Name = "btnPrint"; + this.btnPrint.Size = new System.Drawing.Size(56, 48); + this.btnPrint.TabIndex = 19; + this.btnPrint.UseVisualStyleBackColor = true; + this.btnPrint.Click += new System.EventHandler(this.btnPrint_Click); + // + // btnSave + // + this.btnSave.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnSave.Image = global::ShareX.MediaLib.Properties.Resources.disk_black; + this.btnSave.Location = new System.Drawing.Point(72, 696); + this.btnSave.Name = "btnSave"; + this.btnSave.Size = new System.Drawing.Size(56, 48); + this.btnSave.TabIndex = 18; + this.btnSave.UseVisualStyleBackColor = true; + this.btnSave.Click += new System.EventHandler(this.btnSave_Click); + // + // btnUpload + // + this.btnUpload.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnUpload.Image = global::ShareX.MediaLib.Properties.Resources.upload_cloud; + this.btnUpload.Location = new System.Drawing.Point(200, 696); + this.btnUpload.Name = "btnUpload"; + this.btnUpload.Size = new System.Drawing.Size(56, 48); + this.btnUpload.TabIndex = 17; + this.btnUpload.UseVisualStyleBackColor = true; + this.btnUpload.Click += new System.EventHandler(this.btnUpload_Click); + // + // btnSaveAs + // + this.btnSaveAs.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnSaveAs.Image = global::ShareX.MediaLib.Properties.Resources.disks_black; + this.btnSaveAs.Location = new System.Drawing.Point(136, 696); + this.btnSaveAs.Name = "btnSaveAs"; + this.btnSaveAs.Size = new System.Drawing.Size(56, 48); + this.btnSaveAs.TabIndex = 16; + this.btnSaveAs.UseVisualStyleBackColor = true; + this.btnSaveAs.Click += new System.EventHandler(this.btnSaveAs_Click); + // + // btnCopy + // + this.btnCopy.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnCopy.Image = global::ShareX.MediaLib.Properties.Resources.document_copy; + this.btnCopy.Location = new System.Drawing.Point(8, 696); + this.btnCopy.Name = "btnCopy"; + this.btnCopy.Size = new System.Drawing.Size(56, 48); + this.btnCopy.TabIndex = 15; + this.btnCopy.UseVisualStyleBackColor = true; + this.btnCopy.Click += new System.EventHandler(this.btnCopy_Click); + // // pbBackground // this.pbBackground.Cursor = System.Windows.Forms.Cursors.Hand; @@ -249,18 +328,6 @@ private void InitializeComponent() this.pbBackground.TabStop = false; this.pbBackground.Click += new System.EventHandler(this.pbBackground_Click); // - // pbPreview - // - this.pbPreview.BackColor = System.Drawing.SystemColors.Window; - this.pbPreview.Dock = System.Windows.Forms.DockStyle.Fill; - this.pbPreview.DrawCheckeredBackground = true; - this.pbPreview.Location = new System.Drawing.Point(335, 0); - this.pbPreview.Margin = new System.Windows.Forms.Padding(0); - this.pbPreview.Name = "pbPreview"; - this.pbPreview.PictureBoxBackColor = System.Drawing.SystemColors.Window; - this.pbPreview.Size = new System.Drawing.Size(1049, 761); - this.pbPreview.TabIndex = 12; - // // ImageBeautifierForm // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); @@ -269,6 +336,7 @@ private void InitializeComponent() this.Controls.Add(this.tlpMain); this.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.MinimumSize = new System.Drawing.Size(1000, 600); this.Name = "ImageBeautifierForm"; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; @@ -305,5 +373,10 @@ private void InitializeComponent() private System.Windows.Forms.Panel pOptions; private HelpersLib.MyPictureBox pbPreview; private System.Windows.Forms.PictureBox pbBackground; + private System.Windows.Forms.Button btnSave; + private System.Windows.Forms.Button btnUpload; + private System.Windows.Forms.Button btnSaveAs; + private System.Windows.Forms.Button btnCopy; + private System.Windows.Forms.Button btnPrint; } } \ No newline at end of file diff --git a/ShareX.MediaLib/Forms/ImageBeautifierForm.cs b/ShareX.MediaLib/Forms/ImageBeautifierForm.cs index 56a045e9e..551786926 100644 --- a/ShareX.MediaLib/Forms/ImageBeautifierForm.cs +++ b/ShareX.MediaLib/Forms/ImageBeautifierForm.cs @@ -36,12 +36,12 @@ public partial class ImageBeautifierForm : Form public Bitmap SourceImage { get; private set; } public Bitmap PreviewImage { get; private set; } public ImageBeautifierOptions Options { get; private set; } + public string FilePath { get; private set; } private bool isReady, isBusy, isPending; - public ImageBeautifierForm(Bitmap sourceImage, ImageBeautifierOptions options = null) + private ImageBeautifierForm(ImageBeautifierOptions options = null) { - SourceImage = sourceImage; Options = options; if (Options == null) @@ -63,6 +63,17 @@ public ImageBeautifierForm(Bitmap sourceImage, ImageBeautifierOptions options = isReady = true; } + public ImageBeautifierForm(Bitmap sourceImage, ImageBeautifierOptions options = null) : this(options) + { + SourceImage = sourceImage; + } + + public ImageBeautifierForm(string filePath, ImageBeautifierOptions options = null) : this(options) + { + FilePath = filePath; + SourceImage = ImageHelpers.LoadImage(filePath); + } + private void UpdateUI() { lblMarginValue.Text = tbMargin.Value.ToString(); @@ -190,6 +201,45 @@ private async void tbRoundedCorner_Scroll(object sender, EventArgs e) await UpdatePreview(); } + private void btnCopy_Click(object sender, EventArgs e) + { + if (PreviewImage != null) + { + ClipboardHelpers.CopyImage(PreviewImage); + } + } + + private void btnSave_Click(object sender, EventArgs e) + { + if (PreviewImage != null && !string.IsNullOrEmpty(FilePath)) + { + ImageHelpers.SaveImage(PreviewImage, FilePath); + } + } + + private void btnSaveAs_Click(object sender, EventArgs e) + { + if (PreviewImage != null) + { + string filePath = ImageHelpers.SaveImageFileDialog(PreviewImage, FilePath); + + if (!string.IsNullOrEmpty(filePath)) + { + FilePath = filePath; + } + } + } + + private void btnUpload_Click(object sender, EventArgs e) + { + + } + + private void btnPrint_Click(object sender, EventArgs e) + { + + } + private async void tbShadowSize_Scroll(object sender, EventArgs e) { await UpdatePreview(); diff --git a/ShareX.MediaLib/Properties/Resources.Designer.cs b/ShareX.MediaLib/Properties/Resources.Designer.cs index bbfdbc062..ee2475c0d 100644 --- a/ShareX.MediaLib/Properties/Resources.Designer.cs +++ b/ShareX.MediaLib/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace ShareX.MediaLib.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -114,6 +114,36 @@ internal class Resources { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap disk_black { + get { + object obj = ResourceManager.GetObject("disk-black", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap disks_black { + get { + object obj = ResourceManager.GetObject("disks-black", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap document_copy { + get { + object obj = ResourceManager.GetObject("document-copy", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized string similar to FFmpeg error. /// @@ -141,6 +171,16 @@ internal class Resources { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap printer { + get { + object obj = ResourceManager.GetObject("printer", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized string similar to Start encoding. /// @@ -168,6 +208,16 @@ internal class Resources { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap upload_cloud { + get { + object obj = ResourceManager.GetObject("upload-cloud", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized string similar to Browse for media file. /// diff --git a/ShareX.MediaLib/Properties/Resources.resx b/ShareX.MediaLib/Properties/Resources.resx index bffb2a598..39e948dc3 100644 --- a/ShareX.MediaLib/Properties/Resources.resx +++ b/ShareX.MediaLib/Properties/Resources.resx @@ -1,117 +1,146 @@  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 1.3 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Browse for media file + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\document-copy.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a Thumbnails successfully generated. - - Lower quality/size + + ..\Resources\disks-black.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Top + + + Stop encoding Higher quality/size - - Stop encoding + + Bottom + + + Right Start encoding @@ -119,22 +148,28 @@ FFmpeg error - - Top - - + Center - - Bottom + + ..\Resources\upload-cloud.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + Browse for media file Left - + Center - - Right + + Lower quality/size + + + ..\Resources\disk-black.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\printer.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a \ No newline at end of file diff --git a/ShareX.MediaLib/Resources/disk-black.png b/ShareX.MediaLib/Resources/disk-black.png new file mode 100644 index 0000000000000000000000000000000000000000..26507e51bf6ddc4dc3bb7c859ce1be402d5b5bc0 GIT binary patch literal 433 zcmV;i0Z#sjP)=6B{ zxULInnzl9IJpxj|IfupEX!(Z&?68y&Kk7cN^l%U2WhWcr_3Hf zGY6s@20XVP$MH{=Wx13}gUOZp_cpdmfH@bsHqBk2{SEpH0^bf55zl?U7y827TjSj8 b{3pNwM={yTe}a?Z00000NkvXXu0mjf{wBQ% literal 0 HcmV?d00001 diff --git a/ShareX.MediaLib/Resources/disks-black.png b/ShareX.MediaLib/Resources/disks-black.png new file mode 100644 index 0000000000000000000000000000000000000000..4089760effc65c61ec2240289c26aab74d3f4bc3 GIT binary patch literal 516 zcmV+f0{i`mP)ht7^I z)JWa5O3v`GSPwIN38p ztJmuU@m1XwST2`?ZucHDYmiJP!F63qpldR)1pf__>15n%7AizwiK0R{kru1xLUK|B2b0000VHn4sd+${IL2G1= z36bDf1};({2<28od(nRovpUHL z;qleyp6By^zrN22mSw?7sdNMY8?bsk8;0>^8U_S{L7telUO@kNh5Gv#BuZex=3}W; zo$5NwOcOLLHW4h#GCVXImslcTd^$vFdmmVGmw#vUfpo#bMiT+%YzDK*1jgerj7B4P zDwnJH{1D5MtK@NjuImCW5HW(11mE2*ytUiV>U7|`Qh}XBqB7|BZ?W_oW6KMWYye}} z%oy@e$q-LJ&SoK>$+(s-EUSo?ihfIT1)4^!Tmgrm|NmNY0fOC35c&hXmcoGmgm70B z1@3A!I7p=`Em=POvp@<6fC07*uO))eD&+G(Hx-RWq26q&Ef0;$np3N8JZ zeoSZTy(1sRDDfsI@6LVqoH=jq8!?~F;w*#^cWH^?@A1jD?E>LaQR(%1=MR(*z0PJ= zjdmLr)z9|w`8?ikZa(IB5O(_oB-^sk2O;PUR;Pnzqk($8j#{netnU{VR%!oE%P_82 zj*h?(r4l4*XU9n_5+Dd!2zV3)-hlxqlElZt@$oTUuB{q=hbR;IueOEwiP-?KO9#c55~sErWY3%XA6bGPN`J-teB=5 ziAJNNL`J1jfu?EB+NMcVt2J=F)oOwI5DteC3~Jcg+C?Csjxv`8^x@&*M7dlBDUv`C z`};*0MiUn!mf>>ABw{-~tyUL)|Fr~jrB0_4C4qQ@#&*QxsWf2Q3fWcR^=g+ONdr#L z`n`9E#S(GmDr7Z6mXo}}E|~1~s{j0m+%x%R67EnZ$y^rj_5cFgtSq7csdWi+x;vU3|jbo;l3gi3eiXc&;|#gPfacK{s@cC!!RwYXVS_& z+{+y1D(8QquA@<}7XuR$OIO(zl2jDbi@iPP`Ii6#0DvZ256 literal 0 HcmV?d00001 diff --git a/ShareX.MediaLib/Resources/upload-cloud.png b/ShareX.MediaLib/Resources/upload-cloud.png new file mode 100644 index 0000000000000000000000000000000000000000..911345a4b9998633a55727fd2aaee048b2ee6b63 GIT binary patch literal 1541 zcmaJ>eNfY89FD+s3R5_Dw-X&2%gQN2n>77OM#VH~p@T9k-GqsrX&c%IZEBLz7DYL> zn`6`A)KheGQ)l(gKXmHO6{>=pQ*q)KgE^;ncx-z3F;Cfa%85%6kUw_jE_uJ6=lOlU zX(%qro0vE?5deUR=6upBjw!KsyhQxY=zm6uL#kjb6-w9&AwY37fIC?`4Vpcai?-5~ zGqkLo&H;dUhOw0jrItd>!FuFW3?mPEd?FhFa&m({%27!Rpq+LxUcK~Qv{ec+PQ7%2 z+5%a81np+>YdE^3rpV@~sdS)DY3^JwCy0px9$KKlpr^{qV?n)iNEZ|5v2BGE9D)dy zdg*hgN-f18!E!XHmP6SNNCSZySPmm9tyY@_Dj^tBKuQIy%!aiXqQoEw9DbytHO^Uq zSxM8dEpernx&^_9DHMS~KpsHkEay_dD2m23l*()okljLR+XqvBqEI9X!a6hX?TfaQ>a8^Xlm8(~>2FK2i>qi9~R z(l4CaAy%;>eT=D>8;SvkW56sFS4oRiG*MMNJ#=8PU?l7CduXp< zCiPMgDt9tY3_%bAF~B&fR+BJngiwPDH=(FjNfIbxf=nY^vzHeruY(@pGB3F3OSu@q z(Uib)HkPd#X@+7qE3mwq^?^hQ0xn>@PBy^D>Lhv<^ONS7YT9YySPwXqGK?8x-R~Do z;{1WBh&~Akvg?OZ9t^MMCX{0hlm79A}Um)QQ-(diV+(i9d0lf z2$KocDq*!osu0~!#QI}Qzl>~&O&FVwcE7k7y+5>9OgAUqj%F>~0041HGl|=RS5A~f zD}P^-lB+*9b*a65ecBt;hJ@Dwv%?8k)02x;J1);GOFT2VMabX%OTl2niG|&ht`&Y{ zh?f;in3USG(eQm{#=dK(L$frI1G2JBUH7hH9Tz%?TwUK^fk10?VEUSyA?Td_q^xK2 zro(l;k%f;B?JBL}%GSrFsF*){Op0 zB+_Iv&VO@vU!5np=T713qemMDn%13n@jIs^oVs5}0Y6Y%c6Ije-Q9KO$j;Mql9JxB z;VBKbYuXNGZEGGEjfS`N_g9RYu=m~C<+V?Ls{AZzew?H{0IY2NdVGCuha~P%=Z9C* z?^eH(^|R#1NWK03-J-BnAw(C=!_y9!dh4&eE?^n5Wqszz*^1#-I zX&Yv&8DE_DYVDK{4$L~bxbeEBle^H?y<+b4ii(X1{v&%ltKQOgtxi9CE^~iMUf-hu zq4CajeOvj%KX%o)r+l<_JM~?ix5(}wI@%wQJG+*SOT6{*j%3HmQ&TlJl*fBI8=9Lh z7Z|sk{Whz2TH2!UgWh%Lj;*c9nLg)4??u)KcUMyZ?R3!2AfW1{3~k%j-krg TDU#2Z$9~LaV-dN}u%!M!d@M + + + + + + + + + + + + + + +