cdk8s-plus-34 0.0.1 → 2.0.0
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.
- package/.jsii +101649 -0
- package/CODE_OF_CONDUCT.md +3 -0
- package/CONTRIBUTING.md +185 -0
- package/DCO +34 -0
- package/LICENSE +202 -0
- package/NOTICE +1 -0
- package/OWNERS.md +5 -0
- package/README.md +21 -33
- package/SECURITY.md +5 -0
- package/cdk8s.yaml +11 -0
- package/docs/java.md +150009 -0
- package/docs/plus/config-map.md +98 -0
- package/docs/plus/container.md +133 -0
- package/docs/plus/cronjob.md +67 -0
- package/docs/plus/deployment.md +232 -0
- package/docs/plus/horizontal-pod-autoscaler.md +226 -0
- package/docs/plus/ingress.md +68 -0
- package/docs/plus/job.md +48 -0
- package/docs/plus/namespace.md +58 -0
- package/docs/plus/network-policy.md +341 -0
- package/docs/plus/pod.md +455 -0
- package/docs/plus/pv.md +82 -0
- package/docs/plus/pvc.md +77 -0
- package/docs/plus/rbac.md +104 -0
- package/docs/plus/secret.md +32 -0
- package/docs/plus/service-account.md +35 -0
- package/docs/plus/service.md +41 -0
- package/docs/plus/volume.md +84 -0
- package/docs/python.md +161196 -0
- package/docs/typescript.md +139649 -0
- package/git-hooks/README.md +9 -0
- package/git-hooks/prepare-commit-msg +18 -0
- package/git-hooks/setup.sh +10 -0
- package/lib/_action.d.ts +26 -0
- package/lib/_action.js +39 -0
- package/lib/api-resource.d.ts +298 -0
- package/lib/api-resource.js +430 -0
- package/lib/base.d.ts +79 -0
- package/lib/base.js +92 -0
- package/lib/config-map.d.ts +126 -0
- package/lib/config-map.js +159 -0
- package/lib/container.d.ts +1057 -0
- package/lib/container.js +845 -0
- package/lib/cron-job.d.ts +138 -0
- package/lib/cron-job.js +103 -0
- package/lib/daemon-set.d.ts +45 -0
- package/lib/daemon-set.js +55 -0
- package/lib/deployment.d.ts +235 -0
- package/lib/deployment.js +216 -0
- package/lib/handler.d.ts +62 -0
- package/lib/handler.js +54 -0
- package/lib/horizontal-pod-autoscaler.d.ts +500 -0
- package/lib/horizontal-pod-autoscaler.js +569 -0
- package/lib/imports/k8s.d.ts +25809 -0
- package/lib/imports/k8s.js +19238 -0
- package/lib/index.d.ts +26 -0
- package/lib/index.js +44 -0
- package/lib/ingress.d.ts +230 -0
- package/lib/ingress.js +246 -0
- package/lib/job.d.ts +64 -0
- package/lib/job.js +54 -0
- package/lib/namespace.d.ts +128 -0
- package/lib/namespace.js +109 -0
- package/lib/network-policy.d.ts +311 -0
- package/lib/network-policy.js +344 -0
- package/lib/pod.d.ts +1097 -0
- package/lib/pod.js +1147 -0
- package/lib/probe.d.ts +181 -0
- package/lib/probe.js +88 -0
- package/lib/pv.d.ts +375 -0
- package/lib/pv.js +273 -0
- package/lib/pvc.d.ts +163 -0
- package/lib/pvc.js +154 -0
- package/lib/role-binding.d.ts +138 -0
- package/lib/role-binding.js +165 -0
- package/lib/role.d.ts +268 -0
- package/lib/role.js +401 -0
- package/lib/secret.d.ts +195 -0
- package/lib/secret.js +185 -0
- package/lib/service-account.d.ts +83 -0
- package/lib/service-account.js +105 -0
- package/lib/service.d.ts +289 -0
- package/lib/service.js +182 -0
- package/lib/stateful-set.d.ts +206 -0
- package/lib/stateful-set.js +244 -0
- package/lib/utils.d.ts +4 -0
- package/lib/utils.js +33 -0
- package/lib/volume.d.ts +577 -0
- package/lib/volume.js +377 -0
- package/lib/workload.d.ts +121 -0
- package/lib/workload.js +122 -0
- package/node_modules/balanced-match/.github/FUNDING.yml +2 -0
- package/node_modules/balanced-match/LICENSE.md +21 -0
- package/node_modules/balanced-match/README.md +97 -0
- package/node_modules/balanced-match/index.js +62 -0
- package/node_modules/balanced-match/package.json +48 -0
- package/node_modules/brace-expansion/.github/FUNDING.yml +2 -0
- package/node_modules/brace-expansion/LICENSE +21 -0
- package/node_modules/brace-expansion/README.md +135 -0
- package/node_modules/brace-expansion/index.js +202 -0
- package/node_modules/brace-expansion/package.json +49 -0
- package/node_modules/minimatch/LICENSE +15 -0
- package/node_modules/minimatch/README.md +491 -0
- package/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts +2 -0
- package/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts.map +1 -0
- package/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js +14 -0
- package/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js.map +1 -0
- package/node_modules/minimatch/dist/commonjs/ast.d.ts +20 -0
- package/node_modules/minimatch/dist/commonjs/ast.d.ts.map +1 -0
- package/node_modules/minimatch/dist/commonjs/ast.js +747 -0
- package/node_modules/minimatch/dist/commonjs/ast.js.map +1 -0
- package/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts +8 -0
- package/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts.map +1 -0
- package/node_modules/minimatch/dist/commonjs/brace-expressions.js +152 -0
- package/node_modules/minimatch/dist/commonjs/brace-expressions.js.map +1 -0
- package/node_modules/minimatch/dist/commonjs/escape.d.ts +12 -0
- package/node_modules/minimatch/dist/commonjs/escape.d.ts.map +1 -0
- package/node_modules/minimatch/dist/commonjs/escape.js +22 -0
- package/node_modules/minimatch/dist/commonjs/escape.js.map +1 -0
- package/node_modules/minimatch/dist/commonjs/index.d.ts +98 -0
- package/node_modules/minimatch/dist/commonjs/index.d.ts.map +1 -0
- package/node_modules/minimatch/dist/commonjs/index.js +1023 -0
- package/node_modules/minimatch/dist/commonjs/index.js.map +1 -0
- package/node_modules/minimatch/dist/commonjs/package.json +3 -0
- package/node_modules/minimatch/dist/commonjs/unescape.d.ts +17 -0
- package/node_modules/minimatch/dist/commonjs/unescape.d.ts.map +1 -0
- package/node_modules/minimatch/dist/commonjs/unescape.js +24 -0
- package/node_modules/minimatch/dist/commonjs/unescape.js.map +1 -0
- package/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts +2 -0
- package/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts.map +1 -0
- package/node_modules/minimatch/dist/esm/assert-valid-pattern.js +10 -0
- package/node_modules/minimatch/dist/esm/assert-valid-pattern.js.map +1 -0
- package/node_modules/minimatch/dist/esm/ast.d.ts +20 -0
- package/node_modules/minimatch/dist/esm/ast.d.ts.map +1 -0
- package/node_modules/minimatch/dist/esm/ast.js +743 -0
- package/node_modules/minimatch/dist/esm/ast.js.map +1 -0
- package/node_modules/minimatch/dist/esm/brace-expressions.d.ts +8 -0
- package/node_modules/minimatch/dist/esm/brace-expressions.d.ts.map +1 -0
- package/node_modules/minimatch/dist/esm/brace-expressions.js +148 -0
- package/node_modules/minimatch/dist/esm/brace-expressions.js.map +1 -0
- package/node_modules/minimatch/dist/esm/escape.d.ts +12 -0
- package/node_modules/minimatch/dist/esm/escape.d.ts.map +1 -0
- package/node_modules/minimatch/dist/esm/escape.js +18 -0
- package/node_modules/minimatch/dist/esm/escape.js.map +1 -0
- package/node_modules/minimatch/dist/esm/index.d.ts +98 -0
- package/node_modules/minimatch/dist/esm/index.d.ts.map +1 -0
- package/node_modules/minimatch/dist/esm/index.js +1007 -0
- package/node_modules/minimatch/dist/esm/index.js.map +1 -0
- package/node_modules/minimatch/dist/esm/package.json +3 -0
- package/node_modules/minimatch/dist/esm/unescape.d.ts +17 -0
- package/node_modules/minimatch/dist/esm/unescape.d.ts.map +1 -0
- package/node_modules/minimatch/dist/esm/unescape.js +20 -0
- package/node_modules/minimatch/dist/esm/unescape.js.map +1 -0
- package/node_modules/minimatch/package.json +82 -0
- package/package.json +176 -6
- package/rotate.md +85 -0
|
@@ -0,0 +1,569 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a, _b, _c, _d;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.Replicas = exports.ScalingStrategy = exports.MetricTarget = exports.Metric = exports.HorizontalPodAutoscaler = void 0;
|
|
5
|
+
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
6
|
+
const cdk8s_1 = require("cdk8s");
|
|
7
|
+
const base_1 = require("./base");
|
|
8
|
+
const k8s = require("./imports/k8s");
|
|
9
|
+
/**
|
|
10
|
+
* A HorizontalPodAutoscaler scales a workload up or down in response to a metric
|
|
11
|
+
* change. This allows your services to scale up when demand is high and scale down
|
|
12
|
+
* when they are no longer needed.
|
|
13
|
+
*
|
|
14
|
+
*
|
|
15
|
+
* Typical use cases for HorizontalPodAutoscaler:
|
|
16
|
+
*
|
|
17
|
+
* * When Memory usage is above 70%, scale up the number of replicas to meet the demand.
|
|
18
|
+
* * When CPU usage is below 30%, scale down the number of replicas to save resources.
|
|
19
|
+
* * When a service is experiencing a spike in traffic, scale up the number of replicas
|
|
20
|
+
* to meet the demand. Then, when the traffic subsides, scale down the number of
|
|
21
|
+
* replicas to save resources.
|
|
22
|
+
*
|
|
23
|
+
* The autoscaler uses the following algorithm to determine the number of replicas to scale:
|
|
24
|
+
*
|
|
25
|
+
* `desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]`
|
|
26
|
+
*
|
|
27
|
+
* HorizontalPodAutoscaler's can be used to with any `Scalable` workload:
|
|
28
|
+
* * Deployment
|
|
29
|
+
* * StatefulSet
|
|
30
|
+
*
|
|
31
|
+
* **Targets that already have a replica count defined:**
|
|
32
|
+
*
|
|
33
|
+
* Remove any replica counts from the target resource before associating with a
|
|
34
|
+
* HorizontalPodAutoscaler. If this isn't done, then any time a change to that object is applied,
|
|
35
|
+
* Kubernetes will scale the current number of Pods to the value of the target.replicas key. This
|
|
36
|
+
* may not be desired and could lead to unexpected behavior.
|
|
37
|
+
*
|
|
38
|
+
* @see https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#implicit-maintenance-mode-deactivation
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* const backend = new kplus.Deployment(this, 'Backend', ...);
|
|
42
|
+
*
|
|
43
|
+
* const hpa = new kplus.HorizontalPodAutoscaler(chart, 'Hpa', {
|
|
44
|
+
* target: backend,
|
|
45
|
+
* maxReplicas: 10,
|
|
46
|
+
* scaleUp: {
|
|
47
|
+
* policies: [
|
|
48
|
+
* {
|
|
49
|
+
* replicas: kplus.Replicas.absolute(3),
|
|
50
|
+
* duration: Duration.minutes(5),
|
|
51
|
+
* },
|
|
52
|
+
* ],
|
|
53
|
+
* },
|
|
54
|
+
* });
|
|
55
|
+
*/
|
|
56
|
+
class HorizontalPodAutoscaler extends base_1.Resource {
|
|
57
|
+
constructor(scope, id, props) {
|
|
58
|
+
super(scope, id);
|
|
59
|
+
this.resourceType = 'horizontalpodautoscaler';
|
|
60
|
+
this._defaultScalingDuration = cdk8s_1.Duration.seconds(15);
|
|
61
|
+
this.apiObject = new k8s.KubeHorizontalPodAutoscalerV2(this, 'Resource', {
|
|
62
|
+
metadata: props.metadata,
|
|
63
|
+
spec: cdk8s_1.Lazy.any({ produce: () => this._toKube() }),
|
|
64
|
+
});
|
|
65
|
+
if (props?.minReplicas && props.minReplicas > props.maxReplicas) {
|
|
66
|
+
throw new Error(`'minReplicas' (${props.minReplicas}) must be less than or equal to 'maxReplicas' (${props.maxReplicas}) in order for HorizontalPodAutoscaler to scale.`);
|
|
67
|
+
}
|
|
68
|
+
if (props?.scaleUp?.stabilizationWindow !== undefined) {
|
|
69
|
+
this._validateStabilizationWindow('scaleUp', props.scaleUp.stabilizationWindow);
|
|
70
|
+
}
|
|
71
|
+
if (props?.scaleDown?.stabilizationWindow !== undefined) {
|
|
72
|
+
this._validateStabilizationWindow('scaleDown', props.scaleDown.stabilizationWindow);
|
|
73
|
+
}
|
|
74
|
+
if (props?.scaleUp?.policies?.length) {
|
|
75
|
+
this._validateScalingPolicies('scaleUp', props.scaleUp.policies);
|
|
76
|
+
}
|
|
77
|
+
if (props?.scaleDown?.policies?.length) {
|
|
78
|
+
this._validateScalingPolicies('scaleDown', props.scaleDown.policies);
|
|
79
|
+
}
|
|
80
|
+
this.target = props.target;
|
|
81
|
+
this.target.markHasAutoscaler();
|
|
82
|
+
this.maxReplicas = props.maxReplicas;
|
|
83
|
+
this.minReplicas = props.minReplicas ?? 1;
|
|
84
|
+
this.metrics = props.metrics;
|
|
85
|
+
this.scaleUp = {
|
|
86
|
+
strategy: ScalingStrategy.MAX_CHANGE,
|
|
87
|
+
stabilizationWindow: cdk8s_1.Duration.seconds(0),
|
|
88
|
+
...props.scaleUp,
|
|
89
|
+
policies: props.scaleUp?.policies?.map((p) => ({ duration: this._defaultScalingDuration, ...p })) ?? [
|
|
90
|
+
{
|
|
91
|
+
replicas: Replicas.absolute(4),
|
|
92
|
+
duration: cdk8s_1.Duration.minutes(1),
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
replicas: Replicas.percent(200),
|
|
96
|
+
duration: cdk8s_1.Duration.minutes(1),
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
};
|
|
100
|
+
if (props?.scaleUp?.policies?.length) {
|
|
101
|
+
this._validateScalingPolicies('scaleUp', props.scaleUp.policies);
|
|
102
|
+
}
|
|
103
|
+
this.scaleDown = {
|
|
104
|
+
strategy: ScalingStrategy.MAX_CHANGE,
|
|
105
|
+
stabilizationWindow: cdk8s_1.Duration.minutes(5),
|
|
106
|
+
...props.scaleDown,
|
|
107
|
+
policies: props.scaleDown?.policies?.map((p) => ({ duration: this._defaultScalingDuration, ...p })) ?? [
|
|
108
|
+
{
|
|
109
|
+
replicas: Replicas.absolute(this.minReplicas),
|
|
110
|
+
duration: cdk8s_1.Duration.minutes(5),
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
};
|
|
114
|
+
this.node.addValidation({ validate: () => this._validateTargetReplicas() });
|
|
115
|
+
this.node.addValidation({ validate: () => this._validateTargetContainers() });
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Validate a list of scaling policies.
|
|
119
|
+
* @internal
|
|
120
|
+
*/
|
|
121
|
+
_validateScalingPolicies(direction, policies) {
|
|
122
|
+
policies.forEach((p) => {
|
|
123
|
+
if (p.duration !== undefined) {
|
|
124
|
+
this._validateScalingPolicyDuration(direction, p.duration);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Validate `ScalingPolicy.duration` is within the allowed range.
|
|
130
|
+
*
|
|
131
|
+
* `duration` range: 1 second - 30 min
|
|
132
|
+
*
|
|
133
|
+
* Kubernetes name: `ScalingPolicy.periodSeconds`.
|
|
134
|
+
* @see https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/horizontal-pod-autoscaler-v2/#HorizontalPodAutoscalerSpec
|
|
135
|
+
* @internal
|
|
136
|
+
*/
|
|
137
|
+
_validateScalingPolicyDuration(direction, duration) {
|
|
138
|
+
const periodSeconds = duration.toSeconds() ?? 15;
|
|
139
|
+
const isWithinRange = Boolean(0 < periodSeconds && periodSeconds <= 1800);
|
|
140
|
+
if (!isWithinRange) {
|
|
141
|
+
throw new Error(`'${direction}.policies' duration (${duration.toHumanString()}) is outside of the allowed range. Must be at least 1 second long and no longer than 30 minutes.`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Validate `ScalingRules.stabilizationWindow` is within the allowed range.
|
|
146
|
+
*
|
|
147
|
+
* `stabilizationWindow` range: 0 seconds - 1 hour
|
|
148
|
+
*
|
|
149
|
+
* @see https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/horizontal-pod-autoscaler-v2/#HorizontalPodAutoscalerSpec
|
|
150
|
+
* @internal
|
|
151
|
+
*/
|
|
152
|
+
_validateStabilizationWindow(direction, window) {
|
|
153
|
+
const windowSeconds = window.toSeconds();
|
|
154
|
+
const isWithinRange = Boolean(0 <= windowSeconds && windowSeconds <= 3600);
|
|
155
|
+
if (!isWithinRange) {
|
|
156
|
+
throw new Error(`'${direction}.stabilizationWindow' (${window.toHumanString()}) must be 0 seconds or more with a max of 1 hour.`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Guarantee the HPA has a metric to scale on.
|
|
161
|
+
* Verify that metrics are configured, if not check every pod container has a resource limit or
|
|
162
|
+
* request defined.
|
|
163
|
+
* @internal
|
|
164
|
+
*/
|
|
165
|
+
_validateTargetContainers() {
|
|
166
|
+
const containers = this.target.toScalingTarget().containers;
|
|
167
|
+
const hasResourceConstraints = containers.some((c) => this._hasRequestsOrLimits(c));
|
|
168
|
+
if (!hasResourceConstraints && !this.metrics) {
|
|
169
|
+
return ['If HorizontalPodAutoscaler does not have metrics defined, then every container in the target must have a CPU or memory resource constraint defined.'];
|
|
170
|
+
}
|
|
171
|
+
return [];
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Prevent the HPA from scaling a target with a replica count defined.
|
|
175
|
+
* @see https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#implicit-maintenance-mode-deactivation
|
|
176
|
+
* @internal
|
|
177
|
+
*/
|
|
178
|
+
_validateTargetReplicas() {
|
|
179
|
+
const replicas = this.target.toScalingTarget().replicas;
|
|
180
|
+
if (replicas) {
|
|
181
|
+
return [
|
|
182
|
+
`HorizontalPodAutoscaler target cannot have a fixed number of replicas (${replicas}).`,
|
|
183
|
+
];
|
|
184
|
+
}
|
|
185
|
+
return [];
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Validate that the container has at least one CPU/memory request/limit defined.
|
|
189
|
+
* @internal
|
|
190
|
+
*/
|
|
191
|
+
_hasRequestsOrLimits(c) {
|
|
192
|
+
const hasRequests = c.resources?.cpu?.request || c.resources?.memory?.request;
|
|
193
|
+
const hasLimits = c.resources?.cpu?.limit || c.resources?.memory?.limit;
|
|
194
|
+
return Boolean(hasRequests || hasLimits);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* @internal
|
|
198
|
+
*/
|
|
199
|
+
_toKube() {
|
|
200
|
+
const scalingTarget = this.target.toScalingTarget();
|
|
201
|
+
return {
|
|
202
|
+
maxReplicas: this.maxReplicas,
|
|
203
|
+
minReplicas: this.minReplicas,
|
|
204
|
+
scaleTargetRef: {
|
|
205
|
+
apiVersion: scalingTarget.apiVersion,
|
|
206
|
+
name: scalingTarget.name,
|
|
207
|
+
kind: scalingTarget.kind,
|
|
208
|
+
},
|
|
209
|
+
metrics: this.metrics?.map(m => m._toKube()),
|
|
210
|
+
behavior: {
|
|
211
|
+
scaleUp: {
|
|
212
|
+
policies: this.scaleUp.policies?.map((p) => ({
|
|
213
|
+
...p.replicas._toKube(),
|
|
214
|
+
periodSeconds: p.duration?.toSeconds() ?? this._defaultScalingDuration.toSeconds(),
|
|
215
|
+
})),
|
|
216
|
+
selectPolicy: this.scaleUp.strategy,
|
|
217
|
+
stabilizationWindowSeconds: this.scaleUp.stabilizationWindow?.toSeconds(),
|
|
218
|
+
},
|
|
219
|
+
scaleDown: {
|
|
220
|
+
policies: this.scaleDown.policies?.map((p) => ({
|
|
221
|
+
...p.replicas._toKube(),
|
|
222
|
+
periodSeconds: p.duration?.toSeconds() ?? this._defaultScalingDuration.toSeconds(),
|
|
223
|
+
})),
|
|
224
|
+
selectPolicy: this.scaleDown.strategy,
|
|
225
|
+
stabilizationWindowSeconds: this.scaleDown.stabilizationWindow?.toSeconds(),
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
exports.HorizontalPodAutoscaler = HorizontalPodAutoscaler;
|
|
232
|
+
_a = JSII_RTTI_SYMBOL_1;
|
|
233
|
+
HorizontalPodAutoscaler[_a] = { fqn: "cdk8s-plus-34.HorizontalPodAutoscaler", version: "2.0.0" };
|
|
234
|
+
/**
|
|
235
|
+
* A metric condition that HorizontalPodAutoscaler's scale on.
|
|
236
|
+
*/
|
|
237
|
+
class Metric {
|
|
238
|
+
/**
|
|
239
|
+
* Metric that tracks the CPU of a container. This metric
|
|
240
|
+
* will be tracked across all pods of the current scale target.
|
|
241
|
+
*
|
|
242
|
+
*/
|
|
243
|
+
static containerCpu(options) {
|
|
244
|
+
return new Metric({
|
|
245
|
+
type: 'ContainerResource',
|
|
246
|
+
containerResource: {
|
|
247
|
+
name: 'cpu',
|
|
248
|
+
container: options.container.name,
|
|
249
|
+
target: options.target._toKube(),
|
|
250
|
+
},
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Metric that tracks the Memory of a container. This metric
|
|
255
|
+
* will be tracked across all pods of the current scale target.
|
|
256
|
+
*
|
|
257
|
+
*/
|
|
258
|
+
static containerMemory(options) {
|
|
259
|
+
return new Metric({
|
|
260
|
+
type: 'ContainerResource',
|
|
261
|
+
containerResource: {
|
|
262
|
+
name: 'memory',
|
|
263
|
+
container: options.container.name,
|
|
264
|
+
target: options.target._toKube(),
|
|
265
|
+
},
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Metric that tracks the volume size of a container. This metric
|
|
270
|
+
* will be tracked across all pods of the current scale target.
|
|
271
|
+
*
|
|
272
|
+
*/
|
|
273
|
+
static containerStorage(options) {
|
|
274
|
+
return new Metric({
|
|
275
|
+
type: 'ContainerResource',
|
|
276
|
+
containerResource: {
|
|
277
|
+
name: 'storage',
|
|
278
|
+
container: options.container.name,
|
|
279
|
+
target: options.target._toKube(),
|
|
280
|
+
},
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Metric that tracks the local ephemeral storage of a container. This metric
|
|
285
|
+
* will be tracked across all pods of the current scale target.
|
|
286
|
+
*
|
|
287
|
+
*/
|
|
288
|
+
static containerEphemeralStorage(options) {
|
|
289
|
+
return new Metric({
|
|
290
|
+
type: 'ContainerResource',
|
|
291
|
+
containerResource: {
|
|
292
|
+
name: 'ephemeral-storage',
|
|
293
|
+
container: options.container.name,
|
|
294
|
+
target: options.target._toKube(),
|
|
295
|
+
},
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* A global metric that is not associated with any Kubernetes object.
|
|
300
|
+
* Allows for autoscaling based on information coming from components running outside of
|
|
301
|
+
* the cluster.
|
|
302
|
+
*
|
|
303
|
+
* Use case:
|
|
304
|
+
* * Scale up when the length of an SQS queue is greater than 10 messages.
|
|
305
|
+
* * Scale down when an outside load balancer's queries are less than 10000 per second.
|
|
306
|
+
*/
|
|
307
|
+
static external(options) {
|
|
308
|
+
return new Metric({
|
|
309
|
+
type: 'External',
|
|
310
|
+
external: {
|
|
311
|
+
metric: {
|
|
312
|
+
name: options.name,
|
|
313
|
+
selector: options.labelSelector?._toKube(),
|
|
314
|
+
},
|
|
315
|
+
target: options.target._toKube(),
|
|
316
|
+
},
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Metric that describes a metric of a kubernetes object
|
|
321
|
+
*
|
|
322
|
+
* Use case:
|
|
323
|
+
* * Scale on a Kubernetes Ingress's hits-per-second metric.
|
|
324
|
+
*/
|
|
325
|
+
static object(options) {
|
|
326
|
+
return new Metric({
|
|
327
|
+
type: 'Object',
|
|
328
|
+
object: {
|
|
329
|
+
describedObject: {
|
|
330
|
+
apiVersion: options.object.apiVersion,
|
|
331
|
+
kind: options.object.kind,
|
|
332
|
+
name: options.object.name,
|
|
333
|
+
},
|
|
334
|
+
metric: {
|
|
335
|
+
name: options.name,
|
|
336
|
+
selector: options.labelSelector?._toKube(),
|
|
337
|
+
},
|
|
338
|
+
target: options.target._toKube(),
|
|
339
|
+
},
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* A pod metric that will be averaged across all pods of the current scale target.
|
|
344
|
+
*
|
|
345
|
+
* Use case:
|
|
346
|
+
* * Average CPU utilization across all pods
|
|
347
|
+
* * Transactions processed per second across all pods
|
|
348
|
+
*/
|
|
349
|
+
static pods(options) {
|
|
350
|
+
return new Metric({
|
|
351
|
+
type: 'Pods',
|
|
352
|
+
pods: {
|
|
353
|
+
metric: {
|
|
354
|
+
name: options.name,
|
|
355
|
+
selector: options.labelSelector?._toKube(),
|
|
356
|
+
},
|
|
357
|
+
target: options.target._toKube(),
|
|
358
|
+
},
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Tracks the available CPU of the pods in a target.
|
|
363
|
+
*
|
|
364
|
+
* Note: Since the resource usages of all the containers are summed up the total
|
|
365
|
+
* pod utilization may not accurately represent the individual container resource
|
|
366
|
+
* usage. This could lead to situations where a single container might be running
|
|
367
|
+
* with high usage and the HPA will not scale out because the overall pod usage
|
|
368
|
+
* is still within acceptable limits.
|
|
369
|
+
*
|
|
370
|
+
* Use case:
|
|
371
|
+
* * Scale up when CPU is above 40%.
|
|
372
|
+
*/
|
|
373
|
+
static resourceCpu(target) {
|
|
374
|
+
return new Metric({
|
|
375
|
+
type: 'Resource',
|
|
376
|
+
resource: {
|
|
377
|
+
name: 'cpu',
|
|
378
|
+
target: target._toKube(),
|
|
379
|
+
},
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Tracks the available Memory of the pods in a target.
|
|
384
|
+
*
|
|
385
|
+
* Note: Since the resource usages of all the containers are summed up the total
|
|
386
|
+
* pod utilization may not accurately represent the individual container resource
|
|
387
|
+
* usage. This could lead to situations where a single container might be running
|
|
388
|
+
* with high usage and the HPA will not scale out because the overall pod usage
|
|
389
|
+
* is still within acceptable limits.
|
|
390
|
+
*
|
|
391
|
+
* Use case:
|
|
392
|
+
* * Scale up when Memory is above 512MB.
|
|
393
|
+
*/
|
|
394
|
+
static resourceMemory(target) {
|
|
395
|
+
return new Metric({
|
|
396
|
+
type: 'Resource',
|
|
397
|
+
resource: {
|
|
398
|
+
name: 'memory',
|
|
399
|
+
target: target._toKube(),
|
|
400
|
+
},
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Tracks the available Storage of the pods in a target.
|
|
405
|
+
*
|
|
406
|
+
* Note: Since the resource usages of all the containers are summed up the total
|
|
407
|
+
* pod utilization may not accurately represent the individual container resource
|
|
408
|
+
* usage. This could lead to situations where a single container might be running
|
|
409
|
+
* with high usage and the HPA will not scale out because the overall pod usage
|
|
410
|
+
* is still within acceptable limits.
|
|
411
|
+
*
|
|
412
|
+
*/
|
|
413
|
+
static resourceStorage(target) {
|
|
414
|
+
return new Metric({
|
|
415
|
+
type: 'Resource',
|
|
416
|
+
resource: {
|
|
417
|
+
name: 'storage',
|
|
418
|
+
target: target._toKube(),
|
|
419
|
+
},
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Tracks the available Ephemeral Storage of the pods in a target.
|
|
424
|
+
*
|
|
425
|
+
* Note: Since the resource usages of all the containers are summed up the total
|
|
426
|
+
* pod utilization may not accurately represent the individual container resource
|
|
427
|
+
* usage. This could lead to situations where a single container might be running
|
|
428
|
+
* with high usage and the HPA will not scale out because the overall pod usage
|
|
429
|
+
* is still within acceptable limits.
|
|
430
|
+
*
|
|
431
|
+
*/
|
|
432
|
+
static resourceEphemeralStorage(target) {
|
|
433
|
+
return new Metric({
|
|
434
|
+
type: 'Resource',
|
|
435
|
+
resource: {
|
|
436
|
+
name: 'ephemeral-storage',
|
|
437
|
+
target: target._toKube(),
|
|
438
|
+
},
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
constructor(metric) {
|
|
442
|
+
this.metric = metric;
|
|
443
|
+
this.type = metric.type;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* @internal
|
|
447
|
+
*/
|
|
448
|
+
_toKube() {
|
|
449
|
+
return this.metric;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
exports.Metric = Metric;
|
|
453
|
+
_b = JSII_RTTI_SYMBOL_1;
|
|
454
|
+
Metric[_b] = { fqn: "cdk8s-plus-34.Metric", version: "2.0.0" };
|
|
455
|
+
/**
|
|
456
|
+
* A metric condition that will trigger scaling behavior when satisfied.
|
|
457
|
+
*
|
|
458
|
+
* @example
|
|
459
|
+
*
|
|
460
|
+
* MetricTarget.averageUtilization(70); // 70% average utilization
|
|
461
|
+
*
|
|
462
|
+
*/
|
|
463
|
+
class MetricTarget {
|
|
464
|
+
/**
|
|
465
|
+
* Target a specific target value.
|
|
466
|
+
*
|
|
467
|
+
* @param value The target value.
|
|
468
|
+
*/
|
|
469
|
+
static value(value) {
|
|
470
|
+
return new MetricTarget({
|
|
471
|
+
type: 'Value',
|
|
472
|
+
value: k8s.Quantity.fromNumber(value),
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Target the average value across all relevant pods.
|
|
477
|
+
*
|
|
478
|
+
* @param averageValue The average metric value.
|
|
479
|
+
*/
|
|
480
|
+
static averageValue(averageValue) {
|
|
481
|
+
return new MetricTarget({
|
|
482
|
+
type: 'AverageValue',
|
|
483
|
+
averageValue: k8s.Quantity.fromNumber(averageValue),
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Target a percentage value across all relevant pods.
|
|
488
|
+
*
|
|
489
|
+
* @param averageUtilization The percentage of the utilization metric. e.g. `50` for 50%.
|
|
490
|
+
*/
|
|
491
|
+
static averageUtilization(averageUtilization) {
|
|
492
|
+
return new MetricTarget({
|
|
493
|
+
type: 'Utilization',
|
|
494
|
+
averageUtilization,
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
constructor(metric) {
|
|
498
|
+
this.metric = metric;
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* @internal
|
|
502
|
+
*/
|
|
503
|
+
_toKube() {
|
|
504
|
+
return this.metric;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
exports.MetricTarget = MetricTarget;
|
|
508
|
+
_c = JSII_RTTI_SYMBOL_1;
|
|
509
|
+
MetricTarget[_c] = { fqn: "cdk8s-plus-34.MetricTarget", version: "2.0.0" };
|
|
510
|
+
var ScalingStrategy;
|
|
511
|
+
(function (ScalingStrategy) {
|
|
512
|
+
/**
|
|
513
|
+
* Use the policy that provisions the most changes.
|
|
514
|
+
*/
|
|
515
|
+
ScalingStrategy["MAX_CHANGE"] = "Max";
|
|
516
|
+
/**
|
|
517
|
+
* Use the policy that provisions the least amount of changes.
|
|
518
|
+
*/
|
|
519
|
+
ScalingStrategy["MIN_CHANGE"] = "Min";
|
|
520
|
+
/**
|
|
521
|
+
* Disables scaling in this direction.
|
|
522
|
+
*
|
|
523
|
+
* @deprecated - Omit the ScalingRule instead
|
|
524
|
+
*/
|
|
525
|
+
ScalingStrategy["DISABLED"] = "Disabled";
|
|
526
|
+
})(ScalingStrategy || (exports.ScalingStrategy = ScalingStrategy = {}));
|
|
527
|
+
/**
|
|
528
|
+
* The amount of replicas that will change.
|
|
529
|
+
*/
|
|
530
|
+
class Replicas {
|
|
531
|
+
/**
|
|
532
|
+
* Changes the pods by a percentage of the it's current value.
|
|
533
|
+
*
|
|
534
|
+
* @param value The percentage of change to apply. Must be greater than 0.
|
|
535
|
+
*/
|
|
536
|
+
static percent(value) {
|
|
537
|
+
return new Replicas({
|
|
538
|
+
type: 'Percent',
|
|
539
|
+
value,
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Changes the pods by a percentage of the it's current value.
|
|
544
|
+
*
|
|
545
|
+
* @param value The amount of change to apply. Must be greater than 0.
|
|
546
|
+
*/
|
|
547
|
+
static absolute(value) {
|
|
548
|
+
return new Replicas({
|
|
549
|
+
type: 'Pods',
|
|
550
|
+
value,
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
constructor(replicas) {
|
|
554
|
+
this.replicas = replicas;
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* @internal
|
|
558
|
+
*/
|
|
559
|
+
_toKube() {
|
|
560
|
+
return {
|
|
561
|
+
type: this.replicas.type,
|
|
562
|
+
value: this.replicas.value,
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
exports.Replicas = Replicas;
|
|
567
|
+
_d = JSII_RTTI_SYMBOL_1;
|
|
568
|
+
Replicas[_d] = { fqn: "cdk8s-plus-34.Replicas", version: "2.0.0" };
|
|
569
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaG9yaXpvbnRhbC1wb2QtYXV0b3NjYWxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9ob3Jpem9udGFsLXBvZC1hdXRvc2NhbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsaUNBQWtEO0FBRWxELGlDQUE0RDtBQUU1RCxxQ0FBcUM7QUFvR3JDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBOENHO0FBQ0gsTUFBYSx1QkFBd0IsU0FBUSxlQUFRO0lBa0NuRCxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQW1DO1FBQzNFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUE5QkgsaUJBQVksR0FBRyx5QkFBeUIsQ0FBQztRQTBCeEMsNEJBQXVCLEdBQUcsZ0JBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7UUFNOUQsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLEdBQUcsQ0FBQyw2QkFBNkIsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFO1lBQ3ZFLFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUTtZQUN4QixJQUFJLEVBQUUsWUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQztTQUNsRCxDQUFDLENBQUM7UUFFSCxJQUFJLEtBQUssRUFBRSxXQUFXLElBQUksS0FBSyxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDaEUsTUFBTSxJQUFJLEtBQUssQ0FBQyxrQkFBa0IsS0FBSyxDQUFDLFdBQVcsa0RBQWtELEtBQUssQ0FBQyxXQUFXLGtEQUFrRCxDQUFDLENBQUM7UUFDNUssQ0FBQztRQUNELElBQUksS0FBSyxFQUFFLE9BQU8sRUFBRSxtQkFBbUIsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN0RCxJQUFJLENBQUMsNEJBQTRC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SUFDSSxPQUFPO1FBQ1osT0FBTztZQUNMLElBQUksRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUk7WUFDeEIsS0FBSyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSztTQUMzQixDQUFDO0lBQ0osQ0FBQzs7QUFwQ0gsNEJBcUNDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQXBpT2JqZWN0LCBEdXJhdGlvbiwgTGF6eSB9IGZyb20gJ2NkazhzJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgUmVzb3VyY2UsIFJlc291cmNlUHJvcHMsIElSZXNvdXJjZSB9IGZyb20gJy4vYmFzZSc7XG5pbXBvcnQgKiBhcyBjb250YWluZXIgZnJvbSAnLi9jb250YWluZXInO1xuaW1wb3J0ICogYXMgazhzIGZyb20gJy4vaW1wb3J0cy9rOHMnO1xuaW1wb3J0ICogYXMgcG9kIGZyb20gJy4vcG9kJztcblxuXG4vKipcbiAqIFByb3BlcnRpZXMgdXNlZCB0byBjb25maWd1cmUgdGhlIHRhcmdldCBvZiBhbiBBdXRvc2NhbGVyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNjYWxpbmdUYXJnZXQge1xuICAvKipcbiAgICogVGhlIG9iamVjdCBraW5kIChlLmcuIFwiRGVwbG95bWVudFwiKS5cbiAgICovXG4gIHJlYWRvbmx5IGtpbmQ6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBvYmplY3QncyBBUEkgdmVyc2lvbiAoZS5nLiBcImF1dGhvcml6YXRpb24uazhzLmlvL3YxXCIpXG4gICAqL1xuICByZWFkb25seSBhcGlWZXJzaW9uOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgS3ViZXJuZXRlcyBuYW1lIG9mIHRoaXMgcmVzb3VyY2UuXG4gICAqL1xuICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBDb250YWluZXIgZGVmaW5pdGlvbnMgYXNzb2NpYXRlZCB3aXRoIHRoZSB0YXJnZXQuXG4gICAqL1xuICByZWFkb25seSBjb250YWluZXJzOiBjb250YWluZXIuQ29udGFpbmVyW107XG4gIC8qKlxuICAgKiBUaGUgZml4ZWQgbnVtYmVyIG9mIHJlcGxpY2FzIGRlZmluZWQgb24gdGhlIHRhcmdldC4gVGhpcyBpcyB1c2VkXG4gICAqIGZvciB2YWxpZGF0aW9uIHB1cnBvc2VzIGFzIFNjYWxhYmxlIHRhcmdldHMgc2hvdWxkIG5vdCBoYXZlIGFcbiAgICogZml4ZWQgbnVtYmVyIG9mIHJlcGxpY2FzLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVwbGljYXM/OiBudW1iZXI7XG5cblxufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBzY2FsYWJsZSB3b3JrbG9hZC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJU2NhbGFibGUge1xuICAvKipcbiAgICogSWYgdGhpcyBpcyBhIHRhcmdldCBvZiBhbiBhdXRvc2NhbGVyLlxuICAgKi9cbiAgaGFzQXV0b3NjYWxlcjogYm9vbGVhbjtcbiAgLyoqXG4gICAqIENhbGxlZCBvbiBhbGwgSVNjYWxhYmxlIHRhcmdldHMgd2hlbiB0aGV5IGFyZSBhc3NvY2lhdGVkIHdpdGggYW4gYXV0b3NjYWxlci5cbiAgICovXG4gIG1hcmtIYXNBdXRvc2NhbGVyKCk6IHZvaWQ7XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIHRhcmdldCBzcGVjIHByb3BlcnRpZXMgb2YgdGhpcyBTY2FsYWJsZS5cbiAgICovXG4gIHRvU2NhbGluZ1RhcmdldCgpOiBTY2FsaW5nVGFyZ2V0O1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIEhvcml6b250YWxQb2RBdXRvc2NhbGVyXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSG9yaXpvbnRhbFBvZEF1dG9zY2FsZXJQcm9wcyBleHRlbmRzIFJlc291cmNlUHJvcHMge1xuICAvKipcbiAgICogVGhlIHdvcmtsb2FkIHRvIHNjYWxlIHVwIG9yIGRvd24uXG4gICAqXG4gICAqIFNjYWxhYmxlIHdvcmtsb2FkIHR5cGVzOlxuICAgKiAqIERlcGxveW1lbnRcbiAgICogKiBTdGF0ZWZ1bFNldFxuICAgKi9cbiAgcmVhZG9ubHkgdGFyZ2V0OiBJU2NhbGFibGU7XG4gIC8qKlxuICAgKiBUaGUgbWF4aW11bSBudW1iZXIgb2YgcmVwbGljYXMgdGhhdCBjYW4gYmUgc2NhbGVkIHVwIHRvLlxuICAgKi9cbiAgcmVhZG9ubHkgbWF4UmVwbGljYXM6IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBtaW5pbXVtIG51bWJlciBvZiByZXBsaWNhcyB0aGF0IGNhbiBiZSBzY2FsZWQgZG93biB0by5cbiAgICpcbiAgICogQ2FuIGJlIHNldCB0byAwIGlmIHRoZSBhbHBoYSBmZWF0dXJlIGdhdGUgYEhQQVNjYWxlVG9aZXJvYCBpcyBlbmFibGVkIGFuZFxuICAgKiBhdCBsZWFzdCBvbmUgT2JqZWN0IG9yIEV4dGVybmFsIG1ldHJpYyBpcyBjb25maWd1cmVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAxXG4gICAqL1xuICByZWFkb25seSBtaW5SZXBsaWNhcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBtZXRyaWMgY29uZGl0aW9ucyB0aGF0IHRyaWdnZXIgYSBzY2FsZSB1cCBvciBzY2FsZSBkb3duLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIElmIG1ldHJpY3MgYXJlIG5vdCBwcm92aWRlZCwgdGhlbiB0aGUgdGFyZ2V0IHJlc291cmNlXG4gICAqIGNvbnN0cmFpbnRzIChlLmcuIGNwdSBsaW1pdCkgd2lsbCBiZSB1c2VkIGFzIHNjYWxpbmcgbWV0cmljcy5cbiAgICovXG4gIHJlYWRvbmx5IG1ldHJpY3M/OiBNZXRyaWNbXTtcbiAgLyoqXG4gICAqIFRoZSBzY2FsaW5nIGJlaGF2aW9yIHdoZW4gc2NhbGluZyB1cC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBJcyB0aGUgaGlnaGVyIG9mOlxuICAgKiAqIEluY3JlYXNlIG5vIG1vcmUgdGhhbiA0IHBvZHMgcGVyIDYwIHNlY29uZHNcbiAgICogKiBEb3VibGUgdGhlIG51bWJlciBvZiBwb2RzIHBlciA2MCBzZWNvbmRzXG4gICAqL1xuICByZWFkb25seSBzY2FsZVVwPzogU2NhbGluZ1J1bGVzO1xuICAvKipcbiAgICogVGhlIHNjYWxpbmcgYmVoYXZpb3Igd2hlbiBzY2FsaW5nIGRvd24uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gU2NhbGUgZG93biB0byBtaW5SZXBsaWNhIGNvdW50IHdpdGggYSA1IG1pbnV0ZSBzdGFiaWxpemF0aW9uIHdpbmRvdy5cbiAgICovXG4gIHJlYWRvbmx5IHNjYWxlRG93bj86IFNjYWxpbmdSdWxlcztcbn1cblxuLyoqXG4gKiBBIEhvcml6b250YWxQb2RBdXRvc2NhbGVyIHNjYWxlcyBhIHdvcmtsb2FkIHVwIG9yIGRvd24gaW4gcmVzcG9uc2UgdG8gYSBtZXRyaWNcbiAqIGNoYW5nZS4gVGhpcyBhbGxvd3MgeW91ciBzZXJ2aWNlcyB0byBzY2FsZSB1cCB3aGVuIGRlbWFuZCBpcyBoaWdoIGFuZCBzY2FsZSBkb3duXG4gKiB3aGVuIHRoZXkgYXJlIG5vIGxvbmdlciBuZWVkZWQuXG4gKlxuICpcbiAqIFR5cGljYWwgdXNlIGNhc2VzIGZvciBIb3Jpem9udGFsUG9kQXV0b3NjYWxlcjpcbiAqXG4gKiAqIFdoZW4gTWVtb3J5IHVzYWdlIGlzIGFib3ZlIDcwJSwgc2NhbGUgdXAgdGhlIG51bWJlciBvZiByZXBsaWNhcyB0byBtZWV0IHRoZSBkZW1hbmQuXG4gKiAqIFdoZW4gQ1BVIHVzYWdlIGlzIGJlbG93IDMwJSwgc2NhbGUgZG93biB0aGUgbnVtYmVyIG9mIHJlcGxpY2FzIHRvIHNhdmUgcmVzb3VyY2VzLlxuICogKiBXaGVuIGEgc2VydmljZSBpcyBleHBlcmllbmNpbmcgYSBzcGlrZSBpbiB0cmFmZmljLCBzY2FsZSB1cCB0aGUgbnVtYmVyIG9mIHJlcGxpY2FzXG4gKiAgIHRvIG1lZXQgdGhlIGRlbWFuZC4gVGhlbiwgd2hlbiB0aGUgdHJhZmZpYyBzdWJzaWRlcywgc2NhbGUgZG93biB0aGUgbnVtYmVyIG9mXG4gKiAgIHJlcGxpY2FzIHRvIHNhdmUgcmVzb3VyY2VzLlxuICpcbiAqIFRoZSBhdXRvc2NhbGVyIHVzZXMgdGhlIGZvbGxvd2luZyBhbGdvcml0aG0gdG8gZGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgcmVwbGljYXMgdG8gc2NhbGU6XG4gKlxuICogYGRlc2lyZWRSZXBsaWNhcyA9IGNlaWxbY3VycmVudFJlcGxpY2FzICogKCBjdXJyZW50TWV0cmljVmFsdWUgLyBkZXNpcmVkTWV0cmljVmFsdWUgKV1gXG4gKlxuICogSG9yaXpvbnRhbFBvZEF1dG9zY2FsZXIncyBjYW4gYmUgdXNlZCB0byB3aXRoIGFueSBgU2NhbGFibGVgIHdvcmtsb2FkOlxuICogKiBEZXBsb3ltZW50XG4gKiAqIFN0YXRlZnVsU2V0XG4gKlxuICogKipUYXJnZXRzIHRoYXQgYWxyZWFkeSBoYXZlIGEgcmVwbGljYSBjb3VudCBkZWZpbmVkOioqXG4gKlxuICogUmVtb3ZlIGFueSByZXBsaWNhIGNvdW50cyBmcm9tIHRoZSB0YXJnZXQgcmVzb3VyY2UgYmVmb3JlIGFzc29jaWF0aW5nIHdpdGggYVxuICogSG9yaXpvbnRhbFBvZEF1dG9zY2FsZXIuIElmIHRoaXMgaXNuJ3QgZG9uZSwgdGhlbiBhbnkgdGltZSBhIGNoYW5nZSB0byB0aGF0IG9iamVjdCBpcyBhcHBsaWVkLFxuICogS3ViZXJuZXRlcyB3aWxsIHNjYWxlIHRoZSBjdXJyZW50IG51bWJlciBvZiBQb2RzIHRvIHRoZSB2YWx1ZSBvZiB0aGUgdGFyZ2V0LnJlcGxpY2FzIGtleS4gVGhpc1xuICogbWF5IG5vdCBiZSBkZXNpcmVkIGFuZCBjb3VsZCBsZWFkIHRvIHVuZXhwZWN0ZWQgYmVoYXZpb3IuXG4gKlxuICogQHNlZSBodHRwczovL2t1YmVybmV0ZXMuaW8vZG9jcy90YXNrcy9ydW4tYXBwbGljYXRpb24vaG9yaXpvbnRhbC1wb2QtYXV0b3NjYWxlLyNpbXBsaWNpdC1tYWludGVuYW5jZS1tb2RlLWRlYWN0aXZhdGlvblxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBiYWNrZW5kID0gbmV3IGtwbHVzLkRlcGxveW1lbnQodGhpcywgJ0JhY2tlbmQnLCAuLi4pO1xuICpcbiAqIGNvbnN0IGhwYSA9IG5ldyBrcGx1cy5Ib3Jpem9udGFsUG9kQXV0b3NjYWxlcihjaGFydCwgJ0hwYScsIHtcbiAqICB0YXJnZXQ6IGJhY2tlbmQsXG4gKiAgbWF4UmVwbGljYXM6IDEwLFxuICogIHNjYWxlVXA6IHtcbiAqICAgIHBvbGljaWVzOiBbXG4gKiAgICAgIHtcbiAqICAgICAgICByZXBsaWNhczoga3BsdXMuUmVwbGljYXMuYWJzb2x1dGUoMyksXG4gKiAgICAgICAgZHVyYXRpb246IER1cmF0aW9uLm1pbnV0ZXMoNSksXG4gKiAgICAgIH0sXG4gKiAgICBdLFxuICogIH0sXG4gKiB9KTtcbiAqL1xuZXhwb3J0IGNsYXNzIEhvcml6b250YWxQb2RBdXRvc2NhbGVyIGV4dGVuZHMgUmVzb3VyY2Uge1xuICAvKipcbiAqIEBzZWUgYmFzZS5SZXNvdXJjZS5hcGlPYmplY3RcbiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgYXBpT2JqZWN0OiBBcGlPYmplY3Q7XG4gIHB1YmxpYyByZWFkb25seSByZXNvdXJjZVR5cGUgPSAnaG9yaXpvbnRhbHBvZGF1dG9zY2FsZXInO1xuICAvKipcbiAgICogVGhlIHdvcmtsb2FkIHRvIHNjYWxlIHVwIG9yIGRvd24uXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdGFyZ2V0OiBJU2NhbGFibGU7XG4gIC8qKlxuICAgKiBUaGUgbWF4aW11bSBudW1iZXIgb2YgcmVwbGljYXMgdGhhdCBjYW4gYmUgc2NhbGVkIHVwIHRvLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IG1heFJlcGxpY2FzOiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgbWluaW11bSBudW1iZXIgb2YgcmVwbGljYXMgdGhhdCBjYW4gYmUgc2NhbGVkIGRvd24gdG8uXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbWluUmVwbGljYXM6IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBtZXRyaWMgY29uZGl0aW9ucyB0aGF0IHRyaWdnZXIgYSBzY2FsZSB1cCBvciBzY2FsZSBkb3duLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IG1ldHJpY3M/OiBNZXRyaWNbXTtcbiAgLyoqXG4gICAqIFRoZSBzY2FsaW5nIGJlaGF2aW9yIHdoZW4gc2NhbGluZyB1cC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBzY2FsZVVwOiBTY2FsaW5nUnVsZXM7XG4gIC8qKlxuICAgKiBUaGUgc2NhbGluZyBiZWhhdmlvciB3aGVuIHNjYWxpbmcgZG93bi5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBzY2FsZURvd246IFNjYWxpbmdSdWxlcztcblxuICBwcml2YXRlIHJlYWRvbmx5IF9kZWZhdWx0U2NhbGluZ0R1cmF0aW9uID0gRHVyYXRpb24uc2Vjb25kcygxNSk7XG5cblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogSG9yaXpvbnRhbFBvZEF1dG9zY2FsZXJQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICB0aGlzLmFwaU9iamVjdCA9IG5ldyBrOHMuS3ViZUhvcml6b250YWxQb2RBdXRvc2NhbGVyVjIodGhpcywgJ1Jlc291cmNlJywge1xuICAgICAgbWV0YWRhdGE6IHByb3BzLm1ldGFkYXRhLFxuICAgICAgc3BlYzogTGF6eS5hbnkoeyBwcm9kdWNlOiAoKSA9PiB0aGlzLl90b0t1YmUoKSB9KSxcbiAgICB9KTtcblxuICAgIGlmIChwcm9wcz8ubWluUmVwbGljYXMgJiYgcHJvcHMubWluUmVwbGljYXMgPiBwcm9wcy5tYXhSZXBsaWNhcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAnbWluUmVwbGljYXMnICgke3Byb3BzLm1pblJlcGxpY2FzfSkgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gJ21heFJlcGxpY2FzJyAoJHtwcm9wcy5tYXhSZXBsaWNhc30pIGluIG9yZGVyIGZvciBIb3Jpem9udGFsUG9kQXV0b3NjYWxlciB0byBzY2FsZS5gKTtcbiAgICB9XG4gICAgaWYgKHByb3BzPy5zY2FsZVVwPy5zdGFiaWxpemF0aW9uV2luZG93ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuX3ZhbGlkYXRlU3RhYmlsaXphdGlvbldpbmRvdygnc2NhbGVVcCcsIHByb3BzLnNjYWxlVXAuc3RhYmlsaXphdGlvbldpbmRvdyk7XG4gICAgfVxuICAgIGlmIChwcm9wcz8uc2NhbGVEb3duPy5zdGFiaWxpemF0aW9uV2luZG93ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuX3ZhbGlkYXRlU3RhYmlsaXphdGlvbldpbmRvdygnc2NhbGVEb3duJywgcHJvcHMuc2NhbGVEb3duLnN0YWJpbGl6YXRpb25XaW5kb3cpO1xuICAgIH1cbiAgICBpZiAocHJvcHM/LnNjYWxlVXA/LnBvbGljaWVzPy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuX3ZhbGlkYXRlU2NhbGluZ1BvbGljaWVzKCdzY2FsZVVwJywgcHJvcHMuc2NhbGVVcC5wb2xpY2llcyk7XG4gICAgfVxuICAgIGlmIChwcm9wcz8uc2NhbGVEb3duPy5wb2xpY2llcz8ubGVuZ3RoKSB7XG4gICAgICB0aGlzLl92YWxpZGF0ZVNjYWxpbmdQb2xpY2llcygnc2NhbGVEb3duJywgcHJvcHMuc2NhbGVEb3duLnBvbGljaWVzKTtcbiAgICB9XG5cbiAgICB0aGlzLnRhcmdldCA9IHByb3BzLnRhcmdldDtcbiAgICB0aGlzLnRhcmdldC5tYXJrSGFzQXV0b3NjYWxlcigpO1xuICAgIHRoaXMubWF4UmVwbGljYXMgPSBwcm9wcy5tYXhSZXBsaWNhcztcbiAgICB0aGlzLm1pblJlcGxpY2FzID0gcHJvcHMubWluUmVwbGljYXMgPz8gMTtcbiAgICB0aGlzLm1ldHJpY3MgPSBwcm9wcy5tZXRyaWNzO1xuICAgIHRoaXMuc2NhbGVVcCA9IHtcbiAgICAgIHN0cmF0ZWd5OiBTY2FsaW5nU3RyYXRlZ3kuTUFYX0NIQU5HRSxcbiAgICAgIHN0YWJpbGl6YXRpb25XaW5kb3c6IER1cmF0aW9uLnNlY29uZHMoMCksXG4gICAgICAuLi5wcm9wcy5zY2FsZVVwLFxuICAgICAgcG9saWNpZXM6IHByb3BzLnNjYWxlVXA/LnBvbGljaWVzPy5tYXAoKHApID0+ICh7IGR1cmF0aW9uOiB0aGlzLl9kZWZhdWx0U2NhbGluZ0R1cmF0aW9uLCAuLi5wIH0pKSA/PyBbXG4gICAgICAgIHtcbiAgICAgICAgICByZXBsaWNhczogUmVwbGljYXMuYWJzb2x1dGUoNCksXG4gICAgICAgICAgZHVyYXRpb246IER1cmF0aW9uLm1pbnV0ZXMoMSksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICByZXBsaWNhczogUmVwbGljYXMucGVyY2VudCgyMDApLFxuICAgICAgICAgIGR1cmF0aW9uOiBEdXJhdGlvbi5taW51dGVzKDEpLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9O1xuICAgIGlmIChwcm9wcz8uc2NhbGVVcD8ucG9saWNpZXM/Lmxlbmd0aCkge1xuICAgICAgdGhpcy5fdmFsaWRhdGVTY2FsaW5nUG9saWNpZXMoJ3NjYWxlVXAnLCBwcm9wcy5zY2FsZVVwLnBvbGljaWVzKTtcbiAgICB9XG4gICAgdGhpcy5zY2FsZURvd24gPSB7XG4gICAgICBzdHJhdGVneTogU2NhbGluZ1N0cmF0ZWd5Lk1BWF9DSEFOR0UsXG4gICAgICBzdGFiaWxpemF0aW9uV2luZG93OiBEdXJhdGlvbi5taW51dGVzKDUpLFxuICAgICAgLi4ucHJvcHMuc2NhbGVEb3duLFxuICAgICAgcG9saWNpZXM6IHByb3BzLnNjYWxlRG93bj8ucG9saWNpZXM/Lm1hcCgocCkgPT4gKHsgZHVyYXRpb246IHRoaXMuX2RlZmF1bHRTY2FsaW5nRHVyYXRpb24sIC4uLnAgfSkpID8/IFtcbiAgICAgICAge1xuICAgICAgICAgIHJlcGxpY2FzOiBSZXBsaWNhcy5hYnNvbHV0ZSh0aGlzLm1pblJlcGxpY2FzKSxcbiAgICAgICAgICBkdXJhdGlvbjogRHVyYXRpb24ubWludXRlcyg1KSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcblxuICAgIHRoaXMubm9kZS5hZGRWYWxpZGF0aW9uKHsgdmFsaWRhdGU6ICgpID0+IHRoaXMuX3ZhbGlkYXRlVGFyZ2V0UmVwbGljYXMoKSB9KTtcbiAgICB0aGlzLm5vZGUuYWRkVmFsaWRhdGlvbih7IHZhbGlkYXRlOiAoKSA9PiB0aGlzLl92YWxpZGF0ZVRhcmdldENvbnRhaW5lcnMoKSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhIGxpc3Qgb2Ygc2NhbGluZyBwb2xpY2llcy5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBwcml2YXRlIF92YWxpZGF0ZVNjYWxpbmdQb2xpY2llcyhkaXJlY3Rpb246ICdzY2FsZVVwJyB8ICdzY2FsZURvd24nLCBwb2xpY2llczogU2NhbGluZ1BvbGljeVtdKSB7XG4gICAgcG9saWNpZXMuZm9yRWFjaCgocCkgPT4ge1xuICAgICAgaWYgKHAuZHVyYXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLl92YWxpZGF0ZVNjYWxpbmdQb2xpY3lEdXJhdGlvbihkaXJlY3Rpb24sIHAuZHVyYXRpb24pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIGBTY2FsaW5nUG9saWN5LmR1cmF0aW9uYCBpcyB3aXRoaW4gdGhlIGFsbG93ZWQgcmFuZ2UuXG4gICAqXG4gICAqIGBkdXJhdGlvbmAgcmFuZ2U6IDEgc2Vjb25kIC0gMzAgbWluXG4gICAqXG4gICAqIEt1YmVybmV0ZXMgbmFtZTogYFNjYWxpbmdQb2xpY3kucGVyaW9kU2Vjb25kc2AuXG4gICAqIEBzZWUgaHR0cHM6Ly9rdWJlcm5ldGVzLmlvL2RvY3MvcmVmZXJlbmNlL2t1YmVybmV0ZXMtYXBpL3dvcmtsb2FkLXJlc291cmNlcy9ob3Jpem9udGFsLXBvZC1hdXRvc2NhbGVyLXYyLyNIb3Jpem9udGFsUG9kQXV0b3NjYWxlclNwZWNcbiAgICogQGludGVybmFsXG4gICAqL1xuICBwcml2YXRlIF92YWxpZGF0ZVNjYWxpbmdQb2xpY3lEdXJhdGlvbihkaXJlY3Rpb246ICdzY2FsZVVwJyB8ICdzY2FsZURvd24nLCBkdXJhdGlvbjogRHVyYXRpb24pIHtcbiAgICBjb25zdCBwZXJpb2RTZWNvbmRzID0gZHVyYXRpb24udG9TZWNvbmRzKCkgPz8gMTU7XG4gICAgY29uc3QgaXNXaXRoaW5SYW5nZSA9IEJvb2xlYW4oMCA8IHBlcmlvZFNlY29uZHMgJiYgcGVyaW9kU2Vjb25kcyA8PSAxODAwKTtcbiAgICBpZiAoIWlzV2l0aGluUmFuZ2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJyR7ZGlyZWN0aW9ufS5wb2xpY2llcycgZHVyYXRpb24gKCR7ZHVyYXRpb24udG9IdW1hblN0cmluZygpfSkgaXMgb3V0c2lkZSBvZiB0aGUgYWxsb3dlZCByYW5nZS4gTXVzdCBiZSBhdCBsZWFzdCAxIHNlY29uZCBsb25nIGFuZCBubyBsb25nZXIgdGhhbiAzMCBtaW51dGVzLmApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBgU2NhbGluZ1J1bGVzLnN0YWJpbGl6YXRpb25XaW5kb3dgIGlzIHdpdGhpbiB0aGUgYWxsb3dlZCByYW5nZS5cbiAgICpcbiAgICogYHN0YWJpbGl6YXRpb25XaW5kb3dgIHJhbmdlOiAwIHNlY29uZHMgLSAxIGhvdXJcbiAgICpcbiAgICogQHNlZSBodHRwczovL2t1YmVybmV0ZXMuaW8vZG9jcy9yZWZlcmVuY2Uva3ViZXJuZXRlcy1hcGkvd29ya2xvYWQtcmVzb3VyY2VzL2hvcml6b250YWwtcG9kLWF1dG9zY2FsZXItdjIvI0hvcml6b250YWxQb2RBdXRvc2NhbGVyU3BlY1xuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHByaXZhdGUgX3ZhbGlkYXRlU3RhYmlsaXphdGlvbldpbmRvdyhkaXJlY3Rpb246ICdzY2FsZVVwJyB8ICdzY2FsZURvd24nLCB3aW5kb3c6IER1cmF0aW9uKSB7XG4gICAgY29uc3Qgd2luZG93U2Vjb25kcyA9IHdpbmRvdy50b1NlY29uZHMoKTtcbiAgICBjb25zdCBpc1dpdGhpblJhbmdlID0gQm9vbGVhbigwIDw9IHdpbmRvd1NlY29uZHMgJiYgd2luZG93U2Vjb25kcyA8PSAzNjAwKTtcbiAgICBpZiAoIWlzV2l0aGluUmFuZ2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJyR7ZGlyZWN0aW9ufS5zdGFiaWxpemF0aW9uV2luZG93JyAoJHt3aW5kb3cudG9IdW1hblN0cmluZygpfSkgbXVzdCBiZSAwIHNlY29uZHMgb3IgbW9yZSB3aXRoIGEgbWF4IG9mIDEgaG91ci5gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR3VhcmFudGVlIHRoZSBIUEEgaGFzIGEgbWV0cmljIHRvIHNjYWxlIG9uLlxuICAgKiBWZXJpZnkgdGhhdCBtZXRyaWNzIGFyZSBjb25maWd1cmVkLCBpZiBub3QgY2hlY2sgZXZlcnkgcG9kIGNvbnRhaW5lciBoYXMgYSByZXNvdXJjZSBsaW1pdCBvclxuICAgKiByZXF1ZXN0IGRlZmluZWQuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHJpdmF0ZSBfdmFsaWRhdGVUYXJnZXRDb250YWluZXJzKCkge1xuICAgIGNvbnN0IGNvbnRhaW5lcnMgPSB0aGlzLnRhcmdldC50b1NjYWxpbmdUYXJnZXQoKS5jb250YWluZXJzO1xuICAgIGNvbnN0IGhhc1Jlc291cmNlQ29uc3RyYWludHMgPSBjb250YWluZXJzLnNvbWUoKGMpID0+IHRoaXMuX2hhc1JlcXVlc3RzT3JMaW1pdHMoYykpO1xuICAgIGlmICghaGFzUmVzb3VyY2VDb25zdHJhaW50cyAmJiAhdGhpcy5tZXRyaWNzKSB7XG4gICAgICByZXR1cm4gWydJZiBIb3Jpem9udGFsUG9kQXV0b3NjYWxlciBkb2VzIG5vdCBoYXZlIG1ldHJpY3MgZGVmaW5lZCwgdGhlbiBldmVyeSBjb250YWluZXIgaW4gdGhlIHRhcmdldCBtdXN0IGhhdmUgYSBDUFUgb3IgbWVtb3J5IHJlc291cmNlIGNvbnN0cmFpbnQgZGVmaW5lZC4nXTtcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXZlbnQgdGhlIEhQQSBmcm9tIHNjYWxpbmcgYSB0YXJnZXQgd2l0aCBhIHJlcGxpY2EgY291bnQgZGVmaW5lZC5cbiAgICogQHNlZSBodHRwczovL2t1YmVybmV0ZXMuaW8vZG9jcy90YXNrcy9ydW4tYXBwbGljYXRpb24vaG9yaXpvbnRhbC1wb2QtYXV0b3NjYWxlLyNpbXBsaWNpdC1tYWludGVuYW5jZS1tb2RlLWRlYWN0aXZhdGlvblxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHByaXZhdGUgX3ZhbGlkYXRlVGFyZ2V0UmVwbGljYXMoKSB7XG4gICAgY29uc3QgcmVwbGljYXMgPSB0aGlzLnRhcmdldC50b1NjYWxpbmdUYXJnZXQoKS5yZXBsaWNhcztcbiAgICBpZiAocmVwbGljYXMpIHtcbiAgICAgIHJldHVybiBbXG4gICAgICAgIGBIb3Jpem9udGFsUG9kQXV0b3NjYWxlciB0YXJnZXQgY2Fubm90IGhhdmUgYSBmaXhlZCBudW1iZXIgb2YgcmVwbGljYXMgKCR7cmVwbGljYXN9KS5gLFxuICAgICAgXTtcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIHRoYXQgdGhlIGNvbnRhaW5lciBoYXMgYXQgbGVhc3Qgb25lIENQVS9tZW1vcnkgcmVxdWVzdC9saW1pdCBkZWZpbmVkLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHByaXZhdGUgX2hhc1JlcXVlc3RzT3JMaW1pdHMoYzogY29udGFpbmVyLkNvbnRhaW5lcik6IEJvb2xlYW4ge1xuICAgIGNvbnN0IGhhc1JlcXVlc3RzID0gYy5yZXNvdXJjZXM/LmNwdT8ucmVxdWVzdCB8fCBjLnJlc291cmNlcz8ubWVtb3J5Py5yZXF1ZXN0O1xuICAgIGNvbnN0IGhhc0xpbWl0cyA9IGMucmVzb3VyY2VzPy5jcHU/LmxpbWl0IHx8IGMucmVzb3VyY2VzPy5tZW1vcnk/LmxpbWl0O1xuICAgIHJldHVybiBCb29sZWFuKGhhc1JlcXVlc3RzIHx8IGhhc0xpbWl0cyk7XG4gIH1cblxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBfdG9LdWJlKCk6IGs4cy5Ib3Jpem9udGFsUG9kQXV0b3NjYWxlclNwZWNWMiB7XG4gICAgY29uc3Qgc2NhbGluZ1RhcmdldCA9IHRoaXMudGFyZ2V0LnRvU2NhbGluZ1RhcmdldCgpO1xuICAgIHJldHVybiB7XG4gICAgICBtYXhSZXBsaWNhczogdGhpcy5tYXhSZXBsaWNhcyxcbiAgICAgIG1pblJlcGxpY2FzOiB0aGlzLm1pblJlcGxpY2FzLFxuICAgICAgc2NhbGVUYXJnZXRSZWY6IHtcbiAgICAgICAgYXBpVmVyc2lvbjogc2NhbGluZ1RhcmdldC5hcGlWZXJzaW9uLFxuICAgICAgICBuYW1lOiBzY2FsaW5nVGFyZ2V0Lm5hbWUsXG4gICAgICAgIGtpbmQ6IHNjYWxpbmdUYXJnZXQua2luZCxcbiAgICAgIH0sXG4gICAgICBtZXRyaWNzOiB0aGlzLm1ldHJpY3M/Lm1hcChtID0+IG0uX3RvS3ViZSgpKSxcbiAgICAgIGJlaGF2aW9yOiB7XG4gICAgICAgIHNjYWxlVXA6IHtcbiAgICAgICAgICBwb2xpY2llczogdGhpcy5zY2FsZVVwLnBvbGljaWVzPy5tYXAoKHApID0+ICh7XG4gICAgICAgICAgICAuLi5wLnJlcGxpY2FzLl90b0t1YmUoKSxcbiAgICAgICAgICAgIHBlcmlvZFNlY29uZHM6IHAuZHVyYXRpb24/LnRvU2Vjb25kcygpID8/IHRoaXMuX2RlZmF1bHRTY2FsaW5nRHVyYXRpb24udG9TZWNvbmRzKCksXG4gICAgICAgICAgfSkpLFxuICAgICAgICAgIHNlbGVjdFBvbGljeTogdGhpcy5zY2FsZVVwLnN0cmF0ZWd5LFxuICAgICAgICAgIHN0YWJpbGl6YXRpb25XaW5kb3dTZWNvbmRzOiB0aGlzLnNjYWxlVXAuc3RhYmlsaXphdGlvbldpbmRvdz8udG9TZWNvbmRzKCksXG4gICAgICAgIH0sXG4gICAgICAgIHNjYWxlRG93bjoge1xuICAgICAgICAgIHBvbGljaWVzOiB0aGlzLnNjYWxlRG93bi5wb2xpY2llcz8ubWFwKChwKSA9PiAoe1xuICAgICAgICAgICAgLi4ucC5yZXBsaWNhcy5fdG9LdWJlKCksXG4gICAgICAgICAgICBwZXJpb2RTZWNvbmRzOiBwLmR1cmF0aW9uPy50b1NlY29uZHMoKSA/PyB0aGlzLl9kZWZhdWx0U2NhbGluZ0R1cmF0aW9uLnRvU2Vjb25kcygpLFxuICAgICAgICAgIH0pKSxcbiAgICAgICAgICBzZWxlY3RQb2xpY3k6IHRoaXMuc2NhbGVEb3duLnN0cmF0ZWd5LFxuICAgICAgICAgIHN0YWJpbGl6YXRpb25XaW5kb3dTZWNvbmRzOiB0aGlzLnNjYWxlRG93bi5zdGFiaWxpemF0aW9uV2luZG93Py50b1NlY29uZHMoKSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxufVxuXG4vKipcbiAqIEJhc2Ugb3B0aW9ucyBmb3IgYSBNZXRyaWNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNZXRyaWNPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSB0YXJnZXQgbWV0cmljIHZhbHVlIHRoYXQgd2lsbCB0cmlnZ2VyIHNjYWxpbmcuXG4gICAqL1xuICByZWFkb25seSB0YXJnZXQ6IE1ldHJpY1RhcmdldDtcbiAgLyoqXG4gICogVGhlIG5hbWUgb2YgdGhlIG1ldHJpYyB0byBzY2FsZSBvbi5cbiAgKi9cbiAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICAvKipcbiAgICogQSBzZWxlY3RvciB0byBmaW5kIGEgbWV0cmljIGJ5IGxhYmVsLlxuICAgKlxuICAgKiBXaGVuIHNldCwgaXQgaXMgcGFzc2VkIGFzIGFuIGFkZGl0aW9uYWwgcGFyYW1ldGVyIHRvIHRoZSBtZXRyaWNzIHNlcnZlclxuICAgKiBmb3IgbW9yZSBzcGVjaWZpYyBtZXRyaWNzIHNjb3BpbmcuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gSnVzdCB0aGUgbWV0cmljICduYW1lJyB3aWxsIGJlIHVzZWQgdG8gZ2F0aGVyIG1ldHJpY3MuXG4gICAqL1xuICByZWFkb25seSBsYWJlbFNlbGVjdG9yPzogcG9kLkxhYmVsU2VsZWN0b3I7XG59XG5cblxuLyoqXG4gKiBPcHRpb25zIGZvciBgTWV0cmljLmNvbnRhaW5lclJlc291cmNlKClgXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWV0cmljQ29udGFpbmVyUmVzb3VyY2VPcHRpb25zIHtcbiAgLyoqXG4gICAqIENvbnRhaW5lciB3aGVyZSB0aGUgbWV0cmljIGNhbiBiZSBmb3VuZC5cbiAgICovXG4gIHJlYWRvbmx5IGNvbnRhaW5lcjogY29udGFpbmVyLkNvbnRhaW5lcjtcbiAgLyoqXG4gICAqIFRhcmdldCBtZXRyaWMgdmFsdWUgdGhhdCB3aWxsIHRyaWdnZXIgc2NhbGluZy5cbiAgICovXG4gIHJlYWRvbmx5IHRhcmdldDogTWV0cmljVGFyZ2V0O1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGBNZXRyaWMub2JqZWN0KClgXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWV0cmljT2JqZWN0T3B0aW9ucyBleHRlbmRzIE1ldHJpY09wdGlvbnMge1xuICAvKipcbiAgICogUmVzb3VyY2Ugd2hlcmUgdGhlIG1ldHJpYyBjYW4gYmUgZm91bmQuXG4gICAqL1xuICByZWFkb25seSBvYmplY3Q6IElSZXNvdXJjZTtcbn1cblxuLyoqXG4gKiBBIG1ldHJpYyBjb25kaXRpb24gdGhhdCBIb3Jpem9udGFsUG9kQXV0b3NjYWxlcidzIHNjYWxlIG9uLlxuICovXG5leHBvcnQgY2xhc3MgTWV0cmljIHtcblxuICAvKipcbiAgICogTWV0cmljIHRoYXQgdHJhY2tzIHRoZSBDUFUgb2YgYSBjb250YWluZXIuIFRoaXMgbWV0cmljXG4gICAqIHdpbGwgYmUgdHJhY2tlZCBhY3Jvc3MgYWxsIHBvZHMgb2YgdGhlIGN1cnJlbnQgc2NhbGUgdGFyZ2V0LlxuICAgKlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjb250YWluZXJDcHUob3B0aW9uczogTWV0cmljQ29udGFpbmVyUmVzb3VyY2VPcHRpb25zKTogTWV0cmljIHtcbiAgICByZXR1cm4gbmV3IE1ldHJpYyh7XG4gICAgICB0eXBlOiAnQ29udGFpbmVyUmVzb3VyY2UnLFxuICAgICAgY29udGFpbmVyUmVzb3VyY2U6IHtcbiAgICAgICAgbmFtZTogJ2NwdScsXG4gICAgICAgIGNvbnRhaW5lcjogb3B0aW9ucy5jb250YWluZXIubmFtZSxcbiAgICAgICAgdGFyZ2V0OiBvcHRpb25zLnRhcmdldC5fdG9LdWJlKCksXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldHJpYyB0aGF0IHRyYWNrcyB0aGUgTWVtb3J5IG9mIGEgY29udGFpbmVyLiBUaGlzIG1ldHJpY1xuICAgKiB3aWxsIGJlIHRyYWNrZWQgYWNyb3NzIGFsbCBwb2RzIG9mIHRoZSBjdXJyZW50IHNjYWxlIHRhcmdldC5cbiAgICpcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGFpbmVyTWVtb3J5KG9wdGlvbnM6IE1ldHJpY0NvbnRhaW5lclJlc291cmNlT3B0aW9ucyk6IE1ldHJpYyB7XG4gICAgcmV0dXJuIG5ldyBNZXRyaWMoe1xuICAgICAgdHlwZTogJ0NvbnRhaW5lclJlc291cmNlJyxcbiAgICAgIGNvbnRhaW5lclJlc291cmNlOiB7XG4gICAgICAgIG5hbWU6ICdtZW1vcnknLFxuICAgICAgICBjb250YWluZXI6IG9wdGlvbnMuY29udGFpbmVyLm5hbWUsXG4gICAgICAgIHRhcmdldDogb3B0aW9ucy50YXJnZXQuX3RvS3ViZSgpLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRyaWMgdGhhdCB0cmFja3MgdGhlIHZvbHVtZSBzaXplIG9mIGEgY29udGFpbmVyLiBUaGlzIG1ldHJpY1xuICAgKiB3aWxsIGJlIHRyYWNrZWQgYWNyb3NzIGFsbCBwb2RzIG9mIHRoZSBjdXJyZW50IHNjYWxlIHRhcmdldC5cbiAgICpcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY29udGFpbmVyU3RvcmFnZShvcHRpb25zOiBNZXRyaWNDb250YWluZXJSZXNvdXJjZU9wdGlvbnMpOiBNZXRyaWMge1xuICAgIHJldHVybiBuZXcgTWV0cmljKHtcbiAgICAgIHR5cGU6ICdDb250YWluZXJSZXNvdXJjZScsXG4gICAgICBjb250YWluZXJSZXNvdXJjZToge1xuICAgICAgICBuYW1lOiAnc3RvcmFnZScsXG4gICAgICAgIGNvbnRhaW5lcjogb3B0aW9ucy5jb250YWluZXIubmFtZSxcbiAgICAgICAgdGFyZ2V0OiBvcHRpb25zLnRhcmdldC5fdG9LdWJlKCksXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldHJpYyB0aGF0IHRyYWNrcyB0aGUgbG9jYWwgZXBoZW1lcmFsIHN0b3JhZ2Ugb2YgYSBjb250YWluZXIuIFRoaXMgbWV0cmljXG4gICAqIHdpbGwgYmUgdHJhY2tlZCBhY3Jvc3MgYWxsIHBvZHMgb2YgdGhlIGN1cnJlbnQgc2NhbGUgdGFyZ2V0LlxuICAgKlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjb250YWluZXJFcGhlbWVyYWxTdG9yYWdlKG9wdGlvbnM6IE1ldHJpY0NvbnRhaW5lclJlc291cmNlT3B0aW9ucyk6IE1ldHJpYyB7XG4gICAgcmV0dXJuIG5ldyBNZXRyaWMoe1xuICAgICAgdHlwZTogJ0NvbnRhaW5lclJlc291cmNlJyxcbiAgICAgIGNvbnRhaW5lclJlc291cmNlOiB7XG4gICAgICAgIG5hbWU6ICdlcGhlbWVyYWwtc3RvcmFnZScsXG4gICAgICAgIGNvbnRhaW5lcjogb3B0aW9ucy5jb250YWluZXIubmFtZSxcbiAgICAgICAgdGFyZ2V0OiBvcHRpb25zLnRhcmdldC5fdG9LdWJlKCksXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgZ2xvYmFsIG1ldHJpYyB0aGF0IGlzIG5vdCBhc3NvY2lhdGVkIHdpdGggYW55IEt1YmVybmV0ZXMgb2JqZWN0LlxuICAgKiBBbGxvd3MgZm9yIGF1dG9zY2FsaW5nIGJhc2VkIG9uIGluZm9ybWF0aW9uIGNvbWluZyBmcm9tIGNvbXBvbmVudHMgcnVubmluZyBvdXRzaWRlIG9mXG4gICAqIHRoZSBjbHVzdGVyLlxuICAgKlxuICAgKiBVc2UgY2FzZTpcbiAgICogKiBTY2FsZSB1cCB3aGVuIHRoZSBsZW5ndGggb2YgYW4gU1FTIHF1ZXVlIGlzIGdyZWF0ZXIgdGhhbiAxMCBtZXNzYWdlcy5cbiAgICogKiBTY2FsZSBkb3duIHdoZW4gYW4gb3V0c2lkZSBsb2FkIGJhbGFuY2VyJ3MgcXVlcmllcyBhcmUgbGVzcyB0aGFuIDEwMDAwIHBlciBzZWNvbmQuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGV4dGVybmFsKG9wdGlvbnM6IE1ldHJpY09wdGlvbnMpOiBNZXRyaWMge1xuICAgIHJldHVybiBuZXcgTWV0cmljKHtcbiAgICAgIHR5cGU6ICdFeHRlcm5hbCcsXG4gICAgICBleHRlcm5hbDoge1xuICAgICAgICBtZXRyaWM6IHtcbiAgICAgICAgICBuYW1lOiBvcHRpb25zLm5hbWUsXG4gICAgICAgICAgc2VsZWN0b3I6IG9wdGlvbnMubGFiZWxTZWxlY3Rvcj8uX3RvS3ViZSgpLFxuICAgICAgICB9LFxuICAgICAgICB0YXJnZXQ6IG9wdGlvbnMudGFyZ2V0Ll90b0t1YmUoKSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgKiBNZXRyaWMgdGhhdCBkZXNjcmliZXMgYSBtZXRyaWMgb2YgYSBrdWJlcm5ldGVzIG9iamVjdFxuICAqXG4gICogVXNlIGNhc2U6XG4gICogKiBTY2FsZSBvbiBhIEt1YmVybmV0ZXMgSW5ncmVzcydzIGhpdHMtcGVyLXNlY29uZCBtZXRyaWMuXG4gICovXG4gIHB1YmxpYyBzdGF0aWMgb2JqZWN0KG9wdGlvbnM6IE1ldHJpY09iamVjdE9wdGlvbnMpOiBNZXRyaWMge1xuICAgIHJldHVybiBuZXcgTWV0cmljKHtcbiAgICAgIHR5cGU6ICdPYmplY3QnLFxuICAgICAgb2JqZWN0OiB7XG4gICAgICAgIGRlc2NyaWJlZE9iamVjdDoge1xuICAgICAgICAgIGFwaVZlcnNpb246IG9wdGlvbnMub2JqZWN0LmFwaVZlcnNpb24sXG4gICAgICAgICAga2luZDogb3B0aW9ucy5vYmplY3Qua2luZCxcbiAgICAgICAgICBuYW1lOiBvcHRpb25zLm9iamVjdC5uYW1lLFxuICAgICAgICB9LFxuICAgICAgICBtZXRyaWM6IHtcbiAgICAgICAgICBuYW1lOiBvcHRpb25zLm5hbWUsXG4gICAgICAgICAgc2VsZWN0b3I6IG9wdGlvbnMubGFiZWxTZWxlY3Rvcj8uX3RvS3ViZSgpLFxuICAgICAgICB9LFxuICAgICAgICB0YXJnZXQ6IG9wdGlvbnMudGFyZ2V0Ll90b0t1YmUoKSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQSBwb2QgbWV0cmljIHRoYXQgd2lsbCBiZSBhdmVyYWdlZCBhY3Jvc3MgYWxsIHBvZHMgb2YgdGhlIGN1cnJlbnQgc2NhbGUgdGFyZ2V0LlxuICAgKlxuICAgKiBVc2UgY2FzZTpcbiAgICogKiBBdmVyYWdlIENQVSB1dGlsaXphdGlvbiBhY3Jvc3MgYWxsIHBvZHNcbiAgICogKiBUcmFuc2FjdGlvbnMgcHJvY2Vzc2VkIHBlciBzZWNvbmQgYWNyb3NzIGFsbCBwb2RzXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHBvZHMob3B0aW9uczogTWV0cmljT3B0aW9ucyk6IE1ldHJpYyB7XG4gICAgcmV0dXJuIG5ldyBNZXRyaWMoe1xuICAgICAgdHlwZTogJ1BvZHMnLFxuICAgICAgcG9kczoge1xuICAgICAgICBtZXRyaWM6IHtcbiAgICAgICAgICBuYW1lOiBvcHRpb25zLm5hbWUsXG4gICAgICAgICAgc2VsZWN0b3I6IG9wdGlvbnMubGFiZWxTZWxlY3Rvcj8uX3RvS3ViZSgpLFxuICAgICAgICB9LFxuICAgICAgICB0YXJnZXQ6IG9wdGlvbnMudGFyZ2V0Ll90b0t1YmUoKSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVHJhY2tzIHRoZSBhdmFpbGFibGUgQ1BVIG9mIHRoZSBwb2RzIGluIGEgdGFyZ2V0LlxuICAgKlxuICAgKiBOb3RlOiBTaW5jZSB0aGUgcmVzb3VyY2UgdXNhZ2VzIG9mIGFsbCB0aGUgY29udGFpbmVycyBhcmUgc3VtbWVkIHVwIHRoZSB0b3RhbFxuICAgKiBwb2QgdXRpbGl6YXRpb24gbWF5IG5vdCBhY2N1cmF0ZWx5IHJlcHJlc2VudCB0aGUgaW5kaXZpZHVhbCBjb250YWluZXIgcmVzb3VyY2VcbiAgICogdXNhZ2UuIFRoaXMgY291bGQgbGVhZCB0byBzaXR1YXRpb25zIHdoZXJlIGEgc2luZ2xlIGNvbnRhaW5lciBtaWdodCBiZSBydW5uaW5nXG4gICAqIHdpdGggaGlnaCB1c2FnZSBhbmQgdGhlIEhQQSB3aWxsIG5vdCBzY2FsZSBvdXQgYmVjYXVzZSB0aGUgb3ZlcmFsbCBwb2QgdXNhZ2VcbiAgICogaXMgc3RpbGwgd2l0aGluIGFjY2VwdGFibGUgbGltaXRzLlxuICAgKlxuICAgKiBVc2UgY2FzZTpcbiAgICogKiBTY2FsZSB1cCB3aGVuIENQVSBpcyBhYm92ZSA0MCUuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlc291cmNlQ3B1KHRhcmdldDogTWV0cmljVGFyZ2V0KTogTWV0cmljIHtcbiAgICByZXR1cm4gbmV3IE1ldHJpYyh7XG4gICAgICB0eXBlOiAnUmVzb3VyY2UnLFxuICAgICAgcmVzb3VyY2U6IHtcbiAgICAgICAgbmFtZTogJ2NwdScsXG4gICAgICAgIHRhcmdldDogdGFyZ2V0Ll90b0t1YmUoKSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVHJhY2tzIHRoZSBhdmFpbGFibGUgTWVtb3J5IG9mIHRoZSBwb2RzIGluIGEgdGFyZ2V0LlxuICAgKlxuICAgKiBOb3RlOiBTaW5jZSB0aGUgcmVzb3VyY2UgdXNhZ2VzIG9mIGFsbCB0aGUgY29udGFpbmVycyBhcmUgc3VtbWVkIHVwIHRoZSB0b3RhbFxuICAgKiBwb2QgdXRpbGl6YXRpb24gbWF5IG5vdCBhY2N1cmF0ZWx5IHJlcHJlc2VudCB0aGUgaW5kaXZpZHVhbCBjb250YWluZXIgcmVzb3VyY2VcbiAgICogdXNhZ2UuIFRoaXMgY291bGQgbGVhZCB0byBzaXR1YXRpb25zIHdoZXJlIGEgc2luZ2xlIGNvbnRhaW5lciBtaWdodCBiZSBydW5uaW5nXG4gICAqIHdpdGggaGlnaCB1c2FnZSBhbmQgdGhlIEhQQSB3aWxsIG5vdCBzY2FsZSBvdXQgYmVjYXVzZSB0aGUgb3ZlcmFsbCBwb2QgdXNhZ2VcbiAgICogaXMgc3RpbGwgd2l0aGluIGFjY2VwdGFibGUgbGltaXRzLlxuICAgKlxuICAgKiBVc2UgY2FzZTpcbiAgICogKiBTY2FsZSB1cCB3aGVuIE1lbW9yeSBpcyBhYm92ZSA1MTJNQi5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVzb3VyY2VNZW1vcnkodGFyZ2V0OiBNZXRyaWNUYXJnZXQpOiBNZXRyaWMge1xuICAgIHJldHVybiBuZXcgTWV0cmljKHtcbiAgICAgIHR5cGU6ICdSZXNvdXJjZScsXG4gICAgICByZXNvdXJjZToge1xuICAgICAgICBuYW1lOiAnbWVtb3J5JyxcbiAgICAgICAgdGFyZ2V0OiB0YXJnZXQuX3RvS3ViZSgpLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFja3MgdGhlIGF2YWlsYWJsZSBTdG9yYWdlIG9mIHRoZSBwb2RzIGluIGEgdGFyZ2V0LlxuICAgKlxuICAgKiBOb3RlOiBTaW5jZSB0aGUgcmVzb3VyY2UgdXNhZ2VzIG9mIGFsbCB0aGUgY29udGFpbmVycyBhcmUgc3VtbWVkIHVwIHRoZSB0b3RhbFxuICAgKiBwb2QgdXRpbGl6YXRpb24gbWF5IG5vdCBhY2N1cmF0ZWx5IHJlcHJlc2VudCB0aGUgaW5kaXZpZHVhbCBjb250YWluZXIgcmVzb3VyY2VcbiAgICogdXNhZ2UuIFRoaXMgY291bGQgbGVhZCB0byBzaXR1YXRpb25zIHdoZXJlIGEgc2luZ2xlIGNvbnRhaW5lciBtaWdodCBiZSBydW5uaW5nXG4gICAqIHdpdGggaGlnaCB1c2FnZSBhbmQgdGhlIEhQQSB3aWxsIG5vdCBzY2FsZSBvdXQgYmVjYXVzZSB0aGUgb3ZlcmFsbCBwb2QgdXNhZ2VcbiAgICogaXMgc3RpbGwgd2l0aGluIGFjY2VwdGFibGUgbGltaXRzLlxuICAgKlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZXNvdXJjZVN0b3JhZ2UodGFyZ2V0OiBNZXRyaWNUYXJnZXQpOiBNZXRyaWMge1xuICAgIHJldHVybiBuZXcgTWV0cmljKHtcbiAgICAgIHR5cGU6ICdSZXNvdXJjZScsXG4gICAgICByZXNvdXJjZToge1xuICAgICAgICBuYW1lOiAnc3RvcmFnZScsXG4gICAgICAgIHRhcmdldDogdGFyZ2V0Ll90b0t1YmUoKSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVHJhY2tzIHRoZSBhdmFpbGFibGUgRXBoZW1lcmFsIFN0b3JhZ2Ugb2YgdGhlIHBvZHMgaW4gYSB0YXJnZXQuXG4gICAqXG4gICAqIE5vdGU6IFNpbmNlIHRoZSByZXNvdXJjZSB1c2FnZXMgb2YgYWxsIHRoZSBjb250YWluZXJzIGFyZSBzdW1tZWQgdXAgdGhlIHRvdGFsXG4gICAqIHBvZCB1dGlsaXphdGlvbiBtYXkgbm90IGFjY3VyYXRlbHkgcmVwcmVzZW50IHRoZSBpbmRpdmlkdWFsIGNvbnRhaW5lciByZXNvdXJjZVxuICAgKiB1c2FnZS4gVGhpcyBjb3VsZCBsZWFkIHRvIHNpdHVhdGlvbnMgd2hlcmUgYSBzaW5nbGUgY29udGFpbmVyIG1pZ2h0IGJlIHJ1bm5pbmdcbiAgICogd2l0aCBoaWdoIHVzYWdlIGFuZCB0aGUgSFBBIHdpbGwgbm90IHNjYWxlIG91dCBiZWNhdXNlIHRoZSBvdmVyYWxsIHBvZCB1c2FnZVxuICAgKiBpcyBzdGlsbCB3aXRoaW4gYWNjZXB0YWJsZSBsaW1pdHMuXG4gICAqXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlc291cmNlRXBoZW1lcmFsU3RvcmFnZSh0YXJnZXQ6IE1ldHJpY1RhcmdldCk6IE1ldHJpYyB7XG4gICAgcmV0dXJuIG5ldyBNZXRyaWMoe1xuICAgICAgdHlwZTogJ1Jlc291cmNlJyxcbiAgICAgIHJlc291cmNlOiB7XG4gICAgICAgIG5hbWU6ICdlcGhlbWVyYWwtc3RvcmFnZScsXG4gICAgICAgIHRhcmdldDogdGFyZ2V0Ll90b0t1YmUoKSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgcmVhZG9ubHkgdHlwZTogc3RyaW5nO1xuICBwcml2YXRlIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgbWV0cmljOiBrOHMuTWV0cmljU3BlY1YyKSB7XG4gICAgdGhpcy50eXBlID0gbWV0cmljLnR5cGU7XG4gIH1cblxuICAvKipcbiAgICogQGludGVybmFsXG4gICAqL1xuICBwdWJsaWMgX3RvS3ViZSgpOiBrOHMuTWV0cmljU3BlY1YyIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWM7XG4gIH1cblxufVxuXG5cbi8qKlxuICogQSBtZXRyaWMgY29uZGl0aW9uIHRoYXQgd2lsbCB0cmlnZ2VyIHNjYWxpbmcgYmVoYXZpb3Igd2hlbiBzYXRpc2ZpZWQuXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiBNZXRyaWNUYXJnZXQuYXZlcmFnZVV0aWxpemF0aW9uKDcwKTsgLy8gNzAlIGF2ZXJhZ2UgdXRpbGl6YXRpb25cbiAqXG4gKi9cbmV4cG9ydCBjbGFzcyBNZXRyaWNUYXJnZXQge1xuICAvKipcbiAgKiBUYXJnZXQgYSBzcGVjaWZpYyB0YXJnZXQgdmFsdWUuXG4gICpcbiAgKiBAcGFyYW0gdmFsdWUgVGhlIHRhcmdldCB2YWx1ZS5cbiAgKi9cbiAgcHVibGljIHN0YXRpYyB2YWx1ZSh2YWx1ZTogbnVtYmVyKTogTWV0cmljVGFyZ2V0IHtcbiAgICByZXR1cm4gbmV3IE1ldHJpY1RhcmdldCh7XG4gICAgICB0eXBlOiAnVmFsdWUnLFxuICAgICAgdmFsdWU6IGs4cy5RdWFudGl0eS5mcm9tTnVtYmVyKHZhbHVlKSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUYXJnZXQgdGhlIGF2ZXJhZ2UgdmFsdWUgYWNyb3NzIGFsbCByZWxldmFudCBwb2RzLlxuICAgKlxuICAgKiBAcGFyYW0gYXZlcmFnZVZhbHVlIFRoZSBhdmVyYWdlIG1ldHJpYyB2YWx1ZS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgYXZlcmFnZVZhbHVlKGF2ZXJhZ2VWYWx1ZTogbnVtYmVyKTogTWV0cmljVGFyZ2V0IHtcbiAgICByZXR1cm4gbmV3IE1ldHJpY1RhcmdldCh7XG4gICAgICB0eXBlOiAnQXZlcmFnZVZhbHVlJyxcbiAgICAgIGF2ZXJhZ2VWYWx1ZTogazhzLlF1YW50aXR5LmZyb21OdW1iZXIoYXZlcmFnZVZhbHVlKSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUYXJnZXQgYSBwZXJjZW50YWdlIHZhbHVlIGFjcm9zcyBhbGwgcmVsZXZhbnQgcG9kcy5cbiAgICpcbiAgICogQHBhcmFtIGF2ZXJhZ2VVdGlsaXphdGlvbiBUaGUgcGVyY2VudGFnZSBvZiB0aGUgdXRpbGl6YXRpb24gbWV0cmljLiBlLmcuIGA1MGAgZm9yIDUwJS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgYXZlcmFnZVV0aWxpemF0aW9uKGF2ZXJhZ2VVdGlsaXphdGlvbjogbnVtYmVyKTogTWV0cmljVGFyZ2V0IHtcbiAgICByZXR1cm4gbmV3IE1ldHJpY1RhcmdldCh7XG4gICAgICB0eXBlOiAnVXRpbGl6YXRpb24nLFxuICAgICAgYXZlcmFnZVV0aWxpemF0aW9uLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IG1ldHJpYzogazhzLk1ldHJpY1RhcmdldFYyKSB7IH1cblxuICAvKipcbiAgICogQGludGVybmFsXG4gICAqL1xuICBwdWJsaWMgX3RvS3ViZSgpOiBrOHMuTWV0cmljU3BlY1YyIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWM7XG4gIH1cbn1cblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBzY2FsaW5nIGJlaGF2aW9yIGZvciBvbmUgZGlyZWN0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNjYWxpbmdSdWxlcyB7XG4gIC8qKlxuICAgKiBEZWZpbmVzIHRoZSB3aW5kb3cgb2YgcGFzdCBtZXRyaWNzIHRoYXQgdGhlIGF1dG9zY2FsZXIgc2hvdWxkIGNvbnNpZGVyIHdoZW4gY2FsY3VsYXRpbmdcbiAgICogd2V0aGVyIG9yIG5vdCBhdXRvc2NhbGluZyBzaG91bGQgb2NjdXIuXG4gICAqXG4gICAqIE1pbmltdW0gZHVyYXRpb24gaXMgMSBzZWNvbmQsIG1heCBpcyAxIGhvdXIuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIHN0YWJpbGl6YXRpb25XaW5kb3c6IER1cmF0aW9uLm1pbnV0ZXMoMzApXG4gICAqIC8vIEF1dG9zY2FsZXIgY29uc2lkZXJzIHRoZSBsYXN0IDMwIG1pbnV0ZXMgb2YgbWV0cmljcyB3aGVuIGRlY2lkaW5nIHdoZXRoZXIgdG8gc2NhbGUuXG4gICAqXG4gICAqIEBkZWZhdWx0ICogT24gc2NhbGUgZG93biBubyBzdGFiaWxpemF0aW9uIGlzIHBlcmZvcm1lZC5cbiAgICogKiBPbiBzY2FsZSB1cCBzdGFiaWxpemF0aW9uIGlzIHBlcmZvcm1lZCBmb3IgNSBtaW51dGVzLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhYmlsaXphdGlvbldpbmRvdz86IER1cmF0aW9uO1xuICAvKipcbiAgICogVGhlIHN0cmF0ZWd5IHRvIHVzZSB3aGVuIHNjYWxpbmcuXG4gICAqXG4gICAqIEBkZWZhdWx0IE1BWF9DSEFOR0VcbiAgICovXG4gIHJlYWRvbmx5IHN0cmF0ZWd5PzogU2NhbGluZ1N0cmF0ZWd5O1xuICAvKipcbiAgICogVGhlIHNjYWxpbmcgcG9saWNpZXMuXG4gICAqXG4gICAqIEBkZWZhdWx0ICogU2NhbGUgdXBcbiAgICogICAgICAgICAgICAqIEluY3JlYXNlIG5vIG1vcmUgdGhhbiA0IHBvZHMgcGVyIDYwIHNlY29uZHNcbiAgICogICAgICAgICAgICAqIERvdWJsZSB0aGUgbnVtYmVyIG9mIHBvZHMgcGVyIDYwIHNlY29uZHNcbiAgICogICAgICAgICAgKiBTY2FsZSBkb3duXG4gICAqICAgICAgICAgICAgKiBEZWNyZWFzZSB0byBtaW5SZXBsaWNhIGNvdW50XG4gICAqL1xuICByZWFkb25seSBwb2xpY2llcz86IFNjYWxpbmdQb2xpY3lbXTtcbn1cblxuXG5leHBvcnQgZW51bSBTY2FsaW5nU3RyYXRlZ3kge1xuICAvKipcbiAgICogVXNlIHRoZSBwb2xpY3kgdGhhdCBwcm92aXNpb25zIHRoZSBtb3N0IGNoYW5nZXMuXG4gICAqL1xuICBNQVhfQ0hBTkdFID0gJ01heCcsXG4gIC8qKlxuICAgKiBVc2UgdGhlIHBvbGljeSB0aGF0IHByb3Zpc2lvbnMgdGhlIGxlYXN0IGFtb3VudCBvZiBjaGFuZ2VzLlxuICAgKi9cbiAgTUlOX0NIQU5HRSA9ICdNaW4nLFxuICAvKipcbiAgICogRGlzYWJsZXMgc2NhbGluZyBpbiB0aGlzIGRpcmVjdGlvbi5cbiAgICpcbiAgICogQGRlcHJlY2F0ZWQgLSBPbWl0IHRoZSBTY2FsaW5nUnVsZSBpbnN0ZWFkXG4gICAqL1xuICBESVNBQkxFRCA9ICdEaXNhYmxlZCcsXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2NhbGluZ1BvbGljeSB7XG4gIC8qKlxuICAgKiBUaGUgdHlwZSBhbmQgcXVhbnRpdHkgb2YgcmVwbGljYXMgdG8gY2hhbmdlLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVwbGljYXM6IFJlcGxpY2FzO1xuICAvKipcbiAgICogVGhlIGFtb3VudCBvZiB0aW1lIHRoZSBzY2FsaW5nIHBvbGljeSBoYXMgdG9cbiAgICogY29udGludWUgc2NhbGluZyBiZWZvcmUgdGhlIHRhcmdldCBtZXRyaWMgbXVzdCBiZVxuICAgKiByZXZhbGlkYXRlZC5cbiAgICpcbiAgICogTXVzdCBiZSBncmVhdGVyIHRoYW4gMCBzZWNvbmRzIGFuZCBubyBsb25nZXIgdGhhbiAzMCBtaW51dGVzLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIDE1IHNlY29uZHNcbiAgICovXG4gIHJlYWRvbmx5IGR1cmF0aW9uPzogRHVyYXRpb247XG59XG5cblxuLyoqXG4gKiBUaGUgYW1vdW50IG9mIHJlcGxpY2FzIHRoYXQgd2lsbCBjaGFuZ2UuXG4gKi9cbmV4cG9ydCBjbGFzcyBSZXBsaWNhcyB7XG5cbiAgLyoqXG4gICAqIENoYW5nZXMgdGhlIHBvZHMgYnkgYSBwZXJjZW50YWdlIG9mIHRoZSBpdCdzIGN1cnJlbnQgdmFsdWUuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgcGVyY2VudGFnZSBvZiBjaGFuZ2UgdG8gYXBwbHkuIE11c3QgYmUgZ3JlYXRlciB0aGFuIDAuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHBlcmNlbnQodmFsdWU6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgUmVwbGljYXMgKHtcbiAgICAgIHR5cGU6ICdQZXJjZW50JyxcbiAgICAgIHZhbHVlLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENoYW5nZXMgdGhlIHBvZHMgYnkgYSBwZXJjZW50YWdlIG9mIHRoZSBpdCdzIGN1cnJlbnQgdmFsdWUuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgYW1vdW50IG9mIGNoYW5nZSB0byBhcHBseS4gTXVzdCBiZSBncmVhdGVyIHRoYW4gMC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgYWJzb2x1dGUodmFsdWU6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgUmVwbGljYXMoe1xuICAgICAgdHlwZTogJ1BvZHMnLFxuICAgICAgdmFsdWUsXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgcmVwbGljYXM6IFBpY2s8azhzLkhwYVNjYWxpbmdQb2xpY3lWMiwgJ3R5cGUnIHwgJ3ZhbHVlJz4pIHsgfVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBfdG9LdWJlKCk6IFBpY2s8azhzLkhwYVNjYWxpbmdQb2xpY3lWMiwgJ3R5cGUnIHwgJ3ZhbHVlJz4ge1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiB0aGlzLnJlcGxpY2FzLnR5cGUsXG4gICAgICB2YWx1ZTogdGhpcy5yZXBsaWNhcy52YWx1ZSxcbiAgICB9O1xuICB9XG59XG4iXX0=
|