pyodsstream 0.0.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,6 @@
1
+ from .calc_reader_interface import CalcReaderInterface
2
+ from .calc_writer_interface import CalcWriterInterface
3
+ from .readers.ods_doc_reader import OdsDocReader
4
+ from .readers.tsv_reader import TsvReader
5
+ from .writers.ods_doc_writer import OdsDocWriter
6
+ from .writers.tsv_directory_writer import TsvDirectoryWriter
@@ -0,0 +1,31 @@
1
+ # This file is part of pyodsstream.
2
+ #
3
+ # pyodsstream is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # pyodsstream is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with pyodsstream. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ from __future__ import annotations
17
+
18
+ from abc import ABC, abstractmethod
19
+ from typing import Any
20
+
21
+
22
+ class CalcReaderInterface(ABC):
23
+ @abstractmethod
24
+ def yield_sheet_lines(self) -> Any:
25
+ """yield each line from the table"""
26
+ pass
27
+
28
+ @abstractmethod
29
+ def line_position(self) -> int:
30
+ """get the current line position while reading"""
31
+ pass
@@ -0,0 +1,106 @@
1
+ # This file is part of pyodsstream.
2
+ #
3
+ # pyodsstream is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # pyodsstream is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with pyodsstream. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ from __future__ import annotations
17
+
18
+ import datetime
19
+ from abc import ABC, abstractmethod
20
+
21
+ from matplotlib.typing import ColorType
22
+
23
+
24
+ class CalcWriterInterface(ABC):
25
+ @abstractmethod
26
+ def close(self):
27
+ """close the stream/document/file"""
28
+ pass
29
+
30
+ @abstractmethod
31
+ def write_sheet(self, sheet_name: str):
32
+ """open a new sheet
33
+ sheetName the sheet name"""
34
+ pass
35
+
36
+ @abstractmethod
37
+ def write_line(self):
38
+ """open a new line"""
39
+ pass
40
+
41
+ @abstractmethod
42
+ def write_cell(
43
+ self, value: str | int | float | bool | datetime.datetime | datetime.date | None
44
+ ):
45
+ """write a cell"""
46
+ pass
47
+
48
+ @abstractmethod
49
+ def write_cell_percentage(self, value: float):
50
+ """write a double as a percentage
51
+ # *param number double to write must be a ratio (0.5 == 50%)"""
52
+ pass
53
+
54
+ @abstractmethod
55
+ def write_cell_url(self, the_url: str, caption: str):
56
+ """write a text cell with an URL link
57
+ # * param url_link URL link
58
+ # * param text text to write"""
59
+ pass
60
+
61
+ @abstractmethod
62
+ def write_cell_annotation(self, annotation: str):
63
+ """set annotation to write in the next cell
64
+ annotation any comment on this cell"""
65
+ pass
66
+
67
+ def reference_ods_table_cell_style(
68
+ self, foreground_color: ColorType, background_color: ColorType
69
+ ) -> str:
70
+ """build table cell style reference with a style definition
71
+ return OdsTableCellStyleRef str on a style reference"""
72
+ return ""
73
+
74
+ def set_ods_table_cell_style_reference(self, cell_ref: str):
75
+ """set the cell table style. This is applied to in the stream to following
76
+ # * cells. This ends by using an other style reference or by using
77
+ # * setTableCellStyleRef function"""
78
+ pass
79
+
80
+
81
+ # /**
82
+ # * clear cell style definition in the stream. the default style will be
83
+ # * applied.
84
+ # *
85
+ # */
86
+ # void clearTableCellStyleRef();
87
+
88
+
89
+ # /** \brief apply solor scale conditional format on a cell range
90
+ # *
91
+ # */
92
+ # virtual void
93
+ # addColorScale([[maybe_unused]] const OdsColorScale &ods_color_scale);
94
+
95
+ # /** @brief get the last written cell coordinate in ODS coordinate format
96
+ # * get the coordinate of the last written cell or an empty string if the
97
+ # * writer is not an OdsDocWriter
98
+ # *
99
+ # * @return QString with ODS cell coordinate of the form : "classeur.A5"
100
+ # */
101
+ # virtual QString getOdsCellCoordinate();
102
+
103
+ # /** @brief set ODS table settings of the current sheet (table)
104
+ # */
105
+ # virtual void
106
+ # setCurrentOdsTableSettings([[maybe_unused]] const OdsTableSettings &settings);
File without changes
@@ -0,0 +1,440 @@
1
+ # This file is part of pyodsstream.
2
+ #
3
+ # pyodsstream is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # pyodsstream is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with pyodsstream. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+
17
+ import datetime
18
+ import zipfile
19
+ from xml.etree.ElementTree import Element, SubElement, tostring
20
+
21
+ import importlib_resources as resources
22
+ from matplotlib.typing import ColorType
23
+
24
+ from .meta_xml import date_specific_iso
25
+ from .options.ods_table_cell_style import OdsTableCellStyle
26
+
27
+
28
+ def str_xml_encode(str_value: str):
29
+ text_p = Element("pure_xml_quote", name=str_value)
30
+ new_str = tostring(text_p, encoding="utf-8").decode("utf-8")
31
+ return new_str[22:][:-4]
32
+
33
+
34
+ class ContentXml:
35
+ def __init__(self, zf: zipfile.ZipFile):
36
+ self._zfile = zf.open(name="content.xml", mode="w", force_zip64=False)
37
+ ref = resources.files("pyodsstream") / "odsmembers/data/content_part1.xml"
38
+ # Reading the resource
39
+ with ref.open("r") as file:
40
+ self._zfile.write(file.read().encode())
41
+ self._spreadsheet_started = False
42
+ self._table_started = False
43
+ self._table_row_started = False
44
+ self._current_sheet_name = None
45
+ self._row_pos = 0
46
+ self._col_pos = 0
47
+ self._current_style_ref = None
48
+ self._automatic_styles_writed = False
49
+ self._ods_table_cell_style_list = []
50
+
51
+ def _write_automatic_styles(self):
52
+
53
+ if self._automatic_styles_writed:
54
+ return
55
+ self._automatic_styles_writed = True
56
+
57
+ automatic_styles = Element("office:automatic-styles")
58
+ style = SubElement(automatic_styles, "style:style")
59
+ style.attrib["style:name"] = "ce1"
60
+ style.attrib["style:family"] = "table-cell"
61
+ style.attrib["style:parent-style-name"] = "Default"
62
+ style.attrib["style:data-style-name"] = "N0"
63
+
64
+ style2 = SubElement(automatic_styles, "style:style")
65
+ style2.attrib["style:name"] = "ce2"
66
+ style2.attrib["style:family"] = "table-cell"
67
+ style2.attrib["style:parent-style-name"] = "Default"
68
+ style2.attrib["style:data-style-name"] = "N36"
69
+
70
+ co1 = SubElement(automatic_styles, "style:style")
71
+ co1.attrib["style:name"] = "co1"
72
+ co1.attrib["style:family"] = "table-column"
73
+ subco1 = SubElement(co1, "style:table-column-properties")
74
+ subco1.attrib["fo:break-before"] = "auto"
75
+ subco1.attrib["style:column-width"] = "2.27541666666667cm"
76
+
77
+ co2 = SubElement(automatic_styles, "style:style")
78
+ co2.attrib["style:name"] = "co2"
79
+ co2.attrib["style:family"] = "table-column"
80
+ subco1 = SubElement(co2, "style:table-column-properties")
81
+ subco1.attrib["fo:break-before"] = "auto"
82
+ subco1.attrib["style:column-width"] = "2.27541666666667cm"
83
+
84
+ ro1 = SubElement(automatic_styles, "style:style")
85
+ ro1.attrib["style:name"] = "ro1"
86
+ ro1.attrib["style:family"] = "table-row"
87
+ subro1 = SubElement(ro1, "style:table-row-properties")
88
+ subro1.attrib["style:row-height"] = "15pt"
89
+ subro1.attrib["style:use-optimal-row-height"] = "true"
90
+ subro1.attrib["fo:break-before"] = "auto"
91
+
92
+ ta1 = SubElement(automatic_styles, "style:style")
93
+ ta1.attrib["style:name"] = "ta1"
94
+ ta1.attrib["style:family"] = "table"
95
+ ta1.attrib["style:master-page-name"] = "mp1"
96
+ subta1 = SubElement(ta1, "style:table-properties")
97
+ subta1.attrib["table:display"] = "true"
98
+ subta1.attrib["style:writing-mode"] = "lr-tb"
99
+
100
+ for ods_table_cell_style in self._ods_table_cell_style_list:
101
+ ref_style = SubElement(automatic_styles, "style:style")
102
+ ref_style.attrib["style:name"] = ods_table_cell_style.xml_ref
103
+ ref_style.attrib["style:family"] = "table-cell"
104
+ ref_style.attrib["style:parent-style-name"] = "Default"
105
+ ref_style.attrib["style:data-style-name"] = "N0"
106
+ sub_ref_style_bkg = SubElement(ref_style, "style:table-cell-properties")
107
+ sub_ref_style_bkg.attrib["fo:background-color"] = (
108
+ ods_table_cell_style.background_color
109
+ )
110
+ sub_ref_style = SubElement(ref_style, "style:text-properties")
111
+ sub_ref_style.attrib["fo:color"] = ods_table_cell_style.color
112
+
113
+ str_text = tostring(automatic_styles, encoding="utf-8").decode("utf-8")
114
+
115
+ # print(str_text)
116
+ self._zfile.write(str_text.encode())
117
+ # <office:automatic-styles>
118
+ # <style:style
119
+ # style:name="odsce1"
120
+ # style:family="table-cell"
121
+ # style:parent-style-name="Default"
122
+ # style:data-style-name="N0"
123
+ # >
124
+ # <style:table-cell-properties fo:background-color="#ffff00" />
125
+ # <style:text-properties fo:color="#ff0000" />
126
+ # </style:style>
127
+ # </office:automatic-styles>
128
+ pass
129
+
130
+ def reference_ods_table_cell_style(
131
+ self, foreground_color: ColorType, background_color: ColorType
132
+ ) -> str:
133
+ ods_style = OdsTableCellStyle()
134
+ self._ods_table_cell_style_list.append(ods_style)
135
+ ods_style._xml_ref = "".join(
136
+ ["odsce", str(len(self._ods_table_cell_style_list))]
137
+ )
138
+ ods_style._background_color = background_color
139
+ ods_style._text_color = foreground_color
140
+ return ods_style.xml_ref
141
+
142
+ def style_ref(self) -> str:
143
+ style_ref = "ce1"
144
+ if self._current_style_ref is not None:
145
+ style_ref = self._current_style_ref
146
+ self._current_style_ref = None
147
+ return style_ref
148
+
149
+ def set_ods_table_cell_style_reference(self, cell_ref: str):
150
+ """set the cell table style. This is applied to in the stream to following
151
+ # * cells. This ends by using an other style reference or by using
152
+ # * setTableCellStyleRef function"""
153
+ self._current_style_ref = cell_ref
154
+
155
+ def write_sheet(self, table_name: str):
156
+ self._start_spreadsheet()
157
+ self._write_end_table()
158
+ self._current_sheet_name = table_name
159
+ self._table_started = True
160
+ table_str = '<table:table table:name="{table_name}" table:style-name="ta1" table:print="false">'.format(
161
+ table_name=str_xml_encode(table_name)
162
+ )
163
+ self._zfile.write(table_str.encode())
164
+ table_str = '<table:table-column table:style-name="co1" table:default-cell-style-name="ce1" />'
165
+ self._zfile.write(table_str.encode())
166
+ self._row_pos = 0
167
+ self._col_pos = 0
168
+
169
+ def close(self):
170
+
171
+ # self._write_automatic_styles()
172
+ self._start_spreadsheet()
173
+ self._write_end_table()
174
+ self._zfile.write(
175
+ b"</office:spreadsheet></office:body></office:document-content>"
176
+ )
177
+ self._zfile.close()
178
+
179
+ def _start_spreadsheet(self):
180
+ self._write_automatic_styles()
181
+ if self._spreadsheet_started:
182
+ return
183
+ self._spreadsheet_started = True
184
+ self._zfile.write(b"<office:body><office:spreadsheet>")
185
+
186
+ def _write_end_table(self):
187
+ if self._table_row_started:
188
+ self._zfile.write(b"</table:table-row>")
189
+ if self._table_started:
190
+ self._zfile.write(b"</table:table>")
191
+ # void
192
+ # ContentXml::writeEndTable()
193
+ # {
194
+ # if(_tableRowStarted)
195
+ # {
196
+ # _p_writer->writeEndElement();
197
+ # }
198
+
199
+ # if(_tableStarted)
200
+ # {
201
+ # std::vector<OdsColorScale> sheet_color_scale_list =
202
+ # getOdsColorScaleListBySheetName(_current_sheet_name);
203
+ # if(sheet_color_scale_list.size() > 0)
204
+ # {
205
+ # /*
206
+ # <calcext:conditional-formats>
207
+ # <calcext:conditional-format
208
+ # calcext:target-range-address="classeur.A5:classeur.E6" >
209
+ # <calcext:color-scale>
210
+ # <calcext:color-scale-entry calcext:value="0"
211
+ # calcext:type="minimum" calcext:color="#0000ff"/>
212
+ # <calcext:color-scale-entry calcext:value="50"
213
+ # calcext:type="percentile" calcext:color="#ffffff"/>
214
+ # <calcext:color-scale-entry calcext:value="0"
215
+ # calcext:type="maximum" calcext:color="#ff0000"/>
216
+ # </calcext:color-scale>
217
+ # </calcext:conditional-format>
218
+ # </calcext:conditional-formats>
219
+ # </table:table>*/
220
+ # //<calcext:conditional-formats>
221
+ # _p_writer->writeStartElement(MetaXml::getNamespaceURI("calcext"),
222
+ # "conditional-formats");
223
+
224
+ # for(OdsColorScale color_scale : sheet_color_scale_list)
225
+ # {
226
+ # color_scale.writeConditionalFormat(_p_writer);
227
+ # }
228
+
229
+ # //</calcext:conditional-formats>
230
+ # _p_writer->writeEndElement();
231
+ # }
232
+
233
+ # _p_writer->writeEndElement();
234
+ # }
235
+ self._table_started = False
236
+ self._table_row_started = False
237
+ self._row_pos = 0
238
+ self._col_pos = 0
239
+
240
+ def write_line(self):
241
+
242
+ # self._write_automatic_styles()
243
+ self._start_spreadsheet()
244
+ if not self._table_started:
245
+ self.write_sheet("table")
246
+ if self._table_row_started:
247
+ # close current row
248
+ self._zfile.write(b"</table:table-row>")
249
+ self._row_pos = self._row_pos + 1
250
+ self._col_pos = 0
251
+ self._table_row_started = True
252
+ # /*
253
+ # * <table:table-row table:style-name="ro1">
254
+ # */
255
+ self._zfile.write(b'<table:table-row table:style-name="ro1">')
256
+
257
+ def _write_annotation(self, annotation: str | None):
258
+ if annotation is not None:
259
+ text_p = Element("office:annotation")
260
+ # <text:a xlink:href="{the_url}" xlink:type="simple">{the_caption}</text:a>
261
+ text_a = SubElement(text_p, "text:p")
262
+ text_a.text = annotation
263
+ str_text = tostring(text_p, encoding="utf-8").decode("utf-8")
264
+
265
+ self._zfile.write(str_text.encode())
266
+
267
+ # <office:annotation>
268
+ # <text:p>ceci est un commentaire n1</text:p>
269
+ # </office:annotation>
270
+ pass
271
+
272
+ def write_cell_percentage(self, value: float, annotation: str | None):
273
+
274
+ # self._write_automatic_styles()
275
+ self._start_spreadsheet()
276
+ if value is None:
277
+ value = ""
278
+ if not self._table_row_started:
279
+ self.write_line()
280
+
281
+ string_representation = f"{value}"
282
+ str_text = '<table:table-cell office:value-type="percentage" office:value="{str_representation}" calcext:value-type="percentage" table:style-name="{style_ref}">'.format(
283
+ str_representation=str_xml_encode(string_representation),
284
+ style_ref=self.style_ref(),
285
+ )
286
+ self._zfile.write(str_text.encode())
287
+
288
+ self._write_annotation(annotation)
289
+ # _p_writer->writeStartElement(MetaXml::getNamespaceURI("text"), "p");
290
+ # _p_writer->writeCharacters(value);
291
+ # <text:p>truc</text:p>
292
+ text_p = Element("text:p")
293
+ text_p.text = string_representation
294
+ str_text = (
295
+ tostring(text_p, encoding="utf-8").decode("utf-8") + "</table:table-cell>"
296
+ )
297
+ self._zfile.write(str_text.encode())
298
+ # _p_writer->writeEndElement();
299
+
300
+ self._col_pos = self._col_pos + 1
301
+
302
+ def write_cell_url(self, the_url: str, caption: str, annotation: str | None):
303
+ # <text:a
304
+ # xlink:href="http://pappso.inra.fr/"
305
+ # xlink:type="simple"
306
+ # >ceci est un lien</text:a>
307
+
308
+ self._start_spreadsheet()
309
+ if not self._table_row_started:
310
+ self.write_line()
311
+
312
+ str_text = '<table:table-cell office:value-type="string" table:style-name="{style_ref}">'.format(
313
+ style_ref=self.style_ref(),
314
+ )
315
+ self._zfile.write(str_text.encode())
316
+ self._write_annotation(annotation)
317
+ # _p_writer->writeStartElement(MetaXml::getNamespaceURI("text"), "p");
318
+ # _p_writer->writeCharacters(value);
319
+ # <text:p>truc</text:p>
320
+
321
+ text_p = Element("text:p")
322
+ # <text:a xlink:href="{the_url}" xlink:type="simple">{the_caption}</text:a>
323
+ text_a = SubElement(text_p, "text:a")
324
+ text_a.attrib["xlink:href"] = the_url
325
+ text_a.attrib["xlink:type"] = "simple"
326
+ text_a.text = caption
327
+ str_text = (
328
+ tostring(text_p, encoding="utf-8").decode("utf-8") + "</table:table-cell>"
329
+ )
330
+
331
+ self._zfile.write(str_text.encode())
332
+
333
+ self._col_pos = self._col_pos + 1
334
+
335
+ def write_cell(
336
+ self,
337
+ value: str | int | float | bool | datetime.datetime | datetime.date | None,
338
+ annotation: str | None,
339
+ ):
340
+ # self._write_automatic_styles()
341
+ self._start_spreadsheet()
342
+ if value is None:
343
+ value = ""
344
+ if not self._table_row_started:
345
+ self.write_line()
346
+ if isinstance(value, str):
347
+ str_text = '<table:table-cell office:value-type="string" table:style-name="{style_ref}">'.format(
348
+ style_ref=self.style_ref(),
349
+ )
350
+
351
+ # print(str_text)
352
+ self._zfile.write(str_text.encode())
353
+ self._write_annotation(annotation)
354
+ # _p_writer->writeStartElement(MetaXml::getNamespaceURI("text"), "p");
355
+ # _p_writer->writeCharacters(value);
356
+ # <text:p>truc</text:p>
357
+
358
+ text_p = Element("text:p")
359
+ text_p.text = value
360
+ str_text = (
361
+ tostring(text_p, encoding="utf-8").decode("utf-8")
362
+ + "</table:table-cell>"
363
+ )
364
+
365
+ self._zfile.write(str_text.encode())
366
+ # _p_writer->writeEndElement();
367
+
368
+ # _p_writer->writeEndElement();
369
+ elif isinstance(value, bool):
370
+ self._write_cell_bool(value, annotation)
371
+ elif isinstance(value, int):
372
+ self._write_cell_number(value, annotation)
373
+ elif isinstance(value, float):
374
+ self._write_cell_number(value, annotation)
375
+ elif isinstance(value, datetime.datetime):
376
+ self._write_cell_date(value, annotation)
377
+ elif isinstance(value, datetime.date):
378
+ self._write_cell_date(value, annotation)
379
+ else:
380
+ pass
381
+
382
+ self._col_pos = self._col_pos + 1
383
+
384
+ def _write_cell_number(self, number: int | float, annotation: str | None):
385
+
386
+ string_representation = f"{number}"
387
+ str_text = '<table:table-cell office:value-type="float" office:value="{str_representation}" table:style-name="{style_ref}">'.format(
388
+ style_ref=self.style_ref(),
389
+ str_representation=str_xml_encode(string_representation),
390
+ )
391
+ self._zfile.write(str_text.encode())
392
+ self._write_annotation(annotation)
393
+ # _p_writer->writeStartElement(MetaXml::getNamespaceURI("text"), "p");
394
+ # _p_writer->writeCharacters(value);
395
+ # <text:p>truc</text:p>
396
+ str_text = "<text:p>{the_value}</text:p></table:table-cell>".format(
397
+ the_value=str_xml_encode(string_representation)
398
+ )
399
+ self._zfile.write(str_text.encode())
400
+
401
+ def _write_cell_bool(self, the_bool: bool, annotation: str | None):
402
+
403
+ # assert the_bool
404
+ string_representation = "false"
405
+ if the_bool:
406
+ string_representation = "true"
407
+
408
+ str_text = '<table:table-cell office:value-type="boolean" office:boolean-value="{str_representation}" table:style-name="{style_ref}">'.format(
409
+ style_ref=self.style_ref(),
410
+ str_representation=string_representation,
411
+ )
412
+ self._zfile.write(str_text.encode())
413
+ self._write_annotation(annotation)
414
+ # _p_writer->writeStartElement(MetaXml::getNamespaceURI("text"), "p");
415
+ # _p_writer->writeCharacters(value);
416
+ # <text:p>truc</text:p>
417
+ str_text = "<text:p>{the_value}</text:p></table:table-cell>".format(
418
+ the_value=string_representation
419
+ )
420
+ self._zfile.write(str_text.encode())
421
+
422
+ def _write_cell_date(
423
+ self, the_date: datetime.datetime | datetime.date, annotation: str | None
424
+ ):
425
+
426
+ str_text = '<table:table-cell office:value-type="date" office:date-value="{str_representation}" table:style-name="{style_ref}">'.format(
427
+ style_ref=self.style_ref(),
428
+ str_representation=date_specific_iso(the_date),
429
+ )
430
+ self._zfile.write(str_text.encode())
431
+ self._write_annotation(annotation)
432
+ # _p_writer->writeStartElement(MetaXml::getNamespaceURI("text"), "p");
433
+ # _p_writer->writeCharacters(value);
434
+ # <text:p>truc</text:p>
435
+ str_text = "<text:p>{the_value}</text:p></table:table-cell>".format(
436
+ the_value="-".join(
437
+ [str(the_date.year), str(the_date.month), str(the_date.day)]
438
+ )
439
+ )
440
+ self._zfile.write(str_text.encode())
File without changes
@@ -0,0 +1,42 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <office:document-content
3
+ xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0"
4
+ xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0"
5
+ xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
6
+ xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0"
7
+ xmlns:db="urn:oasis:names:tc:opendocument:xmlns:database:1.0"
8
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
9
+ xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
10
+ xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
11
+ xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
12
+ xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
13
+ xmlns:grddl="http://www.w3.org/2003/g/data-view#"
14
+ xmlns:math="http://www.w3.org/1998/Math/MathML"
15
+ xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
16
+ xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
17
+ xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2"
18
+ xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
19
+ xmlns:ooo="http://openoffice.org/2004/office"
20
+ xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0"
21
+ xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
22
+ xmlns:smil="urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0"
23
+ xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
24
+ xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
25
+ xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
26
+ xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
27
+ xmlns:xforms="http://www.w3.org/2002/xforms"
28
+ xmlns:xhtml="http://www.w3.org/1999/xhtml"
29
+ xmlns:xlink="http://www.w3.org/1999/xlink"
30
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
31
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
32
+ office:version="1.2"
33
+ >
34
+ <office:scripts />
35
+ <office:font-face-decls>
36
+ <style:font-face
37
+ style:font-family-generic="swiss"
38
+ style:font-pitch="variable"
39
+ style:name="Arial"
40
+ svg:font-family="Arial"
41
+ />
42
+ </office:font-face-decls>