modsmith 0.6.2 → 0.7.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.
Files changed (39) hide show
  1. package/AGENTS.md +6 -0
  2. package/README.md +131 -20
  3. package/bin/modsmith.mjs +573 -405
  4. package/docs/conformance/README.md +62 -0
  5. package/docs/conformance/farmers-delight-1.21.1-3.3.6.json +209 -0
  6. package/docs/conformance/farmers-delight-dev-live.json +321 -0
  7. package/docs/conformance/moredelight-26.04.30-1.21.json +47 -0
  8. package/docs/conformance/supplementaries-1.21.1-4.0.2.json +227 -0
  9. package/docs/conformance/twilightforest-1.21.1-4.8.796.json +317 -0
  10. package/package.json +16 -3
  11. package/schema/manifest.schema.json +7 -0
  12. package/sidesheets/farmers-delight-3.3.6.crops.json +42 -42
  13. package/src/block-shapes.mjs +176 -0
  14. package/src/calibrate.mjs +1 -0
  15. package/src/conformance-live.mjs +208 -0
  16. package/src/conformance.mjs +366 -0
  17. package/src/cortico-bridge.mjs +397 -325
  18. package/src/crops.mjs +246 -227
  19. package/src/import-dump.mjs +139 -0
  20. package/src/index.mjs +3 -1
  21. package/src/inspect.mjs +466 -461
  22. package/src/manifest-io.mjs +1 -1
  23. package/src/onboard.mjs +21 -3
  24. package/src/probe.mjs +325 -316
  25. package/src/rcon.mjs +14 -8
  26. package/src/server-fingerprint.mjs +5 -5
  27. package/src/stations.mjs +22 -1
  28. package/src/validate.mjs +231 -223
  29. package/src/verify.mjs +18 -10
  30. package/templates/reference-bot/README.md +22 -0
  31. package/templates/reference-bot/index.mjs +59 -0
  32. package/templates/registry-dump/README.md +48 -0
  33. package/templates/registry-dump/build.gradle +39 -0
  34. package/templates/registry-dump/gradle.properties +2 -0
  35. package/templates/registry-dump/modsmith-dump-0.1.2.jar +0 -0
  36. package/templates/registry-dump/settings.gradle +9 -0
  37. package/templates/registry-dump/src/main/java/dev/modsmith/dump/RegistryDumpMod.java +98 -0
  38. package/templates/registry-dump/src/main/resources/fabric.mod.json +18 -0
  39. package/types/index.d.ts +174 -135
