@lagless/net-wire 0.0.33
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/README.md +684 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/clock-sync.d.ts +45 -0
- package/dist/lib/clock-sync.d.ts.map +1 -0
- package/dist/lib/clock-sync.js +163 -0
- package/dist/lib/clock-sync.js.map +1 -0
- package/dist/lib/input-delay-controller.d.ts +12 -0
- package/dist/lib/input-delay-controller.d.ts.map +1 -0
- package/dist/lib/input-delay-controller.js +29 -0
- package/dist/lib/input-delay-controller.js.map +1 -0
- package/dist/lib/protocol.d.ts +148 -0
- package/dist/lib/protocol.d.ts.map +1 -0
- package/dist/lib/protocol.js +395 -0
- package/dist/lib/protocol.js.map +1 -0
- package/dist/lib/tick-input-buffer.d.ts +30 -0
- package/dist/lib/tick-input-buffer.d.ts.map +1 -0
- package/dist/lib/tick-input-buffer.js +83 -0
- package/dist/lib/tick-input-buffer.js.map +1 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { InferBinarySchemaValues } from '@lagless/binary';
|
|
2
|
+
import { PongSchema } from './protocol.js';
|
|
3
|
+
/**
|
|
4
|
+
* Maintains network timing statistics with warmup phase.
|
|
5
|
+
*
|
|
6
|
+
* During warmup: collects samples and uses median for initial estimate.
|
|
7
|
+
* After warmup: uses EWMA for smooth tracking.
|
|
8
|
+
*/
|
|
9
|
+
export declare class ClockSync {
|
|
10
|
+
private _rttEwmaMs;
|
|
11
|
+
private _jitterEwmaMs;
|
|
12
|
+
private _serverTimeOffsetMs;
|
|
13
|
+
private _sampleCount;
|
|
14
|
+
private _isReady;
|
|
15
|
+
private readonly _warmupSamples;
|
|
16
|
+
private readonly _warmupSampleCount;
|
|
17
|
+
constructor(warmupSampleCount?: number);
|
|
18
|
+
get rttEwmaMs(): number;
|
|
19
|
+
get jitterEwmaMs(): number;
|
|
20
|
+
get serverTimeOffsetMs(): number;
|
|
21
|
+
get sampleCount(): number;
|
|
22
|
+
/**
|
|
23
|
+
* Returns true when ClockSync has enough data for reliable estimates.
|
|
24
|
+
* Until ready, consumers should NOT use timing data for game-critical decisions.
|
|
25
|
+
*/
|
|
26
|
+
get isReady(): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Updates timing statistics from a pong response.
|
|
29
|
+
* Returns true if this sample caused the ClockSync to become ready.
|
|
30
|
+
*/
|
|
31
|
+
updateFromPong(clientReceiveMs: number, pong: InferBinarySchemaValues<typeof PongSchema>): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Converts local client time to estimated server time.
|
|
34
|
+
*/
|
|
35
|
+
serverNowMs(clientNowMs: number): number;
|
|
36
|
+
/**
|
|
37
|
+
* Converts server time to estimated client time.
|
|
38
|
+
*/
|
|
39
|
+
clientNowMs(serverNowMs: number): number;
|
|
40
|
+
reset(): void;
|
|
41
|
+
private processWarmupSample;
|
|
42
|
+
private finalizeWarmup;
|
|
43
|
+
private updateEWMA;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=clock-sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clock-sync.d.ts","sourceRoot":"","sources":["../../src/lib/clock-sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AA0B3C;;;;;GAKG;AACH,qBAAa,SAAS;IAKpB,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,QAAQ,CAAS;IAGzB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAoB;IACnD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;gBAMzB,iBAAiB,GAAE,MAA4B;IAQlE,IAAW,SAAS,IAAI,MAAM,CAE7B;IAED,IAAW,YAAY,IAAI,MAAM,CAEhC;IAED,IAAW,kBAAkB,IAAI,MAAM,CAEtC;IAED,IAAW,WAAW,IAAI,MAAM,CAE/B;IAED;;;OAGG;IACH,IAAW,OAAO,IAAI,OAAO,CAE5B;IAMD;;;OAGG;IACI,cAAc,CACnB,eAAe,EAAE,MAAM,EACvB,IAAI,EAAE,uBAAuB,CAAC,OAAO,UAAU,CAAC,GAC/C,OAAO;IA4BV;;OAEG;IACI,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAI/C;;OAEG;IACI,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAIxC,KAAK,IAAI,IAAI;IAapB,OAAO,CAAC,mBAAmB;IAY3B,OAAO,CAAC,cAAc;IAyBtB,OAAO,CAAC,UAAU;CAenB"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { createLogger } from '@lagless/misc';
|
|
2
|
+
const log = createLogger('ClockSync');
|
|
3
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
4
|
+
// Constants
|
|
5
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
6
|
+
const EWMA_ALPHA = 0.15;
|
|
7
|
+
const WARMUP_SAMPLE_COUNT = 5;
|
|
8
|
+
const INITIAL_RTT_MS = 100;
|
|
9
|
+
const INITIAL_JITTER_MS = 20;
|
|
10
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
11
|
+
// ClockSync
|
|
12
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
13
|
+
/**
|
|
14
|
+
* Maintains network timing statistics with warmup phase.
|
|
15
|
+
*
|
|
16
|
+
* During warmup: collects samples and uses median for initial estimate.
|
|
17
|
+
* After warmup: uses EWMA for smooth tracking.
|
|
18
|
+
*/ export class ClockSync {
|
|
19
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
20
|
+
// Public getters
|
|
21
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
22
|
+
get rttEwmaMs() {
|
|
23
|
+
return this._rttEwmaMs;
|
|
24
|
+
}
|
|
25
|
+
get jitterEwmaMs() {
|
|
26
|
+
return this._jitterEwmaMs;
|
|
27
|
+
}
|
|
28
|
+
get serverTimeOffsetMs() {
|
|
29
|
+
return this._serverTimeOffsetMs;
|
|
30
|
+
}
|
|
31
|
+
get sampleCount() {
|
|
32
|
+
return this._sampleCount;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Returns true when ClockSync has enough data for reliable estimates.
|
|
36
|
+
* Until ready, consumers should NOT use timing data for game-critical decisions.
|
|
37
|
+
*/ get isReady() {
|
|
38
|
+
return this._isReady;
|
|
39
|
+
}
|
|
40
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
41
|
+
// Public methods
|
|
42
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
43
|
+
/**
|
|
44
|
+
* Updates timing statistics from a pong response.
|
|
45
|
+
* Returns true if this sample caused the ClockSync to become ready.
|
|
46
|
+
*/ updateFromPong(clientReceiveMs, pong) {
|
|
47
|
+
const rtt = clientReceiveMs - pong.cSend;
|
|
48
|
+
// Sanity check: reject negative or impossibly large RTT
|
|
49
|
+
if (rtt < 0 || rtt > 10000) {
|
|
50
|
+
log.warn(`Invalid RTT ${rtt}ms, skipping sample`);
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
// Calculate server time offset for this sample
|
|
54
|
+
// offset = serverTime - clientTime
|
|
55
|
+
// At the moment client sent ping, server received it ~RTT/2 later
|
|
56
|
+
const oneWayDelay = rtt / 2;
|
|
57
|
+
const serverTimeOffset = pong.sRecv - (pong.cSend + oneWayDelay);
|
|
58
|
+
const sample = {
|
|
59
|
+
rtt,
|
|
60
|
+
serverTimeOffset
|
|
61
|
+
};
|
|
62
|
+
this._sampleCount++;
|
|
63
|
+
// During warmup: collect samples
|
|
64
|
+
if (!this._isReady) {
|
|
65
|
+
return this.processWarmupSample(sample);
|
|
66
|
+
}
|
|
67
|
+
// After warmup: use EWMA
|
|
68
|
+
this.updateEWMA(sample);
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Converts local client time to estimated server time.
|
|
73
|
+
*/ serverNowMs(clientNowMs) {
|
|
74
|
+
return clientNowMs + this._serverTimeOffsetMs;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Converts server time to estimated client time.
|
|
78
|
+
*/ clientNowMs(serverNowMs) {
|
|
79
|
+
return serverNowMs - this._serverTimeOffsetMs;
|
|
80
|
+
}
|
|
81
|
+
reset() {
|
|
82
|
+
this._rttEwmaMs = INITIAL_RTT_MS;
|
|
83
|
+
this._jitterEwmaMs = INITIAL_JITTER_MS;
|
|
84
|
+
this._serverTimeOffsetMs = 0;
|
|
85
|
+
this._sampleCount = 0;
|
|
86
|
+
this._isReady = false;
|
|
87
|
+
this._warmupSamples.length = 0;
|
|
88
|
+
}
|
|
89
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
90
|
+
// Private: Warmup processing
|
|
91
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
92
|
+
processWarmupSample(sample) {
|
|
93
|
+
this._warmupSamples.push(sample);
|
|
94
|
+
if (this._warmupSamples.length < this._warmupSampleCount) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
// Warmup complete: calculate initial estimates using median
|
|
98
|
+
this.finalizeWarmup();
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
finalizeWarmup() {
|
|
102
|
+
const rtts = this._warmupSamples.map((s)=>s.rtt);
|
|
103
|
+
const offsets = this._warmupSamples.map((s)=>s.serverTimeOffset);
|
|
104
|
+
// Use median for robustness against outliers
|
|
105
|
+
this._rttEwmaMs = median(rtts);
|
|
106
|
+
this._serverTimeOffsetMs = median(offsets);
|
|
107
|
+
// Initial jitter estimate from sample variance
|
|
108
|
+
this._jitterEwmaMs = calculateMAD(rtts);
|
|
109
|
+
this._isReady = true;
|
|
110
|
+
this._warmupSamples.length = 0; // Free memory
|
|
111
|
+
log.info(`Ready: RTT=${this._rttEwmaMs.toFixed(1)}ms, ` + `offset=${this._serverTimeOffsetMs.toFixed(1)}ms, ` + `jitter=${this._jitterEwmaMs.toFixed(1)}ms`);
|
|
112
|
+
}
|
|
113
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
114
|
+
// Private: EWMA updates (post-warmup)
|
|
115
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
116
|
+
updateEWMA(sample) {
|
|
117
|
+
const prevRtt = this._rttEwmaMs;
|
|
118
|
+
// EWMA for RTT
|
|
119
|
+
this._rttEwmaMs = EWMA_ALPHA * sample.rtt + (1 - EWMA_ALPHA) * this._rttEwmaMs;
|
|
120
|
+
// EWMA for jitter (deviation from previous RTT)
|
|
121
|
+
const jitterSample = Math.abs(sample.rtt - prevRtt);
|
|
122
|
+
this._jitterEwmaMs = EWMA_ALPHA * jitterSample + (1 - EWMA_ALPHA) * this._jitterEwmaMs;
|
|
123
|
+
// EWMA for server time offset
|
|
124
|
+
this._serverTimeOffsetMs = EWMA_ALPHA * sample.serverTimeOffset + (1 - EWMA_ALPHA) * this._serverTimeOffsetMs;
|
|
125
|
+
}
|
|
126
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
127
|
+
// Constructor
|
|
128
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
129
|
+
constructor(warmupSampleCount = WARMUP_SAMPLE_COUNT){
|
|
130
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
131
|
+
// Private state
|
|
132
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
133
|
+
this._rttEwmaMs = INITIAL_RTT_MS;
|
|
134
|
+
this._jitterEwmaMs = INITIAL_JITTER_MS;
|
|
135
|
+
this._serverTimeOffsetMs = 0;
|
|
136
|
+
this._sampleCount = 0;
|
|
137
|
+
this._isReady = false;
|
|
138
|
+
// Warmup sample buffer
|
|
139
|
+
this._warmupSamples = [];
|
|
140
|
+
this._warmupSampleCount = warmupSampleCount;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
144
|
+
// Utility functions
|
|
145
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
146
|
+
function median(values) {
|
|
147
|
+
if (values.length === 0) return 0;
|
|
148
|
+
const sorted = [
|
|
149
|
+
...values
|
|
150
|
+
].sort((a, b)=>a - b);
|
|
151
|
+
const mid = Math.floor(sorted.length / 2);
|
|
152
|
+
return sorted.length % 2 !== 0 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Median Absolute Deviation - robust measure of variability
|
|
156
|
+
*/ function calculateMAD(values) {
|
|
157
|
+
if (values.length < 2) return 0;
|
|
158
|
+
const med = median(values);
|
|
159
|
+
const deviations = values.map((v)=>Math.abs(v - med));
|
|
160
|
+
return median(deviations);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
//# sourceMappingURL=clock-sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/clock-sync.ts"],"sourcesContent":["import { InferBinarySchemaValues } from '@lagless/binary';\nimport { createLogger } from '@lagless/misc';\nimport { PongSchema } from './protocol.js';\n\nconst log = createLogger('ClockSync');\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Constants\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst EWMA_ALPHA = 0.15;\nconst WARMUP_SAMPLE_COUNT = 5;\nconst INITIAL_RTT_MS = 100;\nconst INITIAL_JITTER_MS = 20;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface PongSample {\n readonly rtt: number;\n readonly serverTimeOffset: number;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ClockSync\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Maintains network timing statistics with warmup phase.\n *\n * During warmup: collects samples and uses median for initial estimate.\n * After warmup: uses EWMA for smooth tracking.\n */\nexport class ClockSync {\n // ─────────────────────────────────────────────────────────────────────────\n // Private state\n // ─────────────────────────────────────────────────────────────────────────\n\n private _rttEwmaMs: number = INITIAL_RTT_MS;\n private _jitterEwmaMs: number = INITIAL_JITTER_MS;\n private _serverTimeOffsetMs = 0;\n private _sampleCount = 0;\n private _isReady = false;\n\n // Warmup sample buffer\n private readonly _warmupSamples: PongSample[] = [];\n private readonly _warmupSampleCount: number;\n\n // ─────────────────────────────────────────────────────────────────────────\n // Constructor\n // ─────────────────────────────────────────────────────────────────────────\n\n public constructor(warmupSampleCount: number = WARMUP_SAMPLE_COUNT) {\n this._warmupSampleCount = warmupSampleCount;\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Public getters\n // ─────────────────────────────────────────────────────────────────────────\n\n public get rttEwmaMs(): number {\n return this._rttEwmaMs;\n }\n\n public get jitterEwmaMs(): number {\n return this._jitterEwmaMs;\n }\n\n public get serverTimeOffsetMs(): number {\n return this._serverTimeOffsetMs;\n }\n\n public get sampleCount(): number {\n return this._sampleCount;\n }\n\n /**\n * Returns true when ClockSync has enough data for reliable estimates.\n * Until ready, consumers should NOT use timing data for game-critical decisions.\n */\n public get isReady(): boolean {\n return this._isReady;\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Public methods\n // ─────────────────────────────────────────────────────────────────────────\n\n /**\n * Updates timing statistics from a pong response.\n * Returns true if this sample caused the ClockSync to become ready.\n */\n public updateFromPong(\n clientReceiveMs: number,\n pong: InferBinarySchemaValues<typeof PongSchema>,\n ): boolean {\n const rtt = clientReceiveMs - pong.cSend;\n\n // Sanity check: reject negative or impossibly large RTT\n if (rtt < 0 || rtt > 10000) {\n log.warn(`Invalid RTT ${rtt}ms, skipping sample`);\n return false;\n }\n\n // Calculate server time offset for this sample\n // offset = serverTime - clientTime\n // At the moment client sent ping, server received it ~RTT/2 later\n const oneWayDelay = rtt / 2;\n const serverTimeOffset = pong.sRecv - (pong.cSend + oneWayDelay);\n\n const sample: PongSample = { rtt, serverTimeOffset };\n this._sampleCount++;\n\n // During warmup: collect samples\n if (!this._isReady) {\n return this.processWarmupSample(sample);\n }\n\n // After warmup: use EWMA\n this.updateEWMA(sample);\n return false;\n }\n\n /**\n * Converts local client time to estimated server time.\n */\n public serverNowMs(clientNowMs: number): number {\n return clientNowMs + this._serverTimeOffsetMs;\n }\n\n /**\n * Converts server time to estimated client time.\n */\n public clientNowMs(serverNowMs: number): number {\n return serverNowMs - this._serverTimeOffsetMs;\n }\n\n public reset(): void {\n this._rttEwmaMs = INITIAL_RTT_MS;\n this._jitterEwmaMs = INITIAL_JITTER_MS;\n this._serverTimeOffsetMs = 0;\n this._sampleCount = 0;\n this._isReady = false;\n this._warmupSamples.length = 0;\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Private: Warmup processing\n // ─────────────────────────────────────────────────────────────────────────\n\n private processWarmupSample(sample: PongSample): boolean {\n this._warmupSamples.push(sample);\n\n if (this._warmupSamples.length < this._warmupSampleCount) {\n return false;\n }\n\n // Warmup complete: calculate initial estimates using median\n this.finalizeWarmup();\n return true;\n }\n\n private finalizeWarmup(): void {\n const rtts = this._warmupSamples.map(s => s.rtt);\n const offsets = this._warmupSamples.map(s => s.serverTimeOffset);\n\n // Use median for robustness against outliers\n this._rttEwmaMs = median(rtts);\n this._serverTimeOffsetMs = median(offsets);\n\n // Initial jitter estimate from sample variance\n this._jitterEwmaMs = calculateMAD(rtts);\n\n this._isReady = true;\n this._warmupSamples.length = 0; // Free memory\n\n log.info(\n `Ready: RTT=${this._rttEwmaMs.toFixed(1)}ms, ` +\n `offset=${this._serverTimeOffsetMs.toFixed(1)}ms, ` +\n `jitter=${this._jitterEwmaMs.toFixed(1)}ms`\n );\n }\n\n // ─────────────────────────────────────────────────────────────────────────\n // Private: EWMA updates (post-warmup)\n // ─────────────────────────────────────────────────────────────────────────\n\n private updateEWMA(sample: PongSample): void {\n const prevRtt = this._rttEwmaMs;\n\n // EWMA for RTT\n this._rttEwmaMs = EWMA_ALPHA * sample.rtt + (1 - EWMA_ALPHA) * this._rttEwmaMs;\n\n // EWMA for jitter (deviation from previous RTT)\n const jitterSample = Math.abs(sample.rtt - prevRtt);\n this._jitterEwmaMs = EWMA_ALPHA * jitterSample + (1 - EWMA_ALPHA) * this._jitterEwmaMs;\n\n // EWMA for server time offset\n this._serverTimeOffsetMs =\n EWMA_ALPHA * sample.serverTimeOffset +\n (1 - EWMA_ALPHA) * this._serverTimeOffsetMs;\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Utility functions\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction median(values: number[]): number {\n if (values.length === 0) return 0;\n\n const sorted = [...values].sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n\n return sorted.length % 2 !== 0\n ? sorted[mid]\n : (sorted[mid - 1] + sorted[mid]) / 2;\n}\n\n/**\n * Median Absolute Deviation - robust measure of variability\n */\nfunction calculateMAD(values: number[]): number {\n if (values.length < 2) return 0;\n\n const med = median(values);\n const deviations = values.map(v => Math.abs(v - med));\n\n return median(deviations);\n}\n"],"names":["createLogger","log","EWMA_ALPHA","WARMUP_SAMPLE_COUNT","INITIAL_RTT_MS","INITIAL_JITTER_MS","ClockSync","rttEwmaMs","_rttEwmaMs","jitterEwmaMs","_jitterEwmaMs","serverTimeOffsetMs","_serverTimeOffsetMs","sampleCount","_sampleCount","isReady","_isReady","updateFromPong","clientReceiveMs","pong","rtt","cSend","warn","oneWayDelay","serverTimeOffset","sRecv","sample","processWarmupSample","updateEWMA","serverNowMs","clientNowMs","reset","_warmupSamples","length","push","_warmupSampleCount","finalizeWarmup","rtts","map","s","offsets","median","calculateMAD","info","toFixed","prevRtt","jitterSample","Math","abs","warmupSampleCount","values","sorted","sort","a","b","mid","floor","med","deviations","v"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class InputDelayController {
|
|
2
|
+
private readonly _minTicks;
|
|
3
|
+
private readonly _maxTicks;
|
|
4
|
+
private _deltaTicks;
|
|
5
|
+
constructor(_minTicks?: number, _maxTicks?: number, initial?: number);
|
|
6
|
+
get deltaTicks(): number;
|
|
7
|
+
/**
|
|
8
|
+
* Δ = ceil( (RTT_EWMA/2 + k*JITTER_EWMA + SAFETY_ms) / TICK_ms )
|
|
9
|
+
*/
|
|
10
|
+
recompute(tickMs: number, rttEwmaMs: number, jitterEwmaMs: number, k?: number, safetyMs?: number): number;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=input-delay-controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-delay-controller.d.ts","sourceRoot":"","sources":["../../src/lib/input-delay-controller.ts"],"names":[],"mappings":"AAIA,qBAAa,oBAAoB;IAI7B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAJ5B,OAAO,CAAC,WAAW,CAAS;gBAGT,SAAS,SAAI,EACb,SAAS,SAAI,EAC9B,OAAO,SAAI;IAKb,IAAW,UAAU,WAEpB;IAED;;OAEG;IACI,SAAS,CACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,CAAC,SAAM,EACP,QAAQ,SAAK,GACZ,MAAM;CAqBV"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { createLogger } from '@lagless/misc';
|
|
2
|
+
const log = createLogger('InputDelayController');
|
|
3
|
+
export class InputDelayController {
|
|
4
|
+
get deltaTicks() {
|
|
5
|
+
return this._deltaTicks;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Δ = ceil( (RTT_EWMA/2 + k*JITTER_EWMA + SAFETY_ms) / TICK_ms )
|
|
9
|
+
*/ recompute(tickMs, rttEwmaMs, jitterEwmaMs, k = 1.8, safetyMs = 10) {
|
|
10
|
+
const prevDelta = this._deltaTicks;
|
|
11
|
+
const needMs = rttEwmaMs * 0.5 + k * jitterEwmaMs + safetyMs;
|
|
12
|
+
const want = Math.ceil(needMs / tickMs);
|
|
13
|
+
// Hysteresis: up - fast, down - slow (minus 1 per step)
|
|
14
|
+
if (want > this._deltaTicks) this._deltaTicks = want;
|
|
15
|
+
else if (want < this._deltaTicks) this._deltaTicks = Math.max(want, this._deltaTicks - 1);
|
|
16
|
+
this._deltaTicks = Math.max(this._minTicks, Math.min(this._deltaTicks, this._maxTicks));
|
|
17
|
+
if (this._deltaTicks !== prevDelta) {
|
|
18
|
+
log.info(`Recomputed deltaTicks: ${prevDelta} -> ${this._deltaTicks} ` + `(want: ${want}, needMs: ${needMs.toFixed(2)}ms, ` + `RTT: ${rttEwmaMs.toFixed(2)}ms, JITTER: ${jitterEwmaMs.toFixed(2)}ms)`);
|
|
19
|
+
}
|
|
20
|
+
return this._deltaTicks;
|
|
21
|
+
}
|
|
22
|
+
constructor(_minTicks = 1, _maxTicks = 8, initial = 2){
|
|
23
|
+
this._minTicks = _minTicks;
|
|
24
|
+
this._maxTicks = _maxTicks;
|
|
25
|
+
this._deltaTicks = Math.max(this._minTicks, Math.min(initial, this._maxTicks));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
//# sourceMappingURL=input-delay-controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/input-delay-controller.ts"],"sourcesContent":["import { createLogger } from '@lagless/misc';\n\nconst log = createLogger('InputDelayController');\n\nexport class InputDelayController {\n private _deltaTicks: number;\n\n public constructor(\n private readonly _minTicks = 1,\n private readonly _maxTicks = 8,\n initial = 2,\n ) {\n this._deltaTicks = Math.max(this._minTicks, Math.min(initial, this._maxTicks));\n }\n\n public get deltaTicks() {\n return this._deltaTicks;\n }\n\n /**\n * Δ = ceil( (RTT_EWMA/2 + k*JITTER_EWMA + SAFETY_ms) / TICK_ms )\n */\n public recompute(\n tickMs: number,\n rttEwmaMs: number,\n jitterEwmaMs: number,\n k = 1.8,\n safetyMs = 10,\n ): number {\n const prevDelta = this._deltaTicks;\n const needMs = rttEwmaMs * 0.5 + k * jitterEwmaMs + safetyMs;\n const want = Math.ceil(needMs / tickMs);\n\n // Hysteresis: up - fast, down - slow (minus 1 per step)\n if (want > this._deltaTicks) this._deltaTicks = want;\n else if (want < this._deltaTicks) this._deltaTicks = Math.max(want, this._deltaTicks - 1);\n\n this._deltaTicks = Math.max(this._minTicks, Math.min(this._deltaTicks, this._maxTicks));\n\n if (this._deltaTicks !== prevDelta) {\n log.info(\n `Recomputed deltaTicks: ${prevDelta} -> ${this._deltaTicks} ` +\n `(want: ${want}, needMs: ${needMs.toFixed(2)}ms, ` +\n `RTT: ${rttEwmaMs.toFixed(2)}ms, JITTER: ${jitterEwmaMs.toFixed(2)}ms)`\n );\n }\n\n return this._deltaTicks;\n }\n}\n"],"names":["createLogger","log","InputDelayController","deltaTicks","_deltaTicks","recompute","tickMs","rttEwmaMs","jitterEwmaMs","k","safetyMs","prevDelta","needMs","want","Math","ceil","max","_minTicks","min","_maxTicks","info","toFixed","initial"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,YAAY,QAAQ,gBAAgB;AAE7C,MAAMC,MAAMD,aAAa;AAEzB,OAAO,MAAME;IAWX,IAAWC,aAAa;QACtB,OAAO,IAAI,CAACC,WAAW;IACzB;IAEA;;GAEC,GACD,AAAOC,UACLC,MAAc,EACdC,SAAiB,EACjBC,YAAoB,EACpBC,IAAI,GAAG,EACPC,WAAW,EAAE,EACL;QACR,MAAMC,YAAY,IAAI,CAACP,WAAW;QAClC,MAAMQ,SAASL,YAAY,MAAME,IAAID,eAAeE;QACpD,MAAMG,OAAOC,KAAKC,IAAI,CAACH,SAASN;QAEhC,wDAAwD;QACxD,IAAIO,OAAO,IAAI,CAACT,WAAW,EAAE,IAAI,CAACA,WAAW,GAAGS;aAC3C,IAAIA,OAAO,IAAI,CAACT,WAAW,EAAE,IAAI,CAACA,WAAW,GAAGU,KAAKE,GAAG,CAACH,MAAM,IAAI,CAACT,WAAW,GAAG;QAEvF,IAAI,CAACA,WAAW,GAAGU,KAAKE,GAAG,CAAC,IAAI,CAACC,SAAS,EAAEH,KAAKI,GAAG,CAAC,IAAI,CAACd,WAAW,EAAE,IAAI,CAACe,SAAS;QAErF,IAAI,IAAI,CAACf,WAAW,KAAKO,WAAW;YAClCV,IAAImB,IAAI,CACN,CAAC,uBAAuB,EAAET,UAAU,IAAI,EAAE,IAAI,CAACP,WAAW,CAAC,CAAC,CAAC,GAC7D,CAAC,OAAO,EAAES,KAAK,UAAU,EAAED,OAAOS,OAAO,CAAC,GAAG,IAAI,CAAC,GAClD,CAAC,KAAK,EAAEd,UAAUc,OAAO,CAAC,GAAG,YAAY,EAAEb,aAAaa,OAAO,CAAC,GAAG,GAAG,CAAC;QAE3E;QAEA,OAAO,IAAI,CAACjB,WAAW;IACzB;IAzCA,YACE,AAAiBa,YAAY,CAAC,EAC9B,AAAiBE,YAAY,CAAC,EAC9BG,UAAU,CAAC,CACX;aAHiBL,YAAAA;aACAE,YAAAA;QAGjB,IAAI,CAACf,WAAW,GAAGU,KAAKE,GAAG,CAAC,IAAI,CAACC,SAAS,EAAEH,KAAKI,GAAG,CAACI,SAAS,IAAI,CAACH,SAAS;IAC9E;AAoCF"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { BinarySchema, FieldType } from '@lagless/binary';
|
|
2
|
+
export declare const WIRE_VERSION = 1;
|
|
3
|
+
export declare const enum MsgType {
|
|
4
|
+
ServerHello = 0,
|
|
5
|
+
TickInput = 1,
|
|
6
|
+
TickInputFanout = 2,
|
|
7
|
+
CancelInput = 3,
|
|
8
|
+
Ping = 4,
|
|
9
|
+
Pong = 5,
|
|
10
|
+
StateRequest = 6,
|
|
11
|
+
StateResponse = 7,
|
|
12
|
+
PlayerFinished = 8,
|
|
13
|
+
TickInputBatch = 9
|
|
14
|
+
}
|
|
15
|
+
export declare const enum TickInputKind {
|
|
16
|
+
Client = 0,
|
|
17
|
+
Server = 1
|
|
18
|
+
}
|
|
19
|
+
export declare const enum CancelReason {
|
|
20
|
+
TooOld = 0,
|
|
21
|
+
TooFarFuture = 1,
|
|
22
|
+
InvalidSlot = 2
|
|
23
|
+
}
|
|
24
|
+
export declare const HeaderSchema: BinarySchema<{
|
|
25
|
+
version: FieldType.Uint8;
|
|
26
|
+
type: FieldType.Uint8;
|
|
27
|
+
}>;
|
|
28
|
+
export declare const ServerHelloSchema: BinarySchema<{
|
|
29
|
+
playerSlot: FieldType.Uint8;
|
|
30
|
+
serverTick: FieldType.Uint32;
|
|
31
|
+
maxPlayers: FieldType.Uint8;
|
|
32
|
+
playerCount: FieldType.Uint8;
|
|
33
|
+
}>;
|
|
34
|
+
export declare const TickInputSchema: BinarySchema<{
|
|
35
|
+
tick: FieldType.Uint32;
|
|
36
|
+
playerSlot: FieldType.Uint8;
|
|
37
|
+
seq: FieldType.Uint32;
|
|
38
|
+
kind: FieldType.Uint8;
|
|
39
|
+
payloadLength: FieldType.Uint16;
|
|
40
|
+
}>;
|
|
41
|
+
export declare const TickInputFanoutSchema: BinarySchema<{
|
|
42
|
+
serverTick: FieldType.Uint32;
|
|
43
|
+
inputCount: FieldType.Uint8;
|
|
44
|
+
}>;
|
|
45
|
+
export declare const TickInputBatchSchema: BinarySchema<{
|
|
46
|
+
inputCount: FieldType.Uint8;
|
|
47
|
+
}>;
|
|
48
|
+
export declare const CancelInputSchema: BinarySchema<{
|
|
49
|
+
tick: FieldType.Uint32;
|
|
50
|
+
playerSlot: FieldType.Uint8;
|
|
51
|
+
seq: FieldType.Uint32;
|
|
52
|
+
reason: FieldType.Uint8;
|
|
53
|
+
}>;
|
|
54
|
+
export declare const PingSchema: BinarySchema<{
|
|
55
|
+
cSend: FieldType.Float64;
|
|
56
|
+
}>;
|
|
57
|
+
export declare const PongSchema: BinarySchema<{
|
|
58
|
+
cSend: FieldType.Float64;
|
|
59
|
+
sRecv: FieldType.Float64;
|
|
60
|
+
sSend: FieldType.Float64;
|
|
61
|
+
sTick: FieldType.Uint32;
|
|
62
|
+
}>;
|
|
63
|
+
export declare const StateRequestSchema: BinarySchema<{
|
|
64
|
+
requestId: FieldType.Uint32;
|
|
65
|
+
}>;
|
|
66
|
+
export declare const StateResponseHeaderSchema: BinarySchema<{
|
|
67
|
+
requestId: FieldType.Uint32;
|
|
68
|
+
tick: FieldType.Uint32;
|
|
69
|
+
hash: FieldType.Uint32;
|
|
70
|
+
stateLength: FieldType.Uint32;
|
|
71
|
+
}>;
|
|
72
|
+
export declare const PlayerFinishedSchema: BinarySchema<{
|
|
73
|
+
tick: FieldType.Uint32;
|
|
74
|
+
playerSlot: FieldType.Uint8;
|
|
75
|
+
payloadLength: FieldType.Uint16;
|
|
76
|
+
}>;
|
|
77
|
+
export interface ServerHelloPlayer {
|
|
78
|
+
readonly playerId: Uint8Array;
|
|
79
|
+
readonly slot: number;
|
|
80
|
+
readonly isBot: boolean;
|
|
81
|
+
readonly metadataJson: string;
|
|
82
|
+
}
|
|
83
|
+
export interface ServerHelloData {
|
|
84
|
+
readonly seed: Uint8Array;
|
|
85
|
+
readonly playerSlot: number;
|
|
86
|
+
readonly serverTick: number;
|
|
87
|
+
readonly maxPlayers: number;
|
|
88
|
+
readonly players: ReadonlyArray<ServerHelloPlayer>;
|
|
89
|
+
readonly scopeJson: string;
|
|
90
|
+
}
|
|
91
|
+
export interface TickInputData {
|
|
92
|
+
readonly tick: number;
|
|
93
|
+
readonly playerSlot: number;
|
|
94
|
+
readonly seq: number;
|
|
95
|
+
readonly kind: TickInputKind;
|
|
96
|
+
readonly payload: Uint8Array;
|
|
97
|
+
}
|
|
98
|
+
export interface FanoutData {
|
|
99
|
+
readonly serverTick: number;
|
|
100
|
+
readonly inputs: ReadonlyArray<TickInputData>;
|
|
101
|
+
}
|
|
102
|
+
export interface CancelInputData {
|
|
103
|
+
readonly tick: number;
|
|
104
|
+
readonly playerSlot: number;
|
|
105
|
+
readonly seq: number;
|
|
106
|
+
readonly reason: CancelReason;
|
|
107
|
+
}
|
|
108
|
+
export interface PongData {
|
|
109
|
+
readonly cSend: number;
|
|
110
|
+
readonly sRecv: number;
|
|
111
|
+
readonly sSend: number;
|
|
112
|
+
readonly sTick: number;
|
|
113
|
+
}
|
|
114
|
+
export interface StateResponseData {
|
|
115
|
+
readonly requestId: number;
|
|
116
|
+
readonly tick: number;
|
|
117
|
+
readonly hash: number;
|
|
118
|
+
readonly state: ArrayBuffer;
|
|
119
|
+
}
|
|
120
|
+
export interface PlayerFinishedData {
|
|
121
|
+
readonly tick: number;
|
|
122
|
+
readonly playerSlot: number;
|
|
123
|
+
readonly payload: Uint8Array;
|
|
124
|
+
}
|
|
125
|
+
export declare function packServerHello(data: ServerHelloData): Uint8Array;
|
|
126
|
+
export declare function packTickInput(data: TickInputData): Uint8Array;
|
|
127
|
+
export declare function packTickInputFanout(data: FanoutData): Uint8Array;
|
|
128
|
+
export declare function packTickInputBatch(inputs: ReadonlyArray<TickInputData>): Uint8Array;
|
|
129
|
+
export declare function packCancelInput(data: CancelInputData): Uint8Array;
|
|
130
|
+
export declare function packPing(cSend: number): Uint8Array;
|
|
131
|
+
export declare function packPong(data: PongData): Uint8Array;
|
|
132
|
+
export declare function packStateRequest(requestId: number): Uint8Array;
|
|
133
|
+
export declare function packStateResponse(data: StateResponseData): Uint8Array;
|
|
134
|
+
export declare function packPlayerFinished(data: PlayerFinishedData): Uint8Array;
|
|
135
|
+
export declare function unpackHeader(data: ArrayBuffer): {
|
|
136
|
+
version: number;
|
|
137
|
+
type: MsgType;
|
|
138
|
+
};
|
|
139
|
+
export declare function unpackServerHello(data: ArrayBuffer): ServerHelloData;
|
|
140
|
+
export declare function unpackTickInput(data: ArrayBuffer): TickInputData;
|
|
141
|
+
export declare function unpackCancelInput(data: ArrayBuffer): CancelInputData;
|
|
142
|
+
export declare function unpackPing(data: ArrayBuffer): number;
|
|
143
|
+
export declare function unpackPong(data: ArrayBuffer): PongData;
|
|
144
|
+
export declare function unpackStateRequest(data: ArrayBuffer): number;
|
|
145
|
+
export declare function unpackStateResponse(data: ArrayBuffer): StateResponseData;
|
|
146
|
+
export declare function unpackPlayerFinished(data: ArrayBuffer): PlayerFinishedData;
|
|
147
|
+
export declare function unpackTickInputFanout(data: ArrayBuffer): FanoutData;
|
|
148
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/lib/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAGZ,SAAS,EAEV,MAAM,iBAAiB,CAAC;AAMzB,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B,0BAAkB,OAAO;IACvB,WAAW,IAAS;IACpB,SAAS,IAAW;IACpB,eAAe,IAAK;IACpB,WAAW,IAAS;IACpB,IAAI,IAAgB;IACpB,IAAI,IAAgB;IACpB,YAAY,IAAQ;IACpB,aAAa,IAAO;IACpB,cAAc,IAAM;IACpB,cAAc,IAAM;CACrB;AAED,0BAAkB,aAAa;IAC7B,MAAM,IAAI;IACV,MAAM,IAAI;CACX;AAED,0BAAkB,YAAY;IAC5B,MAAM,IAAW;IACjB,YAAY,IAAK;IACjB,WAAW,IAAM;CAClB;AAMD,eAAO,MAAM,YAAY;;;EAGvB,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;EAK5B,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;;EAM1B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;EAGhC,CAAC;AAEH,eAAO,MAAM,oBAAoB;;EAE/B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;EAK5B,CAAC;AAEH,eAAO,MAAM,UAAU;;EAErB,CAAC;AAEH,eAAO,MAAM,UAAU;;;;;EAKrB,CAAC;AAEH,eAAO,MAAM,kBAAkB;;EAE7B,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;EAKpC,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;EAI/B,CAAC;AAMH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IACnD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;CAC/B;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;CAC7B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;CAC9B;AAUD,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,GAAG,UAAU,CAsCjE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,UAAU,CAY7D;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAoBhE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,CAAC,aAAa,CAAC,GAAG,UAAU,CAiBnF;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,GAAG,UAAU,CAUjE;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAKlD;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,CAKnD;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAK9D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,iBAAiB,GAAG,UAAU,CAWrE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,UAAU,CAUvE;AAMD,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAIlF;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,eAAe,CA0CpE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,aAAa,CAYhE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,eAAe,CAUpE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAKpD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,QAAQ,CAItD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAK5D;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,WAAW,GAAG,iBAAiB,CAYxE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,WAAW,GAAG,kBAAkB,CAW1E;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,WAAW,GAAG,UAAU,CAqBnE"}
|