edfcore 0.1.6 → 0.1.8

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.
@@ -0,0 +1,45 @@
1
+ /**
2
+ * The BioSemi Status channel.
3
+ *
4
+ * Layer 7. BioSemi's ActiveTwo writes BDF files whose last channel is labelled `Status`, and its
5
+ * 24-bit samples are not a measurement — they are a bit field the amplifier latched at each
6
+ * sample. The low 16 bits are the parallel trigger input, which is how nearly every ERP
7
+ * experiment records stimulus onsets.
8
+ *
9
+ * Reading that is file access, not analysis. The codes were written by the hardware at
10
+ * acquisition time, exactly like an EDF+ annotation, and this module only reports what is in the
11
+ * bytes. Nothing here inspects a biosignal, so event detection remains a non-goal.
12
+ *
13
+ * Only the bits BioSemi documents are named. `raw` carries all 24 so a caller with a rig-specific
14
+ * convention can decode the rest without waiting for this module to learn about it — inventing
15
+ * meanings for the bits above 18 would be guessing, and a wrong trigger code is worse than none.
16
+ */
17
+ import type { EdfHeader, EdfRecording, EdfSignal, EdfStatusWord, EdfTriggerEvent, ReadOptions, TriggerSelection } from './types.js';
18
+ /**
19
+ * The `Status` channel of a BDF file, or `undefined` when there is none.
20
+ *
21
+ * Returns `undefined` rather than throwing for a plain EDF or a BDF without the channel: a file
22
+ * having no Status channel is an ordinary fact about the file, not an error.
23
+ */
24
+ export declare function getStatusSignal(header: EdfHeader): EdfSignal | undefined;
25
+ /**
26
+ * Decodes one 24-bit Status sample.
27
+ *
28
+ * `decodeDigital` sign-extends BDF samples, as it must for a measurement, so bit 23 of a Status
29
+ * word arrives as a negative number. The bit field is unsigned, so it is masked back before
30
+ * anything is read out of it.
31
+ */
32
+ export declare function decodeStatusWord(sample: number): EdfStatusWord;
33
+ /**
34
+ * Every change of the trigger word in a window, as timed events.
35
+ *
36
+ * A parallel trigger is held for as long as the stimulus computer asserts it, so the same code
37
+ * repeats over many samples. What an experimenter wants is the TRANSITION, which is why this
38
+ * reports changes rather than samples: one event per change, carrying the code it changed to.
39
+ *
40
+ * Code 0 is "no trigger asserted", so a return to 0 is reported as an event with `trigger: 0`
41
+ * and is easy to filter out. It is reported rather than dropped because the release time is what
42
+ * gives a trigger its duration.
43
+ */
44
+ export declare function readTriggers(recording: EdfRecording, selection: TriggerSelection, options?: ReadOptions): Promise<readonly EdfTriggerEvent[]>;
45
+ //# sourceMappingURL=biosemi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"biosemi.d.ts","sourceRoot":"","sources":["../src/biosemi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH,OAAO,KAAK,EACV,SAAS,EACT,YAAY,EACZ,SAAS,EACT,aAAa,EACb,eAAe,EACf,WAAW,EAEX,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAWpB;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAOxE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAS9D;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,YAAY,EACvB,SAAS,EAAE,gBAAgB,EAC3B,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC,CAiErC"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * The BioSemi Status channel.
3
+ *
4
+ * Layer 7. BioSemi's ActiveTwo writes BDF files whose last channel is labelled `Status`, and its
5
+ * 24-bit samples are not a measurement — they are a bit field the amplifier latched at each
6
+ * sample. The low 16 bits are the parallel trigger input, which is how nearly every ERP
7
+ * experiment records stimulus onsets.
8
+ *
9
+ * Reading that is file access, not analysis. The codes were written by the hardware at
10
+ * acquisition time, exactly like an EDF+ annotation, and this module only reports what is in the
11
+ * bytes. Nothing here inspects a biosignal, so event detection remains a non-goal.
12
+ *
13
+ * Only the bits BioSemi documents are named. `raw` carries all 24 so a caller with a rig-specific
14
+ * convention can decode the rest without waiting for this module to learn about it — inventing
15
+ * meanings for the bits above 18 would be guessing, and a wrong trigger code is worse than none.
16
+ */
17
+ import { decodeDigitalCounted } from './decode/digital.js';
18
+ import { readRecordBytes } from './io/read.js';
19
+ import { scanChunkRecords } from './record-index.js';
20
+ import { ticksToSeconds } from './tal/ticks.js';
21
+ import { resolveTimeWindow } from './time/window.js';
22
+ /** BioSemi's own label for the channel. Matched case-insensitively after trimming. */
23
+ const STATUS_LABEL = 'status';
24
+ /** The parallel input occupies the low 16 bits; the flags sit immediately above it. */
25
+ const TRIGGER_MASK = 0xffff;
26
+ const EPOCH_BIT = 1 << 16;
27
+ const CMS_IN_RANGE_BIT = 1 << 17;
28
+ const BATTERY_LOW_BIT = 1 << 18;
29
+ /**
30
+ * The `Status` channel of a BDF file, or `undefined` when there is none.
31
+ *
32
+ * Returns `undefined` rather than throwing for a plain EDF or a BDF without the channel: a file
33
+ * having no Status channel is an ordinary fact about the file, not an error.
34
+ */
35
+ export function getStatusSignal(header) {
36
+ if (header.bytesPerSample !== 3)
37
+ return undefined;
38
+ for (const index of header.dataSignalIndices) {
39
+ const signal = header.signals[index];
40
+ if (signal !== undefined && signal.label.trim().toLowerCase() === STATUS_LABEL)
41
+ return signal;
42
+ }
43
+ return undefined;
44
+ }
45
+ /**
46
+ * Decodes one 24-bit Status sample.
47
+ *
48
+ * `decodeDigital` sign-extends BDF samples, as it must for a measurement, so bit 23 of a Status
49
+ * word arrives as a negative number. The bit field is unsigned, so it is masked back before
50
+ * anything is read out of it.
51
+ */
52
+ export function decodeStatusWord(sample) {
53
+ const raw = sample & 0xffffff;
54
+ return {
55
+ raw,
56
+ trigger: raw & TRIGGER_MASK,
57
+ newEpoch: (raw & EPOCH_BIT) !== 0,
58
+ cmsInRange: (raw & CMS_IN_RANGE_BIT) !== 0,
59
+ batteryLow: (raw & BATTERY_LOW_BIT) !== 0,
60
+ };
61
+ }
62
+ /**
63
+ * Every change of the trigger word in a window, as timed events.
64
+ *
65
+ * A parallel trigger is held for as long as the stimulus computer asserts it, so the same code
66
+ * repeats over many samples. What an experimenter wants is the TRANSITION, which is why this
67
+ * reports changes rather than samples: one event per change, carrying the code it changed to.
68
+ *
69
+ * Code 0 is "no trigger asserted", so a return to 0 is reported as an event with `trigger: 0`
70
+ * and is easy to filter out. It is reported rather than dropped because the release time is what
71
+ * gives a trigger its duration.
72
+ */
73
+ export async function readTriggers(recording, selection, options) {
74
+ const { source, header, timeline } = recording;
75
+ const status = getStatusSignal(header);
76
+ if (status === undefined) {
77
+ throw new RangeError('readTriggers(): this file has no BioSemi Status channel — it is either not a BDF file, ' +
78
+ 'or no signal is labelled "Status". Next: check header.signals, or read EDF+ ' +
79
+ 'annotations with readAnnotations().');
80
+ }
81
+ const ranges = resolveTimeWindow(timeline, recording.index, selection.startSeconds, selection.durationSeconds);
82
+ const events = [];
83
+ // Carried across runs so a trigger held over a gap is not reported twice. `undefined` means
84
+ // nothing has been seen yet, which is what makes the very first sample an event.
85
+ let previous;
86
+ for (const records of ranges) {
87
+ const chunkRecords = scanChunkRecords(header, options?.maxMaterializeBytes);
88
+ let scanned = 0;
89
+ let scratch;
90
+ while (scanned < records.count) {
91
+ const slice = {
92
+ start: records.start + scanned,
93
+ count: Math.min(chunkRecords, records.count - scanned),
94
+ };
95
+ const bytes = await readRecordBytes(source, header, slice, options);
96
+ const decoded = decodeDigitalCounted(header, bytes, slice, status.index, scratch, options);
97
+ scratch = decoded.digital;
98
+ const sampleCount = status.samplesPerRecord * slice.count;
99
+ const firstSampleIndex = slice.start * status.samplesPerRecord;
100
+ for (let i = 0; i < sampleCount; i += 1) {
101
+ const word = decodeStatusWord(decoded.digital[i]);
102
+ if (previous !== undefined && word.trigger === previous)
103
+ continue;
104
+ previous = word.trigger;
105
+ const sampleIndex = firstSampleIndex + i;
106
+ const ticks = header.recordDurationTicks > 0n && status.samplesPerRecord > 0
107
+ ? (BigInt(sampleIndex) * header.recordDurationTicks) / BigInt(status.samplesPerRecord)
108
+ : 0n;
109
+ events.push({
110
+ sampleIndex,
111
+ seconds: ticksToSeconds(ticks),
112
+ ticks,
113
+ trigger: word.trigger,
114
+ status: word,
115
+ });
116
+ }
117
+ scanned += slice.count;
118
+ }
119
+ }
120
+ return Object.freeze(events);
121
+ }
122
+ //# sourceMappingURL=biosemi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"biosemi.js","sourceRoot":"","sources":["../src/biosemi.ts"],"names":[],"mappings":"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"}
@@ -109,5 +109,5 @@ export declare const SIGNAL_FIELD_BLOCK_OFFSETS: {
109
109
  readonly reserved: 224;
110
110
  };
