scitex 2.10.3__py3-none-any.whl → 2.13.0__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.
Files changed (504) hide show
  1. scitex/__init__.py +1 -4
  2. scitex/__main__.py +24 -5
  3. scitex/__version__.py +1 -1
  4. scitex/_install_guide.py +14 -2
  5. scitex/_optional_deps.py +33 -0
  6. scitex/ai/classification/reporters/_ClassificationReporter.py +1 -1
  7. scitex/ai/classification/timeseries/_TimeSeriesBlockingSplit.py +2 -2
  8. scitex/ai/classification/timeseries/_TimeSeriesCalendarSplit.py +2 -2
  9. scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +2 -2
  10. scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit_v01-not-using-n_splits.py +2 -2
  11. scitex/ai/classification/timeseries/_TimeSeriesStratifiedSplit.py +2 -2
  12. scitex/ai/classification/timeseries/_normalize_timestamp.py +1 -1
  13. scitex/ai/metrics/_calc_seizure_prediction_metrics.py +1 -1
  14. scitex/ai/plt/_plot_feature_importance.py +1 -1
  15. scitex/ai/plt/_plot_learning_curve.py +1 -1
  16. scitex/ai/plt/_plot_optuna_study.py +1 -1
  17. scitex/ai/plt/_plot_pre_rec_curve.py +1 -1
  18. scitex/ai/plt/_plot_roc_curve.py +1 -1
  19. scitex/ai/plt/_stx_conf_mat.py +1 -1
  20. scitex/ai/training/_LearningCurveLogger.py +1 -1
  21. scitex/audio/mcp_server.py +38 -8
  22. scitex/bridge/_figrecipe.py +1 -1
  23. scitex/bridge/_helpers.py +1 -1
  24. scitex/bridge/_plt_vis.py +1 -1
  25. scitex/bridge/_stats_plt.py +1 -1
  26. scitex/bridge/_stats_vis.py +2 -2
  27. scitex/browser/automation/CookieHandler.py +1 -1
  28. scitex/browser/core/BrowserMixin.py +1 -1
  29. scitex/browser/core/ChromeProfileManager.py +1 -1
  30. scitex/browser/debugging/_browser_logger.py +1 -1
  31. scitex/browser/debugging/_highlight_element.py +1 -1
  32. scitex/browser/debugging/_show_grid.py +1 -1
  33. scitex/browser/interaction/click_center.py +1 -1
  34. scitex/browser/interaction/click_with_fallbacks.py +1 -1
  35. scitex/browser/interaction/close_popups.py +1 -1
  36. scitex/browser/interaction/fill_with_fallbacks.py +1 -1
  37. scitex/browser/pdf/click_download_for_chrome_pdf_viewer.py +1 -1
  38. scitex/browser/pdf/detect_chrome_pdf_viewer.py +1 -1
  39. scitex/browser/stealth/HumanBehavior.py +1 -1
  40. scitex/browser/stealth/StealthManager.py +1 -1
  41. scitex/{fig → canvas}/__init__.py +84 -96
  42. scitex/canvas/_mcp_handlers.py +372 -0
  43. scitex/canvas/_mcp_tool_schemas.py +219 -0
  44. scitex/{fig → canvas}/backend/_parser.py +1 -1
  45. scitex/{fig → canvas}/canvas.py +13 -14
  46. scitex/{fts/_fig/_editor → canvas/editor}/_defaults.py +2 -2
  47. scitex/{fig → canvas}/editor/edit/__init__.py +11 -14
  48. scitex/{fig → canvas}/editor/edit/bundle_resolver.py +56 -48
  49. scitex/{fig → canvas}/editor/edit/editor_launcher.py +79 -26
  50. scitex/{fts/_fig/_editor/_cui/_panel_loader.py → canvas/editor/edit/panel_loader.py} +8 -8
  51. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_bbox.py +2 -1
  52. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_core.py +84 -84
  53. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_renderer.py +7 -6
  54. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/static/css/features/canvas.css +2 -2
  55. scitex/{fig → canvas}/editor/flask_editor/static/css/features/panel-grid.css +1 -1
  56. scitex/{fig → canvas}/editor/flask_editor/static/js/core/api.js +3 -4
  57. scitex/{fig → canvas}/editor/flask_editor/static/js/editor/preview.js +5 -5
  58. scitex/{fig → canvas}/editor/flask_editor/templates/_html.py +3 -3
  59. scitex/{fig → canvas}/editor/flask_editor/templates/_scripts.py +10 -10
  60. scitex/{fig → canvas}/editor/flask_editor/templates/_styles.py +3 -3
  61. scitex/{fig → canvas}/io/__init__.py +32 -38
  62. scitex/{fig → canvas}/io/_bundle.py +217 -154
  63. scitex/{fig → canvas}/io/_canvas.py +1 -1
  64. scitex/{fig → canvas}/io/_data.py +1 -1
  65. scitex/{fig → canvas}/io/_export.py +1 -1
  66. scitex/{fig → canvas}/io/_load.py +1 -1
  67. scitex/{fig → canvas}/io/_panel.py +1 -1
  68. scitex/{fig → canvas}/io/_save.py +1 -1
  69. scitex/canvas/mcp_server.py +151 -0
  70. scitex/{fig → canvas}/model/__init__.py +1 -1
  71. scitex/{fig → canvas}/model/_annotations.py +1 -1
  72. scitex/{fig → canvas}/model/_axes.py +1 -1
  73. scitex/{fig → canvas}/model/_figure.py +1 -1
  74. scitex/{fig → canvas}/model/_guides.py +1 -1
  75. scitex/{fig → canvas}/model/_plot.py +1 -1
  76. scitex/{fig → canvas}/model/_styles.py +1 -1
  77. scitex/{fig → canvas}/utils/__init__.py +1 -1
  78. scitex/capture/mcp_server.py +41 -12
  79. scitex/cli/audio.py +233 -0
  80. scitex/cli/capture.py +307 -0
  81. scitex/cli/convert.py +10 -6
  82. scitex/cli/main.py +27 -4
  83. scitex/cli/repro.py +233 -0
  84. scitex/cli/resource.py +240 -0
  85. scitex/cli/stats.py +325 -0
  86. scitex/cli/template.py +236 -0
  87. scitex/cli/tex.py +286 -0
  88. scitex/cli/web.py +11 -12
  89. scitex/dev/__init__.py +3 -0
  90. scitex/dev/_pyproject.py +405 -0
  91. scitex/dev/plt/__init__.py +2 -2
  92. scitex/dev/plt/mpl/get_dir_ax.py +1 -1
  93. scitex/dev/plt/mpl/get_signatures.py +1 -1
  94. scitex/dev/plt/mpl/get_signatures_details.py +1 -1
  95. scitex/diagram/README.md +7 -7
  96. scitex/diagram/_mcp_handlers.py +400 -0
  97. scitex/diagram/_mcp_tool_schemas.py +157 -0
  98. scitex/diagram/mcp_server.py +151 -0
  99. scitex/dsp/_demo_sig.py +51 -5
  100. scitex/dsp/_mne.py +13 -2
  101. scitex/dsp/_modulation_index.py +15 -3
  102. scitex/dsp/_pac.py +23 -5
  103. scitex/dsp/_psd.py +16 -4
  104. scitex/dsp/_resample.py +24 -4
  105. scitex/dsp/_transform.py +16 -3
  106. scitex/dsp/add_noise.py +15 -1
  107. scitex/dsp/norm.py +17 -2
  108. scitex/dsp/reference.py +17 -1
  109. scitex/dsp/utils/_differential_bandpass_filters.py +20 -2
  110. scitex/dsp/utils/_zero_pad.py +18 -4
  111. scitex/dt/_normalize_timestamp.py +1 -1
  112. scitex/git/_session.py +1 -1
  113. scitex/io/__init__.py +7 -19
  114. scitex/io/_load.py +15 -19
  115. scitex/io/_load_modules/_canvas.py +2 -2
  116. scitex/io/_load_modules/_con.py +17 -6
  117. scitex/io/_load_modules/_eeg.py +28 -13
  118. scitex/io/_load_modules/_optuna.py +21 -63
  119. scitex/io/_load_modules/_torch.py +11 -3
  120. scitex/io/_save.py +11 -16
  121. scitex/io/_save_modules/__init__.py +6 -10
  122. scitex/io/_save_modules/_canvas.py +3 -3
  123. scitex/io/_save_modules/_optuna_study_as_csv_and_pngs.py +13 -2
  124. scitex/io/_save_modules/_plot_bundle.py +112 -0
  125. scitex/io/_save_modules/{_pltz_stx.py → _plot_scitex.py} +7 -7
  126. scitex/io/_save_modules/_stx_bundle.py +16 -16
  127. scitex/io/_save_modules/_torch.py +11 -3
  128. scitex/io/bundle/README.md +89 -80
  129. scitex/{fts/_bundle/_FTS.py → io/bundle/_Bundle.py} +197 -95
  130. scitex/io/bundle/__init__.py +67 -35
  131. scitex/{fts/_bundle → io/bundle}/_children.py +32 -40
  132. scitex/io/bundle/_core.py +184 -97
  133. scitex/{fts/_bundle/_dataclasses/_Node.py → io/bundle/_dataclasses/_Spec.py} +29 -23
  134. scitex/{fts/_bundle/_dataclasses/_NodeRefs.py → io/bundle/_dataclasses/_SpecRefs.py} +6 -6
  135. scitex/{fts/_bundle → io/bundle}/_dataclasses/__init__.py +4 -4
  136. scitex/{fts/_bundle → io/bundle}/_loader.py +19 -19
  137. scitex/io/bundle/_manifest.py +99 -0
  138. scitex/{fts/_bundle → io/bundle}/_mpl_helpers.py +119 -28
  139. scitex/io/bundle/_nested.py +113 -100
  140. scitex/{fts/_bundle → io/bundle}/_saver.py +13 -14
  141. scitex/{fts/_bundle → io/bundle}/_storage.py +3 -3
  142. scitex/io/bundle/_types.py +41 -16
  143. scitex/{fts/_bundle → io/bundle}/_validation.py +20 -18
  144. scitex/io/bundle/_zip.py +21 -31
  145. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_backend/_parser.py +1 -1
  146. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Annotations.py +1 -1
  147. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Axes.py +1 -1
  148. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Figure.py +1 -1
  149. scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_Guides.py +1 -1
  150. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Plot.py +1 -1
  151. scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_Styles.py +1 -1
  152. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_utils/_plot_layout.py +1 -1
  153. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/__init__.py +1 -1
  154. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_editor/_app.py +1 -1
  155. scitex/{fts/_tables → io/bundle/kinds/_table}/_latex/_export.py +1 -1
  156. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_figure_exporter.py +1 -1
  157. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_table_exporter.py +1 -1
  158. scitex/io/bundle/schemas/__init__.py +30 -0
  159. scitex/mcp_server.py +159 -0
  160. scitex/parallel/_run.py +5 -4
  161. scitex/path/_find.py +60 -83
  162. scitex/path/_get_module_path.py +23 -21
  163. scitex/path/_get_spath.py +6 -27
  164. scitex/path/_getsize.py +23 -9
  165. scitex/path/_increment_version.py +31 -38
  166. scitex/path/_mk_spath.py +26 -29
  167. scitex/path/_path.py +5 -12
  168. scitex/path/_split.py +27 -15
  169. scitex/path/_this_path.py +23 -9
  170. scitex/plt/_mcp_handlers.py +361 -0
  171. scitex/plt/_mcp_tool_schemas.py +169 -0
  172. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/__init__.py +2 -1
  173. scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +2 -2
  174. scitex/plt/gallery/_generate.py +76 -50
  175. scitex/plt/io/__init__.py +17 -19
  176. scitex/plt/io/_bundle.py +99 -52
  177. scitex/plt/io/_layered_bundle.py +303 -168
  178. scitex/plt/mcp_server.py +205 -0
  179. scitex/plt/utils/_csv_column_naming.py +250 -118
  180. scitex/repro/README_RandomStateManager.md +3 -3
  181. scitex/repro/_RandomStateManager.py +14 -14
  182. scitex/repro/_gen_ID.py +1 -1
  183. scitex/repro/_gen_timestamp.py +1 -1
  184. scitex/repro/_hash_array.py +4 -4
  185. scitex/schema/__init__.py +69 -73
  186. scitex/schema/_canvas.py +1 -1
  187. scitex/schema/_stats.py +2 -2
  188. scitex/scholar/__main__.py +24 -2
  189. scitex/scholar/_mcp_handlers.py +685 -0
  190. scitex/scholar/_mcp_tool_schemas.py +339 -0
  191. scitex/scholar/docs/template.py +1 -1
  192. scitex/scholar/examples/07_storage_integration.py +1 -1
  193. scitex/scholar/impact_factor/jcr/ImpactFactorJCREngine.py +1 -1
  194. scitex/scholar/impact_factor/jcr/build_database.py +1 -1
  195. scitex/scholar/mcp_server.py +315 -0
  196. scitex/scholar/pdf_download/ScholarPDFDownloader.py +1 -1
  197. scitex/scholar/pipelines/ScholarPipelineBibTeX.py +1 -1
  198. scitex/scholar/pipelines/ScholarPipelineParallel.py +1 -1
  199. scitex/scholar/pipelines/ScholarPipelineSingle.py +1 -1
  200. scitex/scholar/storage/PaperIO.py +1 -1
  201. scitex/session/README.md +4 -4
  202. scitex/session/__init__.py +1 -1
  203. scitex/session/_decorator.py +9 -9
  204. scitex/session/_lifecycle.py +5 -5
  205. scitex/session/template.py +1 -1
  206. scitex/stats/__init__.py +30 -33
  207. scitex/stats/__main__.py +281 -0
  208. scitex/stats/_mcp_handlers.py +1191 -0
  209. scitex/stats/_mcp_tool_schemas.py +384 -0
  210. scitex/stats/_schema.py +1 -1
  211. scitex/stats/correct/_correct_bonferroni.py +1 -1
  212. scitex/stats/correct/_correct_fdr.py +1 -1
  213. scitex/stats/correct/_correct_fdr_.py +1 -1
  214. scitex/stats/correct/_correct_holm.py +1 -1
  215. scitex/stats/correct/_correct_sidak.py +1 -1
  216. scitex/stats/effect_sizes/_cliffs_delta.py +1 -1
  217. scitex/stats/effect_sizes/_cohens_d.py +1 -1
  218. scitex/stats/effect_sizes/_epsilon_squared.py +1 -1
  219. scitex/stats/effect_sizes/_eta_squared.py +1 -1
  220. scitex/stats/effect_sizes/_prob_superiority.py +1 -1
  221. scitex/stats/io/__init__.py +10 -11
  222. scitex/stats/io/_bundle.py +16 -16
  223. scitex/stats/mcp_server.py +405 -0
  224. scitex/stats/posthoc/_dunnett.py +1 -1
  225. scitex/stats/posthoc/_games_howell.py +1 -1
  226. scitex/stats/posthoc/_tukey_hsd.py +1 -1
  227. scitex/stats/power/_power.py +1 -1
  228. scitex/stats/utils/_effect_size.py +1 -1
  229. scitex/stats/utils/_formatters.py +1 -1
  230. scitex/stats/utils/_power.py +1 -1
  231. scitex/template/_mcp_handlers.py +259 -0
  232. scitex/template/_mcp_tool_schemas.py +112 -0
  233. scitex/template/mcp_server.py +186 -0
  234. scitex/utils/_verify_scitex_format.py +2 -2
  235. scitex/utils/template.py +1 -1
  236. scitex/web/__init__.py +12 -11
  237. scitex/web/_scraping.py +26 -265
  238. scitex/web/download_images.py +316 -0
  239. scitex/writer/Writer.py +1 -1
  240. scitex/writer/_clone_writer_project.py +1 -1
  241. scitex/writer/_validate_tree_structures.py +1 -1
  242. scitex/writer/dataclasses/config/_WriterConfig.py +1 -1
  243. scitex/writer/dataclasses/contents/_ManuscriptContents.py +1 -1
  244. scitex/writer/dataclasses/core/_Document.py +1 -1
  245. scitex/writer/dataclasses/core/_DocumentSection.py +1 -1
  246. scitex/writer/dataclasses/results/_CompilationResult.py +1 -1
  247. scitex/writer/dataclasses/results/_LaTeXIssue.py +1 -1
  248. scitex/writer/utils/.legacy_git_retry.py +7 -5
  249. scitex/writer/utils/_parse_latex_logs.py +1 -1
  250. scitex-2.13.0.dist-info/METADATA +1231 -0
  251. {scitex-2.10.3.dist-info → scitex-2.13.0.dist-info}/RECORD +376 -470
  252. scitex-2.13.0.dist-info/entry_points.txt +11 -0
  253. scitex/fig/editor/_defaults.py +0 -300
  254. scitex/fig/editor/edit/panel_loader.py +0 -232
  255. scitex/fig/editor/flask_editor/_bbox.py +0 -1299
  256. scitex/fig/editor/flask_editor/_core.py +0 -1429
  257. scitex/fig/editor/flask_editor/_renderer.py +0 -813
  258. scitex/fig/editor/flask_editor/static/css/features/canvas.css +0 -176
  259. scitex/fts/README.md +0 -262
  260. scitex/fts/TODO.md +0 -66
  261. scitex/fts/__init__.py +0 -90
  262. scitex/fts/_bundle/README_IN_BUNDLE.md +0 -102
  263. scitex/fts/_bundle/__init__.py +0 -38
  264. scitex/fts/_bundle/_utils/__init__.py +0 -55
  265. scitex/fts/_bundle/_utils/_const.py +0 -26
  266. scitex/fts/_bundle/_utils/_errors.py +0 -73
  267. scitex/fts/_bundle/_utils/_generate.py +0 -21
  268. scitex/fts/_bundle/_utils/_types.py +0 -76
  269. scitex/fts/_bundle/_zipbundle.py +0 -165
  270. scitex/fts/_fig/__init__.py +0 -22
  271. scitex/fts/_fig/_backend/_parser.py +0 -188
  272. scitex/fts/_fig/_editor/__init__.py +0 -14
  273. scitex/fts/_fig/_editor/_cui/__init__.py +0 -33
  274. scitex/fts/_fig/_editor/_cui/_backend_detector.py +0 -39
  275. scitex/fts/_fig/_editor/_cui/_bundle_resolver.py +0 -366
  276. scitex/fts/_fig/_editor/_cui/_editor_launcher.py +0 -175
  277. scitex/fts/_fig/_editor/_cui/_manual_handler.py +0 -52
  278. scitex/fts/_fig/_editor/_cui/_path_resolver.py +0 -66
  279. scitex/fts/_fig/_editor/_gui/__init__.py +0 -11
  280. scitex/fts/_fig/_editor/_gui/_flask_editor/__init__.py +0 -20
  281. scitex/fts/_fig/_editor/_gui/_flask_editor/_plotter.py +0 -664
  282. scitex/fts/_fig/_editor/_gui/_flask_editor/_utils.py +0 -79
  283. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/reset.css +0 -41
  284. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/typography.css +0 -16
  285. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/variables.css +0 -85
  286. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/buttons.css +0 -217
  287. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/context-menu.css +0 -93
  288. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/dropdown.css +0 -57
  289. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/forms.css +0 -112
  290. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/modal.css +0 -59
  291. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/sections.css +0 -212
  292. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/element-inspector.css +0 -190
  293. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/loading.css +0 -59
  294. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/overlay.css +0 -45
  295. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/panel-grid.css +0 -95
  296. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/selection.css +0 -101
  297. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/statistics.css +0 -138
  298. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/index.css +0 -31
  299. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/container.css +0 -7
  300. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/controls.css +0 -56
  301. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/preview.css +0 -78
  302. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/axis.js +0 -314
  303. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/basic.js +0 -107
  304. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/distribute.js +0 -54
  305. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/canvas.js +0 -172
  306. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/dragging.js +0 -258
  307. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/resize.js +0 -48
  308. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/selection.js +0 -71
  309. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/api.js +0 -288
  310. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/state.js +0 -143
  311. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/utils.js +0 -245
  312. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/dev/element-inspector.js +0 -992
  313. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/bbox.js +0 -339
  314. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/element-drag.js +0 -286
  315. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/overlay.js +0 -371
  316. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/preview.js +0 -293
  317. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/main.js +0 -426
  318. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/context-menu.js +0 -152
  319. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/keyboard.js +0 -265
  320. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/controls.js +0 -184
  321. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/download.js +0 -57
  322. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/help.js +0 -100
  323. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/theme.js +0 -34
  324. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/__init__.py +0 -124
  325. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_html.py +0 -851
  326. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_scripts.py +0 -4932
  327. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_styles.py +0 -1657
  328. scitex/fts/_fig/_editor/_gui/_flask_editor.py +0 -36
  329. scitex/fts/_fig/_models/_Annotations.py +0 -115
  330. scitex/fts/_fig/_models/_Axes.py +0 -152
  331. scitex/fts/_fig/_models/_Figure.py +0 -138
  332. scitex/fts/_fig/_models/_Plot.py +0 -123
  333. scitex/fts/_fig/_utils/_plot_layout.py +0 -397
  334. scitex/fts/_kinds/_figure/_composite.py +0 -345
  335. scitex/fts/_kinds/_plot/_backend/__init__.py +0 -53
  336. scitex/fts/_kinds/_plot/_backend/_export.py +0 -165
  337. scitex/fts/_kinds/_plot/_backend/_render.py +0 -538
  338. scitex/fts/_kinds/_plot/_dataclasses/_ChannelEncoding.py +0 -46
  339. scitex/fts/_kinds/_plot/_dataclasses/_Encoding.py +0 -82
  340. scitex/fts/_kinds/_plot/_dataclasses/_Theme.py +0 -441
  341. scitex/fts/_kinds/_plot/_dataclasses/_TraceEncoding.py +0 -52
  342. scitex/fts/_kinds/_plot/_dataclasses/__init__.py +0 -47
  343. scitex/fts/_kinds/_plot/_models/_Guides.py +0 -104
  344. scitex/fts/_kinds/_plot/_models/_Styles.py +0 -245
  345. scitex/fts/_kinds/_plot/_models/__init__.py +0 -80
  346. scitex/fts/_kinds/_plot/_models/_plot_types/__init__.py +0 -156
  347. scitex/fts/_kinds/_plot/_models/_plot_types/_bar.py +0 -43
  348. scitex/fts/_kinds/_plot/_models/_plot_types/_box.py +0 -38
  349. scitex/fts/_kinds/_plot/_models/_plot_types/_distribution.py +0 -36
  350. scitex/fts/_kinds/_plot/_models/_plot_types/_errorbar.py +0 -60
  351. scitex/fts/_kinds/_plot/_models/_plot_types/_histogram.py +0 -30
  352. scitex/fts/_kinds/_plot/_models/_plot_types/_image.py +0 -61
  353. scitex/fts/_kinds/_plot/_models/_plot_types/_line.py +0 -57
  354. scitex/fts/_kinds/_plot/_models/_plot_types/_scatter.py +0 -30
  355. scitex/fts/_kinds/_plot/_models/_plot_types/_seaborn.py +0 -121
  356. scitex/fts/_kinds/_plot/_models/_plot_types/_violin.py +0 -36
  357. scitex/fts/_kinds/_plot/_utils/__init__.py +0 -129
  358. scitex/fts/_kinds/_plot/_utils/_auto_layout.py +0 -127
  359. scitex/fts/_kinds/_plot/_utils/_calc_bounds.py +0 -111
  360. scitex/fts/_kinds/_plot/_utils/_const_sizes.py +0 -48
  361. scitex/fts/_kinds/_plot/_utils/_convert_coords.py +0 -77
  362. scitex/fts/_kinds/_plot/_utils/_get_template.py +0 -178
  363. scitex/fts/_kinds/_plot/_utils/_normalize.py +0 -73
  364. scitex/fts/_kinds/_plot/_utils/_validate.py +0 -197
  365. scitex/fts/_kinds/_table/_latex/_export.py +0 -279
  366. scitex/fts/_stats/__init__.py +0 -48
  367. scitex/fts/_stats/_dataclasses/_Stats.py +0 -423
  368. scitex/fts/_stats/_dataclasses/__init__.py +0 -48
  369. scitex/fts/_tables/__init__.py +0 -65
  370. scitex/fts/_tables/_latex/__init__.py +0 -93
  371. scitex/fts/_tables/_latex/_editor/__init__.py +0 -11
  372. scitex/fts/_tables/_latex/_editor/_app.py +0 -725
  373. scitex/fts/_tables/_latex/_figure_exporter.py +0 -153
  374. scitex/fts/_tables/_latex/_stats_formatter.py +0 -274
  375. scitex/fts/_tables/_latex/_table_exporter.py +0 -362
  376. scitex/fts/_tables/_latex/_utils.py +0 -369
  377. scitex/fts/_tables/_latex/_validator.py +0 -445
  378. scitex/io/_save_modules/_pltz_bundle.py +0 -356
  379. scitex-2.10.3.dist-info/METADATA +0 -952
  380. scitex-2.10.3.dist-info/entry_points.txt +0 -2
  381. /scitex/{fig → canvas}/README.md +0 -0
  382. /scitex/{fig → canvas}/backend/__init__.py +0 -0
  383. /scitex/{fig → canvas}/backend/_export.py +0 -0
  384. /scitex/{fig → canvas}/backend/_render.py +0 -0
  385. /scitex/{fig → canvas}/docs/CANVAS_ARCHITECTURE.md +0 -0
  386. /scitex/{fig → canvas}/editor/__init__.py +0 -0
  387. /scitex/{fig → canvas}/editor/_dearpygui_editor.py +0 -0
  388. /scitex/{fig → canvas}/editor/_flask_editor.py +0 -0
  389. /scitex/{fig → canvas}/editor/_mpl_editor.py +0 -0
  390. /scitex/{fig → canvas}/editor/_qt_editor.py +0 -0
  391. /scitex/{fig → canvas}/editor/_tkinter_editor.py +0 -0
  392. /scitex/{fig → canvas}/editor/edit/backend_detector.py +0 -0
  393. /scitex/{fig → canvas}/editor/edit/manual_handler.py +0 -0
  394. /scitex/{fig → canvas}/editor/edit/path_resolver.py +0 -0
  395. /scitex/{fig → canvas}/editor/flask_editor/__init__.py +0 -0
  396. /scitex/{fig → canvas}/editor/flask_editor/_plotter.py +0 -0
  397. /scitex/{fig → canvas}/editor/flask_editor/_utils.py +0 -0
  398. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/reset.css +0 -0
  399. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/typography.css +0 -0
  400. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/variables.css +0 -0
  401. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/buttons.css +0 -0
  402. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/context-menu.css +0 -0
  403. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/dropdown.css +0 -0
  404. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/forms.css +0 -0
  405. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/modal.css +0 -0
  406. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/sections.css +0 -0
  407. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/element-inspector.css +0 -0
  408. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/loading.css +0 -0
  409. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/overlay.css +0 -0
  410. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/selection.css +0 -0
  411. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/statistics.css +0 -0
  412. /scitex/{fig → canvas}/editor/flask_editor/static/css/index.css +0 -0
  413. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/container.css +0 -0
  414. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/controls.css +0 -0
  415. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/preview.css +0 -0
  416. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/axis.js +0 -0
  417. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/basic.js +0 -0
  418. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/distribute.js +0 -0
  419. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/canvas.js +0 -0
  420. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/dragging.js +0 -0
  421. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/resize.js +0 -0
  422. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/selection.js +0 -0
  423. /scitex/{fig → canvas}/editor/flask_editor/static/js/core/state.js +0 -0
  424. /scitex/{fig → canvas}/editor/flask_editor/static/js/core/utils.js +0 -0
  425. /scitex/{fig → canvas}/editor/flask_editor/static/js/dev/element-inspector.js +0 -0
  426. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/bbox.js +0 -0
  427. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/element-drag.js +0 -0
  428. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/overlay.js +0 -0
  429. /scitex/{fig → canvas}/editor/flask_editor/static/js/main.js +0 -0
  430. /scitex/{fig → canvas}/editor/flask_editor/static/js/shortcuts/context-menu.js +0 -0
  431. /scitex/{fig → canvas}/editor/flask_editor/static/js/shortcuts/keyboard.js +0 -0
  432. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/controls.js +0 -0
  433. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/download.js +0 -0
  434. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/help.js +0 -0
  435. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/theme.js +0 -0
  436. /scitex/{fig → canvas}/editor/flask_editor/templates/__init__.py +0 -0
  437. /scitex/{fig → canvas}/io/_directory.py +0 -0
  438. /scitex/{fig → canvas}/model/_plot_types.py +0 -0
  439. /scitex/{fig → canvas}/utils/_defaults.py +0 -0
  440. /scitex/{fig → canvas}/utils/_validate.py +0 -0
  441. /scitex/{fts/_bundle → io/bundle}/_conversion/__init__.py +0 -0
  442. /scitex/{fts/_bundle → io/bundle}/_conversion/_bundle2dict.py +0 -0
  443. /scitex/{fts/_bundle → io/bundle}/_conversion/_dict2bundle.py +0 -0
  444. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_Axes.py +0 -0
  445. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_BBox.py +0 -0
  446. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_ColumnDef.py +0 -0
  447. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataFormat.py +0 -0
  448. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataInfo.py +0 -0
  449. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataSource.py +0 -0
  450. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_SizeMM.py +0 -0
  451. /scitex/{fts/_bundle → io/bundle}/_extractors/__init__.py +0 -0
  452. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_bar.py +0 -0
  453. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_line.py +0 -0
  454. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_scatter.py +0 -0
  455. /scitex/{fts/_kinds → io/bundle/kinds}/__init__.py +0 -0
  456. /scitex/{fts/_kinds → io/bundle/kinds}/_figure/__init__.py +0 -0
  457. /scitex/{fts/_fig → io/bundle/kinds/_figure}/_composite.py +0 -0
  458. /scitex/{fts/_kinds → io/bundle/kinds}/_plot/__init__.py +0 -0
  459. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/__init__.py +0 -0
  460. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/_export.py +0 -0
  461. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/_render.py +0 -0
  462. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_ChannelEncoding.py +0 -0
  463. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_Encoding.py +0 -0
  464. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_Theme.py +0 -0
  465. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_TraceEncoding.py +0 -0
  466. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/__init__.py +0 -0
  467. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/__init__.py +0 -0
  468. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/__init__.py +0 -0
  469. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_bar.py +0 -0
  470. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_box.py +0 -0
  471. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_distribution.py +0 -0
  472. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_errorbar.py +0 -0
  473. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_histogram.py +0 -0
  474. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_image.py +0 -0
  475. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_line.py +0 -0
  476. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_scatter.py +0 -0
  477. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_seaborn.py +0 -0
  478. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_violin.py +0 -0
  479. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/__init__.py +0 -0
  480. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_auto_layout.py +0 -0
  481. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_calc_bounds.py +0 -0
  482. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_const_sizes.py +0 -0
  483. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_convert_coords.py +0 -0
  484. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_get_template.py +0 -0
  485. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_normalize.py +0 -0
  486. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_validate.py +0 -0
  487. /scitex/{fts/_kinds → io/bundle/kinds}/_shape/__init__.py +0 -0
  488. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/__init__.py +0 -0
  489. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/_dataclasses/_Stats.py +0 -0
  490. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/_dataclasses/__init__.py +0 -0
  491. /scitex/{fts/_kinds → io/bundle/kinds}/_table/__init__.py +0 -0
  492. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_editor/__init__.py +0 -0
  493. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_stats_formatter.py +0 -0
  494. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_utils.py +0 -0
  495. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_validator.py +0 -0
  496. /scitex/{fts/_kinds → io/bundle/kinds}/_text/__init__.py +0 -0
  497. /scitex/{fts/_schemas → io/bundle/schemas}/data_info.schema.json +0 -0
  498. /scitex/{fts/_schemas → io/bundle/schemas}/encoding.schema.json +0 -0
  499. /scitex/{fts/_schemas → io/bundle/schemas}/node.schema.json +0 -0
  500. /scitex/{fts/_schemas → io/bundle/schemas}/render_manifest.schema.json +0 -0
  501. /scitex/{fts/_schemas → io/bundle/schemas}/stats.schema.json +0 -0
  502. /scitex/{fts/_schemas → io/bundle/schemas}/theme.schema.json +0 -0
  503. {scitex-2.10.3.dist-info → scitex-2.13.0.dist-info}/WHEEL +0 -0
  504. {scitex-2.10.3.dist-info → scitex-2.13.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,441 +0,0 @@
1
- #!/usr/bin/env python3
2
- # Timestamp: 2025-12-21
3
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/fts/_fig/_dataclasses/_Theme.py
4
-
5
- """Theme - Visual aesthetics for FTS bundles."""
6
-
7
- import json
8
- from dataclasses import dataclass, field
9
- from typing import Any, Dict, List, Optional
10
-
11
- THEME_VERSION = "1.0.0"
12
-
13
-
14
- @dataclass
15
- class Colors:
16
- """Color palette configuration."""
17
-
18
- palette: List[str] = field(
19
- default_factory=lambda: ["#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd"]
20
- )
21
- primary: Optional[str] = None
22
- secondary: Optional[str] = None
23
- background: str = "#ffffff"
24
- text: str = "#000000"
25
- axis: str = "#333333"
26
- grid: str = "#e0e0e0"
27
-
28
- def to_dict(self) -> Dict[str, Any]:
29
- result = {
30
- "palette": self.palette,
31
- "background": self.background,
32
- "text": self.text,
33
- "axis": self.axis,
34
- "grid": self.grid,
35
- }
36
- if self.primary:
37
- result["primary"] = self.primary
38
- if self.secondary:
39
- result["secondary"] = self.secondary
40
- return result
41
-
42
- @classmethod
43
- def from_dict(cls, data: Any) -> "Colors":
44
- # Return if already a Colors instance
45
- if isinstance(data, cls):
46
- return data
47
- if not isinstance(data, dict):
48
- return cls()
49
- return cls(
50
- palette=data.get("palette", ["#1f77b4", "#ff7f0e", "#2ca02c"]),
51
- primary=data.get("primary"),
52
- secondary=data.get("secondary"),
53
- background=data.get("background", "#ffffff"),
54
- text=data.get("text", "#000000"),
55
- axis=data.get("axis", "#333333"),
56
- grid=data.get("grid", "#e0e0e0"),
57
- )
58
-
59
-
60
- @dataclass
61
- class Typography:
62
- """Typography configuration."""
63
-
64
- family: str = "sans-serif"
65
- size_pt: float = 8.0
66
- title_size_pt: float = 10.0
67
- label_size_pt: float = 8.0
68
- tick_size_pt: float = 7.0
69
-
70
- def to_dict(self) -> Dict[str, Any]:
71
- return {
72
- "family": self.family,
73
- "size_pt": self.size_pt,
74
- "title_size_pt": self.title_size_pt,
75
- "label_size_pt": self.label_size_pt,
76
- "tick_size_pt": self.tick_size_pt,
77
- }
78
-
79
- @classmethod
80
- def from_dict(cls, data: Any) -> "Typography":
81
- # Return if already a Typography instance
82
- if isinstance(data, cls):
83
- return data
84
- if not isinstance(data, dict):
85
- return cls()
86
- return cls(
87
- family=data.get("family", "sans-serif"),
88
- size_pt=data.get("size_pt", 8.0),
89
- title_size_pt=data.get("title_size_pt", data.get("title_size", 10.0)),
90
- label_size_pt=data.get("label_size_pt", data.get("label_size", 8.0)),
91
- tick_size_pt=data.get("tick_size_pt", data.get("tick_size", 7.0)),
92
- )
93
-
94
-
95
- @dataclass
96
- class Lines:
97
- """Line style configuration."""
98
-
99
- width_pt: float = 1.0
100
- style: str = "solid" # solid, dashed, dotted, dashdot
101
-
102
- def to_dict(self) -> Dict[str, Any]:
103
- return {"width_pt": self.width_pt, "style": self.style}
104
-
105
- @classmethod
106
- def from_dict(cls, data: Any) -> "Lines":
107
- if isinstance(data, cls):
108
- return data
109
- if not isinstance(data, dict):
110
- return cls()
111
- return cls(
112
- width_pt=data.get("width_pt", 1.0),
113
- style=data.get("style", "solid"),
114
- )
115
-
116
-
117
- @dataclass
118
- class Markers:
119
- """Marker style configuration."""
120
-
121
- size_pt: float = 4.0
122
- symbol: str = "circle" # circle, square, triangle, cross, diamond
123
-
124
- def to_dict(self) -> Dict[str, Any]:
125
- return {"size_pt": self.size_pt, "symbol": self.symbol}
126
-
127
- @classmethod
128
- def from_dict(cls, data: Any) -> "Markers":
129
- if isinstance(data, cls):
130
- return data
131
- if not isinstance(data, dict):
132
- return cls()
133
- return cls(
134
- size_pt=data.get("size_pt", 4.0),
135
- symbol=data.get("symbol", "circle"),
136
- )
137
-
138
-
139
- @dataclass
140
- class Grid:
141
- """Grid line configuration."""
142
-
143
- show: bool = True
144
- major_width_pt: float = 0.5
145
- minor_width_pt: float = 0.25
146
- major_alpha: float = 0.3
147
- minor_alpha: float = 0.1
148
-
149
- def to_dict(self) -> Dict[str, Any]:
150
- return {
151
- "show": self.show,
152
- "major_width_pt": self.major_width_pt,
153
- "minor_width_pt": self.minor_width_pt,
154
- "major_alpha": self.major_alpha,
155
- "minor_alpha": self.minor_alpha,
156
- }
157
-
158
- @classmethod
159
- def from_dict(cls, data: Any) -> "Grid":
160
- if isinstance(data, cls):
161
- return data
162
- if isinstance(data, bool):
163
- return cls(show=data)
164
- if not isinstance(data, dict):
165
- return cls()
166
- return cls(
167
- show=data.get("show", True),
168
- major_width_pt=data.get("major_width_pt", 0.5),
169
- minor_width_pt=data.get("minor_width_pt", 0.25),
170
- major_alpha=data.get("major_alpha", 0.3),
171
- minor_alpha=data.get("minor_alpha", 0.1),
172
- )
173
-
174
-
175
- @dataclass
176
- class TraceTheme:
177
- """Per-trace theme overrides."""
178
-
179
- trace_id: str
180
- color: Optional[str] = None
181
- line_width_pt: Optional[float] = None
182
- marker_size_pt: Optional[float] = None
183
- alpha: Optional[float] = None
184
-
185
- def to_dict(self) -> Dict[str, Any]:
186
- result = {"trace_id": self.trace_id}
187
- if self.color:
188
- result["color"] = self.color
189
- if self.line_width_pt is not None:
190
- result["line_width_pt"] = self.line_width_pt
191
- if self.marker_size_pt is not None:
192
- result["marker_size_pt"] = self.marker_size_pt
193
- if self.alpha is not None:
194
- result["alpha"] = self.alpha
195
- return result
196
-
197
- @classmethod
198
- def from_dict(cls, data: Any) -> "TraceTheme":
199
- if isinstance(data, cls):
200
- return data
201
- if not isinstance(data, dict):
202
- return cls(trace_id="trace_0")
203
- return cls(
204
- trace_id=data.get("trace_id", "trace_0"),
205
- color=data.get("color"),
206
- line_width_pt=data.get("line_width_pt"),
207
- marker_size_pt=data.get("marker_size_pt"),
208
- alpha=data.get("alpha"),
209
- )
210
-
211
-
212
- @dataclass
213
- class FigureTitle:
214
- """Figure title configuration for publications."""
215
-
216
- text: str = ""
217
- prefix: str = "Figure"
218
- number: Optional[int] = None
219
- fontsize: Optional[float] = None
220
- fontweight: str = "bold"
221
-
222
- def to_dict(self) -> Dict[str, Any]:
223
- result = {"text": self.text, "prefix": self.prefix, "fontweight": self.fontweight}
224
- if self.number is not None:
225
- result["number"] = self.number
226
- if self.fontsize is not None:
227
- result["fontsize"] = self.fontsize
228
- return result
229
-
230
- @classmethod
231
- def from_dict(cls, data: Any) -> "FigureTitle":
232
- if isinstance(data, cls):
233
- return data
234
- if not isinstance(data, dict):
235
- return cls()
236
- return cls(
237
- text=data.get("text", ""),
238
- prefix=data.get("prefix", "Figure"),
239
- number=data.get("number"),
240
- fontsize=data.get("fontsize"),
241
- fontweight=data.get("fontweight", "bold"),
242
- )
243
-
244
-
245
- @dataclass
246
- class PanelDescription:
247
- """Single panel description for captions."""
248
-
249
- label: str
250
- description: str
251
-
252
- def to_dict(self) -> Dict[str, Any]:
253
- return {"label": self.label, "description": self.description}
254
-
255
- @classmethod
256
- def from_dict(cls, data: Any) -> "PanelDescription":
257
- if isinstance(data, cls):
258
- return data
259
- if not isinstance(data, dict):
260
- return cls(label="", description="")
261
- return cls(
262
- label=data.get("label", ""),
263
- description=data.get("description", ""),
264
- )
265
-
266
-
267
- @dataclass
268
- class Caption:
269
- """Figure caption for publications."""
270
-
271
- text: str = ""
272
- panels: List[PanelDescription] = field(default_factory=list)
273
-
274
- def to_dict(self) -> Dict[str, Any]:
275
- result = {"text": self.text}
276
- if self.panels:
277
- result["panels"] = [p.to_dict() for p in self.panels]
278
- return result
279
-
280
- @classmethod
281
- def from_dict(cls, data: Any) -> "Caption":
282
- if isinstance(data, cls):
283
- return data
284
- if not isinstance(data, dict):
285
- return cls()
286
- panels = [PanelDescription.from_dict(p) for p in data.get("panels", [])]
287
- return cls(text=data.get("text", ""), panels=panels)
288
-
289
-
290
- @dataclass
291
- class PanelLabels:
292
- """Panel label styling (A, B, C, etc.)."""
293
-
294
- style: str = "uppercase" # uppercase, lowercase, numeric
295
- fontsize: float = 12.0
296
- fontweight: str = "bold"
297
- position: str = "top-left" # top-left, top-right, bottom-left, bottom-right
298
- offset_x: float = 0.02
299
- offset_y: float = 0.98
300
-
301
- def to_dict(self) -> Dict[str, Any]:
302
- return {
303
- "style": self.style,
304
- "fontsize": self.fontsize,
305
- "fontweight": self.fontweight,
306
- "position": self.position,
307
- "offset_x": self.offset_x,
308
- "offset_y": self.offset_y,
309
- }
310
-
311
- @classmethod
312
- def from_dict(cls, data: Any) -> "PanelLabels":
313
- if isinstance(data, cls):
314
- return data
315
- if not isinstance(data, dict):
316
- return cls()
317
- return cls(
318
- style=data.get("style", "uppercase"),
319
- fontsize=data.get("fontsize", 12.0),
320
- fontweight=data.get("fontweight", "bold"),
321
- position=data.get("position", "top-left"),
322
- offset_x=data.get("offset_x", 0.02),
323
- offset_y=data.get("offset_y", 0.98),
324
- )
325
-
326
-
327
- @dataclass
328
- class Theme:
329
- """Complete theme specification for an FTS bundle.
330
-
331
- Stored in canonical/theme.json.
332
- """
333
-
334
- # Core mode
335
- mode: str = "light" # "light" | "dark"
336
-
337
- # Styling components
338
- colors: Colors = field(default_factory=Colors)
339
- typography: Typography = field(default_factory=Typography)
340
- lines: Lines = field(default_factory=Lines)
341
- markers: Markers = field(default_factory=Markers)
342
- grid: Grid = field(default_factory=Grid)
343
-
344
- # Per-trace overrides
345
- traces: List[TraceTheme] = field(default_factory=list)
346
-
347
- # Publication metadata
348
- preset: Optional[str] = None # nature, science, cell, ieee, acs, minimal, presentation
349
- figure_title: Optional[FigureTitle] = None
350
- caption: Optional[Caption] = None
351
- panel_labels: Optional[PanelLabels] = None
352
-
353
- # Alias for typography (for convenience)
354
- fonts: Optional[Typography] = None
355
-
356
- # Schema metadata
357
- schema_name: str = "fts.theme"
358
- schema_version: str = THEME_VERSION
359
-
360
- def to_dict(self) -> Dict[str, Any]:
361
- result = {
362
- "mode": self.mode,
363
- "colors": self.colors.to_dict(),
364
- "typography": self.typography.to_dict(),
365
- "lines": self.lines.to_dict(),
366
- "markers": self.markers.to_dict(),
367
- "grid": self.grid.to_dict(),
368
- }
369
- if self.traces:
370
- result["traces"] = [t.to_dict() for t in self.traces]
371
- if self.preset:
372
- result["preset"] = self.preset
373
- if self.figure_title:
374
- result["figure_title"] = self.figure_title.to_dict()
375
- if self.caption:
376
- result["caption"] = self.caption.to_dict()
377
- if self.panel_labels:
378
- result["panel_labels"] = self.panel_labels.to_dict()
379
- return result
380
-
381
- def to_json(self, indent: int = 2) -> str:
382
- return json.dumps(self.to_dict(), indent=indent)
383
-
384
- @classmethod
385
- def from_dict(cls, data: Dict[str, Any]) -> "Theme":
386
- # Handle fonts as alias for typography
387
- typography_data = data.get("typography", {})
388
- fonts_data = data.get("fonts")
389
- if fonts_data and not typography_data:
390
- typography_data = fonts_data
391
-
392
- # Parse figure_title
393
- figure_title = None
394
- if "figure_title" in data and data["figure_title"]:
395
- figure_title = FigureTitle.from_dict(data["figure_title"])
396
-
397
- # Parse caption
398
- caption = None
399
- if "caption" in data and data["caption"]:
400
- caption = Caption.from_dict(data["caption"])
401
-
402
- # Parse panel_labels
403
- panel_labels = None
404
- if "panel_labels" in data and data["panel_labels"]:
405
- panel_labels = PanelLabels.from_dict(data["panel_labels"])
406
-
407
- return cls(
408
- mode=data.get("mode", "light"),
409
- colors=Colors.from_dict(data.get("colors", {})),
410
- typography=Typography.from_dict(typography_data),
411
- lines=Lines.from_dict(data.get("lines", {})),
412
- markers=Markers.from_dict(data.get("markers", {})),
413
- grid=Grid.from_dict(data.get("grid", {})),
414
- traces=[TraceTheme.from_dict(t) for t in data.get("traces", [])],
415
- preset=data.get("preset"),
416
- figure_title=figure_title,
417
- caption=caption,
418
- panel_labels=panel_labels,
419
- )
420
-
421
- @classmethod
422
- def from_json(cls, json_str: str) -> "Theme":
423
- return cls.from_dict(json.loads(json_str))
424
-
425
-
426
- __all__ = [
427
- "THEME_VERSION",
428
- "Colors",
429
- "Typography",
430
- "Lines",
431
- "Markers",
432
- "Grid",
433
- "TraceTheme",
434
- "FigureTitle",
435
- "PanelDescription",
436
- "Caption",
437
- "PanelLabels",
438
- "Theme",
439
- ]
440
-
441
- # EOF
@@ -1,52 +0,0 @@
1
- #!/usr/bin/env python3
2
- # Timestamp: 2025-12-20
3
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/fsb/_dataclasses/TraceEncoding.py
4
-
5
- """TraceEncoding - Encoding for a single trace/data series."""
6
-
7
- from dataclasses import dataclass
8
- from typing import Any, Dict, Optional
9
-
10
- from ._ChannelEncoding import ChannelEncoding
11
-
12
-
13
- @dataclass
14
- class TraceEncoding:
15
- """Encoding specification for a single trace/data series."""
16
-
17
- trace_id: str
18
- data_ref: Optional[str] = None # Path to data file within bundle
19
- x: Optional[ChannelEncoding] = None
20
- y: Optional[ChannelEncoding] = None
21
- color: Optional[ChannelEncoding] = None
22
- size: Optional[ChannelEncoding] = None
23
- group: Optional[ChannelEncoding] = None
24
- label: Optional[ChannelEncoding] = None
25
-
26
- def to_dict(self) -> Dict[str, Any]:
27
- result = {"trace_id": self.trace_id}
28
- if self.data_ref:
29
- result["data_ref"] = self.data_ref
30
- for channel in ["x", "y", "color", "size", "group", "label"]:
31
- enc = getattr(self, channel)
32
- if enc:
33
- result[channel] = enc.to_dict()
34
- return result
35
-
36
- @classmethod
37
- def from_dict(cls, data: Dict[str, Any]) -> "TraceEncoding":
38
- return cls(
39
- trace_id=data.get("trace_id", "trace_0"),
40
- data_ref=data.get("data_ref"),
41
- x=ChannelEncoding.from_dict(data["x"]) if "x" in data else None,
42
- y=ChannelEncoding.from_dict(data["y"]) if "y" in data else None,
43
- color=ChannelEncoding.from_dict(data["color"]) if "color" in data else None,
44
- size=ChannelEncoding.from_dict(data["size"]) if "size" in data else None,
45
- group=ChannelEncoding.from_dict(data["group"]) if "group" in data else None,
46
- label=ChannelEncoding.from_dict(data["label"]) if "label" in data else None,
47
- )
48
-
49
-
50
- __all__ = ["TraceEncoding"]
51
-
52
- # EOF
@@ -1,47 +0,0 @@
1
- #!/usr/bin/env python3
2
- # Timestamp: 2025-12-21
3
- # File: /home/ywatanabe/proj/scitex-code/src/scitex/fts/_fig/_dataclasses/__init__.py
4
-
5
- """Figure-specific dataclasses for FTS."""
6
-
7
- from ._ChannelEncoding import ChannelEncoding
8
- from ._Encoding import ENCODING_VERSION, AxesConfig, Encoding
9
- from ._Theme import (
10
- THEME_VERSION,
11
- Caption,
12
- Colors,
13
- FigureTitle,
14
- Grid,
15
- Lines,
16
- Markers,
17
- PanelDescription,
18
- PanelLabels,
19
- Theme,
20
- TraceTheme,
21
- Typography,
22
- )
23
- from ._TraceEncoding import TraceEncoding
24
-
25
- __all__ = [
26
- # Encoding
27
- "ENCODING_VERSION",
28
- "AxesConfig",
29
- "ChannelEncoding",
30
- "TraceEncoding",
31
- "Encoding",
32
- # Theme
33
- "THEME_VERSION",
34
- "Colors",
35
- "Typography",
36
- "Lines",
37
- "Markers",
38
- "Grid",
39
- "TraceTheme",
40
- "FigureTitle",
41
- "PanelDescription",
42
- "Caption",
43
- "PanelLabels",
44
- "Theme",
45
- ]
46
-
47
- # EOF
@@ -1,104 +0,0 @@
1
- #!/usr/bin/env python3
2
- # File: ./src/scitex/vis/model/guides.py
3
- """Guide elements (lines, spans) JSON model for scitex.fig."""
4
-
5
- from dataclasses import asdict, dataclass, field
6
- from typing import Any, Dict, Optional
7
-
8
- from ._Styles import GuideStyle
9
-
10
-
11
- @dataclass
12
- class GuideModel:
13
- """
14
- Guide model for reference lines, spans, and regions.
15
-
16
- Separates structure from style properties for easier:
17
- - UI property panel generation
18
- - Style copy/paste
19
- - Batch style application
20
-
21
- Supports:
22
- - axhline, axvline: Horizontal/vertical reference lines
23
- - axhspan, axvspan: Horizontal/vertical shaded regions
24
- """
25
-
26
- # Guide type
27
- guide_type: str # "axhline", "axvline", "axhspan", "axvspan"
28
-
29
- # Position/range (structure, not style)
30
- y: Optional[float] = None # For axhline
31
- x: Optional[float] = None # For axvline
32
- ymin: Optional[float] = None # For axhspan
33
- ymax: Optional[float] = None # For axhspan
34
- xmin: Optional[float] = None # For axvspan
35
- xmax: Optional[float] = None # For axvspan
36
-
37
- # Human-readable identifiers
38
- label: Optional[str] = None
39
- guide_id: Optional[str] = None
40
-
41
- # Style properties (separated for clean UI/copy/paste)
42
- style: GuideStyle = field(default_factory=GuideStyle)
43
-
44
- def to_dict(self) -> Dict[str, Any]:
45
- """Convert to dictionary for JSON serialization."""
46
- d = asdict(self)
47
- d["style"] = self.style.to_dict()
48
- return d
49
-
50
- @classmethod
51
- def from_dict(cls, data: Dict[str, Any]) -> "GuideModel":
52
- """Create GuideModel from dictionary."""
53
- # Handle old format (backward compatibility)
54
- if "style" not in data:
55
- # Extract style properties from flat structure
56
- style_fields = GuideStyle.__annotations__.keys()
57
- style_data = {k: v for k, v in data.items() if k in style_fields}
58
- data = {k: v for k, v in data.items() if k not in style_fields}
59
- data["style"] = style_data
60
-
61
- # Extract and parse style
62
- style_data = data.pop("style", {})
63
- obj = cls(**{k: v for k, v in data.items() if k in cls.__annotations__})
64
- obj.style = GuideStyle.from_dict(style_data)
65
- return obj
66
-
67
- def validate(self) -> bool:
68
- """
69
- Validate the guide model.
70
-
71
- Returns
72
- -------
73
- bool
74
- True if valid, raises ValueError otherwise
75
- """
76
- valid_guide_types = ["axhline", "axvline", "axhspan", "axvspan"]
77
-
78
- if self.guide_type not in valid_guide_types:
79
- raise ValueError(
80
- f"Invalid guide_type: {self.guide_type}. "
81
- f"Must be one of {valid_guide_types}"
82
- )
83
-
84
- # Type-specific validation
85
- if self.guide_type == "axhline":
86
- if self.y is None:
87
- raise ValueError("axhline requires 'y' parameter")
88
-
89
- elif self.guide_type == "axvline":
90
- if self.x is None:
91
- raise ValueError("axvline requires 'x' parameter")
92
-
93
- elif self.guide_type == "axhspan":
94
- if self.ymin is None or self.ymax is None:
95
- raise ValueError("axhspan requires 'ymin' and 'ymax' parameters")
96
-
97
- elif self.guide_type == "axvspan":
98
- if self.xmin is None or self.xmax is None:
99
- raise ValueError("axvspan requires 'xmin' and 'xmax' parameters")
100
-
101
- return True
102
-
103
-
104
- # EOF