@haniffalab/cherita-react 1.2.0 → 1.3.0-dev.2025-05-29.ee7e9b72
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.
- package/dist/cjs/components/controls/Controls.js +60 -0
- package/dist/cjs/components/dotplot/Dotplot.js +47 -38
- package/dist/cjs/components/dotplot/DotplotControls.js +77 -114
- package/dist/cjs/components/full-page/FullPage.js +29 -33
- package/dist/cjs/components/full-page/FullPagePseudospatial.js +30 -33
- package/dist/cjs/components/heatmap/Heatmap.js +33 -22
- package/dist/cjs/components/heatmap/HeatmapControls.js +2 -19
- package/dist/cjs/components/matrixplot/Matrixplot.js +35 -24
- package/dist/cjs/components/matrixplot/MatrixplotControls.js +4 -34
- package/dist/cjs/components/obs-list/ObsItem.js +63 -51
- package/dist/cjs/components/obs-list/ObsList.js +53 -48
- package/dist/cjs/components/obsm-list/ObsmList.js +17 -12
- package/dist/cjs/components/offcanvas/index.js +14 -11
- package/dist/cjs/components/pseudospatial/Pseudospatial.js +78 -68
- package/dist/cjs/components/pseudospatial/PseudospatialToolbar.js +27 -21
- package/dist/cjs/components/scatterplot/Scatterplot.js +82 -76
- package/dist/cjs/components/scatterplot/ScatterplotControls.js +18 -31
- package/dist/cjs/components/scatterplot/SpatialControls.js +53 -23
- package/dist/cjs/components/scatterplot/Toolbox.js +1 -18
- package/dist/cjs/components/search-bar/SearchBar.js +156 -59
- package/dist/cjs/components/search-bar/SearchInfo.js +182 -0
- package/dist/cjs/components/search-bar/SearchResults.js +90 -60
- package/dist/cjs/components/var-list/VarItem.js +52 -75
- package/dist/cjs/components/var-list/VarList.js +47 -172
- package/dist/cjs/components/var-list/VarListToolbar.js +7 -8
- package/dist/cjs/components/var-list/VarSet.js +66 -57
- package/dist/cjs/components/violin/Violin.js +54 -43
- package/dist/cjs/components/violin/ViolinControls.js +4 -20
- package/dist/cjs/context/DatasetContext.js +26 -513
- package/dist/cjs/context/FilterContext.js +9 -8
- package/dist/cjs/context/SettingsContext.js +539 -0
- package/dist/cjs/context/ZarrDataContext.js +1 -2
- package/dist/cjs/helpers/color-helper.js +8 -8
- package/dist/cjs/helpers/zarr-helper.js +19 -16
- package/dist/cjs/utils/Filter.js +25 -21
- package/dist/cjs/utils/Histogram.js +4 -3
- package/dist/cjs/utils/ImageViewer.js +1 -2
- package/dist/cjs/utils/Legend.js +18 -12
- package/dist/cjs/utils/LoadingIndicators.js +1 -1
- package/dist/cjs/utils/VirtualizedList.js +16 -13
- package/dist/cjs/utils/errors.js +20 -22
- package/dist/cjs/utils/requests.js +13 -10
- package/dist/cjs/utils/zarrData.js +31 -50
- package/dist/css/cherita.css +84 -24
- package/dist/css/cherita.css.map +1 -1
- package/dist/esm/components/controls/Controls.js +51 -0
- package/dist/esm/components/dotplot/Dotplot.js +47 -37
- package/dist/esm/components/dotplot/DotplotControls.js +77 -112
- package/dist/esm/components/full-page/FullPage.js +29 -32
- package/dist/esm/components/full-page/FullPagePseudospatial.js +30 -32
- package/dist/esm/components/heatmap/Heatmap.js +32 -20
- package/dist/esm/components/heatmap/HeatmapControls.js +3 -20
- package/dist/esm/components/matrixplot/Matrixplot.js +34 -22
- package/dist/esm/components/matrixplot/MatrixplotControls.js +5 -35
- package/dist/esm/components/obs-list/ObsItem.js +63 -49
- package/dist/esm/components/obs-list/ObsList.js +53 -47
- package/dist/esm/components/obsm-list/ObsmList.js +17 -11
- package/dist/esm/components/offcanvas/index.js +14 -11
- package/dist/esm/components/pseudospatial/Pseudospatial.js +77 -66
- package/dist/esm/components/pseudospatial/PseudospatialToolbar.js +27 -20
- package/dist/esm/components/scatterplot/Scatterplot.js +81 -74
- package/dist/esm/components/scatterplot/ScatterplotControls.js +18 -29
- package/dist/esm/components/scatterplot/SpatialControls.js +54 -23
- package/dist/esm/components/scatterplot/Toolbox.js +1 -18
- package/dist/esm/components/search-bar/SearchBar.js +156 -59
- package/dist/esm/components/search-bar/SearchInfo.js +173 -0
- package/dist/esm/components/search-bar/SearchResults.js +91 -60
- package/dist/esm/components/var-list/VarItem.js +53 -76
- package/dist/esm/components/var-list/VarList.js +47 -171
- package/dist/esm/components/var-list/VarListToolbar.js +6 -6
- package/dist/esm/components/var-list/VarSet.js +67 -57
- package/dist/esm/components/violin/Violin.js +53 -41
- package/dist/esm/components/violin/ViolinControls.js +5 -21
- package/dist/esm/context/DatasetContext.js +25 -510
- package/dist/esm/context/FilterContext.js +8 -6
- package/dist/esm/context/SettingsContext.js +528 -0
- package/dist/esm/helpers/color-helper.js +8 -8
- package/dist/esm/helpers/zarr-helper.js +19 -16
- package/dist/esm/utils/Filter.js +25 -21
- package/dist/esm/utils/Histogram.js +4 -3
- package/dist/esm/utils/Legend.js +17 -10
- package/dist/esm/utils/LoadingIndicators.js +1 -1
- package/dist/esm/utils/VirtualizedList.js +15 -11
- package/dist/esm/utils/errors.js +20 -22
- package/dist/esm/utils/requests.js +13 -10
- package/dist/esm/utils/zarrData.js +33 -51
- package/package.json +6 -3
- package/scss/cherita.scss +50 -9
- package/scss/components/layouts.scss +24 -13
- package/scss/components/lists.scss +10 -0
- package/scss/components/plots.scss +3 -5
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.SettingsDispatchContext = exports.SettingsContext = void 0;
|
|
7
|
+
exports.SettingsProvider = SettingsProvider;
|
|
8
|
+
exports.useSettings = useSettings;
|
|
9
|
+
exports.useSettingsDispatch = useSettingsDispatch;
|
|
10
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
11
|
+
var _lodash = _interopRequireDefault(require("lodash"));
|
|
12
|
+
var _constants = require("../constants/constants");
|
|
13
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
15
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
16
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
17
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
18
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
19
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
20
|
+
const SettingsContext = exports.SettingsContext = /*#__PURE__*/(0, _react.createContext)(null);
|
|
21
|
+
const SettingsDispatchContext = exports.SettingsDispatchContext = /*#__PURE__*/(0, _react.createContext)(null);
|
|
22
|
+
const initialSettings = {
|
|
23
|
+
selectedObs: null,
|
|
24
|
+
selectedVar: null,
|
|
25
|
+
selectedObsm: null,
|
|
26
|
+
selectedMultiObs: [],
|
|
27
|
+
selectedMultiVar: [],
|
|
28
|
+
colorEncoding: null,
|
|
29
|
+
labelObs: [],
|
|
30
|
+
vars: [],
|
|
31
|
+
sliceBy: {
|
|
32
|
+
obs: false,
|
|
33
|
+
polygons: false
|
|
34
|
+
},
|
|
35
|
+
polygons: {},
|
|
36
|
+
controls: {
|
|
37
|
+
colorScale: "Viridis",
|
|
38
|
+
valueRange: [0, 1],
|
|
39
|
+
range: [0, 1],
|
|
40
|
+
colorAxis: {
|
|
41
|
+
dmin: 0,
|
|
42
|
+
dmax: 1,
|
|
43
|
+
cmin: 0,
|
|
44
|
+
cmax: 1
|
|
45
|
+
},
|
|
46
|
+
scale: {
|
|
47
|
+
dotplot: _constants.DOTPLOT_SCALES.NONE.value,
|
|
48
|
+
matrixplot: _constants.MATRIXPLOT_SCALES.NONE.value,
|
|
49
|
+
violinplot: _constants.VIOLINPLOT_SCALES.WIDTH.value
|
|
50
|
+
},
|
|
51
|
+
meanOnlyExpressed: false,
|
|
52
|
+
expressionCutoff: 0.0
|
|
53
|
+
},
|
|
54
|
+
varSort: {
|
|
55
|
+
var: {
|
|
56
|
+
sort: _constants.VAR_SORT.NONE,
|
|
57
|
+
sortOrder: _constants.VAR_SORT_ORDER.ASC
|
|
58
|
+
},
|
|
59
|
+
disease: {
|
|
60
|
+
sort: _constants.VAR_SORT.NONE,
|
|
61
|
+
sortOrder: _constants.VAR_SORT_ORDER.ASC
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
pseudospatial: {
|
|
65
|
+
maskSet: null,
|
|
66
|
+
maskValues: null,
|
|
67
|
+
categoricalMode: _constants.PSEUDOSPATIAL_CATEGORICAL_MODES.ACROSS.value
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const initializer = _ref => {
|
|
71
|
+
let {
|
|
72
|
+
canOverrideSettings,
|
|
73
|
+
defaultSettings,
|
|
74
|
+
localSettings
|
|
75
|
+
} = _ref;
|
|
76
|
+
return canOverrideSettings ? _lodash.default.assign({}, initialSettings, defaultSettings, localSettings) : _lodash.default.assign({}, initialSettings, defaultSettings);
|
|
77
|
+
};
|
|
78
|
+
function SettingsProvider(_ref2) {
|
|
79
|
+
let {
|
|
80
|
+
dataset_url,
|
|
81
|
+
defaultSettings,
|
|
82
|
+
canOverrideSettings,
|
|
83
|
+
children
|
|
84
|
+
} = _ref2;
|
|
85
|
+
const DATASET_STORAGE_KEY = "".concat(_constants.LOCAL_STORAGE_KEY, "-").concat(dataset_url);
|
|
86
|
+
// Use localStorage directly instead of useLocalStorage due to unnecessary re-renders
|
|
87
|
+
// https://github.com/uidotdev/usehooks/issues/157
|
|
88
|
+
const localSettings = JSON.parse(localStorage.getItem(DATASET_STORAGE_KEY)) || {};
|
|
89
|
+
const [settings, dispatch] = (0, _react.useReducer)(settingsReducer, {
|
|
90
|
+
canOverrideSettings,
|
|
91
|
+
defaultSettings,
|
|
92
|
+
localSettings
|
|
93
|
+
}, initializer);
|
|
94
|
+
(0, _react.useEffect)(() => {
|
|
95
|
+
if (canOverrideSettings) {
|
|
96
|
+
try {
|
|
97
|
+
localStorage.setItem(DATASET_STORAGE_KEY, JSON.stringify(settings));
|
|
98
|
+
} catch (err) {
|
|
99
|
+
if (err.code === 22 || err.code === 1014 || err.name === "QuotaExceededError" || err.name === "NS_ERROR_DOM_QUOTA_REACHED") {
|
|
100
|
+
console.err("Browser storage quota exceeded");
|
|
101
|
+
} else {
|
|
102
|
+
console.err(err);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}, [DATASET_STORAGE_KEY, canOverrideSettings, settings]);
|
|
107
|
+
return /*#__PURE__*/_react.default.createElement(SettingsContext.Provider, {
|
|
108
|
+
value: settings
|
|
109
|
+
}, /*#__PURE__*/_react.default.createElement(SettingsDispatchContext.Provider, {
|
|
110
|
+
value: dispatch
|
|
111
|
+
}, children));
|
|
112
|
+
}
|
|
113
|
+
function useSettings() {
|
|
114
|
+
return (0, _react.useContext)(SettingsContext);
|
|
115
|
+
}
|
|
116
|
+
function useSettingsDispatch() {
|
|
117
|
+
return (0, _react.useContext)(SettingsDispatchContext);
|
|
118
|
+
}
|
|
119
|
+
function settingsReducer(settings, action) {
|
|
120
|
+
switch (action.type) {
|
|
121
|
+
case "select.obs":
|
|
122
|
+
{
|
|
123
|
+
var _action$obs;
|
|
124
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
125
|
+
selectedObs: action.obs,
|
|
126
|
+
controls: _objectSpread(_objectSpread({}, settings.controls), {}, {
|
|
127
|
+
range: ((_action$obs = action.obs) === null || _action$obs === void 0 ? void 0 : _action$obs.type) === _constants.OBS_TYPES.CATEGORICAL ? [0, 1] : settings.controls.range
|
|
128
|
+
}),
|
|
129
|
+
colorEncoding: settings.colorEncoding === _constants.COLOR_ENCODINGS.OBS && !action.obs ? null : settings.colorEncoding,
|
|
130
|
+
sliceBy: _objectSpread(_objectSpread({}, settings.sliceBy), {}, {
|
|
131
|
+
obs: action.obs ? settings.sliceBy.obs : false
|
|
132
|
+
})
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
case "select.obsm":
|
|
136
|
+
{
|
|
137
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
138
|
+
selectedObsm: action.obsm
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
case "select.var":
|
|
142
|
+
{
|
|
143
|
+
if (settings.vars.find(v => _lodash.default.isEqual(v, action.var))) {
|
|
144
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
145
|
+
selectedVar: action.var
|
|
146
|
+
});
|
|
147
|
+
} else {
|
|
148
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
149
|
+
selectedVar: action.var,
|
|
150
|
+
vars: [...settings.vars, action.var]
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
case "select.multivar":
|
|
155
|
+
{
|
|
156
|
+
const vars = settings.vars.find(v => _lodash.default.isEqual(v, action.var)) ? settings.vars : [...settings.vars, action.var];
|
|
157
|
+
if (settings.selectedMultiVar.find(v => _lodash.default.isEqual(v, action.var))) {
|
|
158
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
159
|
+
vars: vars
|
|
160
|
+
});
|
|
161
|
+
} else {
|
|
162
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
163
|
+
selectedMultiVar: [...settings.selectedMultiVar, action.var],
|
|
164
|
+
vars: vars
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
case "deselect.multivar":
|
|
169
|
+
{
|
|
170
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
171
|
+
selectedMultiVar: settings.selectedMultiVar.filter(v => v !== action.var.name)
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
case "toggle.multivar":
|
|
175
|
+
{
|
|
176
|
+
const inMultiVar = settings.selectedMultiVar.some(v => v.name === action.var.name);
|
|
177
|
+
if (inMultiVar) {
|
|
178
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
179
|
+
selectedMultiVar: settings.selectedMultiVar.filter(v => v.name !== action.var.name)
|
|
180
|
+
});
|
|
181
|
+
} else {
|
|
182
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
183
|
+
selectedMultiVar: [...settings.selectedMultiVar, action.var]
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
case "set.colorEncoding":
|
|
188
|
+
{
|
|
189
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
190
|
+
colorEncoding: action.value
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
case "reset.vars":
|
|
194
|
+
{
|
|
195
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
196
|
+
vars: [],
|
|
197
|
+
selectedVar: null,
|
|
198
|
+
selectedMultiVar: []
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
case "reset.multiVar":
|
|
202
|
+
{
|
|
203
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
204
|
+
selectedMultiVar: [],
|
|
205
|
+
colorEncoding: settings.colorEncoding === _constants.COLOR_ENCODINGS.VAR ? null : settings.colorEncoding
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
case "reset.var":
|
|
209
|
+
{
|
|
210
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
211
|
+
selectedVar: null,
|
|
212
|
+
colorEncoding: settings.colorEncoding === _constants.COLOR_ENCODINGS.VAR ? null : settings.colorEncoding
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
case "add.var":
|
|
216
|
+
{
|
|
217
|
+
if (settings.vars.find(v => v.name === action.var.name)) {
|
|
218
|
+
return settings;
|
|
219
|
+
} else {
|
|
220
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
221
|
+
vars: [...settings.vars, action.var]
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
case "remove.var":
|
|
226
|
+
{
|
|
227
|
+
var _settings$selectedVar;
|
|
228
|
+
const selectedVar = ((_settings$selectedVar = settings.selectedVar) === null || _settings$selectedVar === void 0 ? void 0 : _settings$selectedVar.name) === action.var.name ? null : settings.selectedVar;
|
|
229
|
+
const selectedMultiVar = settings.selectedMultiVar.filter(v => v.name !== action.var.name);
|
|
230
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
231
|
+
vars: settings.vars.filter(a => a.name !== action.var.name),
|
|
232
|
+
selectedVar: selectedVar,
|
|
233
|
+
selectedMultiVar: selectedMultiVar
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
case "add.varSet.var":
|
|
237
|
+
{
|
|
238
|
+
const varSet = settings.vars.find(s => s.isSet && s.name === action.varSet.name);
|
|
239
|
+
if (!varSet) {
|
|
240
|
+
return settings;
|
|
241
|
+
}
|
|
242
|
+
if (varSet.vars.some(v => v.name === action.var.name)) {
|
|
243
|
+
return settings;
|
|
244
|
+
} else {
|
|
245
|
+
var _settings$selectedVar2;
|
|
246
|
+
const varSetVars = [...varSet.vars, action.var];
|
|
247
|
+
const vars = settings.vars.map(v => {
|
|
248
|
+
if (v.name === varSet.name) {
|
|
249
|
+
return _objectSpread(_objectSpread({}, v), {}, {
|
|
250
|
+
vars: varSetVars
|
|
251
|
+
});
|
|
252
|
+
} else {
|
|
253
|
+
return v;
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
const selectedVar = ((_settings$selectedVar2 = settings.selectedVar) === null || _settings$selectedVar2 === void 0 ? void 0 : _settings$selectedVar2.name) === action.varSet.name ? _objectSpread(_objectSpread({}, varSet), {}, {
|
|
257
|
+
vars: varSetVars
|
|
258
|
+
}) : settings.selectedVar;
|
|
259
|
+
const selectedMultiVar = settings.selectedMultiVar.map(v => {
|
|
260
|
+
if (v.name === varSet.name) {
|
|
261
|
+
return _objectSpread(_objectSpread({}, v), {}, {
|
|
262
|
+
vars: varSetVars
|
|
263
|
+
});
|
|
264
|
+
} else {
|
|
265
|
+
return v;
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
269
|
+
vars: vars,
|
|
270
|
+
selectedVar: selectedVar,
|
|
271
|
+
selectedMultiVar: selectedMultiVar
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
case "remove.varSet.var":
|
|
276
|
+
{
|
|
277
|
+
const varSet = settings.vars.find(s => s.isSet && s.name === action.varSet.name);
|
|
278
|
+
if (!varSet) {
|
|
279
|
+
return settings;
|
|
280
|
+
}
|
|
281
|
+
if (!varSet.vars.some(v => v.name === action.var.name)) {
|
|
282
|
+
return settings;
|
|
283
|
+
} else {
|
|
284
|
+
const varSetVars = varSet.vars.filter(v => v.name !== action.var.name);
|
|
285
|
+
const vars = settings.vars.map(v => {
|
|
286
|
+
if (v.name === varSet.name) {
|
|
287
|
+
return _objectSpread(_objectSpread({}, v), {}, {
|
|
288
|
+
vars: varSetVars
|
|
289
|
+
});
|
|
290
|
+
} else {
|
|
291
|
+
return v;
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
// Remove from selected if varSet vars is empty
|
|
295
|
+
if (!varSetVars.length) {
|
|
296
|
+
var _settings$selectedVar3;
|
|
297
|
+
const selectedVar = ((_settings$selectedVar3 = settings.selectedVar) === null || _settings$selectedVar3 === void 0 ? void 0 : _settings$selectedVar3.name) === action.varSet.name ? null : settings.selectedVar;
|
|
298
|
+
const selectedMultiVar = settings.selectedMultiVar.filter(v => v.name !== action.varSet.name);
|
|
299
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
300
|
+
vars: vars,
|
|
301
|
+
selectedVar: selectedVar,
|
|
302
|
+
selectedMultiVar: selectedMultiVar
|
|
303
|
+
});
|
|
304
|
+
} else {
|
|
305
|
+
var _settings$selectedVar4;
|
|
306
|
+
// Update selected if varSet is selected
|
|
307
|
+
const selectedVar = ((_settings$selectedVar4 = settings.selectedVar) === null || _settings$selectedVar4 === void 0 ? void 0 : _settings$selectedVar4.name) === action.varSet.name ? _objectSpread(_objectSpread({}, varSet), {}, {
|
|
308
|
+
vars: varSetVars
|
|
309
|
+
}) : settings.selectedVar;
|
|
310
|
+
const selectedMultiVar = settings.selectedMultiVar.map(v => {
|
|
311
|
+
if (v.name === varSet.name) {
|
|
312
|
+
return _objectSpread(_objectSpread({}, v), {}, {
|
|
313
|
+
vars: varSetVars
|
|
314
|
+
});
|
|
315
|
+
} else {
|
|
316
|
+
return v;
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
320
|
+
vars: vars,
|
|
321
|
+
selectedVar: selectedVar,
|
|
322
|
+
selectedMultiVar: selectedMultiVar
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
case "set.controls.colorScale":
|
|
328
|
+
{
|
|
329
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
330
|
+
controls: _objectSpread(_objectSpread({}, settings.controls), {}, {
|
|
331
|
+
colorScale: action.colorScale
|
|
332
|
+
})
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
case "set.controls.valueRange":
|
|
336
|
+
{
|
|
337
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
338
|
+
controls: _objectSpread(_objectSpread({}, settings.controls), {}, {
|
|
339
|
+
valueRange: action.valueRange
|
|
340
|
+
})
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
case "set.controls.range":
|
|
344
|
+
{
|
|
345
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
346
|
+
controls: _objectSpread(_objectSpread({}, settings.controls), {}, {
|
|
347
|
+
range: action.range
|
|
348
|
+
})
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
case "set.controls.colorAxis":
|
|
352
|
+
{
|
|
353
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
354
|
+
controls: _objectSpread(_objectSpread({}, settings.controls), {}, {
|
|
355
|
+
colorAxis: action.colorAxis
|
|
356
|
+
})
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
case "set.controls.colorAxis.crange":
|
|
360
|
+
{
|
|
361
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
362
|
+
controls: _objectSpread(_objectSpread({}, settings.controls), {}, {
|
|
363
|
+
colorAxis: _objectSpread(_objectSpread({}, settings.controls.colorAxis), {}, {
|
|
364
|
+
cmin: action.cmin,
|
|
365
|
+
cmax: action.cmax
|
|
366
|
+
})
|
|
367
|
+
})
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
case "set.controls.colorAxis.cmin":
|
|
371
|
+
{
|
|
372
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
373
|
+
controls: _objectSpread(_objectSpread({}, settings.controls), {}, {
|
|
374
|
+
colorAxis: _objectSpread(_objectSpread({}, settings.controls.colorAxis), {}, {
|
|
375
|
+
cmin: action.cmin
|
|
376
|
+
})
|
|
377
|
+
})
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
case "set.controls.colorAxis.cmax":
|
|
381
|
+
{
|
|
382
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
383
|
+
controls: _objectSpread(_objectSpread({}, settings.controls), {}, {
|
|
384
|
+
colorAxis: _objectSpread(_objectSpread({}, settings.controls.colorAxis), {}, {
|
|
385
|
+
cmax: action.cmax
|
|
386
|
+
})
|
|
387
|
+
})
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
case "set.controls.scale":
|
|
391
|
+
{
|
|
392
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
393
|
+
controls: _objectSpread(_objectSpread({}, settings.controls), {}, {
|
|
394
|
+
scale: _objectSpread(_objectSpread({}, settings.controls.scale), {}, {
|
|
395
|
+
[action.plot]: action.scale
|
|
396
|
+
})
|
|
397
|
+
})
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
case "set.controls.meanOnlyExpressed":
|
|
401
|
+
{
|
|
402
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
403
|
+
controls: _objectSpread(_objectSpread({}, settings.controls), {}, {
|
|
404
|
+
meanOnlyExpressed: action.meanOnlyExpressed
|
|
405
|
+
})
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
case "set.controls.expressionCutoff":
|
|
409
|
+
{
|
|
410
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
411
|
+
controls: _objectSpread(_objectSpread({}, settings.controls), {}, {
|
|
412
|
+
expressionCutoff: action.expressionCutoff
|
|
413
|
+
})
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
case "toggle.slice.obs":
|
|
417
|
+
{
|
|
418
|
+
if (_lodash.default.isEqual(settings.selectedObs, action.obs)) {
|
|
419
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
420
|
+
sliceBy: _objectSpread(_objectSpread({}, settings.sliceBy), {}, {
|
|
421
|
+
obs: !settings.sliceBy.obs
|
|
422
|
+
})
|
|
423
|
+
});
|
|
424
|
+
} else {
|
|
425
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
426
|
+
selectedObs: action.obs,
|
|
427
|
+
sliceBy: _objectSpread(_objectSpread({}, settings.sliceBy), {}, {
|
|
428
|
+
obs: true
|
|
429
|
+
})
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
case "toggle.slice.polygons":
|
|
434
|
+
{
|
|
435
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
436
|
+
sliceBy: _objectSpread(_objectSpread({}, settings.sliceBy), {}, {
|
|
437
|
+
polygons: !settings.sliceBy.polygons
|
|
438
|
+
})
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
case "disable.slice.polygons":
|
|
442
|
+
{
|
|
443
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
444
|
+
sliceBy: _objectSpread(_objectSpread({}, settings.sliceBy), {}, {
|
|
445
|
+
polygons: false
|
|
446
|
+
})
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
case "add.label.obs":
|
|
450
|
+
{
|
|
451
|
+
if (settings.labelObs.find(i => _lodash.default.isEqual(i, action.obs))) {
|
|
452
|
+
return settings;
|
|
453
|
+
} else {
|
|
454
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
455
|
+
labelObs: [...settings.labelObs, action.obs]
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
case "remove.label.obs":
|
|
460
|
+
{
|
|
461
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
462
|
+
labelObs: settings.labelObs.filter(a => a.name !== action.obsName)
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
case "reset.label.obs":
|
|
466
|
+
{
|
|
467
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
468
|
+
labelObs: []
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
case "set.varSort":
|
|
472
|
+
{
|
|
473
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
474
|
+
varSort: _objectSpread(_objectSpread({}, settings.varSort), {}, {
|
|
475
|
+
[action.var]: {
|
|
476
|
+
sort: action.sort,
|
|
477
|
+
sortOrder: action.sortOrder
|
|
478
|
+
}
|
|
479
|
+
})
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
case "set.varSort.sort":
|
|
483
|
+
{
|
|
484
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
485
|
+
varSort: _objectSpread(_objectSpread({}, settings.varSort), {}, {
|
|
486
|
+
[action.var]: _objectSpread(_objectSpread({}, settings.varSort[action.var]), {}, {
|
|
487
|
+
sort: action.sort
|
|
488
|
+
})
|
|
489
|
+
})
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
case "set.varSort.sortOrder":
|
|
493
|
+
{
|
|
494
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
495
|
+
varSort: _objectSpread(_objectSpread({}, settings.varSort), {}, {
|
|
496
|
+
[action.var]: _objectSpread(_objectSpread({}, settings.varSort[action.var]), {}, {
|
|
497
|
+
sortOrder: action.sortOrder
|
|
498
|
+
})
|
|
499
|
+
})
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
case "set.polygons":
|
|
503
|
+
{
|
|
504
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
505
|
+
polygons: _objectSpread(_objectSpread({}, settings.polygons), {}, {
|
|
506
|
+
[action.obsm]: action.polygons
|
|
507
|
+
})
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
case "set.pseudospatial.maskSet":
|
|
511
|
+
{
|
|
512
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
513
|
+
pseudospatial: _objectSpread(_objectSpread({}, settings.pseudospatial), {}, {
|
|
514
|
+
maskSet: action.maskSet
|
|
515
|
+
})
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
case "set.pseudospatial.maskValues":
|
|
519
|
+
{
|
|
520
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
521
|
+
pseudospatial: _objectSpread(_objectSpread({}, settings.pseudospatial), {}, {
|
|
522
|
+
maskValues: action.maskValues
|
|
523
|
+
})
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
case "set.pseudospatial.categoricalMode":
|
|
527
|
+
{
|
|
528
|
+
return _objectSpread(_objectSpread({}, settings), {}, {
|
|
529
|
+
pseudospatial: _objectSpread(_objectSpread({}, settings.pseudospatial), {}, {
|
|
530
|
+
categoricalMode: action.categoricalMode
|
|
531
|
+
})
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
default:
|
|
535
|
+
{
|
|
536
|
+
throw Error("Unknown action: " + action.type);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
@@ -8,8 +8,7 @@ exports.useZarrData = useZarrData;
|
|
|
8
8
|
var _react = _interopRequireWildcard(require("react"));
|
|
9
9
|
var _Filter = require("../utils/Filter");
|
|
10
10
|
var _zarrData = require("../utils/zarrData");
|
|
11
|
-
function
|
|
12
|
-
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
11
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
13
12
|
const ZarrDataContext = /*#__PURE__*/(0, _react.createContext)(null);
|
|
14
13
|
function ZarrDataProvider(_ref) {
|
|
15
14
|
let {
|
|
@@ -6,12 +6,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.useColor = exports.rgbToHex = void 0;
|
|
7
7
|
var _react = require("react");
|
|
8
8
|
var _colorscales = require("../constants/colorscales");
|
|
9
|
-
var
|
|
9
|
+
var _SettingsContext = require("../context/SettingsContext");
|
|
10
10
|
const GRAY = [214, 212, 212];
|
|
11
11
|
const parseHexColor = color => {
|
|
12
|
-
const r = parseInt(color
|
|
13
|
-
const g = parseInt(color
|
|
14
|
-
const b = parseInt(color
|
|
12
|
+
const r = parseInt(color === null || color === void 0 ? void 0 : color.substring(1, 3), 16);
|
|
13
|
+
const g = parseInt(color === null || color === void 0 ? void 0 : color.substring(3, 5), 16);
|
|
14
|
+
const b = parseInt(color === null || color === void 0 ? void 0 : color.substring(5, 7), 16);
|
|
15
15
|
return [r, g, b];
|
|
16
16
|
};
|
|
17
17
|
const interpolateColor = (color1, color2, factor) => {
|
|
@@ -41,7 +41,7 @@ const rgbToHex = color => {
|
|
|
41
41
|
};
|
|
42
42
|
exports.rgbToHex = rgbToHex;
|
|
43
43
|
const useColor = () => {
|
|
44
|
-
const
|
|
44
|
+
const settings = (0, _SettingsContext.useSettings)();
|
|
45
45
|
const getColor = (0, _react.useCallback)(_ref => {
|
|
46
46
|
let {
|
|
47
47
|
value,
|
|
@@ -51,10 +51,10 @@ const useColor = () => {
|
|
|
51
51
|
alpha = 0.75,
|
|
52
52
|
gray = 0.95
|
|
53
53
|
} = {},
|
|
54
|
-
colorEncoding =
|
|
54
|
+
colorEncoding = settings.colorEncoding,
|
|
55
55
|
colorscale = null
|
|
56
56
|
} = _ref;
|
|
57
|
-
const colormap = colorscale || _colorscales.COLORSCALES[categorical ? "Accent" :
|
|
57
|
+
const colormap = colorscale || _colorscales.COLORSCALES[categorical ? "Accent" : settings.controls.colorScale];
|
|
58
58
|
if (colorEncoding) {
|
|
59
59
|
if (grayOut) {
|
|
60
60
|
// Mix color with gray manually instead of chroma.mix to get better performance with deck.gl
|
|
@@ -66,7 +66,7 @@ const useColor = () => {
|
|
|
66
66
|
} else {
|
|
67
67
|
return null;
|
|
68
68
|
}
|
|
69
|
-
}, [
|
|
69
|
+
}, [settings.colorEncoding, settings.controls.colorScale]);
|
|
70
70
|
return {
|
|
71
71
|
getColor
|
|
72
72
|
};
|
|
@@ -7,6 +7,11 @@ exports.useZarr = exports.useMultipleZarr = exports.ZarrHelper = exports.GET_OPT
|
|
|
7
7
|
var _react = require("react");
|
|
8
8
|
var _reactQuery = require("@tanstack/react-query");
|
|
9
9
|
var _zarr = require("zarr");
|
|
10
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
11
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
12
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
13
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
14
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
10
15
|
const GET_OPTIONS = exports.GET_OPTIONS = {
|
|
11
16
|
concurrencyLimit: 10,
|
|
12
17
|
// max number of concurrent requests (default 10)
|
|
@@ -15,7 +20,7 @@ const GET_OPTIONS = exports.GET_OPTIONS = {
|
|
|
15
20
|
progress,
|
|
16
21
|
queueSize
|
|
17
22
|
} = _ref;
|
|
18
|
-
console.debug(
|
|
23
|
+
console.debug("".concat(progress / queueSize * 100, "% complete."));
|
|
19
24
|
} // callback executed after each request
|
|
20
25
|
};
|
|
21
26
|
class ZarrHelper {
|
|
@@ -45,27 +50,26 @@ const fetchDataFromZarr = async (url, path, s, opts) => {
|
|
|
45
50
|
const useZarr = function (_ref2) {
|
|
46
51
|
let {
|
|
47
52
|
url,
|
|
48
|
-
path
|
|
53
|
+
path,
|
|
54
|
+
s = null
|
|
49
55
|
} = _ref2;
|
|
50
|
-
let
|
|
51
|
-
let
|
|
52
|
-
let opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
56
|
+
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : GET_OPTIONS;
|
|
57
|
+
let opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
53
58
|
const {
|
|
54
59
|
data = null,
|
|
55
60
|
isLoading: isPending = false,
|
|
56
61
|
error: serverError = null
|
|
57
|
-
} = (0, _reactQuery.useQuery)({
|
|
62
|
+
} = (0, _reactQuery.useQuery)(_objectSpread({
|
|
58
63
|
queryKey: ["zarr", url, path, s],
|
|
59
64
|
queryFn: () => fetchDataFromZarr(url, path, s, options),
|
|
60
65
|
retry: (failureCount, _ref3) => {
|
|
61
66
|
let {
|
|
62
67
|
error
|
|
63
68
|
} = _ref3;
|
|
64
|
-
if ([400, 401, 403, 404, 422].includes(error
|
|
69
|
+
if ([400, 401, 403, 404, 422].includes(error === null || error === void 0 ? void 0 : error.status)) return false;
|
|
65
70
|
return failureCount < 3;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
});
|
|
71
|
+
}
|
|
72
|
+
}, opts));
|
|
69
73
|
return {
|
|
70
74
|
data,
|
|
71
75
|
isPending,
|
|
@@ -77,7 +81,7 @@ const aggregateData = (inputs, data) => {
|
|
|
77
81
|
const dataObject = {};
|
|
78
82
|
inputs.forEach((input, index) => {
|
|
79
83
|
const key = input.key;
|
|
80
|
-
dataObject[key] = data
|
|
84
|
+
dataObject[key] = data === null || data === void 0 ? void 0 : data[index];
|
|
81
85
|
});
|
|
82
86
|
return dataObject;
|
|
83
87
|
};
|
|
@@ -97,18 +101,17 @@ const useMultipleZarr = function (inputs) {
|
|
|
97
101
|
isLoading: isPending = false,
|
|
98
102
|
serverError = null
|
|
99
103
|
} = (0, _reactQuery.useQueries)({
|
|
100
|
-
queries: inputs.map(input => ({
|
|
104
|
+
queries: inputs.map(input => _objectSpread({
|
|
101
105
|
queryKey: ["zarr", input.url, input.path, input.s],
|
|
102
106
|
queryFn: () => fetchDataFromZarr(input.url, input.path, input.s, options),
|
|
103
107
|
retry: (failureCount, _ref4) => {
|
|
104
108
|
let {
|
|
105
109
|
error
|
|
106
110
|
} = _ref4;
|
|
107
|
-
if ([400, 401, 403, 404, 422].includes(error
|
|
111
|
+
if ([400, 401, 403, 404, 422].includes(error === null || error === void 0 ? void 0 : error.status)) return false;
|
|
108
112
|
return failureCount < 3;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
})),
|
|
113
|
+
}
|
|
114
|
+
}, opts)),
|
|
112
115
|
combine
|
|
113
116
|
});
|
|
114
117
|
return {
|