yom-format 0.1.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 (199) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +86 -0
  3. package/dist/cli.d.ts +30 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +344 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/index.d.ts +36 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +25 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/pipeline/avif.d.ts +3 -0
  12. package/dist/pipeline/avif.d.ts.map +1 -0
  13. package/dist/pipeline/avif.js +30 -0
  14. package/dist/pipeline/avif.js.map +1 -0
  15. package/dist/pipeline/convert.d.ts +28 -0
  16. package/dist/pipeline/convert.d.ts.map +1 -0
  17. package/dist/pipeline/convert.js +111 -0
  18. package/dist/pipeline/convert.js.map +1 -0
  19. package/dist/pipeline/index.d.ts +17 -0
  20. package/dist/pipeline/index.d.ts.map +1 -0
  21. package/dist/pipeline/index.js +17 -0
  22. package/dist/pipeline/index.js.map +1 -0
  23. package/dist/pipeline/ocrLayoutBuilder.d.ts +10 -0
  24. package/dist/pipeline/ocrLayoutBuilder.d.ts.map +1 -0
  25. package/dist/pipeline/ocrLayoutBuilder.js +62 -0
  26. package/dist/pipeline/ocrLayoutBuilder.js.map +1 -0
  27. package/dist/pipeline/pdfDocument.d.ts +12 -0
  28. package/dist/pipeline/pdfDocument.d.ts.map +1 -0
  29. package/dist/pipeline/pdfDocument.js +76 -0
  30. package/dist/pipeline/pdfDocument.js.map +1 -0
  31. package/dist/pipeline/renderPage.d.ts +10 -0
  32. package/dist/pipeline/renderPage.d.ts.map +1 -0
  33. package/dist/pipeline/renderPage.js +36 -0
  34. package/dist/pipeline/renderPage.js.map +1 -0
  35. package/dist/pipeline/textExtract.d.ts +29 -0
  36. package/dist/pipeline/textExtract.d.ts.map +1 -0
  37. package/dist/pipeline/textExtract.js +48 -0
  38. package/dist/pipeline/textExtract.js.map +1 -0
  39. package/dist/yom/blobLimits.d.ts +15 -0
  40. package/dist/yom/blobLimits.d.ts.map +1 -0
  41. package/dist/yom/blobLimits.js +25 -0
  42. package/dist/yom/blobLimits.js.map +1 -0
  43. package/dist/yom/byteSource.d.ts +56 -0
  44. package/dist/yom/byteSource.d.ts.map +1 -0
  45. package/dist/yom/byteSource.js +111 -0
  46. package/dist/yom/byteSource.js.map +1 -0
  47. package/dist/yom/bytes.d.ts +2 -0
  48. package/dist/yom/bytes.d.ts.map +1 -0
  49. package/dist/yom/bytes.js +13 -0
  50. package/dist/yom/bytes.js.map +1 -0
  51. package/dist/yom/constants.d.ts +34 -0
  52. package/dist/yom/constants.d.ts.map +1 -0
  53. package/dist/yom/constants.js +82 -0
  54. package/dist/yom/constants.js.map +1 -0
  55. package/dist/yom/errors.d.ts +44 -0
  56. package/dist/yom/errors.d.ts.map +1 -0
  57. package/dist/yom/errors.js +44 -0
  58. package/dist/yom/errors.js.map +1 -0
  59. package/dist/yom/flatbufferVerify.d.ts +21 -0
  60. package/dist/yom/flatbufferVerify.d.ts.map +1 -0
  61. package/dist/yom/flatbufferVerify.js +255 -0
  62. package/dist/yom/flatbufferVerify.js.map +1 -0
  63. package/dist/yom/generated/yomu/yom/blob-kind.d.ts +9 -0
  64. package/dist/yom/generated/yomu/yom/blob-kind.d.ts.map +1 -0
  65. package/dist/yom/generated/yomu/yom/blob-kind.js +12 -0
  66. package/dist/yom/generated/yomu/yom/blob-kind.js.map +1 -0
  67. package/dist/yom/generated/yomu/yom/blob-ref.d.ts +45 -0
  68. package/dist/yom/generated/yomu/yom/blob-ref.d.ts.map +1 -0
  69. package/dist/yom/generated/yomu/yom/blob-ref.js +141 -0
  70. package/dist/yom/generated/yomu/yom/blob-ref.js.map +1 -0
  71. package/dist/yom/generated/yomu/yom/book-metadata.d.ts +32 -0
  72. package/dist/yom/generated/yomu/yom/book-metadata.d.ts.map +1 -0
  73. package/dist/yom/generated/yomu/yom/book-metadata.js +89 -0
  74. package/dist/yom/generated/yomu/yom/book-metadata.js.map +1 -0
  75. package/dist/yom/generated/yomu/yom/compression.d.ts +5 -0
  76. package/dist/yom/generated/yomu/yom/compression.d.ts.map +1 -0
  77. package/dist/yom/generated/yomu/yom/compression.js +8 -0
  78. package/dist/yom/generated/yomu/yom/compression.js.map +1 -0
  79. package/dist/yom/generated/yomu/yom/main-index.d.ts +63 -0
  80. package/dist/yom/generated/yomu/yom/main-index.d.ts.map +1 -0
  81. package/dist/yom/generated/yomu/yom/main-index.js +208 -0
  82. package/dist/yom/generated/yomu/yom/main-index.js.map +1 -0
  83. package/dist/yom/generated/yomu/yom/ocrblock.d.ts +32 -0
  84. package/dist/yom/generated/yomu/yom/ocrblock.d.ts.map +1 -0
  85. package/dist/yom/generated/yomu/yom/ocrblock.js +84 -0
  86. package/dist/yom/generated/yomu/yom/ocrblock.js.map +1 -0
  87. package/dist/yom/generated/yomu/yom/ocrlayout.d.ts +27 -0
  88. package/dist/yom/generated/yomu/yom/ocrlayout.d.ts.map +1 -0
  89. package/dist/yom/generated/yomu/yom/ocrlayout.js +76 -0
  90. package/dist/yom/generated/yomu/yom/ocrlayout.js.map +1 -0
  91. package/dist/yom/generated/yomu/yom/ocrline.d.ts +35 -0
  92. package/dist/yom/generated/yomu/yom/ocrline.d.ts.map +1 -0
  93. package/dist/yom/generated/yomu/yom/ocrline.js +95 -0
  94. package/dist/yom/generated/yomu/yom/ocrline.js.map +1 -0
  95. package/dist/yom/generated/yomu/yom/ocrpage.d.ts +46 -0
  96. package/dist/yom/generated/yomu/yom/ocrpage.d.ts.map +1 -0
  97. package/dist/yom/generated/yomu/yom/ocrpage.js +147 -0
  98. package/dist/yom/generated/yomu/yom/ocrpage.js.map +1 -0
  99. package/dist/yom/generated/yomu/yom/ocrtoken.d.ts +44 -0
  100. package/dist/yom/generated/yomu/yom/ocrtoken.d.ts.map +1 -0
  101. package/dist/yom/generated/yomu/yom/ocrtoken.js +128 -0
  102. package/dist/yom/generated/yomu/yom/ocrtoken.js.map +1 -0
  103. package/dist/yom/generated/yomu/yom/outline-entry.d.ts +31 -0
  104. package/dist/yom/generated/yomu/yom/outline-entry.d.ts.map +1 -0
  105. package/dist/yom/generated/yomu/yom/outline-entry.js +92 -0
  106. package/dist/yom/generated/yomu/yom/outline-entry.js.map +1 -0
  107. package/dist/yom/generated/yomu/yom/page-entry.d.ts +95 -0
  108. package/dist/yom/generated/yomu/yom/page-entry.d.ts.map +1 -0
  109. package/dist/yom/generated/yomu/yom/page-entry.js +288 -0
  110. package/dist/yom/generated/yomu/yom/page-entry.js.map +1 -0
  111. package/dist/yom/generated/yomu/yom/pdfexport-metadata.d.ts +32 -0
  112. package/dist/yom/generated/yomu/yom/pdfexport-metadata.d.ts.map +1 -0
  113. package/dist/yom/generated/yomu/yom/pdfexport-metadata.js +96 -0
  114. package/dist/yom/generated/yomu/yom/pdfexport-metadata.js.map +1 -0
  115. package/dist/yom/generated/yomu/yom/reading-direction.d.ts +5 -0
  116. package/dist/yom/generated/yomu/yom/reading-direction.d.ts.map +1 -0
  117. package/dist/yom/generated/yomu/yom/reading-direction.js +8 -0
  118. package/dist/yom/generated/yomu/yom/reading-direction.js.map +1 -0
  119. package/dist/yom/generated/yomu/yom/search-term-ref.d.ts +34 -0
  120. package/dist/yom/generated/yomu/yom/search-term-ref.d.ts.map +1 -0
  121. package/dist/yom/generated/yomu/yom/search-term-ref.js +99 -0
  122. package/dist/yom/generated/yomu/yom/search-term-ref.js.map +1 -0
  123. package/dist/yom/generated/yomu/yom.d.ts +6 -0
  124. package/dist/yom/generated/yomu/yom.d.ts.map +1 -0
  125. package/dist/yom/generated/yomu/yom.js +8 -0
  126. package/dist/yom/generated/yomu/yom.js.map +1 -0
  127. package/dist/yom/hash.d.ts +4 -0
  128. package/dist/yom/hash.d.ts.map +1 -0
  129. package/dist/yom/hash.js +21 -0
  130. package/dist/yom/hash.js.map +1 -0
  131. package/dist/yom/header.d.ts +44 -0
  132. package/dist/yom/header.d.ts.map +1 -0
  133. package/dist/yom/header.js +115 -0
  134. package/dist/yom/header.js.map +1 -0
  135. package/dist/yom/reader.d.ts +57 -0
  136. package/dist/yom/reader.d.ts.map +1 -0
  137. package/dist/yom/reader.js +141 -0
  138. package/dist/yom/reader.js.map +1 -0
  139. package/dist/yom/searchIndex.d.ts +41 -0
  140. package/dist/yom/searchIndex.d.ts.map +1 -0
  141. package/dist/yom/searchIndex.js +133 -0
  142. package/dist/yom/searchIndex.js.map +1 -0
  143. package/dist/yom/textNormalizer.d.ts +19 -0
  144. package/dist/yom/textNormalizer.d.ts.map +1 -0
  145. package/dist/yom/textNormalizer.js +77 -0
  146. package/dist/yom/textNormalizer.js.map +1 -0
  147. package/dist/yom/validator.d.ts +14 -0
  148. package/dist/yom/validator.d.ts.map +1 -0
  149. package/dist/yom/validator.js +197 -0
  150. package/dist/yom/validator.js.map +1 -0
  151. package/dist/yom/writer.d.ts +76 -0
  152. package/dist/yom/writer.d.ts.map +1 -0
  153. package/dist/yom/writer.js +154 -0
  154. package/dist/yom/writer.js.map +1 -0
  155. package/dist/yom/zstd.d.ts +14 -0
  156. package/dist/yom/zstd.d.ts.map +1 -0
  157. package/dist/yom/zstd.js +43 -0
  158. package/dist/yom/zstd.js.map +1 -0
  159. package/package.json +65 -0
  160. package/src/cli.ts +372 -0
  161. package/src/index.ts +109 -0
  162. package/src/pipeline/avif.ts +33 -0
  163. package/src/pipeline/convert.ts +148 -0
  164. package/src/pipeline/index.ts +28 -0
  165. package/src/pipeline/ocrLayoutBuilder.ts +73 -0
  166. package/src/pipeline/pdfDocument.ts +86 -0
  167. package/src/pipeline/renderPage.ts +48 -0
  168. package/src/pipeline/textExtract.ts +64 -0
  169. package/src/worker/convert.worker.ts +54 -0
  170. package/src/yom/blobLimits.ts +30 -0
  171. package/src/yom/byteSource.ts +144 -0
  172. package/src/yom/bytes.ts +11 -0
  173. package/src/yom/constants.ts +89 -0
  174. package/src/yom/errors.ts +43 -0
  175. package/src/yom/flatbufferVerify.ts +298 -0
  176. package/src/yom/generated/yomu/yom/blob-kind.ts +12 -0
  177. package/src/yom/generated/yomu/yom/blob-ref.ts +184 -0
  178. package/src/yom/generated/yomu/yom/book-metadata.ts +121 -0
  179. package/src/yom/generated/yomu/yom/compression.ts +8 -0
  180. package/src/yom/generated/yomu/yom/main-index.ts +257 -0
  181. package/src/yom/generated/yomu/yom/ocrblock.ts +117 -0
  182. package/src/yom/generated/yomu/yom/ocrlayout.ts +102 -0
  183. package/src/yom/generated/yomu/yom/ocrline.ts +131 -0
  184. package/src/yom/generated/yomu/yom/ocrpage.ts +191 -0
  185. package/src/yom/generated/yomu/yom/ocrtoken.ts +173 -0
  186. package/src/yom/generated/yomu/yom/outline-entry.ts +124 -0
  187. package/src/yom/generated/yomu/yom/page-entry.ts +388 -0
  188. package/src/yom/generated/yomu/yom/pdfexport-metadata.ts +128 -0
  189. package/src/yom/generated/yomu/yom/reading-direction.ts +8 -0
  190. package/src/yom/generated/yomu/yom/search-term-ref.ts +134 -0
  191. package/src/yom/generated/yomu/yom.ts +9 -0
  192. package/src/yom/hash.ts +20 -0
  193. package/src/yom/header.ts +132 -0
  194. package/src/yom/reader.ts +163 -0
  195. package/src/yom/searchIndex.ts +178 -0
  196. package/src/yom/textNormalizer.ts +92 -0
  197. package/src/yom/validator.ts +245 -0
  198. package/src/yom/writer.ts +337 -0
  199. package/src/yom/zstd.ts +47 -0
