metanorma-ogc 2.7.3 → 2.7.5

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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/lib/isodoc/ogc/base_convert.rb +4 -17
  3. data/lib/isodoc/ogc/html/htmlstyle.css +1 -1
  4. data/lib/isodoc/ogc/html/htmlstyle.scss +1 -1
  5. data/lib/isodoc/ogc/html/ogc.css +1 -1
  6. data/lib/isodoc/ogc/html/ogc.scss +1 -1
  7. data/lib/isodoc/ogc/ogc.abstract-specification-topic.xsl +354 -82
  8. data/lib/isodoc/ogc/ogc.best-practice.xsl +354 -82
  9. data/lib/isodoc/ogc/ogc.change-request-supporting-document.xsl +354 -82
  10. data/lib/isodoc/ogc/ogc.community-practice.xsl +354 -82
  11. data/lib/isodoc/ogc/ogc.community-standard.xsl +354 -82
  12. data/lib/isodoc/ogc/ogc.discussion-paper.xsl +354 -82
  13. data/lib/isodoc/ogc/ogc.draft-standard.xsl +354 -82
  14. data/lib/isodoc/ogc/ogc.engineering-report.xsl +354 -82
  15. data/lib/isodoc/ogc/ogc.other.xsl +354 -82
  16. data/lib/isodoc/ogc/ogc.policy.xsl +354 -82
  17. data/lib/isodoc/ogc/ogc.reference-model.xsl +354 -82
  18. data/lib/isodoc/ogc/ogc.release-notes.xsl +354 -82
  19. data/lib/isodoc/ogc/ogc.standard.xsl +354 -82
  20. data/lib/isodoc/ogc/ogc.test-suite.xsl +354 -82
  21. data/lib/isodoc/ogc/ogc.user-guide.xsl +354 -82
  22. data/lib/isodoc/ogc/ogc.white-paper.xsl +341 -68
  23. data/lib/isodoc/ogc/presentation_sections.rb +18 -14
  24. data/lib/isodoc/ogc/presentation_xml_convert.rb +18 -8
  25. data/lib/isodoc/ogc/sections.rb +0 -11
  26. data/lib/isodoc/ogc/xref.rb +9 -10
  27. data/lib/metanorma/ogc/basicdoc.rng +14 -8
  28. data/lib/metanorma/ogc/biblio-standoc.rng +37 -7
  29. data/lib/metanorma/ogc/biblio.rng +30 -18
  30. data/lib/metanorma/ogc/cleanup.rb +8 -18
  31. data/lib/metanorma/ogc/converter.rb +12 -12
  32. data/lib/metanorma/ogc/isodoc.rng +130 -96
  33. data/lib/metanorma/ogc/ogc.rng +2 -67
  34. data/lib/metanorma/ogc/relaton-ogc.rng +0 -16
  35. data/lib/metanorma/ogc/reqt.rng +7 -6
  36. data/lib/metanorma/ogc/validate.rb +18 -21
  37. data/lib/metanorma/ogc/version.rb +1 -1
  38. metadata +2 -2
@@ -4,15 +4,24 @@ module IsoDoc
4
4
  def middle_title(docxml); end
5
5
 
6
6
  def preface_rearrange(doc)
7
- super
7
+ [
8
+ ["//preface/abstract",
9
+ %w(executivesummary foreword introduction clause acknowledgements)],
10
+ ["//preface/executivesummary",
11
+ %w(foreword introduction clause acknowledgements)],
12
+ ["//preface/foreword",
13
+ %w(introduction clause acknowledgements)],
14
+ ["//preface/introduction",
15
+ %w(clause acknowledgements)],
16
+ ["//preface/acknowledgements", %w()],
17
+ ].each do |x|
18
+ preface_move(doc.xpath(ns(x[0])), x[1], doc)
19
+ end
8
20
  insert_preface_sections(doc)
9
21
  end
10
22
 
11
23
  def insert_preface_sections(doc)
