misleep 0.2.0b0__tar.gz → 0.2.2b0__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 (55) hide show
  1. {misleep-0.2.0b0 → misleep-0.2.2b0}/PKG-INFO +2 -2
  2. {misleep-0.2.0b0 → misleep-0.2.2b0}/README.md +1 -1
  3. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/config.ini +2 -2
  4. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/gui/dialog.py +16 -2
  5. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/gui/main_window.py +6 -1
  6. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/gui/uis/main_window_ui.py +5 -5
  7. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/gui/uis/transfer_result_dialog_ui.py +32 -13
  8. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/io/signal_io.py +13 -6
  9. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep.egg-info/PKG-INFO +2 -2
  10. {misleep-0.2.0b0 → misleep-0.2.2b0}/setup.py +1 -1
  11. {misleep-0.2.0b0 → misleep-0.2.2b0}/LICENSE +0 -0
  12. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/__init__.py +0 -0
  13. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/__main__.py +0 -0
  14. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/gui/__init__.py +0 -0
  15. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/gui/about.py +0 -0
  16. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/gui/resources/__init__.py +0 -0
  17. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/gui/resources/entire_logo.png +0 -0
  18. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/gui/resources/logo.png +0 -0
  19. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/gui/resources/misleep.py +0 -0
  20. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/gui/resources/misleep.qrc +0 -0
  21. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/gui/show.py +0 -0
  22. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/gui/spec_window.py +0 -0
  23. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/gui/thread.py +0 -0
  24. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/gui/uis/__init__.py +0 -0
  25. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/gui/uis/about_ui.py +0 -0
  26. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/gui/uis/label_dialog_ui.py +0 -0
  27. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/gui/uis/save_data_dialog_ui.py +0 -0
  28. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/gui/uis/spec_window_ui.py +0 -0
  29. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/gui/utils.py +0 -0
  30. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/io/__init__.py +0 -0
  31. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/io/annotation_io.py +0 -0
  32. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/io/base.py +0 -0
  33. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/preprocessing/__init__.py +0 -0
  34. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/preprocessing/channel.py +0 -0
  35. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/preprocessing/signals.py +0 -0
  36. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/preprocessing/spectral.py +0 -0
  37. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/utils/__init__.py +0 -0
  38. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/utils/annotation.py +0 -0
  39. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/utils/signals.py +0 -0
  40. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/viz/__init__.py +0 -0
  41. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/viz/hypnogram.py +0 -0
  42. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/viz/signals.py +0 -0
  43. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep/viz/spectral.py +0 -0
  44. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep.egg-info/SOURCES.txt +0 -0
  45. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep.egg-info/dependency_links.txt +0 -0
  46. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep.egg-info/requires.txt +0 -0
  47. {misleep-0.2.0b0 → misleep-0.2.2b0}/misleep.egg-info/top_level.txt +0 -0
  48. {misleep-0.2.0b0 → misleep-0.2.2b0}/setup.cfg +0 -0
  49. {misleep-0.2.0b0 → misleep-0.2.2b0}/test/test_annotation_io.py +0 -0
  50. {misleep-0.2.0b0 → misleep-0.2.2b0}/test/test_loadmat73.py +0 -0
  51. {misleep-0.2.0b0 → misleep-0.2.2b0}/test/test_midata.py +0 -0
  52. {misleep-0.2.0b0 → misleep-0.2.2b0}/test/test_show.py +0 -0
  53. {misleep-0.2.0b0 → misleep-0.2.2b0}/test/test_signal_io.py +0 -0
  54. {misleep-0.2.0b0 → misleep-0.2.2b0}/test/test_signals_viz.py +0 -0
  55. {misleep-0.2.0b0 → misleep-0.2.2b0}/test/test_spectral_viz.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: misleep
3
- Version: 0.2.0b0
3
+ Version: 0.2.2b0
4
4
  Summary: MiSleep: Mice Sleep EEG/EMG visualization, scoring and analysis.
5
5
  Home-page: https://github.com/BryanWang0702/MiSleep/
6
6
  Download-URL: https://github.com/BryanWang0702/MiSleep/
@@ -37,7 +37,7 @@ MiSleep is for EEG/EMG signal processing and visualization
37
37
 
38
38
  ## Get start
