Footnotes initial support (#718)

* Initial footnotes support: add content-types dependency

* Initial footnotes support: add relationship

* Initial footnotes support: add footnotes.xml

* Initial footnotes support: add footnote_reference() for XMLBuilder

* Initial footnotes support: add FootnoteReference to RunChild

* Initial footnotes support: add footnotes to XMLDocx

* Initial footnotes support: add footnotes module

* Initial footnotes support: add footnote and footnote_reference modules

* Initial footnotes support: add footnotes handling logic

* Initial footnotes support: add footnotes example

* Initial footnotes support: add footnote element

* Initial footnotes support: add footnote_reference element

* Initial footnotes support: add footnotes document

* Initial footnotes support: add open_footnotes for XMLBuilder

* Initial footnotes support: add test for footnotes reading

* Initial footnotes support: update snapshots for footnotes

* Initial footnotes support: add test docx for footnotes reading

* Initial footnotes support: update features list

* Initial footnotes support: update snapshots for footnotes

* Initial footnotes support: fix clippy lint - redundant-clone

* Initial footnotes support: add automatic footnote ID generation

* Initial footnotes support: add footnote_id module

* Initial footnotes support: switch to automatically generated IDs

* Initial footnotes support: switch to automatically generated IDs
main
git-noise 2024-06-24 07:37:27 -04:00 committed by GitHub
parent f8c84a2e5e
commit 0ef897ed85
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
57 changed files with 711 additions and 45 deletions

View File

@ -100,14 +100,14 @@ writeFileSync("hello.docx", buffer);
You can run example with following code.
Please see `examples` directory.
``` sh
```sh
$ cargo run --example [EXAMPLE_NAME]
```
For Example if you want to run `hello` example.
Please run following command.
``` sh
```sh
$ cargo run --example hello
```
@ -165,6 +165,7 @@ $ yarn test -- --updateSnapshot
- [x] vanish
- [x] Italic
- [x] TextBorder
- [x] Footnote
- [x] Break
- [x] Header
- [x] Footer
@ -176,4 +177,3 @@ $ yarn test -- --updateSnapshot
- [x] Table of contents
- [ ] Section
- [ ] Textbox

View File

@ -0,0 +1,20 @@
use docx_rs::*;
pub fn main() -> Result<(), DocxError> {
let path = std::path::Path::new("./footnotes.docx");
let file = std::fs::File::create(path).unwrap();
Docx::new()
.add_paragraph(
Paragraph::new()
.add_run(Run::new().add_text("Hello"))
.add_run(
Run::new().add_footnote_reference(
Footnote::new()
.add_content(Paragraph::new().add_run(Run::new().add_text("World"))),
),
),
)
.build()
.pack(file)?;
Ok(())
}

View File

@ -130,6 +130,14 @@ impl ContentTypes {
);
self
}
pub fn add_footnotes(mut self) -> Self {
self.types.insert(
"/word/footnotes.xml".to_owned(),
"application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml"
.to_owned(),
);
self
}
}
impl Default for ContentTypes {

View File

@ -9,6 +9,7 @@ use crate::{escape::*, xml_builder::*};
pub struct DocumentRels {
pub has_comments: bool,
pub has_numberings: bool,
pub has_footnotes: bool,
pub images: Vec<(String, String)>,
pub hyperlinks: Vec<(String, String, String)>,
pub custom_xml_count: usize,
@ -86,6 +87,14 @@ impl BuildXML for DocumentRels {
)
}
if self.has_footnotes {
b = b.relationship(
"rId8",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes",
"footnotes.xml",
)
}
for i in 0..self.header_count {
b = b.relationship(
&create_header_rid(i + 1),

View File

@ -0,0 +1,93 @@
use serde::Serialize;
use crate::documents::*;
use crate::xml_builder::*;
use footnote_id::generate_footnote_id;
#[derive(Serialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Footnote {
pub id: usize,
pub content: Vec<Paragraph>,
}
impl Default for Footnote {
fn default() -> Self {
Footnote {
id: 1,
content: vec![],
}
}
}
impl Footnote {
pub fn new() -> Self {
Self {
id: generate_footnote_id(),
..Default::default()
}
}
pub fn id(&self) -> usize {
self.id
}
pub fn add_content(&mut self, p: Paragraph) -> Self {
self.content.push(p);
self.clone()
}
}
impl From<&FootnoteReference> for Footnote {
fn from(reference: &FootnoteReference) -> Self {
Footnote {
id: reference.id,
content: reference.content.clone(),
}
}
}
impl BuildXML for Footnote {
fn build(&self) -> Vec<u8> {
// To ensure docx compatible XML serialization for footnotes, we default to an empty paragraph.
let mut footnote = self.clone();
if self.content == vec![] {
eprintln!("{:?}", footnote);
footnote.add_content(Paragraph::new());
}
XMLBuilder::new()
.open_footnote(&format!("{}", self.id))
.add_children(&footnote.content)
.close()
.build()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(test)]
use pretty_assertions::assert_eq;
use std::str;
#[test]
fn test_footnote_build_default() {
let b = Footnote::new().build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:footnote w:id="1"><w:p w14:paraId="12345678"><w:pPr><w:rPr /></w:pPr></w:p></w:footnote>"#
);
}
#[test]
fn test_footnote_build_with_paragraph() {
let b = Footnote::new()
.add_content(Paragraph::new().add_run(Run::new().add_text("hello")))
.build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:footnote w:id="1"><w:p w14:paraId="12345678"><w:pPr><w:rPr /></w:pPr><w:r><w:rPr /><w:t xml:space="preserve">hello</w:t></w:r></w:p></w:footnote>"#
);
}
}

