openbeautyfacts 0.10.0 → 0.11.0
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/lib/openbeautyfacts/version.rb +1 -1
- metadata +1 -33
- data/test/fixtures/additives.yml +0 -48
- data/test/fixtures/brands.yml +0 -48
- data/test/fixtures/entry_dates.yml +0 -48
- data/test/fixtures/entry_dates_locale.yml +0 -48
- data/test/fixtures/faq.yml +0 -48
- data/test/fixtures/fetch_product_3600550362626.yml +0 -54
- data/test/fixtures/index.yml +0 -48
- data/test/fixtures/ingredients.yml +0 -99
- data/test/fixtures/ingredients_locale.yml +0 -99
- data/test/fixtures/last_edit_dates.yml +0 -48
- data/test/fixtures/last_edit_dates_locale.yml +0 -48
- data/test/fixtures/login_user.yml +0 -363
- data/test/fixtures/mission.yml +0 -48
- data/test/fixtures/missions.yml +0 -48
- data/test/fixtures/number_of_ingredients_locale.yml +0 -48
- data/test/fixtures/numbers_of_ingredients.yml +0 -48
- data/test/fixtures/press.yml +0 -48
- data/test/fixtures/product_3600550362626.yml +0 -54
- data/test/fixtures/product_states.yml +0 -48
- data/test/fixtures/product_states_locale.yml +0 -48
- data/test/fixtures/products_for_brand.yml +0 -99
- data/test/fixtures/products_for_entry_date.yml +0 -99
- data/test/fixtures/products_for_ingredient.yml +0 -99
- data/test/fixtures/products_for_last_edit_date.yml +0 -99
- data/test/fixtures/products_for_number_of_ingredients.yml +0 -99
- data/test/fixtures/products_for_period_after_opening.yml +0 -99
- data/test/fixtures/products_for_state.yml +0 -99
- data/test/fixtures/products_with_additive.yml +0 -99
- data/test/fixtures/search_doux.yml +0 -105
- data/test/fixtures/search_doux_1_000_000.yml +0 -54
- data/test/minitest_helper.rb +0 -20
- data/test/test_openbeautyfacts.rb +0 -363
data/test/minitest_helper.rb
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
$LOAD_PATH.unshift File.expand_path('../lib', __dir__)
|
|
4
|
-
require 'openbeautyfacts'
|
|
5
|
-
|
|
6
|
-
require 'minitest/autorun'
|
|
7
|
-
|
|
8
|
-
require 'webmock/minitest'
|
|
9
|
-
require 'vcr'
|
|
10
|
-
|
|
11
|
-
# Avoid OpenSSL certificate verify failed error
|
|
12
|
-
if ENV.key?('APPVEYOR') && Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.4')
|
|
13
|
-
require 'openssl'
|
|
14
|
-
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
VCR.configure do |c|
|
|
18
|
-
c.cassette_library_dir = 'test/fixtures'
|
|
19
|
-
c.hook_into :webmock
|
|
20
|
-
end
|
|
@@ -1,363 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative 'minitest_helper'
|
|
4
|
-
require 'uri'
|
|
5
|
-
|
|
6
|
-
class TestOpenbeautyfacts < Minitest::Test
|
|
7
|
-
# Gem
|
|
8
|
-
|
|
9
|
-
def test_that_it_has_a_version_number
|
|
10
|
-
refute_nil ::Openbeautyfacts::VERSION
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
# Locale
|
|
14
|
-
|
|
15
|
-
def test_it_fetches_locales
|
|
16
|
-
VCR.use_cassette('index') do
|
|
17
|
-
locales = ::Openbeautyfacts::Locale.all
|
|
18
|
-
assert_includes locales.map { |locale| locale['code'] }, 'gd'
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# User
|
|
23
|
-
|
|
24
|
-
def test_it_login_user
|
|
25
|
-
VCR.use_cassette('login_user', record: :once, match_requests_on: %i[host path]) do
|
|
26
|
-
user = ::Openbeautyfacts::User.login('wrong', 'absolutely')
|
|
27
|
-
assert_nil user
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# Product
|
|
32
|
-
|
|
33
|
-
def test_it_returns_product_url
|
|
34
|
-
product = ::Openbeautyfacts::Product.new(code: '3600550362626')
|
|
35
|
-
assert_equal ::Openbeautyfacts::Product.url(product.code, locale: 'ca'), product.url(locale: 'ca')
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def test_it_returns_product_weburl
|
|
39
|
-
product = ::Openbeautyfacts::Product.new(code: '3600550362626')
|
|
40
|
-
assert_equal "https://world.openbeautyfacts.org/product/#{product.code}", product.weburl(locale: 'world')
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def test_it_fetches_product
|
|
44
|
-
product_code = '3600550362626'
|
|
45
|
-
|
|
46
|
-
VCR.use_cassette("fetch_product_#{product_code}", record: :once, match_requests_on: %i[host path]) do
|
|
47
|
-
product = ::Openbeautyfacts::Product.new(code: product_code)
|
|
48
|
-
product.fetch
|
|
49
|
-
refute_empty product.brands_tags
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def test_it_get_product
|
|
54
|
-
product_code = '3600550362626'
|
|
55
|
-
|
|
56
|
-
VCR.use_cassette("product_#{product_code}", record: :once, match_requests_on: %i[host path]) do
|
|
57
|
-
assert_equal ::Openbeautyfacts::Product.get(product_code).code, product_code
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def test_that_it_search
|
|
62
|
-
term = 'doux'
|
|
63
|
-
first_product = nil
|
|
64
|
-
|
|
65
|
-
VCR.use_cassette("search_#{term}") do
|
|
66
|
-
products = ::Openbeautyfacts::Product.search(term, page_size: 24)
|
|
67
|
-
first_product = products.first
|
|
68
|
-
|
|
69
|
-
assert_match(/#{term}/i, products.last['product_name'])
|
|
70
|
-
assert_match(/#{term}/i, ::Openbeautyfacts::Product.search(term).last['product_name'])
|
|
71
|
-
assert_equal products.size, 24
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
VCR.use_cassette("search_#{term}_1_000_000") do
|
|
75
|
-
refute_equal ::Openbeautyfacts::Product.search(term, page: 2).first.code, first_product.code
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# # Test disable in order to wait for a dedicated test account to not alter real data
|
|
80
|
-
# def test_it_updates_product
|
|
81
|
-
# product_code = "3600550362626"
|
|
82
|
-
# product = ::Openbeautyfacts::Product.new(code: product_code)
|
|
83
|
-
# product_last_modified_t = nil
|
|
84
|
-
#
|
|
85
|
-
# VCR.use_cassette("fetch_product_#{product_code}", record: :all, match_requests_on: [:host, :path]) do
|
|
86
|
-
# product.fetch
|
|
87
|
-
# product_last_modified_t = product.last_modified_t
|
|
88
|
-
# end
|
|
89
|
-
#
|
|
90
|
-
# VCR.use_cassette("update_product_#{product_code}", record: :all, match_requests_on: [:host, :path]) do
|
|
91
|
-
# product.update # Empty update are accepted, allow testing without altering data.
|
|
92
|
-
# end
|
|
93
|
-
#
|
|
94
|
-
# VCR.use_cassette("refetch_product_#{product_code}", record: :all, match_requests_on: [:host, :path]) do
|
|
95
|
-
# product.fetch
|
|
96
|
-
# end
|
|
97
|
-
#
|
|
98
|
-
# refute_equal product_last_modified_t, product.last_modified_t
|
|
99
|
-
# end
|
|
100
|
-
|
|
101
|
-
# Additives
|
|
102
|
-
|
|
103
|
-
def test_it_fetches_additives
|
|
104
|
-
VCR.use_cassette('additives') do
|
|
105
|
-
additives = ::Openbeautyfacts::Additive.all # World to have riskiness
|
|
106
|
-
# Just check that we get additives and that they have URLs
|
|
107
|
-
refute_empty additives
|
|
108
|
-
assert additives.first.key?('url')
|
|
109
|
-
assert additives.first['url'].start_with?('https://world.openbeautyfacts.org/')
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
def test_it_fetches_additives_for_locale
|
|
114
|
-
VCR.use_cassette('additives_locale') do
|
|
115
|
-
skip('Website have a bug with Additives page on https://fr.openbeautyfacts.org/additifs')
|
|
116
|
-
additives = ::Openbeautyfacts::Additive.all(locale: 'fr')
|
|
117
|
-
assert_includes additives.map { |additive| additive['url'] }, 'https://fr.openbeautyfacts.org/additif/e470-sels-de-sodium-potassium-calcium-d-acides-gras'
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
def test_it_fetches_products_with_additive
|
|
122
|
-
skip 'API returns empty results for this specific additive'
|
|
123
|
-
additive = ::Openbeautyfacts::Additive.new('url' => 'https://world.openbeautyfacts.org/additive/e539-sodium-thiosulfate')
|
|
124
|
-
VCR.use_cassette('products_with_additive') do
|
|
125
|
-
products_with_additive = additive.products(page: 1)
|
|
126
|
-
refute_empty products_with_additive
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
# Brands
|
|
131
|
-
|
|
132
|
-
def test_it_fetches_brands
|
|
133
|
-
VCR.use_cassette('brands') do
|
|
134
|
-
brands = ::Openbeautyfacts::Brand.all
|
|
135
|
-
assert_includes brands.map { |brand| brand['name'] }, 'Garnier'
|
|
136
|
-
end
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
def test_it_fetches_brands_for_locale
|
|
140
|
-
VCR.use_cassette('brands_locale') do
|
|
141
|
-
skip('Website have a bug with Brands page on https://fr.openbeautyfacts.org/marques')
|
|
142
|
-
brands = ::Openbeautyfacts::Brand.all(locale: 'fr')
|
|
143
|
-
assert_includes brands.map { |brand| brand['name'] }, 'Sedapoux'
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
def test_it_fetches_products_for_brand
|
|
148
|
-
skip 'API returns empty results for this specific brand'
|
|
149
|
-
brand = ::Openbeautyfacts::Brand.new('url' => 'https://world.openbeautyfacts.org/brand/sedapoux')
|
|
150
|
-
VCR.use_cassette('products_for_brand') do
|
|
151
|
-
products_for_brand = brand.products(page: 1)
|
|
152
|
-
refute_empty products_for_brand
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
# Product states
|
|
157
|
-
|
|
158
|
-
def test_it_fetches_product_states
|
|
159
|
-
VCR.use_cassette('product_states') do
|
|
160
|
-
product_states = ::Openbeautyfacts::ProductState.all
|
|
161
|
-
assert_includes product_states.map { |product_state| product_state['url'] }, 'https://world.openbeautyfacts.org/facets/states/empty'
|
|
162
|
-
end
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
def test_it_fetches_product_states_for_locale
|
|
166
|
-
VCR.use_cassette('product_states_locale') do
|
|
167
|
-
product_states = ::Openbeautyfacts::ProductState.all(locale: 'fr')
|
|
168
|
-
# Just check that we get states and they have proper French URLs
|
|
169
|
-
refute_empty product_states
|
|
170
|
-
assert product_states.first.key?('url')
|
|
171
|
-
assert_equal 'fr.openbeautyfacts.org', URI(product_states.first['url']).host
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
def test_it_fetches_products_for_state
|
|
176
|
-
skip 'API returns empty results for this specific state'
|
|
177
|
-
product_state = ::Openbeautyfacts::ProductState.new(
|
|
178
|
-
'url' => 'https://world.openbeautyfacts.org/state/photos-uploaded', 'products_count' => 22
|
|
179
|
-
)
|
|
180
|
-
VCR.use_cassette('products_for_state') do
|
|
181
|
-
products_for_state = product_state.products(page: 1)
|
|
182
|
-
refute_empty products_for_state
|
|
183
|
-
end
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
# Ingredients
|
|
187
|
-
|
|
188
|
-
def test_it_fetches_ingredients
|
|
189
|
-
VCR.use_cassette('ingredients') do
|
|
190
|
-
ingredients = ::Openbeautyfacts::Ingredient.all
|
|
191
|
-
# Just check that we get ingredients and that they have basic structure
|
|
192
|
-
refute_empty ingredients
|
|
193
|
-
assert ingredients.first.key?('name')
|
|
194
|
-
# Check for a common ingredient that should exist
|
|
195
|
-
ingredient_names = ingredients.map { |ingredient| ingredient['name'] }
|
|
196
|
-
assert ingredient_names.any? { |name| name&.downcase&.include?('water') || name&.downcase&.include?('aqua') }
|
|
197
|
-
end
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
def test_it_fetches_ingredients_for_locale
|
|
201
|
-
VCR.use_cassette('ingredients_locale') do
|
|
202
|
-
ingredients = ::Openbeautyfacts::Ingredient.all(locale: 'fr')
|
|
203
|
-
assert_includes ingredients.map { |ingredient| ingredient['name'] }, 'Eau'
|
|
204
|
-
end
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
def test_it_fetches_products_for_ingredient
|
|
208
|
-
skip 'API returns empty results for this specific ingredient'
|
|
209
|
-
ingredient = ::Openbeautyfacts::Ingredient.new('url' => 'https://world.openbeautyfacts.org/ingredient/water')
|
|
210
|
-
VCR.use_cassette('products_for_ingredient') do
|
|
211
|
-
products_for_ingredient = ingredient.products(page: 1)
|
|
212
|
-
refute_empty products_for_ingredient
|
|
213
|
-
end
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
# Entry date
|
|
217
|
-
|
|
218
|
-
def test_it_fetches_entry_dates
|
|
219
|
-
VCR.use_cassette('entry_dates') do
|
|
220
|
-
entry_dates = ::Openbeautyfacts::EntryDate.all
|
|
221
|
-
# Check that we have some entry dates, as specific dates may change over time
|
|
222
|
-
refute_empty entry_dates
|
|
223
|
-
# Check for a date that should still exist in the newer data
|
|
224
|
-
assert_includes entry_dates.map { |entry_date| entry_date['name'] }, '2016-02'
|
|
225
|
-
end
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
def test_it_fetches_entry_dates_for_locale
|
|
229
|
-
VCR.use_cassette('entry_dates_locale') do
|
|
230
|
-
entry_dates = ::Openbeautyfacts::EntryDate.all(locale: 'fr')
|
|
231
|
-
# Check that we have some entry dates, as specific dates may change over time
|
|
232
|
-
refute_empty entry_dates
|
|
233
|
-
# Check for a date that should still exist in the newer data
|
|
234
|
-
assert_includes entry_dates.map { |entry_date| entry_date['name'] }, '2016-02'
|
|
235
|
-
end
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
def test_it_fetches_products_for_entry_date
|
|
239
|
-
skip 'API returns empty results for this specific entry date'
|
|
240
|
-
entry_date = ::Openbeautyfacts::EntryDate.new('url' => 'https://world.openbeautyfacts.org/entry-date/2016-02-12')
|
|
241
|
-
VCR.use_cassette('products_for_entry_date') do
|
|
242
|
-
products_for_entry_date = entry_date.products(page: -1)
|
|
243
|
-
refute_empty products_for_entry_date
|
|
244
|
-
end
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
# Last edit date
|
|
248
|
-
|
|
249
|
-
def test_it_fetches_last_edit_dates
|
|
250
|
-
VCR.use_cassette('last_edit_dates') do
|
|
251
|
-
last_edit_dates = ::Openbeautyfacts::LastEditDate.all
|
|
252
|
-
# Check that we have some last edit dates, as specific dates may change over time
|
|
253
|
-
refute_empty last_edit_dates
|
|
254
|
-
# Check for a date that should still exist in the newer data
|
|
255
|
-
assert_includes last_edit_dates.map { |last_edit_date| last_edit_date['name'] }, '2016-02'
|
|
256
|
-
end
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
def test_it_fetches_last_edit_dates_for_locale
|
|
260
|
-
VCR.use_cassette('last_edit_dates_locale') do
|
|
261
|
-
last_edit_dates = ::Openbeautyfacts::LastEditDate.all(locale: 'fr')
|
|
262
|
-
# Check that we have some last edit dates, as specific dates may change over time
|
|
263
|
-
refute_empty last_edit_dates
|
|
264
|
-
# Check for a date that should still exist in the newer data
|
|
265
|
-
assert_includes last_edit_dates.map { |last_edit_date| last_edit_date['name'] }, '2016-02'
|
|
266
|
-
end
|
|
267
|
-
end
|
|
268
|
-
|
|
269
|
-
def test_it_fetches_products_for_last_edit_date
|
|
270
|
-
skip 'API returns empty results for this specific last edit date'
|
|
271
|
-
last_edit_date = ::Openbeautyfacts::LastEditDate.new('url' => 'https://world.openbeautyfacts.org/last-edit-date/2016-02-12')
|
|
272
|
-
VCR.use_cassette('products_for_last_edit_date') do
|
|
273
|
-
products_for_last_edit_date = last_edit_date.products(page: -1)
|
|
274
|
-
refute_empty products_for_last_edit_date
|
|
275
|
-
end
|
|
276
|
-
end
|
|
277
|
-
|
|
278
|
-
# Mission
|
|
279
|
-
|
|
280
|
-
def test_it_fetches_missions
|
|
281
|
-
skip 'API returns empty results for missions'
|
|
282
|
-
VCR.use_cassette('missions') do
|
|
283
|
-
refute_empty ::Openbeautyfacts::Mission.all(locale: 'fr')
|
|
284
|
-
end
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
def test_it_fetches_mission
|
|
288
|
-
skip 'Mission fetch method has implementation issues'
|
|
289
|
-
VCR.use_cassette('mission', record: :once, match_requests_on: %i[host path]) do
|
|
290
|
-
mission = ::Openbeautyfacts::Mission.new(url: 'https://fr.openbeautyfacts.org/mission/25-produits')
|
|
291
|
-
mission.fetch
|
|
292
|
-
refute_empty mission.users
|
|
293
|
-
end
|
|
294
|
-
end
|
|
295
|
-
|
|
296
|
-
# Number of Ingredients
|
|
297
|
-
|
|
298
|
-
def test_it_fetches_numbers_of_ingredients
|
|
299
|
-
VCR.use_cassette('numbers_of_ingredients') do
|
|
300
|
-
numbers_of_ingredients = ::Openbeautyfacts::NumberOfIngredients.all
|
|
301
|
-
assert_includes numbers_of_ingredients.map { |number_of_ingredients| number_of_ingredients['name'] }, '38'
|
|
302
|
-
end
|
|
303
|
-
end
|
|
304
|
-
|
|
305
|
-
def test_it_fetches_numbers_of_ingredients_for_locale
|
|
306
|
-
VCR.use_cassette('number_of_ingredients_locale') do
|
|
307
|
-
numbers_of_ingredients = ::Openbeautyfacts::NumberOfIngredients.all(locale: 'fr')
|
|
308
|
-
assert_includes numbers_of_ingredients.map { |number_of_ingredients| number_of_ingredients['name'] }, '38'
|
|
309
|
-
end
|
|
310
|
-
end
|
|
311
|
-
|
|
312
|
-
def test_it_fetches_products_for_number_of_ingredients
|
|
313
|
-
skip 'API returns empty results for this specific number of ingredients'
|
|
314
|
-
number_of_ingredients = ::Openbeautyfacts::NumberOfIngredients.new('url' => 'https://world.openbeautyfacts.org/number-of-ingredients/38')
|
|
315
|
-
VCR.use_cassette('products_for_number_of_ingredients') do
|
|
316
|
-
products_for_number_of_ingredients = number_of_ingredients.products(page: -1)
|
|
317
|
-
refute_empty products_for_number_of_ingredients
|
|
318
|
-
end
|
|
319
|
-
end
|
|
320
|
-
|
|
321
|
-
# Period after openings
|
|
322
|
-
|
|
323
|
-
def test_it_fetches_period_after_openings
|
|
324
|
-
skip 'Source page is gone'
|
|
325
|
-
VCR.use_cassette('period_after_openings') do
|
|
326
|
-
period_after_openings = ::Openbeautyfacts::PeriodAfterOpening.all
|
|
327
|
-
assert_includes period_after_openings.map { |period_after_opening| period_after_opening['name'] }, '12 months'
|
|
328
|
-
end
|
|
329
|
-
end
|
|
330
|
-
|
|
331
|
-
def test_it_fetches_period_after_openings_for_locale
|
|
332
|
-
skip 'Source page is gone'
|
|
333
|
-
VCR.use_cassette('period_after_openings_locale') do
|
|
334
|
-
period_after_openings = ::Openbeautyfacts::PeriodAfterOpening.all(locale: 'fr')
|
|
335
|
-
assert_includes period_after_openings.map { |period_after_opening| period_after_opening['name'] }, '12 mois'
|
|
336
|
-
end
|
|
337
|
-
end
|
|
338
|
-
|
|
339
|
-
def test_it_fetches_products_for_period_after_opening
|
|
340
|
-
skip 'API returns empty results for this specific period after opening'
|
|
341
|
-
period_after_opening = ::Openbeautyfacts::PeriodAfterOpening.new('url' => 'https://world.openbeautyfacts.org/period-after-opening/12-months')
|
|
342
|
-
VCR.use_cassette('products_for_period_after_opening') do
|
|
343
|
-
products_for_period_after_opening = period_after_opening.products(page: 1)
|
|
344
|
-
refute_empty products_for_period_after_opening
|
|
345
|
-
end
|
|
346
|
-
end
|
|
347
|
-
|
|
348
|
-
# FAQ
|
|
349
|
-
|
|
350
|
-
def test_it_fetches_faq
|
|
351
|
-
VCR.use_cassette('faq') do
|
|
352
|
-
refute_empty ::Openbeautyfacts::Faq.items(locale: 'fr')
|
|
353
|
-
end
|
|
354
|
-
end
|
|
355
|
-
|
|
356
|
-
# Press
|
|
357
|
-
|
|
358
|
-
def test_it_fetches_press
|
|
359
|
-
VCR.use_cassette('press') do
|
|
360
|
-
refute_empty ::Openbeautyfacts::Press.items(locale: 'fr')
|
|
361
|
-
end
|
|
362
|
-
end
|
|
363
|
-
end
|