@cornerstonejs/core 1.30.0 → 1.31.0
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/RenderingEngine/StackViewport.js +1 -0
- package/dist/cjs/RenderingEngine/StackViewport.js.map +1 -1
- package/dist/cjs/RenderingEngine/Viewport.js +1 -1
- package/dist/cjs/RenderingEngine/Viewport.js.map +1 -1
- package/dist/cjs/enums/RequestType.d.ts +2 -1
- package/dist/cjs/enums/RequestType.js +1 -0
- package/dist/cjs/enums/RequestType.js.map +1 -1
- package/dist/cjs/index.d.ts +2 -2
- package/dist/cjs/index.js +2 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/init.d.ts +2 -1
- package/dist/cjs/init.js +16 -1
- package/dist/cjs/init.js.map +1 -1
- package/dist/cjs/requestPool/requestPoolManager.d.ts +1 -2
- package/dist/cjs/requestPool/requestPoolManager.js +8 -10
- package/dist/cjs/requestPool/requestPoolManager.js.map +1 -1
- package/dist/cjs/webWorkerManager/webWorkerManager.d.ts +21 -0
- package/dist/cjs/webWorkerManager/webWorkerManager.js +167 -0
- package/dist/cjs/webWorkerManager/webWorkerManager.js.map +1 -0
- package/dist/esm/RenderingEngine/StackViewport.js +1 -0
- package/dist/esm/RenderingEngine/StackViewport.js.map +1 -1
- package/dist/esm/RenderingEngine/Viewport.js +1 -1
- package/dist/esm/RenderingEngine/Viewport.js.map +1 -1
- package/dist/esm/enums/RequestType.js +1 -0
- package/dist/esm/enums/RequestType.js.map +1 -1
- package/dist/esm/index.js +2 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/init.js +12 -1
- package/dist/esm/init.js.map +1 -1
- package/dist/esm/requestPool/requestPoolManager.js +8 -10
- package/dist/esm/requestPool/requestPoolManager.js.map +1 -1
- package/dist/esm/webWorkerManager/webWorkerManager.js +132 -0
- package/dist/esm/webWorkerManager/webWorkerManager.js.map +1 -0
- package/dist/types/RenderingEngine/StackViewport.d.ts.map +1 -1
- package/dist/types/enums/RequestType.d.ts +2 -1
- package/dist/types/enums/RequestType.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/init.d.ts +2 -1
- package/dist/types/init.d.ts.map +1 -1
- package/dist/types/requestPool/requestPoolManager.d.ts +1 -2
- package/dist/types/requestPool/requestPoolManager.d.ts.map +1 -1
- package/dist/types/webWorkerManager/webWorkerManager.d.ts +22 -0
- package/dist/types/webWorkerManager/webWorkerManager.d.ts.map +1 -0
- package/dist/umd/index.js +1 -2
- package/dist/umd/index.js.map +1 -1
- package/package.json +3 -2
- package/src/RenderingEngine/StackViewport.ts +1 -0
- package/src/RenderingEngine/Viewport.ts +1 -1
- package/src/enums/RequestType.ts +3 -1
- package/src/index.ts +2 -0
- package/src/init.ts +18 -0
- package/src/requestPool/requestPoolManager.ts +9 -13
- package/src/webWorkerManager/webWorkerManager.js +218 -0
- package/dist/umd/index.js.LICENSE.txt +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cornerstonejs/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.31.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "dist/types/index.d.ts",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@kitware/vtk.js": "27.3.1",
|
|
34
|
+
"comlink": "^4.4.1",
|
|
34
35
|
"detect-gpu": "^5.0.22",
|
|
35
36
|
"gl-matrix": "^3.4.3",
|
|
36
37
|
"lodash.clonedeep": "4.5.0"
|
|
@@ -46,5 +47,5 @@
|
|
|
46
47
|
"type": "individual",
|
|
47
48
|
"url": "https://ohif.org/donate"
|
|
48
49
|
},
|
|
49
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "280c27226cb94a0b422f28656e69dbc059f95323"
|
|
50
51
|
}
|
|
@@ -1113,7 +1113,7 @@ class Viewport implements IViewport {
|
|
|
1113
1113
|
}
|
|
1114
1114
|
|
|
1115
1115
|
if (viewUp) {
|
|
1116
|
-
viewUpHasChanged = isEqual(currentViewUp, prevViewUp);
|
|
1116
|
+
viewUpHasChanged = !isEqual(currentViewUp, prevViewUp);
|
|
1117
1117
|
}
|
|
1118
1118
|
|
|
1119
1119
|
// only modify the clipping planes if the camera is modified out of plane
|
package/src/enums/RequestType.ts
CHANGED
|
@@ -6,8 +6,10 @@ enum RequestType {
|
|
|
6
6
|
Interaction = 'interaction',
|
|
7
7
|
/** Second highest priority for loading*/
|
|
8
8
|
Thumbnail = 'thumbnail',
|
|
9
|
-
/**
|
|
9
|
+
/** Third highest priority for loading, usually used for image loading in the background*/
|
|
10
10
|
Prefetch = 'prefetch',
|
|
11
|
+
/** Lower priority, often used for background computations in the worker */
|
|
12
|
+
Compute = 'compute',
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
export default RequestType;
|
package/src/index.ts
CHANGED
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
resetUseSharedArrayBuffer,
|
|
41
41
|
getConfiguration,
|
|
42
42
|
setConfiguration,
|
|
43
|
+
getWebWorkerManager,
|
|
43
44
|
} from './init';
|
|
44
45
|
|
|
45
46
|
// Classes
|
|
@@ -85,6 +86,7 @@ export {
|
|
|
85
86
|
// configs
|
|
86
87
|
getConfiguration,
|
|
87
88
|
setConfiguration,
|
|
89
|
+
getWebWorkerManager,
|
|
88
90
|
// enums
|
|
89
91
|
Enums,
|
|
90
92
|
CONSTANTS,
|
package/src/init.ts
CHANGED
|
@@ -6,6 +6,8 @@ let useSharedArrayBuffer = true;
|
|
|
6
6
|
let sharedArrayBufferMode = SharedArrayBufferModes.TRUE;
|
|
7
7
|
import { deepMerge } from './utilities';
|
|
8
8
|
import { Cornerstone3DConfig } from './types';
|
|
9
|
+
import CentralizedWebWorkerManager from './webWorkerManager/webWorkerManager';
|
|
10
|
+
|
|
9
11
|
// TODO: move sharedArrayBuffer into config.
|
|
10
12
|
// TODO: change config into a class with methods to better control get/set
|
|
11
13
|
const defaultConfig: Cornerstone3DConfig = {
|
|
@@ -36,6 +38,8 @@ let config: Cornerstone3DConfig = {
|
|
|
36
38
|
// ...
|
|
37
39
|
};
|
|
38
40
|
|
|
41
|
+
let webWorkerManager = null;
|
|
42
|
+
|
|
39
43
|
function _getGLContext(): RenderingContext {
|
|
40
44
|
// Create canvas element. The canvas is not added to the
|
|
41
45
|
// document itself, so it is never displayed in the
|
|
@@ -133,6 +137,11 @@ async function init(configuration = config): Promise<boolean> {
|
|
|
133
137
|
setUseSharedArrayBuffer(sharedArrayBufferMode);
|
|
134
138
|
|
|
135
139
|
csRenderInitialized = true;
|
|
140
|
+
|
|
141
|
+
if (!webWorkerManager) {
|
|
142
|
+
webWorkerManager = new CentralizedWebWorkerManager();
|
|
143
|
+
}
|
|
144
|
+
|
|
136
145
|
return csRenderInitialized;
|
|
137
146
|
}
|
|
138
147
|
|
|
@@ -256,6 +265,14 @@ function _updateRenderingPipelinesForAllViewports(): void {
|
|
|
256
265
|
);
|
|
257
266
|
}
|
|
258
267
|
|
|
268
|
+
function getWebWorkerManager() {
|
|
269
|
+
if (!webWorkerManager) {
|
|
270
|
+
webWorkerManager = new CentralizedWebWorkerManager();
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return webWorkerManager;
|
|
274
|
+
}
|
|
275
|
+
|
|
259
276
|
export {
|
|
260
277
|
init,
|
|
261
278
|
getShouldUseCPURendering,
|
|
@@ -268,4 +285,5 @@ export {
|
|
|
268
285
|
resetUseSharedArrayBuffer,
|
|
269
286
|
getConfiguration,
|
|
270
287
|
setConfiguration,
|
|
288
|
+
getWebWorkerManager,
|
|
271
289
|
};
|
|
@@ -78,12 +78,14 @@ class RequestPoolManager {
|
|
|
78
78
|
interaction: 0,
|
|
79
79
|
thumbnail: 0,
|
|
80
80
|
prefetch: 0,
|
|
81
|
+
compute: 0,
|
|
81
82
|
};
|
|
82
83
|
/* maximum number of requests of each type. */
|
|
83
84
|
public maxNumRequests: {
|
|
84
85
|
interaction: number;
|
|
85
86
|
thumbnail: number;
|
|
86
87
|
prefetch: number;
|
|
88
|
+
compute: number;
|
|
87
89
|
};
|
|
88
90
|
/* A public property that is used to set the delay between requests. */
|
|
89
91
|
public grabDelay: number;
|
|
@@ -101,6 +103,7 @@ class RequestPoolManager {
|
|
|
101
103
|
interaction: { 0: [] },
|
|
102
104
|
thumbnail: { 0: [] },
|
|
103
105
|
prefetch: { 0: [] },
|
|
106
|
+
compute: { 0: [] },
|
|
104
107
|
};
|
|
105
108
|
|
|
106
109
|
this.grabDelay = 5;
|
|
@@ -110,12 +113,14 @@ class RequestPoolManager {
|
|
|
110
113
|
interaction: 0,
|
|
111
114
|
thumbnail: 0,
|
|
112
115
|
prefetch: 0,
|
|
116
|
+
compute: 0,
|
|
113
117
|
};
|
|
114
118
|
|
|
115
119
|
this.maxNumRequests = {
|
|
116
120
|
interaction: 6,
|
|
117
121
|
thumbnail: 6,
|
|
118
122
|
prefetch: 5,
|
|
123
|
+
compute: 15,
|
|
119
124
|
};
|
|
120
125
|
}
|
|
121
126
|
|
|
@@ -185,15 +190,7 @@ class RequestPoolManager {
|
|
|
185
190
|
// Adding the request to the correct priority group of the request type
|
|
186
191
|
this.requestPool[type][priority].push(requestDetails);
|
|
187
192
|
|
|
188
|
-
|
|
189
|
-
if (!this.awake) {
|
|
190
|
-
this.awake = true;
|
|
191
|
-
this.startGrabbing();
|
|
192
|
-
} else if (type === RequestType.Interaction) {
|
|
193
|
-
// Todo: this is a hack for interaction right now, we should separate
|
|
194
|
-
// the grabbing from the adding requests
|
|
195
|
-
this.startGrabbing();
|
|
196
|
-
}
|
|
193
|
+
this.startGrabbing();
|
|
197
194
|
}
|
|
198
195
|
|
|
199
196
|
/**
|
|
@@ -273,11 +270,13 @@ class RequestPoolManager {
|
|
|
273
270
|
const hasRemainingPrefetchRequests = this.sendRequests(
|
|
274
271
|
RequestType.Prefetch
|
|
275
272
|
);
|
|
273
|
+
const hasRemainingComputeRequests = this.sendRequests(RequestType.Compute);
|
|
276
274
|
|
|
277
275
|
if (
|
|
278
276
|
!hasRemainingInteractionRequests &&
|
|
279
277
|
!hasRemainingThumbnailRequests &&
|
|
280
|
-
!hasRemainingPrefetchRequests
|
|
278
|
+
!hasRemainingPrefetchRequests &&
|
|
279
|
+
!hasRemainingComputeRequests
|
|
281
280
|
) {
|
|
282
281
|
this.awake = false;
|
|
283
282
|
}
|
|
@@ -323,7 +322,4 @@ class RequestPoolManager {
|
|
|
323
322
|
}
|
|
324
323
|
}
|
|
325
324
|
|
|
326
|
-
const requestPoolManager = new RequestPoolManager();
|
|
327
|
-
|
|
328
325
|
export { RequestPoolManager };
|
|
329
|
-
export default requestPoolManager;
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import * as Comlink from 'comlink';
|
|
2
|
+
import { RequestType } from '../enums/';
|
|
3
|
+
import { RequestPoolManager } from '../requestPool/requestPoolManager';
|
|
4
|
+
|
|
5
|
+
class CentralizedWorkerManager {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.workerRegistry = {};
|
|
8
|
+
this.workerPoolManager = new RequestPoolManager('webworker');
|
|
9
|
+
this.checkIntervalForIdleWorkers = 1000;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
setCheckIntervalForIdleWorkers(value) {
|
|
13
|
+
this.checkIntervalForIdleWorkers = value;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Registers a new worker, it doesn't mean that the function will get executed.
|
|
18
|
+
*
|
|
19
|
+
* @param workerName - The name of the worker.
|
|
20
|
+
* @param workerFn - The function that creates a new instance of the worker.
|
|
21
|
+
* @param options - Optional parameters.
|
|
22
|
+
* @param options.maxWorkerInstances - The maximum number of instances of this worker that can be created.
|
|
23
|
+
* For instance if you create a worker with maxWorkerInstances = 2, then only 2 instances of this worker will be created
|
|
24
|
+
* and in case there are 10 tasks that need to be executed, each will get assigned 5 tasks.
|
|
25
|
+
* @param options.overwrite - Whether to overwrite the worker if it's already registered.
|
|
26
|
+
* @param options.autoTerminateOnIdle - Whether to automatically terminate idle workers.
|
|
27
|
+
*/
|
|
28
|
+
registerWorker(workerName, workerFn, options = {}) {
|
|
29
|
+
const {
|
|
30
|
+
maxWorkerInstances = 1,
|
|
31
|
+
overwrite = false,
|
|
32
|
+
autoTerminateOnIdle = false,
|
|
33
|
+
} = options;
|
|
34
|
+
|
|
35
|
+
if (this.workerRegistry[workerName] && !overwrite) {
|
|
36
|
+
console.warn(`Worker type '${workerName}' is already registered...`);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (overwrite && this.workerRegistry[workerName]?.idleCheckIntervalId) {
|
|
41
|
+
clearInterval(this.workerRegistry[workerName].idleCheckIntervalId);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const workerProperties = {
|
|
45
|
+
workerFn: null,
|
|
46
|
+
idleCheckIntervalId: null,
|
|
47
|
+
instances: [],
|
|
48
|
+
loadCounters: [],
|
|
49
|
+
lastActiveTime: [],
|
|
50
|
+
// used for termination
|
|
51
|
+
nativeWorkers: [],
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
if (
|
|
55
|
+
(autoTerminateOnIdle && !workerProperties.idleCheckIntervalId) ||
|
|
56
|
+
overwrite
|
|
57
|
+
) {
|
|
58
|
+
const idleCheckIntervalId = setInterval(() => {
|
|
59
|
+
this.terminateIdleWorkers(workerName, autoTerminateOnIdle);
|
|
60
|
+
}, this.checkIntervalForIdleWorkers);
|
|
61
|
+
|
|
62
|
+
workerProperties.idleCheckIntervalId = idleCheckIntervalId;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
workerProperties.loadCounters = Array(maxWorkerInstances).fill(0);
|
|
66
|
+
workerProperties.lastActiveTime = Array(maxWorkerInstances).fill(null);
|
|
67
|
+
|
|
68
|
+
for (let i = 0; i < maxWorkerInstances; i++) {
|
|
69
|
+
const worker = workerFn();
|
|
70
|
+
workerProperties.instances.push(Comlink.wrap(worker));
|
|
71
|
+
workerProperties.nativeWorkers.push(worker);
|
|
72
|
+
workerProperties.workerFn = workerFn;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
this.workerRegistry[workerName] = workerProperties;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
getNextWorkerAPI(workerName) {
|
|
79
|
+
const workerProperties = this.workerRegistry[workerName];
|
|
80
|
+
|
|
81
|
+
if (!workerProperties) {
|
|
82
|
+
console.error(`Worker type '${workerName}' is not registered.`);
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Find the worker with the minimum load.
|
|
87
|
+
const workerInstances = workerProperties.instances.filter(
|
|
88
|
+
(instance) => instance !== null
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
let minLoadIndex = 0;
|
|
92
|
+
let minLoadValue = workerProperties.loadCounters[0] || 0;
|
|
93
|
+
|
|
94
|
+
for (let i = 1; i < workerInstances.length; i++) {
|
|
95
|
+
const currentLoadValue = workerProperties.loadCounters[i] || 0;
|
|
96
|
+
if (currentLoadValue < minLoadValue) {
|
|
97
|
+
minLoadIndex = i;
|
|
98
|
+
minLoadValue = currentLoadValue;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Check and recreate the worker if it was terminated.
|
|
103
|
+
if (workerProperties.instances[minLoadIndex] === null) {
|
|
104
|
+
const worker = workerProperties.workerFn();
|
|
105
|
+
workerProperties.instances[minLoadIndex] = Comlink.wrap(worker);
|
|
106
|
+
workerProperties.nativeWorkers[minLoadIndex] = worker;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Update the load counter.
|
|
110
|
+
workerProperties.loadCounters[minLoadIndex] += 1;
|
|
111
|
+
|
|
112
|
+
// return the worker that has the minimum load.
|
|
113
|
+
return {
|
|
114
|
+
api: workerProperties.instances[minLoadIndex],
|
|
115
|
+
index: minLoadIndex,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Executes a task on a worker.
|
|
121
|
+
*
|
|
122
|
+
* @param workerName - The name of the worker to execute the task on.
|
|
123
|
+
* @param methodName - The name of the method to execute on the worker.
|
|
124
|
+
* @param args - The arguments to pass to the method. Default is an empty object.
|
|
125
|
+
* @param options - An object containing options for the request. Default is an empty object.
|
|
126
|
+
* @param options.requestType - The type of the request. Default is RequestType.Compute.
|
|
127
|
+
* @param options.priority - The priority of the request. Default is 0.
|
|
128
|
+
* @param options.options - Additional options for the request. Default is an empty object.
|
|
129
|
+
*
|
|
130
|
+
* @returns A promise that resolves with the result of the task.
|
|
131
|
+
*/
|
|
132
|
+
executeTask(
|
|
133
|
+
workerName,
|
|
134
|
+
methodName,
|
|
135
|
+
args = {},
|
|
136
|
+
{ requestType = RequestType.Compute, priority = 0, options = {} } = {}
|
|
137
|
+
) {
|
|
138
|
+
return new Promise((resolve, reject) => {
|
|
139
|
+
const requestFn = async () => {
|
|
140
|
+
const { api, index } = this.getNextWorkerAPI(workerName);
|
|
141
|
+
if (!api) {
|
|
142
|
+
const error = new Error(
|
|
143
|
+
`No available worker instance for '${workerName}'`
|
|
144
|
+
);
|
|
145
|
+
console.error(error);
|
|
146
|
+
reject(error);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
const results = await api[methodName](args);
|
|
152
|
+
|
|
153
|
+
const workerProperties = this.workerRegistry[workerName];
|
|
154
|
+
workerProperties.lastActiveTime[index] = Date.now();
|
|
155
|
+
|
|
156
|
+
resolve(results);
|
|
157
|
+
} catch (err) {
|
|
158
|
+
console.error(
|
|
159
|
+
`Error executing method '${methodName}' on worker '${workerName}':`,
|
|
160
|
+
err
|
|
161
|
+
);
|
|
162
|
+
reject(err);
|
|
163
|
+
} finally {
|
|
164
|
+
this.workerRegistry[workerName].loadCounters[index]--;
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
this.workerPoolManager.addRequest(
|
|
169
|
+
requestFn,
|
|
170
|
+
requestType,
|
|
171
|
+
options,
|
|
172
|
+
priority
|
|
173
|
+
);
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
terminateIdleWorkers(workerName, idleTimeThreshold) {
|
|
178
|
+
const workerProperties = this.workerRegistry[workerName];
|
|
179
|
+
|
|
180
|
+
const now = Date.now();
|
|
181
|
+
|
|
182
|
+
workerProperties.instances.forEach((workerInstance, index) => {
|
|
183
|
+
// If the worker has not yet executed any task, skip this iteration
|
|
184
|
+
if (workerProperties.lastActiveTime[index] == null) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const idleTime = now - workerProperties.lastActiveTime[index];
|
|
189
|
+
|
|
190
|
+
// If the worker has been idle for longer than the threshold and it exists
|
|
191
|
+
if (idleTime > idleTimeThreshold && workerInstance !== null) {
|
|
192
|
+
workerInstance[Comlink.releaseProxy]();
|
|
193
|
+
workerProperties.nativeWorkers[index].terminate();
|
|
194
|
+
|
|
195
|
+
workerProperties.instances[index] = null;
|
|
196
|
+
workerProperties.lastActiveTime[index] = null;
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
terminate(workerName) {
|
|
202
|
+
const workerProperties = this.workerRegistry[workerName];
|
|
203
|
+
if (!workerProperties) {
|
|
204
|
+
console.error(`Worker type '${workerName}' is not registered.`);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
workerProperties.instances.forEach((workerInstance) => {
|
|
209
|
+
workerInstance[Comlink.releaseProxy]();
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
workerProperties.nativeWorkers.forEach((worker) => {
|
|
213
|
+
worker.terminate();
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export default CentralizedWorkerManager;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
|