SayaSS commited on
Commit
f8ec1c0
1 Parent(s): 81b7cbf

update app.py

Browse files
Files changed (2) hide show
  1. app.py +142 -119
  2. pretrained_models/info.json +23 -23
app.py CHANGED
@@ -111,12 +111,18 @@ if __name__ == '__main__':
111
  parser.add_argument("--share", action="store_true", default=False, help="share gradio app")
112
  args = parser.parse_args()
113
  device = torch.device(args.device)
114
-
 
 
 
 
 
 
115
  models = []
116
  with open("pretrained_models/info.json", "r", encoding="utf-8") as f:
117
  models_info = json.load(f)
118
  for i, info in models_info.items():
119
- if not info['enable']:
120
  continue
121
  sid = info['sid']
122
  name_en = info['name_en']
@@ -138,127 +144,144 @@ if __name__ == '__main__':
138
  gr.Markdown(
139
  "# <center> vits-models\n"
140
  "## <center> Please do not generate content that could infringe upon the rights or cause harm to individuals or organizations.\n"
141
- "## <center> ·请不要生成会对个人以及组织造成侵害的内容\n"
142
  "![visitor badge](https://visitor-badge.glitch.me/badge?page_id=sayashi.vits-models)\n\n"
143
- "[Open In Colab]"
144
- "(https://colab.research.google.com/drive/10QOk9NPgoKZUXkIhhuVaZ7SYra1MPMKH?usp=share_link)"
145
- " without queue and length limitation.(无需等待队列,并且没有长度限制)\n\n"
146
- "[Finetune your own model](https://github.com/SayaSS/vits-finetuning)"
147
  )
148
 
149
  with gr.Tabs():
150
- with gr.TabItem("EN"):
151
- for (sid, name_en, name_zh, title, cover, example, language, net_g_ms, tts_fn, to_symbol_fn) in models:
152
- with gr.TabItem(name_en):
153
- with gr.Row():
154
- gr.Markdown(
155
- '<div align="center">'
156
- f'<a><strong>{title}</strong></a>'
157
- f'<img style="width:auto;height:300px;" src="file/{cover}">' if cover else ""
158
- '</div>'
159
- )
160
- with gr.Row():
161
- with gr.Column():
162
- input_text = gr.Textbox(label="Text (100 words limitation)" if limitation else "Text", lines=5, value=example, elem_id=f"input-text-en-{name_en.replace(' ','')}")
163
- lang = gr.Dropdown(label="Language", choices=["Chinese", "Japanese", "Mix(wrap the Chinese text with [ZH][ZH], wrap the Japanese text with [JA][JA])"],
164
- type="index", value=language)
165
- with gr.Accordion(label="Advanced Options", open=False):
166
- symbol_input = gr.Checkbox(value=False, label="Symbol input")
167
- symbol_list = gr.Dataset(label="Symbol list", components=[input_text],
168
- samples=[[x] for x in hps_ms.symbols])
169
- symbol_list_json = gr.Json(value=hps_ms.symbols, visible=False)
170
- btn = gr.Button(value="Generate", variant="primary")
171
  with gr.Row():