12
- preface_insert(doc.at(ns("//preface/clause" \
13
- "[@type = 'executivesummary']")),
14
- doc.at(ns("//preface/abstract")), doc)
15
- preface_insert(doc.at(ns("//preface//submitters")),
24
+ preface_insert(doc.at(ns("//preface//clause[@type = 'submitters' or @type = 'contributors']")),
16
25
  submit_orgs_append_pt(doc), doc)
17
26
  insert_submitting_orgs(doc)
18
27
  preface_insert(doc.at(ns("//preface/clause[@type = 'security']")),
@@ -39,8 +48,8 @@ module IsoDoc
39
48
  def submit_orgs_append_pt(docxml)
40
49
  docxml.at(ns("//foreword")) ||
41
50
  docxml.at(ns("//preface/clause[@type = 'keywords']")) ||
42
- docxml.at(ns("//preface/clause[@type = 'executivesummary']")) ||
43
- docxml.at(ns("//preface/abstract"))
51
+ docxml.at(ns("//preface/abstract")) ||
52
+ docxml.at(ns("//preface/executivesummary"))
44
53
  end
45
54
 
46
55
  def insert_submitting_orgs(docxml)
@@ -78,7 +87,7 @@ module IsoDoc
78
87
  kw = @meta.get[:keywords]
79
88
  kw.empty? and return
80
89
  if abstract =
81
- docxml.at(ns("//preface/clause[@type = 'executivesummary']")) ||
90
+ docxml.at(ns("//preface/executivesummary")) ||
82
91
  docxml.at(ns("//preface/abstract"))
83
92
  abstract.next = keyword_clause(kw)
84
93
  else
@@ -88,12 +97,7 @@ module IsoDoc
88
97
  end
89
98
 
90
99
  def annex_delim(_elem)
91
- "<br/>"
92
- end
93
-
94
- def clause(docxml)
95
- super
96
- docxml.xpath(ns("//submitters")).each { |f| clause1(f) }
100
+ "<br/>"
97
101
  end
98
102
 
99
103
  def clause1(elem)
@@ -51,9 +51,7 @@ module IsoDoc
51
51
  <title>#{@i18n.dochistory}</title>
52
52
  <table><thead>
53
53
  <tr><th>Date</th><th>Release</th><th>Author</th><th>Paragraph Modified</th><th>Description</th></tr>
54
- </thead><tbody>
55
- #{ret}
56
- </tbody></table></annex>
54
+ </thead><tbody>#{ret}</tbody></table></annex>
57
55
  XML
58
56
  end
59
57
 
@@ -175,15 +173,13 @@ module IsoDoc
175
173
  end
176
174
  end
177
175
 
178
- #def designation_boldface(desgn); end
176
+ # def designation_boldface(desgn); end
179
177
 
180
178
  def source_label(elem)
181
179
  labelled_ancestor(elem) and return
182
- #lbl = "<span class='fmt-element-name'>#{lower2cap @i18n.sourcecode}</span>"
183
180
  n = @xrefs.get[elem["id"]]
184
- #(n.nil? || n[:label].nil? || n[:label].empty?) or
185
- #lbl = l10n("#{lbl} #{autonum(elem['id'], n[:label])}")
186
- lbl = labelled_autonum(lower2cap(@i18n.sourcecode), elem["id"], n&.dig(:label))
181
+ lbl = labelled_autonum(lower2cap(@i18n.sourcecode), elem["id"],
182
+ n&.dig(:label))
187
183
  prefix_name(elem, { caption: block_delim }, lbl, "name")
188
184
  end
189
185
 
@@ -218,6 +214,20 @@ module IsoDoc
218
214
  true
219
215
  end
220
216
 
217
+ def ul_label_list(_elem)
218
+ if @doctype == "white-paper" then %w(&#x2014;)
219
+ else %w(&#x2022;)
220
+ end
221
+ end
222
+
223
+ def ol_label_template(_elem)
224
+ super
225
+ .merge({
226
+ alphabet_upper: %{%<span class="fmt-label-delim">)</span>},
227
+ arabic: %{%<span class="fmt-label-delim">.</span>},
228
+ })
229
+ end
230
+
221
231
  include Init
222
232
  end
223
233
  end
@@ -1,13 +1,6 @@
1
1
  module IsoDoc
2
2
  module Ogc
3
3
  module BaseConvert
4
- def top_element_render(node, out)
5
- case node.name
6
- when "submitters" then intro_clause node, out
7
- else super
8
- end
9
- end
10
-
11
4
  def preface(clause, out)
12
5
  case clause["type"]
13
6
  when "toc"
@@ -17,10 +10,6 @@ module IsoDoc
17
10
  end
18
11
  end
19
12
 
20
- def sections_names
21
- super + %w[submitters]
22
- end
23
-
24
13
  def intro_clause(elem, out)
25
14
  out.div class: "Section3", id: elem["id"] do |div|
26
15
  clause_name(elem, elem&.at(ns("./fmt-title")), div,
@@ -42,7 +42,7 @@ module IsoDoc
42
42
  def middle_section_asset_names(doc)
43
43
  middle_sections =
44
44
  "//clause[@type = 'scope' or @type = 'conformance'] | //foreword | " \
45
- "//introduction | //preface/abstract | //submitters | " \
45
+ "//introduction | //preface/abstract | " \
46
46
  "//acknowledgements | //preface/clause | " \
47
47
  "#{@klass.norm_ref_xpath} | //sections/terms | " \
48
48
  "//sections/definitions | //clause[parent::sections]"
@@ -69,7 +69,7 @@ module IsoDoc
69
69
  def preface_names_numbered1(clause, parentnum, num, level)
70
70
  lbl = clause_number_semx(parentnum, clause, num)
71
71
  @anchors[clause["id"]] =
72
- { label: lbl, level: level,
72
+ { label: lbl, level: level,
73
73
  xref: labelled_autonum(@labels["clause"], lbl),
74
74
  type: "clause", elem: @labels["clause"] }
75
75
  clause.xpath(ns(SUBCLAUSES)).each_with_index do |c, i|
@@ -110,7 +110,7 @@ module IsoDoc
110
110
  @anchors[t["id"]] = anchor_struct(
111
111
  c.print, t,
112
112
  @labels["sourcecode"], "sourcecode",
113
- { unnumb: t["unnumbered"], container: container}
113
+ { unnumb: t["unnumbered"], container: container }
114
114
  )
115
115
  end
116
116
  end
@@ -123,13 +123,12 @@ module IsoDoc
123
123
  def hierarchical_sourcecode_names(clauses, num)
124
124
  c = Counter.new
125
125
  nodeSet(clauses).each do |clause|
126
- clause.xpath(ns(LISTING)).noblank.each do |t|
127
- @anchors[t["id"]] =
128
- anchor_struct(#"#{num}#{hier_separator}#{c.increment(t).print}",
129
- hiersemx(clause, num, c.increment(t), t),
130
- t, @labels["sourcecode"],
131
- "sourcecode", { unnumb:t["unnumbered"] })
132
- end
126
+ clause.xpath(ns(LISTING)).noblank.each do |t|
127
+ @anchors[t["id"]] =
128
+ anchor_struct(hiersemx(clause, num, c.increment(t), t),
129
+ t, @labels["sourcecode"],
130
+ "sourcecode", { unnumb: t["unnumbered"] })
131
+ end
133
132
  end
134
133
  end
135
134
  end
@@ -1701,16 +1701,22 @@ which can be bookmarks as well as block or section references</a:documentation>
1701
1701
  <a:documentation>Inline reference to a paragraph or paragraphs, appearing as a footnote.
1702
1702
  The target of a footnote is the location it is embedded in within the text</a:documentation>
1703
1703
  <element name="fn">
1704
- <attribute name="reference">
1705
- <a:documentation>The number of the footnote, used to identify it visually</a:documentation>
1706
- </attribute>
1707
- <oneOrMore>
1708
- <ref name="paragraph">
1709
- <a:documentation>The content of the footnote</a:documentation>
1710
- </ref>
1711
- </oneOrMore>
1704
+ <ref name="FnAttributes"/>
1705
+ <ref name="FnBody"/>
1712
1706
  </element>
1713
1707
  </define>
1708
+ <define name="FnBody">
1709
+ <oneOrMore>
1710
+ <ref name="paragraph">
1711
+ <a:documentation>The content of the footnote</a:documentation>
1712
+ </ref>
1713
+ </oneOrMore>
1714
+ </define>
1715
+ <define name="FnAttributes">
1716
+ <attribute name="reference">
1717
+ <a:documentation>The number of the footnote, used to identify it visually</a:documentation>
1718
+ </attribute>
1719
+ </define>
1714
1720
  <define name="callout">
1715
1721
  <a:documentation>Inline reference to a paragraph or paragraphs, appearing as annotation of source code</a:documentation>
1716
1722
  <element name="callout">
@@ -1,13 +1,14 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <grammar xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" xmlns="http://relaxng.org/ns/structure/1.0">
3
- <!--
4
- Add-ons to biblio.rnc for standoc model: defines the extension point BibDataExtensionType
5
- of relaton
6
-
7
- Specialisations as for biblio.rnc. Extension point can be redefined completely for a flavour of standoc
8
- (SDO); but other elements in Bibdata can only be extended (more specialised vocabularies for Bibdata)
9
- -->
10
3
  <include href="biblio.rng">
4
+ <!-- ALERT: we cannot have comments on root element, as they intervene with https://github.com/metanorma/metanorma/issues/437 fix -->
5
+ <!--
6
+ Add-ons to biblio.rnc for standoc model: defines the extension point BibDataExtensionType
7
+ of relaton
8
+
9
+ Specialisations as for biblio.rnc. Extension point can be redefined completely for a flavour of standoc
10
+ (SDO); but other elements in Bibdata can only be extended (more specialised vocabularies for Bibdata)
11
+ -->
11
12
  <define name="BibData">
12
13
  <a:documentation>The bibliographic description of a standardisation document</a:documentation>
13
14
  <ref name="StandardBibliographicItem"/>
@@ -91,6 +92,9 @@ a standards definition organization</a:documentation>
91
92
  <a:documentation>Representation of the identifier for the standardisation document, giving its individual semantic components</a:documentation>
92
93
  </ref>
93
94
  </zeroOrMore>
95
+ <ref name="DocumentImages">
96
+ <a:documentation>Coverpage and other images to be rendered with document</a:documentation>
97
+ </ref>
94
98
  </define>
95
99
  <define name="doctype">
96
100
  <a:documentation>Classification of the standardisation document</a:documentation>
@@ -268,6 +272,32 @@ and not those document components</a:documentation>
268
272
  </optional>
269
273
  </element>
270
274
  </define>
275
+ <define name="DocumentImages">
276
+ <zeroOrMore>
277
+ <element name="coverpage-image">
278
+ <a:documentation>Images to be displayed on the coverpage of the document</a:documentation>
279
+ <ref name="image-no-id"/>
280
+ </element>
281
+ </zeroOrMore>
282
+ <zeroOrMore>
283
+ <element name="innercoverpage-image">
284
+ <a:documentation>Images to be displayed on the inner coverpage of the document</a:documentation>
285
+ <ref name="image-no-id"/>
286
+ </element>
287
+ </zeroOrMore>
288
+ <zeroOrMore>
289
+ <element name="tocside-image">
290
+ <a:documentation>Images to be displayed on the Table of Contents page of the document</a:documentation>
291
+ <ref name="image-no-id"/>
292
+ </element>
293
+ </zeroOrMore>
294
+ <zeroOrMore>
295
+ <element name="backpage-image">
296
+ <a:documentation>Images to be displayed on the backpage of the document</a:documentation>
297
+ <ref name="image-no-id"/>
298
+ </element>
299
+ </zeroOrMore>
300
+ </define>
271
301
  <define name="StandardBibliographicItem">
272
302
  <ref name="BibliographicItem"/>
273
303
  <zeroOrMore>
@@ -1,23 +1,25 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <!--
3
- instantiations of this grammar may replace leaf strings
4
- with more elaborated types; e.g. title (text) replaced with
5
- title-main, title-intro, title-part; type replaced with
6
- enum.
7
-
8
- some renaming at leaf nodes is permissible
9
-
10
- obligations can change both from optional to mandatory,
11
- and from mandatory to optional; optional elements may
12
- be omitted; freely positioned alternatives may be replaced
13
- with strict ordering
14
-
15
- DO NOT introduce a namespace here. We do not want a distinct namespace
16
- for these elements, and a distinct namespace for any grammar inheriting
17
- these elements; we just want one namespace for any child grammars
18
- of this.
19
- -->
20
2
  <grammar xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
3
+ <!--
4
+ ALERT: we cannot have comments on root element, as they intervene with https://github.com/metanorma/metanorma/issues/437 fix
5
+
6
+ Instantiations of this grammar may replace leaf strings
7
+ with more elaborated types; e.g. title (text) replaced with
8
+ title-main, title-intro, title-part; type replaced with
9
+ enum.
10
+
11
+ Some renaming at leaf nodes is permissible
12
+
13
+ Obligations can change both from optional to mandatory,
14
+ and from mandatory to optional; optional elements may
15
+ be omitted; freely positioned alternatives may be replaced
16
+ with strict ordering
17
+
18
+ DO NOT introduce a namespace here. We do not want a distinct namespace
19
+ for these elements, and a distinct namespace for any grammar inheriting
20
+ these elements; we just want one namespace for any child grammars
21
+ of this.
22
+ -->
21
23
  <!--
22
24
  https://www.myintervals.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/
23
25
  iso8601date = xsd:string { pattern = "([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?" }
@@ -1241,6 +1243,11 @@ Refer to `BibliographicItem` for definitions</a:documentation>
1241
1243
  </define>
1242
1244
  <define name="formattedref">
1243
1245
  <element name="formattedref">
1246
+ <optional>
1247
+ <attribute name="format">
1248
+ <a:documentation>format of formatted reference; Metanorma assumes references are formatted as Metanorma XML</a:documentation>
1249
+ </attribute>
1250
+ </optional>
1244
1251
  <oneOrMore>
1245
1252
  <ref name="TextElement"/>
1246
1253
  </oneOrMore>
@@ -1812,6 +1819,11 @@ May be used to differentiate rendering of notes in bibliographies</a:documentati
1812
1819
  <a:documentation>Abstract of bibliographic item</a:documentation>
1813
1820
  <element name="abstract">
1814
1821
  <ref name="LocalizedStringAttributes"/>
1822
+ <optional>
1823
+ <attribute name="format">
1824
+ <a:documentation>What format the formatted abstract is in. In Metanorma, assumed to be Metanorma XML</a:documentation>
1825
+ </attribute>
1826
+ </optional>
1815
1827
  <choice>
1816
1828
  <oneOrMore>
1817
1829
  <ref name="BasicBlockNoId">
@@ -14,7 +14,6 @@ module Metanorma
14
14
 
15
15
  def make_preface(xml, sect)
16
16
  super
17
- insert_execsummary(xml, sect)
18
17
  insert_security(xml, sect)
19
18
  insert_submitters(xml, sect)
20
19
  end
@@ -23,17 +22,9 @@ module Metanorma
23
22
  %(id="_#{UUIDTools::UUID.random_create}")
24
23
  end
25
24
 
26
- def insert_execsummary(xml, sect)
27
- summ = xml&.at("//clause[@type = 'executivesummary']")&.remove or
28
- return
29
- preface = sect.at("//preface") ||
30
- sect.add_previous_sibling("<preface/>").first
31
- preface.add_child summ
32
- end
33
-
34
25
  def insert_security(xml, sect)
35
- description = "document"
36
- description = "standard" if %w(standard community-standard)
26
+ "document"
27
+ "standard" if %w(standard community-standard)
37
28
  .include?(@doctype)
38
29
  @doctype == "engineering-report" and return remove_security(xml)
39
30
  preface = sect.at("//preface") ||
@@ -61,14 +52,13 @@ module Metanorma
61
52
  end
62
53
 
63
54
  def insert_submitters(xml, sect)
64
- if xml.at("//submitters")
65
- preface = sect.at("//preface") ||
55
+ if xml.at("//clause[@type = 'submitters' or @type = 'contributors']")
56
+ p = sect.at("//preface") ||
66
57
  sect.add_previous_sibling("<preface/>").first
67
- xml.xpath("//submitters").each do |s|
68
- s.xpath(".//table").each do |t|
69
- t["unnumbered"] = true
70
- end
71
- preface.add_child s.remove
58
+ xml.xpath("//clause[@type = 'submitters' or @type = 'contributors']")
59
+ .each do |s|
60
+ s.xpath(".//table").each { |t| t["unnumbered"] = true }
61
+ p.add_child s.remove
72
62
  end
73
63
  end
74
64
  end
@@ -11,9 +11,6 @@ module Metanorma
11
11
  # schema encapsulation of the document for validation
12
12
  #
13
13
  class Converter < Standoc::Converter
14
- #XML_ROOT_TAG = "ogc-standard".freeze
15
- #XML_NAMESPACE = "https://www.metanorma.org/ns/ogc".freeze
16
-
17
14
  register_for "ogc"
18
15
 
19
16
  def init_toc(node)
@@ -71,10 +68,8 @@ module Metanorma
71
68
 
72
69
  def override_style(node)
73
70
  s = node.attr("style")
74
- if %w(executive_summary overview future_outlook value_proposition
75
- contributors).include?(s)
71
+ if %w(overview future_outlook value_proposition contributors).include?(s)
76
72
  node.set_attr("style", "preface")
77
- s == "executive_summary" and s = "executivesummary"
78
73
  node.set_attr("type", s)
79
74
  end
80
75
  if %w(aims objectives topics outlook security).include?(s)
@@ -93,6 +88,12 @@ module Metanorma
93
88
  end
94
89
  end
95
90
 
91
+ # legacy encoding
92
+ def sectiontype1(node)
93
+ role_style(node, "executive_summary") and return "executivesummary"
94
+ super
95
+ end
96
+
96
97
  def outputs(node, ret)
97
98
  File.open("#{@filename}.xml", "w:UTF-8") { |f| f.write(ret) }
98
99
  presentation_xml_converter(node).convert("#{@filename}.xml")
@@ -105,20 +106,18 @@ module Metanorma
105
106
  end
106
107
 
107
108
  def clause_parse(attrs, xml, node)
108
- %w(executivesummary overview future_outlook value_proposition
109
+ %w(overview future_outlook value_proposition
109
110
  contributors aims objectives topics outlook security)
110
111
  .include?(node.attr("type")) and
111
112
  attrs = attrs.merge(type: node.attr("type"))
112
113
  case node.attr("heading")&.downcase || node.title.downcase
113
114
  when "submitters"
114
- return submitters_parse(attrs, xml, node)
115
+ return submitters_parse(attrs.merge(type: "submitters"), xml, node)
115
116
  when "contributors"
116
117
  return submitters_parse(attrs.merge(type: "contributors"), xml, node)
117
118
  when "conformance" then attrs = attrs.merge(type: "conformance")
118
119
  when "security considerations"
119
120
  attrs = attrs.merge(type: "security")
120
- when "executive summary"
121
- attrs = attrs.merge(type: "executivesummary")
122
121
  end
123
122
  super
124
123
  end
@@ -128,7 +127,7 @@ module Metanorma
128
127
  doctype(node) == "engineering-report" ||
129
128
  attrs[:type] == "contributors" and
130
129
  title = @i18n.contributors_clause
131
- xml.submitters **attr_code(attrs) do |xml_section|
130
+ xml.clause **attr_code(attrs) do |xml_section|
132
131
  xml_section.title title
133
132
  xml_section << node.content
134
133
  end
@@ -164,7 +163,8 @@ module Metanorma
164
163
  end
165
164
  end
166
165
 
167
- def highlight_parse(text, xml)
166
+ # KILL
167
+ def highlight_parsex(text, xml)
168
168
  xml.hi { |s| s << text }
169
169
  end
170
170