jspurefix 5.11.2 → 5.11.4
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/.gitattributes +4 -0
- package/dist/buffer/index.d.ts +6 -0
- package/dist/buffer/index.js +6 -0
- package/dist/buffer/index.js.map +1 -1
- package/dist/collections/index.d.ts +1 -0
- package/dist/collections/index.js +16 -0
- package/dist/collections/index.js.map +1 -1
- package/dist/config/winston-logger.js +2 -0
- package/dist/config/winston-logger.js.map +1 -1
- package/dist/dictionary/contained/index.d.ts +3 -0
- package/dist/dictionary/contained/index.js +3 -0
- package/dist/dictionary/contained/index.js.map +1 -1
- package/dist/dictionary/index.d.ts +5 -0
- package/dist/dictionary/index.js +5 -0
- package/dist/dictionary/index.js.map +1 -1
- package/dist/generator/applicability.d.ts +3 -0
- package/dist/generator/applicability.js +48 -0
- package/dist/generator/applicability.js.map +1 -0
- package/dist/generator/case-builder.d.ts +34 -0
- package/dist/generator/case-builder.js +111 -0
- package/dist/generator/case-builder.js.map +1 -0
- package/dist/generator/corpus-store.d.ts +43 -0
- package/dist/generator/corpus-store.js +115 -0
- package/dist/generator/corpus-store.js.map +1 -0
- package/dist/generator/index.d.ts +12 -0
- package/dist/generator/index.js +29 -0
- package/dist/generator/index.js.map +1 -0
- package/dist/generator/instrument-universe.d.ts +54 -0
- package/dist/generator/instrument-universe.js +286 -0
- package/dist/generator/instrument-universe.js.map +1 -0
- package/dist/generator/layout.d.ts +46 -0
- package/dist/generator/layout.js +208 -0
- package/dist/generator/layout.js.map +1 -0
- package/dist/generator/market-context.d.ts +64 -0
- package/dist/generator/market-context.js +119 -0
- package/dist/generator/market-context.js.map +1 -0
- package/dist/generator/outcome.d.ts +16 -0
- package/dist/generator/outcome.js +71 -0
- package/dist/generator/outcome.js.map +1 -0
- package/dist/generator/realistic-generator.d.ts +53 -0
- package/dist/generator/realistic-generator.js +275 -0
- package/dist/generator/realistic-generator.js.map +1 -0
- package/dist/generator/rng.d.ts +12 -0
- package/dist/generator/rng.js +60 -0
- package/dist/generator/rng.js.map +1 -0
- package/dist/generator/scatter.d.ts +50 -0
- package/dist/generator/scatter.js +285 -0
- package/dist/generator/scatter.js.map +1 -0
- package/dist/generator/scenarios.d.ts +13 -0
- package/dist/generator/scenarios.js +139 -0
- package/dist/generator/scenarios.js.map +1 -0
- package/dist/generator/value-conventions.d.ts +15 -0
- package/dist/generator/value-conventions.js +217 -0
- package/dist/generator/value-conventions.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/jsfix-cmd.d.ts +5 -0
- package/dist/jsfix-cmd.js +161 -0
- package/dist/jsfix-cmd.js.map +1 -1
- package/dist/store/fix-msg-ascii-store-resend.js +2 -2
- package/dist/store/fix-msg-ascii-store-resend.js.map +1 -1
- package/dist/store/fix-msg-store-record.d.ts +1 -1
- package/dist/store/fix-msg-store-record.js.map +1 -1
- package/dist/store/index.d.ts +1 -0
- package/dist/store/index.js +1 -0
- package/dist/store/index.js.map +1 -1
- package/dist/transport/index.d.ts +7 -0
- package/dist/transport/index.js +7 -0
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/session/index.d.ts +1 -0
- package/dist/transport/session/index.js +1 -0
- package/dist/transport/session/index.js.map +1 -1
- package/docs/generated-cases.md +237 -0
- package/docs/instrumentation.md +14 -0
- package/docs/scattered-components.md +60 -5
- package/jsfix.test_client.txt +62 -62
- package/jsfix.test_server.txt +72 -72
- package/package.json +5 -2
- package/src/buffer/index.ts +6 -0
- package/src/collections/index.ts +1 -1
- package/src/config/winston-logger.ts +8 -0
- package/src/dictionary/contained/index.ts +3 -0
- package/src/dictionary/index.ts +5 -0
- package/src/generator/applicability.ts +87 -0
- package/src/generator/case-builder.ts +167 -0
- package/src/generator/corpus-store.ts +166 -0
- package/src/generator/index.ts +12 -0
- package/src/generator/instrument-universe.ts +347 -0
- package/src/generator/layout.ts +279 -0
- package/src/generator/market-context.ts +207 -0
- package/src/generator/outcome.ts +102 -0
- package/src/generator/realistic-generator.ts +404 -0
- package/src/generator/rng.ts +92 -0
- package/src/generator/scatter.ts +432 -0
- package/src/generator/scenarios.ts +167 -0
- package/src/generator/value-conventions.ts +295 -0
- package/src/index.ts +12 -0
- package/src/jsfix-cmd.ts +204 -0
- package/src/store/fix-msg-ascii-store-resend.ts +2 -1
- package/src/store/fix-msg-store-record.ts +4 -1
- package/src/store/index.ts +1 -0
- package/src/transport/index.ts +10 -0
- package/src/transport/session/index.ts +1 -0
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Scatterer = exports.Containment = void 0;
|
|
4
|
+
const layout_1 = require("./layout");
|
|
5
|
+
const fragment_safety_1 = require("../dictionary/fragment-safety");
|
|
6
|
+
var Containment;
|
|
7
|
+
(function (Containment) {
|
|
8
|
+
Containment["Root"] = "root";
|
|
9
|
+
Containment["Within"] = "within";
|
|
10
|
+
Containment["Deeper"] = "deeper";
|
|
11
|
+
})(Containment || (exports.Containment = Containment = {}));
|
|
12
|
+
class Scatterer {
|
|
13
|
+
constructor(layout, rng, fragments = 2) {
|
|
14
|
+
this.layout = layout;
|
|
15
|
+
this.rng = rng;
|
|
16
|
+
this.fragments = fragments;
|
|
17
|
+
}
|
|
18
|
+
plan(depth) {
|
|
19
|
+
for (let want = depth; want >= 1; --want) {
|
|
20
|
+
const chain = this.findChain(this.layout.root, want, Containment.Root);
|
|
21
|
+
if (chain)
|
|
22
|
+
return chain;
|
|
23
|
+
}
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
scatter(depth, delimiter) {
|
|
27
|
+
const sites = this.plan(depth);
|
|
28
|
+
const chains = new Map();
|
|
29
|
+
for (const site of sites) {
|
|
30
|
+
const existing = chains.get(site.level);
|
|
31
|
+
if (existing) {
|
|
32
|
+
existing.push(site.component);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
chains.set(site.level, [site.component]);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const order = this.orderLevel(this.layout.root, chains);
|
|
39
|
+
const { tokens, bodyStart, bodyEnd } = this.layout;
|
|
40
|
+
const head = [];
|
|
41
|
+
for (let i = 0; i < bodyStart; ++i)
|
|
42
|
+
head.push(i);
|
|
43
|
+
const tail = [];
|
|
44
|
+
for (let i = bodyEnd; i < tokens.length; ++i)
|
|
45
|
+
tail.push(i);
|
|
46
|
+
const full = [...head, ...order, ...tail];
|
|
47
|
+
const position = new Map();
|
|
48
|
+
full.forEach((tokenIndex, at) => position.set(tokenIndex, at));
|
|
49
|
+
return {
|
|
50
|
+
wire: (0, layout_1.assemble)(tokens, full, delimiter),
|
|
51
|
+
order,
|
|
52
|
+
plan: {
|
|
53
|
+
depth: sites.length,
|
|
54
|
+
sites: sites.map(site => ({
|
|
55
|
+
level: site.level.path,
|
|
56
|
+
component: site.component.path,
|
|
57
|
+
containment: site.containment,
|
|
58
|
+
structureDepth: site.structureDepth,
|
|
59
|
+
contendedTags: Scatterer.contended(site),
|
|
60
|
+
fragments: Scatterer.runs(site.component.canonical().map(t => { var _a; return (_a = position.get(t)) !== null && _a !== void 0 ? _a : -1; })),
|
|
61
|
+
tags: site.component.canonical()
|
|
62
|
+
.map(t => { var _a; return ({ t, at: (_a = position.get(t)) !== null && _a !== void 0 ? _a : -1 }); })
|
|
63
|
+
.sort((a, b) => a.at - b.at)
|
|
64
|
+
.map(x => tokens[x.t].tag)
|
|
65
|
+
}))
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
static contended(site) {
|
|
70
|
+
const set = site.level.set;
|
|
71
|
+
if (!set)
|
|
72
|
+
return [];
|
|
73
|
+
const name = site.component.name;
|
|
74
|
+
const path = site.level.path;
|
|
75
|
+
const out = [];
|
|
76
|
+
for (const f of fragment_safety_1.FragmentSafety.analyseSet(set, path)) {
|
|
77
|
+
if (f.code !== fragment_safety_1.FragmentSafetyCode.SiblingTagCollision)
|
|
78
|
+
continue;
|
|
79
|
+
if (f.path !== path)
|
|
80
|
+
continue;
|
|
81
|
+
if (!f.owners.includes(name))
|
|
82
|
+
continue;
|
|
83
|
+
out.push(f.tag);
|
|
84
|
+
}
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
87
|
+
static runs(positions) {
|
|
88
|
+
const sorted = positions.slice().sort((a, b) => a - b);
|
|
89
|
+
let count = sorted.length > 0 ? 1 : 0;
|
|
90
|
+
for (let i = 1; i < sorted.length; ++i) {
|
|
91
|
+
if (sorted[i] !== sorted[i - 1] + 1)
|
|
92
|
+
count++;
|
|
93
|
+
}
|
|
94
|
+
return count;
|
|
95
|
+
}
|
|
96
|
+
findChain(level, depth, containment, structureDepth = 0) {
|
|
97
|
+
if (depth <= 0)
|
|
98
|
+
return [];
|
|
99
|
+
const units = this.units(level);
|
|
100
|
+
for (const candidate of Scatterer.candidates(level, units)) {
|
|
101
|
+
const site = { level, component: candidate, containment, structureDepth };
|
|
102
|
+
if (depth === 1)
|
|
103
|
+
return [site];
|
|
104
|
+
const inner = this.findInside(level, candidate, units, depth - 1, structureDepth);
|
|
105
|
+
if (inner)
|
|
106
|
+
return [site, ...inner];
|
|
107
|
+
}
|
|
108
|
+
for (const u of units) {
|
|
109
|
+
if (u.node.kind !== layout_1.LayoutKind.Group)
|
|
110
|
+
continue;
|
|
111
|
+
for (const instance of u.node.children) {
|
|
112
|
+
const chain = this.findChain(instance, depth, Containment.Deeper, structureDepth + 1);
|
|
113
|
+
if (chain)
|
|
114
|
+
return chain;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
static candidates(level, units) {
|
|
120
|
+
var _a;
|
|
121
|
+
const owned = new Map();
|
|
122
|
+
for (const u of units) {
|
|
123
|
+
for (const owner of u.owners) {
|
|
124
|
+
owned.set(owner, ((_a = owned.get(owner)) !== null && _a !== void 0 ? _a : 0) + 1);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const out = [];
|
|
128
|
+
for (const [node, count] of owned) {
|
|
129
|
+
if (count < 2)
|
|
130
|
+
continue;
|
|
131
|
+
if (count >= units.length)
|
|
132
|
+
continue;
|
|
133
|
+
out.push(node);
|
|
134
|
+
}
|
|
135
|
+
out.sort((a, b) => { var _a, _b; return ((_a = owned.get(b)) !== null && _a !== void 0 ? _a : 0) - ((_b = owned.get(a)) !== null && _b !== void 0 ? _b : 0); });
|
|
136
|
+
if (level.kind === layout_1.LayoutKind.Instance && units.length <= 2) {
|
|
137
|
+
return [];
|
|
138
|
+
}
|
|
139
|
+
return out;
|
|
140
|
+
}
|
|
141
|
+
findInside(level, outer, units, depth, structureDepth) {
|
|
142
|
+
var _a;
|
|
143
|
+
const inside = units.filter(u => u.owners.includes(outer));
|
|
144
|
+
const nested = new Map();
|
|
145
|
+
for (const u of inside) {
|
|
146
|
+
const at = u.owners.indexOf(outer);
|
|
147
|
+
for (let i = at + 1; i < u.owners.length; ++i) {
|
|
148
|
+
const n = u.owners[i];
|
|
149
|
+
nested.set(n, ((_a = nested.get(n)) !== null && _a !== void 0 ? _a : 0) + 1);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
const ordered = Array.from(nested.entries())
|
|
153
|
+
.filter(([, count]) => count >= 2 && count < inside.length)
|
|
154
|
+
.sort((a, b) => b[1] - a[1]);
|
|
155
|
+
for (const [node] of ordered) {
|
|
156
|
+
const site = { level, component: node, containment: Containment.Within, structureDepth };
|
|
157
|
+
if (depth === 1)
|
|
158
|
+
return [site];
|
|
159
|
+
const deeper = this.findInside(level, node, units, depth - 1, structureDepth);
|
|
160
|
+
if (deeper)
|
|
161
|
+
return [site, ...deeper];
|
|
162
|
+
}
|
|
163
|
+
const carried = units.filter(u => u.node.kind === layout_1.LayoutKind.Group && u.owners.includes(outer));
|
|
164
|
+
const siblings = units.filter(u => u.node.kind === layout_1.LayoutKind.Group && !u.owners.includes(outer));
|
|
165
|
+
for (const [group, containment] of [
|
|
166
|
+
...carried.map(u => [u.node, Containment.Within]),
|
|
167
|
+
...siblings.map(u => [u.node, Containment.Deeper])
|
|
168
|
+
]) {
|
|
169
|
+
for (const instance of group.children) {
|
|
170
|
+
const chain = this.findChain(instance, depth, containment, structureDepth + 1);
|
|
171
|
+
if (chain && chain.length === depth)
|
|
172
|
+
return chain;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
units(level, chains) {
|
|
178
|
+
const out = [];
|
|
179
|
+
const visit = (node, owners) => {
|
|
180
|
+
for (const child of node.children) {
|
|
181
|
+
switch (child.kind) {
|
|
182
|
+
case layout_1.LayoutKind.Field: {
|
|
183
|
+
const tokens = [child.tokenIndex];
|
|
184
|
+
if (child.extraTokenIndex >= 0)
|
|
185
|
+
tokens.push(child.extraTokenIndex);
|
|
186
|
+
out.push({ tokens, owners: owners.slice(), node: child });
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
case layout_1.LayoutKind.Component:
|
|
190
|
+
visit(child, [...owners, child]);
|
|
191
|
+
break;
|
|
192
|
+
case layout_1.LayoutKind.Group: {
|
|
193
|
+
const tokens = [child.tokenIndex];
|
|
194
|
+
for (const instance of child.children) {
|
|
195
|
+
for (const t of chains ? this.orderLevel(instance, chains) : instance.canonical()) {
|
|
196
|
+
tokens.push(t);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
out.push({ tokens, owners: owners.slice(), node: child });
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
default:
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
visit(level, []);
|
|
208
|
+
return out;
|
|
209
|
+
}
|
|
210
|
+
orderLevel(level, chains) {
|
|
211
|
+
var _a;
|
|
212
|
+
const units = this.units(level, chains);
|
|
213
|
+
const chain = (_a = chains.get(level)) !== null && _a !== void 0 ? _a : [];
|
|
214
|
+
let arranged;
|
|
215
|
+
if (level.kind === layout_1.LayoutKind.Instance && units.length > 0) {
|
|
216
|
+
const pinned = units[0];
|
|
217
|
+
const rest = units.slice(1);
|
|
218
|
+
const target = chain.length > 0 ? chain[0] : null;
|
|
219
|
+
if (target && pinned.owners.includes(target)) {
|
|
220
|
+
arranged = [pinned, ...this.arrange(rest, chain, true)];
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
arranged = [pinned, ...this.arrange(rest, chain, false)];
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
arranged = this.arrange(units, chain, false);
|
|
228
|
+
}
|
|
229
|
+
const out = [];
|
|
230
|
+
for (const u of arranged) {
|
|
231
|
+
for (const t of u.tokens)
|
|
232
|
+
out.push(t);
|
|
233
|
+
}
|
|
234
|
+
return out;
|
|
235
|
+
}
|
|
236
|
+
arrange(units, chain, restFirst) {
|
|
237
|
+
if (chain.length === 0 || units.length === 0)
|
|
238
|
+
return units;
|
|
239
|
+
const target = chain[0];
|
|
240
|
+
const inTarget = units.filter(u => u.owners.includes(target));
|
|
241
|
+
const rest = units.filter(u => !u.owners.includes(target));
|
|
242
|
+
if (inTarget.length === 0 || rest.length === 0)
|
|
243
|
+
return units;
|
|
244
|
+
const ordered = chain.length > 1 ? this.arrange(inTarget, chain.slice(1), false) : inTarget;
|
|
245
|
+
return restFirst
|
|
246
|
+
? Scatterer.weave(rest, ordered, this.fragments, this.rng)
|
|
247
|
+
: Scatterer.weave(ordered, rest, this.fragments, this.rng);
|
|
248
|
+
}
|
|
249
|
+
static weave(target, filler, fragments, rng) {
|
|
250
|
+
const f = Math.min(fragments, target.length, filler.length + 1);
|
|
251
|
+
if (f < 2)
|
|
252
|
+
return [...target, ...filler];
|
|
253
|
+
const targetRuns = Scatterer.split(target, f, rng);
|
|
254
|
+
const fillerRuns = Scatterer.split(filler, f - 1, rng);
|
|
255
|
+
const out = [];
|
|
256
|
+
for (let i = 0; i < f; ++i) {
|
|
257
|
+
out.push(...targetRuns[i]);
|
|
258
|
+
if (i < f - 1)
|
|
259
|
+
out.push(...fillerRuns[i]);
|
|
260
|
+
}
|
|
261
|
+
return out;
|
|
262
|
+
}
|
|
263
|
+
static split(units, parts, rng) {
|
|
264
|
+
if (parts <= 1)
|
|
265
|
+
return [units];
|
|
266
|
+
const cuts = new Set();
|
|
267
|
+
let guard = 0;
|
|
268
|
+
while (cuts.size < parts - 1 && guard++ < 100) {
|
|
269
|
+
cuts.add(rng.int(1, units.length - 1));
|
|
270
|
+
}
|
|
271
|
+
const sorted = Array.from(cuts).sort((a, b) => a - b);
|
|
272
|
+
const out = [];
|
|
273
|
+
let from = 0;
|
|
274
|
+
for (const cut of sorted) {
|
|
275
|
+
out.push(units.slice(from, cut));
|
|
276
|
+
from = cut;
|
|
277
|
+
}
|
|
278
|
+
out.push(units.slice(from));
|
|
279
|
+
while (out.length < parts)
|
|
280
|
+
out.push([]);
|
|
281
|
+
return out;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
exports.Scatterer = Scatterer;
|
|
285
|
+
//# sourceMappingURL=scatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scatter.js","sourceRoot":"","sources":["../../src/generator/scatter.ts"],"names":[],"mappings":";;;AAAA,qCAAoE;AACpE,mEAAkF;AA8ClF,IAAY,WAOX;AAPD,WAAY,WAAW;IAErB,4BAAa,CAAA;IAEb,gCAAiB,CAAA;IAEjB,gCAAiB,CAAA;AACnB,CAAC,EAPW,WAAW,2BAAX,WAAW,QAOtB;AA4DD,MAAa,SAAS;IACpB,YACmB,MAAe,EACf,GAAQ,EACR,YAAoB,CAAC;QAFrB,WAAM,GAAN,MAAM,CAAS;QACf,QAAG,GAAH,GAAG,CAAK;QACR,cAAS,GAAT,SAAS,CAAY;IACxC,CAAC;IASM,IAAI,CAAE,KAAa;QACxB,KAAK,IAAI,IAAI,GAAG,KAAK,EAAE,IAAI,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,CAAA;YACtE,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAA;QACzB,CAAC;QACD,OAAO,EAAE,CAAA;IACX,CAAC;IAEM,OAAO,CAAE,KAAa,EAAE,SAAiB;QAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC9B,MAAM,MAAM,GAAgB,IAAI,GAAG,EAA4B,CAAA;QAC/D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACvC,IAAI,QAAQ,EAAE,CAAC;gBACb,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YAC/B,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAA;YAC1C,CAAC;QACH,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QACvD,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,CAAA;QAClD,MAAM,IAAI,GAAa,EAAE,CAAA;QACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,EAAE,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAChD,MAAM,IAAI,GAAa,EAAE,CAAA;QACzB,KAAK,IAAI,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAC1D,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC,CAAA;QACzC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAA;QAC1C,IAAI,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAA;QAC9D,OAAO;YACL,IAAI,EAAE,IAAA,iBAAQ,EAAC,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC;YACvC,KAAK;YACL,IAAI,EAAE;gBACJ,KAAK,EAAE,KAAK,CAAC,MAAM;gBACnB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACxB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;oBACtB,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI;oBAC9B,WAAW,EAAE,IAAI,CAAC,WAAW;oBAC7B,cAAc,EAAE,IAAI,CAAC,cAAc;oBACnC,aAAa,EAAE,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC;oBACxC,SAAS,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,WAAC,OAAA,MAAA,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,mCAAI,CAAC,CAAC,CAAA,EAAA,CAAC,CAAC;oBACrF,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE;yBAC7B,GAAG,CAAC,CAAC,CAAC,EAAE,WAAC,OAAA,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,MAAA,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,mCAAI,CAAC,CAAC,EAAE,CAAC,CAAA,EAAA,CAAC;yBAC5C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;yBAC3B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;iBAC7B,CAAC,CAAC;aACJ;SACF,CAAA;IACH,CAAC;IAKO,MAAM,CAAC,SAAS,CAAE,IAAc;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAA;QAC1B,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAA;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAA;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAA;QAC5B,MAAM,GAAG,GAAa,EAAE,CAAA;QACxB,KAAK,MAAM,CAAC,IAAI,gCAAc,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;YACrD,IAAI,CAAC,CAAC,IAAI,KAAK,oCAAkB,CAAC,mBAAmB;gBAAE,SAAQ;YAC/D,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI;gBAAE,SAAQ;YAC7B,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAAE,SAAQ;YACtC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QACjB,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;IAMO,MAAM,CAAC,IAAI,CAAE,SAAmB;QACtC,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QACtD,IAAI,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;YACvC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;gBAAE,KAAK,EAAE,CAAA;QAC9C,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAOO,SAAS,CACf,KAAiB,EACjB,KAAa,EACb,WAAwB,EACxB,iBAAyB,CAAC;QAC1B,IAAI,KAAK,IAAI,CAAC;YAAE,OAAO,EAAE,CAAA;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAC/B,KAAK,MAAM,SAAS,IAAI,SAAS,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC;YAC3D,MAAM,IAAI,GAAa,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,CAAA;YACnF,IAAI,KAAK,KAAK,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,CAAA;YAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,EAAE,cAAc,CAAC,CAAA;YACjF,IAAI,KAAK;gBAAE,OAAO,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,CAAA;QACpC,CAAC;QAID,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,mBAAU,CAAC,KAAK;gBAAE,SAAQ;YAC9C,KAAK,MAAM,QAAQ,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACvC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,CAAC,CAAC,CAAA;gBACrF,IAAI,KAAK;oBAAE,OAAO,KAAK,CAAA;YACzB,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAMO,MAAM,CAAC,UAAU,CAAE,KAAiB,EAAE,KAAuB;;QACnE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAA;QAC3C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;gBAC7B,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,MAAA,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,mCAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YAC/C,CAAC;QACH,CAAC;QACD,MAAM,GAAG,GAAiB,EAAE,CAAA;QAC5B,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC;YAClC,IAAI,KAAK,GAAG,CAAC;gBAAE,SAAQ;YACvB,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM;gBAAE,SAAQ;YACnC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAChB,CAAC;QAED,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,eAAC,OAAA,CAAC,MAAA,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,mCAAI,CAAC,CAAC,GAAG,CAAC,MAAA,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,mCAAI,CAAC,CAAC,CAAA,EAAA,CAAC,CAAA;QAC7D,IAAI,KAAK,CAAC,IAAI,KAAK,mBAAU,CAAC,QAAQ,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YAE5D,OAAO,EAAE,CAAA;QACX,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;IAOO,UAAU,CAChB,KAAiB,EACjB,KAAiB,EACjB,KAAuB,EACvB,KAAa,EACb,cAAsB;;QACtB,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;QAG1D,MAAM,MAAM,GAAG,IAAI,GAAG,EAAsB,CAAA;QAC5C,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;YAClC,KAAK,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;gBAC9C,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;gBACrB,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,MAAA,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,mCAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YACzC,CAAC;QACH,CAAC;QACD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;aACzC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,CAAC,IAAI,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;aAC1D,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAC9B,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAa,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,EAAE,CAAA;YAClG,IAAI,KAAK,KAAK,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,CAAA;YAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,EAAE,cAAc,CAAC,CAAA;YAC7E,IAAI,MAAM;gBAAE,OAAO,CAAC,IAAI,EAAE,GAAG,MAAM,CAAC,CAAA;QACtC,CAAC;QAID,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,mBAAU,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;QAC/F,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,mBAAU,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;QACjG,KAAK,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,IAAI;YACjC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAA8B,CAAC;YAC9E,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAA8B,CAAC;SAChF,EAAE,CAAC;YACF,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACtC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,cAAc,GAAG,CAAC,CAAC,CAAA;gBAC9E,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK;oBAAE,OAAO,KAAK,CAAA;YACnD,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IASO,KAAK,CAAE,KAAiB,EAAE,MAAoB;QACpD,MAAM,GAAG,GAAY,EAAE,CAAA;QACvB,MAAM,KAAK,GAAG,CAAC,IAAgB,EAAE,MAAoB,EAAQ,EAAE;YAC7D,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;oBACnB,KAAK,mBAAU,CAAC,KAAK,CAAC,CAAC,CAAC;wBACtB,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;wBACjC,IAAI,KAAK,CAAC,eAAe,IAAI,CAAC;4BAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAA;wBAClE,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;wBACzD,MAAK;oBACP,CAAC;oBACD,KAAK,mBAAU,CAAC,SAAS;wBACvB,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;wBAChC,MAAK;oBACP,KAAK,mBAAU,CAAC,KAAK,CAAC,CAAC,CAAC;wBACtB,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;wBACjC,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;4BAEtC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC;gCAClF,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;4BAChB,CAAC;wBACH,CAAC;wBACD,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;wBACzD,MAAK;oBACP,CAAC;oBACD;wBACE,MAAK;gBACT,CAAC;YACH,CAAC;QACH,CAAC,CAAA;QACD,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;QAChB,OAAO,GAAG,CAAA;IACZ,CAAC;IAEO,UAAU,CAAE,KAAiB,EAAE,MAAmB;;QACxD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QACvC,MAAM,KAAK,GAAG,MAAA,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,mCAAI,EAAE,CAAA;QACrC,IAAI,QAAiB,CAAA;QACrB,IAAI,KAAK,CAAC,IAAI,KAAK,mBAAU,CAAC,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAE3D,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;YACvB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;YAC3B,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;YACjD,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAG7C,QAAQ,GAAG,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAA;YACzD,CAAC;iBAAM,CAAC;gBACN,QAAQ,GAAG,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAA;YAC1D,CAAC;QACH,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;QAC9C,CAAC;QACD,MAAM,GAAG,GAAa,EAAE,CAAA;QACxB,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM;gBAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACvC,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;IAMO,OAAO,CAAE,KAAc,EAAE,KAA4B,EAAE,SAAkB;QAC/E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAA;QAC1D,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACvB,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA;QAC7D,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA;QAC1D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAA;QAE5D,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;QAC3F,OAAO,SAAS;YACd,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC;YAC1D,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAA;IAC9D,CAAC;IAKO,MAAM,CAAC,KAAK,CAAE,MAAe,EAAE,MAAe,EAAE,SAAiB,EAAE,GAAQ;QACjF,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAC/D,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO,CAAC,GAAG,MAAM,EAAE,GAAG,MAAM,CAAC,CAAA;QACxC,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,GAAG,CAAC,CAAA;QAClD,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;QACtD,MAAM,GAAG,GAAY,EAAE,CAAA;QACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;YAC3B,GAAG,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAA;YAC1B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAA;QAC3C,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;IAEO,MAAM,CAAC,KAAK,CAAE,KAAc,EAAE,KAAa,EAAE,GAAQ;QAC3D,IAAI,KAAK,IAAI,CAAC;YAAE,OAAO,CAAC,KAAK,CAAC,CAAA;QAC9B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;QAC9B,IAAI,KAAK,GAAG,CAAC,CAAA;QACb,OAAO,IAAI,CAAC,IAAI,GAAG,KAAK,GAAG,CAAC,IAAI,KAAK,EAAE,GAAG,GAAG,EAAE,CAAC;YAC9C,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAA;QACxC,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QACrD,MAAM,GAAG,GAAc,EAAE,CAAA;QACzB,IAAI,IAAI,GAAG,CAAC,CAAA;QACZ,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;YACzB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAA;YAChC,IAAI,GAAG,GAAG,CAAA;QACZ,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;QAC3B,OAAO,GAAG,CAAC,MAAM,GAAG,KAAK;YAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACvC,OAAO,GAAG,CAAA;IACZ,CAAC;CACF;AA7TD,8BA6TC","sourcesContent":["import { ILayout, LayoutKind, LayoutNode, assemble } from './layout'\nimport { FragmentSafety, FragmentSafetyCode } from '../dictionary/fragment-safety'\nimport { Rng } from './rng'\n\n/**\n * Taking a well formed message apart in a way the specification still permits.\n *\n * Two facts from `docs/scattered-components.md` are the whole basis of this:\n *\n * Contiguity is only forced where framing exists, and framing only exists where it is\n * needed.\n *\n * A repeating group is the sole self describing construct in tag value FIX, so a group\n * run - its `NoXXX` and every instance - is atomic and moves as one block. Everywhere\n * else a component's extent is a convention of the dictionary with no wire\n * representation, so its tags may legally be interleaved with its siblings.\n *\n * And, within one group instance, the delimiter must come first. That is the only other\n * ordering the wire actually constrains, and it is honoured by pinning.\n *\n * Because the result is a permutation of the body's tokens, the encoded length and the\n * sum of the bytes are both unchanged - so `BodyLength` and `CheckSum` stay correct\n * without being recomputed. A scattered message differs from its canonical twin only in\n * the order of the fields, which is precisely the claim under test.\n *\n * ## Depth\n *\n * A *site* is one component made non-adjacent within its level. `--russian-doll n` asks\n * for n sites, each one level further into the message than the last:\n *\n * 1 Instrument scattered in the message body - the shape the shipped repair handles\n * 2 and again inside a group instance, one level down the structure stack\n * 3 and again inside a group instance of that instance\n *\n * A site one level down is preferred where it genuinely sits *within* the site above -\n * a component of the scattered component, or a group carried by it - because that is the\n * russian doll the design note describes. Where the dictionary offers no such shape, and\n * standard FIX 4.4 very often does not, the planner settles for a site at the same\n * structure depth reached through a sibling group instead, and says which it found. Both\n * are past what the engine handles: detection is populated only at structure depth 1, so\n * a component scattered inside any group instance goes unnoticed however it was reached.\n *\n * The planner degrades rather than failing. A message that cannot express three levels\n * yields two and a note, because which shapes a dictionary can express is a finding in\n * itself.\n */\n\nexport enum Containment {\n /** the message body */\n Root = 'root',\n /** genuinely inside the site above it - a nested component, or a group it carries */\n Within = 'within',\n /** the same structure depth, but reached through a sibling group */\n Deeper = 'deeper'\n}\n\nexport interface IScatterSite {\n /** dotted path of the level the site sits in - the message body or a group instance */\n readonly level: string\n /** dotted path of the component made non-adjacent */\n readonly component: string\n /** how this site relates to the one above it */\n readonly containment: Containment\n /**\n * how many group instance bodies enclose the site. 0 is the message body, which is\n * the only depth today's detection is populated at, so anything above 0 is past what\n * the engine notices.\n */\n readonly structureDepth: number\n /** how many runs the component was broken into */\n readonly fragments: number\n /** tags belonging to the component, in the order they now appear */\n readonly tags: number[]\n /**\n * tags of this component that a *sibling* at the same level also claims. Phase 0 of\n * the design note found 57 of these in the QuickFIX FIX50SP2 dictionary, all of them\n * `Currency(15)` declared both inside `Instrument` and beside it. No repair\n * attributing by tag identity can tell which one a scattered tag belonged to, so a\n * case with a non-empty list here is testing something unanswerable rather than\n * something broken.\n */\n readonly contendedTags: number[]\n}\n\ninterface ISiteRef {\n readonly level: LayoutNode\n readonly component: LayoutNode\n readonly containment: Containment\n readonly structureDepth: number\n}\n\nexport interface IScatterPlan {\n readonly depth: number\n readonly sites: readonly IScatterSite[]\n}\n\nexport interface IScatterResult {\n readonly wire: string\n readonly plan: IScatterPlan\n /** body token order, for a caller that wants to show the move */\n readonly order: readonly number[]\n}\n\ninterface IUnit {\n /** tokens in the order they should now appear; a group run carries its whole subtree */\n readonly tokens: number[]\n /** component nodes of this level enclosing the unit, outermost first */\n readonly owners: readonly LayoutNode[]\n readonly node: LayoutNode\n}\n\n/** a level, and the chain of components to scatter within it, outermost first */\ntype LevelChains = Map<LayoutNode, LayoutNode[]>\n\nexport class Scatterer {\n constructor (\n private readonly layout: ILayout,\n private readonly rng: Rng,\n private readonly fragments: number = 2) {\n }\n\n /**\n * the deepest chain of scatter sites this message can support, up to `depth`.\n *\n * Returns fewer sites than asked for rather than failing: which shapes a dictionary\n * can actually express is a finding in its own right, and a caller that wanted three\n * levels is better served by two and a note than by an exception.\n */\n public plan (depth: number): ISiteRef[] {\n for (let want = depth; want >= 1; --want) {\n const chain = this.findChain(this.layout.root, want, Containment.Root)\n if (chain) return chain\n }\n return []\n }\n\n public scatter (depth: number, delimiter: string): IScatterResult {\n const sites = this.plan(depth)\n const chains: LevelChains = new Map<LayoutNode, LayoutNode[]>()\n for (const site of sites) {\n const existing = chains.get(site.level)\n if (existing) {\n existing.push(site.component)\n } else {\n chains.set(site.level, [site.component])\n }\n }\n const order = this.orderLevel(this.layout.root, chains)\n const { tokens, bodyStart, bodyEnd } = this.layout\n const head: number[] = []\n for (let i = 0; i < bodyStart; ++i) head.push(i)\n const tail: number[] = []\n for (let i = bodyEnd; i < tokens.length; ++i) tail.push(i)\n const full = [...head, ...order, ...tail]\n const position = new Map<number, number>()\n full.forEach((tokenIndex, at) => position.set(tokenIndex, at))\n return {\n wire: assemble(tokens, full, delimiter),\n order,\n plan: {\n depth: sites.length,\n sites: sites.map(site => ({\n level: site.level.path,\n component: site.component.path,\n containment: site.containment,\n structureDepth: site.structureDepth,\n contendedTags: Scatterer.contended(site),\n fragments: Scatterer.runs(site.component.canonical().map(t => position.get(t) ?? -1)),\n tags: site.component.canonical()\n .map(t => ({ t, at: position.get(t) ?? -1 }))\n .sort((a, b) => a.at - b.at)\n .map(x => tokens[x.t].tag)\n }))\n }\n }\n }\n\n /**\n * tags of the scattered component that a sibling of it, at the same level, also claims\n */\n private static contended (site: ISiteRef): number[] {\n const set = site.level.set\n if (!set) return []\n const name = site.component.name\n const path = site.level.path\n const out: number[] = []\n for (const f of FragmentSafety.analyseSet(set, path)) {\n if (f.code !== FragmentSafetyCode.SiblingTagCollision) continue\n if (f.path !== path) continue\n if (!f.owners.includes(name)) continue\n out.push(f.tag)\n }\n return out\n }\n\n /**\n * how many separate runs these positions form once sorted - one if the component is\n * still contiguous, which is how a plan reports that it failed to achieve anything\n */\n private static runs (positions: number[]): number {\n const sorted = positions.slice().sort((a, b) => a - b)\n let count = sorted.length > 0 ? 1 : 0\n for (let i = 1; i < sorted.length; ++i) {\n if (sorted[i] !== sorted[i - 1] + 1) count++\n }\n return count\n }\n\n // ---------------------------------------------------------------- planning\n\n /**\n * a chain of sites, each one level further into the message than the last\n */\n private findChain (\n level: LayoutNode,\n depth: number,\n containment: Containment,\n structureDepth: number = 0): ISiteRef[] | null {\n if (depth <= 0) return []\n const units = this.units(level)\n for (const candidate of Scatterer.candidates(level, units)) {\n const site: ISiteRef = { level, component: candidate, containment, structureDepth }\n if (depth === 1) return [site]\n const inner = this.findInside(level, candidate, units, depth - 1, structureDepth)\n if (inner) return [site, ...inner]\n }\n // Nothing scatterable at this level. A market data refresh is the ordinary case:\n // its body is a handful of loose fields and one group, so every component it has\n // lives inside an entry. Descend rather than report the message unscatterable.\n for (const u of units) {\n if (u.node.kind !== LayoutKind.Group) continue\n for (const instance of u.node.children) {\n const chain = this.findChain(instance, depth, Containment.Deeper, structureDepth + 1)\n if (chain) return chain\n }\n }\n return null\n }\n\n /**\n * components of this level worth scattering: at least two units of their own, and at\n * least one unit of the level left over to put between them\n */\n private static candidates (level: LayoutNode, units: readonly IUnit[]): LayoutNode[] {\n const owned = new Map<LayoutNode, number>()\n for (const u of units) {\n for (const owner of u.owners) {\n owned.set(owner, (owned.get(owner) ?? 0) + 1)\n }\n }\n const out: LayoutNode[] = []\n for (const [node, count] of owned) {\n if (count < 2) continue\n if (count >= units.length) continue\n out.push(node)\n }\n // widest first, so the plan uses the component with the most room to be broken up\n out.sort((a, b) => (owned.get(b) ?? 0) - (owned.get(a) ?? 0))\n if (level.kind === LayoutKind.Instance && units.length <= 2) {\n // the delimiter is pinned, so a level of two units has nothing spare to interleave\n return []\n }\n return out\n }\n\n /**\n * the next site down. Preference order is the containment order of the design note:\n * a component nested inside this one, then a group this component carries, then - only\n * because standard FIX rarely offers either - any group at this level.\n */\n private findInside (\n level: LayoutNode,\n outer: LayoutNode,\n units: readonly IUnit[],\n depth: number,\n structureDepth: number): ISiteRef[] | null {\n const inside = units.filter(u => u.owners.includes(outer))\n\n // a component of the scattered component, scattered among its parent's own tags\n const nested = new Map<LayoutNode, number>()\n for (const u of inside) {\n const at = u.owners.indexOf(outer)\n for (let i = at + 1; i < u.owners.length; ++i) {\n const n = u.owners[i]\n nested.set(n, (nested.get(n) ?? 0) + 1)\n }\n }\n const ordered = Array.from(nested.entries())\n .filter(([, count]) => count >= 2 && count < inside.length)\n .sort((a, b) => b[1] - a[1])\n for (const [node] of ordered) {\n const site: ISiteRef = { level, component: node, containment: Containment.Within, structureDepth }\n if (depth === 1) return [site]\n const deeper = this.findInside(level, node, units, depth - 1, structureDepth)\n if (deeper) return [site, ...deeper]\n }\n\n // a group instance is a level of its own; one carried by the scattered component is\n // genuinely within it, one carried by a sibling only reaches the same structure depth\n const carried = units.filter(u => u.node.kind === LayoutKind.Group && u.owners.includes(outer))\n const siblings = units.filter(u => u.node.kind === LayoutKind.Group && !u.owners.includes(outer))\n for (const [group, containment] of [\n ...carried.map(u => [u.node, Containment.Within] as [LayoutNode, Containment]),\n ...siblings.map(u => [u.node, Containment.Deeper] as [LayoutNode, Containment])\n ]) {\n for (const instance of group.children) {\n const chain = this.findChain(instance, depth, containment, structureDepth + 1)\n if (chain && chain.length === depth) return chain\n }\n }\n return null\n }\n\n // ---------------------------------------------------------------- ordering\n\n /**\n * the units of one level: every field is a unit, a component contributes its fields to\n * the enclosing level rather than a unit of its own, and a whole group run is a single\n * atomic unit because the wire frames it\n */\n private units (level: LayoutNode, chains?: LevelChains): IUnit[] {\n const out: IUnit[] = []\n const visit = (node: LayoutNode, owners: LayoutNode[]): void => {\n for (const child of node.children) {\n switch (child.kind) {\n case LayoutKind.Field: {\n const tokens = [child.tokenIndex]\n if (child.extraTokenIndex >= 0) tokens.push(child.extraTokenIndex)\n out.push({ tokens, owners: owners.slice(), node: child })\n break\n }\n case LayoutKind.Component:\n visit(child, [...owners, child])\n break\n case LayoutKind.Group: {\n const tokens = [child.tokenIndex]\n for (const instance of child.children) {\n // an instance is a level, so it may carry a scatter site of its own\n for (const t of chains ? this.orderLevel(instance, chains) : instance.canonical()) {\n tokens.push(t)\n }\n }\n out.push({ tokens, owners: owners.slice(), node: child })\n break\n }\n default:\n break\n }\n }\n }\n visit(level, [])\n return out\n }\n\n private orderLevel (level: LayoutNode, chains: LevelChains): number[] {\n const units = this.units(level, chains)\n const chain = chains.get(level) ?? []\n let arranged: IUnit[]\n if (level.kind === LayoutKind.Instance && units.length > 0) {\n // the group delimiter has to stay at the front of the instance\n const pinned = units[0]\n const rest = units.slice(1)\n const target = chain.length > 0 ? chain[0] : null\n if (target && pinned.owners.includes(target)) {\n // the pinned unit already belongs to the component being scattered, so putting\n // the other units of the level next is enough to break its run\n arranged = [pinned, ...this.arrange(rest, chain, true)]\n } else {\n arranged = [pinned, ...this.arrange(rest, chain, false)]\n }\n } else {\n arranged = this.arrange(units, chain, false)\n }\n const out: number[] = []\n for (const u of arranged) {\n for (const t of u.tokens) out.push(t)\n }\n return out\n }\n\n /**\n * @param restFirst put the untargeted units before the targeted ones, used when the\n * pinned delimiter already belongs to the target\n */\n private arrange (units: IUnit[], chain: readonly LayoutNode[], restFirst: boolean): IUnit[] {\n if (chain.length === 0 || units.length === 0) return units\n const target = chain[0]\n const inTarget = units.filter(u => u.owners.includes(target))\n const rest = units.filter(u => !u.owners.includes(target))\n if (inTarget.length === 0 || rest.length === 0) return units\n // deeper sites in the same level are scattered within the target's own units first\n const ordered = chain.length > 1 ? this.arrange(inTarget, chain.slice(1), false) : inTarget\n return restFirst\n ? Scatterer.weave(rest, ordered, this.fragments, this.rng)\n : Scatterer.weave(ordered, rest, this.fragments, this.rng)\n }\n\n /**\n * break `target` into runs and put pieces of `filler` between them\n */\n private static weave (target: IUnit[], filler: IUnit[], fragments: number, rng: Rng): IUnit[] {\n const f = Math.min(fragments, target.length, filler.length + 1)\n if (f < 2) return [...target, ...filler]\n const targetRuns = Scatterer.split(target, f, rng)\n const fillerRuns = Scatterer.split(filler, f - 1, rng)\n const out: IUnit[] = []\n for (let i = 0; i < f; ++i) {\n out.push(...targetRuns[i])\n if (i < f - 1) out.push(...fillerRuns[i])\n }\n return out\n }\n\n private static split (units: IUnit[], parts: number, rng: Rng): IUnit[][] {\n if (parts <= 1) return [units]\n const cuts = new Set<number>()\n let guard = 0\n while (cuts.size < parts - 1 && guard++ < 100) {\n cuts.add(rng.int(1, units.length - 1))\n }\n const sorted = Array.from(cuts).sort((a, b) => a - b)\n const out: IUnit[][] = []\n let from = 0\n for (const cut of sorted) {\n out.push(units.slice(from, cut))\n from = cut\n }\n out.push(units.slice(from))\n while (out.length < parts) out.push([])\n return out\n }\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { IGeneratorOptions } from './realistic-generator';
|
|
2
|
+
export interface IScenario {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly description: string;
|
|
5
|
+
readonly msgType: string;
|
|
6
|
+
readonly options: IGeneratorOptions;
|
|
7
|
+
}
|
|
8
|
+
export declare const Scenarios: {
|
|
9
|
+
all: readonly IScenario[];
|
|
10
|
+
get(name: string): IScenario | undefined;
|
|
11
|
+
names(): string[];
|
|
12
|
+
describe(): string;
|
|
13
|
+
};
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Scenarios = void 0;
|
|
4
|
+
const instrument_universe_1 = require("./instrument-universe");
|
|
5
|
+
const NoLegs = '555';
|
|
6
|
+
const NoSides = '552';
|
|
7
|
+
const NoPartyIDs = '453';
|
|
8
|
+
const NoUnderlyings = '711';
|
|
9
|
+
const NoMDEntries = '268';
|
|
10
|
+
const NoAllocs = '78';
|
|
11
|
+
const NoRelatedSym = '146';
|
|
12
|
+
const scenarios = [
|
|
13
|
+
{
|
|
14
|
+
name: 'spread-trade-capture',
|
|
15
|
+
description: 'ICE Brent calendar spread, parent plus two legs, both sides with parties',
|
|
16
|
+
msgType: 'AE',
|
|
17
|
+
options: {
|
|
18
|
+
instrument: 'BRN JAN26-FEB26',
|
|
19
|
+
include: [NoLegs, NoSides, NoPartyIDs],
|
|
20
|
+
density: 0.5,
|
|
21
|
+
maxGroupInstances: 2
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'crack-spread-capture',
|
|
26
|
+
description: 'ICE Brent/Gasoil crack spread trade capture with legs and underlyings',
|
|
27
|
+
msgType: 'AE',
|
|
28
|
+
options: {
|
|
29
|
+
instrument: 'BRN-GAS CRACK',
|
|
30
|
+
include: [NoLegs, NoSides, NoPartyIDs, NoUnderlyings],
|
|
31
|
+
density: 0.5,
|
|
32
|
+
maxGroupInstances: 2
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'equity-fill',
|
|
37
|
+
description: 'partial fill on a listed equity order, with the executing parties',
|
|
38
|
+
msgType: '8',
|
|
39
|
+
options: {
|
|
40
|
+
instrument: 'AAPL',
|
|
41
|
+
assetClass: instrument_universe_1.AssetClass.Equity,
|
|
42
|
+
include: [NoPartyIDs],
|
|
43
|
+
density: 0.5
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'equity-order',
|
|
48
|
+
description: 'plain new order single into a lit venue',
|
|
49
|
+
msgType: 'D',
|
|
50
|
+
options: {
|
|
51
|
+
instrument: 'VOD.L',
|
|
52
|
+
assetClass: instrument_universe_1.AssetClass.Equity,
|
|
53
|
+
density: 0.4
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: 'future-order',
|
|
58
|
+
description: 'new order single on a listed future, give-up parties attached',
|
|
59
|
+
msgType: 'D',
|
|
60
|
+
options: {
|
|
61
|
+
instrument: 'BRN',
|
|
62
|
+
assetClass: instrument_universe_1.AssetClass.Future,
|
|
63
|
+
include: [NoPartyIDs],
|
|
64
|
+
density: 0.45
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'bond-trade-capture',
|
|
69
|
+
description: 'treasury trade capture - the one case where the fixed income half of Instrument belongs',
|
|
70
|
+
msgType: 'AE',
|
|
71
|
+
options: {
|
|
72
|
+
instrument: 'US91282CLW12',
|
|
73
|
+
assetClass: instrument_universe_1.AssetClass.Bond,
|
|
74
|
+
include: [NoSides, NoPartyIDs],
|
|
75
|
+
density: 0.6
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: 'option-order',
|
|
80
|
+
description: 'listed option order carrying strike and expiry',
|
|
81
|
+
msgType: 'D',
|
|
82
|
+
options: {
|
|
83
|
+
instrument: 'ESZ5 C6000',
|
|
84
|
+
assetClass: instrument_universe_1.AssetClass.Option,
|
|
85
|
+
density: 0.45
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'md-incremental',
|
|
90
|
+
description: 'incremental market data refresh, several entries against one book',
|
|
91
|
+
msgType: 'X',
|
|
92
|
+
options: {
|
|
93
|
+
instrument: 'ESZ5',
|
|
94
|
+
assetClass: instrument_universe_1.AssetClass.Future,
|
|
95
|
+
include: [NoMDEntries],
|
|
96
|
+
density: 0.35,
|
|
97
|
+
maxGroupInstances: 4
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'md-request',
|
|
102
|
+
description: 'market data request over a small watch list',
|
|
103
|
+
msgType: 'V',
|
|
104
|
+
options: {
|
|
105
|
+
assetClass: instrument_universe_1.AssetClass.Equity,
|
|
106
|
+
include: [NoRelatedSym],
|
|
107
|
+
density: 0.6,
|
|
108
|
+
maxGroupInstances: 3
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: 'block-allocation',
|
|
113
|
+
description: 'allocation instruction breaking a block across accounts',
|
|
114
|
+
msgType: 'J',
|
|
115
|
+
options: {
|
|
116
|
+
instrument: 'AAPL',
|
|
117
|
+
assetClass: instrument_universe_1.AssetClass.Equity,
|
|
118
|
+
include: [NoAllocs, NoPartyIDs],
|
|
119
|
+
density: 0.45,
|
|
120
|
+
maxGroupInstances: 3
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
];
|
|
124
|
+
exports.Scenarios = {
|
|
125
|
+
all: scenarios,
|
|
126
|
+
get(name) {
|
|
127
|
+
return scenarios.find(s => s.name === name);
|
|
128
|
+
},
|
|
129
|
+
names() {
|
|
130
|
+
return scenarios.map(s => s.name);
|
|
131
|
+
},
|
|
132
|
+
describe() {
|
|
133
|
+
const width = Math.max(...scenarios.map(s => s.name.length));
|
|
134
|
+
return scenarios
|
|
135
|
+
.map(s => ` ${s.name.padEnd(width)} ${s.msgType.padEnd(2)} ${s.description}`)
|
|
136
|
+
.join('\n');
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
//# sourceMappingURL=scenarios.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scenarios.js","sourceRoot":"","sources":["../../src/generator/scenarios.ts"],"names":[],"mappings":"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","sourcesContent":["import { IGeneratorOptions } from './realistic-generator'\nimport { AssetClass } from './instrument-universe'\n\n/**\n * Named shapes of traffic, so that asking for something realistic does not mean\n * knowing which tags to force on.\n *\n * A scenario is only a bundle of generator options - it has no logic of its own, and\n * anything it does can be done on the command line instead. Its value is that the\n * combination which produces a *convincing* message is not obvious: a multileg trade\n * capture needs legs, sides and parties present together, and a bond one needs the\n * fixed income half of `Instrument` that the applicability gate would otherwise\n * suppress.\n *\n * Fields are forced by **tag**, not by name, because the name is not portable. The\n * repository rendering calls the leg group `TrdInstrmtLegGrp` and QuickFIX calls it\n * `NoLegs`; both agree it is 555. A scenario therefore runs against any dictionary\n * that carries the message at all.\n */\n\nexport interface IScenario {\n readonly name: string\n readonly description: string\n /** as it appears on the wire in tag 35 */\n readonly msgType: string\n readonly options: IGeneratorOptions\n}\n\nconst NoLegs = '555'\nconst NoSides = '552'\nconst NoPartyIDs = '453'\nconst NoUnderlyings = '711'\nconst NoMDEntries = '268'\nconst NoAllocs = '78'\nconst NoRelatedSym = '146'\n\nconst scenarios: readonly IScenario[] = [\n {\n name: 'spread-trade-capture',\n description: 'ICE Brent calendar spread, parent plus two legs, both sides with parties',\n msgType: 'AE',\n options: {\n instrument: 'BRN JAN26-FEB26',\n include: [NoLegs, NoSides, NoPartyIDs],\n density: 0.5,\n maxGroupInstances: 2\n }\n },\n {\n name: 'crack-spread-capture',\n description: 'ICE Brent/Gasoil crack spread trade capture with legs and underlyings',\n msgType: 'AE',\n options: {\n instrument: 'BRN-GAS CRACK',\n include: [NoLegs, NoSides, NoPartyIDs, NoUnderlyings],\n density: 0.5,\n maxGroupInstances: 2\n }\n },\n {\n name: 'equity-fill',\n description: 'partial fill on a listed equity order, with the executing parties',\n msgType: '8',\n options: {\n instrument: 'AAPL',\n assetClass: AssetClass.Equity,\n include: [NoPartyIDs],\n density: 0.5\n }\n },\n {\n name: 'equity-order',\n description: 'plain new order single into a lit venue',\n msgType: 'D',\n options: {\n instrument: 'VOD.L',\n assetClass: AssetClass.Equity,\n density: 0.4\n }\n },\n {\n name: 'future-order',\n description: 'new order single on a listed future, give-up parties attached',\n msgType: 'D',\n options: {\n instrument: 'BRN',\n assetClass: AssetClass.Future,\n include: [NoPartyIDs],\n density: 0.45\n }\n },\n {\n name: 'bond-trade-capture',\n description: 'treasury trade capture - the one case where the fixed income half of Instrument belongs',\n msgType: 'AE',\n options: {\n instrument: 'US91282CLW12',\n assetClass: AssetClass.Bond,\n include: [NoSides, NoPartyIDs],\n density: 0.6\n }\n },\n {\n name: 'option-order',\n description: 'listed option order carrying strike and expiry',\n msgType: 'D',\n options: {\n instrument: 'ESZ5 C6000',\n assetClass: AssetClass.Option,\n density: 0.45\n }\n },\n {\n name: 'md-incremental',\n description: 'incremental market data refresh, several entries against one book',\n msgType: 'X',\n options: {\n instrument: 'ESZ5',\n assetClass: AssetClass.Future,\n include: [NoMDEntries],\n density: 0.35,\n maxGroupInstances: 4\n }\n },\n {\n name: 'md-request',\n description: 'market data request over a small watch list',\n msgType: 'V',\n options: {\n assetClass: AssetClass.Equity,\n include: [NoRelatedSym],\n density: 0.6,\n maxGroupInstances: 3\n }\n },\n {\n name: 'block-allocation',\n description: 'allocation instruction breaking a block across accounts',\n msgType: 'J',\n options: {\n instrument: 'AAPL',\n assetClass: AssetClass.Equity,\n include: [NoAllocs, NoPartyIDs],\n density: 0.45,\n maxGroupInstances: 3\n }\n }\n]\n\nexport const Scenarios = {\n all: scenarios,\n\n get (name: string): IScenario | undefined {\n return scenarios.find(s => s.name === name)\n },\n\n names (): string[] {\n return scenarios.map(s => s.name)\n },\n\n describe (): string {\n const width = Math.max(...scenarios.map(s => s.name.length))\n return scenarios\n .map(s => ` ${s.name.padEnd(width)} ${s.msgType.padEnd(2)} ${s.description}`)\n .join('\\n')\n }\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SimpleFieldDefinition } from '../dictionary/definition';
|
|
2
|
+
import { MarketContext } from './market-context';
|
|
3
|
+
export interface IFieldContext {
|
|
4
|
+
readonly path: readonly string[];
|
|
5
|
+
readonly instance: number;
|
|
6
|
+
}
|
|
7
|
+
export declare class ValueConventions {
|
|
8
|
+
readonly market: MarketContext;
|
|
9
|
+
constructor(market: MarketContext);
|
|
10
|
+
static knows(tag: number): boolean;
|
|
11
|
+
value(sf: SimpleFieldDefinition, ctx: IFieldContext): any;
|
|
12
|
+
private enumValue;
|
|
13
|
+
private conform;
|
|
14
|
+
private byType;
|
|
15
|
+
}
|