View File

@ -0,0 +1,76 @@
use serde::ser::{Serialize, SerializeStruct, Serializer};
use crate::documents::BuildXML;
use crate::{xml_builder::*, Footnote, Paragraph};
#[derive(Debug, Clone, PartialEq)]
pub struct FootnoteReference {
pub id: usize,
pub style: String,
pub content: Vec<Paragraph>,
}
impl FootnoteReference {
pub fn new(id: usize) -> Self {
FootnoteReference {
id,
style: "FootnoteReference".to_string(),
content: vec![],
}
}
/// Add footnote content as a Paragraph
pub fn footnote(&mut self, p: Paragraph) {
self.content.push(p)
}
}
impl From<Footnote> for FootnoteReference {
fn from(footnote: Footnote) -> Self {
FootnoteReference {
id: footnote.id,
style: "FootnoteReference".to_string(),
content: footnote.content,
}
}
}
impl BuildXML for FootnoteReference {
fn build(&self) -> Vec<u8> {
XMLBuilder::new().footnote_reference(self.id).build()
}
}
impl Serialize for FootnoteReference {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut t = serializer.serialize_struct("FootnoteReference", 2)?;
t.serialize_field("id", &self.id)?;
t.end()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(test)]
use pretty_assertions::assert_eq;
use std::str;
#[test]
fn test_footnotereference_build() {
let b = FootnoteReference::new(1).build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:footnoteReference w:id="1" />"#
);
}
#[test]
fn test_footnotereference_json() {
let t = FootnoteReference::new(1);
assert_eq!(serde_json::to_string(&t).unwrap(), r#"{"id":1}"#);
}
}

View File

@ -31,6 +31,8 @@ mod fld_char;
mod font;
mod font_scheme;
mod footer_reference;
mod footnote;
mod footnote_reference;
mod frame_property;
mod grid_span;
mod header_reference;
@ -165,6 +167,8 @@ pub use fld_char::*;
pub use font::*;
pub use font_scheme::*;
pub use footer_reference::*;
pub use footnote::*;
pub use footnote_reference::*;
pub use frame_property::*;
pub use grid_span::*;
pub use header_reference::*;

View File

@ -39,6 +39,7 @@ pub enum RunChild {
DeleteInstrText(Box<DeleteInstrText>),
// For reader
InstrTextString(String),
FootnoteReference(FootnoteReference),
}
impl Serialize for RunChild {
@ -124,6 +125,12 @@ impl Serialize for RunChild {
t.serialize_field("data", i)?;
t.end()
}
RunChild::FootnoteReference(ref f) => {
let mut t = serializer.serialize_struct("FootnoteReference", 2)?;
t.serialize_field("type", "footnoteReference")?;
t.serialize_field("data", f)?;
t.end()
}
}
}
}
@ -283,6 +290,13 @@ impl Run {
self.run_property = p;
self
}
pub fn add_footnote_reference(mut self, footnote: Footnote) -> Run {
self.run_property = RunProperty::new().style("FootnoteReference");
self.children
.push(RunChild::FootnoteReference(footnote.into()));
self
}
}
impl BuildXML for Run {
@ -306,6 +320,7 @@ impl BuildXML for Run {
RunChild::InstrText(c) => b = b.add_child(c),
RunChild::DeleteInstrText(c) => b = b.add_child(c),
RunChild::InstrTextString(_) => unreachable!(),
RunChild::FootnoteReference(c) => b = b.add_child(c),
}
}
b.close().build()
@ -376,4 +391,13 @@ mod tests {
r#"{"runProperty":{"sz":30,"szCs":30,"color":"C9211E","highlight":"yellow","underline":"single","bold":true,"boldCs":true,"italic":true,"italicCs":true,"vanish":true,"characterSpacing":100},"children":[{"type":"tab"},{"type":"text","data":{"preserveSpace":true,"text":"Hello"}},{"type":"break","data":{"breakType":"page"}},{"type":"deleteText","data":{"text":"deleted","preserveSpace":true}}]}"#,
);
}
#[test]
fn test_run_footnote_reference() {
let c = RunChild::FootnoteReference(FootnoteReference::new(1));
assert_eq!(
serde_json::to_string(&c).unwrap(),
r#"{"type":"footnoteReference","data":{"id":1}}"#
);
}
}