172
- ns = gr.Slider(label="noise_scale", minimum=0.1, maximum=1.0, step=0.1, value=0.6, interactive=True)
173
- nsw = gr.Slider(label="noise_scale_w", minimum=0.1, maximum=1.0, step=0.1, value=0.668, interactive=True)
174
- ls = gr.Slider(label="length_scale", minimum=0.1, maximum=2.0, step=0.1, value=1.2 if language=="Chinese" else 1, interactive=True)
175
- with gr.Column():
176
- o1 = gr.Textbox(label="Output Message")
177
- o2 = gr.Audio(label="Output Audio", elem_id=f"tts-audio-en-{name_en.replace(' ','')}")
178
- download = gr.Button("Download Audio")
179
- btn.click(tts_fn, inputs=[input_text, lang, ns, nsw, ls, symbol_input], outputs=[o1, o2], api_name=f"tts-{name_en}")
180
- download.click(None, [], [], _js=download_audio_js.format(audio_id=f"en-{name_en.replace(' ', '')}"))
181
- lang.change(change_lang, inputs=[lang], outputs=[ns, nsw, ls])
182
- symbol_input.change(
183
- to_symbol_fn,
184
- [symbol_input, input_text, lang],
185
- [input_text]
186
- )
187
- symbol_list.click(None, [symbol_list, symbol_list_json], [input_text],
188
- _js=f"""
189
- (i,symbols) => {{
190
- let root = document.querySelector("body > gradio-app");
191
- if (root.shadowRoot != null)
192
- root = root.shadowRoot;
193
- let text_input = root.querySelector("#input-text-en-{name_en.replace(' ', '')}").querySelector("textarea");
194
- let startPos = text_input.selectionStart;
195
- let endPos = text_input.selectionEnd;
196
- let oldTxt = text_input.value;
197
- let result = oldTxt.substring(0, startPos) + symbols[i] + oldTxt.substring(endPos);
198
- text_input.value = result;
199
- let x = window.scrollX, y = window.scrollY;
200
- text_input.focus();
201
- text_input.selectionStart = startPos + symbols[i].length;
202
- text_input.selectionEnd = startPos + symbols[i].length;
203
- text_input.blur();
204
- window.scrollTo(x, y);
205
- return text_input.value;
206
- }}""")
207
- with gr.TabItem("中文"):
208
- for (sid, name_en, name_zh, title, cover, example, language, net_g_ms, tts_fn, to_symbol_fn) in models:
209
- with gr.TabItem(name_zh):
210
- with gr.Row():
211
- gr.Markdown(
212
- '<div align="center">'
213
- f'<a><strong>{title}</strong></a>'
214
- f'<img style="width:auto;height:300px;" src="file/{cover}">' if cover else ""
215
- '</div>'
216
- )
217
- with gr.Row():
218
- with gr.Column():
219
- input_text = gr.Textbox(label="文本 (100字上限)" if limitation else "文本", lines=5, value=example, elem_id=f"input-text-zh-{name_zh}")
220
- lang = gr.Dropdown(label="语言", choices=["中文", "日语", "中日混合(中文用[ZH][ZH]包裹起来,日文用[JA][JA]包裹起来)"],
221
- type="index", value="中文"if language == "Chinese" else "日语")
222
- with gr.Accordion(label="高级选项", open=False):
223
- symbol_input = gr.Checkbox(value=False, label="符号输入")
224
- symbol_list = gr.Dataset(label="符号列表", components=[input_text],
225
- samples=[[x] for x in hps_ms.symbols])
226
- symbol_list_json = gr.Json(value=hps_ms.symbols, visible=False)
227
- btn = gr.Button(value="生成", variant="primary")
228
  with gr.Row():
229
- ns = gr.Slider(label="控制感情变化程度", minimum=0.1, maximum=1.0, step=0.1, value=0.6, interactive=True)
230
- nsw = gr.Slider(label="控制音素发音长度", minimum=0.1, maximum=1.0, step=0.1, value=0.668, interactive=True)
231
- ls = gr.Slider(label="控制整体语速", minimum=0.1, maximum=2.0, step=0.1, value=1.2 if language=="Chinese" else 1, interactive=True)
232
- with gr.Column():
233
- o1 = gr.Textbox(label="输出信息")
234
- o2 = gr.Audio(label="输出音频", elem_id=f"tts-audio-zh-{name_zh}")
235
- download = gr.Button("下载音频")
236
- btn.click(tts_fn, inputs=[input_text, lang, ns, nsw, ls, symbol_input], outputs=[o1, o2])
237
- download.click(None, [], [], _js=download_audio_js.format(audio_id=f"zh-{name_zh}"))
238
- lang.change(change_lang, inputs=[lang], outputs=[ns, nsw, ls])
239
- symbol_input.change(
240
- to_symbol_fn,
241
- [symbol_input, input_text, lang],
242
- [input_text]
243
- )
244
- symbol_list.click(None, [symbol_list, symbol_list_json], [input_text],
245
- _js=f"""
246
- (i,symbols) => {{
247
- let root = document.querySelector("body > gradio-app");
248
- if (root.shadowRoot != null)
249
- root = root.shadowRoot;
250
- let text_input = root.querySelector("#input-text-zh-{name_zh}").querySelector("textarea");
251
- let startPos = text_input.selectionStart;
252
- let endPos = text_input.selectionEnd;
253
- let oldTxt = text_input.value;
254
- let result = oldTxt.substring(0, startPos) + symbols[i] + oldTxt.substring(endPos);
255
- text_input.value = result;
256
- let x = window.scrollX, y = window.scrollY;
257
- text_input.focus();
258
- text_input.selectionStart = startPos + symbols[i].length;
259
- text_input.selectionEnd = startPos + symbols[i].length;
260
- text_input.blur();
261
- window.scrollTo(x, y);
262
- return text_input.value;
263
- }}""")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
  app.queue(concurrency_count=1, api_open=args.api).launch(share=args.share)
 
