pdk 3.0.1 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +37 -1
  3. data/lib/pdk/cli/build.rb +6 -5
  4. data/lib/pdk/cli/bundle.rb +0 -2
  5. data/lib/pdk/cli/console.rb +0 -2
  6. data/lib/pdk/cli/convert.rb +3 -3
  7. data/lib/pdk/cli/env.rb +0 -2
  8. data/lib/pdk/cli/exec/command.rb +0 -2
  9. data/lib/pdk/cli/new/class.rb +0 -2
  10. data/lib/pdk/cli/new/defined_type.rb +0 -2
  11. data/lib/pdk/cli/new/fact.rb +0 -2
  12. data/lib/pdk/cli/new/function.rb +0 -2
  13. data/lib/pdk/cli/new/module.rb +0 -2
  14. data/lib/pdk/cli/new/provider.rb +0 -2
  15. data/lib/pdk/cli/new/task.rb +0 -2
  16. data/lib/pdk/cli/new/test.rb +0 -2
  17. data/lib/pdk/cli/release/prep.rb +0 -2
  18. data/lib/pdk/cli/release/publish.rb +0 -2
  19. data/lib/pdk/cli/release.rb +0 -9
  20. data/lib/pdk/cli/test/unit.rb +0 -2
  21. data/lib/pdk/cli/update.rb +3 -3
  22. data/lib/pdk/cli/util.rb +0 -38
  23. data/lib/pdk/cli/validate.rb +0 -7
  24. data/lib/pdk/cli.rb +0 -2
  25. data/lib/pdk/config/namespace.rb +3 -3
  26. data/lib/pdk/config/setting.rb +3 -3
  27. data/lib/pdk/config.rb +0 -80
  28. data/lib/pdk/module/convert.rb +8 -3
  29. data/lib/pdk/module/metadata.rb +18 -10
  30. data/lib/pdk/module/release.rb +9 -6
  31. data/lib/pdk/module/update_manager.rb +29 -3
  32. data/lib/pdk/report/event.rb +1 -1
  33. data/lib/pdk/template/renderer/v1/legacy_template_dir.rb +10 -13
  34. data/lib/pdk/template/renderer/v1/renderer.rb +3 -1
  35. data/lib/pdk/template.rb +0 -3
  36. data/lib/pdk/tests/unit.rb +3 -3
  37. data/lib/pdk/util/filesystem.rb +10 -0
  38. data/lib/pdk/util.rb +1 -0
  39. data/lib/pdk/version.rb +2 -2
  40. data/lib/pdk.rb +0 -14
  41. metadata +63 -98
  42. data/lib/pdk/analytics/client/google_analytics.rb +0 -141
  43. data/lib/pdk/analytics/client/noop.rb +0 -25
  44. data/lib/pdk/analytics/util.rb +0 -18
  45. data/lib/pdk/analytics.rb +0 -30
  46. data/lib/pdk/config/analytics_schema.json +0 -26
  47. data/lib/pdk/module/build.rb +0 -302
  48. data/lib/pdk/monkey_patches.rb +0 -268
metadata CHANGED
@@ -1,265 +1,237 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 3.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet, Inc.
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-12-20 00:00:00.000000000 Z
11
+ date: 2024-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: ffi
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 2.1.0
19
+ version: 1.15.5
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: 3.0.0
22
+ version: 2.0.0
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 2.1.0
29
+ version: 1.15.5
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: 3.0.0
33
- - !ruby/object:Gem::Dependency
34
- name: childprocess
35
- requirement: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - "~>"
38
- - !ruby/object:Gem::Version
39
- version: 4.1.0
40
- type: :runtime
41
- prerelease: false
42
- version_requirements: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - "~>"
45
- - !ruby/object:Gem::Version
46
- version: 4.1.0
32
+ version: 2.0.0
47
33
  - !ruby/object:Gem::Dependency
48
- name: cri
34
+ name: minitar
49
35
  requirement: !ruby/object:Gem::Requirement
50
36
  requirements:
