cubevis 1.0.21__tar.gz → 1.0.33__tar.gz
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.
- {cubevis-1.0.21 → cubevis-1.0.33}/PKG-INFO +1 -1
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__js__/bokeh-3.8/cubevisjs.min.js +5 -5
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/__init__.py +1 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/models/_showable.py +82 -13
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/sources/_data_pipe.py +28 -1
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/state/_initialize.py +7 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/toolbox/_cube.py +1 -1
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/utils/__init__.py +1 -1
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/utils/_jupyter.py +35 -12
- {cubevis-1.0.21 → cubevis-1.0.33}/pyproject.toml +1 -1
- {cubevis-1.0.21 → cubevis-1.0.33}/LICENSE +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/README.rst +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/LICENSE.rst +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/20px/fast-backward.svg +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/20px/fast-forward.svg +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/20px/step-backward.svg +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/20px/step-forward.svg +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/add-chan.png +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/add-chan.svg +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/add-cube.png +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/add-cube.svg +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/drag.png +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/drag.svg +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/mask-selected.png +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/mask.png +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/mask.svg +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/new-layer-sm-selected.png +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/new-layer-sm-selected.svg +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/new-layer-sm.png +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/new-layer-sm.svg +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/reset.png +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/reset.svg +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/sub-chan.png +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/sub-chan.svg +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/sub-cube.png +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/sub-cube.svg +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/trash.png +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/trash.svg +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/trash_full.png +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/trash_full.svg +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/trash_full_raw.png +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/zoom-to-fit.png +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__icons__/zoom-to-fit.svg +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__init__.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__js__/bokeh-3.6/cubevisjs.min.js +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__js__/bokeh-3.7/cubevisjs.min.js +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/__js__/casalib.min.js +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/annotations/__init__.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/annotations/_ev_poly_annotation.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/components/__init__.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/format/__init__.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/format/_time_ticks.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/format/_wcs_ticks.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/models/__init__.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/models/_bokeh_app_context.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/models/_edit_span.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/models/_ev_text_input.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/models/_shared_dict.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/models/_tip.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/models/_tip_button.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/sources/__init__.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/sources/_image_data_source.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/sources/_image_pipe.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/sources/_spectra_data_source.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/sources/_updatable_data_source.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/state/__init__.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/state/_current.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/state/_javascript.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/state/_palette.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/state/_session.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/state/js/bokeh-2.4.1.min.js +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/state/js/bokeh-gl-2.4.1.min.js +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/state/js/bokeh-tables-2.4.1.min.js +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/state/js/bokeh-widgets-2.4.1.min.js +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/state/js/casaguijs-v0.0.4.0-b2.4.min.js +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/state/js/casaguijs-v0.0.5.0-b2.4.min.js +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/state/js/casaguijs-v0.0.6.0-b2.4.min.js +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/state/js/casalib-v0.0.1.min.js +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/tools/__init__.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/tools/_cbreset_tool.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/tools/_drag_tool.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/utils/__init__.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/utils/_axes_labels.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/bokeh/utils/_svg_icon.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/data/__init__.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/data/casaimage/__init__.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/exe/__init__.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/exe/_context.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/exe/_mode.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/exe/_setting.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/exe/_task.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/private/_gclean.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/private/apps/__init__.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/private/apps/_createmask.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/private/apps/_createregion.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/private/apps/_interactiveclean.mustache +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/private/apps/_interactiveclean.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/private/apps/_interactivecleannotebook.mustache +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/private/apps/_interactivecleannotebook.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/private/apps/_plotants.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/private/apps/_plotbandpass.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/private/casashell/createmask.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/private/casashell/iclean.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/private/casatasks/__init__.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/private/casatasks/createmask.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/private/casatasks/createregion.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/private/casatasks/iclean.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/private/casatasks/iclean_notebook.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/readme.rst +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/remote/__init__.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/remote/_gclean.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/remote/_local.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/remote/_remote_kernel.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/toolbox/__init__.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/toolbox/_app_context.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/toolbox/_interactive_clean_ui.mustache +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/toolbox/_interactive_clean_ui.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/toolbox/_interactiveclean_wrappers.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/toolbox/_region_list.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/utils/_ResourceManager.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/utils/_browser.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/utils/_contextmgrchain.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/utils/_conversion.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/utils/_copydoc.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/utils/_docenum.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/utils/_git.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/utils/_import_protected_module.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/utils/_logging.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/utils/_mutual_exclusion.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/utils/_pkgs.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/utils/_regions.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/utils/_static.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/cubevis/utils/_tiles.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/alma-many-chan/alma-many-chan.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/basic-websockets-demo/client.html +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/basic-websockets-demo/client.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/basic-websockets-demo/server.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/createmask-demo/run-createmask.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/createregion-demo/run-createregion.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/cubemask-demo/image-slider-spectra-done-stats.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/cubemask-demo/image-slider-spectra-done.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/cubemask-demo/image-slider-spectra.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/cubemask-demo/image-slider.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/cubemask-demo/image.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/iclean-demo/iclean-demo.ipynb +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/iclean-demo/m100_interactive.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/iclean-demo/mask0-iclean.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/iclean-demo/run-gclean.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/iclean-demo/run-iclean-obj.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/iclean-demo/run-iclean.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/iclean-demo/vla-sim-jet-iclean.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/iclean-first-look/run-fl-cont.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/iclean-first-look/run-fl-line.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/iclean-outlier/run-iclean.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/iclean-outlier/test_outlier.txt +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/iclean-remote/iclean_remote_webserver.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/large-cube/run-largecube.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/svg-test.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/updatable-data-source/direct-plot.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/updatable-data-source/simple-update.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/updatable-data-source/updated-plot.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/uranus-demo/uranus-iclean.py +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/websocket-reconnect/client.html +0 -0
- {cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/websocket-reconnect/server.py +0 -0
|
@@ -42,15 +42,15 @@
|
|
|
42
42
|
}
|
|
43
43
|
})
|
|
44
44
|
({
|
|
45
|
-
"07c9fde72b": function _(e,a,
|
|
46
|
-
"
|
|
45
|
+
"07c9fde72b": function _(e,t,a,o,c){o();const i=e("tslib"),n=e("2295368b65");c("DataPipe",n.DataPipe);c("activeDataPipes",e("5179d11e71").activeDataPipes);const p=e("2889e0dd45");c("ImagePipe",p.ImagePipe);const s=e("de65005924");c("ImageDataSource",s.ImageDataSource);const r=e("02e3c3e46c");c("SpectraDataSource",r.SpectraDataSource);const S=e("64b16deff9");c("UpdatableDataSource",S.UpdatableDataSource);const d=e("b6ae454f0d");c("WcsTicks",d.WcsTicks);const l=e("cb7d28d6b3");c("DragTool",l.DragTool);const D=e("9d3c34ff8e");c("CBResetTool",D.CBResetTool);const T=e("e3901fa9f2");c("serialize",T.serialize),c("deserialize",T.deserialize);const b=e("9f961622ce");c("TipButton",b.TipButton);const u=e("ca4c845905");c("Tip",u.Tip);const P=e("a6e757a69a");c("Showable",P.Showable);const f=e("467d2716b0");c("BokehAppContext",f.BokehAppContext);const g=e("50a1e32f01");c("SharedDict",g.SharedDict);const h=e("b55081402e");c("EditSpan",h.EditSpan);const B=e("9144bfc7a5");c("EvTextInput",B.EvTextInput);const E=e("74e0abef8a");c("EvPolyAnnotation",E.EvPolyAnnotation);const I=i.__importStar(e("484bb85d20"));a.find=I;(0,e("@bokehjs/base").register_models)({DataPipe:n.DataPipe,ImagePipe:p.ImagePipe,ImageDataSource:s.ImageDataSource,SpectraDataSource:r.SpectraDataSource,UpdatableDataSource:S.UpdatableDataSource,WcsTicks:d.WcsTicks,DragTool:l.DragTool,CBResetTool:D.CBResetTool,Tip:u.Tip,TipButton:b.TipButton,SharedDict:g.SharedDict,Showable:P.Showable,BokehAppContext:f.BokehAppContext,EditSpan:h.EditSpan,EvTextInput:B.EvTextInput,EvPolyAnnotation:E.EvPolyAnnotation})},
|
|
46
|
+
"2295368b65": function _(e,s,t,i,n){var o;i();const a=e("@bokehjs/models/sources/data_source"),c=e("e3901fa9f2"),r=e("@bokehjs/core/util/callbacks"),l=e("5179d11e71");class d extends a.DataSource{constructor(e){super(e),this.send_queue={},this.connection_queue=[],this.pending={},this.incoming_callbacks={},this.session_id=casalib.object_id(this)}isColab(){return void 0!==window.google&&void 0!==window.google.colab&&void 0!==window.google.colab.kernel}async getWebSocketUrl(){const[e,s]=this.address;if(this.isColab())try{const e=window.google,t=(await e.colab.kernel.proxyPort(s,{cache:!0})).replace(/^https:/,"wss:");return console.log(`Colab proxy URL for port ${s}: ${t}`),t}catch(t){return console.error("Error getting Colab proxy URL:",t),`ws://${e}:${s}`}return`ws://${e}:${s}`}checkSessionConflict(){try{if("undefined"==typeof Storage)return console.warn("localStorage not available, skipping session conflict detection"),!0;const e=localStorage.getItem(this.session_storage_key);if(e){const s=JSON.parse(e);if(s.sessionId!==this.session_id&&Date.now()-s.timestamp<12e4){if(this.conflict_check){const e=`CubeVis DataPipe (${this.instance_key}) is already running in another browser window or tab.\n\nPlease close other instances and refresh this page, or\nclose this window to continue using the other instance.`;return alert(e),window.opener||1===window.history.length?window.close():window.location.href="about:blank",!1}console.group(`DataPipe ${this.instance_key} conflict detected in Jupyter context`),console.log("Current session ID:",this.session_id),console.log("Existing session ID:",s.sessionId),console.log("Existing timestamp:",new Date(s.timestamp).toISOString()),console.log("Age of existing session (ms):",Date.now()-s.timestamp),console.log("Address:",this.address),console.log("Instance key:",this.instance_key),console.log("Storage key:",this.session_storage_key),console.log("Existing data:",s),console.log("All localStorage keys:",Object.keys(localStorage).filter((e=>e.startsWith("cubevis_datapipe_")))),console.groupEnd()}}return this.updateSessionHeartbeat(),!0}catch(e){return console.warn("Session conflict detection failed:",e),!0}}updateSessionHeartbeat(){try{"undefined"!=typeof Storage&&localStorage.setItem(this.session_storage_key,JSON.stringify({sessionId:this.session_id,timestamp:Date.now(),instanceKey:this.instance_key}))}catch(e){console.warn("Session heartbeat update failed:",e)}}startHeartbeat(){this.heartbeat_interval=window.setInterval((()=>{this.updateSessionHeartbeat()}),3e4)}stopHeartbeat(){this.heartbeat_interval&&(clearInterval(this.heartbeat_interval),this.heartbeat_interval=void 0)}cleanupSession(){try{if("undefined"!=typeof Storage){const e=localStorage.getItem(this.session_storage_key);if(e){JSON.parse(e).sessionId===this.session_id&&localStorage.removeItem(this.session_storage_key)}}}catch(e){console.warn("Session cleanup failed:",e)}this.stopHeartbeat()}handleSessionConflictMessage(e){console.error("Session conflict detected by server:",e);let s="Session conflict detected by server.";"session_conflict"===e.type?s=e.error||s:"session_corruption"===e.type&&(s=`Session corruption detected.\nExpected: ${e.expected}\nReceived: ${e.received}`),alert(s+"\n\nThis window will be closed to prevent data corruption."),this.cleanupSession();const t=new CustomEvent("cubevis_session_conflict",{detail:{message:e,sessionId:this.session_id}});window.dispatchEvent(t),setTimeout((()=>{window.opener||1===window.history.length?window.close():window.location.href="about:blank"}),2e3)}generateInstanceKey(){const e=`${this.address[0]}_${this.address[1]}`;return`${this.instance_id}_${e}`}async initializeWebSocket(){const e=await this.getWebSocketUrl();console.log("datapipe url:",e);var s=void 0;document.shutdown_in_progress_=!1;var t=()=>{void 0!==this.websocket&&this.websocket.close(),this.websocket=new WebSocket(e),this.websocket.binaryType="arraybuffer",this.websocket.addEventListener("error",(e=>{console.log("error encountered:",e)})),this.websocket.onmessage=e=>{if("string"==typeof e.data||e.data instanceof String){let s=(0,c.deserialize)(e.data);if("id"in s&&"direction"in s&&"message"in s){let{id:e,message:t,direction:i}=s;if("error"===i&&("session_conflict"===e||e===this.session_id)&&t&&("session_conflict"===t.type||"session_corruption"===t.type||"close_duplicate"===t.action))return void this.handleSessionConflictMessage(t);if(void 0===t&&console.log("Error, event failure",s),"j2p"==i)if(e in this.pending){let{cb:i}=this.pending[e];if(delete this.pending[e],e in this.send_queue&&this.send_queue[e].length>0){let{cb:s,msg:t}=this.send_queue[e].shift();this.pending[e]={cb:s},this.websocket.send((0,c.serialize)(t))}void 0===t?console.log("DROPPING ERROR FOR NOW (maybe need error callbacks)",s):i(t)}else console.log("message received but could not find id");else if(e in this.incoming_callbacks){let s=this.incoming_callbacks[e](t);this.websocket.send((0,c.serialize)({id:e,direction:i,message:s,session:this.session_id}))}}else console.log(`datapipe received message without one of 'id', 'message' or 'direction': ${s}`)}else console.log("datapipe received binary data",e.data.byteLength,"bytes")},this.websocket.onopen=()=>{for(s?0==s.connected&&console.log(`connection reestablished at ${new Date}`):(this.websocket.send((0,c.serialize)({id:"initialize",direction:"j2p",session:this.session_id})),this.startHeartbeat()),s=new casalib.ReconnectState;this.connection_queue.length>0;){let e=this.connection_queue.shift();this.send.apply(e[0],e[1])}},this.websocket.onclose=()=>{if(s&&1==s.connected&&(console.log(`connection lost at ${new Date}`),s.connected=!1,!document.shutdown_in_progress_)){console.log(`connection lost at ${new Date}`);var e=s;function i(n){0==s.connected&&(console.log(`${n+1}\treconnection attempt ${new Date}`),t(),e.backoff(),e.retries>0?setTimeout(i,e.timeout,n+1):0==s.connected&&console.log(`aborting reconnection after ${n} attempts ${new Date}`))}i(0)}}};window.addEventListener("beforeunload",(()=>{this.cleanupSession()})),document.addEventListener("visibilitychange",(()=>{"hidden"===document.visibilityState?this.stopHeartbeat():"visible"===document.visibilityState&&(this.updateSessionHeartbeat(),this.startHeartbeat())})),t()}initialize(){if(super.initialize(),l.activeDataPipes.register(this),this.instance_key=this.generateInstanceKey(),this.session_storage_key=`cubevis_datapipe_${this.instance_key}`,!this.checkSessionConflict())return;this.initializeWebSocket();(()=>{null!=this.init_script&&(0,r.execute)(this.init_script,this)})()}destroy(){l.activeDataPipes.unregister(this),super.destroy()}register(e,s){this.incoming_callbacks[e]=s}send(e,s,t,i=!1){let n={id:e,message:s,direction:"j2p",session:this.session_id};if(!this.websocket||e in this.pending)if(e in this.send_queue)if("boolean"==typeof i&&i&&this.send_queue[e].length>0)this.send_queue[e][0].msg=n,this.send_queue[e][0].cb=t;else if("function"==typeof i&&this.send_queue[e].length>0){let o=!1;for(const a of this.send_queue[e])i(a.msg.message)&&(a.msg=n,a.cb=t,o=!0);o||this.send_queue[e].push({cb:t,msg:n})}else this.send_queue[e].push({cb:t,msg:n});else this.send_queue[e]=[{cb:t,msg:n}];else if(this.websocket.readyState===WebSocket.CONNECTING)this.connection_queue.push([this,[e,s,t]]);else if(e in this.send_queue&&this.send_queue[e].length>0){this.send_queue[e].push({cb:t,msg:n});{let{cb:r,msg:l}=this.send_queue[e].shift();if(this.pending[e]={cb:r},this.websocket.readyState===WebSocket.OPEN)this.websocket.send((0,c.serialize)(l));else{let d=20,h=this;function u(){h.websocket.readyState===WebSocket.OPEN?h.websocket.send((0,c.serialize)(l)):(d-=1,d>0&&setTimeout(u,3e3))}setTimeout(u,3e3)}}}else if(this.websocket.readyState===WebSocket.OPEN)this.pending[e]={cb:t},this.websocket.send((0,c.serialize)(n));else{let g=20,b=this;function p(){b.websocket.readyState===WebSocket.OPEN?(b.pending[e]={cb:t},b.websocket.send((0,c.serialize)(n))):(g-=1,g>0&&setTimeout(p,3e3))}setTimeout(p,3e3)}}}t.DataPipe=d,o=d,d.__name__="DataPipe",d.__module__="cubevis.bokeh.sources._data_pipe",o.define((({Any:e,Tuple:s,String:t,Number:i,Bool:n})=>({init_script:[e,null],address:[s(t,i)],instance_id:[t],conflict_check:[n,!0]})))},
|
|
47
47
|
"e3901fa9f2": function _(e,r,s,i,o){i();const l=e("@bokehjs/base"),a=e("@bokehjs/core/resolvers"),t=e("@bokehjs/core/serialization/deserializer"),n=e("@bokehjs/core/serialization/serializer"),{deserialize:c}=new class{constructor(){this.resolver=new a.ModelResolver(l.default_resolver),this.deserializer=new t.Deserializer(this.resolver),this.deserialize=e=>{try{return this.deserializer.decode(JSON.parse(e))}catch(r){return console.group("deserialize error"),console.log(e),console.log(r),console.groupEnd(),{}}}}};s.deserialize=c;const{serialize:z}=new class{constructor(){this.serializer=new n.Serializer,this.serialize=e=>JSON.stringify(this.serializer.encode(e))}};s.serialize=z},
|
|
48
48
|
"5179d11e71": function _(a,e,n,c,t){c();const i=a("30b45c52a1");n.activeDataPipes=new i.ModelManager},
|
|
49
49
|
"30b45c52a1": function _(e,n,s,t,i){t();class r{constructor(){this.instances=new Map}register(e){this.instances.set(e.id,e),console.log(`registered instance ${e.id}`)}unregister(e){this.instances.delete(e.id),console.log(`unregistered instance ${e.id}`)}getInstances(){return Array.from(this.instances.values())}getInstance(e){return this.instances.get(e)}}s.ModelManager=r,r.__name__="ModelManager"},
|
|
50
|
-
"2889e0dd45": function _(i,e,
|
|
50
|
+
"2889e0dd45": function _(i,s,e,t,n){var a;t();const o=i("@bokehjs/models/sources/column_data_source"),d=i("2295368b65");class r extends d.DataPipe{constructor(i){super(i),this.position={},this._wcs=null}initialize(){super.initialize(),this.fits_header_json&&(this._wcs=new casalib.coordtxl.WCSTransform(new casalib.coordtxl.MapKeywordProvider(JSON.parse(this.fits_header_json))))}channel(i,s,e){this.position[e]={index:i};let t={action:"channel",index:i,id:e};super.send(this.dataid,t,(i=>{null!=this._histogram_source&&"hist"in i&&"top"in i.hist&&"bottom"in i.hist&&"left"in i.hist&&"right"in i.hist&&(this._histogram_source.data=i.hist),s(i)}))}spectrum(i,s,e,t=!1){let n={action:"spectrum",index:i,id:e};super.send(this.dataid,n,s,t)}adjust_colormap(i,s,e,t,n=!1){const a={action:"adjust-colormap",bounds:i,transfer:s,id:t};super.send(this.dataid,a,e,n)}refresh(i,s,e=[0,0]){let{index:t}=s in this.position?this.position[s]:{index:e};if(2===t.length){let e={action:"channel",index:t,id:s};super.send(this.dataid,e,i)}else if(3===t.length){let e={action:"spectrum",index:t,id:s};super.send(this.dataid,e,i)}}wcs(){return this._wcs}}e.ImagePipe=r,a=r,r.__name__="ImagePipe",r.__module__="cubevis.bokeh.sources._image_pipe",a.define((({Number:i,Nullable:s,String:e,Tuple:t,Ref:n})=>({dataid:[e],shape:[t(i,i,i,i)],fits_header_json:[s(e),null],_histogram_source:[s(n(o.ColumnDataSource)),null]})))},
|
|
51
51
|
"de65005924": function _(s,a,t,c,i){var o;c();const e=s("@bokehjs/models/sources/column_data_source"),n=s("@bokehjs/core/util/string"),u=s("2889e0dd45"),h=s("@bokehjs/core/util/callbacks");class r extends e.ColumnDataSource{constructor(s){super(s),this.imid=(0,n.uuid4)()}_mask_contour(s){const a=casalib.d3.contours().size(this.image_source.shape.slice(0,2)).thresholds([1])(s[0])[0].coordinates.map((s=>s.map((s=>s.reduce(((s,a)=>(s[0].push(a[0]),s[1].push(a[1]),s)),[[],[]])))));return{xs:[a.map((s=>s.map((s=>s[0]))))],ys:[a.map((s=>s.map((s=>s[1]))))]}}initialize(){if(super.initialize(),null!=this._mask_contour_source&&"msk"in this.data&&this.data.msk.length>0&&this.data.msk[0].length>0){const s=this.data.msk;this._mask_contour_source.data=this._mask_contour(s)}void 0===this.last_chan&&(this.last_chan=[this.cur_chan[0].valueOf(),this.cur_chan[1].valueOf()]);(()=>{null!=this.init_script&&(0,h.execute)(this.init_script,this)})()}channel(s,a=0,t){this.image_source.channel([a,s],(c=>{void 0!==c&&void 0!==c.chan||console.log("ImageDataSource ERROR ENCOUNTERED <1>",c),this.last_chan=[this.cur_chan[0].valueOf(),this.cur_chan[1].valueOf()],this.cur_chan=[a,s],null!=this._mask_contour_source&&"chan"in c&&"msk"in c.chan&&(c.msk_contour=this._mask_contour(c.chan.msk),this._mask_contour_source.data=c.msk_contour),t&&t(c),this.data=c.chan}),this.imid)}adjust_colormap(s,a,t){this.image_source.adjust_colormap(s,a,t,this.imid,!0)}signal_change(){this.change.emit()}refresh(s){this.image_source.refresh((a=>{void 0!==a&&void 0!==a.chan||console.log("ImageDataSource ERROR ENCOUNTERED <2>",a),null!=this._mask_contour_source&&"chan"in a&&"msk"in a.chan&&(a.msk_contour=this._mask_contour(a.chan.msk),this._mask_contour_source.data=a.msk_contour),s&&s(a),this.data=a.chan}),this.imid,[0,0])}wcs(){return this.image_source.wcs()}}t.ImageDataSource=r,o=r,r.__name__="ImageDataSource",r.__module__="cubevis.bokeh.sources._image_data_source",o.define((({Tuple:s,Number:a,Ref:t,Nullable:c,Any:i})=>({init_script:[i,null],image_source:[t(u.ImagePipe)],_mask_contour_source:[c(t(e.ColumnDataSource)),null],num_chans:[s(a,a)],cur_chan:[s(a,a)]})))},
|
|
52
52
|
"02e3c3e46c": function _(e,s,i,t,r){var a;t();const c=e("@bokehjs/models/sources/column_data_source"),u=e("@bokehjs/core/util/string"),o=e("2889e0dd45");class _ extends c.ColumnDataSource{constructor(e){super(e),this.imid=(0,u.uuid4)()}initialize(){super.initialize()}spectra(e,s,i=0,t=!1){this.image_source.spectrum([e,s,i],(e=>this.data=e.spectrum),this.imid,t)}refresh(){this.image_source.refresh((e=>this.data=e.spectrum),this.imid,[0,0,0])}}i.SpectraDataSource=_,a=_,_.__name__="SpectraDataSource",_.__module__="cubevis.bokeh.sources._spectra_data_source",a.define((({Ref:e})=>({image_source:[e(o.ImagePipe)]})))},
|
|
53
|
-
"64b16deff9": function _(e,s,i,a
|
|
53
|
+
"64b16deff9": function _(e,s,i,t,a){var n;t();const u=e("@bokehjs/models/sources/column_data_source"),l=e("2295368b65"),o=e("@bokehjs/core/util/callbacks");class c extends u.ColumnDataSource{constructor(e){super(e)}send(e,s){this.pipe.send(this.session_id.valueOf(),{action:"callback",message:e},(e=>{s("result"in e?e.result:{error:`expected to find a "result" in "${e}"`,msg:e})}))}initialize(){super.initialize();(()=>{null!=this.js_init&&(0,o.execute)(this.js_init,this)})()}}i.UpdatableDataSource=c,n=c,c.__name__="UpdatableDataSource",c.__module__="cubevis.bokeh.sources._updatable_data_source",n.define((({Ref:e,Any:s,String:i})=>({js_init:[s,null],js_update:[s,null],pipe:[e(l.DataPipe)],session_id:[i]})))},
|
|
54
54
|
"b6ae454f0d": function _(s,i,o,t,e){var r;t();const a=s("@bokehjs/models/formatters/tick_formatter"),c=s("de65005924");class l extends a.TickFormatter{constructor(s){super(s),this._axis=null,this._coord="world"}initialize(){super.initialize(),"x"==this.axis||"X"==this.axis||"y"==this.axis||"Y"==this.axis?this._axis="x"==this.axis||"X"==this.axis?"x":"y":console.log("ERROR: WcsTicks formatter created with invalid axis:",this.axis)}doFormat(s){const i=[];if(this._axis&&this.image_source.wcs()&&"world"==this._coord)for(let o=0,t=s.length;o<t;o++)if("x"==this._axis){const t=new casalib.coordtxl.Point2D(Number(s[o]),0);this.image_source.wcs().imageToWorldCoords(t,!1),i.push(new casalib.coordtxl.WorldCoords(t.getX(),t.getY()).format(2e3)[0])}else{const t=new casalib.coordtxl.Point2D(0,Number(s[o]));this.image_source.wcs().imageToWorldCoords(t,!1),i.push(new casalib.coordtxl.WorldCoords(t.getX(),t.getY()).format(2e3)[1])}else for(let o=0,t=s.length;o<t;o++)i.push(""+s[o]);return i}coordinates(s){return s!=this._coord&&("world"!=s&&"pixel"!=s||(this._coord=s)),this._coord}}o.WcsTicks=l,r=l,l.__name__="WcsTicks",l.__module__="cubevis.bokeh.format._wcs_ticks",r.define((({Ref:s,String:i})=>({axis:[i],image_source:[s(c.ImageDataSource)]})))},
|
|
55
55
|
"cb7d28d6b3": function _(i,e,t,o,s){var d;o();const l=i("@bokehjs/models/tools/gestures/gesture_tool"),r=i("8fc7a9e935"),_=i("484bb85d20"),m=i("@bokehjs/core/util/callbacks");class a extends l.GestureToolView{_pan_start(i){var e;null===(e=this.model.document)||void 0===e||e.interactive_start(this.plot_view.model);const t=(0,_.px_from_sx)(this.plot_view,i.sx),o=(0,_.py_from_sy)(this.plot_view,i.sy),s=(0,_.dx_from_px)(this.plot_view,t),d=(0,_.dy_from_py)(this.plot_view,o),{start:l}=this.model;l?(0,m.execute)(l,this.model,{sx:t,sy:o,x:s,y:d,delta_x:i.dx,delta_y:-i.dy,shift:"modifiers"in i?i.modifiers.shift:void 0,ctrl:"modifiers"in i?i.modifiers.ctrl:void 0,alt:"modifiers"in i?i.modifiers.alt:void 0}):this.model.trigger_event(new r.DragStart(t,o,s,d,i.dx,-i.dy,i.modifiers))}_pan(i){var e;null===(e=this.model.document)||void 0===e||e.interactive_start(this.plot_view.model);const t=(0,_.px_from_sx)(this.plot_view,i.sx),o=(0,_.py_from_sy)(this.plot_view,i.sy),s=(0,_.dx_from_px)(this.plot_view,t),d=(0,_.dy_from_py)(this.plot_view,o),{move:l}=this.model;l?(0,m.execute)(l,this.model,{sx:t,sy:o,x:s,y:d,delta_x:i.dx,delta_y:-i.dy,shift:"modifiers"in i?i.modifiers.shift:void 0,ctrl:"modifiers"in i?i.modifiers.ctrl:void 0,alt:"modifiers"in i?i.modifiers.alt:void 0}):this.model.trigger_event(new r.Drag(t,o,s,d,i.dx,-i.dy,i.modifiers))}_pan_end(i){const e=(0,_.px_from_sx)(this.plot_view,i.sx),t=(0,_.py_from_sy)(this.plot_view,i.sy),o=(0,_.dx_from_px)(this.plot_view,e),s=(0,_.dy_from_py)(this.plot_view,t),{end:d}=this.model;d?(0,m.execute)(d,this.model,{sx:e,sy:t,x:o,y:s,delta_x:i.dx,delta_y:-i.dy,shift:"modifiers"in i?i.modifiers.shift:void 0,ctrl:"modifiers"in i?i.modifiers.ctrl:void 0,alt:"modifiers"in i?i.modifiers.alt:void 0}):this.model.trigger_event(new r.DragEnd(e,t,o,s,i.dx,-i.dy,i.modifiers))}}t.DragToolView=a,a.__name__="DragToolView";class n extends l.GestureTool{constructor(i){super(i),this.tool_name="Drag",this.event_type="pan",this.default_order=10}}t.DragTool=n,d=n,n.__name__="DragTool",n.__module__="cubevis.bokeh.tools._drag_tool",d.prototype.default_view=a,d.define((({Any:i,Nullable:e})=>({start:[e(i),null],move:[e(i),null],end:[e(i),null]})))},
|
|
56
56
|
"8fc7a9e935": function _(e,t,a,s,_){s();const n=e("@bokehjs/core/bokeh_events");class r extends n.Pan{}a.Drag=r,r.__name__="Drag";class l extends n.PanStart{constructor(e,t,a,s,_,n,r){super(e,t,a,s,r),this.delta_x=_,this.delta_y=n}get event_values(){const{delta_x:e,delta_y:t}=this;return{...super.event_values,delta_x:e,delta_y:t}}}a.DragStart=l,l.__name__="DragStart";class d extends n.PanEnd{constructor(e,t,a,s,_,n,r){super(e,t,a,s,r),this.delta_x=_,this.delta_y=n}get event_values(){const{delta_x:e,delta_y:t}=this;return{...super.event_values,delta_x:e,delta_y:t}}}a.DragEnd=d,d.__name__="DragEnd"},
|
|
@@ -64,4 +64,4 @@
|
|
|
64
64
|
"b55081402e": function _(e,n,t,_,s){var a;_();const o=e("@bokehjs/models/annotations/span"),p=e("@bokehjs/core/bokeh_events");class r extends o.SpanView{on_pan_start(e){const n=super.on_pan_start(e);return this.model.trigger_event(new p.LODStart),n}on_pan(e){super.on_pan(e)}on_pan_end(e){super.on_pan_end(e),this.model.trigger_event(new p.LODEnd)}}t.EditSpanView=r,r.__name__="EditSpanView";class d extends o.Span{constructor(e){super(e)}}t.EditSpan=d,a=d,d.__name__="EditSpan",d.__module__="cubevis.bokeh.models._edit_span",a.prototype.default_view=r},
|
|
65
65
|
"9144bfc7a5": function _(e,t,s,n,r){var i;n();const l=e("@bokehjs/models/widgets/text_input"),o=e("@bokehjs/core/dom"),u=e("@bokehjs/core/bokeh_events");class _ extends l.TextInputView{stylesheets(){return[...super.stylesheets(),new o.InlineStyleSheet(".bk-input-prefix { padding: 0 var(--padding-vertical); }")]}connect_signals(){super.connect_signals(),this.el.addEventListener("mouseenter",(e=>{this.model.trigger_event(new u.MouseEnter(e.screenX,e.screenY,e.x,e.y,{shift:e.shiftKey,ctrl:e.ctrlKey,alt:e.altKey}))})),this.el.addEventListener("mouseleave",(e=>{this.model.trigger_event(new u.MouseLeave(e.screenX,e.screenY,e.x,e.y,{shift:e.shiftKey,ctrl:e.ctrlKey,alt:e.altKey}))}))}render(){super.render()}}s.EvTextInputView=_,_.__name__="EvTextInputView";class c extends l.TextInput{constructor(e){super(e)}}s.EvTextInput=c,i=c,c.__name__="EvTextInput",c.__module__="cubevis.bokeh.models._ev_text_input",i.prototype.default_view=_},
|
|
66
66
|
"74e0abef8a": function _(e,t,n,s,o){var i;s();const r=e("@bokehjs/models/annotations/poly_annotation"),a=e("@bokehjs/core/bokeh_events");class _ extends r.PolyAnnotationView{on_enter(e){const{x_scale:t,y_scale:n}=this.plot_view.frame,s=new a.MouseEnter(e.sx,e.sy,t.invert(e.sx),n.invert(e.sy),{shift:e.modifiers.shift,ctrl:e.modifiers.ctrl,alt:e.modifiers.alt}),o=super.on_enter(e);return this.model.trigger_event(s),o}on_leave(e){const{x_scale:t,y_scale:n}=this.plot_view.frame,s=new a.MouseLeave(e.sx,e.sy,t.invert(e.sx),n.invert(e.sy),{shift:e.modifiers.shift,ctrl:e.modifiers.ctrl,alt:e.modifiers.alt});super.on_leave(e),this.model.trigger_event(s)}on_pan_start(e){const{x_scale:t,y_scale:n}=this.plot_view.frame,s=new a.PanStart(e.sx,e.sy,t.invert(e.sx),n.invert(e.sy),{shift:e.modifiers.shift,ctrl:e.modifiers.ctrl,alt:e.modifiers.alt}),o=super.on_pan_start(e);return this.model.trigger_event(s),o}on_pan_end(e){const{x_scale:t,y_scale:n}=this.plot_view.frame,s=new a.PanEnd(e.sx,e.sy,t.invert(e.sx),n.invert(e.sy),{shift:e.modifiers.shift,ctrl:e.modifiers.ctrl,alt:e.modifiers.alt});super.on_pan_end(e),this.model.trigger_event(s)}on_pan(e){super.on_pan(e);const t=new a.RangesUpdate(e.sx,e.sx+e.dx,e.sy,e.sy+e.dy);this.model.trigger_event(t)}}n.EvPolyAnnotationView=_,_.__name__="EvPolyAnnotationView";class l extends r.PolyAnnotation{constructor(e){super(e)}}n.EvPolyAnnotation=l,i=l,l.__name__="EvPolyAnnotation",l.__module__="cubevis.bokeh.annotations._ev_poly_annotation",i.prototype.default_view=_},
|
|
67
|
-
}, "07c9fde72b", {"index":"07c9fde72b","src/bokeh/sources/data_pipe":"
|
|
67
|
+
}, "07c9fde72b", {"index":"07c9fde72b","src/bokeh/sources/data_pipe":"2295368b65","src/bokeh/util/conversions":"e3901fa9f2","src/bokeh/sources/active_data_pipes":"5179d11e71","src/bokeh/util/model_manager":"30b45c52a1","src/bokeh/sources/image_pipe":"2889e0dd45","src/bokeh/sources/image_data_source":"de65005924","src/bokeh/sources/spectra_data_source":"02e3c3e46c","src/bokeh/sources/updatable_data_source":"64b16deff9","src/bokeh/format/wcs_ticks":"b6ae454f0d","src/bokeh/tools/drag_tool":"cb7d28d6b3","src/bokeh/events":"8fc7a9e935","src/bokeh/util/find":"484bb85d20","src/bokeh/tools/cbreset_tool":"9d3c34ff8e","src/bokeh/models/tip_button":"9f961622ce","src/bokeh/models/tip":"ca4c845905","src/bokeh/models/showable":"a6e757a69a","src/bokeh/models/bokeh_app_context":"467d2716b0","src/bokeh/models/shared_dict":"50a1e32f01","src/bokeh/models/edit_span":"b55081402e","src/bokeh/models/ev_text_input":"9144bfc7a5","src/bokeh/annotations/ev_poly_annotation":"74e0abef8a"}, {});});
|
|
@@ -5,6 +5,7 @@ from bokeh.core.properties import Instance, String
|
|
|
5
5
|
|
|
6
6
|
from bokeh.io import curdoc
|
|
7
7
|
from .. import BokehInit
|
|
8
|
+
from ...utils import is_colab
|
|
8
9
|
|
|
9
10
|
logger = logging.getLogger(__name__)
|
|
10
11
|
|
|
@@ -272,8 +273,11 @@ class Showable(LayoutDOM,BokehInit):
|
|
|
272
273
|
Common logic for generating HTML in notebook environments.
|
|
273
274
|
Returns the HTML string to display, or None if not in a notebook.
|
|
274
275
|
"""
|
|
275
|
-
from bokeh.embed import components
|
|
276
|
+
from bokeh.embed import components, json_item
|
|
276
277
|
from bokeh.io.state import curstate
|
|
278
|
+
from bokeh.resources import CDN
|
|
279
|
+
import sys
|
|
280
|
+
import json as json_lib
|
|
277
281
|
|
|
278
282
|
state = curstate()
|
|
279
283
|
|
|
@@ -284,31 +288,96 @@ class Showable(LayoutDOM,BokehInit):
|
|
|
284
288
|
return '<div style="color: red; padding: 10px; border: 1px solid red;">Showable object with no UI set</div>'
|
|
285
289
|
|
|
286
290
|
if self._display_context:
|
|
287
|
-
self._display_context.on_show(
|
|
291
|
+
self._display_context.on_show()
|
|
288
292
|
|
|
289
293
|
if self._notebook_rendering:
|
|
290
294
|
# Return a lightweight reference instead of re-rendering the full GUI
|
|
291
295
|
return f'''
|
|
292
296
|
<div style="padding: 10px; background: #f0f8f0; border-left: 4px solid #4CAF50; margin: 5px 0;">
|
|
293
|
-
<strong
|
|
297
|
+
<strong>→ iclean GUI active above</strong>
|
|
294
298
|
<small style="color: #666; display: block; margin-top: 5px;">
|
|
295
299
|
Showable ID: {self.id[-8:]} | Backend: Running
|
|
296
300
|
</small>
|
|
297
301
|
</div>
|
|
298
302
|
'''
|
|
299
303
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
304
|
+
if is_colab( ):
|
|
305
|
+
# Get all JS paths from the existing function
|
|
306
|
+
# This returns paths in the correct order:
|
|
307
|
+
# [casalib, bokeh-core, bokeh-widgets, bokeh-tables, cubevisjs]
|
|
308
|
+
from cubevis.bokeh import get_bokeh_js_paths
|
|
309
|
+
js_paths = get_bokeh_js_paths( )
|
|
310
|
+
|
|
311
|
+
# Build script tags for all libraries in order
|
|
312
|
+
all_scripts = '\n'.join([
|
|
313
|
+
f'<script type="text/javascript" src="{url}"></script>'
|
|
314
|
+
for url in js_paths
|
|
315
|
+
])
|
|
316
|
+
|
|
317
|
+
print( "-----scripts-being-used-----------------------------------------------" )
|
|
318
|
+
print( all_scripts )
|
|
319
|
+
print( "----------------------------------------------------------------------" )
|
|
320
|
+
|
|
321
|
+
# Use json_item approach which is more reliable in iframes
|
|
322
|
+
item = json_item(self, target=f"bokeh-{self.id}")
|
|
323
|
+
item_json = json_lib.dumps(item)
|
|
324
|
+
|
|
325
|
+
# Build complete HTML with proper loading sequence
|
|
326
|
+
# get_bokeh_js_paths() already returns libs in the correct order:
|
|
327
|
+
# 1. casalib (third-party libs for CustomJS)
|
|
328
|
+
# 2. bokeh-core
|
|
329
|
+
# 3. bokeh-widgets
|
|
330
|
+
# 4. bokeh-tables
|
|
331
|
+
# 5. cubevisjs (custom Bokeh models)
|
|
332
|
+
html = f'''
|
|
333
|
+
{f'<link href="{CDN.css_files[0]}" rel="stylesheet" type="text/css">' if CDN.css_files else ""}
|
|
334
|
+
<div id="bokeh-{self.id}" class="bk-root"></div>
|
|
335
|
+
{all_scripts}
|
|
336
|
+
<script type="text/javascript">
|
|
337
|
+
(function() {{
|
|
338
|
+
var item = {item_json};
|
|
339
|
+
|
|
340
|
+
function embedWhenReady() {{
|
|
341
|
+
// Check if all required libraries are loaded
|
|
342
|
+
if (typeof Bokeh !== 'undefined' && Bokeh.embed) {{
|
|
343
|
+
var target = document.getElementById("bokeh-{self.id}");
|
|
344
|
+
if (target) {{
|
|
345
|
+
try {{
|
|
346
|
+
Bokeh.embed.embed_item(item);
|
|
347
|
+
console.log("Bokeh plot embedded successfully");
|
|
348
|
+
}} catch(e) {{
|
|
349
|
+
console.error("Error embedding Bokeh plot:", e);
|
|
350
|
+
}}
|
|
351
|
+
}} else {{
|
|
352
|
+
console.error("Target element not found");
|
|
353
|
+
setTimeout(embedWhenReady, 50);
|
|
354
|
+
}}
|
|
355
|
+
}} else {{
|
|
356
|
+
setTimeout(embedWhenReady, 50);
|
|
357
|
+
}}
|
|
358
|
+
}}
|
|
359
|
+
|
|
360
|
+
if (document.readyState === 'loading') {{
|
|
361
|
+
document.addEventListener('DOMContentLoaded', embedWhenReady);
|
|
362
|
+
}} else {{
|
|
363
|
+
embedWhenReady();
|
|
364
|
+
}}
|
|
365
|
+
}})();
|
|
366
|
+
</script>
|
|
367
|
+
'''
|
|
305
368
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
self._start_backend()
|
|
369
|
+
if start_backend:
|
|
370
|
+
self._start_backend()
|
|
309
371
|
|
|
310
|
-
|
|
311
|
-
|
|
372
|
+
self._notebook_rendering = html
|
|
373
|
+
return html
|
|
374
|
+
else:
|
|
375
|
+
# In Jupyter Lab/Classic, use components() as before
|
|
376
|
+
script, div = components(self)
|
|
377
|
+
if start_backend:
|
|
378
|
+
self._start_backend()
|
|
379
|
+
self._notebook_rendering = f'{script}\n{div}'
|
|
380
|
+
return self._notebook_rendering
|
|
312
381
|
|
|
313
382
|
def _repr_mimebundle_(self, include=None, exclude=None):
|
|
314
383
|
"""
|
|
@@ -43,7 +43,7 @@ from bokeh.util.compiler import TypeScript
|
|
|
43
43
|
from bokeh.core.properties import Tuple, String, Int, Instance, Nullable, Bool
|
|
44
44
|
from bokeh.models.callbacks import Callback
|
|
45
45
|
|
|
46
|
-
from ...utils import serialize, deserialize, is_interactive_jupyter
|
|
46
|
+
from ...utils import serialize, deserialize, is_interactive_jupyter, is_colab
|
|
47
47
|
from ..state import casalib_url, cubevisjs_url
|
|
48
48
|
from .. import BokehInit
|
|
49
49
|
|
|
@@ -86,6 +86,27 @@ class DataPipe(DataSource,BokehInit):
|
|
|
86
86
|
###################################################################
|
|
87
87
|
#__javascript__ = [ casalib_url( ), cubevisjs_url( ) ]
|
|
88
88
|
|
|
89
|
+
def _expose_colab_port(self):
|
|
90
|
+
"""Expose the WebSocket port through Colab's proxy"""
|
|
91
|
+
try:
|
|
92
|
+
from google.colab import output
|
|
93
|
+
port = self.address[1]
|
|
94
|
+
|
|
95
|
+
# Use serve_kernel_port_as_iframe for newer Colab
|
|
96
|
+
# This doesn't open a popup, just registers the port
|
|
97
|
+
try:
|
|
98
|
+
output.serve_kernel_port_as_iframe(port)
|
|
99
|
+
print(f"✓ Colab: Exposed WebSocket port {port} via iframe proxy")
|
|
100
|
+
except AttributeError:
|
|
101
|
+
# Fallback to older method
|
|
102
|
+
output.serve_kernel_port_as_window(port)
|
|
103
|
+
print(f"✓ Colab: Exposed WebSocket port {port} via window proxy")
|
|
104
|
+
|
|
105
|
+
except Exception as e:
|
|
106
|
+
print(f"⚠ Warning: Could not expose port {port} in Colab: {e}")
|
|
107
|
+
import traceback
|
|
108
|
+
traceback.print_exc()
|
|
109
|
+
|
|
89
110
|
def __init__( self, *args, abort=None, **kwargs ):
|
|
90
111
|
|
|
91
112
|
if 'conflict_check' not in kwargs:
|
|
@@ -106,6 +127,10 @@ class DataPipe(DataSource,BokehInit):
|
|
|
106
127
|
if self.__abort is not None and not callable(self.__abort):
|
|
107
128
|
raise RuntimeError(f'abort function must be callable ({type(self.__abort)} is not)')
|
|
108
129
|
|
|
130
|
+
# Expose port in Colab
|
|
131
|
+
if is_colab( ):
|
|
132
|
+
self._expose_colab_port()
|
|
133
|
+
|
|
109
134
|
def __enqueue_send( self, ident, msg, callback ):
|
|
110
135
|
### it is assumed that this is called AFTER the lock has been aquired
|
|
111
136
|
if ident in self.__send_queue:
|
|
@@ -266,6 +291,8 @@ class DataPipe(DataSource,BokehInit):
|
|
|
266
291
|
self.__websocket = websocket
|
|
267
292
|
session_established = False
|
|
268
293
|
|
|
294
|
+
print(f"✓ WebSocket server received connection on port {self.address[1]}")
|
|
295
|
+
|
|
269
296
|
async for message in websocket:
|
|
270
297
|
msg = deserialize(message)
|
|
271
298
|
if 'session' not in msg:
|
|
@@ -321,6 +321,13 @@ def order_bokeh_js():
|
|
|
321
321
|
resources.Resources.js_files = property(js_files)
|
|
322
322
|
return
|
|
323
323
|
|
|
324
|
+
#def get_bokeh_js_paths( ):
|
|
325
|
+
# modes = ['cdn','inline','server','server-dev','relative','relative-dev','absolute','absolute-dev']
|
|
326
|
+
# return { 'new': { mode: resources.Resources(mode=mode).js_files for mode in modes },
|
|
327
|
+
# 'old': { mode: resources.Resources(mode=mode)._old_js_files for mode in modes } }
|
|
328
|
+
def get_bokeh_js_paths( ):
|
|
329
|
+
return resources.Resources(mode='cdn').js_files
|
|
330
|
+
|
|
324
331
|
def get_jupyter_state( ):
|
|
325
332
|
"""Get the package-level Jupyter state"""
|
|
326
333
|
return _JUPYTER_STATE
|
|
@@ -1082,7 +1082,7 @@ class CubeMask:
|
|
|
1082
1082
|
### Firefox incorrectly sizes the colormap histogram plot resulting in the right
|
|
1083
1083
|
### side being outside of the browser window... this may have to be tweaked again
|
|
1084
1084
|
### when Jupyter notebooks are supported...
|
|
1085
|
-
( [ Spacer( width=120 ) ] if have_firefox( ) else [ ] ), sizing_mode='stretch_both' ),
|
|
1085
|
+
( [ Spacer( width=120 ) ] if not is_interactive_jupyter( ) and have_firefox( ) else [ ] ), sizing_mode='stretch_both' ),
|
|
1086
1086
|
row( Tip( self._cm_adjust['min input'],
|
|
1087
1087
|
tooltip=Tooltip( content=HTML("set minimum clip here or drag the left red line above"),
|
|
1088
1088
|
position="top" ) ),
|
|
@@ -43,7 +43,7 @@ from ._regions import polygon_indexes
|
|
|
43
43
|
from ._docenum import DocEnum
|
|
44
44
|
from ._copydoc import copydoc
|
|
45
45
|
from ._pkgs import find_pkg, load_pkg
|
|
46
|
-
from ._jupyter import is_interactive_jupyter
|
|
46
|
+
from ._jupyter import is_interactive_jupyter, is_colab
|
|
47
47
|
from ._browser import have_firefox
|
|
48
48
|
from ._git import max_git_version
|
|
49
49
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
1
3
|
import logging
|
|
2
4
|
|
|
3
5
|
logger = logging.getLogger(__name__)
|
|
@@ -17,6 +19,15 @@ logger = logging.getLogger(__name__)
|
|
|
17
19
|
# except NameError:
|
|
18
20
|
# return False
|
|
19
21
|
|
|
22
|
+
def is_colab():
|
|
23
|
+
"""
|
|
24
|
+
Detects if the current environment is Google Colab.
|
|
25
|
+
Combines module check (process-level) and env-var check (VM-level).
|
|
26
|
+
"""
|
|
27
|
+
# 1. Check for the Colab-specific environment variable (VM level)
|
|
28
|
+
# 2. Check for the google.colab module (Python process level)
|
|
29
|
+
return os.getenv("COLAB_RELEASE_TAG") is not None or 'google.colab' in sys.modules
|
|
30
|
+
|
|
20
31
|
def is_interactive_jupyter( ) -> bool:
|
|
21
32
|
"""
|
|
22
33
|
Detect if running in an interactive Jupyter notebook with frontend connection.
|
|
@@ -25,6 +36,7 @@ def is_interactive_jupyter( ) -> bool:
|
|
|
25
36
|
- Interactive Jupyter notebook/lab with frontend (returns True)
|
|
26
37
|
- Standalone Jupyter kernel without frontend (returns False)
|
|
27
38
|
- Regular Python interpreter (returns False)
|
|
39
|
+
- Support Google Colab and legacy Jupyter versions.
|
|
28
40
|
|
|
29
41
|
Returns:
|
|
30
42
|
bool: True if running in interactive Jupyter with frontend, False otherwise
|
|
@@ -37,12 +49,21 @@ def is_interactive_jupyter( ) -> bool:
|
|
|
37
49
|
logger.debug(f"\tis_interactive_jupyter<1>: False")
|
|
38
50
|
return False
|
|
39
51
|
|
|
40
|
-
#
|
|
41
|
-
|
|
52
|
+
# Allow Colab's 'Shell' class in addition to standard 'ZMQInteractiveShell'
|
|
53
|
+
shell_class = ipython.__class__.__name__
|
|
54
|
+
is_colab = 'google.colab' in sys.modules
|
|
55
|
+
|
|
56
|
+
# Check if we're in a ZMQ-based shell (kernel) or Colab's 'Shell'
|
|
57
|
+
if shell_class not in ['ZMQInteractiveShell', 'Shell'] and not is_colab:
|
|
42
58
|
logger.debug(f"\tis_interactive_jupyter<2>: False")
|
|
43
59
|
return False
|
|
44
60
|
|
|
45
|
-
#
|
|
61
|
+
# If we are in Colab, the existence of the shell itself implies
|
|
62
|
+
# an interactive frontend, as Colab sessions are inherently interactive.
|
|
63
|
+
if is_colab:
|
|
64
|
+
return True
|
|
65
|
+
|
|
66
|
+
# Check for active frontend connection (Standard Jupyter/Legacy)
|
|
46
67
|
if hasattr(ipython, 'kernel') and ipython.kernel is not None:
|
|
47
68
|
kernel = ipython.kernel
|
|
48
69
|
|
|
@@ -51,14 +72,15 @@ def is_interactive_jupyter( ) -> bool:
|
|
|
51
72
|
# For newer Jupyter versions, check connection count
|
|
52
73
|
if hasattr(kernel, 'connection_count'):
|
|
53
74
|
logger.debug(f"\tis_interactive_jupyter<3>: {kernel.connection_count > 0}")
|
|
54
|
-
|
|
75
|
+
if kernel.connection_count > 0:
|
|
76
|
+
return True
|
|
55
77
|
|
|
56
78
|
# For older versions, check if socket is connected
|
|
57
79
|
try:
|
|
58
80
|
# Try to get socket state - if it fails, likely no frontend
|
|
59
|
-
socket_state = kernel.shell_socket.closed
|
|
60
81
|
logger.debug(f"\tis_interactive_jupyter<4>: {not socket_state}")
|
|
61
|
-
|
|
82
|
+
if not kernel.shell_socket.closed:
|
|
83
|
+
return True
|
|
62
84
|
except AttributeError:
|
|
63
85
|
pass
|
|
64
86
|
|
|
@@ -68,7 +90,8 @@ def is_interactive_jupyter( ) -> bool:
|
|
|
68
90
|
parent = kernel.get_parent()
|
|
69
91
|
# If there's a parent message, we're likely in interactive mode
|
|
70
92
|
logger.debug(f"\tis_interactive_jupyter<5>: {parent is not None and len(parent) > 0}")
|
|
71
|
-
|
|
93
|
+
if parent is not None and len(parent) > 0:
|
|
94
|
+
return True
|
|
72
95
|
except Exception:
|
|
73
96
|
pass
|
|
74
97
|
|
|
@@ -77,12 +100,12 @@ def is_interactive_jupyter( ) -> bool:
|
|
|
77
100
|
logger.debug(f"\tis_interactive_jupyter<6>: True")
|
|
78
101
|
return True
|
|
79
102
|
|
|
80
|
-
# Fallback: Check for
|
|
81
|
-
# This catches cases where kernel introspection doesn't work
|
|
82
|
-
import os
|
|
103
|
+
# Fallback: Check for environment indicators (Legacy/Containerized Jupyter)
|
|
83
104
|
jupyter_indicators = [
|
|
84
|
-
'JPY_PARENT_PID',
|
|
105
|
+
'JPY_PARENT_PID', # JupyterLab/Notebook sets this
|
|
85
106
|
'JUPYTER_RUNTIME_DIR',
|
|
107
|
+
'COLAB_RELEASE_DEVICE', # Additional Colab-specific env check
|
|
108
|
+
'COLAB_GPU' # Additional Colab-specific env check
|
|
86
109
|
]
|
|
87
110
|
|
|
88
111
|
for indicator in jupyter_indicators:
|
|
@@ -99,6 +122,6 @@ def is_interactive_jupyter( ) -> bool:
|
|
|
99
122
|
logger.debug(f"\tis_interactive_jupyter<8>: False")
|
|
100
123
|
return False
|
|
101
124
|
|
|
102
|
-
except ImportError:
|
|
125
|
+
except (ImportError, Exception):
|
|
103
126
|
logger.debug(f"\tis_interactive_jupyter<9>: False")
|
|
104
127
|
return False
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cubevis-1.0.21 → cubevis-1.0.33}/tests/manual/cubemask-demo/image-slider-spectra-done-stats.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|