callman-core 1.36.0 → 1.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +1 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/loadtest/compare.d.ts +32 -0
  6. package/dist/loadtest/compare.d.ts.map +1 -0
  7. package/dist/loadtest/compare.js +55 -0
  8. package/dist/loadtest/compare.js.map +1 -0
  9. package/dist/loadtest/flow-eval.d.ts +21 -0
  10. package/dist/loadtest/flow-eval.d.ts.map +1 -0
  11. package/dist/loadtest/flow-eval.js +199 -0
  12. package/dist/loadtest/flow-eval.js.map +1 -0
  13. package/dist/loadtest/from-collection.d.ts +51 -0
  14. package/dist/loadtest/from-collection.d.ts.map +1 -0
  15. package/dist/loadtest/from-collection.js +131 -0
  16. package/dist/loadtest/from-collection.js.map +1 -0
  17. package/dist/loadtest/histogram.d.ts +41 -0
  18. package/dist/loadtest/histogram.d.ts.map +1 -0
  19. package/dist/loadtest/histogram.js +166 -0
  20. package/dist/loadtest/histogram.js.map +1 -0
  21. package/dist/loadtest/index.d.ts +18 -0
  22. package/dist/loadtest/index.d.ts.map +1 -0
  23. package/dist/loadtest/index.js +14 -0
  24. package/dist/loadtest/index.js.map +1 -0
  25. package/dist/loadtest/node/index.d.ts +4 -0
  26. package/dist/loadtest/node/index.d.ts.map +1 -0
  27. package/dist/loadtest/node/index.js +4 -0
  28. package/dist/loadtest/node/index.js.map +1 -0
  29. package/dist/loadtest/node/metrics.d.ts +84 -0
  30. package/dist/loadtest/node/metrics.d.ts.map +1 -0
  31. package/dist/loadtest/node/metrics.js +396 -0
  32. package/dist/loadtest/node/metrics.js.map +1 -0
  33. package/dist/loadtest/node/orchestrator.d.ts +24 -0
  34. package/dist/loadtest/node/orchestrator.d.ts.map +1 -0
  35. package/dist/loadtest/node/orchestrator.js +363 -0
  36. package/dist/loadtest/node/orchestrator.js.map +1 -0
  37. package/dist/loadtest/node/protocol.d.ts +102 -0
  38. package/dist/loadtest/node/protocol.d.ts.map +1 -0
  39. package/dist/loadtest/node/protocol.js +17 -0
  40. package/dist/loadtest/node/protocol.js.map +1 -0
  41. package/dist/loadtest/node/setup.d.ts +6 -0
  42. package/dist/loadtest/node/setup.d.ts.map +1 -0
  43. package/dist/loadtest/node/setup.js +100 -0
  44. package/dist/loadtest/node/setup.js.map +1 -0
  45. package/dist/loadtest/node/step-compiler.d.ts +29 -0
  46. package/dist/loadtest/node/step-compiler.d.ts.map +1 -0
  47. package/dist/loadtest/node/step-compiler.js +229 -0
  48. package/dist/loadtest/node/step-compiler.js.map +1 -0
  49. package/dist/loadtest/node/transport.d.ts +66 -0
  50. package/dist/loadtest/node/transport.d.ts.map +1 -0
  51. package/dist/loadtest/node/transport.js +414 -0
  52. package/dist/loadtest/node/transport.js.map +1 -0
  53. package/dist/loadtest/node/worker-core.d.ts +77 -0
  54. package/dist/loadtest/node/worker-core.d.ts.map +1 -0
  55. package/dist/loadtest/node/worker-core.js +744 -0
  56. package/dist/loadtest/node/worker-core.js.map +1 -0
  57. package/dist/loadtest/node/worker.d.ts +2 -0
  58. package/dist/loadtest/node/worker.d.ts.map +1 -0
  59. package/dist/loadtest/node/worker.js +28 -0
  60. package/dist/loadtest/node/worker.js.map +1 -0
  61. package/dist/loadtest/plan-file.d.ts +91 -0
  62. package/dist/loadtest/plan-file.d.ts.map +1 -0
  63. package/dist/loadtest/plan-file.js +134 -0
  64. package/dist/loadtest/plan-file.js.map +1 -0
  65. package/dist/loadtest/plan.d.ts +47 -0
  66. package/dist/loadtest/plan.d.ts.map +1 -0
  67. package/dist/loadtest/plan.js +259 -0
  68. package/dist/loadtest/plan.js.map +1 -0
  69. package/dist/loadtest/report.d.ts +8 -0
  70. package/dist/loadtest/report.d.ts.map +1 -0
  71. package/dist/loadtest/report.js +211 -0
  72. package/dist/loadtest/report.js.map +1 -0
  73. package/dist/loadtest/thresholds.d.ts +55 -0
  74. package/dist/loadtest/thresholds.d.ts.map +1 -0
  75. package/dist/loadtest/thresholds.js +203 -0
  76. package/dist/loadtest/thresholds.js.map +1 -0
  77. package/dist/loadtest/types.d.ts +500 -0
  78. package/dist/loadtest/types.d.ts.map +1 -0
  79. package/dist/loadtest/types.js +8 -0
  80. package/dist/loadtest/types.js.map +1 -0
  81. package/dist/loadtest/validate.d.ts +30 -0
  82. package/dist/loadtest/validate.d.ts.map +1 -0
  83. package/dist/loadtest/validate.js +162 -0
  84. package/dist/loadtest/validate.js.map +1 -0
  85. package/dist/templating/compile.d.ts +8 -0
  86. package/dist/templating/compile.d.ts.map +1 -0
  87. package/dist/templating/compile.js +110 -0
  88. package/dist/templating/compile.js.map +1 -0
  89. package/dist/templating/index.d.ts +2 -0
  90. package/dist/templating/index.d.ts.map +1 -1
  91. package/dist/templating/index.js +1 -0
  92. package/dist/templating/index.js.map +1 -1
  93. package/dist/templating/template-engine.d.ts +6 -0
  94. package/dist/templating/template-engine.d.ts.map +1 -1
  95. package/dist/templating/template-engine.js +6 -6
  96. package/dist/templating/template-engine.js.map +1 -1
  97. package/dist-cjs/index.js +1 -0
  98. package/dist-cjs/index.js.map +1 -1
  99. package/dist-cjs/loadtest/compare.js +59 -0
  100. package/dist-cjs/loadtest/compare.js.map +1 -0
  101. package/dist-cjs/loadtest/flow-eval.js +205 -0
  102. package/dist-cjs/loadtest/flow-eval.js.map +1 -0
  103. package/dist-cjs/loadtest/from-collection.js +139 -0
  104. package/dist-cjs/loadtest/from-collection.js.map +1 -0
  105. package/dist-cjs/loadtest/histogram.js +171 -0
  106. package/dist-cjs/loadtest/histogram.js.map +1 -0
  107. package/dist-cjs/loadtest/index.js +78 -0
  108. package/dist-cjs/loadtest/index.js.map +1 -0
  109. package/dist-cjs/loadtest/node/index.js +12 -0
  110. package/dist-cjs/loadtest/node/index.js.map +1 -0
  111. package/dist-cjs/loadtest/node/metrics.js +402 -0
  112. package/dist-cjs/loadtest/node/metrics.js.map +1 -0
  113. package/dist-cjs/loadtest/node/orchestrator.js +372 -0
  114. package/dist-cjs/loadtest/node/orchestrator.js.map +1 -0
  115. package/dist-cjs/loadtest/node/protocol.js +20 -0
  116. package/dist-cjs/loadtest/node/protocol.js.map +1 -0
  117. package/dist-cjs/loadtest/node/setup.js +105 -0
  118. package/dist-cjs/loadtest/node/setup.js.map +1 -0
  119. package/dist-cjs/loadtest/node/step-compiler.js +234 -0
  120. package/dist-cjs/loadtest/node/step-compiler.js.map +1 -0
  121. package/dist-cjs/loadtest/node/transport.js +422 -0
  122. package/dist-cjs/loadtest/node/transport.js.map +1 -0
  123. package/dist-cjs/loadtest/node/worker-core.js +749 -0
  124. package/dist-cjs/loadtest/node/worker-core.js.map +1 -0
  125. package/dist-cjs/loadtest/node/worker.js +30 -0
  126. package/dist-cjs/loadtest/node/worker.js.map +1 -0
  127. package/dist-cjs/loadtest/plan-file.js +143 -0
  128. package/dist-cjs/loadtest/plan-file.js.map +1 -0
  129. package/dist-cjs/loadtest/plan.js +271 -0
  130. package/dist-cjs/loadtest/plan.js.map +1 -0
  131. package/dist-cjs/loadtest/report.js +220 -0
  132. package/dist-cjs/loadtest/report.js.map +1 -0
  133. package/dist-cjs/loadtest/thresholds.js +213 -0
  134. package/dist-cjs/loadtest/thresholds.js.map +1 -0
  135. package/dist-cjs/loadtest/types.js +9 -0
  136. package/dist-cjs/loadtest/types.js.map +1 -0
  137. package/dist-cjs/loadtest/validate.js +169 -0
  138. package/dist-cjs/loadtest/validate.js.map +1 -0
  139. package/dist-cjs/templating/compile.js +114 -0
  140. package/dist-cjs/templating/compile.js.map +1 -0
  141. package/dist-cjs/templating/index.js +3 -1
  142. package/dist-cjs/templating/index.js.map +1 -1
  143. package/dist-cjs/templating/template-engine.js +14 -12
  144. package/dist-cjs/templating/template-engine.js.map +1 -1
  145. package/package.json +10 -1
