@jbrowse/core 2.4.0 → 2.4.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.
- package/BaseFeatureWidget/BaseFeatureDetail.d.ts +1 -3
- package/BaseFeatureWidget/BaseFeatureDetail.js +13 -9
- package/BaseFeatureWidget/SequenceFeatureDetails.js +3 -10
- package/BaseFeatureWidget/SequencePanel.js +1 -1
- package/BaseFeatureWidget/index.d.ts +1 -1
- package/BaseFeatureWidget/index.js +8 -11
- package/PluginLoader.js +8 -8
- package/PluginManager.d.ts +2 -4
- package/PluginManager.js +2 -3
- package/ReExports/Attributes.d.ts +1 -2
- package/ReExports/Attributes.js +4 -3
- package/ReExports/BaseCard.d.ts +1 -2
- package/ReExports/BaseCard.js +4 -3
- package/ReExports/DataGrid.d.ts +1 -2
- package/ReExports/DataGrid.js +2 -2
- package/ReExports/FeatureDetails.d.ts +1 -2
- package/ReExports/FeatureDetails.js +4 -3
- package/ReExports/index.d.ts +1 -2
- package/ReExports/index.js +3 -2
- package/ReExports/modules.d.ts +2 -4
- package/ReExports/modules.js +2 -2
- package/assemblyManager/assembly.js +5 -5
- package/assemblyManager/assemblyConfigSchema.js +2 -2
- package/configuration/configurationSchema.d.ts +3 -1
- package/configuration/configurationSchema.js +1 -1
- package/configuration/configurationSlot.d.ts +1 -0
- package/configuration/util.js +1 -1
- package/data_adapters/BaseAdapter.js +1 -1
- package/data_adapters/CytobandAdapter/CytobandAdapter.js +1 -1
- package/data_adapters/dataAdapterCache.d.ts +3 -2
- package/data_adapters/dataAdapterCache.js +2 -3
- package/package.json +2 -3
- package/pluggableElementTypes/RpcMethodType.js +1 -1
- package/pluggableElementTypes/index.d.ts +11 -1
- package/pluggableElementTypes/index.js +23 -23
- package/pluggableElementTypes/models/BaseConnectionModelFactory.js +2 -2
- package/pluggableElementTypes/models/BaseTrackModel.js +8 -13
- package/pluggableElementTypes/models/baseTrackConfig.js +1 -1
- package/pluggableElementTypes/renderers/ComparativeServerSideRendererType.d.ts +2 -2
- package/pluggableElementTypes/renderers/ComparativeServerSideRendererType.js +1 -3
- package/pluggableElementTypes/renderers/ServerSideRendererType.d.ts +1 -1
- package/pluggableElementTypes/renderers/index.d.ts +7 -9
- package/pluggableElementTypes/renderers/index.js +15 -15
- package/pluggableElementTypes/renderers/util/serializableFilterChain.js +1 -1
- package/rpc/BaseRpcDriver.js +7 -8
- package/rpc/WebWorkerRpcDriver.js +18 -12
- package/rpc/coreRpcMethods.d.ts +9 -11
- package/rpc/coreRpcMethods.js +17 -17
- package/rpc/methods/CoreGetFeatureDetails.js +1 -1
- package/rpc/methods/util.d.ts +2 -2
- package/rpc/methods/util.js +2 -2
- package/rpc/remoteAbortSignals.js +0 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/ui/App.js +1 -1
- package/ui/AppLogo.js +1 -6
- package/ui/ColorPicker.js +1 -1
- package/ui/Dialog.js +1 -1
- package/ui/DrawerWidget.js +4 -4
- package/ui/EditableTypography.js +1 -1
- package/ui/FileSelector/FileSelector.d.ts +2 -2
- package/ui/FileSelector/FileSelector.js +24 -35
- package/ui/FileSelector/index.d.ts +1 -2
- package/ui/FileSelector/index.js +3 -2
- package/ui/LoadingEllipses.js +4 -4
- package/ui/Menu.js +45 -32
- package/ui/ResizeBar.js +6 -1
- package/ui/ResizeHandle.js +3 -6
- package/ui/ViewContainer.d.ts +2 -3
- package/ui/ViewContainer.js +7 -41
- package/ui/ViewContainerTitle.d.ts +6 -0
- package/ui/ViewContainerTitle.js +42 -0
- package/ui/theme.js +7 -7
- package/util/Base1DUtils.js +16 -14
- package/util/Base1DViewModel.d.ts +1 -1
- package/util/Base1DViewModel.js +9 -8
- package/util/aborting.js +1 -1
- package/util/analytics.js +1 -1
- package/util/blockTypes.js +10 -10
- package/util/color/index.d.ts +1 -2
- package/util/color/index.js +4 -3
- package/util/idMaker.js +5 -8
- package/util/index.d.ts +11 -9
- package/util/index.js +42 -50
- package/util/io/RemoteFileWithRangeCache.js +2 -2
- package/util/io/index.d.ts +4 -3
- package/util/io/index.js +14 -9
- package/util/jexl.js +3 -1
- package/util/layouts/GranularRectLayout.js +10 -4
- package/util/layouts/MultiLayout.js +1 -1
- package/util/layouts/SceneGraph.js +3 -7
- package/util/mst-reflection.d.ts +12 -17
- package/util/mst-reflection.js +13 -12
- package/util/offscreenCanvasPonyfill.js +4 -3
- package/util/offscreenCanvasUtils.js +1 -0
- package/util/tracks.d.ts +1 -1
- package/util/tracks.js +0 -1
- package/util/types/index.d.ts +2 -1
- package/util/types/index.js +3 -3
- package/util/types/mst.js +3 -3
- package/util/useMeasure.d.ts +5 -0
- package/util/useMeasure.js +34 -0
package/util/Base1DUtils.js
CHANGED
|
@@ -70,7 +70,7 @@ function pxToBp(self, px) {
|
|
|
70
70
|
if (bp < 0) {
|
|
71
71
|
const r = displayedRegions[0];
|
|
72
72
|
const snap = (0, mobx_state_tree_1.getSnapshot)(r);
|
|
73
|
-
// @ts-
|
|
73
|
+
// @ts-expect-error
|
|
74
74
|
return {
|
|
75
75
|
// xref https://github.com/mobxjs/mobx-state-tree/issues/1524 for Omit
|
|
76
76
|
...snap,
|
|
@@ -88,7 +88,7 @@ function pxToBp(self, px) {
|
|
|
88
88
|
const offset = bp - bpSoFar;
|
|
89
89
|
if (len + bpSoFar > bp && bpSoFar <= bp) {
|
|
90
90
|
const snap = (0, mobx_state_tree_1.getSnapshot)(r);
|
|
91
|
-
// @ts-
|
|
91
|
+
// @ts-expect-error
|
|
92
92
|
return {
|
|
93
93
|
// xref https://github.com/mobxjs/mobx-state-tree/issues/1524 for Omit
|
|
94
94
|
...snap,
|
|
@@ -108,12 +108,12 @@ function pxToBp(self, px) {
|
|
|
108
108
|
bpSoFar += len;
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
-
if (bp >= bpSoFar && displayedRegions.length) {
|
|
111
|
+
if (bp >= bpSoFar && displayedRegions.length > 0) {
|
|
112
112
|
const r = displayedRegions[displayedRegions.length - 1];
|
|
113
113
|
const len = r.end - r.start;
|
|
114
114
|
const offset = bp - bpSoFar + len;
|
|
115
115
|
const snap = (0, mobx_state_tree_1.getSnapshot)(r);
|
|
116
|
-
// @ts-
|
|
116
|
+
// @ts-expect-error
|
|
117
117
|
return {
|
|
118
118
|
// xref https://github.com/mobxjs/mobx-state-tree/issues/1524 for Omit
|
|
119
119
|
...snap,
|
|
@@ -147,11 +147,12 @@ function bpToPx({ refName, coord, regionNumber, self, }) {
|
|
|
147
147
|
for (; i < displayedRegions.length; i++) {
|
|
148
148
|
const r = displayedRegions[i];
|
|
149
149
|
const len = r.end - r.start;
|
|
150
|
-
if (refName === r.refName &&
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
150
|
+
if (refName === r.refName &&
|
|
151
|
+
coord >= r.start &&
|
|
152
|
+
coord <= r.end &&
|
|
153
|
+
(regionNumber ? regionNumber === i : true)) {
|
|
154
|
+
bpSoFar += r.reversed ? r.end - coord : coord - r.start;
|
|
155
|
+
break;
|
|
155
156
|
}
|
|
156
157
|
// add the interRegionPaddingWidth if the boundary is in the screen e.g. in
|
|
157
158
|
// a static block
|
|
@@ -185,11 +186,12 @@ function bpToPxMap({ refName, coord, regionNumber, self, }) {
|
|
|
185
186
|
for (; i < displayedRegions.length; i++) {
|
|
186
187
|
const r = displayedRegions[i];
|
|
187
188
|
const len = r.end - r.start;
|
|
188
|
-
if (refName === r.refName &&
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
189
|
+
if (refName === r.refName &&
|
|
190
|
+
coord >= r.start &&
|
|
191
|
+
coord <= r.end &&
|
|
192
|
+
(regionNumber === undefined ? true : regionNumber === i)) {
|
|
193
|
+
bpSoFar += r.reversed ? r.end - coord : coord - r.start;
|
|
194
|
+
break;
|
|
193
195
|
}
|
|
194
196
|
// add the interRegionPaddingWidth if the boundary is in the screen e.g. in
|
|
195
197
|
// a static block
|
package/util/Base1DViewModel.js
CHANGED
|
@@ -180,15 +180,16 @@ const Base1DView = mobx_state_tree_1.types
|
|
|
180
180
|
/**
|
|
181
181
|
* #action
|
|
182
182
|
*/
|
|
183
|
-
zoomTo(
|
|
184
|
-
const
|
|
185
|
-
if (bpPerPx === self.bpPerPx) {
|
|
186
|
-
return self.bpPerPx;
|
|
187
|
-
}
|
|
183
|
+
zoomTo(bpPerPx, offset = self.width / 2) {
|
|
184
|
+
const newBpPerPx = (0, index_1.clamp)(bpPerPx, 'minBpPerPx' in self ? self.minBpPerPx : 0, 'maxBpPerPx' in self ? self.maxBpPerPx : Infinity);
|
|
188
185
|
const oldBpPerPx = self.bpPerPx;
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
186
|
+
if (Math.abs(oldBpPerPx - newBpPerPx) < 0.000001) {
|
|
187
|
+
return oldBpPerPx;
|
|
188
|
+
}
|
|
189
|
+
self.bpPerPx = newBpPerPx;
|
|
190
|
+
// tweak the offset so that the center of the view remains at the same
|
|
191
|
+
// coordinate
|
|
192
|
+
self.offsetPx = (0, index_1.clamp)(Math.round(((self.offsetPx + offset) * oldBpPerPx) / newBpPerPx - offset), self.minOffset, self.maxOffset);
|
|
192
193
|
return self.bpPerPx;
|
|
193
194
|
},
|
|
194
195
|
/**
|
package/util/aborting.js
CHANGED
|
@@ -75,6 +75,6 @@ function isAbortException(exception) {
|
|
|
75
75
|
// Error: aborted
|
|
76
76
|
// AbortError: aborted
|
|
77
77
|
// AbortError: The user aborted a request.
|
|
78
|
-
|
|
78
|
+
!!/\b(aborted|aborterror)\b/i.test(exception.message)));
|
|
79
79
|
}
|
|
80
80
|
exports.isAbortException = isAbortException;
|
package/util/analytics.js
CHANGED
|
@@ -83,7 +83,7 @@ async function writeGAAnalytics(rootModel, initialTimestamp) {
|
|
|
83
83
|
analyticsScript += `ga('jbrowseTracker.send', 'pageview',${JSON.stringify(gaData)});`;
|
|
84
84
|
const analyticsScriptNode = document.createElement('script');
|
|
85
85
|
analyticsScriptNode.innerHTML = analyticsScript;
|
|
86
|
-
document.getElementsByTagName('head')[0].
|
|
86
|
+
document.getElementsByTagName('head')[0].append(analyticsScriptNode);
|
|
87
87
|
}
|
|
88
88
|
exports.writeGAAnalytics = writeGAAnalytics;
|
|
89
89
|
function doAnalytics(rootModel, initialTimestamp, initialSessionQuery) {
|
package/util/blockTypes.js
CHANGED
|
@@ -6,13 +6,11 @@ class BlockSet {
|
|
|
6
6
|
this.blocks = blocks;
|
|
7
7
|
}
|
|
8
8
|
push(block) {
|
|
9
|
-
if (block instanceof ElidedBlock) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
9
|
+
if (block instanceof ElidedBlock && this.blocks.length > 0) {
|
|
10
|
+
const lastBlock = this.blocks[this.blocks.length - 1];
|
|
11
|
+
if (lastBlock instanceof ElidedBlock) {
|
|
12
|
+
lastBlock.push(block);
|
|
13
|
+
return;
|
|
16
14
|
}
|
|
17
15
|
}
|
|
18
16
|
this.blocks.push(block);
|
|
@@ -24,21 +22,23 @@ class BlockSet {
|
|
|
24
22
|
return this.blocks.map(block => block.toRegion());
|
|
25
23
|
}
|
|
26
24
|
map(func, thisarg) {
|
|
25
|
+
// eslint-disable-next-line unicorn/no-array-method-this-argument
|
|
27
26
|
return this.blocks.map(func, thisarg);
|
|
28
27
|
}
|
|
29
28
|
forEach(func, thisarg) {
|
|
29
|
+
// eslint-disable-next-line unicorn/no-array-method-this-argument
|
|
30
30
|
return this.blocks.forEach(func, thisarg);
|
|
31
31
|
}
|
|
32
32
|
get length() {
|
|
33
33
|
return this.blocks.length;
|
|
34
34
|
}
|
|
35
35
|
get totalWidthPx() {
|
|
36
|
-
return this.blocks.length
|
|
36
|
+
return this.blocks.length > 0
|
|
37
37
|
? this.blocks.map(blocks => blocks.widthPx).reduce((a, b) => a + b)
|
|
38
38
|
: 0;
|
|
39
39
|
}
|
|
40
40
|
get totalWidthPxWithoutBorders() {
|
|
41
|
-
return this.blocks.length
|
|
41
|
+
return this.blocks.length > 0
|
|
42
42
|
? this.blocks
|
|
43
43
|
.filter(block => block.variant !== 'boundary')
|
|
44
44
|
.map(blocks => blocks.widthPx)
|
|
@@ -46,7 +46,7 @@ class BlockSet {
|
|
|
46
46
|
: 0;
|
|
47
47
|
}
|
|
48
48
|
get offsetPx() {
|
|
49
|
-
return this.blocks.length ? this.blocks[0].offsetPx : 0;
|
|
49
|
+
return this.blocks.length > 0 ? this.blocks[0].offsetPx : 0;
|
|
50
50
|
}
|
|
51
51
|
get contentBlocks() {
|
|
52
52
|
return this.blocks.filter(block => block instanceof ContentBlock);
|
package/util/color/index.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { namedColorToHex, isNamedColor } from './cssColorsLevel4';
|
|
2
|
-
export { namedColorToHex, isNamedColor };
|
|
3
1
|
/**
|
|
4
2
|
* Algorithmically pick a contrasting text color that will
|
|
5
3
|
* be visible on top of the given background color. Either
|
|
@@ -22,3 +20,4 @@ export declare function contrastingTextColor(color: string): string;
|
|
|
22
20
|
*/
|
|
23
21
|
export declare function emphasize(color: string, coefficient?: number): string;
|
|
24
22
|
export declare function makeContrasting(foreground: string, background?: string, minContrastRatio?: number): string;
|
|
23
|
+
export { isNamedColor, namedColorToHex } from './cssColorsLevel4';
|
package/util/color/index.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.namedColorToHex = exports.isNamedColor = exports.makeContrasting = exports.emphasize = exports.contrastingTextColor = void 0;
|
|
4
4
|
const styles_1 = require("@mui/material/styles");
|
|
5
5
|
const cssColorsLevel4_1 = require("./cssColorsLevel4");
|
|
6
|
-
Object.defineProperty(exports, "namedColorToHex", { enumerable: true, get: function () { return cssColorsLevel4_1.namedColorToHex; } });
|
|
7
|
-
Object.defineProperty(exports, "isNamedColor", { enumerable: true, get: function () { return cssColorsLevel4_1.isNamedColor; } });
|
|
8
6
|
/**
|
|
9
7
|
* Algorithmically pick a contrasting text color that will
|
|
10
8
|
* be visible on top of the given background color. Either
|
|
@@ -67,3 +65,6 @@ function makeContrasting(foreground, background = 'white', minContrastRatio = 3)
|
|
|
67
65
|
return convertedForeground;
|
|
68
66
|
}
|
|
69
67
|
exports.makeContrasting = makeContrasting;
|
|
68
|
+
var cssColorsLevel4_2 = require("./cssColorsLevel4");
|
|
69
|
+
Object.defineProperty(exports, "isNamedColor", { enumerable: true, get: function () { return cssColorsLevel4_2.isNamedColor; } });
|
|
70
|
+
Object.defineProperty(exports, "namedColorToHex", { enumerable: true, get: function () { return cssColorsLevel4_2.namedColorToHex; } });
|
package/util/idMaker.js
CHANGED
|
@@ -7,17 +7,14 @@ const _1 = require("./");
|
|
|
7
7
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8
8
|
function idMaker(args, id = '') {
|
|
9
9
|
const keys = Object.keys(args);
|
|
10
|
-
for (
|
|
11
|
-
const key = keys[i];
|
|
10
|
+
for (const key of keys) {
|
|
12
11
|
if (id.length > 5000) {
|
|
13
12
|
break;
|
|
14
13
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
id += `${key}-${args[key]};`;
|
|
20
|
-
}
|
|
14
|
+
id +=
|
|
15
|
+
typeof args[key] === 'object' && args[key]
|
|
16
|
+
? idMaker(args[key], id)
|
|
17
|
+
: `${key}-${args[key]};`;
|
|
21
18
|
}
|
|
22
19
|
return (0, _1.hashCode)(id);
|
|
23
20
|
}
|
package/util/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
1
2
|
import PluginManager from '../PluginManager';
|
|
2
3
|
import { IAnyStateTreeNode, IStateTreeNode } from 'mobx-state-tree';
|
|
3
4
|
import { IReactionPublic, IReactionOptions } from 'mobx';
|
|
4
|
-
import
|
|
5
|
+
import { Feature } from './simpleFeature';
|
|
5
6
|
import { AssemblyManager, Region, TypeTestedByPredicate } from './types';
|
|
6
7
|
import { BaseBlock } from './blockTypes';
|
|
7
8
|
export * from './types';
|
|
@@ -9,19 +10,19 @@ export * from './aborting';
|
|
|
9
10
|
export * from './when';
|
|
10
11
|
export * from './range';
|
|
11
12
|
export * from './dedupe';
|
|
12
|
-
export { SimpleFeature, isFeature };
|
|
13
|
-
export type { Feature, SimpleFeatureSerialized };
|
|
14
13
|
export * from './offscreenCanvasPonyfill';
|
|
15
14
|
export * from './offscreenCanvasUtils';
|
|
16
15
|
export declare const inDevelopment: boolean;
|
|
17
16
|
export declare const inProduction: boolean;
|
|
18
17
|
export declare function useDebounce<T>(value: T, delay: number): T;
|
|
18
|
+
export declare function useWidthSetter(view: {
|
|
19
|
+
setWidth: (arg: number) => void;
|
|
20
|
+
}, padding: string): import("react").RefObject<HTMLDivElement>;
|
|
19
21
|
export declare function useDebouncedCallback<T>(callback: (...args: T[]) => void, wait?: number): (...args: T[]) => void;
|
|
20
22
|
/** find the first node in the hierarchy that matches the given predicate */
|
|
21
23
|
export declare function findParentThat(node: IAnyStateTreeNode, predicate: (thing: IAnyStateTreeNode) => boolean): IAnyStateTreeNode;
|
|
22
24
|
export declare function springAnimate(fromValue: number, toValue: number, setValue: (value: number) => void, onFinish?: () => void, precision?: number, tension?: number, friction?: number): (() => void)[];
|
|
23
|
-
|
|
24
|
-
export declare function findParentThatIs<PREDICATE extends (thing: IAnyStateTreeNode) => boolean>(node: IAnyStateTreeNode, predicate: PREDICATE): TypeTestedByPredicate<PREDICATE> & IAnyStateTreeNode;
|
|
25
|
+
export declare function findParentThatIs<T extends (a: IAnyStateTreeNode) => boolean>(node: IAnyStateTreeNode, predicate: T): TypeTestedByPredicate<T> & IAnyStateTreeNode;
|
|
25
26
|
/** get the current JBrowse session model, starting at any node in the state tree */
|
|
26
27
|
export declare function getSession(node: IAnyStateTreeNode): import("./types").AbstractSessionModel & IAnyStateTreeNode;
|
|
27
28
|
/** get the state model of the view in the state tree that contains the given node */
|
|
@@ -286,7 +287,7 @@ export declare const defaultCodonTable: {
|
|
|
286
287
|
export declare function generateCodonTable(table: any): {
|
|
287
288
|
[key: string]: string;
|
|
288
289
|
};
|
|
289
|
-
export declare function updateStatus<U>(msg: string, cb: (arg: string) => void, fn: () => U): Promise<U>;
|
|
290
|
+
export declare function updateStatus<U>(msg: string, cb: (arg: string) => void, fn: () => U | Promise<U>): Promise<U>;
|
|
290
291
|
export declare function hashCode(str: string): number;
|
|
291
292
|
export declare function objectHash(obj: Record<string, any>): string;
|
|
292
293
|
interface VirtualOffset {
|
|
@@ -324,8 +325,8 @@ export declare function getTickDisplayStr(totalBp: number, bpPerPx: number): str
|
|
|
324
325
|
export declare function getViewParams(model: IAnyStateTreeNode, exportSVG?: boolean): {
|
|
325
326
|
offsetPx: number;
|
|
326
327
|
offsetPx1: number;
|
|
327
|
-
start:
|
|
328
|
-
end:
|
|
328
|
+
start: number;
|
|
329
|
+
end: number;
|
|
329
330
|
};
|
|
330
331
|
export declare function getLayoutId({ sessionId, layoutId, }: {
|
|
331
332
|
sessionId: string;
|
|
@@ -337,7 +338,7 @@ export declare function getUriLink(value: {
|
|
|
337
338
|
baseUri?: string;
|
|
338
339
|
}): string;
|
|
339
340
|
export declare function getStr(obj: unknown): string;
|
|
340
|
-
export declare function measureGridWidth(elements:
|
|
341
|
+
export declare function measureGridWidth(elements: unknown[], args?: {
|
|
341
342
|
minWidth?: number;
|
|
342
343
|
fontSize?: number;
|
|
343
344
|
maxWidth?: number;
|
|
@@ -353,3 +354,4 @@ export declare function max(arr: number[], init?: number): number;
|
|
|
353
354
|
export declare function min(arr: number[], init?: number): number;
|
|
354
355
|
export declare function sum(arr: number[]): number;
|
|
355
356
|
export declare function avg(arr: number[]): number;
|
|
357
|
+
export { default as SimpleFeature, type Feature, type SimpleFeatureSerialized, isFeature, } from './simpleFeature';
|
package/util/index.js
CHANGED
|
@@ -10,18 +10,6 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
|
|
|
10
10
|
if (k2 === undefined) k2 = k;
|
|
11
11
|
o[k2] = m[k];
|
|
12
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
13
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
26
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
27
15
|
};
|
|
@@ -29,19 +17,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
29
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
30
18
|
};
|
|
31
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
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.
|
|
33
|
-
exports.avg = exports.sum = exports.min = exports.max = exports.localStorageSetItem = exports.localStorageGetItem = exports.getEnv = exports.measureGridWidth = exports.getStr = exports.getUriLink = exports.useLocalStorage = exports.getLayoutId = exports.getViewParams = exports.getTickDisplayStr = exports.toLocale = exports.getBpDisplayStr =
|
|
20
|
+
exports.supportedIndexingAdapters = 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.useWidthSetter = exports.useDebounce = exports.inProduction = exports.inDevelopment = void 0;
|
|
21
|
+
exports.isFeature = exports.SimpleFeature = exports.avg = exports.sum = exports.min = exports.max = exports.localStorageSetItem = exports.localStorageGetItem = exports.getEnv = exports.measureGridWidth = exports.getStr = exports.getUriLink = exports.useLocalStorage = exports.getLayoutId = exports.getViewParams = exports.getTickDisplayStr = exports.toLocale = exports.getBpDisplayStr = void 0;
|
|
34
22
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
35
23
|
const react_1 = require("react");
|
|
36
24
|
const is_object_1 = __importDefault(require("is-object"));
|
|
37
25
|
const mobx_state_tree_1 = require("mobx-state-tree");
|
|
38
26
|
const mobx_1 = require("mobx");
|
|
39
|
-
const simpleFeature_1 = __importStar(require("./simpleFeature"));
|
|
40
|
-
exports.SimpleFeature = simpleFeature_1.default;
|
|
41
|
-
Object.defineProperty(exports, "isFeature", { enumerable: true, get: function () { return simpleFeature_1.isFeature; } });
|
|
42
27
|
const types_1 = require("./types");
|
|
43
28
|
const aborting_1 = require("./aborting");
|
|
44
29
|
const types_2 = require("./types");
|
|
30
|
+
const useMeasure_1 = __importDefault(require("@jbrowse/core/util/useMeasure"));
|
|
45
31
|
__exportStar(require("./types"), exports);
|
|
46
32
|
__exportStar(require("./aborting"), exports);
|
|
47
33
|
__exportStar(require("./when"), exports);
|
|
@@ -66,6 +52,20 @@ function useDebounce(value, delay) {
|
|
|
66
52
|
return debouncedValue;
|
|
67
53
|
}
|
|
68
54
|
exports.useDebounce = useDebounce;
|
|
55
|
+
// used in ViewContainer files to get the width
|
|
56
|
+
function useWidthSetter(view, padding) {
|
|
57
|
+
const [ref, { width }] = (0, useMeasure_1.default)();
|
|
58
|
+
(0, react_1.useEffect)(() => {
|
|
59
|
+
if (width && (0, mobx_state_tree_1.isAlive)(view)) {
|
|
60
|
+
// sets after a requestAnimationFrame
|
|
61
|
+
// https://stackoverflow.com/a/58701523/2129219
|
|
62
|
+
// avoids ResizeObserver loop error being shown during development
|
|
63
|
+
requestAnimationFrame(() => view.setWidth(width - Number.parseInt(padding, 10) * 2));
|
|
64
|
+
}
|
|
65
|
+
}, [padding, view, width]);
|
|
66
|
+
return ref;
|
|
67
|
+
}
|
|
68
|
+
exports.useWidthSetter = useWidthSetter;
|
|
69
69
|
// https://stackoverflow.com/questions/56283920/
|
|
70
70
|
function useDebouncedCallback(callback, wait = 400) {
|
|
71
71
|
// track args & timeout handle between calls
|
|
@@ -159,7 +159,7 @@ function springAnimate(fromValue, toValue, setValue, onFinish = () => { }, preci
|
|
|
159
159
|
];
|
|
160
160
|
}
|
|
161
161
|
exports.springAnimate = springAnimate;
|
|
162
|
-
|
|
162
|
+
// find the first node in the hierarchy that matches the given 'is' typescript type guard predicate
|
|
163
163
|
function findParentThatIs(node, predicate) {
|
|
164
164
|
return findParentThat(node, predicate);
|
|
165
165
|
}
|
|
@@ -278,12 +278,12 @@ function parseLocStringOneBased(locString, isValidRefName) {
|
|
|
278
278
|
let reversed = false;
|
|
279
279
|
if (locString.endsWith('[rev]')) {
|
|
280
280
|
reversed = true;
|
|
281
|
-
locString = locString.replace(/\[rev
|
|
281
|
+
locString = locString.replace(/\[rev]$/, '');
|
|
282
282
|
}
|
|
283
283
|
// remove any whitespace
|
|
284
284
|
locString = locString.replace(/\s/, '');
|
|
285
285
|
// refNames can have colons, ref https://samtools.github.io/hts-specs/SAMv1.pdf Appendix A
|
|
286
|
-
const assemblyMatch = locString.match(/(
|
|
286
|
+
const assemblyMatch = locString.match(/({(.+)})?(.+)/);
|
|
287
287
|
if (!assemblyMatch) {
|
|
288
288
|
throw new Error(`invalid location string: "${locString}"`);
|
|
289
289
|
}
|
|
@@ -465,8 +465,8 @@ function bpToPx(bp, { reversed, end = 0, start = 0, }, bpPerPx) {
|
|
|
465
465
|
return roundToNearestPointOne((reversed ? end - bp : bp - start) / bpPerPx);
|
|
466
466
|
}
|
|
467
467
|
exports.bpToPx = bpToPx;
|
|
468
|
-
const oneEightyOverPi = 180
|
|
469
|
-
const piOverOneEighty = Math.PI / 180
|
|
468
|
+
const oneEightyOverPi = 180 / Math.PI;
|
|
469
|
+
const piOverOneEighty = Math.PI / 180;
|
|
470
470
|
function radToDeg(radians) {
|
|
471
471
|
return (radians * oneEightyOverPi) % 360;
|
|
472
472
|
}
|
|
@@ -505,7 +505,7 @@ function bpSpanPx(leftBp, rightBp, region, bpPerPx) {
|
|
|
505
505
|
exports.bpSpanPx = bpSpanPx;
|
|
506
506
|
// do an array map of an iterable
|
|
507
507
|
function iterMap(iter, func, sizeHint) {
|
|
508
|
-
const results = sizeHint
|
|
508
|
+
const results = Array.from({ length: sizeHint || 0 });
|
|
509
509
|
let counter = 0;
|
|
510
510
|
for (const item of iter) {
|
|
511
511
|
results[counter] = func(item);
|
|
@@ -552,7 +552,7 @@ exports.findLastIndex = findLastIndex;
|
|
|
552
552
|
* @param errorFunction -
|
|
553
553
|
*/
|
|
554
554
|
function makeAbortableReaction(self, dataFunction, asyncReactionFunction,
|
|
555
|
-
// @ts-
|
|
555
|
+
// @ts-expect-error
|
|
556
556
|
reactionOptions, startedFunction, successFunction, errorFunction) {
|
|
557
557
|
let inProgress;
|
|
558
558
|
function handleError(error) {
|
|
@@ -585,7 +585,7 @@ reactionOptions, startedFunction, successFunction, errorFunction) {
|
|
|
585
585
|
startedFunction(thisInProgress);
|
|
586
586
|
try {
|
|
587
587
|
const result = await asyncReactionFunction(data, thisInProgress.signal, self,
|
|
588
|
-
// @ts-
|
|
588
|
+
// @ts-expect-error
|
|
589
589
|
mobxReactionHandle);
|
|
590
590
|
(0, aborting_1.checkAbortSignal)(thisInProgress.signal);
|
|
591
591
|
if ((0, mobx_state_tree_1.isAlive)(self)) {
|
|
@@ -610,15 +610,12 @@ function renameRegionIfNeeded(refNameMap, region) {
|
|
|
610
610
|
if ((0, mobx_state_tree_1.isStateTreeNode)(region) && !(0, mobx_state_tree_1.isAlive)(region)) {
|
|
611
611
|
return region;
|
|
612
612
|
}
|
|
613
|
-
if (region && refNameMap
|
|
613
|
+
if (region && (refNameMap === null || refNameMap === void 0 ? void 0 : refNameMap[region.refName])) {
|
|
614
614
|
// clone the region so we don't modify it
|
|
615
|
-
|
|
616
|
-
// @ts-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
else {
|
|
620
|
-
region = { ...region };
|
|
621
|
-
}
|
|
615
|
+
region = (0, mobx_state_tree_1.isStateTreeNode)(region)
|
|
616
|
+
? // @ts-expect-error
|
|
617
|
+
{ ...(0, mobx_state_tree_1.getSnapshot)(region) }
|
|
618
|
+
: { ...region };
|
|
622
619
|
// modify it directly in the container
|
|
623
620
|
const newRef = refNameMap[region.refName];
|
|
624
621
|
if (newRef) {
|
|
@@ -634,7 +631,7 @@ async function renameRegionsIfNeeded(assemblyManager, args) {
|
|
|
634
631
|
throw new Error('sessionId is required');
|
|
635
632
|
}
|
|
636
633
|
const assemblyNames = regions.map(region => region.assemblyName);
|
|
637
|
-
const assemblyMaps = Object.fromEntries(await Promise.all(assemblyNames.map(async (assemblyName) => {
|
|
634
|
+
const assemblyMaps = Object.fromEntries(await Promise.all([...new Set(assemblyNames)].map(async (assemblyName) => {
|
|
638
635
|
return [
|
|
639
636
|
assemblyName,
|
|
640
637
|
await assemblyManager.getRefNameMapForAdapter(adapterConfig, assemblyName, args),
|
|
@@ -741,11 +738,9 @@ exports.blobToDataURL = blobToDataURL;
|
|
|
741
738
|
// otherwise listens for prerendered_canvas but reads empty pixels, and doesn't
|
|
742
739
|
// get the contents of the canvas
|
|
743
740
|
exports.rIC = typeof jest === 'undefined'
|
|
744
|
-
?
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
window.requestIdleCallback
|
|
748
|
-
: (cb) => setTimeout(() => cb(), 1)
|
|
741
|
+
? typeof window !== 'undefined' && window.requestIdleCallback
|
|
742
|
+
? window.requestIdleCallback
|
|
743
|
+
: (cb) => setTimeout(() => cb(), 1)
|
|
749
744
|
: (cb) => cb();
|
|
750
745
|
// prettier-ignore
|
|
751
746
|
const widths = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.2796875, 0.2765625, 0.3546875, 0.5546875, 0.5546875, 0.8890625, 0.665625, 0.190625, 0.3328125, 0.3328125, 0.3890625, 0.5828125, 0.2765625, 0.3328125, 0.2765625, 0.3015625, 0.5546875, 0.5546875, 0.5546875, 0.5546875, 0.5546875, 0.5546875, 0.5546875, 0.5546875, 0.5546875, 0.5546875, 0.2765625, 0.2765625, 0.584375, 0.5828125, 0.584375, 0.5546875, 1.0140625, 0.665625, 0.665625, 0.721875, 0.721875, 0.665625, 0.609375, 0.7765625, 0.721875, 0.2765625, 0.5, 0.665625, 0.5546875, 0.8328125, 0.721875, 0.7765625, 0.665625, 0.7765625, 0.721875, 0.665625, 0.609375, 0.721875, 0.665625, 0.94375, 0.665625, 0.665625, 0.609375, 0.2765625, 0.3546875, 0.2765625, 0.4765625, 0.5546875, 0.3328125, 0.5546875, 0.5546875, 0.5, 0.5546875, 0.5546875, 0.2765625, 0.5546875, 0.5546875, 0.221875, 0.240625, 0.5, 0.221875, 0.8328125, 0.5546875, 0.5546875, 0.5546875, 0.5546875, 0.3328125, 0.5, 0.2765625, 0.5546875, 0.5, 0.721875, 0.5, 0.5, 0.5, 0.3546875, 0.259375, 0.353125, 0.5890625];
|
|
@@ -910,10 +905,10 @@ exports.supportedIndexingAdapters = supportedIndexingAdapters;
|
|
|
910
905
|
function getBpDisplayStr(totalBp) {
|
|
911
906
|
let str;
|
|
912
907
|
if (Math.floor(totalBp / 1000000) > 0) {
|
|
913
|
-
str = `${parseFloat((totalBp / 1000000).toPrecision(3))}Mbp`;
|
|
908
|
+
str = `${Number.parseFloat((totalBp / 1000000).toPrecision(3))}Mbp`;
|
|
914
909
|
}
|
|
915
910
|
else if (Math.floor(totalBp / 1000) > 0) {
|
|
916
|
-
str = `${parseFloat((totalBp / 1000).toPrecision(3))}Kbp`;
|
|
911
|
+
str = `${Number.parseFloat((totalBp / 1000).toPrecision(3))}Kbp`;
|
|
917
912
|
}
|
|
918
913
|
else {
|
|
919
914
|
str = `${toLocale(Math.floor(totalBp))}bp`;
|
|
@@ -926,18 +921,12 @@ function toLocale(n) {
|
|
|
926
921
|
}
|
|
927
922
|
exports.toLocale = toLocale;
|
|
928
923
|
function getTickDisplayStr(totalBp, bpPerPx) {
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
}
|
|
933
|
-
else {
|
|
934
|
-
str = `${toLocale(Math.floor(totalBp))}`;
|
|
935
|
-
}
|
|
936
|
-
return str;
|
|
924
|
+
return Math.floor(bpPerPx / 1000) > 0
|
|
925
|
+
? `${toLocale(Number.parseFloat((totalBp / 1000000).toFixed(2)))}M`
|
|
926
|
+
: `${toLocale(Math.floor(totalBp))}`;
|
|
937
927
|
}
|
|
938
928
|
exports.getTickDisplayStr = getTickDisplayStr;
|
|
939
929
|
function getViewParams(model, exportSVG) {
|
|
940
|
-
// @ts-ignore
|
|
941
930
|
const { dynamicBlocks, staticBlocks, offsetPx } = getContainingView(model);
|
|
942
931
|
const b = (dynamicBlocks === null || dynamicBlocks === void 0 ? void 0 : dynamicBlocks.contentBlocks[0]) || {};
|
|
943
932
|
const staticblock = (staticBlocks === null || staticBlocks === void 0 ? void 0 : staticBlocks.contentBlocks[0]) || {};
|
|
@@ -1062,3 +1051,6 @@ function avg(arr) {
|
|
|
1062
1051
|
return sum(arr) / arr.length;
|
|
1063
1052
|
}
|
|
1064
1053
|
exports.avg = avg;
|
|
1054
|
+
var simpleFeature_1 = require("./simpleFeature");
|
|
1055
|
+
Object.defineProperty(exports, "SimpleFeature", { enumerable: true, get: function () { return __importDefault(simpleFeature_1).default; } });
|
|
1056
|
+
Object.defineProperty(exports, "isFeature", { enumerable: true, get: function () { return simpleFeature_1.isFeature; } });
|
|
@@ -50,8 +50,8 @@ class RemoteFileWithRangeCache extends generic_filehandle_1.RemoteFile {
|
|
|
50
50
|
const rangeParse = /bytes=(\d+)-(\d+)/.exec(range);
|
|
51
51
|
if (rangeParse) {
|
|
52
52
|
const [, start, end] = rangeParse;
|
|
53
|
-
const s = parseInt(start, 10);
|
|
54
|
-
const e = parseInt(end, 10);
|
|
53
|
+
const s = Number.parseInt(start, 10);
|
|
54
|
+
const e = Number.parseInt(end, 10);
|
|
55
55
|
const response = (await globalRangeCache.getRange(url, s, e - s + 1, {
|
|
56
56
|
signal: init && init.signal,
|
|
57
57
|
}));
|
package/util/io/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { GenericFilehandle, Fetcher } from 'generic-filehandle';
|
|
2
|
-
import {
|
|
3
|
-
import { FileLocation } from '../types';
|
|
2
|
+
import { FileLocation, UriLocation } from '../types';
|
|
4
3
|
import PluginManager from '../../PluginManager';
|
|
5
|
-
|
|
4
|
+
/** if a UriLocation has a baseUri, resolves its uri with respect to that base */
|
|
5
|
+
export declare function resolveUriLocation(location: UriLocation): UriLocation;
|
|
6
6
|
export declare function openLocation(location: FileLocation, pluginManager?: PluginManager): GenericFilehandle;
|
|
7
7
|
export declare function getFetcher(location: FileLocation, pluginManager?: PluginManager): Fetcher;
|
|
8
|
+
export { RemoteFileWithRangeCache } from './RemoteFileWithRangeCache';
|
package/util/io/index.js
CHANGED
|
@@ -3,12 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getFetcher = exports.openLocation = exports.
|
|
6
|
+
exports.RemoteFileWithRangeCache = exports.getFetcher = exports.openLocation = exports.resolveUriLocation = void 0;
|
|
7
7
|
const generic_filehandle_1 = require("generic-filehandle");
|
|
8
8
|
const detect_node_1 = __importDefault(require("detect-node"));
|
|
9
9
|
// locals
|
|
10
10
|
const RemoteFileWithRangeCache_1 = require("./RemoteFileWithRangeCache");
|
|
11
|
-
Object.defineProperty(exports, "RemoteFileWithRangeCache", { enumerable: true, get: function () { return RemoteFileWithRangeCache_1.RemoteFileWithRangeCache; } });
|
|
12
11
|
const types_1 = require("../types");
|
|
13
12
|
const tracks_1 = require("../tracks");
|
|
14
13
|
const __1 = require("../");
|
|
@@ -18,6 +17,13 @@ function isLocalPathLocation(location) {
|
|
|
18
17
|
function isBlobLocation(location) {
|
|
19
18
|
return 'blobId' in location;
|
|
20
19
|
}
|
|
20
|
+
/** if a UriLocation has a baseUri, resolves its uri with respect to that base */
|
|
21
|
+
function resolveUriLocation(location) {
|
|
22
|
+
return location.baseUri
|
|
23
|
+
? { ...location, uri: new URL(location.uri, location.baseUri).href }
|
|
24
|
+
: location;
|
|
25
|
+
}
|
|
26
|
+
exports.resolveUriLocation = resolveUriLocation;
|
|
21
27
|
function openLocation(location, pluginManager) {
|
|
22
28
|
if (!location) {
|
|
23
29
|
throw new Error('must provide a location to openLocation');
|
|
@@ -47,9 +53,7 @@ function openLocation(location, pluginManager) {
|
|
|
47
53
|
throw new Error('No URI provided');
|
|
48
54
|
}
|
|
49
55
|
// Resolve any relative URLs to absolute URLs
|
|
50
|
-
const absoluteLocation = location
|
|
51
|
-
? { ...location, uri: new URL(location.uri, location.baseUri).href }
|
|
52
|
-
: location;
|
|
56
|
+
const absoluteLocation = resolveUriLocation(location);
|
|
53
57
|
// If there is a plugin manager, we can try internet accounts
|
|
54
58
|
if (pluginManager) {
|
|
55
59
|
const internetAccount = getInternetAccount(location, pluginManager);
|
|
@@ -105,10 +109,11 @@ function getInternetAccount(location, pluginManager) {
|
|
|
105
109
|
async function checkAuthNeededFetch(url, opts) {
|
|
106
110
|
var _a;
|
|
107
111
|
const response = await fetch(url, opts);
|
|
108
|
-
if (response.status === 401
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
+
if (response.status === 401 &&
|
|
113
|
+
((_a = response.headers.get('WWW-Authenticate')) === null || _a === void 0 ? void 0 : _a.includes('Basic'))) {
|
|
114
|
+
throw new types_1.AuthNeededError('Accessing HTTPBasic resource without authentication', url.toString());
|
|
112
115
|
}
|
|
113
116
|
return response;
|
|
114
117
|
}
|
|
118
|
+
var RemoteFileWithRangeCache_2 = require("./RemoteFileWithRangeCache");
|
|
119
|
+
Object.defineProperty(exports, "RemoteFileWithRangeCache", { enumerable: true, get: function () { return RemoteFileWithRangeCache_2.RemoteFileWithRangeCache; } });
|
package/util/jexl.js
CHANGED
|
@@ -45,7 +45,9 @@ function default_1( /* config?: any*/) {
|
|
|
45
45
|
j.addFunction('replaceAll', (s, match, sub) => s.replaceAll(match, sub));
|
|
46
46
|
j.addFunction('slice', (s, start, end) => s.slice(start, end));
|
|
47
47
|
j.addFunction('startsWith', (s, search, pos) => s.startsWith(search, pos));
|
|
48
|
-
j.addFunction('substring', (s, start, end) =>
|
|
48
|
+
j.addFunction('substring', (s, start, end) =>
|
|
49
|
+
// eslint-disable-next-line unicorn/prefer-string-slice
|
|
50
|
+
s.substring(start, end));
|
|
49
51
|
j.addFunction('toLowerCase', (s) => s.toLowerCase());
|
|
50
52
|
j.addFunction('toUpperCase', (s) => s.toUpperCase());
|
|
51
53
|
j.addFunction('trim', (s) => s.trim());
|