Skip to content
This repository was archived by the owner on Oct 10, 2022. It is now read-only.

Commit 328915c

Browse files
committed
Release v0.4, add mp3 download links, update status
1 parent dbf3415 commit 328915c

File tree

2 files changed

+204
-48
lines changed

2 files changed

+204
-48
lines changed

README.md

+181-23
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
# **Russian Open Speech To Text (STT/ASR) Dataset**
22

33
Arguably the largest public Russian STT dataset up to date:
4+
- (**new!**) Now in `.mp3` to reduce download time 7-8x;
45
- ~4.6m utterances;
56
- ~4000 hours;
6-
- 431 GB;
7+
- 431 GB (in `.wav` format in `int16`);
78
- Additional 1,500 hours ... and more ... to be released soon!;
89
- And then maybe even more hours to be released!;
910

11+
1012
Prove [us](mailto:open_stt@googlegroups.com) wrong!
1113
Open issues, collaborate, submit a PR, contribute, share your datasets!
1214
Let's make STT in Russian (and more) as open and available as CV models.
@@ -50,14 +52,20 @@ Let's make STT in Russian (and more) as open and available as CV models.
5052
This alignment was performed using Yuri's alignment tool.
5153
[Contact him](mailto:open_stt@googlegroups.com) if you need alignment for your own dataset.
5254

53-
# **_update 2019-05-07_ Help needed!**
55+
## **_Update 2019-05-10_**
56+
57+
Quickly converted the dataset to MP3 thanks to the community!
58+
Waiting for our account for academic torrents to be approved.
59+
v0.4 will boast MP3 download links.
60+
61+
## **_Update 2019-05-07_ Help needed!**
5462

5563
**If you want to support the project, you can:**
5664
- Help us with hosting (create a mirror) / provide a reliable node for torrent;
5765
- Help us with writing some [helper](https://github.com/snakers4/open_stt/issues/2) functions;
5866
- [Donate](https://buymeacoff.ee/8oneCIN) (each coffee pays for several full downloads) / use our DO referral [link](https://sohabr.net/habr/post/357748/) to help;
5967

60-
We are converting the dataset to MP3 now.
68+
~~We are converting the dataset to MP3 now.~~
6169
Please contact us using the below contacts, if you would like to help.
6270

6371
# **Downloads**
@@ -66,22 +74,22 @@ Please contact us using the below contacts, if you would like to help.
6674

6775
Meta data [file](https://ru-open-stt.ams3.digitaloceanspaces.com/public_meta_data_v03.csv).
6876

77+
| Dataset | GB, wav | GB, mp3 | Wav | Mp3 | Source | Manifest |
78+
|---------------------------------------|------|----------------|-------|-----| -------| ----------|
79+
| audiobook_2 | 166 | 21.0 | down | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/private_buriy_audiobooks_2_mp3.tar.gz) | Sources from the Internet + alignment | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/private_buriy_audiobooks_2.csv) |
80+
| asr_public_phone_calls_2 | 66 | 7.5 | down | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/asr_public_phone_calls_2_mp3.tar.gz) | Sources from the Internet + ASR | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/asr_public_phone_calls_2.csv) |
81+
| asr_public_stories_2 | 9 (7.5) | NA | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/asr_public_stories_2.tar.gz) | NA | Sources from the Internet + alignment | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/asr_public_stories_2.csv) |
82+
| tts_russian_addresses_rhvoice_4voices | 80.9 | 9.9 | down | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/tts_russian_addresses_rhvoice_4voices_mp3.tar.gz) | TTS | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/tts_russian_addresses_rhvoice_4voices.csv) |
83+
| public_youtube700 | 75.0 | 9.6 | down | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/public_youtube700_mp3.tar.gz) | YouTube videos | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/public_youtube700.csv) |
84+
| asr_public_phone_calls_1 | 22.7 | 2.6 | down | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/asr_public_phone_calls_1_mp3.tar.gz) | Sources from the Internet + ASR | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/asr_public_phone_calls_1.csv) |
85+
| asr_public_stories_1 | 4.1 | 0.5 | down | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/asr_public_stories_1_mp3.tar.gz) | Public stories | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/asr_public_stories_1.csv) |
86+
| public_series_1 | 1.9 | 0.2 | down | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/public_series_1_mp3.tar.gz) | Public series | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/public_series_1.csv) |
87+
| ru_RU | 1.9 | 0.2 | down | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/ru_ru.tar.gz) | Caito.de [dataset](https://www.caito.de/data/Training/stt_tts/) | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/ru_RU.csv) |
88+
| voxforge_ru | 1.9 | 0.2 | down | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/voxforge_ru_mp3.tar.gz) | Voxforge [dataset](https://www.repository.voxforge1.org/downloads/) | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/voxforge_ru.csv) |
89+
| russian_single | 0.9 | 0.1 | down | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/russian_single_mp3.tar.gz) | Russian single speaker [dataset](https://www.kaggle.com/bryanpark/russian-single-speaker-speech-dataset) | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/russian_single.csv) |
90+
| public_lecture_1 | 0.7 | 0.1 | down | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/public_lecture_1_mp3.tar.gz) | Sources from the Internet | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/public_lecture_1.csv) |
91+
| Total | 431 | 52 | | | | |
6992