@@ -0,0 +1,62 @@
1
+ # conformance 报告 · 2026-10-29
2
+
3
+ 四个生产包在 `modsmith conformance` 下的离线体检结果(`--server-mods` 对上了同一份服务器指纹)。
4
+ 报告是当时的机器产物,JSON 里每条都有 `id / level / subject / message`。
5
+
6
+ | 包 | 通过 | 警告 | 失败 | 警告说明 |
7
+ |---|---:|---:|---:|---|
8
+ | Farmer's Delight 3.3.6 | 31 | 2 | 0 | 自定义配方类型(无统一 result) |
9
+ | More Delight | 4 | 2 | 0 | manifest 没写 prompt;自定义配方 |
10
+ | Supplementaries 4.0.2 | 16 | 20 | 0 | 自定义序列化器(2 条作物 alias 的 seed 指向自名) |
11
+ | Twilight Forest 4.8.796 | 38 | 13 | 0 | travellers gear / scepter / uncrafting 等自定义配方;manifest 没写 prompt |
12
+
13
+ **这些警告不是失败**:`craftRecipeViews` 只消费 shaped/shapeless 等标准形状;自定义
14
+ 序列化器由 sidesheet/discover 管线处理,不会伪装成“能做”。真正会让机器人做错事的
15
+ 项(假空气、楼梯形状、作物可挖、实体/boss)都是 0 fail。
16
+
17
+ 复跑:
18
+
19
+ ```bash
20
+ modsmith conformance mods/<pack>.json --ids mods/<pack>-ids.json \
21
+ --server-mods mods --json docs/conformance/<pack>.json
22
+ ```
23
+
24
+ 只读 live 复核(需要服务器,不写世界):
25
+
26
+ ```bash
27
+ modsmith conformance mods/twilightforest-1.21.1-4.8.796.json \
28
+ --ids mods/twilightforest-1.21.1-4.8.796-ids.json \
29
+ --server-mods mods --live
30
+ ```
31
+
32
+ 2026-10-29 实跑结果:`通过 73,警告 13,失败 0`;`ModConform @ 1.21.1 overworld`,
33
+ 注册表 523 方块 / 80 实体。
34
+
35
+ ### 写世界采样(RCON,仅测试服)
36
+
37
+ `--rcon-password` 给了才启用:在 `--x/--y/--z` 附近 forceload、setblock、tp,读真实
38
+ bot 的 `blockAt().shapes`,再还原空气。它补的是离线注入检查看不到的那一层——
39
+ “注册表里形状非空”不等于“客户端真的按这个状态显示”。
40
+
41
+ ```bash
42
+ modsmith conformance mods/<pack>.json --ids mods/<pack>-ids.json \
43
+ --server-mods mods --live --port 25566 \
44
+ --rcon-port 25576 --rcon-password <pw> --x 400 --y 100 --z 400
45
+ ```
46
+
47
+ dev 服(FD 3.3.6,2026-10-29)实跑:`通过 40,警告 9,失败 0`,报告见
48
+ [farmers-delight-dev-live.json](farmers-delight-dev-live.json)。采样覆盖 7 个整块 +
49
+ 1 个实体(FD 没有楼梯/台阶)。
50
+
51
+ 同一套采样在 Supplementaries dev 包上验证了上下两态(报告未归档,因为该包没有走
52
+ 完整 onboard,未注册方块会正常报 R1 fail):
53
+
54
+ - `ash_bricks_stairs`:stairs bottom / top 各 `shape 2`,两态形状不同
55
+ - `ash_bricks_slab`:slab bottom / top 各 `shape 1`,两态形状不同
56
+ - 采样会先等 `blockAt().stateId` 进入 `ids` 里对应 `half` / `type` 的集合再读 shape;
57
+ 只等固定 250ms 会把上一态读成当前态,误报“上下相同”
58
+
59
+ 这次采样抓到一个真实的 P0:`templateShapeId` 把状态索引算成了“第一个属性最快变化”,
60
+ 而 registry 实际是**最后一个属性最快**。结果 `oak_slab` 的 top 拿到下半砖形状、bottom
61
+ 拿到上半砖形状(楼梯同理),且 shape 非空,所有只查非空的检查都放过了。已修复并有
62
+ `test/block-shapes.test.mjs` 的索引顺序回归。
@@ -0,0 +1,209 @@
1
+ {
2
+ "pack": "farmersdelight",
3
+ "summary": {
4
+ "pass": 31,
5
+ "warn": 2,
6
+ "fail": 0,
7
+ "total": 33
8
+ },
9
+ "checks": [
10
+ {
11
+ "id": "M1",
12
+ "level": "pass",
13
+ "subject": "manifest",
14
+ "message": "schema/validate 通过"
15
+ },
16
+ {
17
+ "id": "M6",
18
+ "level": "warn",
19
+ "subject": "farmersdelight:cutting",
20
+ "message": "105 条自定义配方没有统一 result,配方视图不会消费(首条 farmersdelight:cutting/beef)"
21
+ },
22
+ {
23
+ "id": "M6",
24
+ "level": "warn",
25
+ "subject": "smithing_trim",
26
+ "message": "18 条自定义配方没有统一 result,配方视图不会消费(首条 minecraft:sentry_armor_trim_smithing_template_smithing_trim)"
27
+ },
28
+ {
29
+ "id": "M6",
30
+ "level": "pass",
31
+ "subject": "recipes",
32
+ "message": "craftRecipeViews 1027 条"
33
+ },
34
+ {
35
+ "id": "I5",
36
+ "level": "pass",
37
+ "subject": "server-mods",
38
+ "message": "服务器 mods 指纹对得上(7 个文件)"
39
+ },
40
+ {
41
+ "id": "R4",
42
+ "level": "pass",
43
+ "subject": "farmersdelight:beetroot_crate",
44
+ "message": "作物可挖"
45
+ },
46
+ {
47
+ "id": "R4",
48
+ "level": "pass",
49
+ "subject": "farmersdelight:budding_tomatoes",
50
+ "message": "作物可挖"
51
+ },
52
+ {
53
+ "id": "R4",
54
+ "level": "pass",
55
+ "subject": "farmersdelight:cabbage_crate",
56
+ "message": "作物可挖"
57
+ },
58
+ {
59
+ "id": "R4",
60
+ "level": "pass",
61
+ "subject": "farmersdelight:cabbages",
62
+ "message": "作物可挖"
63
+ },
64
+ {
65
+ "id": "R4",
66
+ "level": "pass",
67
+ "subject": "farmersdelight:carrot_crate",
68
+ "message": "作物可挖"
69
+ },
70
+ {
71
+ "id": "R4",
72
+ "level": "pass",
73
+ "subject": "farmersdelight:onion_crate",
74
+ "message": "作物可挖"
75
+ },
76
+ {
77
+ "id": "R4",
78
+ "level": "pass",
79
+ "subject": "farmersdelight:onions",
80
+ "message": "作物可挖"
81
+ },
82
+ {
83
+ "id": "R4",
84
+ "level": "pass",
85
+ "subject": "farmersdelight:potato_crate",
86
+ "message": "作物可挖"
87
+ },
88
+ {
89
+ "id": "R4",
90
+ "level": "pass",
91
+ "subject": "farmersdelight:pumpkin_pie",
92
+ "message": "作物可挖"
93
+ },
94
+ {
95
+ "id": "R4",
96
+ "level": "pass",
97
+ "subject": "farmersdelight:rice",
98
+ "message": "作物可挖"
99
+ },
100
+ {
101
+ "id": "R4",
102
+ "level": "pass",
103
+ "subject": "farmersdelight:rice_bag",
104
+ "message": "作物可挖"
105
+ },
106
+ {
107
+ "id": "R4",
108
+ "level": "pass",
109
+ "subject": "farmersdelight:rice_bale",
110
+ "message": "作物可挖"
111
+ },
112
+ {
113
+ "id": "R4",
114
+ "level": "pass",
115
+ "subject": "farmersdelight:rice_panicles",
116
+ "message": "作物可挖"
117
+ },
118
+ {
119
+ "id": "R4",
120
+ "level": "pass",
121
+ "subject": "farmersdelight:rice_roll_medley_block",
122
+ "message": "作物可挖"
123
+ },
124
+ {
125
+ "id": "R4",
126
+ "level": "pass",
127
+ "subject": "farmersdelight:stuffed_pumpkin_block",
128
+ "message": "作物可挖"
129
+ },
130
+ {
131
+ "id": "R4",
132
+ "level": "pass",
133
+ "subject": "farmersdelight:sweet_berry_cheesecake",
134
+ "message": "作物可挖"
135
+ },
136
+ {
137
+ "id": "R4",
138
+ "level": "pass",
139
+ "subject": "farmersdelight:tomato_crate",
140
+ "message": "作物可挖"
141
+ },
142
+ {
143
+ "id": "R4",
144
+ "level": "pass",
145
+ "subject": "farmersdelight:tomatoes",
146
+ "message": "作物可挖"
147
+ },
148
+ {
149
+ "id": "R4",
150
+ "level": "pass",
151
+ "subject": "farmersdelight:tomatoes_on_rope",
152
+ "message": "作物可挖"
153
+ },
154
+ {
155
+ "id": "R4",
156
+ "level": "pass",
157
+ "subject": "farmersdelight:wild_beetroots",
158
+ "message": "作物可挖"
159
+ },
160
+ {
161
+ "id": "R4",
162
+ "level": "pass",
163
+ "subject": "farmersdelight:wild_cabbages",
164
+ "message": "作物可挖"
165
+ },
166
+ {
167
+ "id": "R4",
168
+ "level": "pass",
169
+ "subject": "farmersdelight:wild_carrots",
170
+ "message": "作物可挖"
171
+ },
172
+ {
173
+ "id": "R4",
174
+ "level": "pass",
175
+ "subject": "farmersdelight:wild_onions",
176
+ "message": "作物可挖"
177
+ },
178
+ {
179
+ "id": "R4",
180
+ "level": "pass",
181
+ "subject": "farmersdelight:wild_potatoes",
182
+ "message": "作物可挖"
183
+ },
184
+ {
185
+ "id": "R4",
186
+ "level": "pass",
187
+ "subject": "farmersdelight:wild_rice",
188
+ "message": "作物可挖"
189
+ },
190
+ {
191
+ "id": "R4",
192
+ "level": "pass",
193
+ "subject": "farmersdelight:wild_tomatoes",
194
+ "message": "作物可挖"
195
+ },
196
+ {
197
+ "id": "R6",
198
+ "level": "pass",
199
+ "subject": "recipes",
200
+ "message": "1027 条可消费配方"
201
+ },
202
+ {
203
+ "id": "R7",
204
+ "level": "pass",
205
+ "subject": "entities",
206
+ "message": "1 个实体已注入"
207
+ }
208
+ ]
209
+ }
@@ -0,0 +1,321 @@
1
+ {
2
+ "pack": "farmersdelight",
3
+ "summary": {
4
+ "pass": 40,
5
+ "warn": 9,
6
+ "fail": 0,
7
+ "total": 49
8
+ },
9
+ "checks": [
10
+ {
11
+ "id": "M1",
12
+ "level": "pass",
13
+ "subject": "manifest",
14
+ "message": "schema/validate 通过"
15
+ },
16
+ {
17
+ "id": "M1.warn",
18
+ "level": "warn",
19
+ "subject": "prompt",
20
+ "message": "没有 prompt:提示词里只会写「装了 X」"
21
+ },
22
+ {
23
+ "id": "M5",
24
+ "level": "warn",
25
+ "subject": "onions",
26
+ "message": "seed farmersdelight:onions 不在 items 里"
27
+ },
28
+ {
29
+ "id": "M5",
30
+ "level": "warn",
31
+ "subject": "cabbages",
32
+ "message": "seed farmersdelight:cabbages 不在 items 里"
33
+ },
34
+ {
35
+ "id": "M5",
36
+ "level": "warn",
37
+ "subject": "tomatoes",
38
+ "message": "seed farmersdelight:tomatoes 不在 items 里"
39
+ },
40
+ {
41
+ "id": "M6",
42
+ "level": "warn",
43
+ "subject": "farmersdelight:cutting",
44
+ "message": "111 条自定义配方没有统一 result,配方视图不会消费(首条 farmersdelight:cutting/beef)"
45
+ },
46
+ {
47
+ "id": "M6",
48
+ "level": "warn",
49
+ "subject": "smithing_trim",
50
+ "message": "19 条自定义配方没有统一 result,配方视图不会消费(首条 minecraft:sentry_armor_trim_smithing_template_smithing_trim)"
51
+ },
52
+ {
53
+ "id": "M6",
54
+ "level": "pass",
55
+ "subject": "recipes",
56
+ "message": "craftRecipeViews 1267 条"
57
+ },
58
+ {
59
+ "id": "I1",
60
+ "level": "warn",
61
+ "subject": "farmersdelight:mug",
62
+ "message": "manifest 声明了但服务器没有注册这个物品(兼容/技术物品,通常按实测裁剪)"
63
+ },
64
+ {
65
+ "id": "I1",
66
+ "level": "warn",
67
+ "subject": "farmersdelight:skillet_cooking",
68
+ "message": "manifest 声明了但服务器没有注册这个物品(兼容/技术物品,通常按实测裁剪)"
69
+ },
70
+ {
71
+ "id": "I5",
72
+ "level": "pass",
73
+ "subject": "server-mods",
74
+ "message": "服务器 mods 指纹对得上(5 个文件)"
75
+ },
76
+ {
77
+ "id": "I6",
78
+ "level": "warn",
79
+ "subject": "ids",
80
+ "message": "2 项在导入时被剔除(见 ids.failed)"
81
+ },
82
+ {
83
+ "id": "R4",
84
+ "level": "pass",
85
+ "subject": "farmersdelight:beetroot_crate",
86
+ "message": "作物可挖"
87
+ },
88
+ {
89
+ "id": "R4",
90
+ "level": "pass",
91
+ "subject": "farmersdelight:budding_tomatoes",
92
+ "message": "作物可挖"
93
+ },
94
+ {
95
+ "id": "R4",
96
+ "level": "pass",
97
+ "subject": "farmersdelight:cabbage_crate",
98
+ "message": "作物可挖"
99
+ },
100
+ {
101
+ "id": "R4",
102
+ "level": "pass",
103
+ "subject": "farmersdelight:cabbages",
104
+ "message": "作物可挖"
105
+ },
106
+ {
107
+ "id": "R4",
108
+ "level": "pass",
109
+ "subject": "farmersdelight:carrot_crate",
110
+ "message": "作物可挖"
111
+ },
112
+ {
113
+ "id": "R4",
114
+ "level": "pass",
115
+ "subject": "farmersdelight:onion_crate",
116
+ "message": "作物可挖"
117
+ },
118
+ {
119
+ "id": "R4",
120
+ "level": "pass",
121
+ "subject": "farmersdelight:onions",
122
+ "message": "作物可挖"
123
+ },
124
+ {
125
+ "id": "R4",
126
+ "level": "pass",
127
+ "subject": "farmersdelight:potato_crate",
128
+ "message": "作物可挖"
129
+ },
130
+ {
131
+ "id": "R4",
132
+ "level": "pass",
133
+ "subject": "farmersdelight:pumpkin_pie",
134
+ "message": "作物可挖"
135
+ },
136
+ {
137
+ "id": "R4",
138
+ "level": "pass",
139
+ "subject": "farmersdelight:rice",
140
+ "message": "作物可挖"
141
+ },
142
+ {
143
+ "id": "R4",
144
+ "level": "pass",
145
+ "subject": "farmersdelight:rice_bag",
146
+ "message": "作物可挖"
147
+ },
148
+ {
149
+ "id": "R4",
150
+ "level": "pass",
151
+ "subject": "farmersdelight:rice_bale",
152
+ "message": "作物可挖"
153
+ },
154
+ {
155
+ "id": "R4",
156
+ "level": "pass",
157
+ "subject": "farmersdelight:rice_panicles",
158
+ "message": "作物可挖"
159
+ },
160
+ {
161
+ "id": "R4",
162
+ "level": "pass",
163
+ "subject": "farmersdelight:rice_roll_medley_block",
164
+ "message": "作物可挖"
165
+ },
166
+ {
167
+ "id": "R4",
168
+ "level": "pass",
169
+ "subject": "farmersdelight:stuffed_pumpkin_block",
170
+ "message": "作物可挖"
171
+ },
172
+ {
173
+ "id": "R4",
174
+ "level": "pass",
175
+ "subject": "farmersdelight:sweet_berry_cheesecake",
176
+ "message": "作物可挖"
177
+ },
178
+ {
179
+ "id": "R4",
180
+ "level": "pass",
181
+ "subject": "farmersdelight:tomato_crate",
182
+ "message": "作物可挖"
183
+ },
184
+ {
185
+ "id": "R4",
186
+ "level": "pass",
187
+ "subject": "farmersdelight:tomatoes",
188
+ "message": "作物可挖"
189
+ },
190
+ {
191
+ "id": "R4",
192
+ "level": "pass",
193
+ "subject": "farmersdelight:tomatoes_on_rope",
194
+ "message": "作物可挖"
195
+ },
196
+ {
197
+ "id": "R4",
198
+ "level": "pass",
199
+ "subject": "farmersdelight:wild_beetroots",
200
+ "message": "作物可挖"
201
+ },
202
+ {
203
+ "id": "R4",
204
+ "level": "pass",
205
+ "subject": "farmersdelight:wild_cabbages",
206
+ "message": "作物可挖"
207
+ },
208
+ {
209
+ "id": "R4",
210
+ "level": "pass",
211
+ "subject": "farmersdelight:wild_carrots",
212
+ "message": "作物可挖"
213
+ },
214
+ {
215
+ "id": "R4",
216
+ "level": "pass",
217
+ "subject": "farmersdelight:wild_onions",
218
+ "message": "作物可挖"
219
+ },
220
+ {
221
+ "id": "R4",
222
+ "level": "pass",
223
+ "subject": "farmersdelight:wild_potatoes",
224
+ "message": "作物可挖"
225
+ },
226
+ {
227
+ "id": "R4",
228
+ "level": "pass",
229
+ "subject": "farmersdelight:wild_rice",
230
+ "message": "作物可挖"
231
+ },
232
+ {
233
+ "id": "R4",
234
+ "level": "pass",
235
+ "subject": "farmersdelight:wild_tomatoes",
236
+ "message": "作物可挖"
237
+ },
238
+ {
239
+ "id": "R6",
240
+ "level": "pass",
241
+ "subject": "recipes",
242
+ "message": "1267 条可消费配方"
243
+ },
244
+ {
245
+ "id": "R7",
246
+ "level": "pass",
247
+ "subject": "entities",
248
+ "message": "1 个实体已注入"
249
+ },
250
+ {
251
+ "id": "L2",
252
+ "level": "pass",
253
+ "subject": "farmersdelight:acacia_cabinet",
254
+ "message": "solid full block:已放置,shape 1"
255
+ },
256
+ {
257
+ "id": "L2",
258
+ "level": "pass",
259
+ "subject": "farmersdelight:apple_pie",
260
+ "message": "solid full block:已放置,shape 1"
261
+ },
262
+ {
263
+ "id": "L2",
264
+ "level": "pass",
265
+ "subject": "farmersdelight:bamboo_basket",
266
+ "message": "solid full block:已放置,shape 1"
267
+ },
268
+ {
269
+ "id": "L2",
270
+ "level": "pass",
271
+ "subject": "farmersdelight:bamboo_cabinet",
272
+ "message": "solid full block:已放置,shape 1"
273
+ },
274
+ {
275
+ "id": "L2",
276
+ "level": "pass",
277
+ "subject": "farmersdelight:beetroot_crate",
278
+ "message": "solid full block:已放置,shape 1"
279
+ },
280
+ {
281
+ "id": "L2",
282
+ "level": "pass",
283
+ "subject": "farmersdelight:birch_cabinet",
284
+ "message": "solid full block:已放置,shape 1"
285
+ },
286
+ {
287
+ "id": "L2",
288
+ "level": "pass",
289
+ "subject": "farmersdelight:budding_tomatoes",
290
+ "message": "solid full block:已放置,shape 1"
291
+ },
292
+ {
293
+ "id": "L2",
294
+ "level": "pass",
295
+ "subject": "farmersdelight:cabbage_crate",
296
+ "message": "solid full block:已放置,shape 1"
297
+ },
298
+ {
299
+ "id": "L3",
300
+ "level": "pass",
301
+ "subject": "farmersdelight:rotten_tomato",
302
+ "message": "召唤后 bot.entities 认得出名字"
303
+ }
304
+ ],
305
+ "live": {
306
+ "username": "ModConformDev",
307
+ "version": "1.21.1",
308
+ "dimension": "overworld",
309
+ "position": {
310
+ "x": 401,
311
+ "y": 60,
312
+ "z": 401
313
+ }
314
+ },
315
+ "registry": {
316
+ "blocks": 132,
317
+ "states": 2548,
318
+ "items": 185,
319
+ "entities": 1
320
+ }
321
+ }
@@ -0,0 +1,47 @@
1
+ {
2
+ "pack": "moredelight",
3
+ "summary": {
4
+ "pass": 4,
5
+ "warn": 2,
6
+ "fail": 0,
7
+ "total": 6
8
+ },
9
+ "checks": [
10
+ {
11
+ "id": "M1",
12
+ "level": "pass",
13
+ "subject": "manifest",
14
+ "message": "schema/validate 通过"
15
+ },
16
+ {
17
+ "id": "M1.warn",
18
+ "level": "warn",
19
+ "subject": "prompt",
20
+ "message": "没有 prompt:提示词里只会写「装了 X」"
21
+ },
22
+ {
23
+ "id": "M6",
24
+ "level": "warn",
25
+ "subject": "farmersdelight:cutting",
26
+ "message": "3 条自定义配方没有统一 result,配方视图不会消费(首条 casualness_delight:cutting/diced_potatoes)"
27
+ },
28
+ {
29
+ "id": "M6",
30
+ "level": "pass",
31
+ "subject": "recipes",
32
+ "message": "craftRecipeViews 30 条"
33
+ },
34
+ {
35
+ "id": "I5",
36
+ "level": "pass",
37
+ "subject": "server-mods",
38
+ "message": "服务器 mods 指纹对得上(7 个文件)"
39
+ },
40
+ {
41
+ "id": "R6",
42
+ "level": "pass",
43
+ "subject": "recipes",
44
+ "message": "30 条可消费配方"
45
+ }
46
+ ]
47
+ }