111
  parser.add_argument("--share", action="store_true", default=False, help="share gradio app")
112
  args = parser.parse_args()
113
  device = torch.device(args.device)
114
+ categories = ["Blue Archive", "Lycoris Recoil"]
115
+ others = {
116
+ "Princess Connect! Re:Dive": "https://huggingface.co/spaces/sayashi/vits-models",
117
+ "Genshin Impact": "https://huggingface.co/spaces/sayashi/vits-models",
118
+ "Honkai Impact 3rd": "https://huggingface.co/spaces/sayashi/vits-models",
119
+ "Overwatch 2": "https://huggingface.co/spaces/sayashi/vits-models",
120
+ }
121
  models = []
122
  with open("pretrained_models/info.json", "r", encoding="utf-8") as f:
123
  models_info = json.load(f)
124
  for i, info in models_info.items():
125
+ if info['title'].split("-")[0] not in categories or not info['enable']:
126
  continue
127
  sid = info['sid']
128
  name_en = info['name_en']
 
144
  gr.Markdown(
145
  "# <center> vits-models\n"
146
  "## <center> Please do not generate content that could infringe upon the rights or cause harm to individuals or organizations.\n"
147
+ "## <center> 请不要生成会对个人以及组织造成侵害的内容\n"
148
  "![visitor badge](https://visitor-badge.glitch.me/badge?page_id=sayashi.vits-models)\n\n"
149
+ "[![image](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/10QOk9NPgoKZUXkIhhuVaZ7SYra1MPMKH?usp=share_link)\n\n"
150
+ "[![Duplicate this Space](https://huggingface.co/datasets/huggingface/badges/raw/main/duplicate-this-space-sm-dark.svg)](https://huggingface.co/spaces/sayashi/vits-models?duplicate=true)"
151
+ "[![Finetune your own model](https://badgen.net/badge/icon/github?icon=github&label=Finetune%20your%20own%20model)](https://github.com/SayaSS/vits-finetuning)"
 
152
  )
153
 
154
  with gr.Tabs():
155
+ for category in categories:
156
+ with gr.TabItem(category):
157
+ with gr.TabItem("EN"):
158
+ for (sid, name_en, name_zh, title, cover, example, language, net_g_ms, tts_fn, to_symbol_fn) in models:
159
+ if title.split("-")[0] != category:
160
+ continue
161
+ with gr.TabItem(name_en):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  with gr.Row():
163
+ gr.Markdown(
164
+ '<div align="center">'
165
+ f'<a><strong>{title}</strong></a>'
166
+ f'<img style="width:auto;height:300px;" src="file/{cover}">' if cover else ""
167
+ '</div>'
168
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  with gr.Row():
170
+ with gr.Column():
171
+ input_text = gr.Textbox(label="Text (100 words limitation)" if limitation else "Text", lines=5, value=example, elem_id=f"input-text-en-{name_en.replace(' ','')}")
172
+ lang = gr.Dropdown(label="Language", choices=["Chinese", "Japanese", "Mix(wrap the Chinese text with [ZH][ZH], wrap the Japanese text with [JA][JA])"],
173
+ type="index", value=language)
174
+ with gr.Accordion(label="Advanced Options", open=False):
175
+ symbol_input = gr.Checkbox(value=False, label="Symbol input")
176
+ symbol_list = gr.Dataset(label="Symbol list", components=[input_text],
177
+ samples=[[x] for x in hps_ms.symbols])
178
+ symbol_list_json = gr.Json(value=hps_ms.symbols, visible=False)
179
+ btn = gr.Button(value="Generate", variant="primary")
180
+ with gr.Row():
181
+ ns = gr.Slider(label="noise_scale", minimum=0.1, maximum=1.0, step=0.1, value=0.6, interactive=True)
182
+ nsw = gr.Slider(label="noise_scale_w", minimum=0.1, maximum=1.0, step=0.1, value=0.668, interactive=True)
183
+ ls = gr.Slider(label="length_scale", minimum=0.1, maximum=2.0, step=0.1, value=1.2 if language=="Chinese" else 1, interactive=True)
184
+ with gr.Column():
185
+ o1 = gr.Textbox(label="Output Message")
186
+ o2 = gr.Audio(label="Output Audio", elem_id=f"tts-audio-en-{name_en.replace(' ','')}")
187
+ download = gr.Button("Download Audio")
188
+ btn.click(tts_fn, inputs=[input_text, lang, ns, nsw, ls, symbol_input], outputs=[o1, o2], api_name=f"tts-{name_en}")
189
+ download.click(None, [], [], _js=download_audio_js.format(audio_id=f"en-{name_en.replace(' ', '')}"))
190
+ lang.change(change_lang, inputs=[lang], outputs=[ns, nsw, ls])
191
+ symbol_input.change(
192
+ to_symbol_fn,
193
+ [symbol_input, input_text, lang],
194
+ [input_text]
195
+ )
196
+ symbol_list.click(None, [symbol_list, symbol_list_json], [input_text],
197
+ _js=f"""
198
+ (i,symbols) => {{
199
+ let root = document.querySelector("body > gradio-app");
200
+ if (root.shadowRoot != null)
201
+ root = root.shadowRoot;
202
+ let text_input = root.querySelector("#input-text-en-{name_en.replace(' ', '')}").querySelector("textarea");
203
+ let startPos = text_input.selectionStart;
204
+ let endPos = text_input.selectionEnd;
205
+ let oldTxt = text_input.value;
206
+ let result = oldTxt.substring(0, startPos) + symbols[i] + oldTxt.substring(endPos);
207
+ text_input.value = result;
208
+ let x = window.scrollX, y = window.scrollY;
209
+ text_input.focus();
210
+ text_input.selectionStart = startPos + symbols[i].length;
211
+ text_input.selectionEnd = startPos + symbols[i].length;
212
+ text_input.blur();
213
+ window.scrollTo(x, y);
214
+ return text_input.value;
215
+ }}""")
216
+ with gr.TabItem("中文"):
217
+ for (sid, name_en, name_zh, title, cover, example, language, net_g_ms, tts_fn, to_symbol_fn) in models:
218
+ if title.split("-")[0] != category:
219
+ continue
220
+ with gr.TabItem(name_zh):
221
+ with gr.Row():
222
+ gr.Markdown(
223
+ '<div align="center">'
224
+ f'<a><strong>{title}</strong></a>'
225
+ f'<img style="width:auto;height:300px;" src="file/{cover}">' if cover else ""
226
+ '</div>'
227
+ )
228
+ with gr.Row():
229
+ with gr.Column():
230
+ input_text = gr.Textbox(label="文本 (100字上限)" if limitation else "文本", lines=5, value=example, elem_id=f"input-text-zh-{name_zh}")
231
+ lang = gr.Dropdown(label="语言", choices=["中文", "日语", "中日混合(中文用[ZH][ZH]包裹起来,日文用[JA][JA]包裹起来)"],
232
+ type="index", value="中文"if language == "Chinese" else "日语")
233
+ with gr.Accordion(label="高级选项", open=False):
234
+ symbol_input = gr.Checkbox(value=False, label="符号输入")
235
+ symbol_list = gr.Dataset(label="符号列表", components=[input_text],
236
+ samples=[[x] for x in hps_ms.symbols])
237
+ symbol_list_json = gr.Json(value=hps_ms.symbols, visible=False)
238
+ btn = gr.Button(value="生成", variant="primary")
239
+ with gr.Row():
240
+ ns = gr.Slider(label="控制感情变化程度", minimum=0.1, maximum=1.0, step=0.1, value=0.6, interactive=True)
241
+ nsw = gr.Slider(label="控制音素发音长度", minimum=0.1, maximum=1.0, step=0.1, value=0.668, interactive=True)
242
+ ls = gr.Slider(label="控制整体语速", minimum=0.1, maximum=2.0, step=0.1, value=1.2 if language=="Chinese" else 1, interactive=True)
243
+ with gr.Column():
244
+ o1 = gr.Textbox(label="输出信息")
245
+ o2 = gr.Audio(label="输出音频", elem_id=f"tts-audio-zh-{name_zh}")
246
+ download = gr.Button("下载音频")
247
+ btn.click(tts_fn, inputs=[input_text, lang, ns, nsw, ls, symbol_input], outputs=[o1, o2])
248
+ download.click(None, [], [], _js=download_audio_js.format(audio_id=f"zh-{name_zh}"))
249
+ lang.change(change_lang, inputs=[lang], outputs=[ns, nsw, ls])
250
+ symbol_input.change(
251
+ to_symbol_fn,
252
+ [symbol_input, input_text, lang],
253
+ [input_text]
254
+ )
255
+ symbol_list.click(None, [symbol_list, symbol_list_json], [input_text],
256
+ _js=f"""
257
+ (i,symbols) => {{
258
+ let root = document.querySelector("body > gradio-app");
259
+ if (root.shadowRoot != null)
260
+ root = root.shadowRoot;
261
+ let text_input = root.querySelector("#input-text-zh-{name_zh}").querySelector("textarea");
262
+ let startPos = text_input.selectionStart;
263
+ let endPos = text_input.selectionEnd;
264
+ let oldTxt = text_input.value;
265
+ let result = oldTxt.substring(0, startPos) + symbols[i] + oldTxt.substring(endPos);
266
+ text_input.value = result;
267
+ let x = window.scrollX, y = window.scrollY;
268
+ text_input.focus();
269
+ text_input.selectionStart = startPos + symbols[i].length;
270
+ text_input.selectionEnd = startPos + symbols[i].length;
271
+ text_input.blur();
272
+ window.scrollTo(x, y);
273
+ return text_input.value;
274
+ }}""")
275
+ for category, link in others.items():
276
+ with gr.TabItem(category):
277
+ gr.Markdown(
278
+ f'''
279
+ <center>
280
+ <h2>Click to Go</h2>
281
+ <a href="{link}">
282
+ <img src="https://huggingface.co/datasets/huggingface/badges/raw/main/open-in-hf-spaces-xl-dark.svg"
283
+ </a>
284
+ </center>
285
+ '''
286
+ )
287
  app.queue(concurrency_count=1, api_open=args.api).launch(share=args.share)
pretrained_models/info.json CHANGED
@@ -22,7 +22,7 @@
22
  "type": "single"
23
  },
