joys 0.1.5 → 0.1.7

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: 6927c0ba1da72024357dea7dd031f82c7feb252f079b4835ab98c8554f035f06
4
- data.tar.gz: 0ece16f17983a990d18553873f31e521b23790e00a83c6f572c0ebe86cede617
3
+ metadata.gz: 97eaf65fc04c1055382709a285445f71304e942fc1178e15f12d9a4184b72453
4
+ data.tar.gz: 8c4e0c0a46516a48be09554d2774164e9f2fc1ca662f2e708896b8cd743dffc3
5
5
  SHA512:
6
- metadata.gz: d194c2dd9a7a1ba5d3045efde26b8ff03ed74482256b4157b0bd646ebae50b5ed4eb8736b7491d485fd175a7e1eafd4b9f15c08f20ed7bedb08d45db013ffc0d
7
- data.tar.gz: a830066addb6ced9156c3549464be742b1aaa60df5ec6a279f33e7db1e3125c1b8ed5828b42e132904ea2b573ac0236e1de0f63fc1c2f890282966803fbe6feb
6
+ metadata.gz: 88b135651e912e1b6f2402599372d5c6615873805de142e5a0e4ebfb88ad23862fa3203bb72c1a90417fbf45cb14b3061e89d13bac015206bc7a4e688c398d33
7
+ data.tar.gz: 50882f67ffe2de1da38f7dc3d83462f0eaf0ef6e3ab1149bc73ded3a713104ed078f1c048cea123c1048da8cf77a90a532335b805de6a89652d168ac55c30297
data/CHANGELOG.md CHANGED
@@ -28,4 +28,14 @@
28
28
 
29
29
  ## [0.1.5] - 2025-09-30
30
30
 
31
- - Improved Rails integration and helper availability
31
+ - Improved Rails integration and helper availability
32
+
33
+ ## [0.1.6] - 2025-10-02
34
+
35
+ - Joy.define(:comp) now captures block arguments
36
+
37
+
38
+ ## [0.1.7] - 2026-01-09
39
+
40
+ - Added get() for pulling strings outside the buffer within layouts:
41
+ `body(cs:get(:bodyclass)) {...}`
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ ![joys](https://github.com/user-attachments/assets/ec594256-b1ee-4ec7-a876-491abcfa1d66)
2
+
1
3
  # Joys - HTML Templates at the Speed of Light
2
4
 
3
5
  **Write HTML like Ruby, render it at the speed of C.**
@@ -9,7 +11,7 @@ Joys is a pure-Ruby HTML templating engine with built-in CSS and ludicrous-speed
9
11
  - **Blazing Fast** - 3x faster on cold render. Orders of magnitude faster after caching.
10
12
  - **Pure Ruby** - No new syntax to learn. It's just methods and blocks.
11
13
  - **Testable** - Components are just functions. Test them like any Ruby code.
12
- - **Fully Integrated Styling** - Deduplicated, sorted css right inside your components
14
+ - **Fully Integrated Styling** - Deduplicated, responsive css right inside your components
13
15
  - **Framework Agnostic** - Use it in Rails, Roda, Sinatra, Hanami, Syro, etc.
14
16
 
15
17
  ---
@@ -286,110 +288,6 @@ Joys.define(:comp, :pricing_card) do |plan|
286
288
  }
287
289
  end