111
111
  /** Published package version. Kept in sync with package.json by a test. */
112
- export declare const VERSION = "0.1.6";
112
+ export declare const VERSION = "0.1.8";
113
113
  //# sourceMappingURL=constants.d.ts.map
package/dist/constants.js CHANGED
@@ -79,5 +79,5 @@ export const SIGNAL_FIELD_BLOCK_OFFSETS = {
79
79
  reserved: 224,
80
80
  };
81
81
  /** Published package version. Kept in sync with package.json by a test. */
82
- export const VERSION = '0.1.6';
82
+ export const VERSION = '0.1.8';
83
83
  //# sourceMappingURL=constants.js.map
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Min/max envelope decimation.
3
+ *
4
+ * Layer 7. A twelve-hour recording at 256 Hz is eleven million samples per channel, and a plot is
5
+ * a thousand pixels wide. Something has to reduce eleven million numbers to a thousand, and which
6
+ * reduction you pick decides whether the picture is true.
7
+ *
8
+ * Taking every 11,000th sample is the obvious choice and the wrong one: a spike, a spindle or an
9
+ * artifact is a handful of samples wide, so subsampling hits it with probability near zero and
10
+ * the trace looks calm exactly where a reader most needs it not to. Keeping the MINIMUM and
11
+ * MAXIMUM of each bucket keeps every extreme, at two numbers per pixel. That is the reduction a
12
+ * waveform viewer wants, and it is why this exists as its own function rather than as an option
13
+ * on `readWindow`: the return type is different, so an option would have to change it.
14
+ *
15
+ * This is decimation for display, not analysis. There is no filtering and no anti-aliasing —
16
+ * an envelope is a faithful summary of the samples that are there, not a resampled signal, and
17
+ * resampling remains a permanent non-goal.
18
+ *
19
+ * Memory is bounded by the record chunk, never by the window: a run of a million records is
20
+ * folded into the buckets a chunk at a time, so an envelope over a whole recording costs the
21
+ * buckets plus one chunk.
22
+ */
23
+ import type { EdfChunkSignal, EdfEnvelopeChunk, EdfEnvelopeSignal, EdfPhysicalEnvelope, EdfRecording, EdfSignal, EnvelopeSelection, ReadOptions } from './types.js';
24
+ /**
25
+ * Reduces a time window to per-bucket minima and maxima, one chunk per contiguous run.
26
+ *
27
+ * The shape mirrors `readWindow` exactly — an array of chunks, one per run, empty when the window
28
+ * selects nothing — so a caller that already handles gaps handles envelopes for free.
29
+ */
30
+ export declare function readEnvelope(recording: EdfRecording, selection: EnvelopeSelection, options?: ReadOptions): Promise<readonly EdfEnvelopeChunk[]>;
31
+ /**
32
+ * Converts a digital envelope to physical units.
33
+ *
34
+ * Not `toPhysical` applied twice, and the reason is the sign of the gain. The affine transform
35
+ * `bitValue * (offset + digital)` is DECREASING when `bitValue` is negative — a spec-sanctioned
36
+ * arrangement that edfcore reports rather than rejects — and a decreasing map sends the smallest
37
+ * digital value to the largest physical one. Mapping `min` to `min` would then produce an
38
+ * envelope whose lower bound is above its upper bound, and a viewer would draw it inside out.
39
+ */
40
+ export declare function toPhysicalEnvelope(signal: EdfSignal, envelope: EdfEnvelopeSignal): EdfPhysicalEnvelope;
41
+ /**
42
+ * The envelope of an already-decoded chunk signal, without another read.
43
+ *
44
+ * For a caller who has samples in hand and wants them plotted: same reduction, same bucket rule,
45
+ * no I/O.
46
+ */
47
+ export declare function envelopeOfSamples(chunkSignal: EdfChunkSignal, buckets: number): EdfEnvelopeSignal;
48
+ //# sourceMappingURL=envelope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../src/envelope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AASH,OAAO,KAAK,EACV,cAAc,EAEd,gBAAgB,EAChB,iBAAiB,EAEjB,mBAAmB,EACnB,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,WAAW,EAEZ,MAAM,YAAY,CAAC;AAsBpB;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,YAAY,EACvB,SAAS,EAAE,iBAAiB,EAC5B,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,SAAS,gBAAgB,EAAE,CAAC,CAkBtC;AAsLD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,iBAAiB,GAC1B,mBAAmB,CAuBrB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAkCjG"}
@@ -0,0 +1,263 @@
1
+ /**
2
+ * Min/max envelope decimation.
3
+ *
4
+ * Layer 7. A twelve-hour recording at 256 Hz is eleven million samples per channel, and a plot is
5
+ * a thousand pixels wide. Something has to reduce eleven million numbers to a thousand, and which
6
+ * reduction you pick decides whether the picture is true.
7
+ *
8
+ * Taking every 11,000th sample is the obvious choice and the wrong one: a spike, a spindle or an
9
+ * artifact is a handful of samples wide, so subsampling hits it with probability near zero and
10
+ * the trace looks calm exactly where a reader most needs it not to. Keeping the MINIMUM and
11
+ * MAXIMUM of each bucket keeps every extreme, at two numbers per pixel. That is the reduction a
12
+ * waveform viewer wants, and it is why this exists as its own function rather than as an option
13
+ * on `readWindow`: the return type is different, so an option would have to change it.
14
+ *
15
+ * This is decimation for display, not analysis. There is no filtering and no anti-aliasing —
16
+ * an envelope is a faithful summary of the samples that are there, not a resampled signal, and
17
+ * resampling remains a permanent non-goal.
18
+ *
19
+ * Memory is bounded by the record chunk, never by the window: a run of a million records is
20
+ * folded into the buckets a chunk at a time, so an envelope over a whole recording costs the
21
+ * buckets plus one chunk.
22
+ */
23
+ import { decodeDigitalCounted } from './decode/digital.js';
24
+ import { EdfScalingError } from './errors.js';
25
+ import { readRecordBytes } from './io/read.js';
26
+ import { scanChunkRecords } from './record-index.js';
27
+ import { decodeAnnotations } from './tal/annotations.js';
28
+ import { ticksToSeconds } from './tal/ticks.js';
29
+ import { resolveTimeWindow } from './time/window.js';
30
+ function assertPositiveInteger(value, name) {
31
+ if (Number.isSafeInteger(value) && value > 0)
32
+ return;
33
+ throw new RangeError(`readEnvelope(): ${name} must be a positive whole number, received ${value}. ` +
34
+ 'Next: pass the pixel width of the plot you are drawing into.');
35
+ }
36
+ /**
37
+ * Reduces a time window to per-bucket minima and maxima, one chunk per contiguous run.
38
+ *
39
+ * The shape mirrors `readWindow` exactly — an array of chunks, one per run, empty when the window
40
+ * selects nothing — so a caller that already handles gaps handles envelopes for free.
41
+ */
42
+ export async function readEnvelope(recording, selection, options) {
43
+ assertPositiveInteger(selection.buckets, 'buckets');
44
+ // Validated before the window is resolved, for the same reason readWindow does it: a bad
45
+ // signalIndices must not read back as an empty stretch of recording.
46
+ resolveEnvelopeSignals(recording.header, selection.signalIndices);
47
+ const ranges = resolveTimeWindow(recording.timeline, recording.index, selection.startSeconds, selection.durationSeconds);
48
+ const chunks = [];
49
+ for (const records of ranges) {
50
+ chunks.push(await reduceRange(recording, records, selection, options));
51
+ }
52
+ return Object.freeze(chunks);
53
+ }
54
+ function resolveEnvelopeSignals(header, signalIndices) {
55
+ const seen = new Set();
56
+ const signals = [];
57
+ for (const signalIndex of signalIndices) {
58
+ if (seen.has(signalIndex))
59
+ continue;
60
+ seen.add(signalIndex);
61
+ const signal = header.signals[signalIndex];
62
+ if (signal === undefined) {
63
+ throw new RangeError(`readEnvelope(): signalIndex ${signalIndex} is outside the ${header.signals.length} ` +
64
+ 'signals this file declares. Next: pass an index from header.dataSignalIndices.');
65
+ }
66
+ if (signal.kind === 'annotations') {
67
+ throw new RangeError(`readEnvelope(): signal ${signalIndex} (${JSON.stringify(signal.label)}) is this file's ` +
68
+ 'annotations channel; its bytes are TAL text, not samples, so an envelope over them ' +
69
+ 'would be an envelope over ASCII. Next: call readAnnotations() instead.');
70
+ }
71
+ signals.push(signal);
72
+ }
73
+ return signals;
74
+ }
75
+ async function reduceRange(recording, records, selection, options) {
76
+ const { source, header, timeline } = recording;
77
+ const signals = resolveEnvelopeSignals(header, selection.signalIndices);
78
+ const diagnostics = [];
79
+ // More buckets than the densest signal has samples in this run would leave holes that mean
80
+ // nothing, so the request is clamped rather than honoured literally.
81
+ const densestSamples = signals.reduce((most, signal) => Math.max(most, signal.samplesPerRecord * records.count), 0);
82
+ const bucketCount = Math.max(1, Math.min(selection.buckets, densestSamples));
83
+ const accumulators = signals.map((signal) => ({
84
+ signal,
85
+ // Int32Array zero-fills, so the sentinels have to be written explicitly: a bucket nothing
86
+ // landed in must be distinguishable from a bucket whose samples were all zero.
87
+ min: new Int32Array(bucketCount).fill(0),
88
+ max: new Int32Array(bucketCount).fill(0),
89
+ counts: new Int32Array(bucketCount),
90
+ consumed: 0,
91
+ outOfRange: 0,
92
+ scratch: undefined,
93
+ }));
94
+ const chunkRecords = scanChunkRecords(header, options?.maxMaterializeBytes);
95
+ let byteLength = 0;
96
+ let firstOnsetTicks;
97
+ let lastOnsetTicks;
98
+ let scanned = 0;
99
+ while (scanned < records.count) {
100
+ const slice = {
101
+ start: records.start + scanned,
102
+ count: Math.min(chunkRecords, records.count - scanned),
103
+ };
104
+ const bytes = await readRecordBytes(source, header, slice, options);
105
+ byteLength += bytes.length;
106
+ // Never strict: a defect in one record must not cost the caller the whole picture.
107
+ const annotations = decodeAnnotations(header, bytes, slice, {
108
+ originTicks: timeline.startOffsetTicks,
109
+ });
110
+ for (const diagnostic of annotations.diagnostics)
111
+ diagnostics.push(diagnostic);
112
+ const onsets = annotations.recordOnsetTicks;
113
+ if (firstOnsetTicks === undefined)
114
+ firstOnsetTicks = onsets[0];
115
+ const lastInSlice = onsets[slice.count - 1];
116
+ if (lastInSlice !== undefined)
117
+ lastOnsetTicks = lastInSlice;
118
+ for (const accumulator of accumulators) {
119
+ foldChunk(accumulator, header, bytes, slice, records, bucketCount, options);
120
+ }
121
+ scanned += slice.count;
122
+ }
123
+ const durationTicks = header.recordDurationTicks;
124
+ const startTicks = (firstOnsetTicks ?? timeline.startOffsetTicks) - timeline.startOffsetTicks;
125
+ const spanTicks = firstOnsetTicks !== undefined && lastOnsetTicks !== undefined
126
+ ? lastOnsetTicks + durationTicks - firstOnsetTicks
127
+ : durationTicks * BigInt(records.count);
128
+ const startSeconds = ticksToSeconds(startTicks);
129
+ const durationSeconds = ticksToSeconds(spanTicks);
130
+ const envelopeSignals = accumulators.map((accumulator) => ({
131
+ signalIndex: accumulator.signal.index,
132
+ min: accumulator.min,
133
+ max: accumulator.max,
134
+ counts: accumulator.counts,
135
+ sampleCount: accumulator.consumed,
136
+ firstSampleIndex: records.start * accumulator.signal.samplesPerRecord,
137
+ startSeconds,
138
+ outOfDigitalRangeCount: accumulator.outOfRange,
139
+ }));
140
+ return Object.freeze({
141
+ records,
142
+ startSeconds,
143
+ durationSeconds,
144
+ bucketCount,
145
+ secondsPerBucket: bucketCount > 0 ? durationSeconds / bucketCount : 0,
146
+ byteLength,
147
+ signals: Object.freeze(envelopeSignals),
148
+ precededByGap: undefined,
149
+ diagnostics: Object.freeze(diagnostics),
150
+ });
151
+ }
152
+ /**
153
+ * Folds one chunk of one signal into the buckets.
154
+ *
155
+ * The bucket of a sample is decided by its position on the WHOLE run's grid, not the chunk's, so
156
+ * the chunk size cannot move a sample from one bucket to another. That is the same rule the
157
+ * record scan learned the hard way: chunking bounds memory and must never change the answer.
158
+ */
159
+ function foldChunk(accumulator, header, bytes, slice, run, bucketCount, options) {
160
+ const totalSamples = accumulator.signal.samplesPerRecord * run.count;
161
+ if (totalSamples === 0)
162
+ return;
163
+ const decoded = decodeDigitalCounted(header, bytes, slice, accumulator.signal.index, accumulator.scratch, options);
164
+ // decodeDigitalCounted reuses the buffer when it is large enough, so the allocation happens
165
+ // once per signal per run rather than once per chunk.
166
+ accumulator.scratch = decoded.digital;
167
+ accumulator.outOfRange += decoded.outOfDigitalRangeCount;
168
+ const samples = decoded.digital;
169
+ // The buffer is reused across chunks, so it can be LONGER than this slice. The slice's own
170
+ // sample count is what must be folded, or the tail of a previous, larger chunk is counted again.
171
+ const sampleCount = accumulator.signal.samplesPerRecord * slice.count;
172
+ const { min, max, counts } = accumulator;
173
+ let position = accumulator.consumed;
174
+ for (let i = 0; i < sampleCount; i += 1) {
175
+ const value = samples[i];
176
+ // Integer arithmetic on the run grid: floor(position * buckets / totalSamples).
177
+ const bucket = Math.min(bucketCount - 1, Math.floor((position * bucketCount) / totalSamples));
178
+ const seen = counts[bucket];
179
+ if (seen === 0) {
180
+ min[bucket] = value;
181
+ max[bucket] = value;
182
+ }
183
+ else {
184
+ if (value < min[bucket])
185
+ min[bucket] = value;
186
+ if (value > max[bucket])
187
+ max[bucket] = value;
188
+ }
189
+ counts[bucket] = seen + 1;
190
+ position += 1;
191
+ }
192
+ accumulator.consumed = position;
193
+ }
194
+ /**
195
+ * Converts a digital envelope to physical units.
196
+ *
197
+ * Not `toPhysical` applied twice, and the reason is the sign of the gain. The affine transform
198
+ * `bitValue * (offset + digital)` is DECREASING when `bitValue` is negative — a spec-sanctioned
199
+ * arrangement that edfcore reports rather than rejects — and a decreasing map sends the smallest
200
+ * digital value to the largest physical one. Mapping `min` to `min` would then produce an
201
+ * envelope whose lower bound is above its upper bound, and a viewer would draw it inside out.
202
+ */
203
+ export function toPhysicalEnvelope(signal, envelope) {
204
+ const scale = signal.scale;
205
+ if (scale === undefined) {
206
+ throw new EdfScalingError(`signal ${signal.index} (${JSON.stringify(signal.label)}) has no usable scale, so its ` +
207
+ 'envelope has no physical units. Next: check signal.scale before converting, or plot ' +
208
+ 'the digital envelope as it is.', { code: 'SCALE_UNAVAILABLE', signalIndex: signal.index, label: signal.label });
209
+ }
210
+ const length = envelope.min.length;
211
+ const low = new Float64Array(length);
212
+ const high = new Float64Array(length);
213
+ const decreasing = scale.bitValue < 0;
214
+ for (let i = 0; i < length; i += 1) {
215
+ const a = scale.bitValue * (scale.offset + envelope.min[i]);
216
+ const b = scale.bitValue * (scale.offset + envelope.max[i]);
217
+ low[i] = decreasing ? b : a;
218
+ high[i] = decreasing ? a : b;
219
+ }
220
+ return { min: low, max: high };
221
+ }
222
+ /**
223
+ * The envelope of an already-decoded chunk signal, without another read.
224
+ *
225
+ * For a caller who has samples in hand and wants them plotted: same reduction, same bucket rule,
226
+ * no I/O.
227
+ */
228
+ export function envelopeOfSamples(chunkSignal, buckets) {
229
+ assertPositiveInteger(buckets, 'buckets');
230
+ const samples = chunkSignal.digital;
231
+ const total = samples.length;
232
+ const bucketCount = Math.max(1, Math.min(buckets, total));
233
+ const min = new Int32Array(bucketCount);
234
+ const max = new Int32Array(bucketCount);
235
+ const counts = new Int32Array(bucketCount);
236
+ for (let i = 0; i < total; i += 1) {
237
+ const value = samples[i];
238
+ const bucket = Math.min(bucketCount - 1, Math.floor((i * bucketCount) / total));
239
+ const seen = counts[bucket];
240
+ if (seen === 0) {
241
+ min[bucket] = value;
242
+ max[bucket] = value;
243
+ }
244
+ else {
245
+ if (value < min[bucket])
246
+ min[bucket] = value;
247
+ if (value > max[bucket])
248
+ max[bucket] = value;
249
+ }
250
+ counts[bucket] = seen + 1;
251
+ }
252
+ return {
253
+ signalIndex: chunkSignal.signalIndex,
254
+ min,
255
+ max,
256
+ counts,
257
+ sampleCount: total,
258
+ firstSampleIndex: chunkSignal.firstSampleIndex,
259
+ startSeconds: chunkSignal.startSeconds,
260
+ outOfDigitalRangeCount: chunkSignal.outOfDigitalRangeCount,
261
+ };
262
+ }
263
+ //# sourceMappingURL=envelope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope.js","sourceRoot":"","sources":["../src/envelope.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -22,7 +22,7 @@
22
22
  /** The trailing `options` argument shared by every primitive that can allocate. */
