footprintjs 4.7.0 → 4.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/CLAUDE.md +38 -14
  2. package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.js +97 -90
  3. package/dist/esm/lib/engine/narrative/narrativeTypes.js +1 -1
  4. package/dist/esm/lib/engine/traversal/FlowchartTraverser.js +8 -6
  5. package/dist/esm/lib/memory/StageContext.js +2 -1
  6. package/dist/esm/lib/memory/types.js +1 -1
  7. package/dist/esm/lib/recorder/KeyedRecorder.js +56 -7
  8. package/dist/esm/lib/recorder/SequenceRecorder.js +194 -0
  9. package/dist/esm/lib/recorder/index.js +2 -1
  10. package/dist/esm/lib/scope/recorders/MetricRecorder.js +85 -82
  11. package/dist/esm/lib/scope/recorders/index.js +1 -1
  12. package/dist/esm/trace.js +10 -5
  13. package/dist/lib/engine/narrative/CombinedNarrativeRecorder.js +97 -90
  14. package/dist/lib/engine/narrative/narrativeTypes.js +1 -1
  15. package/dist/lib/engine/traversal/FlowchartTraverser.js +8 -6
  16. package/dist/lib/memory/StageContext.js +2 -1
  17. package/dist/lib/memory/types.js +1 -1
  18. package/dist/lib/recorder/KeyedRecorder.js +56 -7
  19. package/dist/lib/recorder/SequenceRecorder.js +198 -0
  20. package/dist/lib/recorder/index.js +4 -2
  21. package/dist/lib/scope/recorders/MetricRecorder.js +85 -82
  22. package/dist/lib/scope/recorders/index.js +1 -1
  23. package/dist/trace.js +12 -6
  24. package/dist/types/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +8 -18
  25. package/dist/types/lib/engine/narrative/narrativeTypes.d.ts +7 -0
  26. package/dist/types/lib/memory/types.d.ts +2 -0
  27. package/dist/types/lib/recorder/KeyedRecorder.d.ts +29 -6
  28. package/dist/types/lib/recorder/SequenceRecorder.d.ts +112 -0
  29. package/dist/types/lib/recorder/index.d.ts +1 -0
  30. package/dist/types/lib/scope/recorders/MetricRecorder.d.ts +47 -40
  31. package/dist/types/lib/scope/recorders/index.d.ts +1 -1
  32. package/dist/types/trace.d.ts +7 -3
  33. package/package.json +1 -1
@@ -1,39 +1,32 @@
1
1
  /**
2
- * MetricRecorder — Production-focused recorder for timing and execution counts.
2
+ * MetricRecorder — per-step timing and execution counts, keyed by runtimeStageId.
3
3
  *
4
- * Tracks read/write/commit counts per stage and measures stage execution duration.
5
- *
6
- * Each instance gets a unique auto-increment ID (`metrics-1`, `metrics-2`, ...),
7
- * so multiple recorders with different configs coexist. Pass an explicit ID to
8
- * override a specific instance (e.g., a framework-attached recorder).
4
+ * Stores per-invocation data during traversal. Aggregated views computed on read.
5
+ * Extends KeyedRecorder<StepMetrics> for O(1) lookup and standard operations.
9
6
  *
10
7
  * @example
11
8
  * ```typescript
12
- * // Track all stages (default)
13
- * executor.attachRecorder(new MetricRecorder());
9
+ * const metric = new MetricRecorder();
10
+ * executor.attachRecorder(metric);
11
+ * await executor.run();
14
12
  *
15
- * // Track only LLM-related stages
16
- * executor.attachRecorder(new MetricRecorder({
17
- * stageFilter: (name) => ['CallLLM', 'ParseResponse'].includes(name),
18
- * }));
13
+ * // Per-step (time-travel):
14
+ * metric.getByKey('call-llm#5'); // { stageName, readCount, writeCount, duration }
19
15
  *
20
- * // Two recorders: one for LLM timing, one for everything else
21
- * executor.attachRecorder(new MetricRecorder({
22
- * stageFilter: (name) => name === 'CallLLM',
23
- * }));
24
- * executor.attachRecorder(new MetricRecorder({
25
- * stageFilter: (name) => name !== 'CallLLM',
26
- * }));
16
+ * // Aggregated (backward compat):
17
+ * metric.getMetrics(); // { totalDuration, totalReads, stageMetrics: Map<stageName, aggregated> }
27
18
  *
28
- * // Override a framework-attached recorder by passing its well-known ID
29
- * executor.attachRecorder(new MetricRecorder({ id: 'metrics' }));
19
+ * // Progressive (slider):
20
+ * metric.accumulate((sum, m) => sum + m.duration, 0, visibleKeys);
30
21
  * ```
31
22
  */
