scitex 2.10.3__py3-none-any.whl → 2.11.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 (363) hide show
  1. scitex/__init__.py +1 -4
  2. scitex/__version__.py +1 -1
  3. scitex/_install_guide.py +14 -2
  4. scitex/bridge/_figrecipe.py +1 -1
  5. scitex/bridge/_helpers.py +1 -1
  6. scitex/bridge/_plt_vis.py +1 -1
  7. scitex/bridge/_stats_plt.py +1 -1
  8. scitex/bridge/_stats_vis.py +2 -2
  9. scitex/{fig → canvas}/__init__.py +84 -96
  10. scitex/{fig → canvas}/backend/_parser.py +1 -1
  11. scitex/{fig → canvas}/canvas.py +13 -14
  12. scitex/{fts/_fig/_editor → canvas/editor}/_defaults.py +2 -2
  13. scitex/{fig → canvas}/editor/edit/__init__.py +11 -14
  14. scitex/{fig → canvas}/editor/edit/bundle_resolver.py +56 -48
  15. scitex/{fig → canvas}/editor/edit/editor_launcher.py +79 -26
  16. scitex/{fts/_fig/_editor/_cui/_panel_loader.py → canvas/editor/edit/panel_loader.py} +8 -8
  17. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_bbox.py +2 -1
  18. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_core.py +84 -84
  19. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_renderer.py +7 -6
  20. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/static/css/features/canvas.css +2 -2
  21. scitex/{fig → canvas}/editor/flask_editor/static/css/features/panel-grid.css +1 -1
  22. scitex/{fig → canvas}/editor/flask_editor/static/js/core/api.js +3 -4
  23. scitex/{fig → canvas}/editor/flask_editor/static/js/editor/preview.js +5 -5
  24. scitex/{fig → canvas}/editor/flask_editor/templates/_html.py +3 -3
  25. scitex/{fig → canvas}/editor/flask_editor/templates/_scripts.py +10 -10
  26. scitex/{fig → canvas}/editor/flask_editor/templates/_styles.py +3 -3
  27. scitex/{fig → canvas}/io/__init__.py +32 -38
  28. scitex/{fig → canvas}/io/_bundle.py +217 -154
  29. scitex/{fig → canvas}/io/_canvas.py +1 -1
  30. scitex/{fig → canvas}/io/_data.py +1 -1
  31. scitex/{fig → canvas}/io/_export.py +1 -1
  32. scitex/{fig → canvas}/io/_load.py +1 -1
  33. scitex/{fig → canvas}/io/_panel.py +1 -1
  34. scitex/{fig → canvas}/io/_save.py +1 -1
  35. scitex/{fig → canvas}/model/__init__.py +1 -1
  36. scitex/{fig → canvas}/model/_annotations.py +1 -1
  37. scitex/{fig → canvas}/model/_axes.py +1 -1
  38. scitex/{fig → canvas}/model/_figure.py +1 -1
  39. scitex/{fig → canvas}/model/_guides.py +1 -1
  40. scitex/{fig → canvas}/model/_plot.py +1 -1
  41. scitex/{fig → canvas}/model/_styles.py +1 -1
  42. scitex/{fig → canvas}/utils/__init__.py +1 -1
  43. scitex/cli/convert.py +10 -6
  44. scitex/diagram/README.md +7 -7
  45. scitex/io/__init__.py +7 -19
  46. scitex/io/_load.py +15 -19
  47. scitex/io/_load_modules/_canvas.py +2 -2
  48. scitex/io/_load_modules/_con.py +5 -5
  49. scitex/io/_load_modules/_eeg.py +16 -12
  50. scitex/io/_save.py +11 -16
  51. scitex/io/_save_modules/__init__.py +6 -10
  52. scitex/io/_save_modules/_canvas.py +3 -3
  53. scitex/io/_save_modules/_plot_bundle.py +112 -0
  54. scitex/io/_save_modules/{_pltz_stx.py → _plot_scitex.py} +7 -7
  55. scitex/io/_save_modules/_stx_bundle.py +16 -16
  56. scitex/io/bundle/README.md +89 -80
  57. scitex/{fts/_bundle/_FTS.py → io/bundle/_Bundle.py} +197 -95
  58. scitex/io/bundle/__init__.py +67 -35
  59. scitex/{fts/_bundle → io/bundle}/_children.py +32 -40
  60. scitex/io/bundle/_core.py +184 -97
  61. scitex/{fts/_bundle/_dataclasses/_Node.py → io/bundle/_dataclasses/_Spec.py} +29 -23
  62. scitex/{fts/_bundle/_dataclasses/_NodeRefs.py → io/bundle/_dataclasses/_SpecRefs.py} +6 -6
  63. scitex/{fts/_bundle → io/bundle}/_dataclasses/__init__.py +4 -4
  64. scitex/{fts/_bundle → io/bundle}/_loader.py +19 -19
  65. scitex/io/bundle/_manifest.py +99 -0
  66. scitex/{fts/_bundle → io/bundle}/_mpl_helpers.py +119 -28
  67. scitex/io/bundle/_nested.py +113 -100
  68. scitex/{fts/_bundle → io/bundle}/_saver.py +13 -14
  69. scitex/{fts/_bundle → io/bundle}/_storage.py +3 -3
  70. scitex/io/bundle/_types.py +41 -16
  71. scitex/{fts/_bundle → io/bundle}/_validation.py +20 -18
  72. scitex/io/bundle/_zip.py +21 -31
  73. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_backend/_parser.py +1 -1
  74. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Annotations.py +1 -1
  75. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Axes.py +1 -1
  76. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Figure.py +1 -1
  77. scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_Guides.py +1 -1
  78. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Plot.py +1 -1
  79. scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_Styles.py +1 -1
  80. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_utils/_plot_layout.py +1 -1
  81. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/__init__.py +1 -1
  82. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_editor/_app.py +1 -1
  83. scitex/{fts/_tables → io/bundle/kinds/_table}/_latex/_export.py +1 -1
  84. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_figure_exporter.py +1 -1
  85. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_table_exporter.py +1 -1
  86. scitex/io/bundle/schemas/__init__.py +30 -0
  87. scitex/parallel/_run.py +5 -4
  88. scitex/path/_find.py +60 -83
  89. scitex/path/_get_module_path.py +23 -21
  90. scitex/path/_get_spath.py +6 -27
  91. scitex/path/_getsize.py +23 -9
  92. scitex/path/_increment_version.py +31 -38
  93. scitex/path/_mk_spath.py +26 -29
  94. scitex/path/_path.py +5 -12
  95. scitex/path/_split.py +27 -15
  96. scitex/path/_this_path.py +23 -9
  97. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/__init__.py +2 -1
  98. scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +2 -2
  99. scitex/plt/gallery/_generate.py +76 -50
  100. scitex/plt/io/__init__.py +17 -19
  101. scitex/plt/io/_bundle.py +99 -52
  102. scitex/plt/io/_layered_bundle.py +303 -168
  103. scitex/plt/utils/_csv_column_naming.py +250 -118
  104. scitex/schema/__init__.py +69 -73
  105. scitex/schema/_canvas.py +1 -1
  106. scitex/schema/_stats.py +2 -2
  107. scitex/stats/__init__.py +30 -33
  108. scitex/stats/_schema.py +1 -1
  109. scitex/stats/io/__init__.py +10 -11
  110. scitex/stats/io/_bundle.py +16 -16
  111. {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/METADATA +190 -73
  112. {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/RECORD +237 -360
  113. scitex/fig/editor/_defaults.py +0 -300
  114. scitex/fig/editor/edit/panel_loader.py +0 -232
  115. scitex/fig/editor/flask_editor/_bbox.py +0 -1299
  116. scitex/fig/editor/flask_editor/_core.py +0 -1429
  117. scitex/fig/editor/flask_editor/_renderer.py +0 -813
  118. scitex/fig/editor/flask_editor/static/css/features/canvas.css +0 -176
  119. scitex/fts/README.md +0 -262
  120. scitex/fts/TODO.md +0 -66
  121. scitex/fts/__init__.py +0 -90
  122. scitex/fts/_bundle/README_IN_BUNDLE.md +0 -102
  123. scitex/fts/_bundle/__init__.py +0 -38
  124. scitex/fts/_bundle/_utils/__init__.py +0 -55
  125. scitex/fts/_bundle/_utils/_const.py +0 -26
  126. scitex/fts/_bundle/_utils/_errors.py +0 -73
  127. scitex/fts/_bundle/_utils/_generate.py +0 -21
  128. scitex/fts/_bundle/_utils/_types.py +0 -76
  129. scitex/fts/_bundle/_zipbundle.py +0 -165
  130. scitex/fts/_fig/__init__.py +0 -22
  131. scitex/fts/_fig/_backend/_parser.py +0 -188
  132. scitex/fts/_fig/_editor/__init__.py +0 -14
  133. scitex/fts/_fig/_editor/_cui/__init__.py +0 -33
  134. scitex/fts/_fig/_editor/_cui/_backend_detector.py +0 -39
  135. scitex/fts/_fig/_editor/_cui/_bundle_resolver.py +0 -366
  136. scitex/fts/_fig/_editor/_cui/_editor_launcher.py +0 -175
  137. scitex/fts/_fig/_editor/_cui/_manual_handler.py +0 -52
  138. scitex/fts/_fig/_editor/_cui/_path_resolver.py +0 -66
  139. scitex/fts/_fig/_editor/_gui/__init__.py +0 -11
  140. scitex/fts/_fig/_editor/_gui/_flask_editor/__init__.py +0 -20
  141. scitex/fts/_fig/_editor/_gui/_flask_editor/_plotter.py +0 -664
  142. scitex/fts/_fig/_editor/_gui/_flask_editor/_utils.py +0 -79
  143. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/reset.css +0 -41
  144. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/typography.css +0 -16
  145. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/variables.css +0 -85
  146. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/buttons.css +0 -217
  147. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/context-menu.css +0 -93
  148. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/dropdown.css +0 -57
  149. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/forms.css +0 -112
  150. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/modal.css +0 -59
  151. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/sections.css +0 -212
  152. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/element-inspector.css +0 -190
  153. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/loading.css +0 -59
  154. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/overlay.css +0 -45
  155. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/panel-grid.css +0 -95
  156. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/selection.css +0 -101
  157. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/statistics.css +0 -138
  158. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/index.css +0 -31
  159. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/container.css +0 -7
  160. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/controls.css +0 -56
  161. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/preview.css +0 -78
  162. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/axis.js +0 -314
  163. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/basic.js +0 -107
  164. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/distribute.js +0 -54
  165. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/canvas.js +0 -172
  166. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/dragging.js +0 -258
  167. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/resize.js +0 -48
  168. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/selection.js +0 -71
  169. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/api.js +0 -288
  170. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/state.js +0 -143
  171. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/utils.js +0 -245
  172. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/dev/element-inspector.js +0 -992
  173. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/bbox.js +0 -339
  174. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/element-drag.js +0 -286
  175. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/overlay.js +0 -371
  176. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/preview.js +0 -293
  177. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/main.js +0 -426
  178. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/context-menu.js +0 -152
  179. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/keyboard.js +0 -265
  180. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/controls.js +0 -184
  181. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/download.js +0 -57
  182. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/help.js +0 -100
  183. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/theme.js +0 -34
  184. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/__init__.py +0 -124
  185. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_html.py +0 -851
  186. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_scripts.py +0 -4932
  187. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_styles.py +0 -1657
  188. scitex/fts/_fig/_editor/_gui/_flask_editor.py +0 -36
  189. scitex/fts/_fig/_models/_Annotations.py +0 -115
  190. scitex/fts/_fig/_models/_Axes.py +0 -152
  191. scitex/fts/_fig/_models/_Figure.py +0 -138
  192. scitex/fts/_fig/_models/_Plot.py +0 -123
  193. scitex/fts/_fig/_utils/_plot_layout.py +0 -397
  194. scitex/fts/_kinds/_figure/_composite.py +0 -345
  195. scitex/fts/_kinds/_plot/_backend/__init__.py +0 -53
  196. scitex/fts/_kinds/_plot/_backend/_export.py +0 -165
  197. scitex/fts/_kinds/_plot/_backend/_render.py +0 -538
  198. scitex/fts/_kinds/_plot/_dataclasses/_ChannelEncoding.py +0 -46
  199. scitex/fts/_kinds/_plot/_dataclasses/_Encoding.py +0 -82
  200. scitex/fts/_kinds/_plot/_dataclasses/_Theme.py +0 -441
  201. scitex/fts/_kinds/_plot/_dataclasses/_TraceEncoding.py +0 -52
  202. scitex/fts/_kinds/_plot/_dataclasses/__init__.py +0 -47
  203. scitex/fts/_kinds/_plot/_models/_Guides.py +0 -104
  204. scitex/fts/_kinds/_plot/_models/_Styles.py +0 -245
  205. scitex/fts/_kinds/_plot/_models/__init__.py +0 -80
  206. scitex/fts/_kinds/_plot/_models/_plot_types/__init__.py +0 -156
  207. scitex/fts/_kinds/_plot/_models/_plot_types/_bar.py +0 -43
  208. scitex/fts/_kinds/_plot/_models/_plot_types/_box.py +0 -38
  209. scitex/fts/_kinds/_plot/_models/_plot_types/_distribution.py +0 -36
  210. scitex/fts/_kinds/_plot/_models/_plot_types/_errorbar.py +0 -60
  211. scitex/fts/_kinds/_plot/_models/_plot_types/_histogram.py +0 -30
  212. scitex/fts/_kinds/_plot/_models/_plot_types/_image.py +0 -61
  213. scitex/fts/_kinds/_plot/_models/_plot_types/_line.py +0 -57
  214. scitex/fts/_kinds/_plot/_models/_plot_types/_scatter.py +0 -30
  215. scitex/fts/_kinds/_plot/_models/_plot_types/_seaborn.py +0 -121
  216. scitex/fts/_kinds/_plot/_models/_plot_types/_violin.py +0 -36
  217. scitex/fts/_kinds/_plot/_utils/__init__.py +0 -129
  218. scitex/fts/_kinds/_plot/_utils/_auto_layout.py +0 -127
  219. scitex/fts/_kinds/_plot/_utils/_calc_bounds.py +0 -111
  220. scitex/fts/_kinds/_plot/_utils/_const_sizes.py +0 -48
  221. scitex/fts/_kinds/_plot/_utils/_convert_coords.py +0 -77
  222. scitex/fts/_kinds/_plot/_utils/_get_template.py +0 -178
  223. scitex/fts/_kinds/_plot/_utils/_normalize.py +0 -73
  224. scitex/fts/_kinds/_plot/_utils/_validate.py +0 -197
  225. scitex/fts/_kinds/_table/_latex/_export.py +0 -279
  226. scitex/fts/_stats/__init__.py +0 -48
  227. scitex/fts/_stats/_dataclasses/_Stats.py +0 -423
  228. scitex/fts/_stats/_dataclasses/__init__.py +0 -48
  229. scitex/fts/_tables/__init__.py +0 -65
  230. scitex/fts/_tables/_latex/__init__.py +0 -93
  231. scitex/fts/_tables/_latex/_editor/__init__.py +0 -11
  232. scitex/fts/_tables/_latex/_editor/_app.py +0 -725
  233. scitex/fts/_tables/_latex/_figure_exporter.py +0 -153
  234. scitex/fts/_tables/_latex/_stats_formatter.py +0 -274
  235. scitex/fts/_tables/_latex/_table_exporter.py +0 -362
  236. scitex/fts/_tables/_latex/_utils.py +0 -369
  237. scitex/fts/_tables/_latex/_validator.py +0 -445
  238. scitex/io/_save_modules/_pltz_bundle.py +0 -356
  239. /scitex/{fig → canvas}/README.md +0 -0
  240. /scitex/{fig → canvas}/backend/__init__.py +0 -0
  241. /scitex/{fig → canvas}/backend/_export.py +0 -0
  242. /scitex/{fig → canvas}/backend/_render.py +0 -0
  243. /scitex/{fig → canvas}/docs/CANVAS_ARCHITECTURE.md +0 -0
  244. /scitex/{fig → canvas}/editor/__init__.py +0 -0
  245. /scitex/{fig → canvas}/editor/_dearpygui_editor.py +0 -0
  246. /scitex/{fig → canvas}/editor/_flask_editor.py +0 -0
  247. /scitex/{fig → canvas}/editor/_mpl_editor.py +0 -0
  248. /scitex/{fig → canvas}/editor/_qt_editor.py +0 -0
  249. /scitex/{fig → canvas}/editor/_tkinter_editor.py +0 -0
  250. /scitex/{fig → canvas}/editor/edit/backend_detector.py +0 -0
  251. /scitex/{fig → canvas}/editor/edit/manual_handler.py +0 -0
  252. /scitex/{fig → canvas}/editor/edit/path_resolver.py +0 -0
  253. /scitex/{fig → canvas}/editor/flask_editor/__init__.py +0 -0
  254. /scitex/{fig → canvas}/editor/flask_editor/_plotter.py +0 -0
  255. /scitex/{fig → canvas}/editor/flask_editor/_utils.py +0 -0
  256. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/reset.css +0 -0
  257. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/typography.css +0 -0
  258. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/variables.css +0 -0
  259. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/buttons.css +0 -0
  260. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/context-menu.css +0 -0
  261. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/dropdown.css +0 -0
  262. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/forms.css +0 -0
  263. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/modal.css +0 -0
  264. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/sections.css +0 -0
  265. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/element-inspector.css +0 -0
  266. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/loading.css +0 -0
  267. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/overlay.css +0 -0
  268. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/selection.css +0 -0
  269. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/statistics.css +0 -0
  270. /scitex/{fig → canvas}/editor/flask_editor/static/css/index.css +0 -0
  271. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/container.css +0 -0
  272. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/controls.css +0 -0
  273. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/preview.css +0 -0
  274. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/axis.js +0 -0
  275. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/basic.js +0 -0
  276. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/distribute.js +0 -0
  277. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/canvas.js +0 -0
  278. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/dragging.js +0 -0
  279. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/resize.js +0 -0
  280. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/selection.js +0 -0
  281. /scitex/{fig → canvas}/editor/flask_editor/static/js/core/state.js +0 -0
  282. /scitex/{fig → canvas}/editor/flask_editor/static/js/core/utils.js +0 -0
  283. /scitex/{fig → canvas}/editor/flask_editor/static/js/dev/element-inspector.js +0 -0
  284. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/bbox.js +0 -0
  285. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/element-drag.js +0 -0
  286. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/overlay.js +0 -0
  287. /scitex/{fig → canvas}/editor/flask_editor/static/js/main.js +0 -0
  288. /scitex/{fig → canvas}/editor/flask_editor/static/js/shortcuts/context-menu.js +0 -0
  289. /scitex/{fig → canvas}/editor/flask_editor/static/js/shortcuts/keyboard.js +0 -0
  290. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/controls.js +0 -0
  291. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/download.js +0 -0
  292. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/help.js +0 -0
  293. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/theme.js +0 -0
  294. /scitex/{fig → canvas}/editor/flask_editor/templates/__init__.py +0 -0
  295. /scitex/{fig → canvas}/io/_directory.py +0 -0
  296. /scitex/{fig → canvas}/model/_plot_types.py +0 -0
  297. /scitex/{fig → canvas}/utils/_defaults.py +0 -0
  298. /scitex/{fig → canvas}/utils/_validate.py +0 -0
  299. /scitex/{fts/_bundle → io/bundle}/_conversion/__init__.py +0 -0
  300. /scitex/{fts/_bundle → io/bundle}/_conversion/_bundle2dict.py +0 -0
  301. /scitex/{fts/_bundle → io/bundle}/_conversion/_dict2bundle.py +0 -0
  302. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_Axes.py +0 -0
  303. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_BBox.py +0 -0
  304. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_ColumnDef.py +0 -0
  305. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataFormat.py +0 -0
  306. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataInfo.py +0 -0
  307. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataSource.py +0 -0
  308. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_SizeMM.py +0 -0
  309. /scitex/{fts/_bundle → io/bundle}/_extractors/__init__.py +0 -0
  310. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_bar.py +0 -0
  311. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_line.py +0 -0
  312. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_scatter.py +0 -0
  313. /scitex/{fts/_kinds → io/bundle/kinds}/__init__.py +0 -0
  314. /scitex/{fts/_kinds → io/bundle/kinds}/_figure/__init__.py +0 -0
  315. /scitex/{fts/_fig → io/bundle/kinds/_figure}/_composite.py +0 -0
  316. /scitex/{fts/_kinds → io/bundle/kinds}/_plot/__init__.py +0 -0
  317. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/__init__.py +0 -0
  318. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/_export.py +0 -0
  319. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/_render.py +0 -0
  320. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_ChannelEncoding.py +0 -0
  321. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_Encoding.py +0 -0
  322. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_Theme.py +0 -0
  323. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_TraceEncoding.py +0 -0
  324. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/__init__.py +0 -0
  325. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/__init__.py +0 -0
  326. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/__init__.py +0 -0
  327. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_bar.py +0 -0
  328. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_box.py +0 -0
  329. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_distribution.py +0 -0
  330. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_errorbar.py +0 -0
  331. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_histogram.py +0 -0
  332. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_image.py +0 -0
  333. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_line.py +0 -0
  334. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_scatter.py +0 -0
  335. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_seaborn.py +0 -0
  336. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_violin.py +0 -0
  337. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/__init__.py +0 -0
  338. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_auto_layout.py +0 -0
  339. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_calc_bounds.py +0 -0
  340. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_const_sizes.py +0 -0
  341. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_convert_coords.py +0 -0
  342. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_get_template.py +0 -0
  343. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_normalize.py +0 -0
  344. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_validate.py +0 -0
  345. /scitex/{fts/_kinds → io/bundle/kinds}/_shape/__init__.py +0 -0
  346. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/__init__.py +0 -0
  347. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/_dataclasses/_Stats.py +0 -0
  348. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/_dataclasses/__init__.py +0 -0
  349. /scitex/{fts/_kinds → io/bundle/kinds}/_table/__init__.py +0 -0
  350. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_editor/__init__.py +0 -0
  351. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_stats_formatter.py +0 -0
  352. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_utils.py +0 -0
  353. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_validator.py +0 -0
  354. /scitex/{fts/_kinds → io/bundle/kinds}/_text/__init__.py +0 -0
  355. /scitex/{fts/_schemas → io/bundle/schemas}/data_info.schema.json +0 -0
  356. /scitex/{fts/_schemas → io/bundle/schemas}/encoding.schema.json +0 -0
  357. /scitex/{fts/_schemas → io/bundle/schemas}/node.schema.json +0 -0
  358. /scitex/{fts/_schemas → io/bundle/schemas}/render_manifest.schema.json +0 -0
  359. /scitex/{fts/_schemas → io/bundle/schemas}/stats.schema.json +0 -0
  360. /scitex/{fts/_schemas → io/bundle/schemas}/theme.schema.json +0 -0
  361. {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/WHEEL +0 -0
  362. {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/entry_points.txt +0 -0
  363. {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,992 +0,0 @@
1
- /**
2
- * Element Inspector - Visual Debugging Tool
3
- * Shows all HTML elements with colored rectangles and labels.
4
- *
5
- * Shortcuts:
6
- * Alt+I: Toggle inspector overlay
7
- * Ctrl+Alt+I: Rectangle selection mode
8
- * Ctrl+Shift+I: Debug snapshot (console logs + page info)
9
- * Escape: Deactivate inspector / Cancel selection
10
- */
11
-
12
- (function() {
13
- 'use strict';
14
-
15
- // ============================================================================
16
- // State
17
- // ============================================================================
18
- var isActive = false;
19
- var overlayContainer = null;
20
- var elementBoxMap = new Map();
21
- var currentlyHoveredBox = null;
22
- var currentlyHoveredElement = null;
23
- var consoleLogs = [];
24
- var maxLogs = 500;
25
- var onCopyCallback = null;
26
-
27
- // Selection mode state
28
- var selectionMode = false;
29
- var selectionStart = null;
30
- var selectionRect = null;
31
- var selectionOverlay = null;
32
- var currentlySelectedElements = new Set();
33
-
34
- // ============================================================================
35
- // Console Capture (start immediately)
36
- // ============================================================================
37
- var originalConsole = {
38
- log: console.log.bind(console),
39
- warn: console.warn.bind(console),
40
- error: console.error.bind(console),
41
- info: console.info.bind(console)
42
- };
43
-
44
- function captureLog(type, args) {
45
- var entry = {
46
- type: type,
47
- timestamp: new Date().toISOString(),
48
- args: args.map(function(arg) { return stringify(arg); }),
49
- source: getCallSource()
50
- };
51
- consoleLogs.push(entry);
52
- if (consoleLogs.length > maxLogs) {
53
- consoleLogs.shift();
54
- }
55
- }
56
-
57
- function getCallSource() {
58
- try {
59
- var stack = new Error().stack;
60
- if (!stack) return '';
61
- var lines = stack.split('\n');
62
- for (var i = 4; i < lines.length; i++) {
63
- var line = lines[i];
64
- var match = line.match(/(?:at\s+)?(?:.*?\s+\()?([^\s()]+):(\d+):(\d+)\)?$/);
65
- if (match) {
66
- var file = match[1];
67
- var lineNum = match[2];
68
- var fileName = file.split('/').pop() || file;
69
- if (fileName.includes('element-inspector')) continue;
70
- return fileName + ':' + lineNum;
71
- }
72
- }
73
- } catch (e) {}
74
- return '';
75
- }
76
-
77
- function stringify(obj) {
78
- if (obj === null) return 'null';
79
- if (obj === undefined) return 'undefined';
80
- if (typeof obj === 'string') return obj;
81
- if (typeof obj === 'number' || typeof obj === 'boolean') return String(obj);
82
- if (obj instanceof Error) {
83
- return obj.name + ': ' + obj.message + '\n' + (obj.stack || '');
84
- }
85
- try {
86
- return JSON.stringify(obj, null, 2);
87
- } catch (e) {
88
- return String(obj);
89
- }
90
- }
91
-
92
- // Override console methods
93
- console.log = function() {
94
- captureLog('log', Array.from(arguments));
95
- originalConsole.log.apply(console, arguments);
96
- };
97
- console.warn = function() {
98
- captureLog('warn', Array.from(arguments));
99
- originalConsole.warn.apply(console, arguments);
100
- };
101
- console.error = function() {
102
- captureLog('error', Array.from(arguments));
103
- originalConsole.error.apply(console, arguments);
104
- };
105
- console.info = function() {
106
- captureLog('info', Array.from(arguments));
107
- originalConsole.info.apply(console, arguments);
108
- };
109
-
110
- // ============================================================================
111
- // Notification Manager
112
- // ============================================================================
113
- function showNotification(message, type) {
114
- var notification = document.createElement('div');
115
- notification.className = 'element-inspector-notification ' + type;
116
- notification.textContent = message;
117
- document.body.appendChild(notification);
118
-
119
- requestAnimationFrame(function() {
120
- notification.classList.add('visible');
121
- });
122
-
123
- setTimeout(function() {
124
- notification.classList.remove('visible');
125
- setTimeout(function() { notification.remove(); }, 200);
126
- }, 1000);
127
- }
128
-
129
- function showCameraFlash() {
130
- var flash = document.createElement('div');
131
- flash.className = 'camera-flash';
132
- document.body.appendChild(flash);
133
- setTimeout(function() { flash.remove(); }, 300);
134
- }
135
-
136
- function triggerCopyCallback() {
137
- if (onCopyCallback) {
138
- setTimeout(function() {
139
- onCopyCallback();
140
- }, 400);
141
- }
142
- }
143
-
144
- // ============================================================================
145
- // Debug Info Collector
146
- // ============================================================================
147
- function buildCSSSelector(element) {
148
- var tag = element.tagName.toLowerCase();
149
- var id = element.id;
150
- var classes = element.className;
151
-
152
- var selector = tag;
153
- if (id) selector += '#' + id;
154
- if (classes && typeof classes === 'string') {
155
- var classList = classes.split(/\s+/).filter(function(c) { return c; });
156
- if (classList.length > 0) {
157
- selector += '.' + classList.join('.');
158
- }
159
- }
160
- return selector;
161
- }
162
-
163
- function getXPath(element) {
164
- if (element.id) {
165
- return '//*[@id="' + element.id + '"]';
166
- }
167
-
168
- var parts = [];
169
- var current = element;
170
-
171
- while (current && current.nodeType === Node.ELEMENT_NODE) {
172
- var index = 0;
173
- var sibling = current.previousSibling;
174
-
175
- while (sibling) {
176
- if (sibling.nodeType === Node.ELEMENT_NODE && sibling.nodeName === current.nodeName) {
177
- index++;
178
- }
179
- sibling = sibling.previousSibling;
180
- }
181
-
182
- var tagName = current.nodeName.toLowerCase();
183
- var pathIndex = index > 0 ? '[' + (index + 1) + ']' : '';
184
- parts.unshift(tagName + pathIndex);
185
- current = current.parentElement;
186
- }
187
-
188
- return '/' + parts.join('/');
189
- }
190
-
191
- function getParentChain(element) {
192
- var chain = [];
193
- var current = element.parentElement;
194
- var depth = 0;
195
-
196
- while (current && depth < 5) {
197
- chain.push(buildCSSSelector(current));
198
- current = current.parentElement;
199
- depth++;
200
- }
201
-
202
- return chain;
203
- }
204
-
205
- function gatherElementDebugInfo(element) {
206
- var info = {};
207
-
208
- info.url = window.location.href;
209
- info.timestamp = new Date().toISOString();
210
-
211
- var className = typeof element.className === 'string' ? element.className : '';
212
- info.element = {
213
- tag: element.tagName.toLowerCase(),
214
- id: element.id || null,
215
- classes: className ? className.split(/\s+/).filter(function(c) { return c; }) : [],
216
- selector: buildCSSSelector(element),
217
- xpath: getXPath(element)
218
- };
219
-
220
- info.attributes = {};
221
- for (var i = 0; i < element.attributes.length; i++) {
222
- var attr = element.attributes[i];
223
- info.attributes[attr.name] = attr.value;
224
- }
225
-
226
- if (element instanceof HTMLElement) {
227
- var computed = window.getComputedStyle(element);
228
- info.styles = {
229
- display: computed.display,
230
- position: computed.position,
231
- width: computed.width,
232
- height: computed.height,
233
- backgroundColor: computed.backgroundColor,
234
- color: computed.color,
235
- fontSize: computed.fontSize
236
- };
237
-
238
- var rect = element.getBoundingClientRect();
239
- info.dimensions = {
240
- width: rect.width,
241
- height: rect.height,
242
- top: rect.top,
243
- left: rect.left
244
- };
245
-
246
- info.content = {
247
- textContent: (element.textContent || '').substring(0, 200)
248
- };
249
- }
250
-
251
- info.parentChain = getParentChain(element);
252
-
253
- return formatDebugInfoForAI(info);
254
- }
255
-
256
- function formatDebugInfoForAI(info) {
257
- return '# Element Debug Information\n\n' +
258
- '## Page Context\n' +
259
- '- URL: ' + info.url + '\n' +
260
- '- Timestamp: ' + info.timestamp + '\n\n' +
261
- '## Element Identification\n' +
262
- '- Tag: <' + info.element.tag + '>\n' +
263
- '- ID: ' + (info.element.id || 'none') + '\n' +
264
- '- Classes: ' + (info.element.classes.join(', ') || 'none') + '\n' +
265
- '- CSS Selector: ' + info.element.selector + '\n' +
266
- '- XPath: ' + info.element.xpath + '\n\n' +
267
- '## Attributes\n' +
268
- Object.entries(info.attributes).map(function(entry) {
269
- return '- ' + entry[0] + ': ' + entry[1];
270
- }).join('\n') + '\n\n' +
271
- '## Computed Styles\n' +
272
- Object.entries(info.styles || {}).map(function(entry) {
273
- return '- ' + entry[0] + ': ' + entry[1];
274
- }).join('\n') + '\n\n' +
275
- '## Dimensions & Position\n' +
276
- '- Width: ' + (info.dimensions ? info.dimensions.width : 0) + 'px\n' +
277
- '- Height: ' + (info.dimensions ? info.dimensions.height : 0) + 'px\n' +
278
- '- Top: ' + (info.dimensions ? info.dimensions.top : 0) + 'px\n' +
279
- '- Left: ' + (info.dimensions ? info.dimensions.left : 0) + 'px\n\n' +
280
- '## Content (truncated)\n' +
281
- (info.content ? info.content.textContent : 'none') + '\n\n' +
282
- '## Parent Chain\n' +
283
- info.parentChain.map(function(p, i) { return (i + 1) + '. ' + p; }).join('\n') + '\n\n' +
284
- '---\nGenerated by Element Inspector';
285
- }
286
-
287
- // ============================================================================
288
- // Element Scanner
289
- // ============================================================================
290
- function getDepth(element) {
291
- var depth = 0;
292
- var current = element;
293
-
294
- while (current && current !== document.body) {
295
- depth++;
296
- current = current.parentElement;
297
- }
298
-
299
- return depth;
300
- }
301
-
302
- function getColorForDepth(depth) {
303
- var colors = [
304
- '#3B82F6', // Blue (depth 0-2)
305
- '#10B981', // Green (depth 3-5)
306
- '#F59E0B', // Yellow (depth 6-8)
307
- '#EF4444', // Red (depth 9-11)
308
- '#EC4899' // Pink (depth 12+)
309
- ];
310
-
311
- var index = Math.min(Math.floor(depth / 3), colors.length - 1);
312
- return colors[index];
313
- }
314
-
315
- function shouldShowLabel(element, rect, depth) {
316
- if (element.id) {
317
- return rect.width > 20 && rect.height > 20;
318
- }
319
- if (rect.width > 100 || rect.height > 100) {
320
- return true;
321
- }
322
- var importantTags = ['header', 'nav', 'main', 'section', 'article', 'aside', 'footer', 'form', 'table'];
323
- if (importantTags.indexOf(element.tagName.toLowerCase()) !== -1 && (rect.width > 50 || rect.height > 50)) {
324
- return true;
325
- }
326
- var interactiveTags = ['button', 'a', 'input', 'select', 'textarea'];
327
- if (interactiveTags.indexOf(element.tagName.toLowerCase()) !== -1 && (rect.width > 30 || rect.height > 30)) {
328
- return true;
329
- }
330
- if (depth > 8 && rect.width < 100 && rect.height < 100) {
331
- return false;
332
- }
333
- return false;
334
- }
335
-
336
- function scanElements(container) {
337
- var allElements = document.querySelectorAll('*');
338
- var count = 0;
339
- var occupiedPositions = [];
340
-
341
- allElements.forEach(function(element) {
342
- if (element.closest('#element-inspector-overlay')) return;
343
-
344
- if (element instanceof HTMLElement) {
345
- var computed = window.getComputedStyle(element);
346
- if (computed.display === 'none' || computed.visibility === 'hidden') return;
347
- }
348
-
349
- var depth = getDepth(element);
350
- var color = getColorForDepth(depth);
351
-
352
- var rect = element.getBoundingClientRect();
353
- if (rect.width === 0 || rect.height === 0) return;
354
-
355
- var box = document.createElement('div');
356
- box.className = 'element-inspector-box';
357
- box.style.cssText =
358
- 'top: ' + (rect.top + window.scrollY) + 'px;' +
359
- 'left: ' + (rect.left + window.scrollX) + 'px;' +
360
- 'width: ' + rect.width + 'px;' +
361
- 'height: ' + rect.height + 'px;' +
362
- 'border-color: ' + color + ';';
363
-
364
- var tag = element.tagName.toLowerCase();
365
- var id = element.id ? '#' + element.id : '';
366
- box.title = 'Click to copy debug info: ' + tag + id;
367
-
368
- elementBoxMap.set(box, element);
369
-
370
- box.addEventListener('mouseenter', function() {
371
- currentlyHoveredBox = box;
372
- currentlyHoveredElement = element;
373
- });
374
-
375
- box.addEventListener('mouseleave', function() {
376
- if (currentlyHoveredBox === box) {
377
- currentlyHoveredBox = null;
378
- currentlyHoveredElement = null;
379
- }
380
- });
381
-
382
- box.addEventListener('click', function(e) {
383
- e.preventDefault();
384
- e.stopPropagation();
385
-
386
- var selectedElement = currentlyHoveredElement || element;
387
- var selectedBox = currentlyHoveredBox || box;
388
-
389
- selectedBox.classList.add('highlighted');
390
-
391
- var debugInfo = gatherElementDebugInfo(selectedElement);
392
- navigator.clipboard.writeText(debugInfo).then(function() {
393
- showNotification('✓ Copied!', 'success');
394
- console.log('[ElementInspector] Copied:', debugInfo);
395
- triggerCopyCallback();
396
- }).catch(function(err) {
397
- console.error('[ElementInspector] Copy failed:', err);
398
- showNotification('✗ Copy Failed', 'error');
399
- selectedBox.classList.remove('highlighted');
400
- });
401
- });
402
-
403
- if (shouldShowLabel(element, rect, depth)) {
404
- var label = createLabel(element, depth);
405
- if (label) {
406
- var labelPos = findLabelPosition(rect, occupiedPositions);
407
- if (labelPos.isValid) {
408
- label.style.top = labelPos.top + 'px';
409
- label.style.left = labelPos.left + 'px';
410
- addCopyToClipboard(label, element);
411
- addHoverHighlight(label, box, element);
412
-
413
- occupiedPositions.push({
414
- top: labelPos.top - 8,
415
- left: labelPos.left - 8,
416
- bottom: labelPos.top + 20 + 8,
417
- right: labelPos.left + 250 + 8
418
- });
419
-
420
- container.appendChild(label);
421
- }
422
- }
423
- }
424
-
425
- container.appendChild(box);
426
- count++;
427
- });
428
-
429
- console.log('[ElementInspector] Visualized ' + count + ' elements');
430
- }
431
-
432
- function createLabel(element, depth) {
433
- var tag = element.tagName.toLowerCase();
434
- var id = element.id;
435
- var classes = element.className;
436
-
437
- var labelText = '<span class="element-inspector-label-tag">' + tag + '</span>';
438
-
439
- if (id) {
440
- labelText += ' <span class="element-inspector-label-id">#' + id + '</span>';
441
- }
442
-
443
- if (classes && typeof classes === 'string') {
444
- var classList = classes.split(/\s+/).filter(function(c) { return c.length > 0; });
445
- if (classList.length > 0) {
446
- var classPreview = classList.slice(0, 2).join('.');
447
- labelText += ' <span class="element-inspector-label-class">.' + classPreview + '</span>';
448
- if (classList.length > 2) {
449
- labelText += '<span class="element-inspector-label-class">+' + (classList.length - 2) + '</span>';
450
- }
451
- }
452
- }
453
-
454
- if (depth > 5) {
455
- labelText += ' <span style="color: #999; font-size: 9px;">d' + depth + '</span>';
456
- }
457
-
458
- var label = document.createElement('div');
459
- label.className = 'element-inspector-label';
460
- label.innerHTML = labelText;
461
- label.title = 'Click to copy comprehensive debug info for AI';
462
-
463
- return label;
464
- }
465
-
466
- function findLabelPosition(rect, occupiedPositions) {
467
- var scrollY = window.scrollY;
468
- var scrollX = window.scrollX;
469
-
470
- var positions = [
471
- { top: rect.top + scrollY - 24, left: rect.left + scrollX },
472
- { top: rect.top + scrollY - 24, left: rect.right + scrollX - 200 },
473
- { top: rect.top + scrollY + 4, left: rect.left + scrollX + 4 },
474
- { top: rect.bottom + scrollY + 4, left: rect.left + scrollX }
475
- ];
476
-
477
- for (var i = 0; i < positions.length; i++) {
478
- if (!isPositionOccupied(positions[i], occupiedPositions)) {
479
- return { top: positions[i].top, left: positions[i].left, isValid: true };
480
- }
481
- }
482
-
483
- return { top: 0, left: 0, isValid: false };
484
- }
485
-
486
- function isPositionOccupied(pos, occupiedPositions) {
487
- var labelWidth = 250;
488
- var labelHeight = 20;
489
-
490
- for (var i = 0; i < occupiedPositions.length; i++) {
491
- var occupied = occupiedPositions[i];
492
- if (!(pos.left + labelWidth < occupied.left ||
493
- pos.left > occupied.right ||
494
- pos.top + labelHeight < occupied.top ||
495
- pos.top > occupied.bottom)) {
496
- return true;
497
- }
498
- }
499
- return false;
500
- }
501
-
502
- function addHoverHighlight(label, box, element) {
503
- label.addEventListener('mouseenter', function() {
504
- currentlyHoveredBox = box;
505
- currentlyHoveredElement = element;
506
- box.classList.add('highlighted');
507
- if (element instanceof HTMLElement) {
508
- element.style.outline = '3px solid rgba(59, 130, 246, 0.8)';
509
- element.style.outlineOffset = '2px';
510
- }
511
- });
512
-
513
- label.addEventListener('mouseleave', function() {
514
- currentlyHoveredBox = null;
515
- currentlyHoveredElement = null;
516
- box.classList.remove('highlighted');
517
- if (element instanceof HTMLElement) {
518
- element.style.outline = '';
519
- element.style.outlineOffset = '';
520
- }
521
- });
522
- }
523
-
524
- function addCopyToClipboard(label, element) {
525
- label.addEventListener('click', function(e) {
526
- e.stopPropagation();
527
- e.preventDefault();
528
-
529
- var debugInfo = gatherElementDebugInfo(element);
530
-
531
- navigator.clipboard.writeText(debugInfo).then(function() {
532
- showNotification('✓ Copied!', 'success');
533
- console.log('[ElementInspector] Copied debug info to clipboard');
534
- triggerCopyCallback();
535
- }).catch(function(err) {
536
- console.error('[ElementInspector] Failed to copy:', err);
537
- showNotification('✗ Copy Failed', 'error');
538
- });
539
- });
540
- }
541
-
542
- // ============================================================================
543
- // Selection Mode
544
- // ============================================================================
545
- function startSelectionMode() {
546
- if (!isActive) {
547
- activate();
548
- }
549
-
550
- selectionMode = true;
551
- document.body.classList.add('element-inspector-selection-mode');
552
-
553
- selectionOverlay = document.createElement('div');
554
- selectionOverlay.className = 'selection-overlay';
555
- document.body.appendChild(selectionOverlay);
556
-
557
- showNotification('Drag to select area', 'success');
558
-
559
- document.addEventListener('mousedown', onSelectionMouseDown);
560
- document.addEventListener('mousemove', onSelectionMouseMove);
561
- document.addEventListener('mouseup', onSelectionMouseUp);
562
- }
563
-
564
- function cancelSelectionMode() {
565
- selectionMode = false;
566
- document.body.classList.remove('element-inspector-selection-mode');
567
-
568
- if (selectionOverlay) {
569
- selectionOverlay.remove();
570
- selectionOverlay = null;
571
- }
572
-
573
- if (selectionRect) {
574
- selectionRect.remove();
575
- selectionRect = null;
576
- }
577
-
578
- document.removeEventListener('mousedown', onSelectionMouseDown);
579
- document.removeEventListener('mousemove', onSelectionMouseMove);
580
- document.removeEventListener('mouseup', onSelectionMouseUp);
581
-
582
- selectionStart = null;
583
- currentlySelectedElements.clear();
584
- }
585
-
586
- function onSelectionMouseDown(e) {
587
- if (!selectionMode) return;
588
-
589
- e.preventDefault();
590
- selectionStart = { x: e.clientX, y: e.clientY };
591
-
592
- selectionRect = document.createElement('div');
593
- selectionRect.className = 'selection-rectangle';
594
- selectionRect.style.left = e.clientX + 'px';
595
- selectionRect.style.top = e.clientY + 'px';
596
- selectionRect.style.width = '0px';
597
- selectionRect.style.height = '0px';
598
-
599
- document.body.appendChild(selectionRect);
600
- }
601
-
602
- function onSelectionMouseMove(e) {
603
- if (!selectionMode || !selectionStart || !selectionRect) return;
604
-
605
- e.preventDefault();
606
-
607
- var left = Math.min(selectionStart.x, e.clientX);
608
- var top = Math.min(selectionStart.y, e.clientY);
609
- var width = Math.abs(e.clientX - selectionStart.x);
610
- var height = Math.abs(e.clientY - selectionStart.y);
611
-
612
- selectionRect.style.left = left + 'px';
613
- selectionRect.style.top = top + 'px';
614
- selectionRect.style.width = width + 'px';
615
- selectionRect.style.height = height + 'px';
616
- }
617
-
618
- function onSelectionMouseUp(e) {
619
- if (!selectionMode || !selectionStart || !selectionRect) return;
620
-
621
- e.preventDefault();
622
-
623
- var left = Math.min(selectionStart.x, e.clientX);
624
- var top = Math.min(selectionStart.y, e.clientY);
625
- var width = Math.abs(e.clientX - selectionStart.x);
626
- var height = Math.abs(e.clientY - selectionStart.y);
627
-
628
- if (width < 5 || height < 5) {
629
- cancelSelectionMode();
630
- showNotification('Selection too small', 'error');
631
- return;
632
- }
633
-
634
- var selectedElements = findElementsInRect({ left: left, top: top, width: width, height: height });
635
-
636
- console.log('[ElementInspector] Found ' + selectedElements.length + ' elements in selection');
637
-
638
- var selectionInfo = gatherSelectionInfo(selectedElements, { left: left, top: top, width: width, height: height });
639
-
640
- navigator.clipboard.writeText(selectionInfo).then(function() {
641
- showNotification('✓ ' + selectedElements.length + ' elements copied!', 'success');
642
- triggerCopyCallback();
643
- }).catch(function(err) {
644
- console.error('[ElementInspector] Failed to copy:', err);
645
- showNotification('✗ Copy Failed', 'error');
646
- });
647
-
648
- cancelSelectionMode();
649
- }
650
-
651
- function findElementsInRect(rect) {
652
- var selectedElements = [];
653
- var allElements = document.querySelectorAll('*');
654
-
655
- var selectionRect = {
656
- left: rect.left,
657
- top: rect.top,
658
- right: rect.left + rect.width,
659
- bottom: rect.top + rect.height
660
- };
661
-
662
- allElements.forEach(function(element) {
663
- if (element.closest('#element-inspector-overlay') ||
664
- element.classList.contains('selection-rectangle') ||
665
- element.classList.contains('selection-overlay')) {
666
- return;
667
- }
668
-
669
- if (element instanceof HTMLElement) {
670
- var computed = window.getComputedStyle(element);
671
- if (computed.display === 'none' || computed.visibility === 'hidden') return;
672
- }
673
-
674
- var elementRect = element.getBoundingClientRect();
675
- var intersects = !(
676
- elementRect.right < selectionRect.left ||
677
- elementRect.left > selectionRect.right ||
678
- elementRect.bottom < selectionRect.top ||
679
- elementRect.top > selectionRect.bottom
680
- );
681
-
682
- if (intersects) {
683
- selectedElements.push(element);
684
- }
685
- });
686
-
687
- return selectedElements;
688
- }
689
-
690
- function gatherSelectionInfo(elements, rect) {
691
- var info = '# Rectangle Selection Debug Information\n\n' +
692
- '## Selection Area\n' +
693
- '- Position: (' + Math.round(rect.left) + ', ' + Math.round(rect.top) + ')\n' +
694
- '- Size: ' + Math.round(rect.width) + 'x' + Math.round(rect.height) + 'px\n' +
695
- '- URL: ' + window.location.href + '\n' +
696
- '- Elements Found: ' + elements.length + '\n\n---\n\n';
697
-
698
- var elementTypes = {};
699
- elements.forEach(function(el) {
700
- var tag = el.tagName.toLowerCase();
701
- elementTypes[tag] = (elementTypes[tag] || 0) + 1;
702
- });
703
-
704
- info += '## Element Type Summary\n';
705
- Object.entries(elementTypes)
706
- .sort(function(a, b) { return b[1] - a[1]; })
707
- .forEach(function(entry) {
708
- info += '- ' + entry[0] + ': ' + entry[1] + '\n';
709
- });
710
-
711
- info += '\n---\n\n## Detailed Element Information (first 10 elements)\n\n';
712
-
713
- elements.slice(0, 10).forEach(function(element, index) {
714
- info += '### Element ' + (index + 1) + '\n';
715
- info += gatherElementDebugInfo(element);
716
- info += '\n---\n\n';
717
- });
718
-
719
- return info;
720
- }
721
-
722
- // ============================================================================
723
- // Debug Snapshot (Screenshot + Console Logs)
724
- // ============================================================================
725
- function captureDebugSnapshot() {
726
- showCameraFlash();
727
-
728
- // Run screenshot and console log capture in parallel
729
- Promise.all([
730
- captureScreenshot(),
731
- captureConsoleLogs()
732
- ]).then(function(results) {
733
- var screenshotOk = results[0];
734
- var logsOk = results[1];
735
-
736
- if (screenshotOk && logsOk) {
737
- showNotification('✓ Screenshot + logs copied', 'success');
738
- } else if (screenshotOk) {
739
- showNotification('✓ Screenshot copied', 'success');
740
- } else if (logsOk) {
741
- showNotification('✓ Console logs copied', 'success');
742
- } else {
743
- showNotification('✗ Capture failed', 'error');
744
- }
745
- });
746
- }
747
-
748
- function captureScreenshot() {
749
- return navigator.mediaDevices.getDisplayMedia({
750
- video: {
751
- displaySurface: 'browser'
752
- },
753
- preferCurrentTab: true,
754
- selfBrowserSurface: 'include',
755
- systemAudio: 'exclude'
756
- }).then(function(stream) {
757
- var video = document.createElement('video');
758
- video.srcObject = stream;
759
- video.muted = true;
760
-
761
- return new Promise(function(resolve) {
762
- video.onloadedmetadata = function() {
763
- video.play().then(function() {
764
- // Small delay to ensure frame is rendered
765
- setTimeout(function() {
766
- var canvas = document.createElement('canvas');
767
- canvas.width = video.videoWidth;
768
- canvas.height = video.videoHeight;
769
- var ctx = canvas.getContext('2d');
770
-
771
- if (!ctx) {
772
- stream.getTracks().forEach(function(t) { t.stop(); });
773
- resolve(false);
774
- return;
775
- }
776
-
777
- ctx.drawImage(video, 0, 0);
778
- stream.getTracks().forEach(function(t) { t.stop(); });
779
-
780
- // Convert to blob and copy to clipboard
781
- canvas.toBlob(function(blob) {
782
- if (!blob) {
783
- resolve(false);
784
- return;
785
- }
786
-
787
- navigator.clipboard.write([
788
- new ClipboardItem({ 'image/png': blob })
789
- ]).then(function() {
790
- console.log('[ElementInspector] Screenshot copied to clipboard');
791
- resolve(true);
792
- }).catch(function(err) {
793
- console.error('[ElementInspector] Screenshot clipboard write failed:', err);
794
- resolve(false);
795
- });
796
- }, 'image/png');
797
- }, 100);
798
- }).catch(function() {
799
- stream.getTracks().forEach(function(t) { t.stop(); });
800
- resolve(false);
801
- });
802
- };
803
-
804
- video.onerror = function() {
805
- stream.getTracks().forEach(function(t) { t.stop(); });
806
- resolve(false);
807
- };
808
-
809
- // Timeout fallback
810
- setTimeout(function() {
811
- stream.getTracks().forEach(function(t) { t.stop(); });
812
- resolve(false);
813
- }, 5000);
814
- });
815
- }).catch(function(err) {
816
- // User cancelled or permission denied - this is normal
817
- if (err.name !== 'NotAllowedError') {
818
- console.error('[ElementInspector] Screenshot capture failed:', err);
819
- }
820
- return false;
821
- });
822
- }
823
-
824
- function captureConsoleLogs() {
825
- var logs = getConsoleLogs();
826
- return navigator.clipboard.writeText(logs).then(function() {
827
- console.log('[ElementInspector] Console logs copied to clipboard');
828
- return true;
829
- }).catch(function(err) {
830
- console.error('[ElementInspector] Failed to copy logs:', err);
831
- return false;
832
- });
833
- }
834
-
835
- function getConsoleLogs() {
836
- if (consoleLogs.length === 0) {
837
- return 'No console logs captured.';
838
- }
839
-
840
- var output = '# Console Logs\n\n';
841
- output += 'URL: ' + window.location.href + '\n';
842
- output += 'Timestamp: ' + new Date().toISOString() + '\n';
843
- output += 'Total Logs: ' + consoleLogs.length + '\n\n---\n\n';
844
-
845
- consoleLogs.forEach(function(entry) {
846
- var icon = entry.type === 'error' ? '❌' : entry.type === 'warn' ? '⚠️' : '📝';
847
- var source = entry.source ? entry.source + ' ' : '';
848
- output += icon + ' ' + source + entry.args.join(' ') + '\n';
849
- });
850
-
851
- return output;
852
- }
853
-
854
- // ============================================================================
855
- // Main Functions
856
- // ============================================================================
857
- function activate() {
858
- console.log('[ElementInspector] Activating...');
859
- isActive = true;
860
-
861
- // Create overlay container
862
- overlayContainer = document.createElement('div');
863
- overlayContainer.id = 'element-inspector-overlay';
864
-
865
- var docHeight = Math.max(
866
- document.body.scrollHeight,
867
- document.documentElement.scrollHeight,
868
- document.body.offsetHeight,
869
- document.documentElement.offsetHeight
870
- );
871
-
872
- overlayContainer.style.cssText =
873
- 'position: absolute;' +
874
- 'top: 0;' +
875
- 'left: 0;' +
876
- 'width: 100%;' +
877
- 'height: ' + docHeight + 'px;' +
878
- 'pointer-events: none;' +
879
- 'z-index: 999999;';
880
-
881
- document.body.appendChild(overlayContainer);
882
-
883
- // Scan all elements
884
- scanElements(overlayContainer);
885
-
886
- console.log('[ElementInspector] Active - Press Alt+I to deactivate');
887
- }
888
-
889
- function deactivate() {
890
- console.log('[ElementInspector] Deactivating...');
891
- isActive = false;
892
-
893
- elementBoxMap.clear();
894
- currentlyHoveredBox = null;
895
- currentlyHoveredElement = null;
896
-
897
- if (overlayContainer) {
898
- overlayContainer.remove();
899
- overlayContainer = null;
900
- }
901
- }
902
-
903
- function toggle() {
904
- if (isActive) {
905
- deactivate();
906
- } else {
907
- activate();
908
- }
909
- }
910
-
911
- function refresh() {
912
- if (isActive) {
913
- deactivate();
914
- activate();
915
- }
916
- }
917
-
918
- // ============================================================================
919
- // Keyboard Shortcuts
920
- // ============================================================================
921
- document.addEventListener('keydown', function(e) {
922
- var key = e.key.toLowerCase();
923
-
924
- // Ctrl+Shift+I: Debug snapshot
925
- if (e.ctrlKey && e.shiftKey && !e.altKey && key === 'i') {
926
- e.preventDefault();
927
- e.stopPropagation();
928
- console.log('[ElementInspector] Ctrl+Shift+I pressed - capturing debug snapshot');
929
- captureDebugSnapshot();
930
- return;
931
- }
932
-
933
- // Ctrl+Alt+I: Start rectangle selection mode
934
- if (e.ctrlKey && e.altKey && !e.shiftKey && key === 'i') {
935
- e.preventDefault();
936
- startSelectionMode();
937
- return;
938
- }
939
-
940
- // Alt+I: Toggle inspector
941
- if (e.altKey && !e.shiftKey && !e.ctrlKey && key === 'i') {
942
- e.preventDefault();
943
- toggle();
944
- return;
945
- }
946
-
947
- // Escape: Deactivate
948
- if (e.key === 'Escape') {
949
- e.preventDefault();
950
- if (selectionMode) {
951
- cancelSelectionMode();
952
- deactivate();
953
- } else if (isActive) {
954
- deactivate();
955
- }
956
- return;
957
- }
958
- });
959
-
960
- // Set up auto-dismiss callback
961
- onCopyCallback = function() {
962
- deactivate();
963
- };
964
-
965
- // Auto-refresh on window resize
966
- var resizeTimeout;
967
- window.addEventListener('resize', function() {
968
- clearTimeout(resizeTimeout);
969
- resizeTimeout = setTimeout(function() {
970
- if (isActive) {
971
- refresh();
972
- }
973
- }, 500);
974
- });
975
-
976
- // Export to window for manual control
977
- window.elementInspector = {
978
- toggle: toggle,
979
- activate: activate,
980
- deactivate: deactivate,
981
- refresh: refresh,
982
- captureDebugSnapshot: captureDebugSnapshot,
983
- getConsoleLogs: getConsoleLogs
984
- };
985
-
986
- console.log('[ElementInspector] Initialized');
987
- console.log(' Alt+I: Toggle inspector overlay');
988
- console.log(' Ctrl+Alt+I: Rectangle selection mode');
989
- console.log(' Ctrl+Shift+I: Debug snapshot (console logs)');
990
- console.log(' Escape: Deactivate inspector');
991
-
992
- })();