instana 1.11.6 → 1.193.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of instana might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.circleci/config.yml +168 -0
- data/Rakefile +26 -37
- data/gemfiles/libraries.gemfile +2 -0
- data/lib/instana/agent.rb +6 -0
- data/lib/instana/base.rb +2 -0
- data/lib/instana/config.rb +11 -0
- data/lib/instana/frameworks/cuba.rb +33 -0
- data/lib/instana/frameworks/instrumentation/action_controller.rb +11 -0
- data/lib/instana/frameworks/instrumentation/mysql2_adapter.rb +7 -1
- data/lib/instana/frameworks/instrumentation/mysql_adapter.rb +7 -1
- data/lib/instana/frameworks/instrumentation/postgresql_adapter.rb +23 -5
- data/lib/instana/frameworks/roda.rb +41 -0
- data/lib/instana/frameworks/sinatra.rb +17 -0
- data/lib/instana/instrumentation/excon.rb +1 -1
- data/lib/instana/instrumentation/graphql.rb +77 -0
- data/lib/instana/instrumentation/net-http.rb +2 -0
- data/lib/instana/instrumentation/rack.rb +23 -3
- data/lib/instana/secrets.rb +42 -0
- data/lib/instana/setup.rb +1 -0
- data/lib/instana/test.rb +4 -3
- data/lib/instana/tracing/span.rb +23 -10
- data/lib/instana/version.rb +1 -1
- data/test/apps/cuba.rb +4 -0
- data/test/apps/roda.rb +3 -0
- data/test/apps/sinatra.rb +4 -0
- data/test/config_test.rb +1 -17
- data/test/frameworks/cuba_test.rb +14 -1
- data/test/frameworks/rack_test.rb +121 -69
- data/test/frameworks/rails/actioncontroller_test.rb +12 -0
- data/test/frameworks/rails/activerecord_test.rb +80 -28
- data/test/frameworks/roda_test.rb +14 -0
- data/test/frameworks/sinatra_test.rb +37 -15
- data/test/instrumentation/excon_test.rb +0 -2
- data/test/instrumentation/graphql_test.rb +116 -0
- data/test/instrumentation/grpc_test.rb +1 -1
- data/test/instrumentation/redis_test.rb +10 -0
- data/test/secrets_test.rb +73 -0
- data/test/tracing/tracer_test.rb +31 -1
- metadata +10 -6
- data/.travis.yml +0 -43
- data/test/tracing/trace_test.rb +0 -67
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require 'sinatra'
|
2
2
|
if defined?(::Sinatra)
|
3
3
|
require 'test_helper'
|
4
4
|
require File.expand_path(File.dirname(__FILE__) + '/../apps/sinatra')
|
@@ -17,28 +17,50 @@ if defined?(::Sinatra)
|
|
17
17
|
r = get '/'
|
18
18
|
assert last_response.ok?
|
19
19
|
|
20
|
-
assert r.headers.key?("X-Instana-T")
|
21
|
-
assert r.headers.key?("X-Instana-S")
|
22
20
|
|
23
21
|
spans = ::Instana.processor.queued_spans
|
24
22
|
assert_equal 1, spans.count
|
25
23
|
|
26
|
-
|
27
|
-
assert_equal :rack,
|
28
|
-
|
29
|
-
assert first_span[:data].key?(:http)
|
24
|
+
rack_span = spans.first
|
25
|
+
assert_equal :rack, rack_span[:n]
|
26
|
+
# ::Instana::Util.pry!
|
30
27
|
|
31
|
-
assert
|
32
|
-
|
28
|
+
assert r.headers.key?("X-Instana-T")
|
29
|
+
assert r.headers["X-Instana-T"] == ::Instana::Util.id_to_header(rack_span[:t])
|
30
|
+
assert r.headers.key?("X-Instana-S")
|
31
|
+
assert r.headers["X-Instana-S"] == ::Instana::Util.id_to_header(rack_span[:s])
|
32
|
+
assert r.headers.key?("X-Instana-L")
|
33
|
+
assert r.headers["X-Instana-L"] == '1'
|
34
|
+
assert r.headers.key?("Server-Timing")
|
35
|
+
assert r.headers["Server-Timing"] == "intid;desc=#{::Instana::Util.id_to_header(rack_span[:t])}"
|
36
|
+
|
37
|
+
assert rack_span.key?(:data)
|
38
|
+
assert rack_span[:data].key?(:http)
|
39
|
+
assert rack_span[:data][:http].key?(:method)
|
40
|
+
assert_equal "GET", rack_span[:data][:http][:method]
|
33
41
|
|
34
|
-
assert
|
35
|
-
assert_equal "/",
|
42
|
+
assert rack_span[:data][:http].key?(:url)
|
43
|
+
assert_equal "/", rack_span[:data][:http][:url]
|
36
44
|
|
37
|
-
assert
|
38
|
-
assert_equal 200,
|
45
|
+
assert rack_span[:data][:http].key?(:status)
|
46
|
+
assert_equal 200, rack_span[:data][:http][:status]
|
39
47
|
|
40
|
-
assert
|
41
|
-
assert_equal "example.org",
|
48
|
+
assert rack_span[:data][:http].key?(:host)
|
49
|
+
assert_equal "example.org", rack_span[:data][:http][:host]
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_path_template
|
53
|
+
clear_all!
|
54
|
+
|
55
|
+
r = get '/greet/instana'
|
56
|
+
assert last_response.ok?
|
57
|
+
|
58
|
+
spans = ::Instana.processor.queued_spans
|
59
|
+
assert_equal 1, spans.count
|
60
|
+
|
61
|
+
first_span = spans.first
|
62
|
+
assert_equal :rack, first_span[:n]
|
63
|
+
assert_equal '/greet/:name', first_span[:data][:http][:path_tpl]
|
42
64
|
end
|
43
65
|
end
|
44
66
|
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class GraphqlTest < Minitest::Test
|
4
|
+
class TaskType < GraphQL::Schema::Object
|
5
|
+
field :id, ID, null: false
|
6
|
+
field :action, String, null: false
|
7
|
+
end
|
8
|
+
|
9
|
+
class NewTaskType < GraphQL::Schema::Mutation
|
10
|
+
argument :action, String, required: true
|
11
|
+
field :task, TaskType, null: true
|
12
|
+
|
13
|
+
def resolve(action:)
|
14
|
+
{
|
15
|
+
task: OpenStruct.new(id: '0', action: action)
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class QueryType < GraphQL::Schema::Object
|
21
|
+
field :tasks, TaskType.connection_type, null: false
|
22
|
+
|
23
|
+
def tasks()
|
24
|
+
[
|
25
|
+
OpenStruct.new(id: '0', action: 'Sample')
|
26
|
+
]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class MutationType < GraphQL::Schema::Object
|
31
|
+
field :create_task, mutation: NewTaskType
|
32
|
+
end
|
33
|
+
|
34
|
+
class Schema < GraphQL::Schema
|
35
|
+
query QueryType
|
36
|
+
mutation MutationType
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_it_works
|
40
|
+
assert defined?(GraphQL)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_config_defaults
|
44
|
+
assert ::Instana.config[:graphql].is_a?(Hash)
|
45
|
+
assert ::Instana.config[:graphql].key?(:enabled)
|
46
|
+
assert_equal true, ::Instana.config[:graphql][:enabled]
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_query
|
50
|
+
clear_all!
|
51
|
+
|
52
|
+
query = "query Sample {
|
53
|
+
tasks(after: \"\", first: 10) {
|
54
|
+
nodes {
|
55
|
+
action
|
56
|
+
}
|
57
|
+
}
|
58
|
+
}"
|
59
|
+
|
60
|
+
expected_data = {
|
61
|
+
:operationName => "Sample",
|
62
|
+
:operationType => "query",
|
63
|
+
:arguments => { "tasks" => ["after", "first"] },
|
64
|
+
:fields => { "tasks" => ["nodes"], "nodes" => ["action"] }
|
65
|
+
}
|
66
|
+
expected_results = {
|
67
|
+
"data" => {
|
68
|
+
"tasks" => {
|
69
|
+
"nodes" => [{ "action" => "Sample" }]
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
results = Instana.tracer.start_or_continue_trace('graphql-test') { Schema.execute(query) }
|
75
|
+
query_span, root_span = *Instana.processor.queued_spans
|
76
|
+
|
77
|
+
assert_equal expected_results, results.to_h
|
78
|
+
assert_equal :sdk, root_span[:n]
|
79
|
+
assert_equal :'graphql.server', query_span[:n]
|
80
|
+
assert_equal expected_data, query_span[:data][:graphql]
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_mutation
|
84
|
+
clear_all!
|
85
|
+
|
86
|
+
query = "mutation Sample {
|
87
|
+
createTask(action: \"Sample\") {
|
88
|
+
task {
|
89
|
+
action
|
90
|
+
}
|
91
|
+
}
|
92
|
+
}"
|
93
|
+
|
94
|
+
expected_data = {
|
95
|
+
:operationName => "Sample",
|
96
|
+
:operationType => "mutation",
|
97
|
+
:arguments => { "createTask" => ["action"] },
|
98
|
+
:fields => { "createTask" => ["task"], "task" => ["action"] }
|
99
|
+
}
|
100
|
+
expected_results = {
|
101
|
+
"data" => {
|
102
|
+
"createTask" => {
|
103
|
+
"task" => { "action" => "Sample" }
|
104
|
+
}
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
results = Instana.tracer.start_or_continue_trace('graphql-test') { Schema.execute(query) }
|
109
|
+
query_span, root_span = *Instana.processor.queued_spans
|
110
|
+
|
111
|
+
assert_equal expected_results, results.to_h
|
112
|
+
assert_equal :sdk, root_span[:n]
|
113
|
+
assert_equal :'graphql.server', query_span[:n]
|
114
|
+
assert_equal expected_data, query_span[:data][:graphql]
|
115
|
+
end
|
116
|
+
end
|
@@ -20,6 +20,16 @@ class RedisTest < Minitest::Test
|
|
20
20
|
assert_redis_trace('SET')
|
21
21
|
end
|
22
22
|
|
23
|
+
def test_georadius
|
24
|
+
clear_all!
|
25
|
+
|
26
|
+
Instana.tracer.start_or_continue_trace(:redis_test) do
|
27
|
+
@redis_client.georadius('Sicily', '15', '37', '200', 'km', 'WITHCOORD', 'WITHDIST')
|
28
|
+
end
|
29
|
+
|
30
|
+
assert_redis_trace('GEORADIUS')
|
31
|
+
end
|
32
|
+
|
23
33
|
def test_normal_call_with_error
|
24
34
|
clear_all!
|
25
35
|
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SecretsTest < Minitest::Test
|
4
|
+
def setup
|
5
|
+
@subject = Instana::Secrets.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_equals_ignore_case
|
9
|
+
sample_config = {
|
10
|
+
"matcher"=>"equals-ignore-case",
|
11
|
+
"list"=>["key"]
|
12
|
+
}
|
13
|
+
|
14
|
+
url = url_for(%w(key Str kEy KEY))
|
15
|
+
assert_redacted @subject.remove_from_query(url, sample_config), %w(key kEy KEY)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_equals
|
19
|
+
sample_config = {
|
20
|
+
"matcher"=>"equals",
|
21
|
+
"list"=>["key", "kEy"]
|
22
|
+
}
|
23
|
+
|
24
|
+
url = url_for(%w(key Str kEy KEY))
|
25
|
+
assert_redacted @subject.remove_from_query(url, sample_config), %w(key kEy)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_contains_ignore_case
|
29
|
+
sample_config = {
|
30
|
+
"matcher"=>"contains-ignore-case",
|
31
|
+
"list"=>["stan"]
|
32
|
+
}
|
33
|
+
|
34
|
+
url = url_for(%w(instantiate conTESTant sample))
|
35
|
+
assert_redacted @subject.remove_from_query(url, sample_config), %w(instantiate conTESTant)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_contains
|
39
|
+
sample_config = {
|
40
|
+
"matcher"=>"contains",
|
41
|
+
"list"=>["stan"]
|
42
|
+
}
|
43
|
+
|
44
|
+
url = url_for(%w(instantiate conTESTant sample))
|
45
|
+
assert_redacted @subject.remove_from_query(url, sample_config), %w(instantiate)
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_regexp
|
50
|
+
sample_config = {
|
51
|
+
"matcher"=>"regex",
|
52
|
+
"list"=>["l{2}"]
|
53
|
+
}
|
54
|
+
|
55
|
+
url = url_for(%w(ball foot move))
|
56
|
+
assert_redacted @subject.remove_from_query(url, sample_config), %w(ball)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def url_for(keys)
|
62
|
+
url = URI('http://example.com')
|
63
|
+
url.query = URI.encode_www_form(keys.map { |k| [k, rand(1..100)]})
|
64
|
+
url.to_s
|
65
|
+
end
|
66
|
+
|
67
|
+
def assert_redacted(str, keys)
|
68
|
+
url = URI(str)
|
69
|
+
params = CGI.parse(url.query)
|
70
|
+
|
71
|
+
assert_equal keys, params.select { |_, v| v == %w(<redacted>) }.keys, 'to be redacted'
|
72
|
+
end
|
73
|
+
end
|
data/test/tracing/tracer_test.rb
CHANGED
@@ -46,6 +46,37 @@ class TracerTest < Minitest::Test
|
|
46
46
|
assert_equal ::Instana.agent.agent_uuid, first_span[:f][:h]
|
47
47
|
end
|
48
48
|
|
49
|
+
def test_exotic_tag_types
|
50
|
+
clear_all!
|
51
|
+
|
52
|
+
assert_equal false, ::Instana.tracer.tracing?
|
53
|
+
|
54
|
+
require 'resolv'
|
55
|
+
r = Resolv::DNS.new
|
56
|
+
ipv4 = r.getaddress("www.pwpush.com")
|
57
|
+
|
58
|
+
::Instana.tracer.start_or_continue_trace(:rack, {:ipaddr => ipv4}) do
|
59
|
+
assert_equal true, ::Instana.tracer.tracing?
|
60
|
+
sleep 0.1
|
61
|
+
end
|
62
|
+
|
63
|
+
spans = ::Instana.processor.queued_spans
|
64
|
+
assert_equal 1, spans.length
|
65
|
+
|
66
|
+
first_span = spans.first
|
67
|
+
assert_equal :rack, first_span[:n]
|
68
|
+
assert first_span[:ts].is_a?(Integer)
|
69
|
+
assert first_span[:d].is_a?(Integer)
|
70
|
+
assert first_span[:d].between?(100, 130)
|
71
|
+
assert first_span.key?(:data)
|
72
|
+
assert first_span[:data].key?(:ipaddr)
|
73
|
+
assert first_span[:data][:ipaddr].is_a?(String)
|
74
|
+
assert first_span.key?(:f)
|
75
|
+
assert first_span[:f].key?(:e)
|
76
|
+
assert first_span[:f].key?(:h)
|
77
|
+
assert_equal ::Instana.agent.agent_uuid, first_span[:f][:h]
|
78
|
+
end
|
79
|
+
|
49
80
|
def test_errors_are_properly_propagated
|
50
81
|
clear_all!
|
51
82
|
exception_raised = false
|
@@ -198,7 +229,6 @@ class TracerTest < Minitest::Test
|
|
198
229
|
assert_equal sdk_span[:k], 3
|
199
230
|
assert_equal sdk_span[:data][:sdk][:custom][:tags][:sub_task_info], 1
|
200
231
|
assert_equal sdk_span[:data][:sdk][:custom][:tags][:sub_task_exit_info], 1
|
201
|
-
|
202
232
|
end
|
203
233
|
|
204
234
|
def test_block_tracing_error_capture
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: instana
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.193.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Giacomo Lombardo
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -173,11 +173,11 @@ executables: []
|
|
173
173
|
extensions: []
|
174
174
|
extra_rdoc_files: []
|
175
175
|
files:
|
176
|
+
- ".circleci/config.yml"
|
176
177
|
- ".codeclimate.yml"
|
177
178
|
- ".fasterer.yml"
|
178
179
|
- ".gitignore"
|
179
180
|
- ".rubocop.yml"
|
180
|
-
- ".travis.yml"
|
181
181
|
- Dockerfile
|
182
182
|
- Gemfile
|
183
183
|
- LICENSE
|
@@ -231,6 +231,7 @@ files:
|
|
231
231
|
- lib/instana/instrumentation.rb
|
232
232
|
- lib/instana/instrumentation/dalli.rb
|
233
233
|
- lib/instana/instrumentation/excon.rb
|
234
|
+
- lib/instana/instrumentation/graphql.rb
|
234
235
|
- lib/instana/instrumentation/grpc.rb
|
235
236
|
- lib/instana/instrumentation/net-http.rb
|
236
237
|
- lib/instana/instrumentation/rack.rb
|
@@ -242,6 +243,7 @@ files:
|
|
242
243
|
- lib/instana/opentracing/carrier.rb
|
243
244
|
- lib/instana/opentracing/tracer.rb
|
244
245
|
- lib/instana/rack.rb
|
246
|
+
- lib/instana/secrets.rb
|
245
247
|
- lib/instana/setup.rb
|
246
248
|
- lib/instana/test.rb
|
247
249
|
- lib/instana/thread_local.rb
|
@@ -274,6 +276,7 @@ files:
|
|
274
276
|
- test/instana_test.rb
|
275
277
|
- test/instrumentation/dalli_test.rb
|
276
278
|
- test/instrumentation/excon_test.rb
|
279
|
+
- test/instrumentation/graphql_test.rb
|
277
280
|
- test/instrumentation/grpc_test.rb
|
278
281
|
- test/instrumentation/net-http_test.rb
|
279
282
|
- test/instrumentation/redis_test.rb
|
@@ -287,6 +290,7 @@ files:
|
|
287
290
|
- test/jobs/sidekiq_job_2.rb
|
288
291
|
- test/models/block.rb
|
289
292
|
- test/models/block6.rb
|
293
|
+
- test/secrets_test.rb
|
290
294
|
- test/servers/grpc_50051.rb
|
291
295
|
- test/servers/helpers/sidekiq_worker_initializer.rb
|
292
296
|
- test/servers/rackapp_6511.rb
|
@@ -296,7 +300,6 @@ files:
|
|
296
300
|
- test/tracing/custom_test.rb
|
297
301
|
- test/tracing/id_management_test.rb
|
298
302
|
- test/tracing/opentracing_test.rb
|
299
|
-
- test/tracing/trace_test.rb
|
300
303
|
- test/tracing/tracer_async_test.rb
|
301
304
|
- test/tracing/tracer_test.rb
|
302
305
|
homepage: https://www.instana.com/
|
@@ -322,7 +325,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
322
325
|
- !ruby/object:Gem::Version
|
323
326
|
version: '0'
|
324
327
|
requirements: []
|
325
|
-
rubygems_version: 3.
|
328
|
+
rubygems_version: 3.1.4
|
326
329
|
signing_key:
|
327
330
|
specification_version: 4
|
328
331
|
summary: Ruby Distributed Tracing & Metrics Sensor for Instana
|
@@ -332,11 +335,12 @@ test_files:
|
|
332
335
|
- test/tracing/tracer_test.rb
|
333
336
|
- test/tracing/custom_test.rb
|
334
337
|
- test/tracing/opentracing_test.rb
|
335
|
-
- test/tracing/trace_test.rb
|
336
338
|
- test/tracing/tracer_async_test.rb
|
337
339
|
- test/agent/agent_test.rb
|
338
340
|
- test/models/block.rb
|
339
341
|
- test/models/block6.rb
|
342
|
+
- test/secrets_test.rb
|
343
|
+
- test/instrumentation/graphql_test.rb
|
340
344
|
- test/instrumentation/sidekiq-client_test.rb
|
341
345
|
- test/instrumentation/resque_test.rb
|
342
346
|
- test/instrumentation/sidekiq-worker_test.rb
|
data/.travis.yml
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
|
3
|
-
cache:
|
4
|
-
bundler: true
|
5
|
-
directories:
|
6
|
-
- vendor/bundle
|
7
|
-
|
8
|
-
rvm:
|
9
|
-
- 2.6
|
10
|
-
- 2.4
|
11
|
-
|
12
|
-
before_install:
|
13
|
-
- gem update --system
|
14
|
-
- gem install bundler
|
15
|
-
- gem --version
|
16
|
-
|
17
|
-
before_script:
|
18
|
-
- psql -c 'create database travis_ci_test;' -U postgres
|
19
|
-
- mysql -e 'CREATE DATABASE travis_ci_test;'
|
20
|
-
|
21
|
-
script: "bundle exec rake test"
|
22
|
-
|
23
|
-
services:
|
24
|
-
- memcached
|
25
|
-
- redis
|
26
|
-
- mysql
|
27
|
-
- postgresql
|
28
|
-
|
29
|
-
gemfile:
|
30
|
-
- Gemfile
|
31
|
-
- gemfiles/libraries.gemfile
|
32
|
-
- gemfiles/rails50.gemfile
|
33
|
-
- gemfiles/rails60.gemfile
|
34
|
-
|
35
|
-
matrix:
|
36
|
-
exclude:
|
37
|
-
- rvm: 2.4
|
38
|
-
gemfile: gemfiles/rails60.gemfile
|
39
|
-
|
40
|
-
notifications:
|
41
|
-
slack:
|
42
|
-
rooms:
|
43
|
-
secure: Ae9tJmBO9/sgYWthHRS5uufAf8s6uIMdtmQn+gBkcAXaMWJgt1IAzpIj98Qsg15/lhHS8ezwCe7WIAWC4mM1cnwl/hP195dbgLzF4D2uOjaIXj55ckIIE06jBX1yHapu0vMFSaKwgL4auEEVg4xkehBb9TzLNG/LbExadZQOIkeLdtgU04VrPfDC9pZWPplXT4kzjMZkMESzBYaCfNl6eenu0sHdoxSvngv52MImog6aZQKT+k3ccAa1yzZNhUdy4gSZi1HafXdSCn4UTPDtkNIlsWBW8yprICLxZV/NvgUTEEJYSHO6Ucx9Er22LzKtNbEYlAs1GErGWjDzpqvvXt/5UwNx0rLDrVKI/xMIELEbT047mSgJ8tpVd0ErGA/bnDfbF2oDFTAEXq4jaeAMaVR9Q1CW0ZZF2Jh5jOKc41U+AVGgaMDaBA0ukDSeXvJcnteZ9EllOO8ZAtC2FKtBNnj36W13KTR0TkjMCl+KOiVJXnOyRJIR+CUL9BdDuODBVPZHqZaZ48N+MOG9dRb+fvkdTnwh7hU+UmR08kOsd4x+dDlm4dBrFrB8v8udQ7XuBN9AOZty2CPWFUSJM1BxtetyS3We0L6lQ8o/B9STFNK4KTa/M8wNq1Fm85h3ZKHHIHDpQnXM6vD8SV1p9u91C5UI8rEyxzW5IaT2oqXsCzU=
|