39
39
  ```shell
40
- pip install misleep==0.1.3b
40
+ pip install misleep==0.2.2b0
41
41
  ```
42
42
 
43
43
  ### New features
@@ -5,7 +5,7 @@ MiSleep is for EEG/EMG signal processing and visualization
5
5
 
6
6
  ## Get start
7
7
  ```shell
8
- pip install misleep==0.1.3b
8
+ pip install misleep==0.2.2b0
9
9
  ```
10
10
 
11
11
  ### New features
@@ -1,5 +1,5 @@
1
1
  [gui]
2
- version = v0.2.0 Beta
2
+ version = v0.2.2 Beta
3
3
  updatetime = 2024/04/01
4
4
  marker = ['pat', 'add water', 'third']
5
5
  startend = ['SWA', 'SWA', 'start end label', 'start end label', 'start end label', 'start end label', 'start end label']
@@ -8,5 +8,5 @@ statecolor = {"1": "orange", "2": "skyblue", "3": "red", "4": "white"}
8
8
  statecolorbgalpha = 0.1
9
9
  markerlinecolor = "red"
10
10
  startendlinecolor = "blue"
11
- openpath = E:/workplace/EEGProcessing/00_DATA/medusa/example_data/15_48_32_055/label.txt
11
+ openpath = E:/workplace/EEGProcessing/00_DATA/20240117_0700_WXQ_3mice_24h/mouse2/mouse2_label.txt
12
12
 
@@ -158,11 +158,16 @@ class transferResult_dialog(QDialog, Ui_TransferResultDialog):
158
158
  self.setupUi(self)
159
159
 
160
160
  self.ACTimeEditor.setDisabled(True)
161
- self.ResetTimeCheckBox.clicked.connect(self.enable_time_editor)
161
+ self.TransferStartTimeEdit.setDisabled(True)
162
+ self.ResetTimeCheckBox.clicked.connect(self.enable_ac_time_editor)
163
+ self.ResetTransferStartTimeCheckBox.clicked.connect(self.enable_start_time_editor)
162
164
 
163
- def enable_time_editor(self):
165
+ def enable_ac_time_editor(self):
164
166
  self.ACTimeEditor.setEnabled(True)
165
167
 
168
+ def enable_start_time_editor(self):
169
+ self.TransferStartTimeEdit.setEnabled(True)
170
+
166
171
  def transfer(self, config, mianno, ac_time):
167
172
  """Transfer result to dataframe, triggered by okay button"""
168
173
 
@@ -171,6 +176,15 @@ class transferResult_dialog(QDialog, Ui_TransferResultDialog):
171
176
  else:
172
177
  ac_time = datetime.datetime.strptime(ac_time, "%Y%m%d-%H:%M:%S")
173
178
 
179
+ if self.ResetTransferStartTimeCheckBox.isChecked():
180
+ start_time = self.TransferStartTimeEdit.dateTime().toPyDateTime()
181
+ if start_time > ac_time:
182
+ delay_seconds = (start_time - ac_time).seconds
183
+ mianno._marker = mianno.marker[delay_seconds:]
184
+ mianno._start_end = mianno.start_end[delay_seconds:]
185
+ mianno._sleep_state = mianno.sleep_state[delay_seconds:]
186
+ ac_time = start_time
187
+
174
188
 
