@workflow/web-shared 5.0.0-beta.46 → 5.0.0-beta.48

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/dist/components/event-list-view.js +3 -3
  2. package/dist/components/trace-viewer/components/use-alt-held.d.ts +11 -0
  3. package/dist/components/trace-viewer/components/use-alt-held.d.ts.map +1 -0
  4. package/dist/components/trace-viewer/components/use-alt-held.js +48 -0
  5. package/dist/components/trace-viewer/trace-viewer.d.ts.map +1 -1
  6. package/dist/components/trace-viewer/trace-viewer.js +4 -17
  7. package/dist/components/trace-viewer.d.ts +4 -1
  8. package/dist/components/trace-viewer.d.ts.map +1 -1
  9. package/dist/components/trace-viewer.js +4 -3
  10. package/dist/components/ui/data-inspector.d.ts +3 -2
  11. package/dist/components/ui/data-inspector.d.ts.map +1 -1
  12. package/dist/components/ui/data-inspector.js +85 -8
  13. package/dist/components/workflow-traces/trace-span-construction.d.ts +2 -1
  14. package/dist/components/workflow-traces/trace-span-construction.d.ts.map +1 -1
  15. package/dist/components/workflow-traces/trace-span-construction.js +7 -3
  16. package/dist/lib/duplicate-events.d.ts.map +1 -1
  17. package/dist/lib/duplicate-events.js +14 -25
  18. package/dist/lib/hydration.d.ts.map +1 -1
  19. package/dist/lib/hydration.js +13 -1
  20. package/dist/lib/trace-builder.d.ts +3 -1
  21. package/dist/lib/trace-builder.d.ts.map +1 -1
  22. package/dist/lib/trace-builder.js +5 -5
  23. package/package.json +8 -8
  24. package/src/components/event-list-view.tsx +2 -2
  25. package/src/components/trace-viewer/components/use-alt-held.ts +54 -0
  26. package/src/components/trace-viewer/trace-viewer.tsx +3 -15
  27. package/src/components/trace-viewer.tsx +6 -1
  28. package/src/components/ui/data-inspector.tsx +105 -9
  29. package/src/components/workflow-traces/trace-span-construction.ts +14 -2
  30. package/src/lib/duplicate-events.ts +14 -26
  31. package/src/lib/hydration.ts +12 -0
  32. package/src/lib/trace-builder.test.ts +42 -1
  33. package/src/lib/trace-builder.ts +13 -4