24
  "misora": {
25
- "enable": false,
26
  "name_en": "Misora",
27
  "name_zh": "美空",
28
  "title": "Princess Connect! Re:Dive-ミソラ",
@@ -33,7 +33,7 @@
33
  "type": "single"
34
  },
35
  "kyoka": {
36
- "enable": false,
37
  "name_en": "Kyoka",
38
  "name_zh": "镜华",
39
  "title": "Princess Connect! Re:Dive-キョウカ",
@@ -44,7 +44,7 @@
44
  "type": "multi"
45
  },
46
  "hiyori": {
47
- "enable": false,
48
  "name_en": "Hiyori",
49
  "name_zh": "日和莉",
50
  "title": "Princess Connect! Re:Dive-ヒヨリ",
@@ -66,7 +66,7 @@
66
  "type": "single"
67
  },
68
  "hatsune": {
69
- "enable": false,
70
  "name_en": "Hatsune",
71
  "name_zh": "柏崎初音",
72
  "title": "Princess Connect! Re:Dive-柏崎初音",
@@ -77,7 +77,7 @@
77
  "type": "multi"
78
  },
79
  "eriko": {
80
- "enable": false,
81
  "name_en": "Eriko",
82
  "name_zh": "惠理子",
83
  "title": "Princess Connect! Re:Dive-倉石恵理子",
@@ -143,7 +143,7 @@
143
  "type": "single"
144
  },
145
  "ayaka-jp": {
146
- "enable": false,
147
  "name_en": "ayaka-jp",
148
  "name_zh": "神里绫华-日语",
149
  "title": "Genshin Impact-神里綾華",
@@ -154,7 +154,7 @@
154
  "type": "multi"
155
  },
156
  "nahida-jp": {
157
- "enable": false,
158
  "name_en": "nahida-jp",
159
  "name_zh": "纳西妲-日语",
160
  "title": "Genshin Impact-ナヒーダ",
@@ -198,7 +198,7 @@
198
  "type": "multi"
199
  },
