From 7892c92130d8ebeab9eccb2985c85aebc5fc43e2 Mon Sep 17 00:00:00 2001 From: ABykiev Date: Tue, 2 Apr 2024 21:58:45 +0300 Subject: [PATCH] Fix reading document variables Closes #1199 --- OpenXmlFormats/Wordprocessing/Document.cs | 459 +++++++++--------- OpenXmlFormats/Wordprocessing/Settings.cs | 19 +- .../ooxml/XWPF/UserModel/TestXWPFDocument.cs | 96 ++-- testcases/test-data/document/docVars.docx | Bin 0 -> 12310 bytes 4 files changed, 312 insertions(+), 262 deletions(-) create mode 100644 testcases/test-data/document/docVars.docx diff --git a/OpenXmlFormats/Wordprocessing/Document.cs b/OpenXmlFormats/Wordprocessing/Document.cs index 96dbee52a..69fb9110c 100644 --- a/OpenXmlFormats/Wordprocessing/Document.cs +++ b/OpenXmlFormats/Wordprocessing/Document.cs @@ -75,14 +75,14 @@ public class CT_Document : CT_DocumentBase { public static CT_Document Parse(XmlNode node, XmlNamespaceManager namespaceManager) { - if (node == null) + if(node == null) return null; CT_Document ctObj = new CT_Document(); - foreach (XmlNode childNode in node.ChildNodes) + foreach(XmlNode childNode in node.ChildNodes) { - if (childNode.LocalName == "body") + if(childNode.LocalName == "body") ctObj.body = CT_Body.Parse(childNode, namespaceManager); - else if (childNode.LocalName == "background") + else if(childNode.LocalName == "background") ctObj.background = CT_Background.Parse(childNode, namespaceManager); } return ctObj; @@ -108,9 +108,9 @@ internal void Write(StreamWriter sw) sw.Write("xmlns:w16se=\"http://schemas.microsoft.com/office/word/2015/wordml/symex\" xmlns:wpg=\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\" xmlns:wpi=\"http://schemas.microsoft.com/office/word/2010/wordprocessingInk\" "); sw.Write("xmlns:wne=\"http://schemas.microsoft.com/office/word/2006/wordml\" xmlns:wps=\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\" "); sw.Write("mc:Ignorable=\"w14 w15 w16se w16cid w16 w16cex w16sdtdh wp14\">"); - if (this.body != null) + if(this.body != null) this.body.Write(sw, "body"); - if (this.background != null) + if(this.background != null) this.background.Write(sw, "background"); sw.Write(""); } @@ -162,161 +162,161 @@ public CT_Body() } public static CT_Body Parse(XmlNode node, XmlNamespaceManager namespaceManager) { - if (node == null) + if(node == null) return null; CT_Body ctObj = new CT_Body(); - foreach (XmlNode childNode in node.ChildNodes) + foreach(XmlNode childNode in node.ChildNodes) { - if (childNode.LocalName == "moveTo") + if(childNode.LocalName == "moveTo") { ctObj.Items.Add(CT_RunTrackChange.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.moveTo); } - else if (childNode.LocalName == "sectPr") + else if(childNode.LocalName == "sectPr") { ctObj.sectPr = CT_SectPr.Parse(childNode, namespaceManager); } - else if (childNode.LocalName == "oMathPara") + else if(childNode.LocalName == "oMathPara") { ctObj.Items.Add(CT_OMathPara.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.oMathPara); } - else if (childNode.LocalName == "customXml") + else if(childNode.LocalName == "customXml") { ctObj.Items.Add(CT_CustomXmlBlock.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.customXml); } - else if (childNode.LocalName == "oMath") + else if(childNode.LocalName == "oMath") { ctObj.Items.Add(CT_OMath.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.oMath); } - else if (childNode.LocalName == "altChunk") + else if(childNode.LocalName == "altChunk") { ctObj.Items.Add(CT_AltChunk.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.altChunk); } - else if (childNode.LocalName == "bookmarkEnd") + else if(childNode.LocalName == "bookmarkEnd") { ctObj.Items.Add(CT_MarkupRange.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.bookmarkEnd); } - else if (childNode.LocalName == "bookmarkStart") + else if(childNode.LocalName == "bookmarkStart") { ctObj.Items.Add(CT_Bookmark.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.bookmarkStart); } - else if (childNode.LocalName == "commentRangeEnd") + else if(childNode.LocalName == "commentRangeEnd") { ctObj.Items.Add(CT_MarkupRange.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.commentRangeEnd); } - else if (childNode.LocalName == "commentRangeStart") + else if(childNode.LocalName == "commentRangeStart") { ctObj.Items.Add(CT_MarkupRange.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.commentRangeStart); } - else if (childNode.LocalName == "customXmlDelRangeEnd") + else if(childNode.LocalName == "customXmlDelRangeEnd") { ctObj.Items.Add(CT_Markup.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.customXmlDelRangeEnd); } - else if (childNode.LocalName == "customXmlDelRangeStart") + else if(childNode.LocalName == "customXmlDelRangeStart") { ctObj.Items.Add(CT_TrackChange.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.customXmlDelRangeStart); } - else if (childNode.LocalName == "customXmlInsRangeEnd") + else if(childNode.LocalName == "customXmlInsRangeEnd") { ctObj.Items.Add(CT_Markup.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.customXmlInsRangeEnd); } - else if (childNode.LocalName == "customXmlInsRangeStart") + else if(childNode.LocalName == "customXmlInsRangeStart") { ctObj.Items.Add(CT_TrackChange.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.customXmlInsRangeStart); } - else if (childNode.LocalName == "customXmlMoveFromRangeEnd") + else if(childNode.LocalName == "customXmlMoveFromRangeEnd") { ctObj.Items.Add(CT_Markup.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.customXmlMoveFromRangeEnd); } - else if (childNode.LocalName == "customXmlMoveFromRangeStart") + else if(childNode.LocalName == "customXmlMoveFromRangeStart") { ctObj.Items.Add(CT_TrackChange.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.customXmlMoveFromRangeStart); } - else if (childNode.LocalName == "customXmlMoveToRangeEnd") + else if(childNode.LocalName == "customXmlMoveToRangeEnd") { ctObj.Items.Add(CT_Markup.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.customXmlMoveToRangeEnd); } - else if (childNode.LocalName == "customXmlMoveToRangeStart") + else if(childNode.LocalName == "customXmlMoveToRangeStart") { ctObj.Items.Add(CT_TrackChange.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.customXmlMoveToRangeStart); } - else if (childNode.LocalName == "del") + else if(childNode.LocalName == "del") { ctObj.Items.Add(CT_RunTrackChange.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.del); } - else if (childNode.LocalName == "ins") + else if(childNode.LocalName == "ins") { ctObj.Items.Add(CT_RunTrackChange.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.ins); } - else if (childNode.LocalName == "moveFrom") + else if(childNode.LocalName == "moveFrom") { ctObj.Items.Add(CT_RunTrackChange.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.moveFrom); } - else if (childNode.LocalName == "moveFromRangeEnd") + else if(childNode.LocalName == "moveFromRangeEnd") { ctObj.Items.Add(CT_MarkupRange.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.moveFromRangeEnd); } - else if (childNode.LocalName == "moveFromRangeStart") + else if(childNode.LocalName == "moveFromRangeStart") { ctObj.Items.Add(CT_MoveBookmark.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.moveFromRangeStart); } - else if (childNode.LocalName == "moveToRangeEnd") + else if(childNode.LocalName == "moveToRangeEnd") { ctObj.Items.Add(CT_MarkupRange.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.moveToRangeEnd); } - else if (childNode.LocalName == "moveToRangeStart") + else if(childNode.LocalName == "moveToRangeStart") { ctObj.Items.Add(CT_MoveBookmark.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.moveToRangeStart); } - else if (childNode.LocalName == "p") + else if(childNode.LocalName == "p") { ctObj.Items.Add(CT_P.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.p); } - else if (childNode.LocalName == "permEnd") + else if(childNode.LocalName == "permEnd") { ctObj.Items.Add(CT_Perm.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.permEnd); } - else if (childNode.LocalName == "permStart") + else if(childNode.LocalName == "permStart") { ctObj.Items.Add(CT_PermStart.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.permStart); } - else if (childNode.LocalName == "proofErr") + else if(childNode.LocalName == "proofErr") { ctObj.Items.Add(CT_ProofErr.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.proofErr); } - else if (childNode.LocalName == "sdt") + else if(childNode.LocalName == "sdt") { ctObj.Items.Add(CT_SdtBlock.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.sdt); } - else if (childNode.LocalName == "tbl") + else if(childNode.LocalName == "tbl") { ctObj.Items.Add(CT_Tbl.Parse(childNode, namespaceManager)); ctObj.ItemsElementName.Add(DocumentBodyItemChoiceType.tbl); @@ -335,71 +335,71 @@ internal void Write(StreamWriter sw, string nodeName) sw.Write(string.Format(""); int i=0; - foreach (object o in this.Items) - { - if (o is CT_RunTrackChange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.moveTo) - ((CT_RunTrackChange)o).Write(sw, "moveTo"); - else if (o is CT_OMathPara) - ((CT_OMathPara)o).Write(sw, "oMathPara"); - else if (o is CT_CustomXmlBlock) - ((CT_CustomXmlBlock)o).Write(sw, "customXml"); - else if (o is CT_OMath) - ((CT_OMath)o).Write(sw, "oMath"); - else if (o is CT_AltChunk) - ((CT_AltChunk)o).Write(sw, "altChunk"); - else if ((o is CT_MarkupRange)&&this.itemsElementNameField[i]== DocumentBodyItemChoiceType.bookmarkEnd) - ((CT_MarkupRange)o).Write(sw, "bookmarkEnd"); - else if (o is CT_Bookmark && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.bookmarkStart) - ((CT_Bookmark)o).Write(sw, "bookmarkStart"); - else if (o is CT_MarkupRange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.commentRangeEnd) - ((CT_MarkupRange)o).Write(sw, "commentRangeEnd"); - else if (o is CT_MarkupRange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.commentRangeStart) - ((CT_MarkupRange)o).Write(sw, "commentRangeStart"); - else if (o is CT_Markup && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.customXmlDelRangeEnd) - ((CT_Markup)o).Write(sw, "customXmlDelRangeEnd"); - else if (o is CT_TrackChange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.customXmlDelRangeStart) - ((CT_TrackChange)o).Write(sw, "customXmlDelRangeStart"); - else if (o is CT_Markup && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.customXmlInsRangeEnd) - ((CT_Markup)o).Write(sw, "customXmlInsRangeEnd"); - else if (o is CT_TrackChange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.customXmlInsRangeStart) - ((CT_TrackChange)o).Write(sw, "customXmlInsRangeStart"); - else if (o is CT_Markup && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.customXmlMoveFromRangeEnd) - ((CT_Markup)o).Write(sw, "customXmlMoveFromRangeEnd"); - else if (o is CT_TrackChange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.customXmlMoveFromRangeStart) - ((CT_TrackChange)o).Write(sw, "customXmlMoveFromRangeStart"); - else if (o is CT_Markup && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.customXmlMoveToRangeEnd) - ((CT_Markup)o).Write(sw, "customXmlMoveToRangeEnd"); - else if (o is CT_TrackChange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.customXmlMoveToRangeStart) - ((CT_TrackChange)o).Write(sw, "customXmlMoveToRangeStart"); - else if (o is CT_RunTrackChange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.del) - ((CT_RunTrackChange)o).Write(sw, "del"); - else if (o is CT_RunTrackChange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.ins) - ((CT_RunTrackChange)o).Write(sw, "ins"); - else if (o is CT_RunTrackChange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.moveFrom) - ((CT_RunTrackChange)o).Write(sw, "moveFrom"); - else if (o is CT_MarkupRange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.moveFromRangeEnd) - ((CT_MarkupRange)o).Write(sw, "moveFromRangeEnd"); - else if (o is CT_MoveBookmark && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.moveFromRangeStart) - ((CT_MoveBookmark)o).Write(sw, "moveFromRangeStart"); - else if (o is CT_MarkupRange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.moveToRangeEnd) - ((CT_MarkupRange)o).Write(sw, "moveToRangeEnd"); - else if (o is CT_MoveBookmark && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.moveToRangeStart) - ((CT_MoveBookmark)o).Write(sw, "moveToRangeStart"); - else if (o is CT_P) - ((CT_P)o).Write(sw, "p"); - else if (o is CT_Perm) - ((CT_Perm)o).Write(sw, "permEnd"); - else if (o is CT_PermStart) - ((CT_PermStart)o).Write(sw, "permStart"); - else if (o is CT_ProofErr) - ((CT_ProofErr)o).Write(sw, "proofErr"); - else if (o is CT_SdtBlock) - ((CT_SdtBlock)o).Write(sw, "sdt"); - else if (o is CT_Tbl) - ((CT_Tbl)o).Write(sw, "tbl"); + foreach(object o in this.Items) + { + if(o is CT_RunTrackChange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.moveTo) + ((CT_RunTrackChange) o).Write(sw, "moveTo"); + else if(o is CT_OMathPara) + ((CT_OMathPara) o).Write(sw, "oMathPara"); + else if(o is CT_CustomXmlBlock) + ((CT_CustomXmlBlock) o).Write(sw, "customXml"); + else if(o is CT_OMath) + ((CT_OMath) o).Write(sw, "oMath"); + else if(o is CT_AltChunk) + ((CT_AltChunk) o).Write(sw, "altChunk"); + else if((o is CT_MarkupRange)&&this.itemsElementNameField[i]== DocumentBodyItemChoiceType.bookmarkEnd) + ((CT_MarkupRange) o).Write(sw, "bookmarkEnd"); + else if(o is CT_Bookmark && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.bookmarkStart) + ((CT_Bookmark) o).Write(sw, "bookmarkStart"); + else if(o is CT_MarkupRange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.commentRangeEnd) + ((CT_MarkupRange) o).Write(sw, "commentRangeEnd"); + else if(o is CT_MarkupRange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.commentRangeStart) + ((CT_MarkupRange) o).Write(sw, "commentRangeStart"); + else if(o is CT_Markup && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.customXmlDelRangeEnd) + ((CT_Markup) o).Write(sw, "customXmlDelRangeEnd"); + else if(o is CT_TrackChange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.customXmlDelRangeStart) + ((CT_TrackChange) o).Write(sw, "customXmlDelRangeStart"); + else if(o is CT_Markup && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.customXmlInsRangeEnd) + ((CT_Markup) o).Write(sw, "customXmlInsRangeEnd"); + else if(o is CT_TrackChange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.customXmlInsRangeStart) + ((CT_TrackChange) o).Write(sw, "customXmlInsRangeStart"); + else if(o is CT_Markup && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.customXmlMoveFromRangeEnd) + ((CT_Markup) o).Write(sw, "customXmlMoveFromRangeEnd"); + else if(o is CT_TrackChange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.customXmlMoveFromRangeStart) + ((CT_TrackChange) o).Write(sw, "customXmlMoveFromRangeStart"); + else if(o is CT_Markup && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.customXmlMoveToRangeEnd) + ((CT_Markup) o).Write(sw, "customXmlMoveToRangeEnd"); + else if(o is CT_TrackChange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.customXmlMoveToRangeStart) + ((CT_TrackChange) o).Write(sw, "customXmlMoveToRangeStart"); + else if(o is CT_RunTrackChange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.del) + ((CT_RunTrackChange) o).Write(sw, "del"); + else if(o is CT_RunTrackChange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.ins) + ((CT_RunTrackChange) o).Write(sw, "ins"); + else if(o is CT_RunTrackChange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.moveFrom) + ((CT_RunTrackChange) o).Write(sw, "moveFrom"); + else if(o is CT_MarkupRange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.moveFromRangeEnd) + ((CT_MarkupRange) o).Write(sw, "moveFromRangeEnd"); + else if(o is CT_MoveBookmark && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.moveFromRangeStart) + ((CT_MoveBookmark) o).Write(sw, "moveFromRangeStart"); + else if(o is CT_MarkupRange && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.moveToRangeEnd) + ((CT_MarkupRange) o).Write(sw, "moveToRangeEnd"); + else if(o is CT_MoveBookmark && this.itemsElementNameField[i] == DocumentBodyItemChoiceType.moveToRangeStart) + ((CT_MoveBookmark) o).Write(sw, "moveToRangeStart"); + else if(o is CT_P) + ((CT_P) o).Write(sw, "p"); + else if(o is CT_Perm) + ((CT_Perm) o).Write(sw, "permEnd"); + else if(o is CT_PermStart) + ((CT_PermStart) o).Write(sw, "permStart"); + else if(o is CT_ProofErr) + ((CT_ProofErr) o).Write(sw, "proofErr"); + else if(o is CT_SdtBlock) + ((CT_SdtBlock) o).Write(sw, "sdt"); + else if(o is CT_Tbl) + ((CT_Tbl) o).Write(sw, "tbl"); i++; } - if (this.sectPr != null) + if(this.sectPr != null) this.sectPr.Write(sw, "sectPr"); sw.WriteEndW(nodeName); } @@ -461,14 +461,14 @@ public ArrayList Items public CT_P AddNewP() { CT_P p = new CT_P(); - lock (this) + lock(this) { this.itemsField.Add(p); this.itemsElementNameField.Add(DocumentBodyItemChoiceType.p); } return p; } - + [XmlElement("ItemsElementName", Order = 1)] [XmlIgnore] public List ItemsElementName @@ -498,7 +498,7 @@ public CT_SectPr sectPr public CT_Tbl AddNewTbl(int? pos = null) { CT_Tbl tbl = new CT_Tbl(); - lock (this) + lock(this) { if(pos.HasValue) { @@ -562,15 +562,15 @@ public CT_SdtBlock AddNewSdt() return AddNewObject(DocumentBodyItemChoiceType.sdt); } #region Generic methods for object operation - + private List GetObjectList(DocumentBodyItemChoiceType type) where T : class { - lock (this) + lock(this) { List list = new List(); - for (int i = 0; i < itemsElementNameField.Count; i++) + for(int i = 0; i < itemsElementNameField.Count; i++) { - if (itemsElementNameField[i] == type) + if(itemsElementNameField[i] == type) list.Add(itemsField[i] as T); } return list; @@ -578,12 +578,12 @@ private List GetObjectList(DocumentBodyItemChoiceType type) where T : clas } private int SizeOfArray(DocumentBodyItemChoiceType type) { - lock (this) + lock(this) { int size = 0; - for (int i = 0; i < itemsElementNameField.Count; i++) + for(int i = 0; i < itemsElementNameField.Count; i++) { - if (itemsElementNameField[i] == type) + if(itemsElementNameField[i] == type) size++; } return size; @@ -591,10 +591,10 @@ private int SizeOfArray(DocumentBodyItemChoiceType type) } private T GetObjectArray(int p, DocumentBodyItemChoiceType type) where T : class { - lock (this) + lock(this) { int pos = GetObjectIndex(type, p); - if (pos < 0 || pos >= this.itemsField.Count) + if(pos < 0 || pos >= this.itemsField.Count) return null; return itemsField[pos] as T; } @@ -602,24 +602,24 @@ private T GetObjectArray(int p, DocumentBodyItemChoiceType type) where T : cl private T AddNewObject(DocumentBodyItemChoiceType type) where T : class, new() { T t = new T(); - lock (this) + lock(this) { this.itemsElementNameField.Add(type); this.itemsField.Add(t); } return t; } - private void SetObject (DocumentBodyItemChoiceType type, int p, T obj) where T : class + private void SetObject(DocumentBodyItemChoiceType type, int p, T obj) where T : class { - lock (this) + lock(this) { int pos = GetObjectIndex(type, p); - if (pos < 0 || pos >= this.itemsField.Count) + if(pos < 0 || pos >= this.itemsField.Count) return; - if (this.itemsField[pos] is T) + if(this.itemsField[pos] is T) this.itemsField[pos] = obj; else - throw new Exception(string.Format(@"object types are difference, itemsField[{0}] is {1}, and parameter obj is {2}", + throw new Exception(string.Format(@"object types are difference, itemsField[{0}] is {1}, and parameter obj is {2}", pos, this.itemsField[pos].GetType().Name, typeof(T).Name)); } } @@ -627,11 +627,11 @@ private int GetObjectIndex(DocumentBodyItemChoiceType type, int p) { int index = -1; int pos = 0; - for (int i = 0; i < itemsElementNameField.Count; i++) + for(int i = 0; i < itemsElementNameField.Count; i++) { - if (itemsElementNameField[i] == type) + if(itemsElementNameField[i] == type) { - if (pos == p) + if(pos == p) { index = i; break; @@ -644,10 +644,10 @@ private int GetObjectIndex(DocumentBodyItemChoiceType type, int p) } private void RemoveObject(DocumentBodyItemChoiceType type, int p) { - lock (this) + lock(this) { int pos = GetObjectIndex(type, p); - if (pos < 0 || pos >= this.itemsField.Count) + if(pos < 0 || pos >= this.itemsField.Count) return; itemsElementNameField.RemoveAt(pos); itemsField.RemoveAt(pos); @@ -670,78 +670,78 @@ public void SetPArray(int pos, CT_P cT_P) public enum DocumentBodyItemChoiceType { - + [XmlEnum("http://schemas.openxmlformats.org/officeDocument/2006/math:oMath")] oMath, - + [XmlEnum("http://schemas.openxmlformats.org/officeDocument/2006/math:oMathPara")] oMathPara, - + altChunk, - + bookmarkEnd, - + bookmarkStart, - + commentRangeEnd, - + commentRangeStart, - + customXml, - + customXmlDelRangeEnd, - + customXmlDelRangeStart, - + customXmlInsRangeEnd, - + customXmlInsRangeStart, - + customXmlMoveFromRangeEnd, - + customXmlMoveFromRangeStart, - + customXmlMoveToRangeEnd, - + customXmlMoveToRangeStart, - + del, - + ins, - + moveFrom, - + moveFromRangeEnd, - + moveFromRangeStart, - + moveTo, - + moveToRangeEnd, - + moveToRangeStart, /// @@ -749,19 +749,19 @@ public enum DocumentBodyItemChoiceType /// p, - + permEnd, - + permStart, - + proofErr, - + sdt, - + tbl, } @@ -951,13 +951,13 @@ public ST_DocPartBehavior val public enum ST_DocPartBehavior { - + content, - + p, - + pg, } @@ -1035,118 +1035,118 @@ public ST_DocPartGallery val public enum ST_DocPartGallery { - + placeholder, - + any, - + @default, - + docParts, - + coverPg, - + eq, - + ftrs, - + hdrs, - + pgNum, - + tbls, - + watermarks, - + autoTxt, - + txtBox, - + pgNumT, - + pgNumB, - + pgNumMargins, - + tblOfContents, - + bib, - + custQuickParts, - + custCoverPg, - + custEq, - + custFtrs, - + custHdrs, - + custPgNum, - + custTbls, - + custWatermarks, - + custAutoTxt, - + custTxtBox, - + custPgNumT, - + custPgNumB, - + custPgNumMargins, - + custTblOfContents, - + custBib, - + custom1, - + custom2, - + custom3, - + custom4, - + custom5, } @@ -1289,25 +1289,25 @@ public ST_DocPartType val public enum ST_DocPartType { - + none, - + normal, - + autoExp, - + toolbar, - + speller, - + formFld, - + bbPlcHdr, } @@ -1316,25 +1316,25 @@ public enum ST_DocPartType public enum ItemsChoiceType11 { - + behaviors, - + category, - + description, - + guid, - + name, - + style, - + types, } @@ -1359,11 +1359,11 @@ public CT_DocGrid() public static CT_DocGrid Parse(XmlNode node, XmlNamespaceManager namespaceManager) { - if (node == null) + if(node == null) return null; CT_DocGrid ctObj = new CT_DocGrid(); - if (node.Attributes["w:type"] != null) - ctObj.type = (ST_DocGrid)Enum.Parse(typeof(ST_DocGrid), node.Attributes["w:type"].Value); + if(node.Attributes["w:type"] != null) + ctObj.type = (ST_DocGrid) Enum.Parse(typeof(ST_DocGrid), node.Attributes["w:type"].Value); ctObj.linePitch = XmlHelper.ReadString(node.Attributes["w:linePitch"]); ctObj.charSpace = XmlHelper.ReadString(node.Attributes["w:charSpace"]); return ctObj; @@ -1440,16 +1440,16 @@ public string charSpace public enum ST_DocGrid { - + @default, - + lines, - + linesAndChars, - + snapToChars, } @@ -1479,6 +1479,33 @@ public List docVar this.docVarField = value; } } + + public static CT_DocVars Parse(XmlNode node, XmlNamespaceManager namespaceManager) + { + if(node == null) + return null; + + CT_DocVars ctObj = new CT_DocVars(); + ctObj.docVar = new List(); + foreach(XmlNode childNode in node.ChildNodes) + ctObj.docVar.Add(CT_DocVar.Parse(childNode, namespaceManager)); + + return ctObj; + } + + internal void Write(StreamWriter sw, string nodeName) + { + sw.Write(string.Format(""); + if(this.docVar != null) + { + foreach(CT_DocVar x in this.docVar) + { + x.Write(sw, "docVar"); + } + } + sw.WriteEndW(nodeName); + } } } diff --git a/OpenXmlFormats/Wordprocessing/Settings.cs b/OpenXmlFormats/Wordprocessing/Settings.cs index e7c5e224d..ca4f35c3f 100644 --- a/OpenXmlFormats/Wordprocessing/Settings.cs +++ b/OpenXmlFormats/Wordprocessing/Settings.cs @@ -22,7 +22,6 @@ public static CT_Settings Parse(XmlNode node, XmlNamespaceManager namespaceManag return null; CT_Settings ctObj = new CT_Settings(); ctObj.activeWritingStyle = new List(); - ctObj.docVars = new List(); ctObj.attachedSchema = new List(); ctObj.smartTagType = new List(); ctObj.schemaLibrary = new List(); @@ -219,7 +218,7 @@ public static CT_Settings Parse(XmlNode node, XmlNamespaceManager namespaceManag else if (childNode.LocalName == "activeWritingStyle") ctObj.activeWritingStyle.Add(CT_WritingStyle.Parse(childNode, namespaceManager)); else if (childNode.LocalName == "docVars") - ctObj.docVars.Add(CT_DocVar.Parse(childNode, namespaceManager)); + ctObj.docVars = CT_DocVars.Parse(childNode, namespaceManager); else if (childNode.LocalName == "attachedSchema") ctObj.attachedSchema.Add(CT_String.Parse(childNode, namespaceManager)); else if (childNode.LocalName == "smartTagType") @@ -433,12 +432,7 @@ internal void Write(StreamWriter sw) } } if (this.docVars != null) - { - foreach (CT_DocVar x in this.docVars) - { - x.Write(sw, "docVars"); - } - } + this.docVars.Write(sw, "docVars"); if (this.attachedSchema != null) { foreach (CT_String x in this.attachedSchema) @@ -625,7 +619,7 @@ internal void Write(StreamWriter sw) private CT_Compat compatField; - private List docVarsField; + private CT_DocVars docVarsField; private CT_DocRsids rsidsField; @@ -1840,9 +1834,8 @@ public CT_Compat compat } } - [XmlArray(Order = 81)] - [XmlArrayItem("docVar", IsNullable = false)] - public List docVars + [XmlElement(Order = 81)] + public CT_DocVars docVars { get { @@ -6105,8 +6098,10 @@ public static CT_DocVar Parse(XmlNode node, XmlNamespaceManager namespaceManager if (node == null) return null; CT_DocVar ctObj = new CT_DocVar(); + ctObj.name = XmlHelper.ReadString(node.Attributes["w:name"]); ctObj.val = XmlHelper.ReadString(node.Attributes["w:val"]); + return ctObj; } diff --git a/testcases/ooxml/XWPF/UserModel/TestXWPFDocument.cs b/testcases/ooxml/XWPF/UserModel/TestXWPFDocument.cs index c8ddeadbf..af7a95dc8 100644 --- a/testcases/ooxml/XWPF/UserModel/TestXWPFDocument.cs +++ b/testcases/ooxml/XWPF/UserModel/TestXWPFDocument.cs @@ -19,6 +19,7 @@ namespace TestCases.XWPF.UserModel { using NPOI; using NPOI.OpenXml4Net.OPC; + using NPOI.OpenXmlFormats.Wordprocessing; using NPOI.Util; using NPOI.XWPF; using NPOI.XWPF.Extractor; @@ -40,13 +41,13 @@ public void TestContainsMainContentType() OPCPackage pack = doc.Package; bool found = false; - foreach (PackagePart part in pack.GetParts()) + foreach(PackagePart part in pack.GetParts()) { - if (part.ContentType.Equals(XWPFRelation.DOCUMENT.ContentType)) + if(part.ContentType.Equals(XWPFRelation.DOCUMENT.ContentType)) { found = true; } - if (false == found) + if(false == found) { // successful tests should be silent System.Console.WriteLine(part); @@ -143,7 +144,7 @@ public void TestAddPicture() byte[] newJpeg = ((XWPFPictureData)doc.GetRelationById(relationId)).Data; Assert.AreEqual(newJpeg.Length, jpeg.Length); - for (int i = 0; i < jpeg.Length; i++) + for(int i = 0; i < jpeg.Length; i++) { Assert.AreEqual(newJpeg[i], jpeg[i]); } @@ -153,17 +154,17 @@ public void TestAllPictureFormats() { XWPFDocument doc = new XWPFDocument(); - doc.AddPictureData(new byte[10], (int)PictureType.EMF); - doc.AddPictureData(new byte[11], (int)PictureType.WMF); - doc.AddPictureData(new byte[12], (int)PictureType.PICT); - doc.AddPictureData(new byte[13], (int)PictureType.JPEG); - doc.AddPictureData(new byte[14], (int)PictureType.PNG); - doc.AddPictureData(new byte[15], (int)PictureType.DIB); - doc.AddPictureData(new byte[16], (int)PictureType.GIF); - doc.AddPictureData(new byte[17], (int)PictureType.TIFF); - doc.AddPictureData(new byte[18], (int)PictureType.EPS); - doc.AddPictureData(new byte[19], (int)PictureType.BMP); - doc.AddPictureData(new byte[20], (int)PictureType.WPG); + doc.AddPictureData(new byte[10], (int) PictureType.EMF); + doc.AddPictureData(new byte[11], (int) PictureType.WMF); + doc.AddPictureData(new byte[12], (int) PictureType.PICT); + doc.AddPictureData(new byte[13], (int) PictureType.JPEG); + doc.AddPictureData(new byte[14], (int) PictureType.PNG); + doc.AddPictureData(new byte[15], (int) PictureType.DIB); + doc.AddPictureData(new byte[16], (int) PictureType.GIF); + doc.AddPictureData(new byte[17], (int) PictureType.TIFF); + doc.AddPictureData(new byte[18], (int) PictureType.EPS); + doc.AddPictureData(new byte[19], (int) PictureType.BMP); + doc.AddPictureData(new byte[20], (int) PictureType.WPG); Assert.AreEqual(11, doc.AllPictures.Count); @@ -287,7 +288,7 @@ public void TestGetAllPictures() Assert.IsNotNull(allPictures); Assert.AreEqual(3, allPictures.Count); - foreach (XWPFPictureData xwpfPictureData in allPictures) + foreach(XWPFPictureData xwpfPictureData in allPictures) { Assert.IsTrue(allPackagePictures.Contains(xwpfPictureData)); } @@ -297,7 +298,7 @@ public void TestGetAllPictures() allPictures.Add(allPictures[0]); Assert.Fail("This list must be unmodifiable!"); } - catch (NotSupportedException) + catch(NotSupportedException) { // all ok } @@ -319,7 +320,7 @@ public void TestGetAllPackagePictures() allPackagePictures.Add(allPackagePictures[0]); Assert.Fail("This list must be unmodifiable!"); } - catch (NotSupportedException) + catch(NotSupportedException) { // all ok } @@ -406,22 +407,49 @@ public void TestEnforcedWith() } [Test] - [Ignore("XWPF should be able to write to a new Stream when opened Read-Only")] - public void TestWriteFromReadOnlyOPC() { - OPCPackage opc = OPCPackage.Open( - POIDataSamples.GetDocumentInstance().GetFileInfo("SampleDoc.docx"), - PackageAccess.READ - ); - XWPFDocument doc = new XWPFDocument(opc); - XWPFWordExtractor ext = new XWPFWordExtractor(doc); - String origText = ext.Text; - - doc = XWPFTestDataSamples.WriteOutAndReadBack(doc); - ext = new XWPFWordExtractor(doc); - - Assert.AreEqual(origText, ext.Text); - } + [Ignore("XWPF should be able to write to a new Stream when opened Read-Only")] + public void TestWriteFromReadOnlyOPC() + { + OPCPackage opc = OPCPackage.Open( + POIDataSamples.GetDocumentInstance().GetFileInfo("SampleDoc.docx"), + PackageAccess.READ + ); + XWPFDocument doc = new XWPFDocument(opc); + XWPFWordExtractor ext = new XWPFWordExtractor(doc); + String origText = ext.Text; - } + doc = XWPFTestDataSamples.WriteOutAndReadBack(doc); + ext = new XWPFWordExtractor(doc); + + Assert.AreEqual(origText, ext.Text); + } + [Test] + public void TestDocVars() + { + XWPFDocument doc = XWPFTestDataSamples.OpenSampleDocument("docVars.docx"); + + foreach(var part in doc.RelationParts) + { + var relationType = part.Relationship.RelationshipType; + if(relationType == XWPFRelation.SETTINGS.Relation) + { + var settingsPart = (XWPFSettings)part.DocumentPart; + + using(var stream = settingsPart.GetPackagePart().GetInputStream()) + { + var xmldoc = POIXMLDocumentPart.ConvertStreamToXml(stream); + var ctSettings = SettingsDocument.Parse(xmldoc, POIXMLDocumentPart.NamespaceManager).Settings; + var variables = ctSettings.docVars; + + Assert.IsNotNull(variables); + Assert.AreEqual(5, variables.docVar.Count); + + for(int i = 0; i-E6E$LC}yiSpZ1z-~adeUpxaf@x$`n%xK~_QV*hA3^GeqLhx^n z{Q5Cyl>|C!sY?U(s`AU*&8BM5MRL(=mc?XDkNI6oKEY+zzWIh>IJJ^cqIanQEANrJ zTw+WTm-LWff)Mzw%MFfdQOGcR{pzcJ6+$$taItjkQ@%U4P-~N5CvKQM4k}|q0 zc^>Q-Np|fql5dUg1m8XN?)(CwsPZn?k7)DkO~JmEa_iDDi!}iH)meKPRqWN^g|IgP zjp9d>VQ~>#g+5LWxHT`&MwE7NU_C!W0Tlnj&ScdOFi&91I+%Pf!0gm>FtK)IV*Gjk zFDw5SQ}LIdUJ@%O3&nyKbmI3+Hqy$wNJ~DotSh!BXZ#2u%6jjciW*y3_q;+A#yC?O zOw8uKJIE$Fo7zhBm9C%NO}(>2+?K{y)E;TsSv+GQE4G5a1^Ux z2kjQK&UR7wqIHgUSU!@^w*|)~Xq3EXiNs`Jx**7~U)lHU2TRgRWq5H3C}K{nbl~Mp zjk)GPG@2!e`^qi_3v~_OZdhI@Nh&7^a!UDm+UOOx%_U=K{d37K+eK+WT$E-z)IZUs zh@1722y8ih0RW(b=g8I8!I;U|*2vigyrTVF%5oC*Y*U%hI##KVcu7~@8<8T2%M~%~ z7YV#AnmvZ%>O)Xtk*FKY^!|~4_p)kAHJ}Y}ZQstjdNW(`WY8AEpz+wwag4_2ruO;h1z*L?)7*lZGd|B6+D+2$;~FOjdP-v(fBib^01;mh=vX+w0~M7uLs)>FKjh=xl~-NlpIb!YY~Ys2L!Piz5~zIltr9m?F_>xvf@hH-yJa5abq`^p30enq>(g zPS0`f;vtzNV0k9YMk*PP?hN#;zEDq7>DmCB>Gj;$zNwT6FiX?iY-;oJ>LEGdwq_^kDFVR=Vo!{=iXUy5zv|~rZaqnu9vini@SoPeq$kL5&Y#hESM-k z%;L2!m5)5|e z6ptz;TYUZs^QGh|KP5;?fF|_^*Cw~;Mvz}pXH6`~CG@LVy8DdISDcUF^6&3U&#ZB^ z(j}NfEMPtn0^lM3;L^X=pI;gEpS1`ATp@z}{O`U>VuvmNsE`7m{6Bj$@OmqXY+1{Y zEzUjy#EAt9=n+OQ*W1gbqz@+an@%0dK0A*4a4e2@hPi&4@yyQ}a6sGpRPH%P>sCly zek_b;rEYaVM2j1v|6W(uI%C38UUufnR}93ZJi!uN8*j`*$ZjH#CCd~M<-fz;rv_`I z>m2TouFWzC<{7K%sU9hsor^QV!0E*TA?_r@@B z%(7z9yW(oHVG|_bMy&aY^hF)ny@eeH8O7~7RTL*1wF( z+@m2=5b(GIHw=G|noE_TXMW7oM!gZC(4sPTPk;YOquD}U|1QwABqdG80KI0 z%fGQx$&r2h65DqzRW}mb=bPITM5NQ^c)3rwAJ^x(zOft+q8NcO(4;F!ql1GtBMX