23
23
  export type { MaterializeOptions } from './decode/digital.js';
24
24
  export type { FormatDiagnosticsOptions } from './diagnostics/format.js';
25
- export type { AbortSignalLike, BlobLike, BuildIndexOptions, ByteSource, CacheOptions, DecodeAnnotationsOptions, EdfAnnotation, EdfAnnotationsResult, EdfCalendarDate, EdfChunk, EdfChunkSignal, EdfClockTime, EdfDiagnostic, EdfDiagnosticCode, EdfGap, EdfHeader, EdfInspection, EdfKnownDiagnosticCode, EdfLocation, EdfPatientId, EdfRawHeaderFields, EdfRawSignalFields, EdfRecordIndex, EdfRecording, EdfRecordingId, EdfScale, EdfSegment, EdfSeverity, EdfSignal, EdfStartTime, EdfTimeline, EdfVariant, FetchLike, HttpResponseLike, HttpSourceOptions, OpenOptions, ParseOptions, ReadOptions, RecordRange, RecordSelection, WindowSelection, } from './types.js';
25
+ export type { AbortSignalLike, BlobLike, BuildIndexOptions, ByteSource, CacheOptions, DecodeAnnotationsOptions, EdfAnnotation, EdfAnnotationsResult, EdfCalendarDate, EdfChunk, EdfChunkSignal, EdfClockTime, EdfDiagnostic, EdfDiagnosticCode, EdfEnvelopeChunk, EdfEnvelopeSignal, EdfGap, EdfHeader, EdfInspection, EdfKnownDiagnosticCode, EdfLocation, EdfPatientId, EdfPhysicalEnvelope, EdfRawHeaderFields, EdfRawSignalFields, EdfRecordIndex, EdfRecording, EdfRecordingId, EdfScale, EdfSegment, EdfSeverity, EdfSignal, EdfStartTime, EdfStatusWord, EdfTimeline, EdfTriggerEvent, EdfVariant, EnvelopeSelection, FetchLike, HttpResponseLike, HttpSourceOptions, OpenOptions, ParseOptions, ReadOptions, RecordRange, RecordSelection, TriggerSelection, WindowSelection, } from './types.js';
26
26
  export type { AnyEdfError, EdfErrorKind, EdfFormatErrorInit } from './errors.js';
