fitsview 0.3.5.dev0__tar.gz → 0.4.0__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.
Files changed (83) hide show
  1. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/.gitignore +1 -0
  2. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/PKG-INFO +2 -2
  3. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/fitsview/_version.py +1 -1
  4. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/fitsview/labextension/package.json +1 -1
  5. fitsview-0.3.5.dev0/fitsview/labextension/static/7b93d2a8e325f02dc768.wasm → fitsview-0.4.0/fitsview/labextension/static/363f87cc06bfb5adac71.wasm +0 -0
  6. fitsview-0.4.0/fitsview/labextension/static/55.13fa04ce988048ddf392.js +1 -0
  7. fitsview-0.4.0/fitsview/labextension/static/728.eef262677d8cfd2e5451.js +1 -0
  8. fitsview-0.4.0/fitsview/labextension/static/764.6a51334b6670a55d4119.js +1 -0
  9. fitsview-0.4.0/fitsview/labextension/static/777.39bf348560d484e689b7.js +1 -0
  10. fitsview-0.4.0/fitsview/labextension/static/remoteEntry.2ca47d3c0d5292b9b593.js +1 -0
  11. fitsview-0.4.0/src/viewarr.d.ts +87 -0
  12. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/src/widget.ts +72 -101
  13. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/style/base.css +16 -66
  14. fitsview-0.4.0/ui-tests/tests/fitsview.spec.ts +149 -0
  15. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/README.md +1 -1
  16. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/js/index.d.ts +64 -0
  17. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/js/index.js +90 -0
  18. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/pkg/README.md +1 -1
  19. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/pkg/viewarr.d.ts +43 -6
  20. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/pkg/viewarr.js +84 -17
  21. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/pkg/viewarr_bg.wasm +0 -0
  22. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/pkg/viewarr_bg.wasm.d.ts +10 -6
  23. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/pkg/wrapper.d.ts +64 -0
  24. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/pkg/wrapper.js +90 -0
  25. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/src/app.rs +41 -1
  26. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/src/lib.rs +97 -16
  27. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/src/transform.rs +158 -61
  28. fitsview-0.4.0/viewarr/src/widget.rs +4602 -0
  29. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/yarn.lock +2 -2
  30. fitsview-0.3.5.dev0/fitsview/labextension/static/55.63ee9ee87c7737f48ec6.js +0 -1
  31. fitsview-0.3.5.dev0/fitsview/labextension/static/728.d181c6f11da84a449851.js +0 -1
  32. fitsview-0.3.5.dev0/fitsview/labextension/static/764.754d0996bf96c92a233c.js +0 -1
  33. fitsview-0.3.5.dev0/fitsview/labextension/static/777.7bc4a6d6820f793b0d35.js +0 -1
  34. fitsview-0.3.5.dev0/fitsview/labextension/static/remoteEntry.e33d64c8966dcb0c9630.js +0 -1
  35. fitsview-0.3.5.dev0/src/viewarr.d.ts +0 -43
  36. fitsview-0.3.5.dev0/ui-tests/tests/fitsview.spec.ts +0 -81
  37. fitsview-0.3.5.dev0/viewarr/src/widget.rs +0 -2029
  38. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/.copier-answers.yml +0 -0
  39. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/.prettierignore +0 -0
  40. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/.yarnrc.yml +0 -0
  41. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/AGENTS.md +0 -0
  42. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/CHANGELOG.md +0 -0
  43. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/LICENSE +0 -0
  44. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/README.md +0 -0
  45. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/babel.config.js +0 -0
  46. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/conftest.py +0 -0
  47. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/fitsview/__init__.py +0 -0
  48. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/fitsview/handlers.py +0 -0
  49. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/fitsview/labextension/static/style.js +0 -0
  50. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/fitsview/labextension/static/third-party-licenses.json +0 -0
  51. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/fitsview/tests/__init__.py +0 -0
  52. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/fitsview/tests/generate_files.py +0 -0
  53. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/fitsview/tests/test_handlers.py +0 -0
  54. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/install.json +0 -0
  55. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/jest.config.js +0 -0
  56. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/jupyter-config/server-config/fitsview.json +0 -0
  57. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/package.json +0 -0
  58. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/pyproject.toml +0 -0
  59. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/src/__tests__/fitsview.spec.ts +0 -0
  60. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/src/handler.ts +0 -0
  61. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/src/index.ts +0 -0
  62. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/style/index.css +0 -0
  63. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/style/index.js +0 -0
  64. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/tsconfig.json +0 -0
  65. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/tsconfig.test.json +0 -0
  66. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/ui-tests/README.md +0 -0
  67. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/ui-tests/jupyter_server_test_config.py +0 -0
  68. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/ui-tests/package.json +0 -0
  69. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/ui-tests/playwright.config.js +0 -0
  70. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/ui-tests/yarn.lock +0 -0
  71. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/uv.lock +0 -0
  72. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/.gitignore +0 -0
  73. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/.vscode/settings.json +0 -0
  74. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/Cargo.toml +0 -0
  75. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/LICENSE +0 -0
  76. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/build.rs +0 -0
  77. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/generate_colormaps.py +0 -0
  78. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/package-lock.json +0 -0
  79. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/package.json +0 -0
  80. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/pkg/LICENSE +0 -0
  81. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/pkg/package.json +0 -0
  82. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/src/colormap.rs +0 -0
  83. {fitsview-0.3.5.dev0 → fitsview-0.4.0}/viewarr/src/colormap_luts.rs +0 -0
@@ -17,6 +17,7 @@ fitsview/_version.py
17
17
  # Integration tests
18
18
  ui-tests/test-results/
19
19
  ui-tests/playwright-report/
20
+ ui-tests/screenshots/
20
21
 
21
22
  # Created by https://www.gitignore.io/api/python
22
23
  # Edit at https://www.gitignore.io/?templates=python
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: fitsview
3
- Version: 0.3.5.dev0
3
+ Version: 0.4.0
4
4
  Summary: View FITS astronomical data files in JupyterLab without downloading entire files.
5
5
  Project-URL: Homepage, https://github.com/joseph-long/jupyterlab-fitsview/
6
6
  Project-URL: Bug Tracker, https://github.com/joseph-long/jupyterlab-fitsview/issues
@@ -1,4 +1,4 @@
1
1
  # This file is auto-generated by Hatchling. As such, do not:
2
2
  # - modify
3
3
  # - track in version control e.g. be sure to add to .gitignore
4
- __version__ = VERSION = '0.3.5.dev0'
4
+ __version__ = VERSION = '0.4.0'
@@ -116,7 +116,7 @@
116
116
  "extension": true,
117
117
  "outputDir": "fitsview/labextension",
