flakiness 0.309.0 → 0.311.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.
package/lib/cli/cli.js CHANGED
@@ -3,68 +3,6 @@
3
3
  // src/cli/cli.ts
4
4
  import { showReport } from "@flakiness/sdk";
5
5
 
6
- // ../node_modules/.pnpm/vlq@2.0.4/node_modules/vlq/src/index.js
7
- var char_to_integer = {};
8
- var integer_to_char = {};
9
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".split("").forEach(function(char, i) {
10
- char_to_integer[char] = i;
11
- integer_to_char[i] = char;
12
- });
13
- function decode(string) {
14
- let result = [];
15
- let shift = 0;
16
- let value = 0;
17
- for (let i = 0; i < string.length; i += 1) {
18
- let integer = char_to_integer[string[i]];
19
- if (integer === void 0) {
20
- throw new Error("Invalid character (" + string[i] + ")");
21
- }
22
- const has_continuation_bit = integer & 32;
23
- integer &= 31;
24
- value += integer << shift;
25
- if (has_continuation_bit) {
26
- shift += 5;
27
- } else {
28
- const should_negate = value & 1;
29
- value >>>= 1;
30
- if (should_negate) {
31
- result.push(value === 0 ? -2147483648 : -value);
32
- } else {
33
- result.push(value);
34
- }
35
- value = shift = 0;
36
- }
37
- }
38
- return result;
39
- }
40
- function encode(value) {
41
- if (typeof value === "number") {
42
- return encode_integer(value);
43
- }
44
- let result = "";
45
- for (let i = 0; i < value.length; i += 1) {
46
- result += encode_integer(value[i]);
47
- }
48
- return result;
49
- }
50
- function encode_integer(num) {
51
- let result = "";
52
- if (num < 0) {
53
- num = -num << 1 | 1;
54
- } else {
55
- num <<= 1;
56
- }
57
- do {
58
- let clamped = num & 31;
59
- num >>>= 5;
60
- if (num > 0) {
61
- clamped |= 32;
62
- }
63
- result += integer_to_char[clamped];
64
- } while (num > 0);
65
- return result;
66
- }
67
-
68
6
  // ../server/lib/common/heap.js