51
37
  - - "~>"
52
38
  - !ruby/object:Gem::Version
53
- version: 2.15.11
39
+ version: '0.8'
54
40
  type: :runtime
55
41
  prerelease: false
56
42
  version_requirements: !ruby/object:Gem::Requirement
57
43
  requirements:
58
44
  - - "~>"
59
45
  - !ruby/object:Gem::Version
60
- version: 2.15.11
61
- - !ruby/object:Gem::Dependency
62
- name: diff-lcs
63
- requirement: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - ">="
66
- - !ruby/object:Gem::Version
67
- version: 1.5.0
68
- type: :runtime
69
- prerelease: false
70
- version_requirements: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- version: 1.5.0
46
+ version: '0.8'
75
47
  - !ruby/object:Gem::Dependency
76
- name: ffi
48
+ name: bundler
77
49
  requirement: !ruby/object:Gem::Requirement
78
50
  requirements:
79
51
  - - ">="
80
52
  - !ruby/object:Gem::Version
81
- version: 1.15.5
53
+ version: 2.1.0
82
54
  - - "<"
83
55
  - !ruby/object:Gem::Version
84
- version: 2.0.0
56
+ version: 3.0.0
85
57
  type: :runtime
86
58
  prerelease: false
87
59
  version_requirements: !ruby/object:Gem::Requirement
88
60
  requirements:
89
61
  - - ">="
90
62
  - !ruby/object:Gem::Version
91
- version: 1.15.5
63
+ version: 2.1.0
92
64
  - - "<"
93
65
  - !ruby/object:Gem::Version
94
- version: 2.0.0
66
+ version: 3.0.0
95
67
  - !ruby/object:Gem::Dependency
96
- name: hitimes
68
+ name: cri
97
69
  requirement: !ruby/object:Gem::Requirement
98
70
  requirements:
99
- - - '='
71
+ - - "~>"
100
72
  - !ruby/object:Gem::Version
101
- version: 2.0.0
73
+ version: 2.15.11
102
74
  type: :runtime
103
75
  prerelease: false
104
76
  version_requirements: !ruby/object:Gem::Requirement
105
77
  requirements:
106
- - - '='
78
+ - - "~>"
107
79
  - !ruby/object:Gem::Version
108
- version: 2.0.0
80
+ version: 2.15.11
109
81
  - !ruby/object:Gem::Dependency
110
- name: json_pure
82
+ name: childprocess
111
83
  requirement: !ruby/object:Gem::Requirement
112
84
  requirements:
113
85
  - - "~>"
114
86
  - !ruby/object:Gem::Version
115
- version: 2.6.3
87
+ version: '5.0'
116
88
  type: :runtime
117
89
  prerelease: false
118
90
  version_requirements: !ruby/object:Gem::Requirement
119
91
  requirements:
120
92
  - - "~>"
121
93
  - !ruby/object:Gem::Version
122
- version: 2.6.3
94
+ version: '5.0'
123
95
  - !ruby/object:Gem::Dependency
124
- name: json-schema
96
+ name: hitimes
125
97
  requirement: !ruby/object:Gem::Requirement
126
98
  requirements:
127
- - - "~>"
99
+ - - '='
128
100
  - !ruby/object:Gem::Version
129
- version: '4.0'
101
+ version: 2.0.0
130
102
  type: :runtime
131
103
  prerelease: false
132
104
  version_requirements: !ruby/object:Gem::Requirement
133
105
  requirements:
134
- - - "~>"
106
+ - - '='
135
107
  - !ruby/object:Gem::Version
136
- version: '4.0'
108
+ version: 2.0.0
137
109
  - !ruby/object:Gem::Dependency
138
- name: minitar
110
+ name: tty-prompt
139
111
  requirement: !ruby/object:Gem::Requirement
140
112
  requirements:
141
113
  - - "~>"
142
114
  - !ruby/object:Gem::Version
143
- version: '0.8'
115
+ version: '0.23'
144
116
  type: :runtime
