@omnitronix/bonnys-fortune-game-engine 1.8.1 → 1.8.2

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.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,456 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ /**
37
+ * Test Protocol: 10,000-Spin Simulation -- Bonnys Fortune
38
+ *
39
+ * Extended test protocol that validates game engine integrity over 10,000 spins.
40
+ * Writes per-spin NDJSON results to results/ directory for offline analysis.
41
+ *
42
+ * Tests:
43
+ * 1. 10,000 Base Game Spins with Bonus Completion
44
+ * 2. RTP Validation Over 10,000 Spins (tighter bounds: 70%-130%)
45
+ * 3. Bonus Coverage -- Debug Trigger 200x Each Bonus Type
46
+ * 4. State Consistency Over 10,000 Spins
47
+ */
48
+ const fs = __importStar(require("fs"));
49
+ const path = __importStar(require("path"));
50
+ const test_engine_factory_1 = require("./helpers/test-engine-factory");
51
+ // ---------------------------------------------------------------------------
52
+ // NDJSON Output Setup
53
+ // ---------------------------------------------------------------------------
54
+ const RESULTS_DIR = path.resolve(__dirname, '../../results');
55
+ function ensureResultsDir() {
56
+ if (!fs.existsSync(RESULTS_DIR)) {
57
+ fs.mkdirSync(RESULTS_DIR, { recursive: true });
58
+ }
59
+ }
60
+ function ndjsonPath(filename) {
61
+ return path.join(RESULTS_DIR, filename);
62
+ }
63
+ function appendNdjson(filepath, record) {
64
+ fs.appendFileSync(filepath, JSON.stringify(record) + '\n', 'utf-8');
65
+ }
66
+ // ---------------------------------------------------------------------------
67
+ // Helpers (same pattern as integration-1000-spin.test.ts)
68
+ // ---------------------------------------------------------------------------
69
+ /** Extract playerWinning from a command result outcome. */
70
+ function extractPlayerWinning(result) {
71
+ const outcome = result.outcome;
72
+ return outcome?.result?.playerWinning
73
+ ?? outcome?.playerWinning
74
+ ?? outcome?.result?.totalWin
75
+ ?? outcome?.totalWin
76
+ ?? 0;
77
+ }
78
+ /** Drain all pending bonuses, including chained ones (e.g. bonusGame3 -> bonusGame1). */
79
+ async function drainAllBonuses(engine, pub, priv, betAmount, tracker) {
80
+ let maxDepth = 10; // safety guard against infinite chaining
81
+ while (priv.pendingBonuses?.length > 0 && maxDepth-- > 0) {
82
+ const bonus = priv.pendingBonuses[0];
83
+ const bonusType = bonus.bonusType;
84
+ tracker.bonusTriggersPerType[bonusType] =
85
+ (tracker.bonusTriggersPerType[bonusType] ?? 0) + 1;
86
+ try {
87
+ const bonusResult = await (0, test_engine_factory_1.startBonusRound)(engine, pub, priv, bonusType, betAmount);
88
+ expect(bonusResult.success).toBe(true);
89
+ // Sum bonus winnings from results array
90
+ const bonusOutcome = bonusResult.outcome;
91
+ if (bonusOutcome?.results) {
92
+ for (const r of bonusOutcome.results) {
93
+ const win = r.result?.playerWinning ?? 0;
94
+ tracker.totalWon += win;
95
+ }
96
+ }
97
+ else {
98
+ tracker.totalWon += extractPlayerWinning(bonusResult);
99
+ }
100
+ const finalState = (0, test_engine_factory_1.extractFinalBonusState)(bonusResult);
101
+ pub = finalState.publicState;
102
+ priv = finalState.privateState;
103
+ }
104
+ catch (error) {
105
+ // Prevent cascade failures: log and break out of bonus drain
106
+ console.warn(`[drainAllBonuses] Error draining ${bonusType}: ${error instanceof Error ? error.message : String(error)}`);
107
+ break;
108
+ }
109
+ }
110
+ return { pub, priv };
111
+ }
112
+ /** Validate state consistency assertions after any command. */
113
+ function assertStateConsistency(pub, priv) {
114
+ // publicState.bonusMeters has exactly 3 keys
115
+ expect(pub.bonusMeters).toBeDefined();
116
+ expect(Object.keys(pub.bonusMeters).length).toBe(3);
117
+ expect(pub.bonusMeters).toHaveProperty('bonusGame1');
118
+ expect(pub.bonusMeters).toHaveProperty('bonusGame2');
119
+ expect(pub.bonusMeters).toHaveProperty('bonusGame3');
120
+ // privateState.nextSpinType is defined and non-empty
121
+ expect(priv.nextSpinType).toBeDefined();
122
+ expect(typeof priv.nextSpinType).toBe('string');
123
+ expect(priv.nextSpinType.length).toBeGreaterThan(0);
124
+ // privateState.pendingBonuses is an array
125
+ expect(Array.isArray(priv.pendingBonuses)).toBe(true);
126
+ }
127
+ // ---------------------------------------------------------------------------
128
+ // Test Suites
129
+ // ---------------------------------------------------------------------------
130
+ describe('Test Protocol: 10,000-Spin Simulation -- Bonnys Fortune', () => {
131
+ beforeEach(() => {
132
+ (0, test_engine_factory_1.resetCommandIdCounter)();
133
+ });
134
+ // -----------------------------------------------------------------------
135
+ // Test 1: 10,000 Base Game Spins with Bonus Completion
136
+ // -----------------------------------------------------------------------
137
+ describe('Test 1: 10,000 Base Game Spins with Bonus Completion', () => {
138
+ it('should complete 10,000 spins, handling any natural bonus triggers, writing NDJSON results', async () => {
139
+ ensureResultsDir();
140
+ const ndjsonFile = ndjsonPath('test1-10000-base-spins.ndjson');
141
+ // Truncate any previous run
142
+ fs.writeFileSync(ndjsonFile, '', 'utf-8');
143
+ const { engine } = (0, test_engine_factory_1.createEngineWithLcgRng)(99887);
144
+ const session = await (0, test_engine_factory_1.initSession)(engine, 1.0);
145
+ let pub = session.publicState;
146
+ let priv = session.privateState;
147
+ const betAmount = 1.0;
148
+ let totalWagered = 0;
149
+ let totalWon = 0;
150
+ let spinCount = 0;
151
+ const bonusTriggersPerType = {};
152
+ const tracker = { bonusTriggersPerType, totalWon };
153
+ for (let i = 0; i < 10000; i++) {
154
+ // If a bonus is pending, drain it before spinning
155
+ if (priv.nextSpinType &&
156
+ priv.nextSpinType !== 'BASE_GAME_SPIN' &&
157
+ priv.pendingBonuses?.length > 0) {
158
+ const drained = await drainAllBonuses(engine, pub, priv, betAmount, tracker);
159
+ pub = drained.pub;
160
+ priv = drained.priv;
161
+ }
162
+ // Execute base game spin
163
+ const spinResult = await (0, test_engine_factory_1.safeExecuteSpin)(engine, pub, priv, betAmount);
164
+ // safeExecuteSpin returns null if bonus state prevents spin
165
+ if (!spinResult) {
166
+ // Force drain any leftover bonus
167
+ if (priv.pendingBonuses?.length > 0) {
168
+ const drained = await drainAllBonuses(engine, pub, priv, betAmount, tracker);
169
+ pub = drained.pub;
170
+ priv = drained.priv;
171
+ }
172
+ // Retry the spin
173
+ const retry = await (0, test_engine_factory_1.safeExecuteSpin)(engine, pub, priv, betAmount);
174
+ if (!retry) {
175
+ // Skip this iteration if still stuck
176
+ continue;
177
+ }
178
+ spinCount++;
179
+ totalWagered += betAmount;
180
+ const win = extractPlayerWinning(retry);
181
+ totalWon += win;
182
+ pub = retry.publicState;
183
+ priv = retry.privateState;
184
+ // Write NDJSON record for retry
185
+ appendNdjson(ndjsonFile, {
186
+ spin: spinCount,
187
+ iteration: i,
188
+ wagered: betAmount,
189
+ win,
190
+ retried: true,
191
+ nextSpinType: priv.nextSpinType,
192
+ pendingBonuses: priv.pendingBonuses?.length ?? 0,
193
+ });
194
+ continue;
195
+ }
196
+ spinCount++;
197
+ totalWagered += betAmount;
198
+ const win = extractPlayerWinning(spinResult);
199
+ totalWon += win;
200
+ pub = spinResult.publicState;
201
+ priv = spinResult.privateState;
202
+ // Write NDJSON record
203
+ appendNdjson(ndjsonFile, {
204
+ spin: spinCount,
205
+ iteration: i,
206
+ wagered: betAmount,
207
+ win,
208
+ retried: false,
209
+ nextSpinType: priv.nextSpinType,
210
+ pendingBonuses: priv.pendingBonuses?.length ?? 0,
211
+ });
212
+ // If the spin triggered a bonus, drain it
213
+ if (priv.pendingBonuses?.length > 0) {
214
+ const drained = await drainAllBonuses(engine, pub, priv, betAmount, tracker);
215
+ pub = drained.pub;
216
+ priv = drained.priv;
217
+ }
218
+ // Log progress every 1,000 spins
219
+ if (spinCount % 1000 === 0) {
220
+ const runningTotalWon = totalWon + tracker.totalWon;
221
+ console.log(` [Test 1] Progress: ${spinCount} spins | Wagered: ${totalWagered.toFixed(2)} | Won: ${runningTotalWon.toFixed(2)} | RTP: ${totalWagered > 0 ? ((runningTotalWon / totalWagered) * 100).toFixed(2) : 0}%`);
222
+ }
223
+ }
224
+ // Include bonus wins tracked separately
225
+ totalWon += tracker.totalWon;
226
+ console.log('=== Test 1: 10,000 Base Game Spins ===');
227
+ console.log(` Spins completed: ${spinCount}`);
228
+ console.log(` Total wagered: ${totalWagered.toFixed(2)}`);
229
+ console.log(` Total won: ${totalWon.toFixed(2)}`);
230
+ console.log(` RTP: ${totalWagered > 0 ? ((totalWon / totalWagered) * 100).toFixed(2) : 0}%`);
231
+ console.log(` Bonus triggers: ${JSON.stringify(bonusTriggersPerType)}`);
232
+ console.log(` NDJSON output: ${ndjsonFile}`);
233
+ // Assertions
234
+ expect(spinCount).toBeGreaterThanOrEqual(9500);
235
+ expect(totalWon).toBeGreaterThanOrEqual(0);
236
+ expect(totalWagered).toBeGreaterThan(0);
237
+ }, 600000);
238
+ });
239
+ // -----------------------------------------------------------------------
240
+ // Test 2: RTP Validation Over 10,000 Spins
241
+ // -----------------------------------------------------------------------
242
+ describe('Test 2: RTP Validation Over 10,000 Spins', () => {
243
+ it('should produce RTP between 0.70 and 1.30 (70%-130%) -- tighter bounds for 10,000 spins', async () => {
244
+ const { engine } = (0, test_engine_factory_1.createEngineWithLcgRng)(99887);
245
+ const session = await (0, test_engine_factory_1.initSession)(engine, 1.0);
246
+ let pub = session.publicState;
247
+ let priv = session.privateState;
248
+ const betAmount = 1.0;
249
+ let totalWagered = 0;
250
+ let totalWon = 0;
251
+ let paidSpins = 0;
252
+ const tracker = {
253
+ bonusTriggersPerType: {},
254
+ totalWon: 0,
255
+ };
256
+ while (paidSpins < 10000) {
257
+ // Drain any pending bonuses
258
+ if (priv.pendingBonuses?.length > 0) {
259
+ const drained = await drainAllBonuses(engine, pub, priv, betAmount, tracker);
260
+ pub = drained.pub;
261
+ priv = drained.priv;
262
+ }
263
+ // Ensure we're in BASE_GAME_SPIN
264
+ if (priv.nextSpinType !== 'BASE_GAME_SPIN') {
265
+ break;
266
+ }
267
+ const spinResult = await (0, test_engine_factory_1.safeExecuteSpin)(engine, pub, priv, betAmount);
268
+ if (!spinResult)
269
+ break;
270
+ paidSpins++;
271
+ totalWagered += betAmount;
272
+ const win = extractPlayerWinning(spinResult);
273
+ totalWon += win;
274
+ pub = spinResult.publicState;
275
+ priv = spinResult.privateState;
276
+ // Drain bonuses triggered by spin
277
+ if (priv.pendingBonuses?.length > 0) {
278
+ const drained = await drainAllBonuses(engine, pub, priv, betAmount, tracker);
279
+ pub = drained.pub;
280
+ priv = drained.priv;
281
+ }
282
+ // Log progress every 2,500 spins
283
+ if (paidSpins % 2500 === 0) {
284
+ const runningTotalWon = totalWon + tracker.totalWon;
285
+ console.log(` [Test 2] Progress: ${paidSpins} paid spins | RTP: ${totalWagered > 0 ? ((runningTotalWon / totalWagered) * 100).toFixed(2) : 0}%`);
286
+ }
287
+ }
288
+ // Combine base game wins with bonus wins
289
+ totalWon += tracker.totalWon;
290
+ const rtp = totalWagered > 0 ? totalWon / totalWagered : 0;
291
+ console.log('=== Test 2: RTP Validation (10,000 Spins) ===');
292
+ console.log(` Paid spins: ${paidSpins}`);
293
+ console.log(` Total wagered: ${totalWagered.toFixed(2)}`);
294
+ console.log(` Total won: ${totalWon.toFixed(2)}`);
295
+ console.log(` RTP: ${(rtp * 100).toFixed(2)}%`);
296
+ console.log(` Bonus triggers: ${JSON.stringify(tracker.bonusTriggersPerType)}`);
297
+ expect(paidSpins).toBeGreaterThanOrEqual(9500);
298
+ // Tighter bounds for 10,000 spins: declared RTP ~96%, SD shrinks with sqrt(n)
299
+ expect(rtp).toBeGreaterThanOrEqual(0.70);
300
+ expect(rtp).toBeLessThanOrEqual(1.30);
301
+ }, 600000);
302
+ });
303
+ // -----------------------------------------------------------------------
304
+ // Test 3: Bonus Coverage -- Debug Trigger 200x Each Bonus Type
305
+ // -----------------------------------------------------------------------
306
+ describe('Test 3: Bonus Coverage -- 200x Each Bonus Type', () => {
307
+ const bonusTypes = [
308
+ 'bonusGame1',
309
+ 'bonusGame2',
310
+ 'bonusGame3',
311
+ 'collectFeature',
312
+ ];
313
+ for (const bonusType of bonusTypes) {
314
+ it(`should trigger ${bonusType} 200 times without crashes`, async () => {
315
+ let wins = 0;
316
+ let completions = 0;
317
+ for (let i = 0; i < 200; i++) {
318
+ (0, test_engine_factory_1.resetCommandIdCounter)();
319
+ const seed = 50000 + i * 41; // Different seed each iteration, unique from other tests
320
+ const { engine } = (0, test_engine_factory_1.createEngineWithLcgRng)(seed);
321
+ const session = await (0, test_engine_factory_1.initSession)(engine);
322
+ try {
323
+ const debugResult = await (0, test_engine_factory_1.debugTriggerBonus)(engine, session.publicState, session.privateState, bonusType);
324
+ expect(debugResult.success).toBe(true);
325
+ const bonus = debugResult.privateState.pendingBonuses[0];
326
+ const bonusResult = await (0, test_engine_factory_1.startBonusRound)(engine, debugResult.publicState, debugResult.privateState, bonus.bonusType);
327
+ expect(bonusResult.success).toBe(true);
328
+ completions++;
329
+ // Track total wins from bonus results
330
+ const stressOutcome = (0, test_engine_factory_1.getOutcome)(bonusResult);
331
+ if (stressOutcome.results) {
332
+ for (const r of stressOutcome.results) {
333
+ const w = r.result?.playerWinning ?? 0;
334
+ wins += w;
335
+ }
336
+ }
337
+ // Drain chained bonuses (bonusGame3 can chain to bonusGame1)
338
+ const finalState = (0, test_engine_factory_1.extractFinalBonusState)(bonusResult);
339
+ let pub = finalState.publicState;
340
+ let priv = finalState.privateState;
341
+ let depth = 5;
342
+ while (priv.pendingBonuses?.length > 0 && depth-- > 0) {
343
+ const chainedBonus = priv.pendingBonuses[0];
344
+ const chainedResult = await (0, test_engine_factory_1.startBonusRound)(engine, pub, priv, chainedBonus.bonusType);
345
+ expect(chainedResult.success).toBe(true);
346
+ const chainFinal = (0, test_engine_factory_1.extractFinalBonusState)(chainedResult);
347
+ pub = chainFinal.publicState;
348
+ priv = chainFinal.privateState;
349
+ }
350
+ }
351
+ catch (error) {
352
+ // Prevent cascade failures: log and continue to next iteration
353
+ console.warn(`[Test 3] ${bonusType} iteration ${i} failed: ${error instanceof Error ? error.message : String(error)}`);
354
+ }
355
+ }
356
+ console.log(`=== Test 3: Bonus Coverage: ${bonusType} x200 ===`);
357
+ console.log(` Completions: ${completions}/200`);
358
+ console.log(` Total bonus wins: ${wins.toFixed(2)}`);
359
+ expect(completions).toBe(200);
360
+ }, 600000);
361
+ }
362
+ });
363
+ // -----------------------------------------------------------------------
364
+ // Test 4: State Consistency Over 10,000 Spins
365
+ // -----------------------------------------------------------------------
366
+ describe('Test 4: State Consistency Over 10,000 Spins', () => {
367
+ it('should maintain valid state after every spin and bonus round across 10,000 spins', async () => {
368
+ const { engine } = (0, test_engine_factory_1.createEngineWithLcgRng)(99887);
369
+ const session = await (0, test_engine_factory_1.initSession)(engine, 1.0);
370
+ let pub = session.publicState;
371
+ let priv = session.privateState;
372
+ const betAmount = 1.0;
373
+ let stateValidationFailures = 0;
374
+ let spinsCompleted = 0;
375
+ let bonusRoundsValidated = 0;
376
+ // Check initial state
377
+ try {
378
+ assertStateConsistency(pub, priv);
379
+ }
380
+ catch {
381
+ stateValidationFailures++;
382
+ }
383
+ for (let i = 0; i < 10000; i++) {
384
+ // Drain pending bonuses with consistency checks
385
+ if (priv.pendingBonuses?.length > 0) {
386
+ let depth = 10;
387
+ while (priv.pendingBonuses?.length > 0 && depth-- > 0) {
388
+ const bonus = priv.pendingBonuses[0];
389
+ try {
390
+ const bonusResult = await (0, test_engine_factory_1.startBonusRound)(engine, pub, priv, bonus.bonusType, betAmount);
391
+ expect(bonusResult.success).toBe(true);
392
+ // Check bonus winnings are non-negative
393
+ const consistencyOutcome = (0, test_engine_factory_1.getOutcome)(bonusResult);
394
+ if (consistencyOutcome.results) {
395
+ for (const r of consistencyOutcome.results) {
396
+ const w = r.result?.playerWinning ?? 0;
397
+ if (w < 0) {
398
+ stateValidationFailures++;
399
+ }
400
+ }
401
+ }
402
+ const finalState = (0, test_engine_factory_1.extractFinalBonusState)(bonusResult);
403
+ pub = finalState.publicState;
404
+ priv = finalState.privateState;
405
+ // Assert state consistency after every bonus round
406
+ try {
407
+ assertStateConsistency(pub, priv);
408
+ }
409
+ catch {
410
+ stateValidationFailures++;
411
+ }
412
+ bonusRoundsValidated++;
413
+ }
414
+ catch (error) {
415
+ // Prevent cascade failures: log, break bonus drain
416
+ console.warn(`[Test 4] Bonus drain error at spin ${i}: ${error instanceof Error ? error.message : String(error)}`);
417
+ break;
418
+ }
419
+ }
420
+ }
421
+ if (priv.nextSpinType !== 'BASE_GAME_SPIN') {
422
+ continue;
423
+ }
424
+ const spinResult = await (0, test_engine_factory_1.safeExecuteSpin)(engine, pub, priv, betAmount);
425
+ if (!spinResult)
426
+ continue;
427
+ spinsCompleted++;
428
+ // Check spin winning is non-negative
429
+ const spinWin = extractPlayerWinning(spinResult);
430
+ if (spinWin < 0) {
431
+ stateValidationFailures++;
432
+ }
433
+ pub = spinResult.publicState;
434
+ priv = spinResult.privateState;
435
+ // Verify state consistency after every spin
436
+ try {
437
+ assertStateConsistency(pub, priv);
438
+ }
439
+ catch {
440
+ stateValidationFailures++;
441
+ }
442
+ // Log progress every 2,000 spins
443
+ if (spinsCompleted % 2000 === 0) {
444
+ console.log(` [Test 4] Progress: ${spinsCompleted} spins validated | Bonus rounds: ${bonusRoundsValidated} | Failures: ${stateValidationFailures}`);
445
+ }
446
+ }
447
+ console.log('=== Test 4: State Consistency (10,000 Spins) ===');
448
+ console.log(` Spins completed: ${spinsCompleted}`);
449
+ console.log(` Bonus rounds validated: ${bonusRoundsValidated}`);
450
+ console.log(` State validation failures: ${stateValidationFailures}`);
451
+ // Assertions
452
+ expect(stateValidationFailures).toBe(0);
453
+ }, 600000);
454
+ });
455
+ });
456
+ //# sourceMappingURL=test-protocol-10000-spin.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-protocol-10000-spin.test.js","sourceRoot":"","sources":["../../src/__tests__/test-protocol-10000-spin.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;GAWG;AACH,uCAAyB;AACzB,2CAA6B;AAC7B,uEAWuC;AASvC,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;AAE7D,SAAS,gBAAgB;IACvB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,QAAgB;IAClC,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,YAAY,CAAC,QAAgB,EAAE,MAA+B;IACrE,EAAE,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AACtE,CAAC;AAED,8EAA8E;AAC9E,0DAA0D;AAC1D,8EAA8E;AAE9E,2DAA2D;AAC3D,SAAS,oBAAoB,CAAC,MAAkC;IAC9D,MAAM,OAAO,GAAG,MAAM,CAAC,OAIf,CAAC;IACT,OAAO,OAAO,EAAE,MAAM,EAAE,aAAa;WAChC,OAAO,EAAE,aAAa;WACtB,OAAO,EAAE,MAAM,EAAE,QAAQ;WACzB,OAAO,EAAE,QAAQ;WACjB,CAAC,CAAC;AACT,CAAC;AAED,yFAAyF;AACzF,KAAK,UAAU,eAAe,CAC5B,MAAiC,EACjC,GAA6B,EAC7B,IAA+B,EAC/B,SAAiB,EACjB,OAGC;IAED,IAAI,QAAQ,GAAG,EAAE,CAAC,CAAC,yCAAyC;IAC5D,OAAO,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,CAAC,IAAI,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC;QACzD,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;QAElC,OAAO,CAAC,oBAAoB,CAAC,SAAS,CAAC;YACrC,CAAC,OAAO,CAAC,oBAAoB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAErD,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,MAAM,IAAA,qCAAe,EACvC,MAAM,EACN,GAAG,EACH,IAAI,EACJ,SAAS,EACT,SAAS,CACV,CAAC;YACF,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEvC,wCAAwC;YACxC,MAAM,YAAY,GAAG,WAAW,CAAC,OAAyD,CAAC;YAC3F,IAAI,YAAY,EAAE,OAAO,EAAE,CAAC;gBAC1B,KAAK,MAAM,CAAC,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;oBACrC,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,aAAa,IAAI,CAAC,CAAC;oBACzC,OAAO,CAAC,QAAQ,IAAI,GAAG,CAAC;gBAC1B,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,QAAQ,IAAI,oBAAoB,CAAC,WAAW,CAAC,CAAC;YACxD,CAAC;YAED,MAAM,UAAU,GAAG,IAAA,4CAAsB,EAAC,WAAW,CAAC,CAAC;YACvD,GAAG,GAAG,UAAU,CAAC,WAAW,CAAC;YAC7B,IAAI,GAAG,UAAU,CAAC,YAAY,CAAC;QACjC,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,6DAA6D;YAC7D,OAAO,CAAC,IAAI,CACV,oCAAoC,SAAS,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC3G,CAAC;YACF,MAAM;QACR,CAAC;IACH,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AACvB,CAAC;AAED,+DAA+D;AAC/D,SAAS,sBAAsB,CAC7B,GAA6B,EAC7B,IAA+B;IAE/B,6CAA6C;IAC7C,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;IACtC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpD,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;IACrD,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;IACrD,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;IAErD,qDAAqD;IACrD,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;IACxC,MAAM,CAAC,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAEpD,0CAA0C;IAC1C,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxD,CAAC;AAED,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E,QAAQ,CAAC,yDAAyD,EAAE,GAAG,EAAE;IACvE,UAAU,CAAC,GAAG,EAAE;QACd,IAAA,2CAAqB,GAAE,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,uDAAuD;IACvD,0EAA0E;IAC1E,QAAQ,CAAC,sDAAsD,EAAE,GAAG,EAAE;QACpE,EAAE,CACA,2FAA2F,EAC3F,KAAK,IAAI,EAAE;YACT,gBAAgB,EAAE,CAAC;YACnB,MAAM,UAAU,GAAG,UAAU,CAAC,+BAA+B,CAAC,CAAC;YAC/D,4BAA4B;YAC5B,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;YAE1C,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,4CAAsB,EAAC,KAAK,CAAC,CAAC;YACjD,MAAM,OAAO,GAAG,MAAM,IAAA,iCAAW,EAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YAE/C,IAAI,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC;YAC9B,IAAI,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC;YAChC,MAAM,SAAS,GAAG,GAAG,CAAC;YAEtB,IAAI,YAAY,GAAG,CAAC,CAAC;YACrB,IAAI,QAAQ,GAAG,CAAC,CAAC;YACjB,IAAI,SAAS,GAAG,CAAC,CAAC;YAClB,MAAM,oBAAoB,GAA2B,EAAE,CAAC;YACxD,MAAM,OAAO,GAAG,EAAE,oBAAoB,EAAE,QAAQ,EAAE,CAAC;YAEnD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/B,kDAAkD;gBAClD,IACE,IAAI,CAAC,YAAY;oBACjB,IAAI,CAAC,YAAY,KAAK,gBAAgB;oBACtC,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,CAAC,EAC/B,CAAC;oBACD,MAAM,OAAO,GAAG,MAAM,eAAe,CACnC,MAAM,EACN,GAAG,EACH,IAAI,EACJ,SAAS,EACT,OAAO,CACR,CAAC;oBACF,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;oBAClB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;gBACtB,CAAC;gBAED,yBAAyB;gBACzB,MAAM,UAAU,GAAG,MAAM,IAAA,qCAAe,EACtC,MAAM,EACN,GAAG,EACH,IAAI,EACJ,SAAS,CACV,CAAC;gBAEF,4DAA4D;gBAC5D,IAAI,CAAC,UAAU,EAAE,CAAC;oBAChB,iCAAiC;oBACjC,IAAI,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;wBACpC,MAAM,OAAO,GAAG,MAAM,eAAe,CACnC,MAAM,EACN,GAAG,EACH,IAAI,EACJ,SAAS,EACT,OAAO,CACR,CAAC;wBACF,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;wBAClB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;oBACtB,CAAC;oBACD,iBAAiB;oBACjB,MAAM,KAAK,GAAG,MAAM,IAAA,qCAAe,EACjC,MAAM,EACN,GAAG,EACH,IAAI,EACJ,SAAS,CACV,CAAC;oBACF,IAAI,CAAC,KAAK,EAAE,CAAC;wBACX,qCAAqC;wBACrC,SAAS;oBACX,CAAC;oBACD,SAAS,EAAE,CAAC;oBACZ,YAAY,IAAI,SAAS,CAAC;oBAE1B,MAAM,GAAG,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;oBACxC,QAAQ,IAAI,GAAG,CAAC;oBAEhB,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC;oBACxB,IAAI,GAAG,KAAK,CAAC,YAAY,CAAC;oBAE1B,gCAAgC;oBAChC,YAAY,CAAC,UAAU,EAAE;wBACvB,IAAI,EAAE,SAAS;wBACf,SAAS,EAAE,CAAC;wBACZ,OAAO,EAAE,SAAS;wBAClB,GAAG;wBACH,OAAO,EAAE,IAAI;wBACb,YAAY,EAAE,IAAI,CAAC,YAAY;wBAC/B,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,IAAI,CAAC;qBACjD,CAAC,CAAC;oBACH,SAAS;gBACX,CAAC;gBAED,SAAS,EAAE,CAAC;gBACZ,YAAY,IAAI,SAAS,CAAC;gBAE1B,MAAM,GAAG,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;gBAC7C,QAAQ,IAAI,GAAG,CAAC;gBAEhB,GAAG,GAAG,UAAU,CAAC,WAAW,CAAC;gBAC7B,IAAI,GAAG,UAAU,CAAC,YAAY,CAAC;gBAE/B,sBAAsB;gBACtB,YAAY,CAAC,UAAU,EAAE;oBACvB,IAAI,EAAE,SAAS;oBACf,SAAS,EAAE,CAAC;oBACZ,OAAO,EAAE,SAAS;oBAClB,GAAG;oBACH,OAAO,EAAE,KAAK;oBACd,YAAY,EAAE,IAAI,CAAC,YAAY;oBAC/B,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,IAAI,CAAC;iBACjD,CAAC,CAAC;gBAEH,0CAA0C;gBAC1C,IAAI,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;oBACpC,MAAM,OAAO,GAAG,MAAM,eAAe,CACnC,MAAM,EACN,GAAG,EACH,IAAI,EACJ,SAAS,EACT,OAAO,CACR,CAAC;oBACF,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;oBAClB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;gBACtB,CAAC;gBAED,iCAAiC;gBACjC,IAAI,SAAS,GAAG,IAAI,KAAK,CAAC,EAAE,CAAC;oBAC3B,MAAM,eAAe,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;oBACpD,OAAO,CAAC,GAAG,CACT,wBAAwB,SAAS,qBAAqB,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,GAAG,YAAY,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAC3M,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,wCAAwC;YACxC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;YAE7B,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;YACtD,OAAO,CAAC,GAAG,CAAC,sBAAsB,SAAS,EAAE,CAAC,CAAC;YAC/C,OAAO,CAAC,GAAG,CAAC,oBAAoB,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC3D,OAAO,CAAC,GAAG,CAAC,gBAAgB,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACnD,OAAO,CAAC,GAAG,CACT,UAAU,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,YAAY,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CACjF,CAAC;YACF,OAAO,CAAC,GAAG,CACT,qBAAqB,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,EAAE,CAC5D,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,oBAAoB,UAAU,EAAE,CAAC,CAAC;YAE9C,aAAa;YACb,MAAM,CAAC,SAAS,CAAC,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;YAC/C,MAAM,CAAC,QAAQ,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;YAC3C,MAAM,CAAC,YAAY,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC1C,CAAC,EACD,MAAM,CACP,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,2CAA2C;IAC3C,0EAA0E;IAC1E,QAAQ,CAAC,0CAA0C,EAAE,GAAG,EAAE;QACxD,EAAE,CACA,wFAAwF,EACxF,KAAK,IAAI,EAAE;YACT,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,4CAAsB,EAAC,KAAK,CAAC,CAAC;YACjD,MAAM,OAAO,GAAG,MAAM,IAAA,iCAAW,EAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YAE/C,IAAI,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC;YAC9B,IAAI,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC;YAChC,MAAM,SAAS,GAAG,GAAG,CAAC;YAEtB,IAAI,YAAY,GAAG,CAAC,CAAC;YACrB,IAAI,QAAQ,GAAG,CAAC,CAAC;YACjB,IAAI,SAAS,GAAG,CAAC,CAAC;YAClB,MAAM,OAAO,GAAG;gBACd,oBAAoB,EAAE,EAA4B;gBAClD,QAAQ,EAAE,CAAC;aACZ,CAAC;YAEF,OAAO,SAAS,GAAG,KAAK,EAAE,CAAC;gBACzB,4BAA4B;gBAC5B,IAAI,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;oBACpC,MAAM,OAAO,GAAG,MAAM,eAAe,CACnC,MAAM,EACN,GAAG,EACH,IAAI,EACJ,SAAS,EACT,OAAO,CACR,CAAC;oBACF,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;oBAClB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;gBACtB,CAAC;gBAED,iCAAiC;gBACjC,IAAI,IAAI,CAAC,YAAY,KAAK,gBAAgB,EAAE,CAAC;oBAC3C,MAAM;gBACR,CAAC;gBAED,MAAM,UAAU,GAAG,MAAM,IAAA,qCAAe,EACtC,MAAM,EACN,GAAG,EACH,IAAI,EACJ,SAAS,CACV,CAAC;gBACF,IAAI,CAAC,UAAU;oBAAE,MAAM;gBAEvB,SAAS,EAAE,CAAC;gBACZ,YAAY,IAAI,SAAS,CAAC;gBAE1B,MAAM,GAAG,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;gBAC7C,QAAQ,IAAI,GAAG,CAAC;gBAEhB,GAAG,GAAG,UAAU,CAAC,WAAW,CAAC;gBAC7B,IAAI,GAAG,UAAU,CAAC,YAAY,CAAC;gBAE/B,kCAAkC;gBAClC,IAAI,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;oBACpC,MAAM,OAAO,GAAG,MAAM,eAAe,CACnC,MAAM,EACN,GAAG,EACH,IAAI,EACJ,SAAS,EACT,OAAO,CACR,CAAC;oBACF,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;oBAClB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;gBACtB,CAAC;gBAED,iCAAiC;gBACjC,IAAI,SAAS,GAAG,IAAI,KAAK,CAAC,EAAE,CAAC;oBAC3B,MAAM,eAAe,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;oBACpD,OAAO,CAAC,GAAG,CACT,wBAAwB,SAAS,sBAAsB,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,GAAG,YAAY,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CACrI,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,yCAAyC;YACzC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;YAE7B,MAAM,GAAG,GACP,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;YAEjD,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;YAC7D,OAAO,CAAC,GAAG,CAAC,iBAAiB,SAAS,EAAE,CAAC,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,oBAAoB,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC3D,OAAO,CAAC,GAAG,CAAC,gBAAgB,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACnD,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACjD,OAAO,CAAC,GAAG,CACT,qBAAqB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE,CACpE,CAAC;YAEF,MAAM,CAAC,SAAS,CAAC,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;YAC/C,8EAA8E;YAC9E,MAAM,CAAC,GAAG,CAAC,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,CAAC,GAAG,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QACxC,CAAC,EACD,MAAM,CACP,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,+DAA+D;IAC/D,0EAA0E;IAC1E,QAAQ,CAAC,gDAAgD,EAAE,GAAG,EAAE;QAC9D,MAAM,UAAU,GAAG;YACjB,YAAY;YACZ,YAAY;YACZ,YAAY;YACZ,gBAAgB;SACjB,CAAC;QAEF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,EAAE,CACA,kBAAkB,SAAS,4BAA4B,EACvD,KAAK,IAAI,EAAE;gBACT,IAAI,IAAI,GAAG,CAAC,CAAC;gBACb,IAAI,WAAW,GAAG,CAAC,CAAC;gBAEpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC7B,IAAA,2CAAqB,GAAE,CAAC;oBACxB,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,yDAAyD;oBACtF,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,4CAAsB,EAAC,IAAI,CAAC,CAAC;oBAChD,MAAM,OAAO,GAAG,MAAM,IAAA,iCAAW,EAAC,MAAM,CAAC,CAAC;oBAE1C,IAAI,CAAC;wBACH,MAAM,WAAW,GAAG,MAAM,IAAA,uCAAiB,EACzC,MAAM,EACN,OAAO,CAAC,WAAW,EACnB,OAAO,CAAC,YAAY,EACpB,SAAS,CACV,CAAC;wBAEF,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBAEvC,MAAM,KAAK,GAAG,WAAW,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;wBACzD,MAAM,WAAW,GAAG,MAAM,IAAA,qCAAe,EACvC,MAAM,EACN,WAAW,CAAC,WAAW,EACvB,WAAW,CAAC,YAAY,EACxB,KAAK,CAAC,SAAS,CAChB,CAAC;wBAEF,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBACvC,WAAW,EAAE,CAAC;wBAEd,sCAAsC;wBACtC,MAAM,aAAa,GAAG,IAAA,gCAAU,EAAC,WAAW,CAAC,CAAC;wBAC9C,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;4BAC1B,KAAK,MAAM,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;gCACtC,MAAM,CAAC,GACL,CAAC,CAAC,MAAM,EAAE,aAAa,IAAI,CAAC,CAAC;gCAC/B,IAAI,IAAI,CAAC,CAAC;4BACZ,CAAC;wBACH,CAAC;wBAED,6DAA6D;wBAC7D,MAAM,UAAU,GAAG,IAAA,4CAAsB,EAAC,WAAW,CAAC,CAAC;wBACvD,IAAI,GAAG,GAAG,UAAU,CAAC,WAAW,CAAC;wBACjC,IAAI,IAAI,GAAG,UAAU,CAAC,YAAY,CAAC;wBACnC,IAAI,KAAK,GAAG,CAAC,CAAC;wBACd,OAAO,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,CAAC,IAAI,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC;4BACtD,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;4BAC5C,MAAM,aAAa,GAAG,MAAM,IAAA,qCAAe,EACzC,MAAM,EACN,GAAG,EACH,IAAI,EACJ,YAAY,CAAC,SAAS,CACvB,CAAC;4BACF,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;4BACzC,MAAM,UAAU,GAAG,IAAA,4CAAsB,EAAC,aAAa,CAAC,CAAC;4BACzD,GAAG,GAAG,UAAU,CAAC,WAAW,CAAC;4BAC7B,IAAI,GAAG,UAAU,CAAC,YAAY,CAAC;wBACjC,CAAC;oBACH,CAAC;oBAAC,OAAO,KAAc,EAAE,CAAC;wBACxB,+DAA+D;wBAC/D,OAAO,CAAC,IAAI,CACV,YAAY,SAAS,cAAc,CAAC,YAAY,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACzG,CAAC;oBACJ,CAAC;gBACH,CAAC;gBAED,OAAO,CAAC,GAAG,CACT,+BAA+B,SAAS,WAAW,CACpD,CAAC;gBACF,OAAO,CAAC,GAAG,CAAC,kBAAkB,WAAW,MAAM,CAAC,CAAC;gBACjD,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAEtD,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChC,CAAC,EACD,MAAM,CACP,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,8CAA8C;IAC9C,0EAA0E;IAC1E,QAAQ,CAAC,6CAA6C,EAAE,GAAG,EAAE;QAC3D,EAAE,CACA,kFAAkF,EAClF,KAAK,IAAI,EAAE;YACT,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,4CAAsB,EAAC,KAAK,CAAC,CAAC;YACjD,MAAM,OAAO,GAAG,MAAM,IAAA,iCAAW,EAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YAE/C,IAAI,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC;YAC9B,IAAI,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC;YAChC,MAAM,SAAS,GAAG,GAAG,CAAC;YAEtB,IAAI,uBAAuB,GAAG,CAAC,CAAC;YAChC,IAAI,cAAc,GAAG,CAAC,CAAC;YACvB,IAAI,oBAAoB,GAAG,CAAC,CAAC;YAE7B,sBAAsB;YACtB,IAAI,CAAC;gBACH,sBAAsB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACpC,CAAC;YAAC,MAAM,CAAC;gBACP,uBAAuB,EAAE,CAAC;YAC5B,CAAC;YAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/B,gDAAgD;gBAChD,IAAI,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;oBACpC,IAAI,KAAK,GAAG,EAAE,CAAC;oBACf,OAAO,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,CAAC,IAAI,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC;wBACtD,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;wBAErC,IAAI,CAAC;4BACH,MAAM,WAAW,GAAG,MAAM,IAAA,qCAAe,EACvC,MAAM,EACN,GAAG,EACH,IAAI,EACJ,KAAK,CAAC,SAAS,EACf,SAAS,CACV,CAAC;4BAEF,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;4BAEvC,wCAAwC;4BACxC,MAAM,kBAAkB,GAAG,IAAA,gCAAU,EAAC,WAAW,CAAC,CAAC;4BACnD,IAAI,kBAAkB,CAAC,OAAO,EAAE,CAAC;gCAC/B,KAAK,MAAM,CAAC,IAAI,kBAAkB,CAAC,OAAO,EAAE,CAAC;oCAC3C,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,aAAa,IAAI,CAAC,CAAC;oCACvC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;wCACV,uBAAuB,EAAE,CAAC;oCAC5B,CAAC;gCACH,CAAC;4BACH,CAAC;4BAED,MAAM,UAAU,GAAG,IAAA,4CAAsB,EAAC,WAAW,CAAC,CAAC;4BACvD,GAAG,GAAG,UAAU,CAAC,WAAW,CAAC;4BAC7B,IAAI,GAAG,UAAU,CAAC,YAAY,CAAC;4BAE/B,mDAAmD;4BACnD,IAAI,CAAC;gCACH,sBAAsB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;4BACpC,CAAC;4BAAC,MAAM,CAAC;gCACP,uBAAuB,EAAE,CAAC;4BAC5B,CAAC;4BACD,oBAAoB,EAAE,CAAC;wBACzB,CAAC;wBAAC,OAAO,KAAc,EAAE,CAAC;4BACxB,mDAAmD;4BACnD,OAAO,CAAC,IAAI,CACV,sCAAsC,CAAC,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACrG,CAAC;4BACF,MAAM;wBACR,CAAC;oBACH,CAAC;gBACH,CAAC;gBAED,IAAI,IAAI,CAAC,YAAY,KAAK,gBAAgB,EAAE,CAAC;oBAC3C,SAAS;gBACX,CAAC;gBAED,MAAM,UAAU,GAAG,MAAM,IAAA,qCAAe,EACtC,MAAM,EACN,GAAG,EACH,IAAI,EACJ,SAAS,CACV,CAAC;gBACF,IAAI,CAAC,UAAU;oBAAE,SAAS;gBAE1B,cAAc,EAAE,CAAC;gBAEjB,qCAAqC;gBACrC,MAAM,OAAO,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;gBACjD,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;oBAChB,uBAAuB,EAAE,CAAC;gBAC5B,CAAC;gBAED,GAAG,GAAG,UAAU,CAAC,WAAW,CAAC;gBAC7B,IAAI,GAAG,UAAU,CAAC,YAAY,CAAC;gBAE/B,4CAA4C;gBAC5C,IAAI,CAAC;oBACH,sBAAsB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;gBACpC,CAAC;gBAAC,MAAM,CAAC;oBACP,uBAAuB,EAAE,CAAC;gBAC5B,CAAC;gBAED,iCAAiC;gBACjC,IAAI,cAAc,GAAG,IAAI,KAAK,CAAC,EAAE,CAAC;oBAChC,OAAO,CAAC,GAAG,CACT,wBAAwB,cAAc,oCAAoC,oBAAoB,gBAAgB,uBAAuB,EAAE,CACxI,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;YAChE,OAAO,CAAC,GAAG,CAAC,sBAAsB,cAAc,EAAE,CAAC,CAAC;YACpD,OAAO,CAAC,GAAG,CAAC,6BAA6B,oBAAoB,EAAE,CAAC,CAAC;YACjE,OAAO,CAAC,GAAG,CAAC,gCAAgC,uBAAuB,EAAE,CAAC,CAAC;YAEvE,aAAa;YACb,MAAM,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1C,CAAC,EACD,MAAM,CACP,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -4,9 +4,8 @@ import { BonnysFortuneGameLogic } from './logic/bonnys-fortune.game-logic';
4
4
  import { GameLogicConfigLoader } from './config/game-logic-config/game-logic-config-loader';
