@uwrl/qc-utils 0.0.12 → 0.0.14
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/index.d.ts +2 -0
- package/dist/index.js +285 -252
- package/dist/index.umd.cjs +3 -1
- package/dist/types.d.ts +51 -0
- package/dist/utils/__tests__/ellapsedTime.spec.d.ts +1 -0
- package/dist/utils/__tests__/format.spec.d.ts +1 -0
- package/dist/utils/__tests__/notifications.spec.d.ts +1 -0
- package/dist/utils/__tests__/observationsUtils.spec.d.ts +1 -0
- package/dist/utils/ellapsedTime.d.ts +0 -0
- package/dist/utils/format.d.ts +0 -0
- package/dist/utils/notifications.d.ts +46 -0
- package/dist/utils/observationsUtils.d.ts +0 -0
- package/dist/utils/plotting/__tests__/delete-data.worker.spec.d.ts +1 -0
- package/dist/utils/plotting/__tests__/mock.d.ts +4 -0
- package/dist/utils/plotting/__tests__/observationRecord.spec.d.ts +1 -0
- package/dist/utils/plotting/add-data.worker.d.ts +0 -0
- package/dist/utils/plotting/delete-data.worker.d.ts +0 -0
- package/dist/utils/plotting/drift-correction.worker.d.ts +0 -0
- package/dist/utils/plotting/fill-gaps.worker.d.ts +0 -0
- package/dist/utils/plotting/interpolate.worker.d.ts +0 -0
- package/dist/utils/plotting/observationRecord.d.ts +170 -0
- package/dist/utils/plotting/shift-datetimes.worker.d.ts +0 -0
- package/package.json +7 -4
- package/dist/assets/delete-data.worker-Iw4O1ScI.js +0 -1
- package/dist/assets/fill-gaps.worker-BesEL5v2.js +0 -1
package/dist/index.d.ts
ADDED
package/dist/index.js
CHANGED
|
@@ -1,89 +1,122 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
)
|
|
1
|
+
var f = /* @__PURE__ */ ((r) => (r.ADD_POINTS = "ADD_POINTS", r.CHANGE_VALUES = "CHANGE_VALUES", r.DELETE_POINTS = "DELETE_POINTS", r.DRIFT_CORRECTION = "DRIFT_CORRECTION", r.INTERPOLATE = "INTERPOLATE", r.SHIFT_DATETIMES = "SHIFT_DATETIMES", r.FILL_GAPS = "FILL_GAPS", r))(f || {}), _ = /* @__PURE__ */ ((r) => (r.FIND_GAPS = "FIND_GAPS", r.PERSISTENCE = "PERSISTENCE", r.RATE_OF_CHANGE = "RATE_OF_CHANGE", r.VALUE_THRESHOLD = "VALUE_THRESHOLD", r))(_ || {});
|
|
2
|
+
const X = {
|
|
3
|
+
"Less than": (r, t) => r < t,
|
|
4
|
+
"Less than or equal to": (r, t) => r <= t,
|
|
5
|
+
"Greater than": (r, t) => r > t,
|
|
6
|
+
"Greater than or equal to": (r, t) => r >= t,
|
|
7
|
+
Equal: (r, t) => r == t,
|
|
8
|
+
"Start datetime": (r, t) => r == t,
|
|
9
|
+
"End datetime": (r, t) => r == t
|
|
10
|
+
};
|
|
11
|
+
var E = /* @__PURE__ */ ((r) => (r.ADD = "ADD", r.SUB = "SUB", r.MULT = "MULT", r.DIV = "DIV", r.ASSIGN = "ASSIGN", r))(E || {});
|
|
12
|
+
const x = {
|
|
13
|
+
"Less than": (r, t) => r < t,
|
|
14
|
+
"Less than or equal to": (r, t) => r <= t,
|
|
15
|
+
"Greater than": (r, t) => r > t,
|
|
16
|
+
"Greater than or equal to": (r, t) => r >= t,
|
|
17
|
+
Equal: (r, t) => r == t
|
|
18
|
+
}, I = `(function(){"use strict";self.onmessage=o=>{const{bufferX:s,bufferY:n,outputBufferX:u,outputBufferY:f,start:l,end:y,deleteSegment:a,startTarget:c}=o.data,A=new Float64Array(s),d=new Float32Array(n),g=new Float64Array(u),p=new Float32Array(f);let e=0,r=c;for(let t=l;t<=y;t++)e<a.length&&t===a[e]?e++:(g[r]=A[t],p[r]=d[t],r++);self.postMessage("Done")}})();
|
|
19
|
+
`, b = typeof self < "u" && self.Blob && new Blob([I], { type: "text/javascript;charset=utf-8" });
|
|
20
|
+
function U(r) {
|
|
21
|
+
let t;
|
|
22
|
+
try {
|
|
23
|
+
if (t = b && (self.URL || self.webkitURL).createObjectURL(b), !t) throw "";
|
|
24
|
+
const s = new Worker(t, {
|
|
25
|
+
name: r?.name
|
|
26
|
+
});
|
|
27
|
+
return s.addEventListener("error", () => {
|
|
28
|
+
(self.URL || self.webkitURL).revokeObjectURL(t);
|
|
29
|
+
}), s;
|
|
30
|
+
} catch {
|
|
31
|
+
return new Worker(
|
|
32
|
+
"data:text/javascript;charset=utf-8," + encodeURIComponent(I),
|
|
33
|
+
{
|
|
34
|
+
name: r?.name
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
} finally {
|
|
38
|
+
t && (self.URL || self.webkitURL).revokeObjectURL(t);
|
|
39
|
+
}
|
|
8
40
|
}
|
|
9
|
-
function
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
41
|
+
const F = `(function(){"use strict";self.onmessage=function(e){const{bufferX:f,bufferY:t,outputBufferX:u,outputBufferY:s}=e.data;self.postMessage("Done")}})();
|
|
42
|
+
`, R = typeof self < "u" && self.Blob && new Blob([F], { type: "text/javascript;charset=utf-8" });
|
|
43
|
+
function M(r) {
|
|
44
|
+
let t;
|
|
45
|
+
try {
|
|
46
|
+
if (t = R && (self.URL || self.webkitURL).createObjectURL(R), !t) throw "";
|
|
47
|
+
const s = new Worker(t, {
|
|
48
|
+
name: r?.name
|
|
49
|
+
});
|
|
50
|
+
return s.addEventListener("error", () => {
|
|
51
|
+
(self.URL || self.webkitURL).revokeObjectURL(t);
|
|
52
|
+
}), s;
|
|
53
|
+
} catch {
|
|
54
|
+
return new Worker(
|
|
55
|
+
"data:text/javascript;charset=utf-8," + encodeURIComponent(F),
|
|
56
|
+
{
|
|
57
|
+
name: r?.name
|
|
58
|
+
}
|
|
59
|
+
);
|
|
60
|
+
} finally {
|
|
61
|
+
t && (self.URL || self.webkitURL).revokeObjectURL(t);
|
|
62
|
+
}
|
|
16
63
|
}
|
|
17
|
-
const
|
|
18
|
-
let
|
|
19
|
-
for (;
|
|
20
|
-
const
|
|
21
|
-
|
|
64
|
+
const C = (r, t) => {
|
|
65
|
+
let s = 0, e = r.length;
|
|
66
|
+
for (; s < e; ) {
|
|
67
|
+
const n = s + e >> 1;
|
|
68
|
+
r[n] < t ? s = n + 1 : e = n;
|
|
22
69
|
}
|
|
23
|
-
return
|
|
24
|
-
},
|
|
25
|
-
let
|
|
26
|
-
for (;
|
|
27
|
-
const
|
|
28
|
-
|
|
70
|
+
return s;
|
|
71
|
+
}, B = (r, t) => {
|
|
72
|
+
let s = 0, e = r.length;
|
|
73
|
+
for (; s < e; ) {
|
|
74
|
+
const n = s + e >> 1;
|
|
75
|
+
r[n] > t ? e = n : s = n + 1;
|
|
29
76
|
}
|
|
30
|
-
return
|
|
31
|
-
},
|
|
32
|
-
const
|
|
33
|
-
console.log(` Done in ${(
|
|
34
|
-
const
|
|
35
|
-
return { response: e, duration:
|
|
36
|
-
},
|
|
37
|
-
s:
|
|
38
|
-
m:
|
|
39
|
-
h:
|
|
40
|
-
D
|
|
41
|
-
W:
|
|
42
|
-
M:
|
|
43
|
-
Y:
|
|
44
|
-
},
|
|
45
|
-
if (
|
|
46
|
-
const e = new Date(
|
|
77
|
+
return s - 1;
|
|
78
|
+
}, w = async (r, t) => {
|
|
79
|
+
const s = performance.now(), e = await r(), n = performance.now();
|
|
80
|
+
console.log(` Done in ${(n - s).toFixed(2)} ms`);
|
|
81
|
+
const a = +(n - s);
|
|
82
|
+
return { response: e, duration: a };
|
|
83
|
+
}, N = 1, Y = N * 60, S = Y * 60, D = S * 24, G = D * 7, O = S * 30, k = D * 365, A = {
|
|
84
|
+
s: N,
|
|
85
|
+
m: Y,
|
|
86
|
+
h: S,
|
|
87
|
+
D,
|
|
88
|
+
W: G,
|
|
89
|
+
M: O,
|
|
90
|
+
Y: k
|
|
91
|
+
}, H = (r, t, s) => {
|
|
92
|
+
if (s === "M") {
|
|
93
|
+
const e = new Date(r);
|
|
47
94
|
return e.setMonth(e.getMonth() + t), e.getTime();
|
|
48
|
-
} else if (
|
|
49
|
-
const e = new Date(
|
|
95
|
+
} else if (s === "Y") {
|
|
96
|
+
const e = new Date(r);
|
|
50
97
|
return e.setFullYear(e.getFullYear() + t), e.getTime();
|
|
51
98
|
} else
|
|
52
|
-
return
|
|
53
|
-
},
|
|
54
|
-
|
|
55
|
-
"Less than or equal to": (i, t) => i <= t,
|
|
56
|
-
"Greater than": (i, t) => i > t,
|
|
57
|
-
"Greater than or equal to": (i, t) => i >= t,
|
|
58
|
-
Equal: (i, t) => i == t,
|
|
59
|
-
"Start datetime": (i, t) => i == t,
|
|
60
|
-
"End datetime": (i, t) => i == t
|
|
61
|
-
}, P = {
|
|
62
|
-
"Less than": (i, t) => i < t,
|
|
63
|
-
"Less than or equal to": (i, t) => i <= t,
|
|
64
|
-
"Greater than": (i, t) => i > t,
|
|
65
|
-
"Greater than or equal to": (i, t) => i >= t,
|
|
66
|
-
Equal: (i, t) => i == t
|
|
67
|
-
}, g = 20 * 1e3, R = ["date", "value", "qualifier"];
|
|
68
|
-
class O {
|
|
99
|
+
return r + t * A[s] * 1e3;
|
|
100
|
+
}, L = 20 * 1e3, v = ["date", "value", "qualifier"];
|
|
101
|
+
class V {
|
|
69
102
|
/** The generated dataset to be used for plotting */
|
|
70
103
|
dataset = {
|
|
71
|
-
dimensions:
|
|
104
|
+
dimensions: v,
|
|
72
105
|
source: {
|
|
73
106
|
x: new Float64Array(
|
|
74
107
|
new SharedArrayBuffer(
|
|
75
|
-
|
|
108
|
+
L * Float64Array.BYTES_PER_ELEMENT,
|
|
76
109
|
{
|
|
77
|
-
maxByteLength:
|
|
110
|
+
maxByteLength: L * Float64Array.BYTES_PER_ELEMENT
|
|
78
111
|
// Max size the array can reach
|
|
79
112
|
}
|
|
80
113
|
)
|
|
81
114
|
),
|
|
82
115
|
y: new Float32Array(
|
|
83
116
|
new SharedArrayBuffer(
|
|
84
|
-
|
|
117
|
+
L * Float32Array.BYTES_PER_ELEMENT,
|
|
85
118
|
{
|
|
86
|
-
maxByteLength:
|
|
119
|
+
maxByteLength: L * Float32Array.BYTES_PER_ELEMENT
|
|
87
120
|
// Max size the array can reach
|
|
88
121
|
}
|
|
89
122
|
)
|
|
@@ -101,10 +134,10 @@ class O {
|
|
|
101
134
|
if (!t)
|
|
102
135
|
return;
|
|
103
136
|
this.isLoading = !0;
|
|
104
|
-
const
|
|
137
|
+
const s = await w(() => {
|
|
105
138
|
this._growBuffer(t.datetimes.length), this._resizeTo(t.datetimes.length), this.dataX.set(t.datetimes), this.dataY.set(t.dataValues);
|
|
106
139
|
});
|
|
107
|
-
this.loadingTime =
|
|
140
|
+
this.loadingTime = s.duration, this.history.length = 0, this.isLoading = !1;
|
|
108
141
|
}
|
|
109
142
|
get dataX() {
|
|
110
143
|
return this.dataset.source.x;
|
|
@@ -129,23 +162,23 @@ class O {
|
|
|
129
162
|
* @param newLength The total number of elements that the view will contain
|
|
130
163
|
*/
|
|
131
164
|
_growBuffer(t) {
|
|
132
|
-
const
|
|
165
|
+
const s = t * Float64Array.BYTES_PER_ELEMENT;
|
|
133
166
|
let e = this.dataX.buffer.byteLength;
|
|
134
|
-
for (;
|
|
135
|
-
e +=
|
|
167
|
+
for (; s > e; )
|
|
168
|
+
e += L * Float64Array.BYTES_PER_ELEMENT;
|
|
136
169
|
if (e * Float64Array.BYTES_PER_ELEMENT > this.dataX.buffer.maxByteLength) {
|
|
137
|
-
const
|
|
170
|
+
const n = new SharedArrayBuffer(
|
|
138
171
|
this.dataX.buffer.byteLength,
|
|
139
172
|
{
|
|
140
173
|
maxByteLength: e * Float64Array.BYTES_PER_ELEMENT
|
|
141
174
|
}
|
|
142
|
-
),
|
|
175
|
+
), a = new SharedArrayBuffer(
|
|
143
176
|
this.dataY.buffer.byteLength,
|
|
144
177
|
{
|
|
145
178
|
maxByteLength: e * Float32Array.BYTES_PER_ELEMENT
|
|
146
179
|
}
|
|
147
|
-
),
|
|
148
|
-
|
|
180
|
+
), o = new Float64Array(n), i = new Float32Array(a);
|
|
181
|
+
o.set(this.dataX), i.set(this.dataY), this.dataset.source.x = o, this.dataset.source.y = i;
|
|
149
182
|
}
|
|
150
183
|
this.dataX.buffer.byteLength < t * Float64Array.BYTES_PER_ELEMENT && (this.dataX.buffer.grow(t * Float64Array.BYTES_PER_ELEMENT), this.dataY.buffer.grow(t * Float32Array.BYTES_PER_ELEMENT));
|
|
151
184
|
}
|
|
@@ -160,16 +193,16 @@ class O {
|
|
|
160
193
|
* @returns
|
|
161
194
|
*/
|
|
162
195
|
async reloadHistory(t) {
|
|
163
|
-
const
|
|
164
|
-
await this.reload(), await this.dispatch(
|
|
196
|
+
const s = this.history.slice(0, t + 1);
|
|
197
|
+
await this.reload(), await this.dispatch(s.map((e) => [e.method, ...e.args || []]));
|
|
165
198
|
}
|
|
166
199
|
/**
|
|
167
200
|
* Remove a history item
|
|
168
201
|
* @param index
|
|
169
202
|
*/
|
|
170
203
|
async removeHistoryItem(t) {
|
|
171
|
-
const
|
|
172
|
-
|
|
204
|
+
const s = [...this.history];
|
|
205
|
+
s.splice(t, 1), await this.reload(), await this.dispatch(s.map((e) => [e.method, ...e.args || []]));
|
|
173
206
|
}
|
|
174
207
|
get beginTime() {
|
|
175
208
|
return this.dataset.source.x.length ? new Date(this.dataset.source.x[0]) : null;
|
|
@@ -178,88 +211,88 @@ class O {
|
|
|
178
211
|
return this.dataset.source.x.length ? new Date(this.dataset.source.x[this.dataset.source.x.length - 1]) : null;
|
|
179
212
|
}
|
|
180
213
|
/** Dispatch an operation and log its signature in hisotry */
|
|
181
|
-
async dispatch(t, ...
|
|
214
|
+
async dispatch(t, ...s) {
|
|
182
215
|
const e = {
|
|
183
|
-
ADD_POINTS: this._addDataPoints,
|
|
184
|
-
CHANGE_VALUES: this._changeValues,
|
|
185
|
-
DELETE_POINTS: this._deleteDataPoints,
|
|
186
|
-
DRIFT_CORRECTION: this._driftCorrection,
|
|
187
|
-
INTERPOLATE: this._interpolate,
|
|
188
|
-
SHIFT_DATETIMES: this._shift,
|
|
189
|
-
FILL_GAPS: this._fillGaps
|
|
190
|
-
},
|
|
191
|
-
ADD_POINTS: "mdi-plus",
|
|
192
|
-
CHANGE_VALUES: "mdi-pencil",
|
|
193
|
-
DELETE_POINTS: "mdi-trash-can",
|
|
194
|
-
DRIFT_CORRECTION: "mdi-chart-sankey",
|
|
195
|
-
INTERPOLATE: "mdi-transit-connection-horizontal",
|
|
196
|
-
SHIFT_DATETIMES: "mdi-calendar",
|
|
197
|
-
FILL_GAPS: "mdi-keyboard-space"
|
|
216
|
+
[f.ADD_POINTS]: this._addDataPoints,
|
|
217
|
+
[f.CHANGE_VALUES]: this._changeValues,
|
|
218
|
+
[f.DELETE_POINTS]: this._deleteDataPoints,
|
|
219
|
+
[f.DRIFT_CORRECTION]: this._driftCorrection,
|
|
220
|
+
[f.INTERPOLATE]: this._interpolate,
|
|
221
|
+
[f.SHIFT_DATETIMES]: this._shift,
|
|
222
|
+
[f.FILL_GAPS]: this._fillGaps
|
|
223
|
+
}, n = {
|
|
224
|
+
[f.ADD_POINTS]: "mdi-plus",
|
|
225
|
+
[f.CHANGE_VALUES]: "mdi-pencil",
|
|
226
|
+
[f.DELETE_POINTS]: "mdi-trash-can",
|
|
227
|
+
[f.DRIFT_CORRECTION]: "mdi-chart-sankey",
|
|
228
|
+
[f.INTERPOLATE]: "mdi-transit-connection-horizontal",
|
|
229
|
+
[f.SHIFT_DATETIMES]: "mdi-calendar",
|
|
230
|
+
[f.FILL_GAPS]: "mdi-keyboard-space"
|
|
198
231
|
};
|
|
199
|
-
let
|
|
232
|
+
let a = [];
|
|
200
233
|
try {
|
|
201
234
|
if (Array.isArray(t)) {
|
|
202
|
-
for (let
|
|
203
|
-
const
|
|
204
|
-
method:
|
|
235
|
+
for (let o = 0; o < t.length; o++) {
|
|
236
|
+
const i = t[o][0], h = t[o].slice(1, t[o].length), l = {
|
|
237
|
+
method: i,
|
|
205
238
|
args: h,
|
|
206
|
-
icon:
|
|
239
|
+
icon: n[i],
|
|
207
240
|
isLoading: !1
|
|
208
241
|
};
|
|
209
242
|
this.history.push(l);
|
|
210
243
|
}
|
|
211
|
-
for (let
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
const h = await
|
|
244
|
+
for (let o = this.history.length - t.length; o < this.history.length; o++) {
|
|
245
|
+
const i = this.history[o];
|
|
246
|
+
i.isLoading = !0;
|
|
247
|
+
const h = await w(async () => await e[i.method].apply(
|
|
215
248
|
this,
|
|
216
|
-
|
|
249
|
+
i.args
|
|
217
250
|
));
|
|
218
|
-
|
|
251
|
+
i.duration = h.duration, i.isLoading = !1, a.push(h.response);
|
|
219
252
|
}
|
|
220
253
|
} else {
|
|
221
|
-
const
|
|
254
|
+
const o = {
|
|
222
255
|
method: t,
|
|
223
|
-
args:
|
|
224
|
-
icon:
|
|
256
|
+
args: s,
|
|
257
|
+
icon: n[t],
|
|
225
258
|
isLoading: !0
|
|
226
259
|
};
|
|
227
|
-
this.history.push(
|
|
228
|
-
const
|
|
229
|
-
|
|
260
|
+
this.history.push(o);
|
|
261
|
+
const i = await w(async () => await e[t].apply(this, s));
|
|
262
|
+
a = i.response, o.duration = i.duration, o.isLoading = !1;
|
|
230
263
|
}
|
|
231
|
-
} catch (
|
|
264
|
+
} catch (o) {
|
|
232
265
|
console.log(
|
|
233
266
|
`Failed to execute operation: ${t} with arguments: `,
|
|
234
|
-
|
|
235
|
-
), console.log(
|
|
267
|
+
s
|
|
268
|
+
), console.log(o);
|
|
236
269
|
}
|
|
237
|
-
return
|
|
270
|
+
return a;
|
|
238
271
|
}
|
|
239
272
|
/** Filter operations do not transform the data and are not logged in history */
|
|
240
|
-
async dispatchFilter(t, ...
|
|
273
|
+
async dispatchFilter(t, ...s) {
|
|
241
274
|
const e = {
|
|
242
|
-
FIND_GAPS: this._findGaps,
|
|
243
|
-
VALUE_THRESHOLD: this._valueThreshold,
|
|
244
|
-
PERSISTENCE: this._persistence,
|
|
245
|
-
RATE_OF_CHANGE: this._rateOfChange
|
|
275
|
+
[_.FIND_GAPS]: this._findGaps,
|
|
276
|
+
[_.VALUE_THRESHOLD]: this._valueThreshold,
|
|
277
|
+
[_.PERSISTENCE]: this._persistence,
|
|
278
|
+
[_.RATE_OF_CHANGE]: this._rateOfChange
|
|
246
279
|
};
|
|
247
|
-
let
|
|
280
|
+
let n = [];
|
|
248
281
|
try {
|
|
249
282
|
if (Array.isArray(t))
|
|
250
|
-
for (let
|
|
251
|
-
const
|
|
252
|
-
|
|
283
|
+
for (let a = 0; a < t.length; a++) {
|
|
284
|
+
const o = t[a][0], i = t[a].slice(1, t[a].length), h = await e[o].apply(this, i);
|
|
285
|
+
n.push(h);
|
|
253
286
|
}
|
|
254
287
|
else
|
|
255
|
-
|
|
256
|
-
} catch (
|
|
288
|
+
n = await e[t].apply(this, s);
|
|
289
|
+
} catch (a) {
|
|
257
290
|
console.log(
|
|
258
291
|
`Failed to execute filter operation: ${t} with arguments: `,
|
|
259
|
-
|
|
260
|
-
), console.log(
|
|
292
|
+
s
|
|
293
|
+
), console.log(a);
|
|
261
294
|
}
|
|
262
|
-
return
|
|
295
|
+
return n;
|
|
263
296
|
}
|
|
264
297
|
/**
|
|
265
298
|
* @param index An array containing the list of index of values to perform the operations on.
|
|
@@ -267,45 +300,45 @@ class O {
|
|
|
267
300
|
* @param value The value to use in the operation
|
|
268
301
|
* @returns The modified DataFrame
|
|
269
302
|
*/
|
|
270
|
-
_changeValues(t,
|
|
271
|
-
const
|
|
272
|
-
switch (
|
|
273
|
-
case
|
|
274
|
-
return
|
|
275
|
-
case
|
|
303
|
+
_changeValues(t, s, e) {
|
|
304
|
+
const n = (a) => {
|
|
305
|
+
switch (s) {
|
|
306
|
+
case E.ADD:
|
|
307
|
+
return a + e;
|
|
308
|
+
case E.ASSIGN:
|
|
276
309
|
return e;
|
|
277
|
-
case
|
|
278
|
-
return
|
|
279
|
-
case
|
|
280
|
-
return
|
|
281
|
-
case
|
|
282
|
-
return
|
|
310
|
+
case E.DIV:
|
|
311
|
+
return a / e;
|
|
312
|
+
case E.MULT:
|
|
313
|
+
return a * e;
|
|
314
|
+
case E.SUB:
|
|
315
|
+
return a - e;
|
|
283
316
|
default:
|
|
284
|
-
return
|
|
317
|
+
return a;
|
|
285
318
|
}
|
|
286
319
|
};
|
|
287
|
-
t.forEach((
|
|
288
|
-
this.dataset.source.y[
|
|
320
|
+
t.forEach((a) => {
|
|
321
|
+
this.dataset.source.y[a] = n(this.dataset.source.y[a]);
|
|
289
322
|
});
|
|
290
323
|
}
|
|
291
324
|
_interpolate(t) {
|
|
292
325
|
this._getConsecutiveGroups(t).forEach((e) => {
|
|
293
|
-
const
|
|
294
|
-
let
|
|
326
|
+
const n = e[0], a = e[e.length - 1];
|
|
327
|
+
let o = Math.max(0, n - 1), i = Math.min(this.dataset.source.y.length - 1, a + 1);
|
|
295
328
|
const h = this.dataset.source.x, l = this.dataset.source.y;
|
|
296
|
-
for (let
|
|
297
|
-
this.dataset.source.y[e[
|
|
298
|
-
h[e[
|
|
299
|
-
h[n],
|
|
300
|
-
l[n],
|
|
329
|
+
for (let u = 0; u < e.length; u++)
|
|
330
|
+
this.dataset.source.y[e[u]] = this._interpolateLinear(
|
|
331
|
+
h[e[u]],
|
|
301
332
|
h[o],
|
|
302
|
-
l[o]
|
|
333
|
+
l[o],
|
|
334
|
+
h[i],
|
|
335
|
+
l[i]
|
|
303
336
|
);
|
|
304
337
|
});
|
|
305
338
|
}
|
|
306
339
|
/** Interpolate existing values in the data source */
|
|
307
|
-
_interpolateLinear(t,
|
|
308
|
-
return e + (t -
|
|
340
|
+
_interpolateLinear(t, s, e, n, a) {
|
|
341
|
+
return e + (t - s) * (a - e) / (n - s);
|
|
309
342
|
}
|
|
310
343
|
/**
|
|
311
344
|
* Shifts the selected indexes by specified amount of units. Elements are reinserted according to their datetime.
|
|
@@ -314,34 +347,34 @@ class O {
|
|
|
314
347
|
* @param unit {@link TimeUnit}
|
|
315
348
|
* @returns
|
|
316
349
|
*/
|
|
317
|
-
async _shift(t,
|
|
318
|
-
const
|
|
319
|
-
|
|
320
|
-
this.dataY[
|
|
350
|
+
async _shift(t, s, e) {
|
|
351
|
+
const n = t.map((a) => [
|
|
352
|
+
H(this.dataX[a], s, e),
|
|
353
|
+
this.dataY[a]
|
|
321
354
|
]);
|
|
322
|
-
await this._deleteDataPoints(t), await this._addDataPoints(
|
|
355
|
+
await this._deleteDataPoints(t), await this._addDataPoints(n);
|
|
323
356
|
}
|
|
324
|
-
async _fillGapsV2(t,
|
|
325
|
-
const
|
|
357
|
+
async _fillGapsV2(t, s, e, n) {
|
|
358
|
+
const a = navigator.hardwareConcurrency || 1, o = [], i = [], h = this.dataX.length, l = new SharedArrayBuffer(this.dataX.buffer.byteLength, {
|
|
326
359
|
maxByteLength: this.dataX.buffer.maxByteLength
|
|
327
|
-
}),
|
|
360
|
+
}), u = new SharedArrayBuffer(this.dataY.buffer.byteLength, {
|
|
328
361
|
maxByteLength: this.dataY.buffer.maxByteLength
|
|
329
362
|
});
|
|
330
|
-
for (let
|
|
331
|
-
|
|
363
|
+
for (let c = 0; c < a; c++)
|
|
364
|
+
i.push(
|
|
332
365
|
new Promise((d) => {
|
|
333
|
-
const
|
|
334
|
-
|
|
366
|
+
const y = new M();
|
|
367
|
+
o.push(y), y.postMessage({
|
|
335
368
|
bufferX: this.dataX.buffer,
|
|
336
369
|
bufferY: this.dataY.buffer,
|
|
337
370
|
outputBufferX: l,
|
|
338
|
-
outputBufferY:
|
|
339
|
-
}),
|
|
340
|
-
d(
|
|
371
|
+
outputBufferY: u
|
|
372
|
+
}), y.onmessage = (g) => {
|
|
373
|
+
d(g.data);
|
|
341
374
|
};
|
|
342
375
|
})
|
|
343
376
|
);
|
|
344
|
-
await Promise.all(
|
|
377
|
+
await Promise.all(i), o.forEach((c) => c.terminate()), this.dataset.source.x = new Float64Array(l), this.dataset.source.y = new Float32Array(u), this._resizeTo(h);
|
|
345
378
|
}
|
|
346
379
|
/**
|
|
347
380
|
* Find gaps and fill them with placeholder value
|
|
@@ -351,22 +384,22 @@ class O {
|
|
|
351
384
|
* @returns
|
|
352
385
|
*/
|
|
353
386
|
// TODO: this needs to be improved using web workers
|
|
354
|
-
_fillGaps(t,
|
|
355
|
-
const
|
|
356
|
-
for (let
|
|
357
|
-
const
|
|
358
|
-
let d = h +
|
|
387
|
+
_fillGaps(t, s, e, n) {
|
|
388
|
+
const a = this._findGaps(t[0], t[1], n);
|
|
389
|
+
for (let o = a.length - 1; o >= 0; o--) {
|
|
390
|
+
const i = a[o], h = this.dataX[i[0]], l = this.dataX[i[1]], u = [], c = s[0] * A[s[1]] * 1e3;
|
|
391
|
+
let d = h + c;
|
|
359
392
|
for (; d < l; ) {
|
|
360
|
-
const
|
|
393
|
+
const y = e ? this._interpolateLinear(
|
|
361
394
|
d,
|
|
362
|
-
this.dataX[
|
|
363
|
-
this.dataY[
|
|
364
|
-
this.dataX[
|
|
365
|
-
this.dataY[
|
|
395
|
+
this.dataX[i[0]],
|
|
396
|
+
this.dataY[i[0]],
|
|
397
|
+
this.dataX[i[1]],
|
|
398
|
+
this.dataY[i[1]]
|
|
366
399
|
) : -9999;
|
|
367
|
-
|
|
400
|
+
u.push([d, y]), d += c;
|
|
368
401
|
}
|
|
369
|
-
this._addDataPoints(
|
|
402
|
+
this._addDataPoints(u);
|
|
370
403
|
}
|
|
371
404
|
}
|
|
372
405
|
/**
|
|
@@ -379,40 +412,40 @@ class O {
|
|
|
379
412
|
*/
|
|
380
413
|
// TODO: implement similar multithread solutions for other operations
|
|
381
414
|
async _deleteDataPoints(t) {
|
|
382
|
-
const
|
|
383
|
-
for (let
|
|
384
|
-
const d =
|
|
385
|
-
|
|
415
|
+
const s = navigator.hardwareConcurrency || 1, e = Math.ceil(this.dataX.length / s), n = [], a = [];
|
|
416
|
+
for (let c = 0; c < s; c++) {
|
|
417
|
+
const d = c * e, y = Math.min((c + 1) * e - 1, this.dataX.length - 1), g = C(t, d), p = B(t, y), m = t.slice(g, p + 1);
|
|
418
|
+
a.push({ start: d, end: y, deleteSegment: m });
|
|
386
419
|
}
|
|
387
|
-
const
|
|
388
|
-
for (let
|
|
389
|
-
|
|
390
|
-
const
|
|
420
|
+
const o = new Array(s).fill(0);
|
|
421
|
+
for (let c = 1; c < s; c++)
|
|
422
|
+
o[c] = o[c - 1] + a[c - 1].deleteSegment.length;
|
|
423
|
+
const i = [], h = this.dataX.length - t.length, l = new SharedArrayBuffer(this.dataX.buffer.byteLength, {
|
|
391
424
|
maxByteLength: this.dataX.buffer.maxByteLength
|
|
392
|
-
}),
|
|
425
|
+
}), u = new SharedArrayBuffer(this.dataY.buffer.byteLength, {
|
|
393
426
|
maxByteLength: this.dataY.buffer.maxByteLength
|
|
394
427
|
});
|
|
395
|
-
for (let
|
|
396
|
-
const { start: d, end:
|
|
397
|
-
|
|
428
|
+
for (let c = 0; c < s; c++) {
|
|
429
|
+
const { start: d, end: y, deleteSegment: g } = a[c], p = d - o[c];
|
|
430
|
+
i.push(
|
|
398
431
|
new Promise((m) => {
|
|
399
|
-
const
|
|
400
|
-
|
|
432
|
+
const T = new U();
|
|
433
|
+
n.push(T), T.postMessage({
|
|
401
434
|
bufferX: this.dataX.buffer,
|
|
402
435
|
bufferY: this.dataY.buffer,
|
|
403
436
|
outputBufferX: l,
|
|
404
|
-
outputBufferY:
|
|
437
|
+
outputBufferY: u,
|
|
405
438
|
start: d,
|
|
406
|
-
end:
|
|
407
|
-
deleteSegment:
|
|
408
|
-
startTarget:
|
|
409
|
-
}),
|
|
410
|
-
m(
|
|
439
|
+
end: y,
|
|
440
|
+
deleteSegment: g,
|
|
441
|
+
startTarget: p
|
|
442
|
+
}), T.onmessage = (P) => {
|
|
443
|
+
m(P.data);
|
|
411
444
|
};
|
|
412
445
|
})
|
|
413
446
|
);
|
|
414
447
|
}
|
|
415
|
-
await Promise.all(
|
|
448
|
+
await Promise.all(i), n.forEach((c) => c.terminate()), this.dataset.source.x = new Float64Array(l), this.dataset.source.y = new Float32Array(u), this._resizeTo(h);
|
|
416
449
|
}
|
|
417
450
|
/**
|
|
418
451
|
*
|
|
@@ -420,10 +453,10 @@ class O {
|
|
|
420
453
|
* @param end The end index
|
|
421
454
|
* @param value The drift amount
|
|
422
455
|
*/
|
|
423
|
-
_driftCorrection(t,
|
|
424
|
-
const
|
|
425
|
-
for (let l = t; l <
|
|
426
|
-
this.dataset.source.y[l] =
|
|
456
|
+
_driftCorrection(t, s, e) {
|
|
457
|
+
const n = this.dataset.source.x, a = this.dataset.source.y, o = n[t], h = n[s] - o;
|
|
458
|
+
for (let l = t; l < s; l++)
|
|
459
|
+
this.dataset.source.y[l] = a[l] + e * ((n[l] - o) / h);
|
|
427
460
|
}
|
|
428
461
|
/** Traverses the index array and returns groups of consecutive values.
|
|
429
462
|
* i.e.: `[0, 1, 3, 4, 6] => [[0, 1], [3, 4], [6]]`
|
|
@@ -431,27 +464,27 @@ class O {
|
|
|
431
464
|
* @param index: the index array (sorted)
|
|
432
465
|
*/
|
|
433
466
|
_getConsecutiveGroups(t) {
|
|
434
|
-
const
|
|
435
|
-
return t.reduce((e,
|
|
436
|
-
const
|
|
437
|
-
return !
|
|
438
|
-
},
|
|
467
|
+
const s = [[]];
|
|
468
|
+
return t.reduce((e, n) => {
|
|
469
|
+
const a = e[e.length - 1];
|
|
470
|
+
return !a.length || n == a[a.length - 1] + 1 ? a.push(n) : e.push([n]), e;
|
|
471
|
+
}, s), s;
|
|
439
472
|
}
|
|
440
473
|
/**
|
|
441
474
|
* Adds data points. Their insert index is determined using `findFirstGreaterOrEqual` in the x-axis.
|
|
442
475
|
* @param dataPoints
|
|
443
476
|
*/
|
|
444
477
|
async _addDataPoints(t) {
|
|
445
|
-
const
|
|
446
|
-
this._growBuffer(
|
|
447
|
-
const e = t.map((
|
|
448
|
-
this._resizeTo(
|
|
449
|
-
let
|
|
450
|
-
for (let
|
|
451
|
-
const
|
|
452
|
-
for (let h =
|
|
453
|
-
this.dataX[h +
|
|
454
|
-
|
|
478
|
+
const s = this.dataX.length + t.length;
|
|
479
|
+
this._growBuffer(s), t.sort((a, o) => a[0] - o[0]);
|
|
480
|
+
const e = t.map((a) => B(this.dataX, a[0]) + 1);
|
|
481
|
+
this._resizeTo(s), e.push(this.dataX.length);
|
|
482
|
+
let n = t.length;
|
|
483
|
+
for (let a = e.length - 1; a > 0; a--) {
|
|
484
|
+
const o = e[a - 1], i = e[a] - 1;
|
|
485
|
+
for (let h = i; h >= o; h--)
|
|
486
|
+
this.dataX[h + n] = this.dataX[h], this.dataY[h + n] = this.dataY[h];
|
|
487
|
+
n--, this.dataX[o + n] = t[a - 1][0], this.dataY[o + n] = t[a - 1][1];
|
|
455
488
|
}
|
|
456
489
|
}
|
|
457
490
|
// =======================
|
|
@@ -463,13 +496,13 @@ class O {
|
|
|
463
496
|
* @returns
|
|
464
497
|
*/
|
|
465
498
|
_valueThreshold(t) {
|
|
466
|
-
const
|
|
467
|
-
return this.dataset.source.y.forEach((e,
|
|
468
|
-
Object.keys(t).some((
|
|
499
|
+
const s = [];
|
|
500
|
+
return this.dataset.source.y.forEach((e, n) => {
|
|
501
|
+
Object.keys(t).some((a) => X[a]?.(
|
|
469
502
|
e,
|
|
470
|
-
t[
|
|
471
|
-
)) &&
|
|
472
|
-
}),
|
|
503
|
+
t[a]
|
|
504
|
+
)) && s.push(n);
|
|
505
|
+
}), s;
|
|
473
506
|
}
|
|
474
507
|
/**
|
|
475
508
|
*
|
|
@@ -477,14 +510,14 @@ class O {
|
|
|
477
510
|
* @param value
|
|
478
511
|
* @returns
|
|
479
512
|
*/
|
|
480
|
-
_rateOfChange(t,
|
|
481
|
-
const e = [],
|
|
482
|
-
for (let
|
|
483
|
-
const
|
|
484
|
-
|
|
513
|
+
_rateOfChange(t, s) {
|
|
514
|
+
const e = [], n = this.dataset.source.y;
|
|
515
|
+
for (let a = 1; a < n.length; a++) {
|
|
516
|
+
const o = n[a - 1], h = (n[a] - o) / Math.abs(o);
|
|
517
|
+
x[t]?.(
|
|
485
518
|
h,
|
|
486
|
-
|
|
487
|
-
) && e.push(
|
|
519
|
+
s
|
|
520
|
+
) && e.push(a);
|
|
488
521
|
}
|
|
489
522
|
return e;
|
|
490
523
|
}
|
|
@@ -495,16 +528,16 @@ class O {
|
|
|
495
528
|
* @param range If specified, the gaps will be found only within the range
|
|
496
529
|
* @returns
|
|
497
530
|
*/
|
|
498
|
-
_findGaps(t,
|
|
499
|
-
const
|
|
500
|
-
let
|
|
501
|
-
e?.[0] && e?.[1] && (
|
|
502
|
-
let h =
|
|
503
|
-
for (let l =
|
|
504
|
-
const
|
|
505
|
-
|
|
531
|
+
_findGaps(t, s, e) {
|
|
532
|
+
const n = [], a = this.dataset.source.x;
|
|
533
|
+
let o = 0, i = a.length;
|
|
534
|
+
e?.[0] && e?.[1] && (o = e[0], i = e[1]);
|
|
535
|
+
let h = a[o];
|
|
536
|
+
for (let l = o + 1; l <= i; l++) {
|
|
537
|
+
const u = a[l];
|
|
538
|
+
u - h > t * A[s] * 1e3 && n.push([l - 1, l]), h = u;
|
|
506
539
|
}
|
|
507
|
-
return
|
|
540
|
+
return n;
|
|
508
541
|
}
|
|
509
542
|
/**
|
|
510
543
|
* Find points where the values are the same at least x times in a row
|
|
@@ -512,15 +545,15 @@ class O {
|
|
|
512
545
|
* @param range If specified, the points will be found only within the range
|
|
513
546
|
* @returns
|
|
514
547
|
*/
|
|
515
|
-
_persistence(t,
|
|
516
|
-
let e = [],
|
|
517
|
-
|
|
518
|
-
let
|
|
519
|
-
for (let l =
|
|
520
|
-
|
|
548
|
+
_persistence(t, s) {
|
|
549
|
+
let e = [], n = this.dataset.source.y, a = 0, o = n.length;
|
|
550
|
+
s?.[0] && s?.[1] && (a = s[0], o = s[1]);
|
|
551
|
+
let i = n[a], h = [];
|
|
552
|
+
for (let l = a + 1; l < o; l++)
|
|
553
|
+
n[l] != i || l === o ? (h.length >= t && (e = [...e, ...h]), h = []) : h.push(l);
|
|
521
554
|
return e;
|
|
522
555
|
}
|
|
523
556
|
}
|
|
524
557
|
export {
|
|
525
|
-
|
|
558
|
+
V as ObservationRecord
|
|
526
559
|
};
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1,3 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(E,c){typeof exports=="object"&&typeof module<"u"?c(exports):typeof define=="function"&&define.amd?define(["exports"],c):(E=typeof globalThis<"u"?globalThis:E||self,c(E["@uwrl/qc-utils"]={}))})(this,function(E){"use strict";var c=(r=>(r.ADD_POINTS="ADD_POINTS",r.CHANGE_VALUES="CHANGE_VALUES",r.DELETE_POINTS="DELETE_POINTS",r.DRIFT_CORRECTION="DRIFT_CORRECTION",r.INTERPOLATE="INTERPOLATE",r.SHIFT_DATETIMES="SHIFT_DATETIMES",r.FILL_GAPS="FILL_GAPS",r))(c||{}),p=(r=>(r.FIND_GAPS="FIND_GAPS",r.PERSISTENCE="PERSISTENCE",r.RATE_OF_CHANGE="RATE_OF_CHANGE",r.VALUE_THRESHOLD="VALUE_THRESHOLD",r))(p||{});const x={"Less than":(r,t)=>r<t,"Less than or equal to":(r,t)=>r<=t,"Greater than":(r,t)=>r>t,"Greater than or equal to":(r,t)=>r>=t,Equal:(r,t)=>r==t,"Start datetime":(r,t)=>r==t,"End datetime":(r,t)=>r==t};var g=(r=>(r.ADD="ADD",r.SUB="SUB",r.MULT="MULT",r.DIV="DIV",r.ASSIGN="ASSIGN",r))(g||{});const X={"Less than":(r,t)=>r<t,"Less than or equal to":(r,t)=>r<=t,"Greater than":(r,t)=>r>t,"Greater than or equal to":(r,t)=>r>=t,Equal:(r,t)=>r==t},R=`(function(){"use strict";self.onmessage=o=>{const{bufferX:s,bufferY:n,outputBufferX:u,outputBufferY:f,start:l,end:y,deleteSegment:a,startTarget:c}=o.data,A=new Float64Array(s),d=new Float32Array(n),g=new Float64Array(u),p=new Float32Array(f);let e=0,r=c;for(let t=l;t<=y;t++)e<a.length&&t===a[e]?e++:(g[r]=A[t],p[r]=d[t],r++);self.postMessage("Done")}})();
|
|
2
|
+
`,B=typeof self<"u"&&self.Blob&&new Blob([R],{type:"text/javascript;charset=utf-8"});function U(r){let t;try{if(t=B&&(self.URL||self.webkitURL).createObjectURL(B),!t)throw"";const s=new Worker(t,{name:r?.name});return s.addEventListener("error",()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),s}catch{return new Worker("data:text/javascript;charset=utf-8,"+encodeURIComponent(R),{name:r?.name})}finally{t&&(self.URL||self.webkitURL).revokeObjectURL(t)}}const I=`(function(){"use strict";self.onmessage=function(e){const{bufferX:f,bufferY:t,outputBufferX:u,outputBufferY:s}=e.data;self.postMessage("Done")}})();
|
|
3
|
+
`,F=typeof self<"u"&&self.Blob&&new Blob([I],{type:"text/javascript;charset=utf-8"});function M(r){let t;try{if(t=F&&(self.URL||self.webkitURL).createObjectURL(F),!t)throw"";const s=new Worker(t,{name:r?.name});return s.addEventListener("error",()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),s}catch{return new Worker("data:text/javascript;charset=utf-8,"+encodeURIComponent(I),{name:r?.name})}finally{t&&(self.URL||self.webkitURL).revokeObjectURL(t)}}const C=(r,t)=>{let s=0,e=r.length;for(;s<e;){const n=s+e>>1;r[n]<t?s=n+1:e=n}return s},N=(r,t)=>{let s=0,e=r.length;for(;s<e;){const n=s+e>>1;r[n]>t?e=n:s=n+1}return s-1},_=async(r,t)=>{const s=performance.now(),e=await r(),n=performance.now();console.log(` Done in ${(n-s).toFixed(2)} ms`);const a=+(n-s);return{response:e,duration:a}},Y=1,P=Y*60,T=P*60,w=T*24,O=w*7,G=T*30,k=w*365,A={s:Y,m:P,h:T,D:w,W:O,M:G,Y:k},v=(r,t,s)=>{if(s==="M"){const e=new Date(r);return e.setMonth(e.getMonth()+t),e.getTime()}else if(s==="Y"){const e=new Date(r);return e.setFullYear(e.getFullYear()+t),e.getTime()}else return r+t*A[s]*1e3},L=20*1e3,H=["date","value","qualifier"];class j{dataset={dimensions:H,source:{x:new Float64Array(new SharedArrayBuffer(L*Float64Array.BYTES_PER_ELEMENT,{maxByteLength:L*Float64Array.BYTES_PER_ELEMENT})),y:new Float32Array(new SharedArrayBuffer(L*Float32Array.BYTES_PER_ELEMENT,{maxByteLength:L*Float32Array.BYTES_PER_ELEMENT}))}};history=[];loadingTime=null;isLoading=!0;rawData;constructor(t){this.history=[],this.rawData=t,this.loadData(this.rawData)}async loadData(t){if(!t)return;this.isLoading=!0;const s=await _(()=>{this._growBuffer(t.datetimes.length),this._resizeTo(t.datetimes.length),this.dataX.set(t.datetimes),this.dataY.set(t.dataValues)});this.loadingTime=s.duration,this.history.length=0,this.isLoading=!1}get dataX(){return this.dataset.source.x}get dataY(){return this.dataset.source.y}_resizeTo(t){this.dataset.source.x=new Float64Array(this.dataset.source.x.buffer).subarray(0,t),this.dataset.source.y=new Float32Array(this.dataset.source.y.buffer).subarray(0,t)}_growBuffer(t){const s=t*Float64Array.BYTES_PER_ELEMENT;let e=this.dataX.buffer.byteLength;for(;s>e;)e+=L*Float64Array.BYTES_PER_ELEMENT;if(e*Float64Array.BYTES_PER_ELEMENT>this.dataX.buffer.maxByteLength){const n=new SharedArrayBuffer(this.dataX.buffer.byteLength,{maxByteLength:e*Float64Array.BYTES_PER_ELEMENT}),a=new SharedArrayBuffer(this.dataY.buffer.byteLength,{maxByteLength:e*Float32Array.BYTES_PER_ELEMENT}),o=new Float64Array(n),i=new Float32Array(a);o.set(this.dataX),i.set(this.dataY),this.dataset.source.x=o,this.dataset.source.y=i}this.dataX.buffer.byteLength<t*Float64Array.BYTES_PER_ELEMENT&&(this.dataX.buffer.grow(t*Float64Array.BYTES_PER_ELEMENT),this.dataY.buffer.grow(t*Float32Array.BYTES_PER_ELEMENT))}async reload(){this.loadingTime=null,this.isLoading=!0,this.history.length=0,await this.loadData(this.rawData)}async reloadHistory(t){const s=this.history.slice(0,t+1);await this.reload(),await this.dispatch(s.map(e=>[e.method,...e.args||[]]))}async removeHistoryItem(t){const s=[...this.history];s.splice(t,1),await this.reload(),await this.dispatch(s.map(e=>[e.method,...e.args||[]]))}get beginTime(){return this.dataset.source.x.length?new Date(this.dataset.source.x[0]):null}get endTime(){return this.dataset.source.x.length?new Date(this.dataset.source.x[this.dataset.source.x.length-1]):null}async dispatch(t,...s){const e={[c.ADD_POINTS]:this._addDataPoints,[c.CHANGE_VALUES]:this._changeValues,[c.DELETE_POINTS]:this._deleteDataPoints,[c.DRIFT_CORRECTION]:this._driftCorrection,[c.INTERPOLATE]:this._interpolate,[c.SHIFT_DATETIMES]:this._shift,[c.FILL_GAPS]:this._fillGaps},n={[c.ADD_POINTS]:"mdi-plus",[c.CHANGE_VALUES]:"mdi-pencil",[c.DELETE_POINTS]:"mdi-trash-can",[c.DRIFT_CORRECTION]:"mdi-chart-sankey",[c.INTERPOLATE]:"mdi-transit-connection-horizontal",[c.SHIFT_DATETIMES]:"mdi-calendar",[c.FILL_GAPS]:"mdi-keyboard-space"};let a=[];try{if(Array.isArray(t)){for(let o=0;o<t.length;o++){const i=t[o][0],h=t[o].slice(1,t[o].length),l={method:i,args:h,icon:n[i],isLoading:!1};this.history.push(l)}for(let o=this.history.length-t.length;o<this.history.length;o++){const i=this.history[o];i.isLoading=!0;const h=await _(async()=>await e[i.method].apply(this,i.args));i.duration=h.duration,i.isLoading=!1,a.push(h.response)}}else{const o={method:t,args:s,icon:n[t],isLoading:!0};this.history.push(o);const i=await _(async()=>await e[t].apply(this,s));a=i.response,o.duration=i.duration,o.isLoading=!1}}catch(o){console.log(`Failed to execute operation: ${t} with arguments: `,s),console.log(o)}return a}async dispatchFilter(t,...s){const e={[p.FIND_GAPS]:this._findGaps,[p.VALUE_THRESHOLD]:this._valueThreshold,[p.PERSISTENCE]:this._persistence,[p.RATE_OF_CHANGE]:this._rateOfChange};let n=[];try{if(Array.isArray(t))for(let a=0;a<t.length;a++){const o=t[a][0],i=t[a].slice(1,t[a].length),h=await e[o].apply(this,i);n.push(h)}else n=await e[t].apply(this,s)}catch(a){console.log(`Failed to execute filter operation: ${t} with arguments: `,s),console.log(a)}return n}_changeValues(t,s,e){const n=a=>{switch(s){case g.ADD:return a+e;case g.ASSIGN:return e;case g.DIV:return a/e;case g.MULT:return a*e;case g.SUB:return a-e;default:return a}};t.forEach(a=>{this.dataset.source.y[a]=n(this.dataset.source.y[a])})}_interpolate(t){this._getConsecutiveGroups(t).forEach(e=>{const n=e[0],a=e[e.length-1];let o=Math.max(0,n-1),i=Math.min(this.dataset.source.y.length-1,a+1);const h=this.dataset.source.x,l=this.dataset.source.y;for(let f=0;f<e.length;f++)this.dataset.source.y[e[f]]=this._interpolateLinear(h[e[f]],h[o],l[o],h[i],l[i])})}_interpolateLinear(t,s,e,n,a){return e+(t-s)*(a-e)/(n-s)}async _shift(t,s,e){const n=t.map(a=>[v(this.dataX[a],s,e),this.dataY[a]]);await this._deleteDataPoints(t),await this._addDataPoints(n)}async _fillGapsV2(t,s,e,n){const a=navigator.hardwareConcurrency||1,o=[],i=[],h=this.dataX.length,l=new SharedArrayBuffer(this.dataX.buffer.byteLength,{maxByteLength:this.dataX.buffer.maxByteLength}),f=new SharedArrayBuffer(this.dataY.buffer.byteLength,{maxByteLength:this.dataY.buffer.maxByteLength});for(let u=0;u<a;u++)i.push(new Promise(d=>{const y=new M;o.push(y),y.postMessage({bufferX:this.dataX.buffer,bufferY:this.dataY.buffer,outputBufferX:l,outputBufferY:f}),y.onmessage=m=>{d(m.data)}}));await Promise.all(i),o.forEach(u=>u.terminate()),this.dataset.source.x=new Float64Array(l),this.dataset.source.y=new Float32Array(f),this._resizeTo(h)}_fillGaps(t,s,e,n){const a=this._findGaps(t[0],t[1],n);for(let o=a.length-1;o>=0;o--){const i=a[o],h=this.dataX[i[0]],l=this.dataX[i[1]],f=[],u=s[0]*A[s[1]]*1e3;let d=h+u;for(;d<l;){const y=e?this._interpolateLinear(d,this.dataX[i[0]],this.dataY[i[0]],this.dataX[i[1]],this.dataY[i[1]]):-9999;f.push([d,y]),d+=u}this._addDataPoints(f)}}async _deleteDataPoints(t){const s=navigator.hardwareConcurrency||1,e=Math.ceil(this.dataX.length/s),n=[],a=[];for(let u=0;u<s;u++){const d=u*e,y=Math.min((u+1)*e-1,this.dataX.length-1),m=C(t,d),S=N(t,y),D=t.slice(m,S+1);a.push({start:d,end:y,deleteSegment:D})}const o=new Array(s).fill(0);for(let u=1;u<s;u++)o[u]=o[u-1]+a[u-1].deleteSegment.length;const i=[],h=this.dataX.length-t.length,l=new SharedArrayBuffer(this.dataX.buffer.byteLength,{maxByteLength:this.dataX.buffer.maxByteLength}),f=new SharedArrayBuffer(this.dataY.buffer.byteLength,{maxByteLength:this.dataY.buffer.maxByteLength});for(let u=0;u<s;u++){const{start:d,end:y,deleteSegment:m}=a[u],S=d-o[u];i.push(new Promise(D=>{const b=new U;n.push(b),b.postMessage({bufferX:this.dataX.buffer,bufferY:this.dataY.buffer,outputBufferX:l,outputBufferY:f,start:d,end:y,deleteSegment:m,startTarget:S}),b.onmessage=V=>{D(V.data)}}))}await Promise.all(i),n.forEach(u=>u.terminate()),this.dataset.source.x=new Float64Array(l),this.dataset.source.y=new Float32Array(f),this._resizeTo(h)}_driftCorrection(t,s,e){const n=this.dataset.source.x,a=this.dataset.source.y,o=n[t],h=n[s]-o;for(let l=t;l<s;l++)this.dataset.source.y[l]=a[l]+e*((n[l]-o)/h)}_getConsecutiveGroups(t){const s=[[]];return t.reduce((e,n)=>{const a=e[e.length-1];return!a.length||n==a[a.length-1]+1?a.push(n):e.push([n]),e},s),s}async _addDataPoints(t){const s=this.dataX.length+t.length;this._growBuffer(s),t.sort((a,o)=>a[0]-o[0]);const e=t.map(a=>N(this.dataX,a[0])+1);this._resizeTo(s),e.push(this.dataX.length);let n=t.length;for(let a=e.length-1;a>0;a--){const o=e[a-1],i=e[a]-1;for(let h=i;h>=o;h--)this.dataX[h+n]=this.dataX[h],this.dataY[h+n]=this.dataY[h];n--,this.dataX[o+n]=t[a-1][0],this.dataY[o+n]=t[a-1][1]}}_valueThreshold(t){const s=[];return this.dataset.source.y.forEach((e,n)=>{Object.keys(t).some(a=>x[a]?.(e,t[a]))&&s.push(n)}),s}_rateOfChange(t,s){const e=[],n=this.dataset.source.y;for(let a=1;a<n.length;a++){const o=n[a-1],h=(n[a]-o)/Math.abs(o);X[t]?.(h,s)&&e.push(a)}return e}_findGaps(t,s,e){const n=[],a=this.dataset.source.x;let o=0,i=a.length;e?.[0]&&e?.[1]&&(o=e[0],i=e[1]);let h=a[o];for(let l=o+1;l<=i;l++){const f=a[l];f-h>t*A[s]*1e3&&n.push([l-1,l]),h=f}return n}_persistence(t,s){let e=[],n=this.dataset.source.y,a=0,o=n.length;s?.[0]&&s?.[1]&&(a=s[0],o=s[1]);let i=n[a],h=[];for(let l=a+1;l<o;l++)n[l]!=i||l===o?(h.length>=t&&(e=[...e,...h]),h=[]):h.push(l);return e}}E.ObservationRecord=j,Object.defineProperty(E,Symbol.toStringTag,{value:"Module"})});
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export declare enum EnumEditOperations {
|
|
2
|
+
ADD_POINTS = "ADD_POINTS",
|
|
3
|
+
CHANGE_VALUES = "CHANGE_VALUES",
|
|
4
|
+
DELETE_POINTS = "DELETE_POINTS",
|
|
5
|
+
DRIFT_CORRECTION = "DRIFT_CORRECTION",
|
|
6
|
+
INTERPOLATE = "INTERPOLATE",
|
|
7
|
+
SHIFT_DATETIMES = "SHIFT_DATETIMES",
|
|
8
|
+
FILL_GAPS = "FILL_GAPS"
|
|
9
|
+
}
|
|
10
|
+
export declare enum EnumFilterOperations {
|
|
11
|
+
FIND_GAPS = "FIND_GAPS",
|
|
12
|
+
PERSISTENCE = "PERSISTENCE",
|
|
13
|
+
RATE_OF_CHANGE = "RATE_OF_CHANGE",
|
|
14
|
+
VALUE_THRESHOLD = "VALUE_THRESHOLD"
|
|
15
|
+
}
|
|
16
|
+
export type HistoryItem = {
|
|
17
|
+
method: EnumEditOperations;
|
|
18
|
+
icon: string;
|
|
19
|
+
isLoading: boolean;
|
|
20
|
+
args?: any[];
|
|
21
|
+
duration?: number;
|
|
22
|
+
status?: 'success' | 'failed';
|
|
23
|
+
};
|
|
24
|
+
export type EnumDictionary<T extends string | symbol | number, U> = {
|
|
25
|
+
[K in T]: U;
|
|
26
|
+
};
|
|
27
|
+
export declare enum FilterOperation {
|
|
28
|
+
LT = "Less than",
|
|
29
|
+
LTE = "Less than or equal to",
|
|
30
|
+
GT = "Greater than",
|
|
31
|
+
GTE = "Greater than or equal to",
|
|
32
|
+
E = "Equal",
|
|
33
|
+
START = "Start datetime",
|
|
34
|
+
END = "End datetime"
|
|
35
|
+
}
|
|
36
|
+
export declare const FilterOperationFn: EnumDictionary<FilterOperation, (value: number, toCompare: number) => boolean>;
|
|
37
|
+
export declare enum Operator {
|
|
38
|
+
ADD = "ADD",
|
|
39
|
+
SUB = "SUB",
|
|
40
|
+
MULT = "MULT",
|
|
41
|
+
DIV = "DIV",
|
|
42
|
+
ASSIGN = "ASSIGN"
|
|
43
|
+
}
|
|
44
|
+
export declare enum RateOfChangeOperation {
|
|
45
|
+
LT = "Less than",
|
|
46
|
+
LTE = "Less than or equal to",
|
|
47
|
+
GT = "Greater than",
|
|
48
|
+
GTE = "Greater than or equal to",
|
|
49
|
+
E = "Equal"
|
|
50
|
+
}
|
|
51
|
+
export declare const RateOfChangeComparator: EnumDictionary<RateOfChangeOperation, (value: number, toCompare: number) => boolean>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export declare const DEFAULT_SNACK_DURATION = 3000;
|
|
2
|
+
export declare enum SnackColor {
|
|
3
|
+
Warning = "warning",
|
|
4
|
+
Success = "success",
|
|
5
|
+
Error = "error",
|
|
6
|
+
Info = "info"
|
|
7
|
+
}
|
|
8
|
+
export declare enum SnackIcon {
|
|
9
|
+
Success = "mdi-checkbox-marked-circle",
|
|
10
|
+
Warning = "mdi-alert",
|
|
11
|
+
Error = "mdi-alert-circle",
|
|
12
|
+
Info = "mdi-information",
|
|
13
|
+
None = "none"
|
|
14
|
+
}
|
|
15
|
+
export declare enum SnackTitle {
|
|
16
|
+
Warning = "Warning",
|
|
17
|
+
Success = "Success",
|
|
18
|
+
Error = "Error",
|
|
19
|
+
Info = "Info"
|
|
20
|
+
}
|
|
21
|
+
export declare enum Position {
|
|
22
|
+
Center = "center",
|
|
23
|
+
Left = "left",
|
|
24
|
+
Right = "right",
|
|
25
|
+
Bottom = "bottom",
|
|
26
|
+
Top = "top"
|
|
27
|
+
}
|
|
28
|
+
export declare class Snack {
|
|
29
|
+
message: string;
|
|
30
|
+
color: SnackColor;
|
|
31
|
+
icon: SnackIcon;
|
|
32
|
+
title: SnackTitle;
|
|
33
|
+
timeout: number;
|
|
34
|
+
position: Position;
|
|
35
|
+
visible: boolean;
|
|
36
|
+
constructor(message?: string, color?: SnackColor, icon?: SnackIcon, title?: SnackTitle, timeout?: number, position?: Position, visible?: boolean);
|
|
37
|
+
}
|
|
38
|
+
export declare class Snackbar {
|
|
39
|
+
private static subject;
|
|
40
|
+
static get snack$(): import("rxjs").Observable<Snack>;
|
|
41
|
+
private static createSnackbar;
|
|
42
|
+
static success(message: string): void;
|
|
43
|
+
static warn(message: string): void;
|
|
44
|
+
static error(message: string): void;
|
|
45
|
+
static info(message: string): void;
|
|
46
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { EnumDictionary, EnumEditOperations, EnumFilterOperations, HistoryItem } from '../../types';
|
|
2
|
+
export declare function subtractHours(timestamp: string, hours: number): string;
|
|
3
|
+
/** Returns the index of the first value that is greater or equal to the target value */
|
|
4
|
+
export declare const findFirstGreaterOrEqual: (array: number[] | Float64Array<SharedArrayBuffer>, target: number) => number;
|
|
5
|
+
/** Returns the index of the last value that is lesser or equal to the target value */
|
|
6
|
+
export declare const findLastLessOrEqual: (array: number[] | Float64Array<SharedArrayBuffer>, target: number) => number;
|
|
7
|
+
export declare const measureEllapsedTime: (fn: () => any, message?: string) => Promise<{
|
|
8
|
+
response: any;
|
|
9
|
+
duration: number;
|
|
10
|
+
}>;
|
|
11
|
+
export declare enum TimeUnit {
|
|
12
|
+
SECOND = "s",
|
|
13
|
+
MINUTE = "m",
|
|
14
|
+
HOUR = "h",
|
|
15
|
+
DAY = "D",
|
|
16
|
+
WEEK = "W",
|
|
17
|
+
MONTH = "M",
|
|
18
|
+
YEAR = "Y"
|
|
19
|
+
}
|
|
20
|
+
export declare const timeUnitMultipliers: EnumDictionary<TimeUnit, number>;
|
|
21
|
+
export declare const formatDate: (date: Date) => string;
|
|
22
|
+
export declare const formatDuration: (duration: number) => string;
|
|
23
|
+
export declare const shiftDatetime: (datetime: number, amount: number, unit: TimeUnit) => number;
|
|
24
|
+
/**
|
|
25
|
+
* This number should approximate the number of observations that a dataset could increase by during a session.
|
|
26
|
+
* The lower this number, the less memory the entire app uses.
|
|
27
|
+
* Note that when a dataset number of data points increases by more than `INCREASE_AMOUNT`,
|
|
28
|
+
* the `_growBuffer()` method will allocate a new buffer, and the data will be copied into it.
|
|
29
|
+
*/
|
|
30
|
+
export declare const INCREASE_AMOUNT: number;
|
|
31
|
+
export declare class ObservationRecord {
|
|
32
|
+
/** The generated dataset to be used for plotting */
|
|
33
|
+
dataset: {
|
|
34
|
+
dimensions: string[];
|
|
35
|
+
source: {
|
|
36
|
+
x: Float64Array<SharedArrayBuffer>;
|
|
37
|
+
y: Float32Array<SharedArrayBuffer>;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
history: HistoryItem[];
|
|
41
|
+
loadingTime: number | null;
|
|
42
|
+
isLoading: boolean;
|
|
43
|
+
rawData: {
|
|
44
|
+
datetimes: Float64Array<ArrayBuffer> | number[];
|
|
45
|
+
dataValues: Float32Array<ArrayBuffer> | number[];
|
|
46
|
+
};
|
|
47
|
+
constructor(dataArrays: {
|
|
48
|
+
datetimes: Float64Array<ArrayBuffer> | number[];
|
|
49
|
+
dataValues: Float32Array<ArrayBuffer> | number[];
|
|
50
|
+
});
|
|
51
|
+
loadData(dataArrays: {
|
|
52
|
+
datetimes: Float64Array<ArrayBuffer> | number[];
|
|
53
|
+
dataValues: Float32Array<ArrayBuffer> | number[];
|
|
54
|
+
}): Promise<void>;
|
|
55
|
+
get dataX(): Float64Array<SharedArrayBuffer>;
|
|
56
|
+
get dataY(): Float32Array<SharedArrayBuffer>;
|
|
57
|
+
/**
|
|
58
|
+
* Resizes the typed array
|
|
59
|
+
* @param length The total number of elements that the view will contain
|
|
60
|
+
*/
|
|
61
|
+
private _resizeTo;
|
|
62
|
+
/**
|
|
63
|
+
* Buffer size is always in increments of `INCREASE_AMOUNT`.
|
|
64
|
+
* Grows the buffer by `INCREASE_AMOUNT` in bytes if the current data doesn't fit
|
|
65
|
+
* @param newLength The total number of elements that the view will contain
|
|
66
|
+
*/
|
|
67
|
+
private _growBuffer;
|
|
68
|
+
/**
|
|
69
|
+
* Reloads the dataset with the raw data
|
|
70
|
+
*/
|
|
71
|
+
reload(): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* @param index
|
|
74
|
+
* @returns
|
|
75
|
+
*/
|
|
76
|
+
reloadHistory(index: number): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Remove a history item
|
|
79
|
+
* @param index
|
|
80
|
+
*/
|
|
81
|
+
removeHistoryItem(index: number): Promise<void>;
|
|
82
|
+
get beginTime(): Date | null;
|
|
83
|
+
get endTime(): Date | null;
|
|
84
|
+
/** Dispatch an operation and log its signature in hisotry */
|
|
85
|
+
dispatch(action: EnumEditOperations | [EnumEditOperations, ...any][], ...args: any): Promise<any[]>;
|
|
86
|
+
/** Filter operations do not transform the data and are not logged in history */
|
|
87
|
+
dispatchFilter(action: EnumFilterOperations | [EnumFilterOperations, ...any][], ...args: any): Promise<any>;
|
|
88
|
+
/**
|
|
89
|
+
* @param index An array containing the list of index of values to perform the operations on.
|
|
90
|
+
* @param operator The operator that will be applied
|
|
91
|
+
* @param value The value to use in the operation
|
|
92
|
+
* @returns The modified DataFrame
|
|
93
|
+
*/
|
|
94
|
+
private _changeValues;
|
|
95
|
+
private _interpolate;
|
|
96
|
+
/** Interpolate existing values in the data source */
|
|
97
|
+
private _interpolateLinear;
|
|
98
|
+
/**
|
|
99
|
+
* Shifts the selected indexes by specified amount of units. Elements are reinserted according to their datetime.
|
|
100
|
+
* @param index The index of the elements to shift
|
|
101
|
+
* @param amount Number of {@link TimeUnit}
|
|
102
|
+
* @param unit {@link TimeUnit}
|
|
103
|
+
* @returns
|
|
104
|
+
*/
|
|
105
|
+
private _shift;
|
|
106
|
+
private _fillGapsV2;
|
|
107
|
+
/**
|
|
108
|
+
* Find gaps and fill them with placeholder value
|
|
109
|
+
* @param gap Intervals to detect as gaps
|
|
110
|
+
* @param fill Interval used to fill the detected gaps
|
|
111
|
+
* @param interpolateValues If true, the new values will be linearly interpolated
|
|
112
|
+
* @returns
|
|
113
|
+
*/
|
|
114
|
+
private _fillGaps;
|
|
115
|
+
/**
|
|
116
|
+
Deletes data points from a large array using worker threads.
|
|
117
|
+
1. The main thread divides the original array into equal parts to distribute work among workers.
|
|
118
|
+
2. For each segment, binary search locates the indexes to delete (deleteSegment), ensuring efficient lookups.
|
|
119
|
+
3. The cumulative deletions before each segment help compute the starting index (startTarget) for each worker's output, ensuring no overlap.
|
|
120
|
+
4. Each worker processes its segment linearly, skipping deletions and copying kept elements to their computed positions.
|
|
121
|
+
* @param deleteIndices
|
|
122
|
+
*/
|
|
123
|
+
private _deleteDataPoints;
|
|
124
|
+
/**
|
|
125
|
+
*
|
|
126
|
+
* @param start The start index
|
|
127
|
+
* @param end The end index
|
|
128
|
+
* @param value The drift amount
|
|
129
|
+
*/
|
|
130
|
+
private _driftCorrection;
|
|
131
|
+
/** Traverses the index array and returns groups of consecutive values.
|
|
132
|
+
* i.e.: `[0, 1, 3, 4, 6] => [[0, 1], [3, 4], [6]]`
|
|
133
|
+
* Assumes the input array is sorted.
|
|
134
|
+
* @param index: the index array (sorted)
|
|
135
|
+
*/
|
|
136
|
+
private _getConsecutiveGroups;
|
|
137
|
+
/**
|
|
138
|
+
* Adds data points. Their insert index is determined using `findFirstGreaterOrEqual` in the x-axis.
|
|
139
|
+
* @param dataPoints
|
|
140
|
+
*/
|
|
141
|
+
private _addDataPoints;
|
|
142
|
+
/**
|
|
143
|
+
* Filter by applying a set of logical operations
|
|
144
|
+
* @param appliedFilters
|
|
145
|
+
* @returns
|
|
146
|
+
*/
|
|
147
|
+
private _valueThreshold;
|
|
148
|
+
/**
|
|
149
|
+
*
|
|
150
|
+
* @param comparator
|
|
151
|
+
* @param value
|
|
152
|
+
* @returns
|
|
153
|
+
*/
|
|
154
|
+
private _rateOfChange;
|
|
155
|
+
/**
|
|
156
|
+
* Find gaps in the data
|
|
157
|
+
* @param value The time value
|
|
158
|
+
* @param unit The time unit (TimeUnit)
|
|
159
|
+
* @param range If specified, the gaps will be found only within the range
|
|
160
|
+
* @returns
|
|
161
|
+
*/
|
|
162
|
+
private _findGaps;
|
|
163
|
+
/**
|
|
164
|
+
* Find points where the values are the same at least x times in a row
|
|
165
|
+
* @param times The number of times in a row that points can be equal
|
|
166
|
+
* @param range If specified, the points will be found only within the range
|
|
167
|
+
* @returns
|
|
168
|
+
*/
|
|
169
|
+
private _persistence;
|
|
170
|
+
}
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uwrl/qc-utils",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
4
4
|
"description": "Quality Control Utilities",
|
|
5
5
|
"homepage": "https://github.com/hydroserver2/qc-utils#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
},
|
|
13
13
|
"license": "ISC",
|
|
14
14
|
"author": "Maurier Ramirez",
|
|
15
|
-
"type": "module",
|
|
16
15
|
"main": "./dist/index.cjs",
|
|
17
16
|
"module": "./dist/index.js",
|
|
18
17
|
"exports": {
|
|
@@ -21,11 +20,13 @@
|
|
|
21
20
|
"import": "./dist/index.js"
|
|
22
21
|
}
|
|
23
22
|
},
|
|
23
|
+
"types": "./dist/types.d.ts",
|
|
24
24
|
"files": [
|
|
25
25
|
"dist"
|
|
26
26
|
],
|
|
27
|
+
"type": "module",
|
|
27
28
|
"scripts": {
|
|
28
|
-
"build": "npm run clean:dist && vite build --mode prod",
|
|
29
|
+
"build": "npm run clean:dist && vite build --mode prod && vue-tsc --declaration --emitDeclarationOnly",
|
|
29
30
|
"pub": "npm publish --access public",
|
|
30
31
|
"clean:dist": "rimraf dist",
|
|
31
32
|
"clean:coverage": "rimraf coverage",
|
|
@@ -37,6 +38,7 @@
|
|
|
37
38
|
"link": "npm link"
|
|
38
39
|
},
|
|
39
40
|
"dependencies": {
|
|
41
|
+
"rxjs": "^7.8.2",
|
|
40
42
|
"vite": "^7.0.4"
|
|
41
43
|
},
|
|
42
44
|
"devDependencies": {
|
|
@@ -49,6 +51,7 @@
|
|
|
49
51
|
"stylelint": "^16.20.0",
|
|
50
52
|
"taze": "^19.1.0",
|
|
51
53
|
"typescript": "latest",
|
|
52
|
-
"vitest": "^3.2.4"
|
|
54
|
+
"vitest": "^3.2.4",
|
|
55
|
+
"vue-tsc": "^3.0.5"
|
|
53
56
|
}
|
|
54
57
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(function(){"use strict";self.onmessage=o=>{const{bufferX:s,bufferY:n,outputBufferX:u,outputBufferY:f,start:l,end:y,deleteSegment:a,startTarget:c}=o.data,A=new Float64Array(s),d=new Float32Array(n),g=new Float64Array(u),p=new Float32Array(f);let e=0,r=c;for(let t=l;t<=y;t++)e<a.length&&t===a[e]?e++:(g[r]=A[t],p[r]=d[t],r++);self.postMessage("Done")}})();
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(function(){"use strict";self.onmessage=function(e){const{bufferX:f,bufferY:t,outputBufferX:u,outputBufferY:s}=e.data;self.postMessage("Done")}})();
|