flightdata 0.2.10__tar.gz → 0.2.12__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.10 → flightdata-0.2.12}/.github/workflows/publish_pypi.yml +1 -1
- {flightdata-0.2.10/flightdata.egg-info → flightdata-0.2.12}/PKG-INFO +14 -1
- {flightdata-0.2.10 → flightdata-0.2.12}/README.md +13 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/base/table.py +37 -35
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/flight/flight.py +13 -5
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/scripts/collect_logs.py +4 -1
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/scripts/flightline.py +4 -1
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/state.py +1 -1
- {flightdata-0.2.10 → flightdata-0.2.12/flightdata.egg-info}/PKG-INFO +14 -1
- {flightdata-0.2.10 → flightdata-0.2.12}/test/base/test_table.py +16 -13
- {flightdata-0.2.10 → flightdata-0.2.12}/.gitignore +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/.vscode/launch.json +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/.vscode/settings.json +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/LICENSE +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/examples/__init__.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/examples/axis_rates.ipynb +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/examples/data/__init__.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/examples/data/manual_F3A_F23_22_04_28_00000231.json +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/examples/data/manual_F3A_P23_22_05_31_00000350.json +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/examples/data/manual_F3A_P23_23_08_11_00000094.json +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/examples/flight_data.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/examples/flight_dynamics/00000150.json +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/examples/flight_dynamics/__init__.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/examples/flight_dynamics/box.f3a +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/examples/flight_dynamics/param_id.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/examples/state_analysis/__init__.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/examples/state_analysis/axes.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/examples/state_analysis/state_fill_plot.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/__init__.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/base/__init__.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/base/collection.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/base/constructs.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/base/labeling.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/base/numpy_encoder.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/coefficients.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/environment/__init__.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/environment/environment.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/environment/wind.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/flight/__init__.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/flight/ardupilot.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/flight/fields.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/flight/parameters.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/flow.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/model/__init__.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/model/aerodynamic.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/model/thrust.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata/origin.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata.egg-info/SOURCES.txt +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata.egg-info/dependency_links.txt +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata.egg-info/entry_points.txt +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata.egg-info/requires.txt +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/flightdata.egg-info/top_level.txt +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/pyproject.toml +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/requirements-dev.txt +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/requirements.txt +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/setup.cfg +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/EmailedBox.f3a +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/__init__.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/base/__init__.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/base/test_base_constructs.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/conftest.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/data/make_inputs.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/data/manual_F3A_P23.json +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/data/p23.BIN +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/data/p23.json +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/data/p23_box.f3a +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/data/p23_fc.json +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/data/p23_flight.json +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/data/vtol_hover.bin +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/data/vtol_hover.json +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/test_environment/__init__.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/test_environment/test_environment.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/test_environment/test_environment_wind.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/test_fields.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/test_flight.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/test_model/__init__.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/test_model/test_model_coefficients.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/test_model/test_model_flow.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/test_origin.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/test_state/__init__.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/test_state/test_state.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/test_state/test_state_builders.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/test/test_state/test_state_conversions.py +0 -0
- {flightdata-0.2.10 → flightdata-0.2.12}/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.12
|
|
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
|
|
@@ -34,3 +34,16 @@ The State object is a table representing the position and orientation of the air
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
Further documentation will be provided here: https://pfcdocumentation.readthedocs.io/pyflightcoach/flightdata.html
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
### Installation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install pfc-geometry
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Setup from source
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install .
|
|
49
|
+
```
|
|
@@ -12,3 +12,16 @@ The State object is a table representing the position and orientation of the air
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
Further documentation will be provided here: https://pfcdocumentation.readthedocs.io/pyflightcoach/flightdata.html
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install pfc-geometry
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Setup from source
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install .
|
|
27
|
+
```
|
|
@@ -21,7 +21,6 @@ class Table:
|
|
|
21
21
|
self.label_cols = [c for c in data.columns if c not in self.constructs.cols()]
|
|
22
22
|
|
|
23
23
|
self.data = data
|
|
24
|
-
#self.data.index = self.data.index - self.data.index[0]
|
|
25
24
|
|
|
26
25
|
if fill:
|
|
27
26
|
missing = self.constructs.missing(self.data.columns)
|
|
@@ -81,40 +80,16 @@ class Table:
|
|
|
81
80
|
else:
|
|
82
81
|
raise TypeError(f"Expected Number or slice, got {sli.__class__.__name__}")
|
|
83
82
|
|
|
84
|
-
|
|
85
83
|
def slice_raw_t(self, sli):
|
|
86
84
|
inds = self.data.reset_index(names="t2").set_index("t").loc[sli].t2.to_numpy()#set_index("t", drop=False).columns
|
|
87
85
|
|
|
88
86
|
return self.__class__(self.data.loc[inds])
|
|
89
87
|
|
|
90
|
-
@classmethod
|
|
91
|
-
def stack(Cls, sections: list, overlap: int=1) -> Self:
|
|
92
|
-
"""Stack a list of Tables on top of each other.
|
|
93
|
-
The overlap is the number of rows to overlap between each section
|
|
94
|
-
"""
|
|
95
|
-
# first build list of index offsets, to be added to each dataframe
|
|
96
|
-
if overlap > 0:
|
|
97
|
-
offsets = np.cumsum([0] + [sec.data.index[-overlap] for sec in sections[:-1]])
|
|
98
|
-
dfs = [section.data.iloc[:-overlap] for section in sections[:-1]] + [sections[-1].data]
|
|
99
|
-
elif overlap == 0:
|
|
100
|
-
offsets = np.cumsum([0] + [sec.duration + sec.dt[-1] for sec in sections[:-1]])
|
|
101
|
-
dfs = [section.data for section in sections]
|
|
102
|
-
else:
|
|
103
|
-
raise AttributeError("Overlap must be >= 0")
|
|
104
|
-
|
|
105
|
-
for df, offset in zip(dfs, offsets):
|
|
106
|
-
df.index = np.array(df.index) - df.index[0] + offset
|
|
107
|
-
combo = pd.concat(dfs)
|
|
108
|
-
combo.index.name = "t"
|
|
109
|
-
|
|
110
|
-
combo["t"] = combo.index
|
|
111
|
-
|
|
112
|
-
return Cls(combo)
|
|
113
|
-
|
|
114
88
|
def __iter__(self):
|
|
115
89
|
for ind in list(self.data.index):
|
|
116
90
|
yield self[ind]
|
|
117
91
|
|
|
92
|
+
|
|
118
93
|
@classmethod
|
|
119
94
|
def from_constructs(cls, *args,**kwargs) -> Self:
|
|
120
95
|
kwargs = dict(
|
|
@@ -133,7 +108,7 @@ class Table:
|
|
|
133
108
|
)
|
|
134
109
|
|
|
135
110
|
return cls(df)
|
|
136
|
-
|
|
111
|
+
|
|
137
112
|
def __repr__(self):
|
|
138
113
|
return f"{self.__class__.__name__} Table(duration = {self.duration})"
|
|
139
114
|
|
|
@@ -161,6 +136,30 @@ class Table:
|
|
|
161
136
|
ignore_index=True
|
|
162
137
|
).set_index("t", drop=False))
|
|
163
138
|
|
|
139
|
+
@classmethod
|
|
140
|
+
def stack(Cls, sections: list, overlap: int=1) -> Self:
|
|
141
|
+
"""Stack a list of Tables on top of each other.
|
|
142
|
+
The overlap is the number of rows to overlap between each section
|
|
143
|
+
"""
|
|
144
|
+
# first build list of index offsets, to be added to each dataframe
|
|
145
|
+
if overlap > 0:
|
|
146
|
+
offsets = np.cumsum([0] + [sec.data.index[-overlap] for sec in sections[:-1]])
|
|
147
|
+
dfs = [section.data.iloc[:-overlap] for section in sections[:-1]] + [sections[-1].data]
|
|
148
|
+
elif overlap == 0:
|
|
149
|
+
offsets = np.cumsum([0] + [sec.duration + sec.dt[-1] for sec in sections[:-1]])
|
|
150
|
+
dfs = [section.data for section in sections]
|
|
151
|
+
else:
|
|
152
|
+
raise AttributeError("Overlap must be >= 0")
|
|
153
|
+
|
|
154
|
+
for df, offset in zip(dfs, offsets):
|
|
155
|
+
df.index = np.array(df.index) - df.index[0] + offset
|
|
156
|
+
combo = pd.concat(dfs)
|
|
157
|
+
combo.index.name = "t"
|
|
158
|
+
|
|
159
|
+
combo["t"] = combo.index
|
|
160
|
+
|
|
161
|
+
return Cls(combo)
|
|
162
|
+
|
|
164
163
|
def label(self, **kwargs) -> Self:
|
|
165
164
|
return self.__class__(self.data.assign(**kwargs))
|
|
166
165
|
|
|
@@ -177,9 +176,11 @@ class Table:
|
|
|
177
176
|
|
|
178
177
|
def get_subset_df(self, **kwargs) -> pd.DataFrame:
|
|
179
178
|
dfo = self.data
|
|
179
|
+
sel = np.full(len(self.data), True)
|
|
180
180
|
for k, v in kwargs.items():
|
|
181
|
-
|
|
182
|
-
|
|
181
|
+
sel = sel & (dfo[k] == v)
|
|
182
|
+
|
|
183
|
+
return self.data.loc[sel + (sel.astype(int).diff() == -1)]
|
|
183
184
|
|
|
184
185
|
def get_label_subset(self, min_len=1, **kwargs) -> Self:
|
|
185
186
|
return self.__class__(self.get_subset_df(**kwargs), min_len=min_len)
|
|
@@ -244,13 +245,14 @@ class Table:
|
|
|
244
245
|
return self.label(**labels.to_dict(orient='list'))
|
|
245
246
|
|
|
246
247
|
@classmethod
|
|
247
|
-
def shift_multi(Cls, steps: int, tb1: Self, tb2: Self, min_len=
|
|
248
|
+
def shift_multi(Cls, steps: int, tb1: Self, tb2: Self, min_len=1) -> Tuple[Self, Self]:
|
|
248
249
|
'''Take datapoints off the start of tb2 and add to the end tb1'''
|
|
249
|
-
if (steps>0 and len(tb2)-min_len<steps) or (steps<0 and min_len - len(tb1) > steps):
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
250
|
+
#if (steps>0 and len(tb2)-min_len<steps) or (steps<0 and min_len - len(tb1) > steps):
|
|
251
|
+
# raise ValueError(f'Cannot Squash a Table to less than {min_len} datapoints')
|
|
252
|
+
tj = Cls.stack([tb1, tb2]).shift_label(steps, min_len, **dict(tb1.labels.iloc[0]))
|
|
253
|
+
|
|
254
|
+
return Cls(tj.get_subset_df(**dict(tb1.labels.iloc[0]))), \
|
|
255
|
+
Cls(tj.get_subset_df(**dict(tb2.labels.iloc[0])))
|
|
254
256
|
|
|
255
257
|
def shift_label_ratio(self, ratio: float, min_len=None, **kwargs) -> Self:
|
|
256
258
|
'''shift a label within its allowable bounds, with a ratio of
|
|
@@ -473,11 +473,19 @@ class Flight:
|
|
|
473
473
|
wind_N = df['wN'] if 'wN' in df.columns else None,
|
|
474
474
|
wind_E = df['wE'] if 'wE' in df.columns else None,
|
|
475
475
|
)
|
|
476
|
-
origin = Origin(
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
476
|
+
origin = Origin(
|
|
477
|
+
'fcj_origin',
|
|
478
|
+
GPS(
|
|
479
|
+
float(fc_json['parameters']['pilotLat']),
|
|
480
|
+
float(fc_json['parameters']['pilotLng']),
|
|
481
|
+
float(fc_json['parameters']['pilotAlt'])
|
|
482
|
+
).offset(-Point(
|
|
483
|
+
fc_json['parameters']['moveNorth'],
|
|
484
|
+
fc_json['parameters']['moveEast'],
|
|
485
|
+
0,
|
|
486
|
+
)),
|
|
487
|
+
0
|
|
488
|
+
)
|
|
481
489
|
|
|
482
490
|
return Flight(df.set_index('time_flight', drop=False), None, origin, 'position')#.remove_time_flutter()
|
|
483
491
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: flightdata
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.12
|
|
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
|
|
@@ -34,3 +34,16 @@ The State object is a table representing the position and orientation of the air
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
Further documentation will be provided here: https://pfcdocumentation.readthedocs.io/pyflightcoach/flightdata.html
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
### Installation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install pfc-geometry
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Setup from source
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install .
|
|
49
|
+
```
|
|
@@ -8,7 +8,7 @@ from pytest import fixture
|
|
|
8
8
|
|
|
9
9
|
@fixture
|
|
10
10
|
def df():
|
|
11
|
-
df = pd.DataFrame(np.linspace(0,
|
|
11
|
+
df = pd.DataFrame(np.linspace(0,5, 6), columns=['t'])
|
|
12
12
|
return df.set_index("t", drop=False)
|
|
13
13
|
|
|
14
14
|
@fixture
|
|
@@ -54,12 +54,15 @@ def test_get_subset_df(tab_full, labst):
|
|
|
54
54
|
assert len(tab_full) == len(df)
|
|
55
55
|
|
|
56
56
|
|
|
57
|
-
def test_shift_labels_ratios(tab_full):
|
|
58
|
-
tf =
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
def test_shift_labels_ratios(tab_full: Table):
|
|
58
|
+
tf: Table = Table.stack([
|
|
59
|
+
tab_full.label(element='e0', manoeuvre='m0'),
|
|
60
|
+
tab_full.label(element='e1', manoeuvre='m0')
|
|
61
|
+
|
|
62
|
+
])
|
|
63
|
+
|
|
61
64
|
assert sum(tf.shift_labels_ratios([0.5],2).element == 'e1') < sum(tf.element == 'e1')
|
|
62
|
-
|
|
65
|
+
|
|
63
66
|
|
|
64
67
|
def test_stack(tab_full):
|
|
65
68
|
tfn = Table.stack([tab_full.label(element='e0'), tab_full.label(element='e1')], overlap=0)
|
|
@@ -72,18 +75,18 @@ def test_stack(tab_full):
|
|
|
72
75
|
|
|
73
76
|
|
|
74
77
|
def test_shift_multi(tab_full):
|
|
75
|
-
|
|
76
|
-
tb1, tb2 = Table.shift_multi(2,
|
|
78
|
+
tabs = Table.stack([tab_full.label(element='e0'), tab_full.label(element='e1')], overlap=1).split_labels()
|
|
79
|
+
tb1, tb2 = Table.shift_multi(2, tabs['e0'], tabs['e1'])
|
|
77
80
|
|
|
78
81
|
assert len(tb1) == len(tab_full) + 2
|
|
79
82
|
assert len(tb2) == len(tab_full) - 2
|
|
80
83
|
assert tb2.duration == tab_full.data.index[-3]
|
|
81
84
|
|
|
82
|
-
tb1, tb2 = Table.shift_multi(-
|
|
85
|
+
tb1, tb2 = Table.shift_multi(-3, tabs['e0'], tabs['e1'])
|
|
83
86
|
|
|
84
|
-
assert len(tb1) == len(tab_full) -
|
|
85
|
-
assert len(tb2) == len(tab_full) +
|
|
86
|
-
assert tb1.duration == tab_full.data.index[-
|
|
87
|
+
assert len(tb1) == len(tab_full) - 3
|
|
88
|
+
assert len(tb2) == len(tab_full) + 3
|
|
89
|
+
assert tb1.duration == tab_full.data.index[-4]
|
|
87
90
|
|
|
88
91
|
|
|
89
92
|
def test_table_cumulative_labels(tab_full):
|
|
@@ -102,6 +105,6 @@ def test_table_cumulative_labels(tab_full):
|
|
|
102
105
|
indexes = np.unique(res, return_index=True)[1]
|
|
103
106
|
np.testing.assert_array_equal(
|
|
104
107
|
[res[index] for index in sorted(indexes)],
|
|
105
|
-
np.array(['
|
|
108
|
+
np.array(['a1_b1_0', 'a2_b1_0', 'a2_b2_0', 'a1_b1_1'])
|
|
106
109
|
)
|
|
107
110
|
pass
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|