flightdata 0.2.15__tar.gz → 0.2.16__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.
- {flightdata-0.2.15/flightdata.egg-info → flightdata-0.2.16}/PKG-INFO +4 -3
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/base/table.py +6 -2
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/flight/fields.py +1 -2
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/flight/flight.py +24 -40
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/origin.py +16 -16
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/state.py +4 -6
- {flightdata-0.2.15 → flightdata-0.2.16/flightdata.egg-info}/PKG-INFO +4 -3
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata.egg-info/requires.txt +3 -2
- {flightdata-0.2.15 → flightdata-0.2.16}/requirements-dev.txt +1 -1
- flightdata-0.2.16/requirements.txt +5 -0
- flightdata-0.2.15/requirements.txt +0 -4
- {flightdata-0.2.15 → flightdata-0.2.16}/.github/workflows/publish_pypi.yml +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/.gitignore +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/.vscode/launch.json +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/.vscode/settings.json +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/LICENSE +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/README.md +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/examples/__init__.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/examples/axis_rates.ipynb +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/examples/data/__init__.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/examples/data/manual_F3A_F23_22_04_28_00000231.json +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/examples/data/manual_F3A_P23_22_05_31_00000350.json +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/examples/data/manual_F3A_P23_23_08_11_00000094.json +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/examples/flight_data.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/examples/flight_dynamics/00000150.json +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/examples/flight_dynamics/__init__.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/examples/flight_dynamics/box.f3a +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/examples/flight_dynamics/param_id.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/examples/state_analysis/__init__.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/examples/state_analysis/axes.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/examples/state_analysis/state_fill_plot.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/__init__.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/base/__init__.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/base/collection.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/base/constructs.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/base/labeling.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/base/numpy_encoder.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/coefficients.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/environment/__init__.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/environment/environment.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/environment/wind.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/flight/__init__.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/flight/ardupilot.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/flight/parameters.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/flow.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/model/__init__.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/model/aerodynamic.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/model/thrust.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/scripts/collect_logs.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata/scripts/flightline.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata.egg-info/SOURCES.txt +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata.egg-info/dependency_links.txt +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata.egg-info/entry_points.txt +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/flightdata.egg-info/top_level.txt +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/pyproject.toml +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/setup.cfg +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/EmailedBox.f3a +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/__init__.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/base/__init__.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/base/test_base_constructs.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/base/test_table.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/conftest.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/data/make_inputs.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/data/manual_F3A_P23.json +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/data/p23.BIN +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/data/p23.json +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/data/p23_box.f3a +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/data/p23_fc.json +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/data/p23_flight.json +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/data/vtol_hover.bin +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/data/vtol_hover.json +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/test_environment/__init__.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/test_environment/test_environment.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/test_environment/test_environment_wind.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/test_fields.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/test_flight.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/test_model/__init__.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/test_model/test_model_coefficients.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/test_model/test_model_flow.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/test_origin.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/test_state/__init__.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/test_state/test_state.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/test_state/test_state_builders.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/test_state/test_state_conversions.py +0 -0
- {flightdata-0.2.15 → flightdata-0.2.16}/test/test_state/test_state_measurements.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: flightdata
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.16
|
|
4
4
|
Summary: Module for handling UAV flight log data
|
|
5
5
|
Author-email: Thomas David <thomasdavid0@gmail.com>
|
|
6
6
|
License: GNU GPL v3
|
|
@@ -11,12 +11,13 @@ License-File: LICENSE
|
|
|
11
11
|
Requires-Dist: numpy
|
|
12
12
|
Requires-Dist: pandas
|
|
13
13
|
Requires-Dist: simplejson
|
|
14
|
-
Requires-Dist: pfc-geometry>=0.2.
|
|
14
|
+
Requires-Dist: pfc-geometry>=0.2.8
|
|
15
|
+
Requires-Dist: json_stream
|
|
15
16
|
Provides-Extra: dev
|
|
16
17
|
Requires-Dist: numpy; extra == "dev"
|
|
17
18
|
Requires-Dist: pandas; extra == "dev"
|
|
18
19
|
Requires-Dist: simplejson; extra == "dev"
|
|
19
|
-
Requires-Dist: pfc-geometry>=0.2.
|
|
20
|
+
Requires-Dist: pfc-geometry>=0.2.8; extra == "dev"
|
|
20
21
|
Requires-Dist: ardupilot-log-reader>=0.3.3; extra == "dev"
|
|
21
22
|
Requires-Dist: pytest; extra == "dev"
|
|
22
23
|
|
|
@@ -69,7 +69,11 @@ class Table:
|
|
|
69
69
|
|
|
70
70
|
def __getitem__(self, sli):
|
|
71
71
|
if isinstance(sli, slice):
|
|
72
|
-
return self.__class__(self.data.loc[slice(
|
|
72
|
+
return self.__class__(self.data.loc[slice(
|
|
73
|
+
sli.start if sli.start else self.data.index[0],
|
|
74
|
+
sli.stop if sli.stop else self.data.index[-1],
|
|
75
|
+
sli.step
|
|
76
|
+
)])
|
|
73
77
|
elif isinstance(sli, Number):
|
|
74
78
|
if sli<0:
|
|
75
79
|
return self.__class__(self.data.iloc[[int(sli)], :])
|
|
@@ -87,7 +91,7 @@ class Table:
|
|
|
87
91
|
|
|
88
92
|
def __iter__(self):
|
|
89
93
|
for ind in list(self.data.index):
|
|
90
|
-
yield self[ind]
|
|
94
|
+
yield self[ind - self.data.index[0]]
|
|
91
95
|
|
|
92
96
|
|
|
93
97
|
@classmethod
|
|
@@ -14,9 +14,8 @@ from typing import Self, Union, IO
|
|
|
14
14
|
import numpy as np
|
|
15
15
|
import pandas as pd
|
|
16
16
|
from .fields import fields, Field
|
|
17
|
-
from geometry import GPS, Point
|
|
17
|
+
from geometry import GPS, Point, P0
|
|
18
18
|
from geometry.testing import assert_almost_equal
|
|
19
|
-
from pathlib import Path
|
|
20
19
|
from time import time
|
|
21
20
|
from json import load, dump
|
|
22
21
|
from flightdata.base.numpy_encoder import NumpyEncoder
|
|
@@ -240,15 +239,14 @@ class Flight:
|
|
|
240
239
|
return False
|
|
241
240
|
|
|
242
241
|
@staticmethod
|
|
243
|
-
def from_log(log:
|
|
242
|
+
def from_log(log: str, extra_types: list[str] = None, **kwargs) -> Flight:
|
|
244
243
|
"""Constructor from an ardupilot bin file."""
|
|
245
244
|
from ardupilot_log_reader.reader import Ardupilot
|
|
246
245
|
extra_types = [] if extra_types is None else extra_types
|
|
247
246
|
|
|
248
|
-
|
|
247
|
+
parser = log
|
|
248
|
+
if not isinstance(log, Ardupilot):
|
|
249
249
|
parser = Ardupilot.parse(str(log), types=list(set(Flight.ardupilot_types + extra_types)))
|
|
250
|
-
else:
|
|
251
|
-
parser = log
|
|
252
250
|
|
|
253
251
|
params = Flight.build_cols(
|
|
254
252
|
time_actual = parser.PARM.timestamp,
|
|
@@ -448,7 +446,10 @@ class Flight:
|
|
|
448
446
|
return dfs
|
|
449
447
|
|
|
450
448
|
@staticmethod
|
|
451
|
-
def parse_fcj_data(origin: Origin,
|
|
449
|
+
def parse_fcj_data(df: pd.DataFrame | dict, origin: Origin, shift: Point=None):
|
|
450
|
+
|
|
451
|
+
df = pd.DataFrame(df, dtype=float) if isinstance(df, dict) else df
|
|
452
|
+
|
|
452
453
|
df = Flight.build_cols(
|
|
453
454
|
time_actual = df['time']/1e6 + int(time()),
|
|
454
455
|
time_flight = df['time']/1e6,
|
|
@@ -464,7 +465,10 @@ class Flight:
|
|
|
464
465
|
wind_N = df['wN'] if 'wN' in df.columns else None,
|
|
465
466
|
wind_E = df['wE'] if 'wE' in df.columns else None,
|
|
466
467
|
)
|
|
467
|
-
|
|
468
|
+
shift = P0() if shift is None else shift
|
|
469
|
+
df['position_N'] = df['position_N'] + shift.x
|
|
470
|
+
df['position_E'] = df['position_E'] + shift.y
|
|
471
|
+
df['position_D'] = df['position_D'] + shift.z
|
|
468
472
|
return Flight(df.set_index('time_flight', drop=False), None, origin, 'position')
|
|
469
473
|
|
|
470
474
|
|
|
@@ -477,42 +481,22 @@ class Flight:
|
|
|
477
481
|
elif isinstance(fc_json, IO):
|
|
478
482
|
fc_json = load(f)
|
|
479
483
|
|
|
480
|
-
df = pd.DataFrame.from_dict(fc_json['data'], dtype=float)
|
|
481
|
-
|
|
482
|
-
df = Flight.build_cols(
|
|
483
|
-
time_actual = df['time']/1e6 + int(time()),
|
|
484
|
-
time_flight = df['time']/1e6,
|
|
485
|
-
attitude_roll = np.radians(df['r']),
|
|
486
|
-
attitude_pitch = np.radians(df['p']),
|
|
487
|
-
attitude_yaw = np.radians(df['yw']),
|
|
488
|
-
position_N = df['N'],
|
|
489
|
-
position_E = df['E'],
|
|
490
|
-
position_D = df['D'],
|
|
491
|
-
velocity_N = df['VN'],
|
|
492
|
-
velocity_E = df['VE'],
|
|
493
|
-
velocity_D = df['VD'],
|
|
494
|
-
wind_N = df['wN'] if 'wN' in df.columns else None,
|
|
495
|
-
wind_E = df['wE'] if 'wE' in df.columns else None,
|
|
496
|
-
)
|
|
497
|
-
|
|
498
484
|
if 'parameters' in fc_json:
|
|
499
|
-
origin = Origin(
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
float(fc_json['parameters']['pilotLng']),
|
|
504
|
-
float(fc_json['parameters']['pilotAlt'])
|
|
505
|
-
).offset(-Point(
|
|
506
|
-
fc_json['parameters']['moveNorth'],
|
|
507
|
-
fc_json['parameters']['moveEast'],
|
|
508
|
-
0,
|
|
509
|
-
)),
|
|
485
|
+
origin = Origin.from_fcjson_parameters(fc_json['parameters'])
|
|
486
|
+
shift = origin.rotation.transform_point(Point(
|
|
487
|
+
fc_json['parameters']['moveEast'],
|
|
488
|
+
-fc_json['parameters']['moveNorth'],
|
|
510
489
|
0
|
|
511
|
-
)
|
|
490
|
+
))
|
|
512
491
|
else:
|
|
513
492
|
origin = Origin('dummy_origin', GPS(0,0,0), -np.pi/2)
|
|
514
|
-
|
|
515
|
-
|
|
493
|
+
shift=P0()
|
|
494
|
+
|
|
495
|
+
return Flight.parse_fcj_data(
|
|
496
|
+
pd.DataFrame(fc_json['data'], dtype=float),
|
|
497
|
+
origin,
|
|
498
|
+
shift
|
|
499
|
+
)
|
|
516
500
|
|
|
517
501
|
def remove_time_flutter(self):
|
|
518
502
|
#I think the best option is just to take the average of the timestep.
|
|
@@ -1,19 +1,10 @@
|
|
|
1
|
-
"""
|
|
2
|
-
This program is free software: you can redistribute it and/or modify it under
|
|
3
|
-
the terms of the GNU General Public License as published by the Free Software
|
|
4
|
-
Foundation, either version 3 of the License, or (at your option) any later
|
|
5
|
-
version.
|
|
6
|
-
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
7
|
-
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
8
|
-
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
9
|
-
You should have received a copy of the GNU General Public License along with
|
|
10
|
-
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
1
|
import geometry as g
|
|
14
2
|
import numpy as np
|
|
15
3
|
from json import load, dump
|
|
16
4
|
from typing import Self
|
|
5
|
+
import json_stream
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
17
8
|
|
|
18
9
|
class Origin(object):
|
|
19
10
|
'''This class defines an aerobatic box in the world, it uses the pilot position and the direction
|
|
@@ -123,12 +114,21 @@ class Origin(object):
|
|
|
123
114
|
)
|
|
124
115
|
|
|
125
116
|
@staticmethod
|
|
126
|
-
def
|
|
127
|
-
|
|
117
|
+
def from_fcjson_parameters(data: dict | str | Path):
|
|
118
|
+
if not isinstance(data, dict):
|
|
119
|
+
data = json_stream.to_standard_types(
|
|
120
|
+
json_stream.load(open(data, 'r'))['parameters']
|
|
121
|
+
)
|
|
122
|
+
return Origin(
|
|
128
123
|
"FCJ_box",
|
|
129
|
-
g.GPS(
|
|
130
|
-
|
|
124
|
+
g.GPS(
|
|
125
|
+
float(data['pilotLat']),
|
|
126
|
+
float(data['pilotLng']),
|
|
127
|
+
float(data['pilotAlt'])
|
|
128
|
+
),
|
|
129
|
+
float(data['rotation'])
|
|
131
130
|
)
|
|
131
|
+
|
|
132
132
|
|
|
133
133
|
|
|
134
134
|
def gps_to_point(self, gps: g.GPS) -> g.Point:
|
|
@@ -52,7 +52,7 @@ class State(Table):
|
|
|
52
52
|
if rotation_only:
|
|
53
53
|
self.back_transform.rotate(pin)
|
|
54
54
|
else:
|
|
55
|
-
return self.back_transform.
|
|
55
|
+
return self.back_transform.point(pin)
|
|
56
56
|
|
|
57
57
|
def fill(self, time: g.Time) -> State:
|
|
58
58
|
'''Project forward through time assuming small angles and uniform circular motion'''
|
|
@@ -98,15 +98,13 @@ class State(Table):
|
|
|
98
98
|
origin = Origin.from_json(origin)
|
|
99
99
|
elif origin is None:
|
|
100
100
|
origin = flight.origin
|
|
101
|
-
|
|
101
|
+
|
|
102
102
|
time = g.Time.from_t(np.array(flight.data.time_flight))
|
|
103
103
|
|
|
104
104
|
if all(flight.contains('gps')) and flight.primary_pos_source == 'gps':
|
|
105
|
-
pos = origin.rotation.transform_point(g.GPS(flight.gps.ffill().bfill()) - origin.pos
|
|
105
|
+
pos = origin.rotation.transform_point(g.GPS(flight.gps.ffill().bfill()) - origin.pos)
|
|
106
106
|
else:
|
|
107
|
-
pos = origin.rotation.transform_point(
|
|
108
|
-
flight.origin.pos.offset(g.Point(flight.position.ffill().bfill())) - origin.pos[0]
|
|
109
|
-
)
|
|
107
|
+
pos = origin.rotation.transform_point(g.Point(flight.position.ffill().bfill()))
|
|
110
108
|
|
|
111
109
|
att = origin.rotation * g.Euler(flight.attitude.ffill().bfill())
|
|
112
110
|
vel = att.inverse().transform_point(origin.rotation.transform_point(g.Point(flight.velocity.ffill().bfill()))) if all(flight.contains('velocity')) else None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: flightdata
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.16
|
|
4
4
|
Summary: Module for handling UAV flight log data
|
|
5
5
|
Author-email: Thomas David <thomasdavid0@gmail.com>
|
|
6
6
|
License: GNU GPL v3
|
|
@@ -11,12 +11,13 @@ License-File: LICENSE
|
|
|
11
11
|
Requires-Dist: numpy
|
|
12
12
|
Requires-Dist: pandas
|
|
13
13
|
Requires-Dist: simplejson
|
|
14
|
-
Requires-Dist: pfc-geometry>=0.2.
|
|
14
|
+
Requires-Dist: pfc-geometry>=0.2.8
|
|
15
|
+
Requires-Dist: json_stream
|
|
15
16
|
Provides-Extra: dev
|
|
16
17
|
Requires-Dist: numpy; extra == "dev"
|
|
17
18
|
Requires-Dist: pandas; extra == "dev"
|
|
18
19
|
Requires-Dist: simplejson; extra == "dev"
|
|
19
|
-
Requires-Dist: pfc-geometry>=0.2.
|
|
20
|
+
Requires-Dist: pfc-geometry>=0.2.8; extra == "dev"
|
|
20
21
|
Requires-Dist: ardupilot-log-reader>=0.3.3; extra == "dev"
|
|
21
22
|
Requires-Dist: pytest; extra == "dev"
|
|
22
23
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|