setiastrosuitepro 1.6.1.post1__py3-none-any.whl → 1.6.4__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.

Potentially problematic release.


This version of setiastrosuitepro might be problematic. Click here for more details.

Files changed (139) hide show
  1. setiastro/images/Background_startup.jpg +0 -0
  2. setiastro/images/rotatearbitrary.png +0 -0
  3. setiastro/qml/ResourceMonitor.qml +126 -0
  4. setiastro/saspro/__main__.py +162 -25
  5. setiastro/saspro/_generated/build_info.py +2 -1
  6. setiastro/saspro/abe.py +62 -11
  7. setiastro/saspro/aberration_ai.py +3 -3
  8. setiastro/saspro/add_stars.py +5 -2
  9. setiastro/saspro/astrobin_exporter.py +3 -0
  10. setiastro/saspro/astrospike_python.py +3 -1
  11. setiastro/saspro/autostretch.py +4 -2
  12. setiastro/saspro/backgroundneutral.py +60 -9
  13. setiastro/saspro/batch_convert.py +3 -0
  14. setiastro/saspro/batch_renamer.py +3 -0
  15. setiastro/saspro/blemish_blaster.py +3 -0
  16. setiastro/saspro/blink_comparator_pro.py +474 -251
  17. setiastro/saspro/cheat_sheet.py +50 -15
  18. setiastro/saspro/clahe.py +27 -1
  19. setiastro/saspro/comet_stacking.py +103 -38
  20. setiastro/saspro/convo.py +3 -0
  21. setiastro/saspro/copyastro.py +3 -0
  22. setiastro/saspro/cosmicclarity.py +70 -45
  23. setiastro/saspro/crop_dialog_pro.py +28 -1
  24. setiastro/saspro/curve_editor_pro.py +18 -0
  25. setiastro/saspro/debayer.py +3 -0
  26. setiastro/saspro/doc_manager.py +40 -17
  27. setiastro/saspro/fitsmodifier.py +3 -0
  28. setiastro/saspro/frequency_separation.py +8 -2
  29. setiastro/saspro/function_bundle.py +18 -16
  30. setiastro/saspro/generate_translations.py +715 -1
  31. setiastro/saspro/ghs_dialog_pro.py +3 -0
  32. setiastro/saspro/graxpert.py +3 -0
  33. setiastro/saspro/gui/main_window.py +364 -92
  34. setiastro/saspro/gui/mixins/dock_mixin.py +119 -7
  35. setiastro/saspro/gui/mixins/file_mixin.py +7 -0
  36. setiastro/saspro/gui/mixins/geometry_mixin.py +105 -5
  37. setiastro/saspro/gui/mixins/menu_mixin.py +29 -0
  38. setiastro/saspro/gui/mixins/toolbar_mixin.py +33 -10
  39. setiastro/saspro/gui/statistics_dialog.py +47 -0
  40. setiastro/saspro/halobgon.py +29 -3
  41. setiastro/saspro/histogram.py +3 -0
  42. setiastro/saspro/history_explorer.py +2 -0
  43. setiastro/saspro/i18n.py +22 -10
  44. setiastro/saspro/image_combine.py +3 -0
  45. setiastro/saspro/image_peeker_pro.py +3 -0
  46. setiastro/saspro/imageops/stretch.py +5 -13
  47. setiastro/saspro/isophote.py +3 -0
  48. setiastro/saspro/legacy/numba_utils.py +64 -47
  49. setiastro/saspro/linear_fit.py +3 -0
  50. setiastro/saspro/live_stacking.py +13 -2
  51. setiastro/saspro/mask_creation.py +3 -0
  52. setiastro/saspro/mfdeconv.py +5 -0
  53. setiastro/saspro/morphology.py +30 -5
  54. setiastro/saspro/multiscale_decomp.py +713 -256
  55. setiastro/saspro/nbtorgb_stars.py +12 -2
  56. setiastro/saspro/numba_utils.py +148 -47
  57. setiastro/saspro/ops/scripts.py +77 -17
  58. setiastro/saspro/ops/settings.py +1 -43
  59. setiastro/saspro/perfect_palette_picker.py +1 -0
  60. setiastro/saspro/pixelmath.py +6 -2
  61. setiastro/saspro/plate_solver.py +1 -0
  62. setiastro/saspro/remove_green.py +18 -1
  63. setiastro/saspro/remove_stars.py +136 -162
  64. setiastro/saspro/remove_stars_preset.py +55 -13
  65. setiastro/saspro/resources.py +36 -10
  66. setiastro/saspro/rgb_combination.py +1 -0
  67. setiastro/saspro/rgbalign.py +4 -4
  68. setiastro/saspro/save_options.py +1 -0
  69. setiastro/saspro/selective_color.py +79 -20
  70. setiastro/saspro/sfcc.py +50 -8
  71. setiastro/saspro/shortcuts.py +94 -21
  72. setiastro/saspro/signature_insert.py +3 -0
  73. setiastro/saspro/stacking_suite.py +924 -446
  74. setiastro/saspro/star_alignment.py +291 -331
  75. setiastro/saspro/star_spikes.py +116 -32
  76. setiastro/saspro/star_stretch.py +38 -1
  77. setiastro/saspro/stat_stretch.py +35 -3
  78. setiastro/saspro/status_log_dock.py +1 -1
  79. setiastro/saspro/subwindow.py +63 -2
  80. setiastro/saspro/supernovaasteroidhunter.py +3 -0
  81. setiastro/saspro/swap_manager.py +77 -42
  82. setiastro/saspro/translations/all_source_strings.json +4726 -0
  83. setiastro/saspro/translations/ar_translations.py +4096 -0
  84. setiastro/saspro/translations/de_translations.py +441 -446
  85. setiastro/saspro/translations/es_translations.py +278 -32
  86. setiastro/saspro/translations/fr_translations.py +280 -32
  87. setiastro/saspro/translations/hi_translations.py +3803 -0
  88. setiastro/saspro/translations/integrate_translations.py +38 -1
  89. setiastro/saspro/translations/it_translations.py +1211 -145
  90. setiastro/saspro/translations/ja_translations.py +556 -307
  91. setiastro/saspro/translations/pt_translations.py +3316 -3322
  92. setiastro/saspro/translations/ru_translations.py +3082 -0
  93. setiastro/saspro/translations/saspro_ar.qm +0 -0
  94. setiastro/saspro/translations/saspro_ar.ts +16019 -0
  95. setiastro/saspro/translations/saspro_de.qm +0 -0
  96. setiastro/saspro/translations/saspro_de.ts +14428 -133
  97. setiastro/saspro/translations/saspro_es.qm +0 -0
  98. setiastro/saspro/translations/saspro_es.ts +11503 -7821
  99. setiastro/saspro/translations/saspro_fr.qm +0 -0
  100. setiastro/saspro/translations/saspro_fr.ts +11168 -7812
  101. setiastro/saspro/translations/saspro_hi.qm +0 -0
  102. setiastro/saspro/translations/saspro_hi.ts +14855 -0
  103. setiastro/saspro/translations/saspro_it.qm +0 -0
  104. setiastro/saspro/translations/saspro_it.ts +14347 -7821
  105. setiastro/saspro/translations/saspro_ja.qm +0 -0
  106. setiastro/saspro/translations/saspro_ja.ts +14860 -137
  107. setiastro/saspro/translations/saspro_pt.qm +0 -0
  108. setiastro/saspro/translations/saspro_pt.ts +14904 -137
  109. setiastro/saspro/translations/saspro_ru.qm +0 -0
  110. setiastro/saspro/translations/saspro_ru.ts +11835 -0
  111. setiastro/saspro/translations/saspro_sw.qm +0 -0
  112. setiastro/saspro/translations/saspro_sw.ts +15237 -0
  113. setiastro/saspro/translations/saspro_uk.qm +0 -0
  114. setiastro/saspro/translations/saspro_uk.ts +15248 -0
  115. setiastro/saspro/translations/saspro_zh.qm +0 -0
  116. setiastro/saspro/translations/saspro_zh.ts +10581 -7812
  117. setiastro/saspro/translations/sw_translations.py +3897 -0
  118. setiastro/saspro/translations/uk_translations.py +3929 -0
  119. setiastro/saspro/translations/zh_translations.py +283 -32
  120. setiastro/saspro/versioning.py +36 -5
  121. setiastro/saspro/view_bundle.py +20 -17
  122. setiastro/saspro/wavescale_hdr.py +22 -1
  123. setiastro/saspro/wavescalede.py +23 -1
  124. setiastro/saspro/whitebalance.py +39 -3
  125. setiastro/saspro/widgets/minigame/game.js +991 -0
  126. setiastro/saspro/widgets/minigame/index.html +53 -0
  127. setiastro/saspro/widgets/minigame/style.css +241 -0
  128. setiastro/saspro/widgets/resource_monitor.py +263 -0
  129. setiastro/saspro/widgets/spinboxes.py +18 -0
  130. setiastro/saspro/widgets/wavelet_utils.py +52 -20
  131. setiastro/saspro/wimi.py +100 -80
  132. setiastro/saspro/wims.py +33 -33
  133. setiastro/saspro/window_shelf.py +2 -2
  134. {setiastrosuitepro-1.6.1.post1.dist-info → setiastrosuitepro-1.6.4.dist-info}/METADATA +15 -4
  135. {setiastrosuitepro-1.6.1.post1.dist-info → setiastrosuitepro-1.6.4.dist-info}/RECORD +139 -115
  136. {setiastrosuitepro-1.6.1.post1.dist-info → setiastrosuitepro-1.6.4.dist-info}/WHEEL +0 -0
  137. {setiastrosuitepro-1.6.1.post1.dist-info → setiastrosuitepro-1.6.4.dist-info}/entry_points.txt +0 -0
  138. {setiastrosuitepro-1.6.1.post1.dist-info → setiastrosuitepro-1.6.4.dist-info}/licenses/LICENSE +0 -0
  139. {setiastrosuitepro-1.6.1.post1.dist-info → setiastrosuitepro-1.6.4.dist-info}/licenses/license.txt +0 -0