27
27
  export { EdfAmbiguousChannelError, EdfBudgetError, EdfChannelNotFoundError, EdfError, EdfFormatError, EdfRangeError, EdfScalingError, EdfSourceError, isEdfError, } from './errors.js';
28
28
  export { BDF_ANNOTATIONS_LABEL, BDF_DIGITAL_MAX, BDF_DIGITAL_MIN, EDF_ANNOTATIONS_LABEL, EDF_DIGITAL_MAX, EDF_DIGITAL_MIN, EDF_HEADER_BLOCK_BYTES, EDF_RECOMMENDED_MAX_RECORD_BYTES, TICKS_PER_SECOND, VERSION, } from './constants.js';
@@ -41,6 +41,8 @@ export { cachedSource } from './io/cached.js';
41
41
  export { httpSource } from './io/http.js';
42
42
  export { readHeader, readRecordBytes } from './io/read.js';
43
43
  export { buildRecordIndex, buildTimeline } from './record-index.js';
44
+ export { decodeStatusWord, getStatusSignal, readTriggers } from './biosemi.js';
45
+ export { envelopeOfSamples, readEnvelope, toPhysicalEnvelope } from './envelope.js';
44
46
  export { inspectEdf } from './inspect.js';
45
47
  export { openEdf, readAnnotations, readRecords, readWindow } from './recording.js';
