@fxi/zartigl 0.6.0 → 0.7.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/dist/engine.d.ts CHANGED
@@ -1,3 +1,27 @@
1
+ /** Throws unless the index was written for this catalog entry and source. */
2
+ export declare function assertGeoVideoIndexIdentity(source: CatalogGeoVideoArchiveSource, index: GeoVideoIndex, entry: CatalogEntry): void;
3
+
4
+ /** Particle backdrop off: see BackdropStyle. */
5
+ export declare const BACKDROP_OFF: Readonly<BackdropStyle>;
6
+
7
+ /**
8
+ * Solid color under the particle trails, drawn on valid data cells only: it
9
+ * keeps particles readable over a light basemap. Off by default; an object
10
+ * without `enabled` is on.
11
+ */
12
+ declare interface BackdropStyle {
13
+ enabled: boolean;
14
+ /** Hex color, `#rgb` or `#rrggbb`. */
15
+ color: string;
16
+ opacity: number;
17
+ }
18
+
19
+ /**
20
+ * `u_solid` uniform: straight RGB in [0, 1] and opacity. Alpha is 0 when the
21
+ * backdrop is off, which also skips the draw.
22
+ */
23
+ export declare function backdropVec4(backdrop: BackdropStyle): [number, number, number, number];
24
+
1
25
  declare interface CatalogEntry {
2
26
  id: string;
3
27
  aliases?: string[];
@@ -7,22 +31,10 @@ declare interface CatalogEntry {
7
31
  tags?: string[];
8
32
  kind: "scalar" | "vector";
9
33
  sources: CatalogSource[];
10
- defaults: {
34
+ /** Default source, plus the layer's base style. */
35
+ defaults: LayerStyleInput & {
11
36
  sourceId: string;
12
37
  querySourceId?: string;
13
- palette?: string;
14
- renderMode?: "particles" | "raster" | "raster+particles";
15
- particles?: {
16
- density?: number;
17
- speed?: number;
18
- fade?: number;
19
- };
20
- raster?: {
21
- opacity?: number;
22
- logScale?: boolean;
23
- vibrance?: number;
24
- colorDomain?: [number, number];
25
- };
26
38
  };
27
39
  }
28
40
 
@@ -102,6 +114,12 @@ declare interface CatalogZarrSource extends CatalogSourceBase {
102
114
  variables: CatalogVariables;
103
115
  }
104
116
 
117
+ /**
118
+ * `vec3 gradeColor(vec3 c, vec4 g)` of `colorGradeVec4`; GLSL ES 1.0 and
119
+ * 3.0. It contains VIBRANCE_GLSL: include one or the other, never both.
120
+ */
121
+ export declare const COLOR_GRADE_GLSL: string;
122
+
105
123
  export declare const COLOR_GRADE_OFF: Readonly<ColorGrade>;
106
124
 
107
125
  export declare const COLOR_GRADE_VIBRANT: Readonly<ColorGrade>;
@@ -124,6 +142,9 @@ export declare interface ColorGrade {
124
142
  highlights: number;
125
143
  }
126
144
 
145
+ /** Style `particles.grade` of a color grade: a preset when it is one. */
146
+ export declare function colorGradeToGrade(input: Partial<ColorGrade>): ParticleGrade;
147
+
127
148
  /** `u_grade` uniform: (exposure, contrast, saturation, highlights). */
128
149
  export declare function colorGradeVec4(grade: ColorGrade): [number, number, number, number];
129
150
 
@@ -138,14 +159,136 @@ declare interface CoordArrays {
138
159
 
139
160
  export declare function createColorRampTexture(gl: WebGL2RenderingContext, ramp?: ColorRampInput): WebGLTexture;
140
161
 
162
+ /** The frame source decoding `manifest`: scalar or vector by its encoding. */
163
+ export declare function createGeoVideoFrameSource(manifest: GeoVideoManifest, options?: {
164
+ cacheSize?: number;
165
+ }): GeoVideoScalarSource | GeoVideoVectorSource;
166
+
141
167
  export declare function createProgram(gl: WebGL2RenderingContext, vertSource: string, fragSource: string): WebGLProgram;
142
168
 
169
+ export declare function createShader(gl: WebGL2RenderingContext, type: number, source: string): WebGLShader;
170
+
143
171
  /** Trail length in frames for a 0–1 `fade`. */
144
172
  export declare function fadeToFrames(fade: number): number;
145
173
 
146
174
  /** Per-frame trail opacity multiplier for a 0–1 `fade`. */
147
175
  export declare function fadeToOpacity(fade: number): number;
148
176
 
177
+ /**
178
+ * One immutable chunk of a GeoVideo archive, independent of the catalog: a
179
+ * manifest and the range of its encoded samples.
180
+ */
181
+ export declare interface GeoVideoArchiveChunk extends GeoVideoChunkSpan {
182
+ /** Stable identity of the chunk content (the index chunk key). */
183
+ key: string;
184
+ /** Absolute manifest URL. */
185
+ manifestUrl: string;
186
+ /** Encoded samples, when the index lists them. */
187
+ samples?: number;
188
+ provisional?: boolean;
189
+ }
190
+
191
+ /** One decoded time step of an archive. */
192
+ export declare interface GeoVideoArchiveFrame<TFrame = GeoVideoFrameData> {
193
+ /** Stable identity: archive id, chunk key and step. */
194
+ key: string;
195
+ chunk: GeoVideoArchiveChunk;
196
+ /** Step within the chunk. */
197
+ step: number;
198
+ time: number;
199
+ data: TFrame;
200
+ grid: GeoVideoGrid;
201
+ manifest: GeoVideoManifest;
202
+ }
203
+
204
+ /**
205
+ * The frames bracketing a time, possibly from two chunks: display
206
+ * a·(1 − mix) + b·mix. `b` is `a` with mix 0 in discrete mode or on a step.
207
+ */
208
+ export declare interface GeoVideoArchiveSample<TFrame = GeoVideoFrameData> {
209
+ time: number;
210
+ a: GeoVideoArchiveFrame<TFrame>;
211
+ b: GeoVideoArchiveFrame<TFrame>;
212
+ mix: number;
213
+ }
214
+
215
+ /**
216
+ * Several chunks of a GeoVideo archive as one continuous timeline. Every
217
+ * sample request is independent: aborting one leaves the decodes another
218
+ * request needs. Manifests are cached; chunk sources are kept open in a
219
+ * bounded LRU and released when evicted. The archive answers instants; it
220
+ * neither drives a clock nor picks other archives (see pairChunkSpan).
221
+ */
222
+ export declare class GeoVideoArchiveSource<TFrame = GeoVideoFrameData> {
223
+ readonly id: string;
224
+ /** Chunks sorted by start, without empty ranges. */
225
+ readonly chunks: readonly GeoVideoArchiveChunk[];
226
+ private readonly maxOpenChunks;
227
+ private readonly frameCacheSize;
228
+ private readonly prefetchAt;
229
+ private readonly maxGap;
230
+ private readonly loadManifest;
231
+ private readonly createFrameSource;
232
+ private readonly manifests;
233
+ private readonly open;
234
+ constructor(options: GeoVideoArchiveSourceOptions<TFrame>);
235
+ /** First and last sample of the archive, or null without chunks. */
236
+ get range(): [number, number] | null;
237
+ /** The chunk whose sample range holds `time`, or null. */
238
+ chunkAt(time: number): GeoVideoArchiveChunk | null;
239
+ /** Every step time of the archive; loads all chunk manifests. */
240
+ steps(request?: GeoVideoFrameRequest): Promise<Float64Array>;
241
+ /**
242
+ * The frames bracketing `time`, decoded; null out of coverage (before the
243
+ * first step, after the last, or in a gap wider than `maxGap`).
244
+ */
245
+ sample(time: number, request?: GeoVideoFrameRequest & {
246
+ mode?: GeoVideoSampleMode;
247
+ }): Promise<GeoVideoArchiveSample<TFrame> | null>;
248
+ /** Open `chunk` and decode its first frame ahead of a request. */
249
+ prefetch(chunk: GeoVideoArchiveChunk): void;
250
+ /** Release every open chunk source; later requests reopen them. */
251
+ release(): void;
252
+ private chunkIndexAt;
253
+ private gapLimit;
254
+ private prefetchAfter;
255
+ private manifest;
256
+ /** The open chunk, pinned for a running sample listed in `used`. */
257
+ private acquire;
258
+ /** The open chunk, opened when needed, most recently used; not pinned. */
259
+ private touch;
260
+ private frame;
261
+ /** Release least recently used chunks beyond the bound, unless in use. */
262
+ private trim;
263
+ private close;
264
+ }
265
+
266
+ export declare interface GeoVideoArchiveSourceOptions<TFrame> {
267
+ /** Archive identity, the prefix of every frame key. */
268
+ id: string;
269
+ chunks: readonly GeoVideoArchiveChunk[];
270
+ /** Chunk sources kept open (decoder, video element); at least 2. */
271
+ maxOpenChunks?: number;
272
+ /** Decoded frames cached per chunk source. */
273
+ frameCacheSize?: number;
274
+ /**
275
+ * Progress through a chunk past which the next chunk is opened and its
276
+ * first frame decoded; above 1 disables prefetching.
277
+ */
278
+ prefetchAt?: number;
279
+ /**
280
+ * Longest gap bridged between the last step of a chunk and the first of
281
+ * the next one, in ms. By default 1.5 times the largest step interval at
282
+ * that boundary, and no bridge when both neighbouring chunks hold a
283
+ * single step (no cadence known). Unbridged gaps are out of coverage.
284
+ */
285
+ maxGap?: number;
286
+ loadManifest?: (url: string) => Promise<GeoVideoManifest>;
287
+ createFrameSource?: (manifest: GeoVideoManifest, options: {
288
+ cacheSize: number;
289
+ }) => GeoVideoFrameReader<TFrame>;
290
+ }
291
+
149
292
  export declare type GeoVideoBounds = [
150
293
  west: number,
151
294
  south: number,
@@ -159,11 +302,34 @@ north: number
159
302
  */
160
303
  export declare function geoVideoChunkSources(source: CatalogGeoVideoArchiveSource, index: GeoVideoIndex, entry: CatalogEntry): CatalogGeoVideoSource[];
161
304
 
305
+ /** First and last encoded sample of a chunk, UTC milliseconds. */
306
+ export declare interface GeoVideoChunkSpan {
307
+ start: number;
308
+ end: number;
309
+ }
310
+
311
+ /** Scalar values (NaN invalid) or u/v components (NaN invalid). */
312
+ export declare type GeoVideoFrameData = Float32Array | GeoVideoVectorFrame;
313
+
314
+ /** The part of a frame source an archive reads. */
315
+ export declare interface GeoVideoFrameReader<TFrame> {
316
+ frame(index: number, request?: GeoVideoFrameRequest): Promise<TFrame>;
317
+ release(): void;
318
+ }
319
+
320
+ /** Options of one frame request. */
321
+ export declare interface GeoVideoFrameRequest {
322
+ /** Abandons this request only; the decode stops once no request needs it. */
323
+ signal?: AbortSignal;
324
+ }
325
+
162
326
  /**
163
327
  * GeoVideo frames read one time step at a time (seek, no playback): video
164
- * and static mask loading, luma readback, a serial decode queue that
165
- * cancelAll() aborts, and a small LRU cache of decoded frames. Subclasses
166
- * turn the luma codes of a frame into values.
328
+ * and static mask loading, luma readback, a serial decode queue, and a small
329
+ * LRU cache of decoded frames. Requests for the same step share one decode;
330
+ * each can be abandoned with its own signal, and the decode is dropped once
331
+ * no request waits for it. cancelAll() aborts every pending decode.
332
+ * Subclasses turn the luma codes of a frame into values.
167
333
  */
168
334
  export declare abstract class GeoVideoFrameSource<TFrame> {
169
335
  /** Grid size; the video stacks `planes` grids vertically. */
@@ -179,21 +345,32 @@ export declare abstract class GeoVideoFrameSource<TFrame> {
179
345
  private initPromise;
180
346
  private presented;
181
347
  private primed;
348
+ /** Serializes seeks: the previous decode, settled or not, runs first. */
182
349
  private queue;
183
- private epoch;
350
+ /** LRU of decoded and pending steps. */
184
351
  private readonly frames;
352
+ /** Pending decodes, including those the LRU already evicted. */
353
+ private readonly pending;
185
354
  constructor(manifest: GeoVideoManifest, planes: number, options?: {
186
355
  cacheSize?: number;
187
356
  });
188
357
  /** Codes of the stacked planes and the per-cell mask to frame values. */
189
358
  protected abstract decodeCodes(codes: Uint8Array, mask: Uint8Array, threshold: number): TFrame;
190
359
  init(): Promise<void>;
191
- /** Abort queued frame decodes; frames already decoded stay cached. */
360
+ /** Abort every pending frame decode; frames already decoded stay cached. */
192
361
  cancelAll(): void;
193
362
  /** Release the video element and GL context; a later init() reloads them. */
194
363
  release(): void;
195
- /** One decode per time step, cached. */
196
- frame(index: number): Promise<TFrame>;
364
+ /**
365
+ * One decode per time step, cached and shared by concurrent requests.
366
+ * Aborting `request.signal` rejects this request with an AbortError; the
367
+ * decode goes on while another request waits for it.
368
+ */
369
+ frame(index: number, request?: GeoVideoFrameRequest): Promise<TFrame>;
370
+ private enqueue;
371
+ /** A request left; drop the decode when it was the last one waiting. */
372
+ private leave;
373
+ private drop;
197
374
  private load;
198
375
  private loadMask;
199
376
  private loadVideo;
@@ -205,9 +382,30 @@ export declare abstract class GeoVideoFrameSource<TFrame> {
205
382
  * playback would otherwise buffer far beyond the requested frame.
206
383
  */
207
384
  private primeDecoder;
208
- protected decode(index: number, epoch: number): Promise<TFrame>;
385
+ /**
386
+ * Seek, read back and decode one step. `signal` aborts it between steps;
387
+ * a seek already started completes first, keeping the queue serial.
388
+ */
389
+ protected decode(index: number, signal: AbortSignal): Promise<TFrame>;
209
390
  }
210
391
 
392
+ /**
393
+ * Grid of decoded frame values. `bounds` are the outer cell edges
394
+ * [west, south, east, north] in degrees, so cell (column i, row j) is
395
+ * centered at west + (i + 0.5)·dx, north − (j + 0.5)·dy with
396
+ * dx = (east − west) / width and dy = (north − south) / height; an east
397
+ * below west crosses the antimeridian (east + 360). Row 0 is the northern
398
+ * row, values are row-major.
399
+ */
400
+ export declare interface GeoVideoGrid {
401
+ width: number;
402
+ height: number;
403
+ bounds: GeoVideoBounds;
404
+ rowOrder: "north-to-south";
405
+ }
406
+
407
+ export declare function geoVideoGrid(manifest: GeoVideoManifest): GeoVideoGrid;
408
+
211
409
  /** Mutable listing of an archive's published chunks, written by the renderer. */
212
410
  export declare interface GeoVideoIndex {
213
411
  schemaVersion: 1;
@@ -234,6 +432,12 @@ export declare interface GeoVideoIndexChunk {
234
432
  provisional?: boolean;
235
433
  }
236
434
 
435
+ /**
436
+ * Catalog-free chunk descriptors of an index, manifest URLs resolved
437
+ * against the index URL, in index order.
438
+ */
439
+ export declare function geoVideoIndexChunks(index: GeoVideoIndex, indexUrl: string): GeoVideoArchiveChunk[];
440
+
237
441
  export declare interface GeoVideoManifest {
238
442
  schemaVersion: 3;
239
443
  id: string;
@@ -283,6 +487,9 @@ declare interface GeoVideoRangeTimeline {
283
487
  interpolation: "linear" | "nearest";
284
488
  }
285
489
 
490
+ /** Interpolate between bracketing steps, or hold the last step at or before. */
491
+ export declare type GeoVideoSampleMode = "interpolate" | "discrete";
492
+
286
493
  declare interface GeoVideoSampleSequenceTimeline {
287
494
  kind: "sample-sequence";
288
495
  values: string[];
@@ -383,8 +590,34 @@ export declare class GeoVideoVectorSource extends GeoVideoFrameSource<GeoVideoVe
383
590
 
384
591
  export declare function getPalettes(): PaletteMeta[];
385
592
 
593
+ /** Color grade of a style `particles.grade`; an object tunes the vibrant one. */
594
+ export declare function gradeToColorGrade(grade: ParticleGrade | undefined): ColorGrade;
595
+
596
+ /** Vibrant grade values; each one left out takes the vibrant preset's. */
597
+ declare interface GradeTuning {
598
+ /** Mid-tone lift [0, 4]. */
599
+ exposure?: number;
600
+ /** S-curve strength [0, 1]. */
601
+ contrast?: number;
602
+ /** Vibrance-weighted saturation [-1, 1]. */
603
+ saturation?: number;
604
+ /** Push of the bright half toward white [0, 1]. */
605
+ highlights?: number;
606
+ }
607
+
386
608
  export declare function isGeoVideoArchiveSource(source: CatalogSource): source is CatalogGeoVideoArchiveSource;
387
609
 
610
+ /** A `#rgb` or `#rrggbb` color. */
611
+ export declare const isHexColor: (value: unknown) => value is string;
612
+
613
+ /** A partial style: any key left out takes the value below it. */
614
+ declare interface LayerStyleInput {
615
+ palette?: string;
616
+ renderMode?: StyleRenderMode;
617
+ particles?: ParticleStyleInput;
618
+ raster?: Partial<RasterStyle>;
619
+ }
620
+
388
621
  export declare function loadGeoVideoIndex(url: string, signal?: AbortSignal): Promise<GeoVideoIndex>;
389
622
 
390
623
  export declare function loadGeoVideoManifest(source: string | GeoVideoManifest, signal?: AbortSignal): Promise<GeoVideoManifest>;
@@ -403,6 +636,18 @@ export declare function nextChunk<T extends CatalogSource>(chunks: readonly T[],
403
636
  time: number;
404
637
  } | null;
405
638
 
639
+ /**
640
+ * The chunk following the one that ends at `currentEnd` inside `range`, or
641
+ * with `loop`, the first one inside it, with the time playback resumes at.
642
+ */
643
+ export declare function nextChunkSpan<T extends GeoVideoChunkSpan>(chunks: readonly T[], currentEnd: number, options?: {
644
+ range?: readonly [number, number] | null;
645
+ loop?: boolean;
646
+ }): {
647
+ chunk: T;
648
+ time: number;
649
+ } | null;
650
+
406
651
  /**
407
652
  * The candidate whose sample range overlaps `chunk` the most: archives
408
653
  * sampled at different hours (six-hourly from 00:00, daily at 12:00) still
@@ -410,6 +655,13 @@ export declare function nextChunk<T extends CatalogSource>(chunks: readonly T[],
410
655
  */
411
656
  export declare function pairChunk<T extends CatalogSource>(chunk: CatalogSource, candidates: readonly T[]): T | null;
412
657
 
658
+ /**
659
+ * The candidate whose sample range overlaps `span` the most: archives
660
+ * sampled at different hours (six-hourly from 00:00, daily at 12:00) still
661
+ * pair by calendar period. Null when none overlaps.
662
+ */
663
+ export declare function pairChunkSpan<T extends GeoVideoChunkSpan>(span: GeoVideoChunkSpan, candidates: readonly T[]): T | null;
664
+
413
665
  export declare interface PaletteMeta {
414
666
  id: string;
415
667
  label: string;
@@ -417,6 +669,46 @@ export declare interface PaletteMeta {
417
669
  colors: string[];
418
670
  }
419
671
 
672
+ /** Particle trail color grade: a preset, or the vibrant one tuned. */
673
+ declare type ParticleGrade = "off" | "vibrant" | GradeTuning;
674
+
675
+ declare interface ParticleStyle {
676
+ /** Particles per device pixel, (0, 0.2]. */
677
+ density: number;
678
+ /** Css px per frame for the fastest value of the field, (0, 10]. */
679
+ speed: number;
680
+ /** Trail length, [0, 1] (longer when higher). */
681
+ fade: number;
682
+ /** Trail color grade; replaced as a whole, not merged. */
683
+ grade: ParticleGrade;
684
+ /** Solid color under the trails; replaced as a whole, not merged. */
685
+ backdrop: BackdropStyle;
686
+ }
687
+
688
+ /** Partial particle style; a partial backdrop takes the defaults' keys. */
689
+ declare type ParticleStyleInput = Partial<Omit<ParticleStyle, "backdrop">> & {
690
+ backdrop?: Partial<BackdropStyle>;
691
+ };
692
+
693
+ /** `float random(uvec3 v)`, an integer hash in [0, 1); GLSL ES 3.0. */
694
+ export declare const RANDOM_GLSL: string;
695
+
696
+ declare interface RasterStyle {
697
+ opacity: number;
698
+ logScale: boolean;
699
+ /** Vibrance adjustment, [-1, 1]. */
700
+ vibrance: number;
701
+ /** Fixed physical-value domain; null follows the data. */
702
+ colorDomain: [number, number] | null;
703
+ }
704
+
705
+ /**
706
+ * Complete backdrop from partial input. Missing or invalid values take the
707
+ * defaults, opacity is clamped; `enabled` defaults to true when any input is
708
+ * given, so `{ opacity: 0.2 }` means "on".
709
+ */
710
+ export declare function resolveBackdrop(input?: Partial<BackdropStyle>): BackdropStyle;
711
+
420
712
  /**
421
713
  * Complete grade from partial input. Missing or non-finite values take the
422
714
  * vibrant preset, others are clamped to their range; `enabled` defaults to
@@ -430,6 +722,13 @@ export declare function resolveColorRamp(input: ColorRampInput, options?: {
430
722
 
431
723
  export declare type ScalarColorDomain = [number, number];
432
724
 
725
+ /**
726
+ * Layer style: how a layer looks, with the same keys in the catalog
727
+ * `defaults`, the engines and story views. Playback (how time moves) is not
728
+ * part of it, so `particles.speed` is always the particle speed.
729
+ */
730
+ declare type StyleRenderMode = "particles" | "raster" | "raster+particles";
731
+
433
732
  /**
434
733
  * Camera-aware per-frame fade opacity: eases toward a short retention while
435
734
  * the camera moves, then back to the configured one. Smoothstep avoids
@@ -467,6 +766,9 @@ declare type VectorFieldSource = Pick<ZarrSource, "init" | "cancelAll" | "getCoo
467
766
  getValueDomain?(): number;
468
767
  };
469
768
 
769
+ /** `vec3 applyVibrance(vec3 c, float v)`; GLSL ES 1.0 and 3.0. */
770
+ export declare const VIBRANCE_GLSL: string;
771
+
470
772
  declare interface ZarrAttrs {
471
773
  _ARRAY_DIMENSIONS?: string[];
472
774
  units?: string;
package/dist/engine.js CHANGED
@@ -1,29 +1,82 @@
1
- import { C as o, a as r, G as s, b as i, T as d, c as l, d as t, e as c, f as G, g as V, h as m, i as n, j as u, k as C, l as f, m as p, n as v, p as x, r as R, o as S, v as T, q as O } from "./geovideo-index-CD5wflJT.js";
2
- import { G as h } from "./GeoVideoScalarSource-DoQAnyTy.js";
3
- import { v as k } from "./scalar-color-domain-PEK8Hxg1.js";
1
+ import { D as d, E as i, F as l, G as m, T as u, H as v, b as x, I as g, c as p, J as f, K as G, l as V, B as C, L as b, M as S, q as _, x as O, y as R, A as h, m as A, z as L, N as F, O as T, P as k, o as y, Q as I, C as D, v as B } from "./geovideo-index-CMGVia5M.js";
2
+ import { B as w, C as M, e as N, b as P, d as z, c as H, g as K, i as q, a as J, r as Q } from "./backdrop-DctkJ45Q.js";
3
+ var e = `vec3 applyVibrance(vec3 c, float v) {
4
+ float mx = max(c.r, max(c.g, c.b));
5
+ float mn = min(c.r, min(c.g, c.b));
6
+ float boost = v * (1.0 - (mx - mn));
7
+ float luma = dot(c, vec3(0.299, 0.587, 0.114));
8
+ return mix(vec3(luma), c, 1.0 + boost);
9
+ }
10
+
11
+ vec3 gradeColor(vec3 c, vec4 g) {
12
+ float m = max(c.r, max(c.g, c.b));
13
+ if (m > 0.0) {
14
+
15
+
16
+ float e = g.x > 1e-3 ? (1.0 - exp(-g.x * m)) / (1.0 - exp(-g.x)) : m;
17
+
18
+ e += g.w * smoothstep(0.5, 1.0, e) * (1.0 - e);
19
+ c *= e / m;
20
+ }
21
+
22
+ c = mix(c, c * c * (3.0 - 2.0 * c), g.y);
23
+ return clamp(applyVibrance(c, g.z), 0.0, 1.0);
24
+ }`, a = `uint pcg(uint v) {
25
+ uint state = v * 747796405u + 2891336453u;
26
+ uint word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;
27
+ return (word >> 22u) ^ word;
28
+ }
29
+
30
+ float random(uvec3 v) {
31
+ return float(pcg(v.x ^ pcg(v.y ^ pcg(v.z))) >> 8u) * (1.0 / 16777216.0);
32
+ }`, o = `vec3 applyVibrance(vec3 c, float v) {
33
+ float mx = max(c.r, max(c.g, c.b));
34
+ float mn = min(c.r, min(c.g, c.b));
35
+ float boost = v * (1.0 - (mx - mn));
36
+ float luma = dot(c, vec3(0.299, 0.587, 0.114));
37
+ return mix(vec3(luma), c, 1.0 + boost);
38
+ }`;
39
+ const r = o, n = e, c = a;
4
40
  export {
5
- o as COLOR_GRADE_OFF,
6
- r as COLOR_GRADE_VIBRANT,
7
- s as GeoVideoFrameSource,
8
- h as GeoVideoScalarSource,
9
- i as GeoVideoVectorSource,
10
- d as TrailFade,
11
- l as colorGradeVec4,
12
- t as createColorRampTexture,
13
- c as createProgram,
41
+ w as BACKDROP_OFF,
42
+ n as COLOR_GRADE_GLSL,
43
+ M as COLOR_GRADE_OFF,
44
+ N as COLOR_GRADE_VIBRANT,
45
+ d as GeoVideoArchiveSource,
46
+ i as GeoVideoFrameSource,
47
+ l as GeoVideoScalarSource,
48
+ m as GeoVideoVectorSource,
49
+ c as RANDOM_GLSL,
50
+ u as TrailFade,
51
+ r as VIBRANCE_GLSL,
52
+ v as assertGeoVideoIndexIdentity,
53
+ P as backdropVec4,
54
+ z as colorGradeToGrade,
55
+ H as colorGradeVec4,
56
+ x as createColorRampTexture,
57
+ g as createGeoVideoFrameSource,
58
+ p as createProgram,
59
+ f as createShader,
14
60
  G as fadeToFrames,
15
61
  V as fadeToOpacity,
16
- m as geoVideoChunkSources,
17
- n as geoVideoTimelineValues,
18
- u as getPalettes,
19
- C as isGeoVideoArchiveSource,
20
- f as loadGeoVideoIndex,
21
- p as loadGeoVideoManifest,
22
- v as nextChunk,
23
- x as pairChunk,
24
- R as resolveColorGrade,
25
- S as resolveColorRamp,
26
- T as validateGeoVideoIndex,
27
- O as validateGeoVideoManifest,
28
- k as validateScalarColorDomain
62
+ C as geoVideoChunkSources,
63
+ b as geoVideoGrid,
64
+ S as geoVideoIndexChunks,
65
+ _ as geoVideoTimelineValues,
66
+ O as getPalettes,
67
+ K as gradeToColorGrade,
68
+ R as isGeoVideoArchiveSource,
69
+ q as isHexColor,
70
+ h as loadGeoVideoIndex,
71
+ A as loadGeoVideoManifest,
72
+ L as nextChunk,
73
+ F as nextChunkSpan,
74
+ T as pairChunk,
75
+ k as pairChunkSpan,
76
+ J as resolveBackdrop,
77
+ Q as resolveColorGrade,
78
+ y as resolveColorRamp,
79
+ I as validateGeoVideoIndex,
80
+ D as validateGeoVideoManifest,
81
+ B as validateScalarColorDomain
29
82
  };