setiastrosuitepro 1.6.2.post1__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 (367) hide show
  1. setiastro/__init__.py +2 -0
  2. setiastro/data/SASP_data.fits +0 -0
  3. setiastro/data/catalogs/List_of_Galaxies_with_Distances_Gly.csv +488 -0
  4. setiastro/data/catalogs/astrobin_filters.csv +890 -0
  5. setiastro/data/catalogs/astrobin_filters_page1_local.csv +51 -0
  6. setiastro/data/catalogs/cali2.csv +63 -0
  7. setiastro/data/catalogs/cali2color.csv +65 -0
  8. setiastro/data/catalogs/celestial_catalog - original.csv +16471 -0
  9. setiastro/data/catalogs/celestial_catalog.csv +24031 -0
  10. setiastro/data/catalogs/detected_stars.csv +24784 -0
  11. setiastro/data/catalogs/fits_header_data.csv +46 -0
  12. setiastro/data/catalogs/test.csv +8 -0
  13. setiastro/data/catalogs/updated_celestial_catalog.csv +16471 -0
  14. setiastro/images/Astro_Spikes.png +0 -0
  15. setiastro/images/Background_startup.jpg +0 -0
  16. setiastro/images/HRDiagram.png +0 -0
  17. setiastro/images/LExtract.png +0 -0
  18. setiastro/images/LInsert.png +0 -0
  19. setiastro/images/Oxygenation-atm-2.svg.png +0 -0
  20. setiastro/images/RGB080604.png +0 -0
  21. setiastro/images/abeicon.png +0 -0
  22. setiastro/images/aberration.png +0 -0
  23. setiastro/images/andromedatry.png +0 -0
  24. setiastro/images/andromedatry_satellited.png +0 -0
  25. setiastro/images/annotated.png +0 -0
  26. setiastro/images/aperture.png +0 -0
  27. setiastro/images/astrosuite.ico +0 -0
  28. setiastro/images/astrosuite.png +0 -0
  29. setiastro/images/astrosuitepro.icns +0 -0
  30. setiastro/images/astrosuitepro.ico +0 -0
  31. setiastro/images/astrosuitepro.png +0 -0
  32. setiastro/images/background.png +0 -0
  33. setiastro/images/background2.png +0 -0
  34. setiastro/images/benchmark.png +0 -0
  35. setiastro/images/big_moon_stabilizer_timeline.png +0 -0
  36. setiastro/images/big_moon_stabilizer_timeline_clean.png +0 -0
  37. setiastro/images/blaster.png +0 -0
  38. setiastro/images/blink.png +0 -0
  39. setiastro/images/clahe.png +0 -0
  40. setiastro/images/collage.png +0 -0
  41. setiastro/images/colorwheel.png +0 -0
  42. setiastro/images/contsub.png +0 -0
  43. setiastro/images/convo.png +0 -0
  44. setiastro/images/copyslot.png +0 -0
  45. setiastro/images/cosmic.png +0 -0
  46. setiastro/images/cosmicsat.png +0 -0
  47. setiastro/images/crop1.png +0 -0
  48. setiastro/images/cropicon.png +0 -0
  49. setiastro/images/curves.png +0 -0
  50. setiastro/images/cvs.png +0 -0
  51. setiastro/images/debayer.png +0 -0
  52. setiastro/images/denoise_cnn_custom.png +0 -0
  53. setiastro/images/denoise_cnn_graph.png +0 -0
  54. setiastro/images/disk.png +0 -0
  55. setiastro/images/dse.png +0 -0
  56. setiastro/images/exoicon.png +0 -0
  57. setiastro/images/eye.png +0 -0
  58. setiastro/images/fliphorizontal.png +0 -0
  59. setiastro/images/flipvertical.png +0 -0
  60. setiastro/images/font.png +0 -0
  61. setiastro/images/freqsep.png +0 -0
  62. setiastro/images/functionbundle.png +0 -0
  63. setiastro/images/graxpert.png +0 -0
  64. setiastro/images/green.png +0 -0
  65. setiastro/images/gridicon.png +0 -0
  66. setiastro/images/halo.png +0 -0
  67. setiastro/images/hdr.png +0 -0
  68. setiastro/images/histogram.png +0 -0
  69. setiastro/images/hubble.png +0 -0
  70. setiastro/images/imagecombine.png +0 -0
  71. setiastro/images/invert.png +0 -0
  72. setiastro/images/isophote.png +0 -0
  73. setiastro/images/isophote_demo_figure.png +0 -0
  74. setiastro/images/isophote_demo_image.png +0 -0
  75. setiastro/images/isophote_demo_model.png +0 -0
  76. setiastro/images/isophote_demo_residual.png +0 -0
  77. setiastro/images/jwstpupil.png +0 -0
  78. setiastro/images/linearfit.png +0 -0
  79. setiastro/images/livestacking.png +0 -0
  80. setiastro/images/mask.png +0 -0
  81. setiastro/images/maskapply.png +0 -0
  82. setiastro/images/maskcreate.png +0 -0
  83. setiastro/images/maskremove.png +0 -0
  84. setiastro/images/morpho.png +0 -0
  85. setiastro/images/mosaic.png +0 -0
  86. setiastro/images/multiscale_decomp.png +0 -0
  87. setiastro/images/nbtorgb.png +0 -0
  88. setiastro/images/neutral.png +0 -0
  89. setiastro/images/nuke.png +0 -0
  90. setiastro/images/openfile.png +0 -0
  91. setiastro/images/pedestal.png +0 -0
  92. setiastro/images/pen.png +0 -0
  93. setiastro/images/pixelmath.png +0 -0
  94. setiastro/images/platesolve.png +0 -0
  95. setiastro/images/ppp.png +0 -0
  96. setiastro/images/pro.png +0 -0
  97. setiastro/images/project.png +0 -0
  98. setiastro/images/psf.png +0 -0
  99. setiastro/images/redo.png +0 -0
  100. setiastro/images/redoicon.png +0 -0
  101. setiastro/images/rescale.png +0 -0
  102. setiastro/images/rgbalign.png +0 -0
  103. setiastro/images/rgbcombo.png +0 -0
  104. setiastro/images/rgbextract.png +0 -0
  105. setiastro/images/rotate180.png +0 -0
  106. setiastro/images/rotateclockwise.png +0 -0
  107. setiastro/images/rotatecounterclockwise.png +0 -0
  108. setiastro/images/satellite.png +0 -0
  109. setiastro/images/script.png +0 -0
  110. setiastro/images/selectivecolor.png +0 -0
  111. setiastro/images/simbad.png +0 -0
  112. setiastro/images/slot0.png +0 -0
  113. setiastro/images/slot1.png +0 -0
  114. setiastro/images/slot2.png +0 -0
  115. setiastro/images/slot3.png +0 -0
  116. setiastro/images/slot4.png +0 -0
  117. setiastro/images/slot5.png +0 -0
  118. setiastro/images/slot6.png +0 -0
  119. setiastro/images/slot7.png +0 -0
  120. setiastro/images/slot8.png +0 -0
  121. setiastro/images/slot9.png +0 -0
  122. setiastro/images/spcc.png +0 -0
  123. setiastro/images/spin_precession_vs_lunar_distance.png +0 -0
  124. setiastro/images/spinner.gif +0 -0
  125. setiastro/images/stacking.png +0 -0
  126. setiastro/images/staradd.png +0 -0
  127. setiastro/images/staralign.png +0 -0
  128. setiastro/images/starnet.png +0 -0
  129. setiastro/images/starregistration.png +0 -0
  130. setiastro/images/starspike.png +0 -0
  131. setiastro/images/starstretch.png +0 -0
  132. setiastro/images/statstretch.png +0 -0
  133. setiastro/images/supernova.png +0 -0
  134. setiastro/images/uhs.png +0 -0
  135. setiastro/images/undoicon.png +0 -0
  136. setiastro/images/upscale.png +0 -0
  137. setiastro/images/viewbundle.png +0 -0
  138. setiastro/images/whitebalance.png +0 -0
  139. setiastro/images/wimi_icon_256x256.png +0 -0
  140. setiastro/images/wimilogo.png +0 -0
  141. setiastro/images/wims.png +0 -0
  142. setiastro/images/wrench_icon.png +0 -0
  143. setiastro/images/xisfliberator.png +0 -0
  144. setiastro/qml/ResourceMonitor.qml +126 -0
  145. setiastro/saspro/__init__.py +20 -0
  146. setiastro/saspro/__main__.py +945 -0
  147. setiastro/saspro/_generated/__init__.py +7 -0
  148. setiastro/saspro/_generated/build_info.py +3 -0
  149. setiastro/saspro/abe.py +1346 -0
  150. setiastro/saspro/abe_preset.py +196 -0
  151. setiastro/saspro/aberration_ai.py +694 -0
  152. setiastro/saspro/aberration_ai_preset.py +224 -0
  153. setiastro/saspro/accel_installer.py +218 -0
  154. setiastro/saspro/accel_workers.py +30 -0
  155. setiastro/saspro/add_stars.py +624 -0
  156. setiastro/saspro/astrobin_exporter.py +1010 -0
  157. setiastro/saspro/astrospike.py +153 -0
  158. setiastro/saspro/astrospike_python.py +1841 -0
  159. setiastro/saspro/autostretch.py +198 -0
  160. setiastro/saspro/backgroundneutral.py +602 -0
  161. setiastro/saspro/batch_convert.py +328 -0
  162. setiastro/saspro/batch_renamer.py +522 -0
  163. setiastro/saspro/blemish_blaster.py +491 -0
  164. setiastro/saspro/blink_comparator_pro.py +2926 -0
  165. setiastro/saspro/bundles.py +61 -0
  166. setiastro/saspro/bundles_dock.py +114 -0
  167. setiastro/saspro/cheat_sheet.py +213 -0
  168. setiastro/saspro/clahe.py +368 -0
  169. setiastro/saspro/comet_stacking.py +1442 -0
  170. setiastro/saspro/common_tr.py +107 -0
  171. setiastro/saspro/config.py +38 -0
  172. setiastro/saspro/config_bootstrap.py +40 -0
  173. setiastro/saspro/config_manager.py +316 -0
  174. setiastro/saspro/continuum_subtract.py +1617 -0
  175. setiastro/saspro/convo.py +1400 -0
  176. setiastro/saspro/convo_preset.py +414 -0
  177. setiastro/saspro/copyastro.py +190 -0
  178. setiastro/saspro/cosmicclarity.py +1589 -0
  179. setiastro/saspro/cosmicclarity_preset.py +407 -0
  180. setiastro/saspro/crop_dialog_pro.py +973 -0
  181. setiastro/saspro/crop_preset.py +189 -0
  182. setiastro/saspro/curve_editor_pro.py +2562 -0
  183. setiastro/saspro/curves_preset.py +375 -0
  184. setiastro/saspro/debayer.py +673 -0
  185. setiastro/saspro/debug_utils.py +29 -0
  186. setiastro/saspro/dnd_mime.py +35 -0
  187. setiastro/saspro/doc_manager.py +2664 -0
  188. setiastro/saspro/exoplanet_detector.py +2166 -0
  189. setiastro/saspro/file_utils.py +284 -0
  190. setiastro/saspro/fitsmodifier.py +748 -0
  191. setiastro/saspro/fix_bom.py +32 -0
  192. setiastro/saspro/free_torch_memory.py +48 -0
  193. setiastro/saspro/frequency_separation.py +1349 -0
  194. setiastro/saspro/function_bundle.py +1596 -0
  195. setiastro/saspro/generate_translations.py +3092 -0
  196. setiastro/saspro/ghs_dialog_pro.py +663 -0
  197. setiastro/saspro/ghs_preset.py +284 -0
  198. setiastro/saspro/graxpert.py +637 -0
  199. setiastro/saspro/graxpert_preset.py +287 -0
  200. setiastro/saspro/gui/__init__.py +0 -0
  201. setiastro/saspro/gui/main_window.py +8810 -0
  202. setiastro/saspro/gui/mixins/__init__.py +33 -0
  203. setiastro/saspro/gui/mixins/dock_mixin.py +362 -0
  204. setiastro/saspro/gui/mixins/file_mixin.py +450 -0
  205. setiastro/saspro/gui/mixins/geometry_mixin.py +403 -0
  206. setiastro/saspro/gui/mixins/header_mixin.py +441 -0
  207. setiastro/saspro/gui/mixins/mask_mixin.py +421 -0
  208. setiastro/saspro/gui/mixins/menu_mixin.py +389 -0
  209. setiastro/saspro/gui/mixins/theme_mixin.py +367 -0
  210. setiastro/saspro/gui/mixins/toolbar_mixin.py +1457 -0
  211. setiastro/saspro/gui/mixins/update_mixin.py +309 -0
  212. setiastro/saspro/gui/mixins/view_mixin.py +435 -0
  213. setiastro/saspro/gui/statistics_dialog.py +47 -0
  214. setiastro/saspro/halobgon.py +488 -0
  215. setiastro/saspro/header_viewer.py +448 -0
  216. setiastro/saspro/headless_utils.py +88 -0
  217. setiastro/saspro/histogram.py +756 -0
  218. setiastro/saspro/history_explorer.py +941 -0
  219. setiastro/saspro/i18n.py +168 -0
  220. setiastro/saspro/image_combine.py +417 -0
  221. setiastro/saspro/image_peeker_pro.py +1604 -0
  222. setiastro/saspro/imageops/__init__.py +37 -0
  223. setiastro/saspro/imageops/mdi_snap.py +292 -0
  224. setiastro/saspro/imageops/scnr.py +36 -0
  225. setiastro/saspro/imageops/starbasedwhitebalance.py +210 -0
  226. setiastro/saspro/imageops/stretch.py +236 -0
  227. setiastro/saspro/isophote.py +1182 -0
  228. setiastro/saspro/layers.py +208 -0
  229. setiastro/saspro/layers_dock.py +714 -0
  230. setiastro/saspro/lazy_imports.py +193 -0
  231. setiastro/saspro/legacy/__init__.py +2 -0
  232. setiastro/saspro/legacy/image_manager.py +2226 -0
  233. setiastro/saspro/legacy/numba_utils.py +3676 -0
  234. setiastro/saspro/legacy/xisf.py +1071 -0
  235. setiastro/saspro/linear_fit.py +537 -0
  236. setiastro/saspro/live_stacking.py +1841 -0
  237. setiastro/saspro/log_bus.py +5 -0
  238. setiastro/saspro/logging_config.py +460 -0
  239. setiastro/saspro/luminancerecombine.py +309 -0
  240. setiastro/saspro/main_helpers.py +201 -0
  241. setiastro/saspro/mask_creation.py +931 -0
  242. setiastro/saspro/masks_core.py +56 -0
  243. setiastro/saspro/mdi_widgets.py +353 -0
  244. setiastro/saspro/memory_utils.py +666 -0
  245. setiastro/saspro/metadata_patcher.py +75 -0
  246. setiastro/saspro/mfdeconv.py +3831 -0
  247. setiastro/saspro/mfdeconv_earlystop.py +71 -0
  248. setiastro/saspro/mfdeconvcudnn.py +3263 -0
  249. setiastro/saspro/mfdeconvsport.py +2382 -0
  250. setiastro/saspro/minorbodycatalog.py +567 -0
  251. setiastro/saspro/morphology.py +407 -0
  252. setiastro/saspro/multiscale_decomp.py +1293 -0
  253. setiastro/saspro/nbtorgb_stars.py +541 -0
  254. setiastro/saspro/numba_utils.py +3145 -0
  255. setiastro/saspro/numba_warmup.py +141 -0
  256. setiastro/saspro/ops/__init__.py +9 -0
  257. setiastro/saspro/ops/command_help_dialog.py +623 -0
  258. setiastro/saspro/ops/command_runner.py +217 -0
  259. setiastro/saspro/ops/commands.py +1594 -0
  260. setiastro/saspro/ops/script_editor.py +1102 -0
  261. setiastro/saspro/ops/scripts.py +1473 -0
  262. setiastro/saspro/ops/settings.py +637 -0
  263. setiastro/saspro/parallel_utils.py +554 -0
  264. setiastro/saspro/pedestal.py +121 -0
  265. setiastro/saspro/perfect_palette_picker.py +1071 -0
  266. setiastro/saspro/pipeline.py +110 -0
  267. setiastro/saspro/pixelmath.py +1604 -0
  268. setiastro/saspro/plate_solver.py +2445 -0
  269. setiastro/saspro/project_io.py +797 -0
  270. setiastro/saspro/psf_utils.py +136 -0
  271. setiastro/saspro/psf_viewer.py +549 -0
  272. setiastro/saspro/pyi_rthook_astroquery.py +95 -0
  273. setiastro/saspro/remove_green.py +331 -0
  274. setiastro/saspro/remove_stars.py +1599 -0
  275. setiastro/saspro/remove_stars_preset.py +404 -0
  276. setiastro/saspro/resources.py +501 -0
  277. setiastro/saspro/rgb_combination.py +208 -0
  278. setiastro/saspro/rgb_extract.py +19 -0
  279. setiastro/saspro/rgbalign.py +723 -0
  280. setiastro/saspro/runtime_imports.py +7 -0
  281. setiastro/saspro/runtime_torch.py +754 -0
  282. setiastro/saspro/save_options.py +73 -0
  283. setiastro/saspro/selective_color.py +1552 -0
  284. setiastro/saspro/sfcc.py +1472 -0
  285. setiastro/saspro/shortcuts.py +3043 -0
  286. setiastro/saspro/signature_insert.py +1102 -0
  287. setiastro/saspro/stacking_suite.py +18470 -0
  288. setiastro/saspro/star_alignment.py +7435 -0
  289. setiastro/saspro/star_alignment_preset.py +329 -0
  290. setiastro/saspro/star_metrics.py +49 -0
  291. setiastro/saspro/star_spikes.py +765 -0
  292. setiastro/saspro/star_stretch.py +507 -0
  293. setiastro/saspro/stat_stretch.py +538 -0
  294. setiastro/saspro/status_log_dock.py +78 -0
  295. setiastro/saspro/subwindow.py +3328 -0
  296. setiastro/saspro/supernovaasteroidhunter.py +1719 -0
  297. setiastro/saspro/swap_manager.py +99 -0
  298. setiastro/saspro/torch_backend.py +89 -0
  299. setiastro/saspro/torch_rejection.py +434 -0
  300. setiastro/saspro/translations/all_source_strings.json +3654 -0
  301. setiastro/saspro/translations/ar_translations.py +3865 -0
  302. setiastro/saspro/translations/de_translations.py +3749 -0
  303. setiastro/saspro/translations/es_translations.py +3939 -0
  304. setiastro/saspro/translations/fr_translations.py +3858 -0
  305. setiastro/saspro/translations/hi_translations.py +3571 -0
  306. setiastro/saspro/translations/integrate_translations.py +270 -0
  307. setiastro/saspro/translations/it_translations.py +3678 -0
  308. setiastro/saspro/translations/ja_translations.py +3601 -0
  309. setiastro/saspro/translations/pt_translations.py +3869 -0
  310. setiastro/saspro/translations/ru_translations.py +2848 -0
  311. setiastro/saspro/translations/saspro_ar.qm +0 -0
  312. setiastro/saspro/translations/saspro_ar.ts +255 -0
  313. setiastro/saspro/translations/saspro_de.qm +0 -0
  314. setiastro/saspro/translations/saspro_de.ts +253 -0
  315. setiastro/saspro/translations/saspro_es.qm +0 -0
  316. setiastro/saspro/translations/saspro_es.ts +12520 -0
  317. setiastro/saspro/translations/saspro_fr.qm +0 -0
  318. setiastro/saspro/translations/saspro_fr.ts +12514 -0
  319. setiastro/saspro/translations/saspro_hi.qm +0 -0
  320. setiastro/saspro/translations/saspro_hi.ts +257 -0
  321. setiastro/saspro/translations/saspro_it.qm +0 -0
  322. setiastro/saspro/translations/saspro_it.ts +12520 -0
  323. setiastro/saspro/translations/saspro_ja.qm +0 -0
  324. setiastro/saspro/translations/saspro_ja.ts +257 -0
  325. setiastro/saspro/translations/saspro_pt.qm +0 -0
  326. setiastro/saspro/translations/saspro_pt.ts +257 -0
  327. setiastro/saspro/translations/saspro_ru.qm +0 -0
  328. setiastro/saspro/translations/saspro_ru.ts +237 -0
  329. setiastro/saspro/translations/saspro_sw.qm +0 -0
  330. setiastro/saspro/translations/saspro_sw.ts +257 -0
  331. setiastro/saspro/translations/saspro_uk.qm +0 -0
  332. setiastro/saspro/translations/saspro_uk.ts +10771 -0
  333. setiastro/saspro/translations/saspro_zh.qm +0 -0
  334. setiastro/saspro/translations/saspro_zh.ts +12520 -0
  335. setiastro/saspro/translations/sw_translations.py +3671 -0
  336. setiastro/saspro/translations/uk_translations.py +3700 -0
  337. setiastro/saspro/translations/zh_translations.py +3675 -0
  338. setiastro/saspro/versioning.py +77 -0
  339. setiastro/saspro/view_bundle.py +1558 -0
  340. setiastro/saspro/wavescale_hdr.py +645 -0
  341. setiastro/saspro/wavescale_hdr_preset.py +101 -0
  342. setiastro/saspro/wavescalede.py +680 -0
  343. setiastro/saspro/wavescalede_preset.py +230 -0
  344. setiastro/saspro/wcs_update.py +374 -0
  345. setiastro/saspro/whitebalance.py +492 -0
  346. setiastro/saspro/widgets/__init__.py +48 -0
  347. setiastro/saspro/widgets/common_utilities.py +306 -0
  348. setiastro/saspro/widgets/graphics_views.py +122 -0
  349. setiastro/saspro/widgets/image_utils.py +518 -0
  350. setiastro/saspro/widgets/minigame/game.js +986 -0
  351. setiastro/saspro/widgets/minigame/index.html +53 -0
  352. setiastro/saspro/widgets/minigame/style.css +241 -0
  353. setiastro/saspro/widgets/preview_dialogs.py +280 -0
  354. setiastro/saspro/widgets/resource_monitor.py +237 -0
  355. setiastro/saspro/widgets/spinboxes.py +275 -0
  356. setiastro/saspro/widgets/themed_buttons.py +13 -0
  357. setiastro/saspro/widgets/wavelet_utils.py +331 -0
  358. setiastro/saspro/wimi.py +7996 -0
  359. setiastro/saspro/wims.py +578 -0
  360. setiastro/saspro/window_shelf.py +185 -0
  361. setiastro/saspro/xisf.py +1123 -0
  362. setiastrosuitepro-1.6.2.post1.dist-info/METADATA +278 -0
  363. setiastrosuitepro-1.6.2.post1.dist-info/RECORD +367 -0
  364. setiastrosuitepro-1.6.2.post1.dist-info/WHEEL +4 -0
  365. setiastrosuitepro-1.6.2.post1.dist-info/entry_points.txt +6 -0
  366. setiastrosuitepro-1.6.2.post1.dist-info/licenses/LICENSE +674 -0
  367. setiastrosuitepro-1.6.2.post1.dist-info/licenses/license.txt +2580 -0
