musa-dsl 0.23.1 → 0.23.6

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: 38a9835b1d87d869a99fac037037eed22b8eaaf3ad133c70e732578a5631aa79
4
- data.tar.gz: 7e9057ff2498fc3039baa1d749cb1c23b5fcc42bdb56879aab38c4fafc3d9468
3
+ metadata.gz: d4151142ca6664ad550224f1ab9af55f31ce8982ff24cd4bfdd5bcd02bd45756
4
+ data.tar.gz: 9c2f01bb75266047984017e7edbd7f18ed353c34321b197af0faf7a3e385449a
5
5
  SHA512:
6
- metadata.gz: 191ea705bc3b3378d5660d1e75e63bb53ef0e53d1030fcae2642ff777b9753118b33af4ec7cf0edaec884c793fecded95d41bc6aef9ad41698feb2ca2c04e14e
7
- data.tar.gz: 0ee6ed871246af66ed7553a95ec2ca683d874034344b06e3c6128c54f70ec9592b33c7ac0df196dd11dc9a5290bd4c247df008fbf5b4f57af975fbd3a66bb468
6
+ metadata.gz: 5b02d2620956fd954a7435bb7b6888d7107d02b7e57722a0f5e2f84c57f38576eab3a3bc5972b058387bcf4ad92833acce44d60c2808f36690e865b2ac776d38
7
+ data.tar.gz: 6a13c17fb864649fe6881e5ee3d34f2c1c48ada65b1640835310fb1658897d43a631cb63c30a186c7fa71bf3cee809ddd46627a36869a25a0a94099ea079bcb0
data/Gemfile CHANGED
@@ -1,5 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ ruby '2.7.3'
4
+
3
5
  gem 'logger', '~> 1.4', '>= 1.4.3'
4
6
 
5
7
  group :neuma do
@@ -38,12 +38,12 @@ module Musa
38
38
  include SerieImplementation
39
39
 
40
40
  if source
41
- define_method source_as do ||
41
+ define_method source_as do
42
42
  @source
43
43
  end
44
44
 
45
45
  define_method source_setter do |serie|
46
- raise ArgumentError, "New source should be a #{@get}" unless @source.nil? || @source.prototype? == serie&.prototype?
46
+ raise ArgumentError, "New #{source_as} should be a #{@get}" unless @source.nil? || @source.prototype? == serie&.prototype?
47
47
 
48
48
  serie ||= Musa::Series::Constructors.NIL
49
49
  @get = serie&.instance? ? :instance : :prototype
@@ -294,7 +294,7 @@ module Musa
294
294
  @source&.infinite? || false
295
295
  end
296
296
 
297
- def to_a(recursive: nil, duplicate: nil, restart: nil, dr: nil)
297
+ def to_a(duplicate: nil, recursive: nil, restart: nil, dr: nil)
298
298
  recursive ||= false
299
299
 
300
300
  dr = instance? if dr.nil?
@@ -117,18 +117,18 @@ module Musa
117
117
  @buffer
118
118
  end
119
119
 
120
- private def _restart(main)
121
- raise ArgumentError, "Can't restart a BufferSerie directly. Should use a buffer instance instead." unless main
120
+ private def _restart(buffer)
121
+ raise ArgumentError, "Can't restart a BufferSerie directly. Should use a buffer instance instead." unless buffer
122
122
  return if @source_just_restarted
123
123
 
124
- next_nil = @nils.find { |_| _ > main.index }
124
+ next_nil = @nils.find { |_| _ > buffer.index }
125
125
 
126
- if next_nil && main.index < next_nil
127
- main.last_nil_index = main.index = next_nil
126
+ if next_nil && buffer.index < next_nil
127
+ buffer.last_nil_index = buffer.index = next_nil
128
128
 
129
129
  else
130
130
  until _next_value.nil?; end
131
- main.last_nil_index = main.index = @nils.last
131
+ buffer.last_nil_index = buffer.index = @nils.last
132
132
  end
133
133
 
134
134
  clear_old_history
@@ -216,8 +216,7 @@ module Musa
216
216
  @index += 1
217
217
  value = @history[@index]
218
218
  else
