ebird-api-data 0.2.2__tar.gz → 0.2.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.
Files changed (43) hide show
  1. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/PKG-INFO +1 -1
  2. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/pyproject.toml +2 -2
  3. ebird_api_data-0.2.3/src/ebird/api/data/__init__.py +1 -0
  4. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/loaders.py +1 -1
  5. ebird_api_data-0.2.3/src/ebird/api/data/migrations/0001_squashed_0010_alter_species_category.py +704 -0
  6. ebird_api_data-0.2.3/src/ebird/api/data/migrations/0011_checklist_modified_country_modified_county_modified_and_more.py +58 -0
  7. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/models/checklist.py +4 -0
  8. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/models/country.py +4 -0
  9. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/models/county.py +4 -0
  10. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/models/filter.py +4 -0
  11. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/models/location.py +4 -0
  12. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/models/observation.py +4 -0
  13. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/models/observer.py +4 -0
  14. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/models/species.py +4 -0
  15. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/models/state.py +4 -0
  16. ebird_api_data-0.2.2/src/ebird/api/data/__init__.py +0 -1
  17. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/.gitignore +0 -0
  18. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/LICENSE +0 -0
  19. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/README.md +0 -0
  20. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/admin.py +0 -0
  21. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/apps.py +0 -0
  22. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/fields.py +0 -0
  23. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/locale/en/LC_MESSAGES/django.mo +0 -0
  24. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/locale/en/LC_MESSAGES/django.po +0 -0
  25. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/management/__init__.py +0 -0
  26. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/management/commands/__init__.py +0 -0
  27. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/management/commands/add_checklists.py +0 -0
  28. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/migrations/0001_initial.py +0 -0
  29. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/migrations/0002_convert_foreign_keys_to_integers.py +0 -0
  30. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/migrations/0003_make_codes_and_identifiers_primary_keys.py +0 -0
  31. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/migrations/0004_rename_foreign_keys.py +0 -0
  32. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/migrations/0005_add_new_foreign_keys.py +0 -0
  33. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/migrations/0006_set_new_foreign_keys.py +0 -0
  34. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/migrations/0007_remove_old_fields_and_ids.py +0 -0
  35. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/migrations/0008_rename_created_checklist_added.py +0 -0
  36. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/migrations/0009_add_created_timestamps.py +0 -0
  37. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/migrations/0010_alter_species_category.py +0 -0
  38. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/migrations/__init__.py +0 -0
  39. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/models/__init__.py +0 -0
  40. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/templates/admin/data/species/change_list_object_tools.html +0 -0
  41. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/templates/admin/data/species/fetch_species.html +0 -0
  42. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/templates/data/widgets/translation_field.html +0 -0
  43. {ebird_api_data-0.2.2 → ebird_api_data-0.2.3}/src/ebird/api/data/widgets.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ebird-api-data
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: eBird API Data is a reusable Django app for loading data from eBird into a database.
5
5
  Author-email: Stuart MacKay <smackay@flagstonesoftware.com>
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ebird-api-data"
3
- version = "0.2.2"
3
+ version = "0.2.3"
4
4
  description = "eBird API Data is a reusable Django app for loading data from eBird into a database."
5
5
  keywords = ["checklists", "observations", "species", "Django", "eBird", "models"]
6
6
  license = "MIT"
@@ -65,7 +65,7 @@ dev-dependencies = [
65
65
  ]
66
66
 
67
67
  [tool.bumpversion]
68
- current_version = "0.2.2"
68
+ current_version = "0.2.3"
69
69
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
70
70
  serialize = ["{major}.{minor}.{patch}"]
71
71
  ignore_missing_version = false
@@ -0,0 +1 @@
1
+ __version__ = "0.2.3"
@@ -221,7 +221,7 @@ class APILoader:
221
221
  values["taxon_order"] = int(data["taxonOrder"])
222
222
  values["order"] = data.get("order", "")
223
223
  values["category"] = data["category"]
224
- values["family_code"] = data["familyCode"]
224
+ values["family_code"] = data.get("familyCode", "")
225
225
  values["common_name"][language] = data["comName"]
226
226
  values["scientific_name"] = data["sciName"]
227
227
  values["family_common_name"][language] = data["familyComName"]
