natour 0.10.0 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.natour.yml +29 -0
- data/CHANGELOG.adoc +29 -17
- data/README.adoc +2 -1
- data/bin/natour +9 -36
- data/lib/natour/asciinurse.rb +14 -10
- data/lib/natour/config.rb +3 -6
- data/lib/natour/create_reports.rb +3 -2
- data/lib/natour/gps_track.rb +2 -1
- data/lib/natour/gpx_file.rb +10 -1
- data/lib/natour/public_transport.rb +1 -1
- data/lib/natour/report.rb +1 -0
- data/lib/natour/species_list.rb +2 -2
- data/lib/natour/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ac583bda8dbd5de8b922cc64bee346916b01c07b4ee986b845ef3c2c87985d0
|
4
|
+
data.tar.gz: 3e89dd11b0dda46ba30fdc62aec372068f5390209f7d119182d9340e4d5fbbfa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 96b0e7a19722f0749d08fe5a51cc9b8491b1e0f04533aed2a07f0fc091ae27eb5df2f1e0c4dc1fd67ef21673840744b9aab27f28bd12376b7dfdd3c126d7b441
|
7
|
+
data.tar.gz: 55f7c5dbfa646ac25e715f3dc7a1b169fc72bc223bf49893f19bbd6d0cc3c5b773ad1bef64f3520ebe4290d1ec2ea7a28b1da745157de877cce9a485bcc55467
|
data/.natour.yml
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
---
|
2
|
+
:report:
|
3
|
+
:create:
|
4
|
+
:out_dir: null
|
5
|
+
:out_file: null
|
6
|
+
:overwrite: false
|
7
|
+
:track_formats:
|
8
|
+
- :gpx
|
9
|
+
- :fit
|
10
|
+
:map: true
|
11
|
+
:map_layers: []
|
12
|
+
:adoc_author: null
|
13
|
+
:short_species_names: false
|
14
|
+
:convert:
|
15
|
+
:out_dir: null
|
16
|
+
:out_file: null
|
17
|
+
:overwrite: false
|
18
|
+
:backend: :pdf
|
19
|
+
:draft: false
|
20
|
+
:draft_backend: null
|
21
|
+
:image_maxdim: 1800
|
22
|
+
:map:
|
23
|
+
:create:
|
24
|
+
:out_dir: null
|
25
|
+
:out_file: null
|
26
|
+
:overwrite: false
|
27
|
+
:gps_colors: []
|
28
|
+
:map_layers: []
|
29
|
+
:image_size: [1200, 900]
|
data/CHANGELOG.adoc
CHANGED
@@ -4,15 +4,41 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
|
5
5
|
The format is based on https://keepachangelog.com/en/1.0.0/[Keep a Changelog^], and this project adheres to https://semver.org/spec/v2.0.0.html[Semantic Versioning^].
|
6
6
|
|
7
|
+
IMPORTANT: As per Semantic Versioning, the major version zero is for initial development and anything may change at any time.
|
8
|
+
|
7
9
|
== Unreleased
|
8
10
|
|
11
|
+
== 0.12.0 - 2023-11-22
|
12
|
+
|
13
|
+
=== Added
|
14
|
+
|
15
|
+
- Add command line option to use short species names in the AsciiDoc output. The species names are truncated by removing the authority (botany only).
|
16
|
+
|
17
|
+
=== Changed
|
18
|
+
|
19
|
+
- Do not use shorthand syntax for the breakable option in the AsciiDoc output.
|
20
|
+
|
21
|
+
=== Fixed
|
22
|
+
|
23
|
+
- Do not abort report creation if species lists are empty (assume default columns for the AsciiDoc output).
|
24
|
+
- Fix search of public transport stations if distance is missing (e.g. if the coordinates are outside of Switzerland).
|
25
|
+
|
26
|
+
== 0.11.0 - 2023-04-15
|
27
|
+
|
28
|
+
=== Changed
|
29
|
+
|
30
|
+
- Specify files to load for a configuration instead of a file and directories.
|
31
|
+
- The configuration files must now be named `.natour.yml` (prefixed with a dot).
|
32
|
+
|
33
|
+
=== Fixed
|
34
|
+
|
35
|
+
- Do not abort creating reports if GPX files do not contain tracks.
|
36
|
+
|
9
37
|
== 0.10.0 - 2023-02-18
|
10
38
|
|
11
39
|
=== Fixed
|
12
40
|
|
13
41
|
- Prevent orphaned section titles and table captions in PDF output.
|
14
|
-
+
|
15
|
-
IMPORTANT: This is a breaking change for existing AsciiDoc files that are converted again. Apply the breakable option to tables containing species lists; otherwise the numbering of the tables will not be consecutive.
|
16
42
|
|
17
43
|
== 0.9.0 - 2022-10-08
|
18
44
|
|
@@ -22,7 +48,7 @@ IMPORTANT: This is a breaking change for existing AsciiDoc files that are conver
|
|
22
48
|
|
23
49
|
=== Changed
|
24
50
|
|
25
|
-
- Omit empty columns of species lists in AsciiDoc output.
|
51
|
+
- Omit empty columns of species lists in the AsciiDoc output.
|
26
52
|
|
27
53
|
=== Fixed
|
28
54
|
|
@@ -39,21 +65,11 @@ IMPORTANT: This is a breaking change for existing AsciiDoc files that are conver
|
|
39
65
|
=== Changed
|
40
66
|
|
41
67
|
- Rename arguments of `Natour::MapGeoAdmin.save_image`, i.e. `tracks` to `gps_files`, `layers` to `map_layers` and `size` to `image_size`.
|
42
|
-
+
|
43
|
-
IMPORTANT: This is a breaking change.
|
44
68
|
- Improve the error reporting on the command line interface in case of file errors.
|
45
69
|
- Rework the configuration; the structure and naming follows the command line interface and the keys are of type Ruby Symbol. For details, see the README file.
|
46
|
-
+
|
47
|
-
IMPORTANT: This is a breaking change. Adapt the configuration file accordingly.
|
48
70
|
- Rework the command line interface. Use `natour --help` to get more information.
|
49
|
-
+
|
50
|
-
IMPORTANT: This is a breaking change. Adapt the commands accordingly.
|
51
71
|
- Change `backend` and `draft_backend` arguments of `Natour::convert_report` to symbols.
|
52
|
-
+
|
53
|
-
IMPORTANT: This is a breaking change. Adapt the configuration file accordingly.
|
54
72
|
- Rename `Natour::create` to `Natour::create_reports` and `Natour::convert` to `Natour::convert_report`.
|
55
|
-
+
|
56
|
-
IMPORTANT: This is a breaking change.
|
57
73
|
|
58
74
|
=== Fixed
|
59
75
|
|
@@ -110,8 +126,6 @@ IMPORTANT: This is a breaking change.
|
|
110
126
|
=== Removed
|
111
127
|
|
112
128
|
- Remove redundant method `Natour::Image.portrait?`.
|
113
|
-
+
|
114
|
-
IMPORTANT: This is a breaking change. Use `Natour::Image.landscape?` instead.
|
115
129
|
|
116
130
|
== 0.3.0 - 2021-03-07
|
117
131
|
|
@@ -136,8 +150,6 @@ IMPORTANT: This is a breaking change. Use `Natour::Image.landscape?` instead.
|
|
136
150
|
=== Changed
|
137
151
|
|
138
152
|
- Rename `Natour::SpeciesList.name` to `Natour::SpeciesList.title`.
|
139
|
-
+
|
140
|
-
IMPORTANT: This is a breaking change.
|
141
153
|
- Return an empty array from `Natour::SpeciesList.load_file` if the format is unknown.
|
142
154
|
- Change the format of the start time in the AsciiDoc output from _12:30_ to _12:30 Uhr_.
|
143
155
|
- Change the format of the duration in the AsciiDoc output from _1h30_ to _1:30 h_.
|
data/README.adoc
CHANGED
@@ -90,7 +90,7 @@ NOTE: Use `natour --help` to get more information.
|
|
90
90
|
|
91
91
|
=== Configuration
|
92
92
|
|
93
|
-
The configuration is built by loading https://yaml.org/[YAML^] files in hierarchical order. The files must be named
|
93
|
+
The configuration is built by loading https://yaml.org/[YAML^] files in hierarchical order. The files must be named `.natour.yml` and are loaded first from the home directory of the current user and then from the current working directory. The values of the previously loaded files are overwritten by the values of the files loaded later. The values are stored internally in nested, dictionary-like collections (Ruby `Hash`), where the structure follows to the command line interface. All keys are of type Ruby `Symbol` and correspond to the commands and options, with middle hyphens replaced by underscores, leading hyphens removed, and without the `no-` prefix for boolean switches. The following configuration file shows all entries and their default values.
|
94
94
|
|
95
95
|
[source,yml]
|
96
96
|
----
|
@@ -106,6 +106,7 @@ The configuration is built by loading https://yaml.org/[YAML^] files in hierarch
|
|
106
106
|
:map: true
|
107
107
|
:map_layers: []
|
108
108
|
:adoc_author: null
|
109
|
+
:short_species_names: false
|
109
110
|
:convert:
|
110
111
|
:out_dir: null
|
111
112
|
:out_file: null
|
data/bin/natour
CHANGED
@@ -21,6 +21,7 @@ class NatourCmd < Clamp::Command
|
|
21
21
|
option(%W[--\[no-\]map], :flag, 'Create map images')
|
22
22
|
option(%w[--map-layers], 'LAYERS', 'Add additional layers to map images') { |s| s.split(',') }
|
23
23
|
option(%w[--adoc-author], 'AUTHOR', 'AsciiDoc author (name <email>[; name2 <email2>...])')
|
24
|
+
option(%W[--\[no-\]short-species-names], :flag, 'Use short species names (botany only)')
|
24
25
|
parameter('PATH', 'Path to directory')
|
25
26
|
|
26
27
|
def execute
|
@@ -33,7 +34,9 @@ class NatourCmd < Clamp::Command
|
|
33
34
|
track_formats: track_formats || config[:track_formats],
|
34
35
|
create_map: Natour::BooleanUtils.to_boolean(map?, default_value: config[:map]),
|
35
36
|
map_layers: map_layers || config[:map_layers],
|
36
|
-
adoc_author: adoc_author || config[:adoc_author]
|
37
|
+
adoc_author: adoc_author || config[:adoc_author],
|
38
|
+
short_species_names: Natour::BooleanUtils.to_boolean(short_species_names?,
|
39
|
+
default_value: config[:short_species_names])
|
37
40
|
)
|
38
41
|
rescue Errno::EEXIST, Errno::ENOENT, Errno::EACCES, Errno::EISDIR, Errno::EINVAL => e
|
39
42
|
message, _, path = Natour::ErrnoUtils.split_message(e)
|
@@ -125,41 +128,11 @@ class NatourCmd < Clamp::Command
|
|
125
128
|
end
|
126
129
|
end
|
127
130
|
|
128
|
-
config = Natour::Config.
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
out_dir: nil,
|
134
|
-
out_file: nil,
|
135
|
-
overwrite: false,
|
136
|
-
track_formats: %i[gpx fit],
|
137
|
-
map: true,
|
138
|
-
map_layers: [],
|
139
|
-
adoc_author: nil
|
140
|
-
},
|
141
|
-
convert: {
|
142
|
-
out_dir: nil,
|
143
|
-
out_file: nil,
|
144
|
-
overwrite: false,
|
145
|
-
backend: :pdf,
|
146
|
-
draft: false,
|
147
|
-
draft_backend: nil,
|
148
|
-
image_maxdim: 1800
|
149
|
-
}
|
150
|
-
},
|
151
|
-
map: {
|
152
|
-
create: {
|
153
|
-
out_dir: nil,
|
154
|
-
out_file: nil,
|
155
|
-
overwrite: false,
|
156
|
-
gps_colors: [],
|
157
|
-
map_layers: [],
|
158
|
-
image_size: [1200, 900]
|
159
|
-
}
|
160
|
-
}
|
161
|
-
}
|
162
|
-
)
|
131
|
+
config = Natour::Config.load_files([
|
132
|
+
"#{__dir__}/../.natour.yml",
|
133
|
+
Pathname(Dir.home).join('.natour.yml'),
|
134
|
+
Pathname(Dir.pwd).join('.natour.yml')
|
135
|
+
])
|
163
136
|
|
164
137
|
NatourCmd.run(
|
165
138
|
Pathname($PROGRAM_NAME).basename,
|
data/lib/natour/asciinurse.rb
CHANGED
@@ -4,7 +4,7 @@ require 'pathname'
|
|
4
4
|
|
5
5
|
module Natour
|
6
6
|
module Asciinurse
|
7
|
-
def save_adoc(filename, overwrite: false, author: nil)
|
7
|
+
def save_adoc(filename, overwrite: false, author: nil, short_species_names: false)
|
8
8
|
dir = Pathname(filename).dirname
|
9
9
|
FileUtils.mkdir_p(dir)
|
10
10
|
mode = File::WRONLY | File::CREAT | File::TRUNC
|
@@ -14,12 +14,13 @@ module Natour
|
|
14
14
|
doc_root: Pathname(path).realpath
|
15
15
|
.relative_path_from(dir.realpath)
|
16
16
|
.to_s.force_encoding('utf-8'),
|
17
|
-
author: author
|
17
|
+
author: author,
|
18
|
+
short_species_names: short_species_names
|
18
19
|
))
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
22
|
-
def to_adoc(doc_root: '.', author: nil)
|
23
|
+
def to_adoc(doc_root: '.', author: nil, short_species_names: false)
|
23
24
|
distance = ->(gps_track) { "#{gps_track.distance / 1000} km" if gps_track&.distance }
|
24
25
|
ascent = ->(gps_track) { "#{gps_track.ascent} m" if gps_track&.ascent }
|
25
26
|
descent = ->(gps_track) { "#{gps_track.descent} m" if gps_track&.descent }
|
@@ -98,16 +99,19 @@ module Natour
|
|
98
99
|
group: :plants,
|
99
100
|
title: 'Pflanzenarten',
|
100
101
|
columns: [
|
101
|
-
OpenStruct.new(
|
102
|
-
|
102
|
+
OpenStruct.new(
|
103
|
+
header: 'Wissenschaftlicher Name',
|
104
|
+
accessor: ->(species) { short_species_names ? BotanicalNameUtils.parse(species.name) : species.name }
|
105
|
+
),
|
106
|
+
OpenStruct.new(header: 'Deutscher Name', accessor: ->(species) { species.name_de })
|
103
107
|
]
|
104
108
|
),
|
105
109
|
OpenStruct.new(
|
106
110
|
group: :birds,
|
107
111
|
title: 'Vogelarten',
|
108
112
|
columns: [
|
109
|
-
OpenStruct.new(header: 'Deutscher Name', accessor:
|
110
|
-
OpenStruct.new(header: 'Wissenschaftlicher Name', accessor:
|
113
|
+
OpenStruct.new(header: 'Deutscher Name', accessor: ->(species) { species.name_de }),
|
114
|
+
OpenStruct.new(header: 'Wissenschaftlicher Name', accessor: ->(species) { species.name })
|
111
115
|
]
|
112
116
|
)
|
113
117
|
].each do |info|
|
@@ -120,16 +124,16 @@ module Natour
|
|
120
124
|
caption = '.Tabelle {counter:species_lists}'
|
121
125
|
caption << ": #{species_list.description}" if species_list.description
|
122
126
|
columns = info.columns.select do |column|
|
123
|
-
species_list.any? { |species| !
|
127
|
+
species_list.count.zero? || species_list.any? { |species| !column.accessor.call(species).nil? }
|
124
128
|
end
|
125
129
|
cols = [1] + [5 * info.columns.size / columns.size] * columns.size
|
126
130
|
doc << caption
|
127
|
-
doc << "[
|
131
|
+
doc << "[cols=\"#{cols.join(',')}\",options=\"header,breakable\"]"
|
128
132
|
doc << '|==='
|
129
133
|
doc << "|Nr.|#{columns.map(&:header).join('|')}"
|
130
134
|
species_list.each do |species|
|
131
135
|
doc <<
|
132
|
-
"|{counter:species_list#{index}}|#{columns.map { |column|
|
136
|
+
"|{counter:species_list#{index}}|#{columns.map { |column| column.accessor.call(species) }
|
133
137
|
.join('|')}"
|
134
138
|
end
|
135
139
|
doc << '|==='
|
data/lib/natour/config.rb
CHANGED
@@ -4,12 +4,9 @@ require 'yaml'
|
|
4
4
|
|
5
5
|
module Natour
|
6
6
|
class Config
|
7
|
-
def self.
|
8
|
-
configs =
|
9
|
-
config = YAML.safe_load(
|
10
|
-
File.read(Pathname(dir).join(filename)),
|
11
|
-
permitted_classes: [Symbol]
|
12
|
-
)
|
7
|
+
def self.load_files(filenames, default: {})
|
8
|
+
configs = filenames.map do |filename|
|
9
|
+
config = YAML.safe_load(File.read(filename), permitted_classes: [Symbol])
|
13
10
|
config || {}
|
14
11
|
rescue Errno::ENOENT
|
15
12
|
{}
|
@@ -4,7 +4,8 @@ module Natour
|
|
4
4
|
module_function
|
5
5
|
|
6
6
|
def create_reports(dir, out_dir: nil, out_file: nil, overwrite: false,
|
7
|
-
track_formats: %i[gpx fit], create_map: true, map_layers: [],
|
7
|
+
track_formats: %i[gpx fit], create_map: true, map_layers: [],
|
8
|
+
adoc_author: nil, short_species_names: false)
|
8
9
|
out_dir = Pathname(out_dir || dir)
|
9
10
|
out_file = Pathname(out_file || "#{Pathname(dir).realpath.basename}.adoc")
|
10
11
|
reports = Report.load_directory(
|
@@ -16,7 +17,7 @@ module Natour
|
|
16
17
|
else
|
17
18
|
out_dir.join("#{out_file.basename('.*')} (#{index})#{out_file.extname}")
|
18
19
|
end
|
19
|
-
report.save_adoc(filename, overwrite: overwrite, author: adoc_author)
|
20
|
+
report.save_adoc(filename, overwrite: overwrite, author: adoc_author, short_species_names: short_species_names)
|
20
21
|
filename.to_s
|
21
22
|
end
|
22
23
|
end
|
data/lib/natour/gps_track.rb
CHANGED
@@ -29,7 +29,8 @@ module Natour
|
|
29
29
|
format = Pathname(filename).extname.to_s.delete_prefix('.').to_sym if format == :auto
|
30
30
|
case format
|
31
31
|
when :gpx
|
32
|
-
GPXFile.new(filename)
|
32
|
+
gpx_file = GPXFile.new(filename)
|
33
|
+
gpx_file if gpx_file.types.include?(:track)
|
33
34
|
when :fit
|
34
35
|
FITFile.new(filename)
|
35
36
|
end
|
data/lib/natour/gpx_file.rb
CHANGED
@@ -9,9 +9,16 @@ module Natour
|
|
9
9
|
'xmlns:gpxtrkx' => 'http://www.garmin.com/xmlschemas/TrackStatsExtension/v1'
|
10
10
|
}.freeze
|
11
11
|
|
12
|
+
attr_reader :types
|
13
|
+
|
12
14
|
def initialize(filename)
|
13
15
|
@doc = Nokogiri.XML(File.read(filename, mode: 'r:utf-8'))
|
14
16
|
|
17
|
+
@types = []
|
18
|
+
@types << :waypoint if @doc.at('/xmlns:gpx/xmlns:wpt', GPX_XMLNS)
|
19
|
+
@types << :route if @doc.at('/xmlns:gpx/xmlns:rte', GPX_XMLNS)
|
20
|
+
@types << :track if @doc.at('/xmlns:gpx/xmlns:trk', GPX_XMLNS)
|
21
|
+
|
15
22
|
stats = @doc.at('/xmlns:gpx/xmlns:trk/xmlns:extensions/gpxtrkx:TrackStatsExtension', GPX_XMLNS)
|
16
23
|
if stats
|
17
24
|
ascent = stats.at('./gpxtrkx:Ascent', GPX_XMLNS).text.to_i
|
@@ -23,7 +30,7 @@ module Natour
|
|
23
30
|
start_point = to_track_point(@doc.at('/xmlns:gpx/xmlns:trk/xmlns:trkseg[1]/xmlns:trkpt[1]', GPX_XMLNS))
|
24
31
|
end_point = to_track_point(@doc.at('/xmlns:gpx/xmlns:trk/xmlns:trkseg[last()]/xmlns:trkpt[last()]', GPX_XMLNS))
|
25
32
|
|
26
|
-
super(filename, start_point
|
33
|
+
super(filename, start_point&.time&.to_date, ascent, descent, distance, duration, start_point, end_point)
|
27
34
|
end
|
28
35
|
|
29
36
|
def to_gpx
|
@@ -33,6 +40,8 @@ module Natour
|
|
33
40
|
private
|
34
41
|
|
35
42
|
def to_track_point(trkpt)
|
43
|
+
return nil unless trkpt
|
44
|
+
|
36
45
|
GPSTrackPoint.new(
|
37
46
|
trkpt['lat'].to_f,
|
38
47
|
trkpt['lon'].to_f,
|
@@ -16,7 +16,7 @@ module Natour
|
|
16
16
|
return unless response.is_a?(Net::HTTPSuccess)
|
17
17
|
|
18
18
|
stations = JSON.parse(response.body, symbolize_names: true)
|
19
|
-
stations.reject! { |station| station[:dist] > radius }
|
19
|
+
stations.reject! { |station| !station.key?(:dist) || station[:dist] > radius }
|
20
20
|
station_types = %w[
|
21
21
|
sl-icon-type-train
|
22
22
|
sl-icon-type-strain
|
data/lib/natour/report.rb
CHANGED
data/lib/natour/species_list.rb
CHANGED
@@ -65,7 +65,7 @@ module Natour
|
|
65
65
|
chunks.map do |rows|
|
66
66
|
name, description = rows.shift
|
67
67
|
date = DateUtils.parse(name, Pathname(filename).basename).compact.first
|
68
|
-
items = rows.map { |row| Species.new(
|
68
|
+
items = rows.map { |row| Species.new(row[1], row[2]) }
|
69
69
|
.sort_by(&:name).uniq
|
70
70
|
SpeciesList.new(
|
71
71
|
filename,
|
@@ -82,7 +82,7 @@ module Natour
|
|
82
82
|
CSV.open(filename, 'r:bom|utf-16le:utf-8', col_sep: "\t", headers: true) do |csv|
|
83
83
|
date = DateUtils.parse(Pathname(filename).basename).compact.first
|
84
84
|
items = csv.select { |row| row[0] }
|
85
|
-
.map { |row| Species.new(
|
85
|
+
.map { |row| Species.new(row[11], nil) }
|
86
86
|
.sort_by(&:name).uniq
|
87
87
|
[SpeciesList.new(filename, date, :info_flora, :plants, nil, nil, items)]
|
88
88
|
end
|
data/lib/natour/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: natour
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Simon Gysi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: asciidoctor
|
@@ -213,6 +213,7 @@ executables:
|
|
213
213
|
extensions: []
|
214
214
|
extra_rdoc_files: []
|
215
215
|
files:
|
216
|
+
- ".natour.yml"
|
216
217
|
- CHANGELOG.adoc
|
217
218
|
- LICENSE
|
218
219
|
- README.adoc
|