219
- @source.next_value
220
- value = _next_value
219
+ value = _next_value unless @source.next_value.nil?
221
220
  end
222
221
 
223
222
  if value.nil?
@@ -1,19 +1,32 @@
1
1
  module Musa
2
2
  module Series::Operations
3
3
  def split
4
- Splitter.new(Splitter::BufferedProxy.new(self))
4
+ Splitter.new(self)
5
5
  end
6
6
 
7
7
  class Splitter
8
8
  include Enumerable
9
+ include Series::Serie::Prototyping
9
10
 
10
- def initialize(proxy)
11
- @proxy = proxy
11
+ def initialize(source)
12
+ @source = source
12
13
  @series = {}
13
14
  end
14
15
 
16
+ def source=(serie)
17
+ @source = serie
18
+ @proxy.source = @source if @proxy
19
+ end
20
+
21
+ protected def _instance!
22
+ super
23
+ @proxy = SplitterProxy.new(@source)
24
+ end
25
+
15
26
  def [](key_or_index)
16
- if @series.has_key?(key_or_index)
27
+ raise "Can't get a component because Splitter is a prototype. To get a component you need a Splitter instance." unless @is_instance
28
+
29
+ if @series.key?(key_or_index)
17
30
  @series[key_or_index]
18
31
  else
19
32
  @series[key_or_index] = Split.new(@proxy, key_or_index)
@@ -21,6 +34,8 @@ module Musa
21
34
  end
22
35
 
23
36
  def each
37
+ raise "Can't iterate because Splitter is a prototype. To iterate you need a Splitter instance." unless @is_instance
38
+
24
39
  if block_given?
25
40
  if @proxy.hash_mode?
26
41
  @proxy.components.each do |key|
@@ -60,24 +75,24 @@ module Musa
60
75
  end
61
76
  end
62
77
 
63
- class BufferedProxy
64
- include Series::Serie::Prototyping
65
-
78
+ class SplitterProxy
66
79
  def initialize(hash_or_array_serie)
67
80
  @source = hash_or_array_serie
68
- mark_regarding! @source
69
-
70
- init
81
+ infer_components
71
82
  end
72
83
 
73
- attr_reader :components
84
+ attr_reader :source
85
+
86
+ def source=(hash_or_array_serie)
87
+ @source = hash_or_array_serie
88
+ infer_components
89
+ end
74
90
 
75
91
  def hash_mode?; @hash_mode; end
92
+
76
93
  def array_mode?; @array_mode; end
77
94
 
78
- def init
79
- infer_components
80
- end
95
+ attr_reader :components
81
96
 
82
97
  def restart(key_or_index = nil)
83
98
  if key_or_index
@@ -151,18 +166,18 @@ module Musa
151
166
  include Series::Serie.base
152
167
 
153
168
  def initialize(proxy, key_or_index)
154
- @source = proxy
169
+ @proxy = proxy
155
170
  @key_or_index = key_or_index
156
171
 
157
- mark_regarding! @source
172
+ mark_as_instance!
158
173
  end
159
174
 
160
175
  private def _restart
161
- @source.restart @key_or_index
176
+ @proxy.restart(@key_or_index)
162
177
  end
163
178
 
164
179
  private def _next_value
165
- @source.next_value(@key_or_index)
180
+ @proxy.next_value(@key_or_index)
166
181
  end
167
182
  end
168
183
 
@@ -566,7 +566,7 @@ module Musa
566
566
  end
567
567
 
568
568
  private def _next_value
569
- unless @have_current && @value.nil?
569
+ unless @sources.empty? || @have_current && @value.nil?
570
570
  pre_value = @sources.collect(&:peek_next_value)
571
571
 
572
572
  nils = 0
@@ -116,6 +116,10 @@ module Musa
116
116
  Anticipate.new self, &block
117
117
  end
118
118
 
119
+ def lazy(&block)
120
+ LazySerieEval.new self, &block
121
+ end
122
+
119
123
  ###
120
124
  ### Implementation
121
125
  ###
@@ -1006,6 +1010,45 @@ module Musa
1006
1010
  end
1007
1011
 
1008
1012
  private_constant :HashFromSeriesArray
