@kduma-oss/pcf 0.0.1

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 (57) hide show
  1. package/README.md +116 -0
  2. package/dist/consts.d.ts +42 -0
  3. package/dist/consts.d.ts.map +1 -0
  4. package/dist/consts.js +44 -0
  5. package/dist/consts.js.map +1 -0
  6. package/dist/container.d.ts +124 -0
  7. package/dist/container.d.ts.map +1 -0
  8. package/dist/container.js +441 -0
  9. package/dist/container.js.map +1 -0
  10. package/dist/crc.d.ts +15 -0
  11. package/dist/crc.d.ts.map +1 -0
  12. package/dist/crc.js +62 -0
  13. package/dist/crc.js.map +1 -0
  14. package/dist/entry.d.ts +44 -0
  15. package/dist/entry.d.ts.map +1 -0
  16. package/dist/entry.js +118 -0
  17. package/dist/entry.js.map +1 -0
  18. package/dist/errors.d.ts +56 -0
  19. package/dist/errors.d.ts.map +1 -0
  20. package/dist/errors.js +88 -0
  21. package/dist/errors.js.map +1 -0
  22. package/dist/hash.d.ts +59 -0
  23. package/dist/hash.d.ts.map +1 -0
  24. package/dist/hash.js +151 -0
  25. package/dist/hash.js.map +1 -0
  26. package/dist/header.d.ts +20 -0
  27. package/dist/header.d.ts.map +1 -0
  28. package/dist/header.js +38 -0
  29. package/dist/header.js.map +1 -0
  30. package/dist/index.d.ts +42 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +42 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/node-storage.d.ts +24 -0
  35. package/dist/node-storage.d.ts.map +1 -0
  36. package/dist/node-storage.js +52 -0
  37. package/dist/node-storage.js.map +1 -0
  38. package/dist/storage.d.ts +35 -0
  39. package/dist/storage.d.ts.map +1 -0
  40. package/dist/storage.js +66 -0
  41. package/dist/storage.js.map +1 -0
  42. package/dist/table.d.ts +28 -0
  43. package/dist/table.d.ts.map +1 -0
  44. package/dist/table.js +48 -0
  45. package/dist/table.js.map +1 -0
  46. package/package.json +60 -0
  47. package/src/consts.ts +50 -0
  48. package/src/container.ts +575 -0
  49. package/src/crc.ts +69 -0
  50. package/src/entry.ts +152 -0
  51. package/src/errors.ts +124 -0
  52. package/src/hash.ts +165 -0
  53. package/src/header.ts +50 -0
  54. package/src/index.ts +68 -0
  55. package/src/node-storage.ts +75 -0
  56. package/src/storage.ts +85 -0
  57. package/src/table.ts +67 -0
