relaton-bib 0.9.2 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.hound.yml +2 -0
- data/README.adoc +14 -7
- data/docs/hash.adoc +53 -53
- data/lib/relaton_bib/bib_item_locality.rb +59 -16
- data/lib/relaton_bib/bibliographic_item.rb +6 -2
- data/lib/relaton_bib/bibtex_parser.rb +22 -20
- data/lib/relaton_bib/document_relation.rb +49 -25
- data/lib/relaton_bib/document_relation_collection.rb +18 -5
- data/lib/relaton_bib/document_status.rb +46 -8
- data/lib/relaton_bib/formatted_string.rb +3 -3
- data/lib/relaton_bib/hash_converter.rb +59 -21
- data/lib/relaton_bib/localized_string.rb +33 -12
- data/lib/relaton_bib/typed_title_string.rb +1 -1
- data/lib/relaton_bib/version.rb +1 -1
- data/lib/relaton_bib/xml_parser.rb +94 -20
- data/relaton-bib.gemspec +3 -3
- metadata +17 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57c6be55831892ce4762c2a9e8f4526cc6e7efadb3f99b0a1cf0cea7219ed001
|
4
|
+
data.tar.gz: ae71060872bb8fb1630a66fda9a7af01c9dbc5497efbe16669193fbca4c426a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b3074c5b9dc2ee9e963b766e7428f1c56aa2cd961e11618e4eea8e0c0f5d20e35bd9d16a1ede8f821f2840bb0de4cf1e053666c486dfe6f6927d07999ad5c9b6
|
7
|
+
data.tar.gz: 9b5f8e1c773a95438942b6a69e13ce0f82e4fb194c364d141580d38726adc2329a00fc8b5b2ac96197591ae8993a1886148313b75676ca2b32865b1d7b17fbbc
|
data/.hound.yml
ADDED
data/README.adoc
CHANGED
@@ -155,8 +155,16 @@ item = RelatonBib::BibliographicItem.new(
|
|
155
155
|
bibitem: RelatonBib::BibliographicItem.new(
|
156
156
|
formattedref: RelatonBib::FormattedRef.new(content: "ISO 19115:2003"),
|
157
157
|
),
|
158
|
-
|
159
|
-
RelatonBib::
|
158
|
+
locality: [
|
159
|
+
RelatonBib::LocalityStack.new([
|
160
|
+
RelatonBib::Locality.new("volume", "1"),
|
161
|
+
RelatonBib::Locality.new("section", "2"),
|
162
|
+
]),
|
163
|
+
],
|
164
|
+
source_locality: [
|
165
|
+
RelatonBib::SourceLocalityStack.new([
|
166
|
+
RelatonBib::SourceLocality.new("chapter", "4"),
|
167
|
+
]),
|
160
168
|
],
|
161
169
|
},
|
162
170
|
{
|
@@ -249,7 +257,6 @@ item.abstract
|
|
249
257
|
|
250
258
|
item.abstract(lang: "en").to_s
|
251
259
|
=> "ISO 19115-1:2014 defines the schema required for ..."
|
252
|
-
"
|
253
260
|
----
|
254
261
|
|
255
262
|
=== BibliographicItem references
|
@@ -274,11 +281,11 @@ item.to_xml
|
|
274
281
|
----
|
275
282
|
|
276
283
|
Default root element is `bibitem`. With argument `bibdata: true` the XML wrapped with `bibdata` element.
|
277
|
-
[source,ruby]
|
278
284
|
|
285
|
+
[source,ruby]
|
279
286
|
----
|
280
|
-
item.to_xml
|
281
|
-
=> "<
|
287
|
+
item.to_xml bibdata: true
|
288
|
+
=> "<bibdata type=\"standard\">
|
282
289
|
<fetched>2019-04-30</fetched>
|
283
290
|
<title type=\"main\" language=\"en\" script=\"Latn\">Geographic information</title>
|
284
291
|
...
|
@@ -288,8 +295,8 @@ item.to_xml
|
|
288
295
|
==== Date format
|
289
296
|
|
290
297
|
By default date elements are formatted as year (yyyy). Option `:date_format` allows to output date elements in `:short` (yyyy-mm) and `:full` (yyyy-mm-dd) additiona formats.
|
291
|
-
[surce,ruby]
|
292
298
|
|
299
|
+
[surce,ruby]
|
293
300
|
----
|
294
301
|
item.to_xml date_format: :short
|
295
302
|
=> "<bibitem id=\"ISO/TC211\" type=\"standard\">
|
data/docs/hash.adoc
CHANGED
@@ -2,24 +2,24 @@
|
|
2
2
|
|
3
3
|
== YAML
|
4
4
|
|
5
|
-
The following structure is in place for encoding bibitem as YAML objects, and is also used
|
6
|
-
to represent bibliographic entries in Metanorma
|
5
|
+
The following structure is in place for encoding bibitem as YAML objects, and is also used
|
6
|
+
to represent bibliographic entries in Metanorma AsciiDoc. The structure has not yet been
|
7
7
|
generalised to `bibdata/ext`, the flavour-specific extensions of relaton.
|
8
8
|
|
9
9
|
If an element in Relaton XML has attributes, the content of the element is represented in YAML
|
10
10
|
with a `content` key:
|
11
11
|
|
12
12
|
[source,xml]
|
13
|
-
|
13
|
+
----
|
14
14
|
<title type="main">Geographic information</title>
|
15
|
-
|
15
|
+
----
|
16
16
|
|
17
17
|
[source,yaml]
|
18
|
-
|
18
|
+
----
|
19
19
|
title:
|
20
20
|
type: main
|
21
21
|
content: Geographic information
|
22
|
-
|
22
|
+
----
|
23
23
|
|
24
24
|
Any elements with a cardinality of many can be represented as arrays, but
|
25
25
|
they can also be populated by a hash or single element. For example,
|
@@ -27,7 +27,7 @@ a Relaton title can have multiple titles, and multiple scripts; so
|
|
27
27
|
the following are equivalent:
|
28
28
|
|
29
29
|
[source,yaml]
|
30
|
-
|
30
|
+
----
|
31
31
|
title:
|
32
32
|
- type: main
|
33
33
|
content: Geographic information
|
@@ -37,7 +37,7 @@ title:
|
|
37
37
|
script:
|
38
38
|
- Latn
|
39
39
|
script: Latn
|
40
|
-
|
40
|
+
----
|
41
41
|
|
42
42
|
In YAML, "on" is a reserved word, and thus cannot be used as a key. "value" is used as a synonym for
|
43
43
|
"on" in dates.
|
@@ -45,7 +45,7 @@ In YAML, "on" is a reserved word, and thus cannot be used as a key. "value" is u
|
|
45
45
|
The structure below is given in YAML format:
|
46
46
|
|
47
47
|
[source,yaml]
|
48
|
-
|
48
|
+
----
|
49
49
|
# bibliographic item anchor, used to crossreference within document
|
50
50
|
id: ISO/TC211
|
51
51
|
# date record was created
|
@@ -118,11 +118,11 @@ abstract:
|
|
118
118
|
# Initials, forename, additions, prefixes are arrays.
|
119
119
|
# Name field values are either strings, or hashes, with content and language and script attributes.
|
120
120
|
# The language and script attribute can also be given on the name.
|
121
|
-
# Contacts are an array, containing either addresses, or other fields.
|
122
|
-
# Addresses are identified as hashes containing a city attribute; they can also contain a street
|
121
|
+
# Contacts are an array, containing either addresses, or other fields.
|
122
|
+
# Addresses are identified as hashes containing a city attribute; they can also contain a street
|
123
123
|
# (which is an array), a postcode, a state, and a country. The other contact fields
|
124
124
|
# are phones, emails, uris; they contain a type giving the field name, and a value.
|
125
|
-
# Affiliations are an array, and they contains an organization, and an optional description.
|
125
|
+
# Affiliations are an array, and they contains an organization, and an optional description.
|
126
126
|
# The affiliation description can be a single string, or a hash of content, language, script, and format.
|
127
127
|
contributor:
|
128
128
|
- organization:
|
@@ -130,7 +130,7 @@ contributor:
|
|
130
130
|
url: www.iso.org
|
131
131
|
abbreviation: ISO
|
132
132
|
subdivision: division
|
133
|
-
role:
|
133
|
+
role:
|
134
134
|
type: publisher
|
135
135
|
description: Publisher role
|
136
136
|
- person:
|
@@ -142,7 +142,7 @@ contributor:
|
|
142
142
|
- organization:
|
143
143
|
name: IETF
|
144
144
|
abbreviation: IETF
|
145
|
-
identifier:
|
145
|
+
identifier:
|
146
146
|
- type: uri
|
147
147
|
id: www.ietf.org
|
148
148
|
description: Affiliation description
|
@@ -181,7 +181,7 @@ contributor:
|
|
181
181
|
identifier:
|
182
182
|
- type: uri
|
183
183
|
id: www.person.com
|
184
|
-
role:
|
184
|
+
role:
|
185
185
|
author
|
186
186
|
# copyright consists of an owner (a hash containing the fields of an organisation),
|
187
187
|
# a "from" date, and an optional "to" date
|
@@ -220,7 +220,7 @@ relation:
|
|
220
220
|
# an abbreviation, a from, a to, a number, and a partnumber.
|
221
221
|
# The series title, like the titles of bibliographic items, contains a type,
|
222
222
|
# content, and optional language, script, and format attributes.
|
223
|
-
# The abbreviation and formattedref are either a string,
|
223
|
+
# The abbreviation and formattedref are either a string,
|
224
224
|
# or a hash containing content, language, and script.
|
225
225
|
series:
|
226
226
|
- type: main
|
@@ -241,7 +241,7 @@ series:
|
|
241
241
|
number: serie1234
|
242
242
|
partnumber: part5678
|
243
243
|
- type: alt
|
244
|
-
formattedref:
|
244
|
+
formattedref:
|
245
245
|
content: serieref
|
246
246
|
language: en
|
247
247
|
script: Latn
|
@@ -269,30 +269,30 @@ validity:
|
|
269
269
|
begins: 2010-10-10 12:21
|
270
270
|
ends: 2011-02-03 18:30
|
271
271
|
revision: 2011-03-04 09:00
|
272
|
-
|
272
|
+
----
|
273
273
|
|
274
274
|
== Metanorma structure (AsciiBib): nested definition list
|
275
275
|
|
276
|
-
The Metanorma
|
276
|
+
The Metanorma AsciiDoc representation of the Relaton hash structure
|
277
277
|
in a bibliography
|
278
278
|
is as a definition list of element name and element contents,
|
279
279
|
with nested definition lists for nested structures. If a nested
|
280
280
|
definition is given for an element, the element itself has a blank definition.
|
281
281
|
|
282
|
-
As with the YAML representation, if an element in Relaton XML has attributes,
|
282
|
+
As with the YAML representation, if an element in Relaton XML has attributes,
|
283
283
|
the content of the element is represented in YAML with a `content` key:
|
284
284
|
|
285
285
|
[source,xml]
|
286
|
-
|
286
|
+
----
|
287
287
|
<title type="main">Geographic information</title>
|
288
|
-
|
288
|
+
----
|
289
289
|
|
290
290
|
[source,asciidoc]
|
291
|
-
|
291
|
+
----
|
292
292
|
title::
|
293
293
|
type::: main
|
294
294
|
content::: Geographic information
|
295
|
-
|
295
|
+
----
|
296
296
|
|
297
297
|
Likewise, as with the YAML representation,
|
298
298
|
Repeating elements in a hash can be realised as ordered or unordered lists.
|
@@ -304,9 +304,9 @@ language::
|
|
304
304
|
. fr
|
305
305
|
----
|
306
306
|
|
307
|
-
Metanorma
|
307
|
+
Metanorma AsciiDoc also supports representing repeating elements
|
308
308
|
by repeating the key for that entry. This will almost always be more
|
309
|
-
straightforward to use in
|
309
|
+
straightforward to use in AsciiDoc:
|
310
310
|
|
311
311
|
[source,asciidoc]
|
312
312
|
----
|
@@ -314,19 +314,19 @@ language:: en
|
|
314
314
|
language:: fr
|
315
315
|
----
|
316
316
|
|
317
|
-
Each Relaton entry in a bibliography is represented in Metanorma
|
317
|
+
Each Relaton entry in a bibliography is represented in Metanorma AsciiDoc
|
318
318
|
through a subclause with option attribute `[%bibitem]`. Any title given to the
|
319
319
|
subclause is treated as the title for the bibliographic entry, with language `en`,
|
320
|
-
script `Latn`, format `text/plain`, and type `main`.
|
320
|
+
script `Latn`, format `text/plain`, and type `main`.
|
321
321
|
|
322
|
-
So the following is a very simple reference in Metanorma
|
322
|
+
So the following is a very simple reference in Metanorma AsciiDoc:
|
323
323
|
|
324
324
|
[source,asciidoc]
|
325
325
|
----
|
326
326
|
[%bibitem]
|
327
327
|
=== Rubber latex -- Sampling
|
328
328
|
id:: iso123
|
329
|
-
docid::
|
329
|
+
docid::
|
330
330
|
type::: ISO
|
331
331
|
id::: ISO 123
|
332
332
|
docid::
|
@@ -355,7 +355,7 @@ content::: Latex de caoutchouc -- Échantillonnage
|
|
355
355
|
Note the use of `content` as a key to represent the contents of the `title` tag.
|
356
356
|
|
357
357
|
The anchor crossreference for the bibliographic entry may be encoded as either the
|
358
|
-
`id` entry in the definition list, or as the normal
|
358
|
+
`id` entry in the definition list, or as the normal AsciiDoc anchor on the
|
359
359
|
subclause, which takes priority:
|
360
360
|
|
361
361
|
[source,asciidoc]
|
@@ -363,7 +363,7 @@ subclause, which takes priority:
|
|
363
363
|
[[iso123]]
|
364
364
|
[%bibitem]
|
365
365
|
=== Rubber latex -- Sampling
|
366
|
-
docid::
|
366
|
+
docid::
|
367
367
|
type::: ISO
|
368
368
|
id::: ISO 123
|
369
369
|
type:: standard
|
@@ -376,7 +376,7 @@ Repeating elements in a hash can be realised as ordered or unordered lists.
|
|
376
376
|
[[iso123]]
|
377
377
|
[%bibitem]
|
378
378
|
=== Rubber latex -- Sampling
|
379
|
-
docid::
|
379
|
+
docid::
|
380
380
|
type::: ISO
|
381
381
|
id::: ISO 123
|
382
382
|
language::
|
@@ -384,23 +384,23 @@ language::
|
|
384
384
|
. fr
|
385
385
|
----
|
386
386
|
|
387
|
-
Metanorma
|
387
|
+
Metanorma AsciiDoc also supports representing repeating elements
|
388
388
|
by repeating the key for that entry. This will almost always be more
|
389
|
-
straightforward to use in
|
389
|
+
straightforward to use in AsciiDoc:
|
390
390
|
|
391
391
|
[source,asciidoc]
|
392
392
|
----
|
393
393
|
[[iso123]]
|
394
394
|
[%bibitem]
|
395
395
|
=== Rubber latex -- Sampling
|
396
|
-
docid::
|
396
|
+
docid::
|
397
397
|
type::: ISO
|
398
398
|
id::: ISO 123
|
399
399
|
language:: en
|
400
400
|
language:: fr
|
401
401
|
----
|
402
402
|
|
403
|
-
|
403
|
+
AsciiDoc does not recognise definition lists more than four levels
|
404
404
|
deep. If deeper nesting is needed, you will need to attach a new definition
|
405
405
|
list with a list continuation, with the definition list depth reset back to one:
|
406
406
|
|
@@ -409,7 +409,7 @@ list with a list continuation, with the definition list depth reset back to one:
|
|
409
409
|
[[iso123]]
|
410
410
|
[%bibitem]
|
411
411
|
=== Rubber latex -- Sampling
|
412
|
-
docid::
|
412
|
+
docid::
|
413
413
|
type::: ISO
|
414
414
|
id::: ISO 123
|
415
415
|
type:: standard
|
@@ -428,25 +428,25 @@ completename::
|
|
428
428
|
(This is very awkward, and <<JSONPath>> provides a workaround.)
|
429
429
|
|
430
430
|
The most heavily nested parts of a Relaton entry are the contributors,
|
431
|
-
series, and relations.
|
431
|
+
series, and relations.
|
432
432
|
Each of these can be marked up as subclauses within the entry, with the clause
|
433
433
|
titles "contributor", "series", and "relation". Each subclause contains
|
434
434
|
a new definition list, with its definition list reset to zero depth;
|
435
435
|
the subclauses can be repeated for multiple instances of the same subentity.
|
436
436
|
|
437
|
-
AsciiBib citations can be combined with other
|
438
|
-
same Metanorma document; but any
|
437
|
+
AsciiBib citations can be combined with other AsciiDoc citations in the
|
438
|
+
same Metanorma document; but any AsciiDoc citations need be precede
|
439
439
|
AsciiBib citations. Each AsciiBib citations constitutes a subclause of its own,
|
440
440
|
and Metanorma will (unsuccessfully) attempt to incorporate any trailing material
|
441
|
-
in the subclause, including
|
441
|
+
in the subclause, including AsciiDoc citations, into the current AsciiBib
|
442
442
|
citation.
|
443
443
|
|
444
|
-
The following is Metanorma
|
444
|
+
The following is Metanorma AsciiDoc markup corresponding to the YAML
|
445
445
|
given above:
|
446
446
|
|
447
447
|
|
448
448
|
[source,asciidoc]
|
449
|
-
|
449
|
+
----
|
450
450
|
[[ISO/TC211]]
|
451
451
|
[%bibitem]
|
452
452
|
=== {blank}
|
@@ -547,7 +547,7 @@ organization::
|
|
547
547
|
url::: www.iso.org
|
548
548
|
abbreviation::: ISO
|
549
549
|
subdivision::: division
|
550
|
-
role::
|
550
|
+
role::
|
551
551
|
type::: publisher
|
552
552
|
description::: Publisher role
|
553
553
|
|
@@ -654,15 +654,15 @@ formattedref::
|
|
654
654
|
content::: serieref
|
655
655
|
language::: en
|
656
656
|
script::: Latn
|
657
|
-
|
657
|
+
----
|
658
658
|
|
659
659
|
[[JSONPath]]
|
660
660
|
== JSON Path style definition lists
|
661
661
|
|
662
662
|
The foregoing structure requires frequent breakouts into open blocks, to deal
|
663
|
-
with the limitation on
|
664
|
-
represent the nested structure of Relaton records in a simple, one-level definition list,
|
665
|
-
and to use the key for each key-value pair to represent the hierarchical nesting of entries,
|
663
|
+
with the limitation on AsciiDoc nested definition lists. An alternative is to
|
664
|
+
represent the nested structure of Relaton records in a simple, one-level definition list,
|
665
|
+
and to use the key for each key-value pair to represent the hierarchical nesting of entries,
|
666
666
|
as a dot-delimited path of keys. For example,
|
667
667
|
|
668
668
|
[source,asciidoc]
|
@@ -670,7 +670,7 @@ as a dot-delimited path of keys. For example,
|
|
670
670
|
[%bibitem]
|
671
671
|
=== Rubber latex -- Sampling
|
672
672
|
id:: iso123
|
673
|
-
docid::
|
673
|
+
docid::
|
674
674
|
type::: ISO
|
675
675
|
id::: ISO 123
|
676
676
|
----
|
@@ -693,7 +693,7 @@ Whenever part of the key is repeated between entries, the entries are assumed to
|
|
693
693
|
[%bibitem]
|
694
694
|
=== Rubber latex -- Sampling
|
695
695
|
id:: iso123
|
696
|
-
docid::
|
696
|
+
docid::
|
697
697
|
type::: ISO
|
698
698
|
id::: ISO 123
|
699
699
|
docid::
|
@@ -754,11 +754,11 @@ contributor.person.contact.type:: phone
|
|
754
754
|
contributor.person.contact.value:: 223322
|
755
755
|
----
|
756
756
|
|
757
|
-
The following is Metanorma
|
757
|
+
The following is Metanorma AsciiDoc markup corresponding to the YAML
|
758
758
|
given above, using JSON Path style definition lists instead of nested definition lists:
|
759
759
|
|
760
760
|
[source,asciidoc]
|
761
|
-
|
761
|
+
----
|
762
762
|
[[ISO/TC211]]
|
763
763
|
[%bibitem]
|
764
764
|
=== {blank}
|
@@ -1,20 +1,4 @@
|
|
1
1
|
module RelatonBib
|
2
|
-
# class SpecificLocalityType
|
3
|
-
# SECTION = 'section'
|
4
|
-
# CLAUSE = 'clause'
|
5
|
-
# PART = 'part'
|
6
|
-
# PARAGRAPH = 'paragraph'
|
7
|
-
# CHAPTER = 'chapter'
|
8
|
-
# PAGE = 'page'
|
9
|
-
# WHOLE = 'whole'
|
10
|
-
# TABLE = 'table'
|
11
|
-
# ANNEX = 'annex'
|
12
|
-
# FIGURE = 'figure'
|
13
|
-
# NOTE = 'note'
|
14
|
-
# EXAMPLE = 'example'
|
15
|
-
# # generic String is allowed
|
16
|
-
# end
|
17
|
-
|
18
2
|
# Bibliographic item locality.
|
19
3
|
class BibItemLocality
|
20
4
|
# @return [String]
|
@@ -30,6 +14,13 @@ module RelatonBib
|
|
30
14
|
# @param referenceFrom [String]
|
31
15
|
# @param referenceTo [String, NilClass]
|
32
16
|
def initialize(type, reference_from, reference_to = nil)
|
17
|
+
type_ptrn = %r{section|clause|part|paragraph|chapter|page|whole|table|
|
18
|
+
annex|figure|note|list|example|volume|issue|time|
|
19
|
+
locality:[a-zA-Z0-9_]+}x
|
20
|
+
unless type =~ type_ptrn
|
21
|
+
warn "[relaton-bib] WARNING: invalid locality type: #{type}"
|
22
|
+
end
|
23
|
+
|
33
24
|
@type = type
|
34
25
|
@reference_from = reference_from
|
35
26
|
@reference_to = reference_to
|
@@ -49,4 +40,56 @@ module RelatonBib
|
|
49
40
|
hash
|
50
41
|
end
|
51
42
|
end
|
43
|
+
|
44
|
+
class Locality < BibItemLocality
|
45
|
+
# @param builder [Nokogiri::XML::Builder]
|
46
|
+
def to_xml(builder)
|
47
|
+
builder.locality { |b| super(b) }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class LocalityStack
|
52
|
+
include RelatonBib
|
53
|
+
|
54
|
+
# @return [Array<RelatonBib::Locality>]
|
55
|
+
attr_reader :locality
|
56
|
+
|
57
|
+
# @param locality [Array<RelatonBib::Locality>]
|
58
|
+
def initialize(locality)
|
59
|
+
@locality = locality
|
60
|
+
end
|
61
|
+
|
62
|
+
# @param builder [Nokogiri::XML::Builder]
|
63
|
+
def to_xml(builder)
|
64
|
+
builder.localityStack do |b|
|
65
|
+
locality.each { |l| l.to_xml(b) }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# @returnt [Hash]
|
70
|
+
def to_hash
|
71
|
+
{ "locality_stack" => single_element_array(locality) }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
class SourceLocality < BibItemLocality
|
76
|
+
# @param builder [Nokogiri::XML::Builder]
|
77
|
+
def to_xml(builder)
|
78
|
+
builder.sourceLocality { |b| super(b) }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class SourceLocalityStack < LocalityStack
|
83
|
+
# @param builder [Nokogiri::XML::Builder]
|
84
|
+
def to_xml(builder)
|
85
|
+
builder.sourceLocalityStack do |b|
|
86
|
+
locality.each { |l| l.to_xml(b) }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# @returnt [Hash]
|
91
|
+
def to_hash
|
92
|
+
{ "source_locality_stack" => single_element_array(locality) }
|
93
|
+
end
|
94
|
+
end
|
52
95
|
end
|