riddl 0.101.26 → 0.102
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/examples/declaration-server-distributed/declaration.rb +1 -1
- data/examples/declaration-server-distributed/declaration.xml +4 -4
- data/examples/declaration-server-distributed/main.rb +4 -4
- data/examples/declaration-server-distributed/properties.rb +5 -5
- data/examples/declaration-server-distributed/xsloverlay.rb +1 -1
- data/examples/declaration-server-hybrid/declaration.rb +6 -6
- data/examples/declaration-server-hybrid/declaration.xml +2 -2
- data/examples/declaration-server-hybrid/xsloverlay.rb +1 -1
- data/examples/declaration-server-local/declaration.rb +5 -5
- data/examples/declaration-test/main.rb +5 -5
- data/examples/downloadify/client.rb +1 -1
- data/examples/downloadify/server.rb +2 -2
- data/examples/flickr/declaration.xml +1 -1
- data/examples/library/server.rb +1 -1
- data/examples/notifications/producer.rb +3 -3
- data/examples/properties/server.properties.xml +1 -1
- data/lib/ruby/riddl/handlers/plain-type.rb +1 -1
- data/lib/ruby/riddl/wrapper.rb +12 -5
- data/riddl.gemspec +2 -2
- data/test/smartrunner.rb +21 -14
- data/test/tc_declaration-distributed.rb +1 -0
- data/test/tc_websocket.rb +16 -15
- metadata +3 -13
- data/examples/xmpp/blather/description.xml +0 -981
- data/examples/xmpp/blather/direct.rb +0 -44
- data/examples/xmpp/blather/load.rb +0 -18
- data/examples/xmpp/blather/pp.rb +0 -40
- data/examples/xmpp/blather/test.rb +0 -32
- data/examples/xmpp/client.rb +0 -20
- data/examples/xmpp/description.rb +0 -17
- data/examples/xmpp/properties.xml +0 -1
- data/examples/xmpp/server.properties.schema +0 -34
- data/examples/xmpp/server.properties.xml +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 02d6544bef02c48146f11bcce856f60a78b782678028a61d877c8e191b26a9c3
|
4
|
+
data.tar.gz: 03f040ece9e74f900ecb93e4961afe7a8f26951b84f33a083c9acc2f30cca1c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 405ed0327b0e51c6dba40b3e08476fce1f3888d05719e3741ec67d75d2061106c8a41d75e0c09beb2318e9ac06cbf49e922389737e614906be14c033e6daabf5
|
7
|
+
data.tar.gz: 89ecf78f0fb11bf552bc9fd8d1b4bb5585c04c266903c19531544e7fe15679f9b617d89e6263d2805d583bb80c5cf6fe69a498fb4c6642164cb9ac859c33fc1b
|
@@ -1,4 +1,4 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + '/../../lib/ruby/riddl/server')
|
3
3
|
|
4
|
-
Riddl::Server.new(File.dirname(__FILE__) + '/declaration.xml', :port =>
|
4
|
+
Riddl::Server.new(File.dirname(__FILE__) + '/declaration.xml', :port => 9004).loop!
|
@@ -1,13 +1,13 @@
|
|
1
1
|
<declaration xmlns="http://riddl.org/ns/declaration/1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
|
2
|
-
<interface name="main" location="http://localhost:
|
2
|
+
<interface name="main" location="http://localhost:9003">
|
3
3
|
<xi:include href="main.xml"/>
|
4
4
|
</interface>
|
5
|
-
<interface name="properties" location="http://localhost:
|
5
|
+
<interface name="properties" location="http://localhost:9002">
|
6
6
|
<xi:include href="properties.xml"/>
|
7
7
|
</interface>
|
8
|
-
<interface name="xsloverlay" location='http://localhost:
|
8
|
+
<interface name="xsloverlay" location='http://localhost:9001'>
|
9
9
|
<xi:include href="xsloverlay.xml"/>
|
10
|
-
</interface>
|
10
|
+
</interface>
|
11
11
|
|
12
12
|
<facade>
|
13
13
|
<tile>
|
@@ -20,16 +20,16 @@ class Info < Riddl::Implementation
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
Riddl::Server.new(File.dirname(__FILE__) + '/main.xml', :port =>
|
23
|
+
Riddl::Server.new(File.dirname(__FILE__) + '/main.xml', :port => 9003) do
|
24
24
|
on resource do
|
25
25
|
run Riddl::Utils::FileServe, 'instances/instances.xml' if get '*'
|
26
26
|
on resource do
|
27
27
|
run Info if get
|
28
|
-
end
|
28
|
+
end
|
29
29
|
on resource 'xsls' do
|
30
30
|
on resource do
|
31
31
|
run Riddl::Utils::FileServe, "xsls" if get
|
32
|
-
end
|
33
|
-
end
|
32
|
+
end
|
33
|
+
end
|
34
34
|
end
|
35
35
|
end.loop!
|
@@ -3,17 +3,17 @@ require 'pp'
|
|
3
3
|
require File.expand_path(File.dirname(__FILE__) + '/../../lib/ruby/riddl/server')
|
4
4
|
require File.expand_path(File.dirname(__FILE__) + '/../../lib/ruby/riddl/utils/properties')
|
5
5
|
|
6
|
-
Riddl::Server.new(File.dirname(__FILE__) + '/properties.xml', :port =>
|
6
|
+
Riddl::Server.new(File.dirname(__FILE__) + '/properties.xml', :port => 9002) do
|
7
7
|
on resource do |r|
|
8
8
|
### header RIDDL_DECLARATION_PATH holds the full path used in the declaration
|
9
9
|
### from there we get the instance, which is not present in the path used for properties
|
10
10
|
properties = if r[:h]['RIDDL_DECLARATION_PATH']
|
11
11
|
@riddl_opts[:basepath] + '/instances/' + r[:h]['RIDDL_DECLARATION_PATH'].split('/')[1] + '/properties.xml'
|
12
|
-
else
|
12
|
+
else
|
13
13
|
@riddl_opts[:basepath] + '/instances/1/properties.xml'
|
14
|
-
end
|
15
|
-
backend = Riddl::Utils::Properties::Backend.new(
|
16
|
-
@riddl_opts[:basepath] + '/instances/properties.schema',
|
14
|
+
end
|
15
|
+
backend = Riddl::Utils::Properties::Backend.new(
|
16
|
+
@riddl_opts[:basepath] + '/instances/properties.schema',
|
17
17
|
properties
|
18
18
|
)
|
19
19
|
|
@@ -3,7 +3,7 @@ require 'pp'
|
|
3
3
|
require File.expand_path(File.dirname(__FILE__) + '/../../lib/ruby/riddl/server')
|
4
4
|
require File.expand_path(File.dirname(__FILE__) + '/../../lib/ruby/riddl/utils/xsloverlay')
|
5
5
|
|
6
|
-
Riddl::Server.new(File.dirname(__FILE__) + '/xsloverlay.xml', :port =>
|
6
|
+
Riddl::Server.new(File.dirname(__FILE__) + '/xsloverlay.xml', :port => 9001) do
|
7
7
|
on resource do
|
8
8
|
run Riddl::Utils::XSLOverlay, "/xsls/instances.xsl" if get && declaration_resource == '/'
|
9
9
|
run Riddl::Utils::XSLOverlay, "/xsls/info.xsl" if get && declaration_resource == '/{}'
|
@@ -21,25 +21,25 @@ class Info < Riddl::Implementation
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
Riddl::Server.new(File.dirname(__FILE__) + '/declaration.xml', :port =>
|
24
|
+
Riddl::Server.new(File.dirname(__FILE__) + '/declaration.xml', :port => 9002) do
|
25
25
|
accessible_description true
|
26
26
|
|
27
27
|
interface 'main' do
|
28
28
|
run Riddl::Utils::FileServe, 'instances/instances.xml' if get '*'
|
29
29
|
on resource do
|
30
30
|
run Info if get
|
31
|
-
end
|
31
|
+
end
|
32
32
|
on resource 'xsls' do
|
33
33
|
on resource do
|
34
34
|
run Riddl::Utils::FileServe, "xsls" if get
|
35
|
-
end
|
36
|
-
end
|
35
|
+
end
|
36
|
+
end
|
37
37
|
end
|
38
38
|
|
39
39
|
interface 'properties' do |r|
|
40
40
|
properties = @riddl_opts[:basepath] + '/instances/' + r[:h]['RIDDL_DECLARATION_PATH'].split('/')[1] + '/properties.xml'
|
41
|
-
backend = Riddl::Utils::Properties::Backend.new(
|
42
|
-
@riddl_opts[:basepath] + '/instances/properties.schema',
|
41
|
+
backend = Riddl::Utils::Properties::Backend.new(
|
42
|
+
@riddl_opts[:basepath] + '/instances/properties.schema',
|
43
43
|
properties
|
44
44
|
)
|
45
45
|
|
@@ -5,9 +5,9 @@
|
|
5
5
|
<interface name="properties">
|
6
6
|
<xi:include href="properties.xml"/>
|
7
7
|
</interface>
|
8
|
-
<interface name="xsloverlay" location='http://localhost:
|
8
|
+
<interface name="xsloverlay" location='http://localhost:9001'>
|
9
9
|
<xi:include href="xsloverlay.xml"/>
|
10
|
-
</interface>
|
10
|
+
</interface>
|
11
11
|
|
12
12
|
<facade>
|
13
13
|
<tile>
|
@@ -3,7 +3,7 @@ require 'pp'
|
|
3
3
|
require File.expand_path(File.dirname(__FILE__) + '/../../lib/ruby/riddl/server')
|
4
4
|
require File.expand_path(File.dirname(__FILE__) + '/../../lib/ruby/riddl/utils/xsloverlay')
|
5
5
|
|
6
|
-
Riddl::Server.new(File.dirname(__FILE__) + '/xsloverlay.xml', :port =>
|
6
|
+
Riddl::Server.new(File.dirname(__FILE__) + '/xsloverlay.xml', :port => 9001) do
|
7
7
|
# accessible_description true
|
8
8
|
|
9
9
|
on resource do
|
@@ -5,12 +5,12 @@ require File.expand_path(File.dirname(__FILE__) + '/../../lib/ruby/riddl/utils/p
|
|
5
5
|
require File.expand_path(File.dirname(__FILE__) + '/../../lib/ruby/riddl/utils/xsloverlay')
|
6
6
|
require File.expand_path(File.dirname(__FILE__) + '/../../lib/ruby/riddl/utils/fileserve')
|
7
7
|
|
8
|
-
Riddl::Server.new(File.dirname(__FILE__) + '/declaration.xml', :port =>
|
8
|
+
Riddl::Server.new(File.dirname(__FILE__) + '/declaration.xml', :port => 9001) do
|
9
9
|
accessible_description true
|
10
10
|
|
11
|
-
backend = Riddl::Utils::Properties::Backend.new(
|
12
|
-
@riddl_opts[:basepath] + '/server.properties.schema',
|
13
|
-
@riddl_opts[:basepath] + '/server.properties.xml'
|
11
|
+
backend = Riddl::Utils::Properties::Backend.new(
|
12
|
+
@riddl_opts[:basepath] + '/server.properties.schema',
|
13
|
+
@riddl_opts[:basepath] + '/server.properties.xml'
|
14
14
|
)
|
15
15
|
|
16
16
|
interface 'main' do
|
@@ -20,7 +20,7 @@ Riddl::Server.new(File.dirname(__FILE__) + '/declaration.xml', :port => 9292) do
|
|
20
20
|
interface 'xsls' do |r|
|
21
21
|
on resource do
|
22
22
|
run Riddl::Utils::FileServe, "xsls" if get
|
23
|
-
end
|
23
|
+
end
|
24
24
|
end
|
25
25
|
|
26
26
|
interface 'xsloverlay' do
|
@@ -7,24 +7,24 @@ class A < Riddl::Implementation
|
|
7
7
|
def response
|
8
8
|
Riddl::Parameter::Simple.new("x","1")
|
9
9
|
end
|
10
|
-
end
|
10
|
+
end
|
11
11
|
class B < Riddl::Implementation
|
12
12
|
def response
|
13
13
|
Riddl::Parameter::Simple.new("y","1")
|
14
14
|
end
|
15
|
-
end
|
15
|
+
end
|
16
16
|
class C < Riddl::Implementation
|
17
17
|
def response
|
18
18
|
Riddl::Parameter::Simple.new("z","1")
|
19
19
|
end
|
20
|
-
end
|
20
|
+
end
|
21
21
|
class S < Riddl::Implementation
|
22
22
|
def response
|
23
23
|
@p # return input parameters unchanged
|
24
24
|
end
|
25
|
-
end
|
25
|
+
end
|
26
26
|
|
27
|
-
Riddl::Server.new("main.xml", :port =>
|
27
|
+
Riddl::Server.new("main.xml", :port => 9001) do
|
28
28
|
process_out false
|
29
29
|
logger Riddl::CommonLogger.new("Main","main.log")
|
30
30
|
on resource do
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + '/../../lib/ruby/riddl/server')
|
3
3
|
|
4
|
-
srv = Riddl::Client.interface("http://localhost:
|
4
|
+
srv = Riddl::Client.interface("http://localhost:9001","server.declaration.xml")
|
5
5
|
|
6
6
|
status, ret = srv.resource('/test.txt').post [
|
7
7
|
Riddl::Parameter::Simple.new("mimetype","text/plain"),
|
@@ -2,13 +2,13 @@
|
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + '/../../lib/ruby/riddl/server')
|
3
3
|
require File.expand_path(File.dirname(__FILE__) + '/../../lib/ruby/riddl/downloadify')
|
4
4
|
|
5
|
-
Riddl::Server.new(::File.dirname(__FILE__) + '/server.declaration.xml', :port =>
|
5
|
+
Riddl::Server.new(::File.dirname(__FILE__) + '/server.declaration.xml', :port => 9001) do
|
6
6
|
accessible_description true
|
7
7
|
|
8
8
|
interface "main" do
|
9
9
|
end
|
10
10
|
|
11
|
-
interface "downloadify" do
|
11
|
+
interface "downloadify" do
|
12
12
|
on resource do
|
13
13
|
run Riddl::Utils::Downloadify if get 'dfin'
|
14
14
|
run Riddl::Utils::Downloadify if post 'dfin'
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<interface name="main" location="http://api.flickr.com/services">
|
3
3
|
<xi:include href="Flickr/flickr.xml"/>
|
4
4
|
</interface>
|
5
|
-
<interface name="exif" location="http://localhost:
|
5
|
+
<interface name="exif" location="http://localhost:9001">
|
6
6
|
<xi:include href="Exif/exif.xml"/>
|
7
7
|
</interface>
|
8
8
|
|
data/examples/library/server.rb
CHANGED
@@ -34,7 +34,7 @@ class BookDescription < Riddl::Implementation
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
Riddl::Server.new(File.dirname(__FILE__) + '/description.xml', :port =>
|
37
|
+
Riddl::Server.new(File.dirname(__FILE__) + '/description.xml', :port => 9001, :bind => '::') do
|
38
38
|
accessible_description true
|
39
39
|
|
40
40
|
on resource do
|
@@ -3,7 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../../lib/ruby/riddl/server'
|
|
3
3
|
require File.expand_path(File.dirname(__FILE__) + '/../../lib/ruby/riddl/utils/fileserve')
|
4
4
|
require File.expand_path(File.dirname(__FILE__) + '/../../lib/ruby/riddl/utils/notifications_producer')
|
5
5
|
|
6
|
-
Riddl::Server.new(::File.dirname(__FILE__) + '/producer.declaration.xml', :port =>
|
6
|
+
Riddl::Server.new(::File.dirname(__FILE__) + '/producer.declaration.xml', :port => 9001) do
|
7
7
|
accessible_description true
|
8
8
|
backend = Riddl::Utils::Notifications::Producer::Backend.new(
|
9
9
|
::File.dirname(__FILE__) + '/topics.xml',
|
@@ -14,7 +14,7 @@ Riddl::Server.new(::File.dirname(__FILE__) + '/producer.declaration.xml', :port
|
|
14
14
|
run Riddl::Utils::FileServe, "implementation/index.html" if get
|
15
15
|
on resource 'oliver' do
|
16
16
|
run Riddl::Utils::FileServe, "implementation/oliver.html" if get
|
17
|
-
end
|
17
|
+
end
|
18
18
|
on resource 'juergen' do
|
19
19
|
run Riddl::Utils::FileServe, "implementation/juergen.html" if get
|
20
20
|
end
|
@@ -22,5 +22,5 @@ Riddl::Server.new(::File.dirname(__FILE__) + '/producer.declaration.xml', :port
|
|
22
22
|
|
23
23
|
interface 'main' do |r|
|
24
24
|
use Riddl::Utils::Notifications::Producer::implementation(backend,nil,@riddl_opts[:mode])
|
25
|
-
end
|
25
|
+
end
|
26
26
|
end.loop!
|
data/lib/ruby/riddl/wrapper.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require 'open-uri'
|
3
2
|
gem 'xml-smart', '>= 0.3.0'
|
4
3
|
require 'xml/smart'
|
5
4
|
|
@@ -79,10 +78,18 @@ module Riddl
|
|
79
78
|
name = File.expand_path(File.dirname(__FILE__)) + $2
|
80
79
|
end
|
81
80
|
begin
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
81
|
+
if name.respond_to?(:read)
|
82
|
+
fpath = File.dirname(name.path) if name.is_a?(File) || name.is_a?(Tempfile)
|
83
|
+
xml = name.read
|
84
|
+
name.close
|
85
|
+
elsif File.exist?(name)
|
86
|
+
fpath = File.dirname(name)
|
87
|
+
xml = File.read(name)
|
88
|
+
else
|
89
|
+
fpath = nil
|
90
|
+
xml = Typhoeus.get(name, ssl_verifypeer: false).response_body
|
91
|
+
end
|
92
|
+
@doc = XML::Smart.string(xml)
|
86
93
|
rescue
|
87
94
|
begin
|
88
95
|
@doc = XML::Smart.string(name)
|
data/riddl.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "riddl"
|
3
|
-
s.version = "0.
|
3
|
+
s.version = "0.102"
|
4
4
|
s.platform = Gem::Platform::RUBY
|
5
5
|
s.license = "LGPL-3.0"
|
6
6
|
s.summary = "restful interface description and declaration language: tools and client/server libs"
|
@@ -29,7 +29,7 @@ Gem::Specification.new do |s|
|
|
29
29
|
s.add_runtime_dependency 'rack', '~>2.2'
|
30
30
|
s.add_runtime_dependency 'thin', '~>1.6'
|
31
31
|
s.add_runtime_dependency 'eventmachine', '>= 1.0.0', '~>1.0'
|
32
|
-
s.add_runtime_dependency 'em-websocket', '>= 0.
|
32
|
+
s.add_runtime_dependency 'em-websocket', '>= 0.5.2', '~>0'
|
33
33
|
s.add_runtime_dependency 'faye-websocket', '>= 0.1', '~>0'
|
34
34
|
s.add_runtime_dependency 'mime-types', '>= 3.0', '~>3'
|
35
35
|
s.add_runtime_dependency 'minitest', '>= 5.0.0', '~>5'
|
data/test/smartrunner.rb
CHANGED
@@ -13,27 +13,34 @@ class TestServerInfo
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
module ServerCase
|
16
|
+
module ServerCase
|
17
17
|
def setup
|
18
18
|
self.class::SERVER.each do |s|
|
19
19
|
if self.class::NORUN
|
20
20
|
out = `#{s.server} info`
|
21
21
|
s.port = out.match(/:(\d+)\)/)[1].to_i
|
22
22
|
s.url = out.match(/\(([^\)]+)\)/)[1]
|
23
|
-
else
|
24
|
-
|
23
|
+
else
|
24
|
+
Thread.new do
|
25
|
+
`#{s.server} -v start`
|
26
|
+
end
|
27
|
+
out = 'not running'
|
28
|
+
while out.match(/not running/)
|
29
|
+
out = `#{s.server} info`
|
30
|
+
sleep 0.2
|
31
|
+
end
|
25
32
|
s.port = out.match(/:(\d+)\)/)[1].to_i
|
26
33
|
s.url = out.match(/\(([^\)]+)\)/)[1]
|
27
34
|
|
28
|
-
up = false
|
29
|
-
until up
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
35
|
+
# up = false
|
36
|
+
# until up
|
37
|
+
# begin
|
38
|
+
# TCPSocket.new('localhost', s.port)
|
39
|
+
# up = true
|
40
|
+
# rescue
|
41
|
+
# sleep 0.2
|
42
|
+
# end
|
43
|
+
# end
|
37
44
|
end
|
38
45
|
end
|
39
46
|
end
|
@@ -42,7 +49,7 @@ module ServerCase
|
|
42
49
|
unless self.class::NORUN
|
43
50
|
self.class::SERVER.each do |s|
|
44
51
|
`#{s.server} stop`
|
45
|
-
end
|
46
|
-
end
|
52
|
+
end
|
53
|
+
end
|
47
54
|
end
|
48
55
|
end
|
data/test/tc_websocket.rb
CHANGED
@@ -27,36 +27,37 @@ class TestWebsocket < Minitest::Test
|
|
27
27
|
test.ws do |conn|
|
28
28
|
cbs = []
|
29
29
|
|
30
|
-
conn.
|
30
|
+
conn.on :open do
|
31
31
|
### called on connection
|
32
|
-
conn.
|
33
|
-
conn.
|
32
|
+
conn.send "hello world"
|
33
|
+
conn.send "done"
|
34
34
|
end
|
35
35
|
|
36
|
-
conn.
|
36
|
+
conn.on :error do |e|
|
37
37
|
### called on error
|
38
38
|
cbs << "Got error: #{e}"
|
39
39
|
end
|
40
40
|
|
41
|
-
conn.
|
41
|
+
conn.on :message do |msg|
|
42
42
|
### called when server responds
|
43
|
-
cbs << "<#{msg}>"
|
43
|
+
cbs << "<#{msg.data}>"
|
44
44
|
if msg.data == "done"
|
45
|
-
conn.
|
45
|
+
conn.close
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
conn.
|
49
|
+
conn.on :close do
|
50
50
|
### called on disconnect
|
51
51
|
cbs << "gone"
|
52
52
|
EM::stop_event_loop
|
53
|
-
|
54
|
-
assert cbs.length ==
|
55
|
-
assert cbs[0] == '<
|
56
|
-
assert cbs[1] == '<
|
57
|
-
assert cbs[2] == '
|
53
|
+
|
54
|
+
assert cbs.length == 4
|
55
|
+
assert cbs[0] == '<oasch 1>'
|
56
|
+
assert cbs[1] == '<hello world>'
|
57
|
+
assert cbs[2] == '<done>'
|
58
|
+
assert cbs[3] == 'gone'
|
58
59
|
end
|
59
60
|
end
|
60
61
|
|
61
|
-
end
|
62
|
-
end
|
62
|
+
end
|
63
|
+
end
|