@jbrowse/core 2.3.2 → 2.3.4
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/PluginLoader.d.ts +7 -8
- package/PluginLoader.js +18 -20
- package/PluginManager.js +1 -1
- package/data_adapters/BaseAdapter.d.ts +1 -0
- package/data_adapters/BaseAdapter.js +9 -9
- package/package.json +4 -3
- package/pluggableElementTypes/renderers/ComparativeServerSideRendererType.js +3 -3
- package/pluggableElementTypes/renderers/FeatureRendererType.js +3 -1
- package/rpc/methods/CoreGetFeatures.js +3 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/ui/Dialog.js +8 -1
- package/ui/DropDownMenu.js +1 -4
- package/ui/EditableTypography.js +1 -1
- package/ui/FatalErrorDialog.js +0 -1
- package/ui/Menu.js +9 -1
- package/ui/ResizeBar.d.ts +11 -0
- package/ui/ResizeBar.js +95 -0
- package/ui/ResizeHandle.d.ts +1 -1
- package/ui/ResizeHandle.js +1 -1
- package/ui/SanitizedHTML.js +1 -1
- package/ui/theme.d.ts +10 -0
- package/ui/theme.js +10 -0
- package/util/Base1DUtils.d.ts +6 -0
- package/util/Base1DUtils.js +57 -24
- package/util/Base1DViewModel.d.ts +3 -1
- package/util/index.d.ts +17 -7
- package/util/index.js +49 -10
- package/util/stats.js +3 -4
package/ui/Dialog.js
CHANGED
|
@@ -7,8 +7,11 @@ const react_1 = __importDefault(require("react"));
|
|
|
7
7
|
const material_1 = require("@mui/material");
|
|
8
8
|
const mobx_react_1 = require("mobx-react");
|
|
9
9
|
const mui_1 = require("tss-react/mui");
|
|
10
|
+
const react_error_boundary_1 = require("react-error-boundary");
|
|
10
11
|
// icons
|
|
11
12
|
const Close_1 = __importDefault(require("@mui/icons-material/Close"));
|
|
13
|
+
// locals
|
|
14
|
+
const ErrorMessage_1 = __importDefault(require("./ErrorMessage"));
|
|
12
15
|
const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
13
16
|
closeButton: {
|
|
14
17
|
position: 'absolute',
|
|
@@ -17,6 +20,10 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
|
17
20
|
color: theme.palette.grey[500],
|
|
18
21
|
},
|
|
19
22
|
}));
|
|
23
|
+
function DialogError({ error }) {
|
|
24
|
+
return (react_1.default.createElement("div", { style: { width: 800, margin: 40 } },
|
|
25
|
+
react_1.default.createElement(ErrorMessage_1.default, { error: error })));
|
|
26
|
+
}
|
|
20
27
|
function JBrowseDialog(props) {
|
|
21
28
|
const { classes } = useStyles();
|
|
22
29
|
const { title, children, onClose } = props;
|
|
@@ -30,6 +37,6 @@ function JBrowseDialog(props) {
|
|
|
30
37
|
} },
|
|
31
38
|
react_1.default.createElement(Close_1.default, null))) : null),
|
|
32
39
|
react_1.default.createElement(material_1.Divider, null),
|
|
33
|
-
children)));
|
|
40
|
+
react_1.default.createElement(react_error_boundary_1.ErrorBoundary, { FallbackComponent: DialogError }, children))));
|
|
34
41
|
}
|
|
35
42
|
exports.default = (0, mobx_react_1.observer)(JBrowseDialog);
|
package/ui/DropDownMenu.js
CHANGED
|
@@ -33,9 +33,6 @@ const mobx_react_1 = require("mobx-react");
|
|
|
33
33
|
const ArrowDropDown_1 = __importDefault(require("@mui/icons-material/ArrowDropDown"));
|
|
34
34
|
const Menu_1 = __importDefault(require("./Menu"));
|
|
35
35
|
const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
36
|
-
root: {
|
|
37
|
-
display: 'flex',
|
|
38
|
-
},
|
|
39
36
|
buttonRoot: {
|
|
40
37
|
'&:hover': {
|
|
41
38
|
backgroundColor: (0, material_1.alpha)(theme.palette.primary.contrastText, theme.palette.action.hoverOpacity),
|
|
@@ -59,7 +56,7 @@ function DropDownMenu({ menuTitle, session, menuItems, }) {
|
|
|
59
56
|
function handleClose() {
|
|
60
57
|
setOpen(false);
|
|
61
58
|
}
|
|
62
|
-
return (react_1.default.createElement(
|
|
59
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
63
60
|
react_1.default.createElement(material_1.Button, { ref: anchorEl, onClick: handleToggle, color: "inherit", "data-testid": "dropDownMenuButton", classes: { root: classes.buttonRoot } },
|
|
64
61
|
menuTitle,
|
|
65
62
|
react_1.default.createElement(ArrowDropDown_1.default, null)),
|
package/ui/EditableTypography.js
CHANGED
package/ui/FatalErrorDialog.js
CHANGED
|
@@ -36,7 +36,6 @@ const ResetComponent = ({ onFactoryReset, resetButtonText, }) => {
|
|
|
36
36
|
react_1.default.createElement(FactoryResetDialog_1.default, { onClose: () => setDialogOpen(false), open: dialogOpen, onFactoryReset: onFactoryReset })));
|
|
37
37
|
};
|
|
38
38
|
const FatalErrorDialog = ({ componentStack, error = 'No error message provided', onFactoryReset, resetButtonText = 'Factory Reset', }) => {
|
|
39
|
-
console.error(error);
|
|
40
39
|
return (react_1.default.createElement(material_1.Dialog, { open: true },
|
|
41
40
|
react_1.default.createElement(material_1.DialogTitle, { style: { background: '#e88' } }, "Fatal error"),
|
|
42
41
|
react_1.default.createElement(material_1.DialogContent, null,
|
package/ui/Menu.js
CHANGED
|
@@ -245,7 +245,15 @@ const MenuPage = react_1.default.forwardRef((props, ref) => {
|
|
|
245
245
|
});
|
|
246
246
|
function Menu(props) {
|
|
247
247
|
const { open, onClose, menuItems, onMenuItemClick, ...other } = props;
|
|
248
|
-
return (react_1.default.createElement(material_1.Popover, {
|
|
248
|
+
return (react_1.default.createElement(material_1.Popover, { open: open, onClose: onClose, BackdropProps: { invisible: true }, anchorOrigin: {
|
|
249
|
+
vertical: 'bottom',
|
|
250
|
+
horizontal: 'right',
|
|
251
|
+
...other.anchorOrigin,
|
|
252
|
+
}, transformOrigin: {
|
|
253
|
+
vertical: 'top',
|
|
254
|
+
horizontal: 'left',
|
|
255
|
+
...other.transformOrigin,
|
|
256
|
+
}, ...other },
|
|
249
257
|
react_1.default.createElement(MenuPage, { open: open, onClose: onClose, menuItems: menuItems, onMenuItemClick: onMenuItemClick, top: true })));
|
|
250
258
|
}
|
|
251
259
|
exports.default = Menu;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export declare function useResizeBar(): {
|
|
3
|
+
ref: React.RefObject<HTMLDivElement>;
|
|
4
|
+
scrollLeft: number;
|
|
5
|
+
};
|
|
6
|
+
export default function ResizeBar({ widths, setWidths, checkbox, scrollLeft, }: {
|
|
7
|
+
widths: number[];
|
|
8
|
+
setWidths: (arg: number[]) => void;
|
|
9
|
+
checkbox?: boolean;
|
|
10
|
+
scrollLeft?: number;
|
|
11
|
+
}): JSX.Element;
|
package/ui/ResizeBar.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.useResizeBar = void 0;
|
|
30
|
+
const react_1 = __importStar(require("react"));
|
|
31
|
+
const mui_1 = require("tss-react/mui");
|
|
32
|
+
// locals
|
|
33
|
+
const ResizeHandle_1 = __importDefault(require("./ResizeHandle"));
|
|
34
|
+
const useStyles = (0, mui_1.makeStyles)()({
|
|
35
|
+
resizeBar: {
|
|
36
|
+
background: 'lightgrey',
|
|
37
|
+
height: 12,
|
|
38
|
+
position: 'relative',
|
|
39
|
+
overflow: 'hidden',
|
|
40
|
+
},
|
|
41
|
+
tick: {
|
|
42
|
+
position: 'absolute',
|
|
43
|
+
height: '100%',
|
|
44
|
+
pointerEvents: 'none',
|
|
45
|
+
background: 'black',
|
|
46
|
+
width: 1,
|
|
47
|
+
},
|
|
48
|
+
hiddenTick: {
|
|
49
|
+
position: 'absolute',
|
|
50
|
+
height: '100%',
|
|
51
|
+
background: 'lightgrey',
|
|
52
|
+
width: 5,
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
function useResizeBar() {
|
|
56
|
+
const ref = (0, react_1.useRef)(null);
|
|
57
|
+
const [scrollLeft, setScrollLeft] = (0, react_1.useState)(0);
|
|
58
|
+
(0, react_1.useEffect)(() => {
|
|
59
|
+
const timer = setInterval(() => {
|
|
60
|
+
var _a;
|
|
61
|
+
const elt = (_a = ref.current) === null || _a === void 0 ? void 0 : _a.querySelector('.MuiDataGrid-virtualScroller');
|
|
62
|
+
if (elt) {
|
|
63
|
+
setScrollLeft(elt.scrollLeft);
|
|
64
|
+
}
|
|
65
|
+
}, 100);
|
|
66
|
+
return () => {
|
|
67
|
+
clearInterval(timer);
|
|
68
|
+
};
|
|
69
|
+
}, []);
|
|
70
|
+
return { ref, scrollLeft };
|
|
71
|
+
}
|
|
72
|
+
exports.useResizeBar = useResizeBar;
|
|
73
|
+
function Tick({ left, scrollLeft, idx, onDrag, }) {
|
|
74
|
+
const { classes } = useStyles();
|
|
75
|
+
const cb = (0, react_1.useCallback)((d) => {
|
|
76
|
+
onDrag(d, idx);
|
|
77
|
+
}, [idx, onDrag]);
|
|
78
|
+
// has an invisible wider than tick mark (1px) clickable area (5px)
|
|
79
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
80
|
+
react_1.default.createElement(ResizeHandle_1.default, { onDrag: cb, vertical: true, className: classes.hiddenTick, style: { left: left - scrollLeft - 2.5 } }),
|
|
81
|
+
react_1.default.createElement("div", { style: { left: left - scrollLeft }, className: classes.tick })));
|
|
82
|
+
}
|
|
83
|
+
function ResizeBar({ widths, setWidths, checkbox, scrollLeft = 0, }) {
|
|
84
|
+
const { classes } = useStyles();
|
|
85
|
+
const offsets = [];
|
|
86
|
+
widths.reduce((a, b, i) => (offsets[i] = a + b), checkbox ? 52 : 0);
|
|
87
|
+
const onDrag = (0, react_1.useCallback)((distance, idx) => {
|
|
88
|
+
const newWidths = [...widths];
|
|
89
|
+
// mui doesn't allow columns smaller than 50
|
|
90
|
+
newWidths[idx] = Math.max(newWidths[idx] + distance, 50);
|
|
91
|
+
setWidths(newWidths);
|
|
92
|
+
}, [widths, setWidths]);
|
|
93
|
+
return (react_1.default.createElement("div", { className: classes.resizeBar }, offsets.map((left, i) => (react_1.default.createElement(Tick, { key: i, left: i === offsets.length - 1 ? left - 3 : left, onDrag: onDrag, idx: i, scrollLeft: scrollLeft })))));
|
|
94
|
+
}
|
|
95
|
+
exports.default = ResizeBar;
|
package/ui/ResizeHandle.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
declare function ResizeHandle({ onDrag, vertical, flexbox, className: originalClassName, ...props }: {
|
|
3
|
-
onDrag: (arg: number) => number;
|
|
3
|
+
onDrag: (arg: number) => number | void;
|
|
4
4
|
vertical?: boolean;
|
|
5
5
|
flexbox?: boolean;
|
|
6
6
|
className?: string;
|
package/ui/ResizeHandle.js
CHANGED
|
@@ -89,6 +89,6 @@ function ResizeHandle({ onDrag, vertical = false, flexbox = false, className: or
|
|
|
89
89
|
event.preventDefault();
|
|
90
90
|
prevPos.current = vertical ? event.clientX : event.clientY;
|
|
91
91
|
setMouseDragging(true);
|
|
92
|
-
},
|
|
92
|
+
}, className: cx(className, originalClassName), ...props }));
|
|
93
93
|
}
|
|
94
94
|
exports.default = ResizeHandle;
|
package/ui/SanitizedHTML.js
CHANGED
|
@@ -65,7 +65,7 @@ function SanitizedHTML({ html }) {
|
|
|
65
65
|
}
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
|
-
return (react_1.default.createElement("
|
|
68
|
+
return (react_1.default.createElement("span", {
|
|
69
69
|
// eslint-disable-next-line react/no-danger
|
|
70
70
|
dangerouslySetInnerHTML: {
|
|
71
71
|
__html: dompurify_1.default.sanitize(value),
|
package/ui/theme.d.ts
CHANGED
|
@@ -116,6 +116,16 @@ export declare function createJBrowseDefaultProps(): {
|
|
|
116
116
|
size: "small";
|
|
117
117
|
};
|
|
118
118
|
};
|
|
119
|
+
MuiPopover: {
|
|
120
|
+
defaultProps: {
|
|
121
|
+
transitionDuration: number;
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
MuiMenu: {
|
|
125
|
+
defaultProps: {
|
|
126
|
+
transitionDuration: number;
|
|
127
|
+
};
|
|
128
|
+
};
|
|
119
129
|
MuiMenuList: {
|
|
120
130
|
defaultProps: {
|
|
121
131
|
dense: boolean;
|
package/ui/theme.js
CHANGED
|
@@ -102,6 +102,16 @@ function createJBrowseDefaultProps( /* palette: PaletteOptions = {} */) {
|
|
|
102
102
|
size: 'small',
|
|
103
103
|
},
|
|
104
104
|
},
|
|
105
|
+
MuiPopover: {
|
|
106
|
+
defaultProps: {
|
|
107
|
+
transitionDuration: 0,
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
MuiMenu: {
|
|
111
|
+
defaultProps: {
|
|
112
|
+
transitionDuration: 0,
|
|
113
|
+
},
|
|
114
|
+
},
|
|
105
115
|
MuiMenuList: {
|
|
106
116
|
defaultProps: {
|
|
107
117
|
dense: true,
|
package/util/Base1DUtils.d.ts
CHANGED
|
@@ -30,3 +30,9 @@ export declare function bpToPx({ refName, coord, regionNumber, self, }: {
|
|
|
30
30
|
index: number;
|
|
31
31
|
offsetPx: number;
|
|
32
32
|
} | undefined;
|
|
33
|
+
export declare function bpToPxMap({ refName, coord, regionNumber, self, }: {
|
|
34
|
+
refName: string;
|
|
35
|
+
coord: number;
|
|
36
|
+
regionNumber?: number;
|
|
37
|
+
self: ViewSnap;
|
|
38
|
+
}): {};
|
package/util/Base1DUtils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.bpToPx = exports.pxToBp = exports.moveTo = void 0;
|
|
3
|
+
exports.bpToPxMap = exports.bpToPx = exports.pxToBp = exports.moveTo = void 0;
|
|
4
4
|
const mobx_state_tree_1 = require("mobx-state-tree");
|
|
5
5
|
function lengthBetween(self, start, end) {
|
|
6
6
|
let bpSoFar = 0;
|
|
@@ -57,6 +57,9 @@ function moveTo(self, start, end) {
|
|
|
57
57
|
self.scrollTo(Math.round(bpToStart / self.bpPerPx));
|
|
58
58
|
}
|
|
59
59
|
exports.moveTo = moveTo;
|
|
60
|
+
function coord(r, bp) {
|
|
61
|
+
return Math.floor(r.reversed ? r.end - bp : r.start + bp) + 1;
|
|
62
|
+
}
|
|
60
63
|
// manual return type since getSnapshot hard to infer here
|
|
61
64
|
function pxToBp(self, px) {
|
|
62
65
|
var _a;
|
|
@@ -65,16 +68,14 @@ function pxToBp(self, px) {
|
|
|
65
68
|
const blocks = staticBlocks.contentBlocks;
|
|
66
69
|
const bp = (offsetPx + px) * bpPerPx;
|
|
67
70
|
if (bp < 0) {
|
|
68
|
-
const
|
|
69
|
-
const snap = (0, mobx_state_tree_1.getSnapshot)(
|
|
71
|
+
const r = displayedRegions[0];
|
|
72
|
+
const snap = (0, mobx_state_tree_1.getSnapshot)(r);
|
|
70
73
|
// @ts-ignore
|
|
71
74
|
return {
|
|
72
75
|
// xref https://github.com/mobxjs/mobx-state-tree/issues/1524 for Omit
|
|
73
76
|
...snap,
|
|
74
77
|
oob: true,
|
|
75
|
-
coord:
|
|
76
|
-
? Math.floor(region.end - bp) + 1
|
|
77
|
-
: Math.floor(region.start + bp) + 1,
|
|
78
|
+
coord: coord(r, bp),
|
|
78
79
|
offset: bp,
|
|
79
80
|
index: 0,
|
|
80
81
|
};
|
|
@@ -82,20 +83,18 @@ function pxToBp(self, px) {
|
|
|
82
83
|
const interRegionPaddingBp = interRegionPaddingWidth * bpPerPx;
|
|
83
84
|
let currBlock = 0;
|
|
84
85
|
for (let i = 0; i < displayedRegions.length; i++) {
|
|
85
|
-
const
|
|
86
|
-
const len =
|
|
86
|
+
const r = displayedRegions[i];
|
|
87
|
+
const len = r.end - r.start;
|
|
87
88
|
const offset = bp - bpSoFar;
|
|
88
89
|
if (len + bpSoFar > bp && bpSoFar <= bp) {
|
|
89
|
-
const snap = (0, mobx_state_tree_1.getSnapshot)(
|
|
90
|
+
const snap = (0, mobx_state_tree_1.getSnapshot)(r);
|
|
90
91
|
// @ts-ignore
|
|
91
92
|
return {
|
|
92
93
|
// xref https://github.com/mobxjs/mobx-state-tree/issues/1524 for Omit
|
|
93
94
|
...snap,
|
|
94
95
|
oob: false,
|
|
95
96
|
offset,
|
|
96
|
-
coord:
|
|
97
|
-
? Math.floor(region.end - offset) + 1
|
|
98
|
-
: Math.floor(region.start + offset) + 1,
|
|
97
|
+
coord: coord(r, offset),
|
|
99
98
|
index: i,
|
|
100
99
|
};
|
|
101
100
|
}
|
|
@@ -110,19 +109,17 @@ function pxToBp(self, px) {
|
|
|
110
109
|
}
|
|
111
110
|
}
|
|
112
111
|
if (bp >= bpSoFar && displayedRegions.length) {
|
|
113
|
-
const
|
|
114
|
-
const len =
|
|
112
|
+
const r = displayedRegions[displayedRegions.length - 1];
|
|
113
|
+
const len = r.end - r.start;
|
|
115
114
|
const offset = bp - bpSoFar + len;
|
|
116
|
-
const snap = (0, mobx_state_tree_1.getSnapshot)(
|
|
115
|
+
const snap = (0, mobx_state_tree_1.getSnapshot)(r);
|
|
117
116
|
// @ts-ignore
|
|
118
117
|
return {
|
|
119
118
|
// xref https://github.com/mobxjs/mobx-state-tree/issues/1524 for Omit
|
|
120
119
|
...snap,
|
|
121
120
|
oob: true,
|
|
122
121
|
offset,
|
|
123
|
-
coord:
|
|
124
|
-
? Math.floor(region.end - offset) + 1
|
|
125
|
-
: Math.floor(region.start + offset) + 1,
|
|
122
|
+
coord: coord(r, offset),
|
|
126
123
|
index: displayedRegions.length - 1,
|
|
127
124
|
};
|
|
128
125
|
}
|
|
@@ -148,13 +145,11 @@ function bpToPx({ refName, coord, regionNumber, self, }) {
|
|
|
148
145
|
let currBlock = 0;
|
|
149
146
|
let i = 0;
|
|
150
147
|
for (; i < displayedRegions.length; i++) {
|
|
151
|
-
const
|
|
152
|
-
const len =
|
|
153
|
-
if (refName ===
|
|
154
|
-
coord >= region.start &&
|
|
155
|
-
coord <= region.end) {
|
|
148
|
+
const r = displayedRegions[i];
|
|
149
|
+
const len = r.end - r.start;
|
|
150
|
+
if (refName === r.refName && coord >= r.start && coord <= r.end) {
|
|
156
151
|
if (regionNumber ? regionNumber === i : true) {
|
|
157
|
-
bpSoFar +=
|
|
152
|
+
bpSoFar += r.reversed ? r.end - coord : coord - r.start;
|
|
158
153
|
break;
|
|
159
154
|
}
|
|
160
155
|
}
|
|
@@ -178,3 +173,41 @@ function bpToPx({ refName, coord, regionNumber, self, }) {
|
|
|
178
173
|
return undefined;
|
|
179
174
|
}
|
|
180
175
|
exports.bpToPx = bpToPx;
|
|
176
|
+
function bpToPxMap({ refName, coord, regionNumber, self, }) {
|
|
177
|
+
var _a;
|
|
178
|
+
let bpSoFar = 0;
|
|
179
|
+
const { interRegionPaddingWidth, bpPerPx, displayedRegions, staticBlocks } = self;
|
|
180
|
+
const blocks = staticBlocks.contentBlocks;
|
|
181
|
+
const interRegionPaddingBp = interRegionPaddingWidth * bpPerPx;
|
|
182
|
+
const map = {};
|
|
183
|
+
let currBlock = 0;
|
|
184
|
+
let i = 0;
|
|
185
|
+
for (; i < displayedRegions.length; i++) {
|
|
186
|
+
const r = displayedRegions[i];
|
|
187
|
+
const len = r.end - r.start;
|
|
188
|
+
if (refName === r.refName && coord >= r.start && coord <= r.end) {
|
|
189
|
+
if (regionNumber !== undefined ? regionNumber === i : true) {
|
|
190
|
+
bpSoFar += r.reversed ? r.end - coord : coord - r.start;
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// add the interRegionPaddingWidth if the boundary is in the screen e.g. in
|
|
195
|
+
// a static block
|
|
196
|
+
if (((_a = blocks[currBlock]) === null || _a === void 0 ? void 0 : _a.regionNumber) === i) {
|
|
197
|
+
bpSoFar += len + interRegionPaddingBp;
|
|
198
|
+
currBlock++;
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
bpSoFar += len;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
const found = displayedRegions[i];
|
|
205
|
+
if (found) {
|
|
206
|
+
return {
|
|
207
|
+
index: i,
|
|
208
|
+
offsetPx: Math.round(bpSoFar / bpPerPx),
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
return map;
|
|
212
|
+
}
|
|
213
|
+
exports.bpToPxMap = bpToPxMap;
|
package/util/index.d.ts
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import PluginManager from '../PluginManager';
|
|
2
2
|
import { IAnyStateTreeNode, IStateTreeNode } from 'mobx-state-tree';
|
|
3
3
|
import { IReactionPublic, IReactionOptions } from 'mobx';
|
|
4
|
-
import SimpleFeature, { Feature, isFeature } from './simpleFeature';
|
|
4
|
+
import SimpleFeature, { Feature, SimpleFeatureSerialized, isFeature } from './simpleFeature';
|
|
5
5
|
import { AssemblyManager, Region, TypeTestedByPredicate } from './types';
|
|
6
6
|
import { BaseBlock } from './blockTypes';
|
|
7
|
-
export type { Feature };
|
|
8
7
|
export * from './types';
|
|
9
8
|
export * from './aborting';
|
|
10
9
|
export * from './when';
|
|
11
10
|
export * from './range';
|
|
12
11
|
export * from './dedupe';
|
|
13
12
|
export { SimpleFeature, isFeature };
|
|
13
|
+
export type { Feature, SimpleFeatureSerialized };
|
|
14
14
|
export * from './offscreenCanvasPonyfill';
|
|
15
15
|
export * from './offscreenCanvasUtils';
|
|
16
16
|
export declare const inDevelopment: boolean;
|
|
17
17
|
export declare const inProduction: boolean;
|
|
18
18
|
export declare function useDebounce<T>(value: T, delay: number): T;
|
|
19
|
-
export declare function useDebouncedCallback<
|
|
19
|
+
export declare function useDebouncedCallback<T>(callback: (...args: T[]) => void, wait?: number): (...args: T[]) => void;
|
|
20
20
|
/** find the first node in the hierarchy that matches the given predicate */
|
|
21
21
|
export declare function findParentThat(node: IAnyStateTreeNode, predicate: (thing: IAnyStateTreeNode) => boolean): IAnyStateTreeNode;
|
|
22
22
|
export declare function springAnimate(fromValue: number, toValue: number, setValue: (value: number) => void, onFinish?: () => void, precision?: number, tension?: number, friction?: number): (() => void)[];
|
|
@@ -153,7 +153,7 @@ export declare function bpSpanPx(leftBp: number, rightBp: number, region: {
|
|
|
153
153
|
end: number;
|
|
154
154
|
reversed?: boolean;
|
|
155
155
|
}, bpPerPx: number): [number, number];
|
|
156
|
-
export declare function iterMap<T, U>(
|
|
156
|
+
export declare function iterMap<T, U>(iter: Iterable<T>, func: (arg: T) => U, sizeHint?: number): U[];
|
|
157
157
|
/**
|
|
158
158
|
* Returns the index of the last element in the array where predicate is true,
|
|
159
159
|
* and -1 otherwise.
|
|
@@ -280,8 +280,8 @@ export declare const defaultCodonTable: {
|
|
|
280
280
|
GGT: string;
|
|
281
281
|
};
|
|
282
282
|
/**
|
|
283
|
-
*
|
|
284
|
-
*
|
|
283
|
+
* take CodonTable above and generate larger codon table that includes all
|
|
284
|
+
* permutations of upper and lower case nucleotides
|
|
285
285
|
*/
|
|
286
286
|
export declare function generateCodonTable(table: any): {
|
|
287
287
|
[key: string]: string;
|
|
@@ -337,8 +337,18 @@ export declare function getUriLink(value: {
|
|
|
337
337
|
baseUri?: string;
|
|
338
338
|
}): string;
|
|
339
339
|
export declare function getStr(obj: unknown): string;
|
|
340
|
-
export declare function measureGridWidth(elements: string[]
|
|
340
|
+
export declare function measureGridWidth(elements: string[], args?: {
|
|
341
|
+
minWidth?: number;
|
|
342
|
+
fontSize?: number;
|
|
343
|
+
maxWidth?: number;
|
|
344
|
+
padding?: number;
|
|
345
|
+
stripHTML?: boolean;
|
|
346
|
+
}): number;
|
|
341
347
|
export declare function getEnv(obj: any): {
|
|
342
348
|
pluginManager: PluginManager;
|
|
343
349
|
};
|
|
344
350
|
export declare function localStorageGetItem(item: string): string | null | undefined;
|
|
351
|
+
export declare function max(arr: number[]): number;
|
|
352
|
+
export declare function min(arr: number[]): number;
|
|
353
|
+
export declare function sum(arr: number[]): number;
|
|
354
|
+
export declare function avg(arr: number[]): number;
|
package/util/index.js
CHANGED
|
@@ -30,7 +30,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
30
30
|
};
|
|
31
31
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
32
|
exports.bytesForRegions = exports.objectHash = exports.hashCode = exports.updateStatus = exports.generateCodonTable = exports.defaultCodonTable = exports.defaultStops = exports.defaultStarts = exports.measureText = exports.rIC = exports.blobToDataURL = exports.complement = exports.reverse = exports.revcom = exports.isElectron = exports.stringify = exports.shorten = exports.minmax = exports.renameRegionsIfNeeded = exports.renameRegionIfNeeded = exports.makeAbortableReaction = exports.findLastIndex = exports.iterMap = exports.bpSpanPx = exports.featureSpanPx = exports.cartesianToPolar = exports.polarToCartesian = exports.degToRad = exports.radToDeg = exports.bpToPx = exports.clamp = exports.compareLocStrings = exports.compareLocs = exports.parseLocString = exports.parseLocStringOneBased = exports.assembleLocStringFast = exports.assembleLocString = exports.getContainingDisplay = exports.getContainingTrack = exports.getContainingView = exports.getSession = exports.findParentThatIs = exports.springAnimate = exports.findParentThat = exports.useDebouncedCallback = exports.useDebounce = exports.inProduction = exports.inDevelopment = exports.isFeature = exports.SimpleFeature = void 0;
|
|
33
|
-
exports.localStorageGetItem = exports.getEnv = exports.measureGridWidth = exports.getStr = exports.getUriLink = exports.useLocalStorage = exports.getLayoutId = exports.getViewParams = exports.getTickDisplayStr = exports.toLocale = exports.getBpDisplayStr = exports.supportedIndexingAdapters = void 0;
|
|
33
|
+
exports.avg = exports.sum = exports.min = exports.max = exports.localStorageGetItem = exports.getEnv = exports.measureGridWidth = exports.getStr = exports.getUriLink = exports.useLocalStorage = exports.getLayoutId = exports.getViewParams = exports.getTickDisplayStr = exports.toLocale = exports.getBpDisplayStr = exports.supportedIndexingAdapters = void 0;
|
|
34
34
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
35
35
|
const react_1 = require("react");
|
|
36
36
|
const is_object_1 = __importDefault(require("is-object"));
|
|
@@ -66,7 +66,7 @@ function useDebounce(value, delay) {
|
|
|
66
66
|
return debouncedValue;
|
|
67
67
|
}
|
|
68
68
|
exports.useDebounce = useDebounce;
|
|
69
|
-
// https://stackoverflow.com/questions/56283920/
|
|
69
|
+
// https://stackoverflow.com/questions/56283920/
|
|
70
70
|
function useDebouncedCallback(callback, wait = 400) {
|
|
71
71
|
// track args & timeout handle between calls
|
|
72
72
|
const argsRef = (0, react_1.useRef)();
|
|
@@ -504,10 +504,10 @@ function bpSpanPx(leftBp, rightBp, region, bpPerPx) {
|
|
|
504
504
|
}
|
|
505
505
|
exports.bpSpanPx = bpSpanPx;
|
|
506
506
|
// do an array map of an iterable
|
|
507
|
-
function iterMap(
|
|
507
|
+
function iterMap(iter, func, sizeHint) {
|
|
508
508
|
const results = sizeHint ? new Array(sizeHint) : [];
|
|
509
509
|
let counter = 0;
|
|
510
|
-
for (const item of
|
|
510
|
+
for (const item of iter) {
|
|
511
511
|
results[counter] = func(item);
|
|
512
512
|
counter += 1;
|
|
513
513
|
}
|
|
@@ -664,8 +664,10 @@ function stringify({ refName, coord, oob, }) {
|
|
|
664
664
|
: '';
|
|
665
665
|
}
|
|
666
666
|
exports.stringify = stringify;
|
|
667
|
-
// this is recommended in a later comment in
|
|
668
|
-
// for detecting electron in a
|
|
667
|
+
// this is recommended in a later comment in
|
|
668
|
+
// https://github.com/electron/electron/issues/2288 for detecting electron in a
|
|
669
|
+
// renderer process, which is the one that has node enabled for us
|
|
670
|
+
//
|
|
669
671
|
// const isElectron = process.versions.electron
|
|
670
672
|
// const i2 = process.versions.hasOwnProperty('electron')
|
|
671
673
|
exports.isElectron = /electron/i.test(typeof navigator !== 'undefined' ? navigator.userAgent : '');
|
|
@@ -829,8 +831,8 @@ exports.defaultCodonTable = {
|
|
|
829
831
|
GGT: 'G',
|
|
830
832
|
};
|
|
831
833
|
/**
|
|
832
|
-
*
|
|
833
|
-
*
|
|
834
|
+
* take CodonTable above and generate larger codon table that includes all
|
|
835
|
+
* permutations of upper and lower case nucleotides
|
|
834
836
|
*/
|
|
835
837
|
function generateCodonTable(table) {
|
|
836
838
|
const tempCodonTable = {};
|
|
@@ -1002,9 +1004,18 @@ function getStr(obj) {
|
|
|
1002
1004
|
: String(obj);
|
|
1003
1005
|
}
|
|
1004
1006
|
exports.getStr = getStr;
|
|
1007
|
+
// tries to measure grid width without HTML tags included
|
|
1008
|
+
function coarseStripHTML(s) {
|
|
1009
|
+
return s.replace(/(<([^>]+)>)/gi, '');
|
|
1010
|
+
}
|
|
1005
1011
|
// heuristic measurement for a column of a @mui/x-data-grid, pass in values from a column
|
|
1006
|
-
function measureGridWidth(elements) {
|
|
1007
|
-
|
|
1012
|
+
function measureGridWidth(elements, args) {
|
|
1013
|
+
const { padding = 30, minWidth = 80, fontSize = 12, maxWidth = 1000, stripHTML = false, } = args || {};
|
|
1014
|
+
return max(elements
|
|
1015
|
+
.map(element => getStr(element))
|
|
1016
|
+
.map(str => (stripHTML ? coarseStripHTML(str) : str))
|
|
1017
|
+
.map(str => measureText(str, fontSize))
|
|
1018
|
+
.map(n => Math.min(Math.max(n + padding, minWidth), maxWidth)));
|
|
1008
1019
|
}
|
|
1009
1020
|
exports.measureGridWidth = measureGridWidth;
|
|
1010
1021
|
function getEnv(obj) {
|
|
@@ -1017,3 +1028,31 @@ function localStorageGetItem(item) {
|
|
|
1017
1028
|
: undefined;
|
|
1018
1029
|
}
|
|
1019
1030
|
exports.localStorageGetItem = localStorageGetItem;
|
|
1031
|
+
function max(arr) {
|
|
1032
|
+
let max = -Infinity;
|
|
1033
|
+
for (let i = 0; i < arr.length; i++) {
|
|
1034
|
+
max = arr[i] > max ? arr[i] : max;
|
|
1035
|
+
}
|
|
1036
|
+
return max;
|
|
1037
|
+
}
|
|
1038
|
+
exports.max = max;
|
|
1039
|
+
function min(arr) {
|
|
1040
|
+
let min = Infinity;
|
|
1041
|
+
for (let i = 0; i < arr.length; i++) {
|
|
1042
|
+
min = arr[i] < min ? arr[i] : min;
|
|
1043
|
+
}
|
|
1044
|
+
return min;
|
|
1045
|
+
}
|
|
1046
|
+
exports.min = min;
|
|
1047
|
+
function sum(arr) {
|
|
1048
|
+
let sum = 0;
|
|
1049
|
+
for (let i = 0; i < arr.length; i++) {
|
|
1050
|
+
sum += arr[i];
|
|
1051
|
+
}
|
|
1052
|
+
return sum;
|
|
1053
|
+
}
|
|
1054
|
+
exports.sum = sum;
|
|
1055
|
+
function avg(arr) {
|
|
1056
|
+
return sum(arr) / arr.length;
|
|
1057
|
+
}
|
|
1058
|
+
exports.avg = avg;
|
package/util/stats.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.blankStats = exports.scoresToStats = exports.calcPerBaseStats = exports.rectifyStats = exports.calcStdFromSums = void 0;
|
|
4
|
+
const rxjs_1 = require("rxjs");
|
|
4
5
|
const operators_1 = require("rxjs/operators");
|
|
5
6
|
/**
|
|
6
7
|
* calculate standard deviation using the 'shortcut method' that accepts
|
|
@@ -96,8 +97,7 @@ async function scoresToStats(region, feats) {
|
|
|
96
97
|
featureCount: 0,
|
|
97
98
|
};
|
|
98
99
|
let found = false;
|
|
99
|
-
const { scoreMin, scoreMax, scoreSum, scoreSumSquares, featureCount } = await feats
|
|
100
|
-
.pipe((0, operators_1.reduce)((acc, f) => {
|
|
100
|
+
const { scoreMin, scoreMax, scoreSum, scoreSumSquares, featureCount } = await (0, rxjs_1.firstValueFrom)(feats.pipe((0, operators_1.reduce)((acc, f) => {
|
|
101
101
|
const s = f.get('score');
|
|
102
102
|
const summary = f.get('summary');
|
|
103
103
|
const { scoreMax, scoreMin } = acc;
|
|
@@ -108,8 +108,7 @@ async function scoresToStats(region, feats) {
|
|
|
108
108
|
acc.featureCount += 1;
|
|
109
109
|
found = true;
|
|
110
110
|
return acc;
|
|
111
|
-
}, seed))
|
|
112
|
-
.toPromise();
|
|
111
|
+
}, seed)));
|
|
113
112
|
return found
|
|
114
113
|
? rectifyStats({
|
|
115
114
|
scoreMax,
|