UNPKG

@nova-ui/charts

Version:

Nova Charts is a library created to provide potential consumers with solutions for various data visualizations that conform with the Nova Design Language. It's designed to solve common patterns identified by UX designers, but also be very flexible so that

140 lines 25.2 kB
// © 2022 SolarWinds Worldwide, LLC. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import { select } from "d3-selection"; import findIndex from "lodash/findIndex"; import isArray from "lodash/isArray"; import isUndefined from "lodash/isUndefined"; import { DATA_POINT_INTERACTION_RESET, DATA_POINT_NOT_FOUND, } from "../../../constants"; import { isBandScale, } from "../../../core/common/scales/types"; import { UtilityService } from "../../../core/common/utility.service"; import { RenderLayerName, RenderState, } from "../../types"; export class BarHighlightStrategy { scaleKey; levels; selectedDataPointIdxFn; /** * @param scaleKey scale that will be used for searching for the data point that will be highlighted * @param levels for band scales, how many levels deep do we go to compare values */ constructor(scaleKey, levels = 1, selectedDataPointIdxFn) { this.scaleKey = scaleKey; this.levels = levels; this.selectedDataPointIdxFn = selectedDataPointIdxFn; } getDataPointIndex(renderer, series, values, scales) { const value = values[this.scaleKey]; if (typeof value === "undefined") { // if there is no value we're returning -2 (DATA_POINT_INTERACTION_RESET) which helps highlightDataPoint // to understand that we need to emphasise things when we are moving outside of an interactive area return DATA_POINT_INTERACTION_RESET; } return this.findDataPointByValue(series, value, this.scaleKey, scales); } findDataPointByValue(series, value, scaleKey, scales) { const accessorSuffix = scaleKey.toUpperCase(); const dataAccessors = series.accessors.data; const startAccessor = dataAccessors["start" + accessorSuffix]; const endAccessor = dataAccessors["end" + accessorSuffix]; if (typeof value === "string") { return findIndex(series.data, (d, i) => value === startAccessor?.(d, i, series.data, series)); } if (isArray(value)) { return findIndex(series.data, (d, i) => { const start = startAccessor?.(d, i, series.data, series); const lengthLimit = Math.min(this.levels, value.length, start.length); // diy efficient array comparison for (let j = 0; j < lengthLimit; j++) { if (value[j] !== start[j]) { return false; } } return true; }); } if (value.valueOf) { const valueOf = value.valueOf(); if (scales && scales[scaleKey]?.isContinuous()) { let index = findIndex(series.data, (d, i) => valueOf >= startAccessor?.(d, i, series.data, series).valueOf() && valueOf <= endAccessor?.(d, i, series.data, series).valueOf()); if (index === -1 && typeof endAccessor !== "undefined") { if (isBandScale(scales[scaleKey])) { const accessor = (d, i) => startAccessor?.(d, i, series.data, series); const nearestIndex = UtilityService.findNearestIndex(series.data, value, accessor); index = nearestIndex >= series.data.length || accessor(series.data[nearestIndex], nearestIndex) > valueOf ? -1 : nearestIndex; } else { // @ts-ignore // Needs to catch -1 otherwise typescript errors index = UtilityService.getClosestIndex(series.data, (d, i) => endAccessor(d, i, series.data, series), value) ?? -1; } } return index; } return findIndex(series.data, (d, i) => valueOf >= startAccessor?.(d, i, series.data, series).valueOf() && valueOf <= endAccessor?.(d, i, series.data, series).valueOf()); } return DATA_POINT_INTERACTION_RESET; } highlightDataPoint(renderer, renderSeries, dataPointIndex, rendererSubject) { const target = renderSeries.containers[RenderLayerName.data]; const barStylesFn = renderer.getContainerStateStyles; const selectedDataPointIdx = !isUndefined(this.selectedDataPointIdxFn) ? this.selectedDataPointIdxFn(renderSeries.dataSeries.id) : DATA_POINT_NOT_FOUND; target .selectAll(`g.${renderer.barContainerClass}`) .each(function (d, index) { let renderState; if (dataPointIndex === DATA_POINT_INTERACTION_RESET) { if (index === selectedDataPointIdx || selectedDataPointIdx === DATA_POINT_NOT_FOUND) { renderState = RenderState.default; } else { renderState = RenderState.deemphasized; } } else if (dataPointIndex === index || index === selectedDataPointIdx) { renderState = RenderState.emphasized; } else { renderState = RenderState.deemphasized; } select(this).attrs(barStylesFn(renderState)); }); // rendererSubject.next({ // eventName: HIGHLIGHT_SERIES_EVENT, // data: renderer.getDataPoint(renderSeries, renderSeries.dataSeries.data[dataPointIndex], dataPointIndex), // }); } draw(renderer, renderSeries, rendererSubject) { } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFyLWhpZ2hsaWdodC1zdHJhdGVneS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9yZW5kZXJlcnMvYmFyL2hpZ2hsaWdodC1zdHJhdGVnaWVzL2Jhci1oaWdobGlnaHQtc3RyYXRlZ3kudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEseURBQXlEO0FBQ3pELEVBQUU7QUFDRiwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLDhFQUE4RTtBQUM5RSwrRUFBK0U7QUFDL0UsOEVBQThFO0FBQzlFLDREQUE0RDtBQUM1RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLHVEQUF1RDtBQUN2RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLDRFQUE0RTtBQUM1RSwrRUFBK0U7QUFDL0UsMEVBQTBFO0FBQzFFLGlGQUFpRjtBQUNqRiw2RUFBNkU7QUFDN0UsaUJBQWlCO0FBRWpCLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDdEMsT0FBTyxTQUFTLE1BQU0sa0JBQWtCLENBQUM7QUFDekMsT0FBTyxPQUFPLE1BQU0sZ0JBQWdCLENBQUM7QUFDckMsT0FBTyxXQUFXLE1BQU0sb0JBQW9CLENBQUM7QUFHN0MsT0FBTyxFQUNILDRCQUE0QixFQUM1QixvQkFBb0IsR0FDdkIsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QixPQUFPLEVBQ0gsV0FBVyxHQUdkLE1BQU0sbUNBQW1DLENBQUM7QUFFM0MsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBRXRFLE9BQU8sRUFHSCxlQUFlLEVBQ2YsV0FBVyxHQUNkLE1BQU0sYUFBYSxDQUFDO0FBS3JCLE1BQU0sT0FBTyxvQkFBb0I7SUFRZjtJQUNBO0lBQ0E7SUFQZDs7O09BR0c7SUFDSCxZQUNjLFFBQXlCLEVBQ3pCLFNBQVMsQ0FBQyxFQUNWLHNCQUE4QztRQUY5QyxhQUFRLEdBQVIsUUFBUSxDQUFpQjtRQUN6QixXQUFNLEdBQU4sTUFBTSxDQUFJ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Q0gsV0FBVyxHQUFHLFdBQVcsQ0FBQyxZQUFZLENBQUM7YUFDMUM7WUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO1FBQ2pELENBQUMsQ0FBQyxDQUFDO1FBRVAseUJBQXlCO1FBQ3pCLHlDQUF5QztRQUN6QywrR0FBK0c7UUFDL0csTUFBTTtJQUNWLENBQUM7SUFFTSxJQUFJLENBQ1AsUUFBcUIsRUFDckIsWUFBZ0QsRUFDaEQsZUFBK0MsSUFDMUMsQ0FBQztDQUNiIiwic291cmNlc0NvbnRlbnQiOlsiLy8gwqkgMjAyMiBTb2xhcldpbmRzIFdvcmxkd2lkZSwgTExDLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuLy8gIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4vLyAgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4vLyAgc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vICBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyAgYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vICBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vICBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCB7IHNlbGVjdCB9IGZyb20gXCJkMy1zZWxlY3Rpb25cIjtcbmltcG9ydCBmaW5kSW5kZXggZnJvbSBcImxvZGFzaC9maW5kSW5kZXhcIjtcbmltcG9ydCBpc0FycmF5IGZyb20gXCJsb2Rhc2gvaXNBcnJheVwiO1xuaW1wb3J0IGlzVW5kZWZpbmVkIGZyb20gXCJsb2Rhc2gvaXNVbmRlZmluZWRcIjtcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tIFwicnhqc1wiO1xuXG5pbXBvcnQge1xuICAgIERBVEFfUE9JTlRfSU5URVJBQ1RJT05fUkVTRVQsXG4gICAgREFUQV9QT0lOVF9OT1RfRk9VTkQsXG59IGZyb20gXCIuLi8uLi8uLi9jb25zdGFudHNcIjtcbmltcG9ydCB7XG4gICAgaXNCYW5kU2NhbGUsXG4gICAgSVhZU2NhbGVzLFxuICAgIFNjYWxlcyxcbn0gZnJvbSBcIi4uLy4uLy4uL2NvcmUvY29tbW9uL3NjYWxlcy90eXBlc1wiO1xuaW1wb3J0IHsgSURhdGFTZXJpZXMsIElSZW5kZXJlckV2ZW50UGF5bG9hZCB9IGZyb20gXCIuLi8uLi8uLi9jb3JlL2NvbW1vbi90eXBlc1wiO1xuaW1wb3J0IHsgVXRpbGl0eVNlcnZpY2UgfSBmcm9tIFwiLi4vLi4vLi4vY29yZS9jb21tb24vdXRpbGl0eS5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBJUmVjdGFuZ2xlQWNjZXNzb3JzIH0gZnJvbSBcIi4uLy4uL2FjY2Vzc29ycy9yZWN0YW5nbGUtYWNjZXNzb3JzXCI7XG5pbXBvcnQge1xuICAgIElIaWdobGlnaHRTdHJhdGVneSxcbiAgICBJUmVuZGVyU2VyaWVzLFxuICAgIFJlbmRlckxheWVyTmFtZSxcbiAgICBSZW5kZXJTdGF0ZSxcbn0gZnJvbSBcIi4uLy4uL3R5cGVzXCI7XG5pbXBvcnQgeyBCYXJSZW5kZXJlciB9IGZyb20gXCIuLi9iYXItcmVuZGVyZXJcIjtcblxuZXhwb3J0IHR5cGUgU2VsZWN0ZWREYXRQb2ludElkeEZuID0gKHNlcmllc0lkOiBzdHJpbmcpID0+IG51bWJlcjtcblxuZXhwb3J0IGNsYXNzIEJhckhpZ2hsaWdodFN0cmF0ZWd5XG4gICAgaW1wbGVtZW50cyBJSGlnaGxpZ2h0U3RyYXRlZ3k8SVJlY3RhbmdsZUFjY2Vzc29ycywgQmFyUmVuZGVyZXI+XG57XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHNjYWxlS2V5IHNjYWxlIHRoYXQgd2lsbCBiZSB1c2VkIGZvciBzZWFyY2hpbmcgZm9yIHRoZSBkYXRhIHBvaW50IHRoYXQgd2lsbCBiZSBoaWdobGlnaHRlZFxuICAgICAqIEBwYXJhbSBsZXZlbHMgZm9yIGJhbmQgc2NhbGVzLCBob3cgbWFueSBsZXZlbHMgZGVlcCBkbyB3ZSBnbyB0byBjb21wYXJlIHZhbHVlc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcm90ZWN0ZWQgc2NhbGVLZXk6IGtleW9mIElYWVNjYWxlcyxcbiAgICAgICAgcHJvdGVjdGVkIGxldmVscyA9IDEsXG4gICAgICAgIHByb3RlY3RlZCBzZWxlY3RlZERhdGFQb2ludElkeEZuPzogU2VsZWN0ZWREYXRQb2ludElkeEZuXG4gICAgKSB7fVxuXG4gICAgcHVibGljIGdldERhdGFQb2ludEluZGV4KFxuICAgICAgICByZW5kZXJlcjogQmFyUmVuZGVyZXIsXG4gICAgICAgIHNlcmllczogSURhdGFTZXJpZXM8SVJlY3RhbmdsZUFjY2Vzc29ycz4sXG4gICAgICAgIHZhbHVlczogeyBbcDogc3RyaW5nXTogYW55IH0sXG4gICAgICAgIHNjYWxlczogU2NhbGVzXG4gICAgKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB2YWx1ZXNbdGhpcy5zY2FsZUtleV07XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIHZhbHVlIHdlJ3JlIHJldHVybmluZyAtMiAoREFUQV9QT0lOVF9JTlRFUkFDVElPTl9SRVNFVCkgd2hpY2ggaGVscHMgaGlnaGxpZ2h0RGF0YVBvaW50XG4gICAgICAgICAgICAvLyB0byB1bmRlcnN0YW5kIHRoYXQgd2UgbmVlZCB0byBlbXBoYXNpc2UgdGhpbmdzIHdoZW4gd2UgYXJlIG1vdmluZyBvdXRzaWRlIG9mIGFuIGludGVyYWN0aXZlIGFyZWFcbiAgICAgICAgICAgIHJldHVybiBEQVRBX1BPSU5UX0lOVEVSQUNUSU9OX1JFU0VUO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZmluZERhdGFQb2ludEJ5VmFsdWUoc2VyaWVzLCB2YWx1ZSwgdGhpcy5zY2FsZUtleSwgc2NhbGVzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZmluZERhdGFQb2ludEJ5VmFsdWUoXG4gICAgICAgIHNlcmllczogSURhdGFTZXJpZXM8SVJlY3RhbmdsZUFjY2Vzc29ycz4sXG4gICAgICAgIHZhbHVlOiBhbnksXG4gICAgICAgIHNjYWxlS2V5OiBrZXlvZiBJWFlTY2FsZXMsXG4gICAgICAgIHNjYWxlcz86IFNjYWxlc1xuICAgICk6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IGFjY2Vzc29yU3VmZml4ID0gKHNjYWxlS2V5IGFzIHN0cmluZykudG9VcHBlckNhc2UoKTtcbiAgICAgICAgY29uc3QgZGF0YUFjY2Vzc29ycyA9IHNlcmllcy5hY2Nlc3NvcnMuZGF0YTtcblxuICAgICAgICBjb25zdCBzdGFydEFjY2Vzc29yID0gZGF0YUFjY2Vzc29yc1tcInN0YXJ0XCIgKyBhY2Nlc3NvclN1ZmZpeF07XG4gICAgICAgIGNvbnN0IGVuZEFjY2Vzc29yID0gZGF0YUFjY2Vzc29yc1tcImVuZFwiICsgYWNjZXNzb3JTdWZmaXhdO1xuXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBmaW5kSW5kZXgoXG4gICAgICAgICAgICAgICAgc2VyaWVzLmRhdGEsXG4gICAgICAgICAgICAgICAgKGQsIGkpID0+IHZhbHVlID09PSBzdGFydEFjY2Vzc29yPy4oZCwgaSwgc2VyaWVzLmRhdGEsIHNlcmllcylcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmluZEluZGV4KHNlcmllcy5kYXRhLCAoZCwgaSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0gc3RhcnRBY2Nlc3Nvcj8uKGQsIGksIHNlcmllcy5kYXRhLCBzZXJpZXMpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGxlbmd0aExpbWl0ID0gTWF0aC5taW4oXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubGV2ZWxzLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZS5sZW5ndGgsXG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0Lmxlbmd0aFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgLy8gZGl5IGVmZmljaWVudCBhcnJheSBjb21wYXJpc29uXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBsZW5ndGhMaW1pdDsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZVtqXSAhPT0gc3RhcnRbal0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh2YWx1ZS52YWx1ZU9mKSB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZU9mID0gdmFsdWUudmFsdWVPZigpO1xuICAgICAgICAgICAgaWYgKHNjYWxlcyAmJiBzY2FsZXNbc2NhbGVLZXldPy5pc0NvbnRpbnVvdXMoKSkge1xuICAgICAgICAgICAgICAgIGxldCBpbmRleCA9IGZpbmRJbmRleChcbiAgICAgICAgICAgICAgICAgICAgc2VyaWVzLmRhdGEsXG4gICAgICAgICAgICAgICAgICAgIChkLCBpKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVPZiA+PVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0QWNjZXNzb3I/LihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VyaWVzLmRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcmllc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICkudmFsdWVPZigpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZU9mIDw9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kQWNjZXNzb3I/LihkLCBpLCBzZXJpZXMuZGF0YSwgc2VyaWVzKS52YWx1ZU9mKClcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGlmIChpbmRleCA9PT0gLTEgJiYgdHlwZW9mIGVuZEFjY2Vzc29yICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0JhbmRTY2FsZShzY2FsZXNbc2NhbGVLZXldKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWNjZXNzb3IgPSAoZDogYW55LCBpOiBhbnkpID0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRBY2Nlc3Nvcj8uKGQsIGksIHNlcmllcy5kYXRhLCBzZXJpZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmVhcmVzdEluZGV4ID0gVXRpbGl0eVNlcnZpY2UuZmluZE5lYXJlc3RJbmRleChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXJpZXMuZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY2Nlc3NvclxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZWFyZXN0SW5kZXggPj0gc2VyaWVzLmRhdGEubGVuZ3RoIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXNzb3Ioc2VyaWVzLmRhdGFbbmVhcmVzdEluZGV4XSwgbmVhcmVzdEluZGV4KSA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlT2ZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAtMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG5lYXJlc3RJbmRleDtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5lZWRzIHRvIGNhdGNoIC0xIG90aGVyd2lzZSB0eXBlc2NyaXB0IGVycm9yc1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFV0aWxpdHlTZXJ2aWNlLmdldENsb3Nlc3RJbmRleChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VyaWVzLmRhdGEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkLCBpKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kQWNjZXNzb3IoZCwgaSwgc2VyaWVzLmRhdGEsIHNlcmllcyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKSA/PyAtMTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmluZEluZGV4KFxuICAgICAgICAgICAgICAgIHNlcmllcy5kYXRhLFxuICAgICAgICAgICAgICAgIChkLCBpKSA9PlxuICAgICAgICAgICAgICAgICAgICB2YWx1ZU9mID49XG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFydEFjY2Vzc29yPy4oZCwgaSwgc2VyaWVzLmRhdGEsIHNlcmllcykudmFsdWVPZigpICYmXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlT2YgPD1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVuZEFjY2Vzc29yPy4oZCwgaSwgc2VyaWVzLmRhdGEsIHNlcmllcykudmFsdWVPZigpXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIERBVEFfUE9JTlRfSU5URVJBQ1RJT05fUkVTRVQ7XG4gICAgfVxuXG4gICAgcHVibGljIGhpZ2hsaWdodERhdGFQb2ludChcbiAgICAgICAgcmVuZGVyZXI6IEJhclJlbmRlcmVyLFxuICAgICAgICByZW5kZXJTZXJpZXM6IElSZW5kZXJTZXJpZXM8SVJlY3RhbmdsZUFjY2Vzc29ycz4sXG4gICAgICAgIGRhdGFQb2ludEluZGV4OiBudW1iZXIsXG4gICAgICAgIHJlbmRlcmVyU3ViamVjdDogU3ViamVjdDxJUmVuZGVyZXJFdmVudFBheWxvYWQ+XG4gICAgKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHRhcmdldCA9IHJlbmRlclNlcmllcy5jb250YWluZXJzW1JlbmRlckxheWVyTmFtZS5kYXRhXTtcbiAgICAgICAgY29uc3QgYmFyU3R5bGVzRm4gPSByZW5kZXJlci5nZXRDb250YWluZXJTdGF0ZVN0eWxlcztcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWREYXRhUG9pbnRJZHggPSAhaXNVbmRlZmluZWQodGhpcy5zZWxlY3RlZERhdGFQb2ludElkeEZuKVxuICAgICAgICAgICAgPyB0aGlzLnNlbGVjdGVkRGF0YVBvaW50SWR4Rm4ocmVuZGVyU2VyaWVzLmRhdGFTZXJpZXMuaWQpXG4gICAgICAgICAgICA6IERBVEFfUE9JTlRfTk9UX0ZPVU5EO1xuXG4gICAgICAgIHRhcmdldFxuICAgICAgICAgICAgLnNlbGVjdEFsbChgZy4ke3JlbmRlcmVyLmJhckNvbnRhaW5lckNsYXNzfWApXG4gICAgICAgICAgICAuZWFjaChmdW5jdGlvbiAoZDogYW55LCBpbmRleDogbnVtYmVyKSB7XG4gICAgICAgICAgICAgICAgbGV0IHJlbmRlclN0YXRlOiBSZW5kZXJTdGF0ZTtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YVBvaW50SW5kZXggPT09IERBVEFfUE9JTlRfSU5URVJBQ1RJT05fUkVTRVQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPT09IHNlbGVjdGVkRGF0YVBvaW50SWR4IHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZERhdGFQb2ludElkeCA9PT0gREFUQV9QT0lOVF9OT1RfRk9VTkRcbiAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZW5kZXJTdGF0ZSA9IFJlbmRlclN0YXRlLmRlZmF1bHQ7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZW5kZXJTdGF0ZSA9IFJlbmRlclN0YXRlLmRlZW1waGFzaXplZDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgICAgICAgIGRhdGFQb2ludEluZGV4ID09PSBpbmRleCB8fFxuICAgICAgICAgICAgICAgICAgICBpbmRleCA9PT0gc2VsZWN0ZWREYXRhUG9pbnRJZHhcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgcmVuZGVyU3RhdGUgPSBSZW5kZXJTdGF0ZS5lbXBoYXNpemVkO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlbmRlclN0YXRlID0gUmVuZGVyU3RhdGUuZGVlbXBoYXNpemVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzZWxlY3QodGhpcykuYXR0cnMoYmFyU3R5bGVzRm4ocmVuZGVyU3RhdGUpKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIC8vIHJlbmRlcmVyU3ViamVjdC5uZXh0KHtcbiAgICAgICAgLy8gICAgIGV2ZW50TmFtZTogSElHSExJR0hUX1NFUklFU19FVkVOVCxcbiAgICAgICAgLy8gICAgIGRhdGE6IHJlbmRlcmVyLmdldERhdGFQb2ludChyZW5kZXJTZXJpZXMsIHJlbmRlclNlcmllcy5kYXRhU2VyaWVzLmRhdGFbZGF0YVBvaW50SW5kZXhdLCBkYXRhUG9pbnRJbmRleCksXG4gICAgICAgIC8vIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBkcmF3KFxuICAgICAgICByZW5kZXJlcjogQmFyUmVuZGVyZXIsXG4gICAgICAgIHJlbmRlclNlcmllczogSVJlbmRlclNlcmllczxJUmVjdGFuZ2xlQWNjZXNzb3JzPixcbiAgICAgICAgcmVuZGVyZXJTdWJqZWN0OiBTdWJqZWN0PElSZW5kZXJlckV2ZW50UGF5bG9hZD5cbiAgICApOiB2b2lkIHt9XG59XG4iXX0=