voicemeeter_api_ruby 2.0.3 → 2.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b3a0e9817ffa5ec8ae524a4af3fe6a64f9f85277a83cb6e39c64f7746006a564
4
- data.tar.gz: eecdc15368fb025b6632961ab3df850ac505e79de105f472569e6b0678dd96d9
3
+ metadata.gz: feb89f841882b2ece4f1bc959c8a5a728a738b054798635d2937ff9dceacf37c
4
+ data.tar.gz: 382ba6af1cde36e8b450d0549e383f9e6c68040d8385923ec8b2c413ddfc3d1b
5
5
  SHA512:
6
- metadata.gz: 390dda38c9597c3996d913b3c5c0462307ffd7df102ca5fad2879e76b682104b373ecb5c9b0879911cee20622decfece3f0756082d7d1c85e3ad349ace1a547f
7
- data.tar.gz: fd2bf7bfb8bd6157f4dc54e22e1636629ae7a934c466752ddc2f3fda23b9abebef31f5002435dcc4d75075fe792e34aad78295296c5910b107a72adad261750b
6
+ metadata.gz: 719e6d87cf5514dc7d759bdf15bf75ae32a533686894c172e4c1d4151dc2b7c480e8967a0d0d41a4187a0df2ff7f4094a3bc9520f86cf7f75c0604f00b711b7e
7
+ data.tar.gz: 728b8458b2897592282c24b944a0d1a3dca0af14791c0c3c73a1d1eb474a9462f4f24eecd5aa3caad2fec024f111998dedac8e057b5d092f727a763feda6ab5e
data/lib/base.rb CHANGED
@@ -1,11 +1,18 @@
1
+ require 'toml'
1
2
  require 'ffi'
2
3
  require_relative 'inst'
3
4
 
4
5
  include InstallationFunctions
5
6
 
7
+
6
8
  module Base
9
+ """
10
+ Perform low level tasks.
11
+ """
7
12
  extend FFI::Library
8
13
 
14
+ $kinds_all = ["basic", "banana", "potato"]
15
+
9
16
  begin
10
17
  OS_BITS = get_arch
11
18
  VM_PATH = get_vmpath(OS_BITS)
@@ -48,32 +55,29 @@ module Base
48
55
  DELAY = 0.001
49
56
  MAX_POLLS = 8
50
57
 
51
- def cache=(value)
52
- @cache = value
53
- end
54
-
55
- def pdirty
58
+ def pdirty?
56
59
  return vmr_pdirty&.nonzero?
57
60
  end
58
61
 
59
- def mdirty
62
+ def mdirty?
60
63
  return vmr_mdirty&.nonzero?
61
64
  end
62
65
 
66
+ private
63
67
  def clear_polling
64
- while self.pdirty || self.mdirty
68
+ while self.pdirty? || self.mdirty?
65
69
  end
66
70
  end
67
71
 
68
- def polling(func, name=nil, id=nil, mode=nil)
72
+ def polling(func, **kwargs)
69
73
  params = {
70
- "get_parameter" => name,
71
- "macro_getstatus" => "mb_#{id}_#{mode}"
74
+ "get_parameter" => kwargs[:name],
75
+ "macro_getstatus" => "mb_#{kwargs[:id]}_#{kwargs[:mode]}"
72
76
  }
73
- MAX_POLLS.times do |i|
77
+ @max_polls.times do |i|
74
78
  if @cache.key? params[func]
75
- if func.include?('param') && self.pdirty ||
76
- func.include?('macro') && self.mdirty
79
+ if func.include?('param') && self.pdirty? ||
80
+ func.include?('macro') && self.mdirty?
77
81
  return @cache.delete(params[func])[0]
78
82
  end
79
83
  sleep(DELAY)
@@ -82,7 +86,7 @@ module Base
82
86
  end
83
87
 
84
88
  val = yield
85
- self.cache.store(params[func], [val, false])
89
+ @cache.store(params[func], [val, false])
86
90
  val
87
91
  end
88
92
 
@@ -101,38 +105,41 @@ module Base
101
105
  end
102
106
 
103
107
  module Define_Version
108
+ """
109
+ Defines the console layout for a specific kind of Voicemeeter.
110
+ """
104
111
  include Base
105
-
112
+ private
106
113
  def define_version(kind)
107
114
  case kind
108
115
  when "basic"
109
- self.properties = {
116
+ @properties = {
110
117
  :name => kind,
111
- :exe => "voicemeeter.exe"
118
+ :exe => "voicemeeter.exe",
112
119
  }
113
- self.layout = {
120
+ @layout = {
114
121
  :strip => {:p_in => 2, :v_in=> 1},
115
122
  :bus => {:p_out => 1, :v_out=> 1},
116
123
  :vban => {:instream => 4, :outstream => 4},
117
124
  :mb => 70,
118
125
  }
119
126
  when "banana"
120
- self.properties = {
127
+ @properties = {
121
128
  :name => kind,
122
- :exe => "voicemeeterpro.exe"
129
+ :exe => "voicemeeterpro.exe",
123
130
  }
124
- self.layout = {
131
+ @layout = {
125
132
  :strip => {:p_in => 3, :v_in=> 2},
126
133
  :bus => {:p_out => 3, :v_out=> 2},
127
134
  :vban => {:instream => 8, :outstream => 8},
128
135
  :mb => 70,
129
136
  }
130
137
  when "potato"
131
- self.properties = {
138
+ @properties = {
132
139
  :name => kind,
133
- :exe => "voicemeeter8#{OS_BITS == 64 ? "x64" : ""}.exe"
140
+ :exe => "voicemeeter8#{OS_BITS == 64 ? "x64" : ""}.exe",
134
141
  }
135
- self.layout = {
142
+ @layout = {
136
143
  :strip => {:p_in => 5, :v_in=> 3},
137
144
  :bus => {:p_out => 5, :v_out=> 3},
138
145
  :vban => {:instream => 8, :outstream => 8},
@@ -141,3 +148,24 @@ module Define_Version
141
148
  end
142
149
  end
143
150
  end
151
+
152
+
153
+ module Profiles
154
+ include Define_Version
155
+ private
156
+ def get_profiles
157
+ filepath = File.join(File.dirname(__dir__), "/profiles/#{@properties[:name]}/*.toml")
158
+
159
+ Dir.glob(filepath).to_h do |toml_file|
160
+ filename = File.basename(toml_file, ".toml")
161
+ puts "loading profile #{@properties[:name]}/#{filename}"
162
+ [filename, TOML::Parser.new(File.read(toml_file)).parsed]
163
+ end
164
+ end
165
+ public
166
+ def set_profile(value)
167
+ raise VMRemoteErrors.new("No profile with name #{value} was loaded") unless @profiles.key? value
168
+ self.send("set_multi", @profiles[value])
169
+ sleep(DELAY)
170
+ end
171
+ end
data/lib/bus.rb CHANGED
@@ -2,13 +2,14 @@ require_relative 'channel'
2
2
 
3
3
 
4
4
  class Bus < IChannel
5
+ """
6
+ Concrete class for Bus objects
7
+ """
5
8
  def self.make(remote, layout_bus)
6
9
  "
7
10
  Factory function for Bus classes.
8
11
  "
9
- p_out = layout_bus[:p_out]
10
- v_out = layout_bus[:v_out]
11
-
12
+ p_out, v_out = layout_bus.map { |k, v| v }
12
13
  (0...(p_out + v_out)).map do |i|
13
14
  i < p_out ? \
14
15
  PhysicalBus.new(remote, i) : \
@@ -20,6 +21,7 @@ class Bus < IChannel
20
21
  super
21
22
  self.make_accessor_bool :mute, :mono, :eq
22
23
  self.make_accessor_float :gain
24
+ self.make_accessor_string :label
23
25
  end
24
26
 
25
27
  def cmd
data/lib/button.rb CHANGED
@@ -23,6 +23,7 @@ class IMacroButton
23
23
  param_hash.each do |(key,val)|
24
24
  self.send("#{key}=", val)
25
25
  end
26
+ sleep(remote.delay)
26
27
  end
27
28
  end
28
29
 
@@ -38,4 +39,4 @@ class MacroButton < IMacroButton
38
39
  super
39
40
  self.make_accessor_macrobutton :state, :stateonly, :trigger
40
41
  end
41
- end
42
+ end
data/lib/channel.rb CHANGED
@@ -2,6 +2,9 @@ require_relative 'meta'
2
2
  require_relative 'errors'
3
3
 
4
4
  class IChannel
5
+ """
6
+ Base class for audio channels
7
+ """
5
8
  include Channel_Meta_Functions
6
9
 
7
10
  attr_accessor :remote, :index
data/lib/errors.rb CHANGED
@@ -34,4 +34,4 @@ module Errors
34
34
  end
35
35
  end
36
36
  end
37
- end
37
+ end
data/lib/inst.rb CHANGED
@@ -4,11 +4,8 @@ require_relative 'errors'
4
4
 
5
5
  include Errors
6
6
 
7
- BASIC = 1
8
- BANANA = 2
9
- POTATO = 3
10
-
11
7
  module InstallationFunctions
8
+ private
12
9
  def get_arch
13
10
  key = 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'
14
11
  Win32::Registry::HKEY_LOCAL_MACHINE.open(key) do |reg|
@@ -23,7 +20,6 @@ module InstallationFunctions
23
20
  def get_vmpath(os_bits)
24
21
  vm_key = "VB:Voicemeeter {17359A74-1236-5467}"
25
22
  reg_key = "Software#{os_bits == 64 ? "\\WOW6432Node" : ""}\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"
26
-
27
23
  Win32::Registry::HKEY_LOCAL_MACHINE.open(reg_key + vm_key) do |reg|
28
24
  value = reg["UninstallString"]
29
25
 
data/lib/meta.rb CHANGED
@@ -1,16 +1,20 @@
1
1
  require_relative 'errors'
2
2
 
3
+ class FalseClass; def to_i; 0 end end
4
+ class TrueClass; def to_i; 1 end end
5
+
3
6
  module Meta_Functions
7
+ private
4
8
  def make_accessor_bool(*params)
5
9
  params.each do |param|
6
10
  define_singleton_method("#{param}") do
7
11
  return !(self.getter("#{param}")).zero?
8
12
  end
9
13
 
10
- opts = [false, true]
14
+ opts = [false, true, 0, 1]
11
15
  define_singleton_method("#{param}=") do |value|
12
16
  raise OutOfBoundsErrors.new(opts) unless opts.include? value
13
- self.setter("#{param}", value ? 1 : 0)
17
+ self.setter("#{param}", value.to_i == 1 ? 1 : 0)
14
18
  end
15
19
  end
16
20
  end
@@ -64,12 +68,10 @@ module Meta_Functions
64
68
  end
65
69
  end
66
70
 
67
- def _make_channel_props(num_A, num_B)
68
- channels = (1..(num_A + num_B)).map.each do |i|
71
+ def make_channel_props(num_A, num_B)
72
+ (1..(num_A + num_B)).map do |i|
69
73
  i <= num_A ? "A#{i}" : "B#{i - num_A}"
70
74
  end
71
-
72
- self.make_accessor_bool *channels
73
75
  end
74
76
  end
75
77
 
@@ -88,10 +90,10 @@ module Channel_Meta_Functions
88
90
  return !(self.getter("#{val}")).zero?
89
91
  end
90
92
 
91
- opts = [false, true]
93
+ opts = [false, true, 0, 1]
92
94
  define_singleton_method("#{param}=") do |value|
93
95
  raise OutOfBoundsErrors.new(opts) unless opts.include? value
94
- self.setter("#{val}", value ? 1 : 0)
96
+ self.setter("#{val}", value.to_i == 1 ? 1 : 0)
95
97
  end
96
98
  end
97
99
  end
@@ -214,10 +216,10 @@ module MacroButton_Meta_Functions
214
216
  return !(self.getter(mode[param])).zero?
215
217
  end
216
218
 
217
- opts = [false, true]
219
+ opts = [false, true, 0, 1]
218
220
  define_singleton_method("#{param}=") do |value|
219
221
  raise OutOfBoundsErrors.new(opts[param]) unless opts.include? value
220
- self.setter(value ? 1 : 0, mode[param])
222
+ self.setter(value.to_i == 1 ? 1 : 0, mode[param])
221
223
  end
222
224
  end
223
225
  end
@@ -243,7 +245,7 @@ module Commands_Meta_Functions
243
245
  opts = [false, true]
244
246
  define_singleton_method("#{param}=") do |value|
245
247
  raise OutOfBoundsErrors.new(opts) unless opts.include? value
246
- self.setter("#{param}", value ? 1 : 0)
248
+ self.setter("#{param}", value.to_i == 1 ? 1 : 0)
247
249
  end
248
250
  end
249
251
  end
data/lib/recorder.rb CHANGED
@@ -2,6 +2,9 @@ require_relative 'meta'
2
2
 
3
3
 
4
4
  class IRecorder
5
+ """
6
+ Base class for Recorder object
7
+ """
5
8
  include Meta_Functions
6
9
 
7
10
  attr_accessor :remote
@@ -25,13 +28,15 @@ end
25
28
 
26
29
 
27
30
  class Recorder < IRecorder
28
- def initialize(remote, layout_bus)
31
+ """
32
+ Concrete class for recorder
33
+ """
34
+ def initialize(remote)
29
35
  super(remote)
30
36
  self.make_writer_only :play, :stop, :record, :ff, :rew
31
37
 
32
- num_A = layout_bus[:p_out]
33
- num_B = layout_bus[:v_out]
34
- self._make_channel_props(num_A, num_B)
38
+ num_A, num_B = remote.layout[:bus].map { |k, v| v }
39
+ self.make_accessor_bool *make_channel_props(num_A, num_B)
35
40
  end
36
41
 
37
42
  def cmd
data/lib/routines.rb CHANGED
@@ -10,25 +10,29 @@ require_relative 'recorder'
10
10
 
11
11
  class Routines
12
12
  """
13
- define basic behaviours of API functions
14
- mixin modules
13
+ Define basic behaviours of API functions
14
+
15
+ Mixin required modules
15
16
  """
16
- include Define_Version
17
+ include Profiles
17
18
  include RunVM
18
19
 
19
- attr_accessor :properties, :layout, :strip, :bus, :button, :vban, :command,
20
- :recorder
20
+ attr_accessor :strip, :bus, :button, :vban, :command, :recorder
21
21
 
22
- attr_reader :retval, :cache, :wait
22
+ attr_reader :retval, :cache, :wait, :layout, :properties,
23
+ :delay, :max_polls, :profiles
23
24
 
24
25
  SIZE = 1
25
26
  BUFF = 512
26
27
 
27
- def initialize(kind)
28
+ def initialize(kind, **kwargs)
28
29
  define_version(kind)
29
30
 
30
- self.cache = Hash.new
31
+ @cache = Hash.new
31
32
  @wait = true
33
+ @delay = kwargs[:delay] || DELAY
34
+ @max_polls = kwargs[:max_polls] || MAX_POLLS
35
+ @profiles = get_profiles
32
36
  end
33
37
 
34
38
  def login
@@ -38,7 +42,8 @@ class Routines
38
42
  rescue CAPIErrors => error
39
43
  case
40
44
  when error.value == 1
41
- run_voicemeeter
45
+ self.start(@properties[:name])
46
+ clear_polling
42
47
  when error.value < 0
43
48
  raise
44
49
  end
@@ -50,7 +55,7 @@ class Routines
50
55
  end
51
56
 
52
57
  def get_parameter(name, is_string=false)
53
- self.polling("get_parameter", name) do
58
+ self.polling("get_parameter", name: name) do
54
59
  if is_string
55
60
  c_get = FFI::MemoryPointer.new(:string, BUFF, true)
56
61
  run_as("get_parameter_string", name, c_get)
@@ -69,11 +74,11 @@ class Routines
69
74
  else
70
75
  run_as("set_parameter_float", name, value.to_f)
71
76
  end
72
- self.cache.store(name, [value, true])
77
+ @cache.store(name, [value, true])
73
78
  end
74
79
 
75
80
  def macro_getstatus(id, mode)
76
- self.polling("macro_getstatus", name=nil, id, mode) do
81
+ self.polling("macro_getstatus", id: id, mode: mode) do
77
82
  c_get = FFI::MemoryPointer.new(:float, SIZE)
78
83
  run_as("macro_getstatus", id, c_get, mode)
79
84
  c_get.read_float.to_i
@@ -82,7 +87,7 @@ class Routines
82
87
 
83
88
  def macro_setstatus(id, state, mode)
84
89
  run_as("macro_setstatus", id, state, mode)
85
- self.cache.store("mb_#{id}_#{mode}", [state, true])
90
+ @cache.store("mb_#{id}_#{mode}", [state, true])
86
91
  end
87
92
 
88
93
  def set_parameter_multi(param_hash)
@@ -109,7 +114,10 @@ class Routines
109
114
  end
110
115
  @wait = true
111
116
  end
117
+
112
118
  alias_method "set_multi", :set_parameter_multi
113
- alias_method "set", :set_parameter
114
119
  alias_method "get", :get_parameter
120
+ alias_method "set", :set_parameter
121
+ alias_method "pdirty", :pdirty?
122
+ alias_method "mdirty", :pdirty?
115
123
  end
data/lib/runvm.rb CHANGED
@@ -1,20 +1,18 @@
1
- require 'open3'
2
- require_relative 'errors'
3
1
  require_relative 'base'
4
2
 
5
- module RunVM
6
- include Base
3
+ include Base
7
4
 
8
- def run_voicemeeter
9
- if VM_PATH.join(@properties[:exe]).executable?
10
- exe_path = String(VM_PATH.join(@properties[:exe]))
11
- else
12
- raise InstallErrors.new("Could not find Voicemeeter exe file")
5
+ module RunVM
6
+ """
7
+ Starts Voicemeeter of the Kind requested.
8
+ """
9
+ def start(kind)
10
+ enums = $kinds_all.map.with_index do |val, i|
11
+ get_arch == 64 && val == "potato" ? [val, i+4] : [val, i+1]
13
12
  end
13
+ exes = enums.to_h { |k, v| [k, v.to_i] }
14
14
 
15
- Open3.popen3(exe_path, '')
15
+ run_as('runvm', exes[kind])
16
16
  sleep(1)
17
-
18
- clear_polling
19
17
  end
20
18
  end
data/lib/strip.rb CHANGED
@@ -2,30 +2,29 @@ require_relative 'channel'
2
2
 
3
3
 
4
4
  class Strip < IChannel
5
- attr_reader :num_A, :num_B
6
-
7
- def self.make(remote, layout_strip, out_channels)
5
+ """
6
+ Concrete class for Strip objects
7
+ """
8
+ def self.make(remote, layout_strip)
8
9
  "
9
10
  Factory function for Strip classes.
10
11
  "
11
- p_in = layout_strip[:p_in]
12
- v_in = layout_strip[:v_in]
13
- num_A = out_channels[:p_out]
14
- num_B = out_channels[:v_out]
15
-
12
+ p_in, v_in = layout_strip.map { |k, v| v }
16
13
  (0...(p_in + v_in)).map do |i|
17
14
  i < p_in ? \
18
- PhysicalStrip.new(remote, i, num_A, num_B) : \
19
- VirtualStrip.new(remote, i, num_A, num_B)
15
+ PhysicalStrip.new(remote, i) : \
16
+ VirtualStrip.new(remote, i)
20
17
  end
21
18
  end
22
19
 
23
- def initialize(remote, i, num_A, num_B)
24
- super(remote, i)
20
+ def initialize(remote, i)
21
+ super
25
22
  self.make_accessor_bool :solo, :mute, :mono
26
23
  self.make_accessor_float :gain
27
24
  self.make_accessor_string :label
28
- self._make_channel_props(num_A, num_B)
25
+
26
+ num_A, num_B = remote.layout[:bus].map { |k, v| v }
27
+ self.make_accessor_bool *make_channel_props(num_A, num_B)
29
28
  end
30
29
 
31
30
  def cmd
@@ -34,7 +33,7 @@ class Strip < IChannel
34
33
  end
35
34
 
36
35
  class PhysicalStrip < Strip
37
- def initialize(remote, i, num_A, num_B)
36
+ def initialize(remote, i)
38
37
  super
39
38
  self.make_accessor_float :comp, :gate
40
39
  self.make_accessor_int :limit
@@ -43,7 +42,7 @@ class PhysicalStrip < Strip
43
42
  end
44
43
 
45
44
  class VirtualStrip < Strip
46
- def initialize(remote, i, num_A, num_B)
45
+ def initialize(remote, i)
47
46
  super
48
47
  self.make_accessor_bool :mc, :k
49
48
  end
data/lib/vban.rb CHANGED
@@ -3,6 +3,9 @@ require_relative 'errors'
3
3
 
4
4
 
5
5
  class IVban
6
+ """
7
+ Base class for Vban objects
8
+ """
6
9
  include Vban_Meta_Functions
7
10
 
8
11
  attr_accessor :remote, :index
@@ -37,6 +40,9 @@ end
37
40
 
38
41
 
39
42
  class Vban < IVban
43
+ """
44
+ Concrete class for Vban objects
45
+ """
40
46
  def self.make(remote, vban_streams)
41
47
  "
42
48
  Factory function for Vban class.
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Voicemeeter_API_Ruby
2
- VERSION = '2.0.3'
2
+ VERSION = '2.0.4'
3
3
  end
data/lib/voicemeeter.rb CHANGED
@@ -1,22 +1,38 @@
1
1
  require_relative 'routines'
2
2
  require_relative 'errors'
3
3
 
4
+
4
5
  module Voicemeeter
6
+ include RunVM
7
+
8
+ private
5
9
  class Remote < Routines
6
- def self.make
7
- ["basic", "banana", "potato"].to_h do |kind|
8
- [kind, Remote.new(kind)]
10
+ """
11
+ Remote class, subclasses Routines
12
+
13
+ Console layout built according to version definition.
14
+
15
+ Offers a run method for resource closure.
16
+ """
17
+ def self.make(**kwargs)
18
+ """
19
+ Factory function that generates a remote class for each kind.
20
+
21
+ Returns a hash of Remote classes.
22
+ """
23
+ $kinds_all.to_h do |kind|
24
+ [kind, Remote.new(kind, **kwargs)]
9
25
  end
10
26
  end
11
27
 
12
28
  def initialize(kind)
13
29
  super
14
- self.strip = Strip.make(self, @layout[:strip], @layout[:bus])
30
+ self.strip = Strip.make(self, @layout[:strip])
15
31
  self.bus = Bus.make(self, @layout[:bus])
16
32
  self.button = MacroButton.make(self, @layout[:mb])
17
33
  self.vban = Vban.make(self, @layout[:vban])
18
34
  self.command = Command.new(self)
19
- self.recorder = Recorder.new(self, @layout[:bus])
35
+ self.recorder = Recorder.new(self)
20
36
  end
21
37
 
22
38
  def run
@@ -27,13 +43,18 @@ module Voicemeeter
27
43
  end
28
44
  end
29
45
 
30
- def remote(kind)
31
- _remotes = Remote.make
46
+ public
47
+ def remote(kind, **kwargs)
48
+ """
49
+ Request a Remote for a specific kind and login to the API
50
+ """
51
+ _remotes = Remote.make(**kwargs)
52
+
53
+ raise VMRemoteErrors.new("Unknown Voicemeeter Kind.") unless _remotes.key? kind
32
54
 
33
- raise VMRemoteErrors.new("Unknown Voicemeeter Kind") unless _remotes[kind]
34
55
  _remotes[kind].login
35
56
  return _remotes[kind]
36
57
  end
37
58
 
38
- module_function :remote
59
+ module_function :remote, :start
39
60
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: voicemeeter_api_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.3
4
+ version: 2.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - onyx_online
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-20 00:00:00.000000000 Z
11
+ date: 2022-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -30,6 +30,20 @@ dependencies:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
32
  version: 1.9.10
33
+ - !ruby/object:Gem::Dependency
34
+ name: toml
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 0.3.0
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 0.3.0
33
47
  - !ruby/object:Gem::Dependency
34
48
  name: rake
35
49
  requirement: !ruby/object:Gem::Requirement