@aws-cdk/aws-medialive-alpha 2.268.0-alpha.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 +60888 -0
- package/.jsii.tabl.json.gz +0 -0
- package/.warnings.jsii.js +524 -0
- package/LICENSE +201 -0
- package/NOTICE +2 -0
- package/README.md +1297 -0
- package/grants.json +27 -0
- package/lib/audio-codec-settings.d.ts +901 -0
- package/lib/audio-codec-settings.js +1098 -0
- package/lib/audio-selector.d.ts +170 -0
- package/lib/audio-selector.js +306 -0
- package/lib/avail-settings.d.ts +231 -0
- package/lib/avail-settings.js +226 -0
- package/lib/caption-selector.d.ts +234 -0
- package/lib/caption-selector.js +413 -0
- package/lib/caption-settings.d.ts +349 -0
- package/lib/caption-settings.js +482 -0
- package/lib/channel-features.d.ts +106 -0
- package/lib/channel-features.js +85 -0
- package/lib/channel-placement-group.d.ts +73 -0
- package/lib/channel-placement-group.js +132 -0
- package/lib/channel.d.ts +687 -0
- package/lib/channel.js +1096 -0
- package/lib/cluster.d.ts +129 -0
- package/lib/cluster.js +158 -0
- package/lib/color-correction.d.ts +39 -0
- package/lib/color-correction.js +29 -0
- package/lib/destinations.d.ts +242 -0
- package/lib/destinations.js +455 -0
- package/lib/encode-configuration.d.ts +615 -0
- package/lib/encode-configuration.js +629 -0
- package/lib/enums.d.ts +698 -0
- package/lib/enums.js +1045 -0
- package/lib/file-location.d.ts +65 -0
- package/lib/file-location.js +150 -0
- package/lib/framerate.d.ts +31 -0
- package/lib/framerate.js +71 -0
- package/lib/index.d.ts +26 -0
- package/lib/index.js +43 -0
- package/lib/input-attachment.d.ts +319 -0
- package/lib/input-attachment.js +228 -0
- package/lib/input-security-group.d.ts +51 -0
- package/lib/input-security-group.js +123 -0
- package/lib/input-specification.d.ts +111 -0
- package/lib/input-specification.js +181 -0
- package/lib/input.d.ts +505 -0
- package/lib/input.js +803 -0
- package/lib/m2ts-settings.d.ts +421 -0
- package/lib/m2ts-settings.js +469 -0
- package/lib/m3u8-settings.d.ts +272 -0
- package/lib/m3u8-settings.js +304 -0
- package/lib/medialive-grants.generated.d.ts +30 -0
- package/lib/medialive-grants.generated.js +92 -0
- package/lib/network.d.ts +83 -0
- package/lib/network.js +132 -0
- package/lib/output-group.d.ts +924 -0
- package/lib/output-group.js +941 -0
- package/lib/outputs.d.ts +304 -0
- package/lib/outputs.js +598 -0
- package/lib/sdi-source.d.ts +124 -0
- package/lib/sdi-source.js +180 -0
- package/lib/shared.d.ts +44 -0
- package/lib/shared.js +146 -0
- package/lib/video-codec-settings.d.ts +1500 -0
- package/lib/video-codec-settings.js +1722 -0
- package/lib/video-selection.d.ts +92 -0
- package/lib/video-selection.js +95 -0
- package/package.json +135 -0
- package/rosetta/_generated.ts-fixture +6 -0
- package/rosetta/default.ts-fixture +21 -0
package/lib/outputs.js
ADDED
|
@@ -0,0 +1,598 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MediaConnectRouterOutput = exports.MsSmoothOutput = exports.FrameCaptureOutput = exports.CmafIngestOutput = exports.SrtOutput = exports.RtmpOutput = exports.ArchiveOutput = exports.UdpOutput = exports.HlsOutput = exports.MediaPackageV2Output = exports.ArchiveContainer = exports.Output = void 0;
|
|
4
|
+
exports.toDestinationId = toDestinationId;
|
|
5
|
+
exports.validateCodecs = validateCodecs;
|
|
6
|
+
exports.validateSingleVideoEncode = validateSingleVideoEncode;
|
|
7
|
+
exports.validateFec = validateFec;
|
|
8
|
+
const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
|
|
9
|
+
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
10
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
11
|
+
const helpers_internal_1 = require("aws-cdk-lib/core/lib/helpers-internal");
|
|
12
|
+
const audio_codec_settings_1 = require("./audio-codec-settings");
|
|
13
|
+
const enums_1 = require("./enums");
|
|
14
|
+
const m3u8_settings_1 = require("./m3u8-settings");
|
|
15
|
+
const video_codec_settings_1 = require("./video-codec-settings");
|
|
16
|
+
/**
|
|
17
|
+
* Convert an output name to a valid MediaLive channel `DestinationId`.
|
|
18
|
+
*
|
|
19
|
+
* Derives a valid CFN destination ID from a name (output group name or per-output name).
|
|
20
|
+
* The service requires destination IDs to contain only alphanumeric characters and hyphens,
|
|
21
|
+
* with no leading/trailing hyphen. Since names may contain underscores or other characters,
|
|
22
|
+
* we sanitise here.
|
|
23
|
+
*
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
function toDestinationId(outputName) {
|
|
27
|
+
if (aws_cdk_lib_1.Token.isUnresolved(outputName))
|
|
28
|
+
return outputName;
|
|
29
|
+
return outputName
|
|
30
|
+
.replace(/[^a-zA-Z0-9]+/g, '-')
|
|
31
|
+
.replace(/^-|-$/g, '');
|
|
32
|
+
}
|
|
33
|
+
/** @internal */
|
|
34
|
+
function validateCodecs(opts) {
|
|
35
|
+
opts.encodes.forEach(encode => {
|
|
36
|
+
const vType = encode._videoCodecType();
|
|
37
|
+
if (vType && !opts.allowedVideo.includes(vType)) {
|
|
38
|
+
const label = opts.groupName ? `${opts.outputName}' in group '${opts.groupName}` : opts.outputName;
|
|
39
|
+
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `UnsupportedVideoCodec`, `Output '${label}' does not support video codec '${vType}'.`
|
|
40
|
+
+ ` Supported: ${opts.allowedVideo.join(', ')}.`);
|
|
41
|
+
}
|
|
42
|
+
const aType = encode._audioCodecType();
|
|
43
|
+
if (aType && !opts.allowedAudio.includes(aType)) {
|
|
44
|
+
const label = opts.groupName ? `${opts.outputName}' in group '${opts.groupName}` : opts.outputName;
|
|
45
|
+
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `UnsupportedAudioCodec`, `Output '${label}' does not support audio codec '${aType}'.`
|
|
46
|
+
+ ` Supported: ${opts.allowedAudio.join(', ')}.`);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Validates that an MPEG-TS or RTMP output contains at most one video encode.
|
|
52
|
+
* These container formats support a single video PID. Multiple audio encodes are allowed.
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
55
|
+
function validateSingleVideoEncode(encodes, outputName, groupName) {
|
|
56
|
+
const videoEncodes = encodes.filter(e => e._videoCodecType() !== undefined);
|
|
57
|
+
if (videoEncodes.length > 1) {
|
|
58
|
+
const label = groupName ? `${outputName}' in group '${groupName}` : outputName;
|
|
59
|
+
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `MultipleVideoEncodes`, `Output '${label}' contains ${videoEncodes.length} video encodes, but only one is allowed per output.`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Validate FEC output settings: SMPTE 2022-1 ranges, and that FEC is only used with rtp://
|
|
64
|
+
* destinations (the only protocol MediaLive supports for FEC). Tokenized values are skipped.
|
|
65
|
+
* @internal
|
|
66
|
+
*/
|
|
67
|
+
function validateFec(fec, outputName, destinationUrls) {
|
|
68
|
+
if (!fec) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (fec.columnDepth !== undefined && !aws_cdk_lib_1.Token.isUnresolved(fec.columnDepth)
|
|
72
|
+
&& (fec.columnDepth < 4 || fec.columnDepth > 20)) {
|
|
73
|
+
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `FecColumnDepthRange`, `UDP output '${outputName}' fec.columnDepth must be between 4 and 20, got ${JSON.stringify(fec.columnDepth)}`);
|
|
74
|
+
}
|
|
75
|
+
if (fec.rowLength !== undefined && !aws_cdk_lib_1.Token.isUnresolved(fec.rowLength)
|
|
76
|
+
&& (fec.rowLength < 1 || fec.rowLength > 20)) {
|
|
77
|
+
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `FecRowLengthRange`, `UDP output '${outputName}' fec.rowLength must be between 1 and 20, got ${JSON.stringify(fec.rowLength)}`);
|
|
78
|
+
}
|
|
79
|
+
// MediaLive only supports FEC on rtp:// destinations. The destinations are shared by the whole
|
|
80
|
+
// UDP group, so any non-rtp destination makes this FEC output invalid.
|
|
81
|
+
const nonRtp = destinationUrls.find(url => !aws_cdk_lib_1.Token.isUnresolved(url) && !url.startsWith('rtp://'));
|
|
82
|
+
if (nonRtp !== undefined) {
|
|
83
|
+
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `FecRequiresRtp`, `UDP output '${outputName}' has FEC enabled, which requires every destination in the group to use the rtp:// protocol, got ${JSON.stringify(nonRtp)}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// =============================================================================
|
|
87
|
+
// Output (abstract base + subclasses per output group type)
|
|
88
|
+
// =============================================================================
|
|
89
|
+
/**
|
|
90
|
+
* Represents an output within an output group.
|
|
91
|
+
* Each output group type has its own Output subclass that knows how to render its output settings.
|
|
92
|
+
*/
|
|
93
|
+
class Output {
|
|
94
|
+
outputName;
|
|
95
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-medialive-alpha.Output", version: "2.268.0-alpha.0" };
|
|
96
|
+
encodes = [];
|
|
97
|
+
/** @internal */
|
|
98
|
+
constructor(outputName) {
|
|
99
|
+
this.outputName = outputName;
|
|
100
|
+
if (!aws_cdk_lib_1.Token.isUnresolved(outputName)) {
|
|
101
|
+
if (outputName.length < 1 || outputName.length > 256) {
|
|
102
|
+
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `OutputNameLength`, 'Output name must be between 1 and 256 characters.');
|
|
103
|
+
}
|
|
104
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(outputName)) {
|
|
105
|
+
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `OutputNameFormat`, 'Output name must contain only alphanumeric characters, hyphens, and underscores.');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/** @internal */
|
|
110
|
+
_getEncodes() {
|
|
111
|
+
return this.encodes;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Grant the channel role read access to external files referenced by this output. The base
|
|
115
|
+
* grants files referenced by the output's encodes (e.g. burn-in caption fonts); subclasses
|
|
116
|
+
* override to add output-type-specific files (e.g. audio-only cover art).
|
|
117
|
+
* @internal
|
|
118
|
+
*/
|
|
119
|
+
_grantPermissions(role) {
|
|
120
|
+
this.encodes.forEach(e => e._grantRead(role));
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Wire an encode configuration to this output.
|
|
124
|
+
* @internal
|
|
125
|
+
*/
|
|
126
|
+
_addEncode(encode) {
|
|
127
|
+
this.encodes.push(encode);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Validate encodes for this output type. Called at synth time.
|
|
131
|
+
* @internal
|
|
132
|
+
*/
|
|
133
|
+
_validate() {
|
|
134
|
+
}
|
|
135
|
+
/** @internal */
|
|
136
|
+
_bind() {
|
|
137
|
+
this._validate();
|
|
138
|
+
const videoNames = this.encodes.flatMap(e => e._bindVideo()?.name ?? []);
|
|
139
|
+
const audioNames = this.encodes.flatMap(e => e._bindAudio()?.name ?? []);
|
|
140
|
+
const captionNames = this.encodes.flatMap(e => e._bindCaption()?.name ?? []);
|
|
141
|
+
return {
|
|
142
|
+
outputSettings: this._bindOutputSettings(),
|
|
143
|
+
outputName: this.outputName,
|
|
144
|
+
videoDescriptionName: videoNames[0],
|
|
145
|
+
audioDescriptionNames: audioNames.length > 0 ? audioNames : undefined,
|
|
146
|
+
captionDescriptionNames: captionNames.length > 0 ? captionNames : undefined,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
exports.Output = Output;
|
|
151
|
+
/**
|
|
152
|
+
* The container (transport stream) for an Archive output. Use the static factory methods to
|
|
153
|
+
* select between an MPEG-TS (M2TS) container or a raw container.
|
|
154
|
+
*/
|
|
155
|
+
class ArchiveContainer {
|
|
156
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-medialive-alpha.ArchiveContainer", version: "2.268.0-alpha.0" };
|
|
157
|
+
/** An MPEG-TS (M2TS) container, optionally configured via `M2tsSettings`. */
|
|
158
|
+
static m2ts(settings) {
|
|
159
|
+
try {
|
|
160
|
+
jsiiDeprecationWarnings._aws_cdk_aws_medialive_alpha_M2tsSettings(settings);
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
|
164
|
+
Error.captureStackTrace(error, this.m2ts);
|
|
165
|
+
}
|
|
166
|
+
throw error;
|
|
167
|
+
}
|
|
168
|
+
return new M2tsArchiveContainer(settings);
|
|
169
|
+
}
|
|
170
|
+
/** A raw container (no transport-stream wrapping). */
|
|
171
|
+
static raw() {
|
|
172
|
+
return new RawArchiveContainer();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
exports.ArchiveContainer = ArchiveContainer;
|
|
176
|
+
/** @internal */
|
|
177
|
+
class M2tsArchiveContainer extends ArchiveContainer {
|
|
178
|
+
settings;
|
|
179
|
+
constructor(settings) {
|
|
180
|
+
super();
|
|
181
|
+
this.settings = settings;
|
|
182
|
+
}
|
|
183
|
+
_bind() {
|
|
184
|
+
return { m2TsSettings: this.settings?._bind() ?? {} };
|
|
185
|
+
}
|
|
186
|
+
_isRaw() {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/** @internal */
|
|
191
|
+
class RawArchiveContainer extends ArchiveContainer {
|
|
192
|
+
_bind() {
|
|
193
|
+
return { rawSettings: {} };
|
|
194
|
+
}
|
|
195
|
+
_isRaw() {
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// =============================================================================
|
|
200
|
+
// Output subclasses (one per output group type)
|
|
201
|
+
// =============================================================================
|
|
202
|
+
/** @internal */
|
|
203
|
+
class MediaPackageV2Output extends Output {
|
|
204
|
+
def;
|
|
205
|
+
groupName;
|
|
206
|
+
constructor(def, groupName) {
|
|
207
|
+
super(def.outputName);
|
|
208
|
+
this.def = def;
|
|
209
|
+
this.groupName = groupName;
|
|
210
|
+
this._addEncode(def.encode);
|
|
211
|
+
for (const caption of def.captions ?? []) {
|
|
212
|
+
this._addEncode(caption);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
_validate() {
|
|
216
|
+
const encode = this.def.encode;
|
|
217
|
+
if (encode._bindVideo() && !encode._hasExplicitFramerate()) {
|
|
218
|
+
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `MediaPackageFramerateRequired`, `MediaPackage V2 output group '${this.groupName}' requires explicit framerate on video encode '${encode.name}'.`);
|
|
219
|
+
}
|
|
220
|
+
// Validate the primary encode is not a caption
|
|
221
|
+
if (encode._bindCaption()) {
|
|
222
|
+
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `MediaPackagePrimaryEncodeNotCaption`, `MediaPackage V2 output '${this.def.outputName}': 'encode' must be a video or audio encode. Captions must go in the 'captions' prop alongside a video encode.`);
|
|
223
|
+
}
|
|
224
|
+
// Validate captions are actually caption encodes and are in-band only
|
|
225
|
+
for (const caption of this.def.captions ?? []) {
|
|
226
|
+
if (!caption._bindCaption()) {
|
|
227
|
+
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `MediaPackageCaptionsMustBeCaptions`, `MediaPackage V2 output '${this.def.outputName}': 'captions' must contain caption encodes only, got '${caption.name}'.`);
|
|
228
|
+
}
|
|
229
|
+
if (!caption._isInBandCaption()) {
|
|
230
|
+
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `MediaPackageCaptionsMustBeInBand`, `MediaPackage V2 output '${this.def.outputName}': caption '${caption.name}' uses an out-of-band destination (e.g. WebVTT, TTML). Only in-band types (burn-in, embedded) can ride alongside the primary encode. Put out-of-band captions in their own output.`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// Only one embedded caption per output
|
|
234
|
+
const embeddedCount = (this.def.captions ?? []).filter(c => c._isEmbeddedCaption()).length
|
|
235
|
+
+ (encode._bindCaption() && encode._isEmbeddedCaption() ? 1 : 0);
|
|
236
|
+
if (embeddedCount > 1) {
|
|
237
|
+
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `MediaPackageOneEmbeddedCaption`, `MediaPackage V2 output '${this.def.outputName}': only one embedded caption is allowed per output.`);
|
|
238
|
+
}
|
|
239
|
+
validateCodecs({
|
|
240
|
+
outputName: this.groupName,
|
|
241
|
+
// MediaPackage V2 uses CMAF Ingest under the hood, which supports AV1 in addition to
|
|
242
|
+
// H.264/H.265 — see https://docs.aws.amazon.com/mediapackage/latest/userguide/cmaf-ingest.html.
|
|
243
|
+
allowedVideo: [video_codec_settings_1.VideoCodecType.H264, video_codec_settings_1.VideoCodecType.H265, video_codec_settings_1.VideoCodecType.AV1, video_codec_settings_1.VideoCodecType.FRAME_CAPTURE],
|
|
244
|
+
allowedAudio: [audio_codec_settings_1.AudioCodecType.AAC, audio_codec_settings_1.AudioCodecType.AC3, audio_codec_settings_1.AudioCodecType.EAC3, audio_codec_settings_1.AudioCodecType.EAC3_ATMOS, audio_codec_settings_1.AudioCodecType.PASSTHROUGH],
|
|
245
|
+
encodes: [this.def.encode],
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
_bindOutputSettings() {
|
|
249
|
+
return {
|
|
250
|
+
mediaPackageOutputSettings: {
|
|
251
|
+
mediaPackageV2DestinationSettings: {
|
|
252
|
+
audioGroupId: this.def.audioGroupId,
|
|
253
|
+
audioRenditionSets: this.def.audioRenditionSets,
|
|
254
|
+
hlsAutoSelect: (this.def.hlsAutoSelect ?? enums_1.MediaPackageV2HlsSetting.OMIT).value,
|
|
255
|
+
hlsDefault: (this.def.hlsDefault ?? enums_1.MediaPackageV2HlsSetting.OMIT).value,
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
exports.MediaPackageV2Output = MediaPackageV2Output;
|
|
262
|
+
/** @internal */
|
|
263
|
+
class HlsOutput extends Output {
|
|
264
|
+
def;
|
|
265
|
+
constructor(def) {
|
|
266
|
+
super(def.outputName);
|
|
267
|
+
this.def = def;
|
|
268
|
+
def.encodes.forEach(e => this._addEncode(e));
|
|
269
|
+
}
|
|
270
|
+
_validate() {
|
|
271
|
+
validateCodecs({
|
|
272
|
+
outputName: this.outputName,
|
|
273
|
+
allowedVideo: [video_codec_settings_1.VideoCodecType.H264, video_codec_settings_1.VideoCodecType.H265, video_codec_settings_1.VideoCodecType.FRAME_CAPTURE],
|
|
274
|
+
allowedAudio: [audio_codec_settings_1.AudioCodecType.AAC, audio_codec_settings_1.AudioCodecType.AC3, audio_codec_settings_1.AudioCodecType.EAC3, audio_codec_settings_1.AudioCodecType.EAC3_ATMOS, audio_codec_settings_1.AudioCodecType.PASSTHROUGH],
|
|
275
|
+
encodes: this._getEncodes(),
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
_bindOutputSettings() {
|
|
279
|
+
return {
|
|
280
|
+
hlsOutputSettings: {
|
|
281
|
+
nameModifier: this.def.nameModifier,
|
|
282
|
+
segmentModifier: this.def.segmentModifier,
|
|
283
|
+
h265PackagingType: this.def.h265PackagingType?.value,
|
|
284
|
+
hlsSettings: (this.def.hlsSettings ?? m3u8_settings_1.HlsSettings.standard())._bind(),
|
|
285
|
+
},
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
_grantPermissions(role) {
|
|
289
|
+
super._grantPermissions(role);
|
|
290
|
+
// Audio-only HLS settings may reference a cover-art image in S3.
|
|
291
|
+
this.def.hlsSettings?._grantRead(role);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
exports.HlsOutput = HlsOutput;
|
|
295
|
+
/** @internal */
|
|
296
|
+
class UdpOutput extends Output {
|
|
297
|
+
def;
|
|
298
|
+
groupProps;
|
|
299
|
+
constructor(def, groupProps) {
|
|
300
|
+
super(def.outputName);
|
|
301
|
+
this.def = def;
|
|
302
|
+
this.groupProps = groupProps;
|
|
303
|
+
def.encodes.forEach(e => this._addEncode(e));
|
|
304
|
+
}
|
|
305
|
+
_validate() {
|
|
306
|
+
validateCodecs({
|
|
307
|
+
outputName: this.outputName,
|
|
308
|
+
allowedVideo: [video_codec_settings_1.VideoCodecType.H264, video_codec_settings_1.VideoCodecType.H265],
|
|
309
|
+
allowedAudio: [
|
|
310
|
+
audio_codec_settings_1.AudioCodecType.AAC, audio_codec_settings_1.AudioCodecType.AC3, audio_codec_settings_1.AudioCodecType.EAC3, audio_codec_settings_1.AudioCodecType.EAC3_ATMOS,
|
|
311
|
+
audio_codec_settings_1.AudioCodecType.MP2, audio_codec_settings_1.AudioCodecType.PASSTHROUGH,
|
|
312
|
+
],
|
|
313
|
+
encodes: this._getEncodes(),
|
|
314
|
+
});
|
|
315
|
+
validateSingleVideoEncode(this._getEncodes(), this.outputName);
|
|
316
|
+
validateFec(this.def.fec, this.outputName, this.groupProps.destinations.map(d => d._bind().url));
|
|
317
|
+
}
|
|
318
|
+
_bindOutputSettings() {
|
|
319
|
+
return {
|
|
320
|
+
udpOutputSettings: {
|
|
321
|
+
bufferMsec: this.def.buffer?.toMilliseconds() ?? this.groupProps.buffer?.toMilliseconds(),
|
|
322
|
+
destination: {
|
|
323
|
+
destinationRefId: this.groupProps.name,
|
|
324
|
+
},
|
|
325
|
+
containerSettings: {
|
|
326
|
+
m2TsSettings: this.def.m2tsSettings?._bind() ?? {},
|
|
327
|
+
},
|
|
328
|
+
fecOutputSettings: this.def.fec ? {
|
|
329
|
+
includeFec: this.def.fec.mode?.value,
|
|
330
|
+
columnDepth: this.def.fec.columnDepth,
|
|
331
|
+
rowLength: this.def.fec.rowLength,
|
|
332
|
+
} : undefined,
|
|
333
|
+
},
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
exports.UdpOutput = UdpOutput;
|
|
338
|
+
/** @internal */
|
|
339
|
+
class ArchiveOutput extends Output {
|
|
340
|
+
def;
|
|
341
|
+
constructor(def) {
|
|
342
|
+
super(def.outputName);
|
|
343
|
+
this.def = def;
|
|
344
|
+
def.encodes.forEach(e => this._addEncode(e));
|
|
345
|
+
}
|
|
346
|
+
_validate() {
|
|
347
|
+
const isRaw = (this.def.container ?? ArchiveContainer.m2ts())._isRaw();
|
|
348
|
+
if (isRaw) {
|
|
349
|
+
// Raw containers require an explicit file extension.
|
|
350
|
+
validateCodecs({
|
|
351
|
+
outputName: this.outputName,
|
|
352
|
+
allowedVideo: [video_codec_settings_1.VideoCodecType.H264, video_codec_settings_1.VideoCodecType.H265],
|
|
353
|
+
allowedAudio: [
|
|
354
|
+
audio_codec_settings_1.AudioCodecType.AAC, audio_codec_settings_1.AudioCodecType.AC3, audio_codec_settings_1.AudioCodecType.EAC3, audio_codec_settings_1.AudioCodecType.EAC3_ATMOS,
|
|
355
|
+
audio_codec_settings_1.AudioCodecType.MP2, audio_codec_settings_1.AudioCodecType.WAV, audio_codec_settings_1.AudioCodecType.PASSTHROUGH,
|
|
356
|
+
],
|
|
357
|
+
encodes: this._getEncodes(),
|
|
358
|
+
});
|
|
359
|
+
if (this.def.extension === undefined) {
|
|
360
|
+
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `RawArchiveExtensionRequired`, `Archive output '${this.outputName}' uses a raw container, which requires an explicit 'extension'`);
|
|
361
|
+
}
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
validateCodecs({
|
|
365
|
+
outputName: this.outputName,
|
|
366
|
+
allowedVideo: [video_codec_settings_1.VideoCodecType.H264, video_codec_settings_1.VideoCodecType.H265],
|
|
367
|
+
allowedAudio: [
|
|
368
|
+
audio_codec_settings_1.AudioCodecType.AAC, audio_codec_settings_1.AudioCodecType.AC3, audio_codec_settings_1.AudioCodecType.EAC3, audio_codec_settings_1.AudioCodecType.EAC3_ATMOS,
|
|
369
|
+
audio_codec_settings_1.AudioCodecType.MP2, audio_codec_settings_1.AudioCodecType.PASSTHROUGH,
|
|
370
|
+
],
|
|
371
|
+
encodes: this._getEncodes(),
|
|
372
|
+
});
|
|
373
|
+
validateSingleVideoEncode(this._getEncodes(), this.outputName);
|
|
374
|
+
}
|
|
375
|
+
_bindOutputSettings() {
|
|
376
|
+
return {
|
|
377
|
+
archiveOutputSettings: {
|
|
378
|
+
nameModifier: this.def.nameModifier,
|
|
379
|
+
extension: this.def.extension,
|
|
380
|
+
containerSettings: (this.def.container ?? ArchiveContainer.m2ts())._bind(),
|
|
381
|
+
},
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
exports.ArchiveOutput = ArchiveOutput;
|
|
386
|
+
/** @internal */
|
|
387
|
+
class RtmpOutput extends Output {
|
|
388
|
+
def;
|
|
389
|
+
groupName;
|
|
390
|
+
constructor(def, groupName) {
|
|
391
|
+
super(def.outputName);
|
|
392
|
+
this.def = def;
|
|
393
|
+
this.groupName = groupName;
|
|
394
|
+
def.encodes.forEach(e => this._addEncode(e));
|
|
395
|
+
}
|
|
396
|
+
_validate() {
|
|
397
|
+
validateCodecs({
|
|
398
|
+
outputName: this.outputName,
|
|
399
|
+
groupName: this.groupName,
|
|
400
|
+
allowedVideo: [video_codec_settings_1.VideoCodecType.H264],
|
|
401
|
+
allowedAudio: [audio_codec_settings_1.AudioCodecType.AAC],
|
|
402
|
+
encodes: this._getEncodes(),
|
|
403
|
+
});
|
|
404
|
+
validateSingleVideoEncode(this._getEncodes(), this.outputName, this.groupName);
|
|
405
|
+
}
|
|
406
|
+
_bindOutputSettings() {
|
|
407
|
+
return {
|
|
408
|
+
rtmpOutputSettings: {
|
|
409
|
+
certificateMode: this.def.certificateMode?.value,
|
|
410
|
+
connectionRetryInterval: this.def.connectionRetryInterval?.toSeconds(),
|
|
411
|
+
numRetries: this.def.numRetries,
|
|
412
|
+
destination: {
|
|
413
|
+
destinationRefId: toDestinationId(this.outputName),
|
|
414
|
+
},
|
|
415
|
+
},
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
exports.RtmpOutput = RtmpOutput;
|
|
420
|
+
/** @internal */
|
|
421
|
+
class SrtOutput extends Output {
|
|
422
|
+
def;
|
|
423
|
+
groupName;
|
|
424
|
+
constructor(def, groupName) {
|
|
425
|
+
super(def.outputName);
|
|
426
|
+
this.def = def;
|
|
427
|
+
this.groupName = groupName;
|
|
428
|
+
def.encodes.forEach(e => this._addEncode(e));
|
|
429
|
+
}
|
|
430
|
+
_validate() {
|
|
431
|
+
validateCodecs({
|
|
432
|
+
outputName: this.outputName,
|
|
433
|
+
groupName: this.groupName,
|
|
434
|
+
allowedVideo: [video_codec_settings_1.VideoCodecType.H264, video_codec_settings_1.VideoCodecType.H265],
|
|
435
|
+
allowedAudio: [
|
|
436
|
+
audio_codec_settings_1.AudioCodecType.AAC, audio_codec_settings_1.AudioCodecType.AC3, audio_codec_settings_1.AudioCodecType.EAC3, audio_codec_settings_1.AudioCodecType.EAC3_ATMOS,
|
|
437
|
+
audio_codec_settings_1.AudioCodecType.MP2, audio_codec_settings_1.AudioCodecType.PASSTHROUGH,
|
|
438
|
+
],
|
|
439
|
+
encodes: this._getEncodes(),
|
|
440
|
+
});
|
|
441
|
+
validateSingleVideoEncode(this._getEncodes(), this.outputName, this.groupName);
|
|
442
|
+
}
|
|
443
|
+
_bindOutputSettings() {
|
|
444
|
+
return {
|
|
445
|
+
srtOutputSettings: {
|
|
446
|
+
bufferMsec: this.def.buffer?.toMilliseconds(),
|
|
447
|
+
encryptionType: this.def.encryptionType?.value,
|
|
448
|
+
latency: this.def.latency?.toMilliseconds(),
|
|
449
|
+
// Each SRT output has its own channel destination, keyed by the output name.
|
|
450
|
+
destination: {
|
|
451
|
+
destinationRefId: toDestinationId(this.outputName),
|
|
452
|
+
},
|
|
453
|
+
containerSettings: {
|
|
454
|
+
m2TsSettings: this.def.m2tsSettings?._bind() ?? {},
|
|
455
|
+
},
|
|
456
|
+
},
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
exports.SrtOutput = SrtOutput;
|
|
461
|
+
/** @internal */
|
|
462
|
+
class CmafIngestOutput extends Output {
|
|
463
|
+
def;
|
|
464
|
+
constructor(def) {
|
|
465
|
+
super(def.outputName);
|
|
466
|
+
this.def = def;
|
|
467
|
+
this._addEncode(def.encode);
|
|
468
|
+
for (const caption of def.captions ?? []) {
|
|
469
|
+
this._addEncode(caption);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
_validate() {
|
|
473
|
+
// Validate captions are actually caption encodes and are in-band only
|
|
474
|
+
for (const caption of this.def.captions ?? []) {
|
|
475
|
+
if (!caption._bindCaption()) {
|
|
476
|
+
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `CmafIngestCaptionsMustBeCaptions`, `CMAF Ingest output '${this.def.outputName}': 'captions' must contain caption encodes only, got '${caption.name}'.`);
|
|
477
|
+
}
|
|
478
|
+
if (!caption._isInBandCaption()) {
|
|
479
|
+
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `CmafIngestCaptionsMustBeInBand`, `CMAF Ingest output '${this.def.outputName}': caption '${caption.name}' uses an out-of-band destination. Only in-band types (burn-in, embedded) can ride alongside the primary encode. Put out-of-band captions in their own output.`);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
// Only one embedded caption per output
|
|
483
|
+
const embeddedCount = (this.def.captions ?? []).filter(c => c._isEmbeddedCaption()).length
|
|
484
|
+
+ (this.def.encode._bindCaption() && this.def.encode._isEmbeddedCaption() ? 1 : 0);
|
|
485
|
+
if (embeddedCount > 1) {
|
|
486
|
+
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `CmafIngestOneEmbeddedCaption`, `CMAF Ingest output '${this.def.outputName}': only one embedded caption is allowed per output.`);
|
|
487
|
+
}
|
|
488
|
+
validateCodecs({
|
|
489
|
+
outputName: this.outputName,
|
|
490
|
+
allowedVideo: [video_codec_settings_1.VideoCodecType.H264, video_codec_settings_1.VideoCodecType.H265, video_codec_settings_1.VideoCodecType.AV1],
|
|
491
|
+
allowedAudio: [audio_codec_settings_1.AudioCodecType.AAC, audio_codec_settings_1.AudioCodecType.AC3, audio_codec_settings_1.AudioCodecType.EAC3, audio_codec_settings_1.AudioCodecType.EAC3_ATMOS, audio_codec_settings_1.AudioCodecType.PASSTHROUGH],
|
|
492
|
+
encodes: [this.def.encode],
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
_bindOutputSettings() {
|
|
496
|
+
return {
|
|
497
|
+
cmafIngestOutputSettings: {
|
|
498
|
+
nameModifier: this.def.nameModifier,
|
|
499
|
+
},
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
exports.CmafIngestOutput = CmafIngestOutput;
|
|
504
|
+
/** @internal */
|
|
505
|
+
class FrameCaptureOutput extends Output {
|
|
506
|
+
def;
|
|
507
|
+
constructor(def) {
|
|
508
|
+
super(def.outputName);
|
|
509
|
+
this.def = def;
|
|
510
|
+
def.encodes.forEach(e => this._addEncode(e));
|
|
511
|
+
}
|
|
512
|
+
_validate() {
|
|
513
|
+
const allowedVideo = [video_codec_settings_1.VideoCodecType.FRAME_CAPTURE];
|
|
514
|
+
this._getEncodes().forEach(encode => {
|
|
515
|
+
const vType = encode._videoCodecType();
|
|
516
|
+
if (vType && !allowedVideo.includes(vType)) {
|
|
517
|
+
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `UnsupportedVideoCodec`, `Frame Capture output '${this.outputName}' does not support video codec '${vType}'.`
|
|
518
|
+
+ ` Supported: ${allowedVideo.join(', ')}.`);
|
|
519
|
+
}
|
|
520
|
+
const aType = encode._audioCodecType();
|
|
521
|
+
if (aType) {
|
|
522
|
+
throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `UnsupportedAudioCodec`, 'Frame Capture outputs do not support audio.');
|
|
523
|
+
}
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
_bindOutputSettings() {
|
|
527
|
+
return {
|
|
528
|
+
frameCaptureOutputSettings: {
|
|
529
|
+
nameModifier: this.def.nameModifier,
|
|
530
|
+
},
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
exports.FrameCaptureOutput = FrameCaptureOutput;
|
|
535
|
+
/** @internal */
|
|
536
|
+
class MsSmoothOutput extends Output {
|
|
537
|
+
def;
|
|
538
|
+
constructor(def) {
|
|
539
|
+
super(def.outputName);
|
|
540
|
+
this.def = def;
|
|
541
|
+
def.encodes.forEach(e => this._addEncode(e));
|
|
542
|
+
}
|
|
543
|
+
_validate() {
|
|
544
|
+
validateCodecs({
|
|
545
|
+
outputName: this.outputName,
|
|
546
|
+
allowedVideo: [video_codec_settings_1.VideoCodecType.H264, video_codec_settings_1.VideoCodecType.H265],
|
|
547
|
+
allowedAudio: [audio_codec_settings_1.AudioCodecType.AAC, audio_codec_settings_1.AudioCodecType.AC3, audio_codec_settings_1.AudioCodecType.EAC3],
|
|
548
|
+
encodes: this._getEncodes(),
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
_bindOutputSettings() {
|
|
552
|
+
return {
|
|
553
|
+
msSmoothOutputSettings: {
|
|
554
|
+
nameModifier: this.def.nameModifier,
|
|
555
|
+
h265PackagingType: this.def.h265PackagingType?.value,
|
|
556
|
+
},
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
exports.MsSmoothOutput = MsSmoothOutput;
|
|
561
|
+
/** @internal */
|
|
562
|
+
class MediaConnectRouterOutput extends Output {
|
|
563
|
+
def;
|
|
564
|
+
groupName;
|
|
565
|
+
constructor(def, groupName) {
|
|
566
|
+
super(def.outputName);
|
|
567
|
+
this.def = def;
|
|
568
|
+
this.groupName = groupName;
|
|
569
|
+
def.encodes.forEach(e => this._addEncode(e));
|
|
570
|
+
}
|
|
571
|
+
_validate() {
|
|
572
|
+
validateCodecs({
|
|
573
|
+
outputName: this.outputName,
|
|
574
|
+
groupName: this.groupName,
|
|
575
|
+
allowedVideo: [video_codec_settings_1.VideoCodecType.H264, video_codec_settings_1.VideoCodecType.H265],
|
|
576
|
+
allowedAudio: [
|
|
577
|
+
audio_codec_settings_1.AudioCodecType.AAC, audio_codec_settings_1.AudioCodecType.AC3, audio_codec_settings_1.AudioCodecType.EAC3, audio_codec_settings_1.AudioCodecType.EAC3_ATMOS,
|
|
578
|
+
audio_codec_settings_1.AudioCodecType.MP2, audio_codec_settings_1.AudioCodecType.PASSTHROUGH,
|
|
579
|
+
],
|
|
580
|
+
encodes: this._getEncodes(),
|
|
581
|
+
});
|
|
582
|
+
validateSingleVideoEncode(this._getEncodes(), this.outputName, this.groupName);
|
|
583
|
+
}
|
|
584
|
+
_bindOutputSettings() {
|
|
585
|
+
return {
|
|
586
|
+
mediaConnectRouterOutputSettings: {
|
|
587
|
+
destination: {
|
|
588
|
+
destinationRefId: toDestinationId(this.groupName),
|
|
589
|
+
},
|
|
590
|
+
containerSettings: {
|
|
591
|
+
m2TsSettings: this.def.m2tsSettings?._bind() ?? {},
|
|
592
|
+
},
|
|
593
|
+
},
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
exports.MediaConnectRouterOutput = MediaConnectRouterOutput;
|
|
598
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3V0cHV0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm91dHB1dHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBeUJBLDBDQUtDO0FBWUQsd0NBcUJDO0FBT0QsOERBU0M7QUFPRCxrQ0EyQkM7OztBQWhIRCw2Q0FBNkQ7QUFHN0QsNEVBQTREO0FBQzVELGlFQUF3RDtBQUl4RCxtQ0FBbUQ7QUFFbkQsbURBQThDO0FBRTlDLGlFQUF3RDtBQUV4RDs7Ozs7Ozs7O0dBU0c7QUFDSCxTQUFnQixlQUFlLENBQUMsVUFBa0I7SUFDaEQsSUFBSSxtQkFBSyxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUM7UUFBRSxPQUFPLFVBQVUsQ0FBQztJQUN0RCxPQUFPLFVBQVU7U0FDZCxPQUFPLENBQUMsZ0JBQWdCLEVBQUUsR0FBRyxDQUFDO1NBQzlCLE9BQU8sQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDM0IsQ0FBQztBQVdELGdCQUFnQjtBQUNoQixTQUFnQixjQUFjLENBQUMsSUFBMkI7SUFDeEQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUU7UUFDNUIsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3ZDLElBQUksS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNoRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxVQUFVLGVBQWUsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDO1lBQ25HLE1BQU0sSUFBSSxxQ0FBdUIsQ0FDL0IsSUFBQSxzQkFBRyxFQUFBLHVCQUF1QixFQUMxQixXQUFXLEtBQUssbUNBQW1DLEtBQUssSUFBSTtrQkFDMUQsZUFBZSxJQUFJLENBQUMsWUFBWSxDQUFD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O1lBQ2IsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO1lBQzNCLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztZQUN6QixZQUFZLEVBQUUsQ0FBQyxxQ0FBYyxDQUFDLElBQUksRUFBRSxxQ0FBYyxDQUFDLElBQUksQ0FBQztZQUN4RCxZQUFZLEVBQUU7Z0JBQ1oscUNBQWMsQ0FBQyxHQUFHLEVBQUUscUNBQWMsQ0FBQyxHQUFHLEVBQUUscUNBQWMsQ0FBQyxJQUFJLEVBQUUscUNBQWMsQ0FBQyxVQUFVO2dCQUN0RixxQ0FBYyxDQUFDLEdBQUcsRUFBRSxxQ0FBYyxDQUFDLFdBQVc7YUFDL0M7WUFDRCxPQUFPLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFBRTtTQUM1QixDQUFDLENBQUM7UUFDSCx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7S0FDaEY7SUFFUyxtQkFBbUI7UUFDM0IsT0FBTztZQUNMLGdDQUFnQyxFQUFFO2dCQUNoQyxXQUFXLEVBQUU7b0JBQ1gsZ0JBQWdCLEVBQUUsZUFBZSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7aUJBQ2xEO2dCQUNELGlCQUFpQixFQUFFO29CQUNqQixZQUFZLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRTtpQkFDbkQ7YUFDRjtTQUNGLENBQUM7S0FDSDtDQUNGO0FBaENELDREQWdDQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgRHVyYXRpb24gfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvciwgVG9rZW4gfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgdHlwZSB7IElSb2xlLCBJUm9sZVJlZiB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0IHR5cGUgeyBDZm5DaGFubmVsIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLW1lZGlhbGl2ZSc7XG5pbXBvcnQgeyBsaXQgfSBmcm9tICdhd3MtY2RrLWxpYi9jb3JlL2xpYi9oZWxwZXJzLWludGVybmFsJztcbmltcG9ydCB7IEF1ZGlvQ29kZWNUeXBlIH0gZnJvbSAnLi9hdWRpby1jb2RlYy1zZXR0aW5ncyc7XG5pbXBvcnQgdHlwZSB7IFJ0bXBEZXN0aW5hdGlvbiwgU3J0RGVzdGluYXRpb24gfSBmcm9tICcuL2Rlc3RpbmF0aW9ucyc7XG5pbXBvcnQgdHlwZSB7IEVuY29kZUNvbmZpZ3VyYXRpb24gfSBmcm9tICcuL2VuY29kZS1jb25maWd1cmF0aW9uJztcbmltcG9ydCB0eXBlIHsgRmVjTW9kZSwgSDI2NVBhY2thZ2luZ1R5cGUsIFJ0bXBDZXJ0aWZpY2F0ZU1vZGUsIFNydEVuY3J5cHRpb25UeXBlIH0gZnJvbSAnLi9lbnVtcyc7XG5pbXBvcnQgeyBNZWRpYVBhY2thZ2VWMkhsc1NldHRpbmcgfSBmcm9tICcuL2VudW1zJztcbmltcG9ydCB0eXBlIHsgTTJ0c1NldHRpbmdzIH0gZnJvbSAnLi9tMnRzLXNldHRpbmdzJztcbmltcG9ydCB7IEhsc1NldHRpbmdzIH0gZnJvbSAnLi9tM3U4LXNldHRpbmdzJztcbmltcG9ydCB0eXBlIHsgVWRwT3V0cHV0R3JvdXBQcm9wcyB9IGZyb20gJy4vb3V0cHV0LWdyb3VwJztcbmltcG9ydCB7IFZpZGVvQ29kZWNUeXBlIH0gZnJvbSAnLi92aWRlby1jb2RlYy1zZXR0aW5ncyc7XG5cbi8qKlxuICogQ29udmVydCBhbiBvdXRwdXQgbmFtZSB0byBhIHZhbGlkIE1lZGlhTGl2ZSBjaGFubmVsIGBEZXN0aW5hdGlvbklkYC5cbiAqXG4gKiBEZXJpdmVzIGEgdmFsaWQgQ0ZOIGRlc3RpbmF0aW9uIElEIGZyb20gYSBuYW1lIChvdXRwdXQgZ3JvdXAgbmFtZSBvciBwZXItb3V0cHV0IG5hbWUpLlxuICogVGhlIHNlcnZpY2UgcmVxdWlyZXMgZGVzdGluYXRpb24gSURzIHRvIGNvbnRhaW4gb25seSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyBhbmQgaHlwaGVucyxcbiAqIHdpdGggbm8gbGVhZGluZy90cmFpbGluZyBoeXBoZW4uIFNpbmNlIG5hbWVzIG1heSBjb250YWluIHVuZGVyc2NvcmVzIG9yIG90aGVyIGNoYXJhY3RlcnMsXG4gKiB3ZSBzYW5pdGlzZSBoZXJlLlxuICpcbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgZnVuY3Rpb24gdG9EZXN0aW5hdGlvbklkKG91dHB1dE5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmIChUb2tlbi5pc1VucmVzb2x2ZWQob3V0cHV0TmFtZSkpIHJldHVybiBvdXRwdXROYW1lO1xuICByZXR1cm4gb3V0cHV0TmFtZVxuICAgIC5yZXBsYWNlKC9bXmEtekEtWjAtOV0rL2csICctJylcbiAgICAucmVwbGFjZSgvXi18LSQvZywgJycpO1xufVxuXG4vKiogQGludGVybmFsICovXG5pbnRlcmZhY2UgVmFsaWRhdGVDb2RlY3NPcHRpb25zIHtcbiAgcmVhZG9ubHkgb3V0cHV0TmFtZTogc3RyaW5nO1xuICByZWFkb25seSBncm91cE5hbWU/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGFsbG93ZWRWaWRlbzogVmlkZW9Db2RlY1R5cGVbXTtcbiAgcmVhZG9ubHkgYWxsb3dlZEF1ZGlvOiBBdWRpb0NvZGVjVHlwZVtdO1xuICByZWFkb25seSBlbmNvZGVzOiBFbmNvZGVDb25maWd1cmF0aW9uW107XG59XG5cbi8qKiBAaW50ZXJuYWwgKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZUNvZGVjcyhvcHRzOiBWYWxpZGF0ZUNvZGVjc09wdGlvbnMpOiB2b2lkIHtcbiAgb3B0cy5lbmNvZGVzLmZvckVhY2goZW5jb2RlID0+IHtcbiAgICBjb25zdCB2VHlwZSA9IGVuY29kZS5fdmlkZW9Db2RlY1R5cGUoKTtcbiAgICBpZiAodlR5cGUgJiYgIW9wdHMuYWxsb3dlZFZpZGVvLmluY2x1ZGVzKHZUeXBlKSkge1xuICAgICAgY29uc3QgbGFiZWwgPSBvcHRzLmdyb3VwTmFtZSA/IGAke29wdHMub3V0cHV0TmFtZX0nIGluIGdyb3VwICcke29wdHMuZ3JvdXBOYW1lfWAgOiBvcHRzLm91dHB1dE5hbWU7XG4gICAgICB0aHJvdyBuZXcgVW5zY29wZWRWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgIGxpdGBVbnN1cHBvcnRlZFZpZGVvQ29kZWNgLFxuICAgICAgICBgT3V0cHV0ICcke2xhYmVsfScgZG9lcyBub3Qgc3VwcG9ydCB2aWRlbyBjb2RlYyAnJHt2VHlwZX0nLmBcbiAgICAgICAgKyBgIFN1cHBvcnRlZDogJHtvcHRzLmFsbG93ZWRWaWRlby5qb2luKCcsICcpfS5gLFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgYVR5cGUgPSBlbmNvZGUuX2F1ZGlvQ29kZWNUeXBlKCk7XG4gICAgaWYgKGFUeXBlICYmICFvcHRzLmFsbG93ZWRBdWRpby5pbmNsdWRlcyhhVHlwZSkpIHtcbiAgICAgIGNvbnN0IGxhYmVsID0gb3B0cy5ncm91cE5hbWUgPyBgJHtvcHRzLm91dHB1dE5hbWV9JyBpbiBncm91cCAnJHtvcHRzLmdyb3VwTmFtZX1gIDogb3B0cy5vdXRwdXROYW1lO1xuICAgICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICBsaXRgVW5zdXBwb3J0ZWRBdWRpb0NvZGVjYCxcbiAgICAgICAgYE91dHB1dCAnJHtsYWJlbH0nIGRvZXMgbm90IHN1cHBvcnQgYXVkaW8gY29kZWMgJyR7YVR5cGV9Jy5gXG4gICAgICAgICsgYCBTdXBwb3J0ZWQ6ICR7b3B0cy5hbGxvd2VkQXVkaW8uam9pbignLCAnKX0uYCxcbiAgICAgICk7XG4gICAgfVxuICB9KTtcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgdGhhdCBhbiBNUEVHLVRTIG9yIFJUTVAgb3V0cHV0IGNvbnRhaW5zIGF0IG1vc3Qgb25lIHZpZGVvIGVuY29kZS5cbiAqIFRoZXNlIGNvbnRhaW5lciBmb3JtYXRzIHN1cHBvcnQgYSBzaW5nbGUgdmlkZW8gUElELiBNdWx0aXBsZSBhdWRpbyBlbmNvZGVzIGFyZSBhbGxvd2VkLlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVNpbmdsZVZpZGVvRW5jb2RlKGVuY29kZXM6IEVuY29kZUNvbmZpZ3VyYXRpb25bXSwgb3V0cHV0TmFtZTogc3RyaW5nLCBncm91cE5hbWU/OiBzdHJpbmcpOiB2b2lkIHtcbiAgY29uc3QgdmlkZW9FbmNvZGVzID0gZW5jb2Rlcy5maWx0ZXIoZSA9PiBlLl92aWRlb0NvZGVjVHlwZSgpICE9PSB1bmRlZmluZWQpO1xuICBpZiAodmlkZW9FbmNvZGVzLmxlbmd0aCA+IDEpIHtcbiAgICBjb25zdCBsYWJlbCA9IGdyb3VwTmFtZSA/IGAke291dHB1dE5hbWV9JyBpbiBncm91cCAnJHtncm91cE5hbWV9YCA6IG91dHB1dE5hbWU7XG4gICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKFxuICAgICAgbGl0YE11bHRpcGxlVmlkZW9FbmNvZGVzYCxcbiAgICAgIGBPdXRwdXQgJyR7bGFiZWx9JyBjb250YWlucyAke3ZpZGVvRW5jb2Rlcy5sZW5ndGh9IHZpZGVvIGVuY29kZXMsIGJ1dCBvbmx5IG9uZSBpcyBhbGxvd2VkIHBlciBvdXRwdXQuYCxcbiAgICApO1xuICB9XG59XG5cbi8qKlxuICogVmFsaWRhdGUgRkVDIG91dHB1dCBzZXR0aW5nczogU01QVEUgMjAyMi0xIHJhbmdlcywgYW5kIHRoYXQgRkVDIGlzIG9ubHkgdXNlZCB3aXRoIHJ0cDovL1xuICogZGVzdGluYXRpb25zICh0aGUgb25seSBwcm90b2NvbCBNZWRpYUxpdmUgc3VwcG9ydHMgZm9yIEZFQykuIFRva2VuaXplZCB2YWx1ZXMgYXJlIHNraXBwZWQuXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlRmVjKGZlYzogRmVjT3V0cHV0U2V0dGluZ3MgfCB1bmRlZmluZWQsIG91dHB1dE5hbWU6IHN0cmluZywgZGVzdGluYXRpb25VcmxzOiBzdHJpbmdbXSk6IHZvaWQge1xuICBpZiAoIWZlYykge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoZmVjLmNvbHVtbkRlcHRoICE9PSB1bmRlZmluZWQgJiYgIVRva2VuLmlzVW5yZXNvbHZlZChmZWMuY29sdW1uRGVwdGgpXG4gICAgJiYgKGZlYy5jb2x1bW5EZXB0aCA8IDQgfHwgZmVjLmNvbHVtbkRlcHRoID4gMjApKSB7XG4gICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKFxuICAgICAgbGl0YEZlY0NvbHVtbkRlcHRoUmFuZ2VgLFxuICAgICAgYFVEUCBvdXRwdXQgJyR7b3V0cHV0TmFtZX0nIGZlYy5jb2x1bW5EZXB0aCBtdXN0IGJlIGJldHdlZW4gNCBhbmQgMjAsIGdvdCAke0pTT04uc3RyaW5naWZ5KGZlYy5jb2x1bW5EZXB0aCl9YCxcbiAgICApO1xuICB9XG4gIGlmIChmZWMucm93TGVuZ3RoICE9PSB1bmRlZmluZWQgJiYgIVRva2VuLmlzVW5yZXNvbHZlZChmZWMucm93TGVuZ3RoKVxuICAgICYmIChmZWMucm93TGVuZ3RoIDwgMSB8fCBmZWMucm93TGVuZ3RoID4gMjApKSB7XG4gICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKFxuICAgICAgbGl0YEZlY1Jvd0xlbmd0aFJhbmdlYCxcbiAgICAgIGBVRFAgb3V0cHV0ICcke291dHB1dE5hbWV9JyBmZWMucm93TGVuZ3RoIG11c3QgYmUgYmV0d2VlbiAxIGFuZCAyMCwgZ290ICR7SlNPTi5zdHJpbmdpZnkoZmVjLnJvd0xlbmd0aCl9YCxcbiAgICApO1xuICB9XG4gIC8vIE1lZGlhTGl2ZSBvbmx5IHN1cHBvcnRzIEZFQyBvbiBydHA6Ly8gZGVzdGluYXRpb25zLiBUaGUgZGVzdGluYXRpb25zIGFyZSBzaGFyZWQgYnkgdGhlIHdob2xlXG4gIC8vIFVEUCBncm91cCwgc28gYW55IG5vbi1ydHAgZGVzdGluYXRpb24gbWFrZXMgdGhpcyBGRUMgb3V0cHV0IGludmFsaWQuXG4gIGNvbnN0IG5vblJ0cCA9IGRlc3RpbmF0aW9uVXJscy5maW5kKHVybCA9PiAhVG9rZW4uaXNVbnJlc29sdmVkKHVybCkgJiYgIXVybC5zdGFydHNXaXRoKCdydHA6Ly8nKSk7XG4gIGlmIChub25SdHAgIT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihcbiAgICAgIGxpdGBGZWNSZXF1aXJlc1J0cGAsXG4gICAgICBgVURQIG91dHB1dCAnJHtvdXRwdXROYW1lfScgaGFzIEZFQyBlbmFibGVkLCB3aGljaCByZXF1aXJlcyBldmVyeSBkZXN0aW5hdGlvbiBpbiB0aGUgZ3JvdXAgdG8gdXNlIHRoZSBydHA6Ly8gcHJvdG9jb2wsIGdvdCAke0pTT04uc3RyaW5naWZ5KG5vblJ0cCl9YCxcbiAgICApO1xuICB9XG59XG5cbi8qKlxuICogQmFzZSBvdXRwdXQgZGVmaW5pdGlvbiDigJQgc2hhcmVkIGJ5IGFsbCBvdXRwdXQgZ3JvdXAgdHlwZXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT3V0cHV0RGVmaW5pdGlvbiB7XG4gIC8qKlxuICAgKiBUaGUgZW5jb2RlIGNvbmZpZ3VyYXRpb25zIHRvIHdpcmUgdG8gdGhpcyBvdXRwdXQuXG4gICAqL1xuICByZWFkb25seSBlbmNvZGVzOiBFbmNvZGVDb25maWd1cmF0aW9uW107XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGlzIG91dHB1dC4gTXVzdCBiZSB1bmlxdWUgYWNyb3NzIGFsbCBvdXRwdXRzIGluIHRoZSBjaGFubmVsLlxuICAgKi9cbiAgcmVhZG9ubHkgb3V0cHV0TmFtZTogc3RyaW5nO1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gT3V0cHV0IChhYnN0cmFjdCBiYXNlICsgc3ViY2xhc3NlcyBwZXIgb3V0cHV0IGdyb3VwIHR5cGUpXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKipcbiAqIFJlcHJlc2VudHMgYW4gb3V0cHV0IHdpdGhpbiBhbiBvdXRwdXQgZ3JvdXAuXG4gKiBFYWNoIG91dHB1dCBncm91cCB0eXBlIGhhcyBpdHMgb3duIE91dHB1dCBzdWJjbGFzcyB0aGF0IGtub3dzIGhvdyB0byByZW5kZXIgaXRzIG91dHB1dCBzZXR0aW5ncy5cbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIE91dHB1dCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZW5jb2RlczogRW5jb2RlQ29uZmlndXJhdGlvbltdID0gW107XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgcmVhZG9ubHkgb3V0cHV0TmFtZTogc3RyaW5nKSB7XG4gICAgaWYgKCFUb2tlbi5pc1VucmVzb2x2ZWQob3V0cHV0TmFtZSkpIHtcbiAgICAgIGlmIChvdXRwdXROYW1lLmxlbmd0aCA8IDEgfHwgb3V0cHV0TmFtZS5sZW5ndGggPiAyNTYpIHtcbiAgICAgICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKGxpdGBPdXRwdXROYW1lTGVuZ3RoYCwgJ091dHB1dCBuYW1lIG11c3QgYmUgYmV0d2VlbiAxIGFuZCAyNTYgY2hhcmFjdGVycy4nKTtcbiAgICAgIH1cbiAgICAgIGlmICghL15bYS16QS1aMC05Xy1dKyQvLnRlc3Qob3V0cHV0TmFtZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKGxpdGBPdXRwdXROYW1lRm9ybWF0YCwgJ091dHB1dCBuYW1lIG11c3QgY29udGFpbiBvbmx5IGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzLCBoeXBoZW5zLCBhbmQgdW5kZXJzY29yZXMuJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwdWJsaWMgX2dldEVuY29kZXMoKTogRW5jb2RlQ29uZmlndXJhdGlvbltdIHtcbiAgICByZXR1cm4gdGhpcy5lbmNvZGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50IHRoZSBjaGFubmVsIHJvbGUgcmVhZCBhY2Nlc3MgdG8gZXh0ZXJuYWwgZmlsZXMgcmVmZXJlbmNlZCBieSB0aGlzIG91dHB1dC4gVGhlIGJhc2VcbiAgICogZ3JhbnRzIGZpbGVzIHJlZmVyZW5jZWQgYnkgdGhlIG91dHB1dCdzIGVuY29kZXMgKGUuZy4gYnVybi1pbiBjYXB0aW9uIGZvbnRzKTsgc3ViY2xhc3Nlc1xuICAgKiBvdmVycmlkZSB0byBhZGQgb3V0cHV0LXR5cGUtc3BlY2lmaWMgZmlsZXMgKGUuZy4gYXVkaW8tb25seSBjb3ZlciBhcnQpLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBfZ3JhbnRQZXJtaXNzaW9ucyhyb2xlOiBJUm9sZVJlZik6IHZvaWQge1xuICAgIHRoaXMuZW5jb2Rlcy5mb3JFYWNoKGUgPT4gZS5fZ3JhbnRSZWFkKHJvbGUpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaXJlIGFuIGVuY29kZSBjb25maWd1cmF0aW9uIHRvIHRoaXMgb3V0cHV0LlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBfYWRkRW5jb2RlKGVuY29kZTogRW5jb2RlQ29uZmlndXJhdGlvbik6IHZvaWQge1xuICAgIHRoaXMuZW5jb2Rlcy5wdXNoKGVuY29kZSk7XG4gIH1cblxuICAvKipcbiAgICogUmVuZGVyIHRoZSBvdXRwdXQgc2V0dGluZ3MgZm9yIHRoaXMgb3V0cHV0IHR5cGUuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHJvdGVjdGVkIGFic3RyYWN0IF9iaW5kT3V0cHV0U2V0dGluZ3MoKTogQ2ZuQ2hhbm5lbC5PdXRwdXRTZXR0aW5nc1Byb3BlcnR5O1xuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBlbmNvZGVzIGZvciB0aGlzIG91dHB1dCB0eXBlLiBDYWxsZWQgYXQgc3ludGggdGltZS5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBwcm90ZWN0ZWQgX3ZhbGlkYXRlKCk6IHZvaWQge1xuICAgIC8vIERlZmF1bHQ6IG5vIHZhbGlkYXRpb24uIFN1YmNsYXNzZXMgb3ZlcnJpZGUuXG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gIHB1YmxpYyBfYmluZCgpOiBDZm5DaGFubmVsLk91dHB1dFByb3BlcnR5IHtcbiAgICB0aGlzLl92YWxpZGF0ZSgpO1xuXG4gICAgY29uc3QgdmlkZW9OYW1lcyA9IHRoaXMuZW5jb2Rlcy5mbGF0TWFwKGUgPT4gZS5fYmluZFZpZGVvKCk/Lm5hbWUgPz8gW10pO1xuICAgIGNvbnN0IGF1ZGlvTmFtZXMgPSB0aGlzLmVuY29kZXMuZmxhdE1hcChlID0+IGUuX2JpbmRBdWRpbygpPy5uYW1lID8/IFtdKTtcbiAgICBjb25zdCBjYXB0aW9uTmFtZXMgPSB0aGlzLmVuY29kZXMuZmxhdE1hcChlID0+IGUuX2JpbmRDYXB0aW9uKCk/Lm5hbWUgPz8gW10pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIG91dHB1dFNldHRpbmdzOiB0aGlzLl9iaW5kT3V0cHV0U2V0dGluZ3MoKSxcbiAgICAgIG91dHB1dE5hbWU6IHRoaXMub3V0cHV0TmFtZSxcbiAgICAgIHZpZGVvRGVzY3JpcHRpb25OYW1lOiB2aWRlb05hbWVzWzBdLFxuICAgICAgYXVkaW9EZXNjcmlwdGlvbk5hbWVzOiBhdWRpb05hbWVzLmxlbmd0aCA+IDAgPyBhdWRpb05hbWVzIDogdW5kZWZpbmVkLFxuICAgICAgY2FwdGlvbkRlc2NyaXB0aW9uTmFtZXM6IGNhcHRpb25OYW1lcy5sZW5ndGggPiAwID8gY2FwdGlvbk5hbWVzIDogdW5kZWZpbmVkLFxuICAgIH07XG4gIH1cbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFBlci10eXBlIG91dHB1dCBkZWZpbml0aW9ucyAoZXh0ZW5kIGJhc2Ugd2l0aCB0eXBlLXNwZWNpZmljIHNldHRpbmdzKVxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBPdXRwdXQgZGVmaW5pdGlvbiBmb3IgYSBNZWRpYVBhY2thZ2UgVjIgb3V0cHV0IGdyb3VwLlxuICpcbiAqIE1lZGlhUGFja2FnZSBWMiB1c2VzIENNQUYgaW5nZXN0IHdoaWNoIHJlcXVpcmVzIG9uZSBtZWRpYSB0cmFjayAodmlkZW8gb3IgYXVkaW8pIHBlciBvdXRwdXQuXG4gKiBJbi1iYW5kIGNhcHRpb25zIChidXJuLWluLCBlbWJlZGRlZCkgY2FuIHJpZGUgYWxvbmdzaWRlIHRoZSBwcmltYXJ5IGVuY29kZSBiZWNhdXNlIHRoZXkgZG8gbm90XG4gKiBwcm9kdWNlIGEgc2VwYXJhdGUgdHJhY2suXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWVkaWFQYWNrYWdlVjJPdXRwdXREZWZpbml0aW9uIHtcbiAgLyoqXG4gICAqIFRoZSBwcmltYXJ5IGVuY29kZSBmb3IgdGhpcyBvdXRwdXQg4oCUIG9uZSB2aWRlbyBvciBvbmUgYXVkaW8gdHJhY2suXG4gICAqL1xuICByZWFkb25seSBlbmNvZGU6IEVuY29kZUNvbmZpZ3VyYXRpb247XG4gIC8qKlxuICAgKiBDYXB0aW9uIGVuY29kZXMgdGhhdCByaWRlIGFsb25nc2lkZSB0aGUgcHJpbWFyeSBlbmNvZGUuIE9ubHkgaW4tYmFuZCBjYXB0aW9uIHR5cGVzIGFyZVxuICAgKiBhbGxvd2VkIChidXJuLWluLCBlbWJlZGRlZCkg4oCUIG91dC1vZi1iYW5kIGNhcHRpb25zIG11c3QgZ28gaW4gdGhlaXIgb3duIG91dHB1dC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBjYXB0aW9ucyBvbiB0aGlzIG91dHB1dFxuICAgKi9cbiAgcmVhZG9ubHkgY2FwdGlvbnM/OiBFbmNvZGVDb25maWd1cmF0aW9uW107XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGlzIG91dHB1dC4gTXVzdCBiZSB1bmlxdWUgYWNyb3NzIGFsbCBvdXRwdXRzIGluIHRoZSBjaGFubmVsLlxuICAgKi9cbiAgcmVhZG9ubHkgb3V0cHV0TmFtZTogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIGF1ZGlvIGdyb3VwIElEIGZvciBhdWRpbyBvdXRwdXRzLlxuICAgKiBAZGVmYXVsdCAtIHNlcnZpY2UgZGVmYXVsdFxuICAgKi9cbiAgcmVhZG9ubHkgYXVkaW9Hcm91cElkPzogc3RyaW5nO1xuICAvKipcbiAgICogRm9yIGF1ZGlvIG91dHB1dHMsIHdoZXRoZXIgTWVkaWFQYWNrYWdlIHNldHMgdGhpcyByZW5kaXRpb24gYXMgdGhlIGF1dG8tc2VsZWN0IHJlbmRpdGlvbiBpbiB0aGVcbiAgICogSExTIG1hbmlmZXN0LlxuICAgKiBAZGVmYXVsdCBNZWRpYVBhY2thZ2VWMkhsc1NldHRpbmcuT01JVFxuICAgKi9cbiAgcmVhZG9ubHkgaGxzQXV0b1NlbGVjdD86IE1lZGlhUGFja2FnZVYySGxzU2V0dGluZztcbiAgLyoqXG4gICAqIEZvciBhdWRpbyBvdXRwdXRzLCB3aGV0aGVyIE1lZGlhUGFja2FnZSBzZXRzIHRoaXMgcmVuZGl0aW9uIGFzIHRoZSBkZWZhdWx0IHJlbmRpdGlvbiBpbiB0aGUgSExTXG4gICAqIG1hbmlmZXN0LlxuICAgKiBAZGVmYXVsdCBNZWRpYVBhY2thZ2VWMkhsc1NldHRpbmcuT01JVFxuICAgKi9cbiAgcmVhZG9ubHkgaGxzRGVmYXVsdD86IE1lZGlhUGFja2FnZVYySGxzU2V0dGluZztcbiAgLyoqXG4gICAqIFRoZSBhdWRpbyByZW5kaXRpb24gc2V0cyBmb3IgdmlkZW8gb3V0cHV0cy5cbiAgICogQGRlZmF1bHQgLSBzZXJ2aWNlIGRlZmF1bHRcbiAgICovXG4gIHJlYWRvbmx5IGF1ZGlvUmVuZGl0aW9uU2V0cz86IHN0cmluZztcbn1cblxuLyoqXG4gKiBPdXRwdXQgZGVmaW5pdGlvbiBmb3IgYW4gSExTIG91dHB1dCBncm91cC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBIbHNPdXRwdXREZWZpbml0aW9uIGV4dGVuZHMgT3V0cHV0RGVmaW5pdGlvbiB7XG4gIC8qKlxuICAgKiBBIHN0cmluZyBjb25jYXRlbmF0ZWQgdG8gdGhlIGVuZCBvZiB0aGUgZGVzdGluYXRpb24gZmlsZSBuYW1lLlxuICAgKiBAZGVmYXVsdCAtIHNlcnZpY2UgZGVmYXVsdFxuICAgKi9cbiAgcmVhZG9ubHkgbmFtZU1vZGlmaWVyPzogc3RyaW5nO1xuICAvKipcbiAgICogQSBzdHJpbmcgY29uY2F0ZW5hdGVkIHRvIHRoZSBlbmQgb2Ygc2VnbWVudCBmaWxlIG5hbWVzLlxuICAgKiBAZGVmYXVsdCAtIG5vIHNlZ21lbnQgbW9kaWZpZXJcbiAgICovXG4gIHJlYWRvbmx5IHNlZ21lbnRNb2RpZmllcj86IHN0cmluZztcbiAgLyoqXG4gICAqIEZvciBILjI2NSB2aWRlbywgd2hldGhlciB0byBwYWNrYWdlIGFzIEhFVjEgb3IgSFZDMS5cbiAgICogQGRlZmF1bHQgLSBzZXJ2aWNlIGRlZmF1bHRcbiAgICovXG4gIHJlYWRvbmx5IGgyNjVQYWNrYWdpbmdUeXBlPzogSDI2NVBhY2thZ2luZ1R5cGU7XG4gIC8qKlxuICAgKiBUaGUgcGVyLW91dHB1dCBITFMgc2V0dGluZ3MgKHN0YW5kYXJkLCBhdWRpby1vbmx5LCBmTVA0LCBvciBmcmFtZS1jYXB0dXJlKS4gVXNlIHRoZVxuICAgKiBgSGxzU2V0dGluZ3NgIGZhY3RvcnkgbWV0aG9kcy4gU3RhbmRhcmQgb3V0cHV0cyBhZGRpdGlvbmFsbHkgY29uZmlndXJlIHRoZSBNM1U4IGNvbnRhaW5lclxuICAgKiB2aWEgYEhsc1NldHRpbmdzLnN0YW5kYXJkKHsgbTN1OFNldHRpbmdzIH0pYC5cbiAgICogQGRlZmF1bHQgLSBIbHNTZXR0aW5ncy5zdGFuZGFyZCgpIHdpdGggc2VydmljZS1kZWZhdWx0IE0zVTggc2V0dGluZ3NcbiAgICovXG4gIHJlYWRvbmx5IGhsc1NldHRpbmdzPzogSGxzU2V0dGluZ3M7XG59XG5cbi8qKlxuICogRm9yd2FyZCBFcnJvciBDb3JyZWN0aW9uIChGRUMpIHNldHRpbmdzIGZvciBhIFVEUCBvdXRwdXQgKFNNUFRFIDIwMjItMSkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRmVjT3V0cHV0U2V0dGluZ3Mge1xuICAvKipcbiAgICogV2hldGhlciB0byBlbmFibGUgY29sdW1uLW9ubHkgb3IgY29sdW1uLWFuZC1yb3cgRkVDLlxuICAgKiBAZGVmYXVsdCAtIHNlcnZpY2UgZGVmYXVsdFxuICAgKi9cbiAgcmVhZG9ubHkgbW9kZT86IEZlY01vZGU7XG4gIC8qKlxuICAgKiBQYXJhbWV0ZXIgRCBmcm9tIFNNUFRFIDIwMjItMSDigJQgdGhlIGhlaWdodCBvZiB0aGUgRkVDIHByb3RlY3Rpb24gbWF0cml4IChudW1iZXIgb2ZcbiAgICogdHJhbnNwb3J0IHN0cmVhbSBwYWNrZXRzIHBlciBjb2x1bW4gZXJyb3ItY29ycmVjdGlvbiBwYWNrZXQpLiBNdXN0IGJlIDQuLjIwLlxuICAgKiBAZGVmYXVsdCAtIHNlcnZpY2UgZGVmYXVsdFxuICAgKi9cbiAgcmVhZG9ubHkgY29sdW1uRGVwdGg/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBQYXJhbWV0ZXIgTCBmcm9tIFNNUFRFIDIwMjItMSDigJQgdGhlIHdpZHRoIG9mIHRoZSBGRUMgcHJvdGVjdGlvbiBtYXRyaXguIE11c3QgYmUgMS4uMjBcbiAgICogZm9yIGNvbHVtbi1vbmx5IEZFQywgb3IgNC4uMjAgZm9yIGNvbHVtbi1hbmQtcm93IEZFQy5cbiAgICogQGRlZmF1bHQgLSBzZXJ2aWNlIGRlZmF1bHRcbiAgICovXG4gIHJlYWRvbmx5IHJvd0xlbmd0aD86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBPdXRwdXQgZGVmaW5pdGlvbiBmb3IgYSBVRFAgb3V0cHV0IGdyb3VwLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFVkcE91dHB1dERlZmluaXRpb24gZXh0ZW5kcyBPdXRwdXREZWZpbml0aW9uIHtcbiAgLyoqXG4gICAqIFRoZSBvdXRwdXQgYnVmZmVyaW5nIChvdmVycmlkZXMgZ3JvdXAtbGV2ZWwgc2V0dGluZykuIEFwcGxpZWQgYXQgbWlsbGlzZWNvbmQgZ3JhbnVsYXJpdHkuXG4gICAqIEBkZWZhdWx0IC0gdXNlcyBncm91cC1sZXZlbCBidWZmZXJcbiAgICovXG4gIHJlYWRvbmx5IGJ1ZmZlcj86IER1cmF0aW9uO1xuICAvKipcbiAgICogTVBFRy1UUyAoTTJUUykgY29udGFpbmVyIHNldHRpbmdzIGZvciB0aGlzIG91dHB1dC5cbiAgICogQGRlZmF1bHQgLSBzZXJ2aWNlIGRlZmF1bHRzXG4gICAqL1xuICByZWFkb25seSBtMnRzU2V0dGluZ3M/OiBNMnRzU2V0dGluZ3M7XG4gIC8qKlxuICAgKiBGb3J3YXJkIEVycm9yIENvcnJlY3Rpb24gKEZFQykgc2V0dGluZ3MgZm9yIHRoaXMgb3V0cHV0LlxuICAgKiBAZGVmYXVsdCAtIG5vIEZFQ1xuICAgKi9cbiAgcmVhZG9ubHkgZmVjPzogRmVjT3V0cHV0U2V0dGluZ3M7XG59XG5cbi8qKlxuICogVGhlIGNvbnRhaW5lciAodHJhbnNwb3J0IHN0cmVhbSkgZm9yIGFuIEFyY2hpdmUgb3V0cHV0LiBVc2UgdGhlIHN0YXRpYyBmYWN0b3J5IG1ldGhvZHMgdG9cbiAqIHNlbGVjdCBiZXR3ZWVuIGFuIE1QRUctVFMgKE0yVFMpIGNvbnRhaW5lciBvciBhIHJhdyBjb250YWluZXIuXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBBcmNoaXZlQ29udGFpbmVyIHtcbiAgLyoqIEFuIE1QRUctVFMgKE0yVFMpIGNvbnRhaW5lciwgb3B0aW9uYWxseSBjb25maWd1cmVkIHZpYSBgTTJ0c1NldHRpbmdzYC4gKi9cbiAgcHVibGljIHN0YXRpYyBtMnRzKHNldHRpbmdzPzogTTJ0c1NldHRpbmdzKTogQXJjaGl2ZUNvbnRhaW5lciB7XG4gICAgcmV0dXJuIG5ldyBNMnRzQXJjaGl2ZUNvbnRhaW5lcihzZXR0aW5ncyk7XG4gIH1cbiAgLyoqIEEgcmF3IGNvbnRhaW5lciAobm8gdHJhbnNwb3J0LXN0cmVhbSB3cmFwcGluZykuICovXG4gIHB1YmxpYyBzdGF0aWMgcmF3KCk6IEFyY2hpdmVDb250YWluZXIge1xuICAgIHJldHVybiBuZXcgUmF3QXJjaGl2ZUNvbnRhaW5lcigpO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwdWJsaWMgYWJzdHJhY3QgX2JpbmQoKTogQ2ZuQ2hhbm5lbC5BcmNoaXZlQ29udGFpbmVyU2V0dGluZ3NQcm9wZXJ0eTtcblxuICAvKipcbiAgICogV2hldGhlciB0aGlzIGlzIGEgcmF3IGNvbnRhaW5lci4gUmF3IGNvbnRhaW5lcnMgaG9sZCBhIHNpbmdsZSB1bmNvbXByZXNzZWQgKFdBVikgYXVkaW9cbiAgICogc3RyZWFtIOKAlCBubyB2aWRlbywgbm8gY29tcHJlc3NlZCBhdWRpby5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBwdWJsaWMgYWJzdHJhY3QgX2lzUmF3KCk6IGJvb2xlYW47XG59XG5cbi8qKiBAaW50ZXJuYWwgKi9cbmNsYXNzIE0ydHNBcmNoaXZlQ29udGFpbmVyIGV4dGVuZHMgQXJjaGl2ZUNvbnRhaW5lciB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgc2V0dGluZ3M/OiBNMnRzU2V0dGluZ3MpIHsgc3VwZXIoKTsgfVxuICBwdWJsaWMgX2JpbmQoKTogQ2ZuQ2hhbm5lbC5BcmNoaXZlQ29udGFpbmVyU2V0dGluZ3NQcm9wZXJ0eSB7XG4gICAgcmV0dXJuIHsgbTJUc1NldHRpbmdzOiB0aGlzLnNldHRpbmdzPy5fYmluZCgpID8/IHt9IH07XG4gIH1cbiAgcHVibGljIF9pc1JhdygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuY2xhc3MgUmF3QXJjaGl2ZUNvbnRhaW5lciBleHRlbmRzIEFyY2hpdmVDb250YWluZXIge1xuICBwdWJsaWMgX2JpbmQoKTogQ2ZuQ2hhbm5lbC5BcmNoaXZlQ29udGFpbmVyU2V0dGluZ3NQcm9wZXJ0eSB7XG4gICAgcmV0dXJuIHsgcmF3U2V0dGluZ3M6IHt9IH07XG4gIH1cbiAgcHVibGljIF9pc1JhdygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG4vKipcbiAqIE91dHB1dCBkZWZpbml0aW9uIGZvciBhbiBBcmNoaXZlIG91dHB1dCBncm91cC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBcmNoaXZlT3V0cHV0RGVmaW5pdGlvbiBleHRlbmRzIE91dHB1dERlZmluaXRpb24ge1xuICAvKipcbiAgICogQSBzdHJpbmcgY29uY2F0ZW5hdGVkIHRvIHRoZSBlbmQgb2YgdGhlIGRlc3RpbmF0aW9uIGZpbGUgbmFtZS4gUmVxdWlyZWQgaWYgdGhlIG91dHB1dCBncm91cFxuICAgKiBjb250YWlucyBtb3JlIHRoYW4gb25lIG91dHB1dCBvZiB0aGUgc2FtZSBjb250YWluZXIgdHlwZS5cbiAgICogQGRlZmF1bHQgLSBubyBuYW1lIG1vZGlmaWVyXG4gICAqL1xuICByZWFkb25seSBuYW1lTW9kaWZpZXI/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgb3V0cHV0IGZpbGUgZXh0ZW5zaW9uLlxuICAgKiBAZGVmYXVsdCAtIGF1dG8tc2VsZWN0ZWQgZnJvbSBjb250YWluZXIgdHlwZVxuICAgKi9cbiAgcmVhZG9ubHkgZXh0ZW5zaW9uPzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIGNvbnRhaW5lciAodHJhbnNwb3J0IHN0cmVhbSkgZm9yIHRoaXMgb3V0cHV0IOKAlCBhbiBNUEVHLVRTIChNMlRTKSBvciByYXcgY29udGFpbmVyLlxuICAgKiBVc2UgdGhlIGBBcmNoaXZlQ29udGFpbmVyYCBmYWN0b3J5IG1ldGhvZHMuXG4gICAqIEBkZWZhdWx0IC0gQXJjaGl2ZUNvbnRhaW5lci5tMnRzKCkgd2l0aCBzZXJ2aWNlLWRlZmF1bHQgTTJUUyBzZXR0aW5nc1xuICAgKi9cbiAgcmVhZG9ubHkgY29udGFpbmVyPzogQXJjaGl2ZUNvbnRhaW5lcjtcbn1cblxuLyoqXG4gKiBPdXRwdXQgZGVmaW5pdGlvbiBmb3IgYW4gUlRNUCBvdXRwdXQgZ3JvdXAuXG4gKiBgb3V0cHV0TmFtZWAgaXMgbm9ybWFsaXNlZCAodW5kZXJzY29yZXMg4oaSIGh5cGhlbnMpIGZvciB1c2UgYXMgdGhlIGRlc3RpbmF0aW9uIHJlZmVyZW5jZSBJRC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSdG1wT3V0cHV0RGVmaW5pdGlvbiBleHRlbmRzIE91dHB1dERlZmluaXRpb24ge1xuICAvKipcbiAgICogVGhlIFJUTVAgZGVzdGluYXRpb24ocykgZm9yIHRoaXMgb3V0cHV0IOKAlCBvbmUgcGVyIGNoYW5uZWwgcGlwZWxpbmUuXG4gICAqXG4gICAqIE1lZGlhTGl2ZSBwdWJsaXNoZXMgZWFjaCBSVE1QIG91dHB1dCB0byBvbmUgZGVzdGluYXRpb24gcGVyIHBpcGVsaW5lICh0aGUgY29uc29sZVxuICAgKiBjYWxscyB0aGVzZSBcIkRlc3RpbmF0aW9uIEFcIiBhbmQgXCJEZXN0aW5hdGlvbiBCXCIpLiBQcm92aWRlIGEgc2luZ2xlIGRlc3RpbmF0aW9uIGZvciBhXG4gICAqIGBTSU5HTEVfUElQRUxJTkVgIGNoYW5uZWwsIG9yIHR3byAoQSB0aGVuIEIpIGZvciBhIGBTVEFOREFSRGAgY2hhbm5lbC5cbiAgICovXG4gIHJlYWRvbmx5IGRlc3RpbmF0aW9uczogUnRtcERlc3RpbmF0aW9uW107XG4gIC8qKlxuICAgKiBUaGUgVExTIGNlcnRpZmljYXRlIHZlcmlmaWNhdGlvbiBtb2RlLlxuICAgKiBAZGVmYXVsdCAtIHNlcnZpY2UgZGVmYXVsdFxuICAgKi9cbiAgcmVhZG9ubHkgY2VydGlmaWNhdGVNb2RlPzogUnRtcENlcnRpZmljYXRlTW9kZTtcbiAgLyoqXG4gICAqIFRoZSBpbnRlcnZhbCBiZXR3ZWVuIGNvbm5lY3Rpb24gcmV0cnkgYXR0ZW1wdHMuXG4gICAqIEBkZWZhdWx0IC0gc2VydmljZSBkZWZhdWx0XG4gICAqL1xuICByZWFkb25seSBjb25uZWN0aW9uUmV0cnlJbnRlcnZhbD86IER1cmF0aW9uO1xuICAvKipcbiAgICogVGhlIG51bWJlciBvZiByZXRyeSBhdHRlbXB0cy5cbiAgICogQGRlZmF1bHQgLSBzZXJ2aWNlIGRlZmF1bHRcbiAgICovXG4gIHJlYWRvbmx5IG51bVJldHJpZXM/OiBudW1iZXI7XG59XG5cbi8qKlxuICogT3V0cHV0IGRlZmluaXRpb24gZm9yIGFuIFNSVCBvdXRwdXQgZ3JvdXAuXG4gKiBgb3V0cHV0TmFtZWAgaXMgbm9ybWFsaXNlZCAodW5kZXJzY29yZXMg4oaSIGh5cGhlbnMpIGZvciB1c2UgYXMgdGhlIGRlc3RpbmF0aW9uIHJlZmVyZW5jZSBJRC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTcnRPdXRwdXREZWZpbml0aW9uIGV4dGVuZHMgT3V0cHV0RGVmaW5pdGlvbiB7XG4gIC8qKlxuICAgKiBUaGUgU1JUIGRlc3RpbmF0aW9uKHMpIGZvciB0aGlzIG91dHB1dCDigJQgb25lIHBlciBjaGFubmVsIHBpcGVsaW5lLlxuICAgKlxuICAgKiBNZWRpYUxpdmUgcHVibGlzaGVzIGVhY2ggU1JUIG91dHB1dCB0byBvbmUgZGVzdGluYXRpb24gcGVyIHBpcGVsaW5lICh0aGUgY29uc29sZVxuICAgKiBjYWxscyB0aGVzZSBcIkRlc3RpbmF0aW9uIEFcIiBhbmQgXCJEZXN0aW5hdGlvbiBCXCIpLiBQcm92aWRlIGEgc2luZ2xlIGRlc3RpbmF0aW9uIGZvciBhXG4gICAqIGBTSU5HTEVfUElQRUxJTkVgIGNoYW5uZWwsIG9yIHR3byAoQSB0aGVuIEIpIGZvciBhIGBTVEFOREFSRGAgY2hhbm5lbC4gRWFjaCBwaXBlbGluZVxuICAgKiBjYW4gdGFyZ2V0IGEgZGlmZmVyZW50IGxpc3RlbmVyIGFuZCBjYXJyeSBpdHMgb3duIGVuY3J5cHRpb24gcGFzc3BocmFzZS5cbiAgICovXG4gIHJlYWRvbmx5IGRlc3RpbmF0aW9uczogU3J0RGVzdGluYXRpb25bXTtcbiAgLyoqXG4gICAqIFRoZSBvdXRwdXQgYnVmZmVyaW5nLiBBcHBsaWVkIGF0IG1pbGxpc2Vjb25kIGdyYW51bGFyaXR5LlxuICAgKiBAZGVmYXVsdCAtIHNlcnZpY2UgZGVmYXVsdFxuICAgKi9cbiAgcmVhZG9ubHkgYnVmZmVyPzogRHVyYXRpb247XG4gIC8qKlxuICAgKiBUaGUgZW5jcnlwdGlvbiB0eXBlIGZvciB0aGUgU1JUIG91dHB1dC5cbiAgICogQGRlZmF1bHQgLSBubyBlbmNyeXB0aW9uXG4gICAqL1xuICByZWFkb25seSBlbmNyeXB0aW9uVHlwZT86IFNydEVuY3J5cHRpb25UeXBlO1xuICAvKipcbiAgICogVGhlIFNSVCBsYXRlbmN5LlxuICAgKiBAZGVmYXVsdCAtIHNlcnZpY2UgZGVmYXVsdFxuICAgKi9cbiAgcmVhZG9ubHkgbGF0ZW5jeT86IER1cmF0aW9uO1xuICAvKipcbiAgICogTVBFRy1UUyAoTTJUUykgY29udGFpbmVyIHNldHRpbmdzIGZvciB0aGlzIG91dHB1dC5cbiAgICogQGRlZmF1bHQgLSBzZXJ2aWNlIGRlZmF1bHRzXG4gICAqL1xuICByZWFkb25seSBtMnRzU2V0dGluZ3M/OiBNMnRzU2V0dGluZ3M7XG59XG5cbi8qKlxuICogT3V0cHV0IGRlZmluaXRpb24gZm9yIGEgQ01BRiBJbmdlc3Qgb3V0cHV0IGdyb3VwLlxuICpcbiAqIENNQUYgSW5nZXN0IHJlcXVpcmVzIG9uZSBtZWRpYSB0cmFjayAodmlkZW8gb3IgYXVkaW8pIHBlciBvdXRwdXQuIEluLWJhbmQgY2FwdGlvbnMgKGJ1cm4taW4sXG4gKiBlbWJlZGRlZCkgY2FuIHJpZGUgYWxvbmdzaWRlIHRoZSBwcmltYXJ5IGVuY29kZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDbWFmSW5nZXN0T3V0cHV0RGVmaW5pdGlvbiB7XG4gIC8qKlxuICAgKiBUaGUgcHJpbWFyeSBlbmNvZGUgZm9yIHRoaXMgb3V0cHV0IOKAlCBvbmUgdmlkZW8gb3Igb25lIGF1ZGlvIHRyYWNrLlxuICAgKi9cbiAgcmVhZG9ubHkgZW5jb2RlOiBFbmNvZGVDb25maWd1cmF0aW9uO1xuICAvKipcbiAgICogQ2FwdGlvbiBlbmNvZGVzIHRoYXQgcmlkZSBhbG9uZ3NpZGUgdGhlIHByaW1hcnkgZW5jb2RlLiBPbmx5IGluLWJhbmQgY2FwdGlvbiB0eXBlcyBhcmVcbiAgICogYWxsb3dlZCAoYnVybi1pbiwgZW1iZWRkZWQpIOKAlCBvdXQtb2YtYmFuZCBjYXB0aW9ucyBtdXN0IGdvIGluIHRoZWlyIG93biBvdXRwdXQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gY2FwdGlvbnMgb24gdGhpcyBvdXRwdXRcbiAgICovXG4gIHJlYWRvbmx5IGNhcHRpb25zPzogRW5jb2RlQ29uZmlndXJhdGlvbltdO1xuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhpcyBvdXRwdXQuIE11c3QgYmUgdW5pcXVlIGFjcm9zcyBhbGwgb3V0cHV0cyBpbiB0aGUgY2hhbm5lbC5cbiAgICovXG4gIHJlYWRvbmx5IG91dHB1dE5hbWU6IHN0cmluZztcbiAgLyoqXG4gICAqIEEgc3RyaW5nIGNvbmNhdGVuYXRlZCB0byB0aGUgZW5kIG9mIHRoZSBkZXN0aW5hdGlvbiBmaWxlIG5hbWUuXG4gICAqIEBkZWZhdWx0IC0gbm8gbmFtZSBtb2RpZmllclxuICAgKi9cbiAgcmVhZG9ubHkgbmFtZU1vZGlmaWVyPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIE91dHB1dCBkZWZpbml0aW9uIGZvciBhIEZyYW1lIENhcHR1cmUgb3V0cHV0IGdyb3VwLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEZyYW1lQ2FwdHVyZU91dHB1dERlZmluaXRpb24gZXh0ZW5kcyBPdXRwdXREZWZpbml0aW9uIHtcbiAgLyoqXG4gICAqIEEgc3RyaW5nIGNvbmNhdGVuYXRlZCB0byB0aGUgZW5kIG9mIHRoZSBkZXN0aW5hdGlvbiBmaWxlIG5hbWUuXG4gICAqIFJlcXVpcmVkIGlmIHRoZSBvdXRwdXQgZ3JvdXAgY29udGFpbnMgbW9yZSB0aGFuIG9uZSBvdXRwdXQuXG4gICAqIEBkZWZhdWx0IC0gbm8gbmFtZSBtb2RpZmllclxuICAgKi9cbiAgcmVhZG9ubHkgbmFtZU1vZGlmaWVyPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIE91dHB1dCBkZWZpbml0aW9uIGZvciBhbiBNUyBTbW9vdGggb3V0cHV0IGdyb3VwLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE1zU21vb3RoT3V0cHV0RGVmaW5pdGlvbiBleHRlbmRzIE91dHB1dERlZmluaXRpb24ge1xuICAvKipcbiAgICogQSBzdHJpbmcgY29uY2F0ZW5hdGVkIHRvIHRoZSBlbmQgb2YgdGhlIGRlc3RpbmF0aW9uIGZpbGUgbmFtZS4gUmVxdWlyZWQgaWYgdGhlIG91dHB1dCBncm91cFxuICAgKiBjb250YWlucyBtb3JlIHRoYW4gb25lIG91dHB1dC5cbiAgICogQGRlZmF1bHQgLSBubyBuYW1lIG1vZGlmaWVyXG4gICAqL1xuICByZWFkb25seSBuYW1lTW9kaWZpZXI/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBGb3IgSC4yNjUgdmlkZW8sIHdoZXRoZXIgdG8gcGFja2FnZSBhcyBIRVYxIG9yIEhWQzEuXG4gICAqIEBkZWZhdWx0IC0gc2VydmljZSBkZWZhdWx0XG4gICAqL1xuICByZWFkb25seSBoMjY1UGFja2FnaW5nVHlwZT86IEgyNjVQYWNrYWdpbmdUeXBlO1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gT3V0cHV0IHN1YmNsYXNzZXMgKG9uZSBwZXIgb3V0cHV0IGdyb3VwIHR5cGUpXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vKiogQGludGVybmFsICovXG5leHBvcnQgY2xhc3MgTWVkaWFQYWNrYWdlVjJPdXRwdXQgZXh0ZW5kcyBPdXRwdXQge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGRlZjogTWVkaWFQYWNrYWdlVjJPdXRwdXREZWZpbml0aW9uLCBwcml2YXRlIHJlYWRvbmx5IGdyb3VwTmFtZTogc3RyaW5nKSB7XG4gICAgc3VwZXIoZGVmLm91dHB1dE5hbWUpO1xuICAgIHRoaXMuX2FkZEVuY29kZShkZWYuZW5jb2RlKTtcbiAgICBmb3IgKGNvbnN0IGNhcHRpb24gb2YgZGVmLmNhcHRpb25zID8/IFtdKSB7XG4gICAgICB0aGlzLl9hZGRFbmNvZGUoY2FwdGlvbik7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIF92YWxpZGF0ZSgpOiB2b2lkIHtcbiAgICBjb25zdCBlbmNvZGUgPSB0aGlzLmRlZi5lbmNvZGU7XG4gICAgaWYgKGVuY29kZS5fYmluZFZpZGVvKCkgJiYgIWVuY29kZS5faGFzRXhwbGljaXRGcmFtZXJhdGUoKSkge1xuICAgICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICBsaXRgTWVkaWFQYWNrYWdlRnJhbWVyYXRlUmVxdWlyZWRgLFxuICAgICAgICBgTWVkaWFQYWNrYWdlIFYyIG91dHB1dCBncm91cCAnJHt0aGlzLmdyb3VwTmFtZX0nIHJlcXVpcmVzIGV4cGxpY2l0IGZyYW1lcmF0ZSBvbiB2aWRlbyBlbmNvZGUgJyR7ZW5jb2RlLm5hbWV9Jy5gLFxuICAgICAgKTtcbiAgICB9XG4gICAgLy8gVmFsaWRhdGUgdGhlIHByaW1hcnkgZW5jb2RlIGlzIG5vdCBhIGNhcHRpb25cbiAgICBpZiAoZW5jb2RlLl9iaW5kQ2FwdGlvbigpKSB7XG4gICAgICB0aHJvdyBuZXcgVW5zY29wZWRWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgIGxpdGBNZWRpYVBhY2thZ2VQcmltYXJ5RW5jb2RlTm90Q2FwdGlvbmAsXG4gICAgICAgIGBNZWRpYVBhY2thZ2UgVjIgb3V0cHV0ICcke3RoaXMuZGVmLm91dHB1dE5hbWV9JzogJ2VuY29kZScgbXVzdCBiZSBhIHZpZGVvIG9yIGF1ZGlvIGVuY29kZS4gQ2FwdGlvbnMgbXVzdCBnbyBpbiB0aGUgJ2NhcHRpb25zJyBwcm9wIGFsb25nc2lkZSBhIHZpZGVvIGVuY29kZS5gLFxuICAgICAgKTtcbiAgICB9XG4gICAgLy8gVmFsaWRhdGUgY2FwdGlvbnMgYXJlIGFjdHVhbGx5IGNhcHRpb24gZW5jb2RlcyBhbmQgYXJlIGluLWJhbmQgb25seVxuICAgIGZvciAoY29uc3QgY2FwdGlvbiBvZiB0aGlzLmRlZi5jYXB0aW9ucyA/PyBbXSkge1xuICAgICAgaWYgKCFjYXB0aW9uLl9iaW5kQ2FwdGlvbigpKSB7XG4gICAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgICBsaXRgTWVkaWFQYWNrYWdlQ2FwdGlvbnNNdXN0QmVDYXB0aW9uc2AsXG4gICAgICAgICAgYE1lZGlhUGFja2FnZSBWMiBvdXRwdXQgJyR7dGhpcy5kZWYub3V0cHV0TmFtZX0nOiAnY2FwdGlvbnMnIG11c3QgY29udGFpbiBjYXB0aW9uIGVuY29kZXMgb25seSwgZ290ICcke2NhcHRpb24ubmFtZX0nLmAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoIWNhcHRpb24uX2lzSW5CYW5kQ2FwdGlvbigpKSB7XG4gICAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgICBsaXRgTWVkaWFQYWNrYWdlQ2FwdGlvbnNNdXN0QmVJbkJhbmRgLFxuICAgICAgICAgIGBNZWRpYVBhY2thZ2UgVjIgb3V0cHV0ICcke3RoaXMuZGVmLm91dHB1dE5hbWV9JzogY2FwdGlvbiAnJHtjYXB0aW9uLm5hbWV9JyB1c2VzIGFuIG91dC1vZi1iYW5kIGRlc3RpbmF0aW9uIChlLmcuIFdlYlZUVCwgVFRNTCkuIE9ubHkgaW4tYmFuZCB0eXBlcyAoYnVybi1pbiwgZW1iZWRkZWQpIGNhbiByaWRlIGFsb25nc2lkZSB0aGUgcHJpbWFyeSBlbmNvZGUuIFB1dCBvdXQtb2YtYmFuZCBjYXB0aW9ucyBpbiB0aGVpciBvd24gb3V0cHV0LmAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIE9ubHkgb25lIGVtYmVkZGVkIGNhcHRpb24gcGVyIG91dHB1dFxuICAgIGNvbnN0IGVtYmVkZGVkQ291bnQgPSAodGhpcy5kZWYuY2FwdGlvbnMgPz8gW10pLmZpbHRlcihjID0+IGMuX2lzRW1iZWRkZWRDYXB0aW9uKCkpLmxlbmd0aFxuICAgICAgKyAoZW5jb2RlLl9iaW5kQ2FwdGlvbigpICYmIGVuY29kZS5faXNFbWJlZGRlZENhcHRpb24oKSA/IDEgOiAwKTtcbiAgICBpZiAoZW1iZWRkZWRDb3VudCA+IDEpIHtcbiAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgbGl0YE1lZGlhUGFja2FnZU9uZUVtYmVkZGVkQ2FwdGlvbmAsXG4gICAgICAgIGBNZWRpYVBhY2thZ2UgVjIgb3V0cHV0ICcke3RoaXMuZGVmLm91dHB1dE5hbWV9Jzogb25seSBvbmUgZW1iZWRkZWQgY2FwdGlvbiBpcyBhbGxvd2VkIHBlciBvdXRwdXQuYCxcbiAgICAgICk7XG4gICAgfVxuICAgIHZhbGlkYXRlQ29kZWNzKHtcbiAgICAgIG91dHB1dE5hbWU6IHRoaXMuZ3JvdXBOYW1lLFxuICAgICAgLy8gTWVkaWFQYWNrYWdlIFYyIHVzZXMgQ01BRiBJbmdlc3QgdW5kZXIgdGhlIGhvb2QsIHdoaWNoIHN1cHBvcnRzIEFWMSBpbiBhZGRpdGlvbiB0b1xuICAgICAgLy8gSC4yNjQvSC4yNjUg4oCUIHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbWVkaWFwYWNrYWdlL2xhdGVzdC91c2VyZ3VpZGUvY21hZi1pbmdlc3QuaHRtbC5cbiAgICAgIGFsbG93ZWRWaWRlbzogW1ZpZGVvQ29kZWNUeXBlLkgyNjQsIFZpZGVvQ29kZWNUeXBlLkgyNjUsIFZpZGVvQ29kZWNUeXBlLkFWMSwgVmlkZW9Db2RlY1R5cGUuRlJBTUVfQ0FQVFVSRV0sXG4gICAgICBhbGxvd2VkQXVkaW86IFtBdWRpb0NvZGVjVHlwZS5BQUMsIEF1ZGlvQ29kZWNUeXBlLkFDMywgQXVkaW9Db2RlY1R5cGUuRUFDMywgQXVkaW9Db2RlY1R5cGUuRUFDM19BVE1PUywgQXVkaW9Db2RlY1R5cGUuUEFTU1RIUk9VR0hdLFxuICAgICAgZW5jb2RlczogW3RoaXMuZGVmLmVuY29kZV0sXG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgX2JpbmRPdXRwdXRTZXR0aW5ncygpOiBDZm5DaGFubmVsLk91dHB1dFNldHRpbmdzUHJvcGVydHkge1xuICAgIHJldHVybiB7XG4gICAgICBtZWRpYVBhY2thZ2VPdXRwdXRTZXR0aW5nczoge1xuICAgICAgICBtZWRpYVBhY2thZ2VWMkRlc3RpbmF0aW9uU2V0dGluZ3M6IHtcbiAgICAgICAgICBhdWRpb0dyb3VwSWQ6IHRoaXMuZGVmLmF1ZGlvR3JvdXBJZCxcbiAgICAgICAgICBhdWRpb1JlbmRpdGlvblNldHM6IHRoaXMuZGVmLmF1ZGlvUmVuZGl0aW9uU2V0cyxcbiAgICAgICAgICBobHNBdXRvU2VsZWN0OiAodGhpcy5kZWYuaGxzQXV0b1NlbGVjdCA/PyBNZWRpYVBhY2thZ2VWMkhsc1NldHRpbmcuT01JVCkudmFsdWUsXG4gICAgICAgICAgaGxzRGVmYXVsdDogKHRoaXMuZGVmLmhsc0RlZmF1bHQgPz8gTWVkaWFQYWNrYWdlVjJIbHNTZXR0aW5nLk9NSVQpLnZhbHVlLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG59XG5cbi8qKiBAaW50ZXJuYWwgKi9cbmV4cG9ydCBjbGFzcyBIbHNPdXRwdXQgZXh0ZW5kcyBPdXRwdXQge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGRlZjogSGxzT3V0cHV0RGVmaW5pdGlvbikge1xuICAgIHN1cGVyKGRlZi5vdXRwdXROYW1lKTtcbiAgICBkZWYuZW5jb2Rlcy5mb3JFYWNoKGUgPT4gdGhpcy5fYWRkRW5jb2RlKGUpKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfdmFsaWRhdGUoKTogdm9pZCB7XG4gICAgdmFsaWRhdGVDb2RlY3Moe1xuICAgICAgb3V0cHV0TmFtZTogdGhpcy5vdXRwdXROYW1lLFxuICAgICAgYWxsb3dlZFZpZGVvOiBbVmlkZW9Db2RlY1R5cGUuSDI2NCwgVmlkZW9Db2RlY1R5cGUuSDI2NSwgVmlkZW9Db2RlY1R5cGUuRlJBTUVfQ0FQVFVSRV0sXG4gICAgICBhbGxvd2VkQXVkaW86IFtBdWRpb0NvZGVjVHlwZS5BQUMsIEF1ZGlvQ29kZWNUeXBlLkFDMywgQXVkaW9Db2RlY1R5cGUuRUFDMywgQXVkaW9Db2RlY1R5cGUuRUFDM19BVE1PUywgQXVkaW9Db2RlY1R5cGUuUEFTU1RIUk9VR0hdLFxuICAgICAgZW5jb2RlczogdGhpcy5fZ2V0RW5jb2RlcygpLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9iaW5kT3V0cHV0U2V0dGluZ3MoKTogQ2ZuQ2hhbm5lbC5PdXRwdXRTZXR0aW5nc1Byb3BlcnR5IHtcbiAgICByZXR1cm4ge1xuICAgICAgaGxzT3V0cHV0U2V0dGluZ3M6IHtcbiAgICAgICAgbmFtZU1vZGlmaWVyOiB0aGlzLmRlZi5uYW1lTW9kaWZpZXIsXG4gICAgICAgIHNlZ21lbnRNb2RpZmllcjogdGhpcy5kZWYuc2VnbWVudE1vZGlmaWVyLFxuICAgICAgICBoMjY1UGFja2FnaW5nVHlwZTogdGhpcy5kZWYuaDI2NVBhY2thZ2luZ1R5cGU/LnZhbHVlLFxuICAgICAgICBobHNTZXR0aW5nczogKHRoaXMuZGVmLmhsc1NldHRpbmdzID8/IEhsc1NldHRpbmdzLnN0YW5kYXJkKCkpLl9iaW5kKCksXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBwdWJsaWMgb3ZlcnJpZGUgX2dyYW50UGVybWlzc2lvbnMocm9sZTogSVJvbGUpOiB2b2lkIHtcbiAgICBzdXBlci5fZ3JhbnRQZXJtaXNzaW9ucyhyb2xlKTtcbiAgICAvLyBBdWRpby1vbmx5IEhMUyBzZXR0aW5ncyBtYXkgcmVmZXJlbmNlIGEgY292ZXItYXJ0IGltYWdlIGluIFMzLlxuICAgIHRoaXMuZGVmLmhsc1NldHRpbmdzPy5fZ3JhbnRSZWFkKHJvbGUpO1xuICB9XG59XG5cbi8qKiBAaW50ZXJuYWwgKi9cbmV4cG9ydCBjbGFzcyBVZHBPdXRwdXQgZXh0ZW5kcyBPdXRwdXQge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGRlZjogVWRwT3V0cHV0RGVmaW5pdGlvbiwgcHJpdmF0ZSByZWFkb25seSBncm91cFByb3BzOiBVZHBPdXRwdXRHcm91cFByb3BzKSB7XG4gICAgc3VwZXIoZGVmLm91dHB1dE5hbWUpO1xuICAgIGRlZi5lbmNvZGVzLmZvckVhY2goZSA9PiB0aGlzLl9hZGRFbmNvZGUoZSkpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF92YWxpZGF0ZSgpOiB2b2lkIHtcbiAgICB2YWxpZGF0ZUNvZGVjcyh7XG4gICAgICBvdXRwdXROYW1lOiB0aGlzLm91dHB1dE5hbWUsXG4gICAgICBhbGxvd2VkVmlkZW86IFtWaWRlb0NvZGVjVHlwZS5IMjY0LCBWaWRlb0NvZGVjVHlwZS5IMjY1XSxcbiAgICAgIGFsbG93ZWRBdWRpbzogW1xuICAgICAgICBBdWRpb0NvZGVjVHlwZS5BQUMsIEF1ZGlvQ29kZWNUeXBlLkFDMywgQXVkaW9Db2RlY1R5cGUuRUFDMywgQXVkaW9Db2RlY1R5cGUuRUFDM19BVE1PUyxcbiAgICAgICAgQXVkaW9Db2RlY1R5cGUuTVAyLCBBdWRpb0NvZGVjVHlwZS5QQVNTVEhST1VHSCxcbiAgICAgIF0sXG4gICAgICBlbmNvZGVzOiB0aGlzLl9nZXRFbmNvZGVzKCksXG4gICAgfSk7XG4gICAgdmFsaWRhdGVTaW5nbGVWaWRlb0VuY29kZSh0aGlzLl9nZXRFbmNvZGVzKCksIHRoaXMub3V0cHV0TmFtZSk7XG4gICAgdmFsaWRhdGVGZWModGhpcy5kZWYuZmVjLCB0aGlzLm91dHB1dE5hbWUsIHRoaXMuZ3JvdXBQcm9wcy5kZXN0aW5hdGlvbnMubWFwKGQgPT4gZC5fYmluZCgpLnVybCkpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9iaW5kT3V0cHV0U2V0dGluZ3MoKTogQ2ZuQ2hhbm5lbC5PdXRwdXRTZXR0aW5nc1Byb3BlcnR5IHtcbiAgICByZXR1cm4ge1xuICAgICAgdWRwT3V0cHV0U2V0dGluZ3M6IHtcbiAgICAgICAgYnVmZmVyTXNlYzogdGhpcy5kZWYuYnVmZmVyPy50b01pbGxpc2Vjb25kcygpID8/IHRoaXMuZ3JvdXBQcm9wcy5idWZmZXI/LnRvTWlsbGlzZWNvbmRzKCksXG4gICAgICAgIGRlc3RpbmF0aW9uOiB7XG4gICAgICAgICAgZGVzdGluYXRpb25SZWZJZDogdGhpcy5ncm91cFByb3BzLm5hbWUsXG4gICAgICAgIH0sXG4gICAgICAgIGNvbnRhaW5lclNldHRpbmdzOiB7XG4gICAgICAgICAgbTJUc1NldHRpbmdzOiB0aGlzLmRlZi5tMnRzU2V0dGluZ3M/Ll9iaW5kKCkgPz8ge30sXG4gICAgICAgIH0sXG4gICAgICAgIGZlY091dHB1dFNldHRpbmdzOiB0aGlzLmRlZi5mZWMgPyB7XG4gICAgICAgICAgaW5jbHVkZUZlYzogdGhpcy5kZWYuZmVjLm1vZGU/LnZhbHVlLFxuICAgICAgICAgIGNvbHVtbkRlcHRoOiB0aGlzLmRlZi5mZWMuY29sdW1uRGVwdGgsXG4gICAgICAgICAgcm93TGVuZ3RoOiB0aGlzLmRlZi5mZWMucm93TGVuZ3RoLFxuICAgICAgICB9IDogdW5kZWZpbmVkLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG59XG5cbi8qKiBAaW50ZXJuYWwgKi9cbmV4cG9ydCBjbGFzcyBBcmNoaXZlT3V0cHV0IGV4dGVuZHMgT3V0cHV0IHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBkZWY6IEFyY2hpdmVPdXRwdXREZWZpbml0aW9uKSB7XG4gICAgc3VwZXIoZGVmLm91dHB1dE5hbWUpO1xuICAgIGRlZi5lbmNvZGVzLmZvckVhY2goZSA9PiB0aGlzLl9hZGRFbmNvZGUoZSkpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF92YWxpZGF0ZSgpOiB2b2lkIHtcbiAgICBjb25zdCBpc1JhdyA9ICh0aGlzLmRlZi5jb250YWluZXIgPz8gQXJjaGl2ZUNvbnRhaW5lci5tMnRzKCkpLl9pc1JhdygpO1xuICAgIGlmIChpc1Jhdykge1xuICAgICAgLy8gUmF3IGNvbnRhaW5lcnMgcmVxdWlyZSBhbiBleHBsaWNpdCBmaWxlIGV4dGVuc2lvbi5cbiAgICAgIHZhbGlkYXRlQ29kZWNzKHtcbiAgICAgICAgb3V0cHV0TmFtZTogdGhpcy5vdXRwdXROYW1lLFxuICAgICAgICBhbGxvd2VkVmlkZW86IFtWaWRlb0NvZGVjVHlwZS5IMjY0LCBWaWRlb0NvZGVjVHlwZS5IMjY1XSxcbiAgICAgICAgYWxsb3dlZEF1ZGlvOiBbXG4gICAgICAgICAgQXVkaW9Db2RlY1R5cGUuQUFDLCBBdWRpb0NvZGVjVHlwZS5BQzMsIEF1ZGlvQ29kZWNUeXBlLkVBQzMsIEF1ZGlvQ29kZWNUeXBlLkVBQzNfQVRNT1MsXG4gICAgICAgICAgQXVkaW9Db2RlY1R5cGUuTVAyLCBBdWRpb0NvZGVjVHlwZS5XQVYsIEF1ZGlvQ29kZWNUeXBlLlBBU1NUSFJPVUdILFxuICAgICAgICBdLFxuICAgICAgICBlbmNvZGVzOiB0aGlzLl9nZXRFbmNvZGVzKCksXG4gICAgICB9KTtcbiAgICAgIGlmICh0aGlzLmRlZi5leHRlbnNpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgVW5zY29wZWRWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgICAgbGl0YFJhd0FyY2hpdmVFeHRlbnNpb25SZXF1aXJlZGAsXG4gICAgICAgICAgYEFyY2hpdmUgb3V0cHV0ICcke3RoaXMub3V0cHV0TmFtZX0nIHVzZXMgYSByYXcgY29udGFpbmVyLCB3aGljaCByZXF1aXJlcyBhbiBleHBsaWNpdCAnZXh0ZW5zaW9uJ2AsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhbGlkYXRlQ29kZWNzKHtcbiAgICAgIG91dHB1dE5hbWU6IHRoaXMub3V0cHV0TmFtZSxcbiAgICAgIGFsbG93ZWRWaWRlbzogW1ZpZGVvQ29kZWNUeXBlLkgyNjQsIFZpZGVvQ29kZWNUeXBlLkgyNjVdLFxuICAgICAgYWxsb3dlZEF1ZGlvOiBbXG4gICAgICAgIEF1ZGlvQ29kZWNUeXBlLkFBQywgQXVkaW9Db2RlY1R5cGUuQUMzLCBBdWRpb0NvZGVjVHlwZS5FQUMzLCBBdWRpb0NvZGVjVHlwZS5FQUMzX0FUTU9TLFxuICAgICAgICBBdWRpb0NvZGVjVHlwZS5NUDIsIEF1ZGlvQ29kZWNUeXBlLlBBU1NUSFJPVUdILFxuICAgICAgXSxcbiAgICAgIGVuY29kZXM6IHRoaXMuX2dldEVuY29kZXMoKSxcbiAgICB9KTtcbiAgICB2YWxpZGF0ZVNpbmdsZVZpZGVvRW5jb2RlKHRoaXMuX2dldEVuY29kZXMoKSwgdGhpcy5vdXRwdXROYW1lKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfYmluZE91dHB1dFNldHRpbmdzKCk6IENmbkNoYW5uZWwuT3V0cHV0U2V0dGluZ3NQcm9wZXJ0eSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGFyY2hpdmVPdXRwdXRTZXR0aW5nczoge1xuICAgICAgICBuYW1lTW9kaWZpZXI6IHRoaXMuZGVmLm5hbWVNb2RpZmllcixcbiAgICAgICAgZXh0ZW5zaW9uOiB0aGlzLmRlZi5leHRlbnNpb24sXG4gICAgICAgIGNvbnRhaW5lclNldHRpbmdzOiAodGhpcy5kZWYuY29udGFpbmVyID8/IEFyY2hpdmVDb250YWluZXIubTJ0cygpKS5fYmluZCgpLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG59XG5cbi8qKiBAaW50ZXJuYWwgKi9cbmV4cG9ydCBjbGFzcyBSdG1wT3V0cHV0IGV4dGVuZHMgT3V0cHV0IHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBkZWY6IFJ0bXBPdXRwdXREZWZpbml0aW9uLCBwcml2YXRlIHJlYWRvbmx5IGdyb3VwTmFtZTogc3RyaW5nKSB7XG4gICAgc3VwZXIoZGVmLm91dHB1dE5hbWUpO1xuICAgIGRlZi5lbmNvZGVzLmZvckVhY2goZSA9PiB0aGlzLl9hZGRFbmNvZGUoZSkpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF92YWxpZGF0ZSgpOiB2b2lkIHtcbiAgICB2YWxpZGF0ZUNvZGVjcyh7XG4gICAgICBvdXRwdXROYW1lOiB0aGlzLm91dHB1dE5hbWUsXG4gICAgICBncm91cE5hbWU6IHRoaXMuZ3JvdXBOYW1lLFxuICAgICAgYWxsb3dlZFZpZGVvOiBbVmlkZW9Db2RlY1R5cGUuSDI2NF0sXG4gICAgICBhbGxvd2VkQXVkaW86IFtBdWRpb0NvZGVjVHlwZS5BQUNdLFxuICAgICAgZW5jb2RlczogdGhpcy5fZ2V0RW5jb2RlcygpLFxuICAgIH0pO1xuICAgIHZhbGlkYXRlU2luZ2xlVmlkZW9FbmNvZGUodGhpcy5fZ2V0RW5jb2RlcygpLCB0aGlzLm91dHB1dE5hbWUsIHRoaXMuZ3JvdXBOYW1lKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfYmluZE91dHB1dFNldHRpbmdzKCk6IENmbkNoYW5uZWwuT3V0cHV0U2V0dGluZ3NQcm9wZXJ0eSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHJ0bXBPdXRwdXRTZXR0aW5nczoge1xuICAgICAgICBjZXJ0aWZpY2F0ZU1vZGU6IHRoaXMuZGVmLmNlcnRpZmljYXRlTW9kZT8udmFsdWUsXG4gICAgICAgIGNvbm5lY3Rpb25SZXRyeUludGVydmFsOiB0aGlzLmRlZi5jb25uZWN0aW9uUmV0cnlJbnRlcnZhbD8udG9TZWNvbmRzKCksXG4gICAgICAgIG51bVJldHJpZXM6IHRoaXMuZGVmLm51bVJldHJpZXMsXG4gICAgICAgIGRlc3RpbmF0aW9uOiB7XG4gICAgICAgICAgZGVzdGluYXRpb25SZWZJZDogdG9EZXN0aW5hdGlvbklkKHRoaXMub3V0cHV0TmFtZSksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cbn1cblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGNsYXNzIFNydE91dHB1dCBleHRlbmRzIE91dHB1dCB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgZGVmOiBTcnRPdXRwdXREZWZpbml0aW9uLCBwcml2YXRlIHJlYWRvbmx5IGdyb3VwTmFtZTogc3RyaW5nKSB7XG4gICAgc3VwZXIoZGVmLm91dHB1dE5hbWUpO1xuICAgIGRlZi5lbmNvZGVzLmZvckVhY2goZSA9PiB0aGlzLl9hZGRFbmNvZGUoZSkpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF92YWxpZGF0ZSgpOiB2b2lkIHtcbiAgICB2YWxpZGF0ZUNvZGVjcyh7XG4gICAgICBvdXRwdXROYW1lOiB0aGlzLm91dHB1dE5hbWUsXG4gICAgICBncm91cE5hbWU6IHRoaXMuZ3JvdXBOYW1lLFxuICAgICAgYWxsb3dlZFZpZGVvOiBbVmlkZW9Db2RlY1R5cGUuSDI2NCwgVmlkZW9Db2RlY1R5cGUuSDI2NV0sXG4gICAgICBhbGxvd2VkQXVkaW86IFtcbiAgICAgICAgQXVkaW9Db2RlY1R5cGUuQUFDLCBBdWRpb0NvZGVjVHlwZS5BQzMsIEF1ZGlvQ29kZWNUeXBlLkVBQzMsIEF1ZGlvQ29kZWNUeXBlLkVBQzNfQVRNT1MsXG4gICAgICAgIEF1ZGlvQ29kZWNUeXBlLk1QMiwgQXVkaW9Db2RlY1R5cGUuUEFTU1RIUk9VR0gsXG4gICAgICBdLFxuICAgICAgZW5jb2RlczogdGhpcy5fZ2V0RW5jb2RlcygpLFxuICAgIH0pO1xuICAgIHZhbGlkYXRlU2luZ2xlVmlkZW9FbmNvZGUodGhpcy5fZ2V0RW5jb2RlcygpLCB0aGlzLm91dHB1dE5hbWUsIHRoaXMuZ3JvdXBOYW1lKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfYmluZE91dHB1dFNldHRpbmdzKCk6IENmbkNoYW5uZWwuT3V0cHV0U2V0dGluZ3NQcm9wZXJ0eSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNydE91dHB1dFNldHRpbmdzOiB7XG4gICAgICAgIGJ1ZmZlck1zZWM6IHRoaXMuZGVmLmJ1ZmZlcj8udG9NaWxsaXNlY29uZHMoKSxcbiAgICAgICAgZW5jcnlwdGlvblR5cGU6IHRoaXMuZGVmLmVuY3J5cHRpb25UeXBlPy52YWx1ZSxcbiAgICAgICAgbGF0ZW5jeTogdGhpcy5kZWYubGF0ZW5jeT8udG9NaWxsaXNlY29uZHMoKSxcbiAgICAgICAgLy8gRWFjaCBTUlQgb3V0cHV0IGhhcyBpdHMgb3duIGNoYW5uZWwgZGVzdGluYXRpb24sIGtleWVkIGJ5IHRoZSBvdXRwdXQgbmFtZS5cbiAgICAgICAgZGVzdGluYXRpb246IHtcbiAgICAgICAgICBkZXN0aW5hdGlvblJlZklkOiB0b0Rlc3RpbmF0aW9uSWQodGhpcy5vdXRwdXROYW1lKSxcbiAgICAgICAgfSxcbiAgICAgICAgY29udGFpbmVyU2V0dGluZ3M6IHtcbiAgICAgICAgICBtMlRzU2V0dGluZ3M6IHRoaXMuZGVmLm0ydHNTZXR0aW5ncz8uX2JpbmQoKSA/PyB7fSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxufVxuXG4vKiogQGludGVybmFsICovXG5leHBvcnQgY2xhc3MgQ21hZkluZ2VzdE91dHB1dCBleHRlbmRzIE91dHB1dCB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgZGVmOiBDbWFmSW5nZXN0T3V0cHV0RGVmaW5pdGlvbikge1xuICAgIHN1cGVyKGRlZi5vdXRwdXROYW1lKTtcbiAgICB0aGlzLl9hZGRFbmNvZGUoZGVmLmVuY29kZSk7XG4gICAgZm9yIChjb25zdCBjYXB0aW9uIG9mIGRlZi5jYXB0aW9ucyA/PyBbXSkge1xuICAgICAgdGhpcy5fYWRkRW5jb2RlKGNhcHRpb24pO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBfdmFsaWRhdGUoKTogdm9pZCB7XG4gICAgLy8gVmFsaWRhdGUgY2FwdGlvbnMgYXJlIGFjdHVhbGx5IGNhcHRpb24gZW5jb2RlcyBhbmQgYXJlIGluLWJhbmQgb25seVxuICAgIGZvciAoY29uc3QgY2FwdGlvbiBvZiB0aGlzLmRlZi5jYXB0aW9ucyA/PyBbXSkge1xuICAgICAgaWYgKCFjYXB0aW9uLl9iaW5kQ2FwdGlvbigpKSB7XG4gICAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgICBsaXRgQ21hZkluZ2VzdENhcHRpb25zTXVzdEJlQ2FwdGlvbnNgLFxuICAgICAgICAgIGBDTUFGIEluZ2VzdCBvdXRwdXQgJyR7dGhpcy5kZWYub3V0cHV0TmFtZX0nOiAnY2FwdGlvbnMnIG11c3QgY29udGFpbiBjYXB0aW9uIGVuY29kZXMgb25seSwgZ290ICcke2NhcHRpb24ubmFtZX0nLmAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoIWNhcHRpb24uX2lzSW5CYW5kQ2FwdGlvbigpKSB7XG4gICAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgICBsaXRgQ21hZkluZ2VzdENhcHRpb25zTXVzdEJlSW5CYW5kYCxcbiAgICAgICAgICBgQ01BRiBJbmdlc3Qgb3V0cHV0ICcke3RoaXMuZGVmLm91dHB1dE5hbWV9JzogY2FwdGlvbiAnJHtjYXB0aW9uLm5hbWV9JyB1c2VzIGFuIG91dC1vZi1iYW5kIGRlc3RpbmF0aW9uLiBPbmx5IGluLWJhbmQgdHlwZXMgKGJ1cm4taW4sIGVtYmVkZGVkKSBjYW4gcmlkZSBhbG9uZ3NpZGUgdGhlIHByaW1hcnkgZW5jb2RlLiBQdXQgb3V0LW9mLWJhbmQgY2FwdGlvbnMgaW4gdGhlaXIgb3duIG91dHB1dC5gLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBPbmx5IG9uZSBlbWJlZGRlZCBjYXB0aW9uIHBlciBvdXRwdXRcbiAgICBjb25zdCBlbWJlZGRlZENvdW50ID0gKHRoaXMuZGVmLmNhcHRpb25zID8/IFtdKS5maWx0ZXIoYyA9PiBjLl9pc0VtYmVkZGVkQ2FwdGlvbigpKS5sZW5ndGhcbiAgICAgICsgKHRoaXMuZGVmLmVuY29kZS5fYmluZENhcHRpb24oKSAmJiB0aGlzLmRlZi5lbmNvZGUuX2lzRW1iZWRkZWRDYXB0aW9uKCkgPyAxIDogMCk7XG4gICAgaWYgKGVtYmVkZGVkQ291bnQgPiAxKSB7XG4gICAgICB0aHJvdyBuZXcgVW5zY29wZWRWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgIGxpdGBDbWFmSW5nZXN0T25lRW1iZWRkZWRDYXB0aW9uYCxcbiAgICAgICAgYENNQUYgSW5nZXN0IG91dHB1dCAnJHt0aGlzLmRlZi5vdXRwdXROYW1lfSc6IG9ubHkgb25lIGVtYmVkZGVkIGNhcHRpb24gaXMgYWxsb3dlZCBwZXIgb3V0cHV0LmAsXG4gICAgICApO1xuICAgIH1cbiAgICB2YWxpZGF0ZUNvZGVjcyh7XG4gICAgICBvdXRwdXROYW1lOiB0aGlzLm91dHB1dE5hbWUsXG4gICAgICBhbGxvd2VkVmlkZW86IFtWaWRlb0NvZGVjVHlwZS5IMjY0LCBWaWRlb0NvZGVjVHlwZS5IMjY1LCBWaWRlb0NvZGVjVHlwZS5BVjFdLFxuICAgICAgYWxsb3dlZEF1ZGlvOiBbQXVkaW9Db2RlY1R5cGUuQUFDLCBBdWRpb0NvZGVjVHlwZS5BQzMsIEF1ZGlvQ29kZWNUeXBlLkVBQzMsIEF1ZGlvQ29kZWNUeXBlLkVBQzNfQVRNT1MsIEF1ZGlvQ29kZWNUeXBlLlBBU1NUSFJPVUdIXSxcbiAgICAgIGVuY29kZXM6IFt0aGlzLmRlZi5lbmNvZGVdLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9iaW5kT3V0cHV0U2V0dGluZ3MoKTogQ2ZuQ2hhbm5lbC5PdXRwdXRTZXR0aW5nc1Byb3BlcnR5IHtcbiAgICByZXR1cm4ge1xuICAgICAgY21hZkluZ2VzdE91dHB1dFNldHRpbmdzOiB7XG4gICAgICAgIG5hbWVNb2RpZmllcjogdGhpcy5kZWYubmFtZU1vZGlmaWVyLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG59XG5cbi8qKiBAaW50ZXJuYWwgKi9cbmV4cG9ydCBjbGFzcyBGcmFtZUNhcHR1cmVPdXRwdXQgZXh0ZW5kcyBPdXRwdXQge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGRlZjogRnJhbWVDYXB0dXJlT3V0cHV0RGVmaW5pdGlvbikge1xuICAgIHN1cGVyKGRlZi5vdXRwdXROYW1lKTtcbiAgICBkZWYuZW5jb2Rlcy5mb3JFYWNoKGUgPT4gdGhpcy5fYWRkRW5jb2RlKGUpKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfdmFsaWRhdGUoKTogdm9pZCB7XG4gICAgY29uc3QgYWxsb3dlZFZpZGVvOiBWaWRlb0NvZGVjVHlwZVtdID0gW1ZpZGVvQ29kZWNUeXBlLkZSQU1FX0NBUFRVUkVdO1xuICAgIHRoaXMuX2dldEVuY29kZXMoKS5mb3JFYWNoKGVuY29kZSA9PiB7XG4gICAgICBjb25zdCB2VHlwZSA9IGVuY29kZS5fdmlkZW9Db2RlY1R5cGUoKTtcbiAgICAgIGlmICh2VHlwZSAmJiAhYWxsb3dlZFZpZGVvLmluY2x1ZGVzKHZUeXBlKSkge1xuICAgICAgICB0aHJvdyBuZXcgVW5zY29wZWRWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgICAgbGl0YFVuc3VwcG9ydGVkVmlkZW9Db2RlY2AsXG4gICAgICAgICAgYEZyYW1lIENhcHR1cmUgb3V0cHV0ICcke3RoaXMub3V0cHV0TmFtZX0nIGRvZXMgbm90IHN1cHBvcnQgdmlkZW8gY29kZWMgJyR7dlR5cGV9Jy5gXG4gICAgICAgICAgKyBgIFN1cHBvcnRlZDogJHthbGxvd2VkVmlkZW8uam9pbignLCAnKX0uYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGFUeXBlID0gZW5jb2RlLl9hdWRpb0NvZGVjVHlwZSgpO1xuICAgICAgaWYgKGFUeXBlKSB7XG4gICAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihsaXRgVW5zdXBwb3J0ZWRBdWRpb0NvZGVjYCwgJ0ZyYW1lIENhcHR1cmUgb3V0cHV0cyBkbyBub3Qgc3VwcG9ydCBhdWRpby4nKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBfYmluZE91dHB1dFNldHRpbmdzKCk6IENmbkNoYW5uZWwuT3V0cHV0U2V0dGluZ3NQcm9wZXJ0eSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGZyYW1lQ2FwdHVyZU91dHB1dFNldHRpbmdzOiB7XG4gICAgICAgIG5hbWVNb2RpZmllcjogdGhpcy5kZWYubmFtZU1vZGlmaWVyLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG59XG5cbi8qKiBAaW50ZXJuYWwgKi9cbmV4cG9ydCBjbGFzcyBNc1Ntb290aE91dHB1dCBleHRlbmRzIE91dHB1dCB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgZGVmOiBNc1Ntb290aE91dHB1dERlZmluaXRpb24pIHtcbiAgICBzdXBlcihkZWYub3V0cHV0TmFtZSk7XG4gICAgZGVmLmVuY29kZXMuZm9yRWFjaChlID0+IHRoaXMuX2FkZEVuY29kZShlKSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgX3ZhbGlkYXRlKCk6IHZvaWQge1xuICAgIHZhbGlkYXRlQ29kZWNzKHtcbiAgICAgIG91dHB1dE5hbWU6IHRoaXMub3V0cHV0TmFtZSxcbiAgICAgIGFsbG93ZWRWaWRlbzogW1ZpZGVvQ29kZWNUeXBlLkgyNjQsIFZpZGVvQ29kZWNUeXBlLkgyNjVdLFxuICAgICAgYWxsb3dlZEF1ZGlvOiBbQXVkaW9Db2RlY1R5cGUuQUFDLCBBdWRpb0NvZGVjVHlwZS5BQzMsIEF1ZGlvQ29kZWNUeXBlLkVBQzNdLFxuICAgICAgZW5jb2RlczogdGhpcy5fZ2V0RW5jb2RlcygpLFxuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9iaW5kT3V0cHV0U2V0dGluZ3MoKTogQ2ZuQ2hhbm5lbC5PdXRwdXRTZXR0aW5nc1Byb3BlcnR5IHtcbiAgICByZXR1cm4ge1xuICAgICAgbXNTbW9vdGhPdXRwdXRTZXR0aW5nczoge1xuICAgICAgICBuYW1lTW9kaWZpZXI6IHRoaXMuZGVmLm5hbWVNb2RpZmllcixcbiAgICAgICAgaDI2NVBhY2thZ2luZ1R5cGU6IHRoaXMuZGVmLmgyNjVQYWNrYWdpbmdUeXBlPy52YWx1ZSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxufVxuXG4vKipcbiAqIE91dHB1dCBkZWZpbml0aW9uIGZvciBhIE1lZGlhQ29ubmVjdCBSb3V0ZXIgb3V0cHV0IGdyb3VwLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE1lZGlhQ29ubmVjdFJvdXRlck91dHB1dERlZmluaXRpb24gZXh0ZW5kcyBPdXRwdXREZWZpbml0aW9uIHtcbiAgLyoqXG4gICAqIE1QRUctVFMgKE0yVFMpIGNvbnRhaW5lciBzZXR0aW5ncyBmb3IgdGhpcyBvdXRwdXQuXG4gICAqIEBkZWZhdWx0IC0gc2VydmljZSBkZWZhdWx0c1xuICAgKi9cbiAgcmVhZG9ubHkgbTJ0c1NldHRpbmdzPzogTTJ0c1NldHRpbmdzO1xufVxuXG4vKiogQGludGVybmFsICovXG5leHBvcnQgY2xhc3MgTWVkaWFDb25uZWN0Um91dGVyT3V0cHV0IGV4dGVuZHMgT3V0cHV0IHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBkZWY6IE1lZGlhQ29ubmVjdFJvdXRlck91dHB1dERlZmluaXRpb24sIHByaXZhdGUgcmVhZG9ubHkgZ3JvdXBOYW1lOiBzdHJpbmcpIHtcbiAgICBzdXBlcihkZWYub3V0cHV0TmFtZSk7XG4gICAgZGVmLmVuY29kZXMuZm9yRWFjaChlID0+IHRoaXMuX2FkZEVuY29kZShlKSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgX3ZhbGlkYXRlKCk6IHZvaWQge1xuICAgIHZhbGlkYXRlQ29kZWNzKHtcbiAgICAgIG91dHB1dE5hbWU6IHRoaXMub3V0cHV0TmFtZSxcbiAgICAgIGdyb3VwTmFtZTogdGhpcy5ncm91cE5hbWUsXG4gICAgICBhbGxvd2VkVmlkZW86IFtWaWRlb0NvZGVjVHlwZS5IMjY0LCBWaWRlb0NvZGVjVHlwZS5IMjY1XSxcbiAgICAgIGFsbG93ZWRBdWRpbzogW1xuICAgICAgICBBdWRpb0NvZGVjVHlwZS5BQUMsIEF1ZGlvQ29kZWNUeXBlLkFDMywgQXVkaW9Db2RlY1R5cGUuRUFDMywgQXVkaW9Db2RlY1R5cGUuRUFDM19BVE1PUyxcbiAgICAgICAgQXVkaW9Db2RlY1R5cGUuTVAyLCBBdWRpb0NvZGVjVHlwZS5QQVNTVEhST1VHSCxcbiAgICAgIF0sXG4gICAgICBlbmNvZGVzOiB0aGlzLl9nZXRFbmNvZGVzKCksXG4gICAgfSk7XG4gICAgdmFsaWRhdGVTaW5nbGVWaWRlb0VuY29kZSh0aGlzLl9nZXRFbmNvZGVzKCksIHRoaXMub3V0cHV0TmFtZSwgdGhpcy5ncm91cE5hbWUpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9iaW5kT3V0cHV0U2V0dGluZ3MoKTogQ2ZuQ2hhbm5lbC5PdXRwdXRTZXR0aW5nc1Byb3BlcnR5IHtcbiAgICByZXR1cm4ge1xuICAgICAgbWVkaWFDb25uZWN0Um91dGVyT3V0cHV0U2V0dGluZ3M6IHtcbiAgICAgICAgZGVzdGluYXRpb246IHtcbiAgICAgICAgICBkZXN0aW5hdGlvblJlZklkOiB0b0Rlc3RpbmF0aW9uSWQodGhpcy5ncm91cE5hbWUpLFxuICAgICAgICB9LFxuICAgICAgICBjb250YWluZXJTZXR0aW5nczoge1xuICAgICAgICAgIG0yVHNTZXR0aW5nczogdGhpcy5kZWYubTJ0c1NldHRpbmdzPy5fYmluZCgpID8/IHt9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG59XG4iXX0=
|