46
48
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAOH,mFAAmF;AACnF,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,YAAY,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACxE,YAAY,EACV,eAAe,EACf,QAAQ,EACR,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,wBAAwB,EACxB,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,MAAM,EACN,SAAS,EACT,aAAa,EACb,sBAAsB,EACtB,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,UAAU,EACV,WAAW,EACX,SAAS,EACT,YAAY,EACZ,WAAW,EACX,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,WAAW,EACX,WAAW,EACX,eAAe,EACf,eAAe,GAChB,MAAM,YAAY,CAAC;AAUpB,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EACL,wBAAwB,EACxB,cAAc,EACd,uBAAuB,EACvB,QAAQ,EACR,cAAc,EACd,aAAa,EACb,eAAe,EACf,cAAc,EACd,UAAU,GACX,MAAM,aAAa,CAAC;AAMrB,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,gCAAgC,EAChC,gBAAgB,EAChB,OAAO,GACR,MAAM,gBAAgB,CAAC;AAOxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAQnE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAM1C,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAMpE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAOH,mFAAmF;AACnF,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,YAAY,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACxE,YAAY,EACV,eAAe,EACf,QAAQ,EACR,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,wBAAwB,EACxB,aAAa,EACb,oBAAoB,EACpB,eAAe,EACf,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,MAAM,EACN,SAAS,EACT,aAAa,EACb,sBAAsB,EACtB,WAAW,EACX,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,UAAU,EACV,WAAW,EACX,SAAS,EACT,YAAY,EACZ,aAAa,EACb,WAAW,EACX,eAAe,EACf,UAAU,EACV,iBAAiB,EACjB,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,WAAW,EACX,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,eAAe,GAChB,MAAM,YAAY,CAAC;AAUpB,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EACL,wBAAwB,EACxB,cAAc,EACd,uBAAuB,EACvB,QAAQ,EACR,cAAc,EACd,aAAa,EACb,eAAe,EACf,cAAc,EACd,UAAU,GACX,MAAM,aAAa,CAAC;AAMrB,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,gCAAgC,EAChC,gBAAgB,EAChB,OAAO,GACR,MAAM,gBAAgB,CAAC;AAOxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAQnE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAM1C,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAMpE,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -54,6 +54,8 @@ export { buildRecordIndex, buildTimeline } from './record-index.js';
54
54
  // ===========================================================================
