@realsee/hdr-toolbox 1.1.3 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -87,39 +87,65 @@ hdr-toolbox cube-to-equirect \
87
87
 
88
88
  SDR 文件名为 `<prefix>_[r,l,u,d,f,b].jpg`。gain map 同时兼容 `<prefix>_<face>_gainmap.jpg` 和示例里的 `<prefix>_<face>.gainmap.jpg`。配置自动读取输入目录下的 `<prefix>_gainmap_cfg.json`(找不到时回退 `<prefix>_gainmap_cfg.xmp`)。六面必须是同尺寸、正方形且边长为 2 的幂。输出尺寸是面宽的 4×2 倍。
89
89
 
90
- ### 4. 线性 HDR(EXR / Radiance HDR)↔ Ultra HDR
90
+ ### 4. 格式转换(EXR / Radiance HDR、Ultra HDR、AVIF)
91
91
 
92
- `convert` 在线性浮点 HDR 文件和 Ultra HDR JPEG 之间互转,方向由输入/输出扩展名推断:一侧是线性 HDR(`.exr` 或 `.hdr`/`.pic`),另一侧是 Ultra HDR(`.jpg`/`.jpeg`)。
92
+ `convert` 根据扩展名在三类容器之间转换:线性浮点 HDR(`.exr`、`.hdr`/`.pic`)、Ultra HDR JPEG(`.jpg`/`.jpeg`)和 AVIF(`.avif`)。输入和输出可以互换。
93
93
 
94
94
  ```bash
95
- # Ultra HDR → EXR:按增益图重建线性 HDR,写成 32-bit float EXR
95
+ # Ultra HDR → EXR / Radiance HDR(按增益图重建线性 HDR)
96
96
  hdr-toolbox convert --input examples/ultra-hdr.jpg --output output/ultra-hdr.exr
97
-
98
- # Ultra HDR → Radiance HDR:同样的重建,写成 RGBE 编码的 .hdr(体积更小)
99
97
  hdr-toolbox convert --input examples/ultra-hdr.jpg --output output/ultra-hdr.hdr
100
98
 
101
- # EXR / HDR → Ultra HDR:色调映射出 SDR 基图,反算增益图,封装成 Ultra HDR
99
+ # EXR / HDR → Ultra HDR(色调映射出 SDR 基图,反算增益图)
102
100
  hdr-toolbox convert --input output/ultra-hdr.exr --output output/from-exr.uhdr.jpg
103
- hdr-toolbox convert --input output/ultra-hdr.hdr --output output/from-hdr.uhdr.jpg
101
+
102
+ # Ultra HDR → gain map AVIF(默认 --avif-mode gainmap)
103
+ hdr-toolbox convert --input examples/ultra-hdr.jpg --output output/ultra-hdr.avif
104
+
105
+ # Ultra HDR / EXR / HDR → 10-bit PQ AVIF
106
+ hdr-toolbox convert --input examples/ultra-hdr.jpg --output output/ultra-hdr-pq.avif --avif-mode hdr10
107
+
108
+ # AVIF → Ultra HDR / 线性 HDR
109
+ hdr-toolbox convert --input output/ultra-hdr.avif --output output/from-avif.uhdr.jpg
110
+ hdr-toolbox convert --input output/ultra-hdr-pq.avif --output output/from-pq.exr
104
111
  ```
105
112
 
106
- 支持两种线性 HDR 容器:
113
+ #### AVIF 的两种输出形式
114
+
115
+ | `--avif-mode` | 内容 | 适用场景 |
116
+ | ----------------- | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
117
+ | `gainmap`(默认) | 8-bit SDR 基图 + 8-bit 增益图 + ISO 21496-1 `tmap`,基图为 `pitm`,`tmap` 通过 `dimg` 引用两者并放入 `altr` 分组 | 支持 gain map 的查看器显示 HDR,其余显示 SDR 基图 |
118
+ | `hdr10` | 单张 10-bit PQ(BT.2020,full range,4:2:0),没有 SDR 回退 | 只需要 HDR 的场景 |
119
+
120
+ AVIF 的有损质量由 `--avif-quality` 控制(0-100,默认 90)。
107
121
 
108
- - **EXR**(OpenEXR):读取支持 HALF/FLOAT 通道、NO_COMPRESSION 与 ZIP/ZIPS 压缩;写入固定为单层、未压缩的 scanline FLOAT RGB,任意 EXR 读取器都能打开。
109
- - **Radiance HDR**(RGBE,`.hdr`/`.pic`):读取支持 flat、旧式与新式 RLE 编码;写入新式 RLE。RGBE 的共享指数带来 ~0.4% 的量化,但体积明显小于未压缩 EXR。
122
+ #### AVIF 读取的范围
110
123
 
