metanorma-plugin-lutaml 0.7.43 → 0.7.45
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.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +14 -93
- data/bin/console +1 -1
- data/lib/metanorma/plugin/lutaml/asciidoctor.rb +12 -0
- data/lib/metanorma/plugin/lutaml/base_preprocessor.rb +1 -3
- data/lib/metanorma/plugin/lutaml/base_structured_text_preprocessor.rb +0 -3
- data/lib/metanorma/plugin/lutaml/cache_store.rb +51 -0
- data/lib/metanorma/plugin/lutaml/config/package.rb +8 -0
- data/lib/metanorma/plugin/lutaml/config.rb +6 -5
- data/lib/metanorma/plugin/lutaml/content.rb +0 -2
- data/lib/metanorma/plugin/lutaml/data2_text_preprocessor.rb +0 -3
- data/lib/metanorma/plugin/lutaml/express_remarks_decorator.rb +1 -7
- data/lib/metanorma/plugin/lutaml/json2_text_preprocessor.rb +0 -3
- data/lib/metanorma/plugin/lutaml/liquid/custom_blocks.rb +14 -0
- data/lib/metanorma/plugin/lutaml/liquid/custom_filters/loadfile.rb +1 -1
- data/lib/metanorma/plugin/lutaml/liquid/custom_filters.rb +18 -0
- data/lib/metanorma/plugin/lutaml/liquid.rb +14 -0
- data/lib/metanorma/plugin/lutaml/lutaml_diagram_base.rb +1 -2
- data/lib/metanorma/plugin/lutaml/lutaml_diagram_block.rb +0 -2
- data/lib/metanorma/plugin/lutaml/lutaml_diagram_block_macro.rb +0 -2
- data/lib/metanorma/plugin/lutaml/lutaml_ea_diagram_block_macro.rb +0 -2
- data/lib/metanorma/plugin/lutaml/lutaml_ea_xmi_base.rb +5 -417
- data/lib/metanorma/plugin/lutaml/lutaml_ea_xmi_preprocessor.rb +0 -3
- data/lib/metanorma/plugin/lutaml/lutaml_gml_dictionary_base.rb +0 -2
- data/lib/metanorma/plugin/lutaml/lutaml_preprocessor.rb +27 -29
- data/lib/metanorma/plugin/lutaml/lutaml_uml_datamodel_description_preprocessor.rb +0 -3
- data/lib/metanorma/plugin/lutaml/lutaml_xmi_uml_preprocessor.rb +0 -3
- data/lib/metanorma/plugin/lutaml/lutaml_xsd_preprocessor.rb +7 -7
- data/lib/metanorma/plugin/lutaml/source_extractor.rb +0 -4
- data/lib/metanorma/plugin/lutaml/utils.rb +6 -10
- data/lib/metanorma/plugin/lutaml/version.rb +1 -1
- data/lib/metanorma/plugin/lutaml/xmi_cache.rb +148 -0
- data/lib/metanorma/plugin/lutaml/xmi_config.rb +34 -0
- data/lib/metanorma/plugin/lutaml/xmi_context_builder.rb +100 -0
- data/lib/metanorma/plugin/lutaml/xmi_package_filter.rb +71 -0
- data/lib/metanorma/plugin/lutaml/xmi_renderer.rb +100 -0
- data/lib/metanorma/plugin/lutaml/yaml2_text_preprocessor.rb +0 -3
- data/lib/metanorma/plugin/lutaml.rb +14 -0
- data/lib/metanorma-plugin-lutaml.rb +62 -21
- data/metanorma-plugin-lutaml.gemspec +1 -1
- metadata +13 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ecadace3879b75e1ec4f08f435da722a2151c32a419fed84476646f2dc7314f6
|
|
4
|
+
data.tar.gz: bc0e618b7252c140a1b9acc404194f2fdfa30e65c8b4ae8823c6bc19222a4a8a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8d621151fd02cf3582d75366b8fc943f51286357d95584863c3158b7911b082dfaa877919505ba3483219d5c08eeae1ad449fe9862f0aa63b3507f08764f9a3a
|
|
7
|
+
data.tar.gz: 54823d6d7ae810e8791dc27d3dec120a44eb224fadce8ccedbd4884d4d8a28c54127bb1e8bf6b2c54e0c740085c52c5968d1e8181964902371cee15f329b990e
|
data/.rubocop_todo.yml
CHANGED
|
@@ -1,85 +1,40 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config`
|
|
3
|
-
# on 2026-05-
|
|
3
|
+
# on 2026-05-15 01:32:12 UTC using RuboCop version 1.86.1.
|
|
4
4
|
# The point is for the user to remove these configuration records
|
|
5
5
|
# one by one as the offenses are removed from the code base.
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
|
8
8
|
|
|
9
|
-
# Offense count:
|
|
10
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
11
|
-
Gemspec/RequireMFA:
|
|
12
|
-
Exclude:
|
|
13
|
-
- 'metanorma-plugin-lutaml.gemspec'
|
|
14
|
-
|
|
15
|
-
# Offense count: 4
|
|
16
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
17
|
-
# Configuration parameters: EnforcedStyle, IndentationWidth.
|
|
18
|
-
# SupportedStyles: with_first_argument, with_fixed_indentation
|
|
19
|
-
Layout/ArgumentAlignment:
|
|
20
|
-
Exclude:
|
|
21
|
-
- 'spec/regen_expected.rb'
|
|
22
|
-
- 'spec/regen_expected_spec.rb'
|
|
23
|
-
|
|
24
|
-
# Offense count: 1
|
|
25
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
26
|
-
# Configuration parameters: IndentationWidth.
|
|
27
|
-
Layout/AssignmentIndentation:
|
|
28
|
-
Exclude:
|
|
29
|
-
- 'lib/metanorma/plugin/lutaml/base_preprocessor.rb'
|
|
30
|
-
|
|
31
|
-
# Offense count: 2
|
|
32
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
33
|
-
Layout/EmptyLines:
|
|
34
|
-
Exclude:
|
|
35
|
-
- 'spec/regen_expected.rb'
|
|
36
|
-
|
|
37
|
-
# Offense count: 12
|
|
9
|
+
# Offense count: 14
|
|
38
10
|
# This cop supports safe autocorrection (--autocorrect).
|
|
39
11
|
# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
|
|
40
12
|
# URISchemes: http, https
|
|
41
13
|
Layout/LineLength:
|
|
42
14
|
Exclude:
|
|
43
15
|
- 'Rakefile'
|
|
44
|
-
- 'lib/metanorma/plugin/lutaml/base_preprocessor.rb'
|
|
45
|
-
- 'lib/metanorma/plugin/lutaml/lutaml_ea_xmi_base.rb'
|
|
46
16
|
- 'lib/metanorma/plugin/lutaml/utils.rb'
|
|
17
|
+
- 'spec/metanorma/plugin/lutaml/express_remarks_decorator_spec.rb'
|
|
18
|
+
- 'spec/metanorma/plugin/lutaml/lutaml_text_preprocessor_spec.rb'
|
|
47
19
|
- 'spec/metanorma/plugin/lutaml/lutaml_uml_datamodel_description_preprocessor_spec.rb'
|
|
48
20
|
- 'spec/metanorma/plugin/lutaml/lutaml_xsd_preprocessor_spec.rb'
|
|
49
|
-
- 'spec/
|
|
50
|
-
- 'spec/
|
|
21
|
+
- 'spec/metanorma/plugin/lutaml/macros_data2text_spec.rb'
|
|
22
|
+
- 'spec/metanorma/plugin/lutaml/macros_json2text_spec.rb'
|
|
23
|
+
- 'spec/metanorma/plugin/lutaml/macros_yaml2text_spec.rb'
|
|
24
|
+
- 'spec/metanorma/plugin/lutaml/source_extractor_spec.rb'
|
|
51
25
|
- 'spec/support/shared_examples/structured_data_2_text_preprocessor.rb'
|
|
52
26
|
|
|
53
|
-
# Offense count:
|
|
54
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
55
|
-
# Configuration parameters: EnforcedStyle.
|
|
56
|
-
# SupportedStyles: final_newline, final_blank_line
|
|
57
|
-
Layout/TrailingEmptyLines:
|
|
58
|
-
Exclude:
|
|
59
|
-
- 'Gemfile'
|
|
60
|
-
- 'spec/regen_expected.rb'
|
|
61
|
-
|
|
62
|
-
# Offense count: 5
|
|
63
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
64
|
-
# Configuration parameters: AllowInHeredoc.
|
|
65
|
-
Layout/TrailingWhitespace:
|
|
66
|
-
Exclude:
|
|
67
|
-
- 'lib/metanorma/plugin/lutaml/base_preprocessor.rb'
|
|
68
|
-
- 'spec/regen_expected.rb'
|
|
69
|
-
- 'spec/regen_expected_spec.rb'
|
|
70
|
-
|
|
71
|
-
# Offense count: 2
|
|
27
|
+
# Offense count: 3
|
|
72
28
|
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
|
|
73
29
|
Metrics/AbcSize:
|
|
74
30
|
Exclude:
|
|
75
31
|
- 'lib/metanorma/plugin/lutaml/lutaml_xsd_preprocessor.rb'
|
|
76
32
|
- 'lib/metanorma/plugin/lutaml/utils.rb'
|
|
77
33
|
|
|
78
|
-
# Offense count:
|
|
34
|
+
# Offense count: 1
|
|
79
35
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
80
36
|
Metrics/CyclomaticComplexity:
|
|
81
37
|
Exclude:
|
|
82
|
-
- 'lib/metanorma/plugin/lutaml/lutaml_ea_xmi_base.rb'
|
|
83
38
|
- 'lib/metanorma/plugin/lutaml/utils.rb'
|
|
84
39
|
|
|
85
40
|
# Offense count: 7
|
|
@@ -87,11 +42,10 @@ Metrics/CyclomaticComplexity:
|
|
|
87
42
|
Metrics/MethodLength:
|
|
88
43
|
Max: 19
|
|
89
44
|
|
|
90
|
-
# Offense count:
|
|
45
|
+
# Offense count: 1
|
|
91
46
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
92
47
|
Metrics/PerceivedComplexity:
|
|
93
48
|
Exclude:
|
|
94
|
-
- 'lib/metanorma/plugin/lutaml/lutaml_ea_xmi_base.rb'
|
|
95
49
|
- 'lib/metanorma/plugin/lutaml/utils.rb'
|
|
96
50
|
|
|
97
51
|
# Offense count: 1
|
|
@@ -127,16 +81,10 @@ RSpec/ContextWording:
|
|
|
127
81
|
- 'spec/metanorma/plugin/lutaml/macros_data2text_spec.rb'
|
|
128
82
|
- 'spec/support/shared_examples/structured_data_2_text_preprocessor.rb'
|
|
129
83
|
|
|
130
|
-
# Offense count:
|
|
131
|
-
# Configuration parameters: IgnoredMetadata.
|
|
132
|
-
RSpec/DescribeClass:
|
|
133
|
-
Exclude:
|
|
134
|
-
- 'spec/regen_expected_spec.rb'
|
|
135
|
-
|
|
136
|
-
# Offense count: 40
|
|
84
|
+
# Offense count: 44
|
|
137
85
|
# Configuration parameters: CountAsOne.
|
|
138
86
|
RSpec/ExampleLength:
|
|
139
|
-
Max:
|
|
87
|
+
Max: 26
|
|
140
88
|
|
|
141
89
|
# Offense count: 13
|
|
142
90
|
# Configuration parameters: Max, AllowedIdentifiers, AllowedPatterns.
|
|
@@ -161,7 +109,7 @@ RSpec/LeakyLocalVariable:
|
|
|
161
109
|
- 'spec/metanorma/plugin/lutaml/lutaml_uml_datamodel_description_preprocessor_spec.rb'
|
|
162
110
|
- 'spec/metanorma/plugin/lutaml/lutaml_xmi_index_spec.rb'
|
|
163
111
|
|
|
164
|
-
# Offense count:
|
|
112
|
+
# Offense count: 21
|
|
165
113
|
RSpec/MultipleExpectations:
|
|
166
114
|
Max: 6
|
|
167
115
|
|
|
@@ -188,17 +136,6 @@ RSpec/NamedSubject:
|
|
|
188
136
|
RSpec/NestedGroups:
|
|
189
137
|
Max: 7
|
|
190
138
|
|
|
191
|
-
# Offense count: 3
|
|
192
|
-
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
193
|
-
RSpec/Output:
|
|
194
|
-
Exclude:
|
|
195
|
-
- 'spec/regen_expected.rb'
|
|
196
|
-
|
|
197
|
-
# Offense count: 1
|
|
198
|
-
RSpec/PendingWithoutReason:
|
|
199
|
-
Exclude:
|
|
200
|
-
- 'spec/metanorma/plugin/lutaml/lutaml_text_preprocessor_spec.rb'
|
|
201
|
-
|
|
202
139
|
# Offense count: 2
|
|
203
140
|
RSpec/RepeatedExampleGroupBody:
|
|
204
141
|
Exclude:
|
|
@@ -220,19 +157,3 @@ RSpec/SpecFilePathFormat:
|
|
|
220
157
|
RSpec/SubjectDeclaration:
|
|
221
158
|
Exclude:
|
|
222
159
|
- 'spec/metanorma/plugin/lutaml/config/root_spec.rb'
|
|
223
|
-
|
|
224
|
-
# Offense count: 1
|
|
225
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
226
|
-
# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
|
|
227
|
-
# SupportedStyles: single_quotes, double_quotes
|
|
228
|
-
Style/StringLiterals:
|
|
229
|
-
Exclude:
|
|
230
|
-
- 'metanorma-plugin-lutaml.gemspec'
|
|
231
|
-
|
|
232
|
-
# Offense count: 1
|
|
233
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
234
|
-
# Configuration parameters: EnforcedStyle.
|
|
235
|
-
# SupportedStyles: single_quotes, double_quotes
|
|
236
|
-
Style/StringLiteralsInInterpolation:
|
|
237
|
-
Exclude:
|
|
238
|
-
- 'spec/metanorma/plugin/lutaml/lutaml_xsd_preprocessor_spec.rb'
|
data/bin/console
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
3
|
require "bundler/setup"
|
|
4
|
-
|
|
4
|
+
require_relative "../lib/metanorma-plugin-lutaml"
|
|
5
5
|
|
|
6
6
|
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
7
|
# with your gem easier. You can also use a different console, if you like.
|
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
require "liquid"
|
|
4
4
|
require "asciidoctor"
|
|
5
5
|
require "asciidoctor/reader"
|
|
6
|
-
require "metanorma/plugin/lutaml/utils"
|
|
7
|
-
require "metanorma/plugin/lutaml/asciidoctor/preprocessor"
|
|
8
6
|
|
|
9
7
|
module Metanorma
|
|
10
8
|
module Plugin
|
|
@@ -173,7 +171,7 @@ module Metanorma
|
|
|
173
171
|
)
|
|
174
172
|
parsed_template.assigns["schemas_order"] =
|
|
175
173
|
options["selected_schemas"]
|
|
176
|
-
parsed_template.render
|
|
174
|
+
parsed_template.render.split("\n", -1)
|
|
177
175
|
end.flatten
|
|
178
176
|
rescue StandardError => e
|
|
179
177
|
::Metanorma::Util.log(
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Metanorma
|
|
4
|
+
module Plugin
|
|
5
|
+
module Lutaml
|
|
6
|
+
class CacheStore
|
|
7
|
+
def initialize(max_size: 50)
|
|
8
|
+
@store = {}
|
|
9
|
+
@max_size = max_size
|
|
10
|
+
@mutex = Mutex.new
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def fetch(key)
|
|
14
|
+
@mutex.synchronize { @store[key] }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def store(key, value)
|
|
18
|
+
@mutex.synchronize do
|
|
19
|
+
evict! if @store.size >= @max_size
|
|
20
|
+
@store[key] = value
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def fetch_or_store(key)
|
|
25
|
+
@mutex.synchronize do
|
|
26
|
+
if @store.key?(key)
|
|
27
|
+
@store[key]
|
|
28
|
+
else
|
|
29
|
+
evict! if @store.size >= @max_size
|
|
30
|
+
@store[key] = yield
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def clear
|
|
36
|
+
@mutex.synchronize { @store.clear }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def size
|
|
40
|
+
@mutex.synchronize { @store.size }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def evict!
|
|
46
|
+
@store.shift
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -14,6 +14,14 @@ module Metanorma
|
|
|
14
14
|
map "skip_tables", to: :skip_tables
|
|
15
15
|
map "render_entities", to: :render_entities
|
|
16
16
|
end
|
|
17
|
+
|
|
18
|
+
def collection_for(key)
|
|
19
|
+
case key
|
|
20
|
+
when "render_entities" then render_entities
|
|
21
|
+
when "skip_tables" then skip_tables
|
|
22
|
+
else raise ArgumentError, "Unknown collection key: #{key}"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
17
25
|
end
|
|
18
26
|
end
|
|
19
27
|
end
|
|
@@ -3,16 +3,17 @@
|
|
|
3
3
|
require "yaml"
|
|
4
4
|
require "lutaml"
|
|
5
5
|
require "lutaml/model"
|
|
6
|
-
require_relative "config/package"
|
|
7
|
-
require_relative "config/root"
|
|
8
|
-
require_relative "config/guidance_attribute"
|
|
9
|
-
require_relative "config/guidance_klass"
|
|
10
|
-
require_relative "config/guidance"
|
|
11
6
|
|
|
12
7
|
module Metanorma
|
|
13
8
|
module Plugin
|
|
14
9
|
module Lutaml
|
|
15
10
|
module Config
|
|
11
|
+
autoload :Guidance, "metanorma/plugin/lutaml/config/guidance"
|
|
12
|
+
autoload :GuidanceAttribute,
|
|
13
|
+
"metanorma/plugin/lutaml/config/guidance_attribute"
|
|
14
|
+
autoload :GuidanceKlass, "metanorma/plugin/lutaml/config/guidance_klass"
|
|
15
|
+
autoload :Package, "metanorma/plugin/lutaml/config/package"
|
|
16
|
+
autoload :Root, "metanorma/plugin/lutaml/config/root"
|
|
16
17
|
end
|
|
17
18
|
end
|
|
18
19
|
end
|
|
@@ -55,13 +55,7 @@ module Metanorma
|
|
|
55
55
|
|
|
56
56
|
def prefix_relative_paths(line, path_prefix)
|
|
57
57
|
line.gsub(RELATIVE_PREFIX_MACRO_REGEXP) do |_match|
|
|
58
|
-
|
|
59
|
-
# Transform relative path (../path/to/file) into the absolute path
|
|
60
|
-
# because `image::` macro wont understand it other way
|
|
61
|
-
if prefixed_path.start_with?("../")
|
|
62
|
-
prefixed_path = File.absolute_path(prefixed_path)
|
|
63
|
-
end
|
|
64
|
-
full_path = File.expand_path(prefixed_path)
|
|
58
|
+
full_path = File.expand_path(File.join(path_prefix, $3.strip))
|
|
65
59
|
"#{$1}#{$2}#{full_path}#{$4}"
|
|
66
60
|
end
|
|
67
61
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Metanorma
|
|
4
|
+
module Plugin
|
|
5
|
+
module Lutaml
|
|
6
|
+
module Liquid
|
|
7
|
+
module CustomFilters
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
require_relative "custom_filters/html2adoc"
|
|
15
|
+
require_relative "custom_filters/values"
|
|
16
|
+
require_relative "custom_filters/replace_regex"
|
|
17
|
+
require_relative "custom_filters/loadfile"
|
|
18
|
+
require_relative "custom_filters/file_exist"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Metanorma
|
|
4
|
+
module Plugin
|
|
5
|
+
module Lutaml
|
|
6
|
+
module Liquid
|
|
7
|
+
autoload :CustomBlocks, "metanorma/plugin/lutaml/liquid/custom_blocks"
|
|
8
|
+
autoload :CustomFilters, "metanorma/plugin/lutaml/liquid/custom_filters"
|
|
9
|
+
autoload :LocalFileSystem,
|
|
10
|
+
"metanorma/plugin/lutaml/liquid/multiply_local_file_system"
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -6,7 +6,6 @@ require "asciidoctor/reader"
|
|
|
6
6
|
require "lutaml"
|
|
7
7
|
require "lutaml/uml"
|
|
8
8
|
require "lutaml/formatter"
|
|
9
|
-
require "metanorma/plugin/lutaml/utils"
|
|
10
9
|
|
|
11
10
|
module Metanorma
|
|
12
11
|
module Plugin
|
|
@@ -33,7 +32,7 @@ module Metanorma
|
|
|
33
32
|
def abort(parent, reader, attrs, msg)
|
|
34
33
|
warn(msg)
|
|
35
34
|
attrs["language"] = "lutaml"
|
|
36
|
-
source = reader.
|
|
35
|
+
source = reader.is_a?(::Asciidoctor::Reader) ? reader.source : reader
|
|
37
36
|
create_listing_block(
|
|
38
37
|
parent,
|
|
39
38
|
source,
|