cloudmr-ux 2.0.7 → 3.0.2

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 (206) hide show
  1. package/README.md +24 -24
  2. package/dist/CmrComponents/CmrButton/CmrButton.css +0 -0
  3. package/dist/CmrComponents/CmrButton/CmrButton.d.ts +4 -0
  4. package/dist/CmrComponents/CmrButton/CmrButton.js +30 -0
  5. package/dist/CmrComponents/CmrButton/index.d.ts +1 -0
  6. package/dist/CmrComponents/CmrButton/index.js +1 -0
  7. package/dist/CmrComponents/CmrCheckbox/CmrCheckbox.css +29 -0
  8. package/dist/CmrComponents/CmrCheckbox/CmrCheckbox.d.ts +14 -0
  9. package/dist/CmrComponents/CmrCheckbox/CmrCheckbox.js +30 -0
  10. package/dist/CmrComponents/CmrCheckbox/index.d.ts +1 -0
  11. package/dist/CmrComponents/CmrCheckbox/index.js +1 -0
  12. package/dist/CmrComponents/CmrColorPicker/CmrColorPicker.d.ts +8 -0
  13. package/dist/CmrComponents/CmrColorPicker/CmrColorPicker.js +29 -0
  14. package/dist/CmrComponents/CmrColorPicker/CmrColorPicker.scss +27 -0
  15. package/dist/CmrComponents/CmrInput/CmrInput.css +27 -0
  16. package/dist/CmrComponents/CmrInput/CmrInput.d.ts +17 -0
  17. package/dist/CmrComponents/CmrInput/CmrInput.js +29 -0
  18. package/dist/CmrComponents/CmrInput/index.d.ts +1 -0
  19. package/dist/CmrComponents/CmrInput/index.js +1 -0
  20. package/dist/CmrComponents/CmrRadioGroup/CmrRadioGroup.css +25 -0
  21. package/dist/CmrComponents/CmrRadioGroup/CmrRadioGroup.d.ts +15 -0
  22. package/dist/CmrComponents/CmrRadioGroup/CmrRadioGroup.js +37 -0
  23. package/dist/CmrComponents/CmrRadioGroup/index.d.ts +1 -0
  24. package/dist/CmrComponents/CmrRadioGroup/index.js +1 -0
  25. package/dist/CmrComponents/CmrSelect/CmrSelect.css +1 -0
  26. package/dist/CmrComponents/CmrSelect/CmrSelect.d.ts +24 -0
  27. package/dist/CmrComponents/CmrSelect/CmrSelect.js +46 -0
  28. package/dist/CmrComponents/CmrSelect/index.d.ts +1 -0
  29. package/dist/CmrComponents/CmrSelect/index.js +1 -0
  30. package/dist/CmrComponents/checkbox/Checkbox.css +8 -0
  31. package/dist/CmrComponents/checkbox/Checkbox.d.ts +15 -0
  32. package/dist/CmrComponents/checkbox/Checkbox.js +25 -0
  33. package/dist/CmrComponents/collapse/Collapse.css +3 -0
  34. package/dist/CmrComponents/collapse/Collapse.d.ts +18 -0
  35. package/dist/CmrComponents/collapse/Collapse.js +87 -0
  36. package/dist/CmrComponents/dialogue/Confirmation.d.ts +20 -0
  37. package/dist/CmrComponents/dialogue/Confirmation.js +36 -0
  38. package/dist/CmrComponents/dialogue/DeletionDialog.d.ts +4 -0
  39. package/dist/CmrComponents/dialogue/DeletionDialog.js +39 -0
  40. package/dist/CmrComponents/dialogue/EditConfirmation.d.ts +13 -0
  41. package/dist/CmrComponents/dialogue/EditConfirmation.js +45 -0
  42. package/dist/CmrComponents/double-slider/DualSlider.d.ts +21 -0
  43. package/dist/CmrComponents/double-slider/DualSlider.js +152 -0
  44. package/dist/CmrComponents/double-slider/InvertibleDualSlider.d.ts +24 -0
  45. package/dist/CmrComponents/double-slider/InvertibleDualSlider.js +174 -0
  46. package/dist/CmrComponents/gui-slider/ControlledSlider.d.ts +9 -0
  47. package/dist/CmrComponents/gui-slider/ControlledSlider.js +96 -0
  48. package/dist/CmrComponents/gui-slider/Slider.d.ts +20 -0
  49. package/dist/CmrComponents/gui-slider/Slider.js +127 -0
  50. package/dist/CmrComponents/header/Header.d.ts +17 -0
  51. package/dist/CmrComponents/header/Header.js +90 -0
  52. package/dist/CmrComponents/header/Header.scss +32 -0
  53. package/dist/CmrComponents/input-number/InputNumber.css +0 -0
  54. package/dist/CmrComponents/input-number/InputNumber.d.ts +17 -0
  55. package/dist/CmrComponents/input-number/InputNumber.js +30 -0
  56. package/dist/CmrComponents/label/Label.css +13 -0
  57. package/dist/CmrComponents/label/Label.d.ts +9 -0
  58. package/dist/CmrComponents/label/Label.js +18 -0
  59. package/dist/CmrComponents/panel/Panel.css +5 -0
  60. package/dist/CmrComponents/panel/Panel.d.ts +12 -0
  61. package/dist/CmrComponents/panel/Panel.js +42 -0
  62. package/dist/CmrComponents/rename/edit.d.ts +7 -0
  63. package/dist/CmrComponents/rename/edit.js +117 -0
  64. package/dist/CmrComponents/select-upload/SelectUpload.css +26 -0
  65. package/dist/CmrComponents/select-upload/SelectUpload.d.ts +33 -0
  66. package/dist/CmrComponents/select-upload/SelectUpload.js +90 -0
  67. package/dist/CmrComponents/tk-dualrange/TKDualRange.d.ts +17 -0
  68. package/dist/CmrComponents/tk-dualrange/TKDualRange.js +65 -0
  69. package/dist/CmrComponents/tk-dualrange/tk-dual-range.css +140 -0
  70. package/dist/CmrComponents/tooltip/Tooltip.css +0 -0
  71. package/dist/CmrComponents/tooltip/Tooltip.d.ts +18 -0
  72. package/dist/CmrComponents/tooltip/Tooltip.js +30 -0
  73. package/dist/CmrComponents/upload/Upload.css +5 -0
  74. package/dist/CmrComponents/upload/Upload.d.ts +80 -0
  75. package/dist/CmrComponents/upload/Upload.js +185 -0
  76. package/dist/CmrComponents/upload/UploadWindow.d.ts +15 -0
  77. package/dist/CmrComponents/upload/UploadWindow.js +286 -0
  78. package/dist/CmrTable/CmrTable.css +26 -0
  79. package/dist/CmrTable/CmrTable.d.ts +13 -0
  80. package/dist/CmrTable/CmrTable.js +47 -0
  81. package/dist/CmrTabs/CmrTabs.d.ts +7 -0
  82. package/dist/CmrTabs/CmrTabs.js +64 -0
  83. package/dist/CmrTabs/tab.model.d.ts +12 -0
  84. package/dist/CmrTabs/tab.model.js +1 -0
  85. package/dist/core/app/main/Main.d.ts +6 -0
  86. package/dist/core/app/main/Main.js +18 -0
  87. package/dist/core/app/results/Logs.d.ts +1 -0
  88. package/dist/core/app/results/Logs.js +33 -0
  89. package/dist/core/app/results/PreprocessJob.d.ts +1 -0
  90. package/dist/core/app/results/PreprocessJob.js +100 -0
  91. package/dist/core/app/results/Results.d.ts +15 -0
  92. package/dist/core/app/results/Results.js +372 -0
  93. package/dist/core/app/results/Results.scss +92 -0
  94. package/dist/core/app/results/Rois.d.ts +11 -0
  95. package/dist/core/app/results/Rois.js +269 -0
  96. package/dist/core/app/settings/Settings.d.ts +1 -0
  97. package/dist/core/app/settings/Settings.js +109 -0
  98. package/dist/core/app/signin/ForgotPassword.d.ts +3 -0
  99. package/dist/core/app/signin/ForgotPassword.js +142 -0
  100. package/dist/core/app/signin/Register.d.ts +3 -0
  101. package/dist/core/app/signin/Register.js +126 -0
  102. package/dist/core/app/signin/Signin.d.ts +5 -0
  103. package/dist/core/app/signin/Signin.js +84 -0
  104. package/dist/core/app/signin/Signin.scss +86 -0
  105. package/dist/core/app/upload/Upload.d.ts +3 -0
  106. package/dist/core/app/upload/Upload.js +261 -0
  107. package/dist/core/app/upload/Upload.scss +0 -0
  108. package/dist/core/common/components/CmrColorPicker/CmrColorPicker.d.ts +8 -0
  109. package/dist/core/common/components/CmrColorPicker/CmrColorPicker.js +29 -0
  110. package/dist/core/common/components/CmrColorPicker/CmrColorPicker.scss +27 -0
  111. package/dist/core/common/components/NiivueTools/Niivue.css +8 -0
  112. package/dist/core/common/components/NiivueTools/Niivue.d.ts +14 -0
  113. package/dist/core/common/components/NiivueTools/Niivue.js +1270 -0
  114. package/dist/core/common/components/NiivueTools/NiivuePatcher.js +1875 -0
  115. package/dist/core/common/components/NiivueTools/components/ColorPicker.d.ts +5 -0
  116. package/dist/core/common/components/NiivueTools/components/ColorPicker.js +68 -0
  117. package/dist/core/common/components/NiivueTools/components/DrawPlatte.d.ts +10 -0
  118. package/dist/core/common/components/NiivueTools/components/DrawPlatte.js +88 -0
  119. package/dist/core/common/components/NiivueTools/components/DrawToolKit.d.ts +32 -0
  120. package/dist/core/common/components/NiivueTools/components/DrawToolKit.js +164 -0
  121. package/dist/core/common/components/NiivueTools/components/EraserPlatte.d.ts +10 -0
  122. package/dist/core/common/components/NiivueTools/components/EraserPlatte.js +43 -0
  123. package/dist/core/common/components/NiivueTools/components/Layer.d.ts +10 -0
  124. package/dist/core/common/components/NiivueTools/components/Layer.js +117 -0
  125. package/dist/core/common/components/NiivueTools/components/LayersPanel.d.ts +8 -0
  126. package/dist/core/common/components/NiivueTools/components/LayersPanel.js +108 -0
  127. package/dist/core/common/components/NiivueTools/components/LocationTable.d.ts +9 -0
  128. package/dist/core/common/components/NiivueTools/components/LocationTable.js +42 -0
  129. package/dist/core/common/components/NiivueTools/components/MaskPlatte.d.ts +10 -0
  130. package/dist/core/common/components/NiivueTools/components/MaskPlatte.js +123 -0
  131. package/dist/core/common/components/NiivueTools/components/NiivuePanel.d.ts +34 -0
  132. package/dist/core/common/components/NiivueTools/components/NiivuePanel.js +305 -0
  133. package/dist/core/common/components/NiivueTools/components/NumberPicker.d.ts +8 -0
  134. package/dist/core/common/components/NiivueTools/components/NumberPicker.js +40 -0
  135. package/dist/core/common/components/NiivueTools/components/SettingsPanel.d.ts +7 -0
  136. package/dist/core/common/components/NiivueTools/components/SettingsPanel.js +30 -0
  137. package/dist/core/common/components/NiivueTools/components/Switch.d.ts +5 -0
  138. package/dist/core/common/components/NiivueTools/components/Switch.js +26 -0
  139. package/dist/core/common/components/NiivueTools/components/Toolbar.d.ts +40 -0
  140. package/dist/core/common/components/NiivueTools/components/Toolbar.js +184 -0
  141. package/dist/core/common/components/NiivueTools/components/Toolbar.scss +39 -0
  142. package/dist/core/common/components/NiivueTools/components/stats.d.ts +2 -0
  143. package/dist/core/common/components/NiivueTools/components/stats.js +13 -0
  144. package/dist/core/common/components/NiivueTools/index.css +14 -0
  145. package/dist/core/common/components/NiivueTools/util.js +309 -0
  146. package/dist/core/common/components/footer/Footer.d.ts +3 -0
  147. package/dist/core/common/components/footer/Footer.js +20 -0
  148. package/dist/core/common/components/footer/Footer.scss +5 -0
  149. package/dist/core/common/utilities/AuthenticatedRequests.d.ts +16 -0
  150. package/dist/core/common/utilities/AuthenticatedRequests.js +158 -0
  151. package/dist/core/common/utilities/CalendarHelper.d.ts +5 -0
  152. package/dist/core/common/utilities/CalendarHelper.js +27 -0
  153. package/dist/core/common/utilities/DownloadFromText.d.ts +3 -0
  154. package/dist/core/common/utilities/DownloadFromText.js +20 -0
  155. package/dist/core/common/utilities/StoreToRequest.d.ts +1 -0
  156. package/dist/core/common/utilities/StoreToRequest.js +4 -0
  157. package/dist/core/common/utilities/SystemUtilities.d.ts +4 -0
  158. package/dist/core/common/utilities/SystemUtilities.js +79 -0
  159. package/dist/core/common/utilities/file-transformation/anonymize.d.ts +1 -0
  160. package/dist/core/common/utilities/file-transformation/anonymize.js +114 -0
  161. package/dist/core/common/utilities/file-transformation/utilities.d.ts +2 -0
  162. package/dist/core/common/utilities/file-transformation/utilities.js +23 -0
  163. package/dist/core/common/utilities/index.d.ts +25 -0
  164. package/dist/core/common/utilities/index.js +118 -0
  165. package/dist/core/common/utilities/parse-jwt.d.ts +1 -0
  166. package/dist/core/common/utilities/parse-jwt.js +14 -0
  167. package/dist/core/components/PasswordRequirements.d.ts +7 -0
  168. package/dist/core/components/PasswordRequirements.js +30 -0
  169. package/dist/core/config/AppConfig.d.ts +5 -0
  170. package/dist/core/config/AppConfig.js +42 -0
  171. package/dist/core/config/types.d.ts +40 -0
  172. package/dist/core/config/types.js +1 -0
  173. package/dist/core/features/authenticate/authenticateActionCreation.d.ts +46 -0
  174. package/dist/core/features/authenticate/authenticateActionCreation.js +326 -0
  175. package/dist/core/features/authenticate/authenticateSlice.d.ts +45 -0
  176. package/dist/core/features/authenticate/authenticateSlice.js +203 -0
  177. package/dist/core/features/data/dataActionCreation.d.ts +40 -0
  178. package/dist/core/features/data/dataActionCreation.js +340 -0
  179. package/dist/core/features/data/dataSlice.d.ts +37 -0
  180. package/dist/core/features/data/dataSlice.js +87 -0
  181. package/dist/core/features/jobs/jobActionCreation.d.ts +35 -0
  182. package/dist/core/features/jobs/jobActionCreation.js +242 -0
  183. package/dist/core/features/jobs/jobsSlice.d.ts +57 -0
  184. package/dist/core/features/jobs/jobsSlice.js +54 -0
  185. package/dist/core/features/rois/resultActionCreation.d.ts +21 -0
  186. package/dist/core/features/rois/resultActionCreation.js +114 -0
  187. package/dist/core/features/rois/resultSlice.d.ts +24 -0
  188. package/dist/core/features/rois/resultSlice.js +68 -0
  189. package/dist/core/features/rois/roiTypes.d.ts +44 -0
  190. package/dist/core/features/rois/roiTypes.js +1 -0
  191. package/dist/core/features/setup/setupActionCreation.d.ts +7 -0
  192. package/dist/core/features/setup/setupActionCreation.js +100 -0
  193. package/dist/core/index.d.ts +22 -0
  194. package/dist/core/index.js +27 -0
  195. package/dist/core/store/configureStore.d.ts +13 -0
  196. package/dist/core/store/configureStore.js +38 -0
  197. package/dist/core/store/hooks.d.ts +11 -0
  198. package/dist/core/store/hooks.js +5 -0
  199. package/dist/core/utils/passwordValidation.d.ts +25 -0
  200. package/dist/core/utils/passwordValidation.js +19 -0
  201. package/dist/index.d.ts +29 -329
  202. package/dist/index.js +26 -1402
  203. package/dist/style.css +47 -0
  204. package/package.json +309 -41
  205. package/dist/index.css +0 -170
  206. package/dist/index.mjs +0 -1354