@@ -0,0 +1,704 @@
1
+ # Generated by Django 5.2.4 on 2025-07-24 03:38
2
+
3
+ import django.core.validators
4
+ import django.db.migrations.operations.special
5
+ import django.db.models.deletion
6
+ from django.db import connection, migrations, models
7
+
8
+
9
+ # Functions from the following migrations need manual copying.
10
+ # Move them and any dependencies into this file, then update the
11
+ # RunPython operations to refer to the local versions:
12
+ # ebird.api.data.migrations.0006_set_new_foreign_keys
13
+
14
+ def update_location_country(apps, schema_editor):
15
+ with connection.cursor() as cursor:
16
+ cursor.execute(
17
+ "UPDATE data_location "
18
+ "SET country_id = data_country.code "
19
+ "FROM data_country "
20
+ "WHERE data_location.country_old = data_country.id"
21
+ )
22
+
23
+
24
+ def update_location_state(apps, schema_editor):
25
+ with connection.cursor() as cursor:
26
+ cursor.execute(
27
+ "UPDATE data_location "
28
+ "SET state_id = data_state.code "
29
+ "FROM data_state "
30
+ "WHERE data_location.state_old = data_state.id"
31
+ )
32
+
33
+
34
+ def update_location_county(apps, schema_editor):
35
+ with connection.cursor() as cursor:
36
+ cursor.execute(
37
+ "UPDATE data_location "
38
+ "SET county_id = data_county.code "
39
+ "FROM data_county "
40
+ "WHERE data_location.county_old = data_county.id"
41
+ )
42
+
43
+
44
+ def update_checklist_country(apps, schema_editor):
45
+ with connection.cursor() as cursor:
46
+ cursor.execute(
47
+ "UPDATE data_checklist "
48
+ "SET country_id = data_country.code "
49
+ "FROM data_country "
50
+ "WHERE data_checklist.country_old = data_country.id"
51
+ )
52
+
53
+
54
+ def update_checklist_state(apps, schema_editor):
55
+ with connection.cursor() as cursor:
56
+ cursor.execute(
57
+ "UPDATE data_checklist "
58
+ "SET state_id = data_state.code "
59
+ "FROM data_state "
60
+ "WHERE data_checklist.state_old = data_state.id"
61
+ )
62
+
63
+
64
+ def update_checklist_county(apps, schema_editor):
65
+ with connection.cursor() as cursor:
66
+ cursor.execute(
67
+ "UPDATE data_checklist "
68
+ "SET county_id = data_county.code "
69
+ "FROM data_county "
70
+ "WHERE data_checklist.county_old = data_county.id"
71
+ )
72
+
73
+
74
+ def update_checklist_location(apps, schema_editor):
75
+ with connection.cursor() as cursor:
76
+ cursor.execute(
77
+ "UPDATE data_checklist "
78
+ "SET location_id = data_location.identifier "
79
+ "FROM data_location "
80
+ "WHERE data_checklist.location_old = data_location.id"
81
+ )
82
+
83
+
84
+ def update_checklist_observer(apps, schema_editor):
85
+ with connection.cursor() as cursor:
86
+ cursor.execute(
87
+ "UPDATE data_checklist "
88
+ "SET observer_id = data_observer.identifier "
89
+ "FROM data_observer "
90
+ "WHERE data_checklist.observer_old = data_observer.id"
91
+ )
92
+
93
+
94
+ def update_observation_country(apps, schema_editor):
95
+ with connection.cursor() as cursor:
96
+ cursor.execute(
97
+ "UPDATE data_observation "
98
+ "SET country_id = data_country.code "
99
+ "FROM data_country "
100
+ "WHERE data_observation.country_old = data_country.id"
101
+ )
102
+
103
+
104
+ def update_observation_state(apps, schema_editor):
105
+ with connection.cursor() as cursor:
106
+ cursor.execute(
107
+ "UPDATE data_observation "
108
+ "SET state_id = data_state.code "
109
+ "FROM data_state "
110
+ "WHERE data_observation.state_old = data_state.id"
111
+ )
112
+
113
+
114
+ def update_observation_county(apps, schema_editor):
115
+ with connection.cursor() as cursor:
116
+ cursor.execute(
117
+ "UPDATE data_observation "
118
+ "SET county_id = data_county.code "
119
+ "FROM data_county "
120
+ "WHERE data_observation.county_old = data_county.id"
121
+ )
122
+
123
+
124
+ def update_observation_location(apps, schema_editor):
125
+ with connection.cursor() as cursor:
126
+ cursor.execute(
127
+ "UPDATE data_observation "
128
+ "SET location_id = data_location.identifier "
129
+ "FROM data_location "
130
+ "WHERE data_observation.location_old = data_location.id"
131
+ )
132
+
133
+
134
+ def update_observation_observer(apps, schema_editor):
135
+ with connection.cursor() as cursor:
136
+ cursor.execute(
137
+ "UPDATE data_observation "
138
+ "SET observer_id = data_observer.identifier "
139
+ "FROM data_observer "
140
+ "WHERE data_observation.observer_old = data_observer.id"
141
+ )
142
+
143
+
144
+ def update_observation_checklist(apps, schema_editor):
145
+ with connection.cursor() as cursor:
146
+ cursor.execute(
147
+ "UPDATE data_observation "
148
+ "SET checklist_id = data_checklist.identifier "
149
+ "FROM data_checklist "
150
+ "WHERE data_observation.checklist_old = data_checklist.id"
151
+ )
152
+
153
+
154
+ def update_observation_species(apps, schema_editor):
155
+ with connection.cursor() as cursor:
156
+ cursor.execute(
157
+ "UPDATE data_observation "
158
+ "SET species_id = data_species.species_code "
159
+ "FROM data_species "
160
+ "WHERE data_observation.species_old = data_species.id"
161
+ )
162
+
163
+
164
+ def update_filter_species(apps, schema_editor):
165
+ with connection.cursor() as cursor:
166
+ cursor.execute(
167
+ "UPDATE data_filter "
168
+ "SET species_id = data_species.species_code "
169
+ "FROM data_species "
170
+ "WHERE data_filter.species_old = data_species.id"
171
+ )
172
+
173
+
174
+ def update_filter_location(apps, schema_editor):
175
+ with connection.cursor() as cursor:
176
+ cursor.execute(
177
+ "UPDATE data_filter "
178
+ "SET location_id = data_location.identifier "
179
+ "FROM data_location "
180
+ "WHERE data_filter.location_old = data_location.id"
181
+ )
182
+
183
+
184
+ def update_filter_update_species(apps, schema_editor):
185
+ with connection.cursor() as cursor:
186
+ cursor.execute(
187
+ "UPDATE data_filter "
188
+ "SET update_species_id = data_species.species_code "
189
+ "FROM data_species "
190
+ "WHERE data_filter.update_species_old = data_species.id"
191
+ )
192
+
193
+
194
+ class Migration(migrations.Migration):
195
+
196
+ replaces = [('data', '0001_initial'), ('data', '0002_convert_foreign_keys_to_integers'), ('data', '0003_make_codes_and_identifiers_primary_keys'), ('data', '0004_rename_foreign_keys'), ('data', '0005_add_new_foreign_keys'), ('data', '0006_set_new_foreign_keys'), ('data', '0007_remove_old_fields_and_ids'), ('data', '0008_rename_created_checklist_added'), ('data', '0009_add_created_timestamps'), ('data', '0010_alter_species_category')]
197
+
198
+ initial = True
199
+
200
+ dependencies = [
201
+ ]
202
+
203
+ operations = [
204
+ migrations.CreateModel(
205
+ name='Country',
206
+ fields=[
207
+ ('id', models.IntegerField()),
208
+ ('code', models.CharField(help_text='The code used to identify the country.', max_length=2, primary_key=True, serialize=False, verbose_name='code')),
209
+ ('name', models.TextField(help_text='The name of the country.', verbose_name='name')),
210
+ ('place', models.TextField(help_text='The hierarchical name of the country.', verbose_name='place')),
211
+ ],
212
+ options={
213
+ 'verbose_name': 'country',
214
+ 'verbose_name_plural': 'countries',
215
+ },
216
+ ),
217
+ migrations.CreateModel(
218
+ name='County',
219
+ fields=[
220
+ ('id', models.IntegerField()),
221
+ ('code', models.CharField(help_text='The code used to identify the county.', max_length=10, primary_key=True, serialize=False, verbose_name='code')),
222
+ ('name', models.TextField(help_text='The name of the county.', verbose_name='name')),
223
+ ('place', models.TextField(help_text='The hierarchical name of the county.', verbose_name='place')),
224
+ ],
225
+ options={
226
+ 'verbose_name': 'county',
227
+ 'verbose_name_plural': 'counties',
228
+ },
229
+ ),
230
+ migrations.CreateModel(
231
+ name='Observer',
232
+ fields=[
233
+ ('id', models.IntegerField()),
234
+ ('identifier', models.CharField(help_text='The code for the person submitted the checklist.', max_length=15, primary_key=True, serialize=False, verbose_name='identifier')),
235
+ ('original', models.TextField(help_text='The original name of the observer from eBird.', verbose_name='original name')),
236
+ ('name', models.TextField(help_text='The display name of the observer.', verbose_name='name')),
237
+ ('multiple', models.BooleanField(default=False, help_text='Is the name used by more than one eBird account.', verbose_name='Multiple accounts')),
238
+ ('enabled', models.BooleanField(default=True, help_text='Load checklists from the eBird observer.', verbose_name='Enabled')),
239
+ ('data', models.JSONField(blank=True, default=dict, help_text='Data describing an Observer.', verbose_name='Data')),
240
+ ],
241
+ options={
242
+ 'verbose_name': 'observer',
243
+ 'verbose_name_plural': 'observers',
244
+ },
245
+ ),
246
+ migrations.CreateModel(
247
+ name='Species',
248
+ fields=[
249
+ ('id', models.IntegerField()),
250
+ ('taxon_order', models.IntegerField(blank=True, help_text='The position in the eBird/Clements taxonomic order.', null=True, verbose_name='taxonomy order')),
251
+ ('order', models.TextField(blank=True, help_text='The order, e.g. Struthioniformes, from the eBird/Clements taxonomy.', verbose_name='order')),
252
+ ('category', models.TextField(blank=True, choices=[('', 'All categories'), ('species', 'Species'), ('issf', 'Subspecies'), ('domestic', 'Domestic'), ('hybrid', 'Hybrid')], help_text='The category from the eBird/Clements taxonomy.', verbose_name='category')),
253
+ ('species_code', models.CharField(help_text='The species code, e.g. ostric2, used in the eBird API.', max_length=10, primary_key=True, serialize=False, verbose_name='species code')),
254
+ ('family_code', models.TextField(blank=True, help_text='The family code, e.g. struth1, used in the eBird API.', verbose_name='family code')),
255
+ ('common_name', models.TextField(help_text='The species common name in the eBird/Clements taxonomy.', verbose_name='common name')),
256
+ ('scientific_name', models.TextField(help_text='The species scientific name in the eBird/Clements taxonomy.', verbose_name='scientific name')),
257
+ ('family_common_name', models.TextField(blank=True, help_text='The common name for the species family in the eBird/Clements taxonomy.', verbose_name='family common name')),
258
+ ('family_scientific_name', models.TextField(blank=True, help_text='The scientific name for the species family in the eBird/Clements taxonomy.', verbose_name='family scientific name')),
259
+ ('data', models.JSONField(blank=True, default=dict, help_text='Data describing a Species.', verbose_name='Data')),
260
+ ],
261
+ options={
262
+ 'verbose_name': 'species',
263
+ 'verbose_name_plural': 'species',
264
+ },
265
+ ),
266
+ migrations.CreateModel(
267
+ name='State',
268
+ fields=[
269
+ ('id', models.IntegerField()),
270
+ ('code', models.CharField(help_text='The code used to identify the state.', max_length=6, primary_key=True, serialize=False, verbose_name='code')),
271
+ ('name', models.TextField(help_text='The name of the state.', verbose_name='name')),
272
+ ('place', models.TextField(help_text='The hierarchical name of the state.', verbose_name='place')),
273
+ ],
274
+ options={
275
+ 'verbose_name': 'state',
276
+ 'verbose_name_plural': 'states',
277
+ },
278
+ ),
279
+ migrations.CreateModel(
280
+ name='Location',
281
+ fields=[
282
+ ('id', models.IntegerField()),
283
+ ('identifier', models.CharField(help_text='The unique identifier for the location.', max_length=15, primary_key=True, serialize=False, verbose_name='identifier')),
284
+ ('original', models.TextField(help_text='The original name of the location from eBird.', verbose_name='original name')),
285
+ ('name', models.TextField(help_text='The display name of the location.', verbose_name='name')),
286
+ ('latitude', models.DecimalField(blank=True, decimal_places=7, help_text='The decimal latitude of the location, relative to the equator.', max_digits=9, null=True, verbose_name='latitude')),
287
+ ('longitude', models.DecimalField(blank=True, decimal_places=7, help_text='The decimal longitude of the location, relative to the prime meridian.', max_digits=10, null=True, verbose_name='longitude')),
288
+ ('url', models.URLField(blank=True, help_text='URL of the location page on eBird.', verbose_name='url')),
289
+ ('hotspot', models.BooleanField(blank=True, help_text='Is the location a hotspot.', null=True, verbose_name='is hotspot')),
290
+ ('data', models.JSONField(blank=True, default=dict, help_text='Data describing a Location.', verbose_name='Data')),
291
+ ('country_old', models.IntegerField()),
292
+ ('county_old', models.IntegerField(null=True)),
293
+ ('state_old', models.IntegerField()),
294
+ ('country', models.ForeignKey(help_text='The country for the location.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='locations', to='data.country', verbose_name='country')),
295
+ ('county', models.ForeignKey(blank=True, help_text='The county for the location.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='locations', to='data.county', verbose_name='county')),
296
+ ('state', models.ForeignKey(help_text='The state for the location.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='locations', to='data.state', verbose_name='state')),
297
+ ],
298
+ options={
299
+ 'verbose_name': 'location',
300
+ 'verbose_name_plural': 'locations',
301
+ },
302
+ ),
303
+ migrations.CreateModel(
304
+ name='Checklist',
305
+ fields=[
306
+ ('id', models.IntegerField()),
307
+ ('created', models.DateTimeField(blank=True, help_text='The date and time the checklist was added to eBird.', null=True, verbose_name='created')),
308
+ ('edited', models.DateTimeField(blank=True, help_text='The date and time the eBird checklist was last edited.', null=True, verbose_name='edited')),
309
+ ('published', models.BooleanField(help_text='Is the checklist published?', verbose_name='published')),
310
+ ('identifier', models.CharField(help_text='The unique identifier for the checklist.', max_length=15, primary_key=True, serialize=False, verbose_name='identifier')),
311
+ ('observer_count', models.IntegerField(blank=True, help_text='The total number of observers.', null=True, verbose_name='observer count')),
312
+ ('species_count', models.IntegerField(blank=True, help_text='The number of species reported.', null=True, verbose_name='species count')),
313
+ ('date', models.DateField(db_index=True, help_text='The date the checklist was started.', verbose_name='date')),
314
+ ('time', models.TimeField(blank=True, help_text='The time the checklist was started.', null=True, verbose_name='time')),
315
+ ('started', models.DateTimeField(blank=True, db_index=True, help_text='The date and time the checklist was started.', null=True, verbose_name='date & time')),
316
+ ('protocol_code', models.TextField(blank=True, help_text='The code used to identify the protocol.', verbose_name='protocol code')),
317
+ ('project_code', models.TextField(blank=True, help_text='The code used to identify the project (portal).', verbose_name='project code')),
318
+ ('duration', models.IntegerField(blank=True, help_text='The number of minutes spent counting.', null=True, verbose_name='duration')),
319
+ ('distance', models.DecimalField(blank=True, decimal_places=3, help_text='The distance, in metres, covered while travelling.', max_digits=6, null=True, verbose_name='distance')),
320
+ ('area', models.DecimalField(blank=True, decimal_places=3, help_text='The area covered, in hectares.', max_digits=6, null=True, verbose_name='area')),
321
+ ('complete', models.BooleanField(default=False, help_text='All species seen are reported.', verbose_name='complete')),
322
+ ('comments', models.TextField(blank=True, help_text='Any comments about the checklist.', verbose_name='comments')),
323
+ ('url', models.URLField(blank=True, help_text='URL where the original checklist can be viewed.', verbose_name='url')),
324
+ ('data', models.JSONField(blank=True, default=dict, help_text='Data describing a Checklist.', verbose_name='Data')),
325
+ ('country_old', models.IntegerField()),
326
+ ('county_old', models.IntegerField(null=True)),
327
+ ('location_old', models.IntegerField()),
328
+ ('observer_old', models.IntegerField()),
329
+ ('state_old', models.IntegerField()),
330
+ ('country', models.ForeignKey(help_text='The country where the checklist was made.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='checklists', to='data.country', verbose_name='country')),
331
+ ('county', models.ForeignKey(blank=True, help_text='The county where the checklist was made.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='checklists', to='data.county', verbose_name='county')),
332
+ ('location', models.ForeignKey(help_text='The location where checklist was made.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='checklists', to='data.location', verbose_name='location')),
333
+ ('observer', models.ForeignKey(help_text='The person who submitted the checklist.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='checklists', to='data.observer', verbose_name='observer')),
334
+ ('state', models.ForeignKey(help_text='The state where the checklist was made.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='checklists', to='data.state', verbose_name='state')),
335
+ ],
336
+ options={
337
+ 'verbose_name': 'checklist',
338
+ 'verbose_name_plural': 'checklists',
339
+ },
340
+ ),
341
+ migrations.CreateModel(
342
+ name='Filter',
343
+ fields=[
344
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
345
+ ('enabled', models.BooleanField(help_text='Is the filter active?', verbose_name='enabled')),
346
+ ('name', models.TextField(help_text='The name of the filter.', verbose_name='name')),
347
+ ('location_old', models.IntegerField(null=True)),
348
+ ('species_old', models.IntegerField()),
349
+ ('update_species_old', models.IntegerField()),
350
+ ('location', models.ForeignKey(blank=True, help_text='The location used to find matching Observations.', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='filtered_on', to='data.location', verbose_name='location')),
351
+ ('species', models.ForeignKey(help_text='The species used to find matching Observations.', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='filtered_on', to='data.species', verbose_name='species')),
352
+ ('update_species', models.ForeignKey(help_text='Matching Observations are updated to this species.', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='filtered_by', to='data.species', verbose_name='update species')),
353
+ ],
354
+ options={
355
+ 'verbose_name': 'filter',
356
+ 'verbose_name_plural': 'filters',
357
+ },
358
+ ),
359
+ migrations.CreateModel(
360
+ name='Observation',
361
+ fields=[
362
+ ('id', models.IntegerField()),
363
+ ('edited', models.DateTimeField(blank=True, help_text='The date and time the eBird checklist was last edited.', null=True, verbose_name='edited')),
364
+ ('published', models.BooleanField(help_text='Is the observation published?', verbose_name='published')),
365
+ ('identifier', models.CharField(help_text='A global unique identifier for the observation.', max_length=15, primary_key=True, serialize=False, verbose_name='identifier')),
366
+ ('date', models.DateField(db_index=True, help_text='The date the observation was made.', verbose_name='date')),
367
+ ('time', models.TimeField(blank=True, help_text='The time the observation was made.', null=True, verbose_name='time')),
368
+ ('started', models.DateTimeField(blank=True, db_index=True, help_text='The date and time the observation was made.', null=True, verbose_name='date & time')),
369
+ ('count', models.IntegerField(help_text='The number of birds seen.', validators=[django.core.validators.MinValueValidator(0)], verbose_name='count')),
370
+ ('audio', models.BooleanField(default=False, help_text='Have audio recordings been uploaded to the Macaulay library.', verbose_name='has audio')),
371
+ ('photo', models.BooleanField(default=False, help_text='Have photos been uploaded to the Macaulay library.', verbose_name='has photos')),
372
+ ('video', models.BooleanField(default=False, help_text='Have video recordings been uploaded to the Macaulay library.', verbose_name='has video')),
373
+ ('approved', models.BooleanField(default=True, help_text='Has the observation been accepted.', verbose_name='Approved')),
374
+ ('reason', models.TextField(blank=True, help_text='The reason given for the observation to be marked as not approved.', verbose_name='Reason')),
375
+ ('comments', models.TextField(blank=True, help_text='Any comments about the observation.', verbose_name='comments')),
376
+ ('urn', models.TextField(blank=True, help_text='The globally unique identifier for the observation.', verbose_name='URN')),
377
+ ('data', models.JSONField(blank=True, default=dict, help_text='Data describing an Observation.', verbose_name='Data')),
378
+ ('checklist_old', models.IntegerField()),
379
+ ('country_old', models.IntegerField()),
380
+ ('county_old', models.IntegerField(null=True)),
381
+ ('location_old', models.IntegerField()),
382
+ ('observer_old', models.IntegerField()),
383
+ ('species_old', models.IntegerField()),
384
+ ('state_old', models.IntegerField()),
385
+ ('checklist', models.ForeignKey(help_text='The checklist this observation belongs to.', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='observations', to='data.checklist', verbose_name='checklist')),
386
+ ('country', models.ForeignKey(help_text='The country where the observation was made.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.country', verbose_name='country')),
387
+ ('county', models.ForeignKey(blank=True, help_text='The county where the observation was made.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.county', verbose_name='county')),
388
+ ('location', models.ForeignKey(help_text='The location where the observation was made.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.location', verbose_name='location')),
389
+ ('observer', models.ForeignKey(help_text='The person who made the observation.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.observer', verbose_name='observer')),
390
+ ('species', models.ForeignKey(help_text='The identified species.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.species', verbose_name='species')),
391
+ ('state', models.ForeignKey(help_text='The state where the observation was made.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.state', verbose_name='state')),
392
+ ],
393
+ options={
394
+ 'verbose_name': 'observation',
395
+ 'verbose_name_plural': 'observations',
396
+ },
397
+ ),
398
+ migrations.RunPython(
399
+ code=update_location_country,
400
+ reverse_code=django.db.migrations.operations.special.RunPython.noop,
401
+ ),
402
+ migrations.RunPython(
403
+ code=update_location_state,
404
+ reverse_code=django.db.migrations.operations.special.RunPython.noop,
405
+ ),
406
+ migrations.RunPython(
407
+ code=update_location_county,
408
+ reverse_code=django.db.migrations.operations.special.RunPython.noop,
409
+ ),
410
+ migrations.RunPython(
411
+ code=update_checklist_country,
412
+ reverse_code=django.db.migrations.operations.special.RunPython.noop,
413
+ ),
414
+ migrations.RunPython(
415
+ code=update_checklist_state,
416
+ reverse_code=django.db.migrations.operations.special.RunPython.noop,
417
+ ),
418
+ migrations.RunPython(
419
+ code=update_checklist_county,
420
+ reverse_code=django.db.migrations.operations.special.RunPython.noop,
421
+ ),
422
+ migrations.RunPython(
423
+ code=update_checklist_location,
424
+ reverse_code=django.db.migrations.operations.special.RunPython.noop,
425
+ ),
426
+ migrations.RunPython(
427
+ code=update_checklist_observer,
428
+ reverse_code=django.db.migrations.operations.special.RunPython.noop,
429
+ ),
430
+ migrations.RunPython(
431
+ code=update_observation_country,
432
+ reverse_code=django.db.migrations.operations.special.RunPython.noop,
433
+ ),
434
+ migrations.RunPython(
435
+ code=update_observation_state,
436
+ reverse_code=django.db.migrations.operations.special.RunPython.noop,
437
+ ),
438
+ migrations.RunPython(
439
+ code=update_observation_county,
440
+ reverse_code=django.db.migrations.operations.special.RunPython.noop,
441
+ ),
442
+ migrations.RunPython(
443
+ code=update_observation_location,
444
+ reverse_code=django.db.migrations.operations.special.RunPython.noop,
445
+ ),
446
+ migrations.RunPython(
447
+ code=update_observation_observer,
448
+ reverse_code=django.db.migrations.operations.special.RunPython.noop,
449
+ ),
450
+ migrations.RunPython(
451
+ code=update_observation_checklist,
452
+ reverse_code=django.db.migrations.operations.special.RunPython.noop,
453
+ ),
454
+ migrations.RunPython(
455
+ code=update_observation_species,
456
+ reverse_code=django.db.migrations.operations.special.RunPython.noop,
457
+ ),
458
+ migrations.RunPython(
459
+ code=update_filter_species,
460
+ reverse_code=django.db.migrations.operations.special.RunPython.noop,
461
+ ),
462
+ migrations.RunPython(
463
+ code=update_filter_location,
464
+ reverse_code=django.db.migrations.operations.special.RunPython.noop,
465
+ ),
466
+ migrations.RunPython(
467
+ code=update_filter_update_species,
468
+ reverse_code=django.db.migrations.operations.special.RunPython.noop,
469
+ ),
470
+ migrations.RemoveField(
471
+ model_name='checklist',
472
+ name='country_old',
473
+ ),
474
+ migrations.RemoveField(
475
+ model_name='checklist',
476
+ name='county_old',
477
+ ),
478
+ migrations.RemoveField(
479
+ model_name='checklist',
480
+ name='id',
481
+ ),
482
+ migrations.RemoveField(
483
+ model_name='checklist',
484
+ name='location_old',
485
+ ),
486
+ migrations.RemoveField(
487
+ model_name='checklist',
488
+ name='observer_old',
489
+ ),
490
+ migrations.RemoveField(
491
+ model_name='checklist',
492
+ name='state_old',
493
+ ),
494
+ migrations.RemoveField(
495
+ model_name='country',
496
+ name='id',
497
+ ),
498
+ migrations.RemoveField(
499
+ model_name='county',
500
+ name='id',
501
+ ),
502
+ migrations.RemoveField(
503
+ model_name='filter',
504
+ name='location_old',
505
+ ),
506
+ migrations.RemoveField(
507
+ model_name='filter',
508
+ name='species_old',
509
+ ),
510
+ migrations.RemoveField(
511
+ model_name='filter',
512
+ name='update_species_old',
513
+ ),
514
+ migrations.RemoveField(
515
+ model_name='location',
516
+ name='country_old',
517
+ ),
518
+ migrations.RemoveField(
519
+ model_name='location',
520
+ name='county_old',
521
+ ),
522
+ migrations.RemoveField(
523
+ model_name='location',
524
+ name='id',
525
+ ),
526
+ migrations.RemoveField(
527
+ model_name='location',
528
+ name='state_old',
529
+ ),
530
+ migrations.RemoveField(
531
+ model_name='observation',
532
+ name='checklist_old',
533
+ ),
534
+ migrations.RemoveField(
535
+ model_name='observation',
536
+ name='country_old',
537
+ ),
538
+ migrations.RemoveField(
539
+ model_name='observation',
540
+ name='county_old',
541
+ ),
542
+ migrations.RemoveField(
543
+ model_name='observation',
544
+ name='id',
545
+ ),
546
+ migrations.RemoveField(
547
+ model_name='observation',
548
+ name='location_old',
549
+ ),
550
+ migrations.RemoveField(
551
+ model_name='observation',
552
+ name='observer_old',
553
+ ),
554
+ migrations.RemoveField(
555
+ model_name='observation',
556
+ name='species_old',
557
+ ),
558
+ migrations.RemoveField(
559
+ model_name='observation',
560
+ name='state_old',
561
+ ),
562
+ migrations.RemoveField(
563
+ model_name='observer',
564
+ name='id',
565
+ ),
566
+ migrations.RemoveField(
567
+ model_name='species',
568
+ name='id',
569
+ ),
570
+ migrations.RemoveField(
571
+ model_name='state',
572
+ name='id',
573
+ ),
574
+ migrations.AlterField(
575
+ model_name='checklist',
576
+ name='country',
577
+ field=models.ForeignKey(help_text='The country where the checklist was made.', on_delete=django.db.models.deletion.PROTECT, related_name='checklists', to='data.country', verbose_name='country'),
578
+ ),
579
+ migrations.AlterField(
580
+ model_name='checklist',
581
+ name='location',
582
+ field=models.ForeignKey(help_text='The location where checklist was made.', on_delete=django.db.models.deletion.PROTECT, related_name='checklists', to='data.location', verbose_name='location'),
583
+ ),
584
+ migrations.AlterField(
585
+ model_name='checklist',
586
+ name='observer',
587
+ field=models.ForeignKey(help_text='The person who submitted the checklist.', on_delete=django.db.models.deletion.PROTECT, related_name='checklists', to='data.observer', verbose_name='observer'),
588
+ ),
589
+ migrations.AlterField(
590
+ model_name='checklist',
591
+ name='state',
592
+ field=models.ForeignKey(help_text='The state where the checklist was made.', on_delete=django.db.models.deletion.PROTECT, related_name='checklists', to='data.state', verbose_name='state'),
593
+ ),
594
+ migrations.AlterField(
595
+ model_name='filter',
596
+ name='species',
597
+ field=models.ForeignKey(help_text='The species used to find matching Observations.', on_delete=django.db.models.deletion.CASCADE, related_name='filtered_on', to='data.species', verbose_name='species'),
598
+ ),
599
+ migrations.AlterField(
600
+ model_name='filter',
601
+ name='update_species',
602
+ field=models.ForeignKey(help_text='Matching Observations are updated to this species.', on_delete=django.db.models.deletion.CASCADE, related_name='filtered_by', to='data.species', verbose_name='update species'),
603
+ ),
604
+ migrations.AlterField(
605
+ model_name='location',
606
+ name='country',
607
+ field=models.ForeignKey(help_text='The country for the location.', on_delete=django.db.models.deletion.PROTECT, related_name='locations', to='data.country', verbose_name='country'),
608
+ ),
609
+ migrations.AlterField(
610
+ model_name='location',
611
+ name='state',
612
+ field=models.ForeignKey(help_text='The state for the location.', on_delete=django.db.models.deletion.PROTECT, related_name='locations', to='data.state', verbose_name='state'),
613
+ ),
614
+ migrations.AlterField(
615
+ model_name='observation',
616
+ name='checklist',
617
+ field=models.ForeignKey(help_text='The checklist this observation belongs to.', on_delete=django.db.models.deletion.CASCADE, related_name='observations', to='data.checklist', verbose_name='checklist'),
618
+ ),
619
+ migrations.AlterField(
620
+ model_name='observation',
621
+ name='country',
622
+ field=models.ForeignKey(help_text='The country where the observation was made.', on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.country', verbose_name='country'),
623
+ ),
624
+ migrations.AlterField(
625
+ model_name='observation',
626
+ name='location',
627
+ field=models.ForeignKey(help_text='The location where the observation was made.', on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.location', verbose_name='location'),
628
+ ),
629
+ migrations.AlterField(
630
+ model_name='observation',
631
+ name='observer',
632
+ field=models.ForeignKey(help_text='The person who made the observation.', on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.observer', verbose_name='observer'),
633
+ ),
634
+ migrations.AlterField(
635
+ model_name='observation',
636
+ name='species',
637
+ field=models.ForeignKey(help_text='The identified species.', on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.species', verbose_name='species'),
638
+ ),
639
+ migrations.AlterField(
640
+ model_name='observation',
641
+ name='state',
642
+ field=models.ForeignKey(help_text='The state where the observation was made.', on_delete=django.db.models.deletion.PROTECT, related_name='observations', to='data.state', verbose_name='state'),
643
+ ),
644
+ migrations.RenameField(
645
+ model_name='checklist',
646
+ old_name='created',
647
+ new_name='added',
648
+ ),
649
+ migrations.AlterField(
650
+ model_name='checklist',
651
+ name='added',
652
+ field=models.DateTimeField(blank=True, help_text='The date and time the checklist was added to eBird.', null=True, verbose_name='added'),
653
+ ),
654
+ migrations.AddField(
655
+ model_name='checklist',
656
+ name='created',
657
+ field=models.DateTimeField(auto_now_add=True, help_text='When was the record created.', null=True),
658
+ ),
659
+ migrations.AddField(
660
+ model_name='country',
661
+ name='created',
662
+ field=models.DateTimeField(auto_now_add=True, help_text='When was the record created.', null=True),
663
+ ),
664
+ migrations.AddField(
665
+ model_name='county',
666
+ name='created',
667
+ field=models.DateTimeField(auto_now_add=True, help_text='When was the record created.', null=True),
668
+ ),
669
+ migrations.AddField(
670
+ model_name='filter',
671
+ name='created',
672
+ field=models.DateTimeField(auto_now_add=True, help_text='When was the record created.', null=True),
673
+ ),
674
+ migrations.AddField(
675
+ model_name='location',
676
+ name='created',
677
+ field=models.DateTimeField(auto_now_add=True, help_text='When was the record created.', null=True),
678
+ ),
679
+ migrations.AddField(
680
+ model_name='observation',
681
+ name='created',
682
+ field=models.DateTimeField(auto_now_add=True, help_text='When was the record created.', null=True),
683
+ ),
684
+ migrations.AddField(
685
+ model_name='observer',
686
+ name='created',
687
+ field=models.DateTimeField(auto_now_add=True, help_text='When was the record created.', null=True),
688
+ ),
689
+ migrations.AddField(
690
+ model_name='species',
691
+ name='created',
692
+ field=models.DateTimeField(auto_now_add=True, help_text='When was the record created.', null=True),
693
+ ),
694
+ migrations.AddField(
695
+ model_name='state',
696
+ name='created',
697
+ field=models.DateTimeField(auto_now_add=True, help_text='When was the record created.', null=True),
698
+ ),
699
+ migrations.AlterField(
700
+ model_name='species',
701
+ name='category',
702
+ field=models.TextField(blank=True, choices=[('species', 'Species'), ('slash', 'Species pairs'), ('issf', 'Subspecies'), ('domestic', 'Domestic species'), ('hybrid', 'Hybrids'), ('form', 'Species forms'), ('spuh', 'Unidentified species'), ('intergrade', 'Intergrades')], help_text='The category from the eBird/Clements taxonomy.', verbose_name='category'),
703
+ ),
704
+ ]
@@ -0,0 +1,58 @@
1
+ # Generated by Django 5.2.4 on 2025-07-24 09:11
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('data', '0001_squashed_0010_alter_species_category'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AddField(
14
+ model_name='checklist',
15
+ name='modified',
16
+ field=models.DateTimeField(auto_now=True, help_text='When was the record updated.', null=True),
17
+ ),
18
+ migrations.AddField(
19
+ model_name='country',
20
+ name='modified',
21
+ field=models.DateTimeField(auto_now=True, help_text='When was the record updated.', null=True),
22
+ ),
23
+ migrations.AddField(
24
+ model_name='county',
25
+ name='modified',
26
+ field=models.DateTimeField(auto_now=True, help_text='When was the record updated.', null=True),
27
+ ),
28
+ migrations.AddField(
29
+ model_name='filter',
30
+ name='modified',
31
+ field=models.DateTimeField(auto_now=True, help_text='When was the record updated.', null=True),
32
+ ),
33
+ migrations.AddField(
34
+ model_name='location',
35
+ name='modified',
36
+ field=models.DateTimeField(auto_now=True, help_text='When was the record updated.', null=True),
37
+ ),
38
+ migrations.AddField(
39
+ model_name='observation',
40
+ name='modified',
41
+ field=models.DateTimeField(auto_now=True, help_text='When was the record updated.', null=True),
42
+ ),
43
+ migrations.AddField(
44
+ model_name='observer',
45
+ name='modified',
46
+ field=models.DateTimeField(auto_now=True, help_text='When was the record updated.', null=True),
47
+ ),
48
+ migrations.AddField(
49
+ model_name='species',
50
+ name='modified',
51
+ field=models.DateTimeField(auto_now=True, help_text='When was the record updated.', null=True),
52
+ ),
53
+ migrations.AddField(
54
+ model_name='state',
55
+ name='modified',
56
+ field=models.DateTimeField(auto_now=True, help_text='When was the record updated.', null=True),
57
+ ),
58
+ ]
@@ -192,6 +192,10 @@ class Checklist(models.Model):
192
192
  null=True, auto_now_add=True, help_text=_("When was the record created.")
193
193
  )
194
194
 
195
+ modified = models.DateTimeField(
196
+ null=True, auto_now=True, help_text=_("When was the record updated.")
197
+ )
198
+
195
199
  def __repr__(self) -> str:
196
200
  return str(self.identifier)
197
201
 
@@ -26,6 +26,10 @@ class Country(models.Model):
26
26
  null=True, auto_now_add=True, help_text=_("When was the record created.")
27
27
  )
28
28
 
29
+ modified = models.DateTimeField(
30
+ null=True, auto_now=True, help_text=_("When was the record updated.")
31
+ )
32
+
29
33
  def __repr__(self) -> str:
30
34
  return str(self.code)
31
35
 
@@ -26,6 +26,10 @@ class County(models.Model):
26
26
  null=True, auto_now_add=True, help_text=_("When was the record created.")
27
27
  )
28
28
 
29
+ modified = models.DateTimeField(
30
+ null=True, auto_now=True, help_text=_("When was the record updated.")
31
+ )
32
+
29
33
  def __repr__(self) -> str:
30
34
  return str(self.code)
31
35
 
@@ -52,6 +52,10 @@ class Filter(models.Model):
52
52
  null=True, auto_now_add=True, help_text=_("When was the record created.")
53
53
  )
54
54
 
55
+ modified = models.DateTimeField(
56
+ null=True, auto_now=True, help_text=_("When was the record updated.")
57
+ )
58
+
55
59
  def __repr__(self) -> str:
56
60
  return str(self.name)
57
61
 
@@ -151,6 +151,10 @@ class Location(models.Model):
151
151
  null=True, auto_now_add=True, help_text=_("When was the record created.")
152
152
  )
153
153
 
154
+ modified = models.DateTimeField(
155
+ null=True, auto_now=True, help_text=_("When was the record updated.")
156
+ )
157
+
154
158
  def __repr__(self) -> str:
155
159
  return str(self.identifier)
156
160
 
@@ -175,6 +175,10 @@ class Observation(models.Model):
175
175
  null=True, auto_now_add=True, help_text=_("When was the record created.")
176
176
  )
177
177
 
178
+ modified = models.DateTimeField(
179
+ null=True, auto_now=True, help_text=_("When was the record updated.")
180
+ )
181
+
178
182
  def __repr__(self) -> str:
179
183
  return str(self.identifier)
180
184
 
@@ -47,6 +47,10 @@ class Observer(models.Model):
47
47
  null=True, auto_now_add=True, help_text=_("When was the record created.")
48
48
  )
49
49
 
50
+ modified = models.DateTimeField(
51
+ null=True, auto_now=True, help_text=_("When was the record updated.")
52
+ )
53
+
50
54
  def __repr__(self) -> str:
51
55
  return str(self.identifier)
52
56
 
@@ -97,6 +97,10 @@ class Species(models.Model):
97
97
  null=True, auto_now_add=True, help_text=_("When was the record created.")
98
98
  )
99
99
 
100
+ modified = models.DateTimeField(
101
+ null=True, auto_now=True, help_text=_("When was the record updated.")
102
+ )
103
+
100
104
  def __repr__(self) -> str:
101
105
  return str(self.species_code)
102
106
 
@@ -26,6 +26,10 @@ class State(models.Model):
26
26
  null=True, auto_now_add=True, help_text=_("When was the record created.")
27
27
  )
28
28
 
29
+ modified = models.DateTimeField(
30
+ null=True, auto_now=True, help_text=_("When was the record updated.")
31
+ )
32
+
29
33
  def __repr__(self) -> str:
30
34
  return str(self.code)
31
35
 
@@ -1 +0,0 @@
1
- __version__ = "0.2.2"
File without changes
File without changes