Kp2aX?M0R{!8DUOwuwaYuee2!kNtd_mA zWeX<`I+T_3_QrtK!u@i8&a4&0Rhkp0B4jvQ zAq1*#b_hCUUpW`6zm1VWNicb?k80J<&42ECp)#nY)9C$5y|fndn0e(LAWl1)Qq+O9 z3kn{q3_1RiTiBCQK8F~#j#=Z;{T)qW%4LXDK-wo`x?5vtOC!wax$zGkkB106jW?HD zE9KNTCz(t4y++P>Rr7ToSKUd^d_RyLAGey-QQNLJ10$XZH&k{&zY}UeUiJz}7 z&%%TCS{}}P;o7>t*mk2zhru+3MNJ|n7KOUQc6dLTVh1CjEgDjX!x(4T@a>hoCA|EK zpm@6GQc2MHUK_y|)y=}IpUf-zw33o|ErHV6=l;{APG75I6R5u`n|aLedCkju69^!@ z>jN@v)$*mvLqirI|=G@Pt8AW}w5lL$}j*DjNgvD5XWsVcVNg14T zQj*uT$11I=`%1u%c2(Z`+V+c%g!eJ;?SOcZ4#dnZ#yjdyN&56;SFAzt3j_Sop;23% z0m1Sefhx(7EG7j624r3wbGJQTJjD@01dr~WVw=yZ65Nd5p+R$GmV|} z-hE^mE55$?LDi^e;E0~7Qy-D)w7u*pM8hBbGVCT`()LRp&Xr1bA#V1a>c{wk4JR%* z97kr8p5%x4fh|(s82mg#iICnIXZnc{geyOTl-4$9IHLS}`l0u93EviTSpk|gNmdsw z&MN~gwJS8b**nK_3>@XnY>*4ra#9-pjg%bxl=#(s@1#B_mj;SYcW<<~w8sXzzpVyc zlR!QWidcGGPS>Eyf$tG%7O!3Hbxm$Y>=JvX?<3j>$}K2r zTMDheVd!k?>I=IR#vsZTAi5yPf>gCqaRN|~Z}Fv|ug`8Uf*MHGr%U%9zN=a*Wo1L> zQHL??a4*I0I+eKN=7m=~983>h8l~sd3pguqP7x)VmvISQ7VghQxw;O#FF{;()!3eD zEpQ%9o-O5}T6q$xD8TaPo?$matp$C}t?PT?`)0|@qKt=P)*GL`Ov_tn|;bn%P|I3>LxpHMd*FZO=v6h!u#SKjQ|yEFBW zU7C8|TF(#>4j_!iC8pcnYEo0(tBl^6zr6P~Yq7HhjcPsB;%4}&$aU(7Cc-VWV9jk| z+32hH{m!_c?#U}eD`d+eD8`1A3d4ocnlkFgHd@+|Xb&pO5eV%UgV8|>jr(krwkb{O z@M;ut4kDo|H=CWLM;@Gp3pSLQZaDlBh_B-{tc+OE58k}4ct*fJ=f3BO%ca2&YOLeE zrpiO}Un?T7MO>LL_kgNEl&=%y?Ma->st<=9=Q@@jsH%07ck9ba1a-)C!m!{&Qa)7J zpLZxV-_Xr3l1w&1UYP5v_s2x(?vQ?1BV{-}8um(aBk``_yA~Zvx|4n{xD`E5^H{4N zNfIQ-q@xQpm2f?=vaq^MMC6TSV=Cwq1|gXp|;&yjXQIEgYz zs_E%^yFYBOH|RyE1LC?6o=a9N4+qZ$4r9;5JXKq*LmXVS&tVJ1Y~xEmXO}qqVMr}h z8Y||#Yh)kI$YJYpc2l~}+Nv%>dB9d3CP}~;{%i5>VaHEG*OV<7BA&P&QYCB=>^&Uc zq^OpS#dzLe(bhCrLTg97c&1BVxM`uu8lOSv?UP{j}c6>0W;Qt(|geh%V_OT|3gAXrx909i-~1ngPRtJ8R(Ff ztlr~?+?p6N@5SZ&RiL?ay>yVaYBsYH*0ctV_Squ7jgm0asH*T1rk&$z^MR&?r&-K% zaxXiY?S`Whg4=LDy~5kJObj6k?z7DKLnJfo@lfpM(nCXx&tW%}K7oGT4Q8t0$N*8s z**SljpO0kHx?a?p8H7I2c012x*^iqZOyXx)(#{%n243Pdos&^yf_a$rGHu8t@9^tn zy7Loa)dq1^jbyUbEViN?o#1g#hg{C^Xv((Zg!v+aL-Wb}iK9CQ-4cJypHL_)_FSw# z93GNkL`>T|;WH5nCx*L4XQc6oZJ2XMVN)o$_e(i&@P+OaPX`aU)$z$q_0H#aWTwiE zxLr#JC0GohIAXu(agbKr9YV76&W;&Q*j*?k7abNwx%0!fSvgTey)D&0XGK#GNqC86sfO=O&sxFrSLx*B} zh7N7J++SMb&XZ%tIXS_eSi?BEp5E1RL&bI#7&FBtK2hVTeuYiq)vlbJtlO<#P^L4y zlWM+@8&qObY<^2?a9K}s_v-rd5gHNi$cL;hLhPEy4bpJ`Ln&Kammg(8CKKM7%MtACtwxe8IT)O4wGvbJbVH5B!sDj(QxXAQ}dby6aF%zY0cElE-s`< zF(L`5>*I$hzXk{Y^_%=D!&|lnO8lqwBI&`2QaqsHqOor3g4uCKS?4DQ?^S=iXUNiJ zwmP{pQF_zJ*YKEjb!K-4w70|Q;TSL~+TDOJfd+)(k2aMwESQc45_LUE>t2;UgOeC& zNG=R~4yQNfm{j|2&Qsz2#qLbfajGXyiIJYwREize5MsmWI6pRx3Lu8YgN^`-aL)Q3q9Q*m0|-EO{h3kj*pE3N!l4P%;+6)48bUsVE}4i`5b*7iF?bS zg_6~MV^%WdIY>rR)42wYWC03C`nB8JVi^~naeQ5QjY%VHYHS*_$~7##xpHGOttfVx z6eg6bX1+y8c>^Dc7k1dwlDM04!=GhkI8^8GDz(*1UB&uU zl%n$26IzK8|ICGxnKPAiE^|Ef+OsRq#ENg)Z&G45bcvs&tHP7#3BB6cQd!!xq{GAU z(BXz%hwN57mRs<>U*9W?YL4?TPHVlot4g-oQfg}3IYUjMw{l-IbSX%Q)mzb7hVKhZ zQ>a^Iuoz?1jGgG>Dwom}d6u`ZSD!S#f7Hvoil6v^ej!J;O42Sct!1owzR!}Eo1(up z=~rNISA@jsd@Y!M1S0zKW%`}WOb$Ln2e#x8i1h~uJ=KiJ*D>m*hyUBl8z+UOYJPjY zlhAupg{4&}M2*aaAux}bmV3>|u6`tdh z9QF+o>N~fOk`DF~lhE}fzdx*>nJn&~x-yjTZ!oc+Wz4-9znPa|^OdN#3`HWO)N^+l zErLj==6$qzXI7GhzdEvgZ{5Li6>QZ}3H#Pk=mkE5rtT0I1R#@woWdG6={osQiNhr-Zuw5Z62zj$tlZ0XKeky3Xy;1kH9Gog%&8 z=3yXEuxZEG=~dD!Gzz$;D-`YX48Cj}-WrL`S>eyEC*nfk(e5A_Hw5MtSm-(k_q-$B z%Kx+y_oWJ5ycylAlq1!B(wYQDsEGW{3%APUHIdKi61<17sO7Q z96sT=;1KSo3{#8ydJNnf!{XA$Q`63+~9p2oDpeDa<62qE4`WM&?C_0P0W;DqI17f zRbgMi`Dmt`n&ZXREGG$lx`7+KM=g+ccY$X|PUS;!n`~m|5WpaGy%kc)+3ceQC>^xN z$VDAPz#*DOpKh6#Q{f}`!SM!lp{aqoMsz~Ma-i*?Nw)n%5t~=4Ut$^Ax2TCHw!d{f zl)87>ennAYer#D+&#d6ZP|BYWN1-5FJiyC+T~kxWqae@6P-=3z<Ls zo!YXKHFZ$AInb}%1N{61gp^XChGi@vfKi)|=#sX{$5XNN0yQBh7TQ3{SibO2T9EjX zTc^ZTcod3GTPx=y6Ooy=3>`m%4a-y;AtGy&ZKu2_3&x}Z5*A(wV6-}Nclh~o~Te5kzl7H zoVgpVj+7v%V(=TYn2K!Bn<_0<_yNno*`jGeHHKtRBSPDE@RPL(fs{WTx1j=vsbRp0 zNd2Zn3qKY=vj7OGVyRKP6_2mR5FvwHoG6hSq$&$6H269dJyT(6A!Yfnb@(bP2mE2S za(7X#64(;^9*kh8{Fetc24rb|dtn#D)Bn*7_L}w|<5U6I>mb9QSg#OyBA40GFDYl&l4?l(4}tIajz!Z;PyN==0`|e zGH?pCrWIZ%?9MqHGMVPyp{hz>*j3aacyA<7qCbuZZmZ1*>{NKqWL~#DB5SnUl60F3 zpvPdtxylAE3ZS2SLDX zbs)Rh#gwPO*`bP$qvN> zPqVzps^EwBOpy#sDF~WJ#tGRxlq*E%e25uD#%s;5Uoe z#cZo8TX^HiBtwo-aai5#$`5*B<56>iGRBw*oJGQ@xm*yTM>}T*%UDE*D`XN+v8-x* zSn^4r$V!GBN*(`q?7i50?Ip}ySa%$Ux$o8wCgj8Is!AsAV4Xs073Iz0s+S0;~&u?o#Hh*~ho~Lt^%e>(4^+i2x z>x0GHRzyfSnW0MEffPjeSx*hwe7r|H*W2;zfkeH+NVwkAT^Syad8codN z+^C!nlD?z8ut^$8M&#*pYv+Evjt897#W!$dSSzYRehBCK@O*G}3a3+yKv@O(dWLyq z_PS%Hq`5Nao#^&Xti{(mkZ-V+r_l^0wYLSFs>EfDdBYU_4DTp|5H-hwSD)?aeVykhU%a`d{(@a1M545puBd06*w1~QCp^%R-Wg5s_&d0kKi-jzjs@v z9U3z>V7iBcBM=>YY6U*3QgpDjb7V5Ib@(Irz_N+|9#w&984x=x(=CJJYSK%IXyVT@tgm-nsFHM^V~k@gm4pMYC>v8LBAdUWt^jPp5-a&Nq9 z=CfZk{VtgUJpo>aMFz6~;-nlOv*$o`*l9oxcQBeNsgmHr>I?JrY3+`Lffs0DzU(!j zvYFUq_;jkbxUxJ!pQL18YI6oR4unkQ;;#EmAmBl`*xbXLWl4!(c1BFl^H6BfzFc@6 zE*Vqj7hotw231DsLJwE22}2&o3%4)^o6Mq$Rq;~i4X?*5O}Io8iv->9?+++#%`FYU za!b~g!!XD&zknYq0Hwwd;vxipfNhIKT@pqi;}s|vDR!E+Nbh^*5AP?Hk287_k31jC z+7A?TT3~LOmPTHDuG%RU2g*8`RA_f@FiRm3E$eAJeQmrN8{32k(_Z9fwi$O)FwEa2 zx%OIYvvmNDmIr=g?P!;HY^ZcR^t`UKrwUoQOP_6MsxIdW@zdjlo)$7BFN67*CoVY(0z*6TqQ+uUMc6gQc22m$w6;UqC0mE z6`5;mcY5Eio5HU+i{}Le83AsR=Y!tV(1E;O6CJAWZ4S*B1U0gO8=c&A6=H%;$#NQg z+V?52Th{VVlNg+qFQmtyNqib^DrFqVZUH?W`JgE&sCXt_gpA}3XZTt3Kz7Z$vAw;x z^2&zeZET&!HTSSAY>q4vP^W(yVn*slslERvi0G1nI;FtnxVlLUf>QdDLU&ENRH4&V z6nmJW_lFUz>23UsH(8VY_HrSrPt*@RVOHq0K@qFpqL<3~x?p7#kW zf{P?aoSprOs25>`sqXo%fc((b$zd`t+8TCqGM%}ZS5Klh^mEHrxGH824krD!51mcd za*B}>qmp9PPoIIJ`%KLQ?)bZfY>UsWoy)Iik+^uubdk+!dE8UJ6-KmUv+W?fVdEH{9STs>mmFz{`Bi7rRLO*E81Iw?o{%Yj@k_PLn z?QJq7pNIqPTPr#!;z!q38tr|fZLURTIW8;DrSl_7(n&^9_R9_kI-S|1zYv0OSF=p3 zHrAfPteqXJsuxG?FI)H?{YZqVbyiJJBl@X!St6mDOihHCUqfP7y8FER zWFb5pRyuov_9@>4(YGk~ z9{vUYzdPo?gMaVv{sga){u}&TzxTU`-&>YHJt&d?+rwWPnBVb#Ejs^10|4Wc0Knf$ z(BI*Itp|REJ5v7w|95rpJNmDg@>g^c?JsDf|C=`zWnsYa1ppv{ACTY>eWL&Q?*9OT Cxn