startback-websocket 0.14.0 → 0.14.1
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/Gemfile +3 -2
- data/README.md +64 -9
- data/lib/startback/ext/context.rb +6 -0
- data/lib/startback/ext.rb +1 -2
- data/lib/startback/websocket/app.rb +82 -0
- data/lib/startback/websocket/hub/app.rb +28 -0
- data/lib/startback/websocket/hub/builder.rb +55 -0
- data/lib/startback/websocket/hub/errors.rb +9 -0
- data/lib/startback/websocket/hub/message.rb +29 -0
- data/lib/startback/websocket/hub/middleware/command_handler.rb +34 -0
- data/lib/startback/websocket/hub/middleware/room_handler.rb +30 -0
- data/lib/startback/websocket/hub/middleware.rb +12 -0
- data/lib/startback/websocket/hub/participant.rb +16 -0
- data/lib/startback/websocket/hub/room.rb +46 -0
- data/lib/startback/websocket/hub.rb +15 -0
- data/lib/startback/websocket.rb +8 -0
- data/spec/spec_helper.rb +21 -32
- data/spec/unit/hub/test_builder.rb +141 -0
- data/spec/unit/hub/test_room.rb +27 -0
- data/spec/unit/test_app.rb +35 -0
- data/tasks/test.rake +0 -1
- metadata +20 -91
- data/lib/startback/audit/prometheus.rb +0 -87
- data/lib/startback/audit/shared.rb +0 -17
- data/lib/startback/audit/trailer.rb +0 -129
- data/lib/startback/audit.rb +0 -3
- data/lib/startback/caching/entity_cache.rb +0 -157
- data/lib/startback/caching/no_store.rb +0 -28
- data/lib/startback/caching/store.rb +0 -34
- data/lib/startback/context/h_factory.rb +0 -43
- data/lib/startback/context/middleware.rb +0 -53
- data/lib/startback/context.rb +0 -122
- data/lib/startback/errors.rb +0 -197
- data/lib/startback/event/agent.rb +0 -84
- data/lib/startback/event/bus/bunny/async.rb +0 -162
- data/lib/startback/event/bus/bunny.rb +0 -1
- data/lib/startback/event/bus/memory/async.rb +0 -45
- data/lib/startback/event/bus/memory/sync.rb +0 -35
- data/lib/startback/event/bus/memory.rb +0 -2
- data/lib/startback/event/bus.rb +0 -100
- data/lib/startback/event/engine.rb +0 -94
- data/lib/startback/event/ext/context.rb +0 -5
- data/lib/startback/event/ext/operation.rb +0 -13
- data/lib/startback/event.rb +0 -47
- data/lib/startback/ext/date_time.rb +0 -9
- data/lib/startback/ext/time.rb +0 -9
- data/lib/startback/model.rb +0 -6
- data/lib/startback/operation/error_operation.rb +0 -19
- data/lib/startback/operation/multi_operation.rb +0 -28
- data/lib/startback/operation.rb +0 -78
- data/lib/startback/services.rb +0 -11
- data/lib/startback/support/data_object.rb +0 -71
- data/lib/startback/support/env.rb +0 -41
- data/lib/startback/support/fake_logger.rb +0 -18
- data/lib/startback/support/hooks.rb +0 -48
- data/lib/startback/support/log_formatter.rb +0 -34
- data/lib/startback/support/logger.rb +0 -34
- data/lib/startback/support/operation_runner.rb +0 -150
- data/lib/startback/support/robustness.rb +0 -157
- data/lib/startback/support/transaction_manager.rb +0 -25
- data/lib/startback/support/transaction_policy.rb +0 -33
- data/lib/startback/support/world.rb +0 -54
- data/lib/startback/support.rb +0 -26
- data/lib/startback/version.rb +0 -8
- data/lib/startback/web/api.rb +0 -99
- data/lib/startback/web/auto_caching.rb +0 -85
- data/lib/startback/web/catch_all.rb +0 -52
- data/lib/startback/web/cors_headers.rb +0 -80
- data/lib/startback/web/health_check.rb +0 -49
- data/lib/startback/web/magic_assets/ng_html_transformer.rb +0 -80
- data/lib/startback/web/magic_assets/rake_tasks.rb +0 -64
- data/lib/startback/web/magic_assets.rb +0 -98
- data/lib/startback/web/middleware.rb +0 -13
- data/lib/startback/web/prometheus.rb +0 -16
- data/lib/startback/web/shield.rb +0 -58
- data/lib/startback.rb +0 -43
- data/spec/unit/audit/test_prometheus.rb +0 -72
- data/spec/unit/audit/test_trailer.rb +0 -105
- data/spec/unit/caching/test_entity_cache.rb +0 -136
- data/spec/unit/context/test_abstraction_factory.rb +0 -64
- data/spec/unit/context/test_dup.rb +0 -42
- data/spec/unit/context/test_fork.rb +0 -37
- data/spec/unit/context/test_h_factory.rb +0 -31
- data/spec/unit/context/test_middleware.rb +0 -45
- data/spec/unit/context/test_with_world.rb +0 -20
- data/spec/unit/context/test_world.rb +0 -17
- data/spec/unit/event/bus/memory/test_async.rb +0 -43
- data/spec/unit/event/bus/memory/test_sync.rb +0 -43
- data/spec/unit/support/hooks/test_after_hook.rb +0 -54
- data/spec/unit/support/hooks/test_before_hook.rb +0 -54
- data/spec/unit/support/operation_runner/test_around_run.rb +0 -156
- data/spec/unit/support/operation_runner/test_before_after_call.rb +0 -48
- data/spec/unit/support/test_data_object.rb +0 -156
- data/spec/unit/support/test_env.rb +0 -75
- data/spec/unit/support/test_robusteness.rb +0 -229
- data/spec/unit/support/test_transaction_manager.rb +0 -64
- data/spec/unit/support/test_world.rb +0 -72
- data/spec/unit/test_event.rb +0 -62
- data/spec/unit/test_operation.rb +0 -55
- data/spec/unit/test_support.rb +0 -40
- data/spec/unit/web/fixtures/assets/app/hello.es6 +0 -4
- data/spec/unit/web/fixtures/assets/app/hello.html +0 -1
- data/spec/unit/web/fixtures/assets/index.es6 +0 -1
- data/spec/unit/web/test_api.rb +0 -82
- data/spec/unit/web/test_auto_caching.rb +0 -81
- data/spec/unit/web/test_catch_all.rb +0 -77
- data/spec/unit/web/test_cors_headers.rb +0 -88
- data/spec/unit/web/test_healthcheck.rb +0 -59
- data/spec/unit/web/test_magic_assets.rb +0 -82
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'startback/web/auto_caching'
|
|
3
|
-
|
|
4
|
-
module Startback
|
|
5
|
-
module Web
|
|
6
|
-
describe AutoCaching do
|
|
7
|
-
include Rack::Test::Methods
|
|
8
|
-
|
|
9
|
-
context 'when used without options' do
|
|
10
|
-
def app
|
|
11
|
-
Rack::Builder.new do
|
|
12
|
-
use AutoCaching
|
|
13
|
-
run ->(env){ [200, {}, ["Hello error"]] }
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
it 'sets the development Cache-Control since this is a test' do
|
|
18
|
-
get '/'
|
|
19
|
-
expect(last_response['Cache-Control']). to eql("no-cache, no-store, max-age=0, must-revalidate")
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
context 'when forcing production' do
|
|
24
|
-
def app
|
|
25
|
-
Rack::Builder.new do
|
|
26
|
-
use AutoCaching, false
|
|
27
|
-
run ->(env){ [200, {}, ["Hello error"]] }
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
it 'sets the production Cache-Control' do
|
|
32
|
-
get '/'
|
|
33
|
-
expect(last_response['Cache-Control']). to eql("public, must-revalidate, max-age=3600, s-max-age=3600")
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
context 'when forcing development headers' do
|
|
38
|
-
def app
|
|
39
|
-
Rack::Builder.new do
|
|
40
|
-
use AutoCaching, development: { "Cache-Control" => "no-cache" }
|
|
41
|
-
run ->(env){ [200, {}, ["Hello error"]] }
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
it 'sets the production Cache-Control' do
|
|
46
|
-
get '/'
|
|
47
|
-
expect(last_response['Cache-Control']). to eql("no-cache")
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
context 'when setting the Cache-Control header only' do
|
|
52
|
-
def app
|
|
53
|
-
Rack::Builder.new do
|
|
54
|
-
use AutoCaching, development: "no-cache"
|
|
55
|
-
run ->(env){ [200, {}, ["Hello error"]] }
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
it 'sets the production Cache-Control' do
|
|
60
|
-
get '/'
|
|
61
|
-
expect(last_response['Cache-Control']). to eql("no-cache")
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
context 'when a Cache-Control header is already set by the app' do
|
|
66
|
-
def app
|
|
67
|
-
Rack::Builder.new do
|
|
68
|
-
use AutoCaching
|
|
69
|
-
run ->(env){ [200, {"Cache-Control" => "priority"}, ["Hello error"]] }
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
it 'sets the production Cache-Control' do
|
|
74
|
-
get '/'
|
|
75
|
-
expect(last_response['Cache-Control']). to eql("priority")
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
end # CatchAll
|
|
80
|
-
end # module Web
|
|
81
|
-
end # module Startback
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'singleton'
|
|
3
|
-
require 'startback/web/catch_all'
|
|
4
|
-
|
|
5
|
-
module Startback
|
|
6
|
-
module Web
|
|
7
|
-
describe CatchAll do
|
|
8
|
-
include Rack::Test::Methods
|
|
9
|
-
|
|
10
|
-
context 'when used without context' do
|
|
11
|
-
def app
|
|
12
|
-
Rack::Builder.new do
|
|
13
|
-
use CatchAll
|
|
14
|
-
run ->(env){ raise "Hello error" }
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
it 'returns a 500 with json explanation' do
|
|
19
|
-
get '/'
|
|
20
|
-
expect(last_response.status).to eql(500)
|
|
21
|
-
expect(last_response.content_type).to eql("application/json")
|
|
22
|
-
result = JSON.parse(last_response.body)
|
|
23
|
-
expect(result).to eql({
|
|
24
|
-
"code" => "Startback::Errors::InternalServerError",
|
|
25
|
-
"description" => "An error occured, sorry"
|
|
26
|
-
})
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
context 'when used with a context providing an error handler' do
|
|
31
|
-
|
|
32
|
-
class AnError < StandardError
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
class ErrorHandler
|
|
36
|
-
include Singleton
|
|
37
|
-
|
|
38
|
-
attr_reader :ex
|
|
39
|
-
|
|
40
|
-
def fatal(ex)
|
|
41
|
-
@ex = ex
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
class MyContextWithErrorHandler < Startback::Context
|
|
47
|
-
|
|
48
|
-
def error_handler
|
|
49
|
-
ErrorHandler.instance
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def app
|
|
55
|
-
Rack::Builder.new do
|
|
56
|
-
use Context::Middleware, MyContextWithErrorHandler.new
|
|
57
|
-
use CatchAll
|
|
58
|
-
run ->(env){ raise AnError, "Hello error" }
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
it 'returns a 500 with json explanation' do
|
|
63
|
-
get '/'
|
|
64
|
-
expect(last_response.status).to eql(500)
|
|
65
|
-
expect(last_response.content_type).to eql("application/json")
|
|
66
|
-
result = JSON.parse(last_response.body)
|
|
67
|
-
expect(result).to eql({
|
|
68
|
-
"code" => "Startback::Errors::InternalServerError",
|
|
69
|
-
"description" => "An error occured, sorry"
|
|
70
|
-
})
|
|
71
|
-
expect(ErrorHandler.instance.ex).to be_a(AnError)
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
end # CatchAll
|
|
76
|
-
end # module Web
|
|
77
|
-
end # module Startback
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'startback/web/cors_headers'
|
|
3
|
-
|
|
4
|
-
module Startback
|
|
5
|
-
module Web
|
|
6
|
-
describe CorsHeaders do
|
|
7
|
-
include Rack::Test::Methods
|
|
8
|
-
|
|
9
|
-
context 'when used without options' do
|
|
10
|
-
def app
|
|
11
|
-
Rack::Builder.new do
|
|
12
|
-
use CorsHeaders
|
|
13
|
-
run ->(env){ [200, {}, ["Hello world"]] }
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
it 'sets the CORS headers to default values' do
|
|
18
|
-
header('Origin', "https://test.com")
|
|
19
|
-
get '/'
|
|
20
|
-
expect(last_response['Access-Control-Allow-Origin']). to eql("*")
|
|
21
|
-
expect(last_response['Access-Control-Allow-Methods']). to eql("OPTIONS, HEAD, GET, POST, PUT, PATCH, DELETE")
|
|
22
|
-
expect(last_response.body).to eql("Hello world")
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
it 'strips everything when option' do
|
|
26
|
-
header('Origin', "https://test.com")
|
|
27
|
-
options '/'
|
|
28
|
-
expect(last_response['Access-Control-Allow-Origin']). to eql("*")
|
|
29
|
-
expect(last_response['Access-Control-Allow-Methods']). to eql("OPTIONS, HEAD, GET, POST, PUT, PATCH, DELETE")
|
|
30
|
-
expect(last_response.status).to eql(204)
|
|
31
|
-
expect(last_response.body).to eql("")
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
context 'when used with the :bounce option' do
|
|
36
|
-
def app
|
|
37
|
-
Rack::Builder.new do
|
|
38
|
-
use CorsHeaders, bounce: true
|
|
39
|
-
run ->(env){ [200, {}, ["Hello world"]] }
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
it 'sets the CORS Origin header to the caller' do
|
|
44
|
-
header('Origin', "https://test.com")
|
|
45
|
-
get '/'
|
|
46
|
-
expect(last_response['Access-Control-Allow-Origin']). to eql("https://test.com")
|
|
47
|
-
expect(last_response['Access-Control-Allow-Methods']). to eql("OPTIONS, HEAD, GET, POST, PUT, PATCH, DELETE")
|
|
48
|
-
expect(last_response.body).to eql("Hello world")
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
context 'when overriding a header' do
|
|
53
|
-
def app
|
|
54
|
-
Rack::Builder.new do
|
|
55
|
-
use CorsHeaders, headers: { 'Access-Control-Allow-Methods' => "POST" }
|
|
56
|
-
run ->(env){ [200, {}, ["Hello world"]] }
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
it 'sets the CORS Origin header to the caller' do
|
|
61
|
-
header('Origin', "https://test.com")
|
|
62
|
-
get '/'
|
|
63
|
-
expect(last_response['Access-Control-Allow-Origin']). to eql("*")
|
|
64
|
-
expect(last_response['Access-Control-Allow-Methods']). to eql("POST")
|
|
65
|
-
expect(last_response.body).to eql("Hello world")
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
context 'when the app sets specific headers' do
|
|
70
|
-
def app
|
|
71
|
-
Rack::Builder.new do
|
|
72
|
-
use CorsHeaders
|
|
73
|
-
run ->(env){ [200, {'Access-Control-Allow-Methods' => "POST"}, ["Hello world"]] }
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
it 'does not override them' do
|
|
78
|
-
header('Origin', "https://test.com")
|
|
79
|
-
get '/'
|
|
80
|
-
expect(last_response['Access-Control-Allow-Origin']). to eql("*")
|
|
81
|
-
expect(last_response['Access-Control-Allow-Methods']). to eql("POST")
|
|
82
|
-
expect(last_response.body).to eql("Hello world")
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
end # CatchAll
|
|
87
|
-
end # module Web
|
|
88
|
-
end # module Startback
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'startback/web/health_check'
|
|
3
|
-
|
|
4
|
-
module Startback
|
|
5
|
-
module Web
|
|
6
|
-
describe HealthCheck do
|
|
7
|
-
include Rack::Test::Methods
|
|
8
|
-
|
|
9
|
-
context 'when used without a block and no failure' do
|
|
10
|
-
def app
|
|
11
|
-
HealthCheck.new
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
it 'returns a 204 when ok' do
|
|
15
|
-
get '/'
|
|
16
|
-
expect(last_response.status).to eql(204)
|
|
17
|
-
expect(last_response.body).to be_empty
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
context 'when used without a block a failure' do
|
|
22
|
-
def app
|
|
23
|
-
app = HealthCheck.new
|
|
24
|
-
def app.check!(env)
|
|
25
|
-
raise "Hello error"
|
|
26
|
-
end
|
|
27
|
-
app
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
it 'raises when ko' do
|
|
31
|
-
expect(->(){ get '/' }).to raise_error("Hello error")
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
context 'when used with a block returning a debug message' do
|
|
36
|
-
def app
|
|
37
|
-
HealthCheck.new{ "Hello world" }
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
it 'returns a 200 with plain text message' do
|
|
41
|
-
get '/'
|
|
42
|
-
expect(last_response.status).to eql(200)
|
|
43
|
-
expect(last_response.body).to eql("Hello world")
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
context 'when used with a block raising an exception' do
|
|
48
|
-
def app
|
|
49
|
-
HealthCheck.new{ raise("Hello error") }
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
it 're-raises it' do
|
|
53
|
-
expect(->(){ get '/' }).to raise_error("Hello error")
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
end
|
|
58
|
-
end # module Web
|
|
59
|
-
end # module Startback
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'startback/web/magic_assets'
|
|
3
|
-
require 'startback/web/magic_assets/ng_html_transformer'
|
|
4
|
-
|
|
5
|
-
module Startback
|
|
6
|
-
module Web
|
|
7
|
-
describe MagicAssets do
|
|
8
|
-
include Rack::Test::Methods
|
|
9
|
-
|
|
10
|
-
context 'when used as an app' do
|
|
11
|
-
let(:app){
|
|
12
|
-
MagicAssets.new({
|
|
13
|
-
folder: Path.dir/"fixtures/assets"
|
|
14
|
-
})
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
it 'works as expected' do
|
|
18
|
-
get "/index.js"
|
|
19
|
-
expect(last_response.status).to eql(200)
|
|
20
|
-
expect(last_response.body).to match(/function test/)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it 'delegates a [] call to sprockets' do
|
|
24
|
-
result = app['index.js']
|
|
25
|
-
expect(result.to_s).to match(/function test/)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
it 'returns a 404 on unknown' do
|
|
29
|
-
get '/nosuchone.js'
|
|
30
|
-
expect(last_response.status).to eql(404)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
context 'when used as a middleware' do
|
|
35
|
-
let(:app){
|
|
36
|
-
Rack::Builder.new do
|
|
37
|
-
use MagicAssets, {
|
|
38
|
-
folder: Path.dir/"fixtures/assets",
|
|
39
|
-
path: "/my-assets"
|
|
40
|
-
}
|
|
41
|
-
run ->(t){
|
|
42
|
-
[200, {}, ["Hello world"]]
|
|
43
|
-
}
|
|
44
|
-
end
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
it 'lets unrelated things pass' do
|
|
48
|
-
get "/hello"
|
|
49
|
-
expect(last_response.status).to eql(200)
|
|
50
|
-
expect(last_response.body).to eql("Hello world")
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
it 'serves the assets under the chosen path' do
|
|
54
|
-
get "/my-assets/index.js"
|
|
55
|
-
expect(last_response.status).to eql(200)
|
|
56
|
-
expect(last_response.body).to match(/function test/)
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
context 'when registering the NgHtmlTransformer' do
|
|
61
|
-
let(:app){
|
|
62
|
-
plugin = MagicAssets::NgHtmlTransformer.new({
|
|
63
|
-
ng_module: "test.templates"
|
|
64
|
-
})
|
|
65
|
-
MagicAssets.new({
|
|
66
|
-
folder: Path.dir/"fixtures/assets",
|
|
67
|
-
plugins: [plugin]
|
|
68
|
-
})
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
it 'works as expected' do
|
|
72
|
-
get "/index.js"
|
|
73
|
-
expect(last_response.status).to eql(200)
|
|
74
|
-
expect(last_response.body).to match(/function test/)
|
|
75
|
-
expect(last_response.body).to match(/Hello \{\{who\}\}/)
|
|
76
|
-
expect(last_response.body).to match(/angular.module\("test.templates"\)/)
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|