@@ -0,0 +1,259 @@
1
+ // Turns an executor into a time → load function. Pure and renderer-safe: the
2
+ // desktop's config preview, the estimate panel and the Node engine all call
3
+ // the same code, so what the user sees is what the generator does.
4
+ const lerp = (from, to, t) => from + (to - from) * Math.max(0, Math.min(1, t));
5
+ const stagesToSegments = (start, stages) => {
6
+ const segments = [];
7
+ let cursor = 0;
8
+ let previous = start;
9
+ for (const stage of stages) {
10
+ const duration = Math.max(0, stage.durationMs);
11
+ if (duration === 0) {
12
+ previous = stage.target;
13
+ continue;
14
+ }
15
+ segments.push({ startMs: cursor, endMs: cursor + duration, from: previous, to: stage.target });
16
+ cursor += duration;
17
+ previous = stage.target;
18
+ }
19
+ return segments;
20
+ };
21
+ export const buildLoadPlan = (executor) => {
22
+ switch (executor.type) {
23
+ case "constant-vus": {
24
+ const duration = Math.max(0, executor.durationMs);
25
+ return {
26
+ kind: "vus",
27
+ totalDurationMs: duration,
28
+ peakTarget: executor.vus,
29
+ timeUnitMs: 1000,
30
+ maxVus: executor.vus,
31
+ segments: [{ startMs: 0, endMs: duration, from: executor.vus, to: executor.vus }],
32
+ };
33
+ }
34
+ case "ramping-vus": {
35
+ const segments = stagesToSegments(executor.startVus, executor.stages);
36
+ const peak = Math.max(executor.startVus, ...executor.stages.map((s) => s.target), 0);
37
+ return {
38
+ kind: "vus",
39
+ totalDurationMs: segments.length ? segments[segments.length - 1].endMs : 0,
40
+ peakTarget: peak,
41
+ timeUnitMs: 1000,
42
+ maxVus: peak,
43
+ segments,
44
+ };
45
+ }
46
+ case "constant-arrival-rate": {
47
+ const duration = Math.max(0, executor.durationMs);
48
+ const unit = executor.timeUnitMs && executor.timeUnitMs > 0 ? executor.timeUnitMs : 1000;
49
+ return {
50
+ kind: "rate",
51
+ totalDurationMs: duration,
52
+ peakTarget: executor.rate,
53
+ timeUnitMs: unit,
54
+ maxVus: Math.max(1, executor.maxVus ?? Math.max(Math.ceil(executor.rate), 50)),
55
+ segments: [{ startMs: 0, endMs: duration, from: executor.rate, to: executor.rate }],
56
+ };
57
+ }
58
+ case "ramping-arrival-rate": {
59
+ const unit = executor.timeUnitMs && executor.timeUnitMs > 0 ? executor.timeUnitMs : 1000;
60
+ const segments = stagesToSegments(executor.startRate, executor.stages);
61
+ const peak = Math.max(executor.startRate, ...executor.stages.map((s) => s.target), 0);
62
+ return {
63
+ kind: "rate",
64
+ totalDurationMs: segments.length ? segments[segments.length - 1].endMs : 0,
65
+ peakTarget: peak,
66
+ timeUnitMs: unit,
67
+ maxVus: Math.max(1, executor.maxVus ?? Math.max(Math.ceil(peak), 50)),
68
+ segments,
69
+ };
70
+ }
71
+ }
72
+ };
73
+ /** Target at `elapsedMs`: VUs (vus plans) or rate per `timeUnitMs` (rate plans). 0 past the end. */
74
+ export const targetAt = (plan, elapsedMs) => {
75
+ if (elapsedMs < 0 || elapsedMs >= plan.totalDurationMs)
76
+ return 0;
77
+ for (const segment of plan.segments) {
78
+ if (elapsedMs >= segment.startMs && elapsedMs < segment.endMs) {
79
+ return lerp(segment.from, segment.to, (elapsedMs - segment.startMs) / (segment.endMs - segment.startMs));
80
+ }
81
+ }
82
+ return 0;
83
+ };
84
+ /**
85
+ * Arrival-rate plans: how many iterations should have STARTED by `elapsedMs`
86
+ * (the integral of the rate). A segment's rate is linear, so the integral is
87
+ * exact — no accumulated rounding drift over a long soak.
88
+ */
89
+ export const cumulativeIterationsAt = (plan, elapsedMs) => {
90
+ let total = 0;
91
+ const clamped = Math.min(Math.max(elapsedMs, 0), plan.totalDurationMs);
92
+ for (const segment of plan.segments) {
93
+ if (clamped <= segment.startMs)
94
+ break;
95
+ const upTo = Math.min(clamped, segment.endMs);
96
+ const span = segment.endMs - segment.startMs;
97
+ const s = upTo - segment.startMs;
98
+ const slope = span === 0 ? 0 : (segment.to - segment.from) / span;
99
+ // ∫ (from + slope·x) dx over [0, s], converted from "per timeUnit" to per ms.
100
+ total += (segment.from * s + (slope * s * s) / 2) / plan.timeUnitMs;
101
+ }
102
+ return total;
103
+ };
104
+ /**
105
+ * Inverse of `cumulativeIterationsAt`: when does iteration number `n`
106
+ * (fractional, 1-based "n-th start") become due? Used as the *intended* start
107
+ * time for coordinated-omission-corrected latency.
108
+ */
109
+ export const intendedStartMs = (plan, n) => {
110
+ let before = 0;
111
+ for (const segment of plan.segments) {
112
+ const span = segment.endMs - segment.startMs;
113
+ const slope = span === 0 ? 0 : (segment.to - segment.from) / span;
114
+ const inSegment = (segment.from * span + (slope * span * span) / 2) / plan.timeUnitMs;
115
+ if (n <= before + inSegment || segment === plan.segments[plan.segments.length - 1]) {
116
+ const need = (n - before) * plan.timeUnitMs;
117
+ // slope/2·s² + from·s − need = 0
118
+ let s;
119
+ if (Math.abs(slope) < 1e-12) {
120
+ s = segment.from === 0 ? 0 : need / segment.from;
121
+ }
122
+ else {
123
+ const discriminant = segment.from * segment.from + 2 * slope * need;
124
+ s = (-segment.from + Math.sqrt(Math.max(0, discriminant))) / slope;
125
+ }
126
+ return segment.startMs + Math.max(0, Math.min(s, span));
127
+ }
128
+ before += inSegment;
129
+ }
130
+ return plan.totalDurationMs;
131
+ };
132
+ /** Total iterations the plan will start if the generator keeps up (arrival plans). */
133
+ export const plannedIterations = (plan) => plan.kind === "rate" ? cumulativeIterationsAt(plan, plan.totalDurationMs) : 0;
134
+ /** Samples for the config preview chart. */
135
+ export const planTimeline = (plan, sampleEveryMs = 250) => {
136
+ const points = [];
137
+ const step = Math.max(10, sampleEveryMs);
138
+ for (let atMs = 0; atMs < plan.totalDurationMs; atMs += step) {
139
+ points.push({ atMs, target: targetAt(plan, atMs) });
140
+ }
141
+ points.push({ atMs: plan.totalDurationMs, target: targetAt(plan, plan.totalDurationMs - 1) });
142
+ return points;
143
+ };
144
+ export const legacyProfileToExecutor = (profile) => {
145
+ switch (profile.type) {
146
+ case "fixed":
147
+ return { type: "constant-vus", vus: profile.vus, durationMs: profile.durationMs };
148
+ case "ramp-up":
149
+ return {
150
+ type: "ramping-vus",
151
+ startVus: 0,
152
+ stages: [
153
+ { durationMs: profile.rampDurationMs, target: profile.peakVus },
154
+ { durationMs: profile.holdDurationMs, target: profile.peakVus },
155
+ ],
156
+ };
157
+ case "spike": {
158
+ const before = Math.max(0, profile.spikeStartAtMs);
159
+ const spike = Math.max(0, profile.spikeDurationMs);
160
+ const after = Math.max(0, profile.totalDurationMs - before - spike);
161
+ return {
162
+ type: "ramping-vus",
163
+ startVus: profile.baselineVus,
164
+ stages: [
165
+ { durationMs: before, target: profile.baselineVus },
166
+ { durationMs: spike, target: profile.spikeVus },
167
+ { durationMs: after, target: profile.baselineVus },
168
+ ],
169
+ };
170
+ }
171
+ case "peak-hold":
172
+ return {
173
+ type: "ramping-vus",
174
+ startVus: 0,
175
+ stages: [
176
+ { durationMs: profile.rampUpDurationMs, target: profile.peakVus },
177
+ { durationMs: profile.holdDurationMs, target: profile.peakVus },
178
+ { durationMs: profile.rampDownDurationMs, target: 0 },
179
+ ],
180
+ };
181
+ }
182
+ };
183
+ /** Step-wise ramp that climbs until something breaks — pair with an `abortOnFail` threshold. */
184
+ export const stressStages = (peak, steps, stepDurationMs, settleMs = 0) => {
185
+ const stages = [];
186
+ const count = Math.max(1, Math.round(steps));
187
+ for (let index = 1; index <= count; index += 1) {
188
+ const target = Math.max(1, Math.round((peak * index) / count));
189
+ stages.push({ durationMs: Math.max(1, Math.round(stepDurationMs / 4)), target });
190
+ stages.push({ durationMs: Math.max(1, Math.round(stepDurationMs * 0.75)), target });
191
+ }
192
+ if (settleMs > 0)
193
+ stages.push({ durationMs: settleMs, target: 0 });
194
+ return stages;
195
+ };
196
+ export const buildPresetExecutor = (preset, options = {}) => {
197
+ const vus = Math.max(1, options.vus ?? 50);
198
+ const rate = Math.max(1, options.rate ?? 100);
199
+ const duration = Math.max(1000, options.durationMs ?? 60_000);
200
+ switch (preset) {
201
+ case "smoke":
202
+ return { type: "constant-vus", vus: Math.min(vus, 2), durationMs: Math.min(duration, 30_000) };
203
+ case "load":
204
+ return {
205
+ type: "ramping-vus",
206
+ startVus: 0,
207
+ stages: [
208
+ { durationMs: Math.round(duration * 0.2), target: vus },
209
+ { durationMs: Math.round(duration * 0.7), target: vus },
210
+ { durationMs: Math.round(duration * 0.1), target: 0 },
211
+ ],
212
+ };
213
+ case "stress":
214
+ return { type: "ramping-vus", startVus: 0, stages: stressStages(vus * 2, 5, duration / 5) };
215
+ case "spike":
216
+ return {
217
+ type: "ramping-vus",
218
+ startVus: Math.max(1, Math.round(vus * 0.1)),
219
+ stages: [
220
+ { durationMs: Math.round(duration * 0.4), target: Math.max(1, Math.round(vus * 0.1)) },
221
+ { durationMs: Math.round(duration * 0.05), target: vus * 3 },
222
+ { durationMs: Math.round(duration * 0.15), target: vus * 3 },
223
+ { durationMs: Math.round(duration * 0.05), target: Math.max(1, Math.round(vus * 0.1)) },
224
+ { durationMs: Math.round(duration * 0.35), target: Math.max(1, Math.round(vus * 0.1)) },
225
+ ],
226
+ };
227
+ case "soak":
228
+ return {
229
+ type: "ramping-vus",
230
+ startVus: 0,
231
+ stages: [
232
+ { durationMs: Math.round(duration * 0.05), target: vus },
233
+ { durationMs: Math.round(duration * 0.9), target: vus },
234
+ { durationMs: Math.round(duration * 0.05), target: 0 },
235
+ ],
236
+ };
237
+ case "breakpoint":
238
+ return {
239
+ type: "ramping-arrival-rate",
240
+ startRate: Math.max(1, Math.round(rate * 0.1)),
241
+ stages: [{ durationMs: duration, target: rate * 10 }],
242
+ maxVus: Math.max(200, vus * 10),
243
+ };
244
+ case "constant-rate":
245
+ return { type: "constant-arrival-rate", rate, durationMs: duration, maxVus: Math.max(50, vus) };
246
+ case "ramping-rate":
247
+ return {
248
+ type: "ramping-arrival-rate",
249
+ startRate: 1,
250
+ stages: [
251
+ { durationMs: Math.round(duration * 0.3), target: rate },
252
+ { durationMs: Math.round(duration * 0.6), target: rate },
253
+ { durationMs: Math.round(duration * 0.1), target: 0 },
254
+ ],
255
+ maxVus: Math.max(50, vus),
256
+ };
257
+ }
258
+ };
259
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/loadtest/plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { LoadCompleteEvent, LoadTestConfig, LoadTestReport } from "./types.js";
2
+ export declare const buildLoadTestReport: (config: LoadTestConfig, result: LoadCompleteEvent) => LoadTestReport;
3
+ export declare const formatDuration: (ms: number) => string;
4
+ export declare const formatBytes: (bytes: number) => string;
5
+ export declare const renderTextSummary: (result: LoadCompleteEvent, name?: string) => string;
6
+ export declare const renderJUnit: (result: LoadCompleteEvent, name?: string) => string;
7
+ export declare const renderHtmlReport: (config: LoadTestConfig | null, result: LoadCompleteEvent, title?: string) => string;
8
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/loadtest/report.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,iBAAiB,EACjB,cAAc,EACd,cAAc,EAEf,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,mBAAmB,GAAI,QAAQ,cAAc,EAAE,QAAQ,iBAAiB,KAAG,cAevF,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,IAAI,MAAM,KAAG,MAI3C,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,OAAO,MAAM,KAAG,MAK3C,CAAC;AAcF,eAAO,MAAM,iBAAiB,GAAI,QAAQ,iBAAiB,EAAE,OAAO,MAAM,KAAG,MAgD5E,CAAC;AAOF,eAAO,MAAM,WAAW,GAAI,QAAQ,iBAAiB,EAAE,aAAkB,KAAG,MAa3E,CAAC;AAiCF,eAAO,MAAM,gBAAgB,GAAI,QAAQ,cAAc,GAAG,IAAI,EAAE,QAAQ,iBAAiB,EAAE,cAA0B,KAAG,MAwFvH,CAAC"}
@@ -0,0 +1,211 @@
1
+ // Report builders: JSON (schema v2), a self-contained HTML page, JUnit XML for
2
+ // CI, and the plain-text summary the CLI prints. All pure string work, so the
3
+ // desktop (renderer or main) and the CLI produce identical files.
4
+ export const buildLoadTestReport = (config, result) => {
5
+ const { dataset, ...rest } = config;
6
+ return {
7
+ schemaVersion: 2,
8
+ exportedAt: new Date().toISOString(),
9
+ config: {
10
+ ...rest,
11
+ ...(dataset
12
+ ? { dataset: dataset.kind === "rows" ? { kind: "omitted", rows: dataset.rows.length } : dataset }
13
+ : {}),
14
+ // Never persist secrets that were only meant for the run.
15
+ environment: undefined,
16
+ },
17
+ result,
18
+ };
19
+ };
20
+ export const formatDuration = (ms) => {
21
+ if (ms >= 60_000)
22
+ return `${Math.floor(ms / 60_000)}m ${String(Math.round((ms % 60_000) / 1000)).padStart(2, "0")}s`;
23
+ if (ms >= 1000)
24
+ return `${(ms / 1000).toFixed(ms >= 10_000 ? 0 : 1)}s`;
25
+ return `${Math.round(ms)}ms`;
26
+ };
27
+ export const formatBytes = (bytes) => {
28
+ if (bytes >= 1024 ** 3)
29
+ return `${(bytes / 1024 ** 3).toFixed(2)} GB`;
30
+ if (bytes >= 1024 ** 2)
31
+ return `${(bytes / 1024 ** 2).toFixed(1)} MB`;
32
+ if (bytes >= 1024)
33
+ return `${(bytes / 1024).toFixed(1)} KB`;
34
+ return `${Math.round(bytes)} B`;
35
+ };
36
+ const fmt = (value, digits = 1) => Number.isFinite(value) ? (Math.round(value * 10 ** digits) / 10 ** digits).toLocaleString("en-US") : "—";
37
+ const percentText = (value) => `${(value * 100).toFixed(value < 0.1 ? 2 : 1)}%`;
38
+ const passedAll = (result) => result.thresholds.every((verdict) => verdict.passed);
39
+ // ── Plain text (CLI) ─────────────────────────────────────────────────────────
40
+ const statsLine = (label, stats) => `${label.padEnd(22)} avg=${fmt(stats.avg)}ms min=${fmt(stats.min)}ms med=${fmt(stats.p50)}ms p90=${fmt(stats.p90)}ms p95=${fmt(stats.p95)}ms p99=${fmt(stats.p99)}ms max=${fmt(stats.max)}ms`;
41
+ export const renderTextSummary = (result, name) => {
42
+ const lines = [];
43
+ const s = result.summary;
44
+ lines.push(`${name ? `${name} — ` : ""}load test ${passedAll(result) ? "PASSED" : "FAILED"}${result.abortedByThreshold ? " (aborted by threshold)" : result.stoppedByUser ? " (stopped)" : ""}`);
45
+ lines.push("");
46
+ lines.push(` duration ${formatDuration(s.durationMs)}`);
47
+ lines.push(` requests ${s.totalRequests.toLocaleString("en-US")} (${fmt(s.avgRps)} req/s avg, ${fmt(s.peakRps)} peak)`);
48
+ lines.push(` failed ${s.failedCount.toLocaleString("en-US")} (${percentText(1 - s.successRate)})`);
49
+ lines.push(` iterations ${s.totalIterations.toLocaleString("en-US")}${s.droppedIterations > 0 ? ` — ${s.droppedIterations.toLocaleString("en-US")} DROPPED (generator or VU limit reached)` : ""}`);
50
+ lines.push(` peak VUs ${s.peakVus}`);
51
+ lines.push(` data ${formatBytes(s.bytesSent)} sent, ${formatBytes(s.bytesReceived)} received`);
52
+ if (s.checksPassed + s.checksFailed > 0) {
53
+ lines.push(` checks ${percentText(s.checksPassed / (s.checksPassed + s.checksFailed))} (${s.checksPassed} passed, ${s.checksFailed} failed)`);
54
+ }
55
+ lines.push("");
56
+ lines.push(statsLine("http_req_duration", result.duration));
57
+ if (result.correctedDuration)
58
+ lines.push(statsLine(" (from intended start)", result.correctedDuration));
59
+ lines.push(statsLine("iteration_duration", result.iterationDuration));
60
+ const p = result.phases;
61
+ lines.push(`phases (mean) blocked=${fmt(p.blocked)}ms connecting=${fmt(p.connecting)}ms tls=${fmt(p.tls)}ms sending=${fmt(p.sending)}ms waiting=${fmt(p.waiting)}ms receiving=${fmt(p.receiving)}ms`);
62
+ if (result.steps.length > 1) {
63
+ lines.push("");
64
+ lines.push("steps");
65
+ for (const step of result.steps) {
66
+ lines.push(` ${step.name.padEnd(28)} ${String(step.requests).padStart(8)} req ${fmt(step.rps)}/s p95=${fmt(step.duration.p95)}ms failed=${percentText(step.failedRate)}`);
67
+ }
68
+ }
69
+ if (result.errors.length > 0) {
70
+ lines.push("");
71
+ lines.push("errors");
72
+ for (const error of result.errors.slice(0, 6)) {
73
+ lines.push(` ${String(error.count).padStart(8)} ${error.errorClass} (${error.blame}) ${error.example}`);
74
+ }
75
+ }
76
+ if (result.thresholds.length > 0) {
77
+ lines.push("");
78
+ lines.push("thresholds");
79
+ for (const verdict of result.thresholds) {
80
+ const actual = verdict.actual === null ? "no data" : fmt(verdict.actual, 3);
81
+ lines.push(` ${verdict.passed ? "✓" : "✗"} ${verdict.threshold.expression} (actual: ${actual})${verdict.aborted ? " ABORTED THE RUN" : ""}${verdict.note ? ` — ${verdict.note}` : ""}`);
82
+ }
83
+ }
84
+ if (result.generator.saturated) {
85
+ lines.push("");
86
+ lines.push(`⚠ The load generator was saturated (event-loop lag up to ${fmt(result.generator.maxLoopLagMs)}ms). Latencies may be overstated — lower the load or run from a stronger machine.`);
87
+ }
88
+ return lines.join("\n");
89
+ };
90
+ // ── JUnit ────────────────────────────────────────────────────────────────────
91
+ const xml = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
92
+ export const renderJUnit = (result, name = "Load test") => {
93
+ const cases = result.thresholds;
94
+ const failures = cases.filter((verdict) => !verdict.passed).length;
95
+ const time = (result.summary.durationMs / 1000).toFixed(3);
96
+ const body = cases
97
+ .map((verdict) => {
98
+ const label = xml(verdict.threshold.expression);
99
+ if (verdict.passed)
100
+ return ` <testcase classname="${xml(name)}" name="${label}" time="0"/>`;
101
+ const actual = verdict.actual === null ? "no data" : String(verdict.actual);
102
+ return ` <testcase classname="${xml(name)}" name="${label}" time="0">\n <failure message="${xml(`${verdict.metric}:${verdict.aggregate} was ${actual}, expected ${verdict.operator} ${verdict.limit}`)}"/>\n </testcase>`;
103
+ })
104
+ .join("\n");
105
+ return `<?xml version="1.0" encoding="UTF-8"?>\n<testsuites>\n <testsuite name="${xml(name)}" tests="${cases.length}" failures="${failures}" time="${time}">\n${body}\n </testsuite>\n</testsuites>\n`;
106
+ };
107
+ // ── HTML ─────────────────────────────────────────────────────────────────────
108
+ const esc = (value) => String(value).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
109
+ const chart = (title, points, series, unit) => {
110
+ const width = 560;
111
+ const height = 150;
112
+ const pad = { l: 44, r: 8, t: 8, b: 20 };
113
+ if (points.length < 2)
114
+ return `<div class="card"><h3>${esc(title)}</h3><p class="muted">Not enough data.</p></div>`;
115
+ const maxX = points[points.length - 1].atMs || 1;
116
+ const maxY = Math.max(1e-9, ...series.flatMap((s) => points.map(s.pick))) * 1.1;
117
+ const x = (at) => pad.l + (at / maxX) * (width - pad.l - pad.r);
118
+ const y = (value) => pad.t + (1 - value / maxY) * (height - pad.t - pad.b);
119
+ const paths = series
120
+ .map((s) => `<polyline fill="none" stroke="${s.color}" stroke-width="1.6" points="${points.map((p) => `${x(p.atMs).toFixed(1)},${y(s.pick(p)).toFixed(1)}`).join(" ")}"/>`)
121
+ .join("");
122
+ const legend = series.map((s) => `<span><i style="background:${s.color}"></i>${esc(s.label)}</span>`).join("");
123
+ return `<div class="card"><h3>${esc(title)} <small>${esc(unit)}</small></h3><svg viewBox="0 0 ${width} ${height}" role="img" aria-label="${esc(title)}">
124
+ <line x1="${pad.l}" y1="${height - pad.b}" x2="${width - pad.r}" y2="${height - pad.b}" stroke="currentColor" opacity=".25"/>
125
+ <line x1="${pad.l}" y1="${pad.t}" x2="${pad.l}" y2="${height - pad.b}" stroke="currentColor" opacity=".25"/>
126
+ <text x="4" y="${pad.t + 8}" font-size="10" fill="currentColor" opacity=".6">${fmt(maxY / 1.1, 1)}</text>
127
+ <text x="${width - pad.r}" y="${height - 6}" font-size="10" text-anchor="end" fill="currentColor" opacity=".6">${esc(formatDuration(maxX))}</text>
128
+ ${paths}</svg><div class="legend">${legend}</div></div>`;
129
+ };
130
+ export const renderHtmlReport = (config, result, title = "Load test report") => {
131
+ const s = result.summary;
132
+ const ok = passedAll(result);
133
+ const stat = (label, value, tone = "") => `<div class="stat ${tone}"><span>${esc(label)}</span><b>${esc(value)}</b></div>`;
134
+ const stats = [
135
+ stat("Verdict", ok ? "Passed" : "Failed", ok ? "good" : "bad"),
136
+ stat("Duration", formatDuration(s.durationMs)),
137
+ stat("Requests", s.totalRequests.toLocaleString("en-US")),
138
+ stat("Throughput", `${fmt(s.avgRps)} /s (peak ${fmt(s.peakRps)})`),
139
+ stat("p95", `${fmt(result.duration.p95)} ms`),
140
+ stat("p99", `${fmt(result.duration.p99)} ms`),
141
+ stat("Failed", percentText(1 - s.successRate), s.failedCount > 0 ? "bad" : "good"),
142
+ stat("Peak VUs", String(s.peakVus)),
143
+ ...(s.droppedIterations > 0 ? [stat("Dropped iterations", s.droppedIterations.toLocaleString("en-US"), "bad")] : []),
144
+ ...(s.checksPassed + s.checksFailed > 0 ? [stat("Checks", percentText(s.checksPassed / (s.checksPassed + s.checksFailed)))] : []),
145
+ ].join("");
146
+ const latencyRow = (label, l) => `<tr><td>${esc(label)}</td><td>${fmt(l.avg)}</td><td>${fmt(l.min)}</td><td>${fmt(l.p50)}</td><td>${fmt(l.p90)}</td><td>${fmt(l.p95)}</td><td>${fmt(l.p99)}</td><td>${fmt(l.p999)}</td><td>${fmt(l.max)}</td></tr>`;
147
+ const thresholds = result.thresholds.length
148
+ ? `<h2>Thresholds</h2><table><thead><tr><th></th><th>Expression</th><th>Actual</th></tr></thead><tbody>${result.thresholds
149
+ .map((v) => `<tr class="${v.passed ? "" : "bad-row"}"><td>${v.passed ? "✓" : "✗"}</td><td><code>${esc(v.threshold.expression)}</code>${v.aborted ? " <b>aborted the run</b>" : ""}</td><td>${v.actual === null ? "no data" : fmt(v.actual, 3)}${v.note ? ` <span class="muted">${esc(v.note)}</span>` : ""}</td></tr>`)
150
+ .join("")}</tbody></table>`
151
+ : "";
152
+ const steps = result.steps.length
153
+ ? `<h2>Steps</h2><table><thead><tr><th>Step</th><th>Requests</th><th>/s</th><th>Failed</th><th>avg</th><th>p95</th><th>p99</th><th>max</th></tr></thead><tbody>${result.steps
154
+ .map((st) => `<tr><td>${esc(st.name)}<div class="muted">${esc(st.method)} ${esc(st.url)}</div></td><td>${st.requests.toLocaleString("en-US")}</td><td>${fmt(st.rps)}</td><td>${percentText(st.failedRate)}</td><td>${fmt(st.duration.avg)}</td><td>${fmt(st.duration.p95)}</td><td>${fmt(st.duration.p99)}</td><td>${fmt(st.duration.max)}</td></tr>`)
155
+ .join("")}</tbody></table>`
156
+ : "";
157
+ const checks = result.steps.flatMap((st) => st.checks.map((c) => ({ step: st.name, ...c })));
158
+ const checksTable = checks.length
159
+ ? `<h2>Checks</h2><table><thead><tr><th>Step</th><th>Check</th><th>Passed</th><th>Failed</th></tr></thead><tbody>${checks
160
+ .map((c) => `<tr class="${c.failed > 0 ? "bad-row" : ""}"><td>${esc(c.step)}</td><td>${esc(c.name)}</td><td>${c.passed.toLocaleString("en-US")}</td><td>${c.failed.toLocaleString("en-US")}</td></tr>`)
161
+ .join("")}</tbody></table>`
162
+ : "";
163
+ const errors = result.errors.length
164
+ ? `<h2>Errors</h2><table><thead><tr><th>Count</th><th>Kind</th><th>Blame</th><th>Example</th></tr></thead><tbody>${result.errors
165
+ .map((e) => `<tr><td>${e.count.toLocaleString("en-US")}</td><td>${esc(e.errorClass)}</td><td>${esc(e.blame)}</td><td>${esc(e.example)}</td></tr>`)
166
+ .join("")}</tbody></table>`
167
+ : "";
168
+ const status = Object.entries(result.statusCodeCounts)
169
+ .map(([code, count]) => `<span class="pill">${esc(code === "0" ? "network" : code)} · ${count.toLocaleString("en-US")}</span>`)
170
+ .join(" ");
171
+ return `<!doctype html>
172
+ <html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
173
+ <title>${esc(title)}</title>
174
+ <style>
175
+ :root{--bg:#fff;--fg:#14171f;--muted:#6b7280;--line:#e5e7eb;--card:#f8fafc;--good:#047857;--bad:#b91c1c;color-scheme:light dark}
176
+ @media (prefers-color-scheme:dark){:root{--bg:#0f1218;--fg:#e6e8ee;--muted:#9aa3b2;--line:#252b37;--card:#161b24;--good:#34d399;--bad:#f87171}}
177
+ body{margin:0;background:var(--bg);color:var(--fg);font:14px/1.5 system-ui,-apple-system,Segoe UI,sans-serif}
178
+ main{max-width:1080px;margin:0 auto;padding:28px 16px 60px}
179
+ h1{font-size:22px;margin:0 0 4px}h2{font-size:16px;margin:28px 0 10px}h3{font-size:13px;margin:0 0 6px}h3 small{color:var(--muted);font-weight:400}
180
+ .muted{color:var(--muted);font-size:12px}.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;margin:18px 0}
181
+ .stat{background:var(--card);border:1px solid var(--line);border-radius:10px;padding:10px 12px}.stat span{display:block;color:var(--muted);font-size:12px}.stat b{font-size:17px}
182
+ .stat.good b{color:var(--good)}.stat.bad b{color:var(--bad)}
183
+ .grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:12px}.card{background:var(--card);border:1px solid var(--line);border-radius:10px;padding:12px}
184
+ svg{width:100%;height:auto}.legend{display:flex;gap:12px;font-size:12px;color:var(--muted)}.legend i{display:inline-block;width:10px;height:3px;margin-right:5px;vertical-align:middle}
185
+ table{width:100%;border-collapse:collapse;font-size:13px}th,td{text-align:left;padding:6px 8px;border-bottom:1px solid var(--line);vertical-align:top}th{color:var(--muted);font-weight:500}
186
+ .bad-row td{color:var(--bad)}code{font-family:ui-monospace,Menlo,monospace;font-size:12px}.pill{display:inline-block;border:1px solid var(--line);border-radius:99px;padding:1px 9px;font-size:12px;margin:2px}
187
+ .warn{background:#fef3c7;color:#92400e;border-radius:8px;padding:8px 12px;margin:12px 0}
188
+ </style></head><body><main>
189
+ <h1>${esc(title)}</h1>
190
+ <div class="muted">${esc(config?.name ?? "")} ${esc(s.startedAt)} → ${esc(s.finishedAt)}${result.abortedByThreshold ? " · aborted by a threshold" : result.stoppedByUser ? " · stopped by user" : ""}</div>
191
+ ${result.generator.saturated ? `<div class="warn">The load generator was saturated (event-loop lag up to ${fmt(result.generator.maxLoopLagMs)} ms). Latencies may be overstated.</div>` : ""}
192
+ <div class="stats">${stats}</div>
193
+ <div class="grid">
194
+ ${chart("Throughput", result.timeseries, [{ label: "req/s", color: "#2563eb", pick: (p) => p.rps }], "requests / s")}
195
+ ${chart("Latency", result.timeseries, [{ label: "p50", color: "#10b981", pick: (p) => p.p50 }, { label: "p95", color: "#f59e0b", pick: (p) => p.p95 }, { label: "p99", color: "#ef4444", pick: (p) => p.p99 }], "ms")}
196
+ ${chart("Virtual users", result.timeseries, [{ label: "active", color: "#7c3aed", pick: (p) => p.activeVus }], "VUs")}
197
+ ${chart("Errors", result.timeseries, [{ label: "failed", color: "#ef4444", pick: (p) => p.errors }, { label: "dropped", color: "#6b7280", pick: (p) => p.dropped }], "per interval")}
198
+ </div>
199
+ <h2>Latency (ms)</h2>
200
+ <table><thead><tr><th></th><th>avg</th><th>min</th><th>p50</th><th>p90</th><th>p95</th><th>p99</th><th>p99.9</th><th>max</th></tr></thead><tbody>
201
+ ${latencyRow("Request duration", result.duration)}
202
+ ${result.correctedDuration ? latencyRow("From intended start", result.correctedDuration) : ""}
203
+ ${latencyRow("Iteration", result.iterationDuration)}
204
+ </tbody></table>
205
+ <p class="muted">Mean phases: blocked ${fmt(result.phases.blocked)} · connecting ${fmt(result.phases.connecting)} · TLS ${fmt(result.phases.tls)} · sending ${fmt(result.phases.sending)} · waiting ${fmt(result.phases.waiting)} · receiving ${fmt(result.phases.receiving)} (ms)</p>
206
+ ${thresholds}${steps}${checksTable}${errors}
207
+ <h2>Status codes</h2><p>${status || '<span class="muted">none</span>'}</p>
208
+ <p class="muted">Data: ${formatBytes(s.bytesSent)} sent, ${formatBytes(s.bytesReceived)} received · Generator: ${result.generator.workers} worker(s), peak ${result.generator.peakRssMb} MB</p>
209
+ </main></body></html>`;
210
+ };
211
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/loadtest/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import type { LatencyHistogram } from "./histogram.js";
2
+ import type { LoadThreshold, ThresholdVerdict } from "./types.js";
3
+ export type MetricKind = "trend" | "rate" | "counter" | "gauge";
4
+ export declare const METRIC_KINDS: Readonly<Record<string, MetricKind>>;
5
+ export type ThresholdOperator = "<" | "<=" | ">" | ">=" | "==" | "!=";
6
+ export type ThresholdAggregate = {
7
+ kind: "avg" | "min" | "max" | "med" | "count" | "rate" | "value";
8
+ } | {
9
+ kind: "p";
10
+ percentile: number;
11
+ };
12
+ export interface ParsedThreshold {
13
+ metric: string;
14
+ metricKind: MetricKind;
15
+ tag: {
16
+ key: string;
17
+ value: string;
18
+ } | null;
19
+ aggregate: ThresholdAggregate;
20
+ operator: ThresholdOperator;
21
+ limit: number;
22
+ }
23
+ export declare class ThresholdParseError extends Error {
24
+ constructor(message: string);
25
+ }
26
+ export declare const normalizeThresholdExpression: (input: string) => string;
27
+ export declare const parseThreshold: (expression: string) => ParsedThreshold;
28
+ /** Read access to the cumulative metrics, supplied by the engine. */
29
+ export type MetricReading = {
30
+ kind: "trend";
31
+ histogram: LatencyHistogram;
32
+ } | {
33
+ kind: "rate";
34
+ passes: number;
35
+ total: number;
36
+ } | {
37
+ kind: "counter";
38
+ value: number;
39
+ } | {
40
+ kind: "gauge";
41
+ value: number;
42
+ };
43
+ export interface MetricSource {
44
+ read(metric: string, tag: {
45
+ key: string;
46
+ value: string;
47
+ } | null): MetricReading | null;
48
+ elapsedMs(): number;
49
+ }
50
+ export declare const readAggregate: (parsed: ParsedThreshold, source: MetricSource) => number | null;
51
+ export declare const evaluateThreshold: (threshold: LoadThreshold, source: MetricSource) => ThresholdVerdict;
52
+ export declare const evaluateThresholds: (thresholds: readonly LoadThreshold[], source: MetricSource) => ThresholdVerdict[];
53
+ export type LegacyThresholdMetric = "http_req_duration_p95" | "http_req_duration_p99" | "http_req_duration_avg" | "http_req_failed_rate" | "iter_duration_avg" | "error_rate";
54
+ export declare const legacyThresholdExpression: (metric: LegacyThresholdMetric, operator: ThresholdOperator, value: number, unit: "ms" | "s" | "%") => string;
55
+ //# sourceMappingURL=thresholds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thresholds.d.ts","sourceRoot":"","sources":["../../src/loadtest/thresholds.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAElE,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;AAEhE,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAkB7D,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEtE,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAA;CAAE,GACpE;IAAE,IAAI,EAAE,GAAG,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtC,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,UAAU,CAAC;IACvB,GAAG,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC3C,SAAS,EAAE,kBAAkB,CAAC;IAC9B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAWD,eAAO,MAAM,4BAA4B,GAAI,OAAO,MAAM,KAAG,MAQ5D,CAAC;AAKF,eAAO,MAAM,cAAc,GAAI,YAAY,MAAM,KAAG,eAoDnD,CAAC;AAEF,qEAAqE;AACrE,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,gBAAgB,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAErC,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,GAAG,aAAa,GAAG,IAAI,CAAC;IACvF,SAAS,IAAI,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,aAAa,GAAI,QAAQ,eAAe,EAAE,QAAQ,YAAY,KAAG,MAAM,GAAG,IAgCtF,CAAC;AAmBF,eAAO,MAAM,iBAAiB,GAC5B,WAAW,aAAa,EACxB,QAAQ,YAAY,KACnB,gBA+BF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,YAAY,SAAS,aAAa,EAAE,EACpC,QAAQ,YAAY,KACnB,gBAAgB,EAAyE,CAAC;AAI7F,MAAM,MAAM,qBAAqB,GAC7B,uBAAuB,GACvB,uBAAuB,GACvB,uBAAuB,GACvB,sBAAsB,GACtB,mBAAmB,GACnB,YAAY,CAAC;AAEjB,eAAO,MAAM,yBAAyB,GACpC,QAAQ,qBAAqB,EAC7B,UAAU,iBAAiB,EAC3B,OAAO,MAAM,EACb,MAAM,IAAI,GAAG,GAAG,GAAG,GAAG,KACrB,MAeF,CAAC"}