@ifc-lite/renderer 6.0.0 → 6.3.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/README.md +21 -0
- package/dist/ao-pass.d.ts +0 -16
- package/dist/ao-pass.d.ts.map +1 -1
- package/dist/ao-pass.js +2 -0
- package/dist/ao-pass.js.map +1 -1
- package/dist/camera-animation.d.ts +1 -1
- package/dist/camera-animation.d.ts.map +1 -1
- package/dist/camera-animation.js +11 -11
- package/dist/camera-animation.js.map +1 -1
- package/dist/camera-inertia.d.ts +27 -0
- package/dist/camera-inertia.d.ts.map +1 -0
- package/dist/camera-inertia.js +33 -0
- package/dist/camera-inertia.js.map +1 -0
- package/dist/camera.d.ts.map +1 -1
- package/dist/camera.js +3 -0
- package/dist/camera.js.map +1 -1
- package/dist/deviation/deviation-computer.d.ts +5 -1
- package/dist/deviation/deviation-computer.d.ts.map +1 -1
- package/dist/deviation/deviation-computer.js +13 -6
- package/dist/deviation/deviation-computer.js.map +1 -1
- package/dist/deviation/deviation-readback.d.ts +16 -3
- package/dist/deviation/deviation-readback.d.ts.map +1 -1
- package/dist/deviation/deviation-readback.js +46 -36
- package/dist/deviation/deviation-readback.js.map +1 -1
- package/dist/deviation/deviation-statistics-kernel.d.ts +111 -0
- package/dist/deviation/deviation-statistics-kernel.d.ts.map +1 -0
- package/dist/deviation/deviation-statistics-kernel.js +303 -0
- package/dist/deviation/deviation-statistics-kernel.js.map +1 -0
- package/dist/deviation/deviation-statistics.d.ts +100 -0
- package/dist/deviation/deviation-statistics.d.ts.map +1 -0
- package/dist/deviation/deviation-statistics.js +100 -0
- package/dist/deviation/deviation-statistics.js.map +1 -0
- package/dist/device-recovery.d.ts.map +1 -1
- package/dist/device-recovery.js +5 -0
- package/dist/device-recovery.js.map +1 -1
- package/dist/device.d.ts +0 -3
- package/dist/device.d.ts.map +1 -1
- package/dist/device.js +5 -1
- package/dist/device.js.map +1 -1
- package/dist/edge-pass.d.ts +0 -12
- package/dist/edge-pass.d.ts.map +1 -1
- package/dist/edge-pass.js +3 -0
- package/dist/edge-pass.js.map +1 -1
- package/dist/edl-pass.d.ts +0 -21
- package/dist/edl-pass.d.ts.map +1 -1
- package/dist/edl-pass.js +23 -0
- package/dist/edl-pass.js.map +1 -1
- package/dist/frame-timing-gpu.d.ts +11 -15
- package/dist/frame-timing-gpu.d.ts.map +1 -1
- package/dist/frame-timing-gpu.js +57 -26
- package/dist/frame-timing-gpu.js.map +1 -1
- package/dist/gpu-counters.d.ts +30 -0
- package/dist/gpu-counters.d.ts.map +1 -0
- package/dist/gpu-counters.js +84 -0
- package/dist/gpu-counters.js.map +1 -0
- package/dist/gpu-static-upload.d.ts.map +1 -1
- package/dist/gpu-static-upload.js +2 -0
- package/dist/gpu-static-upload.js.map +1 -1
- package/dist/index.d.ts +33 -21
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +70 -59
- package/dist/index.js.map +1 -1
- package/dist/picker-depth-sample.d.ts +9 -0
- package/dist/picker-depth-sample.d.ts.map +1 -0
- package/dist/picker-depth-sample.js +63 -0
- package/dist/picker-depth-sample.js.map +1 -0
- package/dist/picker-readbacks.d.ts +8 -1
- package/dist/picker-readbacks.d.ts.map +1 -1
- package/dist/picker-readbacks.js +18 -1
- package/dist/picker-readbacks.js.map +1 -1
- package/dist/picker.d.ts +2 -0
- package/dist/picker.d.ts.map +1 -1
- package/dist/picker.js +70 -94
- package/dist/picker.js.map +1 -1
- package/dist/picking-manager.d.ts +5 -2
- package/dist/picking-manager.d.ts.map +1 -1
- package/dist/picking-manager.js +25 -8
- package/dist/picking-manager.js.map +1 -1
- package/dist/pipeline.d.ts +8 -0
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +22 -0
- package/dist/pipeline.js.map +1 -1
- package/dist/pointcloud/point-cloud-keyed-chunks.d.ts +23 -0
- package/dist/pointcloud/point-cloud-keyed-chunks.d.ts.map +1 -0
- package/dist/pointcloud/point-cloud-keyed-chunks.js +44 -0
- package/dist/pointcloud/point-cloud-keyed-chunks.js.map +1 -0
- package/dist/pointcloud/point-cloud-node.d.ts +5 -1
- package/dist/pointcloud/point-cloud-node.d.ts.map +1 -1
- package/dist/pointcloud/point-cloud-node.js +8 -4
- package/dist/pointcloud/point-cloud-node.js.map +1 -1
- package/dist/pointcloud/point-cloud-placement.d.ts +6 -0
- package/dist/pointcloud/point-cloud-placement.d.ts.map +1 -1
- package/dist/pointcloud/point-cloud-placement.js +8 -0
- package/dist/pointcloud/point-cloud-placement.js.map +1 -1
- package/dist/pointcloud/point-cloud-ray-transform.d.ts +17 -8
- package/dist/pointcloud/point-cloud-ray-transform.d.ts.map +1 -1
- package/dist/pointcloud/point-cloud-ray-transform.js +17 -13
- package/dist/pointcloud/point-cloud-ray-transform.js.map +1 -1
- package/dist/pointcloud/point-cloud-renderer.d.ts +10 -8
- package/dist/pointcloud/point-cloud-renderer.d.ts.map +1 -1
- package/dist/pointcloud/point-cloud-renderer.js +20 -31
- package/dist/pointcloud/point-cloud-renderer.js.map +1 -1
- package/dist/pointcloud/point-cloud-stream-lifecycle.d.ts +8 -1
- package/dist/pointcloud/point-cloud-stream-lifecycle.d.ts.map +1 -1
- package/dist/pointcloud/point-cloud-stream-lifecycle.js +17 -2
- package/dist/pointcloud/point-cloud-stream-lifecycle.js.map +1 -1
- package/dist/pointcloud/point-cloud-uniforms.d.ts +11 -0
- package/dist/pointcloud/point-cloud-uniforms.d.ts.map +1 -1
- package/dist/pointcloud/point-cloud-uniforms.js +8 -0
- package/dist/pointcloud/point-cloud-uniforms.js.map +1 -1
- package/dist/post-pass-chain.d.ts +2 -0
- package/dist/post-pass-chain.d.ts.map +1 -1
- package/dist/post-pass-chain.js +1 -1
- package/dist/post-pass-chain.js.map +1 -1
- package/dist/raycast-point-cloud-query.d.ts.map +1 -1
- package/dist/raycast-point-cloud-query.js +11 -1
- package/dist/raycast-point-cloud-query.js.map +1 -1
- package/dist/renderer-frame-timing.d.ts +21 -0
- package/dist/renderer-frame-timing.d.ts.map +1 -0
- package/dist/renderer-frame-timing.js +104 -0
- package/dist/renderer-frame-timing.js.map +1 -0
- package/dist/renderer-viewport.d.ts +13 -7
- package/dist/renderer-viewport.d.ts.map +1 -1
- package/dist/renderer-viewport.js +15 -7
- package/dist/renderer-viewport.js.map +1 -1
- package/dist/scene-batch-rebuild.d.ts +7 -0
- package/dist/scene-batch-rebuild.d.ts.map +1 -1
- package/dist/scene-batch-rebuild.js +12 -0
- package/dist/scene-batch-rebuild.js.map +1 -1
- package/dist/scene-contents.d.ts +3 -2
- package/dist/scene-contents.d.ts.map +1 -1
- package/dist/scene-flush.d.ts +43 -0
- package/dist/scene-flush.d.ts.map +1 -0
- package/dist/scene-flush.js +103 -0
- package/dist/scene-flush.js.map +1 -0
- package/dist/scene-geometry.d.ts.map +1 -1
- package/dist/scene-geometry.js +2 -0
- package/dist/scene-geometry.js.map +1 -1
- package/dist/scene-precision.d.ts +1 -1
- package/dist/scene-precision.d.ts.map +1 -1
- package/dist/scene-precision.js +11 -2
- package/dist/scene-precision.js.map +1 -1
- package/dist/scene.d.ts +10 -27
- package/dist/scene.d.ts.map +1 -1
- package/dist/scene.js +38 -107
- package/dist/scene.js.map +1 -1
- package/dist/selection-mask-pass.d.ts +2 -27
- package/dist/selection-mask-pass.d.ts.map +1 -1
- package/dist/selection-mask-pass.js +44 -39
- package/dist/selection-mask-pass.js.map +1 -1
- package/dist/selection-mask-pipelines.d.ts +3 -3
- package/dist/selection-mask-pipelines.d.ts.map +1 -1
- package/dist/selection-mask-pipelines.js +11 -8
- package/dist/selection-mask-pipelines.js.map +1 -1
- package/dist/shaders/depth-nudge.wgsl.d.ts +67 -0
- package/dist/shaders/depth-nudge.wgsl.d.ts.map +1 -0
- package/dist/shaders/depth-nudge.wgsl.js +130 -0
- package/dist/shaders/depth-nudge.wgsl.js.map +1 -0
- package/dist/shaders/ghost.wgsl.d.ts +2 -0
- package/dist/shaders/ghost.wgsl.d.ts.map +1 -0
- package/dist/shaders/ghost.wgsl.js +46 -0
- package/dist/shaders/ghost.wgsl.js.map +1 -0
- package/dist/shaders/main.wgsl.d.ts +1 -1
- package/dist/shaders/main.wgsl.d.ts.map +1 -1
- package/dist/shaders/main.wgsl.js +6 -4
- package/dist/shaders/main.wgsl.js.map +1 -1
- package/dist/shaders/section-2d-overlay.wgsl.d.ts +1 -16
- package/dist/shaders/section-2d-overlay.wgsl.d.ts.map +1 -1
- package/dist/shaders/section-2d-overlay.wgsl.js +6 -6
- package/dist/shaders/section-2d-overlay.wgsl.js.map +1 -1
- package/dist/shaders/selection-mask.wgsl.d.ts +2 -10
- package/dist/shaders/selection-mask.wgsl.d.ts.map +1 -1
- package/dist/shaders/selection-mask.wgsl.js +9 -42
- package/dist/shaders/selection-mask.wgsl.js.map +1 -1
- package/dist/shaders/symbolic-overlay.wgsl.d.ts +1 -1
- package/dist/shaders/symbolic-overlay.wgsl.d.ts.map +1 -1
- package/dist/shaders/symbolic-overlay.wgsl.js +5 -4
- package/dist/shaders/symbolic-overlay.wgsl.js.map +1 -1
- package/dist/shadow-pass.d.ts +0 -19
- package/dist/shadow-pass.d.ts.map +1 -1
- package/dist/shadow-pass.js +19 -0
- package/dist/shadow-pass.js.map +1 -1
- package/dist/test/frame-timing-device.d.ts +17 -0
- package/dist/test/frame-timing-device.d.ts.map +1 -0
- package/dist/test/frame-timing-device.js +70 -0
- package/dist/test/frame-timing-device.js.map +1 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/xray-alpha.d.ts +8 -0
- package/dist/xray-alpha.d.ts.map +1 -1
- package/dist/xray-alpha.js +23 -0
- package/dist/xray-alpha.js.map +1 -1
- package/package.json +4 -3
|
@@ -1,22 +1,33 @@
|
|
|
1
1
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
import { summarizeDeviationAssetsAsync, } from './deviation-statistics.js';
|
|
4
5
|
/**
|
|
5
|
-
* Read
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Read every computed point's signed distance back from the GPU, on demand.
|
|
7
|
+
* The normal compute and render path does no readback.
|
|
8
|
+
*
|
|
9
|
+
* The result is ONE `Float32Array` (4 bytes per computed point, the size of
|
|
10
|
+
* the GPU deviation buffers themselves) with each scan asset as a contiguous
|
|
11
|
+
* range, so per-asset and whole-run statistics share it without a second
|
|
12
|
+
* copy. One staging buffer is alive at a time, so VRAM grows by one chunk.
|
|
8
13
|
*/
|
|
9
|
-
export async function
|
|
10
|
-
const
|
|
14
|
+
export async function readDeviationDistances(device, nodes, wasComputed) {
|
|
15
|
+
const assets = [];
|
|
16
|
+
const plan = [];
|
|
17
|
+
let total = 0;
|
|
11
18
|
for (const node of nodes) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
const chunks = node.chunks.filter((chunk) => chunk.pointCount > 0 && wasComputed(chunk.deviationBuffer));
|
|
20
|
+
const count = chunks.reduce((sum, chunk) => sum + chunk.pointCount, 0);
|
|
21
|
+
if (count === 0)
|
|
22
|
+
continue;
|
|
23
|
+
assets.push({ expressId: node.meta.expressId, modelIndex: node.meta.modelIndex ?? 0, offset: total, count });
|
|
24
|
+
plan.push(chunks);
|
|
25
|
+
total += count;
|
|
26
|
+
}
|
|
27
|
+
const values = new Float32Array(total);
|
|
28
|
+
let cursor = 0;
|
|
29
|
+
for (const chunks of plan) {
|
|
30
|
+
for (const chunk of chunks) {
|
|
20
31
|
const size = chunk.pointCount * Float32Array.BYTES_PER_ELEMENT;
|
|
21
32
|
const staging = device.createBuffer({
|
|
22
33
|
size,
|
|
@@ -24,21 +35,13 @@ export async function readDeviationAssetStats(device, nodes, wasComputed) {
|
|
|
24
35
|
});
|
|
25
36
|
let mapped = false;
|
|
26
37
|
try {
|
|
27
|
-
const encoder = device.createCommandEncoder({ label: 'deviation-
|
|
38
|
+
const encoder = device.createCommandEncoder({ label: 'deviation-readback' });
|
|
28
39
|
encoder.copyBufferToBuffer(chunk.deviationBuffer, 0, staging, 0, size);
|
|
29
40
|
device.queue.submit([encoder.finish()]);
|
|
30
41
|
await staging.mapAsync(GPUMapMode.READ);
|
|
31
42
|
mapped = true;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
for (const value of values) {
|
|
35
|
-
if (!Number.isFinite(value))
|
|
36
|
-
continue;
|
|
37
|
-
finiteCount++;
|
|
38
|
-
sum += value;
|
|
39
|
-
min = Math.min(min, value);
|
|
40
|
-
max = Math.max(max, value);
|
|
41
|
-
}
|
|
43
|
+
values.set(new Float32Array(staging.getMappedRange(), 0, chunk.pointCount), cursor);
|
|
44
|
+
cursor += chunk.pointCount;
|
|
42
45
|
}
|
|
43
46
|
finally {
|
|
44
47
|
try {
|
|
@@ -50,18 +53,25 @@ export async function readDeviationAssetStats(device, nodes, wasComputed) {
|
|
|
50
53
|
}
|
|
51
54
|
}
|
|
52
55
|
}
|
|
53
|
-
if (count === 0)
|
|
54
|
-
continue;
|
|
55
|
-
results.push({
|
|
56
|
-
expressId: node.meta.expressId,
|
|
57
|
-
modelIndex: node.meta.modelIndex ?? 0,
|
|
58
|
-
pointsProcessed: count,
|
|
59
|
-
finitePoints: finiteCount,
|
|
60
|
-
minimumDeviation: finiteCount > 0 ? min : null,
|
|
61
|
-
maximumDeviation: finiteCount > 0 ? max : null,
|
|
62
|
-
meanDeviation: finiteCount > 0 ? sum / finiteCount : null,
|
|
63
|
-
});
|
|
64
56
|
}
|
|
65
|
-
return
|
|
57
|
+
return { values, assets };
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Per-scan-asset statistics over {@link readDeviationDistances}. Holds the
|
|
61
|
+
* readback (4 bytes per point) for the duration of the call; the statistics
|
|
62
|
+
* themselves add a fixed ~1 MiB and run in slices that yield to the event loop.
|
|
63
|
+
*/
|
|
64
|
+
export async function readDeviationAssetStats(device, nodes, wasComputed) {
|
|
65
|
+
const distances = await readDeviationDistances(device, nodes, wasComputed);
|
|
66
|
+
return (await summarizeDeviationAssetsAsync(distances)).map(({ expressId, modelIndex, statistics }) => ({
|
|
67
|
+
expressId,
|
|
68
|
+
modelIndex,
|
|
69
|
+
pointsProcessed: statistics.count,
|
|
70
|
+
finitePoints: statistics.validCount,
|
|
71
|
+
minimumDeviation: statistics.min,
|
|
72
|
+
maximumDeviation: statistics.max,
|
|
73
|
+
meanDeviation: statistics.mean,
|
|
74
|
+
statistics,
|
|
75
|
+
}));
|
|
66
76
|
}
|
|
67
77
|
//# sourceMappingURL=deviation-readback.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deviation-readback.js","sourceRoot":"","sources":["../../src/deviation/deviation-readback.ts"],"names":[],"mappings":"AAAA;;+DAE+D;
|
|
1
|
+
{"version":3,"file":"deviation-readback.js","sourceRoot":"","sources":["../../src/deviation/deviation-readback.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Linear passes behind the deviation summary statistics (#6872).
|
|
3
|
+
*
|
|
4
|
+
* Every figure is built from at most two O(n) passes over the readback, each
|
|
5
|
+
* of which can run in one call or in time-boxed slices that yield to the
|
|
6
|
+
* event loop, so a 25M-point cloud never blocks the main thread in one task.
|
|
7
|
+
*
|
|
8
|
+
* Exact percentiles without a copy: for a non-negative float32, the IEEE bit
|
|
9
|
+
* pattern read as an unsigned integer is monotone in the value. So |d|'s
|
|
10
|
+
* order statistics are the order statistics of `bits & 0x7fffffff`, found by
|
|
11
|
+
* a two-level radix select: pass 1 counts the high 16 bits (65,536 bins), the
|
|
12
|
+
* cumulative counts name the bucket holding each wanted rank, and pass 2
|
|
13
|
+
* counts the low 16 bits of the values in just those (at most three)
|
|
14
|
+
* buckets. Memory is four 256 KiB count tables, independent of n, and the
|
|
15
|
+
* input is never reordered or copied.
|
|
16
|
+
*/
|
|
17
|
+
import type { DeviationHistogram, DeviationHistogramRange } from './deviation-statistics.js';
|
|
18
|
+
/** A pass over `[start, end)`, then an optional step once the pass is done. */
|
|
19
|
+
export interface Phase {
|
|
20
|
+
scan(start: number, end: number): void;
|
|
21
|
+
done?(): void;
|
|
22
|
+
}
|
|
23
|
+
export declare function runPhases(length: number, phases: readonly Phase[]): void;
|
|
24
|
+
/**
|
|
25
|
+
* Run the phases in slices of at most ~{@link SLICE_BUDGET_MS} ms. Always
|
|
26
|
+
* yields once before starting, so the caller's task (a click, a render)
|
|
27
|
+
* finishes first and an abort raised in it is seen before any work.
|
|
28
|
+
*/
|
|
29
|
+
export declare function runPhasesSliced(length: number, phases: readonly Phase[], signal?: AbortSignal): Promise<void>;
|
|
30
|
+
export declare function checkMask(values: Float32Array, valid: ArrayLike<number> | undefined): void;
|
|
31
|
+
export declare function checkTolerance(tolerance: number): void;
|
|
32
|
+
/** Valid points with |d| ≤ tolerance. */
|
|
33
|
+
export declare class ToleranceCount implements Phase {
|
|
34
|
+
private readonly values;
|
|
35
|
+
private readonly tolerance;
|
|
36
|
+
private readonly valid?;
|
|
37
|
+
count: number;
|
|
38
|
+
constructor(values: Float32Array, tolerance: number, valid?: ArrayLike<number> | undefined);
|
|
39
|
+
scan(start: number, end: number): void;
|
|
40
|
+
}
|
|
41
|
+
/** Fixed bins over [center − h, center + h], the colour ramp's own range. */
|
|
42
|
+
export declare class HistogramBinner {
|
|
43
|
+
readonly histogram: DeviationHistogram;
|
|
44
|
+
private readonly last;
|
|
45
|
+
constructor(range: DeviationHistogramRange);
|
|
46
|
+
/** `v` must be finite. */
|
|
47
|
+
add(v: number): void;
|
|
48
|
+
}
|
|
49
|
+
/** Histogram as a standalone pass. */
|
|
50
|
+
export declare class HistogramPass implements Phase {
|
|
51
|
+
private readonly values;
|
|
52
|
+
private readonly valid?;
|
|
53
|
+
readonly binner: HistogramBinner;
|
|
54
|
+
constructor(values: Float32Array, range: DeviationHistogramRange, valid?: ArrayLike<number> | undefined);
|
|
55
|
+
scan(start: number, end: number): void;
|
|
56
|
+
}
|
|
57
|
+
/** Neumaier compensated sum: exact-to-rounding for mixed magnitudes. */
|
|
58
|
+
declare class CompensatedSum {
|
|
59
|
+
private sum;
|
|
60
|
+
private compensation;
|
|
61
|
+
add(x: number): void;
|
|
62
|
+
value(): number;
|
|
63
|
+
}
|
|
64
|
+
/** Nearest-rank index (0-based) of the `percent`-th percentile of n values. */
|
|
65
|
+
export declare function nearestRank(percent: number, n: number): number;
|
|
66
|
+
/** Percentiles of |d| reported, in percent. */
|
|
67
|
+
export declare const PERCENTILES: readonly [50, 95, 99];
|
|
68
|
+
export interface MomentOptions {
|
|
69
|
+
valid?: ArrayLike<number>;
|
|
70
|
+
tolerance?: number;
|
|
71
|
+
/** Compared against `Math.fround(clipRange)`: the shader pegs in float32. */
|
|
72
|
+
clipRange?: number;
|
|
73
|
+
histogram?: DeviationHistogramRange;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The two passes of a full summary: moments, extremes, counts and the
|
|
77
|
+
* high-bits table first; then σ about the now-known mean, and the low bits
|
|
78
|
+
* of the percentile buckets.
|
|
79
|
+
*/
|
|
80
|
+
export declare class StatisticsPasses {
|
|
81
|
+
private readonly values;
|
|
82
|
+
private readonly options;
|
|
83
|
+
readonly phases: readonly Phase[];
|
|
84
|
+
n: number;
|
|
85
|
+
within: number;
|
|
86
|
+
clipped: number;
|
|
87
|
+
min: number;
|
|
88
|
+
max: number;
|
|
89
|
+
maxAbs: number;
|
|
90
|
+
mean: number;
|
|
91
|
+
readonly sum: CompensatedSum;
|
|
92
|
+
readonly sumAbs: CompensatedSum;
|
|
93
|
+
readonly sumSq: CompensatedSum;
|
|
94
|
+
readonly residual: CompensatedSum;
|
|
95
|
+
readonly binner: HistogramBinner | null;
|
|
96
|
+
/** |d| for each of {@link PERCENTILES}, set after the second pass. */
|
|
97
|
+
readonly percentiles: number[];
|
|
98
|
+
private readonly bits;
|
|
99
|
+
private readonly high;
|
|
100
|
+
private readonly clipAt;
|
|
101
|
+
/** Per wanted rank: its high-bits bucket and the rank within that bucket. */
|
|
102
|
+
private targets;
|
|
103
|
+
constructor(values: Float32Array, options: MomentOptions);
|
|
104
|
+
private scanMoments;
|
|
105
|
+
/** Locate each wanted rank's high-bits bucket from the cumulative counts. */
|
|
106
|
+
private plan;
|
|
107
|
+
private scanResiduals;
|
|
108
|
+
private resolve;
|
|
109
|
+
}
|
|
110
|
+
export {};
|
|
111
|
+
//# sourceMappingURL=deviation-statistics-kernel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deviation-statistics-kernel.d.ts","sourceRoot":"","sources":["../../src/deviation/deviation-statistics-kernel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
const ABS_MASK = 0x7fffffff;
|
|
5
|
+
/** |d| bit patterns at or above this are ±Infinity or NaN. */
|
|
6
|
+
const NON_FINITE = 0x7f800000;
|
|
7
|
+
const RADIX = 1 << 16;
|
|
8
|
+
const LOW_MASK = RADIX - 1;
|
|
9
|
+
/** Elements per slice between clock checks. */
|
|
10
|
+
const SLICE = 1 << 16;
|
|
11
|
+
/** Longest stretch of work before yielding, ms. */
|
|
12
|
+
const SLICE_BUDGET_MS = 8;
|
|
13
|
+
export function runPhases(length, phases) {
|
|
14
|
+
for (const phase of phases) {
|
|
15
|
+
phase.scan(0, length);
|
|
16
|
+
phase.done?.();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Yield through a MessageChannel task, not `scheduler.yield()`: that
|
|
21
|
+
* continuation runs ahead of already-queued normal tasks, React renders
|
|
22
|
+
* included, so a loop yielding through it still starves the UI (the same
|
|
23
|
+
* reasoning as the IDS validator's yield).
|
|
24
|
+
*/
|
|
25
|
+
function yieldToEventLoop() {
|
|
26
|
+
return new Promise((resolve) => {
|
|
27
|
+
const channel = new MessageChannel();
|
|
28
|
+
channel.port1.onmessage = () => {
|
|
29
|
+
// An open port keeps a Node process alive.
|
|
30
|
+
channel.port1.close();
|
|
31
|
+
channel.port2.close();
|
|
32
|
+
resolve();
|
|
33
|
+
};
|
|
34
|
+
channel.port2.postMessage(null);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Run the phases in slices of at most ~{@link SLICE_BUDGET_MS} ms. Always
|
|
39
|
+
* yields once before starting, so the caller's task (a click, a render)
|
|
40
|
+
* finishes first and an abort raised in it is seen before any work.
|
|
41
|
+
*/
|
|
42
|
+
export async function runPhasesSliced(length, phases, signal) {
|
|
43
|
+
await yieldToEventLoop();
|
|
44
|
+
signal?.throwIfAborted();
|
|
45
|
+
let sliceStart = performance.now();
|
|
46
|
+
for (const phase of phases) {
|
|
47
|
+
for (let start = 0; start < length;) {
|
|
48
|
+
const end = Math.min(length, start + SLICE);
|
|
49
|
+
phase.scan(start, end);
|
|
50
|
+
start = end;
|
|
51
|
+
if (performance.now() - sliceStart >= SLICE_BUDGET_MS) {
|
|
52
|
+
await yieldToEventLoop();
|
|
53
|
+
signal?.throwIfAborted();
|
|
54
|
+
sliceStart = performance.now();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
phase.done?.();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export function checkMask(values, valid) {
|
|
61
|
+
if (valid && valid.length !== values.length) {
|
|
62
|
+
throw new RangeError(`deviation statistics: mask length ${valid.length} != values length ${values.length}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export function checkTolerance(tolerance) {
|
|
66
|
+
if (!(tolerance >= 0) || !Number.isFinite(tolerance)) {
|
|
67
|
+
throw new RangeError(`deviation statistics: tolerance must be a finite value ≥ 0, got ${tolerance}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function bitsOf(values) {
|
|
71
|
+
return new Uint32Array(values.buffer, values.byteOffset, values.length);
|
|
72
|
+
}
|
|
73
|
+
const bitCast = new Uint32Array(1);
|
|
74
|
+
const floatCast = new Float32Array(bitCast.buffer);
|
|
75
|
+
function floatFromBits(bits) {
|
|
76
|
+
bitCast[0] = bits;
|
|
77
|
+
return floatCast[0];
|
|
78
|
+
}
|
|
79
|
+
/** Valid points with |d| ≤ tolerance. */
|
|
80
|
+
export class ToleranceCount {
|
|
81
|
+
values;
|
|
82
|
+
tolerance;
|
|
83
|
+
valid;
|
|
84
|
+
count = 0;
|
|
85
|
+
constructor(values, tolerance, valid) {
|
|
86
|
+
this.values = values;
|
|
87
|
+
this.tolerance = tolerance;
|
|
88
|
+
this.valid = valid;
|
|
89
|
+
checkMask(values, valid);
|
|
90
|
+
checkTolerance(tolerance);
|
|
91
|
+
}
|
|
92
|
+
scan(start, end) {
|
|
93
|
+
const { values, tolerance, valid } = this;
|
|
94
|
+
let count = 0;
|
|
95
|
+
for (let i = start; i < end; i++) {
|
|
96
|
+
// NaN and ±Infinity fail the comparison on their own.
|
|
97
|
+
if (Math.abs(values[i]) <= tolerance && (!valid || valid[i] !== 0))
|
|
98
|
+
count++;
|
|
99
|
+
}
|
|
100
|
+
this.count += count;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/** Fixed bins over [center − h, center + h], the colour ramp's own range. */
|
|
104
|
+
export class HistogramBinner {
|
|
105
|
+
histogram;
|
|
106
|
+
last;
|
|
107
|
+
constructor(range) {
|
|
108
|
+
const { center, halfRange, bins } = range;
|
|
109
|
+
if (!(halfRange > 0) || !Number.isFinite(halfRange) || !Number.isFinite(center)) {
|
|
110
|
+
throw new RangeError(`deviation histogram: halfRange must be finite and > 0, got ${halfRange}`);
|
|
111
|
+
}
|
|
112
|
+
if (!Number.isInteger(bins) || bins < 1) {
|
|
113
|
+
throw new RangeError(`deviation histogram: bins must be a positive integer, got ${bins}`);
|
|
114
|
+
}
|
|
115
|
+
this.histogram = {
|
|
116
|
+
min: center - halfRange, max: center + halfRange, binWidth: (2 * halfRange) / bins,
|
|
117
|
+
counts: new Array(bins).fill(0), below: 0, above: 0,
|
|
118
|
+
};
|
|
119
|
+
this.last = bins - 1;
|
|
120
|
+
}
|
|
121
|
+
/** `v` must be finite. */
|
|
122
|
+
add(v) {
|
|
123
|
+
const h = this.histogram;
|
|
124
|
+
if (v < h.min)
|
|
125
|
+
h.below++;
|
|
126
|
+
else if (v > h.max)
|
|
127
|
+
h.above++;
|
|
128
|
+
else
|
|
129
|
+
h.counts[Math.min(this.last, Math.floor((v - h.min) / h.binWidth))]++;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/** Histogram as a standalone pass. */
|
|
133
|
+
export class HistogramPass {
|
|
134
|
+
values;
|
|
135
|
+
valid;
|
|
136
|
+
binner;
|
|
137
|
+
constructor(values, range, valid) {
|
|
138
|
+
this.values = values;
|
|
139
|
+
this.valid = valid;
|
|
140
|
+
checkMask(values, valid);
|
|
141
|
+
this.binner = new HistogramBinner(range);
|
|
142
|
+
}
|
|
143
|
+
scan(start, end) {
|
|
144
|
+
const { values, valid, binner } = this;
|
|
145
|
+
for (let i = start; i < end; i++) {
|
|
146
|
+
const v = values[i];
|
|
147
|
+
if (Number.isFinite(v) && (!valid || valid[i] !== 0))
|
|
148
|
+
binner.add(v);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/** Neumaier compensated sum: exact-to-rounding for mixed magnitudes. */
|
|
153
|
+
class CompensatedSum {
|
|
154
|
+
sum = 0;
|
|
155
|
+
compensation = 0;
|
|
156
|
+
add(x) {
|
|
157
|
+
const t = this.sum + x;
|
|
158
|
+
if (Math.abs(this.sum) >= Math.abs(x))
|
|
159
|
+
this.compensation += (this.sum - t) + x;
|
|
160
|
+
else
|
|
161
|
+
this.compensation += (x - t) + this.sum;
|
|
162
|
+
this.sum = t;
|
|
163
|
+
}
|
|
164
|
+
value() {
|
|
165
|
+
return this.sum + this.compensation;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/** Nearest-rank index (0-based) of the `percent`-th percentile of n values. */
|
|
169
|
+
export function nearestRank(percent, n) {
|
|
170
|
+
return Math.min(n - 1, Math.max(0, Math.ceil((percent * n) / 100) - 1));
|
|
171
|
+
}
|
|
172
|
+
/** Percentiles of |d| reported, in percent. */
|
|
173
|
+
export const PERCENTILES = [50, 95, 99];
|
|
174
|
+
/**
|
|
175
|
+
* The two passes of a full summary: moments, extremes, counts and the
|
|
176
|
+
* high-bits table first; then σ about the now-known mean, and the low bits
|
|
177
|
+
* of the percentile buckets.
|
|
178
|
+
*/
|
|
179
|
+
export class StatisticsPasses {
|
|
180
|
+
values;
|
|
181
|
+
options;
|
|
182
|
+
phases;
|
|
183
|
+
n = 0;
|
|
184
|
+
within = 0;
|
|
185
|
+
clipped = 0;
|
|
186
|
+
min = Infinity;
|
|
187
|
+
max = -Infinity;
|
|
188
|
+
maxAbs = 0;
|
|
189
|
+
mean = 0;
|
|
190
|
+
sum = new CompensatedSum();
|
|
191
|
+
sumAbs = new CompensatedSum();
|
|
192
|
+
sumSq = new CompensatedSum();
|
|
193
|
+
residual = new CompensatedSum();
|
|
194
|
+
binner;
|
|
195
|
+
/** |d| for each of {@link PERCENTILES}, set after the second pass. */
|
|
196
|
+
percentiles = [];
|
|
197
|
+
bits;
|
|
198
|
+
high = new Uint32Array(RADIX);
|
|
199
|
+
clipAt;
|
|
200
|
+
/** Per wanted rank: its high-bits bucket and the rank within that bucket. */
|
|
201
|
+
targets = [];
|
|
202
|
+
constructor(values, options) {
|
|
203
|
+
this.values = values;
|
|
204
|
+
this.options = options;
|
|
205
|
+
checkMask(values, options.valid);
|
|
206
|
+
if (options.tolerance !== undefined)
|
|
207
|
+
checkTolerance(options.tolerance);
|
|
208
|
+
this.binner = options.histogram ? new HistogramBinner(options.histogram) : null;
|
|
209
|
+
this.clipAt = options.clipRange === undefined ? undefined : Math.fround(options.clipRange);
|
|
210
|
+
this.bits = bitsOf(values);
|
|
211
|
+
this.phases = [
|
|
212
|
+
{ scan: (s, e) => this.scanMoments(s, e), done: () => this.plan() },
|
|
213
|
+
{ scan: (s, e) => this.scanResiduals(s, e), done: () => this.resolve() },
|
|
214
|
+
];
|
|
215
|
+
}
|
|
216
|
+
scanMoments(start, end) {
|
|
217
|
+
const { values, bits, high, binner, sum, sumAbs, sumSq, clipAt } = this;
|
|
218
|
+
const { valid } = this.options;
|
|
219
|
+
// Absent options compare against NaN / +Infinity, so they never count.
|
|
220
|
+
const tolerance = this.options.tolerance ?? Number.NaN;
|
|
221
|
+
const clip = clipAt ?? Number.POSITIVE_INFINITY;
|
|
222
|
+
let { n, min, max, maxAbs, within, clipped } = this;
|
|
223
|
+
for (let i = start; i < end; i++) {
|
|
224
|
+
const b = bits[i] & ABS_MASK;
|
|
225
|
+
if (b >= NON_FINITE || (valid && valid[i] === 0))
|
|
226
|
+
continue;
|
|
227
|
+
const v = values[i];
|
|
228
|
+
const abs = Math.abs(v);
|
|
229
|
+
n++;
|
|
230
|
+
high[b >>> 16]++;
|
|
231
|
+
sum.add(v);
|
|
232
|
+
sumAbs.add(abs);
|
|
233
|
+
sumSq.add(v * v);
|
|
234
|
+
if (v < min)
|
|
235
|
+
min = v;
|
|
236
|
+
if (v > max)
|
|
237
|
+
max = v;
|
|
238
|
+
if (abs > maxAbs)
|
|
239
|
+
maxAbs = abs;
|
|
240
|
+
if (abs <= tolerance)
|
|
241
|
+
within++;
|
|
242
|
+
if (abs >= clip)
|
|
243
|
+
clipped++;
|
|
244
|
+
binner?.add(v);
|
|
245
|
+
}
|
|
246
|
+
Object.assign(this, { n, min, max, maxAbs, within, clipped });
|
|
247
|
+
}
|
|
248
|
+
/** Locate each wanted rank's high-bits bucket from the cumulative counts. */
|
|
249
|
+
plan() {
|
|
250
|
+
const n = this.n;
|
|
251
|
+
if (n === 0)
|
|
252
|
+
return;
|
|
253
|
+
this.mean = this.sum.value() / n;
|
|
254
|
+
const lows = new Map();
|
|
255
|
+
let bucket = 0;
|
|
256
|
+
let below = 0;
|
|
257
|
+
// Ranks ascend with the percentiles, so one forward walk serves all.
|
|
258
|
+
for (const percent of PERCENTILES) {
|
|
259
|
+
const rank = nearestRank(percent, n);
|
|
260
|
+
while (below + this.high[bucket] <= rank)
|
|
261
|
+
below += this.high[bucket++];
|
|
262
|
+
let low = lows.get(bucket);
|
|
263
|
+
if (!low)
|
|
264
|
+
lows.set(bucket, low = new Uint32Array(RADIX));
|
|
265
|
+
this.targets.push({ bucket, rank: rank - below, low });
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
scanResiduals(start, end) {
|
|
269
|
+
if (this.n === 0)
|
|
270
|
+
return;
|
|
271
|
+
const { values, bits, residual, mean } = this;
|
|
272
|
+
const { valid } = this.options;
|
|
273
|
+
// At most three distinct buckets; unused slots never match (> 0xffff).
|
|
274
|
+
const [t0, t1, t2] = [0, 1, 2].map((k) => this.targets[k]);
|
|
275
|
+
const b0 = t0.bucket, b1 = t1.bucket === b0 ? -1 : t1.bucket;
|
|
276
|
+
const b2 = t2.bucket === b0 || t2.bucket === t1.bucket ? -1 : t2.bucket;
|
|
277
|
+
const l0 = t0.low, l1 = t1.low, l2 = t2.low;
|
|
278
|
+
for (let i = start; i < end; i++) {
|
|
279
|
+
const b = bits[i] & ABS_MASK;
|
|
280
|
+
if (b >= NON_FINITE || (valid && valid[i] === 0))
|
|
281
|
+
continue;
|
|
282
|
+
const d = values[i] - mean;
|
|
283
|
+
residual.add(d * d);
|
|
284
|
+
const h = b >>> 16;
|
|
285
|
+
if (h === b0)
|
|
286
|
+
l0[b & LOW_MASK]++;
|
|
287
|
+
else if (h === b1)
|
|
288
|
+
l1[b & LOW_MASK]++;
|
|
289
|
+
else if (h === b2)
|
|
290
|
+
l2[b & LOW_MASK]++;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
resolve() {
|
|
294
|
+
for (const { bucket, rank, low } of this.targets) {
|
|
295
|
+
let below = 0;
|
|
296
|
+
let l = 0;
|
|
297
|
+
while (below + low[l] <= rank)
|
|
298
|
+
below += low[l++];
|
|
299
|
+
this.percentiles.push(floatFromBits((bucket << 16) | l));
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=deviation-statistics-kernel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deviation-statistics-kernel.js","sourceRoot":"","sources":["../../src/deviation/deviation-statistics-kernel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/** A bin layout that lines up with the deviation colour ramp. */
|
|
2
|
+
export interface DeviationHistogramRange {
|
|
3
|
+
/** Ramp centre in metres (`deviationRange.centerOffset`). */
|
|
4
|
+
center: number;
|
|
5
|
+
/** Ramp half-width in metres; bins span [center − h, center + h]. */
|
|
6
|
+
halfRange: number;
|
|
7
|
+
/** Number of equal-width bins. */
|
|
8
|
+
bins: number;
|
|
9
|
+
}
|
|
10
|
+
export interface DeviationHistogram {
|
|
11
|
+
/** Lower edge of the first bin, metres. */
|
|
12
|
+
min: number;
|
|
13
|
+
/** Upper edge of the last bin (inclusive), metres. */
|
|
14
|
+
max: number;
|
|
15
|
+
binWidth: number;
|
|
16
|
+
/** Valid points per bin, low → high. */
|
|
17
|
+
counts: number[];
|
|
18
|
+
/** Valid points below `min` / above `max` (the ramp's saturated ends). */
|
|
19
|
+
below: number;
|
|
20
|
+
above: number;
|
|
21
|
+
}
|
|
22
|
+
export interface DeviationToleranceShare {
|
|
23
|
+
tolerance: number;
|
|
24
|
+
/** Valid points with |d| ≤ tolerance. */
|
|
25
|
+
count: number;
|
|
26
|
+
/** `count / validCount`; null when no point is valid. */
|
|
27
|
+
share: number | null;
|
|
28
|
+
}
|
|
29
|
+
export interface DeviationStatistics {
|
|
30
|
+
/** Every input point, valid or not. */
|
|
31
|
+
count: number;
|
|
32
|
+
/** Points that are unmasked and finite; every other figure is over these. */
|
|
33
|
+
validCount: number;
|
|
34
|
+
/** Valid points with |d| ≥ `clipRange` (pegged by the compute clip). */
|
|
35
|
+
clippedCount: number;
|
|
36
|
+
min: number | null;
|
|
37
|
+
max: number | null;
|
|
38
|
+
/** Signed mean. */
|
|
39
|
+
mean: number | null;
|
|
40
|
+
meanAbs: number | null;
|
|
41
|
+
rms: number | null;
|
|
42
|
+
/** Population standard deviation of the signed values. */
|
|
43
|
+
stdDev: number | null;
|
|
44
|
+
p50Abs: number | null;
|
|
45
|
+
p95Abs: number | null;
|
|
46
|
+
p99Abs: number | null;
|
|
47
|
+
maxAbs: number | null;
|
|
48
|
+
withinTolerance: DeviationToleranceShare | null;
|
|
49
|
+
histogram: DeviationHistogram | null;
|
|
50
|
+
}
|
|
51
|
+
export interface DeviationStatisticsOptions {
|
|
52
|
+
/** Per-point validity; zero excludes the point. Must match `values.length`. */
|
|
53
|
+
valid?: ArrayLike<number>;
|
|
54
|
+
/** Report the share of points with |d| ≤ tolerance (metres, ≥ 0). */
|
|
55
|
+
tolerance?: number;
|
|
56
|
+
/**
|
|
57
|
+
* The `maxRange` the compute pass clamped to, to count pegged points. The
|
|
58
|
+
* shader pegs at the float32 value, so the comparison is against
|
|
59
|
+
* `Math.fround(clipRange)`: 0.7 m pegs at 0.699999988 m.
|
|
60
|
+
*/
|
|
61
|
+
clipRange?: number;
|
|
62
|
+
histogram?: DeviationHistogramRange;
|
|
63
|
+
}
|
|
64
|
+
/** One scan asset's slice of a shared readback array. */
|
|
65
|
+
export interface DeviationAssetRange {
|
|
66
|
+
expressId: number;
|
|
67
|
+
modelIndex: number;
|
|
68
|
+
offset: number;
|
|
69
|
+
count: number;
|
|
70
|
+
}
|
|
71
|
+
/** Every computed point's signed distance, grouped by scan asset. */
|
|
72
|
+
export interface DeviationDistances {
|
|
73
|
+
values: Float32Array;
|
|
74
|
+
assets: DeviationAssetRange[];
|
|
75
|
+
}
|
|
76
|
+
/** Cancellation for the sliced `…Async` variants. */
|
|
77
|
+
export interface DeviationAsyncOptions {
|
|
78
|
+
/** Aborting rejects with the signal's reason at the next slice boundary. */
|
|
79
|
+
signal?: AbortSignal;
|
|
80
|
+
}
|
|
81
|
+
export interface DeviationAssetSummary {
|
|
82
|
+
expressId: number;
|
|
83
|
+
modelIndex: number;
|
|
84
|
+
statistics: DeviationStatistics;
|
|
85
|
+
}
|
|
86
|
+
/** Full summary in one synchronous call: two O(n) passes, no copy. */
|
|
87
|
+
export declare function computeDeviationStatistics(values: Float32Array, options?: DeviationStatisticsOptions): DeviationStatistics;
|
|
88
|
+
/** {@link computeDeviationStatistics} in time-boxed slices that yield to the event loop. */
|
|
89
|
+
export declare function computeDeviationStatisticsAsync(values: Float32Array, options?: DeviationStatisticsOptions & DeviationAsyncOptions): Promise<DeviationStatistics>;
|
|
90
|
+
/** Valid points with |d| ≤ tolerance: one O(n) pass in yielding slices, no allocation. */
|
|
91
|
+
export declare function countWithinToleranceAsync(values: Float32Array, tolerance: number, options?: {
|
|
92
|
+
valid?: ArrayLike<number>;
|
|
93
|
+
} & DeviationAsyncOptions): Promise<number>;
|
|
94
|
+
/** Fixed-bin histogram over the ramp range: one O(n) pass in yielding slices. */
|
|
95
|
+
export declare function deviationHistogramAsync(values: Float32Array, range: DeviationHistogramRange, options?: {
|
|
96
|
+
valid?: ArrayLike<number>;
|
|
97
|
+
} & DeviationAsyncOptions): Promise<DeviationHistogram>;
|
|
98
|
+
/** Per-asset statistics over each asset's slice of one readback array, in yielding slices. */
|
|
99
|
+
export declare function summarizeDeviationAssetsAsync(distances: DeviationDistances, options?: Omit<DeviationStatisticsOptions, 'valid'> & DeviationAsyncOptions): Promise<DeviationAssetSummary[]>;
|
|
100
|
+
//# sourceMappingURL=deviation-statistics.d.ts.map
|