toji 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/example/koji_making.ipynb +7 -7
  3. data/example/koji_making.rb +5 -5
  4. data/example/koji_recipe.rb +1 -1
  5. data/example/moromi.ipynb +55 -21
  6. data/example/moromi.rb +5 -5
  7. data/example/rice_recipe.rb +2 -2
  8. data/example/shubo.ipynb +6 -6
  9. data/example/shubo.rb +5 -5
  10. data/example/three_step_mashing_recipe.rb +2 -2
  11. data/lib/toji/brew/base.rb +88 -0
  12. data/lib/toji/brew/builder.rb +27 -0
  13. data/lib/toji/brew/graph/ab.rb +85 -0
  14. data/lib/toji/brew/graph/bmd.rb +58 -0
  15. data/lib/toji/brew/graph/progress.rb +142 -0
  16. data/lib/toji/brew/graph.rb +10 -0
  17. data/lib/toji/{product/koji_making.rb → brew/koji.rb} +35 -43
  18. data/lib/toji/{product → brew}/moromi.rb +105 -96
  19. data/lib/toji/brew/shubo.rb +122 -0
  20. data/lib/toji/brew/state.rb +117 -0
  21. data/lib/toji/{product/job_accessor.rb → brew/state_accessor.rb} +4 -4
  22. data/lib/toji/brew/state_record.rb +82 -0
  23. data/lib/toji/brew.rb +21 -0
  24. data/lib/toji/recipe/ingredient/koji/actual.rb +23 -0
  25. data/lib/toji/recipe/ingredient/koji/actual_fermentable.rb +17 -0
  26. data/lib/toji/recipe/ingredient/koji/base.rb +28 -0
  27. data/lib/toji/recipe/ingredient/koji/expected.rb +53 -0
  28. data/lib/toji/recipe/ingredient/koji/expected_fermentable.rb +17 -0
  29. data/lib/toji/recipe/ingredient/koji.rb +21 -0
  30. data/lib/toji/recipe/ingredient/lactic_acid.rb +21 -0
  31. data/lib/toji/recipe/ingredient/rice/actual.rb +20 -0
  32. data/lib/toji/recipe/ingredient/rice/actual_steamable.rb +29 -0
  33. data/lib/toji/recipe/ingredient/rice/base.rb +42 -0
  34. data/lib/toji/recipe/ingredient/rice/expected.rb +48 -0
  35. data/lib/toji/recipe/ingredient/rice/expected_steamable.rb +31 -0
  36. data/lib/toji/recipe/ingredient/rice.rb +21 -0
  37. data/lib/toji/recipe/ingredient/yeast.rb +21 -0
  38. data/lib/toji/recipe/ingredient.rb +11 -0
  39. data/lib/toji/recipe/lactic_acid_rate.rb +17 -0
  40. data/lib/toji/recipe/three_step_mashing.rb +4 -2
  41. data/lib/toji/recipe/yeast_rate.rb +41 -0
  42. data/lib/toji/recipe.rb +3 -0
  43. data/lib/toji/version.rb +1 -1
  44. data/lib/toji.rb +1 -3
  45. metadata +32 -29
  46. data/lib/toji/graph/ab.rb +0 -79
  47. data/lib/toji/graph/bmd.rb +0 -56
  48. data/lib/toji/graph/progress.rb +0 -87
  49. data/lib/toji/graph.rb +0 -8
  50. data/lib/toji/ingredient/koji/actual.rb +0 -21
  51. data/lib/toji/ingredient/koji/actual_fermentable.rb +0 -15
  52. data/lib/toji/ingredient/koji/base.rb +0 -26
  53. data/lib/toji/ingredient/koji/expected.rb +0 -51
  54. data/lib/toji/ingredient/koji/expected_fermentable.rb +0 -15
  55. data/lib/toji/ingredient/koji.rb +0 -19
  56. data/lib/toji/ingredient/rice/actual.rb +0 -18
  57. data/lib/toji/ingredient/rice/actual_steamable.rb +0 -27
  58. data/lib/toji/ingredient/rice/base.rb +0 -40
  59. data/lib/toji/ingredient/rice/expected.rb +0 -46
  60. data/lib/toji/ingredient/rice/expected_steamable.rb +0 -29
  61. data/lib/toji/ingredient/rice.rb +0 -19
  62. data/lib/toji/ingredient/yeast/base.rb +0 -21
  63. data/lib/toji/ingredient/yeast/red_star.rb +0 -30
  64. data/lib/toji/ingredient/yeast.rb +0 -9
  65. data/lib/toji/ingredient.rb +0 -8
  66. data/lib/toji/product/base.rb +0 -74
  67. data/lib/toji/product/job.rb +0 -176
  68. data/lib/toji/product/shubo.rb +0 -130
  69. data/lib/toji/product.rb +0 -11
