usertrust 1.5.0 → 2.0.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 (115) hide show
  1. package/README.md +17 -1
  2. package/dist/anomaly/detector.js.map +1 -1
  3. package/dist/anomaly/index.d.ts +2 -2
  4. package/dist/anomaly/index.d.ts.map +1 -1
  5. package/dist/anomaly/index.js +1 -1
  6. package/dist/anomaly/index.js.map +1 -1
  7. package/dist/audit/anchor-doctor.d.ts +42 -0
  8. package/dist/audit/anchor-doctor.d.ts.map +1 -0
  9. package/dist/audit/anchor-doctor.js +285 -0
  10. package/dist/audit/anchor-doctor.js.map +1 -0
  11. package/dist/audit/anchor-verify.d.ts +229 -0
  12. package/dist/audit/anchor-verify.d.ts.map +1 -0
  13. package/dist/audit/anchor-verify.js +809 -0
  14. package/dist/audit/anchor-verify.js.map +1 -0
  15. package/dist/audit/anchor.d.ts +177 -0
  16. package/dist/audit/anchor.d.ts.map +1 -0
  17. package/dist/audit/anchor.js +922 -0
  18. package/dist/audit/anchor.js.map +1 -0
  19. package/dist/audit/canonical.js +1 -1
  20. package/dist/audit/canonical.js.map +1 -1
  21. package/dist/audit/chain.d.ts.map +1 -1
  22. package/dist/audit/chain.js +21 -7
  23. package/dist/audit/chain.js.map +1 -1
  24. package/dist/audit/read.d.ts +19 -0
  25. package/dist/audit/read.d.ts.map +1 -0
  26. package/dist/audit/read.js +94 -0
  27. package/dist/audit/read.js.map +1 -0
  28. package/dist/audit/rekor-verify.d.ts +116 -0
  29. package/dist/audit/rekor-verify.d.ts.map +1 -0
  30. package/dist/audit/rekor-verify.js +533 -0
  31. package/dist/audit/rekor-verify.js.map +1 -0
  32. package/dist/audit/rekor.d.ts +71 -0
  33. package/dist/audit/rekor.d.ts.map +1 -0
  34. package/dist/audit/rekor.js +556 -0
  35. package/dist/audit/rekor.js.map +1 -0
  36. package/dist/audit/rotation.js +1 -1
  37. package/dist/audit/rotation.js.map +1 -1
  38. package/dist/audit/sigv4.d.ts +44 -0
  39. package/dist/audit/sigv4.d.ts.map +1 -0
  40. package/dist/audit/sigv4.js +134 -0
  41. package/dist/audit/sigv4.js.map +1 -0
  42. package/dist/audit/verify.d.ts +78 -0
  43. package/dist/audit/verify.d.ts.map +1 -1
  44. package/dist/audit/verify.js +195 -1
  45. package/dist/audit/verify.js.map +1 -1
  46. package/dist/cli/anchor.d.ts +3 -0
  47. package/dist/cli/anchor.d.ts.map +1 -0
  48. package/dist/cli/anchor.js +626 -0
  49. package/dist/cli/anchor.js.map +1 -0
  50. package/dist/cli/completions.js +1 -1
  51. package/dist/cli/export.d.ts +3 -0
  52. package/dist/cli/export.d.ts.map +1 -0
  53. package/dist/cli/export.js +58 -0
  54. package/dist/cli/export.js.map +1 -0
  55. package/dist/cli/health.js.map +1 -1
  56. package/dist/cli/init.js +1 -1
  57. package/dist/cli/init.js.map +1 -1
  58. package/dist/cli/inspect.d.ts.map +1 -1
  59. package/dist/cli/inspect.js +4 -34
  60. package/dist/cli/inspect.js.map +1 -1
  61. package/dist/cli/main.d.ts +2 -2
  62. package/dist/cli/main.d.ts.map +1 -1
  63. package/dist/cli/main.js +20 -1
  64. package/dist/cli/main.js.map +1 -1
  65. package/dist/cli/pricing.js +1 -1
  66. package/dist/cli/pricing.js.map +1 -1
  67. package/dist/cli/ui.d.ts +3 -0
  68. package/dist/cli/ui.d.ts.map +1 -0
  69. package/dist/cli/ui.js +35 -0
  70. package/dist/cli/ui.js.map +1 -0
  71. package/dist/cli/verify.d.ts.map +1 -1
  72. package/dist/cli/verify.js +342 -3
  73. package/dist/cli/verify.js.map +1 -1
  74. package/dist/config.d.ts.map +1 -1
  75. package/dist/config.js.map +1 -1
  76. package/dist/detect.d.ts +37 -15
  77. package/dist/detect.d.ts.map +1 -1
  78. package/dist/detect.js +17 -6
  79. package/dist/detect.js.map +1 -1
  80. package/dist/export/markdown.d.ts +12 -0
  81. package/dist/export/markdown.d.ts.map +1 -0
  82. package/dist/export/markdown.js +142 -0
  83. package/dist/export/markdown.js.map +1 -0
  84. package/dist/govern.d.ts +60 -3
  85. package/dist/govern.d.ts.map +1 -1
  86. package/dist/govern.js +842 -229
  87. package/dist/govern.js.map +1 -1
  88. package/dist/headless.d.ts.map +1 -1
  89. package/dist/headless.js +4 -4
  90. package/dist/headless.js.map +1 -1
  91. package/dist/index.d.ts +33 -26
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +30 -25
  94. package/dist/index.js.map +1 -1
  95. package/dist/ledger/client.d.ts.map +1 -1
  96. package/dist/ledger/client.js +57 -46
  97. package/dist/ledger/client.js.map +1 -1
  98. package/dist/ledger/engine.d.ts.map +1 -1
  99. package/dist/ledger/engine.js +22 -13
  100. package/dist/ledger/engine.js.map +1 -1
  101. package/dist/shared/types.d.ts +114 -475
  102. package/dist/shared/types.d.ts.map +1 -1
  103. package/dist/shared/types.js +13 -13
  104. package/dist/shared/types.js.map +1 -1
  105. package/dist/snapshot/checkpoint.d.ts.map +1 -1
  106. package/dist/snapshot/checkpoint.js +20 -2
  107. package/dist/snapshot/checkpoint.js.map +1 -1
  108. package/dist/streaming.d.ts +9 -4
  109. package/dist/streaming.d.ts.map +1 -1
  110. package/dist/streaming.js +27 -0
  111. package/dist/streaming.js.map +1 -1
  112. package/dist/supply-chain/sign.d.ts.map +1 -1
  113. package/dist/supply-chain/sign.js +3 -0
  114. package/dist/supply-chain/sign.js.map +1 -1
  115. package/package.json +6 -4
