@dsh-triage/core 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +36 -0
- package/dist/messages.js.map +1 -1
- package/dist/outcome.d.ts +143 -0
- package/dist/outcome.d.ts.map +1 -0
- package/dist/outcome.js +376 -0
- package/dist/outcome.js.map +1 -0
- package/dist/upgrade.d.ts +202 -0
- package/dist/upgrade.d.ts.map +1 -0
- package/dist/upgrade.js +538 -0
- package/dist/upgrade.js.map +1 -0
- package/package.json +1 -1
package/dist/outcome.js
ADDED
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local outcome records: the whitelist that proves a record carries no PII.
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS MODULE EXISTS (spec `docs/specs/M5-reflow.md` §3–§5, `T-501`):
|
|
5
|
+
* "we only store the four-state conclusion" is a claim; a whitelist projection that
|
|
6
|
+
* *rejects* the whole line when one unknown key appears is an enforcement. Everything
|
|
7
|
+
* the local store can hold is declared here, and there is exactly one function that
|
|
8
|
+
* decides whether a candidate record is allowed to reach disk (`sanitizeOutcome`) and
|
|
9
|
+
* one that decides whether an existing line may be read back (`assertOutcomeLine`).
|
|
10
|
+
*
|
|
11
|
+
* WHAT THIS MODULE MUST NEVER DO (§12 of the spec, machine-checked by the
|
|
12
|
+
* `outcome-privacy` check of `scripts/gate_governance.mjs`):
|
|
13
|
+
* - no network client of any kind, no `fs`, no clock, no `process.env`;
|
|
14
|
+
* - no randomness: `id` and `at` are injected by the caller, exactly like `generatedAt`
|
|
15
|
+
* in `verdict.ts`;
|
|
16
|
+
* - no repair: a rejected record is rejected, never "cleaned up and written anyway".
|
|
17
|
+
*
|
|
18
|
+
* TIER DISCIPLINE (`ADR-0011` option A): a `LocalPrior` is an *annotation*. It never
|
|
19
|
+
* enters `conclusion` / `confidence` / `evidence[]`, and there is no evidence tier for
|
|
20
|
+
* it (`measured-local` is reused as a label for "this machine measured this before").
|
|
21
|
+
*/
|
|
22
|
+
import { valid } from 'semver';
|
|
23
|
+
import { CONCLUSION_VALUES } from './types.js';
|
|
24
|
+
export const OUTCOME_OS_VALUES = ['win32', 'darwin', 'linux', 'freebsd', 'other'];
|
|
25
|
+
export const OUTCOME_ARCH_VALUES = ['x64', 'arm64', 'ia32', 'other'];
|
|
26
|
+
export const OUTCOME_PROFILE_KIND_VALUES = ['web', 'tui', 'headless', 'unknown'];
|
|
27
|
+
export const OUTCOME_SOURCE_VALUES = ['check', 'probe'];
|
|
28
|
+
export const TIMING_BUCKET_VALUES = ['lt5s', '5to20s', '20to60s', 'gte60s'];
|
|
29
|
+
/** The five evidence tiers, as a value list, so the sanitizer does not have to trust a cast. */
|
|
30
|
+
export const EVIDENCE_TIER_VALUES = ['inferred', 'declared', 'scanned', 'measured-registry', 'measured-local'];
|
|
31
|
+
/** Exactly the keys of {@link OutcomeRecord}. Anything else is an `unknown-field` rejection. */
|
|
32
|
+
const ALLOWED_FIELDS = new Set([
|
|
33
|
+
'schema_version',
|
|
34
|
+
'id',
|
|
35
|
+
'at',
|
|
36
|
+
'source',
|
|
37
|
+
'package',
|
|
38
|
+
'version',
|
|
39
|
+
'dsh_version',
|
|
40
|
+
'os',
|
|
41
|
+
'arch',
|
|
42
|
+
'node_major',
|
|
43
|
+
'profile_kind',
|
|
44
|
+
'conclusion',
|
|
45
|
+
'reason_message_ids',
|
|
46
|
+
'evidence_tiers',
|
|
47
|
+
'probe',
|
|
48
|
+
]);
|
|
49
|
+
const PROBE_FIELDS = new Set(['total_ms_bucket', 'boot_ms_bucket']);
|
|
50
|
+
/** npm's own name grammar (scope-aware), kept literal so a package name containing `/` is legal. */
|
|
51
|
+
const PACKAGE_RE = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;
|
|
52
|
+
const ID_RE = /^[0-9a-f]{32}$/;
|
|
53
|
+
const ISO_UTC_MS_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
|
|
54
|
+
const MESSAGE_ID_RE = /^(admission|collision|registry|runtime|remediation|missing|probe|tool|prior)\.[a-z0-9.-]+$/;
|
|
55
|
+
const MAX_PACKAGE = 214;
|
|
56
|
+
const MAX_VERSION = 64;
|
|
57
|
+
const MAX_REASON_IDS = 12;
|
|
58
|
+
const MAX_TIERS = 8;
|
|
59
|
+
/** One line, 1024 bytes. A defence line, not a formatting preference (§5.5). */
|
|
60
|
+
export const MAX_OUTCOME_BYTES = 1024;
|
|
61
|
+
/**
|
|
62
|
+
* Forbidden shapes, scanned over every final string value (§5.3).
|
|
63
|
+
*
|
|
64
|
+
* WHY the context around `/`: a scoped package name (`@scope/name`) is legal, so a bare
|
|
65
|
+
* separator cannot be the signal. A path needs a drive letter, a leading separator after
|
|
66
|
+
* whitespace/`"`/`=`, a UNC prefix, or a `file://` scheme — those are the shapes that
|
|
67
|
+
* actually carry a username.
|
|
68
|
+
*/
|
|
69
|
+
const FORBIDDEN_SHAPES = [
|
|
70
|
+
/[A-Za-z]:[\\/]/,
|
|
71
|
+
/\\\\[A-Za-z0-9._-]+\\/,
|
|
72
|
+
/(^|[\s"=])\/(Users|home|root|tmp)\//,
|
|
73
|
+
/file:\/\//i,
|
|
74
|
+
/~\//,
|
|
75
|
+
/sk-[A-Za-z0-9]{20,}/,
|
|
76
|
+
/ghp_[A-Za-z0-9]{20,}/,
|
|
77
|
+
/npm_[A-Za-z0-9]{20,}/,
|
|
78
|
+
/bearer\s/i,
|
|
79
|
+
/token=/i,
|
|
80
|
+
];
|
|
81
|
+
function isPlainObject(value) {
|
|
82
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
83
|
+
}
|
|
84
|
+
function hasForbiddenShape(value) {
|
|
85
|
+
return FORBIDDEN_SHAPES.some((pattern) => pattern.test(value));
|
|
86
|
+
}
|
|
87
|
+
/** UTF-8 length without touching a Node-only global (core stays bundle-safe). */
|
|
88
|
+
function utf8Length(value) {
|
|
89
|
+
return new TextEncoder().encode(value).length;
|
|
90
|
+
}
|
|
91
|
+
/** Every final string of the assembled record, so the forbidden-shape scan cannot skip one. */
|
|
92
|
+
function recordStrings(record) {
|
|
93
|
+
const values = [
|
|
94
|
+
record.id,
|
|
95
|
+
record.at,
|
|
96
|
+
record.source,
|
|
97
|
+
record.package,
|
|
98
|
+
record.version,
|
|
99
|
+
record.os,
|
|
100
|
+
record.arch,
|
|
101
|
+
record.profile_kind,
|
|
102
|
+
record.conclusion,
|
|
103
|
+
...record.reason_message_ids,
|
|
104
|
+
...record.evidence_tiers,
|
|
105
|
+
];
|
|
106
|
+
if (record.dsh_version !== null)
|
|
107
|
+
values.push(record.dsh_version);
|
|
108
|
+
if (record.probe !== null) {
|
|
109
|
+
values.push(record.probe.total_ms_bucket);
|
|
110
|
+
if (record.probe.boot_ms_bucket !== null)
|
|
111
|
+
values.push(record.probe.boot_ms_bucket);
|
|
112
|
+
}
|
|
113
|
+
return values;
|
|
114
|
+
}
|
|
115
|
+
/** A string array that is deduplicated AND ascending: order is part of the contract, not noise. */
|
|
116
|
+
function readSortedStrings(value, limit, accept) {
|
|
117
|
+
if (!Array.isArray(value) || value.length > limit)
|
|
118
|
+
return null;
|
|
119
|
+
const out = [];
|
|
120
|
+
for (const [index, item] of value.entries()) {
|
|
121
|
+
if (typeof item !== 'string' || !accept(item))
|
|
122
|
+
return null;
|
|
123
|
+
// Strictly ascending ⇒ sorted AND deduplicated. A caller that hands us an unordered
|
|
124
|
+
// list has already lost the guarantee the gate recomputes, so we refuse instead of sorting.
|
|
125
|
+
if (index > 0) {
|
|
126
|
+
const previous = out[index - 1];
|
|
127
|
+
if (previous === undefined || !(previous < item))
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
out.push(item);
|
|
131
|
+
}
|
|
132
|
+
return out;
|
|
133
|
+
}
|
|
134
|
+
function fail(reason, field) {
|
|
135
|
+
return { ok: false, reason, field };
|
|
136
|
+
}
|
|
137
|
+
const isEnumValue = (values, value) => typeof value === 'string' && values.includes(value);
|
|
138
|
+
/**
|
|
139
|
+
* Project a candidate record onto the whitelist, or refuse it.
|
|
140
|
+
*
|
|
141
|
+
* Order of operations is the contract (§5): unknown keys → value domains → forbidden
|
|
142
|
+
* shapes over the *assembled* record → byte cap. A rejection never mutates the input and
|
|
143
|
+
* never returns a partially cleaned record.
|
|
144
|
+
*/
|
|
145
|
+
export function sanitizeOutcome(input) {
|
|
146
|
+
if (!isPlainObject(input))
|
|
147
|
+
return fail('not-an-object', null);
|
|
148
|
+
// 1. Whitelist projection: an unknown key means the caller already holds data it should
|
|
149
|
+
// not have, so the whole record dies (§5.1). Silently dropping it would hide that path.
|
|
150
|
+
for (const key of Object.keys(input)) {
|
|
151
|
+
if (!ALLOWED_FIELDS.has(key))
|
|
152
|
+
return fail('unknown-field', key);
|
|
153
|
+
}
|
|
154
|
+
if (input['schema_version'] !== 1)
|
|
155
|
+
return fail('value-shape', 'schema_version');
|
|
156
|
+
const id = input['id'];
|
|
157
|
+
if (typeof id !== 'string' || !ID_RE.test(id))
|
|
158
|
+
return fail('value-shape', 'id');
|
|
159
|
+
const at = input['at'];
|
|
160
|
+
if (typeof at !== 'string' || !ISO_UTC_MS_RE.test(at) || Number.isNaN(Date.parse(at))) {
|
|
161
|
+
return fail('bad-timestamp', 'at');
|
|
162
|
+
}
|
|
163
|
+
const source = input['source'];
|
|
164
|
+
if (!isEnumValue(OUTCOME_SOURCE_VALUES, source))
|
|
165
|
+
return fail('value-shape', 'source');
|
|
166
|
+
const packageName = input['package'];
|
|
167
|
+
if (typeof packageName !== 'string' || packageName.length > MAX_PACKAGE || !PACKAGE_RE.test(packageName)) {
|
|
168
|
+
return fail('value-shape', 'package');
|
|
169
|
+
}
|
|
170
|
+
// `+build` would smuggle a build fingerprint into a version string, so it is refused
|
|
171
|
+
// rather than stripped (`semver.valid` keeps it, which is why the check is explicit).
|
|
172
|
+
const version = input['version'];
|
|
173
|
+
if (typeof version !== 'string' ||
|
|
174
|
+
version.length > MAX_VERSION ||
|
|
175
|
+
version.includes('+') ||
|
|
176
|
+
valid(version) === null) {
|
|
177
|
+
return fail('value-shape', 'version');
|
|
178
|
+
}
|
|
179
|
+
const dshVersion = input['dsh_version'];
|
|
180
|
+
if (dshVersion !== null) {
|
|
181
|
+
if (typeof dshVersion !== 'string' || dshVersion.length > MAX_VERSION || valid(dshVersion) === null) {
|
|
182
|
+
return fail('value-shape', 'dsh_version');
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const os = input['os'];
|
|
186
|
+
if (!isEnumValue(OUTCOME_OS_VALUES, os))
|
|
187
|
+
return fail('value-shape', 'os');
|
|
188
|
+
const arch = input['arch'];
|
|
189
|
+
if (!isEnumValue(OUTCOME_ARCH_VALUES, arch))
|
|
190
|
+
return fail('value-shape', 'arch');
|
|
191
|
+
const nodeMajor = input['node_major'];
|
|
192
|
+
if (typeof nodeMajor !== 'number' || !Number.isInteger(nodeMajor) || nodeMajor < 18 || nodeMajor > 99) {
|
|
193
|
+
return fail('value-shape', 'node_major');
|
|
194
|
+
}
|
|
195
|
+
const profileKind = input['profile_kind'];
|
|
196
|
+
if (!isEnumValue(OUTCOME_PROFILE_KIND_VALUES, profileKind))
|
|
197
|
+
return fail('value-shape', 'profile_kind');
|
|
198
|
+
const conclusion = input['conclusion'];
|
|
199
|
+
if (!isEnumValue(CONCLUSION_VALUES, conclusion))
|
|
200
|
+
return fail('value-shape', 'conclusion');
|
|
201
|
+
const reasonIds = readSortedStrings(input['reason_message_ids'], MAX_REASON_IDS, (item) => MESSAGE_ID_RE.test(item));
|
|
202
|
+
if (reasonIds === null)
|
|
203
|
+
return fail('value-shape', 'reason_message_ids');
|
|
204
|
+
const tiers = readSortedStrings(input['evidence_tiers'], MAX_TIERS, (item) => isEnumValue(EVIDENCE_TIER_VALUES, item));
|
|
205
|
+
if (tiers === null)
|
|
206
|
+
return fail('value-shape', 'evidence_tiers');
|
|
207
|
+
const rawProbe = input['probe'];
|
|
208
|
+
let probe = null;
|
|
209
|
+
if (rawProbe !== null) {
|
|
210
|
+
if (!isPlainObject(rawProbe))
|
|
211
|
+
return fail('value-shape', 'probe');
|
|
212
|
+
for (const key of Object.keys(rawProbe)) {
|
|
213
|
+
if (!PROBE_FIELDS.has(key))
|
|
214
|
+
return fail('unknown-field', `probe.${key}`);
|
|
215
|
+
}
|
|
216
|
+
// Only a probe run can carry probe facts; a `check` record with buckets would be a
|
|
217
|
+
// claim about a measurement that never happened.
|
|
218
|
+
if (source !== 'probe')
|
|
219
|
+
return fail('value-shape', 'probe');
|
|
220
|
+
const total = rawProbe['total_ms_bucket'];
|
|
221
|
+
if (!isEnumValue(TIMING_BUCKET_VALUES, total))
|
|
222
|
+
return fail('value-shape', 'probe.total_ms_bucket');
|
|
223
|
+
const boot = rawProbe['boot_ms_bucket'];
|
|
224
|
+
if (boot !== null && !isEnumValue(TIMING_BUCKET_VALUES, boot)) {
|
|
225
|
+
return fail('value-shape', 'probe.boot_ms_bucket');
|
|
226
|
+
}
|
|
227
|
+
probe = { total_ms_bucket: total, boot_ms_bucket: boot };
|
|
228
|
+
}
|
|
229
|
+
const record = {
|
|
230
|
+
schema_version: 1,
|
|
231
|
+
id,
|
|
232
|
+
at,
|
|
233
|
+
source,
|
|
234
|
+
package: packageName,
|
|
235
|
+
version,
|
|
236
|
+
dsh_version: dshVersion,
|
|
237
|
+
os,
|
|
238
|
+
arch,
|
|
239
|
+
node_major: nodeMajor,
|
|
240
|
+
profile_kind: profileKind,
|
|
241
|
+
conclusion,
|
|
242
|
+
reason_message_ids: reasonIds,
|
|
243
|
+
evidence_tiers: tiers,
|
|
244
|
+
probe,
|
|
245
|
+
};
|
|
246
|
+
// 3. Forbidden shapes, over the assembled record (never over the raw input: only what we
|
|
247
|
+
// are about to write matters).
|
|
248
|
+
for (const value of recordStrings(record)) {
|
|
249
|
+
if (hasForbiddenShape(value))
|
|
250
|
+
return fail('value-shape', fieldOfShapeHit(record, value));
|
|
251
|
+
}
|
|
252
|
+
// 5. Byte cap. Free text cannot fit in a record that is capped at one short line.
|
|
253
|
+
if (utf8Length(JSON.stringify(record)) > MAX_OUTCOME_BYTES)
|
|
254
|
+
return fail('too-long', null);
|
|
255
|
+
return { ok: true, record };
|
|
256
|
+
}
|
|
257
|
+
/** Name the field a forbidden shape was found in, so the rejection is actionable. */
|
|
258
|
+
function fieldOfShapeHit(record, value) {
|
|
259
|
+
if (value === record.id)
|
|
260
|
+
return 'id';
|
|
261
|
+
if (value === record.at)
|
|
262
|
+
return 'at';
|
|
263
|
+
if (value === record.package)
|
|
264
|
+
return 'package';
|
|
265
|
+
if (value === record.version)
|
|
266
|
+
return 'version';
|
|
267
|
+
if (value === record.dsh_version)
|
|
268
|
+
return 'dsh_version';
|
|
269
|
+
if (value === record.source)
|
|
270
|
+
return 'source';
|
|
271
|
+
if (value === record.os)
|
|
272
|
+
return 'os';
|
|
273
|
+
if (value === record.arch)
|
|
274
|
+
return 'arch';
|
|
275
|
+
if (value === record.profile_kind)
|
|
276
|
+
return 'profile_kind';
|
|
277
|
+
if (value === record.conclusion)
|
|
278
|
+
return 'conclusion';
|
|
279
|
+
if (record.reason_message_ids.includes(value))
|
|
280
|
+
return 'reason_message_ids';
|
|
281
|
+
if (record.evidence_tiers.includes(value))
|
|
282
|
+
return 'evidence_tiers';
|
|
283
|
+
return 'probe';
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Read back one stored line.
|
|
287
|
+
*
|
|
288
|
+
* WHY A SECOND FUNCTION: reading is where a hand-edited or corrupted library turns into fake
|
|
289
|
+
* evidence. A line that does not validate is dropped by the caller and counted as
|
|
290
|
+
* `rejected_lines`; it is never repaired, and it never aborts the whole read.
|
|
291
|
+
*/
|
|
292
|
+
export function assertOutcomeLine(line) {
|
|
293
|
+
if (typeof line !== 'string' || line.trim() === '')
|
|
294
|
+
return { ok: false, reason: 'not-json', field: null };
|
|
295
|
+
let parsed;
|
|
296
|
+
try {
|
|
297
|
+
parsed = JSON.parse(line);
|
|
298
|
+
}
|
|
299
|
+
catch {
|
|
300
|
+
return { ok: false, reason: 'not-json', field: null };
|
|
301
|
+
}
|
|
302
|
+
const result = sanitizeOutcome(parsed);
|
|
303
|
+
if (!result.ok)
|
|
304
|
+
return result;
|
|
305
|
+
return { ok: true, record: result.record };
|
|
306
|
+
}
|
|
307
|
+
/** The seven-tuple of a record (§2). One definition, so the store, the prior and D4 agree. */
|
|
308
|
+
export function outcomeKeyOf(record) {
|
|
309
|
+
return {
|
|
310
|
+
package: record.package,
|
|
311
|
+
version: record.version,
|
|
312
|
+
dsh: record.dsh_version,
|
|
313
|
+
os: record.os,
|
|
314
|
+
arch: record.arch,
|
|
315
|
+
node_major: record.node_major,
|
|
316
|
+
profile_kind: record.profile_kind,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
/** A key is usable for prior matching only when all seven positions are known (§2, B10). */
|
|
320
|
+
export function isCompleteOutcomeKey(key) {
|
|
321
|
+
return key.dsh !== null && key.profile_kind !== 'unknown';
|
|
322
|
+
}
|
|
323
|
+
export function sameOutcomeKey(left, right) {
|
|
324
|
+
return (left.package === right.package &&
|
|
325
|
+
left.version === right.version &&
|
|
326
|
+
left.dsh === right.dsh &&
|
|
327
|
+
left.os === right.os &&
|
|
328
|
+
left.arch === right.arch &&
|
|
329
|
+
left.node_major === right.node_major &&
|
|
330
|
+
left.profile_kind === right.profile_kind);
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* The local prior for one key: counts, strict majority, agreement.
|
|
334
|
+
*
|
|
335
|
+
* `majority` is a **strict majority** (`counts[majority] * 2 > n`), so a tie - and any
|
|
336
|
+
* plurality that does not exceed half - reads as "no majority" rather than as a winner.
|
|
337
|
+
* Stricter than a plain mode on purpose: this number is shown to a user next to a verdict
|
|
338
|
+
* that it must not influence (`ADR-0011` §4.1), and "2 of 4 said go" is not a majority.
|
|
339
|
+
*
|
|
340
|
+
* Returns `null` when the key is incomplete or `n = 0`, and the caller then omits the whole
|
|
341
|
+
* `prior` key (§10.2: "nothing" must be distinguishable from "empty").
|
|
342
|
+
*/
|
|
343
|
+
export function computeLocalPrior(records, key) {
|
|
344
|
+
if (!isCompleteOutcomeKey(key))
|
|
345
|
+
return null;
|
|
346
|
+
const counts = { go: 0, risky: 0, blocked: 0, unknown: 0 };
|
|
347
|
+
let n = 0;
|
|
348
|
+
for (const record of records) {
|
|
349
|
+
if (!sameOutcomeKey(outcomeKeyOf(record), key))
|
|
350
|
+
continue;
|
|
351
|
+
counts[record.conclusion] += 1;
|
|
352
|
+
n += 1;
|
|
353
|
+
}
|
|
354
|
+
if (n < 1)
|
|
355
|
+
return null;
|
|
356
|
+
let majority = null;
|
|
357
|
+
for (const conclusion of CONCLUSION_VALUES) {
|
|
358
|
+
if (counts[conclusion] * 2 > n)
|
|
359
|
+
majority = conclusion;
|
|
360
|
+
}
|
|
361
|
+
return {
|
|
362
|
+
schema_version: 1,
|
|
363
|
+
annotation_only: true,
|
|
364
|
+
key,
|
|
365
|
+
source: 'local-outcomes',
|
|
366
|
+
method: 'outcome-log',
|
|
367
|
+
n,
|
|
368
|
+
counts,
|
|
369
|
+
majority,
|
|
370
|
+
agreement: majority === null ? null : counts[majority] / n,
|
|
371
|
+
tier: 'measured-local',
|
|
372
|
+
evidence_id: 'prior-local',
|
|
373
|
+
note_id: 'prior.annotation-only',
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
//# sourceMappingURL=outcome.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outcome.js","sourceRoot":"","sources":["../src/outcome.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC9B,OAAO,EAAE,iBAAiB,EAAsC,MAAM,YAAY,CAAA;AAelF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAU,CAAA;AAC1F,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAU,CAAA;AAC7E,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,CAAU,CAAA;AACzF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,OAAO,EAAE,OAAO,CAAU,CAAA;AAChE,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAU,CAAA;AAEpF,gGAAgG;AAChG,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,mBAAmB,EAAE,gBAAgB,CAAU,CAAA;AAkEvH,gGAAgG;AAChG,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC;IAClD,gBAAgB;IAChB,IAAI;IACJ,IAAI;IACJ,QAAQ;IACR,SAAS;IACT,SAAS;IACT,aAAa;IACb,IAAI;IACJ,MAAM;IACN,YAAY;IACZ,cAAc;IACd,YAAY;IACZ,oBAAoB;IACpB,gBAAgB;IAChB,OAAO;CACR,CAAC,CAAA;AAEF,MAAM,YAAY,GAAwB,IAAI,GAAG,CAAC,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,CAAC,CAAA;AAExF,oGAAoG;AACpG,MAAM,UAAU,GAAG,wDAAwD,CAAA;AAC3E,MAAM,KAAK,GAAG,gBAAgB,CAAA;AAC9B,MAAM,aAAa,GAAG,+CAA+C,CAAA;AACrE,MAAM,aAAa,GAAG,4FAA4F,CAAA;AAElH,MAAM,WAAW,GAAG,GAAG,CAAA;AACvB,MAAM,WAAW,GAAG,EAAE,CAAA;AACtB,MAAM,cAAc,GAAG,EAAE,CAAA;AACzB,MAAM,SAAS,GAAG,CAAC,CAAA;AACnB,gFAAgF;AAChF,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAA;AAErC;;;;;;;GAOG;AACH,MAAM,gBAAgB,GAAsB;IAC1C,gBAAgB;IAChB,uBAAuB;IACvB,qCAAqC;IACrC,YAAY;IACZ,KAAK;IACL,qBAAqB;IACrB,sBAAsB;IACtB,sBAAsB;IACtB,WAAW;IACX,SAAS;CACV,CAAA;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC7E,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAa;IACtC,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;AAChE,CAAC;AAED,iFAAiF;AACjF,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAA;AAC/C,CAAC;AAED,+FAA+F;AAC/F,SAAS,aAAa,CAAC,MAAqB;IAC1C,MAAM,MAAM,GAAa;QACvB,MAAM,CAAC,EAAE;QACT,MAAM,CAAC,EAAE;QACT,MAAM,CAAC,MAAM;QACb,MAAM,CAAC,OAAO;QACd,MAAM,CAAC,OAAO;QACd,MAAM,CAAC,EAAE;QACT,MAAM,CAAC,IAAI;QACX,MAAM,CAAC,YAAY;QACnB,MAAM,CAAC,UAAU;QACjB,GAAG,MAAM,CAAC,kBAAkB;QAC5B,GAAG,MAAM,CAAC,cAAc;KACzB,CAAA;IACD,IAAI,MAAM,CAAC,WAAW,KAAK,IAAI;QAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;IAChE,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAA;QACzC,IAAI,MAAM,CAAC,KAAK,CAAC,cAAc,KAAK,IAAI;YAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAA;IACpF,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,mGAAmG;AACnG,SAAS,iBAAiB,CACxB,KAAc,EACd,KAAa,EACb,MAAiC;IAEjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,KAAK;QAAE,OAAO,IAAI,CAAA;IAC9D,MAAM,GAAG,GAAa,EAAE,CAAA;IACxB,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QAC5C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAA;QAC1D,oFAAoF;QACpF,4FAA4F;QAC5F,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;YAC/B,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAA;QAC/D,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAChB,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,SAAS,IAAI,CAAC,MAAwB,EAAE,KAAoB;IAC1D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;AACrC,CAAC;AAED,MAAM,WAAW,GAAG,CAAmB,MAAoB,EAAE,KAAc,EAAc,EAAE,CACzF,OAAO,KAAK,KAAK,QAAQ,IAAK,MAA4B,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;AAE5E;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,CAAA;IAE7D,wFAAwF;IACxF,wFAAwF;IACxF,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC,eAAe,EAAE,GAAG,CAAC,CAAA;IACjE,CAAC;IAED,IAAI,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAA;IAE/E,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;IACtB,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAA;IAE/E,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;IACtB,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACtF,OAAO,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,CAAA;IACpC,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAA;IAC9B,IAAI,CAAC,WAAW,CAAC,qBAAqB,EAAE,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAA;IAErF,MAAM,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC,CAAA;IACpC,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,CAAC,MAAM,GAAG,WAAW,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QACzG,OAAO,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,CAAA;IACvC,CAAC;IAED,qFAAqF;IACrF,sFAAsF;IACtF,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,CAAA;IAChC,IACE,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,CAAC,MAAM,GAAG,WAAW;QAC5B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;QACrB,KAAK,CAAC,OAAO,CAAC,KAAK,IAAI,EACvB,CAAC;QACD,OAAO,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,CAAA;IACvC,CAAC;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,aAAa,CAAC,CAAA;IACvC,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACxB,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,MAAM,GAAG,WAAW,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE,CAAC;YACpG,OAAO,IAAI,CAAC,aAAa,EAAE,aAAa,CAAC,CAAA;QAC3C,CAAC;IACH,CAAC;IAED,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;IACtB,IAAI,CAAC,WAAW,CAAC,iBAAiB,EAAE,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAA;IAEzE,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAA;IAC1B,IAAI,CAAC,WAAW,CAAC,mBAAmB,EAAE,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAA;IAE/E,MAAM,SAAS,GAAG,KAAK,CAAC,YAAY,CAAC,CAAA;IACrC,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,EAAE,IAAI,SAAS,GAAG,EAAE,EAAE,CAAC;QACtG,OAAO,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAA;IAC1C,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,cAAc,CAAC,CAAA;IACzC,IAAI,CAAC,WAAW,CAAC,2BAA2B,EAAE,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC,aAAa,EAAE,cAAc,CAAC,CAAA;IAEtG,MAAM,UAAU,GAAG,KAAK,CAAC,YAAY,CAAC,CAAA;IACtC,IAAI,CAAC,WAAW,CAAC,iBAAiB,EAAE,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAA;IAEzF,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAAE,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE,CACxF,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CACzB,CAAA;IACD,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC,aAAa,EAAE,oBAAoB,CAAC,CAAA;IAExE,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,CAC3E,WAAW,CAAC,oBAAoB,EAAE,IAAI,CAAC,CACxC,CAAA;IACD,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAA;IAEhE,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,CAAA;IAC/B,IAAI,KAAK,GAAwB,IAAI,CAAA;IACrC,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC;YAAE,OAAO,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAA;QACjE,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,OAAO,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,EAAE,CAAC,CAAA;QAC1E,CAAC;QACD,mFAAmF;QACnF,iDAAiD;QACjD,IAAI,MAAM,KAAK,OAAO;YAAE,OAAO,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,CAAA;QAC3D,MAAM,KAAK,GAAG,QAAQ,CAAC,iBAAiB,CAAC,CAAA;QACzC,IAAI,CAAC,WAAW,CAAC,oBAAoB,EAAE,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,aAAa,EAAE,uBAAuB,CAAC,CAAA;QAClG,MAAM,IAAI,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAA;QACvC,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,oBAAoB,EAAE,IAAI,CAAC,EAAE,CAAC;YAC9D,OAAO,IAAI,CAAC,aAAa,EAAE,sBAAsB,CAAC,CAAA;QACpD,CAAC;QACD,KAAK,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,CAAA;IAC1D,CAAC;IAED,MAAM,MAAM,GAAkB;QAC5B,cAAc,EAAE,CAAC;QACjB,EAAE;QACF,EAAE;QACF,MAAM;QACN,OAAO,EAAE,WAAW;QACpB,OAAO;QACP,WAAW,EAAE,UAAU;QACvB,EAAE;QACF,IAAI;QACJ,UAAU,EAAE,SAAS;QACrB,YAAY,EAAE,WAAW;QACzB,UAAU;QACV,kBAAkB,EAAE,SAAS;QAC7B,cAAc,EAAE,KAAgC;QAChD,KAAK;KACN,CAAA;IAED,yFAAyF;IACzF,+BAA+B;IAC/B,KAAK,MAAM,KAAK,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1C,IAAI,iBAAiB,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,aAAa,EAAE,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;IAC1F,CAAC;IAED,kFAAkF;IAClF,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,iBAAiB;QAAE,OAAO,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;IAEzF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;AAC7B,CAAC;AAED,qFAAqF;AACrF,SAAS,eAAe,CAAC,MAAqB,EAAE,KAAa;IAC3D,IAAI,KAAK,KAAK,MAAM,CAAC,EAAE;QAAE,OAAO,IAAI,CAAA;IACpC,IAAI,KAAK,KAAK,MAAM,CAAC,EAAE;QAAE,OAAO,IAAI,CAAA;IACpC,IAAI,KAAK,KAAK,MAAM,CAAC,OAAO;QAAE,OAAO,SAAS,CAAA;IAC9C,IAAI,KAAK,KAAK,MAAM,CAAC,OAAO;QAAE,OAAO,SAAS,CAAA;IAC9C,IAAI,KAAK,KAAK,MAAM,CAAC,WAAW;QAAE,OAAO,aAAa,CAAA;IACtD,IAAI,KAAK,KAAK,MAAM,CAAC,MAAM;QAAE,OAAO,QAAQ,CAAA;IAC5C,IAAI,KAAK,KAAK,MAAM,CAAC,EAAE;QAAE,OAAO,IAAI,CAAA;IACpC,IAAI,KAAK,KAAK,MAAM,CAAC,IAAI;QAAE,OAAO,MAAM,CAAA;IACxC,IAAI,KAAK,KAAK,MAAM,CAAC,YAAY;QAAE,OAAO,cAAc,CAAA;IACxD,IAAI,KAAK,KAAK,MAAM,CAAC,UAAU;QAAE,OAAO,YAAY,CAAA;IACpD,IAAI,MAAM,CAAC,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,oBAAoB,CAAA;IAC1E,IAAI,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAqB,CAAC;QAAE,OAAO,gBAAgB,CAAA;IAClF,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IACzG,IAAI,MAAe,CAAA;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IACvD,CAAC;IACD,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC,CAAA;IACtC,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,OAAO,MAAM,CAAA;IAC7B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAA;AAC5C,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,YAAY,CAAC,MAAqB;IAChD,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,GAAG,EAAE,MAAM,CAAC,WAAW;QACvB,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,YAAY,EAAE,MAAM,CAAC,YAAY;KAClC,CAAA;AACH,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,oBAAoB,CAAC,GAAe;IAClD,OAAO,GAAG,CAAC,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,YAAY,KAAK,SAAS,CAAA;AAC3D,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAgB,EAAE,KAAiB;IAChE,OAAO,CACL,IAAI,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO;QAC9B,IAAI,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO;QAC9B,IAAI,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG;QACtB,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE;QACpB,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI;QACxB,IAAI,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU;QACpC,IAAI,CAAC,YAAY,KAAK,KAAK,CAAC,YAAY,CACzC,CAAA;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAAiC,EACjC,GAAe;IAEf,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IAC3C,MAAM,MAAM,GAA+B,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAA;IACtF,IAAI,CAAC,GAAG,CAAC,CAAA;IACT,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC;YAAE,SAAQ;QACxD,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;QAC9B,CAAC,IAAI,CAAC,CAAA;IACR,CAAC;IACD,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IAEtB,IAAI,QAAQ,GAAsB,IAAI,CAAA;IACtC,KAAK,MAAM,UAAU,IAAI,iBAAiB,EAAE,CAAC;QAC3C,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,QAAQ,GAAG,UAAU,CAAA;IACvD,CAAC;IACD,OAAO;QACL,cAAc,EAAE,CAAC;QACjB,eAAe,EAAE,IAAI;QACrB,GAAG;QACH,MAAM,EAAE,gBAAgB;QACxB,MAAM,EAAE,aAAa;QACrB,CAAC;QACD,MAAM;QACN,QAAQ;QACR,SAAS,EAAE,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;QAC1D,IAAI,EAAE,gBAAgB;QACtB,WAAW,EAAE,aAAa;QAC1B,OAAO,EAAE,uBAAuB;KACjC,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upgrade impact: "if I move to dsh `<target>`, which loader rows and bundles get denied?"
|
|
3
|
+
*
|
|
4
|
+
* WHAT THIS MODULE IS ALLOWED TO SAY
|
|
5
|
+
* ----------------------------------
|
|
6
|
+
* One thing per unit: **would the target runtime be admitted by the range this unit
|
|
7
|
+
* declares?** It answers that by calling `evaluateAdmission` — the same function `why`,
|
|
8
|
+
* `check`, `audit` and the panel use — with `env.dsh` replaced by the target. There is no
|
|
9
|
+
* second range implementation here on purpose: admission semantics are locked by
|
|
10
|
+
* `data/gold/admission-cases.json`, and a local copy of "engines first, then peers" would
|
|
11
|
+
* be a second rule set that drifts silently.
|
|
12
|
+
*
|
|
13
|
+
* WHAT IT REFUSES TO SAY
|
|
14
|
+
* ----------------------
|
|
15
|
+
* - "this row will *work*": a declaration being admitted is not a measurement;
|
|
16
|
+
* - anything about feature behaviour, configuration names or data migration;
|
|
17
|
+
* - anything about a plugin that is not installed (no manifest = nothing to judge);
|
|
18
|
+
* - anything about another profile. `impact.profile` names the one that was read
|
|
19
|
+
* (`BS-38`: two profiles, two correct answers).
|
|
20
|
+
*
|
|
21
|
+
* PURITY
|
|
22
|
+
* ------
|
|
23
|
+
* No filesystem access, no network, no clock, no environment reads. Rows and bundles arrive
|
|
24
|
+
* already parsed, the timestamp arrives from the caller. Same input (in any array order) →
|
|
25
|
+
* byte-identical output: the ordering keys below form a total order and never use
|
|
26
|
+
* `localeCompare`, whose result depends on the ICU build of the machine that runs it.
|
|
27
|
+
*/
|
|
28
|
+
import type { AdmissionMode, AdmissionStatus, Requirement } from './admission.js';
|
|
29
|
+
import { type Locale } from './messages.js';
|
|
30
|
+
import type { EnvFingerprint, Reason, Remediation, Verdict } from './types.js';
|
|
31
|
+
import type { RowDeclaration } from './verdict.js';
|
|
32
|
+
/** The four buckets, in terminal order. A unit lands in exactly one of them. */
|
|
33
|
+
export declare const UPGRADE_BUCKETS: readonly ["would-be-denied", "cannot-tell", "improved", "likely-fine"];
|
|
34
|
+
export type UpgradeBucket = (typeof UPGRADE_BUCKETS)[number];
|
|
35
|
+
/**
|
|
36
|
+
* Machine-readable reason for the bucket a unit landed in.
|
|
37
|
+
*
|
|
38
|
+
* `cannot-tell` is deliberately narrow: it means **admission was not established**, never
|
|
39
|
+
* "it looks fine" and never "a definite denial that we decided not to report".
|
|
40
|
+
*/
|
|
41
|
+
export type UpgradeCause = 'target-denied' | 'unusable-declaration' | 'no-declaration' | 'not-installed' | 'runtime-unknown' | 'denied-now-admitted-then' | 'admitted-at-target';
|
|
42
|
+
/** `null` = the runtime string was absent; `invalid-runtime` = present but not a version. */
|
|
43
|
+
export type UpgradeStandingStatus = AdmissionStatus | 'not-installed' | 'invalid-runtime' | null;
|
|
44
|
+
export interface UpgradeStanding {
|
|
45
|
+
readonly runtime: string | null;
|
|
46
|
+
readonly status: UpgradeStandingStatus;
|
|
47
|
+
readonly mode: AdmissionMode | null;
|
|
48
|
+
/** Requirements that did not hold under **this** runtime (empty unless denied). */
|
|
49
|
+
readonly unmet: readonly Requirement[];
|
|
50
|
+
}
|
|
51
|
+
/** A bundle layer as the composition loader read it. */
|
|
52
|
+
export interface UpgradeBundleInput {
|
|
53
|
+
readonly name: string;
|
|
54
|
+
readonly version: string | null;
|
|
55
|
+
/** Raw `package.json`; `null` when the snapshot names a bundle it does not contain. */
|
|
56
|
+
readonly manifest: unknown | null;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Registry lookups are **secondary evidence**: a newer published build whose declaration
|
|
60
|
+
* admits the target. They are attached as annotations and are never read while bucketing.
|
|
61
|
+
*/
|
|
62
|
+
export interface UpgradeRegistryFact {
|
|
63
|
+
readonly package: string;
|
|
64
|
+
readonly version: string;
|
|
65
|
+
readonly declaredRange: string;
|
|
66
|
+
/** Computed by the caller with the same `evaluateAdmission`; never recomputed here. */
|
|
67
|
+
readonly admitsTarget: boolean;
|
|
68
|
+
readonly publishedAt?: string | null;
|
|
69
|
+
}
|
|
70
|
+
export interface UpgradeRegistryFailure {
|
|
71
|
+
readonly package: string;
|
|
72
|
+
readonly code: string;
|
|
73
|
+
readonly detail: string;
|
|
74
|
+
}
|
|
75
|
+
export interface UpgradeRegistryNote {
|
|
76
|
+
readonly annotation_only: true;
|
|
77
|
+
readonly tier: 'measured-registry';
|
|
78
|
+
readonly package: string;
|
|
79
|
+
readonly version: string;
|
|
80
|
+
readonly declared_range: string;
|
|
81
|
+
readonly admits_target: boolean;
|
|
82
|
+
readonly published_at: string | null;
|
|
83
|
+
readonly note_id: 'upgrade.registry-annotation';
|
|
84
|
+
}
|
|
85
|
+
export interface UpgradeUnit {
|
|
86
|
+
/** `bundle:<name>` or `row:<rowId>`; unique across the list. */
|
|
87
|
+
readonly id: string;
|
|
88
|
+
readonly kind: 'bundle' | 'row';
|
|
89
|
+
/** Bundle name, or the module a row imports. */
|
|
90
|
+
readonly name: string;
|
|
91
|
+
readonly version: string | null;
|
|
92
|
+
readonly row_ids: readonly string[];
|
|
93
|
+
/** Patch layer that declares the row; `null` for a bundle. */
|
|
94
|
+
readonly source: string | null;
|
|
95
|
+
readonly bucket: UpgradeBucket;
|
|
96
|
+
readonly cause: UpgradeCause;
|
|
97
|
+
/** The current runtime denies this unit too: the upgrade did not cause the denial. */
|
|
98
|
+
readonly already_denied_at_current: boolean;
|
|
99
|
+
readonly current: UpgradeStanding;
|
|
100
|
+
readonly target: UpgradeStanding;
|
|
101
|
+
/** Exactly the remediation the same engine prints for this denial. */
|
|
102
|
+
readonly remediation: readonly Remediation[];
|
|
103
|
+
readonly reasons: readonly Reason[];
|
|
104
|
+
readonly missing_evidence: readonly string[];
|
|
105
|
+
/** Verdict at the target runtime (`env.dsh === target`); `null` when there is nothing to judge. */
|
|
106
|
+
readonly verdict: Verdict | null;
|
|
107
|
+
readonly suggestions: readonly UpgradeRegistryNote[];
|
|
108
|
+
}
|
|
109
|
+
export interface UpgradeCounts {
|
|
110
|
+
readonly bundles: number;
|
|
111
|
+
readonly rows: number;
|
|
112
|
+
readonly would_be_denied: number;
|
|
113
|
+
readonly cannot_tell: number;
|
|
114
|
+
readonly improved: number;
|
|
115
|
+
readonly likely_fine: number;
|
|
116
|
+
readonly total: number;
|
|
117
|
+
}
|
|
118
|
+
export type UpgradeRelation = 'same' | 'newer' | 'older' | 'unknown';
|
|
119
|
+
export interface UpgradeImpact {
|
|
120
|
+
readonly schema_version: 1;
|
|
121
|
+
/** The profile this answer is about. Never "your setup in general". */
|
|
122
|
+
readonly profile: string;
|
|
123
|
+
readonly profile_source: 'live' | 'snapshot';
|
|
124
|
+
readonly current: string | null;
|
|
125
|
+
readonly current_valid: boolean;
|
|
126
|
+
readonly target: string;
|
|
127
|
+
readonly target_valid: true;
|
|
128
|
+
readonly target_relation: UpgradeRelation;
|
|
129
|
+
readonly buckets: readonly UpgradeBucket[];
|
|
130
|
+
readonly counts: UpgradeCounts;
|
|
131
|
+
readonly units: readonly UpgradeUnit[];
|
|
132
|
+
readonly registry: {
|
|
133
|
+
readonly consulted: boolean;
|
|
134
|
+
readonly facts: number;
|
|
135
|
+
readonly failures: readonly UpgradeRegistryFailure[];
|
|
136
|
+
};
|
|
137
|
+
readonly generated_at: string;
|
|
138
|
+
}
|
|
139
|
+
export type UpgradeJudgement = {
|
|
140
|
+
readonly ok: true;
|
|
141
|
+
readonly impact: UpgradeImpact;
|
|
142
|
+
} | {
|
|
143
|
+
readonly ok: false;
|
|
144
|
+
readonly code: 'invalid-target';
|
|
145
|
+
readonly detail: string;
|
|
146
|
+
readonly target: string;
|
|
147
|
+
};
|
|
148
|
+
export interface UpgradeImpactInput {
|
|
149
|
+
/** The environment the profile was read from. `env.dsh` **is** the current runtime. */
|
|
150
|
+
readonly env: EnvFingerprint;
|
|
151
|
+
readonly target: string;
|
|
152
|
+
readonly bundles: readonly UpgradeBundleInput[];
|
|
153
|
+
readonly rows: readonly RowDeclaration[];
|
|
154
|
+
readonly generatedAt: string;
|
|
155
|
+
readonly profileSource?: 'live' | 'snapshot';
|
|
156
|
+
readonly registry?: readonly UpgradeRegistryFact[];
|
|
157
|
+
readonly registryFailures?: readonly UpgradeRegistryFailure[];
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Validate a target before anything is read.
|
|
161
|
+
*
|
|
162
|
+
* Exposed because the CLI must reject `--to ^0.3.0` **before** it touches a profile: a
|
|
163
|
+
* usage error that depends on whether the profile exists would report the wrong thing.
|
|
164
|
+
*/
|
|
165
|
+
export declare function upgradeTargetProblem(target: string): string | null;
|
|
166
|
+
/**
|
|
167
|
+
* Judge the impact of moving to `input.target`.
|
|
168
|
+
*
|
|
169
|
+
* The target is validated first: `semver.satisfies('0.3', '*')` returns `false` without
|
|
170
|
+
* throwing, so an unvalidated target would silently turn every unit into "denied". A bad
|
|
171
|
+
* target is a usage error, not a finding.
|
|
172
|
+
*/
|
|
173
|
+
export declare function judgeUpgradeImpact(input: UpgradeImpactInput): UpgradeJudgement;
|
|
174
|
+
/**
|
|
175
|
+
* Turn one packument's version→manifest map into ONE annotation.
|
|
176
|
+
*
|
|
177
|
+
* Chosen here (in core, next to the range logic) rather than in the CLI, because picking
|
|
178
|
+
* "the newest version whose declaration admits the target" needs semver ordering — a second
|
|
179
|
+
* implementation of that ordering in the CLI would be exactly the kind of drift this file
|
|
180
|
+
* exists to avoid.
|
|
181
|
+
*
|
|
182
|
+
* `admitsTarget: false` is a legitimate answer: it means "I looked, and no published version
|
|
183
|
+
* declares the target". Dropping it would make the search invisible.
|
|
184
|
+
*/
|
|
185
|
+
export declare function registryFactFor(input: {
|
|
186
|
+
readonly packageName: string;
|
|
187
|
+
readonly versions: ReadonlyMap<string, unknown>;
|
|
188
|
+
readonly target: string;
|
|
189
|
+
readonly publishedAt?: Readonly<Record<string, string>> | null;
|
|
190
|
+
}): UpgradeRegistryFact | null;
|
|
191
|
+
/**
|
|
192
|
+
* Total order: bucket → kind → name → version → id.
|
|
193
|
+
*
|
|
194
|
+
* `localeCompare` is not used anywhere in this chain: it depends on the ICU build, so the
|
|
195
|
+
* same input could sort differently on two machines and the artifact would stop reproducing.
|
|
196
|
+
*/
|
|
197
|
+
export declare function compareUnits(left: UpgradeUnit, right: UpgradeUnit): number;
|
|
198
|
+
/** Terminal rendering. Pure: locale in, text out; no colour, no clock, no width probing. */
|
|
199
|
+
export declare function renderUpgradeImpact(impact: UpgradeImpact, locale: Locale): string;
|
|
200
|
+
/** Convenience for callers that only need a yes/no: is anything going to be denied? */
|
|
201
|
+
export declare function hasNewDenials(impact: UpgradeImpact): boolean;
|
|
202
|
+
//# sourceMappingURL=upgrade.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../src/upgrade.ts"],"names":[],"mappings":"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"}
|