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,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ValueConventions = void 0;
|
|
4
|
+
const tag_type_1 = require("../buffer/tag/tag-type");
|
|
5
|
+
const market_context_1 = require("./market-context");
|
|
6
|
+
const mics = ['XLON', 'XNAS', 'XNYS', 'XETR', 'IFEU', 'XCME', 'XOFF'];
|
|
7
|
+
const currencies = ['USD', 'EUR', 'GBP', 'JPY', 'CHF'];
|
|
8
|
+
const sessions = ['DAY', 'REG', 'ELECTRONIC', 'AFTERHOURS'];
|
|
9
|
+
const ratings = ['AAA', 'AA+', 'A', 'BBB+', 'BB-'];
|
|
10
|
+
const countries = ['US', 'GB', 'DE', 'NL', 'JP'];
|
|
11
|
+
const ordinalName = /(Type|Status|Reason|Indicator|Action|Capacity|Method|Mode|Level)$/;
|
|
12
|
+
const byTag = new Map([
|
|
13
|
+
[1, m => m.account],
|
|
14
|
+
[6, m => m.avgPx],
|
|
15
|
+
[11, (m, ctx) => (ctx.instance > 0 ? `${m.clOrdId}-${ctx.instance}` : m.clOrdId)],
|
|
16
|
+
[14, m => m.cumQty],
|
|
17
|
+
[15, m => m.instrument.currency],
|
|
18
|
+
[17, m => `${m.execId}-${m.nextSeq()}`],
|
|
19
|
+
[22, m => m.current().securityIdSource],
|
|
20
|
+
[30, m => m.instrument.securityExchange],
|
|
21
|
+
[31, m => m.lastPx],
|
|
22
|
+
[32, m => m.lastQty],
|
|
23
|
+
[37, (m, ctx) => (ctx.instance > 0 ? `${m.orderId}-${ctx.instance}` : m.orderId)],
|
|
24
|
+
[38, m => m.orderQty],
|
|
25
|
+
[41, m => m.origClOrdId],
|
|
26
|
+
[44, m => m.price],
|
|
27
|
+
[48, m => m.current().securityId],
|
|
28
|
+
[54, (m, ctx) => (ctx.instance % 2 === 0 ? m.side : (m.side === '1' ? '2' : '1'))],
|
|
29
|
+
[55, m => m.current().symbol],
|
|
30
|
+
[58, m => m.text()],
|
|
31
|
+
[60, m => m.transactTime],
|
|
32
|
+
[64, m => m.settlDate],
|
|
33
|
+
[75, m => m.tradeDate],
|
|
34
|
+
[76, m => m.firms[0].id],
|
|
35
|
+
[100, m => m.instrument.securityExchange],
|
|
36
|
+
[107, m => m.instrument.name],
|
|
37
|
+
[110, m => m.instrument.lotSize],
|
|
38
|
+
[151, m => m.leavesQty],
|
|
39
|
+
[167, m => m.current().securityType],
|
|
40
|
+
[200, m => { var _a; return (_a = m.current().maturityMonthYear) !== null && _a !== void 0 ? _a : m.instrument.maturityMonthYear; }],
|
|
41
|
+
[201, m => m.instrument.putOrCall],
|
|
42
|
+
[202, m => m.instrument.strikePrice],
|
|
43
|
+
[207, m => m.instrument.securityExchange],
|
|
44
|
+
[231, m => m.instrument.contractMultiplier],
|
|
45
|
+
[336, m => m.rng.pick(sessions)],
|
|
46
|
+
[375, m => m.firms[2].id],
|
|
47
|
+
[381, m => m.grossAmount()],
|
|
48
|
+
[447, (m, ctx) => m.party(ctx.instance).idSource],
|
|
49
|
+
[448, (m, ctx) => m.party(ctx.instance).id],
|
|
50
|
+
[452, (m, ctx) => m.party(ctx.instance).role],
|
|
51
|
+
[460, m => m.instrument.product],
|
|
52
|
+
[461, m => m.instrument.cfiCode],
|
|
53
|
+
[541, m => m.instrument.maturityDate],
|
|
54
|
+
[571, m => m.tradeId],
|
|
55
|
+
[255, m => m.rng.pick(ratings)],
|
|
56
|
+
[470, m => m.rng.pick(countries)],
|
|
57
|
+
[472, m => m.rng.pick(countries)],
|
|
58
|
+
[65, () => undefined],
|
|
59
|
+
[572, m => `${m.tradeId}-REF`],
|
|
60
|
+
[600, m => m.current().symbol],
|
|
61
|
+
[602, m => m.current().securityId],
|
|
62
|
+
[603, m => m.current().securityIdSource],
|
|
63
|
+
[609, m => m.current().securityType],
|
|
64
|
+
[610, m => m.current().maturityMonthYear],
|
|
65
|
+
[623, m => { var _a, _b; return (_b = (_a = m.leg) === null || _a === void 0 ? void 0 : _a.ratio) !== null && _b !== void 0 ? _b : 1; }],
|
|
66
|
+
[624, m => { var _a, _b; return (_b = (_a = m.leg) === null || _a === void 0 ? void 0 : _a.side) !== null && _b !== void 0 ? _b : m.side; }],
|
|
67
|
+
[566, m => m.priceNear()],
|
|
68
|
+
[637, m => m.priceNear()],
|
|
69
|
+
[687, m => { var _a, _b; return m.lastQty * ((_b = (_a = m.leg) === null || _a === void 0 ? void 0 : _a.ratio) !== null && _b !== void 0 ? _b : 1); }],
|
|
70
|
+
[311, m => { var _a, _b; return (_b = (_a = m.underlying) === null || _a === void 0 ? void 0 : _a.symbol) !== null && _b !== void 0 ? _b : m.instrument.symbol; }],
|
|
71
|
+
[309, m => { var _a, _b; return (_b = (_a = m.underlying) === null || _a === void 0 ? void 0 : _a.securityId) !== null && _b !== void 0 ? _b : m.instrument.securityId; }],
|
|
72
|
+
[305, m => { var _a, _b; return (_b = (_a = m.underlying) === null || _a === void 0 ? void 0 : _a.securityIdSource) !== null && _b !== void 0 ? _b : m.instrument.securityIdSource; }],
|
|
73
|
+
[79, m => m.account],
|
|
74
|
+
[80, m => m.lastQty],
|
|
75
|
+
[270, m => m.priceNear()],
|
|
76
|
+
[271, m => m.quantity()],
|
|
77
|
+
[272, m => m.tradeDate],
|
|
78
|
+
[273, m => m.transactTime],
|
|
79
|
+
[346, m => m.rng.int(1, 25)]
|
|
80
|
+
]);
|
|
81
|
+
const nameRules = [
|
|
82
|
+
{ test: /(Type|Source|Status|Reason|Indicator|Capacity|Restrictions)$/, apply: () => undefined },
|
|
83
|
+
{ test: /(Px|Price)$/, apply: m => m.priceNear() },
|
|
84
|
+
{ test: /(Qty|Quantity|Shares|Size|Volume)$/, apply: m => m.quantity() },
|
|
85
|
+
{ test: /(Currency|Ccy)$/, apply: m => m.rng.pick(currencies) },
|
|
86
|
+
{ test: /Symbol$/, apply: m => m.current().symbol },
|
|
87
|
+
{ test: /(Exchange|Mkt|Market)$/, apply: m => m.rng.pick(mics) },
|
|
88
|
+
{ test: /SecurityID$/, apply: m => m.current().securityId },
|
|
89
|
+
{ test: /(MonthYear)$/, apply: m => { var _a; return (_a = m.current().maturityMonthYear) !== null && _a !== void 0 ? _a : m.instrument.maturityMonthYear; } },
|
|
90
|
+
{ test: /(Amt|Amount|Notional|Consideration)$/, apply: m => m.grossAmount() },
|
|
91
|
+
{ test: /(Rate|Yield|Coupon)$/, apply: m => Number((m.rng.int(1, 800) / 10000).toFixed(5)) },
|
|
92
|
+
{ test: /(Percent|Pct|Ratio)$/, apply: m => Number((m.rng.int(0, 10000) / 100).toFixed(2)) },
|
|
93
|
+
{ test: /Account$/, apply: m => m.account },
|
|
94
|
+
{ test: /(Desk|Division)$/, apply: m => m.desk },
|
|
95
|
+
{ test: /(Text|Desc|Description|Comment|Instructions)$/, apply: m => m.text() },
|
|
96
|
+
{ test: /(Timestamp|Time)$/, apply: m => m.transactTime },
|
|
97
|
+
{ test: /Date$/, apply: m => m.tradeDate },
|
|
98
|
+
{ test: /(Broker|Firm)$/, apply: (m, ctx) => m.party(ctx.instance).id },
|
|
99
|
+
{ test: /(Trader|User|Operator)$/, apply: m => m.traders[0].id }
|
|
100
|
+
];
|
|
101
|
+
function initials(name) {
|
|
102
|
+
const caps = name.replace(/[^A-Z]/g, '');
|
|
103
|
+
if (caps.length >= 2)
|
|
104
|
+
return caps.substring(0, 4);
|
|
105
|
+
return name.substring(0, 3).toUpperCase();
|
|
106
|
+
}
|
|
107
|
+
class ValueConventions {
|
|
108
|
+
constructor(market) {
|
|
109
|
+
this.market = market;
|
|
110
|
+
}
|
|
111
|
+
static knows(tag) {
|
|
112
|
+
return byTag.has(tag);
|
|
113
|
+
}
|
|
114
|
+
value(sf, ctx) {
|
|
115
|
+
const exact = byTag.get(sf.tag);
|
|
116
|
+
if (exact) {
|
|
117
|
+
const v = exact(this.market, ctx, sf);
|
|
118
|
+
if (v != null)
|
|
119
|
+
return this.conform(sf, v);
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
if (sf.isEnum()) {
|
|
123
|
+
return this.enumValue(sf);
|
|
124
|
+
}
|
|
125
|
+
for (const rule of nameRules) {
|
|
126
|
+
if (!rule.test.test(sf.name))
|
|
127
|
+
continue;
|
|
128
|
+
const v = rule.apply(this.market, ctx, sf);
|
|
129
|
+
if (v == null)
|
|
130
|
+
break;
|
|
131
|
+
return this.conform(sf, v);
|
|
132
|
+
}
|
|
133
|
+
return this.byType(sf, ctx);
|
|
134
|
+
}
|
|
135
|
+
enumValue(sf) {
|
|
136
|
+
const keys = Array.from(sf.enums.keys());
|
|
137
|
+
if (keys.length === 0)
|
|
138
|
+
return undefined;
|
|
139
|
+
const choice = keys[this.market.rng.frontBiased(keys.length)];
|
|
140
|
+
switch (sf.tagType) {
|
|
141
|
+
case tag_type_1.TagType.Int: return parseInt(choice, 10);
|
|
142
|
+
case tag_type_1.TagType.Float: return parseFloat(choice);
|
|
143
|
+
case tag_type_1.TagType.Boolean: return choice === 'Y';
|
|
144
|
+
default: return choice;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
conform(sf, v) {
|
|
148
|
+
switch (sf.tagType) {
|
|
149
|
+
case tag_type_1.TagType.RawData: {
|
|
150
|
+
if (Buffer.isBuffer(v))
|
|
151
|
+
return v;
|
|
152
|
+
return Buffer.from(String(v));
|
|
153
|
+
}
|
|
154
|
+
case tag_type_1.TagType.Int:
|
|
155
|
+
case tag_type_1.TagType.Length: {
|
|
156
|
+
if (typeof v === 'number')
|
|
157
|
+
return Math.round(v);
|
|
158
|
+
const n = parseInt(String(v), 10);
|
|
159
|
+
return isNaN(n) ? undefined : n;
|
|
160
|
+
}
|
|
161
|
+
case tag_type_1.TagType.Float: {
|
|
162
|
+
if (typeof v === 'number')
|
|
163
|
+
return v;
|
|
164
|
+
const f = parseFloat(String(v));
|
|
165
|
+
return isNaN(f) ? undefined : f;
|
|
166
|
+
}
|
|
167
|
+
case tag_type_1.TagType.Boolean: {
|
|
168
|
+
if (typeof v === 'boolean')
|
|
169
|
+
return v;
|
|
170
|
+
return String(v) === 'Y' || String(v) === 'true';
|
|
171
|
+
}
|
|
172
|
+
case tag_type_1.TagType.String: {
|
|
173
|
+
if (v instanceof Date)
|
|
174
|
+
return market_context_1.MarketContext.yyyymmdd(v);
|
|
175
|
+
return String(v);
|
|
176
|
+
}
|
|
177
|
+
default:
|
|
178
|
+
return v;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
byType(sf, ctx) {
|
|
182
|
+
const m = this.market;
|
|
183
|
+
const rng = m.rng;
|
|
184
|
+
switch (sf.tagType) {
|
|
185
|
+
case tag_type_1.TagType.String:
|
|
186
|
+
if (ordinalName.test(sf.name))
|
|
187
|
+
return String(rng.int(0, 4));
|
|
188
|
+
return `${initials(sf.name)}-${rng.int(1000, 99999)}`;
|
|
189
|
+
case tag_type_1.TagType.Int:
|
|
190
|
+
return ordinalName.test(sf.name) ? rng.int(0, 4) : rng.int(1, 500);
|
|
191
|
+
case tag_type_1.TagType.Float:
|
|
192
|
+
return Number((rng.int(1, 100000) / 100).toFixed(2));
|
|
193
|
+
case tag_type_1.TagType.Length:
|
|
194
|
+
return undefined;
|
|
195
|
+
case tag_type_1.TagType.Boolean:
|
|
196
|
+
return rng.bool(0.5);
|
|
197
|
+
case tag_type_1.TagType.UtcTimestamp:
|
|
198
|
+
return m.transactTime;
|
|
199
|
+
case tag_type_1.TagType.UtcTimeOnly: {
|
|
200
|
+
const t = m.transactTime;
|
|
201
|
+
return new Date(Date.UTC(0, 0, 0, t.getUTCHours(), t.getUTCMinutes(), t.getUTCSeconds(), 0));
|
|
202
|
+
}
|
|
203
|
+
case tag_type_1.TagType.UtcDateOnly:
|
|
204
|
+
return m.tradeDate;
|
|
205
|
+
case tag_type_1.TagType.LocalDate: {
|
|
206
|
+
const d = m.tradeDate;
|
|
207
|
+
return new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), 0, 0, 0, 0);
|
|
208
|
+
}
|
|
209
|
+
case tag_type_1.TagType.RawData:
|
|
210
|
+
return Buffer.from(`${initials(sf.name)}:${m.tradeId}:${ctx.instance}`);
|
|
211
|
+
default:
|
|
212
|
+
return undefined;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
exports.ValueConventions = ValueConventions;
|
|
217
|
+
//# sourceMappingURL=value-conventions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"value-conventions.js","sourceRoot":"","sources":["../../src/generator/value-conventions.ts"],"names":[],"mappings":";;;AACA,qDAAgD;AAChD,qDAAgD;AAgChD,MAAM,IAAI,GAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;AACxF,MAAM,UAAU,GAAsB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;AACzE,MAAM,QAAQ,GAAsB,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,CAAC,CAAA;AAC9E,MAAM,OAAO,GAAsB,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;AACrE,MAAM,SAAS,GAAsB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;AAGnE,MAAM,WAAW,GAAG,mEAAmE,CAAA;AASvF,MAAM,KAAK,GAAyB,IAAI,GAAG,CAAkB;IAC3D,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IACnB,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IACjB,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACjF,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IACnB,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC;IAChC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;IACvC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,gBAAgB,CAAC;IACvC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,gBAAgB,CAAC;IACxC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IACnB,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IACpB,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACjF,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;IACrB,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;IACxB,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IAClB,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC;IACjC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAClF,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC;IAC7B,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACnB,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC;IACzB,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACtB,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACtB,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACxB,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,gBAAgB,CAAC;IACzC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;IAC7B,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC;IAChC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACvB,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,YAAY,CAAC;IACpC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,WAAC,OAAA,MAAA,CAAC,CAAC,OAAO,EAAE,CAAC,iBAAiB,mCAAI,CAAC,CAAC,UAAU,CAAC,iBAAiB,CAAA,EAAA,CAAC;IAC3E,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC;IAClC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC;IACpC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,gBAAgB,CAAC;IACzC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,kBAAkB,CAAC;IAC3C,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACzB,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC3B,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC;IACjD,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;IAC3C,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;IAC7C,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC;IAChC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC;IAChC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC;IACrC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IACrB,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACjC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACjC,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC;IACrB,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,MAAM,CAAC;IAG9B,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC;IAC9B,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC;IAClC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,gBAAgB,CAAC;IACxC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,YAAY,CAAC;IACpC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,iBAAiB,CAAC;IACzC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,eAAC,OAAA,MAAA,MAAA,CAAC,CAAC,GAAG,0CAAE,KAAK,mCAAI,CAAC,CAAA,EAAA,CAAC;IAC7B,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,eAAC,OAAA,MAAA,MAAA,CAAC,CAAC,GAAG,0CAAE,IAAI,mCAAI,CAAC,CAAC,IAAI,CAAA,EAAA,CAAC;IACjC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;IACzB,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;IACzB,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,eAAC,OAAA,CAAC,CAAC,OAAO,GAAG,CAAC,MAAA,MAAA,CAAC,CAAC,GAAG,0CAAE,KAAK,mCAAI,CAAC,CAAC,CAAA,EAAA,CAAC;IAG3C,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,eAAC,OAAA,MAAA,MAAA,CAAC,CAAC,UAAU,0CAAE,MAAM,mCAAI,CAAC,CAAC,UAAU,CAAC,MAAM,CAAA,EAAA,CAAC;IACvD,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,eAAC,OAAA,MAAA,MAAA,CAAC,CAAC,UAAU,0CAAE,UAAU,mCAAI,CAAC,CAAC,UAAU,CAAC,UAAU,CAAA,EAAA,CAAC;IAC/D,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,eAAC,OAAA,MAAA,MAAA,CAAC,CAAC,UAAU,0CAAE,gBAAgB,mCAAI,CAAC,CAAC,UAAU,CAAC,gBAAgB,CAAA,EAAA,CAAC;IAG3E,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IACpB,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IAGpB,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;IACzB,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACvB,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC;IAC1B,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;CAC7B,CAAC,CAAA;AAWF,MAAM,SAAS,GAAyB;IACtC,EAAE,IAAI,EAAE,8DAA8D,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE;IAEhG,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE;IAClD,EAAE,IAAI,EAAE,oCAAoC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE;IACxE,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;IAC/D,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE;IACnD,EAAE,IAAI,EAAE,wBAAwB,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;IAChE,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,UAAU,EAAE;IAC3D,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,WAAC,OAAA,MAAA,CAAC,CAAC,OAAO,EAAE,CAAC,iBAAiB,mCAAI,CAAC,CAAC,UAAU,CAAC,iBAAiB,CAAA,EAAA,EAAE;IACrG,EAAE,IAAI,EAAE,sCAAsC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE;IAC7E,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;IAC5F,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;IAC5F,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE;IAC3C,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE;IAChD,EAAE,IAAI,EAAE,+CAA+C,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE;IAC/E,EAAE,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,EAAE;IACzD,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE;IAC1C,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE;IACvE,EAAE,IAAI,EAAE,yBAAyB,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE;CACjE,CAAA;AAED,SAAS,QAAQ,CAAE,IAAY;IAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;IACxC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IACjD,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;AAC3C,CAAC;AAED,MAAa,gBAAgB;IAC3B,YAA6B,MAAqB;QAArB,WAAM,GAAN,MAAM,CAAe;IAClD,CAAC;IAOM,MAAM,CAAC,KAAK,CAAE,GAAW;QAC9B,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACvB,CAAC;IAKM,KAAK,CAAE,EAAyB,EAAE,GAAkB;QACzD,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;QAC/B,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAA;YACrC,IAAI,CAAC,IAAI,IAAI;gBAAE,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;YAGzC,OAAO,SAAS,CAAA;QAClB,CAAC;QACD,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC;YAChB,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;QAC3B,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;gBAAE,SAAQ;YACtC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAA;YAC1C,IAAI,CAAC,IAAI,IAAI;gBAAE,MAAK;YACpB,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;QAC5B,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;IAC7B,CAAC;IAQO,SAAS,CAAE,EAAyB;QAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;QACxC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAA;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;QAC7D,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC;YACnB,KAAK,kBAAO,CAAC,GAAG,CAAC,CAAC,OAAO,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;YAC7C,KAAK,kBAAO,CAAC,KAAK,CAAC,CAAC,OAAO,UAAU,CAAC,MAAM,CAAC,CAAA;YAC7C,KAAK,kBAAO,CAAC,OAAO,CAAC,CAAC,OAAO,MAAM,KAAK,GAAG,CAAA;YAC3C,OAAO,CAAC,CAAC,OAAO,MAAM,CAAA;QACxB,CAAC;IACH,CAAC;IAOO,OAAO,CAAE,EAAyB,EAAE,CAAM;QAChD,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC;YACnB,KAAK,kBAAO,CAAC,OAAO,CAAC,CAAC,CAAC;gBAIrB,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;oBAAE,OAAO,CAAC,CAAA;gBAChC,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;YAC/B,CAAC;YACD,KAAK,kBAAO,CAAC,GAAG,CAAC;YACjB,KAAK,kBAAO,CAAC,MAAM,CAAC,CAAC,CAAC;gBACpB,IAAI,OAAO,CAAC,KAAK,QAAQ;oBAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;gBAC/C,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;gBACjC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAA;YACjC,CAAC;YACD,KAAK,kBAAO,CAAC,KAAK,CAAC,CAAC,CAAC;gBACnB,IAAI,OAAO,CAAC,KAAK,QAAQ;oBAAE,OAAO,CAAC,CAAA;gBACnC,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;gBAC/B,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAA;YACjC,CAAC;YACD,KAAK,kBAAO,CAAC,OAAO,CAAC,CAAC,CAAC;gBACrB,IAAI,OAAO,CAAC,KAAK,SAAS;oBAAE,OAAO,CAAC,CAAA;gBACpC,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAA;YAClD,CAAC;YACD,KAAK,kBAAO,CAAC,MAAM,CAAC,CAAC,CAAC;gBACpB,IAAI,CAAC,YAAY,IAAI;oBAAE,OAAO,8BAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;gBACvD,OAAO,MAAM,CAAC,CAAC,CAAC,CAAA;YAClB,CAAC;YACD;gBACE,OAAO,CAAC,CAAA;QACZ,CAAC;IACH,CAAC;IAEO,MAAM,CAAE,EAAyB,EAAE,GAAkB;QAC3D,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAA;QACrB,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAA;QACjB,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC;YACnB,KAAK,kBAAO,CAAC,MAAM;gBACjB,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;oBAAE,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;gBAG3D,OAAO,GAAG,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAA;YACvD,KAAK,kBAAO,CAAC,GAAG;gBACd,OAAO,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;YACpE,KAAK,kBAAO,CAAC,KAAK;gBAChB,OAAO,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;YACtD,KAAK,kBAAO,CAAC,MAAM;gBAEjB,OAAO,SAAS,CAAA;YAClB,KAAK,kBAAO,CAAC,OAAO;gBAClB,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YACtB,KAAK,kBAAO,CAAC,YAAY;gBACvB,OAAO,CAAC,CAAC,YAAY,CAAA;YACvB,KAAK,kBAAO,CAAC,WAAW,CAAC,CAAC,CAAC;gBACzB,MAAM,CAAC,GAAG,CAAC,CAAC,YAAY,CAAA;gBACxB,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;YAC9F,CAAC;YACD,KAAK,kBAAO,CAAC,WAAW;gBACtB,OAAO,CAAC,CAAC,SAAS,CAAA;YACpB,KAAK,kBAAO,CAAC,SAAS,CAAC,CAAC,CAAC;gBACvB,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAA;gBACrB,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;YAClF,CAAC;YACD,KAAK,kBAAO,CAAC,OAAO;gBAClB,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAA;YACzE;gBACE,OAAO,SAAS,CAAA;QACpB,CAAC;IACH,CAAC;CACF;AAjID,4CAiIC","sourcesContent":["import { SimpleFieldDefinition } from '../dictionary/definition'\nimport { TagType } from '../buffer/tag/tag-type'\nimport { MarketContext } from './market-context'\n\n/**\n * How a tag gets a value that looks like the thing it names.\n *\n * Three layers, tried in order, and the ordering is the design:\n *\n * 1. a table of tags whose meaning the generator actually knows, read off the\n * `MarketContext` so they agree with each other;\n * 2. conventions over the field *name* - anything ending `Px`, `Qty`, `Currency`,\n * `Date` and so on - which is what lets an unfamiliar message type, or a broker\n * dialect nobody here has seen, still come out readable;\n * 3. the type, as a last resort, but with ranges a trader would not blink at rather\n * than a signed float with seven decimal places.\n *\n * Layer 2 is doing most of the work. FIX field naming is remarkably disciplined -\n * `LegLastPx`, `UnderlyingSettlPrice`, `AllocSettlCurrency` - so a suffix is very nearly\n * a type declaration, and treating it as one covers thousands of fields for the cost of\n * a dozen rules.\n *\n * Which *instrument* a value is read from is not decided here. The walker moves\n * `MarketContext.leg` and `.underlying` as it descends, so `LegPrice` inside the second\n * leg resolves against that leg without this layer knowing where it is.\n */\n\nexport interface IFieldContext {\n /** set names from the message down to the field, e.g. ['TrdCapRptSideGrp', 'Parties'] */\n readonly path: readonly string[]\n /** index within the nearest enclosing group instance, 0 when not in a group */\n readonly instance: number\n}\n\nconst mics: readonly string[] = ['XLON', 'XNAS', 'XNYS', 'XETR', 'IFEU', 'XCME', 'XOFF']\nconst currencies: readonly string[] = ['USD', 'EUR', 'GBP', 'JPY', 'CHF']\nconst sessions: readonly string[] = ['DAY', 'REG', 'ELECTRONIC', 'AFTERHOURS']\nconst ratings: readonly string[] = ['AAA', 'AA+', 'A', 'BBB+', 'BB-']\nconst countries: readonly string[] = ['US', 'GB', 'DE', 'NL', 'JP']\n/** a field named for a classification but with no enumeration behind it in this\n * dictionary - still a small ordinal, not a five digit number */\nconst ordinalName = /(Type|Status|Reason|Indicator|Action|Capacity|Method|Mode|Level)$/\n\ntype Handler = (m: MarketContext, ctx: IFieldContext, sf: SimpleFieldDefinition) => any\n\n/**\n * Tags the generator understands well enough to keep consistent with the rest of the\n * message. Everything absent from here still gets a plausible value from the name\n * conventions below - it just is not tied to the trade.\n */\nconst byTag: Map<number, Handler> = new Map<number, Handler>([\n [1, m => m.account],\n [6, m => m.avgPx],\n [11, (m, ctx) => (ctx.instance > 0 ? `${m.clOrdId}-${ctx.instance}` : m.clOrdId)],\n [14, m => m.cumQty],\n [15, m => m.instrument.currency],\n [17, m => `${m.execId}-${m.nextSeq()}`],\n [22, m => m.current().securityIdSource],\n [30, m => m.instrument.securityExchange],\n [31, m => m.lastPx],\n [32, m => m.lastQty],\n [37, (m, ctx) => (ctx.instance > 0 ? `${m.orderId}-${ctx.instance}` : m.orderId)],\n [38, m => m.orderQty],\n [41, m => m.origClOrdId],\n [44, m => m.price],\n [48, m => m.current().securityId],\n [54, (m, ctx) => (ctx.instance % 2 === 0 ? m.side : (m.side === '1' ? '2' : '1'))],\n [55, m => m.current().symbol],\n [58, m => m.text()],\n [60, m => m.transactTime],\n [64, m => m.settlDate],\n [75, m => m.tradeDate],\n [76, m => m.firms[0].id],\n [100, m => m.instrument.securityExchange],\n [107, m => m.instrument.name],\n [110, m => m.instrument.lotSize],\n [151, m => m.leavesQty],\n [167, m => m.current().securityType],\n [200, m => m.current().maturityMonthYear ?? m.instrument.maturityMonthYear],\n [201, m => m.instrument.putOrCall],\n [202, m => m.instrument.strikePrice],\n [207, m => m.instrument.securityExchange],\n [231, m => m.instrument.contractMultiplier],\n [336, m => m.rng.pick(sessions)],\n [375, m => m.firms[2].id],\n [381, m => m.grossAmount()],\n [447, (m, ctx) => m.party(ctx.instance).idSource],\n [448, (m, ctx) => m.party(ctx.instance).id],\n [452, (m, ctx) => m.party(ctx.instance).role],\n [460, m => m.instrument.product],\n [461, m => m.instrument.cfiCode],\n [541, m => m.instrument.maturityDate],\n [571, m => m.tradeId],\n [255, m => m.rng.pick(ratings)],\n [470, m => m.rng.pick(countries)],\n [472, m => m.rng.pick(countries)],\n [65, () => undefined],\n [572, m => `${m.tradeId}-REF`],\n\n // legs - resolved through current(), which the walker has already pointed at the leg\n [600, m => m.current().symbol],\n [602, m => m.current().securityId],\n [603, m => m.current().securityIdSource],\n [609, m => m.current().securityType],\n [610, m => m.current().maturityMonthYear],\n [623, m => m.leg?.ratio ?? 1],\n [624, m => m.leg?.side ?? m.side],\n [566, m => m.priceNear()],\n [637, m => m.priceNear()],\n [687, m => m.lastQty * (m.leg?.ratio ?? 1)],\n\n // underlyings\n [311, m => m.underlying?.symbol ?? m.instrument.symbol],\n [309, m => m.underlying?.securityId ?? m.instrument.securityId],\n [305, m => m.underlying?.securityIdSource ?? m.instrument.securityIdSource],\n\n // allocation\n [79, m => m.account],\n [80, m => m.lastQty],\n\n // market data\n [270, m => m.priceNear()],\n [271, m => m.quantity()],\n [272, m => m.tradeDate],\n [273, m => m.transactTime],\n [346, m => m.rng.int(1, 25)]\n])\n\ninterface INameRule {\n readonly test: RegExp\n readonly apply: Handler\n}\n\n/**\n * Suffix first, then a few prefixes. Order matters - `PriceType` must not be caught by\n * the `Price` rule, so the more specific patterns are listed above the general ones.\n */\nconst nameRules: readonly INameRule[] = [\n { test: /(Type|Source|Status|Reason|Indicator|Capacity|Restrictions)$/, apply: () => undefined },\n\n { test: /(Px|Price)$/, apply: m => m.priceNear() },\n { test: /(Qty|Quantity|Shares|Size|Volume)$/, apply: m => m.quantity() },\n { test: /(Currency|Ccy)$/, apply: m => m.rng.pick(currencies) },\n { test: /Symbol$/, apply: m => m.current().symbol },\n { test: /(Exchange|Mkt|Market)$/, apply: m => m.rng.pick(mics) },\n { test: /SecurityID$/, apply: m => m.current().securityId },\n { test: /(MonthYear)$/, apply: m => m.current().maturityMonthYear ?? m.instrument.maturityMonthYear },\n { test: /(Amt|Amount|Notional|Consideration)$/, apply: m => m.grossAmount() },\n { test: /(Rate|Yield|Coupon)$/, apply: m => Number((m.rng.int(1, 800) / 10000).toFixed(5)) },\n { test: /(Percent|Pct|Ratio)$/, apply: m => Number((m.rng.int(0, 10000) / 100).toFixed(2)) },\n { test: /Account$/, apply: m => m.account },\n { test: /(Desk|Division)$/, apply: m => m.desk },\n { test: /(Text|Desc|Description|Comment|Instructions)$/, apply: m => m.text() },\n { test: /(Timestamp|Time)$/, apply: m => m.transactTime },\n { test: /Date$/, apply: m => m.tradeDate },\n { test: /(Broker|Firm)$/, apply: (m, ctx) => m.party(ctx.instance).id },\n { test: /(Trader|User|Operator)$/, apply: m => m.traders[0].id }\n]\n\nfunction initials (name: string): string {\n const caps = name.replace(/[^A-Z]/g, '')\n if (caps.length >= 2) return caps.substring(0, 4)\n return name.substring(0, 3).toUpperCase()\n}\n\nexport class ValueConventions {\n constructor (public readonly market: MarketContext) {\n }\n\n /**\n * whether this tag is one the generator understands rather than merely guesses at.\n * The field walker reads it as a proxy for \"would a real message of this type carry\n * this field\", which is a crude signal but a better one than the tag number alone.\n */\n public static knows (tag: number): boolean {\n return byTag.has(tag)\n }\n\n /**\n * a value for this field, or undefined if the caller should leave the tag out\n */\n public value (sf: SimpleFieldDefinition, ctx: IFieldContext): any {\n const exact = byTag.get(sf.tag)\n if (exact) {\n const v = exact(this.market, ctx, sf)\n if (v != null) return this.conform(sf, v)\n // a handler declining - e.g. StrikePrice on a future - is a reason to omit, not\n // a reason to fall through and invent one\n return undefined\n }\n if (sf.isEnum()) {\n return this.enumValue(sf)\n }\n for (const rule of nameRules) {\n if (!rule.test.test(sf.name)) continue\n const v = rule.apply(this.market, ctx, sf)\n if (v == null) break\n return this.conform(sf, v)\n }\n return this.byType(sf, ctx)\n }\n\n /**\n * Dictionaries list enumerated values roughly in order of how ordinary they are, so a\n * front biased pick lands on Side 1 or 2 far more often than on the twenty exotics\n * below them. Not true universally, but true often enough to be worth more than a\n * uniform draw, and it stays deterministic.\n */\n private enumValue (sf: SimpleFieldDefinition): any {\n const keys = Array.from(sf.enums.keys())\n if (keys.length === 0) return undefined\n const choice = keys[this.market.rng.frontBiased(keys.length)]\n switch (sf.tagType) {\n case TagType.Int: return parseInt(choice, 10)\n case TagType.Float: return parseFloat(choice)\n case TagType.Boolean: return choice === 'Y'\n default: return choice\n }\n }\n\n /**\n * a value supplied by tag or by name may not be of the type the dictionary declares -\n * `SecurityIDSource` is a String in one dictionary and an Int in another - so coerce\n * rather than emit something the encoder will mangle\n */\n private conform (sf: SimpleFieldDefinition, v: any): any {\n switch (sf.tagType) {\n case TagType.RawData: {\n // a name rule may well have produced a perfectly good string for EncodedText,\n // but the encoder writes the preceding Length only when handed a Buffer, and a\n // raw field arriving without its length is unparseable\n if (Buffer.isBuffer(v)) return v\n return Buffer.from(String(v))\n }\n case TagType.Int:\n case TagType.Length: {\n if (typeof v === 'number') return Math.round(v)\n const n = parseInt(String(v), 10)\n return isNaN(n) ? undefined : n\n }\n case TagType.Float: {\n if (typeof v === 'number') return v\n const f = parseFloat(String(v))\n return isNaN(f) ? undefined : f\n }\n case TagType.Boolean: {\n if (typeof v === 'boolean') return v\n return String(v) === 'Y' || String(v) === 'true'\n }\n case TagType.String: {\n if (v instanceof Date) return MarketContext.yyyymmdd(v)\n return String(v)\n }\n default:\n return v\n }\n }\n\n private byType (sf: SimpleFieldDefinition, ctx: IFieldContext): any {\n const m = this.market\n const rng = m.rng\n switch (sf.tagType) {\n case TagType.String:\n if (ordinalName.test(sf.name)) return String(rng.int(0, 4))\n // identifier shaped, and carrying the field it came from, so a message can be\n // read back to the dictionary by eye\n return `${initials(sf.name)}-${rng.int(1000, 99999)}`\n case TagType.Int:\n return ordinalName.test(sf.name) ? rng.int(0, 4) : rng.int(1, 500)\n case TagType.Float:\n return Number((rng.int(1, 100000) / 100).toFixed(2))\n case TagType.Length:\n // written by the encoder from the RawData it precedes\n return undefined\n case TagType.Boolean:\n return rng.bool(0.5)\n case TagType.UtcTimestamp:\n return m.transactTime\n case TagType.UtcTimeOnly: {\n const t = m.transactTime\n return new Date(Date.UTC(0, 0, 0, t.getUTCHours(), t.getUTCMinutes(), t.getUTCSeconds(), 0))\n }\n case TagType.UtcDateOnly:\n return m.tradeDate\n case TagType.LocalDate: {\n const d = m.tradeDate\n return new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), 0, 0, 0, 0)\n }\n case TagType.RawData:\n return Buffer.from(`${initials(sf.name)}:${m.tradeId}:${ctx.instance}`)\n default:\n return undefined\n }\n }\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,3 +4,9 @@ export * from './buffer';
|
|
|
4
4
|
export * from './transport';
|
|
5
5
|
export * from './config';
|
|
6
6
|
export * from './types';
|
|
7
|
+
export * from './collections';
|
|
8
|
+
export * from './store';
|
|
9
|
+
export * from './util/definition-factory';
|
|
10
|
+
export * from './util/dictionary-path';
|
|
11
|
+
export type { IStandardHeader, IHop } from './types/FIX4.4/repo';
|
|
12
|
+
export type { IStandardHeader as IFixmlStandardHeader } from './types/FIXML50SP2';
|
package/dist/index.js
CHANGED
|
@@ -20,4 +20,8 @@ __exportStar(require("./buffer"), exports);
|
|
|
20
20
|
__exportStar(require("./transport"), exports);
|
|
21
21
|
__exportStar(require("./config"), exports);
|
|
22
22
|
__exportStar(require("./types"), exports);
|
|
23
|
+
__exportStar(require("./collections"), exports);
|
|
24
|
+
__exportStar(require("./store"), exports);
|
|
25
|
+
__exportStar(require("./util/definition-factory"), exports);
|
|
26
|
+
__exportStar(require("./util/dictionary-path"), exports);
|
|
23
27
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4CAAyB;AACzB,+CAA4B;AAC5B,2CAAwB;AACxB,8CAA2B;AAC3B,2CAAwB;AACxB,0CAAuB","sourcesContent":["export * from './runtime'\nexport * from './dictionary'\nexport * from './buffer'\nexport * from './transport'\nexport * from './config'\nexport * from './types'\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4CAAyB;AACzB,+CAA4B;AAC5B,2CAAwB;AACxB,8CAA2B;AAC3B,2CAAwB;AACxB,0CAAuB;AACvB,gDAA6B;AAC7B,0CAAuB;AACvB,4DAAyC;AACzC,yDAAsC","sourcesContent":["export * from './runtime'\nexport * from './dictionary'\nexport * from './buffer'\nexport * from './transport'\nexport * from './config'\nexport * from './types'\nexport * from './collections'\nexport * from './store'\nexport * from './util/definition-factory'\nexport * from './util/dictionary-path'\n\n// These live in the generated dictionaries but appear in the public signature of\n// the session message factory, so an application overriding logon() or header()\n// has to be able to name them. Without this it can only reach them behind a\n// dist/ path, which is what drove the module augmentation in issue #85. The\n// FIXML one is aliased because both dictionaries call theirs IStandardHeader.\nexport type { IStandardHeader, IHop } from './types/FIX4.4/repo'\nexport type { IStandardHeader as IFixmlStandardHeader } from './types/FIXML50SP2'\n"]}
|
package/dist/jsfix-cmd.d.ts
CHANGED
|
@@ -31,6 +31,11 @@ export declare class JsfixCmd {
|
|
|
31
31
|
exec(): Promise<any>;
|
|
32
32
|
private firstMessage;
|
|
33
33
|
protected generate(): Promise<void>;
|
|
34
|
+
private generateCase;
|
|
35
|
+
private static generatorOverrides;
|
|
36
|
+
private addToCorpus;
|
|
37
|
+
private reportRoundTrip;
|
|
38
|
+
private parseOnce;
|
|
34
39
|
private single;
|
|
35
40
|
private script;
|
|
36
41
|
private unitTest;
|
package/dist/jsfix-cmd.js
CHANGED
|
@@ -50,6 +50,7 @@ require("reflect-metadata");
|
|
|
50
50
|
const buffer_1 = require("./buffer");
|
|
51
51
|
const ascii_1 = require("./buffer/ascii");
|
|
52
52
|
const util_1 = require("./util");
|
|
53
|
+
const generator_1 = require("./generator");
|
|
53
54
|
const transport_1 = require("./transport");
|
|
54
55
|
const types_1 = require("./types");
|
|
55
56
|
const util = __importStar(require("util"));
|
|
@@ -141,6 +142,38 @@ const options = (0, minimist_options_1.default)({
|
|
|
141
142
|
alias: 'd',
|
|
142
143
|
default: 0.8
|
|
143
144
|
},
|
|
145
|
+
scenarios: {
|
|
146
|
+
type: 'boolean',
|
|
147
|
+
default: false
|
|
148
|
+
},
|
|
149
|
+
realistic: {
|
|
150
|
+
type: 'boolean',
|
|
151
|
+
default: false
|
|
152
|
+
},
|
|
153
|
+
'russian-doll': {
|
|
154
|
+
type: 'number',
|
|
155
|
+
default: 0
|
|
156
|
+
},
|
|
157
|
+
fragments: {
|
|
158
|
+
type: 'number',
|
|
159
|
+
default: 2
|
|
160
|
+
},
|
|
161
|
+
seed: {
|
|
162
|
+
type: 'number',
|
|
163
|
+
default: 0
|
|
164
|
+
},
|
|
165
|
+
'as-of': {
|
|
166
|
+
type: 'string',
|
|
167
|
+
default: ''
|
|
168
|
+
},
|
|
169
|
+
'corpus-add': {
|
|
170
|
+
type: 'string',
|
|
171
|
+
default: ''
|
|
172
|
+
},
|
|
173
|
+
note: {
|
|
174
|
+
type: 'string',
|
|
175
|
+
default: ''
|
|
176
|
+
},
|
|
144
177
|
repeats: {
|
|
145
178
|
type: 'number',
|
|
146
179
|
alias: 'r',
|
|
@@ -336,6 +369,15 @@ class JsfixCmd {
|
|
|
336
369
|
}
|
|
337
370
|
generate() {
|
|
338
371
|
return __awaiter(this, void 0, void 0, function* () {
|
|
372
|
+
if (argv.scenarios) {
|
|
373
|
+
console.log('scenarios - a named shape of traffic, generated to look like the real thing');
|
|
374
|
+
console.log(generator_1.Scenarios.describe());
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
if (argv.scenario || argv.realistic || argv['russian-doll'] > 0) {
|
|
378
|
+
yield this.generateCase();
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
339
381
|
const lipPath = path.join(this.root, 'data/examples/lipsum.txt');
|
|
340
382
|
const words = yield (0, util_1.getWords)(lipPath);
|
|
341
383
|
const generator = new util_1.MessageGenerator(words, this.definitions);
|
|
@@ -355,6 +397,104 @@ class JsfixCmd {
|
|
|
355
397
|
}
|
|
356
398
|
});
|
|
357
399
|
}
|
|
400
|
+
generateCase() {
|
|
401
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
402
|
+
if (!this.session) {
|
|
403
|
+
console.log('provide a session json file e.g. --session=data/session/test-initiator.json');
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
const delimiter = String.fromCharCode(this.delimiter);
|
|
407
|
+
const builder = new generator_1.CaseBuilder(this.definitions, (msgType, obj) => this.encodeObject(msgType, obj));
|
|
408
|
+
const generated = builder.build({
|
|
409
|
+
scenario: argv.scenario,
|
|
410
|
+
msgType: argv.type,
|
|
411
|
+
seed: argv.seed || 0x5eed,
|
|
412
|
+
depth: argv['russian-doll'] || 0,
|
|
413
|
+
fragments: argv.fragments || 2,
|
|
414
|
+
delimiter,
|
|
415
|
+
generator: JsfixCmd.generatorOverrides()
|
|
416
|
+
});
|
|
417
|
+
console.log((0, generator_1.describeCase)(generated, delimiter));
|
|
418
|
+
console.log('');
|
|
419
|
+
console.log(JSON.stringify(generated.object, null, 4));
|
|
420
|
+
console.log('');
|
|
421
|
+
console.log(`canonical ${generated.canonical}`);
|
|
422
|
+
if (generated.plan.depth > 0) {
|
|
423
|
+
console.log(`scattered ${generated.scattered}`);
|
|
424
|
+
}
|
|
425
|
+
const outcome = yield this.reportRoundTrip(generated);
|
|
426
|
+
if (argv.unit) {
|
|
427
|
+
yield JsfixCmd.writeFile('./fix.txt', generated.scattered);
|
|
428
|
+
yield JsfixCmd.writeFile('./canonical.txt', generated.canonical);
|
|
429
|
+
yield JsfixCmd.writeFile('./object.json', JSON.stringify(generated.object, null, 4));
|
|
430
|
+
yield JsfixCmd.writeFile('./plan.json', JSON.stringify(generated.plan, null, 4));
|
|
431
|
+
yield JsfixCmd.writeFile('./case.txt', (0, generator_1.describeCase)(generated, delimiter));
|
|
432
|
+
}
|
|
433
|
+
if (argv['corpus-add']) {
|
|
434
|
+
this.addToCorpus(generated, outcome, delimiter);
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
static generatorOverrides() {
|
|
439
|
+
const overrides = {};
|
|
440
|
+
if (argv['as-of']) {
|
|
441
|
+
overrides.asOf = new Date(argv['as-of']);
|
|
442
|
+
}
|
|
443
|
+
if (argv.realistic && argv.density != null) {
|
|
444
|
+
overrides.density = parseFloat(argv.density);
|
|
445
|
+
}
|
|
446
|
+
return overrides;
|
|
447
|
+
}
|
|
448
|
+
addToCorpus(generated, outcome, delimiter) {
|
|
449
|
+
var _a, _b, _c, _d;
|
|
450
|
+
if (generated.plan.depth === 0) {
|
|
451
|
+
console.log('cannot add to the corpus - nothing was scattered, so there is nothing to assert');
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
if (!outcome) {
|
|
455
|
+
console.log('cannot add to the corpus - the canonical encoding did not parse');
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
const name = `${argv['corpus-add']}`;
|
|
459
|
+
const note = argv.note ? `${argv.note}` : (0, generator_1.describeOutcome)(outcome);
|
|
460
|
+
const session = `${argv.session}`.replace(/^.*data[\\/]/, '');
|
|
461
|
+
const store = new generator_1.CorpusStore(path.join(this.root, 'data/corpus'));
|
|
462
|
+
const entry = generator_1.CorpusStore.fromCase(name, note, `${(_d = (_a = argv.dict) !== null && _a !== void 0 ? _a : (_c = (_b = this.sessionDescription) === null || _b === void 0 ? void 0 : _b.application) === null || _c === void 0 ? void 0 : _c.dictionary) !== null && _d !== void 0 ? _d : 'unknown'}`, session, delimiter, generated, outcome.outcome, outcome, argv['as-of'] ? new Date(argv['as-of']) : undefined);
|
|
463
|
+
const written = store.save(entry, generated.canonical, generated.scattered);
|
|
464
|
+
console.log(`corpus case ${name} written to ${written}`);
|
|
465
|
+
console.log(`expected outcome recorded as ${outcome.outcome} - read it before committing`);
|
|
466
|
+
}
|
|
467
|
+
reportRoundTrip(generated) {
|
|
468
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
469
|
+
var _a;
|
|
470
|
+
const canonical = yield this.parseOnce(generated.canonical);
|
|
471
|
+
if (!canonical.view) {
|
|
472
|
+
console.log(`canonical does not parse: ${(_a = canonical.error) !== null && _a !== void 0 ? _a : 'no message'}`);
|
|
473
|
+
return null;
|
|
474
|
+
}
|
|
475
|
+
if (generated.plan.depth === 0) {
|
|
476
|
+
console.log('canonical parses');
|
|
477
|
+
return null;
|
|
478
|
+
}
|
|
479
|
+
const scattered = yield this.parseOnce(generated.scattered);
|
|
480
|
+
const outcome = (0, generator_1.classify)(canonical.view.toObject(), scattered.view ? scattered.view.toObject() : null);
|
|
481
|
+
console.log((0, generator_1.describeOutcome)(outcome));
|
|
482
|
+
return outcome;
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
parseOnce(fix) {
|
|
486
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
487
|
+
var _a;
|
|
488
|
+
const transport = new factory_1.MsgTransport(1, this.session.config, new transport_1.StringDuplex(fix));
|
|
489
|
+
try {
|
|
490
|
+
const view = yield this.firstMessage(transport);
|
|
491
|
+
return { view, error: null };
|
|
492
|
+
}
|
|
493
|
+
catch (e) {
|
|
494
|
+
return { view: null, error: (_a = e === null || e === void 0 ? void 0 : e.message) !== null && _a !== void 0 ? _a : `${e}` };
|
|
495
|
+
}
|
|
496
|
+
});
|
|
497
|
+
}
|
|
358
498
|
single(generator, density) {
|
|
359
499
|
return __awaiter(this, void 0, void 0, function* () {
|
|
360
500
|
if (!argv.type) {
|
|
@@ -761,6 +901,27 @@ function showHelp() {
|
|
|
761
901
|
console.log('script to describe field in fixml');
|
|
762
902
|
console.log('npm run fixml -- --field=50');
|
|
763
903
|
console.log();
|
|
904
|
+
console.log('list the named scenarios - lifelike messages built from a book of real instruments');
|
|
905
|
+
console.log('node dist/jsfix-cmd --generate --scenarios --session=data/session/test-initiator.json');
|
|
906
|
+
console.log('npm run scenarios');
|
|
907
|
+
console.log();
|
|
908
|
+
console.log('generate one lifelike message - prices on tick, quantities in lots, dates that agree');
|
|
909
|
+
console.log('node dist/jsfix-cmd --generate --scenario=spread-trade-capture --delimiter="|" --session=data/session/test-initiator.json');
|
|
910
|
+
console.log('npm run scenario -- --scenario=equity-fill');
|
|
911
|
+
console.log();
|
|
912
|
+
console.log('take the message apart - russian doll n scatters a component inside a component, n levels deep,');
|
|
913
|
+
console.log('then parses both orderings and says whether this engine survives the shape');
|
|
914
|
+
console.log('node dist/jsfix-cmd --generate --scenario=spread-trade-capture --russian-doll=2 --delimiter="|" --session=data/session/test-initiator.json');
|
|
915
|
+
console.log('npm run doll -- --scenario=spread-trade-capture --russian-doll=2');
|
|
916
|
+
console.log('add --seed=42 --as-of=2026-01-15T10:30:00Z to reproduce a case exactly, --unit to write the files');
|
|
917
|
+
console.log();
|
|
918
|
+
console.log('keep an interesting case - freezes the two encodings and the outcome into data/corpus,');
|
|
919
|
+
console.log('where src/test/ascii/corpus.test.ts picks it up. read what it wrote, then commit it');
|
|
920
|
+
console.log('npm run doll -- --scenario=spread-trade-capture --russian-doll=2 --seed=1 --as-of=2026-01-15T10:30:00Z --corpus-add=my-case --note="what this shows"');
|
|
921
|
+
console.log();
|
|
922
|
+
console.log('any message type, lifelike rather than dense - see docs/scattered-components.md for what doll depth means');
|
|
923
|
+
console.log('node dist/jsfix-cmd --generate --realistic --type=8 --density=0.5 --delimiter="|" --session=data/session/test-initiator.json');
|
|
924
|
+
console.log();
|
|
764
925
|
console.log('generate unit test set of files - i.e. randomly generate an object, encode to fix. density 1 is all fields');
|
|
765
926
|
console.log('node dist/jsfix-cmd --generate --type=AE --density=0.8 --unit --delimiter="|" --session=data/session/test-initiator.json');
|
|
766
927
|
console.log('npm run repo44-unit -- --type=AE');
|