5
5
  import { GameLogicConfigValidationService } from './validation/game-logic-config-validation.service';
6
6
  import { ILogger, DebugIntrospectable, DebugCommandDefinition } from '@omnitronix/game-engine-contract';
7
- import { SlotGameHandler } from '@omnitronix/game-engine-sdk/dist/handlers';
8
- import type { BetConfig as SdkBetConfig, SlotState as SdkSlotState, SpinResult as SdkSpinResult, BonusTrigger as SdkBonusTrigger, BonusResult as SdkBonusResult } from '@omnitronix/game-engine-sdk/dist/handlers';
9
- import type { GameTypeConfig } from '@omnitronix/game-engine-sdk/dist/game-type-config';
7
+ import { SlotGameHandler } from '@omnitronix/game-engine-sdk';
8
+ import type { BetConfig as SdkBetConfig, SlotState as SdkSlotState, SpinResult as SdkSpinResult, BonusTrigger as SdkBonusTrigger, BonusResult as SdkBonusResult, GameTypeConfig } from '@omnitronix/game-engine-sdk';
10
9
  import { ReelStripsConfigLoader } from './config/reel-strips-config/reel-strips-config-loader';
11
10
  import { ReelStripsConfigMapper } from './domain/mappers/reel-strips-config.mapper';
