howso-engine 65.0.2__tar.gz → 65.0.3__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.
- {howso_engine-65.0.2/howso_engine.egg-info → howso_engine-65.0.3}/PKG-INFO +1 -1
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/feature_attributes/abstract_data.py +71 -16
- {howso_engine-65.0.2 → howso_engine-65.0.3/howso_engine.egg-info}/PKG-INFO +1 -1
- {howso_engine-65.0.2 → howso_engine-65.0.3}/.coveragerc +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/.flake8 +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/.github/CODEOWNERS +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/.github/templates/version_summary.md +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/.github/workflows/build-pr.yml +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/.github/workflows/build-release.yml +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/.github/workflows/build.yml +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/.github/workflows/rebuild-requirements.yml +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/.github/workflows/version-update.yml +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/.gitignore +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/.gitmodules +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/.pylintrc +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/CONTRIBUTING.md +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/LICENSE-3RD-PARTY.txt +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/LICENSE.txt +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/MANIFEST.in +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/Makefile +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/README.md +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/bin/build.sh +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/config/latest-mt-debug-howso.yml +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/config/latest-mt-howso.yml +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/config/latest-mt-noavx-traces-howso.yml +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/config/latest-mt-traces-howso.yml +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/config/latest-st-debug-howso.yml +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/config/latest-st-howso.yml +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/config/latest-st-traces-howso.yml +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/config/powershell/Download-Tzdata.ps1 +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/config/powershell/Helper-Functions.ps1 +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/hatch.toml +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/__main__.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/__init__.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/api.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/base.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/cache.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/client.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/configuration.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/exceptions.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/feature_flags.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/pandas/__init__.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/pandas/client.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/protocols.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/schemas/__init__.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/schemas/aggregate_reaction.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/schemas/base.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/schemas/group_reaction.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/schemas/project.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/schemas/reaction.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/schemas/session.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/schemas/trainee.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/schemas/version.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/client/typing.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/direct/__init__.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/direct/_utilities.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/direct/client.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/direct/schemas/__init__.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/direct/schemas/trainee.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/engine/__init__.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/engine/client.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/engine/project.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/engine/session.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/engine/trainee.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/howso-engine/howso.caml +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/howso-engine/migrations/migrations.caml +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/howso-engine/version.json +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/scikit/__init__.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/scikit/scikit.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/__init__.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/decorators.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/fanout_features.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/feature_attributes/__init__.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/feature_attributes/base.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/feature_attributes/infer_feature_attributes.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/feature_attributes/pandas.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/feature_attributes/protocols.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/feature_attributes/relational.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/feature_attributes/serializers.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/feature_attributes/suggestions.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/feature_attributes/time_series.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/feature_attributes/warnings.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/features.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/installation_verification.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/internals.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/json_wrapper.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/locale.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/monitors.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/posix.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/random.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/reaction.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/testing.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/tokenizing.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/utilities.py +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso_engine.egg-info/SOURCES.txt +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso_engine.egg-info/dependency_links.txt +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso_engine.egg-info/entry_points.txt +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso_engine.egg-info/requires.txt +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/howso_engine.egg-info/top_level.txt +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/pyproject.toml +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/pyrightconfig.json +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/requirements-3.11-dev.txt +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/requirements-3.11.txt +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/requirements-3.12-dev.txt +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/requirements-3.12.txt +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/requirements-3.13-dev.txt +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/requirements-3.13.txt +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/requirements-3.14-dev.txt +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/requirements-3.14.txt +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/ruff.toml +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/setup.cfg +0 -0
- {howso_engine-65.0.2 → howso_engine-65.0.3}/version.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: howso-engine
|
|
3
|
-
Version: 65.0.
|
|
3
|
+
Version: 65.0.3
|
|
4
4
|
Summary: The Howso Engine™ is a natively and fully explainable ML engine, serving as an alternative to black box AI neural networks.
|
|
5
5
|
Author: Howso Incorporated
|
|
6
6
|
Author-email: support@howso.com
|
{howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/feature_attributes/abstract_data.py
RENAMED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from collections.abc import Collection, Iterable, Mapping
|
|
4
|
+
from contextlib import suppress
|
|
4
5
|
import datetime
|
|
5
6
|
from datetime import time, timedelta
|
|
6
7
|
import decimal
|
|
@@ -148,21 +149,55 @@ class InferFeatureAttributesAbstractData(InferFeatureAttributesBase):
|
|
|
148
149
|
|
|
149
150
|
return any([c['column_names'] == [feature_name] for c in uniques])
|
|
150
151
|
|
|
152
|
+
def _get_column_dtype(self, feature_name: str) -> t.Any:
|
|
153
|
+
"""
|
|
154
|
+
Return a feature's dtype, coercing a string representation to a real dtype.
|
|
155
|
+
|
|
156
|
+
Some ADCs report dtypes as their string representation. Parse those
|
|
157
|
+
with Pandas rather than NumPy: NumPy has no concept of a time zone, so
|
|
158
|
+
`np.dtype` rejects strings like "datetime64[ns, UTC]" outright. A dtype
|
|
159
|
+
left as a string makes every `DatetimeTZDtype` and `tz` check below
|
|
160
|
+
read as though the column were tz-naive, which both misclassifies a
|
|
161
|
+
tz-aware column whose first value falls at midnight as date-only and
|
|
162
|
+
drops the "%z" from its inferred format.
|
|
163
|
+
"""
|
|
164
|
+
dtype = self.data.get_column_dtype(feature_name)
|
|
165
|
+
if isinstance(dtype, str):
|
|
166
|
+
# Not every string names a dtype Pandas recognizes; leave those as-is.
|
|
167
|
+
with suppress(TypeError):
|
|
168
|
+
dtype = pd.api.types.pandas_dtype(dtype)
|
|
169
|
+
return dtype
|
|
170
|
+
|
|
171
|
+
def _is_datetime_date_only(self, feature_name: str, max_rows: int = 1000) -> bool:
|
|
172
|
+
"""
|
|
173
|
+
Return whether every sampled value of a datetime feature falls at midnight.
|
|
174
|
+
|
|
175
|
+
A date-only column deserialized into a datetime dtype carries
|
|
176
|
+
a midnight time component on every row. Deciding that from a single
|
|
177
|
+
value misreads any column that merely starts at midnight -- hourly
|
|
178
|
+
telemetry beginning at 00:00, for instance -- and silently discards its
|
|
179
|
+
time component. Scanning stops at the first value that proves the
|
|
180
|
+
column carries a time, so the common case costs one chunk at most.
|
|
181
|
+
"""
|
|
182
|
+
seen = 0
|
|
183
|
+
for chunk in self.data.yield_chunk(maintain_natural_order=True):
|
|
184
|
+
column = pd.to_datetime(chunk[feature_name], errors="coerce").dropna()
|
|
185
|
+
if column.empty:
|
|
186
|
+
continue
|
|
187
|
+
if (column != column.dt.normalize()).any():
|
|
188
|
+
return False
|
|
189
|
+
seen += len(column)
|
|
190
|
+
if seen >= max_rows:
|
|
191
|
+
break
|
|
192
|
+
# No non-null values observed: nothing indicates a time component.
|
|
193
|
+
return True
|
|
194
|
+
|
|
151
195
|
def _get_feature_type(self, feature_name: str # noqa: C901
|
|
152
196
|
) -> tuple[FeatureType | None, dict | None]:
|
|
153
197
|
# Import this here to avoid circular import
|
|
154
198
|
from howso.client.exceptions import HowsoError
|
|
155
199
|
|
|
156
|
-
dtype = self.
|
|
157
|
-
|
|
158
|
-
# Some ADCs will return the string representation of the dtype.
|
|
159
|
-
# Convert to NumPy DType so that we can access attributes like 'itemsize.'
|
|
160
|
-
if isinstance(dtype, str):
|
|
161
|
-
try:
|
|
162
|
-
dtype = np.dtype(dtype)
|
|
163
|
-
except Exception:
|
|
164
|
-
# If there is a problem, leave as-is
|
|
165
|
-
pass
|
|
200
|
+
dtype = self._get_column_dtype(feature_name)
|
|
166
201
|
try:
|
|
167
202
|
if is_float_dtype(dtype):
|
|
168
203
|
typing_info = {}
|
|
@@ -191,20 +226,40 @@ class InferFeatureAttributesAbstractData(InferFeatureAttributesBase):
|
|
|
191
226
|
return FeatureType.DATE, {}
|
|
192
227
|
# datetime64[Y/M/D] only supported by Pandas > 3.0; need more checks for date-only columns
|
|
193
228
|
first_non_null = self._get_first_non_null(feature_name)
|
|
194
|
-
if isinstance(first_non_null, datetime.date)
|
|
195
|
-
|
|
196
|
-
#
|
|
229
|
+
if (isinstance(first_non_null, datetime.date)
|
|
230
|
+
and not isinstance(first_non_null, datetime.datetime)):
|
|
231
|
+
# `datetime.datetime` subclasses `datetime.date` (and
|
|
232
|
+
# `pd.Timestamp` subclasses `datetime.datetime`), so only a
|
|
233
|
+
# value that is a date and not a datetime is strictly
|
|
234
|
+
# date-only. Excluding just `pd.Timestamp` here let the
|
|
235
|
+
# plain `datetime.datetime` objects that several connectors
|
|
236
|
+
# return be misread as dates. Datetimes fall through so
|
|
237
|
+
# their time and tzinfo are inspected below.
|
|
197
238
|
return FeatureType.DATE, {}
|
|
198
|
-
# Date-only Timestamp objects in Pandas will have a default time of
|
|
199
|
-
|
|
239
|
+
# Date-only Timestamp objects in Pandas will have a default time of
|
|
240
|
+
# midnight. Confirm that holds across the column rather than for
|
|
241
|
+
# just this one value, so a timed column that happens to start at
|
|
242
|
+
# midnight is not demoted to a date.
|
|
243
|
+
if (isinstance(first_non_null, datetime.datetime)
|
|
200
244
|
and first_non_null.time() == datetime.time(0, 0, 0)
|
|
201
245
|
and (not hasattr(dtype, "tz") or not dtype.tz)
|
|
246
|
+
and self._is_datetime_date_only(feature_name)
|
|
202
247
|
):
|
|
248
|
+
# `datetime.datetime` rather than `pd.Timestamp`: several
|
|
249
|
+
# connectors hand back plain datetimes, and testing only
|
|
250
|
+
# for Timestamp let a genuine date-only column from
|
|
251
|
+
# those sources fall through as a datetime.
|
|
203
252
|
return FeatureType.DATE, {}
|
|
204
253
|
if isinstance(dtype, pd.DatetimeTZDtype):
|
|
205
254
|
# If using a named time zone capture it, otherwise
|
|
206
255
|
# rely on the offset in the iso8601 format
|
|
207
256
|
tz_name = getattr(dtype.tz, 'key', None) or getattr(dtype.tz, 'zone', None)
|
|
257
|
+
if tz_name is None and dtype.tz is datetime.timezone.utc:
|
|
258
|
+
# Parsing a dtype *string* yields stdlib UTC, which
|
|
259
|
+
# exposes neither `key` nor `zone` the way `zoneinfo`
|
|
260
|
+
# and `pytz` zones do. It is still a named zone, unlike
|
|
261
|
+
# the fixed offsets that deliberately fall through here.
|
|
262
|
+
tz_name = 'UTC'
|
|
208
263
|
if tz_name:
|
|
209
264
|
typing_info['timezone'] = tz_name
|
|
210
265
|
return FeatureType.DATETIME, typing_info
|
|
@@ -660,7 +715,7 @@ class InferFeatureAttributesAbstractData(InferFeatureAttributesBase):
|
|
|
660
715
|
'type': 'nominal',
|
|
661
716
|
}
|
|
662
717
|
|
|
663
|
-
dtype = self.
|
|
718
|
+
dtype = self._get_column_dtype(feature_name)
|
|
664
719
|
# Pandas datetime64 columns will be deserialized to ISO8601
|
|
665
720
|
dt_format = ISO_8601_FORMAT
|
|
666
721
|
if isinstance(dtype, pd.DatetimeTZDtype):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: howso-engine
|
|
3
|
-
Version: 65.0.
|
|
3
|
+
Version: 65.0.3
|
|
4
4
|
Summary: The Howso Engine™ is a natively and fully explainable ML engine, serving as an alternative to black box AI neural networks.
|
|
5
5
|
Author: Howso Incorporated
|
|
6
6
|
Author-email: support@howso.com
|
|
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
|
{howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/feature_attributes/relational.py
RENAMED
|
File without changes
|
{howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/feature_attributes/serializers.py
RENAMED
|
File without changes
|
{howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/feature_attributes/suggestions.py
RENAMED
|
File without changes
|
{howso_engine-65.0.2 → howso_engine-65.0.3}/howso/utilities/feature_attributes/time_series.py
RENAMED
|
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
|