View File

@ -0,0 +1,18 @@
#[cfg(not(test))]
use std::sync::atomic::AtomicUsize;
#[cfg(not(test))]
static FOOTNOTE_ID: AtomicUsize = AtomicUsize::new(1);
#[cfg(not(test))]
pub fn generate_footnote_id() -> usize {
use std::sync::atomic::Ordering;
let id = FOOTNOTE_ID.load(Ordering::Relaxed);
FOOTNOTE_ID.store(id.wrapping_add(1), Ordering::Relaxed);
id
}
#[cfg(test)]
pub fn generate_footnote_id() -> usize {
1
}

View File

@ -0,0 +1,50 @@
use super::Footnote;
use crate::documents::BuildXML;
use crate::xml_builder::*;
use serde::Serialize;
#[derive(Debug, Clone, PartialEq, Serialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct Footnotes {
pub(crate) footnotes: Vec<Footnote>,
}
impl Footnotes {
pub fn new() -> Self {
Self::default()
}
pub(crate) fn add(&mut self, footnotes: Vec<Footnote>) {
self.footnotes.extend(footnotes)
}
}
impl BuildXML for Footnotes {
fn build(&self) -> Vec<u8> {
let mut b = XMLBuilder::new().declaration(Some(true)).open_footnotes();
for c in &self.footnotes {
b = b.add_child(c)
}
b.close().build()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(test)]
use pretty_assertions::assert_eq;
use std::str;
#[test]
fn test_footnotes() {
let b = Footnotes::new().build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:footnotes xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:oel="http://schemas.microsoft.com/office/2019/extlst" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16du="http://schemas.microsoft.com/office/word/2023/wordml/word16du" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" 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" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh w16du wp14" />"#
);
}
}

View File

@ -16,6 +16,8 @@ mod font_table;
mod footer;
mod footer_id;
mod footer_rels;
mod footnote_id;
mod footnotes;
mod header;
mod header_id;
mod header_rels;
@ -61,6 +63,7 @@ pub use font_table::*;
pub use footer::*;
pub use footer_id::*;
pub use footer_rels::*;
pub use footnotes::*;
pub use header::*;
pub use header_id::*;
pub use header_rels::*;
@ -137,6 +140,7 @@ pub struct Docx {
pub images: Vec<(String, String, Image, Png)>,
// reader only
pub hyperlinks: Vec<(String, String, String)>,
pub footnotes: Footnotes,
}
impl Default for Docx {
@ -154,6 +158,7 @@ impl Default for Docx {
let media = vec![];
let comments_extended = CommentsExtended::new();
let web_settings = WebSettings::new();
let footnotes = Footnotes::default();
Docx {
content_type,
@ -178,6 +183,7 @@ impl Default for Docx {
themes: vec![],
images: vec![],
hyperlinks: vec![],
footnotes,
}
}
}
@ -592,6 +598,13 @@ impl Docx {
.map(|h| h.build())
.collect();
// Collect footnotes
if self.collect_footnotes() {
// Relationship entry for footnotes
self.content_type = self.content_type.add_footnotes();
self.document_rels.has_footnotes = true;
}
XMLDocx {
content_type: self.content_type.build(),
rels: self.rels.build(),
@ -615,6 +628,7 @@ impl Docx {
custom_items,
custom_item_rels,
custom_item_props,
footnotes: self.footnotes.build(),
}
}
@ -1183,6 +1197,33 @@ impl Docx {
}
(footer_images, image_bufs)
}
/// Collect footnotes from all Runs to the docx footnotes node.
pub fn collect_footnotes(&mut self) -> bool {
let footnotes: Vec<Footnote> = self
.document
.children
.iter()
.filter_map(|child| match child {
DocumentChild::Paragraph(paragraph) => Some(&paragraph.children),
_ => None,
})
.flat_map(|children| children.iter())
.filter_map(|para_child| match para_child {
ParagraphChild::Run(run) => Some(&run.children),
_ => None,
})
.flat_map(|children| children.iter())
.filter_map(|run_child| match run_child {
RunChild::FootnoteReference(footnote_ref) => Some(footnote_ref),
_ => None,
})
.map(Into::<Footnote>::into)
.collect();
let is_footnotes = !footnotes.is_empty();
self.footnotes.add(footnotes);
is_footnotes
}
}
fn collect_dependencies_in_paragraph(

View File

@ -28,6 +28,7 @@ pub struct XMLDocx {
pub custom_items: Vec<Vec<u8>>,
pub custom_item_rels: Vec<Vec<u8>>,
pub custom_item_props: Vec<Vec<u8>>,
pub footnotes: Vec<u8>,
}
impl XMLDocx {

View File

@ -730,6 +730,18 @@ impl XMLBuilder {
self.close()
}
// FootnoteReference
// w:footnoteReference w:id="1"
pub(crate) fn footnote_reference(mut self, id: usize) -> Self {
self.writer
.write(XmlEvent::start_element("w:footnoteReference").attr("w:id", &id.to_string()))
.expect(EXPECT_MESSAGE);
self.close()
}
// Footnotes
open!(open_footnote, "w:footnote", "w:id");
}
#[cfg(test)]
@ -789,4 +801,14 @@ mod tests {
r#"<w:basedOn w:val="Normal" />"#
);
}
#[test]
fn test_footnote_reference() {
let b = XMLBuilder::new();
let r = b.footnote_reference(1).build();
assert_eq!(
str::from_utf8(&r).unwrap(),
r#"<w:footnoteReference w:id="1" />"#
);
}
}