200
  "karin": {
201
- "enable": false,
202
  "name_en": "Kakudate Karin",
203
  "name_zh": "角楯花凛",
204
  "title": "Blue Archive-角楯カリン",
@@ -209,7 +209,7 @@
209
  "type": "multi"
210
  },
211
  "asuna": {
212
- "enable": false,
213
  "name_en": "Ichinose Asuna",
214
  "name_zh": "一之濑明日奈",
215
  "title": "Blue Archive-一之瀬アスナ",
@@ -253,7 +253,7 @@
253
  "type": "multi"
254
  },
255
  "hoshino": {
256
- "enable": false,
257
  "name_en": "Takanasi Hosino",
258
  "name_zh": "小鸟游星野",
259
  "title": "Blue Archive-小鳥遊 ホシノ",
@@ -308,7 +308,7 @@
308
  "type": "multi"
309
  },
310
  "doom": {
311
- "enable": false,
312
  "name_en": "Doomfist",
313
  "name_zh": "末日铁拳",
314
  "title": "Overwatch 2-Doomfist",
@@ -319,7 +319,7 @@
319
  "type": "multi"
320
  },
321
  "echo": {
322
- "enable": false,
323
  "name_en": "Echo",
324
  "name_zh": "回声",
325
  "title": "Overwatch 2-Echo",
@@ -330,7 +330,7 @@
330
  "type": "multi"
331
  },
332
  "zenyatta": {
333
- "enable": false,
334
  "name_en": "Zenyatta",
335
  "name_zh": "禅雅塔",
336
  "title": "Overwatch 2-Zenyatta",
@@ -341,10 +341,10 @@
341
  "type": "multi"
342
  },
343
  "abyssinvoker": {
344
- "enable": false,
345
  "name_en": "Abyss Invoker",
346
  "name_zh": "深渊使徒",
347
- "title": "原神-深渊使徒",
348
  "cover": "cover.png",
349
  "sid": 94,
350
  "example": "今天晚上吃啥好呢",
@@ -352,10 +352,10 @@
352
  "type": "multi"
353
  },
354
  "keqing": {
355
- "enable": false,
356
  "name_en": "Keqing",
357
  "name_zh": "刻晴",
358
- "title": "原神-刻晴",
359
  "cover": "cover.png",
360
  "sid": 115,
361
  "example": "今天晚上吃啥好呢",
@@ -363,10 +363,10 @@
363
  "type": "multi"
364
  },
365
  "eula": {
366
- "enable": false,
367
  "name_en": "Eula",
368
  "name_zh": "优菈",
369
- "title": "原神-优菈",
370
  "cover": "cover.png",
371
  "sid": 124,
372
  "example": "今天晚上吃啥好呢",
@@ -374,10 +374,10 @@
374
  "type": "multi"
375
  },
376
  "bronya": {
377
- "enable": false,
378
  "name_en": "Herrscher of Reason",
379
  "name_zh": "理之律者",
380
- "title": "崩坏3-理之律者",
381
  "cover": "cover.png",
382
  "sid": 193,
383
  "example": "今天晚上吃啥好呢",
@@ -385,10 +385,10 @@
385
  "type": "multi"
386
  },
387
  "theresa": {
388
- "enable": false,
389
  "name_en": "Theresa",
390
  "name_zh": "德丽莎",
391
- "title": "崩坏3-德丽莎",
392
  "cover": "cover.png",
393
  "sid": 193,
394
  "example": "今天晚上吃啥好呢",
 
22
  "type": "single"
23
  },
24
  "misora": {
25
+ "enable": true,
26
  "name_en": "Misora",
27
  "name_zh": "美空",
28
  "title": "Princess Connect! Re:Dive-ミソラ",
 
33
  "type": "single"
34
  },
35
  "kyoka": {
36
+ "enable": true,
37
  "name_en": "Kyoka",
38
  "name_zh": "镜华",
39
  "title": "Princess Connect! Re:Dive-キョウカ",
 
44
  "type": "multi"
45
  },
46
  "hiyori": {
47
+ "enable": true,
48
  "name_en": "Hiyori",
49
  "name_zh": "日和莉",
50
  "title": "Princess Connect! Re:Dive-ヒヨリ",
 
66
  "type": "single"
67
  },