175
189
  fd, _ = QFileDialog.getSaveFileName(self, "Save transfered result",
176
190
  f"{config['gui']['openpath'].split('/')[0]}/transfer_result.xlsx",
@@ -916,6 +916,7 @@ class main_window(QMainWindow, Ui_MiSleep):
916
916
  self.plot_marker_line()
917
917
 
918
918
  self.is_saved = False
919
+ self.AnnotationPathLabel.setText('*Annotation path:')
919
920
 
920
921
  if self.StartEndRadio.isChecked():
921
922
  x = round(event.xdata / self.midata.sf[
@@ -1289,6 +1290,7 @@ class main_window(QMainWindow, Ui_MiSleep):
1289
1290
  [sleep_type] * (self.start_end[1] - self.start_end[0])
1290
1291
 
1291
1292
  self.is_saved = False
1293
+ self.AnnotationPathLabel.setText('*Annotation path:')
1292
1294
  self.replot_sleep_state_bg(state=sleep_type)
1293
1295
  self.plot_hypo()
1294
1296
 
@@ -1319,6 +1321,7 @@ class main_window(QMainWindow, Ui_MiSleep):
1319
1321
  self.plot_start_end_label_line()
1320
1322
 
1321
1323
  self.is_saved = False
1324
+ self.AnnotationPathLabel.setText('*Annotation path:')
1322
1325
 
1323
1326
  def about_bar_dispatcher(self, signal):
1324
1327
  """Triggered by AboutBar action, show About dialog"""
@@ -1349,6 +1352,7 @@ class main_window(QMainWindow, Ui_MiSleep):
1349
1352
  def transfer_result(self):
1350
1353
  """Transfer result into file"""
1351
1354
  self.transfer_result_dialog.ACTimeEditor.setDateTime(self.ac_time)
1355
+ self.transfer_result_dialog.TransferStartTimeEdit.setDateTime(self.ac_time)
1352
1356
  self.transfer_result_dialog.exec_()
1353
1357
  if self.label_dialog.closed:
1354
1358
  return
@@ -1363,7 +1367,8 @@ class main_window(QMainWindow, Ui_MiSleep):
1363
1367
  saved = save_thread.save_anno()
1364
1368
  if saved:
1365
1369
  self.is_saved = True
1366
- QMessageBox.about(self, "Info", "Annotation saved")
1370
+
1371
+ self.AnnotationPathLabel.setText('Annotation path:')
1367
1372
  save_thread.quit()
1368
1373
 
1369
1374
  def save_data(self):
@@ -69,9 +69,9 @@ class Ui_MiSleep(object):
69
69
  self.DataPathEdit.setReadOnly(True)
70
70
  self.DataPathEdit.setObjectName("DataPathEdit")
71
71
  self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.DataPathEdit)
72
- self.label_5 = QtWidgets.QLabel(self.dockWidgetContents_3)
73
- self.label_5.setObjectName("label_5")
74
- self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_5)
72
+ self.AnnotationPathLabel = QtWidgets.QLabel(self.dockWidgetContents_3)
73
+ self.AnnotationPathLabel.setObjectName("AnnotationPathLabel")
74
+ self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.AnnotationPathLabel)
75
75
  self.AnnoPathEdit = QtWidgets.QLineEdit(self.dockWidgetContents_3)
76
76
  self.AnnoPathEdit.setReadOnly(True)
77
77
  self.AnnoPathEdit.setObjectName("AnnoPathEdit")
@@ -355,7 +355,7 @@ class Ui_MiSleep(object):
355
355
  MiSleep.setWindowTitle(_translate("MiSleep", "MiSleep"))
356
356
  self.MetaDock.setWindowTitle(_translate("MiSleep", "Meta"))
357
357
  self.label_4.setText(_translate("MiSleep", "Data path:"))
358
- self.label_5.setText(_translate("MiSleep", "Annotation path:"))
358
+ self.AnnotationPathLabel.setText(_translate("MiSleep", "Annotation path:"))
359
359
  self.label_6.setText(_translate("MiSleep", "Acquisition Time:"))
360
360
  self.AcTimeEdit.setDisplayFormat(_translate("MiSleep", "yyyy/MM/dd HH:mm:ss"))
361
361
  self.ChannelDock.setWindowTitle(_translate("MiSleep", "Channel"))
@@ -407,4 +407,4 @@ class Ui_MiSleep(object):
407
407
  self.actionMerge_Data.setText(_translate("MiSleep", "Merge Data"))
408
408
  self.actionTransfer_Result.setText(_translate("MiSleep", "Transfer Result"))
409
409
  self.actionTransfer_Result.setToolTip(_translate("MiSleep", "Transfer Result"))
410
- from misleep.gui.resources import misleep
410
+ from misleep.gui.resources import misleep
@@ -14,27 +14,43 @@ from PyQt5 import QtCore, QtGui, QtWidgets
14
14
  class Ui_TransferResultDialog(object):
15
15
  def setupUi(self, TransferResultDialog):
16
16
  TransferResultDialog.setObjectName("TransferResultDialog")
17
- TransferResultDialog.resize(324, 193)
17
+ TransferResultDialog.resize(278, 290)
18
18
  self.verticalLayout = QtWidgets.QVBoxLayout(TransferResultDialog)
19
19
  self.verticalLayout.setObjectName("verticalLayout")