@@ -1,221 +1,230 @@
1
1
  module Toji
2
- module Product
2
+ module Brew
3
3
  class Moromi < Base
4
4
 
5
5
  TEMPLATES = {
6
6
  default: [
7
- Job.new(
7
+ {
8
8
  time: Time.mktime(2019, 1, 16),
9
- id: :soe,
9
+ mark: :soe,
10
10
  room_temp: 9,
11
11
  temps: [14.8, 11.0],
12
- ),
13
- Job.new(
12
+ },
13
+ {
14
14
  time: Time.mktime(2019, 1, 17),
15
15
  room_temp: 9,
16
16
  temps: 14.3,
17
- ),
18
- Job.new(
17
+ },
18
+ {
19
19
  time: Time.mktime(2019, 1, 18),
20
20
  room_temp: 8.5,
21
21
  temps: 11.3,
22
- ),
23
- Job.new(
22
+ },
23
+ {
24
24
  time: Time.mktime(2019, 1, 19),
25
- id: :naka,
25
+ mark: :naka,
26
26
  room_temp: 9,
27
27
  temps: [6.9, 10.6],
28
- ),
29
- Job.new(
28
+ },
29
+ {
30
30
  time: Time.mktime(2019, 1, 20),
31
- id: :tome,
31
+ mark: :tome,
32
32
  room_temp: 6,
33
33
  temps: [7.5, 8.0],
34
- ),
35
- Job.new(
34
+ },
35
+ {
36
36
  time: Time.mktime(2019, 1, 21),
37
37
  room_temp: 7,
38
38
  temps: 9.1,
39
- ),
40
- Job.new(
39
+ },
40
+ {
41
41
  time: Time.mktime(2019, 1, 22),
42
42
  room_temp: 7,
43
43
  temps: 10.4,
44
- ),
45
- Job.new(
44
+ },
45
+ {
46
46
  time: Time.mktime(2019, 1, 23),
47
47
  room_temp: 8,
48
48
  temps: 11.9,
49
49
  baume: 8.6,
50
- ),
51
- Job.new(
50
+ },
51
+ {
52
52
  time: Time.mktime(2019, 1, 24),
53
53
  room_temp: 8,
54
54
  temps: 12.3,
55
55
  baume: 8.0,
56
56
  alcohol: 4.8,
57
- ),
58
- Job.new(
57
+ },
58
+ {
59
59
  time: Time.mktime(2019, 1, 25),
60
60
  room_temp: 7.5,
61
61
  temps: 13.1,
62
62
  baume: 7.2,
63
63
  alcohol: 6.75,
64
- ),
65
- Job.new(
64
+ },
65
+ {
66
66
  time: Time.mktime(2019, 1, 26),
67
67
  room_temp: 7.5,
68
68
  temps: 13.1,
69
69
  baume: 5.8,
70
70
  alcohol: 7.992,
71
- ),
72
- Job.new(
71
+ },
72
+ {
73
73
  time: Time.mktime(2019, 1, 27),
74
74
  room_temp: 7.5,
75
75
  temps: 12.9,
76
76
  baume: 4.8,
77
- ),
78
- Job.new(
77
+ },
78
+ {
79
79
  time: Time.mktime(2019, 1, 28),
80
80
  room_temp: 7.0,
81
81
  temps: 12.8,
82
82
  baume: 4.0,
83
83
  alcohol: 10.7,
84
- ),
85
- Job.new(
84
+ },
85
+ {
86
86
  time: Time.mktime(2019, 1, 29),
87
87
  room_temp: 8.0,
88
88
  temps: 12.9,
89
89
  baume: 3.4,
90
90
  alcohol: 11.6,
91
- ),
92
- Job.new(
91
+ },
92
+ {
93
93
  time: Time.mktime(2019, 1, 30),
94
94
  room_temp: 8.0,
95
95
  temps: 12.6,
96
96
  nihonshudo: -27,
97
97
  alcohol: 12.7,
98
- ),
99
- Job.new(
98
+ },
99
+ {
100
100
  time: Time.mktime(2019, 1, 31),
101
101
  room_temp: 7.0,
102
102
  temps: 12.0,
103
103
  nihonshudo: -21,
104
104
  alcohol: 13.7,
105
- ),
106
- Job.new(
105
+ },
106
+ {
107
107
  time: Time.mktime(2019, 2, 1),
108
108
  room_temp: 7.0,
109
109
  temps: 11.2,
110
110
  nihonshudo: -17,
111
- ),
112
- Job.new(
111
+ },
112
+ {
113
113
  time: Time.mktime(2019, 2, 2),
114
114
  room_temp: 6.5,
115
115
  temps: 10.2,
116
116
  nihonshudo: -13,
117
- ),
118
- Job.new(
117
+ },
118
+ {
119
119
  time: Time.mktime(2019, 2, 3),
120
120
  room_temp: 7.0,
121
121
  temps: 9.7,
122
- ),
123
- Job.new(
122
+ },
123
+ {
124
124
  time: Time.mktime(2019, 2, 4),
125
125
  room_temp: 8.0,
126
126
  temps: 9.8,
127
127
  nihonshudo: -8,
128
128
  alcohol: 16.0,
129
- ),
130
- Job.new(
129
+ },
130
+ {
131
131
  time: Time.mktime(2019, 2, 5),
132
132
  room_temp: 6.0,
133
133
  temps: 9.1,
134
134
  nihonshudo: -5,
135
- ),
136
- Job.new(
135
+ },
136
+ {
137
137
  time: Time.mktime(2019, 2, 6),
138
138
  room_temp: 5.0,
139
139
  temps: 8.4,
140
140
  nihonshudo: -3,
141
141
  alcohol: 16.3,
142
- ),
143
- Job.new(
142
+ },
143
+ {
144
144
  time: Time.mktime(2019, 2, 7),
145
145
  room_temp: 5.0,
146
146
  temps: 8.1,
147
147
  nihonshudo: -2,
148
- ),
149
- Job.new(
148
+ },
149
+ {
150
150
  time: Time.mktime(2019, 2, 8),
151
151
  room_temp: 7.0,
152
152
  temps: 8.3,
153
153
  nihonshudo: 0,
154
- ),
155
- Job.new(
154
+ },
155
+ {
156
156
  time: Time.mktime(2019, 2, 9),
157
157
  room_temp: 6.0,
158
158
  temps: 8.1,
159
- ),
159
+ },
160
160
  ],
161
161
  }
