@ifc-lite/pointcloud 0.3.3 → 0.3.5
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 +15 -2
- package/dist/formats/e57-decode.d.ts +86 -1
- package/dist/formats/e57-decode.d.ts.map +1 -1
- package/dist/formats/e57-decode.js +176 -114
- package/dist/formats/e57-decode.js.map +1 -1
- package/dist/formats/e57-page.d.ts +7 -0
- package/dist/formats/e57-page.d.ts.map +1 -1
- package/dist/formats/e57-page.js +12 -0
- package/dist/formats/e57-page.js.map +1 -1
- package/dist/streaming/e57-source.d.ts +53 -3
- package/dist/streaming/e57-source.d.ts.map +1 -1
- package/dist/streaming/e57-source.js +365 -48
- package/dist/streaming/e57-source.js.map +1 -1
- package/dist/streaming/inline-worker.js +1 -1
- package/package.json +3 -3
|
@@ -1,17 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* E57 (ASTM E2807-11) streaming source.
|
|
3
|
+
*
|
|
4
|
+
* Unlike a naive "read the whole file, then decode" approach — which
|
|
5
|
+
* allocates the entire file (plus a CRC-stripped copy of it) in one
|
|
6
|
+
* `ArrayBuffer` and dies with "Array buffer allocation failed" on
|
|
7
|
+
* multi-GB scans — this source reads the binary CompressedVector
|
|
8
|
+
* section incrementally:
|
|
9
|
+
*
|
|
10
|
+
* open(): read the 48-byte FileHeader + the (small) XML section, then
|
|
11
|
+
* resolve every Data3D scan's binary data offset by reading
|
|
12
|
+
* just its 32-byte CompressedVector section header.
|
|
13
|
+
* next(): read a bounded LOGICAL window from the blob (page-CRC
|
|
14
|
+
* stripped on the fly), walk the DataPackets inside it,
|
|
15
|
+
* apply stride + per-scan pose, and emit a decoded chunk.
|
|
16
|
+
*
|
|
17
|
+
* Peak memory is therefore ~one window (≤ 16 MiB) plus one output chunk,
|
|
18
|
+
* not the whole file. The per-packet decode primitives are shared with
|
|
19
|
+
* the whole-file `decodeE57Scan` so both paths agree byte-for-byte.
|
|
20
|
+
*/
|
|
1
21
|
import type { DecodedPointChunk } from '../types.js';
|
|
2
22
|
import type { DownsampleHint, PointSourceInfo, StreamingPointSource } from './types.js';
|
|
3
23
|
export declare class E57StreamingSource implements StreamingPointSource {
|
|
4
|
-
private
|
|
24
|
+
private bytes;
|
|
5
25
|
private downsample;
|
|
6
26
|
private label?;
|
|
7
|
-
|
|
8
|
-
private
|
|
27
|
+
/** Test hook: force a fixed window size to exercise straddle/re-read. */
|
|
28
|
+
private windowBytesOverride?;
|
|
29
|
+
private opened;
|
|
30
|
+
private pageSize;
|
|
31
|
+
private fileLogicalSize;
|
|
32
|
+
private scans;
|
|
33
|
+
private totalPointCount;
|
|
34
|
+
private hasColor;
|
|
35
|
+
private hasIntensity;
|
|
36
|
+
private hasClassification;
|
|
37
|
+
private scanIdx;
|
|
38
|
+
private logCursor;
|
|
39
|
+
/** Records consumed of the CURRENT scan (resets at each scan boundary). */
|
|
40
|
+
private recordsWritten;
|
|
41
|
+
/**
|
|
42
|
+
* Cumulative declared `recordCount` of every scan BEFORE the current one.
|
|
43
|
+
* `scanRecordBase + recordsWritten` is the record's index in the merged
|
|
44
|
+
* multi-scan cloud — the phase the stride must align to so downsampling
|
|
45
|
+
* matches the whole-file decoder (which strides the merged cloud globally)
|
|
46
|
+
* rather than restarting the stride phase inside each scan.
|
|
47
|
+
*/
|
|
48
|
+
private scanRecordBase;
|
|
9
49
|
constructor(blob: Blob, options?: {
|
|
10
50
|
label?: string;
|
|
11
51
|
downsample?: DownsampleHint;
|
|
52
|
+
windowBytes?: number;
|
|
12
53
|
});
|
|
13
54
|
open(signal?: AbortSignal): Promise<PointSourceInfo>;
|
|
14
55
|
next(maxPoints: number, signal?: AbortSignal): Promise<DecodedPointChunk | null>;
|
|
15
56
|
close(): void;
|
|
57
|
+
/**
|
|
58
|
+
* Resolve a scan's binary data offset by reading its 32-byte
|
|
59
|
+
* CompressedVector section header (E57 §6.4.2). The XML's `fileOffset`
|
|
60
|
+
* points at this section header, not the first DataPacket.
|
|
61
|
+
*/
|
|
62
|
+
private resolveDataOffset;
|
|
63
|
+
/** Logical bytes to pull on the next read — bounded and EOF-clamped. */
|
|
64
|
+
private computeWindowLen;
|
|
65
|
+
private toInfo;
|
|
16
66
|
}
|
|
17
67
|
//# sourceMappingURL=e57-source.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"e57-source.d.ts","sourceRoot":"","sources":["../../src/streaming/e57-source.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"e57-source.d.ts","sourceRoot":"","sources":["../../src/streaming/e57-source.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAuBrD,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,oBAAoB,EACrB,MAAM,YAAY,CAAC;AA4BpB,qBAAa,kBAAmB,YAAW,oBAAoB;IAC7D,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,KAAK,CAAC,CAAS;IACvB,yEAAyE;IACzE,OAAO,CAAC,mBAAmB,CAAC,CAAS;IAErC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,iBAAiB,CAAS;IAGlC,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,SAAS,CAAK;IACtB,2EAA2E;IAC3E,OAAO,CAAC,cAAc,CAAK;IAC3B;;;;;;OAMG;IACH,OAAO,CAAC,cAAc,CAAK;gBAGzB,IAAI,EAAE,IAAI,EACV,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,cAAc,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAO;IAQ/E,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC;IAwDpD,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAwHtF,KAAK,IAAI,IAAI;IASb;;;;OAIG;YACW,iBAAiB;IAwB/B,wEAAwE;IACxE,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,MAAM;CAiBf"}
|
|
@@ -1,85 +1,402 @@
|
|
|
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 {
|
|
4
|
+
import { computeBBox, decodeE57Packet, peekPacketHeader, resolveScanFields, } from '../formats/e57-decode.js';
|
|
5
|
+
import { applyPoseInPlace } from '../formats/e57.js';
|
|
6
|
+
import { parseE57FileHeader, physicalToLogical, readU64LE, stripPageCrc, } from '../formats/e57-page.js';
|
|
7
|
+
import { parseE57Xml, } from '../formats/e57-xml.js';
|
|
8
|
+
import { BlobByteSource } from './blob-source.js';
|
|
9
|
+
/** 1 MiB — always ≥ any single packet (E57 packets are ≤ 64 KiB). */
|
|
10
|
+
const MIN_WINDOW_BYTES = 1 << 20;
|
|
11
|
+
/** 16 MiB — caps peak window memory per `next()`. */
|
|
12
|
+
const MAX_WINDOW_BYTES = 16 << 20;
|
|
5
13
|
export class E57StreamingSource {
|
|
6
|
-
|
|
14
|
+
bytes;
|
|
7
15
|
downsample;
|
|
8
16
|
label;
|
|
9
|
-
|
|
10
|
-
|
|
17
|
+
/** Test hook: force a fixed window size to exercise straddle/re-read. */
|
|
18
|
+
windowBytesOverride;
|
|
19
|
+
opened = false;
|
|
20
|
+
pageSize = 1024;
|
|
21
|
+
fileLogicalSize = 0;
|
|
22
|
+
scans = [];
|
|
23
|
+
totalPointCount = 0;
|
|
24
|
+
hasColor = false;
|
|
25
|
+
hasIntensity = false;
|
|
26
|
+
hasClassification = false;
|
|
27
|
+
// Streaming cursor.
|
|
28
|
+
scanIdx = 0;
|
|
29
|
+
logCursor = 0;
|
|
30
|
+
/** Records consumed of the CURRENT scan (resets at each scan boundary). */
|
|
31
|
+
recordsWritten = 0;
|
|
32
|
+
/**
|
|
33
|
+
* Cumulative declared `recordCount` of every scan BEFORE the current one.
|
|
34
|
+
* `scanRecordBase + recordsWritten` is the record's index in the merged
|
|
35
|
+
* multi-scan cloud — the phase the stride must align to so downsampling
|
|
36
|
+
* matches the whole-file decoder (which strides the merged cloud globally)
|
|
37
|
+
* rather than restarting the stride phase inside each scan.
|
|
38
|
+
*/
|
|
39
|
+
scanRecordBase = 0;
|
|
11
40
|
constructor(blob, options = {}) {
|
|
12
|
-
this.
|
|
41
|
+
this.bytes = new BlobByteSource(blob);
|
|
13
42
|
this.downsample = options.downsample ?? { stride: 1 };
|
|
14
43
|
this.label = options.label;
|
|
44
|
+
this.windowBytesOverride = options.windowBytes;
|
|
15
45
|
}
|
|
16
46
|
async open(signal) {
|
|
47
|
+
if (this.opened)
|
|
48
|
+
return this.toInfo();
|
|
17
49
|
abortIfAborted(signal);
|
|
18
|
-
const
|
|
50
|
+
const headerBytes = await this.bytes.read(0, 64);
|
|
19
51
|
abortIfAborted(signal);
|
|
20
|
-
const
|
|
21
|
-
if (
|
|
52
|
+
const header = parseE57FileHeader(headerBytes);
|
|
53
|
+
if (header.pageSize <= 4) {
|
|
54
|
+
throw new Error(`E57: invalid pageSize ${header.pageSize}`);
|
|
55
|
+
}
|
|
56
|
+
this.pageSize = header.pageSize;
|
|
57
|
+
// Prefer the header's logical size; fall back to the blob size mapped
|
|
58
|
+
// through the page math when a producer leaves fileLogicalSize at 0.
|
|
59
|
+
this.fileLogicalSize = header.fileLogicalSize > 0
|
|
60
|
+
? header.fileLogicalSize
|
|
61
|
+
: physicalToLogical(this.bytes.size, header.pageSize);
|
|
62
|
+
const xmlLogical = await readLogicalRange(this.bytes, header.xmlLogicalOffset, header.xmlLogicalLength, header.pageSize);
|
|
63
|
+
abortIfAborted(signal);
|
|
64
|
+
const xmlText = new TextDecoder().decode(xmlLogical);
|
|
65
|
+
const entries = parseE57Xml(xmlText);
|
|
66
|
+
if (entries.length === 0) {
|
|
22
67
|
throw new Error('E57: file contains no Data3D scans');
|
|
23
68
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
69
|
+
const scans = [];
|
|
70
|
+
let total = 0;
|
|
71
|
+
for (const entry of entries) {
|
|
72
|
+
const dataLogicalOffset = await this.resolveDataOffset(entry, header.pageSize, signal);
|
|
73
|
+
const fields = resolveScanFields(entry.prototype);
|
|
74
|
+
scans.push({
|
|
75
|
+
recordCount: entry.recordCount,
|
|
76
|
+
dataLogicalOffset,
|
|
77
|
+
fields,
|
|
78
|
+
prototype: entry.prototype,
|
|
79
|
+
pose: entry.pose,
|
|
80
|
+
bytesPerRecord: estimateBytesPerRecord(entry.prototype),
|
|
81
|
+
});
|
|
82
|
+
total += entry.recordCount;
|
|
83
|
+
}
|
|
84
|
+
this.scans = scans;
|
|
85
|
+
this.totalPointCount = total;
|
|
86
|
+
this.hasColor = scans.some((s) => s.fields.hasRgb);
|
|
87
|
+
this.hasIntensity = scans.some((s) => s.fields.hasIntensity);
|
|
88
|
+
this.hasClassification = scans.some((s) => s.fields.hasClassification);
|
|
89
|
+
this.scanIdx = 0;
|
|
90
|
+
this.logCursor = scans[0].dataLogicalOffset;
|
|
91
|
+
this.recordsWritten = 0;
|
|
92
|
+
this.scanRecordBase = 0;
|
|
93
|
+
this.opened = true;
|
|
94
|
+
return this.toInfo();
|
|
33
95
|
}
|
|
34
96
|
async next(maxPoints, signal) {
|
|
35
97
|
abortIfAborted(signal);
|
|
36
|
-
if (!this.
|
|
98
|
+
if (!this.opened) {
|
|
99
|
+
throw new Error('E57StreamingSource: open() must be awaited before next()');
|
|
100
|
+
}
|
|
101
|
+
if (!Number.isFinite(maxPoints) || maxPoints <= 0) {
|
|
102
|
+
// 0/negative would emit empty chunks without advancing the cursor,
|
|
103
|
+
// creating a non-terminating loop in the host.
|
|
104
|
+
throw new Error(`E57StreamingSource: maxPoints must be > 0 (got ${maxPoints})`);
|
|
105
|
+
}
|
|
106
|
+
const stride = Math.max(1, this.downsample.stride | 0);
|
|
107
|
+
const parts = [];
|
|
108
|
+
let produced = 0;
|
|
109
|
+
let anyColor = false;
|
|
110
|
+
let anyIntensity = false;
|
|
111
|
+
let anyClassification = false;
|
|
112
|
+
while (produced < maxPoints) {
|
|
113
|
+
abortIfAborted(signal);
|
|
114
|
+
// Skip past any fully-consumed scans, re-seating the cursor on the
|
|
115
|
+
// next scan's data region.
|
|
116
|
+
while (this.scanIdx < this.scans.length
|
|
117
|
+
&& this.recordsWritten >= this.scans[this.scanIdx].recordCount) {
|
|
118
|
+
// Carry the finished scan's full declared record count into the
|
|
119
|
+
// file-global phase so the next scan keeps striding on the merged
|
|
120
|
+
// cloud's index line (…, k·stride, …) instead of re-aligning to 0.
|
|
121
|
+
this.scanRecordBase += this.scans[this.scanIdx].recordCount;
|
|
122
|
+
this.scanIdx++;
|
|
123
|
+
if (this.scanIdx < this.scans.length) {
|
|
124
|
+
this.logCursor = this.scans[this.scanIdx].dataLogicalOffset;
|
|
125
|
+
this.recordsWritten = 0;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (this.scanIdx >= this.scans.length)
|
|
129
|
+
break; // stream exhausted
|
|
130
|
+
const scan = this.scans[this.scanIdx];
|
|
131
|
+
const windowLen = this.computeWindowLen(scan, maxPoints - produced, stride);
|
|
132
|
+
if (windowLen <= 0) {
|
|
133
|
+
// No file bytes remain for this scan (over-reported recordCount).
|
|
134
|
+
this.recordsWritten = scan.recordCount;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
let window = await readLogicalRange(this.bytes, this.logCursor, windowLen, this.pageSize);
|
|
138
|
+
abortIfAborted(signal);
|
|
139
|
+
if (window.length === 0) {
|
|
140
|
+
this.recordsWritten = scan.recordCount;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
let view = new DataView(window.buffer, window.byteOffset, window.byteLength);
|
|
144
|
+
// Guarantee the first packet fits: if it straddles the window end
|
|
145
|
+
// and we're not at EOF, re-read a window sized to exactly that
|
|
146
|
+
// packet. (With the default ≥1 MiB window this never fires; it
|
|
147
|
+
// matters only for the tiny windows tests use.)
|
|
148
|
+
if (window.length >= 4) {
|
|
149
|
+
const peek0 = peekPacketHeader(view, 0);
|
|
150
|
+
const atEof = this.logCursor + window.length >= this.fileLogicalSize;
|
|
151
|
+
if (peek0.packetLength > window.length && !atEof) {
|
|
152
|
+
window = await readLogicalRange(this.bytes, this.logCursor, peek0.packetLength, this.pageSize);
|
|
153
|
+
abortIfAborted(signal);
|
|
154
|
+
view = new DataView(window.buffer, window.byteOffset, window.byteLength);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
let local = 0;
|
|
158
|
+
let progressed = false;
|
|
159
|
+
while (produced < maxPoints && this.recordsWritten < scan.recordCount) {
|
|
160
|
+
if (local + 4 > window.length)
|
|
161
|
+
break; // header needs more bytes
|
|
162
|
+
const peek = peekPacketHeader(view, local);
|
|
163
|
+
if (local + peek.packetLength > window.length) {
|
|
164
|
+
// Packet straddles the window end. We've already advanced
|
|
165
|
+
// logCursor past every packet consumed so far; break and let
|
|
166
|
+
// the outer loop re-read a fresh window starting at this packet.
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
const packet = decodeE57Packet(window, view, local, scan.fields, scan.prototype, scan.recordCount - this.recordsWritten);
|
|
170
|
+
if (packet.packetType !== 1) {
|
|
171
|
+
// Skip non-data packets (index/empty); may appear interleaved.
|
|
172
|
+
local += packet.packetLength;
|
|
173
|
+
this.logCursor += packet.packetLength;
|
|
174
|
+
progressed = true;
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (packet.take > 0 && packet.positions) {
|
|
178
|
+
// Phase the stride on the file-global record index so multi-scan
|
|
179
|
+
// downsampling matches the whole-file decoder, not per-scan.
|
|
180
|
+
const sel = selectStride(packet, this.scanRecordBase + this.recordsWritten, stride, scan.pose);
|
|
181
|
+
if (sel.count > 0) {
|
|
182
|
+
parts.push(sel);
|
|
183
|
+
produced += sel.count;
|
|
184
|
+
if (sel.colors)
|
|
185
|
+
anyColor = true;
|
|
186
|
+
if (sel.intensities)
|
|
187
|
+
anyIntensity = true;
|
|
188
|
+
if (sel.classifications)
|
|
189
|
+
anyClassification = true;
|
|
190
|
+
}
|
|
191
|
+
this.recordsWritten += packet.take;
|
|
192
|
+
}
|
|
193
|
+
local += packet.packetLength;
|
|
194
|
+
this.logCursor += packet.packetLength;
|
|
195
|
+
progressed = true;
|
|
196
|
+
}
|
|
197
|
+
if (!progressed) {
|
|
198
|
+
// Nothing consumable in this window despite bytes remaining —
|
|
199
|
+
// only reachable when the file ends mid-packet (truncated or
|
|
200
|
+
// over-reported recordCount). Drop the scan's phantom tail, like
|
|
201
|
+
// the whole-file decoder trims its under-filled output.
|
|
202
|
+
this.recordsWritten = scan.recordCount;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (produced === 0)
|
|
37
206
|
return null;
|
|
38
|
-
|
|
39
|
-
this.served = true;
|
|
40
|
-
return this.chunk;
|
|
207
|
+
return concatParts(parts, produced, anyColor, anyIntensity, anyClassification);
|
|
41
208
|
}
|
|
42
209
|
close() {
|
|
43
|
-
this.
|
|
44
|
-
this.
|
|
210
|
+
this.opened = false;
|
|
211
|
+
this.scans = [];
|
|
212
|
+
this.scanIdx = 0;
|
|
213
|
+
this.logCursor = 0;
|
|
214
|
+
this.recordsWritten = 0;
|
|
215
|
+
this.scanRecordBase = 0;
|
|
45
216
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
for (let i = 0; i < chunk.pointCount; i += s) {
|
|
58
|
-
positions[dst * 3] = chunk.positions[i * 3];
|
|
59
|
-
positions[dst * 3 + 1] = chunk.positions[i * 3 + 1];
|
|
60
|
-
positions[dst * 3 + 2] = chunk.positions[i * 3 + 2];
|
|
61
|
-
if (colors && chunk.colors) {
|
|
62
|
-
colors[dst * 3] = chunk.colors[i * 3];
|
|
63
|
-
colors[dst * 3 + 1] = chunk.colors[i * 3 + 1];
|
|
64
|
-
colors[dst * 3 + 2] = chunk.colors[i * 3 + 2];
|
|
217
|
+
/**
|
|
218
|
+
* Resolve a scan's binary data offset by reading its 32-byte
|
|
219
|
+
* CompressedVector section header (E57 §6.4.2). The XML's `fileOffset`
|
|
220
|
+
* points at this section header, not the first DataPacket.
|
|
221
|
+
*/
|
|
222
|
+
async resolveDataOffset(entry, pageSize, signal) {
|
|
223
|
+
const sectionLogical = physicalToLogical(entry.binaryFileOffset, pageSize);
|
|
224
|
+
const headerBytes = await readLogicalRange(this.bytes, sectionLogical, 32, pageSize);
|
|
225
|
+
abortIfAborted(signal);
|
|
226
|
+
if (headerBytes.length < 32) {
|
|
227
|
+
throw new Error(`E57: CompressedVector section header at logical ${sectionLogical} runs past end of file`);
|
|
65
228
|
}
|
|
66
|
-
|
|
67
|
-
|
|
229
|
+
const view = new DataView(headerBytes.buffer, headerBytes.byteOffset, headerBytes.byteLength);
|
|
230
|
+
const sectionId = view.getUint8(0);
|
|
231
|
+
if (sectionId !== 1) {
|
|
232
|
+
throw new Error(`E57: expected CompressedVector section (id=1) at physical ${entry.binaryFileOffset}, got id=${sectionId}`);
|
|
68
233
|
}
|
|
69
|
-
|
|
70
|
-
|
|
234
|
+
const dataPhysicalOffset = readU64LE(view, 16);
|
|
235
|
+
return physicalToLogical(dataPhysicalOffset, pageSize);
|
|
236
|
+
}
|
|
237
|
+
/** Logical bytes to pull on the next read — bounded and EOF-clamped. */
|
|
238
|
+
computeWindowLen(scan, remainingPoints, stride) {
|
|
239
|
+
const remainingFile = this.fileLogicalSize - this.logCursor;
|
|
240
|
+
if (remainingFile <= 0)
|
|
241
|
+
return 0;
|
|
242
|
+
if (this.windowBytesOverride && this.windowBytesOverride > 0) {
|
|
243
|
+
return Math.min(this.windowBytesOverride, remainingFile);
|
|
244
|
+
}
|
|
245
|
+
// Aim for ~remainingPoints worth of source records, +15% slack for
|
|
246
|
+
// packet/bytestream-table overhead, clamped to [MIN, MAX].
|
|
247
|
+
const want = remainingPoints * stride * scan.bytesPerRecord * 1.15 + 4096;
|
|
248
|
+
const len = Math.min(MAX_WINDOW_BYTES, Math.max(MIN_WINDOW_BYTES, want));
|
|
249
|
+
return Math.min(len, remainingFile);
|
|
250
|
+
}
|
|
251
|
+
toInfo() {
|
|
252
|
+
const stride = Math.max(1, this.downsample.stride | 0);
|
|
253
|
+
return {
|
|
254
|
+
totalPointCount: stride === 1
|
|
255
|
+
? this.totalPointCount
|
|
256
|
+
: Math.ceil(this.totalPointCount / stride),
|
|
257
|
+
// The source-wide bbox is aggregated by the host from each emitted
|
|
258
|
+
// chunk's bbox; we can't know it without decoding, so report a
|
|
259
|
+
// finite zero bbox as the fallback the host only uses if no chunk
|
|
260
|
+
// is ever emitted.
|
|
261
|
+
bbox: { min: [0, 0, 0], max: [0, 0, 0] },
|
|
262
|
+
hasColor: this.hasColor,
|
|
263
|
+
hasClassification: this.hasClassification,
|
|
264
|
+
hasIntensity: this.hasIntensity,
|
|
265
|
+
label: this.label,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Read a LOGICAL byte range [logStart, logStart+logLength) from a
|
|
271
|
+
* CRC-paged E57 file. Reads the covering physical page span, strips the
|
|
272
|
+
* 4-byte per-page CRC tails, and returns the requested logical slice.
|
|
273
|
+
*
|
|
274
|
+
* Returns fewer bytes than requested (or empty) near EOF — callers treat
|
|
275
|
+
* a short read as "scan ends here".
|
|
276
|
+
*/
|
|
277
|
+
async function readLogicalRange(src, logStart, logLength, pageSize) {
|
|
278
|
+
if (logLength <= 0)
|
|
279
|
+
return new Uint8Array(0);
|
|
280
|
+
const payloadPerPage = pageSize - 4;
|
|
281
|
+
const firstPage = Math.floor(logStart / payloadPerPage);
|
|
282
|
+
const logicalPageStart = firstPage * payloadPerPage;
|
|
283
|
+
const physicalStart = firstPage * pageSize;
|
|
284
|
+
const logEnd = logStart + logLength;
|
|
285
|
+
// Page containing the last byte we need (inclusive).
|
|
286
|
+
const lastPage = Math.floor((logEnd - 1) / payloadPerPage);
|
|
287
|
+
const physicalEnd = (lastPage + 1) * pageSize; // exclusive; read() clamps to size
|
|
288
|
+
const physical = await src.read(physicalStart, physicalEnd);
|
|
289
|
+
if (physical.length === 0)
|
|
290
|
+
return new Uint8Array(0);
|
|
291
|
+
// `physical` starts on a page boundary, so stripPageCrc treats byte 0
|
|
292
|
+
// as a page start correctly. A clamped (EOF) tail is handled by
|
|
293
|
+
// stripPageCrc's partial-page logic.
|
|
294
|
+
const logical = stripPageCrc(physical, pageSize);
|
|
295
|
+
const rel = logStart - logicalPageStart;
|
|
296
|
+
if (rel >= logical.length)
|
|
297
|
+
return new Uint8Array(0);
|
|
298
|
+
return logical.subarray(rel, Math.min(rel + logLength, logical.length));
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Take every `stride`-th record from a decoded packet (phased by the
|
|
302
|
+
* file-global record index `base` — the record's position in the merged
|
|
303
|
+
* multi-scan cloud, so the kept set is {i : (base+j) ≡ 0 mod stride})
|
|
304
|
+
* and apply the scan's pose. Returns a fresh, tightly-sized slice — the
|
|
305
|
+
* packet's own buffers are reused verbatim when `stride === 1`.
|
|
306
|
+
*/
|
|
307
|
+
function selectStride(packet, base, stride, pose) {
|
|
308
|
+
const take = packet.take;
|
|
309
|
+
const pos = packet.positions;
|
|
310
|
+
if (stride === 1) {
|
|
311
|
+
if (pose)
|
|
312
|
+
applyPoseInPlace(pos, take, pose);
|
|
313
|
+
return {
|
|
314
|
+
count: take,
|
|
315
|
+
positions: pos,
|
|
316
|
+
colors: packet.colors,
|
|
317
|
+
intensities: packet.intensities,
|
|
318
|
+
classifications: packet.classifications,
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
// First in-packet index j whose global index (base+j) is stride-aligned.
|
|
322
|
+
const firstKept = (stride - (base % stride)) % stride;
|
|
323
|
+
let count = 0;
|
|
324
|
+
for (let j = firstKept; j < take; j += stride)
|
|
325
|
+
count++;
|
|
326
|
+
const positions = new Float32Array(count * 3);
|
|
327
|
+
const colors = packet.colors ? new Float32Array(count * 3) : undefined;
|
|
328
|
+
const intensities = packet.intensities ? new Uint16Array(count) : undefined;
|
|
329
|
+
const classifications = packet.classifications ? new Uint8Array(count) : undefined;
|
|
330
|
+
let dst = 0;
|
|
331
|
+
for (let j = firstKept; j < take; j += stride) {
|
|
332
|
+
positions[dst * 3] = pos[j * 3];
|
|
333
|
+
positions[dst * 3 + 1] = pos[j * 3 + 1];
|
|
334
|
+
positions[dst * 3 + 2] = pos[j * 3 + 2];
|
|
335
|
+
if (colors && packet.colors) {
|
|
336
|
+
colors[dst * 3] = packet.colors[j * 3];
|
|
337
|
+
colors[dst * 3 + 1] = packet.colors[j * 3 + 1];
|
|
338
|
+
colors[dst * 3 + 2] = packet.colors[j * 3 + 2];
|
|
71
339
|
}
|
|
340
|
+
if (intensities && packet.intensities)
|
|
341
|
+
intensities[dst] = packet.intensities[j];
|
|
342
|
+
if (classifications && packet.classifications)
|
|
343
|
+
classifications[dst] = packet.classifications[j];
|
|
72
344
|
dst++;
|
|
73
345
|
}
|
|
346
|
+
if (pose)
|
|
347
|
+
applyPoseInPlace(positions, count, pose);
|
|
348
|
+
return { count, positions, colors, intensities, classifications };
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Concatenate per-packet selected parts into one chunk. Channels are
|
|
352
|
+
* unioned across parts (a multi-scan chunk where one scan lacks colour
|
|
353
|
+
* leaves that scan's slice at zeros), mirroring `decodeE57`'s merge.
|
|
354
|
+
*/
|
|
355
|
+
function concatParts(parts, total, anyColor, anyIntensity, anyClassification) {
|
|
356
|
+
const positions = new Float32Array(total * 3);
|
|
357
|
+
const colors = anyColor ? new Float32Array(total * 3) : undefined;
|
|
358
|
+
const intensities = anyIntensity ? new Uint16Array(total) : undefined;
|
|
359
|
+
const classifications = anyClassification ? new Uint8Array(total) : undefined;
|
|
360
|
+
let off = 0;
|
|
361
|
+
for (const p of parts) {
|
|
362
|
+
positions.set(p.positions, off * 3);
|
|
363
|
+
if (colors && p.colors)
|
|
364
|
+
colors.set(p.colors, off * 3);
|
|
365
|
+
if (intensities && p.intensities)
|
|
366
|
+
intensities.set(p.intensities, off);
|
|
367
|
+
if (classifications && p.classifications)
|
|
368
|
+
classifications.set(p.classifications, off);
|
|
369
|
+
off += p.count;
|
|
370
|
+
}
|
|
74
371
|
return {
|
|
75
372
|
positions,
|
|
76
373
|
colors,
|
|
77
374
|
intensities,
|
|
78
375
|
classifications,
|
|
79
|
-
pointCount:
|
|
80
|
-
bbox:
|
|
376
|
+
pointCount: total,
|
|
377
|
+
bbox: computeBBox(positions),
|
|
81
378
|
};
|
|
82
379
|
}
|
|
380
|
+
/** Rough logical bytes per record — window-sizing heuristic only. */
|
|
381
|
+
function estimateBytesPerRecord(prototype) {
|
|
382
|
+
let bytes = 0;
|
|
383
|
+
for (const f of prototype) {
|
|
384
|
+
if (f.kind === 'Float') {
|
|
385
|
+
bytes += f.precision === 'single' ? 4 : 8;
|
|
386
|
+
}
|
|
387
|
+
else if (f.kind === 'Integer') {
|
|
388
|
+
const widest = Math.max(Math.abs(f.minimum ?? 0), Math.abs(f.maximum ?? 255));
|
|
389
|
+
bytes += widest > 255 ? 2 : 1;
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
// ScaledInteger: ceil(log2(span+1)) bits per record.
|
|
393
|
+
const span = Math.max(0, (f.maximum ?? 0) - (f.minimum ?? 0));
|
|
394
|
+
const bits = span <= 0 ? 1 : Math.ceil(Math.log2(span + 1));
|
|
395
|
+
bytes += bits / 8;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
return Math.max(1, bytes);
|
|
399
|
+
}
|
|
83
400
|
function abortIfAborted(signal) {
|
|
84
401
|
if (signal?.aborted) {
|
|
85
402
|
throw new DOMException('Aborted', 'AbortError');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"e57-source.js","sourceRoot":"","sources":["../../src/streaming/e57-source.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"e57-source.js","sourceRoot":"","sources":["../../src/streaming/e57-source.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAwB/D,OAAO,EACL,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,iBAAiB,GAGlB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,SAAS,EACT,YAAY,GACb,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,WAAW,GAIZ,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAOlD,qEAAqE;AACrE,MAAM,gBAAgB,GAAG,CAAC,IAAI,EAAE,CAAC;AACjC,qDAAqD;AACrD,MAAM,gBAAgB,GAAG,EAAE,IAAI,EAAE,CAAC;AAuBlC,MAAM,OAAO,kBAAkB;IACrB,KAAK,CAAiB;IACtB,UAAU,CAAiB;IAC3B,KAAK,CAAU;IACvB,yEAAyE;IACjE,mBAAmB,CAAU;IAE7B,MAAM,GAAG,KAAK,CAAC;IACf,QAAQ,GAAG,IAAI,CAAC;IAChB,eAAe,GAAG,CAAC,CAAC;IACpB,KAAK,GAAe,EAAE,CAAC;IACvB,eAAe,GAAG,CAAC,CAAC;IACpB,QAAQ,GAAG,KAAK,CAAC;IACjB,YAAY,GAAG,KAAK,CAAC;IACrB,iBAAiB,GAAG,KAAK,CAAC;IAElC,oBAAoB;IACZ,OAAO,GAAG,CAAC,CAAC;IACZ,SAAS,GAAG,CAAC,CAAC;IACtB,2EAA2E;IACnE,cAAc,GAAG,CAAC,CAAC;IAC3B;;;;;;OAMG;IACK,cAAc,GAAG,CAAC,CAAC;IAE3B,YACE,IAAU,EACV,UAAiF,EAAE;QAEnF,IAAI,CAAC,KAAK,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QACtD,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,mBAAmB,GAAG,OAAO,CAAC,WAAW,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAoB;QAC7B,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QACtC,cAAc,CAAC,MAAM,CAAC,CAAC;QAEvB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACjD,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,MAAM,MAAM,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;QAC/C,IAAI,MAAM,CAAC,QAAQ,IAAI,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,yBAAyB,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QAChC,sEAAsE;QACtE,qEAAqE;QACrE,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,GAAG,CAAC;YAC/C,CAAC,CAAC,MAAM,CAAC,eAAe;YACxB,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QAExD,MAAM,UAAU,GAAG,MAAM,gBAAgB,CACvC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,QAAQ,CAC9E,CAAC;QACF,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACxD,CAAC;QAED,MAAM,KAAK,GAAe,EAAE,CAAC;QAC7B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACvF,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAClD,KAAK,CAAC,IAAI,CAAC;gBACT,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,iBAAiB;gBACjB,MAAM;gBACN,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,cAAc,EAAE,sBAAsB,CAAC,KAAK,CAAC,SAAS,CAAC;aACxD,CAAC,CAAC;YACH,KAAK,IAAI,KAAK,CAAC,WAAW,CAAC;QAC7B,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACnD,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAC7D,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;QACvE,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC;QAC5C,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;QACxB,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;QACxB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAiB,EAAE,MAAoB;QAChD,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC9E,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;YAClD,mEAAmE;YACnE,+CAA+C;YAC/C,MAAM,IAAI,KAAK,CAAC,kDAAkD,SAAS,GAAG,CAAC,CAAC;QAClF,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAEvD,MAAM,KAAK,GAAmB,EAAE,CAAC;QACjC,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI,YAAY,GAAG,KAAK,CAAC;QACzB,IAAI,iBAAiB,GAAG,KAAK,CAAC;QAE9B,OAAO,QAAQ,GAAG,SAAS,EAAE,CAAC;YAC5B,cAAc,CAAC,MAAM,CAAC,CAAC;YAEvB,mEAAmE;YACnE,2BAA2B;YAC3B,OACE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM;mBAC7B,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,WAAW,EAC9D,CAAC;gBACD,gEAAgE;gBAChE,kEAAkE;gBAClE,mEAAmE;gBACnE,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC;gBAC5D,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;oBACrC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,iBAAiB,CAAC;oBAC5D,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM;gBAAE,MAAM,CAAC,mBAAmB;YACjE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAEtC,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,SAAS,GAAG,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC5E,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;gBACnB,kEAAkE;gBAClE,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,WAAW,CAAC;gBACvC,SAAS;YACX,CAAC;YACD,IAAI,MAAM,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC1F,cAAc,CAAC,MAAM,CAAC,CAAC;YACvB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,WAAW,CAAC;gBACvC,SAAS;YACX,CAAC;YACD,IAAI,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;YAE7E,kEAAkE;YAClE,+DAA+D;YAC/D,+DAA+D;YAC/D,gDAAgD;YAChD,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;gBACvB,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;gBACxC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,eAAe,CAAC;gBACrE,IAAI,KAAK,CAAC,YAAY,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;oBACjD,MAAM,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;oBAC/F,cAAc,CAAC,MAAM,CAAC,CAAC;oBACvB,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;gBAC3E,CAAC;YACH,CAAC;YAED,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,IAAI,UAAU,GAAG,KAAK,CAAC;YACvB,OAAO,QAAQ,GAAG,SAAS,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;gBACtE,IAAI,KAAK,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM;oBAAE,MAAM,CAAC,0BAA0B;gBAChE,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBAC3C,IAAI,KAAK,GAAG,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;oBAC9C,0DAA0D;oBAC1D,6DAA6D;oBAC7D,iEAAiE;oBACjE,MAAM;gBACR,CAAC;gBACD,MAAM,MAAM,GAAG,eAAe,CAC5B,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,cAAc,CACzF,CAAC;gBACF,IAAI,MAAM,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;oBAC5B,+DAA+D;oBAC/D,KAAK,IAAI,MAAM,CAAC,YAAY,CAAC;oBAC7B,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC,YAAY,CAAC;oBACtC,UAAU,GAAG,IAAI,CAAC;oBAClB,SAAS;gBACX,CAAC;gBACD,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;oBACxC,iEAAiE;oBACjE,6DAA6D;oBAC7D,MAAM,GAAG,GAAG,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;oBAC/F,IAAI,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;wBAClB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;wBAChB,QAAQ,IAAI,GAAG,CAAC,KAAK,CAAC;wBACtB,IAAI,GAAG,CAAC,MAAM;4BAAE,QAAQ,GAAG,IAAI,CAAC;wBAChC,IAAI,GAAG,CAAC,WAAW;4BAAE,YAAY,GAAG,IAAI,CAAC;wBACzC,IAAI,GAAG,CAAC,eAAe;4BAAE,iBAAiB,GAAG,IAAI,CAAC;oBACpD,CAAC;oBACD,IAAI,CAAC,cAAc,IAAI,MAAM,CAAC,IAAI,CAAC;gBACrC,CAAC;gBACD,KAAK,IAAI,MAAM,CAAC,YAAY,CAAC;gBAC7B,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC,YAAY,CAAC;gBACtC,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;YAED,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,8DAA8D;gBAC9D,6DAA6D;gBAC7D,iEAAiE;gBACjE,wDAAwD;gBACxD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,WAAW,CAAC;YACzC,CAAC;QACH,CAAC;QAED,IAAI,QAAQ,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAChC,OAAO,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,iBAAiB,CAAC,CAAC;IACjF,CAAC;IAED,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAChB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QACnB,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;QACxB,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,iBAAiB,CAC7B,KAAkB,EAClB,QAAgB,EAChB,MAAoB;QAEpB,MAAM,cAAc,GAAG,iBAAiB,CAAC,KAAK,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;QAC3E,MAAM,WAAW,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC;QACrF,cAAc,CAAC,MAAM,CAAC,CAAC;QACvB,IAAI,WAAW,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CACb,mDAAmD,cAAc,wBAAwB,CAC1F,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,UAAU,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;QAC9F,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACnC,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CACb,6DAA6D,KAAK,CAAC,gBAAgB,YAAY,SAAS,EAAE,CAC3G,CAAC;QACJ,CAAC;QACD,MAAM,kBAAkB,GAAG,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC/C,OAAO,iBAAiB,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC;IACzD,CAAC;IAED,wEAAwE;IAChE,gBAAgB,CAAC,IAAc,EAAE,eAAuB,EAAE,MAAc;QAC9E,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC;QAC5D,IAAI,aAAa,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC;QACjC,IAAI,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,mBAAmB,GAAG,CAAC,EAAE,CAAC;YAC7D,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,mBAAmB,EAAE,aAAa,CAAC,CAAC;QAC3D,CAAC;QACD,mEAAmE;QACnE,2DAA2D;QAC3D,MAAM,IAAI,GAAG,eAAe,GAAG,MAAM,GAAG,IAAI,CAAC,cAAc,GAAG,IAAI,GAAG,IAAI,CAAC;QAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC,CAAC;QACzE,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IACtC,CAAC;IAEO,MAAM;QACZ,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACvD,OAAO;YACL,eAAe,EAAE,MAAM,KAAK,CAAC;gBAC3B,CAAC,CAAC,IAAI,CAAC,eAAe;gBACtB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC;YAC5C,mEAAmE;YACnE,+DAA+D;YAC/D,kEAAkE;YAClE,mBAAmB;YACnB,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;YACxC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC;IACJ,CAAC;CACF;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,gBAAgB,CAC7B,GAAmB,EACnB,QAAgB,EAChB,SAAiB,EACjB,QAAgB;IAEhB,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IAC7C,MAAM,cAAc,GAAG,QAAQ,GAAG,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,cAAc,CAAC,CAAC;IACxD,MAAM,gBAAgB,GAAG,SAAS,GAAG,cAAc,CAAC;IACpD,MAAM,aAAa,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC3C,MAAM,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;IACpC,qDAAqD;IACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC;IAC3D,MAAM,WAAW,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,mCAAmC;IAClF,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;IAC5D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IACpD,sEAAsE;IACtE,gEAAgE;IAChE,qCAAqC;IACrC,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,QAAQ,GAAG,gBAAgB,CAAC;IACxC,IAAI,GAAG,IAAI,OAAO,CAAC,MAAM;QAAE,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IACpD,OAAO,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED;;;;;;GAMG;AACH,SAAS,YAAY,CACnB,MAAqB,EACrB,IAAY,EACZ,MAAc,EACd,IAAc;IAEd,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IACzB,MAAM,GAAG,GAAG,MAAM,CAAC,SAAU,CAAC;IAC9B,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;QACjB,IAAI,IAAI;YAAE,gBAAgB,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAC5C,OAAO;YACL,KAAK,EAAE,IAAI;YACX,SAAS,EAAE,GAAG;YACd,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,eAAe,EAAE,MAAM,CAAC,eAAe;SACxC,CAAC;IACJ,CAAC;IACD,yEAAyE;IACzE,MAAM,SAAS,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC;IACtD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,SAAS,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,MAAM;QAAE,KAAK,EAAE,CAAC;IAEvD,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvE,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5E,MAAM,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACnF,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,SAAS,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC;QAC9C,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAChC,SAAS,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACxC,SAAS,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACxC,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAC5B,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACvC,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YAC/C,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,CAAC;QACD,IAAI,WAAW,IAAI,MAAM,CAAC,WAAW;YAAE,WAAW,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAChF,IAAI,eAAe,IAAI,MAAM,CAAC,eAAe;YAAE,eAAe,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAChG,GAAG,EAAE,CAAC;IACR,CAAC;IACD,IAAI,IAAI;QAAE,gBAAgB,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IACnD,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC;AACpE,CAAC;AAED;;;;GAIG;AACH,SAAS,WAAW,CAClB,KAAqB,EACrB,KAAa,EACb,QAAiB,EACjB,YAAqB,EACrB,iBAA0B;IAE1B,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAClE,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACtE,MAAM,eAAe,GAAG,iBAAiB,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9E,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;QACpC,IAAI,MAAM,IAAI,CAAC,CAAC,MAAM;YAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;QACtD,IAAI,WAAW,IAAI,CAAC,CAAC,WAAW;YAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QACtE,IAAI,eAAe,IAAI,CAAC,CAAC,eAAe;YAAE,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;QACtF,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC;IACjB,CAAC;IACD,OAAO;QACL,SAAS;QACT,MAAM;QACN,WAAW;QACX,eAAe;QACf,UAAU,EAAE,KAAK;QACjB,IAAI,EAAE,WAAW,CAAC,SAAS,CAAC;KAC7B,CAAC;AACJ,CAAC;AAED,qEAAqE;AACrE,SAAS,sBAAsB,CAAC,SAA2B;IACzD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACvB,KAAK,IAAI,CAAC,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,CAAC;aAAM,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC;YAC9E,KAAK,IAAI,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,qDAAqD;YACrD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;YAC9D,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;YAC5D,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AAC5B,CAAC;AAED,SAAS,cAAc,CAAC,MAAoB;IAC1C,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,YAAY,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAClD,CAAC;AACH,CAAC"}
|