layershift 0.2.2 → 0.4.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.
Files changed (47) hide show
  1. package/README.md +14 -0
  2. package/dist/components/layershift.js +921 -647
  3. package/dist/npm/layershift.es.js +3354 -2266
  4. package/dist/types/components/layershift/global.d.ts +2 -2
  5. package/dist/types/components/layershift/index.d.ts +5 -1
  6. package/dist/types/components/layershift/index.d.ts.map +1 -1
  7. package/dist/types/components/layershift/layershift-element.d.ts +41 -10
  8. package/dist/types/components/layershift/layershift-element.d.ts.map +1 -1
  9. package/dist/types/components/layershift/lifecycle.d.ts +6 -0
  10. package/dist/types/components/layershift/lifecycle.d.ts.map +1 -1
  11. package/dist/types/components/layershift/portal-element.d.ts +13 -4
  12. package/dist/types/components/layershift/portal-element.d.ts.map +1 -1
  13. package/dist/types/components/layershift/types.d.ts +30 -9
  14. package/dist/types/components/layershift/types.d.ts.map +1 -1
  15. package/dist/types/depth-analysis.d.ts +10 -6
  16. package/dist/types/depth-analysis.d.ts.map +1 -1
  17. package/dist/types/depth-effect-renderer.d.ts +186 -0
  18. package/dist/types/depth-effect-renderer.d.ts.map +1 -0
  19. package/dist/types/depth-estimator.d.ts +96 -0
  20. package/dist/types/depth-estimator.d.ts.map +1 -0
  21. package/dist/types/input-handler.d.ts +8 -2
  22. package/dist/types/input-handler.d.ts.map +1 -1
  23. package/dist/types/jfa-distance-field.d.ts +78 -0
  24. package/dist/types/jfa-distance-field.d.ts.map +1 -0
  25. package/dist/types/media-source.d.ts +76 -0
  26. package/dist/types/media-source.d.ts.map +1 -0
  27. package/dist/types/portal-renderer.d.ts +65 -66
  28. package/dist/types/portal-renderer.d.ts.map +1 -1
  29. package/dist/types/precomputed-depth.d.ts +14 -51
  30. package/dist/types/precomputed-depth.d.ts.map +1 -1
  31. package/dist/types/quality.d.ts +95 -0
  32. package/dist/types/quality.d.ts.map +1 -0
  33. package/dist/types/render-pass.d.ts +171 -0
  34. package/dist/types/render-pass.d.ts.map +1 -0
  35. package/dist/types/renderer-base.d.ts +129 -0
  36. package/dist/types/renderer-base.d.ts.map +1 -0
  37. package/dist/types/shared/channel-to-renderer.d.ts +72 -0
  38. package/dist/types/shared/channel-to-renderer.d.ts.map +1 -0
  39. package/dist/types/shared/filter-config.d.ts +184 -0
  40. package/dist/types/shared/filter-config.d.ts.map +1 -0
  41. package/dist/types/video-source.d.ts +0 -1
  42. package/dist/types/video-source.d.ts.map +1 -1
  43. package/dist/types/webgl-utils.d.ts +29 -0
  44. package/dist/types/webgl-utils.d.ts.map +1 -0
  45. package/package.json +31 -5
  46. package/dist/types/parallax-renderer.d.ts +0 -175
  47. package/dist/types/parallax-renderer.d.ts.map +0 -1
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Browser-based monocular depth estimation using Depth Anything v2 via ONNX Runtime Web.
3
+ *
4
+ * Runs inference on the main thread:
5
+ * - **WebGPU EP** (preferred): GPU-accelerated, ~200ms/frame on modern hardware.
6
+ * - **WASM EP** (fallback): Uses onnxruntime's built-in proxy worker for off-thread execution.
7
+ *
8
+ * A double-buffer pattern bridges async inference (~5fps) with the synchronous
9
+ * `readDepth()` contract that the renderer expects every frame at 60fps.
10
+ *
11
+ * @see ADR-014 for the architectural decision and rationale.
12
+ */
13
+ import type { TextureImageSource } from './media-source';
14
+ /** Progress information emitted during model download. */
15
+ export interface ModelDownloadProgress {
16
+ /** Bytes received so far. */
17
+ receivedBytes: number;
18
+ /** Total bytes (from Content-Length header), or null if unknown. */
19
+ totalBytes: number | null;
20
+ /** Download fraction 0–1 (0 if total is unknown). */
21
+ fraction: number;
22
+ /** Human-readable status label. */
23
+ label: string;
24
+ }
25
+ /** Callback invoked during model download with progress updates. */
26
+ export type OnModelProgress = (progress: ModelDownloadProgress) => void;
27
+ export declare class DepthEstimator {
28
+ private readonly depthWidth;
29
+ private readonly depthHeight;
30
+ private ort;
31
+ private session;
32
+ private inputName;
33
+ private outputName;
34
+ private frontBuffer;
35
+ private backBuffer;
36
+ private inferenceInFlight;
37
+ private readyResolve;
38
+ private readonly readyPromise;
39
+ private captureCanvas;
40
+ private captureCtx;
41
+ private disposed;
42
+ constructor(depthWidth: number, depthHeight: number);
43
+ /**
44
+ * Load the ONNX model and prepare the inference session.
45
+ *
46
+ * Downloads the model with progress tracking, then creates the ONNX
47
+ * session from the in-memory buffer. Tries WebGPU EP first
48
+ * (GPU-accelerated on main thread), falls back to WASM EP.
49
+ */
50
+ init(modelUrl: string, onProgress?: OnModelProgress): Promise<void>;
51
+ /** Wait for model loading and session creation to complete. */
52
+ waitUntilReady(): Promise<void>;
53
+ /**
54
+ * Submit a frame for depth estimation. Non-blocking.
55
+ *
56
+ * If a previous inference is still in-flight, the frame is silently
57
+ * dropped. This naturally throttles to the model's inference rate (~5fps),
58
+ * matching the precomputed depth cadence.
59
+ */
60
+ submitFrame(source: TextureImageSource): void;
61
+ /**
62
+ * Submit a single frame and wait for the result.
63
+ *
64
+ * Used for still images where we need depth before rendering starts.
65
+ */
66
+ submitFrameAndWait(source: TextureImageSource): Promise<Uint8Array>;
67
+ /** Return the latest available depth buffer. Always synchronous. */
68
+ getLatestDepth(): Uint8Array;
69
+ dispose(): void;
70
+ private runInference;
71
+ /**
72
+ * Convert RGBA ImageData → NCHW float32 tensor with ImageNet normalisation.
73
+ */
74
+ private preprocess;
75
+ /**
76
+ * Bilinear resize from model output dimensions → depth texture dimensions,
77
+ * normalise to full [0, 255] range, and write into `backBuffer`.
78
+ *
79
+ * Depth Anything v2 (like v1) outputs inverse depth (disparity-like):
80
+ * higher raw values = closer to camera. This matches the convention used
81
+ * by the precompute pipeline (`normalizeToUint8` in scripts/precompute-depth.ts),
82
+ * so no inversion is applied: 255 = nearest, 0 = farthest.
83
+ */
84
+ private postProcess;
85
+ }
86
+ /**
87
+ * Create and initialise a DepthEstimator.
88
+ *
89
+ * Returns a ready-to-use estimator. The front buffer starts as flat
90
+ * mid-gray (128) so the renderer can start immediately while the first
91
+ * real inference result arrives asynchronously.
92
+ *
93
+ * @param onProgress — Optional callback for download progress updates.
94
+ */
95
+ export declare function createDepthEstimator(modelUrl: string, depthWidth: number, depthHeight: number, onProgress?: OnModelProgress): Promise<DepthEstimator>;
96
+ //# sourceMappingURL=depth-estimator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"depth-estimator.d.ts","sourceRoot":"","sources":["../../src/depth-estimator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAMzD,0DAA0D;AAC1D,MAAM,WAAW,qBAAqB;IACpC,6BAA6B;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,qDAAqD;IACrD,QAAQ,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,oEAAoE;AACpE,MAAM,MAAM,eAAe,GAAG,CAAC,QAAQ,EAAE,qBAAqB,KAAK,IAAI,CAAC;AAkCxE,qBAAa,cAAc;IA0BvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAzB9B,OAAO,CAAC,GAAG,CAA0B;IACrC,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,UAAU,CAAM;IAIxB,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,UAAU,CAAa;IAG/B,OAAO,CAAC,iBAAiB,CAAS;IAGlC,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;IAG7C,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,UAAU,CAAyC;IAE3D,OAAO,CAAC,QAAQ,CAAS;gBAGN,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM;IAiBtC;;;;;;OAMG;IACG,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA8CzE,+DAA+D;IAC/D,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ/B;;;;;;OAMG;IACH,WAAW,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI;IAM7C;;;;OAIG;IACG,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,CAAC;IAYzE,oEAAoE;IACpE,cAAc,IAAI,UAAU;IAQ5B,OAAO,IAAI,IAAI;YAaD,YAAY;IA2C1B;;OAEG;IACH,OAAO,CAAC,UAAU;IAelB;;;;;;;;OAQG;IACH,OAAO,CAAC,WAAW;CA6CpB;AAMD;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,eAAe,GAC3B,OAAO,CAAC,cAAc,CAAC,CAIzB"}
@@ -1,6 +1,12 @@
1
- export interface ParallaxInput {
1
+ export interface EffectInput {
2
2
  x: number;
3
3
  y: number;
4
+ /** Depth offset for blur curve lookup. Used by rack focus focal band input. */
5
+ focalBandOffset?: number;
6
+ /** Tilted focal plane normal vector [nx, ny, nz] (Scheimpflug simulation). */
7
+ tiltPlaneNormal?: [number, number, number];
8
+ /** Tilted focal plane distance constant (dot(normal, focalPoint)). */
9
+ tiltPlaneD?: number;
4
10
  }
5
11
  export declare class InputHandler {
6
12
  private readonly motionLerpFactor;
@@ -16,7 +22,7 @@ export declare class InputHandler {
16
22
  get isMotionSupported(): boolean;
17
23
  get isMotionEnabled(): boolean;
18
24
  enableMotionControls(): Promise<boolean>;
19
- update(): ParallaxInput;
25
+ update(): EffectInput;
20
26
  dispose(): void;
21
27
  private readonly handleMouseMove;
22
28
  private readonly resetPointerTarget;
@@ -1 +1 @@
1
- {"version":3,"file":"input-handler.d.ts","sourceRoot":"","sources":["../../src/input-handler.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AASD,qBAAa,YAAY;IAUX,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IAT7C,OAAO,CAAC,aAAa,CAAiC;IACtD,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,cAAc,CAAiC;IACvD,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,sBAAsB,CAAS;IACvC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,YAAY,CAAK;gBAEI,gBAAgB,EAAE,MAAM;IASrD,IAAI,iBAAiB,IAAI,OAAO,CAkB/B;IAED,IAAI,eAAe,IAAI,OAAO,CAE7B;IAEK,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC;IAsB9C,MAAM,IAAI,aAAa;IAqBvB,OAAO,IAAI,IAAI;IAaf,OAAO,CAAC,QAAQ,CAAC,eAAe,CAK9B;IAEF,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAGjC;IAEF,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAQ/B;IAEF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAO9B;IAEF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAI7B;IAEF,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAOtC;CACH"}
1
+ {"version":3,"file":"input-handler.d.ts","sourceRoot":"","sources":["../../src/input-handler.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,+EAA+E;IAC/E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,8EAA8E;IAC9E,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AASD,qBAAa,YAAY;IAUX,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IAT7C,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,sBAAsB,CAAS;IACvC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,YAAY,CAAK;gBAEI,gBAAgB,EAAE,MAAM;IASrD,IAAI,iBAAiB,IAAI,OAAO,CAkB/B;IAED,IAAI,eAAe,IAAI,OAAO,CAE7B;IAEK,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC;IAsB9C,MAAM,IAAI,WAAW;IAqBrB,OAAO,IAAI,IAAI;IAaf,OAAO,CAAC,QAAQ,CAAC,eAAe,CAK9B;IAEF,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAGjC;IAEF,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAQ/B;IAEF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAO9B;IAEF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAI7B;IAEF,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAOtC;CACH"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * JFA Distance Field — Jump Flood Algorithm for screen-space distance fields.
3
+ *
4
+ * Computes a distance field from a binary mask (e.g., logo silhouette) using:
5
+ * 1. Edge seed extraction from the mask
6
+ * 2. Jump Flood iterations to propagate nearest-seed info
7
+ * 3. Distance conversion to a normalized scalar field
8
+ *
9
+ * Extracted from PortalRenderer to share orchestration logic between
10
+ * WebGL2 and WebGPU backends.
11
+ */
12
+ import type { RenderPass } from './render-pass';
13
+ /** Parameters for computing the distance field each frame. */
14
+ export interface JFAComputeParams {
15
+ /** Mask shader pass (renders logo mesh to binary mask). */
16
+ maskPass: RenderPass;
17
+ /** JFA seed extraction pass. */
18
+ seedPass: RenderPass;
19
+ /** JFA flood iteration pass. */
20
+ floodPass: RenderPass;
21
+ /** JFA distance conversion pass. */
22
+ distPass: RenderPass;
23
+ /** VAO for the logo mesh (used in mask rendering). */
24
+ maskVao: WebGLVertexArrayObject;
25
+ /** Fullscreen quad VAO (used for seed/flood/dist passes). */
26
+ quadVao: WebGLVertexArrayObject;
27
+ /** Mesh scale X in NDC. */
28
+ meshScaleX: number;
29
+ /** Mesh scale Y in NDC. */
30
+ meshScaleY: number;
31
+ /** Number of triangulated indices in the logo mesh. */
32
+ stencilIndexCount: number;
33
+ /** Maximum distance range for normalization (max of bevelWidth, edgeOcclusionWidth). */
34
+ distRange: number;
35
+ }
36
+ export declare class JFADistanceField {
37
+ private readonly gl;
38
+ private readonly hasColorBufferFloat;
39
+ private maskFbo;
40
+ private maskTex;
41
+ private pingFbo;
42
+ private pingTex;
43
+ private pongFbo;
44
+ private pongTex;
45
+ private distFbo;
46
+ private distTex;
47
+ private _width;
48
+ private _height;
49
+ private _dirty;
50
+ constructor(gl: WebGL2RenderingContext, hasColorBufferFloat: boolean);
51
+ get width(): number;
52
+ get height(): number;
53
+ get isDirty(): boolean;
54
+ get distanceTexture(): WebGLTexture | null;
55
+ get maskTexture(): WebGLTexture | null;
56
+ markDirty(): void;
57
+ /**
58
+ * Create (or recreate) all JFA FBO/texture resources at the given canvas
59
+ * dimensions, divided by the quality tier's JFA divisor.
60
+ */
61
+ createResources(canvasWidth: number, canvasHeight: number, jfaDivisor: number): void;
62
+ /**
63
+ * Compute the distance field from the logo mask.
64
+ *
65
+ * Pipeline: mask render → seed extraction → JFA flood → distance conversion.
66
+ * After completion, `distanceTexture` holds the result and `isDirty` is false.
67
+ *
68
+ * The caller is responsible for restoring the viewport after this call.
69
+ */
70
+ compute(params: JFAComputeParams): void;
71
+ /**
72
+ * Compute the sequence of JFA step sizes for the given resolution.
73
+ * Steps halve from ceil(maxDim/2) down to 1.
74
+ */
75
+ static computeFloodIterations(width: number, height: number): number[];
76
+ dispose(): void;
77
+ }
78
+ //# sourceMappingURL=jfa-distance-field.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jfa-distance-field.d.ts","sourceRoot":"","sources":["../../src/jfa-distance-field.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAMhD,8DAA8D;AAC9D,MAAM,WAAW,gBAAgB;IAC/B,2DAA2D;IAC3D,QAAQ,EAAE,UAAU,CAAC;IACrB,gCAAgC;IAChC,QAAQ,EAAE,UAAU,CAAC;IACrB,gCAAgC;IAChC,SAAS,EAAE,UAAU,CAAC;IACtB,oCAAoC;IACpC,QAAQ,EAAE,UAAU,CAAC;IACrB,sDAAsD;IACtD,OAAO,EAAE,sBAAsB,CAAC;IAChC,6DAA6D;IAC7D,OAAO,EAAE,sBAAsB,CAAC;IAChC,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,wFAAwF;IACxF,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAyB;IAC5C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAU;IAG9C,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,OAAO,CAA6B;IAG5C,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,MAAM,CAAQ;gBAEV,EAAE,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,OAAO;IAOpE,IAAI,KAAK,IAAI,MAAM,CAAwB;IAC3C,IAAI,MAAM,IAAI,MAAM,CAAyB;IAC7C,IAAI,OAAO,IAAI,OAAO,CAAwB;IAC9C,IAAI,eAAe,IAAI,YAAY,GAAG,IAAI,CAAyB;IACnE,IAAI,WAAW,IAAI,YAAY,GAAG,IAAI,CAAyB;IAE/D,SAAS,IAAI,IAAI;IAMjB;;;OAGG;IACH,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IA6CpF;;;;;;;OAOG;IACH,OAAO,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI;IAoGvC;;;OAGG;IACH,MAAM,CAAC,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAetE,OAAO,IAAI,IAAI;CAchB"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Unified media source abstraction.
3
+ *
4
+ * Provides a common interface over HTMLVideoElement, HTMLImageElement,
5
+ * and MediaStream-backed video (camera) so that renderers and Web
6
+ * Components can consume any visual source without branching.
7
+ */
8
+ export type MediaSourceType = 'video' | 'image' | 'camera';
9
+ /**
10
+ * Texture-uploadable image source — the subset of CanvasImageSource that
11
+ * is accepted by both WebGL texImage2D and WebGPU copyExternalImageToTexture.
12
+ * Excludes SVGImageElement which neither API supports.
13
+ */
14
+ export type TextureImageSource = HTMLCanvasElement | HTMLImageElement | HTMLVideoElement | ImageBitmap | OffscreenCanvas | VideoFrame;
15
+ export interface MediaSource {
16
+ readonly type: MediaSourceType;
17
+ readonly width: number;
18
+ readonly height: number;
19
+ readonly currentTime: number;
20
+ /** Duration in seconds. Infinity for camera, 0 for images, finite for video. */
21
+ readonly duration: number;
22
+ /** Whether playback is currently paused. Always false for images. */
23
+ readonly paused: boolean;
24
+ /** True for video and camera (continuous frame stream). */
25
+ readonly isLive: boolean;
26
+ /** Return the underlying element suitable for texImage2D / copyExternalImageToTexture. */
27
+ getImageSource(): TextureImageSource | null;
28
+ requestVideoFrameCallback?(cb: (now: number, metadata: VideoFrameCallbackMetadata) => void): number;
29
+ cancelVideoFrameCallback?(handle: number): void;
30
+ play?(): Promise<void>;
31
+ pause?(): void;
32
+ addEventListener?(type: string, listener: EventListener): void;
33
+ removeEventListener?(type: string, listener: EventListener): void;
34
+ dispose(): void;
35
+ }
36
+ export interface VideoSourceOptions {
37
+ parent?: Node;
38
+ loop?: boolean;
39
+ muted?: boolean;
40
+ autoplay?: boolean;
41
+ }
42
+ /**
43
+ * Create a MediaSource backed by an HTMLVideoElement.
44
+ *
45
+ * The video is appended to `parent` (default: `document.body`) as a
46
+ * hidden element and metadata is loaded before the promise resolves.
47
+ */
48
+ export declare function createVideoSource(url: string, options?: VideoSourceOptions): Promise<MediaSource>;
49
+ export interface ImageSourceOptions {
50
+ parent?: Node;
51
+ }
52
+ /**
53
+ * Create a MediaSource backed by an HTMLImageElement.
54
+ *
55
+ * Static source — `currentTime` is always 0, `isLive` is false.
56
+ * RVFC is not available; renderers fall back to RAF-only.
57
+ */
58
+ export declare function createImageSource(url: string, _options?: ImageSourceOptions): Promise<MediaSource>;
59
+ export interface CameraSourceOptions {
60
+ parent?: Node;
61
+ }
62
+ /**
63
+ * Create a MediaSource backed by a camera stream (getUserMedia).
64
+ *
65
+ * Live source — `currentTime` ticks with the stream, `isLive` is true.
66
+ * RVFC is available on the underlying video element.
67
+ */
68
+ export declare function createCameraSource(constraints?: MediaStreamConstraints, options?: CameraSourceOptions): Promise<MediaSource>;
69
+ /**
70
+ * Convenience factory that dispatches to the correct source creator
71
+ * based on `sourceType`.
72
+ */
73
+ export declare function createMediaSource(src: string, sourceType: MediaSourceType, options?: VideoSourceOptions & CameraSourceOptions & {
74
+ cameraConstraints?: MediaStreamConstraints;
75
+ }): Promise<MediaSource>;
76
+ //# sourceMappingURL=media-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-source.d.ts","sourceRoot":"","sources":["../../src/media-source.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE3D;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAC1B,iBAAiB,GACjB,gBAAgB,GAChB,gBAAgB,GAChB,WAAW,GACX,eAAe,GACf,UAAU,CAAC;AAEf,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,gFAAgF;IAChF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAEzB,0FAA0F;IAC1F,cAAc,IAAI,kBAAkB,GAAG,IAAI,CAAC;IAE5C,yBAAyB,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,0BAA0B,KAAK,IAAI,GAAG,MAAM,CAAC;IACpG,wBAAwB,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhD,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,KAAK,CAAC,IAAI,IAAI,CAAC;IAEf,gBAAgB,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IAC/D,mBAAmB,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IAElE,OAAO,IAAI,IAAI,CAAC;CACjB;AAMD,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,WAAW,CAAC,CAyBtB;AAkDD,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,IAAI,CAAC;CACf;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,QAAQ,GAAE,kBAAuB,GAChC,OAAO,CAAC,WAAW,CAAC,CAYtB;AAyBD,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,IAAI,CAAC;CACf;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,GAAE,sBAAwC,EACrD,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,WAAW,CAAC,CAkBtB;AAuDD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,eAAe,EAC3B,OAAO,CAAC,EAAE,kBAAkB,GAAG,mBAAmB,GAAG;IAAE,iBAAiB,CAAC,EAAE,sBAAsB,CAAA;CAAE,GAClG,OAAO,CAAC,WAAW,CAAC,CAStB"}
@@ -29,13 +29,23 @@
29
29
  * refraction, chromatic fringe, occlusion — all driven by distance field
30
30
  * and interior depth texture.
31
31
  */
32
- import type { ParallaxInput } from './input-handler';
33
32
  import type { ShapeMesh } from './shape-generator';
33
+ import type { QualityTier } from './quality';
34
+ import { RendererBase } from './renderer-base';
35
+ import type { MediaSource } from './media-source';
34
36
  export interface PortalRendererConfig {
35
37
  parallaxStrength: number;
36
38
  overscanPadding: number;
37
39
  /** POM step count for interior (default: 16). */
38
40
  pomSteps: number;
41
+ /**
42
+ * Adaptive quality tier. Controls render resolution, JFA resolution,
43
+ * depth resolution, and sample counts.
44
+ * - 'auto' — probe device capabilities and classify automatically.
45
+ * - 'high' / 'medium' / 'low' — use the specified tier directly.
46
+ * - undefined — defaults to 'auto'.
47
+ */
48
+ quality?: 'auto' | QualityTier;
39
49
  rimLightIntensity: number;
40
50
  rimLightColor: [number, number, number];
41
51
  rimLightWidth: number;
@@ -66,7 +76,7 @@ export interface PortalRendererConfig {
66
76
  chamferWidth: number;
67
77
  /** Chamfer angle in degrees (0 = face-forward, 90 = wall). Default: 45 */
68
78
  chamferAngle: number;
69
- /** Chamfer base color [r, g, b] in 01 range. Default: [0.15, 0.15, 0.18] */
79
+ /** Chamfer base color [r, g, b] in 0-1 range. Default: [0.15, 0.15, 0.18] */
70
80
  chamferColor: [number, number, number];
71
81
  /** Chamfer ambient light level. Default: 0.12 */
72
82
  chamferAmbient: number;
@@ -81,29 +91,36 @@ export interface PortalRendererConfig {
81
91
  /** 3D light direction [x, y, z] for chamfer lighting (will be normalized). */
82
92
  lightDirection: [number, number, number];
83
93
  }
84
- export declare class PortalRenderer {
85
- private static readonly RESIZE_DEBOUNCE_MS;
86
- private readonly canvas;
94
+ export declare function buildEdgeMesh(edgeVertices: Float32Array): {
95
+ vertices: Float32Array;
96
+ count: number;
97
+ };
98
+ /**
99
+ * Build geometric chamfer ring around each contour with smooth per-vertex
100
+ * normals and inner/outer lerp parameter for progressive blur.
101
+ *
102
+ * Normals are averaged between adjacent segments at shared vertices so the
103
+ * chamfer surface appears smooth rather than faceted. The `lerpT` value is
104
+ * 0 at the inner (silhouette) edge and 1 at the outer edge, driving blur
105
+ * intensity in the fragment shader.
106
+ *
107
+ * Vertex format: [x, y, nx3, ny3, nz3, lerpT] — 6 floats per vertex.
108
+ */
109
+ export declare function buildChamferMesh(edgeVertices: Float32Array, contourOffsets: number[], contourIsHole: boolean[], chamferWidth: number, chamferAngle: number): {
110
+ vertices: Float32Array;
111
+ count: number;
112
+ };
113
+ export declare class PortalRenderer extends RendererBase {
87
114
  private gl;
88
- private readonly container;
89
- private stencilProgram;
90
- private maskProgram;
91
- private jfaSeedProgram;
92
- private jfaFloodProgram;
93
- private jfaDistProgram;
94
- private interiorProgram;
95
- private compositeProgram;
96
- private boundaryProgram;
97
- private chamferProgram;
98
- private stencilUniforms;
99
- private maskUniforms;
100
- private jfaSeedUniforms;
101
- private jfaFloodUniforms;
102
- private jfaDistUniforms;
103
- private interiorUniforms;
104
- private compositeUniforms;
105
- private boundaryUniforms;
106
- private chamferUniforms;
115
+ private stencilPass;
116
+ private maskPass;
117
+ private jfaSeedPass;
118
+ private jfaFloodPass;
119
+ private jfaDistPass;
120
+ private interiorPass;
121
+ private compositePass;
122
+ private boundaryPass;
123
+ private chamferPass;
107
124
  private quadVao;
108
125
  private stencilVao;
109
126
  private stencilIndexCount;
@@ -112,48 +129,25 @@ export declare class PortalRenderer {
112
129
  private boundaryVertexCount;
113
130
  private chamferVao;
114
131
  private chamferVertexCount;
115
- private videoTexture;
116
- private depthTexture;
132
+ private readonly textures;
133
+ private readonly videoSlot;
134
+ private readonly depthSlot;
117
135
  private interiorFbo;
118
136
  private interiorColorTex;
119
137
  private interiorDepthTex;
120
138
  private fboWidth;
121
139
  private fboHeight;
122
- private maskFbo;
123
- private maskTex;
124
- private jfaPingFbo;
125
- private jfaPingTex;
126
- private jfaPongFbo;
127
- private jfaPongTex;
128
- private distFbo;
129
- private distTex;
130
- private jfaWidth;
131
- private jfaHeight;
132
- private distFieldDirty;
140
+ private jfa;
133
141
  private hasColorBufferFloat;
134
- private depthWidth;
135
- private depthHeight;
136
- private videoAspect;
137
142
  private meshAspect;
138
143
  private meshScaleX;
139
144
  private meshScaleY;
140
- private readDepth;
141
- private readInput;
142
- private playbackVideo;
143
- private onVideoFrame;
144
- private animationFrameHandle;
145
- private rvfcHandle;
146
- private rvfcSupported;
147
- private resizeObserver;
148
- private resizeTimer;
149
- private uvOffset;
150
- private uvScale;
151
145
  private lightDirX;
152
146
  private lightDirY;
153
147
  private lightDir3;
154
148
  private readonly config;
155
149
  constructor(parent: HTMLElement, config: PortalRendererConfig);
156
- initialize(video: HTMLVideoElement, depthWidth: number, depthHeight: number, mesh: ShapeMesh): void;
150
+ initialize(source: MediaSource, depthWidth: number, depthHeight: number, mesh: ShapeMesh): void;
157
151
  private uploadStencilMesh;
158
152
  private uploadMaskMesh;
159
153
  private uploadBoundaryMesh;
@@ -162,25 +156,30 @@ export declare class PortalRenderer {
162
156
  private createFBO;
163
157
  private createJFAResources;
164
158
  private computeDistanceField;
165
- start(video: HTMLVideoElement, readDepth: (timeSec: number) => Uint8Array, readInput: () => ParallaxInput, onVideoFrame?: (currentTime: number, frameNumber: number) => void): void;
166
- stop(): void;
167
- dispose(): void;
168
159
  private initGPUResources;
169
- private getUniforms;
170
- private readonly videoFrameLoop;
171
- private readonly renderLoop;
172
- private updateDepthTexture;
173
- private setupResizeHandling;
174
- private readonly scheduleResizeRecalculate;
175
- private recalculateViewportLayout;
176
- private getViewportSize;
177
- private readonly handleContextLost;
178
- private readonly handleContextRestored;
160
+ /**
161
+ * Main render loop — called every animation frame at display refresh rate.
162
+ *
163
+ * Handles interior FBO rendering, stencil marking, emissive composite,
164
+ * chamfer geometry, and boundary effects in a multi-pass pipeline.
165
+ */
166
+ protected onRenderFrame(): void;
167
+ /**
168
+ * Upload depth data to the GPU texture.
169
+ * Called from the RVFC loop at video frame rate, or from RAF fallback.
170
+ */
171
+ protected onDepthUpdate(timeSec: number): void;
172
+ protected recalculateViewportLayout(): void;
173
+ /** Rebuild GPU state after context restoration. */
174
+ protected onContextRestored(): void;
175
+ /** Dispose source textures via the registry (video, depth). */
179
176
  private disposeTextures;
180
177
  private disposeFBO;
181
- private disposeJFA;
182
178
  private disposeStencilGeometry;
183
179
  private disposeBoundaryGeometry;
180
+ /** Dispose all GPU resources — called by base class dispose(). */
181
+ protected disposeRenderer(): void;
182
+ /** Dispose all render passes and shared VAO. */
184
183
  private disposeGPUResources;
185
184
  }
186
185
  //# sourceMappingURL=portal-renderer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"portal-renderer.d.ts","sourceRoot":"","sources":["../../src/portal-renderer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"portal-renderer.d.ts","sourceRoot":"","sources":["../../src/portal-renderer.ts"],"names":[],"mappings":"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"}
@@ -15,67 +15,30 @@ export interface BinaryDownloadProgress {
15
15
  fraction: number;
16
16
  }
17
17
  /**
18
- * Worker-backed depth frame interpolator.
18
+ * Depth frame interpolator — synchronous keyframe blending.
19
19
  *
20
- * Offloads the bilateral filter, interpolation, and resize to a Web Worker
21
- * so the main thread stays free for smooth rendering. Uses double-buffering:
22
- * the main thread always has a ready-to-use depth frame while the worker
23
- * computes the next one in parallel.
20
+ * Interpolates between precomputed depth keyframes at ~5fps and returns
21
+ * raw Uint8 depth data for GPU upload. The bilateral filter runs on the
22
+ * GPU as a dedicated shader pass (see parallax-renderer.ts), so this
23
+ * class only handles temporal interpolation.
24
24
  *
25
- * ## Double-buffer strategy
26
- *
27
- * - `currentBuffer` the latest completed depth frame, always available
28
- * for synchronous reads via `sample()`.
29
- * - When the render loop calls `sample(timeSec)`, it returns `currentBuffer`
30
- * immediately (zero main-thread work) and posts a request to the worker
31
- * for the new time if it differs from the last requested time.
32
- * - When the worker responds, `currentBuffer` is swapped to the new result.
33
- * - During the 1-2 frames of latency, the previous depth frame is shown —
34
- * this is imperceptible since depth only changes at ~5fps.
25
+ * Frame-change caching avoids redundant computation: depth only changes
26
+ * at ~5fps (keyframe transitions), but the render loop calls sample()
27
+ * at 60fps. Caching skips recomputation for ~12 identical frames.
35
28
  */
36
- export declare class WorkerDepthInterpolator {
37
- private worker;
38
- private currentBuffer;
39
- private pendingTimeSec;
40
- private workerBusy;
41
- private disposed;
42
- private constructor();
43
- /**
44
- * Create a WorkerDepthInterpolator, initializing the worker with frame data.
45
- *
46
- * The frame ArrayBuffers are transferred (zero-copy) to the worker.
47
- * After this call, the original depthData.frames arrays are neutered
48
- * and should not be accessed.
49
- */
50
- static create(depthData: PrecomputedDepthData, targetWidth: number, targetHeight: number): Promise<WorkerDepthInterpolator>;
51
- /**
52
- * Get the current depth frame — always synchronous, zero main-thread work.
53
- *
54
- * Returns the latest completed depth frame from the worker. If the worker
55
- * hasn't finished processing the current time yet, returns the previous
56
- * frame (1-2 frame latency is imperceptible at ~5fps depth changes).
57
- *
58
- * Automatically requests the worker to process the new time in the background.
59
- */
60
- sample(timeSec: number): Uint8Array;
61
- /** Send a sample request to the worker if it's not busy. */
62
- private requestSample;
63
- /** Terminate the worker and release resources. */
64
- dispose(): void;
65
- }
66
29
  export declare class DepthFrameInterpolator {
67
30
  private readonly depthData;
68
- private readonly targetWidth;
69
- private readonly targetHeight;
70
- private readonly interpolatedDepth;
71
- private readonly resizedDepth;
72
- private readonly bilateralOutput;
73
31
  private readonly uint8Output;
74
32
  private lastFrameIndex;
75
33
  private lastNextFrameIndex;
76
34
  private lastLerpFactor;
77
- constructor(depthData: PrecomputedDepthData, targetWidth: number, targetHeight: number);
35
+ constructor(depthData: PrecomputedDepthData);
78
36
  sample(timeSec: number): Uint8Array;
79
37
  }
80
38
  export declare function loadPrecomputedDepth(depthDataUrl: string, depthMetaUrl: string, onProgress?: (progress: BinaryDownloadProgress) => void): Promise<PrecomputedDepthData>;
39
+ /**
40
+ * Generate a single-frame flat depth map (mid-gray 128) for sources
41
+ * that lack precomputed depth data, such as live camera feeds.
42
+ */
43
+ export declare function createFlatDepthData(width: number, height: number): PrecomputedDepthData;
81
44
  //# sourceMappingURL=precomputed-depth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"precomputed-depth.d.ts","sourceRoot":"","sources":["../../src/precomputed-depth.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO;IAQP;;;;;;OAMG;WACU,MAAM,CACjB,SAAS,EAAE,oBAAoB,EAC/B,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,uBAAuB,CAAC;IAqEnC;;;;;;;;OAQG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU;IAKnC,4DAA4D;IAC5D,OAAO,CAAC,aAAa;IAarB,kDAAkD;IAClD,OAAO,IAAI,IAAI;CAIhB;AAED,qBAAa,sBAAsB;IAe/B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAhB/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAe;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAe;IAC/C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IAMzC,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,kBAAkB,CAAM;IAChC,OAAO,CAAC,cAAc,CAAM;gBAGT,SAAS,EAAE,oBAAoB,EAC/B,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM;IAUvC,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU;CA8DpC;AAED,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,sBAAsB,KAAK,IAAI,GACtD,OAAO,CAAC,oBAAoB,CAAC,CAO/B"}
1
+ {"version":3,"file":"precomputed-depth.d.ts","sourceRoot":"","sources":["../../src/precomputed-depth.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,sBAAsB;IAS/B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAR5B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IAGzC,OAAO,CAAC,cAAc,CAAM;IAC5B,OAAO,CAAC,kBAAkB,CAAM;IAChC,OAAO,CAAC,cAAc,CAAM;gBAGT,SAAS,EAAE,oBAAoB;IAMlD,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU;CA4BpC;AAED,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,sBAAsB,KAAK,IAAI,GACtD,OAAO,CAAC,oBAAoB,CAAC,CAO/B;AA8ID;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,oBAAoB,CAOvF"}