footprintjs 10.0.1 → 10.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +2 -1
- package/CLAUDE.md +61 -7
- package/README.md +136 -312
- package/dist/esm/index.d.ts +62 -2
- package/dist/esm/index.js +13 -6
- package/dist/esm/lib/attempt/anySignal.d.ts +19 -0
- package/dist/esm/lib/attempt/anySignal.js +39 -0
- package/dist/esm/lib/attempt/call.d.ts +88 -0
- package/dist/esm/lib/attempt/call.js +129 -0
- package/dist/esm/lib/attempt/category.d.ts +37 -0
- package/dist/esm/lib/attempt/category.js +131 -0
- package/dist/esm/lib/attempt/correlation.d.ts +95 -0
- package/dist/esm/lib/attempt/correlation.js +178 -0
- package/dist/esm/lib/attempt/deadline.d.ts +44 -0
- package/dist/esm/lib/attempt/deadline.js +101 -0
- package/dist/esm/lib/attempt/decision.d.ts +52 -0
- package/dist/esm/lib/attempt/decision.js +134 -0
- package/dist/esm/lib/attempt/effect.d.ts +76 -0
- package/dist/esm/lib/attempt/effect.js +160 -0
- package/dist/esm/lib/attempt/errors.d.ts +41 -0
- package/dist/esm/lib/attempt/errors.js +44 -0
- package/dist/esm/lib/attempt/index.d.ts +18 -0
- package/dist/esm/lib/attempt/index.js +15 -0
- package/dist/esm/lib/attempt/name.d.ts +21 -0
- package/dist/esm/lib/attempt/name.js +43 -0
- package/dist/esm/lib/attempt/observed.d.ts +66 -0
- package/dist/esm/lib/attempt/observed.js +171 -0
- package/dist/esm/lib/attempt/policy.d.ts +45 -0
- package/dist/esm/lib/attempt/policy.js +83 -0
- package/dist/esm/lib/attempt/record.d.ts +11 -0
- package/dist/esm/lib/attempt/record.js +24 -0
- package/dist/esm/lib/attempt/retryLoopContext.d.ts +18 -0
- package/dist/esm/lib/attempt/retryLoopContext.js +24 -0
- package/dist/esm/lib/attempt/retryLoopTypes.d.ts +18 -0
- package/dist/esm/lib/attempt/retryLoopTypes.js +2 -0
- package/dist/esm/lib/attempt/runner.d.ts +157 -0
- package/dist/esm/lib/attempt/runner.js +523 -0
- package/dist/esm/lib/attempt/standalone.d.ts +47 -0
- package/dist/esm/lib/attempt/standalone.js +126 -0
- package/dist/esm/lib/attempt/types.d.ts +453 -0
- package/dist/esm/lib/attempt/types.js +16 -0
- package/dist/esm/lib/budget/index.d.ts +9 -0
- package/dist/esm/lib/budget/index.js +9 -0
- package/dist/esm/lib/budget/timeBudget.d.ts +136 -0
- package/dist/esm/lib/budget/timeBudget.js +666 -0
- package/dist/esm/lib/builder/FlowChartBuilder.d.ts +88 -3
- package/dist/esm/lib/builder/FlowChartBuilder.js +199 -9
- package/dist/esm/lib/builder/retryLoop.d.ts +56 -0
- package/dist/esm/lib/builder/retryLoop.js +283 -0
- package/dist/esm/lib/builder/types.d.ts +35 -1
- package/dist/esm/lib/builder/types.js +1 -1
- package/dist/esm/lib/decide/decide.js +2 -2
- package/dist/esm/lib/decide/index.d.ts +1 -1
- package/dist/esm/lib/decide/index.js +2 -2
- package/dist/esm/lib/decide/types.d.ts +3 -0
- package/dist/esm/lib/decide/types.js +1 -8
- package/dist/esm/lib/engine/graph/StageNode.d.ts +11 -1
- package/dist/esm/lib/engine/graph/StageNode.js +1 -1
- package/dist/esm/lib/engine/graph/prefixNodeTree.js +5 -1
- package/dist/esm/lib/engine/handlers/ChildrenExecutor.js +36 -6
- package/dist/esm/lib/engine/handlers/DeciderHandler.js +9 -5
- package/dist/esm/lib/engine/handlers/ResumeEntry.js +3 -1
- package/dist/esm/lib/engine/handlers/SelectorHandler.js +6 -5
- package/dist/esm/lib/engine/handlers/StageRunner.d.ts +8 -1
- package/dist/esm/lib/engine/handlers/StageRunner.js +36 -9
- package/dist/esm/lib/engine/handlers/SubflowExecutor.js +24 -5
- package/dist/esm/lib/engine/handlers/commitStage.d.ts +7 -0
- package/dist/esm/lib/engine/handlers/commitStage.js +22 -4
- package/dist/esm/lib/engine/handlers/stageError.d.ts +9 -0
- package/dist/esm/lib/engine/handlers/stageError.js +23 -1
- package/dist/esm/lib/engine/index.d.ts +2 -2
- package/dist/esm/lib/engine/index.js +1 -1
- package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +27 -13
- package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.js +68 -40
- package/dist/esm/lib/engine/narrative/FlowRecorderDispatcher.d.ts +4 -1
- package/dist/esm/lib/engine/narrative/FlowRecorderDispatcher.js +19 -2
- package/dist/esm/lib/engine/narrative/NarrativeFlowRecorder.d.ts +22 -3
- package/dist/esm/lib/engine/narrative/NarrativeFlowRecorder.js +61 -9
- package/dist/esm/lib/engine/narrative/NullControlFlowNarrativeGenerator.d.ts +1 -0
- package/dist/esm/lib/engine/narrative/NullControlFlowNarrativeGenerator.js +2 -1
- package/dist/esm/lib/engine/narrative/formatting/sentences.d.ts +23 -0
- package/dist/esm/lib/engine/narrative/formatting/sentences.js +127 -1
- package/dist/esm/lib/engine/narrative/index.d.ts +2 -2
- package/dist/esm/lib/engine/narrative/index.js +1 -1
- package/dist/esm/lib/engine/narrative/narrativeTypes.d.ts +27 -21
- package/dist/esm/lib/engine/narrative/narrativeTypes.js +1 -1
- package/dist/esm/lib/engine/narrative/recorders/ManifestFlowRecorder.d.ts +45 -2
- package/dist/esm/lib/engine/narrative/recorders/ManifestFlowRecorder.js +55 -2
- package/dist/esm/lib/engine/narrative/recorders/index.d.ts +1 -1
- package/dist/esm/lib/engine/narrative/recorders/index.js +1 -1
- package/dist/esm/lib/engine/narrative/types.d.ts +74 -5
- package/dist/esm/lib/engine/narrative/types.js +1 -1
- package/dist/esm/lib/engine/traversal/FlowchartTraverser.d.ts +59 -19
- package/dist/esm/lib/engine/traversal/FlowchartTraverser.js +194 -118
- package/dist/esm/lib/engine/traversalContext.d.ts +7 -2
- package/dist/esm/lib/engine/traversalContext.js +6 -3
- package/dist/esm/lib/engine/types.d.ts +52 -57
- package/dist/esm/lib/engine/types.js +1 -1
- package/dist/esm/lib/errors/terminalFailure.d.ts +29 -0
- package/dist/esm/lib/errors/terminalFailure.js +60 -0
- package/dist/esm/lib/{decide → filter}/evaluator.d.ts +7 -2
- package/dist/esm/lib/filter/evaluator.js +135 -0
- package/dist/esm/lib/ids/idempotencyKey.d.ts +14 -0
- package/dist/esm/lib/ids/idempotencyKey.js +24 -0
- package/dist/esm/lib/memory/StageContext.d.ts +123 -3
- package/dist/esm/lib/memory/StageContext.js +245 -4
- package/dist/esm/lib/memory/attention.d.ts +26 -0
- package/dist/esm/lib/memory/attention.js +171 -0
- package/dist/esm/lib/memory/borrowedMutation.d.ts +8 -0
- package/dist/esm/lib/memory/borrowedMutation.js +14 -1
- package/dist/esm/lib/memory/frameTypes.d.ts +38 -0
- package/dist/esm/lib/memory/frameTypes.js +3 -1
- package/dist/esm/lib/memory/redaction.d.ts +12 -0
- package/dist/esm/lib/memory/redaction.js +54 -5
- package/dist/esm/lib/pause/record.js +10 -1
- package/dist/esm/lib/pause/types.d.ts +19 -0
- package/dist/esm/lib/pause/types.js +17 -1
- package/dist/esm/lib/reactive/createTypedScope.js +3 -1
- package/dist/esm/lib/reactive/types.d.ts +36 -4
- package/dist/esm/lib/reactive/types.js +3 -1
- package/dist/esm/lib/recorder/AttemptRecorder.d.ts +141 -0
- package/dist/esm/lib/recorder/AttemptRecorder.js +412 -0
- package/dist/esm/lib/recorder/ControlDepRecorder.d.ts +36 -2
- package/dist/esm/lib/recorder/ControlDepRecorder.js +50 -2
- package/dist/esm/lib/recorder/EmitRecorder.d.ts +3 -0
- package/dist/esm/lib/recorder/EmitRecorder.js +1 -1
- package/dist/esm/lib/recorder/InOutRecorder.d.ts +37 -1
- package/dist/esm/lib/recorder/InOutRecorder.js +75 -6
- package/dist/esm/lib/recorder/QualityRecorder.d.ts +32 -5
- package/dist/esm/lib/recorder/QualityRecorder.js +87 -29
- package/dist/esm/lib/recorder/TopologyRecorder.d.ts +35 -5
- package/dist/esm/lib/recorder/TopologyRecorder.js +76 -2
- package/dist/esm/lib/recorder/attemptMetricRows.d.ts +11 -0
- package/dist/esm/lib/recorder/attemptMetricRows.js +202 -0
- package/dist/esm/lib/recorder/attemptMetrics.d.ts +7 -0
- package/dist/esm/lib/recorder/attemptMetrics.js +165 -0
- package/dist/esm/lib/recorder/attemptMetricsTypes.d.ts +114 -0
- package/dist/esm/lib/recorder/attemptMetricsTypes.js +2 -0
- package/dist/esm/lib/recorder/attemptOTel.d.ts +78 -0
- package/dist/esm/lib/recorder/attemptOTel.js +107 -0
- package/dist/esm/lib/recorder/attemptSeries.d.ts +81 -0
- package/dist/esm/lib/recorder/attemptSeries.js +103 -0
- package/dist/esm/lib/recorder/hooks.d.ts +9 -0
- package/dist/esm/lib/recorder/hooks.js +4 -1
- package/dist/esm/lib/runner/DeferredObserverTier.js +13 -1
- package/dist/esm/lib/runner/ExecutionRuntime.d.ts +54 -6
- package/dist/esm/lib/runner/ExecutionRuntime.js +57 -5
- package/dist/esm/lib/runner/FlowChartExecutor.d.ts +46 -2
- package/dist/esm/lib/runner/FlowChartExecutor.js +330 -101
- package/dist/esm/lib/runner/RunnableChart.d.ts +6 -0
- package/dist/esm/lib/runner/RunnableChart.js +5 -1
- package/dist/esm/lib/runner/attach.d.ts +2 -1
- package/dist/esm/lib/runner/attach.js +8 -2
- package/dist/esm/lib/runner/checkpoint.js +3 -1
- package/dist/esm/lib/runner/deadline.d.ts +42 -0
- package/dist/esm/lib/runner/deadline.js +90 -0
- package/dist/esm/lib/runner/index.d.ts +3 -1
- package/dist/esm/lib/runner/index.js +2 -1
- package/dist/esm/lib/runner/options.d.ts +17 -0
- package/dist/esm/lib/runner/options.js +3 -1
- package/dist/esm/lib/runner/recordSink.d.ts +128 -0
- package/dist/esm/lib/runner/recordSink.js +296 -0
- package/dist/esm/lib/runner/resume.d.ts +3 -0
- package/dist/esm/lib/runner/resume.js +22 -2
- package/dist/esm/lib/runner/snapshot.d.ts +2 -2
- package/dist/esm/lib/runner/snapshot.js +6 -2
- package/dist/esm/lib/scope/ScopeFacade.d.ts +118 -4
- package/dist/esm/lib/scope/ScopeFacade.js +304 -7
- package/dist/esm/lib/scope/recorders/DebugRecorder.d.ts +17 -3
- package/dist/esm/lib/scope/recorders/DebugRecorder.js +79 -13
- package/dist/esm/lib/scope/recorders/MetricRecorder.d.ts +10 -0
- package/dist/esm/lib/scope/recorders/MetricRecorder.js +15 -2
- package/dist/esm/lib/scope/runtime.d.ts +3 -0
- package/dist/esm/lib/scope/runtime.js +1 -1
- package/dist/esm/lib/scope/types.d.ts +6 -0
- package/dist/esm/lib/scope/types.js +1 -1
- package/dist/esm/lib/sinks/fileSink.d.ts +135 -0
- package/dist/esm/lib/sinks/fileSink.js +387 -0
- package/dist/esm/recorders.d.ts +8 -2
- package/dist/esm/recorders.js +7 -1
- package/dist/esm/sinks.d.ts +23 -0
- package/dist/esm/sinks.js +23 -0
- package/dist/esm/trace.d.ts +2 -2
- package/dist/esm/trace.js +1 -1
- package/dist/index.js +77 -60
- package/dist/lib/attempt/anySignal.js +43 -0
- package/dist/lib/attempt/call.js +134 -0
- package/dist/lib/attempt/category.js +136 -0
- package/dist/lib/attempt/correlation.js +186 -0
- package/dist/lib/attempt/deadline.js +112 -0
- package/dist/lib/attempt/decision.js +139 -0
- package/dist/lib/attempt/effect.js +174 -0
- package/dist/lib/attempt/errors.js +49 -0
- package/dist/lib/attempt/index.js +26 -0
- package/dist/lib/attempt/name.js +48 -0
- package/dist/lib/attempt/observed.js +177 -0
- package/dist/lib/attempt/policy.js +92 -0
- package/dist/lib/attempt/record.js +29 -0
- package/dist/lib/attempt/retryLoopContext.js +31 -0
- package/dist/lib/attempt/retryLoopTypes.js +3 -0
- package/dist/lib/attempt/runner.js +530 -0
- package/dist/lib/attempt/standalone.js +130 -0
- package/dist/lib/attempt/types.js +17 -0
- package/dist/lib/budget/index.js +17 -0
- package/dist/lib/budget/timeBudget.js +674 -0
- package/dist/lib/builder/FlowChartBuilder.js +199 -9
- package/dist/lib/builder/retryLoop.js +287 -0
- package/dist/lib/builder/types.js +1 -1
- package/dist/lib/decide/decide.js +2 -2
- package/dist/lib/decide/index.js +2 -2
- package/dist/lib/decide/types.js +1 -8
- package/dist/lib/engine/graph/StageNode.js +1 -1
- package/dist/lib/engine/graph/prefixNodeTree.js +5 -1
- package/dist/lib/engine/handlers/ChildrenExecutor.js +36 -6
- package/dist/lib/engine/handlers/DeciderHandler.js +7 -3
- package/dist/lib/engine/handlers/ResumeEntry.js +3 -1
- package/dist/lib/engine/handlers/SelectorHandler.js +4 -3
- package/dist/lib/engine/handlers/StageRunner.js +36 -9
- package/dist/lib/engine/handlers/SubflowExecutor.js +24 -5
- package/dist/lib/engine/handlers/commitStage.js +24 -5
- package/dist/lib/engine/handlers/stageError.js +26 -2
- package/dist/lib/engine/index.js +1 -1
- package/dist/lib/engine/narrative/CombinedNarrativeRecorder.js +67 -39
- package/dist/lib/engine/narrative/FlowRecorderDispatcher.js +19 -2
- package/dist/lib/engine/narrative/NarrativeFlowRecorder.js +60 -8
- package/dist/lib/engine/narrative/NullControlFlowNarrativeGenerator.js +2 -1
- package/dist/lib/engine/narrative/formatting/sentences.js +131 -2
- package/dist/lib/engine/narrative/index.js +1 -1
- package/dist/lib/engine/narrative/narrativeTypes.js +1 -1
- package/dist/lib/engine/narrative/recorders/ManifestFlowRecorder.js +55 -2
- package/dist/lib/engine/narrative/recorders/index.js +1 -1
- package/dist/lib/engine/narrative/types.js +1 -1
- package/dist/lib/engine/traversal/FlowchartTraverser.js +192 -116
- package/dist/lib/engine/traversalContext.js +6 -3
- package/dist/lib/engine/types.js +1 -1
- package/dist/lib/errors/terminalFailure.js +64 -0
- package/dist/lib/filter/evaluator.js +139 -0
- package/dist/lib/ids/idempotencyKey.js +28 -0
- package/dist/lib/memory/StageContext.js +246 -5
- package/dist/lib/memory/attention.js +175 -0
- package/dist/lib/memory/borrowedMutation.js +16 -2
- package/dist/lib/memory/frameTypes.js +3 -1
- package/dist/lib/memory/redaction.js +54 -5
- package/dist/lib/pause/record.js +10 -1
- package/dist/lib/pause/types.js +17 -1
- package/dist/lib/reactive/createTypedScope.js +3 -1
- package/dist/lib/reactive/types.js +3 -1
- package/dist/lib/recorder/AttemptRecorder.js +417 -0
- package/dist/lib/recorder/ControlDepRecorder.js +50 -2
- package/dist/lib/recorder/EmitRecorder.js +1 -1
- package/dist/lib/recorder/InOutRecorder.js +75 -6
- package/dist/lib/recorder/QualityRecorder.js +87 -29
- package/dist/lib/recorder/TopologyRecorder.js +76 -2
- package/dist/lib/recorder/attemptMetricRows.js +209 -0
- package/dist/lib/recorder/attemptMetrics.js +174 -0
- package/dist/lib/recorder/attemptMetricsTypes.js +3 -0
- package/dist/lib/recorder/attemptOTel.js +111 -0
- package/dist/lib/recorder/attemptSeries.js +113 -0
- package/dist/lib/recorder/hooks.js +4 -1
- package/dist/lib/runner/DeferredObserverTier.js +13 -1
- package/dist/lib/runner/ExecutionRuntime.js +57 -5
- package/dist/lib/runner/FlowChartExecutor.js +330 -101
- package/dist/lib/runner/RunnableChart.js +5 -1
- package/dist/lib/runner/attach.js +8 -2
- package/dist/lib/runner/checkpoint.js +3 -1
- package/dist/lib/runner/deadline.js +94 -0
- package/dist/lib/runner/index.js +4 -2
- package/dist/lib/runner/options.js +3 -1
- package/dist/lib/runner/recordSink.js +302 -0
- package/dist/lib/runner/resume.js +22 -2
- package/dist/lib/runner/snapshot.js +6 -2
- package/dist/lib/scope/ScopeFacade.js +303 -6
- package/dist/lib/scope/recorders/DebugRecorder.js +79 -13
- package/dist/lib/scope/recorders/MetricRecorder.js +15 -2
- package/dist/lib/scope/runtime.js +1 -1
- package/dist/lib/scope/types.js +1 -1
- package/dist/lib/sinks/fileSink.js +392 -0
- package/dist/recorders.js +10 -2
- package/dist/sinks.js +32 -0
- package/dist/trace.js +1 -1
- package/dist/types/index.d.ts +62 -2
- package/dist/types/lib/attempt/anySignal.d.ts +19 -0
- package/dist/types/lib/attempt/call.d.ts +88 -0
- package/dist/types/lib/attempt/category.d.ts +37 -0
- package/dist/types/lib/attempt/correlation.d.ts +95 -0
- package/dist/types/lib/attempt/deadline.d.ts +44 -0
- package/dist/types/lib/attempt/decision.d.ts +52 -0
- package/dist/types/lib/attempt/effect.d.ts +76 -0
- package/dist/types/lib/attempt/errors.d.ts +41 -0
- package/dist/types/lib/attempt/index.d.ts +18 -0
- package/dist/types/lib/attempt/name.d.ts +21 -0
- package/dist/types/lib/attempt/observed.d.ts +66 -0
- package/dist/types/lib/attempt/policy.d.ts +45 -0
- package/dist/types/lib/attempt/record.d.ts +11 -0
- package/dist/types/lib/attempt/retryLoopContext.d.ts +18 -0
- package/dist/types/lib/attempt/retryLoopTypes.d.ts +18 -0
- package/dist/types/lib/attempt/runner.d.ts +157 -0
- package/dist/types/lib/attempt/standalone.d.ts +47 -0
- package/dist/types/lib/attempt/types.d.ts +453 -0
- package/dist/types/lib/budget/index.d.ts +9 -0
- package/dist/types/lib/budget/timeBudget.d.ts +136 -0
- package/dist/types/lib/builder/FlowChartBuilder.d.ts +88 -3
- package/dist/types/lib/builder/retryLoop.d.ts +56 -0
- package/dist/types/lib/builder/types.d.ts +35 -1
- package/dist/types/lib/decide/index.d.ts +1 -1
- package/dist/types/lib/decide/types.d.ts +3 -0
- package/dist/types/lib/engine/graph/StageNode.d.ts +11 -1
- package/dist/types/lib/engine/handlers/StageRunner.d.ts +8 -1
- package/dist/types/lib/engine/handlers/commitStage.d.ts +7 -0
- package/dist/types/lib/engine/handlers/stageError.d.ts +9 -0
- package/dist/types/lib/engine/index.d.ts +2 -2
- package/dist/types/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +27 -13
- package/dist/types/lib/engine/narrative/FlowRecorderDispatcher.d.ts +4 -1
- package/dist/types/lib/engine/narrative/NarrativeFlowRecorder.d.ts +22 -3
- package/dist/types/lib/engine/narrative/NullControlFlowNarrativeGenerator.d.ts +1 -0
- package/dist/types/lib/engine/narrative/formatting/sentences.d.ts +23 -0
- package/dist/types/lib/engine/narrative/index.d.ts +2 -2
- package/dist/types/lib/engine/narrative/narrativeTypes.d.ts +27 -21
- package/dist/types/lib/engine/narrative/recorders/ManifestFlowRecorder.d.ts +45 -2
- package/dist/types/lib/engine/narrative/recorders/index.d.ts +1 -1
- package/dist/types/lib/engine/narrative/types.d.ts +74 -5
- package/dist/types/lib/engine/traversal/FlowchartTraverser.d.ts +59 -19
- package/dist/types/lib/engine/traversalContext.d.ts +7 -2
- package/dist/types/lib/engine/types.d.ts +52 -57
- package/dist/types/lib/errors/terminalFailure.d.ts +29 -0
- package/dist/types/lib/{decide → filter}/evaluator.d.ts +7 -2
- package/dist/types/lib/ids/idempotencyKey.d.ts +14 -0
- package/dist/types/lib/memory/StageContext.d.ts +123 -3
- package/dist/types/lib/memory/attention.d.ts +26 -0
- package/dist/types/lib/memory/borrowedMutation.d.ts +8 -0
- package/dist/types/lib/memory/frameTypes.d.ts +38 -0
- package/dist/types/lib/memory/redaction.d.ts +12 -0
- package/dist/types/lib/pause/types.d.ts +19 -0
- package/dist/types/lib/reactive/types.d.ts +36 -4
- package/dist/types/lib/recorder/AttemptRecorder.d.ts +141 -0
- package/dist/types/lib/recorder/ControlDepRecorder.d.ts +36 -2
- package/dist/types/lib/recorder/EmitRecorder.d.ts +3 -0
- package/dist/types/lib/recorder/InOutRecorder.d.ts +37 -1
- package/dist/types/lib/recorder/QualityRecorder.d.ts +32 -5
- package/dist/types/lib/recorder/TopologyRecorder.d.ts +35 -5
- package/dist/types/lib/recorder/attemptMetricRows.d.ts +11 -0
- package/dist/types/lib/recorder/attemptMetrics.d.ts +7 -0
- package/dist/types/lib/recorder/attemptMetricsTypes.d.ts +114 -0
- package/dist/types/lib/recorder/attemptOTel.d.ts +78 -0
- package/dist/types/lib/recorder/attemptSeries.d.ts +81 -0
- package/dist/types/lib/recorder/hooks.d.ts +9 -0
- package/dist/types/lib/runner/ExecutionRuntime.d.ts +54 -6
- package/dist/types/lib/runner/FlowChartExecutor.d.ts +46 -2
- package/dist/types/lib/runner/RunnableChart.d.ts +6 -0
- package/dist/types/lib/runner/attach.d.ts +2 -1
- package/dist/types/lib/runner/deadline.d.ts +42 -0
- package/dist/types/lib/runner/index.d.ts +3 -1
- package/dist/types/lib/runner/options.d.ts +17 -0
- package/dist/types/lib/runner/recordSink.d.ts +128 -0
- package/dist/types/lib/runner/resume.d.ts +3 -0
- package/dist/types/lib/runner/snapshot.d.ts +2 -2
- package/dist/types/lib/scope/ScopeFacade.d.ts +118 -4
- package/dist/types/lib/scope/recorders/DebugRecorder.d.ts +17 -3
- package/dist/types/lib/scope/recorders/MetricRecorder.d.ts +10 -0
- package/dist/types/lib/scope/runtime.d.ts +3 -0
- package/dist/types/lib/scope/types.d.ts +6 -0
- package/dist/types/lib/sinks/fileSink.d.ts +135 -0
- package/dist/types/recorders.d.ts +8 -2
- package/dist/types/sinks.d.ts +23 -0
- package/dist/types/trace.d.ts +2 -2
- package/package.json +20 -6
- package/dist/esm/lib/decide/evaluator.js +0 -130
- package/dist/lib/decide/evaluator.js +0 -134
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* sinks/fileSink.ts — the record, one JSON line per entry, in a file (design §3.5, §4, packet P6). NODE ONLY: the
|
|
4
|
+
* one file in `src/` that imports a Node built-in, reachable only through the `footprintjs/sinks` door.
|
|
5
|
+
*
|
|
6
|
+
* WHY A FILE, WHY THIS SHAPE. A run's record must outlive the process that made it — a killed process, a crashed
|
|
7
|
+
* host, a serverless freeze. Each entry the log hands over is encoded, checked and given its own offset in the file,
|
|
8
|
+
* and its write is handed to the I/O pool AT ONCE (a positional write — no entry waits for the event loop to turn);
|
|
9
|
+
* the pool's threads perform them while the main thread runs on. A process killed after a pool thread wrote an entry
|
|
10
|
+
* keeps it. Until then it is not on disk: microseconds on a free pool, but the pool (4 threads by default) is shared
|
|
11
|
+
* with DNS lookups, zlib, crypto and other fs work, so while it is busy the window is as long as that work — and since
|
|
12
|
+
* writes complete out of order, a kill can lose an entry in the middle (the reader reports the hole). `flush()` waits for every write and
|
|
13
|
+
* `fsync`s — the step that also survives the machine losing power, and the one the executor awaits after each run's
|
|
14
|
+
* closing entry.
|
|
15
|
+
*
|
|
16
|
+
* THE THREAT MODEL, as code — every resource bounded, nothing that can stall the run:
|
|
17
|
+
* - ONLY THE PATH THE APP GIVES. Resolved once and opened once, at `fileSink(path)`; every entry goes to that open
|
|
18
|
+
* file. A symbolic link at the path is refused (`O_NOFOLLOW`, where the platform has it), and so is anything
|
|
19
|
+
* that is not a regular file, a file with another hard link, another owner, or group/world write. A file the
|
|
20
|
+
* sink creates is `0o600`.
|
|
21
|
+
* - ATOMIC PER ENTRY. A line is encoded in full first — an entry JSON cannot write (a `BigInt`, a cycle) is
|
|
22
|
+
* refused whole — then written at its own offset. A write that fails part-way leaves a hole up to the next
|
|
23
|
+
* entry's offset; the reader splits at it (NUL), so a torn line never swallows the one after it (an existing
|
|
24
|
+
* file with a torn tail gets a newline first).
|
|
25
|
+
* - BOUNDED: `maxEntryBytes` (one line, 8 MiB — refused by name, before it is encoded when its length already
|
|
26
|
+
* says so), `maxQueuedBytes` (accepted, not yet written, 16 MiB — past it an entry is DROPPED and counted, never
|
|
27
|
+
* buffered without limit), `maxBytes` (the file, 64 MiB — once full, every further entry is refused and counted;
|
|
28
|
+
* a closing entry may use a 64 KiB reserve so a full file can still say how the run ended), `flushTimeoutMs`
|
|
29
|
+
* (10 s — then `flush()` rejects). Every refusal throws from the sink method, which the log counts
|
|
30
|
+
* (`getSnapshot().sink`); a write that fails later rejects that entry's promise, counted the same way.
|
|
31
|
+
* - ASYNCHRONOUS WRITES ONLY. No method blocks on the disk; the file is released asynchronously, after every
|
|
32
|
+
* write and every started fsync.
|
|
33
|
+
* - NO SECRET ON DISK is the EXECUTOR's law, applied before any entry reaches an adapter (`runner/recordSink.ts`):
|
|
34
|
+
* this file writes what it is handed and reads nothing else.
|
|
35
|
+
* - ONE WRITER PER FILE. A second sink on a file this process has open is refused (by device and inode, across the
|
|
36
|
+
* CommonJS and ESM builds). ANOTHER PROCESS writing the same path is not seen at open: each writes at its own
|
|
37
|
+
* offsets and would overwrite the other. `flush()` checks the file's size against what this sink placed and rejects
|
|
38
|
+
* (a loss the run counts) when another writer's bytes reach past it — best effort: an overwrite this sink's own
|
|
39
|
+
* later writes cover is not seen. Give each process its own file.
|
|
40
|
+
*
|
|
41
|
+
* WHAT JSON KEEPS. A line holds what `JSON.stringify` keeps: a `Date` becomes its ISO string, a `Map` / `Set` an
|
|
42
|
+
* empty object, `undefined` disappears. A record of plain JSON values reads back exactly (`readRecordFile` →
|
|
43
|
+
* `readStoredRecord`); for richer values, bring an adapter with a richer encoding.
|
|
44
|
+
*/
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.readRecordFile = exports.fileSink = exports.DEFAULT_FILE_SINK_FLUSH_TIMEOUT_MS = exports.DEFAULT_FILE_SINK_MAX_QUEUED_BYTES = exports.DEFAULT_FILE_SINK_MAX_ENTRY_BYTES = exports.DEFAULT_FILE_SINK_MAX_BYTES = void 0;
|
|
47
|
+
const node_fs_1 = require("node:fs");
|
|
48
|
+
const node_path_1 = require("node:path");
|
|
49
|
+
const node_process_1 = require("node:process");
|
|
50
|
+
/** The default cap on a record file: 64 MiB. */
|
|
51
|
+
exports.DEFAULT_FILE_SINK_MAX_BYTES = 64 * 1024 * 1024;
|
|
52
|
+
/** The default cap on ONE entry's line: 8 MiB. */
|
|
53
|
+
exports.DEFAULT_FILE_SINK_MAX_ENTRY_BYTES = 8 * 1024 * 1024;
|
|
54
|
+
/** The default cap on bytes accepted but not yet written: 16 MiB. */
|
|
55
|
+
exports.DEFAULT_FILE_SINK_MAX_QUEUED_BYTES = 16 * 1024 * 1024;
|
|
56
|
+
/** The default bound on `flush()`: 10 s. */
|
|
57
|
+
exports.DEFAULT_FILE_SINK_FLUSH_TIMEOUT_MS = 10_000;
|
|
58
|
+
/** How far past `maxBytes` a CLOSING entry may still go, so a full file can say how the run ended: 64 KiB. */
|
|
59
|
+
const CLOSE_RESERVE_BYTES = 64 * 1024;
|
|
60
|
+
/** The default cap `readRecordFile` reads: 256 MiB. */
|
|
61
|
+
const DEFAULT_READ_MAX_BYTES = 256 * 1024 * 1024;
|
|
62
|
+
/**
|
|
63
|
+
* A record sink that appends each entry to `path` as one JSON line — the crash-safe record on a Node host.
|
|
64
|
+
*
|
|
65
|
+
* Every method returns at once: the line is encoded, checked against every bound, given its offset and handed to
|
|
66
|
+
* the I/O pool. The method's promise settles when that line is written; a write that fails rejects it, and the run
|
|
67
|
+
* counts the loss.
|
|
68
|
+
*
|
|
69
|
+
* @throws TypeError when `path` is not a non-empty string or does not name a regular file the writer owns alone;
|
|
70
|
+
* RangeError for a bound that is not a whole number ≥ 1; the operating system's error when
|
|
71
|
+
* the file cannot be opened (a symbolic link at `path` included). Made once, at setup — never during a run.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* import { fileSink, readRecordFile } from 'footprintjs/sinks';
|
|
76
|
+
* import { readStoredRecord } from 'foottrace';
|
|
77
|
+
*
|
|
78
|
+
* const sink = fileSink('/var/footprint/orders.jsonl');
|
|
79
|
+
* const executor = new FlowChartExecutor(chart, { sink });
|
|
80
|
+
* await executor.run({ input });
|
|
81
|
+
* // …later, or after a crash:
|
|
82
|
+
* const record = readStoredRecord(readRecordFile('/var/footprint/orders.jsonl').entries);
|
|
83
|
+
* record.root(runId)?.complete; // false for a run that never ended
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
function fileSink(path, options) {
|
|
87
|
+
if (typeof path !== 'string' || path === '')
|
|
88
|
+
throw new TypeError('fileSink: path must be a non-empty string');
|
|
89
|
+
const maxBytes = bound('maxBytes', options?.maxBytes, exports.DEFAULT_FILE_SINK_MAX_BYTES, 1);
|
|
90
|
+
const maxEntryBytes = bound('maxEntryBytes', options?.maxEntryBytes, exports.DEFAULT_FILE_SINK_MAX_ENTRY_BYTES, 1);
|
|
91
|
+
const maxQueuedBytes = bound('maxQueuedBytes', options?.maxQueuedBytes, exports.DEFAULT_FILE_SINK_MAX_QUEUED_BYTES, 1);
|
|
92
|
+
const flushTimeoutMs = bound('flushTimeoutMs', options?.flushTimeoutMs, exports.DEFAULT_FILE_SINK_FLUSH_TIMEOUT_MS, 1);
|
|
93
|
+
const absolute = (0, node_path_1.resolve)(path);
|
|
94
|
+
// NOT `O_APPEND`: each entry is written at the offset it was given when it was queued (a positional write), so
|
|
95
|
+
// every entry is handed to the I/O pool the moment it is accepted — none waits for the event loop to turn.
|
|
96
|
+
const fd = (0, node_fs_1.openSync)(absolute, node_fs_1.constants.O_RDWR | node_fs_1.constants.O_CREAT | (node_fs_1.constants.O_NOFOLLOW ?? 0), 0o600);
|
|
97
|
+
let identity;
|
|
98
|
+
let size;
|
|
99
|
+
let needsNewline; // the file ends with a torn line: the first entry starts a new one
|
|
100
|
+
try {
|
|
101
|
+
const stat = (0, node_fs_1.fstatSync)(fd);
|
|
102
|
+
if (!stat.isFile())
|
|
103
|
+
throw new TypeError(`fileSink: ${absolute} is not a regular file`);
|
|
104
|
+
refuseForeign(absolute, stat);
|
|
105
|
+
identity = `${stat.dev}:${stat.ino}`;
|
|
106
|
+
// One writer per file, in this process: a second sink would place its entries over the first's.
|
|
107
|
+
if (OPEN_FILES.has(identity))
|
|
108
|
+
throw new TypeError(`fileSink: ${absolute} already has an open sink in this process`);
|
|
109
|
+
size = stat.size;
|
|
110
|
+
needsNewline = size > 0 && !endsWithNewline(fd, size);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
(0, node_fs_1.closeSync)(fd);
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
116
|
+
OPEN_FILES.add(identity);
|
|
117
|
+
const encoder = new TextEncoder();
|
|
118
|
+
let next = size; // the offset the next accepted entry is written at — what `maxBytes` bounds
|
|
119
|
+
let written = size; // bytes known on disk
|
|
120
|
+
let queuedBytes = 0; // accepted, not yet written (in the I/O pool's hands)
|
|
121
|
+
let inFlight = 0;
|
|
122
|
+
let syncing = 0;
|
|
123
|
+
let full = false;
|
|
124
|
+
let closing = false;
|
|
125
|
+
let released = false;
|
|
126
|
+
let drained = [];
|
|
127
|
+
let closedSignal;
|
|
128
|
+
const whenReleased = new Promise((resolve) => (closedSignal = resolve));
|
|
129
|
+
/** Release the file once nothing is in flight and no fsync is pending — asynchronously; an error is ignored. */
|
|
130
|
+
const releaseIfIdle = () => {
|
|
131
|
+
if (!closing || released || inFlight > 0 || syncing > 0)
|
|
132
|
+
return;
|
|
133
|
+
released = true;
|
|
134
|
+
OPEN_FILES.delete(identity);
|
|
135
|
+
(0, node_fs_1.close)(fd, () => closedSignal?.());
|
|
136
|
+
};
|
|
137
|
+
/** Everything accepted is written: start each waiting flush's fsync, then release if closing. */
|
|
138
|
+
const settleDrained = () => {
|
|
139
|
+
if (inFlight > 0)
|
|
140
|
+
return;
|
|
141
|
+
const waiting = drained;
|
|
142
|
+
drained = [];
|
|
143
|
+
for (const start of waiting)
|
|
144
|
+
start();
|
|
145
|
+
releaseIfIdle();
|
|
146
|
+
};
|
|
147
|
+
/** One entry: refused whole with a named bound (the log counts it), or submitted — never in part, never blocking. */
|
|
148
|
+
const enqueue = (entry) => {
|
|
149
|
+
if (closing)
|
|
150
|
+
throw new Error(`fileSink: ${absolute} is closed`);
|
|
151
|
+
// The cheap refusals first: a full file or a full queue costs no encoding.
|
|
152
|
+
if (full && entry.kind !== 'closed')
|
|
153
|
+
throw fileFull(absolute, maxBytes, entry.kind);
|
|
154
|
+
// A closing entry is exempt from the queue bound (as from `maxBytes`, within its reserve): how a log ended is
|
|
155
|
+
// the one entry a full queue must not drop.
|
|
156
|
+
const isClosingEntry = entry.kind === 'closed';
|
|
157
|
+
if (!isClosingEntry && queuedBytes >= maxQueuedBytes)
|
|
158
|
+
throw queueFull(absolute, queuedBytes, maxQueuedBytes, entry.kind);
|
|
159
|
+
const json = JSON.stringify(entry); // an entry JSON cannot write (a BigInt, a cycle) throws here, whole
|
|
160
|
+
// A string's length never exceeds its UTF-8 size: an entry already too long is refused before it is encoded.
|
|
161
|
+
if (json.length + 1 > maxEntryBytes)
|
|
162
|
+
throw tooLarge(absolute, entry.kind, maxEntryBytes);
|
|
163
|
+
const encoded = encoder.encode(`${needsNewline ? '\n' : ''}${json}\n`);
|
|
164
|
+
if (encoded.length > maxEntryBytes + 1)
|
|
165
|
+
throw tooLarge(absolute, entry.kind, maxEntryBytes);
|
|
166
|
+
const limit = entry.kind === 'closed' ? maxBytes + CLOSE_RESERVE_BYTES : maxBytes;
|
|
167
|
+
if (next + encoded.length > limit) {
|
|
168
|
+
if (entry.kind !== 'closed')
|
|
169
|
+
full = true;
|
|
170
|
+
throw fileFull(absolute, maxBytes, entry.kind);
|
|
171
|
+
}
|
|
172
|
+
if (!isClosingEntry && queuedBytes + encoded.length > maxQueuedBytes) {
|
|
173
|
+
throw queueFull(absolute, queuedBytes, maxQueuedBytes, entry.kind);
|
|
174
|
+
}
|
|
175
|
+
needsNewline = false;
|
|
176
|
+
const at = next;
|
|
177
|
+
next += encoded.length;
|
|
178
|
+
queuedBytes += encoded.length;
|
|
179
|
+
inFlight += 1;
|
|
180
|
+
return new Promise((resolve, reject) => {
|
|
181
|
+
writeAt(fd, encoded, at, (error, wrote) => {
|
|
182
|
+
inFlight -= 1;
|
|
183
|
+
queuedBytes -= encoded.length;
|
|
184
|
+
written += wrote;
|
|
185
|
+
// A line cut short leaves a hole up to the next entry's offset: the reader splits at it (NUL), so a torn
|
|
186
|
+
// line never swallows the entry after it.
|
|
187
|
+
if (error)
|
|
188
|
+
reject(error);
|
|
189
|
+
else
|
|
190
|
+
resolve();
|
|
191
|
+
settleDrained();
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
};
|
|
195
|
+
return {
|
|
196
|
+
path: absolute,
|
|
197
|
+
get bytes() {
|
|
198
|
+
return written;
|
|
199
|
+
},
|
|
200
|
+
get queuedBytes() {
|
|
201
|
+
return queuedBytes;
|
|
202
|
+
},
|
|
203
|
+
get full() {
|
|
204
|
+
return full;
|
|
205
|
+
},
|
|
206
|
+
opened: ({ address, at, initialState, meta }) => enqueue({ kind: 'opened', address, at, initialState, ...(meta === undefined ? {} : { meta }) }),
|
|
207
|
+
commit: ({ address, at, bundle }) => enqueue({ kind: 'commit', address, at, bundle }),
|
|
208
|
+
note: ({ address, at, kind, data }) => enqueue({ kind: 'note', address, at, note: kind, data }),
|
|
209
|
+
closed: ({ address, at, outcome, commits, meta }) => enqueue({ kind: 'closed', address, at, outcome, commits, ...(meta === undefined ? {} : { meta }) }),
|
|
210
|
+
flush: () => {
|
|
211
|
+
if (closing)
|
|
212
|
+
return Promise.reject(new Error(`fileSink: ${absolute} is closed`));
|
|
213
|
+
const work = new Promise((resolve, reject) => {
|
|
214
|
+
drained.push(() => {
|
|
215
|
+
syncing += 1;
|
|
216
|
+
(0, node_fs_1.fsync)(fd, (error) => {
|
|
217
|
+
if (error) {
|
|
218
|
+
syncing -= 1;
|
|
219
|
+
reject(error);
|
|
220
|
+
releaseIfIdle();
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
// Another writer (another process on the same path) grew the file past what this sink placed: its
|
|
224
|
+
// entries and ours overlap. Said, never silent.
|
|
225
|
+
(0, node_fs_1.fstat)(fd, (statError, stat) => {
|
|
226
|
+
syncing -= 1;
|
|
227
|
+
if (statError)
|
|
228
|
+
reject(statError);
|
|
229
|
+
else if (stat.size > next) {
|
|
230
|
+
reject(new Error(`fileSink: ${absolute} was written by another writer (one sink per file)`));
|
|
231
|
+
}
|
|
232
|
+
else
|
|
233
|
+
resolve();
|
|
234
|
+
releaseIfIdle();
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
settleDrained();
|
|
239
|
+
});
|
|
240
|
+
return withTimeout(work, flushTimeoutMs, `fileSink: flush() of ${absolute} did not finish in ${flushTimeoutMs}ms`);
|
|
241
|
+
},
|
|
242
|
+
close: () => {
|
|
243
|
+
if (!closing) {
|
|
244
|
+
closing = true;
|
|
245
|
+
releaseIfIdle();
|
|
246
|
+
}
|
|
247
|
+
return whenReleased;
|
|
248
|
+
},
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
exports.fileSink = fileSink;
|
|
252
|
+
/**
|
|
253
|
+
* Files a sink of this process has open, by device and inode — one writer per file. Kept on the global object, so
|
|
254
|
+
* the package's CommonJS and ESM builds (two module instances in one process) share it.
|
|
255
|
+
*/
|
|
256
|
+
const OPEN_FILES = (globalThis[Symbol.for('footprintjs.fileSink.open')] ??=
|
|
257
|
+
new Set());
|
|
258
|
+
function fileFull(path, maxBytes, kind) {
|
|
259
|
+
return new RangeError(`fileSink: ${path} is full (maxBytes ${maxBytes}); this ${kind} entry was not written`);
|
|
260
|
+
}
|
|
261
|
+
function queueFull(path, queued, maxQueuedBytes, kind) {
|
|
262
|
+
return new RangeError(`fileSink: ${path} has ${queued} bytes waiting (maxQueuedBytes ${maxQueuedBytes}); this ${kind} entry was dropped`);
|
|
263
|
+
}
|
|
264
|
+
/** A bound read off the options: absent → the default; else a whole number ≥ `min`, or a RangeError naming it. */
|
|
265
|
+
function bound(name, value, fallback, min) {
|
|
266
|
+
if (value === undefined)
|
|
267
|
+
return fallback;
|
|
268
|
+
if (!Number.isSafeInteger(value) || value < min) {
|
|
269
|
+
throw new RangeError(`fileSink: ${name} must be a whole number, at least ${min}`);
|
|
270
|
+
}
|
|
271
|
+
return value;
|
|
272
|
+
}
|
|
273
|
+
function tooLarge(path, kind, maxEntryBytes) {
|
|
274
|
+
return new RangeError(`fileSink: a ${kind} entry larger than maxEntryBytes (${maxEntryBytes}) was not written to ${path}`);
|
|
275
|
+
}
|
|
276
|
+
/** Write all of `buffer` at `position` (asynchronously, as many writes as it takes); `wrote` is how much went out. */
|
|
277
|
+
function writeAt(fd, buffer, position, done) {
|
|
278
|
+
const step = (offset) => {
|
|
279
|
+
(0, node_fs_1.write)(fd, buffer, offset, buffer.length - offset, position + offset, (error, n) => {
|
|
280
|
+
if (error)
|
|
281
|
+
done(error, offset);
|
|
282
|
+
else if (n === 0)
|
|
283
|
+
done(new Error('fileSink: the disk took no bytes'), offset);
|
|
284
|
+
else if (offset + n < buffer.length)
|
|
285
|
+
step(offset + n);
|
|
286
|
+
else
|
|
287
|
+
done(null, buffer.length);
|
|
288
|
+
});
|
|
289
|
+
};
|
|
290
|
+
step(0);
|
|
291
|
+
}
|
|
292
|
+
/** `work`, or a rejection naming the bound once `ms` passed — the work goes on, nobody waits for it. */
|
|
293
|
+
function withTimeout(work, ms, message) {
|
|
294
|
+
return new Promise((resolve, reject) => {
|
|
295
|
+
const timer = setTimeout(() => reject(new Error(message)), ms);
|
|
296
|
+
// A timer that only bounds a wait never keeps the process alive on its own.
|
|
297
|
+
timer.unref?.();
|
|
298
|
+
Promise.prototype.then.call(work, () => {
|
|
299
|
+
clearTimeout(timer);
|
|
300
|
+
resolve();
|
|
301
|
+
}, (error) => {
|
|
302
|
+
clearTimeout(timer);
|
|
303
|
+
reject(error);
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Refuse a file someone else could read or rewrite behind the sink: a hard link (another name for the same bytes —
|
|
309
|
+
* the sink would append into it), a file owned by another user, or one others may write. A file the sink creates is
|
|
310
|
+
* `0o600` and passes; a pre-existing one must already be private to the writer. (Not on Windows, whose modes and
|
|
311
|
+
* owners do not map: there `O_NOFOLLOW` is absent too — the guide names both.)
|
|
312
|
+
*/
|
|
313
|
+
function refuseForeign(path, stat) {
|
|
314
|
+
if (stat.nlink > 1)
|
|
315
|
+
throw new TypeError(`fileSink: ${path} has other hard links — refusing to write through one`);
|
|
316
|
+
const uid = typeof node_process_1.getuid === 'function' ? (0, node_process_1.getuid)() : undefined;
|
|
317
|
+
if (uid !== undefined && stat.uid !== uid)
|
|
318
|
+
throw new TypeError(`fileSink: ${path} belongs to another user`);
|
|
319
|
+
if (uid !== undefined && (stat.mode & 0o022) !== 0) {
|
|
320
|
+
throw new TypeError(`fileSink: ${path} is writable by others — make it 0o600 (or remove it) first`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
/** Whether the file's last byte is a newline — read once, when the sink opens an existing file. */
|
|
324
|
+
function endsWithNewline(fd, size) {
|
|
325
|
+
const last = new Uint8Array(1);
|
|
326
|
+
return (0, node_fs_1.readSync)(fd, last, 0, 1, size - 1) === 1 && last[0] === 0x0a;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Read a record file back, line by line — the entries for `readStoredRecord`, and every line that could not be
|
|
330
|
+
* read, by number, never a failed read. A stored key named `__proto__` stays data (`JSON.parse` makes it an own
|
|
331
|
+
* property). The file is untrusted: a file larger than `maxBytes` (default 256 MiB) is refused before it is read.
|
|
332
|
+
*
|
|
333
|
+
* @throws RangeError when the file is larger than `maxBytes`; the operating system's error when it cannot be read.
|
|
334
|
+
*/
|
|
335
|
+
function readRecordFile(path, options) {
|
|
336
|
+
if (typeof path !== 'string' || path === '')
|
|
337
|
+
throw new TypeError('readRecordFile: path must be a non-empty string');
|
|
338
|
+
const maxBytes = bound('maxBytes', options?.maxBytes, DEFAULT_READ_MAX_BYTES, 1);
|
|
339
|
+
// One descriptor for the check AND the read (a file that grows between them is still bounded); a regular file
|
|
340
|
+
// only (a FIFO would block, a device never end); at most `maxBytes` read.
|
|
341
|
+
// O_NONBLOCK: a FIFO at the path must not block the open before the regular-file check refuses it.
|
|
342
|
+
const fd = (0, node_fs_1.openSync)(path, node_fs_1.constants.O_RDONLY | (node_fs_1.constants.O_NOFOLLOW ?? 0) | (node_fs_1.constants.O_NONBLOCK ?? 0));
|
|
343
|
+
let raw;
|
|
344
|
+
try {
|
|
345
|
+
const stat = (0, node_fs_1.fstatSync)(fd);
|
|
346
|
+
if (!stat.isFile())
|
|
347
|
+
throw new TypeError(`readRecordFile: ${path} is not a regular file`);
|
|
348
|
+
if (stat.size > maxBytes) {
|
|
349
|
+
throw new RangeError(`readRecordFile: ${path} holds ${stat.size} bytes, past the limit of ${maxBytes}`);
|
|
350
|
+
}
|
|
351
|
+
const buffer = new Uint8Array(Math.min(stat.size, maxBytes) + 1);
|
|
352
|
+
let read = 0;
|
|
353
|
+
for (;;) {
|
|
354
|
+
const n = (0, node_fs_1.readSync)(fd, buffer, read, buffer.length - read, read);
|
|
355
|
+
if (n === 0)
|
|
356
|
+
break;
|
|
357
|
+
read += n;
|
|
358
|
+
if (read === buffer.length) {
|
|
359
|
+
throw new RangeError(`readRecordFile: ${path} grew past the limit of ${maxBytes} bytes while being read`);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
raw = buffer.subarray(0, read);
|
|
363
|
+
}
|
|
364
|
+
finally {
|
|
365
|
+
(0, node_fs_1.closeSync)(fd);
|
|
366
|
+
}
|
|
367
|
+
const text = new TextDecoder('utf-8').decode(raw);
|
|
368
|
+
const entries = [];
|
|
369
|
+
const unreadable = [];
|
|
370
|
+
const lines = text.split('\n');
|
|
371
|
+
for (let i = 0; i < lines.length; i++) {
|
|
372
|
+
// A run of NUL bytes is a hole a cut-short write left before the next entry's offset: it ends the torn part,
|
|
373
|
+
// so the entry after it reads on its own (the same line number names both pieces).
|
|
374
|
+
const line = lines[i];
|
|
375
|
+
// A hole is reported, never skipped: bytes that never reached the disk may be a whole entry lost mid-file.
|
|
376
|
+
if (line.includes('\0'))
|
|
377
|
+
unreadable.push({ line: i + 1, reason: 'a hole — bytes that never reached the disk' });
|
|
378
|
+
for (const piece of line.split(/\0+/)) {
|
|
379
|
+
if (piece.trim() === '')
|
|
380
|
+
continue;
|
|
381
|
+
try {
|
|
382
|
+
entries.push(JSON.parse(piece));
|
|
383
|
+
}
|
|
384
|
+
catch {
|
|
385
|
+
unreadable.push({ line: i + 1, reason: 'not JSON — a torn or corrupt line' });
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return { entries, unreadable };
|
|
390
|
+
}
|
|
391
|
+
exports.readRecordFile = readRecordFile;
|
|
392
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZVNpbmsuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3NpbmtzL2ZpbGVTaW5rLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMENHOzs7QUFFSCxxQ0FBMEc7QUFDMUcseUNBQW1EO0FBQ25ELCtDQUFzQztBQUl0QyxnREFBZ0Q7QUFDbkMsUUFBQSwyQkFBMkIsR0FBRyxFQUFFLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQUM1RCxrREFBa0Q7QUFDckMsUUFBQSxpQ0FBaUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQUNqRSxxRUFBcUU7QUFDeEQsUUFBQSxrQ0FBa0MsR0FBRyxFQUFFLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQUNuRSw0Q0FBNEM7QUFDL0IsUUFBQSxrQ0FBa0MsR0FBRyxNQUFNLENBQUM7QUFDekQsOEdBQThHO0FBQzlHLE1BQU0sbUJBQW1CLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUN0Qyx1REFBdUQ7QUFDdkQsTUFBTSxzQkFBc0IsR0FBRyxHQUFHLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQTBDakQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBdUJHO0FBQ0gsU0FBZ0IsUUFBUSxDQUFDLElBQVksRUFBRSxPQUF5QjtJQUM5RCxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsSUFBSSxJQUFJLEtBQUssRUFBRTtRQUFFLE1BQU0sSUFBSSxTQUFTLENBQUMsMkNBQTJDLENBQUMsQ0FBQztJQUM5RyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsVUFBVSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsbUNBQTJCLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDdEYsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDLGVBQWUsRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFFLHlDQUFp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QUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUNsQyxDQUFDO1lBQUMsTUFBTSxDQUFDO2dCQUNQLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxNQUFNLEVBQUUsbUNBQW1DLEVBQUUsQ0FBQyxDQUFDO1lBQ2hGLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLENBQUM7QUFDakMsQ0FBQztBQWhERCx3Q0FnREMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIHNpbmtzL2ZpbGVTaW5rLnRzIOKAlCB0aGUgcmVjb3JkLCBvbmUgSlNPTiBsaW5lIHBlciBlbnRyeSwgaW4gYSBmaWxlIChkZXNpZ24gwqczLjUsIMKnNCwgcGFja2V0IFA2KS4gTk9ERSBPTkxZOiB0aGVcbiAqIG9uZSBmaWxlIGluIGBzcmMvYCB0aGF0IGltcG9ydHMgYSBOb2RlIGJ1aWx0LWluLCByZWFjaGFibGUgb25seSB0aHJvdWdoIHRoZSBgZm9vdHByaW50anMvc2lua3NgIGRvb3IuXG4gKlxuICogV0hZIEEgRklMRSwgV0hZIFRISVMgU0hBUEUuIEEgcnVuJ3MgcmVjb3JkIG11c3Qgb3V0bGl2ZSB0aGUgcHJvY2VzcyB0aGF0IG1hZGUgaXQg4oCUIGEga2lsbGVkIHByb2Nlc3MsIGEgY3Jhc2hlZFxuICogaG9zdCwgYSBzZXJ2ZXJsZXNzIGZyZWV6ZS4gRWFjaCBlbnRyeSB0aGUgbG9nIGhhbmRzIG92ZXIgaXMgZW5jb2RlZCwgY2hlY2tlZCBhbmQgZ2l2ZW4gaXRzIG93biBvZmZzZXQgaW4gdGhlIGZpbGUsXG4gKiBhbmQgaXRzIHdyaXRlIGlzIGhhbmRlZCB0byB0aGUgSS9PIHBvb2wgQVQgT05DRSAoYSBwb3NpdGlvbmFsIHdyaXRlIOKAlCBubyBlbnRyeSB3YWl0cyBmb3IgdGhlIGV2ZW50IGxvb3AgdG8gdHVybik7XG4gKiB0aGUgcG9vbCdzIHRocmVhZHMgcGVyZm9ybSB0aGVtIHdoaWxlIHRoZSBtYWluIHRocmVhZCBydW5zIG9uLiBBIHByb2Nlc3Mga2lsbGVkIGFmdGVyIGEgcG9vbCB0aHJlYWQgd3JvdGUgYW4gZW50cnlcbiAqIGtlZXBzIGl0LiBVbnRpbCB0aGVuIGl0IGlzIG5vdCBvbiBkaXNrOiBtaWNyb3NlY29uZHMgb24gYSBmcmVlIHBvb2wsIGJ1dCB0aGUgcG9vbCAoNCB0aHJlYWRzIGJ5IGRlZmF1bHQpIGlzIHNoYXJlZFxuICogd2l0aCBETlMgbG9va3VwcywgemxpYiwgY3J5cHRvIGFuZCBvdGhlciBmcyB3b3JrLCBzbyB3aGlsZSBpdCBpcyBidXN5IHRoZSB3aW5kb3cgaXMgYXMgbG9uZyBhcyB0aGF0IHdvcmsg4oCUIGFuZCBzaW5jZVxuICogd3JpdGVzIGNvbXBsZXRlIG91dCBvZiBvcmRlciwgYSBraWxsIGNhbiBsb3NlIGFuIGVudHJ5IGluIHRoZSBtaWRkbGUgKHRoZSByZWFkZXIgcmVwb3J0cyB0aGUgaG9sZSkuIGBmbHVzaCgpYCB3YWl0cyBmb3IgZXZlcnkgd3JpdGUgYW5kXG4gKiBgZnN5bmNgcyDigJQgdGhlIHN0ZXAgdGhhdCBhbHNvIHN1cnZpdmVzIHRoZSBtYWNoaW5lIGxvc2luZyBwb3dlciwgYW5kIHRoZSBvbmUgdGhlIGV4ZWN1dG9yIGF3YWl0cyBhZnRlciBlYWNoIHJ1bidzXG4gKiBjbG9zaW5nIGVudHJ5LlxuICpcbiAqIFRIRSBUSFJFQVQgTU9ERUwsIGFzIGNvZGUg4oCUIGV2ZXJ5IHJlc291cmNlIGJvdW5kZWQsIG5vdGhpbmcgdGhhdCBjYW4gc3RhbGwgdGhlIHJ1bjpcbiAqICAgLSBPTkxZIFRIRSBQQVRIIFRIRSBBUFAgR0lWRVMuIFJlc29sdmVkIG9uY2UgYW5kIG9wZW5lZCBvbmNlLCBhdCBgZmlsZVNpbmsocGF0aClgOyBldmVyeSBlbnRyeSBnb2VzIHRvIHRoYXQgb3BlblxuICogICAgIGZpbGUuIEEgc3ltYm9saWMgbGluayBhdCB0aGUgcGF0aCBpcyByZWZ1c2VkIChgT19OT0ZPTExPV2AsIHdoZXJlIHRoZSBwbGF0Zm9ybSBoYXMgaXQpLCBhbmQgc28gaXMgYW55dGhpbmdcbiAqICAgICB0aGF0IGlzIG5vdCBhIHJlZ3VsYXIgZmlsZSwgYSBmaWxlIHdpdGggYW5vdGhlciBoYXJkIGxpbmssIGFub3RoZXIgb3duZXIsIG9yIGdyb3VwL3dvcmxkIHdyaXRlLiBBIGZpbGUgdGhlXG4gKiAgICAgc2luayBjcmVhdGVzIGlzIGAwbzYwMGAuXG4gKiAgIC0gQVRPTUlDIFBFUiBFTlRSWS4gQSBsaW5lIGlzIGVuY29kZWQgaW4gZnVsbCBmaXJzdCDigJQgYW4gZW50cnkgSlNPTiBjYW5ub3Qgd3JpdGUgKGEgYEJpZ0ludGAsIGEgY3ljbGUpIGlzXG4gKiAgICAgcmVmdXNlZCB3aG9sZSDigJQgdGhlbiB3cml0dGVuIGF0IGl0cyBvd24gb2Zmc2V0LiBBIHdyaXRlIHRoYXQgZmFpbHMgcGFydC13YXkgbGVhdmVzIGEgaG9sZSB1cCB0byB0aGUgbmV4dFxuICogICAgIGVudHJ5J3Mgb2Zmc2V0OyB0aGUgcmVhZGVyIHNwbGl0cyBhdCBpdCAoTlVMKSwgc28gYSB0b3JuIGxpbmUgbmV2ZXIgc3dhbGxvd3MgdGhlIG9uZSBhZnRlciBpdCAoYW4gZXhpc3RpbmdcbiAqICAgICBmaWxlIHdpdGggYSB0b3JuIHRhaWwgZ2V0cyBhIG5ld2xpbmUgZmlyc3QpLlxuICogICAtIEJPVU5ERUQ6IGBtYXhFbnRyeUJ5dGVzYCAob25lIGxpbmUsIDggTWlCIOKAlCByZWZ1c2VkIGJ5IG5hbWUsIGJlZm9yZSBpdCBpcyBlbmNvZGVkIHdoZW4gaXRzIGxlbmd0aCBhbHJlYWR5XG4gKiAgICAgc2F5cyBzbyksIGBtYXhRdWV1ZWRCeXRlc2AgKGFjY2VwdGVkLCBub3QgeWV0IHdyaXR0ZW4sIDE2IE1pQiDigJQgcGFzdCBpdCBhbiBlbnRyeSBpcyBEUk9QUEVEIGFuZCBjb3VudGVkLCBuZXZlclxuICogICAgIGJ1ZmZlcmVkIHdpdGhvdXQgbGltaXQpLCBgbWF4Qnl0ZXNgICh0aGUgZmlsZSwgNjQgTWlCIOKAlCBvbmNlIGZ1bGwsIGV2ZXJ5IGZ1cnRoZXIgZW50cnkgaXMgcmVmdXNlZCBhbmQgY291bnRlZDtcbiAqICAgICBhIGNsb3NpbmcgZW50cnkgbWF5IHVzZSBhIDY0IEtpQiByZXNlcnZlIHNvIGEgZnVsbCBmaWxlIGNhbiBzdGlsbCBzYXkgaG93IHRoZSBydW4gZW5kZWQpLCBgZmx1c2hUaW1lb3V0TXNgXG4gKiAgICAgKDEwIHMg4oCUIHRoZW4gYGZsdXNoKClgIHJlamVjdHMpLiBFdmVyeSByZWZ1c2FsIHRocm93cyBmcm9tIHRoZSBzaW5rIG1ldGhvZCwgd2hpY2ggdGhlIGxvZyBjb3VudHNcbiAqICAgICAoYGdldFNuYXBzaG90KCkuc2lua2ApOyBhIHdyaXRlIHRoYXQgZmFpbHMgbGF0ZXIgcmVqZWN0cyB0aGF0IGVudHJ5J3MgcHJvbWlzZSwgY291bnRlZCB0aGUgc2FtZSB3YXkuXG4gKiAgIC0gQVNZTkNIUk9OT1VTIFdSSVRFUyBPTkxZLiBObyBtZXRob2QgYmxvY2tzIG9uIHRoZSBkaXNrOyB0aGUgZmlsZSBpcyByZWxlYXNlZCBhc3luY2hyb25vdXNseSwgYWZ0ZXIgZXZlcnlcbiAqICAgICB3cml0ZSBhbmQgZXZlcnkgc3RhcnRlZCBmc3luYy5cbiAqICAgLSBOTyBTRUNSRVQgT04gRElTSyBpcyB0aGUgRVhFQ1VUT1IncyBsYXcsIGFwcGxpZWQgYmVmb3JlIGFueSBlbnRyeSByZWFjaGVzIGFuIGFkYXB0ZXIgKGBydW5uZXIvcmVjb3JkU2luay50c2ApOlxuICogICAgIHRoaXMgZmlsZSB3cml0ZXMgd2hhdCBpdCBpcyBoYW5kZWQgYW5kIHJlYWRzIG5vdGhpbmcgZWxzZS5cbiAqICAgLSBPTkUgV1JJVEVSIFBFUiBGSUxFLiBBIHNlY29uZCBzaW5rIG9uIGEgZmlsZSB0aGlzIHByb2Nlc3MgaGFzIG9wZW4gaXMgcmVmdXNlZCAoYnkgZGV2aWNlIGFuZCBpbm9kZSwgYWNyb3NzIHRoZVxuICogICAgIENvbW1vbkpTIGFuZCBFU00gYnVpbGRzKS4gQU5PVEhFUiBQUk9DRVNTIHdyaXRpbmcgdGhlIHNhbWUgcGF0aCBpcyBub3Qgc2VlbiBhdCBvcGVuOiBlYWNoIHdyaXRlcyBhdCBpdHMgb3duXG4gKiAgICAgb2Zmc2V0cyBhbmQgd291bGQgb3ZlcndyaXRlIHRoZSBvdGhlci4gYGZsdXNoKClgIGNoZWNrcyB0aGUgZmlsZSdzIHNpemUgYWdhaW5zdCB3aGF0IHRoaXMgc2luayBwbGFjZWQgYW5kIHJlamVjdHNcbiAqICAgICAoYSBsb3NzIHRoZSBydW4gY291bnRzKSB3aGVuIGFub3RoZXIgd3JpdGVyJ3MgYnl0ZXMgcmVhY2ggcGFzdCBpdCDigJQgYmVzdCBlZmZvcnQ6IGFuIG92ZXJ3cml0ZSB0aGlzIHNpbmsncyBvd25cbiAqICAgICBsYXRlciB3cml0ZXMgY292ZXIgaXMgbm90IHNlZW4uIEdpdmUgZWFjaCBwcm9jZXNzIGl0cyBvd24gZmlsZS5cbiAqXG4gKiBXSEFUIEpTT04gS0VFUFMuIEEgbGluZSBob2xkcyB3aGF0IGBKU09OLnN0cmluZ2lmeWAga2VlcHM6IGEgYERhdGVgIGJlY29tZXMgaXRzIElTTyBzdHJpbmcsIGEgYE1hcGAgLyBgU2V0YCBhblxuICogZW1wdHkgb2JqZWN0LCBgdW5kZWZpbmVkYCBkaXNhcHBlYXJzLiBBIHJlY29yZCBvZiBwbGFpbiBKU09OIHZhbHVlcyByZWFkcyBiYWNrIGV4YWN0bHkgKGByZWFkUmVjb3JkRmlsZWAg4oaSXG4gKiBgcmVhZFN0b3JlZFJlY29yZGApOyBmb3IgcmljaGVyIHZhbHVlcywgYnJpbmcgYW4gYWRhcHRlciB3aXRoIGEgcmljaGVyIGVuY29kaW5nLlxuICovXG5cbmltcG9ydCB7IGNsb3NlLCBjbG9zZVN5bmMsIGNvbnN0YW50cywgZnN0YXQsIGZzdGF0U3luYywgZnN5bmMsIG9wZW5TeW5jLCByZWFkU3luYywgd3JpdGUgfSBmcm9tICdub2RlOmZzJztcbmltcG9ydCB7IHJlc29sdmUgYXMgcmVzb2x2ZVBhdGggfSBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0IHsgZ2V0dWlkIH0gZnJvbSAnbm9kZTpwcm9jZXNzJztcblxuaW1wb3J0IHR5cGUgeyBSZWNvcmRFbnRyeSwgUmVjb3JkU2luayB9IGZyb20gJ2Zvb3R0cmFjZS93cml0ZSc7XG5cbi8qKiBUaGUgZGVmYXVsdCBjYXAgb24gYSByZWNvcmQgZmlsZTogNjQgTWlCLiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfRklMRV9TSU5LX01BWF9CWVRFUyA9IDY0ICogMTAyNCAqIDEwMjQ7XG4vKiogVGhlIGRlZmF1bHQgY2FwIG9uIE9ORSBlbnRyeSdzIGxpbmU6IDggTWlCLiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfRklMRV9TSU5LX01BWF9FTlRSWV9CWVRFUyA9IDggKiAxMDI0ICogMTAyNDtcbi8qKiBUaGUgZGVmYXVsdCBjYXAgb24gYnl0ZXMgYWNjZXB0ZWQgYnV0IG5vdCB5ZXQgd3JpdHRlbjogMTYgTWlCLiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfRklMRV9TSU5LX01BWF9RVUVVRURfQllURVMgPSAxNiAqIDEwMjQgKiAxMDI0O1xuLyoqIFRoZSBkZWZhdWx0IGJvdW5kIG9uIGBmbHVzaCgpYDogMTAgcy4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX0ZJTEVfU0lOS19GTFVTSF9USU1FT1VUX01TID0gMTBfMDAwO1xuLyoqIEhvdyBmYXIgcGFzdCBgbWF4Qnl0ZXNgIGEgQ0xPU0lORyBlbnRyeSBtYXkgc3RpbGwgZ28sIHNvIGEgZnVsbCBmaWxlIGNhbiBzYXkgaG93IHRoZSBydW4gZW5kZWQ6IDY0IEtpQi4gKi9cbmNvbnN0IENMT1NFX1JFU0VSVkVfQllURVMgPSA2NCAqIDEwMjQ7XG4vKiogVGhlIGRlZmF1bHQgY2FwIGByZWFkUmVjb3JkRmlsZWAgcmVhZHM6IDI1NiBNaUIuICovXG5jb25zdCBERUZBVUxUX1JFQURfTUFYX0JZVEVTID0gMjU2ICogMTAyNCAqIDEwMjQ7XG5cbi8qKiBgZmlsZVNpbmtgJ3Mgb3B0aW9ucyDigJQgZXZlcnkgcmVzb3VyY2UgdGhlIHNpbmsgY2FuIHNwZW5kLCBib3VuZGVkLiAqL1xuZXhwb3J0IGludGVyZmFjZSBGaWxlU2lua09wdGlvbnMge1xuICAvKipcbiAgICogVGhlIG1vc3QgYnl0ZXMgdGhlIGZpbGUgbWF5IGhvbGQgKHRoZSBieXRlcyBhbHJlYWR5IGluIGl0IGNvdW50KS4gT25jZSBhbiBlbnRyeSB3b3VsZCBwYXNzIGl0LCB0aGUgZmlsZSBpcyBGVUxMOlxuICAgKiB0aGF0IGVudHJ5IGFuZCBldmVyeSBsYXRlciBvbmUgaXMgcmVmdXNlZCBhbmQgY291bnRlZCBieSB0aGUgcnVuLCBuZXZlciB3cml0dGVuIOKAlCBleGNlcHQgYSBjbG9zaW5nIGVudHJ5LCB3aGljaFxuICAgKiBtYXkgdXNlIDY0IEtpQiBtb3JlIHNvIGEgZnVsbCBmaWxlIGNhbiBzdGlsbCBzYXkgaG93IHRoZSBydW4gZW5kZWQuIERlZmF1bHQgNjQgTWlCLlxuICAgKi9cbiAgcmVhZG9ubHkgbWF4Qnl0ZXM/OiBudW1iZXI7XG4gIC8qKiBUaGUgbGFyZ2VzdCBPTkUgZW50cnkncyBsaW5lIG1heSBiZTsgYSBsYXJnZXIgZW50cnkgaXMgcmVmdXNlZCB3aG9sZSAoYG1heEVudHJ5Qnl0ZXNgIG5hbWVkKS4gRGVmYXVsdCA4IE1pQi4gKi9cbiAgcmVhZG9ubHkgbWF4RW50cnlCeXRlcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBtb3N0IGJ5dGVzIGFjY2VwdGVkIGFuZCBub3QgeWV0IG9uIGRpc2suIFdyaXRlcyBhcmUgYXN5bmNocm9ub3VzLCBzbyBhIHNpbmsgc2xvd2VyIHRoYW4gdGhlIHJ1biBxdWV1ZXM7IHBhc3RcbiAgICogdGhpcyBib3VuZCBhbiBlbnRyeSBpcyBEUk9QUEVEIGFuZCBjb3VudGVkIChuZXZlciBidWZmZXJlZCB3aXRob3V0IGxpbWl0LCBuZXZlciBhIHN0YWxsKS4gRGVmYXVsdCAxNiBNaUIuXG4gICAqL1xuICByZWFkb25seSBtYXhRdWV1ZWRCeXRlcz86IG51bWJlcjtcbiAgLyoqIEhvdyBsb25nIGBmbHVzaCgpYCAoZHJhaW4gdGhlIHF1ZXVlLCB0aGVuIGBmc3luY2ApIG1heSB0YWtlIGJlZm9yZSBpdCByZWplY3RzLiBEZWZhdWx0IDEwIHMuICovXG4gIHJlYWRvbmx5IGZsdXNoVGltZW91dE1zPzogbnVtYmVyO1xufVxuXG4vKiogQSByZWNvcmQgc2luayB0aGF0IGFwcGVuZHMgdG8gb25lIGZpbGUg4oCUIGBSZWNvcmRTaW5rYCBwbHVzIHdoYXQgdGhlIGFwcCBuZWVkcyB0byBtYW5hZ2UgdGhlIGZpbGUuICovXG5leHBvcnQgaW50ZXJmYWNlIEZpbGVTaW5rIGV4dGVuZHMgUmVjb3JkU2luayB7XG4gIC8qKiBUaGUgYWJzb2x1dGUgcGF0aCB0aGUgc2luayB3cml0ZXMgdG8g4oCUIHJlc29sdmVkIG9uY2UsIHdoZW4gaXQgd2FzIG1hZGUuICovXG4gIHJlYWRvbmx5IHBhdGg6IHN0cmluZztcbiAgLyoqXG4gICAqIEJ5dGVzIHRoaXMgc2luayBrbm93cyBhcmUgb24gZGlzazogdGhlIGZpbGUncyBzaXplIHdoZW4gaXQgb3BlbmVkIHBsdXMgZXZlcnkgYnl0ZSBpdHMgd3JpdGVzIGNvbXBsZXRlZCDigJQgYVxuICAgKiBydW5uaW5nIHN1bSwgbm90IHRoZSBmaWxlJ3MgZW5kICh3cml0ZXMgY29tcGxldGUgb3V0IG9mIG9yZGVyOyBhIGZhaWxlZCBvbmUgbGVhdmVzIGEgaG9sZSkuXG4gICAqL1xuICByZWFkb25seSBieXRlczogbnVtYmVyO1xuICAvKiogQnl0ZXMgYWNjZXB0ZWQgYW5kIG5vdCB5ZXQgd3JpdHRlbi4gKi9cbiAgcmVhZG9ubHkgcXVldWVkQnl0ZXM6IG51bWJlcjtcbiAgLyoqIGB0cnVlYCBvbmNlIGFuIGVudHJ5IHdhcyByZWZ1c2VkIGZvciBgbWF4Qnl0ZXNgOiB0aGUgZmlsZSBpcyBmdWxsLCBhbmQgb25seSBhIGNsb3NpbmcgZW50cnkgbWF5IHN0aWxsIGdvLiAqL1xuICByZWFkb25seSBmdWxsOiBib29sZWFuO1xuICAvKipcbiAgICogUmVsZWFzZSB0aGUgZmlsZS4gSWRlbXBvdGVudC4gRXZlcnkgZW50cnkgYWZ0ZXIgaXQgaXMgcmVmdXNlZCAodGhlIHJ1biBjb3VudHMgaXQpLCBhbmQgYGZsdXNoKClgIHJlamVjdHM7XG4gICAqIGVudHJpZXMgYWxyZWFkeSBhY2NlcHRlZCBhcmUgc3RpbGwgd3JpdHRlbiAoYW5kIGEgZmx1c2ggYWxyZWFkeSBzdGFydGVkIGZpbmlzaGVzKSwgdGhlbiB0aGUgZmlsZSBpcyBjbG9zZWQg4oCUXG4gICAqIHRoZSBwcm9taXNlIHNldHRsZXMgdGhlbi5cbiAgICovXG4gIGNsb3NlKCk6IFByb21pc2U8dm9pZD47XG59XG5cbi8qKlxuICogQSByZWNvcmQgc2luayB0aGF0IGFwcGVuZHMgZWFjaCBlbnRyeSB0byBgcGF0aGAgYXMgb25lIEpTT04gbGluZSDigJQgdGhlIGNyYXNoLXNhZmUgcmVjb3JkIG9uIGEgTm9kZSBob3N0LlxuICpcbiAqIEV2ZXJ5IG1ldGhvZCByZXR1cm5zIGF0IG9uY2U6IHRoZSBsaW5lIGlzIGVuY29kZWQsIGNoZWNrZWQgYWdhaW5zdCBldmVyeSBib3VuZCwgZ2l2ZW4gaXRzIG9mZnNldCBhbmQgaGFuZGVkIHRvXG4gKiB0aGUgSS9PIHBvb2wuIFRoZSBtZXRob2QncyBwcm9taXNlIHNldHRsZXMgd2hlbiB0aGF0IGxpbmUgaXMgd3JpdHRlbjsgYSB3cml0ZSB0aGF0IGZhaWxzIHJlamVjdHMgaXQsIGFuZCB0aGUgcnVuXG4gKiBjb3VudHMgdGhlIGxvc3MuXG4gKlxuICogQHRocm93cyBUeXBlRXJyb3Igd2hlbiBgcGF0aGAgaXMgbm90IGEgbm9uLWVtcHR5IHN0cmluZyBvciBkb2VzIG5vdCBuYW1lIGEgcmVndWxhciBmaWxlIHRoZSB3cml0ZXIgb3ducyBhbG9uZTtcbiAqICAgUmFuZ2VFcnJvciBmb3IgYSBib3VuZCB0aGF0IGlzIG5vdCBhIHdob2xlIG51bWJlciDiiaUgMTsgdGhlIG9wZXJhdGluZyBzeXN0ZW0ncyBlcnJvciB3aGVuXG4gKiAgIHRoZSBmaWxlIGNhbm5vdCBiZSBvcGVuZWQgKGEgc3ltYm9saWMgbGluayBhdCBgcGF0aGAgaW5jbHVkZWQpLiBNYWRlIG9uY2UsIGF0IHNldHVwIOKAlCBuZXZlciBkdXJpbmcgYSBydW4uXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IGZpbGVTaW5rLCByZWFkUmVjb3JkRmlsZSB9IGZyb20gJ2Zvb3RwcmludGpzL3NpbmtzJztcbiAqIGltcG9ydCB7IHJlYWRTdG9yZWRSZWNvcmQgfSBmcm9tICdmb290dHJhY2UnO1xuICpcbiAqIGNvbnN0IHNpbmsgPSBmaWxlU2luaygnL3Zhci9mb290cHJpbnQvb3JkZXJzLmpzb25sJyk7XG4gKiBjb25zdCBleGVjdXRvciA9IG5ldyBGbG93Q2hhcnRFeGVjdXRvcihjaGFydCwgeyBzaW5rIH0pO1xuICogYXdhaXQgZXhlY3V0b3IucnVuKHsgaW5wdXQgfSk7XG4gKiAvLyDigKZsYXRlciwgb3IgYWZ0ZXIgYSBjcmFzaDpcbiAqIGNvbnN0IHJlY29yZCA9IHJlYWRTdG9yZWRSZWNvcmQocmVhZFJlY29yZEZpbGUoJy92YXIvZm9vdHByaW50L29yZGVycy5qc29ubCcpLmVudHJpZXMpO1xuICogcmVjb3JkLnJvb3QocnVuSWQpPy5jb21wbGV0ZTsgLy8gZmFsc2UgZm9yIGEgcnVuIHRoYXQgbmV2ZXIgZW5kZWRcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gZmlsZVNpbmsocGF0aDogc3RyaW5nLCBvcHRpb25zPzogRmlsZVNpbmtPcHRpb25zKTogRmlsZVNpbmsge1xuICBpZiAodHlwZW9mIHBhdGggIT09ICdzdHJpbmcnIHx8IHBhdGggPT09ICcnKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdmaWxlU2luazogcGF0aCBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycpO1xuICBjb25zdCBtYXhCeXRlcyA9IGJvdW5kKCdtYXhCeXRlcycsIG9wdGlvbnM/Lm1heEJ5dGVzLCBERUZBVUxUX0ZJTEVfU0lOS19NQVhfQllURVMsIDEpO1xuICBjb25zdCBtYXhFbnRyeUJ5dGVzID0gYm91bmQoJ21heEVudHJ5Qnl0ZXMnLCBvcHRpb25zPy5tYXhFbnRyeUJ5dGVzLCBERUZBVUxUX0ZJTEVfU0lOS19NQVhfRU5UUllfQllURVMsIDEpO1xuICBjb25zdCBtYXhRdWV1ZWRCeXRlcyA9IGJvdW5kKCdtYXhRdWV1ZWRCeXRlcycsIG9wdGlvbnM/Lm1heFF1ZXVlZEJ5dGVzLCBERUZBVUxUX0ZJTEVfU0lOS19NQVhfUVVFVUVEX0JZVEVTLCAxKTtcbiAgY29uc3QgZmx1c2hUaW1lb3V0TXMgPSBib3VuZCgnZmx1c2hUaW1lb3V0TXMnLCBvcHRpb25zPy5mbHVzaFRpbWVvdXRNcywgREVGQVVMVF9GSUxFX1NJTktfRkxVU0hfVElNRU9VVF9NUywgMSk7XG4gIGNvbnN0IGFic29sdXRlID0gcmVzb2x2ZVBhdGgocGF0aCk7XG4gIC8vIE5PVCBgT19BUFBFTkRgOiBlYWNoIGVudHJ5IGlzIHdyaXR0ZW4gYXQgdGhlIG9mZnNldCBpdCB3YXMgZ2l2ZW4gd2hlbiBpdCB3YXMgcXVldWVkIChhIHBvc2l0aW9uYWwgd3JpdGUpLCBzb1xuICAvLyBldmVyeSBlbnRyeSBpcyBoYW5kZWQgdG8gdGhlIEkvTyBwb29sIHRoZSBtb21lbnQgaXQgaXMgYWNjZXB0ZWQg4oCUIG5vbmUgd2FpdHMgZm9yIHRoZSBldmVudCBsb29wIHRvIHR1cm4uXG4gIGNvbnN0IGZkID0gb3BlblN5bmMoYWJzb2x1dGUsIGNvbnN0YW50cy5PX1JEV1IgfCBjb25zdGFudHMuT19DUkVBVCB8IChjb25zdGFudHMuT19OT0ZPTExPVyA/PyAwKSwgMG82MDApO1xuICBsZXQgaWRlbnRpdHk6IHN0cmluZztcbiAgbGV0IHNpemU6IG51bWJlcjtcbiAgbGV0IG5lZWRzTmV3bGluZTogYm9vbGVhbjsgLy8gdGhlIGZpbGUgZW5kcyB3aXRoIGEgdG9ybiBsaW5lOiB0aGUgZmlyc3QgZW50cnkgc3RhcnRzIGEgbmV3IG9uZVxuICB0cnkge1xuICAgIGNvbnN0IHN0YXQgPSBmc3RhdFN5bmMoZmQpO1xuICAgIGlmICghc3RhdC5pc0ZpbGUoKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihgZmlsZVNpbms6ICR7YWJzb2x1dGV9IGlzIG5vdCBhIHJlZ3VsYXIgZmlsZWApO1xuICAgIHJlZnVzZUZvcmVpZ24oYWJzb2x1dGUsIHN0YXQpO1xuICAgIGlkZW50aXR5ID0gYCR7c3RhdC5kZXZ9OiR7c3RhdC5pbm99YDtcbiAgICAvLyBPbmUgd3JpdGVyIHBlciBmaWxlLCBpbiB0aGlzIHByb2Nlc3M6IGEgc2Vjb25kIHNpbmsgd291bGQgcGxhY2UgaXRzIGVudHJpZXMgb3ZlciB0aGUgZmlyc3Qncy5cbiAgICBpZiAoT1BFTl9GSUxFUy5oYXMoaWRlbnRpdHkpKSB0aHJvdyBuZXcgVHlwZUVycm9yKGBmaWxlU2luazogJHthYnNvbHV0ZX0gYWxyZWFkeSBoYXMgYW4gb3BlbiBzaW5rIGluIHRoaXMgcHJvY2Vzc2ApO1xuICAgIHNpemUgPSBzdGF0LnNpemU7XG4gICAgbmVlZHNOZXdsaW5lID0gc2l6ZSA+IDAgJiYgIWVuZHNXaXRoTmV3bGluZShmZCwgc2l6ZSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY2xvc2VTeW5jKGZkKTtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuICBPUEVOX0ZJTEVTLmFkZChpZGVudGl0eSk7XG5cbiAgY29uc3QgZW5jb2RlciA9IG5ldyBUZXh0RW5jb2RlcigpO1xuICBsZXQgbmV4dCA9IHNpemU7IC8vIHRoZSBvZmZzZXQgdGhlIG5leHQgYWNjZXB0ZWQgZW50cnkgaXMgd3JpdHRlbiBhdCDigJQgd2hhdCBgbWF4Qnl0ZXNgIGJvdW5kc1xuICBsZXQgd3JpdHRlbiA9IHNpemU7IC8vIGJ5dGVzIGtub3duIG9uIGRpc2tcbiAgbGV0IHF1ZXVlZEJ5dGVzID0gMDsgLy8gYWNjZXB0ZWQsIG5vdCB5ZXQgd3JpdHRlbiAoaW4gdGhlIEkvTyBwb29sJ3MgaGFuZHMpXG4gIGxldCBpbkZsaWdodCA9IDA7XG4gIGxldCBzeW5jaW5nID0gMDtcbiAgbGV0IGZ1bGwgPSBmYWxzZTtcbiAgbGV0IGNsb3NpbmcgPSBmYWxzZTtcbiAgbGV0IHJlbGVhc2VkID0gZmFsc2U7XG4gIGxldCBkcmFpbmVkOiAoKCkgPT4gdm9pZClbXSA9IFtdO1xuICBsZXQgY2xvc2VkU2lnbmFsOiAoKCkgPT4gdm9pZCkgfCB1bmRlZmluZWQ7XG4gIGNvbnN0IHdoZW5SZWxlYXNlZCA9IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiAoY2xvc2VkU2lnbmFsID0gcmVzb2x2ZSkpO1xuXG4gIC8qKiBSZWxlYXNlIHRoZSBmaWxlIG9uY2Ugbm90aGluZyBpcyBpbiBmbGlnaHQgYW5kIG5vIGZzeW5jIGlzIHBlbmRpbmcg4oCUIGFzeW5jaHJvbm91c2x5OyBhbiBlcnJvciBpcyBpZ25vcmVkLiAqL1xuICBjb25zdCByZWxlYXNlSWZJZGxlID0gKCk6IHZvaWQgPT4ge1xuICAgIGlmICghY2xvc2luZyB8fCByZWxlYXNlZCB8fCBpbkZsaWdodCA+IDAgfHwgc3luY2luZyA+IDApIHJldHVybjtcbiAgICByZWxlYXNlZCA9IHRydWU7XG4gICAgT1BFTl9GSUxFUy5kZWxldGUoaWRlbnRpdHkpO1xuICAgIGNsb3NlKGZkLCAoKSA9PiBjbG9zZWRTaWduYWw/LigpKTtcbiAgfTtcblxuICAvKiogRXZlcnl0aGluZyBhY2NlcHRlZCBpcyB3cml0dGVuOiBzdGFydCBlYWNoIHdhaXRpbmcgZmx1c2gncyBmc3luYywgdGhlbiByZWxlYXNlIGlmIGNsb3NpbmcuICovXG4gIGNvbnN0IHNldHRsZURyYWluZWQgPSAoKTogdm9pZCA9PiB7XG4gICAgaWYgKGluRmxpZ2h0ID4gMCkgcmV0dXJuO1xuICAgIGNvbnN0IHdhaXRpbmcgPSBkcmFpbmVkO1xuICAgIGRyYWluZWQgPSBbXTtcbiAgICBmb3IgKGNvbnN0IHN0YXJ0IG9mIHdhaXRpbmcpIHN0YXJ0KCk7XG4gICAgcmVsZWFzZUlmSWRsZSgpO1xuICB9O1xuXG4gIC8qKiBPbmUgZW50cnk6IHJlZnVzZWQgd2hvbGUgd2l0aCBhIG5hbWVkIGJvdW5kICh0aGUgbG9nIGNvdW50cyBpdCksIG9yIHN1Ym1pdHRlZCDigJQgbmV2ZXIgaW4gcGFydCwgbmV2ZXIgYmxvY2tpbmcuICovXG4gIGNvbnN0IGVucXVldWUgPSAoZW50cnk6IFJlY29yZEVudHJ5KTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgaWYgKGNsb3NpbmcpIHRocm93IG5ldyBFcnJvcihgZmlsZVNpbms6ICR7YWJzb2x1dGV9IGlzIGNsb3NlZGApO1xuICAgIC8vIFRoZSBjaGVhcCByZWZ1c2FscyBmaXJzdDogYSBmdWxsIGZpbGUgb3IgYSBmdWxsIHF1ZXVlIGNvc3RzIG5vIGVuY29kaW5nLlxuICAgIGlmIChmdWxsICYmIGVudHJ5LmtpbmQgIT09ICdjbG9zZWQnKSB0aHJvdyBmaWxlRnVsbChhYnNvbHV0ZSwgbWF4Qnl0ZXMsIGVudHJ5LmtpbmQpO1xuICAgIC8vIEEgY2xvc2luZyBlbnRyeSBpcyBleGVtcHQgZnJvbSB0aGUgcXVldWUgYm91bmQgKGFzIGZyb20gYG1heEJ5dGVzYCwgd2l0aGluIGl0cyByZXNlcnZlKTogaG93IGEgbG9nIGVuZGVkIGlzXG4gICAgLy8gdGhlIG9uZSBlbnRyeSBhIGZ1bGwgcXVldWUgbXVzdCBub3QgZHJvcC5cbiAgICBjb25zdCBpc0Nsb3NpbmdFbnRyeSA9IGVudHJ5LmtpbmQgPT09ICdjbG9zZWQnO1xuICAgIGlmICghaXNDbG9zaW5nRW50cnkgJiYgcXVldWVkQnl0ZXMgPj0gbWF4UXVldWVkQnl0ZXMpXG4gICAgICB0aHJvdyBxdWV1ZUZ1bGwoYWJzb2x1dGUsIHF1ZXVlZEJ5dGVzLCBtYXhRdWV1ZWRCeXRlcywgZW50cnkua2luZCk7XG4gICAgY29uc3QganNvbiA9IEpTT04uc3RyaW5naWZ5KGVudHJ5KTsgLy8gYW4gZW50cnkgSlNPTiBjYW5ub3Qgd3JpdGUgKGEgQmlnSW50LCBhIGN5Y2xlKSB0aHJvd3MgaGVyZSwgd2hvbGVcbiAgICAvLyBBIHN0cmluZydzIGxlbmd0aCBuZXZlciBleGNlZWRzIGl0cyBVVEYtOCBzaXplOiBhbiBlbnRyeSBhbHJlYWR5IHRvbyBsb25nIGlzIHJlZnVzZWQgYmVmb3JlIGl0IGlzIGVuY29kZWQuXG4gICAgaWYgKGpzb24ubGVuZ3RoICsgMSA+IG1heEVudHJ5Qnl0ZXMpIHRocm93IHRvb0xhcmdlKGFic29sdXRlLCBlbnRyeS5raW5kLCBtYXhFbnRyeUJ5dGVzKTtcbiAgICBjb25zdCBlbmNvZGVkID0gZW5jb2Rlci5lbmNvZGUoYCR7bmVlZHNOZXdsaW5lID8gJ1xcbicgOiAnJ30ke2pzb259XFxuYCk7XG4gICAgaWYgKGVuY29kZWQubGVuZ3RoID4gbWF4RW50cnlCeXRlcyArIDEpIHRocm93IHRvb0xhcmdlKGFic29sdXRlLCBlbnRyeS5raW5kLCBtYXhFbnRyeUJ5dGVzKTtcbiAgICBjb25zdCBsaW1pdCA9IGVudHJ5LmtpbmQgPT09ICdjbG9zZWQnID8gbWF4Qnl0ZXMgKyBDTE9TRV9SRVNFUlZFX0JZVEVTIDogbWF4Qnl0ZXM7XG4gICAgaWYgKG5leHQgKyBlbmNvZGVkLmxlbmd0aCA+IGxpbWl0KSB7XG4gICAgICBpZiAoZW50cnkua2luZCAhPT0gJ2Nsb3NlZCcpIGZ1bGwgPSB0cnVlO1xuICAgICAgdGhyb3cgZmlsZUZ1bGwoYWJzb2x1dGUsIG1heEJ5dGVzLCBlbnRyeS5raW5kKTtcbiAgICB9XG4gICAgaWYgKCFpc0Nsb3NpbmdFbnRyeSAmJiBxdWV1ZWRCeXRlcyArIGVuY29kZWQubGVuZ3RoID4gbWF4UXVldWVkQnl0ZXMpIHtcbiAgICAgIHRocm93IHF1ZXVlRnVsbChhYnNvbHV0ZSwgcXVldWVkQnl0ZXMsIG1heFF1ZXVlZEJ5dGVzLCBlbnRyeS5raW5kKTtcbiAgICB9XG4gICAgbmVlZHNOZXdsaW5lID0gZmFsc2U7XG4gICAgY29uc3QgYXQgPSBuZXh0O1xuICAgIG5leHQgKz0gZW5jb2RlZC5sZW5ndGg7XG4gICAgcXVldWVkQnl0ZXMgKz0gZW5jb2RlZC5sZW5ndGg7XG4gICAgaW5GbGlnaHQgKz0gMTtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgd3JpdGVBdChmZCwgZW5jb2RlZCwgYXQsIChlcnJvciwgd3JvdGUpID0+IHtcbiAgICAgICAgaW5GbGlnaHQgLT0gMTtcbiAgICAgICAgcXVldWVkQnl0ZXMgLT0gZW5jb2RlZC5sZW5ndGg7XG4gICAgICAgIHdyaXR0ZW4gKz0gd3JvdGU7XG4gICAgICAgIC8vIEEgbGluZSBjdXQgc2hvcnQgbGVhdmVzIGEgaG9sZSB1cCB0byB0aGUgbmV4dCBlbnRyeSdzIG9mZnNldDogdGhlIHJlYWRlciBzcGxpdHMgYXQgaXQgKE5VTCksIHNvIGEgdG9yblxuICAgICAgICAvLyBsaW5lIG5ldmVyIHN3YWxsb3dzIHRoZSBlbnRyeSBhZnRlciBpdC5cbiAgICAgICAgaWYgKGVycm9yKSByZWplY3QoZXJyb3IpO1xuICAgICAgICBlbHNlIHJlc29sdmUoKTtcbiAgICAgICAgc2V0dGxlRHJhaW5lZCgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgcmV0dXJuIHtcbiAgICBwYXRoOiBhYnNvbHV0ZSxcbiAgICBnZXQgYnl0ZXMoKSB7XG4gICAgICByZXR1cm4gd3JpdHRlbjtcbiAgICB9LFxuICAgIGdldCBxdWV1ZWRCeXRlcygpIHtcbiAgICAgIHJldHVybiBxdWV1ZWRCeXRlcztcbiAgICB9LFxuICAgIGdldCBmdWxsKCkge1xuICAgICAgcmV0dXJuIGZ1bGw7XG4gICAgfSxcbiAgICBvcGVuZWQ6ICh7IGFkZHJlc3MsIGF0LCBpbml0aWFsU3RhdGUsIG1ldGEgfSkgPT5cbiAgICAgIGVucXVldWUoeyBraW5kOiAnb3BlbmVkJywgYWRkcmVzcywgYXQsIGluaXRpYWxTdGF0ZSwgLi4uKG1ldGEgPT09IHVuZGVmaW5lZCA/IHt9IDogeyBtZXRhIH0pIH0pLFxuICAgIGNvbW1pdDogKHsgYWRkcmVzcywgYXQsIGJ1bmRsZSB9KSA9PiBlbnF1ZXVlKHsga2luZDogJ2NvbW1pdCcsIGFkZHJlc3MsIGF0LCBidW5kbGUgfSksXG4gICAgbm90ZTogKHsgYWRkcmVzcywgYXQsIGtpbmQsIGRhdGEgfSkgPT4gZW5xdWV1ZSh7IGtpbmQ6ICdub3RlJywgYWRkcmVzcywgYXQsIG5vdGU6IGtpbmQsIGRhdGEgfSksXG4gICAgY2xvc2VkOiAoeyBhZGRyZXNzLCBhdCwgb3V0Y29tZSwgY29tbWl0cywgbWV0YSB9KSA9PlxuICAgICAgZW5xdWV1ZSh7IGtpbmQ6ICdjbG9zZWQnLCBhZGRyZXNzLCBhdCwgb3V0Y29tZSwgY29tbWl0cywgLi4uKG1ldGEgPT09IHVuZGVmaW5lZCA/IHt9IDogeyBtZXRhIH0pIH0pLFxuICAgIGZsdXNoOiAoKSA9PiB7XG4gICAgICBpZiAoY2xvc2luZykgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihgZmlsZVNpbms6ICR7YWJzb2x1dGV9IGlzIGNsb3NlZGApKTtcbiAgICAgIGNvbnN0IHdvcmsgPSBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGRyYWluZWQucHVzaCgoKSA9PiB7XG4gICAgICAgICAgc3luY2luZyArPSAxO1xuICAgICAgICAgIGZzeW5jKGZkLCAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICBzeW5jaW5nIC09IDE7XG4gICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgIHJlbGVhc2VJZklkbGUoKTtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQW5vdGhlciB3cml0ZXIgKGFub3RoZXIgcHJvY2VzcyBvbiB0aGUgc2FtZSBwYXRoKSBncmV3IHRoZSBmaWxlIHBhc3Qgd2hhdCB0aGlzIHNpbmsgcGxhY2VkOiBpdHNcbiAgICAgICAgICAgIC8vIGVudHJpZXMgYW5kIG91cnMgb3ZlcmxhcC4gU2FpZCwgbmV2ZXIgc2lsZW50LlxuICAgICAgICAgICAgZnN0YXQoZmQsIChzdGF0RXJyb3IsIHN0YXQpID0+IHtcbiAgICAgICAgICAgICAgc3luY2luZyAtPSAxO1xuICAgICAgICAgICAgICBpZiAoc3RhdEVycm9yKSByZWplY3Qoc3RhdEVycm9yKTtcbiAgICAgICAgICAgICAgZWxzZSBpZiAoc3RhdC5zaXplID4gbmV4dCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYGZpbGVTaW5rOiAke2Fic29sdXRlfSB3YXMgd3JpdHRlbiBieSBhbm90aGVyIHdyaXRlciAob25lIHNpbmsgcGVyIGZpbGUpYCkpO1xuICAgICAgICAgICAgICB9IGVsc2UgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICByZWxlYXNlSWZJZGxlKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHNldHRsZURyYWluZWQoKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHdpdGhUaW1lb3V0KFxuICAgICAgICB3b3JrLFxuICAgICAgICBmbHVzaFRpbWVvdXRNcyxcbiAgICAgICAgYGZpbGVTaW5rOiBmbHVzaCgpIG9mICR7YWJzb2x1dGV9IGRpZCBub3QgZmluaXNoIGluICR7Zmx1c2hUaW1lb3V0TXN9bXNgLFxuICAgICAgKTtcbiAgICB9LFxuICAgIGNsb3NlOiAoKSA9PiB7XG4gICAgICBpZiAoIWNsb3NpbmcpIHtcbiAgICAgICAgY2xvc2luZyA9IHRydWU7XG4gICAgICAgIHJlbGVhc2VJZklkbGUoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB3aGVuUmVsZWFzZWQ7XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBGaWxlcyBhIHNpbmsgb2YgdGhpcyBwcm9jZXNzIGhhcyBvcGVuLCBieSBkZXZpY2UgYW5kIGlub2RlIOKAlCBvbmUgd3JpdGVyIHBlciBmaWxlLiBLZXB0IG9uIHRoZSBnbG9iYWwgb2JqZWN0LCBzb1xuICogdGhlIHBhY2thZ2UncyBDb21tb25KUyBhbmQgRVNNIGJ1aWxkcyAodHdvIG1vZHVsZSBpbnN0YW5jZXMgaW4gb25lIHByb2Nlc3MpIHNoYXJlIGl0LlxuICovXG5jb25zdCBPUEVOX0ZJTEVTOiBTZXQ8c3RyaW5nPiA9ICgoZ2xvYmFsVGhpcyBhcyBSZWNvcmQ8c3ltYm9sLCB1bmtub3duPilbU3ltYm9sLmZvcignZm9vdHByaW50anMuZmlsZVNpbmsub3BlbicpXSA/Pz1cbiAgbmV3IFNldDxzdHJpbmc+KCkpIGFzIFNldDxzdHJpbmc+O1xuXG5mdW5jdGlvbiBmaWxlRnVsbChwYXRoOiBzdHJpbmcsIG1heEJ5dGVzOiBudW1iZXIsIGtpbmQ6IHN0cmluZyk6IFJhbmdlRXJyb3Ige1xuICByZXR1cm4gbmV3IFJhbmdlRXJyb3IoYGZpbGVTaW5rOiAke3BhdGh9IGlzIGZ1bGwgKG1heEJ5dGVzICR7bWF4Qnl0ZXN9KTsgdGhpcyAke2tpbmR9IGVudHJ5IHdhcyBub3Qgd3JpdHRlbmApO1xufVxuXG5mdW5jdGlvbiBxdWV1ZUZ1bGwocGF0aDogc3RyaW5nLCBxdWV1ZWQ6IG51bWJlciwgbWF4UXVldWVkQnl0ZXM6IG51bWJlciwga2luZDogc3RyaW5nKTogUmFuZ2VFcnJvciB7XG4gIHJldHVybiBuZXcgUmFuZ2VFcnJvcihcbiAgICBgZmlsZVNpbms6ICR7cGF0aH0gaGFzICR7cXVldWVkfSBieXRlcyB3YWl0aW5nIChtYXhRdWV1ZWRCeXRlcyAke21heFF1ZXVlZEJ5dGVzfSk7IHRoaXMgJHtraW5kfSBlbnRyeSB3YXMgZHJvcHBlZGAsXG4gICk7XG59XG5cbi8qKiBBIGJvdW5kIHJlYWQgb2ZmIHRoZSBvcHRpb25zOiBhYnNlbnQg4oaSIHRoZSBkZWZhdWx0OyBlbHNlIGEgd2hvbGUgbnVtYmVyIOKJpSBgbWluYCwgb3IgYSBSYW5nZUVycm9yIG5hbWluZyBpdC4gKi9cbmZ1bmN0aW9uIGJvdW5kKG5hbWU6IHN0cmluZywgdmFsdWU6IG51bWJlciB8IHVuZGVmaW5lZCwgZmFsbGJhY2s6IG51bWJlciwgbWluOiBudW1iZXIpOiBudW1iZXIge1xuICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkgcmV0dXJuIGZhbGxiYWNrO1xuICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKHZhbHVlKSB8fCB2YWx1ZSA8IG1pbikge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBmaWxlU2luazogJHtuYW1lfSBtdXN0IGJlIGEgd2hvbGUgbnVtYmVyLCBhdCBsZWFzdCAke21pbn1gKTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIHRvb0xhcmdlKHBhdGg6IHN0cmluZywga2luZDogc3RyaW5nLCBtYXhFbnRyeUJ5dGVzOiBudW1iZXIpOiBSYW5nZUVycm9yIHtcbiAgcmV0dXJuIG5ldyBSYW5nZUVycm9yKFxuICAgIGBmaWxlU2luazogYSAke2tpbmR9IGVudHJ5IGxhcmdlciB0aGFuIG1heEVudHJ5Qnl0ZXMgKCR7bWF4RW50cnlCeXRlc30pIHdhcyBub3Qgd3JpdHRlbiB0byAke3BhdGh9YCxcbiAgKTtcbn1cblxuLyoqIFdyaXRlIGFsbCBvZiBgYnVmZmVyYCBhdCBgcG9zaXRpb25gIChhc3luY2hyb25vdXNseSwgYXMgbWFueSB3cml0ZXMgYXMgaXQgdGFrZXMpOyBgd3JvdGVgIGlzIGhvdyBtdWNoIHdlbnQgb3V0LiAqL1xuZnVuY3Rpb24gd3JpdGVBdChcbiAgZmQ6IG51bWJlcixcbiAgYnVmZmVyOiBVaW50OEFycmF5LFxuICBwb3NpdGlvbjogbnVtYmVyLFxuICBkb25lOiAoZXJyb3I6IEVycm9yIHwgbnVsbCwgd3JvdGU6IG51bWJlcikgPT4gdm9pZCxcbik6IHZvaWQge1xuICBjb25zdCBzdGVwID0gKG9mZnNldDogbnVtYmVyKTogdm9pZCA9PiB7XG4gICAgd3JpdGUoZmQsIGJ1ZmZlciwgb2Zmc2V0LCBidWZmZXIubGVuZ3RoIC0gb2Zmc2V0LCBwb3NpdGlvbiArIG9mZnNldCwgKGVycm9yLCBuKSA9PiB7XG4gICAgICBpZiAoZXJyb3IpIGRvbmUoZXJyb3IsIG9mZnNldCk7XG4gICAgICBlbHNlIGlmIChuID09PSAwKSBkb25lKG5ldyBFcnJvcignZmlsZVNpbms6IHRoZSBkaXNrIHRvb2sgbm8gYnl0ZXMnKSwgb2Zmc2V0KTtcbiAgICAgIGVsc2UgaWYgKG9mZnNldCArIG4gPCBidWZmZXIubGVuZ3RoKSBzdGVwKG9mZnNldCArIG4pO1xuICAgICAgZWxzZSBkb25lKG51bGwsIGJ1ZmZlci5sZW5ndGgpO1xuICAgIH0pO1xuICB9O1xuICBzdGVwKDApO1xufVxuXG4vKiogYHdvcmtgLCBvciBhIHJlamVjdGlvbiBuYW1pbmcgdGhlIGJvdW5kIG9uY2UgYG1zYCBwYXNzZWQg4oCUIHRoZSB3b3JrIGdvZXMgb24sIG5vYm9keSB3YWl0cyBmb3IgaXQuICovXG5mdW5jdGlvbiB3aXRoVGltZW91dCh3b3JrOiBQcm9taXNlPHZvaWQ+LCBtczogbnVtYmVyLCBtZXNzYWdlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4gcmVqZWN0KG5ldyBFcnJvcihtZXNzYWdlKSksIG1zKTtcbiAgICAvLyBBIHRpbWVyIHRoYXQgb25seSBib3VuZHMgYSB3YWl0IG5ldmVyIGtlZXBzIHRoZSBwcm9jZXNzIGFsaXZlIG9uIGl0cyBvd24uXG4gICAgKHRpbWVyIGFzIHsgdW5yZWY/OiAoKSA9PiB2b2lkIH0pLnVucmVmPy4oKTtcbiAgICBQcm9taXNlLnByb3RvdHlwZS50aGVuLmNhbGwoXG4gICAgICB3b3JrLFxuICAgICAgKCkgPT4ge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9LFxuICAgICAgKGVycm9yOiB1bmtub3duKSA9PiB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICB9LFxuICAgICk7XG4gIH0pO1xufVxuXG4vKipcbiAqIFJlZnVzZSBhIGZpbGUgc29tZW9uZSBlbHNlIGNvdWxkIHJlYWQgb3IgcmV3cml0ZSBiZWhpbmQgdGhlIHNpbms6IGEgaGFyZCBsaW5rIChhbm90aGVyIG5hbWUgZm9yIHRoZSBzYW1lIGJ5dGVzIOKAlFxuICogdGhlIHNpbmsgd291bGQgYXBwZW5kIGludG8gaXQpLCBhIGZpbGUgb3duZWQgYnkgYW5vdGhlciB1c2VyLCBvciBvbmUgb3RoZXJzIG1heSB3cml0ZS4gQSBmaWxlIHRoZSBzaW5rIGNyZWF0ZXMgaXNcbiAqIGAwbzYwMGAgYW5kIHBhc3NlczsgYSBwcmUtZXhpc3Rpbmcgb25lIG11c3QgYWxyZWFkeSBiZSBwcml2YXRlIHRvIHRoZSB3cml0ZXIuIChOb3Qgb24gV2luZG93cywgd2hvc2UgbW9kZXMgYW5kXG4gKiBvd25lcnMgZG8gbm90IG1hcDogdGhlcmUgYE9fTk9GT0xMT1dgIGlzIGFic2VudCB0b28g4oCUIHRoZSBndWlkZSBuYW1lcyBib3RoLilcbiAqL1xuZnVuY3Rpb24gcmVmdXNlRm9yZWlnbihwYXRoOiBzdHJpbmcsIHN0YXQ6IHsgcmVhZG9ubHkgbmxpbms6IG51bWJlcjsgcmVhZG9ubHkgdWlkOiBudW1iZXI7IHJlYWRvbmx5IG1vZGU6IG51bWJlciB9KSB7XG4gIGlmIChzdGF0Lm5saW5rID4gMSkgdGhyb3cgbmV3IFR5cGVFcnJvcihgZmlsZVNpbms6ICR7cGF0aH0gaGFzIG90aGVyIGhhcmQgbGlua3Mg4oCUIHJlZnVzaW5nIHRvIHdyaXRlIHRocm91Z2ggb25lYCk7XG4gIGNvbnN0IHVpZCA9IHR5cGVvZiBnZXR1aWQgPT09ICdmdW5jdGlvbicgPyBnZXR1aWQoKSA6IHVuZGVmaW5lZDtcbiAgaWYgKHVpZCAhPT0gdW5kZWZpbmVkICYmIHN0YXQudWlkICE9PSB1aWQpIHRocm93IG5ldyBUeXBlRXJyb3IoYGZpbGVTaW5rOiAke3BhdGh9IGJlbG9uZ3MgdG8gYW5vdGhlciB1c2VyYCk7XG4gIGlmICh1aWQgIT09IHVuZGVmaW5lZCAmJiAoc3RhdC5tb2RlICYgMG8wMjIpICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgZmlsZVNpbms6ICR7cGF0aH0gaXMgd3JpdGFibGUgYnkgb3RoZXJzIOKAlCBtYWtlIGl0IDBvNjAwIChvciByZW1vdmUgaXQpIGZpcnN0YCk7XG4gIH1cbn1cblxuLyoqIFdoZXRoZXIgdGhlIGZpbGUncyBsYXN0IGJ5dGUgaXMgYSBuZXdsaW5lIOKAlCByZWFkIG9uY2UsIHdoZW4gdGhlIHNpbmsgb3BlbnMgYW4gZXhpc3RpbmcgZmlsZS4gKi9cbmZ1bmN0aW9uIGVuZHNXaXRoTmV3bGluZShmZDogbnVtYmVyLCBzaXplOiBudW1iZXIpOiBib29sZWFuIHtcbiAgY29uc3QgbGFzdCA9IG5ldyBVaW50OEFycmF5KDEpO1xuICByZXR1cm4gcmVhZFN5bmMoZmQsIGxhc3QsIDAsIDEsIHNpemUgLSAxKSA9PT0gMSAmJiBsYXN0WzBdID09PSAweDBhO1xufVxuXG4vKiogQSByZWNvcmQgZmlsZSByZWFkIGJhY2s6IGV2ZXJ5IHBhcnNlZCBsaW5lLCBhbmQgZXZlcnkgbGluZSB0aGF0IGNvdWxkIG5vdCBiZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVjb3JkRmlsZSB7XG4gIC8qKiBUaGUgcGFyc2VkIGVudHJpZXMsIGluIGZpbGUgb3JkZXIg4oCUIHVudHJ1c3RlZCBpbnB1dCBmb3IgYHJlYWRTdG9yZWRSZWNvcmRgIChgZm9vdHRyYWNlYCkuICovXG4gIHJlYWRvbmx5IGVudHJpZXM6IHJlYWRvbmx5IHVua25vd25bXTtcbiAgLyoqIEVhY2ggbGluZSB0aGF0IGlzIG5vdCBKU09OIChhIHRvcm4gbGFzdCBsaW5lLCBhIGNvcnJ1cHQgb25lKSwgYnkgaXRzIDEtYmFzZWQgbnVtYmVyLiBCbGFuayBsaW5lcyBhcmUgc2tpcHBlZC4gKi9cbiAgcmVhZG9ubHkgdW5yZWFkYWJsZTogcmVhZG9ubHkgeyByZWFkb25seSBsaW5lOiBudW1iZXI7IHJlYWRvbmx5IHJlYXNvbjogc3RyaW5nIH1bXTtcbn1cblxuLyoqXG4gKiBSZWFkIGEgcmVjb3JkIGZpbGUgYmFjaywgbGluZSBieSBsaW5lIOKAlCB0aGUgZW50cmllcyBmb3IgYHJlYWRTdG9yZWRSZWNvcmRgLCBhbmQgZXZlcnkgbGluZSB0aGF0IGNvdWxkIG5vdCBiZVxuICogcmVhZCwgYnkgbnVtYmVyLCBuZXZlciBhIGZhaWxlZCByZWFkLiBBIHN0b3JlZCBrZXkgbmFtZWQgYF9fcHJvdG9fX2Agc3RheXMgZGF0YSAoYEpTT04ucGFyc2VgIG1ha2VzIGl0IGFuIG93blxuICogcHJvcGVydHkpLiBUaGUgZmlsZSBpcyB1bnRydXN0ZWQ6IGEgZmlsZSBsYXJnZXIgdGhhbiBgbWF4Qnl0ZXNgIChkZWZhdWx0IDI1NiBNaUIpIGlzIHJlZnVzZWQgYmVmb3JlIGl0IGlzIHJlYWQuXG4gKlxuICogQHRocm93cyBSYW5nZUVycm9yIHdoZW4gdGhlIGZpbGUgaXMgbGFyZ2VyIHRoYW4gYG1heEJ5dGVzYDsgdGhlIG9wZXJhdGluZyBzeXN0ZW0ncyBlcnJvciB3aGVuIGl0IGNhbm5vdCBiZSByZWFkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZFJlY29yZEZpbGUocGF0aDogc3RyaW5nLCBvcHRpb25zPzogeyByZWFkb25seSBtYXhCeXRlcz86IG51bWJlciB9KTogUmVjb3JkRmlsZSB7XG4gIGlmICh0eXBlb2YgcGF0aCAhPT0gJ3N0cmluZycgfHwgcGF0aCA9PT0gJycpIHRocm93IG5ldyBUeXBlRXJyb3IoJ3JlYWRSZWNvcmRGaWxlOiBwYXRoIG11c3QgYmUgYSBub24tZW1wdHkgc3RyaW5nJyk7XG4gIGNvbnN0IG1heEJ5dGVzID0gYm91bmQoJ21heEJ5dGVzJywgb3B0aW9ucz8ubWF4Qnl0ZXMsIERFRkFVTFRfUkVBRF9NQVhfQllURVMsIDEpO1xuICAvLyBPbmUgZGVzY3JpcHRvciBmb3IgdGhlIGNoZWNrIEFORCB0aGUgcmVhZCAoYSBmaWxlIHRoYXQgZ3Jvd3MgYmV0d2VlbiB0aGVtIGlzIHN0aWxsIGJvdW5kZWQpOyBhIHJlZ3VsYXIgZmlsZVxuICAvLyBvbmx5IChhIEZJRk8gd291bGQgYmxvY2ssIGEgZGV2aWNlIG5ldmVyIGVuZCk7IGF0IG1vc3QgYG1heEJ5dGVzYCByZWFkLlxuICAvLyBPX05PTkJMT0NLOiBhIEZJRk8gYXQgdGhlIHBhdGggbXVzdCBub3QgYmxvY2sgdGhlIG9wZW4gYmVmb3JlIHRoZSByZWd1bGFyLWZpbGUgY2hlY2sgcmVmdXNlcyBpdC5cbiAgY29uc3QgZmQgPSBvcGVuU3luYyhwYXRoLCBjb25zdGFudHMuT19SRE9OTFkgfCAoY29uc3RhbnRzLk9fTk9GT0xMT1cgPz8gMCkgfCAoY29uc3RhbnRzLk9fTk9OQkxPQ0sgPz8gMCkpO1xuICBsZXQgcmF3OiBVaW50OEFycmF5O1xuICB0cnkge1xuICAgIGNvbnN0IHN0YXQgPSBmc3RhdFN5bmMoZmQpO1xuICAgIGlmICghc3RhdC5pc0ZpbGUoKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihgcmVhZFJlY29yZEZpbGU6ICR7cGF0aH0gaXMgbm90IGEgcmVndWxhciBmaWxlYCk7XG4gICAgaWYgKHN0YXQuc2l6ZSA+IG1heEJ5dGVzKSB7XG4gICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgcmVhZFJlY29yZEZpbGU6ICR7cGF0aH0gaG9sZHMgJHtzdGF0LnNpemV9IGJ5dGVzLCBwYXN0IHRoZSBsaW1pdCBvZiAke21heEJ5dGVzfWApO1xuICAgIH1cbiAgICBjb25zdCBidWZmZXIgPSBuZXcgVWludDhBcnJheShNYXRoLm1pbihzdGF0LnNpemUsIG1heEJ5dGVzKSArIDEpO1xuICAgIGxldCByZWFkID0gMDtcbiAgICBmb3IgKDs7KSB7XG4gICAgICBjb25zdCBuID0gcmVhZFN5bmMoZmQsIGJ1ZmZlciwgcmVhZCwgYnVmZmVyLmxlbmd0aCAtIHJlYWQsIHJlYWQpO1xuICAgICAgaWYgKG4gPT09IDApIGJyZWFrO1xuICAgICAgcmVhZCArPSBuO1xuICAgICAgaWYgKHJlYWQgPT09IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYHJlYWRSZWNvcmRGaWxlOiAke3BhdGh9IGdyZXcgcGFzdCB0aGUgbGltaXQgb2YgJHttYXhCeXRlc30gYnl0ZXMgd2hpbGUgYmVpbmcgcmVhZGApO1xuICAgICAgfVxuICAgIH1cbiAgICByYXcgPSBidWZmZXIuc3ViYXJyYXkoMCwgcmVhZCk7XG4gIH0gZmluYWxseSB7XG4gICAgY2xvc2VTeW5jKGZkKTtcbiAgfVxuICBjb25zdCB0ZXh0ID0gbmV3IFRleHREZWNvZGVyKCd1dGYtOCcpLmRlY29kZShyYXcpO1xuICBjb25zdCBlbnRyaWVzOiB1bmtub3duW10gPSBbXTtcbiAgY29uc3QgdW5yZWFkYWJsZTogeyBsaW5lOiBudW1iZXI7IHJlYXNvbjogc3RyaW5nIH1bXSA9IFtdO1xuICBjb25zdCBsaW5lcyA9IHRleHQuc3BsaXQoJ1xcbicpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgLy8gQSBydW4gb2YgTlVMIGJ5dGVzIGlzIGEgaG9sZSBhIGN1dC1zaG9ydCB3cml0ZSBsZWZ0IGJlZm9yZSB0aGUgbmV4dCBlbnRyeSdzIG9mZnNldDogaXQgZW5kcyB0aGUgdG9ybiBwYXJ0LFxuICAgIC8vIHNvIHRoZSBlbnRyeSBhZnRlciBpdCByZWFkcyBvbiBpdHMgb3duICh0aGUgc2FtZSBsaW5lIG51bWJlciBuYW1lcyBib3RoIHBpZWNlcykuXG4gICAgY29uc3QgbGluZSA9IGxpbmVzW2ldO1xuICAgIC8vIEEgaG9sZSBpcyByZXBvcnRlZCwgbmV2ZXIgc2tpcHBlZDogYnl0ZXMgdGhhdCBuZXZlciByZWFjaGVkIHRoZSBkaXNrIG1heSBiZSBhIHdob2xlIGVudHJ5IGxvc3QgbWlkLWZpbGUuXG4gICAgaWYgKGxpbmUuaW5jbHVkZXMoJ1xcMCcpKSB1bnJlYWRhYmxlLnB1c2goeyBsaW5lOiBpICsgMSwgcmVhc29uOiAnYSBob2xlIOKAlCBieXRlcyB0aGF0IG5ldmVyIHJlYWNoZWQgdGhlIGRpc2snIH0pO1xuICAgIGZvciAoY29uc3QgcGllY2Ugb2YgbGluZS5zcGxpdCgvXFwwKy8pKSB7XG4gICAgICBpZiAocGllY2UudHJpbSgpID09PSAnJykgY29udGludWU7XG4gICAgICB0cnkge1xuICAgICAgICBlbnRyaWVzLnB1c2goSlNPTi5wYXJzZShwaWVjZSkpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHVucmVhZGFibGUucHVzaCh7IGxpbmU6IGkgKyAxLCByZWFzb246ICdub3QgSlNPTiDigJQgYSB0b3JuIG9yIGNvcnJ1cHQgbGluZScgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiB7IGVudHJpZXMsIHVucmVhZGFibGUgfTtcbn1cbiJdfQ==
|
package/dist/recorders.js
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* Pass directly to chart.recorder(). No wrapping, no proxying -- just the class + shortcuts.
|
|
26
26
|
*/
|
|
27
27
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
-
exports.CompositeRecorder = exports.windowed = exports.milestone = exports.adaptive = exports.manifest = exports.debug = exports.metrics = exports.narrative = void 0;
|
|
28
|
+
exports.attempts = exports.CompositeRecorder = exports.memoryStore = exports.windowed = exports.milestone = exports.adaptive = exports.manifest = exports.debug = exports.metrics = exports.narrative = void 0;
|
|
29
29
|
const CombinedNarrativeRecorder_js_1 = require("./lib/engine/narrative/CombinedNarrativeRecorder.js");
|
|
30
30
|
const AdaptiveNarrativeFlowRecorder_js_1 = require("./lib/engine/narrative/recorders/AdaptiveNarrativeFlowRecorder.js");
|
|
31
31
|
const ManifestFlowRecorder_js_1 = require("./lib/engine/narrative/recorders/ManifestFlowRecorder.js");
|
|
@@ -86,6 +86,14 @@ function windowed(maxEntries) {
|
|
|
86
86
|
return new WindowedNarrativeFlowRecorder_js_1.WindowedNarrativeFlowRecorder(maxEntries);
|
|
87
87
|
}
|
|
88
88
|
exports.windowed = windowed;
|
|
89
|
+
var AttemptRecorder_js_1 = require("./lib/recorder/AttemptRecorder.js");
|
|
90
|
+
Object.defineProperty(exports, "memoryStore", { enumerable: true, get: function () { return AttemptRecorder_js_1.memoryStore; } });
|
|
89
91
|
var index_js_1 = require("./lib/recorder/index.js");
|
|
90
92
|
Object.defineProperty(exports, "CompositeRecorder", { enumerable: true, get: function () { return index_js_1.CompositeRecorder; } });
|
|
91
|
-
|
|
93
|
+
const AttemptRecorder_js_2 = require("./lib/recorder/AttemptRecorder.js");
|
|
94
|
+
/** Collect payload-free attempts during traversal; storage adapters are optional and provider-neutral. */
|
|
95
|
+
function attempts(options) {
|
|
96
|
+
return new AttemptRecorder_js_2.AttemptRecorder(options);
|
|
97
|
+
}
|
|
98
|
+
exports.attempts = attempts;
|
|
99
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3JlY29yZGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQkc7QUFDSDs7Ozs7OztHQU9HOzs7QUFHSCxzR0FBZ0c7QUFnQmhHLHdIQUFrSDtBQUVsSCxzR0FBZ0c7QUFDaEcsMEhBQW9IO0FBQ3BILHdIQUFrSDtBQUdsSCw2RUFBdUU7QUFFdkUsK0VBQXlFO0FBZXpFLFNBQWdCLFNBQVMsQ0FBQyxPQUEwQztJQUNsRSxPQUFPLElBQUksd0RBQXlCLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDaEQsQ0FBQztBQUZELDhCQUVDO0FBWUQsU0FBZ0IsT0FBTyxDQUFDLE9BQStCO0lBQ3JELE1BQU0sR0FBRyxHQUFHLElBQUksa0NBQWMsQ0FBQyxPQUFPLENBQW9CLENBQUM7SUFDM0QsR0FBRyxDQUFDLEtBQUssR0FBRztRQUNWLE9BQU8sSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLFVBQVUsQ0FBQztJQUN0QyxDQUFDLENBQUM7SUFDRixHQUFHLENBQUMsTUFBTSxHQUFHO1FBQ1gsT0FBTyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsV0FBVyxDQUFDO0lBQ3ZDLENBQUMsQ0FBQztJQUNGLEdBQUcsQ0FBQyxPQUFPLEdBQUc7UUFDWixPQUFPLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxZQUFZLENBQUM7SUFDeEMsQ0FBQyxDQUFDO0lBQ0YsR0FBRyxDQUFDLEtBQUssR0FBRyxVQUFnQyxJQUFZO1FBQ3RELE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNwQyxDQUFDLENBQUM7SUFDRixHQUFHLENBQUMsR0FBRyxHQUFHO1FBQ1IsT0FBTyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDM0IsQ0FBQyxDQUFDO0lBQ0YsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBbEJELDBCQWtCQztBQVFELFNBQWdCLEtBQUssQ0FBQyxPQUE4QjtJQUNsRCxNQUFNLEdBQUcsR0FBRyxJQUFJLGdDQUFhLENBQUMsT0FBTyxDQUFrQixDQUFDO0lBQ3hELEdBQUcsQ0FBQyxJQUFJLEdBQUc7UUFDVCxPQUFPLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUMzQixDQUFDLENBQUM7SUFDRixPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFORCxzQkFNQztBQVFELFNBQWdCLFFBQVE7SUFDdEIsTUFBTSxHQUFHLEdBQUcsSUFBSSw4Q0FBb0IsRUFBc0IsQ0FBQztJQUMzRCxHQUFHLENBQUMsT0FBTyxHQUFHO1FBQ1osT0FBTyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDNUIsQ0FBQyxDQUFDO0lBQ0YsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBTkQsNEJBTUM7QUFFRCxxQ0FBcUM7QUFFckMsU0FBZ0IsUUFBUTtJQUN0QixPQUFPLElBQUksZ0VBQTZCLEVBQUUsQ0FBQztBQUM3QyxDQUFDO0FBRkQsNEJBRUM7QUFDRCxTQUFnQixTQUFTO0lBQ3ZCLE9BQU8sSUFBSSxrRUFBOEIsRUFBRSxDQUFDO0FBQzlDLENBQUM7QUFGRCw4QkFFQztBQUNELFNBQWdCLFFBQVEsQ0FBQyxVQUFtQjtJQUMxQyxPQUFPLElBQUksZ0VBQTZCLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDdkQsQ0FBQztBQUZELDRCQUVDO0FBbUNELHdFQUFnRTtBQUF2RCxpSEFBQSxXQUFXLE9BQUE7QUFFcEIsb0RBQTREO0FBQW5ELDZHQUFBLGlCQUFpQixPQUFBO0FBRTFCLDBFQUFvRTtBQUNwRSwwR0FBMEc7QUFDMUcsU0FBZ0IsUUFBUSxDQUFDLE9BQWdDO0lBQ3ZELE9BQU8sSUFBSSxvQ0FBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3RDLENBQUM7QUFGRCw0QkFFQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogZm9vdHByaW50anMvcmVjb3JkZXJzIOKAlCBGYWN0b3J5IGZ1bmN0aW9ucyBmb3IgYnVpbHQtaW4gcmVjb3JkZXJzLlxuICpcbiAqIFByZWZlciB0aGVzZSBmYWN0b3J5IGZ1bmN0aW9ucyBvdmVyIGNvbnN0cnVjdGluZyByZWNvcmRlciBjbGFzc2VzIGRpcmVjdGx5LlxuICogRWFjaCBmYWN0b3J5IHJldHVybnMgdGhlIHJlY29yZGVyIGluc3RhbmNlIGVucmljaGVkIHdpdGggc2hvcnQgY29udmVuaWVuY2UgbWV0aG9kcy5cbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgbmFycmF0aXZlLCBtZXRyaWNzLCBkZWJ1ZywgbWFuaWZlc3QgfSBmcm9tICdmb290cHJpbnRqcy9yZWNvcmRlcnMnO1xuICpcbiAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNoYXJ0XG4gKiAgIC5yZWNvcmRlcihuYXJyYXRpdmUoKSlcbiAqICAgLnJlY29yZGVyKG1ldHJpY3MoKSlcbiAqICAgLnJ1bigpO1xuICogYGBgXG4gKlxuICogQG1vZHVsZSByZWNvcmRlcnNcbiAqL1xuLyoqXG4gKiBmb290cHJpbnRqcy9yZWNvcmRlcnMgLS0gRmFjdG9yeSBmdW5jdGlvbnMgZm9yIGJ1aWx0LWluIHJlY29yZGVycy5cbiAqXG4gKiBJbXBvcnQ6IGltcG9ydCB7IG5hcnJhdGl2ZSwgbWV0cmljcywgZGVidWcsIG1hbmlmZXN0IH0gZnJvbSAnZm9vdHByaW50anMvcmVjb3JkZXJzJztcbiAqXG4gKiBFYWNoIGZhY3RvcnkgcmV0dXJucyB0aGUgcmF3IHJlY29yZGVyIGluc3RhbmNlIHdpdGggYWRkZWQgc2hvcnQgY29udmVuaWVuY2UgbWV0aG9kcy5cbiAqIFBhc3MgZGlyZWN0bHkgdG8gY2hhcnQucmVjb3JkZXIoKS4gTm8gd3JhcHBpbmcsIG5vIHByb3h5aW5nIC0tIGp1c3QgdGhlIGNsYXNzICsgc2hvcnRjdXRzLlxuICovXG5cbmltcG9ydCB0eXBlIHsgQ29tYmluZWROYXJyYXRpdmVSZWNvcmRlck9wdGlvbnMgfSBmcm9tICcuL2xpYi9lbmdpbmUvbmFycmF0aXZlL0NvbWJpbmVkTmFycmF0aXZlUmVjb3JkZXIuanMnO1xuaW1wb3J0IHsgQ29tYmluZWROYXJyYXRpdmVSZWNvcmRlciB9IGZyb20gJy4vbGliL2VuZ2luZS9uYXJyYXRpdmUvQ29tYmluZWROYXJyYXRpdmVSZWNvcmRlci5qcyc7XG5pbXBvcnQgdHlwZSB7XG4gIEF0dGVtcHRSZW5kZXJDb250ZXh0LFxuICBCcmVha1JlbmRlckNvbnRleHQsXG4gIENvbWJpbmVkTmFycmF0aXZlRW50cnksXG4gIERlY2lzaW9uUmVuZGVyQ29udGV4dCxcbiAgRW1pdFJlbmRlckNvbnRleHQsXG4gIEVycm9yUmVuZGVyQ29udGV4dCxcbiAgRm9ya1JlbmRlckNvbnRleHQsXG4gIExvb3BSZW5kZXJDb250ZXh0LFxuICBOYXJyYXRpdmVGb3JtYXR0ZXIsXG4gIE9wUmVuZGVyQ29udGV4dCxcbiAgU2VsZWN0ZWRSZW5kZXJDb250ZXh0LFxuICBTdGFnZVJlbmRlckNvbnRleHQsXG4gIFN1YmZsb3dSZW5kZXJDb250ZXh0LFxufSBmcm9tICcuL2xpYi9lbmdpbmUvbmFycmF0aXZlL25hcnJhdGl2ZVR5cGVzLmpzJztcbmltcG9ydCB7IEFkYXB0aXZlTmFycmF0aXZlRmxvd1JlY29yZGVyIH0gZnJvbSAnLi9saWIvZW5naW5lL25hcnJhdGl2ZS9yZWNvcmRlcnMvQWRhcHRpdmVOYXJyYXRpdmVGbG93UmVjb3JkZXIuanMnO1xuaW1wb3J0IHR5cGUgeyBNYW5pZmVzdEVudHJ5IH0gZnJvbSAnLi9saWIvZW5naW5lL25hcnJhdGl2ZS9yZWNvcmRlcnMvTWFuaWZlc3RGbG93UmVjb3JkZXIuanMnO1xuaW1wb3J0IHsgTWFuaWZlc3RGbG93UmVjb3JkZXIgfSBmcm9tICcuL2xpYi9lbmdpbmUvbmFycmF0aXZlL3JlY29yZGVycy9NYW5pZmVzdEZsb3dSZWNvcmRlci5qcyc7XG5pbXBvcnQgeyBNaWxlc3RvbmVOYXJyYXRpdmVGbG93UmVjb3JkZXIgfSBmcm9tICcuL2xpYi9lbmdpbmUvbmFycmF0aXZlL3JlY29yZGVycy9NaWxlc3RvbmVOYXJyYXRpdmVGbG93UmVjb3JkZXIuanMnO1xuaW1wb3J0IHsgV2luZG93ZWROYXJyYXRpdmVGbG93UmVjb3JkZXIgfSBmcm9tICcuL2xpYi9lbmdpbmUvbmFycmF0aXZlL3JlY29yZGVycy9XaW5kb3dlZE5hcnJhdGl2ZUZsb3dSZWNvcmRlci5qcyc7XG5pbXBvcnQgdHlwZSB7IEVtaXRFdmVudCwgRW1pdFJlY29yZGVyIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvRW1pdFJlY29yZGVyLmpzJztcbmltcG9ydCB0eXBlIHsgRGVidWdFbnRyeSwgRGVidWdSZWNvcmRlck9wdGlvbnMgfSBmcm9tICcuL2xpYi9zY29wZS9yZWNvcmRlcnMvRGVidWdSZWNvcmRlci5qcyc7XG5pbXBvcnQgeyBEZWJ1Z1JlY29yZGVyIH0gZnJvbSAnLi9saWIvc2NvcGUvcmVjb3JkZXJzL0RlYnVnUmVjb3JkZXIuanMnO1xuaW1wb3J0IHR5cGUgeyBBZ2dyZWdhdGVkTWV0cmljcywgTWV0cmljUmVjb3JkZXJPcHRpb25zLCBTdGFnZU1ldHJpY3MgfSBmcm9tICcuL2xpYi9zY29wZS9yZWNvcmRlcnMvTWV0cmljUmVjb3JkZXIuanMnO1xuaW1wb3J0IHsgTWV0cmljUmVjb3JkZXIgfSBmcm9tICcuL2xpYi9zY29wZS9yZWNvcmRlcnMvTWV0cmljUmVjb3JkZXIuanMnO1xuXG4vLyAtLS0tIE5hcnJhdGl2ZSAtLS0tXG5cbi8qKlxuICogU2NvcGVSZWNvcmRlciBmYWN0b3J5IGZvciBjb21iaW5lZCBmbG93K2RhdGEgbmFycmF0aXZlLlxuICpcbiAqIFRoZSByZXR1cm5lZCByZWNvcmRlciBpcyBhIGBDb21iaW5lZE5hcnJhdGl2ZVJlY29yZGVyYCDigJQgYXR0YWNoIGl0IHRvIGFcbiAqIGNoYXJ0L2V4ZWN1dG9yLCB0aGVuIHJlYWQgc3RydWN0dXJlZCBlbnRyaWVzIHZpYSBgLmdldEVudHJpZXMoKWAgYWZ0ZXJcbiAqIHRoZSBydW4uIEZvciBmbGF0IHN0cmluZ3MsIGNhbGwgYC5nZXRFbnRyaWVzKCkubWFwKGUgPT4gZS50ZXh0KWAgbG9jYWxseS5cbiAqIEVhY2ggaW5zdGFuY2UgaGFzIGl0cyBvd24gZ2VuZXJhdGVkIElEOyBkZXRhY2ggdXNpbmcgYHJlY29yZGVyLmlkYC5cbiAqIEl0cyBmb3JtYXR0aW5nIG9wdGlvbnMgYWZmZWN0IHRoaXMgaW5zdGFuY2UsIG5vdCB0aGUgZXhlY3V0b3IncyBvd24gdmlldy5cbiAqL1xuZXhwb3J0IHR5cGUgTmFycmF0aXZlSW5zdGFuY2UgPSBDb21iaW5lZE5hcnJhdGl2ZVJlY29yZGVyO1xuXG5leHBvcnQgZnVuY3Rpb24gbmFycmF0aXZlKG9wdGlvbnM/OiBDb21iaW5lZE5hcnJhdGl2ZVJlY29yZGVyT3B0aW9ucyk6IE5hcnJhdGl2ZUluc3RhbmNlIHtcbiAgcmV0dXJuIG5ldyBDb21iaW5lZE5hcnJhdGl2ZVJlY29yZGVyKG9wdGlvbnMpO1xufVxuXG4vLyAtLS0tIE1ldHJpY3MgLS0tLVxuXG5leHBvcnQgdHlwZSBNZXRyaWNzSW5zdGFuY2UgPSBNZXRyaWNSZWNvcmRlciAmIHtcbiAgcmVhZHMoKTogbnVtYmVyO1xuICB3cml0ZXMoKTogbnVtYmVyO1xuICBjb21taXRzKCk6IG51bWJlcjtcbiAgc3RhZ2UobmFtZTogc3RyaW5nKTogU3RhZ2VNZXRyaWNzIHwgdW5kZWZpbmVkO1xuICBhbGwoKTogQWdncmVnYXRlZE1ldHJpY3M7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gbWV0cmljcyhvcHRpb25zPzogTWV0cmljUmVjb3JkZXJPcHRpb25zKTogTWV0cmljc0luc3RhbmNlIHtcbiAgY29uc3QgcmVjID0gbmV3IE1ldHJpY1JlY29yZGVyKG9wdGlvbnMpIGFzIE1ldHJpY3NJbnN0YW5jZTtcbiAgcmVjLnJlYWRzID0gZnVuY3Rpb24gKHRoaXM6IE1ldHJpY1JlY29yZGVyKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TWV0cmljcygpLnRvdGFsUmVhZHM7XG4gIH07XG4gIHJlYy53cml0ZXMgPSBmdW5jdGlvbiAodGhpczogTWV0cmljUmVjb3JkZXIpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRNZXRyaWNzKCkudG90YWxXcml0ZXM7XG4gIH07XG4gIHJlYy5jb21taXRzID0gZnVuY3Rpb24gKHRoaXM6IE1ldHJpY1JlY29yZGVyKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TWV0cmljcygpLnRvdGFsQ29tbWl0cztcbiAgfTtcbiAgcmVjLnN0YWdlID0gZnVuY3Rpb24gKHRoaXM6IE1ldHJpY1JlY29yZGVyLCBuYW1lOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRTdGFnZU1ldHJpY3MobmFtZSk7XG4gIH07XG4gIHJlYy5hbGwgPSBmdW5jdGlvbiAodGhpczogTWV0cmljUmVjb3JkZXIpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRNZXRyaWNzKCk7XG4gIH07XG4gIHJldHVybiByZWM7XG59XG5cbi8vIC0tLS0gRGVidWcgLS0tLVxuXG5leHBvcnQgdHlwZSBEZWJ1Z0luc3RhbmNlID0gRGVidWdSZWNvcmRlciAmIHtcbiAgbG9ncygpOiBEZWJ1Z0VudHJ5W107XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZGVidWcob3B0aW9ucz86IERlYnVnUmVjb3JkZXJPcHRpb25zKTogRGVidWdJbnN0YW5jZSB7XG4gIGNvbnN0IHJlYyA9IG5ldyBEZWJ1Z1JlY29yZGVyKG9wdGlvbnMpIGFzIERlYnVnSW5zdGFuY2U7XG4gIHJlYy5sb2dzID0gZnVuY3Rpb24gKHRoaXM6IERlYnVnUmVjb3JkZXIpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRFbnRyaWVzKCk7XG4gIH07XG4gIHJldHVybiByZWM7XG59XG5cbi8vIC0tLS0gTWFuaWZlc3QgLS0tLVxuXG5leHBvcnQgdHlwZSBNYW5pZmVzdEluc3RhbmNlID0gTWFuaWZlc3RGbG93UmVjb3JkZXIgJiB7XG4gIGVudHJpZXMoKTogTWFuaWZlc3RFbnRyeVtdO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIG1hbmlmZXN0KCk6IE1hbmlmZXN0SW5zdGFuY2Uge1xuICBjb25zdCByZWMgPSBuZXcgTWFuaWZlc3RGbG93UmVjb3JkZXIoKSBhcyBNYW5pZmVzdEluc3RhbmNlO1xuICByZWMuZW50cmllcyA9IGZ1bmN0aW9uICh0aGlzOiBNYW5pZmVzdEZsb3dSZWNvcmRlcikge1xuICAgIHJldHVybiB0aGlzLmdldE1hbmlmZXN0KCk7XG4gIH07XG4gIHJldHVybiByZWM7XG59XG5cbi8vIC0tLS0gRmxvdyByZWNvcmRlciBzdHJhdGVnaWVzIC0tLS1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkYXB0aXZlKCkge1xuICByZXR1cm4gbmV3IEFkYXB0aXZlTmFycmF0aXZlRmxvd1JlY29yZGVyKCk7XG59XG5leHBvcnQgZnVuY3Rpb24gbWlsZXN0b25lKCkge1xuICByZXR1cm4gbmV3IE1pbGVzdG9uZU5hcnJhdGl2ZUZsb3dSZWNvcmRlcigpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHdpbmRvd2VkKG1heEVudHJpZXM/OiBudW1iZXIpIHtcbiAgcmV0dXJuIG5ldyBXaW5kb3dlZE5hcnJhdGl2ZUZsb3dSZWNvcmRlcihtYXhFbnRyaWVzKTtcbn1cblxuLy8gLS0tLSBSZS1leHBvcnRlZCB0eXBlcyAtLS0tXG5leHBvcnQgdHlwZSB7XG4gIEF0dGVtcHRSZW5kZXJDb250ZXh0LFxuICBCcmVha1JlbmRlckNvbnRleHQsXG4gIENvbWJpbmVkTmFycmF0aXZlUmVjb3JkZXJPcHRpb25zLFxuICBEZWNpc2lvblJlbmRlckNvbnRleHQsXG4gIEVtaXRFdmVudCxcbiAgRW1pdFJlY29yZGVyLFxuICBFbWl0UmVuZGVyQ29udGV4dCxcbiAgRXJyb3JSZW5kZXJDb250ZXh0LFxuICBGb3JrUmVuZGVyQ29udGV4dCxcbiAgTG9vcFJlbmRlckNvbnRleHQsXG4gIE5hcnJhdGl2ZUZvcm1hdHRlcixcbiAgT3BSZW5kZXJDb250ZXh0LFxuICBTZWxlY3RlZFJlbmRlckNvbnRleHQsXG4gIFN0YWdlUmVuZGVyQ29udGV4dCxcbiAgU3ViZmxvd1JlbmRlckNvbnRleHQsXG59O1xuZXhwb3J0IHR5cGUgeyBBZ2dyZWdhdGVkTWV0cmljcywgTWV0cmljUmVjb3JkZXJPcHRpb25zLCBTdGFnZU1ldHJpY3MgfTtcbmV4cG9ydCB0eXBlIHtcbiAgQXR0ZW1wdEFnZ3JlZ2F0ZSxcbiAgQXR0ZW1wdERlY2lzaW9uUm93LFxuICBBdHRlbXB0TWV0cmljUmVmLFxuICBBdHRlbXB0UXVlcnksXG4gIEF0dGVtcHRSZWNvcmRlck9wdGlvbnMsXG4gIEF0dGVtcHRSb3csXG4gIEF0dGVtcHRSdW5Sb3csXG4gIEF0dGVtcHRSdW5TdGF0cyxcbiAgQXR0ZW1wdFN0YXRzLFxuICBBdHRlbXB0U3RvcmFnZVN0YXRzLFxuICBBdHRlbXB0U3RvcmUsXG4gIFBoeXNpY2FsQXR0ZW1wdFJvdyxcbn0gZnJvbSAnLi9saWIvcmVjb3JkZXIvYXR0ZW1wdE1ldHJpY3NUeXBlcy5qcyc7XG5leHBvcnQgeyBtZW1vcnlTdG9yZSB9IGZyb20gJy4vbGliL3JlY29yZGVyL0F0dGVtcHRSZWNvcmRlci5qcyc7XG5leHBvcnQgdHlwZSB7IENvbXBvc2l0ZVNuYXBzaG90IH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvaW5kZXguanMnO1xuZXhwb3J0IHsgQ29tcG9zaXRlUmVjb3JkZXIgfSBmcm9tICcuL2xpYi9yZWNvcmRlci9pbmRleC5qcyc7XG5pbXBvcnQgdHlwZSB7IEF0dGVtcHRSZWNvcmRlck9wdGlvbnMgfSBmcm9tICcuL2xpYi9yZWNvcmRlci9hdHRlbXB0TWV0cmljc1R5cGVzLmpzJztcbmltcG9ydCB7IEF0dGVtcHRSZWNvcmRlciB9IGZyb20gJy4vbGliL3JlY29yZGVyL0F0dGVtcHRSZWNvcmRlci5qcyc7XG4vKiogQ29sbGVjdCBwYXlsb2FkLWZyZWUgYXR0ZW1wdHMgZHVyaW5nIHRyYXZlcnNhbDsgc3RvcmFnZSBhZGFwdGVycyBhcmUgb3B0aW9uYWwgYW5kIHByb3ZpZGVyLW5ldXRyYWwuICovXG5leHBvcnQgZnVuY3Rpb24gYXR0ZW1wdHMob3B0aW9ucz86IEF0dGVtcHRSZWNvcmRlck9wdGlvbnMpOiBBdHRlbXB0UmVjb3JkZXIge1xuICByZXR1cm4gbmV3IEF0dGVtcHRSZWNvcmRlcihvcHRpb25zKTtcbn1cbiJdfQ==
|
package/dist/sinks.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* footprintjs/sinks — where a run's crash-safe record goes on a Node host (10.1, design §3.5).
|
|
4
|
+
*
|
|
5
|
+
* NODE ONLY. This door imports `node:fs`; it is the one door that does (`test/architecture/layering.test.ts`), so
|
|
6
|
+
* every other door stays loadable in a browser. The port itself — `RecordSink`, and the reference `memorySink()` —
|
|
7
|
+
* is foottrace's (`foottrace/write`); the reader is `readStoredRecord` (`foottrace`).
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { flowChart, FlowChartExecutor } from 'footprintjs';
|
|
12
|
+
* import { fileSink, readRecordFile } from 'footprintjs/sinks';
|
|
13
|
+
* import { readStoredRecord } from 'foottrace';
|
|
14
|
+
*
|
|
15
|
+
* const executor = new FlowChartExecutor(chart, { sink: fileSink('/var/footprint/orders.jsonl') });
|
|
16
|
+
* await executor.run({ input });
|
|
17
|
+
*
|
|
18
|
+
* // After a crash — in another process:
|
|
19
|
+
* const record = readStoredRecord(readRecordFile('/var/footprint/orders.jsonl').entries);
|
|
20
|
+
* for (const log of record.logs.values()) if (!log.complete) console.log('never finished:', log.address);
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.readRecordFile = exports.fileSink = exports.DEFAULT_FILE_SINK_MAX_QUEUED_BYTES = exports.DEFAULT_FILE_SINK_MAX_ENTRY_BYTES = exports.DEFAULT_FILE_SINK_MAX_BYTES = exports.DEFAULT_FILE_SINK_FLUSH_TIMEOUT_MS = void 0;
|
|
25
|
+
var fileSink_js_1 = require("./lib/sinks/fileSink.js");
|
|
26
|
+
Object.defineProperty(exports, "DEFAULT_FILE_SINK_FLUSH_TIMEOUT_MS", { enumerable: true, get: function () { return fileSink_js_1.DEFAULT_FILE_SINK_FLUSH_TIMEOUT_MS; } });
|
|
27
|
+
Object.defineProperty(exports, "DEFAULT_FILE_SINK_MAX_BYTES", { enumerable: true, get: function () { return fileSink_js_1.DEFAULT_FILE_SINK_MAX_BYTES; } });
|
|
28
|
+
Object.defineProperty(exports, "DEFAULT_FILE_SINK_MAX_ENTRY_BYTES", { enumerable: true, get: function () { return fileSink_js_1.DEFAULT_FILE_SINK_MAX_ENTRY_BYTES; } });
|
|
29
|
+
Object.defineProperty(exports, "DEFAULT_FILE_SINK_MAX_QUEUED_BYTES", { enumerable: true, get: function () { return fileSink_js_1.DEFAULT_FILE_SINK_MAX_QUEUED_BYTES; } });
|
|
30
|
+
Object.defineProperty(exports, "fileSink", { enumerable: true, get: function () { return fileSink_js_1.fileSink; } });
|
|
31
|
+
Object.defineProperty(exports, "readRecordFile", { enumerable: true, get: function () { return fileSink_js_1.readRecordFile; } });
|
|
32
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lua3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc2lua3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CRzs7O0FBR0gsdURBT2lDO0FBTi9CLGlJQUFBLGtDQUFrQyxPQUFBO0FBQ2xDLDBIQUFBLDJCQUEyQixPQUFBO0FBQzNCLGdJQUFBLGlDQUFpQyxPQUFBO0FBQ2pDLGlJQUFBLGtDQUFrQyxPQUFBO0FBQ2xDLHVHQUFBLFFBQVEsT0FBQTtBQUNSLDZHQUFBLGNBQWMsT0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogZm9vdHByaW50anMvc2lua3Mg4oCUIHdoZXJlIGEgcnVuJ3MgY3Jhc2gtc2FmZSByZWNvcmQgZ29lcyBvbiBhIE5vZGUgaG9zdCAoMTAuMSwgZGVzaWduIMKnMy41KS5cbiAqXG4gKiBOT0RFIE9OTFkuIFRoaXMgZG9vciBpbXBvcnRzIGBub2RlOmZzYDsgaXQgaXMgdGhlIG9uZSBkb29yIHRoYXQgZG9lcyAoYHRlc3QvYXJjaGl0ZWN0dXJlL2xheWVyaW5nLnRlc3QudHNgKSwgc29cbiAqIGV2ZXJ5IG90aGVyIGRvb3Igc3RheXMgbG9hZGFibGUgaW4gYSBicm93c2VyLiBUaGUgcG9ydCBpdHNlbGYg4oCUIGBSZWNvcmRTaW5rYCwgYW5kIHRoZSByZWZlcmVuY2UgYG1lbW9yeVNpbmsoKWAg4oCUXG4gKiBpcyBmb290dHJhY2UncyAoYGZvb3R0cmFjZS93cml0ZWApOyB0aGUgcmVhZGVyIGlzIGByZWFkU3RvcmVkUmVjb3JkYCAoYGZvb3R0cmFjZWApLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQgeyBmbG93Q2hhcnQsIEZsb3dDaGFydEV4ZWN1dG9yIH0gZnJvbSAnZm9vdHByaW50anMnO1xuICogaW1wb3J0IHsgZmlsZVNpbmssIHJlYWRSZWNvcmRGaWxlIH0gZnJvbSAnZm9vdHByaW50anMvc2lua3MnO1xuICogaW1wb3J0IHsgcmVhZFN0b3JlZFJlY29yZCB9IGZyb20gJ2Zvb3R0cmFjZSc7XG4gKlxuICogY29uc3QgZXhlY3V0b3IgPSBuZXcgRmxvd0NoYXJ0RXhlY3V0b3IoY2hhcnQsIHsgc2luazogZmlsZVNpbmsoJy92YXIvZm9vdHByaW50L29yZGVycy5qc29ubCcpIH0pO1xuICogYXdhaXQgZXhlY3V0b3IucnVuKHsgaW5wdXQgfSk7XG4gKlxuICogLy8gQWZ0ZXIgYSBjcmFzaCDigJQgaW4gYW5vdGhlciBwcm9jZXNzOlxuICogY29uc3QgcmVjb3JkID0gcmVhZFN0b3JlZFJlY29yZChyZWFkUmVjb3JkRmlsZSgnL3Zhci9mb290cHJpbnQvb3JkZXJzLmpzb25sJykuZW50cmllcyk7XG4gKiBmb3IgKGNvbnN0IGxvZyBvZiByZWNvcmQubG9ncy52YWx1ZXMoKSkgaWYgKCFsb2cuY29tcGxldGUpIGNvbnNvbGUubG9nKCduZXZlciBmaW5pc2hlZDonLCBsb2cuYWRkcmVzcyk7XG4gKiBgYGBcbiAqL1xuXG5leHBvcnQgdHlwZSB7IEZpbGVTaW5rLCBGaWxlU2lua09wdGlvbnMsIFJlY29yZEZpbGUgfSBmcm9tICcuL2xpYi9zaW5rcy9maWxlU2luay5qcyc7XG5leHBvcnQge1xuICBERUZBVUxUX0ZJTEVfU0lOS19GTFVTSF9USU1FT1VUX01TLFxuICBERUZBVUxUX0ZJTEVfU0lOS19NQVhfQllURVMsXG4gIERFRkFVTFRfRklMRV9TSU5LX01BWF9FTlRSWV9CWVRFUyxcbiAgREVGQVVMVF9GSUxFX1NJTktfTUFYX1FVRVVFRF9CWVRFUyxcbiAgZmlsZVNpbmssXG4gIHJlYWRSZWNvcmRGaWxlLFxufSBmcm9tICcuL2xpYi9zaW5rcy9maWxlU2luay5qcyc7XG4iXX0=
|
package/dist/trace.js
CHANGED
|
@@ -38,4 +38,4 @@ Object.defineProperty(exports, "SequenceStore", { enumerable: true, get: functio
|
|
|
38
38
|
var TopologyRecorder_js_1 = require("./lib/recorder/TopologyRecorder.js");
|
|
39
39
|
Object.defineProperty(exports, "TopologyRecorder", { enumerable: true, get: function () { return TopologyRecorder_js_1.TopologyRecorder; } });
|
|
40
40
|
Object.defineProperty(exports, "topologyRecorder", { enumerable: true, get: function () { return TopologyRecorder_js_1.topologyRecorder; } });
|
|
41
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
41
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHJhY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7R0FNRzs7O0FBR0gsc0VBQWtFO0FBQXpELHFIQUFBLGVBQWUsT0FBQTtBQUN4QiwrREFNb0M7QUFMbEMseUhBQUEscUJBQXFCLE9BQUE7QUFDckIsc0hBQUEsa0JBQWtCLE9BQUE7QUFDbEIsMEhBQUEsc0JBQXNCLE9BQUE7QUFDdEIsbUhBQUEsZUFBZSxPQUFBO0FBQ2Ysc0hBQUEsa0JBQWtCLE9BQUE7QUFFcEIsOEVBQTBFO0FBQWpFLDJIQUFBLGtCQUFrQixPQUFBO0FBRTNCLDhFQUE4RjtBQUFyRiwySEFBQSxrQkFBa0IsT0FBQTtBQUFFLDJIQUFBLGtCQUFrQixPQUFBO0FBRS9DLG9FQUF1SDtBQUE5RyxpSEFBQSxhQUFhLE9BQUE7QUFBRSxpSEFBQSxhQUFhLE9BQUE7QUFBRSx5SEFBQSxxQkFBcUIsT0FBQTtBQUFFLG1IQUFBLGVBQWUsT0FBQTtBQUM3RSw4REFBMEQ7QUFBakQsMkdBQUEsVUFBVSxPQUFBO0FBRW5CLHdFQUFvRTtBQUEzRCxxSEFBQSxlQUFlLE9BQUE7QUFFeEIsa0VBQWtGO0FBQXpFLHFIQUFBLGtCQUFrQixPQUFBO0FBQUUsK0dBQUEsWUFBWSxPQUFBO0FBQ3pDLG9FQUFnRTtBQUF2RCxpSEFBQSxhQUFhLE9BQUE7QUFTdEIsMEVBQXdGO0FBQS9FLHVIQUFBLGdCQUFnQixPQUFBO0FBQUUsdUhBQUEsZ0JBQWdCLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGZvb3RwcmludGpzL3RyYWNlIOKAlCByZWNvcmRlciBzdG9yZXMsIHRvcG9sb2d5LCBjaGFydCBib3VuZGFyaWVzIGFuZCBjb250cm9sIGRlcGVuZGVuY2llcy5cbiAqXG4gKiBSZWNvcmQgcmVhZGVycywgdHlwZXMgYW5kIHJ1bnRpbWUtSUQgZ3JhbW1hciBiZWxvbmcgdG8gYGZvb3R0cmFjZWA7IHJlY29yZCBwYXRoIGhlbHBlcnMgYmVsb25nXG4gKiB0byBgZm9vdHRyYWNlL3BhdGhzYCwgYW5kIHJlY29yZCB3cml0ZXJzIHRvIGBmb290dHJhY2Uvd3JpdGVgLiBUaGlzIGRvb3IgZXhwb3J0cyBvbmx5IGVuZ2luZS1vd25lZFxuICogb2JzZXJ2ZXIgdG9vbHMuIFJlY29yZCBzeW1ib2xzIGFyZSBuZXZlciByZS1leHBvcnRlZCBhY3Jvc3MgdGhlIHBhY2thZ2UgYm91bmRhcnkuXG4gKi9cblxuZXhwb3J0IHR5cGUgeyBXYWxrZXJJdGVtLCBXYWxrZXJPcHRpb25zIH0gZnJvbSAnLi9saWIvZW5naW5lL3dhbGtTdWJmbG93U3BlYy5qcyc7XG5leHBvcnQgeyB3YWxrU3ViZmxvd1NwZWMgfSBmcm9tICcuL2xpYi9lbmdpbmUvd2Fsa1N1YmZsb3dTcGVjLmpzJztcbmV4cG9ydCB7XG4gIEJSQU5DSF9TRUdNRU5UX01BUktFUixcbiAgYnVpbGRCcmFuY2hTZWdtZW50LFxuICBoYXNCcmFuY2hTZWdtZW50TWFya2VyLFxuICBpc0JyYW5jaFNlZ21lbnQsXG4gIHBhcnNlQnJhbmNoU2VnbWVudCxcbn0gZnJvbSAnLi9saWIvaWRzL2JyYW5jaFNlZ21lbnQuanMnO1xuZXhwb3J0IHsgQm91bmRhcnlTdGF0ZVN0b3JlIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvQm91bmRhcnlTdGF0ZVN0b3JlLmpzJztcbmV4cG9ydCB0eXBlIHsgQ29udHJvbERlY2lzaW9uUmVjb3JkLCBDb250cm9sRGVwUmVjb3JkZXJPcHRpb25zIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvQ29udHJvbERlcFJlY29yZGVyLmpzJztcbmV4cG9ydCB7IENvbnRyb2xEZXBSZWNvcmRlciwgY29udHJvbERlcFJlY29yZGVyIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvQ29udHJvbERlcFJlY29yZGVyLmpzJztcbmV4cG9ydCB0eXBlIHsgSW5PdXRBdHRlbXB0cywgSW5PdXRFbnRyeSwgSW5PdXRQaGFzZSwgSW5PdXRSZWNvcmRlck9wdGlvbnMgfSBmcm9tICcuL2xpYi9yZWNvcmRlci9Jbk91dFJlY29yZGVyLmpzJztcbmV4cG9ydCB7IEluT3V0UmVjb3JkZXIsIGluT3V0UmVjb3JkZXIsIFJPT1RfUlVOVElNRV9TVEFHRV9JRCwgUk9PVF9TVUJGTE9XX0lEIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvSW5PdXRSZWNvcmRlci5qcyc7XG5leHBvcnQgeyBLZXllZFN0b3JlIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvS2V5ZWRTdG9yZS5qcyc7XG5leHBvcnQgdHlwZSB7IFF1YWxpdHlFbnRyeSwgUXVhbGl0eVJlY29yZGVyT3B0aW9ucywgUXVhbGl0eVNjb3JpbmdGbiB9IGZyb20gJy4vbGliL3JlY29yZGVyL1F1YWxpdHlSZWNvcmRlci5qcyc7XG5leHBvcnQgeyBRdWFsaXR5UmVjb3JkZXIgfSBmcm9tICcuL2xpYi9yZWNvcmRlci9RdWFsaXR5UmVjb3JkZXIuanMnO1xuZXhwb3J0IHR5cGUgeyBRdWFsaXR5RnJhbWUsIFF1YWxpdHlTdGFja1RyYWNlIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvcXVhbGl0eVRyYWNlLmpzJztcbmV4cG9ydCB7IGZvcm1hdFF1YWxpdHlUcmFjZSwgcXVhbGl0eVRyYWNlIH0gZnJvbSAnLi9saWIvcmVjb3JkZXIvcXVhbGl0eVRyYWNlLmpzJztcbmV4cG9ydCB7IFNlcXVlbmNlU3RvcmUgfSBmcm9tICcuL2xpYi9yZWNvcmRlci9TZXF1ZW5jZVN0b3JlLmpzJztcbmV4cG9ydCB0eXBlIHtcbiAgVG9wb2xvZ3ksXG4gIFRvcG9sb2d5RWRnZSxcbiAgVG9wb2xvZ3lJbmNvbWluZ0tpbmQsXG4gIFRvcG9sb2d5Tm9kZSxcbiAgVG9wb2xvZ3lOb2RlS2luZCxcbiAgVG9wb2xvZ3lSZWNvcmRlck9wdGlvbnMsXG59IGZyb20gJy4vbGliL3JlY29yZGVyL1RvcG9sb2d5UmVjb3JkZXIuanMnO1xuZXhwb3J0IHsgVG9wb2xvZ3lSZWNvcmRlciwgdG9wb2xvZ3lSZWNvcmRlciB9IGZyb20gJy4vbGliL3JlY29yZGVyL1RvcG9sb2d5UmVjb3JkZXIuanMnO1xuIl19
|