@testchimp/playwright 0.2.18 → 0.2.20

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,384 @@
1
+ "use strict";
2
+ /**
3
+ * Smart-smoke: config merge, suite walk, related-tests load, selection sidecar.
4
+ */
5
+ var __importDefault = (this && this.__importDefault) || function (mod) {
6
+ return (mod && mod.__esModule) ? mod : { "default": mod };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.getBranchName = exports.SMART_SMOKE_SELECTION_FILENAME = exports.SMART_SMOKE_SKIP_REASON = void 0;
10
+ exports.isTruthyEnv = isTruthyEnv;
11
+ exports.normalizeTag = normalizeTag;
12
+ exports.resolveSmartSmokeConfig = resolveSmartSmokeConfig;
13
+ exports.readSmartSmokeUseFromConfig = readSmartSmokeUseFromConfig;
14
+ exports.folderPathSegments = folderPathSegments;
15
+ exports.locatorFromDerived = locatorFromDerived;
16
+ exports.normalizeLocator = normalizeLocator;
17
+ exports.locatorKey = locatorKey;
18
+ exports.locatorsEqual = locatorsEqual;
19
+ exports.collectSuiteCandidates = collectSuiteCandidates;
20
+ exports.findPlansRoot = findPlansRoot;
21
+ exports.loadRelatedTests = loadRelatedTests;
22
+ exports.getSmartSmokeSelectionFilePath = getSmartSmokeSelectionFilePath;
23
+ exports.writeSmartSmokeSelectionFile = writeSmartSmokeSelectionFile;
24
+ exports.invalidateSmartSmokeSelectionCache = invalidateSmartSmokeSelectionCache;
25
+ exports.loadSmartSmokeSelectionLookup = loadSmartSmokeSelectionLookup;
26
+ exports.readSmartSmokeSelectionFile = readSmartSmokeSelectionFile;
27
+ exports.unlinkSmartSmokeSelectionFile = unlinkSmartSmokeSelectionFile;
28
+ exports.unionLocators = unionLocators;
29
+ exports.isLocatorSelected = isLocatorSelected;
30
+ exports.resolveSkipReasonFromAnnotations = resolveSkipReasonFromAnnotations;
31
+ exports.maybeSkipForSmartSmoke = maybeSkipForSmartSmoke;
32
+ exports.toWireLocator = toWireLocator;
33
+ exports.fromWireLocator = fromWireLocator;
34
+ const fs_1 = __importDefault(require("fs"));
35
+ const path_1 = __importDefault(require("path"));
36
+ const utils_1 = require("./utils");
37
+ Object.defineProperty(exports, "getBranchName", { enumerable: true, get: function () { return utils_1.getBranchName; } });
38
+ exports.SMART_SMOKE_SKIP_REASON = 'smart-smoke';
39
+ exports.SMART_SMOKE_SELECTION_FILENAME = '.testchimp-smart-smoke-selection.json';
40
+ function isTruthyEnv(value) {
41
+ if (value == null)
42
+ return false;
43
+ const v = String(value).trim().toLowerCase();
44
+ return v === 'true' || v === '1';
45
+ }
46
+ function normalizeTag(tag) {
47
+ const t = String(tag || '').trim();
48
+ if (!t)
49
+ return '';
50
+ return t.startsWith('@') ? t.toLowerCase() : `@${t.toLowerCase()}`;
51
+ }
52
+ /** Env field → use field → fallback (warn + 20% suite % when no size constraint). */
53
+ function resolveSmartSmokeConfig(useOpts, env = process.env) {
54
+ const enabled = isTruthyEnv(env.TESTCHIMP_SMART_SMOKE_ENABLED);
55
+ const use = useOpts || {};
56
+ const maxTestsEnv = env.TESTCHIMP_SMART_SMOKE_MAX_TESTS?.trim();
57
+ const suitePctEnv = env.TESTCHIMP_SMART_SMOKE_SUITE_PERCENTAGE?.trim();
58
+ const timeEnv = env.TESTCHIMP_SMART_SMOKE_MAX_TIME_BUDGET_MINS?.trim();
59
+ const tagsEnv = env.TESTCHIMP_SMART_SMOKE_INCLUDE_TAGS?.trim();
60
+ const relatedOnlyEnv = env.TESTCHIMP_SMART_SMOKE_RELATED_TESTS_ONLY;
61
+ let maxTests;
62
+ if (maxTestsEnv) {
63
+ const n = parseInt(maxTestsEnv, 10);
64
+ if (Number.isFinite(n) && n > 0)
65
+ maxTests = n;
66
+ }
67
+ else if (typeof use.maxTests === 'number' && use.maxTests > 0) {
68
+ maxTests = use.maxTests;
69
+ }
70
+ let suitePercentage;
71
+ if (suitePctEnv) {
72
+ const n = Number(suitePctEnv);
73
+ if (Number.isFinite(n) && n > 0)
74
+ suitePercentage = n;
75
+ }
76
+ else if (typeof use.suitePercentage === 'number' && use.suitePercentage > 0) {
77
+ suitePercentage = use.suitePercentage;
78
+ }
79
+ let maxTimeBudgetMins;
80
+ if (timeEnv) {
81
+ const n = parseInt(timeEnv, 10);
82
+ if (Number.isFinite(n) && n > 0)
83
+ maxTimeBudgetMins = n;
84
+ }
85
+ else if (typeof use.maxTimeBudgetMins === 'number' && use.maxTimeBudgetMins > 0) {
86
+ maxTimeBudgetMins = use.maxTimeBudgetMins;
87
+ }
88
+ let includeTags = [];
89
+ if (tagsEnv) {
90
+ includeTags = tagsEnv.split(',').map((t) => t.trim()).filter(Boolean);
91
+ }
92
+ else if (Array.isArray(use.includeTags)) {
93
+ includeTags = [...use.includeTags];
94
+ }
95
+ const relatedTestsOnly = relatedOnlyEnv != null && String(relatedOnlyEnv).trim() !== ''
96
+ ? isTruthyEnv(relatedOnlyEnv)
97
+ : Boolean(use.relatedTestsOnly);
98
+ let usedDefaultSuitePercentage = false;
99
+ if (enabled &&
100
+ !relatedTestsOnly &&
101
+ maxTests == null &&
102
+ suitePercentage == null &&
103
+ maxTimeBudgetMins == null) {
104
+ suitePercentage = 20;
105
+ usedDefaultSuitePercentage = true;
106
+ }
107
+ return {
108
+ enabled,
109
+ maxTests,
110
+ suitePercentage,
111
+ maxTimeBudgetMins,
112
+ includeTags,
113
+ relatedTestsOnly,
114
+ usedDefaultSuitePercentage,
115
+ };
116
+ }
117
+ function readSmartSmokeUseFromConfig(config) {
118
+ const projects = config.projects || [];
119
+ for (const p of projects) {
120
+ const use = p.use;
121
+ const raw = use?.testchimpSmartSmoke;
122
+ if (raw && typeof raw === 'object') {
123
+ return raw;
124
+ }
125
+ }
126
+ return undefined;
127
+ }
128
+ function folderPathSegments(folderPath) {
129
+ if (Array.isArray(folderPath)) {
130
+ return folderPath.map((s) => String(s || '').trim()).filter((s) => s && s !== '.');
131
+ }
132
+ const norm = (0, utils_1.normalizeManifestFolderPath)(String(folderPath || ''));
133
+ if (!norm)
134
+ return [];
135
+ return norm.split('/').filter(Boolean);
136
+ }
137
+ function locatorFromDerived(paths) {
138
+ return {
139
+ folderPath: folderPathSegments(paths.folderPath),
140
+ fileName: paths.fileName,
141
+ testSuite: Array.isArray(paths.suitePath) ? [...paths.suitePath] : [],
142
+ testName: paths.testName,
143
+ };
144
+ }
145
+ function normalizeLocator(raw) {
146
+ const folder = raw.folder_path ??
147
+ (Array.isArray(raw.folderPath) ? raw.folderPath : folderPathSegments(raw.folderPath));
148
+ return {
149
+ folderPath: folderPathSegments(folder),
150
+ fileName: raw.file_name ?? raw.fileName ?? '',
151
+ testSuite: raw.test_suite ?? raw.testSuite ?? [],
152
+ testName: raw.test_name ?? raw.testName ?? '',
153
+ };
154
+ }
155
+ function locatorKey(loc) {
156
+ const n = normalizeLocator(loc);
157
+ const folder = Array.isArray(n.folderPath) ? n.folderPath : folderPathSegments(n.folderPath);
158
+ const suite = Array.isArray(n.testSuite) ? n.testSuite : [];
159
+ return [
160
+ folder.join('/'),
161
+ n.fileName || '',
162
+ suite.join('\u0001'),
163
+ n.testName || '',
164
+ ].join('\0');
165
+ }
166
+ function locatorsEqual(a, b) {
167
+ return locatorKey(a) === locatorKey(b);
168
+ }
169
+ function collectSuiteCandidates(suite, testsFolder, rootDir, includeTags) {
170
+ const wanted = new Set(includeTags.map(normalizeTag).filter(Boolean));
171
+ const suiteCandidates = [];
172
+ const taggedTests = [];
173
+ const seen = new Set();
174
+ const seenTagged = new Set();
175
+ const visit = (s) => {
176
+ for (const test of s.tests) {
177
+ const paths = (0, utils_1.derivePaths)(test, testsFolder, rootDir, false);
178
+ const loc = locatorFromDerived(paths);
179
+ const key = locatorKey(loc);
180
+ if (!seen.has(key)) {
181
+ seen.add(key);
182
+ suiteCandidates.push(loc);
183
+ }
184
+ if (wanted.size > 0 && testMatchesTags(test, wanted) && !seenTagged.has(key)) {
185
+ seenTagged.add(key);
186
+ taggedTests.push(loc);
187
+ }
188
+ }
189
+ for (const child of s.suites) {
190
+ visit(child);
191
+ }
192
+ };
193
+ visit(suite);
194
+ return { suiteCandidates, taggedTests };
195
+ }
196
+ function testMatchesTags(test, wantedNormalized) {
197
+ const tags = test.tags;
198
+ if (!Array.isArray(tags) || tags.length === 0)
199
+ return false;
200
+ for (const t of tags) {
201
+ if (wantedNormalized.has(normalizeTag(t)))
202
+ return true;
203
+ }
204
+ return false;
205
+ }
206
+ function findPlansRoot(startDir) {
207
+ let dir = path_1.default.resolve(startDir);
208
+ for (let i = 0; i < 40; i++) {
209
+ if (fs_1.default.existsSync(path_1.default.join(dir, '.testchimp-plans'))) {
210
+ return dir;
211
+ }
212
+ const plansDir = path_1.default.join(dir, 'plans');
213
+ if (fs_1.default.existsSync(plansDir) && fs_1.default.statSync(plansDir).isDirectory()) {
214
+ // Prefer mapped plans root (marker inside plans/) over a bare folder name match.
215
+ if (fs_1.default.existsSync(path_1.default.join(plansDir, '.testchimp-plans'))) {
216
+ return plansDir;
217
+ }
218
+ // Fallback: conventional plans/ directory when marker is absent.
219
+ return plansDir;
220
+ }
221
+ const parent = path_1.default.dirname(dir);
222
+ if (parent === dir)
223
+ break;
224
+ dir = parent;
225
+ }
226
+ return undefined;
227
+ }
228
+ /**
229
+ * Load related-tests.json for the current branch under plans/smart-smoke/<branch>/.
230
+ * Branch path segments are kept literally (nested dirs for `/` in branch names).
231
+ */
232
+ function loadRelatedTests(plansRoot, branchName) {
233
+ if (!plansRoot || !branchName?.trim())
234
+ return [];
235
+ const filePath = path_1.default.join(plansRoot, 'smart-smoke', ...branchName.split(/[/\\]+/), 'related-tests.json');
236
+ try {
237
+ const raw = JSON.parse(fs_1.default.readFileSync(filePath, 'utf8'));
238
+ const list = Array.isArray(raw)
239
+ ? raw
240
+ : Array.isArray(raw.relatedTests)
241
+ ? raw.relatedTests
242
+ : Array.isArray(raw.related_tests)
243
+ ? raw.related_tests
244
+ : [];
245
+ return list
246
+ .filter((x) => x != null && typeof x === 'object')
247
+ .map(normalizeLocator);
248
+ }
249
+ catch {
250
+ return [];
251
+ }
252
+ }
253
+ function getSmartSmokeSelectionFilePath(projectRootDir = process.cwd()) {
254
+ return ((0, utils_1.getEnvVar)('TESTCHIMP_SMART_SMOKE_SELECTION_FILE') ||
255
+ path_1.default.join(projectRootDir, exports.SMART_SMOKE_SELECTION_FILENAME));
256
+ }
257
+ function writeSmartSmokeSelectionFile(projectRootDir, payload) {
258
+ const filePath = getSmartSmokeSelectionFilePath(projectRootDir);
259
+ fs_1.default.mkdirSync(path_1.default.dirname(filePath), { recursive: true });
260
+ fs_1.default.writeFileSync(filePath, JSON.stringify(payload, null, 2), 'utf8');
261
+ invalidateSmartSmokeSelectionCache();
262
+ return filePath;
263
+ }
264
+ let selectionCache = null;
265
+ function invalidateSmartSmokeSelectionCache() {
266
+ selectionCache = null;
267
+ }
268
+ /**
269
+ * Load selection sidecar once per worker (re-read only when mtime changes).
270
+ * Returns undefined when smart-smoke is not active for this process.
271
+ */
272
+ function loadSmartSmokeSelectionLookup(projectRootDir = process.cwd()) {
273
+ // Env is the source of truth for "is this run smart-smoke" — ignore stale sidecars
274
+ // left behind when a previous run crashed before onEnd unlink.
275
+ if (!isTruthyEnv(process.env.TESTCHIMP_SMART_SMOKE_ENABLED)) {
276
+ return undefined;
277
+ }
278
+ const filePath = getSmartSmokeSelectionFilePath(projectRootDir);
279
+ try {
280
+ const st = fs_1.default.statSync(filePath);
281
+ if (selectionCache &&
282
+ selectionCache.filePath === filePath &&
283
+ selectionCache.mtimeMs === st.mtimeMs) {
284
+ return { selection: selectionCache.selection, keySet: selectionCache.keySet };
285
+ }
286
+ const parsed = JSON.parse(fs_1.default.readFileSync(filePath, 'utf8'));
287
+ if (!parsed || !Array.isArray(parsed.selectedTests) || !parsed.enabled) {
288
+ selectionCache = null;
289
+ return undefined;
290
+ }
291
+ const selection = {
292
+ ...parsed,
293
+ selectedTests: parsed.selectedTests.map(normalizeLocator),
294
+ };
295
+ const keySet = new Set(selection.selectedTests.map((t) => locatorKey(t)));
296
+ selectionCache = { filePath, mtimeMs: st.mtimeMs, selection, keySet };
297
+ return { selection, keySet };
298
+ }
299
+ catch {
300
+ selectionCache = null;
301
+ return undefined;
302
+ }
303
+ }
304
+ function readSmartSmokeSelectionFile(projectRootDir = process.cwd()) {
305
+ return loadSmartSmokeSelectionLookup(projectRootDir)?.selection;
306
+ }
307
+ function unlinkSmartSmokeSelectionFile(filePath) {
308
+ if (!filePath)
309
+ return;
310
+ try {
311
+ fs_1.default.unlinkSync(filePath);
312
+ }
313
+ catch {
314
+ // ignore
315
+ }
316
+ invalidateSmartSmokeSelectionCache();
317
+ }
318
+ /** Client-side must_include when related-tests-only or API unavailable. */
319
+ function unionLocators(...lists) {
320
+ const map = new Map();
321
+ for (const list of lists) {
322
+ for (const loc of list) {
323
+ const n = normalizeLocator(loc);
324
+ map.set(locatorKey(n), n);
325
+ }
326
+ }
327
+ return [...map.values()];
328
+ }
329
+ function isLocatorSelected(paths, selected, keySet) {
330
+ const key = locatorKey(locatorFromDerived(paths));
331
+ if (keySet)
332
+ return keySet.has(key);
333
+ return selected.some((s) => locatorKey(s) === key);
334
+ }
335
+ function resolveSkipReasonFromAnnotations(annotations, playwrightSkipMessage) {
336
+ if (!annotations?.length && !playwrightSkipMessage)
337
+ return undefined;
338
+ for (const a of annotations || []) {
339
+ if (a.type === 'skip-reason' && a.description?.trim()) {
340
+ return a.description.trim();
341
+ }
342
+ }
343
+ for (const a of annotations || []) {
344
+ if ((a.type === 'skip' || a.type === 'fix') && a.description?.trim()) {
345
+ return a.description.trim();
346
+ }
347
+ }
348
+ const msg = playwrightSkipMessage?.trim();
349
+ return msg || undefined;
350
+ }
351
+ function maybeSkipForSmartSmoke(testInfo) {
352
+ const rootDir = testInfo.project?.rootDir ?? process.cwd();
353
+ const lookup = loadSmartSmokeSelectionLookup(rootDir);
354
+ if (!lookup)
355
+ return;
356
+ const testsFolder = (0, utils_1.getEnvVar)('TESTCHIMP_TESTS_FOLDER') || 'tests';
357
+ const paths = (0, utils_1.derivePathsFromTestInfo)(testInfo, testsFolder, rootDir);
358
+ if (isLocatorSelected(paths, lookup.selection.selectedTests, lookup.keySet))
359
+ return;
360
+ testInfo.annotations.push({ type: 'skip-reason', description: exports.SMART_SMOKE_SKIP_REASON });
361
+ testInfo.skip(true, exports.SMART_SMOKE_SKIP_REASON);
362
+ }
363
+ function toWireLocator(loc) {
364
+ const n = normalizeLocator(loc);
365
+ return {
366
+ folder_path: n.folderPath || [],
367
+ file_name: n.fileName || '',
368
+ test_suite: n.testSuite || [],
369
+ test_name: n.testName || '',
370
+ };
371
+ }
372
+ function fromWireLocator(raw) {
373
+ return normalizeLocator({
374
+ folder_path: raw.folder_path,
375
+ folderPath: raw.folderPath,
376
+ file_name: raw.file_name,
377
+ fileName: raw.fileName,
378
+ test_suite: raw.test_suite,
379
+ testSuite: raw.testSuite,
380
+ test_name: raw.test_name,
381
+ testName: raw.testName,
382
+ });
383
+ }
384
+ //# sourceMappingURL=smart-smoke.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smart-smoke.js","sourceRoot":"","sources":["../src/smart-smoke.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;AAwDH,kCAIC;AAED,oCAIC;AAGD,0DAqEC;AAED,kEAUC;AAED,gDAOC;AAED,gDAOC;AAED,4CAUC;AAED,gCAUC;AAED,sCAEC;AAED,wDAgCC;AAWD,sCAoBC;AAMD,4CAkBC;AAED,wEAKC;AAED,oEASC;AAWD,gFAEC;AAMD,sEAkCC;AAED,kEAIC;AAED,sEAQC;AAGD,sCASC;AAED,8CAQC;AAED,4EAiBC;AAED,wDAaC;AAED,sCAQC;AAED,0CAWC;AAjcD,4CAAoB;AACpB,gDAAwB;AAExB,mCAQiB;AAwbR,8FA7bP,qBAAa,OA6bO;AAtbT,QAAA,uBAAuB,GAAG,aAAa,CAAC;AACxC,QAAA,8BAA8B,GAAG,uCAAuC,CAAC;AAwCtF,SAAgB,WAAW,CAAC,KAAgC;IAC1D,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,KAAK,CAAC;IAChC,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC7C,OAAO,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,GAAG,CAAC;AACnC,CAAC;AAED,SAAgB,YAAY,CAAC,GAAW;IACtC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACnC,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAClB,OAAO,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;AACrE,CAAC;AAED,qFAAqF;AACrF,SAAgB,uBAAuB,CACrC,OAAkD,EAClD,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAC/D,MAAM,GAAG,GAAG,OAAO,IAAI,EAAE,CAAC;IAE1B,MAAM,WAAW,GAAG,GAAG,CAAC,+BAA+B,EAAE,IAAI,EAAE,CAAC;IAChE,MAAM,WAAW,GAAG,GAAG,CAAC,sCAAsC,EAAE,IAAI,EAAE,CAAC;IACvE,MAAM,OAAO,GAAG,GAAG,CAAC,0CAA0C,EAAE,IAAI,EAAE,CAAC;IACvE,MAAM,OAAO,GAAG,GAAG,CAAC,kCAAkC,EAAE,IAAI,EAAE,CAAC;IAC/D,MAAM,cAAc,GAAG,GAAG,CAAC,wCAAwC,CAAC;IAEpE,IAAI,QAA4B,CAAC;IACjC,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,CAAC,GAAG,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACpC,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,QAAQ,GAAG,CAAC,CAAC;IAChD,CAAC;SAAM,IAAI,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QAChE,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC1B,CAAC;IAED,IAAI,eAAmC,CAAC;IACxC,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;QAC9B,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,eAAe,GAAG,CAAC,CAAC;IACvD,CAAC;SAAM,IAAI,OAAO,GAAG,CAAC,eAAe,KAAK,QAAQ,IAAI,GAAG,CAAC,eAAe,GAAG,CAAC,EAAE,CAAC;QAC9E,eAAe,GAAG,GAAG,CAAC,eAAe,CAAC;IACxC,CAAC;IAED,IAAI,iBAAqC,CAAC;IAC1C,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,CAAC,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAChC,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,iBAAiB,GAAG,CAAC,CAAC;IACzD,CAAC;SAAM,IAAI,OAAO,GAAG,CAAC,iBAAiB,KAAK,QAAQ,IAAI,GAAG,CAAC,iBAAiB,GAAG,CAAC,EAAE,CAAC;QAClF,iBAAiB,GAAG,GAAG,CAAC,iBAAiB,CAAC;IAC5C,CAAC;IAED,IAAI,WAAW,GAAa,EAAE,CAAC;IAC/B,IAAI,OAAO,EAAE,CAAC;QACZ,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACxE,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;QAC1C,WAAW,GAAG,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC;IACrC,CAAC;IAED,MAAM,gBAAgB,GAAG,cAAc,IAAI,IAAI,IAAI,MAAM,CAAC,cAAc,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE;QACrF,CAAC,CAAC,WAAW,CAAC,cAAc,CAAC;QAC7B,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAElC,IAAI,0BAA0B,GAAG,KAAK,CAAC;IACvC,IACE,OAAO;QACP,CAAC,gBAAgB;QACjB,QAAQ,IAAI,IAAI;QAChB,eAAe,IAAI,IAAI;QACvB,iBAAiB,IAAI,IAAI,EACzB,CAAC;QACD,eAAe,GAAG,EAAE,CAAC;QACrB,0BAA0B,GAAG,IAAI,CAAC;IACpC,CAAC;IAED,OAAO;QACL,OAAO;QACP,QAAQ;QACR,eAAe;QACf,iBAAiB;QACjB,WAAW;QACX,gBAAgB;QAChB,0BAA0B;KAC3B,CAAC;AACJ,CAAC;AAED,SAAgB,2BAA2B,CAAC,MAAkB;IAC5D,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,GAAG,GAAI,CAAuC,CAAC,GAAG,CAAC;QACzD,MAAM,GAAG,GAAG,GAAG,EAAE,mBAAmB,CAAC;QACrC,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YACnC,OAAO,GAAoC,CAAC;QAC9C,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAgB,kBAAkB,CAAC,UAAyC;IAC1E,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACrF,CAAC;IACD,MAAM,IAAI,GAAG,IAAA,mCAA2B,EAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC;IACnE,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AACzC,CAAC;AAED,SAAgB,kBAAkB,CAAC,KAAmB;IACpD,OAAO;QACL,UAAU,EAAE,kBAAkB,CAAC,KAAK,CAAC,UAAU,CAAC;QAChD,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE;QACrE,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACzB,CAAC;AACJ,CAAC;AAED,SAAgB,gBAAgB,CAAC,GAAoB;IACnD,MAAM,MAAM,GACV,GAAG,CAAC,WAAW;QACf,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAgC,CAAC,CAAC,CAAC;IAC9G,OAAO;QACL,UAAU,EAAE,kBAAkB,CAAC,MAAM,CAAC;QACtC,QAAQ,EAAE,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,QAAQ,IAAI,EAAE;QAC7C,SAAS,EAAE,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,SAAS,IAAI,EAAE;QAChD,QAAQ,EAAE,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,QAAQ,IAAI,EAAE;KAC9C,CAAC;AACJ,CAAC;AAED,SAAgB,UAAU,CAAC,GAAoB;IAC7C,MAAM,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAC7F,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5D,OAAO;QACL,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;QAChB,CAAC,CAAC,QAAQ,IAAI,EAAE;QAChB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;QACpB,CAAC,CAAC,QAAQ,IAAI,EAAE;KACjB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAgB,aAAa,CAAC,CAAkB,EAAE,CAAkB;IAClE,OAAO,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,SAAgB,sBAAsB,CACpC,KAAY,EACZ,WAAmB,EACnB,OAAe,EACf,WAAqB;IAErB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACtE,MAAM,eAAe,GAAsB,EAAE,CAAC;IAC9C,MAAM,WAAW,GAAsB,EAAE,CAAC;IAC1C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IAErC,MAAM,KAAK,GAAG,CAAC,CAAQ,EAAE,EAAE;QACzB,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,IAAA,mBAAW,EAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;YAC7D,MAAM,GAAG,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;YACtC,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACd,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC5B,CAAC;YACD,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,IAAI,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7E,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACpB,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YAC7B,KAAK,CAAC,KAAK,CAAC,CAAC;QACf,CAAC;IACH,CAAC,CAAC;IACF,KAAK,CAAC,KAAK,CAAC,CAAC;IACb,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC;AAC1C,CAAC;AAED,SAAS,eAAe,CAAC,IAAc,EAAE,gBAA6B;IACpE,MAAM,IAAI,GAAI,IAA4B,CAAC,IAAI,CAAC;IAChD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5D,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,gBAAgB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;IACzD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAgB,aAAa,CAAC,QAAgB;IAC5C,IAAI,GAAG,GAAG,cAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,IAAI,YAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC,EAAE,CAAC;YACtD,OAAO,GAAG,CAAC;QACb,CAAC;QACD,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACzC,IAAI,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,YAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YACnE,iFAAiF;YACjF,IAAI,YAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC,EAAE,CAAC;gBAC3D,OAAO,QAAQ,CAAC;YAClB,CAAC;YACD,iEAAiE;YACjE,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,MAAM,MAAM,GAAG,cAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,SAA6B,EAAE,UAA8B;IAC5F,IAAI,CAAC,SAAS,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,CAAC;IACjD,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,oBAAoB,CAAC,CAAC;IAC1G,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAY,CAAC;QACrE,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;YAC7B,CAAC,CAAC,GAAG;YACL,CAAC,CAAC,KAAK,CAAC,OAAO,CAAE,GAAkC,CAAC,YAAY,CAAC;gBAC/D,CAAC,CAAE,GAAmC,CAAC,YAAY;gBACnD,CAAC,CAAC,KAAK,CAAC,OAAO,CAAE,GAAmC,CAAC,aAAa,CAAC;oBACjE,CAAC,CAAE,GAAoC,CAAC,aAAa;oBACrD,CAAC,CAAC,EAAE,CAAC;QACX,OAAO,IAAI;aACR,MAAM,CAAC,CAAC,CAAC,EAAwB,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,CAAC;aACvE,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAgB,8BAA8B,CAAC,iBAAyB,OAAO,CAAC,GAAG,EAAE;IACnF,OAAO,CACL,IAAA,iBAAS,EAAC,sCAAsC,CAAC;QACjD,cAAI,CAAC,IAAI,CAAC,cAAc,EAAE,sCAA8B,CAAC,CAC1D,CAAC;AACJ,CAAC;AAED,SAAgB,4BAA4B,CAC1C,cAAsB,EACtB,OAAgC;IAEhC,MAAM,QAAQ,GAAG,8BAA8B,CAAC,cAAc,CAAC,CAAC;IAChE,YAAE,CAAC,SAAS,CAAC,cAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,YAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACrE,kCAAkC,EAAE,CAAC;IACrC,OAAO,QAAQ,CAAC;AAClB,CAAC;AASD,IAAI,cAAc,GAA+B,IAAI,CAAC;AAEtD,SAAgB,kCAAkC;IAChD,cAAc,GAAG,IAAI,CAAC;AACxB,CAAC;AAED;;;GAGG;AACH,SAAgB,6BAA6B,CAC3C,iBAAyB,OAAO,CAAC,GAAG,EAAE;IAEtC,mFAAmF;IACnF,+DAA+D;IAC/D,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,EAAE,CAAC;QAC5D,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,QAAQ,GAAG,8BAA8B,CAAC,cAAc,CAAC,CAAC;IAChE,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,YAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACjC,IACE,cAAc;YACd,cAAc,CAAC,QAAQ,KAAK,QAAQ;YACpC,cAAc,CAAC,OAAO,KAAK,EAAE,CAAC,OAAO,EACrC,CAAC;YACD,OAAO,EAAE,SAAS,EAAE,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,CAAC,MAAM,EAAE,CAAC;QAChF,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAA4B,CAAC;QACxF,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACvE,cAAc,GAAG,IAAI,CAAC;YACtB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,SAAS,GAA4B;YACzC,GAAG,MAAM;YACT,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,gBAAgB,CAAC;SAC1D,CAAC;QACF,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1E,cAAc,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QACtE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,cAAc,GAAG,IAAI,CAAC;QACtB,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAgB,2BAA2B,CACzC,iBAAyB,OAAO,CAAC,GAAG,EAAE;IAEtC,OAAO,6BAA6B,CAAC,cAAc,CAAC,EAAE,SAAS,CAAC;AAClE,CAAC;AAED,SAAgB,6BAA6B,CAAC,QAAmC;IAC/E,IAAI,CAAC,QAAQ;QAAE,OAAO;IACtB,IAAI,CAAC;QACH,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;IACD,kCAAkC,EAAE,CAAC;AACvC,CAAC;AAED,2EAA2E;AAC3E,SAAgB,aAAa,CAAC,GAAG,KAA0B;IACzD,MAAM,GAAG,GAAG,IAAI,GAAG,EAA2B,CAAC;IAC/C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;YAChC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;AAC3B,CAAC;AAED,SAAgB,iBAAiB,CAC/B,KAAmB,EACnB,QAA2B,EAC3B,MAAoB;IAEpB,MAAM,GAAG,GAAG,UAAU,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;IAClD,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACnC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;AACrD,CAAC;AAED,SAAgB,gCAAgC,CAC9C,WAAuE,EACvE,qBAA8B;IAE9B,IAAI,CAAC,WAAW,EAAE,MAAM,IAAI,CAAC,qBAAqB;QAAE,OAAO,SAAS,CAAC;IACrE,KAAK,MAAM,CAAC,IAAI,WAAW,IAAI,EAAE,EAAE,CAAC;QAClC,IAAI,CAAC,CAAC,IAAI,KAAK,aAAa,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,CAAC;YACtD,OAAO,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QAC9B,CAAC;IACH,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,WAAW,IAAI,EAAE,EAAE,CAAC;QAClC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,CAAC;YACrE,OAAO,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QAC9B,CAAC;IACH,CAAC;IACD,MAAM,GAAG,GAAG,qBAAqB,EAAE,IAAI,EAAE,CAAC;IAC1C,OAAO,GAAG,IAAI,SAAS,CAAC;AAC1B,CAAC;AAED,SAAgB,sBAAsB,CAAC,QAItC;IACC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC3D,MAAM,MAAM,GAAG,6BAA6B,CAAC,OAAO,CAAC,CAAC;IACtD,IAAI,CAAC,MAAM;QAAE,OAAO;IACpB,MAAM,WAAW,GAAG,IAAA,iBAAS,EAAC,wBAAwB,CAAC,IAAI,OAAO,CAAC;IACnE,MAAM,KAAK,GAAG,IAAA,+BAAuB,EAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IACtE,IAAI,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC;QAAE,OAAO;IACpF,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,+BAAuB,EAAE,CAAC,CAAC;IACzF,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,+BAAuB,CAAC,CAAC;AAC/C,CAAC;AAED,SAAgB,aAAa,CAAC,GAAoB;IAChD,MAAM,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAChC,OAAO;QACL,WAAW,EAAE,CAAC,CAAC,UAAU,IAAI,EAAE;QAC/B,SAAS,EAAE,CAAC,CAAC,QAAQ,IAAI,EAAE;QAC3B,UAAU,EAAE,CAAC,CAAC,SAAS,IAAI,EAAE;QAC7B,SAAS,EAAE,CAAC,CAAC,QAAQ,IAAI,EAAE;KAC5B,CAAC;AACJ,CAAC;AAED,SAAgB,eAAe,CAAC,GAA4B;IAC1D,OAAO,gBAAgB,CAAC;QACtB,WAAW,EAAE,GAAG,CAAC,WAAmC;QACpD,UAAU,EAAE,GAAG,CAAC,UAA2C;QAC3D,SAAS,EAAE,GAAG,CAAC,SAA+B;QAC9C,QAAQ,EAAE,GAAG,CAAC,QAA8B;QAC5C,UAAU,EAAE,GAAG,CAAC,UAAkC;QAClD,SAAS,EAAE,GAAG,CAAC,SAAiC;QAChD,SAAS,EAAE,GAAG,CAAC,SAA+B;QAC9C,QAAQ,EAAE,GAAG,CAAC,QAA8B;KAC7C,CAAC,CAAC;AACL,CAAC"}
@@ -33,6 +33,8 @@ export declare class TestChimpReporter implements Reporter {
33
33
  /** Path we wrote for this run; unlinked in onEnd when write succeeded. */
34
34
  private batchInvocationFileWrittenPath;
35
35
  private shouldUnlinkBatchInvocationFile;
36
+ /** Smart-smoke selection sidecar written in onBegin; unlinked in onEnd. */
37
+ private smartSmokeSelectionFilePath;
36
38
  private testsFolder;
37
39
  private testExecutions;
38
40
  private testRetryInfo;
@@ -54,7 +56,7 @@ export declare class TestChimpReporter implements Reporter {
54
56
  /** Idempotency: same journey execution id must not POST journey_execution_end twice (CI + platform + finally). */
55
57
  private exploreChimpJourneyEndSentIds;
56
58
  constructor(options?: TestChimpReporterOptions);
57
- onBegin(config: FullConfig, suite: Suite): void;
59
+ onBegin(config: FullConfig, suite: Suite): Promise<void>;
58
60
  private loadJobManifest;
59
61
  /**
60
62
  * Resolve jobId from the platform manifest.
@@ -90,6 +92,12 @@ export declare class TestChimpReporter implements Reporter {
90
92
  onEnd(result: FullResult): Promise<void>;
91
93
  /** Align ExploreChimp workers with suite batch id (env then file); same path as {@link readTestChimpBatchInvocationId}. */
92
94
  private writeSuiteBatchInvocationFileForExploreChimp;
95
+ /**
96
+ * When TESTCHIMP_SMART_SMOKE_ENABLED, select a subset and write a sidecar for workers.
97
+ * When disabled, remove any leftover sidecar so a prior crashed run cannot skip the suite.
98
+ */
99
+ private maybeRunSmartSmokeSelection;
100
+ private naiveLocalSuiteSlice;
93
101
  private unlinkSuiteBatchInvocationFileIfWritten;
94
102
  private getTestKey;
95
103
  private platformFinalizeTestEnd;
@@ -1 +1 @@
1
- {"version":3,"file":"testchimp-reporter.d.ts","sourceRoot":"","sources":["../src/testchimp-reporter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"testchimp-reporter.d.ts","sourceRoot":"","sources":["../src/testchimp-reporter.ts"],"names":[],"mappings":"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"}
@@ -9,10 +9,12 @@ const sharp_1 = __importDefault(require("sharp"));
9
9
  const api_client_1 = require("./api-client");
10
10
  const types_1 = require("./types");
11
11
  const execution_context_1 = require("./execution-context");
12
+ const annotations_1 = require("./annotations");
12
13
  const utils_1 = require("./utils");
13
14
  const index_1 = require("./explorechimp/index");
14
15
  const analytics_step_screen_state_registry_1 = require("./explorechimp/analytics-step-screen-state-registry");
15
16
  const capture_1 = require("./api-coverage/capture");
17
+ const smart_smoke_1 = require("./smart-smoke");
16
18
  const path_1 = __importDefault(require("path"));
17
19
  function resolveDurationMs(reportedDurationMs, startedAtMillis, completedAtMillis) {
18
20
  if (typeof reportedDurationMs === 'number' &&
@@ -46,6 +48,8 @@ class TestChimpReporter {
46
48
  /** Path we wrote for this run; unlinked in onEnd when write succeeded. */
47
49
  this.batchInvocationFileWrittenPath = null;
48
50
  this.shouldUnlinkBatchInvocationFile = false;
51
+ /** Smart-smoke selection sidecar written in onBegin; unlinked in onEnd. */
52
+ this.smartSmokeSelectionFilePath = null;
49
53
  this.testsFolder = '';
50
54
  // Track test executions (keyed by test ID + attempt, e.g. "testId_attempt_0", "testId_attempt_1").
51
55
  // In platform mode we keep all attempts until test_end so the job detail we send includes full retryAttemptLogs.
@@ -94,7 +98,7 @@ class TestChimpReporter {
94
98
  executionMode
95
99
  };
96
100
  }
97
- onBegin(config, suite) {
101
+ async onBegin(config, suite) {
98
102
  this.config = config;
99
103
  this.batchInvocationId = (0, utils_1.getEnvVar)('TESTCHIMP_BATCH_INVOCATION_ID', this.options.batchInvocationId) || (0, utils_1.generateUUID)();
100
104
  this.writeSuiteBatchInvocationFileForExploreChimp();
@@ -120,6 +124,7 @@ class TestChimpReporter {
120
124
  if (!apiKey && this.options.executionMode !== 'repair') {
121
125
  console.warn('[TestChimp] Missing TESTCHIMP_API_KEY. Reporting disabled.');
122
126
  this.isEnabled = false;
127
+ await this.maybeRunSmartSmokeSelection(suite, null);
123
128
  return;
124
129
  }
125
130
  this.apiClient = new api_client_1.TestChimpApiClient(backendUrl, apiKey || 'local-repair', projectId || '', this.options.verbose);
@@ -156,6 +161,7 @@ class TestChimpReporter {
156
161
  }
157
162
  // Scan suite to understand retry configuration
158
163
  this.scanTestRetries(suite);
164
+ await this.maybeRunSmartSmokeSelection(suite, this.apiClient);
159
165
  }
160
166
  loadJobManifest() {
161
167
  const manifestPath = (0, utils_1.getEnvVar)('TESTCHIMP_JOB_MANIFEST_PATH') ||
@@ -244,10 +250,16 @@ class TestChimpReporter {
244
250
  buildFinalJobDetailForPlatform(test, result, testName, currentSteps) {
245
251
  const status = this.mapStatus(result.status);
246
252
  const jobDetail = this.buildJobDetailFromAttempts(test.id, testName, result.retry, true, status, result.error?.message);
253
+ const annotations = (0, annotations_1.collectPlaywrightAnnotations)(test, result);
254
+ const skipReason = status === types_1.SmartTestExecutionStatus.SMART_TEST_EXECUTION_SKIPPED
255
+ ? (0, smart_smoke_1.resolveSkipReasonFromAnnotations)(annotations, result.error?.message)
256
+ : undefined;
247
257
  return {
248
258
  ...jobDetail,
249
259
  steps: [...currentSteps],
250
- pwError: this.toPlaywrightError(result.error)
260
+ pwError: this.toPlaywrightError(result.error),
261
+ annotations,
262
+ skipReason,
251
263
  };
252
264
  }
253
265
  onTestBegin(test, result) {
@@ -646,6 +658,8 @@ class TestChimpReporter {
646
658
  }
647
659
  finally {
648
660
  this.unlinkSuiteBatchInvocationFileIfWritten();
661
+ (0, smart_smoke_1.unlinkSmartSmokeSelectionFile)(this.smartSmokeSelectionFilePath);
662
+ this.smartSmokeSelectionFilePath = null;
649
663
  }
650
664
  }
651
665
  // ============================================================================
@@ -667,6 +681,96 @@ class TestChimpReporter {
667
681
  this.shouldUnlinkBatchInvocationFile = false;
668
682
  }
669
683
  }
684
+ /**
685
+ * When TESTCHIMP_SMART_SMOKE_ENABLED, select a subset and write a sidecar for workers.
686
+ * When disabled, remove any leftover sidecar so a prior crashed run cannot skip the suite.
687
+ */
688
+ async maybeRunSmartSmokeSelection(suite, apiClient) {
689
+ const rootDir = this.config?.rootDir || process.cwd();
690
+ const useOpts = (0, smart_smoke_1.readSmartSmokeUseFromConfig)(this.config);
691
+ const smoke = (0, smart_smoke_1.resolveSmartSmokeConfig)(useOpts);
692
+ if (!smoke.enabled) {
693
+ (0, smart_smoke_1.unlinkSmartSmokeSelectionFile)((0, smart_smoke_1.getSmartSmokeSelectionFilePath)(rootDir));
694
+ return;
695
+ }
696
+ if (smoke.usedDefaultSuitePercentage) {
697
+ console.warn('[TestChimp] Smart-smoke: no size constraint from env or use.testchimpSmartSmoke — defaulting to suitePercentage=20');
698
+ }
699
+ const branchName = (0, utils_1.getBranchName)();
700
+ const plansRoot = (0, smart_smoke_1.findPlansRoot)(rootDir);
701
+ if (!plansRoot) {
702
+ console.warn(`[TestChimp] Smart-smoke: could not find plans root (.testchimp-plans or plans/) under ${rootDir}; related-tests.json will be empty`);
703
+ }
704
+ else if (!branchName) {
705
+ console.warn('[TestChimp] Smart-smoke: branch name unresolved (set TESTCHIMP_BRANCH_NAME); related-tests.json will be empty');
706
+ }
707
+ const relatedTests = (0, smart_smoke_1.loadRelatedTests)(plansRoot, branchName);
708
+ const { suiteCandidates, taggedTests } = (0, smart_smoke_1.collectSuiteCandidates)(suite, this.testsFolder, rootDir, smoke.includeTags);
709
+ const mustInclude = (0, smart_smoke_1.unionLocators)(relatedTests, taggedTests);
710
+ let selected;
711
+ if (smoke.relatedTestsOnly) {
712
+ selected = (0, smart_smoke_1.unionLocators)(relatedTests);
713
+ console.log(`[TestChimp] Smart-smoke related-tests-only: ${selected.length} test(s) from related-tests.json (branch=${branchName || '(unknown)'})`);
714
+ }
715
+ else if (apiClient) {
716
+ try {
717
+ // Phase-1 server only uses suite_candidates when must_include is empty — omit otherwise
718
+ // to avoid large POST bodies on big suites.
719
+ const resp = await apiClient.selectSmartSmokeTests({
720
+ related_tests: relatedTests.map(smart_smoke_1.toWireLocator),
721
+ include_tags: smoke.includeTags,
722
+ tagged_tests: taggedTests.map(smart_smoke_1.toWireLocator),
723
+ suite_candidates: mustInclude.length === 0 ? suiteCandidates.map(smart_smoke_1.toWireLocator) : [],
724
+ max_time_budget_mins: smoke.maxTimeBudgetMins,
725
+ max_tests: smoke.maxTests,
726
+ suite_percentage: smoke.suitePercentage,
727
+ branch_name: branchName,
728
+ environment: this.options.environment || undefined,
729
+ });
730
+ selected = (resp.selectedTests || []).map((r) => (0, smart_smoke_1.fromWireLocator)(r));
731
+ console.log(`[TestChimp] Smart-smoke selection API returned ${selected.length} test(s) (candidates=${suiteCandidates.length}, related=${relatedTests.length}, tagged=${taggedTests.length})`);
732
+ }
733
+ catch (e) {
734
+ selected = mustInclude;
735
+ console.warn(`[TestChimp] Smart-smoke selection API failed; falling back to related∪tagged (${selected.length}):`, e);
736
+ if (selected.length === 0 && suiteCandidates.length > 0) {
737
+ selected = this.naiveLocalSuiteSlice(suiteCandidates, smoke);
738
+ console.warn(`[TestChimp] Smart-smoke local naive slice: ${selected.length} of ${suiteCandidates.length}`);
739
+ }
740
+ }
741
+ }
742
+ else {
743
+ selected = mustInclude;
744
+ if (selected.length === 0 && suiteCandidates.length > 0) {
745
+ selected = this.naiveLocalSuiteSlice(suiteCandidates, smoke);
746
+ }
747
+ console.warn(`[TestChimp] Smart-smoke: no API client; local selection ${selected.length} test(s)`);
748
+ }
749
+ if (selected.length === 0) {
750
+ console.warn('[TestChimp] Smart-smoke: selection is empty — all tests will be skipped. Check related-tests.json / tags / budget.');
751
+ }
752
+ try {
753
+ this.smartSmokeSelectionFilePath = (0, smart_smoke_1.writeSmartSmokeSelectionFile)(rootDir, {
754
+ enabled: true,
755
+ selectedTests: selected,
756
+ relatedTestsOnly: smoke.relatedTestsOnly,
757
+ branchName,
758
+ });
759
+ console.log(`[TestChimp] Smart-smoke selection written: ${this.smartSmokeSelectionFilePath} (${selected.length} test(s))`);
760
+ }
761
+ catch (e) {
762
+ console.error('[TestChimp] Smart-smoke: failed to write selection file:', e);
763
+ this.smartSmokeSelectionFilePath = null;
764
+ }
765
+ }
766
+ naiveLocalSuiteSlice(suiteCandidates, smoke) {
767
+ const pct = smoke.suitePercentage ?? 20;
768
+ let n = Math.max(1, Math.ceil(suiteCandidates.length * (pct / 100)));
769
+ if (smoke.maxTests != null && smoke.maxTests > 0) {
770
+ n = Math.min(n, smoke.maxTests);
771
+ }
772
+ return suiteCandidates.slice(0, n);
773
+ }
670
774
  unlinkSuiteBatchInvocationFileIfWritten() {
671
775
  if (!this.shouldUnlinkBatchInvocationFile || !this.batchInvocationFileWrittenPath)
672
776
  return;
@@ -879,6 +983,10 @@ class TestChimpReporter {
879
983
  const status = this.mapStatus(result.status);
880
984
  const executionContext = (0, execution_context_1.buildExecutionDeviceContext)(test);
881
985
  const completedAtMillis = Date.now();
986
+ const annotations = (0, annotations_1.collectPlaywrightAnnotations)(test, result);
987
+ const skipReason = status === types_1.SmartTestExecutionStatus.SMART_TEST_EXECUTION_SKIPPED
988
+ ? (0, smart_smoke_1.resolveSkipReasonFromAnnotations)(annotations, result.error?.message)
989
+ : undefined;
882
990
  const report = {
883
991
  folderPath: paths.folderPath,
884
992
  fileName: paths.fileName,
@@ -896,6 +1004,8 @@ class TestChimpReporter {
896
1004
  scenarioCoverageResults: [], // Backend will populate if empty
897
1005
  executionContext,
898
1006
  gitCommitSha,
1007
+ annotations,
1008
+ skipReason,
899
1009
  },
900
1010
  startedAtMillis: execution.startedAt,
901
1011
  completedAtMillis,
@@ -904,6 +1014,7 @@ class TestChimpReporter {
904
1014
  branchId: branchIdValid,
905
1015
  gitCommitSha,
906
1016
  executionContext,
1017
+ annotations,
907
1018
  };
908
1019
  const exploreChimpJobId = this.exploreChimpJourneyExecutionJobId(test, result, paths);
909
1020
  if (exploreChimpJobId) {