boris-behav-obs 9.3.2__py2.py3-none-any.whl → 9.3.3__py2.py3-none-any.whl

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.
boris/config.py CHANGED
@@ -155,6 +155,7 @@ CHECK_PROJECT_INTEGRITY = "check_project_integrity"
155
155
  YES = "Yes"
156
156
  NO = "No"
157
157
  CANCEL = "Cancel"
158
+ IGNORE = "Ignore"
158
159
  APPEND = "Append"
159
160
  CLOSE = "Close"
160
161
  REPLACE = "Replace"
@@ -454,7 +455,8 @@ POINT = "POINT"
454
455
  START = "START"
455
456
  STOP = "STOP"
456
457
 
457
- PLAYER1, PLAYER2 = "1", "2"
458
+ PLAYER1 = "1"
459
+ PLAYER2 = "2"
458
460
  ALL_PLAYERS = [str(x + 1) for x in range(N_PLAYER)]
459
461
 
460
462
  VISUALIZE_SPECTROGRAM = "visualize_spectrogram"
@@ -701,6 +703,7 @@ EMPTY_PROJECT = {
701
703
  ETHOGRAM: {},
702
704
  OBSERVATIONS: {},
703
705
  BEHAVIORAL_CATEGORIES: [],
706
+ BEHAVIORAL_CATEGORIES_CONF: {},
704
707
  INDEPENDENT_VARIABLES: {},
705
708
  CODING_MAP: {},
706
709
  BEHAVIORS_CODING_MAP: [],
boris/core.py CHANGED
@@ -114,7 +114,6 @@ from . import cmd_arguments
114
114
 
115
115
  from . import core_qrc
116
116
  from .core_ui import Ui_MainWindow
117
- import exifread
118
117
  from . import config as cfg
119
118
  from . import video_operations
120
119
 
@@ -4317,12 +4316,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
4317
4316
  if not sys.platform.startswith(cfg.MACOS_CODE):
4318
4317
  if self.dw_player[0].player.time_pos is not None:
4319
4318
  for n_player in range(1, len(self.dw_player)):
4320
- print(f"{n_player=}")
4321
-
4322
4319
  ct = self.getLaps(n_player=n_player)
4323
4320
 
4324
- print(f"{ct=}")
4325
-
4326
4321
  # sync players 2..8 if time diff >= 1 s
4327
4322
  if (
4328
4323
  abs(ct0 - (ct + dec(self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.OFFSET][str(n_player + 1)])))
boris/dialog.py CHANGED
@@ -88,7 +88,7 @@ def MessageDialog(title: str, text: str, buttons: tuple) -> str:
88
88
  for button in buttons:
89
89
  message.addButton(button, QMessageBox.YesRole)
90
90
 
91
- message.setWindowFlags(Qt.WindowStaysOnTopHint)
91
+ message.setWindowFlags(message.windowFlags() | Qt.WindowStaysOnTopHint)
92
92
  message.exec()
93
93
  return message.clickedButton().text()
94
94
 
boris/media_file.py CHANGED
@@ -20,11 +20,13 @@ This file is part of BORIS.
20
20
 
21
21
  """
22
22
 
23
+ from PySide6.QtWidgets import QFileDialog
24
+
23
25
  from . import config as cfg
24
26
  from . import utilities as util
25
27
  from . import dialog
26
28
  from . import project_functions
27
- from PySide6.QtWidgets import QFileDialog
29
+ from . import utilities as util
28
30
 
29
31
 
30
32
  def get_info(self) -> None:
@@ -38,17 +40,17 @@ def get_info(self) -> None:
38
40
  if "error" in r:
39
41
  ffmpeg_output = f"File path: {media_full_path}<br><br>{r['error']}<br><br>"
40
42
  else:
41
- ffmpeg_output = f"<br><b>{r['analysis_program'] } analysis</b><br>"
43
+ ffmpeg_output = f"<br><b>{r['analysis_program']} analysis</b><br>"
42
44
 
43
45
  ffmpeg_output += (
44
46
  f"File path: <b>{media_full_path}</b><br><br>"
45
47
  f"Duration: {r['duration']} seconds ({util.convertTime(self.timeFormat, r['duration'])})<br>"
48
+ f"FPS: {r['fps']}<br>"
49
+ f"Resolution: {r['resolution']} pixels<br>"
46
50
  f"Format long name: {r.get('format_long_name', cfg.NA)}<br>"
47
51
  f"Creation time: {r.get('creation_time', cfg.NA)}<br>"
48
- f"Resolution: {r['resolution']}<br>"
49
52
  f"Number of frames: {r['frames_number']}<br>"
50
53
  f"Bitrate: {util.smart_size_format(r['bitrate'])} <br>"
51
- f"FPS: {r['fps']}<br>"
52
54
  f"Has video: {r['has_video']}<br>"
53
55
  f"Has audio: {r['has_audio']}<br>"
54
56
  f"File size: {util.smart_size_format(r.get('file size', cfg.NA))}<br>"
@@ -70,6 +72,12 @@ def get_info(self) -> None:
70
72
 
71
73
  mpv_output = (
72
74
  "<b>MPV information</b><br>"
75
+ f"Duration: {dw.player.duration} seconds ({util.seconds2time(dw.player.duration)})<br>"
76
+ # "Position: {} %<br>"
77
+ f"FPS: {dw.player.container_fps}<br>"
78
+ # "Rate: {}<br>"
79
+ f"Resolution: {dw.player.width}x{dw.player.height} pixels<br>"
80
+ # "Scale: {}<br>"
73
81
  f"Video format: {dw.player.video_format}<br>"
74
82
  # "State: {}<br>"
75
83
  # "Media Resource Location: {}<br>"
@@ -77,12 +85,6 @@ def get_info(self) -> None:
77
85
  # "Track: {}/{}<br>"
78
86
  f"Number of media in media list: {dw.player.playlist_count}<br>"
79
87
  f"Current time position: {dw.player.time_pos}<br>"
80
- f"Duration: {dw.player.duration}<br>"
81
- # "Position: {} %<br>"
82
- f"FPS: {dw.player.container_fps}<br>"
83
- # "Rate: {}<br>"
84
- f"Video size: {dw.player.width}x{dw.player.height}<br>"
85
- # "Scale: {}<br>"
86
88
  f"Aspect ratio: {round(dw.player.width / dw.player.height, 3)}<br>"
87
89
  # "is seekable? {}<br>"
88
90
  # "has_vout? {}<br>"
@@ -2406,15 +2406,15 @@ def event2media_file_name(observation: dict, timestamp: dec) -> Optional[str]:
2406
2406
  """
2407
2407
 
2408
2408
  cumul_media_durations: list = [dec(0)]
2409
- for media_file in observation[cfg.FILE]["1"]:
2409
+ for media_file in observation[cfg.FILE][cfg.PLAYER1]:
2410
2410
  media_duration = dec(str(observation[cfg.MEDIA_INFO][cfg.LENGTH][media_file]))
2411
- cumul_media_durations.append(cumul_media_durations[-1] + media_duration)
2411
+ cumul_media_durations.append(round(cumul_media_durations[-1] + media_duration, 3))
2412
2412
 
2413
2413
  cumul_media_durations.remove(dec(0))
2414
2414
 
2415
2415
  # test if timestamp is at end of last media
2416
2416
  if timestamp == cumul_media_durations[-1]:
2417
- player_idx = len(observation[cfg.FILE]["1"]) - 1
2417
+ player_idx = len(observation[cfg.FILE][cfg.PLAYER1]) - 1
2418
2418
  else:
2419
2419
  player_idx = -1
2420
2420
  for idx, value in enumerate(cumul_media_durations):
@@ -2424,7 +2424,7 @@ def event2media_file_name(observation: dict, timestamp: dec) -> Optional[str]:
2424
2424
  break
2425
2425
 
2426
2426
  if player_idx != -1:
2427
- video_file_name = observation[cfg.FILE]["1"][player_idx]
2427
+ video_file_name = observation[cfg.FILE][cfg.PLAYER1][player_idx]
2428
2428
  else:
2429
2429
  video_file_name = None
2430
2430
 
boris/project.py CHANGED
@@ -82,12 +82,12 @@ class BehavioralCategories(QDialog):
82
82
  # add categories
83
83
  self.lw.setColumnCount(2)
84
84
  self.lw.setHorizontalHeaderLabels(["Category name", "Color"])
85
- # self.lw.verticalHeader().hide()
86
85
  self.lw.setEditTriggers(QAbstractItemView.NoEditTriggers)
87
86
 
88
- # self.lw.setSelectionBehavior(QAbstractItemView.SelectRows)
89
87
  self.lw.setSelectionMode(QAbstractItemView.SingleSelection)
90
88
 
89
+ behavioral_categories: list = []
90
+
91
91
  if cfg.BEHAVIORAL_CATEGORIES_CONF in pj:
92
92
  self.lw.setRowCount(len(pj.get(cfg.BEHAVIORAL_CATEGORIES_CONF, {})))
93
93
  behav_cat = pj.get(cfg.BEHAVIORAL_CATEGORIES_CONF, {})
@@ -95,7 +95,7 @@ class BehavioralCategories(QDialog):
95
95
  # name
96
96
  item = QTableWidgetItem()
97
97
  item.setText(behav_cat[key]["name"])
98
- # item.setFlags(Qt.ItemIsEnabled)
98
+ behavioral_categories.append(behav_cat[key]["name"])
99
99
  self.lw.setItem(idx, 0, item)
100
100
  # color
101
101
  item = QTableWidgetItem()
@@ -103,24 +103,21 @@ class BehavioralCategories(QDialog):
103
103
  if behav_cat[key].get(cfg.COLOR, ""):
104
104
  item.setBackground(QColor(behav_cat[key].get(cfg.COLOR, "")))
105
105
  else:
106
- # item.setBackground(QColor(230, 230, 230))
107
106
  item.setBackground(self.not_editable_column_color())
108
- # item.setFlags(Qt.ItemIsEnabled)
109
107
  self.lw.setItem(idx, 1, item)
110
108
  else:
111
109
  self.lw.setRowCount(len(pj.get(cfg.BEHAVIORAL_CATEGORIES, [])))
112
110
  for idx, category in enumerate(sorted(pj.get(cfg.BEHAVIORAL_CATEGORIES, []))):
111
+ # name
113
112
  item = QTableWidgetItem()
114
113
  item.setText(category)
115
- # item.setFlags(Qt.ItemIsEnabled)
114
+ behavioral_categories.append(category)
116
115
  self.lw.setItem(idx, 0, item)
117
-
116
+ # color
118
117
  item = QTableWidgetItem()
119
118
  item.setText("")
120
- # item.setFlags(Qt.ItemIsEnabled)
121
- self.lw.setItem(idx, 1, item)
122
119
 
123
- # self.lw.addItem(QListWidgetItem(category))
120
+ self.lw.setItem(idx, 1, item)
124
121
 
125
122
  self.vbox.addWidget(self.lw)
126
123
 
@@ -148,6 +145,41 @@ class BehavioralCategories(QDialog):
148
145
 
149
146
  self.setLayout(self.vbox)
150
147
 
148
+ # check if behavioral categories are present in events
149
+ behavioral_categories_in_ethogram = set(
150
+ sorted([pj[cfg.ETHOGRAM][idx].get(cfg.BEHAVIOR_CATEGORY, "") for idx in pj.get(cfg.ETHOGRAM, {})])
151
+ )
152
+
153
+ if behavioral_categories_in_ethogram.difference(set(behavioral_categories)):
154
+ if (
155
+ dialog.MessageDialog(
156
+ cfg.programName,
157
+ (
158
+ "They are behavioral categories that are present in ethogram but not defined.<br>"
159
+ f"{behavioral_categories_in_ethogram.difference(set(behavioral_categories))}<br>"
160
+ "<br>"
161
+ "Do you want to add them in the behavioral categories list?"
162
+ ),
163
+ [cfg.YES, cfg.NO],
164
+ )
165
+ == cfg.YES
166
+ ):
167
+ # add behavioral categories present in ethogram in behavioal categories list
168
+ rc = self.lw.rowCount()
169
+ self.lw.setRowCount(rc + len(behavioral_categories_in_ethogram.difference(set(behavioral_categories))))
170
+ for idx, category in enumerate(sorted(list(behavioral_categories_in_ethogram.difference(set(behavioral_categories))))):
171
+ print(category)
172
+ # name
173
+ item = QTableWidgetItem()
174
+ item.setText(category)
175
+ # behavioral_categories.append(category)
176
+ self.lw.setItem(rc + idx, 0, item)
177
+ # color
178
+ item = QTableWidgetItem()
179
+ item.setText("")
180
+
181
+ self.lw.setItem(rc + idx, 1, item)
182
+
151
183
  def not_editable_column_color(self):
152
184
  """
153
185
  return a color for the not editable column
@@ -663,7 +695,7 @@ class projectDialog(QDialog, Ui_dlgProject):
663
695
  QMessageBox.warning(
664
696
  self,
665
697
  cfg.programName,
666
- ("The following behavior{} are not defined in the ethogram:<br>" "{}").format(
698
+ ("The following behavior{} are not defined in the ethogram:<br>{}").format(
667
699
  "s" if len(bcm_code_not_found) > 1 else "", ",".join(bcm_code_not_found)
668
700
  ),
669
701
  )
@@ -733,7 +765,7 @@ class projectDialog(QDialog, Ui_dlgProject):
733
765
  behavioral categories manager
734
766
  """
735
767
 
736
- bc = BehavioralCategories(self.pj) # self.config_param.get(cfg.DARK_MODE, cfg.DEFAULT_FRAME_MODE)
768
+ bc = BehavioralCategories(self.pj)
737
769
 
738
770
  if bc.exec_():
739
771
  self.pj[cfg.BEHAVIORAL_CATEGORIES] = []
@@ -1377,7 +1409,7 @@ class projectDialog(QDialog, Ui_dlgProject):
1377
1409
  # let user select a coding maop
1378
1410
  file_name, _ = QFileDialog().getOpenFileName(
1379
1411
  self,
1380
- "Select a modifier coding map for " f"{self.twBehaviors.item(row, cfg.behavioursFields['code']).text()} behavior",
1412
+ f"Select a modifier coding map for {self.twBehaviors.item(row, cfg.behavioursFields['code']).text()} behavior",
1381
1413
  "",
1382
1414
  "BORIS map files (*.boris_map);;All files (*)",
1383
1415
  )
@@ -1759,24 +1791,40 @@ class projectDialog(QDialog, Ui_dlgProject):
1759
1791
  return {cfg.CANCEL: True}
1760
1792
 
1761
1793
  # check if behavior belong to category that is not in categories list
1762
- behavior_category: list = []
1794
+ missing_behavior_category: list = []
1763
1795
  for idx in checked_ethogram:
1764
1796
  if cfg.BEHAVIOR_CATEGORY in checked_ethogram[idx]:
1765
1797
  if checked_ethogram[idx][cfg.BEHAVIOR_CATEGORY]:
1766
1798
  if checked_ethogram[idx][cfg.BEHAVIOR_CATEGORY] not in self.pj[cfg.BEHAVIORAL_CATEGORIES]:
1767
- behavior_category.append((checked_ethogram[idx][cfg.BEHAVIOR_CODE], checked_ethogram[idx][cfg.BEHAVIOR_CATEGORY]))
1768
- if behavior_category:
1799
+ missing_behavior_category.append(
1800
+ (checked_ethogram[idx][cfg.BEHAVIOR_CODE], checked_ethogram[idx][cfg.BEHAVIOR_CATEGORY])
1801
+ )
1802
+ if missing_behavior_category:
1769
1803
  response = dialog.MessageDialog(
1770
1804
  f"{cfg.programName} - Behavioral categories",
1771
1805
  (
1772
- "The behavioral categorie(s) "
1773
- f"{', '.join(set(['<b>' + x[1] + '</b>' + ' (used with <b>' + x[0] + '</b>)' for x in behavior_category]))} "
1774
- "are no more defined in behavioral categories list"
1806
+ "The behavioral category/ies<br> "
1807
+ f"{', '.join(set(['<b>' + x[1] + '</b>' + ' (used with <b>' + x[0] + '</b>)<br>' for x in missing_behavior_category]))} "
1808
+ "are not defined in behavioral categories list.<br>"
1775
1809
  ),
1776
- ["Add behavioral category/ies", "Ignore", cfg.CANCEL],
1810
+ ["Add behavioral category/ies", cfg.IGNORE, cfg.CANCEL],
1777
1811
  )
1778
1812
  if response == "Add behavioral category/ies":
1779
- [self.pj[cfg.BEHAVIORAL_CATEGORIES].append(x1) for x1 in set(x[1] for x in behavior_category)]
1813
+ if cfg.BEHAVIORAL_CATEGORIES_CONF not in self.pj:
1814
+ self.pj[cfg.BEHAVIORAL_CATEGORIES_CONF] = {}
1815
+ for x1 in set(x[1] for x in missing_behavior_category):
1816
+ self.pj[cfg.BEHAVIORAL_CATEGORIES].append(x1)
1817
+
1818
+ if self.pj[cfg.BEHAVIORAL_CATEGORIES_CONF]:
1819
+ index = str(max([int(k) for k in self.pj[cfg.BEHAVIORAL_CATEGORIES_CONF]]) + 1)
1820
+ else:
1821
+ index = "0"
1822
+
1823
+ self.pj[cfg.BEHAVIORAL_CATEGORIES_CONF][index] = {
1824
+ "name": x1,
1825
+ cfg.COLOR: "",
1826
+ }
1827
+
1780
1828
  if response == cfg.CANCEL:
1781
1829
  return {cfg.CANCEL: True}
1782
1830
 
@@ -89,9 +89,10 @@ def export_ethogram(self) -> None:
89
89
  return
90
90
  pj = dict(cfg.EMPTY_PROJECT)
91
91
  pj[cfg.ETHOGRAM] = dict(r)
92
- # behavioral categories
93
92
 
93
+ # behavioral categories
94
94
  pj[cfg.BEHAVIORAL_CATEGORIES] = list(self.pj[cfg.BEHAVIORAL_CATEGORIES])
95
+ pj[cfg.BEHAVIORAL_CATEGORIES_CONF] = dict(self.pj.get(cfg.BEHAVIORAL_CATEGORIES_CONF, {}))
95
96
 
96
97
  # project file indentation
97
98
  file_indentation = self.config_param.get(cfg.PROJECT_FILE_INDENTATION, cfg.PROJECT_FILE_INDENTATION_DEFAULT_VALUE)
@@ -309,6 +310,7 @@ def import_ethogram_from_dict(self, project: dict):
309
310
  """
310
311
  # import behavioral_categories
311
312
  self.pj[cfg.BEHAVIORAL_CATEGORIES] = list(project.get(cfg.BEHAVIORAL_CATEGORIES, []))
313
+ self.pj[cfg.BEHAVIORAL_CATEGORIES_CONF] = list(project.get(cfg.BEHAVIORAL_CATEGORIES_CONF, {}))
312
314
 
313
315
  # configuration of behaviours
314
316
  if not (cfg.ETHOGRAM in project and project[cfg.ETHOGRAM]):
boris/utilities.py CHANGED
@@ -21,7 +21,6 @@ Copyright 2012-2025 Olivier Friard
21
21
 
22
22
  import csv
23
23
  import datetime as dt
24
- import hashlib
25
24
  import json
26
25
  import logging
27
26
  import math
boris/version.py CHANGED
@@ -20,5 +20,5 @@ This file is part of BORIS.
20
20
 
21
21
  """
22
22
 
23
- __version__ = "9.3.2"
24
- __version_date__ = "2025-04-14"
23
+ __version__ = "9.3.3"
24
+ __version_date__ = "2025-05-07"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boris-behav-obs
3
- Version: 9.3.2
3
+ Version: 9.3.3
4
4
  Summary: BORIS - Behavioral Observation Research Interactive Software
5
5
  Author-email: Olivier Friard <olivier.friard@unito.it>
6
6
  License-Expression: GPL-3.0-only
@@ -10,18 +10,18 @@ boris/behaviors_coding_map.py,sha256=xIGJxp2eghrpiGDmYH73eJPERuyc4A_54uT-Got3zTs
10
10
  boris/boris_cli.py,sha256=n0OiVvZM1gM6E7yKaff9wlgmpAGK4TK052VRi8AabJo,13196
11
11
  boris/cmd_arguments.py,sha256=oWb-FvhKLbKJhATlTHy9muWu8XnnUfOZ-3Fmz2M8Yzc,1848
12
12
  boris/coding_pad.py,sha256=fBKdp7DDyupySJosIYtqNd8s2E-GruzCgVhDFsoVWKE,10986
13
- boris/config.py,sha256=cy4MSVFMHYaEHpHdncljuiaMSTpV6rFNm1OyVYF28Bc,17295
13
+ boris/config.py,sha256=rPfhmdE5XilliNjioC1KuDL_LNze4MZBDy_p0zK4tt8,17349
14
14
  boris/config_file.py,sha256=1-2ZmTvKET57rwrLR1dXblt0AxMpGB1LAiHxu-Sy8es,13543
15
15
  boris/connections.py,sha256=rVI18AuXh8cEnnoCKJk0RMWAaiNOpiaS554Okgk3SBY,19383
16
16
  boris/converters.py,sha256=c1Jps-URoglY5ILQHz-pCCf6-4DFUHZLtqr_ofsrFg0,11722
17
17
  boris/converters_ui.py,sha256=uu7LOBV_fKv2DBdOqsqPwjGsjgONr5ODBoscAA-EP48,9900
18
18
  boris/cooccurence.py,sha256=tVERC-V8MWjWHlGEfDuu08iS94qjt4do-38jwI62QaY,10367
19
- boris/core.py,sha256=qO8ZQoPxr_jjdy7-oihjcPcNvWgHvs-IWd7JWmxy_M0,233608
19
+ boris/core.py,sha256=EK19Xn0Z_sxu9TaqeRimMzzpn9ThZdTqUtlJJXz6pVY,233512
20
20
  boris/core_qrc.py,sha256=T3ki5e2Pj0I0QBGz63MPUgZzl8F_VHZwSq074mRNBDU,650669
21
21
  boris/core_ui.py,sha256=SeC26uveDCjrCBLsRPuQ6FaapKfON_HIRcQStEDLhl4,76384
22
22
  boris/db_functions.py,sha256=Uw9wWH_Pe-qNzpV1k21YG_jKsoOmfY_iiK_7ARZHGDc,13352
23
23
  boris/dev.py,sha256=9pUElbjl9g17rFUJXX5aVSu55_iIKIuDxNdrB0DI_d0,3671
24
- boris/dialog.py,sha256=0mWbOQu9QvkCr6AIa1Tue5EYaTxbHo7rm-tnGAqQ3nk,33047
24
+ boris/dialog.py,sha256=6MayZdOsLZCXP1ns02EH9bygYbWPNoEKrXNQrOaw_aw,33071
25
25
  boris/duration_widget.py,sha256=GjZgCAMGOcsNjoPiRImEVe6yMkH2vuNoh44ulpd5nlg,6924
26
26
  boris/edit_event.py,sha256=2hpxn9DYuJW1CK02hF4iU0--J_0C_KTiN9gGZ1frJBc,7678
27
27
  boris/edit_event_ui.py,sha256=vhglQrhkF9tt0HVlkXnkG7symW0eOFA7nhbk6l_qn3k,7772
@@ -39,7 +39,7 @@ boris/import_observations.py,sha256=hwEPIag741AXTFIuxDdZLDvLrsmvaqTkjyTjQu5M_RA,
39
39
  boris/irr.py,sha256=o5QN3B2b-02AUkrklMJCitFGsfiUDtmI0MxUbPv2cBg,22472
40
40
  boris/latency.py,sha256=48z9L_A582-wKCfD0M3h0uyYkeL2ezjlQAS_GzeoOe0,9739
41
41
  boris/measurement_widget.py,sha256=lZV62KtK6TjdoNbKxj3uyNAuL5dfnQnn7mYwzMo-dOM,4480
42
- boris/media_file.py,sha256=QzUC0mT905SzlONvcXUJB2OCxhj8kJ0h0W6PN1ssSIY,4722
42
+ boris/media_file.py,sha256=Wnw-PCyAz6CA00zhjrx0UTgXZ0wmHuNlnElV_TzJ_2M,4818
43
43
  boris/menu_options.py,sha256=UEB3GxRh6YKNCg67qbhOVhJW1ZOznuPe15bADc_CNTI,7062
44
44
  boris/modifier_coding_map_creator.py,sha256=NQHy_txgxKZnGByXiro_Oy_cq4DrFaFiAYwVp1CWrTs,33281
45
45
  boris/modifiers_coding_map.py,sha256=oT56ZY_PXhEJsMoblEsyNMAPbDpv7ZMOCnvmt7Ibx_Y,4554
@@ -47,7 +47,7 @@ boris/mpv-1.0.3.py,sha256=EXRtzQqFjOn4wMC6482Ilq3fNQ9N1GRP1VxwLzdeaBY,88077
47
47
  boris/mpv.py,sha256=EfzIHjPbgewG4w3smEtqEUPZoVwYmMQkL4Q8ZyW-a58,76410
48
48
  boris/mpv2.py,sha256=IUI4t4r9GYX7G5OXTjd3RhMMOkDdfal_15buBgksLsk,92152
49
49
  boris/observation.py,sha256=d-7q-RkMHuLDV87nF4yahvDFPYhlXp6GmE80vckn5zU,57073
50
- boris/observation_operations.py,sha256=hYtwMk3dx9O1UURbxPUewlyL111jDThO5_b3CnNmI1o,105756
50
+ boris/observation_operations.py,sha256=Eh-D4ApnuHaXX6fhrFwSsAvEFjMHu7eaI_9vci-drgQ,105790
51
51
  boris/observation_ui.py,sha256=DAnU94QBNvkLuHT6AxTwqSk_D_n6VUhSl8PexZv_dUk,33309
52
52
  boris/observations_list.py,sha256=NqwECGHtHYmKhSe-qCfqPmJ24SSfzlXvIXS2i3op_zE,10591
53
53
  boris/otx_parser.py,sha256=70QvilzFHXbjAHR88YH0aEXJ3xxheLS5fZGgHFHGpNE,16367
@@ -62,9 +62,9 @@ boris/plot_waveform_rt.py,sha256=05JN_6HCq674ROore_6PNw93GQNZJQDlDxp2ODAFkkA,747
62
62
  boris/plugins.py,sha256=CCS1I44OMkGZqcfLGKNPGfEQXPgngocy5YhWveXQPKM,10029
63
63
  boris/preferences.py,sha256=qPfd9Tyg7u30kXwVqMOgkdy2RXri9bItRa5U2-ZVQmg,16847
64
64
  boris/preferences_ui.py,sha256=D2bFLb3E0m6IwSeqKoItRDiqvPmJGoeXLHF2K02n1Zo,26293
65
- boris/project.py,sha256=hAeAb5pD0u_l0bezU9ePvbTOYQKfxrFGvYB2NAqSDHg,84377
65
+ boris/project.py,sha256=Yrpoqr5kF8wlvbeYiwm_RK2A9-dLfnxfnhp8TU5ZQbM,86452
66
66
  boris/project_functions.py,sha256=mPaKTjcegsC6n-J8ZsOhWh_4TepJ3Y-vwXiIgl9nij0,79702
67
- boris/project_import_export.py,sha256=1FdsYFzZ_jrhPRaH7xEkcPnh-hQXN4HFz1PhsIsSoL8,38361
67
+ boris/project_import_export.py,sha256=oBG1CSXfKISsb3TLNT-8BH8kZPAzxIYSNemlLVH1Lh8,38560
68
68
  boris/project_ui.py,sha256=yB-ewhHt8S8DTTRIk-dNK2tPMNU24lNji9fDW_Xazu8,38805
69
69
  boris/qrc_boris.py,sha256=aH-qUirYY1CGxmTK1SFCPvuZfazIHX4DdUKF1gxZeYM,675008
70
70
  boris/qrc_boris5.py,sha256=prnOw7VGXWXRuVCYp_yIrmWhrlG1F9rx-3BQvkPenjY,161608
@@ -77,8 +77,8 @@ boris/synthetic_time_budget.py,sha256=3Eb9onMLmgqCLd50CuxV9L8RV2ESzfaMWvPK_bXUMM
77
77
  boris/time_budget_functions.py,sha256=y5He8crz0xsTxVfz0jATwFFQVnPAIrNHja_0sF6NtRE,52551
78
78
  boris/time_budget_widget.py,sha256=z-tyITBtIz-KH1H2OdMB5a8x9QQLK7Wu96-zkC6NVDA,43213
79
79
  boris/transitions.py,sha256=_aZJfJWv3EBrtmQ7qsdTCayQo6uWU7BXqtQQgflEhr4,12250
80
- boris/utilities.py,sha256=SoVTDiFkidh-POwYcu_TVfJsFeXHYZV--s1tdxKH1VU,52654
81
- boris/version.py,sha256=1P9L6ZnUsH7kDLTVpQPQLqCJMN5PAWXFyIRRUTkgDkA,787
80
+ boris/utilities.py,sha256=7iZ6XQ8G1by9j-xVjTCBX6dp9FQg_9MbC5Ym1sZJYp0,52639
81
+ boris/version.py,sha256=wqhoE3kKrpzgOgOUWT2QNHWqh24C1Kp05JOwqZKmU8k,787
82
82
  boris/video_equalizer.py,sha256=FartoGghFK-T53zklP70rPKYqTuzL8qdvfGlsOF2wwc,5854
83
83
  boris/video_equalizer_ui.py,sha256=1CG3s79eM4JAbaCx3i1ILZXLceb41_gGXlOLNfpBgnw,10142
84
84
  boris/video_operations.py,sha256=mh3iR__Sm2KnV44L_sW2pOo3AgLwlM7wiTnnqQiAVs4,9381
@@ -96,9 +96,9 @@ boris/portion/dict.py,sha256=SyHxc7PfDw2ufNLFQycwJtzmRfL48rDp4UrM2KN7IWc,11282
96
96
  boris/portion/func.py,sha256=3TkQtFKLfsqntwd27HSGHceFhnXHmT-EbNMqktElC5Q,2174
97
97
  boris/portion/interval.py,sha256=bAdUiJjGeUAPgsBAImwNeviiwfQq5odfhFZccAWzOTA,20299
98
98
  boris/portion/io.py,sha256=ppNeRpiLNrocF1yzGeuEUIhYMf2LfsR-cji3d0nmvUs,6371
99
- boris_behav_obs-9.3.2.dist-info/licenses/LICENSE.TXT,sha256=WJ7YI-moTFb-uVrFjnzzhGJrnL9P2iqQe8NuED3hutI,35141
100
- boris_behav_obs-9.3.2.dist-info/METADATA,sha256=ZUt0hNpFSkVJweQn-PndnIpkRpCN--vQaJOqYwfEZMg,4518
101
- boris_behav_obs-9.3.2.dist-info/WHEEL,sha256=MAQBAzGbXNI3bUmkDsiV_duv8i-gcdnLzw7cfUFwqhU,109
102
- boris_behav_obs-9.3.2.dist-info/entry_points.txt,sha256=k__8XvFi4vaA4QFvQehCZjYkKmZH34HSAJI2iYCWrMs,52
103
- boris_behav_obs-9.3.2.dist-info/top_level.txt,sha256=fJSgm62S7WesiwTorGbOO4nNN0yzgZ3klgfGi3Px4qI,6
104
- boris_behav_obs-9.3.2.dist-info/RECORD,,
99
+ boris_behav_obs-9.3.3.dist-info/licenses/LICENSE.TXT,sha256=WJ7YI-moTFb-uVrFjnzzhGJrnL9P2iqQe8NuED3hutI,35141
100
+ boris_behav_obs-9.3.3.dist-info/METADATA,sha256=oiGWIVEJKIfM9EOznjvVeDr15l2rtecxzculq_IsJAg,4518
101
+ boris_behav_obs-9.3.3.dist-info/WHEEL,sha256=oSJJyWjO7Z2XSScFQUpXG1HL-N0sFMqqeKVVbZTPkWc,109
102
+ boris_behav_obs-9.3.3.dist-info/entry_points.txt,sha256=k__8XvFi4vaA4QFvQehCZjYkKmZH34HSAJI2iYCWrMs,52
103
+ boris_behav_obs-9.3.3.dist-info/top_level.txt,sha256=fJSgm62S7WesiwTorGbOO4nNN0yzgZ3klgfGi3Px4qI,6
104
+ boris_behav_obs-9.3.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.1.0)
2
+ Generator: setuptools (80.3.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py2-none-any
5
5
  Tag: py3-none-any