valkey-objects 0.2.0 → 0.2.1

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: 66451b3bbdc217925b068c50c8cdcd5cd392a6ddef99adbc7300c683c112d152
4
- data.tar.gz: eb06049f2987c87b8cb7fb188e15960fab83d2f7a820205b3ddd06df1ed11828
3
+ metadata.gz: 8a6bb452e823041de80c00be7bbea235bb937feef6937cac1ec122dd216a47f9
4
+ data.tar.gz: 15edeaffe86bf2eb97360e78930befcba9a7ab41c4a9f9a56e99cd7fedba1e3e
5
5
  SHA512:
6
- metadata.gz: 78d4470e2aa1cc2b9763265c7a940f4f2da58798460fbce998e2aedd32cdcd6136accca257d83719328e59011b6da185c59f590863642d430488966b9a77cb9e
7
- data.tar.gz: ad6b0974b14ebd9bc022aa259a4a953556d5ec567d370a0335b279fc695f655713cba4d0499e8cb7d6bc15e610a5ba4918d8a81bdeca4ce8820bd0d65f8f6439
6
+ metadata.gz: 1380445b88e8949132e7967b16ece714f74a3118bab76373e7d412a95709a062b63b1bfe56844d0f315d0b672e66b0f4ba67761472ec4c816aadbfc1de7ddb57
7
+ data.tar.gz: 6871da9972c3489afbedf59fb356edf2ba340deb9e4fe4ff47e172e144bb99624e0707497ed89fe4042206ad650b3e83938eb6eca2ce82245625509619779a38
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Valkey
4
4
  module Objects
5
- VERSION = "0.2.0"
5
+ VERSION = "0.2.1"
6
6
  end
7
7
  end
@@ -5,8 +5,14 @@ require_relative "objects/version"
5
5
  require 'redis-client'
6
6
  require 'json'
7
7
  require 'ruby-duration'
8
+ require 'amatch'
8
9
  require 'ap'
9
10
  module VK
11
+
12
+ @@XX = {}
13
+
14
+
15
+
10
16
  def self.included(x)
11
17
  x.extend VK
12
18
  end
@@ -16,6 +22,8 @@ module VK
16
22
  # Example:
17
23
  # class ExmpleObject
18
24
  # include VK
25
+ #
26
+ ## Add Object Containers by Value Type:
19
27
  # value :myValue
20
28
  # counter :myCounter
21
29
  # hashkey :myHashKey
@@ -25,49 +33,83 @@ module VK
25
33
  # place :myPlace
26
34
  # pipe :myPipe
27
35
  # toggle :myToggle
36
+ # ticker :myTicker
37
+ # entry :myEntry
38
+ #
39
+ ## Add an Object Container With an Implicit Expiration:
40
+ # value :myExpiringValue, ttl: (seconds to live without interaction)
41
+ #
28
42
  # def initialize k
29
43
  # @id = k
30
44
  # end
31
45
  # end
32
- #
33
- # Instantiation: @obj = ExampleObject.new('object id...')
46
+ ##
47
+ # Create the Object:
48
+ # @obj = ExampleObject.new('object id...')
49
+ ##
50
+ # For all object methods:
51
+ # @obj.myObjectContainer.expire(seconds)
52
+ # @obj.myObjectContainer.delete!
53
+ #
34
54
  xx = x.name.gsub("::", "-")
35
55
  ##
56
+ # Object Method Types:
57
+ ##
58
+ # A String Value
59
+ ##
36
60
  # value :myValue
37
- # @obj.myValue => A string
61
+ # @obj.myValue
62
+ # @obj.myValue.exist?
38
63
  # @obj.myValue.value = "my value"
39
64
  # @obj.myValue.value => "my value"