12
11
  import { ReelStripsConfigValidationService } from './validation/reel-strips-config-validation.service';
@@ -8,7 +8,7 @@ const file_system_reel_strips_config_loader_1 = require("./config/reel-strips-co
8
8
  const game_logic_config_validation_service_1 = require("./validation/game-logic-config-validation.service");
9
9
  const game_round_types_1 = require("./domain/game-round.types");
10
10
  const game_engine_contract_1 = require("@omnitronix/game-engine-contract");
11
- const handlers_1 = require("@omnitronix/game-engine-sdk/dist/handlers");
11
+ const game_engine_sdk_1 = require("@omnitronix/game-engine-sdk");
12
12
  const debug_command_definitions_1 = require("./debug/debug-command-definitions");
13
13
  const reel_strips_config_mapper_1 = require("./domain/mappers/reel-strips-config.mapper");
14
14
  const reel_strips_config_validation_service_1 = require("./validation/reel-strips-config-validation.service");
@@ -16,7 +16,7 @@ const rng_client_factory_1 = require("./rng/rng-client.factory");
16
16
  const rng_service_1 = require("./rng/rng-service");
17
17
  // eslint-disable-next-line @typescript-eslint/no-var-requires
18
18
  const packageJson = require('../package.json');
19
- class BonnysFortuneV1GameEngine extends handlers_1.SlotGameHandler {
19
+ class BonnysFortuneV1GameEngine extends game_engine_sdk_1.SlotGameHandler {
20
20
  constructor(config = {}) {
21
21
  super();
22
22
  this.gameCode = 'bonnys-fortune';
@@ -1 +1 @@
1
- {"version":3,"file":"bonnys-fortune-v1.game-engine.js","sourceRoot":"","sources":["../src/bonnys-fortune-v1.game-engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bonnys-fortune-v1.game-engine.js","sourceRoot":"","sources":["../src/bonnys-fortune-v1.game-engine.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -3,5 +3,4 @@ export { BonnysFortuneV1GameEngine, BonnysFortuneV1GameEngineConfig, } from './b
3
3
  export { GameEngine, GameEngineInfo, GameActionCommand, CommandProcessingResult, RngOutcome, RngOutcomeRecord, ILogger, DebugIntrospectable, DebugCommandDefinition, isDebugIntrospectable, } from '@omnitronix/game-engine-contract';
4
4
  export { BONNYS_FORTUNE_BONUS_TYPES, BONNYS_FORTUNE_DEBUG_DEFINITIONS, getDebugCommandDefinitions, DebugSecurityError, } from './debug/debug-command-definitions';
5
5
  export { GameEngineConfig, GameEngineMetricsHandlers } from './game-engine.interface';
6
- export type { GameTypeConfig } from '@omnitronix/game-engine-sdk/dist/game-type-config';
7
- export type { BonusResultDeliveryStrategy, BonusRoundResponse } from '@omnitronix/game-engine-sdk/dist/core';
6
+ export type { GameTypeConfig, BonusResultDeliveryStrategy, BonusRoundResponse } from '@omnitronix/game-engine-sdk';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omnitronix/bonnys-fortune-game-engine",
3
- "version": "1.8.1",
3
+ "version": "1.8.2",
4
4
  "description": "Bonnys Fortune Game Engine",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -29,6 +29,7 @@
29
29
  },
30
30
  "devDependencies": {
31
31
  "@omnitronix/game-test-utils": "^1.1.0",
32
+ "@types/express": "^5.0.6",
32
33
  "@types/jest": "^29.5.0",
33
34
  "@types/node": "^20.0.0",
34
35
  "@types/uuid": "^9.0.0",
@@ -0,0 +1,643 @@
1
+ /**
2
+ * Test Protocol: 10,000-Spin Simulation -- Bonnys Fortune
3
+ *
4
+ * Extended test protocol that validates game engine integrity over 10,000 spins.
5
+ * Writes per-spin NDJSON results to results/ directory for offline analysis.
6
+ *
7
+ * Tests:
8
+ * 1. 10,000 Base Game Spins with Bonus Completion
9
+ * 2. RTP Validation Over 10,000 Spins (tighter bounds: 70%-130%)
10
+ * 3. Bonus Coverage -- Debug Trigger 200x Each Bonus Type
11
+ * 4. State Consistency Over 10,000 Spins
12
+ */
13
+ import * as fs from 'fs';
14
+ import * as path from 'path';
15
+ import {
16
+ createEngineWithLcgRng,
17
+ initSession,
18
+ executeSpin,
19
+ safeExecuteSpin,
20
+ startBonusRound,
21
+ extractFinalBonusState,
22
+ debugTriggerBonus,
23
+ resetCommandIdCounter,
24
+ BonnysFortuneCommandResult,
25
+ getOutcome,
26
+ } from './helpers/test-engine-factory';
27
+ import { BonnysFortuneV1GameEngine } from '../bonnys-fortune-v1.game-engine';
28
+ import {
29
+ BonnysFortunePublicState,
30
+ BonnysFortunePrivateState,
31
+ SpinResult,
32
+ BonusRoundResult,
33
+ } from '../logic/bonnys-fortune.types';
34
+
35
+ // ---------------------------------------------------------------------------
36
+ // NDJSON Output Setup
37
+ // ---------------------------------------------------------------------------
38
+
39
+ const RESULTS_DIR = path.resolve(__dirname, '../../results');
40
+
41
+ function ensureResultsDir(): void {
42
+ if (!fs.existsSync(RESULTS_DIR)) {
43
+ fs.mkdirSync(RESULTS_DIR, { recursive: true });
44
+ }
45
+ }
46
+
47
+ function ndjsonPath(filename: string): string {
48
+ return path.join(RESULTS_DIR, filename);
49
+ }
50
+
51
+ function appendNdjson(filepath: string, record: Record<string, unknown>): void {
52
+ fs.appendFileSync(filepath, JSON.stringify(record) + '\n', 'utf-8');
53
+ }
54
+
55
+ // ---------------------------------------------------------------------------
56
+ // Helpers (same pattern as integration-1000-spin.test.ts)
57
+ // ---------------------------------------------------------------------------
58
+
59
+ /** Extract playerWinning from a command result outcome. */
60
+ function extractPlayerWinning(result: BonnysFortuneCommandResult): number {
61
+ const outcome = result.outcome as unknown as {
62
+ result?: { playerWinning?: number; totalWin?: number };
63
+ playerWinning?: number;
64
+ totalWin?: number;
65
+ } | null;
66
+ return outcome?.result?.playerWinning
67
+ ?? outcome?.playerWinning
68
+ ?? outcome?.result?.totalWin
69
+ ?? outcome?.totalWin
70
+ ?? 0;
71
+ }
72
+
73
+ /** Drain all pending bonuses, including chained ones (e.g. bonusGame3 -> bonusGame1). */
74
+ async function drainAllBonuses(
75
+ engine: BonnysFortuneV1GameEngine,
76
+ pub: BonnysFortunePublicState,
77
+ priv: BonnysFortunePrivateState,
78
+ betAmount: number,
79
+ tracker: {
80
+ bonusTriggersPerType: Record<string, number>;
81
+ totalWon: number;
82
+ },
83
+ ): Promise<{ pub: BonnysFortunePublicState; priv: BonnysFortunePrivateState }> {
84
+ let maxDepth = 10; // safety guard against infinite chaining
85
+ while (priv.pendingBonuses?.length > 0 && maxDepth-- > 0) {
86
+ const bonus = priv.pendingBonuses[0];
87
+ const bonusType = bonus.bonusType;
88
+
89
+ tracker.bonusTriggersPerType[bonusType] =
90
+ (tracker.bonusTriggersPerType[bonusType] ?? 0) + 1;
91
+
92
+ try {
93
+ const bonusResult = await startBonusRound(
94
+ engine,
95
+ pub,
96
+ priv,
97
+ bonusType,
98
+ betAmount,
99
+ );
100
+ expect(bonusResult.success).toBe(true);
101
+
102
+ // Sum bonus winnings from results array
103
+ const bonusOutcome = bonusResult.outcome as unknown as BonusRoundResult<SpinResult> | null;
104
+ if (bonusOutcome?.results) {
105
+ for (const r of bonusOutcome.results) {
106
+ const win = r.result?.playerWinning ?? 0;
107
+ tracker.totalWon += win;
108
+ }
109
+ } else {
110
+ tracker.totalWon += extractPlayerWinning(bonusResult);
111
+ }
112
+
113
+ const finalState = extractFinalBonusState(bonusResult);
114
+ pub = finalState.publicState;
115
+ priv = finalState.privateState;
116
+ } catch (error: unknown) {
117
+ // Prevent cascade failures: log and break out of bonus drain
118
+ console.warn(
119
+ `[drainAllBonuses] Error draining ${bonusType}: ${error instanceof Error ? error.message : String(error)}`,
120
+ );
121
+ break;
122
+ }
123
+ }
124
+ return { pub, priv };
125
+ }
126
+
127
+ /** Validate state consistency assertions after any command. */
128
+ function assertStateConsistency(
129
+ pub: BonnysFortunePublicState,
130
+ priv: BonnysFortunePrivateState,
131
+ ): void {
132
+ // publicState.bonusMeters has exactly 3 keys
133
+ expect(pub.bonusMeters).toBeDefined();
134
+ expect(Object.keys(pub.bonusMeters).length).toBe(3);
135
+ expect(pub.bonusMeters).toHaveProperty('bonusGame1');
136
+ expect(pub.bonusMeters).toHaveProperty('bonusGame2');
137
+ expect(pub.bonusMeters).toHaveProperty('bonusGame3');
138
+
139
+ // privateState.nextSpinType is defined and non-empty
140
+ expect(priv.nextSpinType).toBeDefined();
141
+ expect(typeof priv.nextSpinType).toBe('string');
142
+ expect(priv.nextSpinType.length).toBeGreaterThan(0);
143
+
144
+ // privateState.pendingBonuses is an array
145
+ expect(Array.isArray(priv.pendingBonuses)).toBe(true);
146
+ }
147
+
148
+ // ---------------------------------------------------------------------------
149
+ // Test Suites
150
+ // ---------------------------------------------------------------------------
151
+
152
+ describe('Test Protocol: 10,000-Spin Simulation -- Bonnys Fortune', () => {
153
+ beforeEach(() => {
154
+ resetCommandIdCounter();
155
+ });
156
+
157
+ // -----------------------------------------------------------------------
158
+ // Test 1: 10,000 Base Game Spins with Bonus Completion
159
+ // -----------------------------------------------------------------------
160
+ describe('Test 1: 10,000 Base Game Spins with Bonus Completion', () => {
161
+ it(
162
+ 'should complete 10,000 spins, handling any natural bonus triggers, writing NDJSON results',
163
+ async () => {
164
+ ensureResultsDir();
165
+ const ndjsonFile = ndjsonPath('test1-10000-base-spins.ndjson');
166
+ // Truncate any previous run
167
+ fs.writeFileSync(ndjsonFile, '', 'utf-8');
168
+
169
+ const { engine } = createEngineWithLcgRng(99887);
170
+ const session = await initSession(engine, 1.0);
171
+
172
+ let pub = session.publicState;
173
+ let priv = session.privateState;
174
+ const betAmount = 1.0;
175
+
176
+ let totalWagered = 0;
177
+ let totalWon = 0;
178
+ let spinCount = 0;
179
+ const bonusTriggersPerType: Record<string, number> = {};
180
+ const tracker = { bonusTriggersPerType, totalWon };
181
+
182
+ for (let i = 0; i < 10000; i++) {
183
+ // If a bonus is pending, drain it before spinning
184
+ if (
185
+ priv.nextSpinType &&
186
+ priv.nextSpinType !== 'BASE_GAME_SPIN' &&
187
+ priv.pendingBonuses?.length > 0
188
+ ) {
189
+ const drained = await drainAllBonuses(
190
+ engine,
191
+ pub,
192
+ priv,
193
+ betAmount,
194
+ tracker,
195
+ );
196
+ pub = drained.pub;
197
+ priv = drained.priv;
198
+ }
199
+
200
+ // Execute base game spin
201
+ const spinResult = await safeExecuteSpin(
202
+ engine,
203
+ pub,
204
+ priv,
205
+ betAmount,
206
+ );
207
+
208
+ // safeExecuteSpin returns null if bonus state prevents spin
209
+ if (!spinResult) {
210
+ // Force drain any leftover bonus
211
+ if (priv.pendingBonuses?.length > 0) {
212
+ const drained = await drainAllBonuses(
213
+ engine,
214
+ pub,
215
+ priv,
216
+ betAmount,
217
+ tracker,
218
+ );
219
+ pub = drained.pub;
220
+ priv = drained.priv;
221
+ }
222
+ // Retry the spin
223
+ const retry = await safeExecuteSpin(
224
+ engine,
225
+ pub,
226
+ priv,
227
+ betAmount,
228
+ );
229
+ if (!retry) {
230
+ // Skip this iteration if still stuck
231
+ continue;
232
+ }
233
+ spinCount++;
234
+ totalWagered += betAmount;
235
+
236
+ const win = extractPlayerWinning(retry);
237
+ totalWon += win;
238
+
239
+ pub = retry.publicState;
240
+ priv = retry.privateState;
241
+
242
+ // Write NDJSON record for retry
243
+ appendNdjson(ndjsonFile, {
244
+ spin: spinCount,
245
+ iteration: i,
246
+ wagered: betAmount,
247
+ win,
248
+ retried: true,
249
+ nextSpinType: priv.nextSpinType,
250
+ pendingBonuses: priv.pendingBonuses?.length ?? 0,
251
+ });
252
+ continue;
253
+ }
254
+
255
+ spinCount++;
256
+ totalWagered += betAmount;
257
+
258
+ const win = extractPlayerWinning(spinResult);
259
+ totalWon += win;
260
+
261
+ pub = spinResult.publicState;
262
+ priv = spinResult.privateState;
263
+
264
+ // Write NDJSON record
265
+ appendNdjson(ndjsonFile, {
266
+ spin: spinCount,
267
+ iteration: i,
268
+ wagered: betAmount,
269
+ win,
270
+ retried: false,
271
+ nextSpinType: priv.nextSpinType,
272
+ pendingBonuses: priv.pendingBonuses?.length ?? 0,
273
+ });
274
+
275
+ // If the spin triggered a bonus, drain it
276
+ if (priv.pendingBonuses?.length > 0) {
277
+ const drained = await drainAllBonuses(
278
+ engine,
279
+ pub,
280
+ priv,
281
+ betAmount,
282
+ tracker,
283
+ );
284
+ pub = drained.pub;
285
+ priv = drained.priv;
286
+ }
287
+
288
+ // Log progress every 1,000 spins
289
+ if (spinCount % 1000 === 0) {
290
+ const runningTotalWon = totalWon + tracker.totalWon;
291
+ console.log(
292
+ ` [Test 1] Progress: ${spinCount} spins | Wagered: ${totalWagered.toFixed(2)} | Won: ${runningTotalWon.toFixed(2)} | RTP: ${totalWagered > 0 ? ((runningTotalWon / totalWagered) * 100).toFixed(2) : 0}%`,
293
+ );
294
+ }
295
+ }
296
+
297
+ // Include bonus wins tracked separately
298
+ totalWon += tracker.totalWon;
299
+
300
+ console.log('=== Test 1: 10,000 Base Game Spins ===');
301
+ console.log(` Spins completed: ${spinCount}`);
302
+ console.log(` Total wagered: ${totalWagered.toFixed(2)}`);
303
+ console.log(` Total won: ${totalWon.toFixed(2)}`);
304
+ console.log(
305
+ ` RTP: ${totalWagered > 0 ? ((totalWon / totalWagered) * 100).toFixed(2) : 0}%`,
306
+ );
307
+ console.log(
308
+ ` Bonus triggers: ${JSON.stringify(bonusTriggersPerType)}`,
309
+ );
310
+ console.log(` NDJSON output: ${ndjsonFile}`);
311
+
312
+ // Assertions
313
+ expect(spinCount).toBeGreaterThanOrEqual(9500);
314
+ expect(totalWon).toBeGreaterThanOrEqual(0);
315
+ expect(totalWagered).toBeGreaterThan(0);
316
+ },
317
+ 600000,
318
+ );
319
+ });
320
+
321
+ // -----------------------------------------------------------------------
322
+ // Test 2: RTP Validation Over 10,000 Spins
323
+ // -----------------------------------------------------------------------
324
+ describe('Test 2: RTP Validation Over 10,000 Spins', () => {
325
+ it(
326
+ 'should produce RTP between 0.70 and 1.30 (70%-130%) -- tighter bounds for 10,000 spins',
327
+ async () => {
328
+ const { engine } = createEngineWithLcgRng(99887);
329
+ const session = await initSession(engine, 1.0);
330
+
331
+ let pub = session.publicState;
332
+ let priv = session.privateState;
333
+ const betAmount = 1.0;
334
+
335
+ let totalWagered = 0;
336
+ let totalWon = 0;
337
+ let paidSpins = 0;
338
+ const tracker = {
339
+ bonusTriggersPerType: {} as Record<string, number>,
340
+ totalWon: 0,
341
+ };
342
+
343
+ while (paidSpins < 10000) {
344
+ // Drain any pending bonuses
345
+ if (priv.pendingBonuses?.length > 0) {
346
+ const drained = await drainAllBonuses(
347
+ engine,
348
+ pub,
349
+ priv,
350
+ betAmount,
351
+ tracker,
352
+ );
353
+ pub = drained.pub;
354
+ priv = drained.priv;
355
+ }
356
+
357
+ // Ensure we're in BASE_GAME_SPIN
358
+ if (priv.nextSpinType !== 'BASE_GAME_SPIN') {
359
+ break;
360
+ }
361
+
362
+ const spinResult = await safeExecuteSpin(
363
+ engine,
364
+ pub,
365
+ priv,
366
+ betAmount,
367
+ );
368
+ if (!spinResult) break;
369
+
370
+ paidSpins++;
371
+ totalWagered += betAmount;
372
+
373
+ const win = extractPlayerWinning(spinResult);
374
+ totalWon += win;
375
+
376
+ pub = spinResult.publicState;
377
+ priv = spinResult.privateState;
378
+
379
+ // Drain bonuses triggered by spin
380
+ if (priv.pendingBonuses?.length > 0) {
381
+ const drained = await drainAllBonuses(
382
+ engine,
383
+ pub,
384
+ priv,
385
+ betAmount,
386
+ tracker,
387
+ );
388
+ pub = drained.pub;
389
+ priv = drained.priv;
390
+ }
391
+
392
+ // Log progress every 2,500 spins
393
+ if (paidSpins % 2500 === 0) {
394
+ const runningTotalWon = totalWon + tracker.totalWon;
395
+ console.log(
396
+ ` [Test 2] Progress: ${paidSpins} paid spins | RTP: ${totalWagered > 0 ? ((runningTotalWon / totalWagered) * 100).toFixed(2) : 0}%`,
397
+ );
398
+ }
399
+ }
400
+
401
+ // Combine base game wins with bonus wins
402
+ totalWon += tracker.totalWon;
403
+
404
+ const rtp =
405
+ totalWagered > 0 ? totalWon / totalWagered : 0;
406
+
407
+ console.log('=== Test 2: RTP Validation (10,000 Spins) ===');
408
+ console.log(` Paid spins: ${paidSpins}`);
409
+ console.log(` Total wagered: ${totalWagered.toFixed(2)}`);
410
+ console.log(` Total won: ${totalWon.toFixed(2)}`);
411
+ console.log(` RTP: ${(rtp * 100).toFixed(2)}%`);
412
+ console.log(
413
+ ` Bonus triggers: ${JSON.stringify(tracker.bonusTriggersPerType)}`,
414
+ );
415
+
416
+ expect(paidSpins).toBeGreaterThanOrEqual(9500);
417
+ // Tighter bounds for 10,000 spins: declared RTP ~96%, SD shrinks with sqrt(n)
418
+ expect(rtp).toBeGreaterThanOrEqual(0.70);
419
+ expect(rtp).toBeLessThanOrEqual(1.30);
420
+ },
421
+ 600000,
422
+ );
423
+ });
424
+
425
+ // -----------------------------------------------------------------------
426
+ // Test 3: Bonus Coverage -- Debug Trigger 200x Each Bonus Type
427
+ // -----------------------------------------------------------------------
428
+ describe('Test 3: Bonus Coverage -- 200x Each Bonus Type', () => {
429
+ const bonusTypes = [
430
+ 'bonusGame1',
431
+ 'bonusGame2',
432
+ 'bonusGame3',
433
+ 'collectFeature',
434
+ ];
435
+
436
+ for (const bonusType of bonusTypes) {
437
+ it(
438
+ `should trigger ${bonusType} 200 times without crashes`,
439
+ async () => {
440
+ let wins = 0;
441
+ let completions = 0;
442
+
443
+ for (let i = 0; i < 200; i++) {
444
+ resetCommandIdCounter();
445
+ const seed = 50000 + i * 41; // Different seed each iteration, unique from other tests
446
+ const { engine } = createEngineWithLcgRng(seed);
447
+ const session = await initSession(engine);
448
+
449
+ try {
450
+ const debugResult = await debugTriggerBonus(
451
+ engine,
452
+ session.publicState,
453
+ session.privateState,
454
+ bonusType,
455
+ );
456
+
457
+ expect(debugResult.success).toBe(true);
458
+
459
+ const bonus = debugResult.privateState.pendingBonuses[0];
460
+ const bonusResult = await startBonusRound(
461
+ engine,
462
+ debugResult.publicState,
463
+ debugResult.privateState,
464
+ bonus.bonusType,
465
+ );
466
+
467
+ expect(bonusResult.success).toBe(true);
468
+ completions++;
469
+
470
+ // Track total wins from bonus results
471
+ const stressOutcome = getOutcome(bonusResult);
472
+ if (stressOutcome.results) {
473
+ for (const r of stressOutcome.results) {
474
+ const w =
475
+ r.result?.playerWinning ?? 0;
476
+ wins += w;
477
+ }
478
+ }
479
+
480
+ // Drain chained bonuses (bonusGame3 can chain to bonusGame1)
481
+ const finalState = extractFinalBonusState(bonusResult);
482
+ let pub = finalState.publicState;
483
+ let priv = finalState.privateState;
484
+ let depth = 5;
485
+ while (priv.pendingBonuses?.length > 0 && depth-- > 0) {
486
+ const chainedBonus = priv.pendingBonuses[0];
487
+ const chainedResult = await startBonusRound(
488
+ engine,
489
+ pub,
490
+ priv,
491
+ chainedBonus.bonusType,
492
+ );
493
+ expect(chainedResult.success).toBe(true);
494
+ const chainFinal = extractFinalBonusState(chainedResult);
495
+ pub = chainFinal.publicState;
496
+ priv = chainFinal.privateState;
497
+ }
498
+ } catch (error: unknown) {
499
+ // Prevent cascade failures: log and continue to next iteration
500
+ console.warn(
501
+ `[Test 3] ${bonusType} iteration ${i} failed: ${error instanceof Error ? error.message : String(error)}`,
502
+ );
503
+ }
504
+ }
505
+
506
+ console.log(
507
+ `=== Test 3: Bonus Coverage: ${bonusType} x200 ===`,
508
+ );
509
+ console.log(` Completions: ${completions}/200`);
510
+ console.log(` Total bonus wins: ${wins.toFixed(2)}`);
511
+
512
+ expect(completions).toBe(200);
513
+ },
514
+ 600000,
515
+ );
516
+ }
517
+ });
518
+
519
+ // -----------------------------------------------------------------------
520
+ // Test 4: State Consistency Over 10,000 Spins
521
+ // -----------------------------------------------------------------------
522
+ describe('Test 4: State Consistency Over 10,000 Spins', () => {
523
+ it(
524
+ 'should maintain valid state after every spin and bonus round across 10,000 spins',
525
+ async () => {
526
+ const { engine } = createEngineWithLcgRng(99887);
527
+ const session = await initSession(engine, 1.0);
528
+
529
+ let pub = session.publicState;
530
+ let priv = session.privateState;
531
+ const betAmount = 1.0;
532
+
533
+ let stateValidationFailures = 0;
534
+ let spinsCompleted = 0;
535
+ let bonusRoundsValidated = 0;
536
+
537
+ // Check initial state
538
+ try {
539
+ assertStateConsistency(pub, priv);
540
+ } catch {
541
+ stateValidationFailures++;
542
+ }
543
+
544
+ for (let i = 0; i < 10000; i++) {
545
+ // Drain pending bonuses with consistency checks
546
+ if (priv.pendingBonuses?.length > 0) {
547
+ let depth = 10;
548
+ while (priv.pendingBonuses?.length > 0 && depth-- > 0) {
549
+ const bonus = priv.pendingBonuses[0];
550
+
551
+ try {
552
+ const bonusResult = await startBonusRound(
553
+ engine,
554
+ pub,
555
+ priv,
556
+ bonus.bonusType,
557
+ betAmount,
558
+ );
559
+
560
+ expect(bonusResult.success).toBe(true);
561
+
562
+ // Check bonus winnings are non-negative
563
+ const consistencyOutcome = getOutcome(bonusResult);
564
+ if (consistencyOutcome.results) {
565
+ for (const r of consistencyOutcome.results) {
566
+ const w = r.result?.playerWinning ?? 0;
567
+ if (w < 0) {
568
+ stateValidationFailures++;
569
+ }
570
+ }
571
+ }
572
+
573
+ const finalState = extractFinalBonusState(bonusResult);
574
+ pub = finalState.publicState;
575
+ priv = finalState.privateState;
576
+
577
+ // Assert state consistency after every bonus round
578
+ try {
579
+ assertStateConsistency(pub, priv);
580
+ } catch {
581
+ stateValidationFailures++;
582
+ }
583
+ bonusRoundsValidated++;
584
+ } catch (error: unknown) {
585
+ // Prevent cascade failures: log, break bonus drain
586
+ console.warn(
587
+ `[Test 4] Bonus drain error at spin ${i}: ${error instanceof Error ? error.message : String(error)}`,
588
+ );
589
+ break;
590
+ }
591
+ }
592
+ }
593
+
594
+ if (priv.nextSpinType !== 'BASE_GAME_SPIN') {
595
+ continue;
596
+ }
597
+
598
+ const spinResult = await safeExecuteSpin(
599
+ engine,
600
+ pub,
601
+ priv,
602
+ betAmount,
603
+ );
604
+ if (!spinResult) continue;
605
+
606
+ spinsCompleted++;
607
+
608
+ // Check spin winning is non-negative
609
+ const spinWin = extractPlayerWinning(spinResult);
610
+ if (spinWin < 0) {
611
+ stateValidationFailures++;
612
+ }
613
+
614
+ pub = spinResult.publicState;
615
+ priv = spinResult.privateState;
616
+
617
+ // Verify state consistency after every spin
618
+ try {
619
+ assertStateConsistency(pub, priv);
620
+ } catch {
621
+ stateValidationFailures++;
622
+ }
623
+
624
+ // Log progress every 2,000 spins
625
+ if (spinsCompleted % 2000 === 0) {
626
+ console.log(
627
+ ` [Test 4] Progress: ${spinsCompleted} spins validated | Bonus rounds: ${bonusRoundsValidated} | Failures: ${stateValidationFailures}`,
628
+ );
629
+ }
630
+ }
631
+
632
+ console.log('=== Test 4: State Consistency (10,000 Spins) ===');
633
+ console.log(` Spins completed: ${spinsCompleted}`);
634
+ console.log(` Bonus rounds validated: ${bonusRoundsValidated}`);
635
+ console.log(` State validation failures: ${stateValidationFailures}`);
636
+
637
+ // Assertions
638
+ expect(stateValidationFailures).toBe(0);
639
+ },
640
+ 600000,
641
+ );
642
+ });
643
+ });
@@ -32,21 +32,17 @@ import {
32
32
  } from '@omnitronix/game-engine-contract';
33
33
  import {
34
34
  SlotGameHandler,
35
- } from '@omnitronix/game-engine-sdk/dist/handlers';
35
+ } from '@omnitronix/game-engine-sdk';
36
36
  import type {
37
37
  BetConfig as SdkBetConfig,
38
38
  SlotState as SdkSlotState,
39
39
  SpinResult as SdkSpinResult,
40
40
  BonusTrigger as SdkBonusTrigger,
41
41
  BonusResult as SdkBonusResult,
42
- } from '@omnitronix/game-engine-sdk/dist/handlers';
43
- import type {
44
42
  GameTypeConfig,
45
- } from '@omnitronix/game-engine-sdk/dist/game-type-config';
46
- import type {
47
43
  BonusResultDeliveryStrategy,
48
44
  BonusRoundResponse,
49
- } from '@omnitronix/game-engine-sdk/dist/core';
45
+ } from '@omnitronix/game-engine-sdk';
50
46
  import { getDebugCommandDefinitions } from './debug/debug-command-definitions';
51
47
  import { ReelStripsConfig } from './domain/reel-strips-config';
52
48
  import { ReelStripsConfigLoader } from './config/reel-strips-config/reel-strips-config-loader';
package/src/index.ts CHANGED
@@ -31,5 +31,4 @@ export {
31
31
  export { GameEngineConfig, GameEngineMetricsHandlers } from './game-engine.interface';
32
32
 
33
33
  // Re-export SDK types for consumers
34
- export type { GameTypeConfig } from '@omnitronix/game-engine-sdk/dist/game-type-config';
35
- export type { BonusResultDeliveryStrategy, BonusRoundResponse } from '@omnitronix/game-engine-sdk/dist/core';
34
+ export type { GameTypeConfig, BonusResultDeliveryStrategy, BonusRoundResponse } from '@omnitronix/game-engine-sdk';