qpid_proton 0.18.1 → 0.19.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/ext/cproton/cproton.c +863 -75
- data/lib/codec/data.rb +589 -815
- data/lib/codec/mapping.rb +142 -126
- data/lib/core/condition.rb +89 -0
- data/lib/core/connection.rb +188 -228
- data/lib/core/connection_driver.rb +202 -0
- data/lib/core/container.rb +366 -0
- data/lib/core/delivery.rb +76 -251
- data/lib/core/disposition.rb +21 -35
- data/lib/core/endpoint.rb +21 -53
- data/lib/core/event.rb +156 -0
- data/lib/core/exceptions.rb +109 -106
- data/lib/core/link.rb +24 -49
- data/lib/core/listener.rb +82 -0
- data/lib/core/message.rb +59 -155
- data/lib/core/messaging_handler.rb +190 -0
- data/lib/core/receiver.rb +38 -7
- data/lib/core/sasl.rb +43 -46
- data/lib/core/sender.rb +55 -32
- data/lib/core/session.rb +58 -58
- data/lib/core/ssl.rb +5 -13
- data/lib/core/ssl_details.rb +1 -2
- data/lib/core/ssl_domain.rb +5 -8
- data/lib/core/terminus.rb +62 -30
- data/lib/core/tracker.rb +45 -0
- data/lib/core/transfer.rb +121 -0
- data/lib/core/transport.rb +62 -97
- data/lib/core/uri.rb +73 -0
- data/lib/core/url.rb +11 -7
- data/lib/handler/adapter.rb +78 -0
- data/lib/handler/messaging_adapter.rb +127 -0
- data/lib/handler/messaging_handler.rb +128 -178
- data/lib/handler/reactor_messaging_adapter.rb +158 -0
- data/lib/messenger/messenger.rb +9 -8
- data/lib/messenger/subscription.rb +1 -2
- data/lib/messenger/tracker.rb +1 -2
- data/lib/messenger/tracker_status.rb +1 -2
- data/lib/qpid_proton.rb +36 -66
- data/lib/reactor/container.rb +40 -234
- data/lib/types/array.rb +73 -130
- data/lib/types/described.rb +2 -44
- data/lib/types/hash.rb +19 -56
- data/lib/types/strings.rb +1 -2
- data/lib/types/type.rb +68 -0
- data/lib/util/{handler.rb → deprecation.rb} +22 -15
- data/lib/util/error_handler.rb +4 -25
- data/lib/util/timeout.rb +1 -2
- data/lib/util/version.rb +1 -2
- data/lib/util/wrapper.rb +58 -38
- metadata +16 -33
- data/lib/core/base_handler.rb +0 -31
- data/lib/core/selectable.rb +0 -130
- data/lib/event/collector.rb +0 -148
- data/lib/event/event.rb +0 -318
- data/lib/event/event_base.rb +0 -91
- data/lib/event/event_type.rb +0 -71
- data/lib/handler/acking.rb +0 -70
- data/lib/handler/c_adaptor.rb +0 -47
- data/lib/handler/c_flow_controller.rb +0 -33
- data/lib/handler/endpoint_state_handler.rb +0 -217
- data/lib/handler/incoming_message_handler.rb +0 -74
- data/lib/handler/outgoing_message_handler.rb +0 -100
- data/lib/handler/wrapped_handler.rb +0 -76
- data/lib/reactor/acceptor.rb +0 -41
- data/lib/reactor/backoff.rb +0 -41
- data/lib/reactor/connector.rb +0 -115
- data/lib/reactor/global_overrides.rb +0 -44
- data/lib/reactor/link_option.rb +0 -90
- data/lib/reactor/reactor.rb +0 -196
- data/lib/reactor/session_per_connection.rb +0 -45
- data/lib/reactor/ssl_config.rb +0 -41
- data/lib/reactor/task.rb +0 -39
- data/lib/reactor/urls.rb +0 -45
- data/lib/util/class_wrapper.rb +0 -54
- data/lib/util/condition.rb +0 -47
- data/lib/util/constants.rb +0 -85
- data/lib/util/engine.rb +0 -82
- data/lib/util/reactor.rb +0 -32
- data/lib/util/swig_helper.rb +0 -114
- data/lib/util/uuid.rb +0 -32
@@ -1,44 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Licensed to the Apache Software Foundation (ASF) under one
|
3
|
-
# or more contributor license agreements. See the NOTICE file
|
4
|
-
# distributed with this work for additional information
|
5
|
-
# regarding copyright ownership. The ASF licenses this file
|
6
|
-
# to you under the Apache License, Version 2.0 (the
|
7
|
-
# "License"); you may not use this file except in compliance
|
8
|
-
# with the License. You may obtain a copy of the License at
|
9
|
-
#
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
12
|
-
# Unless required by applicable law or agreed to in writing,
|
13
|
-
# software distributed under the License is distributed on an
|
14
|
-
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
15
|
-
# KIND, either express or implied. See the License for the
|
16
|
-
# specific language governing permissions and limitations
|
17
|
-
# under the License.
|
18
|
-
#++
|
19
|
-
|
20
|
-
module Qpid::Proton::Reactor
|
21
|
-
|
22
|
-
class GlobalOverrides
|
23
|
-
|
24
|
-
def initialize(base)
|
25
|
-
@base = base
|
26
|
-
end
|
27
|
-
|
28
|
-
def on_unhandled(name, event)
|
29
|
-
event.dispatch(@base) unless self.override?(event)
|
30
|
-
end
|
31
|
-
|
32
|
-
def override?(event)
|
33
|
-
conn = event.connection
|
34
|
-
if !conn.nil? && conn.overrides?
|
35
|
-
overrides = conn.overrides
|
36
|
-
result = event.dispatch(overrides)
|
37
|
-
return result
|
38
|
-
end
|
39
|
-
false
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
data/lib/reactor/link_option.rb
DELETED
@@ -1,90 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Licensed to the Apache Software Foundation (ASF) under one
|
3
|
-
# or more contributor license agreements. See the NOTICE file
|
4
|
-
# distributed with this work for additional information
|
5
|
-
# regarding copyright ownership. The ASF licenses this file
|
6
|
-
# to you under the Apache License, Version 2.0 (the
|
7
|
-
# "License"); you may not use this file except in compliance
|
8
|
-
# with the License. You may obtain a copy of the License at
|
9
|
-
#
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
12
|
-
# Unless required by applicable law or agreed to in writing,
|
13
|
-
# software distributed under the License is distributed on an
|
14
|
-
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
15
|
-
# KIND, either express or implied. See the License for the
|
16
|
-
# specific language governing permissions and limitations
|
17
|
-
# under the License.
|
18
|
-
#++
|
19
|
-
|
20
|
-
module Qpid::Proton::Reactor
|
21
|
-
|
22
|
-
class LinkOption
|
23
|
-
def apply(link)
|
24
|
-
end
|
25
|
-
|
26
|
-
# Subclasses should override this to selectively apply an option.
|
27
|
-
def test(link)
|
28
|
-
true
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
class AtMostOne < LinkOption
|
33
|
-
def apply(link)
|
34
|
-
link.snd_settle_mod = Link::SND_SETTLED
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
class AtLeastOnce < LinkOption
|
39
|
-
def apply(link)
|
40
|
-
link.snd_settle_mode = Link::SND_UNSETTLED
|
41
|
-
link.rcv_settle_mode = Link::RCV_FIRST
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
class SenderOption < LinkOption
|
46
|
-
def test(link)
|
47
|
-
link.sender?
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
class ReceiverOption < LinkOption
|
52
|
-
def test(link)
|
53
|
-
link.receiver?
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
class DynamicNodeProperties < LinkOption
|
58
|
-
def initialize(properties = {})
|
59
|
-
@properties = []
|
60
|
-
properties.each do |property|
|
61
|
-
@properties << property.to_sym
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def apply(link)
|
66
|
-
if link.receiver?
|
67
|
-
link.source.properties.dict = @properties
|
68
|
-
else
|
69
|
-
link.target.properties.dict = @properties
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
class Filter < ReceiverOption
|
75
|
-
def initialize(filter_set = {})
|
76
|
-
@filter_set = filter_set
|
77
|
-
end
|
78
|
-
|
79
|
-
def apply(receiver)
|
80
|
-
receiver.source.filter.dict = @filter_set
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
#class Selector < Filter
|
85
|
-
# def initialize(value, name = 'selector')
|
86
|
-
#
|
87
|
-
# end
|
88
|
-
#end
|
89
|
-
|
90
|
-
end
|
data/lib/reactor/reactor.rb
DELETED
@@ -1,196 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Licensed to the Apache Software Foundation (ASF) under one
|
3
|
-
# or more contributor license agreements. See the NOTICE file
|
4
|
-
# distributed with this work for additional information
|
5
|
-
# regarding copyright ownership. The ASF licenses this file
|
6
|
-
# to you under the Apache License, Version 2.0 (the
|
7
|
-
# "License"); you may not use this file except in compliance
|
8
|
-
# with the License. You may obtain a copy of the License at
|
9
|
-
#
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
12
|
-
# Unless required by applicable law or agreed to in writing,
|
13
|
-
# software distributed under the License is distributed on an
|
14
|
-
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
15
|
-
# KIND, either express or implied. See the License for the
|
16
|
-
# specific language governing permissions and limitations
|
17
|
-
# under the License.
|
18
|
-
#++
|
19
|
-
|
20
|
-
module Qpid::Proton::Reactor
|
21
|
-
|
22
|
-
class Reactor
|
23
|
-
|
24
|
-
include Qpid::Proton::Util::Handler
|
25
|
-
|
26
|
-
# @private
|
27
|
-
include Qpid::Proton::Util::SwigHelper
|
28
|
-
|
29
|
-
# @private
|
30
|
-
PROTON_METHOD_PREFIX = "pn_reactor"
|
31
|
-
|
32
|
-
proton_caller :yield
|
33
|
-
|
34
|
-
proton_caller :mark
|
35
|
-
|
36
|
-
proton_caller :start
|
37
|
-
|
38
|
-
proton_caller :stop
|
39
|
-
|
40
|
-
# @private
|
41
|
-
include Qpid::Proton::Util::Timeout
|
42
|
-
|
43
|
-
include Qpid::Proton::Util::Wrapper
|
44
|
-
|
45
|
-
attr_reader :errors
|
46
|
-
|
47
|
-
def self.wrap(impl)
|
48
|
-
return nil if impl.nil?
|
49
|
-
|
50
|
-
self.fetch_instance(impl, :pn_reactor_attachments) || Reactor.new(nil, :impl => impl)
|
51
|
-
end
|
52
|
-
|
53
|
-
def initialize(handlers, options = {})
|
54
|
-
@impl = options[:impl]
|
55
|
-
if @impl.nil?
|
56
|
-
@impl = Cproton.pn_reactor
|
57
|
-
end
|
58
|
-
if !handlers.nil?
|
59
|
-
[handlers].flatten.each {|handler| self.handler.add(handler)}
|
60
|
-
end
|
61
|
-
@errors = []
|
62
|
-
@handlers = []
|
63
|
-
self.class.store_instance(self, :pn_reactor_attachments)
|
64
|
-
end
|
65
|
-
|
66
|
-
# Returns whether the reactor has any unbuffered data.
|
67
|
-
#
|
68
|
-
# @return [Boolean] True if there is no unbuffered data.
|
69
|
-
#
|
70
|
-
def quiesced?
|
71
|
-
Cproton.pn_reactor_quiesced(@impl)
|
72
|
-
end
|
73
|
-
|
74
|
-
def on_error(info)
|
75
|
-
self.errors << info
|
76
|
-
self.yield
|
77
|
-
end
|
78
|
-
|
79
|
-
def global_handler
|
80
|
-
impl = Cproton.pn_reactor_get_global_handler(@impl)
|
81
|
-
Qpid::Proton::Handler::WrappedHandler.wrap(impl, self.method(:on_error))
|
82
|
-
end
|
83
|
-
|
84
|
-
def global_handler=(handler)
|
85
|
-
impl = chandler(handler, self.method(:on_error))
|
86
|
-
Cproton.pn_reactor_set_global_handler(@impl, impl)
|
87
|
-
Cproton.pn_decref(impl)
|
88
|
-
end
|
89
|
-
|
90
|
-
# Returns the timeout period.
|
91
|
-
#
|
92
|
-
# @return [Integer] The timeout period, in seconds.
|
93
|
-
#
|
94
|
-
def timeout
|
95
|
-
millis_to_timeout(Cproton.pn_reactor_get_timeout(@impl))
|
96
|
-
end
|
97
|
-
|
98
|
-
# Sets the timeout period.
|
99
|
-
#
|
100
|
-
# @param timeout [Integer] The timeout, in seconds.
|
101
|
-
#
|
102
|
-
def timeout=(timeout)
|
103
|
-
Cproton.pn_reactor_set_timeout(@impl, timeout_to_millis(timeout))
|
104
|
-
end
|
105
|
-
|
106
|
-
def handler
|
107
|
-
impl = Cproton.pn_reactor_get_handler(@impl)
|
108
|
-
Qpid::Proton::Handler::WrappedHandler.wrap(impl, self.method(:on_error))
|
109
|
-
end
|
110
|
-
|
111
|
-
def handler=(handler)
|
112
|
-
impl = chandler(handler, set.method(:on_error))
|
113
|
-
Cproton.pn_reactor_set_handler(@impl, impl)
|
114
|
-
Cproton.pn_decref(impl)
|
115
|
-
end
|
116
|
-
|
117
|
-
def run(&block)
|
118
|
-
self.timeout = 3.14159265359
|
119
|
-
self.start
|
120
|
-
while self.process do
|
121
|
-
if block_given?
|
122
|
-
yield
|
123
|
-
end
|
124
|
-
end
|
125
|
-
self.stop
|
126
|
-
end
|
127
|
-
|
128
|
-
def wakeup
|
129
|
-
n = Cproton.pn_reactor_wakeup(@impl)
|
130
|
-
unless n.zero?
|
131
|
-
raise IOError.new(Cproton.pn_reactor_error(@impl))
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
def process
|
136
|
-
result = Cproton.pn_reactor_process(@impl)
|
137
|
-
if !self.errors.nil? && !self.errors.empty?
|
138
|
-
(0...self.errors.size).each do |index|
|
139
|
-
error_set = self.errors[index]
|
140
|
-
print error.backtrace.join("\n")
|
141
|
-
end
|
142
|
-
raise self.errors.last
|
143
|
-
end
|
144
|
-
return result
|
145
|
-
end
|
146
|
-
|
147
|
-
def schedule(delay, task)
|
148
|
-
impl = chandler(task, self.method(:on_error))
|
149
|
-
task = Task.wrap(Cproton.pn_reactor_schedule(@impl, sec_to_millis(delay), impl))
|
150
|
-
Cproton.pn_decref(impl)
|
151
|
-
return task
|
152
|
-
end
|
153
|
-
|
154
|
-
def acceptor(host, port, handler = nil)
|
155
|
-
impl = chandler(handler, self.method(:on_error))
|
156
|
-
aimpl = Cproton.pn_reactor_acceptor(@impl, host, "#{port}", impl)
|
157
|
-
Cproton.pn_decref(impl)
|
158
|
-
if !aimpl.nil?
|
159
|
-
return Acceptor.new(aimpl)
|
160
|
-
else
|
161
|
-
io_error = Cproton.pn_reactor_error(@impl)
|
162
|
-
error_text = Cproton.pn_error_text(io_error)
|
163
|
-
text = "(#{Cproton.pn_error_text(io_error)} (#{host}:#{port}))"
|
164
|
-
raise IOError.new(text)
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
def connection(handler = nil)
|
169
|
-
impl = chandler(handler, self.method(:on_error))
|
170
|
-
conn = Qpid::Proton::Connection.wrap(Cproton.pn_reactor_connection(@impl, impl))
|
171
|
-
Cproton.pn_decref(impl)
|
172
|
-
return conn
|
173
|
-
end
|
174
|
-
|
175
|
-
def selectable(handler = nil)
|
176
|
-
impl = chandler(handler, self.method(:on_error))
|
177
|
-
result = Selectable.wrap(Cproton.pn_reactor_selectable(@impl))
|
178
|
-
if !impl.nil?
|
179
|
-
record = Cproton.pn_selectable_attachments(result.impl)
|
180
|
-
Cproton.pn_record_set_handler(record, impl)
|
181
|
-
Cproton.pn_decref(impl)
|
182
|
-
end
|
183
|
-
return result
|
184
|
-
end
|
185
|
-
|
186
|
-
def update(sel)
|
187
|
-
Cproton.pn_reactor_update(@impl, sel.impl)
|
188
|
-
end
|
189
|
-
|
190
|
-
def push_event(obj, etype)
|
191
|
-
Cproton.pn_collector_put(Cproton.pn_reactor_collector(@impl), Qpid::Proton::Util::RBCTX, Cproton.pn_py2void(obj), etype.number)
|
192
|
-
end
|
193
|
-
|
194
|
-
end
|
195
|
-
|
196
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Licensed to the Apache Software Foundation (ASF) under one
|
3
|
-
# or more contributor license agreements. See the NOTICE file
|
4
|
-
# distributed with this work for additional information
|
5
|
-
# regarding copyright ownership. The ASF licenses this file
|
6
|
-
# to you under the Apache License, Version 2.0 (the
|
7
|
-
# "License"); you may not use this file except in compliance
|
8
|
-
# with the License. You may obtain a copy of the License at
|
9
|
-
#
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
12
|
-
# Unless required by applicable law or agreed to in writing,
|
13
|
-
# software distributed under the License is distributed on an
|
14
|
-
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
15
|
-
# KIND, either express or implied. See the License for the
|
16
|
-
# specific language governing permissions and limitations
|
17
|
-
# under the License.
|
18
|
-
#++
|
19
|
-
|
20
|
-
module Qpid::Proton::Reactor
|
21
|
-
|
22
|
-
class SessionPerConnection
|
23
|
-
|
24
|
-
include Qpid::Proton::Util::Reactor
|
25
|
-
|
26
|
-
def initialize
|
27
|
-
@default_session = nil
|
28
|
-
end
|
29
|
-
|
30
|
-
def session(connection)
|
31
|
-
if @default_session.nil?
|
32
|
-
@default_session = self.create_session
|
33
|
-
@default_session.context = self
|
34
|
-
end
|
35
|
-
return @default_session
|
36
|
-
end
|
37
|
-
|
38
|
-
def on_session_remote_close(event)
|
39
|
-
event.connection.close
|
40
|
-
@default_session = nil
|
41
|
-
end
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
data/lib/reactor/ssl_config.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Licensed to the Apache Software Foundation (ASF) under one
|
3
|
-
# or more contributor license agreements. See the NOTICE file
|
4
|
-
# distributed with this work for additional information
|
5
|
-
# regarding copyright ownership. The ASF licenses this file
|
6
|
-
# to you under the Apache License, Version 2.0 (the
|
7
|
-
# "License"); you may not use this file except in compliance
|
8
|
-
# with the License. You may obtain a copy of the License at
|
9
|
-
#
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
12
|
-
# Unless required by applicable law or agreed to in writing,
|
13
|
-
# software distributed under the License is distributed on an
|
14
|
-
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
15
|
-
# KIND, either express or implied. See the License for the
|
16
|
-
# specific language governing permissions and limitations
|
17
|
-
# under the License.
|
18
|
-
#++
|
19
|
-
|
20
|
-
module Qpid::Proton::Reactor
|
21
|
-
|
22
|
-
class SSLConfig
|
23
|
-
|
24
|
-
def initialize
|
25
|
-
@client = Qpid::Proton::SSLDomain.new(Qpid::Proton::SSLDomain::MODE_CLIENT)
|
26
|
-
@server = Qpid::Proton::SSLDomain.new(Qpid::Proton::SSLDomain::MODE_SERVER)
|
27
|
-
end
|
28
|
-
|
29
|
-
def set_credentials(cert_file, key_file, password)
|
30
|
-
@client.set_credentials(cert_file, key_file, password)
|
31
|
-
@server.set_credentials(cert_file, key_file, password)
|
32
|
-
end
|
33
|
-
|
34
|
-
def set_trusted_ca_db(certificate_db)
|
35
|
-
@client.set_trusted_ca_db(certificate_db)
|
36
|
-
@server.set_trusted_ca_db(certificate_db)
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
data/lib/reactor/task.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Licensed to the Apache Software Foundation (ASF) under one
|
3
|
-
# or more contributor license agreements. See the NOTICE file
|
4
|
-
# distributed with this work for additional information
|
5
|
-
# regarding copyright ownership. The ASF licenses this file
|
6
|
-
# to you under the Apache License, Version 2.0 (the
|
7
|
-
# "License"); you may not use this file except in compliance
|
8
|
-
# with the License. You may obtain a copy of the License at
|
9
|
-
#
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
-
#
|
12
|
-
# Unless required by applicable law or agreed to in writing,
|
13
|
-
# software distributed under the License is distributed on an
|
14
|
-
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
15
|
-
# KIND, either express or implied. See the License for the
|
16
|
-
# specific language governing permissions and limitations
|
17
|
-
# under the License.
|
18
|
-
#++
|
19
|
-
|
20
|
-
module Qpid::Proton::Reactor
|
21
|
-
|
22
|
-
class Task
|
23
|
-
|
24
|
-
# @private
|
25
|
-
include Qpid::Proton::Util::Wrapper
|
26
|
-
|
27
|
-
def self.wrap(impl)
|
28
|
-
return nil if impl.nil?
|
29
|
-
self.fetch_instance(impl, :pn_task_attachments) || Task.new(impl)
|
30
|
-
end
|
31
|
-
|
32
|
-
def initialize(impl)
|
33
|
-
@impl = impl
|
34
|
-
self.class.store_instance(self, :pn_task_attachments)
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|