145
117
  prerelease: false
146
118
  version_requirements: !ruby/object:Gem::Requirement
147
119
  requirements:
148
120
  - - "~>"
149
121
  - !ruby/object:Gem::Version
150
- version: '0.8'
122
+ version: '0.23'
151
123
  - !ruby/object:Gem::Dependency
152
- name: pathspec
124
+ name: tty-spinner
153
125
  requirement: !ruby/object:Gem::Requirement
154
126
  requirements:
155
127
  - - "~>"
156
128
  - !ruby/object:Gem::Version
157
- version: '1.1'
129
+ version: '0.9'
158
130
  type: :runtime
159
131
  prerelease: false
160
132
  version_requirements: !ruby/object:Gem::Requirement
161
133
  requirements:
162
134
  - - "~>"
163
135
  - !ruby/object:Gem::Version
164
- version: '1.1'
136
+ version: '0.9'
165
137
  - !ruby/object:Gem::Dependency
166
- name: tty-prompt
138
+ name: tty-which
167
139
  requirement: !ruby/object:Gem::Requirement
168
140
  requirements:
169
141
  - - "~>"
170
142
  - !ruby/object:Gem::Version
171
- version: '0.23'
143
+ version: '0.5'
172
144
  type: :runtime
173
145
  prerelease: false
174
146
  version_requirements: !ruby/object:Gem::Requirement
175
147
  requirements:
176
148
  - - "~>"
177
149
  - !ruby/object:Gem::Version
178
- version: '0.23'
150
+ version: '0.5'
179
151
  - !ruby/object:Gem::Dependency
180
- name: tty-spinner
152
+ name: json-schema
181
153
  requirement: !ruby/object:Gem::Requirement
182
154
  requirements:
183
155
  - - "~>"
184
156
  - !ruby/object:Gem::Version
185
- version: '0.9'
157
+ version: '4.0'
186
158
  type: :runtime
187
159
  prerelease: false
188
160
  version_requirements: !ruby/object:Gem::Requirement
189
161
  requirements:
190
162
  - - "~>"
191
163
  - !ruby/object:Gem::Version
192
- version: '0.9'
164
+ version: '4.0'
193
165
  - !ruby/object:Gem::Dependency
194
- name: tty-which
166
+ name: puppet-modulebuilder
195
167
  requirement: !ruby/object:Gem::Requirement
196
168
  requirements:
197
169
  - - "~>"
198
170
  - !ruby/object:Gem::Version
199
- version: '0.5'
171
+ version: '1.0'
200
172
  type: :runtime
201
173
  prerelease: false
202
174
  version_requirements: !ruby/object:Gem::Requirement
203
175
  requirements:
204
176
  - - "~>"
205
177
  - !ruby/object:Gem::Version
206
- version: '0.5'
178
+ version: '1.0'
207
179
  - !ruby/object:Gem::Dependency
208
- name: concurrent-ruby
180
+ name: deep_merge
209
181
  requirement: !ruby/object:Gem::Requirement
210
182
  requirements:
211
- - - '='
183
+ - - "~>"
212
184
  - !ruby/object:Gem::Version
213
- version: 1.1.10
185
+ version: 1.2.2
214
186
  type: :runtime
215
187
  prerelease: false
216
188
  version_requirements: !ruby/object:Gem::Requirement
217
189
  requirements:
218
- - - '='
190
+ - - "~>"
219
191
  - !ruby/object:Gem::Version
220
- version: 1.1.10
192
+ version: 1.2.2
221
193
  - !ruby/object:Gem::Dependency
222
- name: facter
194
+ name: diff-lcs
223
195
  requirement: !ruby/object:Gem::Requirement
224
196
  requirements:
225
- - - "~>"
197
+ - - ">="
226
198
  - !ruby/object:Gem::Version
227
- version: '4.0'
199
+ version: 1.5.0
228
200
  type: :runtime
229
201
  prerelease: false
230
202
  version_requirements: !ruby/object:Gem::Requirement
231
203
  requirements:
