plexora 0.0.1__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 (248) hide show
  1. plexora/__init__.py +129 -0
  2. plexora/__main__.py +15 -0
  3. plexora/_url.py +105 -0
  4. plexora/api/__init__.py +55 -0
  5. plexora/api/dataset.py +398 -0
  6. plexora/api/http.py +19 -0
  7. plexora/api/plugin.py +541 -0
  8. plexora/api/store.py +221 -0
  9. plexora/cli.py +777 -0
  10. plexora/client/dist/354_bundle.js +2 -0
  11. plexora/client/dist/354_bundle.js.LICENSE.txt +20 -0
  12. plexora/client/dist/418_bundle.js +2 -0
  13. plexora/client/dist/418_bundle.js.LICENSE.txt +1 -0
  14. plexora/client/dist/693b935cb1f907814be9c6199a68c217.svg +19 -0
  15. plexora/client/dist/713c134ff47cd328a5b711526f151082.svg +18 -0
  16. plexora/client/dist/770_bundle.js +1 -0
  17. plexora/client/dist/ff743f408972e0e96ca9153ed5ae4c83.svg +23 -0
  18. plexora/client/dist/vendor_bundle.js +2 -0
  19. plexora/client/dist/vendor_bundle.js.LICENSE.txt +308 -0
  20. plexora/client/external/openseadragon-bin-2.4.0/LICENSE.txt +28 -0
  21. plexora/client/external/openseadragon-bin-2.4.0/canvas-overlay-hd.js +140 -0
  22. plexora/client/external/openseadragon-bin-2.4.0/changelog.txt +501 -0
  23. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/.gitattributes +17 -0
  24. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/LICENSE.txt +116 -0
  25. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/Toolbar.png +0 -0
  26. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/fullpage.psd +0 -0
  27. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/home.psd +0 -0
  28. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/next.psd +0 -0
  29. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/previous.psd +0 -0
  30. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/rotateleft.psd +0 -0
  31. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/rotateright.psd +0 -0
  32. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/zoom.psd +0 -0
  33. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/README.md +9 -0
  34. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_grouphover.png +0 -0
  35. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_hover.png +0 -0
  36. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_pressed.png +0 -0
  37. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_rest.png +0 -0
  38. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_grouphover.png +0 -0
  39. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_hover.png +0 -0
  40. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_pressed.png +0 -0
  41. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_rest.png +0 -0
  42. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_grouphover.png +0 -0
  43. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_hover.png +0 -0
  44. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_pressed.png +0 -0
  45. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_rest.png +0 -0
  46. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_grouphover.png +0 -0
  47. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_hover.png +0 -0
  48. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_pressed.png +0 -0
  49. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_rest.png +0 -0
  50. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_grouphover.png +0 -0
  51. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_hover.png +0 -0
  52. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_pressed.png +0 -0
  53. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_rest.png +0 -0
  54. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_grouphover.png +0 -0
  55. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_hover.png +0 -0
  56. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_pressed.png +0 -0
  57. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_rest.png +0 -0
  58. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_grouphover.png +0 -0
  59. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_hover.png +0 -0
  60. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_pressed.png +0 -0
  61. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_rest.png +0 -0
  62. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_grouphover.png +0 -0
  63. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_hover.png +0 -0
  64. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_pressed.png +0 -0
  65. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_rest.png +0 -0
  66. plexora/client/external/openseadragon-bin-2.4.0/openseadragon-scalebar.js +562 -0
  67. plexora/client/src/css/import.css +474 -0
  68. plexora/client/src/css/main.css +903 -0
  69. plexora/client/src/css/openProject.css +363 -0
  70. plexora/client/src/css/quickView.css +166 -0
  71. plexora/client/src/css/tokens.css +51 -0
  72. plexora/client/src/css/viewer.css +1655 -0
  73. plexora/client/src/img/apple-touch-icon.png +0 -0
  74. plexora/client/src/img/favicon.ico +0 -0
  75. plexora/client/src/img/logo.ai +8892 -33
  76. plexora/client/src/img/logo.svg +1 -0
  77. plexora/client/src/img/logo_with_text.ai +9011 -34
  78. plexora/client/src/img/logo_with_text.svg +1 -0
  79. plexora/client/src/js/main.js +704 -0
  80. plexora/client/src/js/pluginRegistry.js +108 -0
  81. plexora/client/src/js/services/appStatus.js +286 -0
  82. plexora/client/src/js/services/browsePicker.js +73 -0
  83. plexora/client/src/js/services/dataLayer.js +400 -0
  84. plexora/client/src/js/services/datasetContext.js +143 -0
  85. plexora/client/src/js/services/glRenderer.js +143 -0
  86. plexora/client/src/js/services/importFormValidation.js +257 -0
  87. plexora/client/src/js/services/numericData.js +100 -0
  88. plexora/client/src/js/services/passVariablesToFrontend.js +20 -0
  89. plexora/client/src/js/services/simpleEventHandler.js +25 -0
  90. plexora/client/src/js/vendor.js +29 -0
  91. plexora/client/src/js/views/channelList.js +663 -0
  92. plexora/client/src/js/views/colorSwatchPicker.js +202 -0
  93. plexora/client/src/js/views/columnClassifier.js +146 -0
  94. plexora/client/src/js/views/coordinateField.js +133 -0
  95. plexora/client/src/js/views/dataSourceField.js +276 -0
  96. plexora/client/src/js/views/imageViewer.js +3306 -0
  97. plexora/client/src/js/views/miniMap.js +787 -0
  98. plexora/client/src/js/views/navbarControls.js +178 -0
  99. plexora/client/src/js/views/openProjectPage.js +239 -0
  100. plexora/client/src/js/views/projectEdit.js +335 -0
  101. plexora/client/src/js/views/quickViewLanding.js +136 -0
  102. plexora/client/src/js/views/rainbow.js +326 -0
  103. plexora/client/src/js/views/requirementsModal.js +572 -0
  104. plexora/client/src/js/views/rgbImageViewer.js +115 -0
  105. plexora/client/src/js/views/searchableSelect.js +411 -0
  106. plexora/client/src/js/views/segmentationProgress.js +122 -0
  107. plexora/client/src/js/views/toolLoader.js +747 -0
  108. plexora/client/src/js/views/viewerControls.js +689 -0
  109. plexora/client/src/js/views/viewerManager.js +434 -0
  110. plexora/client/src/js/views/viewerSidebar.js +1117 -0
  111. plexora/client/src/js/workers/tileDecoder.js +130 -0
  112. plexora/client/src/shaders/frag.glsl +528 -0
  113. plexora/client/src/shaders/vert.glsl +12 -0
  114. plexora/client/templates/base.html +212 -0
  115. plexora/client/templates/index.html +238 -0
  116. plexora/client/templates/open_project.html +96 -0
  117. plexora/client/templates/project_columns.html +86 -0
  118. plexora/client/templates/project_edit.html +196 -0
  119. plexora/client/templates/upload.html +118 -0
  120. plexora/connect.py +528 -0
  121. plexora/datasource.py +782 -0
  122. plexora/jupyter.py +406 -0
  123. plexora/notebook_env.py +232 -0
  124. plexora/paths.py +486 -0
  125. plexora/plugins/__init__.py +12 -0
  126. plexora/plugins/cell_explorer/__init__.py +100 -0
  127. plexora/plugins/cell_explorer/server/__init__.py +11 -0
  128. plexora/plugins/cell_explorer/server/routes.py +167 -0
  129. plexora/plugins/cell_explorer/server/state.py +281 -0
  130. plexora/plugins/cell_explorer/server/values.py +145 -0
  131. plexora/plugins/cell_explorer/server/variables.py +367 -0
  132. plexora/plugins/cell_explorer/static/cellExplorerApi.js +158 -0
  133. plexora/plugins/cell_explorer/static/cellExplorerColors.js +316 -0
  134. plexora/plugins/cell_explorer/static/cellExplorerContinuous.js +403 -0
  135. plexora/plugins/cell_explorer/static/cellExplorerFigureBridge.js +133 -0
  136. plexora/plugins/cell_explorer/static/cellExplorerLegend.js +188 -0
  137. plexora/plugins/cell_explorer/static/cellExplorerRoiBridge.js +822 -0
  138. plexora/plugins/cell_explorer/static/cellExplorerSidebarController.js +826 -0
  139. plexora/plugins/cell_explorer/static/cellExplorerState.js +372 -0
  140. plexora/plugins/cell_explorer/static/cell_explorer.css +752 -0
  141. plexora/plugins/cell_explorer/templates/cell_explorer/panel.html +137 -0
  142. plexora/plugins/figure_builder/__init__.py +125 -0
  143. plexora/plugins/figure_builder/server/__init__.py +7 -0
  144. plexora/plugins/figure_builder/server/compose.py +365 -0
  145. plexora/plugins/figure_builder/server/export.py +784 -0
  146. plexora/plugins/figure_builder/server/export_jobs.py +148 -0
  147. plexora/plugins/figure_builder/server/operations.py +556 -0
  148. plexora/plugins/figure_builder/server/pixels.py +142 -0
  149. plexora/plugins/figure_builder/server/provenance.py +174 -0
  150. plexora/plugins/figure_builder/server/render.py +278 -0
  151. plexora/plugins/figure_builder/server/repository.py +701 -0
  152. plexora/plugins/figure_builder/server/routes.py +594 -0
  153. plexora/plugins/figure_builder/server/schema.py +1023 -0
  154. plexora/plugins/figure_builder/server/sources.py +120 -0
  155. plexora/plugins/figure_builder/server/textmetrics.py +155 -0
  156. plexora/plugins/figure_builder/static/figureActions.js +363 -0
  157. plexora/plugins/figure_builder/static/figureBuilderApi.js +255 -0
  158. plexora/plugins/figure_builder/static/figureCanvas.js +2362 -0
  159. plexora/plugins/figure_builder/static/figureCaptureBoxes.js +369 -0
  160. plexora/plugins/figure_builder/static/figureCaptureDock.js +466 -0
  161. plexora/plugins/figure_builder/static/figureCaptureTool.js +1034 -0
  162. plexora/plugins/figure_builder/static/figureConfirm.js +136 -0
  163. plexora/plugins/figure_builder/static/figureContextBar.js +1193 -0
  164. plexora/plugins/figure_builder/static/figureContextMenu.js +253 -0
  165. plexora/plugins/figure_builder/static/figureDocumentState.js +275 -0
  166. plexora/plugins/figure_builder/static/figureExportUi.js +174 -0
  167. plexora/plugins/figure_builder/static/figureLibrary.js +247 -0
  168. plexora/plugins/figure_builder/static/figureQuickEdit.js +628 -0
  169. plexora/plugins/figure_builder/static/figureRichText.js +634 -0
  170. plexora/plugins/figure_builder/static/figureSceneSnapshot.js +361 -0
  171. plexora/plugins/figure_builder/static/figureSchema.js +218 -0
  172. plexora/plugins/figure_builder/static/figureSidebarController.js +1159 -0
  173. plexora/plugins/figure_builder/static/figureTextEditor.js +503 -0
  174. plexora/plugins/figure_builder/static/figureTextPanel.js +491 -0
  175. plexora/plugins/figure_builder/static/figureViewOptions.js +273 -0
  176. plexora/plugins/figure_builder/static/figureWorkspace.js +2030 -0
  177. plexora/plugins/figure_builder/static/figure_builder.css +3292 -0
  178. plexora/plugins/figure_builder/templates/figure_builder/library.html +74 -0
  179. plexora/plugins/figure_builder/templates/figure_builder/workspace.html +27 -0
  180. plexora/plugins/figure_builder/templates/figure_builder/workspace_body.html +458 -0
  181. plexora/plugins/gating/__init__.py +76 -0
  182. plexora/plugins/gating/server/__init__.py +0 -0
  183. plexora/plugins/gating/server/anndata_gates.py +367 -0
  184. plexora/plugins/gating/server/database.py +16 -0
  185. plexora/plugins/gating/server/model.py +320 -0
  186. plexora/plugins/gating/server/routes.py +235 -0
  187. plexora/plugins/gating/static/csvGatingList.js +947 -0
  188. plexora/plugins/gating/static/gating.css +289 -0
  189. plexora/plugins/gating/static/gatingApi.js +221 -0
  190. plexora/plugins/gating/static/gatingSidebarController.js +513 -0
  191. plexora/plugins/gating/templates/gating/legacy.html +26 -0
  192. plexora/plugins/gating/templates/gating/panel.html +69 -0
  193. plexora/plugins/roi/__init__.py +95 -0
  194. plexora/plugins/roi/server/__init__.py +8 -0
  195. plexora/plugins/roi/server/adapters.py +655 -0
  196. plexora/plugins/roi/server/geojson.py +267 -0
  197. plexora/plugins/roi/server/geometry.py +181 -0
  198. plexora/plugins/roi/server/mapping.py +169 -0
  199. plexora/plugins/roi/server/operations.py +293 -0
  200. plexora/plugins/roi/server/repository.py +215 -0
  201. plexora/plugins/roi/server/routes.py +409 -0
  202. plexora/plugins/roi/server/schema.py +323 -0
  203. plexora/plugins/roi/static/roi.css +583 -0
  204. plexora/plugins/roi/static/roiApi.js +177 -0
  205. plexora/plugins/roi/static/roiFigureBridge.js +107 -0
  206. plexora/plugins/roi/static/roiGeometry.js +350 -0
  207. plexora/plugins/roi/static/roiRenderer.js +278 -0
  208. plexora/plugins/roi/static/roiSidebarController.js +1038 -0
  209. plexora/plugins/roi/static/roiState.js +518 -0
  210. plexora/plugins/roi/static/roiTools.js +993 -0
  211. plexora/plugins/roi/templates/roi/panel.html +240 -0
  212. plexora/proxy.py +57 -0
  213. plexora/server/models/adapters/__init__.py +94 -0
  214. plexora/server/models/adapters/anndata_adapter.py +388 -0
  215. plexora/server/models/adapters/base.py +93 -0
  216. plexora/server/models/adapters/classify.py +192 -0
  217. plexora/server/models/adapters/csv_adapter.py +105 -0
  218. plexora/server/models/adapters/inspection.py +265 -0
  219. plexora/server/models/adapters/spatialdata_adapter.py +248 -0
  220. plexora/server/models/centroid_tiles.py +305 -0
  221. plexora/server/models/data_model.py +1659 -0
  222. plexora/server/models/database_model.py +169 -0
  223. plexora/server/models/project.py +1270 -0
  224. plexora/server/plugins.py +199 -0
  225. plexora/server/routes/browse_routes.py +41 -0
  226. plexora/server/routes/data_routes.py +294 -0
  227. plexora/server/routes/import_routes.py +603 -0
  228. plexora/server/routes/page_routes.py +139 -0
  229. plexora/server/routes/project_routes.py +438 -0
  230. plexora/server/routes/quick_view_routes.py +62 -0
  231. plexora/server/routes/system_routes.py +39 -0
  232. plexora/server/routes/tool_routes.py +418 -0
  233. plexora/server/utils/addHEColumns.py +11 -0
  234. plexora/server/utils/fast_png.py +97 -0
  235. plexora/server/utils/fullConversion.py +50 -0
  236. plexora/server/utils/native_dialog.py +168 -0
  237. plexora/server/utils/pre_normalization.py +47 -0
  238. plexora/server/utils/segmentation_pyramid.py +598 -0
  239. plexora/server/utils/smallestenclosingcircle.py +126 -0
  240. plexora/server/utils/tiffsurgeon.py +372 -0
  241. plexora/server_cli.py +48 -0
  242. plexora/test.py +0 -0
  243. plexora-0.0.1.dist-info/METADATA +341 -0
  244. plexora-0.0.1.dist-info/RECORD +248 -0
  245. plexora-0.0.1.dist-info/WHEEL +5 -0
  246. plexora-0.0.1.dist-info/entry_points.txt +12 -0
  247. plexora-0.0.1.dist-info/licenses/LICENSE +207 -0
  248. plexora-0.0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,289 @@