View File

@ -0,0 +1,144 @@
use super::XMLBuilder;
use super::XmlEvent;
impl XMLBuilder {
pub(crate) fn open_footnotes(mut self) -> Self {
self.writer
.write(
XmlEvent::start_element("w:footnotes")
.attr(
"xmlns:wpc",
"http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",
)
.attr(
"xmlns:cx",
"http://schemas.microsoft.com/office/drawing/2014/chartex",
)
.attr(
"xmlns:cx1",
"http://schemas.microsoft.com/office/drawing/2015/9/8/chartex",
)
.attr(
"xmlns:cx2",
"http://schemas.microsoft.com/office/drawing/2015/10/21/chartex",
)
.attr(
"xmlns:cx3",
"http://schemas.microsoft.com/office/drawing/2016/5/9/chartex",
)
.attr(
"xmlns:cx4",
"http://schemas.microsoft.com/office/drawing/2016/5/10/chartex",
)
.attr(
"xmlns:cx5",
"http://schemas.microsoft.com/office/drawing/2016/5/11/chartex",
)
.attr(
"xmlns:cx6",
"http://schemas.microsoft.com/office/drawing/2016/5/12/chartex",
)
.attr(
"xmlns:cx7",
"http://schemas.microsoft.com/office/drawing/2016/5/13/chartex",
)
.attr(
"xmlns:cx8",
"http://schemas.microsoft.com/office/drawing/2016/5/14/chartex",
)
.attr(
"xmlns:mc",
"http://schemas.openxmlformats.org/markup-compatibility/2006",
)
.attr(
"xmlns:aink",
"http://schemas.microsoft.com/office/drawing/2016/ink",
)
.attr(
"xmlns:am3d",
"http://schemas.microsoft.com/office/drawing/2017/model3d",
)
.attr("xmlns:o", "urn:schemas-microsoft-com:office:office")
.attr(
"xmlns:oel",
"http://schemas.microsoft.com/office/2019/extlst",
)
.attr(
"xmlns:r",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships",
)
.attr(
"xmlns:m",
"http://schemas.openxmlformats.org/officeDocument/2006/math",
)
.attr("xmlns:v", "urn:schemas-microsoft-com:vml")
.attr(
"xmlns:wp14",
"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing",
)
.attr(
"xmlns:wp",
"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
)
.attr("xmlns:w10", "urn:schemas-microsoft-com:office:word")
.attr(
"xmlns:w",
"http://schemas.openxmlformats.org/wordprocessingml/2006/main",
)
.attr(
"xmlns:w14",
"http://schemas.microsoft.com/office/word/2010/wordml",
)
.attr(
"xmlns:w15",
"http://schemas.microsoft.com/office/word/2012/wordml",
)
.attr(
"xmlns:w16cex",
"http://schemas.microsoft.com/office/word/2018/wordml/cex",
)
.attr(
"xmlns:w16cid",
"http://schemas.microsoft.com/office/word/2016/wordml/cid",
)
.attr(
"xmlns:w16",
"http://schemas.microsoft.com/office/word/2018/wordml",
)
.attr(
"xmlns:w16du",
"http://schemas.microsoft.com/office/word/2023/wordml/word16du",
)
.attr(
"xmlns:w16sdtdh",
"http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash",
)
.attr(
"xmlns:w16se",
"http://schemas.microsoft.com/office/word/2015/wordml/symex",
)
.attr(
"xmlns:wpg",
"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup",
)
.attr(
"xmlns:wpi",
"http://schemas.microsoft.com/office/word/2010/wordprocessingInk",
)
.attr(
"xmlns:wne",
"http://schemas.microsoft.com/office/word/2006/wordml",
)
.attr(
"xmlns:wps",
"http://schemas.microsoft.com/office/word/2010/wordprocessingShape",
)
.attr(
"mc:Ignorable",
"w14 w15 w16se w16cid w16 w16cex w16sdtdh w16du wp14",
),
)
.expect("should write to buf");
self
}
}