1013
+
1014
+ class LazySerieEval
1015
+ include Serie.with(source: true, block: true)
1016
+
1017
+ def initialize(serie, &block)
1018
+ self.source = serie
1019
+ self.proc = block
1020
+
1021
+ init
1022
+ end
1023
+
1024
+ def source=(serie)
1025
+ super
1026
+ @processed = nil
1027
+ end
1028
+
1029
+ def proc(&block)
1030
+ super
1031
+ @processed = nil if block
1032
+ end
1033
+
1034
+ def proc=(block)
1035
+ super
1036
+ @processed = nil if block
1037
+ end
1038
+
1039
+ private def _restart
1040
+ @processed = nil
1041
+ @source.restart
1042
+ end
1043
+
1044
+ private def _next_value
1045
+ @processed ||= @block.call(@source)
1046
+ @processed.next_value
1047
+ end
1048
+ end
1049
+
1050
+ private_constant :LazySerieEval
1009
1051
  end
1052
+
1010
1053
  end
1011
1054
  end
@@ -7,10 +7,10 @@ module Musa
7
7
  end
8
8
 
9
9
  class ProxySerie
10
- include Series::Serie.with(source: true)
10
+ include Series::Serie.with(source: true, source_as: :proxy_source)
11
11
 
12
12
  def initialize(serie)
13
- self.source = serie
13
+ self.proxy_source = serie
14
14
  init
15
15
  end
16
16
 
@@ -27,15 +27,19 @@ module Musa
27
27
  end
28
28
 
29
29
  private def method_missing(method_name, *args, **key_args, &block)
30
- if @source && @source.respond_to?(method_name)
31
- @source.send method_name, *args, **key_args, &block
30
+ if @source
31
+ if @source.respond_to?(method_name)
32
+ @source.send method_name, *args, **key_args, &block
33
+ else
34
+ raise NoMethodError, "undefined method '#{method_name}' for proxied #{@source.to_s}"
35
+ end
32
36
  else
33
37
  super
34
38
  end
35
39
  end
36
40
 
37
41
  private def respond_to_missing?(method_name, include_private)
38
- @source && @source.respond_to?(method_name, include_private) # || super
42
+ @source && @source.respond_to?(method_name, include_private) # || super ??
39
43
  end
40
44
  end
41
45
  end
@@ -4,38 +4,73 @@ require_relative '../core-ext/with'
4
4
 
5
5
  module Musa
6
6
  module Series
7
+ module Operations
8
+ def composer(&block)
9
+ Composer::Composer.new(input: self, &block).output
10
+ end
11
+ end
12
+
7
13
  module Composer
8
14
  class Composer
9
15
  using Musa::Extension::Arrayfy
10
16
 
11
- attr_reader :inputs, :outputs
17
+ def initialize(input: nil, inputs: [:input], outputs: [:output], auto_commit: nil, &block)
18
+ auto_commit = true if auto_commit.nil?
19
+
20
+ inputs = case inputs
21
+ when Array
22
+ inputs.collect { |_| [_, nil] }.to_h
23
+ when nil
24
+ {}
25
+ when Hash
26
+ inputs
27
+ else
28
+ raise ArgumentError, "inputs: expected a Hash with input names and source series { name: serie, ... } or an Array with names [name, ...] but received #{inputs}"
29
+ end
30
+
31
+ inputs[:input] = input if input
12
32
 
13
- def initialize(inputs: [:input], outputs: [:output], &block)
14
33
  @pipelines = {}
15
34
 
16
- @links = Set[]
17
- @links_from = {}
18
- @links_to = {}
35
+ def @pipelines.[]=(name, pipeline)
36
+ pipeline_to_add = @commited ? pipeline.commit! : pipeline
37
+ super(name, pipeline_to_add)
38
+ end
19
39
 
20
- @dsl = DSLContext.new(@pipelines, @links, @links_from, @links_to)
40
+ @dsl = DSLContext.new(@pipelines)
21
41
  @inputs = {}
22
42
  @outputs = {}
23
43
 
