aws-sdk 1.1.4 → 1.2.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.
- data/lib/aws.rb +2 -0
- data/lib/aws/api_config/ELB-2011-08-15.yml +380 -0
- data/lib/aws/api_config/SNS-2010-03-31.yml +2 -2
- data/lib/aws/api_config/SimpleEmailService-2010-12-01.yml +5 -5
- data/lib/aws/core.rb +18 -3
- data/lib/aws/core/client_logging.rb +5 -6
- data/lib/aws/core/collection.rb +241 -0
- data/lib/aws/core/collection/batchable.rb +133 -0
- data/lib/aws/core/collection/limitable.rb +92 -0
- data/lib/aws/core/collection/simple.rb +89 -0
- data/lib/aws/core/configuration.rb +23 -0
- data/lib/aws/core/option_grammar.rb +2 -0
- data/lib/aws/core/page_result.rb +73 -0
- data/lib/aws/ec2/security_group.rb +154 -89
- data/lib/aws/ec2/security_group/egress_ip_permission_collection.rb +1 -2
- data/lib/aws/ec2/security_group/{ip_permission_collection.rb → ingress_ip_permission_collection.rb} +4 -1
- data/lib/aws/ec2/security_group/ip_permission.rb +23 -45
- data/lib/aws/elb.rb +65 -0
- data/lib/aws/elb/availability_zone_collection.rb +138 -0
- data/lib/aws/elb/backend_server_policy_collection.rb +150 -0
- data/lib/aws/elb/client.rb +35 -0
- data/lib/aws/elb/client/xml.rb +33 -0
- data/lib/aws/elb/config.rb +18 -0
- data/lib/aws/elb/errors.rb +30 -0
- data/lib/aws/elb/instance_collection.rb +174 -0
- data/lib/aws/elb/listener.rb +189 -0
- data/lib/aws/elb/listener_collection.rb +119 -0
- data/lib/aws/elb/listener_opts.rb +45 -0
- data/lib/aws/elb/listener_spec.rb +14 -0
- data/lib/aws/elb/load_balancer.rb +255 -0
- data/lib/aws/elb/load_balancer_collection.rb +113 -0
- data/lib/aws/elb/load_balancer_policy.rb +93 -0
- data/lib/aws/elb/load_balancer_policy_collection.rb +208 -0
- data/lib/aws/elb/request.rb +23 -0
- data/lib/aws/iam/collection.rb +24 -26
- data/lib/aws/iam/group_user_collection.rb +21 -28
- data/lib/aws/iam/server_certificate_collection.rb +1 -37
- data/lib/aws/record.rb +1 -1
- data/lib/aws/record/base.rb +14 -1
- data/lib/aws/record/finder_methods.rb +4 -1
- data/lib/aws/record/validations.rb +73 -32
- data/lib/aws/{core/api_config_transform.rb → record/validators/method.rb} +9 -12
- data/lib/aws/s3/bucket_collection.rb +6 -4
- data/lib/aws/s3/client.rb +37 -6
- data/lib/aws/s3/config.rb +3 -1
- data/lib/aws/s3/prefixed_collection.rb +1 -2
- data/lib/aws/s3/presigned_post.rb +37 -4
- data/lib/aws/s3/s3_object.rb +93 -1
- data/lib/aws/simple_db/domain.rb +8 -0
- data/lib/aws/simple_db/item.rb +15 -0
- data/lib/aws/simple_db/item_collection.rb +255 -201
- data/lib/aws/simple_db/item_data.rb +1 -1
- data/lib/aws/simple_email_service/client.rb +0 -1
- data/lib/aws/sns/client.rb +0 -1
- metadata +107 -55
- data/lib/aws/core/collections.rb +0 -229
- data/lib/aws/simple_email_service/client/options.rb +0 -21
- data/lib/aws/sns/client/options.rb +0 -21
@@ -0,0 +1,35 @@
|
|
1
|
+
# Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
# http://aws.amazon.com/apache2.0/
|
8
|
+
#
|
9
|
+
# or in the "license" file accompanying this file. This file is
|
10
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
11
|
+
# ANY KIND, either express or implied. See the License for the specific
|
12
|
+
# language governing permissions and limitations under the License.
|
13
|
+
|
14
|
+
module AWS
|
15
|
+
class ELB
|
16
|
+
|
17
|
+
# @private
|
18
|
+
class Client < Core::Client
|
19
|
+
|
20
|
+
AWS.register_autoloads(self) do
|
21
|
+
autoload :XML, 'xml'
|
22
|
+
end
|
23
|
+
|
24
|
+
include Core::ConfiguredClientMethods
|
25
|
+
|
26
|
+
API_VERSION = '2011-08-15'
|
27
|
+
|
28
|
+
# @private
|
29
|
+
REQUEST_CLASS = ELB::Request
|
30
|
+
|
31
|
+
configure_client
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
# http://aws.amazon.com/apache2.0/
|
8
|
+
#
|
9
|
+
# or in the "license" file accompanying this file. This file is
|
10
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
11
|
+
# ANY KIND, either express or implied. See the License for the specific
|
12
|
+
# language governing permissions and limitations under the License.
|
13
|
+
|
14
|
+
module AWS
|
15
|
+
class ELB
|
16
|
+
class Client < Core::Client
|
17
|
+
|
18
|
+
# @private
|
19
|
+
module XML
|
20
|
+
|
21
|
+
include Core::ConfiguredXmlGrammars
|
22
|
+
extend Core::IgnoreResultElement
|
23
|
+
|
24
|
+
BaseError = Core::XmlGrammar.customize do
|
25
|
+
element("Error") { ignore }
|
26
|
+
end
|
27
|
+
|
28
|
+
define_configured_grammars
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
# http://aws.amazon.com/apache2.0/
|
8
|
+
#
|
9
|
+
# or in the "license" file accompanying this file. This file is
|
10
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
11
|
+
# ANY KIND, either express or implied. See the License for the specific
|
12
|
+
# language governing permissions and limitations under the License.
|
13
|
+
|
14
|
+
AWS::Core::Configuration.module_eval do
|
15
|
+
|
16
|
+
add_service 'ELB', 'elb', 'elasticloadbalancing.us-east-1.amazonaws.com'
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
# http://aws.amazon.com/apache2.0/
|
8
|
+
#
|
9
|
+
# or in the "license" file accompanying this file. This file is
|
10
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
11
|
+
# ANY KIND, either express or implied. See the License for the specific
|
12
|
+
# language governing permissions and limitations under the License.
|
13
|
+
|
14
|
+
module AWS
|
15
|
+
class ELB
|
16
|
+
|
17
|
+
# @private
|
18
|
+
module Errors
|
19
|
+
|
20
|
+
BASE_ERROR_GRAMMAR = Client::XML::BaseError
|
21
|
+
|
22
|
+
include Core::LazyErrorClasses
|
23
|
+
|
24
|
+
def self.error_class(code)
|
25
|
+
super(code.sub(/^ElasticLoadBalancing\./, ''))
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
# Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
# http://aws.amazon.com/apache2.0/
|
8
|
+
#
|
9
|
+
# or in the "license" file accompanying this file. This file is
|
10
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
11
|
+
# ANY KIND, either express or implied. See the License for the specific
|
12
|
+
# language governing permissions and limitations under the License.
|
13
|
+
|
14
|
+
module AWS
|
15
|
+
class ELB
|
16
|
+
|
17
|
+
class InstanceCollection
|
18
|
+
|
19
|
+
include Core::Collection::Simple
|
20
|
+
|
21
|
+
def initialize load_balancer, options = {}
|
22
|
+
@load_balancer = load_balancer
|
23
|
+
super
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns an {EC2::Instance} object with 3 extra methods added:
|
27
|
+
#
|
28
|
+
# * +#load_balancer+
|
29
|
+
#
|
30
|
+
# * +#remove_from_load_balancer+
|
31
|
+
#
|
32
|
+
# * +#elb_health+
|
33
|
+
#
|
34
|
+
# See {#health} for more information about what +#elb_health+ returns.
|
35
|
+
#
|
36
|
+
# @return [EC2::Instance] Return an EC2::Instance object with additional
|
37
|
+
# methods added.
|
38
|
+
#
|
39
|
+
def [] instance_id
|
40
|
+
|
41
|
+
load_balancer = self.load_balancer
|
42
|
+
|
43
|
+
instance = EC2.new(:config => config).instances[instance_id]
|
44
|
+
|
45
|
+
Core::MetaUtils.extend_method(instance, :load_balancer) do
|
46
|
+
load_balancer
|
47
|
+
end
|
48
|
+
|
49
|
+
Core::MetaUtils.extend_method(instance, :elb_health) do
|
50
|
+
health = load_balancer.instances.health(id).first
|
51
|
+
health.delete(:instance)
|
52
|
+
health
|
53
|
+
end
|
54
|
+
|
55
|
+
Core::MetaUtils.extend_method(instance, :remove_from_load_balancer) do
|
56
|
+
load_balancer.instances.deregister(self)
|
57
|
+
end
|
58
|
+
|
59
|
+
instance
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns an array of instance health descriptions. Each description
|
64
|
+
# is a hash with the following entries:
|
65
|
+
#
|
66
|
+
# * +:instance+ - The {EC2::Instance} being described.
|
67
|
+
#
|
68
|
+
# * +:description+ - Provides a description of the instance.
|
69
|
+
#
|
70
|
+
# * +:state+ - Specifies the current state of the instance.
|
71
|
+
#
|
72
|
+
# * +:reason_code+ - Provides information about the cause of
|
73
|
+
# OutOfService instances. Specifically, it indicates whether the
|
74
|
+
# cause is Elastic Load Balancing or the instance behind the
|
75
|
+
# load balancer.
|
76
|
+
#
|
77
|
+
# You can get the health of all instances for this load balancer
|
78
|
+
# by passing no arguments to this method:
|
79
|
+
#
|
80
|
+
# # get the health of all instances in the collection
|
81
|
+
# load_balancer.instances.health.each do |instance_health|
|
82
|
+
# puts "Instance: " + instance_health[:instance].id
|
83
|
+
# puts "description: " + instance_health[:description]
|
84
|
+
# puts "state: " + instance_health[:state]
|
85
|
+
# puts "reason code: " + instance_health[:reason_code]
|
86
|
+
# end
|
87
|
+
#
|
88
|
+
# If you want the health of a specific list of instances, pass
|
89
|
+
# instance ids or instance objects to this method:
|
90
|
+
#
|
91
|
+
# # get the health for a few specific instances
|
92
|
+
# load_balancer.instances.health('i-12345', 'i-67890').each{|h| ... }
|
93
|
+
#
|
94
|
+
# == Health for a Single Instance
|
95
|
+
#
|
96
|
+
# If you want the health of a single instance you can use the {#[]}
|
97
|
+
# instead:
|
98
|
+
#
|
99
|
+
# load_balancer.instances['i-123456'].elb_health
|
100
|
+
# # => { :state => ..., :reason_code => ..., :description => ... }
|
101
|
+
#
|
102
|
+
# @param [String,EC2::Instance] One or more instances to receive
|
103
|
+
# health information for.
|
104
|
+
#
|
105
|
+
# @return [Array<Hash>] Returns an array of hashes. Each hash represents
|
106
|
+
# the health of a single instance. Each hash includes the following
|
107
|
+
# entries:
|
108
|
+
#
|
109
|
+
def health *instances
|
110
|
+
|
111
|
+
instance_ids = instance_ids(instances)
|
112
|
+
|
113
|
+
opts = {}
|
114
|
+
opts[:load_balancer_name] = load_balancer.name
|
115
|
+
opts[:instances] = instance_ids unless instance_ids.empty?
|
116
|
+
|
117
|
+
client.describe_instance_health(opts).instance_states.map do |state|
|
118
|
+
{
|
119
|
+
:instance => self[state.instance_id],
|
120
|
+
:description => state.description,
|
121
|
+
:state => state.state,
|
122
|
+
:reason_code => state.reason_code,
|
123
|
+
}
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
# @return [LoadBalancer] Returns the load balancer this collection
|
129
|
+
# belongs to.
|
130
|
+
attr_reader :load_balancer
|
131
|
+
|
132
|
+
def register *instances
|
133
|
+
|
134
|
+
client.register_instances_with_load_balancer(
|
135
|
+
:load_balancer_name => load_balancer.name,
|
136
|
+
:instances => instance_ids(instances))
|
137
|
+
|
138
|
+
nil
|
139
|
+
|
140
|
+
end
|
141
|
+
alias_method :add, :register
|
142
|
+
|
143
|
+
def deregister *instances
|
144
|
+
|
145
|
+
client.deregister_instances_from_load_balancer(
|
146
|
+
:load_balancer_name => load_balancer.name,
|
147
|
+
:instances => instance_ids(instances))
|
148
|
+
|
149
|
+
nil
|
150
|
+
|
151
|
+
end
|
152
|
+
alias_method :remove, :deregister
|
153
|
+
|
154
|
+
protected
|
155
|
+
def instance_ids instances
|
156
|
+
instances.flatten.collect do |instance|
|
157
|
+
case instance
|
158
|
+
when EC2::Instance then { :instance_id => instance.id }
|
159
|
+
else { :instance_id => instance }
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
protected
|
165
|
+
def _each_item options = {}
|
166
|
+
load_balancer.instance_descriptions.each do |instance|
|
167
|
+
instance = self[instance.instance_id]
|
168
|
+
yield(instance)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
# Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
# http://aws.amazon.com/apache2.0/
|
8
|
+
#
|
9
|
+
# or in the "license" file accompanying this file. This file is
|
10
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
11
|
+
# ANY KIND, either express or implied. See the License for the specific
|
12
|
+
# language governing permissions and limitations under the License.
|
13
|
+
|
14
|
+
module AWS
|
15
|
+
class ELB
|
16
|
+
|
17
|
+
class Listener
|
18
|
+
|
19
|
+
include Core::Model
|
20
|
+
|
21
|
+
# @param [LoadBalancer] load_balancer The load balancer this listener
|
22
|
+
# belongs to.
|
23
|
+
#
|
24
|
+
# @param [Integer] port The external load balancer port number.
|
25
|
+
#
|
26
|
+
# @param [Hash] options
|
27
|
+
#
|
28
|
+
# @option (see ListenerCollection#create)
|
29
|
+
#
|
30
|
+
def initialize load_balancer, port, options = {}
|
31
|
+
|
32
|
+
@load_balancer = load_balancer
|
33
|
+
@port = port.to_i
|
34
|
+
@protocol = options[:protocol]
|
35
|
+
@instance_port = options[:instance_port]
|
36
|
+
@instance_protocol = options[:instance_protocol]
|
37
|
+
|
38
|
+
super
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [LoadBalancer]
|
43
|
+
attr_reader :load_balancer
|
44
|
+
|
45
|
+
# @return [Integer]
|
46
|
+
attr_reader :port
|
47
|
+
|
48
|
+
# @return [Symbol] Returns the protocl for this listener.
|
49
|
+
def protocol
|
50
|
+
proto = @protocol || _description.listener.protocol
|
51
|
+
proto.to_s.downcase.to_sym
|
52
|
+
end
|
53
|
+
|
54
|
+
# @return [Integer]
|
55
|
+
def instance_port
|
56
|
+
@instance_port || _description.listener.instance_port
|
57
|
+
end
|
58
|
+
|
59
|
+
# @return [Symbol]
|
60
|
+
def instance_protocol
|
61
|
+
proto = @instance_protocol || _description.listener.instance_protocol
|
62
|
+
proto.to_s.downcase.to_sym
|
63
|
+
end
|
64
|
+
|
65
|
+
# Sets the certificate that terminates the specified listener's SSL
|
66
|
+
# connections. The specified certificate replaces any prior
|
67
|
+
# certificate for this listener.
|
68
|
+
#
|
69
|
+
# @param [String,IAM::ServerCertificate] server_certificate The ARN
|
70
|
+
# of an IAM::ServerCertificate or an IAM::ServerCertificate object.
|
71
|
+
#
|
72
|
+
# @return [nil]
|
73
|
+
#
|
74
|
+
def server_certificate= server_certificate
|
75
|
+
|
76
|
+
arn = server_certificate.is_a?(IAM::ServerCertificate) ?
|
77
|
+
server_certificate.arn : server_certificate
|
78
|
+
|
79
|
+
client.set_load_balancer_listener_ssl_certificate(
|
80
|
+
:load_balancer_name => load_balancer.name,
|
81
|
+
:load_balancer_port => port,
|
82
|
+
:ssl_certificate_id => arn)
|
83
|
+
|
84
|
+
nil
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
# @return [IAM::ServerCertificate,nil] Returns the IAM::ServerCertificate
|
89
|
+
# associated with this listener, or nil if there is none.
|
90
|
+
def server_certificate
|
91
|
+
desc = _description
|
92
|
+
if desc.listener.respond_to?(:ssl_certificate_id)
|
93
|
+
AWS.memoize do
|
94
|
+
arn = desc.listener.ssl_certificate_id
|
95
|
+
iam = IAM.new(:config => config)
|
96
|
+
iam.server_certificates.find{|cert| cert.arn == arn }
|
97
|
+
end
|
98
|
+
else
|
99
|
+
nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# @return [LoadBalancerPolicy,nil] Returns the current policy for this
|
104
|
+
# listener. Returns nil if no load balancer policy has been
|
105
|
+
# associated with it.
|
106
|
+
def policy
|
107
|
+
policy_name = _description.policy_names.first
|
108
|
+
policy_name ? load_balancer.policies[policy_name] : nil
|
109
|
+
end
|
110
|
+
|
111
|
+
# @param [String,LoadBalancerPolicy] policy_or_policy_name Sets
|
112
|
+
# the policy for this listener.
|
113
|
+
# @return [LoadBalancerPolicy]
|
114
|
+
def policy= policy_or_policy_name
|
115
|
+
|
116
|
+
policy_name = policy_or_policy_name.is_a?(LoadBalancerPolicy) ?
|
117
|
+
policy_or_policy_name.name : policy_or_policy_name.to_s
|
118
|
+
|
119
|
+
client.set_load_balancer_policies_of_listener(
|
120
|
+
:load_balancer_name => load_balancer.name,
|
121
|
+
:load_balancer_port => port,
|
122
|
+
:policy_names => [policy_name])
|
123
|
+
|
124
|
+
LoadBalancerPolicy.new(load_balancer, policy_name, :config => config)
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
# Removes the current policy from this listener.
|
129
|
+
# @return [nil]
|
130
|
+
def remove_policy
|
131
|
+
|
132
|
+
client.set_load_balancer_policies_of_listener(
|
133
|
+
:load_balancer_name => load_balancer.name,
|
134
|
+
:load_balancer_port => port,
|
135
|
+
:policy_names => [])
|
136
|
+
|
137
|
+
nil
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
# Returns true if this listener exists.
|
142
|
+
#
|
143
|
+
# load_balancer = ELB.new.load_balancers['my-load-balancer']
|
144
|
+
# listener = load_balancer.listeners[80] # port 80
|
145
|
+
# listener.exists?
|
146
|
+
#
|
147
|
+
# @return [Boolean] Returns true if the load balancer has a listener
|
148
|
+
# on this port.
|
149
|
+
def exists?
|
150
|
+
!_description.nil?
|
151
|
+
rescue AWS::Core::Resource::NotFound
|
152
|
+
false
|
153
|
+
end
|
154
|
+
|
155
|
+
# Deletes the listener from its load balancer.
|
156
|
+
# @return [nil]
|
157
|
+
def delete
|
158
|
+
|
159
|
+
client.delete_load_balancer_listeners(
|
160
|
+
:load_balancer_name => load_balancer.name,
|
161
|
+
:load_balancer_ports => [port])
|
162
|
+
|
163
|
+
nil
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
# @private
|
168
|
+
def inspect
|
169
|
+
"#{self.class.name} port:#{port}>"
|
170
|
+
end
|
171
|
+
|
172
|
+
# @private
|
173
|
+
def == other
|
174
|
+
other.is_a?(Listener) and
|
175
|
+
other.load_balancer == load_balancer and
|
176
|
+
other.port == port
|
177
|
+
end
|
178
|
+
alias_method :eql?, :==
|
179
|
+
|
180
|
+
protected
|
181
|
+
def _description
|
182
|
+
load_balancer.listener_descriptions.find do |desc|
|
183
|
+
desc.listener.load_balancer_port == port
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|