@graphty/graph-format 0.0.0 → 0.2.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 (224) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +216 -43
  3. package/dist/graph-format.d.ts +1 -0
  4. package/dist/graph-format.d.ts.map +1 -0
  5. package/dist/graph-format.js +15798 -0
  6. package/dist/graph-format.js.map +1 -0
  7. package/dist/src/builder/arena.d.ts +85 -0
  8. package/dist/src/builder/arena.d.ts.map +1 -0
  9. package/dist/src/builder/arena.js +154 -0
  10. package/dist/src/builder/arena.js.map +1 -0
  11. package/dist/src/builder/compact.d.ts +515 -0
  12. package/dist/src/builder/compact.d.ts.map +1 -0
  13. package/dist/src/builder/compact.js +1553 -0
  14. package/dist/src/builder/compact.js.map +1 -0
  15. package/dist/src/builder/counting-sort.d.ts +96 -0
  16. package/dist/src/builder/counting-sort.d.ts.map +1 -0
  17. package/dist/src/builder/counting-sort.js +430 -0
  18. package/dist/src/builder/counting-sort.js.map +1 -0
  19. package/dist/src/builder/freeze.d.ts +72 -0
  20. package/dist/src/builder/freeze.d.ts.map +1 -0
  21. package/dist/src/builder/freeze.js +548 -0
  22. package/dist/src/builder/freeze.js.map +1 -0
  23. package/dist/src/builder/graph-builder.d.ts +602 -0
  24. package/dist/src/builder/graph-builder.d.ts.map +1 -0
  25. package/dist/src/builder/graph-builder.js +1940 -0
  26. package/dist/src/builder/graph-builder.js.map +1 -0
  27. package/dist/src/builder/options.d.ts +16 -0
  28. package/dist/src/builder/options.d.ts.map +1 -0
  29. package/dist/src/builder/options.js +21 -0
  30. package/dist/src/builder/options.js.map +1 -0
  31. package/dist/src/columns/bitmap.d.ts +96 -0
  32. package/dist/src/columns/bitmap.d.ts.map +1 -0
  33. package/dist/src/columns/bitmap.js +184 -0
  34. package/dist/src/columns/bitmap.js.map +1 -0
  35. package/dist/src/columns/column.d.ts +220 -0
  36. package/dist/src/columns/column.d.ts.map +1 -0
  37. package/dist/src/columns/column.js +2109 -0
  38. package/dist/src/columns/column.js.map +1 -0
  39. package/dist/src/columns/dictionary.d.ts +60 -0
  40. package/dist/src/columns/dictionary.d.ts.map +1 -0
  41. package/dist/src/columns/dictionary.js +102 -0
  42. package/dist/src/columns/dictionary.js.map +1 -0
  43. package/dist/src/columns/growable.d.ts +198 -0
  44. package/dist/src/columns/growable.d.ts.map +1 -0
  45. package/dist/src/columns/growable.js +296 -0
  46. package/dist/src/columns/growable.js.map +1 -0
  47. package/dist/src/columns/infer.d.ts +121 -0
  48. package/dist/src/columns/infer.d.ts.map +1 -0
  49. package/dist/src/columns/infer.js +268 -0
  50. package/dist/src/columns/infer.js.map +1 -0
  51. package/dist/src/columns/remap.d.ts +143 -0
  52. package/dist/src/columns/remap.d.ts.map +1 -0
  53. package/dist/src/columns/remap.js +588 -0
  54. package/dist/src/columns/remap.js.map +1 -0
  55. package/dist/src/columns/table.d.ts +184 -0
  56. package/dist/src/columns/table.d.ts.map +1 -0
  57. package/dist/src/columns/table.js +485 -0
  58. package/dist/src/columns/table.js.map +1 -0
  59. package/dist/src/constants.d.ts +34 -0
  60. package/dist/src/constants.d.ts.map +1 -0
  61. package/dist/src/constants.js +79 -0
  62. package/dist/src/constants.js.map +1 -0
  63. package/dist/src/errors.d.ts +76 -0
  64. package/dist/src/errors.d.ts.map +1 -0
  65. package/dist/src/errors.js +32 -0
  66. package/dist/src/errors.js.map +1 -0
  67. package/dist/src/ids/edge-id-index.d.ts +77 -0
  68. package/dist/src/ids/edge-id-index.d.ts.map +1 -0
  69. package/dist/src/ids/edge-id-index.js +155 -0
  70. package/dist/src/ids/edge-id-index.js.map +1 -0
  71. package/dist/src/ids/node-id-map.d.ts +280 -0
  72. package/dist/src/ids/node-id-map.d.ts.map +1 -0
  73. package/dist/src/ids/node-id-map.js +1139 -0
  74. package/dist/src/ids/node-id-map.js.map +1 -0
  75. package/dist/src/ids/string-store.d.ts +219 -0
  76. package/dist/src/ids/string-store.d.ts.map +1 -0
  77. package/dist/src/ids/string-store.js +526 -0
  78. package/dist/src/ids/string-store.js.map +1 -0
  79. package/dist/src/index.d.ts +30 -0
  80. package/dist/src/index.d.ts.map +1 -0
  81. package/dist/src/index.js +29 -0
  82. package/dist/src/index.js.map +1 -0
  83. package/dist/src/populate/from-csr.d.ts +61 -0
  84. package/dist/src/populate/from-csr.d.ts.map +1 -0
  85. package/dist/src/populate/from-csr.js +706 -0
  86. package/dist/src/populate/from-csr.js.map +1 -0
  87. package/dist/src/populate/from-edge-arrays.d.ts +51 -0
  88. package/dist/src/populate/from-edge-arrays.d.ts.map +1 -0
  89. package/dist/src/populate/from-edge-arrays.js +217 -0
  90. package/dist/src/populate/from-edge-arrays.js.map +1 -0
  91. package/dist/src/populate/from-records.d.ts +51 -0
  92. package/dist/src/populate/from-records.d.ts.map +1 -0
  93. package/dist/src/populate/from-records.js +447 -0
  94. package/dist/src/populate/from-records.js.map +1 -0
  95. package/dist/src/snapshot/derived.d.ts +211 -0
  96. package/dist/src/snapshot/derived.d.ts.map +1 -0
  97. package/dist/src/snapshot/derived.js +1254 -0
  98. package/dist/src/snapshot/derived.js.map +1 -0
  99. package/dist/src/snapshot/graph-meta.d.ts +23 -0
  100. package/dist/src/snapshot/graph-meta.d.ts.map +1 -0
  101. package/dist/src/snapshot/graph-meta.js +159 -0
  102. package/dist/src/snapshot/graph-meta.js.map +1 -0
  103. package/dist/src/snapshot/graph-snapshot.d.ts +509 -0
  104. package/dist/src/snapshot/graph-snapshot.d.ts.map +1 -0
  105. package/dist/src/snapshot/graph-snapshot.js +1247 -0
  106. package/dist/src/snapshot/graph-snapshot.js.map +1 -0
  107. package/dist/src/snapshot/hash.d.ts +90 -0
  108. package/dist/src/snapshot/hash.d.ts.map +1 -0
  109. package/dist/src/snapshot/hash.js +228 -0
  110. package/dist/src/snapshot/hash.js.map +1 -0
  111. package/dist/src/snapshot/queries.d.ts +74 -0
  112. package/dist/src/snapshot/queries.d.ts.map +1 -0
  113. package/dist/src/snapshot/queries.js +131 -0
  114. package/dist/src/snapshot/queries.js.map +1 -0
  115. package/dist/src/snapshot/validate.d.ts +192 -0
  116. package/dist/src/snapshot/validate.d.ts.map +1 -0
  117. package/dist/src/snapshot/validate.js +990 -0
  118. package/dist/src/snapshot/validate.js.map +1 -0
  119. package/dist/src/snapshot/views.d.ts +274 -0
  120. package/dist/src/snapshot/views.d.ts.map +1 -0
  121. package/dist/src/snapshot/views.js +856 -0
  122. package/dist/src/snapshot/views.js.map +1 -0
  123. package/dist/src/types/builder.d.ts +456 -0
  124. package/dist/src/types/builder.d.ts.map +1 -0
  125. package/dist/src/types/builder.js +11 -0
  126. package/dist/src/types/builder.js.map +1 -0
  127. package/dist/src/types/columns.d.ts +615 -0
  128. package/dist/src/types/columns.d.ts.map +1 -0
  129. package/dist/src/types/columns.js +14 -0
  130. package/dist/src/types/columns.js.map +1 -0
  131. package/dist/src/types/index.d.ts +14 -0
  132. package/dist/src/types/index.d.ts.map +1 -0
  133. package/dist/src/types/index.js +11 -0
  134. package/dist/src/types/index.js.map +1 -0
  135. package/dist/src/types/internal.d.ts +172 -0
  136. package/dist/src/types/internal.d.ts.map +1 -0
  137. package/dist/src/types/internal.js +13 -0
  138. package/dist/src/types/internal.js.map +1 -0
  139. package/dist/src/types/snapshot.d.ts +801 -0
  140. package/dist/src/types/snapshot.d.ts.map +1 -0
  141. package/dist/src/types/snapshot.js +14 -0
  142. package/dist/src/types/snapshot.js.map +1 -0
  143. package/dist/src/types/wire.d.ts +196 -0
  144. package/dist/src/types/wire.d.ts.map +1 -0
  145. package/dist/src/types/wire.js +8 -0
  146. package/dist/src/types/wire.js.map +1 -0
  147. package/dist/src/util/mask.d.ts +55 -0
  148. package/dist/src/util/mask.d.ts.map +1 -0
  149. package/dist/src/util/mask.js +71 -0
  150. package/dist/src/util/mask.js.map +1 -0
  151. package/dist/src/util/options.d.ts +22 -0
  152. package/dist/src/util/options.d.ts.map +1 -0
  153. package/dist/src/util/options.js +49 -0
  154. package/dist/src/util/options.js.map +1 -0
  155. package/dist/src/util/shared-buffers.d.ts +42 -0
  156. package/dist/src/util/shared-buffers.d.ts.map +1 -0
  157. package/dist/src/util/shared-buffers.js +52 -0
  158. package/dist/src/util/shared-buffers.js.map +1 -0
  159. package/dist/src/util/typed-array.d.ts +205 -0
  160. package/dist/src/util/typed-array.d.ts.map +1 -0
  161. package/dist/src/util/typed-array.js +289 -0
  162. package/dist/src/util/typed-array.js.map +1 -0
  163. package/dist/src/wire/bytes.d.ts +69 -0
  164. package/dist/src/wire/bytes.d.ts.map +1 -0
  165. package/dist/src/wire/bytes.js +361 -0
  166. package/dist/src/wire/bytes.js.map +1 -0
  167. package/dist/src/wire/carried-views.d.ts +111 -0
  168. package/dist/src/wire/carried-views.d.ts.map +1 -0
  169. package/dist/src/wire/carried-views.js +286 -0
  170. package/dist/src/wire/carried-views.js.map +1 -0
  171. package/dist/src/wire/from-wire.d.ts +144 -0
  172. package/dist/src/wire/from-wire.d.ts.map +1 -0
  173. package/dist/src/wire/from-wire.js +1425 -0
  174. package/dist/src/wire/from-wire.js.map +1 -0
  175. package/dist/src/wire/to-wire.d.ts +171 -0
  176. package/dist/src/wire/to-wire.d.ts.map +1 -0
  177. package/dist/src/wire/to-wire.js +652 -0
  178. package/dist/src/wire/to-wire.js.map +1 -0
  179. package/dist/tsconfig.build.tsbuildinfo +1 -0
  180. package/package.json +72 -7
  181. package/src/builder/arena.ts +192 -0
  182. package/src/builder/compact.ts +1811 -0
  183. package/src/builder/counting-sort.ts +506 -0
  184. package/src/builder/freeze.ts +689 -0
  185. package/src/builder/graph-builder.ts +2264 -0
  186. package/src/builder/options.ts +29 -0
  187. package/src/columns/bitmap.ts +196 -0
  188. package/src/columns/column.ts +2574 -0
  189. package/src/columns/dictionary.ts +114 -0
  190. package/src/columns/growable.ts +350 -0
  191. package/src/columns/infer.ts +285 -0
  192. package/src/columns/remap.ts +663 -0
  193. package/src/columns/table.ts +568 -0
  194. package/src/constants.ts +89 -0
  195. package/src/errors.ts +115 -0
  196. package/src/ids/edge-id-index.ts +179 -0
  197. package/src/ids/node-id-map.ts +1340 -0
  198. package/src/ids/string-store.ts +589 -0
  199. package/src/index.ts +139 -0
  200. package/src/lib-resizable-array-buffer.d.ts +34 -0
  201. package/src/populate/from-csr.ts +802 -0
  202. package/src/populate/from-edge-arrays.ts +257 -0
  203. package/src/populate/from-records.ts +536 -0
  204. package/src/snapshot/derived.ts +1486 -0
  205. package/src/snapshot/graph-meta.ts +167 -0
  206. package/src/snapshot/graph-snapshot.ts +1503 -0
  207. package/src/snapshot/hash.ts +241 -0
  208. package/src/snapshot/queries.ts +136 -0
  209. package/src/snapshot/validate.ts +1108 -0
  210. package/src/snapshot/views.ts +943 -0
  211. package/src/types/builder.ts +480 -0
  212. package/src/types/columns.ts +727 -0
  213. package/src/types/index.ts +14 -0
  214. package/src/types/internal.ts +195 -0
  215. package/src/types/snapshot.ts +886 -0
  216. package/src/types/wire.ts +207 -0
  217. package/src/util/mask.ts +89 -0
  218. package/src/util/options.ts +57 -0
  219. package/src/util/shared-buffers.ts +56 -0
  220. package/src/util/typed-array.ts +371 -0
  221. package/src/wire/bytes.ts +440 -0
  222. package/src/wire/carried-views.ts +327 -0
  223. package/src/wire/from-wire.ts +1690 -0
  224. package/src/wire/to-wire.ts +755 -0
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Low-level typed-array helpers shared by every module of @graphty/graph-format (design sections 5.7,
3
+ * 6.2, 9.5, 10.2 and 10.3): rounding and alignment arithmetic, arena segment layout, the 4-byte
4
+ * padding rules of I10, the u8 adoption predicate, the wire buffer-range check, per-dtype
5
+ * typed-array constructors, and the growth primitive of the builder staging (doubling into a
6
+ * resizable ArrayBuffer when the engine has one, allocate-and-copy doubling otherwise).
7
+ *
8
+ * Nothing here knows about graphs; everything is arithmetic over byte lengths and typed arrays.
9
+ */
10
+ import { type Dtype, type TypedArrayData, type U8, type U32 } from "../types/index.js";
11
+ /**
12
+ * Whether resizable ArrayBuffer is available, detected once at module load (design section 6.2). The
13
+ * growth helpers take it as their default; tests pass an explicit value to exercise both paths.
14
+ */
15
+ export declare const HAS_RESIZABLE_ARRAY_BUFFER: boolean;
16
+ /** Staging capacities are rounded up to this many elements (design section 6.2). */
17
+ export declare const STAGING_ELEMENT_GRANULE = 16;
18
+ /** Staging backing buffers are a multiple of this many bytes (design section 6.2). */
19
+ export declare const STAGING_BYTE_GRANULE = 64;
20
+ /**
21
+ * Virtual address space reserved (`maxByteLength`) for a fresh resizable staging buffer: 256 MiB, so
22
+ * a staging array grows in place without copying up to 64M u32 elements. Reservations are
23
+ * address-space only (pages are committed as the buffer grows), and a buffer that outgrows its
24
+ * reservation is reallocated with a doubled one, so the constant bounds the number of copies rather
25
+ * than the size of anything.
26
+ */
27
+ export declare const STAGING_RESERVE_BYTES: number;
28
+ /**
29
+ * Round `value` up to the next multiple of `multiple`. Written with `%`, not bit masks, because arc
30
+ * counts and byte lengths exceed 2^31 (invariant I3, design section 10.6).
31
+ * @param value - a non-negative integer
32
+ * @param multiple - a positive integer
33
+ * @returns the smallest multiple of `multiple` that is >= value
34
+ */
35
+ export declare function roundUp(value: number, multiple: number): number;
36
+ /**
37
+ * Pad a byte length to the next multiple of 4: the size of the padded u32 view of a u8 column and
38
+ * the rule every GPU-bound array satisfies (design sections 5.7 and 10.2).
39
+ * @param byteLength - a non-negative byte count
40
+ * @returns roundUp(byteLength, 4)
41
+ */
42
+ export declare function padTo4(byteLength: number): number;
43
+ /**
44
+ * The number of u32 words that span a byte range: ceil(byteLength / 4) (design section 10.2).
45
+ * @param byteLength - a non-negative byte count
46
+ * @returns the word count of the padded u32 view
47
+ */
48
+ export declare function paddedWordCount(byteLength: number): number;
49
+ /**
50
+ * Align a byte offset up to the next arena segment boundary (design section 10.3; 256 bytes, the
51
+ * WebGPU minStorageBufferOffsetAlignment default).
52
+ * @param byteOffset - a non-negative byte offset
53
+ * @param alignment - the alignment in bytes; defaults to ALIGNMENT (256)
54
+ * @returns roundUp(byteOffset, alignment)
55
+ */
56
+ export declare function alignUp(byteOffset: number, alignment?: number): number;
57
+ /**
58
+ * The result of laying out consecutive segments at aligned offsets (design section 10.3).
59
+ */
60
+ interface SegmentLayout {
61
+ /**
62
+ * One entry per input length: the segment's byte offset relative to the start of the arena, or null for
63
+ * a zero-length segment, which occupies nothing.
64
+ */
65
+ readonly offsets: readonly (number | null)[];
66
+ /** One entry per input length: offset + length, or null for a zero-length segment. */
67
+ readonly ends: readonly (number | null)[];
68
+ /** The end of the last non-empty segment; 0 when every segment is empty. No trailing padding is added. */
69
+ readonly byteLength: number;
70
+ /** The bytes spent on inter-segment padding. */
71
+ readonly padding: number;
72
+ }
73
+ /**
74
+ * Lay out segments back to back, each non-empty one starting at a multiple of `alignment`, in the
75
+ * given order (design section 10.3: hot to cold). Zero-length segments get a null offset and occupy
76
+ * nothing, which is how an absent `weights`, a zero-arc `colIdx` and an identity permutation stay out
77
+ * of the arena. For the worked example of section 10.3 (400,004 / 8,000,000 / 8,000,000 / 8,000,000 /
78
+ * 4,000,000) the offsets are 0 / 400,128 / 8,400,128 / 16,400,128 / 24,400,128 and the total is
79
+ * 28,400,128 with 124 bytes of padding.
80
+ * @param byteLengths - the unpadded byte length of every segment in arena order (0 = absent)
81
+ * @param alignment - the segment alignment in bytes; defaults to ALIGNMENT (256)
82
+ * @returns the offsets, ends, total byte length and padding of the layout
83
+ */
84
+ export declare function layoutSegments(byteLengths: readonly number[], alignment?: number): SegmentLayout;
85
+ /**
86
+ * The I10 predicate for a GPU-bound array: a view whose byteOffset and byteLength are both multiples
87
+ * of 4 (design section 10.2).
88
+ * @param view - any ArrayBufferView
89
+ * @returns true when both byteOffset and byteLength are multiples of 4
90
+ */
91
+ export declare function isFourByteAligned(view: ArrayBufferView): boolean;
92
+ /**
93
+ * The "plain ArrayBuffer" half of invariant I10 (decision D-SAB, design section 9.4): the view's
94
+ * buffer is an `ArrayBuffer` that is neither a `SharedArrayBuffer` nor resizable, so its bytes are a
95
+ * `BufferSource` for `GPUQueue.writeBuffer`, transferable, and of fixed length for the life of the
96
+ * snapshot (invariant I17).
97
+ * @param view - any ArrayBufferView
98
+ * @returns true when the buffer is a plain, fixed-length ArrayBuffer
99
+ */
100
+ export declare function isOverPlainBuffer(view: ArrayBufferView): boolean;
101
+ /**
102
+ * The u8 adoption predicate of design section 5.7: "a zero-copy padded Uint32Array view is
103
+ * constructible", i.e. `byteOffset % 4 === 0 && byteOffset + roundUp(byteLength, 4) <=
104
+ * buffer.byteLength`.
105
+ * @param data - the u8 array a column would adopt
106
+ * @returns true when paddedU32View(data) can be built without copying
107
+ */
108
+ export declare function canViewAsPaddedU32(data: U8): boolean;
109
+ /**
110
+ * The zero-copy Uint32Array of ceil(byteLength / 4) words over a u8 array's own byte range (design
111
+ * sections 5.7 and 10.2); the trailing lanes of the last word are whatever the buffer holds there.
112
+ * @param data - a u8 array satisfying canViewAsPaddedU32()
113
+ * @returns the padded u32 view; E_COLUMN_ALIGNMENT when the view is not constructible
114
+ */
115
+ export declare function paddedU32View(data: U8): U32;
116
+ /**
117
+ * Copy a u8 array into a fresh store over which the padded u32 view is constructible: a new
118
+ * ArrayBuffer of roundUp(length, 4) bytes viewed at offset 0 with the original length (design section
119
+ * 5.7, the `adopt: "copy"` path). The padding bytes are zero.
120
+ * @param data - the u8 array to copy
121
+ * @returns a new U8 of the same length whose store satisfies canViewAsPaddedU32()
122
+ */
123
+ export declare function copyToPaddedStore(data: U8): U8;
124
+ /**
125
+ * The dtypes whose storage is one flat typed array: the five numeric dtypes plus bool (packed u32
126
+ * words) and dict (u32 codes). string, list and json have offsets, children or JS values instead.
127
+ */
128
+ export type TypedDtype = Exclude<Dtype, "string" | "list" | "json">;
129
+ /**
130
+ * A typed-array class as the helpers use it: BYTES_PER_ELEMENT plus the (buffer, byteOffset, length)
131
+ * constructor. Every concrete typed-array constructor satisfies it with T fixed to its
132
+ * ArrayBuffer-parameterised instance type.
133
+ */
134
+ export interface TypedArrayCtor<T extends TypedArrayData> {
135
+ /** Bytes per element. */
136
+ readonly BYTES_PER_ELEMENT: number;
137
+ /**
138
+ * Construct a view of `length` elements over `buffer` starting at `byteOffset`.
139
+ * @param buffer - the backing buffer
140
+ * @param byteOffset - the start of the view in bytes
141
+ * @param length - the element count of the view
142
+ */
143
+ new (buffer: ArrayBuffer, byteOffset: number, length: number): T;
144
+ }
145
+ /**
146
+ * Throw E_UNSUPPORTED for a dtype value outside the union; the `default` branch of every dtype switch
147
+ * (design section 13.4) calls this so an unknown dtype coming from untrusted data fails loudly. Always
148
+ * throws.
149
+ * @param dtype - the value that reached the default branch
150
+ */
151
+ export declare function unsupportedDtype(dtype: never): never;
152
+ /**
153
+ * The typed-array class that stores a flat dtype (design section 5.1): Float32Array for f32,
154
+ * Float64Array for f64, Int32Array for i32, Uint8Array for u8, and Uint32Array for u32, for the packed
155
+ * words of bool and for the codes of dict.
156
+ * @param dtype - a flat dtype
157
+ * @returns the constructor; E_UNSUPPORTED for an unknown dtype
158
+ */
159
+ export declare function typedArrayCtorOf(dtype: TypedDtype): TypedArrayCtor<TypedArrayData>;
160
+ /**
161
+ * The next staging capacity, in elements, that holds at least `needed`: doubling from `current`,
162
+ * rounded up to STAGING_ELEMENT_GRANULE (design section 6.2). A capacity of 0 grows to the granule.
163
+ * @param current - the present capacity in elements
164
+ * @param needed - the minimum capacity required
165
+ * @returns the new capacity, >= needed, >= 2 * current, a multiple of 16
166
+ */
167
+ export declare function growCapacity(current: number, needed: number): number;
168
+ /**
169
+ * The byte length of a staging backing buffer for `capacity` elements of `bytesPerElement` bytes each:
170
+ * rounded up to STAGING_BYTE_GRANULE (design section 6.2). Because every element size divides 64 the
171
+ * result is always a whole number of elements.
172
+ * @param capacity - the capacity in elements
173
+ * @param bytesPerElement - the element size in bytes (1, 4 or 8)
174
+ * @returns the buffer byte length, a multiple of 64
175
+ */
176
+ export declare function stagingByteLength(capacity: number, bytesPerElement: number): number;
177
+ /**
178
+ * Allocate a staging buffer of `byteLength` bytes. With `resizable` true the buffer is created with a
179
+ * `maxByteLength` of at least `reserveBytes` (and at least `byteLength`) so it can later grow in place;
180
+ * should the engine refuse that reservation with a RangeError (an address-space limit, not a missing
181
+ * capability) the buffer is created resizable with `maxByteLength === byteLength`, which simply means
182
+ * its next growth reallocates. With `resizable` false a plain fixed-length buffer is returned.
183
+ * @param byteLength - the initial byte length
184
+ * @param resizable - whether to create a resizable buffer; defaults to HAS_RESIZABLE_ARRAY_BUFFER
185
+ * @param reserveBytes - the address space to reserve for in-place growth; defaults to STAGING_RESERVE_BYTES
186
+ * @returns the new buffer
187
+ */
188
+ export declare function allocateStagingBuffer(byteLength: number, resizable?: boolean, reserveBytes?: number): ArrayBuffer;
189
+ /**
190
+ * Grow a staging array so it holds at least `minLength` elements, preserving its contents (design
191
+ * section 6.2). When the array is the leading view of a resizable buffer with room left, the buffer is
192
+ * resized in place and no bytes move; otherwise a new buffer is allocated (resizable per `resizable`,
193
+ * with a reservation of at least twice the old one so repeated overflow stays amortised) and the
194
+ * contents copied. Either way the returned array is a fresh view object of exactly the new capacity;
195
+ * the caller replaces its reference. Elements beyond the old length are zero on the copy path and on a
196
+ * freshly resized region.
197
+ * @param array - the current staging array, viewed from byteOffset 0 of its buffer
198
+ * @param ctor - the array's constructor
199
+ * @param minLength - the minimum element count required
200
+ * @param resizable - whether new buffers are resizable; defaults to HAS_RESIZABLE_ARRAY_BUFFER
201
+ * @returns a view of growCapacity(array.length, minLength) elements holding the old contents
202
+ */
203
+ export declare function growTypedArray<T extends TypedArrayData>(array: T, ctor: TypedArrayCtor<T>, minLength: number, resizable?: boolean): T;
204
+ export {};
205
+ //# sourceMappingURL=typed-array.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typed-array.d.ts","sourceRoot":"","sources":["../../../src/util/typed-array.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,289 @@
1
+ /**
2
+ * Low-level typed-array helpers shared by every module of @graphty/graph-format (design sections 5.7,
3
+ * 6.2, 9.5, 10.2 and 10.3): rounding and alignment arithmetic, arena segment layout, the 4-byte
4
+ * padding rules of I10, the u8 adoption predicate, the wire buffer-range check, per-dtype
5
+ * typed-array constructors, and the growth primitive of the builder staging (doubling into a
6
+ * resizable ArrayBuffer when the engine has one, allocate-and-copy doubling otherwise).
7
+ *
8
+ * Nothing here knows about graphs; everything is arithmetic over byte lengths and typed arrays.
9
+ */
10
+ import { ALIGNMENT } from "../constants.js";
11
+ import { GraphFormatError } from "../errors.js";
12
+ // ============================================================ resizable ArrayBuffer detection
13
+ /**
14
+ * Probe once whether this engine supports resizable ArrayBuffer (ES2024: Node 20+, Chrome 111+,
15
+ * Safari 16.4+, Firefox 128+). The probe constructs a tiny resizable buffer and grows it; any throw or
16
+ * missing member means "not supported", in which case staging grows by allocate-and-copy (design
17
+ * section 6.2).
18
+ * @returns true when `new ArrayBuffer(n, { maxByteLength })` and `resize()` work
19
+ */
20
+ function detectResizableArrayBuffer() {
21
+ try {
22
+ const probe = new ArrayBuffer(0, { maxByteLength: 64 });
23
+ if (!probe.resizable || typeof probe.resize !== "function") {
24
+ return false;
25
+ }
26
+ probe.resize(64);
27
+ return probe.byteLength === 64 && probe.maxByteLength === 64;
28
+ }
29
+ catch {
30
+ return false;
31
+ }
32
+ }
33
+ /**
34
+ * Whether resizable ArrayBuffer is available, detected once at module load (design section 6.2). The
35
+ * growth helpers take it as their default; tests pass an explicit value to exercise both paths.
36
+ */
37
+ export const HAS_RESIZABLE_ARRAY_BUFFER = detectResizableArrayBuffer();
38
+ // ============================================================ staging growth constants
39
+ /** Staging capacities are rounded up to this many elements (design section 6.2). */
40
+ export const STAGING_ELEMENT_GRANULE = 16;
41
+ /** Staging backing buffers are a multiple of this many bytes (design section 6.2). */
42
+ export const STAGING_BYTE_GRANULE = 64;
43
+ /**
44
+ * Virtual address space reserved (`maxByteLength`) for a fresh resizable staging buffer: 256 MiB, so
45
+ * a staging array grows in place without copying up to 64M u32 elements. Reservations are
46
+ * address-space only (pages are committed as the buffer grows), and a buffer that outgrows its
47
+ * reservation is reallocated with a doubled one, so the constant bounds the number of copies rather
48
+ * than the size of anything.
49
+ */
50
+ export const STAGING_RESERVE_BYTES = 256 * 1024 * 1024;
51
+ // ============================================================ rounding and alignment
52
+ /**
53
+ * Round `value` up to the next multiple of `multiple`. Written with `%`, not bit masks, because arc
54
+ * counts and byte lengths exceed 2^31 (invariant I3, design section 10.6).
55
+ * @param value - a non-negative integer
56
+ * @param multiple - a positive integer
57
+ * @returns the smallest multiple of `multiple` that is >= value
58
+ */
59
+ export function roundUp(value, multiple) {
60
+ const remainder = value % multiple;
61
+ return remainder === 0 ? value : value + multiple - remainder;
62
+ }
63
+ /**
64
+ * Pad a byte length to the next multiple of 4: the size of the padded u32 view of a u8 column and
65
+ * the rule every GPU-bound array satisfies (design sections 5.7 and 10.2).
66
+ * @param byteLength - a non-negative byte count
67
+ * @returns roundUp(byteLength, 4)
68
+ */
69
+ export function padTo4(byteLength) {
70
+ return roundUp(byteLength, 4);
71
+ }
72
+ /**
73
+ * The number of u32 words that span a byte range: ceil(byteLength / 4) (design section 10.2).
74
+ * @param byteLength - a non-negative byte count
75
+ * @returns the word count of the padded u32 view
76
+ */
77
+ export function paddedWordCount(byteLength) {
78
+ return Math.ceil(byteLength / 4);
79
+ }
80
+ /**
81
+ * Align a byte offset up to the next arena segment boundary (design section 10.3; 256 bytes, the
82
+ * WebGPU minStorageBufferOffsetAlignment default).
83
+ * @param byteOffset - a non-negative byte offset
84
+ * @param alignment - the alignment in bytes; defaults to ALIGNMENT (256)
85
+ * @returns roundUp(byteOffset, alignment)
86
+ */
87
+ export function alignUp(byteOffset, alignment = ALIGNMENT) {
88
+ return roundUp(byteOffset, alignment);
89
+ }
90
+ /**
91
+ * Lay out segments back to back, each non-empty one starting at a multiple of `alignment`, in the
92
+ * given order (design section 10.3: hot to cold). Zero-length segments get a null offset and occupy
93
+ * nothing, which is how an absent `weights`, a zero-arc `colIdx` and an identity permutation stay out
94
+ * of the arena. For the worked example of section 10.3 (400,004 / 8,000,000 / 8,000,000 / 8,000,000 /
95
+ * 4,000,000) the offsets are 0 / 400,128 / 8,400,128 / 16,400,128 / 24,400,128 and the total is
96
+ * 28,400,128 with 124 bytes of padding.
97
+ * @param byteLengths - the unpadded byte length of every segment in arena order (0 = absent)
98
+ * @param alignment - the segment alignment in bytes; defaults to ALIGNMENT (256)
99
+ * @returns the offsets, ends, total byte length and padding of the layout
100
+ */
101
+ export function layoutSegments(byteLengths, alignment = ALIGNMENT) {
102
+ const offsets = [];
103
+ const ends = [];
104
+ let cursor = 0;
105
+ let padding = 0;
106
+ for (const byteLength of byteLengths) {
107
+ if (byteLength === 0) {
108
+ offsets.push(null);
109
+ ends.push(null);
110
+ continue;
111
+ }
112
+ const offset = alignUp(cursor, alignment);
113
+ padding += offset - cursor;
114
+ offsets.push(offset);
115
+ cursor = offset + byteLength;
116
+ ends.push(cursor);
117
+ }
118
+ return { offsets, ends, byteLength: cursor, padding };
119
+ }
120
+ // ============================================================ 4-byte rules and adoption (I10, 5.7)
121
+ /**
122
+ * The I10 predicate for a GPU-bound array: a view whose byteOffset and byteLength are both multiples
123
+ * of 4 (design section 10.2).
124
+ * @param view - any ArrayBufferView
125
+ * @returns true when both byteOffset and byteLength are multiples of 4
126
+ */
127
+ export function isFourByteAligned(view) {
128
+ return view.byteOffset % 4 === 0 && view.byteLength % 4 === 0;
129
+ }
130
+ /**
131
+ * The "plain ArrayBuffer" half of invariant I10 (decision D-SAB, design section 9.4): the view's
132
+ * buffer is an `ArrayBuffer` that is neither a `SharedArrayBuffer` nor resizable, so its bytes are a
133
+ * `BufferSource` for `GPUQueue.writeBuffer`, transferable, and of fixed length for the life of the
134
+ * snapshot (invariant I17).
135
+ * @param view - any ArrayBufferView
136
+ * @returns true when the buffer is a plain, fixed-length ArrayBuffer
137
+ */
138
+ export function isOverPlainBuffer(view) {
139
+ const { buffer } = view;
140
+ return buffer instanceof ArrayBuffer && !buffer.resizable;
141
+ }
142
+ /**
143
+ * The u8 adoption predicate of design section 5.7: "a zero-copy padded Uint32Array view is
144
+ * constructible", i.e. `byteOffset % 4 === 0 && byteOffset + roundUp(byteLength, 4) <=
145
+ * buffer.byteLength`.
146
+ * @param data - the u8 array a column would adopt
147
+ * @returns true when paddedU32View(data) can be built without copying
148
+ */
149
+ export function canViewAsPaddedU32(data) {
150
+ return data.byteOffset % 4 === 0 && data.byteOffset + padTo4(data.byteLength) <= data.buffer.byteLength;
151
+ }
152
+ /**
153
+ * The zero-copy Uint32Array of ceil(byteLength / 4) words over a u8 array's own byte range (design
154
+ * sections 5.7 and 10.2); the trailing lanes of the last word are whatever the buffer holds there.
155
+ * @param data - a u8 array satisfying canViewAsPaddedU32()
156
+ * @returns the padded u32 view; E_COLUMN_ALIGNMENT when the view is not constructible
157
+ */
158
+ export function paddedU32View(data) {
159
+ if (!canViewAsPaddedU32(data)) {
160
+ throw new GraphFormatError("E_COLUMN_ALIGNMENT", `u8 array at byteOffset ${data.byteOffset} with byteLength ${data.byteLength} has no zero-copy padded u32 view`, { byteOffset: data.byteOffset, byteLength: data.byteLength, bufferByteLength: data.buffer.byteLength });
161
+ }
162
+ return new Uint32Array(data.buffer, data.byteOffset, paddedWordCount(data.byteLength));
163
+ }
164
+ /**
165
+ * Copy a u8 array into a fresh store over which the padded u32 view is constructible: a new
166
+ * ArrayBuffer of roundUp(length, 4) bytes viewed at offset 0 with the original length (design section
167
+ * 5.7, the `adopt: "copy"` path). The padding bytes are zero.
168
+ * @param data - the u8 array to copy
169
+ * @returns a new U8 of the same length whose store satisfies canViewAsPaddedU32()
170
+ */
171
+ export function copyToPaddedStore(data) {
172
+ const store = new Uint8Array(new ArrayBuffer(padTo4(data.byteLength)), 0, data.byteLength);
173
+ store.set(data);
174
+ return store;
175
+ }
176
+ /**
177
+ * Throw E_UNSUPPORTED for a dtype value outside the union; the `default` branch of every dtype switch
178
+ * (design section 13.4) calls this so an unknown dtype coming from untrusted data fails loudly. Always
179
+ * throws.
180
+ * @param dtype - the value that reached the default branch
181
+ */
182
+ export function unsupportedDtype(dtype) {
183
+ throw new GraphFormatError("E_UNSUPPORTED", `unsupported dtype ${String(dtype)}`, { dtype });
184
+ }
185
+ /**
186
+ * The typed-array class that stores a flat dtype (design section 5.1): Float32Array for f32,
187
+ * Float64Array for f64, Int32Array for i32, Uint8Array for u8, and Uint32Array for u32, for the packed
188
+ * words of bool and for the codes of dict.
189
+ * @param dtype - a flat dtype
190
+ * @returns the constructor; E_UNSUPPORTED for an unknown dtype
191
+ */
192
+ export function typedArrayCtorOf(dtype) {
193
+ switch (dtype) {
194
+ case "f32":
195
+ return Float32Array;
196
+ case "f64":
197
+ return Float64Array;
198
+ case "i32":
199
+ return Int32Array;
200
+ case "u8":
201
+ return Uint8Array;
202
+ case "u32":
203
+ case "bool":
204
+ case "dict":
205
+ return Uint32Array;
206
+ default:
207
+ return unsupportedDtype(dtype);
208
+ }
209
+ }
210
+ // ============================================================ staging growth
211
+ /**
212
+ * The next staging capacity, in elements, that holds at least `needed`: doubling from `current`,
213
+ * rounded up to STAGING_ELEMENT_GRANULE (design section 6.2). A capacity of 0 grows to the granule.
214
+ * @param current - the present capacity in elements
215
+ * @param needed - the minimum capacity required
216
+ * @returns the new capacity, >= needed, >= 2 * current, a multiple of 16
217
+ */
218
+ export function growCapacity(current, needed) {
219
+ return roundUp(Math.max(needed, current * 2, STAGING_ELEMENT_GRANULE), STAGING_ELEMENT_GRANULE);
220
+ }
221
+ /**
222
+ * The byte length of a staging backing buffer for `capacity` elements of `bytesPerElement` bytes each:
223
+ * rounded up to STAGING_BYTE_GRANULE (design section 6.2). Because every element size divides 64 the
224
+ * result is always a whole number of elements.
225
+ * @param capacity - the capacity in elements
226
+ * @param bytesPerElement - the element size in bytes (1, 4 or 8)
227
+ * @returns the buffer byte length, a multiple of 64
228
+ */
229
+ export function stagingByteLength(capacity, bytesPerElement) {
230
+ return roundUp(capacity * bytesPerElement, STAGING_BYTE_GRANULE);
231
+ }
232
+ /**
233
+ * Allocate a staging buffer of `byteLength` bytes. With `resizable` true the buffer is created with a
234
+ * `maxByteLength` of at least `reserveBytes` (and at least `byteLength`) so it can later grow in place;
235
+ * should the engine refuse that reservation with a RangeError (an address-space limit, not a missing
236
+ * capability) the buffer is created resizable with `maxByteLength === byteLength`, which simply means
237
+ * its next growth reallocates. With `resizable` false a plain fixed-length buffer is returned.
238
+ * @param byteLength - the initial byte length
239
+ * @param resizable - whether to create a resizable buffer; defaults to HAS_RESIZABLE_ARRAY_BUFFER
240
+ * @param reserveBytes - the address space to reserve for in-place growth; defaults to STAGING_RESERVE_BYTES
241
+ * @returns the new buffer
242
+ */
243
+ export function allocateStagingBuffer(byteLength, resizable = HAS_RESIZABLE_ARRAY_BUFFER, reserveBytes = STAGING_RESERVE_BYTES) {
244
+ if (!resizable) {
245
+ return new ArrayBuffer(byteLength);
246
+ }
247
+ const maxByteLength = Math.max(byteLength, reserveBytes);
248
+ try {
249
+ return new ArrayBuffer(byteLength, { maxByteLength });
250
+ }
251
+ catch (err) {
252
+ if (err instanceof RangeError && maxByteLength > byteLength) {
253
+ return new ArrayBuffer(byteLength, { maxByteLength: byteLength });
254
+ }
255
+ throw err;
256
+ }
257
+ }
258
+ /**
259
+ * Grow a staging array so it holds at least `minLength` elements, preserving its contents (design
260
+ * section 6.2). When the array is the leading view of a resizable buffer with room left, the buffer is
261
+ * resized in place and no bytes move; otherwise a new buffer is allocated (resizable per `resizable`,
262
+ * with a reservation of at least twice the old one so repeated overflow stays amortised) and the
263
+ * contents copied. Either way the returned array is a fresh view object of exactly the new capacity;
264
+ * the caller replaces its reference. Elements beyond the old length are zero on the copy path and on a
265
+ * freshly resized region.
266
+ * @param array - the current staging array, viewed from byteOffset 0 of its buffer
267
+ * @param ctor - the array's constructor
268
+ * @param minLength - the minimum element count required
269
+ * @param resizable - whether new buffers are resizable; defaults to HAS_RESIZABLE_ARRAY_BUFFER
270
+ * @returns a view of growCapacity(array.length, minLength) elements holding the old contents
271
+ */
272
+ export function growTypedArray(array, ctor, minLength, resizable = HAS_RESIZABLE_ARRAY_BUFFER) {
273
+ if (minLength <= array.length) {
274
+ return array;
275
+ }
276
+ const bytesPerElement = ctor.BYTES_PER_ELEMENT;
277
+ const byteLength = stagingByteLength(growCapacity(array.length, minLength), bytesPerElement);
278
+ const capacity = byteLength / bytesPerElement;
279
+ const { buffer } = array;
280
+ if (buffer.resizable && array.byteOffset === 0 && byteLength <= buffer.maxByteLength) {
281
+ buffer.resize(byteLength);
282
+ return new ctor(buffer, 0, capacity);
283
+ }
284
+ const reserve = Math.max(buffer.maxByteLength * 2, STAGING_RESERVE_BYTES);
285
+ const next = new ctor(allocateStagingBuffer(byteLength, resizable, reserve), 0, capacity);
286
+ next.set(array);
287
+ return next;
288
+ }
289
+ //# sourceMappingURL=typed-array.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typed-array.js","sourceRoot":"","sources":["../../../src/util/typed-array.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * The GSNP byte container (design section 9.2): `toBytes()` writes one contiguous buffer,
3
+ * `toByteChunks()` the same bytes as a sequence (header + manifest, then every 256-padded segment
4
+ * in manifest order), `fromBytes()` adopts a container's buffer region as the arena and
5
+ * `fromByteChunks()` adopts each chunk's buffer per segment. The snapshot's `toBytes` /
6
+ * `toByteChunks` methods call the functions of this module directly.
7
+ *
8
+ * Layout, all integers little-endian:
9
+ *
10
+ * ```
11
+ * offset size field
12
+ * 0 4 magic "GSNP"
13
+ * 4 2 wire major (u16)
14
+ * 6 2 wire minor (u16)
15
+ * 8 4 endianness probe: 0x01020304 written through a host-order Uint32Array
16
+ * 12 4 manifest byte length L (u32)
17
+ * 16 L manifest: UTF-8 JSON of the WireManifest, every reference into buffer 0 with a
18
+ * region-relative byteOffset
19
+ * 16+L pad zero padding to the next multiple of 256
20
+ * B ... buffer region: each array at a 256-aligned offset in manifest order, core arrays
21
+ * first so the region's prefix is the arena; every segment padded to 256 bytes
22
+ * ```
23
+ *
24
+ * The reader refuses a bad magic, an unexpected probe, a truncated header or manifest, a manifest
25
+ * whose versions disagree with the header (E_BAD_SERIALIZATION), an unknown wire major
26
+ * (E_UNSUPPORTED_VERSION) and everything the manifest reader of from-wire.ts refuses.
27
+ */
28
+ import { type GraphSnapshot } from "../snapshot/graph-snapshot.js";
29
+ import { type FromWireOptions, type ToBytesOptions, type U8 } from "../types/index.js";
30
+ /** Bytes before the manifest: magic, major, minor, probe and manifest length. */
31
+ export declare const CONTAINER_HEADER_BYTES = 16;
32
+ /**
33
+ * The GSNP container of a snapshot as one contiguous buffer (design section 9.2).
34
+ * @param snapshot - the snapshot
35
+ * @param options - the cached views to carry
36
+ * @returns the container bytes at offset 0 of a fresh ArrayBuffer; E_UNSUPPORTED on a big-endian host
37
+ */
38
+ export declare function toBytes(snapshot: GraphSnapshot, options?: ToBytesOptions): U8;
39
+ /**
40
+ * The GSNP container as a sequence of chunks whose concatenation equals `toBytes()` (design section
41
+ * 9.2): the header + manifest padded to 256, then each non-empty segment padded to 256, in manifest
42
+ * order. The layout is computed when this function is called; the chunk copies are made lazily.
43
+ * @param snapshot - the snapshot
44
+ * @param options - the cached views to carry
45
+ * @returns the chunks; E_UNSUPPORTED on a big-endian host
46
+ */
47
+ export declare function toByteChunks(snapshot: GraphSnapshot, options?: ToBytesOptions): Iterable<U8>;
48
+ /**
49
+ * Rebuild a snapshot from a GSNP container (design section 9.2). Defaults: `validate: "full"` and
50
+ * `copy: false`. The buffer region is adopted as the arena when the container is a plain
51
+ * ArrayBuffer viewed at a byteOffset that is a multiple of 8 (so f64 segments align); a
52
+ * SharedArrayBuffer, an odd offset or `copy: true` take the copy path into a fresh 256-aligned
53
+ * buffer.
54
+ * @param bytes - the container: a Uint8Array, an ArrayBuffer or a SharedArrayBuffer
55
+ * @param options - validation level, copy and unknown-column policy
56
+ * @returns the snapshot; E_BAD_SERIALIZATION / E_UNSUPPORTED_VERSION / E_UNSUPPORTED / E_INVALID_SNAPSHOT on bad input
57
+ */
58
+ export declare function fromBytes(bytes: Uint8Array | ArrayBufferLike, options?: FromWireOptions): GraphSnapshot;
59
+ /**
60
+ * Rebuild a snapshot from the chunks `toByteChunks()` produced (or any split of a container's
61
+ * bytes): each segment is adopted as a view into the chunk that holds it (a segment spanning two
62
+ * chunks, or one in a SharedArrayBuffer, is copied) and the snapshot has `arena === null` (design
63
+ * section 9.2). Defaults: `validate: "full"`, `copy: false`.
64
+ * @param chunks - the chunks in order
65
+ * @param options - validation level, copy and unknown-column policy
66
+ * @returns the snapshot
67
+ */
68
+ export declare function fromByteChunks(chunks: Iterable<Uint8Array>, options?: FromWireOptions): GraphSnapshot;
69
+ //# sourceMappingURL=bytes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bytes.d.ts","sourceRoot":"","sources":["../../../src/wire/bytes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAIH,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAuB,KAAK,EAAE,EAAE,MAAM,mBAAmB,CAAC;AAiB5G,iFAAiF;AACjF,eAAO,MAAM,sBAAsB,KAAK,CAAC;AA2DzC;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,aAAa,EAAE,OAAO,GAAE,cAAmB,GAAG,EAAE,CASjF;AAuBD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,aAAa,EAAE,OAAO,GAAE,cAAmB,GAAG,QAAQ,CAAC,EAAE,CAAC,CAEhG;AAuGD;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,eAAe,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,aAAa,CAsBvG;AA6HD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,aAAa,CAcrG"}