24
- inputs&.each do |input|
25
- @inputs[input] = Series::Constructors.PROXY
26
- @pipelines[input] = { input: nil, output: @inputs[input].buffered }
44
+ inputs.keys&.each do |input|
45
+ p = PROXY()
46
+ p.proxy_source = inputs[input] if inputs[input]
47
+
48
+ @inputs[input] = @pipelines[input] = Pipeline.new(input, input: p, output: p.buffered, pipelines: @pipelines)
27
49
 
28
50
  @dsl.define_singleton_method(input) { input }
29
51
  end
30
52
 
31
53
  outputs&.each do |output|
32
- @outputs[output] = Series::Constructors.PROXY
33
- @pipelines[output] = { input: @outputs[output], output: nil }
54
+ p = PROXY()
55
+ @outputs[output] = @pipelines[output] = Pipeline.new(output, is_output: true, input: p, output: p, pipelines: @pipelines)
34
56
 
35
57
  @dsl.define_singleton_method(output) { output }
36
58
  end
37
59
 
38
60
  @dsl.with &block if block
61
+ commit! if auto_commit
62
+ end
63
+
64
+ def input(name = nil)
65
+ name ||= :input
66
+ @inputs[name].input
67
+ end
68
+
69
+ def output(name = nil)
70
+ raise "Can't access output if the Composer is uncommited. Call '.commit' first." unless @commited
71
+
72
+ name ||= :output
73
+ @outputs[name].output
39
74
  end
40
75
 
41
76
  def route(from, to:, on: nil, as: nil)
@@ -50,15 +85,76 @@ module Musa
50
85
  @dsl.with &block
51
86
  end
52
87
 
88
+ def commit!
89
+ raise 'Already commited' if @commited
90
+
91
+ @outputs.each_value do |pipeline|
92
+ pipeline.commit!
93
+ end
94
+
95
+ @commited = true
96
+ end
97
+
98
+ class Pipeline
99
+ def initialize(name, is_output: false, input: nil, output: nil, first_proc: nil, chain_proc: nil, pipelines:)
100
+ @name = name
101
+ @is_output = is_output
102
+ @input = input
103
+ @output = output
104
+ @first_proc = first_proc
105
+ @chain_proc = chain_proc
106
+ @routes = {}
107
+ @pipelines = pipelines
108
+ end
109
+
110
+ attr_reader :name, :is_output
111
+ attr_accessor :input, :output, :proc
112
+
113
+ def [](on, as)
114
+ @routes[[on, as]]
115
+ end
116
+
117
+ def []=(on, as, source)
118
+ @routes[[on, as]] = Route.new(on, as, source)
119
+ end
120
+
121
+ def commit!
122
+ first_serie_operation = @first_proc&.call(NIL())
123
+ @input ||= first_serie_operation
124
+
125
+ @routes.each_value do |route|
126
+ route.source.commit!
127
+
128
+ if @is_output
129
+ @input.proxy_source = route.source.output.buffer
130
+ elsif route.as
131
+ @input.send(route.on)[route.as] = route.source.output.buffer
132
+ else
133
+ @input.send("#{route.on.to_s}=".to_sym, route.source.output.buffer)
134
+ end
135
+ end
136
+
137
+ chain_serie_operation = @chain_proc&.call(@input) || @input
138
+ @output ||= chain_serie_operation.buffered
139
+
140
+ self
141
+ end
142
+ end
143
+
144
+ class Route
145
+ def initialize(on, as, source)
146
+ @on = on
147
+ @as = as
148
+ @source = source
149
+ end
150
+ attr_accessor :on, :as, :source
151
+ end
152
+
53
153
  class DSLContext
54
154
  include Musa::Extension::With
55
155
 
56
- def initialize(pipelines, links, links_from, links_to)
156
+ def initialize(pipelines)
57
157
  @pipelines = pipelines
58
-
59
- @links = links
60
- @links_from = links_from
61
- @links_to = links_to
62
158
  end
63
159
 
64
160
  def route(from, to:, on: nil, as: nil)
@@ -68,69 +164,159 @@ module Musa
68
164
  raise ArgumentError, "Pipeline '#{from}' not found." unless from_pipeline
69
165
  raise ArgumentError, "Pipeline '#{to}' not found." unless to_pipeline
70
166
 
71
- @links_from[from] ||= Set[]
167
+ if to_pipeline.is_output && (on || as)
168
+ raise ArgumentError, "Output pipeline #{to_pipeline.name} only allows default routing"
169
+ end
72
170
 
