UNPKG

@aws-cdk/aws-cloudwatch

Version:

The CDK Construct Library for AWS::CloudWatch

180 lines 21.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MetricSet = exports.allMetricsGraphJson = void 0; const drop_empty_object_at_the_end_of_an_array_token_1 = require("./drop-empty-object-at-the-end-of-an-array-token"); const env_tokens_1 = require("./env-tokens"); const metric_util_1 = require("./metric-util"); const object_1 = require("./object"); /** * Return the JSON structure which represents these metrics in a graph. * * Depending on the metric type (stat or expression), one `Metric` object * can render to multiple time series. * * - Top-level metrics will be rendered visibly, additionally added metrics will * be rendered invisibly. * - IDs used in math expressions need to be either globally unique, or refer to the same * metric object. * * This will be called by GraphWidget, no need for clients to call this. */ function allMetricsGraphJson(left, right) { // Add metrics to a set which will automatically expand them recursively, // making sure to retain conflicting the visible one on conflicting metrics objects. const mset = new MetricSet(); mset.addTopLevel('left', ...left); mset.addTopLevel('right', ...right); // Render all metrics from the set. return mset.entries.map(entry => new drop_empty_object_at_the_end_of_an_array_token_1.DropEmptyObjectAtTheEndOfAnArray(metricGraphJson(entry.metric, entry.tag, entry.id))); } exports.allMetricsGraphJson = allMetricsGraphJson; function metricGraphJson(metric, yAxis, id) { const config = metric.toMetricConfig(); const ret = []; const options = { ...config.renderingProperties }; metric_util_1.dispatchMetric(metric, { withStat(stat) { ret.push(stat.namespace, stat.metricName); // Dimensions for (const dim of (stat.dimensions || [])) { ret.push(dim.name, dim.value); } // Metric attributes that are rendered to graph options if (stat.account) { options.accountId = env_tokens_1.accountIfDifferentFromStack(stat.account); } if (stat.region) { options.region = env_tokens_1.regionIfDifferentFromStack(stat.region); } if (stat.period && stat.period.toSeconds() !== 300) { options.period = stat.period.toSeconds(); } if (stat.statistic && stat.statistic !== 'Average') { options.stat = stat.statistic; } }, withExpression(expr) { options.expression = expr.expression; if (expr.searchAccount) { options.accountId = env_tokens_1.accountIfDifferentFromStack(expr.searchAccount); } if (expr.searchRegion) { options.region = env_tokens_1.regionIfDifferentFromStack(expr.searchRegion); } if (expr.period && expr.period !== 300) { options.period = expr.period; } }, }); // Options if (!yAxis) { options.visible = false; } if (yAxis !== 'left') { options.yAxis = yAxis; } if (id) { options.id = id; } if (options.visible !== false && options.expression && !options.label) { // Label may be '' or undefined. // // If undefined, we'll render the expression as the label, to suppress // the default behavior of CW where it would render the metric // id as label, which we (inelegantly) generate to be something like "metric_alias0". // // For array expressions (returning more than 1 TS) users may sometimes want to // suppress the label completely. For those cases, we'll accept the empty string, // and not render a label at all. options.label = options.label === '' ? undefined : metric.toString(); } const renderedOpts = object_1.dropUndefined(options); if (Object.keys(renderedOpts).length !== 0) { ret.push(renderedOpts); } return ret; } /** * Contain a set of metrics, expanding math expressions * * "Primary" metrics (added via a top-level call) can be tagged with an additional value. */ class MetricSet { constructor() { this.metrics = new Array(); this.metricById = new Map(); this.metricByKey = new Map(); } /** * Add the given set of metrics to this set */ addTopLevel(tag, ...metrics) { for (const metric of metrics) { this.addOne(metric, tag); } } /** * Access all the accumulated timeseries entries */ get entries() { return this.metrics; } /** * Add a metric into the set * * The id may not be the same as a previous metric added, unless it's the same metric. * * It can be made visible, in which case the new "metric" object replaces the old * one (and the new ones "renderingPropertieS" will be honored instead of the old * one's). */ addOne(metric, tag, id) { const key = metric_util_1.metricKey(metric); let existingEntry; // Try lookup existing by id if we have one if (id) { existingEntry = this.metricById.get(id); if (existingEntry && metric_util_1.metricKey(existingEntry.metric) !== key) { throw new Error(`Cannot have two different metrics share the same id ('${id}') in one Alarm or Graph. Rename one of them.`); } } if (!existingEntry) { // Try lookup by metric if we didn't find one by id existingEntry = this.metricByKey.get(key); // If the one we found already has an id, it must be different from the id // we're trying to add and we want to add a new metric. Pretend we didn't // find one. if ((existingEntry === null || existingEntry === void 0 ? void 0 : existingEntry.id) && id) { existingEntry = undefined; } } // Create a new entry if we didn't find one so far let entry; if (existingEntry) { entry = existingEntry; } else { entry = { metric }; this.metrics.push(entry); this.metricByKey.set(key, entry); } // If it didn't have an id but now we do, add one if (!entry.id && id) { entry.id = id; this.metricById.set(id, entry); } // If it didn't have a tag but now we do, add one if (!entry.tag && tag) { entry.tag = tag; } // Recurse and add children const conf = metric.toMetricConfig(); if (conf.mathExpression) { for (const [subId, subMetric] of Object.entries(conf.mathExpression.usingMetrics)) { this.addOne(subMetric, undefined, subId); } } } } exports.MetricSet = MetricSet; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZGVyaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicmVuZGVyaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHFIQUFvRztBQUNwRyw2Q0FBdUY7QUFDdkYsK0NBQTBEO0FBQzFELHFDQUF5QztBQUV6Qzs7Ozs7Ozs7Ozs7O0dBWUc7QUFDSCxTQUFnQixtQkFBbUIsQ0FBQyxJQUFlLEVBQUUsS0FBZ0I7SUFDbkUseUVBQXlFO0lBQ3pFLG9GQUFvRjtJQUNwRixNQUFNLElBQUksR0FBRyxJQUFJLFNBQVMsRUFBVSxDQUFDO0lBQ3JDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7SUFDbEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsR0FBRyxLQUFLLENBQUMsQ0FBQztJQUVwQyxtQ0FBbUM7SUFDbkMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksaUZBQWdDLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzdILENBQUM7QUFURCxrREFTQztBQUVELFNBQVMsZUFBZSxDQUFDLE1BQWUsRUFBRSxLQUFjLEVBQUUsRUFBVztJQUNuRSxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7SUFFdkMsTUFBTSxHQUFHLEdBQVUsRUFBRSxDQUFDO0lBQ3RCLE1BQU0sT0FBTyxHQUFRLEVBQUUsR0FBRyxNQUFNLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztJQUV2RCw0QkFBYyxDQUFDLE1BQU0sRUFBRTtRQUNyQixRQUFRLENBQUMsSUFBSTtZQUNYLEdBQUcsQ0FBQyxJQUFJLENBQ04sSUFBSSxDQUFDLFNBQVMsRUFDZCxJQUFJLENBQUMsVUFBVSxDQUNoQixDQUFDO1lBRUYsYUFB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LElBQUksS0FBSyxDQUFDO1FBQ1YsSUFBSSxhQUFhLEVBQUU7WUFDakIsS0FBSyxHQUFHLGFBQWEsQ0FBQztTQUN2QjthQUFNO1lBQ0wsS0FBSyxHQUFHLEVBQUUsTUFBTSxFQUFFLENBQUM7WUFDbkIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDekIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQ2xDO1FBRUQsaURBQWlEO1FBQ2pELElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRTtZQUNuQixLQUFLLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztZQUNkLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztTQUNoQztRQUVELGlEQUFpRDtRQUNqRCxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsSUFBSSxHQUFHLEVBQUU7WUFDckIsS0FBSyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7U0FDakI7UUFFRCwyQkFBMkI7UUFDM0IsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3JDLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRTtZQUN2QixLQUFLLE1BQU0sQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxFQUFFO2dCQUNqRixJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7YUFDMUM7U0FDRjtLQUNGO0NBQ0Y7QUFsRkQsOEJBa0ZDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSU1ldHJpYyB9IGZyb20gJy4uL21ldHJpYy10eXBlcyc7XG5pbXBvcnQgeyBEcm9wRW1wdHlPYmplY3RBdFRoZUVuZE9mQW5BcnJheSB9IGZyb20gJy4vZHJvcC1lbXB0eS1vYmplY3QtYXQtdGhlLWVuZC1vZi1hbi1hcnJheS10b2tlbic7XG5pbXBvcnQgeyBhY2NvdW50SWZEaWZmZXJlbnRGcm9tU3RhY2ssIHJlZ2lvbklmRGlmZmVyZW50RnJvbVN0YWNrIH0gZnJvbSAnLi9lbnYtdG9rZW5zJztcbmltcG9ydCB7IGRpc3BhdGNoTWV0cmljLCBtZXRyaWNLZXkgfSBmcm9tICcuL21ldHJpYy11dGlsJztcbmltcG9ydCB7IGRyb3BVbmRlZmluZWQgfSBmcm9tICcuL29iamVjdCc7XG5cbi8qKlxuICogUmV0dXJuIHRoZSBKU09OIHN0cnVjdHVyZSB3aGljaCByZXByZXNlbnRzIHRoZXNlIG1ldHJpY3MgaW4gYSBncmFwaC5cbiAqXG4gKiBEZXBlbmRpbmcgb24gdGhlIG1ldHJpYyB0eXBlIChzdGF0IG9yIGV4cHJlc3Npb24pLCBvbmUgYE1ldHJpY2Agb2JqZWN0XG4gKiBjYW4gcmVuZGVyIHRvIG11bHRpcGxlIHRpbWUgc2VyaWVzLlxuICpcbiAqIC0gVG9wLWxldmVsIG1ldHJpY3Mgd2lsbCBiZSByZW5kZXJlZCB2aXNpYmx5LCBhZGRpdGlvbmFsbHkgYWRkZWQgbWV0cmljcyB3aWxsXG4gKiAgIGJlIHJlbmRlcmVkIGludmlzaWJseS5cbiAqIC0gSURzIHVzZWQgaW4gbWF0aCBleHByZXNzaW9ucyBuZWVkIHRvIGJlIGVpdGhlciBnbG9iYWxseSB1bmlxdWUsIG9yIHJlZmVyIHRvIHRoZSBzYW1lXG4gKiAgIG1ldHJpYyBvYmplY3QuXG4gKlxuICogVGhpcyB3aWxsIGJlIGNhbGxlZCBieSBHcmFwaFdpZGdldCwgbm8gbmVlZCBmb3IgY2xpZW50cyB0byBjYWxsIHRoaXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhbGxNZXRyaWNzR3JhcGhKc29uKGxlZnQ6IElNZXRyaWNbXSwgcmlnaHQ6IElNZXRyaWNbXSk6IGFueVtdIHtcbiAgLy8gQWRkIG1ldHJpY3MgdG8gYSBzZXQgd2hpY2ggd2lsbCBhdXRvbWF0aWNhbGx5IGV4cGFuZCB0aGVtIHJlY3Vyc2l2ZWx5LFxuICAvLyBtYWtpbmcgc3VyZSB0byByZXRhaW4gY29uZmxpY3RpbmcgdGhlIHZpc2libGUgb25lIG9uIGNvbmZsaWN0aW5nIG1ldHJpY3Mgb2JqZWN0cy5cbiAgY29uc3QgbXNldCA9IG5ldyBNZXRyaWNTZXQ8c3RyaW5nPigpO1xuICBtc2V0LmFkZFRvcExldmVsKCdsZWZ0JywgLi4ubGVmdCk7XG4gIG1zZXQuYWRkVG9wTGV2ZWwoJ3JpZ2h0JywgLi4ucmlnaHQpO1xuXG4gIC8vIFJlbmRlciBhbGwgbWV0cmljcyBmcm9tIHRoZSBzZXQuXG4gIHJldHVybiBtc2V0LmVudHJpZXMubWFwKGVudHJ5ID0+IG5ldyBEcm9wRW1wdHlPYmplY3RBdFRoZUVuZE9mQW5BcnJheShtZXRyaWNHcmFwaEpzb24oZW50cnkubWV0cmljLCBlbnRyeS50YWcsIGVudHJ5LmlkKSkpO1xufVxuXG5mdW5jdGlvbiBtZXRyaWNHcmFwaEpzb24obWV0cmljOiBJTWV0cmljLCB5QXhpcz86IHN0cmluZywgaWQ/OiBzdHJpbmcpIHtcbiAgY29uc3QgY29uZmlnID0gbWV0cmljLnRvTWV0cmljQ29uZmlnKCk7XG5cbiAgY29uc3QgcmV0OiBhbnlbXSA9IFtdO1xuICBjb25zdCBvcHRpb25zOiBhbnkgPSB7IC4uLmNvbmZpZy5yZW5kZXJpbmdQcm9wZXJ0aWVzIH07XG5cbiAgZGlzcGF0Y2hNZXRyaWMobWV0cmljLCB7XG4gICAgd2l0aFN0YXQoc3RhdCkge1xuICAgICAgcmV0LnB1c2goXG4gICAgICAgIHN0YXQubmFtZXNwYWNlLFxuICAgICAgICBzdGF0Lm1ldHJpY05hbWUsXG4gICAgICApO1xuXG4gICAgICAvLyBEaW1lbnNpb25zXG4gICAgICBmb3IgKGNvbnN0IGRpbSBvZiAoc3RhdC5kaW1lbnNpb25zIHx8IFtdKSkge1xuICAgICAgICByZXQucHVzaChkaW0ubmFtZSwgZGltLnZhbHVlKTtcbiAgICAgIH1cblxuICAgICAgLy8gTWV0cmljIGF0dHJpYnV0ZXMgdGhhdCBhcmUgcmVuZGVyZWQgdG8gZ3JhcGggb3B0aW9uc1xuICAgICAgaWYgKHN0YXQuYWNjb3VudCkgeyBvcHRpb25zLmFjY291bnRJZCA9IGFjY291bnRJZkRpZmZlcmVudEZyb21TdGFjayhzdGF0LmFjY291bnQpOyB9XG4gICAgICBpZiAoc3RhdC5yZWdpb24pIHsgb3B0aW9ucy5yZWdpb24gPSByZWdpb25JZkRpZmZlcmVudEZyb21TdGFjayhzdGF0LnJlZ2lvbik7IH1cbiAgICAgIGlmIChzdGF0LnBlcmlvZCAmJiBzdGF0LnBlcmlvZC50b1NlY29uZHMoKSAhPT0gMzAwKSB7IG9wdGlvbnMucGVyaW9kID0gc3RhdC5wZXJpb2QudG9TZWNvbmRzKCk7IH1cbiAgICAgIGlmIChzdGF0LnN0YXRpc3RpYyAmJiBzdGF0LnN0YXRpc3RpYyAhPT0gJ0F2ZXJhZ2UnKSB7IG9wdGlvbnMuc3RhdCA9IHN0YXQuc3RhdGlzdGljOyB9XG4gICAgfSxcblxuICAgIHdpdGhFeHByZXNzaW9uKGV4cHIpIHtcbiAgICAgIG9wdGlvbnMuZXhwcmVzc2lvbiA9IGV4cHIuZXhwcmVzc2lvbjtcbiAgICAgIGlmIChleHByLnNlYXJjaEFjY291bnQpIHsgb3B0aW9ucy5hY2NvdW50SWQgPSBhY2NvdW50SWZEaWZmZXJlbnRGcm9tU3RhY2soZXhwci5zZWFyY2hBY2NvdW50KTsgfVxuICAgICAgaWYgKGV4cHIuc2VhcmNoUmVnaW9uKSB7IG9wdGlvbnMucmVnaW9uID0gcmVnaW9uSWZEaWZmZXJlbnRGcm9tU3RhY2soZXhwci5zZWFyY2hSZWdpb24pOyB9XG4gICAgICBpZiAoZXhwci5wZXJpb2QgJiYgZXhwci5wZXJpb2QgIT09IDMwMCkgeyBvcHRpb25zLnBlcmlvZCA9IGV4cHIucGVyaW9kOyB9XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8gT3B0aW9uc1xuICBpZiAoIXlBeGlzKSB7IG9wdGlvbnMudmlzaWJsZSA9IGZhbHNlOyB9XG4gIGlmICh5QXhpcyAhPT0gJ2xlZnQnKSB7IG9wdGlvbnMueUF4aXMgPSB5QXhpczsgfVxuICBpZiAoaWQpIHsgb3B0aW9ucy5pZCA9IGlkOyB9XG5cbiAgaWYgKG9wdGlvbnMudmlzaWJsZSAhPT0gZmFsc2UgJiYgb3B0aW9ucy5leHByZXNzaW9uICYmICFvcHRpb25zLmxhYmVsKSB7XG4gICAgLy8gTGFiZWwgbWF5IGJlICcnIG9yIHVuZGVmaW5lZC5cbiAgICAvL1xuICAgIC8vIElmIHVuZGVmaW5lZCwgd2UnbGwgcmVuZGVyIHRoZSBleHByZXNzaW9uIGFzIHRoZSBsYWJlbCwgdG8gc3VwcHJlc3NcbiAgICAvLyB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiBDVyB3aGVyZSBpdCB3b3VsZCByZW5kZXIgdGhlIG1ldHJpY1xuICAgIC8vIGlkIGFzIGxhYmVsLCB3aGljaCB3ZSAoaW5lbGVnYW50bHkpIGdlbmVyYXRlIHRvIGJlIHNvbWV0aGluZyBsaWtlIFwibWV0cmljX2FsaWFzMFwiLlxuICAgIC8vXG4gICAgLy8gRm9yIGFycmF5IGV4cHJlc3Npb25zIChyZXR1cm5pbmcgbW9yZSB0aGFuIDEgVFMpIHVzZXJzIG1heSBzb21ldGltZXMgd2FudCB0b1xuICAgIC8vIHN1cHByZXNzIHRoZSBsYWJlbCBjb21wbGV0ZWx5LiBGb3IgdGhvc2UgY2FzZXMsIHdlJ2xsIGFjY2VwdCB0aGUgZW1wdHkgc3RyaW5nLFxuICAgIC8vIGFuZCBub3QgcmVuZGVyIGEgbGFiZWwgYXQgYWxsLlxuICAgIG9wdGlvbnMubGFiZWwgPSBvcHRpb25zLmxhYmVsID09PSAnJyA/IHVuZGVmaW5lZCA6IG1ldHJpYy50b1N0cmluZygpO1xuICB9XG5cbiAgY29uc3QgcmVuZGVyZWRPcHRzID0gZHJvcFVuZGVmaW5lZChvcHRpb25zKTtcblxuICBpZiAoT2JqZWN0LmtleXMocmVuZGVyZWRPcHRzKS5sZW5ndGggIT09IDApIHtcbiAgICByZXQucHVzaChyZW5kZXJlZE9wdHMpO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQSBzaW5nbGUgbWV0cmljIGluIGEgTWV0cmljU2V0XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWV0cmljRW50cnk8QT4ge1xuICAvKipcbiAgICogVGhlIG1ldHJpYyBvYmplY3RcbiAgICovXG4gIHJlYWRvbmx5IG1ldHJpYzogSU1ldHJpYztcblxuICAvKipcbiAgICogVGhlIHRhZywgYWRkZWQgaWYgdGhlIG9iamVjdCBpcyBhIHByaW1hcnkgbWV0cmljXG4gICAqL1xuICB0YWc/OiBBO1xuXG4gIC8qKlxuICAgKiBJRCBmb3IgdGhpcyBtZXRyaWMgb2JqZWN0XG4gICAqL1xuICBpZD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBDb250YWluIGEgc2V0IG9mIG1ldHJpY3MsIGV4cGFuZGluZyBtYXRoIGV4cHJlc3Npb25zXG4gKlxuICogXCJQcmltYXJ5XCIgbWV0cmljcyAoYWRkZWQgdmlhIGEgdG9wLWxldmVsIGNhbGwpIGNhbiBiZSB0YWdnZWQgd2l0aCBhbiBhZGRpdGlvbmFsIHZhbHVlLlxuICovXG5leHBvcnQgY2xhc3MgTWV0cmljU2V0PEE+IHtcbiAgcHJpdmF0ZSByZWFkb25seSBtZXRyaWNzID0gbmV3IEFycmF5PE1ldHJpY0VudHJ5PEE+PigpO1xuICBwcml2YXRlIHJlYWRvbmx5IG1ldHJpY0J5SWQgPSBuZXcgTWFwPHN0cmluZywgTWV0cmljRW50cnk8QT4+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWV0cmljQnlLZXkgPSBuZXcgTWFwPHN0cmluZywgTWV0cmljRW50cnk8QT4+KCk7XG5cbiAgLyoqXG4gICAqIEFkZCB0aGUgZ2l2ZW4gc2V0IG9mIG1ldHJpY3MgdG8gdGhpcyBzZXRcbiAgICovXG4gIHB1YmxpYyBhZGRUb3BMZXZlbCh0YWc6IEEsIC4uLm1ldHJpY3M6IElNZXRyaWNbXSkge1xuICAgIGZvciAoY29uc3QgbWV0cmljIG9mIG1ldHJpY3MpIHtcbiAgICAgIHRoaXMuYWRkT25lKG1ldHJpYywgdGFnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQWNjZXNzIGFsbCB0aGUgYWNjdW11bGF0ZWQgdGltZXNlcmllcyBlbnRyaWVzXG4gICAqL1xuICBwdWJsaWMgZ2V0IGVudHJpZXMoKTogUmVhZG9ubHlBcnJheTxNZXRyaWNFbnRyeTxBPj4ge1xuICAgIHJldHVybiB0aGlzLm1ldHJpY3M7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgbWV0cmljIGludG8gdGhlIHNldFxuICAgKlxuICAgKiBUaGUgaWQgbWF5IG5vdCBiZSB0aGUgc2FtZSBhcyBhIHByZXZpb3VzIG1ldHJpYyBhZGRlZCwgdW5sZXNzIGl0J3MgdGhlIHNhbWUgbWV0cmljLlxuICAgKlxuICAgKiBJdCBjYW4gYmUgbWFkZSB2aXNpYmxlLCBpbiB3aGljaCBjYXNlIHRoZSBuZXcgXCJtZXRyaWNcIiBvYmplY3QgcmVwbGFjZXMgdGhlIG9sZFxuICAgKiBvbmUgKGFuZCB0aGUgbmV3IG9uZXMgXCJyZW5kZXJpbmdQcm9wZXJ0aWVTXCIgd2lsbCBiZSBob25vcmVkIGluc3RlYWQgb2YgdGhlIG9sZFxuICAgKiBvbmUncykuXG4gICAqL1xuICBwcml2YXRlIGFkZE9uZShtZXRyaWM6IElNZXRyaWMsIHRhZz86IEEsIGlkPzogc3RyaW5nKSB7XG4gICAgY29uc3Qga2V5ID0gbWV0cmljS2V5KG1ldHJpYyk7XG5cbiAgICBsZXQgZXhpc3RpbmdFbnRyeTogTWV0cmljRW50cnk8QT4gfCB1bmRlZmluZWQ7XG5cbiAgICAvLyBUcnkgbG9va3VwIGV4aXN0aW5nIGJ5IGlkIGlmIHdlIGhhdmUgb25lXG4gICAgaWYgKGlkKSB7XG4gICAgICBleGlzdGluZ0VudHJ5ID0gdGhpcy5tZXRyaWNCeUlkLmdldChpZCk7XG4gICAgICBpZiAoZXhpc3RpbmdFbnRyeSAmJiBtZXRyaWNLZXkoZXhpc3RpbmdFbnRyeS5tZXRyaWMpICE9PSBrZXkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgaGF2ZSB0d28gZGlmZmVyZW50IG1ldHJpY3Mgc2hhcmUgdGhlIHNhbWUgaWQgKCcke2lkfScpIGluIG9uZSBBbGFybSBvciBHcmFwaC4gUmVuYW1lIG9uZSBvZiB0aGVtLmApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghZXhpc3RpbmdFbnRyeSkge1xuICAgICAgLy8gVHJ5IGxvb2t1cCBieSBtZXRyaWMgaWYgd2UgZGlkbid0IGZpbmQgb25lIGJ5IGlkXG4gICAgICBleGlzdGluZ0VudHJ5ID0gdGhpcy5tZXRyaWNCeUtleS5nZXQoa2V5KTtcblxuICAgICAgLy8gSWYgdGhlIG9uZSB3ZSBmb3VuZCBhbHJlYWR5IGhhcyBhbiBpZCwgaXQgbXVzdCBiZSBkaWZmZXJlbnQgZnJvbSB0aGUgaWRcbiAgICAgIC8vIHdlJ3JlIHRyeWluZyB0byBhZGQgYW5kIHdlIHdhbnQgdG8gYWRkIGEgbmV3IG1ldHJpYy4gUHJldGVuZCB3ZSBkaWRuJ3RcbiAgICAgIC8vIGZpbmQgb25lLlxuICAgICAgaWYgKGV4aXN0aW5nRW50cnk/LmlkICYmIGlkKSB7IGV4aXN0aW5nRW50cnkgPSB1bmRlZmluZWQ7IH1cbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgYSBuZXcgZW50cnkgaWYgd2UgZGlkbid0IGZpbmQgb25lIHNvIGZhclxuICAgIGxldCBlbnRyeTtcbiAgICBpZiAoZXhpc3RpbmdFbnRyeSkge1xuICAgICAgZW50cnkgPSBleGlzdGluZ0VudHJ5O1xuICAgIH0gZWxzZSB7XG4gICAgICBlbnRyeSA9IHsgbWV0cmljIH07XG4gICAgICB0aGlzLm1ldHJpY3MucHVzaChlbnRyeSk7XG4gICAgICB0aGlzLm1ldHJpY0J5S2V5LnNldChrZXksIGVudHJ5KTtcbiAgICB9XG5cbiAgICAvLyBJZiBpdCBkaWRuJ3QgaGF2ZSBhbiBpZCBidXQgbm93IHdlIGRvLCBhZGQgb25lXG4gICAgaWYgKCFlbnRyeS5pZCAmJiBpZCkge1xuICAgICAgZW50cnkuaWQgPSBpZDtcbiAgICAgIHRoaXMubWV0cmljQnlJZC5zZXQoaWQsIGVudHJ5KTtcbiAgICB9XG5cbiAgICAvLyBJZiBpdCBkaWRuJ3QgaGF2ZSBhIHRhZyBidXQgbm93IHdlIGRvLCBhZGQgb25lXG4gICAgaWYgKCFlbnRyeS50YWcgJiYgdGFnKSB7XG4gICAgICBlbnRyeS50YWcgPSB0YWc7XG4gICAgfVxuXG4gICAgLy8gUmVjdXJzZSBhbmQgYWRkIGNoaWxkcmVuXG4gICAgY29uc3QgY29uZiA9IG1ldHJpYy50b01ldHJpY0NvbmZpZygpO1xuICAgIGlmIChjb25mLm1hdGhFeHByZXNzaW9uKSB7XG4gICAgICBmb3IgKGNvbnN0IFtzdWJJZCwgc3ViTWV0cmljXSBvZiBPYmplY3QuZW50cmllcyhjb25mLm1hdGhFeHByZXNzaW9uLnVzaW5nTWV0cmljcykpIHtcbiAgICAgICAgdGhpcy5hZGRPbmUoc3ViTWV0cmljLCB1bmRlZmluZWQsIHN1YklkKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiJdfQ==