From a2553496729195462b202b6f7c3bbf6d6969cbf2 Mon Sep 17 00:00:00 2001 From: Daniel Kraus Date: Thu, 26 Nov 2015 19:11:25 +0100 Subject: [PATCH 01/15] Initial Prescription model with factory. --- Tests/Medication/PrescriptionTest.cs | 48 ++++++++++++ Tests/Tests.csproj | 1 + zaaReloaded2/Medication/Prescription.cs | 99 +++++++++++++++++++++++++ zaaReloaded2/zaaReloaded2.csproj | 1 + 4 files changed, 149 insertions(+) create mode 100755 Tests/Medication/PrescriptionTest.cs create mode 100755 zaaReloaded2/Medication/Prescription.cs diff --git a/Tests/Medication/PrescriptionTest.cs b/Tests/Medication/PrescriptionTest.cs new file mode 100755 index 0000000..139870c --- /dev/null +++ b/Tests/Medication/PrescriptionTest.cs @@ -0,0 +1,48 @@ +/* PrescriptionTest.cs + * part of zaaReloaded2 + * + * Copyright 2015 Daniel Kraus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using zaaReloaded2.Medication; + +namespace Tests.Medication +{ + [TestFixture] + class PrescriptionTest + { + [Test] + [TestCase("Ramipril 5 mg 1-2-3", "Ramipril 5 mg", "1", "2", "3")] + [TestCase("Ramipril 5 mg 1 -2 - 3", "Ramipril 5 mg", "1", "2", "3")] + [TestCase("Ramipril 5 mg 1 - 2 - 3", "Ramipril 5 mg", "1", "2", "3")] + [TestCase("Ramipril 5 mg 1 - 2 - 3", "Ramipril 5 mg", "1", "2", "3")] + [TestCase("Ramipril 5 mg 1 1/2-2-3", "Ramipril 5 mg", "1 1/2", "2", "3")] + [TestCase("Ramipril 5 mg 1 1/2 - 2 - 3", "Ramipril 5 mg", "1 1/2", "2", "3")] + [TestCase("Ramipril 5 mg ½-⅓-¼", "Ramipril 5 mg", "½", "⅓", "¼")] + public void ParseLine(string line, string drug, string morning, + string noon, string evening) + { + Prescription p = Prescription.FromLine(line); + Assert.AreEqual(drug, p.Drug, "Drug should be " + drug); + Assert.AreEqual(morning, p.Morning, "Morning should be " + morning); + Assert.AreEqual(noon, p.Noon, "Noon should be " + noon); + Assert.AreEqual(evening, p.Evening, "Evening should be " + evening); + } + } +} diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index c65c868..d47ddf6 100755 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -83,6 +83,7 @@ + diff --git a/zaaReloaded2/Medication/Prescription.cs b/zaaReloaded2/Medication/Prescription.cs new file mode 100755 index 0000000..1615044 --- /dev/null +++ b/zaaReloaded2/Medication/Prescription.cs @@ -0,0 +1,99 @@ +/* Prescription.cs + * part of zaaReloaded2 + * + * Copyright 2015 Daniel Kraus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace zaaReloaded2.Medication +{ + /// + /// Represents a prescription + /// + public class Prescription + { + #region Factory + + /// + /// Creates a new Prescription object by parsing a line (e.g., + /// from a physician's letter). + /// + /// Line to parse + /// Prescription created from the + public static Prescription FromLine(string line) + { + // Replace any runs of whitespace with a single space + // (from http://stackoverflow.com/a/206946/270712) + line = Regex.Replace(line, @"\s+", " "); + Match m = lineRegex.Match(line); + int n = m.Groups[DOSING_GROUP].Captures.Count; + + return new Prescription( + m.Groups["drug"].Value, + n > 0 ? m.Groups[DOSING_GROUP].Captures[0].Value : String.Empty, + n > 1 ? m.Groups[DOSING_GROUP].Captures[1].Value : String.Empty, + n > 2 ? m.Groups[DOSING_GROUP].Captures[2].Value : String.Empty, + n > 3 ? m.Groups[DOSING_GROUP].Captures[3].Value : String.Empty + ); + } + + #endregion + + #region Properties + + public string Drug { get; set; } + + public string Morning { get; set; } + + public string Noon { get; set; } + + public string Evening { get; set; } + + public string Night { get; set; } + + #endregion + + #region Constructor + + public Prescription() { } + + public Prescription(string drug, string morning, string noon, + string evening, string night) + { + Drug = drug; + Morning = morning; + Noon = noon; + Evening = evening; + Night = night; + } + + #endregion + + #region Fields + + private const string DOSING_GROUP = "dosing"; + private const string DOSING = @"(\d{1,3}((\s1)?/[234])?|[\u00bd\u2153\u00bc])"; + private const string SPACER = @"\s*[-\u2012\u2013\u2014]+\s*"; + private static readonly Regex lineRegex = new Regex( + @"(?.+?)\s(?" + DOSING + + @")(\s?[-\u2012\u2013\u2014]+\s?(?" + DOSING + @")){1,3}"); + + #endregion + } +} diff --git a/zaaReloaded2/zaaReloaded2.csproj b/zaaReloaded2/zaaReloaded2.csproj index 91a98c3..2e1f7cc 100755 --- a/zaaReloaded2/zaaReloaded2.csproj +++ b/zaaReloaded2/zaaReloaded2.csproj @@ -221,6 +221,7 @@ + From c35c73f56a67f0c47186df654b50f8f4679305d3 Mon Sep 17 00:00:00 2001 From: Daniel Kraus Date: Thu, 26 Nov 2015 19:44:33 +0100 Subject: [PATCH 02/15] Add multiple prescriptions parsing. --- Tests/Medication/PrescriptionTest.cs | 26 ++++++++ zaaReloaded2/Medication/Prescription.cs | 89 +++++++++++++++++++++++-- 2 files changed, 108 insertions(+), 7 deletions(-) diff --git a/Tests/Medication/PrescriptionTest.cs b/Tests/Medication/PrescriptionTest.cs index 139870c..ae68e3f 100755 --- a/Tests/Medication/PrescriptionTest.cs +++ b/Tests/Medication/PrescriptionTest.cs @@ -44,5 +44,31 @@ namespace Tests.Medication Assert.AreEqual(noon, p.Noon, "Noon should be " + noon); Assert.AreEqual(evening, p.Evening, "Evening should be " + evening); } + + [Test] + public void MultiplePrescriptions() + { + IEnumerable list = Prescription.ManyFromLine( + "Ramipril 5 mg 1-0-0 Prograf 1 mg 1-0-1"); + Assert.AreEqual(2, list.Count()); + Assert.AreEqual("Ramipril 5 mg\t1-0-0", list.First().ToString()); + Assert.AreEqual("Prograf 1 mg\t1-0-1", list.Last().ToString()); + } + + [Test] + [TestCase("Ramipril 5 mg", "1", "0", "0", "0", "Ramipril 5 mg\t1-0-0-0")] + [TestCase("Ramipril 5 mg", "1", "0", "0", "", "Ramipril 5 mg\t1-0-0")] + [TestCase("Ramipril 5 mg", "1", "0", "", "", "Ramipril 5 mg\t1-0")] + [TestCase("Ramipril 5 mg", "1", "", "", "", "Ramipril 5 mg\t1")] + [TestCase("Ramipril 5 mg", "1", "", "0", "0", "Ramipril 5 mg\t1-0-0-0")] + [TestCase("Ramipril 5 mg", "1", "0", "", "0", "Ramipril 5 mg\t1-0-0-0")] + [TestCase("Ramipril 5 mg", "1", "", "", "0", "Ramipril 5 mg\t1-0-0-0")] + [TestCase("Ramipril 5 mg", "", "", "", "", "Ramipril 5 mg\t")] + public void PrescriptionToString(string drug, string morning, string noon, + string evening, string night, string formatted) + { + Prescription p = new Prescription(drug, morning, noon, evening, night); + Assert.AreEqual(formatted, p.ToString()); + } } } diff --git a/zaaReloaded2/Medication/Prescription.cs b/zaaReloaded2/Medication/Prescription.cs index 1615044..7220230 100755 --- a/zaaReloaded2/Medication/Prescription.cs +++ b/zaaReloaded2/Medication/Prescription.cs @@ -53,6 +53,30 @@ namespace zaaReloaded2.Medication ); } + /// + /// Extracts several prescriptions from a given line. + /// + /// Line that contains several prescriptions. + /// Enumerable with s. + public static IEnumerable ManyFromLine(string line) + { + MatchCollection mc = lineRegex.Matches(line); + List list = new List(); + foreach (Match m in mc) + { + int n = m.Groups[DOSING_GROUP].Captures.Count; + list.Add(new Prescription( + m.Groups["drug"].Value, + n > 0 ? m.Groups[DOSING_GROUP].Captures[0].Value : String.Empty, + n > 1 ? m.Groups[DOSING_GROUP].Captures[1].Value : String.Empty, + n > 2 ? m.Groups[DOSING_GROUP].Captures[2].Value : String.Empty, + n > 3 ? m.Groups[DOSING_GROUP].Captures[3].Value : String.Empty + ) + ); + } + return list; + } + #endregion #region Properties @@ -69,6 +93,54 @@ namespace zaaReloaded2.Medication #endregion + #region Overrides + + public override string ToString() + { + string s = Drug + "\t"; + if (!String.IsNullOrEmpty(Morning)) + { + s += Morning; + } + else + { + if (!(String.IsNullOrEmpty(Noon) && String.IsNullOrEmpty(Evening) && + String.IsNullOrEmpty(Night))) + { + s += "0"; + } + } + if (!String.IsNullOrEmpty(Noon)) + { + s += "-" + Noon; + } + else + { + if (!(String.IsNullOrEmpty(Evening) && String.IsNullOrEmpty(Night))) + { + s += "-0"; + } + } + if (!String.IsNullOrEmpty(Evening)) + { + s += "-" + Evening; + } + else + { + if (!String.IsNullOrEmpty(Night)) + { + s += "-0"; + } + } + if (!String.IsNullOrEmpty(Night)) + { + s += "-" + Night; + } + return s; + } + + #endregion + #region Constructor public Prescription() { } @@ -76,11 +148,11 @@ namespace zaaReloaded2.Medication public Prescription(string drug, string morning, string noon, string evening, string night) { - Drug = drug; - Morning = morning; - Noon = noon; - Evening = evening; - Night = night; + Drug = drug.Trim(); + Morning = morning.Trim(); + Noon = noon.Trim(); + Evening = evening.Trim(); + Night = night.Trim(); } #endregion @@ -90,9 +162,12 @@ namespace zaaReloaded2.Medication private const string DOSING_GROUP = "dosing"; private const string DOSING = @"(\d{1,3}((\s1)?/[234])?|[\u00bd\u2153\u00bc])"; private const string SPACER = @"\s*[-\u2012\u2013\u2014]+\s*"; + + // Enclose entire regular expression in parentheses so we can use it + // to split a line and capture the delimiter. private static readonly Regex lineRegex = new Regex( - @"(?.+?)\s(?" + DOSING + - @")(\s?[-\u2012\u2013\u2014]+\s?(?" + DOSING + @")){1,3}"); + @"((?.+?)\s(?" + DOSING + + @")(\s?[-\u2012\u2013\u2014]+\s?(?" + DOSING + @")){1,3})"); #endregion } From bcbed5bca306ca20ee2859822e49b759c38dcab0 Mon Sep 17 00:00:00 2001 From: Daniel Kraus Date: Thu, 26 Nov 2015 20:02:07 +0100 Subject: [PATCH 03/15] Add prescriptions importer. --- zaaReloaded2/Helpers.cs | 44 +++++++ .../Importer/ZaaImporter/ZaaImporter.cs | 7 +- zaaReloaded2/Medication/Importer.cs | 112 ++++++++++++++++++ zaaReloaded2/Medication/Prescription.cs | 13 ++ zaaReloaded2/zaaReloaded2.csproj | 2 + 5 files changed, 172 insertions(+), 6 deletions(-) create mode 100755 zaaReloaded2/Helpers.cs create mode 100755 zaaReloaded2/Medication/Importer.cs diff --git a/zaaReloaded2/Helpers.cs b/zaaReloaded2/Helpers.cs new file mode 100755 index 0000000..265bd15 --- /dev/null +++ b/zaaReloaded2/Helpers.cs @@ -0,0 +1,44 @@ +/* Helpers.cs + * part of zaaReloaded2 + * + * Copyright 2015 Daniel Kraus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +using System; + +namespace zaaReloaded2 +{ + /// + /// Common helper methods. + /// + public static class Helpers + { + /// + /// Splits a text into paragraphs. + /// + /// Text to split. + /// Array of paragraphs in the text. + /// + /// This implementation relies on the fact that the order of + /// splitting strings in C#'s String.Split() method is + /// important; see http://stackoverflow.com/a/8664639/270712 + /// + public static string[] SplitParagraphs(string text) + { + return text.Split( + new string[] { "\r\n", "\n\r", "\r", "\n" }, + StringSplitOptions.RemoveEmptyEntries); + } + } +} diff --git a/zaaReloaded2/Importer/ZaaImporter/ZaaImporter.cs b/zaaReloaded2/Importer/ZaaImporter/ZaaImporter.cs index aea8b8a..3377e3d 100755 --- a/zaaReloaded2/Importer/ZaaImporter/ZaaImporter.cs +++ b/zaaReloaded2/Importer/ZaaImporter/ZaaImporter.cs @@ -67,12 +67,7 @@ namespace zaaReloaded2.Importer.ZaaImporter /// ZAA-formatted Lauris output to import. public void Import(string text) { - // Split the text into parargraphs. This implementation relies on the fact - // that the order or splitting strings in C#'s String.Split() method is - // important; see http://stackoverflow.com/a/8664639/270712 - string[] paragraphs = text.Split( - new string[] { "\r\n", "\n\r", "\r", "\n" }, - StringSplitOptions.RemoveEmptyEntries); + string[] paragraphs = Helpers.SplitParagraphs(text); LaurisTimePoint timePoint = null; foreach (string paragraph in paragraphs) diff --git a/zaaReloaded2/Medication/Importer.cs b/zaaReloaded2/Medication/Importer.cs new file mode 100755 index 0000000..2da3f3d --- /dev/null +++ b/zaaReloaded2/Medication/Importer.cs @@ -0,0 +1,112 @@ +using Microsoft.Office.Interop.Word; +/* Importer.cs + * part of zaaReloaded2 + * + * Copyright 2015 Daniel Kraus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace zaaReloaded2.Medication +{ + /// + /// Imports prescriptions from a physician's letter. + /// + public class Importer + { + #region Static methods + + /// + /// Attempts to automatically detect a block of prescriptions + /// in a document. The document is screened from end to start. + /// The detected block is selected. + /// + /// True if a block was detected, false if not. + public bool AutoDetect(Document document) + { + Paragraph start = null; + Paragraph end = null; + int i = document.Paragraphs.Count; + + while (i > 1) + { + string line = document.Paragraphs[i].Range.Text; + if (Prescription.IsPrescriptionLine(line)) + { + start = document.Paragraphs[i]; + break; + } + i--; + } + + if (start != null) + { + end = start; + while (i > 1) + { + if (!Prescription.IsPrescriptionLine(document.Paragraphs[i - 1].Range.Text)) + { + end = document.Paragraphs[i]; + break; + } + i--; + } + + document.Range(start.Range.Start, end.Range.End).Select(); + return true; + } + return false; + } + + #endregion + + #region Properties + + public List Prescriptions { get; protected set; } + + #endregion + + #region Constructor + + public Importer() { } + + public Importer(string text) + : this() + { + Import(text); + } + + #endregion + + #region Private methods + + protected virtual void Import(string text) + { + Prescriptions = new List(); + string[] lines = Helpers.SplitParagraphs(text); + foreach (string line in lines) + { + if (Prescription.IsPrescriptionLine(line)) + { + Prescriptions.Add(Prescription.FromLine(line)); + } + } + } + + #endregion + } +} diff --git a/zaaReloaded2/Medication/Prescription.cs b/zaaReloaded2/Medication/Prescription.cs index 7220230..482782b 100755 --- a/zaaReloaded2/Medication/Prescription.cs +++ b/zaaReloaded2/Medication/Prescription.cs @@ -28,6 +28,19 @@ namespace zaaReloaded2.Medication /// public class Prescription { + #region Static methods + + /// + /// Determines whether a line contains prescriptions. + /// + /// Line to inspect. + /// True if the line contains prescriptions. + public static bool IsPrescriptionLine(string line) + { + return lineRegex.IsMatch(line); + } + + #endregion #region Factory /// diff --git a/zaaReloaded2/zaaReloaded2.csproj b/zaaReloaded2/zaaReloaded2.csproj index 2e1f7cc..71af781 100755 --- a/zaaReloaded2/zaaReloaded2.csproj +++ b/zaaReloaded2/zaaReloaded2.csproj @@ -194,6 +194,7 @@ --> + @@ -221,6 +222,7 @@ + From 21e7d4418780dc855231fa07425e9e110970d02d Mon Sep 17 00:00:00 2001 From: Daniel Kraus Date: Thu, 26 Nov 2015 21:33:10 +0100 Subject: [PATCH 04/15] First working version of drugs formatting. --- Tests/Medication/ImporterTest.cs | 45 +++++++++++++++ Tests/Tests.csproj | 1 + gimp/m.xcf | Bin 0 -> 2537 bytes zaaReloaded2/Commands.cs | 25 ++++++++ zaaReloaded2/Demo/Demo.docx | Bin 27125 -> 23665 bytes zaaReloaded2/Formatter/Formatter.cs | 13 +---- zaaReloaded2/Helpers.cs | 25 ++++++++ zaaReloaded2/Icons/m.png | Bin 0 -> 778 bytes zaaReloaded2/Medication/Formatter.cs | 83 +++++++++++++++++++++++++++ zaaReloaded2/Medication/Importer.cs | 14 ++--- zaaReloaded2/Ribbon.cs | 8 +++ zaaReloaded2/Ribbon.xml | 9 ++- zaaReloaded2/zaaReloaded2.csproj | 4 ++ 13 files changed, 207 insertions(+), 20 deletions(-) create mode 100755 Tests/Medication/ImporterTest.cs create mode 100644 gimp/m.xcf create mode 100644 zaaReloaded2/Icons/m.png create mode 100755 zaaReloaded2/Medication/Formatter.cs diff --git a/Tests/Medication/ImporterTest.cs b/Tests/Medication/ImporterTest.cs new file mode 100755 index 0000000..2a69659 --- /dev/null +++ b/Tests/Medication/ImporterTest.cs @@ -0,0 +1,45 @@ +/* ImporterTest.cs + * part of zaaReloaded2 + * + * Copyright 2015 Daniel Kraus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; + +namespace Tests.Medication +{ + [TestFixture] + class ImporterTest + { + [Test] + public void ImportDrugsTwoColumns() + { + string s = + "Aktuelle Medikation:\r" + + "Advagraf 1 mg 2-0-0 CellCept 500 mg 1-0-1\r" + + "CellCept 250 mg 1-0-1 Decortin 10 mg 1-0-0\r" + + "Beloc-Zok mite 1-0-1 Ramipril 5 mg 0-0-1 (neu)\r" + + "Pantozol 40 mg 0-0-1 Decostriol 0,5 µg 2-0-0\r" + + "Euthyrox 200 µg 1-1-1 (gesteigert) Ossofortin forte 1-0-1\r" + + "Vfend 200 mg 2-0-2 CPS-Pulver 0-1-0\r" + + "Cyklokapron 500 mg 1-1-1 Tamsulosin 0,4 mg 1-0-0 "; + zaaReloaded2.Medication.Importer i = new zaaReloaded2.Medication.Importer(s); + Assert.AreEqual(14, i.Prescriptions.Count); + } + } +} diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index d47ddf6..91145c5 100755 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -83,6 +83,7 @@ + diff --git a/gimp/m.xcf b/gimp/m.xcf new file mode 100644 index 0000000000000000000000000000000000000000..bf91a15722b2bab2b9fc0dc972d39cba26490bc7 GIT binary patch literal 2537 zcmeHJ%Wl&^6dfn&BYlVhr9!1bqppgOQ4#O~v!@$pRNdL@3#z-(mAtgu;WK3g+2Eqkk%lny%o|i$o9#JCeQ^o*9^`I=1in0iQ~h88{0T zpFTI8jxON5cAY`$LYLIs&;Jc5wGl2^w)7l+K3@yQW;dg@nRQP_*u1?cXx9zDS`9_i z+8|~BZOSa2sZZ|Ic`B`Hy(*bWV%*U1TdvHetC*)e6lu)>QsFX zaMrH}QUv_ExXWjJw~~9zP~H>#;-&m@v-s4SRc}c)giD3DyhvKEv_jrYFJcjVGBajX z>#mCk*Ycb?*vBU;g63baLSa^9kWr4iQ2^tgoZE*kx9edft4(f${(|yd=?OEZ%Z0sd zyCOnB%VXv&q<#1ev*uR>uQWZYCT(p>dDS`|9fxR{9*zpBM{!MqoFX7Y@oT58M3=&r z3ll7k6IE34mpCaVyE|+rDJ60Ih80<_N)lC4M$)I^MypG+|)WH~B3%w8rXDs`U6Zmy6{VQ@% qA5yHGj&2{){G*P5@)I4$p-J#wFRwt;;F*+H>0!CV#v$8Uzx)l;mLJOi literal 0 HcmV?d00001 diff --git a/zaaReloaded2/Commands.cs b/zaaReloaded2/Commands.cs index 6cd54ec..6354980 100755 --- a/zaaReloaded2/Commands.cs +++ b/zaaReloaded2/Commands.cs @@ -138,6 +138,31 @@ namespace zaaReloaded2 Globals.ThisAddIn.Application.Selection); } + public static void FormatDrugs() + { + // If no "real" selection exists, attempt to auto-detect the drugs section. + // (NB Technically, there is never _no_ selection in a document.) + Word.Window activeWindow = Globals.ThisAddIn.Application.ActiveWindow; + Word.Selection sel = activeWindow.Selection; + if (!(sel.Paragraphs.Count > 1 + || (sel.Text.Length > 1 && sel.Text.EndsWith("\r")))) + { + if (!Medication.Importer.AutoDetect(activeWindow.Document)) + { + NotificationAction a = new NotificationAction(); + a.Caption = "Formatieren nicht möglich"; + a.Message = "Das Dokument scheint keine Medikationsliste zu enthalten."; + a.OkButtonLabel = "Schließen"; + a.Invoke(); + return; + } + } + + Medication.Importer importer = new Medication.Importer(activeWindow.Selection.Text); + Medication.Formatter formatter = new Medication.Formatter(importer.Prescriptions); + formatter.FormatOneColumn(activeWindow.Document); + } + #endregion #region Private methods diff --git a/zaaReloaded2/Demo/Demo.docx b/zaaReloaded2/Demo/Demo.docx index ac0714c8bfbbf7a344906a2ad0bbb476bfb4f05a..e9f87bcb21b9f4499194a24ff00322add02fb2f5 100755 GIT binary patch delta 18533 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 delta 21924 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 diff --git a/zaaReloaded2/Formatter/Formatter.cs b/zaaReloaded2/Formatter/Formatter.cs index 2d39b55..27c0c2b 100755 --- a/zaaReloaded2/Formatter/Formatter.cs +++ b/zaaReloaded2/Formatter/Formatter.cs @@ -142,13 +142,7 @@ namespace zaaReloaded2.Formatter // Create undo record and styles prior to iterating over the elements // because a column switching element might trigger output to the // document. - bool hasAddin = Globals.ThisAddIn != null; - if (hasAddin) - { - Globals.ThisAddIn.Application.UndoRecord.StartCustomRecord( - String.Format("Laborformatierung ({0})", Properties.Settings.Default.AddinName) - ); - } + Helpers.StartUndo("Laborformatierung"); CreateStyles(); int current = 0; @@ -177,10 +171,7 @@ namespace zaaReloaded2.Formatter } _secondaryBuffer.Flush(); - if (hasAddin) - { - Globals.ThisAddIn.Application.UndoRecord.EndCustomRecord(); - } + Helpers.EndUndo(); } /// diff --git a/zaaReloaded2/Helpers.cs b/zaaReloaded2/Helpers.cs index 265bd15..b658361 100755 --- a/zaaReloaded2/Helpers.cs +++ b/zaaReloaded2/Helpers.cs @@ -40,5 +40,30 @@ namespace zaaReloaded2 new string[] { "\r\n", "\n\r", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries); } + + /// + /// Starts a custom undo record. + /// + /// + public static void StartUndo(string message) + { + if (Globals.ThisAddIn != null) + { + Globals.ThisAddIn.Application.UndoRecord.StartCustomRecord( + String.Format("{0} ({1})", message, Properties.Settings.Default.AddinName) + ); + } + } + + /// + /// Ends an undo record. + /// + public static void EndUndo() + { + if (Globals.ThisAddIn != null) + { + Globals.ThisAddIn.Application.UndoRecord.EndCustomRecord(); + } + } } } diff --git a/zaaReloaded2/Icons/m.png b/zaaReloaded2/Icons/m.png new file mode 100644 index 0000000000000000000000000000000000000000..b1c5cbac5ed39308e8ea2a15b49b31b69295a94b GIT binary patch literal 778 zcmV+l1NHogP)eSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00Lr3 zL_t(o!|hg2PZ~iK|II90D5Oa#=>-Bev9SlJMCGC}(eL09u6_n?db3Ip$V}H3=F%|)0kmd*zzYKHok=H&Trqm_nUdYc>{^EXc?+SS+v};TD&%> zJqsZOkshYs%m4sY2LM2vF^CXC$U&?ZyY$Hy3Hs!Vj589$X)jqzdg-e=bBGoIWO=sc z7Qr*czj2rtL0!0NS(dFfNTZJ^iyVGCQrVgeYtkya_@X+EMlO~U3buiekO)yD zV0;6Bo!-uE9rd2XI(Eli;VTu_J!p_d9{}2OPSrC0IQ6Yv2*j^-i-tq^y+9M{;|)uDFyd7tiw6C@GP zp_3+>{gPe!b7Gw|tEhHUNWDMM4nAc_=0k!c0zm|62OX;}>fJN@taWOg{^o>>u^MpG z`J%01H`s1}_Xi`)9w|Yr7rT@{x5u^dX=qKjt9rT-29&GC#%Sd_bHaT zPO@a>h#$T9#c4cn{_gyX=P7XR#wOdmF^S2&y2BRRx_KZEo_@|ndWz63xtqBqe>;Y+ zhd_?zB8G0H$6Y&yZlrTG7n!J)8U3c}1C#z}&+7Mf87-Z_Ux3no6Kdf47XSbN07*qo IM6N<$g5;P}U;qFB literal 0 HcmV?d00001 diff --git a/zaaReloaded2/Medication/Formatter.cs b/zaaReloaded2/Medication/Formatter.cs new file mode 100755 index 0000000..9aadc30 --- /dev/null +++ b/zaaReloaded2/Medication/Formatter.cs @@ -0,0 +1,83 @@ +using Microsoft.Office.Interop.Word; +/* Formatter.cs + * part of zaaReloaded2 + * + * Copyright 2015 Daniel Kraus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace zaaReloaded2.Medication +{ + /// + /// Formats prescriptions + /// + public class Formatter + { + #region Properties + + public IList Prescriptions { get; set; } + + #endregion + + #region Constructor + + public Formatter() { } + + public Formatter(IList prescriptions) + : this() + { + Prescriptions = prescriptions; + } + + #endregion + + #region Methods + + /// + /// Writes a block of prescriptions with one column to a + /// Word document. + /// + /// + public void FormatOneColumn(Document document) + { + if (document == null) + { + throw new ArgumentNullException( + "Cannot format prescriptions because no document was given."); + } + + Helpers.StartUndo("Medikation formatieren"); + foreach (Prescription p in Prescriptions) + { + document.ActiveWindow.Selection.TypeText(p.ToString() + "\r"); + } + Helpers.EndUndo(); + } + + /// + /// Creates a table containing all prescriptions and copies it to + /// the clipboard. + /// + public void CreatePrescriptionsTable() + { + throw new NotImplementedException(); + } + + #endregion + } +} diff --git a/zaaReloaded2/Medication/Importer.cs b/zaaReloaded2/Medication/Importer.cs index 2da3f3d..2057683 100755 --- a/zaaReloaded2/Medication/Importer.cs +++ b/zaaReloaded2/Medication/Importer.cs @@ -36,7 +36,7 @@ namespace zaaReloaded2.Medication /// The detected block is selected. /// /// True if a block was detected, false if not. - public bool AutoDetect(Document document) + public static bool AutoDetect(Document document) { Paragraph start = null; Paragraph end = null; @@ -47,20 +47,20 @@ namespace zaaReloaded2.Medication string line = document.Paragraphs[i].Range.Text; if (Prescription.IsPrescriptionLine(line)) { - start = document.Paragraphs[i]; + end = document.Paragraphs[i]; break; } i--; } - if (start != null) + if (end != null) { - end = start; - while (i > 1) + start = end; + while (i > 2) { if (!Prescription.IsPrescriptionLine(document.Paragraphs[i - 1].Range.Text)) { - end = document.Paragraphs[i]; + start = document.Paragraphs[i]; break; } i--; @@ -102,7 +102,7 @@ namespace zaaReloaded2.Medication { if (Prescription.IsPrescriptionLine(line)) { - Prescriptions.Add(Prescription.FromLine(line)); + Prescriptions.AddRange(Prescription.ManyFromLine(line)); } } } diff --git a/zaaReloaded2/Ribbon.cs b/zaaReloaded2/Ribbon.cs index d098166..95996b6 100755 --- a/zaaReloaded2/Ribbon.cs +++ b/zaaReloaded2/Ribbon.cs @@ -105,6 +105,9 @@ namespace zaaReloaded2 case "zrlDemo": Commands.LoadDemo(); break; + case "zrlFormatDrugs": + Commands.FormatDrugs(); + break; default: throw new InvalidOperationException("No operation defined for " + control.Id); } @@ -150,6 +153,11 @@ namespace zaaReloaded2 return Commands.CanFormat(); } + public bool CanFormatDrugs(Office.IRibbonControl control) + { + return Commands.CanFormat(); + } + #endregion #region Public methods diff --git a/zaaReloaded2/Ribbon.xml b/zaaReloaded2/Ribbon.xml index 0fb6d2e..a59f63b 100755 --- a/zaaReloaded2/Ribbon.xml +++ b/zaaReloaded2/Ribbon.xml @@ -23,8 +23,8 @@ - - /// True if a block was detected, false if not. + /// + /// + /// Autodetection works by examining the document paragraph by + /// paragraph, starting at the end of the document. The first + /// block of at least two lines that are identified as prescription + /// lines is selected. + /// + /// + /// It should be noted that every paragraph (a.k.a. line) may + /// be regarded as one of three things: + /// + /// + /// A typical prescription line (in the form "Ramipril 5 mg 1-0-0") + /// A typical non-prescription text line + /// Something inbetween, e.g. a line with tab stops as in + /// "Ramipril 5 mg \t alle zwei Tage" or in "Prof. B. Oss \t Dr. A. Sistent" + /// + /// + /// + /// It is the third type of line that may cause confusion. If such a line + /// is encountered at the start of a putative block of prescriptions, we + /// therefore enter a "fuzzy" state in the detection algorithm and take + /// it from there, i.e. disregard the block if there are no lines that + /// are clearly prescriptions lines, or accept the block if we do detect + /// adjacent lines with unequivocal prescriptions. + /// + /// + /// public static bool AutoDetect(Document document) { Paragraph start = null; Paragraph end = null; + bool insideBlock = false; + bool fuzzy = false; + bool result = false; int i = document.Paragraphs.Count; while (i > 1) { string line = document.Paragraphs[i].Range.Text; - if (Prescription.IsPrescriptionLine(line)) + + if (Prescription.IsCanonicalPrescriptionLine(line)) { - end = document.Paragraphs[i]; - break; + // The current line is unequivocally a prescription line: + // If we're not inside a block already, mark the bottom + // of the block. + // If we are inside a block already, make sure to leave + // the 'fuzzy' state because this clearly now is a prescription + // block. + if (insideBlock) + { + fuzzy = false; + } + else + { + end = document.Paragraphs[i]; + insideBlock = true; + } } + else if (Prescription.IsPotentialPrescriptionLine(line)) + { + // The current line is a putative prescription line: + // If we're not inside a block already, enter the + // "fuzzy" state. + // If we are inside a block, no special action is + // needed, we can continue with the next paragraph. + if (!insideBlock) + { + fuzzy = true; + insideBlock = true; + end = document.Paragraphs[i]; + } + } + else + { + // The current line is not a prescription line: + // If we are currently in a definitive block of prescriptions, + // mark the line below the current line as the start of the block. + // If we're in a putative block, discard the information + // about the bottom end of the block and reset all flags. + if (insideBlock) + { + if (!fuzzy) + { + start = document.Paragraphs[i + 1]; + break; + } + else + { + fuzzy = false; + insideBlock = false; + end = null; + } + } + } + i--; } if (end != null) - { - start = end; - while (i > 2) + { + // If we don't have a start paragraph, + // but do have an end paragraph, we set the start paragraph to the + // first paragraph of the document. + if (start == null) { - if (!Prescription.IsPrescriptionLine(document.Paragraphs[i - 1].Range.Text)) - { - start = document.Paragraphs[i]; - break; - } - i--; + start = document.Paragraphs[1]; } - document.Range(start.Range.Start, end.Range.End).Select(); - return true; - } - return false; + result = true; + } + return result; } #endregion @@ -102,7 +180,7 @@ namespace zaaReloaded2.Medication string[] lines = Helpers.SplitParagraphs(text); foreach (string line in lines) { - if (Prescription.IsPrescriptionLine(line)) + if (Prescription.IsCanonicalPrescriptionLine(line)) { addition = Prescription.ManyFromLine(line); columns = System.Math.Max(columns, addition.Count); diff --git a/zaaReloaded2/Medication/Prescription.cs b/zaaReloaded2/Medication/Prescription.cs index 67bb130..dff6bf5 100755 --- a/zaaReloaded2/Medication/Prescription.cs +++ b/zaaReloaded2/Medication/Prescription.cs @@ -35,11 +35,16 @@ namespace zaaReloaded2.Medication /// /// Line to inspect. /// True if the line contains prescriptions. - public static bool IsPrescriptionLine(string line) + public static bool IsCanonicalPrescriptionLine(string line) { return canonicalRegex.IsMatch(line); } + public static bool IsPotentialPrescriptionLine(string line) + { + return alternativeRegex.IsMatch(line); + } + #endregion #region Factory From d28d51e87556047f6c6c838a632cec669e08bfc7 Mon Sep 17 00:00:00 2001 From: Daniel Kraus Date: Thu, 3 Dec 2015 06:03:35 +0100 Subject: [PATCH 15/15] Improve detection of two prescription columns. --- zaaReloaded2/Demo/Demo.docx | Bin 23665 -> 24384 bytes zaaReloaded2/Medication/Prescription.cs | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/zaaReloaded2/Demo/Demo.docx b/zaaReloaded2/Demo/Demo.docx index e9f87bcb21b9f4499194a24ff00322add02fb2f5..7957a0417a81aec04a6038e28f5b315fcc93a025 100755 GIT binary patch delta 13584 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 delta 12851 zcmZ8|WmKI_vM%oK?hxEP5Zom=1lNtb>l@r5u(9Co?h@RB1$TFM3x2*iGjs13v$NDoDvNvJV`5C03Dt~UFeWbmi22C>S;jEvmS@sPwQfYwT*Pj5Vk&Bj{ zABfivN^BPEAl4|E$B zb*-$vgxydobr(Kd>S(KLzxn&;)_0h8eQLfttZOk@?EB?suJw43N`&L#_{IdWJpQKp z?o%8gT>9Z-Jn3vVDQa}<%M?mgoQ2-D@I}>P;;I+$DKz1-d52s>5x_8*i3(78P0-(- z6dKIDjI9=mr_JrUUP|Q+2tI^^w&f3qQMwG1A)ygD-mMS+d$cst+L5RF^Qr4DVbL4@ zu**AKo1<%c{QLl+0N-G5DS_nZEpGGVjuh2@xqrYh#3A85%soK-;WOB1CoLso1H?70 zh=dO?nPxn_%{)r?-yNb;%6TtCgq0iXZmlIpeC>fIK)RjeRs=ISD5UJ73$ti)K z+>aHg?_b`w7o4+7%FsDG`D35+<$YuD{7X9UAeV={PV?5sL3&>R?k(9fZ^O$%_>u*C zT!%&aIZkHRmB3(s@-2{f>deD<_F3}LOW%>+JP>~JEzvR4|7;8~&|K;s zA}}V$-bo~>%f79p&+%I)IOxOmYv+$Z+>mSl9h@7I5oP=bJ<3q;mGx8Mj#21ivtkJF z!uXUgM>yO!r7uA8cO%Q))>>GACE@N<^`{)o2KsEyx)6MX2^U`i<1u1Ip?-SpIk(2= z;JvRrWhu%{)t0_AJUqCkY)60_7$ZzId%6uQP7ff*-fcDQ?_8kzt9{vhlx$HurMvaQ zo_VL+4BwPFXu(C9VAZ;sN)5ad8SMiaTovG;)Wv1TaDU>55N3Li)Ffrf9R*^Y)btvsNfv2$8$ zIGN4!jugVkgj!vsz6zz8mkJZ#7HL;o_Z13`5r{K%L9vO? zHh+~8{wCC|V>_huD{Bd8@k=^9DlIwAghlr%$0U>M!g&pZRuRjGMPX%FynTYhaYnA z9iTiI!z+E(%xx-*@DDE|2W)4xsLE}^{;Djq0O5pi!MiS3rBoVs;#7Z5~0eK)LWmkdXxzQD_d7sxmA0utrYbVs_d2 z#*@}jhE0mgf(2GS-+E9f_X|nq8e``;N25Me)Z`>AN&W54$*CG37HGf!vQEvqj-`Z3 zBz8`li?$|0DEmkXJngF3jRd$Kg#zSM$ao6nmC4&wTE^Bk35BfxY?uj3^Z=D`MOXEL zb3#-uBA`3sH){oEnng<&EKoi-chaiL(ERPgheEGqxMkIG@*U~vXeq(ZYHF5mTVcbv zJhH{IW?;JF4{Te&iCg5_mCF-8$C*sYq!Sz)M2BE|Z44iV!UGZ8?_-+F-&R_buZ(Tb zxb==gd7oUvcB*j0c(IHEtyYah!YPX~zWDH3>;t;_V%Vw0bfD@yo&s&KbH_5D4ym@~ z=GO6FIPIlHLD_@Qq&7{4wbKL%Z_^L0XYa_**|>G*lH#w_*0Hj9IIPok=Ttluwm2pk z4R7Way`xle0@RzF8E!?)d*IQz)!LlR$PVLV4#Qbey?VQLiQDkBJ!kJy zAtnfpa9Mxbq8g$n`Qejw=uQNRV;L1(1VAetj(K%5cGRlMcq*ti$Dc~4W9F}yue0~7 z^Snz%`UN$-#ClOuC}J?cO56+KHE^Wi?BGTU4KzhAIIZNIG7PLIci?(R zz_E_5-%8V##CAt#)?{ApY-!p;!wdGup+M;sq9XUNI6}q7G*RUK470|oOtn>SE0aXt zg3v4hD-#3TV#+_^1)+ga-t4*rm!{9@F`lh8EWZOhZI3}I5NqF?xO53HsAPkt`x?xl z=*@EC@rD{B6LDkkq%rS6$<3KFet;muL@E}frsv+nZDN1ScCrL<(Pm0Tepv*~hlRPj zBLmN;FLMl>W-9Hl{94X(`yyKs2t0vEOfuA~1^qQ46@~0WL?)&j)&Bmm5q8Nz7Db$c z=#WP!{H3>Bi~$QQUu9aHXrZ*Jm??a*W|I*L)fY=8drJ3{5!{334qLGxr+`F@WCZi< z18u4v4nxgI2!qia0(x&=8@`>u_w*PSNG{iaouZd)Y?|v+$lI-+2(ZVp= zR2cc$!8oD6n4)J_RhJ;y^7i>7G`_3c=;-Hk4+4|8n4%8i_;jUz?8gWpecpE5HES@R ziLN)$R8NRG8WG+%6yh8 zk;~lcYgB(FVM7>Ea<FxYWcd z&Bz7DVFu+0=WkKiy|=Io%8K*249Yv4TR4Yd49dUb)HBbBYaMgbVe%``!Bs5E&f@s4 zQQ+jkZN_N3sxhCzN4;8J^5Y)dPfyX(V_VI#8Fvt7cUQAw=&q2=4_*q$#!QWv`sv+0 zsQf^k!#h;p9@Nqk@Pxb*8Nbs-yvH`m)fO@T6uoTQ3gIz+P>5t~_QQB%b${+)pUtbD zd2~xdb$f`AWW$T}V#sz_^zN6X6Am$^4AMg z&~_2@;lQh^pOZz74F_)3xVviKT|k}HSXcD zovSV)n|d6!J$kW7Om@CKe+B5@X!(2`mQzH;)w^lUHeQaN;XUk6YTM11Fy781LfWeX z=?M)nh0>|s0nv}oKk{HCo<`bLh0mey#9ABLgLR-}U5+3$XW@r-q4DqHBP#^CEL(jd zD^eeHI~#YEtn92-iph0bw!A)`y^Rkez}ATKvcNjn~cn}|Li$@L&3(Qg^-Pt zqqu_nb&Idx9adAt?xh%a5H8WJH#u6)BN>kFie=(w3(}?$?R-Cn!s=FaEt81i&Y2JX zRfbc3mRZb%B^&AVhEf?}foDcsI2l*vc$U4P(c`~}0+YnV?&j<^6G^z-kEm_sYd@HN zrnnNh0Q0uk>nc0%?CN@{{?1$??;d=~;c6h-y&P%_JWslejs9~5jBi^TbRLcwX`;-9 zgtS_4t!$bKbpu#DL)lcmQEd-6m`FQe4yW91V^&dqj7xK$nX{K??vz@hd+3R#$qFjy z5i++;g9ixn1{o6@RZ)dr2O1le*Pa4N!*d-`*w>xTLw7H6a(UekZjk6zDKGR})(lJOakOb!(8=LV|a zw~+jbT&O*X*DqI9bw1Oh`-hFC$In7%lKuYb^IZ^EUp|Us%y9K=?66CcKckeRZAfJ> z9>AL}4MNVaMIk)#X;oRYD>dyz_`}N+c7#_HTqglfn!I6kOnV?}9w&JqJI*6RmA0cb zN5CnwW1zs=OnKEe;OIKNOGhMq&ofQt)$3#&#&XrRhyis#)c?d2run_2K*=c7*c@#o zA9#8r_>eiHj8wDwi4jWo$1n$l-bF&<;)n*3}3{E zo0DG(m*E#K$PQyi6PG=Gl3%59nfXC^^I(A_tLREY7D7@_wpR@{Ku)*Qnw_KITi$!e z)t9+qzT^pWm-ly#-PUJw#(I(GZ3*=2871n6Q)6SYL8&lrxEaNYB$7C@#akdq0U}DA zFcoO_y7Px>#rkAsYUvp@%~94x2ulOgpr0p7;M?*s$u^K1BwbWIuEWw3eL13&dytSS zH!S|q(MLWLrNqgzP_$oOOC($enG>Rkw*!Y$x%ktbVK350U`LWJ_NBcTw|#|MFb#ha zZ#&nF_wO?Q4m(;v)(@zlsfk0m1QZiJjaC!y$^0|Y&RxB^Tzti>!mJX!1=}Ih>Nc_P z9cl`cRji*oB8o)ecJ6-O7UV*#s4q@d18c6%WQ3G%vsAP^%ul(6ID)= zZgiBgph~YpBDq1sv&(IAo@*&gb;+!3MY5}QoT|rmD)=FYDBe=Cd&TzJ0>0~8XZn=K zW^-~4n!F$!tQrJEOkV@cjJ=6w_UUmu1F^6v`idA)SOmw>d-8$+_Ve*?MOWu)AX`c6 zpUXZn7=}QPV~_Z*obbm+SRDuGtG+WI@-3X3;E)jvM2-kxW~(9TxMfASIj~ z-Z)=fp@Ot3vo&5WJ@xEJU`8>?A__U;p9*W*TwNsWLFnFBiY=YBN9H~=wMD~uV$L!r zhwU&$REkZdZP;sv%93d|hnO8ec~V$uyY#?(q|~0c++IjcI9dvpGJe4=#kPWy&T^vq zsrqRx!)^R?ORfWdna>mtlG1&=@9el1NzH-Rz2WZsvhjouWFyNCFfY?HraXtLZIju% z-ELA%e9*p4OPGn&w6B-mE2b92#cvC8vRUGHfwK%)XFu`ct08vyA`}emv3*>L4!=Kq z=9JW%N2jmPr|90Fba;Rgx19V59I}ag5_THlB!vR;&#fqEmQLB7FwJxBu5$O4a@0Xz1=>rqwGxRW!U@&?2sP;{yCh8$wL2F2v@HqT7I zMJ)H_=pFmDSdA=tfu3>oY(K`-&K>)e1M*D&oPjeegBT*PilU6pwr8rBKsI!DaK~N} zE+9O9yq$c!%?Y*Ih`4>n&f)Adc)hJja_L3gTL^thMTA?8KwZ5ST5sb2Ud^Ol4ah4DoG@)xGg&L_q%F6Im1RT2?Em;H z?*^$%ey$2~dfw?nDqO`vm91EzDQ;uTZ83V^`b{cxVcum>`wQCMcF&k&$^$jmUalgj z6hu3v)ugWXr(c8WqGIiaod-d#gTP85H|9x55%bcHp&BF7E;S-r?aO+&`Bn@Oi0hW! z9vJAKqv++DN(pR6X|%{aC$M@Ef9?wP5xKi&?X^p`ZqS@o-H}-hx4tRzcV`=suIG!~ zvB&dlTPVT zYq5Z`koMHMu=iNre{K;_^Ym(n`kT%aR=k+^1ov+Lf0gUi)pPTqEMRWC6KYX#OSUAs z*0VUUe0sYhm66$pS`TVibXs7};OR%R_g<*fDv(9Dobc&dOs$st@t_7PZsq|nZFrDe zG@F5QhwxU>KrN&7da5JHgS0V4XIee4ed=jr4pQGxK`lG^Zqa48E}O5V(ywEgZbnSU zapL{+a*snc9u@L`z!&UFV~H31!Yxm#lDJ($#~a2TOiN9%i5E)g$(e44vG9&U{KsFE z+u3B}w05V^8uU0iG<%36uLyw#Jr=W;@`=GC_GDgl>%)q(R$e$2ZawMHHi5K^;5GrY zxOE$0nt5LS36Afk?#moIZwkbPn7^_8j-^y*PEG``X_y5Wu1h!4hZ(IqIl;zUT+YhMyum(;*ktDFz`?sW;E~UOJ)9aCEkotYZ_{cWi8g^79&T>RnPXUCR0HJv`;_^)UG$y!Jyc!QD0fwWTwL zxGq~thtkY$EXlg`h8Rtl4iuqkgeRWvVTb~p@dv5AA~)?wTT6uA91G#KZdkVO%YDwf z%Ckb4aEsj-xqET$uLtTpB|QSiGZ}2go#6?<7vOR&u%m$d(59CQjVqw58S+utFZ#+}^)G z)Bzoy)jy!4Lj(PVg=%C8cG|p&@w?*73s;(RsM&PtWmj zcQ3`O=pdQS%Q3IHEwVCx?WpecUFZNQ^S^F5xUc5{7_lSc##*P93%A7!;nTd*QARSw z#JZH{u;>ysB3;!!|F7B61X!!Dg{YHQGZ)}AC8s^S-z@u4Gga<#o&A}r3VA4$x6>@W z(s8(#wewHLgr(S-yNJnjGe-S6E!#D46;aOCr#K)1y3loC6s#NnyVq6OeyMwaT1kH& zAhT%9>HZ0p{frLKkFz6Tm&wysS+!acC8Bfe1B(~T_8HqD8u|E^zKpt&oQauZWkCm7I8o$9ze#%( zYu2ll%wZVY&}Y{a0OqjAu%`=LqN_AFlZw73 zQV|Jo%Z%s__*yf3r3f6LYJrHBAMQxJk<)hfVTl9`t!#}q zg7?tdu8MF`lpIFWFN-U~wg1)|k$#4A&BwwD=<#E%L{WscM`(KXQB-MNze)cQCCx`A zPp$U#s3iac1YBNc#kW`jup(yIA!ifb(?`AwuP>dt0^ZPPq7aQ|^cW=t8B=^OEY8~x zf+sNYWe`E??#Z$R-DJz#zu^rHJoK5YA{RAy|NbA!4WqpSLA-v@`8&Ho?;uemk6IVEn!v;e@x4~r3g-zB zzTH+?64NrmQ}_>a6ZS+n9=?cN{Zz?GU5E~I+~WFZE>1{LC0}L1?OK8oqZ^qFX*q!; z>}~w5L6{M`bDDADLUTzQWaM4bbwjt6#Nu(OAy7!b?xH2keWCOXlE9Hrm+eF=7>j7n z(J+30>*#QOd){7uYE)lt6Rie1-{sLB!of>g=8xU9>pabslr{IkcIMW^KWhC6x~ zk3|YY55bKezh9ZPajgqP-~L5$qX!tajNPRwrRUHg#v&E=ScD2i#g%~Etfm50 zKInCo)_{2(2`-hE80Yg-TYmkh?`;}k5?a-7R8W7qUA{L!U?JMA-|CEx%WhSEq=-Qk zn0gz~uzNV$*7jo)B!?x4%L^t0Z!wjXp2*oc^d&CUzI_Xb@SQ(M$z+WoLh&gAx4Ej1 z5LdrT>GYs=BO%6UHO9bzXxIVjKte>Jy4jpbXR!`#X{d&JV++iG8){^5Hcp@K&nmoAxHOT^;r0(V84(QghZTXd?84@^-b_Nza1a zvaFGjM#KMUAB8M1YXKPVmGtH!>AZBBLbSXEG+r*;4cLx{9LFx6RU7Vw;>5ag!yCWp zTjY~}5}{|Gon6t;!TLxnH_8%TT1lPp7XXj)Xn8jhOc=RXp@C;LG=>`qBty;KpQ-GZ zqF|dZ=5HOYafG2}!Yup;bK=)AR&vUsinJ$#M=*~OdE@mXYNfLsWSA^+cpK-+7nZ^} z)sNB@^FHfhes0dYEP$&*w=%4y77*$}RT2wxUQLoWlZboQp>j2--ZPGS06(4C*8>F> zbw;-Gup~o)nUu!Cr7E+RPrG#!0j>4MI02CbD2sV;Z&hc5`AtRz}@azxmtea@9%{ zdnAGpbZkp!To=cGH$0AKLEe+HL;(IilRg#W48+BXMyanRGEAn!4~czB)?+RAt0b4Q z1o4-0mY*M^3YctM^@BIx?{pwqui${4< zEYO7cv$x<()-+xubO!H_%|$K--N|a^a@hIl@#AMBI$CU{q$tzD_yw)CopvBKBhr*; zumx|c-hUO^Ji3%&KBf$sbxfU(jwp?(!0IBm%(&cQ=i>J1=VuY7G;dC4!y)x>yu`E$ zCw`=H)h!{ZK-Wy(tj${k$#Bxh9UNy#L;JRJ^+&;cBVLJ3s7@C<;6x)UIxdiYOY=|0 z?lPD2o}VB)I4CMs#Xwb0Di+vH#-*}WTBTg*s`P&>_iqUJ@bS%MLAZ^h%bSX*NETq4 zV6WEiZzYqZd@>KB#KuXKRc0&rp|K8`%IgO=u||RqvQM~2Jdj6QK)|L^7cFmrH)JPClO-3|)wug`G6Y6Has5nnPjE2y zk#VjZRm4AT-29%`-=Hp$idi`c;4LtQY! zbltUj=W7LYj{h`|jN>HR zqR4~~ZQICcyX>J6?GR0S!;^KxDimxowYW>;;jt3%>sH zNr2dvQ4&x9;Ym-ufgz)!ciDg+_3c-e5?7-E?dW2HFeL08kKlSJMCRCzQmI|e6*Hq| z<8EH?!H>~S#`SpKN0oQ^DmLRPW+trL`oV%Jh^(YKgPJ*W8eXzULc91RSz!E9e1g^Xae%y0?Q3LNqKM6OD)*@)t@C zG|5ABaS@@en!gLK*o37|N=sJE0KyRkOsx^D_cm-wh9adDR?HUqPpp*{(x?bBAWn!c zxDLY#K*l7PrW$4Dv{TB9LZPKnc?F$wel4jSnr;H2_ECivsBXE>gbN^i6Mp}dJ|!H{ z1C)w#_XSJAsOARJ?Nb)xnQ|xT;|}PVcC+4pa5mt+NT*jBCuMi-`!1#~#Nx2|&yp@j zq7_a}-1Qw)(K@o+Ha3~V_!$eDT=%tuwIJ{o5g_AbwQ$@mU|!A1D+TtUIH1VBWlNgM z-Cc@ijt;ljf%zR_6c3@)ZrhkLlEzmM0I%jAyTDse;C9nN!p%|d(t7X`(>b4F!ogj% zWixkO&N0-MVv!Yu;&(r?1Sv^;#IcwvHJAd~`qiY5Y+uZvU*w|2fjSuZCL=uXlqbV{ z8;G@grBL~Op| zeX`;L@fz^ya-irijrG4n4Makc+T{x*pW!OLzxwSJ77|f6hPILk9BtV?x6Di;W6m$X zesO_`h*QHU3?f_xaYBC0M)WGh{afVbJCoYkyqr4eZ@s~o6*}|<&~s1o<+Lh16(Bu8 zK*RS;!>$o5k=7>Z^!1*nJ0a_9)~=nVSQ5`{ikEqP-8oZC76YqCrVJpxK}G#q!VUS% zk6UZ>3GK5OwZQ_@Bpd5*64e6q`4svu+|wymUbq{pSY{eIxp8;F7d>2B zRngg<$-<{v$>HW60HiCR^Ki;m@P%3(p8VN17}~*@`y8%R6WjiHs3TczCh~ZePyko{ zXrvBxyA+#^Az=R7x7m!B1B1AS``Yr}C42rvUb=HHUQkwAmeO#c>SBJjp>%^Pi!s?2 zJgr1`2jQ=cH3I`AH~!f>J>i7(=+1c1CZ8jWDxHPfjv|RYApUp(5(wx&$%i~A3EYlOUho2lEr<(JVY&uwQu z0SE!8wG={tx9@wB5zP~W;0wbhg~3DVA8vtoXJamBa;~nO3scahlke48TVtogwc|#W zQ>6+Bv^~qUS;%YY3H$X@Ag8=}@9?>6jZN1vwb%^Re+&=8Idu!t{0GrmF_O@;#hU)!O z+_U7i^?ffy_I-%}k@HcYD7{jsy>~fYc1#}t7wCyygnzVK1`n5WQ;~`4Rqwx9No48! zQe6vl%&>HIkETH1@3q6igvUney*$Ydzuv=1L62Smn}NOILT*q|8it+>yY7Hx*hlZz zH-i(MfYE4z7_!~?ZnMS1-pjUoVL<4Cv(F>`zrq`$?mA>7>2?e z?pE-IZXok#1&@Nm4jD%#u~zs+d-jyol=M#Zy^6YQFJq9w1+x_{GU&lmTB_~D?WW*D zmvpj&RxPPw>P})yyo$^wioSI>9W5>V{ZiqwZMid+OqkF&uvUhXv%O5d1-72Jc@|LX z)hv>u88i7f!Mq6m< zvcOlb+D^{|zq?*v9bYVQ+O>jj?Hb+Z@r1n9Jf!(@yWxWk0s?$3h6Cm{z-SQX9fkuO zaGP^updlbm5g`7V7lnZEbaXLibG2}Dvv#m_W%aVRYt&M3T;<2;Vype=o$@A?i`(U2 z;g`Z1Ud40PtDG6zpigLyxPncr-+6yVljA5S=A+j=8=3RF&5oBa>hj*PYouOLVZf6M zNTj8vvWYBPVojVxuecT>B#efURzw2oWgiA;9IM}7ck7u@>hR{q5%dw%uY3}?7s{!W zl-4og#v?T(AzBmCsgZMhGF%GD^?0gjwSUhED?fa5C!jiA z+1PpE&?KG+IGamFcVU2l0K+m*Kd#iv1N_y9-^bw|u~87UPW=#R{B}GiY#i0s1TbGQ ziF$0Dkqzg7hSbOV#kyf1I#+5cTF#n7r`=P^rgo#MO`mT|fHlQ2mN*BQW~VZC23;=C zgj;%sF(5K|0O{~hPT4nkBLWy(50ro#zAvKAlr~GIBF#@F=rL5LFrSz_iLK}v7lwu1 z<7MZtx*6LLwxZ!dIsfLD^?k3Vr9%|0DrQT+=`R+9HiDhIuoWVc?OUJ2!KTkjn7JVQ zCU!&nCSDC2ut}t_E&X>Cpbq{=V0Ve{#XEt?AEGJ|>RB3(0i=UZb%3cxRoQ}CH#ULS zRY&g(za*csj@!~ef4ABSe;9K|>z~U%zC-*?kRvG#4H*_kGn6jrN{$y7ag+_OLOF)y z5(l@l$V;99N8uX*nZ5UZoO%ZQ#HGbGf%p#lelyys+j|ilJAoQ45!&hb(<>~rwL4Np z<4FiC|+16Z0>b_nkHB zx>(mi^IvB&+FS%a#upkNZeM7 zYOAbagnsvyu;ULZcI_7H?Wo@rN7^-n=SVj&pMM(LY_kRCrxko^$^Vo++Q}>7ySxHz za5%zH0ey@>9nIRa7Jt&Sr2g8WzlN-$o@>^2IA7cPffUJQV<(4m=EcO5bhdc1xp8~N zwtvF(@7!(vCwI3+gOOmyzqdj(SSip!0&1#X``9r8_^w5m{Wn*js9Sqvldke<=uEl0 z<{!R~F7Vi!TwR{?5-2M9ovuHwdwOoV3kmOitA#hS$fJvphJnrXqAb+?I(6zo7N=rN zsvcw!8iXhqBsF{Y02+7iLx!F#o-)paA@-uRz^?vewVSET-s}f0(2!tBk6w)g2DlC- z8ivxZS@fVUFgXVV`03KjTCq^vDgrv=*)78}>6v~@QC+SXzPeR^?eg*|(?%^S|F!ddrfw?|%o^+#!}j%~ zzGISYt6Hul5WW@i015mjE%66zJP>wnXW$FRIM(9Cj7(k0b}89q_)cM=(c`yy(zC0^kV;A`Xn<%j9RYicWZFT5gKnQmS$nD`J`yCy!qZ(Sz0Y%g{*P z*7*LTt7EtfnBvyn=Ie*VnqfwBE1qT zldW+=Hbr5}&Mth{%|f6IDrFuX9rFxneg+rb9GVRwToP{*z))F3n|P`KiWX;TZ8%X0 z7ULyDD?!P|R7879J|!x)AAZ98Xt8$C+(V9E9>J{LBAlyEMA(rTDC0kc5^A8YP+X)4 z!?_^oN~DG1*skRHyYMU&aeW6G{bqZ+uk2Iyqxh5b?DF6A2E!1*xq3#PN=eIaadg!f zS&=NAkfshAuzbT(cKsGC=oMQMG2{8fXO95lCUjm%4>`0rE?R}Xw#K9UoLZAyX)Je% zA6g0J^gy=tNU`gnt%l7lvh#|7RP{9|An!bGc25p2LS3&==D3Mlb~f6gYIZ3Z`ADi5 z)9Oc(?c2~<>b<=%W{7f=xjx>I@tA0&f?#`I(3Q#*uzE#aTkyrMe=7gM$p_>)Om2|c z>@kx$Fm!Z4ymk5&" + DOSE + @")" + SPACER + @"(?" + DOSE + @")" + @"(" + SPACER + @"(?" + DOSE + @"))?" + - @"( +(?[^\t]+))?)"; + @"( +(?[^\t]+))?\s*)"; private static readonly Regex canonicalRegex = new Regex(canonicalPattern); ///