@@ -0,0 +1,309 @@
1
+ import { mat4, vec3, vec4 } from 'gl-matrix'
2
+
3
+
4
+ // rotate image to match right-anterior-superior voxel order
5
+ export function img2ras16(volume) {
6
+ // return image oriented to RAS space as int16
7
+ const dims = volume.hdr.dims // reverse to original
8
+ const perm = volume.permRAS
9
+ const vx = dims[1] * dims[2] * dims[3]
10
+ // this.drawBitmap = new Uint8Array(vx);
11
+ const img16 = new Int16Array(vx)
12
+ const layout = [0, 0, 0]
13
+ for (let i = 0; i < 3; i++) {
14
+ for (let j = 0; j < 3; j++) {
15
+ if (Math.abs(perm[i]) - 1 !== j) {
16
+ continue
17
+ }
18
+ layout[j] = i * Math.sign(perm[i])
19
+ }
20
+ }
21
+ let stride = 1
22
+ const instride = [1, 1, 1]
23
+ const inflip = [false, false, false]
24
+ for (let i = 0; i < layout.length; i++) {
25
+ for (let j = 0; j < layout.length; j++) {
26
+ const a = Math.abs(layout[j])
27
+ if (a !== i) {
28
+ continue
29
+ }
30
+ instride[j] = stride
31
+ // detect -0: https://medium.com/coding-at-dawn/is-negative-zero-0-a-number-in-javascript-c62739f80114
32
+ if (layout[j] < 0 || Object.is(layout[j], -0)) {
33
+ inflip[j] = true
34
+ }
35
+ stride *= dims[j + 1]
36
+ }
37
+ }
38
+ // lookup table for flips and stride offsets:
39
+ const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1 }, (_, i) => start + i * step)
40
+ let xlut = range(0, dims[1] - 1, 1)
41
+ if (inflip[0]) {
42
+ xlut = range(dims[1] - 1, 0, -1)
43
+ }
44
+ for (let i = 0; i < dims[1]; i++) {
45
+ xlut[i] *= instride[0]
46
+ }
47
+ let ylut = range(0, dims[2] - 1, 1)
48
+ if (inflip[1]) {
49
+ ylut = range(dims[2] - 1, 0, -1)
50
+ }
51
+ for (let i = 0; i < dims[2]; i++) {
52
+ ylut[i] *= instride[1]
53
+ }
54
+ let zlut = range(0, dims[3] - 1, 1)
55
+ if (inflip[2]) {
56
+ zlut = range(dims[3] - 1, 0, -1)
57
+ }
58
+ for (let i = 0; i < dims[3]; i++) {
59
+ zlut[i] *= instride[2]
60
+ }
61
+ // convert data
62
+ let j = 0
63
+ for (let z = 0; z < dims[3]; z++) {
64
+ for (let y = 0; y < dims[2]; y++) {
65
+ for (let x = 0; x < dims[1]; x++) {
66
+ img16[xlut[x] + ylut[y] + zlut[z]] = volume.img[j]
67
+ j++
68
+ }
69
+ }
70
+ }
71
+ return img16
72
+ }
73
+
74
+ function nice(x, round) {
75
+ const exp = Math.floor(Math.log(x) / Math.log(10))
76
+ const f = x / Math.pow(10, exp)
77
+ let nf
78
+ if (round) {
79
+ if (f < 1.5) {
80
+ nf = 1
81
+ } else if (f < 3) {
82
+ nf = 2
83
+ } else if (f < 7) {
84
+ nf = 5
85
+ } else {
86
+ nf = 10
87
+ }
88
+ } else {
89
+ if (f <= 1) {
90
+ nf = 1
91
+ } else if (f <= 2) {
92
+ nf = 2
93
+ } else if (f <= 5) {
94
+ nf = 5
95
+ } else {
96
+ nf = 10
97
+ }
98
+ }
99
+ return nf * Math.pow(10, exp)
100
+ }
101
+
102
+ function loose_label(min, max, ntick = 4) {
103
+ const range = nice(max - min, false)
104
+ const d = nice(range / (ntick - 1), true)
105
+ const graphmin = Math.floor(min / d) * d
106
+ const graphmax = Math.ceil(max / d) * d
107
+ const perfect = graphmin === min && graphmax === max
108
+ return [d, graphmin, graphmax, perfect]
109
+ }
110
+
111
+ // "Nice Numbers for Graph Labels", Graphics Gems, pp 61-63
112
+ // https://github.com/cenfun/nice-ticks/blob/master/docs/Nice-Numbers-for-Graph-Labels.pdf
113
+ export function tickSpacing(mn, mx) {
114
+ let v = loose_label(mn, mx, 3)
115
+ if (!v[3]) {
116
+ v = loose_label(mn, mx, 5)
117
+ }
118
+ if (!v[3]) {
119
+ v = loose_label(mn, mx, 4)
120
+ }
121
+ if (!v[3]) {
122
+ v = loose_label(mn, mx, 3)
123
+ }
124
+ if (!v[3]) {
125
+ v = loose_label(mn, mx, 5)
126
+ }
127
+ return [v[0], v[1], v[2]]
128
+ }
129
+
130
+ // convert degrees to radians
131
+ export function deg2rad(deg) {
132
+ return deg * (Math.PI / 180.0)
133
+ }
134
+
135
+ export function negMinMax(min, max, minNeg, maxNeg) {
136
+ let mn = -min
137
+ let mx = -max
138
+ if (isFinite(minNeg) && isFinite(maxNeg)) {
139
+ mn = minNeg
140
+ mx = maxNeg
141
+ }
142
+ if (mn > mx) {
143
+ ;[mn, mx] = [mx, mn]
144
+ }
145
+ return [mn, mx]
146
+ }
147
+
148
+ export function swizzleVec3(vec, order = [0, 1, 2]) {
149
+ const vout = vec3.create()
150
+ vout[0] = vec[order[0]]
151
+ vout[1] = vec[order[1]]
152
+ vout[2] = vec[order[2]]
153
+ return vout
154
+ }
155
+
156
+ // return boolean is 2D slice view is radiological
157
+ // n.b. ambiguous for pure sagittal views
158
+ export function isRadiological(mtx) {
159
+ const vRight = vec4.fromValues(1, 0, 0, 0) // pure right vector
160
+ const vRotated = vec4.create()
161
+ vec4.transformMat4(vRotated, vRight, mtx)
162
+ return vRotated[0]
163
+ }
164
+
165
+ export function unProject(winX, winY, winZ, mvpMatrix) {
166
+ // https://github.com/bringhurst/webgl-unproject
167
+ const inp = vec4.fromValues(winX, winY, winZ, 1.0)
168
+ const finalMatrix = mat4.clone(mvpMatrix)
169
+ // mat.mat4.multiply(finalMatrix, model, proj);
170
+ mat4.invert(finalMatrix, finalMatrix)
171
+ // view is leftTopWidthHeight
172
+ /* Map to range -1 to 1 */
173
+ inp[0] = inp[0] * 2 - 1
174
+ inp[1] = inp[1] * 2 - 1
175
+ inp[2] = inp[2] * 2 - 1
176
+ const out = vec4.create()
177
+ vec4.transformMat4(out, inp, finalMatrix)
178
+ if (out[3] === 0.0) {
179
+ return out
180
+ } // error
181
+ out[0] /= out[3]
182
+ out[1] /= out[3]
183
+ out[2] /= out[3]
184
+ return out
185
+ }
186
+
187
+ export function unpackFloatFromVec4i(val) {
188
+ // Convert 32-bit rgba to float32
189
+ // https://github.com/rii-mango/Papaya/blob/782a19341af77a510d674c777b6da46afb8c65f1/src/js/viewer/screensurface.js#L552
190
+ const bitSh = [1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0]
191
+ return (val[0] * bitSh[0] + val[1] * bitSh[1] + val[2] * bitSh[2] + val[3] * bitSh[3]) / 255.0
192
+ }
193
+
194
+ // https://stackoverflow.com/questions/11409895/whats-the-most-elegant-way-to-cap-a-number-to-a-segment
195
+ export function clamp(value, min, max) {
196
+ return Math.min(Math.max(value, min), max)
197
+ }
198
+
199
+ // Internal function to compress drawing using run length encoding
200
+ // inputs
201
+ // data: Uint8Array to compress
202
+ // output
203
+ // returns rle compressed Uint8Array
204
+ export function encodeRLE(data) {
205
+ // https://en.wikipedia.org/wiki/PackBits
206
+ // run length encoding
207
+ // input and output are Uint8Array
208
+ // Will compress data with long runs up to x64
209
+ // Worst case encoded size is ~1% larger than input
210
+ const dl = data.length // input length
211
+ let dp = 0 // input position
212
+ // worst case: run length encoding (1+1/127) times larger than input
213
+ const r = new Uint8Array(dl + Math.ceil(0.01 * dl))
214
+ const rI = new Int8Array(r.buffer) // typecast as header can be negative
215
+ let rp = 0 // run length position
216
+ while (dp < dl) {
217
+ // for each byte in input
218
+ let v = data[dp]
219
+ dp++
220
+ let rl = 1 // run length
221
+ while (rl < 129 && dp < dl && data[dp] === v) {
222
+ dp++
223
+ rl++
224
+ }
225
+ if (rl > 1) {
226
+ // header
227
+ rI[rp] = -rl + 1
228
+ rp++
229
+ r[rp] = v
230
+ rp++
231
+ continue
232
+ }
233
+ // count literal length
234
+ while (dp < dl) {
235
+ if (rl > 127) {
236
+ break
237
+ }
238
+ if (dp + 2 < dl) {
239
+ // console.log(':', v, data[dp], data[dp+1]);
240
+ if (v !== data[dp] && data[dp + 2] === data[dp] && data[dp + 1] === data[dp]) {
241
+ break
242
+ }
243
+ }
244
+ v = data[dp]
245
+ dp++
246
+ rl++
247
+ }
248
+ // write header
249
+ r[rp] = rl - 1
250
+ rp++
251
+ for (let i = 0; i < rl; i++) {
252
+ r[rp] = data[dp - rl + i]
253
+ rp++
254
+ }
255
+ }
256
+ console.log('PackBits ' + dl + ' -> ' + rp + ' bytes (x' + dl / rp + ')')
257
+ return r.slice(0, rp)
258
+ }
259
+
260
+ // Internal function to decompress drawing using run length encoding
261
+ // inputs
262
+ // rle: packbits compressed stream
263
+ // decodedlen: size of uncompressed data
264
+ // output
265
+ // returns Uint8Array of decodedlen bytes
266
+ export function decodeRLE(rle, decodedlen) {
267
+ const r = new Uint8Array(rle.buffer)
268
+ const rI = new Int8Array(r.buffer) // typecast as header can be negative
269
+ let rp = 0 // input position in rle array
270
+ // d: output uncompressed data array
271
+ const d = new Uint8Array(decodedlen)
272
+ let dp = 0 // output position in decoded array
273
+ while (rp < r.length) {
274
+ // read header
275
+ const hdr = rI[rp]
276
+ rp++
277
+ if (hdr < 0) {
278
+ // write run
279
+ const v = rI[rp]
280
+ rp++
281
+ for (let i = 0; i < 1 - hdr; i++) {
282
+ d[dp] = v
283
+ dp++
284
+ }
285
+ } else {
286
+ // write literal
287
+ for (let i = 0; i < hdr + 1; i++) {
288
+ d[dp] = rI[rp]
289
+ rp++
290
+ dp++
291
+ }
292
+ }
293
+ }
294
+ return d
295
+ }
296
+
297
+ /**
298
+ * scale the raw intensity values by the header scale slope and intercept
299
+ * @param {object} hdr the header object
300
+ * @param {Array} raw the raw intensity values
301
+ * @returns {Array} the scaled intensity values
302
+ * @private
303
+ */
304
+ export function intensityRaw2Scaled(hdr, raw) {
305
+ if (hdr.scl_slope === 0) {
306
+ hdr.scl_slope = 1.0
307
+ }
308
+ return raw * hdr.scl_slope + hdr.scl_inter
309
+ }
@@ -0,0 +1,3 @@
1
+ import './Footer.scss';
2
+ declare const FooterBar: () => import("react/jsx-runtime").JSX.Element;
3
+ export default FooterBar;
@@ -0,0 +1,20 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ import { jsxs as _jsxs } from "react/jsx-runtime";
13
+ import './Footer.scss';
14
+ import { Layout } from 'antd';
15
+ var Footer = Layout.Footer;
16
+ var FooterBar = function () {
17
+ var currentYear = new Date().getFullYear();
18
+ return (_jsxs(Footer, __assign({ className: 'cmr-footer', style: { textAlign: 'center', background: '#f8fafc' } }, { children: ["@ ", currentYear, " Copyright: NYU Center for Biomedical Imaging. All rights reserved."] })));
19
+ };
20
+ export default FooterBar;
@@ -0,0 +1,5 @@
1
+ .cmr-footer{
2
+ position: absolute;
3
+ bottom: 0;
4
+ width: 100%;
5
+ }
@@ -0,0 +1,16 @@
1
+ import { type AxiosRequestConfig, type AxiosResponse } from 'axios';
2
+ import { AuthenticateState, AuthenticateToken } from '../../features/authenticate/authenticateSlice';
3
+ type TokenGetter = () => AuthenticateState;
4
+ export declare class AuthenticatedHttpClient {
5
+ private static authGetter;
6
+ private static dispatch;
7
+ static setAuthenticateStateGetter(getter: TokenGetter): void;
8
+ static setDispatch(dispatch: any): void;
9
+ static refreshToken(tk: AuthenticateToken): any;
10
+ static request<T = any>(config: AxiosRequestConfig): Promise<AxiosResponse<T>>;
11
+ static get<T = any>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
12
+ static post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
13
+ static put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
14
+ static delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>;
15
+ }
16
+ export {};
@@ -0,0 +1,158 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
+ return new (P || (P = Promise))(function (resolve, reject) {
15
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
19
+ });
20
+ };
21
+ var __generator = (this && this.__generator) || function (thisArg, body) {
22
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
23
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24
+ function verb(n) { return function (v) { return step([n, v]); }; }
25
+ function step(op) {
26
+ if (f) throw new TypeError("Generator is already executing.");
27
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
28
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
29
+ if (y = 0, t) op = [op[0] & 2, t.value];
30
+ switch (op[0]) {
31
+ case 0: case 1: t = op; break;
32
+ case 4: _.label++; return { value: op[1], done: false };
33
+ case 5: _.label++; y = op[1]; op = [0]; continue;
34
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
35
+ default:
36
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40
+ if (t[2]) _.ops.pop();
41
+ _.trys.pop(); continue;
42
+ }
43
+ op = body.call(thisArg, _);
44
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
+ }
47
+ };
48
+ import axios from 'axios';
49
+ import { refreshAccessToken } from '../../features/authenticate/authenticateActionCreation';
50
+ import { getAppConfig } from '../../config/AppConfig';
51
+ var AuthenticatedHttpClient = /** @class */ (function () {
52
+ function AuthenticatedHttpClient() {
53
+ }
54
+ AuthenticatedHttpClient.setAuthenticateStateGetter = function (getter) {
55
+ this.authGetter = getter;
56
+ };
57
+ AuthenticatedHttpClient.setDispatch = function (dispatch) {
58
+ this.dispatch = dispatch;
59
+ };
60
+ AuthenticatedHttpClient.refreshToken = function (tk) {
61
+ return this.dispatch(refreshAccessToken(tk.refreshToken)).unwrap();
62
+ };
63
+ AuthenticatedHttpClient.request = function (config) {
64
+ var _a, _b;
65
+ return __awaiter(this, void 0, void 0, function () {
66
+ var appConfig, logged_in_token, requestConfig, error_1, error_2;
67
+ return __generator(this, function (_c) {
68
+ switch (_c.label) {
69
+ case 0:
70
+ appConfig = getAppConfig();
71
+ _c.label = 1;
72
+ case 1:
73
+ _c.trys.push([1, 12, , 13]);
74
+ logged_in_token = this.authGetter().logged_in_token;
75
+ if (!logged_in_token) {
76
+ throw Error("Not logged in!");
77
+ }
78
+ if (!((logged_in_token.parsedToken.exp - Math.floor(Date.now() / 1000)) < (60 * 15))) return [3 /*break*/, 3];
79
+ return [4 /*yield*/, this.refreshToken(logged_in_token)];
80
+ case 2:
81
+ logged_in_token = _c.sent();
82
+ _c.label = 3;
83
+ case 3:
84
+ if (!logged_in_token) {
85
+ throw Error("Not logged in!");
86
+ }
87
+ requestConfig = __assign(__assign({ timeout: appConfig.REQUESTS_TIMEOUT }, config), { headers: __assign(__assign({}, config.headers), { 'Authorization': "Bearer ".concat(logged_in_token.idToken) }) });
88
+ _c.label = 4;
89
+ case 4:
90
+ _c.trys.push([4, 6, , 11]);
91
+ return [4 /*yield*/, axios.request(requestConfig)];
92
+ case 5: return [2 /*return*/, _c.sent()];
93
+ case 6:
94
+ error_1 = _c.sent();
95
+ if (!(((_a = error_1.response) === null || _a === void 0 ? void 0 : _a.status) === 401 || ((_b = error_1.response) === null || _b === void 0 ? void 0 : _b.status) === 403)) return [3 /*break*/, 9];
96
+ return [4 /*yield*/, this.refreshToken(logged_in_token)];
97
+ case 7:
98
+ logged_in_token = _c.sent();
99
+ if (!logged_in_token) {
100
+ throw Error("Not logged in!");
101
+ }
102
+ // Retry the original request with the new token
103
+ if (!requestConfig.headers)
104
+ requestConfig.headers = {};
105
+ requestConfig.headers['Authorization'] = "Bearer ".concat(logged_in_token.idToken);
106
+ return [4 /*yield*/, axios.request(requestConfig)];
107
+ case 8: return [2 /*return*/, _c.sent()];
108
+ case 9: throw error_1;
109
+ case 10: return [3 /*break*/, 11];
110
+ case 11: return [3 /*break*/, 13];
111
+ case 12:
112
+ error_2 = _c.sent();
113
+ console.error('Authenticated request failed:', error_2);
114
+ throw error_2;
115
+ case 13: return [2 /*return*/];
116
+ }
117
+ });
118
+ });
119
+ };
120
+ AuthenticatedHttpClient.get = function (url, config) {
121
+ if (config === void 0) { config = {}; }
122
+ return __awaiter(this, void 0, void 0, function () {
123
+ var appConfig, requestConfig;
124
+ return __generator(this, function (_a) {
125
+ appConfig = getAppConfig();
126
+ requestConfig = __assign(__assign({}, config), { params: __assign(__assign({}, config.params), { "cloudapp_name": appConfig.APP_NAME }), method: 'GET', url: url });
127
+ return [2 /*return*/, this.request(requestConfig)];
128
+ });
129
+ });
130
+ };
131
+ AuthenticatedHttpClient.post = function (url, data, config) {
132
+ if (config === void 0) { config = {}; }
133
+ return __awaiter(this, void 0, void 0, function () {
134
+ var appConfig, requestConfig;
135
+ return __generator(this, function (_a) {
136
+ appConfig = getAppConfig();
137
+ requestConfig = __assign(__assign({}, config), { method: 'post', url: url, data: __assign(__assign({}, data), { "cloudapp_name": appConfig.APP_NAME }) });
138
+ return [2 /*return*/, this.request(requestConfig)];
139
+ });
140
+ });
141
+ };
142
+ AuthenticatedHttpClient.put = function (url, data, config) {
143
+ return __awaiter(this, void 0, void 0, function () {
144
+ return __generator(this, function (_a) {
145
+ return [2 /*return*/, this.request(__assign(__assign({}, config), { method: 'PUT', url: url, data: data }))];
146
+ });
147
+ });
148
+ };
149
+ AuthenticatedHttpClient["delete"] = function (url, config) {
150
+ return __awaiter(this, void 0, void 0, function () {
151
+ return __generator(this, function (_a) {
152
+ return [2 /*return*/, this.request(__assign(__assign({}, config), { method: 'DELETE', url: url }))];
153
+ });
154
+ });
155
+ };
156
+ return AuthenticatedHttpClient;
157
+ }());
158
+ export { AuthenticatedHttpClient };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Convert timestamp in ISO 8601 to local time
3
+ * @param timestamp
4
+ */
5
+ export declare function convertTimestamp(timestamp: string): string;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Convert timestamp in ISO 8601 to local time
3
+ * @param timestamp
4
+ */
5
+ export function convertTimestamp(timestamp) {
6
+ try {
7
+ // Create a new Date object from the timestamp
8
+ var date = new Date(timestamp);
9
+ // Check if date is valid
10
+ if (isNaN(date.getTime())) {
11
+ return timestamp; // Return original if invalid
12
+ }
13
+ // Format the date and time
14
+ var year = date.getFullYear();
15
+ var month = String(date.getMonth() + 1).padStart(2, '0'); // Months are 0-indexed in JavaScript
16
+ var day = String(date.getDate()).padStart(2, '0');
17
+ var hours = String(date.getHours()).padStart(2, '0');
18
+ var minutes = String(date.getMinutes()).padStart(2, '0');
19
+ var seconds = String(date.getSeconds()).padStart(2, '0');
20
+ // Return the formatted string
21
+ return "".concat(year, "-").concat(month, "-").concat(day, " ").concat(hours, ":").concat(minutes, ":").concat(seconds);
22
+ }
23
+ catch (e) {
24
+ console.error('Error converting timestamp:', e);
25
+ return timestamp;
26
+ }
27
+ }
@@ -0,0 +1,3 @@
1
+ declare function downloadStringAsFile(content: string, fileName: string): void;
2
+ export { downloadStringAsFile };
3
+ export default downloadStringAsFile;
@@ -0,0 +1,20 @@
1
+ function downloadStringAsFile(content, fileName) {
2
+ // Step 1: Create a Blob from the string
3
+ var blob = new Blob([content], { type: 'text/plain' });
4
+ // Step 2: Create a URL for the Blob
5
+ var url = URL.createObjectURL(blob);
6
+ // Step 3: Use an anchor element to initiate the download
7
+ var a = document.createElement('a');
8
+ a.href = url;
9
+ // Step 4: Set the download attribute of the anchor element
10
+ a.download = fileName;
11
+ // Append the anchor to the body (this is necessary for Firefox)
12
+ document.body.appendChild(a);
13
+ // Step 5: Simulate a click on the anchor element
14
+ a.click();
15
+ // Cleanup: Remove the anchor from the body and revoke the Blob URL
16
+ document.body.removeChild(a);
17
+ URL.revokeObjectURL(url);
18
+ }
19
+ export { downloadStringAsFile };
20
+ export default downloadStringAsFile;
@@ -0,0 +1 @@
1
+ export declare function createRequest(state: any): string;
@@ -0,0 +1,4 @@
1
+ // This will be updated to work with the shared store type
2
+ export function createRequest(state) {
3
+ return "{}";
4
+ }
@@ -0,0 +1,4 @@
1
+ import type { AxiosResponse } from "axios";
2
+ export declare function getFileExtension(filename: string): string;
3
+ export declare function formatBytes(bytes: number, decimals?: number): string;
4
+ export declare const uploadHandlerFactory: (uploadToken: string, dispatch: any, uploader: any, uploadTarget?: string) => (file: File, fileAlias: string, fileDatabase?: string, onProgress?: ((progress: number) => void) | undefined, onUploaded?: ((res: AxiosResponse, file: File) => void) | undefined) => Promise<any>;
@@ -0,0 +1,79 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ // File extension utility functions
38
+ export function getFileExtension(filename) {
39
+ var parts = filename.split(".");
40
+ if (parts.length === 1)
41
+ return "";
42
+ if (parts.length === 2)
43
+ return parts[1];
44
+ // Handle .nii.gz case
45
+ if (parts[parts.length - 2] === "nii" && parts[parts.length - 1] === "gz") {
46
+ return "nii.gz";
47
+ }
48
+ return parts[parts.length - 1];
49
+ }
50
+ export function formatBytes(bytes, decimals) {
51
+ if (decimals === void 0) { decimals = 2; }
52
+ if (bytes === 0)
53
+ return "0 Bytes";
54
+ var k = 1024;
55
+ var dm = decimals < 0 ? 0 : decimals;
56
+ var sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
57
+ var i = Math.floor(Math.log(bytes) / Math.log(k));
58
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
59
+ }
60
+ export var uploadHandlerFactory = function (uploadToken, dispatch, uploader, uploadTarget) {
61
+ return function (file, fileAlias, fileDatabase, onProgress, onUploaded) { return __awaiter(void 0, void 0, void 0, function () {
62
+ var result;
63
+ return __generator(this, function (_a) {
64
+ switch (_a.label) {
65
+ case 0: return [4 /*yield*/, dispatch(uploader({
66
+ file: file,
67
+ fileAlias: fileAlias,
68
+ uploadToken: uploadToken,
69
+ onProgress: onProgress,
70
+ onUploaded: onUploaded,
71
+ uploadTarget: uploadTarget
72
+ }))];
73
+ case 1:
74
+ result = _a.sent();
75
+ return [2 /*return*/, result.payload.code];
76
+ }
77
+ });
78
+ }); };
79
+ };
@@ -0,0 +1 @@
1
+ export declare const is_safe_twix: (file: File) => Promise<boolean>;