55
55
  // Convenience layer
56
56
  // ===========================================================================
57
+ export { decodeStatusWord, getStatusSignal, readTriggers } from './biosemi.js';
58
+ export { envelopeOfSamples, readEnvelope, toPhysicalEnvelope } from './envelope.js';
57
59
  export { inspectEdf } from './inspect.js';
58
60
  export { openEdf, readAnnotations, readRecords, readWindow } from './recording.js';
59
61
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AA+DH,OAAO,EACL,wBAAwB,EACxB,cAAc,EACd,uBAAuB,EACvB,QAAQ,EACR,cAAc,EACd,aAAa,EACb,eAAe,EACf,cAAc,EACd,UAAU,GACX,MAAM,aAAa,CAAC;AAErB,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,gCAAgC,EAChC,gBAAgB,EAChB,OAAO,GACR,MAAM,gBAAgB,CAAC;AAExB,8EAA8E;AAC9E,2EAA2E;AAC3E,2CAA2C;AAC3C,8EAA8E;AAE9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEnE,8EAA8E;AAC9E,yEAAyE;AACzE,2EAA2E;AAC3E,6CAA6C;AAC7C,8EAA8E;AAE9E,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,8EAA8E;AAC9E,uCAAuC;AACvC,8EAA8E;AAE9E,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEpE,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAsEH,OAAO,EACL,wBAAwB,EACxB,cAAc,EACd,uBAAuB,EACvB,QAAQ,EACR,cAAc,EACd,aAAa,EACb,eAAe,EACf,cAAc,EACd,UAAU,GACX,MAAM,aAAa,CAAC;AAErB,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,gCAAgC,EAChC,gBAAgB,EAChB,OAAO,GACR,MAAM,gBAAgB,CAAC;AAExB,8EAA8E;AAC9E,2EAA2E;AAC3E,2CAA2C;AAC3C,8EAA8E;AAE9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEnE,8EAA8E;AAC9E,yEAAyE;AACzE,2EAA2E;AAC3E,6CAA6C;AAC7C,8EAA8E;AAE9E,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,8EAA8E;AAC9E,uCAAuC;AACvC,8EAA8E;AAE9E,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEpE,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC"}