32
- export class MetricRecorder {
23
+ import { KeyedRecorder } from '../../recorder/KeyedRecorder.js';
24
+ export class MetricRecorder extends KeyedRecorder {
33
25
  constructor(idOrOptions) {
34
26
  var _a;
35
- this.metrics = new Map();
27
+ super();
36
28
  this.stageStartTimes = new Map();
29
+ this.currentRuntimeStageId = '';
37
30
  if (typeof idOrOptions === 'string') {
38
31
  this.id = idOrOptions;
39
32
  }
@@ -45,73 +38,96 @@ export class MetricRecorder {
45
38
  shouldRecord(stageName) {
46
39
  return !this.stageFilter || this.stageFilter(stageName);
47
40
  }
41
+ /** Get or create the StepMetrics for the current stage. */
42
+ current() {
43
+ const key = this.currentRuntimeStageId;
44
+ let m = this.getByKey(key);
45
+ if (!m) {
46
+ m = { stageName: '', readCount: 0, writeCount: 0, commitCount: 0, pauseCount: 0, duration: 0 };
47
+ this.store(key, m);
48
+ }
49
+ return m;
50
+ }
51
+ onStageStart(event) {
52
+ if (!this.shouldRecord(event.stageName))
53
+ return;
54
+ this.currentRuntimeStageId = event.runtimeStageId;
55
+ this.stageStartTimes.set(event.runtimeStageId, event.timestamp);
56
+ const m = this.current();
57
+ m.stageName = event.stageName;
58
+ }
48
59
  onRead(event) {
49
60
  if (!this.shouldRecord(event.stageName))
50
61
  return;
51
- this.getOrCreateStageMetrics(event.stageName).readCount++;
62
+ this.current().readCount++;
52
63
  }
53
64
  onWrite(event) {
54
65
  if (!this.shouldRecord(event.stageName))
55
66
  return;
56
- this.getOrCreateStageMetrics(event.stageName).writeCount++;
67
+ this.current().writeCount++;
57
68
  }
58
69
  onCommit(event) {
59
70
  if (!this.shouldRecord(event.stageName))
60
71
  return;
61
- this.getOrCreateStageMetrics(event.stageName).commitCount++;
72
+ this.current().commitCount++;
62
73
  }
63
74
  onPause(event) {
64
75
  if (!this.shouldRecord(event.stageName))
65
76
  return;
66
- this.getOrCreateStageMetrics(event.stageName).pauseCount++;
67
- }
68
- onStageStart(event) {
69
- if (!this.shouldRecord(event.stageName))
70
- return;
71
- this.stageStartTimes.set(event.stageName, event.timestamp);
72
- this.getOrCreateStageMetrics(event.stageName).invocationCount++;
77
+ this.current().pauseCount++;
73
78
  }
74
79
  onStageEnd(event) {
75
80
  if (!this.shouldRecord(event.stageName))
76
81
  return;
77
- const stageMetrics = this.getOrCreateStageMetrics(event.stageName);
78
- let duration;
82
+ const m = this.current();
79
83
  if (event.duration !== undefined) {
80
- duration = event.duration;
84
+ m.duration = event.duration;
81
85
  }
82
86
  else {
83
- const startTime = this.stageStartTimes.get(event.stageName);
84
- duration = startTime !== undefined ? event.timestamp - startTime : 0;
87
+ const startTime = this.stageStartTimes.get(event.runtimeStageId);
88
+ m.duration = startTime !== undefined ? event.timestamp - startTime : 0;
85
89
  }
86
- stageMetrics.totalDuration += duration;
87
- this.stageStartTimes.delete(event.stageName);
90
+ this.stageStartTimes.delete(event.runtimeStageId);
88
91
  }
92
+ /** Aggregated metrics — computes totals on the fly from per-step data (backward compatible). */
89
93
  getMetrics() {
90
- let totalDuration = 0;
91
- let totalReads = 0;
92
- let totalWrites = 0;
93
- let totalCommits = 0;
94
- let totalPauses = 0;
95
- for (const stageMetrics of this.metrics.values()) {
96
- totalDuration += stageMetrics.totalDuration;
97
- totalReads += stageMetrics.readCount;
98
- totalWrites += stageMetrics.writeCount;
99
- totalCommits += stageMetrics.commitCount;
100
- totalPauses += stageMetrics.pauseCount;
94
+ const byName = new Map();
95
+ const totalDuration = this.aggregate((sum, m) => sum + m.duration, 0);
96
+ const totalReads = this.aggregate((sum, m) => sum + m.readCount, 0);
97
+ const totalWrites = this.aggregate((sum, m) => sum + m.writeCount, 0);
98
+ const totalCommits = this.aggregate((sum, m) => sum + m.commitCount, 0);
99
+ const totalPauses = this.aggregate((sum, m) => sum + m.pauseCount, 0);
100
+ // Group by stageName for backward compat
101
+ for (const m of this.values()) {
102
+ const existing = byName.get(m.stageName);
103
+ if (existing) {
104
+ existing.readCount += m.readCount;
105
+ existing.writeCount += m.writeCount;
106
+ existing.commitCount += m.commitCount;
107
+ existing.pauseCount += m.pauseCount;
108
+ existing.totalDuration += m.duration;
109
+ existing.invocationCount++;
110
+ }
111
+ else {
112
+ byName.set(m.stageName, {
113
+ stageName: m.stageName,
114
+ readCount: m.readCount,
115
+ writeCount: m.writeCount,
116
+ commitCount: m.commitCount,
117
+ pauseCount: m.pauseCount,
118
+ totalDuration: m.duration,
119
+ invocationCount: 1,
120
+ });
121
+ }
101
122
  }
102
- return {
103
- totalDuration,
104
- totalReads,
105
- totalWrites,
106
- totalCommits,
107
- totalPauses,
108
- stageMetrics: new Map(this.metrics),
109
- };
123
+ return { totalDuration, totalReads, totalWrites, totalCommits, totalPauses, stageMetrics: byName };
110
124
  }
125
+ /** Get aggregated metrics for a specific stage name (backward compatible). */
111
126
  getStageMetrics(stageName) {
112
- const metrics = this.metrics.get(stageName);
113
- return metrics ? { ...metrics } : undefined;
127
+ const metrics = this.getMetrics();
128
+ return metrics.stageMetrics.get(stageName);
114
129
  }
130
+ /** Snapshot for serialization (backward compatible format). */
115
131
  toSnapshot() {
116
132
  const metrics = this.getMetrics();
117
133
  return {
@@ -125,29 +141,16 @@ export class MetricRecorder {
125
141
  },
126
142
  };
127
143
  }
128
- reset() {
129
- this.metrics.clear();
130
- this.stageStartTimes.clear();
131
- }
144
+ /** Clear all state — called by executor before each run(). */
132
145
  clear() {
133
- this.reset();
146
+ super.clear();
147
+ this.stageStartTimes.clear();
148
+ this.currentRuntimeStageId = '';
134
149
  }
135
- getOrCreateStageMetrics(stageName) {
136
- let stageMetrics = this.metrics.get(stageName);
137
- if (!stageMetrics) {
138
- stageMetrics = {
139
- stageName,
140
- readCount: 0,
141
- writeCount: 0,
142
- commitCount: 0,
143
- pauseCount: 0,
144
- totalDuration: 0,
145
- invocationCount: 0,
146
- };
147
- this.metrics.set(stageName, stageMetrics);
148
- }
149
- return stageMetrics;
150
+ /** Alias for clear() (backward compat). */
151
+ reset() {
152
+ this.clear();
150
153
  }
151
154
  }
152
155
  MetricRecorder._counter = 0;
153
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWV0cmljUmVjb3JkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3Njb3BlL3JlY29yZGVycy9NZXRyaWNSZWNvcmRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBOEJHO0FBd0NILE1BQU0sT0FBTyxjQUFjO0lBUXpCLFlBQVksV0FBNEM7O1FBSmhELFlBQU8sR0FBOEIsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUMvQyxvQkFBZSxHQUF3QixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBSXZELElBQUksT0FBTyxXQUFXLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDcEMsSUFBSSxDQUFDLEVBQUUsR0FBRyxXQUFXLENBQUM7UUFDeEIsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUMsRUFBRSxHQUFHLE1BQUEsV0FBVyxhQUFYLFdBQVcsdUJBQVgsV0FBVyxDQUFFLEVBQUUsbUNBQUksV0FBVyxFQUFFLGNBQWMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNwRSxJQUFJLENBQUMsV0FBVyxHQUFHLFdBQVcsYUFBWCxXQUFXLHVCQUFYLFdBQVcsQ0FBRSxXQUFXLENBQUM7UUFDOUMsQ0FBQztJQUNILENBQUM7SUFFTyxZQUFZLENBQUMsU0FBaUI7UUFDcEMsT0FBTyxDQUFDLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBRUQsTUFBTSxDQUFDLEtBQWdCO1FBQ3JCLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUM7WUFBRSxPQUFPO1FBQ2hELElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDNUQsQ0FBQztJQUVELE9BQU8sQ0FBQyxLQUFpQjtRQUN2QixJQUFJLENB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Z0JBQ2IsYUFBYSxFQUFFLENBQUM7Z0JBQ2hCLGVBQWUsRUFBRSxDQUFDO2FBQ25CLENBQUM7WUFDRixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDNUMsQ0FBQztRQUNELE9BQU8sWUFBWSxDQUFDO0lBQ3RCLENBQUM7O0FBaEljLHVCQUFRLEdBQUcsQ0FBQyxBQUFKLENBQUsiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE1ldHJpY1JlY29yZGVyIOKAlCBQcm9kdWN0aW9uLWZvY3VzZWQgcmVjb3JkZXIgZm9yIHRpbWluZyBhbmQgZXhlY3V0aW9uIGNvdW50cy5cbiAqXG4gKiBUcmFja3MgcmVhZC93cml0ZS9jb21taXQgY291bnRzIHBlciBzdGFnZSBhbmQgbWVhc3VyZXMgc3RhZ2UgZXhlY3V0aW9uIGR1cmF0aW9uLlxuICpcbiAqIEVhY2ggaW5zdGFuY2UgZ2V0cyBhIHVuaXF1ZSBhdXRvLWluY3JlbWVudCBJRCAoYG1ldHJpY3MtMWAsIGBtZXRyaWNzLTJgLCAuLi4pLFxuICogc28gbXVsdGlwbGUgcmVjb3JkZXJzIHdpdGggZGlmZmVyZW50IGNvbmZpZ3MgY29leGlzdC4gUGFzcyBhbiBleHBsaWNpdCBJRCB0b1xuICogb3ZlcnJpZGUgYSBzcGVjaWZpYyBpbnN0YW5jZSAoZS5nLiwgYSBmcmFtZXdvcmstYXR0YWNoZWQgcmVjb3JkZXIpLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBUcmFjayBhbGwgc3RhZ2VzIChkZWZhdWx0KVxuICogZXhlY3V0b3IuYXR0YWNoUmVjb3JkZXIobmV3IE1ldHJpY1JlY29yZGVyKCkpO1xuICpcbiAqIC8vIFRyYWNrIG9ubHkgTExNLXJlbGF0ZWQgc3RhZ2VzXG4gKiBleGVjdXRvci5hdHRhY2hSZWNvcmRlcihuZXcgTWV0cmljUmVjb3JkZXIoe1xuICogICBzdGFnZUZpbHRlcjogKG5hbWUpID0+IFsnQ2FsbExMTScsICdQYXJzZVJlc3BvbnNlJ10uaW5jbHVkZXMobmFtZSksXG4gKiB9KSk7XG4gKlxuICogLy8gVHdvIHJlY29yZGVyczogb25lIGZvciBMTE0gdGltaW5nLCBvbmUgZm9yIGV2ZXJ5dGhpbmcgZWxzZVxuICogZXhlY3V0b3IuYXR0YWNoUmVjb3JkZXIobmV3IE1ldHJpY1JlY29yZGVyKHtcbiAqICAgc3RhZ2VGaWx0ZXI6IChuYW1lKSA9PiBuYW1lID09PSAnQ2FsbExMTScsXG4gKiB9KSk7XG4gKiBleGVjdXRvci5hdHRhY2hSZWNvcmRlcihuZXcgTWV0cmljUmVjb3JkZXIoe1xuICogICBzdGFnZUZpbHRlcjogKG5hbWUpID0+IG5hbWUgIT09ICdDYWxsTExNJyxcbiAqIH0pKTtcbiAqXG4gKiAvLyBPdmVycmlkZSBhIGZyYW1ld29yay1hdHRhY2hlZCByZWNvcmRlciBieSBwYXNzaW5nIGl0cyB3ZWxsLWtub3duIElEXG4gKiBleGVjdXRvci5hdHRhY2hSZWNvcmRlcihuZXcgTWV0cmljUmVjb3JkZXIoeyBpZDogJ21ldHJpY3MnIH0pKTtcbiAqIGBgYFxuICovXG5cbmltcG9ydCB0eXBlIHsgQ29tbWl0RXZlbnQsIFBhdXNlRXZlbnQsIFJlYWRFdmVudCwgUmVjb3JkZXIsIFN0YWdlRXZlbnQsIFdyaXRlRXZlbnQgfSBmcm9tICcuLi90eXBlcy5qcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RhZ2VNZXRyaWNzIHtcbiAgc3RhZ2VOYW1lOiBzdHJpbmc7XG4gIHJlYWRDb3VudDogbnVtYmVyO1xuICB3cml0ZUNvdW50OiBudW1iZXI7XG4gIGNvbW1pdENvdW50OiBudW1iZXI7XG4gIHBhdXNlQ291bnQ6IG51bWJlcjtcbiAgdG90YWxEdXJhdGlvbjogbnVtYmVyO1xuICBpbnZvY2F0aW9uQ291bnQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBZ2dyZWdhdGVkTWV0cmljcyB7XG4gIHRvdGFsRHVyYXRpb246IG51bWJlcjtcbiAgdG90YWxSZWFkczogbnVtYmVyO1xuICB0b3RhbFdyaXRlczogbnVtYmVyO1xuICB0b3RhbENvbW1pdHM6IG51bWJlcjtcbiAgdG90YWxQYXVzZXM6IG51bWJlcjtcbiAgc3RhZ2VNZXRyaWNzOiBNYXA8c3RyaW5nLCBTdGFnZU1ldHJpY3M+O1xufVxuXG4vKiogT3B0aW9ucyBmb3IgTWV0cmljUmVjb3JkZXIuIEFsbCBmaWVsZHMgYXJlIG9wdGlvbmFsLiAqL1xuZXhwb3J0IGludGVyZmFjZSBNZXRyaWNSZWNvcmRlck9wdGlvbnMge1xuICAvKiogUmVjb3JkZXIgSUQuIERlZmF1bHRzIHRvIGF1dG8taW5jcmVtZW50IChgbWV0cmljcy0xYCwgYG1ldHJpY3MtMmAsIC4uLikuICovXG4gIGlkPzogc3RyaW5nO1xuICAvKipcbiAgICogRmlsdGVyIHdoaWNoIHN0YWdlcyBhcmUgcmVjb3JkZWQuIFJldHVybiBgdHJ1ZWAgdG8gcmVjb3JkLCBgZmFsc2VgIHRvIHNraXAuXG4gICAqIFdoZW4gb21pdHRlZCwgYWxsIHN0YWdlcyBhcmUgcmVjb3JkZWQuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogLy8gT25seSB0cmFjayBzdGFnZXMgdGhhdCBzdGFydCB3aXRoIFwiQ2FsbFwiXG4gICAqIHN0YWdlRmlsdGVyOiAobmFtZSkgPT4gbmFtZS5zdGFydHNXaXRoKCdDYWxsJylcbiAgICogYGBgXG4gICAqL1xuICBzdGFnZUZpbHRlcj86IChzdGFnZU5hbWU6IHN0cmluZykgPT4gYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNsYXNzIE1ldHJpY1JlY29yZGVyIGltcGxlbWVudHMgUmVjb3JkZXIge1xuICBwcml2YXRlIHN0YXRpYyBfY291bnRlciA9IDA7XG5cbiAgcmVhZG9ubHkgaWQ6IHN0cmluZztcbiAgcHJpdmF0ZSBtZXRyaWNzOiBNYXA8c3RyaW5nLCBTdGFnZU1ldHJpY3M+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIHN0YWdlU3RhcnRUaW1lczogTWFwPHN0cmluZywgbnVtYmVyPiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBzdGFnZUZpbHRlcj86IChzdGFnZU5hbWU6IHN0cmluZykgPT4gYm9vbGVhbjtcblxuICBjb25zdHJ1Y3RvcihpZE9yT3B0aW9ucz86IHN0cmluZyB8IE1ldHJpY1JlY29yZGVyT3B0aW9ucykge1xuICAgIGlmICh0eXBlb2YgaWRPck9wdGlvbnMgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0aGlzLmlkID0gaWRPck9wdGlvbnM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaWQgPSBpZE9yT3B0aW9ucz8uaWQgPz8gYG1ldHJpY3MtJHsrK01ldHJpY1JlY29yZGVyLl9jb3VudGVyfWA7XG4gICAgICB0aGlzLnN0YWdlRmlsdGVyID0gaWRPck9wdGlvbnM/LnN0YWdlRmlsdGVyO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2hvdWxkUmVjb3JkKHN0YWdlTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICF0aGlzLnN0YWdlRmlsdGVyIHx8IHRoaXMuc3RhZ2VGaWx0ZXIoc3RhZ2VOYW1lKTtcbiAgfVxuXG4gIG9uUmVhZChldmVudDogUmVhZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnNob3VsZFJlY29yZChldmVudC5zdGFnZU5hbWUpKSByZXR1cm47XG4gICAgdGhpcy5nZXRPckNyZWF0ZVN0YWdlTWV0cmljcyhldmVudC5zdGFnZU5hbWUpLnJlYWRDb3VudCsrO1xuICB9XG5cbiAgb25Xcml0ZShldmVudDogV3JpdGVFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5zaG91bGRSZWNvcmQoZXZlbnQuc3RhZ2VOYW1lKSkgcmV0dXJuO1xuICAgIHRoaXMuZ2V0T3JDcmVhdGVTdGFnZU1ldHJpY3MoZXZlbnQuc3RhZ2VOYW1lKS53cml0ZUNvdW50Kys7XG4gIH1cblxuICBvbkNvbW1pdChldmVudDogQ29tbWl0RXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuc2hvdWxkUmVjb3JkKGV2ZW50LnN0YWdlTmFtZSkpIHJldHVybjtcbiAgICB0aGlzLmdldE9yQ3JlYXRlU3RhZ2VNZXRyaWNzKGV2ZW50LnN0YWdlTmFtZSkuY29tbWl0Q291bnQrKztcbiAgfVxuXG4gIG9uUGF1c2UoZXZlbnQ6IFBhdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuc2hvdWxkUmVjb3JkKGV2ZW50LnN0YWdlTmFtZSkpIHJldHVybjtcbiAgICB0aGlzLmdldE9yQ3JlYXRlU3RhZ2VNZXRyaWNzKGV2ZW50LnN0YWdlTmFtZSkucGF1c2VDb3VudCsrO1xuICB9XG5cbiAgb25TdGFnZVN0YXJ0KGV2ZW50OiBTdGFnZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnNob3VsZFJlY29yZChldmVudC5zdGFnZU5hbWUpKSByZXR1cm47XG4gICAgdGhpcy5zdGFnZVN0YXJ0VGltZXMuc2V0KGV2ZW50LnN0YWdlTmFtZSwgZXZlbnQudGltZXN0YW1wKTtcbiAgICB0aGlzLmdldE9yQ3JlYXRlU3RhZ2VNZXRyaWNzKGV2ZW50LnN0YWdlTmFtZSkuaW52b2NhdGlvbkNvdW50Kys7XG4gIH1cblxuICBvblN0YWdlRW5kKGV2ZW50OiBTdGFnZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnNob3VsZFJlY29yZChldmVudC5zdGFnZU5hbWUpKSByZXR1cm47XG4gICAgY29uc3Qgc3RhZ2VNZXRyaWNzID0gdGhpcy5nZXRPckNyZWF0ZVN0YWdlTWV0cmljcyhldmVudC5zdGFnZU5hbWUpO1xuICAgIGxldCBkdXJhdGlvbjogbnVtYmVyO1xuICAgIGlmIChldmVudC5kdXJhdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBkdXJhdGlvbiA9IGV2ZW50LmR1cmF0aW9uO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBzdGFydFRpbWUgPSB0aGlzLnN0YWdlU3RhcnRUaW1lcy5nZXQoZXZlbnQuc3RhZ2VOYW1lKTtcbiAgICAgIGR1cmF0aW9uID0gc3RhcnRUaW1lICE9PSB1bmRlZmluZWQgPyBldmVudC50aW1lc3RhbXAgLSBzdGFydFRpbWUgOiAwO1xuICAgIH1cbiAgICBzdGFnZU1ldHJpY3MudG90YWxEdXJhdGlvbiArPSBkdXJhdGlvbjtcbiAgICB0aGlzLnN0YWdlU3RhcnRUaW1lcy5kZWxldGUoZXZlbnQuc3RhZ2VOYW1lKTtcbiAgfVxuXG4gIGdldE1ldHJpY3MoKTogQWdncmVnYXRlZE1ldHJpY3Mge1xuICAgIGxldCB0b3RhbER1cmF0aW9uID0gMDtcbiAgICBsZXQgdG90YWxSZWFkcyA9IDA7XG4gICAgbGV0IHRvdGFsV3JpdGVzID0gMDtcbiAgICBsZXQgdG90YWxDb21taXRzID0gMDtcbiAgICBsZXQgdG90YWxQYXVzZXMgPSAwO1xuXG4gICAgZm9yIChjb25zdCBzdGFnZU1ldHJpY3Mgb2YgdGhpcy5tZXRyaWNzLnZhbHVlcygpKSB7XG4gICAgICB0b3RhbER1cmF0aW9uICs9IHN0YWdlTWV0cmljcy50b3RhbER1cmF0aW9uO1xuICAgICAgdG90YWxSZWFkcyArPSBzdGFnZU1ldHJpY3MucmVhZENvdW50O1xuICAgICAgdG90YWxXcml0ZXMgKz0gc3RhZ2VNZXRyaWNzLndyaXRlQ291bnQ7XG4gICAgICB0b3RhbENvbW1pdHMgKz0gc3RhZ2VNZXRyaWNzLmNvbW1pdENvdW50O1xuICAgICAgdG90YWxQYXVzZXMgKz0gc3RhZ2VNZXRyaWNzLnBhdXNlQ291bnQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRvdGFsRHVyYXRpb24sXG4gICAgICB0b3RhbFJlYWRzLFxuICAgICAgdG90YWxXcml0ZXMsXG4gICAgICB0b3RhbENvbW1pdHMsXG4gICAgICB0b3RhbFBhdXNlcyxcbiAgICAgIHN0YWdlTWV0cmljczogbmV3IE1hcCh0aGlzLm1ldHJpY3MpLFxuICAgIH07XG4gIH1cblxuICBnZXRTdGFnZU1ldHJpY3Moc3RhZ2VOYW1lOiBzdHJpbmcpOiBTdGFnZU1ldHJpY3MgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IG1ldHJpY3MgPSB0aGlzLm1ldHJpY3MuZ2V0KHN0YWdlTmFtZSk7XG4gICAgcmV0dXJuIG1ldHJpY3MgPyB7IC4uLm1ldHJpY3MgfSA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHRvU25hcHNob3QoKTogeyBuYW1lOiBzdHJpbmc7IGRhdGE6IHVua25vd24gfSB7XG4gICAgY29uc3QgbWV0cmljcyA9IHRoaXMuZ2V0TWV0cmljcygpO1xuICAgIHJldHVybiB7XG4gICAgICBuYW1lOiAnTWV0cmljcycsXG4gICAgICBkYXRhOiB7XG4gICAgICAgIHRvdGFsRHVyYXRpb246IG1ldHJpY3MudG90YWxEdXJhdGlvbixcbiAgICAgICAgdG90YWxSZWFkczogbWV0cmljcy50b3RhbFJlYWRzLFxuICAgICAgICB0b3RhbFdyaXRlczogbWV0cmljcy50b3RhbFdyaXRlcyxcbiAgICAgICAgdG90YWxDb21taXRzOiBtZXRyaWNzLnRvdGFsQ29tbWl0cyxcbiAgICAgICAgc3RhZ2VzOiBPYmplY3QuZnJvbUVudHJpZXMobWV0cmljcy5zdGFnZU1ldHJpY3MpLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy5tZXRyaWNzLmNsZWFyKCk7XG4gICAgdGhpcy5zdGFnZVN0YXJ0VGltZXMuY2xlYXIoKTtcbiAgfVxuXG4gIGNsZWFyKCk6IHZvaWQge1xuICAgIHRoaXMucmVzZXQoKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0T3JDcmVhdGVTdGFnZU1ldHJpY3Moc3RhZ2VOYW1lOiBzdHJpbmcpOiBTdGFnZU1ldHJpY3Mge1xuICAgIGxldCBzdGFnZU1ldHJpY3MgPSB0aGlzLm1ldHJpY3MuZ2V0KHN0YWdlTmFtZSk7XG4gICAgaWYgKCFzdGFnZU1ldHJpY3MpIHtcbiAgICAgIHN0YWdlTWV0cmljcyA9IHtcbiAgICAgICAgc3RhZ2VOYW1lLFxuICAgICAgICByZWFkQ291bnQ6IDAsXG4gICAgICAgIHdyaXRlQ291bnQ6IDAsXG4gICAgICAgIGNvbW1pdENvdW50OiAwLFxuICAgICAgICBwYXVzZUNvdW50OiAwLFxuICAgICAgICB0b3RhbER1cmF0aW9uOiAwLFxuICAgICAgICBpbnZvY2F0aW9uQ291bnQ6IDAsXG4gICAgICB9O1xuICAgICAgdGhpcy5tZXRyaWNzLnNldChzdGFnZU5hbWUsIHN0YWdlTWV0cmljcyk7XG4gICAgfVxuICAgIHJldHVybiBzdGFnZU1ldHJpY3M7XG4gIH1cbn1cbiJdfQ==
156
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWV0cmljUmVjb3JkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3Njb3BlL3JlY29yZGVycy9NZXRyaWNSZWNvcmRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcUJHO0FBRUgsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBaURoRSxNQUFNLE9BQU8sY0FBZSxTQUFRLGFBQTBCO0lBUTVELFlBQVksV0FBNEM7O1FBQ3RELEtBQUssRUFBRSxDQUFDO1FBTEYsb0JBQWUsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztRQUM1QywwQkFBcUIsR0FBRyxFQUFFLENBQUM7UUFLakMsSUFBSSxPQUFPLFdBQVcsS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUNwQyxJQUFJLENBQUMsRUFBRSxHQUFHLFdBQVcsQ0FBQztRQUN4QixDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxFQUFFLEdBQUcsTUFBQSxXQUFXLGFBQVgsV0FBVyx1QkFBWCxXQUFXLENBQUUsRUFBRSxtQ0FBSSxXQUFXLEVBQUUsY0FBYyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3BFLElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxhQUFYLFdBQVcsdUJBQVgsV0FBVyxDQUFFLFdBQVcsQ0FBQztRQUM5QyxDQUFDO0lBQ0gsQ0FBQztJQUVPLFlBQVksQ0FBQyxTQUFpQjtRQUNwQyxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzFELENBQUM7SUFFRCwyREFBMkQ7SUFDbkQsT0FBTztRQUNiLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQztRQUN2QyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzNCLElBQUksQ0FBQyxDQUFDLEVB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WUFBWSxDQUFDO2FBQ2pEO1NBQ0YsQ0FBQztJQUNKLENBQUM7SUFFRCw4REFBOEQ7SUFDckQsS0FBSztRQUNaLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNkLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLHFCQUFxQixHQUFHLEVBQUUsQ0FBQztJQUNsQyxDQUFDO0lBRUQsMkNBQTJDO0lBQzNDLEtBQUs7UUFDSCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDZixDQUFDOztBQTNJYyx1QkFBUSxHQUFHLENBQUMsQUFBSixDQUFLIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNZXRyaWNSZWNvcmRlciDigJQgcGVyLXN0ZXAgdGltaW5nIGFuZCBleGVjdXRpb24gY291bnRzLCBrZXllZCBieSBydW50aW1lU3RhZ2VJZC5cbiAqXG4gKiBTdG9yZXMgcGVyLWludm9jYXRpb24gZGF0YSBkdXJpbmcgdHJhdmVyc2FsLiBBZ2dyZWdhdGVkIHZpZXdzIGNvbXB1dGVkIG9uIHJlYWQuXG4gKiBFeHRlbmRzIEtleWVkUmVjb3JkZXI8U3RlcE1ldHJpY3M+IGZvciBPKDEpIGxvb2t1cCBhbmQgc3RhbmRhcmQgb3BlcmF0aW9ucy5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgbWV0cmljID0gbmV3IE1ldHJpY1JlY29yZGVyKCk7XG4gKiBleGVjdXRvci5hdHRhY2hSZWNvcmRlcihtZXRyaWMpO1xuICogYXdhaXQgZXhlY3V0b3IucnVuKCk7XG4gKlxuICogLy8gUGVyLXN0ZXAgKHRpbWUtdHJhdmVsKTpcbiAqIG1ldHJpYy5nZXRCeUtleSgnY2FsbC1sbG0jNScpOyAgLy8geyBzdGFnZU5hbWUsIHJlYWRDb3VudCwgd3JpdGVDb3VudCwgZHVyYXRpb24gfVxuICpcbiAqIC8vIEFnZ3JlZ2F0ZWQgKGJhY2t3YXJkIGNvbXBhdCk6XG4gKiBtZXRyaWMuZ2V0TWV0cmljcygpOyAgLy8geyB0b3RhbER1cmF0aW9uLCB0b3RhbFJlYWRzLCBzdGFnZU1ldHJpY3M6IE1hcDxzdGFnZU5hbWUsIGFnZ3JlZ2F0ZWQ+IH1cbiAqXG4gKiAvLyBQcm9ncmVzc2l2ZSAoc2xpZGVyKTpcbiAqIG1ldHJpYy5hY2N1bXVsYXRlKChzdW0sIG0pID0+IHN1bSArIG0uZHVyYXRpb24sIDAsIHZpc2libGVLZXlzKTtcbiAqIGBgYFxuICovXG5cbmltcG9ydCB7IEtleWVkUmVjb3JkZXIgfSBmcm9tICcuLi8uLi9yZWNvcmRlci9LZXllZFJlY29yZGVyLmpzJztcbmltcG9ydCB0eXBlIHsgQ29tbWl0RXZlbnQsIFBhdXNlRXZlbnQsIFJlYWRFdmVudCwgUmVjb3JkZXIsIFN0YWdlRXZlbnQsIFdyaXRlRXZlbnQgfSBmcm9tICcuLi90eXBlcy5qcyc7XG5cbi8qKiBQZXItaW52b2NhdGlvbiBtZXRyaWNzIGZvciBhIHNpbmdsZSBleGVjdXRpb24gc3RlcC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RlcE1ldHJpY3Mge1xuICAvKiogSHVtYW4tcmVhZGFibGUgc3RhZ2UgbmFtZS4gKi9cbiAgc3RhZ2VOYW1lOiBzdHJpbmc7XG4gIC8qKiBOdW1iZXIgb2Ygc2NvcGUgcmVhZHMgZHVyaW5nIHRoaXMgaW52b2NhdGlvbi4gKi9cbiAgcmVhZENvdW50OiBudW1iZXI7XG4gIC8qKiBOdW1iZXIgb2Ygc2NvcGUgd3JpdGVzIGR1cmluZyB0aGlzIGludm9jYXRpb24uICovXG4gIHdyaXRlQ291bnQ6IG51bWJlcjtcbiAgLyoqIE51bWJlciBvZiBjb21taXRzIGR1cmluZyB0aGlzIGludm9jYXRpb24uICovXG4gIGNvbW1pdENvdW50OiBudW1iZXI7XG4gIC8qKiBOdW1iZXIgb2YgcGF1c2VzIGR1cmluZyB0aGlzIGludm9jYXRpb24uICovXG4gIHBhdXNlQ291bnQ6IG51bWJlcjtcbiAgLyoqIER1cmF0aW9uIGluIG1zIGZvciB0aGlzIGludm9jYXRpb24uICovXG4gIGR1cmF0aW9uOiBudW1iZXI7XG59XG5cbi8qKiBBZ2dyZWdhdGVkIG1ldHJpY3MgYWNyb3NzIGFsbCBpbnZvY2F0aW9ucyAoYmFja3dhcmQgY29tcGF0aWJsZSkuICovXG5leHBvcnQgaW50ZXJmYWNlIEFnZ3JlZ2F0ZWRNZXRyaWNzIHtcbiAgdG90YWxEdXJhdGlvbjogbnVtYmVyO1xuICB0b3RhbFJlYWRzOiBudW1iZXI7XG4gIHRvdGFsV3JpdGVzOiBudW1iZXI7XG4gIHRvdGFsQ29tbWl0czogbnVtYmVyO1xuICB0b3RhbFBhdXNlczogbnVtYmVyO1xuICAvKiogQWdncmVnYXRlZCBieSBzdGFnZU5hbWUg4oCUIHN1bXMgYWNyb3NzIGxvb3AgaW52b2NhdGlvbnMuICovXG4gIHN0YWdlTWV0cmljczogTWFwPHN0cmluZywgU3RhZ2VNZXRyaWNzPjtcbn1cblxuLyoqIEFnZ3JlZ2F0ZWQgcGVyLXN0YWdlTmFtZSAoYmFja3dhcmQgY29tcGF0aWJsZSB3aXRoIHByZS1ydW50aW1lU3RhZ2VJZCBBUEkpLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdGFnZU1ldHJpY3Mge1xuICBzdGFnZU5hbWU6IHN0cmluZztcbiAgcmVhZENvdW50OiBudW1iZXI7XG4gIHdyaXRlQ291bnQ6IG51bWJlcjtcbiAgY29tbWl0Q291bnQ6IG51bWJlcjtcbiAgcGF1c2VDb3VudDogbnVtYmVyO1xuICB0b3RhbER1cmF0aW9uOiBudW1iZXI7XG4gIGludm9jYXRpb25Db3VudDogbnVtYmVyO1xufVxuXG4vKiogT3B0aW9ucyBmb3IgTWV0cmljUmVjb3JkZXIuICovXG5leHBvcnQgaW50ZXJmYWNlIE1ldHJpY1JlY29yZGVyT3B0aW9ucyB7XG4gIC8qKiBSZWNvcmRlciBJRC4gRGVmYXVsdHMgdG8gYXV0by1pbmNyZW1lbnQgKGBtZXRyaWNzLTFgLCBgbWV0cmljcy0yYCwgLi4uKS4gKi9cbiAgaWQ/OiBzdHJpbmc7XG4gIC8qKiBGaWx0ZXIgd2hpY2ggc3RhZ2VzIGFyZSByZWNvcmRlZC4gUmV0dXJuIGB0cnVlYCB0byByZWNvcmQsIGBmYWxzZWAgdG8gc2tpcC4gKi9cbiAgc3RhZ2VGaWx0ZXI/OiAoc3RhZ2VOYW1lOiBzdHJpbmcpID0+IGJvb2xlYW47XG59XG5cbmV4cG9ydCBjbGFzcyBNZXRyaWNSZWNvcmRlciBleHRlbmRzIEtleWVkUmVjb3JkZXI8U3RlcE1ldHJpY3M+IGltcGxlbWVudHMgUmVjb3JkZXIge1xuICBwcml2YXRlIHN0YXRpYyBfY291bnRlciA9IDA7XG5cbiAgcmVhZG9ubHkgaWQ6IHN0cmluZztcbiAgcHJpdmF0ZSBzdGFnZVN0YXJ0VGltZXMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICBwcml2YXRlIGN1cnJlbnRSdW50aW1lU3RhZ2VJZCA9ICcnO1xuICBwcml2YXRlIHN0YWdlRmlsdGVyPzogKHN0YWdlTmFtZTogc3RyaW5nKSA9PiBib29sZWFuO1xuXG4gIGNvbnN0cnVjdG9yKGlkT3JPcHRpb25zPzogc3RyaW5nIHwgTWV0cmljUmVjb3JkZXJPcHRpb25zKSB7XG4gICAgc3VwZXIoKTtcbiAgICBpZiAodHlwZW9mIGlkT3JPcHRpb25zID09PSAnc3RyaW5nJykge1xuICAgICAgdGhpcy5pZCA9IGlkT3JPcHRpb25zO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmlkID0gaWRPck9wdGlvbnM/LmlkID8/IGBtZXRyaWNzLSR7KytNZXRyaWNSZWNvcmRlci5fY291bnRlcn1gO1xuICAgICAgdGhpcy5zdGFnZUZpbHRlciA9IGlkT3JPcHRpb25zPy5zdGFnZUZpbHRlcjtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNob3VsZFJlY29yZChzdGFnZU5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhdGhpcy5zdGFnZUZpbHRlciB8fCB0aGlzLnN0YWdlRmlsdGVyKHN0YWdlTmFtZSk7XG4gIH1cblxuICAvKiogR2V0IG9yIGNyZWF0ZSB0aGUgU3RlcE1ldHJpY3MgZm9yIHRoZSBjdXJyZW50IHN0YWdlLiAqL1xuICBwcml2YXRlIGN1cnJlbnQoKTogU3RlcE1ldHJpY3Mge1xuICAgIGNvbnN0IGtleSA9IHRoaXMuY3VycmVudFJ1bnRpbWVTdGFnZUlkO1xuICAgIGxldCBtID0gdGhpcy5nZXRCeUtleShrZXkpO1xuICAgIGlmICghbSkge1xuICAgICAgbSA9IHsgc3RhZ2VOYW1lOiAnJywgcmVhZENvdW50OiAwLCB3cml0ZUNvdW50OiAwLCBjb21taXRDb3VudDogMCwgcGF1c2VDb3VudDogMCwgZHVyYXRpb246IDAgfTtcbiAgICAgIHRoaXMuc3RvcmUoa2V5LCBtKTtcbiAgICB9XG4gICAgcmV0dXJuIG07XG4gIH1cblxuICBvblN0YWdlU3RhcnQoZXZlbnQ6IFN0YWdlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuc2hvdWxkUmVjb3JkKGV2ZW50LnN0YWdlTmFtZSkpIHJldHVybjtcbiAgICB0aGlzLmN1cnJlbnRSdW50aW1lU3RhZ2VJZCA9IGV2ZW50LnJ1bnRpbWVTdGFnZUlkO1xuICAgIHRoaXMuc3RhZ2VTdGFydFRpbWVzLnNldChldmVudC5ydW50aW1lU3RhZ2VJZCwgZXZlbnQudGltZXN0YW1wKTtcbiAgICBjb25zdCBtID0gdGhpcy5jdXJyZW50KCk7XG4gICAgbS5zdGFnZU5hbWUgPSBldmVudC5zdGFnZU5hbWU7XG4gIH1cblxuICBvblJlYWQoZXZlbnQ6IFJlYWRFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5zaG91bGRSZWNvcmQoZXZlbnQuc3RhZ2VOYW1lKSkgcmV0dXJuO1xuICAgIHRoaXMuY3VycmVudCgpLnJlYWRDb3VudCsrO1xuICB9XG5cbiAgb25Xcml0ZShldmVudDogV3JpdGVFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5zaG91bGRSZWNvcmQoZXZlbnQuc3RhZ2VOYW1lKSkgcmV0dXJuO1xuICAgIHRoaXMuY3VycmVudCgpLndyaXRlQ291bnQrKztcbiAgfVxuXG4gIG9uQ29tbWl0KGV2ZW50OiBDb21taXRFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5zaG91bGRSZWNvcmQoZXZlbnQuc3RhZ2VOYW1lKSkgcmV0dXJuO1xuICAgIHRoaXMuY3VycmVudCgpLmNvbW1pdENvdW50Kys7XG4gIH1cblxuICBvblBhdXNlKGV2ZW50OiBQYXVzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnNob3VsZFJlY29yZChldmVudC5zdGFnZU5hbWUpKSByZXR1cm47XG4gICAgdGhpcy5jdXJyZW50KCkucGF1c2VDb3VudCsrO1xuICB9XG5cbiAgb25TdGFnZUVuZChldmVudDogU3RhZ2VFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5zaG91bGRSZWNvcmQoZXZlbnQuc3RhZ2VOYW1lKSkgcmV0dXJuO1xuICAgIGNvbnN0IG0gPSB0aGlzLmN1cnJlbnQoKTtcbiAgICBpZiAoZXZlbnQuZHVyYXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgbS5kdXJhdGlvbiA9IGV2ZW50LmR1cmF0aW9uO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBzdGFydFRpbWUgPSB0aGlzLnN0YWdlU3RhcnRUaW1lcy5nZXQoZXZlbnQucnVudGltZVN0YWdlSWQpO1xuICAgICAgbS5kdXJhdGlvbiA9IHN0YXJ0VGltZSAhPT0gdW5kZWZpbmVkID8gZXZlbnQudGltZXN0YW1wIC0gc3RhcnRUaW1lIDogMDtcbiAgICB9XG4gICAgdGhpcy5zdGFnZVN0YXJ0VGltZXMuZGVsZXRlKGV2ZW50LnJ1bnRpbWVTdGFnZUlkKTtcbiAgfVxuXG4gIC8qKiBBZ2dyZWdhdGVkIG1ldHJpY3Mg4oCUIGNvbXB1dGVzIHRvdGFscyBvbiB0aGUgZmx5IGZyb20gcGVyLXN0ZXAgZGF0YSAoYmFja3dhcmQgY29tcGF0aWJsZSkuICovXG4gIGdldE1ldHJpY3MoKTogQWdncmVnYXRlZE1ldHJpY3Mge1xuICAgIGNvbnN0IGJ5TmFtZSA9IG5ldyBNYXA8c3RyaW5nLCBTdGFnZU1ldHJpY3M+KCk7XG5cbiAgICBjb25zdCB0b3RhbER1cmF0aW9uID0gdGhpcy5hZ2dyZWdhdGUoKHN1bSwgbSkgPT4gc3VtICsgbS5kdXJhdGlvbiwgMCk7XG4gICAgY29uc3QgdG90YWxSZWFkcyA9IHRoaXMuYWdncmVnYXRlKChzdW0sIG0pID0+IHN1bSArIG0ucmVhZENvdW50LCAwKTtcbiAgICBjb25zdCB0b3RhbFdyaXRlcyA9IHRoaXMuYWdncmVnYXRlKChzdW0sIG0pID0+IHN1bSArIG0ud3JpdGVDb3VudCwgMCk7XG4gICAgY29uc3QgdG90YWxDb21taXRzID0gdGhpcy5hZ2dyZWdhdGUoKHN1bSwgbSkgPT4gc3VtICsgbS5jb21taXRDb3VudCwgMCk7XG4gICAgY29uc3QgdG90YWxQYXVzZXMgPSB0aGlzLmFnZ3JlZ2F0ZSgoc3VtLCBtKSA9PiBzdW0gKyBtLnBhdXNlQ291bnQsIDApO1xuXG4gICAgLy8gR3JvdXAgYnkgc3RhZ2VOYW1lIGZvciBiYWNrd2FyZCBjb21wYXRcbiAgICBmb3IgKGNvbnN0IG0gb2YgdGhpcy52YWx1ZXMoKSkge1xuICAgICAgY29uc3QgZXhpc3RpbmcgPSBieU5hbWUuZ2V0KG0uc3RhZ2VOYW1lKTtcbiAgICAgIGlmIChleGlzdGluZykge1xuICAgICAgICBleGlzdGluZy5yZWFkQ291bnQgKz0gbS5yZWFkQ291bnQ7XG4gICAgICAgIGV4aXN0aW5nLndyaXRlQ291bnQgKz0gbS53cml0ZUNvdW50O1xuICAgICAgICBleGlzdGluZy5jb21taXRDb3VudCArPSBtLmNvbW1pdENvdW50O1xuICAgICAgICBleGlzdGluZy5wYXVzZUNvdW50ICs9IG0ucGF1c2VDb3VudDtcbiAgICAgICAgZXhpc3RpbmcudG90YWxEdXJhdGlvbiArPSBtLmR1cmF0aW9uO1xuICAgICAgICBleGlzdGluZy5pbnZvY2F0aW9uQ291bnQrKztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJ5TmFtZS5zZXQobS5zdGFnZU5hbWUsIHtcbiAgICAgICAgICBzdGFnZU5hbWU6IG0uc3RhZ2VOYW1lLFxuICAgICAgICAgIHJlYWRDb3VudDogbS5yZWFkQ291bnQsXG4gICAgICAgICAgd3JpdGVDb3VudDogbS53cml0ZUNvdW50LFxuICAgICAgICAgIGNvbW1pdENvdW50OiBtLmNvbW1pdENvdW50LFxuICAgICAgICAgIHBhdXNlQ291bnQ6IG0ucGF1c2VDb3VudCxcbiAgICAgICAgICB0b3RhbER1cmF0aW9uOiBtLmR1cmF0aW9uLFxuICAgICAgICAgIGludm9jYXRpb25Db3VudDogMSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgdG90YWxEdXJhdGlvbiwgdG90YWxSZWFkcywgdG90YWxXcml0ZXMsIHRvdGFsQ29tbWl0cywgdG90YWxQYXVzZXMsIHN0YWdlTWV0cmljczogYnlOYW1lIH07XG4gIH1cblxuICAvKiogR2V0IGFnZ3JlZ2F0ZWQgbWV0cmljcyBmb3IgYSBzcGVjaWZpYyBzdGFnZSBuYW1lIChiYWNrd2FyZCBjb21wYXRpYmxlKS4gKi9cbiAgZ2V0U3RhZ2VNZXRyaWNzKHN0YWdlTmFtZTogc3RyaW5nKTogU3RhZ2VNZXRyaWNzIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBtZXRyaWNzID0gdGhpcy5nZXRNZXRyaWNzKCk7XG4gICAgcmV0dXJuIG1ldHJpY3Muc3RhZ2VNZXRyaWNzLmdldChzdGFnZU5hbWUpO1xuICB9XG5cbiAgLyoqIFNuYXBzaG90IGZvciBzZXJpYWxpemF0aW9uIChiYWNrd2FyZCBjb21wYXRpYmxlIGZvcm1hdCkuICovXG4gIHRvU25hcHNob3QoKTogeyBuYW1lOiBzdHJpbmc7IGRhdGE6IHVua25vd24gfSB7XG4gICAgY29uc3QgbWV0cmljcyA9IHRoaXMuZ2V0TWV0cmljcygpO1xuICAgIHJldHVybiB7XG4gICAgICBuYW1lOiAnTWV0cmljcycsXG4gICAgICBkYXRhOiB7XG4gICAgICAgIHRvdGFsRHVyYXRpb246IG1ldHJpY3MudG90YWxEdXJhdGlvbixcbiAgICAgICAgdG90YWxSZWFkczogbWV0cmljcy50b3RhbFJlYWRzLFxuICAgICAgICB0b3RhbFdyaXRlczogbWV0cmljcy50b3RhbFdyaXRlcyxcbiAgICAgICAgdG90YWxDb21taXRzOiBtZXRyaWNzLnRvdGFsQ29tbWl0cyxcbiAgICAgICAgc3RhZ2VzOiBPYmplY3QuZnJvbUVudHJpZXMobWV0cmljcy5zdGFnZU1ldHJpY3MpLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqIENsZWFyIGFsbCBzdGF0ZSDigJQgY2FsbGVkIGJ5IGV4ZWN1dG9yIGJlZm9yZSBlYWNoIHJ1bigpLiAqL1xuICBvdmVycmlkZSBjbGVhcigpOiB2b2lkIHtcbiAgICBzdXBlci5jbGVhcigpO1xuICAgIHRoaXMuc3RhZ2VTdGFydFRpbWVzLmNsZWFyKCk7XG4gICAgdGhpcy5jdXJyZW50UnVudGltZVN0YWdlSWQgPSAnJztcbiAgfVxuXG4gIC8qKiBBbGlhcyBmb3IgY2xlYXIoKSAoYmFja3dhcmQgY29tcGF0KS4gKi9cbiAgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy5jbGVhcigpO1xuICB9XG59XG4iXX0=
@@ -1,3 +1,3 @@
1
1
  export { DebugRecorder } from './DebugRecorder.js';
2
2
  export { MetricRecorder } from './MetricRecorder.js';
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3Njb3BlL3JlY29yZGVycy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFXQSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFbkQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHFCQUFxQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogaXN0YW5idWwgaWdub3JlIGZpbGUgKi9cbmV4cG9ydCB0eXBlIHtcbiAgQ29tbWl0RXZlbnQsXG4gIEVycm9yRXZlbnQsXG4gIFJlYWRFdmVudCxcbiAgUmVjb3JkZXIsXG4gIFJlY29yZGVyQ29udGV4dCxcbiAgU3RhZ2VFdmVudCxcbiAgV3JpdGVFdmVudCxcbn0gZnJvbSAnLi4vdHlwZXMuanMnO1xuZXhwb3J0IHR5cGUgeyBEZWJ1Z0VudHJ5LCBEZWJ1Z1JlY29yZGVyT3B0aW9ucywgRGVidWdWZXJib3NpdHkgfSBmcm9tICcuL0RlYnVnUmVjb3JkZXIuanMnO1xuZXhwb3J0IHsgRGVidWdSZWNvcmRlciB9IGZyb20gJy4vRGVidWdSZWNvcmRlci5qcyc7XG5leHBvcnQgdHlwZSB7IEFnZ3JlZ2F0ZWRNZXRyaWNzLCBTdGFnZU1ldHJpY3MgfSBmcm9tICcuL01ldHJpY1JlY29yZGVyLmpzJztcbmV4cG9ydCB7IE1ldHJpY1JlY29yZGVyIH0gZnJvbSAnLi9NZXRyaWNSZWNvcmRlci5qcyc7XG4iXX0=
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3Njb3BlL3JlY29yZGVycy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFXQSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFbkQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHFCQUFxQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogaXN0YW5idWwgaWdub3JlIGZpbGUgKi9cbmV4cG9ydCB0eXBlIHtcbiAgQ29tbWl0RXZlbnQsXG4gIEVycm9yRXZlbnQsXG4gIFJlYWRFdmVudCxcbiAgUmVjb3JkZXIsXG4gIFJlY29yZGVyQ29udGV4dCxcbiAgU3RhZ2VFdmVudCxcbiAgV3JpdGVFdmVudCxcbn0gZnJvbSAnLi4vdHlwZXMuanMnO1xuZXhwb3J0IHR5cGUgeyBEZWJ1Z0VudHJ5LCBEZWJ1Z1JlY29yZGVyT3B0aW9ucywgRGVidWdWZXJib3NpdHkgfSBmcm9tICcuL0RlYnVnUmVjb3JkZXIuanMnO1xuZXhwb3J0IHsgRGVidWdSZWNvcmRlciB9IGZyb20gJy4vRGVidWdSZWNvcmRlci5qcyc7XG5leHBvcnQgdHlwZSB7IEFnZ3JlZ2F0ZWRNZXRyaWNzLCBTdGFnZU1ldHJpY3MsIFN0ZXBNZXRyaWNzIH0gZnJvbSAnLi9NZXRyaWNSZWNvcmRlci5qcyc7XG5leHBvcnQgeyBNZXRyaWNSZWNvcmRlciB9IGZyb20gJy4vTWV0cmljUmVjb3JkZXIuanMnO1xuIl19
package/dist/esm/trace.js CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * footprintjs/trace — Execution tracing, debugging, and backtracking utilities.
3
3
  *
4
- * Runtime stage IDs, commit log queries, and keyed recorder base class.
4
+ * Runtime stage IDs, commit log queries, and recorder base classes.
5
5
  *
6
6
  * @example
7
7
  * ```typescript
8
- * import { parseRuntimeStageId, findLastWriter, KeyedRecorder } from 'footprintjs/trace';
8
+ * import { parseRuntimeStageId, findLastWriter, KeyedRecorder, SequenceRecorder } from 'footprintjs/trace';
9
9
  *
10
10
  * // Parse a runtimeStageId
11
11
  * const { stageId, executionIndex } = parseRuntimeStageId('call-llm#5');
@@ -13,13 +13,18 @@
13
13
  * // Backtrack: who wrote 'systemPrompt' before stage at idx 8?
14
14
  * const writer = findLastWriter(commitLog, 'systemPrompt', 8);
15
15
  *
16
- * // Build a keyed recorder
16
+ * // Build a keyed recorder (1:1 — one entry per step)
17
17
  * class MyRecorder extends KeyedRecorder<MyEntry> { ... }
18
+ *
19
+ * // Build a sequence recorder (1:N — multiple entries per step, ordering matters)
20
+ * class AuditRecorder extends SequenceRecorder<AuditEntry> { ... }
18
21
  * ```
19
22
  */
20
23
  export { buildRuntimeStageId, createExecutionCounter, parseRuntimeStageId } from './lib/engine/runtimeStageId.js';
21
24
  // Commit log queries — typed utilities for backtracking
22
25
  export { findCommit, findCommits, findLastWriter } from './lib/memory/commitLogUtils.js';
23
- // KeyedRecorder — base class for Map-based recorders
26
+ // KeyedRecorder — base class for 1:1 Map-based recorders
24
27
  export { KeyedRecorder } from './lib/recorder/KeyedRecorder.js';
25
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHJhY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtCRztBQUlILE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxzQkFBc0IsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBRWxILHdEQUF3RDtBQUN4RCxPQUFPLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxjQUFjLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUV6RixxREFBcUQ7QUFDckQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBmb290cHJpbnRqcy90cmFjZSDigJQgRXhlY3V0aW9uIHRyYWNpbmcsIGRlYnVnZ2luZywgYW5kIGJhY2t0cmFja2luZyB1dGlsaXRpZXMuXG4gKlxuICogUnVudGltZSBzdGFnZSBJRHMsIGNvbW1pdCBsb2cgcXVlcmllcywgYW5kIGtleWVkIHJlY29yZGVyIGJhc2UgY2xhc3MuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IHBhcnNlUnVudGltZVN0YWdlSWQsIGZpbmRMYXN0V3JpdGVyLCBLZXllZFJlY29yZGVyIH0gZnJvbSAnZm9vdHByaW50anMvdHJhY2UnO1xuICpcbiAqIC8vIFBhcnNlIGEgcnVudGltZVN0YWdlSWRcbiAqIGNvbnN0IHsgc3RhZ2VJZCwgZXhlY3V0aW9uSW5kZXggfSA9IHBhcnNlUnVudGltZVN0YWdlSWQoJ2NhbGwtbGxtIzUnKTtcbiAqXG4gKiAvLyBCYWNrdHJhY2s6IHdobyB3cm90ZSAnc3lzdGVtUHJvbXB0JyBiZWZvcmUgc3RhZ2UgYXQgaWR4IDg/XG4gKiBjb25zdCB3cml0ZXIgPSBmaW5kTGFzdFdyaXRlcihjb21taXRMb2csICdzeXN0ZW1Qcm9tcHQnLCA4KTtcbiAqXG4gKiAvLyBCdWlsZCBhIGtleWVkIHJlY29yZGVyXG4gKiBjbGFzcyBNeVJlY29yZGVyIGV4dGVuZHMgS2V5ZWRSZWNvcmRlcjxNeUVudHJ5PiB7IC4uLiB9XG4gKiBgYGBcbiAqL1xuXG4vLyBSdW50aW1lIHN0YWdlIElEIOKAlCB1bmlxdWUgZXhlY3V0aW9uIHN0ZXAgaWRlbnRpZmllcnNcbmV4cG9ydCB0eXBlIHsgRXhlY3V0aW9uQ291bnRlciB9IGZyb20gJy4vbGliL2VuZ2luZS9ydW50aW1lU3RhZ2VJZC5qcyc7XG5leHBvcnQgeyBidWlsZFJ1bnRpbWVTdGFnZUlkLCBjcmVhdGVFeGVjdXRpb25Db3VudGVyLCBwYXJzZVJ1bnRpbWVTdGFnZUlkIH0gZnJvbSAnLi9saWIvZW5naW5lL3J1bnRpbWVTdGFnZUlkLmpzJztcblxuLy8gQ29tbWl0IGxvZyBxdWVyaWVzIOKAlCB0eXBlZCB1dGlsaXRpZXMgZm9yIGJhY2t0cmFja2luZ1xuZXhwb3J0IHsgZmluZENvbW1pdCwgZmluZENvbW1pdHMsIGZpbmRMYXN0V3JpdGVyIH0gZnJvbSAnLi9saWIvbWVtb3J5L2NvbW1pdExvZ1V0aWxzLmpzJztcblxuLy8gS2V5ZWRSZWNvcmRlciDigJQgYmFzZSBjbGFzcyBmb3IgTWFwLWJhc2VkIHJlY29yZGVyc1xuZXhwb3J0IHsgS2V5ZWRSZWNvcmRlciB9IGZyb20gJy4vbGliL3JlY29yZGVyL0tleWVkUmVjb3JkZXIuanMnO1xuIl19
28
+ // SequenceRecorder — base class for 1:N ordered sequence recorders with keyed index
29
+ export { SequenceRecorder } from './lib/recorder/SequenceRecorder.js';
30
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHJhY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUlILE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxzQkFBc0IsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBRWxILHdEQUF3RDtBQUN4RCxPQUFPLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxjQUFjLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUV6Rix5REFBeUQ7QUFDekQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRWhFLG9GQUFvRjtBQUNwRixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogZm9vdHByaW50anMvdHJhY2Ug4oCUIEV4ZWN1dGlvbiB0cmFjaW5nLCBkZWJ1Z2dpbmcsIGFuZCBiYWNrdHJhY2tpbmcgdXRpbGl0aWVzLlxuICpcbiAqIFJ1bnRpbWUgc3RhZ2UgSURzLCBjb21taXQgbG9nIHF1ZXJpZXMsIGFuZCByZWNvcmRlciBiYXNlIGNsYXNzZXMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IHBhcnNlUnVudGltZVN0YWdlSWQsIGZpbmRMYXN0V3JpdGVyLCBLZXllZFJlY29yZGVyLCBTZXF1ZW5jZVJlY29yZGVyIH0gZnJvbSAnZm9vdHByaW50anMvdHJhY2UnO1xuICpcbiAqIC8vIFBhcnNlIGEgcnVudGltZVN0YWdlSWRcbiAqIGNvbnN0IHsgc3RhZ2VJZCwgZXhlY3V0aW9uSW5kZXggfSA9IHBhcnNlUnVudGltZVN0YWdlSWQoJ2NhbGwtbGxtIzUnKTtcbiAqXG4gKiAvLyBCYWNrdHJhY2s6IHdobyB3cm90ZSAnc3lzdGVtUHJvbXB0JyBiZWZvcmUgc3RhZ2UgYXQgaWR4IDg/XG4gKiBjb25zdCB3cml0ZXIgPSBmaW5kTGFzdFdyaXRlcihjb21taXRMb2csICdzeXN0ZW1Qcm9tcHQnLCA4KTtcbiAqXG4gKiAvLyBCdWlsZCBhIGtleWVkIHJlY29yZGVyICgxOjEg4oCUIG9uZSBlbnRyeSBwZXIgc3RlcClcbiAqIGNsYXNzIE15UmVjb3JkZXIgZXh0ZW5kcyBLZXllZFJlY29yZGVyPE15RW50cnk+IHsgLi4uIH1cbiAqXG4gKiAvLyBCdWlsZCBhIHNlcXVlbmNlIHJlY29yZGVyICgxOk4g4oCUIG11bHRpcGxlIGVudHJpZXMgcGVyIHN0ZXAsIG9yZGVyaW5nIG1hdHRlcnMpXG4gKiBjbGFzcyBBdWRpdFJlY29yZGVyIGV4dGVuZHMgU2VxdWVuY2VSZWNvcmRlcjxBdWRpdEVudHJ5PiB7IC4uLiB9XG4gKiBgYGBcbiAqL1xuXG4vLyBSdW50aW1lIHN0YWdlIElEIOKAlCB1bmlxdWUgZXhlY3V0aW9uIHN0ZXAgaWRlbnRpZmllcnNcbmV4cG9ydCB0eXBlIHsgRXhlY3V0aW9uQ291bnRlciB9IGZyb20gJy4vbGliL2VuZ2luZS9ydW50aW1lU3RhZ2VJZC5qcyc7XG5leHBvcnQgeyBidWlsZFJ1bnRpbWVTdGFnZUlkLCBjcmVhdGVFeGVjdXRpb25Db3VudGVyLCBwYXJzZVJ1bnRpbWVTdGFnZUlkIH0gZnJvbSAnLi9saWIvZW5naW5lL3J1bnRpbWVTdGFnZUlkLmpzJztcblxuLy8gQ29tbWl0IGxvZyBxdWVyaWVzIOKAlCB0eXBlZCB1dGlsaXRpZXMgZm9yIGJhY2t0cmFja2luZ1xuZXhwb3J0IHsgZmluZENvbW1pdCwgZmluZENvbW1pdHMsIGZpbmRMYXN0V3JpdGVyIH0gZnJvbSAnLi9saWIvbWVtb3J5L2NvbW1pdExvZ1V0aWxzLmpzJztcblxuLy8gS2V5ZWRSZWNvcmRlciDigJQgYmFzZSBjbGFzcyBmb3IgMToxIE1hcC1iYXNlZCByZWNvcmRlcnNcbmV4cG9ydCB7IEtleWVkUmVjb3JkZXIgfSBmcm9tICcuL2xpYi9yZWNvcmRlci9LZXllZFJlY29yZGVyLmpzJztcblxuLy8gU2VxdWVuY2VSZWNvcmRlciDigJQgYmFzZSBjbGFzcyBmb3IgMTpOIG9yZGVyZWQgc2VxdWVuY2UgcmVjb3JkZXJzIHdpdGgga2V5ZWQgaW5kZXhcbmV4cG9ydCB7IFNlcXVlbmNlUmVjb3JkZXIgfSBmcm9tICcuL2xpYi9yZWNvcmRlci9TZXF1ZW5jZVJlY29yZGVyLmpzJztcbiJdfQ==