View File

@ -11,6 +11,7 @@ mod drawing;
mod elements;
mod fonts;
mod footer;
mod footnotes;
mod header;
mod numbering;
mod pic;

View File

@ -45,6 +45,8 @@ where
zip.write_all(&xml.numberings)?;
zip.start_file("word/commentsExtended.xml", options)?;
zip.write_all(&xml.comments_extended)?;
zip.start_file("word/footnotes.xml", options)?;
zip.write_all(&xml.footnotes)?;
for (i, h) in xml.headers.iter().enumerate() {
zip.start_file(format!("word/header{}.xml", i + 1), options)?;

View File

@ -274,3 +274,18 @@ pub fn read_line_spacing() {
file.write_all(json.as_bytes()).unwrap();
file.flush().unwrap();
}
#[test]
pub fn read_footnotes() {
let mut file = File::open("../fixtures/footnotes/footnotes.docx").unwrap();
let mut buf = vec![];
file.read_to_end(&mut buf).unwrap();
let json = read_docx(&buf).unwrap().json();
assert_json_snapshot!("read_footnotes", &json);
let path = std::path::Path::new("./tests/output/footnotes.json");
let mut file = std::fs::File::create(path).unwrap();
file.write_all(json.as_bytes()).unwrap();
file.flush().unwrap();
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -542,12 +542,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 0,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -1413,12 +1417,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 1,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -1670,12 +1678,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 0,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -2143,12 +2155,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 0,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -4496,12 +4512,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 0,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -5645,12 +5665,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 3,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -9622,12 +9646,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": true,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 1,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -9992,12 +10020,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 0,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -11322,12 +11354,16 @@ Object {
"customXmlCount": 0,
"footerCount": 3,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 3,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -14356,12 +14392,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 0,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -15248,12 +15288,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 0,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [
Array [
"rId4",
@ -16887,12 +16931,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 0,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [
Array [
"rId5",
@ -18440,12 +18488,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 0,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [
Array [
@ -19637,12 +19689,16 @@ Object {
"customXmlCount": 0,
"footerCount": 1,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 1,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -27072,12 +27128,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 1,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -27489,12 +27549,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 0,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -30042,12 +30106,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": true,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 1,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -32224,12 +32292,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 0,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -33358,12 +33430,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 0,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -36455,12 +36531,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 2,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -40556,12 +40636,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 0,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -44872,12 +44956,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 1,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -116802,12 +116890,16 @@ Object {
"customXmlCount": 0,
"footerCount": 2,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 2,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -124203,12 +124295,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 0,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -127575,12 +127671,16 @@ Object {
"customXmlCount": 0,
"footerCount": 1,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 1,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -145146,12 +145246,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 0,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -146173,12 +146277,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 0,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -147553,12 +147661,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 0,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -150782,12 +150894,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 0,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -154694,12 +154810,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 0,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -155721,12 +155841,16 @@ Object {
"customXmlCount": 0,
"footerCount": 0,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 0,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],
@ -156783,12 +156907,16 @@ Object {
"customXmlCount": 0,
"footerCount": 1,
"hasComments": false,
"hasFootnotes": false,
"hasNumberings": false,
"headerCount": 2,
"hyperlinks": Array [],
"images": Array [],
},
"fontTable": Object {},
"footnotes": Object {
"footnotes": Array [],
},
"hyperlinks": Array [],
"images": Array [],
"media": Array [],

Binary file not shown.