118
118
  "_build": {
119
- "load": "static/remoteEntry.e33d64c8966dcb0c9630.js",
119
+ "load": "static/remoteEntry.2ca47d3c0d5292b9b593.js",
120
120
  "extension": "./extension",
121
121
  "style": "./style"
122
122
  }
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunkfitsview=self.webpackChunkfitsview||[]).push([[55],{55(e,n,t){t.r(n),t.d(n,{ViewerHandle:()=>_,default:()=>Y,initSync:()=>X});class _{static __wrap(e){e>>>=0;const n=Object.create(_.prototype);return n.__wbg_ptr=e,b.register(n,n.__wbg_ptr,n),n}__destroy_into_raw(){const e=this.__wbg_ptr;return this.__wbg_ptr=0,b.unregister(this),e}free(){const e=this.__destroy_into_raw();G.__wbg_viewerhandle_free(e,0)}clearCallbacks(){G.viewerhandle_clearCallbacks(this.__wbg_ptr)}static create(e){return G.viewerhandle_create(e)}destroy(){G.viewerhandle_destroy(this.__wbg_ptr)}failSliceRequest(e){const n=D(e,G.__wbindgen_malloc),t=H;G.viewerhandle_failSliceRequest(this.__wbg_ptr,n,t)}getBias(){return G.viewerhandle_getBias(this.__wbg_ptr)}getColormap(){let e,n;try{const t=G.viewerhandle_getColormap(this.__wbg_ptr);return e=t[0],n=t[1],E(t[0],t[1])}finally{G.__wbindgen_free(e,n,1)}}getColormapReversed(){return 0!==G.viewerhandle_getColormapReversed(this.__wbg_ptr)}getContrast(){return G.viewerhandle_getContrast(this.__wbg_ptr)}getMarkers(){return G.viewerhandle_getMarkers(this.__wbg_ptr)}getOverlayMessage(){let e,n;try{const t=G.viewerhandle_getOverlayMessage(this.__wbg_ptr);return e=t[0],n=t[1],E(t[0],t[1])}finally{G.__wbindgen_free(e,n,1)}}getPivotPoint(){return G.viewerhandle_getPivotPoint(this.__wbg_ptr)}getRotation(){return G.viewerhandle_getRotation(this.__wbg_ptr)}getShowPivotMarker(){return 0!==G.viewerhandle_getShowPivotMarker(this.__wbg_ptr)}getStretchMode(){let e,n;try{const t=G.viewerhandle_getStretchMode(this.__wbg_ptr);return e=t[0],n=t[1],E(t[0],t[1])}finally{G.__wbindgen_free(e,n,1)}}getValueRange(){return G.viewerhandle_getValueRange(this.__wbg_ptr)}getViewBounds(e,n){return G.viewerhandle_getViewBounds(this.__wbg_ptr,e,n)}getZoom(){return G.viewerhandle_getZoom(this.__wbg_ptr)}onClick(e){G.viewerhandle_onClick(this.__wbg_ptr,e)}onSliceRequest(e){G.viewerhandle_onSliceRequest(this.__wbg_ptr,e)}onStateChange(e){G.viewerhandle_onStateChange(this.__wbg_ptr,e)}setBias(e){G.viewerhandle_setBias(this.__wbg_ptr,e)}setColormap(e){const n=z(e,G.__wbindgen_malloc,G.__wbindgen_realloc),t=H;G.viewerhandle_setColormap(this.__wbg_ptr,n,t)}setColormapReversed(e){G.viewerhandle_setColormapReversed(this.__wbg_ptr,e)}setContrast(e){G.viewerhandle_setContrast(this.__wbg_ptr,e)}setCube(e){const n=D(e,G.__wbindgen_malloc),t=H;G.viewerhandle_setCube(this.__wbg_ptr,n,t)}setImageData(e,n,t,_){const r=z(_,G.__wbindgen_malloc,G.__wbindgen_realloc),c=H,o=G.viewerhandle_setImageData(this.__wbg_ptr,e,n,t,r,c);if(o[1])throw U(o[0])}setMarkers(e){const n=function(e,n){const t=n(4*e.length,4)>>>0;return I().set(e,t/4),H=e.length,t}(e,G.__wbindgen_malloc),t=H;G.viewerhandle_setMarkers(this.__wbg_ptr,n,t)}setOverlayMessage(e){const n=z(e,G.__wbindgen_malloc,G.__wbindgen_realloc),t=H;G.viewerhandle_setOverlayMessage(this.__wbg_ptr,n,t)}setPivotPoint(e,n){G.viewerhandle_setPivotPoint(this.__wbg_ptr,e,n)}setRotation(e){G.viewerhandle_setRotation(this.__wbg_ptr,e)}setShowPivotMarker(e){G.viewerhandle_setShowPivotMarker(this.__wbg_ptr,e)}setSliceData(e,n,t,_,r){const c=z(_,G.__wbindgen_malloc,G.__wbindgen_realloc),o=H,a=D(r,G.__wbindgen_malloc),i=H,b=G.viewerhandle_setSliceData(this.__wbg_ptr,e,n,t,c,o,a,i);if(b[1])throw U(b[0])}setStretchMode(e){const n=z(e,G.__wbindgen_malloc,G.__wbindgen_realloc),t=H;G.viewerhandle_setStretchMode(this.__wbg_ptr,n,t)}setValueRange(e,n){G.viewerhandle_setValueRange(this.__wbg_ptr,e,n)}setViewBounds(e,n,t,_,r,c){G.viewerhandle_setViewBounds(this.__wbg_ptr,e,n,t,_,r,c)}setZoom(e){G.viewerhandle_setZoom(this.__wbg_ptr,e)}zoomIn(){G.viewerhandle_zoomIn(this.__wbg_ptr)}zoomOut(){G.viewerhandle_zoomOut(this.__wbg_ptr)}zoomToFit(){G.viewerhandle_zoomToFit(this.__wbg_ptr)}}function r(){const e={__proto__:null,__wbg___wbindgen_boolean_get_bbbb1c18aa2f5e25:function(e){const n="boolean"==typeof e?e:void 0;return T(n)?16777215:n?1:0},__wbg___wbindgen_debug_string_0bc8482c6e3508ae:function(e,n){const t=z(d(n),G.__wbindgen_malloc,G.__wbindgen_realloc),_=H;x().setInt32(e+4,_,!0),x().setInt32(e+0,t,!0)},__wbg___wbindgen_in_47fa6863be6f2f25:function(e,n){return e in n},__wbg___wbindgen_is_function_0095a73b8b156f76:function(e){return"function"==typeof e},__wbg___wbindgen_is_undefined_9e4d92534c42d778:function(e){return void 0===e},__wbg___wbindgen_number_get_8ff4255516ccad3e:function(e,n){const t="number"==typeof n?n:void 0;x().setFloat64(e+8,T(t)?0:t,!0),x().setInt32(e+0,!T(t),!0)},__wbg___wbindgen_string_get_72fb696202c56729:function(e,n){const t="string"==typeof n?n:void 0;var _=T(t)?0:z(t,G.__wbindgen_malloc,G.__wbindgen_realloc),r=H;x().setInt32(e+4,r,!0),x().setInt32(e+0,_,!0)},__wbg___wbindgen_throw_be289d5034ed271b:function(e,n){throw new Error(E(e,n))},__wbg__wbg_cb_unref_d9b87ff7982e3b21:function(e){e._wbg_cb_unref()},__wbg_activeElement_1554b6917654f8d6:function(e){const n=e.activeElement;return T(n)?0:f(n)},__wbg_activeElement_d9d2a80dfafa67ed:function(e){const n=e.activeElement;return T(n)?0:f(n)},__wbg_activeTexture_6f9a710514686c24:function(e,n){e.activeTexture(n>>>0)},__wbg_activeTexture_7e39cb8fdf4b6d5a:function(e,n){e.activeTexture(n>>>0)},__wbg_addEventListener_c917b5aafbcf493f:function(){return F(function(e,n,t,_,r){e.addEventListener(E(n,t),_,r)},arguments)},__wbg_altKey_73c1173ba53073d5:function(e){return e.altKey},__wbg_altKey_8155c319c215e3aa:function(e){return e.altKey},__wbg_appendChild_dea38765a26d346d:function(){return F(function(e,n){return e.appendChild(n)},arguments)},__wbg_arrayBuffer_05ce1af23e9064e8:function(e){return e.arrayBuffer()},__wbg_at_dfc235641cc0e40c:function(e,n){return e.at(n)},__wbg_attachShader_32114efcf2744eb6:function(e,n,t){e.attachShader(n,t)},__wbg_attachShader_b36058e5c9eeaf54:function(e,n,t){e.attachShader(n,t)},__wbg_bindBuffer_69a7a0b8f3f9b9cf:function(e,n,t){e.bindBuffer(n>>>0,t)},__wbg_bindBuffer_c9068e8712a034f5:function(e,n,t){e.bindBuffer(n>>>0,t)},__wbg_bindTexture_b2b7b1726a83f93e:function(e,n,t){e.bindTexture(n>>>0,t)},__wbg_bindTexture_ec13ddcb9dc8e032:function(e,n,t){e.bindTexture(n>>>0,t)},__wbg_bindVertexArrayOES_c2610602f7485b3f:function(e,n){e.bindVertexArrayOES(n)},__wbg_bindVertexArray_78220d1edb1d2382:function(e,n){e.bindVertexArray(n)},__wbg_blendEquationSeparate_1b12c43928cc7bc1:function(e,n,t){e.blendEquationSeparate(n>>>0,t>>>0)},__wbg_blendEquationSeparate_a8094fbec94cf80e:function(e,n,t){e.blendEquationSeparate(n>>>0,t>>>0)},__wbg_blendFuncSeparate_95465944f788a092:function(e,n,t,_,r){e.blendFuncSeparate(n>>>0,t>>>0,_>>>0,r>>>0)},__wbg_blendFuncSeparate_f366c170c5097fbe:function(e,n,t,_,r){e.blendFuncSeparate(n>>>0,t>>>0,_>>>0,r>>>0)},__wbg_blockSize_ef9a626745d7dfac:function(e){return e.blockSize},__wbg_blur_07f34335e06e5234:function(){return F(function(e){e.blur()},arguments)},__wbg_body_f67922363a220026:function(e){const n=e.body;return T(n)?0:f(n)},__wbg_bottom_c7ec510a18034add:function(e){return e.bottom},__wbg_bufferData_52235e85894af988:function(e,n,t,_){e.bufferData(n>>>0,t,_>>>0)},__wbg_bufferData_98f6c413a8f0f139:function(e,n,t,_){e.bufferData(n>>>0,t,_>>>0)},__wbg_button_d86841d0a03adc44:function(e){return e.button},__wbg_call_389efe28435a9388:function(){return F(function(e,n){return e.call(n)},arguments)},__wbg_call_4708e0c13bdc8e95:function(){return F(function(e,n,t){return e.call(n,t)},arguments)},__wbg_cancelAnimationFrame_cd35895d78cf4510:function(){return F(function(e,n){e.cancelAnimationFrame(n)},arguments)},__wbg_cancel_8f4e3a220b2f0fe1:function(e){e.cancel()},__wbg_changedTouches_b6ab7be7b1aed8d6:function(e){return e.changedTouches},__wbg_clearColor_404a3b16d43db93b:function(e,n,t,_,r){e.clearColor(n,t,_,r)},__wbg_clearColor_f16a5dae33fe425d:function(e,n,t,_,r){e.clearColor(n,t,_,r)},__wbg_clearInterval_c75df0651e74fbb8:function(e,n){e.clearInterval(n)},__wbg_clear_4d801d0d054c3579:function(e,n){e.clear(n>>>0)},__wbg_clear_7187030f892c5ca0:function(e,n){e.clear(n>>>0)},__wbg_clientX_a3c5f4ff30e91264:function(e){return e.clientX},__wbg_clientX_ed7d2827ca30c165:function(e){return e.clientX},__wbg_clientY_79ab4711d0597b2c:function(e){return e.clientY},__wbg_clientY_e28509acb9b4a42a:function(e){return e.clientY},__wbg_clipboardData_018789e461e23aaa:function(e){const n=e.clipboardData;return T(n)?0:f(n)},__wbg_clipboard_98c5a32249fa8416:function(e){return e.clipboard},__wbg_colorMask_177d9762658e5e28:function(e,n,t,_,r){e.colorMask(0!==n,0!==t,0!==_,0!==r)},__wbg_colorMask_7a8dbc86e7376a9b:function(e,n,t,_,r){e.colorMask(0!==n,0!==t,0!==_,0!==r)},__wbg_compileShader_63b824e86bb00b8f:function(e,n){e.compileShader(n)},__wbg_compileShader_94718a93495d565d:function(e,n){e.compileShader(n)},__wbg_contentBoxSize_328a5cd3e7d063a9:function(e){return e.contentBoxSize},__wbg_contentRect_79b98e4d4f4728a4:function(e){return e.contentRect},__wbg_createBuffer_26534c05e01b8559:function(e){const n=e.createBuffer();return T(n)?0:f(n)},__wbg_createBuffer_c4ec897aacc1b91c:function(e){const n=e.createBuffer();return T(n)?0:f(n)},__wbg_createElement_49f60fdcaae809c8:function(){return F(function(e,n,t){return e.createElement(E(n,t))},arguments)},__wbg_createProgram_98aaa91f7c81c5e2:function(e){const n=e.createProgram();return T(n)?0:f(n)},__wbg_createProgram_9b7710a1f2701c2c:function(e){const n=e.createProgram();return T(n)?0:f(n)},__wbg_createShader_e3ac08ed8c5b14b2:function(e,n){const t=e.createShader(n>>>0);return T(t)?0:f(t)},__wbg_createShader_f2b928ca9a426b14:function(e,n){const t=e.createShader(n>>>0);return T(t)?0:f(t)},__wbg_createTexture_16d2c8a3d7d4a75a:function(e){const n=e.createTexture();return T(n)?0:f(n)},__wbg_createTexture_f9451a82c7527ce2:function(e){const n=e.createTexture();return T(n)?0:f(n)},__wbg_createVertexArrayOES_bd76ceee6ab9b95e:function(e){const n=e.createVertexArrayOES();return T(n)?0:f(n)},__wbg_createVertexArray_ad5294951ae57497:function(e){const n=e.createVertexArray();return T(n)?0:f(n)},__wbg_ctrlKey_09a1b54d77dea92b:function(e){return e.ctrlKey},__wbg_ctrlKey_96ff94f8b18636a3:function(e){return e.ctrlKey},__wbg_dataTransfer_d924a622fbe51b06:function(e){const n=e.dataTransfer;return T(n)?0:f(n)},__wbg_data_acd149571f3b741a:function(e,n){const t=n.data;var _=T(t)?0:z(t,G.__wbindgen_malloc,G.__wbindgen_realloc),r=H;x().setInt32(e+4,r,!0),x().setInt32(e+0,_,!0)},__wbg_debug_21bee8b7f5110d62:function(e,n){console.debug(E(e,n))},__wbg_deleteBuffer_22fcc93912cbf659:function(e,n){e.deleteBuffer(n)},__wbg_deleteBuffer_ab099883c168644d:function(e,n){e.deleteBuffer(n)},__wbg_deleteProgram_9298fb3e3c1d3a78:function(e,n){e.deleteProgram(n)},__wbg_deleteProgram_f354e79b8cae8076:function(e,n){e.deleteProgram(n)},__wbg_deleteShader_aaf3b520a64d5d9d:function(e,n){e.deleteShader(n)},__wbg_deleteShader_ff70ca962883e241:function(e,n){e.deleteShader(n)},__wbg_deleteTexture_2be78224e5584a8b:function(e,n){e.deleteTexture(n)},__wbg_deleteTexture_9d411c0e60ffa324:function(e,n){e.deleteTexture(n)},__wbg_deltaMode_a1d1df711e44cefc:function(e){return e.deltaMode},__wbg_deltaX_f0ca9116db5f7bc1:function(e){return e.deltaX},__wbg_deltaY_eb94120160ac821c:function(e){return e.deltaY},__wbg_detachShader_0837532df5c988ca:function(e,n,t){e.detachShader(n,t)},__wbg_detachShader_1ba1e8cb604560a9:function(e,n,t){e.detachShader(n,t)},__wbg_devicePixelContentBoxSize_8f39437eab7f03ea:function(e){return e.devicePixelContentBoxSize},__wbg_devicePixelRatio_5c458affc89fc209:function(e){return e.devicePixelRatio},__wbg_disableVertexAttribArray_24a020060006b10f:function(e,n){e.disableVertexAttribArray(n>>>0)},__wbg_disableVertexAttribArray_4bac633c27bae599:function(e,n){e.disableVertexAttribArray(n>>>0)},__wbg_disable_7fe6fb3e97717f88:function(e,n){e.disable(n>>>0)},__wbg_disable_bd37bdcca1764aea:function(e,n){e.disable(n>>>0)},__wbg_disconnect_5202f399852258c0:function(e){e.disconnect()},__wbg_document_ee35a3d3ae34ef6c:function(e){const n=e.document;return T(n)?0:f(n)},__wbg_drawElements_94f6577070a45da2:function(e,n,t,_,r){e.drawElements(n>>>0,t,_>>>0,r)},__wbg_drawElements_ea2abffa9d1dc736:function(e,n,t,_,r){e.drawElements(n>>>0,t,_>>>0,r)},__wbg_elementFromPoint_c626cb9a65328c63:function(e,n,t){const _=e.elementFromPoint(n,t);return T(_)?0:f(_)},__wbg_elementFromPoint_fcddd007465b6e73:function(e,n,t){const _=e.elementFromPoint(n,t);return T(_)?0:f(_)},__wbg_enableVertexAttribArray_475e06c31777296d:function(e,n){e.enableVertexAttribArray(n>>>0)},__wbg_enableVertexAttribArray_aa6e40408261eeb9:function(e,n){e.enableVertexAttribArray(n>>>0)},__wbg_enable_d1ac04dfdd2fb3ae:function(e,n){e.enable(n>>>0)},__wbg_enable_fee40f19b7053ea3:function(e,n){e.enable(n>>>0)},__wbg_error_541113e32ba1ecbd:function(e,n){let t,_;try{t=e,_=n,console.error(E(e,n))}finally{G.__wbindgen_free(t,_,1)}},__wbg_files_c7608e3fb8eb4d07:function(e){const n=e.files;return T(n)?0:f(n)},__wbg_focus_128ff465f65677cc:function(){return F(function(e){e.focus()},arguments)},__wbg_force_6acda126382fc3c0:function(e){return e.force},__wbg_generateMipmap_5f9058c19cf7c6c1:function(e,n){e.generateMipmap(n>>>0)},__wbg_generateMipmap_c3aad515dd61ffd6:function(e,n){e.generateMipmap(n>>>0)},__wbg_getAttribLocation_16c406a68275ed4b:function(e,n,t,_){return e.getAttribLocation(n,E(t,_))},__wbg_getAttribLocation_7321cf2d67e036f6:function(e,n,t,_){return e.getAttribLocation(n,E(t,_))},__wbg_getBoundingClientRect_b5c8c34d07878818:function(e){return e.getBoundingClientRect()},__wbg_getComputedStyle_2d1f9dfe4ee7e0b9:function(){return F(function(e,n){const t=e.getComputedStyle(n);return T(t)?0:f(t)},arguments)},__wbg_getContext_2a5764d48600bc43:function(){return F(function(e,n,t){const _=e.getContext(E(n,t));return T(_)?0:f(_)},arguments)},__wbg_getData_2aada4ab05d445e3:function(){return F(function(e,n,t,_){const r=z(n.getData(E(t,_)),G.__wbindgen_malloc,G.__wbindgen_realloc),c=H;x().setInt32(e+4,c,!0),x().setInt32(e+0,r,!0)},arguments)},__wbg_getError_1182114725905664:function(e){return e.getError()},__wbg_getError_bba8594facbfd5e1:function(e){return e.getError()},__wbg_getExtension_388df13305a298af:function(){return F(function(e,n,t){const _=e.getExtension(E(n,t));return T(_)?0:f(_)},arguments)},__wbg_getExtension_3c0cb5ae01bb4b17:function(){return F(function(e,n,t){const _=e.getExtension(E(n,t));return T(_)?0:f(_)},arguments)},__wbg_getItem_0c792d344808dcf5:function(){return F(function(e,n,t,_){const r=n.getItem(E(t,_));var c=T(r)?0:z(r,G.__wbindgen_malloc,G.__wbindgen_realloc),o=H;x().setInt32(e+4,o,!0),x().setInt32(e+0,c,!0)},arguments)},__wbg_getParameter_1ecb910cfdd21f88:function(){return F(function(e,n){return e.getParameter(n>>>0)},arguments)},__wbg_getParameter_2e1f97ecaab76274:function(){return F(function(e,n){return e.getParameter(n>>>0)},arguments)},__wbg_getProgramInfoLog_2ffa30e3abb8b5c2:function(e,n,t){const _=n.getProgramInfoLog(t);var r=T(_)?0:z(_,G.__wbindgen_malloc,G.__wbindgen_realloc),c=H;x().setInt32(e+4,c,!0),x().setInt32(e+0,r,!0)},__wbg_getProgramInfoLog_dbfda4b6e7eb1b37:function(e,n,t){const _=n.getProgramInfoLog(t);var r=T(_)?0:z(_,G.__wbindgen_malloc,G.__wbindgen_realloc),c=H;x().setInt32(e+4,c,!0),x().setInt32(e+0,r,!0)},__wbg_getProgramParameter_43fbc6d2613c08b3:function(e,n,t){return e.getProgramParameter(n,t>>>0)},__wbg_getProgramParameter_92e4540ca9da06b2:function(e,n,t){return e.getProgramParameter(n,t>>>0)},__wbg_getPropertyValue_d6911b2a1f9acba9:function(){return F(function(e,n,t,_){const r=z(n.getPropertyValue(E(t,_)),G.__wbindgen_malloc,G.__wbindgen_realloc),c=H;x().setInt32(e+4,c,!0),x().setInt32(e+0,r,!0)},arguments)},__wbg_getRootNode_193e544ed534e810:function(e){return e.getRootNode()},__wbg_getShaderInfoLog_9991e9e77b0c6805:function(e,n,t){const _=n.getShaderInfoLog(t);var r=T(_)?0:z(_,G.__wbindgen_malloc,G.__wbindgen_realloc),c=H;x().setInt32(e+4,c,!0),x().setInt32(e+0,r,!0)},__wbg_getShaderInfoLog_9e0b96da4b13ae49:function(e,n,t){const _=n.getShaderInfoLog(t);var r=T(_)?0:z(_,G.__wbindgen_malloc,G.__wbindgen_realloc),c=H;x().setInt32(e+4,c,!0),x().setInt32(e+0,r,!0)},__wbg_getShaderParameter_786fd84f85720ca8:function(e,n,t){return e.getShaderParameter(n,t>>>0)},__wbg_getShaderParameter_afa4a3dd9dd397c1:function(e,n,t){return e.getShaderParameter(n,t>>>0)},__wbg_getSupportedExtensions_57142a6b598d7787:function(e){const n=e.getSupportedExtensions();return T(n)?0:f(n)},__wbg_getSupportedExtensions_c37f749a951eba04:function(e){const n=e.getSupportedExtensions();return T(n)?0:f(n)},__wbg_getUniformLocation_71c070e6644669ad:function(e,n,t,_){const r=e.getUniformLocation(n,E(t,_));return T(r)?0:f(r)},__wbg_getUniformLocation_d06b3a5b3c60e95c:function(e,n,t,_){const r=e.getUniformLocation(n,E(t,_));return T(r)?0:f(r)},__wbg_get_4fe487fe39ff3573:function(e,n){const t=e[n>>>0];return T(t)?0:f(t)},__wbg_get_5bd55a138a9e899f:function(e,n){const t=e[n>>>0];return T(t)?0:f(t)},__wbg_get_9a1f194723936140:function(e,n){const t=e[n>>>0];return T(t)?0:f(t)},__wbg_get_9b94d73e6221f75c:function(e,n){return e[n>>>0]},__wbg_get_b3ed3ad4be2bc8ac:function(){return F(function(e,n){return Reflect.get(e,n)},arguments)},__wbg_get_index_bbec7c126dd67fce:function(e,n){return e[n>>>0]},__wbg_get_index_efdc399e215e9164:function(e,n){return e[n>>>0]},__wbg_hash_90eadad0e1447454:function(){return F(function(e,n){const t=z(n.hash,G.__wbindgen_malloc,G.__wbindgen_realloc),_=H;x().setInt32(e+4,_,!0),x().setInt32(e+0,t,!0)},arguments)},__wbg_height_38750dc6de41ee75:function(e){return e.height},__wbg_height_c2027cf67d1c9b11:function(e){return e.height},__wbg_hidden_8ce6a98b8c12451c:function(e){return e.hidden},__wbg_host_92d607209031b72c:function(){return F(function(e,n){const t=z(n.host,G.__wbindgen_malloc,G.__wbindgen_realloc),_=H;x().setInt32(e+4,_,!0),x().setInt32(e+0,t,!0)},arguments)},__wbg_hostname_0c450e33386895ba:function(){return F(function(e,n){const t=z(n.hostname,G.__wbindgen_malloc,G.__wbindgen_realloc),_=H;x().setInt32(e+4,_,!0),x().setInt32(e+0,t,!0)},arguments)},__wbg_href_67854c3dd511f6f3:function(){return F(function(e,n){const t=z(n.href,G.__wbindgen_malloc,G.__wbindgen_realloc),_=H;x().setInt32(e+4,_,!0),x().setInt32(e+0,t,!0)},arguments)},__wbg_id_ff64a5892a30d4e9:function(e,n){const t=z(n.id,G.__wbindgen_malloc,G.__wbindgen_realloc),_=H;x().setInt32(e+4,_,!0),x().setInt32(e+0,t,!0)},__wbg_identifier_5feaba602edf9981:function(e){return e.identifier},__wbg_info_2e7d618e9cb88d77:function(e,n){console.info(E(e,n))},__wbg_inlineSize_3e4e7e8c813884fd:function(e){return e.inlineSize},__wbg_instanceof_Document_50f5ff170c1a7826:function(e){let n;try{n=e instanceof Document}catch(e){n=!1}return n},__wbg_instanceof_Element_9e662f49ab6c6beb:function(e){let n;try{n=e instanceof Element}catch(e){n=!1}return n},__wbg_instanceof_HtmlElement_5abfac207260fd6f:function(e){let n;try{n=e instanceof HTMLElement}catch(e){n=!1}return n},__wbg_instanceof_HtmlInputElement_c10b7260b4e0710a:function(e){let n;try{n=e instanceof HTMLInputElement}catch(e){n=!1}return n},__wbg_instanceof_ResizeObserverEntry_16bca25646e32231:function(e){let n;try{n=e instanceof ResizeObserverEntry}catch(e){n=!1}return n},__wbg_instanceof_ResizeObserverSize_cee71be747d9d29e:function(e){let n;try{n=e instanceof ResizeObserverSize}catch(e){n=!1}return n},__wbg_instanceof_ShadowRoot_5285adde3587c73e:function(e){let n;try{n=e instanceof ShadowRoot}catch(e){n=!1}return n},__wbg_instanceof_WebGl2RenderingContext_4a08a94517ed5240:function(e){let n;try{n=e instanceof WebGL2RenderingContext}catch(e){n=!1}return n},__wbg_instanceof_WebGlRenderingContext_53391327f021e3ab:function(e){let n;try{n=e instanceof WebGLRenderingContext}catch(e){n=!1}return n},__wbg_instanceof_Window_ed49b2db8df90359:function(e){let n;try{n=e instanceof Window}catch(e){n=!1}return n},__wbg_isComposing_1eafc5b1376f01d1:function(e){return e.isComposing},__wbg_isComposing_9323fa62320f5fc0:function(e){return e.isComposing},__wbg_isSecureContext_1e186b850f07cfb3:function(e){return e.isSecureContext},__wbg_is_f29129f676e5410c:function(e,n){return Object.is(e,n)},__wbg_item_98b174cdde606b25:function(e,n){const t=e.item(n>>>0);return T(t)?0:f(t)},__wbg_items_4130211600bde9a4:function(e){return e.items},__wbg_keyCode_155291a11654466e:function(e){return e.keyCode},__wbg_key_d41e8e825e6bb0e9:function(e,n){const t=z(n.key,G.__wbindgen_malloc,G.__wbindgen_realloc),_=H;x().setInt32(e+4,_,!0),x().setInt32(e+0,t,!0)},__wbg_lastModified_a5cfce993c651681:function(e){return e.lastModified},__wbg_left_3b7c3c1030d5ca7a:function(e){return e.left},__wbg_length_0a185f5e6b78bcc5:function(e){return e.length},__wbg_length_182cff298f8d099b:function(e){return e.length},__wbg_length_1e8b0a6e52c08b9a:function(e){return e.length},__wbg_length_25b2ccd77d48ecb1:function(e){return e.length},__wbg_length_32ed9a279acd054c:function(e){return e.length},__wbg_length_35a7bace40f36eac:function(e){return e.length},__wbg_length_500e25dbc316fd13:function(e){return e.length},__wbg_length_8ce069301528a78d:function(e){return e.length},__wbg_length_9a7876c9728a0979:function(e){return e.length},__wbg_length_9efde69e99cd464e:function(e){return e.length},__wbg_length_b1593d937f31cef9:function(e){return e.length},__wbg_length_dd7a84decbd9cde7:function(e){return e.length},__wbg_length_e2449a254c768bd8:function(e){return e.length},__wbg_length_f7386240689107f3:function(e){return e.length},__wbg_linkProgram_6600dd2c0863bbfd:function(e,n){e.linkProgram(n)},__wbg_linkProgram_be6b825cf66d177b:function(e,n){e.linkProgram(n)},__wbg_localStorage_a22d31b9eacc4594:function(){return F(function(e){const n=e.localStorage;return T(n)?0:f(n)},arguments)},__wbg_location_df7ca06c93e51763:function(e){return e.location},__wbg_matchMedia_91d4fc9729dc3c84:function(){return F(function(e,n,t){const _=e.matchMedia(E(n,t));return T(_)?0:f(_)},arguments)},__wbg_matches_4b5c22bd830f7bb3:function(e){return e.matches},__wbg_metaKey_374999c340f70626:function(e){return e.metaKey},__wbg_metaKey_67113fb40365d736:function(e){return e.metaKey},__wbg_name_171cddfde96a29c8:function(e,n){const t=z(n.name,G.__wbindgen_malloc,G.__wbindgen_realloc),_=H;x().setInt32(e+4,_,!0),x().setInt32(e+0,t,!0)},__wbg_navigator_43be698ba96fc088:function(e){return e.navigator},__wbg_new_1e41d4ad75c60d04:function(e){return new Int16Array(e)},__wbg_new_2e2be9617c4407d5:function(){return F(function(e){return new ResizeObserver(e)},arguments)},__wbg_new_358bba68c164c0c7:function(){return new Error},__wbg_new_361308b2356cecd0:function(){return new Object},__wbg_new_3eb36ae241fe6f44:function(){return new Array},__wbg_new_4e06668820182522:function(e){return new Uint16Array(e)},__wbg_new_62561633336f4cb6:function(e){return new BigUint64Array(e)},__wbg_new_6860731fa32d2e93:function(e){return new Int8Array(e)},__wbg_new_72c627ba80de1c21:function(e){return new Int32Array(e)},__wbg_new_9ccae8c3d6099588:function(e){return new Float32Array(e)},__wbg_new_b5d9e2fb389fef91:function(e,n){try{var t={a:e,b:n};const _=new Promise((e,n)=>{const _=t.a;t.a=0;try{return function(e,n,t,_){G.wasm_bindgen_90774f07ac80778b___convert__closures_____invoke___wasm_bindgen_90774f07ac80778b___JsValue__wasm_bindgen_90774f07ac80778b___JsValue_____(e,n,t,_)}(_,t.b,e,n)}finally{t.a=_}});return _}finally{t.a=t.b=0}},__wbg_new_d17d15ba1d2042a1:function(e){return new Float64Array(e)},__wbg_new_d9eada177dd1dc88:function(e){return new BigInt64Array(e)},__wbg_new_dd2b680c8bf6ae29:function(e){return new Uint8Array(e)},__wbg_new_ebe5c47b71282e03:function(e){return new Uint32Array(e)},__wbg_new_from_slice_a3d2629dc1826784:function(e,n){return new Uint8Array(y(e,n))},__wbg_new_no_args_1c7c842f08d00ebb:function(e,n){return new Function(E(e,n))},__wbg_new_with_length_63f2683cc2521026:function(e){return new Float32Array(e>>>0)},__wbg_new_with_length_6523745c0bd32809:function(e){return new Float64Array(e>>>0)},__wbg_new_with_record_from_str_to_blob_promise_17d3b40dbba6c99d:function(){return F(function(e){return new ClipboardItem(e)},arguments)},__wbg_new_with_text_c4caedd46c3e5f01:function(){return F(function(e,n){return new SpeechSynthesisUtterance(E(e,n))},arguments)},__wbg_new_with_u8_array_sequence_and_options_cc0f8f2c1ef62e68:function(){return F(function(e,n){return new Blob(e,n)},arguments)},__wbg_now_2c95c9de01293173:function(e){return e.now()},__wbg_now_ebffdf7e580f210d:function(e){return e.now()},__wbg_observe_1ae37077cf10b11b:function(e,n,t){e.observe(n,t)},__wbg_of_f915f7cd925b21a5:function(e){return Array.of(e)},__wbg_offsetTop_e3d5b0a34b3200fc:function(e){return e.offsetTop},__wbg_open_ea44acde696d3b0c:function(){return F(function(e,n,t,_,r){const c=e.open(E(n,t),E(_,r));return T(c)?0:f(c)},arguments)},__wbg_origin_a9c891fa602b4d40:function(){return F(function(e,n){const t=z(n.origin,G.__wbindgen_malloc,G.__wbindgen_realloc),_=H;x().setInt32(e+4,_,!0),x().setInt32(e+0,t,!0)},arguments)},__wbg_performance_06f12ba62483475d:function(e){const n=e.performance;return T(n)?0:f(n)},__wbg_performance_7a3ffd0b17f663ad:function(e){return e.performance},__wbg_pixelStorei_2a65936c11b710fe:function(e,n,t){e.pixelStorei(n>>>0,t)},__wbg_pixelStorei_f7cc498f52d523f1:function(e,n,t){e.pixelStorei(n>>>0,t)},__wbg_port_dc56bc76d55c2b55:function(){return F(function(e,n){const t=z(n.port,G.__wbindgen_malloc,G.__wbindgen_realloc),_=H;x().setInt32(e+4,_,!0),x().setInt32(e+0,t,!0)},arguments)},__wbg_preventDefault_cdcfcd7e301b9702:function(e){e.preventDefault()},__wbg_protocol_4c3b13957de7d079:function(){return F(function(e,n){const t=z(n.protocol,G.__wbindgen_malloc,G.__wbindgen_realloc),_=H;x().setInt32(e+4,_,!0),x().setInt32(e+0,t,!0)},arguments)},__wbg_prototypesetcall_2adb484744144f7f:function(e,n,t){Uint16Array.prototype.set.call(m(e,n),t)},__wbg_prototypesetcall_4846d4aa386c936f:function(e,n,t){Uint32Array.prototype.set.call(p(e,n),t)},__wbg_prototypesetcall_4f65a157230198d8:function(e,n,t){Int8Array.prototype.set.call(h(e,n),t)},__wbg_prototypesetcall_55c7bc6bcd6a9457:function(e,n,t){Int16Array.prototype.set.call(l(e,n),t)},__wbg_prototypesetcall_aefe6319f589ab4b:function(e,n,t){Float64Array.prototype.set.call(s(e,n),t)},__wbg_prototypesetcall_bdcdcc5842e4d77d:function(e,n,t){Uint8Array.prototype.set.call(y(e,n),t)},__wbg_prototypesetcall_c7e6a26aeade796d:function(e,n,t){Float32Array.prototype.set.call(g(e,n),t)},__wbg_prototypesetcall_f8118a9f36fee41e:function(e,n,t){Int32Array.prototype.set.call(w(e,n),t)},__wbg_push_8ffdcb2063340ba5:function(e,n){return e.push(n)},__wbg_queueMicrotask_0aa0a927f78f5d98:function(e){return e.queueMicrotask},__wbg_queueMicrotask_5bb536982f78a56f:function(e){queueMicrotask(e)},__wbg_readPixels_55b18304384e073d:function(){return F(function(e,n,t,_,r,c,o,a){e.readPixels(n,t,_,r,c>>>0,o>>>0,a)},arguments)},__wbg_readPixels_6ea8e288a8673282:function(){return F(function(e,n,t,_,r,c,o,a){e.readPixels(n,t,_,r,c>>>0,o>>>0,a)},arguments)},__wbg_readPixels_95b2464a7bb863a2:function(){return F(function(e,n,t,_,r,c,o,a){e.readPixels(n,t,_,r,c>>>0,o>>>0,a)},arguments)},__wbg_removeEventListener_e63328781a5b9af9:function(){return F(function(e,n,t,_){e.removeEventListener(E(n,t),_)},arguments)},__wbg_remove_31c39325eee968fc:function(e){e.remove()},__wbg_requestAnimationFrame_43682f8e1c5e5348:function(){return F(function(e,n){return e.requestAnimationFrame(n)},arguments)},__wbg_resolve_002c4b7d9d8f6b64:function(e){return Promise.resolve(e)},__wbg_right_154af6c2b1bf0c89:function(e){return e.right},__wbg_scissor_2ff8f18f05a6d408:function(e,n,t,_,r){e.scissor(n,t,_,r)},__wbg_scissor_b870b1434a9c25b4:function(e,n,t,_,r){e.scissor(n,t,_,r)},__wbg_search_1b385e665c888780:function(){return F(function(e,n){const t=z(n.search,G.__wbindgen_malloc,G.__wbindgen_realloc),_=H;x().setInt32(e+4,_,!0),x().setInt32(e+0,t,!0)},arguments)},__wbg_setAttribute_cc8e4c8a2a008508:function(){return F(function(e,n,t,_,r){e.setAttribute(E(n,t),E(_,r))},arguments)},__wbg_setItem_cf340bb2edbd3089:function(){return F(function(e,n,t,_,r){e.setItem(E(n,t),E(_,r))},arguments)},__wbg_setProperty_cbb25c4e74285b39:function(){return F(function(e,n,t,_,r){e.setProperty(E(n,t),E(_,r))},arguments)},__wbg_set_6cb8631f80447a67:function(){return F(function(e,n,t){return Reflect.set(e,n,t)},arguments)},__wbg_set_a7e6b10165583fc4:function(e,n,t){e.set(s(n,t))},__wbg_set_autofocus_7125a4a223a1d570:function(){return F(function(e,n){e.autofocus=0!==n},arguments)},__wbg_set_box_73d3355c6f95f24d:function(e,n){e.box=i[n]},__wbg_set_f8edeec46569cc70:function(e,n,t){e.set(g(n,t))},__wbg_set_height_f21f985387070100:function(e,n){e.height=n>>>0},__wbg_set_once_56ba1b87a9884c15:function(e,n){e.once=0!==n},__wbg_set_pitch_91774e1f0bbc52fa:function(e,n){e.pitch=n},__wbg_set_rate_63dfcd5b7bcdbc07:function(e,n){e.rate=n},__wbg_set_tabIndex_eb89b6ffe111cd2c:function(e,n){e.tabIndex=n},__wbg_set_type_148de20768639245:function(e,n,t){e.type=E(n,t)},__wbg_set_type_abc37fa3c213f717:function(e,n,t){e.type=E(n,t)},__wbg_set_value_62a965e38b22b38c:function(e,n,t){e.value=E(n,t)},__wbg_set_volume_789cc971c19a2e24:function(e,n){e.volume=n},__wbg_set_width_d60bc4f2f20c56a4:function(e,n){e.width=n>>>0},__wbg_shaderSource_32425cfe6e5a1e52:function(e,n,t,_){e.shaderSource(n,E(t,_))},__wbg_shaderSource_8f4bda03f70359df:function(e,n,t,_){e.shaderSource(n,E(t,_))},__wbg_shiftKey_5558a3288542c985:function(e){return e.shiftKey},__wbg_shiftKey_564be91ec842bcc4:function(e){return e.shiftKey},__wbg_size_e05d31cc6049815f:function(e){return e.size},__wbg_speak_67796aeb0b5fd194:function(e,n){e.speak(n)},__wbg_speechSynthesis_95b40351572bb250:function(){return F(function(e){return e.speechSynthesis},arguments)},__wbg_stack_d87a83f5bc721084:function(e,n){const t=z(n.stack,G.__wbindgen_malloc,G.__wbindgen_realloc),_=H;x().setInt32(e+4,_,!0),x().setInt32(e+0,t,!0)},__wbg_static_accessor_GLOBAL_12837167ad935116:function(){const e=void 0===t.g?null:t.g;return T(e)?0:f(e)},__wbg_static_accessor_GLOBAL_THIS_e628e89ab3b1c95f:function(){const e="undefined"==typeof globalThis?null:globalThis;return T(e)?0:f(e)},__wbg_static_accessor_SELF_a621d3dfbb60d0ce:function(){const e="undefined"==typeof self?null:self;return T(e)?0:f(e)},__wbg_static_accessor_WINDOW_f8727f0cf888e0bd:function(){const e="undefined"==typeof window?null:window;return T(e)?0:f(e)},__wbg_stopPropagation_6e5e2a085214ac63:function(e){e.stopPropagation()},__wbg_style_0b7c9bd318f8b807:function(e){return e.style},__wbg_texImage2D_087ef94df78081f0:function(){return F(function(e,n,t,_,r,c,o,a,i,b){e.texImage2D(n>>>0,t,_,r,c,o,a>>>0,i>>>0,b)},arguments)},__wbg_texImage2D_13414a4692836804:function(){return F(function(e,n,t,_,r,c,o,a,i,b){e.texImage2D(n>>>0,t,_,r,c,o,a>>>0,i>>>0,b)},arguments)},__wbg_texImage2D_e71049312f3172d9:function(){return F(function(e,n,t,_,r,c,o,a,i,b){e.texImage2D(n>>>0,t,_,r,c,o,a>>>0,i>>>0,b)},arguments)},__wbg_texParameteri_0d45be2c88d6bad8:function(e,n,t,_){e.texParameteri(n>>>0,t>>>0,_)},__wbg_texParameteri_ec937d2161018946:function(e,n,t,_){e.texParameteri(n>>>0,t>>>0,_)},__wbg_texSubImage2D_19ae4cadb809f264:function(){return F(function(e,n,t,_,r,c,o,a,i,b){e.texSubImage2D(n>>>0,t,_,r,c,o,a>>>0,i>>>0,b)},arguments)},__wbg_texSubImage2D_d17a39cdec4a3495:function(){return F(function(e,n,t,_,r,c,o,a,i,b){e.texSubImage2D(n>>>0,t,_,r,c,o,a>>>0,i>>>0,b)},arguments)},__wbg_texSubImage2D_edf5bd70fda3feaf:function(){return F(function(e,n,t,_,r,c,o,a,i,b){e.texSubImage2D(n>>>0,t,_,r,c,o,a>>>0,i>>>0,b)},arguments)},__wbg_then_0d9fe2c7b1857d32:function(e,n,t){return e.then(n,t)},__wbg_then_b9e7b3b5f1a9e1b5:function(e,n){return e.then(n)},__wbg_top_3d27ff6f468cf3fc:function(e){return e.top},__wbg_touches_55ce167b42bcdf52:function(e){return e.touches},__wbg_type_9a3860e6dd3a4156:function(e,n){const t=z(n.type,G.__wbindgen_malloc,G.__wbindgen_realloc),_=H;x().setInt32(e+4,_,!0),x().setInt32(e+0,t,!0)},__wbg_type_e8c7fade6d73451b:function(e,n){const t=z(n.type,G.__wbindgen_malloc,G.__wbindgen_realloc),_=H;x().setInt32(e+4,_,!0),x().setInt32(e+0,t,!0)},__wbg_uniform1i_9f3f72dbcb98ada9:function(e,n,t){e.uniform1i(n,t)},__wbg_uniform1i_e9aee4b9e7fe8c4b:function(e,n,t){e.uniform1i(n,t)},__wbg_uniform2f_1887b1268f65bfee:function(e,n,t,_){e.uniform2f(n,t,_)},__wbg_uniform2f_2aa77a6395d47f1d:function(e,n,t,_){e.uniform2f(n,t,_)},__wbg_useProgram_e82c1a5f87d81579:function(e,n){e.useProgram(n)},__wbg_useProgram_fe720ade4d3b6edb:function(e,n){e.useProgram(n)},__wbg_userAgent_34463fd660ba4a2a:function(){return F(function(e,n){const t=z(n.userAgent,G.__wbindgen_malloc,G.__wbindgen_realloc),_=H;x().setInt32(e+4,_,!0),x().setInt32(e+0,t,!0)},arguments)},__wbg_value_e506a07878790ca0:function(e,n){const t=z(n.value,G.__wbindgen_malloc,G.__wbindgen_realloc),_=H;x().setInt32(e+4,_,!0),x().setInt32(e+0,t,!0)},__wbg_vertexAttribPointer_75f6ff47f6c9f8cb:function(e,n,t,_,r,c,o){e.vertexAttribPointer(n>>>0,t,_>>>0,0!==r,c,o)},__wbg_vertexAttribPointer_adbd1853cce679ad:function(e,n,t,_,r,c,o){e.vertexAttribPointer(n>>>0,t,_>>>0,0!==r,c,o)},__wbg_viewerhandle_new:function(e){return _.__wrap(e)},__wbg_viewport_174ae1c2209344ae:function(e,n,t,_,r){e.viewport(n,t,_,r)},__wbg_viewport_df236eac68bc7467:function(e,n,t,_,r){e.viewport(n,t,_,r)},__wbg_warn_11b4e4f7bff9ffb7:function(e,n){console.warn(E(e,n))},__wbg_width_5f66bde2e810fbde:function(e){return e.width},__wbg_width_7444cca5dfea0645:function(e){return e.width},__wbg_writeText_be1c3b83a3e46230:function(e,n,t){return e.writeText(E(n,t))},__wbg_write_d429ce72e918e180:function(e,n){return e.write(n)},__wbindgen_cast_0000000000000001:function(e,n){return V(e,n,G.wasm_bindgen_90774f07ac80778b___closure__destroy___dyn_core_d941ad8722425d2e___ops__function__FnMut__js_sys_88d3431ccd25c44___Array____Output_______,o)},__wbindgen_cast_0000000000000002:function(e,n){return V(e,n,G.wasm_bindgen_90774f07ac80778b___closure__destroy___dyn_core_d941ad8722425d2e___ops__function__FnMut__js_sys_88d3431ccd25c44___Array____Output_______,o)},__wbindgen_cast_0000000000000003:function(e,n){return V(e,n,G.wasm_bindgen_90774f07ac80778b___closure__destroy___dyn_core_d941ad8722425d2e___ops__function__FnMut__js_sys_88d3431ccd25c44___Array____Output_______,c)},__wbindgen_cast_0000000000000004:function(e,n){return V(e,n,G.wasm_bindgen_90774f07ac80778b___closure__destroy___dyn_core_d941ad8722425d2e___ops__function__FnMut__wasm_bindgen_90774f07ac80778b___JsValue____Output_______,a)},__wbindgen_cast_0000000000000005:function(e){return e},__wbindgen_cast_0000000000000006:function(e,n){return g(e,n)},__wbindgen_cast_0000000000000007:function(e,n){return l(e,n)},__wbindgen_cast_0000000000000008:function(e,n){return w(e,n)},__wbindgen_cast_0000000000000009:function(e,n){return h(e,n)},__wbindgen_cast_000000000000000a:function(e,n){return m(e,n)},__wbindgen_cast_000000000000000b:function(e,n){return p(e,n)},__wbindgen_cast_000000000000000c:function(e,n){return y(e,n)},__wbindgen_cast_000000000000000d:function(e,n){return E(e,n)},__wbindgen_init_externref_table:function(){const e=G.__wbindgen_externrefs,n=e.grow(4);e.set(0,void 0),e.set(n+0,void 0),e.set(n+1,null),e.set(n+2,!0),e.set(n+3,!1)}};return{__proto__:null,"./viewarr_bg.js":e}}function c(e,n){const t=G.wasm_bindgen_90774f07ac80778b___convert__closures_____invoke___core_d941ad8722425d2e___result__Result_____wasm_bindgen_90774f07ac80778b___JsValue__(e,n);if(t[1])throw U(t[0])}function o(e,n,t){G.wasm_bindgen_90774f07ac80778b___convert__closures_____invoke___js_sys_88d3431ccd25c44___Array_____(e,n,t)}function a(e,n,t){G.wasm_bindgen_90774f07ac80778b___convert__closures_____invoke___wasm_bindgen_90774f07ac80778b___JsValue_____(e,n,t)}Symbol.dispose&&(_.prototype[Symbol.dispose]=_.prototype.free);const i=["border-box","content-box","device-pixel-content-box"],b="undefined"==typeof FinalizationRegistry?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(e=>G.__wbg_viewerhandle_free(e>>>0,1));function f(e){const n=G.__externref_table_alloc();return G.__wbindgen_externrefs.set(n,e),n}const u="undefined"==typeof FinalizationRegistry?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(e=>e.dtor(e.a,e.b));function d(e){const n=typeof e;if("number"==n||"boolean"==n||null==e)return`${e}`;if("string"==n)return`"${e}"`;if("symbol"==n){const n=e.description;return null==n?"Symbol":`Symbol(${n})`}if("function"==n){const n=e.name;return"string"==typeof n&&n.length>0?`Function(${n})`:"Function"}if(Array.isArray(e)){const n=e.length;let t="[";n>0&&(t+=d(e[0]));for(let _=1;_<n;_++)t+=", "+d(e[_]);return t+="]",t}const t=/\[object ([^\]]+)\]/.exec(toString.call(e));let _;if(!(t&&t.length>1))return toString.call(e);if(_=t[1],"Object"==_)try{return"Object("+JSON.stringify(e)+")"}catch(e){return"Object"}return e instanceof Error?`${e.name}: ${e.message}\n${e.stack}`:_}function g(e,n){return e>>>=0,I().subarray(e/4,e/4+n)}function s(e,n){return e>>>=0,(null!==A&&0!==A.byteLength||(A=new Float64Array(G.memory.buffer)),A).subarray(e/8,e/8+n)}function l(e,n){return e>>>=0,(null!==P&&0!==P.byteLength||(P=new Int16Array(G.memory.buffer)),P).subarray(e/2,e/2+n)}function w(e,n){return e>>>=0,(null!==C&&0!==C.byteLength||(C=new Int32Array(G.memory.buffer)),C).subarray(e/4,e/4+n)}function h(e,n){return e>>>=0,(null!==R&&0!==R.byteLength||(R=new Int8Array(G.memory.buffer)),R).subarray(e/1,e/1+n)}function m(e,n){return e>>>=0,(null!==k&&0!==k.byteLength||(k=new Uint16Array(G.memory.buffer)),k).subarray(e/2,e/2+n)}function p(e,n){return e>>>=0,L().subarray(e/4,e/4+n)}function y(e,n){return e>>>=0,B().subarray(e/1,e/1+n)}let v=null;function x(){return(null===v||!0===v.buffer.detached||void 0===v.buffer.detached&&v.buffer!==G.memory.buffer)&&(v=new DataView(G.memory.buffer)),v}let S=null;function I(){return null!==S&&0!==S.byteLength||(S=new Float32Array(G.memory.buffer)),S}let A=null,P=null,C=null,R=null;function E(e,n){return function(e,n){return q+=n,q>=j&&(W=new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0}),W.decode(),q=n),W.decode(B().subarray(e,e+n))}(e>>>=0,n)}let k=null,M=null;function L(){return null!==M&&0!==M.byteLength||(M=new Uint32Array(G.memory.buffer)),M}let O=null;function B(){return null!==O&&0!==O.byteLength||(O=new Uint8Array(G.memory.buffer)),O}function F(e,n){try{return e.apply(this,n)}catch(e){const n=f(e);G.__wbindgen_exn_store(n)}}function T(e){return null==e}function V(e,n,t,_){const r={a:e,b:n,cnt:1,dtor:t},c=(...e)=>{r.cnt++;const n=r.a;r.a=0;try{return _(n,r.b,...e)}finally{r.a=n,c._wbg_cb_unref()}};return c._wbg_cb_unref=()=>{0===--r.cnt&&(r.dtor(r.a,r.b),r.a=0,u.unregister(r))},u.register(c,r,r),c}function D(e,n){const t=n(4*e.length,4)>>>0;return L().set(e,t/4),H=e.length,t}function z(e,n,t){if(void 0===t){const t=K.encode(e),_=n(t.length,1)>>>0;return B().subarray(_,_+t.length).set(t),H=t.length,_}let _=e.length,r=n(_,1)>>>0;const c=B();let o=0;for(;o<_;o++){const n=e.charCodeAt(o);if(n>127)break;c[r+o]=n}if(o!==_){0!==o&&(e=e.slice(o)),r=t(r,_,_=o+3*e.length,1)>>>0;const n=B().subarray(r+o,r+_);o+=K.encodeInto(e,n).written,r=t(r,_,o,1)>>>0}return H=o,r}function U(e){const n=G.__wbindgen_externrefs.get(e);return G.__externref_table_dealloc(e),n}let W=new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0});W.decode();const j=2146435072;let q=0;const K=new TextEncoder;"encodeInto"in K||(K.encodeInto=function(e,n){const t=K.encode(e);return n.set(t),{read:e.length,written:t.length}});let $,G,H=0;function J(e,n){return G=e.exports,$=n,v=null,S=null,A=null,P=null,C=null,R=null,k=null,M=null,O=null,G.__wbindgen_start(),G}function X(e){if(void 0!==G)return G;void 0!==e&&(Object.getPrototypeOf(e)===Object.prototype?({module:e}=e):console.warn("using deprecated parameters for `initSync()`; pass a single object instead"));const n=r();return e instanceof WebAssembly.Module||(e=new WebAssembly.Module(e)),J(new WebAssembly.Instance(e,n),e)}async function Y(e){if(void 0!==G)return G;void 0!==e&&(Object.getPrototypeOf(e)===Object.prototype?({module_or_path:e}=e):console.warn("using deprecated parameters for the initialization function; pass a single object instead")),void 0===e&&(e=new URL(t(119),t.b));const n=r();("string"==typeof e||"function"==typeof Request&&e instanceof Request||"function"==typeof URL&&e instanceof URL)&&(e=fetch(e));const{instance:_,module:c}=await async function(e,n){if("function"==typeof Response&&e instanceof Response){if("function"==typeof WebAssembly.instantiateStreaming)try{return await WebAssembly.instantiateStreaming(e,n)}catch(n){if(!e.ok||!function(e){switch(e){case"basic":case"cors":case"default":return!0}return!1}(e.type)||"application/wasm"===e.headers.get("Content-Type"))throw n;console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",n)}const t=await e.arrayBuffer();return await WebAssembly.instantiate(t,n)}{const t=await WebAssembly.instantiate(e,n);return t instanceof WebAssembly.Instance?{instance:t,module:e}:t}}(await e,n);return J(_,c)}},119(e,n,t){e.exports=t.p+"363f87cc06bfb5adac71.wasm"}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunkfitsview=self.webpackChunkfitsview||[]).push([[728],{56(n,e,r){n.exports=function(n){var e=r.nc;e&&n.setAttribute("nonce",e)}},72(n){var e=[];function r(n){for(var r=-1,o=0;o<e.length;o++)if(e[o].identifier===n){r=o;break}return r}function o(n,o){for(var a={},i=[],p=0;p<n.length;p++){var l=n[p],c=o.base?l[0]+o.base:l[0],d=a[c]||0,s="".concat(c," ").concat(d);a[c]=d+1;var u=r(s),f={css:l[1],media:l[2],sourceMap:l[3],supports:l[4],layer:l[5]};if(-1!==u)e[u].references++,e[u].updater(f);else{var h=t(f,o);o.byIndex=p,e.splice(p,0,{identifier:s,updater:h,references:1})}i.push(s)}return i}function t(n,e){var r=e.domAPI(e);return r.update(n),function(e){if(e){if(e.css===n.css&&e.media===n.media&&e.sourceMap===n.sourceMap&&e.supports===n.supports&&e.layer===n.layer)return;r.update(n=e)}else r.remove()}}n.exports=function(n,t){var a=o(n=n||[],t=t||{});return function(n){n=n||[];for(var i=0;i<a.length;i++){var p=r(a[i]);e[p].references--}for(var l=o(n,t),c=0;c<a.length;c++){var d=r(a[c]);0===e[d].references&&(e[d].updater(),e.splice(d,1))}a=l}}},113(n){n.exports=function(n,e){if(e.styleSheet)e.styleSheet.cssText=n;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(n))}}},314(n){n.exports=function(n){var e=[];return e.toString=function(){return this.map(function(e){var r="",o=void 0!==e[5];return e[4]&&(r+="@supports (".concat(e[4],") {")),e[2]&&(r+="@media ".concat(e[2]," {")),o&&(r+="@layer".concat(e[5].length>0?" ".concat(e[5]):""," {")),r+=n(e),o&&(r+="}"),e[2]&&(r+="}"),e[4]&&(r+="}"),r}).join("")},e.i=function(n,r,o,t,a){"string"==typeof n&&(n=[[null,n,void 0]]);var i={};if(o)for(var p=0;p<this.length;p++){var l=this[p][0];null!=l&&(i[l]=!0)}for(var c=0;c<n.length;c++){var d=[].concat(n[c]);o&&i[d[0]]||(void 0!==a&&(void 0===d[5]||(d[1]="@layer".concat(d[5].length>0?" ".concat(d[5]):""," {").concat(d[1],"}")),d[5]=a),r&&(d[2]?(d[1]="@media ".concat(d[2]," {").concat(d[1],"}"),d[2]=r):d[2]=r),t&&(d[4]?(d[1]="@supports (".concat(d[4],") {").concat(d[1],"}"),d[4]=t):d[4]="".concat(t)),e.push(d))}},e}},475(n,e,r){r.d(e,{A:()=>p});var o=r(601),t=r.n(o),a=r(314),i=r.n(a)()(t());i.push([n.id,"/*\n See the JupyterLab Developer Guide for useful CSS Patterns:\n\n https://jupyterlab.readthedocs.io/en/stable/developer/css.html\n*/\n\n.jp-FITSViewer {\n overflow: hidden;\n font-family: var(--jp-ui-font-family);\n height: 100%;\n}\n\n.jp-FITSViewer-content {\n height: 100%;\n}\n\n.jp-FITSViewer-layout {\n display: flex;\n height: 100%;\n}\n\n.jp-FITSViewer-viewerPanel {\n flex: 1;\n min-width: 300px;\n display: flex;\n flex-direction: column;\n}\n\n/* Control bar containing HDU buttons (slice + play controls live in the viewer) */\n.jp-FITSViewer-controlBar {\n display: flex;\n flex-direction: column;\n background: var(--jp-layout-color1);\n border-bottom: 1px solid var(--jp-border-color1);\n}\n\n/* Horizontal HDU button bar */\n.jp-FITSViewer-hduBar {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n padding: 6px 8px;\n}\n\n.jp-FITSViewer-hduBar:empty {\n display: none;\n}\n\n.jp-FITSViewer-hduButton {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n background: var(--jp-layout-color2);\n border: 1px solid var(--jp-border-color1);\n border-radius: 4px;\n cursor: pointer;\n font-size: 12px;\n color: var(--jp-ui-font-color1);\n transition:\n border-color 0.15s ease,\n background-color 0.15s ease;\n}\n\n.jp-FITSViewer-hduButton:hover:not(:disabled) {\n background: var(--jp-layout-color3);\n border-color: var(--jp-border-color2);\n}\n\n.jp-FITSViewer-hduButton-active {\n background: var(--jp-brand-color3);\n border-color: var(--jp-brand-color1);\n}\n\n.jp-FITSViewer-hduButton-disabled {\n cursor: default;\n opacity: 0.6;\n}\n\n.jp-FITSViewer-hduContent {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 1px;\n}\n\n.jp-FITSViewer-hduName {\n white-space: nowrap;\n font-weight: 500;\n}\n\n.jp-FITSViewer-hduInfo {\n white-space: nowrap;\n font-size: 10px;\n color: var(--jp-ui-font-color2);\n}\n\n.jp-FITSViewer-hduLabel {\n white-space: nowrap;\n}\n\n.jp-FITSViewer-headerIcon {\n color: var(--jp-brand-color1);\n text-decoration: none;\n font-size: 14px;\n line-height: 1;\n opacity: 0.8;\n transition: opacity 0.15s ease;\n}\n\n.jp-FITSViewer-headerIcon:hover {\n opacity: 1;\n text-decoration: none;\n}\n\n.jp-FITSViewer-viewerContainer {\n flex: 1;\n min-height: 200px;\n background: var(--jp-layout-color2);\n border: 1px solid var(--jp-border-color1);\n border-radius: 4px;\n overflow: hidden;\n position: relative;\n}\n\n/* When the egui canvas (which eframe makes focusable) has keyboard focus,\n recolor the border to a contrasting brand color and add an inset line — a\n doubled border — so it's clear which viewer keypresses (zoom +/-/0, F1) will\n go to. Drawn inside the existing border, so the layout never shifts. */\n.jp-FITSViewer-viewerContainer:focus-within {\n border-color: var(--jp-brand-color1);\n box-shadow: inset 0 0 0 1px var(--jp-brand-color1);\n}\n\n/* Suppress the canvas's default focus outline; the container border above is\n the focus indicator. */\n.jp-FITSViewer-viewerContainer canvas:focus {\n outline: none;\n}\n\n.jp-FITSViewer-viewerPlaceholder {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: var(--jp-ui-font-color2);\n font-style: italic;\n}\n\n.jp-FITSViewer-metadataPanel {\n width: 350px;\n min-width: 250px;\n max-width: 450px;\n overflow-y: auto;\n padding: 16px;\n background: var(--jp-layout-color0);\n border-left: 1px solid var(--jp-border-color1);\n}\n\n.jp-FITSViewer-metadataPanel h2 {\n margin-top: 0;\n font-size: 1.2em;\n color: var(--jp-ui-font-color0);\n}\n\n.jp-FITSViewer-metadataPanel h3 {\n font-size: 1em;\n margin-bottom: 8px;\n color: var(--jp-ui-font-color1);\n}\n\n.jp-FITSViewer-hdu {\n margin-bottom: 24px;\n padding: 12px;\n background: var(--jp-layout-color1);\n border-radius: 4px;\n border: 1px solid var(--jp-border-color1);\n}\n\n.jp-FITSViewer-hdu-viewable {\n cursor: pointer;\n transition:\n border-color 0.15s ease,\n background-color 0.15s ease;\n}\n\n.jp-FITSViewer-hdu-viewable:hover {\n border-color: var(--jp-brand-color1);\n background: var(--jp-layout-color2);\n}\n\n.jp-FITSViewer-hdu-active {\n border-color: var(--jp-brand-color1);\n border-width: 2px;\n background: var(--jp-layout-color2);\n}\n\n.jp-FITSViewer-viewerStack {\n flex: 1;\n position: relative;\n min-height: 0;\n}\n\n.jp-FITSViewer-viewerStack .jp-FITSViewer-viewerContainer {\n position: absolute;\n inset: 0;\n}\n\n.jp-FITSViewer-headerLink {\n color: var(--jp-content-link-color);\n text-decoration: none;\n font-size: 13px;\n}\n\n.jp-FITSViewer-headerLink:hover {\n text-decoration: underline;\n}\n\n.jp-FITSViewer-headerTable {\n font-size: 0.85em;\n border-collapse: collapse;\n margin-top: 8px;\n}\n\n.jp-FITSViewer-headerTable td {\n padding: 4px 8px;\n border-bottom: 1px solid var(--jp-border-color2);\n}\n\n.jp-FITSViewer-headerTable td:first-child {\n font-weight: bold;\n color: var(--jp-ui-font-color1);\n}\n\n.jp-FITSViewer-viewButton {\n margin-top: 8px;\n margin-right: 8px;\n padding: 6px 12px;\n background: var(--jp-brand-color1);\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n font-size: 0.9em;\n}\n\n.jp-FITSViewer-viewButton:hover {\n background: var(--jp-brand-color0);\n}\n\n.jp-FITSViewer-sliceResult {\n margin-top: 8px;\n padding: 8px;\n background: var(--jp-layout-color2);\n border-radius: 4px;\n font-family: var(--jp-code-font-family);\n font-size: 0.85em;\n white-space: pre;\n overflow-x: auto;\n}\n\n.jp-FITSViewer-error {\n color: var(--jp-error-color1);\n padding: 12px;\n background: var(--jp-error-color3);\n border-radius: 4px;\n}\n\n.jp-FITSViewer-headerPre {\n margin: 0;\n padding: 8px;\n background: var(--jp-layout-color1);\n border: 1px solid var(--jp-border-color1);\n border-radius: 4px;\n font-family: var(--jp-code-font-family);\n font-size: 0.85em;\n line-height: 1.4;\n white-space: pre;\n overflow: auto;\n max-height: 400px;\n}\n\n/* Large image prompt UI */\n.jp-FITSViewer-largeImagePrompt {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n padding: 20px;\n text-align: center;\n gap: 16px;\n}\n\n.jp-FITSViewer-largeImagePrompt p {\n margin: 0;\n color: var(--jp-ui-font-color1);\n font-size: 1em;\n}\n\n.jp-FITSViewer-fetchButton {\n padding: 8px 24px;\n font-size: 1em;\n}\n\n.jp-FITSViewer-progressContainer {\n display: flex;\n align-items: center;\n gap: 12px;\n width: 100%;\n max-width: 400px;\n}\n\n.jp-FITSViewer-progressBar {\n flex: 1;\n height: 20px;\n background: var(--jp-layout-color2);\n border-radius: 4px;\n overflow: hidden;\n border: 1px solid var(--jp-border-color1);\n}\n\n.jp-FITSViewer-progressFill {\n height: 100%;\n width: 0%;\n background: var(--jp-brand-color1);\n transition: width 0.1s ease-out;\n}\n\n.jp-FITSViewer-progressText {\n min-width: 180px;\n font-family: var(--jp-code-font-family);\n font-size: 0.85em;\n color: var(--jp-ui-font-color1);\n}\n\n.jp-FITSViewer-cancelButton {\n padding: 4px 12px;\n font-size: 0.9em;\n}\n",""]);const p=i},540(n){n.exports=function(n){var e=document.createElement("style");return n.setAttributes(e,n.attributes),n.insert(e,n.options),e}},601(n){n.exports=function(n){return n[1]}},659(n){var e={};n.exports=function(n,r){var o=function(n){if(void 0===e[n]){var r=document.querySelector(n);if(window.HTMLIFrameElement&&r instanceof window.HTMLIFrameElement)try{r=r.contentDocument.head}catch(n){r=null}e[n]=r}return e[n]}(n);if(!o)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");o.appendChild(r)}},728(n,e,r){var o=r(72),t=r.n(o),a=r(825),i=r.n(a),p=r(659),l=r.n(p),c=r(56),d=r.n(c),s=r(540),u=r.n(s),f=r(113),h=r.n(f),v=r(475),b={};b.styleTagTransform=h(),b.setAttributes=d(),b.insert=l().bind(null,"head"),b.domAPI=i(),b.insertStyleElement=u(),t()(v.A,b),v.A&&v.A.locals&&v.A.locals},825(n){n.exports=function(n){if("undefined"==typeof document)return{update:function(){},remove:function(){}};var e=n.insertStyleElement(n);return{update:function(r){!function(n,e,r){var o="";r.supports&&(o+="@supports (".concat(r.supports,") {")),r.media&&(o+="@media ".concat(r.media," {"));var t=void 0!==r.layer;t&&(o+="@layer".concat(r.layer.length>0?" ".concat(r.layer):""," {")),o+=r.css,t&&(o+="}"),r.media&&(o+="}"),r.supports&&(o+="}");var a=r.sourceMap;a&&"undefined"!=typeof btoa&&(o+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(a))))," */")),e.styleTagTransform(o,n,e.options)}(e,n,r)},remove:function(){!function(n){if(null===n.parentNode)return!1;n.parentNode.removeChild(n)}(e)}}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunkfitsview=self.webpackChunkfitsview||[]).push([[764],{764(e,t,o){o.r(t),o.d(t,{clearCallbacks:()=>F,createViewer:()=>a,default:()=>U,destroyViewer:()=>f,failSliceRequest:()=>d,getActiveViewers:()=>u,getBias:()=>y,getColormap:()=>k,getColormapReversed:()=>$,getContrast:()=>v,getMarkers:()=>L,getOverlayMessage:()=>Z,getPivotPoint:()=>B,getRotation:()=>P,getShowPivotMarker:()=>O,getStretchMode:()=>C,getValueRange:()=>S,getViewBounds:()=>E,getZoom:()=>h,hasViewer:()=>w,onClick:()=>H,onSliceRequest:()=>j,onStateChange:()=>I,setBias:()=>p,setColormap:()=>N,setColormapReversed:()=>b,setContrast:()=>m,setCube:()=>c,setImageData:()=>s,setMarkers:()=>T,setOverlayMessage:()=>q,setPivotPoint:()=>A,setRotation:()=>x,setShowPivotMarker:()=>D,setSliceData:()=>l,setStretchMode:()=>M,setValueRange:()=>V,setViewBounds:()=>R,setViewerState:()=>z,setZoom:()=>g});let n=null,r=null;const i=new Map;async function a(e){const t=document.getElementById(e);if(!t)throw new Error(`Container element with id "${e}" not found`);if(i.has(e))return void console.warn(`Viewer already exists for container "${e}"`);t.innerHTML="";const a=document.createElement("div");a.style.cssText="\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n font-family: system-ui, -apple-system, sans-serif;\n color: #666;\n ",a.textContent="Loading viewer...",t.appendChild(a);try{await async function(){return r||(r=(async()=>{const e=await o.e(55).then(o.bind(o,55));await e.default(),n=e})(),r)}();const a=document.createElement("canvas");a.id=`${e}_canvas`,a.style.cssText="\n width: 100%;\n height: 100%;\n display: block;\n ",a.addEventListener("dragstart",e=>{e.preventDefault()}),a.draggable=!1,a.addEventListener("mousedown",e=>{e.altKey&&e.preventDefault()}),t.innerHTML="",t.appendChild(a);const s=await n.ViewerHandle.create(a);i.set(e,{handle:s,canvas:a,container:t});const c=new MutationObserver(o=>{o.forEach(o=>{o.removedNodes.forEach(o=>{(o===t||o.contains(t))&&(console.debug(`Cleaning up viewer ${e} because its DOM node went away...`),f(e),console.debug(`Done cleaning up viewer ${e}.`),c.disconnect())})})});c.observe(document.body,{childList:!0,subtree:!0}),console.log("Installed mutation observer"),i.get(e).mutationObserver=c}catch(e){t.innerHTML="";const o=document.createElement("div");o.style.cssText="\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n font-family: system-ui, -apple-system, sans-serif;\n color: #c00;\n padding: 20px;\n box-sizing: border-box;\n text-align: center;\n ";const n=document.createElement("div");n.style.fontWeight="bold",n.style.marginBottom="10px",n.textContent="Failed to load viewer";const r=document.createElement("div");throw r.style.cssText="\n font-family: monospace;\n font-size: 12px;\n white-space: pre-wrap;\n word-break: break-word;\n max-width: 100%;\n ",r.textContent=e.message||String(e),o.appendChild(n),o.appendChild(r),t.appendChild(o),console.error("viewarr initialization failed:",e),e}}function s(e,t,o,n,r){const a=i.get(e);if(!a)throw new Error(`No viewer found for container "${e}"`);a.handle.setImageData(t,o,n,r)}function c(e,t){const o=i.get(e);if(!o)throw new Error(`No viewer found for container "${e}"`);o.handle.setCube(Uint32Array.from(t??[]))}function l(e,t,o,n,r,a){const s=i.get(e);if(!s)throw new Error(`No viewer found for container "${e}"`);s.handle.setSliceData(t,o,n,r,Uint32Array.from(a??[]))}function d(e,t){const o=i.get(e);o&&o.handle.failSliceRequest(Uint32Array.from(t??[]))}function f(e){const t=i.get(e);t&&(t.handle.destroy(),t.mutationObserver&&t.mutationObserver.disconnect(),t.container.innerHTML="",i.delete(e))}function w(e){return i.has(e)}function u(){return Array.from(i.keys())}function h(e){const t=i.get(e);if(!t)throw new Error(`No viewer found for container "${e}"`);return t.handle.getZoom()}function g(e,t){const o=i.get(e);if(!o)throw new Error(`No viewer found for container "${e}"`);o.handle.setZoom(t)}function v(e){const t=i.get(e);if(!t)throw new Error(`No viewer found for container "${e}"`);return t.handle.getContrast()}function m(e,t){const o=i.get(e);if(!o)throw new Error(`No viewer found for container "${e}"`);o.handle.setContrast(t)}function y(e){const t=i.get(e);if(!t)throw new Error(`No viewer found for container "${e}"`);return t.handle.getBias()}function p(e,t){const o=i.get(e);if(!o)throw new Error(`No viewer found for container "${e}"`);o.handle.setBias(t)}function C(e){const t=i.get(e);if(!t)throw new Error(`No viewer found for container "${e}"`);return t.handle.getStretchMode()}function M(e,t){const o=i.get(e);if(!o)throw new Error(`No viewer found for container "${e}"`);o.handle.setStretchMode(t)}function E(e){const t=i.get(e);if(!t)throw new Error(`No viewer found for container "${e}"`);const o=t.container.getBoundingClientRect(),n=t.handle.getViewBounds(o.width,o.height);return Array.from(n)}function R(e,t,o,n,r){const a=i.get(e);if(!a)throw new Error(`No viewer found for container "${e}"`);const s=a.container.getBoundingClientRect();a.handle.setViewBounds(t,o,n,r,s.width,s.height)}function k(e){const t=i.get(e);if(!t)throw new Error(`No viewer found for container "${e}"`);return t.handle.getColormap()}function N(e,t){const o=i.get(e);if(!o)throw new Error(`No viewer found for container "${e}"`);o.handle.setColormap(t)}function $(e){const t=i.get(e);if(!t)throw new Error(`No viewer found for container "${e}"`);return t.handle.getColormapReversed()}function b(e,t){const o=i.get(e);if(!o)throw new Error(`No viewer found for container "${e}"`);o.handle.setColormapReversed(t)}function S(e){const t=i.get(e);if(!t)throw new Error(`No viewer found for container "${e}"`);const o=t.handle.getValueRange();return Array.from(o)}function V(e,t,o){const n=i.get(e);if(!n)throw new Error(`No viewer found for container "${e}"`);n.handle.setValueRange(t,o)}function P(e){const t=i.get(e);if(!t)throw new Error(`No viewer found for container "${e}"`);return t.handle.getRotation()}function x(e,t){const o=i.get(e);if(!o)throw new Error(`No viewer found for container "${e}"`);o.handle.setRotation(t)}function B(e){const t=i.get(e);if(!t)throw new Error(`No viewer found for container "${e}"`);const o=t.handle.getPivotPoint();return Array.from(o)}function A(e,t,o){const n=i.get(e);if(!n)throw new Error(`No viewer found for container "${e}"`);n.handle.setPivotPoint(t,o)}function O(e){const t=i.get(e);if(!t)throw new Error(`No viewer found for container "${e}"`);return t.handle.getShowPivotMarker()}function D(e,t){const o=i.get(e);if(!o)throw new Error(`No viewer found for container "${e}"`);o.handle.setShowPivotMarker(t)}function Z(e){const t=i.get(e);if(!t)throw new Error(`No viewer found for container "${e}"`);return t.handle.getOverlayMessage()}function q(e,t){const o=i.get(e);if(!o)throw new Error(`No viewer found for container "${e}"`);o.handle.setOverlayMessage(t)}function L(e){const t=i.get(e);if(!t)throw new Error(`No viewer found for container "${e}"`);const o=Array.from(t.handle.getMarkers()),n=[];for(let e=0;e+1<o.length;e+=2)n.push([o[e],o[e+1]]);return n}function T(e,t){const o=i.get(e);if(!o)throw new Error(`No viewer found for container "${e}"`);if(!Array.isArray(t))return void o.handle.setMarkers([]);const n=[];for(const e of t){if(!Array.isArray(e)||2!==e.length)continue;const t=Number(e[0]),o=Number(e[1]);Number.isFinite(t)&&Number.isFinite(o)&&n.push(t,o)}o.handle.setMarkers(n)}function z(e,t){const o=i.get(e);if(!o)throw new Error(`No viewer found for container "${e}"`);if(t&&"object"==typeof t){if("contrast"in t&&void 0!==t.contrast&&o.handle.setContrast(t.contrast),"bias"in t&&void 0!==t.bias&&o.handle.setBias(t.bias),"stretchMode"in t&&void 0!==t.stretchMode&&o.handle.setStretchMode(t.stretchMode),"colormap"in t&&void 0!==t.colormap&&o.handle.setColormap(t.colormap),"colormapReversed"in t&&void 0!==t.colormapReversed&&o.handle.setColormapReversed(t.colormapReversed),"vmin"in t&&"vmax"in t&&void 0!==t.vmin&&void 0!==t.vmax&&o.handle.setValueRange(t.vmin,t.vmax),"xlim"in t&&"ylim"in t&&void 0!==t.xlim&&void 0!==t.ylim&&Array.isArray(t.xlim)&&Array.isArray(t.ylim)&&2===t.xlim.length&&2===t.ylim.length){const e=o.container.getBoundingClientRect();o.handle.setViewBounds(t.xlim[0],t.xlim[1],t.ylim[0],t.ylim[1],e.width,e.height)}"rotation"in t&&void 0!==t.rotation&&o.handle.setRotation(t.rotation),"pivot"in t&&void 0!==t.pivot&&Array.isArray(t.pivot)&&2===t.pivot.length&&o.handle.setPivotPoint(t.pivot[0],t.pivot[1]),"showPivotMarker"in t&&void 0!==t.showPivotMarker&&o.handle.setShowPivotMarker(t.showPivotMarker),"overlayMessage"in t&&void 0!==t.overlayMessage&&o.handle.setOverlayMessage(t.overlayMessage),"markers"in t&&void 0!==t.markers&&T(e,t.markers),"zoom"in t&&void 0!==t.zoom&&o.handle.setZoom(t.zoom)}}function I(e,t){const o=i.get(e);if(!o)throw new Error(`No viewer found for container "${e}"`);o.handle.onStateChange(t)}function H(e,t){const o=i.get(e);if(!o)throw new Error(`No viewer found for container "${e}"`);o.handle.onClick(t)}function j(e,t){const o=i.get(e);if(!o)throw new Error(`No viewer found for container "${e}"`);o.handle.onSliceRequest(e=>t(Array.from(e)))}function F(e){const t=i.get(e);if(!t)throw new Error(`No viewer found for container "${e}"`);t.handle.clearCallbacks()}window.viewarr={createViewer:a,setImageData:s,setCube:c,setSliceData:l,failSliceRequest:d,destroyViewer:f,hasViewer:w,getActiveViewers:u,getZoom:h,setZoom:g,getContrast:v,setContrast:m,getBias:y,setBias:p,getStretchMode:C,setStretchMode:M,getViewBounds:E,setViewBounds:R,getColormap:k,setColormap:N,getColormapReversed:$,setColormapReversed:b,getValueRange:S,setValueRange:V,getRotation:P,setRotation:x,getPivotPoint:B,setPivotPoint:A,getShowPivotMarker:O,setShowPivotMarker:D,getOverlayMessage:Z,setOverlayMessage:q,getMarkers:L,setMarkers:T,setViewerState:z,onStateChange:I,onClick:H,onSliceRequest:j,clearCallbacks:F};const U={createViewer:a,setImageData:s,setCube:c,setSliceData:l,failSliceRequest:d,destroyViewer:f,hasViewer:w,getActiveViewers:u,getZoom:h,setZoom:g,getContrast:v,setContrast:m,getBias:y,setBias:p,getStretchMode:C,setStretchMode:M,getViewBounds:E,setViewBounds:R,getColormap:k,setColormap:N,getColormapReversed:$,setColormapReversed:b,getValueRange:S,setValueRange:V,getRotation:P,setRotation:x,getPivotPoint:B,setPivotPoint:A,getShowPivotMarker:O,setShowPivotMarker:D,getOverlayMessage:Z,setOverlayMessage:q,getMarkers:L,setMarkers:T,setViewerState:z,onStateChange:I,onClick:H,onSliceRequest:j,clearCallbacks:F}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunkfitsview=self.webpackChunkfitsview||[]).push([[777],{777(e,t,n){n.r(t),n.d(t,{default:()=>I});var i,r=n(206),s=n(961),a=n(534),o=n(684);function c(e){return e<1024?`${e} B`:e<1048576?`${(e/1024).toFixed(1)} KB`:e<1073741824?`${(e/1048576).toFixed(1)} MB`:`${(e/1073741824).toFixed(2)} GB`}!function(e){e.INT8="i8",e.UINT8="u8",e.INT16="i16",e.UINT16="u16",e.INT32="i32",e.UINT32="u32",e.INT64="i64",e.UINT64="u64",e.FLOAT32="f32",e.FLOAT64="f64"}(i||(i={}));let l=null;const d=n.e(32).then(n.t.bind(n,32,23)).then(e=>{l=e}).catch(e=>{console.warn("viewarr module not available, image viewer disabled:",e)});class h extends a.Widget{constructor(e){super(),this._viewerContainers=new Map,this._sliceStates=new Map,this._activeHduIndex=null,this._fetchAbortController=null,this._metadata=null,this._context=e,this.addClass("jp-FITSViewer"),this._baseViewerId="fitsview-"+h._instanceCounter++,this._content=document.createElement("div"),this._content.className="jp-FITSViewer-content",this.node.appendChild(this._content),e.ready.then(()=>{this._loadMetadata()})}_getViewerId(e){return`${this._baseViewerId}-hdu${e}`}async _loadMetadata(){const e=this._context.path;this._content.innerHTML=`<p>Loading metadata for ${e}...</p>`;try{const t=await async function(e="",t={}){const n=s.ServerConnection.makeSettings(),i=o.URLExt.join(n.baseUrl,"fitsview",e);let r;try{r=await s.ServerConnection.makeRequest(i,t,n)}catch(e){throw new s.ServerConnection.NetworkError(e)}let a=await r.text();if(a.length>0)try{a=JSON.parse(a)}catch(e){console.log("Not a JSON response body.",r)}if(!r.ok){let e="Unknown error";throw"string"==typeof a?e=a:a&&"object"==typeof a&&(e=a.error||a.message||JSON.stringify(a)),new s.ServerConnection.ResponseError(r,e)}return a}(`metadata?path=${encodeURIComponent(e)}`);this._metadata=t,this._renderMetadata()}catch(e){this._content.innerHTML=`<p class="jp-FITSViewer-error">Error loading FITS metadata: ${e}</p>`}}_renderMetadata(){if(!this._metadata)return;const{hdus:e}=this._metadata,t=e.filter(e=>e.shape&&e.shape.length>=2&&e.arrayType);let n="";for(const e of t)n+=`\n <div id="${this._getViewerId(e.index)}" class="jp-FITSViewer-viewerContainer" data-hdu="${e.index}" style="display: none;">\n <div class="jp-FITSViewer-viewerPlaceholder">Loading...</div>\n </div>\n `;0===t.length&&(n='\n <div class="jp-FITSViewer-viewerContainer">\n <div class="jp-FITSViewer-viewerPlaceholder">No viewable image data</div>\n </div>\n ');let i="";for(const t of e){const e=t.shape&&t.shape.length>=2&&t.arrayType,n=t.name||`HDU ${t.index}`;let r;r=t.shape&&t.shape.length>=2&&t.arrayType?`${t.shape.join("×")} [${t.arrayType}]`:t.shape&&1===t.shape.length?`${t.shape[0]} rows`:"—";const s=e?"":"disabled";i+=`\n <button class="${e?"jp-FITSViewer-hduButton":"jp-FITSViewer-hduButton jp-FITSViewer-hduButton-disabled"}" data-hdu="${t.index}" ${s}>\n <div class="jp-FITSViewer-hduContent">\n <span class="jp-FITSViewer-hduName">${t.index}: ${n}</span>\n <span class="jp-FITSViewer-hduInfo">${r}</span>\n </div>\n <a href="#" class="jp-FITSViewer-headerIcon" data-hdu="${t.index}" title="View Header">ⓘ</a>\n </button>\n `}const r=`\n <div class="jp-FITSViewer-layout">\n <div class="jp-FITSViewer-viewerPanel">\n <div class="jp-FITSViewer-controlBar">\n <div class="jp-FITSViewer-hduBar">${i}</div>\n </div>\n <div class="jp-FITSViewer-viewerStack">\n ${n}\n </div>\n </div>\n </div>\n `;this._content.innerHTML=r,this._viewerContainers.clear();for(const e of t){const t=this._getViewerId(e.index),n=document.getElementById(t);n&&this._viewerContainers.set(e.index,n)}d.then(()=>{this._autoDisplayFirstHDU()}),this._content.querySelectorAll(".jp-FITSViewer-hduButton").forEach(e=>{e.addEventListener("click",t=>{if(t.target.classList.contains("jp-FITSViewer-headerIcon"))return;const n=parseInt(e.dataset.hdu||"0",10);this._switchToHDU(n)})}),this._content.querySelectorAll(".jp-FITSViewer-headerIcon").forEach(e=>{e.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation();const n=parseInt(e.dataset.hdu||"0",10);this._openHeaderWindow(n)})})}async _switchToHDU(e){if(this._activeHduIndex===e)return;if(null!==this._activeHduIndex){const e=this._viewerContainers.get(this._activeHduIndex);e&&(e.style.display="none");const t=this._content.querySelector(`.jp-FITSViewer-hduButton[data-hdu="${this._activeHduIndex}"]`);t?.classList.remove("jp-FITSViewer-hduButton-active")}const t=this._viewerContainers.get(e);t&&(t.style.display="flex");const n=this._content.querySelector(`.jp-FITSViewer-hduButton[data-hdu="${e}"]`);n?.classList.add("jp-FITSViewer-hduButton-active"),this._activeHduIndex=e,await this._viewHDUImage(e)}_openHeaderWindow(e){const t=this._metadata?.hdus.find(t=>t.index===e);if(!t||!t.header)return;const n=`${this._context.path.split("/").pop()||"file"} - ${t.name||`HDU ${e}`} Header`,i=window.open("","_blank","width=800,height=600");i&&(i.document.write(`<!DOCTYPE html>\n<html>\n<head>\n <title>${n}</title>\n <style>\n body {\n font-family: monospace;\n padding: 16px;\n margin: 0;\n background: #1e1e1e;\n color: #d4d4d4;\n }\n pre {\n white-space: pre;\n margin: 0;\n line-height: 1.4;\n }\n </style>\n</head>\n<body>\n<pre>${t.header.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}</pre>\n</body>\n</html>`),i.document.close())}async _ensureViewer(e){await d;const t=this._viewerContainers.get(e),n=this._getViewerId(e);if(!l||!t)return!1;if(l.hasViewer(n))return!0;try{return t.innerHTML="",await l.createViewer(n),this._setupViewer(e,n),!0}catch(e){return console.error("Failed to create viewarr viewer:",e),!1}}_setupViewer(e,t){if(!l)return;const n=this._metadata?.hdus.find(t=>t.index===e),i=n?.shape;if(!i||i.length<2)return;const r=i.length>2?i.slice(0,i.length-2):[];l.setCube(t,r),l.onSliceRequest(t,t=>{this._onSliceRequest(e,t)})}async _onSliceRequest(e,t){const n=this._sliceStates.get(e);n?(n.sliceIndices=t.slice(),await this._fetchAndDisplaySlice()):l?.failSliceRequest(this._getViewerId(e),t)}_autoDisplayFirstHDU(){if(!this._metadata||!l)return;const e=this._metadata.hdus.find(e=>e.shape&&e.shape.length>=2&&e.arrayType);e&&this._switchToHDU(e.index)}async _viewHDUImage(e){if(!l)return void console.warn("viewarr not available");const t=this._metadata?.hdus.find(t=>t.index===e);if(!t||!t.shape||t.shape.length<2||!t.arrayType)return;const n=t.shape,r=n.length-2;let s=this._sliceStates.get(e);s||(s={hduIndex:e,shape:n,sliceIndices:new Array(r).fill(0)},this._sliceStates.set(e,s));const a=this._getViewerId(e);if(l.hasViewer(a))return;const o=function(e,t){if(e.length<2)return 0;const n=e[e.length-2];return e[e.length-1]*n*function(e){switch(e){case i.INT8:case i.UINT8:return 1;case i.INT16:case i.UINT16:return 2;case i.INT32:case i.UINT32:case i.FLOAT32:return 4;case i.INT64:case i.UINT64:case i.FLOAT64:default:return 8}}(t)}(n,t.arrayType);o<=5242880?await this._fetchAndDisplaySlice():this._showLargeImagePrompt(o)}_getActiveSliceState(){if(null!==this._activeHduIndex)return this._sliceStates.get(this._activeHduIndex)}_getActiveViewerContainer(){if(null!==this._activeHduIndex)return this._viewerContainers.get(this._activeHduIndex)}_showLargeImagePrompt(e){const t=this._getActiveViewerContainer();if(!t)return;const n=c(e);t.innerHTML=`\n <div class="jp-FITSViewer-largeImagePrompt">\n <p>This image slice is <strong>${n}</strong>, which exceeds the auto-fetch limit.</p>\n <button class="jp-FITSViewer-fetchButton jp-mod-styled">\n Fetch and Display\n </button>\n <div class="jp-FITSViewer-progressContainer" style="display: none;">\n <div class="jp-FITSViewer-progressBar">\n <div class="jp-FITSViewer-progressFill"></div>\n </div>\n <span class="jp-FITSViewer-progressText">0%</span>\n <button class="jp-FITSViewer-cancelButton jp-mod-styled jp-mod-warn">\n Cancel\n </button>\n </div>\n </div>\n `;const i=t.querySelector(".jp-FITSViewer-fetchButton"),r=t.querySelector(".jp-FITSViewer-progressContainer"),s=t.querySelector(".jp-FITSViewer-progressFill"),a=t.querySelector(".jp-FITSViewer-progressText"),o=t.querySelector(".jp-FITSViewer-cancelButton");i.addEventListener("click",()=>{i.style.display="none",r.style.display="flex",this._fetchAndDisplaySliceWithProgress(s,a,r)}),o.addEventListener("click",()=>{this._fetchAbortController&&(this._fetchAbortController.abort(),this._fetchAbortController=null),i.style.display="block",r.style.display="none",s.style.width="0%",a.textContent="0%"})}async _fetchAndDisplaySliceWithProgress(e,t,n){const r=this._getActiveSliceState(),a=this._getActiveViewerContainer(),d=this._activeHduIndex;if(console.log("[FITSViewer] _fetchAndDisplaySliceWithProgress called"),console.log("[FITSViewer] sliceState:",r),console.log("[FITSViewer] viewarr:",l),!r||!l||null===d)return void console.warn("[FITSViewer] Early return: missing sliceState or viewarr");const h=this._getViewerId(d),{shape:p,sliceIndices:u}=r,w=p.map((e,t)=>{if(t<p.length-2){const e=u[t];return`${e}:${e+1}`}return`0:${e}`}).join(",");this._fetchAbortController=new AbortController;try{const n=this._context.path;console.log("[FITSViewer] Fetching slice:",{path:n,hduIndex:d,slices:w});const{buffer:r,shape:p,arrayType:g}=await async function(e,t,n){const r=s.ServerConnection.makeSettings(),a=o.URLExt.join(r.baseUrl,"fitsview",e),c={};r.token&&(c.Authorization=`token ${r.token}`);const l=await fetch(a,{method:"GET",credentials:"same-origin",headers:c,signal:n});if(!l.ok){const e=await l.text();let t=e;try{const n=JSON.parse(e);t=n.error||n.message||e}catch{}throw new s.ServerConnection.ResponseError(l,t)}const d=l.headers.get("X-FITS-Shape"),h=d?JSON.parse(d):[],p=l.headers.get("X-FITS-Type")||i.FLOAT64,u=l.headers.get("Content-Length"),w=u?parseInt(u,10):0;if(!t||!w||!l.body)return{buffer:await l.arrayBuffer(),shape:h,arrayType:p};const g=l.body.getReader(),f=[];let I=0,y=await g.read();for(;!y.done;)f.push(y.value),I+=y.value.length,t(I,w),y=await g.read();const S=new ArrayBuffer(I),v=new Uint8Array(S);let T=0;for(const e of f)v.set(e,T),T+=e.length;return{buffer:S,shape:h,arrayType:p}}(`slice?path=${encodeURIComponent(n)}&hdu=${d}&slices=${encodeURIComponent(w)}`,(n,i)=>{const r=Math.round(n/i*100);e.style.width=`${r}%`,t.textContent=`${r}% (${c(n)} / ${c(i)})`},this._fetchAbortController.signal);console.log("[FITSViewer] Fetch complete:",{bufferLength:r.byteLength,resultShape:p,arrayType:g}),this._fetchAbortController=null;const f=p[p.length-2]||1,I=p[p.length-1]||1;console.log("[FITSViewer] Image dimensions:",{width:I,height:f}),a?(console.log("[FITSViewer] Clearing container and creating viewer"),a.innerHTML="",await l.createViewer(h),this._setupViewer(d,h),console.log("[FITSViewer] Viewer created, hasViewer:",l.hasViewer(h))):console.warn("[FITSViewer] No viewer container!"),console.log("[FITSViewer] Calling setSliceData"),l.setSliceData(h,r,I,f,g,u),console.log("[FITSViewer] setSliceData complete")}catch(e){if(this._fetchAbortController=null,"AbortError"===e.name)return void console.log("Fetch cancelled by user");console.error("Failed to load slice:",e),n.innerHTML=`<span class="jp-FITSViewer-error">Error: ${e}</span>`}}async _fetchAndDisplaySlice(){const e=this._getActiveSliceState(),t=this._activeHduIndex;if(!e||!l||null===t)return;const n=this._getViewerId(t),{shape:r,sliceIndices:a}=e;if(!await this._ensureViewer(t))return void l.failSliceRequest(n,a);const c=r.map((e,t)=>{if(t<r.length-2){const e=a[t];return`${e}:${e+1}`}return`0:${e}`}).join(",");try{const e=this._context.path,{buffer:r,shape:d,arrayType:h}=await async function(e="",t={}){const n=s.ServerConnection.makeSettings(),r=o.URLExt.join(n.baseUrl,"fitsview",e);let a;try{a=await s.ServerConnection.makeRequest(r,t,n)}catch(e){throw new s.ServerConnection.NetworkError(e)}if(!a.ok){const e=await a.text();let t=e;try{const n=JSON.parse(e);t=n.error||n.message||e}catch{}throw new s.ServerConnection.ResponseError(a,t)}const c=await a.arrayBuffer(),l=a.headers.get("X-FITS-Shape");return{buffer:c,shape:l?JSON.parse(l):[],arrayType:a.headers.get("X-FITS-Type")||i.FLOAT64}}(`slice?path=${encodeURIComponent(e)}&hdu=${t}&slices=${encodeURIComponent(c)}`),p=d[d.length-2]||1,u=d[d.length-1]||1;l.setSliceData(n,r,u,p,h,a)}catch(e){console.error("Failed to load slice:",e),l.failSliceRequest(n,a)}}onCloseRequest(e){l&&this._viewerContainers.forEach((e,t)=>{const n=this._getViewerId(t);l.hasViewer(n)&&l.destroyViewer(n)}),super.onCloseRequest(e),this.dispose()}}h._instanceCounter=0;class p extends r.DocumentWidget{constructor(e){super(e)}}const u="fitsview-provider";class w extends s.RestContentProvider{async get(e,t){return super.get(e,{...t,content:!1})}}class g extends r.ABCWidgetFactory{createNewWidget(e){const t=new h(e);return new p({context:e,content:t})}}class f{constructor(){this._disposed=!1}get name(){return"fits-model"}get contentType(){return"file"}get fileFormat(){return null}get isDisposed(){return this._disposed}dispose(){this._disposed=!0}preferredLanguage(e){return""}createNew(e){return new r.DocumentModel}}const I={id:"fitsview:plugin",description:"View FITS files in JupyterLab without downloading full content",autoStart:!0,requires:[s.IDefaultDrive],activate:(e,t)=>{console.log("JupyterLab extension fitsview is activated!");const n=t.contentProviderRegistry;if(n){const e=t.serverSettings;n.register(u,new w({apiEndpoint:"api/contents",serverSettings:e})),console.log("Registered FITS content provider")}e.docRegistry.addFileType({name:"fits",displayName:"FITS Image",mimeTypes:["image/fits"],extensions:[".fits",".fit",".fts"],fileFormat:"base64",contentType:"file",icon:void 0});const i=new f;e.docRegistry.addModelFactory(i);const r=new g({name:"FITS Viewer",modelName:"fits-model",fileTypes:["fits"],defaultFor:["fits"],contentProviderId:u});e.docRegistry.addWidgetFactory(r),console.log("FITS viewer factory registered")}}}}]);
@@ -0,0 +1 @@
1
+ var _JUPYTERLAB;(()=>{"use strict";var e,r,t,n,o,a,i,u,f,s,l,c,d,p,v,h,b,g,m,y,w,j,O,S,E,P,k,_={364(e,r,t){var n={"./index":()=>t.e(777).then(()=>()=>t(777)),"./extension":()=>t.e(777).then(()=>()=>t(777)),"./style":()=>t.e(728).then(()=>()=>t(728))},o=(e,r)=>(t.R=r,r=t.o(n,e)?n[e]():Promise.resolve().then(()=>{throw new Error('Module "'+e+'" does not exist in container.')}),t.R=void 0,r),a=(e,r)=>{if(t.S){var n="default",o=t.S[n];if(o&&o!==e)throw new Error("Container initialization failed as it has already been initialized with a different share scope");return t.S[n]=e,t.I(n,r)}};t.d(r,{get:()=>o,init:()=>a})}},T={};function x(e){var r=T[e];if(void 0!==r)return r.exports;var t=T[e]={id:e,exports:{}};return _[e](t,t.exports,x),t.exports}x.m=_,x.c=T,x.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return x.d(r,{a:r}),r},r=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,x.t=function(t,n){if(1&n&&(t=this(t)),8&n)return t;if("object"==typeof t&&t){if(4&n&&t.__esModule)return t;if(16&n&&"function"==typeof t.then)return t}var o=Object.create(null);x.r(o);var a={};e=e||[null,r({}),r([]),r(r)];for(var i=2&n&&t;("object"==typeof i||"function"==typeof i)&&!~e.indexOf(i);i=r(i))Object.getOwnPropertyNames(i).forEach(e=>a[e]=()=>t[e]);return a.default=()=>t,x.d(o,a),o},x.d=(e,r)=>{for(var t in r)x.o(r,t)&&!x.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},x.f={},x.e=e=>Promise.all(Object.keys(x.f).reduce((r,t)=>(x.f[t](e,r),r),[])),x.u=e=>e+"."+{55:"13fa04ce988048ddf392",728:"eef262677d8cfd2e5451",764:"6a51334b6670a55d4119",777:"39bf348560d484e689b7"}[e]+".js?v="+{55:"13fa04ce988048ddf392",728:"eef262677d8cfd2e5451",764:"6a51334b6670a55d4119",777:"39bf348560d484e689b7"}[e],x.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),x.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),t={},n="fitsview:",x.l=(e,r,o,a)=>{if(t[e])t[e].push(r);else{var i,u;if(void 0!==o)for(var f=document.getElementsByTagName("script"),s=0;s<f.length;s++){var l=f[s];if(l.getAttribute("src")==e||l.getAttribute("data-webpack")==n+o){i=l;break}}i||(u=!0,(i=document.createElement("script")).charset="utf-8",x.nc&&i.setAttribute("nonce",x.nc),i.setAttribute("data-webpack",n+o),i.src=e),t[e]=[r];var c=(r,n)=>{i.onerror=i.onload=null,clearTimeout(d);var o=t[e];if(delete t[e],i.parentNode&&i.parentNode.removeChild(i),o&&o.forEach(e=>e(n)),r)return r(n)},d=setTimeout(c.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=c.bind(null,i.onerror),i.onload=c.bind(null,i.onload),u&&document.head.appendChild(i)}},x.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{x.S={};var e={},r={};x.I=(t,n)=>{n||(n=[]);var o=r[t];if(o||(o=r[t]={}),!(n.indexOf(o)>=0)){if(n.push(o),e[t])return e[t];x.o(x.S,t)||(x.S[t]={});var a=x.S[t],i="fitsview",u=(e,r,t,n)=>{var o=a[e]=a[e]||{},u=o[r];(!u||!u.loaded&&(!n!=!u.eager?n:i>u.from))&&(o[r]={get:t,from:i,eager:!!n})},f=[];return"default"===t&&(u("fitsview","0.1.0",()=>x.e(777).then(()=>()=>x(777))),u("viewarr","0.1.0",()=>x.e(764).then(()=>()=>x(764)))),e[t]=f.length?Promise.all(f).then(()=>e[t]=1):1}}})(),(()=>{var e;x.g.importScripts&&(e=x.g.location+"");var r=x.g.document;if(!e&&r&&(r.currentScript&&"SCRIPT"===r.currentScript.tagName.toUpperCase()&&(e=r.currentScript.src),!e)){var t=r.getElementsByTagName("script");if(t.length)for(var n=t.length-1;n>-1&&(!e||!/^http(s?):/.test(e));)e=t[n--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),x.p=e})(),o=e=>{var r=e=>e.split(".").map(e=>+e==e?+e:e),t=/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(e),n=t[1]?r(t[1]):[];return t[2]&&(n.length++,n.push.apply(n,r(t[2]))),t[3]&&(n.push([]),n.push.apply(n,r(t[3]))),n},a=(e,r)=>{e=o(e),r=o(r);for(var t=0;;){if(t>=e.length)return t<r.length&&"u"!=(typeof r[t])[0];var n=e[t],a=(typeof n)[0];if(t>=r.length)return"u"==a;var i=r[t],u=(typeof i)[0];if(a!=u)return"o"==a&&"n"==u||"s"==u||"u"==a;if("o"!=a&&"u"!=a&&n!=i)return n<i;t++}},i=e=>{var r=e[0],t="";if(1===e.length)return"*";if(r+.5){t+=0==r?">=":-1==r?"<":1==r?"^":2==r?"~":r>0?"=":"!=";for(var n=1,o=1;o<e.length;o++)n--,t+="u"==(typeof(u=e[o]))[0]?"-":(n>0?".":"")+(n=2,u);return t}var a=[];for(o=1;o<e.length;o++){var u=e[o];a.push(0===u?"not("+f()+")":1===u?"("+f()+" || "+f()+")":2===u?a.pop()+" "+a.pop():i(u))}return f();function f(){return a.pop().replace(/^\((.+)\)$/,"$1")}},u=(e,r)=>{if(0 in e){r=o(r);var t=e[0],n=t<0;n&&(t=-t-1);for(var a=0,i=1,f=!0;;i++,a++){var s,l,c=i<e.length?(typeof e[i])[0]:"";if(a>=r.length||"o"==(l=(typeof(s=r[a]))[0]))return!f||("u"==c?i>t&&!n:""==c!=n);if("u"==l){if(!f||"u"!=c)return!1}else if(f)if(c==l)if(i<=t){if(s!=e[i])return!1}else{if(n?s>e[i]:s<e[i])return!1;s!=e[i]&&(f=!1)}else if("s"!=c&&"n"!=c){if(n||i<=t)return!1;f=!1,i--}else{if(i<=t||l<c!=n)return!1;f=!1}else"s"!=c&&"n"!=c&&(f=!1,i--)}}var d=[],p=d.pop.bind(d);for(a=1;a<e.length;a++){var v=e[a];d.push(1==v?p()|p():2==v?p()&p():v?u(v,r):!p())}return!!p()},f=(e,r)=>e&&x.o(e,r),s=e=>(e.loaded=1,e.get()),l=e=>Object.keys(e).reduce((r,t)=>(e[t].eager&&(r[t]=e[t]),r),{}),c=(e,r,t)=>{var n=t?l(e[r]):e[r];return(r=Object.keys(n).reduce((e,r)=>!e||a(e,r)?r:e,0))&&n[r]},d=(e,r,t,n)=>{var o=n?l(e[r]):e[r];return(r=Object.keys(o).reduce((e,r)=>!u(t,r)||e&&!a(e,r)?e:r,0))&&o[r]},p=(e,r,t)=>{var n=t?l(e[r]):e[r];return Object.keys(n).reduce((e,r)=>!e||!n[e].loaded&&a(e,r)?r:e,0)},v=(e,r,t,n)=>"Unsatisfied version "+t+" from "+(t&&e[r][t].from)+" of shared singleton module "+r+" (required "+i(n)+")",h=(e,r,t,n,o)=>{var a=e[t];return"No satisfying version ("+i(n)+")"+(o?" for eager consumption":"")+" of shared module "+t+" found in shared scope "+r+".\nAvailable versions: "+Object.keys(a).map(e=>e+" from "+a[e].from).join(", ")},b=e=>{throw new Error(e)},g=e=>{"undefined"!=typeof console&&console.warn&&console.warn(e)},y=(e,r,t)=>t?t():((e,r)=>b("Shared module "+r+" doesn't exist in shared scope "+e))(e,r),w=(m=e=>function(r,t,n,o,a){var i=x.I(r);return i&&i.then&&!n?i.then(e.bind(e,r,x.S[r],t,!1,o,a)):e(r,x.S[r],t,n,o,a)})((e,r,t,n,o)=>f(r,t)?s(c(r,t,n)):y(e,t,o)),j=m((e,r,t,n,o,a)=>{if(!f(r,t))return y(e,t,a);var i=d(r,t,o,n);return i?s(i):(g(h(r,e,t,o,n)),s(c(r,t,n)))}),O=m((e,r,t,n,o,a)=>{if(!f(r,t))return y(e,t,a);var i=p(r,t,n);return u(o,i)||g(v(r,t,i,o)),s(r[t][i])}),S={},E={206:()=>j("default","@jupyterlab/docregistry",!1,[1,4,0,13]),534:()=>O("default","@lumino/widgets",!1,[1,2,0,1]),684:()=>O("default","@jupyterlab/coreutils",!1,[1,6,0,13]),961:()=>O("default","@jupyterlab/services",!1,[1,7,0,13]),32:()=>w("default","viewarr",!1,()=>x.e(764).then(()=>()=>x(764)))},P={32:[32],777:[206,534,684,961]},k={},x.f.consumes=(e,r)=>{x.o(P,e)&&P[e].forEach(e=>{if(x.o(S,e))return r.push(S[e]);if(!k[e]){var t=r=>{S[e]=0,x.m[e]=t=>{delete x.c[e],t.exports=r()}};k[e]=!0;var n=r=>{delete S[e],x.m[e]=t=>{throw delete x.c[e],r}};try{var o=E[e]();o.then?r.push(S[e]=o.then(t).catch(n)):t(o)}catch(e){n(e)}}})},(()=>{x.b="undefined"!=typeof document&&document.baseURI||self.location.href;var e={712:0};x.f.j=(r,t)=>{var n=x.o(e,r)?e[r]:void 0;if(0!==n)if(n)t.push(n[2]);else if(32!=r){var o=new Promise((t,o)=>n=e[r]=[t,o]);t.push(n[2]=o);var a=x.p+x.u(r),i=new Error;x.l(a,t=>{if(x.o(e,r)&&(0!==(n=e[r])&&(e[r]=void 0),n)){var o=t&&("load"===t.type?"missing":t.type),a=t&&t.target&&t.target.src;i.message="Loading chunk "+r+" failed.\n("+o+": "+a+")",i.name="ChunkLoadError",i.type=o,i.request=a,n[1](i)}},"chunk-"+r,r)}else e[r]=0};var r=(r,t)=>{var n,o,[a,i,u]=t,f=0;if(a.some(r=>0!==e[r])){for(n in i)x.o(i,n)&&(x.m[n]=i[n]);u&&u(x)}for(r&&r(t);f<a.length;f++)o=a[f],x.o(e,o)&&e[o]&&e[o][0](),e[o]=0},t=self.webpackChunkfitsview=self.webpackChunkfitsview||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),x.nc=void 0;var A=x(364);(_JUPYTERLAB=void 0===_JUPYTERLAB?{}:_JUPYTERLAB).fitsview=A})();
@@ -0,0 +1,87 @@
1
+ // Type declarations for viewarr WASM module
2
+ declare module 'viewarr' {
3
+ /**
4
+ * Create a new viewer instance in the specified container.
5
+ */
6
+ export function createViewer(containerId: string): Promise<void>;
7
+
8
+ /**
9
+ * Set image data for a viewer.
10
+ * Pan is reset if dimensions change; zoom is always preserved.
11
+ */
12
+ export function setImageData(
13
+ containerId: string,
14
+ buffer: ArrayBuffer,
15
+ width: number,
16
+ height: number,
17
+ dtype: string
18
+ ): void;
19
+
20
+ /**
21
+ * Declare the sliceable leading axes of an N-D cube. The widget renders the
22
+ * slice + play controls; pass an empty array for a plain 2D image.
23
+ * @param dims - Lengths of the leading (sliceable) axes, outer→inner.
24
+ */
25
+ export function setCube(containerId: string, dims: number[]): void;
26
+
27
+ /**
28
+ * Set image data for a specific cube slice, tagged with its slice indices so
29
+ * the widget can sync slider positions and correlate play-mode prefetches.
30
+ * @param indices - Slice indices this image corresponds to (may be empty).
31
+ */
32
+ export function setSliceData(
33
+ containerId: string,
34
+ buffer: ArrayBuffer,
35
+ width: number,
36
+ height: number,
37
+ dtype: string,
38
+ indices: number[]
39
+ ): void;
40
+
41
+ /**
42
+ * Abandon an in-flight slice request that could not be fulfilled.
43
+ *
44
+ * The widget only issues a new request while none is in flight, so a request
45
+ * that never gets a reply leaves the scrubber permanently dead. Call this on
46
+ * every path where a fetch fails or is dropped.
47
+ * @param indices - The indices of the request being abandoned.
48
+ */
49
+ export function failSliceRequest(
50
+ containerId: string,
51
+ indices: number[]
52
+ ): void;
53
+
54
+ /**
55
+ * Register a callback invoked when the widget needs a cube slice fetched
56
+ * (slider drag or play loop). The host should fetch that slice and deliver it
57
+ * via setSliceData.
58
+ */
59
+ export function onSliceRequest(
60
+ containerId: string,
61
+ callback: (indices: number[]) => void
62
+ ): void;
63
+
64
+ /**
65
+ * Notify a viewer that its container has been resized.
66
+ */
67
+ export function notifyResize(
68
+ containerId: string,
69
+ width: number,
70
+ height: number
71
+ ): void;
72
+
73
+ /**
74
+ * Destroy a viewer instance and clean up resources.
75
+ */
76
+ export function destroyViewer(containerId: string): void;
77
+
78
+ /**
79
+ * Check if a viewer exists for a given container.
80
+ */
81
+ export function hasViewer(containerId: string): boolean;
82
+
83
+ /**
84
+ * Get all active viewer IDs.
85
+ */
86
+ export function getActiveViewers(): string[];
87
+ }
@@ -77,7 +77,6 @@ export class FITSPanel extends Widget {
77
77
  private _sliceStates: Map<number, ISliceState> = new Map();
78
78
  // Currently active HDU index
79
79
  private _activeHduIndex: number | null = null;
80
- private _sliceControlsContainer: HTMLDivElement | null = null;
81
80
  private _fetchAbortController: AbortController | null = null;
82
81
 
83
82
  constructor(context: DocumentRegistry.IContext<DocumentModel>) {
@@ -200,7 +199,6 @@ export class FITSPanel extends Widget {
200
199
  <div class="jp-FITSViewer-viewerPanel">
201
200
  <div class="jp-FITSViewer-controlBar">
202
201
  <div class="jp-FITSViewer-hduBar">${hduButtonsHtml}</div>
203
- <div id="${this._baseViewerId}-controls" class="jp-FITSViewer-sliceControls"></div>
204
202
  </div>
205
203
  <div class="jp-FITSViewer-viewerStack">
206
204
  ${viewerContainersHtml}
@@ -221,10 +219,6 @@ export class FITSPanel extends Widget {
221
219
  }
222
220
  }
223
221
 
224
- this._sliceControlsContainer = document.getElementById(
225
- `${this._baseViewerId}-controls`
226
- ) as HTMLDivElement;
227
-
228
222
  // Wait for viewarr to be ready, then auto-display first viewable HDU
229
223
  // Note: We don't create the viewer here - it's created on-demand when needed
230
224
  void viewarrPromise.then(() => {
@@ -369,6 +363,7 @@ export class FITSPanel extends Widget {
369
363
  // Clear any placeholder content
370
364
  viewerContainer.innerHTML = '';
371
365
  await viewarr.createViewer(viewerId);
366
+ this._setupViewer(hduIndex, viewerId);
372
367
  return true;
373
368
  } catch (error) {
374
369
  console.error('Failed to create viewarr viewer:', error);
@@ -376,6 +371,47 @@ export class FITSPanel extends Widget {
376
371
  }
377
372
  }
378
373
 
374
+ /**
375
+ * Declare the cube's sliceable leading axes to a freshly-created viewer and
376
+ * register the slice-request callback. The slice + play UI lives in the
377
+ * widget; slices are still served on demand from the FITS backend.
378
+ */
379
+ private _setupViewer(hduIndex: number, viewerId: string): void {
380
+ if (!viewarr) {
381
+ return;
382
+ }
383
+ const hdu = this._metadata?.hdus.find(h => h.index === hduIndex);
384
+ const shape = hdu?.shape;
385
+ if (!shape || shape.length < 2) {
386
+ return;
387
+ }
388
+ const leading = shape.length > 2 ? shape.slice(0, shape.length - 2) : [];
389
+ viewarr.setCube(viewerId, leading);
390
+ viewarr.onSliceRequest(viewerId, indices => {
391
+ void this._onSliceRequest(hduIndex, indices);
392
+ });
393
+ }
394
+
395
+ /**
396
+ * Handle a slice request from the viewer widget (slider drag or play loop):
397
+ * record the requested leading-axis indices and fetch that slice on demand.
398
+ */
399
+ private async _onSliceRequest(
400
+ hduIndex: number,
401
+ indices: number[]
402
+ ): Promise<void> {
403
+ const sliceState = this._sliceStates.get(hduIndex);
404
+ if (!sliceState) {
405
+ // Nothing here can serve the request, so tell the widget it died.
406
+ // Otherwise it waits forever on a reply that is never coming and the
407
+ // scrubber stops responding for the rest of the session.
408
+ viewarr?.failSliceRequest(this._getViewerId(hduIndex), indices);
409
+ return;
410
+ }
411
+ sliceState.sliceIndices = indices.slice();
412
+ await this._fetchAndDisplaySlice();
413
+ }
414
+
379
415
  /**
380
416
  * Automatically display the first HDU with viewable 2D+ data
381
417
  */
@@ -422,9 +458,6 @@ export class FITSPanel extends Widget {
422
458
  this._sliceStates.set(hduIndex, sliceState);
423
459
  }
424
460
 
425
- // Render slice controls for this HDU
426
- this._renderSliceControls();
427
-
428
461
  // Check if viewer already has data loaded (don't re-fetch if switching back)
429
462
  const viewerId = this._getViewerId(hduIndex);
430
463
  if (viewarr.hasViewer(viewerId)) {
@@ -605,6 +638,7 @@ export class FITSPanel extends Widget {
605
638
  console.log('[FITSViewer] Clearing container and creating viewer');
606
639
  viewerContainer.innerHTML = '';
607
640
  await viewarr.createViewer(viewerId);
641
+ this._setupViewer(hduIndex, viewerId);
608
642
  console.log(
609
643
  '[FITSViewer] Viewer created, hasViewer:',
610
644
  viewarr.hasViewer(viewerId)
@@ -613,9 +647,16 @@ export class FITSPanel extends Widget {
613
647
  console.warn('[FITSViewer] No viewer container!');
614
648
  }
615
649
 
616
- console.log('[FITSViewer] Calling setImageData');
617
- viewarr.setImageData(viewerId, buffer, width, height, arrayType);
618
- console.log('[FITSViewer] setImageData complete');
650
+ console.log('[FITSViewer] Calling setSliceData');
651
+ viewarr.setSliceData(
652
+ viewerId,
653
+ buffer,
654
+ width,
655
+ height,
656
+ arrayType,
657
+ sliceIndices
658
+ );
659
+ console.log('[FITSViewer] setSliceData complete');
619
660
  } catch (error) {
620
661
  this._fetchAbortController = null;
621
662
  if ((error as Error).name === 'AbortError') {
@@ -627,90 +668,6 @@ export class FITSPanel extends Widget {
627
668
  }
628
669
  }
629
670
 
630
- /**
631
- * Render slice navigation controls for leading axes
632
- */
633
- private _renderSliceControls(): void {
634
- const sliceState = this._getActiveSliceState();
635
- if (!this._sliceControlsContainer || !sliceState) {
636
- return;
637
- }
638
-
639
- const { shape, sliceIndices } = sliceState;
640
- const numLeadingAxes = shape.length - 2;
641
-
642
- if (numLeadingAxes === 0) {
643
- // No leading axes, hide controls
644
- this._sliceControlsContainer.innerHTML = '';
645
- return;
646
- }
647
-
648
- let html = '';
649
- for (let axis = 0; axis < numLeadingAxes; axis++) {
650
- const axisSize = shape[axis];
651
- const currentIndex = sliceIndices[axis];
652
- const axisLabel = numLeadingAxes === 1 ? 'Plane' : `Axis ${axis}`;
653
-
654
- html += `
655
- <div class="jp-FITSViewer-sliceControl" data-axis="${axis}">
656
- <button class="jp-FITSViewer-sliceButton jp-FITSViewer-prevButton"
657
- data-axis="${axis}"
658
- data-direction="prev"
659
- ${currentIndex === 0 ? 'disabled' : ''}>
660
- ◀
661
- </button>
662
- <span class="jp-FITSViewer-sliceLabel">
663
- ${axisLabel}: <strong>${currentIndex + 1}</strong> / ${axisSize}
664
- </span>
665
- <button class="jp-FITSViewer-sliceButton jp-FITSViewer-nextButton"
666
- data-axis="${axis}"
667
- data-direction="next"
668
- ${currentIndex >= axisSize - 1 ? 'disabled' : ''}>
669
- ▶
670
- </button>
671
- </div>
672
- `;
673
- }
674
-
675
- this._sliceControlsContainer.innerHTML = html;
676
-
677
- // Attach event listeners
678
- const buttons = this._sliceControlsContainer.querySelectorAll(
679
- '.jp-FITSViewer-sliceButton'
680
- );
681
- buttons.forEach(btn => {
682
- btn.addEventListener('click', e => {
683
- const target = e.currentTarget as HTMLElement;
684
- const axis = parseInt(target.dataset.axis || '0', 10);
685
- const direction = target.dataset.direction;
686
- this._navigateSlice(axis, direction === 'next' ? 1 : -1);
687
- });
688
- });
689
- }
690
-
691
- /**
692
- * Navigate to a different slice along a given axis
693
- */
694
- private _navigateSlice(axis: number, delta: number): void {
695
- const sliceState = this._getActiveSliceState();
696
- if (!sliceState) {
697
- return;
698
- }
699
-
700
- const { shape, sliceIndices } = sliceState;
701
- const axisSize = shape[axis];
702
- const newIndex = Math.max(
703
- 0,
704
- Math.min(axisSize - 1, sliceIndices[axis] + delta)
705
- );
706
-
707
- if (newIndex !== sliceIndices[axis]) {
708
- sliceState.sliceIndices[axis] = newIndex;
709
- this._renderSliceControls();
710
- void this._fetchAndDisplaySlice();
711
- }
712
- }
713
-
714
671
  /**
715
672
  * Fetch and display the current slice based on slice state
716
673
  */
@@ -722,15 +679,16 @@ export class FITSPanel extends Widget {
722
679
  return;
723
680
  }
724
681
 
682
+ const viewerId = this._getViewerId(hduIndex);
683
+ const { shape, sliceIndices } = sliceState;
684
+
725
685
  // Ensure viewer exists (creates on-demand)
726
686
  const viewerReady = await this._ensureViewer(hduIndex);
727
687
  if (!viewerReady) {
688
+ viewarr.failSliceRequest(viewerId, sliceIndices);
728
689
  return;
729
690
  }
730
691
 
731
- const viewerId = this._getViewerId(hduIndex);
732
- const { shape, sliceIndices } = sliceState;
733
-
734
692
  // Build slice string: for leading axes use current index, for image axes use full extent
735
693
  const slices = shape
736
694
  .map((size, i) => {
@@ -756,10 +714,23 @@ export class FITSPanel extends Widget {
756
714
  const height = resultShape[resultShape.length - 2] || 1;
757
715
  const width = resultShape[resultShape.length - 1] || 1;
758
716
 
759
- // Use arrayType from response for proper data interpretation
760
- viewarr.setImageData(viewerId, buffer, width, height, arrayType);
717
+ // Tag the slice with its leading-axis indices so the widget can track the
718
+ // slider position and correlate play-mode prefetch responses.
719
+ viewarr.setSliceData(
720
+ viewerId,
721
+ buffer,
722
+ width,
723
+ height,
724
+ arrayType,
725
+ sliceIndices
726
+ );
761
727
  } catch (error) {
762
728
  console.error('Failed to load slice:', error);
729
+ // A dropped reply wedges the widget: it only issues a new slice request
730
+ // while none is in flight, so swallowing this failure would leave the
731
+ // scrubber dead until the document is reloaded. One flaky request should
732
+ // cost one frame, not the session.
733
+ viewarr.failSliceRequest(viewerId, sliceIndices);
763
734
  }
764
735
  }
765
736