1
+ /* ------------------------------------------------------------------------
2
+ Moved out of core's viewer.css.
3
+
4
+ These style ids that only this plugin's templates render (panel.html,
5
+ legacy.html), so core was carrying a plugin's appearance: a core-only build
6
+ shipped ~150 lines of CSS for a tool it does not have, and gating alone got
7
+ a look it never had to ship. No plugin written by anyone else would be
8
+ styled by core, which made gating privileged in a way the plugin API is
9
+ meant to rule out.
10
+ Kept at the top of this file because viewer.css loaded first; the cascade
11
+ these rules take part in is therefore unchanged.
12
+ Custom properties (--surface-2 and friends) still resolve -- core's :root
13
+ defines them for the whole document, and core is always present.
14
+ ------------------------------------------------------------------------ */
15
+
16
+ #gate_marker_section {
17
+ border-color: var(--accent-gate-soft);
18
+ position: relative;
19
+ }
20
+
21
+ #gate_marker_section .section-heading h2 {
22
+ color: #ffe5da;
23
+ }
24
+
25
+ #gate_auto_button {
26
+ background: #4a5160;
27
+ color: #f1f4f8;
28
+ }
29
+
30
+ /* Was two rules in viewer.css: a shared one with #channel_list_wrapper, then
31
+ an override. Merged here -- the override's top wins, as it did before. */
32
+ #csv_channel_list_wrapper {
33
+ background-color: rgba(0, 0, 0, 0);
34
+ left: 0;
35
+ position: absolute;
36
+ top: 120px;
37
+ width: 360px;
38
+ z-index: 1;
39
+ }
40
+
41
+ #boxHeading3 {
42
+ color: rgba(255, 255, 255, 1);
43
+ font-size: 16px;
44
+ position: relative;
45
+ }
46
+
47
+ #download-gating-header-div {
48
+ color: rgba(255, 255, 255, 1);
49
+ }
50
+
51
+ #gating_upload_icon, #gating_download_icon {
52
+ cursor: pointer;
53
+ }
54
+
55
+ #gating_download_panel {
56
+ background: var(--surface-2);
57
+ border: 1px solid var(--border-strong);
58
+ border-radius: var(--radius-md);
59
+ box-shadow: var(--shadow-md);
60
+ color: #eef3f8;
61
+ left: 0;
62
+ margin: 0;
63
+ padding: 28px 10px 12px;
64
+ position: absolute;
65
+ right: 0;
66
+ top: 42px;
67
+ visibility: hidden;
68
+ width: auto;
69
+ z-index: 105;
70
+ }
71
+
72
+ #gating_download_panel #gating_exit {
73
+ color: var(--text-secondary);
74
+ cursor: pointer;
75
+ font-size: 14px;
76
+ position: absolute;
77
+ right: 9px;
78
+ top: 5px;
79
+ transition: color var(--duration-fast) var(--ease-standard);
80
+ }
81
+
82
+ #gating_download_panel #gating_exit:hover {
83
+ color: #ffffff;
84
+ }
85
+
86
+ #gating_download_panel label {
87
+ color: var(--text-secondary);
88
+ font-size: 12px;
89
+ margin-bottom: 8px;
90
+ width: 100%;
91
+ }
92
+
93
+ #gating_download_panel .download_flex {
94
+ display: flex;
95
+ gap: 7px;
96
+ margin-top: 4px;
97
+ width: 100%;
98
+ }
99
+
100
+ #gating_download_panel .download_flex input[type=text] {
101
+ background: var(--surface-1);
102
+ border: 1px solid var(--border-strong);
103
+ border-radius: 4px;
104
+ color: #eef3f8;
105
+ font-size: 11px;
106
+ min-width: 0;
107
+ padding: 5px;
108
+ width: 100%;
109
+ }
110
+
111
+ #gating_download_panel .download_button {
112
+ color: var(--accent-gate);
113
+ cursor: pointer;
114
+ font-size: 18px;
115
+ line-height: 1;
116
+ transition: transform var(--duration-fast) var(--ease-standard);
117
+ }
118
+
119
+ #gating_download_panel .download_button:hover {
120
+ transform: scale(1.1);
121
+ }
122
+
123
+ #gating_save_anndata_panel {
124
+ background: var(--surface-2);
125
+ border: 1px solid var(--border-strong);
126
+ border-radius: var(--radius-md);
127
+ box-shadow: var(--shadow-md);
128
+ color: #eef3f8;
129
+ margin-top: 8px;
130
+ /* Top padding leaves room for the absolutely-positioned close button,
131
+ matching #gating_download_panel above. */
132
+ padding: 28px 10px 12px;
133
+ position: relative;
134
+ width: 100%;
135
+ }
136
+
137
+ #gating_save_anndata_panel #save_anndata_exit {
138
+ color: var(--text-secondary);
139
+ font-size: 14px;
140
+ position: absolute;
141
+ right: 6px;
142
+ top: 4px;
143
+ }
144
+
145
+ #gating_save_anndata_panel #save_anndata_exit:hover {
146
+ color: #ffffff;
147
+ }
148
+
149
+ #gating_save_anndata_panel label {
150
+ color: var(--text-secondary);
151
+ display: block;
152
+ font-size: 12px;
153
+ margin-bottom: 8px;
154
+ width: 100%;
155
+ }
156
+
157
+ #gating_save_anndata_panel input[type=text] {
158
+ background: var(--surface-1);
159
+ border: 1px solid var(--border-strong);
160
+ border-radius: 4px;
161
+ color: #eef3f8;
162
+ font-size: 11px;
163
+ margin-top: 4px;
164
+ padding: 5px;
165
+ width: 100%;
166
+ }
167
+
168
+ #gating_save_anndata_panel .save-anndata-actions {
169
+ display: flex;
170
+ gap: 8px;
171
+ margin-top: 4px;
172
+ }
173
+
174
+ #gating_save_anndata_panel .save-anndata-actions .sidebar-action {
175
+ flex: 1;
176
+ }
177
+
178
+ #gating_save_anndata_panel #save_anndata_status {
179
+ font-size: 11px;
180
+ margin-top: 8px;
181
+ word-break: break-word;
182
+ }
183
+
184
+ #gating_save_anndata_panel #save_anndata_status.error {
185
+ color: #ff6b6b;
186
+ }
187
+
188
+ #gating_save_anndata_panel #save_anndata_status.success {
189
+ color: #2bd46f;
190
+ }
191
+
192
+ /* --- this plugin's own stylesheet, as it already was -------------------- */
193
+
194
+ /* viewer.css also had `#channel_list, #csv_gating_list { ... }`. Every one of
195
+ its declarations is repeated identically below, so it was dropped on the way
196
+ out rather than moved. */
197
+ #csv_gating_list {
198
+ width: 100%;
199
+ height: 80vh;
200
+ font-size: 10pt;
201
+ overflow-y: auto;
202
+ overflow-x: hidden;
203
+ box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
204
+
205
+ }
206
+
207
+ #csv_gating_list .list-group-item {
208
+ padding: .20rem 0.5rem;
209
+ border: 0;
210
+ }
211
+
212
+ #csv_gating_list .active {
213
+ background-color: rgba(0, 0, 0, 0.75);
214
+ border-top: 1px solid rgba(255, 255, 255, 0.5);
215
+ border-right: none;
216
+ border-bottom: 1px solid rgba(255, 255, 255, 0.5);
217
+ border-left: none;
218
+ height: 90px;
219
+ }
220
+
221
+ #csv_gating_list .list-group {
222
+ border-radius: 0rem;
223
+ }
224
+
225
+ #csv_gating_list_loader {
226
+ margin-left: 33px;
227
+ }
228
+
229
+ .auto-btn {
230
+ float: right;
231
+ padding-top: 0;
232
+ padding-bottom: 0;
233
+ border: 1px;
234
+ }
235
+
236
+ .distribution_line {
237
+ stroke: rgba(130, 130, 130, 0.5);
238
+ stroke-width: 4px;
239
+ fill: none;
240
+ }
241
+
242
+ .gmm_line {
243
+ stroke-width: 1px;
244
+ stroke-opacity: 0.75;
245
+ fill: none;
246
+ }
247
+
248
+ line.track {
249
+ stroke-width: 4px !important;
250
+ }
251
+
252
+
253
+ #drag-and-drop-text {
254
+ font-size: 30pt;
255
+ text-align: center;
256
+ }
257
+
258
+ #drag-and-drop-info {
259
+ display: none;
260
+ }
261
+
262
+ .dz-preview, .dz-file-preview {
263
+ display: none;
264
+ }
265
+
266
+ #arrow-upload-form, #arrow-upload-form * {
267
+ display: none
268
+ }
269
+
270
+ .viewer-sidebar #gating_download_panel {
271
+ background: #101721;
272
+ border: 1px solid rgba(255, 255, 255, 0.14);
273
+ border-radius: 8px;
274
+ box-shadow: 0 10px 28px rgba(0, 0, 0, 0.35);
275
+ color: #eef3f8;
276
+ left: 0;
277
+ margin: 0;
278
+ padding: 28px 10px 12px;
279
+ position: absolute;
280
+ right: 0;
281
+ top: auto;
282
+ visibility: hidden;
283
+ width: auto;
284
+ z-index: 105;
285
+ }
286
+
287
+ .viewer-sidebar #gate_marker_section #gating_download_panel {
288
+ top: 42px;
289
+ }
@@ -0,0 +1,221 @@
1
+ /**
2
+ * GatingApi - this plugin's own HTTP client.
3
+ *
4
+ * These nine methods lived on core's DataLayer, which meant core shipped the
5
+ * URLs of a plugin's routes: `plugins/gating/save_gating_list` and friends were
6
+ * written into plexora/client/src/js/services/dataLayer.js. A core-only build
7
+ * carried them for a tool it did not have, and no third-party plugin could ever
8
+ * be given the same treatment -- it would have to bring its own client. Gating
9
+ * was privileged in exactly the way the plugin API exists to rule out.
10
+ *
11
+ * Nothing about the requests changed in the move. Only the two globals they
12
+ * reached for did: `plexoraUrl(...)` and the bare `datasource` are now
13
+ * `ctx.url(...)` and `ctx.datasource`, which is what makes these calls resolve
14
+ * correctly under a mounted deployment (PLEXORA_BASE_URL, e.g. Jupyter's proxy)
15
+ * instead of depending on core's script-scope names.
16
+ *
17
+ * Each method swallows its own errors, as it did on DataLayer. That is what hid
18
+ * `saveGatingList` failing outright for every call after `lassos` stopped being
19
+ * a parameter but stayed in the payload; tests/js/datalayer_globals_probe.mjs
20
+ * exists to catch a repeat, and points here.
21
+ */
22
+ class GatingApi {
23
+
24
+ constructor(ctx) {
25
+ this.url = ctx.url;
26
+ this.datasource = ctx.datasource;
27
+ }
28
+
29
+ async getUploadedGatingCsvValues() {
30
+ try {
31
+ let response = await fetch(this.url('plugins/gating/get_uploaded_gating_csv_values') + '?' + new URLSearchParams({
32
+ datasource: this.datasource
33
+ }))
34
+ let response_data = await response.json();
35
+ return response_data;
36
+ } catch (e) {
37
+ console.log("Error Getting Uploaded Gates", e);
38
+ }
39
+ }
40
+
41
+ async getSavedGatingList() {
42
+ try {
43
+ let response = await fetch(this.url('plugins/gating/get_saved_gating_list') + '?' + new URLSearchParams({
44
+ datasource: this.datasource
45
+ }))
46
+ let response_data = await response.json();
47
+ return response_data;
48
+ } catch (e) {
49
+ console.log("Error Getting Saved Gating List", e);
50
+ }
51
+ }
52
+
53
+ downloadGatingCSV(channels, selections, selection_ids, fullCsv = false) {
54
+ let form = document.createElement("form");
55
+ form.action = this.url("plugins/gating/download_gating_csv");
56
+
57
+ form.method = "post";
58
+
59
+ let filename = '';
60
+ if (!fullCsv) {
61
+ filename = document.getElementById('download_input1').value;
62
+ }else{
63
+ filename = document.getElementById('download_input2').value;
64
+ }
65
+ let fileNameElemment = document.createElement("input");
66
+ fileNameElemment.type = "hidden";
67
+ fileNameElemment.value = _.toString(filename);
68
+ fileNameElemment.name = "filename";
69
+ form.appendChild(fileNameElemment);
70
+
71
+ let fullCsvElemment = document.createElement("input");
72
+ fullCsvElemment.type = "hidden";
73
+ fullCsvElemment.value = _.toString(fullCsv);
74
+ fullCsvElemment.name = "fullCsv";
75
+ form.appendChild(fullCsvElemment);
76
+
77
+ let encoding = document.getElementById('encoding').value;
78
+ let encodingElement = document.createElement("input");
79
+ encodingElement.type = "hidden";
80
+ encodingElement.value = _.toString(encoding);
81
+ encodingElement.name = "encoding";
82
+ form.appendChild(encodingElement);
83
+
84
+ let selectionsElement = document.createElement("input");
85
+ selectionsElement.type = "hidden";
86
+ selectionsElement.value = JSON.stringify(selections);
87
+ selectionsElement.name = "filter";
88
+ form.appendChild(selectionsElement);
89
+
90
+ let channelsElement = document.createElement("input");
91
+ channelsElement.type = "hidden";
92
+ channelsElement.value = JSON.stringify(channels);
93
+ channelsElement.name = "channels";
94
+ form.appendChild(channelsElement);
95
+
96
+
97
+ let idsElement = document.createElement("input");
98
+ idsElement.type = "hidden";
99
+ idsElement.value = JSON.stringify(selection_ids);
100
+ idsElement.name = "selection_ids";
101
+ form.appendChild(idsElement);
102
+
103
+ let datasourceElement = document.createElement("input");
104
+ datasourceElement.type = "hidden";
105
+ datasourceElement.value = this.datasource;
106
+ datasourceElement.name = "datasource";
107
+ form.appendChild(datasourceElement);
108
+
109
+ document.body.appendChild(form);
110
+ form.submit()
111
+ }
112
+
113
+ async saveGatingList(channels, selections) {
114
+ try {
115
+ let response = await fetch(this.url('plugins/gating/save_gating_list'), {
116
+ method: 'POST',
117
+ headers: {
118
+ 'Accept': 'application/json',
119
+ 'Content-Type': 'application/json'
120
+ },
121
+ body: JSON.stringify(
122
+ {
123
+ datasource: this.datasource,
124
+ filter: selections,
125
+ channels: channels
126
+ }
127
+ )
128
+ });
129
+ let response_data = await response.json();
130
+ return response_data;
131
+ } catch (e) {
132
+ console.log("Error Saving Gating List", e);
133
+ }
134
+ }
135
+
136
+ async saveGatesToAnndata(tableName) {
137
+ let response = await fetch(this.url('plugins/gating/save_gates_to_anndata'), {
138
+ method: 'POST',
139
+ headers: {
140
+ 'Accept': 'application/json',
141
+ 'Content-Type': 'application/json'
142
+ },
143
+ body: JSON.stringify(
144
+ {
145
+ datasource: this.datasource,
146
+ table_name: tableName
147
+ }
148
+ )
149
+ });
150
+ let response_data = await response.json();
151
+ if (!response.ok || !response_data.success) {
152
+ throw new Error(response_data.error || 'Failed to save gates to AnnData');
153
+ }
154
+ return response_data;
155
+ }
156
+
157
+ async getGatesFromAnndata(tableName = "gates") {
158
+ try {
159
+ let response = await fetch(this.url('plugins/gating/get_gates_from_anndata') + '?' + new URLSearchParams({
160
+ datasource: this.datasource,
161
+ table_name: tableName
162
+ }));
163
+ let response_data = await response.json();
164
+ return response_data.success ? response_data.gates : {};
165
+ } catch (e) {
166
+ console.log("Error Getting Gates From AnnData", e);
167
+ return {};
168
+ }
169
+ }
170
+
171
+ async submitGatingUpload(formData) {
172
+ try {
173
+ formData.append('datasource', this.datasource);
174
+ let response = await fetch(this.url('plugins/gating/upload_gates'), {
175
+ method: "POST",
176
+ body: formData
177
+ })
178
+ let cell = await response.json();
179
+ return cell;
180
+ } catch (e) {
181
+ console.log("Error Getting Submitting Form Upload", e);
182
+ }
183
+ }
184
+
185
+ async getGatedCellIds(filter, start_keys) {
186
+ try {
187
+ let response = await fetch(this.url('plugins/gating/get_gated_cell_ids') + '?' + new URLSearchParams({
188
+ filter: JSON.stringify(filter),
189
+ start_keys: start_keys,
190
+ datasource: this.datasource
191
+ }))
192
+ let cellIds = await response.json();
193
+ return cellIds;
194
+ } catch (e) {
195
+ console.log("Error Getting Gated Cell Ids", e);
196
+ }
197
+ }
198
+
199
+ async getGatingGMM(channel, selection_ids) {
200
+ try {
201
+ let response = await fetch(this.url('plugins/gating/get_gating_gmm'), {
202
+ method: 'POST',
203
+ headers: {
204
+ 'Accept': 'application/json',
205
+ 'Content-Type': 'application/json'
206
+ },
207
+ body: JSON.stringify(
208
+ {
209
+ channel: channel,
210
+ datasource: this.datasource,
211
+ selection_ids: selection_ids
212
+ }
213
+ )
214
+ });
215
+ let packet_gmm = await response.json();
216
+ return packet_gmm;
217
+ } catch (e) {
218
+ console.log("Error Getting Gating GMM", e);
219
+ }
220
+ }
221
+ }