288
290
  ```
289
- ---
290
- ## A Word on Performance
291
-
292
- Using simple components and views (only 3 layers of nesting) we can see how Joy stacks up:
293
-
294
- ### Simple Templates (385 chars)
295
-
296
- #### ❄️ COLD RENDER (new object per call)
297
- | | user | system | total | real. |
298
- |------|--------|--------|--------|--------|
299
- |Joys: |0.060535|0.000200|0.060735|0.060736|
300
- |Slim: |0.048344|0.000183|0.048527|0.048530|
301
- |ERB: |0.301811|0.000808|0.302619|0.302625|
302
- |Phlex:|0.069636|0.000470|0.070106|0.071157|
303
-
304
- #### 🔥 HOT RENDER (cached objects)
305
- | | user | system | total | real |
306
- |------|--------|---------|--------|--------|
307
- |Joys: |0.065255| 0.000257|0.065512|0.065512|
308
- |Slim: |0.049323| 0.000295|0.049618|0.049695|
309
- |ERB: |0.309757| 0.001167|0.310924|0.310929|
310
- |Phlex:|0.069663| 0.000141|0.069804|0.069805|
311
-
312
- #### 💾 MEMORY USAGE
313
- Joys memory: 532356 bytes
314
- Slim memory: 40503436 bytes
315
- Phlex memory: 8000 bytes
316
- ERB memory: 1669256 bytes
317
-
318
- At smaller scales performance is on par with Phlex, which has excellent speed and superior
319
-
320
- ### Complex Templates (8,000+ chars)
321
-
322
- As template complexity grows, Joys starts to really show off its optimizations. This benchmark tests a full dashboard page with 5 components and 2 loops yields:
323
-
324
- * Data parsing
325
- * Layouts
326
- * Multiple Content Slots
327
- * Multiple Components
328
- * Several Iterations
329
- * Conditions
330
-
331
- ### ❄️ COLD RENDER (new object per call)
332
-
333
- This is the bare bones benchmark, no "cheating" allowed.
334
-
335
- | | user | system | total | real |
336
- |------|--------|--------|--------|--------|
337
- | Joys |0.051715|0.000364|0.052079|0.052080|
338
- | ERB |0.520495|0.003696|0.524191|0.524187|
339
- | Slim |6.001650|0.019418|6.021068|6.021013|
340
- | Phlex|0.169567|0.000373|0.169940|0.169938|
341
-
342
- Note: Joys achieves its 'cold render' speed by eliminating object overhead and using simple string operations with smart memory management.
343
-
344
- ### 🔥 HOT RENDER (cached objects)
345
-
346
- | | user | system | total | real |
347
- |------|---------|--------|---------|--------|
348
- |JOYS: | 0.000463|0.000010| 0.000473|0.000473|
349
- |SLIM: | 0.045881|0.000358| 0.046239|0.046243|
350
- |PHLEX:| 0.167631|0.000760| 0.168391|0.168661|
351
- |ERB: | 0.394509|0.004084| 0.398593|0.398614|
352
-
353
- Note: Joys achieves its 'hot render' speed by compiling a template's structure into a highly optimized render function the first time it's called. Subsequent calls with the same component structure reuse this function, bypassing compilation and object allocation, and only interpolating the dynamic data.
354
-
355
-
356
- ### 💾 MEMORY USAGE
357
-
358
- Joys memory: 7587400 bytes
359
- Slim memory: 217778600 bytes
360
- Phlex memory: 9956000 bytes
361
- ERB memory: 7264240 bytes
362
-
363
- Even without caching, Joys is rendering at around 50 milliseconds.
364
-
365
- The real performance comes after caching at half a millisecond.
366
-
367
- That's not just fast, its _ludicrous speed_ 🚀 All thanks to Joys's one-time compilation and caching of the template structure.
368
-
369
- But don't take our word for it:
370
-
371
- ```
372
- gem install erb slim phlex joys
373
-
374
- # Simple benchmark
375
- ruby text/bench/simple.rb
376
-
377
- # Complex benchmark
378
- ruby text/bench/deep.rb
379
- ```
380
-
381
- Note: If you have any additions, critiques or input on these benchmarks please submit a pull request.
382
-
383
- ### Performance Philosophy
384
-
385
- Joys attains its incredible speed through:
386
-
387
- 1. **Precompiled layouts** - Templates compile once, render many
388
- 2. **Direct string building** - No intermediate AST or object allocation
389
- 3. **Smart caching** - Components cache by arguments automatically
390
- 4. **Zero abstraction penalty** - It's just method calls and string concatenation
391
-
392
- All achieved without C or Rust. Just plain old Ruby, with a core of under 500 lines of code.
393
291
 
394
292
  ---
395
293
 
@@ -1117,6 +1015,113 @@ The `?` suffix provides a clean, consistent way to integrate markup processing i
1117
1015
 
1118
1016
  ---
1119
1017
 
1018
+ ---
1019
+ ## A Word on Performance
1020
+
1021
+ Using simple components and views (only 3 layers of nesting) we can see how Joy stacks up:
1022
+
1023
+ ### Simple Templates (385 chars)
1024
+
1025
+ #### ❄️ COLD RENDER (new object per call)
1026
+ | | user | system | total | real. |
1027
+ |------|--------|--------|--------|--------|
1028
+ |Joys: |0.060535|0.000200|0.060735|0.060736|
1029
+ |Slim: |0.048344|0.000183|0.048527|0.048530|
1030
+ |ERB: |0.301811|0.000808|0.302619|0.302625|
1031
+ |Phlex:|0.069636|0.000470|0.070106|0.071157|
1032
+
1033
+ #### 🔥 HOT RENDER (cached objects)
1034
+ | | user | system | total | real |
1035
+ |------|--------|---------|--------|--------|
1036
+ |Joys: |0.065255| 0.000257|0.065512|0.065512|
1037
+ |Slim: |0.049323| 0.000295|0.049618|0.049695|
1038
+ |ERB: |0.309757| 0.001167|0.310924|0.310929|
1039
+ |Phlex:|0.069663| 0.000141|0.069804|0.069805|
1040
+
1041
+ #### 💾 MEMORY USAGE
1042
+ Joys memory: 532356 bytes
1043
+ Slim memory: 40503436 bytes
1044
+ Phlex memory: 8000 bytes
1045
+ ERB memory: 1669256 bytes
1046
+
1047
+ At smaller scales performance is on par with Phlex, which has excellent speed and superior
1048
+
1049
+ ### Complex Templates (8,000+ chars)
1050
+
1051
+ As template complexity grows, Joys starts to really show off its optimizations. This benchmark tests a full dashboard page with 5 components and 2 loops yields:
1052
+
1053
+ * Data parsing
1054
+ * Layouts
1055
+ * Multiple Content Slots
1056
+ * Multiple Components
1057
+ * Several Iterations
1058
+ * Conditions
1059
+
1060
+ ### ❄️ COLD RENDER (new object per call)
1061
+
1062
+ This is the bare bones benchmark, no "cheating" allowed.
1063
+
1064
+ | | user | system | total | real |
1065
+ |------|--------|--------|--------|--------|
1066
+ | Joys |0.051715|0.000364|0.052079|0.052080|
1067
+ | ERB |0.520495|0.003696|0.524191|0.524187|
1068
+ | Slim |6.001650|0.019418|6.021068|6.021013|
1069
+ | Phlex|0.169567|0.000373|0.169940|0.169938|
1070
+
1071
+ Note: Joys achieves its 'cold render' speed by eliminating object overhead and using simple string operations with smart memory management.
1072
+
1073
+ ### 🔥 HOT RENDER (cached objects)
1074
+
1075
+ | | user | system | total | real |
1076
+ |------|---------|--------|---------|--------|
1077
+ |JOYS: | 0.000463|0.000010| 0.000473|0.000473|
1078
+ |SLIM: | 0.045881|0.000358| 0.046239|0.046243|
1079
+ |PHLEX:| 0.167631|0.000760| 0.168391|0.168661|
1080
+ |ERB: | 0.394509|0.004084| 0.398593|0.398614|
1081
+
1082
+ Note: Joys achieves its 'hot render' speed by compiling a template's structure into a highly optimized render function the first time it's called. Subsequent calls with the same component structure reuse this function, bypassing compilation and object allocation, and only interpolating the dynamic data.
1083
+
1084
+
1085
+ ### 💾 MEMORY USAGE
1086
+
1087
+ Joys memory: 7587400 bytes
1088
+ Slim memory: 217778600 bytes
1089
+ Phlex memory: 9956000 bytes
1090
+ ERB memory: 7264240 bytes
1091
+
1092
+ Even without caching, Joys is rendering at around 50 milliseconds.
1093
+
1094
+ The real performance comes after caching at half a millisecond.
1095
+
1096
+ That's not just fast, its _ludicrous speed_ 🚀 All thanks to Joys's one-time compilation and caching of the template structure.
1097
+
1098
+ But don't take our word for it:
1099
+
1100
+ ```
1101
+ gem install erb slim phlex joys
1102
+
1103
+ # Simple benchmark
1104
+ ruby text/bench/simple.rb
1105
+
1106
+ # Complex benchmark
1107
+ ruby text/bench/deep.rb
1108
+ ```
1109
+
1110
+ Note: If you have any additions, critiques or input on these benchmarks please submit a pull request.
1111
+
1112
+ ### Performance Philosophy
1113
+
1114
+ Joys attains its incredible speed through:
1115
+
1116
+ 1. **Precompiled layouts** - Templates compile once, render many
1117
+ 2. **Direct string building** - No intermediate AST or object allocation
1118
+ 3. **Smart caching** - Components cache by arguments automatically
1119
+ 4. **Zero abstraction penalty** - It's just method calls and string concatenation
1120
+
1121
+ All achieved without C or Rust. Just plain old Ruby, with a core of under 500 lines of code.
1122
+
1123
+ ---
1124
+
1120
1125
  ## The Final Assessment: When to Use Joys
1121
1126
 
1122
1127
  - You want **high-throughput** Ruby APIs serving HTML.
@@ -1182,4 +1187,4 @@ Joys isn’t just a templating engine. It’s a new definition of what rendering
1182
1187
 
1183
1188
  ## Thanks and Gratitude
1184
1189
 
1185
- Massive shout-out to the Masatoshi Seki (ERB), Daniel Mendler (Slim), Daniel Mendler (Phlex/P2), and Jonathan Gillette (Markaby). All of you have made countless lives so much easier. The ruby community thanks you for your service!
1190
+ Massive shout-out to the Masatoshi Seki (ERB), Daniel Mendler (Slim), Daniel Mendler (Phlex/P2), and Jonathan Gillette (Markaby). All of you have made countless lives so much easier. The ruby community thanks you for your service!
data/joys-0.1.5.gem ADDED
Binary file
data/lib/joys/config.rb CHANGED
@@ -63,17 +63,13 @@ module Joys
63
63
  }
64
64
  end
65
65
  module ControllerMethods
66
- def render_joy(path, **locals)
67
- Joys.reload! if Config.dev?
68
- file = File.join(Config.pages, "#{path}.rb")
69
- raise "Template not found: #{file}" unless File.exist?(file)
70
-
71
- renderer = Object.new
72
- renderer.extend(Render::Helpers)
73
- locals.each { |k, v| renderer.instance_variable_set(:"@#{k}", v) }
74
-
75
- result = renderer.instance_eval(File.read(file), file)
76
- result.is_a?(String) ? result.freeze : ""
66
+ def render_joy(path,**locals)
67
+ context=Joys.adapter.controller_context(self)
68
+ context.each{|k,v|Thread.current[k]=v}
69
+ result=Joys.render_joy(path,**locals)
70
+ render html:result.html_safe,layout:false
71
+ ensure
72
+ context&.keys&.each{|k|Thread.current[k]=nil}
77
73
  end
78
74
  end
79
75
  end
@@ -92,14 +88,20 @@ module Joys
92
88
  end
93
89
  class << self
94
90
  attr_accessor :adapter,:css_registry
95
- def render_joy(path,**locals)
96
- Joys.reload! if Config.dev?
97
- file=File.join(Config.pages,"#{path}.rb")
98
- raise "Template not found: #{file}" unless File.exist?(file)
99
- locals.each{|k,v|eval("@#{k}=v",binding)}
100
- result=eval(File.read(file),binding,file)
101
- result.is_a?(String) ? result.freeze : ""
102
- end
91
+ def render_joy(path, **locals)
92
+ Joys.reload! if Config.dev?
93
+ file = File.join(Config.pages, "#{path}.rb")
94
+ raise "Template not found: #{file}" unless File.exist?(file)
95
+
96
+ locals.each { |k, v| eval("@#{k} = v", binding) }
97
+
98
+ # Extend the current binding with helpers
99
+ helper_binding = binding
100
+ helper_binding.eval("extend Joys::Render::Helpers")
101
+
102
+ result = eval(File.read(file), helper_binding, file)
103
+ result.is_a?(String) ? result.freeze : ""
104
+ end
103
105
  def preload!;load_helpers;load_dir(Config.layouts);load_dir(Config.components);load_css_parts;end
104
106
  def load_helpers
105
107
  return unless Dir.exist?(Config.helpers)
@@ -129,6 +131,7 @@ module Joys
129
131
  end
130
132
  @adapter&.integrate!
131
133
  end
134
+
132
135
  def reload!;clear_cache!;@css_registry={};preload!;end
133
136
  def load_dir(dir);Dir.exist?(dir)&&Dir.glob("#{dir}/**/*.rb").each{|f|load f};end
134
137
  end
data/lib/joys/core.rb CHANGED
@@ -2,16 +2,10 @@
2
2
  # lib/joys/core.rb
3
3
  module Joys
4
4
  @css_path = "public/css";@cache={};@templates={};@compiled_styles={};@consolidated_cache={};@current_component = nil;@layouts={}
5
+
5
6
  class << self
6
7
  attr_reader :cache, :templates, :compiled_styles, :consolidated_cache, :layouts
7
8
  attr_accessor :current_component, :current_page, :css_path,:adapter,:css_registry
8
- # def load_css_parts
9
- # return unless Dir.exist?(Config.css_parts)
10
- # Dir.glob("#{Config.css_parts}/**/*.css").each do |f|
11
- # relative_path = f.sub("#{Config.css_parts}/", '').sub('.css', '')
12
- # @css_registry[relative_path] = File.read(f).gsub(/\r?\n/, "")
13
- # end
14
- # end
15
9
  end
16
10
  def self.make(name, *args, **kwargs, &block)
17
11
  Joys.define :comp, name, *args, **kwargs, &block
@@ -57,17 +51,31 @@ module Joys
57
51
  result.freeze
58
52
  end
59
53
  else
60
- define_singleton_method(full_name) do |*args|
61
- old_component = @current_component
62
- @current_component = full_name if type == :comp
63
- result = cache(full_name, *args) do
64
- # This call now returns a hash, and the hash will be cached.
65
- Joys::Render.compile(full_name) { instance_exec(*args, &template) }
66
- end
67
- @current_component = old_component
68
- result
54
+ define_singleton_method(full_name) do |*args, **kwargs, &block| # ADD &block here
55
+ old_component = @current_component
56
+ @current_component = full_name
57
+ result = cache(full_name, *args, kwargs.hash, block.object_id) do # Include block in cache key
58
+ # Capture block content if provided
59
+ content = nil
60
+ if block
61
+ capture_renderer = Object.new
62
+ capture_renderer.extend(Render::Helpers)
63
+ capture_renderer.extend(Tags)
64
+ capture_renderer.instance_eval { @bf = String.new(capacity: 8192) }
65
+ capture_renderer.instance_exec(&block)
66
+ content = capture_renderer.instance_variable_get(:@bf)
67
+ end
68
+
69
+ # Compile with content available
70
+ Joys::Render.compile(full_name) do
71
+ @content = content
72
+ instance_exec(*args, **kwargs, &template)
69
73
  end
70
74
  end
75
+ @current_component = old_component
76
+ result
77
+ end
78
+ end
71
79
  end
72
80
  def self.clear_cache!
73
81
  @cache.clear
@@ -95,29 +103,70 @@ module Joys
95
103
  @current_page = old_page
96
104
  renderer.instance_variable_get(:@bf).freeze
97
105
  end
98
- def self.comp(name, *args, **locals, &block)
99
- renderer = Object.new
100
- renderer.extend(Render::Helpers)
101
- renderer.extend(Tags)
102
- locals.each { |k, v| renderer.instance_variable_set("@#{k}", v) }
103
- renderer.instance_eval do
104
- @bf = String.new(capacity: 8192)
105
- @slots = {}
106
- @used_components = Set.new
107
- end
106
+ def self.comp(name, *args, **locals, &block)
107
+ renderer = Object.new
108
+ renderer.extend(Render::Helpers)
109
+ renderer.extend(Tags)
110
+ locals.each { |k, v| renderer.instance_variable_set("@#{k}", v) }
111
+
112
+ # ADD THIS: Set args as instance variables
113
+ args.each_with_index do |arg, i|
114
+ renderer.instance_variable_set("@arg#{i}", arg)
115
+ end
116
+
117
+ renderer.instance_eval do
118
+ @bf = String.new(capacity: 8192)
119
+ @slots = {}
120
+ @used_components = Set.new
121
+ end
122
+
123
+ comp_template = @templates["comp_#{name}"]
124
+ raise "No comp template defined for #{name}" unless comp_template
125
+
126
+ old_component = @current_component
127
+ @current_component = "comp_#{name}"
128
+
129
+ if block
130
+ capture_renderer = Object.new
131
+ capture_renderer.extend(Render::Helpers)
132
+ capture_renderer.extend(Tags)
133
+ capture_renderer.instance_eval { @bf = String.new(capacity: 8192) }
134
+ capture_renderer.instance_exec(&block)
135
+ renderer.instance_variable_set(:@content, capture_renderer.instance_variable_get(:@bf))
136
+ end
137
+
138
+ renderer.instance_exec(*args, &comp_template)
139
+
140
+ @current_component = old_component
141
+
142
+ {
143
+ html: renderer.instance_variable_get(:@bf).freeze,
144
+ components: renderer.instance_variable_get(:@used_components)
145
+ }
146
+ end
147
+ # def self.comp(name, *args, **locals, &block)
148
+ # renderer = Object.new
149
+ # renderer.extend(Render::Helpers)
150
+ # renderer.extend(Tags)
151
+ # locals.each { |k, v| renderer.instance_variable_set("@#{k}", v) }
152
+ # renderer.instance_eval do
153
+ # @bf = String.new(capacity: 8192)
154
+ # @slots = {}
155
+ # @used_components = Set.new
156
+ # end
108
157
 
109
- comp_template = @templates["comp_#{name}"]
110
- raise "No comp template defined for #{name}" unless comp_template
158
+ # comp_template = @templates["comp_#{name}"]
159
+ # raise "No comp template defined for #{name}" unless comp_template
111
160
 
112
- old_component = @current_component
113
- @current_component = "comp_#{name}"
161
+ # old_component = @current_component
162
+ # @current_component = "comp_#{name}"
114
163
 
115
- # Pass the block as a regular argument to the template
116
- renderer.instance_exec(*args, block, &comp_template)
164
+ # # Pass the block as a regular argument to the template
165
+ # renderer.instance_exec(*args, block, &comp_template)
117
166
 
118
- @current_component = old_component
119
- renderer.instance_variable_get(:@bf).freeze
120
- end
167
+ # @current_component = old_component
168
+ # renderer.instance_variable_get(:@bf).freeze
169
+ # end
121
170
  def self.html(&block)
122
171
  # Clear any previous tracking
123
172
  clear_tracked_components
@@ -159,6 +208,7 @@ end
159
208
  template = Object.new;template.extend(Helpers);template.extend(Tags)
160
209
  template.instance_eval { @bf = String.new;@slots={};@used_components = Set.new }
161
210
  template.define_singleton_method(:pull) { |name = :main| @bf << "<!--SLOT:#{name}-->"; nil }
211
+ template.define_singleton_method(:get) { |name| "" }
162
212
  template.instance_eval(&layout_block)
163
213
  precompiled = template.instance_variable_get(:@bf).freeze
164
214
  ->(context, &content_block) {
data/lib/joys/helpers.rb CHANGED
@@ -12,6 +12,10 @@ module Joys
12
12
  content = @bf;@slots[name] = content
13
13
  @bf = old_buffer;nil
14
14
  end
15
+ def get(name)
16
+ @slots ||= {}
17
+ @slots[name].to_s
18
+ end
15
19
  def pull(name = :main)
16
20
  @slots ||= {};@bf << @slots[name].to_s if @slots[name];nil
17
21
  end
data/lib/joys/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Joys
4
- VERSION = "0.1.5"
4
+ VERSION = "0.1.7"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: joys
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Garcia
@@ -29,7 +29,7 @@ files:
29
29
  - joys-0.1.2.gem
30
30
  - joys-0.1.3.gem
31
31
  - joys-0.1.4.gem
32
- - lib/.DS_Store
32
+ - joys-0.1.5.gem
33
33
  - lib/joys.rb
34
34
  - lib/joys/cli.rb
35
35
  - lib/joys/config.rb
data/lib/.DS_Store DELETED
Binary file