attenu-guard 0.1.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/CHANGELOG.md +46 -0
- package/LICENSE +202 -0
- package/README.md +200 -0
- package/SECURITY.md +34 -0
- package/bin/attenu-guard.js +4 -0
- package/dist/cjs/adapters/langgraph.d.ts +174 -0
- package/dist/cjs/adapters/langgraph.d.ts.map +1 -0
- package/dist/cjs/adapters/langgraph.js +242 -0
- package/dist/cjs/adapters/langgraph.js.map +1 -0
- package/dist/cjs/audit.d.ts +82 -0
- package/dist/cjs/audit.d.ts.map +1 -0
- package/dist/cjs/audit.js +195 -0
- package/dist/cjs/audit.js.map +1 -0
- package/dist/cjs/authority.d.ts +114 -0
- package/dist/cjs/authority.d.ts.map +1 -0
- package/dist/cjs/authority.js +238 -0
- package/dist/cjs/authority.js.map +1 -0
- package/dist/cjs/canonical.d.ts +91 -0
- package/dist/cjs/canonical.d.ts.map +1 -0
- package/dist/cjs/canonical.js +372 -0
- package/dist/cjs/canonical.js.map +1 -0
- package/dist/cjs/ceilings.d.ts +211 -0
- package/dist/cjs/ceilings.d.ts.map +1 -0
- package/dist/cjs/ceilings.js +476 -0
- package/dist/cjs/ceilings.js.map +1 -0
- package/dist/cjs/chain.d.ts +106 -0
- package/dist/cjs/chain.d.ts.map +1 -0
- package/dist/cjs/chain.js +0 -0
- package/dist/cjs/chain.js.map +1 -0
- package/dist/cjs/cli.d.ts +16 -0
- package/dist/cjs/cli.d.ts.map +1 -0
- package/dist/cjs/cli.js +100 -0
- package/dist/cjs/cli.js.map +1 -0
- package/dist/cjs/evidence.d.ts +163 -0
- package/dist/cjs/evidence.d.ts.map +1 -0
- package/dist/cjs/evidence.js +409 -0
- package/dist/cjs/evidence.js.map +1 -0
- package/dist/cjs/guard.d.ts +186 -0
- package/dist/cjs/guard.d.ts.map +1 -0
- package/dist/cjs/guard.js +432 -0
- package/dist/cjs/guard.js.map +1 -0
- package/dist/cjs/index.d.ts +52 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +99 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/reasons.d.ts +93 -0
- package/dist/cjs/reasons.d.ts.map +1 -0
- package/dist/cjs/reasons.js +139 -0
- package/dist/cjs/reasons.js.map +1 -0
- package/dist/cjs/strikes.d.ts +24 -0
- package/dist/cjs/strikes.d.ts.map +1 -0
- package/dist/cjs/strikes.js +30 -0
- package/dist/cjs/strikes.js.map +1 -0
- package/dist/cjs/wire.d.ts +83 -0
- package/dist/cjs/wire.d.ts.map +1 -0
- package/dist/cjs/wire.js +165 -0
- package/dist/cjs/wire.js.map +1 -0
- package/dist/esm/adapters/langgraph.d.ts +174 -0
- package/dist/esm/adapters/langgraph.d.ts.map +1 -0
- package/dist/esm/adapters/langgraph.js +199 -0
- package/dist/esm/adapters/langgraph.js.map +1 -0
- package/dist/esm/audit.d.ts +82 -0
- package/dist/esm/audit.d.ts.map +1 -0
- package/dist/esm/audit.js +189 -0
- package/dist/esm/audit.js.map +1 -0
- package/dist/esm/authority.d.ts +114 -0
- package/dist/esm/authority.d.ts.map +1 -0
- package/dist/esm/authority.js +233 -0
- package/dist/esm/authority.js.map +1 -0
- package/dist/esm/canonical.d.ts +91 -0
- package/dist/esm/canonical.d.ts.map +1 -0
- package/dist/esm/canonical.js +359 -0
- package/dist/esm/canonical.js.map +1 -0
- package/dist/esm/ceilings.d.ts +211 -0
- package/dist/esm/ceilings.d.ts.map +1 -0
- package/dist/esm/ceilings.js +460 -0
- package/dist/esm/ceilings.js.map +1 -0
- package/dist/esm/chain.d.ts +106 -0
- package/dist/esm/chain.d.ts.map +1 -0
- package/dist/esm/chain.js +0 -0
- package/dist/esm/chain.js.map +1 -0
- package/dist/esm/cli.d.ts +16 -0
- package/dist/esm/cli.d.ts.map +1 -0
- package/dist/esm/cli.js +97 -0
- package/dist/esm/cli.js.map +1 -0
- package/dist/esm/evidence.d.ts +163 -0
- package/dist/esm/evidence.d.ts.map +1 -0
- package/dist/esm/evidence.js +398 -0
- package/dist/esm/evidence.js.map +1 -0
- package/dist/esm/guard.d.ts +186 -0
- package/dist/esm/guard.d.ts.map +1 -0
- package/dist/esm/guard.js +427 -0
- package/dist/esm/guard.js.map +1 -0
- package/dist/esm/index.d.ts +52 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +42 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/reasons.d.ts +93 -0
- package/dist/esm/reasons.d.ts.map +1 -0
- package/dist/esm/reasons.js +134 -0
- package/dist/esm/reasons.js.map +1 -0
- package/dist/esm/strikes.d.ts +24 -0
- package/dist/esm/strikes.d.ts.map +1 -0
- package/dist/esm/strikes.js +26 -0
- package/dist/esm/strikes.js.map +1 -0
- package/dist/esm/wire.d.ts +83 -0
- package/dist/esm/wire.d.ts.map +1 -0
- package/dist/esm/wire.js +159 -0
- package/dist/esm/wire.js.map +1 -0
- package/package.json +89 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* canonical.ts — byte-exact interoperability with the Python implementation.
|
|
4
|
+
*
|
|
5
|
+
* Every hash, seal and signature in Attenu is taken over a canonical JSON
|
|
6
|
+
* serialisation. The Python library produces those bytes with
|
|
7
|
+
* `json.dumps(obj, sort_keys=True, separators=(",", ":"))`, whose defaults
|
|
8
|
+
* include `ensure_ascii=True`. `JSON.stringify` differs from that in three
|
|
9
|
+
* ways that would each silently break cross-language verification:
|
|
10
|
+
*
|
|
11
|
+
* 1. key order — `JSON.stringify` preserves insertion order, Python sorts;
|
|
12
|
+
* 2. non-ASCII — Python escapes every code point above U+007E as `\uXXXX`
|
|
13
|
+
* (astral characters as a surrogate pair), `JSON.stringify` emits them raw;
|
|
14
|
+
* 3. numbers — Python distinguishes `int` from `float` (`100` vs `100.0`) and
|
|
15
|
+
* switches to exponential notation at different magnitudes than JavaScript
|
|
16
|
+
* (`1e-05` where `String()` gives `0.00001`).
|
|
17
|
+
*
|
|
18
|
+
* (1) and (2) are handled by `canonicalJson` below. (3) cannot be solved by a
|
|
19
|
+
* serialiser alone, because a JavaScript `number` has forgotten whether the
|
|
20
|
+
* document said `100` or `100.0`. So a document that is going to be re-hashed —
|
|
21
|
+
* a ledger or a bundle produced elsewhere — is read with `parseJson`, which
|
|
22
|
+
* keeps each number's original literal alongside its value as a `RawNumber`.
|
|
23
|
+
* `canonicalJson` re-emits that literal verbatim, so a Python-written entry
|
|
24
|
+
* hashes to the byte-identical digest here. Values created in this library are
|
|
25
|
+
* plain numbers, and `pyNumber` formats them the way Python's `json` would, so
|
|
26
|
+
* the reverse direction round-trips too.
|
|
27
|
+
*/
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.RawNumber = void 0;
|
|
30
|
+
exports.compareCodePoints = compareCodePoints;
|
|
31
|
+
exports.sortedStrings = sortedStrings;
|
|
32
|
+
exports.pyNumber = pyNumber;
|
|
33
|
+
exports.pyString = pyString;
|
|
34
|
+
exports.canonicalJson = canonicalJson;
|
|
35
|
+
exports.pyJsonDumps = pyJsonDumps;
|
|
36
|
+
exports.canonicalBytes = canonicalBytes;
|
|
37
|
+
exports.toPlain = toPlain;
|
|
38
|
+
exports.parseJson = parseJson;
|
|
39
|
+
/** A number as it was written in the source document, plus its parsed value. */
|
|
40
|
+
class RawNumber {
|
|
41
|
+
raw;
|
|
42
|
+
value;
|
|
43
|
+
constructor(raw, value) {
|
|
44
|
+
this.raw = raw;
|
|
45
|
+
this.value = value;
|
|
46
|
+
}
|
|
47
|
+
valueOf() {
|
|
48
|
+
return this.value;
|
|
49
|
+
}
|
|
50
|
+
toJSON() {
|
|
51
|
+
return this.value;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.RawNumber = RawNumber;
|
|
55
|
+
/** Compare two strings by Unicode code point, as Python's `sorted` does. */
|
|
56
|
+
function compareCodePoints(a, b) {
|
|
57
|
+
const ca = Array.from(a);
|
|
58
|
+
const cb = Array.from(b);
|
|
59
|
+
const n = Math.min(ca.length, cb.length);
|
|
60
|
+
for (let i = 0; i < n; i++) {
|
|
61
|
+
const x = ca[i].codePointAt(0);
|
|
62
|
+
const y = cb[i].codePointAt(0);
|
|
63
|
+
if (x !== y)
|
|
64
|
+
return x < y ? -1 : 1;
|
|
65
|
+
}
|
|
66
|
+
return ca.length - cb.length;
|
|
67
|
+
}
|
|
68
|
+
/** Sort strings by code point (Python's `sorted(list_of_str)`). */
|
|
69
|
+
function sortedStrings(values) {
|
|
70
|
+
return Array.from(values).sort(compareCodePoints);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Format a number the way Python's `json.dumps` would.
|
|
74
|
+
*
|
|
75
|
+
* Integral values are emitted without a decimal point, matching a Python `int`.
|
|
76
|
+
* A TypeScript number cannot record that it was meant to be the float `100.0`,
|
|
77
|
+
* so such a value serialises as `100`; Python reads that back as an `int` and
|
|
78
|
+
* re-emits `100`, which keeps the chain verifiable in both directions. Values
|
|
79
|
+
* with a fractional part follow CPython's `repr`: shortest round-tripping
|
|
80
|
+
* digits, exponential notation when the decimal exponent is below -4 or at
|
|
81
|
+
* least 16, a two-digit signed exponent, and always a decimal point otherwise.
|
|
82
|
+
*/
|
|
83
|
+
function pyNumber(n) {
|
|
84
|
+
if (Number.isNaN(n))
|
|
85
|
+
return "NaN";
|
|
86
|
+
if (!Number.isFinite(n))
|
|
87
|
+
return n > 0 ? "Infinity" : "-Infinity";
|
|
88
|
+
if (Object.is(n, -0))
|
|
89
|
+
return "-0.0";
|
|
90
|
+
if (Number.isInteger(n) && Math.abs(n) < 1e21)
|
|
91
|
+
return n.toFixed(0);
|
|
92
|
+
return pyFloatRepr(n);
|
|
93
|
+
}
|
|
94
|
+
function pyFloatRepr(n) {
|
|
95
|
+
// `toExponential()` with no argument yields the shortest digit string that
|
|
96
|
+
// uniquely identifies the value — the same "shortest round-trip" digits
|
|
97
|
+
// CPython's repr produces. Only the layout around them differs.
|
|
98
|
+
const parsed = /^(-?)(\d)(?:\.(\d+))?e([+-]\d+)$/.exec(n.toExponential());
|
|
99
|
+
if (!parsed)
|
|
100
|
+
return String(n); // unreachable for a finite double
|
|
101
|
+
const sign = parsed[1];
|
|
102
|
+
const digits = parsed[2] + (parsed[3] ?? "");
|
|
103
|
+
const exp = parseInt(parsed[4], 10);
|
|
104
|
+
if (exp < -4 || exp >= 16) {
|
|
105
|
+
const mantissa = digits.length > 1 ? `${digits[0]}.${digits.slice(1)}` : digits;
|
|
106
|
+
const expSign = exp < 0 ? "-" : "+";
|
|
107
|
+
return `${sign}${mantissa}e${expSign}${String(Math.abs(exp)).padStart(2, "0")}`;
|
|
108
|
+
}
|
|
109
|
+
if (exp >= 0) {
|
|
110
|
+
const body = digits.length > exp + 1
|
|
111
|
+
? `${digits.slice(0, exp + 1)}.${digits.slice(exp + 1)}`
|
|
112
|
+
: `${digits.padEnd(exp + 1, "0")}.0`;
|
|
113
|
+
return sign + body;
|
|
114
|
+
}
|
|
115
|
+
return `${sign}0.${"0".repeat(-exp - 1)}${digits}`;
|
|
116
|
+
}
|
|
117
|
+
/** Escape a string the way Python's `json.dumps(ensure_ascii=True)` does. */
|
|
118
|
+
function pyString(s) {
|
|
119
|
+
let out = '"';
|
|
120
|
+
for (let i = 0; i < s.length; i++) {
|
|
121
|
+
const ch = s[i];
|
|
122
|
+
const code = s.charCodeAt(i);
|
|
123
|
+
if (ch === '"')
|
|
124
|
+
out += '\\"';
|
|
125
|
+
else if (ch === "\\")
|
|
126
|
+
out += "\\\\";
|
|
127
|
+
else if (code === 0x08)
|
|
128
|
+
out += "\\b";
|
|
129
|
+
else if (code === 0x09)
|
|
130
|
+
out += "\\t";
|
|
131
|
+
else if (code === 0x0a)
|
|
132
|
+
out += "\\n";
|
|
133
|
+
else if (code === 0x0c)
|
|
134
|
+
out += "\\f";
|
|
135
|
+
else if (code === 0x0d)
|
|
136
|
+
out += "\\r";
|
|
137
|
+
else if (code < 0x20 || code > 0x7e)
|
|
138
|
+
out += "\\u" + code.toString(16).padStart(4, "0");
|
|
139
|
+
else
|
|
140
|
+
out += ch;
|
|
141
|
+
}
|
|
142
|
+
return out + '"';
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Serialise to the exact bytes Python's
|
|
146
|
+
* `json.dumps(obj, sort_keys=True, separators=(",", ":"))` produces:
|
|
147
|
+
* sorted keys, no incidental whitespace, ASCII-escaped strings.
|
|
148
|
+
*
|
|
149
|
+
* Object entries whose value is `undefined` are omitted, matching a Python dict
|
|
150
|
+
* that simply never held the key. `null` is kept — it is a value.
|
|
151
|
+
*/
|
|
152
|
+
function canonicalJson(value) {
|
|
153
|
+
return pyJsonDumps(value, ",", ":");
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Serialise with sorted keys and ASCII escaping, choosing the separators.
|
|
157
|
+
*
|
|
158
|
+
* `canonicalJson` uses the compact `(",", ":")` pair every hash is taken over.
|
|
159
|
+
* The `.jsonl` ledger on disk is written with Python's DEFAULT separators
|
|
160
|
+
* (`", "` and `": "`), so a line read back by either language re-serialises to
|
|
161
|
+
* the same bytes its writer produced.
|
|
162
|
+
*/
|
|
163
|
+
function pyJsonDumps(value, itemSeparator = ", ", keySeparator = ": ") {
|
|
164
|
+
if (value === null || value === undefined)
|
|
165
|
+
return "null";
|
|
166
|
+
if (value instanceof RawNumber)
|
|
167
|
+
return value.raw;
|
|
168
|
+
switch (typeof value) {
|
|
169
|
+
case "boolean":
|
|
170
|
+
return value ? "true" : "false";
|
|
171
|
+
case "number":
|
|
172
|
+
return pyNumber(value);
|
|
173
|
+
case "string":
|
|
174
|
+
return pyString(value);
|
|
175
|
+
}
|
|
176
|
+
if (Array.isArray(value)) {
|
|
177
|
+
return ("[" + value.map((v) => pyJsonDumps(v, itemSeparator, keySeparator)).join(itemSeparator) + "]");
|
|
178
|
+
}
|
|
179
|
+
const keys = sortedStrings(Object.keys(value).filter((k) => value[k] !== undefined));
|
|
180
|
+
return ("{" +
|
|
181
|
+
keys
|
|
182
|
+
.map((k) => `${pyString(k)}${keySeparator}${pyJsonDumps(value[k], itemSeparator, keySeparator)}`)
|
|
183
|
+
.join(itemSeparator) +
|
|
184
|
+
"}");
|
|
185
|
+
}
|
|
186
|
+
/** The canonical bytes — what every hash, seal and signature is taken over. */
|
|
187
|
+
function canonicalBytes(value) {
|
|
188
|
+
return Buffer.from(canonicalJson(value), "utf8");
|
|
189
|
+
}
|
|
190
|
+
/** Strip `RawNumber` wrappers, yielding ordinary JavaScript values. */
|
|
191
|
+
function toPlain(value) {
|
|
192
|
+
if (value instanceof RawNumber)
|
|
193
|
+
return value.value;
|
|
194
|
+
if (Array.isArray(value))
|
|
195
|
+
return value.map((v) => toPlain(v));
|
|
196
|
+
if (value !== null && typeof value === "object") {
|
|
197
|
+
const out = {};
|
|
198
|
+
for (const [k, v] of Object.entries(value))
|
|
199
|
+
out[k] = toPlain(v);
|
|
200
|
+
return out;
|
|
201
|
+
}
|
|
202
|
+
return value;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Parse JSON, keeping every number's original literal.
|
|
206
|
+
*
|
|
207
|
+
* `JSON.parse` is not used: it discards the literal, and with it the ability to
|
|
208
|
+
* reproduce the bytes the writer hashed. Objects preserve their key order for
|
|
209
|
+
* readability; canonical serialisation sorts them anyway.
|
|
210
|
+
*/
|
|
211
|
+
function parseJson(text) {
|
|
212
|
+
const p = new Parser(text);
|
|
213
|
+
p.skipWhitespace();
|
|
214
|
+
const value = p.parseValue();
|
|
215
|
+
p.skipWhitespace();
|
|
216
|
+
if (!p.atEnd())
|
|
217
|
+
p.fail("unexpected trailing data");
|
|
218
|
+
return value;
|
|
219
|
+
}
|
|
220
|
+
const NUMBER_RE = /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?/;
|
|
221
|
+
class Parser {
|
|
222
|
+
s;
|
|
223
|
+
i = 0;
|
|
224
|
+
constructor(s) {
|
|
225
|
+
this.s = s;
|
|
226
|
+
}
|
|
227
|
+
atEnd() {
|
|
228
|
+
return this.i >= this.s.length;
|
|
229
|
+
}
|
|
230
|
+
fail(message) {
|
|
231
|
+
throw new SyntaxError(`${message} at position ${this.i}`);
|
|
232
|
+
}
|
|
233
|
+
skipWhitespace() {
|
|
234
|
+
while (this.i < this.s.length) {
|
|
235
|
+
const c = this.s[this.i];
|
|
236
|
+
if (c === " " || c === "\t" || c === "\n" || c === "\r")
|
|
237
|
+
this.i++;
|
|
238
|
+
else
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
parseValue() {
|
|
243
|
+
if (this.atEnd())
|
|
244
|
+
this.fail("unexpected end of input");
|
|
245
|
+
const c = this.s[this.i];
|
|
246
|
+
if (c === "{")
|
|
247
|
+
return this.parseObject();
|
|
248
|
+
if (c === "[")
|
|
249
|
+
return this.parseArray();
|
|
250
|
+
if (c === '"')
|
|
251
|
+
return this.parseString();
|
|
252
|
+
if (this.s.startsWith("true", this.i))
|
|
253
|
+
return (this.i += 4), true;
|
|
254
|
+
if (this.s.startsWith("false", this.i))
|
|
255
|
+
return (this.i += 5), false;
|
|
256
|
+
if (this.s.startsWith("null", this.i))
|
|
257
|
+
return (this.i += 4), null;
|
|
258
|
+
return this.parseNumber();
|
|
259
|
+
}
|
|
260
|
+
parseObject() {
|
|
261
|
+
this.i++; // {
|
|
262
|
+
const out = {};
|
|
263
|
+
this.skipWhitespace();
|
|
264
|
+
if (this.s[this.i] === "}")
|
|
265
|
+
return this.i++, out;
|
|
266
|
+
for (;;) {
|
|
267
|
+
this.skipWhitespace();
|
|
268
|
+
if (this.s[this.i] !== '"')
|
|
269
|
+
this.fail("expected an object key");
|
|
270
|
+
const key = this.parseString();
|
|
271
|
+
this.skipWhitespace();
|
|
272
|
+
if (this.s[this.i] !== ":")
|
|
273
|
+
this.fail("expected ':'");
|
|
274
|
+
this.i++;
|
|
275
|
+
this.skipWhitespace();
|
|
276
|
+
out[key] = this.parseValue();
|
|
277
|
+
this.skipWhitespace();
|
|
278
|
+
const c = this.s[this.i];
|
|
279
|
+
if (c === ",") {
|
|
280
|
+
this.i++;
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
if (c === "}")
|
|
284
|
+
return this.i++, out;
|
|
285
|
+
this.fail("expected ',' or '}'");
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
parseArray() {
|
|
289
|
+
this.i++; // [
|
|
290
|
+
const out = [];
|
|
291
|
+
this.skipWhitespace();
|
|
292
|
+
if (this.s[this.i] === "]")
|
|
293
|
+
return this.i++, out;
|
|
294
|
+
for (;;) {
|
|
295
|
+
this.skipWhitespace();
|
|
296
|
+
out.push(this.parseValue());
|
|
297
|
+
this.skipWhitespace();
|
|
298
|
+
const c = this.s[this.i];
|
|
299
|
+
if (c === ",") {
|
|
300
|
+
this.i++;
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
if (c === "]")
|
|
304
|
+
return this.i++, out;
|
|
305
|
+
this.fail("expected ',' or ']'");
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
parseString() {
|
|
309
|
+
this.i++; // opening quote
|
|
310
|
+
let out = "";
|
|
311
|
+
for (;;) {
|
|
312
|
+
if (this.atEnd())
|
|
313
|
+
this.fail("unterminated string");
|
|
314
|
+
const c = this.s[this.i];
|
|
315
|
+
if (c === '"')
|
|
316
|
+
return this.i++, out;
|
|
317
|
+
if (c !== "\\") {
|
|
318
|
+
out += c;
|
|
319
|
+
this.i++;
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
this.i++;
|
|
323
|
+
const esc = this.s[this.i];
|
|
324
|
+
this.i++;
|
|
325
|
+
switch (esc) {
|
|
326
|
+
case '"':
|
|
327
|
+
out += '"';
|
|
328
|
+
break;
|
|
329
|
+
case "\\":
|
|
330
|
+
out += "\\";
|
|
331
|
+
break;
|
|
332
|
+
case "/":
|
|
333
|
+
out += "/";
|
|
334
|
+
break;
|
|
335
|
+
case "b":
|
|
336
|
+
out += "\b";
|
|
337
|
+
break;
|
|
338
|
+
case "f":
|
|
339
|
+
out += "\f";
|
|
340
|
+
break;
|
|
341
|
+
case "n":
|
|
342
|
+
out += "\n";
|
|
343
|
+
break;
|
|
344
|
+
case "r":
|
|
345
|
+
out += "\r";
|
|
346
|
+
break;
|
|
347
|
+
case "t":
|
|
348
|
+
out += "\t";
|
|
349
|
+
break;
|
|
350
|
+
case "u": {
|
|
351
|
+
const hex = this.s.slice(this.i, this.i + 4);
|
|
352
|
+
if (!/^[0-9a-fA-F]{4}$/.test(hex))
|
|
353
|
+
this.fail("bad \\u escape");
|
|
354
|
+
out += String.fromCharCode(parseInt(hex, 16));
|
|
355
|
+
this.i += 4;
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
default:
|
|
359
|
+
this.fail("bad escape");
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
parseNumber() {
|
|
364
|
+
const m = NUMBER_RE.exec(this.s.slice(this.i));
|
|
365
|
+
if (!m)
|
|
366
|
+
this.fail("expected a value");
|
|
367
|
+
const raw = m[0];
|
|
368
|
+
this.i += raw.length;
|
|
369
|
+
return new RawNumber(raw, Number(raw));
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
//# sourceMappingURL=canonical.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonical.js","sourceRoot":"","sources":["../../src/canonical.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ceilings.ts — typed, self-narrowing, self-enforcing bounds on an Authority.
|
|
3
|
+
*
|
|
4
|
+
* A `Ceiling` is a small typed object that knows how to (a) check itself against
|
|
5
|
+
* a request context, (b) narrow itself against a sibling ceiling of the same
|
|
6
|
+
* kind, (c) state whether it admits a superset of what another ceiling of its
|
|
7
|
+
* kind admits, and (d) read and write its own wire form. `Authority` never needs
|
|
8
|
+
* to know the semantics of any particular ceiling — it just calls these methods.
|
|
9
|
+
*
|
|
10
|
+
* The property the Internet-Draft's constraint vocabulary demands: "a verifier
|
|
11
|
+
* that encounters an unknown constraint type MUST treat the action as denied
|
|
12
|
+
* (fail-closed), never as unconstrained." That is `ceilingFromWire`: an
|
|
13
|
+
* unrecognised wire constraint becomes an `UnknownCeiling`, whose `permits`
|
|
14
|
+
* always denies. There is no code path by which an unrecognised bound is
|
|
15
|
+
* silently dropped.
|
|
16
|
+
*/
|
|
17
|
+
import { type CJson, type Json } from "./canonical.js";
|
|
18
|
+
import { Decision } from "./reasons.js";
|
|
19
|
+
/** A request context: the quantities and attributes a call declares. */
|
|
20
|
+
export type Context = Record<string, Json>;
|
|
21
|
+
/** The shape every ceiling — built-in or custom — must implement. */
|
|
22
|
+
export interface Ceiling {
|
|
23
|
+
/** The dimension being bounded, e.g. "max_rows". Pairs ceilings in `meet`. */
|
|
24
|
+
readonly key: string;
|
|
25
|
+
/** The request-context field this ceiling reads, when it differs from `key`. */
|
|
26
|
+
readonly ctxField?: string;
|
|
27
|
+
/** Caller-chosen context field for the generic membership/prefix ceilings. */
|
|
28
|
+
readonly field?: string | null;
|
|
29
|
+
/** Set on a ceiling that bounds a consumed quantity the caller must declare. */
|
|
30
|
+
readonly metered?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Does this ceiling admit the given request context? A context that does not
|
|
33
|
+
* mention this ceiling's dimension is not asserting anything here, and is
|
|
34
|
+
* permitted.
|
|
35
|
+
*/
|
|
36
|
+
permits(ctx: Context): Decision;
|
|
37
|
+
/**
|
|
38
|
+
* The more restrictive of `this` and `other` (same key). Must satisfy:
|
|
39
|
+
* the result's admitted set is a subset of both inputs'. That is what makes
|
|
40
|
+
* `Authority.meet` sound.
|
|
41
|
+
*/
|
|
42
|
+
narrow(other: Ceiling): Ceiling;
|
|
43
|
+
/** True iff `this` admits a superset of what `other` admits. */
|
|
44
|
+
subsumes(other: Ceiling): boolean;
|
|
45
|
+
/** The wire form, per the Internet-Draft's Constraint Vocabulary. */
|
|
46
|
+
toWire(): Record<string, Json>;
|
|
47
|
+
/** Human-readable rendering, for dashboards and parent-vs-child diffs. */
|
|
48
|
+
describe?(): string;
|
|
49
|
+
/** Scoped ceilings only: does this bound bite a request for `scope`? */
|
|
50
|
+
appliesToScope?(scope: string | null | undefined): boolean;
|
|
51
|
+
/** Scoped ceilings only: the pattern this ceiling meters against, or "*". */
|
|
52
|
+
readonly meterKey?: string;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The request-context field a ceiling reads. Prefers an explicit `ctxField`,
|
|
56
|
+
* then the caller-keyed `field`, then the ceiling's own `key`.
|
|
57
|
+
*/
|
|
58
|
+
export declare function ctxFieldOf(ceiling: Ceiling): string;
|
|
59
|
+
/** Uniform human-readable rendering of any ceiling. Never parsed back. */
|
|
60
|
+
export declare function describe(ceiling: Ceiling): string;
|
|
61
|
+
/**
|
|
62
|
+
* A METERED ceiling bounds a consumed quantity the caller must declare (rows
|
|
63
|
+
* read, spend, calls) — by convention its key starts with "max_". Rank and
|
|
64
|
+
* membership ceilings are not metered: omitting them from a context means "not
|
|
65
|
+
* asserting anything here", not "consuming an undeclared amount".
|
|
66
|
+
*/
|
|
67
|
+
export declare function isMetered(ceiling: Ceiling): boolean;
|
|
68
|
+
/** Per-call cap on rows read or returned. Context field: "rows". */
|
|
69
|
+
export declare class RowLimit implements Ceiling {
|
|
70
|
+
readonly maxRows: number;
|
|
71
|
+
readonly key = "max_rows";
|
|
72
|
+
readonly ctxField = "rows";
|
|
73
|
+
constructor(maxRows: number);
|
|
74
|
+
permits(ctx: Context): Decision;
|
|
75
|
+
describe(): string;
|
|
76
|
+
narrow(other: Ceiling): RowLimit;
|
|
77
|
+
subsumes(other: Ceiling): boolean;
|
|
78
|
+
toWire(): Record<string, Json>;
|
|
79
|
+
static fromWire(d: Record<string, Json>): RowLimit;
|
|
80
|
+
}
|
|
81
|
+
/** Per-call cap on spend, currency-agnostic. Context field: "spend". */
|
|
82
|
+
export declare class SpendCap implements Ceiling {
|
|
83
|
+
readonly maxSpend: number;
|
|
84
|
+
readonly key = "max_spend";
|
|
85
|
+
readonly ctxField = "spend";
|
|
86
|
+
constructor(maxSpend: number);
|
|
87
|
+
permits(ctx: Context): Decision;
|
|
88
|
+
describe(): string;
|
|
89
|
+
narrow(other: Ceiling): SpendCap;
|
|
90
|
+
subsumes(other: Ceiling): boolean;
|
|
91
|
+
toWire(): Record<string, Json>;
|
|
92
|
+
static fromWire(d: Record<string, Json>): SpendCap;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Cap on a call COUNT. Context field: "calls" — the running count including
|
|
96
|
+
* this call.
|
|
97
|
+
*
|
|
98
|
+
* `appliesTo` makes the ceiling SCOPED: it only bites requests for that scope
|
|
99
|
+
* (wildcards as in scopes: "fs.write", "web.*"). A scoped limit is its own
|
|
100
|
+
* dimension — `key` becomes `max_calls[<appliesTo>]` — so an unscoped and a
|
|
101
|
+
* scoped limit coexist in one Authority and pair independently.
|
|
102
|
+
*
|
|
103
|
+
* `Guard.check` supplies `calls` itself, per (node, pattern), when the caller
|
|
104
|
+
* does not; an explicit `calls` in the context still wins.
|
|
105
|
+
*/
|
|
106
|
+
export declare class CallLimit implements Ceiling {
|
|
107
|
+
readonly maxCalls: number;
|
|
108
|
+
readonly appliesTo: string | null;
|
|
109
|
+
readonly key: string;
|
|
110
|
+
readonly ctxField: string;
|
|
111
|
+
constructor(maxCalls: number, appliesTo?: string | null);
|
|
112
|
+
/** What this ceiling counts: the pattern it applies to, or every call. */
|
|
113
|
+
get meterKey(): string;
|
|
114
|
+
appliesToScope(scope: string | null | undefined): boolean;
|
|
115
|
+
permits(ctx: Context): Decision;
|
|
116
|
+
describe(): string;
|
|
117
|
+
narrow(other: Ceiling): CallLimit;
|
|
118
|
+
subsumes(other: Ceiling): boolean;
|
|
119
|
+
toWire(): Record<string, Json>;
|
|
120
|
+
static fromWire(d: Record<string, Json>): CallLimit;
|
|
121
|
+
}
|
|
122
|
+
/** Ordered-enum egress ceiling: none < internal < any. Context field: "egress". */
|
|
123
|
+
export declare class EgressRank implements Ceiling {
|
|
124
|
+
readonly level: string;
|
|
125
|
+
readonly key = "egress";
|
|
126
|
+
readonly ctxField = "egress";
|
|
127
|
+
constructor(level: string);
|
|
128
|
+
permits(ctx: Context): Decision;
|
|
129
|
+
describe(): string;
|
|
130
|
+
narrow(other: Ceiling): EgressRank;
|
|
131
|
+
subsumes(other: Ceiling): boolean;
|
|
132
|
+
toWire(): Record<string, Json>;
|
|
133
|
+
static fromWire(d: Record<string, Json>): EgressRank;
|
|
134
|
+
}
|
|
135
|
+
/** Membership allow-list: the context value MUST be one of `oneOf`. */
|
|
136
|
+
export declare class Allow implements Ceiling {
|
|
137
|
+
readonly key: string;
|
|
138
|
+
readonly field: string | null;
|
|
139
|
+
readonly oneOf: ReadonlySet<Json>;
|
|
140
|
+
constructor(key: string, oneOf: Iterable<Json>, field?: string | null);
|
|
141
|
+
private ctxKey;
|
|
142
|
+
permits(ctx: Context): Decision;
|
|
143
|
+
describe(): string;
|
|
144
|
+
narrow(other: Ceiling): Allow;
|
|
145
|
+
subsumes(other: Ceiling): boolean;
|
|
146
|
+
toWire(): Record<string, Json>;
|
|
147
|
+
static fromWire(d: Record<string, Json>): Allow;
|
|
148
|
+
}
|
|
149
|
+
/** Membership deny-list: the context value MUST NOT be one of `notOneOf`. */
|
|
150
|
+
export declare class Deny implements Ceiling {
|
|
151
|
+
readonly key: string;
|
|
152
|
+
readonly field: string | null;
|
|
153
|
+
readonly notOneOf: ReadonlySet<Json>;
|
|
154
|
+
constructor(key: string, notOneOf: Iterable<Json>, field?: string | null);
|
|
155
|
+
private ctxKey;
|
|
156
|
+
permits(ctx: Context): Decision;
|
|
157
|
+
describe(): string;
|
|
158
|
+
narrow(other: Ceiling): Deny;
|
|
159
|
+
subsumes(other: Ceiling): boolean;
|
|
160
|
+
toWire(): Record<string, Json>;
|
|
161
|
+
static fromWire(d: Record<string, Json>): Deny;
|
|
162
|
+
}
|
|
163
|
+
/** String-prefix bound: the context value MUST start with `prefix`. */
|
|
164
|
+
export declare class Prefix implements Ceiling {
|
|
165
|
+
readonly key: string;
|
|
166
|
+
readonly prefix: string;
|
|
167
|
+
readonly field: string | null;
|
|
168
|
+
constructor(key: string, prefix: string, field?: string | null);
|
|
169
|
+
private ctxKey;
|
|
170
|
+
permits(ctx: Context): Decision;
|
|
171
|
+
describe(): string;
|
|
172
|
+
narrow(other: Ceiling): Prefix;
|
|
173
|
+
subsumes(other: Ceiling): boolean;
|
|
174
|
+
toWire(): Record<string, Json>;
|
|
175
|
+
static fromWire(d: Record<string, Json>): Prefix;
|
|
176
|
+
}
|
|
177
|
+
export interface CeilingClass {
|
|
178
|
+
fromWire(d: Record<string, Json>): Ceiling;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Register a ceiling class's `fromWire` under a wire discriminator.
|
|
182
|
+
* Re-registering replaces the previous mapping — callers may shadow a built-in
|
|
183
|
+
* deliberately, but should do so knowingly.
|
|
184
|
+
*/
|
|
185
|
+
export declare function registerCeiling(key: string, cls: CeilingClass): void;
|
|
186
|
+
/**
|
|
187
|
+
* Fail-closed placeholder for a wire constraint this build does not recognise.
|
|
188
|
+
*
|
|
189
|
+
* `permits` always denies. `narrow` stays an unknown ceiling, so it can never
|
|
190
|
+
* resolve to something more permissive than "deny everything". `subsumes` is
|
|
191
|
+
* true only against an identical unknown ceiling — just enough reflexivity for
|
|
192
|
+
* `isNarrowerThan(self)`. `toWire` preserves the original bytes losslessly, so
|
|
193
|
+
* a chain that merely forwards constraints can still do so.
|
|
194
|
+
*/
|
|
195
|
+
export declare class UnknownCeiling implements Ceiling {
|
|
196
|
+
readonly raw: Record<string, Json>;
|
|
197
|
+
readonly key: string;
|
|
198
|
+
constructor(key: Json, raw?: Record<string, Json>);
|
|
199
|
+
permits(_ctx: Context): Decision;
|
|
200
|
+
narrow(_other: Ceiling): UnknownCeiling;
|
|
201
|
+
subsumes(other: Ceiling): boolean;
|
|
202
|
+
toWire(): Record<string, Json>;
|
|
203
|
+
static fromWire(d: Record<string, Json>): UnknownCeiling;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Reconstruct a Ceiling from its wire form. Routes on "type" when present (it
|
|
207
|
+
* disambiguates the generic ceilings), else on "key". An unrecognised
|
|
208
|
+
* discriminator fails closed via `UnknownCeiling`.
|
|
209
|
+
*/
|
|
210
|
+
export declare function ceilingFromWire(wire: CJson): Ceiling;
|
|
211
|
+
//# sourceMappingURL=ceilings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ceilings.d.ts","sourceRoot":"","sources":["../../src/ceilings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAwC,KAAK,KAAK,EAAE,KAAK,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAC7F,OAAO,EAAE,QAAQ,EAAsB,MAAM,cAAc,CAAC;AAE5D,wEAAwE;AACxE,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAE3C,qEAAqE;AACrE,MAAM,WAAW,OAAO;IACtB,8EAA8E;IAC9E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,gFAAgF;IAChF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;OAIG;IACH,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,CAAC;IAEhC;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IAEhC,gEAAgE;IAChE,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IAElC,qEAAqE;IACrE,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAE/B,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,MAAM,CAAC;IAEpB,wEAAwE;IACxE,cAAc,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC;IAE3D,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAYD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAInD;AAED,0EAA0E;AAC1E,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAGjD;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAEnD;AAmBD,oEAAoE;AACpE,qBAAa,QAAS,YAAW,OAAO;IAG1B,QAAQ,CAAC,OAAO,EAAE,MAAM;IAFpC,QAAQ,CAAC,GAAG,cAAc;IAC1B,QAAQ,CAAC,QAAQ,UAAU;gBACN,OAAO,EAAE,MAAM;IAEpC,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ;IAY/B,QAAQ,IAAI,MAAM;IAIlB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ;IAIhC,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;IAIjC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC;IAI9B,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,QAAQ;CAGnD;AAED,wEAAwE;AACxE,qBAAa,QAAS,YAAW,OAAO;IAG1B,QAAQ,CAAC,QAAQ,EAAE,MAAM;IAFrC,QAAQ,CAAC,GAAG,eAAe;IAC3B,QAAQ,CAAC,QAAQ,WAAW;gBACP,QAAQ,EAAE,MAAM;IAErC,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ;IAY/B,QAAQ,IAAI,MAAM;IAIlB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ;IAIhC,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;IAIjC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC;IAI9B,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,QAAQ;CAGnD;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,SAAU,YAAW,OAAO;IAKrC,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IALnC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAGf,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,MAAM,GAAG,IAAW;IAM1C,0EAA0E;IAC1E,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO;IAMzD,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ;IAa/B,QAAQ,IAAI,MAAM;IAIlB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS;IAIjC,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;IAIjC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC;IAK9B,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,SAAS;CAGpD;AAED,mFAAmF;AACnF,qBAAa,UAAW,YAAW,OAAO;IAG5B,QAAQ,CAAC,KAAK,EAAE,MAAM;IAFlC,QAAQ,CAAC,GAAG,YAAY;IACxB,QAAQ,CAAC,QAAQ,YAAY;gBACR,KAAK,EAAE,MAAM;IAElC,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ;IAc/B,QAAQ,IAAI,MAAM;IAIlB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU;IAKlC,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;IAIjC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC;IAI9B,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,UAAU;CAGrD;AAQD,uEAAuE;AACvE,qBAAa,KAAM,YAAW,OAAO;IAGjC,QAAQ,CAAC,GAAG,EAAE,MAAM;IAEpB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAJ/B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;gBAEvB,GAAG,EAAE,MAAM,EACpB,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,EACZ,KAAK,GAAE,MAAM,GAAG,IAAW;IAKtC,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ;IAY/B,QAAQ,IAAI,MAAM;IAIlB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK;IAK7B,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;IAIjC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC;IAM9B,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,KAAK;CAOhD;AAED,6EAA6E;AAC7E,qBAAa,IAAK,YAAW,OAAO;IAGhC,QAAQ,CAAC,GAAG,EAAE,MAAM;IAEpB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAJ/B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;gBAE1B,GAAG,EAAE,MAAM,EACpB,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,EACf,KAAK,GAAE,MAAM,GAAG,IAAW;IAKtC,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ;IAY/B,QAAQ,IAAI,MAAM;IAIlB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAK5B,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;IAMjC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC;IAU9B,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,IAAI;CAO/C;AAED,uEAAuE;AACvE,qBAAa,MAAO,YAAW,OAAO;IAElC,QAAQ,CAAC,GAAG,EAAE,MAAM;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;gBAFpB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,MAAM,GAAG,IAAW;IAGtC,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ;IAc/B,QAAQ,IAAI,MAAM;IAIlB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM;IAc9B,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;IAIjC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC;IAM9B,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,MAAM;CAOjD;AAQD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,OAAO,CAAC;CAC5C;AAID;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,IAAI,CAEpE;AAED;;;;;;;;GAQG;AACH,qBAAa,cAAe,YAAW,OAAO;IAI1C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC;IAHpC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;gBAEnB,GAAG,EAAE,IAAI,EACA,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAM;IAKzC,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ;IAShC,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,cAAc;IAIvC,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;IAOjC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC;IAI9B,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,cAAc;CAGzD;AAQD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,KAAK,GAAG,OAAO,CAMpD"}
|