setiastro/saspro/wims.py CHANGED
@@ -289,7 +289,7 @@ def _tz_vs_longitude_hint(tz_name: str, date_str: str, time_str: str, lon_deg: f
289
289
  class WhatsInMySkyDialog(QDialog):
290
290
  def __init__(self, parent=None, wims_path: Optional[str] = None, wrench_path: Optional[str] = None):
291
291
  super().__init__(parent)
292
- self.setWindowTitle("What's In My Sky")
292
+ self.setWindowTitle(self.tr("What's In My Sky"))
293
293
  if wims_path:
294
294
  self.setWindowIcon(QIcon(wims_path))
295
295
 
@@ -316,14 +316,14 @@ class WhatsInMySkyDialog(QDialog):
316
316
  self.timezone_combo.setFixedWidth(fixed_w)
317
317
 
318
318
  r = 0
319
- layout.addWidget(QLabel("Latitude:"), r, 0); layout.addWidget(self.latitude_entry, r, 1); r += 1
320
- layout.addWidget(QLabel("Longitude (E+, W−):"), r, 0); layout.addWidget(self.longitude_entry, r, 1); r += 1
321
- layout.addWidget(QLabel("Date (YYYY-MM-DD):"), r, 0); layout.addWidget(self.date_entry, r, 1); r += 1
322
- layout.addWidget(QLabel("Time (HH:MM):"), r, 0); layout.addWidget(self.time_entry, r, 1); r += 1
323
- layout.addWidget(QLabel("Time Zone:"), r, 0); layout.addWidget(self.timezone_combo, r, 1); r += 1
319
+ layout.addWidget(QLabel(self.tr("Latitude:")), r, 0); layout.addWidget(self.latitude_entry, r, 1); r += 1
320
+ layout.addWidget(QLabel(self.tr("Longitude (E+, W−):")), r, 0); layout.addWidget(self.longitude_entry, r, 1); r += 1
321
+ layout.addWidget(QLabel(self.tr("Date (YYYY-MM-DD):")), r, 0); layout.addWidget(self.date_entry, r, 1); r += 1
322
+ layout.addWidget(QLabel(self.tr("Time (HH:MM):")), r, 0); layout.addWidget(self.time_entry, r, 1); r += 1
323
+ layout.addWidget(QLabel(self.tr("Time Zone:")), r, 0); layout.addWidget(self.timezone_combo, r, 1); r += 1
324
324
 
325
325
  self.min_altitude_entry = QLineEdit(); self.min_altitude_entry.setFixedWidth(fixed_w)
326
- layout.addWidget(QLabel("Min Altitude (0–90°):"), r, 0); layout.addWidget(self.min_altitude_entry, r, 1); r += 1
326
+ layout.addWidget(QLabel(self.tr("Min Altitude (0–90°):")), r, 0); layout.addWidget(self.min_altitude_entry, r, 1); r += 1
327
327
 
328
328
  # catalogs
329
329
  catalog_frame = QScrollArea()
@@ -334,36 +334,36 @@ class WhatsInMySkyDialog(QDialog):
334
334
  cat_layout.addWidget(cb, i // 5, i % 5)
335
335
  self.catalog_vars[name] = cb
336
336
  catalog_frame.setWidget(cat_widget); catalog_frame.setFixedWidth(fixed_w + 250)
337
- layout.addWidget(QLabel("Catalog Filters:"), r, 0); layout.addWidget(catalog_frame, r, 1); r += 1
337
+ layout.addWidget(QLabel(self.tr("Catalog Filters:")), r, 0); layout.addWidget(catalog_frame, r, 1); r += 1
338
338
 
339
339
  # RA/Dec format
340
- self.ra_dec_degrees = QRadioButton("Degrees")
341
- self.ra_dec_hms = QRadioButton("H:M:S / D:M:S")
340
+ self.ra_dec_degrees = QRadioButton(self.tr("Degrees"))
341
+ self.ra_dec_hms = QRadioButton(self.tr("H:M:S / D:M:S"))
342
342
  self.ra_dec_degrees.setChecked(True)
343
343
  g = QButtonGroup(self); g.addButton(self.ra_dec_degrees); g.addButton(self.ra_dec_hms)
344
344
  ra_row = QHBoxLayout(); ra_row.addWidget(self.ra_dec_degrees); ra_row.addWidget(self.ra_dec_hms)
345
- layout.addWidget(QLabel("RA/Dec Format:"), r, 0); layout.addLayout(ra_row, r, 1); r += 1
345
+ layout.addWidget(QLabel(self.tr("RA/Dec Format:")), r, 0); layout.addLayout(ra_row, r, 1); r += 1
346
346
  self.ra_dec_degrees.toggled.connect(self.update_ra_dec_format)
347
347
  self.ra_dec_hms.toggled.connect(self.update_ra_dec_format)
348
348
 
349
349
  # action buttons / status
350
- calc_btn = QPushButton("Calculate"); calc_btn.setFixedWidth(fixed_w); calc_btn.clicked.connect(self.start_calculation)
350
+ calc_btn = QPushButton(self.tr("Calculate")); calc_btn.setFixedWidth(fixed_w); calc_btn.clicked.connect(self.start_calculation)
351
351
  layout.addWidget(calc_btn, r, 0); r += 1
352
352
 
353
- self.status_label = QLabel("Status: Idle"); layout.addWidget(self.status_label, r, 0, 1, 2); r += 1
354
- self.lst_label = QLabel("Local Sidereal Time: 0.000"); layout.addWidget(self.lst_label, r, 0, 1, 2); r += 1
353
+ self.status_label = QLabel(self.tr("Status: Idle")); layout.addWidget(self.status_label, r, 0, 1, 2); r += 1
354
+ self.lst_label = QLabel(self.tr("Local Sidereal Time: 0.000")); layout.addWidget(self.lst_label, r, 0, 1, 2); r += 1
355
355
 
356
356
  # moon phase preview
357
357
  self.lunar_phase_image_label = QLabel()
358
358
  layout.addWidget(self.lunar_phase_image_label, 0, 2, 4, 1)
359
- self.lunar_phase_label = QLabel("Lunar Phase: N/A")
359
+ self.lunar_phase_label = QLabel(self.tr("Lunar Phase: N/A"))
360
360
  layout.addWidget(self.lunar_phase_label, 4, 2)
361
361
 
362
362
  # results tree
363
363
  self.tree = QTreeWidget()
364
364
  self.tree.setHeaderLabels([
365
- "Name","RA","Dec","Altitude","Azimuth","Minutes to Transit","Before/After Transit",
366
- "Degrees from Moon","Alt Name","Type","Magnitude","Size (arcmin)"
365
+ self.tr("Name"),self.tr("RA"),self.tr("Dec"),self.tr("Altitude"),self.tr("Azimuth"),self.tr("Minutes to Transit"),self.tr("Before/After Transit"),
366
+ self.tr("Degrees from Moon"),self.tr("Alt Name"),self.tr("Type"),self.tr("Magnitude"),self.tr("Size (arcmin)")
367
367
  ])
368
368
  self.tree.setSortingEnabled(True)
369
369
  hdr = self.tree.header()
@@ -374,10 +374,10 @@ class WhatsInMySkyDialog(QDialog):
374
374
  layout.addWidget(self.tree, r, 0, 1, 3); r += 1
375
375
 
376
376
  # bottom row
377
- add_btn = QPushButton("Add Custom Object"); add_btn.setFixedWidth(fixed_w); add_btn.clicked.connect(self.add_custom_object)
377
+ add_btn = QPushButton(self.tr("Add Custom Object")); add_btn.setFixedWidth(fixed_w); add_btn.clicked.connect(self.add_custom_object)
378
378
  layout.addWidget(add_btn, r, 0)
379
379
 
380
- save_btn = QPushButton("Save to CSV"); save_btn.setFixedWidth(fixed_w); save_btn.clicked.connect(self.save_to_csv)
380
+ save_btn = QPushButton(self.tr("Save to CSV")); save_btn.setFixedWidth(fixed_w); save_btn.clicked.connect(self.save_to_csv)
381
381
  layout.addWidget(save_btn, r, 1)
382
382
 
383
383
  settings_btn = QPushButton(); settings_btn.setFixedWidth(fixed_w)
@@ -434,7 +434,7 @@ class WhatsInMySkyDialog(QDialog):
434
434
  tz_str = self.timezone_combo.currentText()
435
435
  min_alt = float(self.min_altitude_entry.text())
436
436
  except ValueError as e:
437
- self.update_status(f"Invalid input: {e}")
437
+ self.update_status(self.tr("Invalid input: {}").format(e))
438
438
  return
439
439
 
440
440
  # Heuristic warning (and gentle auto-fix if user probably forgot the suffix)
@@ -450,9 +450,9 @@ class WhatsInMySkyDialog(QDialog):
450
450
  self.longitude_entry.setText(_format_with_suffix(longitude, "lon"))
451
451
  self.update_status(f"{msg} → Assuming you meant {_format_with_suffix(longitude, 'lon')} (auto-corrected).")
452
452
  else:
453
- self.update_status(msg + " Please verify your longitude/timezone.")
453
+ self.update_status(msg + self.tr(" Please verify your longitude/timezone."))
454
454
  else:
455
- self.update_status("Inputs look consistent.")
455
+ self.update_status(self.tr("Inputs look consistent."))
456
456
 
457
457
  # Persist settings (numeric)
458
458
  self._save_settings(latitude, longitude, date_str, time_str, tz_str, min_alt)
@@ -467,11 +467,11 @@ class WhatsInMySkyDialog(QDialog):
467
467
  self.calc_thread.lst_calculated.connect(self.update_lst)
468
468
  self.calc_thread.status_update.connect(self.update_status)
469
469
 
470
- self.update_status("Calculating…")
470
+ self.update_status(self.tr("Calculating…"))
471
471
  self.calc_thread.start()
472
472
 
473
473
  def update_lunar_phase(self, phase_percentage: int, phase_image_name: str):
474
- self.lunar_phase_label.setText(f"Lunar Phase: {phase_percentage}% illuminated")
474
+ self.lunar_phase_label.setText(self.tr("Lunar Phase: {}% illuminated").format(phase_percentage))
475
475
  pth = imgs_path(phase_image_name)
476
476
  if os.path.exists(pth):
477
477
  pm = QPixmap(pth).scaled(100, 100, Qt.AspectRatioMode.KeepAspectRatio,
@@ -509,13 +509,13 @@ class WhatsInMySkyDialog(QDialog):
509
509
  self.tree.addTopLevelItem(SortableTreeWidgetItem(vals))
510
510
 
511
511
  def update_status(self, msg: str):
512
- self.status_label.setText(f"Status: {msg}")
512
+ self.status_label.setText(self.tr("Status: {}").format(msg))
513
513
 
514
514
  def update_lst(self, msg: str):
515
515
  self.lst_label.setText(msg)
516
516
 
517
517
  def open_settings(self):
518
- n, ok = QInputDialog.getInt(self, "Settings", "Enter number of objects to display:",
518
+ n, ok = QInputDialog.getInt(self, self.tr("Settings"), self.tr("Enter number of objects to display:"),
519
519
  value=int(self.object_limit), min=1, max=1000)
520
520
  if ok:
521
521
  self.object_limit = int(n)
@@ -526,12 +526,12 @@ class WhatsInMySkyDialog(QDialog):
526
526
  webbrowser.open(f"https://www.astrobin.com/search/?q={name}")
527
527
 
528
528
  def add_custom_object(self):
529
- name, ok = QInputDialog.getText(self, "Add Custom Object", "Enter object name:")
529
+ name, ok = QInputDialog.getText(self, self.tr("Add Custom Object"), self.tr("Enter object name:"))
530
530
  if not ok or not name:
531
531
  return
532
- ra, ok = QInputDialog.getDouble(self, "Add Custom Object", "Enter RA (deg):", decimals=3)
532
+ ra, ok = QInputDialog.getDouble(self, self.tr("Add Custom Object"), self.tr("Enter RA (deg):"), decimals=3)
533
533
  if not ok: return
534
- dec, ok = QInputDialog.getDouble(self, "Add Custom Object", "Enter Dec (deg):", decimals=3)
534
+ dec, ok = QInputDialog.getDouble(self, self.tr("Add Custom Object"), self.tr("Enter Dec (deg):"), decimals=3)
535
535
  if not ok: return
536
536
 
537
537
  entry = {"Name": name, "RA": ra, "Dec": dec, "Catalog": "User",
@@ -542,9 +542,9 @@ class WhatsInMySkyDialog(QDialog):
542
542
  df = pd.read_csv(catalog_csv, encoding="ISO-8859-1") if os.path.exists(catalog_csv) else pd.DataFrame()
543
543
  df = pd.concat([df, pd.DataFrame([entry])], ignore_index=True)
544
544
  df.to_csv(catalog_csv, index=False, encoding="ISO-8859-1")
545
- self.update_status(f"Added custom object: {name}")
545
+ self.update_status(self.tr("Added custom object: {}").format(name))
546
546
  except Exception as e:
547
- QMessageBox.warning(self, "Add Custom Object", f"Could not update catalog:\n{e}")
547
+ QMessageBox.warning(self, self.tr("Add Custom Object"), self.tr("Could not update catalog:\n{}").format(e))
548
548
 
549
549
  def update_ra_dec_format(self):
550
550
  use_deg = self.ra_dec_degrees.isChecked()
@@ -566,7 +566,7 @@ class WhatsInMySkyDialog(QDialog):
566
566
  pass
567
567
 
568
568
  def save_to_csv(self):
569
- path, _ = QFileDialog.getSaveFileName(self, "Save CSV File", "", "CSV files (*.csv);;All Files (*)")
569
+ path, _ = QFileDialog.getSaveFileName(self, self.tr("Save CSV File"), "", self.tr("CSV files (*.csv);;All Files (*)"))
570
570
  if not path:
571
571
  return
572
572
  cols = [self.tree.headerItem().text(i) for i in range(self.tree.columnCount())]
@@ -575,4 +575,4 @@ class WhatsInMySkyDialog(QDialog):
575
575
  it = self.tree.topLevelItem(i)
576
576
  rows.append([it.text(j) for j in range(self.tree.columnCount())])
577
577
  pd.DataFrame(rows, columns=cols).to_csv(path, index=False)
578
- self.update_status(f"Data saved to {path}")
578
+ self.update_status(self.tr("Data saved to {}").format(path))
@@ -17,7 +17,7 @@ def _dbg(owner, msg: str):
17
17
 
18
18
  class WindowShelf(QDockWidget):
19
19
  def __init__(self, parent=None):
20
- super().__init__("Minimized Views", parent)
20
+ super().__init__(self.tr("Minimized Views"), parent)
21
21
 
22
22
  # PyQt6 dock area enum
23
23
  self.setAllowedAreas(Qt.DockWidgetArea.AllDockWidgetAreas)
@@ -53,7 +53,7 @@ class WindowShelf(QDockWidget):
53
53
  if sub is None or sub.widget() is None:
54
54
  return
55
55
 
56
- title = sub.windowTitle() or "Untitled"
56
+ title = sub.windowTitle() or self.tr("Untitled")
57
57
  # strip leading dot and Active prefix for the shelf display text only
58
58
 
59
59
  # Remove any number of leading glyphs like ■ ● ◆ ▲ etc.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: setiastrosuitepro
3
- Version: 1.6.1.post1
3
+ Version: 1.6.4
4
4
  Summary: Seti Astro Suite Pro - Advanced astrophotography toolkit for image calibration, stacking, registration, photometry, and visualization
5
5
  License: GPL-3.0
6
6
  License-File: LICENSE
@@ -63,10 +63,21 @@ Description-Content-Type: text/markdown
63
63
  ### Author: Franklin Marek
64
64
  #### Website: [www.setiastro.com](http://www.setiastro.com)
65
65
 
66
- ### Other big contributors:
67
- - [Fabio Tempera](https://github.com/Ft2801)
66
+ ### Other contributors:
67
+ - [Fabio Tempera](https://github.com/Ft2801) 🥇
68
+ - Complete code refactoring of `setiastrosuitepro.py` (20,000+ lines), and duplicated code removal across the project
69
+ - Addition of AstroSpikes tool, secret minigame, system resources monitor, app statistics, and 10+ language translations
70
+ - Implementation of UI elements, startup window, caching methods, lazy imports, utils functions, better memory management, and other important code optimizations across the entire project
68
71
  - [Joaquin Rodriguez](https://github.com/jrhuerta)
69
-
72
+ - Project migration to Poetry
73
+ - [Tim Dicke](https://github.com/dickett)
74
+ - Windows and MacOS installer development
75
+ - MacOS Wiki instructions maintenance
76
+ - App testing and small bugfixes
77
+ - [Michael Lev](https://github.com/MichaelLevAstro)
78
+ - Addition of hebrew language
79
+ - [Andrew Witwicki](https://github.com/awitwicki)
80
+ - Addition of ukrainian language
70
81
  ---
71
82
 
72
83
  ## Overview