70-
| Dataset | GB | GB, compressed | Audio | Source | Manifest |
71-
|---------------------------------------|------|----------------|-------| -------| ----------|
72-
| audiobook_2 | 166 | 131.7 | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/audiobooks_2.tar.gz_aa), [part2](https://ru-open-stt.ams3.digitaloceanspaces.com/audiobooks_2.tar.gz_ab), [part3](https://ru-open-stt.ams3.digitaloceanspaces.com/audiobooks_2.tar.gz_ac), [part4](https://ru-open-stt.ams3.digitaloceanspaces.com/audiobooks_2.tar.gz_ad), [part5](https://ru-open-stt.ams3.digitaloceanspaces.com/audiobooks_2.tar.gz_ae), [part6](https://ru-open-stt.ams3.digitaloceanspaces.com/audiobooks_2.tar.gz_af), [part7](https://ru-open-stt.ams3.digitaloceanspaces.com/audiobooks_2.tar.gz_ag) | Sources from the Internet + alignment | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/private_buriy_audiobooks_2.csv) |
73-
| asr_public_phone_calls_2 | 66 | 51.7 | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/asr_public_phone_calls_2.tar.gz_aa), [part2](https://ru-open-stt.ams3.digitaloceanspaces.com/asr_public_phone_calls_2.tar.gz_ab), [part3](https://ru-open-stt.ams3.digitaloceanspaces.com/asr_public_phone_calls_2.tar.gz_ac) | Sources from the Internet + ASR | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/asr_public_phone_calls_2.csv) |
74-
| asr_public_stories_2 | 9 | 7.5 | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/asr_public_stories_2.tar.gz) | Sources from the Internet + alignment | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/asr_public_stories_2.csv) |
75-
| tts_russian_addresses_rhvoice_4voices | 80.9 | 67.0 | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/tts_russian_addresses_rhvoice_4voices.tar.gz_aa), [part2](https://ru-open-stt.ams3.digitaloceanspaces.com/tts_russian_addresses_rhvoice_4voices.tar.gz_ab), [part3](https://ru-open-stt.ams3.digitaloceanspaces.com/tts_russian_addresses_rhvoice_4voices.tar.gz_ac), [part4](https://ru-open-stt.ams3.digitaloceanspaces.com/tts_russian_addresses_rhvoice_4voices.tar.gz_ad) | TTS | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/tts_russian_addresses_rhvoice_4voices.csv) |
76-
| public_youtube700 | 75.0 | 67.0 | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/public_youtube700.tar.gz_aa), [part2](https://ru-open-stt.ams3.digitaloceanspaces.com/public_youtube700.tar.gz_ab), [part3](https://ru-open-stt.ams3.digitaloceanspaces.com/public_youtube700.tar.gz_ac), [part4](https://ru-open-stt.ams3.digitaloceanspaces.com/public_youtube700.tar.gz_ad) | YouTube videos | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/public_youtube700.csv) |
77-
| asr_public_phone_calls_1 | 22.7 | 19.0 | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/asr_public_phone_calls_1.tar.gz) | Sources from the Internet + ASR | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/asr_public_phone_calls_1.csv) |
78-
| asr_public_stories_1 | 4.1 | 3.8 | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/asr_public_stories_1.tar.gz) | Public stories | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/asr_public_stories_1.csv) |
79-
| public_series_1 | 1.9 | 1.7 | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/public_series_1.tar.gz) | Public series | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/public_series_1.csv) |
80-
| ru_RU | 1.9 | 1.4 | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/ru_ru.tar.gz) | Caito.de [dataset](https://www.caito.de/data/Training/stt_tts/) | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/ru_RU.csv) |
81-
| voxforge_ru | 1.9 | 1.5 | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/voxforge_ru.tar.gz) | Voxforge [dataset](https://www.repository.voxforge1.org/downloads/) | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/voxforge_ru.csv) |
82-
| russian_single | 0.9 | 0.7 | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/russian_single.tar.gz) | Russian single speaker [dataset](https://www.kaggle.com/bryanpark/russian-single-speaker-speech-dataset) | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/russian_single.csv) |
83-
| public_lecture_1 | 0.7 | 0.6 | [part1](https://ru-open-stt.ams3.digitaloceanspaces.com/public_lecture_1.tar.gz) | Sources from the Internet | [link](https://ru-open-stt.ams3.digitaloceanspaces.com/public_lecture_1.csv) |
84-
| Total | 190 | 163 | | | | |
8593

8694

8795
## **Download instructions**
@@ -108,6 +116,7 @@ Meta data [file](https://ru-open-stt.ams3.digitaloceanspaces.com/public_meta_dat
108116

109117
## **Check md5sum**
110118

119+
Including links to deprecated files.
111120
`md5sum /path/to/downloaded/file`
112121

113122
<details>
@@ -118,6 +127,62 @@ Meta data [file](https://ru-open-stt.ams3.digitaloceanspaces.com/public_meta_dat
118127
<th>md5sum</th>
119128
<th>file</th>
120129
</tr>
130+
<tr>
131+
<td>audio</td>
132+
<td>c356e279fe65530a14079b952a3374e1</td>
133+
<td>asr_public_phone_calls_1_mp3.tar.gz</td>
134+
</tr>
135+
<tr>
136+
<td>audio</td>
137+
<td>a9c6c721d5c8cbbf683fae325fbc20e9</td>
138+
<td>asr_public_phone_calls_2_mp3.tar.gz</td>
139+
</tr>
140+
<tr>
141+
<td>audio</td>
142+
<td>dee17aea8d0ba197e5636508bb2ac6a9</td>
143+
<td>asr_public_stories_1_mp3.tar.gz</td>
144+
</tr>
145+
<tr>
146+
<td>audio</td>
147+
<td>be5cec0a66f44e77adacc8fb09142bbd</td>
148+
<td>private_buriy_audiobooks_2_mp3.tar.gz</td>
149+
</tr>
150+
<tr>
151+
<td>audio</td>
152+
<td>e1abff84b5318007ae17d293dcc24783</td>
153+
<td>public_lecture_1_mp3.tar.gz</td>
154+
</tr>
155+
<tr>
156+
<td>audio</td>
157+
<td>3d954ffdc65693fb4caf0bca61171b34</td>
158+
<td>public_series_1_mp3.tar.gz</td>
159+
</tr>
160+
<tr>
161+
<td>audio</td>
162+
<td>501f16dc4bf529a99315beb2d31e76ef</td>
163+
<td>public_youtube700_mp3.tar.gz</td>
164+
</tr>
165+
<tr>
166+
<td>audio</td>
167+
<td>ba9e68fdeb5e60fc9292cbeb24c09eb5</td>
168+
<td>ru_ru_mp3.tar.gz</td>
169+
</tr>
170+
<tr>
171+
<td>audio</td>
172+
<td>d79f85cc8c70cb36255f1cce4d0eddd1</td>
173+
<td>russian_single_mp3.tar.gz</td>
174+
</tr>
175+
<tr>
176+
<td>audio</td>
177+
<td>d6213dc7930591a99a6dd495bc2eda6a</td>
178+
<td>tts_russian_addresses_rhvoice_4voices_mp3.tar.gz</td>
179+
</tr>
180+
<tr>
181+
<td>audio</td>
182+
<td>dd5704a9f0c695ccd333dea807a0cd87</td>
183+
<td>voxforge_ru_mp3.tar.gz</td>
184+
</tr>
185+
121186
<tr>
122187
<td>manifest</td>
123188
<td>b0ce7564ba90b121aeb13aada73a6e30</td>
@@ -316,9 +381,11 @@ Meta data [file](https://ru-open-stt.ams3.digitaloceanspaces.com/public_meta_dat
316381
</table>
317382
</details>
318383

384+
319385
## **End to end download scripts**
320386

321387
You can use this [script](https://github.com/snakers4/open_stt/blob/master/download.sh) with this config [file](https://github.com/snakers4/open_stt/blob/master/md5sum.lst).
388+
Please check the config first.
322389
You can also [contribute](https://github.com/snakers4/open_stt/issues/2) a similar script in python.
323390

324391
# **Annotation methodology**
@@ -404,11 +471,102 @@ Please contact us [here](mailto:open_stt@googlegroups.com) or just create a GitH
404471

405472
# **FAQ**
406473

407-
## **0. Why not MP3?**
474+
## **0. ~~Why not MP3?~~ MP3 encoding / decoding**
475+
476+
#### **Encoding**
477+
478+
Mostly we used `pydub` (via ffmpeg) to convert to MP3.
479+
We omitted blank files (YouTube mostly).
480+
We used the following parameters:
481+
- 16kHz;
482+
- 32 kbps;
483+
- Mono;
484+
485+
Usually 128-192 kbps is enough for music with sr of 44 kHz, 64-96 is enough for speech.
486+
But here we have mono, 16 kHz and usually only one speaker. So 32 kbps was a good choice.
487+
We did not use other formats like `.ogg`, because `.mp3` is much more popular.
488+
489+
<details><summary>See example</summary>
490+
<p>
491+
492+
```python
493+
from pydub import AudioSegment
494+
495+
sound = AudioSegment.from_file(temp_path,
496+
format="wav")
497+
498+
file_handle = sound.export(store_mp3_path,
499+
format="mp3",
500+
parameters =["-ar", "{}".format(str(16000)),"-ac", "1"],
501+
bitrate="{}k".format(str(32)))
502+
```
503+
504+
</p>
505+
</details>
506+
507+
#### **Decoding**
508+
509+
It is up to you, but to save space and spare CPU during training, I would suggest the following pipeline to extract the files:
510+
511+
<details><summary>See example</summary>
512+
<p>
513+
514+
```python
515+
# you can also use pydub, torchaudio, sox or whatever
516+
# we ended up using scipy for speed
517+
# this example also includes hashing step which is not necessary
518+
import librosa
519+
import hashlib
520+
import numpy as np
521+
from pathlib import Path
522+
from scipy.io import wavfile
523+
524+
def save_wav_diskdb(wav,
525+
root_folder='../data/ru_open_stt/',
526+
target_sr=16000):
527+
assert type(wav) == np.ndarray
528+
assert wav.dtype == np.dtype('int16')
529+
assert len(wav.shape)==1
530+
531+
target_format = 'wav'
532+
wavb = wav.tobytes()
533+
534+
# f_path = Path(audio_path)
535+
f_hash = hashlib.sha1(wavb).hexdigest()
536+
537+
store_path = Path(root_folder,
538+
f_hash[0],
539+
f_hash[1:3],
540+
f_hash[3:15]+'.'+target_format)
408541

409-
We were planning to make an MP3 version (around 64 kb/s), and probably we were too quick to publish the dataset - it grew out of control.
410-
Despite having ample free DO credits, we incurred some charges for data transfer.
411-
We are making / will soon make an MP3 version and replace the links with the new ones.
542+
store_path.parent.mkdir(parents=True,
543+
exist_ok=True)
544+
545+
wavfile.write(filename=str(store_path),
546+
rate=target_sr,
547+
data=wav)
548+
549+
return str(store_path)
550+
551+
root_folder = '../data/'
552+
# save to int16, mono, 16 kHz to save space
553+
target_dtype = np.dtype('int16')
554+
target_sr = 16000
555+
# librosa reads mp3
556+
wav, sr = librosa.load(source_mp3_path,
557+
mono=True,
558+
sr=target_sr)
559+
560+
# librosa converts to float32 by default
561+
wav = (wav * 32767).astype(target_dtype) # cast to int
562+
563+
wav_path = save_wav_diskdb(wav,
564+
root_folder=root_folder,
565+
target_sr=target_sr)
566+
```
567+
568+
</p>
569+
</details>
412570

413571
## **1. Issues with reading files**
414572

@@ -444,7 +602,7 @@ TTS does not enjoy the same attention by ML community because it is data hungry
444602
Ultimately it leads to worse-off situation for the general community.
445603

446604
## **3. Known issues with the dataset to be fixed**
447-
- Blank files in Youtube dataset. Just filter them out using meta-data. Will be fixed in future;
605+
- ~~Blank files in Youtube dataset~~. Removed in mp3 archive. Meta-data not cleaned;
448606
- Some files that have low values / crash with tochaudio;
449607
- Looks like scipy does not always write meta-data when saving wavs (or you should save (N,1) shaped file) - this can be fixed as shown above;
450608

md5sum.lst

+23-25
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,27 @@ a81dfb018c88d0ecd5194ab3d8ff6c95 public_youtube700.csv
99
c858f020729c34ba0ab525bbb8950d0c ru_RU.csv
1010
0275525914825dec663fd53390fdc9a0 russian_single.csv
1111
52f406f4e30fcc8c634f992befd91beb tts_russian_addresses_rhvoice_4voices.csv
12-
a5496898ee78654bf398ec6df71540d7 asr_public_phone_calls_1.tar.gz
13-
97594127a922df8a7bcc2eecd2470805 asr_public_phone_calls_2.tar.gz_aa
14-
f9b6475f0f2898b16d9e6e0e648fb531 asr_public_phone_calls_2.tar.gz_ab
15-
b19977c889cda639f621195251e6bb6f asr_public_phone_calls_2.tar.gz_ac
16-
657a31b544b10295f909ef4b2ca5c156 asr_public_stories_1.tar.gz
12+
c356e279fe65530a14079b952a3374e1 asr_public_phone_calls_1_mp3.tar.gz
13+
a9c6c721d5c8cbbf683fae325fbc20e9 asr_public_phone_calls_2_mp3.tar.gz
14+
dee17aea8d0ba197e5636508bb2ac6a9 asr_public_stories_1_mp3.tar.gz
15+
be5cec0a66f44e77adacc8fb09142bbd private_buriy_audiobooks_2_mp3.tar.gz
16+
e1abff84b5318007ae17d293dcc24783 public_lecture_1_mp3.tar.gz
17+
3d954ffdc65693fb4caf0bca61171b34 public_series_1_mp3.tar.gz
18+
501f16dc4bf529a99315beb2d31e76ef public_youtube700_mp3.tar.gz
19+
ba9e68fdeb5e60fc9292cbeb24c09eb5 ru_ru_mp3.tar.gz
20+
d79f85cc8c70cb36255f1cce4d0eddd1 russian_single_mp3.tar.gz
21+
d6213dc7930591a99a6dd495bc2eda6a tts_russian_addresses_rhvoice_4voices_mp3.tar.gz
22+
dd5704a9f0c695ccd333dea807a0cd87 voxforge_ru_mp3.tar.gz
1723
7533581bb26975212817bcacb25546d0 asr_public_stories_2.tar.gz
18-
3955616cd89761bf2d54d0e992f7eae5 audiobooks_2.tar.gz_aa
19-
81b6ec147c0c43bdd56002c41e0288b8 audiobooks_2.tar.gz_ab
20-
15d4cf99171c2db3f375619f4bd2b6d9 audiobooks_2.tar.gz_ac
21-
50635b0f4bdf44fae96e5a65f4738e19 audiobooks_2.tar.gz_ad
22-
f1103be39ffc2da4a98d8f6ddeb50aa0 audiobooks_2.tar.gz_ae
23-
8b45d2bd8b1fa1d906e36b9fabd9fe4c audiobooks_2.tar.gz_af
24-
5104df44933b612b3c1bfc06f6376654 audiobooks_2.tar.gz_ag
25-
e6b9e5f46811d33ea34ce50f6067a762 public_lecture_1.tar.gz
26-
86ebf7e30986b8ee8df11f85b35588a0 public_series_1.tar.gz
27-
dc260dd8151b4fce6cde6d80af13146d public_youtube700.tar.gz_aa
28-
04706ef0f98841ec8d2f20a83aca3cf1 public_youtube700.tar.gz_ab
29-
e11d5b118bf71425e4915e61277a06a9 public_youtube700.tar.gz_ac
30-
d9a93157263eb9d8078c0e0b88c271de public_youtube700.tar.gz_ad
31-
1bbba5eb2f4911c9ed20ec69cbd292cb ru_ru.tar.gz
32-
6f79a9c514ad48a5763e3142919fc765 russian_single.tar.gz
33-
31d515e0bdfc467c3fe63088b817c15c tts_russian_addresses_rhvoice_4voices.tar.gz_aa
34-
4ca15694a8d8a638bbdc5e90832eadb4 tts_russian_addresses_rhvoice_4voices.tar.gz_ab
35-
447559a38cd8bf61c5de64e602f06da3 tts_russian_addresses_rhvoice_4voices.tar.gz_ac
36-
9131347a97c2e794d7c6d5a265083e83 tts_russian_addresses_rhvoice_4voices.tar.gz_ad
37-
91e2115b17b1ad08649f428d2caa643b voxforge_ru.tar.gz
24+
25+
26+
27+
28+
29+
30+
31+
32+
33+
34+
35+

0 commit comments

Comments
 (0)