111
- `Ultra HDR → 线性 HDR` 按 Adobe/Android 增益图恢复公式逐像素重建,在满显示余量(weight = 1)下还原完整 HDR 意图:`hdr = (sdr_linear + offset_sdr) * 2^lerp(log2(min), log2(max), gain^(1/gamma)) - offset_hdr`。
124
+ - 支持 gain map AVIF,以及 10-bit PQ / HLG AVIF(BT.709 或 BT.2020 原色)。
125
+ - 8-bit AVIF 且没有增益图时不含 HDR 数据,会报错拒绝。
126
+ - 不支持分块(`grid`)AVIF,也不支持 HDR 基图(基图余量高于增益图余量)。
127
+ - `tmap` 的三个通道参数可能不同。本工具只取通道 0,与 panorama-viewer 的做法一致,因此高光可能轻微偏色。
112
128
 
113
- `线性 HDR → Ultra HDR` 先把线性 HDR 色调映射成 SDR 基图,再把 `HDR/SDR` 比值编码成增益图。默认用**曝光融合**(`fusion`):从单张 HDR 合成多档虚拟曝光,按 Mertens 权重(对比度 × 饱和度 × 曝光适中度)在拉普拉斯金字塔上融合——这是一种隐式的局部色调映射,能同时保住暗部和高光细节且不产生光晕。也可切回全局 `reinhard` 曲线。可选项(仅此方向生效):
129
+ #### 编码注意事项
114
130
 
115
- | 选项 | 说明 |
116
- | --------------------- | --------------------------------------------------------- |
117
- | `--tone-map` | SDR 色调映射:`fusion`(默认,局部)或 `reinhard`(全局) |
118
- | `--ev-step` | 曝光融合的档间距(stops,默认 2) |
119
- | `--exposure-count` | 曝光融合的合成曝光数,奇数(默认 5) |
120
- | `--max-content-boost` | 要编码的线性 HDR 余量,默认取输入中的最大线性值 |
121
- | `--sdr-quality` | SDR 基图 JPEG 质量(1-100,默认 95) |
122
- | `--gainmap-quality` | 增益图 JPEG 质量(1-100,默认 95) |
131
+ - 10-bit PQ 输出中,线性值 1.0 对应 SDR 白 203 nit,超过 10000 nit(线性约 49.3)的值被裁剪。
132
+ - EXR / HDR 的数值按原样使用,不做自动曝光。若文件的绝对亮度不符合上述约定,需要先在外部缩放。
133
+ - 从 gain map 输入转为 10-bit PQ 时,重建的增益上限会被限制在 PQ 峰值以内,避免高光被裁剪。
134
+ - AVIF 编码使用 `@jsquash/avif`(WASM,libavif 1.0.1),不依赖系统安装的 libavif。
135
+ - 色度矩阵使用 BT.601,这是 jsquash 的 YUV 转换方式,文件的 `colr` 标签与之保持一致。
136
+
137
+ #### convert 选项
138
+
139
+ | 选项 | 说明 |
140
+ | --------------------- | ------------------------------------------------------------------------ |
141
+ | `--avif-mode` | AVIF 输出形式:`gainmap`(默认)或 `hdr10` |
142
+ | `--avif-quality` | AVIF 有损质量(0-100,默认 90) |
143
+ | `--max-content-boost` | 线性 HDR → gain map:要编码的 HDR 余量,默认取输入峰值 |
144
+ | `--tone-map` | 线性 HDR → gain map:`fusion`(默认,局部)、`reinhard`、`aces` 或 `agx` |
145
+ | `--ev-step` | 曝光融合的档间距(stops,默认 2) |
146
+ | `--exposure-count` | 曝光融合的合成曝光数,奇数(默认 5) |
147
+ | `--sdr-quality` | 生成的 SDR 基图 JPEG 质量(1-100,默认 95) |
148
+ | `--gainmap-quality` | 生成的增益图 JPEG 质量(1-100,默认 95) |
123
149
 
124
150
  > 曝光融合是全图金字塔运算,对大图(如 8K 全景)内存和耗时都明显高于 `reinhard`;离线转换可接受,追求速度可用 `--tone-map reinhard`。
125
151
 
@@ -154,19 +180,20 @@ await extractUltraHdr({
154
180
  });