232
- - - "~>"
204
+ - - ">="
233
205
  - !ruby/object:Gem::Version
234
- version: '4.0'
206
+ version: 1.5.0
235
207
  - !ruby/object:Gem::Dependency
236
- name: httpclient
208
+ name: json_pure
237
209
  requirement: !ruby/object:Gem::Requirement
238
210
  requirements:
239
211
  - - "~>"
240
212
  - !ruby/object:Gem::Version
241
- version: 2.8.3
213
+ version: 2.6.3
242
214
  type: :runtime
243
215
  prerelease: false
244
216
  version_requirements: !ruby/object:Gem::Requirement
245
217
  requirements:
246
218
  - - "~>"
247
219
  - !ruby/object:Gem::Version
248
- version: 2.8.3
220
+ version: 2.6.3
249
221
  - !ruby/object:Gem::Dependency
250
- name: deep_merge
222
+ name: pathspec
251
223
  requirement: !ruby/object:Gem::Requirement
252
224
  requirements:
253
225
  - - "~>"
254
226
  - !ruby/object:Gem::Version
255
- version: 1.2.2
227
+ version: '1.1'
256
228
  type: :runtime
257
229
  prerelease: false
258
230
  version_requirements: !ruby/object:Gem::Requirement
259
231
  requirements:
260
232
  - - "~>"
261
233
  - !ruby/object:Gem::Version
262
- version: 1.2.2
234
+ version: '1.1'
263
235
  description: A CLI to facilitate easy, unified development workflows for Puppet modules.
264
236
  email:
265
237
  - pdk-maintainers@puppet.com
@@ -273,10 +245,6 @@ files:
273
245
  - README.md
274
246
  - exe/pdk
275
247
  - lib/pdk.rb
276
- - lib/pdk/analytics.rb
277
- - lib/pdk/analytics/client/google_analytics.rb
278
- - lib/pdk/analytics/client/noop.rb
279
- - lib/pdk/analytics/util.rb
280
248
  - lib/pdk/answer_file.rb
281
249
  - lib/pdk/bolt.rb
282
250
  - lib/pdk/cli.rb
@@ -321,7 +289,6 @@ files:
321
289
  - lib/pdk/cli/util/update_manager_printer.rb
322
290
  - lib/pdk/cli/validate.rb
323
291
  - lib/pdk/config.rb
324
- - lib/pdk/config/analytics_schema.json
325
292
  - lib/pdk/config/errors.rb
326
293
  - lib/pdk/config/ini_file.rb
327
294
  - lib/pdk/config/ini_file_setting.rb
@@ -352,13 +319,11 @@ files:
352
319
  - lib/pdk/generate/transport.rb
353
320
  - lib/pdk/logger.rb
354
321
  - lib/pdk/module.rb
355
- - lib/pdk/module/build.rb
356
322
  - lib/pdk/module/convert.rb
357
323
  - lib/pdk/module/metadata.rb
358
324
  - lib/pdk/module/release.rb
359
325
  - lib/pdk/module/update.rb
360
326
  - lib/pdk/module/update_manager.rb
361
- - lib/pdk/monkey_patches.rb
362
327
  - lib/pdk/report.rb
363
328
  - lib/pdk/report/event.rb
364
329
  - lib/pdk/template.rb
@@ -418,7 +383,7 @@ homepage: https://github.com/puppetlabs/pdk
418
383
  licenses: []
419
384
  metadata:
420
385
  rubygems_mfa_required: 'true'
421
- post_install_message:
386
+ post_install_message:
422
387
  rdoc_options: []
423
388
  require_paths:
424
389
  - lib
@@ -433,8 +398,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
433
398
  - !ruby/object:Gem::Version
434
399
  version: '0'
435
400
  requirements: []
436
- rubygems_version: 3.1.6
437
- signing_key:
401
+ rubygems_version: 3.5.17
402
+ signing_key:
438
403
  specification_version: 4
439
404
  summary: A key part of the Puppet Development Kit, the shortest path to better modules