73
- on ||= as ? :sources : :source
171
+ on ||= (as ? :sources : :source)
74
172
 
75
- raise ArgumentError, "Pipeline #{@links_to[[to, on, as]]} already connected to pipeline #{to} on #{on} as #{as}" if @links_to[[to, on, as]]
173
+ raise ArgumentError,
174
+ "Source of pipeline #{to} on #{on} as #{as} already connected to #{to_pipeline[on, as].source.name}" \
175
+ unless to_pipeline[on, as].nil?
76
176
 
77
- if as
78
- to_pipeline[:input].send(on)[as] = from_pipeline[:output].buffer
79
- else
80
- to_pipeline[:input].send("#{on.to_s}=".to_sym, from_pipeline[:output].buffer)
81
- end
82
177
 
83
- @links_from[from] << [to, on, as]
84
- @links_to[[to, on, as]] = from
85
- @links << [from, to, on, as]
178
+ to_pipeline[on, as] = from_pipeline
86
179
  end
87
180
 
88
181
  def pipeline(name, elements)
89
- first = last = nil
182
+ first, chain = parse(elements)
183
+ @pipelines[name] = Pipeline.new(name, first_proc: first, chain_proc: chain, pipelines: @pipelines)
90
184
 
91
- elements.each do |e|
92
- case e
93
- when Hash
94
- if e.size == 1
95
- operation = e.keys.first
96
- parameters = e.values.first
185
+ define_singleton_method(name) { name }
186
+ end
97
187
 
98
- if Musa::Series::Constructors.instance_methods.include?(operation)
99
- raise ArgumentError, "Called constructor '#{operation}' ignoring previous elements" unless last.nil?
188
+ private def parse(thing)
189
+ case thing
190
+ when Array
191
+ first = chain = nil
192
+
193
+ thing.each do |element|
194
+ case element
195
+ when Hash
196
+ new_chain = parse(element)
197
+ when Symbol
198
+ new_chain = operation_as_chained_proc(element, nil)
199
+ when Proc
200
+ new_chain = operation_as_chained_proc(:map, element)
201
+ else
202
+ raise ArgumentError, "Syntax error: don't know how to handle #{element}"
203
+ end
100
204
 
101
- last = Musa::Series::Constructors.method(operation).call(*parameters)
205
+ if first.nil?
206
+ first = new_chain unless first
207
+ else
208
+ chain = chain ? chain >> new_chain : new_chain
209
+ end
210
+ end
102
211
 
103
- elsif Musa::Series::Operations.instance_methods.include?(operation)
104
- first = last = Musa::Series::Constructors.PROXY if last.nil?
105
- last = last.send(operation, *parameters)
212
+ [first, chain]
106
213
 
107
- end
214
+ when Hash
215
+ if thing.size == 1
216
+ operation = thing.first[0] # key
217
+ parameter = thing.first[1] # value
218
+
219
+ if is_a_series_constructor?(operation)
220
+ operation_as_chained_proc(operation, parameter)
108
221
  else
109
- raise ArgumentError, "Don't know how to handle #{e}"
222
+ operation_as_chained_proc(operation, parse(parameter))
110
223
  end
111
- when Symbol
112
- first = last = Musa::Series::Constructors.PROXY if last.nil?
113
- # operation == e
114
- last = last.send(e) if Musa::Series::Operations.instance_methods.include?(e)
224
+ else
225
+ raise ArgumentError, "Syntax error: don't know how to handle #{element}"
115
226
  end
116
227
 
117
- first ||= last
228
+ when Symbol
229
+ operation_as_chained_proc(operation)
230
+
231
+ when Proc
232
+ thing
233
+
234
+ else
235
+ thing
118
236
  end
237
+ end
119
238
 
120
- @pipelines[name] = { input: first, output: last.buffered }
239
+ private def operation_as_chained_proc(operation, parameter = nil)
240
+ if is_a_series_constructor?(operation)
241
+ proc do |last|
242
+ call_constructor_according_to_last_and_parameter(last, operation, parameter)
243
+ end
121
244
 
