@disclosureos/schema 2.0.0-beta.4 → 2.0.0-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/README.md +19 -0
- package/dist/experimental/v2/index.d.ts +572 -101
- package/dist/experimental/v2/index.js +1354 -682
- package/dist/experimental/v2/index.js.map +1 -1
- package/package.json +11 -7
- package/schema/experimental/claim-review-evaluation-0.1.0.schema.json +52 -0
- package/schema/experimental/claim-review-receipt-0.1.0.schema.json +99 -0
- package/schema/experimental/mcap-source-mapping-0.1.0.schema.json +303 -0
- package/schema/experimental/video-frame-source-mapping-0.1.0.schema.json +165 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { parseExperimentalClaimHistory, compareUtcInstants, parseContextClaimHistory, parseObservationContext, parseExperimentalObservation,
|
|
1
|
+
import { OBSERVATION_CLAIM_HISTORY_SCHEMA_ID, CASE_CLAIM_HISTORY_V02_SCHEMA_ID, parseExperimentalClaimHistory, parseObservationClaimHistory, compareUtcInstants, parseContextClaimHistory, parseObservationContext, parseExperimentalObservation, caseProvenances, parseCaseRecordV02, caseSnapshotKey, parseCaseClaimHistoryV02, parseCaseLinks, parseCaseRecord, parseResearchEntities, parseArchivalEntities, parseMaterialEntities, parseLaboratoryEntities, parseCaseClaimHistory, contextAssertions, parseResearchClaimHistory, researchEntityAssertions, parseArchivalClaimHistory, parseLaboratoryClaimHistory, parseVocabularyBindings, parseVocabularyCatalog, VOCABULARY_CATALOG_SCHEMA_ID, archivalArtifactReferences, researchEntityContextReferences, CASE_CLAIM_HISTORY_SCHEMA_ID, LABORATORY_CLAIM_HISTORY_SCHEMA_ID, ARCHIVAL_CLAIM_HISTORY_SCHEMA_ID, RESEARCH_CLAIM_HISTORY_SCHEMA_ID, CONTEXT_CLAIM_HISTORY_SCHEMA_ID, EXPERIMENTAL_CLAIM_HISTORY_SCHEMA_ID } from '@disclosureos/records/experimental/v2';
|
|
2
2
|
export { VOCABULARY_BINDINGS_SCHEMA_ID, VOCABULARY_CATALOG_SCHEMA_ID, VOCABULARY_TERM_REFERENCE_SCHEMA_ID, VocabularyBindingSchema, VocabularyBindingsSchema, VocabularyCatalogSchema, VocabularyCatalogTermSchema, VocabularyTermReferenceSchema, parseVocabularyBindings, parseVocabularyCatalog, vocabularyBindingsJsonSchema, vocabularyCatalogJsonSchema, vocabularyTermReferenceJsonSchema } from '@disclosureos/records/experimental/v2';
|
|
3
|
+
import { preservePublishedSchema } from '@disclosureos/records/shared';
|
|
3
4
|
import { z } from 'zod';
|
|
4
5
|
import { parseAcquisitionContext } from '@disclosureos/instruments/experimental/v2';
|
|
5
6
|
|
|
@@ -22,10 +23,26 @@ function inventories(observation, claims) {
|
|
|
22
23
|
};
|
|
23
24
|
}
|
|
24
25
|
async function evaluateAssessmentDocumentation(input, options = {}) {
|
|
25
|
-
|
|
26
|
+
return evaluateParsedDocumentation(parseExperimentalClaimHistory(input), options, ASSESSMENT_DOCUMENTATION_PROFILE);
|
|
27
|
+
}
|
|
28
|
+
var OBSERVATION_CLAIM_DOCUMENTATION_PROFILE = Object.freeze({
|
|
29
|
+
id: "urn:disclosureos:experimental:profile:assessment-documentation",
|
|
30
|
+
version: "0.2.0",
|
|
31
|
+
scope: "documentary_only"
|
|
32
|
+
});
|
|
33
|
+
async function evaluateObservationClaimDocumentation(input, options = {}) {
|
|
34
|
+
const parsed = parseObservationClaimHistory(input);
|
|
35
|
+
const result = await evaluateParsedDocumentation(parsed, options, OBSERVATION_CLAIM_DOCUMENTATION_PROFILE);
|
|
36
|
+
return {
|
|
37
|
+
...result,
|
|
38
|
+
processingChronology: "not_checked",
|
|
39
|
+
unknownProcessingTimes: parsed.success ? parsed.data.observation.processing.filter((p) => typeof p.performedAt !== "string").map((p) => ({ processRef: `process:${p.id}`, performedAt: p.performedAt })) : []
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
async function evaluateParsedDocumentation(parsed, options, profile) {
|
|
26
43
|
const result = {
|
|
27
44
|
success: false,
|
|
28
|
-
profile
|
|
45
|
+
profile,
|
|
29
46
|
contract: parsed.contract,
|
|
30
47
|
checks: { ...parsed.checks, profile: "not_checked" },
|
|
31
48
|
scientific: "not_checked",
|
|
@@ -37,71 +54,71 @@ async function evaluateAssessmentDocumentation(input, options = {}) {
|
|
|
37
54
|
if (!parsed.success) return result;
|
|
38
55
|
const observation = parsed.data.observation;
|
|
39
56
|
const inv = inventories(observation, parsed.data.claims);
|
|
40
|
-
const assets2 = new Map([...options.assets ?? []].map(([
|
|
57
|
+
const assets2 = new Map([...options.assets ?? []].map(([ref18, bytes6]) => [ref18, Uint8Array.from(bytes6)]));
|
|
41
58
|
const hashes = /* @__PURE__ */ new Map();
|
|
42
|
-
function
|
|
43
|
-
const cached = hashes.get(
|
|
59
|
+
function hash8(ref18) {
|
|
60
|
+
const cached = hashes.get(ref18);
|
|
44
61
|
if (cached) return cached;
|
|
45
|
-
const
|
|
62
|
+
const bytes6 = assets2.get(ref18);
|
|
46
63
|
const pending = (async () => {
|
|
47
|
-
if (!
|
|
64
|
+
if (!bytes6) return void 0;
|
|
48
65
|
try {
|
|
49
|
-
const
|
|
50
|
-
return [...new Uint8Array(
|
|
66
|
+
const digest12 = await globalThis.crypto.subtle.digest("SHA-256", bytes6);
|
|
67
|
+
return [...new Uint8Array(digest12)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
51
68
|
} catch {
|
|
52
69
|
return void 0;
|
|
53
70
|
}
|
|
54
71
|
})();
|
|
55
|
-
hashes.set(
|
|
72
|
+
hashes.set(ref18, pending);
|
|
56
73
|
return pending;
|
|
57
74
|
}
|
|
58
|
-
function dependencies(
|
|
59
|
-
const claim = inv.claims.get(
|
|
75
|
+
function dependencies(ref18) {
|
|
76
|
+
const claim = inv.claims.get(ref18)?.value;
|
|
60
77
|
if (claim) return claim.kind === "source_assertion" ? [claim.provenance.sourceRef] : claim.inputRefs;
|
|
61
|
-
const measurement = inv.measurements.get(
|
|
78
|
+
const measurement = inv.measurements.get(ref18)?.value;
|
|
62
79
|
if (measurement) return measurement.sourceRefs;
|
|
63
|
-
const assertion = inv.assertions.get(
|
|
80
|
+
const assertion = inv.assertions.get(ref18)?.value;
|
|
64
81
|
if (assertion) return [assertion.provenance.sourceRef];
|
|
65
|
-
const product = inv.products.get(
|
|
82
|
+
const product = inv.products.get(ref18)?.value;
|
|
66
83
|
if (product) return product.kind === "raw" ? product.sourceRefs : [product.generatedBy];
|
|
67
|
-
return inv.processes.get(
|
|
84
|
+
return inv.processes.get(ref18)?.value.inputRefs ?? [];
|
|
68
85
|
}
|
|
69
86
|
function closure(roots) {
|
|
70
87
|
const seen = /* @__PURE__ */ new Set();
|
|
71
88
|
const queue = [...roots];
|
|
72
89
|
for (let i = 0; i < queue.length; i++) {
|
|
73
|
-
const
|
|
74
|
-
if (seen.has(
|
|
75
|
-
seen.add(
|
|
76
|
-
queue.push(...dependencies(
|
|
90
|
+
const ref18 = queue[i];
|
|
91
|
+
if (seen.has(ref18)) continue;
|
|
92
|
+
seen.add(ref18);
|
|
93
|
+
queue.push(...dependencies(ref18));
|
|
77
94
|
}
|
|
78
95
|
return seen;
|
|
79
96
|
}
|
|
80
97
|
for (const claimRef of parsed.currentClaimRefs) {
|
|
81
|
-
let checkMethod2 = function(
|
|
82
|
-
const method2 = inv.methods.get(
|
|
98
|
+
let checkMethod2 = function(ref18) {
|
|
99
|
+
const method2 = inv.methods.get(ref18);
|
|
83
100
|
if (method2 && !method2.value.description) issue("PROFILE.METHOD_CONTEXT", `${method2.pointer}/description`, "The referenced method needs a declared description; correctness is not verified.");
|
|
84
101
|
};
|
|
85
102
|
const entry = inv.claims.get(claimRef);
|
|
86
103
|
const claim = entry.value;
|
|
87
104
|
if (claim.kind !== "assessment") continue;
|
|
88
105
|
const report = { claimRef, status: "not_checked", inputRefs: [...claim.inputRefs], sourceRefs: [], productRefs: [], measurementRefs: [], assets: [], issues: [] };
|
|
89
|
-
const issue = (code, pointer6,
|
|
106
|
+
const issue = (code, pointer6, message2, stage = "profile", severity = "error") => report.issues.push({ code, pointer: pointer6, message: message2, stage, severity });
|
|
90
107
|
if (claim.status === "unassessed") {
|
|
91
108
|
issue("PROFILE.UNASSESSED", `${entry.pointer}/status`, "No evaluator assessment has been made.", "profile", "warning");
|
|
92
109
|
result.assessments.push(report);
|
|
93
110
|
continue;
|
|
94
111
|
}
|
|
95
112
|
const support = closure(claim.inputRefs);
|
|
96
|
-
report.sourceRefs = [...support].filter((
|
|
97
|
-
report.productRefs = [...support].filter((
|
|
98
|
-
report.measurementRefs = [...support].filter((
|
|
113
|
+
report.sourceRefs = [...support].filter((ref18) => inv.sources.has(ref18));
|
|
114
|
+
report.productRefs = [...support].filter((ref18) => inv.products.has(ref18));
|
|
115
|
+
report.measurementRefs = [...support].filter((ref18) => inv.measurements.has(ref18));
|
|
99
116
|
const requiredAssets = new Set(report.productRefs);
|
|
100
117
|
const located = /* @__PURE__ */ new Set();
|
|
101
118
|
checkMethod2(claim.methodRef);
|
|
102
|
-
for (const
|
|
103
|
-
const statement = inv.claims.get(
|
|
104
|
-
const assertion = inv.assertions.get(
|
|
119
|
+
for (const ref18 of support) {
|
|
120
|
+
const statement = inv.claims.get(ref18);
|
|
121
|
+
const assertion = inv.assertions.get(ref18);
|
|
105
122
|
const provenance = statement?.value.kind === "source_assertion" ? statement.value.provenance : assertion?.value.provenance;
|
|
106
123
|
const path2 = statement?.pointer ?? assertion?.pointer;
|
|
107
124
|
if (provenance && path2) {
|
|
@@ -109,28 +126,28 @@ async function evaluateAssessmentDocumentation(input, options = {}) {
|
|
|
109
126
|
if (!provenance.locator) issue("PROFILE.LOCATOR_REQUIRED", `${path2}/provenance/locator`, "A supporting statement or value assertion requires a source passage locator.");
|
|
110
127
|
else located.add(provenance.sourceRef);
|
|
111
128
|
}
|
|
112
|
-
const process = inv.processes.get(
|
|
129
|
+
const process = inv.processes.get(ref18)?.value;
|
|
113
130
|
if (process) checkMethod2(process.methodRef);
|
|
114
|
-
const measurement = inv.measurements.get(
|
|
131
|
+
const measurement = inv.measurements.get(ref18)?.value;
|
|
115
132
|
if (measurement?.selection) checkMethod2(measurement.selection.methodRef);
|
|
116
133
|
if (statement?.value.kind === "assessment" && statement.value.status === "assessed") checkMethod2(statement.value.methodRef);
|
|
117
134
|
}
|
|
118
|
-
for (const
|
|
119
|
-
const source = inv.sources.get(
|
|
135
|
+
for (const ref18 of report.sourceRefs) {
|
|
136
|
+
const source = inv.sources.get(ref18);
|
|
120
137
|
if (source.value.kind === "instrument_data") continue;
|
|
121
|
-
requiredAssets.add(
|
|
122
|
-
if (!located.has(
|
|
138
|
+
requiredAssets.add(ref18);
|
|
139
|
+
if (!located.has(ref18)) issue("PROFILE.LOCATOR_REQUIRED", source.pointer, "A directly cited documentary source needs a passage locator through an assertion.");
|
|
123
140
|
}
|
|
124
141
|
if (!claim.inputRefs.length || !requiredAssets.size) issue("PROFILE.INPUTS_REQUIRED", `${entry.pointer}/inputRefs`, "Assessment requires traceable source content or data products; descriptors alone are insufficient.");
|
|
125
142
|
if (claim.outcome === "confirmed") {
|
|
126
143
|
const measurementSubject = claim.subject.kind === "measurement" ? `measurement:${claim.subject.measurementId}` : void 0;
|
|
127
|
-
const relevant = report.measurementRefs.filter((
|
|
144
|
+
const relevant = report.measurementRefs.filter((ref18) => !measurementSubject || ref18 === measurementSubject);
|
|
128
145
|
if (!relevant.length) issue("PROFILE.MEASUREMENT_REQUIRED", `${entry.pointer}/inputRefs`, "A confirmed declaration requires a measurement input matching its subject.");
|
|
129
146
|
if (observation.eventTime.state !== "known" && observation.eventTime.state !== "approximate") issue("PROFILE.EVENT_TIME", "/observation/eventTime", "Instrument documentation requires a supplied event time; an archival unknown remains valid outside this profile.");
|
|
130
|
-
for (const
|
|
131
|
-
const measurement = inv.measurements.get(
|
|
147
|
+
for (const ref18 of relevant) {
|
|
148
|
+
const measurement = inv.measurements.get(ref18);
|
|
132
149
|
if (measurement.value.value.uncertainty.kind === "unknown") issue("PROFILE.MEASUREMENT_UNCERTAINTY", `${measurement.pointer}/value/uncertainty`, "Measurement uncertainty has not been characterized in the record.");
|
|
133
|
-
const lineage = closure([
|
|
150
|
+
const lineage = closure([ref18]);
|
|
134
151
|
if (![...lineage].some((item) => {
|
|
135
152
|
const raw = inv.products.get(item)?.value;
|
|
136
153
|
return raw?.kind === "raw" && raw.sourceRefs.some((source) => inv.sources.get(source)?.value.kind === "instrument_data");
|
|
@@ -147,34 +164,34 @@ async function evaluateAssessmentDocumentation(input, options = {}) {
|
|
|
147
164
|
if (measurement.value.value.uncertainty.kind !== "unknown") for (const source of measurement.value.value.uncertainty.sourceRefs) requiredAssets.add(source);
|
|
148
165
|
}
|
|
149
166
|
}
|
|
150
|
-
for (const
|
|
151
|
-
const asset = inv.sources.get(
|
|
167
|
+
for (const ref18 of requiredAssets) {
|
|
168
|
+
const asset = inv.sources.get(ref18) ?? inv.products.get(ref18);
|
|
152
169
|
if (!asset) continue;
|
|
153
|
-
const
|
|
154
|
-
const check = { ref:
|
|
155
|
-
if (
|
|
170
|
+
const digest12 = asset.value.digest?.value;
|
|
171
|
+
const check = { ref: ref18, status: "not_checked" };
|
|
172
|
+
if (digest12) check.expectedSha256 = digest12;
|
|
156
173
|
report.assets.push(check);
|
|
157
|
-
if (!
|
|
174
|
+
if (!digest12) {
|
|
158
175
|
issue("PROFILE.DIGEST_REQUIRED", `${asset.pointer}/digest`, "Supporting content requires a pinned SHA-256 digest.");
|
|
159
176
|
continue;
|
|
160
177
|
}
|
|
161
|
-
const
|
|
162
|
-
if (!
|
|
163
|
-
issue("EXTERNAL.ASSET_UNAVAILABLE", asset.pointer, `No local bytes supplied for ${
|
|
178
|
+
const bytes6 = assets2.get(ref18);
|
|
179
|
+
if (!bytes6) {
|
|
180
|
+
issue("EXTERNAL.ASSET_UNAVAILABLE", asset.pointer, `No local bytes supplied for ${ref18}; a URI or digest alone is not verification.`, "external", "warning");
|
|
164
181
|
continue;
|
|
165
182
|
}
|
|
166
|
-
if (!
|
|
183
|
+
if (!bytes6.length) {
|
|
167
184
|
check.status = "failed";
|
|
168
185
|
issue("EXTERNAL.EMPTY_ASSET", asset.pointer, "Empty content cannot support this assessment.", "external");
|
|
169
186
|
continue;
|
|
170
187
|
}
|
|
171
|
-
const actual = await
|
|
188
|
+
const actual = await hash8(ref18);
|
|
172
189
|
if (!actual) {
|
|
173
190
|
issue("EXTERNAL.HASH_UNAVAILABLE", asset.pointer, "SHA-256 verification is unavailable in this runtime.", "external", "warning");
|
|
174
191
|
continue;
|
|
175
192
|
}
|
|
176
193
|
check.actualSha256 = actual;
|
|
177
|
-
check.status = actual ===
|
|
194
|
+
check.status = actual === digest12 ? "passed" : "failed";
|
|
178
195
|
if (check.status === "failed") issue("EXTERNAL.DIGEST_MISMATCH", `${asset.pointer}/digest`, "Supplied bytes do not match the pinned SHA-256 digest.", "external");
|
|
179
196
|
}
|
|
180
197
|
report.status = report.issues.some((item) => item.severity === "error") ? "failed" : report.assets.some((asset) => asset.status === "not_checked") ? "not_checked" : "passed";
|
|
@@ -202,7 +219,7 @@ var AcquisitionBindingsSchema = z.strictObject({
|
|
|
202
219
|
extensions: z.record(z.string().regex(/^[a-z][a-z0-9_-]*(?:\.[a-z0-9_-]+)+(?![\s\S])/), z.json()).optional()
|
|
203
220
|
});
|
|
204
221
|
function acquisitionBindingsJsonSchema() {
|
|
205
|
-
return { ...z.toJSONSchema(AcquisitionBindingsSchema, { target: "draft-2020-12" }), $id: ACQUISITION_BINDINGS_SCHEMA_ID };
|
|
222
|
+
return { ...preservePublishedSchema(z.toJSONSchema(AcquisitionBindingsSchema, { target: "draft-2020-12" })), $id: ACQUISITION_BINDINGS_SCHEMA_ID };
|
|
206
223
|
}
|
|
207
224
|
var ACQUISITION_BINDINGS_PROFILE = Object.freeze({
|
|
208
225
|
id: "urn:disclosureos:experimental:profile:acquisition-bindings",
|
|
@@ -238,7 +255,7 @@ async function evaluateAcquisitionBindings(historyInput, contextInput, bindingsI
|
|
|
238
255
|
}
|
|
239
256
|
const bindingData = bindingParse.data;
|
|
240
257
|
const observation = history.data.observation;
|
|
241
|
-
const issue = (code, path2,
|
|
258
|
+
const issue = (code, path2, message2, stage = "semantic", severity = "error") => result.issues.push({ code, stage, severity, pointer: path2, message: message2 });
|
|
242
259
|
for (const [field2, expected] of [["historyId", history.data.id], ["observationId", observation.id], ["contextId", context.data.id]]) {
|
|
243
260
|
if (bindingData[field2] !== expected) issue("BINDING.DOCUMENT_ID", `/bindings/${field2}`, "Binding document identifies a different input document.");
|
|
244
261
|
}
|
|
@@ -279,11 +296,11 @@ async function evaluateAcquisitionBindings(historyInput, contextInput, bindingsI
|
|
|
279
296
|
}
|
|
280
297
|
if (product.digest && product.digest.value !== target.artifact.digest.value) issue("BINDING.DIGEST_MISMATCH", path2, "The linked product declarations pin different SHA-256 digests.");
|
|
281
298
|
if (product.format !== target.artifact.mediaType) issue("BINDING.FORMAT_MISMATCH", path2, "Declared product format and context media type must match exactly; no format conversion is inferred.");
|
|
282
|
-
const producingSources = product.sourceRefs.filter((
|
|
299
|
+
const producingSources = product.sourceRefs.filter((ref18) => sources.get(ref18)?.kind === "instrument_data");
|
|
283
300
|
if (!producingSources.length) issue("BINDING.SOURCE_KIND", `${path2}/observationProductRef`, "Raw product does not declare an instrument-data source.");
|
|
284
301
|
const acquisition = acquisitions.get(target.acquisitionRef);
|
|
285
|
-
for (const
|
|
286
|
-
const instrument = sourceBindings.get(
|
|
302
|
+
for (const ref18 of producingSources) {
|
|
303
|
+
const instrument = sourceBindings.get(ref18);
|
|
287
304
|
if (instrument && instrument !== acquisition.instrumentRef) issue("BINDING.SOURCE_IDENTITY", path2, "A producing source is mapped to a different instrument than the product acquisition.");
|
|
288
305
|
}
|
|
289
306
|
}
|
|
@@ -292,13 +309,13 @@ async function evaluateAcquisitionBindings(historyInput, contextInput, bindingsI
|
|
|
292
309
|
return result;
|
|
293
310
|
}
|
|
294
311
|
result.checks.semantic = "passed";
|
|
295
|
-
const required = [...products].filter(([, entry]) => entry.value.kind === "raw" && entry.value.sourceRefs.some((
|
|
296
|
-
for (const [
|
|
312
|
+
const required = [...products].filter(([, entry]) => entry.value.kind === "raw" && entry.value.sourceRefs.some((ref18) => sources.get(ref18)?.kind === "instrument_data"));
|
|
313
|
+
for (const [ref18, entry] of required) if (!observationBindings.has(ref18)) issue("BINDING.PRODUCT_REQUIRED", entry.pointer, "Instrument raw product needs an explicit acquisition-product binding.", "profile");
|
|
297
314
|
if (!required.length) issue("BINDING.NO_INSTRUMENT_PRODUCTS", "/history/observation/products", "No instrument raw products are present to evaluate.", "profile", "warning");
|
|
298
315
|
const artifacts = /* @__PURE__ */ new Map();
|
|
299
|
-
const register = (
|
|
300
|
-
artifacts.set(
|
|
301
|
-
if (!report.assetRefs.includes(
|
|
316
|
+
const register = (ref18, artifact2, path2, report) => {
|
|
317
|
+
artifacts.set(ref18, { artifact: artifact2, pointer: path2 });
|
|
318
|
+
if (!report.assetRefs.includes(ref18)) report.assetRefs.push(ref18);
|
|
302
319
|
};
|
|
303
320
|
for (const [i, binding] of bindingData.products.entries()) {
|
|
304
321
|
const product = products.get(binding.observationProductRef);
|
|
@@ -306,10 +323,10 @@ async function evaluateAcquisitionBindings(historyInput, contextInput, bindingsI
|
|
|
306
323
|
const acquisition = acquisitions.get(target.value.acquisitionRef);
|
|
307
324
|
const resolution = resolutions.get(target.value.acquisitionRef);
|
|
308
325
|
const report = { ...binding, acquisitionRef: target.value.acquisitionRef, instrumentRef: acquisition.instrumentRef, assetRefs: [], status: "not_checked", issues: [] };
|
|
309
|
-
const fail = (code, path2,
|
|
326
|
+
const fail = (code, path2, message2) => report.issues.push({ code, stage: "profile", severity: "error", pointer: path2, message: message2 });
|
|
310
327
|
if (!product.value.digest) fail("BINDING.DIGEST_REQUIRED", `${product.pointer}/digest`, "Observation product must pin the same bytes as its context product.");
|
|
311
328
|
if (product.value.kind === "raw") {
|
|
312
|
-
for (const
|
|
329
|
+
for (const ref18 of product.value.sourceRefs) if (sources.get(ref18)?.kind === "instrument_data" && !sourceBindings.has(ref18)) {
|
|
313
330
|
fail("BINDING.SOURCE_REQUIRED", `/bindings/products/${i}`, "Each declared producing instrument source needs an explicit instrument binding.");
|
|
314
331
|
}
|
|
315
332
|
}
|
|
@@ -319,31 +336,31 @@ async function evaluateAcquisitionBindings(historyInput, contextInput, bindingsI
|
|
|
319
336
|
const manifest = manifests.get(acquisition.manifest.ref);
|
|
320
337
|
register(acquisition.manifest.ref, manifest.value.artifact, `${manifest.pointer}/artifact`, report);
|
|
321
338
|
}
|
|
322
|
-
for (const
|
|
323
|
-
const calibration = calibrations.get(
|
|
324
|
-
if (calibration.value.report.state === "known") register(`${
|
|
325
|
-
if (calibration.value.review.state === "reviewed") register(`${
|
|
339
|
+
for (const ref18 of resolution.calibrationRefs) {
|
|
340
|
+
const calibration = calibrations.get(ref18);
|
|
341
|
+
if (calibration.value.report.state === "known") register(`${ref18}/report`, calibration.value.report.artifact, `${calibration.pointer}/report/artifact`, report);
|
|
342
|
+
if (calibration.value.review.state === "reviewed") register(`${ref18}/review`, calibration.value.review.report, `${calibration.pointer}/review/report`, report);
|
|
326
343
|
}
|
|
327
344
|
result.bindings.push(report);
|
|
328
345
|
}
|
|
329
|
-
const assets2 = new Map([...options.assets ?? []].map(([
|
|
330
|
-
for (const [
|
|
331
|
-
const check = { ref:
|
|
346
|
+
const assets2 = new Map([...options.assets ?? []].map(([ref18, bytes6]) => [ref18, Uint8Array.from(bytes6)]));
|
|
347
|
+
for (const [ref18, entry] of artifacts) {
|
|
348
|
+
const check = { ref: ref18, status: "not_checked", pointer: entry.pointer, expectedSha256: entry.artifact.digest.value, expectedByteLength: entry.artifact.byteLength };
|
|
332
349
|
result.assets.push(check);
|
|
333
|
-
const
|
|
334
|
-
if (!
|
|
335
|
-
issue("EXTERNAL.ASSET_UNAVAILABLE", entry.pointer, `No complete local bytes supplied for ${
|
|
350
|
+
const bytes6 = assets2.get(ref18);
|
|
351
|
+
if (!bytes6) {
|
|
352
|
+
issue("EXTERNAL.ASSET_UNAVAILABLE", entry.pointer, `No complete local bytes supplied for ${ref18}.`, "external", "warning");
|
|
336
353
|
continue;
|
|
337
354
|
}
|
|
338
|
-
check.actualByteLength =
|
|
339
|
-
if (!
|
|
355
|
+
check.actualByteLength = bytes6.byteLength;
|
|
356
|
+
if (!bytes6.byteLength || bytes6.byteLength !== entry.artifact.byteLength) {
|
|
340
357
|
check.status = "failed";
|
|
341
|
-
issue(!
|
|
358
|
+
issue(!bytes6.byteLength ? "EXTERNAL.EMPTY_ASSET" : "EXTERNAL.SIZE_MISMATCH", entry.pointer, "Supplied nonempty bytes must match the declared byte length.", "external");
|
|
342
359
|
continue;
|
|
343
360
|
}
|
|
344
361
|
try {
|
|
345
|
-
const
|
|
346
|
-
check.actualSha256 = [...new Uint8Array(
|
|
362
|
+
const digest12 = await globalThis.crypto.subtle.digest("SHA-256", bytes6);
|
|
363
|
+
check.actualSha256 = [...new Uint8Array(digest12)].map((value) => value.toString(16).padStart(2, "0")).join("");
|
|
347
364
|
check.status = check.actualSha256 === entry.artifact.digest.value ? "passed" : "failed";
|
|
348
365
|
if (check.status === "failed") issue("EXTERNAL.DIGEST_MISMATCH", entry.pointer, "Supplied bytes do not match the pinned SHA-256 digest.", "external");
|
|
349
366
|
} catch {
|
|
@@ -352,7 +369,7 @@ async function evaluateAcquisitionBindings(historyInput, contextInput, bindingsI
|
|
|
352
369
|
}
|
|
353
370
|
const assetChecks = new Map(result.assets.map((check) => [check.ref, check]));
|
|
354
371
|
for (const report of result.bindings) {
|
|
355
|
-
const statuses = report.assetRefs.map((
|
|
372
|
+
const statuses = report.assetRefs.map((ref18) => assetChecks.get(ref18).status);
|
|
356
373
|
report.status = report.issues.length || statuses.includes("failed") ? "failed" : statuses.includes("not_checked") ? "not_checked" : "passed";
|
|
357
374
|
result.issues.push(...report.issues);
|
|
358
375
|
}
|
|
@@ -409,7 +426,7 @@ var MeasurementBindingsSchema = z.strictObject({
|
|
|
409
426
|
});
|
|
410
427
|
function measurementBindingsJsonSchema() {
|
|
411
428
|
return {
|
|
412
|
-
...z.toJSONSchema(MeasurementBindingsSchema, { target: "draft-2020-12" }),
|
|
429
|
+
...preservePublishedSchema(z.toJSONSchema(MeasurementBindingsSchema, { target: "draft-2020-12" })),
|
|
413
430
|
$id: MEASUREMENT_BINDINGS_SCHEMA_ID
|
|
414
431
|
};
|
|
415
432
|
}
|
|
@@ -438,12 +455,12 @@ async function evaluateMeasurementBindings(historyInput, contextInput, acquisiti
|
|
|
438
455
|
clockUncertainty: "not_checked",
|
|
439
456
|
artifactContents: "not_checked"
|
|
440
457
|
};
|
|
441
|
-
const issue = (code, path2,
|
|
458
|
+
const issue = (code, path2, message2, stage = "semantic") => result.issues.push({
|
|
442
459
|
code,
|
|
443
460
|
stage,
|
|
444
461
|
severity: "error",
|
|
445
462
|
pointer: path2,
|
|
446
|
-
message
|
|
463
|
+
message: message2
|
|
447
464
|
});
|
|
448
465
|
for (const [parsed, prefix] of [
|
|
449
466
|
[h, "/history"],
|
|
@@ -505,16 +522,16 @@ async function evaluateMeasurementBindings(historyInput, contextInput, acquisiti
|
|
|
505
522
|
const queue = [...refs], seen2 = /* @__PURE__ */ new Set(), raw = /* @__PURE__ */ new Set();
|
|
506
523
|
let instrument = false;
|
|
507
524
|
while (queue.length) {
|
|
508
|
-
const
|
|
509
|
-
if (seen2.has(
|
|
510
|
-
seen2.add(
|
|
511
|
-
const source = sources.get(
|
|
525
|
+
const ref18 = queue.pop();
|
|
526
|
+
if (seen2.has(ref18)) continue;
|
|
527
|
+
seen2.add(ref18);
|
|
528
|
+
const source = sources.get(ref18);
|
|
512
529
|
if (source?.kind === "instrument_data") instrument = true;
|
|
513
|
-
const assertion = assertions.get(
|
|
530
|
+
const assertion = assertions.get(ref18);
|
|
514
531
|
if (assertion) queue.push(assertion.provenance.sourceRef);
|
|
515
|
-
const product = products.get(
|
|
532
|
+
const product = products.get(ref18);
|
|
516
533
|
if (product?.kind === "raw") {
|
|
517
|
-
raw.add(
|
|
534
|
+
raw.add(ref18);
|
|
518
535
|
queue.push(...product.sourceRefs);
|
|
519
536
|
} else if (product?.kind === "derived")
|
|
520
537
|
queue.push(...processes.get(product.generatedBy).inputRefs);
|
|
@@ -548,7 +565,7 @@ async function evaluateMeasurementBindings(historyInput, contextInput, acquisiti
|
|
|
548
565
|
"Bound raw product must occur in primary measurement lineage; uncertainty and unused assertions do not supply support."
|
|
549
566
|
);
|
|
550
567
|
const instrumentRaw = [...support.raw].filter(
|
|
551
|
-
(
|
|
568
|
+
(ref18) => products.get(ref18)?.kind === "raw" && lineage([ref18]).instrument
|
|
552
569
|
);
|
|
553
570
|
if (instrumentRaw.length > 1)
|
|
554
571
|
issue(
|
|
@@ -571,8 +588,8 @@ async function evaluateMeasurementBindings(historyInput, contextInput, acquisiti
|
|
|
571
588
|
);
|
|
572
589
|
continue;
|
|
573
590
|
}
|
|
574
|
-
const
|
|
575
|
-
const manifest =
|
|
591
|
+
const pin5 = acquisition2.manifest;
|
|
592
|
+
const manifest = pin5.state === "pinned" ? c.data.manifests.find((p) => `manifest:${p.id}` === pin5.ref) : void 0;
|
|
576
593
|
const channel = manifest?.channels.find((p) => p.id === binding.channelId);
|
|
577
594
|
if (!channel || !acquisition2.channels.some((p) => p.channelId === binding.channelId))
|
|
578
595
|
issue(
|
|
@@ -637,14 +654,14 @@ async function evaluateMeasurementBindings(historyInput, contextInput, acquisiti
|
|
|
637
654
|
);
|
|
638
655
|
}
|
|
639
656
|
let applicable = 0;
|
|
640
|
-
for (const [
|
|
657
|
+
for (const [ref18, measurement] of measurements)
|
|
641
658
|
if (lineage(measurement.sourceRefs).instrument) {
|
|
642
659
|
applicable++;
|
|
643
|
-
if (!seen.has(
|
|
660
|
+
if (!seen.has(ref18))
|
|
644
661
|
issue(
|
|
645
662
|
"MEASUREMENT.REQUIRED",
|
|
646
663
|
"/measurements/measurements",
|
|
647
|
-
`Instrument-supported ${
|
|
664
|
+
`Instrument-supported ${ref18} needs an explicit channel and capture-time mapping.`,
|
|
648
665
|
"profile"
|
|
649
666
|
);
|
|
650
667
|
}
|
|
@@ -751,15 +768,15 @@ var InstrumentResearchReviewSchema = z.strictObject({
|
|
|
751
768
|
});
|
|
752
769
|
function instrumentResearchReviewJsonSchema() {
|
|
753
770
|
return {
|
|
754
|
-
...z.toJSONSchema(InstrumentResearchReviewSchema, {
|
|
771
|
+
...preservePublishedSchema(z.toJSONSchema(InstrumentResearchReviewSchema, {
|
|
755
772
|
target: "draft-2020-12"
|
|
756
|
-
}),
|
|
773
|
+
})),
|
|
757
774
|
$id: INSTRUMENT_RESEARCH_REVIEW_SCHEMA_ID
|
|
758
775
|
};
|
|
759
776
|
}
|
|
760
777
|
var pointer3 = (path2) => path2.map((p) => `/${String(p).replace(/~/g, "~0").replace(/\//g, "~1")}`).join("");
|
|
761
778
|
var snapshot = (assets2) => new Map(
|
|
762
|
-
[...assets2 ?? []].map(([
|
|
779
|
+
[...assets2 ?? []].map(([ref18, bytes6]) => [ref18, Uint8Array.from(bytes6)])
|
|
763
780
|
);
|
|
764
781
|
async function evaluateInstrumentResearchPrerequisites(historyInput, contextInput, acquisitionBindingsInput, measurementBindingsInput, reviewInput, options = {}) {
|
|
765
782
|
const h = parseExperimentalClaimHistory(historyInput), c = parseAcquisitionContext(contextInput), a = AcquisitionBindingsSchema.safeParse(acquisitionBindingsInput), m = MeasurementBindingsSchema.safeParse(measurementBindingsInput), r = InstrumentResearchReviewSchema.safeParse(reviewInput);
|
|
@@ -786,7 +803,7 @@ async function evaluateInstrumentResearchPrerequisites(historyInput, contextInpu
|
|
|
786
803
|
timingModel: "not_checked",
|
|
787
804
|
reviewerAuthenticity: "not_checked"
|
|
788
805
|
};
|
|
789
|
-
const issue = (code, path2,
|
|
806
|
+
const issue = (code, path2, message2, stage = "profile", severity = "error") => result.issues.push({ code, stage, severity, pointer: path2, message: message2 });
|
|
790
807
|
for (const [parsed, prefix] of [
|
|
791
808
|
[h, "/history"],
|
|
792
809
|
[c, "/context"]
|
|
@@ -831,7 +848,7 @@ async function evaluateInstrumentResearchPrerequisites(historyInput, contextInpu
|
|
|
831
848
|
"semantic"
|
|
832
849
|
);
|
|
833
850
|
const artifacts = /* @__PURE__ */ new Map();
|
|
834
|
-
const inspectReview = (value,
|
|
851
|
+
const inspectReview = (value, ref18, path2, notBefore) => {
|
|
835
852
|
if (value.state !== "reviewed") {
|
|
836
853
|
issue(
|
|
837
854
|
"RESEARCH.REVIEW_REQUIRED",
|
|
@@ -860,7 +877,7 @@ async function evaluateInstrumentResearchPrerequisites(historyInput, contextInpu
|
|
|
860
877
|
`${path2}/outcome`,
|
|
861
878
|
"Rejected or inconclusive review cannot satisfy the prerequisites."
|
|
862
879
|
);
|
|
863
|
-
artifacts.set(
|
|
880
|
+
artifacts.set(ref18, { value: value.report, path: `${path2}/report` });
|
|
864
881
|
};
|
|
865
882
|
const seen = /* @__PURE__ */ new Set();
|
|
866
883
|
for (const [i, entry] of r.data.measurements.entries()) {
|
|
@@ -1045,27 +1062,27 @@ async function evaluateInstrumentResearchPrerequisites(historyInput, contextInpu
|
|
|
1045
1062
|
})),
|
|
1046
1063
|
...measurements.issues
|
|
1047
1064
|
);
|
|
1048
|
-
for (const [
|
|
1065
|
+
for (const [ref18, { value, path: path2 }] of artifacts) {
|
|
1049
1066
|
const check = {
|
|
1050
|
-
ref:
|
|
1067
|
+
ref: ref18,
|
|
1051
1068
|
status: "not_checked",
|
|
1052
1069
|
expectedSha256: value.digest.value,
|
|
1053
1070
|
expectedByteLength: value.byteLength
|
|
1054
1071
|
};
|
|
1055
1072
|
result.reviewAssets.push(check);
|
|
1056
|
-
const
|
|
1057
|
-
if (!
|
|
1073
|
+
const bytes6 = reviewAssets.get(ref18);
|
|
1074
|
+
if (!bytes6) {
|
|
1058
1075
|
issue(
|
|
1059
1076
|
"RESEARCH.REPORT_UNAVAILABLE",
|
|
1060
1077
|
path2,
|
|
1061
|
-
`No local bytes supplied for ${
|
|
1078
|
+
`No local bytes supplied for ${ref18}.`,
|
|
1062
1079
|
"external",
|
|
1063
1080
|
"warning"
|
|
1064
1081
|
);
|
|
1065
1082
|
continue;
|
|
1066
1083
|
}
|
|
1067
|
-
check.actualByteLength =
|
|
1068
|
-
if (
|
|
1084
|
+
check.actualByteLength = bytes6.byteLength;
|
|
1085
|
+
if (bytes6.byteLength !== value.byteLength) {
|
|
1069
1086
|
check.status = "failed";
|
|
1070
1087
|
issue(
|
|
1071
1088
|
"RESEARCH.REPORT_SIZE",
|
|
@@ -1076,8 +1093,8 @@ async function evaluateInstrumentResearchPrerequisites(historyInput, contextInpu
|
|
|
1076
1093
|
continue;
|
|
1077
1094
|
}
|
|
1078
1095
|
try {
|
|
1079
|
-
const
|
|
1080
|
-
check.actualSha256 = [...new Uint8Array(
|
|
1096
|
+
const hash8 = await globalThis.crypto.subtle.digest("SHA-256", bytes6);
|
|
1097
|
+
check.actualSha256 = [...new Uint8Array(hash8)].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1081
1098
|
check.status = check.actualSha256 === value.digest.value ? "passed" : "failed";
|
|
1082
1099
|
if (check.status === "failed")
|
|
1083
1100
|
issue(
|
|
@@ -1155,7 +1172,7 @@ var ReproductionPacketSchema = z.strictObject({
|
|
|
1155
1172
|
});
|
|
1156
1173
|
function reproductionPacketJsonSchema() {
|
|
1157
1174
|
return {
|
|
1158
|
-
...z.toJSONSchema(ReproductionPacketSchema, { target: "draft-2020-12" }),
|
|
1175
|
+
...preservePublishedSchema(z.toJSONSchema(ReproductionPacketSchema, { target: "draft-2020-12" })),
|
|
1159
1176
|
$id: REPRODUCTION_PACKET_SCHEMA_ID
|
|
1160
1177
|
};
|
|
1161
1178
|
}
|
|
@@ -1181,7 +1198,7 @@ async function evaluateReproductionPacket(input, options = {}) {
|
|
|
1181
1198
|
environmentExecution: "not_checked",
|
|
1182
1199
|
scientificEligibility: "not_checked"
|
|
1183
1200
|
};
|
|
1184
|
-
const issue = (code, pointer6,
|
|
1201
|
+
const issue = (code, pointer6, message2) => result.issues.push({ code, pointer: pointer6, message: message2 });
|
|
1185
1202
|
if (!parsed.success) {
|
|
1186
1203
|
result.checks.structural = "failed";
|
|
1187
1204
|
for (const i of parsed.error.issues)
|
|
@@ -1202,13 +1219,13 @@ async function evaluateReproductionPacket(input, options = {}) {
|
|
|
1202
1219
|
inventory.add(file.id);
|
|
1203
1220
|
}
|
|
1204
1221
|
const used = /* @__PURE__ */ new Set();
|
|
1205
|
-
const requireRef = (
|
|
1206
|
-
used.add(
|
|
1207
|
-
if (!inventory.has(
|
|
1222
|
+
const requireRef = (ref18, path2) => {
|
|
1223
|
+
used.add(ref18);
|
|
1224
|
+
if (!inventory.has(ref18))
|
|
1208
1225
|
issue("PACKET.REFERENCE", path2, "File reference is not inventoried.");
|
|
1209
1226
|
};
|
|
1210
|
-
for (const [name,
|
|
1211
|
-
requireRef(
|
|
1227
|
+
for (const [name, ref18] of Object.entries(packet.documents))
|
|
1228
|
+
requireRef(ref18, `/documents/${name}`);
|
|
1212
1229
|
for (const [namespace, entries] of Object.entries(packet.assets)) {
|
|
1213
1230
|
const seen = /* @__PURE__ */ new Set();
|
|
1214
1231
|
for (const [i, entry] of entries.entries()) {
|
|
@@ -1239,12 +1256,12 @@ async function evaluateReproductionPacket(input, options = {}) {
|
|
|
1239
1256
|
`/method/implementations/${i}/environmentRef`
|
|
1240
1257
|
);
|
|
1241
1258
|
}
|
|
1242
|
-
for (const
|
|
1243
|
-
if (!used.has(
|
|
1259
|
+
for (const ref18 of inventory)
|
|
1260
|
+
if (!used.has(ref18))
|
|
1244
1261
|
issue(
|
|
1245
1262
|
"PACKET.UNUSED_FILE",
|
|
1246
1263
|
"/files",
|
|
1247
|
-
`Unreferenced file ${
|
|
1264
|
+
`Unreferenced file ${ref18}; inventory must describe the evaluated packet.`
|
|
1248
1265
|
);
|
|
1249
1266
|
if (result.issues.length) {
|
|
1250
1267
|
result.checks.semantic = "failed";
|
|
@@ -1252,9 +1269,9 @@ async function evaluateReproductionPacket(input, options = {}) {
|
|
|
1252
1269
|
}
|
|
1253
1270
|
result.checks.semantic = "passed";
|
|
1254
1271
|
const files = new Map(
|
|
1255
|
-
[...options.files ?? []].map(([
|
|
1256
|
-
|
|
1257
|
-
Uint8Array.from(
|
|
1272
|
+
[...options.files ?? []].map(([id26, bytes6]) => [
|
|
1273
|
+
id26,
|
|
1274
|
+
Uint8Array.from(bytes6)
|
|
1258
1275
|
])
|
|
1259
1276
|
);
|
|
1260
1277
|
for (const [i, file] of packet.files.entries()) {
|
|
@@ -1265,8 +1282,8 @@ async function evaluateReproductionPacket(input, options = {}) {
|
|
|
1265
1282
|
expectedByteLength: file.byteLength
|
|
1266
1283
|
};
|
|
1267
1284
|
result.files.push(check);
|
|
1268
|
-
const
|
|
1269
|
-
if (!
|
|
1285
|
+
const bytes6 = files.get(file.id);
|
|
1286
|
+
if (!bytes6) {
|
|
1270
1287
|
issue(
|
|
1271
1288
|
"PACKET.MISSING_FILE",
|
|
1272
1289
|
`/files/${i}`,
|
|
@@ -1274,8 +1291,8 @@ async function evaluateReproductionPacket(input, options = {}) {
|
|
|
1274
1291
|
);
|
|
1275
1292
|
continue;
|
|
1276
1293
|
}
|
|
1277
|
-
check.actualByteLength =
|
|
1278
|
-
if (
|
|
1294
|
+
check.actualByteLength = bytes6.byteLength;
|
|
1295
|
+
if (bytes6.byteLength !== file.byteLength) {
|
|
1279
1296
|
check.status = "failed";
|
|
1280
1297
|
issue(
|
|
1281
1298
|
"PACKET.SIZE",
|
|
@@ -1285,8 +1302,8 @@ async function evaluateReproductionPacket(input, options = {}) {
|
|
|
1285
1302
|
continue;
|
|
1286
1303
|
}
|
|
1287
1304
|
try {
|
|
1288
|
-
const
|
|
1289
|
-
check.actualSha256 = [...new Uint8Array(
|
|
1305
|
+
const digest12 = await globalThis.crypto.subtle.digest("SHA-256", bytes6);
|
|
1306
|
+
check.actualSha256 = [...new Uint8Array(digest12)].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1290
1307
|
check.status = check.actualSha256 === file.sha256 ? "passed" : "failed";
|
|
1291
1308
|
if (check.status === "failed")
|
|
1292
1309
|
issue(
|
|
@@ -1309,13 +1326,13 @@ async function evaluateReproductionPacket(input, options = {}) {
|
|
|
1309
1326
|
}
|
|
1310
1327
|
if (result.files.some((f) => f.status === "not_checked")) return result;
|
|
1311
1328
|
const documents = {};
|
|
1312
|
-
for (const [name,
|
|
1329
|
+
for (const [name, ref18] of Object.entries(packet.documents))
|
|
1313
1330
|
try {
|
|
1314
|
-
const
|
|
1331
|
+
const bytes6 = files.get(ref18);
|
|
1315
1332
|
const decoded = new TextDecoder("utf-8", {
|
|
1316
1333
|
fatal: true,
|
|
1317
1334
|
ignoreBOM: true
|
|
1318
|
-
}).decode(
|
|
1335
|
+
}).decode(bytes6);
|
|
1319
1336
|
documents[name] = JSON.parse(decoded);
|
|
1320
1337
|
} catch {
|
|
1321
1338
|
issue(
|
|
@@ -1426,13 +1443,13 @@ var DatasetReleaseSchema = z.strictObject({
|
|
|
1426
1443
|
});
|
|
1427
1444
|
function datasetReleaseJsonSchema() {
|
|
1428
1445
|
return {
|
|
1429
|
-
...z.toJSONSchema(DatasetReleaseSchema, { target: "draft-2020-12" }),
|
|
1446
|
+
...preservePublishedSchema(z.toJSONSchema(DatasetReleaseSchema, { target: "draft-2020-12" })),
|
|
1430
1447
|
$id: DATASET_RELEASE_SCHEMA_ID
|
|
1431
1448
|
};
|
|
1432
1449
|
}
|
|
1433
1450
|
var pointer4 = (path2) => path2.map((p) => `/${String(p).replace(/~/g, "~0").replace(/\//g, "~1")}`).join("");
|
|
1434
|
-
var decode = (
|
|
1435
|
-
new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(
|
|
1451
|
+
var decode = (bytes6) => JSON.parse(
|
|
1452
|
+
new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes6)
|
|
1436
1453
|
);
|
|
1437
1454
|
async function evaluateDatasetRelease(input, options = {}) {
|
|
1438
1455
|
const parsed = DatasetReleaseSchema.safeParse(input);
|
|
@@ -1453,7 +1470,7 @@ async function evaluateDatasetRelease(input, options = {}) {
|
|
|
1453
1470
|
authorization: "not_checked",
|
|
1454
1471
|
crossInstrumentIdentity: "not_checked"
|
|
1455
1472
|
};
|
|
1456
|
-
const issue = (code, path2,
|
|
1473
|
+
const issue = (code, path2, message2, stage = "semantic") => result.issues.push({ code, pointer: path2, message: message2, stage });
|
|
1457
1474
|
if (!parsed.success) {
|
|
1458
1475
|
result.checks.structural = "failed";
|
|
1459
1476
|
for (const i of parsed.error.issues)
|
|
@@ -1516,11 +1533,11 @@ async function evaluateDatasetRelease(input, options = {}) {
|
|
|
1516
1533
|
return result;
|
|
1517
1534
|
}
|
|
1518
1535
|
const packets = new Map(
|
|
1519
|
-
[...options.packets ?? []].map(([
|
|
1520
|
-
|
|
1536
|
+
[...options.packets ?? []].map(([id26, p]) => [
|
|
1537
|
+
id26,
|
|
1521
1538
|
{
|
|
1522
1539
|
manifest: Uint8Array.from(p.manifest),
|
|
1523
|
-
files: new Map([...p.files].map(([
|
|
1540
|
+
files: new Map([...p.files].map(([id27, b]) => [id27, Uint8Array.from(b)]))
|
|
1524
1541
|
}
|
|
1525
1542
|
])
|
|
1526
1543
|
);
|
|
@@ -1689,8 +1706,8 @@ async function evaluateDatasetRelease(input, options = {}) {
|
|
|
1689
1706
|
continue;
|
|
1690
1707
|
}
|
|
1691
1708
|
member.classification = acquisition.classification;
|
|
1692
|
-
const
|
|
1693
|
-
const assigned = canonicalSessions.get(
|
|
1709
|
+
const canonical2 = `${context.id}/${m.acquisitionRef}`;
|
|
1710
|
+
const assigned = canonicalSessions.get(canonical2);
|
|
1694
1711
|
if (assigned && assigned !== s.id) {
|
|
1695
1712
|
member.status = "failed";
|
|
1696
1713
|
issue(
|
|
@@ -1700,7 +1717,7 @@ async function evaluateDatasetRelease(input, options = {}) {
|
|
|
1700
1717
|
);
|
|
1701
1718
|
continue;
|
|
1702
1719
|
}
|
|
1703
|
-
canonicalSessions.set(
|
|
1720
|
+
canonicalSessions.set(canonical2, s.id);
|
|
1704
1721
|
const t = acquisition.time;
|
|
1705
1722
|
if (t.state === "unknown" || s.time.state === "unknown") continue;
|
|
1706
1723
|
const start = t.kind === "instant" ? t.value : t.start, end = t.kind === "instant" ? t.value : t.end;
|
|
@@ -1804,7 +1821,7 @@ var SourceIntakeSchema = z.strictObject({
|
|
|
1804
1821
|
});
|
|
1805
1822
|
function sourceIntakeJsonSchema() {
|
|
1806
1823
|
return {
|
|
1807
|
-
...z.toJSONSchema(SourceIntakeSchema, { target: "draft-2020-12" }),
|
|
1824
|
+
...preservePublishedSchema(z.toJSONSchema(SourceIntakeSchema, { target: "draft-2020-12" })),
|
|
1808
1825
|
$id: SOURCE_INTAKE_SCHEMA_ID
|
|
1809
1826
|
};
|
|
1810
1827
|
}
|
|
@@ -1828,7 +1845,7 @@ async function evaluateSourceIntake(input, options = {}) {
|
|
|
1828
1845
|
artifactContents: "not_checked",
|
|
1829
1846
|
authorization: "not_checked"
|
|
1830
1847
|
};
|
|
1831
|
-
const issue = (code, stage, path2,
|
|
1848
|
+
const issue = (code, stage, path2, message2) => result.issues.push({ code, stage, pointer: path2, message: message2 });
|
|
1832
1849
|
if (!parsed.success) {
|
|
1833
1850
|
result.checks.structural = "failed";
|
|
1834
1851
|
for (const i of parsed.error.issues)
|
|
@@ -1911,7 +1928,7 @@ async function evaluateSourceIntake(input, options = {}) {
|
|
|
1911
1928
|
}
|
|
1912
1929
|
result.checks.semantic = "passed";
|
|
1913
1930
|
const files = new Map(
|
|
1914
|
-
[...options.files ?? []].map(([
|
|
1931
|
+
[...options.files ?? []].map(([id26, b]) => [id26, Uint8Array.from(b)])
|
|
1915
1932
|
);
|
|
1916
1933
|
for (const [i, a] of data.artifacts.entries()) {
|
|
1917
1934
|
const path2 = `/artifacts/${i}`, check = {
|
|
@@ -1921,8 +1938,8 @@ async function evaluateSourceIntake(input, options = {}) {
|
|
|
1921
1938
|
expectedByteLength: a.byteLength
|
|
1922
1939
|
};
|
|
1923
1940
|
result.files.push(check);
|
|
1924
|
-
const
|
|
1925
|
-
if (!
|
|
1941
|
+
const bytes6 = files.get(a.id);
|
|
1942
|
+
if (!bytes6) {
|
|
1926
1943
|
issue(
|
|
1927
1944
|
"INTAKE.FILE_UNAVAILABLE",
|
|
1928
1945
|
"external",
|
|
@@ -1931,8 +1948,8 @@ async function evaluateSourceIntake(input, options = {}) {
|
|
|
1931
1948
|
);
|
|
1932
1949
|
continue;
|
|
1933
1950
|
}
|
|
1934
|
-
check.actualByteLength =
|
|
1935
|
-
if (
|
|
1951
|
+
check.actualByteLength = bytes6.length;
|
|
1952
|
+
if (bytes6.length !== a.byteLength) {
|
|
1936
1953
|
check.status = "failed";
|
|
1937
1954
|
issue(
|
|
1938
1955
|
"INTAKE.SIZE",
|
|
@@ -1945,7 +1962,7 @@ async function evaluateSourceIntake(input, options = {}) {
|
|
|
1945
1962
|
try {
|
|
1946
1963
|
check.actualSha256 = [
|
|
1947
1964
|
...new Uint8Array(
|
|
1948
|
-
await globalThis.crypto.subtle.digest("SHA-256",
|
|
1965
|
+
await globalThis.crypto.subtle.digest("SHA-256", bytes6)
|
|
1949
1966
|
)
|
|
1950
1967
|
].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1951
1968
|
check.status = check.actualSha256 === a.sha256 ? "passed" : "failed";
|
|
@@ -2081,16 +2098,16 @@ async function evaluateDocumentationCompletion(input, options = {}) {
|
|
|
2081
2098
|
const assessed = claim.status === "assessed", confirmed = assessed && claim.outcome === "confirmed";
|
|
2082
2099
|
const subjectRef = claim.subject.kind === "measurement" ? `measurement:${claim.subject.measurementId}` : void 0;
|
|
2083
2100
|
const relevant = report.measurementRefs.filter(
|
|
2084
|
-
(
|
|
2101
|
+
(ref18) => !subjectRef || ref18 === subjectRef
|
|
2085
2102
|
);
|
|
2086
2103
|
const requirements = [];
|
|
2087
2104
|
for (const definition of DOCUMENTATION_REQUIREMENTS) {
|
|
2088
|
-
const
|
|
2105
|
+
const id26 = definition.id;
|
|
2089
2106
|
const issues = report.issues.filter(
|
|
2090
|
-
(i) => codes[
|
|
2107
|
+
(i) => codes[id26].includes(i.code)
|
|
2091
2108
|
);
|
|
2092
2109
|
const row = {
|
|
2093
|
-
id:
|
|
2110
|
+
id: id26,
|
|
2094
2111
|
label: definition.label,
|
|
2095
2112
|
importance: "required",
|
|
2096
2113
|
applicability: "applicable",
|
|
@@ -2099,7 +2116,7 @@ async function evaluateDocumentationCompletion(input, options = {}) {
|
|
|
2099
2116
|
actions: issues.map(action),
|
|
2100
2117
|
blockedBy: []
|
|
2101
2118
|
};
|
|
2102
|
-
if (
|
|
2119
|
+
if (id26 === "assessment") {
|
|
2103
2120
|
if (!assessed) {
|
|
2104
2121
|
row.status = "missing";
|
|
2105
2122
|
row.reason = "No attributed evaluator assessment has been recorded; unassessed remains a valid state.";
|
|
@@ -2109,7 +2126,7 @@ async function evaluateDocumentationCompletion(input, options = {}) {
|
|
|
2109
2126
|
"documentary_support",
|
|
2110
2127
|
"content_digests",
|
|
2111
2128
|
"content_integrity"
|
|
2112
|
-
].includes(
|
|
2129
|
+
].includes(id26);
|
|
2113
2130
|
if (!assessed) {
|
|
2114
2131
|
row.blockedBy = ["assessment"];
|
|
2115
2132
|
row.status = "not_checked";
|
|
@@ -2123,19 +2140,19 @@ async function evaluateDocumentationCompletion(input, options = {}) {
|
|
|
2123
2140
|
"measurement_uncertainty",
|
|
2124
2141
|
"raw_product_lineage",
|
|
2125
2142
|
"reference_frames"
|
|
2126
|
-
].includes(
|
|
2143
|
+
].includes(id26) && !relevant.length) {
|
|
2127
2144
|
row.blockedBy = ["measurement"];
|
|
2128
2145
|
row.status = "not_checked";
|
|
2129
2146
|
row.reason = "A measurement matching the subject is required before this check can run.";
|
|
2130
|
-
} else if (
|
|
2147
|
+
} else if (id26 === "reference_frames" && !relevant.some((ref18) => measurements.get(ref18)?.frameRef)) {
|
|
2131
2148
|
row.status = "not_applicable";
|
|
2132
2149
|
row.applicability = "not_applicable";
|
|
2133
2150
|
row.reason = "No relevant measurement declares a frame reference; this does not establish that a frame is scientifically unnecessary.";
|
|
2134
|
-
} else if (["content_digests", "content_integrity"].includes(
|
|
2151
|
+
} else if (["content_digests", "content_integrity"].includes(id26) && !report.assets.length) {
|
|
2135
2152
|
row.blockedBy = ["documentary_support"];
|
|
2136
2153
|
row.status = "not_checked";
|
|
2137
2154
|
row.reason = "Traceable supporting content is required before pins and local bytes can be checked.";
|
|
2138
|
-
} else if (
|
|
2155
|
+
} else if (id26 === "content_integrity") {
|
|
2139
2156
|
if (report.assets.some((a) => a.status === "failed")) {
|
|
2140
2157
|
row.status = "failed";
|
|
2141
2158
|
row.reason = "Supplied content is empty or differs from its pinned digest.";
|
|
@@ -2310,7 +2327,7 @@ async function evaluateInstrumentResearchCompletion(historyInput, contextInput,
|
|
|
2310
2327
|
blockedBy: [],
|
|
2311
2328
|
actions: []
|
|
2312
2329
|
}));
|
|
2313
|
-
const item = (
|
|
2330
|
+
const item = (id26) => requirements.find((r) => r.id === id26);
|
|
2314
2331
|
const inputs = item("input_consistency");
|
|
2315
2332
|
inputs.actions = actions.filter(
|
|
2316
2333
|
(i) => i.stage === "structural" || i.stage === "semantic"
|
|
@@ -2350,14 +2367,14 @@ async function evaluateInstrumentResearchCompletion(historyInput, contextInput,
|
|
|
2350
2367
|
} else {
|
|
2351
2368
|
reviewed.blockedBy = ["input_consistency", "review_scope"];
|
|
2352
2369
|
}
|
|
2353
|
-
for (const [
|
|
2370
|
+
for (const [id26, nested] of [
|
|
2354
2371
|
["assessment_documentation", validation.documentation],
|
|
2355
2372
|
["measurement_acquisition", validation.measurements]
|
|
2356
2373
|
]) {
|
|
2357
|
-
const row = item(
|
|
2374
|
+
const row = item(id26);
|
|
2358
2375
|
row.actions = nested ? nested.issues.map(
|
|
2359
2376
|
(i) => action2(
|
|
2360
|
-
|
|
2377
|
+
id26 === "assessment_documentation" ? { ...i, pointer: "/documentation" + i.pointer } : i
|
|
2361
2378
|
)
|
|
2362
2379
|
) : [];
|
|
2363
2380
|
if (!nested) {
|
|
@@ -2440,7 +2457,7 @@ var ResearchEvaluationSchema = z.strictObject({
|
|
|
2440
2457
|
});
|
|
2441
2458
|
function researchEvaluationJsonSchema() {
|
|
2442
2459
|
return {
|
|
2443
|
-
...z.toJSONSchema(ResearchEvaluationSchema, { target: "draft-2020-12" }),
|
|
2460
|
+
...preservePublishedSchema(z.toJSONSchema(ResearchEvaluationSchema, { target: "draft-2020-12" })),
|
|
2444
2461
|
$id: RESEARCH_EVALUATION_SCHEMA_ID
|
|
2445
2462
|
};
|
|
2446
2463
|
}
|
|
@@ -2453,15 +2470,15 @@ function serialize(value) {
|
|
|
2453
2470
|
}
|
|
2454
2471
|
return JSON.stringify(value);
|
|
2455
2472
|
}
|
|
2456
|
-
async function digest(
|
|
2457
|
-
const buffer = Uint8Array.from(
|
|
2473
|
+
async function digest(bytes6) {
|
|
2474
|
+
const buffer = Uint8Array.from(bytes6);
|
|
2458
2475
|
return [
|
|
2459
2476
|
...new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", buffer))
|
|
2460
2477
|
].map((v) => v.toString(16).padStart(2, "0")).join("");
|
|
2461
2478
|
}
|
|
2462
|
-
function decode2(
|
|
2479
|
+
function decode2(bytes6) {
|
|
2463
2480
|
return JSON.parse(
|
|
2464
|
-
new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(
|
|
2481
|
+
new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes6)
|
|
2465
2482
|
);
|
|
2466
2483
|
}
|
|
2467
2484
|
async function evaluateResearchEvaluation(input, options = {}) {
|
|
@@ -2486,7 +2503,7 @@ async function evaluateResearchEvaluation(input, options = {}) {
|
|
|
2486
2503
|
vocabularyMembership: "not_checked",
|
|
2487
2504
|
scientificEligibility: "not_checked"
|
|
2488
2505
|
};
|
|
2489
|
-
const issue = (code, pointer6,
|
|
2506
|
+
const issue = (code, pointer6, message2) => result.issues.push({ code, pointer: pointer6, message: message2 });
|
|
2490
2507
|
if (!parsed.success) {
|
|
2491
2508
|
result.checks.structural = "failed";
|
|
2492
2509
|
for (const i of parsed.error.issues)
|
|
@@ -2529,15 +2546,15 @@ async function evaluateResearchEvaluation(input, options = {}) {
|
|
|
2529
2546
|
result.checks.semantic = "passed";
|
|
2530
2547
|
const packetBytes = options.packetBytes ? Uint8Array.from(options.packetBytes) : void 0;
|
|
2531
2548
|
const files = new Map(
|
|
2532
|
-
[...options.files ?? []].map(([
|
|
2533
|
-
|
|
2534
|
-
Uint8Array.from(
|
|
2549
|
+
[...options.files ?? []].map(([ref18, bytes6]) => [
|
|
2550
|
+
ref18,
|
|
2551
|
+
Uint8Array.from(bytes6)
|
|
2535
2552
|
])
|
|
2536
2553
|
);
|
|
2537
2554
|
const dependencyFiles = new Map(
|
|
2538
|
-
[...options.dependencyFiles ?? []].map(([
|
|
2539
|
-
|
|
2540
|
-
Uint8Array.from(
|
|
2555
|
+
[...options.dependencyFiles ?? []].map(([ref18, bytes6]) => [
|
|
2556
|
+
ref18,
|
|
2557
|
+
Uint8Array.from(bytes6)
|
|
2541
2558
|
])
|
|
2542
2559
|
);
|
|
2543
2560
|
const checks = [
|
|
@@ -2638,9 +2655,9 @@ async function evaluateResearchEvaluation(input, options = {}) {
|
|
|
2638
2655
|
);
|
|
2639
2656
|
result.checks.external = "passed";
|
|
2640
2657
|
const documents = Object.fromEntries(
|
|
2641
|
-
Object.entries(packet.data.documents).map(([name,
|
|
2658
|
+
Object.entries(packet.data.documents).map(([name, ref18]) => [
|
|
2642
2659
|
name,
|
|
2643
|
-
decode2(files.get(
|
|
2660
|
+
decode2(files.get(ref18))
|
|
2644
2661
|
])
|
|
2645
2662
|
);
|
|
2646
2663
|
const maps = Object.fromEntries(
|
|
@@ -2746,9 +2763,9 @@ var ReleasedDocumentSelectionSchema = z.strictObject({
|
|
|
2746
2763
|
});
|
|
2747
2764
|
function releasedDocumentSelectionJsonSchema() {
|
|
2748
2765
|
return {
|
|
2749
|
-
...z.toJSONSchema(ReleasedDocumentSelectionSchema, {
|
|
2766
|
+
...preservePublishedSchema(z.toJSONSchema(ReleasedDocumentSelectionSchema, {
|
|
2750
2767
|
target: "draft-2020-12"
|
|
2751
|
-
}),
|
|
2768
|
+
})),
|
|
2752
2769
|
$id: RELEASED_DOCUMENT_SELECTION_SCHEMA_ID
|
|
2753
2770
|
};
|
|
2754
2771
|
}
|
|
@@ -2837,12 +2854,12 @@ async function evaluateReleasedDocuments(historyInput, selectionInput, options =
|
|
|
2837
2854
|
}
|
|
2838
2855
|
if (!validation.success) return result;
|
|
2839
2856
|
const chosen = selection.data, history = validation.data;
|
|
2840
|
-
const problem = (code, pointer6,
|
|
2857
|
+
const problem = (code, pointer6, message2) => result.issues.push({
|
|
2841
2858
|
code,
|
|
2842
2859
|
stage: "semantic",
|
|
2843
2860
|
severity: "error",
|
|
2844
2861
|
pointer: pointer6,
|
|
2845
|
-
message,
|
|
2862
|
+
message: message2,
|
|
2846
2863
|
nextAction: "Resolve the selection against the exact history and source inventory."
|
|
2847
2864
|
});
|
|
2848
2865
|
if (chosen.historyId !== history.id)
|
|
@@ -2878,7 +2895,7 @@ async function evaluateReleasedDocuments(historyInput, selectionInput, options =
|
|
|
2878
2895
|
return result;
|
|
2879
2896
|
}
|
|
2880
2897
|
const assets2 = new Map(
|
|
2881
|
-
[...options.assets ?? []].map(([
|
|
2898
|
+
[...options.assets ?? []].map(([ref18, b]) => [ref18, Uint8Array.from(b)])
|
|
2882
2899
|
);
|
|
2883
2900
|
const current = new Set(validation.currentClaimRefs);
|
|
2884
2901
|
for (const [i, d] of chosen.documents.entries()) {
|
|
@@ -2899,17 +2916,17 @@ async function evaluateReleasedDocuments(historyInput, selectionInput, options =
|
|
|
2899
2916
|
asset: { status: "not_checked" }
|
|
2900
2917
|
};
|
|
2901
2918
|
result.documents.push(row);
|
|
2902
|
-
const requirement = (
|
|
2903
|
-
const pass = (
|
|
2904
|
-
const r = requirement(
|
|
2919
|
+
const requirement = (id26) => row.requirements.find((r) => r.id === id26);
|
|
2920
|
+
const pass = (id26, reason) => {
|
|
2921
|
+
const r = requirement(id26);
|
|
2905
2922
|
r.status = "satisfied";
|
|
2906
2923
|
r.reason = reason;
|
|
2907
2924
|
};
|
|
2908
|
-
const gap = (
|
|
2909
|
-
const r = requirement(
|
|
2925
|
+
const gap = (id26, status, code, pointer6, message2, nextAction, stage = "profile", severity = "error") => {
|
|
2926
|
+
const r = requirement(id26);
|
|
2910
2927
|
r.status = status;
|
|
2911
|
-
r.reason =
|
|
2912
|
-
const issue = { code, pointer: pointer6, message, nextAction, stage, severity };
|
|
2928
|
+
r.reason = message2;
|
|
2929
|
+
const issue = { code, pointer: pointer6, message: message2, nextAction, stage, severity };
|
|
2913
2930
|
r.issues.push(issue);
|
|
2914
2931
|
result.issues.push(issue);
|
|
2915
2932
|
};
|
|
@@ -2965,8 +2982,8 @@ async function evaluateReleasedDocuments(historyInput, selectionInput, options =
|
|
|
2965
2982
|
r.blockedBy = ["content_digest"];
|
|
2966
2983
|
r.reason = "A declared source digest is required before byte comparison.";
|
|
2967
2984
|
} else {
|
|
2968
|
-
const
|
|
2969
|
-
if (!
|
|
2985
|
+
const bytes6 = assets2.get(d.sourceRef);
|
|
2986
|
+
if (!bytes6)
|
|
2970
2987
|
gap(
|
|
2971
2988
|
"content_integrity",
|
|
2972
2989
|
"missing",
|
|
@@ -2978,8 +2995,8 @@ async function evaluateReleasedDocuments(historyInput, selectionInput, options =
|
|
|
2978
2995
|
"warning"
|
|
2979
2996
|
);
|
|
2980
2997
|
else {
|
|
2981
|
-
row.asset.byteLength =
|
|
2982
|
-
if (!
|
|
2998
|
+
row.asset.byteLength = bytes6.length;
|
|
2999
|
+
if (!bytes6.length) {
|
|
2983
3000
|
row.asset.status = "failed";
|
|
2984
3001
|
gap(
|
|
2985
3002
|
"content_integrity",
|
|
@@ -2992,11 +3009,11 @@ async function evaluateReleasedDocuments(historyInput, selectionInput, options =
|
|
|
2992
3009
|
);
|
|
2993
3010
|
} else
|
|
2994
3011
|
try {
|
|
2995
|
-
const
|
|
3012
|
+
const hash8 = await globalThis.crypto.subtle.digest(
|
|
2996
3013
|
"SHA-256",
|
|
2997
|
-
|
|
3014
|
+
bytes6
|
|
2998
3015
|
);
|
|
2999
|
-
row.asset.actualSha256 = [...new Uint8Array(
|
|
3016
|
+
row.asset.actualSha256 = [...new Uint8Array(hash8)].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
3000
3017
|
if (row.asset.actualSha256 === source.digest.value) {
|
|
3001
3018
|
row.asset.status = "passed";
|
|
3002
3019
|
pass(
|
|
@@ -3051,11 +3068,11 @@ async function evaluateReleasedDocuments(historyInput, selectionInput, options =
|
|
|
3051
3068
|
];
|
|
3052
3069
|
row.extractionRefs = extractions.map((e) => e.ref);
|
|
3053
3070
|
if (!extractions.length) {
|
|
3054
|
-
for (const
|
|
3071
|
+
for (const id26 of [
|
|
3055
3072
|
"extraction_traceability",
|
|
3056
3073
|
"source_attribution"
|
|
3057
3074
|
]) {
|
|
3058
|
-
const r = requirement(
|
|
3075
|
+
const r = requirement(id26);
|
|
3059
3076
|
r.status = "not_applicable";
|
|
3060
3077
|
r.reason = "No current source statements or value assertions directly cite this selected document.";
|
|
3061
3078
|
}
|
|
@@ -3100,18 +3117,18 @@ async function evaluateReleasedDocuments(historyInput, selectionInput, options =
|
|
|
3100
3117
|
);
|
|
3101
3118
|
}
|
|
3102
3119
|
}
|
|
3103
|
-
for (const [
|
|
3120
|
+
for (const [id26, value, field2] of [
|
|
3104
3121
|
["source_title", source.title, "title"],
|
|
3105
3122
|
["source_uri", source.uri, "uri"]
|
|
3106
3123
|
]) {
|
|
3107
3124
|
if (value)
|
|
3108
3125
|
pass(
|
|
3109
|
-
|
|
3126
|
+
id26,
|
|
3110
3127
|
"The source supplies this citation aid; correctness and availability are unchecked."
|
|
3111
3128
|
);
|
|
3112
3129
|
else
|
|
3113
3130
|
gap(
|
|
3114
|
-
|
|
3131
|
+
id26,
|
|
3115
3132
|
"missing",
|
|
3116
3133
|
"DOCUMENT." + field2.toUpperCase() + "_RECOMMENDED",
|
|
3117
3134
|
path2 + "/" + field2,
|
|
@@ -3168,9 +3185,9 @@ var HistoricalTestimonySelectionSchema = z.strictObject({
|
|
|
3168
3185
|
});
|
|
3169
3186
|
function historicalTestimonySelectionJsonSchema() {
|
|
3170
3187
|
return {
|
|
3171
|
-
...z.toJSONSchema(HistoricalTestimonySelectionSchema, {
|
|
3188
|
+
...preservePublishedSchema(z.toJSONSchema(HistoricalTestimonySelectionSchema, {
|
|
3172
3189
|
target: "draft-2020-12"
|
|
3173
|
-
}),
|
|
3190
|
+
})),
|
|
3174
3191
|
$id: HISTORICAL_TESTIMONY_SELECTION_SCHEMA_ID
|
|
3175
3192
|
};
|
|
3176
3193
|
}
|
|
@@ -3258,12 +3275,12 @@ async function evaluateHistoricalTestimony(historyInput, selectionInput, options
|
|
|
3258
3275
|
}
|
|
3259
3276
|
if (!validation.success) return result;
|
|
3260
3277
|
const chosen = selection.data, history = validation.data;
|
|
3261
|
-
const problem = (code, pointer6,
|
|
3278
|
+
const problem = (code, pointer6, message2) => result.issues.push({
|
|
3262
3279
|
code,
|
|
3263
3280
|
stage: "semantic",
|
|
3264
3281
|
severity: "error",
|
|
3265
3282
|
pointer: pointer6,
|
|
3266
|
-
message,
|
|
3283
|
+
message: message2,
|
|
3267
3284
|
nextAction: "Resolve the selection against the exact history and source inventory."
|
|
3268
3285
|
});
|
|
3269
3286
|
if (chosen.historyId !== history.id)
|
|
@@ -3299,7 +3316,7 @@ async function evaluateHistoricalTestimony(historyInput, selectionInput, options
|
|
|
3299
3316
|
return result;
|
|
3300
3317
|
}
|
|
3301
3318
|
const assets2 = new Map(
|
|
3302
|
-
[...options.assets ?? []].map(([
|
|
3319
|
+
[...options.assets ?? []].map(([ref18, b]) => [ref18, Uint8Array.from(b)])
|
|
3303
3320
|
);
|
|
3304
3321
|
const current = new Set(validation.currentClaimRefs);
|
|
3305
3322
|
for (const [i, d] of chosen.accounts.entries()) {
|
|
@@ -3320,17 +3337,17 @@ async function evaluateHistoricalTestimony(historyInput, selectionInput, options
|
|
|
3320
3337
|
asset: { status: "not_checked" }
|
|
3321
3338
|
};
|
|
3322
3339
|
result.accounts.push(row);
|
|
3323
|
-
const requirement = (
|
|
3324
|
-
const pass = (
|
|
3325
|
-
const r = requirement(
|
|
3340
|
+
const requirement = (id26) => row.requirements.find((r) => r.id === id26);
|
|
3341
|
+
const pass = (id26, reason) => {
|
|
3342
|
+
const r = requirement(id26);
|
|
3326
3343
|
r.status = "satisfied";
|
|
3327
3344
|
r.reason = reason;
|
|
3328
3345
|
};
|
|
3329
|
-
const gap = (
|
|
3330
|
-
const r = requirement(
|
|
3346
|
+
const gap = (id26, status, code, pointer6, message2, nextAction, stage = "profile", severity = "error") => {
|
|
3347
|
+
const r = requirement(id26);
|
|
3331
3348
|
r.status = status;
|
|
3332
|
-
r.reason =
|
|
3333
|
-
const issue = { code, pointer: pointer6, message, nextAction, stage, severity };
|
|
3349
|
+
r.reason = message2;
|
|
3350
|
+
const issue = { code, pointer: pointer6, message: message2, nextAction, stage, severity };
|
|
3334
3351
|
r.issues.push(issue);
|
|
3335
3352
|
result.issues.push(issue);
|
|
3336
3353
|
};
|
|
@@ -3386,8 +3403,8 @@ async function evaluateHistoricalTestimony(historyInput, selectionInput, options
|
|
|
3386
3403
|
r.blockedBy = ["content_digest"];
|
|
3387
3404
|
r.reason = "A declared source digest is required before byte comparison.";
|
|
3388
3405
|
} else {
|
|
3389
|
-
const
|
|
3390
|
-
if (!
|
|
3406
|
+
const bytes6 = assets2.get(d.sourceRef);
|
|
3407
|
+
if (!bytes6)
|
|
3391
3408
|
gap(
|
|
3392
3409
|
"content_integrity",
|
|
3393
3410
|
"missing",
|
|
@@ -3399,8 +3416,8 @@ async function evaluateHistoricalTestimony(historyInput, selectionInput, options
|
|
|
3399
3416
|
"warning"
|
|
3400
3417
|
);
|
|
3401
3418
|
else {
|
|
3402
|
-
row.asset.byteLength =
|
|
3403
|
-
if (!
|
|
3419
|
+
row.asset.byteLength = bytes6.length;
|
|
3420
|
+
if (!bytes6.length) {
|
|
3404
3421
|
row.asset.status = "failed";
|
|
3405
3422
|
gap(
|
|
3406
3423
|
"content_integrity",
|
|
@@ -3413,11 +3430,11 @@ async function evaluateHistoricalTestimony(historyInput, selectionInput, options
|
|
|
3413
3430
|
);
|
|
3414
3431
|
} else
|
|
3415
3432
|
try {
|
|
3416
|
-
const
|
|
3433
|
+
const hash8 = await globalThis.crypto.subtle.digest(
|
|
3417
3434
|
"SHA-256",
|
|
3418
|
-
|
|
3435
|
+
bytes6
|
|
3419
3436
|
);
|
|
3420
|
-
row.asset.actualSha256 = [...new Uint8Array(
|
|
3437
|
+
row.asset.actualSha256 = [...new Uint8Array(hash8)].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
3421
3438
|
if (row.asset.actualSha256 === source.digest.value) {
|
|
3422
3439
|
row.asset.status = "passed";
|
|
3423
3440
|
pass(
|
|
@@ -3472,8 +3489,8 @@ async function evaluateHistoricalTestimony(historyInput, selectionInput, options
|
|
|
3472
3489
|
];
|
|
3473
3490
|
row.extractionRefs = extractions.map((e) => e.ref);
|
|
3474
3491
|
if (!extractions.length) {
|
|
3475
|
-
for (const
|
|
3476
|
-
const r = requirement(
|
|
3492
|
+
for (const id26 of ["extraction_traceability"]) {
|
|
3493
|
+
const r = requirement(id26);
|
|
3477
3494
|
r.status = "not_applicable";
|
|
3478
3495
|
r.reason = "No current source statements or value assertions directly cite this selected account.";
|
|
3479
3496
|
}
|
|
@@ -3512,18 +3529,18 @@ async function evaluateHistoricalTestimony(historyInput, selectionInput, options
|
|
|
3512
3529
|
);
|
|
3513
3530
|
}
|
|
3514
3531
|
}
|
|
3515
|
-
for (const [
|
|
3532
|
+
for (const [id26, value, field2] of [
|
|
3516
3533
|
["source_title", source.title, "title"],
|
|
3517
3534
|
["source_uri", source.uri, "uri"]
|
|
3518
3535
|
]) {
|
|
3519
3536
|
if (value)
|
|
3520
3537
|
pass(
|
|
3521
|
-
|
|
3538
|
+
id26,
|
|
3522
3539
|
"The source supplies this citation aid; correctness and availability are unchecked."
|
|
3523
3540
|
);
|
|
3524
3541
|
else
|
|
3525
3542
|
gap(
|
|
3526
|
-
|
|
3543
|
+
id26,
|
|
3527
3544
|
"missing",
|
|
3528
3545
|
"TESTIMONY." + field2.toUpperCase() + "_RECOMMENDED",
|
|
3529
3546
|
path2 + "/" + field2,
|
|
@@ -3610,9 +3627,9 @@ var PhysicalSampleSelectionSchema = z.strictObject({
|
|
|
3610
3627
|
});
|
|
3611
3628
|
function physicalSampleSelectionJsonSchema() {
|
|
3612
3629
|
return {
|
|
3613
|
-
...z.toJSONSchema(PhysicalSampleSelectionSchema, {
|
|
3630
|
+
...preservePublishedSchema(z.toJSONSchema(PhysicalSampleSelectionSchema, {
|
|
3614
3631
|
target: "draft-2020-12"
|
|
3615
|
-
}),
|
|
3632
|
+
})),
|
|
3616
3633
|
$id: PHYSICAL_SAMPLE_SELECTION_SCHEMA_ID
|
|
3617
3634
|
};
|
|
3618
3635
|
}
|
|
@@ -3711,12 +3728,12 @@ async function evaluatePhysicalSamples(historyInput, selectionInput, options = {
|
|
|
3711
3728
|
}
|
|
3712
3729
|
if (!validation.success) return result;
|
|
3713
3730
|
const selection = parsed.data, history = validation.data;
|
|
3714
|
-
const problem = (code, pointer6,
|
|
3731
|
+
const problem = (code, pointer6, message2) => result.issues.push({
|
|
3715
3732
|
code,
|
|
3716
3733
|
stage: "semantic",
|
|
3717
3734
|
severity: "error",
|
|
3718
3735
|
pointer: pointer6,
|
|
3719
|
-
message,
|
|
3736
|
+
message: message2,
|
|
3720
3737
|
nextAction: "Resolve the selection against the exact history and source inventory; do not invent references."
|
|
3721
3738
|
});
|
|
3722
3739
|
if (selection.historyId !== history.id)
|
|
@@ -3744,12 +3761,12 @@ async function evaluatePhysicalSamples(historyInput, selectionInput, options = {
|
|
|
3744
3761
|
"Sample ID is selected more than once."
|
|
3745
3762
|
);
|
|
3746
3763
|
sampleIds.add(s.id);
|
|
3747
|
-
for (const
|
|
3748
|
-
if (!sources.has(
|
|
3764
|
+
for (const ref18 of references(s))
|
|
3765
|
+
if (!sources.has(ref18))
|
|
3749
3766
|
problem(
|
|
3750
3767
|
"SAMPLE.SOURCE_REF",
|
|
3751
3768
|
path2,
|
|
3752
|
-
`Cited record ${
|
|
3769
|
+
`Cited record ${ref18} is absent from this history.`
|
|
3753
3770
|
);
|
|
3754
3771
|
if (s.custody.state === "documented") {
|
|
3755
3772
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -3769,7 +3786,7 @@ async function evaluatePhysicalSamples(historyInput, selectionInput, options = {
|
|
|
3769
3786
|
return result;
|
|
3770
3787
|
}
|
|
3771
3788
|
const assets2 = new Map(
|
|
3772
|
-
[...options.assets ?? []].map(([
|
|
3789
|
+
[...options.assets ?? []].map(([ref18, b]) => [ref18, Uint8Array.from(b)])
|
|
3773
3790
|
);
|
|
3774
3791
|
for (const [i, s] of selection.samples.entries()) {
|
|
3775
3792
|
const path2 = `/selection/samples/${i}`;
|
|
@@ -3786,17 +3803,17 @@ async function evaluatePhysicalSamples(historyInput, selectionInput, options = {
|
|
|
3786
3803
|
records: []
|
|
3787
3804
|
};
|
|
3788
3805
|
result.samples.push(row);
|
|
3789
|
-
const requirement = (
|
|
3790
|
-
const pass = (
|
|
3791
|
-
const r = requirement(
|
|
3806
|
+
const requirement = (id26) => row.requirements.find((r) => r.id === id26);
|
|
3807
|
+
const pass = (id26, reason) => {
|
|
3808
|
+
const r = requirement(id26);
|
|
3792
3809
|
r.status = "satisfied";
|
|
3793
3810
|
r.reason = reason;
|
|
3794
3811
|
};
|
|
3795
|
-
const gap = (
|
|
3796
|
-
const r = requirement(
|
|
3812
|
+
const gap = (id26, status, code, pointer6, message2, nextAction, stage = "profile", severity = "error") => {
|
|
3813
|
+
const r = requirement(id26);
|
|
3797
3814
|
r.status = status;
|
|
3798
|
-
r.reason =
|
|
3799
|
-
const issue = { code, pointer: pointer6, message, nextAction, stage, severity };
|
|
3815
|
+
r.reason = message2;
|
|
3816
|
+
const issue = { code, pointer: pointer6, message: message2, nextAction, stage, severity };
|
|
3800
3817
|
r.issues.push(issue);
|
|
3801
3818
|
result.issues.push(issue);
|
|
3802
3819
|
};
|
|
@@ -3925,9 +3942,9 @@ async function evaluatePhysicalSamples(historyInput, selectionInput, options = {
|
|
|
3925
3942
|
r.blockedBy = ["collection_record", "current_custodian"];
|
|
3926
3943
|
r.reason = "No collection, handoff or current-custody records are cited.";
|
|
3927
3944
|
} else {
|
|
3928
|
-
for (const
|
|
3929
|
-
const source = sources.get(
|
|
3930
|
-
sourceRef:
|
|
3945
|
+
for (const ref18 of refs) {
|
|
3946
|
+
const source = sources.get(ref18), check = {
|
|
3947
|
+
sourceRef: ref18,
|
|
3931
3948
|
status: "not_checked"
|
|
3932
3949
|
};
|
|
3933
3950
|
row.records.push(check);
|
|
@@ -3946,8 +3963,8 @@ async function evaluatePhysicalSamples(historyInput, selectionInput, options = {
|
|
|
3946
3963
|
continue;
|
|
3947
3964
|
}
|
|
3948
3965
|
check.expectedSha256 = source.digest.value;
|
|
3949
|
-
const
|
|
3950
|
-
if (!
|
|
3966
|
+
const bytes6 = assets2.get(ref18);
|
|
3967
|
+
if (!bytes6) {
|
|
3951
3968
|
gap(
|
|
3952
3969
|
"record_integrity",
|
|
3953
3970
|
"missing",
|
|
@@ -3960,8 +3977,8 @@ async function evaluatePhysicalSamples(historyInput, selectionInput, options = {
|
|
|
3960
3977
|
);
|
|
3961
3978
|
continue;
|
|
3962
3979
|
}
|
|
3963
|
-
check.byteLength =
|
|
3964
|
-
if (!
|
|
3980
|
+
check.byteLength = bytes6.length;
|
|
3981
|
+
if (!bytes6.length) {
|
|
3965
3982
|
check.status = "failed";
|
|
3966
3983
|
gap(
|
|
3967
3984
|
"record_integrity",
|
|
@@ -3975,8 +3992,8 @@ async function evaluatePhysicalSamples(historyInput, selectionInput, options = {
|
|
|
3975
3992
|
continue;
|
|
3976
3993
|
}
|
|
3977
3994
|
try {
|
|
3978
|
-
const
|
|
3979
|
-
check.actualSha256 = [...new Uint8Array(
|
|
3995
|
+
const hash8 = await globalThis.crypto.subtle.digest("SHA-256", bytes6);
|
|
3996
|
+
check.actualSha256 = [...new Uint8Array(hash8)].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
3980
3997
|
if (check.actualSha256 === source.digest.value)
|
|
3981
3998
|
check.status = "passed";
|
|
3982
3999
|
else {
|
|
@@ -4092,9 +4109,9 @@ var ProfileEvaluationSchema = z.strictObject({
|
|
|
4092
4109
|
});
|
|
4093
4110
|
function profileEvaluationJsonSchema() {
|
|
4094
4111
|
return {
|
|
4095
|
-
...z.toJSONSchema(ProfileEvaluationSchema, {
|
|
4112
|
+
...preservePublishedSchema(z.toJSONSchema(ProfileEvaluationSchema, {
|
|
4096
4113
|
target: "draft-2020-12"
|
|
4097
|
-
}),
|
|
4114
|
+
})),
|
|
4098
4115
|
$id: PROFILE_EVALUATION_SCHEMA_ID
|
|
4099
4116
|
};
|
|
4100
4117
|
}
|
|
@@ -4107,10 +4124,10 @@ function serialize2(value) {
|
|
|
4107
4124
|
}
|
|
4108
4125
|
return JSON.stringify(value);
|
|
4109
4126
|
}
|
|
4110
|
-
async function digest2(
|
|
4127
|
+
async function digest2(bytes6) {
|
|
4111
4128
|
return [
|
|
4112
4129
|
...new Uint8Array(
|
|
4113
|
-
await globalThis.crypto.subtle.digest("SHA-256", Uint8Array.from(
|
|
4130
|
+
await globalThis.crypto.subtle.digest("SHA-256", Uint8Array.from(bytes6))
|
|
4114
4131
|
)
|
|
4115
4132
|
].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
4116
4133
|
}
|
|
@@ -4137,7 +4154,7 @@ async function evaluateProfileEvaluation(input, options = {}) {
|
|
|
4137
4154
|
implementationExecution: "not_attested",
|
|
4138
4155
|
environmentExecution: "not_attested"
|
|
4139
4156
|
};
|
|
4140
|
-
const issue = (code, pointer6,
|
|
4157
|
+
const issue = (code, pointer6, message2) => result.issues.push({ code, pointer: pointer6, message: message2 });
|
|
4141
4158
|
if (!parsed.success) {
|
|
4142
4159
|
result.checks.structural = "failed";
|
|
4143
4160
|
for (const i of parsed.error.issues)
|
|
@@ -4201,15 +4218,15 @@ async function evaluateProfileEvaluation(input, options = {}) {
|
|
|
4201
4218
|
const historyBytes = options.historyBytes ? Uint8Array.from(options.historyBytes) : void 0;
|
|
4202
4219
|
const selectionBytes = options.selectionBytes ? Uint8Array.from(options.selectionBytes) : void 0;
|
|
4203
4220
|
const assetFiles = new Map(
|
|
4204
|
-
[...options.assetFiles ?? []].map(([
|
|
4205
|
-
|
|
4206
|
-
Uint8Array.from(
|
|
4221
|
+
[...options.assetFiles ?? []].map(([ref18, bytes6]) => [
|
|
4222
|
+
ref18,
|
|
4223
|
+
Uint8Array.from(bytes6)
|
|
4207
4224
|
])
|
|
4208
4225
|
);
|
|
4209
4226
|
const files = new Map(
|
|
4210
|
-
[...options.dependencyFiles ?? []].map(([
|
|
4211
|
-
|
|
4212
|
-
Uint8Array.from(
|
|
4227
|
+
[...options.dependencyFiles ?? []].map(([ref18, bytes6]) => [
|
|
4228
|
+
ref18,
|
|
4229
|
+
Uint8Array.from(bytes6)
|
|
4213
4230
|
])
|
|
4214
4231
|
);
|
|
4215
4232
|
const inputs = [
|
|
@@ -4288,13 +4305,13 @@ async function evaluateProfileEvaluation(input, options = {}) {
|
|
|
4288
4305
|
}
|
|
4289
4306
|
result.checks.external = "passed";
|
|
4290
4307
|
const documents = {};
|
|
4291
|
-
for (const [name,
|
|
4308
|
+
for (const [name, bytes6] of [
|
|
4292
4309
|
["history", historyBytes],
|
|
4293
4310
|
["selection", selectionBytes]
|
|
4294
4311
|
]) {
|
|
4295
4312
|
try {
|
|
4296
4313
|
documents[name] = JSON.parse(
|
|
4297
|
-
new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(
|
|
4314
|
+
new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes6)
|
|
4298
4315
|
);
|
|
4299
4316
|
} catch {
|
|
4300
4317
|
result.checks.semantic = "failed";
|
|
@@ -4385,7 +4402,7 @@ var ProfilePreparationSchema = z.strictObject({
|
|
|
4385
4402
|
});
|
|
4386
4403
|
function profilePreparationJsonSchema() {
|
|
4387
4404
|
return {
|
|
4388
|
-
...z.toJSONSchema(ProfilePreparationSchema, { target: "draft-2020-12" }),
|
|
4405
|
+
...preservePublishedSchema(z.toJSONSchema(ProfilePreparationSchema, { target: "draft-2020-12" })),
|
|
4389
4406
|
$id: PROFILE_PREPARATION_SCHEMA_ID
|
|
4390
4407
|
};
|
|
4391
4408
|
}
|
|
@@ -4420,7 +4437,7 @@ var MigrationReviewSchema = z.strictObject({
|
|
|
4420
4437
|
});
|
|
4421
4438
|
function migrationReviewJsonSchema() {
|
|
4422
4439
|
return {
|
|
4423
|
-
...z.toJSONSchema(MigrationReviewSchema, { target: "draft-2020-12" }),
|
|
4440
|
+
...preservePublishedSchema(z.toJSONSchema(MigrationReviewSchema, { target: "draft-2020-12" })),
|
|
4424
4441
|
$id: MIGRATION_REVIEW_SCHEMA_ID
|
|
4425
4442
|
};
|
|
4426
4443
|
}
|
|
@@ -4453,7 +4470,7 @@ var MigrationResolutionSchema = z.strictObject({
|
|
|
4453
4470
|
});
|
|
4454
4471
|
function migrationResolutionJsonSchema() {
|
|
4455
4472
|
return {
|
|
4456
|
-
...z.toJSONSchema(MigrationResolutionSchema, { target: "draft-2020-12" }),
|
|
4473
|
+
...preservePublishedSchema(z.toJSONSchema(MigrationResolutionSchema, { target: "draft-2020-12" })),
|
|
4457
4474
|
$id: MIGRATION_RESOLUTION_SCHEMA_ID
|
|
4458
4475
|
};
|
|
4459
4476
|
}
|
|
@@ -4482,7 +4499,7 @@ var MigrationLegacyScoresSchema = z.strictObject({
|
|
|
4482
4499
|
});
|
|
4483
4500
|
function migrationLegacyScoresJsonSchema() {
|
|
4484
4501
|
return {
|
|
4485
|
-
...z.toJSONSchema(MigrationLegacyScoresSchema, { target: "draft-2020-12" }),
|
|
4502
|
+
...preservePublishedSchema(z.toJSONSchema(MigrationLegacyScoresSchema, { target: "draft-2020-12" })),
|
|
4486
4503
|
$id: MIGRATION_LEGACY_SCORES_SCHEMA_ID
|
|
4487
4504
|
};
|
|
4488
4505
|
}
|
|
@@ -4521,9 +4538,9 @@ var MigrationCompatibilitySchema = z.strictObject({
|
|
|
4521
4538
|
});
|
|
4522
4539
|
function migrationCompatibilityJsonSchema() {
|
|
4523
4540
|
return {
|
|
4524
|
-
...z.toJSONSchema(MigrationCompatibilitySchema, {
|
|
4541
|
+
...preservePublishedSchema(z.toJSONSchema(MigrationCompatibilitySchema, {
|
|
4525
4542
|
target: "draft-2020-12"
|
|
4526
|
-
}),
|
|
4543
|
+
})),
|
|
4527
4544
|
$id: MIGRATION_COMPATIBILITY_SCHEMA_ID
|
|
4528
4545
|
};
|
|
4529
4546
|
}
|
|
@@ -4616,12 +4633,12 @@ async function evaluateContextClaimHistory(input, options) {
|
|
|
4616
4633
|
}));
|
|
4617
4634
|
const snapshots = [];
|
|
4618
4635
|
const contexts = /* @__PURE__ */ new Map();
|
|
4619
|
-
const problem = (code, pointer6,
|
|
4620
|
-
async function load(
|
|
4621
|
-
const supplied = options.documents.get(
|
|
4622
|
-
const
|
|
4623
|
-
if (!
|
|
4624
|
-
snapshots.push({ ...
|
|
4636
|
+
const problem = (code, pointer6, message2, stage = "semantic") => issues.push({ code, pointer: pointer6, message: message2, stage });
|
|
4637
|
+
async function load(ref18, pointer6) {
|
|
4638
|
+
const supplied = options.documents.get(ref18.sha256);
|
|
4639
|
+
const bytes6 = supplied ? Uint8Array.from(supplied) : void 0;
|
|
4640
|
+
if (!bytes6) {
|
|
4641
|
+
snapshots.push({ ...ref18, status: "unavailable" });
|
|
4625
4642
|
problem(
|
|
4626
4643
|
"SNAPSHOT.UNAVAILABLE",
|
|
4627
4644
|
pointer6,
|
|
@@ -4632,10 +4649,10 @@ async function evaluateContextClaimHistory(input, options) {
|
|
|
4632
4649
|
}
|
|
4633
4650
|
if ([
|
|
4634
4651
|
...new Uint8Array(
|
|
4635
|
-
await globalThis.crypto.subtle.digest("SHA-256",
|
|
4652
|
+
await globalThis.crypto.subtle.digest("SHA-256", bytes6)
|
|
4636
4653
|
)
|
|
4637
|
-
].map((b) => b.toString(16).padStart(2, "0")).join("") !==
|
|
4638
|
-
snapshots.push({ ...
|
|
4654
|
+
].map((b) => b.toString(16).padStart(2, "0")).join("") !== ref18.sha256) {
|
|
4655
|
+
snapshots.push({ ...ref18, status: "failed" });
|
|
4639
4656
|
problem(
|
|
4640
4657
|
"SNAPSHOT.DIGEST",
|
|
4641
4658
|
pointer6,
|
|
@@ -4647,10 +4664,10 @@ async function evaluateContextClaimHistory(input, options) {
|
|
|
4647
4664
|
let value;
|
|
4648
4665
|
try {
|
|
4649
4666
|
value = JSON.parse(
|
|
4650
|
-
new TextDecoder("utf-8", { fatal: true }).decode(
|
|
4667
|
+
new TextDecoder("utf-8", { fatal: true }).decode(bytes6)
|
|
4651
4668
|
);
|
|
4652
4669
|
} catch {
|
|
4653
|
-
snapshots.push({ ...
|
|
4670
|
+
snapshots.push({ ...ref18, status: "failed" });
|
|
4654
4671
|
problem(
|
|
4655
4672
|
"SNAPSHOT.JSON",
|
|
4656
4673
|
pointer6,
|
|
@@ -4659,8 +4676,8 @@ async function evaluateContextClaimHistory(input, options) {
|
|
|
4659
4676
|
);
|
|
4660
4677
|
return;
|
|
4661
4678
|
}
|
|
4662
|
-
snapshots.push({ ...
|
|
4663
|
-
if (!value || typeof value !== "object" || value.id !==
|
|
4679
|
+
snapshots.push({ ...ref18, status: "passed" });
|
|
4680
|
+
if (!value || typeof value !== "object" || value.id !== ref18.documentId) {
|
|
4664
4681
|
problem(
|
|
4665
4682
|
"SNAPSHOT.IDENTITY",
|
|
4666
4683
|
pointer6,
|
|
@@ -4721,8 +4738,8 @@ async function evaluateContextClaimHistory(input, options) {
|
|
|
4721
4738
|
const value = assertion.content.value;
|
|
4722
4739
|
if (value === void 0) continue;
|
|
4723
4740
|
if (field2 === "productRefs") {
|
|
4724
|
-
for (const
|
|
4725
|
-
if (!sources.has(
|
|
4741
|
+
for (const ref18 of value)
|
|
4742
|
+
if (!sources.has(ref18))
|
|
4726
4743
|
problem(
|
|
4727
4744
|
"REF.LOCAL_RESOLUTION",
|
|
4728
4745
|
ep,
|
|
@@ -4730,8 +4747,8 @@ async function evaluateContextClaimHistory(input, options) {
|
|
|
4730
4747
|
);
|
|
4731
4748
|
}
|
|
4732
4749
|
if (field2 === "acquisitionIds") {
|
|
4733
|
-
for (const
|
|
4734
|
-
if (!acquisitionIds?.has(
|
|
4750
|
+
for (const id26 of value)
|
|
4751
|
+
if (!acquisitionIds?.has(id26))
|
|
4735
4752
|
problem(
|
|
4736
4753
|
"REF.ACQUISITION",
|
|
4737
4754
|
ep,
|
|
@@ -4873,9 +4890,9 @@ async function evaluateContextClaimHistory(input, options) {
|
|
|
4873
4890
|
"Assessment input must select an existing assertion on its named field."
|
|
4874
4891
|
);
|
|
4875
4892
|
};
|
|
4876
|
-
for (const [i,
|
|
4893
|
+
for (const [i, ref18] of history.data.contextRefs.entries()) {
|
|
4877
4894
|
const p = `/contextRefs/${i}`;
|
|
4878
|
-
const value = await load(
|
|
4895
|
+
const value = await load(ref18, p);
|
|
4879
4896
|
if (value === void 0) continue;
|
|
4880
4897
|
const parsed = parseObservationContext(value);
|
|
4881
4898
|
if (!parsed.success) {
|
|
@@ -4901,14 +4918,14 @@ async function evaluateContextClaimHistory(input, options) {
|
|
|
4901
4918
|
continue;
|
|
4902
4919
|
}
|
|
4903
4920
|
await checkContext(context, observation.data, p);
|
|
4904
|
-
contexts.set(
|
|
4921
|
+
contexts.set(ref18.sha256, context);
|
|
4905
4922
|
}
|
|
4906
4923
|
for (const [i, claim] of history.data.claims.entries()) {
|
|
4907
4924
|
if (claim.subject.kind === "context")
|
|
4908
4925
|
resolve2(claim.subject.reference, `/claims/${i}/subject`);
|
|
4909
4926
|
if (claim.kind === "assessment")
|
|
4910
|
-
for (const [j,
|
|
4911
|
-
resolve2(
|
|
4927
|
+
for (const [j, ref18] of (claim.contextInputRefs ?? []).entries())
|
|
4928
|
+
resolve2(ref18, `/claims/${i}/contextInputRefs/${j}`, ref18.assertionId);
|
|
4912
4929
|
}
|
|
4913
4930
|
}
|
|
4914
4931
|
const external = snapshots.some((s) => s.status === "failed") ? "failed" : snapshots.some((s) => s.status === "unavailable") || !snapshots.length ? "not_checked" : "passed";
|
|
@@ -4947,8 +4964,8 @@ async function checkLaboratoryDependencies(entities, observation, historyId, poi
|
|
|
4947
4964
|
for (const [i, e] of entities.entities.entries()) {
|
|
4948
4965
|
const p = `${pointer6}/entities/${i}`;
|
|
4949
4966
|
if (e.kind === "material" && e.selectionRef) {
|
|
4950
|
-
const
|
|
4951
|
-
const raw = await load(
|
|
4967
|
+
const ref18 = e.selectionRef;
|
|
4968
|
+
const raw = await load(ref18.document, `${p}/selectionRef/document`);
|
|
4952
4969
|
if (raw === void 0) continue;
|
|
4953
4970
|
const parsed = PhysicalSampleSelectionSchema.safeParse(raw);
|
|
4954
4971
|
if (!parsed.success) {
|
|
@@ -4992,7 +5009,7 @@ async function checkLaboratoryDependencies(entities, observation, historyId, poi
|
|
|
4992
5009
|
"Selection record is absent from the scoped observation inventory."
|
|
4993
5010
|
);
|
|
4994
5011
|
}
|
|
4995
|
-
const sample = selection.samples.find((s) => s.id ===
|
|
5012
|
+
const sample = selection.samples.find((s) => s.id === ref18.sampleId);
|
|
4996
5013
|
if (!sample)
|
|
4997
5014
|
problem(
|
|
4998
5015
|
"MATERIAL.SELECTION_SAMPLE",
|
|
@@ -5012,15 +5029,15 @@ async function checkLaboratoryDependencies(entities, observation, historyId, poi
|
|
|
5012
5029
|
"Known specimen lineage differs from the selected specimen declaration."
|
|
5013
5030
|
);
|
|
5014
5031
|
}
|
|
5015
|
-
selections.set(
|
|
5032
|
+
selections.set(ref18.document.sha256, selection);
|
|
5016
5033
|
}
|
|
5017
5034
|
if (e.kind !== "laboratory_analysis" && e.kind !== "laboratory_result")
|
|
5018
5035
|
continue;
|
|
5019
5036
|
for (const a of e.fields.reportArtifacts ?? [])
|
|
5020
5037
|
if ("value" in a.content)
|
|
5021
|
-
for (const
|
|
5022
|
-
const source = sources.get(
|
|
5023
|
-
if (!source?.digest || source.digest.value !==
|
|
5038
|
+
for (const ref18 of a.content.value) {
|
|
5039
|
+
const source = sources.get(ref18.sourceRef);
|
|
5040
|
+
if (!source?.digest || source.digest.value !== ref18.digest.value)
|
|
5024
5041
|
problem(
|
|
5025
5042
|
"LAB.REPORT_IDENTITY",
|
|
5026
5043
|
p,
|
|
@@ -5061,11 +5078,11 @@ async function checkLaboratoryDependencies(entities, observation, historyId, poi
|
|
|
5061
5078
|
}
|
|
5062
5079
|
for (const [i, e] of entities.entities.entries()) {
|
|
5063
5080
|
if (e.kind !== "material_custody_action" || !e.transferRef) continue;
|
|
5064
|
-
const p = `${pointer6}/entities/${i}/transferRef`,
|
|
5065
|
-
const sample = selections.get(
|
|
5081
|
+
const p = `${pointer6}/entities/${i}/transferRef`, ref18 = e.transferRef;
|
|
5082
|
+
const sample = selections.get(ref18.document.sha256)?.samples.find((s) => s.id === ref18.sampleId);
|
|
5066
5083
|
if (!sample) continue;
|
|
5067
5084
|
const transfers = sample.custody.state === "documented" ? sample.custody.transfers : [];
|
|
5068
|
-
const index3 = transfers.findIndex((t) => t.id ===
|
|
5085
|
+
const index3 = transfers.findIndex((t) => t.id === ref18.transferId), transfer = transfers[index3];
|
|
5069
5086
|
if (!transfer) {
|
|
5070
5087
|
problem(
|
|
5071
5088
|
"MATERIAL.SELECTION_TRANSFER",
|
|
@@ -5094,7 +5111,7 @@ async function checkLaboratoryDependencies(entities, observation, historyId, poi
|
|
|
5094
5111
|
const prior = entities.entities.find(
|
|
5095
5112
|
(p2) => p2.kind === "material_custody_action" && p2.id === predecessorId
|
|
5096
5113
|
);
|
|
5097
|
-
if (prior?.kind === "material_custody_action" && prior.transferRef?.document.sha256 ===
|
|
5114
|
+
if (prior?.kind === "material_custody_action" && prior.transferRef?.document.sha256 === ref18.document.sha256 && transfers[index3 - 1]?.id !== prior.transferRef.transferId)
|
|
5098
5115
|
problem(
|
|
5099
5116
|
"MATERIAL.TRANSFER_ORDER",
|
|
5100
5117
|
p,
|
|
@@ -5125,12 +5142,12 @@ async function evaluateEntityHistory(input, options, mode) {
|
|
|
5125
5142
|
const snapshots = [];
|
|
5126
5143
|
const contexts = /* @__PURE__ */ new Map();
|
|
5127
5144
|
const entityDocuments = /* @__PURE__ */ new Map();
|
|
5128
|
-
const problem = (code, pointer6,
|
|
5129
|
-
async function load(
|
|
5130
|
-
const supplied = options.documents.get(
|
|
5131
|
-
const
|
|
5132
|
-
if (!
|
|
5133
|
-
snapshots.push({ ...
|
|
5145
|
+
const problem = (code, pointer6, message2, stage = "semantic") => issues.push({ code, pointer: pointer6, message: message2, stage });
|
|
5146
|
+
async function load(ref18, pointer6) {
|
|
5147
|
+
const supplied = options.documents.get(ref18.sha256);
|
|
5148
|
+
const bytes6 = supplied ? Uint8Array.from(supplied) : void 0;
|
|
5149
|
+
if (!bytes6) {
|
|
5150
|
+
snapshots.push({ ...ref18, status: "unavailable" });
|
|
5134
5151
|
problem(
|
|
5135
5152
|
"SNAPSHOT.UNAVAILABLE",
|
|
5136
5153
|
pointer6,
|
|
@@ -5141,10 +5158,10 @@ async function evaluateEntityHistory(input, options, mode) {
|
|
|
5141
5158
|
}
|
|
5142
5159
|
if ([
|
|
5143
5160
|
...new Uint8Array(
|
|
5144
|
-
await globalThis.crypto.subtle.digest("SHA-256",
|
|
5161
|
+
await globalThis.crypto.subtle.digest("SHA-256", bytes6)
|
|
5145
5162
|
)
|
|
5146
|
-
].map((b) => b.toString(16).padStart(2, "0")).join("") !==
|
|
5147
|
-
snapshots.push({ ...
|
|
5163
|
+
].map((b) => b.toString(16).padStart(2, "0")).join("") !== ref18.sha256) {
|
|
5164
|
+
snapshots.push({ ...ref18, status: "failed" });
|
|
5148
5165
|
problem(
|
|
5149
5166
|
"SNAPSHOT.DIGEST",
|
|
5150
5167
|
pointer6,
|
|
@@ -5156,10 +5173,10 @@ async function evaluateEntityHistory(input, options, mode) {
|
|
|
5156
5173
|
let value;
|
|
5157
5174
|
try {
|
|
5158
5175
|
value = JSON.parse(
|
|
5159
|
-
new TextDecoder("utf-8", { fatal: true }).decode(
|
|
5176
|
+
new TextDecoder("utf-8", { fatal: true }).decode(bytes6)
|
|
5160
5177
|
);
|
|
5161
5178
|
} catch {
|
|
5162
|
-
snapshots.push({ ...
|
|
5179
|
+
snapshots.push({ ...ref18, status: "failed" });
|
|
5163
5180
|
problem(
|
|
5164
5181
|
"SNAPSHOT.JSON",
|
|
5165
5182
|
pointer6,
|
|
@@ -5168,8 +5185,8 @@ async function evaluateEntityHistory(input, options, mode) {
|
|
|
5168
5185
|
);
|
|
5169
5186
|
return;
|
|
5170
5187
|
}
|
|
5171
|
-
snapshots.push({ ...
|
|
5172
|
-
if (!value || typeof value !== "object" || value.id !==
|
|
5188
|
+
snapshots.push({ ...ref18, status: "passed" });
|
|
5189
|
+
if (!value || typeof value !== "object" || value.id !== ref18.documentId) {
|
|
5173
5190
|
problem(
|
|
5174
5191
|
"SNAPSHOT.IDENTITY",
|
|
5175
5192
|
pointer6,
|
|
@@ -5230,8 +5247,8 @@ async function evaluateEntityHistory(input, options, mode) {
|
|
|
5230
5247
|
const value = assertion.content.value;
|
|
5231
5248
|
if (value === void 0) continue;
|
|
5232
5249
|
if (field2 === "productRefs") {
|
|
5233
|
-
for (const
|
|
5234
|
-
if (!sources.has(
|
|
5250
|
+
for (const ref18 of value)
|
|
5251
|
+
if (!sources.has(ref18))
|
|
5235
5252
|
problem(
|
|
5236
5253
|
"REF.LOCAL_RESOLUTION",
|
|
5237
5254
|
ep,
|
|
@@ -5239,8 +5256,8 @@ async function evaluateEntityHistory(input, options, mode) {
|
|
|
5239
5256
|
);
|
|
5240
5257
|
}
|
|
5241
5258
|
if (field2 === "acquisitionIds") {
|
|
5242
|
-
for (const
|
|
5243
|
-
if (!acquisitionIds?.has(
|
|
5259
|
+
for (const id26 of value)
|
|
5260
|
+
if (!acquisitionIds?.has(id26))
|
|
5244
5261
|
problem(
|
|
5245
5262
|
"REF.ACQUISITION",
|
|
5246
5263
|
ep,
|
|
@@ -5438,9 +5455,9 @@ async function evaluateEntityHistory(input, options, mode) {
|
|
|
5438
5455
|
"Citation exceeds the edition's explicitly declared page count."
|
|
5439
5456
|
);
|
|
5440
5457
|
};
|
|
5441
|
-
for (const [i,
|
|
5458
|
+
for (const [i, ref18] of history.data.contextRefs.entries()) {
|
|
5442
5459
|
const p = `/contextRefs/${i}`;
|
|
5443
|
-
const value = await load(
|
|
5460
|
+
const value = await load(ref18, p);
|
|
5444
5461
|
if (value === void 0) continue;
|
|
5445
5462
|
const parsed = parseObservationContext(value);
|
|
5446
5463
|
if (!parsed.success) {
|
|
@@ -5466,11 +5483,11 @@ async function evaluateEntityHistory(input, options, mode) {
|
|
|
5466
5483
|
continue;
|
|
5467
5484
|
}
|
|
5468
5485
|
await checkContext(context, observation.data, p);
|
|
5469
|
-
contexts.set(
|
|
5486
|
+
contexts.set(ref18.sha256, context);
|
|
5470
5487
|
}
|
|
5471
|
-
for (const [i,
|
|
5488
|
+
for (const [i, ref18] of history.data.entityRefs.entries()) {
|
|
5472
5489
|
const p = `/entityRefs/${i}`;
|
|
5473
|
-
const value = await load(
|
|
5490
|
+
const value = await load(ref18, p);
|
|
5474
5491
|
if (value === void 0) continue;
|
|
5475
5492
|
const parsed = mode === "laboratory" ? parseLaboratoryEntities(value) : archival ? parseArchivalEntities(value) : parseResearchEntities(value);
|
|
5476
5493
|
if (!parsed.success) {
|
|
@@ -5537,9 +5554,9 @@ async function evaluateEntityHistory(input, options, mode) {
|
|
|
5537
5554
|
);
|
|
5538
5555
|
}
|
|
5539
5556
|
if (archival) {
|
|
5540
|
-
for (const
|
|
5541
|
-
const source = sources.get(
|
|
5542
|
-
if (!source?.digest || source.digest.value !==
|
|
5557
|
+
for (const ref19 of "artifact" in entity ? archivalArtifactReferences(entity) : []) {
|
|
5558
|
+
const source = sources.get(ref19.sourceRef);
|
|
5559
|
+
if (!source?.digest || source.digest.value !== ref19.digest.value)
|
|
5543
5560
|
problem(
|
|
5544
5561
|
"ARCHIVE.ARTIFACT_IDENTITY",
|
|
5545
5562
|
ep,
|
|
@@ -5571,7 +5588,7 @@ async function evaluateEntityHistory(input, options, mode) {
|
|
|
5571
5588
|
load,
|
|
5572
5589
|
problem
|
|
5573
5590
|
);
|
|
5574
|
-
entityDocuments.set(
|
|
5591
|
+
entityDocuments.set(ref18.sha256, entities);
|
|
5575
5592
|
}
|
|
5576
5593
|
for (const [i, claim] of history.data.claims.entries()) {
|
|
5577
5594
|
if (archival) {
|
|
@@ -5587,17 +5604,17 @@ async function evaluateEntityHistory(input, options, mode) {
|
|
|
5587
5604
|
if (claim.subject.kind === "entity")
|
|
5588
5605
|
resolveEntity2(claim.subject.reference, `/claims/${i}/subject`);
|
|
5589
5606
|
if (claim.kind === "assessment")
|
|
5590
|
-
for (const [j,
|
|
5607
|
+
for (const [j, ref18] of (claim.entityInputRefs ?? []).entries())
|
|
5591
5608
|
resolveEntity2(
|
|
5592
|
-
|
|
5609
|
+
ref18,
|
|
5593
5610
|
`/claims/${i}/entityInputRefs/${j}`,
|
|
5594
|
-
|
|
5611
|
+
ref18.assertionId
|
|
5595
5612
|
);
|
|
5596
5613
|
if (claim.subject.kind === "context")
|
|
5597
5614
|
resolve2(claim.subject.reference, `/claims/${i}/subject`);
|
|
5598
5615
|
if (claim.kind === "assessment")
|
|
5599
|
-
for (const [j,
|
|
5600
|
-
resolve2(
|
|
5616
|
+
for (const [j, ref18] of (claim.contextInputRefs ?? []).entries())
|
|
5617
|
+
resolve2(ref18, `/claims/${i}/contextInputRefs/${j}`, ref18.assertionId);
|
|
5601
5618
|
}
|
|
5602
5619
|
}
|
|
5603
5620
|
const external = snapshots.some((s) => s.status === "failed") ? "failed" : snapshots.some((s) => s.status === "unavailable") || !snapshots.length ? "not_checked" : "passed";
|
|
@@ -5639,7 +5656,10 @@ async function evaluateLaboratoryClaimHistory(input, options) {
|
|
|
5639
5656
|
};
|
|
5640
5657
|
}
|
|
5641
5658
|
async function evaluateCaseRecord(input, options) {
|
|
5642
|
-
|
|
5659
|
+
return evaluateCaseRecordWithParser(input, options, parseCaseRecord);
|
|
5660
|
+
}
|
|
5661
|
+
async function evaluateCaseRecordWithParser(input, options, parse) {
|
|
5662
|
+
const parsed = parse(input);
|
|
5643
5663
|
const result = {
|
|
5644
5664
|
success: false,
|
|
5645
5665
|
issues: [...parsed.issues],
|
|
@@ -5657,20 +5677,20 @@ async function evaluateCaseRecord(input, options) {
|
|
|
5657
5677
|
const data = parsed.data;
|
|
5658
5678
|
const supplied = new Map(
|
|
5659
5679
|
data.observationRefs.map((r) => {
|
|
5660
|
-
const
|
|
5661
|
-
return [r.sha256,
|
|
5680
|
+
const bytes6 = options.documents.get(r.sha256);
|
|
5681
|
+
return [r.sha256, bytes6 ? Uint8Array.from(bytes6) : void 0];
|
|
5662
5682
|
})
|
|
5663
5683
|
);
|
|
5664
5684
|
const observations = /* @__PURE__ */ new Map();
|
|
5665
|
-
const problem = (code, pointer6,
|
|
5666
|
-
for (const [i,
|
|
5667
|
-
const p = `/observationRefs/${i}`,
|
|
5685
|
+
const problem = (code, pointer6, message2) => result.issues.push({ code, stage: "external", pointer: pointer6, message: message2 });
|
|
5686
|
+
for (const [i, ref18] of data.observationRefs.entries()) {
|
|
5687
|
+
const p = `/observationRefs/${i}`, bytes6 = supplied.get(ref18.sha256);
|
|
5668
5688
|
const snapshot3 = {
|
|
5669
|
-
...
|
|
5689
|
+
...ref18,
|
|
5670
5690
|
status: "failed"
|
|
5671
5691
|
};
|
|
5672
5692
|
result.snapshots.push(snapshot3);
|
|
5673
|
-
if (!
|
|
5693
|
+
if (!bytes6) {
|
|
5674
5694
|
snapshot3.status = "unavailable";
|
|
5675
5695
|
problem(
|
|
5676
5696
|
"SNAPSHOT.UNAVAILABLE",
|
|
@@ -5679,10 +5699,10 @@ async function evaluateCaseRecord(input, options) {
|
|
|
5679
5699
|
);
|
|
5680
5700
|
continue;
|
|
5681
5701
|
}
|
|
5682
|
-
const
|
|
5683
|
-
new Uint8Array(await crypto.subtle.digest("SHA-256",
|
|
5702
|
+
const hash8 = Array.from(
|
|
5703
|
+
new Uint8Array(await crypto.subtle.digest("SHA-256", bytes6))
|
|
5684
5704
|
).map((n) => n.toString(16).padStart(2, "0")).join("");
|
|
5685
|
-
if (
|
|
5705
|
+
if (hash8 !== ref18.sha256) {
|
|
5686
5706
|
problem(
|
|
5687
5707
|
"SNAPSHOT.DIGEST",
|
|
5688
5708
|
p,
|
|
@@ -5692,13 +5712,13 @@ async function evaluateCaseRecord(input, options) {
|
|
|
5692
5712
|
}
|
|
5693
5713
|
let raw;
|
|
5694
5714
|
try {
|
|
5695
|
-
raw = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(
|
|
5715
|
+
raw = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes6));
|
|
5696
5716
|
} catch {
|
|
5697
5717
|
problem("SNAPSHOT.JSON", p, "Snapshot is not valid UTF-8 JSON.");
|
|
5698
5718
|
continue;
|
|
5699
5719
|
}
|
|
5700
5720
|
const observation = parseExperimentalObservation(raw);
|
|
5701
|
-
if (!observation.success) {
|
|
5721
|
+
if (!observation.success || ref18.schemaId !== `urn:disclosureos:experimental:observation:${observation.data.schemaVersion}`) {
|
|
5702
5722
|
problem(
|
|
5703
5723
|
"SNAPSHOT.CONTRACT",
|
|
5704
5724
|
p,
|
|
@@ -5706,7 +5726,7 @@ async function evaluateCaseRecord(input, options) {
|
|
|
5706
5726
|
);
|
|
5707
5727
|
continue;
|
|
5708
5728
|
}
|
|
5709
|
-
if (observation.data.id !==
|
|
5729
|
+
if (observation.data.id !== ref18.documentId) {
|
|
5710
5730
|
problem(
|
|
5711
5731
|
"SNAPSHOT.IDENTITY",
|
|
5712
5732
|
p,
|
|
@@ -5714,14 +5734,14 @@ async function evaluateCaseRecord(input, options) {
|
|
|
5714
5734
|
);
|
|
5715
5735
|
continue;
|
|
5716
5736
|
}
|
|
5717
|
-
observations.set(
|
|
5737
|
+
observations.set(ref18.documentId, observation.data);
|
|
5718
5738
|
snapshot3.status = "passed";
|
|
5719
5739
|
}
|
|
5720
5740
|
for (const { pointer: pointer6, provenance: p } of caseProvenances(data)) {
|
|
5721
5741
|
const observation = observations.get(p.observationId);
|
|
5722
5742
|
if (!observation) continue;
|
|
5723
|
-
const [kind,
|
|
5724
|
-
const artifact2 = (kind === "source" ? observation.sources : observation.products).find((s) => s.id ===
|
|
5743
|
+
const [kind, id26] = p.sourceRef.split(":");
|
|
5744
|
+
const artifact2 = (kind === "source" ? observation.sources : observation.products).find((s) => s.id === id26);
|
|
5725
5745
|
if (!artifact2)
|
|
5726
5746
|
problem(
|
|
5727
5747
|
"CASE.SOURCE_SCOPE",
|
|
@@ -5755,8 +5775,14 @@ async function evaluateCaseRecord(input, options) {
|
|
|
5755
5775
|
result.declaredChronology = result.success ? "acyclic" : "incomplete";
|
|
5756
5776
|
return result;
|
|
5757
5777
|
}
|
|
5778
|
+
function evaluateCaseRecordV02(input, options) {
|
|
5779
|
+
return evaluateCaseRecordWithParser(input, options, parseCaseRecordV02);
|
|
5780
|
+
}
|
|
5758
5781
|
async function evaluateCaseClaimHistory(input, options) {
|
|
5759
|
-
|
|
5782
|
+
return evaluateCaseHistoryWithParsers(input, options, parseCaseClaimHistory, parseCaseRecord, evaluateCaseRecord);
|
|
5783
|
+
}
|
|
5784
|
+
async function evaluateCaseHistoryWithParsers(input, options, parseHistory, parseCase, evaluateCase) {
|
|
5785
|
+
const history = parseHistory(input);
|
|
5760
5786
|
const result = {
|
|
5761
5787
|
success: false,
|
|
5762
5788
|
issues: [...history.issues],
|
|
@@ -5771,35 +5797,35 @@ async function evaluateCaseClaimHistory(input, options) {
|
|
|
5771
5797
|
};
|
|
5772
5798
|
if (!history.success) return result;
|
|
5773
5799
|
const data = history.data, copies = /* @__PURE__ */ new Map();
|
|
5774
|
-
const
|
|
5775
|
-
if (!copies.has(
|
|
5776
|
-
const value = options.documents.get(
|
|
5777
|
-
if (value) copies.set(
|
|
5800
|
+
const copy2 = (hash8) => {
|
|
5801
|
+
if (!copies.has(hash8)) {
|
|
5802
|
+
const value = options.documents.get(hash8);
|
|
5803
|
+
if (value) copies.set(hash8, Uint8Array.from(value));
|
|
5778
5804
|
}
|
|
5779
5805
|
};
|
|
5780
|
-
for (const
|
|
5781
|
-
for (const
|
|
5806
|
+
for (const ref18 of data.caseRefs) copy2(ref18.sha256);
|
|
5807
|
+
for (const ref18 of data.caseRefs) {
|
|
5782
5808
|
try {
|
|
5783
|
-
const
|
|
5784
|
-
if (!
|
|
5785
|
-
const peek =
|
|
5786
|
-
JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(
|
|
5809
|
+
const bytes6 = copies.get(ref18.sha256);
|
|
5810
|
+
if (!bytes6) continue;
|
|
5811
|
+
const peek = parseCase(
|
|
5812
|
+
JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes6))
|
|
5787
5813
|
);
|
|
5788
5814
|
if (peek.success)
|
|
5789
|
-
peek.data.observationRefs.forEach((r) =>
|
|
5815
|
+
peek.data.observationRefs.forEach((r) => copy2(r.sha256));
|
|
5790
5816
|
} catch {
|
|
5791
5817
|
}
|
|
5792
5818
|
}
|
|
5793
|
-
const problem = (code, pointer6,
|
|
5819
|
+
const problem = (code, pointer6, message2) => result.issues.push({ code, stage: "external", pointer: pointer6, message: message2 });
|
|
5794
5820
|
const snapshots = /* @__PURE__ */ new Map();
|
|
5795
|
-
async function load(
|
|
5821
|
+
async function load(ref18, p) {
|
|
5796
5822
|
const item = {
|
|
5797
|
-
...
|
|
5823
|
+
...ref18,
|
|
5798
5824
|
status: "failed"
|
|
5799
5825
|
};
|
|
5800
|
-
snapshots.set(caseSnapshotKey(
|
|
5801
|
-
const
|
|
5802
|
-
if (!
|
|
5826
|
+
snapshots.set(caseSnapshotKey(ref18), item);
|
|
5827
|
+
const bytes6 = copies.get(ref18.sha256);
|
|
5828
|
+
if (!bytes6) {
|
|
5803
5829
|
item.status = "unavailable";
|
|
5804
5830
|
problem(
|
|
5805
5831
|
"SNAPSHOT.UNAVAILABLE",
|
|
@@ -5808,10 +5834,10 @@ async function evaluateCaseClaimHistory(input, options) {
|
|
|
5808
5834
|
);
|
|
5809
5835
|
return;
|
|
5810
5836
|
}
|
|
5811
|
-
const
|
|
5812
|
-
new Uint8Array(await crypto.subtle.digest("SHA-256",
|
|
5837
|
+
const digest12 = Array.from(
|
|
5838
|
+
new Uint8Array(await crypto.subtle.digest("SHA-256", bytes6))
|
|
5813
5839
|
).map((n) => n.toString(16).padStart(2, "0")).join("");
|
|
5814
|
-
if (
|
|
5840
|
+
if (digest12 !== ref18.sha256) {
|
|
5815
5841
|
problem(
|
|
5816
5842
|
"SNAPSHOT.DIGEST",
|
|
5817
5843
|
p,
|
|
@@ -5821,18 +5847,18 @@ async function evaluateCaseClaimHistory(input, options) {
|
|
|
5821
5847
|
}
|
|
5822
5848
|
try {
|
|
5823
5849
|
return JSON.parse(
|
|
5824
|
-
new TextDecoder("utf-8", { fatal: true }).decode(
|
|
5850
|
+
new TextDecoder("utf-8", { fatal: true }).decode(bytes6)
|
|
5825
5851
|
);
|
|
5826
5852
|
} catch {
|
|
5827
5853
|
problem("SNAPSHOT.JSON", p, "Snapshot is not valid UTF-8 JSON.");
|
|
5828
5854
|
}
|
|
5829
5855
|
}
|
|
5830
5856
|
const cases = /* @__PURE__ */ new Map(), observations = /* @__PURE__ */ new Map();
|
|
5831
|
-
for (const [i,
|
|
5832
|
-
const p = `/caseRefs/${i}`, raw = await load(
|
|
5857
|
+
for (const [i, ref18] of data.caseRefs.entries()) {
|
|
5858
|
+
const p = `/caseRefs/${i}`, raw = await load(ref18, p);
|
|
5833
5859
|
if (raw === void 0) continue;
|
|
5834
|
-
const parsed =
|
|
5835
|
-
if (!parsed.success) {
|
|
5860
|
+
const parsed = parseCase(raw);
|
|
5861
|
+
if (!parsed.success || ref18.schemaId !== `urn:disclosureos:experimental:case-record:${parsed.data.schemaVersion}`) {
|
|
5836
5862
|
problem(
|
|
5837
5863
|
"SNAPSHOT.CONTRACT",
|
|
5838
5864
|
p,
|
|
@@ -5840,13 +5866,13 @@ async function evaluateCaseClaimHistory(input, options) {
|
|
|
5840
5866
|
);
|
|
5841
5867
|
continue;
|
|
5842
5868
|
}
|
|
5843
|
-
if (parsed.data.id !==
|
|
5869
|
+
if (parsed.data.id !== ref18.documentId) {
|
|
5844
5870
|
problem("SNAPSHOT.IDENTITY", p, "Case ID differs from its reference.");
|
|
5845
5871
|
continue;
|
|
5846
5872
|
}
|
|
5847
|
-
snapshots.get(caseSnapshotKey(
|
|
5848
|
-
cases.set(caseSnapshotKey(
|
|
5849
|
-
const checked = await
|
|
5873
|
+
snapshots.get(caseSnapshotKey(ref18)).status = "passed";
|
|
5874
|
+
cases.set(caseSnapshotKey(ref18), parsed.data);
|
|
5875
|
+
const checked = await evaluateCase(parsed.data, {
|
|
5850
5876
|
documents: copies
|
|
5851
5877
|
});
|
|
5852
5878
|
result.issues.push(
|
|
@@ -5873,10 +5899,10 @@ async function evaluateCaseClaimHistory(input, options) {
|
|
|
5873
5899
|
function observation(r, p) {
|
|
5874
5900
|
const owner = cases.get(caseSnapshotKey(r.case));
|
|
5875
5901
|
if (!owner) return;
|
|
5876
|
-
const
|
|
5902
|
+
const ref18 = owner.observationRefs.find(
|
|
5877
5903
|
(s) => s.documentId === r.observationId
|
|
5878
5904
|
);
|
|
5879
|
-
if (!
|
|
5905
|
+
if (!ref18) {
|
|
5880
5906
|
problem(
|
|
5881
5907
|
"CASE.OBSERVATION_SCOPE",
|
|
5882
5908
|
p,
|
|
@@ -5884,8 +5910,8 @@ async function evaluateCaseClaimHistory(input, options) {
|
|
|
5884
5910
|
);
|
|
5885
5911
|
return;
|
|
5886
5912
|
}
|
|
5887
|
-
const value = observations.get(caseSnapshotKey(
|
|
5888
|
-
return value ? { value, ref:
|
|
5913
|
+
const value = observations.get(caseSnapshotKey(ref18));
|
|
5914
|
+
return value ? { value, ref: ref18 } : void 0;
|
|
5889
5915
|
}
|
|
5890
5916
|
function entity(document, target, p) {
|
|
5891
5917
|
const owner = cases.get(caseSnapshotKey(document));
|
|
@@ -5929,8 +5955,8 @@ async function evaluateCaseClaimHistory(input, options) {
|
|
|
5929
5955
|
if (c.kind === "source_assertion") {
|
|
5930
5956
|
const owner = observation(c.provenance, `${p}/provenance`);
|
|
5931
5957
|
if (!owner) continue;
|
|
5932
|
-
const [kind,
|
|
5933
|
-
const artifact2 = (kind === "source" ? owner.value.sources : owner.value.products).find((a) => a.id ===
|
|
5958
|
+
const [kind, id26] = c.provenance.sourceRef.split(":");
|
|
5959
|
+
const artifact2 = (kind === "source" ? owner.value.sources : owner.value.products).find((a) => a.id === id26);
|
|
5934
5960
|
if (!artifact2)
|
|
5935
5961
|
problem(
|
|
5936
5962
|
"CASE.SOURCE_SCOPE",
|
|
@@ -5960,9 +5986,9 @@ async function evaluateCaseClaimHistory(input, options) {
|
|
|
5960
5986
|
for (const [j, r] of (c.observationInputRefs ?? []).entries()) {
|
|
5961
5987
|
const q = `${p}/observationInputRefs/${j}`, o = observation(r, q)?.value;
|
|
5962
5988
|
if (!o) continue;
|
|
5963
|
-
const [kind,
|
|
5989
|
+
const [kind, id26] = r.ref.split(":");
|
|
5964
5990
|
const rows = kind === "source" ? o.sources : kind === "product" ? o.products : kind === "assertion" ? o.assertions : o.measurements;
|
|
5965
|
-
if (!rows.some((e) => e.id ===
|
|
5991
|
+
if (!rows.some((e) => e.id === id26))
|
|
5966
5992
|
problem(
|
|
5967
5993
|
"CASE.INPUT_RESOLUTION",
|
|
5968
5994
|
q,
|
|
@@ -5994,6 +6020,14 @@ async function evaluateCaseClaimHistory(input, options) {
|
|
|
5994
6020
|
result.snapshots = [...snapshots.values()];
|
|
5995
6021
|
return result;
|
|
5996
6022
|
}
|
|
6023
|
+
function evaluateCaseClaimHistoryV02(input, options) {
|
|
6024
|
+
const parse = (value) => {
|
|
6025
|
+
const old = parseCaseRecord(value);
|
|
6026
|
+
return old.success ? old : parseCaseRecordV02(value);
|
|
6027
|
+
};
|
|
6028
|
+
const evaluate = (value, opts) => parseCaseRecord(value).success ? evaluateCaseRecord(value, opts) : evaluateCaseRecordV02(value, opts);
|
|
6029
|
+
return evaluateCaseHistoryWithParsers(input, options, parseCaseClaimHistoryV02, parse, evaluate);
|
|
6030
|
+
}
|
|
5997
6031
|
async function evaluateCaseLinks(input, options) {
|
|
5998
6032
|
const parsed = parseCaseLinks(input);
|
|
5999
6033
|
const result = {
|
|
@@ -6011,40 +6045,40 @@ async function evaluateCaseLinks(input, options) {
|
|
|
6011
6045
|
};
|
|
6012
6046
|
if (!parsed.success) return result;
|
|
6013
6047
|
const data = parsed.data, copies = /* @__PURE__ */ new Map();
|
|
6014
|
-
const
|
|
6015
|
-
if (!copies.has(
|
|
6016
|
-
const
|
|
6017
|
-
if (
|
|
6048
|
+
const copy2 = (hash8) => {
|
|
6049
|
+
if (!copies.has(hash8)) {
|
|
6050
|
+
const bytes6 = options.documents.get(hash8);
|
|
6051
|
+
if (bytes6) copies.set(hash8, Uint8Array.from(bytes6));
|
|
6018
6052
|
}
|
|
6019
6053
|
};
|
|
6020
|
-
|
|
6054
|
+
copy2(data.caseRef.sha256);
|
|
6021
6055
|
data.links.forEach(
|
|
6022
|
-
(l) =>
|
|
6056
|
+
(l) => copy2(l.kind === "intake" ? l.document.sha256 : l.reference.document.sha256)
|
|
6023
6057
|
);
|
|
6024
6058
|
try {
|
|
6025
|
-
const
|
|
6026
|
-
if (
|
|
6059
|
+
const bytes6 = copies.get(data.caseRef.sha256);
|
|
6060
|
+
if (bytes6) {
|
|
6027
6061
|
const peek = parseCaseRecord(
|
|
6028
|
-
JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(
|
|
6062
|
+
JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes6))
|
|
6029
6063
|
);
|
|
6030
6064
|
if (peek.success)
|
|
6031
|
-
peek.data.observationRefs.forEach((r) =>
|
|
6065
|
+
peek.data.observationRefs.forEach((r) => copy2(r.sha256));
|
|
6032
6066
|
}
|
|
6033
6067
|
} catch {
|
|
6034
6068
|
}
|
|
6035
|
-
const problem = (code, pointer6,
|
|
6069
|
+
const problem = (code, pointer6, message2) => result.issues.push({ code, stage: "external", pointer: pointer6, message: message2 });
|
|
6036
6070
|
const snapshots = /* @__PURE__ */ new Map();
|
|
6037
6071
|
const loaded = /* @__PURE__ */ new Map();
|
|
6038
|
-
async function load(
|
|
6039
|
-
const key3 = caseSnapshotKey(
|
|
6072
|
+
async function load(ref18, p) {
|
|
6073
|
+
const key3 = caseSnapshotKey(ref18);
|
|
6040
6074
|
if (loaded.has(key3)) return loaded.get(key3);
|
|
6041
6075
|
const snapshot3 = {
|
|
6042
|
-
...
|
|
6076
|
+
...ref18,
|
|
6043
6077
|
status: "failed"
|
|
6044
6078
|
};
|
|
6045
6079
|
snapshots.set(key3, snapshot3);
|
|
6046
|
-
const
|
|
6047
|
-
if (!
|
|
6080
|
+
const bytes6 = copies.get(ref18.sha256);
|
|
6081
|
+
if (!bytes6) {
|
|
6048
6082
|
snapshot3.status = "unavailable";
|
|
6049
6083
|
problem(
|
|
6050
6084
|
"SNAPSHOT.UNAVAILABLE",
|
|
@@ -6053,10 +6087,10 @@ async function evaluateCaseLinks(input, options) {
|
|
|
6053
6087
|
);
|
|
6054
6088
|
return;
|
|
6055
6089
|
}
|
|
6056
|
-
const
|
|
6057
|
-
new Uint8Array(await crypto.subtle.digest("SHA-256",
|
|
6090
|
+
const digest12 = Array.from(
|
|
6091
|
+
new Uint8Array(await crypto.subtle.digest("SHA-256", bytes6))
|
|
6058
6092
|
).map((n) => n.toString(16).padStart(2, "0")).join("");
|
|
6059
|
-
if (
|
|
6093
|
+
if (digest12 !== ref18.sha256) {
|
|
6060
6094
|
problem(
|
|
6061
6095
|
"SNAPSHOT.DIGEST",
|
|
6062
6096
|
p,
|
|
@@ -6066,12 +6100,12 @@ async function evaluateCaseLinks(input, options) {
|
|
|
6066
6100
|
}
|
|
6067
6101
|
let raw;
|
|
6068
6102
|
try {
|
|
6069
|
-
raw = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(
|
|
6103
|
+
raw = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes6));
|
|
6070
6104
|
} catch {
|
|
6071
6105
|
problem("SNAPSHOT.JSON", p, "Snapshot is not valid UTF-8 JSON.");
|
|
6072
6106
|
return;
|
|
6073
6107
|
}
|
|
6074
|
-
if (!raw || typeof raw !== "object" || !("id" in raw) || raw.id !==
|
|
6108
|
+
if (!raw || typeof raw !== "object" || !("id" in raw) || raw.id !== ref18.documentId) {
|
|
6075
6109
|
problem(
|
|
6076
6110
|
"SNAPSHOT.IDENTITY",
|
|
6077
6111
|
p,
|
|
@@ -6141,8 +6175,8 @@ async function evaluateCaseLinks(input, options) {
|
|
|
6141
6175
|
"Basis provenance is outside the case snapshot."
|
|
6142
6176
|
);
|
|
6143
6177
|
else if (sourceOwner) {
|
|
6144
|
-
const [kind,
|
|
6145
|
-
const source = (kind === "source" ? sourceOwner.sources : sourceOwner.products).find((s) => s.id ===
|
|
6178
|
+
const [kind, id26] = prov.sourceRef.split(":");
|
|
6179
|
+
const source = (kind === "source" ? sourceOwner.sources : sourceOwner.products).find((s) => s.id === id26);
|
|
6146
6180
|
if (!source)
|
|
6147
6181
|
problem(
|
|
6148
6182
|
"CASE.SOURCE_SCOPE",
|
|
@@ -6156,7 +6190,7 @@ async function evaluateCaseLinks(input, options) {
|
|
|
6156
6190
|
"Declared source digests differ."
|
|
6157
6191
|
);
|
|
6158
6192
|
}
|
|
6159
|
-
const
|
|
6193
|
+
const ref18 = l.kind === "intake" ? l.document : l.reference.document, raw = await load(ref18, p);
|
|
6160
6194
|
if (raw === void 0) continue;
|
|
6161
6195
|
if (l.kind === "intake") {
|
|
6162
6196
|
const intake = SourceIntakeSchema.safeParse(raw);
|
|
@@ -6176,7 +6210,7 @@ async function evaluateCaseLinks(input, options) {
|
|
|
6176
6210
|
);
|
|
6177
6211
|
continue;
|
|
6178
6212
|
}
|
|
6179
|
-
snapshots.get(caseSnapshotKey(
|
|
6213
|
+
snapshots.get(caseSnapshotKey(ref18)).status = "passed";
|
|
6180
6214
|
for (const [j, a] of (l.artifactLinks ?? []).entries()) {
|
|
6181
6215
|
const q = `${p}/artifactLinks/${j}`, artifact2 = intake.data.artifacts.find(
|
|
6182
6216
|
(item) => item.id === a.artifactId
|
|
@@ -6190,8 +6224,8 @@ async function evaluateCaseLinks(input, options) {
|
|
|
6190
6224
|
continue;
|
|
6191
6225
|
}
|
|
6192
6226
|
if (!observation) continue;
|
|
6193
|
-
const [kind,
|
|
6194
|
-
const inventory = (kind === "source" ? observation.sources : observation.products).find((item) => item.id ===
|
|
6227
|
+
const [kind, id26] = a.observationRef.split(":");
|
|
6228
|
+
const inventory = (kind === "source" ? observation.sources : observation.products).find((item) => item.id === id26);
|
|
6195
6229
|
if (!inventory)
|
|
6196
6230
|
problem(
|
|
6197
6231
|
"CASE.INPUT_RESOLUTION",
|
|
@@ -6213,7 +6247,7 @@ async function evaluateCaseLinks(input, options) {
|
|
|
6213
6247
|
}
|
|
6214
6248
|
continue;
|
|
6215
6249
|
}
|
|
6216
|
-
const supplement = l.kind === "context" ? parseObservationContext(raw) :
|
|
6250
|
+
const supplement = l.kind === "context" ? parseObservationContext(raw) : ref18.schemaId === "urn:disclosureos:experimental:research-entities:0.1.0" ? parseResearchEntities(raw) : ref18.schemaId === "urn:disclosureos:experimental:research-entities:0.2.0" ? parseArchivalEntities(raw) : ref18.schemaId === "urn:disclosureos:experimental:research-entities:0.3.0" ? parseMaterialEntities(raw) : parseLaboratoryEntities(raw);
|
|
6217
6251
|
if (!supplement.success) {
|
|
6218
6252
|
problem(
|
|
6219
6253
|
"SNAPSHOT.CONTRACT",
|
|
@@ -6222,7 +6256,7 @@ async function evaluateCaseLinks(input, options) {
|
|
|
6222
6256
|
);
|
|
6223
6257
|
continue;
|
|
6224
6258
|
}
|
|
6225
|
-
snapshots.get(caseSnapshotKey(
|
|
6259
|
+
snapshots.get(caseSnapshotKey(ref18)).status = "passed";
|
|
6226
6260
|
result.supplements.push({
|
|
6227
6261
|
linkId: l.id,
|
|
6228
6262
|
uncheckedRefs: [...supplement.uncheckedRefs],
|
|
@@ -6336,7 +6370,7 @@ var CasePresentationSchema = z.strictObject({
|
|
|
6336
6370
|
});
|
|
6337
6371
|
function casePresentationJsonSchema() {
|
|
6338
6372
|
return {
|
|
6339
|
-
...z.toJSONSchema(CasePresentationSchema, { target: "draft-2020-12", reused: "ref" }),
|
|
6373
|
+
...preservePublishedSchema(z.toJSONSchema(CasePresentationSchema, { target: "draft-2020-12", reused: "ref" })),
|
|
6340
6374
|
$id: CASE_PRESENTATION_SCHEMA_ID
|
|
6341
6375
|
};
|
|
6342
6376
|
}
|
|
@@ -6374,17 +6408,17 @@ function parseCasePresentation(input) {
|
|
|
6374
6408
|
return { success: true, data: d };
|
|
6375
6409
|
}
|
|
6376
6410
|
var approvalSchema = z.strictObject({ presentationSha256: sha256, policyVersion: short });
|
|
6377
|
-
async function digest3(
|
|
6378
|
-
return Array.from(new Uint8Array(await crypto.subtle.digest("SHA-256", Uint8Array.from(
|
|
6411
|
+
async function digest3(bytes6) {
|
|
6412
|
+
return Array.from(new Uint8Array(await crypto.subtle.digest("SHA-256", Uint8Array.from(bytes6)))).map((n) => n.toString(16).padStart(2, "0")).join("");
|
|
6379
6413
|
}
|
|
6380
|
-
var decode3 = (
|
|
6414
|
+
var decode3 = (bytes6) => JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes6));
|
|
6381
6415
|
async function buildPublicCase(presentationBytes, options) {
|
|
6382
6416
|
const approved = approvalSchema.safeParse(options.approval);
|
|
6383
6417
|
if (!approved.success) return { success: false, code: "APPROVAL_REQUIRED" };
|
|
6384
|
-
const
|
|
6418
|
+
const bytes6 = Uint8Array.from(presentationBytes);
|
|
6385
6419
|
let parsed;
|
|
6386
6420
|
try {
|
|
6387
|
-
parsed = parseCasePresentation(decode3(
|
|
6421
|
+
parsed = parseCasePresentation(decode3(bytes6));
|
|
6388
6422
|
} catch {
|
|
6389
6423
|
return { success: false, code: "INVALID_PRESENTATION" };
|
|
6390
6424
|
}
|
|
@@ -6393,21 +6427,21 @@ async function buildPublicCase(presentationBytes, options) {
|
|
|
6393
6427
|
if (d.status === "draft" || d.status === "withdrawn")
|
|
6394
6428
|
return { success: false, code: "NOT_PUBLISHED" };
|
|
6395
6429
|
const copies = /* @__PURE__ */ new Map();
|
|
6396
|
-
const
|
|
6397
|
-
const b = options.documents.get(
|
|
6398
|
-
if (b && !copies.has(
|
|
6430
|
+
const copy2 = (hash8) => {
|
|
6431
|
+
const b = options.documents.get(hash8);
|
|
6432
|
+
if (b && !copies.has(hash8)) copies.set(hash8, Uint8Array.from(b));
|
|
6399
6433
|
};
|
|
6400
6434
|
const refs = [
|
|
6401
6435
|
d.caseRef,
|
|
6402
6436
|
...d.linksRef ? [d.linksRef] : [],
|
|
6403
6437
|
...d.findings.map((f) => f.historyRef)
|
|
6404
6438
|
];
|
|
6405
|
-
refs.forEach((r) =>
|
|
6439
|
+
refs.forEach((r) => copy2(r.sha256));
|
|
6406
6440
|
try {
|
|
6407
6441
|
const c = copies.get(d.caseRef.sha256);
|
|
6408
6442
|
if (c) {
|
|
6409
6443
|
const p = parseCaseRecord(decode3(c));
|
|
6410
|
-
if (p.success) p.data.observationRefs.forEach((r) =>
|
|
6444
|
+
if (p.success) p.data.observationRefs.forEach((r) => copy2(r.sha256));
|
|
6411
6445
|
}
|
|
6412
6446
|
for (const f of d.findings) {
|
|
6413
6447
|
const b = copies.get(f.historyRef.sha256);
|
|
@@ -6415,11 +6449,11 @@ async function buildPublicCase(presentationBytes, options) {
|
|
|
6415
6449
|
const h = parseCaseClaimHistory(decode3(b));
|
|
6416
6450
|
if (h.success)
|
|
6417
6451
|
for (const r of h.data.caseRefs) {
|
|
6418
|
-
|
|
6452
|
+
copy2(r.sha256);
|
|
6419
6453
|
const cb = copies.get(r.sha256);
|
|
6420
6454
|
if (cb) {
|
|
6421
6455
|
const p = parseCaseRecord(decode3(cb));
|
|
6422
|
-
if (p.success) p.data.observationRefs.forEach((o) =>
|
|
6456
|
+
if (p.success) p.data.observationRefs.forEach((o) => copy2(o.sha256));
|
|
6423
6457
|
}
|
|
6424
6458
|
}
|
|
6425
6459
|
}
|
|
@@ -6429,20 +6463,20 @@ async function buildPublicCase(presentationBytes, options) {
|
|
|
6429
6463
|
const links = parseCaseLinks(decode3(b));
|
|
6430
6464
|
if (links.success)
|
|
6431
6465
|
links.data.links.forEach(
|
|
6432
|
-
(l) =>
|
|
6466
|
+
(l) => copy2(l.kind === "intake" ? l.document.sha256 : l.reference.document.sha256)
|
|
6433
6467
|
);
|
|
6434
6468
|
}
|
|
6435
6469
|
}
|
|
6436
6470
|
} catch {
|
|
6437
6471
|
return { success: false, code: "INVALID_REFERENCES" };
|
|
6438
6472
|
}
|
|
6439
|
-
if (await digest3(
|
|
6473
|
+
if (await digest3(bytes6) !== approved.data.presentationSha256)
|
|
6440
6474
|
return { success: false, code: "APPROVAL_REQUIRED" };
|
|
6441
|
-
const load = async (
|
|
6442
|
-
const b = copies.get(
|
|
6443
|
-
if (!b || await digest3(b) !==
|
|
6475
|
+
const load = async (ref18) => {
|
|
6476
|
+
const b = copies.get(ref18.sha256);
|
|
6477
|
+
if (!b || await digest3(b) !== ref18.sha256) throw new Error("reference");
|
|
6444
6478
|
const raw = decode3(b);
|
|
6445
|
-
if (!raw || typeof raw !== "object" || !("id" in raw) || raw.id !==
|
|
6479
|
+
if (!raw || typeof raw !== "object" || !("id" in raw) || raw.id !== ref18.documentId)
|
|
6446
6480
|
throw new Error("reference");
|
|
6447
6481
|
return raw;
|
|
6448
6482
|
};
|
|
@@ -6458,10 +6492,10 @@ async function buildPublicCase(presentationBytes, options) {
|
|
|
6458
6492
|
return [r.documentId, p.data];
|
|
6459
6493
|
})
|
|
6460
6494
|
);
|
|
6461
|
-
const artifact2 = (observationId,
|
|
6495
|
+
const artifact2 = (observationId, ref18) => {
|
|
6462
6496
|
const o = observations.get(observationId);
|
|
6463
|
-
const [kind,
|
|
6464
|
-
return (kind === "source" ? o?.sources : o?.products)?.find((a) => a.id ===
|
|
6497
|
+
const [kind, id26] = ref18.split(":");
|
|
6498
|
+
return (kind === "source" ? o?.sources : o?.products)?.find((a) => a.id === id26);
|
|
6465
6499
|
};
|
|
6466
6500
|
const linkedIds = /* @__PURE__ */ new Set();
|
|
6467
6501
|
if (d.linksRef) {
|
|
@@ -6470,7 +6504,7 @@ async function buildPublicCase(presentationBytes, options) {
|
|
|
6470
6504
|
return invalid5();
|
|
6471
6505
|
const result = await evaluateCaseLinks(links.data, { documents: copies });
|
|
6472
6506
|
if (!result.success) return invalid5();
|
|
6473
|
-
result.resolvedLinkIds.forEach((
|
|
6507
|
+
result.resolvedLinkIds.forEach((id26) => linkedIds.add(id26));
|
|
6474
6508
|
}
|
|
6475
6509
|
for (const c of d.citations) {
|
|
6476
6510
|
if (c.target.kind === "artifact" && !artifact2(c.target.observationId, c.target.ref))
|
|
@@ -6682,10 +6716,10 @@ var ContextCasePresentationSchema = z.strictObject({
|
|
|
6682
6716
|
});
|
|
6683
6717
|
function contextCasePresentationJsonSchema() {
|
|
6684
6718
|
return {
|
|
6685
|
-
...z.toJSONSchema(ContextCasePresentationSchema, {
|
|
6719
|
+
...preservePublishedSchema(z.toJSONSchema(ContextCasePresentationSchema, {
|
|
6686
6720
|
target: "draft-2020-12",
|
|
6687
6721
|
reused: "ref"
|
|
6688
|
-
}),
|
|
6722
|
+
})),
|
|
6689
6723
|
$id: CONTEXT_CASE_PRESENTATION_SCHEMA_ID
|
|
6690
6724
|
};
|
|
6691
6725
|
}
|
|
@@ -6738,23 +6772,23 @@ async function buildPublicContextCase(input, options) {
|
|
|
6738
6772
|
return { success: false, code: "INVALID_PRESENTATION" };
|
|
6739
6773
|
const d = parsed.data, selection = d.context;
|
|
6740
6774
|
const copies = /* @__PURE__ */ new Map();
|
|
6741
|
-
const
|
|
6742
|
-
const b = options.documents.get(
|
|
6743
|
-
if (b && !copies.has(
|
|
6744
|
-
copies.set(
|
|
6775
|
+
const copy2 = (ref18) => {
|
|
6776
|
+
const b = options.documents.get(ref18.sha256);
|
|
6777
|
+
if (b && !copies.has(ref18.sha256))
|
|
6778
|
+
copies.set(ref18.sha256, Uint8Array.from(b));
|
|
6745
6779
|
};
|
|
6746
|
-
[selection.document, selection.history, d.presentation.caseRef].forEach(
|
|
6780
|
+
[selection.document, selection.history, d.presentation.caseRef].forEach(copy2);
|
|
6747
6781
|
try {
|
|
6748
6782
|
const h = parseContextClaimHistory(
|
|
6749
6783
|
decode4(copies.get(selection.history.sha256))
|
|
6750
6784
|
);
|
|
6751
6785
|
if (!h.success) return invalid();
|
|
6752
6786
|
for (const r of h.data.contextRefs) {
|
|
6753
|
-
|
|
6787
|
+
copy2(r);
|
|
6754
6788
|
const c = parseObservationContext(decode4(copies.get(r.sha256)));
|
|
6755
6789
|
if (!c.success) return invalid();
|
|
6756
|
-
|
|
6757
|
-
if (c.data.acquisitionRef)
|
|
6790
|
+
copy2(c.data.observationRef);
|
|
6791
|
+
if (c.data.acquisitionRef) copy2(c.data.acquisitionRef);
|
|
6758
6792
|
}
|
|
6759
6793
|
const baseDocuments = /* @__PURE__ */ new Map();
|
|
6760
6794
|
const pending = [
|
|
@@ -6787,11 +6821,11 @@ async function buildPublicContextCase(input, options) {
|
|
|
6787
6821
|
}
|
|
6788
6822
|
});
|
|
6789
6823
|
if (!base2.success) return base2;
|
|
6790
|
-
const load = async (
|
|
6791
|
-
const b = copies.get(
|
|
6792
|
-
if (!b || await digest4(b) !==
|
|
6824
|
+
const load = async (ref18) => {
|
|
6825
|
+
const b = copies.get(ref18.sha256);
|
|
6826
|
+
if (!b || await digest4(b) !== ref18.sha256) throw new Error("reference");
|
|
6793
6827
|
const v = decode4(b);
|
|
6794
|
-
if (v.id !==
|
|
6828
|
+
if (v.id !== ref18.documentId) throw new Error("reference");
|
|
6795
6829
|
return v;
|
|
6796
6830
|
};
|
|
6797
6831
|
const context = parseObservationContext(await load(selection.document));
|
|
@@ -6814,11 +6848,11 @@ async function buildPublicContextCase(input, options) {
|
|
|
6814
6848
|
return invalid();
|
|
6815
6849
|
const citeRefs = (ids, required) => {
|
|
6816
6850
|
const selected2 = ids.map(
|
|
6817
|
-
(
|
|
6851
|
+
(id26) => d.presentation.citations.find((c) => c.id === id26).target
|
|
6818
6852
|
);
|
|
6819
6853
|
if (required.some(
|
|
6820
|
-
(
|
|
6821
|
-
(t) => t.kind === "artifact" && t.observationId === observation.id && t.ref ===
|
|
6854
|
+
(ref18) => !selected2.some(
|
|
6855
|
+
(t) => t.kind === "artifact" && t.observationId === observation.id && t.ref === ref18
|
|
6822
6856
|
)
|
|
6823
6857
|
))
|
|
6824
6858
|
throw new Error("citation");
|
|
@@ -7091,10 +7125,10 @@ var TestimonyCasePresentationSchema = z.strictObject({
|
|
|
7091
7125
|
});
|
|
7092
7126
|
function testimonyCasePresentationJsonSchema() {
|
|
7093
7127
|
return {
|
|
7094
|
-
...z.toJSONSchema(TestimonyCasePresentationSchema, {
|
|
7128
|
+
...preservePublishedSchema(z.toJSONSchema(TestimonyCasePresentationSchema, {
|
|
7095
7129
|
target: "draft-2020-12",
|
|
7096
7130
|
reused: "ref"
|
|
7097
|
-
}),
|
|
7131
|
+
})),
|
|
7098
7132
|
$id: TESTIMONY_CASE_PRESENTATION_SCHEMA_ID
|
|
7099
7133
|
};
|
|
7100
7134
|
}
|
|
@@ -7175,11 +7209,11 @@ async function buildPublicTestimonyCase(input, options) {
|
|
|
7175
7209
|
const observationId = entities.data.observationRef.documentId;
|
|
7176
7210
|
const cite = (ids, refs) => {
|
|
7177
7211
|
const targets = ids.map(
|
|
7178
|
-
(
|
|
7212
|
+
(id26) => d.presentation.citations.find((c) => c.id === id26).target
|
|
7179
7213
|
);
|
|
7180
7214
|
if (refs.some(
|
|
7181
|
-
(
|
|
7182
|
-
(t) => t.kind === "artifact" && t.observationId === observationId && t.ref ===
|
|
7215
|
+
(ref18) => !targets.some(
|
|
7216
|
+
(t) => t.kind === "artifact" && t.observationId === observationId && t.ref === ref18
|
|
7183
7217
|
)
|
|
7184
7218
|
))
|
|
7185
7219
|
throw Error("citation");
|
|
@@ -7542,10 +7576,10 @@ var ArchivalCasePresentationSchema = z.strictObject({
|
|
|
7542
7576
|
});
|
|
7543
7577
|
function archivalCasePresentationJsonSchema() {
|
|
7544
7578
|
return {
|
|
7545
|
-
...z.toJSONSchema(ArchivalCasePresentationSchema, {
|
|
7579
|
+
...preservePublishedSchema(z.toJSONSchema(ArchivalCasePresentationSchema, {
|
|
7546
7580
|
target: "draft-2020-12",
|
|
7547
7581
|
reused: "ref"
|
|
7548
|
-
}),
|
|
7582
|
+
})),
|
|
7549
7583
|
$id: ARCHIVAL_CASE_PRESENTATION_SCHEMA_ID
|
|
7550
7584
|
};
|
|
7551
7585
|
}
|
|
@@ -7639,11 +7673,11 @@ async function buildPublicArchivalCase(input, options) {
|
|
|
7639
7673
|
const observationId = entities.data.observationRef.documentId;
|
|
7640
7674
|
const cite = (ids, refs) => {
|
|
7641
7675
|
const targets = ids.map(
|
|
7642
|
-
(
|
|
7676
|
+
(id26) => d.presentation.citations.find((c2) => c2.id === id26).target
|
|
7643
7677
|
);
|
|
7644
7678
|
if (refs.some(
|
|
7645
|
-
(
|
|
7646
|
-
(t) => t.kind === "artifact" && t.observationId === observationId && t.ref ===
|
|
7679
|
+
(ref18) => !targets.some(
|
|
7680
|
+
(t) => t.kind === "artifact" && t.observationId === observationId && t.ref === ref18
|
|
7647
7681
|
)
|
|
7648
7682
|
))
|
|
7649
7683
|
throw Error("citation");
|
|
@@ -7824,8 +7858,8 @@ async function buildPublicArchivalCase(input, options) {
|
|
|
7824
7858
|
ordered.push(...ready);
|
|
7825
7859
|
pending = pending.filter((a) => !ready.includes(a));
|
|
7826
7860
|
}
|
|
7827
|
-
const sourceCitationId = e.citationIds.find((
|
|
7828
|
-
const t = d.presentation.citations.find((c2) => c2.id ===
|
|
7861
|
+
const sourceCitationId = e.citationIds.find((id26) => {
|
|
7862
|
+
const t = d.presentation.citations.find((c2) => c2.id === id26).target;
|
|
7829
7863
|
return t.kind === "artifact" && t.observationId === observationId && t.ref === edition.artifact.sourceRef;
|
|
7830
7864
|
});
|
|
7831
7865
|
publicEditions.push({
|
|
@@ -7960,7 +7994,7 @@ async function buildPublicArchivalCaseOutputs(input, options) {
|
|
|
7960
7994
|
action2.citationIds
|
|
7961
7995
|
);
|
|
7962
7996
|
}
|
|
7963
|
-
const editionLabel = (
|
|
7997
|
+
const editionLabel = (id26) => a.editions.find((e) => e.id === id26).label;
|
|
7964
7998
|
for (const p of a.passages)
|
|
7965
7999
|
add3(
|
|
7966
8000
|
`${editionLabel(p.editionId)}, page ${p.page}`,
|
|
@@ -8063,10 +8097,10 @@ var MaterialCasePresentationSchema = z.strictObject({
|
|
|
8063
8097
|
});
|
|
8064
8098
|
function materialCasePresentationJsonSchema() {
|
|
8065
8099
|
return {
|
|
8066
|
-
...z.toJSONSchema(MaterialCasePresentationSchema, {
|
|
8100
|
+
...preservePublishedSchema(z.toJSONSchema(MaterialCasePresentationSchema, {
|
|
8067
8101
|
target: "draft-2020-12",
|
|
8068
8102
|
reused: "ref"
|
|
8069
|
-
}),
|
|
8103
|
+
})),
|
|
8070
8104
|
$id: MATERIAL_CASE_PRESENTATION_SCHEMA_ID
|
|
8071
8105
|
};
|
|
8072
8106
|
}
|
|
@@ -8153,11 +8187,11 @@ async function buildPublicMaterialCase(input, options) {
|
|
|
8153
8187
|
const observation = history.data.observation;
|
|
8154
8188
|
const cite = (ids, refs2) => {
|
|
8155
8189
|
const targets = ids.map(
|
|
8156
|
-
(
|
|
8190
|
+
(id26) => d.presentation.citations.find((c2) => c2.id === id26).target
|
|
8157
8191
|
);
|
|
8158
8192
|
if (refs2.some(
|
|
8159
|
-
(
|
|
8160
|
-
(t) => t.kind === "artifact" && t.observationId === observation.id && t.ref ===
|
|
8193
|
+
(ref18) => !targets.some(
|
|
8194
|
+
(t) => t.kind === "artifact" && t.observationId === observation.id && t.ref === ref18
|
|
8161
8195
|
)
|
|
8162
8196
|
))
|
|
8163
8197
|
throw Error("citation");
|
|
@@ -8476,7 +8510,7 @@ async function buildPublicMaterialCaseOutputs(input, options) {
|
|
|
8476
8510
|
);
|
|
8477
8511
|
search.push(title, ...body);
|
|
8478
8512
|
};
|
|
8479
|
-
const specimen = (
|
|
8513
|
+
const specimen = (id26) => m.specimens.find((x) => x.id === id26).label;
|
|
8480
8514
|
for (const t of m.traces)
|
|
8481
8515
|
add3(
|
|
8482
8516
|
t.label,
|
|
@@ -8550,7 +8584,7 @@ async function buildPublicMaterialCaseOutputs(input, options) {
|
|
|
8550
8584
|
m.review.summary,
|
|
8551
8585
|
`${m.review.reviewerLabel} \xB7 ${m.review.outcome} \xB7 ${m.review.revision}`,
|
|
8552
8586
|
m.review.method,
|
|
8553
|
-
`Reviewed results: ${m.review.resultIds.map((
|
|
8587
|
+
`Reviewed results: ${m.review.resultIds.map((id26) => m.results.find((x) => x.id === id26).label).join(", ")}`
|
|
8554
8588
|
],
|
|
8555
8589
|
m.review.citationIds
|
|
8556
8590
|
);
|
|
@@ -8572,8 +8606,8 @@ var safe = (value) => {
|
|
|
8572
8606
|
if (!integer(value)) throw new Error("Unsafe integer arithmetic");
|
|
8573
8607
|
return value;
|
|
8574
8608
|
};
|
|
8575
|
-
function readSourceCsv(
|
|
8576
|
-
const
|
|
8609
|
+
function readSourceCsv(bytes6) {
|
|
8610
|
+
const text21 = new TextDecoder("utf-8", { fatal: true }).decode(bytes6);
|
|
8577
8611
|
const rows = [];
|
|
8578
8612
|
let row = [], cell = "", quoted = false, closed = false;
|
|
8579
8613
|
const field2 = () => {
|
|
@@ -8586,11 +8620,11 @@ function readSourceCsv(bytes5) {
|
|
|
8586
8620
|
rows.push(row);
|
|
8587
8621
|
row = [];
|
|
8588
8622
|
};
|
|
8589
|
-
for (let i = 0; i <
|
|
8590
|
-
const c =
|
|
8623
|
+
for (let i = 0; i < text21.length; i++) {
|
|
8624
|
+
const c = text21[i];
|
|
8591
8625
|
if (quoted) {
|
|
8592
8626
|
if (c === '"') {
|
|
8593
|
-
if (
|
|
8627
|
+
if (text21[i + 1] === '"') {
|
|
8594
8628
|
cell += '"';
|
|
8595
8629
|
i++;
|
|
8596
8630
|
} else {
|
|
@@ -8600,7 +8634,7 @@ function readSourceCsv(bytes5) {
|
|
|
8600
8634
|
} else cell += c;
|
|
8601
8635
|
} else if (c === ",") field2();
|
|
8602
8636
|
else if (c === "\n" || c === "\r") {
|
|
8603
|
-
if (c === "\r" &&
|
|
8637
|
+
if (c === "\r" && text21[++i] !== "\n") throw new Error("Bare CR in CSV");
|
|
8604
8638
|
record();
|
|
8605
8639
|
} else if (c === '"' && cell === "" && !closed) quoted = true;
|
|
8606
8640
|
else {
|
|
@@ -8612,8 +8646,8 @@ function readSourceCsv(bytes5) {
|
|
|
8612
8646
|
if (cell !== "" || row.length || closed) record();
|
|
8613
8647
|
return rows;
|
|
8614
8648
|
}
|
|
8615
|
-
function readProductSourceSelection(layout, selector,
|
|
8616
|
-
if (
|
|
8649
|
+
function readProductSourceSelection(layout, selector, bytes6) {
|
|
8650
|
+
if (bytes6 && bytes6.byteLength !== layout.byteLength)
|
|
8617
8651
|
throw new Error("Source byte length mismatch");
|
|
8618
8652
|
if (layout.kind === "binary_array" && selector.kind === "array_element") {
|
|
8619
8653
|
if (selector.indices.length !== layout.axes.length)
|
|
@@ -8648,11 +8682,11 @@ function readProductSourceSelection(layout, selector, bytes5) {
|
|
|
8648
8682
|
const timeAxis = layout.axes.find((axis2) => axis2.kind === "time");
|
|
8649
8683
|
if (timeAxis)
|
|
8650
8684
|
result.time = coordinates[timeAxis.name];
|
|
8651
|
-
if (
|
|
8685
|
+
if (bytes6) {
|
|
8652
8686
|
const view = new DataView(
|
|
8653
|
-
|
|
8654
|
-
|
|
8655
|
-
|
|
8687
|
+
bytes6.buffer,
|
|
8688
|
+
bytes6.byteOffset,
|
|
8689
|
+
bytes6.byteLength
|
|
8656
8690
|
), little = layout.byteOrder === "little";
|
|
8657
8691
|
result.value = layout.elementType === "float32" ? view.getFloat32(byteOffset, little) : layout.elementType === "float64" ? view.getFloat64(byteOffset, little) : layout.elementType === "int16" ? view.getInt16(byteOffset, little) : layout.elementType === "uint16" ? view.getUint16(byteOffset, little) : view.getUint8(byteOffset);
|
|
8658
8692
|
if (!Number.isFinite(result.value))
|
|
@@ -8665,8 +8699,8 @@ function readProductSourceSelection(layout, selector, bytes5) {
|
|
|
8665
8699
|
if (layout.kind === "csv_table" && selector.kind === "table_row") {
|
|
8666
8700
|
if (!integer(selector.row) || selector.row >= layout.rowCount)
|
|
8667
8701
|
throw new Error("CSV row outside extent");
|
|
8668
|
-
if (!
|
|
8669
|
-
const rows = readSourceCsv(
|
|
8702
|
+
if (!bytes6) return { mediaDecoding: "not_applicable" };
|
|
8703
|
+
const rows = readSourceCsv(bytes6), header = rows.shift();
|
|
8670
8704
|
if (!header || header.length !== layout.columns.length || header.some((value, i) => value !== layout.columns[i]))
|
|
8671
8705
|
throw new Error("CSV header mismatch");
|
|
8672
8706
|
if (rows.length !== layout.rowCount || rows.some((row) => row.length !== layout.columns.length))
|
|
@@ -8829,9 +8863,9 @@ var ProductSourceSelectionSchema = z.strictObject({
|
|
|
8829
8863
|
});
|
|
8830
8864
|
function productSourceSelectionJsonSchema() {
|
|
8831
8865
|
return {
|
|
8832
|
-
...z.toJSONSchema(ProductSourceSelectionSchema, {
|
|
8866
|
+
...preservePublishedSchema(z.toJSONSchema(ProductSourceSelectionSchema, {
|
|
8833
8867
|
target: "draft-2020-12"
|
|
8834
|
-
}),
|
|
8868
|
+
})),
|
|
8835
8869
|
$id: PRODUCT_SOURCE_SELECTION_SCHEMA_ID
|
|
8836
8870
|
};
|
|
8837
8871
|
}
|
|
@@ -8852,7 +8886,7 @@ async function evaluateProductSourceSelection(observationInput, selectionInput,
|
|
|
8852
8886
|
calibration: "not_checked",
|
|
8853
8887
|
mediaDecoding: "not_checked"
|
|
8854
8888
|
};
|
|
8855
|
-
const issue = (code, stage, pointer6,
|
|
8889
|
+
const issue = (code, stage, pointer6, message2) => result.issues.push({ code, stage, pointer: pointer6, message: message2 });
|
|
8856
8890
|
if (!observation.success)
|
|
8857
8891
|
for (const entry of observation.issues.filter(
|
|
8858
8892
|
(i) => i.severity === "error"
|
|
@@ -8991,15 +9025,15 @@ async function evaluateProductSourceSelection(observationInput, selectionInput,
|
|
|
8991
9025
|
const supports = (refs, target) => {
|
|
8992
9026
|
const queue = [...refs], seen = /* @__PURE__ */ new Set();
|
|
8993
9027
|
while (queue.length) {
|
|
8994
|
-
const
|
|
8995
|
-
if (
|
|
8996
|
-
if (seen.has(
|
|
8997
|
-
seen.add(
|
|
8998
|
-
const p = products.get(
|
|
9028
|
+
const ref18 = queue.pop();
|
|
9029
|
+
if (ref18 === target) return true;
|
|
9030
|
+
if (seen.has(ref18)) continue;
|
|
9031
|
+
seen.add(ref18);
|
|
9032
|
+
const p = products.get(ref18);
|
|
8999
9033
|
if (p?.kind === "derived")
|
|
9000
9034
|
queue.push(...processes.get(p.generatedBy).inputRefs);
|
|
9001
9035
|
const assertion = record.assertions.find(
|
|
9002
|
-
(a) => `assertion:${a.id}` ===
|
|
9036
|
+
(a) => `assertion:${a.id}` === ref18
|
|
9003
9037
|
);
|
|
9004
9038
|
if (assertion) queue.push(assertion.provenance.sourceRef);
|
|
9005
9039
|
}
|
|
@@ -9041,8 +9075,8 @@ async function evaluateProductSourceSelection(observationInput, selectionInput,
|
|
|
9041
9075
|
}
|
|
9042
9076
|
result.checks.semantic = "passed";
|
|
9043
9077
|
const assets2 = new Map(
|
|
9044
|
-
[...options.assets ?? []].map(([
|
|
9045
|
-
|
|
9078
|
+
[...options.assets ?? []].map(([ref18, value]) => [
|
|
9079
|
+
ref18,
|
|
9046
9080
|
Uint8Array.from(value)
|
|
9047
9081
|
])
|
|
9048
9082
|
);
|
|
@@ -9238,9 +9272,9 @@ var RADAR_PROFILE = Object.freeze({
|
|
|
9238
9272
|
scope: "retained_rotating_scan_products_and_declared_processing"
|
|
9239
9273
|
});
|
|
9240
9274
|
function radarProfileJsonSchema() {
|
|
9241
|
-
const schema = z.toJSONSchema(RadarProfileSchema, {
|
|
9275
|
+
const schema = preservePublishedSchema(z.toJSONSchema(RadarProfileSchema, {
|
|
9242
9276
|
target: "draft-2020-12"
|
|
9243
|
-
});
|
|
9277
|
+
}));
|
|
9244
9278
|
for (const branch of schema.anyOf ?? []) {
|
|
9245
9279
|
if (typeof branch !== "object") continue;
|
|
9246
9280
|
const uncertainty = branch.properties?.uncertainty;
|
|
@@ -9352,14 +9386,14 @@ function readRadarProducts(layouts, products, assets2) {
|
|
|
9352
9386
|
const table2 = (role) => {
|
|
9353
9387
|
const product = products[role];
|
|
9354
9388
|
if (!product) return [];
|
|
9355
|
-
const layout = layoutMap.get(product),
|
|
9356
|
-
if (!layout || layout.kind !== "csv_table" || !
|
|
9389
|
+
const layout = layoutMap.get(product), bytes6 = assets2.get(product);
|
|
9390
|
+
if (!layout || layout.kind !== "csv_table" || !bytes6 || bytes6.byteLength !== layout.byteLength)
|
|
9357
9391
|
throw new Error(`Missing or mismatched ${role} table.`);
|
|
9358
9392
|
if (layout.partition || layout.sample)
|
|
9359
9393
|
throw new Error(
|
|
9360
9394
|
`Radar ${role} tables must declare the complete table without a partition or scalar sample mapping.`
|
|
9361
9395
|
);
|
|
9362
|
-
const columns = RADAR_TABLE_COLUMNS[role], records = readSourceCsv(
|
|
9396
|
+
const columns = RADAR_TABLE_COLUMNS[role], records = readSourceCsv(bytes6), header = records.shift();
|
|
9363
9397
|
if (JSON.stringify(header) !== JSON.stringify(columns) || JSON.stringify(layout.columns) !== JSON.stringify(columns) || records.length !== layout.rowCount)
|
|
9364
9398
|
throw new Error(`Invalid ${role} columns or row count.`);
|
|
9365
9399
|
return records.map((row) => {
|
|
@@ -9402,15 +9436,15 @@ function readRadarProducts(layouts, products, assets2) {
|
|
|
9402
9436
|
});
|
|
9403
9437
|
};
|
|
9404
9438
|
const array2 = (role) => {
|
|
9405
|
-
const
|
|
9406
|
-
if (!
|
|
9407
|
-
const layout = layoutMap.get(
|
|
9408
|
-
if (!layout || layout.kind !== "binary_array" || layout.elementType !== (role === "eligibility" ? "uint8" : "float32") || layout.byteOrder !== "little" || !
|
|
9439
|
+
const ref18 = products[role];
|
|
9440
|
+
if (!ref18) return [];
|
|
9441
|
+
const layout = layoutMap.get(ref18), bytes6 = assets2.get(ref18), elementBytes = role === "eligibility" ? 1 : 4;
|
|
9442
|
+
if (!layout || layout.kind !== "binary_array" || layout.elementType !== (role === "eligibility" ? "uint8" : "float32") || layout.byteOrder !== "little" || !bytes6 || bytes6.byteLength !== layout.byteLength || layout.byteOffset < 0 || !Number.isSafeInteger(layout.byteOffset))
|
|
9409
9443
|
throw new Error(`Invalid ${role} array.`);
|
|
9410
9444
|
const count = layout.axes.reduce((n, axis2) => n * axis2.length, 1);
|
|
9411
|
-
if (!Number.isSafeInteger(count) || layout.byteOffset + count * elementBytes !==
|
|
9445
|
+
if (!Number.isSafeInteger(count) || layout.byteOffset + count * elementBytes !== bytes6.byteLength)
|
|
9412
9446
|
throw new Error(`Invalid ${role} extent.`);
|
|
9413
|
-
const view = new DataView(
|
|
9447
|
+
const view = new DataView(bytes6.buffer, bytes6.byteOffset, bytes6.byteLength), values = [];
|
|
9414
9448
|
for (let i = 0; i < count; i++) {
|
|
9415
9449
|
const n = elementBytes === 1 ? view.getUint8(layout.byteOffset + i) : view.getFloat32(layout.byteOffset + i * 4, true);
|
|
9416
9450
|
if (!Number.isFinite(n)) throw new Error(`Non-finite ${role} sample.`);
|
|
@@ -9442,7 +9476,7 @@ function radarCovarianceScaleSquared(probability) {
|
|
|
9442
9476
|
var close = (a, b, tolerance = 1e-6) => Math.abs(a - b) <= tolerance * Math.max(1, Math.abs(a), Math.abs(b));
|
|
9443
9477
|
var positionClose = (a, b) => Math.abs(a - b) <= 1e-6 + 32 * Number.EPSILON * Math.max(1, Math.abs(a), Math.abs(b));
|
|
9444
9478
|
var index = (n, length) => Number.isSafeInteger(n) && n >= 0 && n < length;
|
|
9445
|
-
var key = (
|
|
9479
|
+
var key = (id26, scan) => `${id26}/${scan}`;
|
|
9446
9480
|
var decimal = (value) => {
|
|
9447
9481
|
const match = /^(-?)(\d+)(?:\.(\d+))?(?:e([+-]?\d+))?$/i.exec(value);
|
|
9448
9482
|
const fraction = match[3] ?? "", exponent = Number(match[4] ?? 0) - fraction.length;
|
|
@@ -9474,8 +9508,8 @@ async function evaluateRadarProfile(observationInput, contextInput, selectionInp
|
|
|
9474
9508
|
physicalCalibration: "not_checked",
|
|
9475
9509
|
trackingPerformance: "not_checked"
|
|
9476
9510
|
};
|
|
9477
|
-
const issue = (code, pointer6,
|
|
9478
|
-
result.issues.push({ code, pointer: pointer6, message });
|
|
9511
|
+
const issue = (code, pointer6, message2) => {
|
|
9512
|
+
result.issues.push({ code, pointer: pointer6, message: message2 });
|
|
9479
9513
|
};
|
|
9480
9514
|
const parsed = RadarProfileSchema.safeParse(profileInput), observation = parseExperimentalObservation(observationInput), context = parseAcquisitionContext(contextInput), selection = ProductSourceSelectionSchema.safeParse(selectionInput);
|
|
9481
9515
|
if (!parsed.success || !observation.success || !context.success || !selection.success) {
|
|
@@ -9495,7 +9529,7 @@ async function evaluateRadarProfile(observationInput, contextInput, selectionInp
|
|
|
9495
9529
|
"Profile identifiers must select these exact documents."
|
|
9496
9530
|
);
|
|
9497
9531
|
const roleRefs = Object.values(profile.products).filter(
|
|
9498
|
-
(
|
|
9532
|
+
(ref18) => ref18 !== void 0
|
|
9499
9533
|
);
|
|
9500
9534
|
if (new Set(roleRefs).size !== roleRefs.length)
|
|
9501
9535
|
issue(
|
|
@@ -9532,8 +9566,8 @@ async function evaluateRadarProfile(observationInput, contextInput, selectionInp
|
|
|
9532
9566
|
const layouts = new Map(
|
|
9533
9567
|
sources.layouts.map((layout) => [layout.productRef, layout])
|
|
9534
9568
|
);
|
|
9535
|
-
for (const [role,
|
|
9536
|
-
if (
|
|
9569
|
+
for (const [role, ref18] of Object.entries(profile.products))
|
|
9570
|
+
if (ref18 && !layouts.has(ref18))
|
|
9537
9571
|
issue(
|
|
9538
9572
|
"RADAR.LAYOUT",
|
|
9539
9573
|
`/products/${role}`,
|
|
@@ -9679,8 +9713,8 @@ async function evaluateRadarProfile(observationInput, contextInput, selectionInp
|
|
|
9679
9713
|
"/products/returns",
|
|
9680
9714
|
"The retained return array is the input capture for this profile. Derived inputs need a separately specified profile."
|
|
9681
9715
|
);
|
|
9682
|
-
const ancestors = (
|
|
9683
|
-
const found = /* @__PURE__ */ new Set(), queue = [
|
|
9716
|
+
const ancestors = (ref18) => {
|
|
9717
|
+
const found = /* @__PURE__ */ new Set(), queue = [ref18];
|
|
9684
9718
|
for (let i = 0; i < queue.length; i++) {
|
|
9685
9719
|
const current = queue[i];
|
|
9686
9720
|
if (found.has(current)) continue;
|
|
@@ -9774,7 +9808,7 @@ async function evaluateRadarProfile(observationInput, contextInput, selectionInp
|
|
|
9774
9808
|
obs.sources.map((source) => [`source:${source.id}`, source.kind])
|
|
9775
9809
|
);
|
|
9776
9810
|
const forbidden = [...ancestors(profile.products.truth)].filter(
|
|
9777
|
-
(
|
|
9811
|
+
(ref18) => !sharedSynthesis.has(ref18) || sourceKinds.get(ref18) !== "document"
|
|
9778
9812
|
);
|
|
9779
9813
|
if ([
|
|
9780
9814
|
thresholdInputs,
|
|
@@ -9789,7 +9823,7 @@ async function evaluateRadarProfile(observationInput, contextInput, selectionInp
|
|
|
9789
9823
|
] : [],
|
|
9790
9824
|
...profile.products.siteFeatures ? [ancestors(profile.products.siteFeatures)] : [],
|
|
9791
9825
|
...profile.products.platformPose ? [ancestors(profile.products.platformPose)] : []
|
|
9792
|
-
].some((inputs) => forbidden.some((
|
|
9826
|
+
].some((inputs) => forbidden.some((ref18) => inputs.has(ref18))))
|
|
9793
9827
|
issue(
|
|
9794
9828
|
"RADAR.TRUTH_LEAK",
|
|
9795
9829
|
"/products/truth",
|
|
@@ -9801,9 +9835,9 @@ async function evaluateRadarProfile(observationInput, contextInput, selectionInp
|
|
|
9801
9835
|
return result;
|
|
9802
9836
|
}
|
|
9803
9837
|
const assets2 = new Map(
|
|
9804
|
-
[...options.assets ?? []].map(([
|
|
9805
|
-
|
|
9806
|
-
Uint8Array.from(
|
|
9838
|
+
[...options.assets ?? []].map(([ref18, bytes6]) => [
|
|
9839
|
+
ref18,
|
|
9840
|
+
Uint8Array.from(bytes6)
|
|
9807
9841
|
])
|
|
9808
9842
|
);
|
|
9809
9843
|
const sourceResult = await evaluateProductSourceSelection(obs, sources, {
|
|
@@ -9991,12 +10025,12 @@ async function evaluateRadarProfile(observationInput, contextInput, selectionInp
|
|
|
9991
10025
|
siteGroups.set(vertex.feature_id, group);
|
|
9992
10026
|
previousFeature = vertex.feature_id;
|
|
9993
10027
|
}
|
|
9994
|
-
for (const [
|
|
10028
|
+
for (const [id26, vertices] of siteGroups) {
|
|
9995
10029
|
const first2 = vertices[0], last2 = vertices.at(-1), distinct = new Set(vertices.map((v) => `${v.east_m}/${v.north_m}`));
|
|
9996
10030
|
if (first2.closed ? vertices.length < 4 || distinct.size < 3 || first2.east_m !== last2.east_m || first2.north_m !== last2.north_m : vertices.length < 2 || distinct.size < 2)
|
|
9997
10031
|
issue(
|
|
9998
10032
|
"RADAR.SITE_GEOMETRY",
|
|
9999
|
-
`/products/siteFeatures/${
|
|
10033
|
+
`/products/siteFeatures/${id26}`,
|
|
10000
10034
|
"Closed features need at least three distinct vertices and repeated endpoint; open features need at least two distinct vertices."
|
|
10001
10035
|
);
|
|
10002
10036
|
}
|
|
@@ -10259,9 +10293,9 @@ var SECONDARY_RADAR_PROFILE = Object.freeze({
|
|
|
10259
10293
|
scope: "retained_cooperative_interrogations_and_decoded_replies"
|
|
10260
10294
|
});
|
|
10261
10295
|
function steeredRadarProfileJsonSchema() {
|
|
10262
|
-
const schema = z.toJSONSchema(SteeredRadarProfileSchema, {
|
|
10296
|
+
const schema = preservePublishedSchema(z.toJSONSchema(SteeredRadarProfileSchema, {
|
|
10263
10297
|
target: "draft-2020-12"
|
|
10264
|
-
});
|
|
10298
|
+
}));
|
|
10265
10299
|
const uncertainty = schema.properties?.uncertainty;
|
|
10266
10300
|
const axes = typeof uncertainty === "object" ? uncertainty.properties?.axes : void 0;
|
|
10267
10301
|
if (typeof axes === "object") {
|
|
@@ -10272,7 +10306,7 @@ function steeredRadarProfileJsonSchema() {
|
|
|
10272
10306
|
}
|
|
10273
10307
|
function secondaryRadarProfileJsonSchema() {
|
|
10274
10308
|
return {
|
|
10275
|
-
...z.toJSONSchema(SecondaryRadarProfileSchema, { target: "draft-2020-12" }),
|
|
10309
|
+
...preservePublishedSchema(z.toJSONSchema(SecondaryRadarProfileSchema, { target: "draft-2020-12" })),
|
|
10276
10310
|
$id: SECONDARY_RADAR_PROFILE_SCHEMA_ID
|
|
10277
10311
|
};
|
|
10278
10312
|
}
|
|
@@ -10362,12 +10396,12 @@ function sourceReader(layouts, assets2) {
|
|
|
10362
10396
|
throw new Error("Duplicate radar source layout.");
|
|
10363
10397
|
const map = new Map(layouts.map((l) => [l.productRef, l]));
|
|
10364
10398
|
return {
|
|
10365
|
-
table(
|
|
10366
|
-
if (!
|
|
10367
|
-
const layout = map.get(
|
|
10368
|
-
if (!layout || layout.kind !== "csv_table" || layout.partition || layout.sample || !
|
|
10399
|
+
table(ref18, columns, nullable = false) {
|
|
10400
|
+
if (!ref18) return [];
|
|
10401
|
+
const layout = map.get(ref18), bytes6 = assets2.get(ref18);
|
|
10402
|
+
if (!layout || layout.kind !== "csv_table" || layout.partition || layout.sample || !bytes6 || bytes6.byteLength !== layout.byteLength)
|
|
10369
10403
|
throw new Error("Missing or mismatched radar table.");
|
|
10370
|
-
const rows = readSourceCsv(
|
|
10404
|
+
const rows = readSourceCsv(bytes6), header = rows.shift();
|
|
10371
10405
|
if (JSON.stringify(header) !== JSON.stringify(columns) || JSON.stringify(layout.columns) !== JSON.stringify(columns) || rows.length !== layout.rowCount)
|
|
10372
10406
|
throw new Error("Invalid radar table columns or extent.");
|
|
10373
10407
|
return rows.map((row) => {
|
|
@@ -10403,17 +10437,17 @@ function sourceReader(layouts, assets2) {
|
|
|
10403
10437
|
);
|
|
10404
10438
|
});
|
|
10405
10439
|
},
|
|
10406
|
-
array(
|
|
10407
|
-
const layout = map.get(
|
|
10408
|
-
if (!layout || layout.kind !== "binary_array" || layout.elementType !== "float32" || layout.byteOrder !== "little" || !
|
|
10440
|
+
array(ref18) {
|
|
10441
|
+
const layout = map.get(ref18), bytes6 = assets2.get(ref18);
|
|
10442
|
+
if (!layout || layout.kind !== "binary_array" || layout.elementType !== "float32" || layout.byteOrder !== "little" || !bytes6 || bytes6.byteLength !== layout.byteLength || !Number.isSafeInteger(layout.byteOffset) || layout.byteOffset < 0)
|
|
10409
10443
|
throw new Error("Invalid radar array.");
|
|
10410
10444
|
const count = layout.axes.reduce((n, axis2) => n * axis2.length, 1);
|
|
10411
|
-
if (!Number.isSafeInteger(count) || layout.byteOffset + count * 4 !==
|
|
10445
|
+
if (!Number.isSafeInteger(count) || layout.byteOffset + count * 4 !== bytes6.byteLength)
|
|
10412
10446
|
throw new Error("Invalid radar array extent.");
|
|
10413
10447
|
const view = new DataView(
|
|
10414
|
-
|
|
10415
|
-
|
|
10416
|
-
|
|
10448
|
+
bytes6.buffer,
|
|
10449
|
+
bytes6.byteOffset,
|
|
10450
|
+
bytes6.byteLength
|
|
10417
10451
|
), values = [];
|
|
10418
10452
|
for (let i = 0; i < count; i++) {
|
|
10419
10453
|
const value = view.getFloat32(layout.byteOffset + i * 4, true);
|
|
@@ -10485,7 +10519,7 @@ var compareOffset2 = (origin, seconds, boundary) => {
|
|
|
10485
10519
|
return delta < 0n ? -1 : delta > 0n ? 1 : 0;
|
|
10486
10520
|
};
|
|
10487
10521
|
async function prepare(profile, observationInput, contextInput, selectionInput, options, result) {
|
|
10488
|
-
const issue = (code, pointer6,
|
|
10522
|
+
const issue = (code, pointer6, message2) => result.issues.push({ code, pointer: pointer6, message: message2 });
|
|
10489
10523
|
const observation = parseExperimentalObservation(observationInput), context = parseAcquisitionContext(contextInput), selection = ProductSourceSelectionSchema.safeParse(selectionInput);
|
|
10490
10524
|
if (!observation.success || !context.success || !selection.success) {
|
|
10491
10525
|
result.checks.structure = "failed";
|
|
@@ -10551,8 +10585,8 @@ async function prepare(profile, observationInput, contextInput, selectionInput,
|
|
|
10551
10585
|
);
|
|
10552
10586
|
const within = (seconds) => validOrigin && Number.isFinite(seconds) && seconds >= 0 && acquisition?.time.state === "known" && acquisition.time.kind === "interval" && compareOffset2(profile.timeOrigin, seconds, acquisition.time.start) >= 0 && compareOffset2(profile.timeOrigin, seconds, acquisition.time.end) <= 0;
|
|
10553
10587
|
const layouts = new Map(sources.layouts.map((l) => [l.productRef, l]));
|
|
10554
|
-
for (const [role,
|
|
10555
|
-
if (
|
|
10588
|
+
for (const [role, ref18] of Object.entries(profile.products))
|
|
10589
|
+
if (ref18 && !layouts.has(ref18))
|
|
10556
10590
|
issue(
|
|
10557
10591
|
"RADAR.LAYOUT",
|
|
10558
10592
|
`/products/${role}`,
|
|
@@ -10580,8 +10614,8 @@ async function prepare(profile, observationInput, contextInput, selectionInput,
|
|
|
10580
10614
|
"/products",
|
|
10581
10615
|
"The input capture must be a retained raw product."
|
|
10582
10616
|
);
|
|
10583
|
-
const ancestors = (
|
|
10584
|
-
const found = /* @__PURE__ */ new Set(), queue = [
|
|
10617
|
+
const ancestors = (ref18) => {
|
|
10618
|
+
const found = /* @__PURE__ */ new Set(), queue = [ref18];
|
|
10585
10619
|
for (let i = 0; i < queue.length; i++) {
|
|
10586
10620
|
const current = queue[i];
|
|
10587
10621
|
if (found.has(current)) continue;
|
|
@@ -10627,13 +10661,13 @@ async function prepare(profile, observationInput, contextInput, selectionInput,
|
|
|
10627
10661
|
obs.sources.map((source) => [`source:${source.id}`, source.kind])
|
|
10628
10662
|
);
|
|
10629
10663
|
const forbidden = [...ancestors(profile.products.truth)].filter(
|
|
10630
|
-
(
|
|
10664
|
+
(ref18) => !shared.has(ref18) || sourceKinds.get(ref18) !== "document"
|
|
10631
10665
|
);
|
|
10632
10666
|
if ([
|
|
10633
10667
|
...derived.map((role) => roleProducts[role]),
|
|
10634
10668
|
captureRef,
|
|
10635
10669
|
sourceRole
|
|
10636
|
-
].some((
|
|
10670
|
+
].some((ref18) => forbidden.some((r) => ancestors(ref18).has(r))))
|
|
10637
10671
|
issue(
|
|
10638
10672
|
"RADAR.TRUTH_LEAK",
|
|
10639
10673
|
"/products/truth",
|
|
@@ -10645,9 +10679,9 @@ async function prepare(profile, observationInput, contextInput, selectionInput,
|
|
|
10645
10679
|
return;
|
|
10646
10680
|
}
|
|
10647
10681
|
const assets2 = new Map(
|
|
10648
|
-
[...options.assets ?? []].map(([
|
|
10649
|
-
|
|
10650
|
-
Uint8Array.from(
|
|
10682
|
+
[...options.assets ?? []].map(([ref18, bytes6]) => [
|
|
10683
|
+
ref18,
|
|
10684
|
+
Uint8Array.from(bytes6)
|
|
10651
10685
|
])
|
|
10652
10686
|
);
|
|
10653
10687
|
const checked = await evaluateProductSourceSelection(obs, sources, {
|
|
@@ -11113,7 +11147,7 @@ var SONAR_PROFILE = Object.freeze({
|
|
|
11113
11147
|
});
|
|
11114
11148
|
function sonarProfileJsonSchema() {
|
|
11115
11149
|
return {
|
|
11116
|
-
...z.toJSONSchema(SonarProfileSchema, { target: "draft-2020-12" }),
|
|
11150
|
+
...preservePublishedSchema(z.toJSONSchema(SonarProfileSchema, { target: "draft-2020-12" })),
|
|
11117
11151
|
$id: SONAR_PROFILE_SCHEMA_ID
|
|
11118
11152
|
};
|
|
11119
11153
|
}
|
|
@@ -11217,15 +11251,15 @@ function readSonarProducts(profile, layouts, assets2) {
|
|
|
11217
11251
|
);
|
|
11218
11252
|
if (matches.length !== 1)
|
|
11219
11253
|
throw new Error(`Sonar ${role} requires one source layout.`);
|
|
11220
|
-
const layout = matches[0],
|
|
11221
|
-
if (layout.kind !== "binary_array" || layout.elementType !== (role === "amplitudes" ? "float32" : "uint8") || layout.byteOrder !== "little" || layout.order !== "row_major" || layout.byteOffset !== 0 || layout.quantity !== (role === "amplitudes" ? "normalized_echo_amplitude" : "receive_availability") || layout.unit !== "1" || !
|
|
11254
|
+
const layout = matches[0], bytes6 = assets2.get(layout.productRef), size = role === "amplitudes" ? 4 : 1;
|
|
11255
|
+
if (layout.kind !== "binary_array" || layout.elementType !== (role === "amplitudes" ? "float32" : "uint8") || layout.byteOrder !== "little" || layout.order !== "row_major" || layout.byteOffset !== 0 || layout.quantity !== (role === "amplitudes" ? "normalized_echo_amplitude" : "receive_availability") || layout.unit !== "1" || !bytes6 || bytes6.byteLength !== total * size || layout.byteLength !== bytes6.byteLength)
|
|
11222
11256
|
throw new Error(`Invalid sonar ${role} layout or retained bytes.`);
|
|
11223
11257
|
const [ping, delay] = layout.axes;
|
|
11224
11258
|
if (layout.axes.length !== 2 || !ping || ping.kind !== "time" || ping.name !== "ping" || ping.length !== s.pings || ping.start !== profile.timeOrigin || !Number.isSafeInteger(ping.stepSeconds.numerator) || ping.stepSeconds.numerator <= 0 || !Number.isSafeInteger(ping.stepSeconds.denominator) || ping.stepSeconds.denominator <= 0 || BigInt(ping.stepSeconds.numerator) * decimal3(s.pingStepSeconds).d !== decimal3(s.pingStepSeconds).n * BigInt(ping.stepSeconds.denominator) || !delay || delay.kind !== "regular" || delay.name !== "two_way_delay" || delay.unit !== "s" || delay.length !== s.delayBins || delay.origin !== s.delayStartSeconds || delay.step !== s.delayStepSeconds)
|
|
11225
11259
|
throw new Error(
|
|
11226
11260
|
`Sonar ${role} must use the declared ping time and two-way delay axes.`
|
|
11227
11261
|
);
|
|
11228
|
-
const view = new DataView(
|
|
11262
|
+
const view = new DataView(bytes6.buffer, bytes6.byteOffset, bytes6.byteLength);
|
|
11229
11263
|
decoded[role] = Array.from(
|
|
11230
11264
|
{ length: total },
|
|
11231
11265
|
(_, i) => role === "amplitudes" ? view.getFloat32(i * 4, true) : view.getUint8(i)
|
|
@@ -11233,7 +11267,7 @@ function readSonarProducts(profile, layouts, assets2) {
|
|
|
11233
11267
|
readProductSourceSelection(
|
|
11234
11268
|
layout,
|
|
11235
11269
|
{ kind: "array_element", indices: [s.pings - 1, s.delayBins - 1] },
|
|
11236
|
-
|
|
11270
|
+
bytes6
|
|
11237
11271
|
);
|
|
11238
11272
|
}
|
|
11239
11273
|
for (let i = 0; i < total; i++) {
|
|
@@ -11284,8 +11318,8 @@ async function evaluateSonarProfile(observationInput, contextInput, selectionInp
|
|
|
11284
11318
|
physicalCalibration: "not_checked",
|
|
11285
11319
|
propagationAccuracy: "not_checked"
|
|
11286
11320
|
};
|
|
11287
|
-
const issue = (code, pointer6,
|
|
11288
|
-
result.issues.push({ code, pointer: pointer6, message });
|
|
11321
|
+
const issue = (code, pointer6, message2) => {
|
|
11322
|
+
result.issues.push({ code, pointer: pointer6, message: message2 });
|
|
11289
11323
|
};
|
|
11290
11324
|
const parsed = SonarProfileSchema.safeParse(profileInput), observation = parseExperimentalObservation(observationInput), context = parseAcquisitionContext(contextInput), selection = ProductSourceSelectionSchema.safeParse(selectionInput);
|
|
11291
11325
|
if (!parsed.success || !observation.success || !context.success || !selection.success) {
|
|
@@ -11391,9 +11425,9 @@ async function evaluateSonarProfile(observationInput, contextInput, selectionInp
|
|
|
11391
11425
|
return result;
|
|
11392
11426
|
}
|
|
11393
11427
|
const assets2 = new Map(
|
|
11394
|
-
[...options.assets ?? []].map(([
|
|
11395
|
-
|
|
11396
|
-
Uint8Array.from(
|
|
11428
|
+
[...options.assets ?? []].map(([ref18, bytes6]) => [
|
|
11429
|
+
ref18,
|
|
11430
|
+
Uint8Array.from(bytes6)
|
|
11397
11431
|
])
|
|
11398
11432
|
);
|
|
11399
11433
|
const sourceResult = await evaluateProductSourceSelection(obs, sources, {
|
|
@@ -11480,7 +11514,7 @@ var PASSIVE_SONAR_PROFILE = Object.freeze({
|
|
|
11480
11514
|
});
|
|
11481
11515
|
function passiveSonarProfileJsonSchema() {
|
|
11482
11516
|
return {
|
|
11483
|
-
...z.toJSONSchema(PassiveSonarProfileSchema, { target: "draft-2020-12" }),
|
|
11517
|
+
...preservePublishedSchema(z.toJSONSchema(PassiveSonarProfileSchema, { target: "draft-2020-12" })),
|
|
11484
11518
|
$id: PASSIVE_SONAR_PROFILE_SCHEMA_ID
|
|
11485
11519
|
};
|
|
11486
11520
|
}
|
|
@@ -11635,7 +11669,7 @@ function readPassiveSonarProducts(p, layouts, assets2) {
|
|
|
11635
11669
|
const matches = layouts.filter((l) => l.productRef === p.products[role]);
|
|
11636
11670
|
if (matches.length !== 1)
|
|
11637
11671
|
throw new Error(`Passive sonar ${role} requires one source layout.`);
|
|
11638
|
-
const layout = matches[0],
|
|
11672
|
+
const layout = matches[0], bytes6 = assets2.get(layout.productRef), mask = role === "sampleMask" || role === "frameMask", waveform = role === "pressure" || role === "sampleMask";
|
|
11639
11673
|
const length = waveform ? s.samples : role === "frameMask" ? frames : frames * bins, size = mask ? 1 : 4;
|
|
11640
11674
|
const quantity = {
|
|
11641
11675
|
pressure: "sound_pressure",
|
|
@@ -11649,14 +11683,14 @@ function readPassiveSonarProducts(p, layouts, assets2) {
|
|
|
11649
11683
|
powerSpectralDensity: "Pa^2/Hz",
|
|
11650
11684
|
frameMask: "1"
|
|
11651
11685
|
}[role];
|
|
11652
|
-
if (layout.kind !== "binary_array" || layout.elementType !== (mask ? "uint8" : "float32") || layout.byteOrder !== "little" || layout.order !== "row_major" || layout.byteOffset !== 0 || layout.quantity !== quantity || layout.unit !== unit || !
|
|
11686
|
+
if (layout.kind !== "binary_array" || layout.elementType !== (mask ? "uint8" : "float32") || layout.byteOrder !== "little" || layout.order !== "row_major" || layout.byteOffset !== 0 || layout.quantity !== quantity || layout.unit !== unit || !bytes6 || bytes6.byteLength !== length * size || layout.byteLength !== bytes6.byteLength)
|
|
11653
11687
|
throw new Error(`Invalid passive sonar ${role} layout or bytes.`);
|
|
11654
11688
|
const axis2 = layout.axes[0], frequency = layout.axes[1], numerator = waveform ? 1 : t.hopSamples;
|
|
11655
11689
|
if (!axis2 || axis2.kind !== "time" || axis2.name !== (waveform ? "sample" : "window_start") || axis2.length !== (waveform ? s.samples : frames) || axis2.start !== p.timeOrigin || !Number.isSafeInteger(axis2.stepSeconds.numerator) || axis2.stepSeconds.numerator <= 0 || !Number.isSafeInteger(axis2.stepSeconds.denominator) || axis2.stepSeconds.denominator <= 0 || BigInt(axis2.stepSeconds.numerator) * BigInt(s.sampleRateHz) !== BigInt(numerator) * BigInt(axis2.stepSeconds.denominator) || layout.axes.length !== (role === "powerSpectralDensity" ? 2 : 1))
|
|
11656
11690
|
throw new Error(`Invalid passive sonar ${role} time axis.`);
|
|
11657
11691
|
if (role === "powerSpectralDensity" && (!frequency || frequency.kind !== "regular" || frequency.name !== "frequency" || frequency.unit !== "Hz" || frequency.length !== bins || frequency.origin !== 0 || frequency.step !== s.sampleRateHz / t.windowSamples))
|
|
11658
11692
|
throw new Error("Invalid passive sonar frequency axis.");
|
|
11659
|
-
const view = new DataView(
|
|
11693
|
+
const view = new DataView(bytes6.buffer, bytes6.byteOffset, bytes6.byteLength);
|
|
11660
11694
|
decoded[role] = Array.from(
|
|
11661
11695
|
{ length },
|
|
11662
11696
|
(_, i) => mask ? view.getUint8(i) : view.getFloat32(i * 4, true)
|
|
@@ -11667,7 +11701,7 @@ function readPassiveSonarProducts(p, layouts, assets2) {
|
|
|
11667
11701
|
kind: "array_element",
|
|
11668
11702
|
indices: role === "powerSpectralDensity" ? [frames - 1, bins - 1] : [length - 1]
|
|
11669
11703
|
},
|
|
11670
|
-
|
|
11704
|
+
bytes6
|
|
11671
11705
|
);
|
|
11672
11706
|
}
|
|
11673
11707
|
for (let sample = 0; sample < s.samples; sample++) {
|
|
@@ -11726,7 +11760,7 @@ async function evaluatePassiveSonarProfile(observationInput, contextInput, selec
|
|
|
11726
11760
|
physicalCalibration: "not_checked",
|
|
11727
11761
|
localization: "not_checked"
|
|
11728
11762
|
};
|
|
11729
|
-
const issue = (code, pointer6,
|
|
11763
|
+
const issue = (code, pointer6, message2) => result.issues.push({ code, pointer: pointer6, message: message2 });
|
|
11730
11764
|
const parsed = PassiveSonarProfileSchema.safeParse(profileInput), observation = parseExperimentalObservation(observationInput), context = parseAcquisitionContext(contextInput), selection = ProductSourceSelectionSchema.safeParse(selectionInput);
|
|
11731
11765
|
if (!parsed.success || !observation.success || !context.success || !selection.success) {
|
|
11732
11766
|
result.checks.structure = "failed";
|
|
@@ -11832,9 +11866,9 @@ async function evaluatePassiveSonarProfile(observationInput, contextInput, selec
|
|
|
11832
11866
|
return result;
|
|
11833
11867
|
}
|
|
11834
11868
|
const assets2 = new Map(
|
|
11835
|
-
[...options.assets ?? []].map(([
|
|
11836
|
-
|
|
11837
|
-
Uint8Array.from(
|
|
11869
|
+
[...options.assets ?? []].map(([ref18, bytes6]) => [
|
|
11870
|
+
ref18,
|
|
11871
|
+
Uint8Array.from(bytes6)
|
|
11838
11872
|
])
|
|
11839
11873
|
);
|
|
11840
11874
|
const sourceResult = await evaluateProductSourceSelection(obs, sources, {
|
|
@@ -11942,9 +11976,9 @@ var LIDAR_PROFILE = Object.freeze({
|
|
|
11942
11976
|
scope: "static_discrete_returns_and_complete_pulse_ledger"
|
|
11943
11977
|
});
|
|
11944
11978
|
function lidarProfileJsonSchema() {
|
|
11945
|
-
const schema = z.toJSONSchema(LidarProfileSchema, {
|
|
11979
|
+
const schema = preservePublishedSchema(z.toJSONSchema(LidarProfileSchema, {
|
|
11946
11980
|
target: "draft-2020-12"
|
|
11947
|
-
});
|
|
11981
|
+
}));
|
|
11948
11982
|
const constrainTuples = (node) => {
|
|
11949
11983
|
if (node === null || typeof node !== "object") return;
|
|
11950
11984
|
const value = node;
|
|
@@ -11986,40 +12020,40 @@ function validateLidarDeclaration(p) {
|
|
|
11986
12020
|
if (p.mode !== "static_discrete_return_raster" || f.kind !== "local_cartesian" || f.unit !== "m" || f.handedness !== "right_handed" || f.georeferencing !== "not_provided" || f.axes.join(",") !== "east,north,up" || !f.originDescription.trim() || f.sensorOrigin.length !== 3 || !f.sensorOrigin.every(finite4) || !integer3(s.rows, 1, 4096) || !integer3(s.columns, 1, 4096) || !integer3(s.pulses, 1, 65536) || s.rows * s.columns !== s.pulses || !integer3(s.points, 0, 983040) || s.points > s.pulses * 15 || s.order !== "row_major_index_not_time" || s.aim !== "direction_reference_not_surface_hit" || !finite4(g.nearRangeM) || !finite4(g.farRangeM) || g.nearRangeM <= 0 || g.farRangeM <= g.nearRangeM || !Number.isFinite(g.rayToleranceM) || g.rayToleranceM <= 0 || g.rayToleranceM > 0.1 || g.toleranceMeaning !== "encoding_consistency_not_measurement_uncertainty" || g.bounds.min.length !== 3 || g.bounds.max.length !== 3 || !g.bounds.min.every(finite4) || !g.bounds.max.every(finite4) || g.bounds.min.some((v, i) => v >= g.bounds.max[i]) || p.intensity.kind !== "normalized_return_amplitude" || p.intensity.min !== 0 || p.intensity.max !== 1 || p.intensity.calibration !== "not_calibrated_to_reflectance" || !["authored_annotations", "source_annotations"].includes(c.authority) || !c.method.trim() || !c.classes.length || c.classes.length > 256 || new Set(c.classes.map((v) => v.code)).size !== c.classes.length || c.classes.some((v) => !integer3(v.code, 0, 255) || !v.label.trim()) || p.availability.retained !== "complete_return_group" || p.availability.noReturn !== "zero_detected_returns_not_clear_space" || p.availability.unavailable !== "unknown_return_count_empty_cell" || p.availability.noTiming !== "no_per_pulse_timestamps" || new Set(Object.values(p.products)).size !== 2)
|
|
11987
12021
|
throw new Error("Invalid static lidar declaration.");
|
|
11988
12022
|
}
|
|
11989
|
-
function rowSpans(
|
|
12023
|
+
function rowSpans(bytes6) {
|
|
11990
12024
|
const spans = [];
|
|
11991
12025
|
let start = 0, quoted = false;
|
|
11992
|
-
for (let i = 0; i <
|
|
11993
|
-
if (
|
|
11994
|
-
if (quoted &&
|
|
12026
|
+
for (let i = 0; i < bytes6.length; i++) {
|
|
12027
|
+
if (bytes6[i] === 34) {
|
|
12028
|
+
if (quoted && bytes6[i + 1] === 34) i++;
|
|
11995
12029
|
else quoted = !quoted;
|
|
11996
|
-
} else if (!quoted && (
|
|
12030
|
+
} else if (!quoted && (bytes6[i] === 10 || bytes6[i] === 13)) {
|
|
11997
12031
|
spans.push({ byteOffset: start, byteLength: i - start });
|
|
11998
|
-
if (
|
|
12032
|
+
if (bytes6[i] === 13 && bytes6[i + 1] === 10) i++;
|
|
11999
12033
|
start = i + 1;
|
|
12000
12034
|
}
|
|
12001
12035
|
}
|
|
12002
|
-
if (start <
|
|
12003
|
-
spans.push({ byteOffset: start, byteLength:
|
|
12036
|
+
if (start < bytes6.length)
|
|
12037
|
+
spans.push({ byteOffset: start, byteLength: bytes6.length - start });
|
|
12004
12038
|
return spans.slice(1);
|
|
12005
12039
|
}
|
|
12006
|
-
function table(layouts, assets2,
|
|
12007
|
-
const matches = layouts.filter((l) => l.productRef ===
|
|
12008
|
-
const layout = matches[0],
|
|
12009
|
-
if (matches.length !== 1 || !layout || layout.kind !== "csv_table" || layout.mediaType !== "text/csv" || layout.encoding !== "utf-8" || layout.delimiter !== "," || layout.header !== true || layout.partition || layout.sample || layout.rowCount !== count || layout.columns.join(",") !== columns.join(",") || !
|
|
12010
|
-
throw new Error(`Invalid or absent lidar table ${
|
|
12011
|
-
const rows = readSourceCsv(
|
|
12040
|
+
function table(layouts, assets2, ref18, columns, count) {
|
|
12041
|
+
const matches = layouts.filter((l) => l.productRef === ref18);
|
|
12042
|
+
const layout = matches[0], bytes6 = assets2.get(ref18);
|
|
12043
|
+
if (matches.length !== 1 || !layout || layout.kind !== "csv_table" || layout.mediaType !== "text/csv" || layout.encoding !== "utf-8" || layout.delimiter !== "," || layout.header !== true || layout.partition || layout.sample || layout.rowCount !== count || layout.columns.join(",") !== columns.join(",") || !bytes6 || bytes6.byteLength !== layout.byteLength)
|
|
12044
|
+
throw new Error(`Invalid or absent lidar table ${ref18}.`);
|
|
12045
|
+
const rows = readSourceCsv(bytes6), header = rows.shift();
|
|
12012
12046
|
if (header?.join(",") !== columns.join(",") || rows.length !== count || rows.some((r) => r.length !== columns.length))
|
|
12013
|
-
throw new Error(`Unexpected lidar table rows or header ${
|
|
12014
|
-
const spans = rowSpans(
|
|
12047
|
+
throw new Error(`Unexpected lidar table rows or header ${ref18}.`);
|
|
12048
|
+
const spans = rowSpans(bytes6);
|
|
12015
12049
|
if (spans.length !== count)
|
|
12016
12050
|
throw new Error("CSV source row offsets are inconsistent.");
|
|
12017
12051
|
return { rows, spans };
|
|
12018
12052
|
}
|
|
12019
|
-
var number = (
|
|
12020
|
-
if (!/^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?(?![\s\S])/.test(
|
|
12053
|
+
var number = (text21) => {
|
|
12054
|
+
if (!/^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?(?![\s\S])/.test(text21))
|
|
12021
12055
|
throw new Error("Lidar numeric cell is empty or malformed.");
|
|
12022
|
-
const value = Number(
|
|
12056
|
+
const value = Number(text21);
|
|
12023
12057
|
if (!finite4(value))
|
|
12024
12058
|
throw new Error("Lidar numeric value is not finite or exceeds bounds.");
|
|
12025
12059
|
return value;
|
|
@@ -12042,19 +12076,19 @@ function readLidarProducts(p, layouts, assets2) {
|
|
|
12042
12076
|
const pulseMap = /* @__PURE__ */ new Map(), origin = p.coordinateFrame.sensorOrigin;
|
|
12043
12077
|
const inside = (v, i) => v >= p.geometry.bounds.min[i] && v <= p.geometry.bounds.max[i];
|
|
12044
12078
|
const pulses = a.rows.map((cells, index3) => {
|
|
12045
|
-
const [
|
|
12046
|
-
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*(?![\s\S])/.test(
|
|
12079
|
+
const [id26, row, column, x, y, z32, status, count] = cells;
|
|
12080
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*(?![\s\S])/.test(id26) || pulseMap.has(id26))
|
|
12047
12081
|
throw new Error("Duplicate or invalid pulse identifier.");
|
|
12048
|
-
const scanRow = number(row), scanColumn = number(column), aim = [number(x), number(y), number(
|
|
12082
|
+
const scanRow = number(row), scanColumn = number(column), aim = [number(x), number(y), number(z32)];
|
|
12049
12083
|
const returnCount = count === "" ? null : number(count);
|
|
12050
12084
|
if (scanRow !== Math.floor(index3 / p.scan.columns) || scanColumn !== index3 % p.scan.columns || !aim.every(inside) || Math.hypot(...aim.map((v, i) => v - origin[i])) < p.geometry.nearRangeM)
|
|
12051
12085
|
throw new Error("Pulse grid or aim reference is inconsistent.");
|
|
12052
12086
|
if (!["retained", "no_return", "unavailable"].includes(status) || status === "retained" && (returnCount === null || !integer3(returnCount, 1, 15)) || status === "no_return" && returnCount !== 0 || status === "unavailable" && returnCount !== null)
|
|
12053
12087
|
throw new Error("Pulse status and return count are inconsistent.");
|
|
12054
|
-
pulseMap.set(
|
|
12088
|
+
pulseMap.set(id26, index3);
|
|
12055
12089
|
return {
|
|
12056
12090
|
index: index3,
|
|
12057
|
-
id:
|
|
12091
|
+
id: id26,
|
|
12058
12092
|
scanRow,
|
|
12059
12093
|
scanColumn,
|
|
12060
12094
|
aim,
|
|
@@ -12070,12 +12104,12 @@ function readLidarProducts(p, layouts, assets2) {
|
|
|
12070
12104
|
const pulseIndex = pulseMap.get(pulseId), pulse = pulseIndex === void 0 ? void 0 : pulses[pulseIndex];
|
|
12071
12105
|
if (pulseIndex === void 0 || !pulse || pulse.status !== "retained")
|
|
12072
12106
|
throw new Error("Point does not belong to a retained pulse.");
|
|
12073
|
-
const returnNumber = number(n), returnCount = number(count), x = number(xs), y = number(ys),
|
|
12074
|
-
if (!integer3(returnNumber, 1, 15) || returnCount !== pulse.returnCount || returnNumber !== pulse.pointIndices.length + 1 || intensity < 0 || intensity > 1 || !classes.has(classCode) || ![x, y,
|
|
12107
|
+
const returnNumber = number(n), returnCount = number(count), x = number(xs), y = number(ys), z32 = number(zs), intensity = number(amplitude), classCode = number(classification);
|
|
12108
|
+
if (!integer3(returnNumber, 1, 15) || returnCount !== pulse.returnCount || returnNumber !== pulse.pointIndices.length + 1 || intensity < 0 || intensity > 1 || !classes.has(classCode) || ![x, y, z32].every(inside))
|
|
12075
12109
|
throw new Error(
|
|
12076
12110
|
"Invalid lidar return group, class, intensity or coordinate."
|
|
12077
12111
|
);
|
|
12078
|
-
const d = [x - origin[0], y - origin[1],
|
|
12112
|
+
const d = [x - origin[0], y - origin[1], z32 - origin[2]], direction = pulse.aim.map((v, i) => v - origin[i]), norm = Math.hypot(...direction), rangeM = Math.hypot(...d), along = d.reduce((sum, v, i) => sum + v * direction[i] / norm, 0), residual = Math.hypot(
|
|
12079
12113
|
...d.map((v, i) => v - along * direction[i] / norm)
|
|
12080
12114
|
);
|
|
12081
12115
|
if (rangeM < p.geometry.nearRangeM || rangeM > p.geometry.farRangeM || along <= 0 || residual > p.geometry.rayToleranceM)
|
|
@@ -12089,7 +12123,7 @@ function readLidarProducts(p, layouts, assets2) {
|
|
|
12089
12123
|
returnCount,
|
|
12090
12124
|
x,
|
|
12091
12125
|
y,
|
|
12092
|
-
z:
|
|
12126
|
+
z: z32,
|
|
12093
12127
|
intensity,
|
|
12094
12128
|
classCode,
|
|
12095
12129
|
rangeM,
|
|
@@ -12120,7 +12154,7 @@ async function evaluateLidarProfile(observationInput, contextInput, selectionInp
|
|
|
12120
12154
|
classificationAccuracy: "not_checked",
|
|
12121
12155
|
georeferencing: "not_checked"
|
|
12122
12156
|
};
|
|
12123
|
-
const issue = (code, pointer6,
|
|
12157
|
+
const issue = (code, pointer6, message2) => result.issues.push({ code, pointer: pointer6, message: message2 });
|
|
12124
12158
|
const parsed = LidarProfileSchema.safeParse(profileInput), observation = parseExperimentalObservation(observationInput), context = parseAcquisitionContext(contextInput), selection = ProductSourceSelectionSchema.safeParse(selectionInput);
|
|
12125
12159
|
if (!parsed.success || !observation.success || !context.success || !selection.success) {
|
|
12126
12160
|
result.checks.structure = "failed";
|
|
@@ -12184,9 +12218,9 @@ async function evaluateLidarProfile(observationInput, contextInput, selectionInp
|
|
|
12184
12218
|
return result;
|
|
12185
12219
|
}
|
|
12186
12220
|
const assets2 = new Map(
|
|
12187
|
-
[...options.assets ?? []].map(([
|
|
12188
|
-
|
|
12189
|
-
Uint8Array.from(
|
|
12221
|
+
[...options.assets ?? []].map(([ref18, bytes6]) => [
|
|
12222
|
+
ref18,
|
|
12223
|
+
Uint8Array.from(bytes6)
|
|
12190
12224
|
])
|
|
12191
12225
|
);
|
|
12192
12226
|
const sourceResult = await evaluateProductSourceSelection(obs, sources, {
|
|
@@ -12310,9 +12344,9 @@ var SATELLITE_RASTER_PROFILE = Object.freeze({
|
|
|
12310
12344
|
scope: "north_up_utm_multispectral_reflectance_and_pixel_quality"
|
|
12311
12345
|
});
|
|
12312
12346
|
function satelliteRasterProfileJsonSchema() {
|
|
12313
|
-
const schema = z.toJSONSchema(SatelliteRasterProfileSchema, {
|
|
12347
|
+
const schema = preservePublishedSchema(z.toJSONSchema(SatelliteRasterProfileSchema, {
|
|
12314
12348
|
target: "draft-2020-12"
|
|
12315
|
-
});
|
|
12349
|
+
}));
|
|
12316
12350
|
const constrain = (node) => {
|
|
12317
12351
|
if (node === null || typeof node !== "object") return;
|
|
12318
12352
|
const value = node;
|
|
@@ -12355,13 +12389,13 @@ function satelliteCellBounds(p, row, column) {
|
|
|
12355
12389
|
};
|
|
12356
12390
|
}
|
|
12357
12391
|
function array(p, layouts, assets2, role) {
|
|
12358
|
-
const matches = layouts.filter((v) => v.productRef === p.products[role]), layout = matches[0],
|
|
12392
|
+
const matches = layouts.filter((v) => v.productRef === p.products[role]), layout = matches[0], bytes6 = assets2.get(p.products[role]);
|
|
12359
12393
|
const cube = role === "reflectance", lengths = cube ? [p.bands.length, p.grid.rows, p.grid.columns] : [p.grid.rows, p.grid.columns], names = cube ? ["band", "row", "column"] : ["row", "column"];
|
|
12360
12394
|
if (matches.length !== 1 || !layout || layout.kind !== "binary_array" || layout.elementType !== (cube ? "uint16" : "uint8") || layout.byteOrder !== "little" || layout.order !== "row_major" || layout.byteOffset !== 0 || layout.mediaType !== "application/octet-stream" || layout.quantity !== (cube ? "surface_reflectance_dn" : "pixel_quality_code") || layout.unit !== (cube ? "DN" : "code") || layout.axes.length !== lengths.length || layout.axes.some(
|
|
12361
12395
|
(a, i) => a.kind !== "index" || a.name !== names[i] || a.length !== lengths[i] || a.firstIndex !== 0
|
|
12362
|
-
) || layout.byteLength !== lengths.reduce((a, b) => a * b, 1) * (cube ? 2 : 1) || !
|
|
12396
|
+
) || layout.byteLength !== lengths.reduce((a, b) => a * b, 1) * (cube ? 2 : 1) || !bytes6 || bytes6.byteLength !== layout.byteLength)
|
|
12363
12397
|
throw new Error(`Invalid or absent satellite ${role} array.`);
|
|
12364
|
-
return { layout, bytes:
|
|
12398
|
+
return { layout, bytes: bytes6 };
|
|
12365
12399
|
}
|
|
12366
12400
|
function readSatelliteRasterProducts(p, layouts, assets2) {
|
|
12367
12401
|
validateSatelliteRasterDeclaration(p);
|
|
@@ -12441,7 +12475,7 @@ async function evaluateSatelliteRasterProfile(observationInput, contextInput, se
|
|
|
12441
12475
|
qualityAccuracy: "not_checked",
|
|
12442
12476
|
georeferencing: "not_checked"
|
|
12443
12477
|
};
|
|
12444
|
-
const issue = (code, pointer6,
|
|
12478
|
+
const issue = (code, pointer6, message2) => result.issues.push({ code, pointer: pointer6, message: message2 });
|
|
12445
12479
|
const parsed = SatelliteRasterProfileSchema.safeParse(profileInput), observation = parseExperimentalObservation(observationInput), context = parseAcquisitionContext(contextInput), selection = ProductSourceSelectionSchema.safeParse(selectionInput);
|
|
12446
12480
|
if (!parsed.success || !observation.success || !context.success || !selection.success) {
|
|
12447
12481
|
result.checks.structure = "failed";
|
|
@@ -12511,9 +12545,9 @@ async function evaluateSatelliteRasterProfile(observationInput, contextInput, se
|
|
|
12511
12545
|
return result;
|
|
12512
12546
|
}
|
|
12513
12547
|
const assets2 = new Map(
|
|
12514
|
-
[...options.assets ?? []].map(([
|
|
12515
|
-
|
|
12516
|
-
Uint8Array.from(
|
|
12548
|
+
[...options.assets ?? []].map(([ref18, bytes6]) => [
|
|
12549
|
+
ref18,
|
|
12550
|
+
Uint8Array.from(bytes6)
|
|
12517
12551
|
])
|
|
12518
12552
|
);
|
|
12519
12553
|
const sourceResult = await evaluateProductSourceSelection(obs, sources, {
|
|
@@ -12551,37 +12585,37 @@ var VOCABULARY_BINDINGS_PROFILE = "urn:disclosureos:profile:vocabulary-reference
|
|
|
12551
12585
|
var key2 = (r) => JSON.stringify([r.schemaId, r.documentId, r.sha256]);
|
|
12552
12586
|
var termKey = (t) => JSON.stringify([t.catalogId, t.revision, key2(t.document), t.termId]);
|
|
12553
12587
|
var claimKey = (b) => JSON.stringify([key2(b.claim.document), b.claim.claimId]);
|
|
12554
|
-
var digest9 = async (
|
|
12588
|
+
var digest9 = async (bytes6) => Array.from(
|
|
12555
12589
|
new Uint8Array(
|
|
12556
|
-
await crypto.subtle.digest("SHA-256", Uint8Array.from(
|
|
12590
|
+
await crypto.subtle.digest("SHA-256", Uint8Array.from(bytes6))
|
|
12557
12591
|
)
|
|
12558
12592
|
).map((n) => n.toString(16).padStart(2, "0")).join("");
|
|
12559
|
-
function decode9(
|
|
12560
|
-
const
|
|
12561
|
-
const parsed = JSON.parse(
|
|
12593
|
+
function decode9(bytes6) {
|
|
12594
|
+
const text21 = new TextDecoder("utf-8", { fatal: true }).decode(bytes6);
|
|
12595
|
+
const parsed = JSON.parse(text21);
|
|
12562
12596
|
let index3 = 0;
|
|
12563
12597
|
const ws = () => {
|
|
12564
|
-
while (/\s/.test(
|
|
12598
|
+
while (/\s/.test(text21[index3] ?? "") && index3 < text21.length) index3++;
|
|
12565
12599
|
};
|
|
12566
12600
|
function string() {
|
|
12567
12601
|
const start = index3++;
|
|
12568
|
-
while (index3 <
|
|
12569
|
-
if (
|
|
12570
|
-
if (
|
|
12602
|
+
while (index3 < text21.length) {
|
|
12603
|
+
if (text21[index3++] === '"') break;
|
|
12604
|
+
if (text21[index3 - 1] === "\\") index3++;
|
|
12571
12605
|
}
|
|
12572
|
-
return JSON.parse(
|
|
12606
|
+
return JSON.parse(text21.slice(start, index3));
|
|
12573
12607
|
}
|
|
12574
12608
|
function value() {
|
|
12575
12609
|
ws();
|
|
12576
|
-
if (
|
|
12610
|
+
if (text21[index3] === '"') {
|
|
12577
12611
|
string();
|
|
12578
12612
|
return;
|
|
12579
12613
|
}
|
|
12580
|
-
if (
|
|
12614
|
+
if (text21[index3] === "{") {
|
|
12581
12615
|
index3++;
|
|
12582
12616
|
ws();
|
|
12583
12617
|
const keys = /* @__PURE__ */ new Set();
|
|
12584
|
-
if (
|
|
12618
|
+
if (text21[index3] !== "}")
|
|
12585
12619
|
for (; ; ) {
|
|
12586
12620
|
ws();
|
|
12587
12621
|
const name = string();
|
|
@@ -12591,26 +12625,26 @@ function decode9(bytes5) {
|
|
|
12591
12625
|
index3++;
|
|
12592
12626
|
value();
|
|
12593
12627
|
ws();
|
|
12594
|
-
if (
|
|
12628
|
+
if (text21[index3] !== ",") break;
|
|
12595
12629
|
index3++;
|
|
12596
12630
|
}
|
|
12597
12631
|
index3++;
|
|
12598
12632
|
return;
|
|
12599
12633
|
}
|
|
12600
|
-
if (
|
|
12634
|
+
if (text21[index3] === "[") {
|
|
12601
12635
|
index3++;
|
|
12602
12636
|
ws();
|
|
12603
|
-
if (
|
|
12637
|
+
if (text21[index3] !== "]")
|
|
12604
12638
|
for (; ; ) {
|
|
12605
12639
|
value();
|
|
12606
12640
|
ws();
|
|
12607
|
-
if (
|
|
12641
|
+
if (text21[index3] !== ",") break;
|
|
12608
12642
|
index3++;
|
|
12609
12643
|
}
|
|
12610
12644
|
index3++;
|
|
12611
12645
|
return;
|
|
12612
12646
|
}
|
|
12613
|
-
while (index3 <
|
|
12647
|
+
while (index3 < text21.length && !/[\s,}\]]/.test(text21[index3])) index3++;
|
|
12614
12648
|
}
|
|
12615
12649
|
value();
|
|
12616
12650
|
return parsed;
|
|
@@ -12632,9 +12666,9 @@ var reviews = {
|
|
|
12632
12666
|
};
|
|
12633
12667
|
async function evaluateVocabularyBindings(input, options) {
|
|
12634
12668
|
const documents = new Map(
|
|
12635
|
-
[...options.documents].map(([
|
|
12636
|
-
|
|
12637
|
-
Uint8Array.from(
|
|
12669
|
+
[...options.documents].map(([hash8, bytes6]) => [
|
|
12670
|
+
hash8,
|
|
12671
|
+
Uint8Array.from(bytes6)
|
|
12638
12672
|
])
|
|
12639
12673
|
);
|
|
12640
12674
|
const parsed = [input, ...options.additionalBindings ?? []].map(
|
|
@@ -12657,8 +12691,8 @@ async function evaluateVocabularyBindings(input, options) {
|
|
|
12657
12691
|
scientificValidity: "not_checked",
|
|
12658
12692
|
authenticity: "not_checked"
|
|
12659
12693
|
};
|
|
12660
|
-
const problem = (code, pointer6,
|
|
12661
|
-
result.issues.push({ code, pointer: pointer6, message, stage: "profile", status });
|
|
12694
|
+
const problem = (code, pointer6, message2, status = "failed") => {
|
|
12695
|
+
result.issues.push({ code, pointer: pointer6, message: message2, stage: "profile", status });
|
|
12662
12696
|
};
|
|
12663
12697
|
const bindingsDocs = [], seenDocs = /* @__PURE__ */ new Map();
|
|
12664
12698
|
for (const [i, p] of parsed.entries()) {
|
|
@@ -12688,19 +12722,19 @@ async function evaluateVocabularyBindings(input, options) {
|
|
|
12688
12722
|
const snapshots = /* @__PURE__ */ new Map();
|
|
12689
12723
|
const loaded = /* @__PURE__ */ new Map(), resolvedHistories = /* @__PURE__ */ new Map(), resolvedCatalogs = /* @__PURE__ */ new Map();
|
|
12690
12724
|
const catalogRevisions = /* @__PURE__ */ new Map();
|
|
12691
|
-
function registerCatalog(catalog2,
|
|
12725
|
+
function registerCatalog(catalog2, ref18, pointer6) {
|
|
12692
12726
|
const identity = JSON.stringify([catalog2.catalogId, catalog2.revision]), prior = catalogRevisions.get(identity);
|
|
12693
|
-
if (prior && prior !== key2(
|
|
12727
|
+
if (prior && prior !== key2(ref18))
|
|
12694
12728
|
problem(
|
|
12695
12729
|
"VOCABULARY.REVISION_CONFLICT",
|
|
12696
12730
|
pointer6,
|
|
12697
12731
|
"One catalog revision identifies different supplied snapshots."
|
|
12698
12732
|
);
|
|
12699
|
-
catalogRevisions.set(identity, key2(
|
|
12733
|
+
catalogRevisions.set(identity, key2(ref18));
|
|
12700
12734
|
}
|
|
12701
|
-
for (const [
|
|
12735
|
+
for (const [hash8, bytes6] of documents) {
|
|
12702
12736
|
try {
|
|
12703
|
-
const raw = decode9(
|
|
12737
|
+
const raw = decode9(bytes6);
|
|
12704
12738
|
if (typeof raw === "object" && raw !== null && "kind" in raw && raw.kind === "vocabulary_catalog") {
|
|
12705
12739
|
const catalog2 = parseVocabularyCatalog(raw);
|
|
12706
12740
|
if (catalog2.success)
|
|
@@ -12709,32 +12743,32 @@ async function evaluateVocabularyBindings(input, options) {
|
|
|
12709
12743
|
{
|
|
12710
12744
|
documentId: catalog2.data.id,
|
|
12711
12745
|
schemaId: VOCABULARY_CATALOG_SCHEMA_ID,
|
|
12712
|
-
sha256: await digest9(
|
|
12746
|
+
sha256: await digest9(bytes6)
|
|
12713
12747
|
},
|
|
12714
|
-
`/documents/${
|
|
12748
|
+
`/documents/${hash8}`
|
|
12715
12749
|
);
|
|
12716
12750
|
}
|
|
12717
12751
|
} catch {
|
|
12718
12752
|
}
|
|
12719
12753
|
}
|
|
12720
|
-
async function load(
|
|
12721
|
-
const k = key2(
|
|
12754
|
+
async function load(ref18, pointer6) {
|
|
12755
|
+
const k = key2(ref18);
|
|
12722
12756
|
if (snapshots.has(k)) return loaded.get(k);
|
|
12723
|
-
const snapshot3 = { ...
|
|
12757
|
+
const snapshot3 = { ...ref18, status: "not_checked" };
|
|
12724
12758
|
snapshots.set(k, snapshot3);
|
|
12725
|
-
const
|
|
12726
|
-
if (!
|
|
12759
|
+
const bytes6 = documents.get(ref18.sha256);
|
|
12760
|
+
if (!bytes6) {
|
|
12727
12761
|
problem(
|
|
12728
12762
|
"SNAPSHOT.UNAVAILABLE",
|
|
12729
12763
|
pointer6,
|
|
12730
12764
|
"Required snapshot bytes were not supplied.",
|
|
12731
12765
|
"not_checked"
|
|
12732
12766
|
);
|
|
12733
|
-
result.unresolvedReferences.push(
|
|
12767
|
+
result.unresolvedReferences.push(ref18);
|
|
12734
12768
|
return;
|
|
12735
12769
|
}
|
|
12736
12770
|
snapshot3.status = "failed";
|
|
12737
|
-
if (await digest9(
|
|
12771
|
+
if (await digest9(bytes6) !== ref18.sha256) {
|
|
12738
12772
|
problem(
|
|
12739
12773
|
"SNAPSHOT.DIGEST",
|
|
12740
12774
|
pointer6,
|
|
@@ -12743,8 +12777,8 @@ async function evaluateVocabularyBindings(input, options) {
|
|
|
12743
12777
|
return;
|
|
12744
12778
|
}
|
|
12745
12779
|
try {
|
|
12746
|
-
const data = decode9(
|
|
12747
|
-
if (typeof data !== "object" || data === null || !("id" in data) || data.id !==
|
|
12780
|
+
const data = decode9(bytes6);
|
|
12781
|
+
if (typeof data !== "object" || data === null || !("id" in data) || data.id !== ref18.documentId) {
|
|
12748
12782
|
problem(
|
|
12749
12783
|
"SNAPSHOT.IDENTITY",
|
|
12750
12784
|
pointer6,
|
|
@@ -12762,9 +12796,9 @@ async function evaluateVocabularyBindings(input, options) {
|
|
|
12762
12796
|
);
|
|
12763
12797
|
}
|
|
12764
12798
|
}
|
|
12765
|
-
async function catalog(
|
|
12766
|
-
const k = key2(
|
|
12767
|
-
if (Object.prototype.hasOwnProperty.call(histories,
|
|
12799
|
+
async function catalog(ref18, pointer6) {
|
|
12800
|
+
const k = key2(ref18.document);
|
|
12801
|
+
if (Object.prototype.hasOwnProperty.call(histories, ref18.document.schemaId)) {
|
|
12768
12802
|
problem(
|
|
12769
12803
|
"SNAPSHOT.CONTRACT",
|
|
12770
12804
|
pointer6,
|
|
@@ -12773,13 +12807,13 @@ async function evaluateVocabularyBindings(input, options) {
|
|
|
12773
12807
|
return;
|
|
12774
12808
|
}
|
|
12775
12809
|
if (!snapshots.has(k)) {
|
|
12776
|
-
const raw = await load(
|
|
12810
|
+
const raw = await load(ref18.document, pointer6);
|
|
12777
12811
|
if (raw !== void 0) {
|
|
12778
12812
|
const snapshot3 = snapshots.get(k);
|
|
12779
|
-
if (
|
|
12813
|
+
if (ref18.document.schemaId !== VOCABULARY_CATALOG_SCHEMA_ID) {
|
|
12780
12814
|
if (Object.prototype.hasOwnProperty.call(
|
|
12781
12815
|
histories,
|
|
12782
|
-
|
|
12816
|
+
ref18.document.schemaId
|
|
12783
12817
|
))
|
|
12784
12818
|
problem(
|
|
12785
12819
|
"SNAPSHOT.CONTRACT",
|
|
@@ -12794,7 +12828,7 @@ async function evaluateVocabularyBindings(input, options) {
|
|
|
12794
12828
|
"The declared catalog contract is not supported.",
|
|
12795
12829
|
"not_checked"
|
|
12796
12830
|
);
|
|
12797
|
-
result.unresolvedReferences.push(
|
|
12831
|
+
result.unresolvedReferences.push(ref18.document);
|
|
12798
12832
|
}
|
|
12799
12833
|
} else {
|
|
12800
12834
|
const p = parseVocabularyCatalog(raw);
|
|
@@ -12807,14 +12841,14 @@ async function evaluateVocabularyBindings(input, options) {
|
|
|
12807
12841
|
else {
|
|
12808
12842
|
snapshot3.status = "passed";
|
|
12809
12843
|
resolvedCatalogs.set(k, p.data);
|
|
12810
|
-
registerCatalog(p.data,
|
|
12844
|
+
registerCatalog(p.data, ref18.document, pointer6);
|
|
12811
12845
|
}
|
|
12812
12846
|
}
|
|
12813
12847
|
}
|
|
12814
12848
|
}
|
|
12815
12849
|
const data = resolvedCatalogs.get(k);
|
|
12816
12850
|
if (!data) return;
|
|
12817
|
-
if (data.catalogId !==
|
|
12851
|
+
if (data.catalogId !== ref18.catalogId || data.revision !== ref18.revision) {
|
|
12818
12852
|
problem(
|
|
12819
12853
|
"VOCABULARY.IDENTITY",
|
|
12820
12854
|
pointer6,
|
|
@@ -12822,7 +12856,7 @@ async function evaluateVocabularyBindings(input, options) {
|
|
|
12822
12856
|
);
|
|
12823
12857
|
return;
|
|
12824
12858
|
}
|
|
12825
|
-
const term = data.terms.find((t) => t.id ===
|
|
12859
|
+
const term = data.terms.find((t) => t.id === ref18.termId);
|
|
12826
12860
|
if (!term)
|
|
12827
12861
|
problem(
|
|
12828
12862
|
"VOCABULARY.TERM",
|
|
@@ -12831,9 +12865,9 @@ async function evaluateVocabularyBindings(input, options) {
|
|
|
12831
12865
|
);
|
|
12832
12866
|
return term;
|
|
12833
12867
|
}
|
|
12834
|
-
async function history(
|
|
12835
|
-
const k = key2(
|
|
12836
|
-
if (
|
|
12868
|
+
async function history(ref18, pointer6) {
|
|
12869
|
+
const k = key2(ref18);
|
|
12870
|
+
if (ref18.schemaId === VOCABULARY_CATALOG_SCHEMA_ID) {
|
|
12837
12871
|
problem(
|
|
12838
12872
|
"SNAPSHOT.CONTRACT",
|
|
12839
12873
|
pointer6,
|
|
@@ -12842,11 +12876,11 @@ async function evaluateVocabularyBindings(input, options) {
|
|
|
12842
12876
|
return;
|
|
12843
12877
|
}
|
|
12844
12878
|
if (!snapshots.has(k)) {
|
|
12845
|
-
const raw = await load(
|
|
12879
|
+
const raw = await load(ref18, pointer6);
|
|
12846
12880
|
if (raw !== void 0) {
|
|
12847
|
-
const snapshot3 = snapshots.get(k), parser = Object.prototype.hasOwnProperty.call(histories,
|
|
12881
|
+
const snapshot3 = snapshots.get(k), parser = Object.prototype.hasOwnProperty.call(histories, ref18.schemaId) ? histories[ref18.schemaId] : void 0;
|
|
12848
12882
|
if (!parser) {
|
|
12849
|
-
if (
|
|
12883
|
+
if (ref18.schemaId === VOCABULARY_CATALOG_SCHEMA_ID)
|
|
12850
12884
|
problem(
|
|
12851
12885
|
"SNAPSHOT.CONTRACT",
|
|
12852
12886
|
pointer6,
|
|
@@ -12860,7 +12894,7 @@ async function evaluateVocabularyBindings(input, options) {
|
|
|
12860
12894
|
"The declared history contract is not supported.",
|
|
12861
12895
|
"not_checked"
|
|
12862
12896
|
);
|
|
12863
|
-
result.unresolvedReferences.push(
|
|
12897
|
+
result.unresolvedReferences.push(ref18);
|
|
12864
12898
|
}
|
|
12865
12899
|
} else {
|
|
12866
12900
|
const p = parser(raw);
|
|
@@ -12875,8 +12909,8 @@ async function evaluateVocabularyBindings(input, options) {
|
|
|
12875
12909
|
resolvedHistories.set(k, p.data);
|
|
12876
12910
|
const review2 = Object.prototype.hasOwnProperty.call(
|
|
12877
12911
|
reviews,
|
|
12878
|
-
|
|
12879
|
-
) ? reviews[
|
|
12912
|
+
ref18.schemaId
|
|
12913
|
+
) ? reviews[ref18.schemaId] : void 0;
|
|
12880
12914
|
if (review2) {
|
|
12881
12915
|
const reviewed = await review2(p.data, { documents });
|
|
12882
12916
|
for (const issue of reviewed.issues) {
|
|
@@ -13018,20 +13052,20 @@ async function evaluateVocabularyBindings(input, options) {
|
|
|
13018
13052
|
changed = false;
|
|
13019
13053
|
for (const c of assessed.values())
|
|
13020
13054
|
for (const prior of c.supersedes ?? []) {
|
|
13021
|
-
const
|
|
13022
|
-
if (assessed.has(
|
|
13023
|
-
if (!touched.has(c.id) || !touched.has(
|
|
13055
|
+
const id26 = prior.slice("claim:".length);
|
|
13056
|
+
if (assessed.has(id26) && (touched.has(c.id) || touched.has(id26))) {
|
|
13057
|
+
if (!touched.has(c.id) || !touched.has(id26)) changed = true;
|
|
13024
13058
|
touched.add(c.id);
|
|
13025
|
-
touched.add(
|
|
13059
|
+
touched.add(id26);
|
|
13026
13060
|
}
|
|
13027
13061
|
}
|
|
13028
13062
|
}
|
|
13029
13063
|
for (const c of assessed.values())
|
|
13030
13064
|
if (touched.has(c.id))
|
|
13031
13065
|
for (const prior of c.supersedes ?? []) {
|
|
13032
|
-
const
|
|
13033
|
-
if (!assessed.has(
|
|
13034
|
-
const current = criteria.get(JSON.stringify([historyKey, c.id])) ?? [], previous = criteria.get(JSON.stringify([historyKey,
|
|
13066
|
+
const id26 = prior.slice("claim:".length);
|
|
13067
|
+
if (!assessed.has(id26)) continue;
|
|
13068
|
+
const current = criteria.get(JSON.stringify([historyKey, c.id])) ?? [], previous = criteria.get(JSON.stringify([historyKey, id26])) ?? [];
|
|
13035
13069
|
const all = [...current, ...previous];
|
|
13036
13070
|
if (!current.length || !previous.length || all.some((e) => !e.resolution.resolvedTerm)) {
|
|
13037
13071
|
problem(
|
|
@@ -13063,7 +13097,645 @@ async function evaluateVocabularyBindings(input, options) {
|
|
|
13063
13097
|
result.success = result.checks.structural === "passed" && result.checks.semantic === "passed" && result.checks.profile === "passed";
|
|
13064
13098
|
return result;
|
|
13065
13099
|
}
|
|
13100
|
+
var id24 = z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._-]*(?![\s\S])/);
|
|
13101
|
+
var ref16 = (kind) => z.string().regex(new RegExp(`^${kind}:[A-Za-z0-9][A-Za-z0-9._-]*(?![\\s\\S])`));
|
|
13102
|
+
var text20 = z.string().min(1).regex(/\S/);
|
|
13103
|
+
var digest10 = z.strictObject({
|
|
13104
|
+
algorithm: z.literal("sha256"),
|
|
13105
|
+
value: z.string().regex(/^[a-f0-9]{64}(?![\s\S])/)
|
|
13106
|
+
});
|
|
13107
|
+
var max64 = "18446744073709551615";
|
|
13108
|
+
var belowMax = [...max64].flatMap((digit, i) => {
|
|
13109
|
+
const low = i === 0 ? 1 : 0, high = Number(digit) - 1;
|
|
13110
|
+
return high < low ? [] : [`${max64.slice(0, i)}[${low}-${high}][0-9]{${19 - i}}`];
|
|
13111
|
+
});
|
|
13112
|
+
var uint64 = z.string().regex(
|
|
13113
|
+
new RegExp(
|
|
13114
|
+
`^(?:0|[1-9][0-9]{0,18}|${belowMax.join("|")}|${max64})(?![\\s\\S])`
|
|
13115
|
+
)
|
|
13116
|
+
);
|
|
13117
|
+
var uint16 = z.number().int().min(0).max(65535);
|
|
13118
|
+
var uint32 = z.number().int().min(0).max(4294967295);
|
|
13119
|
+
var schemaIdentity = z.union([
|
|
13120
|
+
z.strictObject({ id: z.literal(0) }),
|
|
13121
|
+
z.strictObject({
|
|
13122
|
+
id: uint16.min(1),
|
|
13123
|
+
name: z.string(),
|
|
13124
|
+
encoding: z.string(),
|
|
13125
|
+
digest: digest10
|
|
13126
|
+
})
|
|
13127
|
+
]);
|
|
13128
|
+
var location = z.discriminatedUnion("kind", [
|
|
13129
|
+
z.strictObject({ kind: z.literal("file"), offset: uint64 }),
|
|
13130
|
+
z.strictObject({
|
|
13131
|
+
kind: z.literal("chunk"),
|
|
13132
|
+
chunkOffset: uint64,
|
|
13133
|
+
recordOffset: uint64
|
|
13134
|
+
})
|
|
13135
|
+
]);
|
|
13136
|
+
var message = z.strictObject({
|
|
13137
|
+
location,
|
|
13138
|
+
sequence: uint32,
|
|
13139
|
+
logTimeNs: uint64,
|
|
13140
|
+
publishTimeNs: uint64
|
|
13141
|
+
});
|
|
13142
|
+
var MCAP_SOURCE_MAPPING_SCHEMA_ID = "urn:disclosureos:experimental:mcap-source-mapping:0.1.0";
|
|
13143
|
+
var McapSourceMappingSchema = z.strictObject({
|
|
13144
|
+
kind: z.literal("mcap_source_mapping"),
|
|
13145
|
+
schemaVersion: z.literal("0.1.0"),
|
|
13146
|
+
id: id24,
|
|
13147
|
+
observationId: id24,
|
|
13148
|
+
recordings: z.array(
|
|
13149
|
+
z.strictObject({
|
|
13150
|
+
id: id24,
|
|
13151
|
+
productRef: ref16("product"),
|
|
13152
|
+
digest: digest10,
|
|
13153
|
+
byteLength: uint64,
|
|
13154
|
+
mediaType: z.literal("application/mcap")
|
|
13155
|
+
})
|
|
13156
|
+
).min(1),
|
|
13157
|
+
channels: z.array(
|
|
13158
|
+
z.strictObject({
|
|
13159
|
+
id: id24,
|
|
13160
|
+
recordingRef: ref16("recording"),
|
|
13161
|
+
channelId: uint16,
|
|
13162
|
+
topic: z.string(),
|
|
13163
|
+
messageEncoding: text20,
|
|
13164
|
+
schema: schemaIdentity,
|
|
13165
|
+
decoder: z.strictObject({
|
|
13166
|
+
methodRef: ref16("method"),
|
|
13167
|
+
methodVersion: text20
|
|
13168
|
+
})
|
|
13169
|
+
})
|
|
13170
|
+
).min(1),
|
|
13171
|
+
selections: z.array(
|
|
13172
|
+
z.strictObject({
|
|
13173
|
+
id: id24,
|
|
13174
|
+
measurementRef: ref16("measurement"),
|
|
13175
|
+
channelRef: ref16("channel"),
|
|
13176
|
+
message,
|
|
13177
|
+
payloadPointer: z.string().regex(/^(?:\/(?:[^~]|~[01])*)?(?![\s\S])/)
|
|
13178
|
+
})
|
|
13179
|
+
)
|
|
13180
|
+
});
|
|
13181
|
+
function mcapSourceMappingJsonSchema() {
|
|
13182
|
+
return {
|
|
13183
|
+
...preservePublishedSchema(z.toJSONSchema(McapSourceMappingSchema, { target: "draft-2020-12" })),
|
|
13184
|
+
$id: MCAP_SOURCE_MAPPING_SCHEMA_ID
|
|
13185
|
+
};
|
|
13186
|
+
}
|
|
13187
|
+
var hash6 = async (bytes6) => [
|
|
13188
|
+
...new Uint8Array(
|
|
13189
|
+
await crypto.subtle.digest("SHA-256", Uint8Array.from(bytes6))
|
|
13190
|
+
)
|
|
13191
|
+
].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
13192
|
+
function equal3(a, b) {
|
|
13193
|
+
if (a === b) return true;
|
|
13194
|
+
if (!a || !b || typeof a !== "object" || typeof b !== "object") return false;
|
|
13195
|
+
const x = a, y = b;
|
|
13196
|
+
return Object.keys(x).length === Object.keys(y).length && Object.keys(x).every(
|
|
13197
|
+
(k) => Object.prototype.hasOwnProperty.call(y, k) && equal3(x[k], y[k])
|
|
13198
|
+
);
|
|
13199
|
+
}
|
|
13200
|
+
function scalarAt(value, pointer6) {
|
|
13201
|
+
for (const token of pointer6 === "" ? [] : pointer6.slice(1).split("/")) {
|
|
13202
|
+
const key3 = token.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
13203
|
+
if (!value || typeof value !== "object" || !Object.prototype.hasOwnProperty.call(value, key3) || Array.isArray(value) && !/^(0|[1-9][0-9]*)$/.test(key3))
|
|
13204
|
+
throw new Error("Payload pointer does not resolve.");
|
|
13205
|
+
value = value[key3];
|
|
13206
|
+
}
|
|
13207
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
13208
|
+
throw new Error("Selected payload must be a finite numeric scalar.");
|
|
13209
|
+
return value;
|
|
13210
|
+
}
|
|
13211
|
+
async function evaluateMcapSourceMapping(observationInput, mappingInput, options = {}) {
|
|
13212
|
+
const observation = parseExperimentalObservation(observationInput), parsed = McapSourceMappingSchema.safeParse(mappingInput);
|
|
13213
|
+
const result = {
|
|
13214
|
+
success: false,
|
|
13215
|
+
checks: {
|
|
13216
|
+
structural: "passed",
|
|
13217
|
+
semantic: "not_checked",
|
|
13218
|
+
external: "not_checked",
|
|
13219
|
+
content: "not_checked"
|
|
13220
|
+
},
|
|
13221
|
+
issues: [],
|
|
13222
|
+
selections: [],
|
|
13223
|
+
scientific: "not_checked",
|
|
13224
|
+
calibration: "not_checked",
|
|
13225
|
+
units: "not_checked"
|
|
13226
|
+
};
|
|
13227
|
+
const issue = (code, pointer6, message2) => result.issues.push({ code, pointer: pointer6, message: message2 });
|
|
13228
|
+
if (!parsed.success)
|
|
13229
|
+
for (const e of parsed.error.issues)
|
|
13230
|
+
issue("STRUCT.VALUE", "/mapping/" + e.path.join("/"), e.message);
|
|
13231
|
+
if (!observation.success)
|
|
13232
|
+
for (const e of observation.issues.filter((i) => i.severity === "error"))
|
|
13233
|
+
issue(e.code, "/observation" + e.pointer, e.message);
|
|
13234
|
+
if (!parsed.success || observation.checks.structural === "failed") {
|
|
13235
|
+
result.checks.structural = "failed";
|
|
13236
|
+
return result;
|
|
13237
|
+
}
|
|
13238
|
+
if (!observation.success) {
|
|
13239
|
+
result.checks.semantic = "failed";
|
|
13240
|
+
return result;
|
|
13241
|
+
}
|
|
13242
|
+
const data = parsed.data, record = observation.data;
|
|
13243
|
+
const products = new Map(record.products.map((p) => [`product:${p.id}`, p]));
|
|
13244
|
+
const assertions = new Map(
|
|
13245
|
+
record.assertions.map((a) => [`assertion:${a.id}`, a])
|
|
13246
|
+
);
|
|
13247
|
+
const processing = new Map(
|
|
13248
|
+
record.processing.map((p) => [`process:${p.id}`, p])
|
|
13249
|
+
);
|
|
13250
|
+
const measurements = new Map(
|
|
13251
|
+
record.measurements.map((m) => [`measurement:${m.id}`, m])
|
|
13252
|
+
);
|
|
13253
|
+
const methods = new Map(record.methods.map((m) => [`method:${m.id}`, m]));
|
|
13254
|
+
function supports(refs, target, seen = /* @__PURE__ */ new Set()) {
|
|
13255
|
+
return refs.some((r) => {
|
|
13256
|
+
if (r === target) return true;
|
|
13257
|
+
if (seen.has(r)) return false;
|
|
13258
|
+
seen.add(r);
|
|
13259
|
+
const a = assertions.get(r), p = products.get(r);
|
|
13260
|
+
if (a) return supports([a.provenance.sourceRef], target, seen);
|
|
13261
|
+
if (p?.kind === "derived")
|
|
13262
|
+
return supports(
|
|
13263
|
+
processing.get(p.generatedBy)?.inputRefs ?? [],
|
|
13264
|
+
target,
|
|
13265
|
+
seen
|
|
13266
|
+
);
|
|
13267
|
+
return false;
|
|
13268
|
+
});
|
|
13269
|
+
}
|
|
13270
|
+
const recordings = /* @__PURE__ */ new Map();
|
|
13271
|
+
const channels = /* @__PURE__ */ new Map();
|
|
13272
|
+
const schemaIds = /* @__PURE__ */ new Map();
|
|
13273
|
+
const productIds = /* @__PURE__ */ new Set(), channelIds = /* @__PURE__ */ new Set(), selectionIds = /* @__PURE__ */ new Set(), measurementIds = /* @__PURE__ */ new Set();
|
|
13274
|
+
if (data.observationId !== record.id)
|
|
13275
|
+
issue(
|
|
13276
|
+
"MCAP.OBSERVATION",
|
|
13277
|
+
"/mapping/observationId",
|
|
13278
|
+
"Mapping identifies a different observation."
|
|
13279
|
+
);
|
|
13280
|
+
for (const [i, r] of data.recordings.entries()) {
|
|
13281
|
+
const p = `/mapping/recordings/${i}`, product = products.get(r.productRef);
|
|
13282
|
+
if (recordings.has(`recording:${r.id}`) || productIds.has(r.productRef))
|
|
13283
|
+
issue(
|
|
13284
|
+
"MCAP.UNIQUE",
|
|
13285
|
+
p,
|
|
13286
|
+
"Recording IDs and product mappings must be unique."
|
|
13287
|
+
);
|
|
13288
|
+
recordings.set(`recording:${r.id}`, r);
|
|
13289
|
+
productIds.add(r.productRef);
|
|
13290
|
+
if (!product || product.format !== r.mediaType || !equal3(product.digest, r.digest) || BigInt(r.byteLength) < 8n)
|
|
13291
|
+
issue(
|
|
13292
|
+
"MCAP.PRODUCT",
|
|
13293
|
+
p,
|
|
13294
|
+
"Recording must pin an existing MCAP product and its exact digest and length."
|
|
13295
|
+
);
|
|
13296
|
+
}
|
|
13297
|
+
for (const [i, c] of data.channels.entries()) {
|
|
13298
|
+
const p = `/mapping/channels/${i}`, key3 = `${c.recordingRef}/${c.channelId}`;
|
|
13299
|
+
if (channels.has(`channel:${c.id}`) || channelIds.has(key3))
|
|
13300
|
+
issue(
|
|
13301
|
+
"MCAP.UNIQUE",
|
|
13302
|
+
p,
|
|
13303
|
+
"Channel IDs and recording/channel mappings must be unique."
|
|
13304
|
+
);
|
|
13305
|
+
channels.set(`channel:${c.id}`, c);
|
|
13306
|
+
channelIds.add(key3);
|
|
13307
|
+
const schemaKey = `${c.recordingRef}/${c.schema.id}`;
|
|
13308
|
+
if (schemaIds.has(schemaKey) && !equal3(schemaIds.get(schemaKey), c.schema))
|
|
13309
|
+
issue(
|
|
13310
|
+
"MCAP.SCHEMA",
|
|
13311
|
+
p,
|
|
13312
|
+
"A recording-local schema ID must retain one identity."
|
|
13313
|
+
);
|
|
13314
|
+
schemaIds.set(schemaKey, c.schema);
|
|
13315
|
+
if (!recordings.has(c.recordingRef))
|
|
13316
|
+
issue("MCAP.RECORDING", p, "Channel recording does not exist.");
|
|
13317
|
+
if (methods.get(c.decoder.methodRef)?.version !== c.decoder.methodVersion)
|
|
13318
|
+
issue(
|
|
13319
|
+
"MCAP.DECODER",
|
|
13320
|
+
p,
|
|
13321
|
+
"Decoder must name a declared method and exact version."
|
|
13322
|
+
);
|
|
13323
|
+
}
|
|
13324
|
+
for (const [i, s] of data.selections.entries()) {
|
|
13325
|
+
const p = `/mapping/selections/${i}`, c = channels.get(s.channelRef), r = c && recordings.get(c.recordingRef), m = measurements.get(s.measurementRef);
|
|
13326
|
+
if (selectionIds.has(s.id) || measurementIds.has(s.measurementRef))
|
|
13327
|
+
issue(
|
|
13328
|
+
"MCAP.UNIQUE",
|
|
13329
|
+
p,
|
|
13330
|
+
"Selection IDs and measurement mappings must be unique."
|
|
13331
|
+
);
|
|
13332
|
+
selectionIds.add(s.id);
|
|
13333
|
+
measurementIds.add(s.measurementRef);
|
|
13334
|
+
if (!c || !r) issue("MCAP.CHANNEL", p, "Selected channel does not exist.");
|
|
13335
|
+
else {
|
|
13336
|
+
if (!m || !supports(m.sourceRefs, r.productRef))
|
|
13337
|
+
issue(
|
|
13338
|
+
"MCAP.MEASUREMENT",
|
|
13339
|
+
p,
|
|
13340
|
+
"Selected recording must be in the measurement's source or processing lineage."
|
|
13341
|
+
);
|
|
13342
|
+
const l = s.message.location, outer = BigInt(l.kind === "file" ? l.offset : l.chunkOffset);
|
|
13343
|
+
if (outer < 8n || outer + 9n > BigInt(r.byteLength))
|
|
13344
|
+
issue("MCAP.LOCATION", p, "Record location is outside the recording.");
|
|
13345
|
+
}
|
|
13346
|
+
}
|
|
13347
|
+
if (result.issues.length) {
|
|
13348
|
+
result.checks.semantic = "failed";
|
|
13349
|
+
return result;
|
|
13350
|
+
}
|
|
13351
|
+
result.checks.semantic = "passed";
|
|
13352
|
+
const assets2 = new Map(
|
|
13353
|
+
[...options.assets ?? []].map(([key3, bytes6]) => [
|
|
13354
|
+
key3,
|
|
13355
|
+
Uint8Array.from(bytes6)
|
|
13356
|
+
])
|
|
13357
|
+
);
|
|
13358
|
+
const valid = /* @__PURE__ */ new Set();
|
|
13359
|
+
for (const r of data.recordings) {
|
|
13360
|
+
const bytes6 = assets2.get(r.productRef);
|
|
13361
|
+
if (!bytes6) continue;
|
|
13362
|
+
if (BigInt(bytes6.length) !== BigInt(r.byteLength) || await hash6(bytes6) !== r.digest.value)
|
|
13363
|
+
issue(
|
|
13364
|
+
"MCAP.ARTIFACT",
|
|
13365
|
+
r.productRef,
|
|
13366
|
+
"Source byte length or digest differs."
|
|
13367
|
+
);
|
|
13368
|
+
else valid.add(r.productRef);
|
|
13369
|
+
}
|
|
13370
|
+
result.checks.external = result.issues.length ? "failed" : valid.size === recordings.size ? "passed" : "not_checked";
|
|
13371
|
+
const cache = /* @__PURE__ */ new Map();
|
|
13372
|
+
for (const [i, s] of data.selections.entries()) {
|
|
13373
|
+
const c = channels.get(s.channelRef), r = recordings.get(c.recordingRef);
|
|
13374
|
+
if (!valid.has(r.productRef) || !options.resolveMessage) {
|
|
13375
|
+
result.selections.push({
|
|
13376
|
+
id: s.id,
|
|
13377
|
+
status: valid.has(r.productRef) || !assets2.has(r.productRef) ? "not_checked" : "failed"
|
|
13378
|
+
});
|
|
13379
|
+
continue;
|
|
13380
|
+
}
|
|
13381
|
+
try {
|
|
13382
|
+
const key3 = JSON.stringify([r.id, c.id, s.message.location]);
|
|
13383
|
+
if (!cache.has(key3))
|
|
13384
|
+
cache.set(
|
|
13385
|
+
key3,
|
|
13386
|
+
Promise.resolve(
|
|
13387
|
+
options.resolveMessage({
|
|
13388
|
+
recording: structuredClone(r),
|
|
13389
|
+
channel: structuredClone(c),
|
|
13390
|
+
message: structuredClone(s.message),
|
|
13391
|
+
bytes: assets2.get(r.productRef)
|
|
13392
|
+
})
|
|
13393
|
+
).then((v) => structuredClone(v))
|
|
13394
|
+
);
|
|
13395
|
+
const found = await cache.get(key3);
|
|
13396
|
+
if (found.channelId !== c.channelId || found.topic !== c.topic || found.messageEncoding !== c.messageEncoding || !equal3(found.schema, c.schema) || !equal3(found.message, s.message))
|
|
13397
|
+
throw new Error("Located message identity differs from the reference.");
|
|
13398
|
+
const value = scalarAt(found.decoded, s.payloadPointer);
|
|
13399
|
+
if (value !== measurements.get(s.measurementRef).value.value)
|
|
13400
|
+
throw new Error("Selected payload value differs from the measurement.");
|
|
13401
|
+
result.selections.push({ id: s.id, status: "passed", value });
|
|
13402
|
+
} catch (error) {
|
|
13403
|
+
issue("MCAP.CONTENT", `/mapping/selections/${i}`, String(error));
|
|
13404
|
+
result.selections.push({ id: s.id, status: "failed" });
|
|
13405
|
+
}
|
|
13406
|
+
}
|
|
13407
|
+
result.checks.content = result.selections.some((s) => s.status === "failed") ? "failed" : result.selections.length > 0 && result.selections.every((s) => s.status === "passed") ? "passed" : "not_checked";
|
|
13408
|
+
result.success = result.checks.external === "passed" && result.checks.content === "passed";
|
|
13409
|
+
return result;
|
|
13410
|
+
}
|
|
13411
|
+
var id25 = z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._-]*(?![\s\S])/);
|
|
13412
|
+
var ref17 = (kind) => z.string().regex(new RegExp(`^${kind}:[A-Za-z0-9][A-Za-z0-9._-]*(?![\\s\\S])`));
|
|
13413
|
+
var integer5 = z.number().int().min(0).max(Number.MAX_SAFE_INTEGER);
|
|
13414
|
+
var positive2 = integer5.min(1);
|
|
13415
|
+
var tick = z.string().max(100).regex(/^(?:0|-?[1-9][0-9]*)(?![\s\S])/);
|
|
13416
|
+
var timeBase = z.strictObject({ numerator: positive2, denominator: positive2 });
|
|
13417
|
+
var stream = z.strictObject({
|
|
13418
|
+
streamIndex: integer5,
|
|
13419
|
+
timeBase,
|
|
13420
|
+
presentationTicks: z.array(tick).min(1)
|
|
13421
|
+
});
|
|
13422
|
+
var VIDEO_FRAME_SOURCE_MAPPING_SCHEMA_ID = "urn:disclosureos:experimental:video-frame-source-mapping:0.1.0";
|
|
13423
|
+
var VideoFrameSourceMappingSchema = z.strictObject({
|
|
13424
|
+
kind: z.literal("video_frame_source_mapping"),
|
|
13425
|
+
schemaVersion: z.literal("0.1.0"),
|
|
13426
|
+
id: id25,
|
|
13427
|
+
observationId: id25,
|
|
13428
|
+
productRef: ref17("product"),
|
|
13429
|
+
digest: z.strictObject({
|
|
13430
|
+
algorithm: z.literal("sha256"),
|
|
13431
|
+
value: z.string().regex(/^[a-f0-9]{64}(?![\s\S])/)
|
|
13432
|
+
}),
|
|
13433
|
+
byteLength: positive2,
|
|
13434
|
+
mediaType: z.string().regex(/^video\/[^\s]+(?![\s\S])/),
|
|
13435
|
+
indexer: z.strictObject({
|
|
13436
|
+
methodRef: ref17("method"),
|
|
13437
|
+
methodVersion: z.string().min(1).regex(/\S/)
|
|
13438
|
+
}),
|
|
13439
|
+
streams: z.array(stream).min(1),
|
|
13440
|
+
selections: z.array(z.strictObject({ id: id25, streamIndex: integer5, frameIndex: integer5 })).min(1)
|
|
13441
|
+
});
|
|
13442
|
+
function videoFrameSourceMappingJsonSchema() {
|
|
13443
|
+
return {
|
|
13444
|
+
...preservePublishedSchema(z.toJSONSchema(VideoFrameSourceMappingSchema, {
|
|
13445
|
+
target: "draft-2020-12"
|
|
13446
|
+
})),
|
|
13447
|
+
$id: VIDEO_FRAME_SOURCE_MAPPING_SCHEMA_ID
|
|
13448
|
+
};
|
|
13449
|
+
}
|
|
13450
|
+
function readVideoFrameReference(mapping, streamIndex, frameIndex) {
|
|
13451
|
+
const s = mapping.streams.find((s2) => s2.streamIndex === streamIndex);
|
|
13452
|
+
if (!s || !Number.isSafeInteger(frameIndex) || frameIndex < 0 || frameIndex >= s.presentationTicks.length)
|
|
13453
|
+
throw new Error(
|
|
13454
|
+
"Video stream or presentation-order frame is outside the index."
|
|
13455
|
+
);
|
|
13456
|
+
const pts = s.presentationTicks[frameIndex];
|
|
13457
|
+
const numerator = BigInt(s.timeBase.numerator), denominator = String(s.timeBase.denominator);
|
|
13458
|
+
return {
|
|
13459
|
+
productRef: mapping.productRef,
|
|
13460
|
+
digest: { ...mapping.digest },
|
|
13461
|
+
streamIndex,
|
|
13462
|
+
frameIndex,
|
|
13463
|
+
presentationTick: pts,
|
|
13464
|
+
timeBase: { ...s.timeBase },
|
|
13465
|
+
presentationSeconds: {
|
|
13466
|
+
numerator: String(BigInt(pts) * numerator),
|
|
13467
|
+
denominator
|
|
13468
|
+
},
|
|
13469
|
+
offsetFromFirstFrameSeconds: {
|
|
13470
|
+
numerator: String(
|
|
13471
|
+
(BigInt(pts) - BigInt(s.presentationTicks[0])) * numerator
|
|
13472
|
+
),
|
|
13473
|
+
denominator
|
|
13474
|
+
}
|
|
13475
|
+
};
|
|
13476
|
+
}
|
|
13477
|
+
async function evaluateVideoFrameSourceMapping(observationInput, mappingInput, options = {}) {
|
|
13478
|
+
const observation = parseExperimentalObservation(observationInput), parsed = VideoFrameSourceMappingSchema.safeParse(mappingInput);
|
|
13479
|
+
const result = {
|
|
13480
|
+
success: false,
|
|
13481
|
+
checks: {
|
|
13482
|
+
structural: "passed",
|
|
13483
|
+
semantic: "not_checked",
|
|
13484
|
+
external: "not_checked",
|
|
13485
|
+
frameTiming: "not_checked"
|
|
13486
|
+
},
|
|
13487
|
+
issues: [],
|
|
13488
|
+
selections: [],
|
|
13489
|
+
captureTime: "not_checked",
|
|
13490
|
+
scientific: "not_checked",
|
|
13491
|
+
calibration: "not_checked",
|
|
13492
|
+
pixelContent: "not_checked"
|
|
13493
|
+
};
|
|
13494
|
+
const issue = (code, pointer6, message2) => {
|
|
13495
|
+
result.issues.push({ code, pointer: pointer6, message: message2 });
|
|
13496
|
+
};
|
|
13497
|
+
if (!parsed.success)
|
|
13498
|
+
for (const e of parsed.error.issues)
|
|
13499
|
+
issue("STRUCT.VALUE", "/mapping/" + e.path.join("/"), e.message);
|
|
13500
|
+
if (!observation.success)
|
|
13501
|
+
for (const e of observation.issues.filter((e2) => e2.severity === "error"))
|
|
13502
|
+
issue(e.code, "/observation" + e.pointer, e.message);
|
|
13503
|
+
if (!parsed.success || observation.checks.structural === "failed") {
|
|
13504
|
+
result.checks.structural = "failed";
|
|
13505
|
+
return result;
|
|
13506
|
+
}
|
|
13507
|
+
if (!observation.success) {
|
|
13508
|
+
result.checks.semantic = "failed";
|
|
13509
|
+
return result;
|
|
13510
|
+
}
|
|
13511
|
+
const data = parsed.data, record = observation.data;
|
|
13512
|
+
if (data.observationId !== record.id)
|
|
13513
|
+
issue(
|
|
13514
|
+
"VIDEO.OBSERVATION",
|
|
13515
|
+
"/mapping/observationId",
|
|
13516
|
+
"Mapping identifies a different observation."
|
|
13517
|
+
);
|
|
13518
|
+
const product = record.products.find(
|
|
13519
|
+
(p) => `product:${p.id}` === data.productRef
|
|
13520
|
+
);
|
|
13521
|
+
if (!product || product.format !== data.mediaType || product.digest?.algorithm !== data.digest.algorithm || product.digest?.value !== data.digest.value)
|
|
13522
|
+
issue(
|
|
13523
|
+
"VIDEO.PRODUCT",
|
|
13524
|
+
"/mapping/productRef",
|
|
13525
|
+
"Mapping must pin an existing video product and its exact digest and media type."
|
|
13526
|
+
);
|
|
13527
|
+
const method2 = record.methods.find(
|
|
13528
|
+
(m) => `method:${m.id}` === data.indexer.methodRef
|
|
13529
|
+
);
|
|
13530
|
+
if (!method2 || method2.version !== data.indexer.methodVersion)
|
|
13531
|
+
issue(
|
|
13532
|
+
"VIDEO.INDEXER",
|
|
13533
|
+
"/mapping/indexer",
|
|
13534
|
+
"Indexer must name a declared method and exact version."
|
|
13535
|
+
);
|
|
13536
|
+
const streamIds = /* @__PURE__ */ new Set(), selectionIds = /* @__PURE__ */ new Set();
|
|
13537
|
+
for (const [i, s] of data.streams.entries()) {
|
|
13538
|
+
if (streamIds.has(s.streamIndex))
|
|
13539
|
+
issue(
|
|
13540
|
+
"VIDEO.UNIQUE",
|
|
13541
|
+
`/mapping/streams/${i}`,
|
|
13542
|
+
"Stream indexes must be unique within this product."
|
|
13543
|
+
);
|
|
13544
|
+
streamIds.add(s.streamIndex);
|
|
13545
|
+
for (let j = 1; j < s.presentationTicks.length; j++)
|
|
13546
|
+
if (BigInt(s.presentationTicks[j]) < BigInt(s.presentationTicks[j - 1])) {
|
|
13547
|
+
issue(
|
|
13548
|
+
"VIDEO.ORDER",
|
|
13549
|
+
`/mapping/streams/${i}/presentationTicks/${j}`,
|
|
13550
|
+
"Frames must be in nondecreasing presentation order, not packet decode order."
|
|
13551
|
+
);
|
|
13552
|
+
break;
|
|
13553
|
+
}
|
|
13554
|
+
}
|
|
13555
|
+
for (const [i, s] of data.selections.entries()) {
|
|
13556
|
+
if (selectionIds.has(s.id))
|
|
13557
|
+
issue(
|
|
13558
|
+
"VIDEO.UNIQUE",
|
|
13559
|
+
`/mapping/selections/${i}`,
|
|
13560
|
+
"Selection IDs must be unique."
|
|
13561
|
+
);
|
|
13562
|
+
selectionIds.add(s.id);
|
|
13563
|
+
try {
|
|
13564
|
+
readVideoFrameReference(data, s.streamIndex, s.frameIndex);
|
|
13565
|
+
} catch (e) {
|
|
13566
|
+
issue("VIDEO.LOCATOR", `/mapping/selections/${i}`, String(e));
|
|
13567
|
+
}
|
|
13568
|
+
}
|
|
13569
|
+
if (result.issues.length) {
|
|
13570
|
+
result.checks.semantic = "failed";
|
|
13571
|
+
return result;
|
|
13572
|
+
}
|
|
13573
|
+
result.checks.semantic = "passed";
|
|
13574
|
+
const supplied = options.assets?.get(data.productRef), bytes6 = supplied && Uint8Array.from(supplied);
|
|
13575
|
+
const resolveFrameIndex = options.resolveFrameIndex;
|
|
13576
|
+
if (bytes6) {
|
|
13577
|
+
const hash8 = [
|
|
13578
|
+
...new Uint8Array(await crypto.subtle.digest("SHA-256", bytes6))
|
|
13579
|
+
].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
13580
|
+
result.checks.external = bytes6.length === data.byteLength && hash8 === data.digest.value ? "passed" : "failed";
|
|
13581
|
+
if (result.checks.external === "failed")
|
|
13582
|
+
issue(
|
|
13583
|
+
"VIDEO.ARTIFACT",
|
|
13584
|
+
data.productRef,
|
|
13585
|
+
"Original byte length or digest differs."
|
|
13586
|
+
);
|
|
13587
|
+
else if (resolveFrameIndex) {
|
|
13588
|
+
try {
|
|
13589
|
+
const decoded = z.array(stream).min(1).parse(
|
|
13590
|
+
await resolveFrameIndex({
|
|
13591
|
+
bytes: bytes6,
|
|
13592
|
+
streamIndexes: data.streams.map((s) => s.streamIndex),
|
|
13593
|
+
indexer: { ...data.indexer }
|
|
13594
|
+
})
|
|
13595
|
+
);
|
|
13596
|
+
if (decoded.length !== data.streams.length || new Set(decoded.map((s) => s.streamIndex)).size !== decoded.length)
|
|
13597
|
+
throw new Error("Decoded stream set differs.");
|
|
13598
|
+
for (const s of data.streams) {
|
|
13599
|
+
const found = decoded.find((d) => d.streamIndex === s.streamIndex);
|
|
13600
|
+
if (!found || found.timeBase.numerator !== s.timeBase.numerator || found.timeBase.denominator !== s.timeBase.denominator || found.presentationTicks.length !== s.presentationTicks.length || found.presentationTicks.some((t, i) => t !== s.presentationTicks[i]))
|
|
13601
|
+
throw new Error(
|
|
13602
|
+
"Decoded stream identity, time base or frame timestamps differ."
|
|
13603
|
+
);
|
|
13604
|
+
}
|
|
13605
|
+
result.checks.frameTiming = "passed";
|
|
13606
|
+
} catch (e) {
|
|
13607
|
+
result.checks.frameTiming = "failed";
|
|
13608
|
+
issue("VIDEO.FRAME_TIMING", "/mapping/streams", String(e));
|
|
13609
|
+
}
|
|
13610
|
+
}
|
|
13611
|
+
}
|
|
13612
|
+
const status = result.checks.external === "failed" || result.checks.frameTiming === "failed" ? "failed" : result.checks.frameTiming === "passed" ? "passed" : "not_checked";
|
|
13613
|
+
for (const s of data.selections)
|
|
13614
|
+
result.selections.push({
|
|
13615
|
+
id: s.id,
|
|
13616
|
+
status,
|
|
13617
|
+
...status === "passed" ? {
|
|
13618
|
+
reference: readVideoFrameReference(
|
|
13619
|
+
data,
|
|
13620
|
+
s.streamIndex,
|
|
13621
|
+
s.frameIndex
|
|
13622
|
+
)
|
|
13623
|
+
} : {}
|
|
13624
|
+
});
|
|
13625
|
+
result.success = result.checks.external === "passed" && result.checks.frameTiming === "passed";
|
|
13626
|
+
return result;
|
|
13627
|
+
}
|
|
13628
|
+
var CLAIM_REVIEW_EVALUATION_SCHEMA_ID = "urn:disclosureos:experimental:claim-review-evaluation:0.1.0";
|
|
13629
|
+
var CLAIM_REVIEW_RECEIPT_SCHEMA_ID = "urn:disclosureos:experimental:claim-review-receipt:0.1.0";
|
|
13630
|
+
var CLAIM_REVIEW_EVALUATION_POLICY = Object.freeze({
|
|
13631
|
+
id: "urn:disclosureos:experimental:policy:claim-review-evaluation",
|
|
13632
|
+
version: "0.1.0",
|
|
13633
|
+
scope: "declared_claims_documentary_support_and_snapshot_identity"
|
|
13634
|
+
});
|
|
13635
|
+
var digest11 = z.string().regex(/^[a-f0-9]{64}(?![\s\S])/);
|
|
13636
|
+
var pin4 = z.strictObject({ sha256: digest11, byteLength: z.number().int().positive().max(Number.MAX_SAFE_INTEGER) });
|
|
13637
|
+
var ClaimReviewEvaluationSchema = z.strictObject({
|
|
13638
|
+
kind: z.literal("claim_review_evaluation"),
|
|
13639
|
+
schemaVersion: z.literal("0.1.0"),
|
|
13640
|
+
id: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._-]*(?![\s\S])/),
|
|
13641
|
+
review: z.strictObject({
|
|
13642
|
+
documentId: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._-]*(?![\s\S])/),
|
|
13643
|
+
schemaId: z.enum([OBSERVATION_CLAIM_HISTORY_SCHEMA_ID, CASE_CLAIM_HISTORY_V02_SCHEMA_ID]),
|
|
13644
|
+
sha256: digest11
|
|
13645
|
+
})
|
|
13646
|
+
});
|
|
13647
|
+
var ClaimReviewReceiptSchema = z.strictObject({
|
|
13648
|
+
kind: z.literal("claim_review_receipt"),
|
|
13649
|
+
schemaVersion: z.literal("0.1.0"),
|
|
13650
|
+
policy: z.strictObject({ id: z.literal(CLAIM_REVIEW_EVALUATION_POLICY.id), version: z.literal("0.1.0"), scope: z.literal(CLAIM_REVIEW_EVALUATION_POLICY.scope) }),
|
|
13651
|
+
serialization: z.literal("sorted-json-utf8:0.1.0"),
|
|
13652
|
+
input: pin4,
|
|
13653
|
+
output: pin4,
|
|
13654
|
+
inputJson: z.string().min(1),
|
|
13655
|
+
outputJson: z.string().min(1)
|
|
13656
|
+
});
|
|
13657
|
+
function claimReviewEvaluationJsonSchema() {
|
|
13658
|
+
return { ...preservePublishedSchema(z.toJSONSchema(ClaimReviewEvaluationSchema, { target: "draft-2020-12" })), $id: CLAIM_REVIEW_EVALUATION_SCHEMA_ID };
|
|
13659
|
+
}
|
|
13660
|
+
function claimReviewReceiptJsonSchema() {
|
|
13661
|
+
return { ...preservePublishedSchema(z.toJSONSchema(ClaimReviewReceiptSchema, { target: "draft-2020-12" })), $id: CLAIM_REVIEW_RECEIPT_SCHEMA_ID };
|
|
13662
|
+
}
|
|
13663
|
+
var bytes5 = (s) => new TextEncoder().encode(s);
|
|
13664
|
+
var hash7 = async (b) => [...new Uint8Array(await crypto.subtle.digest("SHA-256", Uint8Array.from(b)))].map((n) => n.toString(16).padStart(2, "0")).join("");
|
|
13665
|
+
function canonical(v) {
|
|
13666
|
+
if (Array.isArray(v)) return "[" + v.map(canonical).join(",") + "]";
|
|
13667
|
+
if (v && typeof v === "object") return "{" + Object.entries(v).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([k, x]) => JSON.stringify(k) + ":" + canonical(x)).join(",") + "}";
|
|
13668
|
+
const value = JSON.stringify(v);
|
|
13669
|
+
if (value === void 0) throw new Error("Receipt contains a non-JSON value.");
|
|
13670
|
+
return value;
|
|
13671
|
+
}
|
|
13672
|
+
var copy = (map) => new Map([...map ?? []].map(([k, v]) => [k, Uint8Array.from(v)]));
|
|
13673
|
+
async function evaluateClaimReview(input, options = {}) {
|
|
13674
|
+
const parsed = ClaimReviewEvaluationSchema.safeParse(input);
|
|
13675
|
+
const result = {
|
|
13676
|
+
success: false,
|
|
13677
|
+
checks: { structural: parsed.success ? "passed" : "failed", external: "not_checked", evaluation: "not_checked" },
|
|
13678
|
+
issues: [],
|
|
13679
|
+
output: null,
|
|
13680
|
+
receipt: null,
|
|
13681
|
+
scientificEligibility: "not_checked",
|
|
13682
|
+
processingChronology: "not_checked",
|
|
13683
|
+
publicationPolicy: "not_checked"
|
|
13684
|
+
};
|
|
13685
|
+
if (!parsed.success) {
|
|
13686
|
+
result.issues = parsed.error.issues.map((i) => ({ code: "STRUCT.VALUE", pointer: "/" + i.path.join("/"), message: i.message }));
|
|
13687
|
+
return result;
|
|
13688
|
+
}
|
|
13689
|
+
const reviewBytes = options.reviewBytes ? Uint8Array.from(options.reviewBytes) : void 0;
|
|
13690
|
+
const documents = copy(options.documents), assets2 = copy(options.assets), request = parsed.data;
|
|
13691
|
+
const fail = (code, message2) => {
|
|
13692
|
+
result.checks.external = "failed";
|
|
13693
|
+
result.issues.push({ code, pointer: "/review", message: message2 });
|
|
13694
|
+
return result;
|
|
13695
|
+
};
|
|
13696
|
+
if (!reviewBytes) return fail("SNAPSHOT.UNAVAILABLE", "Supply the exact review snapshot bytes.");
|
|
13697
|
+
if (await hash7(reviewBytes) !== request.review.sha256) return fail("SNAPSHOT.DIGEST", "Review bytes differ from the declared digest.");
|
|
13698
|
+
let raw;
|
|
13699
|
+
try {
|
|
13700
|
+
raw = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(reviewBytes));
|
|
13701
|
+
} catch {
|
|
13702
|
+
return fail("SNAPSHOT.JSON", "Review must be a UTF-8 JSON document.");
|
|
13703
|
+
}
|
|
13704
|
+
const review2 = request.review.schemaId === OBSERVATION_CLAIM_HISTORY_SCHEMA_ID ? parseObservationClaimHistory(raw) : parseCaseClaimHistoryV02(raw);
|
|
13705
|
+
if (!review2.success) return fail("SNAPSHOT.CONTRACT", "Review does not satisfy its pinned contract and local semantics.");
|
|
13706
|
+
if (review2.data.id !== request.review.documentId) return fail("SNAPSHOT.IDENTITY", "Review ID differs from the snapshot reference.");
|
|
13707
|
+
result.checks.external = "passed";
|
|
13708
|
+
result.output = request.review.schemaId === OBSERVATION_CLAIM_HISTORY_SCHEMA_ID ? await evaluateObservationClaimDocumentation(raw, { assets: assets2 }) : await evaluateCaseClaimHistoryV02(raw, { documents });
|
|
13709
|
+
result.checks.evaluation = result.output.success ? "passed" : "failed";
|
|
13710
|
+
result.success = result.output.success;
|
|
13711
|
+
const inventory = async (map) => Promise.all([...map].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(async ([ref18, value]) => ({ ref: ref18, sha256: await hash7(value), byteLength: value.length })));
|
|
13712
|
+
const inputJson = canonical({ request, review: { sha256: request.review.sha256, byteLength: reviewBytes.length }, documents: await inventory(documents), assets: await inventory(assets2) });
|
|
13713
|
+
const outputJson = canonical({ policy: CLAIM_REVIEW_EVALUATION_POLICY, output: result.output, scientificEligibility: result.scientificEligibility, processingChronology: result.processingChronology, publicationPolicy: result.publicationPolicy });
|
|
13714
|
+
result.receipt = {
|
|
13715
|
+
kind: "claim_review_receipt",
|
|
13716
|
+
schemaVersion: "0.1.0",
|
|
13717
|
+
policy: CLAIM_REVIEW_EVALUATION_POLICY,
|
|
13718
|
+
serialization: "sorted-json-utf8:0.1.0",
|
|
13719
|
+
input: { sha256: await hash7(bytes5(inputJson)), byteLength: bytes5(inputJson).length },
|
|
13720
|
+
output: { sha256: await hash7(bytes5(outputJson)), byteLength: bytes5(outputJson).length },
|
|
13721
|
+
inputJson,
|
|
13722
|
+
outputJson
|
|
13723
|
+
};
|
|
13724
|
+
return result;
|
|
13725
|
+
}
|
|
13726
|
+
async function verifyClaimReviewReceipt(input) {
|
|
13727
|
+
const p = ClaimReviewReceiptSchema.safeParse(input);
|
|
13728
|
+
if (!p.success) return false;
|
|
13729
|
+
const r = p.data;
|
|
13730
|
+
try {
|
|
13731
|
+
const output = JSON.parse(r.outputJson);
|
|
13732
|
+
if (canonical(JSON.parse(r.inputJson)) !== r.inputJson || canonical(output) !== r.outputJson || canonical(output.policy) !== canonical(r.policy)) return false;
|
|
13733
|
+
} catch {
|
|
13734
|
+
return false;
|
|
13735
|
+
}
|
|
13736
|
+
return r.input.byteLength === bytes5(r.inputJson).length && r.output.byteLength === bytes5(r.outputJson).length && r.input.sha256 === await hash7(bytes5(r.inputJson)) && r.output.sha256 === await hash7(bytes5(r.outputJson));
|
|
13737
|
+
}
|
|
13066
13738
|
|
|
13067
|
-
export { ACQUISITION_BINDINGS_PROFILE, ACQUISITION_BINDINGS_SCHEMA_ID, ARCHIVAL_CASE_PRESENTATION_SCHEMA_ID, ASSESSMENT_DOCUMENTATION_PROFILE, AcquisitionBindingsSchema, ArchivalCasePresentationSchema, CASE_PRESENTATION_SCHEMA_ID, CONTEXT_CASE_PRESENTATION_SCHEMA_ID, CONTEXT_MEASUREMENT_ROLES, CasePresentationSchema, ContextCasePresentationSchema, DATASET_RELEASE_PROFILE, DATASET_RELEASE_SCHEMA_ID, DOCUMENTATION_COMPLETION_POLICY, DOCUMENTATION_REQUIREMENTS, DatasetReleaseSchema, HISTORICAL_TESTIMONY_PROFILE, HISTORICAL_TESTIMONY_REQUIREMENTS, HISTORICAL_TESTIMONY_SELECTION_SCHEMA_ID, HistoricalTestimonySelectionSchema, INSTRUMENT_RESEARCH_COMPLETION_POLICY, INSTRUMENT_RESEARCH_PREREQUISITES_PROFILE, INSTRUMENT_RESEARCH_REQUIREMENTS, INSTRUMENT_RESEARCH_REVIEW_SCHEMA_ID, InstrumentResearchReviewSchema, LIDAR_POINT_COLUMNS, LIDAR_PROFILE, LIDAR_PROFILE_SCHEMA_ID, LIDAR_PULSE_COLUMNS, LidarProfileSchema, MATERIAL_CASE_PRESENTATION_SCHEMA_ID, MEASUREMENT_BINDINGS_PROFILE, MEASUREMENT_BINDINGS_SCHEMA_ID, MIGRATION_COMPATIBILITY_SCHEMA_ID, MIGRATION_LEGACY_SCORES_SCHEMA_ID, MIGRATION_RESOLUTION_SCHEMA_ID, MIGRATION_REVIEW_SCHEMA_ID, MaterialCasePresentationSchema, MeasurementBindingsSchema, MigrationCompatibilitySchema, MigrationLegacyScoresSchema, MigrationResolutionSchema, MigrationReviewSchema, PASSIVE_SONAR_PROFILE, PASSIVE_SONAR_PROFILE_SCHEMA_ID, PHYSICAL_SAMPLE_PROFILE, PHYSICAL_SAMPLE_REQUIREMENTS, PHYSICAL_SAMPLE_SELECTION_SCHEMA_ID, PRODUCT_SOURCE_SELECTION_PROFILE, PRODUCT_SOURCE_SELECTION_SCHEMA_ID, PROFILE_EVALUATION_POLICY, PROFILE_EVALUATION_SCHEMA_ID, PROFILE_PREPARATION_SCHEMA_ID, PassiveSonarProfileSchema, PhysicalSampleSelectionSchema, ProductSourceLayoutSchema, ProductSourceSelectionSchema, ProductSourceSelectorSchema, ProfileEvaluationSchema, ProfilePreparationSchema, RADAR_PROFILE, RADAR_PROFILE_SCHEMA_ID, RADAR_TABLE_COLUMNS, RELEASED_DOCUMENT_PROFILE, RELEASED_DOCUMENT_REQUIREMENTS, RELEASED_DOCUMENT_SELECTION_SCHEMA_ID, REPRODUCTION_PACKET_PROFILE, REPRODUCTION_PACKET_SCHEMA_ID, RESEARCH_EVALUATION_POLICY, RESEARCH_EVALUATION_SCHEMA_ID, RadarProfileSchema, ReleasedDocumentSelectionSchema, ReproductionPacketSchema, ResearchEvaluationSchema, SATELLITE_RASTER_PROFILE, SATELLITE_RASTER_PROFILE_SCHEMA_ID, SECONDARY_RADAR_PROFILE, SECONDARY_RADAR_PROFILE_SCHEMA_ID, SECONDARY_RADAR_TABLE_COLUMNS, SONAR_PROFILE, SONAR_PROFILE_SCHEMA_ID, SOURCE_INTAKE_PROFILE, SOURCE_INTAKE_SCHEMA_ID, STEERED_RADAR_PROFILE, STEERED_RADAR_PROFILE_SCHEMA_ID, STEERED_RADAR_TABLE_COLUMNS, SatelliteRasterProfileSchema, SecondaryRadarProfileSchema, SonarProfileSchema, SourceIntakeSchema, SteeredRadarProfileSchema, TESTIMONY_CASE_PRESENTATION_SCHEMA_ID, TestimonyCasePresentationSchema, VOCABULARY_BINDINGS_PROFILE, acquisitionBindingsJsonSchema, archivalCasePresentationJsonSchema, buildPublicArchivalCase, buildPublicArchivalCaseOutputs, buildPublicCase, buildPublicCaseOutputs, buildPublicContextCase, buildPublicContextCaseOutputs, buildPublicMaterialCase, buildPublicMaterialCaseOutputs, buildPublicTestimonyCase, buildPublicTestimonyCaseOutputs, casePresentationJsonSchema, computePassiveSonarSpectrum, contextCasePresentationJsonSchema, datasetReleaseJsonSchema, evaluateAcquisitionBindings, evaluateArchivalClaimHistory, evaluateAssessmentDocumentation, evaluateCaseClaimHistory, evaluateCaseLinks, evaluateCaseRecord, evaluateContextClaimHistory, evaluateDatasetRelease, evaluateDocumentationCompletion, evaluateHistoricalTestimony, evaluateInstrumentResearchCompletion, evaluateInstrumentResearchPrerequisites, evaluateLaboratoryClaimHistory, evaluateLidarProfile, evaluateMeasurementBindings, evaluatePassiveSonarProfile, evaluatePhysicalSamples, evaluateProductSourceSelection, evaluateProfileEvaluation, evaluateRadarProfile, evaluateReleasedDocuments, evaluateReproductionPacket, evaluateResearchClaimHistory, evaluateResearchEvaluation, evaluateSatelliteRasterProfile, evaluateSecondaryRadarProfile, evaluateSonarProfile, evaluateSourceIntake, evaluateSteeredRadarProfile, evaluateVocabularyBindings, formatPublicCaseOutputs, historicalTestimonySelectionJsonSchema, instrumentResearchReviewJsonSchema, lidarProfileJsonSchema, materialCasePresentationJsonSchema, measurementBindingsJsonSchema, migrationCompatibilityJsonSchema, migrationLegacyScoresJsonSchema, migrationResolutionJsonSchema, migrationReviewJsonSchema, parseArchivalCasePresentation, parseCasePresentation, parseContextCasePresentation, parseMaterialCasePresentation, parseTestimonyCasePresentation, passiveSonarBin, passiveSonarDensityDb, passiveSonarDimensions, passiveSonarProfileJsonSchema, passiveSonarSample, physicalSampleSelectionJsonSchema, productSourceSelectionJsonSchema, profileEvaluationJsonSchema, profilePreparationJsonSchema, radarCellPosition, radarCovarianceScaleSquared, radarProfileJsonSchema, readLidarProducts, readPassiveSonarBin, readPassiveSonarProducts, readPassiveSonarSample, readProductSourceSelection, readRadarProducts, readSatelliteRasterProducts, readSecondaryRadarProducts, readSonarProducts, readSonarSample, readSourceCsv, readSteeredRadarProducts, releasedDocumentSelectionJsonSchema, reproductionPacketJsonSchema, researchEvaluationJsonSchema, satelliteCellBounds, satelliteRasterProfileJsonSchema, secondaryRadarProfileJsonSchema, sonarDistance, sonarProfileJsonSchema, sonarSample, sourceElementBytes, sourceIntakeJsonSchema, steeredRadarProfileJsonSchema, testimonyCasePresentationJsonSchema, validateLidarDeclaration, validatePassiveSonarDeclaration, validateSatelliteRasterDeclaration, validateSonarDeclaration };
|
|
13739
|
+
export { ACQUISITION_BINDINGS_PROFILE, ACQUISITION_BINDINGS_SCHEMA_ID, ARCHIVAL_CASE_PRESENTATION_SCHEMA_ID, ASSESSMENT_DOCUMENTATION_PROFILE, AcquisitionBindingsSchema, ArchivalCasePresentationSchema, CASE_PRESENTATION_SCHEMA_ID, CLAIM_REVIEW_EVALUATION_POLICY, CLAIM_REVIEW_EVALUATION_SCHEMA_ID, CLAIM_REVIEW_RECEIPT_SCHEMA_ID, CONTEXT_CASE_PRESENTATION_SCHEMA_ID, CONTEXT_MEASUREMENT_ROLES, CasePresentationSchema, ClaimReviewEvaluationSchema, ClaimReviewReceiptSchema, ContextCasePresentationSchema, DATASET_RELEASE_PROFILE, DATASET_RELEASE_SCHEMA_ID, DOCUMENTATION_COMPLETION_POLICY, DOCUMENTATION_REQUIREMENTS, DatasetReleaseSchema, HISTORICAL_TESTIMONY_PROFILE, HISTORICAL_TESTIMONY_REQUIREMENTS, HISTORICAL_TESTIMONY_SELECTION_SCHEMA_ID, HistoricalTestimonySelectionSchema, INSTRUMENT_RESEARCH_COMPLETION_POLICY, INSTRUMENT_RESEARCH_PREREQUISITES_PROFILE, INSTRUMENT_RESEARCH_REQUIREMENTS, INSTRUMENT_RESEARCH_REVIEW_SCHEMA_ID, InstrumentResearchReviewSchema, LIDAR_POINT_COLUMNS, LIDAR_PROFILE, LIDAR_PROFILE_SCHEMA_ID, LIDAR_PULSE_COLUMNS, LidarProfileSchema, MATERIAL_CASE_PRESENTATION_SCHEMA_ID, MCAP_SOURCE_MAPPING_SCHEMA_ID, MEASUREMENT_BINDINGS_PROFILE, MEASUREMENT_BINDINGS_SCHEMA_ID, MIGRATION_COMPATIBILITY_SCHEMA_ID, MIGRATION_LEGACY_SCORES_SCHEMA_ID, MIGRATION_RESOLUTION_SCHEMA_ID, MIGRATION_REVIEW_SCHEMA_ID, MaterialCasePresentationSchema, McapSourceMappingSchema, MeasurementBindingsSchema, MigrationCompatibilitySchema, MigrationLegacyScoresSchema, MigrationResolutionSchema, MigrationReviewSchema, OBSERVATION_CLAIM_DOCUMENTATION_PROFILE, PASSIVE_SONAR_PROFILE, PASSIVE_SONAR_PROFILE_SCHEMA_ID, PHYSICAL_SAMPLE_PROFILE, PHYSICAL_SAMPLE_REQUIREMENTS, PHYSICAL_SAMPLE_SELECTION_SCHEMA_ID, PRODUCT_SOURCE_SELECTION_PROFILE, PRODUCT_SOURCE_SELECTION_SCHEMA_ID, PROFILE_EVALUATION_POLICY, PROFILE_EVALUATION_SCHEMA_ID, PROFILE_PREPARATION_SCHEMA_ID, PassiveSonarProfileSchema, PhysicalSampleSelectionSchema, ProductSourceLayoutSchema, ProductSourceSelectionSchema, ProductSourceSelectorSchema, ProfileEvaluationSchema, ProfilePreparationSchema, RADAR_PROFILE, RADAR_PROFILE_SCHEMA_ID, RADAR_TABLE_COLUMNS, RELEASED_DOCUMENT_PROFILE, RELEASED_DOCUMENT_REQUIREMENTS, RELEASED_DOCUMENT_SELECTION_SCHEMA_ID, REPRODUCTION_PACKET_PROFILE, REPRODUCTION_PACKET_SCHEMA_ID, RESEARCH_EVALUATION_POLICY, RESEARCH_EVALUATION_SCHEMA_ID, RadarProfileSchema, ReleasedDocumentSelectionSchema, ReproductionPacketSchema, ResearchEvaluationSchema, SATELLITE_RASTER_PROFILE, SATELLITE_RASTER_PROFILE_SCHEMA_ID, SECONDARY_RADAR_PROFILE, SECONDARY_RADAR_PROFILE_SCHEMA_ID, SECONDARY_RADAR_TABLE_COLUMNS, SONAR_PROFILE, SONAR_PROFILE_SCHEMA_ID, SOURCE_INTAKE_PROFILE, SOURCE_INTAKE_SCHEMA_ID, STEERED_RADAR_PROFILE, STEERED_RADAR_PROFILE_SCHEMA_ID, STEERED_RADAR_TABLE_COLUMNS, SatelliteRasterProfileSchema, SecondaryRadarProfileSchema, SonarProfileSchema, SourceIntakeSchema, SteeredRadarProfileSchema, TESTIMONY_CASE_PRESENTATION_SCHEMA_ID, TestimonyCasePresentationSchema, VIDEO_FRAME_SOURCE_MAPPING_SCHEMA_ID, VOCABULARY_BINDINGS_PROFILE, VideoFrameSourceMappingSchema, acquisitionBindingsJsonSchema, archivalCasePresentationJsonSchema, buildPublicArchivalCase, buildPublicArchivalCaseOutputs, buildPublicCase, buildPublicCaseOutputs, buildPublicContextCase, buildPublicContextCaseOutputs, buildPublicMaterialCase, buildPublicMaterialCaseOutputs, buildPublicTestimonyCase, buildPublicTestimonyCaseOutputs, casePresentationJsonSchema, claimReviewEvaluationJsonSchema, claimReviewReceiptJsonSchema, computePassiveSonarSpectrum, contextCasePresentationJsonSchema, datasetReleaseJsonSchema, evaluateAcquisitionBindings, evaluateArchivalClaimHistory, evaluateAssessmentDocumentation, evaluateCaseClaimHistory, evaluateCaseClaimHistoryV02, evaluateCaseLinks, evaluateCaseRecord, evaluateCaseRecordV02, evaluateClaimReview, evaluateContextClaimHistory, evaluateDatasetRelease, evaluateDocumentationCompletion, evaluateHistoricalTestimony, evaluateInstrumentResearchCompletion, evaluateInstrumentResearchPrerequisites, evaluateLaboratoryClaimHistory, evaluateLidarProfile, evaluateMcapSourceMapping, evaluateMeasurementBindings, evaluateObservationClaimDocumentation, evaluatePassiveSonarProfile, evaluatePhysicalSamples, evaluateProductSourceSelection, evaluateProfileEvaluation, evaluateRadarProfile, evaluateReleasedDocuments, evaluateReproductionPacket, evaluateResearchClaimHistory, evaluateResearchEvaluation, evaluateSatelliteRasterProfile, evaluateSecondaryRadarProfile, evaluateSonarProfile, evaluateSourceIntake, evaluateSteeredRadarProfile, evaluateVideoFrameSourceMapping, evaluateVocabularyBindings, formatPublicCaseOutputs, historicalTestimonySelectionJsonSchema, instrumentResearchReviewJsonSchema, lidarProfileJsonSchema, materialCasePresentationJsonSchema, mcapSourceMappingJsonSchema, measurementBindingsJsonSchema, migrationCompatibilityJsonSchema, migrationLegacyScoresJsonSchema, migrationResolutionJsonSchema, migrationReviewJsonSchema, parseArchivalCasePresentation, parseCasePresentation, parseContextCasePresentation, parseMaterialCasePresentation, parseTestimonyCasePresentation, passiveSonarBin, passiveSonarDensityDb, passiveSonarDimensions, passiveSonarProfileJsonSchema, passiveSonarSample, physicalSampleSelectionJsonSchema, productSourceSelectionJsonSchema, profileEvaluationJsonSchema, profilePreparationJsonSchema, radarCellPosition, radarCovarianceScaleSquared, radarProfileJsonSchema, readLidarProducts, readPassiveSonarBin, readPassiveSonarProducts, readPassiveSonarSample, readProductSourceSelection, readRadarProducts, readSatelliteRasterProducts, readSecondaryRadarProducts, readSonarProducts, readSonarSample, readSourceCsv, readSteeredRadarProducts, readVideoFrameReference, releasedDocumentSelectionJsonSchema, reproductionPacketJsonSchema, researchEvaluationJsonSchema, satelliteCellBounds, satelliteRasterProfileJsonSchema, secondaryRadarProfileJsonSchema, sonarDistance, sonarProfileJsonSchema, sonarSample, sourceElementBytes, sourceIntakeJsonSchema, steeredRadarProfileJsonSchema, testimonyCasePresentationJsonSchema, validateLidarDeclaration, validatePassiveSonarDeclaration, validateSatelliteRasterDeclaration, validateSonarDeclaration, verifyClaimReviewReceipt, videoFrameSourceMappingJsonSchema };
|
|
13068
13740
|
//# sourceMappingURL=index.js.map
|
|
13069
13741
|
//# sourceMappingURL=index.js.map
|