155
181
  ```
156
182
 
157
- 线性 HDR 互转(EXR / Radiance HDR,方向中立的函数名;旧的 `exrToUltraHdr` / `ultraHdrToExr` 作为别名保留):
183
+ 格式互转使用 `convertHdrImage`,输入、输出格式由扩展名决定(`.exr`、`.hdr`、`.jpg`、`.jpeg`、`.avif`)。旧的 `linearHdrToUltraHdr` / `ultraHdrToLinearHdr`(以及别名 `exrToUltraHdr` / `ultraHdrToExr`)仍然可用:
158
184
 
159
185
  ```ts
160
- import { linearHdrToUltraHdr, ultraHdrToLinearHdr } from "@realsee/hdr-toolbox";
186
+ import { readFile } from "node:fs/promises";
187
+ import { convertHdrImage, readAvif } from "@realsee/hdr-toolbox";
161
188
 
162
- // 输出格式由扩展名推断:.exr 或 .hdr
163
- await ultraHdrToLinearHdr({ input: "image.uhdr.jpg", output: "image.hdr" });
189
+ // 扩展名决定格式;默认输出 gain map AVIF
190
+ await convertHdrImage({ input: "image.uhdr.jpg", output: "image.avif" });
164
191
 
165
- await linearHdrToUltraHdr({
166
- input: "image.exr",
167
- output: "image.uhdr.jpg",
168
- maxContentBoost: 8, // 可选,不填则按输入峰值自动推断
169
- });
192
+ // 10-bit PQ AVIF
193
+ await convertHdrImage({ input: "image.exr", output: "image-pq.avif", avifMode: "hdr10" });
194
+
195
+ // 直接读取 AVIF:得到 { kind: "gainmap", pair } 或 { kind: "hdr10", image }
196
+ const content = await readAvif(await readFile("image.avif"));
170
197
  ```
171
198
 
172
199
  底层的编解码函数 `readExr` / `writeExr` 和 `readHdr` / `writeHdr` 也一并导出,都以交错的线性浮点 RGB(`LinearHdrImage`)作为统一的像素表示。
@@ -0,0 +1,43 @@
1
+ /**
2
+ * libavif (WebAssembly, via `@jsquash/avif`) encode and decode.
3
+ *
4
+ * The bundled libavif is v1.0.1, which has no gain-map API, so the container and
5
+ * `tmap` metadata are handled in `avif-container.ts` and `avif-gainmap.ts`. This
6
+ * module only moves pixels in and out of AV1 image items.
7
+ *
8
+ * In Node the emscripten glue cannot fetch its `.wasm` next to the module, so the
9
+ * binary is read from `node_modules` and compiled up front. The codec loads once,
10
+ * on first use.
11
+ */
12
+ /** Chroma subsampling codes used by `@jsquash/avif` (1 = 4:2:0, 3 = 4:4:4). */
13
+ export declare const subsample420 = 1;
14
+ export declare const subsample444 = 3;
15
+ export interface Rgba8Pixels {
16
+ width: number;
17
+ height: number;
18
+ /** Interleaved RGBA, 8 bits per channel. */
19
+ data: Uint8ClampedArray;
20
+ }
21
+ export interface RgbaCodePixels {
22
+ width: number;
23
+ height: number;
24
+ /** Interleaved RGBA code values, 0 .. 2^depth - 1. */
25
+ data: Uint16Array;
26
+ depth: number;
27
+ }
28
+ export interface EncodeAvifOptions {
29
+ /** Quality from 0 to 100 (lossy). */
30
+ quality: number;
31
+ subsample: number;
32
+ }
33
+ /** Encode 8-bit RGBA pixels to an AV1 image (a complete AVIF file). */
34
+ export declare function encodeAvif8(pixels: Rgba8Pixels, options: EncodeAvifOptions): Promise<Buffer>;
35
+ /** Encode 10-bit RGBA code values to an AV1 image (a complete AVIF file). */
36
+ export declare function encodeAvif10(pixels: RgbaCodePixels, options: EncodeAvifOptions): Promise<Buffer>;
37
+ /**
38
+ * Decode a complete AVIF file. Returns RGBA at `bitDepth`: `Uint8ClampedArray`
39
+ * for 8 bits, `Uint16Array` code values for 10, 12 or 16 bits.
40
+ */
41
+ export declare function decodeAvif(bytes: Buffer, bitDepth: 8): Promise<Rgba8Pixels>;
42
+ export declare function decodeAvif(bytes: Buffer, bitDepth: 10 | 12 | 16): Promise<RgbaCodePixels>;
43
+ //# sourceMappingURL=avif-codec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avif-codec.d.ts","sourceRoot":"","sources":["../src/avif-codec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,+EAA+E;AAC/E,eAAO,MAAM,YAAY,IAAI,CAAC;AAC9B,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,IAAI,EAAE,iBAAiB,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AA+CD,uEAAuE;AACvE,wBAAsB,WAAW,CAC/B,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,6EAA6E;AAC7E,wBAAsB,YAAY,CAChC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AACnF,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * libavif (WebAssembly, via `@jsquash/avif`) encode and decode.
3
+ *
4
+ * The bundled libavif is v1.0.1, which has no gain-map API, so the container and
5
+ * `tmap` metadata are handled in `avif-container.ts` and `avif-gainmap.ts`. This
6
+ * module only moves pixels in and out of AV1 image items.
7
+ *
8
+ * In Node the emscripten glue cannot fetch its `.wasm` next to the module, so the
9
+ * binary is read from `node_modules` and compiled up front. The codec loads once,
10
+ * on first use.
11
+ */
12
+ import { readFile } from "node:fs/promises";
13
+ import { createRequire } from "node:module";
14
+ import { dirname, join } from "node:path";
15
+ import { default as decodeModule, init as initDecoder } from "@jsquash/avif/decode.js";
16
+ import { default as encodeModule, init as initEncoder } from "@jsquash/avif/encode.js";
17
+ /** Chroma subsampling codes used by `@jsquash/avif` (1 = 4:2:0, 3 = 4:4:4). */
18
+ export const subsample420 = 1;
19
+ export const subsample444 = 3;
20
+ /** The global WebAssembly namespace, typed only as far as this module uses it. */
21
+ const wasm = globalThis.WebAssembly;
22
+ let encoderReady;
23
+ let decoderReady;
24
+ function codecFile(name) {
25
+ const packageJson = createRequire(import.meta.url).resolve("@jsquash/avif/package.json");
26
+ return join(dirname(packageJson), "codec", name);
27
+ }
28
+ async function compileWasm(name) {
29
+ return wasm.compile(await readFile(codecFile(name)));
30
+ }
31
+ function ensureEncoder() {
32
+ encoderReady ??= (async () => {
33
+ await initEncoder((await compileWasm("enc/avif_enc.wasm")));
34
+ })().catch((error) => {
35
+ encoderReady = undefined;
36
+ throw error;
37
+ });
38
+ return encoderReady;
39
+ }
40
+ function ensureDecoder() {
41
+ decoderReady ??= (async () => {
42
+ await initDecoder((await compileWasm("dec/avif_dec.wasm")));
43
+ })().catch((error) => {
44
+ decoderReady = undefined;
45
+ throw error;
46
+ });
47
+ return decoderReady;
48
+ }
49
+ /** Encode 8-bit RGBA pixels to an AV1 image (a complete AVIF file). */
50
+ export async function encodeAvif8(pixels, options) {
51
+ await ensureEncoder();
52
+ const image = { data: pixels.data, width: pixels.width, height: pixels.height };
53
+ const output = await encodeModule(image, {
54
+ bitDepth: 8,
55
+ quality: options.quality,
56
+ subsample: options.subsample,
57
+ });
58
+ return Buffer.from(output);
59
+ }
60
+ /** Encode 10-bit RGBA code values to an AV1 image (a complete AVIF file). */
61
+ export async function encodeAvif10(pixels, options) {
62
+ if (pixels.depth !== 10)
63
+ throw new Error("encodeAvif10 expects 10-bit code values.");
64
+ await ensureEncoder();
65
+ const image = { data: pixels.data, width: pixels.width, height: pixels.height };
66
+ const output = await encodeModule(image, {
67
+ bitDepth: 10,
68
+ quality: options.quality,
69
+ subsample: options.subsample,
70
+ });
71
+ return Buffer.from(output);
72
+ }
73
+ export async function decodeAvif(bytes, bitDepth) {
74
+ await ensureDecoder();
75
+ const arrayBuffer = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
76
+ if (bitDepth === 8) {
77
+ const result = await decodeModule(arrayBuffer, { bitDepth: 8 });
78
+ if (!result)
79
+ throw new Error("AVIF decoding failed.");
80
+ return {
81
+ width: result.width,
82
+ height: result.height,
83
+ data: result.data,
84
+ };
85
+ }
86
+ const result = await decodeModule(arrayBuffer, { bitDepth });
87
+ if (!result)
88
+ throw new Error("AVIF decoding failed.");
89
+ return { width: result.width, height: result.height, data: result.data, depth: bitDepth };
90
+ }
91
+ //# sourceMappingURL=avif-codec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avif-codec.js","sourceRoot":"","sources":["../src/avif-codec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * AVIF (ISOBMFF / HEIF) container reader and writer.
3
+ *
4
+ * The reader covers the boxes needed to locate image items, their AV1 payloads,
5
+ * their properties (`av1C`, `ispe`, `pixi`, `colr`) and `dimg` references. The
6
+ * writer emits a minimal file with one or more `av01` image items and optional
7
+ * derived `tmap` items (ISO 21496-1 gain maps).
8
+ */
9
+ export interface IsobmffBox {
10
+ type: string;
11
+ /** Byte offset of the box header in the file. */
12
+ start: number;
13
+ headerSize: number;
14
+ /** Total box size, header included. */
15
+ size: number;
16
+ }
17
+ export interface AvifItem {
18
+ id: number;
19
+ type: string;
20
+ /** Item byte ranges in the file, from `iloc`. */
21
+ extents: Array<{
22
+ offset: number;
23
+ length: number;
24
+ }>;
25
+ constructionMethod: number;
26
+ /** Property boxes associated with the item through `ipma`. */
27
+ properties: IsobmffBox[];
28
+ }
29
+ export interface AvifReference {
30
+ type: string;
31
+ from: number;
32
+ to: number[];
33
+ }
34
+ export interface ParsedAvif {
35
+ buffer: Buffer;
36
+ primaryItemId: number | undefined;
37
+ items: Map<number, AvifItem>;
38
+ references: AvifReference[];
39
+ }
40
+ export interface ColourInfo {
41
+ primaries: number;
42
+ transfer: number;
43
+ matrix: number;
44
+ fullRange: boolean;
45
+ }
46
+ /** Parse an AVIF file's item graph. Throws if the file has no `meta` box. */
47
+ export declare function parseAvif(buffer: Buffer): ParsedAvif;
48
+ /** Return the concatenated payload bytes of an item stored in the file. */
49
+ export declare function itemPayload(parsed: ParsedAvif, item: AvifItem): Buffer;
50
+ /** Return the bytes of the first property of a given type on an item. */
51
+ export declare function itemPropertyBytes(parsed: ParsedAvif, item: AvifItem, type: string): Buffer | undefined;
52
+ /** Bit depth declared by an item's `pixi` property, if present. */
53
+ export declare function itemBitDepth(parsed: ParsedAvif, item: AvifItem): number | undefined;
54
+ /** CICP colour information from an item's `colr` (nclx) property. */
55
+ export declare function itemColourInfo(parsed: ParsedAvif, item: AvifItem): ColourInfo | undefined;
56
+ export interface AvifWriteItem {
57
+ id: number;
58
+ /** `av01` for AV1 image items, `tmap` for ISO 21496-1 gain map metadata. */
59
+ type: "av01" | "tmap";
60
+ payload: Buffer;
61
+ /** Raw property boxes (`av1C`, `ispe`, `pixi`, `colr`, ...). */
62
+ properties?: Buffer[];
63
+ }
64
+ /** An `altr` (alternatives) entity group: readers may pick any one member. */
65
+ export interface AvifAlternativesGroup {
66
+ entities: number[];
67
+ }
68
+ export interface AvifWriteOptions {
69
+ primaryItemId: number;
70
+ items: AvifWriteItem[];
71
+ references?: AvifReference[];
72
+ /** Entity groups written to `grpl`. Gain map AVIF uses one group with the tmap and base items. */
73
+ alternatives?: AvifAlternativesGroup[];
74
+ }
75
+ /** CICP `colr` box with an nclx payload. */
76
+ export declare function colrBox(info: ColourInfo): Buffer;
77
+ /**
78
+ * Serialise an AVIF file. Layout: `ftyp`, `meta` (hdlr, pitm, iloc, iinf, iref,
79
+ * iprp), then `mdat` holding the item payloads in order. Item offsets are
80
+ * absolute file offsets (construction method 0).
81
+ */
82
+ export declare function writeAvifContainer(options: AvifWriteOptions): Buffer;
83
+ //# sourceMappingURL=avif-container.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avif-container.d.ts","sourceRoot":"","sources":["../src/avif-container.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,OAAO,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,8DAA8D;IAC9D,UAAU,EAAE,UAAU,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,EAAE,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC7B,UAAU,EAAE,aAAa,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;CACpB;AAiND,6EAA6E;AAC7E,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAiBpD;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,CAStE;AAED,yEAAyE;AACzE,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CAGpB;AAED,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,CAKnF;AAED,qEAAqE;AACrE,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,CAWzF;AAMD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,4EAA4E;IAC5E,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,8EAA8E;AAC9E,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;IAC7B,kGAAkG;IAClG,YAAY,CAAC,EAAE,qBAAqB,EAAE,CAAC;CACxC;AA2BD,4CAA4C;AAC5C,wBAAgB,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAShD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAkHpE"}