fyflow-orchestration 0.7.0 → 0.9.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.
@@ -1,4 +1,5 @@
1
1
  import {
2
+ ASK_REFUSED_KEYS,
2
3
  BUILT_IN_GATE_TYPES,
3
4
  BUILT_IN_GROUP_TYPES,
4
5
  BUILT_IN_NODE_TYPES,
@@ -21,6 +22,7 @@ import {
21
22
  InvalidRunId,
22
23
  InvalidTaskId,
23
24
  KEY_PATH_RE,
25
+ MESSAGE_OPTION_KEYS,
24
26
  MissingJoinPolicy,
25
27
  MultipleRuns,
26
28
  NODE_KEYS_DECLARED,
@@ -30,6 +32,7 @@ import {
30
32
  NoMatchingEdge,
31
33
  NotStarted,
32
34
  POLICIES,
35
+ POOL_INSTANCE_KEYS,
33
36
  POOL_SPEC_KEYS,
34
37
  PREDICATE_GROUP_KEYS,
35
38
  PREDICATE_LEAF_KEYS,
@@ -41,10 +44,12 @@ import {
41
44
  RETRY_POLICY_KEYS,
42
45
  RegistryError,
43
46
  ResumeRefused,
47
+ RunControlRefused,
44
48
  SCHEMA_KEYWORDS,
45
49
  SCHEMA_TYPES,
46
50
  SchemaRefused,
47
51
  TASK_KEYS_DECLARED,
52
+ TERMINAL_EVENTS,
48
53
  TRANSFORM_KEYS,
49
54
  TypeDefaultRefused,
50
55
  UncloneableResult,
@@ -90,11 +95,14 @@ import {
90
95
  gateTypeCollisions,
91
96
  gateTypeProblem,
92
97
  gateTypesOf,
98
+ givenVerdict,
93
99
  groupsNamedBy,
100
+ innermostMapOf,
94
101
  innermostRegionOf,
95
102
  isDerivation,
96
103
  isSuspended,
97
104
  isTerminal,
105
+ isTerminalEvent,
98
106
  keyPathProblem,
99
107
  languagesOf,
100
108
  lastRecordFor,
@@ -122,6 +130,7 @@ import {
122
130
  resolveRegistry,
123
131
  resumeRefusal,
124
132
  retryPolicyProblem,
133
+ routesOf,
125
134
  sampleOf,
126
135
  schemaProblem,
127
136
  selectEdge,
@@ -134,7 +143,7 @@ import {
134
143
  violatedRules,
135
144
  witness,
136
145
  workersOf
137
- } from "./chunks/chunk-YVOP3DIN.js";
146
+ } from "./chunks/chunk-3U4UZC34.js";
138
147
 
139
148
  // src/definition/assist.ts
140
149
  var TYPES = ["object", "array", "string", "number", "integer", "boolean", "null"];
@@ -174,8 +183,8 @@ async function tryTransform(registry, flow, nodeId, transform, options = {}) {
174
183
  else copy.transform = { lang: transform.lang, expr: transform.expr };
175
184
  return copy;
176
185
  });
177
- const report = await checkWiring(registry, { ...flow, nodes }, options);
178
- return report.verdicts.filter((v) => v.consumer === nodeId);
186
+ const { input, ...wiring } = options;
187
+ return await givenVerdict(registry, { ...flow, nodes }, nodeId, input, wiring);
179
188
  }
180
189
  function schemaOfValue(v) {
181
190
  if (v === void 0) return void 0;
@@ -278,13 +287,8 @@ function signaturesOf(workers) {
278
287
  }
279
288
  var PATH_TYPES = ["*", ...TYPES];
280
289
  var TS_TYPE_NAMES = [...TS_STRUCTURED, ...TS_NAMES.keys()];
281
-
282
- // src/driver/events.ts
283
- var TERMINAL_EVENTS = ["branch.arrived", "branch.exited", "branch.lost"];
284
- function isTerminalEvent(e) {
285
- return TERMINAL_EVENTS.includes(e.type);
286
- }
287
290
  export {
291
+ ASK_REFUSED_KEYS,
288
292
  BUILT_IN_GATE_TYPES,
289
293
  BUILT_IN_GROUP_TYPES,
290
294
  BUILT_IN_NODE_TYPES,
@@ -307,6 +311,7 @@ export {
307
311
  InvalidRunId,
308
312
  InvalidTaskId,
309
313
  KEY_PATH_RE,
314
+ MESSAGE_OPTION_KEYS,
310
315
  MissingJoinPolicy,
311
316
  MultipleRuns,
312
317
  NODE_KEYS_DECLARED,
@@ -317,6 +322,7 @@ export {
317
322
  NotStarted,
318
323
  PATH_TYPES,
319
324
  POLICIES,
325
+ POOL_INSTANCE_KEYS,
320
326
  POOL_SPEC_KEYS,
321
327
  PREDICATE_GROUP_KEYS,
322
328
  PREDICATE_LEAF_KEYS,
@@ -328,6 +334,7 @@ export {
328
334
  RETRY_POLICY_KEYS,
329
335
  RegistryError,
330
336
  ResumeRefused,
337
+ RunControlRefused,
331
338
  SCHEMA_KEYWORDS,
332
339
  SCHEMA_TYPES,
333
340
  SchemaRefused,
@@ -380,7 +387,9 @@ export {
380
387
  gateTypeCollisions,
381
388
  gateTypeProblem,
382
389
  gateTypesOf,
390
+ givenVerdict,
383
391
  groupsNamedBy,
392
+ innermostMapOf,
384
393
  innermostRegionOf,
385
394
  isDerivation,
386
395
  isSuspended,
@@ -414,6 +423,7 @@ export {
414
423
  resolveRegistry,
415
424
  resumeRefusal,
416
425
  retryPolicyProblem,
426
+ routesOf,
417
427
  sampleOf,
418
428
  sampledOutput,
419
429
  schemaOfValue,
@@ -1,7 +1,9 @@
1
1
  import {
2
+ Accumulator,
2
3
  BUILT_IN_NODE_TYPES,
3
4
  ConfigRefused,
4
5
  Driver,
6
+ InvalidDefinition,
5
7
  InvalidTaskId,
6
8
  TypeDefaultRefused,
7
9
  checkGateTypes,
@@ -20,38 +22,22 @@ import {
20
22
  poolsOf,
21
23
  resolveRegistry,
22
24
  resumeRefusal,
23
- step,
25
+ retryPolicyProblem,
26
+ validateDefinition,
24
27
  workersOf
25
- } from "../chunks/chunk-YVOP3DIN.js";
28
+ } from "../chunks/chunk-3U4UZC34.js";
26
29
 
27
30
  // src/scheduler/bootstrap.ts
28
31
  import { WorkerManager } from "fyflow-scheduler";
29
32
 
30
33
  // fyflow-envelope-worker:envelope-worker
31
- var envelope_worker_default = "data:text/javascript;base64,Ly8gc3JjL3NjaGVkdWxlci9lbnZlbG9wZS13b3JrZXIudHMKdmFyIE5vdEFuRW52ZWxvcGUgPSBjbGFzcyBleHRlbmRzIEVycm9yIHsKfTsKdmFyIFRyYW5zZm9ybUZhaWxlZCA9IGNsYXNzIGV4dGVuZHMgRXJyb3IgewogIGxhbmc7CiAgZXhwcjsKICBjb2RlOwogIGNvbnN0cnVjdG9yKHRyYW5zZm9ybSwgY29kZSwgd2h5KSB7CiAgICBzdXBlcihgdHJhbnNmb3JtIGZhaWxlZCBcdTIwMTQgJHt0cmFuc2Zvcm0ubGFuZ30gJHtKU09OLnN0cmluZ2lmeSh0cmFuc2Zvcm0uZXhwcil9JHtjb2RlICE9PSB2b2lkIDAgPyBgIFske2NvZGV9XWAgOiAiIn06ICR7d2h5fWApOwogICAgdGhpcy5sYW5nID0gdHJhbnNmb3JtLmxhbmc7CiAgICB0aGlzLmV4cHIgPSB0cmFuc2Zvcm0uZXhwcjsKICAgIHRoaXMuY29kZSA9IGNvZGU7CiAgfQp9OwpmdW5jdGlvbiB1bnBhY2tFbnZlbG9wZShwYXlsb2FkKSB7CiAgaWYgKHR5cGVvZiBwYXlsb2FkICE9PSAib2JqZWN0IiB8fCBwYXlsb2FkID09PSBudWxsIHx8IEFycmF5LmlzQXJyYXkocGF5bG9hZCkpIHsKICAgIHRocm93IG5ldyBOb3RBbkVudmVsb3BlKGB0eXBlZCBwb29sOiB0aGUgcGF5bG9hZCBpcyBub3QgYW4gZW52ZWxvcGUgeyBzZXR0aW5ncywgaW5wdXQgfSBcdTIwMTQgZ290ICR7YnJpZWYocGF5bG9hZCl9YCk7CiAgfQogIGNvbnN0IHAgPSBwYXlsb2FkOwogIGZvciAoY29uc3QgayBvZiBbInNldHRpbmdzIiwgImlucHV0Il0pIHsKICAgIGlmICghKGsgaW4gcCkpIHRocm93IG5ldyBOb3RBbkVudmVsb3BlKGB0eXBlZCBwb29sOiB0aGUgcGF5bG9hZCBpcyBub3QgYW4gZW52ZWxvcGUgXHUyMDE0IGl0IGhhcyBubyAiJHtrfSIga2V5IChrZXlzOiAke09iamVjdC5rZXlzKHApLm1hcCgoeCkgPT4gYCIke3h9ImApLmpvaW4oIiwgIikgfHwgIm5vbmUifSlgKTsKICB9CiAgY29uc3Qgc2V0dGluZ3MgPSBwLnNldHRpbmdzOwogIGlmICh0eXBlb2Ygc2V0dGluZ3MgIT09ICJvYmplY3QiIHx8IHNldHRpbmdzID09PSBudWxsIHx8IEFycmF5LmlzQXJyYXkoc2V0dGluZ3MpKSB7CiAgICB0aHJvdyBuZXcgTm90QW5FbnZlbG9wZShgdHlwZWQgcG9vbDogdGhlIGVudmVsb3BlJ3Mgc2V0dGluZ3MgaXMgbm90IGEgcGxhaW4gb2JqZWN0IFx1MjAxNCBnb3QgJHticmllZihzZXR0aW5ncyl9YCk7CiAgfQogIGNvbnN0IGVudiA9IHsgc2V0dGluZ3MsIGlucHV0OiBwLmlucHV0IH07CiAgaWYgKCJ0cmFuc2Zvcm0iIGluIHApIHsKICAgIGNvbnN0IHQgPSBwLnRyYW5zZm9ybTsKICAgIGNvbnN0IHdlbGxGb3JtZWQgPSB0eXBlb2YgdCA9PT0gIm9iamVjdCIgJiYgdCAhPT0gbnVsbCAmJiAhQXJyYXkuaXNBcnJheSh0KSAmJiB0eXBlb2YgdC5sYW5nID09PSAic3RyaW5nIiAmJiB0eXBlb2YgdC5leHByID09PSAic3RyaW5nIiAmJiBPYmplY3Qua2V5cyh0KS5sZW5ndGggPT09IDI7CiAgICBpZiAoIXdlbGxGb3JtZWQpIHRocm93IG5ldyBOb3RBbkVudmVsb3BlKGB0eXBlZCBwb29sOiB0aGUgZW52ZWxvcGUncyB0cmFuc2Zvcm0gaXMgbm90IHsgbGFuZywgZXhwciB9IFx1MjAxNCBnb3QgJHticmllZihwLnRyYW5zZm9ybSl9YCk7CiAgICBlbnYudHJhbnNmb3JtID0geyBsYW5nOiB0LmxhbmcsIGV4cHI6IHQuZXhwciB9OwogIH0KICByZXR1cm4gZW52Owp9CmZ1bmN0aW9uIGJyaWVmKHYpIHsKICBjb25zdCBzID0gcHJpbnRhYmxlKHYpOwogIHJldHVybiBzLmxlbmd0aCA+IDEyMCA/IGAke3Muc2xpY2UoMCwgMTE3KX0uLi5gIDogczsKfQpmdW5jdGlvbiBwcmludGFibGUodikgewogIHRyeSB7CiAgICBjb25zdCBqID0gSlNPTi5zdHJpbmdpZnkodik7CiAgICBpZiAoaiAhPT0gdm9pZCAwKSByZXR1cm4gajsKICB9IGNhdGNoIHsKICB9CiAgdHJ5IHsKICAgIHJldHVybiBTdHJpbmcodik7CiAgfSBjYXRjaCB7CiAgICByZXR1cm4gYGFuIHVucHJpbnRhYmxlICR7dHlwZW9mIHZ9YDsKICB9Cn0KZnVuY3Rpb24gY29kZU9mKGUpIHsKICBjb25zdCBjID0gZT8uY29kZTsKICByZXR1cm4gdHlwZW9mIGMgPT09ICJzdHJpbmciICYmIGMubGVuZ3RoID8gYyA6IHZvaWQgMDsKfQpmdW5jdGlvbiBtZXNzYWdlT2YoZSkgewogIGlmIChlIGluc3RhbmNlb2YgRXJyb3IpIHJldHVybiBlLm1lc3NhZ2U7CiAgdHJ5IHsKICAgIHJldHVybiBTdHJpbmcoZSk7CiAgfSBjYXRjaCB7CiAgICByZXR1cm4gcHJpbnRhYmxlKGUpOwogIH0KfQp2YXIgRW52ZWxvcGVXb3JrZXIgPSBjbGFzcyB7CiAgY2ZnOwogIHdvcmtlckNvbnRleHQ7CiAgaW5uZXIgPSBudWxsOwogIC8qKgogICAqICoqU2V0IGJ5IGBzZXR1cCgpYCB3aGVuIHRoZSBwb29sIGNvbmZpZyBuYW1lcyBubyB3b3JrZXIg4oCUIGEgdHlwZSB0aGF0IG9ubHkgVFJBTlNGT1JNUyoqIChBRFIgMDA3NSkuCiAgICogSXQgaXMgYSBTRVBBUkFURSBmaWVsZCBmcm9tIGBpbm5lciA9PT0gbnVsbGAgb24gcHVycG9zZSwgYW5kIHRoYXQgaXMgdGhlIHdob2xlIG9mIHRoaXMgYXJtJ3MKICAgKiBjb3JyZWN0bmVzczogYGlubmVyYCBpcyBudWxsIGJlZm9yZSBgc2V0dXAoKWAgYW5kIGFmdGVyIGB0ZWFyZG93bigpYCB0b28sIHdoaWNoIGFyZSBMSUZFQ1lDTEUKICAgKiBzdGF0ZXMgYHJ1bigpYCBoYXMgcmVmdXNlZCBieSBuYW1lIHNpbmNlIHYwLjE3LCBzbyByZWFkaW5nIHRoZSBhYnNlbmNlIG9mZiBgaW5uZXJgIHdvdWxkIHR1cm4KICAgKiAqcnVuKCkgYmVmb3JlIHNldHVwKCkqIGludG8gKnJldHVybiB0aGUgaW5wdXQgdW50b3VjaGVkKiDigJQgYSBydW4gdGhhdCBzaWxlbnRseSBoYW5kcyBhIHdvcmtlcidzCiAgICogc3VjY2Vzc29yIHRoZSB3cm9uZyB2YWx1ZSBpbnN0ZWFkIG9mIGZhaWxpbmcgdGhlIHRhc2suIE1lYXN1cmVkIGF0IFcxMDkncyBkZWNsYXJhdGlvbiBzdGVwOiBiZWZvcmUKICAgKiB0aGlzIGl0ZW0gQk9USCBvZiB0aG9zZSBzdGF0ZXMgdGhyZXcsIGFuZCBuZWl0aGVyIHdhcyBhbiBhcm0uCiAgICovCiAgbm9Jbm5lciA9IGZhbHNlOwogIC8qKgogICAqIFRoZSB3b3JrZXIgaGFsZiBvZiBlYWNoIGxhbmd1YWdlIHRoZSBwb29sIGNvbmZpZyBuYW1lcywgbG9hZGVkIGluIGBzZXR1cCgpYCDigJQgb3IgdGhlIHJlYXNvbgogICAqIGl0IGRpZCBub3QgbG9hZCwgUkVNRU1CRVJFRCBzbyB0aGF0IGBydW4oKWAgY2FuIGZhaWwgdGhlIHRhc2sgd2l0aCBpdCAodGhlIG1haW50YWluZXIncyBjYWxsLAogICAqIHNlZSBgc2V0dXAoKWApLgogICAqLwogIGxhbmdzID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsKICAvKiogRWFjaCBkaXN0aW5jdCBgKGxhbmcsIGV4cHIpYCBjb21waWxlZCBPTkNFIHBlciB3b3JrZXIgaW5zdGFuY2UsIG5ldmVyIHBlciB0YXNrIOKAlCBQMTcgZGVjaXNpb24gMy4gKi8KICBjb21waWxlZCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgLyoqCiAgICogKipXaHkgdGhpcyB3b3JrZXIgY291bGQgbm90IHNldCB1cCwgUkVNRU1CRVJFRCDigJQgb3IgYG51bGxgKiog4oCUCiAgICogW1cxNDFdKC4uLy4uL2RvYy93b3JrLWl0ZW1zL3cxNDEtYS13b3JrZXItdGhhdC1jYW5ub3Qtc2V0LXVwLWZhaWxzLWl0cy10YXNrcy1hbmQtdGhlLXJlZ2lzdHJ5LWhhcy1vbmUtc2hhcGUubWQpLAogICAqIFtRMjY2XSguLi8uLi9kb2MvcXVlc3Rpb25zL3EyNjYubWQpLCBQMzEgZGVjaXNpb24gMzogVzYxJ3Mgcm9hZCBmb3IgYSBsYW5ndWFnZSwgdGFrZW4gZm9yIHRoZSB3aG9sZQogICAqIG9mIGBzZXR1cCgpYC4gU2V0IGJ5IGBzZXR1cCgpYCBpbnN0ZWFkIG9mIHRocm93aW5nOyByZWFkIEZJUlNUIGJ5IGBydW4oKWAsIHdoaWNoIGZhaWxzIGV2ZXJ5IHRhc2sKICAgKiB3aXRoIGl0OyBjbGVhcmVkIGJ5IGB0ZWFyZG93bigpYCwgc28gYSB0b3JuLWRvd24gd29ya2VyIGlzIGluIGl0cyBjb25zdHJ1Y3RlZCBzdGF0ZSBhZ2Fpbi4KICAgKi8KICBzZXR1cEZhaWx1cmUgPSBudWxsOwogIC8qKgogICAqIEJvdGggYXJndW1lbnRzIGFyZSBrZXB0LCBhbmQgdGhlIHNlY29uZCBpcyBmb3J3YXJkZWQgdG8gdGhlIGlubmVyIHdvcmtlcjogdGhlIHNjaGVkdWxlciBwYXNzZXMKICAgKiBpdHMgd29ya2VyLWxldmVsIGNvbnRleHQgaGVyZSwgYW5kIGEgd29ya2VyIHRoYXQgb25seSBhY2NlcHRzIGBjb25maWdgIHNpbGVudGx5IGxvc2VzIHRoZQogICAqIGFiaWxpdHkgdG8gc2VsZi10ZXJtaW5hdGUgKHRoZSBzY2hlZHVsZXIncyBvd24gcmVmZXJlbmNlLCDCpzQpLgogICAqLwogIGNvbnN0cnVjdG9yKGNvbmZpZywgd29ya2VyQ29udGV4dCkgewogICAgdGhpcy5jZmcgPSBjb25maWc7CiAgICB0aGlzLndvcmtlckNvbnRleHQgPSB3b3JrZXJDb250ZXh0OwogIH0KICAvKioKICAgKiBMb2FkcyB0aGUgdHlwZSdzIHdvcmtlciBhbmQgcnVucyBJVFMgc2V0dXAg4oCUIGEgbW9kdWxlIHdpdGggbm8gZGVmYXVsdCBjbGFzcyBpcyByZWZ1c2VkIGJ5CiAgICogbmFtZSwgYXMgYXQgdjAuMTcg4oCUIHRoZW4gdGhlIHdvcmtlciBoYWxmIG9mIGV2ZXJ5IGxhbmd1YWdlIHRoZSBwb29sIGNvbmZpZyBuYW1lcywgT05DRSBwZXIKICAgKiB3b3JrZXIgaW5zdGFuY2UgKFAxNyBkZWNpc2lvbiAzKS4KICAgKgogICAqICoqQSBsYW5ndWFnZSBtb2R1bGUgdGhhdCBGQUlMUyBUTyBMT0FEIGRvZXMgbm90IHRocm93IGhlcmU7IHRoZSBmYWlsdXJlIGlzIHJlbWVtYmVyZWQgYW5kCiAgICogZXZlcnkgdGFzayB3aG9zZSB0cmFuc2Zvcm0gbmFtZXMgdGhhdCBsYW5ndWFnZSBmYWlscyBhdCBgcnVuKClgIHdpdGggaXQuKiogTWVhc3VyZWQgYXQgVzYxJ3MKICAgKiBkZWNsYXJhdGlvbiwgYm90aCBydW50aW1lcywgaW5saW5lIGFuZCB0aHJlYWRlZDogYSB3cmFwcGVyIHdob3NlIGBzZXR1cCgpYCB0aHJvd3MgbGVhdmVzIGV2ZXJ5CiAgICogdGFzayBvZiB0aGUgcG9vbCBgcGVuZGluZ2Agd2l0aCBgYXR0ZW1wdHM6IDBgLCB0aGUgcG9vbCByZXN0YXJ0cyBpdHMgd29ya2VyLCBhbmQgdGhlIHNjaGVkdWxlcgogICAqIGVtaXRzIG5vdGhpbmcgYSBkcml2ZXIgY291bGQgdHVybiBpbnRvIGEgcmVjb3JkIOKAlCB0aGUgZmFpbHVyZSBpcyByZXBvcnRlZCBvbiB0aGUgUE9PTCBhcwogICAqIGB3b3JrZXIuc2V0dXAuZmFpbGVkYCBhbmQgYHRhc2sucmVxdWV1ZV9yZXF1aXJlZGAsIGEgd29ya2VyIGVycm9yIGFuZCBub3QgYSB0YXNrJ3MsIHdoaWNoIGlzCiAgICogUDE3IHByZWRpY3Rpb24gMidzIHN0YXRlZCByZXZlcnNhbCBjb25kaXRpb24uIFRoZSBtYWludGFpbmVyIGNob3NlIHRoaXMgcm9hZCBhdCBXNjEncwogICAqIHN0b3AtYW5kLWFzayAoQURSIDAwNTEgcnVsZSA1KTogYSBVUkwgdGhhdCBkb2VzIG5vdCByZXNvbHZlLCBhIG1vZHVsZSB3aXRoIG5vIGRlZmF1bHQgY29tcGlsZQogICAqIGZ1bmN0aW9uLCBvciBhbiBlbXB0eSBVUkwsIGVhY2ggYmVjb21lcyBhIGBUcmFuc2Zvcm1GYWlsZWRgIG5hbWluZyB0aGUgbGFuZ3VhZ2UgYW5kIHRoZSBsb2FkCiAgICogZXJyb3IsIG9uIGV4YWN0bHkgdGhlIHRhc2tzIHRoYXQgbmVlZCB0aGF0IGxhbmd1YWdlIOKAlCBhIHRhc2sgd2l0aCBubyB0cmFuc2Zvcm0sIG9yIG9uZSBpbiBhCiAgICogbGFuZ3VhZ2UgdGhhdCBkaWQgbG9hZCwgc3RpbGwgcnVucyBvbiB0aGlzIHdvcmtlci4KICAgKgogICAqICoqQW5kIHNpbmNlIFcxNDEgdGhlIHNhbWUgaXMgdHJ1ZSBvZiB0aGUgVFlQRSdzIG93biB3b3JrZXI6IHRoaXMgbWV0aG9kIG5ldmVyIHRocm93cyoqIOKAlCBRMjY2LAogICAqIFAzMSBkZWNpc2lvbiAzLCBXNjEncyByb2FkIHRha2VuIGZvciB0aGUgd2hvbGUgb2YgYHNldHVwKClgLiBGMSBpcyBhIGZhY3QgYWJvdXQgVEhJUyBtZXRob2QKICAgKiB0aHJvd2luZywgd2hhdGV2ZXIgdGhyZXcsIGFuZCBXMTQxIG1lYXN1cmVkIGl0IGFnYWluIG9uIDAuNS4yIHRocm91Z2ggYGNyZWF0ZVJ1bnRpbWVgOiB0aHJlZQogICAqIHRhc2tzIG9uIGEgd29ya2VyIHdob3NlIGBzZXR1cCgpYCB0aHJvd3Mgc3RheSBgcGVuZGluZ2AgZm9yIGV2ZXIgaW4gYm90aCBwb29sIG1vZGVzLCB0aGUgcG9vbAogICAqIHJlcXVldWVpbmcgdGhlbSBvbiBlYWNoIHdvcmtlciBmYWlsdXJlIHVudGlsIGl0cyByZXN0YXJ0IGxpbWl0LCBhbmQgdGhlIHJ1bidzIGZvbGQgc2F5cwogICAqIGBydW5uaW5nYC4gU28gZXZlcnkgd2F5IHRoZSB0eXBlJ3Mgd29ya2VyIGNhbiBmYWlsIHRvIHNldCB1cCDigJQgdGhlIG1vZHVsZSBkb2VzIG5vdCBsb2FkLCBpdAogICAqIGV4cG9ydHMgbm8gZGVmYXVsdCBjbGFzcywgaXRzIGNvbnN0cnVjdG9yIHRocm93cywgaXRzIG93biBgc2V0dXAoKWAgdGhyb3dzIOKAlCBhbmQgdGhlIHR3bwogICAqIHBvb2wtY29uZmlnIHJlZnVzYWxzIHRoaXMgbWV0aG9kIG1hZGUgYnkgbmFtZSwgYXJlIFJFTUVNQkVSRUQgaW4gYHNldHVwRmFpbHVyZWAsIGFuZCBgcnVuKClgCiAgICogZmFpbHMgZXZlcnkgdGFzayBvbiB0aGlzIHdvcmtlciB3aXRoIGl0OiBhbiBvcmRpbmFyeSB0YXNrIGZhaWx1cmUsIHdoaWNoIHRoZSBydW4gcm91dGVzIHBlcgogICAqIEFEUiAwMDA0IOKAlCBkb3duIGFuIGBvbjogWyJmYWlsZWQiXWAgZWRnZSBvbiBhbiBvcHRpb25hbCBub2RlLCBwYXJrZWQgYHVzZXJfYWN0aW9uYCBvbiBhCiAgICogbm9uLW9wdGlvbmFsIG9uZS4gKipBIGNvbnN0cnVjdGVkIGlubmVyIHdvcmtlciBpcyB0b3JuIGRvd24gYXQgb25jZSoqLCBiZWNhdXNlIHRoZSBzY2hlZHVsZXIKICAgKiB0ZWFycyBkb3duIGEgd29ya2VyIHdob3NlIGBzZXR1cCgpYCB0aHJldyAoaXRzIG93biByZWZlcmVuY2UsIMKnNjogKmEgZmFpbGluZyBgc2V0dXAoKWAgc3RpbGwKICAgKiB0ZWFycyB0aGUgd29ya2VyIGRvd24qKSBhbmQgdGhpcyBjbGFzcyBpcyBub3cgdGhlIG9ubHkgdGhpbmcgdGhhdCBrbm93cyBvbmUgZGlkLiBUaGUgd29ya2VyCiAgICogc3RheXMgdXAgYW5kIGZhaWxzIGV2ZXJ5IHRhc2sgdW50aWwgdGhlIHBvb2wgaXMgcmVidWlsdDogYSBzZXR1cCB0aGF0IGZhaWxlZCBmb3IgYSB0cmFuc2llbnQKICAgKiByZWFzb24gaXMgbm90IHJldHJpZWQgaGVyZSAoVzE0MSdzIE91dCkuCiAgICovCiAgYXN5bmMgc2V0dXAoKSB7CiAgICB0aGlzLnNldHVwRmFpbHVyZSA9IG51bGw7CiAgICB0cnkgewogICAgICBhd2FpdCB0aGlzLnNldHVwT3JUaHJvdygpOwogICAgfSBjYXRjaCAoZSkgewogICAgICB0aGlzLnNldHVwRmFpbHVyZSA9IG1lc3NhZ2VPZihlKTsKICAgICAgY29uc3QgaW5uZXIgPSB0aGlzLmlubmVyOwogICAgICB0aGlzLmlubmVyID0gbnVsbDsKICAgICAgdGhpcy5ub0lubmVyID0gZmFsc2U7CiAgICAgIHRoaXMubGFuZ3MuY2xlYXIoKTsKICAgICAgaWYgKGlubmVyICE9PSBudWxsKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGF3YWl0IGlubmVyLnRlYXJkb3duPy4oKTsKICAgICAgICB9IGNhdGNoICh0KSB7CiAgICAgICAgICB0aGlzLnNldHVwRmFpbHVyZSArPSBgIChhbmQgaXRzIHRlYXJkb3duKCkgYWZ0ZXIgdGhlIGZhaWxlZCBzZXR1cCB0aHJldyB0b286ICR7bWVzc2FnZU9mKHQpfSlgOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KICAvKiogV2hhdCBgc2V0dXAoKWAgZGlkIHVudGlsIFcxNDEsIHRocm93cyBhbmQgYWxsOyBgc2V0dXAoKWAgdHVybnMgZWFjaCB0aHJvdyBpbnRvIGBzZXR1cEZhaWx1cmVgLiAqLwogIGFzeW5jIHNldHVwT3JUaHJvdygpIHsKICAgIGlmICh0aGlzLmNmZz8udHJhbnNmb3JtT25seSA9PT0gdHJ1ZSkgewogICAgICBpZiAodGhpcy5jZmcud29ya2VyICE9PSB2b2lkIDApIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGVudmVsb3BlIHdvcmtlcjogdGhlIHBvb2wgY29uZmlnIHNheXMgdHJhbnNmb3JtT25seSBBTkQgbmFtZXMgd29ya2VyICR7YnJpZWYodGhpcy5jZmcud29ya2VyKX0gXHUyMDE0IGEgdHlwZSBlaXRoZXIgaGFzIGFuIGlubmVyIHdvcmtlciBvciBvbmx5IHRyYW5zZm9ybXNgKTsKICAgICAgfQogICAgICB0aGlzLm5vSW5uZXIgPSB0cnVlOwogICAgICBmb3IgKGNvbnN0IFtuYW1lLCB1cmxdIG9mIE9iamVjdC5lbnRyaWVzKHRoaXMuY2ZnLmxhbmd1YWdlcyA/PyB7fSkpIHsKICAgICAgICB0aGlzLmxhbmdzLnNldChuYW1lLCBhd2FpdCB0aGlzLmxvYWRMYW5ndWFnZShuYW1lLCB1cmwpKTsKICAgICAgfQogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAodHlwZW9mIHRoaXMuY2ZnPy53b3JrZXIgIT09ICJzdHJpbmciIHx8IHRoaXMuY2ZnLndvcmtlci5sZW5ndGggPT09IDApIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBlbnZlbG9wZSB3b3JrZXI6IHRoZSBwb29sIGNvbmZpZyBuYW1lcyBubyB3b3JrZXIgVVJMIFx1MjAxNCBnb3QgJHticmllZih0aGlzLmNmZyl9YCk7CiAgICB9CiAgICBjb25zdCB3b3JrZXJVcmwgPSB0aGlzLmNmZy53b3JrZXI7CiAgICBsZXQgbW9kOwogICAgdHJ5IHsKICAgICAgbW9kID0gYXdhaXQgaW1wb3J0KHdvcmtlclVybCk7CiAgICB9IGNhdGNoIChlKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgZW52ZWxvcGUgd29ya2VyOiB0aGUgdHlwZSdzIHdvcmtlciAke0pTT04uc3RyaW5naWZ5KHdvcmtlclVybCl9IGRpZCBub3QgbG9hZDogJHttZXNzYWdlT2YoZSl9YCk7CiAgICB9CiAgICBpZiAodHlwZW9mIG1vZC5kZWZhdWx0ICE9PSAiZnVuY3Rpb24iIHx8ICFtb2QuZGVmYXVsdC5wcm90b3R5cGUpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBlbnZlbG9wZSB3b3JrZXI6IHRoZSB0eXBlJ3Mgd29ya2VyICR7SlNPTi5zdHJpbmdpZnkod29ya2VyVXJsKX0gbXVzdCBleHBvcnQgYSBkZWZhdWx0IGNsYXNzYCk7CiAgICB9CiAgICBjb25zdCBJbm5lciA9IG1vZC5kZWZhdWx0OwogICAgdHJ5IHsKICAgICAgdGhpcy5pbm5lciA9IG5ldyBJbm5lcih0aGlzLmNmZy5jb25maWcgPz8ge30sIHRoaXMud29ya2VyQ29udGV4dCk7CiAgICB9IGNhdGNoIChlKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgZW52ZWxvcGUgd29ya2VyOiB0aGUgdHlwZSdzIHdvcmtlciAke0pTT04uc3RyaW5naWZ5KHdvcmtlclVybCl9IHRocmV3IGZyb20gaXRzIGNvbnN0cnVjdG9yOiAke21lc3NhZ2VPZihlKX1gKTsKICAgIH0KICAgIHRyeSB7CiAgICAgIGF3YWl0IHRoaXMuaW5uZXIuc2V0dXA/LigpOwogICAgfSBjYXRjaCAoZSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYGVudmVsb3BlIHdvcmtlcjogdGhlIHR5cGUncyB3b3JrZXIgJHtKU09OLnN0cmluZ2lmeSh3b3JrZXJVcmwpfSB0aHJldyBmcm9tIGl0cyBzZXR1cCgpOiAke21lc3NhZ2VPZihlKX1gKTsKICAgIH0KICAgIGZvciAoY29uc3QgW25hbWUsIHVybF0gb2YgT2JqZWN0LmVudHJpZXModGhpcy5jZmcubGFuZ3VhZ2VzID8/IHt9KSkgewogICAgICB0aGlzLmxhbmdzLnNldChuYW1lLCBhd2FpdCB0aGlzLmxvYWRMYW5ndWFnZShuYW1lLCB1cmwpKTsKICAgIH0KICB9CiAgLyoqIE9uZSBsYW5ndWFnZSdzIHdvcmtlciBoYWxmLCBvciB0aGUgRXJyb3IgdGhhdCBzdGFuZHMgaW4gZm9yIGl0IOKAlCBuZXZlciBhIHRocm93IChzZWUgYHNldHVwKClgKS4gKi8KICBhc3luYyBsb2FkTGFuZ3VhZ2UobmFtZSwgdXJsKSB7CiAgICBpZiAodHlwZW9mIHVybCAhPT0gInN0cmluZyIgfHwgdXJsLmxlbmd0aCA9PT0gMCkgewogICAgICByZXR1cm4gbmV3IEVycm9yKGBsYW5ndWFnZSAiJHtuYW1lfSIgbmFtZXMgbm8gd29ya2VyIG1vZHVsZSBVUkwgaW4gdGhlIHBvb2wgY29uZmlnIFx1MjAxNCBnb3QgJHticmllZih1cmwpfWApOwogICAgfQogICAgdHJ5IHsKICAgICAgY29uc3QgbG0gPSBhd2FpdCBpbXBvcnQodXJsKTsKICAgICAgaWYgKHR5cGVvZiBsbS5kZWZhdWx0ICE9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgcmV0dXJuIG5ldyBFcnJvcihgbGFuZ3VhZ2UgIiR7bmFtZX0iJ3Mgd29ya2VyIG1vZHVsZSAke3VybH0gbXVzdCBleHBvcnQgYSBkZWZhdWx0IGNvbXBpbGUgZnVuY3Rpb24gKGdvdCAke3R5cGVvZiBsbS5kZWZhdWx0fSlgKTsKICAgICAgfQogICAgICByZXR1cm4gbG0uZGVmYXVsdDsKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgcmV0dXJuIG5ldyBFcnJvcihgbGFuZ3VhZ2UgIiR7bmFtZX0iJ3Mgd29ya2VyIG1vZHVsZSAke3VybH0gZGlkIG5vdCBsb2FkOiAke21lc3NhZ2VPZihlKX1gKTsKICAgIH0KICB9CiAgLyoqCiAgICogYEZELUM1YDogdGhlIGlubmVyIHdvcmtlciByZWNlaXZlcyBgeyBzZXR0aW5ncywgaW5wdXQgfWAgYW5kIG5vdGhpbmcgZWxzZS4gYEZELUM2YDogd2hlbiB0aGUKICAgKiBlbnZlbG9wZSBjYXJyaWVzIGEgYHRyYW5zZm9ybWAsIGBpbnB1dGAgaXMgdGhlIGV2YWx1YXRpb24gb2YgdGhhdCBleHByZXNzaW9uIG92ZXIgdGhlIHZhbHVlCiAgICogcmVjZWl2ZWQsIHdpdGggdGhlIG5vZGUncyBzZXR0aW5ncyBib3VuZCBhcyBgJHNldHRpbmdzYCwgYW5kIHRoZSB0aGlyZCBrZXkgaXMgY29uc3VtZWQgaGVyZS4KICAgKi8KICBhc3luYyBydW4ocGF5bG9hZCwgY29udGV4dCkgewogICAgaWYgKHRoaXMuc2V0dXBGYWlsdXJlICE9PSBudWxsKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLnNldHVwRmFpbHVyZX0gXHUyMDE0IGV2ZXJ5IHRhc2sgb24gdGhpcyB3b3JrZXIgZmFpbHMgd2l0aCB0aGlzIHVudGlsIHRoZSBwb29sIGlzIHJlYnVpbHRgKTsKICAgIH0KICAgIGlmICh0aGlzLmlubmVyID09PSBudWxsICYmICF0aGlzLm5vSW5uZXIpIHRocm93IG5ldyBFcnJvcigiZW52ZWxvcGUgd29ya2VyOiBydW4oKSBiZWZvcmUgc2V0dXAoKSBcdTIwMTQgdGhlIGlubmVyIHdvcmtlciBpcyBub3QgbG9hZGVkIik7CiAgICBjb25zdCBlbnYgPSB1bnBhY2tFbnZlbG9wZShwYXlsb2FkKTsKICAgIGlmICh0aGlzLm5vSW5uZXIpIHsKICAgICAgaWYgKGVudi50cmFuc2Zvcm0gPT09IHZvaWQgMCkgewogICAgICAgIHRocm93IG5ldyBOb3RBbkVudmVsb3BlKCJ0eXBlZCBwb29sOiB0aGlzIHBvb2xgcyB0eXBlIG5hbWVzIG5vIHdvcmtlciwgc28gdGhlIGVudmVsb3BlIG11c3QgY2FycnkgYSB0cmFuc2Zvcm0gXHUyMDE0IHRoZXJlIGlzIG5vdGhpbmcgZWxzZSBmb3IgdGhlIHRhc2sgdG8gZG8gKEZELVY0NiByZWZ1c2VzIHN1Y2ggYSBub2RlIGF0IGNvbnN0cnVjdGlvbikiKTsKICAgICAgfQogICAgICByZXR1cm4gYXdhaXQgdGhpcy50cmFuc2Zvcm0oZW52LnRyYW5zZm9ybSwgZW52LmlucHV0LCBlbnYuc2V0dGluZ3MpOwogICAgfQogICAgY29uc3QgaW5wdXQgPSBlbnYudHJhbnNmb3JtID09PSB2b2lkIDAgPyBlbnYuaW5wdXQgOiBhd2FpdCB0aGlzLnRyYW5zZm9ybShlbnYudHJhbnNmb3JtLCBlbnYuaW5wdXQsIGVudi5zZXR0aW5ncyk7CiAgICByZXR1cm4gYXdhaXQgdGhpcy5pbm5lci5ydW4oeyBzZXR0aW5nczogZW52LnNldHRpbmdzLCBpbnB1dCB9LCBjb250ZXh0KTsKICB9CiAgLyoqIEV2YWx1YXRlcyBvbmUgZGVjbGFyZWQgdHJhbnNmb3JtOyBldmVyeSBmYWlsdXJlIGlzIGEgYFRyYW5zZm9ybUZhaWxlZGAgbmFtaW5nIHdoYXQgZmFpbGVkIGFuZCB3aHkuICovCiAgYXN5bmMgdHJhbnNmb3JtKHQsIGlucHV0LCBzZXR0aW5ncykgewogICAgY29uc3QgY29tcGlsZSA9IHRoaXMubGFuZ3MuZ2V0KHQubGFuZyk7CiAgICBpZiAoY29tcGlsZSA9PT0gdm9pZCAwKSB7CiAgICAgIGNvbnN0IGNhcnJpZWQgPSBPYmplY3Qua2V5cyh0aGlzLmNmZy5sYW5ndWFnZXMgPz8ge30pLm1hcCgoeCkgPT4gYCIke3h9ImApLmpvaW4oIiwgIikgfHwgIm5vIGxhbmd1YWdlcyI7CiAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1GYWlsZWQodCwgdm9pZCAwLCBgbGFuZ3VhZ2UgIiR7dC5sYW5nfSIgaXMgbm90IGxvYWRlZCBpbiB0aGlzIHBvb2wgKHRoZSBwb29sIGNvbmZpZyBjYXJyaWVzICR7Y2FycmllZH0pIFx1MjAxNCB0aGUgYm9vdHN0cmFwIGhlbHBlciB3cml0ZXMgYW4gYWRhcHRlciBVUkwgZm9yIGEgdHlwZSBzb21lIG5vZGUgb2Ygd2hpY2ggZGVjbGFyZXMgYSB0cmFuc2Zvcm0sIGFuZCBuZWVkcyB0aGUgZmxvdyBhbmQgdGhlIGxhbmd1YWdlcyB0byBkbyBpdGApOwogICAgfQogICAgaWYgKGNvbXBpbGUgaW5zdGFuY2VvZiBFcnJvcikgewogICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtRmFpbGVkKHQsIHZvaWQgMCwgYCR7Y29tcGlsZS5tZXNzYWdlfSBcdTIwMTQgZXZlcnkgdGFzayB0cmFuc2Zvcm1pbmcgaW4gIiR7dC5sYW5nfSIgb24gdGhpcyB3b3JrZXIgZmFpbHMgd2l0aCB0aGlzIHVudGlsIHRoZSBwb29sIGlzIHJlYnVpbHRgKTsKICAgIH0KICAgIGNvbnN0IGtleSA9IEpTT04uc3RyaW5naWZ5KFt0LmxhbmcsIHQuZXhwcl0pOwogICAgbGV0IGNvbXBpbGVkID0gdGhpcy5jb21waWxlZC5nZXQoa2V5KTsKICAgIGlmIChjb21waWxlZCA9PT0gdm9pZCAwKSB7CiAgICAgIHRyeSB7CiAgICAgICAgY29tcGlsZWQgPSBjb21waWxlKHQuZXhwcik7CiAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtRmFpbGVkKHQsIGNvZGVPZihlKSwgYHRoZSB3b3JrZXIgaGFsZiBvZiAiJHt0Lmxhbmd9IiByZWZ1c2VkIHRoZSBleHByZXNzaW9uIHRoZSByZWdpc3RyeSBoYWxmIGFjY2VwdGVkOiAke21lc3NhZ2VPZihlKX1gKTsKICAgICAgfQogICAgICBpZiAodHlwZW9mIGNvbXBpbGVkPy5ldmFsdWF0ZSAhPT0gImZ1bmN0aW9uIikgewogICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1GYWlsZWQodCwgdm9pZCAwLCBgdGhlIHdvcmtlciBoYWxmIG9mICIke3QubGFuZ30iIGNvbXBpbGVkIHRvICR7YnJpZWYoY29tcGlsZWQpfSwgd2hpY2ggaGFzIG5vIGV2YWx1YXRlKGlucHV0LCBzZXR0aW5ncylgKTsKICAgICAgfQogICAgICB0aGlzLmNvbXBpbGVkLnNldChrZXksIGNvbXBpbGVkKTsKICAgIH0KICAgIHRyeSB7CiAgICAgIHJldHVybiBhd2FpdCBjb21waWxlZC5ldmFsdWF0ZShpbnB1dCwgc2V0dGluZ3MpOwogICAgfSBjYXRjaCAoZSkgewogICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtRmFpbGVkKHQsIGNvZGVPZihlKSwgbWVzc2FnZU9mKGUpKTsKICAgIH0KICB9CiAgYXN5bmMgdGVhcmRvd24oKSB7CiAgICBhd2FpdCB0aGlzLmlubmVyPy50ZWFyZG93bj8uKCk7CiAgICB0aGlzLmlubmVyID0gbnVsbDsKICAgIHRoaXMubm9Jbm5lciA9IGZhbHNlOwogICAgdGhpcy5zZXR1cEZhaWx1cmUgPSBudWxsOwogICAgdGhpcy5sYW5ncy5jbGVhcigpOwogICAgdGhpcy5jb21waWxlZC5jbGVhcigpOwogIH0KfTsKZXhwb3J0IHsKICBOb3RBbkVudmVsb3BlLAogIFRyYW5zZm9ybUZhaWxlZCwKICBFbnZlbG9wZVdvcmtlciBhcyBkZWZhdWx0LAogIHVucGFja0VudmVsb3BlCn07Cg==";
34
+ var envelope_worker_default = "data:text/javascript;base64,Ly8gc3JjL3NjaGVkdWxlci9lbnZlbG9wZS13b3JrZXIudHMKdmFyIE5vdEFuRW52ZWxvcGUgPSBjbGFzcyBleHRlbmRzIEVycm9yIHsKfTsKdmFyIFRyYW5zZm9ybUZhaWxlZCA9IGNsYXNzIGV4dGVuZHMgRXJyb3IgewogIGxhbmc7CiAgZXhwcjsKICBjb2RlOwogIGNvbnN0cnVjdG9yKHRyYW5zZm9ybSwgY29kZSwgd2h5KSB7CiAgICBzdXBlcihgdHJhbnNmb3JtIGZhaWxlZCBcdTIwMTQgJHt0cmFuc2Zvcm0ubGFuZ30gJHtKU09OLnN0cmluZ2lmeSh0cmFuc2Zvcm0uZXhwcil9JHtjb2RlICE9PSB2b2lkIDAgPyBgIFske2NvZGV9XWAgOiAiIn06ICR7d2h5fWApOwogICAgdGhpcy5sYW5nID0gdHJhbnNmb3JtLmxhbmc7CiAgICB0aGlzLmV4cHIgPSB0cmFuc2Zvcm0uZXhwcjsKICAgIHRoaXMuY29kZSA9IGNvZGU7CiAgfQp9OwpmdW5jdGlvbiB1bnBhY2tFbnZlbG9wZShwYXlsb2FkKSB7CiAgaWYgKHR5cGVvZiBwYXlsb2FkICE9PSAib2JqZWN0IiB8fCBwYXlsb2FkID09PSBudWxsIHx8IEFycmF5LmlzQXJyYXkocGF5bG9hZCkpIHsKICAgIHRocm93IG5ldyBOb3RBbkVudmVsb3BlKGB0eXBlZCBwb29sOiB0aGUgcGF5bG9hZCBpcyBub3QgYW4gZW52ZWxvcGUgeyBzZXR0aW5ncywgaW5wdXQgfSBcdTIwMTQgZ290ICR7YnJpZWYocGF5bG9hZCl9YCk7CiAgfQogIGNvbnN0IHAgPSBwYXlsb2FkOwogIGZvciAoY29uc3QgayBvZiBbInNldHRpbmdzIiwgImlucHV0Il0pIHsKICAgIGlmICghKGsgaW4gcCkpIHRocm93IG5ldyBOb3RBbkVudmVsb3BlKGB0eXBlZCBwb29sOiB0aGUgcGF5bG9hZCBpcyBub3QgYW4gZW52ZWxvcGUgXHUyMDE0IGl0IGhhcyBubyAiJHtrfSIga2V5IChrZXlzOiAke09iamVjdC5rZXlzKHApLm1hcCgoeCkgPT4gYCIke3h9ImApLmpvaW4oIiwgIikgfHwgIm5vbmUifSlgKTsKICB9CiAgY29uc3Qgc2V0dGluZ3MgPSBwLnNldHRpbmdzOwogIGlmICh0eXBlb2Ygc2V0dGluZ3MgIT09ICJvYmplY3QiIHx8IHNldHRpbmdzID09PSBudWxsIHx8IEFycmF5LmlzQXJyYXkoc2V0dGluZ3MpKSB7CiAgICB0aHJvdyBuZXcgTm90QW5FbnZlbG9wZShgdHlwZWQgcG9vbDogdGhlIGVudmVsb3BlJ3Mgc2V0dGluZ3MgaXMgbm90IGEgcGxhaW4gb2JqZWN0IFx1MjAxNCBnb3QgJHticmllZihzZXR0aW5ncyl9YCk7CiAgfQogIGNvbnN0IGVudiA9IHsgc2V0dGluZ3MsIGlucHV0OiBwLmlucHV0IH07CiAgaWYgKCJ0cmFuc2Zvcm0iIGluIHApIHsKICAgIGNvbnN0IHQgPSBwLnRyYW5zZm9ybTsKICAgIGNvbnN0IHdlbGxGb3JtZWQgPSB0eXBlb2YgdCA9PT0gIm9iamVjdCIgJiYgdCAhPT0gbnVsbCAmJiAhQXJyYXkuaXNBcnJheSh0KSAmJiB0eXBlb2YgdC5sYW5nID09PSAic3RyaW5nIiAmJiB0eXBlb2YgdC5leHByID09PSAic3RyaW5nIiAmJiBPYmplY3Qua2V5cyh0KS5sZW5ndGggPT09IDI7CiAgICBpZiAoIXdlbGxGb3JtZWQpIHRocm93IG5ldyBOb3RBbkVudmVsb3BlKGB0eXBlZCBwb29sOiB0aGUgZW52ZWxvcGUncyB0cmFuc2Zvcm0gaXMgbm90IHsgbGFuZywgZXhwciB9IFx1MjAxNCBnb3QgJHticmllZihwLnRyYW5zZm9ybSl9YCk7CiAgICBlbnYudHJhbnNmb3JtID0geyBsYW5nOiB0LmxhbmcsIGV4cHI6IHQuZXhwciB9OwogIH0KICByZXR1cm4gZW52Owp9CmZ1bmN0aW9uIGJyaWVmKHYpIHsKICBjb25zdCBzID0gcHJpbnRhYmxlKHYpOwogIHJldHVybiBzLmxlbmd0aCA+IDEyMCA/IGAke3Muc2xpY2UoMCwgMTE3KX0uLi5gIDogczsKfQpmdW5jdGlvbiBwcmludGFibGUodikgewogIHRyeSB7CiAgICBjb25zdCBqID0gSlNPTi5zdHJpbmdpZnkodik7CiAgICBpZiAoaiAhPT0gdm9pZCAwKSByZXR1cm4gajsKICB9IGNhdGNoIHsKICB9CiAgdHJ5IHsKICAgIHJldHVybiBTdHJpbmcodik7CiAgfSBjYXRjaCB7CiAgICByZXR1cm4gYGFuIHVucHJpbnRhYmxlICR7dHlwZW9mIHZ9YDsKICB9Cn0KZnVuY3Rpb24gY29kZU9mKGUpIHsKICBjb25zdCBjID0gZT8uY29kZTsKICByZXR1cm4gdHlwZW9mIGMgPT09ICJzdHJpbmciICYmIGMubGVuZ3RoID8gYyA6IHZvaWQgMDsKfQpmdW5jdGlvbiBtZXNzYWdlT2YoZSkgewogIGlmIChlIGluc3RhbmNlb2YgRXJyb3IpIHJldHVybiBlLm1lc3NhZ2U7CiAgdHJ5IHsKICAgIHJldHVybiBTdHJpbmcoZSk7CiAgfSBjYXRjaCB7CiAgICByZXR1cm4gcHJpbnRhYmxlKGUpOwogIH0KfQp2YXIgRW52ZWxvcGVXb3JrZXIgPSBjbGFzcyB7CiAgY2ZnOwogIHdvcmtlckNvbnRleHQ7CiAgaW5uZXIgPSBudWxsOwogIC8qKgogICAqICoqU2V0IGJ5IGBzZXR1cCgpYCB3aGVuIHRoZSBwb29sIGNvbmZpZyBuYW1lcyBubyB3b3JrZXIg4oCUIGEgdHlwZSB0aGF0IG9ubHkgVFJBTlNGT1JNUyoqIChBRFIgMDA3NSkuCiAgICogSXQgaXMgYSBTRVBBUkFURSBmaWVsZCBmcm9tIGBpbm5lciA9PT0gbnVsbGAgb24gcHVycG9zZSwgYW5kIHRoYXQgaXMgdGhlIHdob2xlIG9mIHRoaXMgYXJtJ3MKICAgKiBjb3JyZWN0bmVzczogYGlubmVyYCBpcyBudWxsIGJlZm9yZSBgc2V0dXAoKWAgYW5kIGFmdGVyIGB0ZWFyZG93bigpYCB0b28sIHdoaWNoIGFyZSBMSUZFQ1lDTEUKICAgKiBzdGF0ZXMgYHJ1bigpYCBoYXMgcmVmdXNlZCBieSBuYW1lIHNpbmNlIHYwLjE3LCBzbyByZWFkaW5nIHRoZSBhYnNlbmNlIG9mZiBgaW5uZXJgIHdvdWxkIHR1cm4KICAgKiAqcnVuKCkgYmVmb3JlIHNldHVwKCkqIGludG8gKnJldHVybiB0aGUgaW5wdXQgdW50b3VjaGVkKiDigJQgYSBydW4gdGhhdCBzaWxlbnRseSBoYW5kcyBhIHdvcmtlcidzCiAgICogc3VjY2Vzc29yIHRoZSB3cm9uZyB2YWx1ZSBpbnN0ZWFkIG9mIGZhaWxpbmcgdGhlIHRhc2suIE1lYXN1cmVkIGF0IFcxMDkncyBkZWNsYXJhdGlvbiBzdGVwOiBiZWZvcmUKICAgKiB0aGlzIGl0ZW0gQk9USCBvZiB0aG9zZSBzdGF0ZXMgdGhyZXcsIGFuZCBuZWl0aGVyIHdhcyBhbiBhcm0uCiAgICovCiAgbm9Jbm5lciA9IGZhbHNlOwogIC8qKgogICAqIFRoZSB3b3JrZXIgaGFsZiBvZiBlYWNoIGxhbmd1YWdlIHRoZSBwb29sIGNvbmZpZyBuYW1lcywgbG9hZGVkIGluIGBzZXR1cCgpYCDigJQgb3IgdGhlIHJlYXNvbgogICAqIGl0IGRpZCBub3QgbG9hZCwgUkVNRU1CRVJFRCBzbyB0aGF0IGBydW4oKWAgY2FuIGZhaWwgdGhlIHRhc2sgd2l0aCBpdCAodGhlIG1haW50YWluZXIncyBjYWxsLAogICAqIHNlZSBgc2V0dXAoKWApLgogICAqLwogIGxhbmdzID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsKICAvKiogRWFjaCBkaXN0aW5jdCBgKGxhbmcsIGV4cHIpYCBjb21waWxlZCBPTkNFIHBlciB3b3JrZXIgaW5zdGFuY2UsIG5ldmVyIHBlciB0YXNrIOKAlCBQMTcgZGVjaXNpb24gMy4gKi8KICBjb21waWxlZCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgLyoqCiAgICogKipXaHkgdGhpcyB3b3JrZXIgY291bGQgbm90IHNldCB1cCwgUkVNRU1CRVJFRCDigJQgb3IgYG51bGxgKiog4oCUCiAgICogW1cxNDFdKC4uLy4uL2RvYy93b3JrLWl0ZW1zL3cxNDEtYS13b3JrZXItdGhhdC1jYW5ub3Qtc2V0LXVwLWZhaWxzLWl0cy10YXNrcy1hbmQtdGhlLXJlZ2lzdHJ5LWhhcy1vbmUtc2hhcGUubWQpLAogICAqIFtRMjY2XSguLi8uLi9kb2MvcXVlc3Rpb25zL3EyNjYubWQpLCBQMzEgZGVjaXNpb24gMzogVzYxJ3Mgcm9hZCBmb3IgYSBsYW5ndWFnZSwgdGFrZW4gZm9yIHRoZSB3aG9sZQogICAqIG9mIGBzZXR1cCgpYC4gU2V0IGJ5IGBzZXR1cCgpYCBpbnN0ZWFkIG9mIHRocm93aW5nOyByZWFkIEZJUlNUIGJ5IGBydW4oKWAsIHdoaWNoIGZhaWxzIGV2ZXJ5IHRhc2sKICAgKiB3aXRoIGl0OyBjbGVhcmVkIGJ5IGB0ZWFyZG93bigpYCwgc28gYSB0b3JuLWRvd24gd29ya2VyIGlzIGluIGl0cyBjb25zdHJ1Y3RlZCBzdGF0ZSBhZ2Fpbi4KICAgKi8KICBzZXR1cEZhaWx1cmUgPSBudWxsOwogIC8qKgogICAqIEJvdGggYXJndW1lbnRzIGFyZSBrZXB0LCBhbmQgdGhlIHNlY29uZCBpcyBmb3J3YXJkZWQgdG8gdGhlIGlubmVyIHdvcmtlcjogdGhlIHNjaGVkdWxlciBwYXNzZXMKICAgKiBpdHMgd29ya2VyLWxldmVsIGNvbnRleHQgaGVyZSwgYW5kIGEgd29ya2VyIHRoYXQgb25seSBhY2NlcHRzIGBjb25maWdgIHNpbGVudGx5IGxvc2VzIHRoZQogICAqIGFiaWxpdHkgdG8gc2VsZi10ZXJtaW5hdGUgKHRoZSBzY2hlZHVsZXIncyBvd24gcmVmZXJlbmNlLCDCpzQpLgogICAqLwogIGNvbnN0cnVjdG9yKGNvbmZpZywgd29ya2VyQ29udGV4dCkgewogICAgdGhpcy5jZmcgPSBjb25maWc7CiAgICB0aGlzLndvcmtlckNvbnRleHQgPSB3b3JrZXJDb250ZXh0OwogIH0KICAvKioKICAgKiBMb2FkcyB0aGUgdHlwZSdzIHdvcmtlciBhbmQgcnVucyBJVFMgc2V0dXAg4oCUIGEgbW9kdWxlIHdpdGggbm8gZGVmYXVsdCBjbGFzcyBpcyByZWZ1c2VkIGJ5CiAgICogbmFtZSwgYXMgYXQgdjAuMTcg4oCUIHRoZW4gdGhlIHdvcmtlciBoYWxmIG9mIGV2ZXJ5IGxhbmd1YWdlIHRoZSBwb29sIGNvbmZpZyBuYW1lcywgT05DRSBwZXIKICAgKiB3b3JrZXIgaW5zdGFuY2UgKFAxNyBkZWNpc2lvbiAzKS4KICAgKgogICAqICoqQSBsYW5ndWFnZSBtb2R1bGUgdGhhdCBGQUlMUyBUTyBMT0FEIGRvZXMgbm90IHRocm93IGhlcmU7IHRoZSBmYWlsdXJlIGlzIHJlbWVtYmVyZWQgYW5kCiAgICogZXZlcnkgdGFzayB3aG9zZSB0cmFuc2Zvcm0gbmFtZXMgdGhhdCBsYW5ndWFnZSBmYWlscyBhdCBgcnVuKClgIHdpdGggaXQuKiogTWVhc3VyZWQgYXQgVzYxJ3MKICAgKiBkZWNsYXJhdGlvbiwgYm90aCBydW50aW1lcywgaW5saW5lIGFuZCB0aHJlYWRlZDogYSB3cmFwcGVyIHdob3NlIGBzZXR1cCgpYCB0aHJvd3MgbGVhdmVzIGV2ZXJ5CiAgICogdGFzayBvZiB0aGUgcG9vbCBgcGVuZGluZ2Agd2l0aCBgYXR0ZW1wdHM6IDBgLCB0aGUgcG9vbCByZXN0YXJ0cyBpdHMgd29ya2VyLCBhbmQgdGhlIHNjaGVkdWxlcgogICAqIGVtaXRzIG5vdGhpbmcgYSBkcml2ZXIgY291bGQgdHVybiBpbnRvIGEgcmVjb3JkIOKAlCB0aGUgZmFpbHVyZSBpcyByZXBvcnRlZCBvbiB0aGUgUE9PTCBhcwogICAqIGB3b3JrZXIuc2V0dXAuZmFpbGVkYCBhbmQgYHRhc2sucmVxdWV1ZV9yZXF1aXJlZGAsIGEgd29ya2VyIGVycm9yIGFuZCBub3QgYSB0YXNrJ3MsIHdoaWNoIGlzCiAgICogUDE3IHByZWRpY3Rpb24gMidzIHN0YXRlZCByZXZlcnNhbCBjb25kaXRpb24uIFRoZSBtYWludGFpbmVyIGNob3NlIHRoaXMgcm9hZCBhdCBXNjEncwogICAqIHN0b3AtYW5kLWFzayAoQURSIDAwNTEgcnVsZSA1KTogYSBVUkwgdGhhdCBkb2VzIG5vdCByZXNvbHZlLCBhIG1vZHVsZSB3aXRoIG5vIGRlZmF1bHQgY29tcGlsZQogICAqIGZ1bmN0aW9uLCBvciBhbiBlbXB0eSBVUkwsIGVhY2ggYmVjb21lcyBhIGBUcmFuc2Zvcm1GYWlsZWRgIG5hbWluZyB0aGUgbGFuZ3VhZ2UgYW5kIHRoZSBsb2FkCiAgICogZXJyb3IsIG9uIGV4YWN0bHkgdGhlIHRhc2tzIHRoYXQgbmVlZCB0aGF0IGxhbmd1YWdlIOKAlCBhIHRhc2sgd2l0aCBubyB0cmFuc2Zvcm0sIG9yIG9uZSBpbiBhCiAgICogbGFuZ3VhZ2UgdGhhdCBkaWQgbG9hZCwgc3RpbGwgcnVucyBvbiB0aGlzIHdvcmtlci4KICAgKgogICAqICoqQW5kIHNpbmNlIFcxNDEgdGhlIHNhbWUgaXMgdHJ1ZSBvZiB0aGUgVFlQRSdzIG93biB3b3JrZXI6IHRoaXMgbWV0aG9kIG5ldmVyIHRocm93cyoqIOKAlCBRMjY2LAogICAqIFAzMSBkZWNpc2lvbiAzLCBXNjEncyByb2FkIHRha2VuIGZvciB0aGUgd2hvbGUgb2YgYHNldHVwKClgLiBGMSBpcyBhIGZhY3QgYWJvdXQgVEhJUyBtZXRob2QKICAgKiB0aHJvd2luZywgd2hhdGV2ZXIgdGhyZXcsIGFuZCBXMTQxIG1lYXN1cmVkIGl0IGFnYWluIG9uIDAuNS4yIHRocm91Z2ggYGNyZWF0ZVJ1bnRpbWVgOiB0aHJlZQogICAqIHRhc2tzIG9uIGEgd29ya2VyIHdob3NlIGBzZXR1cCgpYCB0aHJvd3Mgc3RheSBgcGVuZGluZ2AgZm9yIGV2ZXIgaW4gYm90aCBwb29sIG1vZGVzLCB0aGUgcG9vbAogICAqIHJlcXVldWVpbmcgdGhlbSBvbiBlYWNoIHdvcmtlciBmYWlsdXJlIHVudGlsIGl0cyByZXN0YXJ0IGxpbWl0LCBhbmQgdGhlIHJ1bidzIGZvbGQgc2F5cwogICAqIGBydW5uaW5nYC4gU28gZXZlcnkgd2F5IHRoZSB0eXBlJ3Mgd29ya2VyIGNhbiBmYWlsIHRvIHNldCB1cCDigJQgdGhlIG1vZHVsZSBkb2VzIG5vdCBsb2FkLCBpdAogICAqIGV4cG9ydHMgbm8gZGVmYXVsdCBjbGFzcywgaXRzIGNvbnN0cnVjdG9yIHRocm93cywgaXRzIG93biBgc2V0dXAoKWAgdGhyb3dzIOKAlCBhbmQgdGhlIHR3bwogICAqIHBvb2wtY29uZmlnIHJlZnVzYWxzIHRoaXMgbWV0aG9kIG1hZGUgYnkgbmFtZSwgYXJlIFJFTUVNQkVSRUQgaW4gYHNldHVwRmFpbHVyZWAsIGFuZCBgcnVuKClgCiAgICogZmFpbHMgZXZlcnkgdGFzayBvbiB0aGlzIHdvcmtlciB3aXRoIGl0OiBhbiBvcmRpbmFyeSB0YXNrIGZhaWx1cmUsIHdoaWNoIHRoZSBydW4gcm91dGVzIHBlcgogICAqIEFEUiAwMDA0IOKAlCBkb3duIGFuIGBvbjogWyJmYWlsZWQiXWAgZWRnZSBvbiBhbiBvcHRpb25hbCBub2RlLCBwYXJrZWQgYHVzZXJfYWN0aW9uYCBvbiBhCiAgICogbm9uLW9wdGlvbmFsIG9uZS4gKipBIGNvbnN0cnVjdGVkIGlubmVyIHdvcmtlciBpcyB0b3JuIGRvd24gYXQgb25jZSoqLCBiZWNhdXNlIHRoZSBzY2hlZHVsZXIKICAgKiB0ZWFycyBkb3duIGEgd29ya2VyIHdob3NlIGBzZXR1cCgpYCB0aHJldyAoaXRzIG93biByZWZlcmVuY2UsIMKnNjogKmEgZmFpbGluZyBgc2V0dXAoKWAgc3RpbGwKICAgKiB0ZWFycyB0aGUgd29ya2VyIGRvd24qKSBhbmQgdGhpcyBjbGFzcyBpcyBub3cgdGhlIG9ubHkgdGhpbmcgdGhhdCBrbm93cyBvbmUgZGlkLiBUaGUgd29ya2VyCiAgICogc3RheXMgdXAgYW5kIGZhaWxzIGV2ZXJ5IHRhc2sgdW50aWwgdGhlIHBvb2wgaXMgcmVidWlsdDogYSBzZXR1cCB0aGF0IGZhaWxlZCBmb3IgYSB0cmFuc2llbnQKICAgKiByZWFzb24gaXMgbm90IHJldHJpZWQgaGVyZSAoVzE0MSdzIE91dCkuCiAgICovCiAgYXN5bmMgc2V0dXAoKSB7CiAgICB0aGlzLnNldHVwRmFpbHVyZSA9IG51bGw7CiAgICB0cnkgewogICAgICBhd2FpdCB0aGlzLnNldHVwT3JUaHJvdygpOwogICAgfSBjYXRjaCAoZSkgewogICAgICB0aGlzLnNldHVwRmFpbHVyZSA9IG1lc3NhZ2VPZihlKTsKICAgICAgY29uc3QgaW5uZXIgPSB0aGlzLmlubmVyOwogICAgICB0aGlzLmlubmVyID0gbnVsbDsKICAgICAgdGhpcy5ub0lubmVyID0gZmFsc2U7CiAgICAgIHRoaXMubGFuZ3MuY2xlYXIoKTsKICAgICAgaWYgKGlubmVyICE9PSBudWxsKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGF3YWl0IGlubmVyLnRlYXJkb3duPy4oKTsKICAgICAgICB9IGNhdGNoICh0KSB7CiAgICAgICAgICB0aGlzLnNldHVwRmFpbHVyZSArPSBgIChhbmQgaXRzIHRlYXJkb3duKCkgYWZ0ZXIgdGhlIGZhaWxlZCBzZXR1cCB0aHJldyB0b286ICR7bWVzc2FnZU9mKHQpfSlgOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KICAvKiogV2hhdCBgc2V0dXAoKWAgZGlkIHVudGlsIFcxNDEsIHRocm93cyBhbmQgYWxsOyBgc2V0dXAoKWAgdHVybnMgZWFjaCB0aHJvdyBpbnRvIGBzZXR1cEZhaWx1cmVgLiAqLwogIGFzeW5jIHNldHVwT3JUaHJvdygpIHsKICAgIGlmICh0aGlzLmNmZz8udHJhbnNmb3JtT25seSA9PT0gdHJ1ZSkgewogICAgICBpZiAodGhpcy5jZmcud29ya2VyICE9PSB2b2lkIDApIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGVudmVsb3BlIHdvcmtlcjogdGhlIHBvb2wgY29uZmlnIHNheXMgdHJhbnNmb3JtT25seSBBTkQgbmFtZXMgd29ya2VyICR7YnJpZWYodGhpcy5jZmcud29ya2VyKX0gXHUyMDE0IGEgdHlwZSBlaXRoZXIgaGFzIGFuIGlubmVyIHdvcmtlciBvciBvbmx5IHRyYW5zZm9ybXNgKTsKICAgICAgfQogICAgICB0aGlzLm5vSW5uZXIgPSB0cnVlOwogICAgICBmb3IgKGNvbnN0IFtuYW1lLCB1cmxdIG9mIE9iamVjdC5lbnRyaWVzKHRoaXMuY2ZnLmxhbmd1YWdlcyA/PyB7fSkpIHsKICAgICAgICB0aGlzLmxhbmdzLnNldChuYW1lLCBhd2FpdCB0aGlzLmxvYWRMYW5ndWFnZShuYW1lLCB1cmwpKTsKICAgICAgfQogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAodHlwZW9mIHRoaXMuY2ZnPy53b3JrZXIgIT09ICJzdHJpbmciIHx8IHRoaXMuY2ZnLndvcmtlci5sZW5ndGggPT09IDApIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBlbnZlbG9wZSB3b3JrZXI6IHRoZSBwb29sIGNvbmZpZyBuYW1lcyBubyB3b3JrZXIgVVJMIFx1MjAxNCBnb3QgJHticmllZih0aGlzLmNmZyl9YCk7CiAgICB9CiAgICBjb25zdCB3b3JrZXJVcmwgPSB0aGlzLmNmZy53b3JrZXI7CiAgICBsZXQgbW9kOwogICAgdHJ5IHsKICAgICAgbW9kID0gYXdhaXQgaW1wb3J0KHdvcmtlclVybCk7CiAgICB9IGNhdGNoIChlKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgZW52ZWxvcGUgd29ya2VyOiB0aGUgdHlwZSdzIHdvcmtlciAke0pTT04uc3RyaW5naWZ5KHdvcmtlclVybCl9IGRpZCBub3QgbG9hZDogJHttZXNzYWdlT2YoZSl9YCk7CiAgICB9CiAgICBpZiAodHlwZW9mIG1vZC5kZWZhdWx0ICE9PSAiZnVuY3Rpb24iIHx8ICFtb2QuZGVmYXVsdC5wcm90b3R5cGUpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBlbnZlbG9wZSB3b3JrZXI6IHRoZSB0eXBlJ3Mgd29ya2VyICR7SlNPTi5zdHJpbmdpZnkod29ya2VyVXJsKX0gbXVzdCBleHBvcnQgYSBkZWZhdWx0IGNsYXNzYCk7CiAgICB9CiAgICBjb25zdCBJbm5lciA9IG1vZC5kZWZhdWx0OwogICAgdHJ5IHsKICAgICAgdGhpcy5pbm5lciA9IG5ldyBJbm5lcih0aGlzLmNmZy5jb25maWcgPz8ge30sIHRoaXMud29ya2VyQ29udGV4dCk7CiAgICB9IGNhdGNoIChlKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgZW52ZWxvcGUgd29ya2VyOiB0aGUgdHlwZSdzIHdvcmtlciAke0pTT04uc3RyaW5naWZ5KHdvcmtlclVybCl9IHRocmV3IGZyb20gaXRzIGNvbnN0cnVjdG9yOiAke21lc3NhZ2VPZihlKX1gKTsKICAgIH0KICAgIHRyeSB7CiAgICAgIGF3YWl0IHRoaXMuaW5uZXIuc2V0dXA/LigpOwogICAgfSBjYXRjaCAoZSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYGVudmVsb3BlIHdvcmtlcjogdGhlIHR5cGUncyB3b3JrZXIgJHtKU09OLnN0cmluZ2lmeSh3b3JrZXJVcmwpfSB0aHJldyBmcm9tIGl0cyBzZXR1cCgpOiAke21lc3NhZ2VPZihlKX1gKTsKICAgIH0KICAgIGZvciAoY29uc3QgW25hbWUsIHVybF0gb2YgT2JqZWN0LmVudHJpZXModGhpcy5jZmcubGFuZ3VhZ2VzID8/IHt9KSkgewogICAgICB0aGlzLmxhbmdzLnNldChuYW1lLCBhd2FpdCB0aGlzLmxvYWRMYW5ndWFnZShuYW1lLCB1cmwpKTsKICAgIH0KICB9CiAgLyoqIE9uZSBsYW5ndWFnZSdzIHdvcmtlciBoYWxmLCBvciB0aGUgRXJyb3IgdGhhdCBzdGFuZHMgaW4gZm9yIGl0IOKAlCBuZXZlciBhIHRocm93IChzZWUgYHNldHVwKClgKS4gKi8KICBhc3luYyBsb2FkTGFuZ3VhZ2UobmFtZSwgdXJsKSB7CiAgICBpZiAodHlwZW9mIHVybCAhPT0gInN0cmluZyIgfHwgdXJsLmxlbmd0aCA9PT0gMCkgewogICAgICByZXR1cm4gbmV3IEVycm9yKGBsYW5ndWFnZSAiJHtuYW1lfSIgbmFtZXMgbm8gd29ya2VyIG1vZHVsZSBVUkwgaW4gdGhlIHBvb2wgY29uZmlnIFx1MjAxNCBnb3QgJHticmllZih1cmwpfWApOwogICAgfQogICAgdHJ5IHsKICAgICAgY29uc3QgbG0gPSBhd2FpdCBpbXBvcnQodXJsKTsKICAgICAgaWYgKHR5cGVvZiBsbS5kZWZhdWx0ICE9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgcmV0dXJuIG5ldyBFcnJvcihgbGFuZ3VhZ2UgIiR7bmFtZX0iJ3Mgd29ya2VyIG1vZHVsZSAke3VybH0gbXVzdCBleHBvcnQgYSBkZWZhdWx0IGNvbXBpbGUgZnVuY3Rpb24gKGdvdCAke3R5cGVvZiBsbS5kZWZhdWx0fSlgKTsKICAgICAgfQogICAgICByZXR1cm4gbG0uZGVmYXVsdDsKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgcmV0dXJuIG5ldyBFcnJvcihgbGFuZ3VhZ2UgIiR7bmFtZX0iJ3Mgd29ya2VyIG1vZHVsZSAke3VybH0gZGlkIG5vdCBsb2FkOiAke21lc3NhZ2VPZihlKX1gKTsKICAgIH0KICB9CiAgLyoqCiAgICogYEZELUM1YDogdGhlIGlubmVyIHdvcmtlciByZWNlaXZlcyBgeyBzZXR0aW5ncywgaW5wdXQgfWAgYXMgaXRzIHBheWxvYWQsIGFuZCB0aGUgc2NoZWR1bGVyJ3MgdGFzayBjb250ZXh0IGFzIGl0cwogICAqIHNlY29uZCBhcmd1bWVudCwgcGFzc2VkIHRocm91Z2ggdW50b3VjaGVkIChXMTU5KS4gYEZELUM2YDogd2hlbiB0aGUKICAgKiBlbnZlbG9wZSBjYXJyaWVzIGEgYHRyYW5zZm9ybWAsIGBpbnB1dGAgaXMgdGhlIGV2YWx1YXRpb24gb2YgdGhhdCBleHByZXNzaW9uIG92ZXIgdGhlIHZhbHVlCiAgICogcmVjZWl2ZWQsIHdpdGggdGhlIG5vZGUncyBzZXR0aW5ncyBib3VuZCBhcyBgJHNldHRpbmdzYCwgYW5kIHRoZSB0aGlyZCBrZXkgaXMgY29uc3VtZWQgaGVyZS4KICAgKi8KICBhc3luYyBydW4ocGF5bG9hZCwgY29udGV4dCkgewogICAgaWYgKHRoaXMuc2V0dXBGYWlsdXJlICE9PSBudWxsKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLnNldHVwRmFpbHVyZX0gXHUyMDE0IGV2ZXJ5IHRhc2sgb24gdGhpcyB3b3JrZXIgZmFpbHMgd2l0aCB0aGlzIHVudGlsIHRoZSBwb29sIGlzIHJlYnVpbHRgKTsKICAgIH0KICAgIGlmICh0aGlzLmlubmVyID09PSBudWxsICYmICF0aGlzLm5vSW5uZXIpIHRocm93IG5ldyBFcnJvcigiZW52ZWxvcGUgd29ya2VyOiBydW4oKSBiZWZvcmUgc2V0dXAoKSBcdTIwMTQgdGhlIGlubmVyIHdvcmtlciBpcyBub3QgbG9hZGVkIik7CiAgICBjb25zdCBlbnYgPSB1bnBhY2tFbnZlbG9wZShwYXlsb2FkKTsKICAgIGlmICh0aGlzLm5vSW5uZXIpIHsKICAgICAgaWYgKGVudi50cmFuc2Zvcm0gPT09IHZvaWQgMCkgewogICAgICAgIHRocm93IG5ldyBOb3RBbkVudmVsb3BlKCJ0eXBlZCBwb29sOiB0aGlzIHBvb2xgcyB0eXBlIG5hbWVzIG5vIHdvcmtlciwgc28gdGhlIGVudmVsb3BlIG11c3QgY2FycnkgYSB0cmFuc2Zvcm0gXHUyMDE0IHRoZXJlIGlzIG5vdGhpbmcgZWxzZSBmb3IgdGhlIHRhc2sgdG8gZG8gKEZELVY0NiByZWZ1c2VzIHN1Y2ggYSBub2RlIGF0IGNvbnN0cnVjdGlvbikiKTsKICAgICAgfQogICAgICByZXR1cm4gYXdhaXQgdGhpcy50cmFuc2Zvcm0oZW52LnRyYW5zZm9ybSwgZW52LmlucHV0LCBlbnYuc2V0dGluZ3MpOwogICAgfQogICAgY29uc3QgaW5wdXQgPSBlbnYudHJhbnNmb3JtID09PSB2b2lkIDAgPyBlbnYuaW5wdXQgOiBhd2FpdCB0aGlzLnRyYW5zZm9ybShlbnYudHJhbnNmb3JtLCBlbnYuaW5wdXQsIGVudi5zZXR0aW5ncyk7CiAgICByZXR1cm4gYXdhaXQgdGhpcy5pbm5lci5ydW4oeyBzZXR0aW5nczogZW52LnNldHRpbmdzLCBpbnB1dCB9LCBjb250ZXh0KTsKICB9CiAgLyoqIEV2YWx1YXRlcyBvbmUgZGVjbGFyZWQgdHJhbnNmb3JtOyBldmVyeSBmYWlsdXJlIGlzIGEgYFRyYW5zZm9ybUZhaWxlZGAgbmFtaW5nIHdoYXQgZmFpbGVkIGFuZCB3aHkuICovCiAgYXN5bmMgdHJhbnNmb3JtKHQsIGlucHV0LCBzZXR0aW5ncykgewogICAgY29uc3QgY29tcGlsZSA9IHRoaXMubGFuZ3MuZ2V0KHQubGFuZyk7CiAgICBpZiAoY29tcGlsZSA9PT0gdm9pZCAwKSB7CiAgICAgIGNvbnN0IGNhcnJpZWQgPSBPYmplY3Qua2V5cyh0aGlzLmNmZy5sYW5ndWFnZXMgPz8ge30pLm1hcCgoeCkgPT4gYCIke3h9ImApLmpvaW4oIiwgIikgfHwgIm5vIGxhbmd1YWdlcyI7CiAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1GYWlsZWQodCwgdm9pZCAwLCBgbGFuZ3VhZ2UgIiR7dC5sYW5nfSIgaXMgbm90IGxvYWRlZCBpbiB0aGlzIHBvb2wgKHRoZSBwb29sIGNvbmZpZyBjYXJyaWVzICR7Y2FycmllZH0pIFx1MjAxNCB0aGUgYm9vdHN0cmFwIGhlbHBlciB3cml0ZXMgZXZlcnkgbGFuZ3VhZ2UgaXQgaXMgZ2l2ZW4gaW50byBldmVyeSBwb29sLCBzbyB0aGlzIG9uZSB3YXMgbm90IGluIHRoZSByZWdpc3RyeSB0aGUgcG9vbCB3YXMgYnVpbHQgZnJvbWApOwogICAgfQogICAgaWYgKGNvbXBpbGUgaW5zdGFuY2VvZiBFcnJvcikgewogICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtRmFpbGVkKHQsIHZvaWQgMCwgYCR7Y29tcGlsZS5tZXNzYWdlfSBcdTIwMTQgZXZlcnkgdGFzayB0cmFuc2Zvcm1pbmcgaW4gIiR7dC5sYW5nfSIgb24gdGhpcyB3b3JrZXIgZmFpbHMgd2l0aCB0aGlzIHVudGlsIHRoZSBwb29sIGlzIHJlYnVpbHRgKTsKICAgIH0KICAgIGNvbnN0IGtleSA9IEpTT04uc3RyaW5naWZ5KFt0LmxhbmcsIHQuZXhwcl0pOwogICAgbGV0IGNvbXBpbGVkID0gdGhpcy5jb21waWxlZC5nZXQoa2V5KTsKICAgIGlmIChjb21waWxlZCA9PT0gdm9pZCAwKSB7CiAgICAgIHRyeSB7CiAgICAgICAgY29tcGlsZWQgPSBjb21waWxlKHQuZXhwcik7CiAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtRmFpbGVkKHQsIGNvZGVPZihlKSwgYHRoZSB3b3JrZXIgaGFsZiBvZiAiJHt0Lmxhbmd9IiByZWZ1c2VkIHRoZSBleHByZXNzaW9uIHRoZSByZWdpc3RyeSBoYWxmIGFjY2VwdGVkOiAke21lc3NhZ2VPZihlKX1gKTsKICAgICAgfQogICAgICBpZiAodHlwZW9mIGNvbXBpbGVkPy5ldmFsdWF0ZSAhPT0gImZ1bmN0aW9uIikgewogICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1GYWlsZWQodCwgdm9pZCAwLCBgdGhlIHdvcmtlciBoYWxmIG9mICIke3QubGFuZ30iIGNvbXBpbGVkIHRvICR7YnJpZWYoY29tcGlsZWQpfSwgd2hpY2ggaGFzIG5vIGV2YWx1YXRlKGlucHV0LCBzZXR0aW5ncylgKTsKICAgICAgfQogICAgICB0aGlzLmNvbXBpbGVkLnNldChrZXksIGNvbXBpbGVkKTsKICAgIH0KICAgIHRyeSB7CiAgICAgIHJldHVybiBhd2FpdCBjb21waWxlZC5ldmFsdWF0ZShpbnB1dCwgc2V0dGluZ3MpOwogICAgfSBjYXRjaCAoZSkgewogICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtRmFpbGVkKHQsIGNvZGVPZihlKSwgbWVzc2FnZU9mKGUpKTsKICAgIH0KICB9CiAgYXN5bmMgdGVhcmRvd24oKSB7CiAgICBhd2FpdCB0aGlzLmlubmVyPy50ZWFyZG93bj8uKCk7CiAgICB0aGlzLmlubmVyID0gbnVsbDsKICAgIHRoaXMubm9Jbm5lciA9IGZhbHNlOwogICAgdGhpcy5zZXR1cEZhaWx1cmUgPSBudWxsOwogICAgdGhpcy5sYW5ncy5jbGVhcigpOwogICAgdGhpcy5jb21waWxlZC5jbGVhcigpOwogIH0KfTsKZXhwb3J0IHsKICBOb3RBbkVudmVsb3BlLAogIFRyYW5zZm9ybUZhaWxlZCwKICBFbnZlbG9wZVdvcmtlciBhcyBkZWZhdWx0LAogIHVucGFja0VudmVsb3BlCn07Cg==";
32
35
 
33
36
  // src/scheduler/bootstrap.ts
34
37
  var ENVELOPE_WORKER_URL = envelope_worker_default;
35
38
  var BootstrapError = class extends Error {
36
39
  };
37
40
  var defaultCreatePool = (scriptUrl, options) => new WorkerManager(scriptUrl, options);
38
- function transformLanguagesByType(flows) {
39
- const out = /* @__PURE__ */ new Map();
40
- for (const flow of flows) {
41
- for (const n of flow.nodes) {
42
- if (n.kind !== "task") continue;
43
- const t = n;
44
- if (t.type === void 0 || t.transform === void 0) continue;
45
- let set = out.get(t.type);
46
- if (set === void 0) {
47
- set = /* @__PURE__ */ new Set();
48
- out.set(t.type, set);
49
- }
50
- set.add(t.transform.lang);
51
- }
52
- }
53
- return out;
54
- }
55
41
  function bootstrap(registry, groups = {}, options = {}) {
56
42
  checkRegistry(registry);
57
43
  const workers = workersOf(registry.workers);
@@ -68,7 +54,7 @@ function bootstrap(registry, groups = {}, options = {}) {
68
54
  for (const [key, inst] of named) {
69
55
  const entry = types.get(inst.type);
70
56
  const def = isDerivation(entry) ? entry : nodeTypeFromDeclaration(entry);
71
- derived[key] = derivePool(key, inst.type, def, def.worker === void 0 ? void 0 : workers.get(def.worker), inst.config, groupKeys, ConfigRefused);
57
+ derived[key] = derivePool(key, inst.type, def, def.worker === void 0 ? void 0 : workers.get(def.worker), inst.config, groupKeys, ConfigRefused, inst.pool);
72
58
  }
73
59
  for (const [name, entry] of types) if (builtIn(name)) one(name, name, entry, (isDerivation(entry) ? entry : nodeTypeFromDeclaration(entry)).config, TypeDefaultRefused);
74
60
  const namedByPools = /* @__PURE__ */ new Set();
@@ -79,28 +65,18 @@ function bootstrap(registry, groups = {}, options = {}) {
79
65
  }
80
66
  }
81
67
  const adapters = languagesOf(options.languages);
82
- const byType = transformLanguagesByType(options.flows ?? []);
83
- const languagesFor = /* @__PURE__ */ new Map();
84
- for (const [name] of types) {
85
- const langs = byType.get(name);
86
- if (langs === void 0 || langs.size === 0) continue;
87
- const urls = {};
88
- for (const lang of [...langs].sort()) {
89
- const adapter = adapters.get(lang);
90
- if (adapter === void 0) {
91
- throw new BootstrapError(`node type "${name}" has a node declaring transform.lang "${lang}", and no adapter was given for it (given: ${[...adapters.keys()].sort().map((x) => `"${x}"`).join(", ") || "none"}) \u2014 the wrapper would meet the transform with nothing to evaluate it`);
92
- }
93
- if (typeof adapter.worker !== "string" || adapter.worker.length === 0) {
94
- throw new BootstrapError(`language "${lang}" names no worker module URL \u2014 LanguageAdapter.worker is the URL of the module whose default export compiles and evaluates it; a function cannot cross to a thread`);
95
- }
96
- urls[lang] = adapter.worker;
68
+ let languages;
69
+ for (const lang of [...adapters.keys()].sort()) {
70
+ const adapter = adapters.get(lang);
71
+ if (typeof adapter?.worker !== "string" || adapter.worker.length === 0) {
72
+ throw new BootstrapError(`language "${lang}" names no worker module URL \u2014 LanguageAdapter.worker is the URL of the module whose default export compiles and evaluates it; a function cannot cross to a thread`);
97
73
  }
98
- languagesFor.set(name, urls);
74
+ (languages ??= {})[lang] = adapter.worker;
99
75
  }
100
76
  const createPool = options.createPool ?? defaultCreatePool;
101
77
  const workerPools = {};
102
78
  for (const [key, p] of Object.entries(derived)) {
103
- workerPools[key] = createPool(ENVELOPE_WORKER_URL, poolOptionsOf(p.spec, p.definition.inline, p.worker?.url, languagesFor.get(p.type)));
79
+ workerPools[key] = createPool(ENVELOPE_WORKER_URL, poolOptionsOf(p.spec, p.definition.inline, p.worker?.url, languages === void 0 ? void 0 : { ...languages }));
104
80
  }
105
81
  return { workerPools, resourceGroups: { ...groups }, derived };
106
82
  }
@@ -122,10 +98,11 @@ var GroupUnusable = class extends RuntimeError {
122
98
  };
123
99
  var GroupNotBuildable = class extends RuntimeError {
124
100
  };
125
- var LanguageNotBuilt = class extends RuntimeError {
126
- };
127
101
  var RunIdInUse = class extends RuntimeError {
128
102
  };
103
+ var LimitKeyMissing = class extends RuntimeError {
104
+ };
105
+ var KEYED_RULE = "FD-R6";
129
106
  var BUILT_IN_GROUP_FACTORIES = {
130
107
  ConcurrentLimitGroup: (config, key) => new ConcurrentLimitGroup(config.limit, key),
131
108
  RateLimitGroup: (config, key) => new RateLimitGroup(config.windows, key),
@@ -161,6 +138,10 @@ function checkGroup(key, typeName, group) {
161
138
  return group;
162
139
  }
163
140
  function createRuntime(document, code = {}, options = {}) {
141
+ if (options.defaultRetryPolicy !== void 0) {
142
+ const problem = retryPolicyProblem(options.defaultRetryPolicy);
143
+ if (problem !== null) throw new InvalidDefinition(["FD-V30"], `defaultRetryPolicy is not a RetryPolicy \u2014 FD-V30: ${problem}`);
144
+ }
164
145
  const resolved = resolveRegistry(document, code);
165
146
  const suppliedPredicateNames = code.predicates === void 0 ? [] : code.predicates instanceof Map ? [...code.predicates.keys()] : code.predicates instanceof Set ? [...code.predicates] : Array.isArray(code.predicates) ? [...code.predicates] : Object.keys(code.predicates);
166
147
  for (const [what, named, given] of [
@@ -192,7 +173,7 @@ function createRuntime(document, code = {}, options = {}) {
192
173
  const nodeTypes = {};
193
174
  for (const [name, def] of resolved.nodeTypes) nodeTypes[name] = def;
194
175
  const pools = {};
195
- for (const [key, p] of resolved.pools) if (key !== p.type) pools[key] = { type: p.type, config: p.config };
176
+ for (const [key, p] of resolved.pools) if (key !== p.type) pools[key] = { type: p.type, config: p.config, ...p.pool !== void 0 ? { pool: p.pool } : {} };
196
177
  const languages = {};
197
178
  for (const [name, adapter] of resolved.languages) languages[name] = adapter;
198
179
  const namedByPools = {};
@@ -201,8 +182,7 @@ function createRuntime(document, code = {}, options = {}) {
201
182
  }
202
183
  const built = bootstrap({ workers, nodeTypes, pools }, namedByPools, {
203
184
  ...options.createPool !== void 0 ? { createPool: options.createPool } : {},
204
- languages,
205
- flows: options.flows ?? []
185
+ languages
206
186
  });
207
187
  const scheduler = (options.createScheduler ?? ((p, g) => new FyflowScheduler(p, g)))(built.workerPools, groups);
208
188
  const predicates = /* @__PURE__ */ new Map();
@@ -220,7 +200,40 @@ function createRuntime(document, code = {}, options = {}) {
220
200
  languages,
221
201
  ...code.gateTypes !== void 0 ? { gateTypes: code.gateTypes } : {}
222
202
  };
223
- const builtLanguages = transformLanguagesByType(options.flows ?? []);
203
+ const validatorRegistry = {
204
+ predicates: new Set(predicates.keys()),
205
+ groups: new Set(registry.groups ?? []),
206
+ nodeTypes: nodeTypesOf(registry.nodeTypes),
207
+ languages: languagesOf(registry.languages),
208
+ workers: workersOf(registry.workers),
209
+ pools: poolsOf(registry.pools),
210
+ ...registry.gateTypes !== void 0 ? { gateTypes: registry.gateTypes } : {}
211
+ };
212
+ const keyedByBuiltIn = /* @__PURE__ */ new Set();
213
+ for (const [key, g] of resolved.groups) if (g.type === "KeyedRateLimitGroup") keyedByBuiltIn.add(key);
214
+ const keyedFindings = (flow) => {
215
+ const nodes = flow?.nodes;
216
+ if (keyedByBuiltIn.size === 0 || typeof nodes?.[Symbol.iterator] !== "function") return [];
217
+ const out = [];
218
+ for (const node of nodes) {
219
+ if (typeof node !== "object" || node === null) continue;
220
+ const n = node;
221
+ if (n.kind !== "task") continue;
222
+ const poolKey = typeof n.pool === "string" ? n.pool : typeof n.type === "string" ? n.type : void 0;
223
+ const fromPool = poolKey === void 0 ? [] : resolved.pools.get(poolKey)?.spec.groups ?? [];
224
+ const fromNode = Array.isArray(n.workerGroups) ? n.workerGroups.filter((g) => typeof g === "string") : [];
225
+ const reached = [.../* @__PURE__ */ new Set([...fromPool, ...fromNode])].filter((g) => keyedByBuiltIn.has(g)).sort();
226
+ if (reached.length === 0) continue;
227
+ const at = typeof n.id === "string" ? n.id : null;
228
+ out.push({
229
+ rule: KEYED_RULE,
230
+ at,
231
+ detail: `node ${at === null ? "<unnamed>" : q(at)} reaches keyed group${reached.length > 1 ? "s" : ""} ${reached.map(q).join(", ")}, built by the built-in KeyedRateLimitGroup factory with no keyFrom \u2014 so every task of it needs a limitKey, which nothing sets unless start is given a createTask, and without one the scheduler's addTask throws "Missing limit key". Two roads work: pass start a createTask that sets limitKey on the task it builds, or declare the group with a code group type (code.groupTypes) whose create() builds a KeyedRateLimitGroup with a keyFrom that derives the key. A key derived from the flow itself is Q248, deferred`
232
+ });
233
+ }
234
+ return out;
235
+ };
236
+ const check = (flow) => [...validateDefinition(flow, validatorRegistry), ...keyedFindings(flow)];
224
237
  let minted = 0;
225
238
  const inUse = /* @__PURE__ */ new Set();
226
239
  const router = settlementRouter(scheduler);
@@ -237,6 +250,7 @@ function createRuntime(document, code = {}, options = {}) {
237
250
  scheduler,
238
251
  pools: built.derived,
239
252
  groups,
253
+ check,
240
254
  start(flow, payload, startOptions = {}) {
241
255
  return openRun(flow, payload, startOptions, null);
242
256
  },
@@ -252,14 +266,12 @@ function createRuntime(document, code = {}, options = {}) {
252
266
  };
253
267
  return runtime;
254
268
  function openRun(flow, payload, startOptions, from) {
255
- for (const [type, langs] of transformLanguagesByType([flow])) {
256
- if (!resolved.nodeTypes.has(type)) continue;
257
- const carried = builtLanguages.get(type) ?? /* @__PURE__ */ new Set();
258
- for (const lang of langs) {
259
- if (!carried.has(lang)) {
260
- throw new LanguageNotBuilt(type, `flow ${q(flow.flowId)} declares transform.lang ${q(lang)} on a node of type ${q(type)}, and this runtime's pools for that type carry ${carried.size ? [...carried].sort().map(q).join(", ") : "no language"} \u2014 pools are built once, so pass every flow this runtime will run as \`flows\` to createRuntime`);
261
- }
262
- }
269
+ const findings = check(flow);
270
+ const definition = findings.filter((f) => f.rule !== KEYED_RULE);
271
+ if (definition.length) throw InvalidDefinition.fromFindings(flow.flowId, definition);
272
+ const keyed = startOptions.createTask === void 0 ? findings.filter((f) => f.rule === KEYED_RULE) : [];
273
+ if (keyed.length) {
274
+ throw new LimitKeyMissing(keyed[0].at ?? "<document>", `flow "${flow.flowId}" cannot start with no createTask \u2014 ` + keyed.map((f) => `${f.rule} at ${f.at ?? "<document>"}: ${f.detail}`).join("; ") + " (ADR 0097)");
263
275
  }
264
276
  const runId = startOptions.runId ?? mint();
265
277
  if (inUse.has(runId)) {
@@ -269,16 +281,75 @@ function createRuntime(document, code = {}, options = {}) {
269
281
  const done = new Promise((resolve) => {
270
282
  settle = resolve;
271
283
  });
272
- let state = emptyState();
284
+ const acc = Accumulator.load(emptyState());
285
+ let cached = null;
286
+ const frozen = /* @__PURE__ */ new WeakSet();
273
287
  let settled = false;
274
288
  let seed = from === null ? null : from.events;
289
+ const own = (input) => {
290
+ if (input.kind !== "outcome" && input.kind !== "resolution") return input;
291
+ const r = input.record;
292
+ return typeof r.result === "object" && r.result !== null ? { kind: input.kind, record: structuredClone(r) } : input;
293
+ };
294
+ const take = (input) => {
295
+ if (acc.apply(own(input))) cached = null;
296
+ };
297
+ const catchUp = () => {
298
+ if (seed === null) return;
299
+ for (const stored of seed) take(stored);
300
+ seed = null;
301
+ };
302
+ const freezeDeep = (root) => {
303
+ const stack = [root];
304
+ while (stack.length > 0) {
305
+ const v = stack.pop();
306
+ if (typeof v !== "object" || v === null || frozen.has(v)) continue;
307
+ frozen.add(v);
308
+ if (ArrayBuffer.isView(v)) continue;
309
+ if (v instanceof Map) for (const [k, x] of v) stack.push(k, x);
310
+ else if (v instanceof Set) for (const x of v) stack.push(x);
311
+ for (const k of Reflect.ownKeys(v)) {
312
+ const d = Object.getOwnPropertyDescriptor(v, k);
313
+ if (d !== void 0 && "value" in d) stack.push(d.value);
314
+ }
315
+ Object.freeze(v);
316
+ }
317
+ return root;
318
+ };
319
+ const current = () => {
320
+ catchUp();
321
+ return cached ??= freezeDeep(acc.materialise());
322
+ };
275
323
  const settleIfTerminal = () => {
276
- if (settled || !isTerminal(state)) return;
324
+ if (settled || !isTerminal({ outcome: acc.outcomeNow() })) return;
277
325
  settled = true;
278
- settle(state);
326
+ const at = current();
327
+ if (at.outcome === "interrupted" && stopping.size > 0) {
328
+ const fin = () => {
329
+ settle(at);
330
+ router.release(runId);
331
+ };
332
+ void Promise.allSettled([...stopping]).then(fin);
333
+ return;
334
+ }
335
+ settle(at);
279
336
  router.release(runId);
280
337
  };
281
- const scheduler2 = router.forRun(runId);
338
+ const view = router.forRun(runId);
339
+ const stopping = /* @__PURE__ */ new Set();
340
+ const viewCancel = view.cancel;
341
+ const scheduler2 = typeof viewCancel === "function" ? {
342
+ ...view,
343
+ cancel: (id, cancelOptions) => {
344
+ const p = viewCancel(id, cancelOptions);
345
+ stopping.add(p);
346
+ const drop = () => {
347
+ stopping.delete(p);
348
+ };
349
+ p.then(drop, drop);
350
+ return p;
351
+ }
352
+ } : view;
282
353
  const driver = new Driver(flow, {
283
354
  runId,
284
355
  scheduler: scheduler2,
@@ -298,16 +369,18 @@ function createRuntime(document, code = {}, options = {}) {
298
369
  // of a run from its first, and it is the well-formed wrong answer the first time a driver's
299
370
  // sequence does not start at this callback's first call.
300
371
  onFoldInput: (input, seq) => {
301
- if (seed !== null) {
302
- for (const stored of seed) state = step(state, stored);
303
- seed = null;
304
- }
305
- state = step(state, input);
372
+ catchUp();
373
+ take(input);
306
374
  queueMicrotask(settleIfTerminal);
307
375
  startOptions.onFoldInput?.(input, seq);
308
376
  },
377
+ ...startOptions.onHeader !== void 0 ? { onHeader: startOptions.onHeader } : {},
309
378
  ...startOptions.onRegionEvent !== void 0 ? { onRegionEvent: startOptions.onRegionEvent } : {},
310
379
  ...startOptions.onRunFailure !== void 0 ? { onRunFailure: startOptions.onRunFailure } : {},
380
+ // **Spread only when given** (`RN-R42`): the driver subscribes the pass-through events for a callback present, so an
381
+ // `undefined` forwarded here must stay ABSENT — and on a runtime the scheduler is subscribed once the first run asks.
382
+ ...startOptions.onTaskMessage !== void 0 ? { onTaskMessage: startOptions.onTaskMessage } : {},
383
+ ...startOptions.onTaskProgress !== void 0 ? { onTaskProgress: startOptions.onTaskProgress } : {},
311
384
  ...startOptions.onUnsatisfiableJoin !== void 0 ? { onUnsatisfiableJoin: startOptions.onUnsatisfiableJoin } : {},
312
385
  ...startOptions.onUnmintedTask !== void 0 ? { onUnmintedTask: startOptions.onUnmintedTask } : {},
313
386
  ...startOptions.onNonconformingResult !== void 0 ? { onNonconformingResult: startOptions.onNonconformingResult } : {},
@@ -321,7 +394,22 @@ function createRuntime(document, code = {}, options = {}) {
321
394
  router.release(runId);
322
395
  throw e;
323
396
  }
324
- return { driver, done, header: driver.checkpoint().header };
397
+ return {
398
+ driver,
399
+ done,
400
+ header: driver.checkpoint().header,
401
+ stop: (stopOptions) => driver.stop(stopOptions),
402
+ state: current,
403
+ outcome: () => {
404
+ catchUp();
405
+ return acc.outcomeNow();
406
+ },
407
+ node: (taskId) => {
408
+ catchUp();
409
+ const entry = acc.entry(taskId);
410
+ return entry === void 0 ? null : freezeDeep(entry);
411
+ }
412
+ };
325
413
  }
326
414
  }
327
415
  function settlementRouter(scheduler) {
@@ -329,7 +417,8 @@ function settlementRouter(scheduler) {
329
417
  const every = /* @__PURE__ */ new Map();
330
418
  const deliver = (name) => (e) => {
331
419
  const detail = "detail" in e ? e.detail : void 0;
332
- const id = typeof detail === "object" && detail !== null ? detail.id : void 0;
420
+ const d = typeof detail === "object" && detail !== null ? detail : void 0;
421
+ const id = typeof d?.id === "string" ? d.id : d?.taskId;
333
422
  let runId = null;
334
423
  if (typeof id === "string") {
335
424
  try {
@@ -355,7 +444,9 @@ function settlementRouter(scheduler) {
355
444
  };
356
445
  return {
357
446
  forRun(runId) {
447
+ const cancel = scheduler.cancel;
358
448
  return {
449
+ ...typeof cancel === "function" ? { cancel: (id, options) => cancel.call(scheduler, id, options) } : {},
359
450
  addTask: (task, options) => scheduler.addTask(task, options),
360
451
  addEventListener(name, listener) {
361
452
  let mine = byRun.get(runId);
@@ -589,7 +680,8 @@ var EnvelopeWorker = class {
589
680
  }
590
681
  }
591
682
  /**
592
- * `FD-C5`: the inner worker receives `{ settings, input }` and nothing else. `FD-C6`: when the
683
+ * `FD-C5`: the inner worker receives `{ settings, input }` as its payload, and the scheduler's task context as its
684
+ * second argument, passed through untouched (W159). `FD-C6`: when the
593
685
  * envelope carries a `transform`, `input` is the evaluation of that expression over the value
594
686
  * received, with the node's settings bound as `$settings`, and the third key is consumed here.
595
687
  */
@@ -613,7 +705,7 @@ var EnvelopeWorker = class {
613
705
  const compile = this.langs.get(t.lang);
614
706
  if (compile === void 0) {
615
707
  const carried = Object.keys(this.cfg.languages ?? {}).map((x) => `"${x}"`).join(", ") || "no languages";
616
- throw new TransformFailed(t, void 0, `language "${t.lang}" is not loaded in this pool (the pool config carries ${carried}) \u2014 the bootstrap helper writes an adapter URL for a type some node of which declares a transform, and needs the flow and the languages to do it`);
708
+ throw new TransformFailed(t, void 0, `language "${t.lang}" is not loaded in this pool (the pool config carries ${carried}) \u2014 the bootstrap helper writes every language it is given into every pool, so this one was not in the registry the pool was built from`);
617
709
  }
618
710
  if (compile instanceof Error) {
619
711
  throw new TransformFailed(t, void 0, `${compile.message} \u2014 every task transforming in "${t.lang}" on this worker fails with this until the pool is rebuilt`);
@@ -654,13 +746,12 @@ export {
654
746
  GROUP_MEMBERS,
655
747
  GroupNotBuildable,
656
748
  GroupUnusable,
657
- LanguageNotBuilt,
749
+ LimitKeyMissing,
658
750
  NotAnEnvelope,
659
751
  RunIdInUse,
660
752
  RuntimeError,
661
753
  TransformFailed,
662
754
  bootstrap,
663
755
  createRuntime,
664
- transformLanguagesByType,
665
756
  unpackEnvelope
666
757
  };
@@ -10,7 +10,7 @@
10
10
  * | | what it answers |
11
11
  * |---|---|
12
12
  * | `pathsOf(schema)` | *what is there to reach for* — every path a value of the schema may carry |
13
- * | `tryTransform(registry, flow, node, transform)` | *does THIS expression fit* — the sample-and-diff loop, one candidate at a time |
13
+ * | `tryTransform(registry, flow, node, transform, { input }?)` | *does THIS expression fit* — the sample-and-diff loop, one candidate at a time, on the arcs' samples or on a value the caller gives |
14
14
  * | `signatureOf(name, worker)` | *what do I write my worker against* — a TypeScript signature from the three schemas |
15
15
  *
16
16
  * **The loop is a SUBSTITUTION over `checkWiring` and not a second evaluator** (W74 fact B): it puts
@@ -19,7 +19,10 @@
19
19
  * branch task composing `"."` and transforming it must be evaluated once per ELEMENT, and an assist
20
20
  * that re-implemented the evaluation would have to rediscover that. Every verdict it returns is
21
21
  * therefore W73's, unchanged: *the sample passed*, never *fits*, with the sample's source and arity
22
- * on it ([Q301](../../doc/questions/q301.md)).
22
+ * on it ([Q301](../../doc/questions/q301.md)). **A given input keeps the substitution** (v0.38,
23
+ * [W166](../../doc/work-items/w166-a-sample-the-caller-gives.md)): the candidate goes on the same copy, and
24
+ * `wiring.ts`'s `givenVerdict` runs it through the same evaluation the arcs take — one verdict, source
25
+ * `'given'`.
23
26
  *
24
27
  * **`pathsOf` does NOT gate on `schemaProblem`, and that is a decision rather than an oversight**
25
28
  * (W74 fact A). ADR 0053 rule 5 puts that gate in front of `findings`, because a VALUE check may not
@@ -91,6 +94,18 @@ export interface CandidateTransform {
91
94
  lang: string;
92
95
  expr: string;
93
96
  }
97
+ /** `tryTransform`'s options: the wiring check's, and the value a caller gives (W166). */
98
+ export interface TryTransformOptions extends WiringOptions {
99
+ /**
100
+ * **What the node RECEIVES — `$` — given by the caller** (v0.38, P37 stop-and-ask (d)): typed or pasted
101
+ * by a person in an editor, or held by an agent. Given, the candidate runs ONCE on this value and
102
+ * `tryTransform` returns ONE verdict of shape `given`, whatever arcs reach the node — the ENTRY node
103
+ * included, which no arc reaches. No `needs` is composed over it: it IS the value the node receives.
104
+ * **`undefined` is not a value** — a key present holding `undefined` is no input, and the arcs answer as
105
+ * they always have (JSON has no `undefined`; `null` IS a value, and is given).
106
+ */
107
+ input?: unknown;
108
+ }
94
109
  /**
95
110
  * **One candidate expression on one node, and what every arc into that node then says** — the
96
111
  * sample-and-diff loop, and the whole of it.
@@ -99,12 +114,21 @@ export interface CandidateTransform {
99
114
  * W73's own: `transform-passes` with the sample's source and arity where every evaluation's result
100
115
  * is accepted by the consumer's `inputSchema`, `transform-fails` with the finding where one is not,
101
116
  * and the transform run once per ELEMENT where the arc is a map's item. Pass `null` to ask what the
102
- * arcs say with NO transform, which is where an author starts.
117
+ * arcs say with NO transform, which is where an author starts — on the ARCS: with a given `input` and
118
+ * `null` there is nothing to run, the one verdict is `unchecked`, and holding that value to the node's
119
+ * `inputSchema` is `findings(schema, value)`'s question (W166's conformity reader, F3).
120
+ *
121
+ * **Given an `input`** (`options.input`, v0.38, [W166](../../doc/work-items/w166-a-sample-the-caller-gives.md)),
122
+ * the candidate goes on the same copy and is run ONCE on that value by `givenVerdict`, the arcs' own
123
+ * evaluation: ONE verdict, shape `given`, NO `producer`, `sample.source: 'given'` — never `'example'` or
124
+ * `'witness'` — the result held to the node's worker `inputSchema` and a compile or evaluation error
125
+ * `transform-fails`, as on an arc. The entry node gets one too. With `null` there is nothing to run the
126
+ * value through, and the one verdict is `unchecked`.
103
127
  *
104
128
  * The flow is never mutated. A node id that names no task returns `[]` — an authoring tool reports,
105
- * and there is nothing to report about a node with no arcs into it.
129
+ * and there is nothing to report about a node with no arcs into it and no input given.
106
130
  */
107
- export declare function tryTransform(registry: WiringRegistry, flow: FlowDefinition, nodeId: string, transform: CandidateTransform | null, options?: WiringOptions): Promise<WiringVerdict[]>;
131
+ export declare function tryTransform(registry: WiringRegistry, flow: FlowDefinition, nodeId: string, transform: CandidateTransform | null, options?: TryTransformOptions): Promise<WiringVerdict[]>;
108
132
  /**
109
133
  * **A schema INFERRED from ONE value** — its TYPE SHAPE in ADR 0053's subset: the types it carries, the
110
134
  * keys it had, and nothing about its values. Evidence about one input and never a declaration, which is