@workflow/core 5.0.0-beta.39 → 5.0.0-beta.40

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 (95) hide show
  1. package/dist/classify-error.d.ts.map +1 -1
  2. package/dist/classify-error.js +5 -2
  3. package/dist/correlation-id.d.ts +109 -0
  4. package/dist/correlation-id.d.ts.map +1 -0
  5. package/dist/correlation-id.js +139 -0
  6. package/dist/describe-error.d.ts.map +1 -1
  7. package/dist/describe-error.js +14 -1
  8. package/dist/events-consumer.d.ts +1 -0
  9. package/dist/events-consumer.d.ts.map +1 -1
  10. package/dist/events-consumer.js +11 -3
  11. package/dist/private.d.ts +17 -1
  12. package/dist/private.d.ts.map +1 -1
  13. package/dist/private.js +1 -1
  14. package/dist/runtime/constants.d.ts +19 -0
  15. package/dist/runtime/constants.d.ts.map +1 -1
  16. package/dist/runtime/constants.js +30 -1
  17. package/dist/runtime/deployment-guard.d.ts +99 -0
  18. package/dist/runtime/deployment-guard.d.ts.map +1 -0
  19. package/dist/runtime/deployment-guard.js +154 -0
  20. package/dist/runtime/quickjs-assets.generated.d.ts +14 -0
  21. package/dist/runtime/quickjs-assets.generated.d.ts.map +1 -0
  22. package/dist/runtime/quickjs-assets.generated.js +30 -0
  23. package/dist/runtime/quickjs-entrypoint.d.ts +124 -0
  24. package/dist/runtime/quickjs-entrypoint.d.ts.map +1 -0
  25. package/dist/runtime/quickjs-entrypoint.js +1429 -0
  26. package/dist/runtime/quickjs-runtime.d.ts +193 -0
  27. package/dist/runtime/quickjs-runtime.d.ts.map +1 -0
  28. package/dist/runtime/quickjs-runtime.js +1944 -0
  29. package/dist/runtime/run.d.ts +2 -0
  30. package/dist/runtime/run.d.ts.map +1 -1
  31. package/dist/runtime/run.js +9 -4
  32. package/dist/runtime/runs.d.ts +18 -1
  33. package/dist/runtime/runs.d.ts.map +1 -1
  34. package/dist/runtime/runs.js +96 -2
  35. package/dist/runtime/start.d.ts.map +1 -1
  36. package/dist/runtime/start.js +9 -1
  37. package/dist/runtime/suspension-handler.d.ts +7 -0
  38. package/dist/runtime/suspension-handler.d.ts.map +1 -1
  39. package/dist/runtime/suspension-handler.js +29 -2
  40. package/dist/runtime/vm-mode.d.ts +44 -0
  41. package/dist/runtime/vm-mode.d.ts.map +1 -0
  42. package/dist/runtime/vm-mode.js +62 -0
  43. package/dist/runtime/vm-serde-bundle.generated.d.ts +14 -0
  44. package/dist/runtime/vm-serde-bundle.generated.d.ts.map +1 -0
  45. package/dist/runtime/vm-serde-bundle.generated.js +16 -0
  46. package/dist/runtime.d.ts +1 -1
  47. package/dist/runtime.d.ts.map +1 -1
  48. package/dist/runtime.js +484 -47
  49. package/dist/serialization/codec-devalue-vm.d.ts +9 -0
  50. package/dist/serialization/codec-devalue-vm.d.ts.map +1 -0
  51. package/dist/serialization/codec-devalue-vm.js +137 -0
  52. package/dist/serialization/reducers/class-vm.d.ts +20 -0
  53. package/dist/serialization/reducers/class-vm.d.ts.map +1 -0
  54. package/dist/serialization/reducers/class-vm.js +77 -0
  55. package/dist/serialization/reducers/common-vm.d.ts +15 -0
  56. package/dist/serialization/reducers/common-vm.d.ts.map +1 -0
  57. package/dist/serialization/reducers/common-vm.js +579 -0
  58. package/dist/serialization/reducers/common.d.ts.map +1 -1
  59. package/dist/serialization/reducers/common.js +28 -6
  60. package/dist/serialization/reducers/step-function-vm.d.ts +44 -0
  61. package/dist/serialization/reducers/step-function-vm.d.ts.map +1 -0
  62. package/dist/serialization/reducers/step-function-vm.js +97 -0
  63. package/dist/serialization/vm-bundle-entry.d.ts +12 -0
  64. package/dist/serialization/vm-bundle-entry.d.ts.map +1 -0
  65. package/dist/serialization/vm-bundle-entry.js +58 -0
  66. package/dist/serialization/workflow-vm.d.ts +24 -0
  67. package/dist/serialization/workflow-vm.d.ts.map +1 -0
  68. package/dist/serialization/workflow-vm.js +66 -0
  69. package/dist/serialization.d.ts +2 -1
  70. package/dist/serialization.d.ts.map +1 -1
  71. package/dist/serialization.js +26 -21
  72. package/dist/source-map.d.ts +20 -0
  73. package/dist/source-map.d.ts.map +1 -1
  74. package/dist/source-map.js +47 -1
  75. package/dist/step.d.ts.map +1 -1
  76. package/dist/step.js +7 -2
  77. package/dist/telemetry/semantic-conventions.d.ts +78 -0
  78. package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
  79. package/dist/telemetry/semantic-conventions.js +56 -1
  80. package/dist/telemetry.d.ts +5 -0
  81. package/dist/telemetry.d.ts.map +1 -1
  82. package/dist/telemetry.js +13 -13
  83. package/dist/version.d.ts +1 -1
  84. package/dist/version.js +2 -2
  85. package/dist/workflow/abort-controller.d.ts.map +1 -1
  86. package/dist/workflow/abort-controller.js +6 -4
  87. package/dist/workflow/attribute-dispatcher.js +2 -2
  88. package/dist/workflow/hook.js +2 -2
  89. package/dist/workflow/sleep.js +2 -2
  90. package/dist/workflow.d.ts +49 -2
  91. package/dist/workflow.d.ts.map +1 -1
  92. package/dist/workflow.js +723 -569
  93. package/docs/api-reference/create-hook.mdx +1 -1
  94. package/docs/foundations/starting-workflows.mdx +74 -1
  95. package/package.json +8 -7
@@ -272,6 +272,23 @@ export function isTurboEnabled() {
272
272
  return true;
273
273
  return !(raw === '0' || raw.toLowerCase() === 'false');
274
274
  }