@@ -0,0 +1,56 @@
1
+ import { YOMError } from "./errors.js";
2
+ /**
3
+ * Gap 1: the byte-source abstraction every reader read goes through, so the
4
+ * same `YOMPackfileReader` can serve a fully in-memory `.yom` or one streamed
5
+ * over HTTP `Range` requests without ever loading the whole file.
6
+ */
7
+ export interface ByteSource {
8
+ /** Total file length in bytes. */
9
+ readonly size: number;
10
+ /** Reads exactly `[offset, offset+length)`; rejects if it can't. */
11
+ read(offset: number, length: number): Promise<Uint8Array>;
12
+ }
13
+ /** Raised when a `ByteSource.read` cannot return the requested extent. */
14
+ export declare class ByteSourceError extends YOMError {
15
+ }
16
+ /** A `ByteSource` over an already-resident `Uint8Array` (zero-copy slices). */
17
+ export declare class MemoryByteSource implements ByteSource {
18
+ readonly size: number;
19
+ private readonly bytes;
20
+ constructor(bytes: Uint8Array);
21
+ read(offset: number, length: number): Promise<Uint8Array>;
22
+ }
23
+ type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
24
+ export interface HttpRangeOptions {
25
+ /** Override the global `fetch` (for tests / custom transports). */
26
+ fetch?: FetchLike;
27
+ /** Extra request headers (auth, etc.). */
28
+ headers?: Record<string, string>;
29
+ /** Skip the size probe if the caller already knows `Content-Length`. */
30
+ size?: number;
31
+ /** Abort in-flight requests. */
32
+ signal?: AbortSignal;
33
+ }
34
+ /**
35
+ * A `ByteSource` backed by HTTP `Range` requests. `create()` learns the total
36
+ * size and confirms range support up front (one `Range: bytes=0-` probe, or a
37
+ * caller-supplied `size`); each `read()` issues `GET Range: bytes=a-b`,
38
+ * validates the `206` + `Content-Range`/length, and returns the slice.
39
+ *
40
+ * The server must answer `206 Partial Content` to ranged requests; a plain
41
+ * `200 OK` means ranges are unsupported and `create()` throws
42
+ * `RangeNotSupportedError`. For cross-origin use the server must expose
43
+ * `Content-Range`, `Accept-Ranges`, and `Content-Length` via CORS.
44
+ */
45
+ export declare class HttpRangeByteSource implements ByteSource {
46
+ readonly size: number;
47
+ private readonly url;
48
+ private readonly fetchFn;
49
+ private readonly headers;
50
+ private readonly signal?;
51
+ private constructor();
52
+ static create(url: string, opts?: HttpRangeOptions): Promise<HttpRangeByteSource>;
53
+ read(offset: number, length: number): Promise<Uint8Array>;
54
+ }
55
+ export {};
56
+ //# sourceMappingURL=byteSource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"byteSource.d.ts","sourceRoot":"","sources":["../../src/yom/byteSource.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE/D;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,kCAAkC;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CAC3D;AAED,0EAA0E;AAC1E,qBAAa,eAAgB,SAAQ,QAAQ;CAAG;AAEhD,+EAA+E;AAC/E,qBAAa,gBAAiB,YAAW,UAAU;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;gBAEvB,KAAK,EAAE,UAAU;IAK7B,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CAM1D;AAED,KAAK,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE1E,MAAM,WAAW,gBAAgB;IAC/B,mEAAmE;IACnE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,mBAAoB,YAAW,UAAU;IACpD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAY;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAc;IAEtC,OAAO;WAQM,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAkCrF,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CAwBhE"}
@@ -0,0 +1,111 @@
1
+ import { RangeNotSupportedError, YOMError } from "./errors.js";
2
+ /** Raised when a `ByteSource.read` cannot return the requested extent. */
3
+ export class ByteSourceError extends YOMError {
4
+ }
5
+ /** A `ByteSource` over an already-resident `Uint8Array` (zero-copy slices). */
6
+ export class MemoryByteSource {
7
+ size;
8
+ bytes;
9
+ constructor(bytes) {
10
+ this.bytes = bytes;
11
+ this.size = bytes.length;
12
+ }
13
+ read(offset, length) {
14
+ if (offset < 0 || length < 0 || offset + length > this.bytes.length) {
15
+ return Promise.reject(new ByteSourceError(`read [${offset}, ${offset + length}) out of bounds (size ${this.size})`));
16
+ }
17
+ return Promise.resolve(this.bytes.subarray(offset, offset + length));
18
+ }
19
+ }
20
+ /**
21
+ * A `ByteSource` backed by HTTP `Range` requests. `create()` learns the total
22
+ * size and confirms range support up front (one `Range: bytes=0-` probe, or a
23
+ * caller-supplied `size`); each `read()` issues `GET Range: bytes=a-b`,
24
+ * validates the `206` + `Content-Range`/length, and returns the slice.
25
+ *
26
+ * The server must answer `206 Partial Content` to ranged requests; a plain
27
+ * `200 OK` means ranges are unsupported and `create()` throws
28
+ * `RangeNotSupportedError`. For cross-origin use the server must expose
29
+ * `Content-Range`, `Accept-Ranges`, and `Content-Length` via CORS.
30
+ */
31
+ export class HttpRangeByteSource {
32
+ size;
33
+ url;
34
+ fetchFn;
35
+ headers;
36
+ signal;
37
+ constructor(url, size, opts) {
38
+ this.url = url;
39
+ this.size = size;
40
+ this.fetchFn = opts.fetch ?? ((input, init) => fetch(input, init));
41
+ this.headers = opts.headers ?? {};
42
+ this.signal = opts.signal;
43
+ }
44
+ static async create(url, opts = {}) {
45
+ const fetchFn = opts.fetch ?? ((input, init) => fetch(input, init));
46
+ const headers = opts.headers ?? {};
47
+ if (typeof opts.size === "number") {
48
+ return new HttpRangeByteSource(url, opts.size, opts);
49
+ }
50
+ // Probe with an open-ended range: a range-capable server answers 206 with
51
+ // a `Content-Range: bytes 0-.../TOTAL` from which we learn the size.
52
+ const res = await fetchFn(url, {
53
+ method: "GET",
54
+ headers: { ...headers, Range: "bytes=0-0" },
55
+ signal: opts.signal,
56
+ });
57
+ if (res.status === 200) {
58
+ // Server ignored the range and sent the whole body.
59
+ throw new RangeNotSupportedError(`server does not support range requests (status 200) for ${url}`);
60
+ }
61
+ if (res.status !== 206) {
62
+ throw new ByteSourceError(`unexpected status ${res.status} probing ${url}`);
63
+ }
64
+ const total = parseContentRangeTotal(res.headers.get("Content-Range"));
65
+ if (total === null) {
66
+ const len = res.headers.get("Content-Length");
67
+ throw new ByteSourceError(`range probe missing Content-Range total for ${url} (Content-Length ${len ?? "?"})`);
68
+ }
69
+ // Drain the tiny probe body to release the connection.
70
+ await res.arrayBuffer().catch(() => undefined);
71
+ return new HttpRangeByteSource(url, total, opts);
72
+ }
73
+ async read(offset, length) {
74
+ if (offset < 0 || length < 0 || offset + length > this.size) {
75
+ throw new ByteSourceError(`read [${offset}, ${offset + length}) out of bounds (size ${this.size})`);
76
+ }
77
+ if (length === 0)
78
+ return new Uint8Array(0);
79
+ const end = offset + length - 1; // HTTP ranges are inclusive
80
+ const res = await this.fetchFn(this.url, {
81
+ method: "GET",
82
+ headers: { ...this.headers, Range: `bytes=${offset}-${end}` },
83
+ signal: this.signal,
84
+ });
85
+ if (res.status === 200) {
86
+ throw new RangeNotSupportedError(`server ignored range request (status 200) for ${this.url}`);
87
+ }
88
+ if (res.status !== 206) {
89
+ throw new ByteSourceError(`unexpected status ${res.status} reading ${this.url}`);
90
+ }
91
+ const body = new Uint8Array(await res.arrayBuffer());
92
+ if (body.length !== length) {
93
+ throw new ByteSourceError(`range read returned ${body.length} bytes, expected ${length}`);
94
+ }
95
+ return body;
96
+ }
97
+ }
98
+ /** Parses the `TOTAL` out of a `Content-Range: bytes A-B/TOTAL` header. */
99
+ function parseContentRangeTotal(header) {
100
+ if (!header)
101
+ return null;
102
+ const slash = header.lastIndexOf("/");
103
+ if (slash < 0)
104
+ return null;
105
+ const total = header.slice(slash + 1).trim();
106
+ if (total === "" || total === "*")
107
+ return null;
108
+ const parsed = Number(total);
109
+ return Number.isInteger(parsed) && parsed >= 0 ? parsed : null;
110
+ }
111
+ //# sourceMappingURL=byteSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"byteSource.js","sourceRoot":"","sources":["../../src/yom/byteSource.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function concatBytes(chunks: Uint8Array[]): Uint8Array;
2
+ //# sourceMappingURL=bytes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bytes.d.ts","sourceRoot":"","sources":["../../src/yom/bytes.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,UAAU,CAU5D"}
@@ -0,0 +1,13 @@
1
+ export function concatBytes(chunks) {
2
+ let total = 0;
3
+ for (const chunk of chunks)
4
+ total += chunk.length;
5
+ const out = new Uint8Array(total);
6
+ let offset = 0;
7
+ for (const chunk of chunks) {
8
+ out.set(chunk, offset);
9
+ offset += chunk.length;
10
+ }
11
+ return out;
12
+ }
13
+ //# sourceMappingURL=bytes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bytes.js","sourceRoot":"","sources":["../../src/yom/bytes.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,MAAoB;IAC9C,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,KAAK,IAAI,MAAM;QAAE,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC;IAClD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC;IACzB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { BlobKind } from "./generated/yomu/yom/blob-kind.js";
2
+ import { Compression } from "./generated/yomu/yom/compression.js";
3
+ /**
4
+ * YOM v1 format constants shared by the writer, reader, and validator.
5
+ * Mirrors the Swift implementation in `swift/Sources/YOMFormat/YOMConstants.swift`
6
+ * field-for-field so Web- and native-generated `.yom` packages agree on
7
+ * layout. See docs/format-spec.md for rationale.
8
+ */
9
+ export declare const YOM_FILE_EXTENSION = "yom";
10
+ export declare const YOM_MIME_TYPE = "application/vnd.yomu.yom";
11
+ export declare const YOM_MAGIC: Uint8Array<ArrayBuffer>;
12
+ export declare const YOM_HEADER_SIZE = 4096;
13
+ export declare const YOM_FORMAT_VERSION = 1;
14
+ export declare const YOM_HASH_LENGTH = 32;
15
+ export declare const YOM_IMAGE_BLOB_ALIGNMENT = 16;
16
+ export declare const YOM_DEFAULT_BLOB_ALIGNMENT = 1;
17
+ export declare function requiredCompression(kind: BlobKind): Compression;
18
+ export declare function requiredAlignment(kind: BlobKind): number;
19
+ /** Per-kind cap on a blob's declared `uncompressed_length`, in bytes. */
20
+ export declare const MAX_BLOB_UNCOMPRESSED_IMAGE: number;
21
+ export declare const MAX_BLOB_UNCOMPRESSED_TEXT: number;
22
+ export declare const MAX_BLOB_UNCOMPRESSED_POSTINGS: number;
23
+ /** Cap on the sum of every blob's declared `uncompressed_length` (whole-file validation). */
24
+ export declare const MAX_TOTAL_UNCOMPRESSED: number;
25
+ /**
26
+ * Reject a blob whose declared inflation ratio
27
+ * (`uncompressed_length / max(compressed_length, 1)`) exceeds this -- the
28
+ * classic zip/zstd-bomb signature. zstd rarely exceeds ~3-5x on scanned-book
29
+ * text/OCR, so 1000x is a generous safety margin.
30
+ */
31
+ export declare const MAX_INFLATION_RATIO = 1000;
32
+ /** The `uncompressed_length` cap that applies to a blob of the given kind. */
33
+ export declare function maxBlobUncompressed(kind: BlobKind): number;
34
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/yom/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAElE;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AACxC,eAAO,MAAM,aAAa,6BAA6B,CAAC;AACxD,eAAO,MAAM,SAAS,yBAA2C,CAAC;AAClE,eAAO,MAAM,eAAe,OAAO,CAAC;AACpC,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,eAAO,MAAM,eAAe,KAAK,CAAC;AAClC,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAE5C,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,GAAG,WAAW,CAa/D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAQxD;AAgBD,yEAAyE;AACzE,eAAO,MAAM,2BAA2B,QAAmB,CAAC;AAC5D,eAAO,MAAM,0BAA0B,QAAmB,CAAC;AAC3D,eAAO,MAAM,8BAA8B,QAAmB,CAAC;AAE/D,6FAA6F;AAC7F,eAAO,MAAM,sBAAsB,QAAyB,CAAC;AAE7D;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAExC,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAc1D"}
@@ -0,0 +1,82 @@
1
+ import { BlobKind } from "./generated/yomu/yom/blob-kind.js";
2
+ import { Compression } from "./generated/yomu/yom/compression.js";
3
+ /**
4
+ * YOM v1 format constants shared by the writer, reader, and validator.
5
+ * Mirrors the Swift implementation in `swift/Sources/YOMFormat/YOMConstants.swift`
6
+ * field-for-field so Web- and native-generated `.yom` packages agree on
7
+ * layout. See docs/format-spec.md for rationale.
8
+ */
9
+ export const YOM_FILE_EXTENSION = "yom";
10
+ export const YOM_MIME_TYPE = "application/vnd.yomu.yom";
11
+ export const YOM_MAGIC = new Uint8Array([0x59, 0x4f, 0x4d, 0x31]); // "YOM1"
12
+ export const YOM_HEADER_SIZE = 4096;
13
+ export const YOM_FORMAT_VERSION = 1;
14
+ export const YOM_HASH_LENGTH = 32;
15
+ export const YOM_IMAGE_BLOB_ALIGNMENT = 16;
16
+ export const YOM_DEFAULT_BLOB_ALIGNMENT = 1;
17
+ export function requiredCompression(kind) {
18
+ switch (kind) {
19
+ case BlobKind.PageImage:
20
+ case BlobKind.ThumbnailImage:
21
+ case BlobKind.SearchPostings:
22
+ return Compression.None;
23
+ case BlobKind.OCRLayout:
24
+ case BlobKind.NormalizedText:
25
+ case BlobKind.SearchDictionary:
26
+ return Compression.Zstd;
27
+ default:
28
+ throw new Error(`unknown blob kind: ${kind}`);
29
+ }
30
+ }
31
+ export function requiredAlignment(kind) {
32
+ switch (kind) {
33
+ case BlobKind.PageImage:
34
+ case BlobKind.ThumbnailImage:
35
+ return YOM_IMAGE_BLOB_ALIGNMENT;
36
+ default:
37
+ return YOM_DEFAULT_BLOB_ALIGNMENT;
38
+ }
39
+ }
40
+ /*
41
+ * -------------------------------------------------------------------------
42
+ * Reader-side safety limits (Gap 2 hardening).
43
+ *
44
+ * IMPORTANT: these are **reader policy, NOT format requirements**. The writer
45
+ * MUST NOT enforce them and the on-disk format places no upper bound on blob
46
+ * sizes -- a conforming `.yom` may legally exceed any of these. They exist
47
+ * only so a *reader* can refuse to allocate unbounded memory for a malformed
48
+ * or hostile file (decompression bombs, forged declared sizes) before it
49
+ * touches the data. Values are chosen comfortably above every real-world and
50
+ * fixture blob size; raise them if a legitimate corpus needs more.
51
+ * -------------------------------------------------------------------------
52
+ */
53
+ /** Per-kind cap on a blob's declared `uncompressed_length`, in bytes. */
54
+ export const MAX_BLOB_UNCOMPRESSED_IMAGE = 64 * 1024 * 1024; // page/thumbnail AVIF
55
+ export const MAX_BLOB_UNCOMPRESSED_TEXT = 16 * 1024 * 1024; // OCR / normalized text / dictionary
56
+ export const MAX_BLOB_UNCOMPRESSED_POSTINGS = 64 * 1024 * 1024; // search postings scale with book size
57
+ /** Cap on the sum of every blob's declared `uncompressed_length` (whole-file validation). */
58
+ export const MAX_TOTAL_UNCOMPRESSED = 4 * 1024 * 1024 * 1024;
59
+ /**
60
+ * Reject a blob whose declared inflation ratio
61
+ * (`uncompressed_length / max(compressed_length, 1)`) exceeds this -- the
62
+ * classic zip/zstd-bomb signature. zstd rarely exceeds ~3-5x on scanned-book
63
+ * text/OCR, so 1000x is a generous safety margin.
64
+ */
65
+ export const MAX_INFLATION_RATIO = 1000;
66
+ /** The `uncompressed_length` cap that applies to a blob of the given kind. */
67
+ export function maxBlobUncompressed(kind) {
68
+ switch (kind) {
69
+ case BlobKind.PageImage:
70
+ case BlobKind.ThumbnailImage:
71
+ return MAX_BLOB_UNCOMPRESSED_IMAGE;
72
+ case BlobKind.SearchPostings:
73
+ return MAX_BLOB_UNCOMPRESSED_POSTINGS;
74
+ case BlobKind.OCRLayout:
75
+ case BlobKind.NormalizedText:
76
+ case BlobKind.SearchDictionary:
77
+ return MAX_BLOB_UNCOMPRESSED_TEXT;
78
+ default:
79
+ return MAX_BLOB_UNCOMPRESSED_TEXT;
80
+ }
81
+ }
82
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/yom/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAElE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC;AACxC,MAAM,CAAC,MAAM,aAAa,GAAG,0BAA0B,CAAC;AACxD,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;AAC5E,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;AACpC,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AACpC,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAClC,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAC3C,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC;AAE5C,MAAM,UAAU,mBAAmB,CAAC,IAAc;IAChD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ,CAAC,SAAS,CAAC;QACxB,KAAK,QAAQ,CAAC,cAAc,CAAC;QAC7B,KAAK,QAAQ,CAAC,cAAc;YAC1B,OAAO,WAAW,CAAC,IAAI,CAAC;QAC1B,KAAK,QAAQ,CAAC,SAAS,CAAC;QACxB,KAAK,QAAQ,CAAC,cAAc,CAAC;QAC7B,KAAK,QAAQ,CAAC,gBAAgB;YAC5B,OAAO,WAAW,CAAC,IAAI,CAAC;QAC1B;YACE,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAc;IAC9C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ,CAAC,SAAS,CAAC;QACxB,KAAK,QAAQ,CAAC,cAAc;YAC1B,OAAO,wBAAwB,CAAC;QAClC;YACE,OAAO,0BAA0B,CAAC;IACtC,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AAEH,yEAAyE;AACzE,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,sBAAsB;AACnF,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,qCAAqC;AACjG,MAAM,CAAC,MAAM,8BAA8B,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,uCAAuC;AAEvG,6FAA6F;AAC7F,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE7D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAExC,8EAA8E;AAC9E,MAAM,UAAU,mBAAmB,CAAC,IAAc;IAChD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ,CAAC,SAAS,CAAC;QACxB,KAAK,QAAQ,CAAC,cAAc;YAC1B,OAAO,2BAA2B,CAAC;QACrC,KAAK,QAAQ,CAAC,cAAc;YAC1B,OAAO,8BAA8B,CAAC;QACxC,KAAK,QAAQ,CAAC,SAAS,CAAC;QACxB,KAAK,QAAQ,CAAC,cAAc,CAAC;QAC7B,KAAK,QAAQ,CAAC,gBAAgB;YAC5B,OAAO,0BAA0B,CAAC;QACpC;YACE,OAAO,0BAA0B,CAAC;IACtC,CAAC;AACH,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Typed error hierarchy for the YOM reader/validator hardening layers.
3
+ *
4
+ * These are all *reader-side* failures raised while opening or reading a
5
+ * possibly-hostile `.yom`. They exist so callers can distinguish "the input
6
+ * is malformed/oversized/corrupt" from ordinary programming errors, and so
7
+ * the size-cap / FlatBuffers-verify / HTTP-Range layers throw a stable,
8
+ * catchable type instead of a bare `Error`.
9
+ */
10
+ /** Base class for every typed reader error added by the hardening layers. */
11
+ export declare class YOMError extends Error {
12
+ }
13
+ /**
14
+ * A blob's declared `uncompressed_length` exceeds the reader's per-kind size
15
+ * cap, or its declared inflation ratio (`uncompressed / compressed`) exceeds
16
+ * `MAX_INFLATION_RATIO`. Raised *before* any decompression happens, so a
17
+ * decompression-bomb never gets to allocate memory.
18
+ */
19
+ export declare class BlobTooLargeError extends YOMError {
20
+ }
21
+ /**
22
+ * A blob decompressed to a different byte length than its declared
23
+ * `uncompressed_length` (or decompression otherwise failed). Raised before
24
+ * the decompressed bytes are used, ahead of the final SHA-256 gate.
25
+ */
26
+ export declare class CorruptBlobError extends YOMError {
27
+ }
28
+ /**
29
+ * The main FlatBuffers index (or an OCR layout blob) failed bounded
30
+ * structural verification: an offset, vtable, table, string, or vector would
31
+ * dereference outside the known index byte range, or a vector length is
32
+ * absurdly large. Raised instead of returning a booby-trapped `getRootAs*`
33
+ * root that could later read out of bounds.
34
+ */
35
+ export declare class MalformedIndexError extends YOMError {
36
+ }
37
+ /**
38
+ * An HTTP source does not support range requests (it answered a ranged `GET`
39
+ * with `200 OK` / no `Accept-Ranges` instead of `206 Partial Content`).
40
+ * Callers may retry with `openURL(url, { fallbackToFullFetch: true })`.
41
+ */
42
+ export declare class RangeNotSupportedError extends YOMError {
43
+ }
44
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/yom/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,6EAA6E;AAC7E,qBAAa,QAAS,SAAQ,KAAK;CAAG;AAEtC;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;CAAG;AAElD;;;;GAIG;AACH,qBAAa,gBAAiB,SAAQ,QAAQ;CAAG;AAEjD;;;;;;GAMG;AACH,qBAAa,mBAAoB,SAAQ,QAAQ;CAAG;AAEpD;;;;GAIG;AACH,qBAAa,sBAAuB,SAAQ,QAAQ;CAAG"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Typed error hierarchy for the YOM reader/validator hardening layers.
3
+ *
4
+ * These are all *reader-side* failures raised while opening or reading a
5
+ * possibly-hostile `.yom`. They exist so callers can distinguish "the input
6
+ * is malformed/oversized/corrupt" from ordinary programming errors, and so
7
+ * the size-cap / FlatBuffers-verify / HTTP-Range layers throw a stable,
8
+ * catchable type instead of a bare `Error`.
9
+ */
10
+ /** Base class for every typed reader error added by the hardening layers. */
11
+ export class YOMError extends Error {
12
+ }
13
+ /**
14
+ * A blob's declared `uncompressed_length` exceeds the reader's per-kind size
15
+ * cap, or its declared inflation ratio (`uncompressed / compressed`) exceeds
16
+ * `MAX_INFLATION_RATIO`. Raised *before* any decompression happens, so a
17
+ * decompression-bomb never gets to allocate memory.
18
+ */
19
+ export class BlobTooLargeError extends YOMError {
20
+ }
21
+ /**
22
+ * A blob decompressed to a different byte length than its declared
23
+ * `uncompressed_length` (or decompression otherwise failed). Raised before
24
+ * the decompressed bytes are used, ahead of the final SHA-256 gate.
25
+ */
26
+ export class CorruptBlobError extends YOMError {
27
+ }
28
+ /**
29
+ * The main FlatBuffers index (or an OCR layout blob) failed bounded
30
+ * structural verification: an offset, vtable, table, string, or vector would
31
+ * dereference outside the known index byte range, or a vector length is
32
+ * absurdly large. Raised instead of returning a booby-trapped `getRootAs*`
33
+ * root that could later read out of bounds.
34
+ */
35
+ export class MalformedIndexError extends YOMError {
36
+ }
37
+ /**
38
+ * An HTTP source does not support range requests (it answered a ranged `GET`
39
+ * with `200 OK` / no `Accept-Ranges` instead of `206 Partial Content`).
40
+ * Callers may retry with `openURL(url, { fallbackToFullFetch: true })`.
41
+ */
42
+ export class RangeNotSupportedError extends YOMError {
43
+ }
44
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/yom/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,6EAA6E;AAC7E,MAAM,OAAO,QAAS,SAAQ,KAAK;CAAG;AAEtC;;;;;GAKG;AACH,MAAM,OAAO,iBAAkB,SAAQ,QAAQ;CAAG;AAElD;;;;GAIG;AACH,MAAM,OAAO,gBAAiB,SAAQ,QAAQ;CAAG;AAEjD;;;;;;GAMG;AACH,MAAM,OAAO,mBAAoB,SAAQ,QAAQ;CAAG;AAEpD;;;;GAIG;AACH,MAAM,OAAO,sBAAuB,SAAQ,QAAQ;CAAG"}
@@ -0,0 +1,21 @@
1
+ import { MainIndex } from "./generated/yomu/yom/main-index.js";
2
+ /**
3
+ * Bounded structural verification of a raw (uncompressed) main-index byte
4
+ * range. `deep` controls whether sub-tables/vectors are recursed into
5
+ * (validator) or only their offsets/lengths bounds-checked (reader open).
6
+ * Throws `MalformedIndexError` on any violation.
7
+ */
8
+ export declare function verifyMainIndex(indexBytes: Uint8Array, deep: boolean): void;
9
+ /**
10
+ * Verify then construct the `MainIndex` root, so a malformed buffer throws
11
+ * `MalformedIndexError` instead of yielding a booby-trapped lazy root.
12
+ */
13
+ export declare function getVerifiedRootAsMainIndex(indexBytes: Uint8Array, deep: boolean): MainIndex;
14
+ /**
15
+ * True only when the index's optional `pdfExport` metadata is genuinely
16
+ * present and safely traversable. Because the writer emits an absent
17
+ * `pdfExport` via `forceDefaults(true)` (a sentinel pointing out of bounds),
18
+ * callers must gate any `pdfExport()`/outline read on this check.
19
+ */
20
+ export declare function pdfExportPresent(indexBytes: Uint8Array): boolean;
21
+ //# sourceMappingURL=flatbufferVerify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flatbufferVerify.d.ts","sourceRoot":"","sources":["../../src/yom/flatbufferVerify.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAqQ/D;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAE3E;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,GAAG,SAAS,CAG3F;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAUhE"}