@@ -0,0 +1,53 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Neon Invaders: Hyperdrive</title>
7
+ <link rel="stylesheet" href="style.css">
8
+ </head>
9
+ <body>
10
+ <div id="game-container">
11
+ <canvas id="gameCanvas"></canvas>
12
+ <div id="ui-layer">
13
+ <div id="hud" class="hidden">
14
+ <div class="hud-item">SCORE: <span id="score">0</span></div>
15
+ <div class="hud-item center">LEVEL: <span id="level">1</span></div>
16
+ <div class="hud-item right">HP: <div id="hp-bar"><div id="hp-fill"></div></div></div>
17
+ </div>
18
+
19
+ <div id="main-menu" class="screen">
20
+ <h1 class="glow-text">NEON INVADERS<br><span class="subtitle">HYPERDRIVE</span></h1>
21
+ <div class="menu-options">
22
+ <button id="btn-start" class="menu-btn">START GAME</button>
23
+ <button id="btn-levels" class="menu-btn">SELECT LEVEL</button>
24
+ <div id="controls-hint">ARROWS to Move • SPACE to Shoot</div>
25
+ </div>
26
+ </div>
27
+
28
+ <div id="level-select" class="screen hidden">
29
+ <h2>SELECT LEVEL</h2>
30
+ <div class="level-grid" id="level-grid">
31
+ <!-- Populated by JS -->
32
+ </div>
33
+ <button id="btn-back" class="menu-btn">BACK</button>
34
+ </div>
35
+
36
+ <div id="game-over" class="screen hidden">
37
+ <h1 class="danger-text">GAME OVER</h1>
38
+ <p>FINAL SCORE: <span id="final-score">0</span></p>
39
+ <button id="btn-retry" class="menu-btn">RETRY</button>
40
+ <button id="btn-menu" class="menu-btn">MAIN MENU</button>
41
+ </div>
42
+
43
+ <div id="victory" class="screen hidden">
44
+ <h1 class="victory-text">MISSION COMPLETE</h1>
45
+ <p>YOU SAVED THE GALAXY!</p>
46
+ <p>FINAL SCORE: <span id="victory-score">0</span></p>
47
+ <button id="btn-menu-win" class="menu-btn">MAIN MENU</button>
48
+ </div>
49
+ </div>
50
+ </div>
51
+ <script src="game.js"></script>
52
+ </body>
53
+ </html>
@@ -0,0 +1,241 @@
1
+ @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&display=swap');
2
+
3
+ :root {
4
+ --neon-blue: #0ff;
5
+ --neon-pink: #f0f;
6
+ --neon-green: #0f0;
7
+ --neon-red: #f00;
8
+ --bg-color: #050510;
9
+ }
10
+
11
+ * {
12
+ box-sizing: border-box;
13
+ user-select: none;
14
+ }
15
+
16
+ body {
17
+ margin: 0;
18
+ padding: 0;
19
+ background-color: #000;
20
+ color: var(--neon-blue);
21
+ font-family: 'Orbitron', sans-serif;
22
+ overflow: hidden;
23
+ height: 100vh;
24
+ display: flex;
25
+ justify-content: center;
26
+ align-items: center;
27
+ }
28
+
29
+ #game-container {
30
+ position: relative;
31
+ width: 100%;
32
+ height: 100%;
33
+ max-width: 800px;
34
+ /* Arcade aspect ratio sort of */
35
+ max-height: 100vh;
36
+ box-shadow: 0 0 50px rgba(0, 255, 255, 0.1);
37
+ background: #000;
38
+ }
39
+
40
+ canvas {
41
+ display: block;
42
+ width: 100%;
43
+ height: 100%;
44
+ }
45
+
46
+ #ui-layer {
47
+ position: absolute;
48
+ top: 0;
49
+ left: 0;
50
+ width: 100%;
51
+ height: 100%;
52
+ pointer-events: none;
53
+ /* Let clicks pass through generally, but enable for buttons */
54
+ }
55
+
56
+ /* Screens */
57
+ .screen {
58
+ position: absolute;
59
+ top: 0;
60
+ left: 0;
61
+ width: 100%;
62
+ height: 100%;
63
+ background: rgba(0, 0, 0, 0.85);
64
+ display: flex;
65
+ flex-direction: column;
66
+ justify-content: center;
67
+ align-items: center;
68
+ text-align: center;
69
+ pointer-events: auto;
70
+ transition: opacity 0.3s;
71
+ z-index: 10;
72
+ }
73
+
74
+ .hidden {
75
+ display: none !important;
76
+ }
77
+
78
+ /* Typography */
79
+ h1 {
80
+ font-size: 3rem;
81
+ margin-bottom: 2rem;
82
+ text-shadow: 0 0 10px currentColor;
83
+ }
84
+
85
+ .subtitle {
86
+ font-size: 1.2rem;
87
+ letter-spacing: 0.5rem;
88
+ color: var(--neon-pink);
89
+ }
90
+
91
+ .glow-text {
92
+ color: var(--neon-blue);
93
+ text-shadow: 0 0 20px var(--neon-blue);
94
+ }
95
+
96
+ .danger-text {
97
+ color: var(--neon-red);
98
+ text-shadow: 0 0 20px var(--neon-red);
99
+ }
100
+
101
+ .victory-text {
102
+ color: var(--neon-green);
103
+ text-shadow: 0 0 20px var(--neon-green);
104
+ }
105
+
106
+ /* Buttons */
107
+ .menu-btn {
108
+ background: transparent;
109
+ border: 2px solid var(--neon-blue);
110
+ color: var(--neon-blue);
111
+ padding: 15px 40px;
112
+ font-size: 1.2rem;
113
+ font-family: 'Orbitron', sans-serif;
114
+ margin: 10px;
115
+ cursor: pointer;
116
+ transition: all 0.2s;
117
+ text-transform: uppercase;
118
+ box-shadow: 0 0 5px var(--neon-blue);
119
+ position: relative;
120
+ overflow: hidden;
121
+ }
122
+
123
+ .menu-btn:hover {
124
+ background: var(--neon-blue);
125
+ color: #000;
126
+ box-shadow: 0 0 20px var(--neon-blue);
127
+ transform: scale(1.05);
128
+ }
129
+
130
+ .menu-btn:active {
131
+ transform: scale(0.98);
132
+ }
133
+
134
+ /* HUD */
135
+ #hud {
136
+ position: absolute;
137
+ top: 0;
138
+ left: 0;
139
+ width: 100%;
140
+ padding: 20px;
141
+ display: flex;
142
+ justify-content: space-between;
143
+ pointer-events: none;
144
+ z-index: 5;
145
+ text-shadow: 0 0 5px currentColor;
146
+ font-weight: bold;
147
+ font-size: 1.2rem;
148
+ }
149
+
150
+ .hud-item {
151
+ flex: 1;
152
+ }
153
+
154
+ .center {
155
+ text-align: center;
156
+ }
157
+
158
+ .right {
159
+ text-align: right;
160
+ display: flex;
161
+ justify-content: flex-end;
162
+ align-items: center;
163
+ gap: 10px;
164
+ }
165
+
166
+ #hp-bar {
167
+ width: 150px;
168
+ height: 15px;
169
+ border: 2px solid var(--neon-red);
170
+ background: #300;
171
+ position: relative;
172
+ }
173
+
174
+ #hp-fill {
175
+ width: 100%;
176
+ height: 100%;
177
+ background: var(--neon-red);
178
+ box-shadow: 0 0 10px var(--neon-red);
179
+ transition: width 0.2s;
180
+ }
181
+
182
+ /* Level Grid */
183
+ .level-grid {
184
+ display: grid;
185
+ grid-template-columns: repeat(5, 1fr);
186
+ gap: 10px;
187
+ margin-bottom: 2rem;
188
+ }
189
+
190
+ .level-btn {
191
+ padding: 15px;
192
+ border: 1px solid var(--neon-pink);
193
+ color: var(--neon-pink);
194
+ background: transparent;
195
+ font-family: 'Orbitron', sans-serif;
196
+ cursor: pointer;
197
+ transition: all 0.2s;
198
+ }
199
+
200
+ .level-btn:hover:not(:disabled) {
201
+ background: var(--neon-pink);
202
+ color: #000;
203
+ box-shadow: 0 0 15px var(--neon-pink);
204
+ }
205
+
206
+ .level-btn:disabled {
207
+ opacity: 0.3;
208
+ cursor: not-allowed;
209
+ border-color: #555;
210
+ color: #555;
211
+ }
212
+
213
+ #controls-hint {
214
+ margin-top: 30px;
215
+ color: #fff;
216
+ opacity: 0.7;
217
+ font-size: 0.8rem;
218
+ }
219
+
220
+ /* Animations */
221
+ @keyframes fadeUp {
222
+ 0% {
223
+ opacity: 0;
224
+ transform: translate(-50%, 0);
225
+ }
226
+
227
+ 20% {
228
+ opacity: 1;
229
+ transform: translate(-50%, -50%);
230
+ }
231
+
232
+ 80% {
233
+ opacity: 1;
234
+ transform: translate(-50%, -50%);
235
+ }
236
+
237
+ 100% {
238
+ opacity: 0;
239
+ transform: translate(-50%, -100%);
240
+ }
241
+ }
@@ -0,0 +1,280 @@
1
+ # pro/widgets/preview_dialogs.py
2
+ """
3
+ Centralized preview dialog widgets for Seti Astro Suite Pro.
4
+ """
5
+ from __future__ import annotations
6
+
7
+ import numpy as np
8
+ from PyQt6.QtCore import Qt, QTimer, QPoint, QEvent
9
+ from PyQt6.QtGui import QImage, QPixmap, QIcon
10
+ from PyQt6.QtWidgets import (
11
+ QDialog, QVBoxLayout, QHBoxLayout, QPushButton, QLabel,
12
+ QScrollArea, QToolButton
13
+ )
14
+
15
+ from setiastro.saspro.widgets.themed_buttons import themed_toolbtn
16
+
17
+ # Import stretch functions - these are core to the app
18
+ from setiastro.saspro.imageops.stretch import stretch_mono_image, stretch_color_image
19
+
20
+ def _as_float01(img: np.ndarray) -> np.ndarray:
21
+ a = np.asarray(img)
22
+
23
+ # Integers: scale by dtype max
24
+ if a.dtype.kind in "ui":
25
+ maxv = float(np.iinfo(a.dtype).max)
26
+ if maxv <= 0:
27
+ return np.zeros_like(a, dtype=np.float32)
28
+ return (a.astype(np.float32) / maxv).clip(0.0, 1.0)
29
+
30
+ # Floats: if already 0..1, keep; otherwise scale down
31
+ af = a.astype(np.float32, copy=False)
32
+
33
+ mx = float(np.nanmax(af)) if af.size else 0.0
34
+ if not np.isfinite(mx) or mx <= 1.0:
35
+ return np.clip(af, 0.0, 1.0)
36
+
37
+ # Common “display buffers”: 0..255 or 0..65535 stored as float
38
+ if mx <= 255.5:
39
+ return np.clip(af / 255.0, 0.0, 1.0)
40
+ if mx <= 65535.5:
41
+ return np.clip(af / 65535.0, 0.0, 1.0)
42
+
43
+ # Fallback: normalize by max
44
+ return np.clip(af / mx, 0.0, 1.0)
45
+
46
+
47
+ class ImagePreviewDialog(QDialog):
48
+ """
49
+ A dialog for previewing images with autostretch and zoom capabilities.
50
+
51
+ Features:
52
+ - AutoStretch toggle
53
+ - Zoom in/out (buttons and mouse wheel)
54
+ - Scroll area for panning
55
+ - Supports mono and RGB images
56
+
57
+ Usage:
58
+ dialog = ImagePreviewDialog(np_image, is_mono=False)
59
+ dialog.exec()
60
+ """
61
+
62
+ def __init__(self, np_image: np.ndarray, is_mono: bool = False, parent=None):
63
+ super().__init__(parent)
64
+ self.setWindowTitle(self.tr("Image Preview"))
65
+ self.resize(640, 480)
66
+
67
+ self.autostretch_enabled = False
68
+ self.is_mono = is_mono
69
+ self.zoom_factor = 1.0
70
+ # Drag-to-pan state
71
+ self._panning = False
72
+ self._pan_last = QPoint()
73
+
74
+ # Store the image, ensure float32 [0,1]
75
+ self.np_image = _as_float01(np_image)
76
+
77
+ # Store the image, ensure float32 [0,1]
78
+ self.np_image = _as_float01(np_image)
79
+
80
+ # Layout
81
+ layout = QVBoxLayout(self)
82
+
83
+ # Toolbar row (themed)
84
+ bar = QHBoxLayout()
85
+
86
+ self.autostretch_button = QToolButton()
87
+ self.autostretch_button.setText(self.tr("AutoStretch (Off)"))
88
+ self.autostretch_button.setToolTip(self.tr("Toggle AutoStretch"))
89
+ self.autostretch_button.setCheckable(True)
90
+ self.autostretch_button.toggled.connect(self._toggle_autostretch)
91
+ bar.addWidget(self.autostretch_button)
92
+
93
+ bar.addStretch(1)
94
+
95
+ self.zoom_in_button = themed_toolbtn("zoom-in", self.tr("Zoom In"))
96
+ self.zoom_out_button = themed_toolbtn("zoom-out", self.tr("Zoom Out"))
97
+ self.zoom_1to1_button = themed_toolbtn("zoom-original", self.tr("1:1 (100%)"))
98
+ self.fit_button = themed_toolbtn("zoom-fit-best", self.tr("Fit to Preview"))
99
+
100
+ self.zoom_in_button.clicked.connect(self._zoom_in)
101
+ self.zoom_out_button.clicked.connect(self._zoom_out)
102
+ self.zoom_1to1_button.clicked.connect(self._one_to_one)
103
+ self.fit_button.clicked.connect(self._fit_to_preview)
104
+
105
+ bar.addWidget(self.zoom_in_button)
106
+ bar.addWidget(self.zoom_out_button)
107
+ bar.addWidget(self.zoom_1to1_button)
108
+ bar.addWidget(self.fit_button)
109
+
110
+ layout.addLayout(bar)
111
+
112
+ # Scroll area
113
+ self.scroll_area = QScrollArea(self)
114
+ self.scroll_area.setWidgetResizable(True)
115
+ layout.addWidget(self.scroll_area)
116
+
117
+ # Image label
118
+ self.image_label = QLabel()
119
+ self.scroll_area.setWidget(self.image_label)
120
+ self.image_label.installEventFilter(self)
121
+ self.scroll_area.viewport().installEventFilter(self)
122
+ self.image_label.setText("")
123
+ self.image_label.setMouseTracking(True)
124
+ # Display initial image
125
+ self._display_image(self.np_image)
126
+
127
+ # Enable mouse wheel zoom
128
+ self.image_label.installEventFilter(self)
129
+
130
+ # Center scrollbars after layout
131
+ QTimer.singleShot(0, self._fit_to_preview)
132
+
133
+ def _display_image(self, np_img: np.ndarray):
134
+ """Convert numpy array to QImage and display at current zoom."""
135
+ # Convert to uint8
136
+ arr = (np.clip(np_img, 0, 1) * 255).astype(np.uint8)
137
+
138
+ if arr.ndim == 3 and arr.shape[2] == 3:
139
+ h, w, _ = arr.shape
140
+ qimg = QImage(arr.tobytes(), w, h, 3 * w, QImage.Format.Format_RGB888)
141
+ elif arr.ndim == 2:
142
+ h, w = arr.shape
143
+ qimg = QImage(arr.tobytes(), w, h, w, QImage.Format.Format_Grayscale8)
144
+ elif arr.ndim == 3 and arr.shape[2] == 1:
145
+ arr = arr.squeeze()
146
+ h, w = arr.shape
147
+ qimg = QImage(arr.tobytes(), w, h, w, QImage.Format.Format_Grayscale8)
148
+ else:
149
+ raise ValueError(f"Unexpected image shape: {arr.shape}")
150
+
151
+ # Apply zoom
152
+ pixmap = QPixmap.fromImage(qimg)
153
+ scaled_w = int(pixmap.width() * self.zoom_factor)
154
+ scaled_h = int(pixmap.height() * self.zoom_factor)
155
+ scaled_pixmap = pixmap.scaled(
156
+ scaled_w, scaled_h,
157
+ Qt.AspectRatioMode.KeepAspectRatio,
158
+ Qt.TransformationMode.SmoothTransformation
159
+ )
160
+ self.image_label.setPixmap(scaled_pixmap)
161
+ self.image_label.adjustSize()
162
+
163
+ def _toggle_autostretch(self, checked: bool):
164
+ """Toggle autostretch on/off."""
165
+ self.autostretch_enabled = checked
166
+ self.autostretch_button.setText(
167
+ self.tr("AutoStretch (On)") if checked else self.tr("AutoStretch (Off)")
168
+ )
169
+ self._apply_display()
170
+
171
+ def _one_to_one(self):
172
+ self.zoom_factor = 1.0
173
+ self._apply_display()
174
+
175
+ def _fit_to_preview(self):
176
+ # Fit image into the scroll viewport
177
+ if self.image_label.pixmap() is None or self.image_label.pixmap().isNull():
178
+ return
179
+ vp = self.scroll_area.viewport().size()
180
+ pm = self.image_label.pixmap()
181
+ if pm.width() <= 0 or pm.height() <= 0:
182
+ return
183
+
184
+ # Compute zoom that fits current *source image* (not already scaled label)
185
+ # So, recompute based on original image dims:
186
+ base_h, base_w = self.np_image.shape[:2]
187
+ if base_w <= 0 or base_h <= 0:
188
+ return
189
+
190
+ zx = vp.width() / float(base_w)
191
+ zy = vp.height() / float(base_h)
192
+ self.zoom_factor = max(0.01, min(zx, zy))
193
+ self._apply_display()
194
+
195
+
196
+ def _apply_display(self):
197
+ """Apply current display settings (autostretch, zoom)."""
198
+ target_median = 0.25
199
+
200
+ if self.autostretch_enabled:
201
+ if self.np_image.ndim == 2:
202
+ stretched = stretch_mono_image(self.np_image, target_median)
203
+ display_img = np.stack([stretched] * 3, axis=-1)
204
+ elif self.np_image.ndim == 3 and self.np_image.shape[2] == 3:
205
+ display_img = stretch_color_image(self.np_image, target_median, linked=False)
206
+ elif self.np_image.ndim == 3 and self.np_image.shape[2] == 1:
207
+ stretched = stretch_mono_image(self.np_image.squeeze(), target_median)
208
+ display_img = np.stack([stretched] * 3, axis=-1)
209
+ else:
210
+ display_img = self.np_image
211
+ else:
212
+ if self.np_image.ndim == 2:
213
+ display_img = np.stack([self.np_image] * 3, axis=-1)
214
+ elif self.np_image.ndim == 3 and self.np_image.shape[2] == 1:
215
+ display_img = np.repeat(self.np_image, 3, axis=2)
216
+ else:
217
+ display_img = self.np_image
218
+
219
+ self._display_image(display_img)
220
+
221
+ def _zoom_in(self):
222
+ """Zoom in by 20%."""
223
+ self.zoom_factor *= 1.2
224
+ self._apply_display()
225
+
226
+ def _zoom_out(self):
227
+ """Zoom out by 20%."""
228
+ self.zoom_factor /= 1.2
229
+ self._apply_display()
230
+
231
+ def _center_scrollbars(self):
232
+ """Center the scroll area on the image."""
233
+ h_bar = self.scroll_area.horizontalScrollBar()
234
+ v_bar = self.scroll_area.verticalScrollBar()
235
+ h_bar.setValue((h_bar.maximum() + h_bar.minimum()) // 2)
236
+ v_bar.setValue((v_bar.maximum() + v_bar.minimum()) // 2)
237
+
238
+ def eventFilter(self, source, event):
239
+ # --- wheel zoom (keep exactly as you had) ---
240
+ if source in (self.image_label, self.scroll_area.viewport()) and event.type() == QEvent.Type.Wheel:
241
+ if event.angleDelta().y() > 0:
242
+ self._zoom_in()
243
+ else:
244
+ self._zoom_out()
245
+ return True
246
+
247
+ # --- drag-to-pan ---
248
+ if source in (self.image_label, self.scroll_area.viewport()):
249
+
250
+ if event.type() == QEvent.Type.MouseButtonPress and event.button() == Qt.MouseButton.LeftButton:
251
+ self._panning = True
252
+ self._pan_last = event.globalPosition().toPoint()
253
+ # nice UX
254
+ self.setCursor(Qt.CursorShape.ClosedHandCursor)
255
+ return True
256
+
257
+ if event.type() == QEvent.Type.MouseMove and self._panning:
258
+ cur = event.globalPosition().toPoint()
259
+ delta = cur - self._pan_last
260
+ self._pan_last = cur
261
+
262
+ h = self.scroll_area.horizontalScrollBar()
263
+ v = self.scroll_area.verticalScrollBar()
264
+ h.setValue(h.value() - delta.x())
265
+ v.setValue(v.value() - delta.y())
266
+ return True
267
+
268
+ if event.type() == QEvent.Type.MouseButtonRelease and event.button() == Qt.MouseButton.LeftButton and self._panning:
269
+ self._panning = False
270
+ self.unsetCursor()
271
+ return True
272
+
273
+ # if mouse leaves while dragging, stop panning so it doesn't get "stuck"
274
+ if event.type() == QEvent.Type.Leave and self._panning:
275
+ self._panning = False
276
+ self.unsetCursor()
277
+ return True
278
+
279
+ return super().eventFilter(source, event)
280
+