275
+ /**
276
+ * Whether the inline loop retains a suspended workflow VM across inline steps
277
+ * within one invocation (default ON). When on, a step-only suspension keeps
278
+ * the live VM, event consumer, and hydrated state alive, and the next loop
279
+ * iteration appends only the newly durable events instead of rebuilding the
280
+ * `vm.Context` and replaying the whole event log. Non-step suspensions and
281
+ * replay divergence always fall back to the ordinary durable replay path.
282
+ *
283
+ * `WORKFLOW_RETAINED_VM=0` (or `false`) is the kill switch: every iteration
284
+ * replays from scratch in a fresh VM, matching the pre-retention behavior.
285
+ */
286
+ export function isVmRetentionEnabled() {
287
+ const raw = process.env.WORKFLOW_RETAINED_VM;
288
+ if (raw === undefined || raw === '')
289
+ return true;
290
+ return !(raw === '0' || raw.toLowerCase() === 'false');
291
+ }
275
292
  /**
276
293
  * Whether inline step ownership is enabled (default ON). When on, the lazy
277
294
  * `step_started` that creates an inline step records the owning queue
@@ -385,4 +402,16 @@ export const PRECONDITION_REINVOKE_DELAY_SECONDS = 2;
385
402
  export function getPreconditionReinvokeDelaySeconds() {
386
403
  return envNumber('WORKFLOW_PRECONDITION_REINVOKE_DELAY_SECONDS', PRECONDITION_REINVOKE_DELAY_SECONDS, { integer: true });
387
404
  }
388
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvY29uc3RhbnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM1QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRTdDLDRFQUE0RTtBQUM1RSw0RUFBNEU7QUFDNUUseUVBQXlFO0FBQ3pFLG9EQUFvRDtBQUNwRCxFQUFFO0FBQ0YsK0VBQStFO0FBQy9FLHNEQUFzRDtBQUN0RCwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLDhFQUE4RTtBQUM5RSx5RUFBeUU7QUFDekUsK0VBQStFO0FBQy9FLDZFQUE2RTtBQUM3RSwrRUFBK0U7QUFDL0UsZ0ZBQWdGO0FBQ2hGLDJFQUEyRTtBQUMzRSwyRUFBMkU7QUFDM0Usc0JBQXNCO0FBQ3RCLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLEVBQUUsQ0FBQztBQUV2Qzs7R0FFRztBQUNILE1BQU0sVUFBVSxxQkFBcUI7SUFDbkMsd0VBQXdFO0lBQ3hFLDBFQUEwRTtJQUMxRSw4RUFBOEU7SUFDOUUseUVBQXlFO0lBQ3pFLDRFQUE0RTtJQUM1RSxPQUFPLFNBQVMsQ0FBQywrQkFBK0IsRUFBRSxvQkFBb0IsRUFBRTtRQUN0RSxPQUFPLEVBQUUsSUFBSTtRQUNiLEdBQUcsRUFBRSxDQUFDO1FBQ04sR0FBRyxFQUFFLG9CQUFvQjtLQUMxQixDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUNILE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLE9BQU8sQ0FBQztBQUV6QywyREFBMkQ7QUFDM0QsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQUcsTUFBTSxDQUFDO0FBRTVDOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxPQUFPLENBQUM7QUFFN0MsMkVBQTJFO0FBQzNFLDJFQUEyRTtBQUMzRSxNQUFNLHlCQUF5QixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7QUFFcEQsU0FBUyxRQUFRLENBQ2YsR0FBVyxFQUNYLE9BQWUsRUFDZixJQUE2QjtJQUU3QixJQUFJLHlCQUF5QixDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7UUFBRSxPQUFPO0lBQy9DLHlCQUF5QixDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNuQyxhQUFhLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztBQUNwQyxDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFVBQVUsa0JBQWtCO0lBQ2hDLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsMEJBQTBCLENBQUM7SUFDbkQsSUFBSSxDQUFDLEdBQUc7UUFBRSxPQUFPLGlCQUFpQixDQUFDO0lBQ25DLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMzQixJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDNUMsUUFBUSxDQUNOLEdBQUcsRUFDSCxrRkFBa0YsRUFDbEYsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLGlCQUFpQixFQUFFLENBQ3RDLENBQUM7UUFDRixPQUFPLGlCQUFpQixDQUFDO0lBQzNCLENBQUM7SUFDRCxJQUFJLE1BQU0sR0FBRyxxQkFBcUIsRUFBRSxDQUFDO1FBQ25DLFFBQVEsQ0FBQyxHQUFHLEVBQUUsbURBQW1ELEVBQUU7WUFDakUsR0FBRztZQUNILFNBQVMsRUFBRSxxQkFBcUI7WUFDaEMsS0FBSyxFQUFFLHFCQUFxQjtTQUM3QixDQUFDLENBQUM7UUFDSCxPQUFPLHFCQUFxQixDQUFDO0lBQy9CLENBQUM7SUFDRCxJQUFJLE1BQU0sR0FBRyxxQkFBcUIsRUFBRSxDQUFDO1FBQ25DLFFBQVEsQ0FBQyxHQUFHLEVBQUUsbURBQW1ELEVBQUU7WUFDakUsR0FBRztZQUNILFNBQVMsRUFBRSxxQkFBcUI7WUFDaEMsS0FBSyxFQUFFLHFCQUFxQjtTQUM3QixDQUFDLENBQUM7UUFDSCxPQUFPLHFCQUFxQixDQUFDO0lBQy9CLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsb0NBQW9DO0lBQ2xELHlCQUF5QixDQUFDLEtBQUssRUFBRSxDQUFDO0FBQ3BDLENBQUM7QUFFRCw4RUFBOEU7QUFDOUUseUVBQXlFO0FBQ3pFLDZFQUE2RTtBQUM3RSxtREFBbUQ7QUFDbkQsTUFBTSxDQUFDLE1BQU0sMEJBQTBCLEdBQUcsQ0FBQyxDQUFDO0FBRTVDOzs7R0FHRztBQUNILE1BQU0sVUFBVSwwQkFBMEI7SUFDeEMsT0FBTyxTQUFTLENBQ2QscUNBQXFDLEVBQ3JDLDBCQUEwQixFQUMxQixFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FDbEIsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO0FBRWxDLDhFQUE4RTtBQUM5RSxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLENBQUM7QUFFdEM7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQUcsRUFBRSxDQUFDO0FBRXZDLHlFQUF5RTtBQUN6RSxNQUFNLDBCQUEwQixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7QUFFckQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxpQkFBaUI7SUFDL0IsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsQ0FBQztJQUNsRCxJQUFJLENBQUMsR0FBRztRQUFFLE9BQU8sZ0JBQWdCLENBQUM7SUFDbEMsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzNCLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUM3QyxJQUFJLENBQUMsMEJBQTBCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDekMsMEJBQTBCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3BDLGFBQWEsQ0FBQyxJQUFJLENBQ2hCLDJFQUEyRSxFQUMzRSxFQUFFLEdBQUcsRUFBRSxZQUFZLEVBQUUsZ0JBQWdCLEVBQUUsQ0FDeEMsQ0FBQztRQUNKLENBQUM7UUFDRCxPQUFPLGdCQUFnQixDQUFDO0lBQzFCLENBQUM7SUFDRCxJQUFJLE1BQU0sR0FBRyxvQkFBb0I7UUFBRSxPQUFPLG9CQUFvQixDQUFDO0lBQy9ELElBQUksTUFBTSxHQUFHLG9CQUFvQixFQUFFLENBQUM7UUFDbEMsSUFBSSxDQUFDLDBCQUEwQixDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3pDLDBCQUEwQixDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNwQyxhQUFhLENBQUMsSUFBSSxDQUFDLGtEQUFrRCxFQUFFO2dCQUNyRSxHQUFHO2dCQUNILFlBQVksRUFBRSxvQkFBb0I7Z0JBQ2xDLFFBQVEsRUFBRSxvQkFBb0I7YUFDL0IsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUNELE9BQU8sb0JBQW9CLENBQUM7SUFDOUIsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRCxNQUFNLHFCQUFxQixHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7QUFFaEQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQjtJQUNsQyxNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLDRCQUE0QixDQUFDO0lBQ3JELElBQUksQ0FBQyxHQUFHO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFDM0IsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzNCLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUM3QyxJQUFJLENBQUMscUJBQXFCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDcEMscUJBQXFCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQy9CLGFBQWEsQ0FBQyxJQUFJLENBQ2hCLG1GQUFtRixFQUNuRixFQUFFLEdBQUcsRUFBRSxDQUNSLENBQUM7UUFDSixDQUFDO1FBQ0QsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFDSCxNQUFNLFVBQVUsOEJBQThCO0lBQzVDLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0NBQWdDLENBQUM7SUFDekQsSUFBSSxHQUFHLEtBQUssU0FBUyxJQUFJLEdBQUcsS0FBSyxFQUFFO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDbEQsT0FBTyxHQUFHLEtBQUssR0FBRyxJQUFJLEdBQUcsQ0FBQyxXQUFXLEVBQUUsS0FBSyxNQUFNLENBQUM7QUFDckQsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxVQUFVLHlDQUF5QztJQUN2RCxNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGdDQUFnQyxDQUFDO0lBQ3pELElBQUksR0FBRyxLQUFLLFNBQVMsSUFBSSxHQUFHLEtBQUssRUFBRTtRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ2xELE9BQU8sR0FBRyxLQUFLLEdBQUcsSUFBSSxHQUFHLENBQUMsV0FBVyxFQUFFLEtBQUssT0FBTyxDQUFDO0FBQ3RELENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUNILE1BQU0sVUFBVSxjQUFjO0lBQzVCLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDO0lBQ3ZDLElBQUksR0FBRyxLQUFLLFNBQVMsSUFBSSxHQUFHLEtBQUssRUFBRTtRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQ2pELE9BQU8sQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHLElBQUksR0FBRyxDQUFDLFdBQVcsRUFBRSxLQUFLLE9BQU8sQ0FBQyxDQUFDO0FBQ3pELENBQUM7QUFFRDs7Ozs7Ozs7Ozs7R0FXRztBQUNILE1BQU0sVUFBVSx3QkFBd0I7SUFDdEMsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsQ0FBQztJQUNsRCxJQUFJLEdBQUcsS0FBSyxTQUFTLElBQUksR0FBRyxLQUFLLEVBQUU7UUFBRSxPQUFPLElBQUksQ0FBQztJQUNqRCxPQUFPLENBQUMsQ0FBQyxHQUFHLEtBQUssR0FBRyxJQUFJLEdBQUcsQ0FBQyxXQUFXLEVBQUUsS0FBSyxPQUFPLENBQUMsQ0FBQztBQUN6RCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMEJHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sOEJBQThCLEdBQUcsR0FBRyxDQUFDO0FBRWxEOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxrQ0FBa0MsR0FBRyxHQUFHLENBQUM7QUFFdEQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsOEJBQThCO0lBQzVDLE9BQU8sU0FBUyxDQUNkLHlDQUF5QyxFQUN6Qyw4QkFBOEIsRUFDOUIsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLGtDQUFrQyxFQUFFLENBQ25FLENBQUM7QUFDSixDQUFDO0FBRUQsMkVBQTJFO0FBQzNFLDJFQUEyRTtBQUMzRSxxRUFBcUU7QUFDckUsTUFBTSxDQUFDLE1BQU0sNkJBQTZCLEdBQUcsQ0FBQyxDQUFDO0FBRS9DOzs7R0FHRztBQUNILE1BQU0sVUFBVSw2QkFBNkI7SUFDM0MsT0FBTyxTQUFTLENBQ2Qsd0NBQXdDLEVBQ3hDLDZCQUE2QixFQUM3QixFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FDbEIsQ0FBQztBQUNKLENBQUM7QUFFRCwrRUFBK0U7QUFDL0UsMkVBQTJFO0FBQzNFLDJFQUEyRTtBQUMzRSxnRkFBZ0Y7QUFDaEYsZ0ZBQWdGO0FBQ2hGLHVDQUF1QztBQUN2QyxNQUFNLENBQUMsTUFBTSxtQ0FBbUMsR0FBRyxDQUFDLENBQUM7QUFFckQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLG1DQUFtQztJQUNqRCxPQUFPLFNBQVMsQ0FDZCw4Q0FBOEMsRUFDOUMsbUNBQW1DLEVBQ25DLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUNsQixDQUFDO0FBQ0osQ0FBQztBQUVELDBFQUEwRTtBQUMxRSxnRkFBZ0Y7QUFDaEYsNkVBQTZFO0FBQzdFLCtFQUErRTtBQUMvRSw0RUFBNEU7QUFDNUUsb0VBQW9FO0FBQ3BFLCtEQUErRDtBQUMvRCxNQUFNLENBQUMsTUFBTSw4QkFBOEIsR0FBRyxDQUFDLENBQUM7QUFFaEQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLCtCQUErQjtJQUM3QyxPQUFPLFNBQVMsQ0FDZCx5Q0FBeUMsRUFDekMsOEJBQThCLEVBQzlCLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUNsQixDQUFDO0FBQ0osQ0FBQztBQUVELDZFQUE2RTtBQUM3RSw0RUFBNEU7QUFDNUUsK0VBQStFO0FBQy9FLDJFQUEyRTtBQUMzRSxNQUFNLENBQUMsTUFBTSxtQ0FBbUMsR0FBRyxDQUFDLENBQUM7QUFFckQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLG1DQUFtQztJQUNqRCxPQUFPLFNBQVMsQ0FDZCw4Q0FBOEMsRUFDOUMsbUNBQW1DLEVBQ25DLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUNsQixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGVudk51bWJlciB9IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQgeyBydW50aW1lTG9nZ2VyIH0gZnJvbSAnLi4vbG9nZ2VyLmpzJztcblxuLy8gTWF4aW11bSBudW1iZXIgb2YgcXVldWUgZGVsaXZlcnkgYXR0ZW1wdHMgYmVmb3JlIHRoZSBoYW5kbGVyIGdpdmVzIHVwIGFuZFxuLy8gZ3JhY2VmdWxseSBmYWlscyB0aGUgcnVuL3N0ZXAuIFRoaXMgbXVzdCBiZSBib3VuZGVkIHVuZGVyIHRoZSBWUVMgbWVzc2FnZVxuLy8gbWF4IHZpc2liaWxpdHkgd2luZG93ICgyNCBob3Vycykgc28gdGhhdCBvdXIgaGFuZGxlci1zaWRlIGZhaWx1cmUgcGF0aFxuLy8gcmVsaWFibHkgZXhlY3V0ZXMgYmVmb3JlIFZRUyBleHBpcmVzIHRoZSBtZXNzYWdlLlxuLy9cbi8vIFRoZSBlZmZlY3RpdmUgd2FsbC1jbG9jayBzdXJ2aXZhbCBkZXBlbmRzIG9uIHRoZSBwZXItcmVkZWxpdmVyeSBiYWNrb2ZmOiB0aGVcbi8vIGByZXRyeS1hZnRlcmAgdGhlIGhhbmRsZXIgcmV0dXJucyAoc2VlIHdvcmxkLXZlcmNlbFxuLy8gYGdldEhhbmRsZXJFcnJvclJldHJ5QWZ0ZXJTZWNvbmRzYCkgZmVkIHRocm91Z2ggVlFTIGBjYWxjdWxhdGVCYWNrb2ZmRGVsYXlgLlxuLy8gVlFTIHVzZXMgb3VyIHZhbHVlIGZvciB0aGUgZmlyc3QgMzIgYXR0ZW1wdHMgKGNsYW1wZWQgdG8gWzVzLCA5MDBzXSkgdGhlblxuLy8gYXBwbGllcyBpdHMgb3duIGV4cG9uZW50aWFsIGdyb3d0aCDigJQgZXZlcnkgaG9wIGhhcmQtY2FwcGVkIGF0IHRoZSBTUVMgbGltaXRcbi8vIG9mIDkwMHMuIFdpdGggdGhlIGJhY2tvZmYgcmFtcGluZyB0b3dhcmQgdGhhdCA5MDBzIGNlaWxpbmcgKHJlYWNoZWQgYnlcbi8vIH5kZWxpdmVyeSAxMSksIDQ4IGF0dGVtcHRzIHNwYW4gcm91Z2hseSA54oCTMTAgaG91cnMgb2Ygd2FsbC1jbG9jayAofjM1LDAwMHMpLFxuLy8gY29tZm9ydGFibHkgdW5kZXIgdGhlIDI0LWhvdXIgbWVzc2FnZS12aXNpYmlsaXR5IGxpbWl0IHNvIHRoZSBmYWlsdXJlIHBhdGhcbi8vIHJ1bnMgYmVmb3JlIHRoZSBtZXNzYWdlIGV4cGlyZXMuIChBIGZsYXR0ZXIsIGxvdy1jYXBwZWQgYmFja29mZiBleGhhdXN0cyB0aGVcbi8vIGJ1ZGdldCBpbiBvbmx5IGEgZmV3IGhvdXJzLCBmYWlsaW5nIG90aGVyd2lzZS1oZWFsdGh5IHJ1bnMgZHVyaW5nIGEgdHJhbnNpZW50XG4vLyBiYWNrZW5kIG91dGFnZTsgY29udmVyc2VseSwgc3Bhbm5pbmcgdGhlIGZ1bGwgMjRoIHdpbmRvdyB3b3VsZCByZXF1aXJlIGFcbi8vIHN1YnN0YW50aWFsbHkgaGlnaGVyIGNhcCBoZXJlLCBub3QgYSBoaWdoZXIgcGVyLWhvcCBjZWlsaW5nIOKAlCBWUVMgY2xhbXBzXG4vLyBldmVyeSBob3AgYXQgOTAwcy4pXG5leHBvcnQgY29uc3QgTUFYX1FVRVVFX0RFTElWRVJJRVMgPSA0ODtcblxuLyoqXG4gKiBFZmZlY3RpdmUgbWF4IHF1ZXVlIGRlbGl2ZXJpZXMuIE92ZXJyaWRlIHZpYSBgV09SS0ZMT1dfTUFYX1FVRVVFX0RFTElWRVJJRVNgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWF4UXVldWVEZWxpdmVyaWVzKCk6IG51bWJlciB7XG4gIC8vIE9ubHkgZXZlciBsb3dlciB0aGUgZGVsaXZlcnkgYnVkZ2V0LiBUaGUgZGVmYXVsdCBpcyBjYWxpYnJhdGVkIHNvIHRoZVxuICAvLyBoYW5kbGVyLXNpZGUgZmFpbHVyZSBwYXRoIHJ1bnMgYmVmb3JlIFZRUyBtZXNzYWdlLXJldGVudGlvbiBleHBpcnkgKHNlZVxuICAvLyBNQVhfUVVFVUVfREVMSVZFUklFUyBhYm92ZSk7IGEgaGlnaGVyIHZhbHVlIHdvdWxkIGJ5cGFzcyB0aGF0IGludmFyaWFudCBhbmRcbiAgLy8gbGV0IGEgYmFkIGRlcGxveW1lbnQgcmVkZWxpdmVyIHVudGlsIHF1ZXVlIGV4cGlyeSBpbnN0ZWFkIG9mIHJlY29yZGluZ1xuICAvLyBydW5fZmFpbC4gYG1heGAgY2xhbXBzIGEgdG9vLWhpZ2ggb3ZlcnJpZGUgYmFjayBkb3duIHRvIHRoZSBzYWZlIGRlZmF1bHQuXG4gIHJldHVybiBlbnZOdW1iZXIoJ1dPUktGTE9XX01BWF9RVUVVRV9ERUxJVkVSSUVTJywgTUFYX1FVRVVFX0RFTElWRVJJRVMsIHtcbiAgICBpbnRlZ2VyOiB0cnVlLFxuICAgIG1pbjogMSxcbiAgICBtYXg6IE1BWF9RVUVVRV9ERUxJVkVSSUVTLFxuICB9KTtcbn1cblxuLyoqXG4gKiBEZWZhdWx0IG1heGltdW0gdGltZSBhbGxvd2VkIGZvciB0aGUgKnJlcGxheSogcG9ydGlvbiBvZiBhIHNpbmdsZSB3b3JrZmxvd1xuICogaGFuZGxlciBpbnZvY2F0aW9uIChpbiBtcykuIFRoaXMgYnVkZ2V0IG9ubHkgY292ZXJzIGRldGVybWluaXN0aWMtcmVwbGF5XG4gKiBhbmQgd29ya2Zsb3ctVk0gZXhlY3V0aW9uIGJldHdlZW4gc3RlcCBib3VuZGFyaWVzIOKAlCBpbmxpbmUgc3RlcCBib2RpZXNcbiAqIChgXCJ1c2Ugc3RlcFwiYCBmdW5jdGlvbnMgaW52b2tlZCB2aWEgYGV4ZWN1dGVTdGVwYCkgZG8gTk9UIGNvdW50IGFnYWluc3RcbiAqIGl0LiBTdGVwIGJvZGllcyBhcmUgYm91bmRlZCBzZXBhcmF0ZWx5IGJ5IHRoZSBwbGF0Zm9ybSdzIGZ1bmN0aW9uXG4gKiBgbWF4RHVyYXRpb25gIChlLmcuIDgwMHMgb24gVmVyY2VsIFBybyBGbHVpZCkgYW5kIGBOT19JTkxJTkVfUkVQTEFZX0FGVEVSX01TYC5cbiAqXG4gKiBJZiB0aGUgbm9uLXN0ZXAgKFwicmVwbGF5XCIpIHRpbWUgd2l0aGluIGEgc2luZ2xlIGludm9jYXRpb24gZXhjZWVkcyB0aGlzXG4gKiBidWRnZXQsIHRoZSBoYW5kbGVyIGV4aXRzIHNvIHRoZSBxdWV1ZSBjYW4gcmV0cnkuIEFmdGVyXG4gKiBgUkVQTEFZX1RJTUVPVVRfTUFYX1JFVFJJRVNgIGV4aGF1c3RlZCBhdHRlbXB0cyB0aGUgcnVuIGlzIGZhaWxlZCB3aXRoXG4gKiBgUlVOX0VSUk9SX0NPREVTLlJFUExBWV9USU1FT1VUYC5cbiAqXG4gKiBOb3RlIHRoYXQgb24gVmVyY2VsIEhvYmJ5IChzdGFuZGFyZCBmdW5jdGlvbnMpLCB0aGUgcGxhdGZvcm0gYG1heER1cmF0aW9uYFxuICogaXMgNjBzIOKAlCB3ZWxsIGJlbG93IHRoaXMgYnVkZ2V0LCBzbyB0aGUgcGxhdGZvcm0gU0lHVEVSTSB3aWxsIGZpcmUgZmlyc3RcbiAqIGFuZCB0aGUgcXVldWUgd2lsbCByZS1kZWxpdmVyIHVudGlsIHRoZSB2aXNpYmlsaXR5IHdpbmRvdyBleHBpcmVzLiBXaXRoXG4gKiBGbHVpZCBDb21wdXRlIG9uIEhvYmJ5IHRoZSBwZXItZnVuY3Rpb24gY2VpbGluZyByaXNlcyB0byAzMDBzLCBzdGlsbFxuICogdW5kZXIgdGhlIGRlZmF1bHQgYnVkZ2V0LlxuICpcbiAqIE92ZXJyaWRlIHZpYSB0aGUgYFdPUktGTE9XX1JFUExBWV9USU1FT1VUX01TYCBlbnYgdmFyIChjbGFtcGVkIHRvXG4gKiBgTUlOX1JFUExBWV9USU1FT1VUX01TYC4uYE1BWF9SRVBMQVlfVElNRU9VVF9NU2ApLlxuICovXG5leHBvcnQgY29uc3QgUkVQTEFZX1RJTUVPVVRfTVMgPSAyNDBfMDAwO1xuXG4vKiogTG93ZXIgYm91bmQgZm9yIHRoZSByZXBsYXktdGltZW91dCBlbnYgdmFyIG92ZXJyaWRlLiAqL1xuZXhwb3J0IGNvbnN0IE1JTl9SRVBMQVlfVElNRU9VVF9NUyA9IDMwXzAwMDtcblxuLyoqXG4gKiBVcHBlciBib3VuZCBmb3IgdGhlIHJlcGxheS10aW1lb3V0IGVudiB2YXIgb3ZlcnJpZGUuIDc4MHMgbGVhdmVzIOKJpTIwcyBvZlxuICogaGVhZHJvb20gdW5kZXIgVmVyY2VsIFBybyBGbHVpZCdzIDgwMHMgZnVuY3Rpb24gY2VpbGluZyBzbyB0aGUgaGFuZGxlclxuICogY2FuIHdyaXRlIGBydW5fZmFpbGVkYCBiZWZvcmUgU0lHVEVSTS5cbiAqL1xuZXhwb3J0IGNvbnN0IE1BWF9SRVBMQVlfVElNRU9VVF9NUyA9IDc4MF8wMDA7XG5cbi8vIFRyYWNrIHdoaWNoIHJhdyBlbnYgdmFyIHZhbHVlcyB3ZSd2ZSBhbHJlYWR5IHdhcm5lZCBhYm91dCBzbyB0aGUgd2FybmluZ1xuLy8gbG9nIG9ubHkgZmlyZXMgb25jZSBwZXIgcHJvY2VzcyAodGhlIGZ1bmN0aW9uIG1heSBiZSBjYWxsZWQgbWFueSB0aW1lcykuXG5jb25zdCB3YXJuZWRSZXBsYXlUaW1lb3V0VmFsdWVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbmZ1bmN0aW9uIHdhcm5PbmNlKFxuICByYXc6IHN0cmluZyxcbiAgbWVzc2FnZTogc3RyaW5nLFxuICBkYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxuKTogdm9pZCB7XG4gIGlmICh3YXJuZWRSZXBsYXlUaW1lb3V0VmFsdWVzLmhhcyhyYXcpKSByZXR1cm47XG4gIHdhcm5lZFJlcGxheVRpbWVvdXRWYWx1ZXMuYWRkKHJhdyk7XG4gIHJ1bnRpbWVMb2dnZXIud2FybihtZXNzYWdlLCBkYXRhKTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIHRoZSBlZmZlY3RpdmUgcmVwbGF5LXRpbWVvdXQgYnVkZ2V0IGZvciB0aGUgY3VycmVudCBwcm9jZXNzLlxuICpcbiAqIFJlYWRzIGBwcm9jZXNzLmVudi5XT1JLRkxPV19SRVBMQVlfVElNRU9VVF9NU2AgbGF6aWx5IHNvIHRlc3RzIGFuZFxuICogZGVwbG95bWVudHMgY2FuIG92ZXJyaWRlIHBlciBpbnZvY2F0aW9uLiBJbnZhbGlkIC8gb3V0LW9mLXJhbmdlIHZhbHVlc1xuICogZmFsbCBiYWNrIHRvIGEgc2FmZSB2YWx1ZSAobm8gdGhyb3cg4oCUIHRoZSBlbnYgdmFyIGlzIGFuIGVzY2FwZSBoYXRjaCxcbiAqIG5vdCBhIGhhcmQgcmVxdWlyZW1lbnQpIGFuZCBlbWl0IGEgb25lLXRpbWUgd2FybmluZyBzbyBtaXNjb25maWd1cmF0aW9uXG4gKiBpcyBvYnNlcnZhYmxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVwbGF5VGltZW91dE1zKCk6IG51bWJlciB7XG4gIGNvbnN0IHJhdyA9IHByb2Nlc3MuZW52LldPUktGTE9XX1JFUExBWV9USU1FT1VUX01TO1xuICBpZiAoIXJhdykgcmV0dXJuIFJFUExBWV9USU1FT1VUX01TO1xuICBjb25zdCBwYXJzZWQgPSBOdW1iZXIocmF3KTtcbiAgaWYgKCFOdW1iZXIuaXNGaW5pdGUocGFyc2VkKSB8fCBwYXJzZWQgPD0gMCkge1xuICAgIHdhcm5PbmNlKFxuICAgICAgcmF3LFxuICAgICAgJ0lnbm9yaW5nIFdPUktGTE9XX1JFUExBWV9USU1FT1VUX01TOiBub3QgYSBwb3NpdGl2ZSBmaW5pdGUgbnVtYmVyOyB1c2luZyBkZWZhdWx0JyxcbiAgICAgIHsgcmF3LCBkZWZhdWx0TXM6IFJFUExBWV9USU1FT1VUX01TIH1cbiAgICApO1xuICAgIHJldHVybiBSRVBMQVlfVElNRU9VVF9NUztcbiAgfVxuICBpZiAocGFyc2VkIDwgTUlOX1JFUExBWV9USU1FT1VUX01TKSB7XG4gICAgd2Fybk9uY2UocmF3LCAnV09SS0ZMT1dfUkVQTEFZX1RJTUVPVVRfTVMgYmVsb3cgbWluaW11bTsgY2xhbXBlZCcsIHtcbiAgICAgIHJhdyxcbiAgICAgIGNsYW1wZWRNczogTUlOX1JFUExBWV9USU1FT1VUX01TLFxuICAgICAgbWluTXM6IE1JTl9SRVBMQVlfVElNRU9VVF9NUyxcbiAgICB9KTtcbiAgICByZXR1cm4gTUlOX1JFUExBWV9USU1FT1VUX01TO1xuICB9XG4gIGlmIChwYXJzZWQgPiBNQVhfUkVQTEFZX1RJTUVPVVRfTVMpIHtcbiAgICB3YXJuT25jZShyYXcsICdXT1JLRkxPV19SRVBMQVlfVElNRU9VVF9NUyBhYm92ZSBtYXhpbXVtOyBjbGFtcGVkJywge1xuICAgICAgcmF3LFxuICAgICAgY2xhbXBlZE1zOiBNQVhfUkVQTEFZX1RJTUVPVVRfTVMsXG4gICAgICBtYXhNczogTUFYX1JFUExBWV9USU1FT1VUX01TLFxuICAgIH0pO1xuICAgIHJldHVybiBNQVhfUkVQTEFZX1RJTUVPVVRfTVM7XG4gIH1cbiAgcmV0dXJuIHBhcnNlZDtcbn1cblxuLyoqXG4gKiBSZXNldCB0aGUgd2Fybi1vbmNlIGNhY2hlLiBUZXN0LW9ubHkg4oCUIGV4cG9ydGVkIHNvIHVuaXQgdGVzdHMgY2FuXG4gKiBleGVyY2lzZSB0aGUgd2FybiBwYXRoIHJlcGVhdGVkbHkgd2l0aG91dCBzaGFyaW5nIHN0YXRlLlxuICpcbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgZnVuY3Rpb24gX3Jlc2V0UmVwbGF5VGltZW91dFdhcm5DYWNoZUZvclRlc3RzKCk6IHZvaWQge1xuICB3YXJuZWRSZXBsYXlUaW1lb3V0VmFsdWVzLmNsZWFyKCk7XG59XG5cbi8vIE51bWJlciBvZiBxdWV1ZSBkZWxpdmVyeSBhdHRlbXB0cyB0byBhbGxvdyBiZWZvcmUgcGVybWFuZW50bHkgZmFpbGluZyBhIHJ1blxuLy8gZHVlIHRvIGEgcmVwbGF5IHRpbWVvdXQuIE9uIGF0dGVtcHRzIDEgdGhyb3VnaCB0aGlzIHZhbHVlLCB0aGUgdGltZW91dFxuLy8gaGFuZGxlciBleGl0cyB3aXRob3V0IHdyaXRpbmcgcnVuX2ZhaWxlZCBzbyB0aGUgcXVldWUgcmV0cmllcyB0aGUgbWVzc2FnZS5cbi8vIE9uIHRoZSBuZXh0IGF0dGVtcHQgdGhlIHJ1biBpcyBtYXJrZWQgYXMgZmFpbGVkLlxuZXhwb3J0IGNvbnN0IFJFUExBWV9USU1FT1VUX01BWF9SRVRSSUVTID0gMztcblxuLyoqXG4gKiBFZmZlY3RpdmUgcmVwbGF5LXRpbWVvdXQgcmV0cnkgYnVkZ2V0LiBPdmVycmlkZSB2aWFcbiAqIGBXT1JLRkxPV19SRVBMQVlfVElNRU9VVF9NQVhfUkVUUklFU2AuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXBsYXlUaW1lb3V0TWF4UmV0cmllcygpOiBudW1iZXIge1xuICByZXR1cm4gZW52TnVtYmVyKFxuICAgICdXT1JLRkxPV19SRVBMQVlfVElNRU9VVF9NQVhfUkVUUklFUycsXG4gICAgUkVQTEFZX1RJTUVPVVRfTUFYX1JFVFJJRVMsXG4gICAgeyBpbnRlZ2VyOiB0cnVlIH1cbiAgKTtcbn1cblxuLyoqXG4gKiBEZWZhdWx0IG1heGltdW0gbnVtYmVyIG9mIHN0ZXBzIHRoZSBvd25lZC1pbmxpbmUgcGF0aCBydW5zIGlubGluZSAoaW5cbiAqIHBhcmFsbGVsKSBwZXIgc3VzcGVuc2lvbi4gVGhlIHJlc3QgYXJlIHF1ZXVlZCB0byBiYWNrZ3JvdW5kIGhhbmRsZXJzLiBFYWNoXG4gKiBpbmxpbmUgc3RlcCBpcyBjcmVhdGVkIGxhemlseSDigJQgaXRzIGBzdGVwX2NyZWF0ZWRgIGlzIGZvbGRlZCBpbnRvIHRoZVxuICogYHN0ZXBfc3RhcnRlZGAgdGhhdCBgZXhlY3V0ZVN0ZXBgIHNlbmRzIOKAlCBzbyBpbmxpbmluZyBOIHN0ZXBzIHNhdmVzIE4gcXVldWVcbiAqIHJvdW5kLXRyaXBzIGZvciBhIGBQcm9taXNlLmFsbGAtc3R5bGUgZmFuLW91dC4gYDFgIHJlcHJvZHVjZXMgdGhlXG4gKiBzaW5nbGUtaW5saW5lLXN0ZXAgYmVoYXZpb3IgZXhhY3RseSAodXNlZnVsIGtpbGwtc3dpdGNoKS5cbiAqXG4gKiBPdmVycmlkZSB2aWEgYFdPUktGTE9XX01BWF9JTkxJTkVfU1RFUFNgIChjbGFtcGVkIHRvXG4gKiBgTUlOX01BWF9JTkxJTkVfU1RFUFNgLi5gTUFYX01BWF9JTkxJTkVfU1RFUFNgKS5cbiAqL1xuZXhwb3J0IGNvbnN0IE1BWF9JTkxJTkVfU1RFUFMgPSAzO1xuXG4vKiogTG93ZXIgYm91bmQgZm9yIHRoZSBpbmxpbmUtc3RlcHMgZW52IG92ZXJyaWRlICgxID0gc2luZ2xlIGlubGluZSBzdGVwKS4gKi9cbmV4cG9ydCBjb25zdCBNSU5fTUFYX0lOTElORV9TVEVQUyA9IDE7XG5cbi8qKlxuICogVXBwZXIgYm91bmQgZm9yIHRoZSBpbmxpbmUtc3RlcHMgZW52IG92ZXJyaWRlLiBJbmxpbmUgYm9kaWVzIHJ1biBpbiBwYXJhbGxlbFxuICogd2l0aGluIG9uZSBmdW5jdGlvbiBpbnZvY2F0aW9uLCBzbyB0aGlzIGNhcHMgbWVtb3J5L0NQVSBmYW4tb3V0IHBlciBoYW5kbGVyLlxuICovXG5leHBvcnQgY29uc3QgTUFYX01BWF9JTkxJTkVfU1RFUFMgPSAxNjtcblxuLy8gV2Fybi1vbmNlIGNhY2hlIGZvciBXT1JLRkxPV19NQVhfSU5MSU5FX1NURVBTLCBrZXllZCBieSByYXcgZW52IHZhbHVlLlxuY29uc3Qgd2FybmVkTWF4SW5saW5lU3RlcHNWYWx1ZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuLyoqXG4gKiBSZXNvbHZlIHRoZSBlZmZlY3RpdmUgbWF4IG51bWJlciBvZiBpbmxpbmUgc3RlcHMgZm9yIHRoZSBjdXJyZW50IHByb2Nlc3MuXG4gKlxuICogUmVhZHMgYHByb2Nlc3MuZW52LldPUktGTE9XX01BWF9JTkxJTkVfU1RFUFNgIGxhemlseSBzbyB0ZXN0cyBhbmRcbiAqIGRlcGxveW1lbnRzIGNhbiBvdmVycmlkZSBwZXIgaW52b2NhdGlvbi4gSW52YWxpZCAvIG91dC1vZi1yYW5nZSB2YWx1ZXMgZmFsbFxuICogYmFjayB0byBhIHNhZmUgdmFsdWUgKG5vIHRocm93IOKAlCB0aGUgZW52IHZhciBpcyBhbiBlc2NhcGUgaGF0Y2gpIGFuZCBlbWl0IGFcbiAqIG9uZS10aW1lIHdhcm5pbmcgc28gbWlzY29uZmlndXJhdGlvbiBpcyBvYnNlcnZhYmxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWF4SW5saW5lU3RlcHMoKTogbnVtYmVyIHtcbiAgY29uc3QgcmF3ID0gcHJvY2Vzcy5lbnYuV09SS0ZMT1dfTUFYX0lOTElORV9TVEVQUztcbiAgaWYgKCFyYXcpIHJldHVybiBNQVhfSU5MSU5FX1NURVBTO1xuICBjb25zdCBwYXJzZWQgPSBOdW1iZXIocmF3KTtcbiAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKHBhcnNlZCkgfHwgcGFyc2VkIDw9IDApIHtcbiAgICBpZiAoIXdhcm5lZE1heElubGluZVN0ZXBzVmFsdWVzLmhhcyhyYXcpKSB7XG4gICAgICB3YXJuZWRNYXhJbmxpbmVTdGVwc1ZhbHVlcy5hZGQocmF3KTtcbiAgICAgIHJ1bnRpbWVMb2dnZXIud2FybihcbiAgICAgICAgJ0lnbm9yaW5nIFdPUktGTE9XX01BWF9JTkxJTkVfU1RFUFM6IG5vdCBhIHBvc2l0aXZlIGludGVnZXI7IHVzaW5nIGRlZmF1bHQnLFxuICAgICAgICB7IHJhdywgZGVmYXVsdFZhbHVlOiBNQVhfSU5MSU5FX1NURVBTIH1cbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBNQVhfSU5MSU5FX1NURVBTO1xuICB9XG4gIGlmIChwYXJzZWQgPCBNSU5fTUFYX0lOTElORV9TVEVQUykgcmV0dXJuIE1JTl9NQVhfSU5MSU5FX1NURVBTO1xuICBpZiAocGFyc2VkID4gTUFYX01BWF9JTkxJTkVfU1RFUFMpIHtcbiAgICBpZiAoIXdhcm5lZE1heElubGluZVN0ZXBzVmFsdWVzLmhhcyhyYXcpKSB7XG4gICAgICB3YXJuZWRNYXhJbmxpbmVTdGVwc1ZhbHVlcy5hZGQocmF3KTtcbiAgICAgIHJ1bnRpbWVMb2dnZXIud2FybignV09SS0ZMT1dfTUFYX0lOTElORV9TVEVQUyBhYm92ZSBtYXhpbXVtOyBjbGFtcGVkJywge1xuICAgICAgICByYXcsXG4gICAgICAgIGNsYW1wZWRWYWx1ZTogTUFYX01BWF9JTkxJTkVfU1RFUFMsXG4gICAgICAgIG1heFZhbHVlOiBNQVhfTUFYX0lOTElORV9TVEVQUyxcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gTUFYX01BWF9JTkxJTkVfU1RFUFM7XG4gIH1cbiAgcmV0dXJuIHBhcnNlZDtcbn1cblxuY29uc3Qgd2FybmVkTWF4RXZlbnRzVmFsdWVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbi8qKlxuICogT3B0aW9uYWwgY2xpZW50LXNpZGUgb3ZlcnJpZGUgZm9yIHRoZSBzZXJ2ZXItc3VwcGxpZWQgcGVyLXJ1biBldmVudCBjZWlsaW5nLlxuICogV2hlbiBzZXQgdG8gYSBwb3NpdGl2ZSBpbnRlZ2VyLCB0aGUgcnVudGltZSBjbGFtcHMgdGhlIHNlcnZlcidzIGxpbWl0ICpkb3duKlxuICogdG8gdGhpcyB2YWx1ZSAobmV2ZXIgcmFpc2VzIGl0KSBzbyBlbmZvcmNlbWVudCBjYW4gYmUgZXhlcmNpc2VkIHdpdGhvdXQgYVxuICogc2VydmVyLXNpZGUgY2hhbmdlLiBgdW5kZWZpbmVkYCAodW5zZXQpIOKHkiB1c2UgdGhlIHNlcnZlciB2YWx1ZSBhcy1pcy5cbiAqXG4gKiBSZWFkcyBgcHJvY2Vzcy5lbnYuV09SS0ZMT1dfTUFYX0VWRU5UU19PVkVSUklERWAgbGF6aWx5IHNvIHRlc3RzIGFuZFxuICogZGVwbG95bWVudHMgY2FuIG92ZXJyaWRlIHBlciBpbnZvY2F0aW9uLiBJbnZhbGlkIHZhbHVlcyBmYWxsIGJhY2sgdG8gdW5zZXRcbiAqIChubyB0aHJvdyDigJQgdGhlIGVudiB2YXIgaXMgYW4gZXNjYXBlIGhhdGNoKSBhbmQgZW1pdCBhIG9uZS10aW1lIHdhcm5pbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRNYXhFdmVudHNPdmVycmlkZSgpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICBjb25zdCByYXcgPSBwcm9jZXNzLmVudi5XT1JLRkxPV19NQVhfRVZFTlRTX09WRVJSSURFO1xuICBpZiAoIXJhdykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgcGFyc2VkID0gTnVtYmVyKHJhdyk7XG4gIGlmICghTnVtYmVyLmlzSW50ZWdlcihwYXJzZWQpIHx8IHBhcnNlZCA8PSAwKSB7XG4gICAgaWYgKCF3YXJuZWRNYXhFdmVudHNWYWx1ZXMuaGFzKHJhdykpIHtcbiAgICAgIHdhcm5lZE1heEV2ZW50c1ZhbHVlcy5hZGQocmF3KTtcbiAgICAgIHJ1bnRpbWVMb2dnZXIud2FybihcbiAgICAgICAgJ0lnbm9yaW5nIFdPUktGTE9XX01BWF9FVkVOVFNfT1ZFUlJJREU6IG5vdCBhIHBvc2l0aXZlIGludGVnZXI7IHVzaW5nIHNlcnZlciBsaW1pdCcsXG4gICAgICAgIHsgcmF3IH1cbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgcmV0dXJuIHBhcnNlZDtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIG9wdGltaXN0aWMgaW5saW5lIHN0ZXAgc3RhcnQgaXMgZW5hYmxlZC4gV2hlbiBvbiwgdGhlIG93bmVkLWlubGluZVxuICogcGF0aCBiZWdpbnMgcnVubmluZyBhIGJyYW5kLW5ldyBzdGVwJ3MgYm9keSAqYmVmb3JlKiBpdHMgbGF6eSBgc3RlcF9zdGFydGVkYFxuICogbmV0d29yayBjYWxsIHJlc29sdmVzICh0aGUgaW5wdXQgaXMgYWxyZWFkeSBrbm93biBsb2NhbGx5KSwgYXdhaXRpbmcgdGhlXG4gKiBgc3RlcF9zdGFydGVkYCBvbmx5IGJlZm9yZSB0aGUgdGVybWluYWwgd3JpdGUuXG4gKlxuICogVGhpcyBjYW4gcnVuIGEgc3RlcCBib2R5IG1vcmUgdGhhbiBvbmNlIHdoZW4gaGFuZGxlcnMgcmFjZSBmb3IgdGhlIHNhbWVcbiAqIHN0ZXAncyBjcmVhdGUtY2xhaW0g4oCUIGJvdGggcnVuIHRoZSBib2R5IGJlZm9yZSBvbmUgd2lucy4gVGhhdCBpcyB1bnNhZmUgZm9yXG4gKiBzdGVwcyB3aXRoIG5vbi1pZGVtcG90ZW50IHNpZGUgZWZmZWN0czsgaW4gcGFydGljdWxhciwgdHdvIGNvbmN1cnJlbnQgcnVuc1xuICogb2YgYSBzdGVwIHRoYXQgd3JpdGVzIHRvIHRoZSB3b3JrZmxvdyBzdHJlYW0gKGUuZy4gYW4gQUkgYWdlbnQgc3RyZWFtaW5nXG4gKiB0b2tlbnMpIGNhbiBpbnRlcmxlYXZlIGFuZCBjb3JydXB0IHRoZSBzdHJlYW0gZGF0YS4gU28gdGhlIG9wdGltaXphdGlvbiBpc1xuICogKipvZmYgYnkgZGVmYXVsdCoqIGFuZCBtdXN0IGJlIGV4cGxpY2l0bHkgb3B0ZWQgaW50byBwZXIgZGVwbG95bWVudC5cbiAqXG4gKiBSZWFkcyBgcHJvY2Vzcy5lbnYuV09SS0ZMT1dfT1BUSU1JU1RJQ19JTkxJTkVfU1RBUlRgIGxhemlseS4gRGVmYXVsdCBPRkY7XG4gKiBlbmFibGVkIG9ubHkgYnkgYW4gZXhwbGljaXQgYCcxJ2AgLyBgJ3RydWUnYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT3B0aW1pc3RpY0lubGluZVN0YXJ0RW5hYmxlZCgpOiBib29sZWFuIHtcbiAgY29uc3QgcmF3ID0gcHJvY2Vzcy5lbnYuV09SS0ZMT1dfT1BUSU1JU1RJQ19JTkxJTkVfU1RBUlQ7XG4gIGlmIChyYXcgPT09IHVuZGVmaW5lZCB8fCByYXcgPT09ICcnKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiByYXcgPT09ICcxJyB8fCByYXcudG9Mb3dlckNhc2UoKSA9PT0gJ3RydWUnO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgYW4gb3BlcmF0b3IgaGFzICoqZXhwbGljaXRseSBkaXNhYmxlZCoqIG9wdGltaXN0aWMgaW5saW5lIHN0YXJ0IHZpYVxuICogYFdPUktGTE9XX09QVElNSVNUSUNfSU5MSU5FX1NUQVJUPTBgIC8gYD1mYWxzZWAuIERpc3RpbmN0IGZyb20gXCJ1bnNldFwiOiB1bnNldFxuICogbGVhdmVzIHRoZSBvcHRpbWl6YXRpb24gb2ZmIGJ5IGRlZmF1bHQgYnV0IGxldHMgdHVyYm8gZm9yY2UgaXQgb247IGFuIGV4cGxpY2l0XG4gKiBgMGAvYGZhbHNlYCBpcyBhbiBvcGVyYXRvciBvcHQtb3V0IHRoYXQgdHVyYm8gbXVzdCBob25vciAodHVyYm8ncyBmb3JjZWRcbiAqIG9wdGltaXN0aWMgc3RhcnQgc3RpbGwgcnVucyBhIHN0ZXAgYm9keSBiZWZvcmUgYHN0ZXBfc3RhcnRlZGAvYHJ1bl9zdGFydGVkYCBpc1xuICogY29uZmlybWVkLCB0aGUgcHJvcGVydHkgc3VjaCBhbiBvcGVyYXRvciBpcyBvcHRpbmcgb3V0IG9mKSwgc29cbiAqIGBmb3JjZU9wdGltaXN0aWNTdGFydGAgZGVmZXJzIHRvIHRoaXMuIFJlYWRzIHRoZSBlbnYgdmFyIGxhemlseS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT3B0aW1pc3RpY0lubGluZVN0YXJ0RXhwbGljaXRseURpc2FibGVkKCk6IGJvb2xlYW4ge1xuICBjb25zdCByYXcgPSBwcm9jZXNzLmVudi5XT1JLRkxPV19PUFRJTUlTVElDX0lOTElORV9TVEFSVDtcbiAgaWYgKHJhdyA9PT0gdW5kZWZpbmVkIHx8IHJhdyA9PT0gJycpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIHJhdyA9PT0gJzAnIHx8IHJhdy50b0xvd2VyQ2FzZSgpID09PSAnZmFsc2UnO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgXCJ0dXJibyBtb2RlXCIgaXMgZW5hYmxlZC4gVHVyYm8gbW9kZSBmYXN0LXBhdGhzIHRoZSAqZmlyc3QgZGVsaXZlcnkgb2ZcbiAqIHRoZSBmaXJzdCBpbnZvY2F0aW9uKiBvZiBhIHJ1biAoZGV0ZWN0ZWQgYnkgdGhlIGVudHJ5cG9pbnQgdmlhIGBydW5JbnB1dGBcbiAqIHByZXNlbmNlICsgYG1ldGFkYXRhLmF0dGVtcHQgPT09IDFgKTogaXQgYmFja2dyb3VuZHMgdGhlIGBydW5fc3RhcnRlZGAgZXZlbnRcbiAqIGNyZWF0aW9uLCBza2lwcyB0aGUgaW5pdGlhbCBldmVudC1sb2cgbG9hZCAobm90aGluZyBoYXMgYmVlbiB3cml0dGVuIHlldCksXG4gKiBhbmQgZm9yY2VzIG9wdGltaXN0aWMgaW5saW5lIHN0ZXAgc3RhcnQgZm9yIHRoYXQgaW52b2NhdGlvbiDigJQgaW5kZXBlbmRlbnQgb2ZcbiAqIGBXT1JLRkxPV19PUFRJTUlTVElDX0lOTElORV9TVEFSVGAuXG4gKlxuICogRm9yY2luZyBvcHRpbWlzdGljIHN0YXJ0IGlzIHNhZmUgaGVyZSBiZWNhdXNlIHRoZSBmaXJzdCBkZWxpdmVyeSBoYXMgbm9cbiAqIGNvbmN1cnJlbnQgcGVlciBoYW5kbGVyIHRvIHJhY2UgdGhlIHN0ZXAgY3JlYXRlLWNsYWltLCBzbyBhIHN0ZXAgYm9keSBydW5zXG4gKiBleGFjdGx5IG9uY2UuIFRoYXQgc2luZ2xlLWhhbmRsZXIgZ3VhcmFudGVlIGVuZHMgYXMgc29vbiBhcyB0aGUgcnVuIGNyZWF0ZXMgYVxuICogaG9vayBvciB3YWl0ICh3aGljaCBpbnRyb2R1Y2UgcmVzdW1lL3BhcmFsbGVsIGludm9jYXRpb25zKSwgc28gdGhlIHJ1bnRpbWVcbiAqIGV4aXRzIHR1cmJvIGF0IHRoYXQgcG9pbnQuXG4gKlxuICogUmVhZHMgYHByb2Nlc3MuZW52LldPUktGTE9XX1RVUkJPYCBsYXppbHkuIERlZmF1bHQgKipPTioqOyBkaXNhYmxlZCBvbmx5IGJ5IGFuXG4gKiBleHBsaWNpdCBgJzAnYCAvIGAnZmFsc2UnYCAoY2FzZS1pbnNlbnNpdGl2ZSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1R1cmJvRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgY29uc3QgcmF3ID0gcHJvY2Vzcy5lbnYuV09SS0ZMT1dfVFVSQk87XG4gIGlmIChyYXcgPT09IHVuZGVmaW5lZCB8fCByYXcgPT09ICcnKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuICEocmF3ID09PSAnMCcgfHwgcmF3LnRvTG93ZXJDYXNlKCkgPT09ICdmYWxzZScpO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgaW5saW5lIHN0ZXAgb3duZXJzaGlwIGlzIGVuYWJsZWQgKGRlZmF1bHQgT04pLiBXaGVuIG9uLCB0aGUgbGF6eVxuICogYHN0ZXBfc3RhcnRlZGAgdGhhdCBjcmVhdGVzIGFuIGlubGluZSBzdGVwIHJlY29yZHMgdGhlIG93bmluZyBxdWV1ZVxuICogbWVzc2FnZSBJRCwgYW5kIHdha2UgcmVwbGF5cyB0aGF0IG9ic2VydmUgYW4gYWN0aXZlbHktb3duZWQgc3RlcCBlbnF1ZXVlIGFcbiAqICpkZWxheWVkIGJhY2tzdG9wKiBtZXNzYWdlIGluc3RlYWQgb2YgaW1tZWRpYXRlbHkgcmVxdWV1ZWluZyBpdCDigJQgZml4aW5nXG4gKiBkdXBsaWNhdGUgaW5saW5lIHN0ZXAgZXhlY3V0aW9uIHdoZW4gYSBob29rL3dhaXQgd2FrZXMgYSBydW4gbWlkLXN0ZXBcbiAqICh2ZXJjZWwvd29ya2Zsb3cjMjc4MCkuXG4gKlxuICogYFdPUktGTE9XX0lOTElORV9PV05FUlNISVA9MGAgKG9yIGBmYWxzZWApIGlzIHRoZSBraWxsIHN3aXRjaDogZGlzcGF0Y2hcbiAqIHJldmVydHMgdG8gdGhlIHVuY29uZGl0aW9uYWwgaW1tZWRpYXRlIHJlcXVldWUuIFN0YW1waW5nIGlzIHVuYWZmZWN0ZWQg4oCUXG4gKiB0aGUgcmVjb3JkZWQgb3duZXJNZXNzYWdlSWQgaXMgaW5lcnQgZGF0YSB3aGVuIHRoZSBzd2l0Y2ggaXMgb2ZmLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNJbmxpbmVPd25lcnNoaXBFbmFibGVkKCk6IGJvb2xlYW4ge1xuICBjb25zdCByYXcgPSBwcm9jZXNzLmVudi5XT1JLRkxPV19JTkxJTkVfT1dORVJTSElQO1xuICBpZiAocmF3ID09PSB1bmRlZmluZWQgfHwgcmF3ID09PSAnJykgcmV0dXJuIHRydWU7XG4gIHJldHVybiAhKHJhdyA9PT0gJzAnIHx8IHJhdy50b0xvd2VyQ2FzZSgpID09PSAnZmFsc2UnKTtcbn1cblxuLyoqXG4gKiBEZWZhdWx0IGlubGluZS1vd25lcnNoaXAgbGVhc2UsIGluIHNlY29uZHM6IGhvdyBsb25nIGFmdGVyIGEgc3RlcCdzIGxhdGVzdFxuICogKHN0YW1wZWQpIGBzdGVwX3N0YXJ0ZWRgIGEgbm9uLW93bmVyIGludm9jYXRpb24gYXNzdW1lcyB0aGUgb3duaW5nXG4gKiBpbnZvY2F0aW9uIG1heSBzdGlsbCBiZSBhbGl2ZS4gV2l0aGluIHRoZSBsZWFzZSwgd2FrZSByZXBsYXlzIGVucXVldWUgdGhlXG4gKiBzdGVwJ3MgYmFja3N0b3AgbWVzc2FnZSB3aXRoIGBkZWxheVNlY29uZHMgPSBsZWFzZSByZW1haW5pbmdgIGluc3RlYWQgb2ZcbiAqIGltbWVkaWF0ZWx5OyBwYXN0IGl0LCB0aGV5IGVucXVldWUgaW1tZWRpYXRlbHkgKHRvZGF5J3MgYmVoYXZpb3IpLlxuICpcbiAqIFdoeSBhIGZpeGVkIDg2MCBhbmQgbm90IGEgdmFsdWUgZGVyaXZlZCBmcm9tIHRoZSBmdW5jdGlvbidzIGBtYXhEdXJhdGlvbmA6XG4gKiBuZWl0aGVyIHJ1bnRpbWUgbm9yIGJ1aWxkIHRpbWUgY2FuIHNlZSB0aGUgcmVzb2x2ZWQgdmFsdWUg4oCUIGJ1aWxkZXJzIGVtaXRcbiAqIGBtYXhEdXJhdGlvbjogJ21heCdgLCB3aGljaCB0aGUgcGxhdGZvcm0gcmVzb2x2ZXMgcGVyLXBsYW4gYXQgZGVwbG95LCBhbmRcbiAqIG5vIGVudiB2YXIgb3IgcmVxdWVzdC1jb250ZXh0IGRlYWRsaW5lIEFQSSBleHBvc2VzIHRoZSByZXN1bHQuIFRoZSBib3VuZFxuICogY29tZXMgZnJvbSBhIHBsYXRmb3JtIHJ1bGUgaW5zdGVhZDogZHVyYXRpb25zIGFib3ZlIDgwMHMgcmVxdWlyZSBleHBsaWNpdFxuICogcGVyLWZ1bmN0aW9uIG51bWVyaWMgY29uZmlnLCBzbyBhIGJ1aWxkZXItZW1pdHRlZCBgJ21heCdgIHJlc29sdmVzIHRvIGF0XG4gKiBtb3N0IDgwMHMg4oCUIDg2MHMgdGhlcmVmb3JlIGRvbWluYXRlcyBhbnkgd29ya2Zsb3cgcm91dGUncyBpbnZvY2F0aW9uXG4gKiBsaWZldGltZSBwbHVzIHNjaGVkdWxpbmcgc2xhY2suIFJldmlzaXQgd2hlbiB0aGF0IGNlaWxpbmcgbW92ZXMgKHRoZVxuICogMzAtbWludXRlIGR1cmF0aW9uIGJldGEgYmVjb21pbmcgcmVhY2hhYmxlIHZpYSBgJ21heCdgIHdvdWxkIGludmFsaWRhdGVcbiAqIHRoZSBib3VuZCkuIFdvcmxkcyB3aXRob3V0IGFuIGludm9jYXRpb24ga2lsbCBib3VuZCAod29ybGQtbG9jYWwsXG4gKiBzZWxmLWhvc3RlZCkgZ2V0IG5vIGRlYXRoIHByb29mIGZyb20gYW55IGNvbnN0YW50IOKAlCB0aGVyZSB0aGUgaW4tcHJvY2Vzc1xuICogc2luZ2xlLWZsaWdodCBsYXllciAoc3RlcC1zaW5nbGUtZmxpZ2h0LnRzKSBpcyB3aGF0IG1ha2VzIGEgYmFja3N0b3BcbiAqIGZpcmluZyBtaWQtc3RlcCBoYXJtbGVzcy5cbiAqXG4gKiA4NjAgYWxzbyBzdGF5cyB1bmRlciB0aGUgcXVldWUncyA5MDBzIG1heGltdW0gZGVsYXkgKFNRUyBjYXApLCBzbyBhXG4gKiBiYWNrc3RvcCdzIGZ1bGwgbGVhc2UgcmVtYWluZGVyIGFsd2F5cyBmaXRzIGluIGEgc2luZ2xlIGRlbGF5ZWQgbWVzc2FnZS5cbiAqXG4gKiBPdmVycmlkZSB2aWEgYFdPUktGTE9XX0lOTElORV9PV05FUlNISVBfTEVBU0VfU0VDT05EU2AgKGNsYW1wZWQgdG9cbiAqIDEuLmBNQVhfSU5MSU5FX09XTkVSU0hJUF9MRUFTRV9TRUNPTkRTYCkuXG4gKi9cbmV4cG9ydCBjb25zdCBJTkxJTkVfT1dORVJTSElQX0xFQVNFX1NFQ09ORFMgPSA4NjA7XG5cbi8qKlxuICogVXBwZXIgYm91bmQgZm9yIHRoZSBsZWFzZSBlbnYgb3ZlcnJpZGUuIDkwMHMgaXMgdGhlIHF1ZXVlJ3MgbWF4aW11bVxuICogcGVyLW1lc3NhZ2UgZGVsYXkgKFNRUyBjYXApIOKAlCBhIGxvbmdlciBsZWFzZSB3b3VsZCBuZWVkIGRlbGF5IGNoYWluaW5nXG4gKiBsaWtlIGxvbmcgd2FpdHMgdXNlOyBjbGFtcCBpbnN0ZWFkIHNvIG9uZSBkZWxheWVkIG1lc3NhZ2UgYWx3YXlzIHN1ZmZpY2VzLlxuICovXG5leHBvcnQgY29uc3QgTUFYX0lOTElORV9PV05FUlNISVBfTEVBU0VfU0VDT05EUyA9IDkwMDtcblxuLyoqXG4gKiBFZmZlY3RpdmUgaW5saW5lLW93bmVyc2hpcCBsZWFzZS4gT3ZlcnJpZGUgdmlhXG4gKiBgV09SS0ZMT1dfSU5MSU5FX09XTkVSU0hJUF9MRUFTRV9TRUNPTkRTYCDigJQgZS5nLiByYWlzZSBpdCBvbiBzZWxmLWhvc3RlZFxuICogbXVsdGktaW5zdGFuY2Ugd29ybGRzIHdpdGggbG9uZy1ydW5uaW5nIHN0ZXBzIHRvIHdpZGVuIHRoZSB3aW5kb3cgaW4gd2hpY2hcbiAqIGEgbGl2ZSBvd25lciBpcyBwcm90ZWN0ZWQgZnJvbSBhIGNvbmN1cnJlbnQgYmFja3N0b3AgZXhlY3V0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW5saW5lT3duZXJzaGlwTGVhc2VTZWNvbmRzKCk6IG51bWJlciB7XG4gIHJldHVybiBlbnZOdW1iZXIoXG4gICAgJ1dPUktGTE9XX0lOTElORV9PV05FUlNISVBfTEVBU0VfU0VDT05EUycsXG4gICAgSU5MSU5FX09XTkVSU0hJUF9MRUFTRV9TRUNPTkRTLFxuICAgIHsgaW50ZWdlcjogdHJ1ZSwgbWluOiAxLCBtYXg6IE1BWF9JTkxJTkVfT1dORVJTSElQX0xFQVNFX1NFQ09ORFMgfVxuICApO1xufVxuXG4vLyBBIHJlcGxheS1jb25zdW1lciBtaXNtYXRjaCBjYW4gYmUgY2F1c2VkIGJ5IGEgdHJhbnNpZW50IGRpdmVyZ2VudCByZXBsYXlcbi8vIHJhdGhlciB0aGFuIGFuIGludmFsaWQgcGVyc2lzdGVkIGhpc3RvcnkuIFF1ZXVlIGJvdW5kZWQgcmVjb3ZlcnkgcmVwbGF5c1xuLy8gYmVmb3JlIHJlY29yZGluZyB0ZXJtaW5hbCBjb3JydXB0aW9uIGZvciBhIHJ1biB0aGF0IGNhbm5vdCByZXBsYXkuXG5leHBvcnQgY29uc3QgUkVQTEFZX0RJVkVSR0VOQ0VfTUFYX1JFVFJJRVMgPSAzO1xuXG4vKipcbiAqIEVmZmVjdGl2ZSByZXBsYXktZGl2ZXJnZW5jZSByZWNvdmVyeSBidWRnZXQuIE92ZXJyaWRlIHZpYVxuICogYFdPUktGTE9XX1JFUExBWV9ESVZFUkdFTkNFX01BWF9SRVRSSUVTYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFJlcGxheURpdmVyZ2VuY2VNYXhSZXRyaWVzKCk6IG51bWJlciB7XG4gIHJldHVybiBlbnZOdW1iZXIoXG4gICAgJ1dPUktGTE9XX1JFUExBWV9ESVZFUkdFTkNFX01BWF9SRVRSSUVTJyxcbiAgICBSRVBMQVlfRElWRVJHRU5DRV9NQVhfUkVUUklFUyxcbiAgICB7IGludGVnZXI6IHRydWUgfVxuICApO1xufVxuXG4vLyBBIHN0YWxlLXNuYXBzaG90IHJlamVjdGlvbiAoNDEyKSBtZWFucyB0aGUgcmVwbGF5J3MgZXZlbnQgbG9nIHdhcyBtaXNzaW5nIGFuXG4vLyBldmVudCB0aGUgV29ybGQgaGFkIGFscmVhZHkgcmVjb3JkZWQsIHNvIHRoZSByZXBsYXkgaXMgcmUtZGVyaXZlZCBmcm9tIGFcbi8vIGNvcnJlY3RlZCBsb2cgaW5zaWRlIHRoZSBzYW1lIGludm9jYXRpb24uIEJvdW5kZWQgYmVjYXVzZSBhIHBlcnNpc3RlbnRseVxuLy8gcmVqZWN0ZWQgd3JpdGUgc2hvdWxkIGVzY2FsYXRlIHJhdGhlciB0aGFuIHNwaW46IGFmdGVyIHRoaXMgbWFueSByZXN0YXJ0cyB0aGVcbi8vIHJ1biBpcyByZS1pbnZva2VkIChhIG5ldyBpbnZvY2F0aW9uLCBwb3NzaWJseSBpbiBhIGRpZmZlcmVudCByZWdpb24pLCBhbmQgdGhlXG4vLyBydW4tbGV2ZWwgYnVkZ2V0IGJlbG93IHRoZW4gYXBwbGllcy5cbmV4cG9ydCBjb25zdCBQUkVDT05ESVRJT05fTUFYX0lOUFJPQ0VTU19SRVNUQVJUUyA9IDM7XG5cbi8qKlxuICogRWZmZWN0aXZlIGluLXByb2Nlc3MgcmVwbGF5LXJlc3RhcnQgYnVkZ2V0IGZvciBzdGFsZS1zbmFwc2hvdCByZWplY3Rpb25zLlxuICogT3ZlcnJpZGUgdmlhIGBXT1JLRkxPV19QUkVDT05ESVRJT05fTUFYX0lOUFJPQ0VTU19SRVNUQVJUU2AuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQcmVjb25kaXRpb25NYXhJblByb2Nlc3NSZXN0YXJ0cygpOiBudW1iZXIge1xuICByZXR1cm4gZW52TnVtYmVyKFxuICAgICdXT1JLRkxPV19QUkVDT05ESVRJT05fTUFYX0lOUFJPQ0VTU19SRVNUQVJUUycsXG4gICAgUFJFQ09ORElUSU9OX01BWF9JTlBST0NFU1NfUkVTVEFSVFMsXG4gICAgeyBpbnRlZ2VyOiB0cnVlIH1cbiAgKTtcbn1cblxuLy8gVGhlIGluLXByb2Nlc3MgYnVkZ2V0IGFib3ZlIGlzIHBlci1pbnZvY2F0aW9uLCBhbmQgYSByZS1pbnZvY2F0aW9uIHRoYXRcbi8vIGVucXVldWVzIGEgZnJlc2ggbWVzc2FnZSBhbHNvIHJlc3RhcnRzIHRoZSBxdWV1ZSdzIGRlbGl2ZXJ5IGNvdW50LCBzbyB3aXRob3V0XG4vLyBhIGNvdW50ZXIgY2FycmllZCBvbiB0aGUgbWVzc2FnZSBhIHBlcm1hbmVudGx5IGZlbmNlZCBydW4gaGFzIG5vIHJ1bi1sZXZlbFxuLy8gYm91bmQgYXQgYWxsLiBJdCBjYW4gc3RheSBmZW5jZWQgd2l0aG91dCBhbnkgcGVybWFuZW50IGZhdWx0IOKAlCBhIGZ1bGwgcmVsb2FkXG4vLyBpcyBub3QgYXRvbWljIGFjcm9zcyBwYWdlcywgc28gYSBidXN5IHJ1biBjYW4gYWNxdWlyZSBhIG5ldyBob2xlIG9uIGV2ZXJ5XG4vLyByZWxvYWQg4oCUIHNvIHRoZSBjaGFpbiBpcyBjb3VudGVkIGFuZCB0aGUgcnVuIGZhaWxzIG9uY2UgdGhpcyBtYW55XG4vLyByZS1pbnZvY2F0aW9ucyBoYXZlIGJlZW4gc3BlbnQgb24gc3RhbGUtc25hcHNob3QgcmVqZWN0aW9ucy5cbmV4cG9ydCBjb25zdCBQUkVDT05ESVRJT05fTUFYX1JFSU5WT0NBVElPTlMgPSA1O1xuXG4vKipcbiAqIEVmZmVjdGl2ZSBwZXItcnVuIGJ1ZGdldCBmb3IgcmUtaW52b2NhdGlvbnMgY2F1c2VkIGJ5IHN0YWxlLXNuYXBzaG90XG4gKiByZWplY3Rpb25zLiBPdmVycmlkZSB2aWEgYFdPUktGTE9XX1BSRUNPTkRJVElPTl9NQVhfUkVJTlZPQ0FUSU9OU2AuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQcmVjb25kaXRpb25NYXhSZWludm9jYXRpb25zKCk6IG51bWJlciB7XG4gIHJldHVybiBlbnZOdW1iZXIoXG4gICAgJ1dPUktGTE9XX1BSRUNPTkRJVElPTl9NQVhfUkVJTlZPQ0FUSU9OUycsXG4gICAgUFJFQ09ORElUSU9OX01BWF9SRUlOVk9DQVRJT05TLFxuICAgIHsgaW50ZWdlcjogdHJ1ZSB9XG4gICk7XG59XG5cbi8vIEJhY2tvZmYgYmVmb3JlIGEgcHJlY29uZGl0aW9uIHJlLWludm9jYXRpb24uIFVubGlrZSB0aGUgaW4tcHJvY2VzcyByZXN0YXJ0XG4vLyAod2hlcmUgdGhlIHBvaW50IGlzIHRvIHJlLXJlYWQgaW1tZWRpYXRlbHkpLCBhIHJlLWludm9jYXRpb24gb25seSBoYXBwZW5zXG4vLyBhZnRlciB0aGUgaW4tcHJvY2VzcyBidWRnZXQgZmFpbGVkIHRvIGNhdGNoIHVwLCBzbyB0aGUgbG9nIGlzIGJlaW5nIGV4dGVuZGVkXG4vLyBmYXN0ZXIgdGhhbiB0aGlzIHJlcGxheSBjYW4gZm9sbG93IGl0LiBXYWl0aW5nIGxldHMgdGhlIHdyaXRlcnMgcXVpZXNjZS5cbmV4cG9ydCBjb25zdCBQUkVDT05ESVRJT05fUkVJTlZPS0VfREVMQVlfU0VDT05EUyA9IDI7XG5cbi8qKlxuICogRWZmZWN0aXZlIGRlbGF5IGJlZm9yZSBhIHByZWNvbmRpdGlvbiByZS1pbnZvY2F0aW9uLiBPdmVycmlkZSB2aWFcbiAqIGBXT1JLRkxPV19QUkVDT05ESVRJT05fUkVJTlZPS0VfREVMQVlfU0VDT05EU2AuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQcmVjb25kaXRpb25SZWludm9rZURlbGF5U2Vjb25kcygpOiBudW1iZXIge1xuICByZXR1cm4gZW52TnVtYmVyKFxuICAgICdXT1JLRkxPV19QUkVDT05ESVRJT05fUkVJTlZPS0VfREVMQVlfU0VDT05EUycsXG4gICAgUFJFQ09ORElUSU9OX1JFSU5WT0tFX0RFTEFZX1NFQ09ORFMsXG4gICAgeyBpbnRlZ2VyOiB0cnVlIH1cbiAgKTtcbn1cbiJdfQ==
405
+ // A delivery reaching a deployment the run is not pinned to is not treated as
406
+ // permanent. Re-route the message at the run's own deployment a bounded number
407
+ // of times before failing the run with DEPLOYMENT_MISMATCH.
408
+ export const DEPLOYMENT_MISMATCH_MAX_RETRIES = 3;
409
+ /**
410
+ * Effective deployment-mismatch re-route budget. Override via
411
+ * `WORKFLOW_DEPLOYMENT_MISMATCH_MAX_RETRIES`; `0` fails the run on the first
412
+ * misrouted delivery instead of attempting recovery.
413
+ */
414
+ export function getDeploymentMismatchMaxRetries() {
415
+ return envNumber('WORKFLOW_DEPLOYMENT_MISMATCH_MAX_RETRIES', DEPLOYMENT_MISMATCH_MAX_RETRIES, { integer: true, min: 0 });
416
+ }
417
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvY29uc3RhbnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM1QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRTdDLDRFQUE0RTtBQUM1RSw0RUFBNEU7QUFDNUUseUVBQXlFO0FBQ3pFLG9EQUFvRDtBQUNwRCxFQUFFO0FBQ0YsK0VBQStFO0FBQy9FLHNEQUFzRDtBQUN0RCwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLDhFQUE4RTtBQUM5RSx5RUFBeUU7QUFDekUsK0VBQStFO0FBQy9FLDZFQUE2RTtBQUM3RSwrRUFBK0U7QUFDL0UsZ0ZBQWdGO0FBQ2hGLDJFQUEyRTtBQUMzRSwyRUFBMkU7QUFDM0Usc0JBQXNCO0FBQ3RCLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLEVBQUUsQ0FBQztBQUV2Qzs7R0FFRztBQUNILE1BQU0sVUFBVSxxQkFBcUI7SUFDbkMsd0VBQXdFO0lBQ3hFLDBFQUEwRTtJQUMxRSw4RUFBOEU7SUFDOUUseUVBQXlFO0lBQ3pFLDRFQUE0RTtJQUM1RSxPQUFPLFNBQVMsQ0FBQywrQkFBK0IsRUFBRSxvQkFBb0IsRUFBRTtRQUN0RSxPQUFPLEVBQUUsSUFBSTtRQUNiLEdBQUcsRUFBRSxDQUFDO1FBQ04sR0FBRyxFQUFFLG9CQUFvQjtLQUMxQixDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUNILE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLE9BQU8sQ0FBQztBQUV6QywyREFBMkQ7QUFDM0QsTUFBTSxDQUFDLE1BQU0scUJBQXFCLEdBQUcsTUFBTSxDQUFDO0FBRTVDOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxPQUFPLENBQUM7QUFFN0Ms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Q25DLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUNsQixDQUFDO0FBQ0osQ0FBQztBQUVELDhFQUE4RTtBQUM5RSwrRUFBK0U7QUFDL0UsNERBQTREO0FBQzVELE1BQU0sQ0FBQyxNQUFNLCtCQUErQixHQUFHLENBQUMsQ0FBQztBQUVqRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLCtCQUErQjtJQUM3QyxPQUFPLFNBQVMsQ0FDZCwwQ0FBMEMsRUFDMUMsK0JBQStCLEVBQy9CLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQzFCLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZW52TnVtYmVyIH0gZnJvbSAnQHdvcmtmbG93L3dvcmxkJztcbmltcG9ydCB7IHJ1bnRpbWVMb2dnZXIgfSBmcm9tICcuLi9sb2dnZXIuanMnO1xuXG4vLyBNYXhpbXVtIG51bWJlciBvZiBxdWV1ZSBkZWxpdmVyeSBhdHRlbXB0cyBiZWZvcmUgdGhlIGhhbmRsZXIgZ2l2ZXMgdXAgYW5kXG4vLyBncmFjZWZ1bGx5IGZhaWxzIHRoZSBydW4vc3RlcC4gVGhpcyBtdXN0IGJlIGJvdW5kZWQgdW5kZXIgdGhlIFZRUyBtZXNzYWdlXG4vLyBtYXggdmlzaWJpbGl0eSB3aW5kb3cgKDI0IGhvdXJzKSBzbyB0aGF0IG91ciBoYW5kbGVyLXNpZGUgZmFpbHVyZSBwYXRoXG4vLyByZWxpYWJseSBleGVjdXRlcyBiZWZvcmUgVlFTIGV4cGlyZXMgdGhlIG1lc3NhZ2UuXG4vL1xuLy8gVGhlIGVmZmVjdGl2ZSB3YWxsLWNsb2NrIHN1cnZpdmFsIGRlcGVuZHMgb24gdGhlIHBlci1yZWRlbGl2ZXJ5IGJhY2tvZmY6IHRoZVxuLy8gYHJldHJ5LWFmdGVyYCB0aGUgaGFuZGxlciByZXR1cm5zIChzZWUgd29ybGQtdmVyY2VsXG4vLyBgZ2V0SGFuZGxlckVycm9yUmV0cnlBZnRlclNlY29uZHNgKSBmZWQgdGhyb3VnaCBWUVMgYGNhbGN1bGF0ZUJhY2tvZmZEZWxheWAuXG4vLyBWUVMgdXNlcyBvdXIgdmFsdWUgZm9yIHRoZSBmaXJzdCAzMiBhdHRlbXB0cyAoY2xhbXBlZCB0byBbNXMsIDkwMHNdKSB0aGVuXG4vLyBhcHBsaWVzIGl0cyBvd24gZXhwb25lbnRpYWwgZ3Jvd3RoIOKAlCBldmVyeSBob3AgaGFyZC1jYXBwZWQgYXQgdGhlIFNRUyBsaW1pdFxuLy8gb2YgOTAwcy4gV2l0aCB0aGUgYmFja29mZiByYW1waW5nIHRvd2FyZCB0aGF0IDkwMHMgY2VpbGluZyAocmVhY2hlZCBieVxuLy8gfmRlbGl2ZXJ5IDExKSwgNDggYXR0ZW1wdHMgc3BhbiByb3VnaGx5IDnigJMxMCBob3VycyBvZiB3YWxsLWNsb2NrICh+MzUsMDAwcyksXG4vLyBjb21mb3J0YWJseSB1bmRlciB0aGUgMjQtaG91ciBtZXNzYWdlLXZpc2liaWxpdHkgbGltaXQgc28gdGhlIGZhaWx1cmUgcGF0aFxuLy8gcnVucyBiZWZvcmUgdGhlIG1lc3NhZ2UgZXhwaXJlcy4gKEEgZmxhdHRlciwgbG93LWNhcHBlZCBiYWNrb2ZmIGV4aGF1c3RzIHRoZVxuLy8gYnVkZ2V0IGluIG9ubHkgYSBmZXcgaG91cnMsIGZhaWxpbmcgb3RoZXJ3aXNlLWhlYWx0aHkgcnVucyBkdXJpbmcgYSB0cmFuc2llbnRcbi8vIGJhY2tlbmQgb3V0YWdlOyBjb252ZXJzZWx5LCBzcGFubmluZyB0aGUgZnVsbCAyNGggd2luZG93IHdvdWxkIHJlcXVpcmUgYVxuLy8gc3Vic3RhbnRpYWxseSBoaWdoZXIgY2FwIGhlcmUsIG5vdCBhIGhpZ2hlciBwZXItaG9wIGNlaWxpbmcg4oCUIFZRUyBjbGFtcHNcbi8vIGV2ZXJ5IGhvcCBhdCA5MDBzLilcbmV4cG9ydCBjb25zdCBNQVhfUVVFVUVfREVMSVZFUklFUyA9IDQ4O1xuXG4vKipcbiAqIEVmZmVjdGl2ZSBtYXggcXVldWUgZGVsaXZlcmllcy4gT3ZlcnJpZGUgdmlhIGBXT1JLRkxPV19NQVhfUVVFVUVfREVMSVZFUklFU2AuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRNYXhRdWV1ZURlbGl2ZXJpZXMoKTogbnVtYmVyIHtcbiAgLy8gT25seSBldmVyIGxvd2VyIHRoZSBkZWxpdmVyeSBidWRnZXQuIFRoZSBkZWZhdWx0IGlzIGNhbGlicmF0ZWQgc28gdGhlXG4gIC8vIGhhbmRsZXItc2lkZSBmYWlsdXJlIHBhdGggcnVucyBiZWZvcmUgVlFTIG1lc3NhZ2UtcmV0ZW50aW9uIGV4cGlyeSAoc2VlXG4gIC8vIE1BWF9RVUVVRV9ERUxJVkVSSUVTIGFib3ZlKTsgYSBoaWdoZXIgdmFsdWUgd291bGQgYnlwYXNzIHRoYXQgaW52YXJpYW50IGFuZFxuICAvLyBsZXQgYSBiYWQgZGVwbG95bWVudCByZWRlbGl2ZXIgdW50aWwgcXVldWUgZXhwaXJ5IGluc3RlYWQgb2YgcmVjb3JkaW5nXG4gIC8vIHJ1bl9mYWlsLiBgbWF4YCBjbGFtcHMgYSB0b28taGlnaCBvdmVycmlkZSBiYWNrIGRvd24gdG8gdGhlIHNhZmUgZGVmYXVsdC5cbiAgcmV0dXJuIGVudk51bWJlcignV09SS0ZMT1dfTUFYX1FVRVVFX0RFTElWRVJJRVMnLCBNQVhfUVVFVUVfREVMSVZFUklFUywge1xuICAgIGludGVnZXI6IHRydWUsXG4gICAgbWluOiAxLFxuICAgIG1heDogTUFYX1FVRVVFX0RFTElWRVJJRVMsXG4gIH0pO1xufVxuXG4vKipcbiAqIERlZmF1bHQgbWF4aW11bSB0aW1lIGFsbG93ZWQgZm9yIHRoZSAqcmVwbGF5KiBwb3J0aW9uIG9mIGEgc2luZ2xlIHdvcmtmbG93XG4gKiBoYW5kbGVyIGludm9jYXRpb24gKGluIG1zKS4gVGhpcyBidWRnZXQgb25seSBjb3ZlcnMgZGV0ZXJtaW5pc3RpYy1yZXBsYXlcbiAqIGFuZCB3b3JrZmxvdy1WTSBleGVjdXRpb24gYmV0d2VlbiBzdGVwIGJvdW5kYXJpZXMg4oCUIGlubGluZSBzdGVwIGJvZGllc1xuICogKGBcInVzZSBzdGVwXCJgIGZ1bmN0aW9ucyBpbnZva2VkIHZpYSBgZXhlY3V0ZVN0ZXBgKSBkbyBOT1QgY291bnQgYWdhaW5zdFxuICogaXQuIFN0ZXAgYm9kaWVzIGFyZSBib3VuZGVkIHNlcGFyYXRlbHkgYnkgdGhlIHBsYXRmb3JtJ3MgZnVuY3Rpb25cbiAqIGBtYXhEdXJhdGlvbmAgKGUuZy4gODAwcyBvbiBWZXJjZWwgUHJvIEZsdWlkKSBhbmQgYE5PX0lOTElORV9SRVBMQVlfQUZURVJfTVNgLlxuICpcbiAqIElmIHRoZSBub24tc3RlcCAoXCJyZXBsYXlcIikgdGltZSB3aXRoaW4gYSBzaW5nbGUgaW52b2NhdGlvbiBleGNlZWRzIHRoaXNcbiAqIGJ1ZGdldCwgdGhlIGhhbmRsZXIgZXhpdHMgc28gdGhlIHF1ZXVlIGNhbiByZXRyeS4gQWZ0ZXJcbiAqIGBSRVBMQVlfVElNRU9VVF9NQVhfUkVUUklFU2AgZXhoYXVzdGVkIGF0dGVtcHRzIHRoZSBydW4gaXMgZmFpbGVkIHdpdGhcbiAqIGBSVU5fRVJST1JfQ09ERVMuUkVQTEFZX1RJTUVPVVRgLlxuICpcbiAqIE5vdGUgdGhhdCBvbiBWZXJjZWwgSG9iYnkgKHN0YW5kYXJkIGZ1bmN0aW9ucyksIHRoZSBwbGF0Zm9ybSBgbWF4RHVyYXRpb25gXG4gKiBpcyA2MHMg4oCUIHdlbGwgYmVsb3cgdGhpcyBidWRnZXQsIHNvIHRoZSBwbGF0Zm9ybSBTSUdURVJNIHdpbGwgZmlyZSBmaXJzdFxuICogYW5kIHRoZSBxdWV1ZSB3aWxsIHJlLWRlbGl2ZXIgdW50aWwgdGhlIHZpc2liaWxpdHkgd2luZG93IGV4cGlyZXMuIFdpdGhcbiAqIEZsdWlkIENvbXB1dGUgb24gSG9iYnkgdGhlIHBlci1mdW5jdGlvbiBjZWlsaW5nIHJpc2VzIHRvIDMwMHMsIHN0aWxsXG4gKiB1bmRlciB0aGUgZGVmYXVsdCBidWRnZXQuXG4gKlxuICogT3ZlcnJpZGUgdmlhIHRoZSBgV09SS0ZMT1dfUkVQTEFZX1RJTUVPVVRfTVNgIGVudiB2YXIgKGNsYW1wZWQgdG9cbiAqIGBNSU5fUkVQTEFZX1RJTUVPVVRfTVNgLi5gTUFYX1JFUExBWV9USU1FT1VUX01TYCkuXG4gKi9cbmV4cG9ydCBjb25zdCBSRVBMQVlfVElNRU9VVF9NUyA9IDI0MF8wMDA7XG5cbi8qKiBMb3dlciBib3VuZCBmb3IgdGhlIHJlcGxheS10aW1lb3V0IGVudiB2YXIgb3ZlcnJpZGUuICovXG5leHBvcnQgY29uc3QgTUlOX1JFUExBWV9USU1FT1VUX01TID0gMzBfMDAwO1xuXG4vKipcbiAqIFVwcGVyIGJvdW5kIGZvciB0aGUgcmVwbGF5LXRpbWVvdXQgZW52IHZhciBvdmVycmlkZS4gNzgwcyBsZWF2ZXMg4omlMjBzIG9mXG4gKiBoZWFkcm9vbSB1bmRlciBWZXJjZWwgUHJvIEZsdWlkJ3MgODAwcyBmdW5jdGlvbiBjZWlsaW5nIHNvIHRoZSBoYW5kbGVyXG4gKiBjYW4gd3JpdGUgYHJ1bl9mYWlsZWRgIGJlZm9yZSBTSUdURVJNLlxuICovXG5leHBvcnQgY29uc3QgTUFYX1JFUExBWV9USU1FT1VUX01TID0gNzgwXzAwMDtcblxuLy8gVHJhY2sgd2hpY2ggcmF3IGVudiB2YXIgdmFsdWVzIHdlJ3ZlIGFscmVhZHkgd2FybmVkIGFib3V0IHNvIHRoZSB3YXJuaW5nXG4vLyBsb2cgb25seSBmaXJlcyBvbmNlIHBlciBwcm9jZXNzICh0aGUgZnVuY3Rpb24gbWF5IGJlIGNhbGxlZCBtYW55IHRpbWVzKS5cbmNvbnN0IHdhcm5lZFJlcGxheVRpbWVvdXRWYWx1ZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuZnVuY3Rpb24gd2Fybk9uY2UoXG4gIHJhdzogc3RyaW5nLFxuICBtZXNzYWdlOiBzdHJpbmcsXG4gIGRhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4pOiB2b2lkIHtcbiAgaWYgKHdhcm5lZFJlcGxheVRpbWVvdXRWYWx1ZXMuaGFzKHJhdykpIHJldHVybjtcbiAgd2FybmVkUmVwbGF5VGltZW91dFZhbHVlcy5hZGQocmF3KTtcbiAgcnVudGltZUxvZ2dlci53YXJuKG1lc3NhZ2UsIGRhdGEpO1xufVxuXG4vKipcbiAqIFJlc29sdmUgdGhlIGVmZmVjdGl2ZSByZXBsYXktdGltZW91dCBidWRnZXQgZm9yIHRoZSBjdXJyZW50IHByb2Nlc3MuXG4gKlxuICogUmVhZHMgYHByb2Nlc3MuZW52LldPUktGTE9XX1JFUExBWV9USU1FT1VUX01TYCBsYXppbHkgc28gdGVzdHMgYW5kXG4gKiBkZXBsb3ltZW50cyBjYW4gb3ZlcnJpZGUgcGVyIGludm9jYXRpb24uIEludmFsaWQgLyBvdXQtb2YtcmFuZ2UgdmFsdWVzXG4gKiBmYWxsIGJhY2sgdG8gYSBzYWZlIHZhbHVlIChubyB0aHJvdyDigJQgdGhlIGVudiB2YXIgaXMgYW4gZXNjYXBlIGhhdGNoLFxuICogbm90IGEgaGFyZCByZXF1aXJlbWVudCkgYW5kIGVtaXQgYSBvbmUtdGltZSB3YXJuaW5nIHNvIG1pc2NvbmZpZ3VyYXRpb25cbiAqIGlzIG9ic2VydmFibGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXBsYXlUaW1lb3V0TXMoKTogbnVtYmVyIHtcbiAgY29uc3QgcmF3ID0gcHJvY2Vzcy5lbnYuV09SS0ZMT1dfUkVQTEFZX1RJTUVPVVRfTVM7XG4gIGlmICghcmF3KSByZXR1cm4gUkVQTEFZX1RJTUVPVVRfTVM7XG4gIGNvbnN0IHBhcnNlZCA9IE51bWJlcihyYXcpO1xuICBpZiAoIU51bWJlci5pc0Zpbml0ZShwYXJzZWQpIHx8IHBhcnNlZCA8PSAwKSB7XG4gICAgd2Fybk9uY2UoXG4gICAgICByYXcsXG4gICAgICAnSWdub3JpbmcgV09SS0ZMT1dfUkVQTEFZX1RJTUVPVVRfTVM6IG5vdCBhIHBvc2l0aXZlIGZpbml0ZSBudW1iZXI7IHVzaW5nIGRlZmF1bHQnLFxuICAgICAgeyByYXcsIGRlZmF1bHRNczogUkVQTEFZX1RJTUVPVVRfTVMgfVxuICAgICk7XG4gICAgcmV0dXJuIFJFUExBWV9USU1FT1VUX01TO1xuICB9XG4gIGlmIChwYXJzZWQgPCBNSU5fUkVQTEFZX1RJTUVPVVRfTVMpIHtcbiAgICB3YXJuT25jZShyYXcsICdXT1JLRkxPV19SRVBMQVlfVElNRU9VVF9NUyBiZWxvdyBtaW5pbXVtOyBjbGFtcGVkJywge1xuICAgICAgcmF3LFxuICAgICAgY2xhbXBlZE1zOiBNSU5fUkVQTEFZX1RJTUVPVVRfTVMsXG4gICAgICBtaW5NczogTUlOX1JFUExBWV9USU1FT1VUX01TLFxuICAgIH0pO1xuICAgIHJldHVybiBNSU5fUkVQTEFZX1RJTUVPVVRfTVM7XG4gIH1cbiAgaWYgKHBhcnNlZCA+IE1BWF9SRVBMQVlfVElNRU9VVF9NUykge1xuICAgIHdhcm5PbmNlKHJhdywgJ1dPUktGTE9XX1JFUExBWV9USU1FT1VUX01TIGFib3ZlIG1heGltdW07IGNsYW1wZWQnLCB7XG4gICAgICByYXcsXG4gICAgICBjbGFtcGVkTXM6IE1BWF9SRVBMQVlfVElNRU9VVF9NUyxcbiAgICAgIG1heE1zOiBNQVhfUkVQTEFZX1RJTUVPVVRfTVMsXG4gICAgfSk7XG4gICAgcmV0dXJuIE1BWF9SRVBMQVlfVElNRU9VVF9NUztcbiAgfVxuICByZXR1cm4gcGFyc2VkO1xufVxuXG4vKipcbiAqIFJlc2V0IHRoZSB3YXJuLW9uY2UgY2FjaGUuIFRlc3Qtb25seSDigJQgZXhwb3J0ZWQgc28gdW5pdCB0ZXN0cyBjYW5cbiAqIGV4ZXJjaXNlIHRoZSB3YXJuIHBhdGggcmVwZWF0ZWRseSB3aXRob3V0IHNoYXJpbmcgc3RhdGUuXG4gKlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfcmVzZXRSZXBsYXlUaW1lb3V0V2FybkNhY2hlRm9yVGVzdHMoKTogdm9pZCB7XG4gIHdhcm5lZFJlcGxheVRpbWVvdXRWYWx1ZXMuY2xlYXIoKTtcbn1cblxuLy8gTnVtYmVyIG9mIHF1ZXVlIGRlbGl2ZXJ5IGF0dGVtcHRzIHRvIGFsbG93IGJlZm9yZSBwZXJtYW5lbnRseSBmYWlsaW5nIGEgcnVuXG4vLyBkdWUgdG8gYSByZXBsYXkgdGltZW91dC4gT24gYXR0ZW1wdHMgMSB0aHJvdWdoIHRoaXMgdmFsdWUsIHRoZSB0aW1lb3V0XG4vLyBoYW5kbGVyIGV4aXRzIHdpdGhvdXQgd3JpdGluZyBydW5fZmFpbGVkIHNvIHRoZSBxdWV1ZSByZXRyaWVzIHRoZSBtZXNzYWdlLlxuLy8gT24gdGhlIG5leHQgYXR0ZW1wdCB0aGUgcnVuIGlzIG1hcmtlZCBhcyBmYWlsZWQuXG5leHBvcnQgY29uc3QgUkVQTEFZX1RJTUVPVVRfTUFYX1JFVFJJRVMgPSAzO1xuXG4vKipcbiAqIEVmZmVjdGl2ZSByZXBsYXktdGltZW91dCByZXRyeSBidWRnZXQuIE92ZXJyaWRlIHZpYVxuICogYFdPUktGTE9XX1JFUExBWV9USU1FT1VUX01BWF9SRVRSSUVTYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFJlcGxheVRpbWVvdXRNYXhSZXRyaWVzKCk6IG51bWJlciB7XG4gIHJldHVybiBlbnZOdW1iZXIoXG4gICAgJ1dPUktGTE9XX1JFUExBWV9USU1FT1VUX01BWF9SRVRSSUVTJyxcbiAgICBSRVBMQVlfVElNRU9VVF9NQVhfUkVUUklFUyxcbiAgICB7IGludGVnZXI6IHRydWUgfVxuICApO1xufVxuXG4vKipcbiAqIERlZmF1bHQgbWF4aW11bSBudW1iZXIgb2Ygc3RlcHMgdGhlIG93bmVkLWlubGluZSBwYXRoIHJ1bnMgaW5saW5lIChpblxuICogcGFyYWxsZWwpIHBlciBzdXNwZW5zaW9uLiBUaGUgcmVzdCBhcmUgcXVldWVkIHRvIGJhY2tncm91bmQgaGFuZGxlcnMuIEVhY2hcbiAqIGlubGluZSBzdGVwIGlzIGNyZWF0ZWQgbGF6aWx5IOKAlCBpdHMgYHN0ZXBfY3JlYXRlZGAgaXMgZm9sZGVkIGludG8gdGhlXG4gKiBgc3RlcF9zdGFydGVkYCB0aGF0IGBleGVjdXRlU3RlcGAgc2VuZHMg4oCUIHNvIGlubGluaW5nIE4gc3RlcHMgc2F2ZXMgTiBxdWV1ZVxuICogcm91bmQtdHJpcHMgZm9yIGEgYFByb21pc2UuYWxsYC1zdHlsZSBmYW4tb3V0LiBgMWAgcmVwcm9kdWNlcyB0aGVcbiAqIHNpbmdsZS1pbmxpbmUtc3RlcCBiZWhhdmlvciBleGFjdGx5ICh1c2VmdWwga2lsbC1zd2l0Y2gpLlxuICpcbiAqIE92ZXJyaWRlIHZpYSBgV09SS0ZMT1dfTUFYX0lOTElORV9TVEVQU2AgKGNsYW1wZWQgdG9cbiAqIGBNSU5fTUFYX0lOTElORV9TVEVQU2AuLmBNQVhfTUFYX0lOTElORV9TVEVQU2ApLlxuICovXG5leHBvcnQgY29uc3QgTUFYX0lOTElORV9TVEVQUyA9IDM7XG5cbi8qKiBMb3dlciBib3VuZCBmb3IgdGhlIGlubGluZS1zdGVwcyBlbnYgb3ZlcnJpZGUgKDEgPSBzaW5nbGUgaW5saW5lIHN0ZXApLiAqL1xuZXhwb3J0IGNvbnN0IE1JTl9NQVhfSU5MSU5FX1NURVBTID0gMTtcblxuLyoqXG4gKiBVcHBlciBib3VuZCBmb3IgdGhlIGlubGluZS1zdGVwcyBlbnYgb3ZlcnJpZGUuIElubGluZSBib2RpZXMgcnVuIGluIHBhcmFsbGVsXG4gKiB3aXRoaW4gb25lIGZ1bmN0aW9uIGludm9jYXRpb24sIHNvIHRoaXMgY2FwcyBtZW1vcnkvQ1BVIGZhbi1vdXQgcGVyIGhhbmRsZXIuXG4gKi9cbmV4cG9ydCBjb25zdCBNQVhfTUFYX0lOTElORV9TVEVQUyA9IDE2O1xuXG4vLyBXYXJuLW9uY2UgY2FjaGUgZm9yIFdPUktGTE9XX01BWF9JTkxJTkVfU1RFUFMsIGtleWVkIGJ5IHJhdyBlbnYgdmFsdWUuXG5jb25zdCB3YXJuZWRNYXhJbmxpbmVTdGVwc1ZhbHVlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4vKipcbiAqIFJlc29sdmUgdGhlIGVmZmVjdGl2ZSBtYXggbnVtYmVyIG9mIGlubGluZSBzdGVwcyBmb3IgdGhlIGN1cnJlbnQgcHJvY2Vzcy5cbiAqXG4gKiBSZWFkcyBgcHJvY2Vzcy5lbnYuV09SS0ZMT1dfTUFYX0lOTElORV9TVEVQU2AgbGF6aWx5IHNvIHRlc3RzIGFuZFxuICogZGVwbG95bWVudHMgY2FuIG92ZXJyaWRlIHBlciBpbnZvY2F0aW9uLiBJbnZhbGlkIC8gb3V0LW9mLXJhbmdlIHZhbHVlcyBmYWxsXG4gKiBiYWNrIHRvIGEgc2FmZSB2YWx1ZSAobm8gdGhyb3cg4oCUIHRoZSBlbnYgdmFyIGlzIGFuIGVzY2FwZSBoYXRjaCkgYW5kIGVtaXQgYVxuICogb25lLXRpbWUgd2FybmluZyBzbyBtaXNjb25maWd1cmF0aW9uIGlzIG9ic2VydmFibGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRNYXhJbmxpbmVTdGVwcygpOiBudW1iZXIge1xuICBjb25zdCByYXcgPSBwcm9jZXNzLmVudi5XT1JLRkxPV19NQVhfSU5MSU5FX1NURVBTO1xuICBpZiAoIXJhdykgcmV0dXJuIE1BWF9JTkxJTkVfU1RFUFM7XG4gIGNvbnN0IHBhcnNlZCA9IE51bWJlcihyYXcpO1xuICBpZiAoIU51bWJlci5pc0ludGVnZXIocGFyc2VkKSB8fCBwYXJzZWQgPD0gMCkge1xuICAgIGlmICghd2FybmVkTWF4SW5saW5lU3RlcHNWYWx1ZXMuaGFzKHJhdykpIHtcbiAgICAgIHdhcm5lZE1heElubGluZVN0ZXBzVmFsdWVzLmFkZChyYXcpO1xuICAgICAgcnVudGltZUxvZ2dlci53YXJuKFxuICAgICAgICAnSWdub3JpbmcgV09SS0ZMT1dfTUFYX0lOTElORV9TVEVQUzogbm90IGEgcG9zaXRpdmUgaW50ZWdlcjsgdXNpbmcgZGVmYXVsdCcsXG4gICAgICAgIHsgcmF3LCBkZWZhdWx0VmFsdWU6IE1BWF9JTkxJTkVfU1RFUFMgfVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIE1BWF9JTkxJTkVfU1RFUFM7XG4gIH1cbiAgaWYgKHBhcnNlZCA8IE1JTl9NQVhfSU5MSU5FX1NURVBTKSByZXR1cm4gTUlOX01BWF9JTkxJTkVfU1RFUFM7XG4gIGlmIChwYXJzZWQgPiBNQVhfTUFYX0lOTElORV9TVEVQUykge1xuICAgIGlmICghd2FybmVkTWF4SW5saW5lU3RlcHNWYWx1ZXMuaGFzKHJhdykpIHtcbiAgICAgIHdhcm5lZE1heElubGluZVN0ZXBzVmFsdWVzLmFkZChyYXcpO1xuICAgICAgcnVudGltZUxvZ2dlci53YXJuKCdXT1JLRkxPV19NQVhfSU5MSU5FX1NURVBTIGFib3ZlIG1heGltdW07IGNsYW1wZWQnLCB7XG4gICAgICAgIHJhdyxcbiAgICAgICAgY2xhbXBlZFZhbHVlOiBNQVhfTUFYX0lOTElORV9TVEVQUyxcbiAgICAgICAgbWF4VmFsdWU6IE1BWF9NQVhfSU5MSU5FX1NURVBTLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBNQVhfTUFYX0lOTElORV9TVEVQUztcbiAgfVxuICByZXR1cm4gcGFyc2VkO1xufVxuXG5jb25zdCB3YXJuZWRNYXhFdmVudHNWYWx1ZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuLyoqXG4gKiBPcHRpb25hbCBjbGllbnQtc2lkZSBvdmVycmlkZSBmb3IgdGhlIHNlcnZlci1zdXBwbGllZCBwZXItcnVuIGV2ZW50IGNlaWxpbmcuXG4gKiBXaGVuIHNldCB0byBhIHBvc2l0aXZlIGludGVnZXIsIHRoZSBydW50aW1lIGNsYW1wcyB0aGUgc2VydmVyJ3MgbGltaXQgKmRvd24qXG4gKiB0byB0aGlzIHZhbHVlIChuZXZlciByYWlzZXMgaXQpIHNvIGVuZm9yY2VtZW50IGNhbiBiZSBleGVyY2lzZWQgd2l0aG91dCBhXG4gKiBzZXJ2ZXItc2lkZSBjaGFuZ2UuIGB1bmRlZmluZWRgICh1bnNldCkg4oeSIHVzZSB0aGUgc2VydmVyIHZhbHVlIGFzLWlzLlxuICpcbiAqIFJlYWRzIGBwcm9jZXNzLmVudi5XT1JLRkxPV19NQVhfRVZFTlRTX09WRVJSSURFYCBsYXppbHkgc28gdGVzdHMgYW5kXG4gKiBkZXBsb3ltZW50cyBjYW4gb3ZlcnJpZGUgcGVyIGludm9jYXRpb24uIEludmFsaWQgdmFsdWVzIGZhbGwgYmFjayB0byB1bnNldFxuICogKG5vIHRocm93IOKAlCB0aGUgZW52IHZhciBpcyBhbiBlc2NhcGUgaGF0Y2gpIGFuZCBlbWl0IGEgb25lLXRpbWUgd2FybmluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldE1heEV2ZW50c092ZXJyaWRlKCk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHJhdyA9IHByb2Nlc3MuZW52LldPUktGTE9XX01BWF9FVkVOVFNfT1ZFUlJJREU7XG4gIGlmICghcmF3KSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCBwYXJzZWQgPSBOdW1iZXIocmF3KTtcbiAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKHBhcnNlZCkgfHwgcGFyc2VkIDw9IDApIHtcbiAgICBpZiAoIXdhcm5lZE1heEV2ZW50c1ZhbHVlcy5oYXMocmF3KSkge1xuICAgICAgd2FybmVkTWF4RXZlbnRzVmFsdWVzLmFkZChyYXcpO1xuICAgICAgcnVudGltZUxvZ2dlci53YXJuKFxuICAgICAgICAnSWdub3JpbmcgV09SS0ZMT1dfTUFYX0VWRU5UU19PVkVSUklERTogbm90IGEgcG9zaXRpdmUgaW50ZWdlcjsgdXNpbmcgc2VydmVyIGxpbWl0JyxcbiAgICAgICAgeyByYXcgfVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICByZXR1cm4gcGFyc2VkO1xufVxuXG4vKipcbiAqIFdoZXRoZXIgb3B0aW1pc3RpYyBpbmxpbmUgc3RlcCBzdGFydCBpcyBlbmFibGVkLiBXaGVuIG9uLCB0aGUgb3duZWQtaW5saW5lXG4gKiBwYXRoIGJlZ2lucyBydW5uaW5nIGEgYnJhbmQtbmV3IHN0ZXAncyBib2R5ICpiZWZvcmUqIGl0cyBsYXp5IGBzdGVwX3N0YXJ0ZWRgXG4gKiBuZXR3b3JrIGNhbGwgcmVzb2x2ZXMgKHRoZSBpbnB1dCBpcyBhbHJlYWR5IGtub3duIGxvY2FsbHkpLCBhd2FpdGluZyB0aGVcbiAqIGBzdGVwX3N0YXJ0ZWRgIG9ubHkgYmVmb3JlIHRoZSB0ZXJtaW5hbCB3cml0ZS5cbiAqXG4gKiBUaGlzIGNhbiBydW4gYSBzdGVwIGJvZHkgbW9yZSB0aGFuIG9uY2Ugd2hlbiBoYW5kbGVycyByYWNlIGZvciB0aGUgc2FtZVxuICogc3RlcCdzIGNyZWF0ZS1jbGFpbSDigJQgYm90aCBydW4gdGhlIGJvZHkgYmVmb3JlIG9uZSB3aW5zLiBUaGF0IGlzIHVuc2FmZSBmb3JcbiAqIHN0ZXBzIHdpdGggbm9uLWlkZW1wb3RlbnQgc2lkZSBlZmZlY3RzOyBpbiBwYXJ0aWN1bGFyLCB0d28gY29uY3VycmVudCBydW5zXG4gKiBvZiBhIHN0ZXAgdGhhdCB3cml0ZXMgdG8gdGhlIHdvcmtmbG93IHN0cmVhbSAoZS5nLiBhbiBBSSBhZ2VudCBzdHJlYW1pbmdcbiAqIHRva2VucykgY2FuIGludGVybGVhdmUgYW5kIGNvcnJ1cHQgdGhlIHN0cmVhbSBkYXRhLiBTbyB0aGUgb3B0aW1pemF0aW9uIGlzXG4gKiAqKm9mZiBieSBkZWZhdWx0KiogYW5kIG11c3QgYmUgZXhwbGljaXRseSBvcHRlZCBpbnRvIHBlciBkZXBsb3ltZW50LlxuICpcbiAqIFJlYWRzIGBwcm9jZXNzLmVudi5XT1JLRkxPV19PUFRJTUlTVElDX0lOTElORV9TVEFSVGAgbGF6aWx5LiBEZWZhdWx0IE9GRjtcbiAqIGVuYWJsZWQgb25seSBieSBhbiBleHBsaWNpdCBgJzEnYCAvIGAndHJ1ZSdgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNPcHRpbWlzdGljSW5saW5lU3RhcnRFbmFibGVkKCk6IGJvb2xlYW4ge1xuICBjb25zdCByYXcgPSBwcm9jZXNzLmVudi5XT1JLRkxPV19PUFRJTUlTVElDX0lOTElORV9TVEFSVDtcbiAgaWYgKHJhdyA9PT0gdW5kZWZpbmVkIHx8IHJhdyA9PT0gJycpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIHJhdyA9PT0gJzEnIHx8IHJhdy50b0xvd2VyQ2FzZSgpID09PSAndHJ1ZSc7XG59XG5cbi8qKlxuICogV2hldGhlciBhbiBvcGVyYXRvciBoYXMgKipleHBsaWNpdGx5IGRpc2FibGVkKiogb3B0aW1pc3RpYyBpbmxpbmUgc3RhcnQgdmlhXG4gKiBgV09SS0ZMT1dfT1BUSU1JU1RJQ19JTkxJTkVfU1RBUlQ9MGAgLyBgPWZhbHNlYC4gRGlzdGluY3QgZnJvbSBcInVuc2V0XCI6IHVuc2V0XG4gKiBsZWF2ZXMgdGhlIG9wdGltaXphdGlvbiBvZmYgYnkgZGVmYXVsdCBidXQgbGV0cyB0dXJibyBmb3JjZSBpdCBvbjsgYW4gZXhwbGljaXRcbiAqIGAwYC9gZmFsc2VgIGlzIGFuIG9wZXJhdG9yIG9wdC1vdXQgdGhhdCB0dXJibyBtdXN0IGhvbm9yICh0dXJibydzIGZvcmNlZFxuICogb3B0aW1pc3RpYyBzdGFydCBzdGlsbCBydW5zIGEgc3RlcCBib2R5IGJlZm9yZSBgc3RlcF9zdGFydGVkYC9gcnVuX3N0YXJ0ZWRgIGlzXG4gKiBjb25maXJtZWQsIHRoZSBwcm9wZXJ0eSBzdWNoIGFuIG9wZXJhdG9yIGlzIG9wdGluZyBvdXQgb2YpLCBzb1xuICogYGZvcmNlT3B0aW1pc3RpY1N0YXJ0YCBkZWZlcnMgdG8gdGhpcy4gUmVhZHMgdGhlIGVudiB2YXIgbGF6aWx5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNPcHRpbWlzdGljSW5saW5lU3RhcnRFeHBsaWNpdGx5RGlzYWJsZWQoKTogYm9vbGVhbiB7XG4gIGNvbnN0IHJhdyA9IHByb2Nlc3MuZW52LldPUktGTE9XX09QVElNSVNUSUNfSU5MSU5FX1NUQVJUO1xuICBpZiAocmF3ID09PSB1bmRlZmluZWQgfHwgcmF3ID09PSAnJykgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gcmF3ID09PSAnMCcgfHwgcmF3LnRvTG93ZXJDYXNlKCkgPT09ICdmYWxzZSc7XG59XG5cbi8qKlxuICogV2hldGhlciBcInR1cmJvIG1vZGVcIiBpcyBlbmFibGVkLiBUdXJibyBtb2RlIGZhc3QtcGF0aHMgdGhlICpmaXJzdCBkZWxpdmVyeSBvZlxuICogdGhlIGZpcnN0IGludm9jYXRpb24qIG9mIGEgcnVuIChkZXRlY3RlZCBieSB0aGUgZW50cnlwb2ludCB2aWEgYHJ1bklucHV0YFxuICogcHJlc2VuY2UgKyBgbWV0YWRhdGEuYXR0ZW1wdCA9PT0gMWApOiBpdCBiYWNrZ3JvdW5kcyB0aGUgYHJ1bl9zdGFydGVkYCBldmVudFxuICogY3JlYXRpb24sIHNraXBzIHRoZSBpbml0aWFsIGV2ZW50LWxvZyBsb2FkIChub3RoaW5nIGhhcyBiZWVuIHdyaXR0ZW4geWV0KSxcbiAqIGFuZCBmb3JjZXMgb3B0aW1pc3RpYyBpbmxpbmUgc3RlcCBzdGFydCBmb3IgdGhhdCBpbnZvY2F0aW9uIOKAlCBpbmRlcGVuZGVudCBvZlxuICogYFdPUktGTE9XX09QVElNSVNUSUNfSU5MSU5FX1NUQVJUYC5cbiAqXG4gKiBGb3JjaW5nIG9wdGltaXN0aWMgc3RhcnQgaXMgc2FmZSBoZXJlIGJlY2F1c2UgdGhlIGZpcnN0IGRlbGl2ZXJ5IGhhcyBub1xuICogY29uY3VycmVudCBwZWVyIGhhbmRsZXIgdG8gcmFjZSB0aGUgc3RlcCBjcmVhdGUtY2xhaW0sIHNvIGEgc3RlcCBib2R5IHJ1bnNcbiAqIGV4YWN0bHkgb25jZS4gVGhhdCBzaW5nbGUtaGFuZGxlciBndWFyYW50ZWUgZW5kcyBhcyBzb29uIGFzIHRoZSBydW4gY3JlYXRlcyBhXG4gKiBob29rIG9yIHdhaXQgKHdoaWNoIGludHJvZHVjZSByZXN1bWUvcGFyYWxsZWwgaW52b2NhdGlvbnMpLCBzbyB0aGUgcnVudGltZVxuICogZXhpdHMgdHVyYm8gYXQgdGhhdCBwb2ludC5cbiAqXG4gKiBSZWFkcyBgcHJvY2Vzcy5lbnYuV09SS0ZMT1dfVFVSQk9gIGxhemlseS4gRGVmYXVsdCAqKk9OKio7IGRpc2FibGVkIG9ubHkgYnkgYW5cbiAqIGV4cGxpY2l0IGAnMCdgIC8gYCdmYWxzZSdgIChjYXNlLWluc2Vuc2l0aXZlKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVHVyYm9FbmFibGVkKCk6IGJvb2xlYW4ge1xuICBjb25zdCByYXcgPSBwcm9jZXNzLmVudi5XT1JLRkxPV19UVVJCTztcbiAgaWYgKHJhdyA9PT0gdW5kZWZpbmVkIHx8IHJhdyA9PT0gJycpIHJldHVybiB0cnVlO1xuICByZXR1cm4gIShyYXcgPT09ICcwJyB8fCByYXcudG9Mb3dlckNhc2UoKSA9PT0gJ2ZhbHNlJyk7XG59XG5cbi8qKlxuICogV2hldGhlciB0aGUgaW5saW5lIGxvb3AgcmV0YWlucyBhIHN1c3BlbmRlZCB3b3JrZmxvdyBWTSBhY3Jvc3MgaW5saW5lIHN0ZXBzXG4gKiB3aXRoaW4gb25lIGludm9jYXRpb24gKGRlZmF1bHQgT04pLiBXaGVuIG9uLCBhIHN0ZXAtb25seSBzdXNwZW5zaW9uIGtlZXBzXG4gKiB0aGUgbGl2ZSBWTSwgZXZlbnQgY29uc3VtZXIsIGFuZCBoeWRyYXRlZCBzdGF0ZSBhbGl2ZSwgYW5kIHRoZSBuZXh0IGxvb3BcbiAqIGl0ZXJhdGlvbiBhcHBlbmRzIG9ubHkgdGhlIG5ld2x5IGR1cmFibGUgZXZlbnRzIGluc3RlYWQgb2YgcmVidWlsZGluZyB0aGVcbiAqIGB2bS5Db250ZXh0YCBhbmQgcmVwbGF5aW5nIHRoZSB3aG9sZSBldmVudCBsb2cuIE5vbi1zdGVwIHN1c3BlbnNpb25zIGFuZFxuICogcmVwbGF5IGRpdmVyZ2VuY2UgYWx3YXlzIGZhbGwgYmFjayB0byB0aGUgb3JkaW5hcnkgZHVyYWJsZSByZXBsYXkgcGF0aC5cbiAqXG4gKiBgV09SS0ZMT1dfUkVUQUlORURfVk09MGAgKG9yIGBmYWxzZWApIGlzIHRoZSBraWxsIHN3aXRjaDogZXZlcnkgaXRlcmF0aW9uXG4gKiByZXBsYXlzIGZyb20gc2NyYXRjaCBpbiBhIGZyZXNoIFZNLCBtYXRjaGluZyB0aGUgcHJlLXJldGVudGlvbiBiZWhhdmlvci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVm1SZXRlbnRpb25FbmFibGVkKCk6IGJvb2xlYW4ge1xuICBjb25zdCByYXcgPSBwcm9jZXNzLmVudi5XT1JLRkxPV19SRVRBSU5FRF9WTTtcbiAgaWYgKHJhdyA9PT0gdW5kZWZpbmVkIHx8IHJhdyA9PT0gJycpIHJldHVybiB0cnVlO1xuICByZXR1cm4gIShyYXcgPT09ICcwJyB8fCByYXcudG9Mb3dlckNhc2UoKSA9PT0gJ2ZhbHNlJyk7XG59XG5cbi8qKlxuICogV2hldGhlciBpbmxpbmUgc3RlcCBvd25lcnNoaXAgaXMgZW5hYmxlZCAoZGVmYXVsdCBPTikuIFdoZW4gb24sIHRoZSBsYXp5XG4gKiBgc3RlcF9zdGFydGVkYCB0aGF0IGNyZWF0ZXMgYW4gaW5saW5lIHN0ZXAgcmVjb3JkcyB0aGUgb3duaW5nIHF1ZXVlXG4gKiBtZXNzYWdlIElELCBhbmQgd2FrZSByZXBsYXlzIHRoYXQgb2JzZXJ2ZSBhbiBhY3RpdmVseS1vd25lZCBzdGVwIGVucXVldWUgYVxuICogKmRlbGF5ZWQgYmFja3N0b3AqIG1lc3NhZ2UgaW5zdGVhZCBvZiBpbW1lZGlhdGVseSByZXF1ZXVlaW5nIGl0IOKAlCBmaXhpbmdcbiAqIGR1cGxpY2F0ZSBpbmxpbmUgc3RlcCBleGVjdXRpb24gd2hlbiBhIGhvb2svd2FpdCB3YWtlcyBhIHJ1biBtaWQtc3RlcFxuICogKHZlcmNlbC93b3JrZmxvdyMyNzgwKS5cbiAqXG4gKiBgV09SS0ZMT1dfSU5MSU5FX09XTkVSU0hJUD0wYCAob3IgYGZhbHNlYCkgaXMgdGhlIGtpbGwgc3dpdGNoOiBkaXNwYXRjaFxuICogcmV2ZXJ0cyB0byB0aGUgdW5jb25kaXRpb25hbCBpbW1lZGlhdGUgcmVxdWV1ZS4gU3RhbXBpbmcgaXMgdW5hZmZlY3RlZCDigJRcbiAqIHRoZSByZWNvcmRlZCBvd25lck1lc3NhZ2VJZCBpcyBpbmVydCBkYXRhIHdoZW4gdGhlIHN3aXRjaCBpcyBvZmYuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0lubGluZU93bmVyc2hpcEVuYWJsZWQoKTogYm9vbGVhbiB7XG4gIGNvbnN0IHJhdyA9IHByb2Nlc3MuZW52LldPUktGTE9XX0lOTElORV9PV05FUlNISVA7XG4gIGlmIChyYXcgPT09IHVuZGVmaW5lZCB8fCByYXcgPT09ICcnKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuICEocmF3ID09PSAnMCcgfHwgcmF3LnRvTG93ZXJDYXNlKCkgPT09ICdmYWxzZScpO1xufVxuXG4vKipcbiAqIERlZmF1bHQgaW5saW5lLW93bmVyc2hpcCBsZWFzZSwgaW4gc2Vjb25kczogaG93IGxvbmcgYWZ0ZXIgYSBzdGVwJ3MgbGF0ZXN0XG4gKiAoc3RhbXBlZCkgYHN0ZXBfc3RhcnRlZGAgYSBub24tb3duZXIgaW52b2NhdGlvbiBhc3N1bWVzIHRoZSBvd25pbmdcbiAqIGludm9jYXRpb24gbWF5IHN0aWxsIGJlIGFsaXZlLiBXaXRoaW4gdGhlIGxlYXNlLCB3YWtlIHJlcGxheXMgZW5xdWV1ZSB0aGVcbiAqIHN0ZXAncyBiYWNrc3RvcCBtZXNzYWdlIHdpdGggYGRlbGF5U2Vjb25kcyA9IGxlYXNlIHJlbWFpbmluZ2AgaW5zdGVhZCBvZlxuICogaW1tZWRpYXRlbHk7IHBhc3QgaXQsIHRoZXkgZW5xdWV1ZSBpbW1lZGlhdGVseSAodG9kYXkncyBiZWhhdmlvcikuXG4gKlxuICogV2h5IGEgZml4ZWQgODYwIGFuZCBub3QgYSB2YWx1ZSBkZXJpdmVkIGZyb20gdGhlIGZ1bmN0aW9uJ3MgYG1heER1cmF0aW9uYDpcbiAqIG5laXRoZXIgcnVudGltZSBub3IgYnVpbGQgdGltZSBjYW4gc2VlIHRoZSByZXNvbHZlZCB2YWx1ZSDigJQgYnVpbGRlcnMgZW1pdFxuICogYG1heER1cmF0aW9uOiAnbWF4J2AsIHdoaWNoIHRoZSBwbGF0Zm9ybSByZXNvbHZlcyBwZXItcGxhbiBhdCBkZXBsb3ksIGFuZFxuICogbm8gZW52IHZhciBvciByZXF1ZXN0LWNvbnRleHQgZGVhZGxpbmUgQVBJIGV4cG9zZXMgdGhlIHJlc3VsdC4gVGhlIGJvdW5kXG4gKiBjb21lcyBmcm9tIGEgcGxhdGZvcm0gcnVsZSBpbnN0ZWFkOiBkdXJhdGlvbnMgYWJvdmUgODAwcyByZXF1aXJlIGV4cGxpY2l0XG4gKiBwZXItZnVuY3Rpb24gbnVtZXJpYyBjb25maWcsIHNvIGEgYnVpbGRlci1lbWl0dGVkIGAnbWF4J2AgcmVzb2x2ZXMgdG8gYXRcbiAqIG1vc3QgODAwcyDigJQgODYwcyB0aGVyZWZvcmUgZG9taW5hdGVzIGFueSB3b3JrZmxvdyByb3V0ZSdzIGludm9jYXRpb25cbiAqIGxpZmV0aW1lIHBsdXMgc2NoZWR1bGluZyBzbGFjay4gUmV2aXNpdCB3aGVuIHRoYXQgY2VpbGluZyBtb3ZlcyAodGhlXG4gKiAzMC1taW51dGUgZHVyYXRpb24gYmV0YSBiZWNvbWluZyByZWFjaGFibGUgdmlhIGAnbWF4J2Agd291bGQgaW52YWxpZGF0ZVxuICogdGhlIGJvdW5kKS4gV29ybGRzIHdpdGhvdXQgYW4gaW52b2NhdGlvbiBraWxsIGJvdW5kICh3b3JsZC1sb2NhbCxcbiAqIHNlbGYtaG9zdGVkKSBnZXQgbm8gZGVhdGggcHJvb2YgZnJvbSBhbnkgY29uc3RhbnQg4oCUIHRoZXJlIHRoZSBpbi1wcm9jZXNzXG4gKiBzaW5nbGUtZmxpZ2h0IGxheWVyIChzdGVwLXNpbmdsZS1mbGlnaHQudHMpIGlzIHdoYXQgbWFrZXMgYSBiYWNrc3RvcFxuICogZmlyaW5nIG1pZC1zdGVwIGhhcm1sZXNzLlxuICpcbiAqIDg2MCBhbHNvIHN0YXlzIHVuZGVyIHRoZSBxdWV1ZSdzIDkwMHMgbWF4aW11bSBkZWxheSAoU1FTIGNhcCksIHNvIGFcbiAqIGJhY2tzdG9wJ3MgZnVsbCBsZWFzZSByZW1haW5kZXIgYWx3YXlzIGZpdHMgaW4gYSBzaW5nbGUgZGVsYXllZCBtZXNzYWdlLlxuICpcbiAqIE92ZXJyaWRlIHZpYSBgV09SS0ZMT1dfSU5MSU5FX09XTkVSU0hJUF9MRUFTRV9TRUNPTkRTYCAoY2xhbXBlZCB0b1xuICogMS4uYE1BWF9JTkxJTkVfT1dORVJTSElQX0xFQVNFX1NFQ09ORFNgKS5cbiAqL1xuZXhwb3J0IGNvbnN0IElOTElORV9PV05FUlNISVBfTEVBU0VfU0VDT05EUyA9IDg2MDtcblxuLyoqXG4gKiBVcHBlciBib3VuZCBmb3IgdGhlIGxlYXNlIGVudiBvdmVycmlkZS4gOTAwcyBpcyB0aGUgcXVldWUncyBtYXhpbXVtXG4gKiBwZXItbWVzc2FnZSBkZWxheSAoU1FTIGNhcCkg4oCUIGEgbG9uZ2VyIGxlYXNlIHdvdWxkIG5lZWQgZGVsYXkgY2hhaW5pbmdcbiAqIGxpa2UgbG9uZyB3YWl0cyB1c2U7IGNsYW1wIGluc3RlYWQgc28gb25lIGRlbGF5ZWQgbWVzc2FnZSBhbHdheXMgc3VmZmljZXMuXG4gKi9cbmV4cG9ydCBjb25zdCBNQVhfSU5MSU5FX09XTkVSU0hJUF9MRUFTRV9TRUNPTkRTID0gOTAwO1xuXG4vKipcbiAqIEVmZmVjdGl2ZSBpbmxpbmUtb3duZXJzaGlwIGxlYXNlLiBPdmVycmlkZSB2aWFcbiAqIGBXT1JLRkxPV19JTkxJTkVfT1dORVJTSElQX0xFQVNFX1NFQ09ORFNgIOKAlCBlLmcuIHJhaXNlIGl0IG9uIHNlbGYtaG9zdGVkXG4gKiBtdWx0aS1pbnN0YW5jZSB3b3JsZHMgd2l0aCBsb25nLXJ1bm5pbmcgc3RlcHMgdG8gd2lkZW4gdGhlIHdpbmRvdyBpbiB3aGljaFxuICogYSBsaXZlIG93bmVyIGlzIHByb3RlY3RlZCBmcm9tIGEgY29uY3VycmVudCBiYWNrc3RvcCBleGVjdXRpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRJbmxpbmVPd25lcnNoaXBMZWFzZVNlY29uZHMoKTogbnVtYmVyIHtcbiAgcmV0dXJuIGVudk51bWJlcihcbiAgICAnV09SS0ZMT1dfSU5MSU5FX09XTkVSU0hJUF9MRUFTRV9TRUNPTkRTJyxcbiAgICBJTkxJTkVfT1dORVJTSElQX0xFQVNFX1NFQ09ORFMsXG4gICAgeyBpbnRlZ2VyOiB0cnVlLCBtaW46IDEsIG1heDogTUFYX0lOTElORV9PV05FUlNISVBfTEVBU0VfU0VDT05EUyB9XG4gICk7XG59XG5cbi8vIEEgcmVwbGF5LWNvbnN1bWVyIG1pc21hdGNoIGNhbiBiZSBjYXVzZWQgYnkgYSB0cmFuc2llbnQgZGl2ZXJnZW50IHJlcGxheVxuLy8gcmF0aGVyIHRoYW4gYW4gaW52YWxpZCBwZXJzaXN0ZWQgaGlzdG9yeS4gUXVldWUgYm91bmRlZCByZWNvdmVyeSByZXBsYXlzXG4vLyBiZWZvcmUgcmVjb3JkaW5nIHRlcm1pbmFsIGNvcnJ1cHRpb24gZm9yIGEgcnVuIHRoYXQgY2Fubm90IHJlcGxheS5cbmV4cG9ydCBjb25zdCBSRVBMQVlfRElWRVJHRU5DRV9NQVhfUkVUUklFUyA9IDM7XG5cbi8qKlxuICogRWZmZWN0aXZlIHJlcGxheS1kaXZlcmdlbmNlIHJlY292ZXJ5IGJ1ZGdldC4gT3ZlcnJpZGUgdmlhXG4gKiBgV09SS0ZMT1dfUkVQTEFZX0RJVkVSR0VOQ0VfTUFYX1JFVFJJRVNgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVwbGF5RGl2ZXJnZW5jZU1heFJldHJpZXMoKTogbnVtYmVyIHtcbiAgcmV0dXJuIGVudk51bWJlcihcbiAgICAnV09SS0ZMT1dfUkVQTEFZX0RJVkVSR0VOQ0VfTUFYX1JFVFJJRVMnLFxuICAgIFJFUExBWV9ESVZFUkdFTkNFX01BWF9SRVRSSUVTLFxuICAgIHsgaW50ZWdlcjogdHJ1ZSB9XG4gICk7XG59XG5cbi8vIEEgc3RhbGUtc25hcHNob3QgcmVqZWN0aW9uICg0MTIpIG1lYW5zIHRoZSByZXBsYXkncyBldmVudCBsb2cgd2FzIG1pc3NpbmcgYW5cbi8vIGV2ZW50IHRoZSBXb3JsZCBoYWQgYWxyZWFkeSByZWNvcmRlZCwgc28gdGhlIHJlcGxheSBpcyByZS1kZXJpdmVkIGZyb20gYVxuLy8gY29ycmVjdGVkIGxvZyBpbnNpZGUgdGhlIHNhbWUgaW52b2NhdGlvbi4gQm91bmRlZCBiZWNhdXNlIGEgcGVyc2lzdGVudGx5XG4vLyByZWplY3RlZCB3cml0ZSBzaG91bGQgZXNjYWxhdGUgcmF0aGVyIHRoYW4gc3BpbjogYWZ0ZXIgdGhpcyBtYW55IHJlc3RhcnRzIHRoZVxuLy8gcnVuIGlzIHJlLWludm9rZWQgKGEgbmV3IGludm9jYXRpb24sIHBvc3NpYmx5IGluIGEgZGlmZmVyZW50IHJlZ2lvbiksIGFuZCB0aGVcbi8vIHJ1bi1sZXZlbCBidWRnZXQgYmVsb3cgdGhlbiBhcHBsaWVzLlxuZXhwb3J0IGNvbnN0IFBSRUNPTkRJVElPTl9NQVhfSU5QUk9DRVNTX1JFU1RBUlRTID0gMztcblxuLyoqXG4gKiBFZmZlY3RpdmUgaW4tcHJvY2VzcyByZXBsYXktcmVzdGFydCBidWRnZXQgZm9yIHN0YWxlLXNuYXBzaG90IHJlamVjdGlvbnMuXG4gKiBPdmVycmlkZSB2aWEgYFdPUktGTE9XX1BSRUNPTkRJVElPTl9NQVhfSU5QUk9DRVNTX1JFU1RBUlRTYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFByZWNvbmRpdGlvbk1heEluUHJvY2Vzc1Jlc3RhcnRzKCk6IG51bWJlciB7XG4gIHJldHVybiBlbnZOdW1iZXIoXG4gICAgJ1dPUktGTE9XX1BSRUNPTkRJVElPTl9NQVhfSU5QUk9DRVNTX1JFU1RBUlRTJyxcbiAgICBQUkVDT05ESVRJT05fTUFYX0lOUFJPQ0VTU19SRVNUQVJUUyxcbiAgICB7IGludGVnZXI6IHRydWUgfVxuICApO1xufVxuXG4vLyBUaGUgaW4tcHJvY2VzcyBidWRnZXQgYWJvdmUgaXMgcGVyLWludm9jYXRpb24sIGFuZCBhIHJlLWludm9jYXRpb24gdGhhdFxuLy8gZW5xdWV1ZXMgYSBmcmVzaCBtZXNzYWdlIGFsc28gcmVzdGFydHMgdGhlIHF1ZXVlJ3MgZGVsaXZlcnkgY291bnQsIHNvIHdpdGhvdXRcbi8vIGEgY291bnRlciBjYXJyaWVkIG9uIHRoZSBtZXNzYWdlIGEgcGVybWFuZW50bHkgZmVuY2VkIHJ1biBoYXMgbm8gcnVuLWxldmVsXG4vLyBib3VuZCBhdCBhbGwuIEl0IGNhbiBzdGF5IGZlbmNlZCB3aXRob3V0IGFueSBwZXJtYW5lbnQgZmF1bHQg4oCUIGEgZnVsbCByZWxvYWRcbi8vIGlzIG5vdCBhdG9taWMgYWNyb3NzIHBhZ2VzLCBzbyBhIGJ1c3kgcnVuIGNhbiBhY3F1aXJlIGEgbmV3IGhvbGUgb24gZXZlcnlcbi8vIHJlbG9hZCDigJQgc28gdGhlIGNoYWluIGlzIGNvdW50ZWQgYW5kIHRoZSBydW4gZmFpbHMgb25jZSB0aGlzIG1hbnlcbi8vIHJlLWludm9jYXRpb25zIGhhdmUgYmVlbiBzcGVudCBvbiBzdGFsZS1zbmFwc2hvdCByZWplY3Rpb25zLlxuZXhwb3J0IGNvbnN0IFBSRUNPTkRJVElPTl9NQVhfUkVJTlZPQ0FUSU9OUyA9IDU7XG5cbi8qKlxuICogRWZmZWN0aXZlIHBlci1ydW4gYnVkZ2V0IGZvciByZS1pbnZvY2F0aW9ucyBjYXVzZWQgYnkgc3RhbGUtc25hcHNob3RcbiAqIHJlamVjdGlvbnMuIE92ZXJyaWRlIHZpYSBgV09SS0ZMT1dfUFJFQ09ORElUSU9OX01BWF9SRUlOVk9DQVRJT05TYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFByZWNvbmRpdGlvbk1heFJlaW52b2NhdGlvbnMoKTogbnVtYmVyIHtcbiAgcmV0dXJuIGVudk51bWJlcihcbiAgICAnV09SS0ZMT1dfUFJFQ09ORElUSU9OX01BWF9SRUlOVk9DQVRJT05TJyxcbiAgICBQUkVDT05ESVRJT05fTUFYX1JFSU5WT0NBVElPTlMsXG4gICAgeyBpbnRlZ2VyOiB0cnVlIH1cbiAgKTtcbn1cblxuLy8gQmFja29mZiBiZWZvcmUgYSBwcmVjb25kaXRpb24gcmUtaW52b2NhdGlvbi4gVW5saWtlIHRoZSBpbi1wcm9jZXNzIHJlc3RhcnRcbi8vICh3aGVyZSB0aGUgcG9pbnQgaXMgdG8gcmUtcmVhZCBpbW1lZGlhdGVseSksIGEgcmUtaW52b2NhdGlvbiBvbmx5IGhhcHBlbnNcbi8vIGFmdGVyIHRoZSBpbi1wcm9jZXNzIGJ1ZGdldCBmYWlsZWQgdG8gY2F0Y2ggdXAsIHNvIHRoZSBsb2cgaXMgYmVpbmcgZXh0ZW5kZWRcbi8vIGZhc3RlciB0aGFuIHRoaXMgcmVwbGF5IGNhbiBmb2xsb3cgaXQuIFdhaXRpbmcgbGV0cyB0aGUgd3JpdGVycyBxdWllc2NlLlxuZXhwb3J0IGNvbnN0IFBSRUNPTkRJVElPTl9SRUlOVk9LRV9ERUxBWV9TRUNPTkRTID0gMjtcblxuLyoqXG4gKiBFZmZlY3RpdmUgZGVsYXkgYmVmb3JlIGEgcHJlY29uZGl0aW9uIHJlLWludm9jYXRpb24uIE92ZXJyaWRlIHZpYVxuICogYFdPUktGTE9XX1BSRUNPTkRJVElPTl9SRUlOVk9LRV9ERUxBWV9TRUNPTkRTYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFByZWNvbmRpdGlvblJlaW52b2tlRGVsYXlTZWNvbmRzKCk6IG51bWJlciB7XG4gIHJldHVybiBlbnZOdW1iZXIoXG4gICAgJ1dPUktGTE9XX1BSRUNPTkRJVElPTl9SRUlOVk9LRV9ERUxBWV9TRUNPTkRTJyxcbiAgICBQUkVDT05ESVRJT05fUkVJTlZPS0VfREVMQVlfU0VDT05EUyxcbiAgICB7IGludGVnZXI6IHRydWUgfVxuICApO1xufVxuXG4vLyBBIGRlbGl2ZXJ5IHJlYWNoaW5nIGEgZGVwbG95bWVudCB0aGUgcnVuIGlzIG5vdCBwaW5uZWQgdG8gaXMgbm90IHRyZWF0ZWQgYXNcbi8vIHBlcm1hbmVudC4gUmUtcm91dGUgdGhlIG1lc3NhZ2UgYXQgdGhlIHJ1bidzIG93biBkZXBsb3ltZW50IGEgYm91bmRlZCBudW1iZXJcbi8vIG9mIHRpbWVzIGJlZm9yZSBmYWlsaW5nIHRoZSBydW4gd2l0aCBERVBMT1lNRU5UX01JU01BVENILlxuZXhwb3J0IGNvbnN0IERFUExPWU1FTlRfTUlTTUFUQ0hfTUFYX1JFVFJJRVMgPSAzO1xuXG4vKipcbiAqIEVmZmVjdGl2ZSBkZXBsb3ltZW50LW1pc21hdGNoIHJlLXJvdXRlIGJ1ZGdldC4gT3ZlcnJpZGUgdmlhXG4gKiBgV09SS0ZMT1dfREVQTE9ZTUVOVF9NSVNNQVRDSF9NQVhfUkVUUklFU2A7IGAwYCBmYWlscyB0aGUgcnVuIG9uIHRoZSBmaXJzdFxuICogbWlzcm91dGVkIGRlbGl2ZXJ5IGluc3RlYWQgb2YgYXR0ZW1wdGluZyByZWNvdmVyeS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERlcGxveW1lbnRNaXNtYXRjaE1heFJldHJpZXMoKTogbnVtYmVyIHtcbiAgcmV0dXJuIGVudk51bWJlcihcbiAgICAnV09SS0ZMT1dfREVQTE9ZTUVOVF9NSVNNQVRDSF9NQVhfUkVUUklFUycsXG4gICAgREVQTE9ZTUVOVF9NSVNNQVRDSF9NQVhfUkVUUklFUyxcbiAgICB7IGludGVnZXI6IHRydWUsIG1pbjogMCB9XG4gICk7XG59XG4iXX0=
@@ -0,0 +1,99 @@
1
+ import { type WorkflowRun, type World } from '@workflow/world';
2
+ /**
3
+ * How the guard resolved a delivery. Both non-`continue` outcomes mean the
4
+ * caller must ack the message and return without executing anything.
5
+ */
6
+ export type DeploymentAffinityOutcome =
7
+ /** The run belongs here (or this world has no deployment affinity). */
8
+ 'continue'
9
+ /** Misrouted; re-enqueued at the run's own deployment. */
10
+ | 'rerouted'
11
+ /** Misrouted and out of budget (or unroutable); `run_failed` recorded. */
12
+ | 'failed';
13
+ /**
14
+ * `spanAttributes` is present only on a misrouted delivery — mismatches are
15
+ * rare, so the presence of `workflow.deployment.pinned_id` on a span *is* the
16
+ * signal that one happened, and `recovered` separates the ones a re-route fixed
17
+ * from the ones that kept misrouting.
18
+ */
19
+ export interface DeploymentAffinityResult {
20
+ outcome: DeploymentAffinityOutcome;
21
+ spanAttributes?: Record<string, string | number | boolean>;
22
+ }
23
+ /**
24
+ * Arguments handed to a call site's re-enqueue closure. The guard owns the
25
+ * policy — counting, backoff, logging, telemetry, escalation — and the call
26
+ * site owns only the shape of the message it needs to put back on the queue.
27
+ */
28
+ export interface ReenqueueArgs {
29
+ /** The deployment to target: the one the run is pinned to. */
30
+ deploymentId: string;
31
+ /**
32
+ * The run's spec version, so the world picks the right queue transport
33
+ * (CBOR vs JSON). Undefined on legacy runs that predate the field; worlds
34
+ * then fall back to their current default.
35
+ */
36
+ specVersion: number | undefined;
37
+ deploymentMismatchRetryCount: number;
38
+ /** Backoff before the re-routed message becomes visible. */
39
+ delaySeconds: number;
40
+ }
41
+ /**
42
+ * Guards deployment affinity: a run may only execute on the deployment it is
43
+ * pinned to.
44
+ *
45
+ * A run's `deploymentId` is fixed when it starts — the deployment that called
46
+ * `start()`, or whatever `start({ deploymentId })` resolved to (an explicit id
47
+ * or `'latest'`) — and no replay or step execution may happen anywhere else:
48
+ * the bundles here may not match the run's persisted history, and any step
49
+ * dispatched from here derives the per-run encryption key from the wrong
50
+ * deployment's master key, which surfaces as a `RuntimeDecryptionError` the
51
+ * queue retry callback swallows into a blank "exceeded max retries".
52
+ *
53
+ * A misrouted delivery is not treated as permanent. Rather than failing
54
+ * immediately, re-enqueue the message *explicitly targeted* at the run's own
55
+ * deployment; that send is strictly better-addressed than the one that
56
+ * misrouted, which inherited the producing deployment's ambient id. Fail only
57
+ * once the budget (`WORKFLOW_DEPLOYMENT_MISMATCH_MAX_RETRIES`, default 3) is
58
+ * spent, mirroring how a replay divergence gets bounded recovery replays before
59
+ * being recorded as a corrupted event log.
60
+ *
61
+ * Callers must pass a run entity they already have in hand — every call site
62
+ * loads the run for other reasons — so the guard costs no extra round trip.
63
+ * (`world.getDeploymentId()` reads the ambient deployment id, e.g.
64
+ * `VERCEL_DEPLOYMENT_ID`, and does not call the backend either.)
65
+ *
66
+ * The failure is recorded **without resolving the run's encryption key**: the
67
+ * key is fetched from the pinned deployment's API, often unavailable once that
68
+ * deployment is past its retention window, so depending on it would throw here
69
+ * instead of recording the failure. The payload is written unencrypted (it
70
+ * holds only deployment ids, nothing sensitive), and the plaintext `errorCode`
71
+ * is the signal observability and the UI key off.
72
+ */
73
+ export declare function guardDeploymentAffinity({ world, run, requestId, retryCount, reenqueue, isDeploymentUnavailableError, beforeStop, }: {
74
+ world: World;
75
+ run: Pick<WorkflowRun, 'runId' | 'deploymentId' | 'specVersion'>;
76
+ requestId?: string;
77
+ /** `deploymentMismatchRetryCount` from the incoming message, if any. */
78
+ retryCount?: number;
79
+ /**
80
+ * Puts this delivery's message back on the queue, targeted at the run's own
81
+ * deployment. Omitted by callers that cannot reconstruct their message, which
82
+ * makes the guard fail-fast.
83
+ */
84
+ reenqueue?: (args: ReenqueueArgs) => Promise<void>;
85
+ /**
86
+ * Classifies a re-enqueue failure as definitive proof that the pinned
87
+ * deployment cannot receive the message. Unclassified failures are retried
88
+ * by rejecting the handler and leaving the current queue message unacked.
89
+ */
90
+ isDeploymentUnavailableError?: (error: unknown) => boolean;
91
+ /**
92
+ * Ordering barrier awaited once a mismatch is confirmed, before either
93
+ * stopping action. Under turbo the `run_started` write is backgrounded, and
94
+ * both outcomes hand the run off (to a `run_failed` here, or to the pinned
95
+ * deployment's own `run_started`) — so that write must have landed first.
96
+ */
97
+ beforeStop?: () => Promise<void>;
98
+ }): Promise<DeploymentAffinityResult>;
99
+ //# sourceMappingURL=deployment-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deployment-guard.d.ts","sourceRoot":"","sources":["../../src/runtime/deployment-guard.ts"],"names":[],"mappings":"AAMA,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,KAAK,EACX,MAAM,iBAAiB,CAAC;AASzB;;;GAGG;AACH,MAAM,MAAM,yBAAyB;AACnC,uEAAuE;AACrE,UAAU;AACZ,0DAA0D;GACxD,UAAU;AACZ,0EAA0E;GACxE,QAAQ,CAAC;AAEb;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,yBAAyB,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CAC5D;AAwBD;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,8DAA8D;IAC9D,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,4BAA4B,EAAE,MAAM,CAAC;IACrC,4DAA4D;IAC5D,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,uBAAuB,CAAC,EAC5C,KAAK,EACL,GAAG,EACH,SAAS,EACT,UAAc,EACd,SAAS,EACT,4BAA4B,EAC5B,UAAU,GACX,EAAE;IACD,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,cAAc,GAAG,aAAa,CAAC,CAAC;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD;;;;OAIG;IACH,4BAA4B,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;IAC3D;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAoIpC"}
@@ -0,0 +1,154 @@
1
+ import { EntityConflictError, RUN_ERROR_CODES, RunExpiredError, WorkflowDeploymentMismatchError, } from '@workflow/errors';
2
+ import { SPEC_VERSION_CURRENT, SPEC_VERSION_SUPPORTS_COMPRESSION, } from '@workflow/world';
3
+ import { runtimeLogger } from '../logger.js';
4
+ import { dehydrateRunError } from '../serialization.js';
5
+ import * as Attribute from '../telemetry/semantic-conventions.js';
6
+ import { getDeploymentMismatchMaxRetries } from './constants.js';
7
+ /** Cap on the re-route backoff, in seconds. */
8
+ const MAX_REROUTE_DELAY_SECONDS = 8;
9
+ /** The common case, allocation-free. */
10
+ const CONTINUE = { outcome: 'continue' };
11
+ /**
12
+ * Builds a stopping result. `attempts` is the re-route count *including* this
13
+ * invocation's own attempt, so the span attribute reads as "attempts so far".
14
+ */
15
+ function result(outcome, pinnedDeploymentId, attempts) {
16
+ return {
17
+ outcome,
18
+ spanAttributes: {
19
+ ...Attribute.WorkflowRunPinnedDeploymentId(pinnedDeploymentId),
20
+ ...Attribute.WorkflowDeploymentMismatchRetryCount(attempts),
21
+ ...Attribute.WorkflowDeploymentMismatchRecovered(outcome === 'rerouted'),
22
+ },
23
+ };
24
+ }
25
+ /**
26
+ * Guards deployment affinity: a run may only execute on the deployment it is
27
+ * pinned to.
28
+ *
29
+ * A run's `deploymentId` is fixed when it starts — the deployment that called
30
+ * `start()`, or whatever `start({ deploymentId })` resolved to (an explicit id
31
+ * or `'latest'`) — and no replay or step execution may happen anywhere else:
32
+ * the bundles here may not match the run's persisted history, and any step
33
+ * dispatched from here derives the per-run encryption key from the wrong
34
+ * deployment's master key, which surfaces as a `RuntimeDecryptionError` the
35
+ * queue retry callback swallows into a blank "exceeded max retries".
36
+ *
37
+ * A misrouted delivery is not treated as permanent. Rather than failing
38
+ * immediately, re-enqueue the message *explicitly targeted* at the run's own
39
+ * deployment; that send is strictly better-addressed than the one that
40
+ * misrouted, which inherited the producing deployment's ambient id. Fail only
41
+ * once the budget (`WORKFLOW_DEPLOYMENT_MISMATCH_MAX_RETRIES`, default 3) is
42
+ * spent, mirroring how a replay divergence gets bounded recovery replays before
43
+ * being recorded as a corrupted event log.
44
+ *
45
+ * Callers must pass a run entity they already have in hand — every call site
46
+ * loads the run for other reasons — so the guard costs no extra round trip.
47
+ * (`world.getDeploymentId()` reads the ambient deployment id, e.g.
48
+ * `VERCEL_DEPLOYMENT_ID`, and does not call the backend either.)
49
+ *
50
+ * The failure is recorded **without resolving the run's encryption key**: the
51
+ * key is fetched from the pinned deployment's API, often unavailable once that
52
+ * deployment is past its retention window, so depending on it would throw here
53
+ * instead of recording the failure. The payload is written unencrypted (it
54
+ * holds only deployment ids, nothing sensitive), and the plaintext `errorCode`
55
+ * is the signal observability and the UI key off.
56
+ */
57
+ export async function guardDeploymentAffinity({ world, run, requestId, retryCount = 0, reenqueue, isDeploymentUnavailableError, beforeStop, }) {
58
+ // Deployment affinity is only meaningful in worlds whose deployments are
59
+ // atomic and immutable, which the World declares (world-vercel does) and
60
+ // capabilities default to unsupported. Local and self-hosted worlds report a
61
+ // synthetic deployment id (e.g. `dpl_local@<sdk-version>`) that legitimately
62
+ // differs across SDK versions within one logical environment, so guarding
63
+ // them would fail ordinary local runs after a version bump.
64
+ if (world.capabilities?.deploymentAffinity !== true) {
65
+ return CONTINUE;
66
+ }
67
+ const currentDeploymentId = await world.getDeploymentId();
68
+ if (run.deploymentId === currentDeploymentId) {
69
+ return CONTINUE;
70
+ }
71
+ await beforeStop?.();
72
+ const maxRetries = getDeploymentMismatchMaxRetries();
73
+ const logContext = {
74
+ workflowRunId: run.runId,
75
+ pinnedDeploymentId: run.deploymentId,
76
+ actualDeploymentId: currentDeploymentId,
77
+ retryCount,
78
+ maxRetries,
79
+ };
80
+ /**
81
+ * Records the terminal `run_failed`. Mirrors `recordFatalRunError`: it
82
+ * records and returns rather than throwing, so the caller acks the message
83
+ * instead of letting the queue redeliver a run that is now terminal.
84
+ */
85
+ const failRun = async (recoveryAttempts, cause) => {
86
+ const error = new WorkflowDeploymentMismatchError(run.runId, run.deploymentId, currentDeploymentId, { recoveryAttempts, cause });
87
+ try {
88
+ await world.events.create(run.runId, {
89
+ eventType: 'run_failed',
90
+ specVersion: SPEC_VERSION_CURRENT,
91
+ eventData: {
92
+ // Unencrypted (undefined key): see the note on
93
+ // `guardDeploymentAffinity`. dehydrate/hydrate are self-describing,
94
+ // so this reads back without a key.
95
+ error: await dehydrateRunError(error, run.runId, undefined, undefined, (run.specVersion ?? 0) >= SPEC_VERSION_SUPPORTS_COMPRESSION),
96
+ errorCode: RUN_ERROR_CODES.DEPLOYMENT_MISMATCH,
97
+ },
98
+ }, { requestId });
99
+ }
100
+ catch (failError) {
101
+ // Run already reached a terminal state (a concurrent writer failed it, or
102
+ // it was cancelled/expired) — still stop. Anything else is a transient
103
+ // persistence failure: rethrow so the queue redelivers and we try again.
104
+ if (!EntityConflictError.is(failError) &&
105
+ !RunExpiredError.is(failError)) {
106
+ throw failError;
107
+ }
108
+ }
109
+ return result('failed', run.deploymentId, recoveryAttempts);
110
+ };
111
+ if (reenqueue && retryCount < maxRetries) {
112
+ const attempt = retryCount + 1;
113
+ // Exponential, capped: 1s, 2s, 4s — cheap insurance against a hot
114
+ // re-enqueue loop, and time for a mid-flight routing change to settle.
115
+ const delaySeconds = Math.min(2 ** retryCount, MAX_REROUTE_DELAY_SECONDS);
116
+ try {
117
+ await reenqueue({
118
+ deploymentId: run.deploymentId,
119
+ specVersion: run.specVersion,
120
+ deploymentMismatchRetryCount: attempt,
121
+ delaySeconds,
122
+ });
123
+ runtimeLogger.warn('Workflow run received by a deployment it is not pinned to; re-routing to its own deployment', { ...logContext, attempt, delaySeconds });
124
+ return result('rerouted', run.deploymentId, attempt);
125
+ }
126
+ catch (reenqueueError) {
127
+ // A generic send failure can be transient (429, 5xx, connect/DNS). Do not
128
+ // turn one infrastructure blip into a terminal run failure: reject the
129
+ // handler so the current message remains unacked and is redelivered.
130
+ if (!isDeploymentUnavailableError?.(reenqueueError)) {
131
+ throw reenqueueError;
132
+ }
133
+ // The World explicitly classified the target as unavailable — deleted,
134
+ // aged out of its retention window, or otherwise undiscoverable. Burning
135
+ // the rest of the budget on a deployment that provably cannot be reached
136
+ // only delays the failure, so fail now.
137
+ runtimeLogger.error('Cannot re-route a misrouted workflow run to its own deployment; failing the run', {
138
+ ...logContext,
139
+ attempt,
140
+ errorMessage: reenqueueError instanceof Error
141
+ ? reenqueueError.message
142
+ : String(reenqueueError),
143
+ });
144
+ // Recovery never actually happened, so report 0 attempts and let `cause`
145
+ // explain why.
146
+ return failRun(0, reenqueueError);
147
+ }
148
+ }
149
+ runtimeLogger.error(retryCount > 0
150
+ ? 'Workflow run kept arriving at a deployment it is not pinned to after re-routing; failing the run'
151
+ : 'Workflow run received by a deployment it is not pinned to; failing the run', logContext);
152
+ return failRun(retryCount);
153
+ }
154
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwbG95bWVudC1ndWFyZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydW50aW1lL2RlcGxveW1lbnQtZ3VhcmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLG1CQUFtQixFQUNuQixlQUFlLEVBQ2YsZUFBZSxFQUNmLCtCQUErQixHQUNoQyxNQUFNLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsaUNBQWlDLEdBR2xDLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUM3QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN4RCxPQUFPLEtBQUssU0FBUyxNQUFNLHNDQUFzQyxDQUFDO0FBQ2xFLE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWpFLCtDQUErQztBQUMvQyxNQUFNLHlCQUF5QixHQUFHLENBQUMsQ0FBQztBQXlCcEMsd0NBQXdDO0FBQ3hDLE1BQU0sUUFBUSxHQUE2QixFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsQ0FBQztBQUVuRTs7O0dBR0c7QUFDSCxTQUFTLE1BQU0sQ0FDYixPQUE4QixFQUM5QixrQkFBMEIsRUFDMUIsUUFBZ0I7SUFFaEIsT0FBTztRQUNMLE9BQU87UUFDUCxjQUFjLEVBQUU7WUFDZCxHQUFHLFNBQVMsQ0FBQyw2QkFBNkIsQ0FBQyxrQkFBa0IsQ0FBQztZQUM5RCxHQUFHLFNBQVMsQ0FBQyxvQ0FBb0MsQ0FBQyxRQUFRLENBQUM7WUFDM0QsR0FBRyxTQUFTLENBQUMsbUNBQW1DLENBQUMsT0FBTyxLQUFLLFVBQVUsQ0FBQztTQUN6RTtLQUNGLENBQUM7QUFDSixDQUFDO0FBcUJEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBK0JHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSx1QkFBdUIsQ0FBQyxFQUM1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QU87Z0JBQ3JDLFlBQVk7YUFDYixDQUFDLENBQUM7WUFDSCxhQUFhLENBQUMsSUFBSSxDQUNoQiw2RkFBNkYsRUFDN0YsRUFBRSxHQUFHLFVBQVUsRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLENBQ3pDLENBQUM7WUFDRixPQUFPLE1BQU0sQ0FBQyxVQUFVLEVBQUUsR0FBRyxDQUFDLFlBQVksRUFBRSxPQUFPLENBQUMsQ0FBQztRQUN2RCxDQUFDO1FBQUMsT0FBTyxjQUFjLEVBQUUsQ0FBQztZQUN4QiwwRUFBMEU7WUFDMUUsdUVBQXVFO1lBQ3ZFLHFFQUFxRTtZQUNyRSxJQUFJLENBQUMsNEJBQTRCLEVBQUUsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDO2dCQUNwRCxNQUFNLGNBQWMsQ0FBQztZQUN2QixDQUFDO1lBRUQsdUVBQXVFO1lBQ3ZFLHlFQUF5RTtZQUN6RSx5RUFBeUU7WUFDekUsd0NBQXdDO1lBQ3hDLGFBQWEsQ0FBQyxLQUFLLENBQ2pCLGlGQUFpRixFQUNqRjtnQkFDRSxHQUFHLFVBQVU7Z0JBQ2IsT0FBTztnQkFDUCxZQUFZLEVBQ1YsY0FBYyxZQUFZLEtBQUs7b0JBQzdCLENBQUMsQ0FBQyxjQUFjLENBQUMsT0FBTztvQkFDeEIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUM7YUFDN0IsQ0FDRixDQUFDO1lBQ0YseUVBQXlFO1lBQ3pFLGVBQWU7WUFDZixPQUFPLE9BQU8sQ0FBQyxDQUFDLEVBQUUsY0FBYyxDQUFDLENBQUM7UUFDcEMsQ0FBQztJQUNILENBQUM7SUFFRCxhQUFhLENBQUMsS0FBSyxDQUNqQixVQUFVLEdBQUcsQ0FBQztRQUNaLENBQUMsQ0FBQyxrR0FBa0c7UUFDcEcsQ0FBQyxDQUFDLDRFQUE0RSxFQUNoRixVQUFVLENBQ1gsQ0FBQztJQUNGLE9BQU8sT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQzdCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBFbnRpdHlDb25mbGljdEVycm9yLFxuICBSVU5fRVJST1JfQ09ERVMsXG4gIFJ1bkV4cGlyZWRFcnJvcixcbiAgV29ya2Zsb3dEZXBsb3ltZW50TWlzbWF0Y2hFcnJvcixcbn0gZnJvbSAnQHdvcmtmbG93L2Vycm9ycyc7XG5pbXBvcnQge1xuICBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgU1BFQ19WRVJTSU9OX1NVUFBPUlRTX0NPTVBSRVNTSU9OLFxuICB0eXBlIFdvcmtmbG93UnVuLFxuICB0eXBlIFdvcmxkLFxufSBmcm9tICdAd29ya2Zsb3cvd29ybGQnO1xuaW1wb3J0IHsgcnVudGltZUxvZ2dlciB9IGZyb20gJy4uL2xvZ2dlci5qcyc7XG5pbXBvcnQgeyBkZWh5ZHJhdGVSdW5FcnJvciB9IGZyb20gJy4uL3NlcmlhbGl6YXRpb24uanMnO1xuaW1wb3J0ICogYXMgQXR0cmlidXRlIGZyb20gJy4uL3RlbGVtZXRyeS9zZW1hbnRpYy1jb252ZW50aW9ucy5qcyc7XG5pbXBvcnQgeyBnZXREZXBsb3ltZW50TWlzbWF0Y2hNYXhSZXRyaWVzIH0gZnJvbSAnLi9jb25zdGFudHMuanMnO1xuXG4vKiogQ2FwIG9uIHRoZSByZS1yb3V0ZSBiYWNrb2ZmLCBpbiBzZWNvbmRzLiAqL1xuY29uc3QgTUFYX1JFUk9VVEVfREVMQVlfU0VDT05EUyA9IDg7XG5cbi8qKlxuICogSG93IHRoZSBndWFyZCByZXNvbHZlZCBhIGRlbGl2ZXJ5LiBCb3RoIG5vbi1gY29udGludWVgIG91dGNvbWVzIG1lYW4gdGhlXG4gKiBjYWxsZXIgbXVzdCBhY2sgdGhlIG1lc3NhZ2UgYW5kIHJldHVybiB3aXRob3V0IGV4ZWN1dGluZyBhbnl0aGluZy5cbiAqL1xuZXhwb3J0IHR5cGUgRGVwbG95bWVudEFmZmluaXR5T3V0Y29tZSA9XG4gIC8qKiBUaGUgcnVuIGJlbG9uZ3MgaGVyZSAob3IgdGhpcyB3b3JsZCBoYXMgbm8gZGVwbG95bWVudCBhZmZpbml0eSkuICovXG4gIHwgJ2NvbnRpbnVlJ1xuICAvKiogTWlzcm91dGVkOyByZS1lbnF1ZXVlZCBhdCB0aGUgcnVuJ3Mgb3duIGRlcGxveW1lbnQuICovXG4gIHwgJ3Jlcm91dGVkJ1xuICAvKiogTWlzcm91dGVkIGFuZCBvdXQgb2YgYnVkZ2V0IChvciB1bnJvdXRhYmxlKTsgYHJ1bl9mYWlsZWRgIHJlY29yZGVkLiAqL1xuICB8ICdmYWlsZWQnO1xuXG4vKipcbiAqIGBzcGFuQXR0cmlidXRlc2AgaXMgcHJlc2VudCBvbmx5IG9uIGEgbWlzcm91dGVkIGRlbGl2ZXJ5IOKAlCBtaXNtYXRjaGVzIGFyZVxuICogcmFyZSwgc28gdGhlIHByZXNlbmNlIG9mIGB3b3JrZmxvdy5kZXBsb3ltZW50LnBpbm5lZF9pZGAgb24gYSBzcGFuICppcyogdGhlXG4gKiBzaWduYWwgdGhhdCBvbmUgaGFwcGVuZWQsIGFuZCBgcmVjb3ZlcmVkYCBzZXBhcmF0ZXMgdGhlIG9uZXMgYSByZS1yb3V0ZSBmaXhlZFxuICogZnJvbSB0aGUgb25lcyB0aGF0IGtlcHQgbWlzcm91dGluZy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEZXBsb3ltZW50QWZmaW5pdHlSZXN1bHQge1xuICBvdXRjb21lOiBEZXBsb3ltZW50QWZmaW5pdHlPdXRjb21lO1xuICBzcGFuQXR0cmlidXRlcz86IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4+O1xufVxuXG4vKiogVGhlIGNvbW1vbiBjYXNlLCBhbGxvY2F0aW9uLWZyZWUuICovXG5jb25zdCBDT05USU5VRTogRGVwbG95bWVudEFmZmluaXR5UmVzdWx0ID0geyBvdXRjb21lOiAnY29udGludWUnIH07XG5cbi8qKlxuICogQnVpbGRzIGEgc3RvcHBpbmcgcmVzdWx0LiBgYXR0ZW1wdHNgIGlzIHRoZSByZS1yb3V0ZSBjb3VudCAqaW5jbHVkaW5nKiB0aGlzXG4gKiBpbnZvY2F0aW9uJ3Mgb3duIGF0dGVtcHQsIHNvIHRoZSBzcGFuIGF0dHJpYnV0ZSByZWFkcyBhcyBcImF0dGVtcHRzIHNvIGZhclwiLlxuICovXG5mdW5jdGlvbiByZXN1bHQoXG4gIG91dGNvbWU6ICdyZXJvdXRlZCcgfCAnZmFpbGVkJyxcbiAgcGlubmVkRGVwbG95bWVudElkOiBzdHJpbmcsXG4gIGF0dGVtcHRzOiBudW1iZXJcbik6IERlcGxveW1lbnRBZmZpbml0eVJlc3VsdCB7XG4gIHJldHVybiB7XG4gICAgb3V0Y29tZSxcbiAgICBzcGFuQXR0cmlidXRlczoge1xuICAgICAgLi4uQXR0cmlidXRlLldvcmtmbG93UnVuUGlubmVkRGVwbG95bWVudElkKHBpbm5lZERlcGxveW1lbnRJZCksXG4gICAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dEZXBsb3ltZW50TWlzbWF0Y2hSZXRyeUNvdW50KGF0dGVtcHRzKSxcbiAgICAgIC4uLkF0dHJpYnV0ZS5Xb3JrZmxvd0RlcGxveW1lbnRNaXNtYXRjaFJlY292ZXJlZChvdXRjb21lID09PSAncmVyb3V0ZWQnKSxcbiAgICB9LFxuICB9O1xufVxuXG4vKipcbiAqIEFyZ3VtZW50cyBoYW5kZWQgdG8gYSBjYWxsIHNpdGUncyByZS1lbnF1ZXVlIGNsb3N1cmUuIFRoZSBndWFyZCBvd25zIHRoZVxuICogcG9saWN5IOKAlCBjb3VudGluZywgYmFja29mZiwgbG9nZ2luZywgdGVsZW1ldHJ5LCBlc2NhbGF0aW9uIOKAlCBhbmQgdGhlIGNhbGxcbiAqIHNpdGUgb3ducyBvbmx5IHRoZSBzaGFwZSBvZiB0aGUgbWVzc2FnZSBpdCBuZWVkcyB0byBwdXQgYmFjayBvbiB0aGUgcXVldWUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVlbnF1ZXVlQXJncyB7XG4gIC8qKiBUaGUgZGVwbG95bWVudCB0byB0YXJnZXQ6IHRoZSBvbmUgdGhlIHJ1biBpcyBwaW5uZWQgdG8uICovXG4gIGRlcGxveW1lbnRJZDogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIHJ1bidzIHNwZWMgdmVyc2lvbiwgc28gdGhlIHdvcmxkIHBpY2tzIHRoZSByaWdodCBxdWV1ZSB0cmFuc3BvcnRcbiAgICogKENCT1IgdnMgSlNPTikuIFVuZGVmaW5lZCBvbiBsZWdhY3kgcnVucyB0aGF0IHByZWRhdGUgdGhlIGZpZWxkOyB3b3JsZHNcbiAgICogdGhlbiBmYWxsIGJhY2sgdG8gdGhlaXIgY3VycmVudCBkZWZhdWx0LlxuICAgKi9cbiAgc3BlY1ZlcnNpb246IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgZGVwbG95bWVudE1pc21hdGNoUmV0cnlDb3VudDogbnVtYmVyO1xuICAvKiogQmFja29mZiBiZWZvcmUgdGhlIHJlLXJvdXRlZCBtZXNzYWdlIGJlY29tZXMgdmlzaWJsZS4gKi9cbiAgZGVsYXlTZWNvbmRzOiBudW1iZXI7XG59XG5cbi8qKlxuICogR3VhcmRzIGRlcGxveW1lbnQgYWZmaW5pdHk6IGEgcnVuIG1heSBvbmx5IGV4ZWN1dGUgb24gdGhlIGRlcGxveW1lbnQgaXQgaXNcbiAqIHBpbm5lZCB0by5cbiAqXG4gKiBBIHJ1bidzIGBkZXBsb3ltZW50SWRgIGlzIGZpeGVkIHdoZW4gaXQgc3RhcnRzIOKAlCB0aGUgZGVwbG95bWVudCB0aGF0IGNhbGxlZFxuICogYHN0YXJ0KClgLCBvciB3aGF0ZXZlciBgc3RhcnQoeyBkZXBsb3ltZW50SWQgfSlgIHJlc29sdmVkIHRvIChhbiBleHBsaWNpdCBpZFxuICogb3IgYCdsYXRlc3QnYCkg4oCUIGFuZCBubyByZXBsYXkgb3Igc3RlcCBleGVjdXRpb24gbWF5IGhhcHBlbiBhbnl3aGVyZSBlbHNlOlxuICogdGhlIGJ1bmRsZXMgaGVyZSBtYXkgbm90IG1hdGNoIHRoZSBydW4ncyBwZXJzaXN0ZWQgaGlzdG9yeSwgYW5kIGFueSBzdGVwXG4gKiBkaXNwYXRjaGVkIGZyb20gaGVyZSBkZXJpdmVzIHRoZSBwZXItcnVuIGVuY3J5cHRpb24ga2V5IGZyb20gdGhlIHdyb25nXG4gKiBkZXBsb3ltZW50J3MgbWFzdGVyIGtleSwgd2hpY2ggc3VyZmFjZXMgYXMgYSBgUnVudGltZURlY3J5cHRpb25FcnJvcmAgdGhlXG4gKiBxdWV1ZSByZXRyeSBjYWxsYmFjayBzd2FsbG93cyBpbnRvIGEgYmxhbmsgXCJleGNlZWRlZCBtYXggcmV0cmllc1wiLlxuICpcbiAqIEEgbWlzcm91dGVkIGRlbGl2ZXJ5IGlzIG5vdCB0cmVhdGVkIGFzIHBlcm1hbmVudC4gUmF0aGVyIHRoYW4gZmFpbGluZ1xuICogaW1tZWRpYXRlbHksIHJlLWVucXVldWUgdGhlIG1lc3NhZ2UgKmV4cGxpY2l0bHkgdGFyZ2V0ZWQqIGF0IHRoZSBydW4ncyBvd25cbiAqIGRlcGxveW1lbnQ7IHRoYXQgc2VuZCBpcyBzdHJpY3RseSBiZXR0ZXItYWRkcmVzc2VkIHRoYW4gdGhlIG9uZSB0aGF0XG4gKiBtaXNyb3V0ZWQsIHdoaWNoIGluaGVyaXRlZCB0aGUgcHJvZHVjaW5nIGRlcGxveW1lbnQncyBhbWJpZW50IGlkLiBGYWlsIG9ubHlcbiAqIG9uY2UgdGhlIGJ1ZGdldCAoYFdPUktGTE9XX0RFUExPWU1FTlRfTUlTTUFUQ0hfTUFYX1JFVFJJRVNgLCBkZWZhdWx0IDMpIGlzXG4gKiBzcGVudCwgbWlycm9yaW5nIGhvdyBhIHJlcGxheSBkaXZlcmdlbmNlIGdldHMgYm91bmRlZCByZWNvdmVyeSByZXBsYXlzIGJlZm9yZVxuICogYmVpbmcgcmVjb3JkZWQgYXMgYSBjb3JydXB0ZWQgZXZlbnQgbG9nLlxuICpcbiAqIENhbGxlcnMgbXVzdCBwYXNzIGEgcnVuIGVudGl0eSB0aGV5IGFscmVhZHkgaGF2ZSBpbiBoYW5kIOKAlCBldmVyeSBjYWxsIHNpdGVcbiAqIGxvYWRzIHRoZSBydW4gZm9yIG90aGVyIHJlYXNvbnMg4oCUIHNvIHRoZSBndWFyZCBjb3N0cyBubyBleHRyYSByb3VuZCB0cmlwLlxuICogKGB3b3JsZC5nZXREZXBsb3ltZW50SWQoKWAgcmVhZHMgdGhlIGFtYmllbnQgZGVwbG95bWVudCBpZCwgZS5nLlxuICogYFZFUkNFTF9ERVBMT1lNRU5UX0lEYCwgYW5kIGRvZXMgbm90IGNhbGwgdGhlIGJhY2tlbmQgZWl0aGVyLilcbiAqXG4gKiBUaGUgZmFpbHVyZSBpcyByZWNvcmRlZCAqKndpdGhvdXQgcmVzb2x2aW5nIHRoZSBydW4ncyBlbmNyeXB0aW9uIGtleSoqOiB0aGVcbiAqIGtleSBpcyBmZXRjaGVkIGZyb20gdGhlIHBpbm5lZCBkZXBsb3ltZW50J3MgQVBJLCBvZnRlbiB1bmF2YWlsYWJsZSBvbmNlIHRoYXRcbiAqIGRlcGxveW1lbnQgaXMgcGFzdCBpdHMgcmV0ZW50aW9uIHdpbmRvdywgc28gZGVwZW5kaW5nIG9uIGl0IHdvdWxkIHRocm93IGhlcmVcbiAqIGluc3RlYWQgb2YgcmVjb3JkaW5nIHRoZSBmYWlsdXJlLiBUaGUgcGF5bG9hZCBpcyB3cml0dGVuIHVuZW5jcnlwdGVkIChpdFxuICogaG9sZHMgb25seSBkZXBsb3ltZW50IGlkcywgbm90aGluZyBzZW5zaXRpdmUpLCBhbmQgdGhlIHBsYWludGV4dCBgZXJyb3JDb2RlYFxuICogaXMgdGhlIHNpZ25hbCBvYnNlcnZhYmlsaXR5IGFuZCB0aGUgVUkga2V5IG9mZi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGd1YXJkRGVwbG95bWVudEFmZmluaXR5KHtcbiAgd29ybGQsXG4gIHJ1bixcbiAgcmVxdWVzdElkLFxuICByZXRyeUNvdW50ID0gMCxcbiAgcmVlbnF1ZXVlLFxuICBpc0RlcGxveW1lbnRVbmF2YWlsYWJsZUVycm9yLFxuICBiZWZvcmVTdG9wLFxufToge1xuICB3b3JsZDogV29ybGQ7XG4gIHJ1bjogUGljazxXb3JrZmxvd1J1biwgJ3J1bklkJyB8ICdkZXBsb3ltZW50SWQnIHwgJ3NwZWNWZXJzaW9uJz47XG4gIHJlcXVlc3RJZD86IHN0cmluZztcbiAgLyoqIGBkZXBsb3ltZW50TWlzbWF0Y2hSZXRyeUNvdW50YCBmcm9tIHRoZSBpbmNvbWluZyBtZXNzYWdlLCBpZiBhbnkuICovXG4gIHJldHJ5Q291bnQ/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBQdXRzIHRoaXMgZGVsaXZlcnkncyBtZXNzYWdlIGJhY2sgb24gdGhlIHF1ZXVlLCB0YXJnZXRlZCBhdCB0aGUgcnVuJ3Mgb3duXG4gICAqIGRlcGxveW1lbnQuIE9taXR0ZWQgYnkgY2FsbGVycyB0aGF0IGNhbm5vdCByZWNvbnN0cnVjdCB0aGVpciBtZXNzYWdlLCB3aGljaFxuICAgKiBtYWtlcyB0aGUgZ3VhcmQgZmFpbC1mYXN0LlxuICAgKi9cbiAgcmVlbnF1ZXVlPzogKGFyZ3M6IFJlZW5xdWV1ZUFyZ3MpID0+IFByb21pc2U8dm9pZD47XG4gIC8qKlxuICAgKiBDbGFzc2lmaWVzIGEgcmUtZW5xdWV1ZSBmYWlsdXJlIGFzIGRlZmluaXRpdmUgcHJvb2YgdGhhdCB0aGUgcGlubmVkXG4gICAqIGRlcGxveW1lbnQgY2Fubm90IHJlY2VpdmUgdGhlIG1lc3NhZ2UuIFVuY2xhc3NpZmllZCBmYWlsdXJlcyBhcmUgcmV0cmllZFxuICAgKiBieSByZWplY3RpbmcgdGhlIGhhbmRsZXIgYW5kIGxlYXZpbmcgdGhlIGN1cnJlbnQgcXVldWUgbWVzc2FnZSB1bmFja2VkLlxuICAgKi9cbiAgaXNEZXBsb3ltZW50VW5hdmFpbGFibGVFcnJvcj86IChlcnJvcjogdW5rbm93bikgPT4gYm9vbGVhbjtcbiAgLyoqXG4gICAqIE9yZGVyaW5nIGJhcnJpZXIgYXdhaXRlZCBvbmNlIGEgbWlzbWF0Y2ggaXMgY29uZmlybWVkLCBiZWZvcmUgZWl0aGVyXG4gICAqIHN0b3BwaW5nIGFjdGlvbi4gVW5kZXIgdHVyYm8gdGhlIGBydW5fc3RhcnRlZGAgd3JpdGUgaXMgYmFja2dyb3VuZGVkLCBhbmRcbiAgICogYm90aCBvdXRjb21lcyBoYW5kIHRoZSBydW4gb2ZmICh0byBhIGBydW5fZmFpbGVkYCBoZXJlLCBvciB0byB0aGUgcGlubmVkXG4gICAqIGRlcGxveW1lbnQncyBvd24gYHJ1bl9zdGFydGVkYCkg4oCUIHNvIHRoYXQgd3JpdGUgbXVzdCBoYXZlIGxhbmRlZCBmaXJzdC5cbiAgICovXG4gIGJlZm9yZVN0b3A/OiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xufSk6IFByb21pc2U8RGVwbG95bWVudEFmZmluaXR5UmVzdWx0PiB7XG4gIC8vIERlcGxveW1lbnQgYWZmaW5pdHkgaXMgb25seSBtZWFuaW5nZnVsIGluIHdvcmxkcyB3aG9zZSBkZXBsb3ltZW50cyBhcmVcbiAgLy8gYXRvbWljIGFuZCBpbW11dGFibGUsIHdoaWNoIHRoZSBXb3JsZCBkZWNsYXJlcyAod29ybGQtdmVyY2VsIGRvZXMpIGFuZFxuICAvLyBjYXBhYmlsaXRpZXMgZGVmYXVsdCB0byB1bnN1cHBvcnRlZC4gTG9jYWwgYW5kIHNlbGYtaG9zdGVkIHdvcmxkcyByZXBvcnQgYVxuICAvLyBzeW50aGV0aWMgZGVwbG95bWVudCBpZCAoZS5nLiBgZHBsX2xvY2FsQDxzZGstdmVyc2lvbj5gKSB0aGF0IGxlZ2l0aW1hdGVseVxuICAvLyBkaWZmZXJzIGFjcm9zcyBTREsgdmVyc2lvbnMgd2l0aGluIG9uZSBsb2dpY2FsIGVudmlyb25tZW50LCBzbyBndWFyZGluZ1xuICAvLyB0aGVtIHdvdWxkIGZhaWwgb3JkaW5hcnkgbG9jYWwgcnVucyBhZnRlciBhIHZlcnNpb24gYnVtcC5cbiAgaWYgKHdvcmxkLmNhcGFiaWxpdGllcz8uZGVwbG95bWVudEFmZmluaXR5ICE9PSB0cnVlKSB7XG4gICAgcmV0dXJuIENPTlRJTlVFO1xuICB9XG5cbiAgY29uc3QgY3VycmVudERlcGxveW1lbnRJZCA9IGF3YWl0IHdvcmxkLmdldERlcGxveW1lbnRJZCgpO1xuICBpZiAocnVuLmRlcGxveW1lbnRJZCA9PT0gY3VycmVudERlcGxveW1lbnRJZCkge1xuICAgIHJldHVybiBDT05USU5VRTtcbiAgfVxuXG4gIGF3YWl0IGJlZm9yZVN0b3A/LigpO1xuXG4gIGNvbnN0IG1heFJldHJpZXMgPSBnZXREZXBsb3ltZW50TWlzbWF0Y2hNYXhSZXRyaWVzKCk7XG4gIGNvbnN0IGxvZ0NvbnRleHQgPSB7XG4gICAgd29ya2Zsb3dSdW5JZDogcnVuLnJ1bklkLFxuICAgIHBpbm5lZERlcGxveW1lbnRJZDogcnVuLmRlcGxveW1lbnRJZCxcbiAgICBhY3R1YWxEZXBsb3ltZW50SWQ6IGN1cnJlbnREZXBsb3ltZW50SWQsXG4gICAgcmV0cnlDb3VudCxcbiAgICBtYXhSZXRyaWVzLFxuICB9O1xuXG4gIC8qKlxuICAgKiBSZWNvcmRzIHRoZSB0ZXJtaW5hbCBgcnVuX2ZhaWxlZGAuIE1pcnJvcnMgYHJlY29yZEZhdGFsUnVuRXJyb3JgOiBpdFxuICAgKiByZWNvcmRzIGFuZCByZXR1cm5zIHJhdGhlciB0aGFuIHRocm93aW5nLCBzbyB0aGUgY2FsbGVyIGFja3MgdGhlIG1lc3NhZ2VcbiAgICogaW5zdGVhZCBvZiBsZXR0aW5nIHRoZSBxdWV1ZSByZWRlbGl2ZXIgYSBydW4gdGhhdCBpcyBub3cgdGVybWluYWwuXG4gICAqL1xuICBjb25zdCBmYWlsUnVuID0gYXN5bmMgKFxuICAgIHJlY292ZXJ5QXR0ZW1wdHM6IG51bWJlcixcbiAgICBjYXVzZT86IHVua25vd25cbiAgKTogUHJvbWlzZTxEZXBsb3ltZW50QWZmaW5pdHlSZXN1bHQ+ID0+IHtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBXb3JrZmxvd0RlcGxveW1lbnRNaXNtYXRjaEVycm9yKFxuICAgICAgcnVuLnJ1bklkLFxuICAgICAgcnVuLmRlcGxveW1lbnRJZCxcbiAgICAgIGN1cnJlbnREZXBsb3ltZW50SWQsXG4gICAgICB7IHJlY292ZXJ5QXR0ZW1wdHMsIGNhdXNlIH1cbiAgICApO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHdvcmxkLmV2ZW50cy5jcmVhdGUoXG4gICAgICAgIHJ1bi5ydW5JZCxcbiAgICAgICAge1xuICAgICAgICAgIGV2ZW50VHlwZTogJ3J1bl9mYWlsZWQnLFxuICAgICAgICAgIHNwZWNWZXJzaW9uOiBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgICAgICAgICBldmVudERhdGE6IHtcbiAgICAgICAgICAgIC8vIFVuZW5jcnlwdGVkICh1bmRlZmluZWQga2V5KTogc2VlIHRoZSBub3RlIG9uXG4gICAgICAgICAgICAvLyBgZ3VhcmREZXBsb3ltZW50QWZmaW5pdHlgLiBkZWh5ZHJhdGUvaHlkcmF0ZSBhcmUgc2VsZi1kZXNjcmliaW5nLFxuICAgICAgICAgICAgLy8gc28gdGhpcyByZWFkcyBiYWNrIHdpdGhvdXQgYSBrZXkuXG4gICAgICAgICAgICBlcnJvcjogYXdhaXQgZGVoeWRyYXRlUnVuRXJyb3IoXG4gICAgICAgICAgICAgIGVycm9yLFxuICAgICAgICAgICAgICBydW4ucnVuSWQsXG4gICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAocnVuLnNwZWNWZXJzaW9uID8/IDApID49IFNQRUNfVkVSU0lPTl9TVVBQT1JUU19DT01QUkVTU0lPTlxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIGVycm9yQ29kZTogUlVOX0VSUk9SX0NPREVTLkRFUExPWU1FTlRfTUlTTUFUQ0gsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgeyByZXF1ZXN0SWQgfVxuICAgICAgKTtcbiAgICB9IGNhdGNoIChmYWlsRXJyb3IpIHtcbiAgICAgIC8vIFJ1biBhbHJlYWR5IHJlYWNoZWQgYSB0ZXJtaW5hbCBzdGF0ZSAoYSBjb25jdXJyZW50IHdyaXRlciBmYWlsZWQgaXQsIG9yXG4gICAgICAvLyBpdCB3YXMgY2FuY2VsbGVkL2V4cGlyZWQpIOKAlCBzdGlsbCBzdG9wLiBBbnl0aGluZyBlbHNlIGlzIGEgdHJhbnNpZW50XG4gICAgICAvLyBwZXJzaXN0ZW5jZSBmYWlsdXJlOiByZXRocm93IHNvIHRoZSBxdWV1ZSByZWRlbGl2ZXJzIGFuZCB3ZSB0cnkgYWdhaW4uXG4gICAgICBpZiAoXG4gICAgICAgICFFbnRpdHlDb25mbGljdEVycm9yLmlzKGZhaWxFcnJvcikgJiZcbiAgICAgICAgIVJ1bkV4cGlyZWRFcnJvci5pcyhmYWlsRXJyb3IpXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgZmFpbEVycm9yO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0KCdmYWlsZWQnLCBydW4uZGVwbG95bWVudElkLCByZWNvdmVyeUF0dGVtcHRzKTtcbiAgfTtcblxuICBpZiAocmVlbnF1ZXVlICYmIHJldHJ5Q291bnQgPCBtYXhSZXRyaWVzKSB7XG4gICAgY29uc3QgYXR0ZW1wdCA9IHJldHJ5Q291bnQgKyAxO1xuICAgIC8vIEV4cG9uZW50aWFsLCBjYXBwZWQ6IDFzLCAycywgNHMg4oCUIGNoZWFwIGluc3VyYW5jZSBhZ2FpbnN0IGEgaG90XG4gICAgLy8gcmUtZW5xdWV1ZSBsb29wLCBhbmQgdGltZSBmb3IgYSBtaWQtZmxpZ2h0IHJvdXRpbmcgY2hhbmdlIHRvIHNldHRsZS5cbiAgICBjb25zdCBkZWxheVNlY29uZHMgPSBNYXRoLm1pbigyICoqIHJldHJ5Q291bnQsIE1BWF9SRVJPVVRFX0RFTEFZX1NFQ09ORFMpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCByZWVucXVldWUoe1xuICAgICAgICBkZXBsb3ltZW50SWQ6IHJ1bi5kZXBsb3ltZW50SWQsXG4gICAgICAgIHNwZWNWZXJzaW9uOiBydW4uc3BlY1ZlcnNpb24sXG4gICAgICAgIGRlcGxveW1lbnRNaXNtYXRjaFJldHJ5Q291bnQ6IGF0dGVtcHQsXG4gICAgICAgIGRlbGF5U2Vjb25kcyxcbiAgICAgIH0pO1xuICAgICAgcnVudGltZUxvZ2dlci53YXJuKFxuICAgICAgICAnV29ya2Zsb3cgcnVuIHJlY2VpdmVkIGJ5IGEgZGVwbG95bWVudCBpdCBpcyBub3QgcGlubmVkIHRvOyByZS1yb3V0aW5nIHRvIGl0cyBvd24gZGVwbG95bWVudCcsXG4gICAgICAgIHsgLi4ubG9nQ29udGV4dCwgYXR0ZW1wdCwgZGVsYXlTZWNvbmRzIH1cbiAgICAgICk7XG4gICAgICByZXR1cm4gcmVzdWx0KCdyZXJvdXRlZCcsIHJ1bi5kZXBsb3ltZW50SWQsIGF0dGVtcHQpO1xuICAgIH0gY2F0Y2ggKHJlZW5xdWV1ZUVycm9yKSB7XG4gICAgICAvLyBBIGdlbmVyaWMgc2VuZCBmYWlsdXJlIGNhbiBiZSB0cmFuc2llbnQgKDQyOSwgNXh4LCBjb25uZWN0L0ROUykuIERvIG5vdFxuICAgICAgLy8gdHVybiBvbmUgaW5mcmFzdHJ1Y3R1cmUgYmxpcCBpbnRvIGEgdGVybWluYWwgcnVuIGZhaWx1cmU6IHJlamVjdCB0aGVcbiAgICAgIC8vIGhhbmRsZXIgc28gdGhlIGN1cnJlbnQgbWVzc2FnZSByZW1haW5zIHVuYWNrZWQgYW5kIGlzIHJlZGVsaXZlcmVkLlxuICAgICAgaWYgKCFpc0RlcGxveW1lbnRVbmF2YWlsYWJsZUVycm9yPy4ocmVlbnF1ZXVlRXJyb3IpKSB7XG4gICAgICAgIHRocm93IHJlZW5xdWV1ZUVycm9yO1xuICAgICAgfVxuXG4gICAgICAvLyBUaGUgV29ybGQgZXhwbGljaXRseSBjbGFzc2lmaWVkIHRoZSB0YXJnZXQgYXMgdW5hdmFpbGFibGUg4oCUIGRlbGV0ZWQsXG4gICAgICAvLyBhZ2VkIG91dCBvZiBpdHMgcmV0ZW50aW9uIHdpbmRvdywgb3Igb3RoZXJ3aXNlIHVuZGlzY292ZXJhYmxlLiBCdXJuaW5nXG4gICAgICAvLyB0aGUgcmVzdCBvZiB0aGUgYnVkZ2V0IG9uIGEgZGVwbG95bWVudCB0aGF0IHByb3ZhYmx5IGNhbm5vdCBiZSByZWFjaGVkXG4gICAgICAvLyBvbmx5IGRlbGF5cyB0aGUgZmFpbHVyZSwgc28gZmFpbCBub3cuXG4gICAgICBydW50aW1lTG9nZ2VyLmVycm9yKFxuICAgICAgICAnQ2Fubm90IHJlLXJvdXRlIGEgbWlzcm91dGVkIHdvcmtmbG93IHJ1biB0byBpdHMgb3duIGRlcGxveW1lbnQ7IGZhaWxpbmcgdGhlIHJ1bicsXG4gICAgICAgIHtcbiAgICAgICAgICAuLi5sb2dDb250ZXh0LFxuICAgICAgICAgIGF0dGVtcHQsXG4gICAgICAgICAgZXJyb3JNZXNzYWdlOlxuICAgICAgICAgICAgcmVlbnF1ZXVlRXJyb3IgaW5zdGFuY2VvZiBFcnJvclxuICAgICAgICAgICAgICA/IHJlZW5xdWV1ZUVycm9yLm1lc3NhZ2VcbiAgICAgICAgICAgICAgOiBTdHJpbmcocmVlbnF1ZXVlRXJyb3IpLFxuICAgICAgICB9XG4gICAgICApO1xuICAgICAgLy8gUmVjb3ZlcnkgbmV2ZXIgYWN0dWFsbHkgaGFwcGVuZWQsIHNvIHJlcG9ydCAwIGF0dGVtcHRzIGFuZCBsZXQgYGNhdXNlYFxuICAgICAgLy8gZXhwbGFpbiB3aHkuXG4gICAgICByZXR1cm4gZmFpbFJ1bigwLCByZWVucXVldWVFcnJvcik7XG4gICAgfVxuICB9XG5cbiAgcnVudGltZUxvZ2dlci5lcnJvcihcbiAgICByZXRyeUNvdW50ID4gMFxuICAgICAgPyAnV29ya2Zsb3cgcnVuIGtlcHQgYXJyaXZpbmcgYXQgYSBkZXBsb3ltZW50IGl0IGlzIG5vdCBwaW5uZWQgdG8gYWZ0ZXIgcmUtcm91dGluZzsgZmFpbGluZyB0aGUgcnVuJ1xuICAgICAgOiAnV29ya2Zsb3cgcnVuIHJlY2VpdmVkIGJ5IGEgZGVwbG95bWVudCBpdCBpcyBub3QgcGlubmVkIHRvOyBmYWlsaW5nIHRoZSBydW4nLFxuICAgIGxvZ0NvbnRleHRcbiAgKTtcbiAgcmV0dXJuIGZhaWxSdW4ocmV0cnlDb3VudCk7XG59XG4iXX0=
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Auto-generated by scripts/build-quickjs-assets.js
3
+ * Do not edit manually.
4
+ *
5
+ * Contains base64-encoded quickjs-wasi WASM binary and native C extension
6
+ * .so files. Decoded at import time so they can be passed directly to
7
+ * QuickJS.create() and QuickJS.restore() without any filesystem access,
8
+ * import.meta.url resolution, or require.resolve calls.
9
+ */
10
+ import type { ExtensionDescriptor } from 'quickjs-wasi';
11
+ declare const quickjsWasm: Uint8Array<ArrayBufferLike>;
12
+ export { quickjsWasm };
13
+ export declare const quickjsExtensions: ExtensionDescriptor[];
14
+ //# sourceMappingURL=quickjs-assets.generated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quickjs-assets.generated.d.ts","sourceRoot":"","sources":["../../src/runtime/quickjs-assets.generated.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAoBxD,QAAA,MAAM,WAAW,6BAAu93xB,CAAC;AAUz+3xB,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB,eAAO,MAAM,iBAAiB,EAAE,mBAAmB,EAKlD,CAAC"}