velocious 1.0.581 → 1.0.583

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 (50) hide show
  1. package/README.md +19 -3
  2. package/build/configuration-types.js +2 -0
  3. package/build/database/drivers/base.js +209 -13
  4. package/build/database/query/preloader/belongs-to.js +32 -31
  5. package/build/database/query/preloader/has-many.js +50 -26
  6. package/build/database/query/preloader/has-one.js +20 -12
  7. package/build/database/query/query-data.js +23 -8
  8. package/build/database/query/with-count.js +47 -11
  9. package/build/environment-handlers/node/cli/commands/test.js +21 -2
  10. package/build/frontend-model-controller.js +131 -28
  11. package/build/src/configuration-types.d.ts +10 -0
  12. package/build/src/configuration-types.d.ts.map +1 -1
  13. package/build/src/configuration-types.js +3 -1
  14. package/build/src/database/drivers/base.d.ts +71 -0
  15. package/build/src/database/drivers/base.d.ts.map +1 -1
  16. package/build/src/database/drivers/base.js +178 -17
  17. package/build/src/database/query/preloader/belongs-to.d.ts.map +1 -1
  18. package/build/src/database/query/preloader/belongs-to.js +33 -31
  19. package/build/src/database/query/preloader/has-many.d.ts.map +1 -1
  20. package/build/src/database/query/preloader/has-many.js +48 -28
  21. package/build/src/database/query/preloader/has-one.d.ts.map +1 -1
  22. package/build/src/database/query/preloader/has-one.js +21 -13
  23. package/build/src/database/query/query-data.js +21 -8
  24. package/build/src/database/query/with-count.js +41 -12
  25. package/build/src/environment-handlers/node/cli/commands/test.d.ts +6 -0
  26. package/build/src/environment-handlers/node/cli/commands/test.d.ts.map +1 -1
  27. package/build/src/environment-handlers/node/cli/commands/test.js +22 -3
  28. package/build/src/frontend-model-controller.d.ts +40 -0
  29. package/build/src/frontend-model-controller.d.ts.map +1 -1
  30. package/build/src/frontend-model-controller.js +116 -28
  31. package/build/src/testing/test-filter-parser.d.ts +5 -0
  32. package/build/src/testing/test-filter-parser.d.ts.map +1 -1
  33. package/build/src/testing/test-filter-parser.js +19 -2
  34. package/build/src/testing/test-suite-splitter.d.ts +16 -1
  35. package/build/src/testing/test-suite-splitter.d.ts.map +1 -1
  36. package/build/src/testing/test-suite-splitter.js +38 -3
  37. package/build/testing/test-filter-parser.js +21 -1
  38. package/build/testing/test-suite-splitter.js +44 -2
  39. package/package.json +4 -1
  40. package/src/configuration-types.js +2 -0
  41. package/src/database/drivers/base.js +209 -13
  42. package/src/database/query/preloader/belongs-to.js +32 -31
  43. package/src/database/query/preloader/has-many.js +50 -26
  44. package/src/database/query/preloader/has-one.js +20 -12
  45. package/src/database/query/query-data.js +23 -8
  46. package/src/database/query/with-count.js +47 -11
  47. package/src/environment-handlers/node/cli/commands/test.js +21 -2
  48. package/src/frontend-model-controller.js +131 -28
  49. package/src/testing/test-filter-parser.js +21 -1
  50. package/src/testing/test-suite-splitter.js +44 -2
@@ -7,6 +7,7 @@
7
7
  * @property {string[]} filteredProcessArgs - Remaining process args with filter flags removed.
8
8
  * @property {number | undefined} groups - Total number of groups for test splitting.
9
9
  * @property {number | undefined} groupNumber - Which group to run (1-indexed).
10
+ * @property {string | undefined} timingManifestPath - JSON timing manifest path.
10
11
  */
11
12
  export type ParseFiltersResult = {
12
13
  /**
@@ -33,6 +34,10 @@ export type ParseFiltersResult = {
33
34
  * - Which group to run (1-indexed).
34
35
  */
35
36
  groupNumber: number | undefined;
37
+ /**
38
+ * - JSON timing manifest path.
39
+ */
40
+ timingManifestPath: string | undefined;
36
41
  };
37
42
  /**
38
43
  * Runs the normalizeExamplePatterns helper.
@@ -1 +1 @@
1
- {"version":3,"file":"test-filter-parser.d.ts","sourceRoot":"","sources":["../../../src/testing/test-filter-parser.js"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAPA,YAAkB,kBAAkB,GACpC;;;;IAAqB,WAAW,EAArB,MAAM,EAAE,CACnB;;;;IAAqB,WAAW,EAArB,MAAM,EAAE,CACnB;;;;IAAqB,eAAe,EAAzB,MAAM,EAAE,CACnB;;;;IAAqB,mBAAmB,EAA7B,MAAM,EAAE,CACnB;;;;IAA+B,MAAM,EAA1B,MAAM,GAAG,SAAS,CAC7B;;;;IAA+B,WAAW,EAA/B,MAAM,GAAG,SAAS,CAC/B;CAAA,CAAA;AAgCD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAHtC,MAAM,EAGgC,GAFpC,MAAM,EAAE,CAgBpB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAH7B,MAAM,EAGuB,GAF3B,kBAAkB,CAmI9B"}
1
+ {"version":3,"file":"test-filter-parser.d.ts","sourceRoot":"","sources":["../../../src/testing/test-filter-parser.js"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AARA,YAAkB,kBAAkB,GACpC;;;;IAAqB,WAAW,EAArB,MAAM,EAAE,CACnB;;;;IAAqB,WAAW,EAArB,MAAM,EAAE,CACnB;;;;IAAqB,eAAe,EAAzB,MAAM,EAAE,CACnB;;;;IAAqB,mBAAmB,EAA7B,MAAM,EAAE,CACnB;;;;IAA+B,MAAM,EAA1B,MAAM,GAAG,SAAS,CAC7B;;;;IAA+B,WAAW,EAA/B,MAAM,GAAG,SAAS,CAC7B;;;;IAA+B,kBAAkB,EAAtC,MAAM,GAAG,SAAS,CAC/B;CAAA,CAAA;AAiCD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAHtC,MAAM,EAGgC,GAFpC,MAAM,EAAE,CAgBpB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAH7B,MAAM,EAGuB,GAF3B,kBAAkB,CAqJ9B"}
@@ -7,6 +7,7 @@
7
7
  * @property {string[]} filteredProcessArgs - Remaining process args with filter flags removed.
8
8
  * @property {number | undefined} groups - Total number of groups for test splitting.
9
9
  * @property {number | undefined} groupNumber - Which group to run (1-indexed).
10
+ * @property {string | undefined} timingManifestPath - JSON timing manifest path.
10
11
  */
11
12
  // @ts-check
12
13
  const INCLUDE_TAG_FLAGS = new Set(["--tag", "--include-tag", "-t"]);
@@ -14,6 +15,7 @@ const EXCLUDE_TAG_FLAGS = new Set(["--exclude-tag", "--skip-tag", "-x"]);
14
15
  const EXAMPLE_FLAGS = new Set(["--example", "--name", "-e"]);
15
16
  const GROUPS_FLAGS = new Set(["--groups"]);
16
17
  const GROUP_NUMBER_FLAGS = new Set(["--group-number"]);
18
+ const TIMING_MANIFEST_FLAGS = new Set(["--timing-manifest"]);
17
19
  /**
18
20
  * Runs split tags.
19
21
  * @param {string | undefined} value - Tag argument value.
@@ -71,6 +73,8 @@ export function parseFilters(processArgs) {
71
73
  * Defines groupNumber.
72
74
  * @type {number | undefined} */
73
75
  let groupNumber;
76
+ /** @type {string | undefined} */
77
+ let timingManifestPath;
74
78
  let inRestArgs = false;
75
79
  for (let i = 1; i < processArgs.length; i++) {
76
80
  const arg = processArgs[i];
@@ -152,6 +156,18 @@ export function parseFilters(processArgs) {
152
156
  groupNumber = parseInt(arg.slice("--group-number=".length), 10);
153
157
  continue;
154
158
  }
159
+ if (TIMING_MANIFEST_FLAGS.has(arg)) {
160
+ const nextValue = processArgs[i + 1];
161
+ if (nextValue && !nextValue.startsWith("-")) {
162
+ timingManifestPath = nextValue;
163
+ i++;
164
+ }
165
+ continue;
166
+ }
167
+ if (arg.startsWith("--timing-manifest=")) {
168
+ timingManifestPath = arg.slice("--timing-manifest=".length);
169
+ continue;
170
+ }
155
171
  }
156
172
  filteredProcessArgs.push(arg);
157
173
  }
@@ -161,7 +177,8 @@ export function parseFilters(processArgs) {
161
177
  examplePatterns,
162
178
  filteredProcessArgs,
163
179
  groups,
164
- groupNumber
180
+ groupNumber,
181
+ timingManifestPath
165
182
  };
166
183
  }
