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