ttsforge 0.1.0__py3-none-any.whl → 0.1.1__py3-none-any.whl
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.
- ttsforge/_version.py +2 -2
- ttsforge/cli/commands_conversion.py +6 -7
- ttsforge/cli/commands_phonemes.py +3 -3
- ttsforge/constants.py +2 -2
- ttsforge/conversion.py +9 -9
- ttsforge/name_extractor.py +3 -3
- ttsforge/phoneme_conversion.py +9 -9
- ttsforge/ssmd_generator.py +4 -4
- {ttsforge-0.1.0.dist-info → ttsforge-0.1.1.dist-info}/METADATA +12 -12
- {ttsforge-0.1.0.dist-info → ttsforge-0.1.1.dist-info}/RECORD +14 -14
- {ttsforge-0.1.0.dist-info → ttsforge-0.1.1.dist-info}/WHEEL +0 -0
- {ttsforge-0.1.0.dist-info → ttsforge-0.1.1.dist-info}/entry_points.txt +0 -0
- {ttsforge-0.1.0.dist-info → ttsforge-0.1.1.dist-info}/licenses/LICENSE +0 -0
- {ttsforge-0.1.0.dist-info → ttsforge-0.1.1.dist-info}/top_level.txt +0 -0
ttsforge/_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.1.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 1,
|
|
31
|
+
__version__ = version = '0.1.1'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 1, 1)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -536,17 +536,17 @@ def convert( # noqa: C901
|
|
|
536
536
|
pause_clause=(
|
|
537
537
|
pause_clause
|
|
538
538
|
if pause_clause is not None
|
|
539
|
-
else config.get("pause_clause", 0.
|
|
539
|
+
else config.get("pause_clause", 0.3)
|
|
540
540
|
),
|
|
541
541
|
pause_sentence=(
|
|
542
542
|
pause_sentence
|
|
543
543
|
if pause_sentence is not None
|
|
544
|
-
else config.get("pause_sentence", 0.
|
|
544
|
+
else config.get("pause_sentence", 0.5)
|
|
545
545
|
),
|
|
546
546
|
pause_paragraph=(
|
|
547
547
|
pause_paragraph
|
|
548
548
|
if pause_paragraph is not None
|
|
549
|
-
else config.get("pause_paragraph", 0.
|
|
549
|
+
else config.get("pause_paragraph", 0.9)
|
|
550
550
|
),
|
|
551
551
|
pause_variance=(
|
|
552
552
|
pause_variance
|
|
@@ -1369,17 +1369,17 @@ def read( # noqa: C901
|
|
|
1369
1369
|
effective_split_mode = config_split_mode
|
|
1370
1370
|
# Pause settings
|
|
1371
1371
|
effective_pause_clause = (
|
|
1372
|
-
pause_clause if pause_clause is not None else config.get("pause_clause", 0.
|
|
1372
|
+
pause_clause if pause_clause is not None else config.get("pause_clause", 0.3)
|
|
1373
1373
|
)
|
|
1374
1374
|
effective_pause_sentence = (
|
|
1375
1375
|
pause_sentence
|
|
1376
1376
|
if pause_sentence is not None
|
|
1377
|
-
else config.get("pause_sentence", 0.
|
|
1377
|
+
else config.get("pause_sentence", 0.5)
|
|
1378
1378
|
)
|
|
1379
1379
|
effective_pause_paragraph = (
|
|
1380
1380
|
pause_paragraph
|
|
1381
1381
|
if pause_paragraph is not None
|
|
1382
|
-
else config.get("pause_paragraph", 0.
|
|
1382
|
+
else config.get("pause_paragraph", 0.9)
|
|
1383
1383
|
)
|
|
1384
1384
|
effective_pause_variance = (
|
|
1385
1385
|
pause_variance
|
|
@@ -1695,7 +1695,6 @@ def read( # noqa: C901
|
|
|
1695
1695
|
|
|
1696
1696
|
def generate_audio(text_segment: str) -> tuple[np.ndarray, int]:
|
|
1697
1697
|
"""Generate audio for a text segment."""
|
|
1698
|
-
print(text_segment)
|
|
1699
1698
|
result = pipeline.run(text_segment)
|
|
1700
1699
|
return result.audio, result.sample_rate
|
|
1701
1700
|
|
|
@@ -603,17 +603,17 @@ def phonemes_convert(
|
|
|
603
603
|
pause_clause=(
|
|
604
604
|
pause_clause
|
|
605
605
|
if pause_clause is not None
|
|
606
|
-
else config.get("pause_clause", 0.
|
|
606
|
+
else config.get("pause_clause", 0.3)
|
|
607
607
|
),
|
|
608
608
|
pause_sentence=(
|
|
609
609
|
pause_sentence
|
|
610
610
|
if pause_sentence is not None
|
|
611
|
-
else config.get("pause_sentence", 0.
|
|
611
|
+
else config.get("pause_sentence", 0.5)
|
|
612
612
|
),
|
|
613
613
|
pause_paragraph=(
|
|
614
614
|
pause_paragraph
|
|
615
615
|
if pause_paragraph is not None
|
|
616
|
-
else config.get("pause_paragraph", 0.
|
|
616
|
+
else config.get("pause_paragraph", 0.9)
|
|
617
617
|
),
|
|
618
618
|
pause_variance=(
|
|
619
619
|
pause_variance
|
ttsforge/constants.py
CHANGED
|
@@ -123,8 +123,8 @@ DEFAULT_CONFIG = {
|
|
|
123
123
|
"default_split_mode": "auto",
|
|
124
124
|
"default_content_mode": "chapters", # Content mode for read: chapters or pages
|
|
125
125
|
"default_page_size": 2000, # Synthetic page size in characters for pages mode
|
|
126
|
-
"pause_clause": 0.
|
|
127
|
-
"pause_sentence": 0.
|
|
126
|
+
"pause_clause": 0.3,
|
|
127
|
+
"pause_sentence": 0.5,
|
|
128
128
|
"pause_paragraph": 0.9,
|
|
129
129
|
"pause_variance": 0.05,
|
|
130
130
|
"pause_mode": "auto", # "tts", "manual", or "auto
|
ttsforge/conversion.py
CHANGED
|
@@ -124,9 +124,9 @@ class ConversionState:
|
|
|
124
124
|
split_mode: str = "auto"
|
|
125
125
|
output_format: str = "m4b"
|
|
126
126
|
silence_between_chapters: float = 2.0
|
|
127
|
-
pause_clause: float = 0.
|
|
128
|
-
pause_sentence: float = 0.
|
|
129
|
-
pause_paragraph: float = 0.
|
|
127
|
+
pause_clause: float = 0.3
|
|
128
|
+
pause_sentence: float = 0.5
|
|
129
|
+
pause_paragraph: float = 0.9
|
|
130
130
|
pause_variance: float = 0.05
|
|
131
131
|
pause_mode: str = "auto" # "tts", "manual", or "auto
|
|
132
132
|
lang: str | None = None # Language override for phonemization
|
|
@@ -174,11 +174,11 @@ class ConversionState:
|
|
|
174
174
|
|
|
175
175
|
# Set defaults for new parameters
|
|
176
176
|
if "pause_clause" not in data:
|
|
177
|
-
data["pause_clause"] = 0.
|
|
177
|
+
data["pause_clause"] = 0.3
|
|
178
178
|
if "pause_sentence" not in data:
|
|
179
|
-
data["pause_sentence"] = 0.
|
|
179
|
+
data["pause_sentence"] = 0.5
|
|
180
180
|
if "pause_paragraph" not in data:
|
|
181
|
-
data["pause_paragraph"] = 0.
|
|
181
|
+
data["pause_paragraph"] = 0.9
|
|
182
182
|
if "pause_variance" not in data:
|
|
183
183
|
data["pause_variance"] = 0.05
|
|
184
184
|
if "pause_mode" not in data:
|
|
@@ -289,9 +289,9 @@ class ConversionOptions:
|
|
|
289
289
|
phoneme_dictionary_path: str | None = None
|
|
290
290
|
phoneme_dict_case_sensitive: bool = False
|
|
291
291
|
# Pause settings (pykokoro built-in pause handling)
|
|
292
|
-
pause_clause: float = 0.
|
|
293
|
-
pause_sentence: float = 0.
|
|
294
|
-
pause_paragraph: float = 0.
|
|
292
|
+
pause_clause: float = 0.3 # For clause boundaries (commas)
|
|
293
|
+
pause_sentence: float = 0.5 # For sentence boundaries
|
|
294
|
+
pause_paragraph: float = 0.9 # For paragraph boundaries
|
|
295
295
|
pause_variance: float = 0.05 # Standard deviation for natural variation
|
|
296
296
|
pause_mode: str = "auto" # "tts", "manual", or "auto
|
|
297
297
|
# Chapter announcement settings
|
ttsforge/name_extractor.py
CHANGED
|
@@ -174,7 +174,7 @@ def generate_phoneme_suggestions(
|
|
|
174
174
|
Dictionary with phoneme suggestions and metadata:
|
|
175
175
|
{
|
|
176
176
|
"name": {
|
|
177
|
-
"phoneme": "
|
|
177
|
+
"phoneme": "phoneme",
|
|
178
178
|
"occurrences": count,
|
|
179
179
|
"suggestion_quality": "auto"
|
|
180
180
|
}
|
|
@@ -190,7 +190,7 @@ def generate_phoneme_suggestions(
|
|
|
190
190
|
phoneme = phonemize(name, language=language).phonemes
|
|
191
191
|
|
|
192
192
|
# Wrap in / / format for dictionary
|
|
193
|
-
phoneme_formatted = f"
|
|
193
|
+
phoneme_formatted = f"{phoneme}"
|
|
194
194
|
|
|
195
195
|
suggestions[name] = {
|
|
196
196
|
"phoneme": phoneme_formatted,
|
|
@@ -201,7 +201,7 @@ def generate_phoneme_suggestions(
|
|
|
201
201
|
logger.warning(f"Failed to generate phoneme for '{name}': {e}")
|
|
202
202
|
# Add placeholder
|
|
203
203
|
suggestions[name] = {
|
|
204
|
-
"phoneme": "
|
|
204
|
+
"phoneme": "FIXME",
|
|
205
205
|
"occurrences": count,
|
|
206
206
|
"suggestion_quality": "error",
|
|
207
207
|
"error": str(e),
|
ttsforge/phoneme_conversion.py
CHANGED
|
@@ -95,9 +95,9 @@ class PhonemeConversionState:
|
|
|
95
95
|
speed: float = 1.0
|
|
96
96
|
output_format: str = "m4b"
|
|
97
97
|
silence_between_chapters: float = 2.0
|
|
98
|
-
pause_clause: float = 0.
|
|
99
|
-
pause_sentence: float = 0.
|
|
100
|
-
pause_paragraph: float = 0.
|
|
98
|
+
pause_clause: float = 0.3
|
|
99
|
+
pause_sentence: float = 0.5
|
|
100
|
+
pause_paragraph: float = 0.9
|
|
101
101
|
pause_variance: float = 0.05
|
|
102
102
|
pause_mode: str = "auto"
|
|
103
103
|
lang: str | None = None # Language override for phonemization
|
|
@@ -145,11 +145,11 @@ class PhonemeConversionState:
|
|
|
145
145
|
|
|
146
146
|
# Set defaults for new parameters
|
|
147
147
|
if "pause_clause" not in data:
|
|
148
|
-
data["pause_clause"] = 0.
|
|
148
|
+
data["pause_clause"] = 0.3
|
|
149
149
|
if "pause_sentence" not in data:
|
|
150
|
-
data["pause_sentence"] = 0.
|
|
150
|
+
data["pause_sentence"] = 0.5
|
|
151
151
|
if "pause_paragraph" not in data:
|
|
152
|
-
data["pause_paragraph"] = 0.
|
|
152
|
+
data["pause_paragraph"] = 0.9
|
|
153
153
|
if "pause_variance" not in data:
|
|
154
154
|
data["pause_variance"] = 0.05
|
|
155
155
|
if "pause_mode" not in data:
|
|
@@ -210,9 +210,9 @@ class PhonemeConversionOptions:
|
|
|
210
210
|
# If None, language from PhonemeSegments is used
|
|
211
211
|
lang: str | None = None
|
|
212
212
|
# Pause settings (pykokoro built-in pause handling)
|
|
213
|
-
pause_clause: float = 0.
|
|
214
|
-
pause_sentence: float = 0.
|
|
215
|
-
pause_paragraph: float = 0.
|
|
213
|
+
pause_clause: float = 0.3 # For clause boundaries (commas)
|
|
214
|
+
pause_sentence: float = 0.5 # For sentence boundaries
|
|
215
|
+
pause_paragraph: float = 0.9 # For paragraph boundaries
|
|
216
216
|
pause_variance: float = 0.05 # Standard deviation for natural variation
|
|
217
217
|
pause_mode: str = "auto" # "tts", "manual", or "auto"
|
|
218
218
|
# Chapter announcement settings
|
ttsforge/ssmd_generator.py
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
This module converts chapter text to SSMD format with markup for:
|
|
4
4
|
- Emphasis (*text* for moderate, **text** for strong)
|
|
5
|
-
- Language switches ([text]
|
|
6
|
-
- Phoneme substitutions ([word]
|
|
5
|
+
- Language switches ([text]{lang="lang_code"})
|
|
6
|
+
- Phoneme substitutions ([word]{ph="phoneme"})
|
|
7
7
|
|
|
8
8
|
Note: Structural breaks (paragraphs, sentences, clauses) are NOT automatically
|
|
9
9
|
added. The SSMD parser in pykokoro handles sentence detection automatically.
|
|
@@ -170,7 +170,7 @@ def _inject_phoneme_substitutions(
|
|
|
170
170
|
if not phoneme:
|
|
171
171
|
return matched_word
|
|
172
172
|
clean_phoneme = phoneme.strip("/")
|
|
173
|
-
return f"[{matched_word}]
|
|
173
|
+
return f"[{matched_word}]" + "{" + f'ph="{clean_phoneme}"' + "}"
|
|
174
174
|
|
|
175
175
|
segments: list[str] = []
|
|
176
176
|
last_index = 0
|
|
@@ -260,7 +260,7 @@ def _strip_redundant_title(chapter_title: str, chapter_text: str) -> str:
|
|
|
260
260
|
return chapter_text
|
|
261
261
|
|
|
262
262
|
trimmed_line = title_pattern.sub("", first_line, count=1).lstrip(
|
|
263
|
-
" \t
|
|
263
|
+
" \t:;-\u2013\u2014"
|
|
264
264
|
)
|
|
265
265
|
if trimmed_line:
|
|
266
266
|
lines[first_idx] = trimmed_line
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ttsforge
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: Generate audiobooks from EPUB files using Kokoro ONNX TTS.
|
|
5
5
|
Author-email: Holger Nahrstaedt <nahrstaedt@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -396,14 +396,14 @@ SSMD files use a simple markdown-like syntax:
|
|
|
396
396
|
**Custom Phonemes**:
|
|
397
397
|
|
|
398
398
|
```
|
|
399
|
-
[Hermione]
|
|
400
|
-
[API]
|
|
399
|
+
[Hermione]{ph="hɝmˈIni"} # Override pronunciation
|
|
400
|
+
[API]{ph="ˌeɪpiˈaɪ"} # Technical terms
|
|
401
401
|
```
|
|
402
402
|
|
|
403
403
|
**Language Switching** (planned):
|
|
404
404
|
|
|
405
405
|
```
|
|
406
|
-
[Bonjour]
|
|
406
|
+
[Bonjour]{lang="fr"} # Mark text as French
|
|
407
407
|
```
|
|
408
408
|
|
|
409
409
|
#### Example SSMD File
|
|
@@ -411,7 +411,7 @@ SSMD files use a simple markdown-like syntax:
|
|
|
411
411
|
```ssmd
|
|
412
412
|
Chapter One ...p
|
|
413
413
|
|
|
414
|
-
[Harry]
|
|
414
|
+
[Harry]{ph="hæɹi"} Potter was a *highly unusual* boy in many ways. ...s
|
|
415
415
|
For one thing, he **hated** the summer holidays more than any other
|
|
416
416
|
time of year. ...s For another, he really wanted to do his homework,
|
|
417
417
|
but was forced to do it in secret, in the dead of the night. ...p
|
|
@@ -498,12 +498,12 @@ Edit `custom_phonemes.json` to fix any incorrect phonemes. The file format is:
|
|
|
498
498
|
},
|
|
499
499
|
"entries": {
|
|
500
500
|
"Hermione": {
|
|
501
|
-
"phoneme": "
|
|
501
|
+
"phoneme": "hɝmˈIni",
|
|
502
502
|
"occurrences": 847,
|
|
503
503
|
"verified": false
|
|
504
504
|
},
|
|
505
505
|
"Kubernetes": {
|
|
506
|
-
"phoneme": "
|
|
506
|
+
"phoneme": "kubɚnˈɛtɪs",
|
|
507
507
|
"occurrences": 12,
|
|
508
508
|
"verified": false
|
|
509
509
|
}
|
|
@@ -515,8 +515,8 @@ Or use the simple format:
|
|
|
515
515
|
|
|
516
516
|
```json
|
|
517
517
|
{
|
|
518
|
-
"Hermione": "
|
|
519
|
-
"Kubernetes": "
|
|
518
|
+
"Hermione": "hɝmˈIni",
|
|
519
|
+
"Kubernetes": "kubɚnˈɛtɪs"
|
|
520
520
|
}
|
|
521
521
|
```
|
|
522
522
|
|
|
@@ -548,9 +548,9 @@ You can create a dictionary manually without extraction:
|
|
|
548
548
|
|
|
549
549
|
```json
|
|
550
550
|
{
|
|
551
|
-
"Katniss": "
|
|
552
|
-
"Peeta": "
|
|
553
|
-
"Panem": "
|
|
551
|
+
"Katniss": "kætnɪs",
|
|
552
|
+
"Peeta": "pitə",
|
|
553
|
+
"Panem": "pænəm"
|
|
554
554
|
}
|
|
555
555
|
```
|
|
556
556
|
|
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
ttsforge/__init__.py,sha256=Jg8_0vPttTVWrnt4HBqrTOKYfmcgpVpfddSVcU4HKXo,2432
|
|
2
|
-
ttsforge/_version.py,sha256=
|
|
2
|
+
ttsforge/_version.py,sha256=m8HxkqoKGw_wAJtc4ZokpJKNLXqp4zwnNhbnfDtro7w,704
|
|
3
3
|
ttsforge/audio_merge.py,sha256=Tt7o8GBNrkcfiSKycUpWvblj-y4zwlULoX-eCblqYpo,5666
|
|
4
4
|
ttsforge/audio_player.py,sha256=HYc4vv46yDXjVXaWRlj1tUtWLiwNTwbzT6oDfOUB5vA,14351
|
|
5
5
|
ttsforge/chapter_selection.py,sha256=a-XlEO4HMzeUBfhvnh6gQOQmDuM0wMpVCi0pw6oM2hQ,2579
|
|
6
|
-
ttsforge/constants.py,sha256=
|
|
7
|
-
ttsforge/conversion.py,sha256=
|
|
6
|
+
ttsforge/constants.py,sha256=Y_u8BanHjZBGiAnc9FVPulVHHGIRYlOJhq74BTtxPYA,5108
|
|
7
|
+
ttsforge/conversion.py,sha256=gz6ePEHjC7Nu1zlPArdsIOZA2rb_EEfJMaV6lA-0V2o,41623
|
|
8
8
|
ttsforge/input_reader.py,sha256=b49SBT-mL4SnR74D8xwyWHC_smPhsJ5jpPAj4QQ5WKo,14068
|
|
9
9
|
ttsforge/kokoro_lang.py,sha256=8603b5whfk0KzGrNK7pqRjzoH1Ge9TKoX7AMzKsX0sk,376
|
|
10
10
|
ttsforge/kokoro_runner.py,sha256=ZGBx70_rHcfwKiUgywa_3-7d5u-wQ_0pPOukQRuACu0,4390
|
|
11
|
-
ttsforge/name_extractor.py,sha256=
|
|
12
|
-
ttsforge/phoneme_conversion.py,sha256=
|
|
11
|
+
ttsforge/name_extractor.py,sha256=CxxBadCO0Pcoepcj7gZwkfWPMud2oa9477h_lDYWrIA,9578
|
|
12
|
+
ttsforge/phoneme_conversion.py,sha256=nLnFk1uuMMD1Mw4a24zZeZHDHG_4mG3kW1xiOcKM9YA,38274
|
|
13
13
|
ttsforge/phonemes.py,sha256=EUZ1Qr-0rPThRpSeuJQe5Z3J3nz7rX1Xs3Rjjw19qIQ,15517
|
|
14
|
-
ttsforge/ssmd_generator.py,sha256=
|
|
14
|
+
ttsforge/ssmd_generator.py,sha256=LknVBSETKH9cY4CoAUBjd1vEfr5VXi0xqEKcft2CR8I,13346
|
|
15
15
|
ttsforge/utils.py,sha256=3BiNFyScV3Dy_xhVm2EigpxUb4Z6YwIQPzzxwDzfCzI,24942
|
|
16
16
|
ttsforge/cli/__init__.py,sha256=CTqYeUAJaKV7YTYqcmr7-VxjwJfjLcnPYM2OKyws0Oc,2103
|
|
17
|
-
ttsforge/cli/commands_conversion.py,sha256=
|
|
18
|
-
ttsforge/cli/commands_phonemes.py,sha256=
|
|
17
|
+
ttsforge/cli/commands_conversion.py,sha256=fvbC62gswEb-qpVoU_9S81nFOApH09v9g29nG0HE9X4,63421
|
|
18
|
+
ttsforge/cli/commands_phonemes.py,sha256=Y1_t4jLDuEFVLY6sQC9uwcU9ptt4Y7FrRBRWtkSAF0o,32371
|
|
19
19
|
ttsforge/cli/commands_utility.py,sha256=_8KMUjVYVqp63PH_gjOjS-fw6ZCujaMDXFxoKfUzlko,48013
|
|
20
20
|
ttsforge/cli/helpers.py,sha256=5Co2EvDhYspKhjW2-P3sNxj9MFFgWyTFeqOyJbPy2yA,2697
|
|
21
21
|
ttsforge/vocab/__init__.py,sha256=lMgS0dY9VbOYI20LnPjjqrWcjLIQ1FKkR4-xcXsvrqc,3641
|
|
22
|
-
ttsforge-0.1.
|
|
23
|
-
ttsforge-0.1.
|
|
24
|
-
ttsforge-0.1.
|
|
25
|
-
ttsforge-0.1.
|
|
26
|
-
ttsforge-0.1.
|
|
27
|
-
ttsforge-0.1.
|
|
22
|
+
ttsforge-0.1.1.dist-info/licenses/LICENSE,sha256=9csb1sDNn0HdUPKgOTUwtb4CkvYPcFXHnkxKCS99EWQ,1074
|
|
23
|
+
ttsforge-0.1.1.dist-info/METADATA,sha256=tVUrSm-pBcKWQ0gyrsazqadW0ufARWPXp00qHJsf6ag,19567
|
|
24
|
+
ttsforge-0.1.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
25
|
+
ttsforge-0.1.1.dist-info/entry_points.txt,sha256=SrcNdlhQpoUCzPzhVbOmMzATQeV7j7XYl0DPrVjZ-ks,47
|
|
26
|
+
ttsforge-0.1.1.dist-info/top_level.txt,sha256=rNLi-3muicHF8UvZu_FuA2ML_Dz9sVPCjik2E8XnCVk,9
|
|
27
|
+
ttsforge-0.1.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|