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.
- plexora/__init__.py +129 -0
- plexora/__main__.py +15 -0
- plexora/_url.py +105 -0
- plexora/api/__init__.py +55 -0
- plexora/api/dataset.py +398 -0
- plexora/api/http.py +19 -0
- plexora/api/plugin.py +541 -0
- plexora/api/store.py +221 -0
- plexora/cli.py +777 -0
- plexora/client/dist/354_bundle.js +2 -0
- plexora/client/dist/354_bundle.js.LICENSE.txt +20 -0
- plexora/client/dist/418_bundle.js +2 -0
- plexora/client/dist/418_bundle.js.LICENSE.txt +1 -0
- plexora/client/dist/693b935cb1f907814be9c6199a68c217.svg +19 -0
- plexora/client/dist/713c134ff47cd328a5b711526f151082.svg +18 -0
- plexora/client/dist/770_bundle.js +1 -0
- plexora/client/dist/ff743f408972e0e96ca9153ed5ae4c83.svg +23 -0
- plexora/client/dist/vendor_bundle.js +2 -0
- plexora/client/dist/vendor_bundle.js.LICENSE.txt +308 -0
- plexora/client/external/openseadragon-bin-2.4.0/LICENSE.txt +28 -0
- plexora/client/external/openseadragon-bin-2.4.0/canvas-overlay-hd.js +140 -0
- plexora/client/external/openseadragon-bin-2.4.0/changelog.txt +501 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/.gitattributes +17 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/LICENSE.txt +116 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/Toolbar.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/fullpage.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/home.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/next.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/previous.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/rotateleft.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/rotateright.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/Photoshop/zoom.psd +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/README.md +9 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/fullpage_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/home_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/next_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/previous_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateleft_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/rotateright_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomin_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_grouphover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_hover.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_pressed.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-flat-toolbar-icons-master/images/zoomout_rest.png +0 -0
- plexora/client/external/openseadragon-bin-2.4.0/openseadragon-scalebar.js +562 -0
- plexora/client/src/css/import.css +474 -0
- plexora/client/src/css/main.css +903 -0
- plexora/client/src/css/openProject.css +363 -0
- plexora/client/src/css/quickView.css +166 -0
- plexora/client/src/css/tokens.css +51 -0
- plexora/client/src/css/viewer.css +1655 -0
- plexora/client/src/img/apple-touch-icon.png +0 -0
- plexora/client/src/img/favicon.ico +0 -0
- plexora/client/src/img/logo.ai +8892 -33
- plexora/client/src/img/logo.svg +1 -0
- plexora/client/src/img/logo_with_text.ai +9011 -34
- plexora/client/src/img/logo_with_text.svg +1 -0
- plexora/client/src/js/main.js +704 -0
- plexora/client/src/js/pluginRegistry.js +108 -0
- plexora/client/src/js/services/appStatus.js +286 -0
- plexora/client/src/js/services/browsePicker.js +73 -0
- plexora/client/src/js/services/dataLayer.js +400 -0
- plexora/client/src/js/services/datasetContext.js +143 -0
- plexora/client/src/js/services/glRenderer.js +143 -0
- plexora/client/src/js/services/importFormValidation.js +257 -0
- plexora/client/src/js/services/numericData.js +100 -0
- plexora/client/src/js/services/passVariablesToFrontend.js +20 -0
- plexora/client/src/js/services/simpleEventHandler.js +25 -0
- plexora/client/src/js/vendor.js +29 -0
- plexora/client/src/js/views/channelList.js +663 -0
- plexora/client/src/js/views/colorSwatchPicker.js +202 -0
- plexora/client/src/js/views/columnClassifier.js +146 -0
- plexora/client/src/js/views/coordinateField.js +133 -0
- plexora/client/src/js/views/dataSourceField.js +276 -0
- plexora/client/src/js/views/imageViewer.js +3306 -0
- plexora/client/src/js/views/miniMap.js +787 -0
- plexora/client/src/js/views/navbarControls.js +178 -0
- plexora/client/src/js/views/openProjectPage.js +239 -0
- plexora/client/src/js/views/projectEdit.js +335 -0
- plexora/client/src/js/views/quickViewLanding.js +136 -0
- plexora/client/src/js/views/rainbow.js +326 -0
- plexora/client/src/js/views/requirementsModal.js +572 -0
- plexora/client/src/js/views/rgbImageViewer.js +115 -0
- plexora/client/src/js/views/searchableSelect.js +411 -0
- plexora/client/src/js/views/segmentationProgress.js +122 -0
- plexora/client/src/js/views/toolLoader.js +747 -0
- plexora/client/src/js/views/viewerControls.js +689 -0
- plexora/client/src/js/views/viewerManager.js +434 -0
- plexora/client/src/js/views/viewerSidebar.js +1117 -0
- plexora/client/src/js/workers/tileDecoder.js +130 -0
- plexora/client/src/shaders/frag.glsl +528 -0
- plexora/client/src/shaders/vert.glsl +12 -0
- plexora/client/templates/base.html +212 -0
- plexora/client/templates/index.html +238 -0
- plexora/client/templates/open_project.html +96 -0
- plexora/client/templates/project_columns.html +86 -0
- plexora/client/templates/project_edit.html +196 -0
- plexora/client/templates/upload.html +118 -0
- plexora/connect.py +528 -0
- plexora/datasource.py +782 -0
- plexora/jupyter.py +406 -0
- plexora/notebook_env.py +232 -0
- plexora/paths.py +486 -0
- plexora/plugins/__init__.py +12 -0
- plexora/plugins/cell_explorer/__init__.py +100 -0
- plexora/plugins/cell_explorer/server/__init__.py +11 -0
- plexora/plugins/cell_explorer/server/routes.py +167 -0
- plexora/plugins/cell_explorer/server/state.py +281 -0
- plexora/plugins/cell_explorer/server/values.py +145 -0
- plexora/plugins/cell_explorer/server/variables.py +367 -0
- plexora/plugins/cell_explorer/static/cellExplorerApi.js +158 -0
- plexora/plugins/cell_explorer/static/cellExplorerColors.js +316 -0
- plexora/plugins/cell_explorer/static/cellExplorerContinuous.js +403 -0
- plexora/plugins/cell_explorer/static/cellExplorerFigureBridge.js +133 -0
- plexora/plugins/cell_explorer/static/cellExplorerLegend.js +188 -0
- plexora/plugins/cell_explorer/static/cellExplorerRoiBridge.js +822 -0
- plexora/plugins/cell_explorer/static/cellExplorerSidebarController.js +826 -0
- plexora/plugins/cell_explorer/static/cellExplorerState.js +372 -0
- plexora/plugins/cell_explorer/static/cell_explorer.css +752 -0
- plexora/plugins/cell_explorer/templates/cell_explorer/panel.html +137 -0
- plexora/plugins/figure_builder/__init__.py +125 -0
- plexora/plugins/figure_builder/server/__init__.py +7 -0
- plexora/plugins/figure_builder/server/compose.py +365 -0
- plexora/plugins/figure_builder/server/export.py +784 -0
- plexora/plugins/figure_builder/server/export_jobs.py +148 -0
- plexora/plugins/figure_builder/server/operations.py +556 -0
- plexora/plugins/figure_builder/server/pixels.py +142 -0
- plexora/plugins/figure_builder/server/provenance.py +174 -0
- plexora/plugins/figure_builder/server/render.py +278 -0
- plexora/plugins/figure_builder/server/repository.py +701 -0
- plexora/plugins/figure_builder/server/routes.py +594 -0
- plexora/plugins/figure_builder/server/schema.py +1023 -0
- plexora/plugins/figure_builder/server/sources.py +120 -0
- plexora/plugins/figure_builder/server/textmetrics.py +155 -0
- plexora/plugins/figure_builder/static/figureActions.js +363 -0
- plexora/plugins/figure_builder/static/figureBuilderApi.js +255 -0
- plexora/plugins/figure_builder/static/figureCanvas.js +2362 -0
- plexora/plugins/figure_builder/static/figureCaptureBoxes.js +369 -0
- plexora/plugins/figure_builder/static/figureCaptureDock.js +466 -0
- plexora/plugins/figure_builder/static/figureCaptureTool.js +1034 -0
- plexora/plugins/figure_builder/static/figureConfirm.js +136 -0
- plexora/plugins/figure_builder/static/figureContextBar.js +1193 -0
- plexora/plugins/figure_builder/static/figureContextMenu.js +253 -0
- plexora/plugins/figure_builder/static/figureDocumentState.js +275 -0
- plexora/plugins/figure_builder/static/figureExportUi.js +174 -0
- plexora/plugins/figure_builder/static/figureLibrary.js +247 -0
- plexora/plugins/figure_builder/static/figureQuickEdit.js +628 -0
- plexora/plugins/figure_builder/static/figureRichText.js +634 -0
- plexora/plugins/figure_builder/static/figureSceneSnapshot.js +361 -0
- plexora/plugins/figure_builder/static/figureSchema.js +218 -0
- plexora/plugins/figure_builder/static/figureSidebarController.js +1159 -0
- plexora/plugins/figure_builder/static/figureTextEditor.js +503 -0
- plexora/plugins/figure_builder/static/figureTextPanel.js +491 -0
- plexora/plugins/figure_builder/static/figureViewOptions.js +273 -0
- plexora/plugins/figure_builder/static/figureWorkspace.js +2030 -0
- plexora/plugins/figure_builder/static/figure_builder.css +3292 -0
- plexora/plugins/figure_builder/templates/figure_builder/library.html +74 -0
- plexora/plugins/figure_builder/templates/figure_builder/workspace.html +27 -0
- plexora/plugins/figure_builder/templates/figure_builder/workspace_body.html +458 -0
- plexora/plugins/gating/__init__.py +76 -0
- plexora/plugins/gating/server/__init__.py +0 -0
- plexora/plugins/gating/server/anndata_gates.py +367 -0
- plexora/plugins/gating/server/database.py +16 -0
- plexora/plugins/gating/server/model.py +320 -0
- plexora/plugins/gating/server/routes.py +235 -0
- plexora/plugins/gating/static/csvGatingList.js +947 -0
- plexora/plugins/gating/static/gating.css +289 -0
- plexora/plugins/gating/static/gatingApi.js +221 -0
- plexora/plugins/gating/static/gatingSidebarController.js +513 -0
- plexora/plugins/gating/templates/gating/legacy.html +26 -0
- plexora/plugins/gating/templates/gating/panel.html +69 -0
- plexora/plugins/roi/__init__.py +95 -0
- plexora/plugins/roi/server/__init__.py +8 -0
- plexora/plugins/roi/server/adapters.py +655 -0
- plexora/plugins/roi/server/geojson.py +267 -0
- plexora/plugins/roi/server/geometry.py +181 -0
- plexora/plugins/roi/server/mapping.py +169 -0
- plexora/plugins/roi/server/operations.py +293 -0
- plexora/plugins/roi/server/repository.py +215 -0
- plexora/plugins/roi/server/routes.py +409 -0
- plexora/plugins/roi/server/schema.py +323 -0
- plexora/plugins/roi/static/roi.css +583 -0
- plexora/plugins/roi/static/roiApi.js +177 -0
- plexora/plugins/roi/static/roiFigureBridge.js +107 -0
- plexora/plugins/roi/static/roiGeometry.js +350 -0
- plexora/plugins/roi/static/roiRenderer.js +278 -0
- plexora/plugins/roi/static/roiSidebarController.js +1038 -0
- plexora/plugins/roi/static/roiState.js +518 -0
- plexora/plugins/roi/static/roiTools.js +993 -0
- plexora/plugins/roi/templates/roi/panel.html +240 -0
- plexora/proxy.py +57 -0
- plexora/server/models/adapters/__init__.py +94 -0
- plexora/server/models/adapters/anndata_adapter.py +388 -0
- plexora/server/models/adapters/base.py +93 -0
- plexora/server/models/adapters/classify.py +192 -0
- plexora/server/models/adapters/csv_adapter.py +105 -0
- plexora/server/models/adapters/inspection.py +265 -0
- plexora/server/models/adapters/spatialdata_adapter.py +248 -0
- plexora/server/models/centroid_tiles.py +305 -0
- plexora/server/models/data_model.py +1659 -0
- plexora/server/models/database_model.py +169 -0
- plexora/server/models/project.py +1270 -0
- plexora/server/plugins.py +199 -0
- plexora/server/routes/browse_routes.py +41 -0
- plexora/server/routes/data_routes.py +294 -0
- plexora/server/routes/import_routes.py +603 -0
- plexora/server/routes/page_routes.py +139 -0
- plexora/server/routes/project_routes.py +438 -0
- plexora/server/routes/quick_view_routes.py +62 -0
- plexora/server/routes/system_routes.py +39 -0
- plexora/server/routes/tool_routes.py +418 -0
- plexora/server/utils/addHEColumns.py +11 -0
- plexora/server/utils/fast_png.py +97 -0
- plexora/server/utils/fullConversion.py +50 -0
- plexora/server/utils/native_dialog.py +168 -0
- plexora/server/utils/pre_normalization.py +47 -0
- plexora/server/utils/segmentation_pyramid.py +598 -0
- plexora/server/utils/smallestenclosingcircle.py +126 -0
- plexora/server/utils/tiffsurgeon.py +372 -0
- plexora/server_cli.py +48 -0
- plexora/test.py +0 -0
- plexora-0.0.1.dist-info/METADATA +341 -0
- plexora-0.0.1.dist-info/RECORD +248 -0
- plexora-0.0.1.dist-info/WHEEL +5 -0
- plexora-0.0.1.dist-info/entry_points.txt +12 -0
- plexora-0.0.1.dist-info/licenses/LICENSE +207 -0
- 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
|
+
}
|