162
162
 
163
+ DAY_LABELS = {
164
+ default: [:soe, :odori, :naka, :tome].freeze,
165
+ moto1: [:moto, :soe, :odori, :naka, :tome].freeze,
166
+ odori2: [:soe, :odori, :odori, :naka, :tome].freeze,
167
+ }.freeze
163
168
 
164
- job_reader :moto
165
- job_reader :soe
166
- job_reader :naka
167
- job_reader :tome
169
+ state_reader :moto
170
+ state_reader :soe
171
+ state_reader :naka
172
+ state_reader :tome
173
+ state_reader :yodan
168
174
 
169
- def initialize(jobs=[], date_line: 0, day_labels: nil)
170
- super(jobs, date_line: date_line)
175
+ attr_writer :prefix_day_labels
171
176
 
172
- if day_labels
173
- @day_labels = [day_labels].flatten
174
- end
175
- end
176
-
177
- def moromi_days
178
- if @day_labels
179
- days - @day_labels.length
180
- else
181
- tome = self[:tome]
182
- if tome
183
- tome_day = (tome.elapsed_time.to_f / Job::DAY).floor + 1
184
- days - tome_day
185
- end
186
- end
187
- end
188
-
189
- def day_labels
190
- if @day_labels
191
- @day_labels + moromi_days.times.map{|i| i+2}
177
+ def prefix_day_labels
178
+ if @prefix_day_labels
179
+ @prefix_day_labels
180
+ elsif !self[:soe] && !self[:tome]
181
+ nil
192
182
  else
