aontu 0.50.1 → 0.52.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/bin/aontu-lsp.js +6 -0
- package/bin/aontu.js +7 -0
- package/dist/aontu.d.ts +4 -2
- package/dist/aontu.js +21 -8
- package/dist/aontu.js.map +1 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +43 -53
- package/dist/cli.js.map +1 -1
- package/dist/ctx.js +1 -1
- package/dist/ctx.js.map +1 -1
- package/dist/err.js +3 -2
- package/dist/err.js.map +1 -1
- package/dist/exactjson.d.ts +37 -0
- package/dist/exactjson.js +228 -0
- package/dist/exactjson.js.map +1 -0
- package/dist/hints.d.ts +3 -1
- package/dist/hints.js +187 -5
- package/dist/hints.js.map +1 -1
- package/dist/keyorder.d.ts +9 -0
- package/dist/keyorder.js +65 -0
- package/dist/keyorder.js.map +1 -0
- package/dist/lang.js +263 -30
- package/dist/lang.js.map +1 -1
- package/dist/lsp-server.d.ts +2 -2
- package/dist/lsp-server.js +10 -10
- package/dist/lsp-server.js.map +1 -1
- package/dist/lsp.js +39 -21
- package/dist/lsp.js.map +1 -1
- package/dist/site.js +1 -1
- package/dist/site.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/unify.js +48 -1
- package/dist/unify.js.map +1 -1
- package/dist/utility.js +3 -8
- package/dist/utility.js.map +1 -1
- package/dist/val/BagVal.js +9 -6
- package/dist/val/BagVal.js.map +1 -1
- package/dist/val/BigDecimalVal.d.ts +13 -0
- package/dist/val/BigDecimalVal.js +80 -0
- package/dist/val/BigDecimalVal.js.map +1 -0
- package/dist/val/BigIntegerVal.d.ts +11 -0
- package/dist/val/BigIntegerVal.js +75 -0
- package/dist/val/BigIntegerVal.js.map +1 -0
- package/dist/val/BooleanVal.js +1 -1
- package/dist/val/BooleanVal.js.map +1 -1
- package/dist/val/CloseFuncVal.js +1 -1
- package/dist/val/CloseFuncVal.js.map +1 -1
- package/dist/val/ConjunctVal.js +1 -1
- package/dist/val/ConjunctVal.js.map +1 -1
- package/dist/val/ConstraintVal.d.ts +56 -0
- package/dist/val/ConstraintVal.js +407 -0
- package/dist/val/ConstraintVal.js.map +1 -0
- package/dist/val/CopyFuncVal.js +1 -1
- package/dist/val/CopyFuncVal.js.map +1 -1
- package/dist/val/Decimal.d.ts +32 -0
- package/dist/val/Decimal.js +318 -0
- package/dist/val/Decimal.js.map +1 -0
- package/dist/val/DisjunctVal.js +1 -29
- package/dist/val/DisjunctVal.js.map +1 -1
- package/dist/val/ExpectVal.js +1 -1
- package/dist/val/ExpectVal.js.map +1 -1
- package/dist/val/FeatureVal.js +1 -1
- package/dist/val/FeatureVal.js.map +1 -1
- package/dist/val/FuncBaseVal.js +1 -1
- package/dist/val/FuncBaseVal.js.map +1 -1
- package/dist/val/HideFuncVal.js +1 -1
- package/dist/val/HideFuncVal.js.map +1 -1
- package/dist/val/IntegerVal.d.ts +2 -0
- package/dist/val/IntegerVal.js +77 -5
- package/dist/val/IntegerVal.js.map +1 -1
- package/dist/val/JunctionVal.js +1 -1
- package/dist/val/JunctionVal.js.map +1 -1
- package/dist/val/KeyFuncVal.d.ts +1 -1
- package/dist/val/KeyFuncVal.js +34 -4
- package/dist/val/KeyFuncVal.js.map +1 -1
- package/dist/val/ListVal.js +7 -7
- package/dist/val/ListVal.js.map +1 -1
- package/dist/val/LowerFuncVal.js +21 -4
- package/dist/val/LowerFuncVal.js.map +1 -1
- package/dist/val/MapVal.js +17 -13
- package/dist/val/MapVal.js.map +1 -1
- package/dist/val/MoveFuncVal.js +26 -9
- package/dist/val/MoveFuncVal.js.map +1 -1
- package/dist/val/NilVal.d.ts +1 -0
- package/dist/val/NilVal.js +10 -3
- package/dist/val/NilVal.js.map +1 -1
- package/dist/val/NullVal.js +1 -1
- package/dist/val/NullVal.js.map +1 -1
- package/dist/val/NumberVal.d.ts +1 -0
- package/dist/val/NumberVal.js +25 -4
- package/dist/val/NumberVal.js.map +1 -1
- package/dist/val/OpBaseVal.js +10 -8
- package/dist/val/OpBaseVal.js.map +1 -1
- package/dist/val/OpenFuncVal.js +1 -1
- package/dist/val/OpenFuncVal.js.map +1 -1
- package/dist/val/PathFuncVal.js +10 -2
- package/dist/val/PathFuncVal.js.map +1 -1
- package/dist/val/PlusOpVal.d.ts +3 -1
- package/dist/val/PlusOpVal.js +140 -29
- package/dist/val/PlusOpVal.js.map +1 -1
- package/dist/val/PrefFuncVal.js +1 -1
- package/dist/val/PrefFuncVal.js.map +1 -1
- package/dist/val/PrefVal.d.ts +2 -0
- package/dist/val/PrefVal.js +44 -7
- package/dist/val/PrefVal.js.map +1 -1
- package/dist/val/RefVal.d.ts +2 -0
- package/dist/val/RefVal.js +135 -11
- package/dist/val/RefVal.js.map +1 -1
- package/dist/val/ScalarKindVal.d.ts +12 -2
- package/dist/val/ScalarKindVal.js +108 -13
- package/dist/val/ScalarKindVal.js.map +1 -1
- package/dist/val/ScalarVal.d.ts +1 -0
- package/dist/val/ScalarVal.js +18 -3
- package/dist/val/ScalarVal.js.map +1 -1
- package/dist/val/StringVal.js +1 -1
- package/dist/val/StringVal.js.map +1 -1
- package/dist/val/SuperFuncVal.d.ts +1 -1
- package/dist/val/SuperFuncVal.js +15 -2
- package/dist/val/SuperFuncVal.js.map +1 -1
- package/dist/val/TopVal.js +1 -1
- package/dist/val/TopVal.js.map +1 -1
- package/dist/val/TypeFuncVal.js +1 -1
- package/dist/val/TypeFuncVal.js.map +1 -1
- package/dist/val/UpperFuncVal.js +21 -4
- package/dist/val/UpperFuncVal.js.map +1 -1
- package/dist/val/Val.d.ts +1 -1
- package/dist/val/Val.js +11 -21
- package/dist/val/Val.js.map +1 -1
- package/dist/val/VarVal.js +8 -2
- package/dist/val/VarVal.js.map +1 -1
- package/dist/val/numcmp.d.ts +14 -0
- package/dist/val/numcmp.js +134 -0
- package/dist/val/numcmp.js.map +1 -0
- package/dist/val/numkind.d.ts +6 -0
- package/dist/val/numkind.js +224 -0
- package/dist/val/numkind.js.map +1 -0
- package/dist/val/valutil.d.ts +1 -0
- package/dist/val/valutil.js +35 -0
- package/dist/val/valutil.js.map +1 -1
- package/package.json +7 -5
- package/src/aontu.ts +26 -9
- package/src/cli.ts +48 -21
- package/src/ctx.ts +1 -1
- package/src/err.ts +3 -2
- package/src/exactjson.ts +254 -0
- package/src/hints.ts +213 -4
- package/src/keyorder.ts +73 -0
- package/src/lang.ts +303 -31
- package/src/lsp-server.ts +17 -15
- package/src/lsp.ts +37 -14
- package/src/site.ts +1 -1
- package/src/type.ts +1 -1
- package/src/unify.ts +52 -1
- package/src/utility.ts +3 -9
- package/src/val/BagVal.ts +9 -6
- package/src/val/BigDecimalVal.ts +117 -0
- package/src/val/BigIntegerVal.ts +110 -0
- package/src/val/BooleanVal.ts +1 -1
- package/src/val/CloseFuncVal.ts +1 -1
- package/src/val/ConjunctVal.ts +1 -1
- package/src/val/ConstraintVal.ts +561 -0
- package/src/val/CopyFuncVal.ts +1 -1
- package/src/val/Decimal.ts +385 -0
- package/src/val/DisjunctVal.ts +1 -37
- package/src/val/ExpectVal.ts +1 -1
- package/src/val/FeatureVal.ts +1 -1
- package/src/val/FuncBaseVal.ts +1 -1
- package/src/val/HideFuncVal.ts +1 -1
- package/src/val/IntegerVal.ts +81 -5
- package/src/val/JunctionVal.ts +1 -1
- package/src/val/KeyFuncVal.ts +36 -4
- package/src/val/ListVal.ts +3 -5
- package/src/val/LowerFuncVal.ts +22 -5
- package/src/val/MapVal.ts +13 -9
- package/src/val/MoveFuncVal.ts +27 -10
- package/src/val/NilVal.ts +13 -3
- package/src/val/NullVal.ts +1 -1
- package/src/val/NumberVal.ts +27 -4
- package/src/val/OpBaseVal.ts +10 -10
- package/src/val/OpenFuncVal.ts +1 -1
- package/src/val/PathFuncVal.ts +10 -2
- package/src/val/PlusOpVal.ts +168 -32
- package/src/val/PrefFuncVal.ts +1 -1
- package/src/val/PrefVal.ts +70 -8
- package/src/val/RefVal.ts +143 -11
- package/src/val/ScalarKindVal.ts +123 -12
- package/src/val/ScalarVal.ts +20 -3
- package/src/val/StringVal.ts +1 -1
- package/src/val/SuperFuncVal.ts +15 -2
- package/src/val/TopVal.ts +1 -1
- package/src/val/TypeFuncVal.ts +1 -1
- package/src/val/UpperFuncVal.ts +22 -5
- package/src/val/Val.ts +13 -8
- package/src/val/VarVal.ts +8 -2
- package/src/val/numcmp.ts +189 -0
- package/src/val/numkind.ts +256 -0
- package/src/val/valutil.ts +36 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.exactJSON = exactJSON;
|
|
5
|
+
/*
|
|
6
|
+
* D9 -- THE EXACT JSON EMITTER.
|
|
7
|
+
*
|
|
8
|
+
* `generate()` returns NATIVE values, and once a document opts into the
|
|
9
|
+
* exact leaves two of them are not things `JSON.stringify` can write: a
|
|
10
|
+
* biginteger generates as a native `bigint`, and a bigdecimal generates
|
|
11
|
+
* as a `Decimal`. `JSON.stringify` THROWS on a bigint ("Do not know how
|
|
12
|
+
* to serialize a BigInt") and a `replacer` cannot rescue it, because a
|
|
13
|
+
* replacer may only return another *value* -- everything it returns that
|
|
14
|
+
* is not already a JSON primitive gets quoted, so the exact digits could
|
|
15
|
+
* only come back as a JSON *string*, which is a different document.
|
|
16
|
+
*
|
|
17
|
+
* JSON itself was never the obstacle. A JSON number is arbitrary-
|
|
18
|
+
* precision decimal TEXT: `{"x":9007199254740993}` is a perfectly legal
|
|
19
|
+
* document that every conforming parser reads, and Go's `encoding/json`
|
|
20
|
+
* already emits exactly that for a `*big.Int`. Only JavaScript's
|
|
21
|
+
* serialiser stands in the way, so aontu ships its own.
|
|
22
|
+
*
|
|
23
|
+
* WHY THIS IS PUBLIC API and not a CLI internal: D9 promises that an
|
|
24
|
+
* exact value reaches JSON as exact digits. A library consumer whose
|
|
25
|
+
* document contains `0d9007199254740993` has no other supported way to
|
|
26
|
+
* keep that promise -- hiding the only implementation behind the command
|
|
27
|
+
* line would leave the contract unfulfillable from the library. The
|
|
28
|
+
* `aontu` CLI consumes this same export (with `indent`), and so does the
|
|
29
|
+
* shared suite's byte-exact `gens` mode, so there is exactly one set of
|
|
30
|
+
* bytes to keep in step with the Go port.
|
|
31
|
+
*
|
|
32
|
+
* PARITY WITH GO. The output must match Go's
|
|
33
|
+
* `json.Encoder` + `SetEscapeHTML(false)` (see specGens in
|
|
34
|
+
* go/spec_test.go) byte for byte:
|
|
35
|
+
*
|
|
36
|
+
* - Key order is the order `generate()` produced. Both ports already
|
|
37
|
+
* sort map keys (see the entries sort in BagVal.gen; Go's encoder
|
|
38
|
+
* sorts map keys), so neither has to sort again here.
|
|
39
|
+
* - Strings keep JavaScript's escaping, which is what the `gens` mode
|
|
40
|
+
* settled on when it turned Go's HTML escaping OFF so that `<`, `>`
|
|
41
|
+
* and `&` stay literal in both ports. U+2028/U+2029 are the one
|
|
42
|
+
* place JS and Go disagree by default -- Go escapes them, JS does
|
|
43
|
+
* not -- so they are escaped here too, which is both legal JSON and
|
|
44
|
+
* the safer output (it can be embedded in a JavaScript source).
|
|
45
|
+
* - Numbers keep JavaScript's `Number.prototype.toString` form, which
|
|
46
|
+
* is already what Go's encoder produces: fixed notation inside
|
|
47
|
+
* [1e-6, 1e21) and an unpadded, always-signed exponent outside it
|
|
48
|
+
* (`1e+21`, `1e-7`).
|
|
49
|
+
* - A bigint writes its digits; a Decimal writes its plain digit form
|
|
50
|
+
* (`1000.0`, `0.1`, `-1.5`) -- no `0d` marker, since that belongs to
|
|
51
|
+
* canon and is not JSON, but an integral bigdecimal keeps its `.0`
|
|
52
|
+
* so the JSON still shows a decimal. Go's `*Decimal.MarshalJSON`
|
|
53
|
+
* mirrors this.
|
|
54
|
+
*
|
|
55
|
+
* NOTE that byte-exact output CANNOT check the other half of D9: an
|
|
56
|
+
* integral bigdecimal and a biginteger can serialise to different text,
|
|
57
|
+
* but a biginteger and an ordinary integer serialise to the SAME text
|
|
58
|
+
* while `generate()` returned the wrong runtime type. Canon pins the AST
|
|
59
|
+
* kind, `gens` pins these bytes, and only the per-port API tests
|
|
60
|
+
* (ts/test/exactjson.test.ts here) pin the returned object.
|
|
61
|
+
*/
|
|
62
|
+
const Decimal_1 = require("./val/Decimal");
|
|
63
|
+
const err_1 = require("./err");
|
|
64
|
+
const keyorder_1 = require("./keyorder");
|
|
65
|
+
// JS leaves U+2028 (LINE SEPARATOR) and U+2029 (PARAGRAPH SEPARATOR)
|
|
66
|
+
// literal in a JSON string; Go's encoder escapes them. Byte parity wins.
|
|
67
|
+
const LSPS_RE = new RegExp('[\u2028\u2029]', 'g');
|
|
68
|
+
// JSON.stringify's `space` argument, normalised the way the spec does:
|
|
69
|
+
// a number is clamped to 0..10 spaces, a string is truncated to 10
|
|
70
|
+
// characters, anything else means "compact".
|
|
71
|
+
function indentUnit(indent) {
|
|
72
|
+
if ('number' === typeof indent) {
|
|
73
|
+
const n = Math.min(10, Math.floor(indent));
|
|
74
|
+
return 0 < n ? ' '.repeat(n) : '';
|
|
75
|
+
}
|
|
76
|
+
if ('string' === typeof indent) {
|
|
77
|
+
return indent.slice(0, 10);
|
|
78
|
+
}
|
|
79
|
+
return '';
|
|
80
|
+
}
|
|
81
|
+
function quote(s) {
|
|
82
|
+
const out = JSON.stringify(s);
|
|
83
|
+
// A raw separator can only appear as itself in the output (never
|
|
84
|
+
// inside an escape), so a straight replace is safe.
|
|
85
|
+
return out.replace(LSPS_RE, (c) => '\u2028' === c ? '\\u2028' : '\\u2029');
|
|
86
|
+
}
|
|
87
|
+
// True for a value JSON.stringify omits from an object and writes as
|
|
88
|
+
// `null` inside an array. generate() never produces one, but a consumer
|
|
89
|
+
// splicing its own data into the result might.
|
|
90
|
+
function skipped(v) {
|
|
91
|
+
return undefined === v || 'function' === typeof v || 'symbol' === typeof v;
|
|
92
|
+
}
|
|
93
|
+
// `seen` tracks the containers on the CURRENT path only (added on entry,
|
|
94
|
+
// removed on exit), so a shared subtree -- which unification can easily
|
|
95
|
+
// produce -- serialises fine and only a true cycle is refused, exactly
|
|
96
|
+
// as JSON.stringify does it.
|
|
97
|
+
function emit(v, unit, pad, seen) {
|
|
98
|
+
if (null === v) {
|
|
99
|
+
return 'null';
|
|
100
|
+
}
|
|
101
|
+
const t = typeof v;
|
|
102
|
+
if ('string' === t) {
|
|
103
|
+
return quote(v);
|
|
104
|
+
}
|
|
105
|
+
if ('number' === t) {
|
|
106
|
+
// JSON has no NaN, no Infinity and no negative zero: JSON.stringify
|
|
107
|
+
// writes `null` for the first two and `0` for the last, and gen()
|
|
108
|
+
// has already normalised -0 away (R2).
|
|
109
|
+
return JSON.stringify(v);
|
|
110
|
+
}
|
|
111
|
+
if ('bigint' === t) {
|
|
112
|
+
// THE POINT OF THIS MODULE: exact digits, as a raw JSON number.
|
|
113
|
+
return v.toString();
|
|
114
|
+
}
|
|
115
|
+
if ('boolean' === t) {
|
|
116
|
+
return v ? 'true' : 'false';
|
|
117
|
+
}
|
|
118
|
+
if (skipped(v)) {
|
|
119
|
+
return 'null';
|
|
120
|
+
}
|
|
121
|
+
// Before any other object handling: a Decimal is a value, not a
|
|
122
|
+
// structure, and its plain digit form is the JSON number.
|
|
123
|
+
if (v instanceof Decimal_1.Decimal) {
|
|
124
|
+
return v.toString();
|
|
125
|
+
}
|
|
126
|
+
if ('object' === t && 'function' === typeof v.toJSON) {
|
|
127
|
+
return emit(v.toJSON(), unit, pad, seen);
|
|
128
|
+
}
|
|
129
|
+
if (seen.has(v)) {
|
|
130
|
+
throw new err_1.AontuError('aontu: cannot convert circular structure to JSON');
|
|
131
|
+
}
|
|
132
|
+
seen.add(v);
|
|
133
|
+
const inner = pad + unit;
|
|
134
|
+
const nl = '' === unit ? '' : '\n';
|
|
135
|
+
let out;
|
|
136
|
+
if (Array.isArray(v)) {
|
|
137
|
+
if (0 === v.length) {
|
|
138
|
+
out = '[]';
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
const parts = v.map((e) => inner + emit(skipped(e) ? null : e, unit, inner, seen));
|
|
142
|
+
out = '[' + nl + parts.join(',' + nl) + nl + pad + ']';
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
const colon = '' === unit ? ':' : ': ';
|
|
147
|
+
const parts = [];
|
|
148
|
+
// OWN enumerable keys, SORTED. A `for ... in` here would additionally
|
|
149
|
+
// walk the prototype chain.
|
|
150
|
+
//
|
|
151
|
+
// WHY THE SORT IS HERE AND NOT IN gen(). BagVal.gen already sorts map
|
|
152
|
+
// entries lexicographically -- and then writes them into a plain JS
|
|
153
|
+
// object, where ECMAScript throws that sort away. OrdinaryOwnPropertyKeys
|
|
154
|
+
// lists canonical ARRAY-INDEX keys first, in ascending NUMERIC order,
|
|
155
|
+
// and only then the remaining string keys in insertion order. So
|
|
156
|
+
// `{9:1,10:2}` came back out as 9 before 10, and `{"!":1,9:2}` put the
|
|
157
|
+
// digit key ahead of the punctuation one.
|
|
158
|
+
//
|
|
159
|
+
// This is not a V8 quirk and not a JSON.stringify quirk; it is the
|
|
160
|
+
// object's own key order, and it CANNOT be fixed upstream, because no
|
|
161
|
+
// JavaScript object can hold "10" before "9". The emitter is the last
|
|
162
|
+
// point that still has the freedom to choose, so it chooses here.
|
|
163
|
+
//
|
|
164
|
+
// The giveaway that it was never a design rule: only indices up to
|
|
165
|
+
// 2^32-2 are hoisted, so `{4294967295:1,4294967296:2,5:3}` emitted as
|
|
166
|
+
// 5, 4294967295, 4294967296 -- and TypeScript's own CANON, which builds
|
|
167
|
+
// text from a sorted list rather than from an object, was lexicographic
|
|
168
|
+
// all along. The port contradicted itself.
|
|
169
|
+
//
|
|
170
|
+
// Lexicographic by UTF-16 code unit, which is what `<` on JS strings
|
|
171
|
+
// does and what MapVal.canon/BagVal.gen already sort by. Go sorts map
|
|
172
|
+
// keys by UTF-8 byte, and the two orders agree on every key that stays
|
|
173
|
+
// inside the BMP; astral-plane keys are a separate, tracked divergence.
|
|
174
|
+
// CODE POINT order (cmpCodePoint), which is what Go's UTF-8 byte sort
|
|
175
|
+
// produces. A bare .sort() is UTF-16 code-unit order, which puts an
|
|
176
|
+
// astral key ahead of everything in U+E000-U+FFFF.
|
|
177
|
+
for (const k of Object.keys(v).sort(keyorder_1.cmpCodePoint)) {
|
|
178
|
+
const cv = v[k];
|
|
179
|
+
if (skipped(cv)) {
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
parts.push(inner + quote(k) + colon + emit(cv, unit, inner, seen));
|
|
183
|
+
}
|
|
184
|
+
out = 0 === parts.length ? '{}' :
|
|
185
|
+
'{' + nl + parts.join(',' + nl) + nl + pad + '}';
|
|
186
|
+
}
|
|
187
|
+
seen.delete(v);
|
|
188
|
+
return out;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Serialise a value produced by `Aontu.generate()` as JSON text,
|
|
192
|
+
* preserving EXACT numbers.
|
|
193
|
+
*
|
|
194
|
+
* Use this instead of `JSON.stringify` on generated output. A document
|
|
195
|
+
* that uses the `0d` exact leaves generates native `bigint` and
|
|
196
|
+
* `Decimal` values; `JSON.stringify` throws on the first and mangles the
|
|
197
|
+
* second, while this emitter writes both as raw JSON numbers with their
|
|
198
|
+
* exact digits -- which is what the D9 generate contract promises, and
|
|
199
|
+
* what the Go port's marshallers produce for the same document.
|
|
200
|
+
*
|
|
201
|
+
* ```ts
|
|
202
|
+
* import { Aontu, exactJSON } from 'aontu'
|
|
203
|
+
*
|
|
204
|
+
* const out = new Aontu().generate('x:0d9007199254740993')
|
|
205
|
+
* typeof out.x // 'bigint'
|
|
206
|
+
* exactJSON(out) // '{"x":9007199254740993}'
|
|
207
|
+
* exactJSON(out, 2) // '{\n "x": 9007199254740993\n}'
|
|
208
|
+
* JSON.stringify(out) // TypeError: Do not know how to serialize a BigInt
|
|
209
|
+
* ```
|
|
210
|
+
*
|
|
211
|
+
* @param value The value to serialise -- normally `generate()` output:
|
|
212
|
+
* `null`, booleans, numbers, strings, `bigint`,
|
|
213
|
+
* `Decimal`, arrays and plain objects. An object with a
|
|
214
|
+
* `toJSON` method is asked for its replacement first
|
|
215
|
+
* (`Decimal` is handled as a number before that check).
|
|
216
|
+
* @param indent Optional indentation, with `JSON.stringify`'s `space`
|
|
217
|
+
* semantics: a number of spaces (clamped to 0..10) or a
|
|
218
|
+
* literal string. Omitted or `0` gives COMPACT output
|
|
219
|
+
* (no spaces, no newlines) -- the form the shared spec
|
|
220
|
+
* suite's `gens` mode compares byte for byte.
|
|
221
|
+
* @returns The JSON text. Unlike `JSON.stringify` this always
|
|
222
|
+
* returns a string: a top-level `undefined` is `null`.
|
|
223
|
+
* @throws {AontuError} if the value contains a reference cycle.
|
|
224
|
+
*/
|
|
225
|
+
function exactJSON(value, indent) {
|
|
226
|
+
return emit(value, indentUnit(indent), '', new Set());
|
|
227
|
+
} /* node:coverage ignore next 6 */
|
|
228
|
+
//# sourceMappingURL=exactjson.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exactjson.js","sourceRoot":"","sources":["../src/exactjson.ts"],"names":[],"mappings":"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"}
|
package/dist/hints.d.ts
CHANGED
|
@@ -5,4 +5,6 @@
|
|
|
5
5
|
* Each value is a human-readable explanation of what the error means.
|
|
6
6
|
*/
|
|
7
7
|
declare const hints: Record<string, string>;
|
|
8
|
-
|
|
8
|
+
declare const codeClasses: Record<string, string>;
|
|
9
|
+
declare function codeClass(code: string): string;
|
|
10
|
+
export { hints, codeClasses, codeClass, };
|
package/dist/hints.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.hints = void 0;
|
|
4
|
+
exports.codeClasses = exports.hints = void 0;
|
|
5
|
+
exports.codeClass = codeClass;
|
|
5
6
|
/**
|
|
6
7
|
* Error code hints for Aontu unification errors.
|
|
7
8
|
*
|
|
@@ -15,12 +16,12 @@ const hints = {
|
|
|
15
16
|
' 1 & 1 -> 1 # Does unify (equal Integers);\n' +
|
|
16
17
|
' a & a -> a # Does unify (equal Strings);\n' +
|
|
17
18
|
' 1 & 2 -> nil # Does not unify (unequal Integers);\n' +
|
|
18
|
-
' 1 & 1.0 -> nil # Does not unify (kinds: Integer &
|
|
19
|
+
' 1 & 1.0 -> nil # Does not unify (kinds: Integer & Float).',
|
|
19
20
|
scalar_kind: 'Literal scalar values of different kinds cannot unify.' +
|
|
20
21
|
'\n \nExamples:\n' +
|
|
21
22
|
' 1 & 1 -> 1 # Does unify (equal Integers);\n' +
|
|
22
23
|
' 1 & a -> nil # Does not unify (Kinds: Integer & String);\n' +
|
|
23
|
-
' 1 & 1.0 -> nil # Does not unify (kinds: Integer &
|
|
24
|
+
' 1 & 1.0 -> nil # Does not unify (kinds: Integer & Float).',
|
|
24
25
|
nil_gen: 'The nil value was present after unification, and nil cannot be\n' +
|
|
25
26
|
'generated because nil is not a literal value.',
|
|
26
27
|
no_gen: 'This value was present after unification, and cannot be generated\n' +
|
|
@@ -37,6 +38,22 @@ const hints = {
|
|
|
37
38
|
unknown_function: 'This function name is not recognized.',
|
|
38
39
|
literal_nil: 'A literal nil cannot unify with any other value.',
|
|
39
40
|
unify_cycle: 'Circular reference detected during unification.',
|
|
41
|
+
constraint: 'This value does not satisfy the constraint. A constraint is the\n' +
|
|
42
|
+
'meet of bound atoms (min, max, above, below) and exclusions (neq)\n' +
|
|
43
|
+
'over one domain; the expected form shown is the normalised\n' +
|
|
44
|
+
'residual the value must satisfy.' +
|
|
45
|
+
'\n \nExamples:\n' +
|
|
46
|
+
' min(0) & 3 -> 3 # Admitted (3 >= 0);\n' +
|
|
47
|
+
' min(0) & 0d5 -> 0d5 # Bounds are leaf-agnostic;\n' +
|
|
48
|
+
' max(65535) & 99999 -> nil # Above the bound;\n' +
|
|
49
|
+
' min(5) & max(3) -> nil # Empty at composition time;\n' +
|
|
50
|
+
' integer & above(1) & below(2) -> nil # No integer in the gap;\n' +
|
|
51
|
+
' neq(1) & 1.0 -> 1.0 # neq excludes leaf AND value.',
|
|
52
|
+
budget_passes: 'The evaluation budget of {limit} fixpoint passes was spent before\n' +
|
|
53
|
+
'the model converged; still refining: {paths}.\n' +
|
|
54
|
+
'This is the evaluator giving up, not a contradiction in the model:\n' +
|
|
55
|
+
'raising the budget helps only a model that is still converging --\n' +
|
|
56
|
+
'a genuine cycle never converges at any budget.',
|
|
40
57
|
conjunct: 'This conjunction (& operator) could not be completed as some terms\n' +
|
|
41
58
|
'could not be resolved.',
|
|
42
59
|
no_path: 'The path reference could not be found.' +
|
|
@@ -51,14 +68,71 @@ const hints = {
|
|
|
51
68
|
'unite': 'Failed to unite two values. The values are incompatible and cannot be unified.',
|
|
52
69
|
'internal': 'Internal error during unification. This indicates an unexpected error in the unification process.',
|
|
53
70
|
// Type mismatch errors
|
|
54
|
-
|
|
55
|
-
|
|
71
|
+
decimal_budget: 'This exact decimal exceeds the exactness budget: at most 4096\n' +
|
|
72
|
+
'coefficient digits and an absolute scale of at most 4096. The\n' +
|
|
73
|
+
'budget applies to computed results as well as to literals.\n' +
|
|
74
|
+
'Aontu never rounds, so a value beyond the budget is refused\n' +
|
|
75
|
+
'rather than approximated.' +
|
|
76
|
+
'\n \nExamples:\n' +
|
|
77
|
+
' 0d1e1000000000 -> nil # Scale far beyond the budget;\n' +
|
|
78
|
+
' 0d1e4000+0d1e-4000 -> nil # An exact sum too wide to hold;\n' +
|
|
79
|
+
' 0d1e-1 -> 0d0.1 # Well within it.',
|
|
80
|
+
lossy_integer_literal: 'This integer literal, {src}, is not exactly representable in\n' +
|
|
81
|
+
'binary64, so storing it would silently round it to a DIFFERENT\n' +
|
|
82
|
+
'number. Aontu refuses rather than corrupts: write it as a `0d`\n' +
|
|
83
|
+
'literal to get the exact integer.\n' +
|
|
84
|
+
'The rule is exactness, not magnitude -- a literal far outside the\n' +
|
|
85
|
+
'int64 window is still a value when it lands exactly on a binary64.' +
|
|
86
|
+
'\n \nExamples:\n' +
|
|
87
|
+
' 9007199254740992 -> 9007199254740992 # 2^53, exact;\n' +
|
|
88
|
+
' 9007199254740993 -> nil # 2^53+1 is not;\n' +
|
|
89
|
+
' 0d9007199254740993 -> 0d9007199254740993 # ... the exact escape;\n' +
|
|
90
|
+
' 0x7fffffffffffffff -> nil # 2^63-1 rounds up to 2^63;\n' +
|
|
91
|
+
' 100000000000000000000 -> 1e20 # 10^20 is huge and exact.',
|
|
92
|
+
exact_float_mix: 'Aontu cannot mix an exact number with a binary float.\n' +
|
|
93
|
+
'Here the operands are {left} and {right}, in that order.\n' +
|
|
94
|
+
'A big type never silently becomes a binary float, in either\n' +
|
|
95
|
+
'operand order -- binary64 cannot hold every exact value, so the\n' +
|
|
96
|
+
'promotion would throw away the exactness the `0d` leaves exist to\n' +
|
|
97
|
+
'guarantee. Write both operands in the same family (`0d1.0` for the\n' +
|
|
98
|
+
'float, or a plain integer for the big).' +
|
|
99
|
+
'\n \nExamples:\n' +
|
|
100
|
+
' 0d2 + 0d0.5 -> 0d2.5 # Exact with exact (widest leaf wins);\n' +
|
|
101
|
+
' 1 + 0d0.5 -> 0d1.5 # integer is on the exact ladder;\n' +
|
|
102
|
+
' 1 + 2.0 -> 3.0 # ... and float still mixes with integer;\n' +
|
|
103
|
+
' 1.0 + 0d2 -> nil # float with biginteger;\n' +
|
|
104
|
+
' 0d0.5 + 1.0 -> nil # ... and the same the other way round.',
|
|
105
|
+
inexact_integer_sum: 'The `integer` leaf holds a value only when it is integral, within\n' +
|
|
106
|
+
'the int64 range, and exactly representable in binary64. This sum\n' +
|
|
107
|
+
'is not: {sum}.\n' +
|
|
108
|
+
'Aontu adds integers exactly and refuses to store a rounded answer\n' +
|
|
109
|
+
'-- write `0d<digits>` for an exact integer beyond that window.' +
|
|
110
|
+
'\n \nExamples:\n' +
|
|
111
|
+
' 4503599627370496 + 4503599627370496 -> 9007199254740992 # Exact;\n' +
|
|
112
|
+
' 4503599627370496 + 4503599627370497 -> nil # 2^53+1 is not;\n' +
|
|
113
|
+
' 0d4503599627370496 + 0d4503599627370497 -> 0d9007199254740993.',
|
|
114
|
+
'scalar-type': 'Scalar kinds only unify when one contains the other. `number` is\n' +
|
|
115
|
+
'the supertype of the numeric leaves (integer, float, biginteger,\n' +
|
|
116
|
+
'bigdecimal), so meeting it with a leaf gives that leaf; two distinct\n' +
|
|
117
|
+
'leaves describe disjoint sets of values and so have no common lower\n' +
|
|
118
|
+
'bound.' +
|
|
119
|
+
'\n \nExamples:\n' +
|
|
120
|
+
' number & integer -> integer # Does unify (integer is a number);\n' +
|
|
121
|
+
' number & number -> number # Does unify (same kind);\n' +
|
|
122
|
+
' float & integer -> nil # Does not unify (disjoint leaves).',
|
|
123
|
+
'no_scalar_unify': 'Cannot unify scalar values. The scalar values have incompatible types.' +
|
|
124
|
+
'\n \nExamples:\n' +
|
|
125
|
+
' number & 1 -> 1 # Does unify (1 is a number);\n' +
|
|
126
|
+
' integer & 1 -> 1 # Does unify (1 is an integer);\n' +
|
|
127
|
+
' float & 1 -> nil # Does not unify (1 is an integer, not a float);\n' +
|
|
128
|
+
' integer & 1.5 -> nil # Does not unify (1.5 is a float, not an integer).',
|
|
56
129
|
'not-scalar-type': 'Expected a scalar type but got a non-scalar type.',
|
|
57
130
|
'map': 'Type mismatch: expected a map value but got a different type.',
|
|
58
131
|
'list': 'Type mismatch: expected a list value but got a different type.',
|
|
59
132
|
// Argument errors
|
|
60
133
|
'arg': 'Missing required argument. A function requires an argument but none was provided.',
|
|
61
134
|
'invalid-arg': 'Invalid argument provided. The argument does not match the expected type or format.',
|
|
135
|
+
'key_level': 'The argument to key() is a LEVEL: how many steps up the path to look, where 0 is the key of the value itself and the default 1 is its parent. It must therefore be an integer -- `key(2)`, or `key(0d2)` for the exact leaf. A float, a decimal, a string, a boolean, a map or a list is not a level. A level beyond the top of the path is not an error; it yields the empty string.',
|
|
62
136
|
'no_first_arg': 'Missing first argument. The function requires a first argument but none was provided.',
|
|
63
137
|
// Variable errors
|
|
64
138
|
'unknown_var': 'Unknown variable reference. The variable has not been defined.',
|
|
@@ -90,4 +164,112 @@ const hints = {
|
|
|
90
164
|
'op[': 'Operator value error: ',
|
|
91
165
|
};
|
|
92
166
|
exports.hints = hints;
|
|
167
|
+
// codeClasses assigns every error code a CLASS: conflict | incomplete |
|
|
168
|
+
// reference | parse | budget | internal. The contract lives in
|
|
169
|
+
// test/spec/errcodes.tsv (mode `errcode`): the spec suite executes one
|
|
170
|
+
// row per code against this table and asserts SET EQUALITY between the
|
|
171
|
+
// file and these keys, in both implementations (go/hints.go mirrors
|
|
172
|
+
// this map exactly). Codes are append-only and never renamed; a class
|
|
173
|
+
// change is a breaking change. Class rulings (why decimal_budget and
|
|
174
|
+
// lossy_integer_literal are conflict, not budget; why unknown_function
|
|
175
|
+
// is reference) are documented in the tsv header.
|
|
176
|
+
const codeClasses = {
|
|
177
|
+
// parse -- the source text is malformed or unusable
|
|
178
|
+
parse: 'parse',
|
|
179
|
+
syntax: 'parse',
|
|
180
|
+
parse_unknown: 'parse',
|
|
181
|
+
parse_bad_src: 'parse',
|
|
182
|
+
unify_no_src: 'parse',
|
|
183
|
+
incomplete_expression: 'parse',
|
|
184
|
+
not_number: 'parse',
|
|
185
|
+
negative: 'parse',
|
|
186
|
+
decimal_syntax: 'parse',
|
|
187
|
+
// conflict -- no common lower bound, or a value refused by a rule
|
|
188
|
+
// (constraint covers the whole algebra family: membership failure,
|
|
189
|
+
// empty meets at composition time, and domain/kind mixing.)
|
|
190
|
+
constraint: 'conflict',
|
|
191
|
+
scalar_value: 'conflict',
|
|
192
|
+
scalar_kind: 'conflict',
|
|
193
|
+
no_scalar_unify: 'conflict',
|
|
194
|
+
'scalar-type': 'conflict',
|
|
195
|
+
'not-scalar-type': 'conflict',
|
|
196
|
+
map: 'conflict',
|
|
197
|
+
list: 'conflict',
|
|
198
|
+
closed: 'conflict',
|
|
199
|
+
literal_nil: 'conflict',
|
|
200
|
+
nil_gen: 'conflict',
|
|
201
|
+
unite: 'conflict',
|
|
202
|
+
'|:empty': 'conflict',
|
|
203
|
+
'|:empty-dist': 'conflict',
|
|
204
|
+
exact_float_mix: 'conflict',
|
|
205
|
+
inexact_integer_sum: 'conflict',
|
|
206
|
+
decimal_budget: 'conflict',
|
|
207
|
+
lossy_integer_literal: 'conflict',
|
|
208
|
+
arg: 'conflict',
|
|
209
|
+
'invalid-arg': 'conflict',
|
|
210
|
+
no_first_arg: 'conflict',
|
|
211
|
+
key_level: 'conflict',
|
|
212
|
+
func: 'conflict',
|
|
213
|
+
'func:': 'conflict',
|
|
214
|
+
op: 'conflict',
|
|
215
|
+
'op:': 'conflict',
|
|
216
|
+
'op[': 'conflict',
|
|
217
|
+
make: 'conflict',
|
|
218
|
+
resolve: 'conflict',
|
|
219
|
+
operate: 'conflict',
|
|
220
|
+
close: 'conflict',
|
|
221
|
+
// incomplete -- residue: the truth requires more than was supplied
|
|
222
|
+
no_gen: 'incomplete',
|
|
223
|
+
conjunct: 'incomplete',
|
|
224
|
+
mapval_no_gen: 'incomplete',
|
|
225
|
+
mapval_required: 'incomplete',
|
|
226
|
+
mapval_spread_required: 'incomplete',
|
|
227
|
+
listval_no_gen: 'incomplete',
|
|
228
|
+
listval_required: 'incomplete',
|
|
229
|
+
listval_spread_required: 'incomplete',
|
|
230
|
+
required_listelem: 'incomplete',
|
|
231
|
+
// reference -- a name or path that does not resolve
|
|
232
|
+
no_path: 'reference',
|
|
233
|
+
// A PROVEN structural cycle is a defect of the model, not a spent
|
|
234
|
+
// evaluation bound: raising a budget never fixes it (G5's ruling --
|
|
235
|
+
// class budget means "retry with more may help", path_cycle means
|
|
236
|
+
// "fix the model").
|
|
237
|
+
path_cycle: 'reference',
|
|
238
|
+
ref: 'reference',
|
|
239
|
+
'ref[': 'reference',
|
|
240
|
+
var: 'reference',
|
|
241
|
+
'var[': 'reference',
|
|
242
|
+
unknown_var: 'reference',
|
|
243
|
+
invalid_var_kind: 'reference',
|
|
244
|
+
unknown_function: 'reference',
|
|
245
|
+
multisource_not_found: 'reference',
|
|
246
|
+
// budget -- an evaluation bound was exceeded
|
|
247
|
+
unify_cycle: 'budget',
|
|
248
|
+
max_depth: 'budget',
|
|
249
|
+
budget_passes: 'budget',
|
|
250
|
+
// internal -- the engine reached a state it should not reach
|
|
251
|
+
internal: 'internal',
|
|
252
|
+
unify_no_res: 'internal',
|
|
253
|
+
unknown_op: 'internal',
|
|
254
|
+
};
|
|
255
|
+
exports.codeClasses = codeClasses;
|
|
256
|
+
// Dynamic-prefix families: the engine appends a name or value to these
|
|
257
|
+
// (e.g. `func:upper`, `op:+`, `var[string]`, `ref[$.x]`, `op[+]`), so
|
|
258
|
+
// class lookup falls back to the registered prefix.
|
|
259
|
+
const CODE_PREFIXES = ['func:', 'op:', 'op[', 'var[', 'ref['];
|
|
260
|
+
// The class of an error code: an exact registry entry, else the
|
|
261
|
+
// registered dynamic prefix it extends, else `internal` -- an
|
|
262
|
+
// unregistered code is an engine defect, not a user error.
|
|
263
|
+
function codeClass(code) {
|
|
264
|
+
const cls = codeClasses[code];
|
|
265
|
+
if (null != cls) {
|
|
266
|
+
return cls;
|
|
267
|
+
}
|
|
268
|
+
for (const prefix of CODE_PREFIXES) {
|
|
269
|
+
if (code.startsWith(prefix)) {
|
|
270
|
+
return codeClasses[prefix];
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return 'internal';
|
|
274
|
+
} /* node:coverage ignore next 8 */
|
|
93
275
|
//# sourceMappingURL=hints.js.map
|
package/dist/hints.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hints.js","sourceRoot":"","sources":["../src/hints.ts"],"names":[],"mappings":";AAAA,oDAAoD;;;
|
|
1
|
+
{"version":3,"file":"hints.js","sourceRoot":"","sources":["../src/hints.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compare two map keys by Unicode CODE POINT.
|
|
3
|
+
*
|
|
4
|
+
* `String.prototype[Symbol.iterator]` yields whole code points, pairing
|
|
5
|
+
* surrogates, so this is a plain lexicographic compare of code point
|
|
6
|
+
* sequences -- the order Go's UTF-8 byte sort produces.
|
|
7
|
+
*/
|
|
8
|
+
declare function cmpCodePoint(a: string, b: string): number;
|
|
9
|
+
export { cmpCodePoint, };
|
package/dist/keyorder.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.cmpCodePoint = cmpCodePoint;
|
|
5
|
+
/*
|
|
6
|
+
* THE ONE MAP-KEY ORDER, shared by every site that emits keys.
|
|
7
|
+
*
|
|
8
|
+
* Map key order is not meaningful in unification, so both ports sort to
|
|
9
|
+
* make output independent of insertion and unification order. The order
|
|
10
|
+
* they sort into has to be the SAME order, and it was not.
|
|
11
|
+
*
|
|
12
|
+
* JavaScript compares strings by UTF-16 CODE UNIT. An astral character is
|
|
13
|
+
* stored as a surrogate pair beginning D800-DBFF, so `<` puts it BEFORE
|
|
14
|
+
* every character in U+E000-U+FFFF -- ahead of the private use area, of
|
|
15
|
+
* U+FFFD, of U+FFFF. Go sorts map keys as UTF-8 bytes, which is code
|
|
16
|
+
* POINT order, so it puts the astral character last. The two agree on
|
|
17
|
+
* everything below U+D800 and disagree above U+DFFF, which is why this
|
|
18
|
+
* survived: the shared suite had no key above the BMP at all, and three
|
|
19
|
+
* separate comments in the tree asserted the ports already agreed.
|
|
20
|
+
*
|
|
21
|
+
* CODE POINT ORDER WINS, and not merely because Go had it. Go's
|
|
22
|
+
* `generate()` returns a native map, so a consumer's own `json.Marshal`
|
|
23
|
+
* sorts byte-wise no matter what this engine chooses -- picking UTF-16
|
|
24
|
+
* order would leave the TypeScript output disagreeing with what a Go
|
|
25
|
+
* consumer produces from the same document.
|
|
26
|
+
*
|
|
27
|
+
* NOT Buffer.compare, which would be the obvious shortcut. A lone
|
|
28
|
+
* surrogate has no valid UTF-8 encoding, so Buffer.from replaces it with
|
|
29
|
+
* U+FFFD and two DISTINCT keys compare equal -- reintroducing exactly the
|
|
30
|
+
* insertion-order dependence the sort exists to remove. Iterating code
|
|
31
|
+
* points keeps distinct keys distinct.
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* Compare two map keys by Unicode CODE POINT.
|
|
35
|
+
*
|
|
36
|
+
* `String.prototype[Symbol.iterator]` yields whole code points, pairing
|
|
37
|
+
* surrogates, so this is a plain lexicographic compare of code point
|
|
38
|
+
* sequences -- the order Go's UTF-8 byte sort produces.
|
|
39
|
+
*/
|
|
40
|
+
function cmpCodePoint(a, b) {
|
|
41
|
+
// Fast path: identical strings, and the common all-BMP case where the
|
|
42
|
+
// two orders coincide, still walk the iterator -- but the loop exits at
|
|
43
|
+
// the first differing code point, so it is one pass over the shared
|
|
44
|
+
// prefix rather than any conversion or allocation.
|
|
45
|
+
const ai = a[Symbol.iterator]();
|
|
46
|
+
const bi = b[Symbol.iterator]();
|
|
47
|
+
for (;;) {
|
|
48
|
+
const x = ai.next();
|
|
49
|
+
const y = bi.next();
|
|
50
|
+
// A prefix sorts before the string it is a prefix of, and two equal
|
|
51
|
+
// strings compare 0 -- the same rule a byte compare gives.
|
|
52
|
+
if (x.done) {
|
|
53
|
+
return y.done ? 0 : -1;
|
|
54
|
+
}
|
|
55
|
+
if (y.done) {
|
|
56
|
+
return 1;
|
|
57
|
+
}
|
|
58
|
+
const xc = x.value.codePointAt(0);
|
|
59
|
+
const yc = y.value.codePointAt(0);
|
|
60
|
+
if (xc !== yc) {
|
|
61
|
+
return xc < yc ? -1 : 1;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
} /* node:coverage ignore next 6 */
|
|
65
|
+
//# sourceMappingURL=keyorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyorder.js","sourceRoot":"","sources":["../src/keyorder.ts"],"names":[],"mappings":";AAAA,oDAAoD;;QAuElD,YAAY;AArEd;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH;;;;;;GAMG;AACH,SAAS,YAAY,CAAC,CAAS,EAAE,CAAS;IACxC,sEAAsE;IACtE,wEAAwE;IACxE,oEAAoE;IACpE,mDAAmD;IACnD,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAA;IAC/B,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAA;IAE/B,SAAU,CAAC;QACT,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,CAAA;QACnB,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,CAAA;QAEnB,oEAAoE;QACpE,2DAA2D;QAC3D,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YACX,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACxB,CAAC;QACD,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YACX,OAAO,CAAC,CAAA;QACV,CAAC;QAED,MAAM,EAAE,GAAI,CAAC,CAAC,KAAgB,CAAC,WAAW,CAAC,CAAC,CAAW,CAAA;QACvD,MAAM,EAAE,GAAI,CAAC,CAAC,KAAgB,CAAC,WAAW,CAAC,CAAC,CAAW,CAAA;QAEvD,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACd,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACzB,CAAC;IACH,CAAC;AACH,CAAC,CAAC,iCAAiC"}
|