69
7
  var Heap = class _Heap {
70
8
  constructor(_cmp, elements = []) {
@@ -288,6 +226,105 @@ function quickAdvance(sequences, cmp, k) {
288
226
  return sequences.map((seq) => offsets.get(seq) ?? seq.length);
289
227
  }
290
228
 
229
+ // ../server/lib/common/vlq64.js
230
+ var VLQ64;
231
+ ((VLQ642) => {
232
+ const CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
233
+ const VALUES = new Int8Array(128).fill(-1);
234
+ for (let i = 0; i < CHARS.length; ++i)
235
+ VALUES[CHARS.charCodeAt(i)] = i;
236
+ const DIGIT_BITS = 5;
237
+ const CONTINUATION = 32;
238
+ const MASK = 31;
239
+ const MAX_NARROW_SHIFT = 30;
240
+ VLQ642.MAX_MAGNITUDE = 2 ** 52 - 1;
241
+ function encode(values) {
242
+ let result = "";
243
+ for (const value of values) {
244
+ if ((value | 0) !== value || value === -2147483648) {
245
+ result += encodeWide(value);
246
+ continue;
247
+ }
248
+ let rest = value < 0 ? -value << 1 | 1 : value << 1;
249
+ do {
250
+ let digit = rest & MASK;
251
+ rest >>>= DIGIT_BITS;
252
+ if (rest > 0)
253
+ digit |= CONTINUATION;
254
+ result += CHARS[digit];
255
+ } while (rest > 0);
256
+ }
257
+ return result;
258
+ }
259
+ VLQ642.encode = encode;
260
+ function encodeWide(value) {
261
+ if (!Number.isInteger(value) || value < -VLQ642.MAX_MAGNITUDE || value > VLQ642.MAX_MAGNITUDE)
262
+ throw new Error(`Cannot VLQ-encode ${value}: expected an integer within +/-${VLQ642.MAX_MAGNITUDE}`);
263
+ let result = "";
264
+ let rest = value < 0 ? -value * 2 + 1 : value * 2;
265
+ do {
266
+ let digit = rest % CONTINUATION;
267
+ rest = Math.floor(rest / CONTINUATION);
268
+ if (rest > 0)
269
+ digit += CONTINUATION;
270
+ result += CHARS[digit];
271
+ } while (rest > 0);
272
+ return result;
273
+ }
274
+ function decode(encoded) {
275
+ const result = [];
276
+ let value = 0;
277
+ let shift = 0;
278
+ for (let i = 0; i < encoded.length; ++i) {
279
+ const digit = digitAt(encoded, i);
280
+ value += (digit & MASK) << shift;
281
+ if (digit & CONTINUATION) {
282
+ shift += DIGIT_BITS;
283
+ if (shift === MAX_NARROW_SHIFT) {
284
+ i = decodeWide(encoded, i + 1, value, result);
285
+ value = 0;
286
+ shift = 0;
287
+ }
288
+ continue;
289
+ }
290
+ if (value === 1)
291
+ result.push(-2147483648);
292
+ else
293
+ result.push(value & 1 ? -(value >>> 1) : value >>> 1);
294
+ value = 0;
295
+ shift = 0;
296
+ }
297
+ return result;
298
+ }
299
+ VLQ642.decode = decode;
300
+ function decodeWide(encoded, start, value, result) {
301
+ let scale = 2 ** MAX_NARROW_SHIFT;
302
+ for (let i = start; i < encoded.length; ++i) {
303
+ const digit = digitAt(encoded, i);
304
+ value += (digit & MASK) * scale;
305
+ if (digit & CONTINUATION) {
306
+ scale *= CONTINUATION;
307
+ continue;
308
+ }
309
+ const negative = value % 2 === 1;
310
+ const magnitude = (value - (negative ? 1 : 0)) / 2;
311
+ if (negative && magnitude === 0)
312
+ result.push(-2147483648);
313
+ else
314
+ result.push(negative ? -magnitude : magnitude);
315
+ return i;
316
+ }
317
+ return encoded.length;
318
+ }
319
+ function digitAt(encoded, i) {
320
+ const code = encoded.charCodeAt(i);
321
+ const digit = code < 128 ? VALUES[code] : -1;
322
+ if (digit < 0)
323
+ throw new Error(`Cannot VLQ-decode: invalid character ${JSON.stringify(encoded[i])} at ${i}`);
324
+ return digit;
325
+ }
326
+ })(VLQ64 || (VLQ64 = {}));
327
+
291
328
  // ../server/lib/common/ranges.js
292
329
  var Ranges;
293
330
  ((Ranges2) => {
@@ -314,13 +351,13 @@ var Ranges;
314
351
  }
315
352
  last = ranges[i + 1];
316
353
  }
317
- return encode(prepared);
354
+ return VLQ64.encode(prepared);
318
355
  }
319
356
  Ranges2.compress = compress;
320
357
  function decompress(compressed) {
321
358
  if (!compressed.length)
322
359
  return [];
323
- const prepared = decode(compressed);
360
+ const prepared = VLQ64.decode(compressed);
324
361
  const result = [];
325
362
  let last = prepared[0];
326
363
  for (let i = 1; i < prepared.length; ++i) {
@@ -1101,7 +1138,7 @@ import { Temporal as Temporal2 } from "temporal-polyfill";
1101
1138
  // ../package.json
1102
1139
  var package_default = {
1103
1140
  name: "@flakiness/monorepo",
1104
- version: "0.309.0",
1141
+ version: "0.311.0",
1105
1142
  type: "module",
1106
1143
  private: true,
1107
1144
  scripts: {
@@ -1991,11 +2028,134 @@ async function downloadRun(api, project, runId) {
1991
2028
  await fs4.promises.rename(tmpDir, finalDir);
1992
2029
  }
1993
2030
 
2031
+ // ../server/lib/common/stats/envGroup.js
2032
+ import { FlakinessReport } from "@flakiness/flakiness-report";
2033
+
2034
+ // ../shared/lib/common/multimap.js
2035
+ var Multimap = class _Multimap {
2036
+ static fromEntries(entries) {
2037
+ const m = new _Multimap();
2038
+ for (const [key, value] of entries)
2039
+ m.set(key, value);
2040
+ return m;
2041
+ }
2042
+ _map = /* @__PURE__ */ new Map();
2043
+ constructor(entries = []) {
2044
+ for (const [k, v] of entries)
2045
+ this.set(k, v);
2046
+ }
2047
+ addAllFromMap(map) {
2048
+ for (const [key, value] of map)
2049
+ this.set(key, value);
2050
+ }
2051
+ map(callback) {
2052
+ const result = [];
2053
+ for (const [key, value] of this._map)
2054
+ result.push(callback(key, value));
2055
+ return result;
2056
+ }
2057
+ [Symbol.iterator]() {
2058
+ return this._map.entries();
2059
+ }
2060
+ hasAny(key) {
2061
+ return this._map.has(key);
2062
+ }
2063
+ has(key, value) {
2064
+ return this._map.get(key)?.has(value) ?? false;
2065
+ }
2066
+ set(key, value) {
2067
+ let s = this._map.get(key);
2068
+ if (!s) {
2069
+ s = /* @__PURE__ */ new Set();
2070
+ this._map.set(key, s);
2071
+ }
2072
+ s.add(value);
2073
+ }
2074
+ get size() {
2075
+ return this._map.size;
2076
+ }
2077
+ setAll(key, values) {
2078
+ let s = this._map.get(key);
2079
+ if (!s) {
2080
+ s = /* @__PURE__ */ new Set();
2081
+ this._map.set(key, s);
2082
+ }
2083
+ for (const v of values)
2084
+ s.add(v);
2085
+ }
2086
+ delete(key, value) {
2087
+ let s = this._map.get(key);
2088
+ if (!s)
2089
+ return;
2090
+ s.delete(value);
2091
+ if (!s.size)
2092
+ this._map.delete(key);
2093
+ }
2094
+ keys() {
2095
+ return this._map.keys();
2096
+ }
2097
+ *values() {
2098
+ for (const set of this._map.values())
2099
+ yield* set.keys();
2100
+ }
2101
+ getAll(key) {
2102
+ let s = this._map.get(key);
2103
+ return s ? [...s] : [];
2104
+ }
2105
+ getFirst(key) {
2106
+ let s = this._map.get(key);
2107
+ if (!s)
2108
+ return void 0;
2109
+ return s.values().next().value;
2110
+ }
2111
+ count(key) {
2112
+ let s = this._map.get(key);
2113
+ return s ? s.size : 0;
2114
+ }
2115
+ deleteAll(key) {
2116
+ this._map.delete(key);
2117
+ }
2118
+ clear() {
2119
+ this._map.clear();
2120
+ }
2121
+ clone() {
2122
+ const m = new _Multimap();
2123
+ for (const [key, values] of this._map)
2124
+ m._map.set(key, new Set(values));
2125
+ return m;
2126
+ }
2127
+ };
2128
+
2129
+ // ../node_modules/.pnpm/stable-hash@0.0.6/node_modules/stable-hash/dist/index.mjs
2130
+ var o = /* @__PURE__ */ new WeakMap();
2131
+ var u = 0;
2132
+ function stableHash(t2) {
2133
+ const i = typeof t2, s = t2 && t2.constructor, c = s === Date;
2134
+ if (Object(t2) === t2 && !c && s != RegExp) {
2135
+ let e2 = o.get(t2);
2136
+ if (e2) return e2;
2137
+ e2 = ++u + "~", o.set(t2, e2);
2138
+ let n;
2139
+ if (s === Array) {
2140
+ for (e2 = "@", n = 0; n < t2.length; n++) e2 += stableHash(t2[n]) + ",";
2141
+ o.set(t2, e2);
2142
+ } else if (s === Object) {
2143
+ e2 = "#";
2144
+ const f = Object.keys(t2).sort();
2145
+ for (; (n = f.pop()) !== void 0; ) t2[n] !== void 0 && (e2 += n + ":" + stableHash(t2[n]) + ",");
2146
+ o.set(t2, e2);
2147
+ }
2148
+ return e2;
2149
+ }
2150
+ return c ? t2.toJSON() : i === "symbol" ? t2.toString() : i === "string" ? JSON.stringify(t2) : "" + t2;
2151
+ }
2152
+ var dist_default = stableHash;
2153
+
1994
2154
  // ../node_modules/.pnpm/xxhash-wasm@1.1.0/node_modules/xxhash-wasm/esm/xxhash-wasm.js
1995
2155
  var t = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 48, 8, 96, 3, 127, 127, 127, 1, 127, 96, 3, 127, 127, 127, 0, 96, 2, 127, 127, 0, 96, 1, 127, 1, 127, 96, 3, 127, 127, 126, 1, 126, 96, 3, 126, 127, 127, 1, 126, 96, 2, 127, 126, 0, 96, 1, 127, 1, 126, 3, 11, 10, 0, 0, 2, 1, 3, 4, 5, 6, 1, 7, 5, 3, 1, 0, 1, 7, 85, 9, 3, 109, 101, 109, 2, 0, 5, 120, 120, 104, 51, 50, 0, 0, 6, 105, 110, 105, 116, 51, 50, 0, 2, 8, 117, 112, 100, 97, 116, 101, 51, 50, 0, 3, 8, 100, 105, 103, 101, 115, 116, 51, 50, 0, 4, 5, 120, 120, 104, 54, 52, 0, 5, 6, 105, 110, 105, 116, 54, 52, 0, 7, 8, 117, 112, 100, 97, 116, 101, 54, 52, 0, 8, 8, 100, 105, 103, 101, 115, 116, 54, 52, 0, 9, 10, 251, 22, 10, 242, 1, 1, 4, 127, 32, 0, 32, 1, 106, 33, 3, 32, 1, 65, 16, 79, 4, 127, 32, 3, 65, 16, 107, 33, 6, 32, 2, 65, 168, 136, 141, 161, 2, 106, 33, 3, 32, 2, 65, 137, 235, 208, 208, 7, 107, 33, 4, 32, 2, 65, 207, 140, 162, 142, 6, 106, 33, 5, 3, 64, 32, 3, 32, 0, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 3, 32, 4, 32, 0, 65, 4, 106, 34, 0, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 4, 32, 2, 32, 0, 65, 4, 106, 34, 0, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 2, 32, 5, 32, 0, 65, 4, 106, 34, 0, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 5, 32, 6, 32, 0, 65, 4, 106, 34, 0, 79, 13, 0, 11, 32, 2, 65, 12, 119, 32, 5, 65, 18, 119, 106, 32, 4, 65, 7, 119, 106, 32, 3, 65, 1, 119, 106, 5, 32, 2, 65, 177, 207, 217, 178, 1, 106, 11, 32, 1, 106, 32, 0, 32, 1, 65, 15, 113, 16, 1, 11, 146, 1, 0, 32, 1, 32, 2, 106, 33, 2, 3, 64, 32, 1, 65, 4, 106, 32, 2, 75, 69, 4, 64, 32, 0, 32, 1, 40, 2, 0, 65, 189, 220, 202, 149, 124, 108, 106, 65, 17, 119, 65, 175, 214, 211, 190, 2, 108, 33, 0, 32, 1, 65, 4, 106, 33, 1, 12, 1, 11, 11, 3, 64, 32, 1, 32, 2, 79, 69, 4, 64, 32, 0, 32, 1, 45, 0, 0, 65, 177, 207, 217, 178, 1, 108, 106, 65, 11, 119, 65, 177, 243, 221, 241, 121, 108, 33, 0, 32, 1, 65, 1, 106, 33, 1, 12, 1, 11, 11, 32, 0, 32, 0, 65, 15, 118, 115, 65, 247, 148, 175, 175, 120, 108, 34, 0, 65, 13, 118, 32, 0, 115, 65, 189, 220, 202, 149, 124, 108, 34, 0, 65, 16, 118, 32, 0, 115, 11, 63, 0, 32, 0, 65, 8, 106, 32, 1, 65, 168, 136, 141, 161, 2, 106, 54, 2, 0, 32, 0, 65, 12, 106, 32, 1, 65, 137, 235, 208, 208, 7, 107, 54, 2, 0, 32, 0, 65, 16, 106, 32, 1, 54, 2, 0, 32, 0, 65, 20, 106, 32, 1, 65, 207, 140, 162, 142, 6, 106, 54, 2, 0, 11, 195, 4, 1, 6, 127, 32, 1, 32, 2, 106, 33, 6, 32, 0, 65, 24, 106, 33, 4, 32, 0, 65, 40, 106, 40, 2, 0, 33, 3, 32, 0, 32, 0, 40, 2, 0, 32, 2, 106, 54, 2, 0, 32, 0, 65, 4, 106, 34, 5, 32, 5, 40, 2, 0, 32, 2, 65, 16, 79, 32, 0, 40, 2, 0, 65, 16, 79, 114, 114, 54, 2, 0, 32, 2, 32, 3, 106, 65, 16, 73, 4, 64, 32, 3, 32, 4, 106, 32, 1, 32, 2, 252, 10, 0, 0, 32, 0, 65, 40, 106, 32, 2, 32, 3, 106, 54, 2, 0, 15, 11, 32, 3, 4, 64, 32, 3, 32, 4, 106, 32, 1, 65, 16, 32, 3, 107, 34, 2, 252, 10, 0, 0, 32, 0, 65, 8, 106, 34, 3, 32, 3, 40, 2, 0, 32, 4, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 54, 2, 0, 32, 0, 65, 12, 106, 34, 3, 32, 3, 40, 2, 0, 32, 4, 65, 4, 106, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 54, 2, 0, 32, 0, 65, 16, 106, 34, 3, 32, 3, 40, 2, 0, 32, 4, 65, 8, 106, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 54, 2, 0, 32, 0, 65, 20, 106, 34, 3, 32, 3, 40, 2, 0, 32, 4, 65, 12, 106, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 54, 2, 0, 32, 0, 65, 40, 106, 65, 0, 54, 2, 0, 32, 1, 32, 2, 106, 33, 1, 11, 32, 1, 32, 6, 65, 16, 107, 77, 4, 64, 32, 6, 65, 16, 107, 33, 8, 32, 0, 65, 8, 106, 40, 2, 0, 33, 2, 32, 0, 65, 12, 106, 40, 2, 0, 33, 3, 32, 0, 65, 16, 106, 40, 2, 0, 33, 5, 32, 0, 65, 20, 106, 40, 2, 0, 33, 7, 3, 64, 32, 2, 32, 1, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 2, 32, 3, 32, 1, 65, 4, 106, 34, 1, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 3, 32, 5, 32, 1, 65, 4, 106, 34, 1, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 5, 32, 7, 32, 1, 65, 4, 106, 34, 1, 40, 2, 0, 65, 247, 148, 175, 175, 120, 108, 106, 65, 13, 119, 65, 177, 243, 221, 241, 121, 108, 33, 7, 32, 8, 32, 1, 65, 4, 106, 34, 1, 79, 13, 0, 11, 32, 0, 65, 8, 106, 32, 2, 54, 2, 0, 32, 0, 65, 12, 106, 32, 3, 54, 2, 0, 32, 0, 65, 16, 106, 32, 5, 54, 2, 0, 32, 0, 65, 20, 106, 32, 7, 54, 2, 0, 11, 32, 1, 32, 6, 73, 4, 64, 32, 4, 32, 1, 32, 6, 32, 1, 107, 34, 1, 252, 10, 0, 0, 32, 0, 65, 40, 106, 32, 1, 54, 2, 0, 11, 11, 97, 1, 1, 127, 32, 0, 65, 16, 106, 40, 2, 0, 33, 1, 32, 0, 65, 4, 106, 40, 2, 0, 4, 127, 32, 1, 65, 12, 119, 32, 0, 65, 20, 106, 40, 2, 0, 65, 18, 119, 106, 32, 0, 65, 12, 106, 40, 2, 0, 65, 7, 119, 106, 32, 0, 65, 8, 106, 40, 2, 0, 65, 1, 119, 106, 5, 32, 1, 65, 177, 207, 217, 178, 1, 106, 11, 32, 0, 40, 2, 0, 106, 32, 0, 65, 24, 106, 32, 0, 65, 40, 106, 40, 2, 0, 16, 1, 11, 255, 3, 2, 3, 126, 1, 127, 32, 0, 32, 1, 106, 33, 6, 32, 1, 65, 32, 79, 4, 126, 32, 6, 65, 32, 107, 33, 6, 32, 2, 66, 214, 235, 130, 238, 234, 253, 137, 245, 224, 0, 124, 33, 3, 32, 2, 66, 177, 169, 172, 193, 173, 184, 212, 166, 61, 125, 33, 4, 32, 2, 66, 249, 234, 208, 208, 231, 201, 161, 228, 225, 0, 124, 33, 5, 3, 64, 32, 3, 32, 0, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 3, 32, 4, 32, 0, 65, 8, 106, 34, 0, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 4, 32, 2, 32, 0, 65, 8, 106, 34, 0, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 2, 32, 5, 32, 0, 65, 8, 106, 34, 0, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 5, 32, 6, 32, 0, 65, 8, 106, 34, 0, 79, 13, 0, 11, 32, 2, 66, 12, 137, 32, 5, 66, 18, 137, 124, 32, 4, 66, 7, 137, 124, 32, 3, 66, 1, 137, 124, 32, 3, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 32, 4, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 32, 2, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 32, 5, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 5, 32, 2, 66, 197, 207, 217, 178, 241, 229, 186, 234, 39, 124, 11, 32, 1, 173, 124, 32, 0, 32, 1, 65, 31, 113, 16, 6, 11, 134, 2, 0, 32, 1, 32, 2, 106, 33, 2, 3, 64, 32, 2, 32, 1, 65, 8, 106, 79, 4, 64, 32, 1, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 32, 0, 133, 66, 27, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 33, 0, 32, 1, 65, 8, 106, 33, 1, 12, 1, 11, 11, 32, 1, 65, 4, 106, 32, 2, 77, 4, 64, 32, 0, 32, 1, 53, 2, 0, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 23, 137, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 249, 243, 221, 241, 153, 246, 153, 171, 22, 124, 33, 0, 32, 1, 65, 4, 106, 33, 1, 11, 3, 64, 32, 1, 32, 2, 73, 4, 64, 32, 0, 32, 1, 49, 0, 0, 66, 197, 207, 217, 178, 241, 229, 186, 234, 39, 126, 133, 66, 11, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 0, 32, 1, 65, 1, 106, 33, 1, 12, 1, 11, 11, 32, 0, 32, 0, 66, 33, 136, 133, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 34, 0, 32, 0, 66, 29, 136, 133, 66, 249, 243, 221, 241, 153, 246, 153, 171, 22, 126, 34, 0, 32, 0, 66, 32, 136, 133, 11, 77, 0, 32, 0, 65, 8, 106, 32, 1, 66, 214, 235, 130, 238, 234, 253, 137, 245, 224, 0, 124, 55, 3, 0, 32, 0, 65, 16, 106, 32, 1, 66, 177, 169, 172, 193, 173, 184, 212, 166, 61, 125, 55, 3, 0, 32, 0, 65, 24, 106, 32, 1, 55, 3, 0, 32, 0, 65, 32, 106, 32, 1, 66, 249, 234, 208, 208, 231, 201, 161, 228, 225, 0, 124, 55, 3, 0, 11, 244, 4, 2, 3, 127, 4, 126, 32, 1, 32, 2, 106, 33, 5, 32, 0, 65, 40, 106, 33, 4, 32, 0, 65, 200, 0, 106, 40, 2, 0, 33, 3, 32, 0, 32, 0, 41, 3, 0, 32, 2, 173, 124, 55, 3, 0, 32, 2, 32, 3, 106, 65, 32, 73, 4, 64, 32, 3, 32, 4, 106, 32, 1, 32, 2, 252, 10, 0, 0, 32, 0, 65, 200, 0, 106, 32, 2, 32, 3, 106, 54, 2, 0, 15, 11, 32, 3, 4, 64, 32, 3, 32, 4, 106, 32, 1, 65, 32, 32, 3, 107, 34, 2, 252, 10, 0, 0, 32, 0, 65, 8, 106, 34, 3, 32, 3, 41, 3, 0, 32, 4, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 55, 3, 0, 32, 0, 65, 16, 106, 34, 3, 32, 3, 41, 3, 0, 32, 4, 65, 8, 106, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 55, 3, 0, 32, 0, 65, 24, 106, 34, 3, 32, 3, 41, 3, 0, 32, 4, 65, 16, 106, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 55, 3, 0, 32, 0, 65, 32, 106, 34, 3, 32, 3, 41, 3, 0, 32, 4, 65, 24, 106, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 55, 3, 0, 32, 0, 65, 200, 0, 106, 65, 0, 54, 2, 0, 32, 1, 32, 2, 106, 33, 1, 11, 32, 1, 65, 32, 106, 32, 5, 77, 4, 64, 32, 5, 65, 32, 107, 33, 2, 32, 0, 65, 8, 106, 41, 3, 0, 33, 6, 32, 0, 65, 16, 106, 41, 3, 0, 33, 7, 32, 0, 65, 24, 106, 41, 3, 0, 33, 8, 32, 0, 65, 32, 106, 41, 3, 0, 33, 9, 3, 64, 32, 6, 32, 1, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 6, 32, 7, 32, 1, 65, 8, 106, 34, 1, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 7, 32, 8, 32, 1, 65, 8, 106, 34, 1, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 8, 32, 9, 32, 1, 65, 8, 106, 34, 1, 41, 3, 0, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 124, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 33, 9, 32, 2, 32, 1, 65, 8, 106, 34, 1, 79, 13, 0, 11, 32, 0, 65, 8, 106, 32, 6, 55, 3, 0, 32, 0, 65, 16, 106, 32, 7, 55, 3, 0, 32, 0, 65, 24, 106, 32, 8, 55, 3, 0, 32, 0, 65, 32, 106, 32, 9, 55, 3, 0, 11, 32, 1, 32, 5, 73, 4, 64, 32, 4, 32, 1, 32, 5, 32, 1, 107, 34, 1, 252, 10, 0, 0, 32, 0, 65, 200, 0, 106, 32, 1, 54, 2, 0, 11, 11, 188, 2, 1, 5, 126, 32, 0, 65, 24, 106, 41, 3, 0, 33, 1, 32, 0, 41, 3, 0, 34, 2, 66, 32, 90, 4, 126, 32, 0, 65, 8, 106, 41, 3, 0, 34, 3, 66, 1, 137, 32, 0, 65, 16, 106, 41, 3, 0, 34, 4, 66, 7, 137, 124, 32, 1, 66, 12, 137, 32, 0, 65, 32, 106, 41, 3, 0, 34, 5, 66, 18, 137, 124, 124, 32, 3, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 32, 4, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 32, 1, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 32, 5, 66, 207, 214, 211, 190, 210, 199, 171, 217, 66, 126, 66, 31, 137, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 133, 66, 135, 149, 175, 175, 152, 182, 222, 155, 158, 127, 126, 66, 157, 163, 181, 234, 131, 177, 141, 138, 250, 0, 125, 5, 32, 1, 66, 197, 207, 217, 178, 241, 229, 186, 234, 39, 124, 11, 32, 2, 124, 32, 0, 65, 40, 106, 32, 2, 66, 31, 131, 167, 16, 6, 11]);
1996
2156
  async function e() {
1997
2157
  return (function(t2) {
1998
- const { exports: { mem: e2, xxh32: n, xxh64: r, init32: i, update32: a, digest32: o, init64: s, update64: u, digest64: c } } = t2;
2158
+ const { exports: { mem: e2, xxh32: n, xxh64: r, init32: i, update32: a, digest32: o2, init64: s, update64: u2, digest64: c } } = t2;
1999
2159
  let h = new Uint8Array(e2.buffer);
2000
2160
  function g(t3, n2) {
2001
2161
  if (e2.buffer.byteLength < t3 + n2) {
@@ -2005,11 +2165,11 @@ async function e() {
2005
2165
  }
2006
2166
  function f(t3, e3, n2, r2, i2, a2) {
2007
2167
  g(t3);
2008
- const o2 = new Uint8Array(t3);
2009
- return h.set(o2), n2(0, e3), o2.set(h.subarray(0, t3)), { update(e4) {
2168
+ const o3 = new Uint8Array(t3);
2169
+ return h.set(o3), n2(0, e3), o3.set(h.subarray(0, t3)), { update(e4) {
2010
2170
  let n3;
2011
- return h.set(o2), "string" == typeof e4 ? (g(3 * e4.length, t3), n3 = w.encodeInto(e4, h.subarray(t3)).written) : (g(e4.byteLength, t3), h.set(e4, t3), n3 = e4.byteLength), r2(0, t3, n3), o2.set(h.subarray(0, t3)), this;
2012
- }, digest: () => (h.set(o2), a2(i2(0))) };
2171
+ return h.set(o3), "string" == typeof e4 ? (g(3 * e4.length, t3), n3 = w.encodeInto(e4, h.subarray(t3)).written) : (g(e4.byteLength, t3), h.set(e4, t3), n3 = e4.byteLength), r2(0, t3, n3), o3.set(h.subarray(0, t3)), this;
2172
+ }, digest: () => (h.set(o3), a2(i2(0))) };
2013
2173
  }
2014
2174
  function y(t3) {
2015
2175
  return t3 >>> 0;
@@ -2025,12 +2185,13 @@ async function e() {
2025
2185
  function L(t3, e3 = p) {
2026
2186
  return g(3 * t3.length, 0), d(r(0, w.encodeInto(t3, h).written, e3));
2027
2187
  }
2028
- return { h32: x, h32ToString: (t3, e3 = l) => x(t3, e3).toString(16).padStart(8, "0"), h32Raw: (t3, e3 = l) => (g(t3.byteLength, 0), h.set(t3), y(n(0, t3.byteLength, e3))), create32: (t3 = l) => f(48, t3, i, a, o, y), h64: L, h64ToString: (t3, e3 = p) => L(t3, e3).toString(16).padStart(16, "0"), h64Raw: (t3, e3 = p) => (g(t3.byteLength, 0), h.set(t3), d(r(0, t3.byteLength, e3))), create64: (t3 = p) => f(88, t3, s, u, c, d) };
2188
+ return { h32: x, h32ToString: (t3, e3 = l) => x(t3, e3).toString(16).padStart(8, "0"), h32Raw: (t3, e3 = l) => (g(t3.byteLength, 0), h.set(t3), y(n(0, t3.byteLength, e3))), create32: (t3 = l) => f(48, t3, i, a, o2, y), h64: L, h64ToString: (t3, e3 = p) => L(t3, e3).toString(16).padStart(16, "0"), h64Raw: (t3, e3 = p) => (g(t3.byteLength, 0), h.set(t3), d(r(0, t3.byteLength, e3))), create64: (t3 = p) => f(88, t3, s, u2, c, d) };
2029
2189
  })((await WebAssembly.instantiate(t)).instance);
2030
2190
  }
2031
2191
 
2032
2192
  // ../shared/lib/common/utils.js
2033
2193
  var xxHasher = await e();
2194
+ var ID_SEPARATOR = `388c03a1c6`;
2034
2195
  function humanReadableMs(ms) {
2035
2196
  if (+ms < 1e-5)
2036
2197
  return `0 ms`;
@@ -2073,42 +2234,413 @@ function durationTrendScale(currentMs, baseMs) {
2073
2234
  return "\xB10%";
2074
2235
  return `-${(1 - trend) * 100 | 0}%`;
2075
2236
  }
2237
+ function xxHash(data) {
2238
+ if (Array.isArray(data))
2239
+ return xxHasher.h64ToString(data.join(ID_SEPARATOR));
2240
+ return xxHasher.h64ToString(data);
2241
+ }
2242
+ function xxHashObject(obj) {
2243
+ return xxHash(dist_default(obj));
2244
+ }
2245
+
2246
+ // ../server/lib/common/stats/envGroup.js
2247
+ function normalize(value) {
2248
+ return value.toLowerCase().trim();
2249
+ }
2250
+ var EnvGroupKey;
2251
+ ((EnvGroupKey2) => {
2252
+ function from(key) {
2253
+ return key.toLowerCase();
2254
+ }
2255
+ EnvGroupKey2.from = from;
2256
+ function metadata(name) {
2257
+ return from(`metadata.${name}`);
2258
+ }
2259
+ EnvGroupKey2.metadata = metadata;
2260
+ EnvGroupKey2.NAME = from("name");
2261
+ EnvGroupKey2.CATEGORY = from("category");
2262
+ EnvGroupKey2.CONFIG_PATH = from("config.path");
2263
+ EnvGroupKey2.OS_NAME = from("os.name");
2264
+ EnvGroupKey2.OS_VERSION = from("os.version");
2265
+ EnvGroupKey2.OS_ARCH = from("os.arch");
2266
+ EnvGroupKey2.ENV_ID = from("env.id");
2267
+ EnvGroupKey2.OS_NAME_WITH_VERSION = from("os.name-version");
2268
+ })(EnvGroupKey || (EnvGroupKey = {}));
2269
+ var COMPUTED_KEYS = /* @__PURE__ */ new Map([
2270
+ // Pins a single environment. Links in GitHub PR comments use it.
2271
+ [EnvGroupKey.ENV_ID, (env) => env.envId],
2272
+ // OS name and version joined with a space. The CLI's `--env-os` sends it.
2273
+ [EnvGroupKey.OS_NAME_WITH_VERSION, (env) => [env.systemData.osName, env.systemData.osVersion].filter(Boolean).join(" ") || void 0]
2274
+ ]);
2275
+ function envEntries(env) {
2276
+ const entries = /* @__PURE__ */ new Map();
2277
+ const add = (key, value) => {
2278
+ if (value !== void 0 && value !== null && value !== "")
2279
+ entries.set(key, String(value));
2280
+ };
2281
+ add(EnvGroupKey.NAME, env.name);
2282
+ add(EnvGroupKey.CATEGORY, env.category);
2283
+ add(EnvGroupKey.CONFIG_PATH, env.configPath);
2284
+ add(EnvGroupKey.OS_NAME, env.systemData.osName);
2285
+ add(EnvGroupKey.OS_VERSION, env.systemData.osVersion);
2286
+ add(EnvGroupKey.OS_ARCH, env.systemData.osArch);
2287
+ for (const [name, value] of Object.entries(env.userSuppliedData ?? {}))
2288
+ add(EnvGroupKey.metadata(name), value);
2289
+ return entries;
2290
+ }
2291
+ var LEGACY_SYSTEM_KEYS = /* @__PURE__ */ new Map([
2292
+ ["env_id", EnvGroupKey.ENV_ID],
2293
+ ["name", EnvGroupKey.NAME],
2294
+ ["path", EnvGroupKey.CONFIG_PATH],
2295
+ ["category", EnvGroupKey.CATEGORY],
2296
+ ["osname", EnvGroupKey.OS_NAME_WITH_VERSION],
2297
+ ["os_name_no_version", EnvGroupKey.OS_NAME],
2298
+ ["osarch", EnvGroupKey.OS_ARCH]
2299
+ ]);
2300
+ function fromLegacyJSON(json) {
2301
+ const eq = {};
2302
+ const add = (name, values, isUserData) => {
2303
+ const key = isUserData ? EnvGroupKey.metadata(name) : LEGACY_SYSTEM_KEYS.get(name);
2304
+ if (key)
2305
+ eq[key] = [...eq[key] ?? [], ...values];
2306
+ };
2307
+ if ("inverse" in json) {
2308
+ for (const { name, values } of json.filters.system ?? [])
2309
+ add(name, values, false);
2310
+ for (const { name, values } of json.filters.user ?? [])
2311
+ add(name, values, true);
2312
+ } else {
2313
+ for (const { name, value } of json.system)
2314
+ add(name, [value], false);
2315
+ for (const { name, value } of json.user)
2316
+ add(name, [value], true);
2317
+ }
2318
+ return EnvGroup.open(eq);
2319
+ }
2320
+ function jsonFilters(filters) {
2321
+ const json = {};
2322
+ for (const key of [...filters.keys()].sort()) {
2323
+ const values = filters.getAll(key).sort();
2324
+ json[key] = values.length === 1 ? values[0] : values;
2325
+ }
2326
+ return json;
2327
+ }
2328
+ function envFilters(env, droplist) {
2329
+ const eq = {};
2330
+ for (const [key, value] of envEntries(env)) {
2331
+ if (!droplist.has(key))
2332
+ eq[key] = value;
2333
+ }
2334
+ return eq;
2335
+ }
2336
+ var EnvGroup = class _EnvGroup {
2337
+ constructor(_type, eq = {}, droplist = []) {
2338
+ this._type = _type;
2339
+ this._addEq(eq);
2340
+ this._drop(droplist);
2341
+ }
2342
+ _type;
2343
+ /**
2344
+ * The maximum number of distinct timelines we expect to have per query.
2345
+ * This constant is used throughout the engine to establish per-timeline caches.
2346
+ */
2347
+ static MAX_TIMELINES = 500;
2348
+ static ALL = _EnvGroup.open();
2349
+ static categoryCollectionLabel(category) {
2350
+ if (category === FlakinessReport.CATEGORY_PLAYWRIGHT)
2351
+ return "Playwright Environments";
2352
+ if (category === FlakinessReport.CATEGORY_JUNIT)
2353
+ return "JUnit Environments";
2354
+ if (category === FlakinessReport.CATEGORY_PYTEST)
2355
+ return "Pytest Environments";
2356
+ if (category === "perf")
2357
+ return "Performance Benchmarks";
2358
+ return `${category} environments`;
2359
+ }
2360
+ static osLabel(input) {
2361
+ return osLabel(input);
2362
+ }
2363
+ static open(eq = {}, droplist = []) {
2364
+ return new _EnvGroup("open", eq, droplist);
2365
+ }
2366
+ static closed(eq = {}, droplist = []) {
2367
+ return new _EnvGroup("closed", eq, droplist);
2368
+ }
2369
+ static closedFromEnv(env, droplist = /* @__PURE__ */ new Set()) {
2370
+ return _EnvGroup.closed(envFilters(env, droplist), droplist);
2371
+ }
2372
+ /** Accepts the legacy JSON as well. */
2373
+ static deserialize(json) {
2374
+ if (!("type" in json))
2375
+ return fromLegacyJSON(json);
2376
+ const group = new _EnvGroup(json.type, {}, (json.drop ?? []).map(EnvGroupKey.from));
2377
+ for (const [key, values] of Object.entries(json.eq ?? {}))
2378
+ group._addEq({ [EnvGroupKey.from(key)]: values });
2379
+ return group;
2380
+ }
2381
+ // Normalized values are used for matching and identity.
2382
+ _filters = new Multimap();
2383
+ // The same values as they were given, one spelling per normalized value, for display.
2384
+ _rawFilters = new Multimap();
2385
+ _droplist = /* @__PURE__ */ new Set();
2386
+ _memoizedAccepts = /* @__PURE__ */ new Map();
2387
+ _memoizedEtag;
2388
+ _memoizedDescription;
2389
+ /**
2390
+ * A copy of this group with the values added to the filters of their keys.
2391
+ * An environment matches a key when it has any of the key's values.
2392
+ */
2393
+ addEq(eq) {
2394
+ const group = this._copy();
2395
+ group._addEq(eq);
2396
+ return group;
2397
+ }
2398
+ /** A copy of this group with the keys added to its droplist. */
2399
+ drop(...keys) {
2400
+ const group = this._copy();
2401
+ group._drop(keys);
2402
+ return group;
2403
+ }
2404
+ _addEq(eq) {
2405
+ for (const [key, rawValues] of Object.entries(eq)) {
2406
+ for (const value of typeof rawValues === "string" ? [rawValues] : rawValues) {
2407
+ const normalized = normalize(value);
2408
+ if (this._filters.has(key, normalized))
2409
+ continue;
2410
+ this._filters.set(key, normalized);
2411
+ this._rawFilters.set(key, value);
2412
+ }
2413
+ }
2414
+ }
2415
+ _drop(keys) {
2416
+ for (const key of keys)
2417
+ this._droplist.add(key);
2418
+ }
2419
+ _copy() {
2420
+ const group = new _EnvGroup(this._type);
2421
+ group._filters = this._filters.clone();
2422
+ group._rawFilters = this._rawFilters.clone();
2423
+ group._droplist = new Set(this._droplist);
2424
+ return group;
2425
+ }
2426
+ groupType() {
2427
+ return this._type;
2428
+ }
2429
+ /** Whether the group accepts every environment. The droplist doesn't matter: it only affects {@link subgroups}. */
2430
+ acceptsAll() {
2431
+ return this._type === "open" && !this._filters.size;
2432
+ }
2433
+ values(key) {
2434
+ return this._rawFilters.getAll(key);
2435
+ }
2436
+ droplist() {
2437
+ return this._droplist;
2438
+ }
2439
+ _computeAccepts(env) {
2440
+ const entries = envEntries(env);
2441
+ for (const key of this._filters.keys()) {
2442
+ const extract = COMPUTED_KEYS.get(key);
2443
+ const value = extract ? extract(env) : entries.get(key);
2444
+ if (value === void 0 || !this._filters.has(key, normalize(value)))
2445
+ return false;
2446
+ }
2447
+ if (this._type === "open")
2448
+ return true;
2449
+ return [...entries.keys()].every((key) => this._filters.hasAny(key) || this._droplist.has(key));
2450
+ }
2451
+ accepts(env) {
2452
+ let result = this._memoizedAccepts.get(env.envId);
2453
+ if (result === void 0) {
2454
+ result = this._computeAccepts(env);
2455
+ this._memoizedAccepts.set(env.envId, result);
2456
+ }
2457
+ return result;
2458
+ }
2459
+ /**
2460
+ * Splits the environments of `envs` that this group accepts. Two
2461
+ * environments share a subgroup when their keys and values match after
2462
+ * the dropped keys are removed.
2463
+ *
2464
+ * A subgroup is closed: it pins the remaining keys and keeps the droplist.
2465
+ * It also keeps this group's filters on the keys it doesn't pin, so it
2466
+ * accepts only environments that this group accepts.
2467
+ */
2468
+ subgroups(envs) {
2469
+ const subgroups = /* @__PURE__ */ new Map();
2470
+ for (const env of envs) {
2471
+ if (!this.accepts(env))
2472
+ continue;
2473
+ const eq = envFilters(env, this._droplist);
2474
+ for (const key of this._rawFilters.keys()) {
2475
+ if (!Object.hasOwn(eq, key))
2476
+ eq[key] = this._rawFilters.getAll(key);
2477
+ }
2478
+ const subgroup = _EnvGroup.closed(eq, this._droplist);
2479
+ subgroups.set(subgroup.etag(), subgroup);
2480
+ }
2481
+ return [...subgroups.values()];
2482
+ }
2483
+ /** Keys with several values are left out of the description. */
2484
+ description() {
2485
+ if (!this._memoizedDescription)
2486
+ this._memoizedDescription = this._computeDescription();
2487
+ return this._memoizedDescription;
2488
+ }
2489
+ compare(other) {
2490
+ const a = this.description();
2491
+ const b = other.description();
2492
+ return cmpText(a.name ?? a.configPath, b.name ?? b.configPath) ?? cmpText(a.metadata, b.metadata) ?? cmpText(a.system, b.system) ?? cmpText(a.configPath, b.configPath) ?? cmpText(a.category, b.category) ?? 0;
2493
+ }
2494
+ serialize() {
2495
+ return {
2496
+ type: this._type,
2497
+ eq: this._rawFilters.size ? jsonFilters(this._rawFilters) : void 0,
2498
+ drop: this._droplist.size ? [...this._droplist].sort() : void 0
2499
+ };
2500
+ }
2501
+ etag() {
2502
+ if (!this._memoizedEtag) {
2503
+ this._memoizedEtag = xxHashObject({
2504
+ type: this._type,
2505
+ filters: jsonFilters(this._filters),
2506
+ droplist: [...this._droplist].sort()
2507
+ });
2508
+ }
2509
+ return this._memoizedEtag;
2510
+ }
2511
+ isEqual(other) {
2512
+ return this.etag() === other.etag();
2513
+ }
2514
+ /** Whether both filters accept the same environments out of `envs`. */
2515
+ isFunctionallyEqual(other, envs) {
2516
+ return envs.every((env) => this.accepts(env) === other.accepts(env));
2517
+ }
2518
+ _computeDescription() {
2519
+ const single = (key) => {
2520
+ const values = this.values(key);
2521
+ return values.length === 1 ? values[0] : void 0;
2522
+ };
2523
+ const name = single(EnvGroupKey.NAME);
2524
+ const systemData = {
2525
+ osName: single(EnvGroupKey.OS_NAME) ?? single(EnvGroupKey.OS_NAME_WITH_VERSION),
2526
+ osVersion: single(EnvGroupKey.OS_VERSION),
2527
+ osArch: single(EnvGroupKey.OS_ARCH)
2528
+ };
2529
+ const tokens = [];
2530
+ for (const key of this._filters.keys()) {
2531
+ const value = key.startsWith("metadata.") ? single(key) : void 0;
2532
+ if (value === void 0 || value.toLowerCase() === "false" || value.toLowerCase() === "default")
2533
+ continue;
2534
+ const metadataKey = key.slice("metadata.".length);
2535
+ if (value.toLowerCase() === "true")
2536
+ tokens.push(metadataKey);
2537
+ else if (Number.isFinite(Number(value)))
2538
+ tokens.push(`${metadataKey}=${value}`);
2539
+ else
2540
+ tokens.push(value);
2541
+ }
2542
+ const system = osLabel(systemData);
2543
+ const systemType = osType(systemData);
2544
+ const impliedContext = [...tokens, system];
2545
+ if (name)
2546
+ impliedContext.push(name);
2547
+ if (systemType === "macos")
2548
+ impliedContext.push("mac", "macos", "mac os");
2549
+ else if (systemType === "windows")
2550
+ impliedContext.push("win32", "win", "windows", "mingw");
2551
+ else if (systemType === "linux")
2552
+ impliedContext.push("linux");
2553
+ if (tokens.some((token) => token.startsWith("chrome")))
2554
+ impliedContext.push("chromium");
2555
+ const metadataTokens = tokens.filter((theToken, theIndex) => impliedContext.every((aToken, aIndex) => aIndex === theIndex || aToken.toLowerCase().indexOf(theToken.toLowerCase()) === -1));
2556
+ return {
2557
+ name,
2558
+ category: single(EnvGroupKey.CATEGORY) ?? "",
2559
+ configPath: single(EnvGroupKey.CONFIG_PATH),
2560
+ metadataTokens,
2561
+ metadata: metadataTokens.length ? metadataTokens.join(", ") : void 0,
2562
+ system,
2563
+ systemType
2564
+ };
2565
+ }
2566
+ };
2567
+ function osType(input) {
2568
+ const lower = (input.osName ?? "").trim().toLowerCase();
2569
+ if (!lower)
2570
+ return void 0;
2571
+ if (/^(darwin|mac ?os|macos)\b/.test(lower))
2572
+ return "macos";
2573
+ if (/^(mingw|win32|windows)/.test(lower))
2574
+ return "windows";
2575
+ if (/^(ubuntu|linux)\b/.test(lower))
2576
+ return "linux";
2577
+ }
2578
+ function osNameLabel(input) {
2579
+ const rawName = (input.osName ?? "").trim();
2580
+ const rawVersion = (input.osVersion ?? "").trim();
2581
+ const suffix = (value, prefix) => value.replace(prefix, "").trim();
2582
+ let name;
2583
+ if (/^(darwin|mac ?os|macos)\b/i.test(rawName))
2584
+ name = ["macOS", suffix(rawName, /^(darwin|mac ?os|macos)\b\s*/i)].filter(Boolean).join(" ");
2585
+ else if (/^mingw/i.test(rawName))
2586
+ name = ["Windows", suffix(rawName, /^mingw(?:32|64)?[_\s-]*/i)].filter(Boolean).join(" ");
2587
+ else if (/^(win32|windows)\b/i.test(rawName))
2588
+ name = ["Windows", suffix(rawName, /^(win32|windows)\b\s*/i)].filter(Boolean).join(" ");
2589
+ else if (/^ubuntu\b/i.test(rawName))
2590
+ name = ["Ubuntu", suffix(rawName, /^ubuntu\b\s*/i)].filter(Boolean).join(" ");
2591
+ else if (/^linux\b/i.test(rawName))
2592
+ name = ["Linux", suffix(rawName, /^linux\b\s*/i)].filter(Boolean).join(" ");
2593
+ else
2594
+ name = rawName;
2595
+ if (rawVersion && !name.toLowerCase().includes(rawVersion.toLowerCase()))
2596
+ name = [name, rawVersion].filter(Boolean).join(" ");
2597
+ return name.trim();
2598
+ }
2599
+ function osArchLabel(input) {
2600
+ const rawArch = (input.osArch ?? "").trim();
2601
+ const lower = rawArch.toLowerCase();
2602
+ if (!lower)
2603
+ return "";
2604
+ if (["x86_64", "amd64", "x64"].includes(lower))
2605
+ return "x86-64";
2606
+ if (["aarch64", "arm64"].includes(lower))
2607
+ return "arm64";
2608
+ if (["x86", "i386", "i686"].includes(lower))
2609
+ return "x86";
2610
+ return rawArch;
2611
+ }
2612
+ function osLabel(input) {
2613
+ const arch = osArchLabel(input);
2614
+ const archLabel = arch && arch !== "x86" && arch !== "x86-64" ? arch : "";
2615
+ return [osNameLabel(input), archLabel].filter(Boolean).join(" ");
2616
+ }
2617
+ function cmpText(a = "", b = "") {
2618
+ a = a.toLowerCase();
2619
+ b = b.toLowerCase();
2620
+ if (a === b)
2621
+ return void 0;
2622
+ return a < b ? -1 : 1;
2623
+ }
2076
2624
 
2077
2625
  // src/cli/cmd-list-tests.ts
2078
- function buildTimelineSplit(filters) {
2079
- const systemFilters = [];
2080
- if (filters.envName?.length)
2081
- systemFilters.push({ name: "name", values: filters.envName });
2082
- if (filters.envPath?.length)
2083
- systemFilters.push({ name: "path", values: filters.envPath });
2084
- if (filters.envCategory?.length)
2085
- systemFilters.push({ name: "category", values: filters.envCategory });
2086
- if (filters.envOs?.length)
2087
- systemFilters.push({ name: "osname", values: filters.envOs });
2088
- if (filters.envArch?.length)
2089
- systemFilters.push({ name: "osarch", values: filters.envArch });
2090
- const userFilters = /* @__PURE__ */ new Map();
2626
+ function buildEnvFilter(filters) {
2627
+ const envFilters2 = {};
2628
+ const add = (key, values) => {
2629
+ if (values?.length)
2630
+ envFilters2[key] = [...envFilters2[key] ?? [], ...values];
2631
+ };
2632
+ add(EnvGroupKey.NAME, filters.envName);
2633
+ add(EnvGroupKey.CONFIG_PATH, filters.envPath);
2634
+ add(EnvGroupKey.CATEGORY, filters.envCategory);
2635
+ add(EnvGroupKey.OS_NAME_WITH_VERSION, filters.envOs);
2636
+ add(EnvGroupKey.OS_ARCH, filters.envArch);
2091
2637
  for (const entry of filters.envMetadata ?? []) {
2092
2638
  const eqIndex = entry.indexOf("=");
2093
- const key = entry.slice(0, eqIndex);
2094
- const value = entry.slice(eqIndex + 1);
2095
- let values = userFilters.get(key);
2096
- if (!values) {
2097
- values = [];
2098
- userFilters.set(key, values);
2099
- }
2100
- values.push(value);
2639
+ add(EnvGroupKey.metadata(entry.slice(0, eqIndex)), [entry.slice(eqIndex + 1)]);
2101
2640
  }
2102
- if (!systemFilters.length && !userFilters.size)
2641
+ if (!Object.keys(envFilters2).length)
2103
2642
  return void 0;
2104
- return {
2105
- splitByDefault: true,
2106
- filters: {
2107
- system: systemFilters.length ? systemFilters : void 0,
2108
- user: userFilters.size ? Array.from(userFilters, ([name, values]) => ({ name, values })) : void 0
2109
- },
2110
- inverse: {}
2111
- };
2643
+ return { type: "open", eq: envFilters2 };
2112
2644
  }
2113
2645
  async function cmdListTests(options) {
2114
2646
  const [orgSlug, projectSlug] = options.flakinessProject.split("/");
@@ -2142,7 +2674,7 @@ async function cmdListTests(options) {
2142
2674
  fql: options.fql,
2143
2675
  // Absent => the server falls back to the project's default history type.
2144
2676
  historyConfig: options.history ? { type: options.history } : void 0,
2145
- timelineSplit: buildTimelineSplit(options)
2677
+ timelineSplit: buildEnvFilter(options)
2146
2678
  }).then((response) => response.page);
2147
2679
  let scope = "default branch";
2148
2680
  if (options.pr !== void 0)