68
  "hatsune": {
69
+ "enable": true,
70
  "name_en": "Hatsune",
71
  "name_zh": "柏崎初音",
72
  "title": "Princess Connect! Re:Dive-柏崎初音",
 
77
  "type": "multi"
78
  },
79
  "eriko": {
80
+ "enable": true,
81
  "name_en": "Eriko",
82
  "name_zh": "惠理子",
83
  "title": "Princess Connect! Re:Dive-倉石恵理子",
 
143
  "type": "single"
144
  },
145
  "ayaka-jp": {
146
+ "enable": true,
147
  "name_en": "ayaka-jp",
148
  "name_zh": "神里绫华-日语",
149
  "title": "Genshin Impact-神里綾華",
 
154
  "type": "multi"
155
  },
156
  "nahida-jp": {
157
+ "enable": true,
158
  "name_en": "nahida-jp",
159
  "name_zh": "纳西妲-日语",
160
  "title": "Genshin Impact-ナヒーダ",
 
198
  "type": "multi"
199
  },
200
  "karin": {
201
+ "enable": true,
202
  "name_en": "Kakudate Karin",
203
  "name_zh": "角楯花凛",
204
  "title": "Blue Archive-角楯カリン",
 
209
  "type": "multi"
210
  },
211
  "asuna": {
212
+ "enable": true,
213
  "name_en": "Ichinose Asuna",
214
  "name_zh": "一之濑明日奈",
215
  "title": "Blue Archive-一之瀬アスナ",
 
253
  "type": "multi"
254
  },
255
  "hoshino": {
256
+ "enable": true,
257
  "name_en": "Takanasi Hosino",
258
  "name_zh": "小鸟游星野",
259
  "title": "Blue Archive-小鳥遊 ホシノ",
 
308
  "type": "multi"
309
  },
310
  "doom": {
311
+ "enable": true,
312
  "name_en": "Doomfist",
313
  "name_zh": "末日铁拳",
314
  "title": "Overwatch 2-Doomfist",
 
319
  "type": "multi"
320
  },
321
  "echo": {
322
+ "enable": true,
323
  "name_en": "Echo",
324
  "name_zh": "回声",
325
  "title": "Overwatch 2-Echo",
 
330
  "type": "multi"
331
  },
332
  "zenyatta": {
333
+ "enable": true,
334
  "name_en": "Zenyatta",
335
  "name_zh": "禅雅塔",
336
  "title": "Overwatch 2-Zenyatta",
 
341
  "type": "multi"
342
  },
343
  "abyssinvoker": {
344
+ "enable": true,
345
  "name_en": "Abyss Invoker",
346
  "name_zh": "深渊使徒",
347
+ "title": "Genshin Impact-深渊使徒",
348
  "cover": "cover.png",
349
  "sid": 94,
350
  "example": "今天晚上吃啥好呢",
 
352
  "type": "multi"
353
  },
354
  "keqing": {
355
+ "enable": true,
356
  "name_en": "Keqing",
357
  "name_zh": "刻晴",
358
+ "title": "Genshin Impact-刻晴",
359
  "cover": "cover.png",
360
  "sid": 115,
361
  "example": "今天晚上吃啥好呢",
 
363
  "type": "multi"
364
  },
365
  "eula": {
366
+ "enable": true,
367
  "name_en": "Eula",
368
  "name_zh": "优菈",
369
+ "title": "Genshin Impact-优菈",
370
  "cover": "cover.png",
371
  "sid": 124,
372
  "example": "今天晚上吃啥好呢",
 
374
  "type": "multi"
375
  },
376
  "bronya": {
377
+ "enable": true,
378
  "name_en": "Herrscher of Reason",
379
  "name_zh": "理之律者",
380
+ "title": "Honkai Impact 3rd-理之律者",
381
  "cover": "cover.png",
382
  "sid": 193,
383
  "example": "今天晚上吃啥好呢",
 
385
  "type": "multi"
386
  },
387
  "theresa": {
388
+ "enable": true,
389
  "name_en": "Theresa",
390
  "name_zh": "德丽莎",
391
+ "title": "Honkai Impact 3rd-德丽莎",
392
  "cover": "cover.png",
393
  "sid": 193,
394
  "example": "今天晚上吃啥好呢",