@primmel/primmel 1.8.2 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -2
- package/dist/index.js.map +1 -1
- package/dist/src/check-rules.d.ts.map +1 -1
- package/dist/src/check-rules.js +55 -0
- package/dist/src/check-rules.js.map +1 -1
- package/dist/src/check.d.ts +74 -2
- package/dist/src/check.d.ts.map +1 -1
- package/dist/src/check.js +514 -15
- package/dist/src/check.js.map +1 -1
- package/dist/src/export/impact.d.ts +45 -0
- package/dist/src/export/impact.d.ts.map +1 -0
- package/dist/src/export/impact.js +234 -0
- package/dist/src/export/impact.js.map +1 -0
- package/dist/src/export/rdf.d.ts.map +1 -1
- package/dist/src/export/rdf.js +4 -1
- package/dist/src/export/rdf.js.map +1 -1
- package/dist/src/export/retrieval.d.ts +408 -0
- package/dist/src/export/retrieval.d.ts.map +1 -0
- package/dist/src/export/retrieval.js +1156 -0
- package/dist/src/export/retrieval.js.map +1 -0
- package/dist/src/model-diff.d.ts +23 -0
- package/dist/src/model-diff.d.ts.map +1 -1
- package/dist/src/model-diff.js +132 -30
- package/dist/src/model-diff.js.map +1 -1
- package/dist/src/ser-des/config/calculation.d.ts.map +1 -1
- package/dist/src/ser-des/config/calculation.js +119 -4
- package/dist/src/ser-des/config/calculation.js.map +1 -1
- package/dist/src/ser-des/config/dimension.d.ts +12 -0
- package/dist/src/ser-des/config/dimension.d.ts.map +1 -0
- package/dist/src/ser-des/config/dimension.js +57 -0
- package/dist/src/ser-des/config/dimension.js.map +1 -0
- package/dist/src/ser-des/config/index.d.ts.map +1 -1
- package/dist/src/ser-des/config/index.js +5 -0
- package/dist/src/ser-des/config/index.js.map +1 -1
- package/dist/src/ser-des/config/packageManifest.d.ts.map +1 -1
- package/dist/src/ser-des/config/packageManifest.js +7 -1
- package/dist/src/ser-des/config/packageManifest.js.map +1 -1
- package/dist/src/ser-des/config/quantityRegister.d.ts.map +1 -1
- package/dist/src/ser-des/config/quantityRegister.js +38 -0
- package/dist/src/ser-des/config/quantityRegister.js.map +1 -1
- package/dist/src/ser-des/config/reference.d.ts.map +1 -1
- package/dist/src/ser-des/config/reference.js +18 -0
- package/dist/src/ser-des/config/reference.js.map +1 -1
- package/dist/src/ser-des/config/requirement.d.ts.map +1 -1
- package/dist/src/ser-des/config/requirement.js +43 -0
- package/dist/src/ser-des/config/requirement.js.map +1 -1
- package/dist/src/ser-des/config/subject.d.ts +10 -1
- package/dist/src/ser-des/config/subject.d.ts.map +1 -1
- package/dist/src/ser-des/config/subject.js +96 -63
- package/dist/src/ser-des/config/subject.js.map +1 -1
- package/dist/src/ser-des/config/term.d.ts.map +1 -1
- package/dist/src/ser-des/config/term.js +82 -20
- package/dist/src/ser-des/config/term.js.map +1 -1
- package/dist/src/ser-des/parse-block.d.ts +1 -0
- package/dist/src/ser-des/parse-block.d.ts.map +1 -1
- package/dist/src/ser-des/parse-block.js +34 -0
- package/dist/src/ser-des/parse-block.js.map +1 -1
- package/dist/src/ser-des/parse.d.ts.map +1 -1
- package/dist/src/ser-des/parse.js +2 -0
- package/dist/src/ser-des/parse.js.map +1 -1
- package/dist/src/ser-des/types.d.ts +2 -1
- package/dist/src/ser-des/types.d.ts.map +1 -1
- package/dist/src/types/Calculation.d.ts +15 -0
- package/dist/src/types/Calculation.d.ts.map +1 -1
- package/dist/src/types/Package.d.ts +8 -0
- package/dist/src/types/Package.d.ts.map +1 -1
- package/dist/src/types/Quantity.d.ts +7 -0
- package/dist/src/types/Quantity.d.ts.map +1 -1
- package/dist/src/types/Reference.d.ts +11 -0
- package/dist/src/types/Reference.d.ts.map +1 -1
- package/dist/src/types/Requirement.d.ts +17 -0
- package/dist/src/types/Requirement.d.ts.map +1 -1
- package/dist/src/types/Standard.d.ts +2 -1
- package/dist/src/types/Standard.d.ts.map +1 -1
- package/dist/src/types/Subject.d.ts +10 -0
- package/dist/src/types/Subject.d.ts.map +1 -1
- package/dist/src/types/Term.d.ts +33 -1
- package/dist/src/types/Term.d.ts.map +1 -1
- package/dist-browser/index.mjs +1647 -1459
- package/dist-cli/primmel.mjs +2118 -166
- package/package.json +1 -1
package/dist-cli/primmel.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// scripts/check.mts
|
|
4
|
-
import { existsSync as existsSync7, readdirSync as
|
|
5
|
-
import { join as
|
|
4
|
+
import { existsSync as existsSync7, readdirSync as readdirSync6, statSync as statSync4, writeFileSync } from "node:fs";
|
|
5
|
+
import { join as join7 } from "node:path";
|
|
6
6
|
|
|
7
7
|
// src/check.ts
|
|
8
8
|
import { existsSync as existsSync5, readdirSync as readdirSync3, readFileSync as readFileSync5, statSync as statSync2 } from "fs";
|
|
@@ -266,6 +266,8 @@ function parse(mmelString, parsers, options = {}) {
|
|
|
266
266
|
// Primmel v3.1 dataspace + trust (TODO.primmel/10)
|
|
267
267
|
dataspaces: {},
|
|
268
268
|
policies: {},
|
|
269
|
+
// Primmel v3.2 consumption constructs (TODO.primmel/11)
|
|
270
|
+
dimensions: {},
|
|
269
271
|
// Issue collection (duplicate IDs, etc.)
|
|
270
272
|
issues: []
|
|
271
273
|
};
|
|
@@ -401,6 +403,16 @@ function resolve(ctx, resolvers) {
|
|
|
401
403
|
}
|
|
402
404
|
|
|
403
405
|
// src/ser-des/parse-block.ts
|
|
406
|
+
var ALIAS_FAMILY_KEYWORDS = /* @__PURE__ */ new Set([
|
|
407
|
+
"aliases",
|
|
408
|
+
"alt",
|
|
409
|
+
"colloquial",
|
|
410
|
+
"abbreviations",
|
|
411
|
+
"deprecated"
|
|
412
|
+
]);
|
|
413
|
+
function isAliasFamilyKeyword(keyword) {
|
|
414
|
+
return ALIAS_FAMILY_KEYWORDS.has(keyword);
|
|
415
|
+
}
|
|
404
416
|
function forEachEntry(data, visitor, errCtx) {
|
|
405
417
|
if (data === "") {
|
|
406
418
|
return;
|
|
@@ -432,6 +444,11 @@ function forEachEntry(data, visitor, errCtx) {
|
|
|
432
444
|
i++;
|
|
433
445
|
i++;
|
|
434
446
|
}
|
|
447
|
+
} else if (isAliasFamilyKeyword(keyword)) {
|
|
448
|
+
i++;
|
|
449
|
+
if (!t[i - 1].startsWith("{") && t[i]?.startsWith("{")) {
|
|
450
|
+
i++;
|
|
451
|
+
}
|
|
435
452
|
} else {
|
|
436
453
|
i++;
|
|
437
454
|
}
|
|
@@ -461,6 +478,15 @@ function skipUnknownValue(t, i, keyword) {
|
|
|
461
478
|
}
|
|
462
479
|
return i;
|
|
463
480
|
}
|
|
481
|
+
if (isAliasFamilyKeyword(keyword)) {
|
|
482
|
+
if (i < t.length) {
|
|
483
|
+
i++;
|
|
484
|
+
}
|
|
485
|
+
if (!t[i - 1]?.startsWith("{") && t[i]?.startsWith("{")) {
|
|
486
|
+
i++;
|
|
487
|
+
}
|
|
488
|
+
return i;
|
|
489
|
+
}
|
|
464
490
|
if (i < t.length) {
|
|
465
491
|
i++;
|
|
466
492
|
}
|
|
@@ -3224,6 +3250,12 @@ var parseReference = (id, data) => {
|
|
|
3224
3250
|
ref.clause = unwrapBlock(t[i++]);
|
|
3225
3251
|
} else if (keyword === "title") {
|
|
3226
3252
|
ref.title = unwrapBlock(t[i++]);
|
|
3253
|
+
} else if (keyword === "org") {
|
|
3254
|
+
ref.org = unwrapBlock(t[i++]);
|
|
3255
|
+
} else if (keyword === "edition") {
|
|
3256
|
+
ref.edition = unwrapBlock(t[i++]);
|
|
3257
|
+
} else if (keyword === "urn") {
|
|
3258
|
+
ref.urn = unwrapBlock(t[i++]);
|
|
3227
3259
|
} else {
|
|
3228
3260
|
i++;
|
|
3229
3261
|
}
|
|
@@ -3246,6 +3278,15 @@ var dumpReference = function(ref) {
|
|
|
3246
3278
|
if (ref.title) {
|
|
3247
3279
|
out += ' title "' + escapeString(ref.title) + '"\n';
|
|
3248
3280
|
}
|
|
3281
|
+
if (ref.org) {
|
|
3282
|
+
out += ' org "' + escapeString(ref.org) + '"\n';
|
|
3283
|
+
}
|
|
3284
|
+
if (ref.edition) {
|
|
3285
|
+
out += ' edition "' + escapeString(ref.edition) + '"\n';
|
|
3286
|
+
}
|
|
3287
|
+
if (ref.urn) {
|
|
3288
|
+
out += ' urn "' + escapeString(ref.urn) + '"\n';
|
|
3289
|
+
}
|
|
3249
3290
|
out += "}\n";
|
|
3250
3291
|
return out;
|
|
3251
3292
|
};
|
|
@@ -5352,6 +5393,10 @@ function parseInputs(block) {
|
|
|
5352
5393
|
let defaultValue = "";
|
|
5353
5394
|
let hasDefault = false;
|
|
5354
5395
|
let enumValues;
|
|
5396
|
+
let quantityKind;
|
|
5397
|
+
let rangeMin;
|
|
5398
|
+
let rangeMax;
|
|
5399
|
+
let hasRange = false;
|
|
5355
5400
|
if (i < t.length && t[i].startsWith("{")) {
|
|
5356
5401
|
const propBlock = unwrapBlock(t[i++]);
|
|
5357
5402
|
const pt = tokenizePackage(propBlock);
|
|
@@ -5360,7 +5405,27 @@ function parseInputs(block) {
|
|
|
5360
5405
|
const cmd = pt[j++];
|
|
5361
5406
|
if (j < pt.length) {
|
|
5362
5407
|
if (cmd === "unit") {
|
|
5363
|
-
unit =
|
|
5408
|
+
unit = stripWrapping(pt[j++]);
|
|
5409
|
+
} else if (cmd === "quantity_kind") {
|
|
5410
|
+
quantityKind = stripWrapping(pt[j++]);
|
|
5411
|
+
} else if (cmd === "range") {
|
|
5412
|
+
const rt = tokenizePackage(unwrapBlock(pt[j++]));
|
|
5413
|
+
let k = 0;
|
|
5414
|
+
while (k < rt.length) {
|
|
5415
|
+
const rc = rt[k++];
|
|
5416
|
+
if (k >= rt.length) {
|
|
5417
|
+
break;
|
|
5418
|
+
}
|
|
5419
|
+
if (rc === "min") {
|
|
5420
|
+
rangeMin = stripWrapping(rt[k++]);
|
|
5421
|
+
hasRange = true;
|
|
5422
|
+
} else if (rc === "max") {
|
|
5423
|
+
rangeMax = stripWrapping(rt[k++]);
|
|
5424
|
+
hasRange = true;
|
|
5425
|
+
} else {
|
|
5426
|
+
unwrapBlock(rt[k++]);
|
|
5427
|
+
}
|
|
5428
|
+
}
|
|
5364
5429
|
} else if (cmd === "description") {
|
|
5365
5430
|
description = unwrapBlock(pt[j++]);
|
|
5366
5431
|
} else if (cmd === "default") {
|
|
@@ -5374,7 +5439,7 @@ function parseInputs(block) {
|
|
|
5374
5439
|
}
|
|
5375
5440
|
}
|
|
5376
5441
|
}
|
|
5377
|
-
|
|
5442
|
+
const inp = {
|
|
5378
5443
|
name,
|
|
5379
5444
|
type,
|
|
5380
5445
|
unit,
|
|
@@ -5382,7 +5447,20 @@ function parseInputs(block) {
|
|
|
5382
5447
|
defaultValue,
|
|
5383
5448
|
hasDefault,
|
|
5384
5449
|
enumValues
|
|
5385
|
-
}
|
|
5450
|
+
};
|
|
5451
|
+
if (quantityKind !== void 0) {
|
|
5452
|
+
inp.quantityKind = quantityKind;
|
|
5453
|
+
}
|
|
5454
|
+
if (hasRange) {
|
|
5455
|
+
inp.hasRange = true;
|
|
5456
|
+
if (rangeMin !== void 0) {
|
|
5457
|
+
inp.rangeMin = rangeMin;
|
|
5458
|
+
}
|
|
5459
|
+
if (rangeMax !== void 0) {
|
|
5460
|
+
inp.rangeMax = rangeMax;
|
|
5461
|
+
}
|
|
5462
|
+
}
|
|
5463
|
+
inputs.push(inp);
|
|
5386
5464
|
}
|
|
5387
5465
|
return inputs;
|
|
5388
5466
|
}
|
|
@@ -5393,6 +5471,10 @@ function parseOutput(block) {
|
|
|
5393
5471
|
let unit = "1";
|
|
5394
5472
|
let name = "";
|
|
5395
5473
|
let description = "";
|
|
5474
|
+
let quantityKind;
|
|
5475
|
+
let rangeMin;
|
|
5476
|
+
let rangeMax;
|
|
5477
|
+
let hasRange = false;
|
|
5396
5478
|
if (t[i] === ":") {
|
|
5397
5479
|
i++;
|
|
5398
5480
|
}
|
|
@@ -5407,7 +5489,27 @@ function parseOutput(block) {
|
|
|
5407
5489
|
const cmd = pt[j++];
|
|
5408
5490
|
if (j < pt.length) {
|
|
5409
5491
|
if (cmd === "unit") {
|
|
5410
|
-
unit =
|
|
5492
|
+
unit = stripWrapping(pt[j++]);
|
|
5493
|
+
} else if (cmd === "quantity_kind") {
|
|
5494
|
+
quantityKind = stripWrapping(pt[j++]);
|
|
5495
|
+
} else if (cmd === "range") {
|
|
5496
|
+
const rt = tokenizePackage(unwrapBlock(pt[j++]));
|
|
5497
|
+
let k = 0;
|
|
5498
|
+
while (k < rt.length) {
|
|
5499
|
+
const rc = rt[k++];
|
|
5500
|
+
if (k >= rt.length) {
|
|
5501
|
+
break;
|
|
5502
|
+
}
|
|
5503
|
+
if (rc === "min") {
|
|
5504
|
+
rangeMin = stripWrapping(rt[k++]);
|
|
5505
|
+
hasRange = true;
|
|
5506
|
+
} else if (rc === "max") {
|
|
5507
|
+
rangeMax = stripWrapping(rt[k++]);
|
|
5508
|
+
hasRange = true;
|
|
5509
|
+
} else {
|
|
5510
|
+
unwrapBlock(rt[k++]);
|
|
5511
|
+
}
|
|
5512
|
+
}
|
|
5411
5513
|
} else if (cmd === "name") {
|
|
5412
5514
|
name = stripWrapping(pt[j++]);
|
|
5413
5515
|
} else if (cmd === "description") {
|
|
@@ -5425,6 +5527,18 @@ function parseOutput(block) {
|
|
|
5425
5527
|
if (description) {
|
|
5426
5528
|
out.description = description;
|
|
5427
5529
|
}
|
|
5530
|
+
if (quantityKind !== void 0) {
|
|
5531
|
+
out.quantityKind = quantityKind;
|
|
5532
|
+
}
|
|
5533
|
+
if (hasRange) {
|
|
5534
|
+
out.hasRange = true;
|
|
5535
|
+
if (rangeMin !== void 0) {
|
|
5536
|
+
out.rangeMin = rangeMin;
|
|
5537
|
+
}
|
|
5538
|
+
if (rangeMax !== void 0) {
|
|
5539
|
+
out.rangeMax = rangeMax;
|
|
5540
|
+
}
|
|
5541
|
+
}
|
|
5428
5542
|
return out;
|
|
5429
5543
|
}
|
|
5430
5544
|
function parseLookup(block) {
|
|
@@ -5494,6 +5608,9 @@ var dumpCalculation = function(c) {
|
|
|
5494
5608
|
for (const inp of c.inputs) {
|
|
5495
5609
|
let line = " " + inp.name + " : " + inp.type + " { ";
|
|
5496
5610
|
line += 'unit "' + escapeString(inp.unit) + '"';
|
|
5611
|
+
if (inp.quantityKind) {
|
|
5612
|
+
line += " quantity_kind " + inp.quantityKind;
|
|
5613
|
+
}
|
|
5497
5614
|
if (inp.description) {
|
|
5498
5615
|
line += ' description "' + escapeString(inp.description) + '"';
|
|
5499
5616
|
}
|
|
@@ -5503,18 +5620,41 @@ var dumpCalculation = function(c) {
|
|
|
5503
5620
|
if (inp.enumValues && inp.enumValues.length > 0) {
|
|
5504
5621
|
line += " enum_values { " + inp.enumValues.join(" ") + " }";
|
|
5505
5622
|
}
|
|
5623
|
+
if (inp.hasRange) {
|
|
5624
|
+
line += " range {";
|
|
5625
|
+
if (inp.rangeMin) {
|
|
5626
|
+
line += " min " + dumpBareSafe(inp.rangeMin);
|
|
5627
|
+
}
|
|
5628
|
+
if (inp.rangeMax) {
|
|
5629
|
+
line += " max " + dumpBareSafe(inp.rangeMax);
|
|
5630
|
+
}
|
|
5631
|
+
line += " }";
|
|
5632
|
+
}
|
|
5506
5633
|
line += " }\n";
|
|
5507
5634
|
out += line;
|
|
5508
5635
|
}
|
|
5509
5636
|
out += " }\n";
|
|
5510
5637
|
}
|
|
5511
5638
|
let outputLine = " output : " + c.output.type + ' { unit "' + escapeString(c.output.unit) + '"';
|
|
5639
|
+
if (c.output.quantityKind) {
|
|
5640
|
+
outputLine += " quantity_kind " + c.output.quantityKind;
|
|
5641
|
+
}
|
|
5512
5642
|
if (c.output.name) {
|
|
5513
5643
|
outputLine += ' name "' + escapeString(c.output.name) + '"';
|
|
5514
5644
|
}
|
|
5515
5645
|
if (c.output.description) {
|
|
5516
5646
|
outputLine += ' description "' + escapeString(c.output.description) + '"';
|
|
5517
5647
|
}
|
|
5648
|
+
if (c.output.hasRange) {
|
|
5649
|
+
outputLine += " range {";
|
|
5650
|
+
if (c.output.rangeMin) {
|
|
5651
|
+
outputLine += " min " + dumpBareSafe(c.output.rangeMin);
|
|
5652
|
+
}
|
|
5653
|
+
if (c.output.rangeMax) {
|
|
5654
|
+
outputLine += " max " + dumpBareSafe(c.output.rangeMax);
|
|
5655
|
+
}
|
|
5656
|
+
outputLine += " }";
|
|
5657
|
+
}
|
|
5518
5658
|
out += outputLine + " }\n";
|
|
5519
5659
|
if (c.expression) {
|
|
5520
5660
|
out += ' expression "' + escapeString(c.expression) + '"\n';
|
|
@@ -7694,6 +7834,25 @@ var dumpConformanceTest = function(ct) {
|
|
|
7694
7834
|
};
|
|
7695
7835
|
|
|
7696
7836
|
// src/ser-des/config/term.ts
|
|
7837
|
+
var ALIAS_KEYWORDS = {
|
|
7838
|
+
aliases: "aliases",
|
|
7839
|
+
alt: "aliases",
|
|
7840
|
+
colloquial: "colloquial",
|
|
7841
|
+
abbreviations: "abbreviations",
|
|
7842
|
+
deprecated: "deprecated"
|
|
7843
|
+
};
|
|
7844
|
+
function isAliasKeyword(command) {
|
|
7845
|
+
return command in ALIAS_KEYWORDS;
|
|
7846
|
+
}
|
|
7847
|
+
function appendAliasEntries(term, facet, entries) {
|
|
7848
|
+
if (facet === "aliases") {
|
|
7849
|
+
const merged = [...term.aliases ?? [], ...entries];
|
|
7850
|
+
term.aliases = merged;
|
|
7851
|
+
term.alt = merged;
|
|
7852
|
+
} else {
|
|
7853
|
+
(term[facet] ??= []).push(...entries);
|
|
7854
|
+
}
|
|
7855
|
+
}
|
|
7697
7856
|
var parseTerm = function(id, data) {
|
|
7698
7857
|
const result = {
|
|
7699
7858
|
id,
|
|
@@ -7764,12 +7923,28 @@ var parseTerm = function(id, data) {
|
|
|
7764
7923
|
result.formType = unwrapped(value);
|
|
7765
7924
|
} else if (command === "part_of_speech") {
|
|
7766
7925
|
result.partOfSpeech = unwrapped(value);
|
|
7767
|
-
} else if (command
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
|
|
7772
|
-
|
|
7926
|
+
} else if (isAliasKeyword(command)) {
|
|
7927
|
+
const first = value();
|
|
7928
|
+
let spelling;
|
|
7929
|
+
let listToken = first;
|
|
7930
|
+
if (!first.startsWith("{")) {
|
|
7931
|
+
spelling = first;
|
|
7932
|
+
const next = peek();
|
|
7933
|
+
if (next === void 0 || !next.startsWith("{")) {
|
|
7934
|
+
throw new Error(
|
|
7935
|
+
`Parsing error: term. ID ${id}: alias-family facet "${command}" with spelling code "${spelling}" expects a list block`
|
|
7936
|
+
);
|
|
7937
|
+
}
|
|
7938
|
+
listToken = value();
|
|
7939
|
+
}
|
|
7940
|
+
const entries = tokenizePackage(listToken).map(stripWrapping);
|
|
7941
|
+
const facet = ALIAS_KEYWORDS[command];
|
|
7942
|
+
if (spelling === void 0) {
|
|
7943
|
+
appendAliasEntries(result, facet, entries);
|
|
7944
|
+
} else {
|
|
7945
|
+
const variant = (result.aliasSpellings ??= {})[spelling] ??= {};
|
|
7946
|
+
(variant[facet] ??= []).push(...entries);
|
|
7947
|
+
}
|
|
7773
7948
|
} else if (command === "see_also") {
|
|
7774
7949
|
result.seeAlso = tokenizePackage(value()).map(stripWrapping);
|
|
7775
7950
|
} else {
|
|
@@ -7826,14 +8001,33 @@ var dumpTerm = function(term) {
|
|
|
7826
8001
|
out += ' part_of_speech "' + escapeString(term.partOfSpeech) + '"\n';
|
|
7827
8002
|
}
|
|
7828
8003
|
const listEntry = (s) => /\s/.test(s) ? '"' + escapeString(s) + '"' : s;
|
|
7829
|
-
|
|
7830
|
-
|
|
8004
|
+
const aliasLine = (facet, list, tag) => " " + facet + (tag ? " " + tag : "") + " { " + list.map(listEntry).join(" ") + " }\n";
|
|
8005
|
+
const aliases = term.aliases ?? term.alt;
|
|
8006
|
+
if (aliases && aliases.length > 0) {
|
|
8007
|
+
out += aliasLine("aliases", aliases);
|
|
7831
8008
|
}
|
|
7832
|
-
if (term.
|
|
7833
|
-
out += "
|
|
8009
|
+
if (term.colloquial && term.colloquial.length > 0) {
|
|
8010
|
+
out += aliasLine("colloquial", term.colloquial);
|
|
7834
8011
|
}
|
|
7835
8012
|
if (term.abbreviations && term.abbreviations.length > 0) {
|
|
7836
|
-
out += "
|
|
8013
|
+
out += aliasLine("abbreviations", term.abbreviations);
|
|
8014
|
+
}
|
|
8015
|
+
if (term.deprecated && term.deprecated.length > 0) {
|
|
8016
|
+
out += aliasLine("deprecated", term.deprecated);
|
|
8017
|
+
}
|
|
8018
|
+
for (const code of Object.keys(term.aliasSpellings ?? {}).sort()) {
|
|
8019
|
+
const variant = term.aliasSpellings[code];
|
|
8020
|
+
for (const facet of [
|
|
8021
|
+
"aliases",
|
|
8022
|
+
"colloquial",
|
|
8023
|
+
"abbreviations",
|
|
8024
|
+
"deprecated"
|
|
8025
|
+
]) {
|
|
8026
|
+
const list = variant[facet];
|
|
8027
|
+
if (list && list.length > 0) {
|
|
8028
|
+
out += aliasLine(facet, list, code);
|
|
8029
|
+
}
|
|
8030
|
+
}
|
|
7837
8031
|
}
|
|
7838
8032
|
if (term.seeAlso && term.seeAlso.length > 0) {
|
|
7839
8033
|
out += " see_also { " + term.seeAlso.map(listEntry).join(" ") + " }\n";
|
|
@@ -8720,6 +8914,7 @@ function readLimit(block) {
|
|
|
8720
8914
|
relativeTo: "",
|
|
8721
8915
|
notes: "",
|
|
8722
8916
|
accepts: null,
|
|
8917
|
+
quantity: null,
|
|
8723
8918
|
acceptance: null,
|
|
8724
8919
|
sourceDiscrepancy: null
|
|
8725
8920
|
};
|
|
@@ -8740,6 +8935,24 @@ function readLimit(block) {
|
|
|
8740
8935
|
limit.relativeTo = stripWrapping(t[i++]);
|
|
8741
8936
|
} else if (cmd === "notes") {
|
|
8742
8937
|
limit.notes = stripWrapping(t[i++]);
|
|
8938
|
+
} else if (cmd === "quantity") {
|
|
8939
|
+
const quantity = { kind: "", unit: "" };
|
|
8940
|
+
const qt = tokenize(unwrapBlock(t[i++]));
|
|
8941
|
+
let k = 0;
|
|
8942
|
+
while (k < qt.length) {
|
|
8943
|
+
const qc = qt[k++];
|
|
8944
|
+
if (k >= qt.length) {
|
|
8945
|
+
break;
|
|
8946
|
+
}
|
|
8947
|
+
if (qc === "kind") {
|
|
8948
|
+
quantity.kind = stripWrapping(qt[k++]);
|
|
8949
|
+
} else if (qc === "unit") {
|
|
8950
|
+
quantity.unit = stripWrapping(qt[k++]);
|
|
8951
|
+
} else {
|
|
8952
|
+
unwrapBlock(qt[k++]);
|
|
8953
|
+
}
|
|
8954
|
+
}
|
|
8955
|
+
limit.quantity = quantity;
|
|
8743
8956
|
} else if (cmd === "accepts") {
|
|
8744
8957
|
limit.accepts = readAccepts(unwrapBlock(t[i++]));
|
|
8745
8958
|
} else if (cmd === "acceptance") {
|
|
@@ -8812,7 +9025,8 @@ function readParameters(block) {
|
|
|
8812
9025
|
rangeMin: "",
|
|
8813
9026
|
rangeMax: "",
|
|
8814
9027
|
hasRange: false,
|
|
8815
|
-
enumValues: []
|
|
9028
|
+
enumValues: [],
|
|
9029
|
+
bind: ""
|
|
8816
9030
|
};
|
|
8817
9031
|
if (i < t.length && !t[i].startsWith("{")) {
|
|
8818
9032
|
param.type = stripWrapping(t[i++]);
|
|
@@ -8829,6 +9043,8 @@ function readParameters(block) {
|
|
|
8829
9043
|
param.description = stripWrapping(pt[j++]);
|
|
8830
9044
|
} else if (pc === "unit") {
|
|
8831
9045
|
param.unit = stripWrapping(pt[j++]);
|
|
9046
|
+
} else if (pc === "bind") {
|
|
9047
|
+
param.bind = stripWrapping(pt[j++]);
|
|
8832
9048
|
} else if (pc === "default") {
|
|
8833
9049
|
param.defaultValue = stripWrapping(pt[j++]);
|
|
8834
9050
|
param.hasDefault = true;
|
|
@@ -8975,6 +9191,16 @@ function dumpLimit(limit) {
|
|
|
8975
9191
|
if (limit.notes) {
|
|
8976
9192
|
out += ' notes "' + escapeString(limit.notes) + '"\n';
|
|
8977
9193
|
}
|
|
9194
|
+
if (limit.quantity) {
|
|
9195
|
+
let line = " quantity {";
|
|
9196
|
+
if (limit.quantity.kind) {
|
|
9197
|
+
line += " kind " + limit.quantity.kind;
|
|
9198
|
+
}
|
|
9199
|
+
if (limit.quantity.unit) {
|
|
9200
|
+
line += " unit " + limit.quantity.unit;
|
|
9201
|
+
}
|
|
9202
|
+
out += line + " }\n";
|
|
9203
|
+
}
|
|
8978
9204
|
if (limit.accepts) {
|
|
8979
9205
|
const a = limit.accepts;
|
|
8980
9206
|
let line = " accepts { verdict " + a.verdict;
|
|
@@ -9036,6 +9262,9 @@ var dumpRequirement = function(r) {
|
|
|
9036
9262
|
if (p.unit) {
|
|
9037
9263
|
line += 'unit "' + escapeString(p.unit) + '" ';
|
|
9038
9264
|
}
|
|
9265
|
+
if (p.bind) {
|
|
9266
|
+
line += 'bind "' + escapeString(p.bind) + '" ';
|
|
9267
|
+
}
|
|
9039
9268
|
if (p.hasDefault) {
|
|
9040
9269
|
line += "default " + dumpBareSafe(p.defaultValue) + " ";
|
|
9041
9270
|
}
|
|
@@ -9298,6 +9527,8 @@ var parsePackage = function(data) {
|
|
|
9298
9527
|
manifest.supersedes = readUrnList(t[i++]);
|
|
9299
9528
|
} else if (cmd === "replaces") {
|
|
9300
9529
|
manifest.replaces = readUrnList(t[i++]);
|
|
9530
|
+
} else if (cmd === "superseded_by") {
|
|
9531
|
+
manifest.supersededBy = readUrnList(t[i++]);
|
|
9301
9532
|
} else if (cmd === "validity") {
|
|
9302
9533
|
const vblock = unwrapBlock(t[i++]);
|
|
9303
9534
|
const vt = tokenize(vblock);
|
|
@@ -10155,6 +10386,14 @@ function parseDimension(id, block) {
|
|
|
10155
10386
|
dim.source = readSource(unwrapBlock(t[i++]));
|
|
10156
10387
|
} else if (cmd === "values") {
|
|
10157
10388
|
dim.values = parseDimensionValues(unwrapBlock(t[i++]));
|
|
10389
|
+
} else if (cmd === "values_of") {
|
|
10390
|
+
dim.valuesOf = stripWrapping(t[i++]);
|
|
10391
|
+
} else if (cmd === "ref") {
|
|
10392
|
+
const r = parseRef(t, i, stripWrapping, unwrapBlock);
|
|
10393
|
+
if (!foldRefIntoLegacy(dim, r.ref)) {
|
|
10394
|
+
(dim.refs ??= []).push(r.ref);
|
|
10395
|
+
}
|
|
10396
|
+
i = r.next;
|
|
10158
10397
|
} else {
|
|
10159
10398
|
i = skipUnknownValue(t, i, cmd);
|
|
10160
10399
|
}
|
|
@@ -10236,6 +10475,73 @@ function parseDimensionValues(block) {
|
|
|
10236
10475
|
}
|
|
10237
10476
|
return out;
|
|
10238
10477
|
}
|
|
10478
|
+
function dumpDimension(d, indent) {
|
|
10479
|
+
const inner = indent + " ";
|
|
10480
|
+
const valueIndent = indent + " ";
|
|
10481
|
+
let out = indent + "dimension " + d.id + " {\n";
|
|
10482
|
+
if (d.label) {
|
|
10483
|
+
out += inner + 'label "' + escapeString(d.label) + '"\n';
|
|
10484
|
+
}
|
|
10485
|
+
if (d.scope) {
|
|
10486
|
+
out += inner + "scope " + d.scope + "\n";
|
|
10487
|
+
}
|
|
10488
|
+
if (d.cardinality) {
|
|
10489
|
+
out += inner + "cardinality " + d.cardinality + "\n";
|
|
10490
|
+
}
|
|
10491
|
+
if (d.labelSeparator) {
|
|
10492
|
+
out += inner + 'label_separator "' + escapeString(d.labelSeparator) + '"\n';
|
|
10493
|
+
}
|
|
10494
|
+
if (d.description) {
|
|
10495
|
+
out += inner + 'description "' + escapeString(d.description) + '"\n';
|
|
10496
|
+
}
|
|
10497
|
+
out += dumpSource("reference", d.source, inner);
|
|
10498
|
+
if (d.valuesOf) {
|
|
10499
|
+
out += inner + "values_of " + d.valuesOf + "\n";
|
|
10500
|
+
}
|
|
10501
|
+
if (d.values.length > 0) {
|
|
10502
|
+
out += inner + "values {\n";
|
|
10503
|
+
for (const v of d.values) {
|
|
10504
|
+
let line = valueIndent + v.id;
|
|
10505
|
+
const hasProps = v.label || v.description || v.termRef || Object.keys(v.payload).length > 0 || v.implies.length > 0;
|
|
10506
|
+
if (hasProps) {
|
|
10507
|
+
line += " { ";
|
|
10508
|
+
if (v.label) {
|
|
10509
|
+
line += 'label "' + escapeString(v.label) + '" ';
|
|
10510
|
+
}
|
|
10511
|
+
if (v.description) {
|
|
10512
|
+
line += 'description "' + escapeString(v.description) + '" ';
|
|
10513
|
+
}
|
|
10514
|
+
if (v.termRef) {
|
|
10515
|
+
line += "term_ref " + v.termRef + " ";
|
|
10516
|
+
}
|
|
10517
|
+
if (v.implies.length > 0) {
|
|
10518
|
+
line += "implies { " + v.implies.join(" ") + " } ";
|
|
10519
|
+
}
|
|
10520
|
+
if (Object.keys(v.payload).length > 0) {
|
|
10521
|
+
line += "payload { ";
|
|
10522
|
+
for (const [k, val] of Object.entries(v.payload)) {
|
|
10523
|
+
if (typeof val === "object" && val !== null) {
|
|
10524
|
+
line += k + " { ";
|
|
10525
|
+
for (const [nk, nv] of Object.entries(val)) {
|
|
10526
|
+
line += nk + ': "' + escapeString(String(nv)) + '" ';
|
|
10527
|
+
}
|
|
10528
|
+
line += "} ";
|
|
10529
|
+
} else {
|
|
10530
|
+
line += k + ': "' + escapeString(String(val)) + '" ';
|
|
10531
|
+
}
|
|
10532
|
+
}
|
|
10533
|
+
line += "} ";
|
|
10534
|
+
}
|
|
10535
|
+
line += "}";
|
|
10536
|
+
}
|
|
10537
|
+
out += line + "\n";
|
|
10538
|
+
}
|
|
10539
|
+
out += inner + "}\n";
|
|
10540
|
+
}
|
|
10541
|
+
out += dumpRefs(d.refs, inner, escapeString);
|
|
10542
|
+
out += indent + "}\n";
|
|
10543
|
+
return out;
|
|
10544
|
+
}
|
|
10239
10545
|
function parseModelGroup(block) {
|
|
10240
10546
|
const mg = {
|
|
10241
10547
|
definition: "",
|
|
@@ -10374,64 +10680,7 @@ var dumpInstrument = function(inst) {
|
|
|
10374
10680
|
out += line + "}\n";
|
|
10375
10681
|
}
|
|
10376
10682
|
for (const d of inst.dimensions) {
|
|
10377
|
-
out +=
|
|
10378
|
-
if (d.label) {
|
|
10379
|
-
out += ' label "' + escapeString(d.label) + '"\n';
|
|
10380
|
-
}
|
|
10381
|
-
if (d.scope) {
|
|
10382
|
-
out += " scope " + d.scope + "\n";
|
|
10383
|
-
}
|
|
10384
|
-
if (d.cardinality) {
|
|
10385
|
-
out += " cardinality " + d.cardinality + "\n";
|
|
10386
|
-
}
|
|
10387
|
-
if (d.labelSeparator) {
|
|
10388
|
-
out += ' label_separator "' + escapeString(d.labelSeparator) + '"\n';
|
|
10389
|
-
}
|
|
10390
|
-
if (d.description) {
|
|
10391
|
-
out += ' description "' + escapeString(d.description) + '"\n';
|
|
10392
|
-
}
|
|
10393
|
-
out += dumpSource("reference", d.source, " ");
|
|
10394
|
-
if (d.values.length > 0) {
|
|
10395
|
-
out += " values {\n";
|
|
10396
|
-
for (const v of d.values) {
|
|
10397
|
-
let line = " " + v.id;
|
|
10398
|
-
const hasProps = v.label || v.description || v.termRef || Object.keys(v.payload).length > 0 || v.implies.length > 0;
|
|
10399
|
-
if (hasProps) {
|
|
10400
|
-
line += " { ";
|
|
10401
|
-
if (v.label) {
|
|
10402
|
-
line += 'label "' + escapeString(v.label) + '" ';
|
|
10403
|
-
}
|
|
10404
|
-
if (v.description) {
|
|
10405
|
-
line += 'description "' + escapeString(v.description) + '" ';
|
|
10406
|
-
}
|
|
10407
|
-
if (v.termRef) {
|
|
10408
|
-
line += "term_ref " + v.termRef + " ";
|
|
10409
|
-
}
|
|
10410
|
-
if (v.implies.length > 0) {
|
|
10411
|
-
line += "implies { " + v.implies.join(" ") + " } ";
|
|
10412
|
-
}
|
|
10413
|
-
if (Object.keys(v.payload).length > 0) {
|
|
10414
|
-
line += "payload { ";
|
|
10415
|
-
for (const [k, val] of Object.entries(v.payload)) {
|
|
10416
|
-
if (typeof val === "object" && val !== null) {
|
|
10417
|
-
line += k + " { ";
|
|
10418
|
-
for (const [nk, nv] of Object.entries(val)) {
|
|
10419
|
-
line += nk + ': "' + escapeString(String(nv)) + '" ';
|
|
10420
|
-
}
|
|
10421
|
-
line += "} ";
|
|
10422
|
-
} else {
|
|
10423
|
-
line += k + ': "' + escapeString(String(val)) + '" ';
|
|
10424
|
-
}
|
|
10425
|
-
}
|
|
10426
|
-
line += "} ";
|
|
10427
|
-
}
|
|
10428
|
-
line += "}";
|
|
10429
|
-
}
|
|
10430
|
-
out += line + "\n";
|
|
10431
|
-
}
|
|
10432
|
-
out += " }\n";
|
|
10433
|
-
}
|
|
10434
|
-
out += " }\n";
|
|
10683
|
+
out += dumpDimension(d, " ");
|
|
10435
10684
|
}
|
|
10436
10685
|
if (inst.familyMetamodelClass || inst.familyDefinition || inst.familyNote || inst.familySource && (inst.familySource.doc || inst.familySource.clause)) {
|
|
10437
10686
|
out += " family {\n";
|
|
@@ -12875,6 +13124,10 @@ function parseKind(id, block) {
|
|
|
12875
13124
|
out.siUnit = stripWrapping(t[i++]);
|
|
12876
13125
|
} else if (cmd === "description") {
|
|
12877
13126
|
out.description = stripWrapping(t[i++]);
|
|
13127
|
+
} else if (cmd === "corresponds") {
|
|
13128
|
+
const { corr, next } = parseCorresponds(t, i, stripWrapping);
|
|
13129
|
+
(out.correspondences ??= []).push(corr);
|
|
13130
|
+
i = next;
|
|
12878
13131
|
} else {
|
|
12879
13132
|
unwrapBlock(t[i++]);
|
|
12880
13133
|
}
|
|
@@ -12910,6 +13163,10 @@ function parseUnit(id, block) {
|
|
|
12910
13163
|
out.offsetToSI = readNumber(t[i++], 0);
|
|
12911
13164
|
} else if (cmd === "definition") {
|
|
12912
13165
|
out.definition = stripWrapping(t[i++]);
|
|
13166
|
+
} else if (cmd === "corresponds") {
|
|
13167
|
+
const { corr, next } = parseCorresponds(t, i, stripWrapping);
|
|
13168
|
+
(out.correspondences ??= []).push(corr);
|
|
13169
|
+
i = next;
|
|
12913
13170
|
} else {
|
|
12914
13171
|
unwrapBlock(t[i++]);
|
|
12915
13172
|
}
|
|
@@ -12945,6 +13202,24 @@ var parseQuantityRegister = function(id, data) {
|
|
|
12945
13202
|
return ctx;
|
|
12946
13203
|
};
|
|
12947
13204
|
};
|
|
13205
|
+
function dumpCorrespondencesInline(corrs) {
|
|
13206
|
+
let out = "";
|
|
13207
|
+
for (const c of corrs ?? []) {
|
|
13208
|
+
out += " corresponds " + dumpBareSafe(c.scheme) + ' "' + escapeString(c.concept) + '"';
|
|
13209
|
+
if (c.projections.length > 0) {
|
|
13210
|
+
out += " {";
|
|
13211
|
+
for (const p of c.projections) {
|
|
13212
|
+
out += " projection " + dumpBareSafe(p.codec) + " {";
|
|
13213
|
+
for (const e of p.entries) {
|
|
13214
|
+
out += " " + dumpBareSafe(e.key) + " " + dumpBareSafe(e.value);
|
|
13215
|
+
}
|
|
13216
|
+
out += " }";
|
|
13217
|
+
}
|
|
13218
|
+
out += " }";
|
|
13219
|
+
}
|
|
13220
|
+
}
|
|
13221
|
+
return out;
|
|
13222
|
+
}
|
|
12948
13223
|
function dumpDimensions(dimensions) {
|
|
12949
13224
|
const keys = Object.keys(dimensions);
|
|
12950
13225
|
if (keys.length === 0) {
|
|
@@ -12962,6 +13237,7 @@ var dumpQuantityRegister = function(reg) {
|
|
|
12962
13237
|
if (k.description) {
|
|
12963
13238
|
line += ' description "' + escapeString(k.description) + '"';
|
|
12964
13239
|
}
|
|
13240
|
+
line += dumpCorrespondencesInline(k.correspondences);
|
|
12965
13241
|
out += line + " }\n";
|
|
12966
13242
|
}
|
|
12967
13243
|
for (const u of reg.units) {
|
|
@@ -12984,6 +13260,7 @@ var dumpQuantityRegister = function(reg) {
|
|
|
12984
13260
|
if (u.definition) {
|
|
12985
13261
|
line += ' definition "' + escapeString(u.definition) + '"';
|
|
12986
13262
|
}
|
|
13263
|
+
line += dumpCorrespondencesInline(u.correspondences);
|
|
12987
13264
|
out += line + " }\n";
|
|
12988
13265
|
}
|
|
12989
13266
|
if (reg.referenceIds.length > 0) {
|
|
@@ -13442,6 +13719,25 @@ var policyConstruct = {
|
|
|
13442
13719
|
dump: dumpPolicy
|
|
13443
13720
|
};
|
|
13444
13721
|
|
|
13722
|
+
// src/ser-des/config/dimension.ts
|
|
13723
|
+
var parseTopLevelDimension = function(id, data) {
|
|
13724
|
+
const dim = parseDimension(id, unwrapBlock(data));
|
|
13725
|
+
return (ctx) => {
|
|
13726
|
+
ctx.dimensions[id] = dim;
|
|
13727
|
+
return ctx;
|
|
13728
|
+
};
|
|
13729
|
+
};
|
|
13730
|
+
var dumpTopLevelDimension = function(d) {
|
|
13731
|
+
return dumpDimension(d, "");
|
|
13732
|
+
};
|
|
13733
|
+
var dimensionConstruct = {
|
|
13734
|
+
keyword: "dimension",
|
|
13735
|
+
field: "dimensions",
|
|
13736
|
+
takesID: true,
|
|
13737
|
+
parse: parseTopLevelDimension,
|
|
13738
|
+
dump: dumpTopLevelDimension
|
|
13739
|
+
};
|
|
13740
|
+
|
|
13445
13741
|
// src/ser-des/config/activityArchetype.ts
|
|
13446
13742
|
var parseActivityArchetype = (id, data) => {
|
|
13447
13743
|
const archetype = {
|
|
@@ -13859,7 +14155,11 @@ var CONSTRUCTS = [
|
|
|
13859
14155
|
// sub-structures (config/trustRef.ts, config/correspondence.ts), not
|
|
13860
14156
|
// top-level constructs.
|
|
13861
14157
|
dataspaceConstruct,
|
|
13862
|
-
policyConstruct
|
|
14158
|
+
policyConstruct,
|
|
14159
|
+
// Primmel v3.2 consumption constructs (TODO.primmel/11; MN 114 clause
|
|
14160
|
+
// 10.6): the top-level applicability dimension (one grammar with the
|
|
14161
|
+
// instrument's inline dimension blocks, two placements).
|
|
14162
|
+
dimensionConstruct
|
|
13863
14163
|
];
|
|
13864
14164
|
function buildParserConfig(constructs) {
|
|
13865
14165
|
const out = {};
|
|
@@ -14005,6 +14305,9 @@ function packageFiles(dir) {
|
|
|
14005
14305
|
}
|
|
14006
14306
|
return files;
|
|
14007
14307
|
}
|
|
14308
|
+
function loadPackage(dir, options = {}) {
|
|
14309
|
+
return loadPackageInternal(dir, options).standard;
|
|
14310
|
+
}
|
|
14008
14311
|
function countNewlines(text) {
|
|
14009
14312
|
let n = 0;
|
|
14010
14313
|
for (let i = 0; i < text.length; i++) {
|
|
@@ -15160,30 +15463,38 @@ var GENERIC_ANCHOR = [
|
|
|
15160
15463
|
"conformanceProcessIds"
|
|
15161
15464
|
];
|
|
15162
15465
|
function provenanceOf(el) {
|
|
15163
|
-
const
|
|
15164
|
-
const push = (r) => {
|
|
15466
|
+
const channels = {};
|
|
15467
|
+
const push = (channel, r) => {
|
|
15165
15468
|
if (r && typeof r === "object" && (r.doc || r.clause)) {
|
|
15166
|
-
|
|
15469
|
+
(channels[channel] ??= []).push(
|
|
15470
|
+
normalizeSourceRef(r.doc ?? "", r.clause ?? "", r.fragment)
|
|
15471
|
+
);
|
|
15167
15472
|
}
|
|
15168
15473
|
};
|
|
15169
|
-
push(el.source);
|
|
15170
|
-
push(el.sourceRef);
|
|
15474
|
+
push("source", el.source);
|
|
15475
|
+
push("sourceRef", el.sourceRef);
|
|
15171
15476
|
for (const r of el.sourceRefs ?? []) {
|
|
15172
|
-
push(r);
|
|
15477
|
+
push("sourceRefs", r);
|
|
15173
15478
|
}
|
|
15174
15479
|
const refString = el.reference;
|
|
15175
15480
|
if (typeof refString === "string" && refString.startsWith("urn:")) {
|
|
15176
|
-
push({ doc: refString, clause: "" });
|
|
15481
|
+
push("reference", { doc: refString, clause: "" });
|
|
15177
15482
|
}
|
|
15178
|
-
const
|
|
15179
|
-
|
|
15180
|
-
|
|
15181
|
-
|
|
15182
|
-
|
|
15183
|
-
|
|
15184
|
-
|
|
15185
|
-
|
|
15186
|
-
|
|
15483
|
+
const dedup = (rs) => {
|
|
15484
|
+
const seen = /* @__PURE__ */ new Set();
|
|
15485
|
+
return rs.filter((r) => {
|
|
15486
|
+
const k = provenanceEdgeKey(r);
|
|
15487
|
+
if (seen.has(k)) {
|
|
15488
|
+
return false;
|
|
15489
|
+
}
|
|
15490
|
+
seen.add(k);
|
|
15491
|
+
return true;
|
|
15492
|
+
});
|
|
15493
|
+
};
|
|
15494
|
+
for (const [channel, rs] of Object.entries(channels)) {
|
|
15495
|
+
channels[channel] = dedup(rs);
|
|
15496
|
+
}
|
|
15497
|
+
return { edges: dedup(Object.values(channels).flat()), channels };
|
|
15187
15498
|
}
|
|
15188
15499
|
function provenanceEdgeKey(r) {
|
|
15189
15500
|
return canonical({ basis: r.basis, clause: r.clause, fragment: r.fragment });
|
|
@@ -15191,26 +15502,28 @@ function provenanceEdgeKey(r) {
|
|
|
15191
15502
|
function elementOf(field, el) {
|
|
15192
15503
|
const id = String(el.id ?? el.entityName ?? "");
|
|
15193
15504
|
const tier = TIER_BY_FIELD[field] ?? "cross-cutting";
|
|
15194
|
-
const provenance = provenanceOf(el);
|
|
15505
|
+
const { edges: provenance, channels: provenanceChannels } = provenanceOf(el);
|
|
15195
15506
|
const consumed = new Set(PROVENANCE_FIELDS);
|
|
15196
15507
|
if (typeof el.reference === "string" && el.reference.startsWith("urn:")) {
|
|
15197
15508
|
consumed.add("reference");
|
|
15198
15509
|
}
|
|
15510
|
+
const fields = {};
|
|
15199
15511
|
const aspects = {};
|
|
15200
15512
|
const spec = ASPECT_SPECS[field];
|
|
15201
|
-
const pick = (
|
|
15513
|
+
const pick = (names) => {
|
|
15202
15514
|
const out = {};
|
|
15203
|
-
for (const f of
|
|
15515
|
+
for (const f of names) {
|
|
15204
15516
|
if (el[f] !== void 0) {
|
|
15205
15517
|
out[f] = el[f];
|
|
15206
15518
|
consumed.add(f);
|
|
15519
|
+
fields[f] = el[f];
|
|
15207
15520
|
}
|
|
15208
15521
|
}
|
|
15209
15522
|
return out;
|
|
15210
15523
|
};
|
|
15211
15524
|
if (spec) {
|
|
15212
|
-
for (const [aspect,
|
|
15213
|
-
const picked = pick(
|
|
15525
|
+
for (const [aspect, names] of Object.entries(spec)) {
|
|
15526
|
+
const picked = pick(names ?? []);
|
|
15214
15527
|
if (Object.keys(picked).length > 0) {
|
|
15215
15528
|
aspects[aspect] = canonical(picked);
|
|
15216
15529
|
}
|
|
@@ -15220,10 +15533,9 @@ function elementOf(field, el) {
|
|
|
15220
15533
|
const entries = el.entries ?? [];
|
|
15221
15534
|
for (const e of entries) {
|
|
15222
15535
|
if (e && typeof e.spelling === "string") {
|
|
15223
|
-
|
|
15224
|
-
|
|
15225
|
-
|
|
15226
|
-
});
|
|
15536
|
+
const entry = { value: e.value, via: e.via };
|
|
15537
|
+
aspects[`spelling:${e.spelling}`] = canonical(entry);
|
|
15538
|
+
fields[`spelling:${e.spelling}`] = entry;
|
|
15227
15539
|
}
|
|
15228
15540
|
}
|
|
15229
15541
|
} else {
|
|
@@ -15244,15 +15556,31 @@ function elementOf(field, el) {
|
|
|
15244
15556
|
fragment: r.fragment
|
|
15245
15557
|
}))
|
|
15246
15558
|
);
|
|
15559
|
+
for (const [channel, edges] of Object.entries(provenanceChannels)) {
|
|
15560
|
+
fields[channel] = edges.map((r) => ({
|
|
15561
|
+
basis: r.basis,
|
|
15562
|
+
clause: r.clause,
|
|
15563
|
+
fragment: r.fragment
|
|
15564
|
+
}));
|
|
15565
|
+
}
|
|
15247
15566
|
}
|
|
15248
15567
|
const rest = {};
|
|
15249
15568
|
for (const [k, v] of Object.entries(el)) {
|
|
15250
15569
|
if (!consumed.has(k) && k !== "id") {
|
|
15251
15570
|
rest[k] = v;
|
|
15571
|
+
fields[k] = v;
|
|
15252
15572
|
}
|
|
15253
15573
|
}
|
|
15254
15574
|
aspects.structure = canonical(rest);
|
|
15255
|
-
return {
|
|
15575
|
+
return {
|
|
15576
|
+
key: `${field}:${id}`,
|
|
15577
|
+
id,
|
|
15578
|
+
kind: field,
|
|
15579
|
+
tier,
|
|
15580
|
+
aspects,
|
|
15581
|
+
fields,
|
|
15582
|
+
provenance
|
|
15583
|
+
};
|
|
15256
15584
|
}
|
|
15257
15585
|
function elementIndex(standard, duplicates) {
|
|
15258
15586
|
const out = /* @__PURE__ */ new Map();
|
|
@@ -15490,6 +15818,46 @@ function labelAspect(elA, elB, name) {
|
|
|
15490
15818
|
}
|
|
15491
15819
|
return `${name} (changed)`;
|
|
15492
15820
|
}
|
|
15821
|
+
var isPlainObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
15822
|
+
function fieldDiffPaths(prefix, a, b, out) {
|
|
15823
|
+
if (isPlainObject(a) && isPlainObject(b)) {
|
|
15824
|
+
const keys = [.../* @__PURE__ */ new Set([...Object.keys(a), ...Object.keys(b)])].sort();
|
|
15825
|
+
for (const k of keys) {
|
|
15826
|
+
fieldDiffPaths(`${prefix}.${k}`, a[k], b[k], out);
|
|
15827
|
+
}
|
|
15828
|
+
return;
|
|
15829
|
+
}
|
|
15830
|
+
if (canonical(a) !== canonical(b)) {
|
|
15831
|
+
out.push(prefix);
|
|
15832
|
+
}
|
|
15833
|
+
}
|
|
15834
|
+
function changedFields(elA, elB) {
|
|
15835
|
+
const names = [
|
|
15836
|
+
.../* @__PURE__ */ new Set([...Object.keys(elA.fields), ...Object.keys(elB.fields)])
|
|
15837
|
+
].sort();
|
|
15838
|
+
const out = [];
|
|
15839
|
+
for (const name of names) {
|
|
15840
|
+
fieldDiffPaths(name, elA.fields[name], elB.fields[name], out);
|
|
15841
|
+
}
|
|
15842
|
+
const PROVENANCE_CHANNELS = [
|
|
15843
|
+
"source",
|
|
15844
|
+
"sourceRef",
|
|
15845
|
+
"sourceRefs",
|
|
15846
|
+
"reference"
|
|
15847
|
+
];
|
|
15848
|
+
const seenMoves = /* @__PURE__ */ new Set();
|
|
15849
|
+
return out.filter((path) => {
|
|
15850
|
+
if (!PROVENANCE_CHANNELS.includes(path)) {
|
|
15851
|
+
return true;
|
|
15852
|
+
}
|
|
15853
|
+
const move = canonical(elA.fields[path]) + " \u2192 " + canonical(elB.fields[path]);
|
|
15854
|
+
if (seenMoves.has(move)) {
|
|
15855
|
+
return false;
|
|
15856
|
+
}
|
|
15857
|
+
seenMoves.add(move);
|
|
15858
|
+
return true;
|
|
15859
|
+
});
|
|
15860
|
+
}
|
|
15493
15861
|
function diffStandards(a, b, options = {}) {
|
|
15494
15862
|
const duplicatesA = [];
|
|
15495
15863
|
const duplicatesB = [];
|
|
@@ -15547,7 +15915,8 @@ function diffStandards(a, b, options = {}) {
|
|
|
15547
15915
|
id: elA.id,
|
|
15548
15916
|
kind: elA.kind,
|
|
15549
15917
|
tier: elA.tier,
|
|
15550
|
-
aspects: differing.map((name) => labelAspect(elA, elB, name)).sort()
|
|
15918
|
+
aspects: differing.map((name) => labelAspect(elA, elB, name)).sort(),
|
|
15919
|
+
fields: changedFields(elA, elB)
|
|
15551
15920
|
});
|
|
15552
15921
|
tally[elA.tier].changed++;
|
|
15553
15922
|
}
|
|
@@ -15630,7 +15999,9 @@ function formatDiffReport(diff) {
|
|
|
15630
15999
|
if (diff.changed.length > 0) {
|
|
15631
16000
|
lines.push("", "changed:");
|
|
15632
16001
|
for (const e of diff.changed) {
|
|
15633
|
-
lines.push(
|
|
16002
|
+
lines.push(
|
|
16003
|
+
` ~ ${fmtEntry(e)} \u2014 ${e.aspects.join(", ")} (fields: ${e.fields.join(", ")})`
|
|
16004
|
+
);
|
|
15634
16005
|
}
|
|
15635
16006
|
}
|
|
15636
16007
|
if (diff.moved.length > 0) {
|
|
@@ -16371,6 +16742,22 @@ var CHECK_RULES = [
|
|
|
16371
16742
|
"normal",
|
|
16372
16743
|
"TODO.roadmap/28, INV-8, doctrine \xA713.5"
|
|
16373
16744
|
),
|
|
16745
|
+
// ── the v3.2 lineage edge (TODO.primmel/11; MN 114 v3.2 clause 9.3.1,
|
|
16746
|
+
// primmel/spec#18) ──
|
|
16747
|
+
// C113: the lineage graph is the union of the backward edges
|
|
16748
|
+
// (supersedes/replaces) and the forward edge (superseded_by); when two
|
|
16749
|
+
// composed packages declare opposite edges between the same pair the
|
|
16750
|
+
// declarations must agree — A supersedes { B } while B declares
|
|
16751
|
+
// superseded_by { C } without A is an error. A missing forward edge is
|
|
16752
|
+
// NOT an error: the backward edges remain the authored minimum.
|
|
16753
|
+
R(
|
|
16754
|
+
"C113",
|
|
16755
|
+
"edition-lineage-coherent",
|
|
16756
|
+
"edition",
|
|
16757
|
+
"error",
|
|
16758
|
+
"normal",
|
|
16759
|
+
"TODO.primmel/11, MN 114 clause 9.3.1 (primmel/spec#18 ask 3)"
|
|
16760
|
+
),
|
|
16374
16761
|
// ── the model supply chain (TODO.roadmap/36, doctrine ch. 15) ───────
|
|
16375
16762
|
// Three publishers — standard (reference), manufacturer (product
|
|
16376
16763
|
// reference), user (implementation) — with mapping as the only
|
|
@@ -16710,6 +17097,108 @@ var CHECK_RULES = [
|
|
|
16710
17097
|
"normal",
|
|
16711
17098
|
"docs/primmel/18 \xA718.6 (the unified reference/relation construct)"
|
|
16712
17099
|
),
|
|
17100
|
+
// ── the v3.2 consumption constructs (TODO.primmel/11; MN 114 v3.2,
|
|
17101
|
+
// primmel/spec#18) ──
|
|
17102
|
+
// C110: the term alias family's shape (clause 13.10.1) — duplicate
|
|
17103
|
+
// entries within one list are errors; the same string in two family
|
|
17104
|
+
// fields of one term and the label echo are warning legs during the
|
|
17105
|
+
// v3.2 rollout (the v2 `alt` semantics allowed the overlap; the
|
|
17106
|
+
// cross-field leg tightens to the spec's error when the consumer wave
|
|
17107
|
+
// re-authors the estate's terms — TODO.primmel/11d).
|
|
17108
|
+
R(
|
|
17109
|
+
"C110",
|
|
17110
|
+
"term-alias-shape",
|
|
17111
|
+
"base",
|
|
17112
|
+
"error",
|
|
17113
|
+
"normal",
|
|
17114
|
+
"TODO.primmel/11, MN 114 clause 13.10.1 (primmel/spec#18 ask 1)"
|
|
17115
|
+
),
|
|
17116
|
+
// C111: the dimension declaration's shape (clause 10.6) — value ids
|
|
17117
|
+
// unique within a dimension, implies targets resolving inside their
|
|
17118
|
+
// own dimension and acyclic, values vs values_of never combined, an
|
|
17119
|
+
// undocumented values_of register warned, and one dimension identifier
|
|
17120
|
+
// once per applicability namespace (the is_dimension-attribute/inline
|
|
17121
|
+
// mirror pattern tolerated — R 144's power_supply precedent).
|
|
17122
|
+
R(
|
|
17123
|
+
"C111",
|
|
17124
|
+
"dimension-shape",
|
|
17125
|
+
"base",
|
|
17126
|
+
"error",
|
|
17127
|
+
"normal",
|
|
17128
|
+
"TODO.primmel/11, MN 114 clause 10.6 (primmel/spec#18 ask 2)"
|
|
17129
|
+
),
|
|
17130
|
+
// C112: the structured reference identity (clause 14.7) — a malformed
|
|
17131
|
+
// urn is an error (the same well-formedness class as C85); a reference
|
|
17132
|
+
// carrying neither urn nor the org+document pair is a warning (a
|
|
17133
|
+
// display-string citation is visible debt, never silently citable).
|
|
17134
|
+
R(
|
|
17135
|
+
"C112",
|
|
17136
|
+
"reference-identity",
|
|
17137
|
+
"base",
|
|
17138
|
+
"error",
|
|
17139
|
+
"normal",
|
|
17140
|
+
"TODO.primmel/11, MN 114 clause 14.7 (primmel/spec#18 ask 3)"
|
|
17141
|
+
),
|
|
17142
|
+
// C114: the limit's quantity typing agrees with the verdict it binds
|
|
17143
|
+
// (clause 11.1.2) — a limit and its acceptance chain can never drift
|
|
17144
|
+
// apart in units. C115: the calculation signature (clause 13.7.1) —
|
|
17145
|
+
// units and quantity kinds resolve against the merged quantity register
|
|
17146
|
+
// and agree in kind, a range's min never exceeds its max, and an
|
|
17147
|
+
// enum-typed input declares its values. The unit-resolution leg ships
|
|
17148
|
+
// as a WARNING during the v3.2 rollout (the C33 doctrine §6.8
|
|
17149
|
+
// precedent: unmapped units are warnings — the estate's R 60 declares
|
|
17150
|
+
// counts/v on inputs no register carries; the leg tightens to the
|
|
17151
|
+
// spec's error when the register catches up — TODO.primmel/11d).
|
|
17152
|
+
R(
|
|
17153
|
+
"C114",
|
|
17154
|
+
"limit-quantity-coherence",
|
|
17155
|
+
"quantities",
|
|
17156
|
+
"error",
|
|
17157
|
+
"normal",
|
|
17158
|
+
"TODO.primmel/11, MN 114 clause 11.1.2 (primmel/spec#18 ask 4)"
|
|
17159
|
+
),
|
|
17160
|
+
R(
|
|
17161
|
+
"C115",
|
|
17162
|
+
"calculation-signature-shape",
|
|
17163
|
+
"quantities",
|
|
17164
|
+
"error",
|
|
17165
|
+
"normal",
|
|
17166
|
+
"TODO.primmel/11, MN 114 clause 13.7.1 (primmel/spec#18 ask 4)"
|
|
17167
|
+
),
|
|
17168
|
+
// C116/C117: the verdict chain (clause 11.3) — a verdict's inputs may
|
|
17169
|
+
// name another verdict, making the acceptance chain an explicit graph.
|
|
17170
|
+
// Every input resolves to a declared symbol, a test variable or
|
|
17171
|
+
// observable, or another verdict; the verdict→verdict graph never
|
|
17172
|
+
// cycles. C118: the instance-parameter schema (clause 11.1.3) — a
|
|
17173
|
+
// parameter's bind path resolves against the subject's aspect catalog
|
|
17174
|
+
// (the binds_to path discipline), its unit resolves against the merged
|
|
17175
|
+
// quantity register (the rollout WARNING leg, the C33 §6.8 precedent —
|
|
17176
|
+
// tightens with C115's leg, TODO.primmel/11d), and a range's min never
|
|
17177
|
+
// exceeds its max.
|
|
17178
|
+
R(
|
|
17179
|
+
"C116",
|
|
17180
|
+
"verdict-inputs-resolve",
|
|
17181
|
+
"characteristics",
|
|
17182
|
+
"error",
|
|
17183
|
+
"normal",
|
|
17184
|
+
"TODO.primmel/11, MN 114 clause 11.3 (primmel/spec#18 ask 5)"
|
|
17185
|
+
),
|
|
17186
|
+
R(
|
|
17187
|
+
"C117",
|
|
17188
|
+
"verdict-chain-acyclic",
|
|
17189
|
+
"characteristics",
|
|
17190
|
+
"error",
|
|
17191
|
+
"normal",
|
|
17192
|
+
"TODO.primmel/11, MN 114 clause 11.3 (primmel/spec#18 ask 5)"
|
|
17193
|
+
),
|
|
17194
|
+
R(
|
|
17195
|
+
"C118",
|
|
17196
|
+
"requirement-parameter-shape",
|
|
17197
|
+
"base",
|
|
17198
|
+
"error",
|
|
17199
|
+
"normal",
|
|
17200
|
+
"TODO.primmel/11, MN 114 clause 11.1.3 (primmel/spec#18 ask 5)"
|
|
17201
|
+
),
|
|
16713
17202
|
// ── the dataspace family (TODO.primmel/10; MN 114 v3.1 clause 19) ──
|
|
16714
17203
|
// The v3.1 extension set: the dataspace definition, the policy
|
|
16715
17204
|
// construct (Primmel's own policy grammar; ODRL is a codec output),
|
|
@@ -17500,12 +17989,12 @@ function uncoveredSentenceMessage(urn, s) {
|
|
|
17500
17989
|
const text = s.text.length > 100 ? `${s.text.slice(0, 97)}\u2026` : s.text;
|
|
17501
17990
|
return `sentence ${urn}#${s.address} (normative, ${s.kind}): bound by no model element and excluded by no allowance \u2014 "${text}" (text-coverage-sentence-uncovered)`;
|
|
17502
17991
|
}
|
|
17503
|
-
function packageTextCoverageReport(dir,
|
|
17992
|
+
function packageTextCoverageReport(dir, loadPackage2) {
|
|
17504
17993
|
const { manifests, config, issues } = loadTextCoverageData(dir);
|
|
17505
17994
|
if (manifests.length === 0) {
|
|
17506
17995
|
return null;
|
|
17507
17996
|
}
|
|
17508
|
-
const { standard } =
|
|
17997
|
+
const { standard } = loadPackage2(dir);
|
|
17509
17998
|
const report = computeTextCoverage(standard, manifests, config);
|
|
17510
17999
|
report.configIssues.unshift(...issues);
|
|
17511
18000
|
return report;
|
|
@@ -17720,6 +18209,10 @@ function checkPackage(dir, options = {}) {
|
|
|
17720
18209
|
issues.push(...checkEditionLifecycle(dir, standard));
|
|
17721
18210
|
issues.push(...checkSpellingCodes(standard));
|
|
17722
18211
|
issues.push(...checkDeclaredPredicates(standard));
|
|
18212
|
+
issues.push(...checkTermAliases(standard));
|
|
18213
|
+
issues.push(...checkDimensions(standard));
|
|
18214
|
+
issues.push(...checkReferences(standard));
|
|
18215
|
+
issues.push(...checkVerdictChains(standard));
|
|
17723
18216
|
const reqIds = new Set(
|
|
17724
18217
|
(standard.requirements ?? []).map((r) => r.id)
|
|
17725
18218
|
);
|
|
@@ -17738,6 +18231,7 @@ function checkPackage(dir, options = {}) {
|
|
|
17738
18231
|
const symbolIds = new Set((standard.symbols ?? []).map((s) => s.id));
|
|
17739
18232
|
const dimIds = /* @__PURE__ */ new Map();
|
|
17740
18233
|
const dimCardinality = /* @__PURE__ */ new Map();
|
|
18234
|
+
const dimCardinalityOpen = /* @__PURE__ */ new Set();
|
|
17741
18235
|
for (const inst of standard.instruments ?? []) {
|
|
17742
18236
|
for (const d of inst.dimensions ?? []) {
|
|
17743
18237
|
dimIds.set(d.id, new Set(d.values.map((v) => v.id)));
|
|
@@ -17746,6 +18240,31 @@ function checkPackage(dir, options = {}) {
|
|
|
17746
18240
|
}
|
|
17747
18241
|
}
|
|
17748
18242
|
}
|
|
18243
|
+
for (const a of standard.attributeDefinitions ?? []) {
|
|
18244
|
+
if (a.isDimension !== true || dimIds.has(a.id)) {
|
|
18245
|
+
continue;
|
|
18246
|
+
}
|
|
18247
|
+
const enumDef = (standard.enums ?? []).find((e) => e.id === a.enumRef);
|
|
18248
|
+
const domain = enumDef ? new Set(enumDef.values.map((v) => v.id)) : a.enumValues && a.enumValues.length > 0 ? new Set(a.enumValues) : null;
|
|
18249
|
+
dimIds.set(a.id, domain);
|
|
18250
|
+
dimCardinalityOpen.add(a.id);
|
|
18251
|
+
}
|
|
18252
|
+
for (const d of standard.dimensions ?? []) {
|
|
18253
|
+
if (dimIds.has(d.id)) {
|
|
18254
|
+
continue;
|
|
18255
|
+
}
|
|
18256
|
+
if (d.valuesOf) {
|
|
18257
|
+
dimIds.set(
|
|
18258
|
+
d.id,
|
|
18259
|
+
d.valuesOf === "capabilities" ? new Set((standard.capabilities ?? []).map((c) => c.id)) : null
|
|
18260
|
+
);
|
|
18261
|
+
} else {
|
|
18262
|
+
dimIds.set(d.id, new Set(d.values.map((v) => v.id)));
|
|
18263
|
+
}
|
|
18264
|
+
if (d.cardinality) {
|
|
18265
|
+
dimCardinality.set(d.id, d.cardinality);
|
|
18266
|
+
}
|
|
18267
|
+
}
|
|
17749
18268
|
for (const form of standard.forms ?? []) {
|
|
17750
18269
|
const checkField = (f) => {
|
|
17751
18270
|
if (f.bind) {
|
|
@@ -17876,7 +18395,7 @@ function checkPackage(dir, options = {}) {
|
|
|
17876
18395
|
"C3",
|
|
17877
18396
|
`conformance test ${t.id}: test_subject dimension "${dim}" not declared`
|
|
17878
18397
|
);
|
|
17879
|
-
} else if (!dimIds.get(dim).has(String(value))) {
|
|
18398
|
+
} else if (dimIds.get(dim) !== null && !dimIds.get(dim).has(String(value))) {
|
|
17880
18399
|
err(
|
|
17881
18400
|
"C3",
|
|
17882
18401
|
`conformance test ${t.id}: test_subject ${dim}="${value}" not in the dimension's values`
|
|
@@ -17895,15 +18414,24 @@ function checkPackage(dir, options = {}) {
|
|
|
17895
18414
|
`requirement ${r.id}: applicability dimension "${a.dimension}" not declared`
|
|
17896
18415
|
);
|
|
17897
18416
|
} else {
|
|
18417
|
+
const domain = dimIds.get(a.dimension) ?? null;
|
|
17898
18418
|
for (const v of a.values ?? []) {
|
|
17899
|
-
if (!
|
|
18419
|
+
if (domain !== null && !domain.has(v)) {
|
|
17900
18420
|
err(
|
|
17901
18421
|
"C3",
|
|
17902
18422
|
`requirement ${r.id}: applicability ${a.dimension}="${v}" not in the dimension's values`
|
|
17903
18423
|
);
|
|
17904
18424
|
}
|
|
17905
18425
|
}
|
|
17906
|
-
|
|
18426
|
+
for (const k of Object.keys(a.mapping ?? {})) {
|
|
18427
|
+
if (domain !== null && !domain.has(k)) {
|
|
18428
|
+
err(
|
|
18429
|
+
"C3",
|
|
18430
|
+
`requirement ${r.id}: applicability ${a.dimension} mapping key "${k}" not in the dimension's values`
|
|
18431
|
+
);
|
|
18432
|
+
}
|
|
18433
|
+
}
|
|
18434
|
+
if ((a.match === "all" || a.match === "exact") && dimCardinality.get(a.dimension) !== "set" && !dimCardinalityOpen.has(a.dimension)) {
|
|
17907
18435
|
warn(
|
|
17908
18436
|
"C3",
|
|
17909
18437
|
`requirement ${r.id}: applicability ${a.dimension} match ${a.match} on a single-cardinality dimension \u2014 only meaningful on set dimensions ('all' reduces to 'any'; a multi-value 'exact' is unsatisfiable on one value)`
|
|
@@ -20080,11 +20608,148 @@ function checkPackage(dir, options = {}) {
|
|
|
20080
20608
|
);
|
|
20081
20609
|
}
|
|
20082
20610
|
}
|
|
20083
|
-
for (const
|
|
20084
|
-
|
|
20611
|
+
for (const r of standard.requirements ?? []) {
|
|
20612
|
+
const q = r.limit?.quantity;
|
|
20613
|
+
const accepts = r.limit?.accepts;
|
|
20614
|
+
if (!q || !accepts) {
|
|
20615
|
+
continue;
|
|
20616
|
+
}
|
|
20617
|
+
const verdict = (standard.verdicts ?? []).find(
|
|
20618
|
+
(v) => v.id === accepts.verdict
|
|
20619
|
+
);
|
|
20620
|
+
if (!verdict) {
|
|
20621
|
+
continue;
|
|
20622
|
+
}
|
|
20623
|
+
if (q.kind && verdict.quantityKind && q.kind !== verdict.quantityKind) {
|
|
20085
20624
|
err(
|
|
20086
|
-
"
|
|
20087
|
-
`
|
|
20625
|
+
"C114",
|
|
20626
|
+
`requirement ${r.id}: limit declares quantity kind "${q.kind}" but accepts verdict ${verdict.id} derives kind "${verdict.quantityKind}" \u2014 a limit and its acceptance chain never drift apart in units (limit-quantity-coherence)`
|
|
20627
|
+
);
|
|
20628
|
+
}
|
|
20629
|
+
if (q.unit && verdict.unit && q.unit !== verdict.unit) {
|
|
20630
|
+
err(
|
|
20631
|
+
"C114",
|
|
20632
|
+
`requirement ${r.id}: limit declares quantity unit "${q.unit}" but accepts verdict ${verdict.id} derives unit "${verdict.unit}" (limit-quantity-coherence)`
|
|
20633
|
+
);
|
|
20634
|
+
}
|
|
20635
|
+
}
|
|
20636
|
+
for (const c of standard.calculations ?? []) {
|
|
20637
|
+
const entries = [
|
|
20638
|
+
...(c.inputs ?? []).map((inp) => ({
|
|
20639
|
+
owner: `calculation ${c.id}: input ${inp.name}`,
|
|
20640
|
+
type: inp.type,
|
|
20641
|
+
unit: inp.unit,
|
|
20642
|
+
isInput: true,
|
|
20643
|
+
quantityKind: inp.quantityKind,
|
|
20644
|
+
rangeMin: inp.rangeMin,
|
|
20645
|
+
rangeMax: inp.rangeMax,
|
|
20646
|
+
hasRange: inp.hasRange,
|
|
20647
|
+
enumValues: inp.enumValues
|
|
20648
|
+
})),
|
|
20649
|
+
{
|
|
20650
|
+
owner: `calculation ${c.id}: output`,
|
|
20651
|
+
type: c.output.type,
|
|
20652
|
+
unit: c.output.unit,
|
|
20653
|
+
isInput: false,
|
|
20654
|
+
quantityKind: c.output.quantityKind,
|
|
20655
|
+
rangeMin: c.output.rangeMin,
|
|
20656
|
+
rangeMax: c.output.rangeMax,
|
|
20657
|
+
hasRange: c.output.hasRange
|
|
20658
|
+
}
|
|
20659
|
+
];
|
|
20660
|
+
for (const e of entries) {
|
|
20661
|
+
const declaredUnit = e.unit && e.unit !== "1" ? e.unit : "";
|
|
20662
|
+
const unitKind = declaredUnit ? kindOfUnit(declaredUnit) : void 0;
|
|
20663
|
+
if (declaredUnit && registersExist && unitKind === void 0) {
|
|
20664
|
+
warn(
|
|
20665
|
+
"C115",
|
|
20666
|
+
`${e.owner}: unit "${declaredUnit}" resolves to no registered unit of the merged quantity register (calculation-signature-shape)`
|
|
20667
|
+
);
|
|
20668
|
+
}
|
|
20669
|
+
if (e.quantityKind) {
|
|
20670
|
+
if (!kindDecl.has(e.quantityKind)) {
|
|
20671
|
+
err(
|
|
20672
|
+
"C115",
|
|
20673
|
+
`${e.owner}: quantity_kind "${e.quantityKind}" resolves to no registered kind of the merged quantity register (calculation-signature-shape)`
|
|
20674
|
+
);
|
|
20675
|
+
} else if (unitKind !== void 0 && unitKind !== e.quantityKind) {
|
|
20676
|
+
err(
|
|
20677
|
+
"C115",
|
|
20678
|
+
`${e.owner}: declared quantity_kind "${e.quantityKind}" but unit "${declaredUnit}" measures kind ${unitKind} \u2014 the typed-unit pair must agree in kind (calculation-signature-shape)`
|
|
20679
|
+
);
|
|
20680
|
+
}
|
|
20681
|
+
}
|
|
20682
|
+
if (e.hasRange && e.rangeMin && e.rangeMax) {
|
|
20683
|
+
const lo = Number(e.rangeMin);
|
|
20684
|
+
const hi = Number(e.rangeMax);
|
|
20685
|
+
if (!Number.isNaN(lo) && !Number.isNaN(hi) && lo > hi) {
|
|
20686
|
+
err(
|
|
20687
|
+
"C115",
|
|
20688
|
+
`${e.owner}: range min ${e.rangeMin} exceeds max ${e.rangeMax} (calculation-signature-shape)`
|
|
20689
|
+
);
|
|
20690
|
+
}
|
|
20691
|
+
}
|
|
20692
|
+
if (e.isInput && e.type === "enum" && (e.enumValues === void 0 || e.enumValues.length === 0)) {
|
|
20693
|
+
err(
|
|
20694
|
+
"C115",
|
|
20695
|
+
`${e.owner}: an enum-typed input declares its values \u2014 enum_values is absent or empty (calculation-signature-shape)`
|
|
20696
|
+
);
|
|
20697
|
+
}
|
|
20698
|
+
}
|
|
20699
|
+
}
|
|
20700
|
+
for (const r of standard.requirements ?? []) {
|
|
20701
|
+
for (const p of r.parameters ?? []) {
|
|
20702
|
+
const where = `requirement ${r.id}: param ${p.name}`;
|
|
20703
|
+
if (p.bind) {
|
|
20704
|
+
const parts = String(p.bind).split(".");
|
|
20705
|
+
const id = parts[2];
|
|
20706
|
+
if (id) {
|
|
20707
|
+
if (parts[1] === "classification") {
|
|
20708
|
+
const dim = DIM_ALIASES[id] ?? id;
|
|
20709
|
+
if (!dimIds.has(dim) && !attrIds.has(id) && !attrIds.has(dim)) {
|
|
20710
|
+
err(
|
|
20711
|
+
"C118",
|
|
20712
|
+
`${where}: bind "${p.bind}" \u2014 dimension "${id}" not declared (requirement-parameter-shape)`
|
|
20713
|
+
);
|
|
20714
|
+
}
|
|
20715
|
+
} else if (parts[1] === "behaviors") {
|
|
20716
|
+
if (!behaviorIds.has(id)) {
|
|
20717
|
+
err(
|
|
20718
|
+
"C118",
|
|
20719
|
+
`${where}: bind "${p.bind}" \u2014 behavior "${id}" not declared (requirement-parameter-shape)`
|
|
20720
|
+
);
|
|
20721
|
+
}
|
|
20722
|
+
} else if (!isIdentityPath(String(p.bind)) && !attrIds.has(id) && !symbolIds.has(id)) {
|
|
20723
|
+
err(
|
|
20724
|
+
"C118",
|
|
20725
|
+
`${where}: bind "${p.bind}" \u2014 attribute "${id}" not defined (requirement-parameter-shape)`
|
|
20726
|
+
);
|
|
20727
|
+
}
|
|
20728
|
+
}
|
|
20729
|
+
}
|
|
20730
|
+
if (p.unit && registersExist && kindOfUnit(p.unit) === void 0) {
|
|
20731
|
+
warn(
|
|
20732
|
+
"C118",
|
|
20733
|
+
`${where}: unit "${p.unit}" resolves to no registered unit of the merged quantity register (requirement-parameter-shape)`
|
|
20734
|
+
);
|
|
20735
|
+
}
|
|
20736
|
+
if (p.hasRange && p.rangeMin && p.rangeMax) {
|
|
20737
|
+
const lo = Number(p.rangeMin);
|
|
20738
|
+
const hi = Number(p.rangeMax);
|
|
20739
|
+
if (!Number.isNaN(lo) && !Number.isNaN(hi) && lo > hi) {
|
|
20740
|
+
err(
|
|
20741
|
+
"C118",
|
|
20742
|
+
`${where}: range min ${p.rangeMin} exceeds max ${p.rangeMax} (requirement-parameter-shape)`
|
|
20743
|
+
);
|
|
20744
|
+
}
|
|
20745
|
+
}
|
|
20746
|
+
}
|
|
20747
|
+
}
|
|
20748
|
+
for (const d of standard.duals ?? []) {
|
|
20749
|
+
if (d.attribute && !attrIds.has(d.attribute)) {
|
|
20750
|
+
err(
|
|
20751
|
+
"C34",
|
|
20752
|
+
`dual ${d.id}: attribute "${d.attribute}" is not a declared attribute_definition (duality-coherence)`
|
|
20088
20753
|
);
|
|
20089
20754
|
}
|
|
20090
20755
|
if (!d.designed && !d.exhibited) {
|
|
@@ -21486,6 +22151,216 @@ function checkDeclaredPredicates(standard) {
|
|
|
21486
22151
|
}
|
|
21487
22152
|
return issues;
|
|
21488
22153
|
}
|
|
22154
|
+
function checkTermAliases(standard) {
|
|
22155
|
+
const issues = [];
|
|
22156
|
+
const err = (message) => issues.push({ check: "C110", severity: "error", message });
|
|
22157
|
+
const warn = (message) => issues.push({ check: "C110", severity: "warning", message });
|
|
22158
|
+
const FACETS = ["aliases", "colloquial", "abbreviations", "deprecated"];
|
|
22159
|
+
for (const t of standard.terms ?? []) {
|
|
22160
|
+
const scopes = [
|
|
22161
|
+
[
|
|
22162
|
+
"",
|
|
22163
|
+
{
|
|
22164
|
+
aliases: t.aliases ?? t.alt,
|
|
22165
|
+
colloquial: t.colloquial,
|
|
22166
|
+
abbreviations: t.abbreviations,
|
|
22167
|
+
deprecated: t.deprecated
|
|
22168
|
+
}
|
|
22169
|
+
],
|
|
22170
|
+
...Object.entries(t.aliasSpellings ?? {}).map(
|
|
22171
|
+
([code, v]) => [
|
|
22172
|
+
` ${code}`,
|
|
22173
|
+
{ ...v }
|
|
22174
|
+
]
|
|
22175
|
+
)
|
|
22176
|
+
];
|
|
22177
|
+
for (const [tag, scope] of scopes) {
|
|
22178
|
+
const where = (facet) => `term ${t.id}: ${facet}${tag ? ` ${tag}` : ""}`;
|
|
22179
|
+
for (const facet of FACETS) {
|
|
22180
|
+
const seen = /* @__PURE__ */ new Set();
|
|
22181
|
+
for (const entry of scope[facet] ?? []) {
|
|
22182
|
+
if (seen.has(entry)) {
|
|
22183
|
+
err(
|
|
22184
|
+
`${where(facet)}: duplicate entry "${entry}" \u2014 one entry has one home (term-alias-shape)`
|
|
22185
|
+
);
|
|
22186
|
+
}
|
|
22187
|
+
seen.add(entry);
|
|
22188
|
+
}
|
|
22189
|
+
}
|
|
22190
|
+
const home = /* @__PURE__ */ new Map();
|
|
22191
|
+
for (const facet of FACETS) {
|
|
22192
|
+
for (const entry of scope[facet] ?? []) {
|
|
22193
|
+
const prior = home.get(entry);
|
|
22194
|
+
if (prior !== void 0 && prior !== facet) {
|
|
22195
|
+
warn(
|
|
22196
|
+
`${where(facet)}: "${entry}" already appears in ${prior} \u2014 one entry has one home (term-alias-shape)`
|
|
22197
|
+
);
|
|
22198
|
+
} else {
|
|
22199
|
+
home.set(entry, facet);
|
|
22200
|
+
}
|
|
22201
|
+
}
|
|
22202
|
+
}
|
|
22203
|
+
}
|
|
22204
|
+
if (t.label) {
|
|
22205
|
+
for (const [tag, scope] of scopes) {
|
|
22206
|
+
for (const facet of FACETS) {
|
|
22207
|
+
if ((scope[facet] ?? []).includes(t.label)) {
|
|
22208
|
+
warn(
|
|
22209
|
+
`term ${t.id}: ${facet}${tag ? ` ${tag}` : ""} entry "${t.label}" merely echoes the term's label \u2014 an alias adds a bridge or it does not belong (term-alias-shape)`
|
|
22210
|
+
);
|
|
22211
|
+
}
|
|
22212
|
+
}
|
|
22213
|
+
}
|
|
22214
|
+
}
|
|
22215
|
+
}
|
|
22216
|
+
return issues;
|
|
22217
|
+
}
|
|
22218
|
+
function checkDimensions(standard) {
|
|
22219
|
+
const issues = [];
|
|
22220
|
+
const err = (message) => issues.push({ check: "C111", severity: "error", message });
|
|
22221
|
+
const warn = (message) => issues.push({ check: "C111", severity: "warning", message });
|
|
22222
|
+
const checkShape = (owner, d) => {
|
|
22223
|
+
const seen = /* @__PURE__ */ new Set();
|
|
22224
|
+
for (const v of d.values) {
|
|
22225
|
+
if (seen.has(v.id)) {
|
|
22226
|
+
err(
|
|
22227
|
+
`${owner} dimension ${d.id}: duplicate value id "${v.id}" (dimension-shape)`
|
|
22228
|
+
);
|
|
22229
|
+
}
|
|
22230
|
+
seen.add(v.id);
|
|
22231
|
+
}
|
|
22232
|
+
const valueIds = new Set(d.values.map((v) => v.id));
|
|
22233
|
+
const adj = /* @__PURE__ */ new Map();
|
|
22234
|
+
for (const v of d.values) {
|
|
22235
|
+
for (const target of v.implies ?? []) {
|
|
22236
|
+
if (!valueIds.has(target)) {
|
|
22237
|
+
err(
|
|
22238
|
+
`${owner} dimension ${d.id}: value ${v.id} implies "${target}", which is not a value of this dimension \u2014 implies targets resolve inside their own dimension (dimension-shape)`
|
|
22239
|
+
);
|
|
22240
|
+
}
|
|
22241
|
+
}
|
|
22242
|
+
adj.set(
|
|
22243
|
+
v.id,
|
|
22244
|
+
(v.implies ?? []).filter((t) => valueIds.has(t))
|
|
22245
|
+
);
|
|
22246
|
+
}
|
|
22247
|
+
const cycle = findCycle(adj);
|
|
22248
|
+
if (cycle) {
|
|
22249
|
+
err(
|
|
22250
|
+
`${owner} dimension ${d.id}: implies cycle ${cycle.join(" \u2192 ")} \u2014 the applicability engine walks the implication closure, so the graph must be acyclic (dimension-shape)`
|
|
22251
|
+
);
|
|
22252
|
+
}
|
|
22253
|
+
if (d.valuesOf && d.values.length > 0) {
|
|
22254
|
+
err(
|
|
22255
|
+
`${owner} dimension ${d.id}: declares both values and values_of \u2014 a dimension carries one value domain (dimension-shape)`
|
|
22256
|
+
);
|
|
22257
|
+
}
|
|
22258
|
+
if (d.valuesOf && d.valuesOf !== "capabilities") {
|
|
22259
|
+
warn(
|
|
22260
|
+
`${owner} dimension ${d.id}: values_of "${d.valuesOf}" names a register the kernel does not document (the documented register is capabilities) \u2014 the value domain stays open (dimension-shape)`
|
|
22261
|
+
);
|
|
22262
|
+
}
|
|
22263
|
+
};
|
|
22264
|
+
for (const inst of standard.instruments ?? []) {
|
|
22265
|
+
for (const d of inst.dimensions ?? []) {
|
|
22266
|
+
checkShape(`instrument ${inst.id}:`, d);
|
|
22267
|
+
}
|
|
22268
|
+
}
|
|
22269
|
+
for (const d of standard.dimensions ?? []) {
|
|
22270
|
+
checkShape("top-level", d);
|
|
22271
|
+
}
|
|
22272
|
+
const inlineHome = /* @__PURE__ */ new Map();
|
|
22273
|
+
for (const inst of standard.instruments ?? []) {
|
|
22274
|
+
for (const d of inst.dimensions ?? []) {
|
|
22275
|
+
const prior = inlineHome.get(d.id);
|
|
22276
|
+
if (prior !== void 0 && prior !== inst.id) {
|
|
22277
|
+
err(
|
|
22278
|
+
`dimension ${d.id}: declared inline on both instrument ${prior} and instrument ${inst.id} \u2014 one dimension identifier once per applicability namespace (dimension-shape)`
|
|
22279
|
+
);
|
|
22280
|
+
} else {
|
|
22281
|
+
inlineHome.set(d.id, inst.id);
|
|
22282
|
+
}
|
|
22283
|
+
}
|
|
22284
|
+
}
|
|
22285
|
+
const attrDims = new Set(
|
|
22286
|
+
(standard.attributeDefinitions ?? []).filter((a) => a.isDimension === true).map((a) => a.id)
|
|
22287
|
+
);
|
|
22288
|
+
for (const d of standard.dimensions ?? []) {
|
|
22289
|
+
if (inlineHome.has(d.id)) {
|
|
22290
|
+
err(
|
|
22291
|
+
`dimension ${d.id}: declared both top-level and inline on instrument ${inlineHome.get(d.id)} \u2014 one dimension identifier once per applicability namespace (dimension-shape)`
|
|
22292
|
+
);
|
|
22293
|
+
}
|
|
22294
|
+
if (attrDims.has(d.id)) {
|
|
22295
|
+
err(
|
|
22296
|
+
`dimension ${d.id}: declared both top-level and as the is_dimension attribute definition of the same id \u2014 one dimension identifier once per applicability namespace (dimension-shape)`
|
|
22297
|
+
);
|
|
22298
|
+
}
|
|
22299
|
+
}
|
|
22300
|
+
return issues;
|
|
22301
|
+
}
|
|
22302
|
+
function checkReferences(standard) {
|
|
22303
|
+
const issues = [];
|
|
22304
|
+
for (const r of standard.references ?? []) {
|
|
22305
|
+
if (r.urn !== void 0) {
|
|
22306
|
+
if (!/^[A-Za-z][A-Za-z0-9+.-]*:[^\s<>"{}|^`\\]*$/.test(r.urn)) {
|
|
22307
|
+
issues.push({
|
|
22308
|
+
check: "C112",
|
|
22309
|
+
severity: "error",
|
|
22310
|
+
message: `reference ${r.id}: urn "${r.urn}" is not a well-formed IRI (a scheme followed by no whitespace or IRI delimiters) (reference-identity)`
|
|
22311
|
+
});
|
|
22312
|
+
}
|
|
22313
|
+
} else if (!(r.org && r.document)) {
|
|
22314
|
+
issues.push({
|
|
22315
|
+
check: "C112",
|
|
22316
|
+
severity: "warning",
|
|
22317
|
+
message: `reference ${r.id}: carries neither urn nor the org-and-document pair \u2014 a display-string citation is not machine-traversable (reference-identity)`
|
|
22318
|
+
});
|
|
22319
|
+
}
|
|
22320
|
+
}
|
|
22321
|
+
return issues;
|
|
22322
|
+
}
|
|
22323
|
+
function checkVerdictChains(standard) {
|
|
22324
|
+
const issues = [];
|
|
22325
|
+
const symbolIds = new Set((standard.symbols ?? []).map((s) => s.id));
|
|
22326
|
+
const testNames = /* @__PURE__ */ new Set();
|
|
22327
|
+
for (const t of standard.conformanceTests ?? []) {
|
|
22328
|
+
for (const v of t.variables ?? []) {
|
|
22329
|
+
testNames.add(v.name);
|
|
22330
|
+
}
|
|
22331
|
+
for (const o of t.observables ?? []) {
|
|
22332
|
+
testNames.add(o.name);
|
|
22333
|
+
}
|
|
22334
|
+
}
|
|
22335
|
+
const verdictIds = new Set((standard.verdicts ?? []).map((v) => v.id));
|
|
22336
|
+
for (const v of standard.verdicts ?? []) {
|
|
22337
|
+
for (const inp of v.inputs ?? []) {
|
|
22338
|
+
if (!symbolIds.has(inp) && !testNames.has(inp) && !verdictIds.has(inp)) {
|
|
22339
|
+
issues.push({
|
|
22340
|
+
check: "C116",
|
|
22341
|
+
severity: "error",
|
|
22342
|
+
message: `verdict ${v.id}: input "${inp}" resolves to no declared symbol, test variable or observable, or verdict (verdict-inputs-resolve)`
|
|
22343
|
+
});
|
|
22344
|
+
}
|
|
22345
|
+
}
|
|
22346
|
+
}
|
|
22347
|
+
const adj = /* @__PURE__ */ new Map();
|
|
22348
|
+
for (const v of standard.verdicts ?? []) {
|
|
22349
|
+
adj.set(
|
|
22350
|
+
v.id,
|
|
22351
|
+
(v.inputs ?? []).filter((i) => verdictIds.has(i))
|
|
22352
|
+
);
|
|
22353
|
+
}
|
|
22354
|
+
const cycle = findCycle(adj);
|
|
22355
|
+
if (cycle) {
|
|
22356
|
+
issues.push({
|
|
22357
|
+
check: "C117",
|
|
22358
|
+
severity: "error",
|
|
22359
|
+
message: `verdict chain cycle: ${cycle.join(" \u2192 ")} \u2014 the acceptance chain is a graph a consumer traverses, so it must be acyclic (verdict-chain-acyclic)`
|
|
22360
|
+
});
|
|
22361
|
+
}
|
|
22362
|
+
return issues;
|
|
22363
|
+
}
|
|
21489
22364
|
function checkEditionLifecycle(dir, standard) {
|
|
21490
22365
|
const issues = [];
|
|
21491
22366
|
const err = (check, message) => issues.push({ check, severity: "error", message });
|
|
@@ -21541,7 +22416,10 @@ function checkEditionLifecycle(dir, standard) {
|
|
|
21541
22416
|
}
|
|
21542
22417
|
const relations = [
|
|
21543
22418
|
...(m.supersedes ?? []).map((t) => ["supersedes", t]),
|
|
21544
|
-
...(m.replaces ?? []).map((t) => ["replaces", t])
|
|
22419
|
+
...(m.replaces ?? []).map((t) => ["replaces", t]),
|
|
22420
|
+
...(m.supersededBy ?? []).map(
|
|
22421
|
+
(t) => ["superseded_by", t]
|
|
22422
|
+
)
|
|
21545
22423
|
];
|
|
21546
22424
|
const ownBasis = normalizeSourceRef(m.baseUrn ?? "", "").basis;
|
|
21547
22425
|
for (const [rel, target] of relations) {
|
|
@@ -21560,7 +22438,7 @@ function checkEditionLifecycle(dir, standard) {
|
|
|
21560
22438
|
continue;
|
|
21561
22439
|
}
|
|
21562
22440
|
const tNorm = normalizeSourceRef(target, "");
|
|
21563
|
-
if (tNorm.basis === ownBasis && tNorm.edition) {
|
|
22441
|
+
if (rel !== "superseded_by" && tNorm.basis === ownBasis && tNorm.edition) {
|
|
21564
22442
|
if (!register.has(tNorm.edition)) {
|
|
21565
22443
|
warn(
|
|
21566
22444
|
"C79",
|
|
@@ -21571,6 +22449,7 @@ function checkEditionLifecycle(dir, standard) {
|
|
|
21571
22449
|
}
|
|
21572
22450
|
if (relations.length > 0) {
|
|
21573
22451
|
const nodes = /* @__PURE__ */ new Map();
|
|
22452
|
+
const forwardByNode = /* @__PURE__ */ new Map();
|
|
21574
22453
|
const parent = dirname2(resolve4(dir));
|
|
21575
22454
|
for (const entry of readdirSync3(parent).sort()) {
|
|
21576
22455
|
const full = join4(parent, entry);
|
|
@@ -21586,6 +22465,7 @@ function checkEditionLifecycle(dir, standard) {
|
|
|
21586
22465
|
),
|
|
21587
22466
|
...(sib.replaces ?? []).map((t) => ["replaces", t])
|
|
21588
22467
|
]);
|
|
22468
|
+
forwardByNode.set(key, new Set(sib.supersededBy ?? []));
|
|
21589
22469
|
} catch {
|
|
21590
22470
|
}
|
|
21591
22471
|
}
|
|
@@ -21603,6 +22483,29 @@ function checkEditionLifecycle(dir, standard) {
|
|
|
21603
22483
|
`supersedes cycle: ${cycle.join(" \u2192 ")} \u2014 the supersedes graph must be acyclic; a package cannot supersede itself through a chain (edition-supersedes-resolves)`
|
|
21604
22484
|
);
|
|
21605
22485
|
}
|
|
22486
|
+
const ownKey = m.baseUrn || m.id;
|
|
22487
|
+
for (const target of [...m.supersedes ?? [], ...m.replaces ?? []]) {
|
|
22488
|
+
const fwd = forwardByNode.get(target);
|
|
22489
|
+
if (fwd !== void 0 && fwd.size > 0 && !fwd.has(ownKey)) {
|
|
22490
|
+
err(
|
|
22491
|
+
"C113",
|
|
22492
|
+
`package "${m.id}": supersedes/replaces ${target}, but that package declares superseded_by { ${[...fwd].join(" ")} } without ${ownKey} \u2014 opposite lineage edges between the same pair must agree (edition-lineage-coherent)`
|
|
22493
|
+
);
|
|
22494
|
+
}
|
|
22495
|
+
}
|
|
22496
|
+
for (const target of m.supersededBy ?? []) {
|
|
22497
|
+
const bwdRels = nodes.get(target);
|
|
22498
|
+
if (bwdRels === void 0) {
|
|
22499
|
+
continue;
|
|
22500
|
+
}
|
|
22501
|
+
const bwd = new Set(bwdRels.map(([, t]) => t));
|
|
22502
|
+
if (bwd.size > 0 && !bwd.has(ownKey)) {
|
|
22503
|
+
err(
|
|
22504
|
+
"C113",
|
|
22505
|
+
`package "${m.id}": superseded_by ${target}, but that package declares supersedes/replaces { ${[...bwd].join(" ")} } without ${ownKey} \u2014 opposite lineage edges between the same pair must agree (edition-lineage-coherent)`
|
|
22506
|
+
);
|
|
22507
|
+
}
|
|
22508
|
+
}
|
|
21606
22509
|
}
|
|
21607
22510
|
if (register.size > 0) {
|
|
21608
22511
|
for (const inst of standard.instances ?? []) {
|
|
@@ -22715,7 +23618,7 @@ function exportStandardRdf(standard) {
|
|
|
22715
23618
|
);
|
|
22716
23619
|
}
|
|
22717
23620
|
t(eIri, SKOSXL_PREF_LABEL, iri(prefIri));
|
|
22718
|
-
(term.alt ?? []).forEach((a, i) => {
|
|
23621
|
+
(term.aliases ?? term.alt ?? []).forEach((a, i) => {
|
|
22719
23622
|
const form = (term.abbreviations ?? []).includes(a) ? "abbreviation" : "";
|
|
22720
23623
|
t(eIri, SKOSXL_ALT_LABEL, iri(labelNode(`alt-${i + 1}`, form, a)));
|
|
22721
23624
|
});
|
|
@@ -22930,61 +23833,1100 @@ function renderJsonLd(prefixes, triples) {
|
|
|
22930
23833
|
`;
|
|
22931
23834
|
}
|
|
22932
23835
|
|
|
22933
|
-
// src/
|
|
22934
|
-
import {
|
|
22935
|
-
import {
|
|
22936
|
-
|
|
22937
|
-
|
|
22938
|
-
|
|
22939
|
-
|
|
22940
|
-
|
|
22941
|
-
|
|
23836
|
+
// src/export/retrieval.ts
|
|
23837
|
+
import { createHash } from "node:crypto";
|
|
23838
|
+
import { readdirSync as readdirSync4, readFileSync as readFileSync6, statSync as statSync3 } from "node:fs";
|
|
23839
|
+
import { join as join5, relative } from "node:path";
|
|
23840
|
+
var RETRIEVAL_PROJECTION = "primmel-retrieval/1";
|
|
23841
|
+
var RETRIEVAL_FACET_VERSION = "retrieval-facet/1";
|
|
23842
|
+
function sortDeep(v) {
|
|
23843
|
+
if (Array.isArray(v)) {
|
|
23844
|
+
return v.map(sortDeep);
|
|
23845
|
+
}
|
|
23846
|
+
if (v && typeof v === "object") {
|
|
23847
|
+
const out = {};
|
|
23848
|
+
for (const k of Object.keys(v).sort()) {
|
|
23849
|
+
const val = sortDeep(v[k]);
|
|
23850
|
+
if (val !== void 0) {
|
|
23851
|
+
out[k] = val;
|
|
22942
23852
|
}
|
|
22943
|
-
profiles.push(
|
|
22944
|
-
...prmToMapProfiles(loadPrm(readFileSync6(join5(dir, entry), "utf8")))
|
|
22945
|
-
);
|
|
22946
23853
|
}
|
|
22947
|
-
}
|
|
22948
|
-
const modelId = standard.packageManifest?.id ?? standard.meta?.namespace ?? "";
|
|
22949
|
-
return profiles.flatMap((p) => mappingsFromProfile(p, modelId));
|
|
22950
|
-
}
|
|
22951
|
-
function packageClauseTexts(dir) {
|
|
22952
|
-
const out = /* @__PURE__ */ new Map();
|
|
22953
|
-
const prdDir = join5(dir, "sources-prd");
|
|
22954
|
-
if (!existsSync6(prdDir)) {
|
|
22955
23854
|
return out;
|
|
22956
23855
|
}
|
|
22957
|
-
|
|
22958
|
-
|
|
22959
|
-
|
|
22960
|
-
|
|
22961
|
-
|
|
22962
|
-
|
|
22963
|
-
|
|
22964
|
-
|
|
23856
|
+
return v;
|
|
23857
|
+
}
|
|
23858
|
+
function canonicalJson(value) {
|
|
23859
|
+
return JSON.stringify(sortDeep(value));
|
|
23860
|
+
}
|
|
23861
|
+
function retrievalDigest(value) {
|
|
23862
|
+
return createHash("sha256").update(canonicalJson(value), "utf8").digest("hex");
|
|
23863
|
+
}
|
|
23864
|
+
function* walkPackage(dir) {
|
|
23865
|
+
for (const entry of readdirSync4(dir).sort()) {
|
|
23866
|
+
if (entry === ".DS_Store") {
|
|
22965
23867
|
continue;
|
|
22966
23868
|
}
|
|
22967
|
-
const
|
|
22968
|
-
if (
|
|
22969
|
-
|
|
23869
|
+
const p = join5(dir, entry);
|
|
23870
|
+
if (statSync3(p).isDirectory()) {
|
|
23871
|
+
yield* walkPackage(p);
|
|
23872
|
+
} else {
|
|
23873
|
+
yield p;
|
|
22970
23874
|
}
|
|
22971
|
-
|
|
22972
|
-
|
|
22973
|
-
|
|
22974
|
-
|
|
22975
|
-
|
|
23875
|
+
}
|
|
23876
|
+
}
|
|
23877
|
+
function packageSourceHash(dir) {
|
|
23878
|
+
const h = createHash("sha256");
|
|
23879
|
+
for (const file of walkPackage(dir)) {
|
|
23880
|
+
h.update(relative(dir, file));
|
|
23881
|
+
h.update("\0");
|
|
23882
|
+
h.update(createHash("sha256").update(readFileSync6(file)).digest());
|
|
23883
|
+
h.update("\n");
|
|
23884
|
+
}
|
|
23885
|
+
return h.digest("hex");
|
|
23886
|
+
}
|
|
23887
|
+
var UUID_ANCHOR = /^_?[0-9a-f]{8}-[0-9a-f]{4}-/i;
|
|
23888
|
+
var DOC_FRAGMENT2 = /#([^#]*)$/;
|
|
23889
|
+
function normalizeClause(doc, clause, fragment = "") {
|
|
23890
|
+
let rest = doc ?? "";
|
|
23891
|
+
let clauseOut = clause ?? "";
|
|
23892
|
+
let frag = fragment ?? "";
|
|
23893
|
+
let anchor;
|
|
23894
|
+
const hash = DOC_FRAGMENT2.exec(rest);
|
|
23895
|
+
if (hash) {
|
|
23896
|
+
rest = rest.slice(0, hash.index);
|
|
23897
|
+
const embedded = hash[1] ?? "";
|
|
23898
|
+
if (!clauseOut && embedded.startsWith("clause-")) {
|
|
23899
|
+
const tail = embedded.slice("clause-".length);
|
|
23900
|
+
const slash = tail.indexOf("/");
|
|
23901
|
+
if (slash >= 0) {
|
|
23902
|
+
clauseOut = tail.slice(0, slash);
|
|
23903
|
+
if (!frag) {
|
|
23904
|
+
frag = tail.slice(slash + 1);
|
|
23905
|
+
}
|
|
23906
|
+
} else {
|
|
23907
|
+
clauseOut = tail;
|
|
22976
23908
|
}
|
|
22977
|
-
|
|
23909
|
+
} else if (embedded && !frag) {
|
|
23910
|
+
anchor = embedded;
|
|
23911
|
+
} else if (embedded) {
|
|
23912
|
+
anchor = embedded;
|
|
22978
23913
|
}
|
|
22979
|
-
|
|
22980
|
-
|
|
23914
|
+
}
|
|
23915
|
+
if (clauseOut && UUID_ANCHOR.test(clauseOut)) {
|
|
23916
|
+
anchor = anchor ?? clauseOut;
|
|
23917
|
+
clauseOut = "";
|
|
23918
|
+
}
|
|
23919
|
+
const urn = rest + (clauseOut ? `#clause-${clauseOut}${frag ? `/${frag}` : ""}` : anchor && !UUID_ANCHOR.test(anchor) ? `#${anchor}` : "");
|
|
23920
|
+
const out = { doc: rest, clause: clauseOut, urn };
|
|
23921
|
+
if (anchor !== void 0) {
|
|
23922
|
+
out.anchor = anchor;
|
|
23923
|
+
}
|
|
23924
|
+
if (frag) {
|
|
23925
|
+
out.fragment = frag;
|
|
23926
|
+
}
|
|
23927
|
+
return out;
|
|
23928
|
+
}
|
|
23929
|
+
function refTargetClause(target) {
|
|
23930
|
+
const m = /^(urn:[^#]+)(?:#(.+))?$/.exec(target);
|
|
23931
|
+
if (!m) {
|
|
23932
|
+
return null;
|
|
23933
|
+
}
|
|
23934
|
+
return { doc: m[1], clause: "", fragment: m[2] ?? "" };
|
|
23935
|
+
}
|
|
23936
|
+
function collectClauses(el) {
|
|
23937
|
+
const out = [];
|
|
23938
|
+
const seen = /* @__PURE__ */ new Set();
|
|
23939
|
+
const push = (r) => {
|
|
23940
|
+
if (!r || !r.doc && !r.clause) {
|
|
23941
|
+
return;
|
|
23942
|
+
}
|
|
23943
|
+
const c = normalizeClause(r.doc ?? "", r.clause ?? "", r.fragment);
|
|
23944
|
+
if (!seen.has(c.urn)) {
|
|
23945
|
+
seen.add(c.urn);
|
|
23946
|
+
out.push(c);
|
|
23947
|
+
}
|
|
23948
|
+
};
|
|
23949
|
+
push(el.source);
|
|
23950
|
+
push(el.sourceRef);
|
|
23951
|
+
for (const r of el.sourceRefs ?? []) {
|
|
23952
|
+
push(r);
|
|
23953
|
+
}
|
|
23954
|
+
const reference = (el.reference ?? "").replace(/^"|"$/g, "");
|
|
23955
|
+
if (reference.startsWith("urn:")) {
|
|
23956
|
+
push(refTargetClause(reference));
|
|
23957
|
+
}
|
|
23958
|
+
for (const r of el.refs ?? []) {
|
|
23959
|
+
if (r && typeof r.target === "string" && r.target.startsWith("urn:")) {
|
|
23960
|
+
push(refTargetClause(r.target));
|
|
22981
23961
|
}
|
|
22982
23962
|
}
|
|
22983
23963
|
return out;
|
|
22984
23964
|
}
|
|
22985
|
-
function
|
|
22986
|
-
const
|
|
22987
|
-
|
|
23965
|
+
function termClauses(term, baseUrn) {
|
|
23966
|
+
const out = [];
|
|
23967
|
+
const seen = /* @__PURE__ */ new Set();
|
|
23968
|
+
const push = (c) => {
|
|
23969
|
+
if (c && !seen.has(c.urn)) {
|
|
23970
|
+
seen.add(c.urn);
|
|
23971
|
+
out.push(c);
|
|
23972
|
+
}
|
|
23973
|
+
};
|
|
23974
|
+
for (const token of (term.source ?? "").split(/\s+/).filter((t) => t)) {
|
|
23975
|
+
push(token.startsWith("urn:") ? normalizeClause(token, "") : null);
|
|
23976
|
+
}
|
|
23977
|
+
if (term.section && !out.some((c) => c.clause)) {
|
|
23978
|
+
push(normalizeClause(baseUrn, term.section));
|
|
23979
|
+
}
|
|
23980
|
+
return out;
|
|
23981
|
+
}
|
|
23982
|
+
function applicabilitySummary(entries) {
|
|
23983
|
+
return (entries ?? []).map((e) => {
|
|
23984
|
+
const mode = e.match && e.match !== "any" ? `(${e.match})` : "";
|
|
23985
|
+
return `${e.dimension}${mode}=${[...e.values].sort().join("|")}`;
|
|
23986
|
+
}).sort().join(";");
|
|
23987
|
+
}
|
|
23988
|
+
function passportOf(unit) {
|
|
23989
|
+
return {
|
|
23990
|
+
v: 1,
|
|
23991
|
+
kind: unit.kind,
|
|
23992
|
+
id: unit.id,
|
|
23993
|
+
text: unit.statement ?? unit.definition ?? unit.name ?? "",
|
|
23994
|
+
expression: unit.expression ?? "",
|
|
23995
|
+
units: unit.units ?? [],
|
|
23996
|
+
applicability: applicabilitySummary(unit.applicability),
|
|
23997
|
+
acceptance: unit.acceptance ?? "",
|
|
23998
|
+
provenance: (unit.clauses ?? []).map((c) => c.urn),
|
|
23999
|
+
content_hash: unit.content_hash
|
|
24000
|
+
};
|
|
24001
|
+
}
|
|
24002
|
+
var BASE_URN_PARTS = /^urn:oiml:pub:([rdbge]):(\d[\d-]*)(?::(\d{4}))?$/i;
|
|
24003
|
+
function retrievalDocParts(baseUrn) {
|
|
24004
|
+
const m = BASE_URN_PARTS.exec(baseUrn);
|
|
24005
|
+
if (!m) {
|
|
24006
|
+
return { doctype: "", doc_number: "", year: "", label: "" };
|
|
24007
|
+
}
|
|
24008
|
+
const doctype = (m[1] ?? "").toLowerCase();
|
|
24009
|
+
const docNumber = m[2] ?? "";
|
|
24010
|
+
const year = m[3] ?? "";
|
|
24011
|
+
return {
|
|
24012
|
+
doctype,
|
|
24013
|
+
doc_number: docNumber,
|
|
24014
|
+
year,
|
|
24015
|
+
label: `OIML ${doctype.toUpperCase()} ${docNumber}${year ? `:${year}` : ""}`
|
|
24016
|
+
};
|
|
24017
|
+
}
|
|
24018
|
+
function retrievalFacet(unit, pkg) {
|
|
24019
|
+
const parts = retrievalDocParts(pkg.base_urn);
|
|
24020
|
+
const facet = {
|
|
24021
|
+
unit_id: unit.id,
|
|
24022
|
+
unit_hash: unit.content_hash,
|
|
24023
|
+
block: unit.kind,
|
|
24024
|
+
doc_id: pkg.id,
|
|
24025
|
+
docidentifier: parts.label || pkg.title,
|
|
24026
|
+
doctype: parts.doctype,
|
|
24027
|
+
doc_number: parts.doc_number,
|
|
24028
|
+
edition: pkg.edition,
|
|
24029
|
+
model_version: pkg.model_version,
|
|
24030
|
+
language: pkg.default_spelling,
|
|
24031
|
+
clause_anchor: unit.clause?.clause ?? "",
|
|
24032
|
+
clause_title: unit.name ?? unit.id,
|
|
24033
|
+
...present(pkg.status) ? { status: pkg.status } : {}
|
|
24034
|
+
};
|
|
24035
|
+
const valuesByDim = /* @__PURE__ */ new Map();
|
|
24036
|
+
const matchByDim = /* @__PURE__ */ new Map();
|
|
24037
|
+
for (const entry of unit.applicability ?? []) {
|
|
24038
|
+
const values = entry.values.length > 0 ? entry.values : Object.keys(entry.mapping ?? {});
|
|
24039
|
+
const set = valuesByDim.get(entry.dimension) ?? /* @__PURE__ */ new Set();
|
|
24040
|
+
for (const v of values) {
|
|
24041
|
+
set.add(v);
|
|
24042
|
+
}
|
|
24043
|
+
valuesByDim.set(entry.dimension, set);
|
|
24044
|
+
if (entry.match && entry.match !== "any" && !matchByDim.has(entry.dimension)) {
|
|
24045
|
+
matchByDim.set(entry.dimension, entry.match);
|
|
24046
|
+
}
|
|
24047
|
+
}
|
|
24048
|
+
for (const dim of [...valuesByDim.keys()].sort()) {
|
|
24049
|
+
facet[`app_${dim}`] = [...valuesByDim.get(dim)].sort().join("|");
|
|
24050
|
+
const match = matchByDim.get(dim);
|
|
24051
|
+
if (match) {
|
|
24052
|
+
facet[`app_${dim}_match`] = match;
|
|
24053
|
+
}
|
|
24054
|
+
}
|
|
24055
|
+
return facet;
|
|
24056
|
+
}
|
|
24057
|
+
function resolveTextAddress(address, elementIds) {
|
|
24058
|
+
const segments = address.split(".");
|
|
24059
|
+
if (segments.length < 2 || segments.some((s) => s === "")) {
|
|
24060
|
+
return null;
|
|
24061
|
+
}
|
|
24062
|
+
for (let i = segments.length - 1; i >= 1; i--) {
|
|
24063
|
+
const candidate = segments.slice(0, i).join(".");
|
|
24064
|
+
if (elementIds.has(candidate)) {
|
|
24065
|
+
return { elementId: candidate, path: segments.slice(i).join(".") };
|
|
24066
|
+
}
|
|
24067
|
+
}
|
|
24068
|
+
return null;
|
|
24069
|
+
}
|
|
24070
|
+
var TEXT_ADDRESS_COLLECTIONS = [
|
|
24071
|
+
"requirements",
|
|
24072
|
+
"requirementClasses",
|
|
24073
|
+
"conformanceTests",
|
|
24074
|
+
"conformanceClasses",
|
|
24075
|
+
"terms",
|
|
24076
|
+
"forms",
|
|
24077
|
+
"subforms",
|
|
24078
|
+
"symbols",
|
|
24079
|
+
"tables",
|
|
24080
|
+
"calculations",
|
|
24081
|
+
"notes",
|
|
24082
|
+
"provisions",
|
|
24083
|
+
"processes",
|
|
24084
|
+
"instruments",
|
|
24085
|
+
"attributeDefinitions",
|
|
24086
|
+
"capabilities",
|
|
24087
|
+
"behaviors",
|
|
24088
|
+
"conditionSets",
|
|
24089
|
+
"subjects",
|
|
24090
|
+
"referenceMaterials",
|
|
24091
|
+
"artifactDefinitions",
|
|
24092
|
+
"monitors",
|
|
24093
|
+
"passports",
|
|
24094
|
+
"invariants",
|
|
24095
|
+
"testSequences",
|
|
24096
|
+
"formulasUsed",
|
|
24097
|
+
"stateMachines",
|
|
24098
|
+
"figures",
|
|
24099
|
+
"links"
|
|
24100
|
+
];
|
|
24101
|
+
function attachVariants(built, standard, pkg) {
|
|
24102
|
+
if (present(pkg.default_spelling)) {
|
|
24103
|
+
for (const b of built) {
|
|
24104
|
+
b.content.language = pkg.default_spelling;
|
|
24105
|
+
}
|
|
24106
|
+
}
|
|
24107
|
+
const texts = standard.texts ?? [];
|
|
24108
|
+
if (texts.length === 0) {
|
|
24109
|
+
return 0;
|
|
24110
|
+
}
|
|
24111
|
+
const registry = /* @__PURE__ */ new Set();
|
|
24112
|
+
for (const field of TEXT_ADDRESS_COLLECTIONS) {
|
|
24113
|
+
for (const item of standard[field] ?? []) {
|
|
24114
|
+
if (item?.id) {
|
|
24115
|
+
registry.add(item.id);
|
|
24116
|
+
}
|
|
24117
|
+
}
|
|
24118
|
+
}
|
|
24119
|
+
const unitByElement = new Map(built.map((b) => [b.elementId, b.content]));
|
|
24120
|
+
let dropped = 0;
|
|
24121
|
+
for (const t of texts) {
|
|
24122
|
+
const resolved = resolveTextAddress(t.id, registry);
|
|
24123
|
+
const content = resolved ? unitByElement.get(resolved.elementId) : void 0;
|
|
24124
|
+
if (!resolved || !content) {
|
|
24125
|
+
dropped++;
|
|
24126
|
+
continue;
|
|
24127
|
+
}
|
|
24128
|
+
const variants = content.variants ??= {};
|
|
24129
|
+
variants[resolved.path] = [
|
|
24130
|
+
...variants[resolved.path] ?? [],
|
|
24131
|
+
...t.entries
|
|
24132
|
+
];
|
|
24133
|
+
}
|
|
24134
|
+
return dropped;
|
|
24135
|
+
}
|
|
24136
|
+
function assemble(content, clauses) {
|
|
24137
|
+
if (clauses.length > 0) {
|
|
24138
|
+
content.clause = clauses[0];
|
|
24139
|
+
content.clauses = clauses;
|
|
24140
|
+
}
|
|
24141
|
+
return content;
|
|
24142
|
+
}
|
|
24143
|
+
function completeUnit(content, pkg) {
|
|
24144
|
+
const hash = retrievalDigest(content);
|
|
24145
|
+
const unit = {
|
|
24146
|
+
...content,
|
|
24147
|
+
content_hash: hash
|
|
24148
|
+
};
|
|
24149
|
+
unit.passport = passportOf(unit);
|
|
24150
|
+
unit.facet = retrievalFacet(unit, pkg);
|
|
24151
|
+
return unit;
|
|
24152
|
+
}
|
|
24153
|
+
function scopeOf(id) {
|
|
24154
|
+
const slash = id.lastIndexOf("/");
|
|
24155
|
+
return slash > 0 ? id.slice(0, slash) : void 0;
|
|
24156
|
+
}
|
|
24157
|
+
var present = (s) => typeof s === "string" && s.length > 0;
|
|
24158
|
+
var presentList = (xs) => xs && xs.length > 0 ? xs : void 0;
|
|
24159
|
+
function requirementUnit(r) {
|
|
24160
|
+
return assemble(
|
|
24161
|
+
{
|
|
24162
|
+
id: r.id,
|
|
24163
|
+
kind: "requirement",
|
|
24164
|
+
...scopeOf(r.id) ? { class: scopeOf(r.id) } : {},
|
|
24165
|
+
...present(r.name) ? { name: r.name } : {},
|
|
24166
|
+
...present(r.statement) ? { statement: r.statement } : {},
|
|
24167
|
+
...present(r.guidance) ? { guidance: r.guidance } : {},
|
|
24168
|
+
...present(r.obligation) ? { obligation: r.obligation } : {},
|
|
24169
|
+
modality: r.limit?.modality || "shall",
|
|
24170
|
+
...r.limit?.expression ? {
|
|
24171
|
+
expression: r.limit.expression,
|
|
24172
|
+
...presentList(r.limit.uses) ? { expression_inputs: r.limit.uses } : {}
|
|
24173
|
+
} : {},
|
|
24174
|
+
...presentList(r.applicability) ? { applicability: r.applicability } : {},
|
|
24175
|
+
...presentList(r.bindsTo) ? { binds_to: r.bindsTo } : {},
|
|
24176
|
+
...r.limit?.accepts ? {
|
|
24177
|
+
acceptance: `${r.limit.accepts.verdict} ${r.limit.accepts.op} ${r.limit.accepts.limit}`
|
|
24178
|
+
} : {},
|
|
24179
|
+
...present(r.acceptanceCriteria) ? { acceptance_criteria: r.acceptanceCriteria } : {},
|
|
24180
|
+
...present(r.verificationMethod) ? {
|
|
24181
|
+
verification: {
|
|
24182
|
+
method: r.verificationMethod,
|
|
24183
|
+
description: r.verificationDescription ?? ""
|
|
24184
|
+
}
|
|
24185
|
+
} : {},
|
|
24186
|
+
...present(r.channel) ? { channel: r.channel } : {},
|
|
24187
|
+
...presentList(r.dependencies) ? { dependencies: r.dependencies } : {}
|
|
24188
|
+
},
|
|
24189
|
+
collectClauses(r)
|
|
24190
|
+
);
|
|
24191
|
+
}
|
|
24192
|
+
function conformanceTestUnit(t) {
|
|
24193
|
+
const payload = {
|
|
24194
|
+
...present(t.kind) ? { test_kind: t.kind } : {},
|
|
24195
|
+
...present(t.methodRef) ? { method_ref: t.methodRef } : {},
|
|
24196
|
+
...presentList(t.preconditions) ? {
|
|
24197
|
+
preconditions: t.preconditions.map((p) => ({
|
|
24198
|
+
id: p.id,
|
|
24199
|
+
check: p.check,
|
|
24200
|
+
description: p.description,
|
|
24201
|
+
on_violation: p.onViolation
|
|
24202
|
+
}))
|
|
24203
|
+
} : {}
|
|
24204
|
+
};
|
|
24205
|
+
return assemble(
|
|
24206
|
+
{
|
|
24207
|
+
id: t.id,
|
|
24208
|
+
kind: "conformance_test",
|
|
24209
|
+
...scopeOf(t.id) ? { class: scopeOf(t.id) } : {},
|
|
24210
|
+
...present(t.name) ? { name: t.name } : {},
|
|
24211
|
+
...present(t.purpose) ? { statement: t.purpose } : {},
|
|
24212
|
+
...present(t.method) ? { definition: t.method } : {},
|
|
24213
|
+
...present(t.guidance) ? { guidance: t.guidance } : {},
|
|
24214
|
+
...present(t.obligation) ? { obligation: t.obligation } : {},
|
|
24215
|
+
...presentList(t.applicability) ? { applicability: t.applicability } : {},
|
|
24216
|
+
...presentList(t.targets) ? { targets: t.targets } : {},
|
|
24217
|
+
...presentList(t.bindsTo) ? { binds_to: t.bindsTo } : {},
|
|
24218
|
+
...present(t.acceptancePassIf) ? { acceptance: t.acceptancePassIf } : present(t.acceptanceCriteriaDescription) ? { acceptance: t.acceptanceCriteriaDescription } : {},
|
|
24219
|
+
...presentList(t.dependencies) ? { dependencies: t.dependencies } : {},
|
|
24220
|
+
...Object.keys(payload).length > 0 ? { payload } : {}
|
|
24221
|
+
},
|
|
24222
|
+
collectClauses(t)
|
|
24223
|
+
);
|
|
24224
|
+
}
|
|
24225
|
+
function termUnit(t, baseUrn) {
|
|
24226
|
+
const payload = {
|
|
24227
|
+
...present(t.section) ? { section: t.section } : {},
|
|
24228
|
+
...present(t.language) ? { language: t.language } : {},
|
|
24229
|
+
...t.vocabRef ? { vocab_ref: t.vocabRef } : {},
|
|
24230
|
+
// The alias family (MN 114 v3.2, clause 13.10.1): the parser folds
|
|
24231
|
+
// the v2 `alt` spelling into the canonical aliases channel; the
|
|
24232
|
+
// payload keeps the deployed `alt` key (contract stability) and adds
|
|
24233
|
+
// the v3.2 facets.
|
|
24234
|
+
...presentList(t.aliases ?? t.alt) ? { alt: t.aliases ?? t.alt } : {},
|
|
24235
|
+
...presentList(t.colloquial) ? { colloquial: t.colloquial } : {},
|
|
24236
|
+
...t.aliasSpellings && Object.keys(t.aliasSpellings).length > 0 ? { alias_spellings: t.aliasSpellings } : {},
|
|
24237
|
+
...presentList(t.abbreviations) ? { abbreviations: t.abbreviations } : {},
|
|
24238
|
+
...presentList(t.seeAlso) ? { see_also: t.seeAlso } : {}
|
|
24239
|
+
};
|
|
24240
|
+
return assemble(
|
|
24241
|
+
{
|
|
24242
|
+
id: `/term/${t.id}`,
|
|
24243
|
+
kind: "term",
|
|
24244
|
+
...present(t.label) ? { name: t.label } : {},
|
|
24245
|
+
...present(t.definition) ? { definition: t.definition } : {},
|
|
24246
|
+
...Object.keys(payload).length > 0 ? { payload } : {}
|
|
24247
|
+
},
|
|
24248
|
+
termClauses(t, baseUrn)
|
|
24249
|
+
);
|
|
24250
|
+
}
|
|
24251
|
+
function attributeUnit(a) {
|
|
24252
|
+
const payload = {
|
|
24253
|
+
...present(a.symbol) ? { symbol: a.symbol } : {},
|
|
24254
|
+
...present(a.quantityKind) ? { quantity_kind: a.quantityKind } : {},
|
|
24255
|
+
...present(a.valueType) ? { value_type: a.valueType } : {},
|
|
24256
|
+
...present(a.origin) ? { origin: a.origin } : {},
|
|
24257
|
+
...present(a.scope) ? { scope: a.scope } : {},
|
|
24258
|
+
...present(a.category) ? { category: a.category } : {},
|
|
24259
|
+
...present(a.irdi) ? { irdi: a.irdi } : {},
|
|
24260
|
+
...presentList(a.enumValues) ? { enum_values: a.enumValues } : {}
|
|
24261
|
+
};
|
|
24262
|
+
return assemble(
|
|
24263
|
+
{
|
|
24264
|
+
id: `/attribute/${a.id}`,
|
|
24265
|
+
kind: "attribute",
|
|
24266
|
+
...present(a.name) ? { name: a.name } : {},
|
|
24267
|
+
...present(a.definition) ? { definition: a.definition } : {},
|
|
24268
|
+
...present(a.unit) && a.unit !== "1" ? { units: [a.unit] } : {},
|
|
24269
|
+
...Object.keys(payload).length > 0 ? { payload } : {}
|
|
24270
|
+
},
|
|
24271
|
+
collectClauses(a)
|
|
24272
|
+
);
|
|
24273
|
+
}
|
|
24274
|
+
function behaviorUnit(b) {
|
|
24275
|
+
const payload = {
|
|
24276
|
+
...present(b.kind) ? { behavior_kind: b.kind } : {},
|
|
24277
|
+
...present(b.stimulus) ? { stimulus: b.stimulus } : {}
|
|
24278
|
+
};
|
|
24279
|
+
return assemble(
|
|
24280
|
+
{
|
|
24281
|
+
id: `/behavior/${b.id}`,
|
|
24282
|
+
kind: "behavior",
|
|
24283
|
+
name: b.id,
|
|
24284
|
+
...present(b.response) ? { statement: b.response } : {},
|
|
24285
|
+
...Object.keys(payload).length > 0 ? { payload } : {}
|
|
24286
|
+
},
|
|
24287
|
+
collectClauses(b)
|
|
24288
|
+
);
|
|
24289
|
+
}
|
|
24290
|
+
function calculationUnits(c) {
|
|
24291
|
+
const out = /* @__PURE__ */ new Set();
|
|
24292
|
+
for (const i of c.inputs ?? []) {
|
|
24293
|
+
if (present(i.unit) && i.unit !== "1") {
|
|
24294
|
+
out.add(i.unit);
|
|
24295
|
+
}
|
|
24296
|
+
}
|
|
24297
|
+
if (c.output && present(c.output.unit) && c.output.unit !== "1") {
|
|
24298
|
+
out.add(c.output.unit);
|
|
24299
|
+
}
|
|
24300
|
+
return [...out].sort();
|
|
24301
|
+
}
|
|
24302
|
+
function calculationUnit(c) {
|
|
24303
|
+
const kind = present(c.ruleType) ? "formula" : "calculation";
|
|
24304
|
+
const units = calculationUnits(c);
|
|
24305
|
+
const payload = {
|
|
24306
|
+
name: c.name,
|
|
24307
|
+
...present(c.ruleType) ? { rule_type: c.ruleType } : {},
|
|
24308
|
+
...present(c.category) ? { category: c.category } : {},
|
|
24309
|
+
...presentList(c.inputs) ? {
|
|
24310
|
+
inputs: c.inputs.map((i) => ({
|
|
24311
|
+
name: i.name,
|
|
24312
|
+
type: i.type,
|
|
24313
|
+
...present(i.unit) ? { unit: i.unit } : {}
|
|
24314
|
+
}))
|
|
24315
|
+
} : {},
|
|
24316
|
+
...c.output && present(c.output.type) ? { output: c.output } : {},
|
|
24317
|
+
...c.lookup ? { lookup: c.lookup } : {},
|
|
24318
|
+
...present(c.profile) ? { profile: c.profile } : {}
|
|
24319
|
+
};
|
|
24320
|
+
return assemble(
|
|
24321
|
+
{
|
|
24322
|
+
id: present(c.identifier) ? c.identifier : `/calculation/${c.id}`,
|
|
24323
|
+
kind,
|
|
24324
|
+
name: c.label || c.name || c.id,
|
|
24325
|
+
...present(c.description) ? { definition: c.description } : {},
|
|
24326
|
+
...present(c.expression) ? { expression: c.expression } : {},
|
|
24327
|
+
...presentList(c.params) ? { expression_inputs: c.params } : {},
|
|
24328
|
+
...units.length > 0 ? { units } : {},
|
|
24329
|
+
payload
|
|
24330
|
+
},
|
|
24331
|
+
collectClauses({
|
|
24332
|
+
sourceRef: c.sourceRef,
|
|
24333
|
+
sourceRefs: c.sourceRefs,
|
|
24334
|
+
refs: c.refs
|
|
24335
|
+
})
|
|
24336
|
+
);
|
|
24337
|
+
}
|
|
24338
|
+
function symbolUnit(s) {
|
|
24339
|
+
const units = present(s.unit) && s.unit !== "1" ? [s.unit] : void 0;
|
|
24340
|
+
const payload = {
|
|
24341
|
+
...present(s.type) ? { symbol_type: s.type } : {},
|
|
24342
|
+
...present(s.kind) ? { symbol_kind: s.kind } : {},
|
|
24343
|
+
...present(s.quantityKind) ? { quantity_kind: s.quantityKind } : {},
|
|
24344
|
+
...present(s.origin) ? { origin: s.origin } : {},
|
|
24345
|
+
...present(s.latex) ? { latex: s.latex } : {},
|
|
24346
|
+
...s.formula && present(s.formula.display) ? { display: s.formula.display } : {},
|
|
24347
|
+
...present(s.calculation) ? { calculation: s.calculation } : {}
|
|
24348
|
+
};
|
|
24349
|
+
return assemble(
|
|
24350
|
+
{
|
|
24351
|
+
id: `/symbol/${s.id}`,
|
|
24352
|
+
kind: "symbol",
|
|
24353
|
+
...present(s.name) ? { name: s.name } : {},
|
|
24354
|
+
...present(s.definition) ? { definition: s.definition } : {},
|
|
24355
|
+
...s.formula && present(s.formula.expression) ? {
|
|
24356
|
+
expression: s.formula.expression,
|
|
24357
|
+
...presentList(s.formula.inputs) ? { expression_inputs: s.formula.inputs } : {}
|
|
24358
|
+
} : {},
|
|
24359
|
+
...units ? { units } : {},
|
|
24360
|
+
...Object.keys(payload).length > 0 ? { payload } : {}
|
|
24361
|
+
},
|
|
24362
|
+
collectClauses({
|
|
24363
|
+
sourceRef: s.sourceRef,
|
|
24364
|
+
sourceRefs: s.sourceRefs,
|
|
24365
|
+
refs: s.refs
|
|
24366
|
+
})
|
|
24367
|
+
);
|
|
24368
|
+
}
|
|
24369
|
+
function constraintUnit(c) {
|
|
24370
|
+
return assemble(
|
|
24371
|
+
{
|
|
24372
|
+
id: `/constraint/${c.id}`,
|
|
24373
|
+
kind: "constraint",
|
|
24374
|
+
...present(c.name) ? { name: c.name } : {},
|
|
24375
|
+
...present(c.violationMeaning) ? { statement: c.violationMeaning } : {},
|
|
24376
|
+
...present(c.check) ? { expression: c.check } : {},
|
|
24377
|
+
payload: {
|
|
24378
|
+
...present(c.stereotype) ? { stereotype: c.stereotype } : {},
|
|
24379
|
+
...present(c.onViolation) ? { on_violation: c.onViolation } : {}
|
|
24380
|
+
}
|
|
24381
|
+
},
|
|
24382
|
+
collectClauses(c)
|
|
24383
|
+
);
|
|
24384
|
+
}
|
|
24385
|
+
function characteristicUnit(v) {
|
|
24386
|
+
const units = present(v.unit) && v.unit !== "1" ? [v.unit] : void 0;
|
|
24387
|
+
const payload = {
|
|
24388
|
+
...present(v.behavior) ? { behavior: v.behavior } : {},
|
|
24389
|
+
...present(v.quantityKind) ? { quantity_kind: v.quantityKind } : {},
|
|
24390
|
+
...v.seriesReduction ? { series_reduction: v.seriesReduction } : {}
|
|
24391
|
+
};
|
|
24392
|
+
return assemble(
|
|
24393
|
+
{
|
|
24394
|
+
id: `/characteristic/${v.id}`,
|
|
24395
|
+
kind: "characteristic",
|
|
24396
|
+
...present(v.symbol) ? { name: v.symbol } : {},
|
|
24397
|
+
...present(v.derive) ? {
|
|
24398
|
+
expression: v.derive,
|
|
24399
|
+
...presentList(v.inputs) ? { expression_inputs: v.inputs } : {}
|
|
24400
|
+
} : {},
|
|
24401
|
+
...units ? { units } : {},
|
|
24402
|
+
...v.acceptance && present(v.acceptance.rule) ? { acceptance: v.acceptance.rule } : {},
|
|
24403
|
+
...Object.keys(payload).length > 0 ? { payload } : {}
|
|
24404
|
+
},
|
|
24405
|
+
collectClauses(v)
|
|
24406
|
+
);
|
|
24407
|
+
}
|
|
24408
|
+
function tableUnit(t) {
|
|
24409
|
+
const units = (t.columnDefs ?? []).map((c) => c.unit).filter((u) => present(u) && u !== "1").sort();
|
|
24410
|
+
const payload = {
|
|
24411
|
+
...presentList(t.columnDefs) ? {
|
|
24412
|
+
columns: t.columnDefs.map((c) => ({
|
|
24413
|
+
name: c.name,
|
|
24414
|
+
type: c.type,
|
|
24415
|
+
...present(c.unit) ? { unit: c.unit } : {}
|
|
24416
|
+
}))
|
|
24417
|
+
} : present(t.columns) ? { columns: t.columns } : {},
|
|
24418
|
+
...presentList(t.data) ? { rows: t.data } : {},
|
|
24419
|
+
...t.profiles ? { profiles: t.profiles } : {}
|
|
24420
|
+
};
|
|
24421
|
+
return assemble(
|
|
24422
|
+
{
|
|
24423
|
+
id: `/table/${t.id}`,
|
|
24424
|
+
kind: "table",
|
|
24425
|
+
...present(t.title) ? { name: t.title } : {},
|
|
24426
|
+
...present(t.description) ? { definition: t.description } : {},
|
|
24427
|
+
...units.length > 0 ? { units: [...new Set(units)] } : {},
|
|
24428
|
+
...Object.keys(payload).length > 0 ? { payload } : {}
|
|
24429
|
+
},
|
|
24430
|
+
collectClauses({
|
|
24431
|
+
sourceRef: t.sourceRef,
|
|
24432
|
+
sourceRefs: t.sourceRefs,
|
|
24433
|
+
refs: t.refs
|
|
24434
|
+
})
|
|
24435
|
+
);
|
|
24436
|
+
}
|
|
24437
|
+
function sequenceUnit(s) {
|
|
24438
|
+
const payload = {
|
|
24439
|
+
steps: s.steps.map((st) => ({
|
|
24440
|
+
order: st.order,
|
|
24441
|
+
...present(st.test) ? { test: st.test } : {},
|
|
24442
|
+
...present(st.phase) ? { phase: st.phase } : {},
|
|
24443
|
+
...present(st.role) ? { role: st.role } : {},
|
|
24444
|
+
...st.dependsOn !== null ? { depends_on: st.dependsOn } : {}
|
|
24445
|
+
})),
|
|
24446
|
+
...present(s.sampleApplicability) ? { sample_applicability: s.sampleApplicability } : {}
|
|
24447
|
+
};
|
|
24448
|
+
return assemble(
|
|
24449
|
+
{
|
|
24450
|
+
id: `/sequence/${s.id}`,
|
|
24451
|
+
kind: "sequence",
|
|
24452
|
+
...present(s.name) ? { name: s.name } : {},
|
|
24453
|
+
...present(s.description) ? { statement: s.description } : {},
|
|
24454
|
+
payload
|
|
24455
|
+
},
|
|
24456
|
+
collectClauses({ sourceRefs: s.sourceRefs, refs: s.refs })
|
|
24457
|
+
);
|
|
24458
|
+
}
|
|
24459
|
+
function noteUnit(n) {
|
|
24460
|
+
return assemble(
|
|
24461
|
+
{
|
|
24462
|
+
id: `/note/${n.id}`,
|
|
24463
|
+
kind: "note",
|
|
24464
|
+
name: n.type,
|
|
24465
|
+
...present(n.message) ? { statement: n.message } : {}
|
|
24466
|
+
},
|
|
24467
|
+
[]
|
|
24468
|
+
);
|
|
24469
|
+
}
|
|
24470
|
+
function stateMachineUnit(m) {
|
|
24471
|
+
const id = m.entityName;
|
|
24472
|
+
const payload = {
|
|
24473
|
+
...present(m.kind) ? { machine_kind: m.kind } : {},
|
|
24474
|
+
...present(m.initialState) ? { initial: m.initialState } : {},
|
|
24475
|
+
...presentList(m.states) ? { states: m.states.map((s) => s.name) } : {},
|
|
24476
|
+
...presentList(m.transitions) ? {
|
|
24477
|
+
transitions: m.transitions.map((t) => ({
|
|
24478
|
+
from: t.from,
|
|
24479
|
+
to: t.to,
|
|
24480
|
+
...present(t.actionName) ? { action: t.actionName } : {},
|
|
24481
|
+
...present(t.guard) ? { guard: t.guard } : {}
|
|
24482
|
+
}))
|
|
24483
|
+
} : {}
|
|
24484
|
+
};
|
|
24485
|
+
return assemble(
|
|
24486
|
+
{
|
|
24487
|
+
id: `/state-machine/${id}`,
|
|
24488
|
+
kind: "state_machine",
|
|
24489
|
+
name: id,
|
|
24490
|
+
...Object.keys(payload).length > 0 ? { payload } : {}
|
|
24491
|
+
},
|
|
24492
|
+
[]
|
|
24493
|
+
);
|
|
24494
|
+
}
|
|
24495
|
+
function dimensionUnit(d) {
|
|
24496
|
+
const payload = {
|
|
24497
|
+
...present(d.scope) ? { scope: d.scope } : {},
|
|
24498
|
+
...present(d.cardinality) ? { cardinality: d.cardinality } : {},
|
|
24499
|
+
values: d.values.map((v) => ({
|
|
24500
|
+
id: v.id,
|
|
24501
|
+
...present(v.label) ? { label: v.label } : {},
|
|
24502
|
+
...presentList(v.implies) ? { implies: v.implies } : {},
|
|
24503
|
+
...present(v.termRef) ? { term_ref: v.termRef } : {}
|
|
24504
|
+
}))
|
|
24505
|
+
};
|
|
24506
|
+
return assemble(
|
|
24507
|
+
{
|
|
24508
|
+
id: `/dimension/${d.id}`,
|
|
24509
|
+
kind: "dimension",
|
|
24510
|
+
...present(d.label) ? { name: d.label } : {},
|
|
24511
|
+
...present(d.description) ? { definition: d.description } : {},
|
|
24512
|
+
payload
|
|
24513
|
+
},
|
|
24514
|
+
collectClauses(d)
|
|
24515
|
+
);
|
|
24516
|
+
}
|
|
24517
|
+
function packageEdition(manifest) {
|
|
24518
|
+
const first = manifest?.editions?.[0];
|
|
24519
|
+
if (present(first)) {
|
|
24520
|
+
return first;
|
|
24521
|
+
}
|
|
24522
|
+
const tail = /:(\d{4})$/.exec(manifest?.baseUrn ?? "");
|
|
24523
|
+
return tail?.[1] ?? "";
|
|
24524
|
+
}
|
|
24525
|
+
function packageBlock(standard) {
|
|
24526
|
+
const m = standard.packageManifest;
|
|
24527
|
+
if (m) {
|
|
24528
|
+
return {
|
|
24529
|
+
id: m.id,
|
|
24530
|
+
title: m.title,
|
|
24531
|
+
kind: m.kind ?? "rec",
|
|
24532
|
+
edition: packageEdition(m),
|
|
24533
|
+
model_version: m.version,
|
|
24534
|
+
editions: [...m.editions ?? []],
|
|
24535
|
+
base_urn: m.baseUrn,
|
|
24536
|
+
...present(m.status) ? { status: m.status } : {},
|
|
24537
|
+
default_spelling: m.defaultSpelling ?? "",
|
|
24538
|
+
spellings: [
|
|
24539
|
+
...m.spellings ?? (m.defaultSpelling ? [m.defaultSpelling] : [])
|
|
24540
|
+
],
|
|
24541
|
+
...presentList(m.supersedes) ? { supersedes: [...m.supersedes] } : {}
|
|
24542
|
+
};
|
|
24543
|
+
}
|
|
24544
|
+
const meta = standard.meta;
|
|
24545
|
+
return {
|
|
24546
|
+
id: meta?.namespace ?? "",
|
|
24547
|
+
title: meta?.title ?? "",
|
|
24548
|
+
kind: "",
|
|
24549
|
+
edition: meta?.edition ?? "",
|
|
24550
|
+
model_version: "",
|
|
24551
|
+
editions: present(meta?.edition) ? [meta.edition] : [],
|
|
24552
|
+
base_urn: "",
|
|
24553
|
+
default_spelling: "",
|
|
24554
|
+
spellings: []
|
|
24555
|
+
};
|
|
24556
|
+
}
|
|
24557
|
+
function exportStandardRetrieval(standard, options = {}) {
|
|
24558
|
+
const pkg = packageBlock(standard);
|
|
24559
|
+
const built = [];
|
|
24560
|
+
const push = (content, elementId) => {
|
|
24561
|
+
built.push({ content, elementId });
|
|
24562
|
+
};
|
|
24563
|
+
for (const r of standard.requirements ?? []) {
|
|
24564
|
+
push(requirementUnit(r), r.id);
|
|
24565
|
+
}
|
|
24566
|
+
for (const t of standard.conformanceTests ?? []) {
|
|
24567
|
+
push(conformanceTestUnit(t), t.id);
|
|
24568
|
+
}
|
|
24569
|
+
for (const t of standard.terms ?? []) {
|
|
24570
|
+
push(termUnit(t, pkg.base_urn), t.id);
|
|
24571
|
+
}
|
|
24572
|
+
for (const a of standard.attributeDefinitions ?? []) {
|
|
24573
|
+
push(attributeUnit(a), a.id);
|
|
24574
|
+
}
|
|
24575
|
+
for (const b of standard.behaviors ?? []) {
|
|
24576
|
+
push(behaviorUnit(b), b.id);
|
|
24577
|
+
}
|
|
24578
|
+
for (const c of standard.calculations ?? []) {
|
|
24579
|
+
push(calculationUnit(c), c.id);
|
|
24580
|
+
}
|
|
24581
|
+
for (const s of standard.symbols ?? []) {
|
|
24582
|
+
push(symbolUnit(s), s.id);
|
|
24583
|
+
}
|
|
24584
|
+
for (const c of standard.constraints ?? []) {
|
|
24585
|
+
push(constraintUnit(c), c.id);
|
|
24586
|
+
}
|
|
24587
|
+
for (const v of standard.verdicts ?? []) {
|
|
24588
|
+
push(characteristicUnit(v), v.id);
|
|
24589
|
+
}
|
|
24590
|
+
for (const t of standard.tables ?? []) {
|
|
24591
|
+
push(tableUnit(t), t.id);
|
|
24592
|
+
}
|
|
24593
|
+
for (const s of standard.testSequences ?? []) {
|
|
24594
|
+
push(sequenceUnit(s), s.id);
|
|
24595
|
+
}
|
|
24596
|
+
for (const n of standard.notes ?? []) {
|
|
24597
|
+
push(noteUnit(n), n.id);
|
|
24598
|
+
}
|
|
24599
|
+
for (const m of standard.stateMachines ?? []) {
|
|
24600
|
+
push(stateMachineUnit(m), m.entityName);
|
|
24601
|
+
}
|
|
24602
|
+
for (const i of standard.instruments ?? []) {
|
|
24603
|
+
for (const d of i.dimensions ?? []) {
|
|
24604
|
+
push(dimensionUnit(d), d.id);
|
|
24605
|
+
}
|
|
24606
|
+
}
|
|
24607
|
+
const droppedTextBlocks = attachVariants(built, standard, pkg);
|
|
24608
|
+
const units = built.map((b) => completeUnit(b.content, pkg));
|
|
24609
|
+
const byKind = {};
|
|
24610
|
+
let withClause = 0;
|
|
24611
|
+
let anchorOnlyProvenance = 0;
|
|
24612
|
+
let nonUrnDocRefs = 0;
|
|
24613
|
+
let withoutProvenance = 0;
|
|
24614
|
+
let withVariants = 0;
|
|
24615
|
+
for (const u of units) {
|
|
24616
|
+
byKind[u.kind] = (byKind[u.kind] ?? 0) + 1;
|
|
24617
|
+
if (u.variants && Object.keys(u.variants).length > 0) {
|
|
24618
|
+
withVariants++;
|
|
24619
|
+
}
|
|
24620
|
+
const clauses = u.clauses ?? [];
|
|
24621
|
+
if (clauses.some((c) => c.clause)) {
|
|
24622
|
+
withClause++;
|
|
24623
|
+
} else if (clauses.length > 0) {
|
|
24624
|
+
anchorOnlyProvenance++;
|
|
24625
|
+
} else {
|
|
24626
|
+
withoutProvenance++;
|
|
24627
|
+
}
|
|
24628
|
+
if (clauses.some((c) => c.doc && !c.doc.startsWith("urn:"))) {
|
|
24629
|
+
nonUrnDocRefs++;
|
|
24630
|
+
}
|
|
24631
|
+
}
|
|
24632
|
+
const document = {
|
|
24633
|
+
projection: RETRIEVAL_PROJECTION,
|
|
24634
|
+
facet_version: RETRIEVAL_FACET_VERSION,
|
|
24635
|
+
package: pkg,
|
|
24636
|
+
...options.sourceHash !== void 0 ? { source_hash: options.sourceHash } : {},
|
|
24637
|
+
units
|
|
24638
|
+
};
|
|
24639
|
+
return {
|
|
24640
|
+
document,
|
|
24641
|
+
json: JSON.stringify(sortDeep(document), null, 2) + "\n",
|
|
24642
|
+
stats: {
|
|
24643
|
+
units: units.length,
|
|
24644
|
+
byKind,
|
|
24645
|
+
withClause,
|
|
24646
|
+
anchorOnlyProvenance,
|
|
24647
|
+
nonUrnDocRefs,
|
|
24648
|
+
withoutProvenance,
|
|
24649
|
+
withVariants,
|
|
24650
|
+
droppedTextBlocks
|
|
24651
|
+
}
|
|
24652
|
+
};
|
|
24653
|
+
}
|
|
24654
|
+
function exportPackageRetrieval(dir) {
|
|
24655
|
+
const { standard } = loadPackageWithIssues(dir);
|
|
24656
|
+
return exportStandardRetrieval(standard, {
|
|
24657
|
+
sourceHash: packageSourceHash(dir)
|
|
24658
|
+
});
|
|
24659
|
+
}
|
|
24660
|
+
|
|
24661
|
+
// src/export/impact.ts
|
|
24662
|
+
var IMPACT_GRAPH_VERSION = "impact-graph/1";
|
|
24663
|
+
function provenanceOf2(el) {
|
|
24664
|
+
const first = el.sourceRefs?.[0] ?? (el.sourceRef && typeof el.sourceRef === "object" ? el.sourceRef : null) ?? (el.source && typeof el.source === "object" ? el.source : null);
|
|
24665
|
+
if (first && (first.doc || first.clause)) {
|
|
24666
|
+
return { source: { doc: first.doc ?? "", clause: first.clause ?? "" } };
|
|
24667
|
+
}
|
|
24668
|
+
const ref = (el.refs ?? []).find((r) => r.predicate === "derives-from");
|
|
24669
|
+
return ref ? { derivesFrom: ref.target } : {};
|
|
24670
|
+
}
|
|
24671
|
+
function impactGraph(standard) {
|
|
24672
|
+
const forward = /* @__PURE__ */ new Map();
|
|
24673
|
+
const add = (element, carrier, kind, facet, target, via) => {
|
|
24674
|
+
if (target === void 0 || target === "") {
|
|
24675
|
+
return;
|
|
24676
|
+
}
|
|
24677
|
+
const edge = { kind, facet, target, ...provenanceOf2(carrier) };
|
|
24678
|
+
if (via !== void 0) {
|
|
24679
|
+
edge.via = via;
|
|
24680
|
+
}
|
|
24681
|
+
const list = forward.get(element);
|
|
24682
|
+
if (list) {
|
|
24683
|
+
list.push(edge);
|
|
24684
|
+
} else {
|
|
24685
|
+
forward.set(element, [edge]);
|
|
24686
|
+
}
|
|
24687
|
+
};
|
|
24688
|
+
const verdictIds = new Set((standard.verdicts ?? []).map((v) => v.id));
|
|
24689
|
+
for (const r of standard.requirements ?? []) {
|
|
24690
|
+
for (const p of r.bindsTo ?? []) {
|
|
24691
|
+
add(r.id, r, "binding", "binds_to", p);
|
|
24692
|
+
}
|
|
24693
|
+
for (const d of r.dependencies ?? []) {
|
|
24694
|
+
add(r.id, r, "prerequisite", "dependencies", d);
|
|
24695
|
+
}
|
|
24696
|
+
if (r.limit?.accepts?.verdict) {
|
|
24697
|
+
add(
|
|
24698
|
+
r.id,
|
|
24699
|
+
r,
|
|
24700
|
+
"acceptance",
|
|
24701
|
+
"limit.accepts.verdict",
|
|
24702
|
+
r.limit.accepts.verdict
|
|
24703
|
+
);
|
|
24704
|
+
}
|
|
24705
|
+
for (const a of r.applicability ?? []) {
|
|
24706
|
+
add(r.id, r, "classification", "applicability", a.dimension);
|
|
24707
|
+
}
|
|
24708
|
+
if (r.channel) {
|
|
24709
|
+
add(r.id, r, "evidence channel", "channel", r.channel);
|
|
24710
|
+
}
|
|
24711
|
+
}
|
|
24712
|
+
for (const t of standard.conformanceTests ?? []) {
|
|
24713
|
+
for (const target of t.targets ?? []) {
|
|
24714
|
+
add(t.id, t, "coverage", "targets", target);
|
|
24715
|
+
}
|
|
24716
|
+
add(
|
|
24717
|
+
t.id,
|
|
24718
|
+
t,
|
|
24719
|
+
"specialization",
|
|
24720
|
+
"inherits_from",
|
|
24721
|
+
t.inheritsFrom || void 0
|
|
24722
|
+
);
|
|
24723
|
+
for (const d of t.dependencies ?? []) {
|
|
24724
|
+
add(t.id, t, "prerequisite", "dependencies", d);
|
|
24725
|
+
}
|
|
24726
|
+
if (t.instances?.by) {
|
|
24727
|
+
add(t.id, t, "instantiation", "instances.by", t.instances.by);
|
|
24728
|
+
}
|
|
24729
|
+
for (const f of t.resultForms ?? []) {
|
|
24730
|
+
add(t.id, t, "evidence view", "result_forms", f);
|
|
24731
|
+
}
|
|
24732
|
+
for (const a of t.producesArtifacts ?? []) {
|
|
24733
|
+
add(t.id, t, "issuance", "produces_artifacts", a);
|
|
24734
|
+
}
|
|
24735
|
+
}
|
|
24736
|
+
for (const v of standard.verdicts ?? []) {
|
|
24737
|
+
for (const inp of v.inputs ?? []) {
|
|
24738
|
+
add(
|
|
24739
|
+
v.id,
|
|
24740
|
+
v,
|
|
24741
|
+
verdictIds.has(inp) ? "acceptance chain" : "derivation",
|
|
24742
|
+
"inputs",
|
|
24743
|
+
inp
|
|
24744
|
+
);
|
|
24745
|
+
}
|
|
24746
|
+
add(v.id, v, "state transition", "behavior", v.behavior || void 0);
|
|
24747
|
+
}
|
|
24748
|
+
for (const c of standard.calculations ?? []) {
|
|
24749
|
+
for (const inp of c.inputs ?? []) {
|
|
24750
|
+
add(c.id, c, "derivation", "inputs", inp.name);
|
|
24751
|
+
}
|
|
24752
|
+
if (c.lookup?.key) {
|
|
24753
|
+
add(c.id, c, "data source", "lookup", c.lookup.key);
|
|
24754
|
+
}
|
|
24755
|
+
add(c.id, c, "data source", "profile", c.profile || void 0);
|
|
24756
|
+
for (const p of c.params ?? []) {
|
|
24757
|
+
add(c.id, c, "parameterization", "params", p);
|
|
24758
|
+
}
|
|
24759
|
+
}
|
|
24760
|
+
for (const f of standard.forms ?? []) {
|
|
24761
|
+
for (const r of f.requirements ?? []) {
|
|
24762
|
+
add(f.id, f, "evidence scope", "requirements", r);
|
|
24763
|
+
}
|
|
24764
|
+
for (const table of f.calculationContext?.tables ?? []) {
|
|
24765
|
+
add(f.id, f, "derivation context", "calculation_context", table);
|
|
24766
|
+
}
|
|
24767
|
+
const fields = (list) => {
|
|
24768
|
+
for (const fld of list ?? []) {
|
|
24769
|
+
add(f.id, f, "binding", "field.bind", fld.bind, fld.name);
|
|
24770
|
+
add(
|
|
24771
|
+
f.id,
|
|
24772
|
+
f,
|
|
24773
|
+
"binding",
|
|
24774
|
+
"field.verdict",
|
|
24775
|
+
fld.verdict || void 0,
|
|
24776
|
+
fld.name
|
|
24777
|
+
);
|
|
24778
|
+
for (const t of fld.targets ?? []) {
|
|
24779
|
+
add(f.id, f, "binding", "field.targets", t, fld.name);
|
|
24780
|
+
}
|
|
24781
|
+
fields(fld.fields);
|
|
24782
|
+
}
|
|
24783
|
+
};
|
|
24784
|
+
fields(f.fields);
|
|
24785
|
+
}
|
|
24786
|
+
for (const fu of standard.formulasUsed ?? []) {
|
|
24787
|
+
for (const formula of fu.formulas ?? []) {
|
|
24788
|
+
add(fu.id, fu, "derivation", "formulas_used", formula);
|
|
24789
|
+
}
|
|
24790
|
+
}
|
|
24791
|
+
const dims = [
|
|
24792
|
+
...standard.dimensions ?? [],
|
|
24793
|
+
...(standard.instruments ?? []).flatMap((i) => i.dimensions ?? [])
|
|
24794
|
+
];
|
|
24795
|
+
for (const d of dims) {
|
|
24796
|
+
for (const v of d.values ?? []) {
|
|
24797
|
+
for (const target of v.implies ?? []) {
|
|
24798
|
+
add(
|
|
24799
|
+
d.id,
|
|
24800
|
+
d,
|
|
24801
|
+
"subsumption",
|
|
24802
|
+
"values.implies",
|
|
24803
|
+
`${d.id}.${target}`,
|
|
24804
|
+
v.id
|
|
24805
|
+
);
|
|
24806
|
+
}
|
|
24807
|
+
}
|
|
24808
|
+
}
|
|
24809
|
+
for (const i of standard.instances ?? []) {
|
|
24810
|
+
add(i.id, {}, "instantiation", "of", i.of);
|
|
24811
|
+
add(i.id, {}, "instantiation", "model", i.model || void 0);
|
|
24812
|
+
add(i.id, {}, "instantiation", "group", i.group || void 0);
|
|
24813
|
+
add(i.id, {}, "instantiation", "family", i.family || void 0);
|
|
24814
|
+
}
|
|
24815
|
+
const m = standard.packageManifest;
|
|
24816
|
+
if (m) {
|
|
24817
|
+
for (const u of m.uses ?? []) {
|
|
24818
|
+
add(m.id, {}, "composition", "uses", u);
|
|
24819
|
+
}
|
|
24820
|
+
for (const mt of m.mapsTo ?? []) {
|
|
24821
|
+
add(m.id, {}, "composition", "maps_to", mt);
|
|
24822
|
+
}
|
|
24823
|
+
for (const s of m.supersedes ?? []) {
|
|
24824
|
+
add(m.id, {}, "edition lineage", "supersedes", s);
|
|
24825
|
+
}
|
|
24826
|
+
for (const s of m.replaces ?? []) {
|
|
24827
|
+
add(m.id, {}, "edition lineage", "replaces", s);
|
|
24828
|
+
}
|
|
24829
|
+
for (const s of m.supersededBy ?? []) {
|
|
24830
|
+
add(m.id, {}, "edition lineage", "superseded_by", s);
|
|
24831
|
+
}
|
|
24832
|
+
}
|
|
24833
|
+
const reverse = {};
|
|
24834
|
+
const forwardObj = {};
|
|
24835
|
+
for (const [element, edges] of [...forward.entries()].sort()) {
|
|
24836
|
+
forwardObj[element] = edges;
|
|
24837
|
+
for (const e of edges) {
|
|
24838
|
+
(reverse[e.target] ??= []).push({ ...e, element });
|
|
24839
|
+
}
|
|
24840
|
+
}
|
|
24841
|
+
return {
|
|
24842
|
+
version: IMPACT_GRAPH_VERSION,
|
|
24843
|
+
package: {
|
|
24844
|
+
id: m?.id ?? "",
|
|
24845
|
+
version: m?.version ?? "",
|
|
24846
|
+
baseUrn: m?.baseUrn ?? ""
|
|
24847
|
+
},
|
|
24848
|
+
forward: forwardObj,
|
|
24849
|
+
reverse
|
|
24850
|
+
};
|
|
24851
|
+
}
|
|
24852
|
+
function exportPackageImpact(dir) {
|
|
24853
|
+
const standard = loadPackage(dir);
|
|
24854
|
+
const graph = impactGraph(standard);
|
|
24855
|
+
const byKind = {};
|
|
24856
|
+
let edges = 0;
|
|
24857
|
+
for (const list of Object.values(graph.forward)) {
|
|
24858
|
+
for (const e of list) {
|
|
24859
|
+
edges++;
|
|
24860
|
+
byKind[e.kind] = (byKind[e.kind] ?? 0) + 1;
|
|
24861
|
+
}
|
|
24862
|
+
}
|
|
24863
|
+
return {
|
|
24864
|
+
graph,
|
|
24865
|
+
json: JSON.stringify(graph, null, 2) + "\n",
|
|
24866
|
+
stats: {
|
|
24867
|
+
edges,
|
|
24868
|
+
elements: Object.keys(graph.forward).length,
|
|
24869
|
+
targets: Object.keys(graph.reverse).length,
|
|
24870
|
+
byKind
|
|
24871
|
+
}
|
|
24872
|
+
};
|
|
24873
|
+
}
|
|
24874
|
+
|
|
24875
|
+
// src/package-diff.ts
|
|
24876
|
+
import { existsSync as existsSync6, readdirSync as readdirSync5, readFileSync as readFileSync7 } from "fs";
|
|
24877
|
+
import { join as join6 } from "path";
|
|
24878
|
+
function packageMappings(dir, standard) {
|
|
24879
|
+
const profiles = [...standard.mapProfiles ?? []];
|
|
24880
|
+
if (existsSync6(dir)) {
|
|
24881
|
+
for (const entry of readdirSync5(dir).sort()) {
|
|
24882
|
+
if (!entry.endsWith(".prm")) {
|
|
24883
|
+
continue;
|
|
24884
|
+
}
|
|
24885
|
+
profiles.push(
|
|
24886
|
+
...prmToMapProfiles(loadPrm(readFileSync7(join6(dir, entry), "utf8")))
|
|
24887
|
+
);
|
|
24888
|
+
}
|
|
24889
|
+
}
|
|
24890
|
+
const modelId = standard.packageManifest?.id ?? standard.meta?.namespace ?? "";
|
|
24891
|
+
return profiles.flatMap((p) => mappingsFromProfile(p, modelId));
|
|
24892
|
+
}
|
|
24893
|
+
function packageClauseTexts(dir) {
|
|
24894
|
+
const out = /* @__PURE__ */ new Map();
|
|
24895
|
+
const prdDir = join6(dir, "sources-prd");
|
|
24896
|
+
if (!existsSync6(prdDir)) {
|
|
24897
|
+
return out;
|
|
24898
|
+
}
|
|
24899
|
+
for (const entry of readdirSync5(prdDir).sort()) {
|
|
24900
|
+
if (!entry.endsWith(".sentences.json")) {
|
|
24901
|
+
continue;
|
|
24902
|
+
}
|
|
24903
|
+
let payload;
|
|
24904
|
+
try {
|
|
24905
|
+
payload = JSON.parse(readFileSync7(join6(prdDir, entry), "utf8"));
|
|
24906
|
+
} catch {
|
|
24907
|
+
continue;
|
|
24908
|
+
}
|
|
24909
|
+
const urn = payload.document?.urn ?? "";
|
|
24910
|
+
if (!urn) {
|
|
24911
|
+
continue;
|
|
24912
|
+
}
|
|
24913
|
+
const basis = normalizeSourceRef(urn, "").basis;
|
|
24914
|
+
const byClause = /* @__PURE__ */ new Map();
|
|
24915
|
+
for (const s of payload.sentences ?? []) {
|
|
24916
|
+
if (!s.clause || s.text === void 0) {
|
|
24917
|
+
continue;
|
|
24918
|
+
}
|
|
24919
|
+
(byClause.get(s.clause) ?? byClause.set(s.clause, []).get(s.clause)).push(s.text);
|
|
24920
|
+
}
|
|
24921
|
+
for (const [clause, texts] of byClause) {
|
|
24922
|
+
out.set(clauseTextKey(basis, clause), texts.join("\n"));
|
|
24923
|
+
}
|
|
24924
|
+
}
|
|
24925
|
+
return out;
|
|
24926
|
+
}
|
|
24927
|
+
function diffPackageDirs(dirA, dirB, options = {}) {
|
|
24928
|
+
const loadedA = loadPackageWithIssues(dirA, {
|
|
24929
|
+
resolvePackage: options.resolvePackage
|
|
22988
24930
|
});
|
|
22989
24931
|
const loadedB = loadPackageWithIssues(dirB, {
|
|
22990
24932
|
resolvePackage: options.resolvePackage
|
|
@@ -23010,18 +24952,18 @@ function diffPackageDirs(dirA, dirB, options = {}) {
|
|
|
23010
24952
|
// scripts/check.mts
|
|
23011
24953
|
var CHECK_USAGE = "Usage: primmel check [--strict] [--audit] [--coverage] [--rules] [--with <pkg-id>=<dir>]\u2026 <package-dir>";
|
|
23012
24954
|
var DIFF_USAGE = "Usage: primmel diff [--json] [--exit-code] [--compare-texts] [--with <pkg-id>=<dir>]\u2026 <a> <b>";
|
|
23013
|
-
var EXPORT_USAGE = "Usage: primmel export reqif|rdf <package-dir> [--out <file>] [--format turtle|jsonld]";
|
|
24955
|
+
var EXPORT_USAGE = "Usage: primmel export reqif|rdf|retrieval|impact <package-dir> [--out <file>] [--format turtle|jsonld]";
|
|
23014
24956
|
function readablePackageDirProblem(target, needsManifest) {
|
|
23015
24957
|
try {
|
|
23016
|
-
if (!
|
|
24958
|
+
if (!statSync4(target).isDirectory()) {
|
|
23017
24959
|
return "not a directory";
|
|
23018
24960
|
}
|
|
23019
|
-
|
|
24961
|
+
readdirSync6(target);
|
|
23020
24962
|
} catch (e) {
|
|
23021
24963
|
const err = e;
|
|
23022
24964
|
return err.code === "ENOENT" ? "no such directory" : err.message;
|
|
23023
24965
|
}
|
|
23024
|
-
if (needsManifest && !existsSync7(
|
|
24966
|
+
if (needsManifest && !existsSync7(join7(target, "package.primmel"))) {
|
|
23025
24967
|
return "no package.primmel found";
|
|
23026
24968
|
}
|
|
23027
24969
|
return null;
|
|
@@ -23180,7 +25122,7 @@ function diffCli(args2) {
|
|
|
23180
25122
|
}
|
|
23181
25123
|
function exportCli(args2) {
|
|
23182
25124
|
const surface = args2[0];
|
|
23183
|
-
if (surface !== "reqif" && surface !== "rdf") {
|
|
25125
|
+
if (surface !== "reqif" && surface !== "rdf" && surface !== "retrieval" && surface !== "impact") {
|
|
23184
25126
|
console.error(EXPORT_USAGE);
|
|
23185
25127
|
process.exit(2);
|
|
23186
25128
|
}
|
|
@@ -23196,7 +25138,7 @@ function exportCli(args2) {
|
|
|
23196
25138
|
process.exit(2);
|
|
23197
25139
|
}
|
|
23198
25140
|
const rdfFormat = values.get("--format") ?? "turtle";
|
|
23199
|
-
if (surface
|
|
25141
|
+
if (surface !== "rdf" && values.has("--format")) {
|
|
23200
25142
|
console.error("--format applies to `primmel export rdf` only");
|
|
23201
25143
|
console.error(EXPORT_USAGE);
|
|
23202
25144
|
process.exit(2);
|
|
@@ -23215,7 +25157,17 @@ function exportCli(args2) {
|
|
|
23215
25157
|
let document;
|
|
23216
25158
|
let summary;
|
|
23217
25159
|
try {
|
|
23218
|
-
if (surface === "
|
|
25160
|
+
if (surface === "impact") {
|
|
25161
|
+
const result = exportPackageImpact(dir);
|
|
25162
|
+
document = result.json;
|
|
25163
|
+
const s = result.stats;
|
|
25164
|
+
summary = `${n(s.edges, "edge", "edges")} (${Object.entries(s.byKind).map(([k, c]) => `${c} ${k}`).join(", ")}), ${n(s.elements, "element", "elements")} declaring, ${n(s.targets, "target", "targets")} indexed`;
|
|
25165
|
+
} else if (surface === "retrieval") {
|
|
25166
|
+
const result = exportPackageRetrieval(dir);
|
|
25167
|
+
document = result.json;
|
|
25168
|
+
const s = result.stats;
|
|
25169
|
+
summary = `${n(s.units, "unit", "units")} (${Object.entries(s.byKind).map(([k, c]) => `${c} ${k}`).join(", ")}), ${n(s.withClause, "unit", "units")} clause-cited` + (s.anchorOnlyProvenance > 0 ? `, ${n(s.anchorOnlyProvenance, "unit", "units")} with anchor-only provenance (ask-1 debt)` : "") + (s.nonUrnDocRefs > 0 ? `, ${n(s.nonUrnDocRefs, "unit", "units")} with legacy non-URN doc refs` : "") + (s.withoutProvenance > 0 ? `, ${n(s.withoutProvenance, "unit", "units")} without provenance` : "") + (s.withVariants > 0 ? `, ${n(s.withVariants, "unit", "units")} with language variants` : "") + (s.droppedTextBlocks > 0 ? `, ${n(s.droppedTextBlocks, "text block", "text blocks")} addressed at unprojected elements (dropped)` : "");
|
|
25170
|
+
} else if (surface === "reqif") {
|
|
23219
25171
|
const result = exportPackageReqif(dir);
|
|
23220
25172
|
document = result.xml;
|
|
23221
25173
|
const s = result.stats;
|