440
405
  test_files: []
@@ -1,141 +0,0 @@
1
- require 'pdk'
2
-
3
- module PDK
4
- module Analytics
5
- module Client
6
- class GoogleAnalytics
7
- PROTOCOL_VERSION = 1
8
- TRACKING_URL = 'https://google-analytics.com/collect'.freeze
9
- CUSTOM_DIMENSIONS = {
10
- operating_system: :cd1,
11
- output_format: :cd2,
12
- ruby_version: :cd3,
13
- cli_options: :cd4,
14
- env_vars: :cd5
15
- }.freeze
16
-
17
- attr_reader :user_id, :logger, :app_name, :app_id, :app_version, :app_installer
18
-
19
- def initialize(opts)
20
- # lazy-load expensive gem code
21
- require 'concurrent/configuration'
22
- require 'concurrent/future'
23
- require 'httpclient'
24
- require 'locale'
25
- require 'pdk/analytics/util'
26
-
27
- @http = HTTPClient.new
28
- @user_id = opts[:user_id]
29
- @executor = Concurrent.global_io_executor
30
- @os = PDK::Analytics::Util.fetch_os_async
31
- @logger = opts[:logger]
32
- @app_name = opts[:app_name]
33
- @app_id = opts[:app_id]
34
- @app_version = opts[:app_version]
35
- @app_installer = opts[:app_installer]
36
- end
37
-
38
- def screen_view(screen, **kwargs)
39
- custom_dimensions = walk_keys(kwargs) do |k|
40
- CUSTOM_DIMENSIONS[k] || raise(format("Unknown analytics key '%{key}'", key: k))
41
- end
42
-
43
- screen_view_params = {
44
- # Type
45
- t: 'screenview',
46
- # Screen Name
47
- cd: screen
48
- }.merge(custom_dimensions)
49
-
50
- submit(base_params.merge(screen_view_params))
51
- end
52
-
53
- def event(category, action, label: nil, value: nil, **kwargs)
54
- custom_dimensions = walk_keys(kwargs) do |k|
55
- CUSTOM_DIMENSIONS[k] || raise(format("Unknown analytics key '%{key}'", key: k))
56
- end
57
-
58
- event_params = {
59
- # Type
60
- t: 'event',
61
- # Event Category
62
- ec: category,
63
- # Event Action
64
- ea: action
65
- }.merge(custom_dimensions)
66
-
67
- # Event Label
68
- event_params[:el] = label if label
69
- # Event Value
70
- event_params[:ev] = value if value
71
-
72
- submit(base_params.merge(event_params))
73
- end
74
-
75
- def submit(params)
76
- # Handle analytics submission in the background to avoid blocking the
77
- # app or polluting the log with errors
78
- Concurrent::Future.execute(executor: @executor) do
79
- require 'json'
80
-
81
- logger.debug "Submitting analytics: #{JSON.pretty_generate(params)}"
82
- @http.post(TRACKING_URL, params)
83
- logger.debug 'Completed analytics submission'
84
- end
85
- end
86
-
87
- # These parameters have terrible names. See this page for complete documentation:
88
- # https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters
89
- def base_params
90
- require 'locale'
91
-
92
- {
93
- v: PROTOCOL_VERSION,
94
- # Client ID
95
- cid: user_id,
96
- # Tracking ID
97
- tid: app_id,
98
- # Application Name
99
- an: app_name,
100
- # Application Version
101
- av: app_version,
102
- # Application Installer ID
103
- aiid: app_installer,
104
- # Anonymize IPs
105
- aip: true,
106
- # User locale
107
- ul: Locale.current.to_rfc,
108
- # Custom Dimension 1 (Operating System)
109
- cd1: @os.value
110
- }
111
- end
112
-
113
- # If the user is running a very fast command, there may not be time for
114
- # analytics submission to complete before the command is finished. In
115
- # that case, we give a little buffer for any stragglers to finish up.
116
- # 250ms strikes a balance between accomodating slower networks while not
117
- # introducing a noticeable "hang".
118
- def finish
119
- @executor.shutdown
120
- @executor.wait_for_termination(0.25)
121
- end
122
-
123
- private
124
-
125
- def walk_keys(data, &block)
126
- case data
127
- when Hash
128
- data.each_with_object({}) do |(k, v), acc|
129
- v = walk_keys(v, &block)
130
- acc[yield(k)] = v
131
- end
132
- when Array
133
- data.map { |v| walk_keys(v, &block) }
134
- else
135
- data
136
- end
137
- end
138
- end
139
- end
140
- end
141
- end
@@ -1,25 +0,0 @@
1
- require 'pdk'
2
-
3
- module PDK
4
- module Analytics
5
- module Client
6
- class Noop
7
- attr_reader :logger
8
-
9
- def initialize(opts)
10
- @logger = opts[:logger]
11
- end
12
-
13
- def screen_view(screen, **_kwargs)
14
- logger.debug "Skipping submission of '#{screen}' screenview because analytics is disabled"
15
- end
16
-
17
- def event(category, action, **_kwargs)
18
- logger.debug "Skipping submission of '#{category} #{action}' event because analytics is disabled"
19
- end
20
-
21
- def finish; end
22
- end
23
- end
24
- end
25
- end
@@ -1,18 +0,0 @@
1
- require 'pdk'
2
-
3
- module PDK
4
- module Analytics
5
- module Util
6
- def self.fetch_os_async
7
- require 'concurrent/configuration'
8
- require 'concurrent/future'
9
-
10
- Concurrent::Future.execute(executor: :io) do
11
- os = Facter.value('os')
12
-
13
- os.nil? ? 'unknown' : "#{os['name']} #{os.fetch('release', {}).fetch('major', '')}".strip
14
- end
15
- end
16
- end
17
- end
18
- end
data/lib/pdk/analytics.rb DELETED
@@ -1,30 +0,0 @@
1
- require 'pdk'
2
-
3
- autoload :Logger, 'logger'
4
-
5
- module PDK
6
- module Analytics
7
- autoload :Util, 'pdk/analytics/util'
8
-
9
- module Client
10
- autoload :Noop, 'pdk/analytics/client/noop'
11
- autoload :GoogleAnalytics, 'pdk/analytics/client/google_analytics'
12
- end
13
-
14
- def self.build_client(opts = {})
15
- opts[:logger] ||= ::Logger.new($stderr)
16
- opts[:client] ||= :noop
17
-
18
- if opts[:disabled]
19
- opts[:logger].debug 'Analytics opt-out is set, analytics will be disabled'
20
- opts[:client] = :noop
21
- end
22
-
23
- client_const = opts[:client].to_s.split('_').map(&:capitalize).join
24
- PDK::Analytics::Client.const_get(client_const).new(opts)
25
- rescue StandardError => e
26
- opts[:logger].debug "Failed to initialize analytics client, analytics will be disabled: #{e}"
27
- PDK::Analytics::Client::Noop.new(opts)
28
- end
29
- end
30
- end
@@ -1,26 +0,0 @@
1
- {
2
- "definitions": {},
3
- "$schema": "http://json-schema.org/draft-06/schema#",
4
- "$id": "http://puppet.com/schema/does_not_exist.json",
5
- "type": "object",
6
- "title": "The PDK Analytics YAML Schema",
7
- "properties": {
8
- "disabled": {
9
- "$id": "#/properties/disabled",
10
- "type": "boolean",
11
- "title": "Disabled property",
12
- "examples": [
13
- false
14
- ]
15
- },
16
- "user-id": {
17
- "$id": "#/properties/user-id",
18
- "type": "string",
19
- "title": "The User-id for analytics",
20
- "examples": [
21
- "cb9ed65f-37dc-48d8-9863-8bd09cbb61c7"
22
- ],
23
- "pattern": "^[0-9a-fA-F]{8}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{4}\\-[0-9a-fA-F]{12}$"
24
- }
25
- }
26
- }