@uwrl/qc-utils 0.0.7 → 0.0.9

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.js CHANGED
@@ -1,60 +1,59 @@
1
- const T = {
2
- [E.SECOND]: 1,
3
- [E.MINUTE]: 60,
4
- [E.HOUR]: 3600,
5
- [E.DAY]: 86400,
6
- [E.WEEK]: 604800,
7
- [E.MONTH]: 108e3,
8
- [E.YEAR]: 31536e3
9
- }, D = (o, t, a) => {
10
- if (a === E.MONTH) {
11
- const e = new Date(o);
12
- return e.setMonth(e.getMonth() + t), e.getTime();
13
- } else if (a === E.YEAR) {
14
- const e = new Date(o);
15
- return e.setFullYear(e.getFullYear() + t), e.getTime();
16
- } else
17
- return o + t * T[a] * 1e3;
18
- }, w = async (o, t) => {
19
- const a = performance.now(), e = await o(), r = performance.now();
20
- console.log(` Done in ${(r - a).toFixed(2)} ms`);
21
- const s = +(r - a);
22
- return { response: e, duration: s };
23
- }, S = (o, t) => {
24
- let a = 0, e = o.length;
1
+ const A = (i, t) => {
2
+ let a = 0, e = i.length;
25
3
  for (; a < e; ) {
26
4
  const r = a + e >> 1;
27
- o[r] < t ? a = r + 1 : e = r;
5
+ i[r] < t ? a = r + 1 : e = r;
28
6
  }
29
7
  return a;
30
- }, L = (o, t) => {
31
- let a = 0, e = o.length;
8
+ }, T = (i, t) => {
9
+ let a = 0, e = i.length;
32
10
  for (; a < e; ) {
33
11
  const r = a + e >> 1;
34
- o[r] > t ? e = r : a = r + 1;
12
+ i[r] > t ? e = r : a = r + 1;
35
13
  }
36
14
  return a - 1;
37
- }, Y = {
38
- "Less than": (o, t) => o < t,
39
- "Less than or equal to": (o, t) => o <= t,
40
- "Greater than": (o, t) => o > t,
41
- "Greater than or equal to": (o, t) => o >= t,
42
- Equal: (o, t) => o == t,
43
- "Start datetime": (o, t) => o == t,
44
- "End datetime": (o, t) => o == t
45
- }, B = {
46
- "Less than": (o, t) => o < t,
47
- "Less than or equal to": (o, t) => o <= t,
48
- "Greater than": (o, t) => o > t,
49
- "Greater than or equal to": (o, t) => o >= t,
50
- Equal: (o, t) => o == t
15
+ }, _ = async (i, t) => {
16
+ const a = performance.now(), e = await i(), r = performance.now();
17
+ console.log(` Done in ${(r - a).toFixed(2)} ms`);
18
+ const s = +(r - a);
19
+ return { response: e, duration: s };
51
20
  };
52
- var E = /* @__PURE__ */ ((o) => (o.SECOND = "s", o.MINUTE = "m", o.HOUR = "h", o.DAY = "D", o.WEEK = "W", o.MONTH = "M", o.YEAR = "Y", o))(E || {});
53
- const g = 20 * 1e3, N = ["date", "value", "qualifier"];
21
+ const w = {
22
+ s: 1,
23
+ m: 60,
24
+ h: 3600,
25
+ D: 86400,
26
+ W: 604800,
27
+ M: 108e3,
28
+ Y: 31536e3
29
+ }, D = (i, t, a) => {
30
+ if (a === "M") {
31
+ const e = new Date(i);
32
+ return e.setMonth(e.getMonth() + t), e.getTime();
33
+ } else if (a === "Y") {
34
+ const e = new Date(i);
35
+ return e.setFullYear(e.getFullYear() + t), e.getTime();
36
+ } else
37
+ return i + t * w[a] * 1e3;
38
+ }, S = {
39
+ "Less than": (i, t) => i < t,
40
+ "Less than or equal to": (i, t) => i <= t,
41
+ "Greater than": (i, t) => i > t,
42
+ "Greater than or equal to": (i, t) => i >= t,
43
+ Equal: (i, t) => i == t,
44
+ "Start datetime": (i, t) => i == t,
45
+ "End datetime": (i, t) => i == t
46
+ }, Y = {
47
+ "Less than": (i, t) => i < t,
48
+ "Less than or equal to": (i, t) => i <= t,
49
+ "Greater than": (i, t) => i > t,
50
+ "Greater than or equal to": (i, t) => i >= t,
51
+ Equal: (i, t) => i == t
52
+ }, g = 20 * 1e3, B = ["date", "value", "qualifier"];
54
53
  class b {
55
54
  /** The generated dataset to be used for plotting */
56
55
  dataset = {
57
- dimensions: N,
56
+ dimensions: B,
58
57
  source: {
59
58
  x: new Float64Array(
60
59
  new SharedArrayBuffer(
@@ -87,7 +86,7 @@ class b {
87
86
  if (!t)
88
87
  return;
89
88
  this.isLoading = !0;
90
- const a = await w(() => {
89
+ const a = await _(() => {
91
90
  this._growBuffer(t.datetimes.length), this._resizeTo(t.datetimes.length), this.dataX.set(t.datetimes), this.dataY.set(t.dataValues);
92
91
  });
93
92
  this.loadingTime = a.duration, this.history.length = 0, this.isLoading = !1;
@@ -130,8 +129,8 @@ class b {
130
129
  {
131
130
  maxByteLength: e * Float32Array.BYTES_PER_ELEMENT
132
131
  }
133
- ), n = new Float64Array(r), i = new Float32Array(s);
134
- n.set(this.dataX), i.set(this.dataY), this.dataset.source.x = n, this.dataset.source.y = i;
132
+ ), n = new Float64Array(r), o = new Float32Array(s);
133
+ n.set(this.dataX), o.set(this.dataY), this.dataset.source.x = n, this.dataset.source.y = o;
135
134
  }
136
135
  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));
137
136
  }
@@ -186,22 +185,22 @@ class b {
186
185
  try {
187
186
  if (Array.isArray(t)) {
188
187
  for (let n = 0; n < t.length; n++) {
189
- const i = t[n][0], h = t[n].slice(1, t[n].length), l = {
190
- method: i,
188
+ const o = t[n][0], h = t[n].slice(1, t[n].length), l = {
189
+ method: o,
191
190
  args: h,
192
- icon: r[i],
191
+ icon: r[o],
193
192
  isLoading: !1
194
193
  };
195
194
  this.history.push(l);
196
195
  }
197
196
  for (let n = this.history.length - t.length; n < this.history.length; n++) {
198
- const i = this.history[n];
199
- i.isLoading = !0;
200
- const h = await w(async () => await e[i.method].apply(
197
+ const o = this.history[n];
198
+ o.isLoading = !0;
199
+ const h = await _(async () => await e[o.method].apply(
201
200
  this,
202
- i.args
201
+ o.args
203
202
  ));
204
- i.duration = h.duration, i.isLoading = !1, s.push(h.response);
203
+ o.duration = h.duration, o.isLoading = !1, s.push(h.response);
205
204
  }
206
205
  } else {
207
206
  const n = {
@@ -211,8 +210,8 @@ class b {
211
210
  isLoading: !0
212
211
  };
213
212
  this.history.push(n);
214
- const i = await w(async () => await e[t].apply(this, a));
215
- s = i.response, n.duration = i.duration, n.isLoading = !1;
213
+ const o = await _(async () => await e[t].apply(this, a));
214
+ s = o.response, n.duration = o.duration, n.isLoading = !1;
216
215
  }
217
216
  } catch (n) {
218
217
  console.log(
@@ -234,7 +233,7 @@ class b {
234
233
  try {
235
234
  if (Array.isArray(t))
236
235
  for (let s = 0; s < t.length; s++) {
237
- const n = t[s][0], i = t[s].slice(1, t[s].length), h = await e[n].apply(this, i);
236
+ const n = t[s][0], o = t[s].slice(1, t[s].length), h = await e[n].apply(this, o);
238
237
  r.push(h);
239
238
  }
240
239
  else
@@ -277,15 +276,15 @@ class b {
277
276
  _interpolate(t) {
278
277
  this._getConsecutiveGroups(t).forEach((e) => {
279
278
  const r = e[0], s = e[e.length - 1];
280
- let n = Math.max(0, r - 1), i = Math.min(this.dataset.source.y.length - 1, s + 1);
279
+ let n = Math.max(0, r - 1), o = Math.min(this.dataset.source.y.length - 1, s + 1);
281
280
  const h = this.dataset.source.x, l = this.dataset.source.y;
282
281
  for (let c = 0; c < e.length; c++)
283
282
  this.dataset.source.y[e[c]] = this._interpolateLinear(
284
283
  h[e[c]],
285
284
  h[n],
286
285
  l[n],
287
- h[i],
288
- l[i]
286
+ h[o],
287
+ l[o]
289
288
  );
290
289
  });
291
290
  }
@@ -308,13 +307,13 @@ class b {
308
307
  await this._deleteDataPoints(t), await this._addDataPoints(r);
309
308
  }
310
309
  async _fillGapsV2(t, a, e, r) {
311
- const s = navigator.hardwareConcurrency || 1, n = [], i = [], h = this.dataX.length, l = new SharedArrayBuffer(this.dataX.buffer.byteLength, {
310
+ const s = navigator.hardwareConcurrency || 1, n = [], o = [], h = this.dataX.length, l = new SharedArrayBuffer(this.dataX.buffer.byteLength, {
312
311
  maxByteLength: this.dataX.buffer.maxByteLength
313
312
  }), c = new SharedArrayBuffer(this.dataY.buffer.byteLength, {
314
313
  maxByteLength: this.dataY.buffer.maxByteLength
315
314
  });
316
315
  for (let u = 0; u < s; u++)
317
- i.push(
316
+ o.push(
318
317
  new Promise((d) => {
319
318
  const f = new Worker(
320
319
  new URL(
@@ -333,7 +332,7 @@ class b {
333
332
  };
334
333
  })
335
334
  );
336
- await Promise.all(i), n.forEach((u) => u.terminate()), this.dataset.source.x = new Float64Array(l), this.dataset.source.y = new Float32Array(c), this._resizeTo(h);
335
+ await Promise.all(o), n.forEach((u) => u.terminate()), this.dataset.source.x = new Float64Array(l), this.dataset.source.y = new Float32Array(c), this._resizeTo(h);
337
336
  }
338
337
  /**
339
338
  * Find gaps and fill them with placeholder value
@@ -346,15 +345,15 @@ class b {
346
345
  _fillGaps(t, a, e, r) {
347
346
  const s = this._findGaps(t[0], t[1], r);
348
347
  for (let n = s.length - 1; n >= 0; n--) {
349
- const i = s[n], h = this.dataX[i[0]], l = this.dataX[i[1]], c = [], u = a[0] * T[a[1]] * 1e3;
348
+ const o = s[n], h = this.dataX[o[0]], l = this.dataX[o[1]], c = [], u = a[0] * w[a[1]] * 1e3;
350
349
  let d = h + u;
351
350
  for (; d < l; ) {
352
351
  const f = e ? this._interpolateLinear(
353
352
  d,
354
- this.dataX[i[0]],
355
- this.dataY[i[0]],
356
- this.dataX[i[1]],
357
- this.dataY[i[1]]
353
+ this.dataX[o[0]],
354
+ this.dataY[o[0]],
355
+ this.dataX[o[1]],
356
+ this.dataY[o[1]]
358
357
  ) : -9999;
359
358
  c.push([d, f]), d += u;
360
359
  }
@@ -373,29 +372,29 @@ class b {
373
372
  async _deleteDataPoints(t) {
374
373
  const a = navigator.hardwareConcurrency || 1, e = Math.ceil(this.dataX.length / a), r = [], s = [];
375
374
  for (let u = 0; u < a; u++) {
376
- const d = u * e, f = Math.min((u + 1) * e - 1, this.dataX.length - 1), y = S(t, d), p = L(t, f), m = t.slice(y, p + 1);
375
+ const d = u * e, f = Math.min((u + 1) * e - 1, this.dataX.length - 1), y = A(t, d), E = T(t, f), m = t.slice(y, E + 1);
377
376
  s.push({ start: d, end: f, deleteSegment: m });
378
377
  }
379
378
  const n = new Array(a).fill(0);
380
379
  for (let u = 1; u < a; u++)
381
380
  n[u] = n[u - 1] + s[u - 1].deleteSegment.length;
382
- const i = [], h = this.dataX.length - t.length, l = new SharedArrayBuffer(this.dataX.buffer.byteLength, {
381
+ const o = [], h = this.dataX.length - t.length, l = new SharedArrayBuffer(this.dataX.buffer.byteLength, {
383
382
  maxByteLength: this.dataX.buffer.maxByteLength
384
383
  }), c = new SharedArrayBuffer(this.dataY.buffer.byteLength, {
385
384
  maxByteLength: this.dataY.buffer.maxByteLength
386
385
  });
387
386
  for (let u = 0; u < a; u++) {
388
- const { start: d, end: f, deleteSegment: y } = s[u], p = d - n[u];
389
- i.push(
387
+ const { start: d, end: f, deleteSegment: y } = s[u], E = d - n[u];
388
+ o.push(
390
389
  new Promise((m) => {
391
- const _ = new Worker(
390
+ const p = new Worker(
392
391
  new URL(
393
392
  /* @vite-ignore */
394
393
  "/assets/delete-data.worker-Iw4O1ScI.js",
395
394
  import.meta.url
396
395
  )
397
396
  );
398
- r.push(_), _.postMessage({
397
+ r.push(p), p.postMessage({
399
398
  bufferX: this.dataX.buffer,
400
399
  bufferY: this.dataY.buffer,
401
400
  outputBufferX: l,
@@ -403,14 +402,14 @@ class b {
403
402
  start: d,
404
403
  end: f,
405
404
  deleteSegment: y,
406
- startTarget: p
407
- }), _.onmessage = (A) => {
408
- m(A.data);
405
+ startTarget: E
406
+ }), p.onmessage = (L) => {
407
+ m(L.data);
409
408
  };
410
409
  })
411
410
  );
412
411
  }
413
- await Promise.all(i), r.forEach((u) => u.terminate()), this.dataset.source.x = new Float64Array(l), this.dataset.source.y = new Float32Array(c), this._resizeTo(h);
412
+ await Promise.all(o), r.forEach((u) => u.terminate()), this.dataset.source.x = new Float64Array(l), this.dataset.source.y = new Float32Array(c), this._resizeTo(h);
414
413
  }
415
414
  /**
416
415
  *
@@ -442,12 +441,12 @@ class b {
442
441
  async _addDataPoints(t) {
443
442
  const a = this.dataX.length + t.length;
444
443
  this._growBuffer(a), t.sort((s, n) => s[0] - n[0]);
445
- const e = t.map((s) => L(this.dataX, s[0]) + 1);
444
+ const e = t.map((s) => T(this.dataX, s[0]) + 1);
446
445
  this._resizeTo(a), e.push(this.dataX.length);
447
446
  let r = t.length;
448
447
  for (let s = e.length - 1; s > 0; s--) {
449
- const n = e[s - 1], i = e[s] - 1;
450
- for (let h = i; h >= n; h--)
448
+ const n = e[s - 1], o = e[s] - 1;
449
+ for (let h = o; h >= n; h--)
451
450
  this.dataX[h + r] = this.dataX[h], this.dataY[h + r] = this.dataY[h];
452
451
  r--, this.dataX[n + r] = t[s - 1][0], this.dataY[n + r] = t[s - 1][1];
453
452
  }
@@ -463,7 +462,7 @@ class b {
463
462
  _valueThreshold(t) {
464
463
  const a = [];
465
464
  return this.dataset.source.y.forEach((e, r) => {
466
- Object.keys(t).some((s) => Y[s]?.(
465
+ Object.keys(t).some((s) => S[s]?.(
467
466
  e,
468
467
  t[s]
469
468
  )) && a.push(r);
@@ -479,7 +478,7 @@ class b {
479
478
  const e = [], r = this.dataset.source.y;
480
479
  for (let s = 1; s < r.length; s++) {
481
480
  const n = r[s - 1], h = (r[s] - n) / Math.abs(n);
482
- B[t]?.(
481
+ Y[t]?.(
483
482
  h,
484
483
  a
485
484
  ) && e.push(s);
@@ -495,12 +494,12 @@ class b {
495
494
  */
496
495
  _findGaps(t, a, e) {
497
496
  const r = [], s = this.dataset.source.x;
498
- let n = 0, i = s.length;
499
- e?.[0] && e?.[1] && (n = e[0], i = e[1]);
497
+ let n = 0, o = s.length;
498
+ e?.[0] && e?.[1] && (n = e[0], o = e[1]);
500
499
  let h = s[n];
501
- for (let l = n + 1; l <= i; l++) {
500
+ for (let l = n + 1; l <= o; l++) {
502
501
  const c = s[l];
503
- c - h > t * T[a] * 1e3 && r.push([l - 1, l]), h = c;
502
+ c - h > t * w[a] * 1e3 && r.push([l - 1, l]), h = c;
504
503
  }
505
504
  return r;
506
505
  }
@@ -513,9 +512,9 @@ class b {
513
512
  _persistence(t, a) {
514
513
  let e = [], r = this.dataset.source.y, s = 0, n = r.length;
515
514
  a?.[0] && a?.[1] && (s = a[0], n = a[1]);
516
- let i = r[s], h = [];
515
+ let o = r[s], h = [];
517
516
  for (let l = s + 1; l < n; l++)
518
- r[l] != i || l === n ? (h.length >= t && (e = [...e, ...h]), h = []) : h.push(l);
517
+ r[l] != o || l === n ? (h.length >= t && (e = [...e, ...h]), h = []) : h.push(l);
519
518
  return e;
520
519
  }
521
520
  }
@@ -1 +1 @@
1
- (function(E,f){typeof exports=="object"&&typeof module<"u"?f(exports):typeof define=="function"&&define.amd?define(["exports"],f):(E=typeof globalThis<"u"?globalThis:E||self,f(E["@uwrl/qc-utils"]={}))})(this,function(E){"use strict";var f=typeof document<"u"?document.currentScript:null;const Y=1,b=Y*60,_=b*60,w=_*24,R=w*7,F=_*30,N=w*365,T={[y.SECOND]:Y,[y.MINUTE]:b,[y.HOUR]:_,[y.DAY]:w,[y.WEEK]:R,[y.MONTH]:F,[y.YEAR]:N},x=(o,t,a)=>{if(a===y.MONTH){const e=new Date(o);return e.setMonth(e.getMonth()+t),e.getTime()}else if(a===y.YEAR){const e=new Date(o);return e.setFullYear(e.getFullYear()+t),e.getTime()}else return o+t*T[a]*1e3},L=async(o,t)=>{const a=performance.now(),e=await o(),r=performance.now();console.log(` Done in ${(r-a).toFixed(2)} ms`);const s=+(r-a);return{response:e,duration:s}},X=(o,t)=>{let a=0,e=o.length;for(;a<e;){const r=a+e>>1;o[r]<t?a=r+1:e=r}return a},B=(o,t)=>{let a=0,e=o.length;for(;a<e;){const r=a+e>>1;o[r]>t?e=r:a=r+1}return a-1},I={"Less than":(o,t)=>o<t,"Less than or equal to":(o,t)=>o<=t,"Greater than":(o,t)=>o>t,"Greater than or equal to":(o,t)=>o>=t,Equal:(o,t)=>o==t,"Start datetime":(o,t)=>o==t,"End datetime":(o,t)=>o==t},M={"Less than":(o,t)=>o<t,"Less than or equal to":(o,t)=>o<=t,"Greater than":(o,t)=>o>t,"Greater than or equal to":(o,t)=>o>=t,Equal:(o,t)=>o==t};var y=(o=>(o.SECOND="s",o.MINUTE="m",o.HOUR="h",o.DAY="D",o.WEEK="W",o.MONTH="M",o.YEAR="Y",o))(y||{});const p=20*1e3,O=["date","value","qualifier"];class P{dataset={dimensions:O,source:{x:new Float64Array(new SharedArrayBuffer(p*Float64Array.BYTES_PER_ELEMENT,{maxByteLength:p*Float64Array.BYTES_PER_ELEMENT})),y:new Float32Array(new SharedArrayBuffer(p*Float32Array.BYTES_PER_ELEMENT,{maxByteLength:p*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 a=await L(()=>{this._growBuffer(t.datetimes.length),this._resizeTo(t.datetimes.length),this.dataX.set(t.datetimes),this.dataY.set(t.dataValues)});this.loadingTime=a.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 a=t*Float64Array.BYTES_PER_ELEMENT;let e=this.dataX.buffer.byteLength;for(;a>e;)e+=p*Float64Array.BYTES_PER_ELEMENT;if(e*Float64Array.BYTES_PER_ELEMENT>this.dataX.buffer.maxByteLength){const r=new SharedArrayBuffer(this.dataX.buffer.byteLength,{maxByteLength:e*Float64Array.BYTES_PER_ELEMENT}),s=new SharedArrayBuffer(this.dataY.buffer.byteLength,{maxByteLength:e*Float32Array.BYTES_PER_ELEMENT}),n=new Float64Array(r),i=new Float32Array(s);n.set(this.dataX),i.set(this.dataY),this.dataset.source.x=n,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 a=this.history.slice(0,t+1);await this.reload(),await this.dispatch(a.map(e=>[e.method,...e.args||[]]))}async removeHistoryItem(t){const a=[...this.history];a.splice(t,1),await this.reload(),await this.dispatch(a.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,...a){const e={ADD_POINTS:this._addDataPoints,CHANGE_VALUES:this._changeValues,DELETE_POINTS:this._deleteDataPoints,DRIFT_CORRECTION:this._driftCorrection,INTERPOLATE:this._interpolate,SHIFT_DATETIMES:this._shift,FILL_GAPS:this._fillGaps},r={ADD_POINTS:"mdi-plus",CHANGE_VALUES:"mdi-pencil",DELETE_POINTS:"mdi-trash-can",DRIFT_CORRECTION:"mdi-chart-sankey",INTERPOLATE:"mdi-transit-connection-horizontal",SHIFT_DATETIMES:"mdi-calendar",FILL_GAPS:"mdi-keyboard-space"};let s=[];try{if(Array.isArray(t)){for(let n=0;n<t.length;n++){const i=t[n][0],h=t[n].slice(1,t[n].length),u={method:i,args:h,icon:r[i],isLoading:!1};this.history.push(u)}for(let n=this.history.length-t.length;n<this.history.length;n++){const i=this.history[n];i.isLoading=!0;const h=await L(async()=>await e[i.method].apply(this,i.args));i.duration=h.duration,i.isLoading=!1,s.push(h.response)}}else{const n={method:t,args:a,icon:r[t],isLoading:!0};this.history.push(n);const i=await L(async()=>await e[t].apply(this,a));s=i.response,n.duration=i.duration,n.isLoading=!1}}catch(n){console.log(`Failed to execute operation: ${t} with arguments: `,a),console.log(n)}return s}async dispatchFilter(t,...a){const e={FIND_GAPS:this._findGaps,VALUE_THRESHOLD:this._valueThreshold,PERSISTENCE:this._persistence,RATE_OF_CHANGE:this._rateOfChange};let r=[];try{if(Array.isArray(t))for(let s=0;s<t.length;s++){const n=t[s][0],i=t[s].slice(1,t[s].length),h=await e[n].apply(this,i);r.push(h)}else r=await e[t].apply(this,a)}catch(s){console.log(`Failed to execute filter operation: ${t} with arguments: `,a),console.log(s)}return r}_changeValues(t,a,e){const r=s=>{switch(a){case"ADD":return s+e;case"ASSIGN":return e;case"DIV":return s/e;case"MULT":return s*e;case"SUB":return s-e;default:return s}};t.forEach(s=>{this.dataset.source.y[s]=r(this.dataset.source.y[s])})}_interpolate(t){this._getConsecutiveGroups(t).forEach(e=>{const r=e[0],s=e[e.length-1];let n=Math.max(0,r-1),i=Math.min(this.dataset.source.y.length-1,s+1);const h=this.dataset.source.x,u=this.dataset.source.y;for(let c=0;c<e.length;c++)this.dataset.source.y[e[c]]=this._interpolateLinear(h[e[c]],h[n],u[n],h[i],u[i])})}_interpolateLinear(t,a,e,r,s){return e+(t-a)*(s-e)/(r-a)}async _shift(t,a,e){const r=t.map(s=>[x(this.dataX[s],a,e),this.dataY[s]]);await this._deleteDataPoints(t),await this._addDataPoints(r)}async _fillGapsV2(t,a,e,r){const s=navigator.hardwareConcurrency||1,n=[],i=[],h=this.dataX.length,u=new SharedArrayBuffer(this.dataX.buffer.byteLength,{maxByteLength:this.dataX.buffer.maxByteLength}),c=new SharedArrayBuffer(this.dataY.buffer.byteLength,{maxByteLength:this.dataY.buffer.maxByteLength});for(let l=0;l<s;l++)i.push(new Promise(d=>{const g=new Worker(new URL("/assets/fill-gaps.worker-BesEL5v2.js",typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__filename).href:typeof document>"u"?location.href:f&&f.tagName.toUpperCase()==="SCRIPT"&&f.src||new URL("index.umd.cjs",document.baseURI).href));n.push(g),g.postMessage({bufferX:this.dataX.buffer,bufferY:this.dataY.buffer,outputBufferX:u,outputBufferY:c}),g.onmessage=m=>{d(m.data)}}));await Promise.all(i),n.forEach(l=>l.terminate()),this.dataset.source.x=new Float64Array(u),this.dataset.source.y=new Float32Array(c),this._resizeTo(h)}_fillGaps(t,a,e,r){const s=this._findGaps(t[0],t[1],r);for(let n=s.length-1;n>=0;n--){const i=s[n],h=this.dataX[i[0]],u=this.dataX[i[1]],c=[],l=a[0]*T[a[1]]*1e3;let d=h+l;for(;d<u;){const g=e?this._interpolateLinear(d,this.dataX[i[0]],this.dataY[i[0]],this.dataX[i[1]],this.dataY[i[1]]):-9999;c.push([d,g]),d+=l}this._addDataPoints(c)}}async _deleteDataPoints(t){const a=navigator.hardwareConcurrency||1,e=Math.ceil(this.dataX.length/a),r=[],s=[];for(let l=0;l<a;l++){const d=l*e,g=Math.min((l+1)*e-1,this.dataX.length-1),m=X(t,d),A=B(t,g),S=t.slice(m,A+1);s.push({start:d,end:g,deleteSegment:S})}const n=new Array(a).fill(0);for(let l=1;l<a;l++)n[l]=n[l-1]+s[l-1].deleteSegment.length;const i=[],h=this.dataX.length-t.length,u=new SharedArrayBuffer(this.dataX.buffer.byteLength,{maxByteLength:this.dataX.buffer.maxByteLength}),c=new SharedArrayBuffer(this.dataY.buffer.byteLength,{maxByteLength:this.dataY.buffer.maxByteLength});for(let l=0;l<a;l++){const{start:d,end:g,deleteSegment:m}=s[l],A=d-n[l];i.push(new Promise(S=>{const D=new Worker(new URL("/assets/delete-data.worker-Iw4O1ScI.js",typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__filename).href:typeof document>"u"?location.href:f&&f.tagName.toUpperCase()==="SCRIPT"&&f.src||new URL("index.umd.cjs",document.baseURI).href));r.push(D),D.postMessage({bufferX:this.dataX.buffer,bufferY:this.dataY.buffer,outputBufferX:u,outputBufferY:c,start:d,end:g,deleteSegment:m,startTarget:A}),D.onmessage=C=>{S(C.data)}}))}await Promise.all(i),r.forEach(l=>l.terminate()),this.dataset.source.x=new Float64Array(u),this.dataset.source.y=new Float32Array(c),this._resizeTo(h)}_driftCorrection(t,a,e){const r=this.dataset.source.x,s=this.dataset.source.y,n=r[t],h=r[a]-n;for(let u=t;u<a;u++)this.dataset.source.y[u]=s[u]+e*((r[u]-n)/h)}_getConsecutiveGroups(t){const a=[[]];return t.reduce((e,r)=>{const s=e[e.length-1];return!s.length||r==s[s.length-1]+1?s.push(r):e.push([r]),e},a),a}async _addDataPoints(t){const a=this.dataX.length+t.length;this._growBuffer(a),t.sort((s,n)=>s[0]-n[0]);const e=t.map(s=>B(this.dataX,s[0])+1);this._resizeTo(a),e.push(this.dataX.length);let r=t.length;for(let s=e.length-1;s>0;s--){const n=e[s-1],i=e[s]-1;for(let h=i;h>=n;h--)this.dataX[h+r]=this.dataX[h],this.dataY[h+r]=this.dataY[h];r--,this.dataX[n+r]=t[s-1][0],this.dataY[n+r]=t[s-1][1]}}_valueThreshold(t){const a=[];return this.dataset.source.y.forEach((e,r)=>{Object.keys(t).some(s=>I[s]?.(e,t[s]))&&a.push(r)}),a}_rateOfChange(t,a){const e=[],r=this.dataset.source.y;for(let s=1;s<r.length;s++){const n=r[s-1],h=(r[s]-n)/Math.abs(n);M[t]?.(h,a)&&e.push(s)}return e}_findGaps(t,a,e){const r=[],s=this.dataset.source.x;let n=0,i=s.length;e?.[0]&&e?.[1]&&(n=e[0],i=e[1]);let h=s[n];for(let u=n+1;u<=i;u++){const c=s[u];c-h>t*T[a]*1e3&&r.push([u-1,u]),h=c}return r}_persistence(t,a){let e=[],r=this.dataset.source.y,s=0,n=r.length;a?.[0]&&a?.[1]&&(s=a[0],n=a[1]);let i=r[s],h=[];for(let u=s+1;u<n;u++)r[u]!=i||u===n?(h.length>=t&&(e=[...e,...h]),h=[]):h.push(u);return e}}E.ObservationRecord=P,Object.defineProperty(E,Symbol.toStringTag,{value:"Module"})});
1
+ (function(g,f){typeof exports=="object"&&typeof module<"u"?f(exports):typeof define=="function"&&define.amd?define(["exports"],f):(g=typeof globalThis<"u"?globalThis:g||self,f(g["@uwrl/qc-utils"]={}))})(this,function(g){"use strict";var f=typeof document<"u"?document.currentScript:null;const Y=(i,t)=>{let a=0,e=i.length;for(;a<e;){const r=a+e>>1;i[r]<t?a=r+1:e=r}return a},D=(i,t)=>{let a=0,e=i.length;for(;a<e;){const r=a+e>>1;i[r]>t?e=r:a=r+1}return a-1},E=async(i,t)=>{const a=performance.now(),e=await i(),r=performance.now();console.log(` Done in ${(r-a).toFixed(2)} ms`);const s=+(r-a);return{response:e,duration:s}},b=1,B=b*60,_=B*60,w=_*24,F=w*7,x=_*30,R=w*365,T={s:b,m:B,h:_,D:w,W:F,M:x,Y:R},X=(i,t,a)=>{if(a==="M"){const e=new Date(i);return e.setMonth(e.getMonth()+t),e.getTime()}else if(a==="Y"){const e=new Date(i);return e.setFullYear(e.getFullYear()+t),e.getTime()}else return i+t*T[a]*1e3},I={"Less than":(i,t)=>i<t,"Less than or equal to":(i,t)=>i<=t,"Greater than":(i,t)=>i>t,"Greater than or equal to":(i,t)=>i>=t,Equal:(i,t)=>i==t,"Start datetime":(i,t)=>i==t,"End datetime":(i,t)=>i==t},N={"Less than":(i,t)=>i<t,"Less than or equal to":(i,t)=>i<=t,"Greater than":(i,t)=>i>t,"Greater than or equal to":(i,t)=>i>=t,Equal:(i,t)=>i==t},p=20*1e3,P=["date","value","qualifier"];class M{dataset={dimensions:P,source:{x:new Float64Array(new SharedArrayBuffer(p*Float64Array.BYTES_PER_ELEMENT,{maxByteLength:p*Float64Array.BYTES_PER_ELEMENT})),y:new Float32Array(new SharedArrayBuffer(p*Float32Array.BYTES_PER_ELEMENT,{maxByteLength:p*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 a=await E(()=>{this._growBuffer(t.datetimes.length),this._resizeTo(t.datetimes.length),this.dataX.set(t.datetimes),this.dataY.set(t.dataValues)});this.loadingTime=a.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 a=t*Float64Array.BYTES_PER_ELEMENT;let e=this.dataX.buffer.byteLength;for(;a>e;)e+=p*Float64Array.BYTES_PER_ELEMENT;if(e*Float64Array.BYTES_PER_ELEMENT>this.dataX.buffer.maxByteLength){const r=new SharedArrayBuffer(this.dataX.buffer.byteLength,{maxByteLength:e*Float64Array.BYTES_PER_ELEMENT}),s=new SharedArrayBuffer(this.dataY.buffer.byteLength,{maxByteLength:e*Float32Array.BYTES_PER_ELEMENT}),n=new Float64Array(r),o=new Float32Array(s);n.set(this.dataX),o.set(this.dataY),this.dataset.source.x=n,this.dataset.source.y=o}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 a=this.history.slice(0,t+1);await this.reload(),await this.dispatch(a.map(e=>[e.method,...e.args||[]]))}async removeHistoryItem(t){const a=[...this.history];a.splice(t,1),await this.reload(),await this.dispatch(a.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,...a){const e={ADD_POINTS:this._addDataPoints,CHANGE_VALUES:this._changeValues,DELETE_POINTS:this._deleteDataPoints,DRIFT_CORRECTION:this._driftCorrection,INTERPOLATE:this._interpolate,SHIFT_DATETIMES:this._shift,FILL_GAPS:this._fillGaps},r={ADD_POINTS:"mdi-plus",CHANGE_VALUES:"mdi-pencil",DELETE_POINTS:"mdi-trash-can",DRIFT_CORRECTION:"mdi-chart-sankey",INTERPOLATE:"mdi-transit-connection-horizontal",SHIFT_DATETIMES:"mdi-calendar",FILL_GAPS:"mdi-keyboard-space"};let s=[];try{if(Array.isArray(t)){for(let n=0;n<t.length;n++){const o=t[n][0],h=t[n].slice(1,t[n].length),u={method:o,args:h,icon:r[o],isLoading:!1};this.history.push(u)}for(let n=this.history.length-t.length;n<this.history.length;n++){const o=this.history[n];o.isLoading=!0;const h=await E(async()=>await e[o.method].apply(this,o.args));o.duration=h.duration,o.isLoading=!1,s.push(h.response)}}else{const n={method:t,args:a,icon:r[t],isLoading:!0};this.history.push(n);const o=await E(async()=>await e[t].apply(this,a));s=o.response,n.duration=o.duration,n.isLoading=!1}}catch(n){console.log(`Failed to execute operation: ${t} with arguments: `,a),console.log(n)}return s}async dispatchFilter(t,...a){const e={FIND_GAPS:this._findGaps,VALUE_THRESHOLD:this._valueThreshold,PERSISTENCE:this._persistence,RATE_OF_CHANGE:this._rateOfChange};let r=[];try{if(Array.isArray(t))for(let s=0;s<t.length;s++){const n=t[s][0],o=t[s].slice(1,t[s].length),h=await e[n].apply(this,o);r.push(h)}else r=await e[t].apply(this,a)}catch(s){console.log(`Failed to execute filter operation: ${t} with arguments: `,a),console.log(s)}return r}_changeValues(t,a,e){const r=s=>{switch(a){case"ADD":return s+e;case"ASSIGN":return e;case"DIV":return s/e;case"MULT":return s*e;case"SUB":return s-e;default:return s}};t.forEach(s=>{this.dataset.source.y[s]=r(this.dataset.source.y[s])})}_interpolate(t){this._getConsecutiveGroups(t).forEach(e=>{const r=e[0],s=e[e.length-1];let n=Math.max(0,r-1),o=Math.min(this.dataset.source.y.length-1,s+1);const h=this.dataset.source.x,u=this.dataset.source.y;for(let c=0;c<e.length;c++)this.dataset.source.y[e[c]]=this._interpolateLinear(h[e[c]],h[n],u[n],h[o],u[o])})}_interpolateLinear(t,a,e,r,s){return e+(t-a)*(s-e)/(r-a)}async _shift(t,a,e){const r=t.map(s=>[X(this.dataX[s],a,e),this.dataY[s]]);await this._deleteDataPoints(t),await this._addDataPoints(r)}async _fillGapsV2(t,a,e,r){const s=navigator.hardwareConcurrency||1,n=[],o=[],h=this.dataX.length,u=new SharedArrayBuffer(this.dataX.buffer.byteLength,{maxByteLength:this.dataX.buffer.maxByteLength}),c=new SharedArrayBuffer(this.dataY.buffer.byteLength,{maxByteLength:this.dataY.buffer.maxByteLength});for(let l=0;l<s;l++)o.push(new Promise(d=>{const y=new Worker(new URL("/assets/fill-gaps.worker-BesEL5v2.js",typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__filename).href:typeof document>"u"?location.href:f&&f.tagName.toUpperCase()==="SCRIPT"&&f.src||new URL("index.umd.cjs",document.baseURI).href));n.push(y),y.postMessage({bufferX:this.dataX.buffer,bufferY:this.dataY.buffer,outputBufferX:u,outputBufferY:c}),y.onmessage=m=>{d(m.data)}}));await Promise.all(o),n.forEach(l=>l.terminate()),this.dataset.source.x=new Float64Array(u),this.dataset.source.y=new Float32Array(c),this._resizeTo(h)}_fillGaps(t,a,e,r){const s=this._findGaps(t[0],t[1],r);for(let n=s.length-1;n>=0;n--){const o=s[n],h=this.dataX[o[0]],u=this.dataX[o[1]],c=[],l=a[0]*T[a[1]]*1e3;let d=h+l;for(;d<u;){const y=e?this._interpolateLinear(d,this.dataX[o[0]],this.dataY[o[0]],this.dataX[o[1]],this.dataY[o[1]]):-9999;c.push([d,y]),d+=l}this._addDataPoints(c)}}async _deleteDataPoints(t){const a=navigator.hardwareConcurrency||1,e=Math.ceil(this.dataX.length/a),r=[],s=[];for(let l=0;l<a;l++){const d=l*e,y=Math.min((l+1)*e-1,this.dataX.length-1),m=Y(t,d),L=D(t,y),A=t.slice(m,L+1);s.push({start:d,end:y,deleteSegment:A})}const n=new Array(a).fill(0);for(let l=1;l<a;l++)n[l]=n[l-1]+s[l-1].deleteSegment.length;const o=[],h=this.dataX.length-t.length,u=new SharedArrayBuffer(this.dataX.buffer.byteLength,{maxByteLength:this.dataX.buffer.maxByteLength}),c=new SharedArrayBuffer(this.dataY.buffer.byteLength,{maxByteLength:this.dataY.buffer.maxByteLength});for(let l=0;l<a;l++){const{start:d,end:y,deleteSegment:m}=s[l],L=d-n[l];o.push(new Promise(A=>{const S=new Worker(new URL("/assets/delete-data.worker-Iw4O1ScI.js",typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__filename).href:typeof document>"u"?location.href:f&&f.tagName.toUpperCase()==="SCRIPT"&&f.src||new URL("index.umd.cjs",document.baseURI).href));r.push(S),S.postMessage({bufferX:this.dataX.buffer,bufferY:this.dataY.buffer,outputBufferX:u,outputBufferY:c,start:d,end:y,deleteSegment:m,startTarget:L}),S.onmessage=O=>{A(O.data)}}))}await Promise.all(o),r.forEach(l=>l.terminate()),this.dataset.source.x=new Float64Array(u),this.dataset.source.y=new Float32Array(c),this._resizeTo(h)}_driftCorrection(t,a,e){const r=this.dataset.source.x,s=this.dataset.source.y,n=r[t],h=r[a]-n;for(let u=t;u<a;u++)this.dataset.source.y[u]=s[u]+e*((r[u]-n)/h)}_getConsecutiveGroups(t){const a=[[]];return t.reduce((e,r)=>{const s=e[e.length-1];return!s.length||r==s[s.length-1]+1?s.push(r):e.push([r]),e},a),a}async _addDataPoints(t){const a=this.dataX.length+t.length;this._growBuffer(a),t.sort((s,n)=>s[0]-n[0]);const e=t.map(s=>D(this.dataX,s[0])+1);this._resizeTo(a),e.push(this.dataX.length);let r=t.length;for(let s=e.length-1;s>0;s--){const n=e[s-1],o=e[s]-1;for(let h=o;h>=n;h--)this.dataX[h+r]=this.dataX[h],this.dataY[h+r]=this.dataY[h];r--,this.dataX[n+r]=t[s-1][0],this.dataY[n+r]=t[s-1][1]}}_valueThreshold(t){const a=[];return this.dataset.source.y.forEach((e,r)=>{Object.keys(t).some(s=>I[s]?.(e,t[s]))&&a.push(r)}),a}_rateOfChange(t,a){const e=[],r=this.dataset.source.y;for(let s=1;s<r.length;s++){const n=r[s-1],h=(r[s]-n)/Math.abs(n);N[t]?.(h,a)&&e.push(s)}return e}_findGaps(t,a,e){const r=[],s=this.dataset.source.x;let n=0,o=s.length;e?.[0]&&e?.[1]&&(n=e[0],o=e[1]);let h=s[n];for(let u=n+1;u<=o;u++){const c=s[u];c-h>t*T[a]*1e3&&r.push([u-1,u]),h=c}return r}_persistence(t,a){let e=[],r=this.dataset.source.y,s=0,n=r.length;a?.[0]&&a?.[1]&&(s=a[0],n=a[1]);let o=r[s],h=[];for(let u=s+1;u<n;u++)r[u]!=o||u===n?(h.length>=t&&(e=[...e,...h]),h=[]):h.push(u);return e}}g.ObservationRecord=M,Object.defineProperty(g,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uwrl/qc-utils",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "Quality Control Utilities",
5
5
  "homepage": "https://github.com/hydroserver2/qc-utils#readme",
6
6
  "bugs": {