167
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1maWx0ZXItcGFyc2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3Rlc3RpbmcvdGVzdC1maWx0ZXItcGFyc2VyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7R0FTRztBQUNILFlBQVk7QUFFWixNQUFNLGlCQUFpQixHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFLGVBQWUsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFBO0FBQ25FLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxlQUFlLEVBQUUsWUFBWSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUE7QUFDeEUsTUFBTSxhQUFhLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxXQUFXLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUE7QUFDNUQsTUFBTSxZQUFZLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFBO0FBQzFDLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUE7QUFFdEQ7Ozs7R0FJRztBQUNILFNBQVMsU0FBUyxDQUFDLEtBQUs7SUFDdEIsSUFBSSxDQUFDLEtBQUs7UUFBRSxPQUFPLEVBQUUsQ0FBQTtJQUVyQixPQUFPLEtBQUs7U0FDVCxLQUFLLENBQUMsR0FBRyxDQUFDO1NBQ1YsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7U0FDeEIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFBO0FBQ3BCLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBUyxZQUFZLENBQUMsS0FBSztJQUN6QixPQUFPLEtBQUssQ0FBQyxPQUFPLENBQUMscUJBQXFCLEVBQUUsTUFBTSxDQUFDLENBQUE7QUFDckQsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVB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QztnQkFDRCxTQUFRO1lBQ1YsQ0FBQztZQUVELElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUM7Z0JBQ3RDLFdBQVcsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQTtnQkFDL0QsU0FBUTtZQUNWLENBQUM7UUFDSCxDQUFDO1FBRUQsbUJBQW1CLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBQy9CLENBQUM7SUFFRCxPQUFPO1FBQ0wsV0FBVyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDN0MsV0FBVyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDN0MsZUFBZTtRQUNmLG1CQUFtQjtRQUNuQixNQUFNO1FBQ04sV0FBVztLQUNaLENBQUE7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQYXJzZUZpbHRlcnNSZXN1bHQgdHlwZS5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IFBhcnNlRmlsdGVyc1Jlc3VsdFxuICogQHByb3BlcnR5IHtzdHJpbmdbXX0gaW5jbHVkZVRhZ3MgLSBUYWdzIHRvIGluY2x1ZGUuXG4gKiBAcHJvcGVydHkge3N0cmluZ1tdfSBleGNsdWRlVGFncyAtIFRhZ3MgdG8gZXhjbHVkZS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IGV4YW1wbGVQYXR0ZXJucyAtIEV4YW1wbGUgbmFtZSBwYXR0ZXJucy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IGZpbHRlcmVkUHJvY2Vzc0FyZ3MgLSBSZW1haW5pbmcgcHJvY2VzcyBhcmdzIHdpdGggZmlsdGVyIGZsYWdzIHJlbW92ZWQuXG4gKiBAcHJvcGVydHkge251bWJlciB8IHVuZGVmaW5lZH0gZ3JvdXBzIC0gVG90YWwgbnVtYmVyIG9mIGdyb3VwcyBmb3IgdGVzdCBzcGxpdHRpbmcuXG4gKiBAcHJvcGVydHkge251bWJlciB8IHVuZGVmaW5lZH0gZ3JvdXBOdW1iZXIgLSBXaGljaCBncm91cCB0byBydW4gKDEtaW5kZXhlZCkuXG4gKi9cbi8vIEB0cy1jaGVja1xuXG5jb25zdCBJTkNMVURFX1RBR19GTEFHUyA9IG5ldyBTZXQoW1wiLS10YWdcIiwgXCItLWluY2x1ZGUtdGFnXCIsIFwiLXRcIl0pXG5jb25zdCBFWENMVURFX1RBR19GTEFHUyA9IG5ldyBTZXQoW1wiLS1leGNsdWRlLXRhZ1wiLCBcIi0tc2tpcC10YWdcIiwgXCIteFwiXSlcbmNvbnN0IEVYQU1QTEVfRkxBR1MgPSBuZXcgU2V0KFtcIi0tZXhhbXBsZVwiLCBcIi0tbmFtZVwiLCBcIi1lXCJdKVxuY29uc3QgR1JPVVBTX0ZMQUdTID0gbmV3IFNldChbXCItLWdyb3Vwc1wiXSlcbmNvbnN0IEdST1VQX05VTUJFUl9GTEFHUyA9IG5ldyBTZXQoW1wiLS1ncm91cC1udW1iZXJcIl0pXG5cbi8qKlxuICogUnVucyBzcGxpdCB0YWdzLlxuICogQHBhcmFtIHtzdHJpbmcgfCB1bmRlZmluZWR9IHZhbHVlIC0gVGFnIGFyZ3VtZW50IHZhbHVlLlxuICogQHJldHVybnMge3N0cmluZ1tdfSAtIFRhZ3MgbGlzdC5cbiAqL1xuZnVuY3Rpb24gc3BsaXRUYWdzKHZhbHVlKSB7XG4gIGlmICghdmFsdWUpIHJldHVybiBbXVxuXG4gIHJldHVybiB2YWx1ZVxuICAgIC5zcGxpdChcIixcIilcbiAgICAubWFwKCh0YWcpID0+IHRhZy50cmltKCkpXG4gICAgLmZpbHRlcihCb29sZWFuKVxufVxuXG4vKipcbiAqIFJ1bnMgZXNjYXBlIHJlZyBleHAuXG4gKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgLSBWYWx1ZS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IC0gRXNjYXBlZCB2YWx1ZSBmb3IgcmVnZXguXG4gKi9cbmZ1bmN0aW9uIGVzY2FwZVJlZ0V4cCh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUucmVwbGFjZSgvWy4qKz9eJHt9KCl8W1xcXVxcXFxdL2csIFwiXFxcXCQmXCIpXG59XG5cbi8qKlxuICogUnVucyB0aGUgbm9ybWFsaXplRXhhbXBsZVBhdHRlcm5zIGhlbHBlci5cbiAqIEBwYXJhbSB7c3RyaW5nW119IHBhdHRlcm5zIC0gUGF0dGVybnMuXG4gKiBAcmV0dXJucyB7UmVnRXhwW119IC0gTm9ybWFsaXplZCBwYXR0ZXJucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZUV4YW1wbGVQYXR0ZXJucyhwYXR0ZXJucykge1xuICBjb25zdCBub3JtYWxpemVkID0gW11cblxuICBmb3IgKGNvbnN0IHBhdHRlcm4gb2YgcGF0dGVybnMpIHtcbiAgICBjb25zdCByZWdleE1hdGNoID0gcGF0dGVybi5tYXRjaCgvXlxcLyguKylcXC8oW2dpbXN1eV0qKSQvKVxuXG4gICAgaWYgKHJlZ2V4TWF0Y2gpIHtcbiAgICAgIG5vcm1hbGl6ZWQucHVzaChuZXcgUmVnRXhwKHJlZ2V4TWF0Y2hbMV0sIHJlZ2V4TWF0Y2hbMl0pKVxuICAgIH0gZWxzZSB7XG4gICAgICBub3JtYWxpemVkLnB1c2gobmV3IFJlZ0V4cChlc2NhcGVSZWdFeHAocGF0dGVybikpKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBub3JtYWxpemVkXG59XG5cbi8qKlxuICogUnVucyB0aGUgcGFyc2VGaWx0ZXJzIGhlbHBlci5cbiAqIEBwYXJhbSB7c3RyaW5nW119IHByb2Nlc3NBcmdzIC0gUHJvY2VzcyBhcmdzLlxuICogQHJldHVybnMge1BhcnNlRmlsdGVyc1Jlc3VsdH0gLSBQYXJzZWQgdGFncywgZ3JvdXAgb3B0aW9ucywgYW5kIHByb2Nlc3MgYXJncy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlRmlsdGVycyhwcm9jZXNzQXJncykge1xuICBjb25zdCBpbmNsdWRlVGFncyA9IFtdXG4gIGNvbnN0IGV4Y2x1ZGVUYWdzID0gW11cbiAgY29uc3QgZmlsdGVyZWRQcm9jZXNzQXJncyA9IHByb2Nlc3NBcmdzLmxlbmd0aCA+IDAgPyBbcHJvY2Vzc0FyZ3NbMF1dIDogW11cbiAgY29uc3QgZXhhbXBsZVBhdHRlcm5zID0gW11cblxuICAvKipcbiAgICogRGVmaW5lcyBncm91cHMuXG4gICAqIEB0eXBlIHtudW1iZXIgfCB1bmRlZmluZWR9ICovXG4gIGxldCBncm91cHNcbiAgLyoqXG4gICAqIERlZmluZXMgZ3JvdXBOdW1iZXIuXG4gICAqIEB0eXBlIHtudW1iZXIgfCB1bmRlZmluZWR9ICovXG4gIGxldCBncm91cE51bWJlclxuXG4gIGxldCBpblJlc3RBcmdzID0gZmFsc2VcblxuICBmb3IgKGxldCBpID0gMTsgaSA8IHByb2Nlc3NBcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgYXJnID0gcHJvY2Vzc0FyZ3NbaV1cblxuICAgIGlmIChhcmcgPT09IFwiLS1cIikge1xuICAgICAgaW5SZXN0QXJncyA9IHRydWVcbiAgICAgIGZpbHRlcmVkUHJvY2Vzc0FyZ3MucHVzaChhcmcpXG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGlmICghaW5SZXN0QXJncykge1xuICAgICAgaWYgKElOQ0xVREVfVEFHX0ZMQUdTLmhhcyhhcmcpKSB7XG4gICAgICAgIGNvbnN0IG5leHRWYWx1ZSA9IHByb2Nlc3NBcmdzW2kgKyAxXVxuXG4gICAgICAgIGlmIChuZXh0VmFsdWUgJiYgIW5leHRWYWx1ZS5zdGFydHNXaXRoKFwiLVwiKSkge1xuICAgICAgICAgIGluY2x1ZGVUYWdzLnB1c2goLi4uc3BsaXRUYWdzKG5leHRWYWx1ZSkpXG4gICAgICAgICAgaSsrXG4gICAgICAgIH1cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKEVYQ0xVREVfVEFHX0ZMQUdTLmhhcyhhcmcpKSB7XG4gICAgICAgIGNvbnN0IG5leHRWYWx1ZSA9IHByb2Nlc3NBcmdzW2kgKyAxXVxuXG4gICAgICAgIGlmIChuZXh0VmFsdWUgJiYgIW5leHRWYWx1ZS5zdGFydHNXaXRoKFwiLVwiKSkge1xuICAgICAgICAgIGV4Y2x1ZGVUYWdzLnB1c2goLi4uc3BsaXRUYWdzKG5leHRWYWx1ZSkpXG4gICAgICAgICAgaSsrXG4gICAgICAgIH1cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKGFyZy5zdGFydHNXaXRoKFwiLS10YWc9XCIpKSB7XG4gICAgICAgIGluY2x1ZGVUYWdzLnB1c2goLi4uc3BsaXRUYWdzKGFyZy5zbGljZShcIi0tdGFnPVwiLmxlbmd0aCkpKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBpZiAoYXJnLnN0YXJ0c1dpdGgoXCItLWluY2x1ZGUtdGFnPVwiKSkge1xuICAgICAgICBpbmNsdWRlVGFncy5wdXNoKC4uLnNwbGl0VGFncyhhcmcuc2xpY2UoXCItLWluY2x1ZGUtdGFnPVwiLmxlbmd0aCkpKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBpZiAoYXJnLnN0YXJ0c1dpdGgoXCItLWV4Y2x1ZGUtdGFnPVwiKSkge1xuICAgICAgICBleGNsdWRlVGFncy5wdXNoKC4uLnNwbGl0VGFncyhhcmcuc2xpY2UoXCItLWV4Y2x1ZGUtdGFnPVwiLmxlbmd0aCkpKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBpZiAoYXJnLnN0YXJ0c1dpdGgoXCItLXNraXAtdGFnPVwiKSkge1xuICAgICAgICBleGNsdWRlVGFncy5wdXNoKC4uLnNwbGl0VGFncyhhcmcuc2xpY2UoXCItLXNraXAtdGFnPVwiLmxlbmd0aCkpKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBpZiAoRVhBTVBMRV9GTEFHUy5oYXMoYXJnKSkge1xuICAgICAgICBjb25zdCBuZXh0VmFsdWUgPSBwcm9jZXNzQXJnc1tpICsgMV1cblxuICAgICAgICBpZiAobmV4dFZhbHVlICYmICFuZXh0VmFsdWUuc3RhcnRzV2l0aChcIi1cIikpIHtcbiAgICAgICAgICBleGFtcGxlUGF0dGVybnMucHVzaChuZXh0VmFsdWUpXG4gICAgICAgICAgaSsrXG4gICAgICAgIH1cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKGFyZy5zdGFydHNXaXRoKFwiLS1leGFtcGxlPVwiKSkge1xuICAgICAgICBleGFtcGxlUGF0dGVybnMucHVzaChhcmcuc2xpY2UoXCItLWV4YW1wbGU9XCIubGVuZ3RoKSlcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKGFyZy5zdGFydHNXaXRoKFwiLS1uYW1lPVwiKSkge1xuICAgICAgICBleGFtcGxlUGF0dGVybnMucHVzaChhcmcuc2xpY2UoXCItLW5hbWU9XCIubGVuZ3RoKSlcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKEdST1VQU19GTEFHUy5oYXMoYXJnKSkge1xuICAgICAgICBjb25zdCBuZXh0VmFsdWUgPSBwcm9jZXNzQXJnc1tpICsgMV1cblxuICAgICAgICBpZiAobmV4dFZhbHVlICYmICFuZXh0VmFsdWUuc3RhcnRzV2l0aChcIi1cIikpIHtcbiAgICAgICAgICBncm91cHMgPSBwYXJzZUludChuZXh0VmFsdWUsIDEwKVxuICAgICAgICAgIGkrK1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChhcmcuc3RhcnRzV2l0aChcIi0tZ3JvdXBzPVwiKSkge1xuICAgICAgICBncm91cHMgPSBwYXJzZUludChhcmcuc2xpY2UoXCItLWdyb3Vwcz1cIi5sZW5ndGgpLCAxMClcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKEdST1VQX05VTUJFUl9GTEFHUy5oYXMoYXJnKSkge1xuICAgICAgICBjb25zdCBuZXh0VmFsdWUgPSBwcm9jZXNzQXJnc1tpICsgMV1cblxuICAgICAgICBpZiAobmV4dFZhbHVlICYmICFuZXh0VmFsdWUuc3RhcnRzV2l0aChcIi1cIikpIHtcbiAgICAgICAgICBncm91cE51bWJlciA9IHBhcnNlSW50KG5leHRWYWx1ZSwgMTApXG4gICAgICAgICAgaSsrXG4gICAgICAgIH1cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKGFyZy5zdGFydHNXaXRoKFwiLS1ncm91cC1udW1iZXI9XCIpKSB7XG4gICAgICAgIGdyb3VwTnVtYmVyID0gcGFyc2VJbnQoYXJnLnNsaWNlKFwiLS1ncm91cC1udW1iZXI9XCIubGVuZ3RoKSwgMTApXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG4gICAgfVxuXG4gICAgZmlsdGVyZWRQcm9jZXNzQXJncy5wdXNoKGFyZylcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgaW5jbHVkZVRhZ3M6IEFycmF5LmZyb20obmV3IFNldChpbmNsdWRlVGFncykpLFxuICAgIGV4Y2x1ZGVUYWdzOiBBcnJheS5mcm9tKG5ldyBTZXQoZXhjbHVkZVRhZ3MpKSxcbiAgICBleGFtcGxlUGF0dGVybnMsXG4gICAgZmlsdGVyZWRQcm9jZXNzQXJncyxcbiAgICBncm91cHMsXG4gICAgZ3JvdXBOdW1iZXJcbiAgfVxufVxuIl19
184
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1maWx0ZXItcGFyc2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3Rlc3RpbmcvdGVzdC1maWx0ZXItcGFyc2VyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7O0dBVUc7QUFDSCxZQUFZO0FBRVosTUFBTSxpQkFBaUIsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxlQUFlLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQTtBQUNuRSxNQUFNLGlCQUFpQixHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsZUFBZSxFQUFFLFlBQVksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFBO0FBQ3hFLE1BQU0sYUFBYSxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFBO0FBQzVELE1BQU0sWUFBWSxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQTtBQUMxQyxNQUFNLGtCQUFrQixHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFBO0FBQ3RELE1BQU0scUJBQXFCLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUE7QUFFNUQ7Ozs7R0FJRztBQUNILFNBQVMsU0FBUyxDQUFDLEtBQUs7SUFDdEIsSUFBSSxDQUFDLEtBQUs7UUFBRSxPQUFPLEVBQUUsQ0FBQTtJQUVyQixPQUFPLEtBQUs7U0FDVCxLQUFLLENBQUMsR0FBRyxDQUFDO1NBQ1YsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7U0FDeEIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFBO0FBQ3BCLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBUyxZQUFZLENBQUMsS0FBSztJQUN6QixPQUFPLEtBQUssQ0FBQyxPQUFPLENB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ZTtRQUNmLG1CQUFtQjtRQUNuQixNQUFNO1FBQ04sV0FBVztRQUNYLGtCQUFrQjtLQUNuQixDQUFBO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUGFyc2VGaWx0ZXJzUmVzdWx0IHR5cGUuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBQYXJzZUZpbHRlcnNSZXN1bHRcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IGluY2x1ZGVUYWdzIC0gVGFncyB0byBpbmNsdWRlLlxuICogQHByb3BlcnR5IHtzdHJpbmdbXX0gZXhjbHVkZVRhZ3MgLSBUYWdzIHRvIGV4Y2x1ZGUuXG4gKiBAcHJvcGVydHkge3N0cmluZ1tdfSBleGFtcGxlUGF0dGVybnMgLSBFeGFtcGxlIG5hbWUgcGF0dGVybnMuXG4gKiBAcHJvcGVydHkge3N0cmluZ1tdfSBmaWx0ZXJlZFByb2Nlc3NBcmdzIC0gUmVtYWluaW5nIHByb2Nlc3MgYXJncyB3aXRoIGZpbHRlciBmbGFncyByZW1vdmVkLlxuICogQHByb3BlcnR5IHtudW1iZXIgfCB1bmRlZmluZWR9IGdyb3VwcyAtIFRvdGFsIG51bWJlciBvZiBncm91cHMgZm9yIHRlc3Qgc3BsaXR0aW5nLlxuICogQHByb3BlcnR5IHtudW1iZXIgfCB1bmRlZmluZWR9IGdyb3VwTnVtYmVyIC0gV2hpY2ggZ3JvdXAgdG8gcnVuICgxLWluZGV4ZWQpLlxuICogQHByb3BlcnR5IHtzdHJpbmcgfCB1bmRlZmluZWR9IHRpbWluZ01hbmlmZXN0UGF0aCAtIEpTT04gdGltaW5nIG1hbmlmZXN0IHBhdGguXG4gKi9cbi8vIEB0cy1jaGVja1xuXG5jb25zdCBJTkNMVURFX1RBR19GTEFHUyA9IG5ldyBTZXQoW1wiLS10YWdcIiwgXCItLWluY2x1ZGUtdGFnXCIsIFwiLXRcIl0pXG5jb25zdCBFWENMVURFX1RBR19GTEFHUyA9IG5ldyBTZXQoW1wiLS1leGNsdWRlLXRhZ1wiLCBcIi0tc2tpcC10YWdcIiwgXCIteFwiXSlcbmNvbnN0IEVYQU1QTEVfRkxBR1MgPSBuZXcgU2V0KFtcIi0tZXhhbXBsZVwiLCBcIi0tbmFtZVwiLCBcIi1lXCJdKVxuY29uc3QgR1JPVVBTX0ZMQUdTID0gbmV3IFNldChbXCItLWdyb3Vwc1wiXSlcbmNvbnN0IEdST1VQX05VTUJFUl9GTEFHUyA9IG5ldyBTZXQoW1wiLS1ncm91cC1udW1iZXJcIl0pXG5jb25zdCBUSU1JTkdfTUFOSUZFU1RfRkxBR1MgPSBuZXcgU2V0KFtcIi0tdGltaW5nLW1hbmlmZXN0XCJdKVxuXG4vKipcbiAqIFJ1bnMgc3BsaXQgdGFncy5cbiAqIEBwYXJhbSB7c3RyaW5nIHwgdW5kZWZpbmVkfSB2YWx1ZSAtIFRhZyBhcmd1bWVudCB2YWx1ZS5cbiAqIEByZXR1cm5zIHtzdHJpbmdbXX0gLSBUYWdzIGxpc3QuXG4gKi9cbmZ1bmN0aW9uIHNwbGl0VGFncyh2YWx1ZSkge1xuICBpZiAoIXZhbHVlKSByZXR1cm4gW11cblxuICByZXR1cm4gdmFsdWVcbiAgICAuc3BsaXQoXCIsXCIpXG4gICAgLm1hcCgodGFnKSA9PiB0YWcudHJpbSgpKVxuICAgIC5maWx0ZXIoQm9vbGVhbilcbn1cblxuLyoqXG4gKiBSdW5zIGVzY2FwZSByZWcgZXhwLlxuICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIC0gVmFsdWUuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSAtIEVzY2FwZWQgdmFsdWUgZm9yIHJlZ2V4LlxuICovXG5mdW5jdGlvbiBlc2NhcGVSZWdFeHAodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlLnJlcGxhY2UoL1suKis/XiR7fSgpfFtcXF1cXFxcXS9nLCBcIlxcXFwkJlwiKVxufVxuXG4vKipcbiAqIFJ1bnMgdGhlIG5vcm1hbGl6ZUV4YW1wbGVQYXR0ZXJucyBoZWxwZXIuXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBwYXR0ZXJucyAtIFBhdHRlcm5zLlxuICogQHJldHVybnMge1JlZ0V4cFtdfSAtIE5vcm1hbGl6ZWQgcGF0dGVybnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVFeGFtcGxlUGF0dGVybnMocGF0dGVybnMpIHtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IFtdXG5cbiAgZm9yIChjb25zdCBwYXR0ZXJuIG9mIHBhdHRlcm5zKSB7XG4gICAgY29uc3QgcmVnZXhNYXRjaCA9IHBhdHRlcm4ubWF0Y2goL15cXC8oLispXFwvKFtnaW1zdXldKikkLylcblxuICAgIGlmIChyZWdleE1hdGNoKSB7XG4gICAgICBub3JtYWxpemVkLnB1c2gobmV3IFJlZ0V4cChyZWdleE1hdGNoWzFdLCByZWdleE1hdGNoWzJdKSlcbiAgICB9IGVsc2Uge1xuICAgICAgbm9ybWFsaXplZC5wdXNoKG5ldyBSZWdFeHAoZXNjYXBlUmVnRXhwKHBhdHRlcm4pKSlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbm9ybWFsaXplZFxufVxuXG4vKipcbiAqIFJ1bnMgdGhlIHBhcnNlRmlsdGVycyBoZWxwZXIuXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBwcm9jZXNzQXJncyAtIFByb2Nlc3MgYXJncy5cbiAqIEByZXR1cm5zIHtQYXJzZUZpbHRlcnNSZXN1bHR9IC0gUGFyc2VkIHRhZ3MsIGdyb3VwIG9wdGlvbnMsIGFuZCBwcm9jZXNzIGFyZ3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUZpbHRlcnMocHJvY2Vzc0FyZ3MpIHtcbiAgY29uc3QgaW5jbHVkZVRhZ3MgPSBbXVxuICBjb25zdCBleGNsdWRlVGFncyA9IFtdXG4gIGNvbnN0IGZpbHRlcmVkUHJvY2Vzc0FyZ3MgPSBwcm9jZXNzQXJncy5sZW5ndGggPiAwID8gW3Byb2Nlc3NBcmdzWzBdXSA6IFtdXG4gIGNvbnN0IGV4YW1wbGVQYXR0ZXJucyA9IFtdXG5cbiAgLyoqXG4gICAqIERlZmluZXMgZ3JvdXBzLlxuICAgKiBAdHlwZSB7bnVtYmVyIHwgdW5kZWZpbmVkfSAqL1xuICBsZXQgZ3JvdXBzXG4gIC8qKlxuICAgKiBEZWZpbmVzIGdyb3VwTnVtYmVyLlxuICAgKiBAdHlwZSB7bnVtYmVyIHwgdW5kZWZpbmVkfSAqL1xuICBsZXQgZ3JvdXBOdW1iZXJcbiAgLyoqIEB0eXBlIHtzdHJpbmcgfCB1bmRlZmluZWR9ICovXG4gIGxldCB0aW1pbmdNYW5pZmVzdFBhdGhcblxuICBsZXQgaW5SZXN0QXJncyA9IGZhbHNlXG5cbiAgZm9yIChsZXQgaSA9IDE7IGkgPCBwcm9jZXNzQXJncy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGFyZyA9IHByb2Nlc3NBcmdzW2ldXG5cbiAgICBpZiAoYXJnID09PSBcIi0tXCIpIHtcbiAgICAgIGluUmVzdEFyZ3MgPSB0cnVlXG4gICAgICBmaWx0ZXJlZFByb2Nlc3NBcmdzLnB1c2goYXJnKVxuICAgICAgY29udGludWVcbiAgICB9XG5cbiAgICBpZiAoIWluUmVzdEFyZ3MpIHtcbiAgICAgIGlmIChJTkNMVURFX1RBR19GTEFHUy5oYXMoYXJnKSkge1xuICAgICAgICBjb25zdCBuZXh0VmFsdWUgPSBwcm9jZXNzQXJnc1tpICsgMV1cblxuICAgICAgICBpZiAobmV4dFZhbHVlICYmICFuZXh0VmFsdWUuc3RhcnRzV2l0aChcIi1cIikpIHtcbiAgICAgICAgICBpbmNsdWRlVGFncy5wdXNoKC4uLnNwbGl0VGFncyhuZXh0VmFsdWUpKVxuICAgICAgICAgIGkrK1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChFWENMVURFX1RBR19GTEFHUy5oYXMoYXJnKSkge1xuICAgICAgICBjb25zdCBuZXh0VmFsdWUgPSBwcm9jZXNzQXJnc1tpICsgMV1cblxuICAgICAgICBpZiAobmV4dFZhbHVlICYmICFuZXh0VmFsdWUuc3RhcnRzV2l0aChcIi1cIikpIHtcbiAgICAgICAgICBleGNsdWRlVGFncy5wdXNoKC4uLnNwbGl0VGFncyhuZXh0VmFsdWUpKVxuICAgICAgICAgIGkrK1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChhcmcuc3RhcnRzV2l0aChcIi0tdGFnPVwiKSkge1xuICAgICAgICBpbmNsdWRlVGFncy5wdXNoKC4uLnNwbGl0VGFncyhhcmcuc2xpY2UoXCItLXRhZz1cIi5sZW5ndGgpKSlcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKGFyZy5zdGFydHNXaXRoKFwiLS1pbmNsdWRlLXRhZz1cIikpIHtcbiAgICAgICAgaW5jbHVkZVRhZ3MucHVzaCguLi5zcGxpdFRhZ3MoYXJnLnNsaWNlKFwiLS1pbmNsdWRlLXRhZz1cIi5sZW5ndGgpKSlcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKGFyZy5zdGFydHNXaXRoKFwiLS1leGNsdWRlLXRhZz1cIikpIHtcbiAgICAgICAgZXhjbHVkZVRhZ3MucHVzaCguLi5zcGxpdFRhZ3MoYXJnLnNsaWNlKFwiLS1leGNsdWRlLXRhZz1cIi5sZW5ndGgpKSlcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKGFyZy5zdGFydHNXaXRoKFwiLS1za2lwLXRhZz1cIikpIHtcbiAgICAgICAgZXhjbHVkZVRhZ3MucHVzaCguLi5zcGxpdFRhZ3MoYXJnLnNsaWNlKFwiLS1za2lwLXRhZz1cIi5sZW5ndGgpKSlcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKEVYQU1QTEVfRkxBR1MuaGFzKGFyZykpIHtcbiAgICAgICAgY29uc3QgbmV4dFZhbHVlID0gcHJvY2Vzc0FyZ3NbaSArIDFdXG5cbiAgICAgICAgaWYgKG5leHRWYWx1ZSAmJiAhbmV4dFZhbHVlLnN0YXJ0c1dpdGgoXCItXCIpKSB7XG4gICAgICAgICAgZXhhbXBsZVBhdHRlcm5zLnB1c2gobmV4dFZhbHVlKVxuICAgICAgICAgIGkrK1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChhcmcuc3RhcnRzV2l0aChcIi0tZXhhbXBsZT1cIikpIHtcbiAgICAgICAgZXhhbXBsZVBhdHRlcm5zLnB1c2goYXJnLnNsaWNlKFwiLS1leGFtcGxlPVwiLmxlbmd0aCkpXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChhcmcuc3RhcnRzV2l0aChcIi0tbmFtZT1cIikpIHtcbiAgICAgICAgZXhhbXBsZVBhdHRlcm5zLnB1c2goYXJnLnNsaWNlKFwiLS1uYW1lPVwiLmxlbmd0aCkpXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChHUk9VUFNfRkxBR1MuaGFzKGFyZykpIHtcbiAgICAgICAgY29uc3QgbmV4dFZhbHVlID0gcHJvY2Vzc0FyZ3NbaSArIDFdXG5cbiAgICAgICAgaWYgKG5leHRWYWx1ZSAmJiAhbmV4dFZhbHVlLnN0YXJ0c1dpdGgoXCItXCIpKSB7XG4gICAgICAgICAgZ3JvdXBzID0gcGFyc2VJbnQobmV4dFZhbHVlLCAxMClcbiAgICAgICAgICBpKytcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBpZiAoYXJnLnN0YXJ0c1dpdGgoXCItLWdyb3Vwcz1cIikpIHtcbiAgICAgICAgZ3JvdXBzID0gcGFyc2VJbnQoYXJnLnNsaWNlKFwiLS1ncm91cHM9XCIubGVuZ3RoKSwgMTApXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChHUk9VUF9OVU1CRVJfRkxBR1MuaGFzKGFyZykpIHtcbiAgICAgICAgY29uc3QgbmV4dFZhbHVlID0gcHJvY2Vzc0FyZ3NbaSArIDFdXG5cbiAgICAgICAgaWYgKG5leHRWYWx1ZSAmJiAhbmV4dFZhbHVlLnN0YXJ0c1dpdGgoXCItXCIpKSB7XG4gICAgICAgICAgZ3JvdXBOdW1iZXIgPSBwYXJzZUludChuZXh0VmFsdWUsIDEwKVxuICAgICAgICAgIGkrK1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChhcmcuc3RhcnRzV2l0aChcIi0tZ3JvdXAtbnVtYmVyPVwiKSkge1xuICAgICAgICBncm91cE51bWJlciA9IHBhcnNlSW50KGFyZy5zbGljZShcIi0tZ3JvdXAtbnVtYmVyPVwiLmxlbmd0aCksIDEwKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBpZiAoVElNSU5HX01BTklGRVNUX0ZMQUdTLmhhcyhhcmcpKSB7XG4gICAgICAgIGNvbnN0IG5leHRWYWx1ZSA9IHByb2Nlc3NBcmdzW2kgKyAxXVxuXG4gICAgICAgIGlmIChuZXh0VmFsdWUgJiYgIW5leHRWYWx1ZS5zdGFydHNXaXRoKFwiLVwiKSkge1xuICAgICAgICAgIHRpbWluZ01hbmlmZXN0UGF0aCA9IG5leHRWYWx1ZVxuICAgICAgICAgIGkrK1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmIChhcmcuc3RhcnRzV2l0aChcIi0tdGltaW5nLW1hbmlmZXN0PVwiKSkge1xuICAgICAgICB0aW1pbmdNYW5pZmVzdFBhdGggPSBhcmcuc2xpY2UoXCItLXRpbWluZy1tYW5pZmVzdD1cIi5sZW5ndGgpXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG4gICAgfVxuXG4gICAgZmlsdGVyZWRQcm9jZXNzQXJncy5wdXNoKGFyZylcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgaW5jbHVkZVRhZ3M6IEFycmF5LmZyb20obmV3IFNldChpbmNsdWRlVGFncykpLFxuICAgIGV4Y2x1ZGVUYWdzOiBBcnJheS5mcm9tKG5ldyBTZXQoZXhjbHVkZVRhZ3MpKSxcbiAgICBleGFtcGxlUGF0dGVybnMsXG4gICAgZmlsdGVyZWRQcm9jZXNzQXJncyxcbiAgICBncm91cHMsXG4gICAgZ3JvdXBOdW1iZXIsXG4gICAgdGltaW5nTWFuaWZlc3RQYXRoXG4gIH1cbn1cbiJdfQ==
@@ -27,6 +27,7 @@ export default class TestSuiteSplitter {
27
27
  _groupNumber: number;
28
28
  _testFiles: string[];
29
29
  _baseDirectory: string;
30
+ _timingManifest: Record<string, number>;
30
31
  /**
31
32
  * Runs constructor.
32
33
  * @param {object} args - Options.
@@ -34,12 +35,14 @@ export default class TestSuiteSplitter {
34
35
  * @param {number} args.groupNumber - Which group to return (1-indexed).
35
36
  * @param {string[]} args.testFiles - All discovered test file paths.
36
37
  * @param {string} [args.baseDirectory] - Base directory for relative path computation.
38
+ * @param {ReturnType<typeof JSON.parse>} [args.timingManifest] - Relative test paths mapped to durations.
37
39
  */
38
- constructor({ groups, groupNumber, testFiles, baseDirectory, ...restArgs }: {
40
+ constructor({ groups, groupNumber, testFiles, baseDirectory, timingManifest, ...restArgs }: {
39
41
  groups: number;
40
42
  groupNumber: number;
41
43
  testFiles: string[];
42
44
  baseDirectory?: string;
45
+ timingManifest?: ReturnType<typeof JSON.parse>;
43
46
  });
44
47
  /**
45
48
  * Returns the test files assigned to this group.
@@ -57,6 +60,18 @@ export default class TestSuiteSplitter {
57
60
  * @returns {number} - Weight value.
58
61
  */
59
62
  computeWeight(filePath: string): number;
63
+ /**
64
+ * Keeps only usable positive finite duration entries keyed by normalized relative path.
65
+ * @param {ReturnType<typeof JSON.parse>} timingManifest - Parsed timing manifest.
66
+ * @returns {Record<string, number>} - Valid normalized duration weights.
67
+ */
68
+ normalizeTimingManifest(timingManifest: ReturnType<typeof JSON.parse>): Record<string, number>;
69
+ /**
70
+ * Normalizes a relative test path to the manifest's portable slash format.
71
+ * @param {string} filePath - Relative test path.
72
+ * @returns {string} - Normalized relative test path.
73
+ */
74
+ normalizeRelativePath(filePath: string): string;
60
75
  /**
61
76
  * Sorts files by weight descending, then by path for determinism.
62
77
  * @param {SplitterFileEntry[]} files - Weighted files.
@@ -1 +1 @@
1
- {"version":3,"file":"test-suite-splitter.d.ts","sourceRoot":"","sources":["../../../src/testing/test-suite-splitter.js"],"names":[],"mappings":"AAOG,YAAkB,iBAAiB,GACnC;;;;IAAmB,QAAQ,EAAhB,MAAM,CACjB;;;;IAAmB,MAAM,EAAd,MAAM,CACnB;CAAA,CAAA;AAIE,YAAkB,WAAW,GAC7B;;;;IAAmB,WAAW,EAAnB,MAAM,CACjB;;;;IAAqB,KAAK,EAAf,MAAM,EAAE,CACrB;CAAA,CAAA;AAmBD;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAiB;IAoB7B,OAAO;IACP,YAAY;IACZ,UAAU;IACV,cAAc;IAtBrB;;;;;;;OAOG;IACH,YAAY,EAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,QAAQ,EAAC,EALrE;QAAqB,MAAM,EAAnB,MAAM,CACd;QAAqB,WAAW,EAAxB,MAAM,CACd;QAAuB,SAAS,EAAxB,MAAM,EAAE,CAChB;QAAsB,aAAa,AAAnC,CACF,EADU,MAAM,CAChB;KACuE,EAevE;IAED;;;OAGG;IACH,aAAa,IAFA,MAAM,EAAE,CAQpB;IAED;;;OAGG;IACH,oBAAoB,IAFP,iBAAiB,EAAE,CAO/B;IAED;;;;OAIG;IACH,aAAa,CAAC,QAAQ,EAHX,MAGW,GAFT,MAAM,CAwBlB;IAED;;;;OAIG;IACH,sBAAsB,CAAC,KAAK,EAHjB,iBAAiB,EAGA,GAFf,iBAAiB,EAAE,CAU/B;IAED;;;;;OAKG;IACH,kBAAkB,CAAC,WAAW,EAHnB,iBAAiB,EAGE,GAFjB,WAAW,EAAE,CAoBzB;IAED;;;;;OAKG;IACH,kBAAkB,CAAC,OAAO,EAHf,WAAW,EAGI,GAFb,WAAW,CAYvB;CACF"}
1
+ {"version":3,"file":"test-suite-splitter.d.ts","sourceRoot":"","sources":["../../../src/testing/test-suite-splitter.js"],"names":[],"mappings":"AAOG,YAAkB,iBAAiB,GACnC;;;;IAAmB,QAAQ,EAAhB,MAAM,CACjB;;;;IAAmB,MAAM,EAAd,MAAM,CACnB;CAAA,CAAA;AAIE,YAAkB,WAAW,GAC7B;;;;IAAmB,WAAW,EAAnB,MAAM,CACjB;;;;IAAqB,KAAK,EAAf,MAAM,EAAE,CACrB;CAAA,CAAA;AAmBD;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAiB;IAqB7B,OAAO;IACP,YAAY;IACZ,UAAU;IACV,cAAc;IACd,eAAe;IAxBtB;;;;;;;;OAQG;IACH,YAAY,EAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,GAAG,QAAQ,EAAC,EANrF;QAAqB,MAAM,EAAnB,MAAM,CACd;QAAqB,WAAW,EAAxB,MAAM,CACd;QAAuB,SAAS,EAAxB,MAAM,EAAE,CAChB;QAAsB,aAAa,AAAnC,CACA,EADQ,MAAM,CACd;QAA6C,cAAc,AAA3D,CACF,EADU,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CACvC;KACuF,EAgBvF;IAED;;;OAGG;IACH,aAAa,IAFA,MAAM,EAAE,CAQpB;IAED;;;OAGG;IACH,oBAAoB,IAFP,iBAAiB,EAAE,CAO/B;IAED;;;;OAIG;IACH,aAAa,CAAC,QAAQ,EAHX,MAGW,GAFT,MAAM,CA+BlB;IAED;;;;OAIG;IACH,uBAAuB,CAAC,cAAc,EAH3B,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAGD,GAFzB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiBlC;IAED;;;;OAIG;IACH,qBAAqB,CAAC,QAAQ,EAHnB,MAGmB,GAFjB,MAAM,CAMlB;IAED;;;;OAIG;IACH,sBAAsB,CAAC,KAAK,EAHjB,iBAAiB,EAGA,GAFf,iBAAiB,EAAE,CAU/B;IAED;;;;;OAKG;IACH,kBAAkB,CAAC,WAAW,EAHnB,iBAAiB,EAGE,GAFjB,WAAW,EAAE,CAoBzB;IAED;;;;;OAKG;IACH,kBAAkB,CAAC,OAAO,EAHf,WAAW,EAGI,GAFb,WAAW,CAYvB;CACF"}
@@ -39,8 +39,9 @@ export default class TestSuiteSplitter {
39
39
  * @param {number} args.groupNumber - Which group to return (1-indexed).
40
40
  * @param {string[]} args.testFiles - All discovered test file paths.
41
41
  * @param {string} [args.baseDirectory] - Base directory for relative path computation.
42
+ * @param {ReturnType<typeof JSON.parse>} [args.timingManifest] - Relative test paths mapped to durations.
42
43
  */
43
- constructor({ groups, groupNumber, testFiles, baseDirectory, ...restArgs }) {
44
+ constructor({ groups, groupNumber, testFiles, baseDirectory, timingManifest, ...restArgs }) {
44
45
  restArgsError(restArgs);
45
46
  if (!Number.isInteger(groups) || groups < 1) {
46
47
  throw new Error(`--groups must be a positive integer, got: ${groups}`);
@@ -52,6 +53,7 @@ export default class TestSuiteSplitter {
52
53
  this._groupNumber = groupNumber;
53
54
  this._testFiles = testFiles;
54
55
  this._baseDirectory = baseDirectory || process.cwd();
56
+ this._timingManifest = this.normalizeTimingManifest(timingManifest);
55
57
  }
56
58
  /**
57
59
  * Returns the test files assigned to this group.
@@ -79,7 +81,12 @@ export default class TestSuiteSplitter {
79
81
  * @returns {number} - Weight value.
80
82
  */
81
83
  computeWeight(filePath) {
82
- const relativePath = path.relative(this._baseDirectory, filePath).split(path.sep).join("/");
84
+ const relativePath = this.normalizeRelativePath(path.relative(this._baseDirectory, filePath));
85
+ const projectRelativePath = this.normalizeRelativePath(path.join(path.basename(this._baseDirectory), relativePath));
86
+ const duration = this._timingManifest[relativePath] ?? this._timingManifest[projectRelativePath];
87
+ if (duration !== undefined) {
88
+ return duration;
89
+ }
83
90
  let weight = DEFAULT_WEIGHT;
84
91
  // Extract the type directory from the relative path.
85
92
  // Matches both "spec/system/..." (base is project root) and "system/..." (base is spec/ itself).
@@ -96,6 +103,34 @@ export default class TestSuiteSplitter {
96
103
  }
97
104
  return weight;
98
105
  }
106
+ /**
107
+ * Keeps only usable positive finite duration entries keyed by normalized relative path.
108
+ * @param {ReturnType<typeof JSON.parse>} timingManifest - Parsed timing manifest.
109
+ * @returns {Record<string, number>} - Valid normalized duration weights.
110
+ */
111
+ normalizeTimingManifest(timingManifest) {
112
+ /** @type {Record<string, number>} */
113
+ const normalized = {};
114
+ if (!timingManifest || typeof timingManifest !== "object" || Array.isArray(timingManifest)) {
115
+ return normalized;
116
+ }
117
+ for (const [filePath, duration] of Object.entries(timingManifest)) {
118
+ if (typeof duration === "number" && Number.isFinite(duration) && duration > 0) {
119
+ normalized[this.normalizeRelativePath(filePath)] = duration;
120
+ }
121
+ }
122
+ return normalized;
123
+ }
124
+ /**
125
+ * Normalizes a relative test path to the manifest's portable slash format.
126
+ * @param {string} filePath - Relative test path.
127
+ * @returns {string} - Normalized relative test path.
128
+ */
129
+ normalizeRelativePath(filePath) {
130
+ return filePath
131
+ .replaceAll("\\", "/")
132
+ .replace(/^\.\//, "");
133
+ }
99
134
  /**
100
135
  * Sorts files by weight descending, then by path for determinism.
101
136
  * @param {SplitterFileEntry[]} files - Weighted files.
@@ -146,4 +181,4 @@ export default class TestSuiteSplitter {
146
181
  return lightest;
147
182
  }
148
183
  }
149
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1zdWl0ZS1zcGxpdHRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90ZXN0aW5nL3Rlc3Qtc3VpdGUtc3BsaXR0ZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQTtBQUN2QixPQUFPLGFBQWEsTUFBTSw2QkFBNkIsQ0FBQTtBQUV2RDs7Ozs7R0FLRztBQUVIOzs7OztHQUtHO0FBRUgsOENBQThDO0FBQzlDLE1BQU0sY0FBYyxHQUFHLENBQUMsQ0FBQTtBQUV4Qjs7OztHQUlHO0FBQ0gsTUFBTSxpQkFBaUIsR0FBRztJQUN4QixNQUFNLEVBQUUsRUFBRTtJQUNWLGlCQUFpQixFQUFFLEVBQUU7SUFDckIsVUFBVSxFQUFFLENBQUM7Q0FDZCxDQUFBO0FBRUQsaUZBQWlGO0FBQ2pGLE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxDQUFBO0FBRWpDOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8saUJBQWlCO0lBQ3BDOzs7Ozs7O09BT0c7SUFDSCxZQUFZLEVBQUMsTUFBTSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFLEdBQUcsUUFBUSxFQUFDO1FBQ3RFLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUV2QixJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDNUMsTUFBTSxJQUFJLEtBQUssQ0FBQyw2Q0FBNkMsTUFBTSxFQUFFLENBQUMsQ0FBQTtRQUN4RSxDQUFDO1FBRUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLElBQUksV0FBVyxHQUFHLENBQUMsSUFBSSxXQUFXLEdBQUcsTUFBTSxFQUFFLENBQUM7WUFDOUUsTUFBTSxJQUFJLEtBQUssQ0FBQyx3Q0FBd0MsTUFBTSxVQUFVLFdBQVcsRUFBRSxDQUFDLENB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LEVBQUMsV0FBVyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFDLENBQUMsQ0FBQTtRQUMzQyxDQUFDO1FBRUQsS0FBSyxNQUFNLEtBQUssSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUNoQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLENBQUE7WUFFakQsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFBO1lBQ25DLFFBQVEsQ0FBQyxXQUFXLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQTtRQUN0QyxDQUFDO1FBRUQsT0FBTyxPQUFPLENBQUE7SUFDaEIsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsa0JBQWtCLENBQUMsT0FBTztRQUN4QixJQUFJLFFBQVEsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFFekIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUN4QyxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEdBQUcsUUFBUSxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUNsRCxRQUFRLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFBO1lBQ3ZCLENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxRQUFRLENBQUE7SUFDakIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCJcbmltcG9ydCByZXN0QXJnc0Vycm9yIGZyb20gXCIuLi91dGlscy9yZXN0LWFyZ3MtZXJyb3IuanNcIlxuXG4vKipcbiAqIFNwbGl0dGVyRmlsZUVudHJ5IHR5cGUuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBTcGxpdHRlckZpbGVFbnRyeVxuICogQHByb3BlcnR5IHtzdHJpbmd9IGZpbGVQYXRoIC0gQWJzb2x1dGUgZmlsZSBwYXRoLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IHdlaWdodCAtIENvbXB1dGVkIHdlaWdodCBmb3IgbG9hZCBiYWxhbmNpbmcuXG4gKi9cblxuLyoqXG4gKiBHcm91cEJ1Y2tldCB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gR3JvdXBCdWNrZXRcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB0b3RhbFdlaWdodCAtIEFjY3VtdWxhdGVkIHdlaWdodC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IGZpbGVzIC0gRmlsZXMgYXNzaWduZWQgdG8gdGhpcyBncm91cC5cbiAqL1xuXG4vKiogRGVmYXVsdCB3ZWlnaHQgZm9yIGEgcmVndWxhciB0ZXN0IGZpbGUuICovXG5jb25zdCBERUZBVUxUX1dFSUdIVCA9IDFcblxuLyoqXG4gKiBXZWlnaHQgbXVsdGlwbGllcnMgYnkgc3BlYyBkaXJlY3RvcnkgbmFtZS5cbiAqIEhlYXZpZXIgdGVzdCB0eXBlcyBnZXQgaGlnaGVyIHdlaWdodHMgc28gZ3JlZWR5IGRpc3RyaWJ1dGlvbiBiYWxhbmNlcyB3YWxsLWNsb2NrIHRpbWUuXG4gKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgbnVtYmVyPn1cbiAqL1xuY29uc3QgRElSRUNUT1JZX1dFSUdIVFMgPSB7XG4gIHN5c3RlbTogMjAsXG4gIFwiZnJvbnRlbmQtbW9kZWxzXCI6IDEwLFxuICBjb250cm9sbGVyOiAzXG59XG5cbi8qKiBFeHRyYSBtdWx0aXBsaWVyIGFwcGxpZWQgdG8gYnJvd3NlciBzcGVjIGZpbGVzIG9uIHRvcCBvZiBkaXJlY3Rvcnkgd2VpZ2h0LiAqL1xuY29uc3QgQlJPV1NFUl9TUEVDX01VTFRJUExJRVIgPSAyXG5cbi8qKlxuICogU3BsaXRzIGEgbGlzdCBvZiB0ZXN0IGZpbGVzIGludG8gYmFsYW5jZWQgZ3JvdXBzIHVzaW5nIGEgZ3JlZWR5IGxvYWQtYmFsYW5jaW5nIGFsZ29yaXRobS5cbiAqIE1vZGVsZWQgYWZ0ZXIgdGVzdF9zdWl0ZV9zcGxpdHRlciBmb3IgUlNwZWMuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRlc3RTdWl0ZVNwbGl0dGVyIHtcbiAgLyoqXG4gICAqIFJ1bnMgY29uc3RydWN0b3IuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGFyZ3MuZ3JvdXBzIC0gVG90YWwgbnVtYmVyIG9mIGdyb3Vwcy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGFyZ3MuZ3JvdXBOdW1iZXIgLSBXaGljaCBncm91cCB0byByZXR1cm4gKDEtaW5kZXhlZCkuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGFyZ3MudGVzdEZpbGVzIC0gQWxsIGRpc2NvdmVyZWQgdGVzdCBmaWxlIHBhdGhzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2FyZ3MuYmFzZURpcmVjdG9yeV0gLSBCYXNlIGRpcmVjdG9yeSBmb3IgcmVsYXRpdmUgcGF0aCBjb21wdXRhdGlvbi5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtncm91cHMsIGdyb3VwTnVtYmVyLCB0ZXN0RmlsZXMsIGJhc2VEaXJlY3RvcnksIC4uLnJlc3RBcmdzfSkge1xuICAgIHJlc3RBcmdzRXJyb3IocmVzdEFyZ3MpXG5cbiAgICBpZiAoIU51bWJlci5pc0ludGVnZXIoZ3JvdXBzKSB8fCBncm91cHMgPCAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYC0tZ3JvdXBzIG11c3QgYmUgYSBwb3NpdGl2ZSBpbnRlZ2VyLCBnb3Q6ICR7Z3JvdXBzfWApXG4gICAgfVxuXG4gICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKGdyb3VwTnVtYmVyKSB8fCBncm91cE51bWJlciA8IDEgfHwgZ3JvdXBOdW1iZXIgPiBncm91cHMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgLS1ncm91cC1udW1iZXIgbXVzdCBiZSBiZXR3ZWVuIDEgYW5kICR7Z3JvdXBzfSwgZ290OiAke2dyb3VwTnVtYmVyfWApXG4gICAgfVxuXG4gICAgdGhpcy5fZ3JvdXBzID0gZ3JvdXBzXG4gICAgdGhpcy5fZ3JvdXBOdW1iZXIgPSBncm91cE51bWJlclxuICAgIHRoaXMuX3Rlc3RGaWxlcyA9IHRlc3RGaWxlc1xuICAgIHRoaXMuX2Jhc2VEaXJlY3RvcnkgPSBiYXNlRGlyZWN0b3J5IHx8IHByb2Nlc3MuY3dkKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSB0ZXN0IGZpbGVzIGFzc2lnbmVkIHRvIHRoaXMgZ3JvdXAuXG4gICAqIEByZXR1cm5zIHtzdHJpbmdbXX0gLSBGaWxlIHBhdGhzIGZvciB0aGUgcmVxdWVzdGVkIGdyb3VwLlxuICAgKi9cbiAgZ2V0R3JvdXBGaWxlcygpIHtcbiAgICBjb25zdCB3ZWlnaHRlZCA9IHRoaXMuY29tcHV0ZVdlaWdodGVkRmlsZXMoKVxuICAgIGNvbnN0IHNvcnRlZCA9IHRoaXMuc29ydEJ5V2VpZ2h0RGVzY2VuZGluZyh3ZWlnaHRlZClcbiAgICBjb25zdCBidWNrZXRzID0gdGhpcy5kaXN0cmlidXRlR3JlZWRpbHkoc29ydGVkKVxuXG4gICAgcmV0dXJuIGJ1Y2tldHNbdGhpcy5fZ3JvdXBOdW1iZXIgLSAxXS5maWxlc1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXB1dGVzIHdlaWdodCBmb3IgZWFjaCB0ZXN0IGZpbGUgYmFzZWQgb24gZGlyZWN0b3J5IHR5cGUgYW5kIGZpbGUgc3VmZml4LlxuICAgKiBAcmV0dXJucyB7U3BsaXR0ZXJGaWxlRW50cnlbXX0gLSBXZWlnaHRlZCBmaWxlIGVudHJpZXMuXG4gICAqL1xuICBjb21wdXRlV2VpZ2h0ZWRGaWxlcygpIHtcbiAgICByZXR1cm4gdGhpcy5fdGVzdEZpbGVzLm1hcCgoZmlsZVBhdGgpID0+ICh7XG4gICAgICBmaWxlUGF0aCxcbiAgICAgIHdlaWdodDogdGhpcy5jb21wdXRlV2VpZ2h0KGZpbGVQYXRoKVxuICAgIH0pKVxuICB9XG5cbiAgLyoqXG4gICAqIENvbXB1dGVzIHRoZSB3ZWlnaHQgZm9yIGEgc2luZ2xlIGZpbGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aCAtIEFic29sdXRlIGZpbGUgcGF0aC5cbiAgICogQHJldHVybnMge251bWJlcn0gLSBXZWlnaHQgdmFsdWUuXG4gICAqL1xuICBjb21wdXRlV2VpZ2h0KGZpbGVQYXRoKSB7XG4gICAgY29uc3QgcmVsYXRpdmVQYXRoID0gcGF0aC5yZWxhdGl2ZSh0aGlzLl9iYXNlRGlyZWN0b3J5LCBmaWxlUGF0aCkuc3BsaXQocGF0aC5zZXApLmpvaW4oXCIvXCIpXG4gICAgbGV0IHdlaWdodCA9IERFRkFVTFRfV0VJR0hUXG5cbiAgICAvLyBFeHRyYWN0IHRoZSB0eXBlIGRpcmVjdG9yeSBmcm9tIHRoZSByZWxhdGl2ZSBwYXRoLlxuICAgIC8vIE1hdGNoZXMgYm90aCBcInNwZWMvc3lzdGVtLy4uLlwiIChiYXNlIGlzIHByb2plY3Qgcm9vdCkgYW5kIFwic3lzdGVtLy4uLlwiIChiYXNlIGlzIHNwZWMvIGl0c2VsZikuXG4gICAgY29uc3Qgc3BlY0Rpck1hdGNoID0gcmVsYXRpdmVQYXRoLm1hdGNoKC9eKD86KD86c3BlY3xfX3Rlc3RzX198dGVzdHMpXFwvKT8oW14vXSspXFwvLylcblxuICAgIGlmIChzcGVjRGlyTWF0Y2gpIHtcbiAgICAgIGNvbnN0IGRpck5hbWUgPSBzcGVjRGlyTWF0Y2hbMV1cblxuICAgICAgaWYgKERJUkVDVE9SWV9XRUlHSFRTW2Rpck5hbWVdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgd2VpZ2h0ID0gRElSRUNUT1JZX1dFSUdIVFNbZGlyTmFtZV1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBCcm93c2VyIHNwZWMgZmlsZXMgYXJlIGhlYXZpZXJcbiAgICBpZiAoZmlsZVBhdGguZW5kc1dpdGgoXCIuYnJvd3Nlci1zcGVjLmpzXCIpIHx8IGZpbGVQYXRoLmVuZHNXaXRoKFwiLmJyb3dzZXItc3BlYy5tanNcIikpIHtcbiAgICAgIHdlaWdodCAqPSBCUk9XU0VSX1NQRUNfTVVMVElQTElFUlxuICAgIH1cblxuICAgIHJldHVybiB3ZWlnaHRcbiAgfVxuXG4gIC8qKlxuICAgKiBTb3J0cyBmaWxlcyBieSB3ZWlnaHQgZGVzY2VuZGluZywgdGhlbiBieSBwYXRoIGZvciBkZXRlcm1pbmlzbS5cbiAgICogQHBhcmFtIHtTcGxpdHRlckZpbGVFbnRyeVtdfSBmaWxlcyAtIFdlaWdodGVkIGZpbGVzLlxuICAgKiBAcmV0dXJucyB7U3BsaXR0ZXJGaWxlRW50cnlbXX0gLSBTb3J0ZWQgZmlsZXMuXG4gICAqL1xuICBzb3J0QnlXZWlnaHREZXNjZW5kaW5nKGZpbGVzKSB7XG4gICAgcmV0dXJuIFsuLi5maWxlc10uc29ydCgoYSwgYikgPT4ge1xuICAgICAgaWYgKGIud2VpZ2h0ICE9PSBhLndlaWdodCkge1xuICAgICAgICByZXR1cm4gYi53ZWlnaHQgLSBhLndlaWdodFxuICAgICAgfVxuXG4gICAgICByZXR1cm4gYS5maWxlUGF0aC5sb2NhbGVDb21wYXJlKGIuZmlsZVBhdGgpXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXN0cmlidXRlcyBmaWxlcyBncmVlZGlseSBpbnRvIE4gYmFsYW5jZWQgZ3JvdXBzLlxuICAgKiBFYWNoIGZpbGUgaXMgYXNzaWduZWQgdG8gdGhlIGdyb3VwIHdpdGggdGhlIGxlYXN0IGFjY3VtdWxhdGVkIHdlaWdodC5cbiAgICogQHBhcmFtIHtTcGxpdHRlckZpbGVFbnRyeVtdfSBzb3J0ZWRGaWxlcyAtIEZpbGVzIHNvcnRlZCBieSB3ZWlnaHQgZGVzY2VuZGluZy5cbiAgICogQHJldHVybnMge0dyb3VwQnVja2V0W119IC0gQXJyYXkgb2YgZ3JvdXAgYnVja2V0cy5cbiAgICovXG4gIGRpc3RyaWJ1dGVHcmVlZGlseShzb3J0ZWRGaWxlcykge1xuICAgIC8qKlxuICAgICAqIEJ1Y2tldHMuXG4gICAgICogQHR5cGUge0dyb3VwQnVja2V0W119ICovXG4gICAgY29uc3QgYnVja2V0cyA9IFtdXG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2dyb3VwczsgaSsrKSB7XG4gICAgICBidWNrZXRzLnB1c2goe3RvdGFsV2VpZ2h0OiAwLCBmaWxlczogW119KVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZW50cnkgb2Ygc29ydGVkRmlsZXMpIHtcbiAgICAgIGNvbnN0IGxpZ2h0ZXN0ID0gdGhpcy5maW5kTGlnaHRlc3RCdWNrZXQoYnVja2V0cylcblxuICAgICAgbGlnaHRlc3QuZmlsZXMucHVzaChlbnRyeS5maWxlUGF0aClcbiAgICAgIGxpZ2h0ZXN0LnRvdGFsV2VpZ2h0ICs9IGVudHJ5LndlaWdodFxuICAgIH1cblxuICAgIHJldHVybiBidWNrZXRzXG4gIH1cblxuICAvKipcbiAgICogRmluZHMgdGhlIGJ1Y2tldCB3aXRoIHRoZSBsZWFzdCBhY2N1bXVsYXRlZCB3ZWlnaHQuXG4gICAqIFRpZXMgYXJlIGJyb2tlbiBieSBidWNrZXQgaW5kZXggKGVhcmxpZXIgYnVja2V0IHdpbnMpIGZvciBkZXRlcm1pbmlzbS5cbiAgICogQHBhcmFtIHtHcm91cEJ1Y2tldFtdfSBidWNrZXRzIC0gR3JvdXAgYnVja2V0cy5cbiAgICogQHJldHVybnMge0dyb3VwQnVja2V0fSAtIFRoZSBsaWdodGVzdCBidWNrZXQuXG4gICAqL1xuICBmaW5kTGlnaHRlc3RCdWNrZXQoYnVja2V0cykge1xuICAgIGxldCBsaWdodGVzdCA9IGJ1Y2tldHNbMF1cblxuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgYnVja2V0cy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGJ1Y2tldHNbaV0udG90YWxXZWlnaHQgPCBsaWdodGVzdC50b3RhbFdlaWdodCkge1xuICAgICAgICBsaWdodGVzdCA9IGJ1Y2tldHNbaV1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbGlnaHRlc3RcbiAgfVxufVxuIl19
184
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1zdWl0ZS1zcGxpdHRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90ZXN0aW5nL3Rlc3Qtc3VpdGUtc3BsaXR0ZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQTtBQUN2QixPQUFPLGFBQWEsTUFBTSw2QkFBNkIsQ0FBQTtBQUV2RDs7Ozs7R0FLRztBQUVIOzs7OztHQUtHO0FBRUgsOENBQThDO0FBQzlDLE1BQU0sY0FBYyxHQUFHLENBQUMsQ0FBQTtBQUV4Qjs7OztHQUlHO0FBQ0gsTUFBTSxpQkFBaUIsR0FBRztJQUN4QixNQUFNLEVBQUUsRUFBRTtJQUNWLGlCQUFpQixFQUFFLEVBQUU7SUFDckIsVUFBVSxFQUFFLENBQUM7Q0FDZCxDQUFBO0FBRUQsaUZBQWlGO0FBQ2pGLE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxDQUFBO0FBRWpDOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8saUJBQWlCO0lBQ3BDOzs7Ozs7OztPQVFHO0lBQ0gsWUFBWSxFQUFDLE1BQU0sRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQUUsR0FBRyxRQUFRLEVBQUM7UUFDdEYsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBRXZCLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUM1QyxNQUFNLElBQUksS0FBSyxDQUFDLDZDQUE2QyxNQUFNLEVBQUUsQ0FBQyxDQUFBO1FBQ3hFLENBQUM7UUFFRCxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsSUFBSSxXQUFXLEdBQUcsQ0FBQyxJQUFJLFdBQVcsR0FBRyxNQUFNLEVBQUUsQ0FBQztZQUM5RSxNQUFNLElBQUksS0FBSyxDQUFDLHdDQUF3QyxNQUFNLFVBQVUsV0FBVyxF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QUMsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDdEMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBQyxDQUFDLENBQUE7UUFDM0MsQ0FBQztRQUVELEtBQUssTUFBTSxLQUFLLElBQUksV0FBVyxFQUFFLENBQUM7WUFDaEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBRWpELFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQTtZQUNuQyxRQUFRLENBQUMsV0FBVyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUE7UUFDdEMsQ0FBQztRQUVELE9BQU8sT0FBTyxDQUFBO0lBQ2hCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILGtCQUFrQixDQUFDLE9BQU87UUFDeEIsSUFBSSxRQUFRLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBRXpCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDeEMsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxHQUFHLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDbEQsUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQTtZQUN2QixDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sUUFBUSxDQUFBO0lBQ2pCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiXG5pbXBvcnQgcmVzdEFyZ3NFcnJvciBmcm9tIFwiLi4vdXRpbHMvcmVzdC1hcmdzLWVycm9yLmpzXCJcblxuLyoqXG4gKiBTcGxpdHRlckZpbGVFbnRyeSB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gU3BsaXR0ZXJGaWxlRW50cnlcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBmaWxlUGF0aCAtIEFic29sdXRlIGZpbGUgcGF0aC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB3ZWlnaHQgLSBDb21wdXRlZCB3ZWlnaHQgZm9yIGxvYWQgYmFsYW5jaW5nLlxuICovXG5cbi8qKlxuICogR3JvdXBCdWNrZXQgdHlwZS5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IEdyb3VwQnVja2V0XG4gKiBAcHJvcGVydHkge251bWJlcn0gdG90YWxXZWlnaHQgLSBBY2N1bXVsYXRlZCB3ZWlnaHQuXG4gKiBAcHJvcGVydHkge3N0cmluZ1tdfSBmaWxlcyAtIEZpbGVzIGFzc2lnbmVkIHRvIHRoaXMgZ3JvdXAuXG4gKi9cblxuLyoqIERlZmF1bHQgd2VpZ2h0IGZvciBhIHJlZ3VsYXIgdGVzdCBmaWxlLiAqL1xuY29uc3QgREVGQVVMVF9XRUlHSFQgPSAxXG5cbi8qKlxuICogV2VpZ2h0IG11bHRpcGxpZXJzIGJ5IHNwZWMgZGlyZWN0b3J5IG5hbWUuXG4gKiBIZWF2aWVyIHRlc3QgdHlwZXMgZ2V0IGhpZ2hlciB3ZWlnaHRzIHNvIGdyZWVkeSBkaXN0cmlidXRpb24gYmFsYW5jZXMgd2FsbC1jbG9jayB0aW1lLlxuICogQHR5cGUge1JlY29yZDxzdHJpbmcsIG51bWJlcj59XG4gKi9cbmNvbnN0IERJUkVDVE9SWV9XRUlHSFRTID0ge1xuICBzeXN0ZW06IDIwLFxuICBcImZyb250ZW5kLW1vZGVsc1wiOiAxMCxcbiAgY29udHJvbGxlcjogM1xufVxuXG4vKiogRXh0cmEgbXVsdGlwbGllciBhcHBsaWVkIHRvIGJyb3dzZXIgc3BlYyBmaWxlcyBvbiB0b3Agb2YgZGlyZWN0b3J5IHdlaWdodC4gKi9cbmNvbnN0IEJST1dTRVJfU1BFQ19NVUxUSVBMSUVSID0gMlxuXG4vKipcbiAqIFNwbGl0cyBhIGxpc3Qgb2YgdGVzdCBmaWxlcyBpbnRvIGJhbGFuY2VkIGdyb3VwcyB1c2luZyBhIGdyZWVkeSBsb2FkLWJhbGFuY2luZyBhbGdvcml0aG0uXG4gKiBNb2RlbGVkIGFmdGVyIHRlc3Rfc3VpdGVfc3BsaXR0ZXIgZm9yIFJTcGVjLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUZXN0U3VpdGVTcGxpdHRlciB7XG4gIC8qKlxuICAgKiBSdW5zIGNvbnN0cnVjdG9yLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBhcmdzLmdyb3VwcyAtIFRvdGFsIG51bWJlciBvZiBncm91cHMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBhcmdzLmdyb3VwTnVtYmVyIC0gV2hpY2ggZ3JvdXAgdG8gcmV0dXJuICgxLWluZGV4ZWQpLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBhcmdzLnRlc3RGaWxlcyAtIEFsbCBkaXNjb3ZlcmVkIHRlc3QgZmlsZSBwYXRocy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFthcmdzLmJhc2VEaXJlY3RvcnldIC0gQmFzZSBkaXJlY3RvcnkgZm9yIHJlbGF0aXZlIHBhdGggY29tcHV0YXRpb24uXG4gICAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IFthcmdzLnRpbWluZ01hbmlmZXN0XSAtIFJlbGF0aXZlIHRlc3QgcGF0aHMgbWFwcGVkIHRvIGR1cmF0aW9ucy5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtncm91cHMsIGdyb3VwTnVtYmVyLCB0ZXN0RmlsZXMsIGJhc2VEaXJlY3RvcnksIHRpbWluZ01hbmlmZXN0LCAuLi5yZXN0QXJnc30pIHtcbiAgICByZXN0QXJnc0Vycm9yKHJlc3RBcmdzKVxuXG4gICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKGdyb3VwcykgfHwgZ3JvdXBzIDwgMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAtLWdyb3VwcyBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlciwgZ290OiAke2dyb3Vwc31gKVxuICAgIH1cblxuICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihncm91cE51bWJlcikgfHwgZ3JvdXBOdW1iZXIgPCAxIHx8IGdyb3VwTnVtYmVyID4gZ3JvdXBzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYC0tZ3JvdXAtbnVtYmVyIG11c3QgYmUgYmV0d2VlbiAxIGFuZCAke2dyb3Vwc30sIGdvdDogJHtncm91cE51bWJlcn1gKVxuICAgIH1cblxuICAgIHRoaXMuX2dyb3VwcyA9IGdyb3Vwc1xuICAgIHRoaXMuX2dyb3VwTnVtYmVyID0gZ3JvdXBOdW1iZXJcbiAgICB0aGlzLl90ZXN0RmlsZXMgPSB0ZXN0RmlsZXNcbiAgICB0aGlzLl9iYXNlRGlyZWN0b3J5ID0gYmFzZURpcmVjdG9yeSB8fCBwcm9jZXNzLmN3ZCgpXG4gICAgdGhpcy5fdGltaW5nTWFuaWZlc3QgPSB0aGlzLm5vcm1hbGl6ZVRpbWluZ01hbmlmZXN0KHRpbWluZ01hbmlmZXN0KVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHRlc3QgZmlsZXMgYXNzaWduZWQgdG8gdGhpcyBncm91cC5cbiAgICogQHJldHVybnMge3N0cmluZ1tdfSAtIEZpbGUgcGF0aHMgZm9yIHRoZSByZXF1ZXN0ZWQgZ3JvdXAuXG4gICAqL1xuICBnZXRHcm91cEZpbGVzKCkge1xuICAgIGNvbnN0IHdlaWdodGVkID0gdGhpcy5jb21wdXRlV2VpZ2h0ZWRGaWxlcygpXG4gICAgY29uc3Qgc29ydGVkID0gdGhpcy5zb3J0QnlXZWlnaHREZXNjZW5kaW5nKHdlaWdodGVkKVxuICAgIGNvbnN0IGJ1Y2tldHMgPSB0aGlzLmRpc3RyaWJ1dGVHcmVlZGlseShzb3J0ZWQpXG5cbiAgICByZXR1cm4gYnVja2V0c1t0aGlzLl9ncm91cE51bWJlciAtIDFdLmZpbGVzXG4gIH1cblxuICAvKipcbiAgICogQ29tcHV0ZXMgd2VpZ2h0IGZvciBlYWNoIHRlc3QgZmlsZSBiYXNlZCBvbiBkaXJlY3RvcnkgdHlwZSBhbmQgZmlsZSBzdWZmaXguXG4gICAqIEByZXR1cm5zIHtTcGxpdHRlckZpbGVFbnRyeVtdfSAtIFdlaWdodGVkIGZpbGUgZW50cmllcy5cbiAgICovXG4gIGNvbXB1dGVXZWlnaHRlZEZpbGVzKCkge1xuICAgIHJldHVybiB0aGlzLl90ZXN0RmlsZXMubWFwKChmaWxlUGF0aCkgPT4gKHtcbiAgICAgIGZpbGVQYXRoLFxuICAgICAgd2VpZ2h0OiB0aGlzLmNvbXB1dGVXZWlnaHQoZmlsZVBhdGgpXG4gICAgfSkpXG4gIH1cblxuICAvKipcbiAgICogQ29tcHV0ZXMgdGhlIHdlaWdodCBmb3IgYSBzaW5nbGUgZmlsZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGZpbGVQYXRoIC0gQWJzb2x1dGUgZmlsZSBwYXRoLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIFdlaWdodCB2YWx1ZS5cbiAgICovXG4gIGNvbXB1dGVXZWlnaHQoZmlsZVBhdGgpIHtcbiAgICBjb25zdCByZWxhdGl2ZVBhdGggPSB0aGlzLm5vcm1hbGl6ZVJlbGF0aXZlUGF0aChwYXRoLnJlbGF0aXZlKHRoaXMuX2Jhc2VEaXJlY3RvcnksIGZpbGVQYXRoKSlcbiAgICBjb25zdCBwcm9qZWN0UmVsYXRpdmVQYXRoID0gdGhpcy5ub3JtYWxpemVSZWxhdGl2ZVBhdGgocGF0aC5qb2luKHBhdGguYmFzZW5hbWUodGhpcy5fYmFzZURpcmVjdG9yeSksIHJlbGF0aXZlUGF0aCkpXG4gICAgY29uc3QgZHVyYXRpb24gPSB0aGlzLl90aW1pbmdNYW5pZmVzdFtyZWxhdGl2ZVBhdGhdID8/IHRoaXMuX3RpbWluZ01hbmlmZXN0W3Byb2plY3RSZWxhdGl2ZVBhdGhdXG5cbiAgICBpZiAoZHVyYXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGR1cmF0aW9uXG4gICAgfVxuXG4gICAgbGV0IHdlaWdodCA9IERFRkFVTFRfV0VJR0hUXG5cbiAgICAvLyBFeHRyYWN0IHRoZSB0eXBlIGRpcmVjdG9yeSBmcm9tIHRoZSByZWxhdGl2ZSBwYXRoLlxuICAgIC8vIE1hdGNoZXMgYm90aCBcInNwZWMvc3lzdGVtLy4uLlwiIChiYXNlIGlzIHByb2plY3Qgcm9vdCkgYW5kIFwic3lzdGVtLy4uLlwiIChiYXNlIGlzIHNwZWMvIGl0c2VsZikuXG4gICAgY29uc3Qgc3BlY0Rpck1hdGNoID0gcmVsYXRpdmVQYXRoLm1hdGNoKC9eKD86KD86c3BlY3xfX3Rlc3RzX198dGVzdHMpXFwvKT8oW14vXSspXFwvLylcblxuICAgIGlmIChzcGVjRGlyTWF0Y2gpIHtcbiAgICAgIGNvbnN0IGRpck5hbWUgPSBzcGVjRGlyTWF0Y2hbMV1cblxuICAgICAgaWYgKERJUkVDVE9SWV9XRUlHSFRTW2Rpck5hbWVdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgd2VpZ2h0ID0gRElSRUNUT1JZX1dFSUdIVFNbZGlyTmFtZV1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBCcm93c2VyIHNwZWMgZmlsZXMgYXJlIGhlYXZpZXJcbiAgICBpZiAoZmlsZVBhdGguZW5kc1dpdGgoXCIuYnJvd3Nlci1zcGVjLmpzXCIpIHx8IGZpbGVQYXRoLmVuZHNXaXRoKFwiLmJyb3dzZXItc3BlYy5tanNcIikpIHtcbiAgICAgIHdlaWdodCAqPSBCUk9XU0VSX1NQRUNfTVVMVElQTElFUlxuICAgIH1cblxuICAgIHJldHVybiB3ZWlnaHRcbiAgfVxuXG4gIC8qKlxuICAgKiBLZWVwcyBvbmx5IHVzYWJsZSBwb3NpdGl2ZSBmaW5pdGUgZHVyYXRpb24gZW50cmllcyBrZXllZCBieSBub3JtYWxpemVkIHJlbGF0aXZlIHBhdGguXG4gICAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IHRpbWluZ01hbmlmZXN0IC0gUGFyc2VkIHRpbWluZyBtYW5pZmVzdC5cbiAgICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIG51bWJlcj59IC0gVmFsaWQgbm9ybWFsaXplZCBkdXJhdGlvbiB3ZWlnaHRzLlxuICAgKi9cbiAgbm9ybWFsaXplVGltaW5nTWFuaWZlc3QodGltaW5nTWFuaWZlc3QpIHtcbiAgICAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIG51bWJlcj59ICovXG4gICAgY29uc3Qgbm9ybWFsaXplZCA9IHt9XG5cbiAgICBpZiAoIXRpbWluZ01hbmlmZXN0IHx8IHR5cGVvZiB0aW1pbmdNYW5pZmVzdCAhPT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KHRpbWluZ01hbmlmZXN0KSkge1xuICAgICAgcmV0dXJuIG5vcm1hbGl6ZWRcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IFtmaWxlUGF0aCwgZHVyYXRpb25dIG9mIE9iamVjdC5lbnRyaWVzKHRpbWluZ01hbmlmZXN0KSkge1xuICAgICAgaWYgKHR5cGVvZiBkdXJhdGlvbiA9PT0gXCJudW1iZXJcIiAmJiBOdW1iZXIuaXNGaW5pdGUoZHVyYXRpb24pICYmIGR1cmF0aW9uID4gMCkge1xuICAgICAgICBub3JtYWxpemVkW3RoaXMubm9ybWFsaXplUmVsYXRpdmVQYXRoKGZpbGVQYXRoKV0gPSBkdXJhdGlvblxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBub3JtYWxpemVkXG4gIH1cblxuICAvKipcbiAgICogTm9ybWFsaXplcyBhIHJlbGF0aXZlIHRlc3QgcGF0aCB0byB0aGUgbWFuaWZlc3QncyBwb3J0YWJsZSBzbGFzaCBmb3JtYXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aCAtIFJlbGF0aXZlIHRlc3QgcGF0aC5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBOb3JtYWxpemVkIHJlbGF0aXZlIHRlc3QgcGF0aC5cbiAgICovXG4gIG5vcm1hbGl6ZVJlbGF0aXZlUGF0aChmaWxlUGF0aCkge1xuICAgIHJldHVybiBmaWxlUGF0aFxuICAgICAgLnJlcGxhY2VBbGwoXCJcXFxcXCIsIFwiL1wiKVxuICAgICAgLnJlcGxhY2UoL15cXC5cXC8vLCBcIlwiKVxuICB9XG5cbiAgLyoqXG4gICAqIFNvcnRzIGZpbGVzIGJ5IHdlaWdodCBkZXNjZW5kaW5nLCB0aGVuIGJ5IHBhdGggZm9yIGRldGVybWluaXNtLlxuICAgKiBAcGFyYW0ge1NwbGl0dGVyRmlsZUVudHJ5W119IGZpbGVzIC0gV2VpZ2h0ZWQgZmlsZXMuXG4gICAqIEByZXR1cm5zIHtTcGxpdHRlckZpbGVFbnRyeVtdfSAtIFNvcnRlZCBmaWxlcy5cbiAgICovXG4gIHNvcnRCeVdlaWdodERlc2NlbmRpbmcoZmlsZXMpIHtcbiAgICByZXR1cm4gWy4uLmZpbGVzXS5zb3J0KChhLCBiKSA9PiB7XG4gICAgICBpZiAoYi53ZWlnaHQgIT09IGEud2VpZ2h0KSB7XG4gICAgICAgIHJldHVybiBiLndlaWdodCAtIGEud2VpZ2h0XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhLmZpbGVQYXRoLmxvY2FsZUNvbXBhcmUoYi5maWxlUGF0aClcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIERpc3RyaWJ1dGVzIGZpbGVzIGdyZWVkaWx5IGludG8gTiBiYWxhbmNlZCBncm91cHMuXG4gICAqIEVhY2ggZmlsZSBpcyBhc3NpZ25lZCB0byB0aGUgZ3JvdXAgd2l0aCB0aGUgbGVhc3QgYWNjdW11bGF0ZWQgd2VpZ2h0LlxuICAgKiBAcGFyYW0ge1NwbGl0dGVyRmlsZUVudHJ5W119IHNvcnRlZEZpbGVzIC0gRmlsZXMgc29ydGVkIGJ5IHdlaWdodCBkZXNjZW5kaW5nLlxuICAgKiBAcmV0dXJucyB7R3JvdXBCdWNrZXRbXX0gLSBBcnJheSBvZiBncm91cCBidWNrZXRzLlxuICAgKi9cbiAgZGlzdHJpYnV0ZUdyZWVkaWx5KHNvcnRlZEZpbGVzKSB7XG4gICAgLyoqXG4gICAgICogQnVja2V0cy5cbiAgICAgKiBAdHlwZSB7R3JvdXBCdWNrZXRbXX0gKi9cbiAgICBjb25zdCBidWNrZXRzID0gW11cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZ3JvdXBzOyBpKyspIHtcbiAgICAgIGJ1Y2tldHMucHVzaCh7dG90YWxXZWlnaHQ6IDAsIGZpbGVzOiBbXX0pXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBzb3J0ZWRGaWxlcykge1xuICAgICAgY29uc3QgbGlnaHRlc3QgPSB0aGlzLmZpbmRMaWdodGVzdEJ1Y2tldChidWNrZXRzKVxuXG4gICAgICBsaWdodGVzdC5maWxlcy5wdXNoKGVudHJ5LmZpbGVQYXRoKVxuICAgICAgbGlnaHRlc3QudG90YWxXZWlnaHQgKz0gZW50cnkud2VpZ2h0XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ1Y2tldHNcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kcyB0aGUgYnVja2V0IHdpdGggdGhlIGxlYXN0IGFjY3VtdWxhdGVkIHdlaWdodC5cbiAgICogVGllcyBhcmUgYnJva2VuIGJ5IGJ1Y2tldCBpbmRleCAoZWFybGllciBidWNrZXQgd2lucykgZm9yIGRldGVybWluaXNtLlxuICAgKiBAcGFyYW0ge0dyb3VwQnVja2V0W119IGJ1Y2tldHMgLSBHcm91cCBidWNrZXRzLlxuICAgKiBAcmV0dXJucyB7R3JvdXBCdWNrZXR9IC0gVGhlIGxpZ2h0ZXN0IGJ1Y2tldC5cbiAgICovXG4gIGZpbmRMaWdodGVzdEJ1Y2tldChidWNrZXRzKSB7XG4gICAgbGV0IGxpZ2h0ZXN0ID0gYnVja2V0c1swXVxuXG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCBidWNrZXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoYnVja2V0c1tpXS50b3RhbFdlaWdodCA8IGxpZ2h0ZXN0LnRvdGFsV2VpZ2h0KSB7XG4gICAgICAgIGxpZ2h0ZXN0ID0gYnVja2V0c1tpXVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBsaWdodGVzdFxuICB9XG59XG4iXX0=
@@ -7,6 +7,7 @@
7
7
  * @property {string[]} filteredProcessArgs - Remaining process args with filter flags removed.
8
8
  * @property {number | undefined} groups - Total number of groups for test splitting.
9
9
  * @property {number | undefined} groupNumber - Which group to run (1-indexed).
10
+ * @property {string | undefined} timingManifestPath - JSON timing manifest path.
10
11
  */
11
12
  // @ts-check
12
13
 
@@ -15,6 +16,7 @@ const EXCLUDE_TAG_FLAGS = new Set(["--exclude-tag", "--skip-tag", "-x"])
15
16
  const EXAMPLE_FLAGS = new Set(["--example", "--name", "-e"])
16
17
  const GROUPS_FLAGS = new Set(["--groups"])
17
18
  const GROUP_NUMBER_FLAGS = new Set(["--group-number"])
19
+ const TIMING_MANIFEST_FLAGS = new Set(["--timing-manifest"])
18
20
 
19
21
  /**
20
22
  * Runs split tags.
@@ -79,6 +81,8 @@ export function parseFilters(processArgs) {
79
81
  * Defines groupNumber.
80
82
  * @type {number | undefined} */
81
83
  let groupNumber
84
+ /** @type {string | undefined} */
85
+ let timingManifestPath
82
86
 
83
87
  let inRestArgs = false
84
88
 
@@ -181,6 +185,21 @@ export function parseFilters(processArgs) {
181
185
  groupNumber = parseInt(arg.slice("--group-number=".length), 10)
182
186
  continue
183
187
  }
188
+
189
+ if (TIMING_MANIFEST_FLAGS.has(arg)) {
190
+ const nextValue = processArgs[i + 1]
191
+
192
+ if (nextValue && !nextValue.startsWith("-")) {
193
+ timingManifestPath = nextValue
194
+ i++
195
+ }
196
+ continue
197
+ }
198
+
199
+ if (arg.startsWith("--timing-manifest=")) {
200
+ timingManifestPath = arg.slice("--timing-manifest=".length)
201
+ continue
202
+ }
184
203
  }
185
204
 
186
205
  filteredProcessArgs.push(arg)
@@ -192,6 +211,7 @@ export function parseFilters(processArgs) {
192
211
  examplePatterns,
193
212
  filteredProcessArgs,
194
213
  groups,
195
- groupNumber
214
+ groupNumber,
215
+ timingManifestPath
196
216
  }
197
217
  }
@@ -46,8 +46,9 @@ export default class TestSuiteSplitter {
46
46
  * @param {number} args.groupNumber - Which group to return (1-indexed).
47
47
  * @param {string[]} args.testFiles - All discovered test file paths.
48
48
  * @param {string} [args.baseDirectory] - Base directory for relative path computation.
49
+ * @param {ReturnType<typeof JSON.parse>} [args.timingManifest] - Relative test paths mapped to durations.
49
50
  */
50
- constructor({groups, groupNumber, testFiles, baseDirectory, ...restArgs}) {
51
+ constructor({groups, groupNumber, testFiles, baseDirectory, timingManifest, ...restArgs}) {
51
52
  restArgsError(restArgs)
52
53
 
53
54
  if (!Number.isInteger(groups) || groups < 1) {
@@ -62,6 +63,7 @@ export default class TestSuiteSplitter {
62
63
  this._groupNumber = groupNumber
63
64
  this._testFiles = testFiles
64
65
  this._baseDirectory = baseDirectory || process.cwd()
66
+ this._timingManifest = this.normalizeTimingManifest(timingManifest)
65
67
  }
66
68
 
67
69
  /**
@@ -93,7 +95,14 @@ export default class TestSuiteSplitter {
93
95
  * @returns {number} - Weight value.
94
96
  */
95
97
  computeWeight(filePath) {
96
- const relativePath = path.relative(this._baseDirectory, filePath).split(path.sep).join("/")
98
+ const relativePath = this.normalizeRelativePath(path.relative(this._baseDirectory, filePath))
99
+ const projectRelativePath = this.normalizeRelativePath(path.join(path.basename(this._baseDirectory), relativePath))
100
+ const duration = this._timingManifest[relativePath] ?? this._timingManifest[projectRelativePath]
101
+
102
+ if (duration !== undefined) {
103
+ return duration
104
+ }
105
+
97
106
  let weight = DEFAULT_WEIGHT
98
107
 
99
108
  // Extract the type directory from the relative path.
@@ -116,6 +125,39 @@ export default class TestSuiteSplitter {
116
125
  return weight
117
126
  }
118
127
 
128
+ /**
129
+ * Keeps only usable positive finite duration entries keyed by normalized relative path.
130
+ * @param {ReturnType<typeof JSON.parse>} timingManifest - Parsed timing manifest.
131
+ * @returns {Record<string, number>} - Valid normalized duration weights.
132
+ */
133
+ normalizeTimingManifest(timingManifest) {
134
+ /** @type {Record<string, number>} */
135
+ const normalized = {}
136
+
137
+ if (!timingManifest || typeof timingManifest !== "object" || Array.isArray(timingManifest)) {
138
+ return normalized
139
+ }
140
+
141
+ for (const [filePath, duration] of Object.entries(timingManifest)) {
142
+ if (typeof duration === "number" && Number.isFinite(duration) && duration > 0) {
143
+ normalized[this.normalizeRelativePath(filePath)] = duration
144
+ }
145
+ }
146
+
147
+ return normalized
148
+ }
149
+
150
+ /**
151
+ * Normalizes a relative test path to the manifest's portable slash format.
152
+ * @param {string} filePath - Relative test path.
153
+ * @returns {string} - Normalized relative test path.
154
+ */
155
+ normalizeRelativePath(filePath) {
156
+ return filePath
157
+ .replaceAll("\\", "/")
158
+ .replace(/^\.\//, "")
159
+ }
160
+
119
161
  /**
120
162
  * Sorts files by weight descending, then by path for determinism.
121
163
  * @param {SplitterFileEntry[]} files - Weighted files.
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "velocious": "build/bin/velocious.js"
4
4
  },
5
5
  "name": "velocious",
6
- "version": "1.0.581",
6
+ "version": "1.0.583",
7
7
  "main": "build/index.js",
8
8
  "types": "build/index.d.ts",
9
9
  "files": [
@@ -17,12 +17,15 @@
17
17
  "scripts": {
18
18
  "all-checks": "npm run lint && npm run test",
19
19
  "benchmark:factory-plan-reuse": "node benchmark/factory-plan-reuse.js",
20
+ "benchmark:insert-multiple-chunking": "node benchmark/insert-multiple-chunking.js",
20
21
  "benchmark:preloader-id-dedup": "node benchmark/preloader-id-dedup.js",
21
22
  "benchmark:mysql-result-row-materialization": "node benchmark/mysql-result-row-materialization.js",
22
23
  "benchmark:query-roundtrip-batching": "node benchmark/query-roundtrip-batching.js",
23
24
  "benchmark:websocket-outbound-queue": "node benchmark/websocket-outbound-queue.js",
24
25
  "benchmark:websocket-frame-buffering": "node benchmark/websocket-frame-buffering.js",
25
26
  "benchmark:http-client-content-length-byte-length": "node benchmark/http-client-content-length-byte-length.js",
27
+ "benchmark:frontend-model-serialization-resource-metadata": "node benchmark/frontend-model-serialization-resource-metadata.js",
28
+ "benchmark:sql-diagnostic-scans": "node --expose-gc benchmark/sql-diagnostic-scans.js",
26
29
  "build": "node scripts/clean-build.js && npm run compile",
27
30
  "compile": "tsc -b && npm run copy:js && npm run copy:ejs && npm run copy:templates && node scripts/ensure-bin-executable.js",
28
31
  "copy:js": "cpy \"index.js\" build && cpy \"bin/**/*.js\" build/bin && cpy \"src/**/*.js\" build --parents",
@@ -75,6 +75,8 @@
75
75
  * @property {boolean} [multipleStatements] - (MySQL) Opt in to multi-statement queries so a whole structure SQL dump loads in one round-trip via `StructureSqlLoader`. Off by default; ordinary queries otherwise reject stacked statements.
76
76
  * @property {number} [maxRowsPerInsert] - Maximum rows per `INSERT ... VALUES (...), (...), ...` statement generated by `Record.insertMultiple`. Defaults to 500.
77
77
  * @property {number} [maxInsertSqlBytes] - Maximum serialized SQL size, in bytes, for a single `INSERT ... VALUES (...), (...), ...` statement. Defaults to 1 MiB (1048576).
78
+ * @property {number} [maxInClauseValues] - Maximum values in a single `IN (...)` cohort used by preloads, association counts, and queryData aggregates. Defaults to 999.
79
+ * @property {number} [maxQuerySqlBytes] - Maximum serialized SQL size, in bytes, for a single cohort query used by preloads, association counts, and queryData aggregates. Defaults to 1 MiB (1048576).
78
80
  * @property {string} [password] - Password for the database user.
79
81
  * @property {number} [port] - Database port.
80
82
  * @property {string} [primaryKeyType] - Default type for implicit migration primary keys and references. Defaults to `uuid`.