@@ -0,0 +1,556 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright 2026 Usertools, Inc.
3
+ /**
4
+ * Witness sinks: S3 (native SigV4) and Rekor (hashedrekord transparency log).
5
+ *
6
+ * Both are AnchorSinks, so both inherit the emitter's contract: a publish that
7
+ * resolves means the record was DURABLY accepted, and a publish that rejects
8
+ * keeps the record in the outbox for redelivery. Everything here therefore
9
+ * fails closed — a sink that resolved on a response it did not fully understand
10
+ * would silently drop a record out of the append-only store, which is precisely
11
+ * the evidence loss anchoring exists to prevent.
12
+ *
13
+ * What Rekor witnesses is deliberately thin (spec §3, delta D14): the entry
14
+ * carries sha256 of the anchor payload, the record's signature, and the vault's
15
+ * public key — never event data, never the payload itself. The receipt lives in
16
+ * its own file because the anchor record schema is FROZEN; a transparency log
17
+ * must not become a field inside the thing it witnesses.
18
+ *
19
+ * EXPERIMENTAL: the Rekor path is exercised against synthetic responses only —
20
+ * the live API is untested in CI, and the entry `apiVersion` is pinned to
21
+ * 0.0.1.
22
+ *
23
+ * Network access is confined to `httpTransport` at the bottom of this file;
24
+ * every other function is pure or writes to the vault, so tests inject a
25
+ * transport and assert on bytes.
26
+ */
27
+ import { createHash } from "node:crypto";
28
+ import { closeSync, fsyncSync, mkdirSync, openSync, readdirSync, readFileSync, writeSync, } from "node:fs";
29
+ import { join } from "node:path";
30
+ // Cyclic by design: anchor.ts builds these sinks from SinkConfig, and the Rekor
31
+ // sink needs the vault's identity + anchors directory. Both bindings are
32
+ // function declarations used only at publish time, so the cycle never observes
33
+ // a partially initialized module.
34
+ import { anchorsDir, readAnchorIdentity } from "./anchor.js";
35
+ import { anchorPayloadHash } from "./anchor-verify.js";
36
+ import { canonicalize } from "./canonical.js";
37
+ import { parseRekorReceipt } from "./rekor-verify.js";
38
+ import { sigV4Headers } from "./sigv4.js";
39
+ export const DEFAULT_REKOR_URL = "https://rekor.sigstore.dev";
40
+ const REKOR_ENTRIES_PATH = "/api/v1/log/entries";
41
+ /** Rekor's hashedrekord schema version. Pinned: 0.0.2+ changes the spec shape. */
42
+ const HASHEDREKORD_API_VERSION = "0.0.1";
43
+ const HEX64 = /^[0-9a-f]{64}$/;
44
+ const BASE64 = /^[A-Za-z0-9+/]*={0,2}$/;
45
+ const MAX_ENTRY_BODY_BYTES = 64 * 1024;
46
+ const MAX_CHECKPOINT_BYTES = 8 * 1024;
47
+ const MAX_INCLUSION_PATH = 64;
48
+ const MAX_SET_BYTES = 1024;
49
+ /** Matches the receipt parser's bound: `* 1000` must stay a valid Date. */
50
+ const MAX_INTEGRATED_TIME = 8_640_000_000_000;
51
+ // ── Shared helpers ──
52
+ const is2xx = (status) => status >= 200 && status < 300;
53
+ /**
54
+ * A store's response body on its way into an error message. Anything that looks
55
+ * like a signed header is dropped: a hostile or misconfigured endpoint can echo
56
+ * our request back, and an error string ends up in logs and issue trackers
57
+ * (delta D6). Truncated to 120 characters — the status code carries the meaning.
58
+ */
59
+ function snippet(body) {
60
+ if (body === "")
61
+ return "";
62
+ const scrubbed = body
63
+ .replace(/authorization[^\n]*/gi, "[redacted]")
64
+ .replace(/x-amz-security-token[^\n]*/gi, "[redacted]")
65
+ .replace(/AWS4-HMAC-SHA256[^\n]*/g, "[redacted]")
66
+ .replace(/\s+/g, " ")
67
+ .trim();
68
+ return scrubbed === "" ? "" : `: ${scrubbed.slice(0, 120)}`;
69
+ }
70
+ const seq12 = (anchorSeq) => String(anchorSeq).padStart(12, "0");
71
+ /** `YYYYMMDDTHHMMSSZ` for SigV4. */
72
+ function amzDate() {
73
+ return `${new Date().toISOString().replace(/[-:]/g, "").slice(0, 15)}Z`;
74
+ }
75
+ function credentialsFromEnv() {
76
+ const accessKeyId = process.env.AWS_ACCESS_KEY_ID;
77
+ const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
78
+ if (!accessKeyId || !secretAccessKey)
79
+ return null;
80
+ const sessionToken = process.env.AWS_SESSION_TOKEN;
81
+ return { accessKeyId, secretAccessKey, ...(sessionToken ? { sessionToken } : {}) };
82
+ }
83
+ // ── S3 sink ──
84
+ /**
85
+ * Endpoint rule for BOTH sinks. Plaintext is refused off-loopback: for S3,
86
+ * SigV4 authenticates the request but does not encrypt it, so an http endpoint
87
+ * on the network would put the credential-bearing headers on the wire; for
88
+ * Rekor, an http log URL lets anyone on the path answer for the witness — and
89
+ * a sink that accepts a forged 201 files forged evidence. Loopback is allowed
90
+ * for dev MinIO/LocalStack and local log instances.
91
+ */
92
+ export function parseEndpoint(endpoint, sinkName = "s3 sink") {
93
+ let url;
94
+ try {
95
+ url = new URL(endpoint);
96
+ }
97
+ catch {
98
+ throw new Error(`${sinkName}: endpoint must include a scheme, got "${endpoint.slice(0, 60)}"`);
99
+ }
100
+ const loopback = url.hostname === "localhost" || url.hostname === "127.0.0.1";
101
+ if (url.protocol !== "https:" && !(url.protocol === "http:" && loopback)) {
102
+ throw new Error(`${sinkName}: endpoint must be https (http is allowed only for localhost/127.0.0.1), got "${url.protocol}//${url.host}"`);
103
+ }
104
+ return url;
105
+ }
106
+ /**
107
+ * Object key + addressing. Virtual-host style against AWS; path-style against a
108
+ * configured endpoint, since S3-compatible stores rarely serve bucket
109
+ * subdomains. Anchor records are a few hundred bytes — one PUT, no multipart.
110
+ */
111
+ function s3Target(cfg, vaultId, anchorSeq) {
112
+ const prefix = (cfg.prefix ?? "anchors").replace(/^\/+|\/+$/g, "");
113
+ const key = `${prefix === "" ? "" : `${prefix}/`}${vaultId}/${seq12(anchorSeq)}.json`;
114
+ const encoded = key.split("/").map(encodeURIComponent).join("/");
115
+ if (cfg.endpoint !== undefined) {
116
+ const base = parseEndpoint(cfg.endpoint);
117
+ const path = `/${encodeURIComponent(cfg.bucket)}/${encoded}`;
118
+ return { host: base.host, path, url: `${base.protocol}//${base.host}${path}` };
119
+ }
120
+ const host = `${cfg.bucket}.s3.${cfg.region}.amazonaws.com`;
121
+ return { host, path: `/${encoded}`, url: `https://${host}/${encoded}` };
122
+ }
123
+ /**
124
+ * PUT one canonical record per object, keyed by vault and anchorSeq. Immutability
125
+ * is the STORE's job (Object Lock retention / a deny-delete bucket policy);
126
+ * `usertrust anchor doctor` reports whether this identity's permissions match
127
+ * that intent.
128
+ */
129
+ export function s3Sink(cfg, transport = httpTransport) {
130
+ const prefix = (cfg.prefix ?? "anchors").replace(/^\/+|\/+$/g, "");
131
+ return {
132
+ name: `s3:${cfg.bucket}/${prefix}`,
133
+ publish: async (record) => {
134
+ const creds = credentialsFromEnv();
135
+ if (creds === null) {
136
+ throw new Error("s3 sink: AWS credentials not found in environment " +
137
+ "(AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY)");
138
+ }
139
+ const payload = Buffer.from(canonicalize(record), "utf8");
140
+ const target = s3Target(cfg, record.vaultId, record.anchorSeq);
141
+ const extra = { "content-type": "application/json" };
142
+ const signed = sigV4Headers({
143
+ method: "PUT",
144
+ host: target.host,
145
+ path: target.path,
146
+ headers: extra,
147
+ payload,
148
+ region: cfg.region,
149
+ service: "s3",
150
+ amzDate: amzDate(),
151
+ }, creds);
152
+ // sigV4Headers signs the caller's headers but returns only its own —
153
+ // both must go on the wire or the signature covers headers that never
154
+ // arrive.
155
+ const res = await transport({
156
+ method: "PUT",
157
+ url: target.url,
158
+ headers: { ...extra, ...signed },
159
+ body: payload,
160
+ });
161
+ if (!is2xx(res.status)) {
162
+ throw new Error(`s3 sink: HTTP ${res.status}${snippet(res.body)}`);
163
+ }
164
+ },
165
+ };
166
+ }
167
+ // ── Rekor entry proposal ──
168
+ /**
169
+ * SPKI base64 as PEM text. The exact bytes matter: this text is base64'd into
170
+ * the entry, and the entry's bytes are what the inclusion proof commits to
171
+ * (delta D13). 64-character lines, LF-only, trailing newline.
172
+ */
173
+ function pemFromSpkiBase64(spkiBase64) {
174
+ const compact = spkiBase64.replace(/\s+/g, "");
175
+ if (compact === "" || !BASE64.test(compact)) {
176
+ throw new Error("rekor sink: vault identity publicKeySpki is not base64");
177
+ }
178
+ const wrapped = (compact.match(/.{1,64}/g) ?? []).join("\n");
179
+ return `-----BEGIN PUBLIC KEY-----\n${wrapped}\n-----END PUBLIC KEY-----\n`;
180
+ }
181
+ /**
182
+ * The hashedrekord entry we PROPOSE for a record: the anchor payload hash as the
183
+ * artifact, the record's Ed25519 signature, and the vault's public key. The log
184
+ * stores its own serialization of this; the receipt carries the log's bytes, so
185
+ * these are the bytes we sign nothing over and merely offer.
186
+ */
187
+ export function buildHashedRekordEntry(record, publicKeySpkiBase64) {
188
+ return canonicalize({
189
+ apiVersion: HASHEDREKORD_API_VERSION,
190
+ kind: "hashedrekord",
191
+ spec: {
192
+ data: { hash: { algorithm: "sha256", value: anchorPayloadHash(record) } },
193
+ signature: {
194
+ content: record.sig,
195
+ publicKey: {
196
+ content: Buffer.from(pemFromSpkiBase64(publicKeySpkiBase64), "utf8").toString("base64"),
197
+ },
198
+ },
199
+ },
200
+ });
201
+ }
202
+ function asObject(value) {
203
+ return value !== null && typeof value === "object" && !Array.isArray(value)
204
+ ? value
205
+ : null;
206
+ }
207
+ function isSafeIntAtLeast(value, min) {
208
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= min;
209
+ }
210
+ /**
211
+ * Validate a 201 down to every field the receipt will quote. A receipt built
212
+ * from a half-understood response is worse than no receipt: it would be filed as
213
+ * evidence and only fail at audit time, long after the anchor left the outbox.
214
+ * Nothing from the response is echoed into these errors — field names only.
215
+ */
216
+ function parseAcceptedEntry(raw) {
217
+ const bad = (message) => ({
218
+ entry: null,
219
+ error: message,
220
+ });
221
+ let parsed;
222
+ try {
223
+ parsed = JSON.parse(raw);
224
+ }
225
+ catch {
226
+ return bad("body is not valid JSON");
227
+ }
228
+ const response = asObject(parsed);
229
+ if (response === null)
230
+ return bad("body is not a JSON object");
231
+ const uuids = Object.keys(response);
232
+ // Rekor keys the response by entry UUID. Two keys means the log is answering
233
+ // about an entry we did not propose; zero means it answered about none.
234
+ if (uuids.length !== 1)
235
+ return bad(`expected exactly one entry, got ${uuids.length}`);
236
+ const entry = asObject(response[uuids[0]]);
237
+ if (entry === null)
238
+ return bad("entry is not a JSON object");
239
+ if (typeof entry.body !== "string" || entry.body === "" || !BASE64.test(entry.body)) {
240
+ return bad("entry.body must be base64");
241
+ }
242
+ const decoded = Buffer.from(entry.body, "base64");
243
+ if (decoded.length === 0)
244
+ return bad("entry.body decodes to no bytes");
245
+ if (decoded.length > MAX_ENTRY_BODY_BYTES)
246
+ return bad("entry.body exceeds 64 KiB decoded");
247
+ if (!isSafeIntAtLeast(entry.logIndex, 0))
248
+ return bad("entry.logIndex must be a safe integer >= 0");
249
+ // Same bound the receipt parser enforces: a receipt we write must be one we
250
+ // can read back, and `integratedTime * 1000` has to stay a printable Date.
251
+ if (!isSafeIntAtLeast(entry.integratedTime, 1) || entry.integratedTime >= MAX_INTEGRATED_TIME) {
252
+ return bad(`entry.integratedTime must be a safe integer > 0 and < ${MAX_INTEGRATED_TIME}`);
253
+ }
254
+ if (entry.logID !== undefined && (typeof entry.logID !== "string" || !HEX64.test(entry.logID))) {
255
+ return bad("entry.logID must be 64 lowercase hex characters");
256
+ }
257
+ const verification = asObject(entry.verification);
258
+ const proof = asObject(verification?.inclusionProof);
259
+ if (proof === null)
260
+ return bad("entry.verification.inclusionProof is missing");
261
+ // The proof's own index — NOT the entry's global logIndex, which counts
262
+ // across the whole log rather than the tree this proof is against.
263
+ if (!isSafeIntAtLeast(proof.logIndex, 0))
264
+ return bad("inclusionProof.logIndex must be >= 0");
265
+ if (!isSafeIntAtLeast(proof.treeSize, 1))
266
+ return bad("inclusionProof.treeSize must be >= 1");
267
+ if (proof.logIndex >= proof.treeSize) {
268
+ return bad("inclusionProof.logIndex must be < inclusionProof.treeSize");
269
+ }
270
+ if (typeof proof.rootHash !== "string" || !HEX64.test(proof.rootHash)) {
271
+ return bad("inclusionProof.rootHash must be 64 lowercase hex characters");
272
+ }
273
+ if (!Array.isArray(proof.hashes) || proof.hashes.length > MAX_INCLUSION_PATH) {
274
+ return bad(`inclusionProof.hashes must be an array of at most ${MAX_INCLUSION_PATH} hashes`);
275
+ }
276
+ for (const h of proof.hashes) {
277
+ if (typeof h !== "string" || !HEX64.test(h)) {
278
+ return bad("inclusionProof.hashes entries must be 64 lowercase hex characters");
279
+ }
280
+ }
281
+ if (typeof proof.checkpoint !== "string" ||
282
+ proof.checkpoint === "" ||
283
+ Buffer.byteLength(proof.checkpoint, "utf8") > MAX_CHECKPOINT_BYTES ||
284
+ proof.checkpoint.includes("\r")) {
285
+ return bad("inclusionProof.checkpoint must be a non-empty LF-only string of at most 8 KiB");
286
+ }
287
+ // The signed entry timestamp is what makes integratedTime worth anything to
288
+ // an auditor, so it is captured whenever the log offers one — but a SET with
289
+ // no logID cannot be verified by anybody (the logID is inside the payload it
290
+ // signs), and filing evidence nobody can check is the failure this module
291
+ // exists to avoid.
292
+ const set = verification?.signedEntryTimestamp;
293
+ if (set !== undefined) {
294
+ if (typeof set !== "string" ||
295
+ set === "" ||
296
+ !BASE64.test(set) ||
297
+ Buffer.byteLength(set, "utf8") > MAX_SET_BYTES) {
298
+ return bad("verification.signedEntryTimestamp must be base64 of at most 1 KiB");
299
+ }
300
+ if (entry.logID === undefined) {
301
+ return bad("verification.signedEntryTimestamp present without entry.logID");
302
+ }
303
+ }
304
+ return {
305
+ entry: {
306
+ body: entry.body,
307
+ integratedTime: entry.integratedTime,
308
+ logIndex: proof.logIndex,
309
+ treeSize: proof.treeSize,
310
+ rootHash: proof.rootHash,
311
+ hashes: proof.hashes,
312
+ checkpoint: proof.checkpoint,
313
+ ...(typeof set === "string" ? { signedEntryTimestamp: set } : {}),
314
+ ...(typeof entry.logID === "string" ? { logID: entry.logID } : {}),
315
+ },
316
+ error: null,
317
+ };
318
+ }
319
+ // ── Receipt persistence ──
320
+ /**
321
+ * `<seq12>.<8 hex of sha256(log url)>.json` — one receipt per (anchor, LOG).
322
+ * Keying by anchorSeq alone made two rekor sinks silently overwrite each
323
+ * other's evidence: the second witness's receipt replaced the first's, and the
324
+ * operator ended up with fewer independent attestations than they configured.
325
+ * Readers glob `*.json` in this directory, so pre-existing `<seq12>.json`
326
+ * receipts keep being found.
327
+ */
328
+ export function rekorReceiptPath(rootDir, anchorSeq, logUrl) {
329
+ const tag = createHash("sha256").update(logUrl, "utf8").digest("hex").slice(0, 8);
330
+ return join(anchorsDir(rootDir), "rekor", `${seq12(anchorSeq)}.${tag}.json`);
331
+ }
332
+ /** Fsync'd receipt write — the same durability the outbox and mirror get. */
333
+ function writeReceipt(rootDir, receipt) {
334
+ const serialized = `${canonicalize(receipt)}\n`;
335
+ // A receipt our own parser rejects is a bug in this module, and it would be
336
+ // discovered at audit time by whoever is relying on it. Fail here instead.
337
+ const check = parseRekorReceipt(serialized);
338
+ if (check.receipt === null) {
339
+ throw new Error(`rekor sink: assembled an unparseable receipt (${check.error})`);
340
+ }
341
+ const dir = join(anchorsDir(rootDir), "rekor");
342
+ mkdirSync(dir, { recursive: true });
343
+ const fd = openSync(rekorReceiptPath(rootDir, receipt.anchorSeq, receipt.log.url), "w", 0o600);
344
+ try {
345
+ writeSync(fd, serialized);
346
+ fsyncSync(fd);
347
+ }
348
+ finally {
349
+ closeSync(fd);
350
+ }
351
+ }
352
+ /**
353
+ * Do the bytes a log stored commit to THIS record — our payload hash AND our
354
+ * signature? Reused for the 201 response and for receipts already on disk; in
355
+ * both cases the alternative is filing evidence about someone else's entry.
356
+ * Decoded bytes are compared, never base64 spellings, since base64 is not
357
+ * canonical and equivalent encodings are the same signature.
358
+ */
359
+ function entryBindsRecord(entryBodyBase64, record) {
360
+ let parsed;
361
+ try {
362
+ parsed = JSON.parse(Buffer.from(entryBodyBase64, "base64").toString("utf8"));
363
+ }
364
+ catch {
365
+ return false;
366
+ }
367
+ const spec = asObject(asObject(parsed)?.spec);
368
+ if (spec === null)
369
+ return false;
370
+ const hash = asObject(asObject(spec.data)?.hash);
371
+ const signature = asObject(spec.signature);
372
+ if (hash === null || signature === null || typeof signature.content !== "string")
373
+ return false;
374
+ if (hash.value !== anchorPayloadHash(record))
375
+ return false;
376
+ const logged = Buffer.from(signature.content, "base64");
377
+ const ours = Buffer.from(record.sig, "base64");
378
+ return ours.length > 0 && logged.equals(ours);
379
+ }
380
+ /**
381
+ * A receipt already on disk from THIS log that witnesses THIS record. Every
382
+ * `*.json` in the directory is considered, because the filename is a
383
+ * convenience and the receipt's own contents are the evidence — a receipt is
384
+ * only accepted when it names the record, carries its payload hash, and its
385
+ * stored entry binds the record's signature.
386
+ */
387
+ function findBindingReceipt(rootDir, record, logUrl) {
388
+ const dir = join(anchorsDir(rootDir), "rekor");
389
+ let names;
390
+ try {
391
+ names = readdirSync(dir).filter((f) => f.endsWith(".json"));
392
+ }
393
+ catch {
394
+ return false;
395
+ }
396
+ for (const name of names.sort()) {
397
+ let raw;
398
+ try {
399
+ raw = readFileSync(join(dir, name), "utf-8");
400
+ }
401
+ catch {
402
+ continue;
403
+ }
404
+ const { receipt } = parseRekorReceipt(raw);
405
+ if (receipt === null)
406
+ continue;
407
+ if (receipt.vaultId === record.vaultId &&
408
+ receipt.anchorSeq === record.anchorSeq &&
409
+ receipt.log.url === logUrl &&
410
+ receipt.artifactHash === anchorPayloadHash(record) &&
411
+ entryBindsRecord(receipt.entryBody, record)) {
412
+ return true;
413
+ }
414
+ }
415
+ return false;
416
+ }
417
+ /**
418
+ * The public key to PROPOSE for a record, resolved from the record's OWN key
419
+ * epoch rather than from whatever key the vault holds today. A record minted
420
+ * before a rotation and redelivered after it is still signed by the old key, so
421
+ * proposing the live key would log a public key that does not verify the
422
+ * signature sitting beside it — a permanently wrong entry in an append-only
423
+ * log. Identities predating key history keep the old behavior; once a history
424
+ * exists, a keyId absent from it is refused rather than guessed at.
425
+ */
426
+ function spkiForRecord(identity, record) {
427
+ if (identity.keyHistory === undefined)
428
+ return identity.publicKeySpki;
429
+ const known = [
430
+ ...identity.keyHistory,
431
+ { keyId: identity.keyId, publicKeySpki: identity.publicKeySpki },
432
+ ];
433
+ const match = known.find((entry) => entry.keyId === record.keyId);
434
+ if (match === undefined) {
435
+ throw new Error(`rekor sink: no public key for keyId ${record.keyId} in this vault's key history`);
436
+ }
437
+ return match.publicKeySpki;
438
+ }
439
+ // ── Rekor sink ──
440
+ /**
441
+ * Publish a record's payload hash to a Rekor transparency log and persist the
442
+ * inclusion receipt next to the mirror.
443
+ *
444
+ * A 409 means the log already holds an entry for this proposal, which happens
445
+ * on exactly one honest path: a crash between writing the receipt and clearing
446
+ * the outbox, so the emitter redelivers a record that IS already witnessed.
447
+ * That case is resolved from the receipt we already hold — never from the 409
448
+ * itself, which carries no evidence. A 409 with no such receipt is a duplicate
449
+ * we cannot account for, and fabricating one from a Location header would mean
450
+ * filing evidence about bytes we never saw (delta D1), so it rejects and the
451
+ * outbox keeps the record for a human.
452
+ */
453
+ export function rekorSink(rootDir, url = DEFAULT_REKOR_URL, transport = httpTransport) {
454
+ // Same rule as the S3 sink, applied at CONSTRUCTION so a plaintext log URL
455
+ // fails before a record is ever offered to it.
456
+ parseEndpoint(url, "rekor sink");
457
+ const base = url.replace(/\/+$/, "");
458
+ return {
459
+ name: `rekor:${base}`,
460
+ publish: async (record) => {
461
+ const identity = readAnchorIdentity(rootDir);
462
+ if (identity === null) {
463
+ throw new Error("rekor sink: no anchor identity — run `usertrust anchor init` first");
464
+ }
465
+ const proposal = Buffer.from(buildHashedRekordEntry(record, spkiForRecord(identity, record)), "utf8");
466
+ const res = await transport({
467
+ method: "POST",
468
+ url: `${base}${REKOR_ENTRIES_PATH}`,
469
+ headers: {
470
+ accept: "application/json",
471
+ "content-type": "application/json",
472
+ },
473
+ body: proposal,
474
+ });
475
+ if (res.status === 409) {
476
+ if (findBindingReceipt(rootDir, record, base))
477
+ return;
478
+ throw new Error("rekor sink: HTTP 409 (duplicate without local receipt — fetch the entry manually)");
479
+ }
480
+ if (res.status !== 201) {
481
+ throw new Error(`rekor sink: HTTP ${res.status}${snippet(res.body)}`);
482
+ }
483
+ const { entry, error } = parseAcceptedEntry(res.body);
484
+ if (entry === null) {
485
+ throw new Error(`rekor sink: invalid 201 response: ${error}`);
486
+ }
487
+ // A well-formed 201 is not yet OUR 201: the receipt is built from the
488
+ // log's bytes, so a response describing somebody else's entry would be
489
+ // persisted as evidence for this record and only fall apart at audit
490
+ // time. Bind it to the record before trusting a single field of it.
491
+ if (!entryBindsRecord(entry.body, record)) {
492
+ throw new Error("rekor sink: 201 response describes an entry that is not this record's " +
493
+ "(payload hash or signature mismatch)");
494
+ }
495
+ writeReceipt(rootDir, {
496
+ v: 1,
497
+ vaultId: record.vaultId,
498
+ anchorSeq: record.anchorSeq,
499
+ artifactHash: anchorPayloadHash(record),
500
+ // VERBATIM (delta D13): the leaf hash is over the bytes the LOG
501
+ // stored, so any reserialization here would break inclusion.
502
+ entryBody: entry.body,
503
+ log: {
504
+ url: base,
505
+ logIndex: entry.logIndex,
506
+ treeSize: entry.treeSize,
507
+ rootHash: entry.rootHash,
508
+ hashes: entry.hashes,
509
+ checkpoint: entry.checkpoint,
510
+ integratedTime: entry.integratedTime,
511
+ ...(entry.signedEntryTimestamp !== undefined
512
+ ? { signedEntryTimestamp: entry.signedEntryTimestamp }
513
+ : {}),
514
+ ...(entry.logID !== undefined ? { logID: entry.logID } : {}),
515
+ },
516
+ });
517
+ },
518
+ };
519
+ }
520
+ // ── Default transport ──
521
+ /** The module's only network access. `http://` is reachable for dev endpoints. */
522
+ async function httpTransport(opts) {
523
+ const { request } = await (opts.url.startsWith("http://")
524
+ ? import("node:http")
525
+ : import("node:https"));
526
+ return new Promise((resolve, reject) => {
527
+ const req = request(opts.url, {
528
+ method: opts.method,
529
+ headers: { ...opts.headers, "content-length": String(opts.body.length) },
530
+ timeout: 15_000,
531
+ }, (res) => {
532
+ const chunks = [];
533
+ res.on("data", (c) => chunks.push(c));
534
+ res.on("end", () => {
535
+ const headers = {};
536
+ for (const [name, value] of Object.entries(res.headers)) {
537
+ if (typeof value === "string")
538
+ headers[name] = value;
539
+ }
540
+ resolve({
541
+ status: res.statusCode ?? 0,
542
+ // Bounded: a receipt is small, and an error body is only ever
543
+ // a snippet.
544
+ body: Buffer.concat(chunks)
545
+ .toString("utf8")
546
+ .slice(0, 256 * 1024),
547
+ headers,
548
+ });
549
+ });
550
+ });
551
+ req.on("timeout", () => req.destroy(new Error("anchor sink: request timeout")));
552
+ req.on("error", reject);
553
+ req.end(opts.body);
554
+ });
555
+ }
556
+ //# sourceMappingURL=rekor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rekor.js","sourceRoot":"","sources":["../../src/audit/rekor.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACN,SAAS,EACT,SAAS,EACT,SAAS,EACT,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,SAAS,GACT,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,gFAAgF;AAChF,yEAAyE;AACzE,+EAA+E;AAC/E,kCAAkC;AAClC,OAAO,EAAwC,UAAU,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACnG,OAAO,EAAqB,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAqB,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAyB,YAAY,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,CAAC,MAAM,iBAAiB,GAAG,4BAA4B,CAAC;AAC9D,MAAM,kBAAkB,GAAG,qBAAqB,CAAC;AAEjD,kFAAkF;AAClF,MAAM,wBAAwB,GAAG,OAAO,CAAC;AAEzC,MAAM,KAAK,GAAG,gBAAgB,CAAC;AAC/B,MAAM,MAAM,GAAG,wBAAwB,CAAC;AACxC,MAAM,oBAAoB,GAAG,EAAE,GAAG,IAAI,CAAC;AACvC,MAAM,oBAAoB,GAAG,CAAC,GAAG,IAAI,CAAC;AACtC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAC9B,MAAM,aAAa,GAAG,IAAI,CAAC;AAC3B,2EAA2E;AAC3E,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;AAqB9C,uBAAuB;AAEvB,MAAM,KAAK,GAAG,CAAC,MAAc,EAAW,EAAE,CAAC,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,CAAC;AAEzE;;;;;GAKG;AACH,SAAS,OAAO,CAAC,IAAY;IAC5B,IAAI,IAAI,KAAK,EAAE;QAAE,OAAO,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAG,IAAI;SACnB,OAAO,CAAC,uBAAuB,EAAE,YAAY,CAAC;SAC9C,OAAO,CAAC,8BAA8B,EAAE,YAAY,CAAC;SACrD,OAAO,CAAC,yBAAyB,EAAE,YAAY,CAAC;SAChD,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;IACT,OAAO,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AAC7D,CAAC;AAED,MAAM,KAAK,GAAG,CAAC,SAAiB,EAAU,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;AAEjF,oCAAoC;AACpC,SAAS,OAAO;IACf,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC;AACzE,CAAC;AAED,SAAS,kBAAkB;IAC1B,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAClD,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;IAC1D,IAAI,CAAC,WAAW,IAAI,CAAC,eAAe;QAAE,OAAO,IAAI,CAAC;IAClD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IACnD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACpF,CAAC;AAED,gBAAgB;AAEhB;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,QAAgB,EAAE,QAAQ,GAAG,SAAS;IACnE,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACJ,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACR,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,0CAA0C,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;IAChG,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,KAAK,WAAW,IAAI,GAAG,CAAC,QAAQ,KAAK,WAAW,CAAC;IAC9E,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,QAAQ,CAAC,EAAE,CAAC;QAC1E,MAAM,IAAI,KAAK,CACd,GAAG,QAAQ,iFAAiF,GAAG,CAAC,QAAQ,KAAK,GAAG,CAAC,IAAI,GAAG,CACxH,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAED;;;;GAIG;AACH,SAAS,QAAQ,CAChB,GAAiB,EACjB,OAAe,EACf,SAAiB;IAEjB,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IACnE,MAAM,GAAG,GAAG,GAAG,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,GAAG,OAAO,IAAI,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC;IACtF,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEjE,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,IAAI,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QAC7D,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,IAAI,GAAG,IAAI,EAAE,EAAE,CAAC;IAChF,CAAC;IACD,MAAM,IAAI,GAAG,GAAG,GAAG,CAAC,MAAM,OAAO,GAAG,CAAC,MAAM,gBAAgB,CAAC;IAC5D,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,OAAO,EAAE,EAAE,GAAG,EAAE,WAAW,IAAI,IAAI,OAAO,EAAE,EAAE,CAAC;AACzE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAC,GAAiB,EAAE,YAA2B,aAAa;IACjF,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IACnE,OAAO;QACN,IAAI,EAAE,MAAM,GAAG,CAAC,MAAM,IAAI,MAAM,EAAE;QAClC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACzB,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;YACnC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CACd,oDAAoD;oBACnD,6CAA6C,CAC9C,CAAC;YACH,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;YAC1D,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;YAC/D,MAAM,KAAK,GAAG,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;YACrD,MAAM,MAAM,GAAG,YAAY,CAC1B;gBACC,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,OAAO,EAAE,KAAK;gBACd,OAAO;gBACP,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,OAAO,EAAE;aAClB,EACD,KAAK,CACL,CAAC;YACF,qEAAqE;YACrE,sEAAsE;YACtE,UAAU;YACV,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC;gBAC3B,MAAM,EAAE,KAAK;gBACb,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,OAAO,EAAE,EAAE,GAAG,KAAK,EAAE,GAAG,MAAM,EAAE;gBAChC,IAAI,EAAE,OAAO;aACb,CAAC,CAAC;YACH,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,iBAAiB,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACpE,CAAC;QACF,CAAC;KACD,CAAC;AACH,CAAC;AAED,6BAA6B;AAE7B;;;;GAIG;AACH,SAAS,iBAAiB,CAAC,UAAkB;IAC5C,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC/C,IAAI,OAAO,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC3E,CAAC;IACD,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7D,OAAO,+BAA+B,OAAO,8BAA8B,CAAC;AAC7E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAoB,EAAE,mBAA2B;IACvF,OAAO,YAAY,CAAC;QACnB,UAAU,EAAE,wBAAwB;QACpC,IAAI,EAAE,cAAc;QACpB,IAAI,EAAE;YACL,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,iBAAiB,CAAC,MAAM,CAAC,EAAE,EAAE;YACzE,SAAS,EAAE;gBACV,OAAO,EAAE,MAAM,CAAC,GAAG;gBACnB,SAAS,EAAE;oBACV,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;iBACvF;aACD;SACD;KACD,CAAC,CAAC;AACJ,CAAC;AAkBD,SAAS,QAAQ,CAAC,KAAc;IAC/B,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAC1E,CAAC,CAAE,KAAiC;QACpC,CAAC,CAAC,IAAI,CAAC;AACT,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc,EAAE,GAAW;IACpD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,GAAG,CAAC;AACjF,CAAC;AAED;;;;;GAKG;AACH,SAAS,kBAAkB,CAAC,GAAW;IACtC,MAAM,GAAG,GAAG,CAAC,OAAe,EAAkC,EAAE,CAAC,CAAC;QACjE,KAAK,EAAE,IAAI;QACX,KAAK,EAAE,OAAO;KACd,CAAC,CAAC;IAEH,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACJ,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtC,CAAC;IACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAClC,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC,2BAA2B,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpC,6EAA6E;IAC7E,wEAAwE;IACxE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC,mCAAmC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IACtF,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAW,CAAC,CAAC,CAAC;IACrD,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAE7D,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACrF,OAAO,GAAG,CAAC,2BAA2B,CAAC,CAAC;IACzC,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAClD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC,gCAAgC,CAAC,CAAC;IACvE,IAAI,OAAO,CAAC,MAAM,GAAG,oBAAoB;QAAE,OAAO,GAAG,CAAC,mCAAmC,CAAC,CAAC;IAC3F,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QACvC,OAAO,GAAG,CAAC,4CAA4C,CAAC,CAAC;IAC1D,4EAA4E;IAC5E,2EAA2E;IAC3E,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,cAAc,IAAI,mBAAmB,EAAE,CAAC;QAC/F,OAAO,GAAG,CAAC,yDAAyD,mBAAmB,EAAE,CAAC,CAAC;IAC5F,CAAC;IACD,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QAChG,OAAO,GAAG,CAAC,iDAAiD,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IACrD,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC,8CAA8C,CAAC,CAAC;IAC/E,wEAAwE;IACxE,mEAAmE;IACnE,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QAAE,OAAO,GAAG,CAAC,sCAAsC,CAAC,CAAC;IAC7F,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QAAE,OAAO,GAAG,CAAC,sCAAsC,CAAC,CAAC;IAC7F,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACtC,OAAO,GAAG,CAAC,2DAA2D,CAAC,CAAC;IACzE,CAAC;IACD,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvE,OAAO,GAAG,CAAC,6DAA6D,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,kBAAkB,EAAE,CAAC;QAC9E,OAAO,GAAG,CAAC,qDAAqD,kBAAkB,SAAS,CAAC,CAAC;IAC9F,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QAC9B,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,OAAO,GAAG,CAAC,mEAAmE,CAAC,CAAC;QACjF,CAAC;IACF,CAAC;IACD,IACC,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ;QACpC,KAAK,CAAC,UAAU,KAAK,EAAE;QACvB,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,oBAAoB;QAClE,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,EAC9B,CAAC;QACF,OAAO,GAAG,CAAC,+EAA+E,CAAC,CAAC;IAC7F,CAAC;IAED,4EAA4E;IAC5E,6EAA6E;IAC7E,6EAA6E;IAC7E,0EAA0E;IAC1E,mBAAmB;IACnB,MAAM,GAAG,GAAG,YAAY,EAAE,oBAAoB,CAAC;IAC/C,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACvB,IACC,OAAO,GAAG,KAAK,QAAQ;YACvB,GAAG,KAAK,EAAE;YACV,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;YACjB,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,aAAa,EAC7C,CAAC;YACF,OAAO,GAAG,CAAC,mEAAmE,CAAC,CAAC;QACjF,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO,GAAG,CAAC,+DAA+D,CAAC,CAAC;QAC7E,CAAC;IACF,CAAC;IAED,OAAO;QACN,KAAK,EAAE;YACN,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,MAAM,EAAE,KAAK,CAAC,MAAkB;YAChC,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,GAAG,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,oBAAoB,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjE,GAAG,CAAC,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAClE;QACD,KAAK,EAAE,IAAI;KACX,CAAC;AACH,CAAC;AAED,4BAA4B;AAE5B;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,SAAiB,EAAE,MAAc;IAClF,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAClF,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC;AAC9E,CAAC;AAED,6EAA6E;AAC7E,SAAS,YAAY,CAAC,OAAe,EAAE,OAAqB;IAC3D,MAAM,UAAU,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC;IAChD,4EAA4E;IAC5E,2EAA2E;IAC3E,MAAM,KAAK,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAC5C,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,iDAAiD,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC;IAClF,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;IAC/C,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,MAAM,EAAE,GAAG,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IAC/F,IAAI,CAAC;QACJ,SAAS,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QAC1B,SAAS,CAAC,EAAE,CAAC,CAAC;IACf,CAAC;YAAS,CAAC;QACV,SAAS,CAAC,EAAE,CAAC,CAAC;IACf,CAAC;AACF,CAAC;AAED;;;;;;GAMG;AACH,SAAS,gBAAgB,CAAC,eAAuB,EAAE,MAAoB;IACtE,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACJ,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9E,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAC;IACd,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;IAC9C,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAChC,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3C,IAAI,IAAI,KAAK,IAAI,IAAI,SAAS,KAAK,IAAI,IAAI,OAAO,SAAS,CAAC,OAAO,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC/F,IAAI,IAAI,CAAC,KAAK,KAAK,iBAAiB,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3D,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC/C,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;;GAMG;AACH,SAAS,kBAAkB,CAAC,OAAe,EAAE,MAAoB,EAAE,MAAc;IAChF,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;IAC/C,IAAI,KAAe,CAAC;IACpB,IAAI,CAAC;QACJ,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAC;IACd,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QACjC,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACJ,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;QAC9C,CAAC;QAAC,MAAM,CAAC;YACR,SAAS;QACV,CAAC;QACD,MAAM,EAAE,OAAO,EAAE,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,OAAO,KAAK,IAAI;YAAE,SAAS;QAC/B,IACC,OAAO,CAAC,OAAO,KAAK,MAAM,CAAC,OAAO;YAClC,OAAO,CAAC,SAAS,KAAK,MAAM,CAAC,SAAS;YACtC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,MAAM;YAC1B,OAAO,CAAC,YAAY,KAAK,iBAAiB,CAAC,MAAM,CAAC;YAClD,gBAAgB,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,EAC1C,CAAC;YACF,OAAO,IAAI,CAAC;QACb,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,aAAa,CAAC,QAAwB,EAAE,MAAoB;IACpE,IAAI,QAAQ,CAAC,UAAU,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC,aAAa,CAAC;IACrE,MAAM,KAAK,GAAG;QACb,GAAG,QAAQ,CAAC,UAAU;QACtB,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,CAAC,aAAa,EAAE;KAChE,CAAC;IACF,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC;IAClE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACd,uCAAuC,MAAM,CAAC,KAAK,8BAA8B,CACjF,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,aAAa,CAAC;AAC5B,CAAC;AAED,mBAAmB;AAEnB;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,SAAS,CACxB,OAAe,EACf,MAAc,iBAAiB,EAC/B,YAA2B,aAAa;IAExC,2EAA2E;IAC3E,+CAA+C;IAC/C,aAAa,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACrC,OAAO;QACN,IAAI,EAAE,SAAS,IAAI,EAAE;QACrB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACzB,MAAM,QAAQ,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;YAC7C,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACvB,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;YACvF,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAC3B,sBAAsB,CAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,EAC/D,MAAM,CACN,CAAC;YACF,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC;gBAC3B,MAAM,EAAE,MAAM;gBACd,GAAG,EAAE,GAAG,IAAI,GAAG,kBAAkB,EAAE;gBACnC,OAAO,EAAE;oBACR,MAAM,EAAE,kBAAkB;oBAC1B,cAAc,EAAE,kBAAkB;iBAClC;gBACD,IAAI,EAAE,QAAQ;aACd,CAAC,CAAC;YACH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACxB,IAAI,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC;oBAAE,OAAO;gBACtD,MAAM,IAAI,KAAK,CACd,mFAAmF,CACnF,CAAC;YACH,CAAC;YACD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,oBAAoB,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACvE,CAAC;YACD,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACtD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,qCAAqC,KAAK,EAAE,CAAC,CAAC;YAC/D,CAAC;YACD,sEAAsE;YACtE,uEAAuE;YACvE,qEAAqE;YACrE,oEAAoE;YACpE,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;gBAC3C,MAAM,IAAI,KAAK,CACd,wEAAwE;oBACvE,sCAAsC,CACvC,CAAC;YACH,CAAC;YACD,YAAY,CAAC,OAAO,EAAE;gBACrB,CAAC,EAAE,CAAC;gBACJ,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,YAAY,EAAE,iBAAiB,CAAC,MAAM,CAAC;gBACvC,gEAAgE;gBAChE,6DAA6D;gBAC7D,SAAS,EAAE,KAAK,CAAC,IAAI;gBACrB,GAAG,EAAE;oBACJ,GAAG,EAAE,IAAI;oBACT,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,UAAU,EAAE,KAAK,CAAC,UAAU;oBAC5B,cAAc,EAAE,KAAK,CAAC,cAAc;oBACpC,GAAG,CAAC,KAAK,CAAC,oBAAoB,KAAK,SAAS;wBAC3C,CAAC,CAAC,EAAE,oBAAoB,EAAE,KAAK,CAAC,oBAAoB,EAAE;wBACtD,CAAC,CAAC,EAAE,CAAC;oBACN,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC5D;aACD,CAAC,CAAC;QACJ,CAAC;KACD,CAAC;AACH,CAAC;AAED,0BAA0B;AAE1B,kFAAkF;AAClF,KAAK,UAAU,aAAa,CAAC,IAK5B;IACA,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;QACxD,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;QACrB,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;IACzB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACtC,MAAM,GAAG,GAAG,OAAO,CAClB,IAAI,CAAC,GAAG,EACR;YACC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;YACxE,OAAO,EAAE,MAAM;SACf,EACD,CAAC,GAAG,EAAE,EAAE;YACP,MAAM,MAAM,GAAa,EAAE,CAAC;YAC5B,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9C,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBAClB,MAAM,OAAO,GAA2B,EAAE,CAAC;gBAC3C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;oBACzD,IAAI,OAAO,KAAK,KAAK,QAAQ;wBAAE,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;gBACtD,CAAC;gBACD,OAAO,CAAC;oBACP,MAAM,EAAE,GAAG,CAAC,UAAU,IAAI,CAAC;oBAC3B,8DAA8D;oBAC9D,aAAa;oBACb,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;yBACzB,QAAQ,CAAC,MAAM,CAAC;yBAChB,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC;oBACtB,OAAO;iBACP,CAAC,CAAC;YACJ,CAAC,CAAC,CAAC;QACJ,CAAC,CACD,CAAC;QACF,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC,CAAC,CAAC;QAChF,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACxB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;AACJ,CAAC"}
@@ -9,7 +9,7 @@
9
9
  *
10
10
  * Structure: .usertrust/audit/<kind>/<YYYY-MM-DD>/<receiptId>.json
11
11
  */
12
- import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
12
+ import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
13
13
  import { join } from "node:path";
14
14
  import { AUDIT_DIR, RECEIPT_VERSION, VAULT_DIR } from "../shared/constants.js";
15
15
  import { trustId } from "../shared/ids.js";
@@ -1 +1 @@
1
- {"version":3,"file":"rotation.js","sourceRoot":"","sources":["../../src/audit/rotation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rotation.js","sourceRoot":"","sources":["../../src/audit/rotation.ts"],"names":[],"mappings":"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"}