gcloud 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 +8 -8
- data/CHANGELOG.md +36 -0
- data/lib/gcloud/backoff.rb +5 -5
- data/lib/gcloud/bigquery.rb +24 -0
- data/lib/gcloud/bigquery/connection.rb +32 -25
- data/lib/gcloud/bigquery/data.rb +99 -1
- data/lib/gcloud/bigquery/dataset.rb +5 -13
- data/lib/gcloud/bigquery/dataset/list.rb +124 -2
- data/lib/gcloud/bigquery/job/list.rb +125 -2
- data/lib/gcloud/bigquery/project.rb +30 -27
- data/lib/gcloud/bigquery/query_data.rb +102 -1
- data/lib/gcloud/bigquery/table.rb +17 -2
- data/lib/gcloud/bigquery/table/list.rb +132 -3
- data/lib/gcloud/datastore.rb +30 -19
- data/lib/gcloud/datastore/dataset.rb +2 -22
- data/lib/gcloud/datastore/dataset/lookup_results.rb +160 -4
- data/lib/gcloud/datastore/dataset/query_results.rb +229 -23
- data/lib/gcloud/datastore/transaction.rb +2 -5
- data/lib/gcloud/dns.rb +20 -0
- data/lib/gcloud/dns/change/list.rb +109 -6
- data/lib/gcloud/dns/connection.rb +18 -9
- data/lib/gcloud/dns/project.rb +4 -8
- data/lib/gcloud/dns/record/list.rb +96 -13
- data/lib/gcloud/dns/zone.rb +9 -24
- data/lib/gcloud/dns/zone/list.rb +102 -5
- data/lib/gcloud/dns/zone/transaction.rb +1 -1
- data/lib/gcloud/logging.rb +19 -0
- data/lib/gcloud/logging/entry/list.rb +83 -14
- data/lib/gcloud/logging/metric/list.rb +89 -12
- data/lib/gcloud/logging/project.rb +18 -30
- data/lib/gcloud/logging/resource_descriptor/list.rb +105 -6
- data/lib/gcloud/logging/sink/list.rb +89 -12
- data/lib/gcloud/pubsub.rb +23 -0
- data/lib/gcloud/pubsub/project.rb +21 -29
- data/lib/gcloud/pubsub/service.rb +1 -3
- data/lib/gcloud/pubsub/subscription/list.rb +167 -13
- data/lib/gcloud/pubsub/topic.rb +15 -13
- data/lib/gcloud/pubsub/topic/batch.rb +10 -4
- data/lib/gcloud/pubsub/topic/list.rb +134 -8
- data/lib/gcloud/resource_manager.rb +24 -0
- data/lib/gcloud/resource_manager/connection.rb +18 -9
- data/lib/gcloud/resource_manager/manager.rb +7 -4
- data/lib/gcloud/resource_manager/project/list.rb +93 -14
- data/lib/gcloud/storage.rb +63 -0
- data/lib/gcloud/storage/bucket.rb +100 -61
- data/lib/gcloud/storage/bucket/list.rb +132 -8
- data/lib/gcloud/storage/connection.rb +68 -44
- data/lib/gcloud/storage/errors.rb +9 -3
- data/lib/gcloud/storage/file.rb +48 -4
- data/lib/gcloud/storage/file/list.rb +151 -15
- data/lib/gcloud/storage/file/verifier.rb +3 -3
- data/lib/gcloud/storage/project.rb +15 -30
- data/lib/gcloud/translate.rb +20 -0
- data/lib/gcloud/translate/connection.rb +12 -3
- data/lib/gcloud/version.rb +1 -1
- data/lib/gcloud/vision.rb +20 -0
- data/lib/gcloud/vision/connection.rb +10 -1
- data/lib/gcloud/vision/image.rb +15 -18
- metadata +16 -2
@@ -34,45 +34,121 @@ module Gcloud
|
|
34
34
|
|
35
35
|
##
|
36
36
|
# Whether there is a next page of sinks.
|
37
|
+
#
|
38
|
+
# @return [Boolean]
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
# require "gcloud"
|
42
|
+
#
|
43
|
+
# gcloud = Gcloud.new
|
44
|
+
# logging = gcloud.logging
|
45
|
+
#
|
46
|
+
# sinks = logging.sinks
|
47
|
+
# if sinks.next?
|
48
|
+
# next_sinks = sinks.next
|
49
|
+
# end
|
50
|
+
#
|
37
51
|
def next?
|
38
52
|
!token.nil?
|
39
53
|
end
|
40
54
|
|
41
55
|
##
|
42
56
|
# Retrieve the next page of sinks.
|
57
|
+
#
|
58
|
+
# @return [Sink::List]
|
59
|
+
#
|
60
|
+
# @example
|
61
|
+
# require "gcloud"
|
62
|
+
#
|
63
|
+
# gcloud = Gcloud.new
|
64
|
+
# logging = gcloud.logging
|
65
|
+
#
|
66
|
+
# sinks = dataset.sinks
|
67
|
+
# if sinks.next?
|
68
|
+
# next_sinks = sinks.next
|
69
|
+
# end
|
70
|
+
#
|
43
71
|
def next
|
44
72
|
return nil unless next?
|
45
73
|
ensure_service!
|
46
|
-
list_grpc = @service.list_sinks token: token
|
74
|
+
list_grpc = @service.list_sinks token: token, max: @max
|
47
75
|
self.class.from_grpc list_grpc, @service
|
48
76
|
rescue GRPC::BadStatus => e
|
49
77
|
raise Gcloud::Error.from_error(e)
|
50
78
|
end
|
51
79
|
|
52
80
|
##
|
53
|
-
# Retrieves all sinks by repeatedly loading {#next
|
54
|
-
# returns `false`.
|
81
|
+
# Retrieves all sinks by repeatedly loading {#next} until {#next?}
|
82
|
+
# returns `false`. Calls the given block once for each sink, which is
|
83
|
+
# passed as the parameter.
|
55
84
|
#
|
56
|
-
#
|
85
|
+
# An Enumerator is returned if no block is given.
|
86
|
+
#
|
87
|
+
# This method may make several API calls until all sinks are retrieved.
|
88
|
+
# Be sure to use as narrow a search criteria as possible. Please use
|
89
|
+
# with caution.
|
90
|
+
#
|
91
|
+
# @param [Integer] request_limit The upper limit of API requests to make
|
92
|
+
# to load all sinks. Default is no limit.
|
93
|
+
# @yield [sink] The block for accessing each sink.
|
94
|
+
# @yieldparam [Sink] sink The sink object.
|
95
|
+
#
|
96
|
+
# @return [Enumerator]
|
97
|
+
#
|
98
|
+
# @example Iterating each sink by passing a block:
|
99
|
+
# require "gcloud"
|
100
|
+
#
|
101
|
+
# gcloud = Gcloud.new
|
102
|
+
# logging = gcloud.logging
|
103
|
+
# sinks = logging.sinks
|
104
|
+
#
|
105
|
+
# sinks.all do |sink|
|
106
|
+
# puts "#{sink.name}: #{sink.filter} -> #{sink.destination}"
|
107
|
+
# end
|
108
|
+
#
|
109
|
+
# @example Using the enumerator by not passing a block:
|
57
110
|
# require "gcloud"
|
58
111
|
#
|
59
112
|
# gcloud = Gcloud.new
|
60
113
|
# logging = gcloud.logging
|
61
|
-
#
|
114
|
+
# sinks = logging.sinks
|
115
|
+
#
|
116
|
+
# all_names = sinks.all.map do |sink|
|
117
|
+
# sink.name
|
118
|
+
# end
|
62
119
|
#
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
120
|
+
# @example Limit the number of API calls made:
|
121
|
+
# require "gcloud"
|
122
|
+
#
|
123
|
+
# gcloud = Gcloud.new
|
124
|
+
# logging = gcloud.logging
|
125
|
+
# sinks = logging.sinks
|
126
|
+
#
|
127
|
+
# sinks.all(request_limit: 10) do |sink|
|
128
|
+
# puts "#{sink.name}: #{sink.filter} -> #{sink.destination}"
|
129
|
+
# end
|
130
|
+
#
|
131
|
+
def all request_limit: nil
|
132
|
+
request_limit = request_limit.to_i if request_limit
|
133
|
+
unless block_given?
|
134
|
+
return enum_for(:all, request_limit: request_limit)
|
135
|
+
end
|
136
|
+
results = self
|
137
|
+
loop do
|
138
|
+
results.each { |r| yield r }
|
139
|
+
if request_limit
|
140
|
+
request_limit -= 1
|
141
|
+
break if request_limit < 0
|
142
|
+
end
|
143
|
+
break unless results.next?
|
144
|
+
results = results.next
|
68
145
|
end
|
69
|
-
self
|
70
146
|
end
|
71
147
|
|
72
148
|
##
|
73
149
|
# @private New Sink::List from a Google::Logging::V2::ListSinksResponse
|
74
150
|
# object.
|
75
|
-
def self.from_grpc grpc_list, service
|
151
|
+
def self.from_grpc grpc_list, service, max = nil
|
76
152
|
sinks = new(Array(grpc_list.sinks).map do |grpc|
|
77
153
|
Sink.from_grpc grpc, service
|
78
154
|
end)
|
@@ -80,6 +156,7 @@ module Gcloud
|
|
80
156
|
token = nil if token == ""
|
81
157
|
sinks.instance_variable_set "@token", token
|
82
158
|
sinks.instance_variable_set "@service", service
|
159
|
+
sinks.instance_variable_set "@max", max
|
83
160
|
sinks
|
84
161
|
end
|
85
162
|
|
data/lib/gcloud/pubsub.rb
CHANGED
@@ -389,6 +389,29 @@ module Gcloud
|
|
389
389
|
# end
|
390
390
|
# ```
|
391
391
|
#
|
392
|
+
# ## Configuring Backoff
|
393
|
+
#
|
394
|
+
# The {Gcloud::Backoff} class allows users to globally configure how Cloud API
|
395
|
+
# requests are automatically retried in the case of some errors, such as a
|
396
|
+
# `500` or `503` status code, or a specific internal error code such as
|
397
|
+
# `rateLimitExceeded`.
|
398
|
+
#
|
399
|
+
# If an API call fails, the response will be inspected to see if the call
|
400
|
+
# should be retried. If the response matches the criteria, then the request
|
401
|
+
# will be retried after a delay. If another error occurs, the delay will be
|
402
|
+
# increased incrementally before a subsequent attempt. The first retry will be
|
403
|
+
# delayed one second, the second retry two seconds, and so on.
|
404
|
+
#
|
405
|
+
# ```ruby
|
406
|
+
# require "gcloud"
|
407
|
+
# require "gcloud/backoff"
|
408
|
+
#
|
409
|
+
# Gcloud::Backoff.retries = 5 # Raise the maximum number of retries from 3
|
410
|
+
# ```
|
411
|
+
#
|
412
|
+
# See the [Pub/Sub error codes](https://cloud.google.com/pubsub/error-codes)
|
413
|
+
# for a list of error conditions.
|
414
|
+
#
|
392
415
|
# ## Working Across Projects
|
393
416
|
#
|
394
417
|
# All calls to the Pub/Sub service use the same project and credentials
|
@@ -197,29 +197,22 @@ module Gcloud
|
|
197
197
|
# puts topic.name
|
198
198
|
# end
|
199
199
|
#
|
200
|
-
# @example
|
200
|
+
# @example Retrieve all topics: (See {Topic::List#all})
|
201
201
|
# require "gcloud"
|
202
202
|
#
|
203
203
|
# gcloud = Gcloud.new
|
204
204
|
# pubsub = gcloud.pubsub
|
205
205
|
#
|
206
|
-
#
|
207
|
-
#
|
208
|
-
#
|
209
|
-
# tmp_topics.each do |topic|
|
210
|
-
# all_topics << topic
|
211
|
-
# end
|
212
|
-
# # break loop if no more topics available
|
213
|
-
# break if tmp_topics.token.nil?
|
214
|
-
# # get the next group of topics
|
215
|
-
# tmp_topics = pubsub.topics token: tmp_topics.token
|
206
|
+
# topics = pubsub.topics
|
207
|
+
# topics.all do |topic|
|
208
|
+
# puts topic.name
|
216
209
|
# end
|
217
210
|
#
|
218
211
|
def topics token: nil, max: nil
|
219
212
|
ensure_service!
|
220
213
|
options = { token: token, max: max }
|
221
214
|
grpc = service.list_topics options
|
222
|
-
Topic::List.from_grpc grpc, service
|
215
|
+
Topic::List.from_grpc grpc, service, max
|
223
216
|
rescue GRPC::BadStatus => e
|
224
217
|
raise Error.from_error(e)
|
225
218
|
end
|
@@ -235,7 +228,7 @@ module Gcloud
|
|
235
228
|
# without a subscription will be lost.
|
236
229
|
#
|
237
230
|
# @param [String] topic_name Name of a topic.
|
238
|
-
# @param [String] data The message data.
|
231
|
+
# @param [String, File] data The message data.
|
239
232
|
# @param [Hash] attributes Optional attributes for the message.
|
240
233
|
# @option attributes [Boolean] :autocreate Flag to control whether the
|
241
234
|
# provided topic will be created if it does not exist.
|
@@ -254,6 +247,14 @@ module Gcloud
|
|
254
247
|
#
|
255
248
|
# msg = pubsub.publish "my-topic", "new-message"
|
256
249
|
#
|
250
|
+
# @example A message can be published using a File object:
|
251
|
+
# require "gcloud"
|
252
|
+
#
|
253
|
+
# gcloud = Gcloud.new
|
254
|
+
# pubsub = gcloud.pubsub
|
255
|
+
#
|
256
|
+
# msg = pubsub.publish "my-topic", File.open("message.txt")
|
257
|
+
#
|
257
258
|
# @example Additionally, a message can be published with attributes:
|
258
259
|
# require "gcloud"
|
259
260
|
#
|
@@ -426,8 +427,6 @@ module Gcloud
|
|
426
427
|
##
|
427
428
|
# Retrieves a list of subscriptions for the given project.
|
428
429
|
#
|
429
|
-
# @param [String] prefix Filter results to subscriptions whose names begin
|
430
|
-
# with this prefix.
|
431
430
|
# @param [String] token A previously-returned page token representing part
|
432
431
|
# of the larger set of results to view.
|
433
432
|
# @param [Integer] max Maximum number of subscriptions to return.
|
@@ -446,29 +445,22 @@ module Gcloud
|
|
446
445
|
# puts subscription.name
|
447
446
|
# end
|
448
447
|
#
|
449
|
-
# @example
|
448
|
+
# @example Retrieve all subscriptions: (See {Subscription::List#all})
|
450
449
|
# require "gcloud"
|
451
450
|
#
|
452
451
|
# gcloud = Gcloud.new
|
453
452
|
# pubsub = gcloud.pubsub
|
454
453
|
#
|
455
|
-
#
|
456
|
-
#
|
457
|
-
#
|
458
|
-
# tmp_subs.each do |subscription|
|
459
|
-
# all_subs << subscription
|
460
|
-
# end
|
461
|
-
# # break loop if no more subscriptions available
|
462
|
-
# break if tmp_subs.token.nil?
|
463
|
-
# # get the next group of subscriptions
|
464
|
-
# tmp_subs = pubsub.subscriptions token: tmp_subs.token
|
454
|
+
# subscriptions = pubsub.subscriptions
|
455
|
+
# subscriptions.all do |subscription|
|
456
|
+
# puts subscription.name
|
465
457
|
# end
|
466
458
|
#
|
467
|
-
def subscriptions
|
459
|
+
def subscriptions token: nil, max: nil
|
468
460
|
ensure_service!
|
469
|
-
options = {
|
461
|
+
options = { token: token, max: max }
|
470
462
|
grpc = service.list_subscriptions options
|
471
|
-
Subscription::List.from_grpc grpc, service
|
463
|
+
Subscription::List.from_grpc grpc, service, max
|
472
464
|
rescue GRPC::BadStatus => e
|
473
465
|
raise Error.from_error(e)
|
474
466
|
end
|
@@ -122,9 +122,7 @@ module Gcloud
|
|
122
122
|
topic: topic_path(topic),
|
123
123
|
messages: messages.map do |data, attributes|
|
124
124
|
Google::Pubsub::V1::PubsubMessage.new(
|
125
|
-
data:
|
126
|
-
attributes: attributes
|
127
|
-
)
|
125
|
+
data: data, attributes: attributes)
|
128
126
|
end
|
129
127
|
)
|
130
128
|
|
@@ -28,25 +28,179 @@ module Gcloud
|
|
28
28
|
attr_accessor :token
|
29
29
|
|
30
30
|
##
|
31
|
-
# Create a new Subscription::List with an array of values.
|
32
|
-
def initialize arr = []
|
31
|
+
# @private Create a new Subscription::List with an array of values.
|
32
|
+
def initialize arr = []
|
33
33
|
super arr
|
34
|
-
@token = token
|
35
|
-
@token = nil if @token == ""
|
36
34
|
end
|
37
35
|
|
38
36
|
##
|
39
|
-
#
|
40
|
-
#
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
37
|
+
# Whether there a next page of subscriptions.
|
38
|
+
#
|
39
|
+
# @return [Boolean]
|
40
|
+
#
|
41
|
+
# @example
|
42
|
+
# require "gcloud"
|
43
|
+
#
|
44
|
+
# gcloud = Gcloud.new
|
45
|
+
# pubsub = gcloud.pubsub
|
46
|
+
#
|
47
|
+
# subscriptions = pubsub.subscriptions
|
48
|
+
# if subscriptions.next?
|
49
|
+
# next_subscriptions = subscriptions.next
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
def next?
|
53
|
+
!token.nil?
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# Retrieve the next page of subscriptions.
|
58
|
+
#
|
59
|
+
# @return [Subscription::List]
|
60
|
+
#
|
61
|
+
# @example
|
62
|
+
# require "gcloud"
|
63
|
+
#
|
64
|
+
# gcloud = Gcloud.new
|
65
|
+
# pubsub = gcloud.pubsub
|
66
|
+
#
|
67
|
+
# subscriptions = pubsub.subscriptions
|
68
|
+
# if subscriptions.next?
|
69
|
+
# next_subscriptions = subscriptions.next
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
def next
|
73
|
+
return nil unless next?
|
74
|
+
ensure_service!
|
75
|
+
if @topic
|
76
|
+
next_topic_subscriptions
|
77
|
+
else
|
78
|
+
next_subscriptions
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# Retrieves all subscriptions by repeatedly loading {#next} until
|
84
|
+
# {#next?} returns `false`. Calls the given block once for each
|
85
|
+
# subscription, which is passed as the parameter.
|
86
|
+
#
|
87
|
+
# An Enumerator is returned if no block is given.
|
88
|
+
#
|
89
|
+
# This method may make several API calls until all subscriptions are
|
90
|
+
# retrieved. Be sure to use as narrow a search criteria as possible.
|
91
|
+
# Please use with caution.
|
92
|
+
#
|
93
|
+
# @param [Integer] request_limit The upper limit of API requests to make
|
94
|
+
# to load all subscriptions. Default is no limit.
|
95
|
+
# @yield [subscription] The block for accessing each subscription.
|
96
|
+
# @yieldparam [Subscription] subscription The subscription object.
|
97
|
+
#
|
98
|
+
# @return [Enumerator]
|
99
|
+
#
|
100
|
+
# @example Iterating each subscription by passing a block:
|
101
|
+
# require "gcloud"
|
102
|
+
#
|
103
|
+
# gcloud = Gcloud.new
|
104
|
+
# pubsub = gcloud.pubsub
|
105
|
+
#
|
106
|
+
# subscriptions = pubsub.subscriptions
|
107
|
+
# subscriptions.all do |subscription|
|
108
|
+
# puts subscription.name
|
109
|
+
# end
|
110
|
+
#
|
111
|
+
# @example Using the enumerator by not passing a block:
|
112
|
+
# require "gcloud"
|
113
|
+
#
|
114
|
+
# gcloud = Gcloud.new
|
115
|
+
# pubsub = gcloud.pubsub
|
116
|
+
#
|
117
|
+
# subscriptions = pubsub.subscriptions
|
118
|
+
# all_names = subscriptions.all.map do |subscription|
|
119
|
+
# subscription.name
|
120
|
+
# end
|
121
|
+
#
|
122
|
+
# @example Limit the number of API calls made:
|
123
|
+
# require "gcloud"
|
124
|
+
#
|
125
|
+
# gcloud = Gcloud.new
|
126
|
+
# pubsub = gcloud.pubsub
|
127
|
+
#
|
128
|
+
# subscriptions = pubsub.subscriptions
|
129
|
+
# subscriptions.all(request_limit: 10) do |subscription|
|
130
|
+
# puts subscription.name
|
131
|
+
# end
|
132
|
+
#
|
133
|
+
def all request_limit: nil
|
134
|
+
request_limit = request_limit.to_i if request_limit
|
135
|
+
unless block_given?
|
136
|
+
return enum_for(:all, request_limit: request_limit)
|
137
|
+
end
|
138
|
+
results = self
|
139
|
+
loop do
|
140
|
+
results.each { |r| yield r }
|
141
|
+
if request_limit
|
142
|
+
request_limit -= 1
|
143
|
+
break if request_limit < 0
|
47
144
|
end
|
145
|
+
break unless results.next?
|
146
|
+
results = results.next
|
48
147
|
end
|
49
|
-
|
148
|
+
end
|
149
|
+
|
150
|
+
##
|
151
|
+
# @private New Subscriptions::List from a
|
152
|
+
# Google::Pubsub::V1::ListSubscriptionsRequest object.
|
153
|
+
def self.from_grpc grpc_list, service, max = nil
|
154
|
+
subs = new(Array(grpc_list.subscriptions).map do |grpc|
|
155
|
+
Subscription.from_grpc grpc, service
|
156
|
+
end)
|
157
|
+
token = grpc_list.next_page_token
|
158
|
+
token = nil if token == ""
|
159
|
+
subs.instance_variable_set "@token", token
|
160
|
+
subs.instance_variable_set "@service", service
|
161
|
+
subs.instance_variable_set "@max", max
|
162
|
+
subs
|
163
|
+
end
|
164
|
+
|
165
|
+
##
|
166
|
+
# @private New Subscriptions::List from a
|
167
|
+
# Google::Pubsub::V1::ListTopicSubscriptionsResponse object.
|
168
|
+
def self.from_topic_grpc grpc_list, service, topic, max = nil
|
169
|
+
subs = new(Array(grpc_list.subscriptions).map do |grpc|
|
170
|
+
Subscription.new_lazy grpc, service
|
171
|
+
end)
|
172
|
+
token = grpc_list.next_page_token
|
173
|
+
token = nil if token == ""
|
174
|
+
subs.instance_variable_set "@token", token
|
175
|
+
subs.instance_variable_set "@service", service
|
176
|
+
subs.instance_variable_set "@topic", topic
|
177
|
+
subs.instance_variable_set "@max", max
|
178
|
+
subs
|
179
|
+
end
|
180
|
+
|
181
|
+
protected
|
182
|
+
|
183
|
+
##
|
184
|
+
# @private Raise an error unless an active connection to the service is
|
185
|
+
# available.
|
186
|
+
def ensure_service!
|
187
|
+
fail "Must have active connection to service" unless @service
|
188
|
+
end
|
189
|
+
|
190
|
+
def next_subscriptions
|
191
|
+
options = { prefix: @prefix, token: @token, max: @max }
|
192
|
+
grpc = @service.list_subscriptions options
|
193
|
+
self.class.from_grpc grpc, @service, @max
|
194
|
+
rescue GRPC::BadStatus => e
|
195
|
+
raise Error.from_error(e)
|
196
|
+
end
|
197
|
+
|
198
|
+
def next_topic_subscriptions
|
199
|
+
options = { token: @token, max: @max }
|
200
|
+
grpc = @service.list_topics_subscriptions @topic, options
|
201
|
+
self.class.from_topic_grpc grpc, @service, @topic, @max
|
202
|
+
rescue GRPC::BadStatus => e
|
203
|
+
raise Error.from_error(e)
|
50
204
|
end
|
51
205
|
end
|
52
206
|
end
|