193
- texts = Array.new(days)
194
- [:soe, :naka, :tome].each {|id|
195
- j = select{|j| j.id==id}.first
196
- if j
197
- i = ((j.elapsed_time + day_offset) / Job::DAY.to_f).floor
198
- texts[i] = id
183
+ labels = []
184
+ [:soe, :naka, :tome].each {|mark|
185
+ s = self[mark]
186
+ if s
187
+ i = s.day - 1
188
+ labels[i] = mark
199
189
  end
200
190
  }
201
191
 
202
- soe_i = texts.index(:soe)
203
- tome_i = texts.index(:tome)
204
- moromi_day = 1
205
- texts.map.with_index {|text,i|
206
- if text
207
- text
192
+ soe_i = labels.index(:soe)
193
+ labels.map.with_index {|label,i|
194
+ if label
195
+ label
208
196
  elsif !soe_i || i<soe_i
209
197
  :moto
210
- elsif !tome_i || i<tome_i
211
- :odori
212
198
  else
213
- moromi_day += 1
199
+ :odori
214
200
  end
215
201
  }
216
202
  end
217
203
  end
218
204
 
205
+ def moromi_tome_day
206
+ prefix_day_labels&.length
207
+ end
208
+
209
+ def moromi_days
210
+ _tome_day = moromi_tome_day
211
+ _days = self.days
212
+
213
+ if _tome_day && _tome_day<_days
214
+ _days - _tome_day + 1
215
+ end
216
+ end
217
+
218
+ def day_labels
219
+ _prefix = prefix_day_labels
220
+
221
+ if _prefix
222
+ _prefix + moromi_days.times.map{|i| i+2}
223
+ else
224
+ self.days.times.map{|i| i+1}
225
+ end
226
+ end
227
+
219
228
  def progress(enable_annotations: true)
220
229
  Graph::Progress.new(self, enable_annotations: enable_annotations)
221
230
  end
@@ -229,7 +238,7 @@ module Toji
229
238
  end
230
239
 
231
240
  def self.template(key=:default)
232
- new(TEMPLATES[key])
241
+ create(TEMPLATES[key])
233
242
  end
234
243
  end
235
244
  end
@@ -0,0 +1,122 @@
1
+ module Toji
2
+ module Brew
3
+ class Shubo < Base
4
+
5
+ TEMPLATES = {
6
+ default: [
7
+ {
8
+ elapsed_time: 0 * Brew::DAY,
9
+ mark: :mizukoji,
10
+ temps: 12.0,
11
+ acid: 13.0,
12
+ },
13
+ {
14
+ elapsed_time: 0 * Brew::DAY + 1 * Brew::HOUR,
15
+ mark: :shikomi,
16
+ temps: 20.0,
17
+ acid: 13.0,
18
+ },
19
+ {
20
+ elapsed_time: 1 * Brew::DAY,
21
+ mark: :utase,
22
+ temps: 14.0,
23
+ baume: 15.0,
24
+ acid: 13.0,
25
+ },
26
+ {
27
+ elapsed_time: 2 * Brew::DAY,
28
+ temps: [8.0, 11.0],
29
+ baume: 16.0,
30
+ acid: 13.0,
31
+ warming: WARM_DAKI,
32
+ },
33
+ {
34
+ elapsed_time: 3 * Brew::DAY,
35
+ temps: [10.0, 13.0],
36
+ baume: 16.5,
37
+ acid: 13.5,
38
+ warming: WARM_DAKI,
39
+ },
40
+ {
41
+ elapsed_time: 4 * Brew::DAY,
42
+ temps: [12.0, 15.0],
43
+ baume: 17.0,
44
+ acid: 13.5,
45
+ warming: WARM_DAKI,
46
+ },
47
+ {
48
+ elapsed_time: 5 * Brew::DAY,
49
+ temps: 14.0,
50
+ baume: 17.0,
51
+ acid: 14.0,
52
+ warming: WARM_ANKA,
53
+ },
54
+ {
55
+ elapsed_time: 6 * Brew::DAY,
56
+ temps: 20.0,
57
+ baume: 17.0,
58
+ acid: 14.5,
59
+ warming: WARM_ANKA,
60
+ },
61
+ {
62
+ elapsed_time: 7 * Brew::DAY,
63
+ temps: 20.0,
64
+ baume: 14.0,
65
+ acid: 15.5,
66
+ },
67
+ {
68
+ elapsed_time: 8 * Brew::DAY,
69
+ temps: 20.0,
70
+ baume: 12.0,
71
+ acid: 16.0,
72
+ },
73
+ {
74
+ elapsed_time: 9 * Brew::DAY,
75
+ mark: :wake,
76
+ temps: 20.0,
77
+ baume: 9.0,
78
+ acid: 16.0,
79
+ },
80
+ {
81
+ elapsed_time: 10 * Brew::DAY,
82
+ temps: 15.0,
83
+ baume: 8.0,
84
+ acid: 16.5,
85
+ },
86
+ {
87
+ elapsed_time: 11 * Brew::DAY,
88
+ temps: 12.0,
89
+ baume: 7.0,
90
+ acid: 17.0,
91
+ },
92
+ {
93
+ elapsed_time: 12 * Brew::DAY,
94
+ temps: 10.0,
95
+ baume: 6.0,
96
+ acid: 17.5,
97
+ },
98
+ {
99
+ elapsed_time: 13 * Brew::DAY,
100
+ temps: 9.0,
101
+ baume: 5.0,
102
+ acid: 17.5,
103
+ },
104
+ ],
105
+ }
106
+
107
+
108
+ state_reader :mizukoji
109
+ state_reader :shikomi
110
+ state_reader :utase
111
+ state_reader :wake
112
+
113
+ def progress(enable_annotations: true)
114
+ Graph::Progress.new(self, enable_annotations: enable_annotations)
115
+ end
116
+
117
+ def self.template(key=:default)
118
+ create(TEMPLATES[key])
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,117 @@
1
+ require 'forwardable'
2
+
3
+ module Toji
4
+ module Brew
5
+ class State
6
+ extend Forwardable
7
+
8
+ attr_accessor :elapsed_time
9
+ attr_accessor :time
10
+ attr_accessor :day_label
11
+ attr_reader :record
12
+ attr_reader :brew
13
+
14
+ def_delegators :@record, :mark
15
+ def_delegators :@record, :temps
16
+ def_delegators :@record, :preset_temp
17
+ def_delegators :@record, :room_temp
18
+ def_delegators :@record, :room_psychrometry
19
+ def_delegators :@record, :acid
20
+ def_delegators :@record, :amino_acid
21
+ def_delegators :@record, :alcohol
22
+ def_delegators :@record, :warming
23
+ def_delegators :@record, :warmings
24
+ def_delegators :@record, :note
25
+
26
+ def_delegators :@record, :has_keys
27
+
28
+ def initialize(elapsed_time, record, brew)
29
+ @elapsed_time = elapsed_time
30
+ @record = record
31
+ @brew = brew
32
+ end
33
+
34
+ def has_keys
35
+ result = [:elapsed_time, :time, :day, :day_label, :display_time]
36
+ keys = [:moromi_day, :display_baume, :bmd] + StateRecord::KEYS
37
+
38
+ result += keys.select {|k|
39
+ !!send(k)
40
+ }
41
+ end
42
+
43
+ def day
44
+ ((elapsed_time_with_offset.to_f + 1) / DAY).ceil
45
+ end
46
+
47
+ def day_label
48
+ @brew.day_labels[day - 1]
49
+ end
50
+
51
+ def elapsed_time_with_offset
52
+ @elapsed_time + @brew.day_offset
53
+ end
54
+
55
+ def baume
56
+ if @record.baume
57
+ @record.baume
58
+ elsif @record.nihonshudo
59
+ @record.nihonshudo * -0.1
60
+ end
61
+ end
62
+
63
+ def nihonshudo
64
+ if @record.nihonshudo
65
+ @record.nihonshudo
66
+ elsif @record.baume
67
+ @record.baume * -10
68
+ end
69
+ end
70
+
71
+ def display_baume
72
+ if @record.baume || @record.nihonshudo
73
+ b = baume
74
+ if b<3.0
75
+ nihonshudo
76
+ else
77
+ b
78
+ end
79
+ end
80
+ end
81
+
82
+ def display_time(format="%m/%d %H:%M")
83
+ if @time
84
+ @time.strftime(format)
85
+ else
86
+ Time.at(@elapsed_time).strftime(format)
87
+ end
88
+ end
89
+
90
+ def moromi_day
91
+ _tome_day = @brew.moromi_tome_day
92
+ _now_day = day
93
+
94
+ if _tome_day && _tome_day < _now_day
95
+ _now_day - _tome_day + 1
96
+ end
97
+ end
98
+
99
+ def bmd
100
+ _moromi_day = moromi_day
101
+ _baume = baume
102
+
103
+ if _moromi_day && _baume
104
+ _moromi_day * _baume
105
+ end
106
+ end
107
+
108
+ def expected_alcohol(target_alc, target_nihonshudo, coef)
109
+ _baume = baume
110
+
111
+ if _baume
112
+ target_alc - (_baume - target_nihonshudo * -0.1) * coef
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -1,10 +1,10 @@
1
1
  module Toji
2
- module Product
3
- module JobAccessor
4
- def job_reader(*args)
2
+ module Brew
3
+ module StateAccessor
4
+ def state_reader(*args)
5
5
  args.each {|arg|
6
6
  define_method(arg) {
7
- self[arg]
7
+ @data[arg]
8
8
  }
9
9
  }
10
10
  end
@@ -0,0 +1,82 @@
1
+ module Toji
2
+ module Brew
3
+ class StateRecord
4
+ KEYS = [
5
+ :time,
6
+ :elapsed_time,
7
+ :mark,
8
+ :temps,
9
+ :preset_temp,
10
+ :room_temp,
11
+ :room_psychrometry,
12
+ :baume,
13
+ :nihonshudo,
14
+ :acid,
15
+ :amino_acid,
16
+ :alcohol,
17
+ :warming,
18
+ :note,
19
+ ].freeze
20
+
21
+ RO_KEYS = [
22
+ :warmings,
23
+ ].freeze
24
+
25
+ attr_accessor :time
26
+ attr_accessor :elapsed_time
27
+ attr_accessor :mark
28
+ attr_accessor :temps
29
+
30
+ attr_accessor :preset_temp
31
+ attr_accessor :room_temp
32
+ attr_accessor :room_psychrometry
33
+
34
+ attr_accessor :baume
35
+ attr_accessor :nihonshudo
36
+ attr_accessor :acid
37
+ attr_accessor :amino_acid
38
+ attr_accessor :alcohol
39
+
40
+ attr_accessor :warming
41
+ attr_accessor :note
42
+
43
+ def temps=(val)
44
+ @temps = [val].flatten.select{|t| t}
45
+ end
46
+
47
+ def warmings
48
+ result = []
49
+ if @warming & WARM_DAKI
50
+ result << :daki
51
+ end
52
+ if @warming & WARM_ANKA
53
+ result << :anka
54
+ end
55
+ if @warming & WARM_MAT
56
+ result << :mat
57
+ end
58
+ result
59
+ end
60
+
61
+ def self.create(r)
62
+ if StateRecord===r
63
+ r
64
+ elsif State==r
65
+ r.record
66
+ elsif Hash===r
67
+ record = new
68
+ KEYS.each {|k|
69
+ record.send("#{k}=", r[k])
70
+ }
71
+ record
72
+ else
73
+ record = new
74
+ KEYS.each {|k|
75
+ record.send("#{k}=", r.send(k))
76
+ }
77
+ record
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
data/lib/toji/brew.rb ADDED
@@ -0,0 +1,21 @@
1
+ module Toji
2
+ module Brew
3
+ HOUR = 60 * 60
4
+ DAY = 24 * HOUR
5
+
6
+ WARM_DAKI = 1
7
+ WARM_ANKA = 1<<1
8
+ WARM_MAT = 1<<2
9
+ end
10
+ end
11
+
12
+ require 'toji/brew/state_accessor'
13
+ require 'toji/brew/base'
14
+ require 'toji/brew/state'
15
+ require 'toji/brew/state_record'
16
+ require 'toji/brew/builder'
17
+ require 'toji/brew/graph'
18
+
19
+ require 'toji/brew/koji'
20
+ require 'toji/brew/shubo'
21
+ require 'toji/brew/moromi'