1 | ;
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.MetricSet = exports.allMetricsGraphJson = void 0;
|
4 | const drop_empty_object_at_the_end_of_an_array_token_1 = require("./drop-empty-object-at-the-end-of-an-array-token");
|
5 | const env_tokens_1 = require("./env-tokens");
|
6 | const metric_util_1 = require("./metric-util");
|
7 | const object_1 = require("./object");
|
8 | /**
|
9 | * Return the JSON structure which represents these metrics in a graph.
|
10 | *
|
11 | * Depending on the metric type (stat or expression), one `Metric` object
|
12 | * can render to multiple time series.
|
13 | *
|
14 | * - Top-level metrics will be rendered visibly, additionally added metrics will
|
15 | * be rendered invisibly.
|
16 | * - IDs used in math expressions need to be either globally unique, or refer to the same
|
17 | * metric object.
|
18 | *
|
19 | * This will be called by GraphWidget, no need for clients to call this.
|
20 | */
|
21 | function allMetricsGraphJson(left, right) {
|
22 | // Add metrics to a set which will automatically expand them recursively,
|
23 | // making sure to retain conflicting the visible one on conflicting metrics objects.
|
24 | const mset = new MetricSet();
|
25 | mset.addTopLevel('left', ...left);
|
26 | mset.addTopLevel('right', ...right);
|
27 | // Render all metrics from the set.
|
28 | 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)));
|
29 | }
|
30 | exports.allMetricsGraphJson = allMetricsGraphJson;
|
31 | function metricGraphJson(metric, yAxis, id) {
|
32 | const config = metric.toMetricConfig();
|
33 | const ret = [];
|
34 | const options = { ...config.renderingProperties };
|
35 | metric_util_1.dispatchMetric(metric, {
|
36 | withStat(stat) {
|
37 | ret.push(stat.namespace, stat.metricName);
|
38 | // Dimensions
|
39 | for (const dim of (stat.dimensions || [])) {
|
40 | ret.push(dim.name, dim.value);
|
41 | }
|
42 | // Metric attributes that are rendered to graph options
|
43 | if (stat.account) {
|
44 | options.accountId = env_tokens_1.accountIfDifferentFromStack(stat.account);
|
45 | }
|
46 | if (stat.region) {
|
47 | options.region = env_tokens_1.regionIfDifferentFromStack(stat.region);
|
48 | }
|
49 | if (stat.period && stat.period.toSeconds() !== 300) {
|
50 | options.period = stat.period.toSeconds();
|
51 | }
|
52 | if (stat.statistic && stat.statistic !== 'Average') {
|
53 | options.stat = stat.statistic;
|
54 | }
|
55 | },
|
56 | withExpression(expr) {
|
57 | options.expression = expr.expression;
|
58 | if (expr.searchAccount) {
|
59 | options.accountId = env_tokens_1.accountIfDifferentFromStack(expr.searchAccount);
|
60 | }
|
61 | if (expr.searchRegion) {
|
62 | options.region = env_tokens_1.regionIfDifferentFromStack(expr.searchRegion);
|
63 | }
|
64 | if (expr.period && expr.period !== 300) {
|
65 | options.period = expr.period;
|
66 | }
|
67 | },
|
68 | });
|
69 | // Options
|
70 | if (!yAxis) {
|
71 | options.visible = false;
|
72 | }
|
73 | if (yAxis !== 'left') {
|
74 | options.yAxis = yAxis;
|
75 | }
|
76 | if (id) {
|
77 | options.id = id;
|
78 | }
|
79 | if (options.visible !== false && options.expression && !options.label) {
|
80 | // Label may be '' or undefined.
|
81 | //
|
82 | // If undefined, we'll render the expression as the label, to suppress
|
83 | // the default behavior of CW where it would render the metric
|
84 | // id as label, which we (inelegantly) generate to be something like "metric_alias0".
|
85 | //
|
86 | // For array expressions (returning more than 1 TS) users may sometimes want to
|
87 | // suppress the label completely. For those cases, we'll accept the empty string,
|
88 | // and not render a label at all.
|
89 | options.label = options.label === '' ? undefined : metric.toString();
|
90 | }
|
91 | const renderedOpts = object_1.dropUndefined(options);
|
92 | if (Object.keys(renderedOpts).length !== 0) {
|
93 | ret.push(renderedOpts);
|
94 | }
|
95 | return ret;
|
96 | }
|
97 | /**
|
98 | * Contain a set of metrics, expanding math expressions
|
99 | *
|
100 | * "Primary" metrics (added via a top-level call) can be tagged with an additional value.
|
101 | */
|
102 | class MetricSet {
|
103 | constructor() {
|
104 | this.metrics = new Array();
|
105 | this.metricById = new Map();
|
106 | this.metricByKey = new Map();
|
107 | }
|
108 | /**
|
109 | * Add the given set of metrics to this set
|
110 | */
|
111 | addTopLevel(tag, ...metrics) {
|
112 | for (const metric of metrics) {
|
113 | this.addOne(metric, tag);
|
114 | }
|
115 | }
|
116 | /**
|
117 | * Access all the accumulated timeseries entries
|
118 | */
|
119 | get entries() {
|
120 | return this.metrics;
|
121 | }
|
122 | /**
|
123 | * Add a metric into the set
|
124 | *
|
125 | * The id may not be the same as a previous metric added, unless it's the same metric.
|
126 | *
|
127 | * It can be made visible, in which case the new "metric" object replaces the old
|
128 | * one (and the new ones "renderingPropertieS" will be honored instead of the old
|
129 | * one's).
|
130 | */
|
131 | addOne(metric, tag, id) {
|
132 | const key = metric_util_1.metricKey(metric);
|
133 | let existingEntry;
|
134 | // Try lookup existing by id if we have one
|
135 | if (id) {
|
136 | existingEntry = this.metricById.get(id);
|
137 | if (existingEntry && metric_util_1.metricKey(existingEntry.metric) !== key) {
|
138 | throw new Error(`Cannot have two different metrics share the same id ('${id}') in one Alarm or Graph. Rename one of them.`);
|
139 | }
|
140 | }
|
141 | if (!existingEntry) {
|
142 | // Try lookup by metric if we didn't find one by id
|
143 | existingEntry = this.metricByKey.get(key);
|
144 | // If the one we found already has an id, it must be different from the id
|
145 | // we're trying to add and we want to add a new metric. Pretend we didn't
|
146 | // find one.
|
147 | if ((existingEntry === null || existingEntry === void 0 ? void 0 : existingEntry.id) && id) {
|
148 | existingEntry = undefined;
|
149 | }
|
150 | }
|
151 | // Create a new entry if we didn't find one so far
|
152 | let entry;
|
153 | if (existingEntry) {
|
154 | entry = existingEntry;
|
155 | }
|
156 | else {
|
157 | entry = { metric };
|
158 | this.metrics.push(entry);
|
159 | this.metricByKey.set(key, entry);
|
160 | }
|
161 | // If it didn't have an id but now we do, add one
|
162 | if (!entry.id && id) {
|
163 | entry.id = id;
|
164 | this.metricById.set(id, entry);
|
165 | }
|
166 | // If it didn't have a tag but now we do, add one
|
167 | if (!entry.tag && tag) {
|
168 | entry.tag = tag;
|
169 | }
|
170 | // Recurse and add children
|
171 | const conf = metric.toMetricConfig();
|
172 | if (conf.mathExpression) {
|
173 | for (const [subId, subMetric] of Object.entries(conf.mathExpression.usingMetrics)) {
|
174 | this.addOne(subMetric, undefined, subId);
|
175 | }
|
176 | }
|
177 | }
|
178 | }
|
179 | exports.MetricSet = MetricSet;
|
180 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZGVyaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicmVuZGVyaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHFIQUFvRztBQUNwRyw2Q0FBdUY7QUFDdkYsK0NBQTBEO0FBQzFELHFDQUF5QztBQUV6Qzs7Ozs7Ozs7Ozs7O0dBWUc7QUFDSCxTQUFnQixtQkFBbUIsQ0FBQyxJQUFlLEVBQUUsS0FBZ0I7SUFDbkUseUVBQXlFO0lBQ3pFLG9GQUFvRjtJQUNwRixNQUFNLElBQUksR0FBRyxJQUFJLFNBQVMsRUFBVSxDQUFDO0lBQ3JDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7SUFDbEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsR0FBRyxLQUFLLENBQUMsQ0FBQztJQUVwQyxtQ0FBbUM7SUFDbkMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksaUZBQWdDLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzdILENBQUM7QUFURCxrREFTQztBQUVELFNBQVMsZUFBZSxDQUFDLE1BQWUsRUFBRSxLQUFjLEVBQUUsRUFBVztJQUNuRSxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7SUFFdkMsTUFBTSxHQUFHLEdBQVUsRUFBRSxDQUFDO0lBQ3RCLE1BQU0sT0FBTyxHQUFRLEVBQUUsR0FBRyxNQUFNLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztJQUV2RCw0QkFBYyxDQUFDLE1BQU0sRUFBRTtRQUNyQixRQUFRLENBQUMsSUFBSTtZQUNYLEdBQUcsQ0FBQyxJQUFJLENBQ04sSUFBSSxDQUFDLFNBQVMsRUFDZCxJQUFJLENBQUMsVUFBVSxDQUNoQixDQUFDO1lBRUYsYUFB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LElBQUksS0FBSyxDQUFDO1FBQ1YsSUFBSSxhQUFhLEVBQUU7WUFDakIsS0FBSyxHQUFHLGFBQWEsQ0FBQztTQUN2QjthQUFNO1lBQ0wsS0FBSyxHQUFHLEVBQUUsTUFBTSxFQUFFLENBQUM7WUFDbkIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDekIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQ2xDO1FBRUQsaURBQWlEO1FBQ2pELElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRTtZQUNuQixLQUFLLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztZQUNkLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztTQUNoQztRQUVELGlEQUFpRDtRQUNqRCxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsSUFBSSxHQUFHLEVBQUU7WUFDckIsS0FBSyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7U0FDakI7UUFFRCwyQkFBMkI7UUFDM0IsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3JDLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRTtZQUN2QixLQUFLLE1BQU0sQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxFQUFFO2dCQUNqRixJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7YUFDMUM7U0FDRjtLQUNGO0NBQ0Y7QUFsRkQsOEJBa0ZDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSU1ldHJpYyB9IGZyb20gJy4uL21ldHJpYy10eXBlcyc7XG5pbXBvcnQgeyBEcm9wRW1wdHlPYmplY3RBdFRoZUVuZE9mQW5BcnJheSB9IGZyb20gJy4vZHJvcC1lbXB0eS1vYmplY3QtYXQtdGhlLWVuZC1vZi1hbi1hcnJheS10b2tlbic7XG5pbXBvcnQgeyBhY2NvdW50SWZEaWZmZXJlbnRGcm9tU3RhY2ssIHJlZ2lvbklmRGlmZmVyZW50RnJvbVN0YWNrIH0gZnJvbSAnLi9lbnYtdG9rZW5zJztcbmltcG9ydCB7IGRpc3BhdGNoTWV0cmljLCBtZXRyaWNLZXkgfSBmcm9tICcuL21ldHJpYy11dGlsJztcbmltcG9ydCB7IGRyb3BVbmRlZmluZWQgfSBmcm9tICcuL29iamVjdCc7XG5cbi8qKlxuICogUmV0dXJuIHRoZSBKU09OIHN0cnVjdHVyZSB3aGljaCByZXByZXNlbnRzIHRoZXNlIG1ldHJpY3MgaW4gYSBncmFwaC5cbiAqXG4gKiBEZXBlbmRpbmcgb24gdGhlIG1ldHJpYyB0eXBlIChzdGF0IG9yIGV4cHJlc3Npb24pLCBvbmUgYE1ldHJpY2Agb2JqZWN0XG4gKiBjYW4gcmVuZGVyIHRvIG11bHRpcGxlIHRpbWUgc2VyaWVzLlxuICpcbiAqIC0gVG9wLWxldmVsIG1ldHJpY3Mgd2lsbCBiZSByZW5kZXJlZCB2aXNpYmx5LCBhZGRpdGlvbmFsbHkgYWRkZWQgbWV0cmljcyB3aWxsXG4gKiAgIGJlIHJlbmRlcmVkIGludmlzaWJseS5cbiAqIC0gSURzIHVzZWQgaW4gbWF0aCBleHByZXNzaW9ucyBuZWVkIHRvIGJlIGVpdGhlciBnbG9iYWxseSB1bmlxdWUsIG9yIHJlZmVyIHRvIHRoZSBzYW1lXG4gKiAgIG1ldHJpYyBvYmplY3QuXG4gKlxuICogVGhpcyB3aWxsIGJlIGNhbGxlZCBieSBHcmFwaFdpZGdldCwgbm8gbmVlZCBmb3IgY2xpZW50cyB0byBjYWxsIHRoaXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhbGxNZXRyaWNzR3JhcGhKc29uKGxlZnQ6IElNZXRyaWNbXSwgcmlnaHQ6IElNZXRyaWNbXSk6IGFueVtdIHtcbiAgLy8gQWRkIG1ldHJpY3MgdG8gYSBzZXQgd2hpY2ggd2lsbCBhdXRvbWF0aWNhbGx5IGV4cGFuZCB0aGVtIHJlY3Vyc2l2ZWx5LFxuICAvLyBtYWtpbmcgc3VyZSB0byByZXRhaW4gY29uZmxpY3RpbmcgdGhlIHZpc2libGUgb25lIG9uIGNvbmZsaWN0aW5nIG1ldHJpY3Mgb2JqZWN0cy5cbiAgY29uc3QgbXNldCA9IG5ldyBNZXRyaWNTZXQ8c3RyaW5nPigpO1xuICBtc2V0LmFkZFRvcExldmVsKCdsZWZ0JywgLi4ubGVmdCk7XG4gIG1zZXQuYWRkVG9wTGV2ZWwoJ3JpZ2h0JywgLi4ucmlnaHQpO1xuXG4gIC8vIFJlbmRlciBhbGwgbWV0cmljcyBmcm9tIHRoZSBzZXQuXG4gIHJldHVybiBtc2V0LmVudHJpZXMubWFwKGVudHJ5ID0+IG5ldyBEcm9wRW1wdHlPYmplY3RBdFRoZUVuZE9mQW5BcnJheShtZXRyaWNHcmFwaEpzb24oZW50cnkubWV0cmljLCBlbnRyeS50YWcsIGVudHJ5LmlkKSkpO1xufVxuXG5mdW5jdGlvbiBtZXRyaWNHcmFwaEpzb24obWV0cmljOiBJTWV0cmljLCB5QXhpcz86IHN0cmluZywgaWQ/OiBzdHJpbmcpIHtcbiAgY29uc3QgY29uZmlnID0gbWV0cmljLnRvTWV0cmljQ29uZmlnKCk7XG5cbiAgY29uc3QgcmV0OiBhbnlbXSA9IFtdO1xuICBjb25zdCBvcHRpb25zOiBhbnkgPSB7IC4uLmNvbmZpZy5yZW5kZXJpbmdQcm9wZXJ0aWVzIH07XG5cbiAgZGlzcGF0Y2hNZXRyaWMobWV0cmljLCB7XG4gICAgd2l0aFN0YXQoc3RhdCkge1xuICAgICAgcmV0LnB1c2goXG4gICAgICAgIHN0YXQubmFtZXNwYWNlLFxuICAgICAgICBzdGF0Lm1ldHJpY05hbWUsXG4gICAgICApO1xuXG4gICAgICAvLyBEaW1lbnNpb25zXG4gICAgICBmb3IgKGNvbnN0IGRpbSBvZiAoc3RhdC5kaW1lbnNpb25zIHx8IFtdKSkge1xuICAgICAgICByZXQucHVzaChkaW0ubmFtZSwgZGltLnZhbHVlKTtcbiAgICAgIH1cblxuICAgICAgLy8gTWV0cmljIGF0dHJpYnV0ZXMgdGhhdCBhcmUgcmVuZGVyZWQgdG8gZ3JhcGggb3B0aW9uc1xuICAgICAgaWYgKHN0YXQuYWNjb3VudCkgeyBvcHRpb25zLmFjY291bnRJZCA9IGFjY291bnRJZkRpZmZlcmVudEZyb21TdGFjayhzdGF0LmFjY291bnQpOyB9XG4gICAgICBpZiAoc3RhdC5yZWdpb24pIHsgb3B0aW9ucy5yZWdpb24gPSByZWdpb25JZkRpZmZlcmVudEZyb21TdGFjayhzdGF0LnJlZ2lvbik7IH1cbiAgICAgIGlmIChzdGF0LnBlcmlvZCAmJiBzdGF0LnBlcmlvZC50b1NlY29uZHMoKSAhPT0gMzAwKSB7IG9wdGlvbnMucGVyaW9kID0gc3RhdC5wZXJpb2QudG9TZWNvbmRzKCk7IH1cbiAgICAgIGlmIChzdGF0LnN0YXRpc3RpYyAmJiBzdGF0LnN0YXRpc3RpYyAhPT0gJ0F2ZXJhZ2UnKSB7IG9wdGlvbnMuc3RhdCA9IHN0YXQuc3RhdGlzdGljOyB9XG4gICAgfSxcblxuICAgIHdpdGhFeHByZXNzaW9uKGV4cHIpIHtcbiAgICAgIG9wdGlvbnMuZXhwcmVzc2lvbiA9IGV4cHIuZXhwcmVzc2lvbjtcbiAgICAgIGlmIChleHByLnNlYXJjaEFjY291bnQpIHsgb3B0aW9ucy5hY2NvdW50SWQgPSBhY2NvdW50SWZEaWZmZXJlbnRGcm9tU3RhY2soZXhwci5zZWFyY2hBY2NvdW50KTsgfVxuICAgICAgaWYgKGV4cHIuc2VhcmNoUmVnaW9uKSB7IG9wdGlvbnMucmVnaW9uID0gcmVnaW9uSWZEaWZmZXJlbnRGcm9tU3RhY2soZXhwci5zZWFyY2hSZWdpb24pOyB9XG4gICAgICBpZiAoZXhwci5wZXJpb2QgJiYgZXhwci5wZXJpb2QgIT09IDMwMCkgeyBvcHRpb25zLnBlcmlvZCA9IGV4cHIucGVyaW9kOyB9XG4gICAgfSxcbiAgfSk7XG5cbiAgLy8gT3B0aW9uc1xuICBpZiAoIXlBeGlzKSB7IG9wdGlvbnMudmlzaWJsZSA9IGZhbHNlOyB9XG4gIGlmICh5QXhpcyAhPT0gJ2xlZnQnKSB7IG9wdGlvbnMueUF4aXMgPSB5QXhpczsgfVxuICBpZiAoaWQpIHsgb3B0aW9ucy5pZCA9IGlkOyB9XG5cbiAgaWYgKG9wdGlvbnMudmlzaWJsZSAhPT0gZmFsc2UgJiYgb3B0aW9ucy5leHByZXNzaW9uICYmICFvcHRpb25zLmxhYmVsKSB7XG4gICAgLy8gTGFiZWwgbWF5IGJlICcnIG9yIHVuZGVmaW5lZC5cbiAgICAvL1xuICAgIC8vIElmIHVuZGVmaW5lZCwgd2UnbGwgcmVuZGVyIHRoZSBleHByZXNzaW9uIGFzIHRoZSBsYWJlbCwgdG8gc3VwcHJlc3NcbiAgICAvLyB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiBDVyB3aGVyZSBpdCB3b3VsZCByZW5kZXIgdGhlIG1ldHJpY1xuICAgIC8vIGlkIGFzIGxhYmVsLCB3aGljaCB3ZSAoaW5lbGVnYW50bHkpIGdlbmVyYXRlIHRvIGJlIHNvbWV0aGluZyBsaWtlIFwibWV0cmljX2FsaWFzMFwiLlxuICAgIC8vXG4gICAgLy8gRm9yIGFycmF5IGV4cHJlc3Npb25zIChyZXR1cm5pbmcgbW9yZSB0aGFuIDEgVFMpIHVzZXJzIG1heSBzb21ldGltZXMgd2FudCB0b1xuICAgIC8vIHN1cHByZXNzIHRoZSBsYWJlbCBjb21wbGV0ZWx5LiBGb3IgdGhvc2UgY2FzZXMsIHdlJ2xsIGFjY2VwdCB0aGUgZW1wdHkgc3RyaW5nLFxuICAgIC8vIGFuZCBub3QgcmVuZGVyIGEgbGFiZWwgYXQgYWxsLlxuICAgIG9wdGlvbnMubGFiZWwgPSBvcHRpb25zLmxhYmVsID09PSAnJyA/IHVuZGVmaW5lZCA6IG1ldHJpYy50b1N0cmluZygpO1xuICB9XG5cbiAgY29uc3QgcmVuZGVyZWRPcHRzID0gZHJvcFVuZGVmaW5lZChvcHRpb25zKTtcblxuICBpZiAoT2JqZWN0LmtleXMocmVuZGVyZWRPcHRzKS5sZW5ndGggIT09IDApIHtcbiAgICByZXQucHVzaChyZW5kZXJlZE9wdHMpO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogQSBzaW5nbGUgbWV0cmljIGluIGEgTWV0cmljU2V0XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWV0cmljRW50cnk8QT4ge1xuICAvKipcbiAgICogVGhlIG1ldHJpYyBvYmplY3RcbiAgICovXG4gIHJlYWRvbmx5IG1ldHJpYzogSU1ldHJpYztcblxuICAvKipcbiAgICogVGhlIHRhZywgYWRkZWQgaWYgdGhlIG9iamVjdCBpcyBhIHByaW1hcnkgbWV0cmljXG4gICAqL1xuICB0YWc/OiBBO1xuXG4gIC8qKlxuICAgKiBJRCBmb3IgdGhpcyBtZXRyaWMgb2JqZWN0XG4gICAqL1xuICBpZD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBDb250YWluIGEgc2V0IG9mIG1ldHJpY3MsIGV4cGFuZGluZyBtYXRoIGV4cHJlc3Npb25zXG4gKlxuICogXCJQcmltYXJ5XCIgbWV0cmljcyAoYWRkZWQgdmlhIGEgdG9wLWxldmVsIGNhbGwpIGNhbiBiZSB0YWdnZWQgd2l0aCBhbiBhZGRpdGlvbmFsIHZhbHVlLlxuICovXG5leHBvcnQgY2xhc3MgTWV0cmljU2V0PEE+IHtcbiAgcHJpdmF0ZSByZWFkb25seSBtZXRyaWNzID0gbmV3IEFycmF5PE1ldHJpY0VudHJ5PEE+PigpO1xuICBwcml2YXRlIHJlYWRvbmx5IG1ldHJpY0J5SWQgPSBuZXcgTWFwPHN0cmluZywgTWV0cmljRW50cnk8QT4+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWV0cmljQnlLZXkgPSBuZXcgTWFwPHN0cmluZywgTWV0cmljRW50cnk8QT4+KCk7XG5cbiAgLyoqXG4gICAqIEFkZCB0aGUgZ2l2ZW4gc2V0IG9mIG1ldHJpY3MgdG8gdGhpcyBzZXRcbiAgICovXG4gIHB1YmxpYyBhZGRUb3BMZXZlbCh0YWc6IEEsIC4uLm1ldHJpY3M6IElNZXRyaWNbXSkge1xuICAgIGZvciAoY29uc3QgbWV0cmljIG9mIG1ldHJpY3MpIHtcbiAgICAgIHRoaXMuYWRkT25lKG1ldHJpYywgdGFnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQWNjZXNzIGFsbCB0aGUgYWNjdW11bGF0ZWQgdGltZXNlcmllcyBlbnRyaWVzXG4gICAqL1xuICBwdWJsaWMgZ2V0IGVudHJpZXMoKTogUmVhZG9ubHlBcnJheTxNZXRyaWNFbnRyeTxBPj4ge1xuICAgIHJldHVybiB0aGlzLm1ldHJpY3M7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgbWV0cmljIGludG8gdGhlIHNldFxuICAgKlxuICAgKiBUaGUgaWQgbWF5IG5vdCBiZSB0aGUgc2FtZSBhcyBhIHByZXZpb3VzIG1ldHJpYyBhZGRlZCwgdW5sZXNzIGl0J3MgdGhlIHNhbWUgbWV0cmljLlxuICAgKlxuICAgKiBJdCBjYW4gYmUgbWFkZSB2aXNpYmxlLCBpbiB3aGljaCBjYXNlIHRoZSBuZXcgXCJtZXRyaWNcIiBvYmplY3QgcmVwbGFjZXMgdGhlIG9sZFxuICAgKiBvbmUgKGFuZCB0aGUgbmV3IG9uZXMgXCJyZW5kZXJpbmdQcm9wZXJ0aWVTXCIgd2lsbCBiZSBob25vcmVkIGluc3RlYWQgb2YgdGhlIG9sZFxuICAgKiBvbmUncykuXG4gICAqL1xuICBwcml2YXRlIGFkZE9uZShtZXRyaWM6IElNZXRyaWMsIHRhZz86IEEsIGlkPzogc3RyaW5nKSB7XG4gICAgY29uc3Qga2V5ID0gbWV0cmljS2V5KG1ldHJpYyk7XG5cbiAgICBsZXQgZXhpc3RpbmdFbnRyeTogTWV0cmljRW50cnk8QT4gfCB1bmRlZmluZWQ7XG5cbiAgICAvLyBUcnkgbG9va3VwIGV4aXN0aW5nIGJ5IGlkIGlmIHdlIGhhdmUgb25lXG4gICAgaWYgKGlkKSB7XG4gICAgICBleGlzdGluZ0VudHJ5ID0gdGhpcy5tZXRyaWNCeUlkLmdldChpZCk7XG4gICAgICBpZiAoZXhpc3RpbmdFbnRyeSAmJiBtZXRyaWNLZXkoZXhpc3RpbmdFbnRyeS5tZXRyaWMpICE9PSBrZXkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgaGF2ZSB0d28gZGlmZmVyZW50IG1ldHJpY3Mgc2hhcmUgdGhlIHNhbWUgaWQgKCcke2lkfScpIGluIG9uZSBBbGFybSBvciBHcmFwaC4gUmVuYW1lIG9uZSBvZiB0aGVtLmApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghZXhpc3RpbmdFbnRyeSkge1xuICAgICAgLy8gVHJ5IGxvb2t1cCBieSBtZXRyaWMgaWYgd2UgZGlkbid0IGZpbmQgb25lIGJ5IGlkXG4gICAgICBleGlzdGluZ0VudHJ5ID0gdGhpcy5tZXRyaWNCeUtleS5nZXQoa2V5KTtcblxuICAgICAgLy8gSWYgdGhlIG9uZSB3ZSBmb3VuZCBhbHJlYWR5IGhhcyBhbiBpZCwgaXQgbXVzdCBiZSBkaWZmZXJlbnQgZnJvbSB0aGUgaWRcbiAgICAgIC8vIHdlJ3JlIHRyeWluZyB0byBhZGQgYW5kIHdlIHdhbnQgdG8gYWRkIGEgbmV3IG1ldHJpYy4gUHJldGVuZCB3ZSBkaWRuJ3RcbiAgICAgIC8vIGZpbmQgb25lLlxuICAgICAgaWYgKGV4aXN0aW5nRW50cnk/LmlkICYmIGlkKSB7IGV4aXN0aW5nRW50cnkgPSB1bmRlZmluZWQ7IH1cbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgYSBuZXcgZW50cnkgaWYgd2UgZGlkbid0IGZpbmQgb25lIHNvIGZhclxuICAgIGxldCBlbnRyeTtcbiAgICBpZiAoZXhpc3RpbmdFbnRyeSkge1xuICAgICAgZW50cnkgPSBleGlzdGluZ0VudHJ5O1xuICAgIH0gZWxzZSB7XG4gICAgICBlbnRyeSA9IHsgbWV0cmljIH07XG4gICAgICB0aGlzLm1ldHJpY3MucHVzaChlbnRyeSk7XG4gICAgICB0aGlzLm1ldHJpY0J5S2V5LnNldChrZXksIGVudHJ5KTtcbiAgICB9XG5cbiAgICAvLyBJZiBpdCBkaWRuJ3QgaGF2ZSBhbiBpZCBidXQgbm93IHdlIGRvLCBhZGQgb25lXG4gICAgaWYgKCFlbnRyeS5pZCAmJiBpZCkge1xuICAgICAgZW50cnkuaWQgPSBpZDtcbiAgICAgIHRoaXMubWV0cmljQnlJZC5zZXQoaWQsIGVudHJ5KTtcbiAgICB9XG5cbiAgICAvLyBJZiBpdCBkaWRuJ3QgaGF2ZSBhIHRhZyBidXQgbm93IHdlIGRvLCBhZGQgb25lXG4gICAgaWYgKCFlbnRyeS50YWcgJiYgdGFnKSB7XG4gICAgICBlbnRyeS50YWcgPSB0YWc7XG4gICAgfVxuXG4gICAgLy8gUmVjdXJzZSBhbmQgYWRkIGNoaWxkcmVuXG4gICAgY29uc3QgY29uZiA9IG1ldHJpYy50b01ldHJpY0NvbmZpZygpO1xuICAgIGlmIChjb25mLm1hdGhFeHByZXNzaW9uKSB7XG4gICAgICBmb3IgKGNvbnN0IFtzdWJJZCwgc3ViTWV0cmljXSBvZiBPYmplY3QuZW50cmllcyhjb25mLm1hdGhFeHByZXNzaW9uLnVzaW5nTWV0cmljcykpIHtcbiAgICAgICAgdGhpcy5hZGRPbmUoc3ViTWV0cmljLCB1bmRlZmluZWQsIHN1YklkKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiJdfQ== |
\ | No newline at end of file |