maps4fs 1.8.11__py3-none-any.whl → 1.8.12__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- maps4fs/generator/background.py +7 -11
- maps4fs/generator/component/__init__.py +1 -0
- maps4fs/generator/component/base/__init__.py +1 -0
- maps4fs/generator/{component.py → component/base/component.py} +39 -23
- maps4fs/generator/component/base/component_xml.py +95 -0
- maps4fs/generator/{config.py → component/config.py} +15 -30
- maps4fs/generator/component/i3d.py +545 -0
- maps4fs/generator/dem.py +1 -10
- maps4fs/generator/game.py +33 -2
- maps4fs/generator/grle.py +10 -16
- maps4fs/generator/map.py +41 -1
- maps4fs/generator/satellite.py +1 -2
- maps4fs/generator/settings.py +11 -0
- maps4fs/generator/texture.py +5 -7
- maps4fs/toolbox/background.py +1 -3
- {maps4fs-1.8.11.dist-info → maps4fs-1.8.12.dist-info}/METADATA +3 -1
- {maps4fs-1.8.11.dist-info → maps4fs-1.8.12.dist-info}/RECORD +20 -17
- maps4fs/generator/i3d.py +0 -624
- {maps4fs-1.8.11.dist-info → maps4fs-1.8.12.dist-info}/LICENSE.md +0 -0
- {maps4fs-1.8.11.dist-info → maps4fs-1.8.12.dist-info}/WHEEL +0 -0
- {maps4fs-1.8.11.dist-info → maps4fs-1.8.12.dist-info}/top_level.txt +0 -0
maps4fs/generator/grle.py
CHANGED
@@ -10,7 +10,7 @@ import numpy as np
|
|
10
10
|
from shapely.geometry import Polygon # type: ignore
|
11
11
|
from tqdm import tqdm
|
12
12
|
|
13
|
-
from maps4fs.generator.component import Component
|
13
|
+
from maps4fs.generator.component.base.component import Component
|
14
14
|
from maps4fs.generator.texture import PREVIEW_MAXIMUM_SIZE, Texture
|
15
15
|
|
16
16
|
ISLAND_DISTORTION = 0.3
|
@@ -92,7 +92,7 @@ class GRLE(Component):
|
|
92
92
|
else:
|
93
93
|
info_layer_data = np.zeros((height, width, channels), dtype=data_type)
|
94
94
|
self.logger.debug("Shape of %s: %s.", info_layer["name"], info_layer_data.shape)
|
95
|
-
cv2.imwrite(file_path, info_layer_data)
|
95
|
+
cv2.imwrite(file_path, info_layer_data)
|
96
96
|
self.logger.debug("InfoLayer PNG file %s created.", file_path)
|
97
97
|
else:
|
98
98
|
self.logger.warning("Invalid InfoLayer schema: %s.", info_layer)
|
@@ -104,7 +104,6 @@ class GRLE(Component):
|
|
104
104
|
else:
|
105
105
|
self.logger.warning("Adding plants it's not supported for the %s.", self.game.code)
|
106
106
|
|
107
|
-
# pylint: disable=no-member
|
108
107
|
def previews(self) -> list[str]:
|
109
108
|
"""Returns a list of paths to the preview images (empty list).
|
110
109
|
The component does not generate any preview images so it returns an empty list.
|
@@ -131,7 +130,7 @@ class GRLE(Component):
|
|
131
130
|
image_with_fields = self.overlay_fields(image_colored)
|
132
131
|
if image_with_fields is None:
|
133
132
|
continue
|
134
|
-
cv2.imwrite(with_fields_save_path, image_with_fields)
|
133
|
+
cv2.imwrite(with_fields_save_path, image_with_fields)
|
135
134
|
preview_paths.append(with_fields_save_path)
|
136
135
|
|
137
136
|
return preview_paths
|
@@ -201,7 +200,6 @@ class GRLE(Component):
|
|
201
200
|
self.logger.warning("InfoLayer PNG file %s not found.", info_layer_farmlands_path)
|
202
201
|
return
|
203
202
|
|
204
|
-
# pylint: disable=no-member
|
205
203
|
image = cv2.imread(info_layer_farmlands_path, cv2.IMREAD_UNCHANGED)
|
206
204
|
farmlands_xml_path = os.path.join(self.map_directory, "map/config/farmlands.xml")
|
207
205
|
if not os.path.isfile(farmlands_xml_path):
|
@@ -244,7 +242,6 @@ class GRLE(Component):
|
|
244
242
|
field_np = field_np // 2
|
245
243
|
self.logger.debug("Divided the coordinates by 2.")
|
246
244
|
|
247
|
-
# pylint: disable=no-member
|
248
245
|
try:
|
249
246
|
cv2.fillPoly(image, [field_np], farmland_id) # type: ignore
|
250
247
|
except Exception as e: # pylint: disable=W0718
|
@@ -267,7 +264,7 @@ class GRLE(Component):
|
|
267
264
|
|
268
265
|
self.logger.debug("Farmlands added to the farmlands XML file: %s.", farmlands_xml_path)
|
269
266
|
|
270
|
-
cv2.imwrite(info_layer_farmlands_path, image)
|
267
|
+
cv2.imwrite(info_layer_farmlands_path, image)
|
271
268
|
self.logger.debug(
|
272
269
|
"Farmlands added to the InfoLayer PNG file: %s.", info_layer_farmlands_path
|
273
270
|
)
|
@@ -300,7 +297,7 @@ class GRLE(Component):
|
|
300
297
|
forest_image_path = forest_layer.get_preview_or_path(weights_directory)
|
301
298
|
self.logger.debug("Forest image path: %s.", forest_image_path)
|
302
299
|
if forest_image_path:
|
303
|
-
|
300
|
+
|
304
301
|
forest_image = cv2.imread(forest_image_path, cv2.IMREAD_UNCHANGED)
|
305
302
|
|
306
303
|
if not grass_image_path or not os.path.isfile(grass_image_path):
|
@@ -318,22 +315,20 @@ class GRLE(Component):
|
|
318
315
|
return
|
319
316
|
|
320
317
|
# Single channeled 8-bit image, where non-zero values (255) are where the grass is.
|
321
|
-
grass_image = cv2.imread(
|
322
|
-
grass_image_path, cv2.IMREAD_UNCHANGED # pylint: disable=no-member
|
323
|
-
)
|
318
|
+
grass_image = cv2.imread(grass_image_path, cv2.IMREAD_UNCHANGED)
|
324
319
|
|
325
320
|
# Density map of the fruits is 2X size of the base image, so we need to resize it.
|
326
321
|
# We'll resize the base image to make it bigger, so we can compare the values.
|
327
|
-
grass_image = cv2.resize(
|
322
|
+
grass_image = cv2.resize(
|
328
323
|
grass_image,
|
329
324
|
(grass_image.shape[1] * 2, grass_image.shape[0] * 2),
|
330
|
-
interpolation=cv2.INTER_NEAREST,
|
325
|
+
interpolation=cv2.INTER_NEAREST,
|
331
326
|
)
|
332
327
|
if forest_image is not None:
|
333
|
-
forest_image = cv2.resize(
|
328
|
+
forest_image = cv2.resize(
|
334
329
|
forest_image,
|
335
330
|
(forest_image.shape[1] * 2, forest_image.shape[0] * 2),
|
336
|
-
interpolation=cv2.INTER_NEAREST,
|
331
|
+
interpolation=cv2.INTER_NEAREST,
|
337
332
|
)
|
338
333
|
|
339
334
|
# Add non zero values from the forest image to the grass image.
|
@@ -348,7 +343,6 @@ class GRLE(Component):
|
|
348
343
|
if not base_layer_pixel_value:
|
349
344
|
base_layer_pixel_value = 131
|
350
345
|
|
351
|
-
# pylint: disable=no-member
|
352
346
|
def create_island_of_plants(image: np.ndarray, count: int) -> np.ndarray:
|
353
347
|
"""Create an island of plants in the image.
|
354
348
|
|
maps4fs/generator/map.py
CHANGED
@@ -7,7 +7,8 @@ import os
|
|
7
7
|
import shutil
|
8
8
|
from typing import Any, Generator
|
9
9
|
|
10
|
-
from maps4fs.generator.
|
10
|
+
from maps4fs.generator.background import Background
|
11
|
+
from maps4fs.generator.component.base.component import Component
|
11
12
|
from maps4fs.generator.dtm.dtm import DTMProvider, DTMProviderSettings
|
12
13
|
from maps4fs.generator.game import Game
|
13
14
|
from maps4fs.generator.settings import (
|
@@ -20,6 +21,7 @@ from maps4fs.generator.settings import (
|
|
20
21
|
SplineSettings,
|
21
22
|
TextureSettings,
|
22
23
|
)
|
24
|
+
from maps4fs.generator.texture import Texture
|
23
25
|
from maps4fs.logger import Logger
|
24
26
|
|
25
27
|
|
@@ -236,6 +238,44 @@ class Map:
|
|
236
238
|
return component
|
237
239
|
return None
|
238
240
|
|
241
|
+
def get_texture_component(self) -> Texture | None:
|
242
|
+
"""Get texture component.
|
243
|
+
|
244
|
+
Returns:
|
245
|
+
Texture | None: Texture instance or None if not found.
|
246
|
+
"""
|
247
|
+
component = self.get_component("Texture")
|
248
|
+
if not isinstance(component, Texture):
|
249
|
+
return None
|
250
|
+
return component
|
251
|
+
|
252
|
+
def get_background_component(self) -> Background | None:
|
253
|
+
"""Get background component.
|
254
|
+
|
255
|
+
Returns:
|
256
|
+
Background | None: Background instance or None if not found.
|
257
|
+
"""
|
258
|
+
component = self.get_component("Background")
|
259
|
+
if not isinstance(component, Background):
|
260
|
+
return None
|
261
|
+
return component
|
262
|
+
|
263
|
+
def get_texture_layer(self, by_usage: str | None = None) -> Texture.Layer | None:
|
264
|
+
"""Get texture layer by usage.
|
265
|
+
|
266
|
+
Arguments:
|
267
|
+
by_usage (str, optional): Texture usage.
|
268
|
+
|
269
|
+
Returns:
|
270
|
+
Texture.Layer | None: Texture layer instance or None if not found.
|
271
|
+
"""
|
272
|
+
texture_component = self.get_texture_component()
|
273
|
+
if not texture_component:
|
274
|
+
return None
|
275
|
+
if by_usage:
|
276
|
+
return texture_component.get_layer_by_usage(by_usage)
|
277
|
+
return None
|
278
|
+
|
239
279
|
def previews(self) -> list[str]:
|
240
280
|
"""Get list of preview images.
|
241
281
|
|
maps4fs/generator/satellite.py
CHANGED
@@ -7,7 +7,7 @@ import cv2
|
|
7
7
|
from pygmdl import save_image # type: ignore
|
8
8
|
|
9
9
|
from maps4fs.generator.background import DEFAULT_DISTANCE
|
10
|
-
from maps4fs.generator.component import Component
|
10
|
+
from maps4fs.generator.component.base.component import Component
|
11
11
|
from maps4fs.generator.texture import PREVIEW_MAXIMUM_SIZE
|
12
12
|
|
13
13
|
|
@@ -65,7 +65,6 @@ class Satellite(Component):
|
|
65
65
|
self.logger.error(f"Failed to download satellite image: {e}")
|
66
66
|
continue
|
67
67
|
|
68
|
-
# pylint: disable=no-member
|
69
68
|
def previews(self) -> list[str]:
|
70
69
|
"""Returns the paths to the preview images.
|
71
70
|
|
maps4fs/generator/settings.py
CHANGED
@@ -7,6 +7,16 @@ from typing import Any
|
|
7
7
|
from pydantic import BaseModel, ConfigDict
|
8
8
|
|
9
9
|
|
10
|
+
class Parameters:
|
11
|
+
"""Simple class to store string constants for parameters."""
|
12
|
+
|
13
|
+
FIELD = "field"
|
14
|
+
FIELDS = "fields"
|
15
|
+
TEXTURES = "textures"
|
16
|
+
FOREST = "forest"
|
17
|
+
ROADS_POLYLINES = "roads_polylines"
|
18
|
+
|
19
|
+
|
10
20
|
class SharedSettings(BaseModel):
|
11
21
|
"""Represents the shared settings for all components."""
|
12
22
|
|
@@ -147,6 +157,7 @@ class I3DSettings(SettingsModel):
|
|
147
157
|
"""
|
148
158
|
|
149
159
|
forest_density: int = 10
|
160
|
+
trees_relative_shift: int = 20
|
150
161
|
|
151
162
|
|
152
163
|
class TextureSettings(SettingsModel):
|
maps4fs/generator/texture.py
CHANGED
@@ -18,7 +18,7 @@ import shapely.geometry # type: ignore
|
|
18
18
|
from shapely.geometry.base import BaseGeometry # type: ignore
|
19
19
|
from tqdm import tqdm
|
20
20
|
|
21
|
-
from maps4fs.generator.component import Component
|
21
|
+
from maps4fs.generator.component.base.component import Component
|
22
22
|
|
23
23
|
PREVIEW_MAXIMUM_SIZE = 2048
|
24
24
|
|
@@ -277,7 +277,6 @@ class Texture(Component):
|
|
277
277
|
self.dissolve()
|
278
278
|
self.copy_procedural()
|
279
279
|
|
280
|
-
# pylint: disable=no-member
|
281
280
|
def add_borders(self) -> None:
|
282
281
|
"""Iterates over all the layers and picks the one which have the border propety defined.
|
283
282
|
Borders are distance from the edge of the map on each side (top, right, bottom, left).
|
@@ -330,7 +329,7 @@ class Texture(Component):
|
|
330
329
|
if not os.path.isfile(blockmask_path):
|
331
330
|
self.logger.debug("BLOCKMASK.png not found, creating an empty file.")
|
332
331
|
img = np.zeros((self.map_size, self.map_size), dtype=np.uint8)
|
333
|
-
cv2.imwrite(blockmask_path, img)
|
332
|
+
cv2.imwrite(blockmask_path, img)
|
334
333
|
|
335
334
|
pg_layers_by_type = defaultdict(list)
|
336
335
|
for layer in self.layers:
|
@@ -353,7 +352,7 @@ class Texture(Component):
|
|
353
352
|
# pylint: disable=E1101
|
354
353
|
texture = cv2.imread(texture_path, cv2.IMREAD_UNCHANGED)
|
355
354
|
merged_texture[texture == 255] = 255
|
356
|
-
cv2.imwrite(procedural_save_path, merged_texture)
|
355
|
+
cv2.imwrite(procedural_save_path, merged_texture)
|
357
356
|
self.logger.debug(
|
358
357
|
"Procedural file %s merged from %s textures.",
|
359
358
|
procedural_save_path,
|
@@ -441,7 +440,7 @@ class Texture(Component):
|
|
441
440
|
|
442
441
|
for filepath in filepaths:
|
443
442
|
img = np.zeros(size, dtype=np.uint8)
|
444
|
-
cv2.imwrite(filepath, img)
|
443
|
+
cv2.imwrite(filepath, img)
|
445
444
|
|
446
445
|
@property
|
447
446
|
def layers(self) -> list[Layer]:
|
@@ -476,7 +475,7 @@ class Texture(Component):
|
|
476
475
|
),
|
477
476
|
)
|
478
477
|
|
479
|
-
# pylint: disable=
|
478
|
+
# pylint: disable = R0912
|
480
479
|
def draw(self) -> None:
|
481
480
|
"""Iterates over layers and fills them with polygons from OSM data."""
|
482
481
|
layers = self.layers_by_priority()
|
@@ -845,7 +844,6 @@ class Texture(Component):
|
|
845
844
|
preview_paths.append(self._osm_preview())
|
846
845
|
return preview_paths
|
847
846
|
|
848
|
-
# pylint: disable=no-member
|
849
847
|
def _osm_preview(self) -> str:
|
850
848
|
"""Merges layers into one image and saves it into the png file.
|
851
849
|
|
maps4fs/toolbox/background.py
CHANGED
@@ -22,9 +22,7 @@ def plane_from_np(
|
|
22
22
|
will result in a simpler mesh.
|
23
23
|
save_path (str) -- The path to save the obj file.
|
24
24
|
"""
|
25
|
-
dem_data = cv2.resize(
|
26
|
-
dem_data, (0, 0), fx=resize_factor, fy=resize_factor
|
27
|
-
)
|
25
|
+
dem_data = cv2.resize(dem_data, (0, 0), fx=resize_factor, fy=resize_factor)
|
28
26
|
|
29
27
|
# Invert the height values.
|
30
28
|
dem_data = dem_data.max() - dem_data
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: maps4fs
|
3
|
-
Version: 1.8.
|
3
|
+
Version: 1.8.12
|
4
4
|
Summary: Generate map templates for Farming Simulator from real places.
|
5
5
|
Author-email: iwatkot <iwatkot@gmail.com>
|
6
6
|
License: MIT License
|
@@ -611,6 +611,8 @@ You can also apply some advanced settings to the map generation process.<br>
|
|
611
611
|
|
612
612
|
- Forest density - the density of the forest in meters. The lower the value, the lower the distance between the trees, which makes the forest denser. Note, that low values will lead to enormous number of trees, which may cause the Giants Editor to crash or lead to performance issues. By default, it's set to 10.
|
613
613
|
|
614
|
+
- Trees relative shift - represents the maximum possible shift of the tree from it's original position in percents of the forest density value. The higher the value, the more the trees will be shifted from their original positions. Warning: higher values can lead to overlapping trees.
|
615
|
+
|
614
616
|
### Texture Advanced settings
|
615
617
|
|
616
618
|
- Dissolve - if enabled, the values from one layer will be splitted between different layers of texture, making it look more natural. Warning: it's a time-consuming process, recommended to enable it, when you generating the final version of the map, not some test versions.
|
@@ -1,18 +1,21 @@
|
|
1
1
|
maps4fs/__init__.py,sha256=_KfKq_ppTfHH6N7yLHTPjYc0QP2AG1HT8BfYTR9SMJE,853
|
2
2
|
maps4fs/logger.py,sha256=B-NEYpMjPAAqlV4VpfTi6nbBFnEABVtQOaYe6nMpidg,1489
|
3
3
|
maps4fs/generator/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
|
4
|
-
maps4fs/generator/background.py,sha256=
|
5
|
-
maps4fs/generator/
|
6
|
-
maps4fs/generator/
|
7
|
-
maps4fs/generator/
|
8
|
-
maps4fs/generator/
|
9
|
-
maps4fs/generator/grle.py,sha256=wWYzi7tqYy5f1CVbYyk2T92nJJntahtV7wSsVnrEgqM,21181
|
10
|
-
maps4fs/generator/i3d.py,sha256=o90zZU1dEzOaBzgrt2C6ymlYIsI8i2Oicqafz7TC1mo,25148
|
11
|
-
maps4fs/generator/map.py,sha256=a50KQEr1XZKjS_WKXywGwh4OC3gyjY6M8FTc0eNcxpg,10183
|
4
|
+
maps4fs/generator/background.py,sha256=p6rciVwGXgmx7o_LoeugjqUY6JLqVdaID9vt33W9Seg,24774
|
5
|
+
maps4fs/generator/dem.py,sha256=RsIaL3LabYnZzow2fzmccsnzBo0m1YjcVVxUkJJGJMU,10735
|
6
|
+
maps4fs/generator/game.py,sha256=zpS6PDd4Nej_VgpncVBeIhEFkAAyXYAD4Pgj-b_sLbQ,9196
|
7
|
+
maps4fs/generator/grle.py,sha256=5bWTTVSYHr2wKbuynYdz6IGYZFD-dlbZBErDPCZ8NQ8,20726
|
8
|
+
maps4fs/generator/map.py,sha256=ataDN-Hsx3XlHdisrLBZbP7q1aKFDaSXG939MEGsiE4,11513
|
12
9
|
maps4fs/generator/qgis.py,sha256=Es8hLuqN_KH8lDfnJE6He2rWYbAKJ3RGPn-o87S6CPI,6116
|
13
|
-
maps4fs/generator/satellite.py,sha256=
|
14
|
-
maps4fs/generator/settings.py,sha256=
|
15
|
-
maps4fs/generator/texture.py,sha256=
|
10
|
+
maps4fs/generator/satellite.py,sha256=jeKZ1IC5kReewDBDIxGzQc11UaGceysyh_XAOxw6JO0,3644
|
11
|
+
maps4fs/generator/settings.py,sha256=rzXOJi6d6GY7GMWZ5SYwKQoih_qcZKkYAuVwiyPMyjo,5917
|
12
|
+
maps4fs/generator/texture.py,sha256=VEmbjTpv-asnQs7yo2pSjvE-jJI8zOFisnNGRbAsQVk,36432
|
13
|
+
maps4fs/generator/component/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
|
14
|
+
maps4fs/generator/component/config.py,sha256=RitKgFDZPzjA1fi8GcEi1na75qqaueUvpcITHjBvCXc,3674
|
15
|
+
maps4fs/generator/component/i3d.py,sha256=3x38yL-kSJ8ylBwICBb6wPYzRSky4gVj8XCk2jzYSeo,19861
|
16
|
+
maps4fs/generator/component/base/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
|
17
|
+
maps4fs/generator/component/base/component.py,sha256=U3XJae0GUvHN08psv2j24Y4PBAAytSkSK3AmD-VjjXE,21404
|
18
|
+
maps4fs/generator/component/base/component_xml.py,sha256=DLSUobR0GtVCdBWOCwZ9VLJv5vY9da5l4fzp86W8QhE,3446
|
16
19
|
maps4fs/generator/dtm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
20
|
maps4fs/generator/dtm/bavaria.py,sha256=7njrEvSCYAC8ZVyvS-_84iXHhWA0oHKrEqSzxdnZuGs,4293
|
18
21
|
maps4fs/generator/dtm/dtm.py,sha256=tbYPlpDbFS374ywHrYIJwRflRRzGzi7M5mmcVqwCYBw,22880
|
@@ -26,11 +29,11 @@ maps4fs/generator/dtm/utils.py,sha256=I-wUSA_J85Xbt8sZCZAVKHSIcrMj5Ng-0adtPVhVmk
|
|
26
29
|
maps4fs/generator/dtm/base/wcs.py,sha256=3Irnk9eJPsuRXe1GNpnEK4sWlbpPSJIJUT1V2W-qpKo,2278
|
27
30
|
maps4fs/generator/dtm/base/wms.py,sha256=tevNGOf9VgGYBtc1TTd_oXWHLjU-nLowTIG8QShWDA0,2197
|
28
31
|
maps4fs/toolbox/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
|
29
|
-
maps4fs/toolbox/background.py,sha256=
|
32
|
+
maps4fs/toolbox/background.py,sha256=ym9a6TjZpRC2ButAUaQ_rwhOEuAo2ScwUQsXdJrV_Hs,2111
|
30
33
|
maps4fs/toolbox/custom_osm.py,sha256=X6ZlPqiOhNjkmdD_qVroIfdOl9Rb90cDwVSLDVYgx80,1892
|
31
34
|
maps4fs/toolbox/dem.py,sha256=z9IPFNmYbjiigb3t02ZenI3Mo8odd19c5MZbjDEovTo,3525
|
32
|
-
maps4fs-1.8.
|
33
|
-
maps4fs-1.8.
|
34
|
-
maps4fs-1.8.
|
35
|
-
maps4fs-1.8.
|
36
|
-
maps4fs-1.8.
|
35
|
+
maps4fs-1.8.12.dist-info/LICENSE.md,sha256=pTKD_oUexcn-yccFCTrMeLkZy0ifLRa-VNcDLqLZaIw,10749
|
36
|
+
maps4fs-1.8.12.dist-info/METADATA,sha256=CYg5s5X_QicDgtaC7_2u0E56TESJ7Hf3UtMCKUDIWbI,42156
|
37
|
+
maps4fs-1.8.12.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
38
|
+
maps4fs-1.8.12.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
|
39
|
+
maps4fs-1.8.12.dist-info/RECORD,,
|