40
- define_method(:value) { |k| define_method(k.to_sym) { V.new(%[#{xx}:value:#{k}:#{@id}]) } };
65
+ define_method(:value) { |k, h={}| define_method(k.to_sym) { VALUE.new(%[#{xx}:value:#{k}:#{@id}], h) } };
66
+ ##
67
+ # A Number Value
41
68
  ##
42
- # counter :myCounter => A number
69
+ # counter :myCounter
43
70
  # @obj.myCounter
71
+ # @obj.myCounter.exist?
44
72
  # @obj.myCounter.value = number
45
- # @obj.myCounter.value => ...
73
+ # @obj.myCounter.value => number
46
74
  # @obj.myCounter.incr number
47
75
  # @obj.myCounter.decr number
48
76
  #
49
- define_method(:counter) { |k| define_method(k.to_sym) { C.new(%[#{xx}:counter:#{k}:#{@id}]); } };
77
+ define_method(:counter) { |k, h={}| define_method(k.to_sym) { COUNTER.new(%[#{xx}:counter:#{k}:#{@id}], h); } };
50
78
  ##
51
- #
52
- define_method(:timestamp) { |k| define_method(k.to_sym) { N.new(%[#{xx}:counter:#{k}:#{@id}]) } }
53
- ##
54
- # hashkey :myHashKey => The ubiquitous Ruby Hash in valkey/redis
79
+ # An Epoch Value
80
+ ##
81
+ # timestamp :myTimestamp
82
+ # @obj.myTimestamp
83
+ # @obj.myTimestamp.exist?
84
+ # @obj.myTimestamp.value!
85
+ # @obj.myTimestamp.value => epoch
86
+ # @obj.myTimestamp.ago => Seconds since epoch
87
+ # @obj.myTimestamp.to_time => Time object
88
+ define_method(:timestamp) { |k, h={}| define_method(k.to_sym) { TIMESTAMP.new(%[#{xx}:timestamp:#{k}:#{@id}], h) } }
89
+ ##
90
+ # A Hash Value
91
+ ##
92
+ # hashkey :myHashKey
55
93
  # @obj.myHashKey
56
94
  # @obj.myHashKey[:key] = value
57
- # @obj.myHashKey[:key] => ...
95
+ # @obj.myHashKey[:key] => "value"
58
96
  #
59
- define_method(:hashkey) { |k| define_method(k.to_sym) { H.new(%[#{xx}:hash:#{k}:#{@id}]); } };
60
- ##
61
- # sortedset :mySortedSet => A ranked collection of members
97
+ define_method(:hashkey) { |k, h={}| define_method(k.to_sym) { HASH.new(%[#{xx}:hashkey:#{k}:#{@id}], h); } };
98
+ ##
99
+ # A Sorted Set Value
100
+ ##
101
+ # sortedset :mySortedSet
62
102
  # @obj.mySortedSet
63
103
  # @obj.mySortedSet[:key] = value
64
104
  # @obj.mySortedSet[:key] => ...
65
105
  # @obj.mySortedSet.value { |key, i| ... }
66
106
  # @obj.mySortedSet.poke key, number
67
107
  #
68
- define_method(:sortedset) { |k| define_method(k.to_sym) { S.new(%[#{xx}:sortedset:#{k}:#{@id}]); } };
69
- ##
70
- # set :mySet => A collect of unique members
108
+ define_method(:sortedset) { |k, h={}| define_method(k.to_sym) { SORTEDSET.new(%[#{xx}:sortedset:#{k}:#{@id}], h); } };
109
+ ##
110
+ # A Collection of Values
111
+ ##
112
+ # set :mySet
71
113
  # @obj.mySet
72
114
  # @obj.mySet << "x"
73
115
  # @obj.myset.rm "x"
@@ -76,17 +118,21 @@ module VK
76
118
  # @obj.myset["pattern"]
77
119
  # @obj.mySet.value { |key, i| ... }
78
120
  #
79
- define_method(:set) { |k| define_method(k.to_sym) { G.new(%[#{xx}:set:#{k}:#{@id}]); } };
80
- ##
81
- # queue :myQueue => An array with push and pop utility
121
+ define_method(:set) { |k, h={}| define_method(k.to_sym) { SET.new(%[#{xx}:set:#{k}:#{@id}], h); } };
122
+ ##
123
+ # A List of Values
124
+ ##
125
+ # queue :myQueue
82
126
  # @obj.myQueue
83
127
  # @obj.myQueue << "x"
84
128
  # @obj.myQueue.front => "x" and pop
85
129
  # @obj.myQueue.value { |key, i| ... }
86
130
  #
87
- define_method(:queue) { |k| define_method(k.to_sym) { Q.new(%[#{xx}:queue:#{k}:#{@id}]); } };
88
- ##
89
- # place :myPlace => GPS Coordinates
131
+ define_method(:queue) { |k, h={}| define_method(k.to_sym) { QUEUE.new(%[#{xx}:queue:#{k}:#{@id}], h); } };
132
+ ##
133
+ # A Collection of Places
134
+ ##
135
+ # place :myPlace
90
136
  # @obj.myPlace
91
137
  # @obj.myPlace.add "key", longitude, latitude
92
138
  # @obj.myPlace["key"] => { longitude: xx, latitude: yy }
@@ -94,24 +140,45 @@ module VK
94
140
  # @obj.myPlace.radius longitude, latitude, distance
95
141
  # @obj.myPlace.value { |key, i| ... }
96
142
  #
97
- define_method(:place) { |k| define_method(k.to_sym) { P.new(%[#{xx}:place:#{k}:#{@id}]); } };
98
- ##
99
- # pipe :myPipe => Subscibe and handle, and publish.
100
- # @obj.myPipe
101
- # @obj.myPipe.on { |msg| ... }
102
- # @obj.myPipe << "input" => publish { input: "input" }
103
- # @obj.myPipe << ["input","input"] => publish { inputs: ["input", "input"] }
104
- # @obj.myPipe << {} => publish {}
105
- #
106
- define_method(:pipe) { |k| define_method(k.to_sym) { B.new(%[#{xx}:pipe:#{k}:#{@id}]); } };
107
- ##
108
- # toggle :myToggle => Boolean toggle.
143
+ define_method(:place) { |k, h={}| define_method(k.to_sym) { PLACE.new(%[#{xx}:place:#{k}:#{@id}], h); } };
144
+ ##
145
+ # A Boolean Value
146
+ ##
147
+ # toggle :myToggle
109
148
  # @obj.myToggle
110
- # @obj.value = bool
111
- # @obj.value => ...
112
- # @obj.value! => value = !value
149
+ # @obj.myToggle.exist?
150
+ # @obj.myToggle.value = bool
151
+ # @obj.myToggle.value => ...
152
+ # @obj.myToggle.value! => value = !value
113
153
  #
114
- define_method(:toggle) { |k| define_method(k.to_sym) { T.new(%[#{xx}:toggle:#{k}:#{@id}]); } };
154
+ define_method(:toggle) { |k, h={}| define_method(k.to_sym) { TOGGLE.new(%[#{xx}:toggle:#{k}:#{@id}], h); } };
155
+ ##
156
+ # A Sorted Hash of Values
157
+ ##
158
+ # ticker :myTicker
159
+ # @obj.myTicker
160
+ # @obj.myTicker[:key] = value
161
+ # @obj.myTicker[:key] => "value"
162
+ # @obj.myticker.value { |i,e| ... }
163
+ define_method(:ticker) { |k, h={}| define_method(k.to_sym) { SORTEDHASH.new(%[#{xx}:ticker:#{k}:#{@id}], h); } };
164
+ ##
165
+ # A List of Hashes
166
+ ##
167
+ # entry :myEntry
168
+ # @obj.myEntry
169
+ # @obj.myEntry << { key: 'value', ... }
170
+ # @obj.myEntry.value { |i,e| ... }
171
+ define_method(:entry) { |k, h={}| define_method(k.to_sym) { HASHLIST.new(%[#{xx}:entry:#{k}:#{@id}], h); } };
172
+ ##
173
+ # A list of Strings
174
+ ##
175
+ # vector :myVector
176
+ # @obj.myVector
177
+ # @obj.myVector << "An Entry of Text."
178
+ # @obj.myVector.value { |i,e| ... }
179
+ # @obj.myvector[0] = "An Entry of Text."
180
+ define_method(:vector) { |k, h={}| define_method(k.to_sym) { VECTOR.new(%[#{xx}:vector:#{k}:#{@id}], h); } };
181
+
115
182
  end
116
183
 
117
184
  def id
@@ -161,11 +228,15 @@ module VK
161
228
  def self.redis
162
229
  RedisClient.config(host: "127.0.0.1", port: 6379, db: 0).new_client
163
230
  end
164
-
231
+
165
232
  class O
166
233
  attr_reader :key
167
- def initialize k
234
+ def initialize k, h={}
168
235
  @key = k
236
+ @opts = h
237
+ if @opts.has_key?(:ttl)
238
+ expire @opts[:ttl]
239
+ end
169
240
  end
170
241
  def delete!
171
242
  VK.redis.call("DEL", key);
@@ -175,13 +246,19 @@ module VK
175
246
  end
176
247
  end
177
248
 
178
- class N < O
249
+ class TIMESTAMP < O
179
250
  def value
180
251
  VK.redis.call("GET", key).to_i;
252
+ if @opts.has_key?(:flush) == true
253
+ delete!
254
+ end
181
255
  end
182
256
  def value!
183
257
  VK.redis.call("SET", key, "#{VK.clock.to_i}");
184
258
  end
259
+ def exist?
260
+ VK.redis.call("GET", key) ? true : false
261
+ end
185
262
  def ago
186
263
  VK.clock.to_i - value;
187
264
  end
@@ -190,10 +267,16 @@ module VK
190
267
  end
191
268
  end
192
269
 
193
- class T < O
270
+ class TOGGLE < O
194
271
  def value
195
- VK.redis.call("GET", key) == 'true' ? true : false
272
+ VK.redis.call("GET", key) == 'true' ? true : false
273
+ if @opts.has_key?(:flush) == true
274
+ delete!
275
+ end
196
276
  end
277
+ def exist?
278
+ VK.redis.call("GET", key) ? true : false
279
+ end
197
280
  def value= x
198
281
  VK.redis.call("SET", key, "#{x.to_s}")
199
282
  end
@@ -206,42 +289,19 @@ module VK
206
289
  end
207
290
  end
208
291
 
209
- class B < O
210
- def on &b
211
- pubsub = VK.redis.pubsub
212
- pubsub.call("SUBSCRIBE", key)
213
- Process.detach( fork do
214
- loop do
215
- if m = pubsub.next_event(0)
216
- cn, ty, na, id = key.split(":")
217
- if m[0] == "message"
218
- b.call({ stub: na, object: cn.gsub("-", "::"), type: ty, id: id, event: m[0], data: JSON.parse(m[2]) })
219
- else
220
- ap({ stub: na, object: cn.gsub("-", "::"), type: ty, id: id, event: m[0], data: m[2] })
221
- end
222
- end
223
- end
224
- end
225
- );
226
- end
227
- def << x
228
- if x.class == String
229
- VK.redis.call("PUBLISH", key, JSON.generate({ input: x }))
230
- elsif x.class == Array
231
- VK.redis.call("PUBLISH", key, JSON.generate({ inputs: x }))
232
- elsif x.class == Hash
233
- VK.redis.call("PUBLISH", key, JSON.generate(x))
234
- end
235
- end
236
- end
237
-
238
- class V < O
292
+ class VALUE < O
239
293
  def value
240
294
  VK.redis.call("GET", key)
295
+ if @opts.has_key?(:flush) == true
296
+ delete!
297
+ end
241
298
  end
242
299
  def value= x
243
300
  VK.redis.call("SET", key, x)
244
301
  end
302
+ def exist?
303
+ VK.redis.call("GET", key) ? true : false
304
+ end
245
305
  def match r, &b
246
306
  m = Regexp.new(r).match(value)
247
307
  if block_given?
@@ -251,8 +311,48 @@ module VK
251
311
  end
252
312
  end
253
313
  end
314
+
315
+ class VECTOR < O
316
+ include Amatch
317
+ def value &b
318
+ VK.redis.call("LRANGE", key, 0, -1).each_with_index { |e, i|
319
+ b.call(i, VK.redis.call("GET", e))
320
+ if @opts.has_key?(:flush) == true
321
+ VK.redis.call("DEL", e);
322
+ end
323
+ }
324
+ if @opts.has_key?(:flush) == true
325
+ delete!
326
+ end
327
+ end
328
+ def [] k
329
+ VK.redis.call("GET", "#{@key}-#{k}");
330
+ end
331
+ def << i
332
+ kk = %[#{@key}-#{VK.redis.call("LLEN",@key)}]
333
+ VK.redis.call("SET", kk, i);
334
+ VK.redis.call("RPUSH", key, kk)
335
+ end
336
+ def nearest p
337
+ h = {}
338
+ value { |i,v|
339
+ h[i] = {
340
+ value: v,
341
+ levenshtein: p.levenshtein_similar(v),
342
+ damerau: p.damerau_levenshtein_similar(v),
343
+ hamming: p.hamming_similar(v),
344
+ distance: p.pair_distance_similar(v),
345
+ subsequence: p.longest_subsequence_similar(v),
346
+ substring: p.longest_substring_similar(v),
347
+ jaro: p.jaro_similar(v),
348
+ winkler: p.jarowinkler_similar(v)
349
+ }
350
+ }
351
+ return h
352
+ end
353
+ end
254
354
 
255
- class C < O
355
+ class COUNTER < O
256
356
  def incr n
257
357
  VK.redis.call("SET", key, value + n.to_f)
258
358
  end
@@ -261,27 +361,36 @@ module VK
261
361
  end
262
362
  def value
263
363
  VK.redis.call("GET", key).to_f
364
+ if @opts.has_key?(:flush) == true
365
+ delete!
366
+ end
264
367
  end
265
368
  def value= n
266
369
  VK.redis.call("SET", key, n.to_f)
267
370
  end
371
+ def exist?
372
+ VK.redis.call("GET", key) ? true : false
373
+ end
268
374
  end
269
375
 
270
- class H < O
376
+ class HASH < O
271
377
  def [] k
272
378
  VK.redis.call("HGET", key, k);
273
379
  end
274
380
  def []= k,v
275
- VK.redis.call("HMSET", key, k, v);
381
+ VK.redis.call("HSET", key, k, v);
276
382
  end
277
383
  def to_h
278
384
  VK.redis.call("HGETALL", key);
279
385
  end
280
386
  end
281
387
 
282
- class Q < O
388
+ class QUEUE < O
283
389
  def value &b
284
390
  VK.redis.call("LRANGE", key, 0, -1).each_with_index { |e, i| b.call(i, e) }
391
+ if @opts.has_key?(:flush) == true
392
+ delete!
393
+ end
285
394
  end
286
395
  def length
287
396
  VK.redis.call("LLEN", key)
@@ -294,9 +403,12 @@ module VK
294
403
  end
295
404
  end
296
405
 
297
- class S < O
406
+ class SORTEDSET < O
298
407
  def value &b
299
408
  VK.redis.call("ZREVRANGE", key, 0, -1, 'WITHSCORES').each_with_index { |e, i| b.call(i, e) }
409
+ if @opts.has_key?(:flush) == true
410
+ delete!
411
+ end
300
412
  end
301
413
  def [] k
302
414
  VK.redis.call("ZSCORE", key, k).to_f;
@@ -309,9 +421,20 @@ module VK
309
421
  end
310
422
  end
311
423
 
312
- class G < O
424
+ class SET < O
313
425
  def value &b
314
- VK.redis.call("SMEMBERS", key).each_with_index { |e, i| b.call(i, e) }
426
+ a = Set.new
427
+ VK.redis.call("SMEMBERS", key).each_with_index { |e, i|
428
+ if block_given?
429
+ a << b.call(i, e)
430
+ else
431
+ a << e
432
+ end
433
+ }
434
+ if @opts.has_key?(:flush) == true
435
+ delete!
436
+ end
437
+ return aa
315
438
  end
316
439
  def include? k
317
440
  if VK.redis.call("SMISMEMBER", key, k)[0] == 0
@@ -342,9 +465,20 @@ module VK
342
465
  end
343
466
  end
344
467
 
345
- class P < O
468
+ class PLACE < O
346
469
  def value &b
347
- VK.redis.call("ZRANGE", key, 0, -1).each_with_index { |e, i| b.call(i, e) };
470
+ a = []
471
+ VK.redis.call("ZRANGE", key, 0, -1).each_with_index { |e, i|
472
+ if block_given?
473
+ a << b.call(i, e)
474
+ else
475
+ a << e
476
+ end
477
+ };
478
+ if @opts.has_key?(:flush) == true
479
+ delete!
480
+ end
481
+ return a
348
482
  end
349
483
  def add i, lon, lat
350
484
  VK.redis.call("GEOADD", key, lon, lat, i)
@@ -363,6 +497,68 @@ module VK
363
497
  end
364
498
  end
365
499
 
500
+ class SORTEDHASH < O
501
+ def value &b
502
+ VK.redis.call("ZREVRANGE", key, 0, -1, 'WITHSCORES').each_with_index { |e, i|
503
+ kx = %[#{@key}-#{e[0]}]
504
+ a = []
505
+ if block_given?
506
+ b.call(i, { key: e[0], value: VK.redis.call("GET", kx), score: e[1] } )
507
+ else
508
+ a << { key: e[0], value: VK.redis.call("GET", kx), score: e[1] }
509
+ end
510
+ if @opts.has_key?(:flush) == true
511
+ VK.redis.call("DEL", kx)
512
+ end
513
+ }
514
+ if @opts.has_key?(:flush) == true
515
+ delete!
516
+ end
517
+ return a
518
+ end
519
+ def [] k
520
+ kx = %[#{@key}-#{k}]
521
+ VK.redis.call("GET", kx)
522
+ end
523
+ def []= k, v
524
+ kx = %[#{@key}-#{k}]
525
+ VK.redis.call("SET", kx, v)
526
+ VK.redis.call("ZINCRBY", key, 1, k)
527
+ end
528
+ end
529
+
530
+ class HASHLIST < O
531
+ def value &b
532
+ a = []
533
+ VK.redis.call("LRANGE", key, 0, -1).each_with_index { |e, i|
534
+ if block_given?
535
+ a << b.call(i, JSON.parse(VK.redis.call("GET", e)))
536
+ else
537
+ a << JSON.parse(VK.redis.call("GET", e))
538
+ end
539
+ if @opts.has_key?(:flush) == true
540
+ VK.redis.call("DEL", e)
541
+ end
542
+ }
543
+ if @opts.has_key?(:flush) == true
544
+ delete!
545
+ end
546
+ return a
547
+ end
548
+ def length
549
+ VK.redis.call("LLEN", key)
550
+ end
551
+ def [] k
552
+ hx = %[#{key}-#{k}]
553
+ JSON.parse(VK.redis.call("GET", hx));
554
+ end
555
+ def push h={}
556
+ hx = %[#{key}-#{length}]
557
+ VK.redis.call("SET", hx, JSON.generate(h));
558
+ VK.redis.call("RPUSH", key, hx)
559
+ end
560
+ end
561
+
366
562
  def self.flushdb!
367
563
  VK.redis.call("FLUSHDB")
368
564
  end
@@ -35,6 +35,7 @@ Gem::Specification.new do |spec|
35
35
  spec.add_dependency "json"
36
36
  spec.add_dependency "ruby-duration"
37
37
  spec.add_dependency "pry"
38
+ spec.add_dependency "amatch"
38
39
  spec.add_dependency "awesome_print"
39
40
  # For more information and examples about making a new gem, check out our
40
41
  # guide at: https://bundler.io/guides/creating_gem.html
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: valkey-objects
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erik Olson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-01-12 00:00:00.000000000 Z
11
+ date: 2025-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis-client
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: amatch
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: awesome_print
71
85
  requirement: !ruby/object:Gem::Requirement