20
20
  self.groupBox = QtWidgets.QGroupBox(TransferResultDialog)
21
21
  self.groupBox.setObjectName("groupBox")
22
22
  self.gridLayout = QtWidgets.QGridLayout(self.groupBox)
23
23
  self.gridLayout.setObjectName("gridLayout")
24
- self.ResetTimeCheckBox = QtWidgets.QCheckBox(self.groupBox)
25
- self.ResetTimeCheckBox.setObjectName("ResetTimeCheckBox")
26
- self.gridLayout.addWidget(self.ResetTimeCheckBox, 0, 0, 1, 1)
24
+ self.line = QtWidgets.QFrame(self.groupBox)
25
+ self.line.setFrameShape(QtWidgets.QFrame.HLine)
26
+ self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
27
+ self.line.setObjectName("line")
28
+ self.gridLayout.addWidget(self.line, 5, 0, 1, 2)
29
+ self.RejectArtifactCheckBox = QtWidgets.QCheckBox(self.groupBox)
30
+ self.RejectArtifactCheckBox.setObjectName("RejectArtifactCheckBox")
31
+ self.gridLayout.addWidget(self.RejectArtifactCheckBox, 7, 0, 1, 1)
32
+ self.ContainEventsCheckBox = QtWidgets.QCheckBox(self.groupBox)
33
+ self.ContainEventsCheckBox.setObjectName("ContainEventsCheckBox")
34
+ self.gridLayout.addWidget(self.ContainEventsCheckBox, 4, 0, 1, 1)
35
+ self.StateSpecAnalysisCheckBox = QtWidgets.QCheckBox(self.groupBox)
36
+ self.StateSpecAnalysisCheckBox.setObjectName("StateSpecAnalysisCheckBox")
37
+ self.gridLayout.addWidget(self.StateSpecAnalysisCheckBox, 6, 0, 1, 1)
27
38
  self.ACTimeEditor = QtWidgets.QDateTimeEdit(self.groupBox)
28
39
  self.ACTimeEditor.setObjectName("ACTimeEditor")
29
40
  self.gridLayout.addWidget(self.ACTimeEditor, 1, 0, 1, 1)
30
- self.ContainEventsCheckBox = QtWidgets.QCheckBox(self.groupBox)
31
- self.ContainEventsCheckBox.setObjectName("ContainEventsCheckBox")
32
- self.gridLayout.addWidget(self.ContainEventsCheckBox, 3, 0, 1, 1)
41
+ self.ResetTimeCheckBox = QtWidgets.QCheckBox(self.groupBox)
42
+ self.ResetTimeCheckBox.setObjectName("ResetTimeCheckBox")
43
+ self.gridLayout.addWidget(self.ResetTimeCheckBox, 0, 0, 1, 1)
44
+ self.ResetTransferStartTimeCheckBox = QtWidgets.QCheckBox(self.groupBox)
45
+ self.ResetTransferStartTimeCheckBox.setObjectName("ResetTransferStartTimeCheckBox")
46
+ self.gridLayout.addWidget(self.ResetTransferStartTimeCheckBox, 2, 0, 1, 1)
33
47
  spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
34
48
  self.gridLayout.addItem(spacerItem, 1, 1, 1, 1)
35
- self.RejectArtifactCheckBox = QtWidgets.QCheckBox(self.groupBox)
36
- self.RejectArtifactCheckBox.setObjectName("RejectArtifactCheckBox")
37
- self.gridLayout.addWidget(self.RejectArtifactCheckBox, 2, 0, 1, 1)
49
+ self.TransferStartTimeEdit = QtWidgets.QDateTimeEdit(self.groupBox)
50
+ self.TransferStartTimeEdit.setObjectName("TransferStartTimeEdit")
51
+ self.gridLayout.addWidget(self.TransferStartTimeEdit, 3, 0, 1, 1)
52
+ spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
53
+ self.gridLayout.addItem(spacerItem1, 3, 1, 1, 1)
38
54
  self.verticalLayout.addWidget(self.groupBox)
39
55
  self.buttonBox = QtWidgets.QDialogButtonBox(TransferResultDialog)
40
56
  self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
@@ -51,7 +67,10 @@ class Ui_TransferResultDialog(object):
51
67
  _translate = QtCore.QCoreApplication.translate
52
68
  TransferResultDialog.setWindowTitle(_translate("TransferResultDialog", "Dialog"))
