From ad30c13d3d06132c3f88693d389558220262c2f5 Mon Sep 17 00:00:00 2001 From: Stewie Date: Tue, 7 Jan 2025 18:29:12 -0500 Subject: [PATCH] Fix issue with NDX Extract and add Hearts font --- TranslationApp/TextPreview.cs | 264 +++++++++++++++++++++++++- TranslationApp/TranslationApp.csproj | 3 + TranslationApp/fMain.Designer.cs | 64 ++++--- TranslationApp/fMain.cs | 28 ++- TranslationApp/res/toh_font_atlas.png | Bin 0 -> 2288 bytes 5 files changed, 323 insertions(+), 36 deletions(-) create mode 100644 TranslationApp/res/toh_font_atlas.png diff --git a/TranslationApp/TextPreview.cs b/TranslationApp/TextPreview.cs index 04f7e38..a4ee114 100644 --- a/TranslationApp/TextPreview.cs +++ b/TranslationApp/TextPreview.cs @@ -8,6 +8,7 @@ using System.IO; using System.Linq; using System.Reflection; +using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; @@ -15,6 +16,7 @@ namespace TranslationApp { + public partial class TextPreview : PictureBox { public Bitmap fontAtlasImage { get; set; } @@ -252,6 +254,107 @@ public font_glyph(byte x, byte y) /* 。 */ new font_glyph(01, 12), }; + private readonly font_glyph[] toh_glyphs = new font_glyph[97] + { + /* */ new font_glyph(00, 18), + /* 0 */ new font_glyph(00, 13), + /* 1 */ new font_glyph(00, 19), + /* 2 */ new font_glyph(00, 13), + /* 3 */ new font_glyph(00, 13), + /* 4 */ new font_glyph(00, 13), + /* 5 */ new font_glyph(00, 13), + /* 6 */ new font_glyph(00, 13), + /* 7 */ new font_glyph(00, 13), + /* 8 */ new font_glyph(00, 13), + /* 9 */ new font_glyph(00, 13), + /* A */ new font_glyph(00, 13), + /* B */ new font_glyph(00, 13), + /* C */ new font_glyph(00, 13), + /* D */ new font_glyph(00, 13), + /* E */ new font_glyph(00, 13), + /* F */ new font_glyph(00, 13), + /* G */ new font_glyph(00, 13), + /* H */ new font_glyph(00, 13), + /* I */ new font_glyph(00, 13), + /* J */ new font_glyph(00, 21), + /* K */ new font_glyph(00, 13), + /* L */ new font_glyph(00, 13), + /* M */ new font_glyph(00, 13), + /* N */ new font_glyph(00, 13), + /* O */ new font_glyph(00, 13), + /* P */ new font_glyph(00, 13), + /* Q */ new font_glyph(00, 13), + /* R */ new font_glyph(00, 13), + /* S */ new font_glyph(00, 13), + /* T */ new font_glyph(00, 13), + /* U */ new font_glyph(00, 13), + /* V */ new font_glyph(00, 13), + /* W */ new font_glyph(00, 13), + /* X */ new font_glyph(00, 13), + /* Y */ new font_glyph(00, 13), + /* Z */ new font_glyph(00, 13), + /* a */ new font_glyph(00, 13), + /* b */ new font_glyph(00, 13), + /* c */ new font_glyph(00, 13), + /* d */ new font_glyph(00, 13), + /* e */ new font_glyph(00, 13), + /* f */ new font_glyph(00, 13), + /* g */ new font_glyph(00, 13), + /* h */ new font_glyph(00, 13), + /* i */ new font_glyph(00, 21), + /* j */ new font_glyph(00, 15), + /* k */ new font_glyph(00, 15), + /* l */ new font_glyph(00, 19), + /* m */ new font_glyph(00, 13), + /* n */ new font_glyph(00, 13), + /* o */ new font_glyph(00, 13), + /* p */ new font_glyph(00, 13), + /* q */ new font_glyph(00, 13), + /* r */ new font_glyph(00, 13), + /* s */ new font_glyph(00, 14), + /* t */ new font_glyph(00, 14), + /* u */ new font_glyph(00, 15), + /* v */ new font_glyph(00, 13), + /* w */ new font_glyph(00, 13), + /* x */ new font_glyph(00, 13), + /* y */ new font_glyph(00, 13), + /* z */ new font_glyph(00, 13), + /* , */ new font_glyph(00, 20), + /* . */ new font_glyph(00, 20), + /* ・ */ new font_glyph(00, 20), + /* : */ new font_glyph(00, 20), + /* ; */ new font_glyph(00, 20), + /* ? */ new font_glyph(00, 14), + /* ! */ new font_glyph(00, 22), + /* / */ new font_glyph(00, 14), + /* ( */ new font_glyph(00, 18), + /* ) */ new font_glyph(00, 18), + /* [ */ new font_glyph(00, 18), + /* ] */ new font_glyph(00, 18), + /* { */ new font_glyph(00, 16), + /* } */ new font_glyph(00, 16), + /* + */ new font_glyph(00, 14), + /* - */ new font_glyph(00, 20), + /* = */ new font_glyph(00, 14), + /* < */ new font_glyph(00, 18), + /* > */ new font_glyph(00, 18), + /* % */ new font_glyph(00, 14), + /* # */ new font_glyph(00, 14), + /* & */ new font_glyph(00, 14), + /* * */ new font_glyph(00, 14), + /* @ */ new font_glyph(00, 14), + /* | */ new font_glyph(00, 22), + /* ” */ new font_glyph(00, 18), + /* ’ */ new font_glyph(00, 22), + /* ^ */ new font_glyph(00, 16), + /* 「 */ new font_glyph(00, 18), + /* 」 */ new font_glyph(00, 18), + /* 〜 */ new font_glyph(00, 14), + /* _ */ new font_glyph(00, 14), + /* 、 */ new font_glyph(00, 20), + /* 。 */ new font_glyph(00, 16), + }; + private readonly font_glyph[] rm2_glyphs = new font_glyph[97] { /* */ new font_glyph(16, 00), @@ -381,6 +484,12 @@ public void ChangeImage(string id) BackColor = Color.FromArgb(0xA0, 0x0, 0x0, 0x0); glyphs = rm2_glyphs; break; + + case "TOH": + res = "TranslationApp.res.toh_font_atlas.png"; + BackColor = Color.FromArgb(0xA0, 0x0, 0x0, 0x0); + glyphs = toh_glyphs; + break; default: fontAtlasImage = null; glyphs = null; @@ -422,6 +531,7 @@ public void ReDraw(string text) Invalidate(); } + private void Raster() { // No image, no fun @@ -603,6 +713,158 @@ private void Raster() } } + + + + public string DoLineBreak(string text, int maxWidth) + { + List<(string Word, int Size)> words = GetListWords(text); + int sum = 0; + int i = 0; + string final = ""; + + if (maxWidth < words.Select(x => x.Size).Max()) + { + maxWidth = words.Select(x => x.Size).Max(); + + } + while (i < words.Count) + { + sum = 0; + List output = words.Select(x => sum += x.Size).ToList(); + List maxCount = Enumerable.Range(0, output.Count).Where(ind => output[ind] <= maxWidth).ToList(); + + string line = ""; + foreach (int c in maxCount) + line += words[c].Word; + + words.RemoveRange(0, maxCount.Count); + i += maxCount.Count; + final += (line + Environment.NewLine); + + + } + + return final; + + + } + + public string WordWrap(string text, int maxWidth) + { + Rectangle space = GetCharacterRectangleFromAtlas(' ', out int s, out bool add); + List<(string,int)> words = GetListWords(text); + + int curLineLength = 0; + StringBuilder strBuilder = new StringBuilder(); + foreach ((string word, int width) in words) + { + string finalWord = word; + // If adding the new word to the current line would be too long, + // then put it on a new line (and split it up if it's too long). + if (curLineLength + width > maxWidth) + { + // Only move down to a new line if we have text on the current line. + // Avoids situation where + // wrapped whitespace causes emptylines in text. + if (curLineLength > 0) + { + strBuilder.Append(Environment.NewLine); + curLineLength = 0; + } + + // Remove leading whitespace from the word, + // so the new line starts flush to the left. + finalWord = word.TrimStart(); + } + strBuilder.Append(word + " "); + curLineLength += (width + space.Width); + } + + return strBuilder.ToString(); + } + + public List<(string, int)> GetListWords(string text) + { + //Split tags and text + string[] result = Regex.Split(text.Replace("\r", ""), @"(<[\w/]+:?\w+>[,|.|\[||\]]*)", RegexOptions.IgnoreCase).Where(x => x != "").ToArray(); + Rectangle space = GetCharacterRectangleFromAtlas(' ', out int s, out bool add); + + string textToRender = ""; + bool shear = false; + List<(string Word, int Size)> wordsSize = new List<(string, int)>(); + + foreach (string element in result) + { + + int d = 0; + string tag = ""; + + int pos = element.IndexOf(">"); + if (pos > -1) + { + tag = element.Substring(0, pos+1); + + if (names.Contains(tag)) + { + textToRender = tag.Substring(1, pos - 1); + } + else if (element.StartsWith("") + { + shear = true; + continue; + } + else if (element == "") + { + shear = false; + continue; + } + else if (element.StartsWith(" x != "")) + { + + wordsSize.Add((word, GetWordWidth(word))); + wordsSize.Add((" ", space.Width)); + + } + } + + wordsSize.RemoveAt(wordsSize.Count - 1); + return wordsSize; + } + + private int GetWordWidth(string word) + { + int width = 0; + foreach (char c in word) { + Rectangle rect = GetCharacterRectangleFromAtlas(c, out int x, out bool b); + width += rect.Width; + } + + return width; + } private void TextPreview_Paint(object sender, PaintEventArgs e) { @@ -719,7 +981,7 @@ private Rectangle GetCharacterRectangleFromAtlas(int character, out int s, out b int y = index * charHeight; int x = glyphs[index].lskip; - charWidth -= glyphs[index].lskip; + charWidth -= (glyphs[index].lskip); s = glyphs[index].rskip; return new Rectangle(x, y, charWidth, charHeight); } diff --git a/TranslationApp/TranslationApp.csproj b/TranslationApp/TranslationApp.csproj index c169c66..85eab7e 100644 --- a/TranslationApp/TranslationApp.csproj +++ b/TranslationApp/TranslationApp.csproj @@ -186,6 +186,9 @@ + + + diff --git a/TranslationApp/fMain.Designer.cs b/TranslationApp/fMain.Designer.cs index beb1330..30b53d2 100644 --- a/TranslationApp/fMain.Designer.cs +++ b/TranslationApp/fMain.Designer.cs @@ -68,7 +68,6 @@ private void InitializeComponent() this.bSaveAll = new System.Windows.Forms.Button(); this.trackBarAlign = new System.Windows.Forms.TrackBar(); this.label7 = new System.Windows.Forms.Label(); - this.verticalLine = new System.Windows.Forms.Panel(); this.cbFileList = new System.Windows.Forms.ComboBox(); this.cbFileType = new System.Windows.Forms.ComboBox(); this.cbStatus = new System.Windows.Forms.ComboBox(); @@ -112,6 +111,8 @@ private void InitializeComponent() this.rightColumn = new System.Windows.Forms.Panel(); this.tabSearchMass = new System.Windows.Forms.TabControl(); this.tpSearch = new System.Windows.Forms.TabPage(); + this.tbWrap = new System.Windows.Forms.TextBox(); + this.tbMax = new System.Windows.Forms.TextBox(); this.cbMatchWhole = new System.Windows.Forms.CheckBox(); this.cbCase = new System.Windows.Forms.CheckBox(); this.lEntriesFound = new System.Windows.Forms.Label(); @@ -168,7 +169,7 @@ private void InitializeComponent() this.menuStripMain.Location = new System.Drawing.Point(0, 0); this.menuStripMain.Name = "menuStripMain"; this.menuStripMain.Padding = new System.Windows.Forms.Padding(4, 1, 0, 1); - this.menuStripMain.Size = new System.Drawing.Size(1047, 24); + this.menuStripMain.Size = new System.Drawing.Size(1301, 24); this.menuStripMain.TabIndex = 0; this.menuStripMain.Text = "menuStrip1"; // @@ -487,11 +488,12 @@ private void InitializeComponent() this.trackBarAlign.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.trackBarAlign.AutoSize = false; - this.trackBarAlign.Location = new System.Drawing.Point(283, 154); - this.trackBarAlign.Maximum = 30; + this.trackBarAlign.Location = new System.Drawing.Point(240, 353); + this.trackBarAlign.Maximum = 100; this.trackBarAlign.Name = "trackBarAlign"; - this.trackBarAlign.Size = new System.Drawing.Size(97, 26); + this.trackBarAlign.Size = new System.Drawing.Size(140, 28); this.trackBarAlign.TabIndex = 18; + this.trackBarAlign.Value = 100; this.trackBarAlign.ValueChanged += new System.EventHandler(this.trackBarAlign_ValueChanged); // // label7 @@ -503,16 +505,6 @@ private void InitializeComponent() this.label7.TabIndex = 19; this.label7.Text = "Text Align"; // - // verticalLine - // - this.verticalLine.BackColor = System.Drawing.SystemColors.ActiveCaptionText; - this.verticalLine.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.verticalLine.Location = new System.Drawing.Point(8, 202); - this.verticalLine.Margin = new System.Windows.Forms.Padding(0, 0, 3, 3); - this.verticalLine.Name = "verticalLine"; - this.verticalLine.Size = new System.Drawing.Size(2, 500); - this.verticalLine.TabIndex = 20; - // // cbFileList // this.cbFileList.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) @@ -945,7 +937,7 @@ private void InitializeComponent() this.rightColumn.Dock = System.Windows.Forms.DockStyle.Fill; this.rightColumn.Location = new System.Drawing.Point(712, 24); this.rightColumn.Name = "rightColumn"; - this.rightColumn.Size = new System.Drawing.Size(335, 709); + this.rightColumn.Size = new System.Drawing.Size(589, 709); this.rightColumn.TabIndex = 53; // // tabSearchMass @@ -959,11 +951,13 @@ private void InitializeComponent() this.tabSearchMass.Location = new System.Drawing.Point(4, 3); this.tabSearchMass.Name = "tabSearchMass"; this.tabSearchMass.SelectedIndex = 0; - this.tabSearchMass.Size = new System.Drawing.Size(328, 699); + this.tabSearchMass.Size = new System.Drawing.Size(582, 699); this.tabSearchMass.TabIndex = 50; // // tpSearch // + this.tpSearch.Controls.Add(this.tbWrap); + this.tpSearch.Controls.Add(this.tbMax); this.tpSearch.Controls.Add(this.cbMatchWhole); this.tpSearch.Controls.Add(this.cbCase); this.tpSearch.Controls.Add(this.lEntriesFound); @@ -979,11 +973,30 @@ private void InitializeComponent() this.tpSearch.Location = new System.Drawing.Point(4, 22); this.tpSearch.Name = "tpSearch"; this.tpSearch.Padding = new System.Windows.Forms.Padding(3); - this.tpSearch.Size = new System.Drawing.Size(320, 673); + this.tpSearch.Size = new System.Drawing.Size(574, 673); this.tpSearch.TabIndex = 0; this.tpSearch.Text = "Search"; this.tpSearch.UseVisualStyleBackColor = true; // + // tbWrap + // + this.tbWrap.Location = new System.Drawing.Point(321, 94); + this.tbWrap.Multiline = true; + this.tbWrap.Name = "tbWrap"; + this.tbWrap.Size = new System.Drawing.Size(224, 111); + this.tbWrap.TabIndex = 61; + // + // tbMax + // + this.tbMax.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tbMax.Location = new System.Drawing.Point(334, 47); + this.tbMax.Name = "tbMax"; + this.tbMax.Size = new System.Drawing.Size(166, 20); + this.tbMax.TabIndex = 60; + this.tbMax.Text = "500"; + this.tbMax.KeyDown += new System.Windows.Forms.KeyEventHandler(this.tbMax_KeyDown); + // // cbMatchWhole // this.cbMatchWhole.AutoSize = true; @@ -1108,7 +1121,7 @@ private void InitializeComponent() this.lbSearch.Location = new System.Drawing.Point(30, 211); this.lbSearch.Name = "lbSearch"; this.lbSearch.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; - this.lbSearch.Size = new System.Drawing.Size(261, 444); + this.lbSearch.Size = new System.Drawing.Size(515, 444); this.lbSearch.TabIndex = 0; this.lbSearch.Click += new System.EventHandler(this.lbSearch_Click); this.lbSearch.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.lbSearch_DrawItem); @@ -1126,7 +1139,7 @@ private void InitializeComponent() this.tpMassReplace.Location = new System.Drawing.Point(4, 22); this.tpMassReplace.Name = "tpMassReplace"; this.tpMassReplace.Padding = new System.Windows.Forms.Padding(3); - this.tpMassReplace.Size = new System.Drawing.Size(320, 673); + this.tpMassReplace.Size = new System.Drawing.Size(574, 673); this.tpMassReplace.TabIndex = 1; this.tpMassReplace.Text = "Other Translations"; this.tpMassReplace.UseVisualStyleBackColor = true; @@ -1214,7 +1227,6 @@ private void InitializeComponent() // // middleColumn // - this.middleColumn.Controls.Add(this.verticalLine); this.middleColumn.Controls.Add(this.pPreviewContainer); this.middleColumn.Controls.Add(this.tbFriendlyName); this.middleColumn.Controls.Add(this.lLineBreak); @@ -1271,11 +1283,11 @@ private void InitializeComponent() this.tbEnglishText.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.tbEnglishText.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.tbEnglishText.Location = new System.Drawing.Point(9, 353); + this.tbEnglishText.Location = new System.Drawing.Point(9, 387); this.tbEnglishText.Multiline = true; this.tbEnglishText.Name = "tbEnglishText"; this.tbEnglishText.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.tbEnglishText.Size = new System.Drawing.Size(372, 163); + this.tbEnglishText.Size = new System.Drawing.Size(372, 129); this.tbEnglishText.TabIndex = 6; this.tbEnglishText.TextPasted += new System.EventHandler(this.tbEnglishText_TextPasted); this.tbEnglishText.TextChanged += new System.EventHandler(this.tbEnglishText_TextChanged); @@ -1330,7 +1342,7 @@ private void InitializeComponent() // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1047, 733); + this.ClientSize = new System.Drawing.Size(1301, 733); this.Controls.Add(this.rightColumn); this.Controls.Add(this.splitter2); this.Controls.Add(this.middleColumn); @@ -1342,7 +1354,6 @@ private void InitializeComponent() this.Name = "fMain"; this.Text = "Translation App"; this.Load += new System.EventHandler(this.fMain_Load); - this.Paint += new System.Windows.Forms.PaintEventHandler(this.fMain_Paint); this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.fMain_KeyDown); this.Resize += new System.EventHandler(this.fMain_Resize); this.menuStripMain.ResumeLayout(false); @@ -1393,7 +1404,6 @@ private void InitializeComponent() private System.Windows.Forms.Button bSaveAll; private System.Windows.Forms.TrackBar trackBarAlign; private System.Windows.Forms.Label label7; - private System.Windows.Forms.Panel verticalLine; private System.Windows.Forms.ComboBox cbFileList; private System.Windows.Forms.ComboBox cbFileType; private System.Windows.Forms.ToolStripMenuItem tsNDXExtract; @@ -1487,6 +1497,8 @@ private void InitializeComponent() private System.Windows.Forms.Splitter splitter2; private System.Windows.Forms.ToolStripMenuItem fontToolStripMenuItem; private System.Windows.Forms.FontDialog fontDialog1; + private System.Windows.Forms.TextBox tbMax; + private System.Windows.Forms.TextBox tbWrap; } } diff --git a/TranslationApp/fMain.cs b/TranslationApp/fMain.cs index 0e38721..e366399 100644 --- a/TranslationApp/fMain.cs +++ b/TranslationApp/fMain.cs @@ -429,7 +429,7 @@ private void ShowOtherTranslations() translation = translation.Replace("\r\n", "\n"); string jptext = tbJapaneseText.Text.Replace("\r\n", "\n"); List Entryfound = FindOtherTranslations("All", jptext, "Japanese", true, false, false); - OtherTranslations = Entryfound.Where(x => x.Entry.JapaneseText.Replace("\r\n", "\n") == jptext && x.Entry.EnglishText.Replace("\r\n", "\n") != translation).ToList(); + OtherTranslations = Entryfound.Where(x => x.Entry.JapaneseText.Replace("\r\n", "\n") == jptext && (x.Entry.EnglishText ?? string.Empty).Replace("\r\n", "\n") != translation).ToList(); string cleanedString = tbEnglishText.Text.Replace("\r\n", "").Replace(" ", ""); List DifferentLineBreak = Entryfound.Where(x => x.Entry.EnglishText != null). @@ -588,17 +588,13 @@ private void bSave_Click(object sender, EventArgs e) UpdateStatusData(); } - private void fMain_Paint(object sender, PaintEventArgs e) - { - Point p = new Point(); - p.X = tbJapaneseText.Location.X + ((tbJapaneseText.Size.Width / trackBarAlign.Maximum) * trackBarAlign.Value); - p.Y = tbJapaneseText.Location.Y; - verticalLine.Location = p; - } private void trackBarAlign_ValueChanged(object sender, EventArgs e) { Invalidate(); + string val = textPreview1.DoLineBreak(tbEnglishText.Text, trackBarAlign.Value * 30); + tbEnglishText.Text = val; + } private string GetTextBasedLanguage(int entryIndex, List EntryList) @@ -651,7 +647,7 @@ private void LoadLastFolder(string gameName) var myConfig = config.GetGameConfig(gameName); if (myConfig != null) { - TryLoadFolder(config.GetGameConfig(gameName).FolderPath, gameName.Equals("NDX")); + TryLoadFolder(config.GetGameConfig(gameName).FolderPath, false); gameConfig = myConfig; UpdateOptionsVisibility(); } @@ -946,8 +942,13 @@ private void tbEnglishText_TextChanged(object sender, EventArgs e) cbStatus.Text = status; textPreview1.ReDraw(tbEnglishText.Text); Project.CurrentFolder.CurrentFile.needsSave = true; + + //string split = textPreview1.DoLineBreak(tbEnglishText.Text, 400); + //string split = textPreview1.WordWrap(tbEnglishText.Text, Convert.ToInt32(tbMax.Text)); + //tbWrap.Text = split; } + private void cbStatus_TextChanged(object sender, EventArgs e) { } @@ -1696,6 +1697,15 @@ private void fMain_Resize(object sender, EventArgs e) LastWindowState = WindowState; } } + + private void tbMax_KeyDown(object sender, KeyEventArgs e) + { + int max = 0; + bool t = Int32.TryParse(tbMax.Text, out max); + + if (t) + tbWrap.Text = textPreview1.DoLineBreak(tbEnglishText.Text, Convert.ToInt32(tbMax.Text)); + } } } \ No newline at end of file diff --git a/TranslationApp/res/toh_font_atlas.png b/TranslationApp/res/toh_font_atlas.png new file mode 100644 index 0000000000000000000000000000000000000000..fe12c06e7c86d29e4dc702e1ca73b60d3b121054 GIT binary patch literal 2288 zcmX9w z7Wy`GZra@8O7+ETTkhSPd0NnW9aR<~GByXokZ@Qglf|a2A4>UC!5JF)hUKg$vpbq# zYEbkDtVqL*>OL_#udY;X{_|2wJs;OHsHvewrwHB`og|o8o3gufm*gwSqzbO~tTj>O z7S0=l!r_|w$sB%Ah-Jdchm@Zt+u0_mjXd}D-w#$tRjn=Z4@Rh%?~jmP(NUa}qdHKU z{rgBJqdLM~tgJSKAJ0eIZ|I|K70io7L0gmCc>@l{$Kfw*NwKQ9G2CDTCTg`^6U{E9 z5hkgVR6P_AJM4m~DP4`Ok$*HwZ$c5_aji&tLqlRii7^hbH05C@5T5gwtwow}%wpI*8;ZHU9uoPP7@x>(m!I^&vxaut zQQX9FykJbyyC~U`W*4XV@%h(>BZE{i67hFvGwf(EgH{l>1B~kOoqxn(D&o`zA z2POW2Mb8O%B#HryaK2K>YFK3eFdi0-LZKS>San!nPtjZv_#phx&-kM#)Ol6Z5IM1C zSut+@frquLCpjdCuO^aFctau1!)p7Pq;xp~z66R5vgx(#*Xpa}b)jmB-2oRs1m20Z z1@>5pb{!Pb?^)(EQo5C)gSDN*Ya;krbi31q-GYd9FMT4}YIp~#f|Z(DLIxOH=A(MO z^wCB8nsBx|g!Dy!mAk0{AI7>&h0>^O@P8R(4|j1PnRViUpHQ4WPqK=r?zABV2s*|; zRe?+L>Qo2vkDy32=O7x}X}}paSHZ%QtyGma#ZNYhf=Pi-6JJJjMt)9uIUX<*l9}0n zXz-J)6-t&y=|gUQbHIFSX=a&qqp}=Kg&;+105(>`LRoLX*le{2t}sA9N$9Gd?VJy~&Y`8wRGJ*>-?E^k_||P-14)e` zx>WQ>S+Hh4xO!d(()tfzgdj5UD{l=d@J1u61jny<-`o5rWz=&|Nk$EV!!Z^b03K8oFog`)O9?kSw*jej z*?m1a(7FH^Z+2DCfg+lBCG>e1_csBsG=W$GbsMf_S#2k#YBR&TcFbKBt(bF zyJ{_@LMg`9+Ksh4Of3`Af@c;Iy#GUb(iBQ9l8QhTk#3Y=ElShEycs<;&w2FHRlt(o z09`}9>}KBQXq)WMw<2&&xCcaWzyJaOoV7Yrp;5;*fEnu7 z${^=27v9&Nk3EQy=-4lgLgN5E9V3FX5MzH=p3!|zdJT%-VEI|*v$!9xzswz2smZ8) zy{;TOS1)h7$6r(uqUV|ec)2Q(m-+dsrT=mT^mB>V2O>YS*JvLGuTcEv+!F4%E5x-q zZgPxKH*!)-@tv_U_5GF8PKp4SICf!LS#=>)y*c7=xkGy-W+wQz{5}{KU-l~G{p)dY z>!`T<@v4@GkcHqCBwQp~L0DaM76X;fM^Ir(FqI zN}5s(8u-k$-$7tnMw2Q}C!cP^nQhXIL>7aBgKz+l;v{S&05n%wT%H;v{W_3vm4DmY z52hB%CZv5qwPv!XEYEq)E$AFjf>ktS*udr>-B&6Jr_q~-;{K7MdCx9P$w$1wsRQm* KFSp7g4DkQ<&nANa literal 0 HcmV?d00001