@@ -1 +1 @@
1
- {"version":3,"file":"trace-builder.d.ts","sourceRoot":"","sources":["../../src/lib/trace-builder.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,KAAK,KAAK,EAIV,KAAK,WAAW,EACjB,MAAM,iBAAiB,CAAC;AAYzB,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,KAAK,KAAG,OAIT,CAAC;AAEvC;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,KAAK,EAAE,EACf,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,KAAK,EAAE,CAMT;AAMD,MAAM,MAAM,aAAa,GAAG;IAC1B,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IACrC,cAAc,EAAE,KAAK,EAAE,CAAC;IACxB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAClC,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;CAClC,CAAC;AAeF,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,aAAa,CAgCvE;AAsED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,EAAE,CAAC;IAClE,iEAAiE;IACjE,eAAe,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACxC;AAED,wBAAgB,UAAU,CACxB,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,KAAK,EAAE,EACf,GAAG,EAAE,IAAI;AACT;;;;;GAKG;AACH,EAAE,iBAAyB,EAAE,GAAE;IAAE,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAAO,GAClE,aAAa,CA8Cf"}
1
+ {"version":3,"file":"trace-builder.d.ts","sourceRoot":"","sources":["../../src/lib/trace-builder.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,KAAK,KAAK,EAIV,KAAK,WAAW,EACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,iBAAiB,EAOvB,MAAM,uDAAuD,CAAC;AAI/D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,KAAK,KAAG,OAIT,CAAC;AAEvC;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,KAAK,EAAE,EACf,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,KAAK,EAAE,CAMT;AAMD,MAAM,MAAM,aAAa,GAAG;IAC1B,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IACrC,cAAc,EAAE,KAAK,EAAE,CAAC;IACxB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAClC,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;CAClC,CAAC;AAeF,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,aAAa,CAgCvE;AAuED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,EAAE,CAAC;IAClE,iEAAiE;IACjE,eAAe,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACxC;AAED,wBAAgB,UAAU,CACxB,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,KAAK,EAAE,EACf,GAAG,EAAE,IAAI;AACT;;;;;GAKG;AACH,EACE,iBAAyB,EACzB,iBAAiB,GAClB,GAAE;IACD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CAClC,GACL,aAAa,CA+Cf"}
@@ -87,14 +87,14 @@ function computeLatestKnownTime(events, run) {
87
87
  }
88
88
  return new Date(latest);
89
89
  }
90
- function buildSpans(run, groupedEvents, now, latestKnownTime) {
90
+ function buildSpans(run, groupedEvents, now, latestKnownTime, getStepAttributes) {
91
91
  // Active child spans cap at latestKnownTime so they don't extend into
92
92
  // unknown territory. Even when the run is completed, we may not have loaded
93
93
  // all events yet, so always use the latest event we've actually seen.
94
94
  const childMaxEnd = latestKnownTime;
95
95
  const runMaxEnd = run.completedAt ?? now;
96
96
  const stepSpans = Array.from(groupedEvents.eventsByStepId.values())
97
- .map((events) => stepToSpan(events, childMaxEnd))
97
+ .map((events) => stepToSpan(events, childMaxEnd, getStepAttributes))
98
98
  .filter((span) => span !== null);
99
99
  const hookSpans = Array.from(groupedEvents.hookEvents.values())
100
100
  .map((events) => hookToSpan(events, childMaxEnd))
@@ -131,7 +131,7 @@ export function buildTrace(run, events, now,
131
131
  * from the only copy the caller was given, and dropping the wrong one moves
132
132
  * a span. See {@link findDuplicateEventIds}.
133
133
  */
134
- { isCompleteHistory = false } = {}) {
134
+ { isCompleteHistory = false, getStepAttributes, } = {}) {
135
135
  // Span geometry comes from what the run acted on. A repeat of a class the
136
136
  // log already records is read past by every replay, and letting one through
137
137
  // here would stretch a span to whenever a concurrent replay committed it.
@@ -146,7 +146,7 @@ export function buildTrace(run, events, now,
146
146
  const actedOnEvents = events.filter((event) => !duplicateEventIds.has(event.eventId) && !isSealedNoopEvent(event));
147
147
  const groupedEvents = groupEventsByCorrelation(actedOnEvents);
148
148
  const latestKnownTime = computeLatestKnownTime(actedOnEvents, run);
149
- const { runSpan, spans } = buildSpans(run, groupedEvents, now, latestKnownTime);
149
+ const { runSpan, spans } = buildSpans(run, groupedEvents, now, latestKnownTime, getStepAttributes);
150
150
  const sortedCascadingSpans = cascadeSpans(runSpan, spans);
151
151
  // Compute known duration relative to trace start
152
152
  const traceStartMs = otelTimeToMs(runSpan.startTime);
@@ -167,4 +167,4 @@ export function buildTrace(run, events, now,
167
167
  duplicateEventIds,
168
168
  };
169
169
  }
170
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2UtYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvdHJhY2UtYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEVBRUwsd0JBQXdCLEVBQ3hCLGVBQWUsRUFDZixlQUFlLEdBRWhCLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUNMLGlCQUFpQixFQUNqQixVQUFVLEVBQ1YsU0FBUyxFQUNULFVBQVUsRUFDVixnQkFBZ0IsRUFDaEIsVUFBVSxHQUNYLE1BQU0sdURBQXVELENBQUM7QUFDL0QsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdEQUFnRCxDQUFDO0FBQzlFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzNELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBR3BEOzs7Ozs7R0FNRztBQUNILE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxDQUFDLEtBQVksRUFBVyxFQUFFLENBQ3ZELENBQUMsS0FBSyxDQUFDLGFBQWE7SUFDcEIsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO1FBQ2hDLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztRQUMxQyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUV2Qzs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxtQkFBbUIsQ0FDakMsTUFBZSxFQUNmLFFBQTRCLEVBQzVCLE1BQTBCO0lBRTFCLElBQUksUUFBUSxLQUFLLEtBQUssRUFBRSxDQUFDO1FBQ3ZCLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBQ0QsSUFBSSxDQUFDLE1BQU07UUFBRSxPQUFPLEVBQUUsQ0FBQztJQUN2QixPQUFPLE1BQU0sQ0FBQyxNQUFNLENB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QyxPQUFPLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxDQUNyRSxDQUFDO0lBRUYsTUFBTSxhQUFhLEdBQUcsd0JBQXdCLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDOUQsTUFBTSxlQUFlLEdBQUcsc0JBQXNCLENBQUMsYUFBYSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ25FLE1BQU0sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEdBQUcsVUFBVSxDQUNuQyxHQUFHLEVBQ0gsYUFBYSxFQUNiLEdBQUcsRUFDSCxlQUFlLENBQ2hCLENBQUM7SUFDRixNQUFNLG9CQUFvQixHQUFHLFlBQVksQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFFMUQsaURBQWlEO0lBQ2pELE1BQU0sWUFBWSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDckQsTUFBTSxlQUFlLEdBQUcsZUFBZSxDQUFDLE9BQU8sRUFBRSxHQUFHLFlBQVksQ0FBQztJQUVqRSxPQUFPO1FBQ0wsT0FBTyxFQUFFLEdBQUcsQ0FBQyxLQUFLO1FBQ2xCLFVBQVUsRUFBRSxHQUFHLENBQUMsS0FBSztRQUNyQixLQUFLLEVBQUUsb0JBQW9CO1FBQzNCLFNBQVMsRUFBRTtZQUNUO2dCQUNFLElBQUksRUFBRSxVQUFVO2dCQUNoQixVQUFVLEVBQUU7b0JBQ1YsY0FBYyxFQUFFLGdCQUFnQixDQUFDLElBQUk7aUJBQ3RDO2FBQ0Y7U0FDRjtRQUNELGVBQWUsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxlQUFlLENBQUM7UUFDN0MsaUJBQWlCO0tBQ2xCLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBCdWlsZHMgYSBjb21wbGV0ZSB0cmFjZSBmcm9tIGEgV29ya2Zsb3dSdW4gYW5kIGl0cyBFdmVudHMuXG4gKlxuICogVGhpcyBtb2R1bGUgZ3JvdXBzIHJhdyBldmVudHMgYnkgY29ycmVsYXRpb24gSUQgYW5kIGVudGl0eSB0eXBlLFxuICogY29udmVydHMgZWFjaCBncm91cCBpbnRvIGFuIE9wZW5UZWxlbWV0cnktc3R5bGUgU3BhbiwgYW5kIHJldHVybnNcbiAqIGEgZnVsbHktZm9ybWVkIFRyYWNlIHJlYWR5IGZvciB0aGUgdHJhY2Ugdmlld2VyLlxuICovXG5cbmltcG9ydCB7XG4gIHR5cGUgRXZlbnQsXG4gIGlzSG9va0xpZmVjeWNsZUV2ZW50VHlwZSxcbiAgaXNTdGVwRXZlbnRUeXBlLFxuICBpc1dhaXRFdmVudFR5cGUsXG4gIHR5cGUgV29ya2Zsb3dSdW4sXG59IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQge1xuICBnZXRFdmVudFRpbWVzdGFtcCxcbiAgaG9va1RvU3BhbixcbiAgcnVuVG9TcGFuLFxuICBzdGVwVG9TcGFuLFxuICBXT1JLRkxPV19MSUJSQVJZLFxuICB3YWl0VG9TcGFuLFxufSBmcm9tICcuLi9jb21wb25lbnRzL3dvcmtmbG93LXRyYWNlcy90cmFjZS1zcGFuLWNvbnN0cnVjdGlvbic7XG5pbXBvcnQgeyBvdGVsVGltZVRvTXMgfSBmcm9tICcuLi9jb21wb25lbnRzL3dvcmtmbG93LXRyYWNlcy90cmFjZS10aW1lLXV0aWxzJztcbmltcG9ydCB7IGZpbmREdXBsaWNhdGVFdmVudElkcyB9IGZyb20gJy4vZHVwbGljYXRlLWV2ZW50cyc7XG5pbXBvcnQgeyBpc1NlYWxlZE5vb3BFdmVudCB9IGZyb20gJy4vc2VhbGVkLWV2ZW50cyc7XG5pbXBvcnQgdHlwZSB7IFNwYW4gfSBmcm9tICcuL3RyYWNlLXR5cGVzJztcblxuLyoqXG4gKiBFdmVudHMgdGhhdCBiZWxvbmcgdG8gdGhlIHJ1biByb290IHNwYW4gcmF0aGVyIHRoYW4gYSBjaGlsZCBlbnRpdHkgc3Bhbi5cbiAqIE1pcnJvcnMgdGhlIGZhbGx0aHJvdWdoIGxvZ2ljIGluIHtAbGluayBncm91cEV2ZW50c0J5Q29ycmVsYXRpb259OiBldmVudHNcbiAqIHdpdGhvdXQgYSBjb3JyZWxhdGlvbklkIChydW4gbGlmZWN5Y2xlKSBwbHVzIGNvcnJlbGF0ZWQgZXZlbnRzIHRoYXQgYXJlbid0XG4gKiBzdGVwL3RpbWVyL2hvb2sgZXZlbnRzIChlLmcuIGBhdHRyX3NldGAsIHdob3NlIGNvcnJlbGF0aW9uSWQgaXMgYSBkZWR1cFxuICogdG9rZW4gcmF0aGVyIHRoYW4gYSBjaGlsZCBlbnRpdHkgSUQpLlxuICovXG5leHBvcnQgY29uc3QgaXNSdW5MZXZlbEV2ZW50ID0gKGV2ZW50OiBFdmVudCk6IGJvb2xlYW4gPT5cbiAgIWV2ZW50LmNvcnJlbGF0aW9uSWQgfHxcbiAgKCFpc1dhaXRFdmVudFR5cGUoZXZlbnQuZXZlbnRUeXBlKSAmJlxuICAgICFpc0hvb2tMaWZlY3ljbGVFdmVudFR5cGUoZXZlbnQuZXZlbnRUeXBlKSAmJlxuICAgICFpc1N0ZXBFdmVudFR5cGUoZXZlbnQuZXZlbnRUeXBlKSk7XG5cbi8qKlxuICogRmlsdGVyIHRoZSByYXcgZXZlbnQgbGlzdCBkb3duIHRvIHRoZSBldmVudHMgZm9yIGEgc2VsZWN0ZWQgc3Bhbi5cbiAqIEZvciB0aGUgcnVuIHJvb3Qgc3BhbiB0aGlzIHJldHVybnMgcnVuLWxldmVsIGV2ZW50cyAoc2VlXG4gKiB7QGxpbmsgaXNSdW5MZXZlbEV2ZW50fSk7IGZvciBjaGlsZCBzcGFucyBpdCByZXR1cm5zIHRoZSBldmVudHNcbiAqIGNvcnJlbGF0ZWQgdG8gdGhhdCBzcGFuJ3MgSUQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaWx0ZXJTcGFuUmF3RXZlbnRzKFxuICBldmVudHM6IEV2ZW50W10sXG4gIHJlc291cmNlOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gIHNwYW5JZDogc3RyaW5nIHwgdW5kZWZpbmVkXG4pOiBFdmVudFtdIHtcbiAgaWYgKHJlc291cmNlID09PSAncnVuJykge1xuICAgIHJldHVybiBldmVudHMuZmlsdGVyKGlzUnVuTGV2ZWxFdmVudCk7XG4gIH1cbiAgaWYgKCFzcGFuSWQpIHJldHVybiBbXTtcbiAgcmV0dXJuIGV2ZW50cy5maWx0ZXIoKGUpID0+IGUuY29ycmVsYXRpb25JZCA9PT0gc3BhbklkKTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBFdmVudCBncm91cGluZ1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmV4cG9ydCB0eXBlIEdyb3VwZWRFdmVudHMgPSB7XG4gIGV2ZW50c0J5U3RlcElkOiBNYXA8c3RyaW5nLCBFdmVudFtdPjtcbiAgcnVuTGV2ZWxFdmVudHM6IEV2ZW50W107XG4gIHRpbWVyRXZlbnRzOiBNYXA8c3RyaW5nLCBFdmVudFtdPjtcbiAgaG9va0V2ZW50czogTWFwPHN0cmluZywgRXZlbnRbXT47XG59O1xuXG5mdW5jdGlvbiBwdXNoRXZlbnQoXG4gIG1hcDogTWFwPHN0cmluZywgRXZlbnRbXT4sXG4gIGNvcnJlbGF0aW9uSWQ6IHN0cmluZyxcbiAgZXZlbnQ6IEV2ZW50XG4pIHtcbiAgY29uc3QgZXhpc3RpbmcgPSBtYXAuZ2V0KGNvcnJlbGF0aW9uSWQpO1xuICBpZiAoZXhpc3RpbmcpIHtcbiAgICBleGlzdGluZy5wdXNoKGV2ZW50KTtcbiAgICByZXR1cm47XG4gIH1cbiAgbWFwLnNldChjb3JyZWxhdGlvbklkLCBbZXZlbnRdKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdyb3VwRXZlbnRzQnlDb3JyZWxhdGlvbihldmVudHM6IEV2ZW50W10pOiBHcm91cGVkRXZlbnRzIHtcbiAgY29uc3QgZXZlbnRzQnlTdGVwSWQgPSBuZXcgTWFwPHN0cmluZywgRXZlbnRbXT4oKTtcbiAgY29uc3QgcnVuTGV2ZWxFdmVudHM6IEV2ZW50W10gPSBbXTtcbiAgY29uc3QgdGltZXJFdmVudHMgPSBuZXcgTWFwPHN0cmluZywgRXZlbnRbXT4oKTtcbiAgY29uc3QgaG9va0V2ZW50cyA9IG5ldyBNYXA8c3RyaW5nLCBFdmVudFtdPigpO1xuXG4gIGZvciAoY29uc3QgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgY29uc3QgY29ycmVsYXRpb25JZCA9IGV2ZW50LmNvcnJlbGF0aW9uSWQ7XG4gICAgaWYgKCFjb3JyZWxhdGlvbklkKSB7XG4gICAgICBydW5MZXZlbEV2ZW50cy5wdXNoKGV2ZW50KTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChpc1dhaXRFdmVudFR5cGUoZXZlbnQuZXZlbnRUeXBlKSkge1xuICAgICAgcHVzaEV2ZW50KHRpbWVyRXZlbnRzLCBjb3JyZWxhdGlvbklkLCBldmVudCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoaXNIb29rTGlmZWN5Y2xlRXZlbnRUeXBlKGV2ZW50LmV2ZW50VHlwZSkpIHtcbiAgICAgIHB1c2hFdmVudChob29rRXZlbnRzLCBjb3JyZWxhdGlvbklkLCBldmVudCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoaXNTdGVwRXZlbnRUeXBlKGV2ZW50LmV2ZW50VHlwZSkpIHtcbiAgICAgIHB1c2hFdmVudChldmVudHNCeVN0ZXBJZCwgY29ycmVsYXRpb25JZCwgZXZlbnQpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgcnVuTGV2ZWxFdmVudHMucHVzaChldmVudCk7XG4gIH1cblxuICByZXR1cm4geyBldmVudHNCeVN0ZXBJZCwgcnVuTGV2ZWxFdmVudHMsIHRpbWVyRXZlbnRzLCBob29rRXZlbnRzIH07XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gVHJhY2UgY29uc3RydWN0aW9uXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLyoqXG4gKiBDb21wdXRlcyB0aGUgbGF0ZXN0IGtub3duIGV2ZW50IHRpbWUgZnJvbSB0aGUgZXZlbnRzIGxpc3QuXG4gKiBBY3RpdmUgKGluLXByb2dyZXNzKSBjaGlsZCBzcGFucyBhcmUgY2FwcGVkIGF0IHRoaXMgdGltZSBpbnN0ZWFkIG9mIGBub3dgLFxuICogc28gdGhleSBvbmx5IGV4dGVuZCBhcyBmYXIgYXMgb3VyIGRhdGEgZ29lcy5cbiAqL1xuZnVuY3Rpb24gY29tcHV0ZUxhdGVzdEtub3duVGltZShldmVudHM6IEV2ZW50W10sIHJ1bjogV29ya2Zsb3dSdW4pOiBEYXRlIHtcbiAgbGV0IGxhdGVzdCA9IG5ldyBEYXRlKHJ1bi5jcmVhdGVkQXQpLmdldFRpbWUoKTtcbiAgZm9yIChjb25zdCBldmVudCBvZiBldmVudHMpIHtcbiAgICBjb25zdCB0ID0gKGdldEV2ZW50VGltZXN0YW1wKGV2ZW50KSA/PyBuZXcgRGF0ZShldmVudC5jcmVhdGVkQXQpKS5nZXRUaW1lKCk7XG4gICAgaWYgKHQgPiBsYXRlc3QpIGxhdGVzdCA9IHQ7XG4gIH1cbiAgcmV0dXJuIG5ldyBEYXRlKGxhdGVzdCk7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkU3BhbnMoXG4gIHJ1bjogV29ya2Zsb3dSdW4sXG4gIGdyb3VwZWRFdmVudHM6IEdyb3VwZWRFdmVudHMsXG4gIG5vdzogRGF0ZSxcbiAgbGF0ZXN0S25vd25UaW1lOiBEYXRlXG4pIHtcbiAgLy8gQWN0aXZlIGNoaWxkIHNwYW5zIGNhcCBhdCBsYXRlc3RLbm93blRpbWUgc28gdGhleSBkb24ndCBleHRlbmQgaW50b1xuICAvLyB1bmtub3duIHRlcnJpdG9yeS4gRXZlbiB3aGVuIHRoZSBydW4gaXMgY29tcGxldGVkLCB3ZSBtYXkgbm90IGhhdmUgbG9hZGVkXG4gIC8vIGFsbCBldmVudHMgeWV0LCBzbyBhbHdheXMgdXNlIHRoZSBsYXRlc3QgZXZlbnQgd2UndmUgYWN0dWFsbHkgc2Vlbi5cbiAgY29uc3QgY2hpbGRNYXhFbmQgPSBsYXRlc3RLbm93blRpbWU7XG4gIGNvbnN0IHJ1bk1heEVuZCA9IHJ1bi5jb21wbGV0ZWRBdCA/PyBub3c7XG5cbiAgY29uc3Qgc3RlcFNwYW5zID0gQXJyYXkuZnJvbShncm91cGVkRXZlbnRzLmV2ZW50c0J5U3RlcElkLnZhbHVlcygpKVxuICAgIC5tYXAoKGV2ZW50cykgPT4gc3RlcFRvU3BhbihldmVudHMsIGNoaWxkTWF4RW5kKSlcbiAgICAuZmlsdGVyKChzcGFuKTogc3BhbiBpcyBTcGFuID0+IHNwYW4gIT09IG51bGwpO1xuXG4gIGNvbnN0IGhvb2tTcGFucyA9IEFycmF5LmZyb20oZ3JvdXBlZEV2ZW50cy5ob29rRXZlbnRzLnZhbHVlcygpKVxuICAgIC5tYXAoKGV2ZW50cykgPT4gaG9va1RvU3BhbihldmVudHMsIGNoaWxkTWF4RW5kKSlcbiAgICAuZmlsdGVyKChzcGFuKTogc3BhbiBpcyBTcGFuID0+IHNwYW4gIT09IG51bGwpO1xuXG4gIGNvbnN0IHdhaXRTcGFucyA9IEFycmF5LmZyb20oZ3JvdXBlZEV2ZW50cy50aW1lckV2ZW50cy52YWx1ZXMoKSlcbiAgICAubWFwKChldmVudHMpID0+IHdhaXRUb1NwYW4oZXZlbnRzLCBjaGlsZE1heEVuZCwgcnVuTWF4RW5kKSlcbiAgICAuZmlsdGVyKChzcGFuKTogc3BhbiBpcyBTcGFuID0+IHNwYW4gIT09IG51bGwpO1xuXG4gIHJldHVybiB7XG4gICAgcnVuU3BhbjogcnVuVG9TcGFuKHJ1biwgZ3JvdXBlZEV2ZW50cy5ydW5MZXZlbEV2ZW50cywgbm93KSxcbiAgICBzcGFuczogWy4uLnN0ZXBTcGFucywgLi4uaG9va1NwYW5zLCAuLi53YWl0U3BhbnNdLFxuICB9O1xufVxuXG5mdW5jdGlvbiBjYXNjYWRlU3BhbnMocnVuU3BhbjogU3Bhbiwgc3BhbnM6IFNwYW5bXSkge1xuICBjb25zdCBzb3J0ZWRTcGFucyA9IFtcbiAgICBydW5TcGFuLFxuICAgIC4uLnNwYW5zLnNsaWNlKCkuc29ydCgoYSwgYikgPT4ge1xuICAgICAgY29uc3QgYVN0YXJ0ID0gb3RlbFRpbWVUb01zKGEuc3RhcnRUaW1lKTtcbiAgICAgIGNvbnN0IGJTdGFydCA9IG90ZWxUaW1lVG9NcyhiLnN0YXJ0VGltZSk7XG4gICAgICByZXR1cm4gYVN0YXJ0IC0gYlN0YXJ0O1xuICAgIH0pLFxuICBdO1xuXG4gIHJldHVybiBzb3J0ZWRTcGFucy5tYXAoKHNwYW4sIGluZGV4KSA9PiB7XG4gICAgY29uc3QgcGFyZW50U3BhbklkID1cbiAgICAgIGluZGV4ID09PSAwID8gdW5kZWZpbmVkIDogU3RyaW5nKHNvcnRlZFNwYW5zW2luZGV4IC0gMV0uc3BhbklkKTtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uc3BhbixcbiAgICAgIHBhcmVudFNwYW5JZCxcbiAgICB9O1xuICB9KTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUcmFjZVdpdGhNZXRhIHtcbiAgdHJhY2VJZDogc3RyaW5nO1xuICByb290U3BhbklkOiBzdHJpbmc7XG4gIHNwYW5zOiBTcGFuW107XG4gIHJlc291cmNlczogeyBuYW1lOiBzdHJpbmc7IGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfVtdO1xuICAvKiogRHVyYXRpb24gaW4gbXMgZnJvbSB0cmFjZSBzdGFydCB0byB0aGUgbGF0ZXN0IGtub3duIGV2ZW50LiAqL1xuICBrbm93bkR1cmF0aW9uTXM6IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBldmVudHMgbGVmdCBvdXQgb2YgdGhlIHNwYW4gZ2VvbWV0cnkgYXMgcmVwZWF0cy4gRW1wdHkgdW5sZXNzIHRoZVxuICAgKiBjYWxsZXIgdm91Y2hlZCBmb3IgdGhlIGxvZyBiZWluZyBjb21wbGV0ZS4gU2VlXG4gICAqIHtAbGluayBmaW5kRHVwbGljYXRlRXZlbnRJZHN9LlxuICAgKi9cbiAgZHVwbGljYXRlRXZlbnRJZHM6IFJlYWRvbmx5U2V0PHN0cmluZz47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFRyYWNlKFxuICBydW46IFdvcmtmbG93UnVuLFxuICBldmVudHM6IEV2ZW50W10sXG4gIG5vdzogRGF0ZSxcbiAgLyoqXG4gICAqIFdoZXRoZXIgYGV2ZW50c2AgaXMgdGhlIHJ1bidzIHdob2xlIGxvZy4gRGVmYXVsdHMgdG8gZmFsc2UsIHdoaWNoIGJ1aWxkc1xuICAgKiB0aGUgdHJhY2UgZnJvbSBldmVyeSBldmVudDogb24gYSBzdWJzZXQgdGhlcmUgaXMgbm8gd2F5IHRvIHRlbGwgYSByZXBlYXRcbiAgICogZnJvbSB0aGUgb25seSBjb3B5IHRoZSBjYWxsZXIgd2FzIGdpdmVuLCBhbmQgZHJvcHBpbmcgdGhlIHdyb25nIG9uZSBtb3Zlc1xuICAgKiBhIHNwYW4uIFNlZSB7QGxpbmsgZmluZER1cGxpY2F0ZUV2ZW50SWRzfS5cbiAgICovXG4gIHsgaXNDb21wbGV0ZUhpc3RvcnkgPSBmYWxzZSB9OiB7IGlzQ29tcGxldGVIaXN0b3J5PzogYm9vbGVhbiB9ID0ge31cbik6IFRyYWNlV2l0aE1ldGEge1xuICAvLyBTcGFuIGdlb21ldHJ5IGNvbWVzIGZyb20gd2hhdCB0aGUgcnVuIGFjdGVkIG9uLiBBIHJlcGVhdCBvZiBhIGNsYXNzIHRoZVxuICAvLyBsb2cgYWxyZWFkeSByZWNvcmRzIGlzIHJlYWQgcGFzdCBieSBldmVyeSByZXBsYXksIGFuZCBsZXR0aW5nIG9uZSB0aHJvdWdoXG4gIC8vIGhlcmUgd291bGQgc3RyZXRjaCBhIHNwYW4gdG8gd2hlbmV2ZXIgYSBjb25jdXJyZW50IHJlcGxheSBjb21taXR0ZWQgaXQuXG4gIC8vIFNlYWxlZC1wb3NpdGlvbiBub29wcyBhcmUgZXhjbHVkZWQgZm9yIHRoZSBzYW1lIHJlYXNvbiB3aXRoIGEgZGlmZmVyZW50XG4gIC8vIGNsb2NrOiBhIG5vb3AncyBjcmVhdGVkQXQgaXMgdGhlIHNlYWxlcidzIHdhbGwgdGltZSwgd2hpY2ggY2FuIHBvc3RkYXRlXG4gIC8vIGV2ZXJ5IHJlYWwgZXZlbnQgYXJvdW5kIGl0LCBzbyBmZWVkaW5nIGl0IGludG8gc3BhbiBncm91cGluZyBvciB0aGVcbiAgLy8gbGF0ZXN0LWtub3duLXRpbWUgYm91bmQgd291bGQgY2hhcnQgdGhlIHNlYWxlcidzIHNjaGVkdWxlIGluc3RlYWQgb2YgdGhlXG4gIC8vIHJ1bidzLiBUaGUgZXZlbnQgbGlzdHMgc3RpbGwgc2hvdyBib3RoLCBtYXJrZWQgd2l0aCB0aGUgcmVhc29uLlxuICBjb25zdCBkdXBsaWNhdGVFdmVudElkcyA9IGZpbmREdXBsaWNhdGVFdmVudElkcyhldmVudHMsIHtcbiAgICBpc0NvbXBsZXRlSGlzdG9yeSxcbiAgfSk7XG4gIGNvbnN0IGFjdGVkT25FdmVudHMgPSBldmVudHMuZmlsdGVyKFxuICAgIChldmVudCkgPT5cbiAgICAgICFkdXBsaWNhdGVFdmVudElkcy5oYXMoZXZlbnQuZXZlbnRJZCkgJiYgIWlzU2VhbGVkTm9vcEV2ZW50KGV2ZW50KVxuICApO1xuXG4gIGNvbnN0IGdyb3VwZWRFdmVudHMgPSBncm91cEV2ZW50c0J5Q29ycmVsYXRpb24oYWN0ZWRPbkV2ZW50cyk7XG4gIGNvbnN0IGxhdGVzdEtub3duVGltZSA9IGNvbXB1dGVMYXRlc3RLbm93blRpbWUoYWN0ZWRPbkV2ZW50cywgcnVuKTtcbiAgY29uc3QgeyBydW5TcGFuLCBzcGFucyB9ID0gYnVpbGRTcGFucyhcbiAgICBydW4sXG4gICAgZ3JvdXBlZEV2ZW50cyxcbiAgICBub3csXG4gICAgbGF0ZXN0S25vd25UaW1lXG4gICk7XG4gIGNvbnN0IHNvcnRlZENhc2NhZGluZ1NwYW5zID0gY2FzY2FkZVNwYW5zKHJ1blNwYW4sIHNwYW5zKTtcblxuICAvLyBDb21wdXRlIGtub3duIGR1cmF0aW9uIHJlbGF0aXZlIHRvIHRyYWNlIHN0YXJ0XG4gIGNvbnN0IHRyYWNlU3RhcnRNcyA9IG90ZWxUaW1lVG9NcyhydW5TcGFuLnN0YXJ0VGltZSk7XG4gIGNvbnN0IGtub3duRHVyYXRpb25NcyA9IGxhdGVzdEtub3duVGltZS5nZXRUaW1lKCkgLSB0cmFjZVN0YXJ0TXM7XG5cbiAgcmV0dXJuIHtcbiAgICB0cmFjZUlkOiBydW4ucnVuSWQsXG4gICAgcm9vdFNwYW5JZDogcnVuLnJ1bklkLFxuICAgIHNwYW5zOiBzb3J0ZWRDYXNjYWRpbmdTcGFucyxcbiAgICByZXNvdXJjZXM6IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ3dvcmtmbG93JyxcbiAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgICdzZXJ2aWNlLm5hbWUnOiBXT1JLRkxPV19MSUJSQVJZLm5hbWUsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIF0sXG4gICAga25vd25EdXJhdGlvbk1zOiBNYXRoLm1heCgwLCBrbm93bkR1cmF0aW9uTXMpLFxuICAgIGR1cGxpY2F0ZUV2ZW50SWRzLFxuICB9O1xufVxuIl19
170
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2UtYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvdHJhY2UtYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEVBRUwsd0JBQXdCLEVBQ3hCLGVBQWUsRUFDZixlQUFlLEdBRWhCLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUVMLGlCQUFpQixFQUNqQixVQUFVLEVBQ1YsU0FBUyxFQUNULFVBQVUsRUFDVixnQkFBZ0IsRUFDaEIsVUFBVSxHQUNYLE1BQU0sdURBQXVELENBQUM7QUFDL0QsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdEQUFnRCxDQUFDO0FBQzlFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzNELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBR3BEOzs7Ozs7R0FNRztBQUNILE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxDQUFDLEtBQVksRUFBVyxFQUFFLENBQ3ZELENBQUMsS0FBSyxDQUFDLGFBQWE7SUFDcEIsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO1FBQ2hDLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztRQUMxQyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUV2Qzs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxtQkFBbUIsQ0FDakMsTUFBZSxFQUNmLFFBQTRCLEVBQzVCLE1BQTBCO0lBRTFCLElBQUksUUFBUSxLQUFLLEtBQUssRUFBRSxDQUFDO1FBQ3ZCLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBQ0QsSUFBSSxDQUFDLE1BQU07UUFBRSxPQUFPLEVBQUUsQ0FBQztJQUN2QixPQUFPLE1BQU0sQ0FBQyxNQUFNLENB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LENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxDQUNyRSxDQUFDO0lBRUYsTUFBTSxhQUFhLEdBQUcsd0JBQXdCLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDOUQsTUFBTSxlQUFlLEdBQUcsc0JBQXNCLENBQUMsYUFBYSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ25FLE1BQU0sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEdBQUcsVUFBVSxDQUNuQyxHQUFHLEVBQ0gsYUFBYSxFQUNiLEdBQUcsRUFDSCxlQUFlLEVBQ2YsaUJBQWlCLENBQ2xCLENBQUM7SUFDRixNQUFNLG9CQUFvQixHQUFHLFlBQVksQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFFMUQsaURBQWlEO0lBQ2pELE1BQU0sWUFBWSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDckQsTUFBTSxlQUFlLEdBQUcsZUFBZSxDQUFDLE9BQU8sRUFBRSxHQUFHLFlBQVksQ0FBQztJQUVqRSxPQUFPO1FBQ0wsT0FBTyxFQUFFLEdBQUcsQ0FBQyxLQUFLO1FBQ2xCLFVBQVUsRUFBRSxHQUFHLENBQUMsS0FBSztRQUNyQixLQUFLLEVBQUUsb0JBQW9CO1FBQzNCLFNBQVMsRUFBRTtZQUNUO2dCQUNFLElBQUksRUFBRSxVQUFVO2dCQUNoQixVQUFVLEVBQUU7b0JBQ1YsY0FBYyxFQUFFLGdCQUFnQixDQUFDLElBQUk7aUJBQ3RDO2FBQ0Y7U0FDRjtRQUNELGVBQWUsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxlQUFlLENBQUM7UUFDN0MsaUJBQWlCO0tBQ2xCLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBCdWlsZHMgYSBjb21wbGV0ZSB0cmFjZSBmcm9tIGEgV29ya2Zsb3dSdW4gYW5kIGl0cyBFdmVudHMuXG4gKlxuICogVGhpcyBtb2R1bGUgZ3JvdXBzIHJhdyBldmVudHMgYnkgY29ycmVsYXRpb24gSUQgYW5kIGVudGl0eSB0eXBlLFxuICogY29udmVydHMgZWFjaCBncm91cCBpbnRvIGFuIE9wZW5UZWxlbWV0cnktc3R5bGUgU3BhbiwgYW5kIHJldHVybnNcbiAqIGEgZnVsbHktZm9ybWVkIFRyYWNlIHJlYWR5IGZvciB0aGUgdHJhY2Ugdmlld2VyLlxuICovXG5cbmltcG9ydCB7XG4gIHR5cGUgRXZlbnQsXG4gIGlzSG9va0xpZmVjeWNsZUV2ZW50VHlwZSxcbiAgaXNTdGVwRXZlbnRUeXBlLFxuICBpc1dhaXRFdmVudFR5cGUsXG4gIHR5cGUgV29ya2Zsb3dSdW4sXG59IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQge1xuICB0eXBlIEdldFN0ZXBBdHRyaWJ1dGVzLFxuICBnZXRFdmVudFRpbWVzdGFtcCxcbiAgaG9va1RvU3BhbixcbiAgcnVuVG9TcGFuLFxuICBzdGVwVG9TcGFuLFxuICBXT1JLRkxPV19MSUJSQVJZLFxuICB3YWl0VG9TcGFuLFxufSBmcm9tICcuLi9jb21wb25lbnRzL3dvcmtmbG93LXRyYWNlcy90cmFjZS1zcGFuLWNvbnN0cnVjdGlvbic7XG5pbXBvcnQgeyBvdGVsVGltZVRvTXMgfSBmcm9tICcuLi9jb21wb25lbnRzL3dvcmtmbG93LXRyYWNlcy90cmFjZS10aW1lLXV0aWxzJztcbmltcG9ydCB7IGZpbmREdXBsaWNhdGVFdmVudElkcyB9IGZyb20gJy4vZHVwbGljYXRlLWV2ZW50cyc7XG5pbXBvcnQgeyBpc1NlYWxlZE5vb3BFdmVudCB9IGZyb20gJy4vc2VhbGVkLWV2ZW50cyc7XG5pbXBvcnQgdHlwZSB7IFNwYW4gfSBmcm9tICcuL3RyYWNlLXR5cGVzJztcblxuLyoqXG4gKiBFdmVudHMgdGhhdCBiZWxvbmcgdG8gdGhlIHJ1biByb290IHNwYW4gcmF0aGVyIHRoYW4gYSBjaGlsZCBlbnRpdHkgc3Bhbi5cbiAqIE1pcnJvcnMgdGhlIGZhbGx0aHJvdWdoIGxvZ2ljIGluIHtAbGluayBncm91cEV2ZW50c0J5Q29ycmVsYXRpb259OiBldmVudHNcbiAqIHdpdGhvdXQgYSBjb3JyZWxhdGlvbklkIChydW4gbGlmZWN5Y2xlKSBwbHVzIGNvcnJlbGF0ZWQgZXZlbnRzIHRoYXQgYXJlbid0XG4gKiBzdGVwL3RpbWVyL2hvb2sgZXZlbnRzIChlLmcuIGBhdHRyX3NldGAsIHdob3NlIGNvcnJlbGF0aW9uSWQgaXMgYSBkZWR1cFxuICogdG9rZW4gcmF0aGVyIHRoYW4gYSBjaGlsZCBlbnRpdHkgSUQpLlxuICovXG5leHBvcnQgY29uc3QgaXNSdW5MZXZlbEV2ZW50ID0gKGV2ZW50OiBFdmVudCk6IGJvb2xlYW4gPT5cbiAgIWV2ZW50LmNvcnJlbGF0aW9uSWQgfHxcbiAgKCFpc1dhaXRFdmVudFR5cGUoZXZlbnQuZXZlbnRUeXBlKSAmJlxuICAgICFpc0hvb2tMaWZlY3ljbGVFdmVudFR5cGUoZXZlbnQuZXZlbnRUeXBlKSAmJlxuICAgICFpc1N0ZXBFdmVudFR5cGUoZXZlbnQuZXZlbnRUeXBlKSk7XG5cbi8qKlxuICogRmlsdGVyIHRoZSByYXcgZXZlbnQgbGlzdCBkb3duIHRvIHRoZSBldmVudHMgZm9yIGEgc2VsZWN0ZWQgc3Bhbi5cbiAqIEZvciB0aGUgcnVuIHJvb3Qgc3BhbiB0aGlzIHJldHVybnMgcnVuLWxldmVsIGV2ZW50cyAoc2VlXG4gKiB7QGxpbmsgaXNSdW5MZXZlbEV2ZW50fSk7IGZvciBjaGlsZCBzcGFucyBpdCByZXR1cm5zIHRoZSBldmVudHNcbiAqIGNvcnJlbGF0ZWQgdG8gdGhhdCBzcGFuJ3MgSUQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaWx0ZXJTcGFuUmF3RXZlbnRzKFxuICBldmVudHM6IEV2ZW50W10sXG4gIHJlc291cmNlOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gIHNwYW5JZDogc3RyaW5nIHwgdW5kZWZpbmVkXG4pOiBFdmVudFtdIHtcbiAgaWYgKHJlc291cmNlID09PSAncnVuJykge1xuICAgIHJldHVybiBldmVudHMuZmlsdGVyKGlzUnVuTGV2ZWxFdmVudCk7XG4gIH1cbiAgaWYgKCFzcGFuSWQpIHJldHVybiBbXTtcbiAgcmV0dXJuIGV2ZW50cy5maWx0ZXIoKGUpID0+IGUuY29ycmVsYXRpb25JZCA9PT0gc3BhbklkKTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBFdmVudCBncm91cGluZ1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmV4cG9ydCB0eXBlIEdyb3VwZWRFdmVudHMgPSB7XG4gIGV2ZW50c0J5U3RlcElkOiBNYXA8c3RyaW5nLCBFdmVudFtdPjtcbiAgcnVuTGV2ZWxFdmVudHM6IEV2ZW50W107XG4gIHRpbWVyRXZlbnRzOiBNYXA8c3RyaW5nLCBFdmVudFtdPjtcbiAgaG9va0V2ZW50czogTWFwPHN0cmluZywgRXZlbnRbXT47XG59O1xuXG5mdW5jdGlvbiBwdXNoRXZlbnQoXG4gIG1hcDogTWFwPHN0cmluZywgRXZlbnRbXT4sXG4gIGNvcnJlbGF0aW9uSWQ6IHN0cmluZyxcbiAgZXZlbnQ6IEV2ZW50XG4pIHtcbiAgY29uc3QgZXhpc3RpbmcgPSBtYXAuZ2V0KGNvcnJlbGF0aW9uSWQpO1xuICBpZiAoZXhpc3RpbmcpIHtcbiAgICBleGlzdGluZy5wdXNoKGV2ZW50KTtcbiAgICByZXR1cm47XG4gIH1cbiAgbWFwLnNldChjb3JyZWxhdGlvbklkLCBbZXZlbnRdKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdyb3VwRXZlbnRzQnlDb3JyZWxhdGlvbihldmVudHM6IEV2ZW50W10pOiBHcm91cGVkRXZlbnRzIHtcbiAgY29uc3QgZXZlbnRzQnlTdGVwSWQgPSBuZXcgTWFwPHN0cmluZywgRXZlbnRbXT4oKTtcbiAgY29uc3QgcnVuTGV2ZWxFdmVudHM6IEV2ZW50W10gPSBbXTtcbiAgY29uc3QgdGltZXJFdmVudHMgPSBuZXcgTWFwPHN0cmluZywgRXZlbnRbXT4oKTtcbiAgY29uc3QgaG9va0V2ZW50cyA9IG5ldyBNYXA8c3RyaW5nLCBFdmVudFtdPigpO1xuXG4gIGZvciAoY29uc3QgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgY29uc3QgY29ycmVsYXRpb25JZCA9IGV2ZW50LmNvcnJlbGF0aW9uSWQ7XG4gICAgaWYgKCFjb3JyZWxhdGlvbklkKSB7XG4gICAgICBydW5MZXZlbEV2ZW50cy5wdXNoKGV2ZW50KTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChpc1dhaXRFdmVudFR5cGUoZXZlbnQuZXZlbnRUeXBlKSkge1xuICAgICAgcHVzaEV2ZW50KHRpbWVyRXZlbnRzLCBjb3JyZWxhdGlvbklkLCBldmVudCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoaXNIb29rTGlmZWN5Y2xlRXZlbnRUeXBlKGV2ZW50LmV2ZW50VHlwZSkpIHtcbiAgICAgIHB1c2hFdmVudChob29rRXZlbnRzLCBjb3JyZWxhdGlvbklkLCBldmVudCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoaXNTdGVwRXZlbnRUeXBlKGV2ZW50LmV2ZW50VHlwZSkpIHtcbiAgICAgIHB1c2hFdmVudChldmVudHNCeVN0ZXBJZCwgY29ycmVsYXRpb25JZCwgZXZlbnQpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgcnVuTGV2ZWxFdmVudHMucHVzaChldmVudCk7XG4gIH1cblxuICByZXR1cm4geyBldmVudHNCeVN0ZXBJZCwgcnVuTGV2ZWxFdmVudHMsIHRpbWVyRXZlbnRzLCBob29rRXZlbnRzIH07XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gVHJhY2UgY29uc3RydWN0aW9uXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLyoqXG4gKiBDb21wdXRlcyB0aGUgbGF0ZXN0IGtub3duIGV2ZW50IHRpbWUgZnJvbSB0aGUgZXZlbnRzIGxpc3QuXG4gKiBBY3RpdmUgKGluLXByb2dyZXNzKSBjaGlsZCBzcGFucyBhcmUgY2FwcGVkIGF0IHRoaXMgdGltZSBpbnN0ZWFkIG9mIGBub3dgLFxuICogc28gdGhleSBvbmx5IGV4dGVuZCBhcyBmYXIgYXMgb3VyIGRhdGEgZ29lcy5cbiAqL1xuZnVuY3Rpb24gY29tcHV0ZUxhdGVzdEtub3duVGltZShldmVudHM6IEV2ZW50W10sIHJ1bjogV29ya2Zsb3dSdW4pOiBEYXRlIHtcbiAgbGV0IGxhdGVzdCA9IG5ldyBEYXRlKHJ1bi5jcmVhdGVkQXQpLmdldFRpbWUoKTtcbiAgZm9yIChjb25zdCBldmVudCBvZiBldmVudHMpIHtcbiAgICBjb25zdCB0ID0gKGdldEV2ZW50VGltZXN0YW1wKGV2ZW50KSA/PyBuZXcgRGF0ZShldmVudC5jcmVhdGVkQXQpKS5nZXRUaW1lKCk7XG4gICAgaWYgKHQgPiBsYXRlc3QpIGxhdGVzdCA9IHQ7XG4gIH1cbiAgcmV0dXJuIG5ldyBEYXRlKGxhdGVzdCk7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkU3BhbnMoXG4gIHJ1bjogV29ya2Zsb3dSdW4sXG4gIGdyb3VwZWRFdmVudHM6IEdyb3VwZWRFdmVudHMsXG4gIG5vdzogRGF0ZSxcbiAgbGF0ZXN0S25vd25UaW1lOiBEYXRlLFxuICBnZXRTdGVwQXR0cmlidXRlcz86IEdldFN0ZXBBdHRyaWJ1dGVzXG4pIHtcbiAgLy8gQWN0aXZlIGNoaWxkIHNwYW5zIGNhcCBhdCBsYXRlc3RLbm93blRpbWUgc28gdGhleSBkb24ndCBleHRlbmQgaW50b1xuICAvLyB1bmtub3duIHRlcnJpdG9yeS4gRXZlbiB3aGVuIHRoZSBydW4gaXMgY29tcGxldGVkLCB3ZSBtYXkgbm90IGhhdmUgbG9hZGVkXG4gIC8vIGFsbCBldmVudHMgeWV0LCBzbyBhbHdheXMgdXNlIHRoZSBsYXRlc3QgZXZlbnQgd2UndmUgYWN0dWFsbHkgc2Vlbi5cbiAgY29uc3QgY2hpbGRNYXhFbmQgPSBsYXRlc3RLbm93blRpbWU7XG4gIGNvbnN0IHJ1bk1heEVuZCA9IHJ1bi5jb21wbGV0ZWRBdCA/PyBub3c7XG5cbiAgY29uc3Qgc3RlcFNwYW5zID0gQXJyYXkuZnJvbShncm91cGVkRXZlbnRzLmV2ZW50c0J5U3RlcElkLnZhbHVlcygpKVxuICAgIC5tYXAoKGV2ZW50cykgPT4gc3RlcFRvU3BhbihldmVudHMsIGNoaWxkTWF4RW5kLCBnZXRTdGVwQXR0cmlidXRlcykpXG4gICAgLmZpbHRlcigoc3Bhbik6IHNwYW4gaXMgU3BhbiA9PiBzcGFuICE9PSBudWxsKTtcblxuICBjb25zdCBob29rU3BhbnMgPSBBcnJheS5mcm9tKGdyb3VwZWRFdmVudHMuaG9va0V2ZW50cy52YWx1ZXMoKSlcbiAgICAubWFwKChldmVudHMpID0+IGhvb2tUb1NwYW4oZXZlbnRzLCBjaGlsZE1heEVuZCkpXG4gICAgLmZpbHRlcigoc3Bhbik6IHNwYW4gaXMgU3BhbiA9PiBzcGFuICE9PSBudWxsKTtcblxuICBjb25zdCB3YWl0U3BhbnMgPSBBcnJheS5mcm9tKGdyb3VwZWRFdmVudHMudGltZXJFdmVudHMudmFsdWVzKCkpXG4gICAgLm1hcCgoZXZlbnRzKSA9PiB3YWl0VG9TcGFuKGV2ZW50cywgY2hpbGRNYXhFbmQsIHJ1bk1heEVuZCkpXG4gICAgLmZpbHRlcigoc3Bhbik6IHNwYW4gaXMgU3BhbiA9PiBzcGFuICE9PSBudWxsKTtcblxuICByZXR1cm4ge1xuICAgIHJ1blNwYW46IHJ1blRvU3BhbihydW4sIGdyb3VwZWRFdmVudHMucnVuTGV2ZWxFdmVudHMsIG5vdyksXG4gICAgc3BhbnM6IFsuLi5zdGVwU3BhbnMsIC4uLmhvb2tTcGFucywgLi4ud2FpdFNwYW5zXSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gY2FzY2FkZVNwYW5zKHJ1blNwYW46IFNwYW4sIHNwYW5zOiBTcGFuW10pIHtcbiAgY29uc3Qgc29ydGVkU3BhbnMgPSBbXG4gICAgcnVuU3BhbixcbiAgICAuLi5zcGFucy5zbGljZSgpLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgIGNvbnN0IGFTdGFydCA9IG90ZWxUaW1lVG9NcyhhLnN0YXJ0VGltZSk7XG4gICAgICBjb25zdCBiU3RhcnQgPSBvdGVsVGltZVRvTXMoYi5zdGFydFRpbWUpO1xuICAgICAgcmV0dXJuIGFTdGFydCAtIGJTdGFydDtcbiAgICB9KSxcbiAgXTtcblxuICByZXR1cm4gc29ydGVkU3BhbnMubWFwKChzcGFuLCBpbmRleCkgPT4ge1xuICAgIGNvbnN0IHBhcmVudFNwYW5JZCA9XG4gICAgICBpbmRleCA9PT0gMCA/IHVuZGVmaW5lZCA6IFN0cmluZyhzb3J0ZWRTcGFuc1tpbmRleCAtIDFdLnNwYW5JZCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnNwYW4sXG4gICAgICBwYXJlbnRTcGFuSWQsXG4gICAgfTtcbiAgfSk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhY2VXaXRoTWV0YSB7XG4gIHRyYWNlSWQ6IHN0cmluZztcbiAgcm9vdFNwYW5JZDogc3RyaW5nO1xuICBzcGFuczogU3BhbltdO1xuICByZXNvdXJjZXM6IHsgbmFtZTogc3RyaW5nOyBhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IH1bXTtcbiAgLyoqIER1cmF0aW9uIGluIG1zIGZyb20gdHJhY2Ugc3RhcnQgdG8gdGhlIGxhdGVzdCBrbm93biBldmVudC4gKi9cbiAga25vd25EdXJhdGlvbk1zOiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgZXZlbnRzIGxlZnQgb3V0IG9mIHRoZSBzcGFuIGdlb21ldHJ5IGFzIHJlcGVhdHMuIEVtcHR5IHVubGVzcyB0aGVcbiAgICogY2FsbGVyIHZvdWNoZWQgZm9yIHRoZSBsb2cgYmVpbmcgY29tcGxldGUuIFNlZVxuICAgKiB7QGxpbmsgZmluZER1cGxpY2F0ZUV2ZW50SWRzfS5cbiAgICovXG4gIGR1cGxpY2F0ZUV2ZW50SWRzOiBSZWFkb25seVNldDxzdHJpbmc+O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRUcmFjZShcbiAgcnVuOiBXb3JrZmxvd1J1bixcbiAgZXZlbnRzOiBFdmVudFtdLFxuICBub3c6IERhdGUsXG4gIC8qKlxuICAgKiBXaGV0aGVyIGBldmVudHNgIGlzIHRoZSBydW4ncyB3aG9sZSBsb2cuIERlZmF1bHRzIHRvIGZhbHNlLCB3aGljaCBidWlsZHNcbiAgICogdGhlIHRyYWNlIGZyb20gZXZlcnkgZXZlbnQ6IG9uIGEgc3Vic2V0IHRoZXJlIGlzIG5vIHdheSB0byB0ZWxsIGEgcmVwZWF0XG4gICAqIGZyb20gdGhlIG9ubHkgY29weSB0aGUgY2FsbGVyIHdhcyBnaXZlbiwgYW5kIGRyb3BwaW5nIHRoZSB3cm9uZyBvbmUgbW92ZXNcbiAgICogYSBzcGFuLiBTZWUge0BsaW5rIGZpbmREdXBsaWNhdGVFdmVudElkc30uXG4gICAqL1xuICB7XG4gICAgaXNDb21wbGV0ZUhpc3RvcnkgPSBmYWxzZSxcbiAgICBnZXRTdGVwQXR0cmlidXRlcyxcbiAgfToge1xuICAgIGlzQ29tcGxldGVIaXN0b3J5PzogYm9vbGVhbjtcbiAgICBnZXRTdGVwQXR0cmlidXRlcz86IEdldFN0ZXBBdHRyaWJ1dGVzO1xuICB9ID0ge31cbik6IFRyYWNlV2l0aE1ldGEge1xuICAvLyBTcGFuIGdlb21ldHJ5IGNvbWVzIGZyb20gd2hhdCB0aGUgcnVuIGFjdGVkIG9uLiBBIHJlcGVhdCBvZiBhIGNsYXNzIHRoZVxuICAvLyBsb2cgYWxyZWFkeSByZWNvcmRzIGlzIHJlYWQgcGFzdCBieSBldmVyeSByZXBsYXksIGFuZCBsZXR0aW5nIG9uZSB0aHJvdWdoXG4gIC8vIGhlcmUgd291bGQgc3RyZXRjaCBhIHNwYW4gdG8gd2hlbmV2ZXIgYSBjb25jdXJyZW50IHJlcGxheSBjb21taXR0ZWQgaXQuXG4gIC8vIFNlYWxlZC1wb3NpdGlvbiBub29wcyBhcmUgZXhjbHVkZWQgZm9yIHRoZSBzYW1lIHJlYXNvbiB3aXRoIGEgZGlmZmVyZW50XG4gIC8vIGNsb2NrOiBhIG5vb3AncyBjcmVhdGVkQXQgaXMgdGhlIHNlYWxlcidzIHdhbGwgdGltZSwgd2hpY2ggY2FuIHBvc3RkYXRlXG4gIC8vIGV2ZXJ5IHJlYWwgZXZlbnQgYXJvdW5kIGl0LCBzbyBmZWVkaW5nIGl0IGludG8gc3BhbiBncm91cGluZyBvciB0aGVcbiAgLy8gbGF0ZXN0LWtub3duLXRpbWUgYm91bmQgd291bGQgY2hhcnQgdGhlIHNlYWxlcidzIHNjaGVkdWxlIGluc3RlYWQgb2YgdGhlXG4gIC8vIHJ1bidzLiBUaGUgZXZlbnQgbGlzdHMgc3RpbGwgc2hvdyBib3RoLCBtYXJrZWQgd2l0aCB0aGUgcmVhc29uLlxuICBjb25zdCBkdXBsaWNhdGVFdmVudElkcyA9IGZpbmREdXBsaWNhdGVFdmVudElkcyhldmVudHMsIHtcbiAgICBpc0NvbXBsZXRlSGlzdG9yeSxcbiAgfSk7XG4gIGNvbnN0IGFjdGVkT25FdmVudHMgPSBldmVudHMuZmlsdGVyKFxuICAgIChldmVudCkgPT5cbiAgICAgICFkdXBsaWNhdGVFdmVudElkcy5oYXMoZXZlbnQuZXZlbnRJZCkgJiYgIWlzU2VhbGVkTm9vcEV2ZW50KGV2ZW50KVxuICApO1xuXG4gIGNvbnN0IGdyb3VwZWRFdmVudHMgPSBncm91cEV2ZW50c0J5Q29ycmVsYXRpb24oYWN0ZWRPbkV2ZW50cyk7XG4gIGNvbnN0IGxhdGVzdEtub3duVGltZSA9IGNvbXB1dGVMYXRlc3RLbm93blRpbWUoYWN0ZWRPbkV2ZW50cywgcnVuKTtcbiAgY29uc3QgeyBydW5TcGFuLCBzcGFucyB9ID0gYnVpbGRTcGFucyhcbiAgICBydW4sXG4gICAgZ3JvdXBlZEV2ZW50cyxcbiAgICBub3csXG4gICAgbGF0ZXN0S25vd25UaW1lLFxuICAgIGdldFN0ZXBBdHRyaWJ1dGVzXG4gICk7XG4gIGNvbnN0IHNvcnRlZENhc2NhZGluZ1NwYW5zID0gY2FzY2FkZVNwYW5zKHJ1blNwYW4sIHNwYW5zKTtcblxuICAvLyBDb21wdXRlIGtub3duIGR1cmF0aW9uIHJlbGF0aXZlIHRvIHRyYWNlIHN0YXJ0XG4gIGNvbnN0IHRyYWNlU3RhcnRNcyA9IG90ZWxUaW1lVG9NcyhydW5TcGFuLnN0YXJ0VGltZSk7XG4gIGNvbnN0IGtub3duRHVyYXRpb25NcyA9IGxhdGVzdEtub3duVGltZS5nZXRUaW1lKCkgLSB0cmFjZVN0YXJ0TXM7XG5cbiAgcmV0dXJuIHtcbiAgICB0cmFjZUlkOiBydW4ucnVuSWQsXG4gICAgcm9vdFNwYW5JZDogcnVuLnJ1bklkLFxuICAgIHNwYW5zOiBzb3J0ZWRDYXNjYWRpbmdTcGFucyxcbiAgICByZXNvdXJjZXM6IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ3dvcmtmbG93JyxcbiAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgICdzZXJ2aWNlLm5hbWUnOiBXT1JLRkxPV19MSUJSQVJZLm5hbWUsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIF0sXG4gICAga25vd25EdXJhdGlvbk1zOiBNYXRoLm1heCgwLCBrbm93bkR1cmF0aW9uTXMpLFxuICAgIGR1cGxpY2F0ZUV2ZW50SWRzLFxuICB9O1xufVxuIl19
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@workflow/web-shared",
3
3
  "description": "Shared components for Workflow Observability UI",
4
- "version": "5.0.0-beta.46",
4
+ "version": "5.0.0-beta.48",
5
5
  "private": false,
6
6
  "files": [
7
7
  "dist",
@@ -42,6 +42,9 @@
42
42
  "@radix-ui/react-tooltip": "1.2.8",
43
43
  "@tailwindcss/postcss": "4",
44
44
  "@tootallnate/zstd-wasm": "0.0.2",
45
+ "@workflow/core": "5.0.0-beta.48",
46
+ "@workflow/utils": "5.0.0-beta.10",
47
+ "@workflow/world": "5.0.0-beta.33",
45
48
  "class-variance-authority": "0.7.1",
46
49
  "clsx": "2.1.1",
47
50
  "date-fns": "4.1.0",
@@ -54,21 +57,18 @@
54
57
  "sonner": "2.0.7",
55
58
  "streamdown": "2.3.0",
56
59
  "tailwind-merge": "3.5.0",
57
- "tailwindcss": "4",
58
- "@workflow/core": "5.0.0-beta.46",
59
- "@workflow/utils": "5.0.0-beta.9",
60
- "@workflow/world": "5.0.0-beta.31"
60
+ "tailwindcss": "4"
61
61
  },
62
62
  "devDependencies": {
63
63
  "@biomejs/biome": "^2.4.4",
64
64
  "@types/node": "22.19.0",
65
65
  "@types/react": "19",
66
66
  "@types/react-dom": "19",
67
+ "@workflow/errors": "5.0.0-beta.20",
68
+ "@workflow/tsconfig": "5.0.0-beta.0",
67
69
  "ai": "6.0.116",
68
70
  "typescript": "^6.0.3",
69
- "vitest": "^4.1.10",
70
- "@workflow/errors": "5.0.0-beta.18",
71
- "@workflow/tsconfig": "5.0.0-beta.0"
71
+ "vitest": "^4.1.10"
72
72
  },
73
73
  "scripts": {
74
74
  "build": "tsc && cp src/components/trace-viewer/components/*.module.css dist/components/trace-viewer/components/ && cp src/styles.css dist/styles.css",
@@ -1007,10 +1007,10 @@ export function EventRow({
1007
1007
  }, []);
1008
1008
 
1009
1009
  // When encryption key changes and this event was previously loaded,
1010
- // re-load to get decrypted data
1010
+ // re-load to get decrypted data. Keep the encrypted value visible until the
1011
+ // refreshed data arrives so the payload does not flash empty while decrypting.
1011
1012
  useEffect(() => {
1012
1013
  if (encryptionKey && hasAttemptedLoad && onLoadEventData) {
1013
- setLoadedEventData(null);
1014
1014
  setHasAttemptedLoad(false);
1015
1015
  onLoadEventData(event)
1016
1016
  .then((data) => {
@@ -0,0 +1,54 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useState } from 'react';
4
+
5
+ function isAltModifierKey(key: string): boolean {
6
+ return key === 'Alt' || key === 'AltGraph';
7
+ }
8
+
9
+ function isTypingTarget(target: EventTarget | null): boolean {
10
+ return (
11
+ target instanceof HTMLInputElement ||
12
+ target instanceof HTMLTextAreaElement ||
13
+ (target instanceof HTMLElement && target.isContentEditable)
14
+ );
15
+ }
16
+
17
+ /**
18
+ * Whether Alt/Option is held, for the timeline delta overlay.
19
+ *
20
+ * preventDefault stops Chrome from taking the menu bar (which kills hover).
21
+ * Capture-phase keys; pointermove recovers if keydown was missed; blur
22
+ * clears after Alt+Tab.
23
+ */
24
+ export function useAltHeld(): { altHeld: boolean } {
25
+ const [altHeld, setAltHeld] = useState(false);
26
+
27
+ useEffect(() => {
28
+ const onKeyDown = (e: KeyboardEvent): void => {
29
+ if (!isAltModifierKey(e.key)) return;
30
+ if (!isTypingTarget(e.target)) {
31
+ e.preventDefault();
32
+ }
33
+ setAltHeld(true);
34
+ };
35
+ const onKeyUp = (e: KeyboardEvent): void => {
36
+ if (isAltModifierKey(e.key)) setAltHeld(false);
37
+ };
38
+ const onBlur = (): void => setAltHeld(false);
39
+ const onPointerMove = (e: PointerEvent): void => setAltHeld(e.altKey);
40
+
41
+ window.addEventListener('keydown', onKeyDown, true);
42
+ window.addEventListener('keyup', onKeyUp, true);
43
+ window.addEventListener('blur', onBlur);
44
+ window.addEventListener('pointermove', onPointerMove, true);
45
+ return () => {
46
+ window.removeEventListener('keydown', onKeyDown, true);
47
+ window.removeEventListener('keyup', onKeyUp, true);
48
+ window.removeEventListener('blur', onBlur);
49
+ window.removeEventListener('pointermove', onPointerMove, true);
50
+ };
51
+ }, []);
52
+
53
+ return { altHeld };
54
+ }
@@ -27,6 +27,7 @@ import {
27
27
  type TimelineHover,
28
28
  } from './components/timeline';
29
29
  import { TraceShortcutHelper } from './components/trace-shortcut-helper';
30
+ import { useAltHeld } from './components/use-alt-held';
30
31
  import { ROW_HEIGHT_PX, scrollRowIntoView } from './components/use-row-window';
31
32
  import { ActiveSpanProvider, useActiveSpan } from './context';
32
33
  import { searchSpans } from './search';
@@ -370,29 +371,16 @@ function TraceViewerContent({
370
371
  [setActiveSpan, scrollSpanIntoView, cancelPendingZoom, focusViewportOnSpan]
371
372
  );
372
373
 
373
- const [altHeld, setAltHeld] = useState(false);
374
+ const { altHeld } = useAltHeld();
374
375
 
375
376
  useEffect(() => {
376
377
  const onKeyDown = (e: KeyboardEvent): void => {
377
378
  if (e.key === 'Escape') {
378
379
  handleClearActiveSpan();
379
- } else if (e.key === 'Alt') {
380
- setAltHeld(true);
381
380
  }
382
381
  };
383
- const onKeyUp = (e: KeyboardEvent): void => {
384
- if (e.key === 'Alt') setAltHeld(false);
385
- };
386
- const onBlur = (): void => setAltHeld(false);
387
-
388
382
  window.addEventListener('keydown', onKeyDown);
389
- window.addEventListener('keyup', onKeyUp);
390
- window.addEventListener('blur', onBlur);
391
- return () => {
392
- window.removeEventListener('keydown', onKeyDown);
393
- window.removeEventListener('keyup', onKeyUp);
394
- window.removeEventListener('blur', onBlur);
395
- };
383
+ return () => window.removeEventListener('keydown', onKeyDown);
396
384
  }, [handleClearActiveSpan]);
397
385
 
398
386
  const timelineRef = useRef<HTMLDivElement>(null);
@@ -8,6 +8,7 @@ import {
8
8
  } from './sidebar/sidebar-data-context';
9
9
  import { TraceViewerSkeleton } from './trace-viewer/components/trace-viewer-skeleton';
10
10
  import { TraceViewer as TraceViewerComponent } from './trace-viewer/trace-viewer';
11
+ import type { GetStepAttributes } from './workflow-traces/trace-span-construction';
11
12
 
12
13
  const TraceViewer = ({
13
14
  run,
@@ -17,6 +18,7 @@ const TraceViewer = ({
17
18
  hasMore,
18
19
  isLoadingMore,
19
20
  loading = false,
21
+ getStepAttributes,
20
22
  }: {
21
23
  run: WorkflowRun;
22
24
  events: Event[];
@@ -25,6 +27,8 @@ const TraceViewer = ({
25
27
  hasMore?: boolean;
26
28
  isLoadingMore?: boolean;
27
29
  loading?: boolean;
30
+ /** Adds product-specific attributes to event-derived step span data. */
31
+ getStepAttributes?: GetStepAttributes;
28
32
  }) => {
29
33
  const trace: TraceWithMeta | undefined = useMemo(() => {
30
34
  if (!run?.runId) {
@@ -35,9 +39,10 @@ const TraceViewer = ({
35
39
  // repeats with the whole log in hand.
36
40
  return buildTrace(run, events, new Date(), {
37
41
  isCompleteHistory: !hasMore,
42
+ getStepAttributes,
38
43
  });
39
44
  // eslint-disable-next-line react-hooks/exhaustive-deps -- `new Date()` is intentionally not a dep
40
- }, [run, events, hasMore]);
45
+ }, [run, events, hasMore, getStepAttributes]);
41
46
 
42
47
  // The sidebar shows one entity's slice of the log, so it takes the trace's
43
48
  // answer rather than recomputing one from the slice.
@@ -344,7 +344,7 @@ function BytesDisplayValue({ display }: { display: BytesDisplay }) {
344
344
  // Tree renderer
345
345
  // ---------------------------------------------------------------------------
346
346
 
347
- type Entry = [field: string | undefined, value: unknown];
347
+ type Entry = [field: string | undefined, value: unknown, key?: string | number];
348
348
 
349
349
  interface NodeContext {
350
350
  level: number;
@@ -357,10 +357,51 @@ function formatField(field: string): string {
357
357
  return field === '' ? '""' : field;
358
358
  }
359
359
 
360
+ function isGenericIterable(
361
+ value: unknown
362
+ ): value is object & Iterable<unknown> {
363
+ if (
364
+ value === null ||
365
+ (typeof value !== 'object' && typeof value !== 'function') ||
366
+ Array.isArray(value) ||
367
+ value instanceof Map ||
368
+ value instanceof Set
369
+ ) {
370
+ return false;
371
+ }
372
+ return (
373
+ typeof (value as { [Symbol.iterator]?: unknown })[Symbol.iterator] ===
374
+ 'function'
375
+ );
376
+ }
377
+
378
+ function isEntryIterable(
379
+ value: object & Iterable<unknown>
380
+ ): value is object & Iterable<unknown> & { entries(): Iterable<unknown> } {
381
+ return typeof (value as { entries?: unknown }).entries === 'function';
382
+ }
383
+
384
+ function collectEntries(
385
+ iterable: Iterable<unknown>,
386
+ asPairs: boolean
387
+ ): Entry[] {
388
+ return Array.from(iterable, (item, index) => {
389
+ if (asPairs && Array.isArray(item) && item.length >= 2) {
390
+ return [String(item[0]), collapseRefs(item[1]), index];
391
+ }
392
+ return [undefined, collapseRefs(item), index];
393
+ });
394
+ }
395
+
396
+ function isSelfIterableIterator(value: object & Iterable<unknown>): boolean {
397
+ return Object.is(value[Symbol.iterator](), value);
398
+ }
399
+
360
400
  /**
361
- * Describe an object/array/map/set as an expandable container. Returns null for
362
- * values that should render as a primitive. `prefix` carries a class name shown
363
- * before the opening bracket (Map/Set and named class instances).
401
+ * Describe an object/array/iterable as an expandable container. Returns null
402
+ * for values that should render as a primitive. `prefix` carries a class name
403
+ * shown before the opening bracket (Map/Set, generic iterables, and named class
404
+ * instances).
364
405
  */
365
406
  function describeContainer(
366
407
  value: unknown
@@ -391,6 +432,25 @@ function describeContainer(
391
432
  prefix: 'Set',
392
433
  };
393
434
  }
435
+ if (isGenericIterable(value)) {
436
+ const name = (value as { constructor?: { name?: string } }).constructor
437
+ ?.name;
438
+ const prefix = name && name !== 'Object' ? name : undefined;
439
+ if (isEntryIterable(value)) {
440
+ return {
441
+ entries: collectEntries(value.entries(), true),
442
+ open: '{',
443
+ close: '}',
444
+ prefix,
445
+ };
446
+ }
447
+ return {
448
+ entries: collectEntries(value, false),
449
+ open: '[',
450
+ close: ']',
451
+ prefix,
452
+ };
453
+ }
394
454
  if (value !== null && typeof value === 'object') {
395
455
  const name = (value as { constructor?: { name?: string } }).constructor
396
456
  ?.name;
@@ -616,9 +676,9 @@ function ExpandableContainer({
616
676
  {expanded ? (
617
677
  // biome-ignore lint/a11y/useSemanticElements: ARIA tree group is the correct role here
618
678
  <ul id={contentsId} className={CLS.childFields} role="group">
619
- {entries.map(([childField, childValue], index) => (
679
+ {entries.map(([childField, childValue, entryKey], index) => (
620
680
  <DataRender
621
- key={childField ?? index}
681
+ key={entryKey ?? childField ?? index}
622
682
  field={childField}
623
683
  value={childValue}
624
684
  isLast={index === lastIndex}
@@ -820,8 +880,8 @@ function makeBytesDisplay(display: FormattedStreamChunkDisplay): unknown {
820
880
  * non-expandable versions so the renderer doesn't show their internals.
821
881
  * Only recurses into plain objects and arrays to avoid stripping class
822
882
  * instances (Date, Error, URL, Headers, etc.) that have their own rendering.
823
- * Map and Set containers are preserved while their contents are prepared for
824
- * display.
883
+ * Map and Set contents are prepared here; other iterable contents are prepared
884
+ * when the renderer traverses them.
825
885
  *
826
886
  * Exported for testing the typed-array detection path used by hydrated
827
887
  * AI agent stream chunks (e.g. `{ delta: new Uint8Array(...) }`).
@@ -962,7 +1022,28 @@ function isSameBytesDisplay(a: BytesDisplay, b: BytesDisplay): boolean {
962
1022
  );
963
1023
  }
964
1024
 
965
- function isDeepEqual(a: unknown, b: unknown, seen = new WeakMap()): boolean {
1025
+ function haveSameIterableValues(
1026
+ a: Iterable<unknown>,
1027
+ b: Iterable<unknown>,
1028
+ seen: WeakMap<object, object>
1029
+ ): boolean {
1030
+ const aIterator = a[Symbol.iterator]();
1031
+ const bIterator = b[Symbol.iterator]();
1032
+ while (true) {
1033
+ const aResult = aIterator.next();
1034
+ const bResult = bIterator.next();
1035
+ if (aResult.done || bResult.done) {
1036
+ return aResult.done === bResult.done;
1037
+ }
1038
+ if (!isDeepEqual(aResult.value, bResult.value, seen)) return false;
1039
+ }
1040
+ }
1041
+
1042
+ export function isDeepEqual(
1043
+ a: unknown,
1044
+ b: unknown,
1045
+ seen = new WeakMap()
1046
+ ): boolean {
966
1047
  if (Object.is(a, b)) return true;
967
1048
 
968
1049
  if (isBytesDisplay(a) || isBytesDisplay(b)) {
@@ -977,6 +1058,21 @@ function isDeepEqual(a: unknown, b: unknown, seen = new WeakMap()): boolean {
977
1058
  return a.source === b.source && a.flags === b.flags;
978
1059
  }
979
1060
 
1061
+ if (isGenericIterable(a) || isGenericIterable(b)) {
1062
+ if (!isGenericIterable(a) || !isGenericIterable(b)) return false;
1063
+ if (Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) return false;
1064
+ if (isSelfIterableIterator(a) || isSelfIterableIterator(b)) return false;
1065
+ if (seen.get(a) === b) return true;
1066
+ seen.set(a, b);
1067
+ const aHasEntries = isEntryIterable(a);
1068
+ const bHasEntries = isEntryIterable(b);
1069
+ if (aHasEntries !== bHasEntries) return false;
1070
+ if (aHasEntries && bHasEntries) {
1071
+ return haveSameIterableValues(a.entries(), b.entries(), seen);
1072
+ }
1073
+ return haveSameIterableValues(a, b, seen);
1074
+ }
1075
+
980
1076
  if (a instanceof Map && b instanceof Map) {
981
1077
  if (a.size !== b.size) return false;
982
1078
  for (const [key, value] of a.entries()) {
@@ -150,6 +150,10 @@ export function waitToSpan(
150
150
  };
151
151
  }
152
152
 
153
+ export type GetStepAttributes = (
154
+ events: Event[]
155
+ ) => Record<string, unknown> | undefined;
156
+
153
157
  export const stepEventsToStepEntity = (
154
158
  events: Event[]
155
159
  ): {
@@ -231,7 +235,11 @@ export const stepEventsToStepEntity = (
231
235
  /**
232
236
  * Converts step events to an OpenTelemetry Span
233
237
  */
234
- export function stepToSpan(stepEvents: Event[], maxEndTime: Date): Span | null {
238
+ export function stepToSpan(
239
+ stepEvents: Event[],
240
+ maxEndTime: Date,
241
+ getStepAttributes?: GetStepAttributes
242
+ ): Span | null {
235
243
  const step = stepEventsToStepEntity(stepEvents);
236
244
  if (!step) {
237
245
  return null;
@@ -242,7 +250,11 @@ export function stepToSpan(stepEvents: Event[], maxEndTime: Date): Span | null {
242
250
 
243
251
  const attributes = {
244
252
  resource: 'step' as const,
245
- data: step,
253
+ data: {
254
+ ...getStepAttributes?.(stepEvents),
255
+ // Canonical event-derived fields cannot be overridden by extensions.
256
+ ...step,
257
+ },
246
258
  };
247
259
 
248
260
  const resource = 'step';
@@ -1,8 +1,9 @@
1
1
  import {
2
+ classifyEntityEvent,
2
3
  type EntityEventClass,
3
4
  type Event,
4
- entityEventClass,
5
5
  isSlotEventId,
6
+ TERMINAL_EVENT_CLASSES,
6
7
  } from '@workflow/world';
7
8
 
8
9
  /**
@@ -10,13 +11,13 @@ import {
10
11
  *
11
12
  * Concurrent replays of one run write to a shared log, so a replay working
12
13
  * from a stale prefix can commit a second `step_created` / `step_started` /
13
- * `wait_created` for an entity the log already records one of. Every replay
14
- * reads the first event of that class at the same position, so a later one
15
- * cannot change what the workflow observes.
14
+ * `wait_created` / `attr_set` for an entity the log already records one of.
15
+ * Every replay reads the first event of that class at the same position, so a
16
+ * later one cannot change what the workflow observes.
16
17
  *
17
- * The classification mirrors `entityEventClass` in `@workflow/world`, which is
18
- * what the runtime keys its own duplicate detection on. What it cannot mirror
19
- * is consumer state: the runtime passes over an event only after every
18
+ * The classification comes from `classifyEntityEvent` in `@workflow/world`,
19
+ * the same function the runtime keys its own duplicate detection on. What it
20
+ * cannot share is consumer state: the runtime passes over an event only after every
20
21
  * registered callback has declined it, and a callback registered for a
21
22
  * still-open entity legitimately claims a repeat (each retry of a step writes
22
23
  * another `step_started`, and a live step consumer absorbs a second
@@ -25,27 +26,11 @@ import {
25
26
  * consumer remains.
26
27
  */
27
28
 
28
- /**
29
- * Classes whose event closes its entity: no consumer is left for it after.
30
- *
31
- * The run's own terminal events are absent because `entityEventClass` gives
32
- * them no class. The runtime exits rather than replaying the body once the log
33
- * holds one, so nothing ever consumes them and nothing can repeat them.
34
- */
35
- const TERMINAL_EVENT_CLASSES: ReadonlySet<EntityEventClass> = new Set([
36
- 'step_terminal',
37
- 'wait_completed',
38
- 'hook_disposed',
39
- ]);
40
-
41
29
  /** Classes with no entity to close first: the log records one per run. */
42
30
  const SINGLETON_EVENT_CLASSES: ReadonlySet<EntityEventClass> = new Set([
43
31
  'run_started',
44
32
  ]);
45
33
 
46
- /** Entity key for events that carry no correlation ID (the run itself). */
47
- const RUN_ENTITY_KEY = '';
48
-
49
34
  /**
50
35
  * Shown against an event this module reports. Deliberately says what the log
51
36
  * shows rather than what the runtime did with it: tolerating these repeats is
@@ -122,10 +107,13 @@ function foldDuplicates(ordered: readonly Event[]): Set<string> {
122
107
  const closedEntities = new Set<string>();
123
108
 
124
109
  for (const event of ordered) {
125
- const eventClass = entityEventClass(event.eventType);
126
- if (eventClass === undefined) continue;
110
+ // Shared with the runtime's own duplicate detection, deliberately: an
111
+ // event it tracks under no class is one it never reads past, so naming it
112
+ // here would grey out an event the run acted on.
113
+ const classification = classifyEntityEvent(event);
114
+ if (classification === undefined) continue;
127
115
 
128
- const entity = event.correlationId ?? RUN_ENTITY_KEY;
116
+ const { eventClass, entity } = classification;
129
117
  const classKey = `${eventClass}:${entity}`;
130
118
  const repeatsClass = seenClasses.has(classKey);
131
119
  const entityWasClosed = closedEntities.has(entity);
@@ -228,6 +228,18 @@ export function getWebRevivers(): Revivers {
228
228
  if (value.stack !== undefined) error.stack = value.stack;
229
229
  return error;
230
230
  },
231
+ StreamError: (value) => {
232
+ const opts = 'cause' in value ? { cause: value.cause } : undefined;
233
+ const error = new Error(value.message, opts) as Error & {
234
+ status?: number;
235
+ url?: string;
236
+ };
237
+ error.name = 'StreamError';
238
+ if (value.status !== undefined) error.status = value.status;
239
+ if (value.url !== undefined) error.url = value.url;
240
+ if (value.stack !== undefined) error.stack = value.stack;
241
+ return error;
242
+ },
231
243
  DOMException: (value) => {
232
244
  // Modern browsers and Node 18+ expose `DOMException` on globalThis.
233
245
  // `AbortController.abort()` with no argument synthesizes one as the