tracksperanto 3.3.12 → 3.3.13
Sign up to get free protection for your applications and to get access to all the features.
- data/CONTRIBUTING.md +25 -14
- data/Gemfile +1 -1
- data/History.txt +4 -0
- data/{README.rdoc → README.md} +24 -18
- data/Rakefile +7 -4
- data/lib/import/nuke_script.rb +2 -1
- data/lib/import/shake_script.rb +11 -2
- data/lib/tracksperanto.rb +7 -2
- data/lib/tracksperanto/buffer_io.rb +14 -6
- data/lib/tracksperanto/ext_io.rb +2 -3
- data/lib/tracksperanto/io_wrapper.rb +8 -0
- data/test/import/test_nuke_import.rb +28 -0
- data/test/import/test_shake_script_import.rb +7 -0
- data/test/test_buffer_io.rb +2 -2
- data/tracksperanto.gemspec +15 -13
- metadata +209 -213
data/CONTRIBUTING.md
CHANGED
@@ -7,7 +7,7 @@ can chew on. Contributions or patches without tests will be rejected at sight.
|
|
7
7
|
|
8
8
|
### Development environment
|
9
9
|
|
10
|
-
Tracksperanto is currently being developed on Ruby
|
10
|
+
Tracksperanto is currently being developed on Ruby 2.0.0 but we maintain compatibility down to 1.8.7.
|
11
11
|
What you will need is everything mentioned in the Gemfile plus Bundler.
|
12
12
|
Development should be done agains the git checkout because the gem does not contain the test files
|
13
13
|
(various example files in different formats that are used for verifying all the import and export modules).
|
@@ -24,30 +24,42 @@ So, to get started:
|
|
24
24
|
|
25
25
|
### Internal tracker representation
|
26
26
|
|
27
|
-
The trackers are represented by Tracker objects, which
|
27
|
+
The trackers are represented by Tracker objects, which walk and quack like Arrays of frames. The Tracker objects
|
28
28
|
contain Keyframe objects, and those in turn contain coordinates. The coordinates are stored in absolute pixels, relative to
|
29
|
-
the zero coordinate in the lower left corner.
|
29
|
+
the zero coordinate in the lower left corner. The Tracker objects wacth after you so that you don't put multiple Keyframes on
|
30
|
+
the same frame number, keep Keyframes sorted and so on - in short, they are a nice container. They are also what is `yield`ed
|
31
|
+
when you import.
|
30
32
|
|
31
|
-
|
32
|
-
|
33
|
+
### Coordinate system
|
34
|
+
|
35
|
+
Tracksperanto uses the **bottom left** coordinate system, with positive values going **up and right**.
|
36
|
+
Pixel registration is on the **lower left corner of the pixel**. Thus the absolute left/bottom of the image
|
37
|
+
has coordinates 0,0 (at the lower left corner of the leftmost bottommost pixel) and 0.5x0.5 in the middle of that pixel.
|
38
|
+
|
39
|
+
When importing data, each import module will conform the coordinate system to these conventions. Each export module will
|
40
|
+
convert from this system to whichever is required by the consumer of the file being exported.
|
33
41
|
|
34
42
|
### Importing your own formats
|
35
43
|
|
36
|
-
To write an import module refer to Tracksperanto::Import::Base
|
37
|
-
|
38
|
-
|
39
|
-
|
44
|
+
To write an import module refer to `Tracksperanto::Import::Base` docs. Your importer will be configured with width and height
|
45
|
+
of the comp that it is importing, and will get an IO object with the file that you are processing. You should then `yield` the parsed
|
46
|
+
trackers packed into `Tracker` objects within the `each` method (tracker objects should be Tracksperanto::Tracker objects or compatibles)
|
47
|
+
|
48
|
+
Since the importer objects also mix-in `Enumerable` you can quickly import into an `Array` and so on.
|
40
49
|
|
41
50
|
### Exporting your own formats
|
42
51
|
|
43
|
-
You can easily write an exporter. Refer to the Tracksperanto::Export::Base docs. Note that your exporter should be able to chew alot of data
|
52
|
+
You can easily write an exporter. Refer to the `Tracksperanto::Export::Base` docs. Note that your exporter should be able to chew alot of data
|
44
53
|
(hundreds of trackers with thousands of keyframes with exported files growing up to 5-10 megs in size are not uncommon!). This means that
|
45
54
|
the exporter should work with streams (smaller parts of the file being exported will be held in memory at a time).
|
46
55
|
|
56
|
+
Export modules are decoupled from the internal `Tracker` representation - all the export module ever sees are raw strings, `Integers`
|
57
|
+
and `Floats`
|
58
|
+
|
47
59
|
### Ading your own processing steps
|
48
60
|
|
49
|
-
You probably want to write a Tool (consult the Tracksperanto::Tool::Base docs) if you need some processing applied to the tracks
|
50
|
-
or their data. A Tool is just like an export module, except that instead it sits between the exporter and the exporting routine. Tools wrap export
|
61
|
+
You probably want to write a `Tool` (consult the Tracksperanto::Tool::Base docs) if you need some processing applied to the tracks
|
62
|
+
or their data. A `Tool` is just like an export module, except that instead it sits between the exporter and the exporting routine. Tools wrap export
|
51
63
|
modules or each other, so you can stack different tool modules together (like "scale first, then move").
|
52
64
|
|
53
65
|
### Writing your own processing pipelines from start to finish
|
@@ -79,8 +91,7 @@ the software user-friendly. A well-behaved Tracksperanto module should manage it
|
|
79
91
|
some_importer.io = File.open("source_file.shk")
|
80
92
|
|
81
93
|
# The importer responds to each() so if your file is not too big you can just load all the trackers
|
82
|
-
# as an array.
|
83
|
-
# instead (see Obuf)
|
94
|
+
# as an array.
|
84
95
|
trackers = some_importer.to_a
|
85
96
|
|
86
97
|
# Create the exporter and pass the output file to it
|
data/Gemfile
CHANGED
data/History.txt
CHANGED
data/{README.rdoc → README.md}
RENAMED
@@ -1,13 +1,17 @@
|
|
1
1
|
Tracksperanto is a universal 2D-track translator between many apps.
|
2
2
|
|
3
|
-
|
3
|
+
## Is it any good?
|
4
|
+
|
5
|
+
Yes.
|
6
|
+
|
7
|
+
## Why Tracksperanto?
|
4
8
|
|
5
9
|
Historically, every matchmoving app uses it's own UI for tracking 2D features.
|
6
10
|
Unfortunately, the UIs of these are all different and not very user-friendly. It happens
|
7
11
|
that an app cannot solve a shot that another one will, but you usually have to redo your 2D
|
8
12
|
tracks in each one of them.
|
9
13
|
|
10
|
-
|
14
|
+
### Efficiency when doing tracks
|
11
15
|
|
12
16
|
Another problem with today's matchmoving apps is that they are vastly inefficient when
|
13
17
|
doing 2D tracks. Almost all of them use OpenGL and want to load the whole frame into memory
|
@@ -29,14 +33,14 @@ So it's very natural to track in a modern compositing app that has selective ima
|
|
29
33
|
loading, and then export one single group of tracks into all of the matchmoving
|
30
34
|
applications at once.
|
31
35
|
|
32
|
-
|
36
|
+
### Evaluating different camera solvers
|
33
37
|
|
34
38
|
Since your 2D tracking data is now freely interchangeable you can load the same tracks
|
35
39
|
into multiple 3D tracking applications and see which one gives you a better solve.
|
36
40
|
Should all the 3D camera trackers fail, you can still take your tracks into the 2D
|
37
41
|
compositing world to do the job.
|
38
42
|
|
39
|
-
|
43
|
+
### Processing 2D tracking data
|
40
44
|
|
41
45
|
Sometimes you need to offset your tracks in time, or resize them to a different pixel format.
|
42
46
|
Very few apps allow you to convert your tracks in one step from format to format - like doing
|
@@ -47,13 +51,13 @@ way to solve the shot will be to retrack it from scratch.
|
|
47
51
|
To circumvent this, Tracksperanto allows you to apply transformations to the tracking data
|
48
52
|
that you export - and you can apply multiple transformations if desired.
|
49
53
|
|
50
|
-
|
54
|
+
## Using Tracksperanto from the command line
|
51
55
|
|
52
56
|
To run on your own computer, make sure you have Ruby installed. Versions from 1.8.7
|
53
|
-
and up are supported.
|
57
|
+
and up are supported.
|
54
58
|
|
55
59
|
$ ruby -v
|
56
|
-
ruby
|
60
|
+
ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin13.0.0]
|
57
61
|
|
58
62
|
Then install tracksperanto. It will be downloaded and unpacked automatically for you by the
|
59
63
|
RubyGems system:
|
@@ -71,7 +75,7 @@ To see the supported options, run
|
|
71
75
|
The converted files will be saved in the same directory as the source, if resulting
|
72
76
|
converted files already exist <b>they will be overwritten without warning</b>.
|
73
77
|
|
74
|
-
|
78
|
+
## Using Tracksperanto through the web
|
75
79
|
|
76
80
|
For situations where you cannot install anything on your machine, or you run a shitty OS that cannot
|
77
81
|
run Ruby decently, or you are in a locked-down environment, we offer a web-enabled version of
|
@@ -86,10 +90,11 @@ data (like script and footage paths) from the files before adding them to the re
|
|
86
90
|
|
87
91
|
If you want your own copy of the web application at your facility we can discuss that, but it's not free.
|
88
92
|
|
89
|
-
|
93
|
+
## Format support
|
90
94
|
|
91
95
|
---
|
92
|
-
|
96
|
+
|
97
|
+
### Formats Tracksperanto can read
|
93
98
|
|
94
99
|
* 3DE v3 point export file
|
95
100
|
* 3DE v4 point export file
|
@@ -105,7 +110,7 @@ If you want your own copy of the web application at your facility we can discuss
|
|
105
110
|
* Syntheyes "All Tracker Paths" export .txt file
|
106
111
|
* Syntheyes 2D tracker paths file
|
107
112
|
|
108
|
-
|
113
|
+
### Formats Tracksperanto can export to
|
109
114
|
|
110
115
|
* 3DE v3 point export .txt file
|
111
116
|
* 3DE v4 point export .txt file
|
@@ -126,29 +131,30 @@ If you want your own copy of the web application at your facility we can discuss
|
|
126
131
|
* Shake trackers in a .txt file
|
127
132
|
* Syntheyes 2D tracker paths file
|
128
133
|
* boujou feature tracks
|
134
|
+
|
129
135
|
---
|
130
136
|
|
131
137
|
|
132
|
-
|
138
|
+
## Editing your tracks while converting
|
133
139
|
|
134
140
|
Tracksperanto has a number of features to scale, move, slip, distort and rename trackers.
|
135
141
|
Consult the --help option to see what is available.
|
136
142
|
|
137
|
-
|
143
|
+
## Development
|
138
144
|
|
139
|
-
|
145
|
+
![Gem Version](https://badge.fury.io/rb/tracksperanto.png)
|
146
|
+
![tests](https://secure.travis-ci.org/guerilla-di/tracksperanto.png)
|
140
147
|
|
141
148
|
If you are interested in reusing Tracksperanto's code or adding modules to the software consult
|
142
|
-
the
|
149
|
+
the [short developer introduction](https://github.com/guerilla-di/tracksperanto/blob/master/CONTRIBUTING.md)
|
143
150
|
|
144
|
-
|
151
|
+
## Limitations
|
145
152
|
|
146
153
|
Information about the search area, reference area and offset is not passed along (outside
|
147
154
|
of scope for the app and different trackers handle these differently, if at all). For some
|
148
155
|
modules no residual will be passed along (3D tracking apps generally do not export residual
|
149
156
|
with backprojected 3D features).
|
150
157
|
|
151
|
-
|
152
|
-
== Licensing
|
158
|
+
## Licensing
|
153
159
|
|
154
160
|
Tracksperanto is made avalable under the MIT license that is included in the package.
|
data/Rakefile
CHANGED
@@ -38,27 +38,30 @@ after :test do
|
|
38
38
|
formats = StringIO.new
|
39
39
|
|
40
40
|
formats.puts(" ")
|
41
|
-
formats.puts(
|
41
|
+
formats.puts(" ")
|
42
|
+
formats.puts('### Formats Tracksperanto can read')
|
42
43
|
formats.puts(" ")
|
43
44
|
Tracksperanto.importers.each do | import_mdoule |
|
44
45
|
formats.puts("* %s" % import_mdoule.human_name)
|
45
46
|
end
|
46
47
|
|
47
48
|
formats.puts(" ")
|
48
|
-
formats.puts('
|
49
|
+
formats.puts('### Formats Tracksperanto can export to')
|
49
50
|
formats.puts(" ")
|
50
51
|
Tracksperanto.exporters.each do | export_module |
|
51
52
|
formats.puts("* %s" % export_module.human_name)
|
52
53
|
end
|
54
|
+
formats.puts(" ")
|
53
55
|
|
54
|
-
readme_text = File.read(File.dirname(__FILE__) + "/README.
|
56
|
+
readme_text = File.read(File.dirname(__FILE__) + "/README.md")
|
55
57
|
three = readme_text.split('---')
|
56
58
|
raise "Should split in 3" unless three.length == 3
|
57
59
|
three[1] = formats.string
|
58
60
|
|
59
|
-
File.open(File.dirname(__FILE__) + "/README.
|
61
|
+
File.open(File.dirname(__FILE__) + "/README.md", "w") do | f |
|
60
62
|
f.write(three.join('---'))
|
61
63
|
end
|
64
|
+
|
62
65
|
end
|
63
66
|
|
64
67
|
task :default => [ :test ]
|
data/lib/import/nuke_script.rb
CHANGED
@@ -14,11 +14,12 @@ class Tracksperanto::Import::NukeScript < Tracksperanto::Import::Base
|
|
14
14
|
|
15
15
|
def self.known_snags
|
16
16
|
"The only supported nodes that we can extract tracks from are Transform2D, Reconcile3D, " +
|
17
|
-
"PlanarTracker and Tracker (
|
17
|
+
"PlanarTracker and Tracker (we support Nuke 5 up to and including 8)"
|
18
18
|
end
|
19
19
|
|
20
20
|
def each
|
21
21
|
parser = Tickly::NodeProcessor.new
|
22
|
+
|
22
23
|
parser.add_node_handler_class(Tracker3)
|
23
24
|
parser.add_node_handler_class(Reconcile3D)
|
24
25
|
parser.add_node_handler_class(PlanarTracker1_0)
|
data/lib/import/shake_script.rb
CHANGED
@@ -262,15 +262,24 @@ class Tracksperanto::Import::ShakeScript < Tracksperanto::Import::Base
|
|
262
262
|
end.compact
|
263
263
|
end
|
264
264
|
|
265
|
+
# Remove tuples which have more than 2 values, and tuples that
|
266
|
+
# have non-Numeric members
|
267
|
+
def clean_tuples(frame_and_value_tuples)
|
268
|
+
frame_and_value_tuples.reject do | element |
|
269
|
+
element.length > 2
|
270
|
+
end.reject do | element |
|
271
|
+
element.any?{|e| !e.is_a?(Numeric) }
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
265
275
|
def collect_stabilizer_tracker(name, x_curve, y_curve)
|
266
276
|
return unless valid_curves?(x_curve, y_curve)
|
267
277
|
|
268
278
|
report_progress("Assembling Stabilizer node tracker #{name}")
|
269
279
|
|
270
|
-
keyframes = zip_curve_tuples(x_curve, y_curve).map do | (frame, x, y) |
|
280
|
+
keyframes = zip_curve_tuples(clean_tuples(x_curve), clean_tuples(y_curve)).map do | (frame, x, y) |
|
271
281
|
Tracksperanto::Keyframe.new(:frame => frame - 1, :abs_x => x, :abs_y => y)
|
272
282
|
end
|
273
|
-
|
274
283
|
Tracksperanto::Tracker.new(:name => name, :keyframes => keyframes)
|
275
284
|
end
|
276
285
|
|
data/lib/tracksperanto.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
-
|
2
|
+
require 'stringio'
|
3
|
+
require 'forwardable'
|
4
|
+
require 'tempfile'
|
3
5
|
|
4
6
|
module Tracksperanto
|
5
7
|
PATH = File.expand_path(File.dirname(__FILE__))
|
6
|
-
VERSION = '3.3.
|
8
|
+
VERSION = '3.3.13'
|
7
9
|
|
8
10
|
module Import; end
|
9
11
|
module Export; end
|
@@ -86,6 +88,8 @@ module Tracksperanto
|
|
86
88
|
|
87
89
|
end
|
88
90
|
|
91
|
+
# We do get loaded as a library so do not add to the load paths,
|
92
|
+
# just load directly
|
89
93
|
%w(
|
90
94
|
returning
|
91
95
|
const_name
|
@@ -96,6 +100,7 @@ end
|
|
96
100
|
keyframe
|
97
101
|
tracker
|
98
102
|
format_detector
|
103
|
+
io_wrapper
|
99
104
|
ext_io
|
100
105
|
buffer_io
|
101
106
|
simple_export
|
@@ -1,16 +1,24 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
require "tempfile"
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
class IOWrapper
|
6
|
+
extend Forwardable
|
7
|
+
attr_reader :backing_buffer
|
8
|
+
IO_METHODS = (IO.instance_methods - Object.instance_methods - Enumerable.instance_methods).map{|e| e.to_sym }
|
9
|
+
def_delegators :backing_buffer, *IO_METHODS
|
10
|
+
end
|
3
11
|
|
4
12
|
# BufferIO is used for writing big segments of text. It works like a StringIO, but when the size
|
5
13
|
# of the underlying string buffer exceeds MAX_IN_MEM_BYTES the string will be flushed to disk
|
6
14
|
# and it automagically becomes a Tempfile
|
7
|
-
class Tracksperanto::BufferIO <
|
15
|
+
class Tracksperanto::BufferIO < Tracksperanto::IOWrapper
|
8
16
|
include Tracksperanto::Returning
|
9
17
|
|
10
18
|
MAX_IN_MEM_BYTES = 5_000_000
|
11
19
|
|
12
20
|
def initialize
|
13
|
-
|
21
|
+
@backing_buffer = StringIO.new
|
14
22
|
end
|
15
23
|
|
16
24
|
def write(s)
|
@@ -27,8 +35,8 @@ class Tracksperanto::BufferIO < DelegateClass(IO)
|
|
27
35
|
end
|
28
36
|
|
29
37
|
def close!
|
30
|
-
|
31
|
-
|
38
|
+
@backing_buffer.close! if @tempfile_in
|
39
|
+
@backing_buffer = nil
|
32
40
|
end
|
33
41
|
|
34
42
|
# Sometimes you just need to upgrade to a File forcibly (for example if you want)
|
@@ -47,7 +55,7 @@ class Tracksperanto::BufferIO < DelegateClass(IO)
|
|
47
55
|
private
|
48
56
|
|
49
57
|
def replace_with_tempfile
|
50
|
-
sio =
|
58
|
+
sio = @backing_buffer
|
51
59
|
tf = Tempfile.new("tracksperanto-xbuf")
|
52
60
|
tf.set_encoding(Encoding::BINARY) if @rewindable_io.respond_to?(:set_encoding)
|
53
61
|
tf.binmode
|
@@ -55,7 +63,7 @@ class Tracksperanto::BufferIO < DelegateClass(IO)
|
|
55
63
|
tf.flush # Needed of we will reopen this file soon from another thread/loop
|
56
64
|
sio.string = ""
|
57
65
|
GC.start
|
58
|
-
|
66
|
+
@backing_buffer = tf
|
59
67
|
|
60
68
|
@tempfile_in = true
|
61
69
|
end
|
data/lib/tracksperanto/ext_io.rb
CHANGED
@@ -6,10 +6,9 @@
|
|
6
6
|
#
|
7
7
|
# io = ExtIO.new(my_open_file)
|
8
8
|
# io.gets_non_empty #=> "This is the first line after 2000 linebreaks"
|
9
|
-
|
10
|
-
class Tracksperanto::ExtIO < DelegateClass(IO)
|
9
|
+
class Tracksperanto::ExtIO < Tracksperanto::IOWrapper
|
11
10
|
def initialize(with)
|
12
|
-
|
11
|
+
@backing_buffer = with
|
13
12
|
end
|
14
13
|
|
15
14
|
# Similar to IO#gets however it will also strip the returned result. This is useful
|
@@ -0,0 +1,8 @@
|
|
1
|
+
# A wrapper for IO which works on the backing buffer
|
2
|
+
# and proxies all IO methods
|
3
|
+
class Tracksperanto::IOWrapper
|
4
|
+
extend Forwardable
|
5
|
+
attr_reader :backing_buffer
|
6
|
+
IO_METHODS = (IO.instance_methods - Object.instance_methods - Enumerable.instance_methods).map{|e| e.to_sym }
|
7
|
+
def_delegators :backing_buffer, *IO_METHODS
|
8
|
+
end
|
@@ -175,6 +175,34 @@ class NukeImportTest < Test::Unit::TestCase
|
|
175
175
|
assert_equal 1, trackers.length
|
176
176
|
end
|
177
177
|
|
178
|
+
def test_parsing_nuke8_tracker4_without_LF_at_end_of_file
|
179
|
+
fixture = File.open(File.dirname(__FILE__) + '/samples/nuke/nuke8_tracker4_copypastes.nk')
|
180
|
+
|
181
|
+
parser = Tracksperanto::Import::NukeScript.new(:io => fixture)
|
182
|
+
parser.width = 2048
|
183
|
+
parser.height = 1152
|
184
|
+
trackers = parser.to_a
|
185
|
+
|
186
|
+
assert_equal 4, trackers.length
|
187
|
+
first_t = trackers[0]
|
188
|
+
assert_equal 'Tracker1_track_1', first_t.name
|
189
|
+
assert_equal 48, first_t.length
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_parsing_nuke8_tracker4
|
193
|
+
fixture = File.open(File.dirname(__FILE__) + '/samples/nuke/track_nuke8.nk')
|
194
|
+
|
195
|
+
parser = Tracksperanto::Import::NukeScript.new(:io => fixture)
|
196
|
+
parser.width = 2048
|
197
|
+
parser.height = 1152
|
198
|
+
trackers = parser.to_a
|
199
|
+
|
200
|
+
assert_equal 5, trackers.length
|
201
|
+
first_t = trackers[0]
|
202
|
+
assert_equal 'Tracker1_track_1', first_t.name
|
203
|
+
assert_equal 88, first_t.length
|
204
|
+
end
|
205
|
+
|
178
206
|
def test_parsing_nuke708_tracker4_with_curve_error
|
179
207
|
fixture = File.open(File.dirname(__FILE__) + '/samples/nuke/A099_L008_0207TW_001_head_R.nk')
|
180
208
|
parser = Tracksperanto::Import::NukeScript.new(:io => fixture, :width => 4800, :height => 2700)
|
@@ -141,6 +141,13 @@ class ShakeScriptImportTest < Test::Unit::TestCase
|
|
141
141
|
assert_equal 850, trackers[0].length
|
142
142
|
end
|
143
143
|
|
144
|
+
def test_stabilize_nodes_in_great_numbers
|
145
|
+
fixture = File.open(File.dirname(__FILE__) + "/samples/shake_script/cliff_many_stabilize.shk")
|
146
|
+
trackers = Tracksperanto::Import::ShakeScript.new(:io => fixture, :width => 1920, :height => 1080).to_a
|
147
|
+
assert_equal 40, trackers.length
|
148
|
+
assert_equal 711, trackers[22].length
|
149
|
+
end
|
150
|
+
|
144
151
|
def test_tracker_supernode_with_curves_having_keyframes_at_negative_offsets
|
145
152
|
fixture = File.open(File.dirname(__FILE__) + "/samples/shake_script/designated_global_range_starting_at_negative_frame.shk")
|
146
153
|
trackers = Tracksperanto::Import::ShakeScript.new(:io => fixture, :width => 720, :height => 576).to_a
|
data/test/test_buffer_io.rb
CHANGED
@@ -6,14 +6,14 @@ class TestBufferIO < Test::Unit::TestCase
|
|
6
6
|
def test_write_in_mem_has_a_stringio
|
7
7
|
io = Tracksperanto::BufferIO.new
|
8
8
|
9000.times { io.write("a") }
|
9
|
-
assert_kind_of StringIO, io.
|
9
|
+
assert_kind_of StringIO, io.backing_buffer
|
10
10
|
assert_nothing_raised { io.close! }
|
11
11
|
end
|
12
12
|
|
13
13
|
def test_write_larger_than_max_swaps_tempfile
|
14
14
|
io = Tracksperanto::BufferIO.new
|
15
15
|
io.write("a" * 6_000_001)
|
16
|
-
f = io.
|
16
|
+
f = io.backing_buffer
|
17
17
|
assert_kind_of Tempfile, f
|
18
18
|
f.rewind
|
19
19
|
assert_equal 6_000_001, f.read.length
|
data/tracksperanto.gemspec
CHANGED
@@ -4,24 +4,25 @@
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
|
-
s.name =
|
8
|
-
s.version = "3.3.
|
7
|
+
s.name = %q{tracksperanto}
|
8
|
+
s.version = "3.3.13"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Julik Tarkhanov"]
|
12
|
-
s.date =
|
13
|
-
s.
|
14
|
-
s.
|
12
|
+
s.date = %q{2014-02-07}
|
13
|
+
s.default_executable = %q{tracksperanto}
|
14
|
+
s.description = %q{Converts 2D track exports between different apps like Flame, MatchMover, PFTrack...}
|
15
|
+
s.email = %q{me@julik.nl}
|
15
16
|
s.executables = ["tracksperanto"]
|
16
17
|
s.extra_rdoc_files = [
|
17
|
-
"README.
|
18
|
+
"README.md"
|
18
19
|
]
|
19
20
|
s.files = [
|
20
21
|
"CONTRIBUTING.md",
|
21
22
|
"Gemfile",
|
22
23
|
"History.txt",
|
23
24
|
"MIT_LICENSE.txt",
|
24
|
-
"README.
|
25
|
+
"README.md",
|
25
26
|
"Rakefile",
|
26
27
|
"bin/tracksperanto",
|
27
28
|
"lib/export/base.rb",
|
@@ -86,6 +87,7 @@ Gem::Specification.new do |s|
|
|
86
87
|
"lib/tracksperanto/const_name.rb",
|
87
88
|
"lib/tracksperanto/ext_io.rb",
|
88
89
|
"lib/tracksperanto/format_detector.rb",
|
90
|
+
"lib/tracksperanto/io_wrapper.rb",
|
89
91
|
"lib/tracksperanto/keyframe.rb",
|
90
92
|
"lib/tracksperanto/parameters.rb",
|
91
93
|
"lib/tracksperanto/pf_coords.rb",
|
@@ -199,11 +201,11 @@ Gem::Specification.new do |s|
|
|
199
201
|
"test/tools/test_start_trim_middleware.rb",
|
200
202
|
"tracksperanto.gemspec"
|
201
203
|
]
|
202
|
-
s.homepage =
|
204
|
+
s.homepage = %q{http://guerilla-di.org/tracksperanto}
|
203
205
|
s.licenses = ["MIT"]
|
204
206
|
s.require_paths = ["lib"]
|
205
|
-
s.rubygems_version =
|
206
|
-
s.summary =
|
207
|
+
s.rubygems_version = %q{1.6.2}
|
208
|
+
s.summary = %q{A universal 2D tracks converter}
|
207
209
|
|
208
210
|
if s.respond_to? :specification_version then
|
209
211
|
s.specification_version = 3
|
@@ -211,7 +213,7 @@ Gem::Specification.new do |s|
|
|
211
213
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
212
214
|
s.add_runtime_dependency(%q<bundler>, [">= 0"])
|
213
215
|
s.add_runtime_dependency(%q<obuf>, ["~> 1.1"])
|
214
|
-
s.add_runtime_dependency(%q<tickly>, ["~> 2.1.
|
216
|
+
s.add_runtime_dependency(%q<tickly>, ["~> 2.1.4"])
|
215
217
|
s.add_runtime_dependency(%q<bychar>, ["~> 2"])
|
216
218
|
s.add_runtime_dependency(%q<progressive_io>, ["~> 1.0"])
|
217
219
|
s.add_runtime_dependency(%q<flame_channel_parser>, ["~> 4.0"])
|
@@ -227,7 +229,7 @@ Gem::Specification.new do |s|
|
|
227
229
|
else
|
228
230
|
s.add_dependency(%q<bundler>, [">= 0"])
|
229
231
|
s.add_dependency(%q<obuf>, ["~> 1.1"])
|
230
|
-
s.add_dependency(%q<tickly>, ["~> 2.1.
|
232
|
+
s.add_dependency(%q<tickly>, ["~> 2.1.4"])
|
231
233
|
s.add_dependency(%q<bychar>, ["~> 2"])
|
232
234
|
s.add_dependency(%q<progressive_io>, ["~> 1.0"])
|
233
235
|
s.add_dependency(%q<flame_channel_parser>, ["~> 4.0"])
|
@@ -244,7 +246,7 @@ Gem::Specification.new do |s|
|
|
244
246
|
else
|
245
247
|
s.add_dependency(%q<bundler>, [">= 0"])
|
246
248
|
s.add_dependency(%q<obuf>, ["~> 1.1"])
|
247
|
-
s.add_dependency(%q<tickly>, ["~> 2.1.
|
249
|
+
s.add_dependency(%q<tickly>, ["~> 2.1.4"])
|
248
250
|
s.add_dependency(%q<bychar>, ["~> 2"])
|
249
251
|
s.add_dependency(%q<progressive_io>, ["~> 1.0"])
|
250
252
|
s.add_dependency(%q<flame_channel_parser>, ["~> 4.0"])
|
metadata
CHANGED
@@ -1,270 +1,258 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: tracksperanto
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 17
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 3
|
8
|
+
- 3
|
9
|
+
- 13
|
10
|
+
version: 3.3.13
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Julik Tarkhanov
|
9
14
|
autorequire:
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
+
|
18
|
+
date: 2014-02-07 00:00:00 +01:00
|
19
|
+
default_executable: tracksperanto
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
17
23
|
none: false
|
18
|
-
requirements:
|
19
|
-
- -
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
hash: 3
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
22
31
|
type: :runtime
|
32
|
+
name: bundler
|
33
|
+
version_requirements: *id001
|
23
34
|
prerelease: false
|
24
|
-
|
25
|
-
|
26
|
-
requirements:
|
27
|
-
- - ! '>='
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '0'
|
30
|
-
- !ruby/object:Gem::Dependency
|
31
|
-
name: obuf
|
32
|
-
requirement: !ruby/object:Gem::Requirement
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
33
37
|
none: false
|
34
|
-
requirements:
|
38
|
+
requirements:
|
35
39
|
- - ~>
|
36
|
-
- !ruby/object:Gem::Version
|
37
|
-
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
hash: 13
|
42
|
+
segments:
|
43
|
+
- 1
|
44
|
+
- 1
|
45
|
+
version: "1.1"
|
38
46
|
type: :runtime
|
47
|
+
name: obuf
|
48
|
+
version_requirements: *id002
|
39
49
|
prerelease: false
|
40
|
-
|
41
|
-
|
42
|
-
requirements:
|
43
|
-
- - ~>
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version: '1.1'
|
46
|
-
- !ruby/object:Gem::Dependency
|
47
|
-
name: tickly
|
48
|
-
requirement: !ruby/object:Gem::Requirement
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
49
52
|
none: false
|
50
|
-
requirements:
|
53
|
+
requirements:
|
51
54
|
- - ~>
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 2
|
59
|
+
- 1
|
60
|
+
- 4
|
61
|
+
version: 2.1.4
|
54
62
|
type: :runtime
|
63
|
+
name: tickly
|
64
|
+
version_requirements: *id003
|
55
65
|
prerelease: false
|
56
|
-
|
66
|
+
- !ruby/object:Gem::Dependency
|
67
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
57
68
|
none: false
|
58
|
-
requirements:
|
69
|
+
requirements:
|
59
70
|
- - ~>
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
none: false
|
66
|
-
requirements:
|
67
|
-
- - ~>
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version: '2'
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
hash: 7
|
73
|
+
segments:
|
74
|
+
- 2
|
75
|
+
version: "2"
|
70
76
|
type: :runtime
|
77
|
+
name: bychar
|
78
|
+
version_requirements: *id004
|
71
79
|
prerelease: false
|
72
|
-
|
73
|
-
|
74
|
-
requirements:
|
75
|
-
- - ~>
|
76
|
-
- !ruby/object:Gem::Version
|
77
|
-
version: '2'
|
78
|
-
- !ruby/object:Gem::Dependency
|
79
|
-
name: progressive_io
|
80
|
-
requirement: !ruby/object:Gem::Requirement
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
81
82
|
none: false
|
82
|
-
requirements:
|
83
|
+
requirements:
|
83
84
|
- - ~>
|
84
|
-
- !ruby/object:Gem::Version
|
85
|
-
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
hash: 15
|
87
|
+
segments:
|
88
|
+
- 1
|
89
|
+
- 0
|
90
|
+
version: "1.0"
|
86
91
|
type: :runtime
|
92
|
+
name: progressive_io
|
93
|
+
version_requirements: *id005
|
87
94
|
prerelease: false
|
88
|
-
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
89
97
|
none: false
|
90
|
-
requirements:
|
98
|
+
requirements:
|
91
99
|
- - ~>
|
92
|
-
- !ruby/object:Gem::Version
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
requirements:
|
99
|
-
- - ~>
|
100
|
-
- !ruby/object:Gem::Version
|
101
|
-
version: '4.0'
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
hash: 27
|
102
|
+
segments:
|
103
|
+
- 4
|
104
|
+
- 0
|
105
|
+
version: "4.0"
|
102
106
|
type: :runtime
|
107
|
+
name: flame_channel_parser
|
108
|
+
version_requirements: *id006
|
103
109
|
prerelease: false
|
104
|
-
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
105
112
|
none: false
|
106
|
-
requirements:
|
107
|
-
- -
|
108
|
-
- !ruby/object:Gem::Version
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
requirements:
|
115
|
-
- - '='
|
116
|
-
- !ruby/object:Gem::Version
|
113
|
+
requirements:
|
114
|
+
- - "="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
hash: 55
|
117
|
+
segments:
|
118
|
+
- 0
|
119
|
+
- 10
|
120
|
+
- 0
|
117
121
|
version: 0.10.0
|
118
122
|
type: :runtime
|
123
|
+
name: progressbar
|
124
|
+
version_requirements: *id007
|
119
125
|
prerelease: false
|
120
|
-
|
121
|
-
|
122
|
-
requirements:
|
123
|
-
- - '='
|
124
|
-
- !ruby/object:Gem::Version
|
125
|
-
version: 0.10.0
|
126
|
-
- !ruby/object:Gem::Dependency
|
127
|
-
name: update_hints
|
128
|
-
requirement: !ruby/object:Gem::Requirement
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
129
128
|
none: false
|
130
|
-
requirements:
|
129
|
+
requirements:
|
131
130
|
- - ~>
|
132
|
-
- !ruby/object:Gem::Version
|
133
|
-
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
hash: 15
|
133
|
+
segments:
|
134
|
+
- 1
|
135
|
+
- 0
|
136
|
+
version: "1.0"
|
134
137
|
type: :runtime
|
138
|
+
name: update_hints
|
139
|
+
version_requirements: *id008
|
135
140
|
prerelease: false
|
136
|
-
|
137
|
-
|
138
|
-
requirements:
|
139
|
-
- - ~>
|
140
|
-
- !ruby/object:Gem::Version
|
141
|
-
version: '1.0'
|
142
|
-
- !ruby/object:Gem::Dependency
|
143
|
-
name: approximately
|
144
|
-
requirement: !ruby/object:Gem::Requirement
|
141
|
+
- !ruby/object:Gem::Dependency
|
142
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
145
143
|
none: false
|
146
|
-
requirements:
|
147
|
-
- -
|
148
|
-
- !ruby/object:Gem::Version
|
149
|
-
|
144
|
+
requirements:
|
145
|
+
- - ">="
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
hash: 3
|
148
|
+
segments:
|
149
|
+
- 0
|
150
|
+
version: "0"
|
150
151
|
type: :development
|
152
|
+
name: approximately
|
153
|
+
version_requirements: *id009
|
151
154
|
prerelease: false
|
152
|
-
|
153
|
-
|
154
|
-
requirements:
|
155
|
-
- - ! '>='
|
156
|
-
- !ruby/object:Gem::Version
|
157
|
-
version: '0'
|
158
|
-
- !ruby/object:Gem::Dependency
|
159
|
-
name: jeweler
|
160
|
-
requirement: !ruby/object:Gem::Requirement
|
155
|
+
- !ruby/object:Gem::Dependency
|
156
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
161
157
|
none: false
|
162
|
-
requirements:
|
163
|
-
- -
|
164
|
-
- !ruby/object:Gem::Version
|
165
|
-
|
158
|
+
requirements:
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
hash: 3
|
162
|
+
segments:
|
163
|
+
- 0
|
164
|
+
version: "0"
|
166
165
|
type: :development
|
166
|
+
name: jeweler
|
167
|
+
version_requirements: *id010
|
167
168
|
prerelease: false
|
168
|
-
|
169
|
-
|
170
|
-
requirements:
|
171
|
-
- - ! '>='
|
172
|
-
- !ruby/object:Gem::Version
|
173
|
-
version: '0'
|
174
|
-
- !ruby/object:Gem::Dependency
|
175
|
-
name: rake
|
176
|
-
requirement: !ruby/object:Gem::Requirement
|
169
|
+
- !ruby/object:Gem::Dependency
|
170
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
177
171
|
none: false
|
178
|
-
requirements:
|
179
|
-
- -
|
180
|
-
- !ruby/object:Gem::Version
|
181
|
-
|
172
|
+
requirements:
|
173
|
+
- - ">="
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
hash: 3
|
176
|
+
segments:
|
177
|
+
- 0
|
178
|
+
version: "0"
|
182
179
|
type: :development
|
180
|
+
name: rake
|
181
|
+
version_requirements: *id011
|
183
182
|
prerelease: false
|
184
|
-
|
183
|
+
- !ruby/object:Gem::Dependency
|
184
|
+
requirement: &id012 !ruby/object:Gem::Requirement
|
185
185
|
none: false
|
186
|
-
requirements:
|
187
|
-
- -
|
188
|
-
- !ruby/object:Gem::Version
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
none: false
|
194
|
-
requirements:
|
195
|
-
- - ! '>='
|
196
|
-
- !ruby/object:Gem::Version
|
197
|
-
version: '0'
|
186
|
+
requirements:
|
187
|
+
- - ">="
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
hash: 3
|
190
|
+
segments:
|
191
|
+
- 0
|
192
|
+
version: "0"
|
198
193
|
type: :development
|
194
|
+
name: linebyline
|
195
|
+
version_requirements: *id012
|
199
196
|
prerelease: false
|
200
|
-
|
197
|
+
- !ruby/object:Gem::Dependency
|
198
|
+
requirement: &id013 !ruby/object:Gem::Requirement
|
201
199
|
none: false
|
202
|
-
requirements:
|
203
|
-
- - ! '>='
|
204
|
-
- !ruby/object:Gem::Version
|
205
|
-
version: '0'
|
206
|
-
- !ruby/object:Gem::Dependency
|
207
|
-
name: flexmock
|
208
|
-
requirement: !ruby/object:Gem::Requirement
|
209
|
-
none: false
|
210
|
-
requirements:
|
200
|
+
requirements:
|
211
201
|
- - ~>
|
212
|
-
- !ruby/object:Gem::Version
|
202
|
+
- !ruby/object:Gem::Version
|
203
|
+
hash: 31
|
204
|
+
segments:
|
205
|
+
- 1
|
206
|
+
- 3
|
207
|
+
- 2
|
213
208
|
version: 1.3.2
|
214
209
|
type: :development
|
210
|
+
name: flexmock
|
211
|
+
version_requirements: *id013
|
215
212
|
prerelease: false
|
216
|
-
|
217
|
-
|
218
|
-
requirements:
|
219
|
-
- - ~>
|
220
|
-
- !ruby/object:Gem::Version
|
221
|
-
version: 1.3.2
|
222
|
-
- !ruby/object:Gem::Dependency
|
223
|
-
name: cli_test
|
224
|
-
requirement: !ruby/object:Gem::Requirement
|
213
|
+
- !ruby/object:Gem::Dependency
|
214
|
+
requirement: &id014 !ruby/object:Gem::Requirement
|
225
215
|
none: false
|
226
|
-
requirements:
|
216
|
+
requirements:
|
227
217
|
- - ~>
|
228
|
-
- !ruby/object:Gem::Version
|
229
|
-
|
218
|
+
- !ruby/object:Gem::Version
|
219
|
+
hash: 15
|
220
|
+
segments:
|
221
|
+
- 1
|
222
|
+
- 0
|
223
|
+
version: "1.0"
|
230
224
|
type: :development
|
225
|
+
name: cli_test
|
226
|
+
version_requirements: *id014
|
231
227
|
prerelease: false
|
232
|
-
|
233
|
-
|
234
|
-
requirements:
|
235
|
-
- - ~>
|
236
|
-
- !ruby/object:Gem::Version
|
237
|
-
version: '1.0'
|
238
|
-
- !ruby/object:Gem::Dependency
|
239
|
-
name: rake-hooks
|
240
|
-
requirement: !ruby/object:Gem::Requirement
|
228
|
+
- !ruby/object:Gem::Dependency
|
229
|
+
requirement: &id015 !ruby/object:Gem::Requirement
|
241
230
|
none: false
|
242
|
-
requirements:
|
243
|
-
- -
|
244
|
-
- !ruby/object:Gem::Version
|
245
|
-
|
231
|
+
requirements:
|
232
|
+
- - ">="
|
233
|
+
- !ruby/object:Gem::Version
|
234
|
+
hash: 3
|
235
|
+
segments:
|
236
|
+
- 0
|
237
|
+
version: "0"
|
246
238
|
type: :development
|
239
|
+
name: rake-hooks
|
240
|
+
version_requirements: *id015
|
247
241
|
prerelease: false
|
248
|
-
|
249
|
-
none: false
|
250
|
-
requirements:
|
251
|
-
- - ! '>='
|
252
|
-
- !ruby/object:Gem::Version
|
253
|
-
version: '0'
|
254
|
-
description: Converts 2D track exports between different apps like Flame, MatchMover,
|
255
|
-
PFTrack...
|
242
|
+
description: Converts 2D track exports between different apps like Flame, MatchMover, PFTrack...
|
256
243
|
email: me@julik.nl
|
257
|
-
executables:
|
244
|
+
executables:
|
258
245
|
- tracksperanto
|
259
246
|
extensions: []
|
260
|
-
|
261
|
-
|
262
|
-
|
247
|
+
|
248
|
+
extra_rdoc_files:
|
249
|
+
- README.md
|
250
|
+
files:
|
263
251
|
- CONTRIBUTING.md
|
264
252
|
- Gemfile
|
265
253
|
- History.txt
|
266
254
|
- MIT_LICENSE.txt
|
267
|
-
- README.
|
255
|
+
- README.md
|
268
256
|
- Rakefile
|
269
257
|
- bin/tracksperanto
|
270
258
|
- lib/export/base.rb
|
@@ -329,6 +317,7 @@ files:
|
|
329
317
|
- lib/tracksperanto/const_name.rb
|
330
318
|
- lib/tracksperanto/ext_io.rb
|
331
319
|
- lib/tracksperanto/format_detector.rb
|
320
|
+
- lib/tracksperanto/io_wrapper.rb
|
332
321
|
- lib/tracksperanto/keyframe.rb
|
333
322
|
- lib/tracksperanto/parameters.rb
|
334
323
|
- lib/tracksperanto/pf_coords.rb
|
@@ -441,32 +430,39 @@ files:
|
|
441
430
|
- test/tools/test_slip_middleware.rb
|
442
431
|
- test/tools/test_start_trim_middleware.rb
|
443
432
|
- tracksperanto.gemspec
|
433
|
+
has_rdoc: true
|
444
434
|
homepage: http://guerilla-di.org/tracksperanto
|
445
|
-
licenses:
|
435
|
+
licenses:
|
446
436
|
- MIT
|
447
437
|
post_install_message:
|
448
438
|
rdoc_options: []
|
449
|
-
|
439
|
+
|
440
|
+
require_paths:
|
450
441
|
- lib
|
451
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
442
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
452
443
|
none: false
|
453
|
-
requirements:
|
454
|
-
- -
|
455
|
-
- !ruby/object:Gem::Version
|
456
|
-
|
457
|
-
segments:
|
444
|
+
requirements:
|
445
|
+
- - ">="
|
446
|
+
- !ruby/object:Gem::Version
|
447
|
+
hash: 3
|
448
|
+
segments:
|
458
449
|
- 0
|
459
|
-
|
460
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
450
|
+
version: "0"
|
451
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
461
452
|
none: false
|
462
|
-
requirements:
|
463
|
-
- -
|
464
|
-
- !ruby/object:Gem::Version
|
465
|
-
|
453
|
+
requirements:
|
454
|
+
- - ">="
|
455
|
+
- !ruby/object:Gem::Version
|
456
|
+
hash: 3
|
457
|
+
segments:
|
458
|
+
- 0
|
459
|
+
version: "0"
|
466
460
|
requirements: []
|
461
|
+
|
467
462
|
rubyforge_project:
|
468
|
-
rubygems_version: 1.
|
463
|
+
rubygems_version: 1.6.2
|
469
464
|
signing_key:
|
470
465
|
specification_version: 3
|
471
466
|
summary: A universal 2D tracks converter
|
472
467
|
test_files: []
|
468
|
+
|