openstef 3.4.53__tar.gz → 3.4.55__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.
- {openstef-3.4.53 → openstef-3.4.55}/PKG-INFO +1 -1
- {openstef-3.4.53 → openstef-3.4.55}/openstef/data_classes/prediction_job.py +3 -1
- {openstef-3.4.53 → openstef-3.4.55}/openstef/enums.py +7 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/feature_engineering/apply_features.py +4 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/feature_engineering/feature_applicator.py +4 -2
- openstef-3.4.55/openstef/feature_engineering/rolling_features.py +43 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/regressors/linear_quantile.py +1 -1
- {openstef-3.4.53 → openstef-3.4.55}/openstef/tasks/create_components_forecast.py +1 -1
- {openstef-3.4.53 → openstef-3.4.55}/openstef/tasks/create_forecast.py +7 -2
- {openstef-3.4.53 → openstef-3.4.55}/openstef/tasks/train_model.py +1 -1
- {openstef-3.4.53 → openstef-3.4.55}/openstef/validation/validation.py +3 -3
- {openstef-3.4.53 → openstef-3.4.55}/openstef.egg-info/PKG-INFO +1 -1
- {openstef-3.4.53 → openstef-3.4.55}/openstef.egg-info/SOURCES.txt +1 -0
- {openstef-3.4.53 → openstef-3.4.55}/setup.py +1 -1
- {openstef-3.4.53 → openstef-3.4.55}/LICENSE +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/README.md +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/__init__.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/__main__.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/app_settings.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/data/NL_terrestrial_radiation.csv +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/data/NL_terrestrial_radiation.csv.license +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/data/dazls_model_3.4.24/dazls_stored_3.4.24_baseline_model.z +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/data/dazls_model_3.4.24/dazls_stored_3.4.24_baseline_model.z.license +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/data/dazls_model_3.4.24/dazls_stored_3.4.24_model_card.md +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/data/dazls_model_3.4.24/dazls_stored_3.4.24_model_card.md.license +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/data/dutch_holidays.csv +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/data/dutch_holidays.csv.license +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/data/pv_single_coefs.csv +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/data/pv_single_coefs.csv.license +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/data_classes/__init__.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/data_classes/data_prep.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/data_classes/model_specifications.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/data_classes/split_function.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/exceptions.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/feature_engineering/__init__.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/feature_engineering/bidding_zone_to_country_mapping.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/feature_engineering/cyclic_features.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/feature_engineering/data_preparation.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/feature_engineering/feature_adder.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/feature_engineering/general.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/feature_engineering/holiday_features.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/feature_engineering/lag_features.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/feature_engineering/missing_values_transformer.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/feature_engineering/weather_features.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/metrics/__init__.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/metrics/figure.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/metrics/metrics.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/metrics/reporter.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/__init__.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/basecase.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/confidence_interval_applicator.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/fallback.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/metamodels/__init__.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/metamodels/feature_clipper.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/metamodels/grouped_regressor.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/metamodels/missing_values_handler.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/model_creator.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/objective.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/objective_creator.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/regressors/__init__.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/regressors/arima.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/regressors/custom_regressor.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/regressors/dazls.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/regressors/flatliner.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/regressors/gblinear_quantile.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/regressors/lgbm.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/regressors/linear.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/regressors/regressor.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/regressors/xgb.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/regressors/xgb_multioutput_quantile.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/regressors/xgb_quantile.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/serializer.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model/standard_deviation_generator.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model_selection/__init__.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/model_selection/model_selection.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/monitoring/__init__.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/monitoring/performance_meter.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/monitoring/teams.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/pipeline/__init__.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/pipeline/create_basecase_forecast.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/pipeline/create_component_forecast.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/pipeline/create_forecast.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/pipeline/optimize_hyperparameters.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/pipeline/train_create_forecast_backtest.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/pipeline/train_model.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/pipeline/utils.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/postprocessing/__init__.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/postprocessing/postprocessing.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/preprocessing/__init__.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/preprocessing/preprocessing.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/settings.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/tasks/__init__.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/tasks/calculate_kpi.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/tasks/create_basecase_forecast.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/tasks/create_solar_forecast.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/tasks/create_wind_forecast.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/tasks/optimize_hyperparameters.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/tasks/split_forecast.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/tasks/utils/__init__.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/tasks/utils/dependencies.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/tasks/utils/predictionjobloop.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/tasks/utils/taskcontext.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef/validation/__init__.py +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef.egg-info/dependency_links.txt +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef.egg-info/requires.txt +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/openstef.egg-info/top_level.txt +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/pyproject.toml +0 -0
- {openstef-3.4.53 → openstef-3.4.55}/setup.cfg +0 -0
@@ -9,7 +9,7 @@ from pydantic.v1 import BaseModel
|
|
9
9
|
from openstef.data_classes.data_prep import DataPrepDataClass
|
10
10
|
from openstef.data_classes.model_specifications import ModelSpecificationDataClass
|
11
11
|
from openstef.data_classes.split_function import SplitFuncDataClass
|
12
|
-
from openstef.enums import PipelineType, BiddingZone
|
12
|
+
from openstef.enums import PipelineType, BiddingZone, AggregateFunction
|
13
13
|
|
14
14
|
|
15
15
|
class PredictionJobDataClass(BaseModel):
|
@@ -83,6 +83,8 @@ class PredictionJobDataClass(BaseModel):
|
|
83
83
|
data_balancing_ratio: Optional[float] = None
|
84
84
|
"""If data balancing is enabled, the data will be balanced with data from 1 year
|
85
85
|
ago in the future."""
|
86
|
+
rolling_aggregate_features: Optional[list[AggregateFunction]] = None
|
87
|
+
"""If not None, rolling aggregate(s) of load will be used as features in the model."""
|
86
88
|
depends_on: Optional[list[Union[int, str]]]
|
87
89
|
"""Link to another prediction job on which this prediction job might depend."""
|
88
90
|
sid: Optional[str]
|
@@ -108,6 +108,13 @@ class BiddingZone(Enum):
|
|
108
108
|
DE_AMP_LU = "DE_AMP_LU"
|
109
109
|
|
110
110
|
|
111
|
+
class AggregateFunction(Enum):
|
112
|
+
MEAN = "mean"
|
113
|
+
MEDIAN = "median"
|
114
|
+
MAX = "max"
|
115
|
+
MIN = "min"
|
116
|
+
|
117
|
+
|
111
118
|
class ModelType(Enum):
|
112
119
|
XGB = "xgb"
|
113
120
|
XGB_QUANTILE = "xgb_quantile"
|
@@ -22,6 +22,7 @@ from openstef.feature_engineering.lag_features import generate_lag_feature_funct
|
|
22
22
|
from openstef.feature_engineering.bidding_zone_to_country_mapping import (
|
23
23
|
BIDDING_ZONE_TO_COUNTRY_CODE_MAPPING,
|
24
24
|
)
|
25
|
+
from openstef.feature_engineering.rolling_features import add_rolling_aggregate_features
|
25
26
|
from openstef.feature_engineering.weather_features import (
|
26
27
|
add_additional_solar_features,
|
27
28
|
add_additional_wind_features,
|
@@ -130,5 +131,8 @@ def apply_features(
|
|
130
131
|
# Adds daylight terrestrial feature
|
131
132
|
data = add_daylight_terrestrial_feature(data)
|
132
133
|
|
134
|
+
if pj.get("rolling_aggregate_features") is not None:
|
135
|
+
data = add_rolling_aggregate_features(data, pj=pj)
|
136
|
+
|
133
137
|
# Return dataframe including all requested features
|
134
138
|
return data
|
@@ -24,7 +24,9 @@ from openstef.feature_engineering.general import (
|
|
24
24
|
remove_non_requested_feature_columns,
|
25
25
|
)
|
26
26
|
|
27
|
-
LATENCY_CONFIG = {
|
27
|
+
LATENCY_CONFIG = {
|
28
|
+
"day_ahead_electricity_price": 24
|
29
|
+
} # A specific latency is part of a specific feature.
|
28
30
|
|
29
31
|
|
30
32
|
class AbstractFeatureApplicator(ABC):
|
@@ -94,7 +96,7 @@ class TrainFeatureApplicator(AbstractFeatureApplicator):
|
|
94
96
|
if not specified a default location is used
|
95
97
|
latency_config: (Optional) Invalidate certain features that are not
|
96
98
|
available for a specific horizon due to data latency. Defaults to
|
97
|
-
``{"
|
99
|
+
``{"day_ahead_electricity_price": 24}``.
|
98
100
|
|
99
101
|
Returns:
|
100
102
|
Input DataFrame with an extra column for every added feature and sorted on the datetime index.
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# SPDX-FileCopyrightText: 2017-2023 Contributors to the OpenSTEF project <korte.termijn.prognoses@alliander.com> # noqa E501>
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MPL-2.0
|
4
|
+
from datetime import timedelta
|
5
|
+
|
6
|
+
import pandas as pd
|
7
|
+
|
8
|
+
from openstef.data_classes.prediction_job import PredictionJobDataClass
|
9
|
+
|
10
|
+
|
11
|
+
def add_rolling_aggregate_features(
|
12
|
+
data: pd.DataFrame,
|
13
|
+
pj: PredictionJobDataClass,
|
14
|
+
rolling_window: timedelta = timedelta(hours=24),
|
15
|
+
) -> pd.DataFrame:
|
16
|
+
"""
|
17
|
+
Adds rolling aggregate features to the input dataframe.
|
18
|
+
|
19
|
+
These features are calculated with an aggregation over a rolling window of the data.
|
20
|
+
A list of requested features is used to determine whether to add the rolling features
|
21
|
+
or not.
|
22
|
+
|
23
|
+
Args:
|
24
|
+
data: Input dataframe to which the rolling features will be added.
|
25
|
+
pj: Prediction job data.
|
26
|
+
rolling_window: Rolling window size for the aggregation.
|
27
|
+
|
28
|
+
Returns:
|
29
|
+
DataFrame with added rolling features.
|
30
|
+
"""
|
31
|
+
# Ensure the index is a DatetimeIndex
|
32
|
+
if not isinstance(data.index, pd.DatetimeIndex):
|
33
|
+
raise ValueError("The DataFrame index must be a DatetimeIndex.")
|
34
|
+
|
35
|
+
if "load" not in data.columns:
|
36
|
+
raise ValueError("The DataFrame must contain a 'load' column.")
|
37
|
+
rolling_window_load = data["load"].rolling(window=rolling_window)
|
38
|
+
|
39
|
+
for aggregate_func in pj["rolling_aggregate_features"]:
|
40
|
+
data[
|
41
|
+
f"rolling_{aggregate_func.value}_load_{rolling_window}"
|
42
|
+
] = rolling_window_load.aggregate(aggregate_func.value)
|
43
|
+
return data
|
@@ -6,7 +6,7 @@
|
|
6
6
|
This code assumes trained models are available from the persistent storage.
|
7
7
|
If these are not available run model_train.py to train all models.
|
8
8
|
To provide the prognoses the following steps are carried out:
|
9
|
-
1. Get historic training data (TDCV, Load, Weather and
|
9
|
+
1. Get historic training data (TDCV, Load, Weather and day_ahead_electricity_price price data)
|
10
10
|
2. Apply features
|
11
11
|
3. Load model
|
12
12
|
4. Make component prediction
|
@@ -6,7 +6,7 @@
|
|
6
6
|
This code assumes trained models are available from the persistent storage. If these
|
7
7
|
are not available run model_train.py to train all models.
|
8
8
|
To provide the prognoses the folowing steps are carried out:
|
9
|
-
1. Get historic training data (TDCV, Load, Weather and
|
9
|
+
1. Get historic training data (TDCV, Load, Weather and day_ahead_electricity_price price data)
|
10
10
|
2. Apply features
|
11
11
|
3. Load model
|
12
12
|
4. Make prediction
|
@@ -24,7 +24,7 @@ from datetime import datetime, timedelta
|
|
24
24
|
from pathlib import Path
|
25
25
|
|
26
26
|
from openstef.data_classes.prediction_job import PredictionJobDataClass
|
27
|
-
from openstef.enums import ModelType, PipelineType
|
27
|
+
from openstef.enums import BiddingZone, ModelType, PipelineType
|
28
28
|
from openstef.exceptions import InputDataOngoingZeroFlatlinerError
|
29
29
|
from openstef.pipeline.create_forecast import create_forecast_pipeline
|
30
30
|
from openstef.tasks.utils.predictionjobloop import PredictionJobLoop
|
@@ -82,8 +82,13 @@ def create_forecast_task(
|
|
82
82
|
location=[pj["lat"], pj["lon"]],
|
83
83
|
datetime_start=datetime_start,
|
84
84
|
datetime_end=datetime_end,
|
85
|
+
market_price=pj.electricity_bidding_zone.value,
|
85
86
|
)
|
86
87
|
|
88
|
+
# Add APX price to the input data for backward compatibility,remove this line when all models are retrained
|
89
|
+
if pj.electricity_bidding_zone == BiddingZone.NL:
|
90
|
+
input_data["APX"] = input_data["day_ahead_electricity_price"]
|
91
|
+
|
87
92
|
try:
|
88
93
|
# Make forecast with the forecast pipeline
|
89
94
|
forecast = create_forecast_pipeline(
|
@@ -4,7 +4,7 @@
|
|
4
4
|
"""This module contains the CRON job that is periodically executed to retrain the prognosis models.
|
5
5
|
|
6
6
|
For this the folowing steps are caried out:
|
7
|
-
1. Get historic training data (TDCV, Load, Weather and
|
7
|
+
1. Get historic training data (TDCV, Load, Weather and day_ahead_electricity_price price data)
|
8
8
|
2. Apply features
|
9
9
|
3. Train and Test the new model
|
10
10
|
4. Check if new model performs better than the old model
|
@@ -313,9 +313,9 @@ def calc_completeness_dataframe(
|
|
313
313
|
expected_numbers_timedelayed=value,
|
314
314
|
)
|
315
315
|
|
316
|
-
# Correct for
|
317
|
-
if "
|
318
|
-
non_na_count["
|
316
|
+
# Correct for day_ahead_electricity_price being only expected to be available up to 24h
|
317
|
+
if "day_ahead_electricity_price" in non_na_count.index:
|
318
|
+
non_na_count["day_ahead_electricity_price"] += max([len(df) - 96, 0])
|
319
319
|
|
320
320
|
completeness_per_column_dataframe = non_na_count / (len(df))
|
321
321
|
|
@@ -40,6 +40,7 @@ openstef/feature_engineering/general.py
|
|
40
40
|
openstef/feature_engineering/holiday_features.py
|
41
41
|
openstef/feature_engineering/lag_features.py
|
42
42
|
openstef/feature_engineering/missing_values_transformer.py
|
43
|
+
openstef/feature_engineering/rolling_features.py
|
43
44
|
openstef/feature_engineering/weather_features.py
|
44
45
|
openstef/metrics/__init__.py
|
45
46
|
openstef/metrics/figure.py
|
@@ -29,7 +29,7 @@ def read_long_description_from_readme():
|
|
29
29
|
|
30
30
|
setup(
|
31
31
|
name="openstef",
|
32
|
-
version="3.4.
|
32
|
+
version="3.4.55",
|
33
33
|
packages=find_packages(include=["openstef", "openstef.*"]),
|
34
34
|
description="Open short term energy forecaster",
|
35
35
|
long_description=read_long_description_from_readme(),
|
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
|
{openstef-3.4.53 → openstef-3.4.55}/openstef/feature_engineering/bidding_zone_to_country_mapping.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{openstef-3.4.53 → openstef-3.4.55}/openstef/feature_engineering/missing_values_transformer.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
|
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
|