122
- define_singleton_method(name) { name }
245
+ elsif is_a_series_operation?(operation)
246
+ proc { |last| call_operation_according_to_parameter(last, operation, parameter) }
247
+
248
+ else
249
+ # non-series operation
250
+ proc { |last| call_operation_according_to_parameter(last, operation, parameter) }
251
+ end
123
252
  end
124
253
 
125
- private def method_missing(symbol, *args, &block)
126
- if Musa::Series::Operations.instance_methods.include?(symbol)
127
- symbol
128
- elsif Musa::Series::Constructors.instance_methods.include?(symbol)
129
- symbol
254
+ private def call_constructor_according_to_last_and_parameter(last, constructor, parameter)
255
+ case last
256
+ when Proc
257
+ call_constructor_according_to_last_and_parameter(last.call, constructor, parameter)
258
+
259
+ when Serie
260
+ # TODO: ignoring last, should make an error?
261
+ Musa::Series::Constructors.method(constructor).call(*parameter)
262
+
263
+ when nil
264
+ Musa::Series::Constructors.method(constructor).call(*parameter)
265
+
266
+ when Array
267
+ raise "Unexpected parameter #{parameter} for constructor #{constructor} " \
268
+ "because the previous operation on the pipeline chain returned non-nil #{last}" \
269
+ unless parameter.nil?
270
+
271
+ Musa::Series::Constructors.method(constructor).call(*last)
272
+
273
+ when Hash
274
+ raise "Unexpected parameter #{parameter} for constructor #{constructor} " \
275
+ "because the previous operation on the pipeline chain returned non-nil #{last}" \
276
+ unless parameter.nil?
277
+
278
+ Musa::Series::Constructors.method(constructor).call(**last)
279
+
280
+ else
281
+ raise ArgumentError, "Don't know how to handle last #{last}"
282
+ end
283
+ end
284
+
285
+ private def call_operation_according_to_parameter(target, operation, parameter)
286
+ case parameter
287
+ when nil
288
+ target.send(operation)
289
+ when Symbol
290
+ target.send(operation).send(parameter)
291
+ when Proc
292
+ target.send(operation, &parameter)
293
+ when Array
294
+ unless parameter.size == 2 && parameter.all? { |_| _.is_a?(Proc) }
295
+ raise ArgumentError, "Don't know how to handle parameter #{parameter}"
296
+ end
297
+
298
+ target.send(operation, &(parameter.first >> parameter.last))
130
299
  else
131
- raise ArgumentError, "Pipeline '#{symbol}' is undefined" if args.empty?
300
+ target.send(operation, parameter)
301
+ end
302
+ end
303
+
304
+ private def is_a_series_constructor?(operation)
305
+ Musa::Series::Constructors.instance_methods.include?(operation)
306
+ end
132
307
 
308
+ private def is_a_series_operation?(operation)
309
+ Musa::Series::Operations.instance_methods.include?(operation)
310
+ end
311
+
312
+ private def method_missing(symbol, *args, &block)
313
+ if is_a_series_constructor?(symbol) || is_a_series_operation?(symbol)
314
+ symbol
315
+ elsif args.any? || block
316
+ args += [block] if block
133
317
  pipeline(symbol, args)
318
+ else # for non-series methods
319
+ symbol
134
320
  end
135
321
  end
136
322
 
@@ -142,6 +328,8 @@ module Musa
142
328
  end
143
329
  end
144
330
 
331
+ private_constant :Pipeline
332
+ private_constant :Route
145
333
  private_constant :DSLContext
146
334
  end
147
335
  end
data/musa-dsl.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'musa-dsl'
3
- s.version = '0.23.1'
4
- s.date = '2021-07-02'
3
+ s.version = '0.23.6'
4
+ s.date = '2021-07-29'
5
5
  s.summary = 'A simple Ruby DSL for making complex music'
6
6
  s.description = 'Musa-DSL: A Ruby framework and DSL for algorithmic sound and musical thinking and composition'
7
7
  s.authors = ['Javier Sánchez Yeste']
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: musa-dsl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.23.1
4
+ version: 0.23.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Javier Sánchez Yeste
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-02 00:00:00.000000000 Z
11
+ date: 2021-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: citrus