thyra 3.2.0__tar.gz → 3.2.2__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.
- {thyra-3.2.0 → thyra-3.2.2}/PKG-INFO +1 -1
- {thyra-3.2.0 → thyra-3.2.2}/pyproject.toml +1 -1
- {thyra-3.2.0 → thyra-3.2.2}/thyra/__init__.py +1 -1
- {thyra-3.2.0 → thyra-3.2.2}/thyra/converters/spatialdata/base_spatialdata_converter.py +53 -52
- {thyra-3.2.0 → thyra-3.2.2}/thyra/converters/spatialdata/spatialdata_2d_converter.py +1 -3
- {thyra-3.2.0 → thyra-3.2.2}/thyra/converters/spatialdata/spatialdata_3d_converter.py +1 -3
- {thyra-3.2.0 → thyra-3.2.2}/thyra/converters/spatialdata/streaming_converter.py +18 -10
- {thyra-3.2.0 → thyra-3.2.2}/LICENSE +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/README.md +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/__main__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/alignment/__init__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/alignment/affine.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/alignment/teaching_points.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/config.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/convert.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/converters/__init__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/converters/spatialdata/__init__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/converters/spatialdata/_chunking.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/converters/spatialdata/converter.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/core/__init__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/core/base_converter.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/core/base_extractor.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/core/base_reader.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/core/registry.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/metadata/__init__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/metadata/extractors/__init__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/metadata/extractors/bruker_extractor.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/metadata/extractors/imzml_extractor.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/metadata/extractors/waters_extractor.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/metadata/ontology/__init__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/metadata/ontology/_ims.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/metadata/ontology/_ms.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/metadata/ontology/_uo.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/metadata/ontology/cache.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/metadata/types.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/metadata/validator.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/preview.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/__init__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/__init__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/base_bruker_reader.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/folder_structure.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/mis_parser.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/rapiflex/__init__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/rapiflex/rapiflex_reader.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/timstof/__init__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/timstof/sdk/__init__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/timstof/sdk/dll/LICENCE-BRUKER.txt +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/timstof/sdk/dll/README.md +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/timstof/sdk/dll/timsdata.dll +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/timstof/sdk/dll/timsdata.so +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/timstof/sdk/dll_manager.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/timstof/sdk/platform_detector.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/timstof/sdk/sdk_functions.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/timstof/timstof_reader.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/timstof/utils/__init__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/timstof/utils/batch_processor.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/timstof/utils/coordinate_cache.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/timstof/utils/mass_axis_builder.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/bruker/timstof/utils/memory_manager.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/imzml/__init__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/imzml/imzml_reader.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/waters/__init__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/waters/imaging_grid.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/waters/lib/MLReader.dll +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/waters/lib/MassLynxRaw.dll +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/waters/lib/libMLReader.so +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/waters/lib/libMassLynxRaw.so +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/waters/masslynx_lib.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/readers/waters/waters_reader.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/resampling/__init__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/resampling/common_axis.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/resampling/constants.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/resampling/data_characteristics.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/resampling/decision_tree.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/resampling/gaps.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/resampling/instrument_detectors.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/resampling/mass_axis/__init__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/resampling/mass_axis/base_generator.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/resampling/mass_axis/fticr_generator.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/resampling/mass_axis/linear_generator.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/resampling/mass_axis/linear_tof_generator.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/resampling/mass_axis/orbitrap_generator.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/resampling/mass_axis/reflector_tof_generator.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/resampling/strategies/__init__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/resampling/strategies/base.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/resampling/strategies/nearest_neighbor.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/resampling/strategies/tic_preserving.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/resampling/tic.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/resampling/types.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/tools/__init__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/tools/check_ontology.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/tools/make_example_data.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/utils/__init__.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/utils/bruker_exceptions.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/utils/logging_config.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/utils/windows_paths.py +0 -0
- {thyra-3.2.0 → thyra-3.2.2}/thyra/utils/zarr_atomic_write.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
|
|
|
4
4
|
|
|
5
5
|
[tool.poetry]
|
|
6
6
|
name = "thyra"
|
|
7
|
-
version = "3.2.
|
|
7
|
+
version = "3.2.2"
|
|
8
8
|
description = "A modern Python library for converting Mass Spectrometry Imaging (MSI) data into SpatialData/Zarr format - your portal to spatial omics"
|
|
9
9
|
authors = ["Theodoros Visvikis <t.visvikis@maastrichtuniversity.nl>"]
|
|
10
10
|
maintainers = ["Theodoros Visvikis <t.visvikis@maastrichtuniversity.nl>"]
|
|
@@ -151,7 +151,7 @@ try:
|
|
|
151
151
|
import xarray as xr
|
|
152
152
|
import zarr
|
|
153
153
|
from anndata import AnnData
|
|
154
|
-
from shapely.geometry import
|
|
154
|
+
from shapely.geometry import box
|
|
155
155
|
from spatialdata import SpatialData
|
|
156
156
|
from spatialdata.models import Image2DModel, ShapesModel, TableModel
|
|
157
157
|
from spatialdata.transformations import Affine, Identity, Scale, Sequence
|
|
@@ -1509,48 +1509,63 @@ class BaseSpatialDataConverter(BaseMSIConverter, ABC):
|
|
|
1509
1509
|
|
|
1510
1510
|
coo_arrays["current_idx"] = end_idx
|
|
1511
1511
|
|
|
1512
|
-
def _create_pixel_shapes(
|
|
1513
|
-
self, adata: AnnData, is_3d: bool = False
|
|
1514
|
-
) -> "ShapesModel":
|
|
1512
|
+
def _create_pixel_shapes(self, adata: AnnData) -> "ShapesModel":
|
|
1515
1513
|
"""Create geometric shapes for pixels with proper transformations.
|
|
1516
1514
|
|
|
1517
1515
|
When optical alignment is available (FlexImaging with Area definitions),
|
|
1518
1516
|
shapes are created in optical image pixel coordinates for proper overlay.
|
|
1519
1517
|
Otherwise, shapes use physical (micrometer) coordinates.
|
|
1520
1518
|
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1519
|
+
**Footprints are two-dimensional, including on a multi-slice
|
|
1520
|
+
volume.** A slice's depth is carried by the TIC image's ``Scale``
|
|
1521
|
+
and by ``obs["spatial_z"]``; it is deliberately not also put on
|
|
1522
|
+
the polygon geometry.
|
|
1523
|
+
|
|
1524
|
+
Three options were measured. All three are imperfect, so what
|
|
1525
|
+
follows is the reasoning rather than a claim that this one is
|
|
1526
|
+
free:
|
|
1527
|
+
|
|
1528
|
+
* **``POLYGON Z``** -- geometrically the most honest, and what
|
|
1529
|
+
7317792 shipped in v3.2.0. It breaks ``spatialdata``'s spatial
|
|
1530
|
+
queries: measured on a 5x3x2 volume, a bounding box enclosing
|
|
1531
|
+
the whole dataset with 1000um of margin returned 26 of 30
|
|
1532
|
+
footprints and 26 of 30 table rows, with no exception and no
|
|
1533
|
+
warning. ``shapely.force_2d`` on the same geometry restored
|
|
1534
|
+
30 of 30. A z-restricted query returned the same rows whether
|
|
1535
|
+
z was inside or far outside the data, so z is ignored by the
|
|
1536
|
+
query path rather than honoured.
|
|
1529
1537
|
* **Flat 2D shapes carrying the depth in a transformation**
|
|
1530
|
-
(one element per slice, each with a ``Translation`` in z).
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
* **
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
in.
|
|
1538
|
+
(one element per slice, each with a ``Translation`` in z).
|
|
1539
|
+
The element parses, coexists with a 3D image and round-trips,
|
|
1540
|
+
but the transform **silently drops z** and every slice comes
|
|
1541
|
+
back at the same depth -- a depth in the metadata that never
|
|
1542
|
+
reaches the geometry. ``test_3d_pixel_shapes_z.py`` pins this,
|
|
1543
|
+
because it is the change someone will otherwise propose.
|
|
1544
|
+
* **Flat, with the depth on the image and in ``obs`` only** --
|
|
1545
|
+
what this does.
|
|
1546
|
+
|
|
1547
|
+
The deciding argument is that ``spatialdata`` itself asks for
|
|
1548
|
+
this. ``ShapesModel.validate`` warns that a 3-dimensional
|
|
1549
|
+
geometry column "could led to unexpected behaviors" and names
|
|
1550
|
+
``force_2d()`` as the remedy; the query result above is that
|
|
1551
|
+
behaviour. 3D shapes are not on the upstream roadmap
|
|
1552
|
+
(scverse/spatialdata#109 has been idle since June 2023 and
|
|
1553
|
+
covers images, labels and transformations only), and the live
|
|
1554
|
+
2.5D discussion (#961) scopes itself to points, images and
|
|
1555
|
+
labels. Serial-section MSI is 2.5D in that taxonomy.
|
|
1556
|
+
|
|
1557
|
+
What this costs: ``docs/coordinate-systems.md``'s promise that
|
|
1558
|
+
every element agrees at ``"global"`` is exact in x and y and
|
|
1559
|
+
silent in z for the shapes element. That is a documented gap
|
|
1560
|
+
rather than a wrong answer, which a truncated query is not. See
|
|
1561
|
+
``docs/output-format.md`` for the consumer-facing statement.
|
|
1562
|
+
|
|
1563
|
+
Reinstating z means restoring the ``is_3d`` parameter at all
|
|
1564
|
+
three call sites as well; it was removed with the geometry so it
|
|
1565
|
+
could not sit unread, which is how the original defect arose.
|
|
1548
1566
|
|
|
1549
1567
|
Args:
|
|
1550
1568
|
adata: AnnData object containing coordinates
|
|
1551
|
-
is_3d: Whether this is the 3D volume route. Combined with
|
|
1552
|
-
:attr:`_is_volume` (which also requires more than one
|
|
1553
|
-
plane), decides whether footprints carry z.
|
|
1554
1569
|
|
|
1555
1570
|
Returns:
|
|
1556
1571
|
SpatialData shapes model
|
|
@@ -1628,29 +1643,15 @@ class BaseSpatialDataConverter(BaseMSIConverter, ABC):
|
|
|
1628
1643
|
y_coords: NDArray[np.float64] = adata.obs["spatial_y"].values
|
|
1629
1644
|
half_pixel_um = self.pixel_size_um / 2
|
|
1630
1645
|
|
|
1631
|
-
#
|
|
1632
|
-
#
|
|
1633
|
-
#
|
|
1634
|
-
#
|
|
1635
|
-
# -- the same column the table stores, which is what keeps the
|
|
1636
|
-
# two elements agreeing.
|
|
1637
|
-
z_coords: Optional[NDArray[np.float64]] = None
|
|
1638
|
-
if is_3d and self._is_volume:
|
|
1639
|
-
z_coords = adata.obs["spatial_z"].values
|
|
1640
|
-
|
|
1646
|
+
# Footprints are flat, on every route including volumes. A
|
|
1647
|
+
# slice's depth lives on the TIC image's Scale and in
|
|
1648
|
+
# obs["spatial_z"]; see the docstring for why it is not also
|
|
1649
|
+
# put on the geometry.
|
|
1641
1650
|
for i in range(len(adata)):
|
|
1642
1651
|
x, y = x_coords[i], y_coords[i]
|
|
1643
1652
|
x0, y0 = x - half_pixel_um, y - half_pixel_um
|
|
1644
1653
|
x1, y1 = x + half_pixel_um, y + half_pixel_um
|
|
1645
|
-
|
|
1646
|
-
if z_coords is None:
|
|
1647
|
-
pixel_box = box(x0, y0, x1, y1)
|
|
1648
|
-
else:
|
|
1649
|
-
z = float(z_coords[i])
|
|
1650
|
-
pixel_box = Polygon(
|
|
1651
|
-
[(x0, y0, z), (x1, y0, z), (x1, y1, z), (x0, y1, z)]
|
|
1652
|
-
)
|
|
1653
|
-
geometries.append(pixel_box)
|
|
1654
|
+
geometries.append(box(x0, y0, x1, y1))
|
|
1654
1655
|
|
|
1655
1656
|
# Create GeoDataFrame with appropriate index
|
|
1656
1657
|
if valid_indices is not None:
|
|
@@ -328,9 +328,7 @@ class SpatialData2DConverter(BaseSpatialDataConverter):
|
|
|
328
328
|
|
|
329
329
|
# Add to tables and create shapes
|
|
330
330
|
data_structures["tables"][slice_id] = table
|
|
331
|
-
data_structures["shapes"][region_key] = self._create_pixel_shapes(
|
|
332
|
-
adata, is_3d=False
|
|
333
|
-
)
|
|
331
|
+
data_structures["shapes"][region_key] = self._create_pixel_shapes(adata)
|
|
334
332
|
|
|
335
333
|
# Create TIC image for this slice
|
|
336
334
|
tic_values = slice_data["tic_values"]
|
|
@@ -246,9 +246,7 @@ class SpatialData3DConverter(BaseSpatialDataConverter):
|
|
|
246
246
|
|
|
247
247
|
# Add to tables and create shapes
|
|
248
248
|
data_structures["tables"][self.dataset_id] = table
|
|
249
|
-
data_structures["shapes"][region_key] = self._create_pixel_shapes(
|
|
250
|
-
adata, is_3d=True
|
|
251
|
-
)
|
|
249
|
+
data_structures["shapes"][region_key] = self._create_pixel_shapes(adata)
|
|
252
250
|
|
|
253
251
|
# Create TIC image
|
|
254
252
|
self._create_tic_image(data_structures)
|
|
@@ -1004,9 +1004,7 @@ class StreamingSpatialDataConverter(BaseSpatialDataConverter):
|
|
|
1004
1004
|
|
|
1005
1005
|
# Add to tables and create shapes
|
|
1006
1006
|
data_structures["tables"][slice_id] = table
|
|
1007
|
-
data_structures["shapes"][region_key] = self._create_pixel_shapes(
|
|
1008
|
-
adata, is_3d=False
|
|
1009
|
-
)
|
|
1007
|
+
data_structures["shapes"][region_key] = self._create_pixel_shapes(adata)
|
|
1010
1008
|
|
|
1011
1009
|
# Create TIC image for this slice
|
|
1012
1010
|
tic_values = slice_data["tic_values"]
|
|
@@ -1278,18 +1276,28 @@ class StreamingSpatialDataConverter(BaseSpatialDataConverter):
|
|
|
1278
1276
|
|
|
1279
1277
|
nnz = len(mz_indices)
|
|
1280
1278
|
if nnz > 0:
|
|
1281
|
-
#
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
# Accumulate for average spectrum (vectorized)
|
|
1279
|
+
# Accumulate for average spectrum (vectorized). Left
|
|
1280
|
+
# outside the bounds check to match the COO pre-scan,
|
|
1281
|
+
# which also averages over every spectrum read rather
|
|
1282
|
+
# than every spectrum stored.
|
|
1286
1283
|
np.add.at(total_intensity, mz_indices, resampled_ints)
|
|
1287
1284
|
|
|
1288
|
-
# TIC and occupancy
|
|
1289
|
-
#
|
|
1285
|
+
# Column counts, TIC and occupancy all describe a
|
|
1286
|
+
# spectrum that is going to get a row, so all three sit
|
|
1287
|
+
# behind the bounds check: a reader yielding a
|
|
1290
1288
|
# coordinate outside the declared dimensions would
|
|
1291
1289
|
# otherwise wrap round and land on an unrelated pixel.
|
|
1290
|
+
#
|
|
1291
|
+
# col_counts and total_nnz size the CSC arrays, and the
|
|
1292
|
+
# scatter pass skips exactly the spectra this rejects
|
|
1293
|
+
# (row_of_grid gives them no row). Counting them here
|
|
1294
|
+
# reserved slots nothing ever wrote: the memmap is
|
|
1295
|
+
# zero-filled, so they surfaced as explicit zeros at
|
|
1296
|
+
# row 0, out of order within their column, which is a
|
|
1297
|
+
# matrix scipy reports as non-canonical.
|
|
1292
1298
|
if 0 <= y < n_y and 0 <= x < n_x:
|
|
1299
|
+
np.add.at(col_counts, mz_indices, 1)
|
|
1300
|
+
total_nnz += nnz
|
|
1293
1301
|
tic_values[y, x] = resampled_ints.sum()
|
|
1294
1302
|
occupancy[y * n_x + x] = True
|
|
1295
1303
|
else:
|
|
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
|
|
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
|
|
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
|