UNPKG

@nova-ui/dashboards

Version:

Nova Dashboards is a framework designed to provide feature developers with a common solution for presenting data coming from various sources within a single view, as well as a set of predefined widget visualizations that are 100% configuration-driven and

104 lines 17 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 * as d3 from "d3"; import cloneDeep from "lodash/cloneDeep"; import { transformLoessSmoothing } from "./transformer-loess"; export function transformChangePoint(data, hasPercentile) { let transformed = cloneDeep(data); const sectionSize = 20; // to change section size const criticalValue = 1.729; // one-tail 0.05 transformed = transformLoessSmoothing(transformed, hasPercentile); let tScore; // The t_score formula enables you to take an individual score and transform it into a standardized form>one which helps you to compare scores. let meanOfFirstSection = 0; let standardDeviationOfFirstSection; let meanOfSecondSection; let standardDeviationOfSecondSection; let yValuesOfFirstSection = []; let yValuesOfSecondSection = []; let merging = true; let startIndex = 0; let endIndex = sectionSize - 1; let startIndex2 = sectionSize; let endIndex2 = startIndex2 + endIndex; while (merging) { merging = false; yValuesOfFirstSection = []; yValuesOfSecondSection = []; for (let i = startIndex; i <= endIndex; i++) { yValuesOfFirstSection.push(data[i].y); } for (let j = startIndex2; j <= endIndex2; j++) { yValuesOfSecondSection.push(data[j].y); } meanOfFirstSection = d3.mean(yValuesOfFirstSection) ?? 0; meanOfSecondSection = d3.mean(yValuesOfSecondSection) ?? 0; standardDeviationOfFirstSection = d3.deviation(yValuesOfFirstSection) ?? 0; if (standardDeviationOfFirstSection < 1.0) { standardDeviationOfFirstSection = 1.0; } standardDeviationOfSecondSection = d3.deviation(yValuesOfSecondSection) ?? 0; if (standardDeviationOfSecondSection < 1.0) { standardDeviationOfSecondSection = 1.0; } tScore = getT_Score(meanOfFirstSection, meanOfSecondSection, standardDeviationOfFirstSection, standardDeviationOfSecondSection, yValuesOfFirstSection.length, yValuesOfSecondSection.length, criticalValue); if (tScore > criticalValue) { for (let k = startIndex; k <= endIndex; k++) { transformed[k].y = meanOfFirstSection; } startIndex = startIndex2; } endIndex = endIndex2; if (endIndex + sectionSize < data.length) { merging = true; startIndex2 = endIndex + 1; endIndex2 = startIndex2 + sectionSize - 1; } else { endIndex = data.length - 1; } } for (let k = startIndex; k <= endIndex; k++) { transformed[k].y = meanOfFirstSection; } return transformed; } function getT_Score(meanOfFirstSection1, meanOfSecondSection, standardDeviationOfFirstSection, standardDeviationOfSecondSection, sizeOfFirstSection, sizeOfSecondSection, criticalValue) { const differenceOfSampleMeans = meanOfFirstSection1 - meanOfSecondSection; const standardDeviationOfBothSections = Math.pow(standardDeviationOfFirstSection, 2) / sizeOfFirstSection + Math.pow(standardDeviationOfSecondSection, 2) / sizeOfSecondSection; const squareRootofResult = Math.sqrt(standardDeviationOfBothSections); let tScore = differenceOfSampleMeans / squareRootofResult; if (tScore > criticalValue) { if (meanOfFirstSection1 < meanOfSecondSection + 2 * standardDeviationOfSecondSection && meanOfFirstSection1 > meanOfSecondSection - 2 * standardDeviationOfSecondSection && meanOfSecondSection < meanOfFirstSection1 + 2 * standardDeviationOfFirstSection && meanOfSecondSection > meanOfFirstSection1 - 2 * standardDeviationOfFirstSection) { tScore = 0.0; } } return Math.abs(tScore); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmb3JtZXItY2hhbmdlLXBvaW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9jb21wb25lbnRzL3RpbWVzZXJpZXMtd2lkZ2V0L3RyYW5zZm9ybWVyL3RyYW5zZm9ybWVyLWNoYW5nZS1wb2ludC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx5REFBeUQ7QUFDekQsRUFBRTtBQUNGLCtFQUErRTtBQUMvRSw0RUFBNEU7QUFDNUUsOEVBQThFO0FBQzlFLCtFQUErRTtBQUMvRSw4RUFBOEU7QUFDOUUsNERBQTREO0FBQzVELEVBQUU7QUFDRiw2RUFBNkU7QUFDN0UsdURBQXVEO0FBQ3ZELEVBQUU7QUFDRiw2RUFBNkU7QUFDN0UsNEVBQTRFO0FBQzVFLCtFQUErRTtBQUMvRSwwRUFBMEU7QUFDMUUsaUZBQWlGO0FBQ2pGLDZFQUE2RTtBQUM3RSxpQkFBaUI7QUFFakIsT0FBTyxLQUFLLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDekIsT0FBTyxTQUFTLE1BQU0sa0JBQWtCLENBQUM7QUFHekMsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFOUQsTUFBTSxVQUFVLG9CQUFvQixDQUNoQyxJQUFtQyxFQUNuQyxhQUF1QjtJQUV2QixJQUFJLFdBQVcsR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbEMsTUFBTSxXQUFXLEdBQUcsRUFBRSxDQUFDLENBQUMseUJBQXlCO0lBQ2pELE1BQU0sYUFBYSxHQUFHLEtBQUssQ0FBQyxDQUFDLGdCQUFnQjtJQUU3QyxXQUFXLEdBQUcsdUJBQXVCLENBQUMsV0FBVyxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBRWxFLElBQUksTUFBYyxDQUFDLENBQUMsK0lBQStJO0lBQ25LLElBQUksa0JBQWtCLEdBQVcsQ0FBQyxDQUFDO0lBQ25DLElBQUksK0JBQXVDLENBQUM7SUFDNUMsSUFBSSxtQkFBMkIsQ0FBQztJQUNoQyxJ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Q2YsbUJBQTJCLEVBQzNCLG1CQUEyQixFQUMzQiwrQkFBdUMsRUFDdkMsZ0NBQXdDLEVBQ3hDLGtCQUEwQixFQUMxQixtQkFBMkIsRUFDM0IsYUFBcUI7SUFFckIsTUFBTSx1QkFBdUIsR0FBRyxtQkFBbUIsR0FBRyxtQkFBbUIsQ0FBQztJQUMxRSxNQUFNLCtCQUErQixHQUNqQyxJQUFJLENBQUMsR0FBRyxDQUFDLCtCQUErQixFQUFFLENBQUMsQ0FBQyxHQUFHLGtCQUFrQjtRQUNqRSxJQUFJLENBQUMsR0FBRyxDQUFDLGdDQUFnQyxFQUFFLENBQUMsQ0FBQyxHQUFHLG1CQUFtQixDQUFDO0lBQ3hFLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO0lBQ3RFLElBQUksTUFBTSxHQUFHLHVCQUF1QixHQUFHLGtCQUFrQixDQUFDO0lBQzFELElBQUksTUFBTSxHQUFHLGFBQWEsRUFBRTtRQUN4QixJQUNJLG1CQUFtQjtZQUNmLG1CQUFtQixHQUFHLENBQUMsR0FBRyxnQ0FBZ0M7WUFDOUQsbUJBQW1CO2dCQUNmLG1CQUFtQixHQUFHLENBQUMsR0FBRyxnQ0FBZ0M7WUFDOUQsbUJBQW1CO2dCQUNmLG1CQUFtQixHQUFHLENBQUMsR0FBRywrQkFBK0I7WUFDN0QsbUJBQW1CO2dCQUNmLG1CQUFtQixHQUFHLENBQUMsR0FBRywrQkFBK0IsRUFDL0Q7WUFDRSxNQUFNLEdBQUcsR0FBRyxDQUFDO1NBQ2hCO0tBQ0o7SUFDRCxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDNUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIMKpIDIwMjIgU29sYXJXaW5kcyBXb3JsZHdpZGUsIExMQy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyAgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG9cbi8vICBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuLy8gIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuLy8gIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyAgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vICBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vICBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vICBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLyAgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vICBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4vLyAgVEhFIFNPRlRXQVJFLlxuXG5pbXBvcnQgKiBhcyBkMyBmcm9tIFwiZDNcIjtcbmltcG9ydCBjbG9uZURlZXAgZnJvbSBcImxvZGFzaC9jbG9uZURlZXBcIjtcblxuaW1wb3J0IHsgSVRpbWVzZXJpZXNXaWRnZXRTZXJpZXNEYXRhIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyB0cmFuc2Zvcm1Mb2Vzc1Ntb290aGluZyB9IGZyb20gXCIuL3RyYW5zZm9ybWVyLWxvZXNzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2Zvcm1DaGFuZ2VQb2ludChcbiAgICBkYXRhOiBJVGltZXNlcmllc1dpZGdldFNlcmllc0RhdGFbXSxcbiAgICBoYXNQZXJjZW50aWxlPzogYm9vbGVhblxuKTogSVRpbWVzZXJpZXNXaWRnZXRTZXJpZXNEYXRhW10ge1xuICAgIGxldCB0cmFuc2Zvcm1lZCA9IGNsb25lRGVlcChkYXRhKTtcbiAgICBjb25zdCBzZWN0aW9uU2l6ZSA9IDIwOyAvLyB0byBjaGFuZ2Ugc2VjdGlvbiBzaXplXG4gICAgY29uc3QgY3JpdGljYWxWYWx1ZSA9IDEuNzI5OyAvLyBvbmUtdGFpbCAwLjA1XG5cbiAgICB0cmFuc2Zvcm1lZCA9IHRyYW5zZm9ybUxvZXNzU21vb3RoaW5nKHRyYW5zZm9ybWVkLCBoYXNQZXJjZW50aWxlKTtcblxuICAgIGxldCB0U2NvcmU6IG51bWJlcjsgLy8gVGhlIHRfc2NvcmUgZm9ybXVsYSBlbmFibGVzIHlvdSB0byB0YWtlIGFuIGluZGl2aWR1YWwgc2NvcmUgYW5kIHRyYW5zZm9ybSBpdCBpbnRvIGEgc3RhbmRhcmRpemVkIGZvcm0+b25lIHdoaWNoIGhlbHBzIHlvdSB0byBjb21wYXJlIHNjb3Jlcy5cbiAgICBsZXQgbWVhbk9mRmlyc3RTZWN0aW9uOiBudW1iZXIgPSAwO1xuICAgIGxldCBzdGFuZGFyZERldmlhdGlvbk9mRmlyc3RTZWN0aW9uOiBudW1iZXI7XG4gICAgbGV0IG1lYW5PZlNlY29uZFNlY3Rpb246IG51bWJlcjtcbiAgICBsZXQgc3RhbmRhcmREZXZpYXRpb25PZlNlY29uZFNlY3Rpb246IG51bWJlcjtcbiAgICBsZXQgeVZhbHVlc09mRmlyc3RTZWN0aW9uID0gW107XG4gICAgbGV0IHlWYWx1ZXNPZlNlY29uZFNlY3Rpb24gPSBbXTtcbiAgICBsZXQgbWVyZ2luZzogYm9vbGVhbiA9IHRydWU7XG4gICAgbGV0IHN0YXJ0SW5kZXg6IG51bWJlciA9IDA7XG4gICAgbGV0IGVuZEluZGV4OiBudW1iZXIgPSBzZWN0aW9uU2l6ZSAtIDE7XG4gICAgbGV0IHN0YXJ0SW5kZXgyOiBudW1iZXIgPSBzZWN0aW9uU2l6ZTtcbiAgICBsZXQgZW5kSW5kZXgyOiBudW1iZXIgPSBzdGFydEluZGV4MiArIGVuZEluZGV4O1xuICAgIHdoaWxlIChtZXJnaW5nKSB7XG4gICAgICAgIG1lcmdpbmcgPSBmYWxzZTtcbiAgICAgICAgeVZhbHVlc09mRmlyc3RTZWN0aW9uID0gW107XG4gICAgICAgIHlWYWx1ZXNPZlNlY29uZFNlY3Rpb24gPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IHN0YXJ0SW5kZXg7IGkgPD0gZW5kSW5kZXg7IGkrKykge1xuICAgICAgICAgICAgeVZhbHVlc09mRmlyc3RTZWN0aW9uLnB1c2goZGF0YVtpXS55KTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBqID0gc3RhcnRJbmRleDI7IGogPD0gZW5kSW5kZXgyOyBqKyspIHtcbiAgICAgICAgICAgIHlWYWx1ZXNPZlNlY29uZFNlY3Rpb24ucHVzaChkYXRhW2pdLnkpO1xuICAgICAgICB9XG4gICAgICAgIG1lYW5PZkZpcnN0U2VjdGlvbiA9IGQzLm1lYW4oeVZhbHVlc09mRmlyc3RTZWN0aW9uKSA/PyAwO1xuICAgICAgICBtZWFuT2ZTZWNvbmRTZWN0aW9uID0gZDMubWVhbih5VmFsdWVzT2ZTZWNvbmRTZWN0aW9uKSA/PyAwO1xuICAgICAgICBzdGFuZGFyZERldmlhdGlvbk9mRmlyc3RTZWN0aW9uID1cbiAgICAgICAgICAgIGQzLmRldmlhdGlvbih5VmFsdWVzT2ZGaXJzdFNlY3Rpb24pID8/IDA7XG4gICAgICAgIGlmIChzdGFuZGFyZERldmlhdGlvbk9mRmlyc3RTZWN0aW9uIDwgMS4wKSB7XG4gICAgICAgICAgICBzdGFuZGFyZERldmlhdGlvbk9mRmlyc3RTZWN0aW9uID0gMS4wO1xuICAgICAgICB9XG4gICAgICAgIHN0YW5kYXJkRGV2aWF0aW9uT2ZTZWNvbmRTZWN0aW9uID1cbiAgICAgICAgICAgIGQzLmRldmlhdGlvbih5VmFsdWVzT2ZTZWNvbmRTZWN0aW9uKSA/PyAwO1xuICAgICAgICBpZiAoc3RhbmRhcmREZXZpYXRpb25PZlNlY29uZFNlY3Rpb24gPCAxLjApIHtcbiAgICAgICAgICAgIHN0YW5kYXJkRGV2aWF0aW9uT2ZTZWNvbmRTZWN0aW9uID0gMS4wO1xuICAgICAgICB9XG4gICAgICAgIHRTY29yZSA9IGdldFRfU2NvcmUoXG4gICAgICAgICAgICBtZWFuT2ZGaXJzdFNlY3Rpb24sXG4gICAgICAgICAgICBtZWFuT2ZTZWNvbmRTZWN0aW9uLFxuICAgICAgICAgICAgc3RhbmRhcmREZXZpYXRpb25PZkZpcnN0U2VjdGlvbixcbiAgICAgICAgICAgIHN0YW5kYXJkRGV2aWF0aW9uT2ZTZWNvbmRTZWN0aW9uLFxuICAgICAgICAgICAgeVZhbHVlc09mRmlyc3RTZWN0aW9uLmxlbmd0aCxcbiAgICAgICAgICAgIHlWYWx1ZXNPZlNlY29uZFNlY3Rpb24ubGVuZ3RoLFxuICAgICAgICAgICAgY3JpdGljYWxWYWx1ZVxuICAgICAgICApO1xuICAgICAgICBpZiAodFNjb3JlID4gY3JpdGljYWxWYWx1ZSkge1xuICAgICAgICAgICAgZm9yIChsZXQgayA9IHN0YXJ0SW5kZXg7IGsgPD0gZW5kSW5kZXg7IGsrKykge1xuICAgICAgICAgICAgICAgIHRyYW5zZm9ybWVkW2tdLnkgPSBtZWFuT2ZGaXJzdFNlY3Rpb247XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdGFydEluZGV4ID0gc3RhcnRJbmRleDI7XG4gICAgICAgIH1cbiAgICAgICAgZW5kSW5kZXggPSBlbmRJbmRleDI7XG4gICAgICAgIGlmIChlbmRJbmRleCArIHNlY3Rpb25TaXplIDwgZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgIG1lcmdpbmcgPSB0cnVlO1xuICAgICAgICAgICAgc3RhcnRJbmRleDIgPSBlbmRJbmRleCArIDE7XG4gICAgICAgICAgICBlbmRJbmRleDIgPSBzdGFydEluZGV4MiArIHNlY3Rpb25TaXplIC0gMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGVuZEluZGV4ID0gZGF0YS5sZW5ndGggLSAxO1xuICAgICAgICB9XG4gICAgfVxuICAgIGZvciAobGV0IGsgPSBzdGFydEluZGV4OyBrIDw9IGVuZEluZGV4OyBrKyspIHtcbiAgICAgICAgdHJhbnNmb3JtZWRba10ueSA9IG1lYW5PZkZpcnN0U2VjdGlvbjtcbiAgICB9XG4gICAgcmV0dXJuIHRyYW5zZm9ybWVkO1xufVxuXG5mdW5jdGlvbiBnZXRUX1Njb3JlKFxuICAgIG1lYW5PZkZpcnN0U2VjdGlvbjE6IG51bWJlcixcbiAgICBtZWFuT2ZTZWNvbmRTZWN0aW9uOiBudW1iZXIsXG4gICAgc3RhbmRhcmREZXZpYXRpb25PZkZpcnN0U2VjdGlvbjogbnVtYmVyLFxuICAgIHN0YW5kYXJkRGV2aWF0aW9uT2ZTZWNvbmRTZWN0aW9uOiBudW1iZXIsXG4gICAgc2l6ZU9mRmlyc3RTZWN0aW9uOiBudW1iZXIsXG4gICAgc2l6ZU9mU2Vjb25kU2VjdGlvbjogbnVtYmVyLFxuICAgIGNyaXRpY2FsVmFsdWU6IG51bWJlclxuKSB7XG4gICAgY29uc3QgZGlmZmVyZW5jZU9mU2FtcGxlTWVhbnMgPSBtZWFuT2ZGaXJzdFNlY3Rpb24xIC0gbWVhbk9mU2Vjb25kU2VjdGlvbjtcbiAgICBjb25zdCBzdGFuZGFyZERldmlhdGlvbk9mQm90aFNlY3Rpb25zID1cbiAgICAgICAgTWF0aC5wb3coc3RhbmRhcmREZXZpYXRpb25PZkZpcnN0U2VjdGlvbiwgMikgLyBzaXplT2ZGaXJzdFNlY3Rpb24gK1xuICAgICAgICBNYXRoLnBvdyhzdGFuZGFyZERldmlhdGlvbk9mU2Vjb25kU2VjdGlvbiwgMikgLyBzaXplT2ZTZWNvbmRTZWN0aW9uO1xuICAgIGNvbnN0IHNxdWFyZVJvb3RvZlJlc3VsdCA9IE1hdGguc3FydChzdGFuZGFyZERldmlhdGlvbk9mQm90aFNlY3Rpb25zKTtcbiAgICBsZXQgdFNjb3JlID0gZGlmZmVyZW5jZU9mU2FtcGxlTWVhbnMgLyBzcXVhcmVSb290b2ZSZXN1bHQ7XG4gICAgaWYgKHRTY29yZSA+IGNyaXRpY2FsVmFsdWUpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgbWVhbk9mRmlyc3RTZWN0aW9uMSA8XG4gICAgICAgICAgICAgICAgbWVhbk9mU2Vjb25kU2VjdGlvbiArIDIgKiBzdGFuZGFyZERldmlhdGlvbk9mU2Vjb25kU2VjdGlvbiAmJlxuICAgICAgICAgICAgbWVhbk9mRmlyc3RTZWN0aW9uMSA+XG4gICAgICAgICAgICAgICAgbWVhbk9mU2Vjb25kU2VjdGlvbiAtIDIgKiBzdGFuZGFyZERldmlhdGlvbk9mU2Vjb25kU2VjdGlvbiAmJlxuICAgICAgICAgICAgbWVhbk9mU2Vjb25kU2VjdGlvbiA8XG4gICAgICAgICAgICAgICAgbWVhbk9mRmlyc3RTZWN0aW9uMSArIDIgKiBzdGFuZGFyZERldmlhdGlvbk9mRmlyc3RTZWN0aW9uICYmXG4gICAgICAgICAgICBtZWFuT2ZTZWNvbmRTZWN0aW9uID5cbiAgICAgICAgICAgICAgICBtZWFuT2ZGaXJzdFNlY3Rpb24xIC0gMiAqIHN0YW5kYXJkRGV2aWF0aW9uT2ZGaXJzdFNlY3Rpb25cbiAgICAgICAgKSB7XG4gICAgICAgICAgICB0U2NvcmUgPSAwLjA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIE1hdGguYWJzKHRTY29yZSk7XG59XG4iXX0=