53
69
  self.groupBox.setTitle(_translate("TransferResultDialog", "Transfer result options"))
54
- self.ResetTimeCheckBox.setText(_translate("TransferResultDialog", "Reset acquisition time"))
55
- self.ACTimeEditor.setDisplayFormat(_translate("TransferResultDialog", "yyyy/MM/dd HH:mm:ss"))
56
- self.ContainEventsCheckBox.setText(_translate("TransferResultDialog", "Contain Start-End events"))
57
70
  self.RejectArtifactCheckBox.setText(_translate("TransferResultDialog", "Reject artifact"))
71
+ self.ContainEventsCheckBox.setText(_translate("TransferResultDialog", "Contain Start-End events"))
72
+ self.StateSpecAnalysisCheckBox.setText(_translate("TransferResultDialog", "State spectral analysis"))
73
+ self.ACTimeEditor.setDisplayFormat(_translate("TransferResultDialog", "yyyy/MM/dd HH:mm:ss"))
74
+ self.ResetTimeCheckBox.setText(_translate("TransferResultDialog", "Reset acquisition time"))
75
+ self.ResetTransferStartTimeCheckBox.setText(_translate("TransferResultDialog", "Reset transfer start time"))
76
+ self.TransferStartTimeEdit.setDisplayFormat(_translate("TransferResultDialog", "yyyy/MM/dd HH:mm:ss"))
@@ -47,9 +47,12 @@ def load_mat(data_path):
47
47
 
48
48
  # If old version misleep data
49
49
  if names is None:
50
- signals = raw_data
51
- channels = [f'ch{each + 1}' for each in range(raw_data.shape[0])]
52
- sf = [305. for _ in range(raw_data.shape[0])]
50
+ if raw_data.shape[0] > raw_data.shape[1]:
51
+ signals = raw_data.T
52
+ else:
53
+ signals = raw_data
54
+ channels = [f'ch{each + 1}' for each in range(signals.shape[0])]
55
+ sf = [305. for _ in range(signals.shape[0])]
53
56
  time = datetime.datetime.now().strftime("%Y%m%d-%H:%M:%S")
54
57
  return MiData(signals=signals, channels=channels, sf=sf, time=time)
55
58
 
@@ -88,9 +91,13 @@ def load_mat(data_path):
88
91
 
89
92
  except Exception:
90
93
  # If old version misleep data
91
- signals = raw_data
92
- channels = [f'ch{each + 1}' for each in range(raw_data.shape[0])]
93
- sf = [305. for _ in range(raw_data.shape[0])]
94
+ if raw_data.shape[0] > raw_data.shape[1]:
95
+ signals = raw_data.T
96
+ else:
97
+ signals = raw_data
98
+
99
+ channels = [f'ch{each + 1}' for each in range(signals.shape[0])]
100
+ sf = [305. for _ in range(signals.shape[0])]
94
101
  time = datetime.datetime.now().strftime("%Y%m%d-%H:%M:%S")
95
102
  return MiData(signals=signals, channels=channels, sf=sf, time=time)
96
103
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: misleep
3
- Version: 0.2.0b0
3
+ Version: 0.2.2b0
4
4
  Summary: MiSleep: Mice Sleep EEG/EMG visualization, scoring and analysis.
5
5
  Home-page: https://github.com/BryanWang0702/MiSleep/
6
6
  Download-URL: https://github.com/BryanWang0702/MiSleep/
@@ -37,7 +37,7 @@ MiSleep is for EEG/EMG signal processing and visualization
37
37
 
38
38
  ## Get start
39
39
  ```shell
40
- pip install misleep==0.1.3b
40
+ pip install misleep==0.2.2b0
41
41
  ```
42
42
 
43
43
  ### New features
@@ -11,7 +11,7 @@ MAINTAINER_EMAIL = "swang@gmail.com"
11
11
  URL = "https://github.com/BryanWang0702/MiSleep/"
12
12
  LICENSE = "BSD (3-clause)"
13
13
  DOWNLOAD_URL = "https://github.com/BryanWang0702/MiSleep/"
14
- VERSION = "0.2.0 Beta"
14
+ VERSION = "0.2.2b0"
15
15
 
16
16
  INSTALL_REQUIRES = [
17
17
  "numpy>=1.18.1",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes