voxcity 0.6.21__tar.gz → 0.6.23__tar.gz
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.
Potentially problematic release.
This version of voxcity might be problematic. Click here for more details.
- {voxcity-0.6.21 → voxcity-0.6.23}/PKG-INFO +1 -1
- {voxcity-0.6.21 → voxcity-0.6.23}/pyproject.toml +1 -1
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/utils/visualization.py +175 -146
- {voxcity-0.6.21 → voxcity-0.6.23}/AUTHORS.rst +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/LICENSE +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/README.md +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/__init__.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/downloader/__init__.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/downloader/citygml.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/downloader/eubucco.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/downloader/gee.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/downloader/mbfp.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/downloader/oemj.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/downloader/osm.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/downloader/overture.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/downloader/utils.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/exporter/__init__.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/exporter/cityles.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/exporter/envimet.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/exporter/magicavoxel.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/exporter/netcdf.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/exporter/obj.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/generator.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/geoprocessor/__init__.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/geoprocessor/draw.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/geoprocessor/grid.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/geoprocessor/mesh.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/geoprocessor/network.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/geoprocessor/polygon.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/geoprocessor/utils.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/simulator/__init__.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/simulator/solar.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/simulator/utils.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/simulator/view.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/utils/__init__.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/utils/lc.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/utils/material.py +0 -0
- {voxcity-0.6.21 → voxcity-0.6.23}/src/voxcity/utils/weather.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "voxcity"
|
|
3
|
-
version = "0.6.
|
|
3
|
+
version = "0.6.23"
|
|
4
4
|
description = "voxcity is an easy and one-stop tool to output 3d city models for microclimate simulation by integrating multiple geospatial open-data"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
@@ -2386,157 +2386,180 @@ def _rgb_tuple_to_plotly_color(rgb_tuple):
|
|
|
2386
2386
|
return "rgb(128,128,128)"
|
|
2387
2387
|
|
|
2388
2388
|
|
|
2389
|
-
def
|
|
2389
|
+
def visualize_building_sim_results_plotly(
|
|
2390
2390
|
voxel_array,
|
|
2391
2391
|
meshsize,
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
opacity=None,
|
|
2395
|
-
max_dimension=128,
|
|
2396
|
-
downsample=None,
|
|
2397
|
-
title=None,
|
|
2398
|
-
width=1000,
|
|
2399
|
-
height=800,
|
|
2400
|
-
show=True,
|
|
2401
|
-
return_fig=False,
|
|
2392
|
+
building_sim_mesh,
|
|
2393
|
+
**kwargs
|
|
2402
2394
|
):
|
|
2403
2395
|
"""
|
|
2404
|
-
Interactive
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
opacity : float or dict[int,float], optional
|
|
2421
|
-
Single opacity for all classes (0-1) or per-class mapping.
|
|
2422
|
-
max_dimension : int
|
|
2423
|
-
If any axis exceeds this and downsample is None, auto downsample to keep
|
|
2424
|
-
dimensions <= max_dimension.
|
|
2425
|
-
downsample : int, optional
|
|
2426
|
-
Explicit stride for all axes (e.g., 2 renders every other voxel).
|
|
2427
|
-
title : str, optional
|
|
2396
|
+
Interactive Plotly visualization of voxels with an overlaid building simulation mesh.
|
|
2397
|
+
|
|
2398
|
+
This function reuses visualize_voxcity_plotly to render voxel cubes and adds a
|
|
2399
|
+
Plotly Mesh3d trace for a provided building simulation mesh (e.g., SVF, temperature).
|
|
2400
|
+
|
|
2401
|
+
Parameters (kwargs)
|
|
2402
|
+
-------------------
|
|
2403
|
+
classes : list[int] or None
|
|
2404
|
+
Classes to render for voxel cubes. Default: all non-zero classes present.
|
|
2405
|
+
voxel_color_map : str or dict
|
|
2406
|
+
Scheme name understood by get_voxel_color_map or explicit mapping {class_id: [R,G,B]}.
|
|
2407
|
+
downsample : int or None
|
|
2408
|
+
Stride for voxel cubes. 1 means no downsampling.
|
|
2409
|
+
cubes_opacity : float
|
|
2410
|
+
Opacity for voxel cubes (default 0.95 for buildings, 0.6 for others via function's per-class logic; here default 0.9).
|
|
2411
|
+
title : str
|
|
2428
2412
|
Figure title.
|
|
2429
2413
|
width, height : int
|
|
2430
|
-
Figure size
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2414
|
+
Figure size.
|
|
2415
|
+
value_name : str
|
|
2416
|
+
Metadata field name on building_sim_mesh storing per-face values (default 'svf_values').
|
|
2417
|
+
colormap : str
|
|
2418
|
+
Matplotlib colormap name for the simulation values (default 'viridis').
|
|
2419
|
+
vmin, vmax : float or None
|
|
2420
|
+
Value range for color mapping. If None, computed from finite values.
|
|
2421
|
+
nan_color : str
|
|
2422
|
+
Color name for NaN values (default 'gray').
|
|
2423
|
+
building_opacity : float
|
|
2424
|
+
Opacity for the simulation mesh (default 1.0).
|
|
2425
|
+
shaded : bool
|
|
2426
|
+
If True, apply lighting-based shading to the simulation mesh. Default False (unlit colors).
|
|
2427
|
+
render_voxel_buildings : bool
|
|
2428
|
+
If True, also render voxel buildings (-3) from voxcity_grid. Default False (hide voxel buildings
|
|
2429
|
+
so only simulation mesh buildings are visible).
|
|
2430
|
+
show : bool, return_fig : bool
|
|
2431
|
+
Standard display controls.
|
|
2440
2432
|
"""
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
if max_dim > max_dimension:
|
|
2454
|
-
# ceil so that max_dim/stride <= max_dimension
|
|
2455
|
-
stride = int(np.ceil(max_dim / max_dimension))
|
|
2456
|
-
|
|
2457
|
-
if stride > 1:
|
|
2458
|
-
vox = vox[::stride, ::stride, ::stride]
|
|
2459
|
-
|
|
2460
|
-
nx, ny, nz = vox.shape
|
|
2461
|
-
# Coordinate axes in meters
|
|
2462
|
-
x = np.arange(nx, dtype=float) * meshsize * stride
|
|
2463
|
-
y = np.arange(ny, dtype=float) * meshsize * stride
|
|
2464
|
-
z = np.arange(nz, dtype=float) * meshsize * stride
|
|
2465
|
-
|
|
2466
|
-
# Select default classes if not provided: render all non-zero classes present
|
|
2433
|
+
classes = kwargs.get('classes')
|
|
2434
|
+
voxel_color_map = kwargs.get('voxel_color_map', 'default')
|
|
2435
|
+
downsample = kwargs.get('downsample')
|
|
2436
|
+
title = kwargs.get('title', None)
|
|
2437
|
+
width = kwargs.get('width', 1000)
|
|
2438
|
+
height = kwargs.get('height', 800)
|
|
2439
|
+
cubes_opacity = kwargs.get('cubes_opacity', 0.9)
|
|
2440
|
+
show = kwargs.get('show', True)
|
|
2441
|
+
return_fig = kwargs.get('return_fig', False)
|
|
2442
|
+
render_voxel_buildings = kwargs.get('render_voxel_buildings', False)
|
|
2443
|
+
|
|
2444
|
+
# Determine classes for voxel cubes and exclude buildings (-3) by default
|
|
2467
2445
|
if classes is None:
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
#
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
# Skip if class not present
|
|
2501
|
-
if not np.any(vox == cls):
|
|
2502
|
-
continue
|
|
2503
|
-
|
|
2504
|
-
# Colorscale with a single color
|
|
2505
|
-
color = class_to_color.get(cls, "rgb(128,128,128)")
|
|
2506
|
-
colorscale = [[0.0, color], [1.0, color]]
|
|
2507
|
-
|
|
2508
|
-
# Use binary mask per class to ensure iso level lies strictly between 0 and 1
|
|
2509
|
-
M = (vox == cls).astype(np.uint8).ravel()
|
|
2510
|
-
|
|
2511
|
-
fig.add_trace(
|
|
2512
|
-
go.Isosurface(
|
|
2513
|
-
x=X,
|
|
2514
|
-
y=Y,
|
|
2515
|
-
z=Z,
|
|
2516
|
-
value=M,
|
|
2517
|
-
isomin=0.5,
|
|
2518
|
-
isomax=0.5001,
|
|
2519
|
-
surface_count=1,
|
|
2520
|
-
caps=dict(x_show=False, y_show=False, z_show=False),
|
|
2521
|
-
colorscale=colorscale,
|
|
2522
|
-
showscale=False,
|
|
2523
|
-
opacity=get_opacity(cls),
|
|
2524
|
-
name=str(cls),
|
|
2446
|
+
classes_all = np.unique(voxel_array[voxel_array != 0]).tolist()
|
|
2447
|
+
else:
|
|
2448
|
+
classes_all = list(classes)
|
|
2449
|
+
classes_cubes = classes_all if render_voxel_buildings else [c for c in classes_all if int(c) != -3]
|
|
2450
|
+
|
|
2451
|
+
# Render voxel cubes background (or blank scene if nothing to render)
|
|
2452
|
+
if len(classes_cubes) > 0:
|
|
2453
|
+
fig = visualize_voxcity_plotly(
|
|
2454
|
+
voxel_array,
|
|
2455
|
+
meshsize,
|
|
2456
|
+
classes=classes_cubes,
|
|
2457
|
+
voxel_color_map=voxel_color_map,
|
|
2458
|
+
opacity=cubes_opacity,
|
|
2459
|
+
downsample=downsample,
|
|
2460
|
+
title=title or "Building Simulation (Plotly)",
|
|
2461
|
+
width=width,
|
|
2462
|
+
height=height,
|
|
2463
|
+
show=False,
|
|
2464
|
+
return_fig=True,
|
|
2465
|
+
)
|
|
2466
|
+
else:
|
|
2467
|
+
fig = go.Figure()
|
|
2468
|
+
fig.update_layout(
|
|
2469
|
+
title=title or "Building Simulation (Plotly)",
|
|
2470
|
+
width=width,
|
|
2471
|
+
height=height,
|
|
2472
|
+
scene=dict(
|
|
2473
|
+
xaxis_title="X (m)",
|
|
2474
|
+
yaxis_title="Y (m)",
|
|
2475
|
+
zaxis_title="Z (m)",
|
|
2476
|
+
aspectmode="data",
|
|
2477
|
+
camera=dict(eye=dict(x=1.6, y=1.6, z=1.0)),
|
|
2525
2478
|
)
|
|
2526
2479
|
)
|
|
2527
2480
|
|
|
2528
|
-
#
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2481
|
+
# Nothing to overlay
|
|
2482
|
+
if building_sim_mesh is None or getattr(building_sim_mesh, 'vertices', None) is None:
|
|
2483
|
+
if show:
|
|
2484
|
+
fig.show()
|
|
2485
|
+
if return_fig:
|
|
2486
|
+
return fig
|
|
2487
|
+
return None
|
|
2488
|
+
|
|
2489
|
+
# Extract geometry
|
|
2490
|
+
V = np.asarray(building_sim_mesh.vertices)
|
|
2491
|
+
F = np.asarray(building_sim_mesh.faces)
|
|
2492
|
+
values = None
|
|
2493
|
+
value_name = kwargs.get('value_name', 'svf_values')
|
|
2494
|
+
if hasattr(building_sim_mesh, 'metadata') and isinstance(building_sim_mesh.metadata, dict):
|
|
2495
|
+
values = building_sim_mesh.metadata.get(value_name)
|
|
2496
|
+
if values is not None:
|
|
2497
|
+
values = np.asarray(values)
|
|
2498
|
+
|
|
2499
|
+
# Compute per-face scalar to avoid color interpolation across edges
|
|
2500
|
+
face_vals = None
|
|
2501
|
+
if values is not None and values.size == len(F):
|
|
2502
|
+
# Already per-face
|
|
2503
|
+
face_vals = values.astype(float)
|
|
2504
|
+
elif values is not None and values.size == len(V):
|
|
2505
|
+
# Average the three vertex values per face
|
|
2506
|
+
vals_v = values.astype(float)
|
|
2507
|
+
face_vals = np.nanmean(vals_v[F], axis=1)
|
|
2508
|
+
|
|
2509
|
+
# Map to colors
|
|
2510
|
+
cmap_name = kwargs.get('colormap', 'viridis')
|
|
2511
|
+
vmin = kwargs.get('vmin')
|
|
2512
|
+
vmax = kwargs.get('vmax')
|
|
2513
|
+
nan_color = kwargs.get('nan_color', 'gray')
|
|
2514
|
+
building_opacity = kwargs.get('building_opacity', 1.0)
|
|
2515
|
+
|
|
2516
|
+
facecolor = None
|
|
2517
|
+
if face_vals is not None:
|
|
2518
|
+
# Compute range
|
|
2519
|
+
finite = np.isfinite(face_vals)
|
|
2520
|
+
if vmin is None:
|
|
2521
|
+
vmin = float(np.nanmin(face_vals[finite])) if np.any(finite) else 0.0
|
|
2522
|
+
if vmax is None:
|
|
2523
|
+
vmax = float(np.nanmax(face_vals[finite])) if np.any(finite) else 1.0
|
|
2524
|
+
norm = mcolors.Normalize(vmin=vmin, vmax=vmax)
|
|
2525
|
+
cmap = cm.get_cmap(cmap_name)
|
|
2526
|
+
# Colors per face (constant on each triangle)
|
|
2527
|
+
colors_rgba = np.zeros((len(F), 4), dtype=float)
|
|
2528
|
+
colors_rgba[finite] = cmap(norm(face_vals[finite]))
|
|
2529
|
+
nan_rgba = np.array(mcolors.to_rgba(nan_color))
|
|
2530
|
+
colors_rgba[~finite] = nan_rgba
|
|
2531
|
+
facecolor = [
|
|
2532
|
+
f"rgb({int(255*c[0])},{int(255*c[1])},{int(255*c[2])})" for c in colors_rgba
|
|
2533
|
+
]
|
|
2534
|
+
|
|
2535
|
+
# Lighting (disable shading by default for true color rendering)
|
|
2536
|
+
shaded = kwargs.get('shaded', False)
|
|
2537
|
+
if shaded:
|
|
2538
|
+
lighting = dict(ambient=0.35, diffuse=1.0, specular=0.4, roughness=0.5, fresnel=0.1)
|
|
2539
|
+
flat = False
|
|
2540
|
+
else:
|
|
2541
|
+
# Unlit: make colors independent of lighting
|
|
2542
|
+
lighting = dict(ambient=1.0, diffuse=0.0, specular=0.0, roughness=0.0, fresnel=0.0)
|
|
2543
|
+
flat = False
|
|
2544
|
+
cx = float((V[:,0].min() + V[:,0].max()) * 0.5)
|
|
2545
|
+
cy = float((V[:,1].min() + V[:,1].max()) * 0.5)
|
|
2546
|
+
cz = float((V[:,2].min() + V[:,2].max()) * 0.5)
|
|
2547
|
+
lx = cx + (V[:,0].max() - V[:,0].min() + meshsize) * 0.9
|
|
2548
|
+
ly = cy + (V[:,1].max() - V[:,1].min() + meshsize) * 0.6
|
|
2549
|
+
lz = cz + (V[:,2].max() - V[:,2].min() + meshsize) * 1.4
|
|
2550
|
+
|
|
2551
|
+
fig.add_trace(
|
|
2552
|
+
go.Mesh3d(
|
|
2553
|
+
x=V[:,0], y=V[:,1], z=V[:,2],
|
|
2554
|
+
i=F[:,0], j=F[:,1], k=F[:,2],
|
|
2555
|
+
facecolor=facecolor if facecolor is not None else None,
|
|
2556
|
+
color=None if facecolor is not None else 'rgb(200,200,200)',
|
|
2557
|
+
opacity=float(building_opacity),
|
|
2558
|
+
flatshading=flat,
|
|
2559
|
+
lighting=lighting,
|
|
2560
|
+
lightposition=dict(x=lx, y=ly, z=lz),
|
|
2561
|
+
name=value_name if facecolor is not None else 'building_mesh'
|
|
2562
|
+
)
|
|
2540
2563
|
)
|
|
2541
2564
|
|
|
2542
2565
|
if show:
|
|
@@ -2545,8 +2568,7 @@ def visualize_voxcity_plotly(
|
|
|
2545
2568
|
return fig
|
|
2546
2569
|
return None
|
|
2547
2570
|
|
|
2548
|
-
|
|
2549
|
-
def visualize_voxcity_plotly_voxels(
|
|
2571
|
+
def visualize_voxcity_plotly(
|
|
2550
2572
|
voxel_array,
|
|
2551
2573
|
meshsize,
|
|
2552
2574
|
classes=None,
|
|
@@ -2565,6 +2587,8 @@ def visualize_voxcity_plotly_voxels(
|
|
|
2565
2587
|
using Plotly Mesh3d. One Mesh3d trace per class.
|
|
2566
2588
|
|
|
2567
2589
|
Parameters are similar to visualize_voxcity_plotly, but rendering is via exact cubes.
|
|
2590
|
+
voxel_color_map may be either a scheme name (str) understood by get_voxel_color_map,
|
|
2591
|
+
or a dict mapping class_id -> [R, G, B] (0-255).
|
|
2568
2592
|
"""
|
|
2569
2593
|
if voxel_array is None or getattr(voxel_array, 'ndim', 0) != 3:
|
|
2570
2594
|
raise ValueError("voxel_array must be a 3D numpy array (nx, ny, nz)")
|
|
@@ -2572,10 +2596,11 @@ def visualize_voxcity_plotly_voxels(
|
|
|
2572
2596
|
vox = voxel_array
|
|
2573
2597
|
|
|
2574
2598
|
# Downsample for performance if requested or auto-needed
|
|
2575
|
-
|
|
2576
|
-
if downsample is not None
|
|
2577
|
-
stride = int(downsample)
|
|
2599
|
+
# Respect explicit downsample even when it is 1 (no auto-downsample)
|
|
2600
|
+
if downsample is not None:
|
|
2601
|
+
stride = max(1, int(downsample))
|
|
2578
2602
|
else:
|
|
2603
|
+
stride = 1
|
|
2579
2604
|
nx, ny, nz = vox.shape
|
|
2580
2605
|
max_dim = max(nx, ny, nz)
|
|
2581
2606
|
if max_dim > max_dimension:
|
|
@@ -2600,7 +2625,11 @@ def visualize_voxcity_plotly_voxels(
|
|
|
2600
2625
|
if not classes:
|
|
2601
2626
|
raise ValueError("No classes to visualize (voxel grid may be empty)")
|
|
2602
2627
|
|
|
2603
|
-
|
|
2628
|
+
# Resolve color map: accept scheme name or explicit dict
|
|
2629
|
+
if isinstance(voxel_color_map, dict):
|
|
2630
|
+
vox_dict = voxel_color_map
|
|
2631
|
+
else:
|
|
2632
|
+
vox_dict = get_voxel_color_map(voxel_color_map)
|
|
2604
2633
|
|
|
2605
2634
|
def exposed_face_masks(occ):
|
|
2606
2635
|
# occ shape (nx, ny, nz)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|