package/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # pcf — Partitioned Container Format (TypeScript implementation)
2
+
3
+ A TypeScript reader/writer for **PCF v1.0**, a language-agnostic binary
4
+ container that stores multiple independent byte regions ("partitions") in one
5
+ file.
6
+
7
+ This package is a faithful port of the Rust reference implementation
8
+ (`reference/PCF-v1.0/`) and mirrors the written specification
9
+ (`specs/PCF-spec-v1.0.txt`) field-for-field. It favours auditability over
10
+ performance and produces the **byte-exact** canonical test vector from spec
11
+ section 15.
12
+
13
+ ## Layout
14
+
15
+ ```
16
+ [ 20-byte header ] [ table block(s) ] [ partition data regions ]
17
+ ```
18
+
19
+ - **Header** (20 B): magic `0x89 K P R T 0x0D 0x0A 0x1A`, major/minor version,
20
+ absolute offset of the first table block.
21
+ - **Table block**: 74-byte header (`partitionCount`, `nextTableOffset`,
22
+ hash algo + 64-byte block hash) followed by `partitionCount` entries. Blocks
23
+ form a singly linked chain to hold more than 255 partitions.
24
+ - **Entry** (141 B): `type`, 16-byte UID, 32-byte ASCII label, `startOffset`,
25
+ `maxLength`, `usedBytes`, 1-byte data-hash algorithm, 64-byte data hash.
26
+
27
+ All integers are little-endian. `u64` fields are modelled as `bigint` to
28
+ preserve full 64-bit fidelity; free space is `maxLength - usedBytes`.
29
+
30
+ ## Hash registry
31
+
32
+ | id | algorithm | id | algorithm |
33
+ |----|------------------|----|-----------|
34
+ | 0 | none | 5 | SHA-1 |
35
+ | 1 | CRC-32/ISO-HDLC | 16 | SHA-256 (default) |
36
+ | 2 | CRC-32C | 17 | SHA-512 |
37
+ | 3 | CRC-64/XZ | 18 | BLAKE3 |
38
+ | 4 | MD5 | | |
39
+
40
+ Digests are provided by the audited [`@noble/hashes`](https://github.com/paulmillr/noble-hashes)
41
+ package; the three CRC variants are implemented in pure TypeScript
42
+ (`src/crc.ts`).
43
+
44
+ ## Usage
45
+
46
+ ```ts
47
+ import { Container, HashAlgo } from "pcf";
48
+
49
+ const c = Container.create();
50
+ const uid = new Uint8Array(16).fill(1);
51
+ c.addPartition(
52
+ 0x10,
53
+ uid,
54
+ "notes",
55
+ new TextEncoder().encode("hello world"),
56
+ 64,
57
+ HashAlgo.Sha256,
58
+ );
59
+
60
+ c.verify();
61
+ const entries = c.entries();
62
+ const data = c.readPartitionData(entries[0]);
63
+ console.log(new TextDecoder().decode(data)); // "hello world"
64
+ ```
65
+
66
+ A `Container` is backed by any `Storage`. Two implementations ship with the
67
+ package:
68
+
69
+ - `MemoryStorage` — an in-memory growable buffer (the default for
70
+ `Container.create()`).
71
+ - `NodeFileStorage` — backed by a Node file descriptor:
72
+
73
+ ```ts
74
+ import { Container, NodeFileStorage, HashAlgo } from "pcf";
75
+
76
+ const store = NodeFileStorage.open("container.pcf", /* truncate */ true);
77
+ const c = Container.create(store);
78
+ // … add partitions …
79
+ store.close();
80
+ ```
81
+
82
+ ## Project layout
83
+
84
+ ```
85
+ implementations/ts/
86
+ ├── package.json
87
+ ├── tsconfig.json
88
+ ├── vitest.config.ts
89
+ ├── src/ # library sources
90
+ │ ├── consts.ts errors.ts crc.ts hash.ts
91
+ │ ├── header.ts entry.ts table.ts
92
+ │ ├── storage.ts node-storage.ts container.ts
93
+ │ └── index.ts # public re-exports
94
+ ├── test/
95
+ │ ├── roundtrip.test.ts # end-to-end black-box tests
96
+ │ ├── coverage.test.ts # targeted error-path / edge-case tests
97
+ │ └── spec-compliance.test.ts # one test per normative MUST/SHALL
98
+ └── examples/
99
+ └── gen-testvector.ts # produces the canonical 395-byte spec vector
100
+ ```
101
+
102
+ ## Scripts
103
+
104
+ Run from this directory:
105
+
106
+ ```
107
+ npm install # install dependencies
108
+ npm run build # type-check and emit dist/ (tsc, strict)
109
+ npm test # run the full vitest suite
110
+ npm run coverage # vitest + v8 coverage (95% line / 100% function floor)
111
+ npm run gen-testvector # writes pcf_testvector.bin (the 395-byte spec vector)
112
+ ```
113
+
114
+ CI (`.github/workflows/ts-ci.yml`) runs the type-check/build, the test suite on
115
+ Linux/macOS/Windows, regenerates and size-checks the spec test vector, and
116
+ enforces the coverage floor.
@@ -0,0 +1,42 @@
1
+ /**
2
+ * On-disk constants defined by PCF v1.0.
3
+ *
4
+ * Every value here is normative and corresponds directly to a figure in the
5
+ * specification (see Appendix A, "Field Layout Summary").
6
+ */
7
+ /** File signature, 8 bytes: `0x89 'K' 'P' 'R' 'T' 0x0D 0x0A 0x1A`. */
8
+ export declare const MAGIC: Uint8Array;
9
+ /** Major format version implemented by this library. */
10
+ export declare const VERSION_MAJOR = 1;
11
+ /** Minor format version implemented by this library. */
12
+ export declare const VERSION_MINOR = 0;
13
+ /** Fixed size of the file header, in bytes. */
14
+ export declare const HEADER_SIZE = 20;
15
+ /** Fixed size of a table-block header, in bytes. */
16
+ export declare const TABLE_HEADER_SIZE = 74;
17
+ /** Fixed size of a single partition entry, in bytes. */
18
+ export declare const ENTRY_SIZE = 141;
19
+ /** Size of every hash field, in bytes (large enough for the widest digest). */
20
+ export declare const HASH_FIELD_SIZE = 64;
21
+ /** Size of the partition label field, in bytes. */
22
+ export declare const LABEL_SIZE = 32;
23
+ /** Size of the partition UID field, in bytes. */
24
+ export declare const UID_SIZE = 16;
25
+ /**
26
+ * Reserved partition type: invalid / uninitialised. MUST NOT label a live
27
+ * partition.
28
+ */
29
+ export declare const TYPE_RESERVED = 0;
30
+ /**
31
+ * Reserved partition type: raw / blob, interpreted entirely by the
32
+ * application.
33
+ */
34
+ export declare const TYPE_RAW = 4294967295;
35
+ /** The NIL UID (all zero). MUST NOT label a live partition. */
36
+ export declare const NIL_UID: Uint8Array;
37
+ /**
38
+ * Maximum number of entries a single table block can hold (`partition_count`
39
+ * is a `u8`).
40
+ */
41
+ export declare const MAX_ENTRIES_PER_BLOCK = 255;
42
+ //# sourceMappingURL=consts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,sEAAsE;AACtE,eAAO,MAAM,KAAK,EAAE,UAElB,CAAC;AAEH,wDAAwD;AACxD,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,wDAAwD;AACxD,eAAO,MAAM,aAAa,IAAI,CAAC;AAE/B,+CAA+C;AAC/C,eAAO,MAAM,WAAW,KAAK,CAAC;AAC9B,oDAAoD;AACpD,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,wDAAwD;AACxD,eAAO,MAAM,UAAU,MAAM,CAAC;AAE9B,+EAA+E;AAC/E,eAAO,MAAM,eAAe,KAAK,CAAC;AAClC,mDAAmD;AACnD,eAAO,MAAM,UAAU,KAAK,CAAC;AAC7B,iDAAiD;AACjD,eAAO,MAAM,QAAQ,KAAK,CAAC;AAE3B;;;GAGG;AACH,eAAO,MAAM,aAAa,IAAc,CAAC;AACzC;;;GAGG;AACH,eAAO,MAAM,QAAQ,aAAc,CAAC;AAEpC,+DAA+D;AAC/D,eAAO,MAAM,OAAO,EAAE,UAAqC,CAAC;AAE5D;;;GAGG;AACH,eAAO,MAAM,qBAAqB,MAAM,CAAC"}
package/dist/consts.js ADDED
@@ -0,0 +1,44 @@
1
+ /**
2
+ * On-disk constants defined by PCF v1.0.
3
+ *
4
+ * Every value here is normative and corresponds directly to a figure in the
5
+ * specification (see Appendix A, "Field Layout Summary").
6
+ */
7
+ /** File signature, 8 bytes: `0x89 'K' 'P' 'R' 'T' 0x0D 0x0A 0x1A`. */
8
+ export const MAGIC = new Uint8Array([
9
+ 0x89, 0x4b, 0x50, 0x52, 0x54, 0x0d, 0x0a, 0x1a,
10
+ ]);
11
+ /** Major format version implemented by this library. */
12
+ export const VERSION_MAJOR = 1;
13
+ /** Minor format version implemented by this library. */
14
+ export const VERSION_MINOR = 0;
15
+ /** Fixed size of the file header, in bytes. */
16
+ export const HEADER_SIZE = 20;
17
+ /** Fixed size of a table-block header, in bytes. */
18
+ export const TABLE_HEADER_SIZE = 74;
19
+ /** Fixed size of a single partition entry, in bytes. */
20
+ export const ENTRY_SIZE = 141;
21
+ /** Size of every hash field, in bytes (large enough for the widest digest). */
22
+ export const HASH_FIELD_SIZE = 64;
23
+ /** Size of the partition label field, in bytes. */
24
+ export const LABEL_SIZE = 32;
25
+ /** Size of the partition UID field, in bytes. */
26
+ export const UID_SIZE = 16;
27
+ /**
28
+ * Reserved partition type: invalid / uninitialised. MUST NOT label a live
29
+ * partition.
30
+ */
31
+ export const TYPE_RESERVED = 0x0000_0000;
32
+ /**
33
+ * Reserved partition type: raw / blob, interpreted entirely by the
34
+ * application.
35
+ */
36
+ export const TYPE_RAW = 0xffff_ffff;
37
+ /** The NIL UID (all zero). MUST NOT label a live partition. */
38
+ export const NIL_UID = new Uint8Array(UID_SIZE);
39
+ /**
40
+ * Maximum number of entries a single table block can hold (`partition_count`
41
+ * is a `u8`).
42
+ */
43
+ export const MAX_ENTRIES_PER_BLOCK = 255;
44
+ //# sourceMappingURL=consts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,sEAAsE;AACtE,MAAM,CAAC,MAAM,KAAK,GAAe,IAAI,UAAU,CAAC;IAC9C,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;CAC/C,CAAC,CAAC;AAEH,wDAAwD;AACxD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC;AAC/B,wDAAwD;AACxD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC;AAE/B,+CAA+C;AAC/C,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAC9B,oDAAoD;AACpD,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AACpC,wDAAwD;AACxD,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAC;AAE9B,+EAA+E;AAC/E,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAClC,mDAAmD;AACnD,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAC;AAC7B,iDAAiD;AACjD,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,CAAC;AAE3B;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,WAAW,CAAC;AACzC;;;GAGG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,WAAW,CAAC;AAEpC,+DAA+D;AAC/D,MAAM,CAAC,MAAM,OAAO,GAAe,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC;AAE5D;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAC"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * The high-level {@link Container} type: reading and writing whole PCF files.
3
+ *
4
+ * `Container` is backed by any {@link Storage}, so it works equally with an
5
+ * in-memory {@link MemoryStorage} and a file-backed `NodeFileStorage`.
6
+ *
7
+ * # Reader vs. writer scope
8
+ *
9
+ * The *reader* side (`open`, `entries`, `readPartitionData`, `verify`) is fully
10
+ * general: it accepts any conforming file, including arbitrary region placement
11
+ * and overflow-block chains.
12
+ *
13
+ * The *writer* side implements one documented placement strategy (the format
14
+ * deliberately leaves layout to the writer, spec section 12 / A7, A9):
15
+ *
16
+ * - The first table block sits immediately after the header and is created with
17
+ * reserved capacity for `firstBlockCapacity` entries, so entries can be
18
+ * appended in place without moving data.
19
+ * - Partition data is appended at a growing end-of-data cursor; each partition
20
+ * may reserve `extraReserve` spare bytes for later in-place growth.
21
+ * - When every known block is full, a new overflow block is appended and linked
22
+ * into the chain.
23
+ * - Block capacity is *not* stored in the file (spec A9); it is tracked only in
24
+ * memory for the lifetime of this handle. After {@link Container.open}, blocks
25
+ * are treated as having no spare capacity, so subsequent additions go into
26
+ * fresh overflow blocks. {@link Container.compactedImage} rebuilds a tightly
27
+ * packed file.
28
+ */
29
+ import { type PartitionEntry } from "./entry.js";
30
+ import { HashAlgo } from "./hash.js";
31
+ import { type FileHeader } from "./header.js";
32
+ import { type Storage } from "./storage.js";
33
+ import { type TableBlockHeader } from "./table.js";
34
+ /**
35
+ * One table block read from disk: its absolute `offset`, its parsed
36
+ * {@link TableBlockHeader} (including `tableHash` and `nextTableOffset`), and
37
+ * its {@link PartitionEntry} list.
38
+ *
39
+ * Returned by {@link Container.readBlockAt}. It lets code layered on PCF group
40
+ * blocks, inspect each block's `tableHash`, and follow non-default
41
+ * `nextTableOffset` chains, instead of {@link Container.entries} which flattens
42
+ * the whole chain.
43
+ */
44
+ export interface BlockView {
45
+ /** Absolute file offset of the table block. */
46
+ offset: number;
47
+ /** Parsed 74-byte block header. */
48
+ header: TableBlockHeader;
49
+ /** The block's entries, in stored order. */
50
+ entries: PartitionEntry[];
51
+ }
52
+ /** A PCF container backed by a {@link Storage}. */
53
+ export declare class Container {
54
+ private storage;
55
+ private fileHeader;
56
+ private blocks;
57
+ private dataEof;
58
+ private defaultCapacity;
59
+ private tableHashAlgo;
60
+ private constructor();
61
+ /**
62
+ * Create an empty container with sensible defaults (first block capacity 16,
63
+ * table hashing with SHA-256). Defaults to an in-memory store.
64
+ */
65
+ static create(storage?: Storage): Container;
66
+ /**
67
+ * Create an empty container, choosing the first block's reserved capacity and
68
+ * the table-hash algorithm.
69
+ */
70
+ static createWith(storage: Storage, firstBlockCapacity: number, tableHashAlgo: HashAlgo): Container;
71
+ /** Open an existing container, validating the header (spec C1, C2). */
72
+ static open(storage: Storage): Container;
73
+ /** Consume the container and return the backing store. */
74
+ intoStorage(): Storage;
75
+ /** The parsed file header. */
76
+ header(): FileHeader;
77
+ private readBlock;
78
+ private writeBlock;
79
+ /** All live partition entries, in chain order. */
80
+ entries(): PartitionEntry[];
81
+ /**
82
+ * Read a single table block at an absolute `offset`, returning its parsed
83
+ * header (including `tableHash`) and entries. Unlike {@link entries}, which
84
+ * flattens the whole chain, this exposes one block at a time so a caller can
85
+ * follow an arbitrary `nextTableOffset` chain and inspect each block's
86
+ * `tableHash`. It is a read-only operation and does not alter the container.
87
+ */
88
+ readBlockAt(offset: number): BlockView;
89
+ /** Read a partition's used data. */
90
+ readPartitionData(entry: PartitionEntry): Uint8Array;
91
+ private locate;
92
+ private blockIndex;
93
+ /**
94
+ * Add a new partition. The data is appended at the end-of-data cursor and
95
+ * reserves `extraReserve` spare bytes for later in-place growth.
96
+ */
97
+ addPartition(partitionType: number, uid: Uint8Array, label: string, data: Uint8Array, extraReserve?: number | bigint, dataHashAlgo?: HashAlgo): void;
98
+ /**
99
+ * Replace a partition's data in place (spec section 8.5, hash cascade).
100
+ * Fails if `newData` exceeds the partition's reservation.
101
+ */
102
+ updatePartitionData(uid: Uint8Array, newData: Uint8Array): void;
103
+ /**
104
+ * Remove a partition. Entries after it in the same block shift down; the
105
+ * freed data region becomes dead space until {@link Container.compactedImage}
106
+ * reclaims it (spec section 11.4).
107
+ */
108
+ removePartition(uid: Uint8Array): void;
109
+ /**
110
+ * Verify every table block and every partition's data against its stored
111
+ * hash, and run the per-entry conformance checks (spec section 12).
112
+ */
113
+ verify(): void;
114
+ /**
115
+ * Build a freshly compacted image: all dead space removed, every `maxLength`
116
+ * trimmed to `usedBytes`, partitions placed contiguously after a tightly
117
+ * packed table (spec section 11.5). The current handle is left unchanged;
118
+ * write the bytes to a new store and re-open it.
119
+ */
120
+ compactedImage(): Uint8Array;
121
+ /** Write a compacted copy of the container to `out`. */
122
+ compactInto(out: Storage): void;
123
+ }
124
+ //# sourceMappingURL=container.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAYH,OAAO,EAIL,KAAK,cAAc,EAEpB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAA+B,QAAQ,EAAY,MAAM,WAAW,CAAC;AAC5E,OAAO,EACL,KAAK,UAAU,EAGhB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,YAAY,CAAC;AAWpB;;;;;;;;;GASG;AACH,MAAM,WAAW,SAAS;IACxB,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,MAAM,EAAE,gBAAgB,CAAC;IACzB,4CAA4C;IAC5C,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAcD,mDAAmD;AACnD,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,aAAa,CAAW;IAEhC,OAAO;IAkBP;;;OAGG;IACH,MAAM,CAAC,MAAM,CAAC,OAAO,GAAE,OAA6B,GAAG,SAAS;IAIhE;;;OAGG;IACH,MAAM,CAAC,UAAU,CACf,OAAO,EAAE,OAAO,EAChB,kBAAkB,EAAE,MAAM,EAC1B,aAAa,EAAE,QAAQ,GACtB,SAAS;IA4BZ,uEAAuE;IACvE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS;IA2BxC,0DAA0D;IAC1D,WAAW,IAAI,OAAO;IAItB,8BAA8B;IAC9B,MAAM,IAAI,UAAU;IAMpB,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,UAAU;IAyBlB,kDAAkD;IAClD,OAAO,IAAI,cAAc,EAAE;IAW3B;;;;;;OAMG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS;IAKtC,oCAAoC;IACpC,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,UAAU;IAQpD,OAAO,CAAC,MAAM;IAcd,OAAO,CAAC,UAAU;IAUlB;;;OAGG;IACH,YAAY,CACV,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,UAAU,EAChB,YAAY,GAAE,MAAM,GAAG,MAAU,EACjC,YAAY,GAAE,QAA0B,GACvC,IAAI;IAuEP;;;OAGG;IACH,mBAAmB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI;IAmB/D;;;;OAIG;IACH,eAAe,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI;IAatC;;;OAGG;IACH,MAAM,IAAI,IAAI;IA8Bd;;;;;OAKG;IACH,cAAc,IAAI,UAAU;IAqF5B,wDAAwD;IACxD,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;CAGhC"}