rubygems-update 2.3.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rubygems-update might be problematic. Click here for more details.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CONTRIBUTING +14 -2
- data/History.txt +63 -0
- data/Rakefile +68 -91
- data/lib/rubygems.rb +5 -3
- data/lib/rubygems/command_manager.rb +1 -0
- data/lib/rubygems/commands/contents_command.rb +23 -2
- data/lib/rubygems/commands/install_command.rb +8 -0
- data/lib/rubygems/commands/open_command.rb +1 -8
- data/lib/rubygems/commands/uninstall_command.rb +9 -1
- data/lib/rubygems/commands/update_command.rb +1 -1
- data/lib/rubygems/core_ext/kernel_gem.rb +8 -1
- data/lib/rubygems/core_ext/kernel_require.rb +12 -22
- data/lib/rubygems/defaults.rb +17 -5
- data/lib/rubygems/dependency.rb +7 -1
- data/lib/rubygems/dependency_installer.rb +3 -0
- data/lib/rubygems/ext/ext_conf_builder.rb +13 -11
- data/lib/rubygems/install_update_options.rb +13 -0
- data/lib/rubygems/installer.rb +36 -20
- data/lib/rubygems/installer_test_case.rb +2 -0
- data/lib/rubygems/local_remote_options.rb +1 -1
- data/lib/rubygems/name_tuple.rb +1 -1
- data/lib/rubygems/request_set.rb +14 -3
- data/lib/rubygems/request_set/gem_dependency_api.rb +12 -0
- data/lib/rubygems/request_set/lockfile.rb +3 -1
- data/lib/rubygems/resolver.rb +15 -0
- data/lib/rubygems/resolver/best_set.rb +28 -0
- data/lib/rubygems/resolver/conflict.rb +45 -7
- data/lib/rubygems/resolver/git_specification.rb +24 -0
- data/lib/rubygems/resolver/lock_specification.rb +22 -0
- data/lib/rubygems/source.rb +2 -0
- data/lib/rubygems/source/git.rb +1 -1
- data/lib/rubygems/source/installed.rb +2 -1
- data/lib/rubygems/specification.rb +16 -15
- data/lib/rubygems/test_case.rb +9 -5
- data/test/rubygems/test_gem.rb +72 -2
- data/test/rubygems/test_gem_commands_contents_command.rb +46 -3
- data/test/rubygems/test_gem_commands_install_command.rb +32 -0
- data/test/rubygems/test_gem_commands_uninstall_command.rb +18 -0
- data/test/rubygems/test_gem_dependency.rb +23 -0
- data/test/rubygems/test_gem_dependency_installer.rb +17 -0
- data/test/rubygems/test_gem_ext_builder.rb +12 -1
- data/test/rubygems/test_gem_ext_ext_conf_builder.rb +2 -2
- data/test/rubygems/test_gem_impossible_dependencies_error.rb +24 -8
- data/test/rubygems/test_gem_install_update_options.rb +16 -0
- data/test/rubygems/test_gem_installer.rb +52 -0
- data/test/rubygems/test_gem_local_remote_options.rb +13 -0
- data/test/rubygems/test_gem_package.rb +3 -1
- data/test/rubygems/test_gem_package_tar_header.rb +2 -0
- data/test/rubygems/test_gem_package_tar_reader.rb +11 -1
- data/test/rubygems/test_gem_package_tar_reader_entry.rb +17 -2
- data/test/rubygems/test_gem_package_tar_writer.rb +1 -0
- data/test/rubygems/test_gem_remote_fetcher.rb +24 -0
- data/test/rubygems/test_gem_request_set.rb +74 -4
- data/test/rubygems/test_gem_request_set_gem_dependency_api.rb +9 -1
- data/test/rubygems/test_gem_request_set_lockfile.rb +3 -1
- data/test/rubygems/test_gem_requirement.rb +8 -0
- data/test/rubygems/test_gem_resolver.rb +39 -0
- data/test/rubygems/test_gem_resolver_best_set.rb +57 -0
- data/test/rubygems/test_gem_resolver_conflict.rb +22 -10
- data/test/rubygems/test_gem_resolver_git_specification.rb +12 -0
- data/test/rubygems/test_gem_source_git.rb +6 -2
- data/test/rubygems/test_gem_source_installed.rb +8 -0
- data/test/rubygems/test_gem_source_lock.rb +2 -2
- data/test/rubygems/test_gem_source_vendor.rb +4 -0
- data/test/rubygems/test_kernel.rb +6 -0
- data/test/rubygems/test_require.rb +60 -0
- metadata +5 -5
- metadata.gz.sig +0 -0
@@ -170,6 +170,45 @@ class TestGemResolver < Gem::TestCase
|
|
170
170
|
assert_empty reqs
|
171
171
|
end
|
172
172
|
|
173
|
+
def test_resolve_conservative
|
174
|
+
a1_spec = util_spec 'a', 1
|
175
|
+
a2_spec = util_spec 'a', 2 do |s|
|
176
|
+
s.add_dependency 'b', 2
|
177
|
+
s.add_dependency 'c'
|
178
|
+
end
|
179
|
+
b1_spec = util_spec 'b', 1
|
180
|
+
b2_spec = util_spec 'b', 2
|
181
|
+
c1_spec = util_spec 'c', 1 do |s| s.add_dependency 'd', 2 end
|
182
|
+
c2_spec = util_spec 'c', 2 do |s| s.add_dependency 'd', 2 end
|
183
|
+
d1_spec = util_spec 'd', 1 do |s| s.add_dependency 'e' end
|
184
|
+
d2_spec = util_spec 'd', 2 do |s| s.add_dependency 'e' end
|
185
|
+
e1_spec = util_spec 'e', 1
|
186
|
+
e2_spec = util_spec 'e', 2
|
187
|
+
|
188
|
+
a_dep = make_dep 'a', '= 2'
|
189
|
+
e_dep = make_dep 'e'
|
190
|
+
|
191
|
+
# When requesting to install:
|
192
|
+
# a-2, e
|
193
|
+
deps = [a_dep, e_dep]
|
194
|
+
|
195
|
+
s = set a1_spec, a2_spec, b1_spec, b2_spec, c1_spec, c2_spec, d1_spec, d2_spec, e1_spec, e2_spec
|
196
|
+
|
197
|
+
res = Gem::Resolver.new deps, s
|
198
|
+
|
199
|
+
# With the following gems already installed:
|
200
|
+
# a-1, b-1, c-1, e-1
|
201
|
+
res.skip_gems = {'a'=>[a1_spec], 'b'=>[b1_spec], 'c'=>[c1_spec], 'e'=>[e1_spec]}
|
202
|
+
|
203
|
+
# Make sure the following gems end up getting used/installed/upgraded:
|
204
|
+
# a-2 (upgraded)
|
205
|
+
# b-2 (upgraded), specific dependency from a-2
|
206
|
+
# c-1 (used, not upgraded), open dependency from a-2
|
207
|
+
# d-2 (installed), specific dependency from c-2
|
208
|
+
# e-1 (used, not upgraded), open dependency from request
|
209
|
+
assert_resolves_to [a2_spec, b2_spec, c1_spec, d2_spec, e1_spec], res
|
210
|
+
end
|
211
|
+
|
173
212
|
def test_resolve_development
|
174
213
|
a_spec = util_spec 'a', 1 do |s| s.add_development_dependency 'b' end
|
175
214
|
b_spec = util_spec 'b', 1 do |s| s.add_development_dependency 'c' end
|
@@ -32,6 +32,26 @@ class TestGemResolverBestSet < Gem::TestCase
|
|
32
32
|
assert_equal %w[a-1], found.map { |s| s.full_name }
|
33
33
|
end
|
34
34
|
|
35
|
+
def test_find_all_fallback
|
36
|
+
spec_fetcher do |fetcher|
|
37
|
+
fetcher.spec 'a', 1
|
38
|
+
end
|
39
|
+
|
40
|
+
set = @DR::BestSet.new
|
41
|
+
|
42
|
+
api_uri = URI(@gem_repo) + './api/v1/dependencies'
|
43
|
+
|
44
|
+
set.sets << Gem::Resolver::APISet.new(api_uri)
|
45
|
+
|
46
|
+
dependency = dep 'a', '~> 1'
|
47
|
+
|
48
|
+
req = @DR::DependencyRequest.new dependency, nil
|
49
|
+
|
50
|
+
found = set.find_all req
|
51
|
+
|
52
|
+
assert_equal %w[a-1], found.map { |s| s.full_name }
|
53
|
+
end
|
54
|
+
|
35
55
|
def test_find_all_local
|
36
56
|
spec_fetcher do |fetcher|
|
37
57
|
fetcher.spec 'a', 1
|
@@ -76,5 +96,42 @@ class TestGemResolverBestSet < Gem::TestCase
|
|
76
96
|
assert_empty set.sets
|
77
97
|
end
|
78
98
|
|
99
|
+
def test_replace_failed_api_set
|
100
|
+
set = @DR::BestSet.new
|
101
|
+
|
102
|
+
api_uri = URI(@gem_repo) + './api/v1/dependencies'
|
103
|
+
api_set = Gem::Resolver::APISet.new api_uri
|
104
|
+
|
105
|
+
set.sets << api_set
|
106
|
+
|
107
|
+
error_uri = api_uri + '?gems=a'
|
108
|
+
|
109
|
+
error = Gem::RemoteFetcher::FetchError.new 'bogus', error_uri
|
110
|
+
|
111
|
+
set.replace_failed_api_set error
|
112
|
+
|
113
|
+
assert_equal 1, set.sets.size
|
114
|
+
|
115
|
+
refute_includes set.sets, api_set
|
116
|
+
|
117
|
+
assert_kind_of Gem::Resolver::IndexSet, set.sets.first
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_replace_failed_api_set_no_api_set
|
121
|
+
set = @DR::BestSet.new
|
122
|
+
|
123
|
+
index_set = Gem::Resolver::IndexSet.new Gem::Source.new @gem_repo
|
124
|
+
|
125
|
+
set.sets << index_set
|
126
|
+
|
127
|
+
error = Gem::RemoteFetcher::FetchError.new 'bogus', @gem_repo
|
128
|
+
|
129
|
+
e = assert_raises Gem::RemoteFetcher::FetchError do
|
130
|
+
set.replace_failed_api_set error
|
131
|
+
end
|
132
|
+
|
133
|
+
assert_equal error, e
|
134
|
+
end
|
135
|
+
|
79
136
|
end
|
80
137
|
|
@@ -22,10 +22,17 @@ class TestGemResolverConflict < Gem::TestCase
|
|
22
22
|
Gem::Resolver::Conflict.new child, active
|
23
23
|
|
24
24
|
expected = <<-EXPECTED
|
25
|
-
Activated net-ssh-2.2.2
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
Activated net-ssh-2.2.2
|
26
|
+
which does not match conflicting dependency (>= 2.6.5)
|
27
|
+
|
28
|
+
Conflicting dependency chains:
|
29
|
+
net-ssh (>= 2.0.13), 2.2.2 activated
|
30
|
+
|
31
|
+
versus:
|
32
|
+
rye (= 0.9.8), 0.9.8 activated depends on
|
33
|
+
net-ssh (>= 2.0.13), 2.2.2 activated depends on
|
34
|
+
net-ssh (>= 2.6.5)
|
35
|
+
|
29
36
|
EXPECTED
|
30
37
|
|
31
38
|
assert_equal expected, conflict.explanation
|
@@ -44,10 +51,15 @@ class TestGemResolverConflict < Gem::TestCase
|
|
44
51
|
conflict = @DR::Conflict.new a1_req, activated
|
45
52
|
|
46
53
|
expected = <<-EXPECTED
|
47
|
-
Activated a-2
|
48
|
-
|
49
|
-
|
50
|
-
|
54
|
+
Activated a-2
|
55
|
+
which does not match conflicting dependency (= 1)
|
56
|
+
|
57
|
+
Conflicting dependency chains:
|
58
|
+
a (= 2), 2 activated
|
59
|
+
|
60
|
+
versus:
|
61
|
+
a (= 1)
|
62
|
+
|
51
63
|
EXPECTED
|
52
64
|
|
53
65
|
assert_equal expected, conflict.explanation
|
@@ -64,8 +76,8 @@ class TestGemResolverConflict < Gem::TestCase
|
|
64
76
|
Gem::Resolver::Conflict.new nil, nil
|
65
77
|
|
66
78
|
expected = [
|
67
|
-
'net-ssh
|
68
|
-
'rye
|
79
|
+
'net-ssh (>= 2.0.13), 2.2.2 activated',
|
80
|
+
'rye (= 0.9.8), 0.9.8 activated'
|
69
81
|
]
|
70
82
|
|
71
83
|
assert_equal expected, conflict.request_path(child.requester)
|
@@ -32,6 +32,18 @@ class TestGemResolverGitSpecification < Gem::TestCase
|
|
32
32
|
refute_equal g_spec_a, i_spec
|
33
33
|
end
|
34
34
|
|
35
|
+
def test_add_dependency
|
36
|
+
git_gem 'a', 1
|
37
|
+
|
38
|
+
git_spec = Gem::Resolver::GitSpecification.new @set, @spec
|
39
|
+
|
40
|
+
b_dep = dep 'b'
|
41
|
+
|
42
|
+
git_spec.add_dependency b_dep
|
43
|
+
|
44
|
+
assert_equal [b_dep], git_spec.dependencies
|
45
|
+
end
|
46
|
+
|
35
47
|
def test_install
|
36
48
|
git_gem 'a', 1
|
37
49
|
|
@@ -194,14 +194,18 @@ class TestGemSourceGit < Gem::TestCase
|
|
194
194
|
git = Gem::Source::Git.new 'a', 'git/a', 'master', false
|
195
195
|
remote = Gem::Source.new @gem_repo
|
196
196
|
installed = Gem::Source::Installed.new
|
197
|
+
vendor = Gem::Source::Vendor.new 'vendor/foo'
|
197
198
|
|
198
199
|
assert_equal( 0, git. <=>(git), 'git <=> git')
|
199
200
|
|
200
201
|
assert_equal( 1, git. <=>(remote), 'git <=> remote')
|
201
202
|
assert_equal(-1, remote. <=>(git), 'remote <=> git')
|
202
203
|
|
203
|
-
assert_equal( 1, installed
|
204
|
-
assert_equal(-1, git
|
204
|
+
assert_equal( 1, git. <=>(installed), 'git <=> installed')
|
205
|
+
assert_equal(-1, installed.<=>(git), 'installed <=> git')
|
206
|
+
|
207
|
+
assert_equal(-1, git. <=>(vendor), 'git <=> vendor')
|
208
|
+
assert_equal( 1, vendor. <=>(git), 'vendor <=> git')
|
205
209
|
end
|
206
210
|
|
207
211
|
def test_specs
|
@@ -11,6 +11,8 @@ class TestGemSourceInstalled < Gem::TestCase
|
|
11
11
|
specific = Gem::Source::SpecificFile.new a1.cache_file
|
12
12
|
installed = Gem::Source::Installed.new
|
13
13
|
local = Gem::Source::Local.new
|
14
|
+
git = Gem::Source::Git.new 'a', 'a', 'master'
|
15
|
+
vendor = Gem::Source::Vendor.new 'a'
|
14
16
|
|
15
17
|
assert_equal( 0, installed.<=>(installed), 'installed <=> installed')
|
16
18
|
|
@@ -22,6 +24,12 @@ class TestGemSourceInstalled < Gem::TestCase
|
|
22
24
|
|
23
25
|
assert_equal(-1, specific. <=>(installed), 'specific <=> installed')
|
24
26
|
assert_equal( 1, installed.<=>(specific), 'installed <=> specific')
|
27
|
+
|
28
|
+
assert_equal( 1, git. <=>(installed), 'git <=> installed')
|
29
|
+
assert_equal(-1, installed.<=>(git), 'installed <=> git')
|
30
|
+
|
31
|
+
assert_equal( 1, vendor. <=>(installed), 'vendor <=> installed')
|
32
|
+
assert_equal(-1, installed.<=>(vendor), 'installed <=> vendor')
|
25
33
|
end
|
26
34
|
|
27
35
|
end
|
@@ -43,8 +43,8 @@ class TestGemSourceLock < Gem::TestCase
|
|
43
43
|
assert_equal( 0, i_lock.<=>(i_lock), 'i_lock <=> i_lock')
|
44
44
|
assert_equal( 0, v_lock.<=>(v_lock), 'v_lock <=> v_lock')
|
45
45
|
|
46
|
-
assert_equal(
|
47
|
-
assert_equal(
|
46
|
+
assert_equal( 1, g_lock.<=>(i_lock), 'g_lock <=> i_lock')
|
47
|
+
assert_equal(-1, i_lock.<=>(g_lock), 'i_lock <=> g_lock')
|
48
48
|
|
49
49
|
assert_equal(-1, g_lock.<=>(v_lock), 'g_lock <=> v_lock')
|
50
50
|
assert_equal( 1, v_lock.<=>(g_lock), 'v_lock <=> g_lock')
|
@@ -12,6 +12,7 @@ class TestGemSourceVendor < Gem::TestCase
|
|
12
12
|
def test_spaceship
|
13
13
|
vendor = Gem::Source::Vendor.new 'vendor/foo'
|
14
14
|
remote = Gem::Source.new @gem_repo
|
15
|
+
git = Gem::Source::Git.new 'a', 'a', 'master'
|
15
16
|
installed = Gem::Source::Installed.new
|
16
17
|
|
17
18
|
assert_equal( 0, vendor. <=>(vendor), 'vendor <=> vendor')
|
@@ -19,6 +20,9 @@ class TestGemSourceVendor < Gem::TestCase
|
|
19
20
|
assert_equal( 1, vendor. <=>(remote), 'vendor <=> remote')
|
20
21
|
assert_equal(-1, remote. <=>(vendor), 'remote <=> vendor')
|
21
22
|
|
23
|
+
assert_equal( 1, vendor. <=>(git), 'vendor <=> git')
|
24
|
+
assert_equal(-1, git. <=>(vendor), 'git <=> vendor')
|
25
|
+
|
22
26
|
assert_equal( 1, vendor. <=>(installed), 'vendor <=> installed')
|
23
27
|
assert_equal(-1, installed.<=>(vendor), 'installed <=> vendor')
|
24
28
|
end
|
@@ -33,6 +33,12 @@ class TestKernel < Gem::TestCase
|
|
33
33
|
assert_equal 1, $:.select { |p| %r{a-1/lib} =~ p }.size
|
34
34
|
end
|
35
35
|
|
36
|
+
def test_gem_prerelease
|
37
|
+
quick_gem 'd', '1.1.a'
|
38
|
+
refute gem('d', '>= 1'), 'release requirement must not load prerelease'
|
39
|
+
assert gem('d', '>= 1.a'), 'prerelease requirement may load prerelease'
|
40
|
+
end
|
41
|
+
|
36
42
|
def test_gem_conflicting
|
37
43
|
assert gem('a', '= 1'), "Should load"
|
38
44
|
|
@@ -2,6 +2,26 @@ require 'rubygems/test_case'
|
|
2
2
|
require 'rubygems'
|
3
3
|
|
4
4
|
class TestGemRequire < Gem::TestCase
|
5
|
+
class Latch
|
6
|
+
def initialize count = 1
|
7
|
+
@count = count
|
8
|
+
@lock = Monitor.new
|
9
|
+
@cv = @lock.new_cond
|
10
|
+
end
|
11
|
+
|
12
|
+
def release
|
13
|
+
@lock.synchronize do
|
14
|
+
@count -= 1 if @count > 0
|
15
|
+
@cv.broadcast if @count.zero?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def await
|
20
|
+
@lock.synchronize do
|
21
|
+
@cv.wait_while { @count > 0 }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
5
25
|
|
6
26
|
def setup
|
7
27
|
super
|
@@ -17,6 +37,46 @@ class TestGemRequire < Gem::TestCase
|
|
17
37
|
assert require(path), "'#{path}' was already required"
|
18
38
|
end
|
19
39
|
|
40
|
+
def append_latch spec
|
41
|
+
dir = spec.gem_dir
|
42
|
+
Dir.chdir dir do
|
43
|
+
spec.files.each do |file|
|
44
|
+
File.open file, 'a' do |fp|
|
45
|
+
fp.puts "FILE_ENTERED_LATCH.release"
|
46
|
+
fp.puts "FILE_EXIT_LATCH.await"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_concurrent_require
|
53
|
+
Object.const_set :FILE_ENTERED_LATCH, Latch.new(2)
|
54
|
+
Object.const_set :FILE_EXIT_LATCH, Latch.new(1)
|
55
|
+
|
56
|
+
a1 = new_spec "a", "1", nil, "lib/a.rb"
|
57
|
+
b1 = new_spec "b", "1", nil, "lib/b.rb"
|
58
|
+
|
59
|
+
install_specs a1, b1
|
60
|
+
|
61
|
+
append_latch a1
|
62
|
+
append_latch b1
|
63
|
+
|
64
|
+
t1 = Thread.new { assert_require 'a' }
|
65
|
+
t2 = Thread.new { assert_require 'b' }
|
66
|
+
|
67
|
+
# wait until both files are waiting on the exit latch
|
68
|
+
FILE_ENTERED_LATCH.await
|
69
|
+
|
70
|
+
# now let them finish
|
71
|
+
FILE_EXIT_LATCH.release
|
72
|
+
|
73
|
+
assert t1.join, "thread 1 should exit"
|
74
|
+
assert t2.join, "thread 2 should exit"
|
75
|
+
ensure
|
76
|
+
Object.send :remove_const, :FILE_ENTERED_LATCH
|
77
|
+
Object.send :remove_const, :FILE_EXIT_LATCH
|
78
|
+
end
|
79
|
+
|
20
80
|
def test_require_is_not_lazy_with_exact_req
|
21
81
|
a1 = new_spec "a", "1", {"b" => "= 1"}, "lib/test_gem_require_a.rb"
|
22
82
|
b1 = new_spec "b", "1", nil, "lib/b/c.rb"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubygems-update
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jim Weirich
|
@@ -31,7 +31,7 @@ cert_chain:
|
|
31
31
|
pfkQPF5Ezsi73pEpFN93Fy21NKCYQH1jCwWeKUF29MIMGd6kE3ZmHW/7fz5GwKIM
|
32
32
|
Ls5SgY48a0l7Hw==
|
33
33
|
-----END CERTIFICATE-----
|
34
|
-
date: 2014-
|
34
|
+
date: 2014-07-17 00:00:00.000000000 Z
|
35
35
|
dependencies:
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: minitest
|
@@ -39,14 +39,14 @@ dependencies:
|
|
39
39
|
requirements:
|
40
40
|
- - "~>"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: '5.
|
42
|
+
version: '5.3'
|
43
43
|
type: :development
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
47
|
- - "~>"
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: '5.
|
49
|
+
version: '5.3'
|
50
50
|
- !ruby/object:Gem::Dependency
|
51
51
|
name: rdoc
|
52
52
|
requirement: !ruby/object:Gem::Requirement
|
@@ -548,7 +548,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
548
548
|
version: '0'
|
549
549
|
requirements: []
|
550
550
|
rubyforge_project: rubygems-update
|
551
|
-
rubygems_version: 2.
|
551
|
+
rubygems_version: 2.3.0
|
552
552
|
signing_key:
|
553
553
|
specification_version: 4
|
554
554
|
summary: RubyGems is a package management framework for Ruby
|
metadata.gz.sig
CHANGED
Binary file
|