aws-cdk-neuronx-patterns 0.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.
@@ -0,0 +1,166 @@
1
+ import { Size } from "aws-cdk-lib";
2
+ import * as ec2 from "aws-cdk-lib/aws-ec2";
3
+ import { ContainerImage } from "aws-cdk-lib/aws-ecs";
4
+ import { IBucket } from "aws-cdk-lib/aws-s3";
5
+ import { Construct } from "constructs";
6
+ import { NeuronxInstanceType } from "./neuronx-instance-type";
7
+ /**
8
+ * Compile runtime.
9
+ */
10
+ export interface CompileRuntime {
11
+ /**
12
+ * An image of the container where the compile job is executed.
13
+ */
14
+ readonly image: ContainerImage;
15
+ /**
16
+ * Neuronx version included in container image.
17
+ */
18
+ readonly neuronxVersion: string;
19
+ }
20
+ /**
21
+ * Quant data type.
22
+ */
23
+ export declare enum QuantDtype {
24
+ /**
25
+ * int8 weight storage.
26
+ */
27
+ S8 = "s8"
28
+ }
29
+ /**
30
+ * Optimization level.
31
+ */
32
+ export declare enum OptLevel {
33
+ /**
34
+ * enables the core performance optimizations in the compiler, while also minimizing compile time.
35
+ */
36
+ MINIMIZING_COMPILE_TIME = 1,
37
+ /**
38
+ * provides the best balance between model performance and compile time.
39
+ */
40
+ BEST_BALANCE = 2,
41
+ /**
42
+ * may provide additional model execution performance but may incur longer compile times and higher host memory usage during model compilation.
43
+ */
44
+ MODEL_EXECUTION_PERFORMANCE = 3
45
+ }
46
+ /**
47
+ * Compile options.
48
+ */
49
+ export interface CompileOptions {
50
+ /**
51
+ * @default - calc from parameters and quantDtype
52
+ */
53
+ readonly tpDegree?: number;
54
+ /**
55
+ * @default - No quant
56
+ */
57
+ readonly quantDtype?: QuantDtype;
58
+ /**
59
+ * @default 4092
60
+ */
61
+ readonly nPositions?: number;
62
+ /**
63
+ * @default OptLevel.BEST_BALANCE
64
+ */
65
+ readonly optLevel?: OptLevel;
66
+ }
67
+ /**
68
+ * Represents the amount of parameters.
69
+ */
70
+ export declare class Parameters {
71
+ private readonly billion;
72
+ /**
73
+ * Create a Parameters representing an amount bilion.
74
+ * @param parameters number of parameters bilionX
75
+ * @returns parameters
76
+ */
77
+ static billion(parameters: number): Parameters;
78
+ private constructor();
79
+ /**
80
+ * Return this number of parameters as bilion.
81
+ * @returns This number of parameters as bilion.
82
+ */
83
+ toBilion(): number;
84
+ }
85
+ /**
86
+ * Compile target model basic infromation
87
+ */
88
+ export interface ModelOptions {
89
+ readonly parameters: Parameters;
90
+ }
91
+ /**
92
+ * Compile target model.
93
+ */
94
+ export declare class Model {
95
+ readonly modelId: string;
96
+ readonly options: ModelOptions;
97
+ /**
98
+ * model informations at HuggingFace
99
+ * @param modelId model id on the HuggingFace
100
+ * @param options model basic infromation
101
+ * @returns model instance
102
+ */
103
+ static fromHuggingFace(modelId: string, options: ModelOptions): Model;
104
+ private constructor();
105
+ }
106
+ /**
107
+ * Props of NeuronxCompile.
108
+ */
109
+ export interface NeuronxCompileProps {
110
+ /**
111
+ * VPC in which this will launch compile worker instance.
112
+ */
113
+ readonly vpc: ec2.IVpc;
114
+ /**
115
+ * The instance type of compile worker instance.
116
+ */
117
+ readonly instanceType?: NeuronxInstanceType;
118
+ /**
119
+ * The bucket to upload compiled artifacts.
120
+ */
121
+ readonly bucket: IBucket;
122
+ /**
123
+ * The model to be compiled.
124
+ */
125
+ readonly model: Model;
126
+ /**
127
+ * The root volume of worker instance.
128
+ * @default - N bilion parameters * 5GiB EBS
129
+ */
130
+ readonly volumeSize?: Size;
131
+ /**
132
+ * Compile runtime.
133
+ * @default { neuronxSdkVersion: "2.19.0", image: ContainerImage.fromRegistry("public.ecr.aws/neuron/pytorch-training-neuronx:2.1.2-neuronx-py310-sdk2.19.0-ubuntu20.04")}
134
+ */
135
+ readonly runtime?: CompileRuntime;
136
+ /**
137
+ * Neuronx compile options.
138
+ * @default - Each properties are set default.
139
+ */
140
+ readonly compileOptions?: CompileOptions;
141
+ /**
142
+ * Whether or not to use spot instances. Spot instances are less expensive EC2 instances that can be reclaimed by EC2 at any time; your job will be given two minutes of notice before reclamation.
143
+ *
144
+ * @default false
145
+ */
146
+ readonly spot?: boolean;
147
+ /**
148
+ * The VPC Subnets this Compute Environment will launch instances in.
149
+ *
150
+ * @default - new subnets will be created
151
+ */
152
+ readonly vpcSubnets?: ec2.SubnetSelection;
153
+ }
154
+ /**
155
+ * Neuronx compile construct. Compile the model to work with Inferentia2 and Trainium1 and upload it to an S3 bucket.
156
+ */
157
+ export declare class NeuronxCompile extends Construct {
158
+ /**
159
+ * S3 URL that compiled artifact uploaded.
160
+ */
161
+ readonly compiledArtifactS3Url: string;
162
+ constructor(scope: Construct, id: string, props: NeuronxCompileProps);
163
+ private connectAcceleratorChips;
164
+ private calcTpDegree;
165
+ private selectInstanceTypeByTpDegree;
166
+ }
@@ -0,0 +1,285 @@
1
+ "use strict";
2
+ var _a, _b, _c;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.NeuronxCompile = exports.Model = exports.Parameters = exports.OptLevel = exports.QuantDtype = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ const fs_1 = require("fs");
7
+ const path_1 = require("path");
8
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
9
+ const batch = require("aws-cdk-lib/aws-batch");
10
+ const ec2 = require("aws-cdk-lib/aws-ec2");
11
+ const aws_ecs_1 = require("aws-cdk-lib/aws-ecs");
12
+ const aws_iam_1 = require("aws-cdk-lib/aws-iam");
13
+ const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
14
+ const custom_resources_1 = require("aws-cdk-lib/custom-resources");
15
+ const constructs_1 = require("constructs");
16
+ const neuronx_instance_type_1 = require("./neuronx-instance-type");
17
+ const neuron_optimized_machine_image_1 = require("./private/neuron-optimized-machine-image");
18
+ /**
19
+ * Quant data type.
20
+ */
21
+ var QuantDtype;
22
+ (function (QuantDtype) {
23
+ /**
24
+ * int8 weight storage.
25
+ */
26
+ QuantDtype["S8"] = "s8";
27
+ })(QuantDtype || (exports.QuantDtype = QuantDtype = {}));
28
+ /**
29
+ * Optimization level.
30
+ */
31
+ var OptLevel;
32
+ (function (OptLevel) {
33
+ /**
34
+ * enables the core performance optimizations in the compiler, while also minimizing compile time.
35
+ */
36
+ OptLevel[OptLevel["MINIMIZING_COMPILE_TIME"] = 1] = "MINIMIZING_COMPILE_TIME";
37
+ /**
38
+ * provides the best balance between model performance and compile time.
39
+ */
40
+ OptLevel[OptLevel["BEST_BALANCE"] = 2] = "BEST_BALANCE";
41
+ /**
42
+ * may provide additional model execution performance but may incur longer compile times and higher host memory usage during model compilation.
43
+ */
44
+ OptLevel[OptLevel["MODEL_EXECUTION_PERFORMANCE"] = 3] = "MODEL_EXECUTION_PERFORMANCE";
45
+ })(OptLevel || (exports.OptLevel = OptLevel = {}));
46
+ /**
47
+ * Represents the amount of parameters.
48
+ */
49
+ class Parameters {
50
+ /**
51
+ * Create a Parameters representing an amount bilion.
52
+ * @param parameters number of parameters bilionX
53
+ * @returns parameters
54
+ */
55
+ static billion(parameters) {
56
+ return new Parameters(parameters);
57
+ }
58
+ constructor(billion) {
59
+ this.billion = billion;
60
+ }
61
+ /**
62
+ * Return this number of parameters as bilion.
63
+ * @returns This number of parameters as bilion.
64
+ */
65
+ toBilion() {
66
+ return this.billion;
67
+ }
68
+ }
69
+ exports.Parameters = Parameters;
70
+ _a = JSII_RTTI_SYMBOL_1;
71
+ Parameters[_a] = { fqn: "aws-cdk-neuronx-patterns.Parameters", version: "0.0.0" };
72
+ /**
73
+ * Compile target model.
74
+ */
75
+ class Model {
76
+ /**
77
+ * model informations at HuggingFace
78
+ * @param modelId model id on the HuggingFace
79
+ * @param options model basic infromation
80
+ * @returns model instance
81
+ */
82
+ static fromHuggingFace(modelId, options) {
83
+ return new Model(modelId, options);
84
+ }
85
+ constructor(modelId, options) {
86
+ this.modelId = modelId;
87
+ this.options = options;
88
+ }
89
+ }
90
+ exports.Model = Model;
91
+ _b = JSII_RTTI_SYMBOL_1;
92
+ Model[_b] = { fqn: "aws-cdk-neuronx-patterns.Model", version: "0.0.0" };
93
+ /**
94
+ * Neuronx compile construct. Compile the model to work with Inferentia2 and Trainium1 and upload it to an S3 bucket.
95
+ */
96
+ class NeuronxCompile extends constructs_1.Construct {
97
+ constructor(scope, id, props) {
98
+ super(scope, id);
99
+ const nPositions = props.compileOptions?.nPositions ?? 4092;
100
+ const quantDtype = props.compileOptions?.quantDtype;
101
+ const optLevel = props.compileOptions?.optLevel ?? OptLevel.BEST_BALANCE;
102
+ const tpDegree = props.compileOptions?.tpDegree ??
103
+ this.calcTpDegree(props.model.options.parameters, {
104
+ nPositions,
105
+ quantDtype,
106
+ });
107
+ const instanceType = props.instanceType ?? this.selectInstanceTypeByTpDegree(tpDegree);
108
+ const launchTemplate = new ec2.LaunchTemplate(this, "LaunchTemplate", {
109
+ blockDevices: [
110
+ {
111
+ deviceName: "/dev/xvda",
112
+ volume: ec2.BlockDeviceVolume.ebs(props.volumeSize?.toGibibytes() ??
113
+ props.model.options.parameters.toBilion() * 5),
114
+ },
115
+ ],
116
+ });
117
+ const computeEnvironment = new batch.ManagedEc2EcsComputeEnvironment(this, "ComputeEnvironment", {
118
+ vpc: props.vpc,
119
+ vpcSubnets: props.vpcSubnets,
120
+ instanceTypes: [instanceType.instanceType],
121
+ useOptimalInstanceClasses: false,
122
+ images: [
123
+ {
124
+ image: new neuron_optimized_machine_image_1.NeuronOptimizedMachineImage(this, "MachinImage"),
125
+ // @ts-ignore
126
+ imageType: "ECS_AL2023",
127
+ },
128
+ ],
129
+ launchTemplate,
130
+ spot: props.spot,
131
+ });
132
+ computeEnvironment.node.defaultChild.addPropertyOverride("ComputeResources.LaunchTemplate.Version", launchTemplate.latestVersionNumber);
133
+ aws_cdk_lib_1.Tags.of(computeEnvironment).add("Name", "neuronx-compile-worker");
134
+ const jobQueue = new batch.JobQueue(this, "JobQueue", {
135
+ computeEnvironments: [
136
+ {
137
+ computeEnvironment,
138
+ order: 1,
139
+ },
140
+ ],
141
+ jobStateTimeLimitActions: [
142
+ {
143
+ state: batch.JobStateTimeLimitActionsState.RUNNABLE,
144
+ reason: batch.JobStateTimeLimitActionsReason.JOB_RESOURCE_REQUIREMENT,
145
+ maxTime: aws_cdk_lib_1.Duration.minutes(10),
146
+ action: batch.JobStateTimeLimitActionsAction.CANCEL,
147
+ },
148
+ ],
149
+ });
150
+ const runtime = props.runtime ?? {
151
+ image: aws_ecs_1.ContainerImage.fromRegistry("public.ecr.aws/neuron/pytorch-training-neuronx:2.1.2-neuronx-py310-sdk2.19.0-ubuntu20.04"),
152
+ neuronxVersion: "2.19.0",
153
+ neuronxTransformersVersion: "0.11.351",
154
+ };
155
+ let compiledArtifactPathPrefix = `${props.model.modelId}/neuronx-${runtime.neuronxVersion}/tp${tpDegree}-np${nPositions}-opt${optLevel}`;
156
+ if (quantDtype) {
157
+ compiledArtifactPathPrefix = `${compiledArtifactPathPrefix}-quant${quantDtype}`;
158
+ }
159
+ props.bucket.grantReadWrite(computeEnvironment.instanceRole, `${compiledArtifactPathPrefix}/*`);
160
+ const compileScript = (0, fs_1.readFileSync)((0, path_1.join)(__dirname, "private/compile.py")).toString();
161
+ const jobDefinition = new batch.EcsJobDefinition(this, "JobDefinition", {
162
+ container: new batch.EcsEc2ContainerDefinition(this, "ContainerDefinition", {
163
+ image: runtime.image,
164
+ // The fllowing command was executed on inf2.8xlarge
165
+ // sh-5.2$ free -b
166
+ // total used free shared buff/cache available
167
+ // Mem: 132265766912 866320384 130341785600 667648 1057660928 130529148928
168
+ // https://docs.aws.amazon.com/batch/latest/userguide/memory-management.html
169
+ memory: aws_cdk_lib_1.Size.mebibytes(Math.ceil(instanceType.memory.toMebibytes() * 0.95)),
170
+ cpu: instanceType.vCpu,
171
+ command: [
172
+ `cat <<EOF > compile.py\n${compileScript}\nEOF\n`,
173
+ [
174
+ runtime.neuronxTransformersVersion
175
+ ? "pip install -U --extra-index-url https://pip.repos.neuron.amazonaws.com transformers-neuronx==$NEURONX_TRANSFORMERS_VERSION"
176
+ : undefined,
177
+ "curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash",
178
+ "apt-get install git-lfs",
179
+ "git lfs install",
180
+ `git clone https://huggingface.co/${props.model.modelId} model`,
181
+ "rm -rf model/.git",
182
+ "python ./compile.py",
183
+ `aws s3 sync --no-progress ./model ${props.bucket.s3UrlForObject(`${compiledArtifactPathPrefix}/model`)}`,
184
+ `aws s3 sync --no-progress ./compiled ${props.bucket.s3UrlForObject(`${compiledArtifactPathPrefix}/compiled`)}`,
185
+ ]
186
+ .filter((v) => !!v)
187
+ .join(" && "),
188
+ ],
189
+ environment: {
190
+ MODEL_ID: props.model.modelId,
191
+ TP_DEGREE: tpDegree.toString(),
192
+ N_POSITIONS: nPositions.toString(),
193
+ OPT_LEVEL: optLevel.toString(),
194
+ QUANT_DTYPE: quantDtype?.toString() ?? "",
195
+ ARTIFACT_S3_URL: props.bucket.s3UrlForObject(compiledArtifactPathPrefix),
196
+ NEURONX_TRANSFORMERS_VERSION: runtime.neuronxTransformersVersion ?? "",
197
+ },
198
+ }),
199
+ });
200
+ this.connectAcceleratorChips(jobDefinition, instanceType);
201
+ const jobSubmitFunction = new aws_lambda_1.SingletonFunction(this, "JobSubmitFunction", {
202
+ code: aws_lambda_1.Code.fromAsset((0, path_1.join)(__dirname, "private/await-compile-job")),
203
+ handler: "index.onEvent",
204
+ runtime: aws_lambda_1.Runtime.NODEJS_20_X,
205
+ uuid: "1361f469-5c92-4c46-9e11-5d1dbf925bac",
206
+ });
207
+ jobDefinition.grantSubmitJob(jobSubmitFunction, jobQueue);
208
+ const jobMonitoringFunction = new aws_lambda_1.SingletonFunction(this, "JobMonitoringFunction", {
209
+ code: aws_lambda_1.Code.fromAsset((0, path_1.join)(__dirname, "private/await-compile-job")),
210
+ handler: "index.isComplete",
211
+ runtime: aws_lambda_1.Runtime.NODEJS_20_X,
212
+ uuid: "df16dba8-5f77-480c-a6ad-cfdf74c3de62",
213
+ });
214
+ aws_iam_1.Grant.addToPrincipal({
215
+ resourceArns: ["*"],
216
+ grantee: jobMonitoringFunction,
217
+ actions: ["batch:DescribeJobs"],
218
+ });
219
+ const provider = new custom_resources_1.Provider(this, "CompileJobProvider", {
220
+ onEventHandler: jobSubmitFunction,
221
+ isCompleteHandler: jobMonitoringFunction,
222
+ queryInterval: aws_cdk_lib_1.Duration.minutes(1),
223
+ totalTimeout: aws_cdk_lib_1.Duration.hours(1),
224
+ });
225
+ const compileJob = new aws_cdk_lib_1.CustomResource(this, "CompileJob", {
226
+ serviceToken: provider.serviceToken,
227
+ resourceType: "Custom::CompileJob",
228
+ properties: {
229
+ jobDefinitionArn: jobDefinition.jobDefinitionArn,
230
+ jobQueueArn: jobQueue.jobQueueArn,
231
+ artifactS3Url: props.bucket.s3UrlForObject(compiledArtifactPathPrefix),
232
+ },
233
+ });
234
+ this.compiledArtifactS3Url = compileJob.getAttString("ArtifactS3Url");
235
+ }
236
+ connectAcceleratorChips(jobDefinition, instanceType) {
237
+ const devices = Array.from({
238
+ length: instanceType.acceleratorChips.chips,
239
+ }).map((_, index) => ({
240
+ HostPath: `/dev/neuron${index}`,
241
+ ContainerPath: `/dev/neuron${index}`,
242
+ Permissions: ["read", "write"],
243
+ }));
244
+ const cfnJobDefinition = jobDefinition.node
245
+ .defaultChild;
246
+ cfnJobDefinition.addPropertyOverride("ContainerProperties.LinuxParameters.Devices", devices);
247
+ }
248
+ calcTpDegree(parameters, compileOptions) {
249
+ // case of float16
250
+ const bytesPerParamete = 16 / 8;
251
+ // memory = bytes per parameter * number of parameters
252
+ let memory = aws_cdk_lib_1.Size.gibibytes(bytesPerParamete * parameters.toBilion());
253
+ switch (compileOptions.quantDtype) {
254
+ case QuantDtype.S8:
255
+ memory = aws_cdk_lib_1.Size.gibibytes(memory.toGibibytes() / 2);
256
+ break;
257
+ }
258
+ const neronxCoreMemory = aws_cdk_lib_1.Size.gibibytes(16);
259
+ const minimum = Math.ceil(memory.toGibibytes() / neronxCoreMemory.toGibibytes());
260
+ const tpDegrees = [1, 2, 4, 8, 24];
261
+ for (const tpDegree of tpDegrees) {
262
+ if (minimum <= tpDegree) {
263
+ return tpDegree;
264
+ }
265
+ }
266
+ throw new Error("This model is too large, I can not support this model current version.");
267
+ }
268
+ selectInstanceTypeByTpDegree(tpDegree) {
269
+ const instanceTypes = [
270
+ neuronx_instance_type_1.NeuronxInstanceType.INF2_8XLARGE,
271
+ neuronx_instance_type_1.NeuronxInstanceType.INF2_24XLARGE,
272
+ neuronx_instance_type_1.NeuronxInstanceType.INF2_48XLARGE,
273
+ ];
274
+ for (const instanceType of instanceTypes) {
275
+ if (tpDegree <= instanceType.acceleratorChips.neuronxCores) {
276
+ return instanceType;
277
+ }
278
+ }
279
+ throw new Error("This model is too large, I can not support this model current version.");
280
+ }
281
+ }
282
+ exports.NeuronxCompile = NeuronxCompile;
283
+ _c = JSII_RTTI_SYMBOL_1;
284
+ NeuronxCompile[_c] = { fqn: "aws-cdk-neuronx-patterns.NeuronxCompile", version: "0.0.0" };
285
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV1cm9ueC1jb21waWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL25ldXJvbngtY29tcGlsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDJCQUFrQztBQUNsQywrQkFBNEI7QUFDNUIsNkNBQW1FO0FBQ25FLCtDQUErQztBQUMvQywyQ0FBMkM7QUFDM0MsaURBQXFEO0FBQ3JELGlEQUE0QztBQUM1Qyx1REFBMEU7QUFFMUUsbUVBQXdEO0FBQ3hELDJDQUF1QztBQUN2QyxtRUFBOEQ7QUFDOUQsNkZBQXVGO0FBZ0J2Rjs7R0FFRztBQUNILElBQVksVUFLWDtBQUxELFdBQVksVUFBVTtJQUNwQjs7T0FFRztJQUNILHVCQUFTLENBQUE7QUFDWCxDQUFDLEVBTFcsVUFBVSwwQkFBVixVQUFVLFFBS3JCO0FBRUQ7O0dBRUc7QUFDSCxJQUFZLFFBYVg7QUFiRCxXQUFZLFFBQVE7SUFDbEI7O09BRUc7SUFDSCw2RUFBMkIsQ0FBQTtJQUMzQjs7T0FFRztJQUNILHVEQUFnQixDQUFBO0lBQ2hCOztPQUVHO0lBQ0gscUZBQStCLENBQUE7QUFDakMsQ0FBQyxFQWJXLFFBQVEsd0JBQVIsUUFBUSxRQWFuQjtBQXdCRDs7R0FFRztBQUNILE1BQWEsVUFBVTtJQUNyQjs7OztPQUlHO0lBQ0gsTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFrQjtRQUMvQixPQUFPLElBQUksVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFDRCxZQUFxQyxPQUFlO1FBQWYsWUFBTyxHQUFQLE9BQU8sQ0FBUTtJQUFHLENBQUM7SUFDeEQ7OztPQUdHO0lBQ0gsUUFBUTtRQUNOLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN0QixDQUFDOztBQWhCSCxnQ0FpQkM7OztBQVFEOztHQUVHO0FBQ0gsTUFBYSxLQUFLO0lBQ2hCOzs7OztPQUtHO0lBQ0gsTUFBTSxDQUFDLGVBQWUsQ0FBQyxPQUFlLEVBQUUsT0FBcUI7UUFDM0QsT0FB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QUMzRCxPQUFPLFlBQVksQ0FBQztZQUN0QixDQUFDO1FBQ0gsQ0FBQztRQUNELE1BQU0sSUFBSSxLQUFLLENBQ2Isd0VBQXdFLENBQ3pFLENBQUM7SUFDSixDQUFDOztBQXpQSCx3Q0EwUEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyByZWFkRmlsZVN5bmMgfSBmcm9tIFwiZnNcIjtcbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgQ3VzdG9tUmVzb3VyY2UsIER1cmF0aW9uLCBTaXplLCBUYWdzIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgKiBhcyBiYXRjaCBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWJhdGNoXCI7XG5pbXBvcnQgKiBhcyBlYzIgZnJvbSBcImF3cy1jZGstbGliL2F3cy1lYzJcIjtcbmltcG9ydCB7IENvbnRhaW5lckltYWdlIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lY3NcIjtcbmltcG9ydCB7IEdyYW50IH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1pYW1cIjtcbmltcG9ydCB7IENvZGUsIFJ1bnRpbWUsIFNpbmdsZXRvbkZ1bmN0aW9uIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1sYW1iZGFcIjtcbmltcG9ydCB7IElCdWNrZXQgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXMzXCI7XG5pbXBvcnQgeyBQcm92aWRlciB9IGZyb20gXCJhd3MtY2RrLWxpYi9jdXN0b20tcmVzb3VyY2VzXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuaW1wb3J0IHsgTmV1cm9ueEluc3RhbmNlVHlwZSB9IGZyb20gXCIuL25ldXJvbngtaW5zdGFuY2UtdHlwZVwiO1xuaW1wb3J0IHsgTmV1cm9uT3B0aW1pemVkTWFjaGluZUltYWdlIH0gZnJvbSBcIi4vcHJpdmF0ZS9uZXVyb24tb3B0aW1pemVkLW1hY2hpbmUtaW1hZ2VcIjtcblxuLyoqXG4gKiBDb21waWxlIHJ1bnRpbWUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcGlsZVJ1bnRpbWUge1xuICAvKipcbiAgICogQW4gaW1hZ2Ugb2YgdGhlIGNvbnRhaW5lciB3aGVyZSB0aGUgY29tcGlsZSBqb2IgaXMgZXhlY3V0ZWQuXG4gICAqL1xuICByZWFkb25seSBpbWFnZTogQ29udGFpbmVySW1hZ2U7XG4gIC8qKlxuICAgKiBOZXVyb254IHZlcnNpb24gaW5jbHVkZWQgaW4gY29udGFpbmVyIGltYWdlLlxuICAgKi9cbiAgcmVhZG9ubHkgbmV1cm9ueFZlcnNpb246IHN0cmluZztcbn1cblxuLyoqXG4gKiBRdWFudCBkYXRhIHR5cGUuXG4gKi9cbmV4cG9ydCBlbnVtIFF1YW50RHR5cGUge1xuICAvKipcbiAgICogaW50OCB3ZWlnaHQgc3RvcmFnZS5cbiAgICovXG4gIFM4ID0gXCJzOFwiLFxufVxuXG4vKipcbiAqIE9wdGltaXphdGlvbiBsZXZlbC5cbiAqL1xuZXhwb3J0IGVudW0gT3B0TGV2ZWwge1xuICAvKipcbiAgICogZW5hYmxlcyB0aGUgY29yZSBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb25zIGluIHRoZSBjb21waWxlciwgd2hpbGUgYWxzbyBtaW5pbWl6aW5nIGNvbXBpbGUgdGltZS5cbiAgICovXG4gIE1JTklNSVpJTkdfQ09NUElMRV9USU1FID0gMSxcbiAgLyoqXG4gICAqIHByb3ZpZGVzIHRoZSBiZXN0IGJhbGFuY2UgYmV0d2VlbiBtb2RlbCBwZXJmb3JtYW5jZSBhbmQgY29tcGlsZSB0aW1lLlxuICAgKi9cbiAgQkVTVF9CQUxBTkNFID0gMixcbiAgLyoqXG4gICAqIG1heSBwcm92aWRlIGFkZGl0aW9uYWwgbW9kZWwgZXhlY3V0aW9uIHBlcmZvcm1hbmNlIGJ1dCBtYXkgaW5jdXIgbG9uZ2VyIGNvbXBpbGUgdGltZXMgYW5kIGhpZ2hlciBob3N0IG1lbW9yeSB1c2FnZSBkdXJpbmcgbW9kZWwgY29tcGlsYXRpb24uXG4gICAqL1xuICBNT0RFTF9FWEVDVVRJT05fUEVSRk9STUFOQ0UgPSAzLFxufVxuXG4vKipcbiAqIENvbXBpbGUgb3B0aW9ucy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb21waWxlT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBAZGVmYXVsdCAtIGNhbGMgZnJvbSBwYXJhbWV0ZXJzIGFuZCBxdWFudER0eXBlXG4gICAqL1xuICByZWFkb25seSB0cERlZ3JlZT86IG51bWJlcjtcbiAgLyoqXG4gICAqIEBkZWZhdWx0IC0gTm8gcXVhbnRcbiAgICovXG4gIHJlYWRvbmx5IHF1YW50RHR5cGU/OiBRdWFudER0eXBlO1xuICAvKipcbiAgICogQGRlZmF1bHQgNDA5MlxuICAgKi9cbiAgcmVhZG9ubHkgblBvc2l0aW9ucz86IG51bWJlcjtcbiAgLyoqXG4gICAqIEBkZWZhdWx0IE9wdExldmVsLkJFU1RfQkFMQU5DRVxuICAgKi9cbiAgcmVhZG9ubHkgb3B0TGV2ZWw/OiBPcHRMZXZlbDtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRzIHRoZSBhbW91bnQgb2YgcGFyYW1ldGVycy5cbiAqL1xuZXhwb3J0IGNsYXNzIFBhcmFtZXRlcnMge1xuICAvKipcbiAgICogQ3JlYXRlIGEgUGFyYW1ldGVycyByZXByZXNlbnRpbmcgYW4gYW1vdW50IGJpbGlvbi5cbiAgICogQHBhcmFtIHBhcmFtZXRlcnMgbnVtYmVyIG9mIHBhcmFtZXRlcnMgYmlsaW9uWFxuICAgKiBAcmV0dXJucyBwYXJhbWV0ZXJzXG4gICAqL1xuICBzdGF0aWMgYmlsbGlvbihwYXJhbWV0ZXJzOiBudW1iZXIpIHtcbiAgICByZXR1cm4gbmV3IFBhcmFtZXRlcnMocGFyYW1ldGVycyk7XG4gIH1cbiAgcHJpdmF0ZSBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGJpbGxpb246IG51bWJlcikge31cbiAgLyoqXG4gICAqIFJldHVybiB0aGlzIG51bWJlciBvZiBwYXJhbWV0ZXJzIGFzIGJpbGlvbi5cbiAgICogQHJldHVybnMgVGhpcyBudW1iZXIgb2YgcGFyYW1ldGVycyBhcyBiaWxpb24uXG4gICAqL1xuICB0b0JpbGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5iaWxsaW9uO1xuICB9XG59XG5cbi8qKlxuICogQ29tcGlsZSB0YXJnZXQgbW9kZWwgYmFzaWMgaW5mcm9tYXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNb2RlbE9wdGlvbnMge1xuICByZWFkb25seSBwYXJhbWV0ZXJzOiBQYXJhbWV0ZXJzO1xufVxuLyoqXG4gKiBDb21waWxlIHRhcmdldCBtb2RlbC5cbiAqL1xuZXhwb3J0IGNsYXNzIE1vZGVsIHtcbiAgLyoqXG4gICAqIG1vZGVsIGluZm9ybWF0aW9ucyBhdCBIdWdnaW5nRmFjZVxuICAgKiBAcGFyYW0gbW9kZWxJZCBtb2RlbCBpZCBvbiB0aGUgSHVnZ2luZ0ZhY2VcbiAgICogQHBhcmFtIG9wdGlvbnMgbW9kZWwgYmFzaWMgaW5mcm9tYXRpb25cbiAgICogQHJldHVybnMgbW9kZWwgaW5zdGFuY2VcbiAgICovXG4gIHN0YXRpYyBmcm9tSHVnZ2luZ0ZhY2UobW9kZWxJZDogc3RyaW5nLCBvcHRpb25zOiBNb2RlbE9wdGlvbnMpIHtcbiAgICByZXR1cm4gbmV3IE1vZGVsKG1vZGVsSWQsIG9wdGlvbnMpO1xuICB9XG4gIHByaXZhdGUgY29uc3RydWN0b3IoXG4gICAgcmVhZG9ubHkgbW9kZWxJZDogc3RyaW5nLFxuICAgIHJlYWRvbmx5IG9wdGlvbnM6IE1vZGVsT3B0aW9ucyxcbiAgKSB7fVxufVxuLyoqXG4gKiBQcm9wcyBvZiBOZXVyb254Q29tcGlsZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBOZXVyb254Q29tcGlsZVByb3BzIHtcbiAgLyoqXG4gICAqIFZQQyBpbiB3aGljaCB0aGlzIHdpbGwgbGF1bmNoIGNvbXBpbGUgd29ya2VyIGluc3RhbmNlLlxuICAgKi9cbiAgcmVhZG9ubHkgdnBjOiBlYzIuSVZwYztcbiAgLyoqXG4gICAqIFRoZSBpbnN0YW5jZSB0eXBlIG9mIGNvbXBpbGUgd29ya2VyIGluc3RhbmNlLlxuICAgKi9cbiAgcmVhZG9ubHkgaW5zdGFuY2VUeXBlPzogTmV1cm9ueEluc3RhbmNlVHlwZTtcbiAgLyoqXG4gICAqIFRoZSBidWNrZXQgdG8gdXBsb2FkIGNvbXBpbGVkIGFydGlmYWN0cy5cbiAgICovXG4gIHJlYWRvbmx5IGJ1Y2tldDogSUJ1Y2tldDtcbiAgLyoqXG4gICAqIFRoZSBtb2RlbCB0byBiZSBjb21waWxlZC5cbiAgICovXG4gIHJlYWRvbmx5IG1vZGVsOiBNb2RlbDtcbiAgLyoqXG4gICAqIFRoZSByb290IHZvbHVtZSBvZiB3b3JrZXIgaW5zdGFuY2UuXG4gICAqIEBkZWZhdWx0IC0gTiBiaWxpb24gcGFyYW1ldGVycyAqIDVHaUIgRUJTXG4gICAqL1xuICByZWFkb25seSB2b2x1bWVTaXplPzogU2l6ZTtcbiAgLyoqXG4gICAqIENvbXBpbGUgcnVudGltZS5cbiAgICogQGRlZmF1bHQgeyBuZXVyb254U2RrVmVyc2lvbjogXCIyLjE5LjBcIiwgaW1hZ2U6IENvbnRhaW5lckltYWdlLmZyb21SZWdpc3RyeShcInB1YmxpYy5lY3IuYXdzL25ldXJvbi9weXRvcmNoLXRyYWluaW5nLW5ldXJvbng6Mi4xLjItbmV1cm9ueC1weTMxMC1zZGsyLjE5LjAtdWJ1bnR1MjAuMDRcIil9XG4gICAqL1xuICByZWFkb25seSBydW50aW1lPzogQ29tcGlsZVJ1bnRpbWU7XG4gIC8qKlxuICAgKiBOZXVyb254IGNvbXBpbGUgb3B0aW9ucy5cbiAgICogQGRlZmF1bHQgLSBFYWNoIHByb3BlcnRpZXMgYXJlIHNldCBkZWZhdWx0LlxuICAgKi9cbiAgcmVhZG9ubHkgY29tcGlsZU9wdGlvbnM/OiBDb21waWxlT3B0aW9ucztcbiAgLyoqXG4gICAqIFdoZXRoZXIgb3Igbm90IHRvIHVzZSBzcG90IGluc3RhbmNlcy4gU3BvdCBpbnN0YW5jZXMgYXJlIGxlc3MgZXhwZW5zaXZlIEVDMiBpbnN0YW5jZXMgdGhhdCBjYW4gYmUgcmVjbGFpbWVkIGJ5IEVDMiBhdCBhbnkgdGltZTsgeW91ciBqb2Igd2lsbCBiZSBnaXZlbiB0d28gbWludXRlcyBvZiBub3RpY2UgYmVmb3JlIHJlY2xhbWF0aW9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgc3BvdD86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBUaGUgVlBDIFN1Ym5ldHMgdGhpcyBDb21wdXRlIEVudmlyb25tZW50IHdpbGwgbGF1bmNoIGluc3RhbmNlcyBpbi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBuZXcgc3VibmV0cyB3aWxsIGJlIGNyZWF0ZWRcbiAgICovXG4gIHJlYWRvbmx5IHZwY1N1Ym5ldHM/OiBlYzIuU3VibmV0U2VsZWN0aW9uO1xufVxuXG4vKipcbiAqIE5ldXJvbnggY29tcGlsZSBjb25zdHJ1Y3QuIENvbXBpbGUgdGhlIG1vZGVsIHRvIHdvcmsgd2l0aCBJbmZlcmVudGlhMiBhbmQgVHJhaW5pdW0xIGFuZCB1cGxvYWQgaXQgdG8gYW4gUzMgYnVja2V0LlxuICovXG5leHBvcnQgY2xhc3MgTmV1cm9ueENvbXBpbGUgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKipcbiAgICogUzMgVVJMIHRoYXQgY29tcGlsZWQgYXJ0aWZhY3QgdXBsb2FkZWQuXG4gICAqL1xuICByZWFkb25seSBjb21waWxlZEFydGlmYWN0UzNVcmw6IHN0cmluZztcbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IE5ldXJvbnhDb21waWxlUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3QgblBvc2l0aW9ucyA9IHByb3BzLmNvbXBpbGVPcHRpb25zPy5uUG9zaXRpb25zID8/IDQwOTI7XG4gICAgY29uc3QgcXVhbnREdHlwZSA9IHByb3BzLmNvbXBpbGVPcHRpb25zPy5xdWFudER0eXBlO1xuICAgIGNvbnN0IG9wdExldmVsID0gcHJvcHMuY29tcGlsZU9wdGlvbnM/Lm9wdExldmVsID8/IE9wdExldmVsLkJFU1RfQkFMQU5DRTtcbiAgICBjb25zdCB0cERlZ3JlZSA9XG4gICAgICBwcm9wcy5jb21waWxlT3B0aW9ucz8udHBEZWdyZWUgPz9cbiAgICAgIHRoaXMuY2FsY1RwRGVncmVlKHByb3BzLm1vZGVsLm9wdGlvbnMucGFyYW1ldGVycywge1xuICAgICAgICBuUG9zaXRpb25zLFxuICAgICAgICBxdWFudER0eXBlLFxuICAgICAgfSk7XG4gICAgY29uc3QgaW5zdGFuY2VUeXBlID1cbiAgICAgIHByb3BzLmluc3RhbmNlVHlwZSA/PyB0aGlzLnNlbGVjdEluc3RhbmNlVHlwZUJ5VHBEZWdyZWUodHBEZWdyZWUpO1xuICAgIGNvbnN0IGxhdW5jaFRlbXBsYXRlID0gbmV3IGVjMi5MYXVuY2hUZW1wbGF0ZSh0aGlzLCBcIkxhdW5jaFRlbXBsYXRlXCIsIHtcbiAgICAgIGJsb2NrRGV2aWNlczogW1xuICAgICAgICB7XG4gICAgICAgICAgZGV2aWNlTmFtZTogXCIvZGV2L3h2ZGFcIixcbiAgICAgICAgICB2b2x1bWU6IGVjMi5CbG9ja0RldmljZVZvbHVtZS5lYnMoXG4gICAgICAgICAgICBwcm9wcy52b2x1bWVTaXplPy50b0dpYmlieXRlcygpID8/XG4gICAgICAgICAgICAgIHByb3BzLm1vZGVsLm9wdGlvbnMucGFyYW1ldGVycy50b0JpbGlvbigpICogNSxcbiAgICAgICAgICApLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9KTtcbiAgICBjb25zdCBjb21wdXRlRW52aXJvbm1lbnQgPSBuZXcgYmF0Y2guTWFuYWdlZEVjMkVjc0NvbXB1dGVFbnZpcm9ubWVudChcbiAgICAgIHRoaXMsXG4gICAgICBcIkNvbXB1dGVFbnZpcm9ubWVudFwiLFxuICAgICAge1xuICAgICAgICB2cGM6IHByb3BzLnZwYyxcbiAgICAgICAgdnBjU3VibmV0czogcHJvcHMudnBjU3VibmV0cyxcbiAgICAgICAgaW5zdGFuY2VUeXBlczogW2luc3RhbmNlVHlwZS5pbnN0YW5jZVR5cGVdLFxuICAgICAgICB1c2VPcHRpbWFsSW5zdGFuY2VDbGFzc2VzOiBmYWxzZSxcbiAgICAgICAgaW1hZ2VzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgaW1hZ2U6IG5ldyBOZXVyb25PcHRpbWl6ZWRNYWNoaW5lSW1hZ2UodGhpcywgXCJNYWNoaW5JbWFnZVwiKSxcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIGltYWdlVHlwZTogXCJFQ1NfQUwyMDIzXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgbGF1bmNoVGVtcGxhdGUsXG4gICAgICAgIHNwb3Q6IHByb3BzLnNwb3QsXG4gICAgICB9LFxuICAgICk7XG4gICAgKFxuICAgICAgY29tcHV0ZUVudmlyb25tZW50Lm5vZGUuZGVmYXVsdENoaWxkIGFzIGJhdGNoLkNmbkNvbXB1dGVFbnZpcm9ubWVudFxuICAgICkuYWRkUHJvcGVydHlPdmVycmlkZShcbiAgICAgIFwiQ29tcHV0ZVJlc291cmNlcy5MYXVuY2hUZW1wbGF0ZS5WZXJzaW9uXCIsXG4gICAgICBsYXVuY2hUZW1wbGF0ZS5sYXRlc3RWZXJzaW9uTnVtYmVyLFxuICAgICk7XG5cbiAgICBUYWdzLm9mKGNvbXB1dGVFbnZpcm9ubWVudCkuYWRkKFwiTmFtZVwiLCBcIm5ldXJvbngtY29tcGlsZS13b3JrZXJcIik7XG4gICAgY29uc3Qgam9iUXVldWUgPSBuZXcgYmF0Y2guSm9iUXVldWUodGhpcywgXCJKb2JRdWV1ZVwiLCB7XG4gICAgICBjb21wdXRlRW52aXJvbm1lbnRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBjb21wdXRlRW52aXJvbm1lbnQsXG4gICAgICAgICAgb3JkZXI6IDEsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgam9iU3RhdGVUaW1lTGltaXRBY3Rpb25zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBzdGF0ZTogYmF0Y2guSm9iU3RhdGVUaW1lTGltaXRBY3Rpb25zU3RhdGUuUlVOTkFCTEUsXG4gICAgICAgICAgcmVhc29uOiBiYXRjaC5Kb2JTdGF0ZVRpbWVMaW1pdEFjdGlvbnNSZWFzb24uSk9CX1JFU09VUkNFX1JFUVVJUkVNRU5ULFxuICAgICAgICAgIG1heFRpbWU6IER1cmF0aW9uLm1pbnV0ZXMoMTApLFxuICAgICAgICAgIGFjdGlvbjogYmF0Y2guSm9iU3RhdGVUaW1lTGltaXRBY3Rpb25zQWN0aW9uLkNBTkNFTCxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG5cbiAgICBjb25zdCBydW50aW1lOiBDb21waWxlUnVudGltZSAmIHsgbmV1cm9ueFRyYW5zZm9ybWVyc1ZlcnNpb24/OiBzdHJpbmcgfSA9XG4gICAgICBwcm9wcy5ydW50aW1lID8/IHtcbiAgICAgICAgaW1hZ2U6IENvbnRhaW5lckltYWdlLmZyb21SZWdpc3RyeShcbiAgICAgICAgICBcInB1YmxpYy5lY3IuYXdzL25ldXJvbi9weXRvcmNoLXRyYWluaW5nLW5ldXJvbng6Mi4xLjItbmV1cm9ueC1weTMxMC1zZGsyLjE5LjAtdWJ1bnR1MjAuMDRcIixcbiAgICAgICAgKSxcbiAgICAgICAgbmV1cm9ueFZlcnNpb246IFwiMi4xOS4wXCIsXG4gICAgICAgIG5ldXJvbnhUcmFuc2Zvcm1lcnNWZXJzaW9uOiBcIjAuMTEuMzUxXCIgYXMgY29uc3QsXG4gICAgICB9O1xuICAgIGxldCBjb21waWxlZEFydGlmYWN0UGF0aFByZWZpeCA9IGAke3Byb3BzLm1vZGVsLm1vZGVsSWR9L25ldXJvbngtJHtydW50aW1lLm5ldXJvbnhWZXJzaW9ufS90cCR7dHBEZWdyZWV9LW5wJHtuUG9zaXRpb25zfS1vcHQke29wdExldmVsfWA7XG4gICAgaWYgKHF1YW50RHR5cGUhISkge1xuICAgICAgY29tcGlsZWRBcnRpZmFjdFBhdGhQcmVmaXggPSBgJHtjb21waWxlZEFydGlmYWN0UGF0aFByZWZpeH0tcXVhbnQke3F1YW50RHR5cGV9YDtcbiAgICB9XG4gICAgcHJvcHMuYnVja2V0LmdyYW50UmVhZFdyaXRlKFxuICAgICAgY29tcHV0ZUVudmlyb25tZW50Lmluc3RhbmNlUm9sZSEsXG4gICAgICBgJHtjb21waWxlZEFydGlmYWN0UGF0aFByZWZpeH0vKmAsXG4gICAgKTtcblxuICAgIGNvbnN0IGNvbXBpbGVTY3JpcHQgPSByZWFkRmlsZVN5bmMoXG4gICAgICBqb2luKF9fZGlybmFtZSwgXCJwcml2YXRlL2NvbXBpbGUucHlcIiksXG4gICAgKS50b1N0cmluZygpO1xuICAgIGNvbnN0IGpvYkRlZmluaXRpb24gPSBuZXcgYmF0Y2guRWNzSm9iRGVmaW5pdGlvbih0aGlzLCBcIkpvYkRlZmluaXRpb25cIiwge1xuICAgICAgY29udGFpbmVyOiBuZXcgYmF0Y2guRWNzRWMyQ29udGFpbmVyRGVmaW5pdGlvbihcbiAgICAgICAgdGhpcyxcbiAgICAgICAgXCJDb250YWluZXJEZWZpbml0aW9uXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBpbWFnZTogcnVudGltZS5pbWFnZSxcbiAgICAgICAgICAvLyBUaGUgZmxsb3dpbmcgY29tbWFuZCB3YXMgZXhlY3V0ZWQgb24gaW5mMi44eGxhcmdlXG4gICAgICAgICAgLy8gc2gtNS4yJCBmcmVlIC1iXG4gICAgICAgICAgLy8gXHRcdFx0dG90YWxcdFx0XHRcdFx0dXNlZFx0XHRcdGZyZWVcdFx0XHRcdFx0c2hhcmVkXHRidWZmL2NhY2hlXHRhdmFpbGFibGVcbiAgICAgICAgICAvLyBNZW06XHQxMzIyNjU3NjY5MTJcdDg2NjMyMDM4NFx0MTMwMzQxNzg1NjAwXHQ2Njc2NDhcdDEwNTc2NjA5MjhcdDEzMDUyOTE0ODkyOFxuICAgICAgICAgIC8vIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9iYXRjaC9sYXRlc3QvdXNlcmd1aWRlL21lbW9yeS1tYW5hZ2VtZW50Lmh0bWxcbiAgICAgICAgICBtZW1vcnk6IFNpemUubWViaWJ5dGVzKFxuICAgICAgICAgICAgTWF0aC5jZWlsKGluc3RhbmNlVHlwZS5tZW1vcnkudG9NZWJpYnl0ZXMoKSAqIDAuOTUpLFxuICAgICAgICAgICksXG4gICAgICAgICAgY3B1OiBpbnN0YW5jZVR5cGUudkNwdSxcbiAgICAgICAgICBjb21tYW5kOiBbXG4gICAgICAgICAgICBgY2F0IDw8RU9GID4gY29tcGlsZS5weVxcbiR7Y29tcGlsZVNjcmlwdH1cXG5FT0ZcXG5gLFxuICAgICAgICAgICAgW1xuICAgICAgICAgICAgICBydW50aW1lLm5ldXJvbnhUcmFuc2Zvcm1lcnNWZXJzaW9uXG4gICAgICAgICAgICAgICAgPyBcInBpcCBpbnN0YWxsIC1VIC0tZXh0cmEtaW5kZXgtdXJsIGh0dHBzOi8vcGlwLnJlcG9zLm5ldXJvbi5hbWF6b25hd3MuY29tIHRyYW5zZm9ybWVycy1uZXVyb254PT0kTkVVUk9OWF9UUkFOU0ZPUk1FUlNfVkVSU0lPTlwiXG4gICAgICAgICAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIFwiY3VybCAtcyBodHRwczovL3BhY2thZ2VjbG91ZC5pby9pbnN0YWxsL3JlcG9zaXRvcmllcy9naXRodWIvZ2l0LWxmcy9zY3JpcHQuZGViLnNoIHwgYmFzaFwiLFxuICAgICAgICAgICAgICBcImFwdC1nZXQgaW5zdGFsbCBnaXQtbGZzXCIsXG4gICAgICAgICAgICAgIFwiZ2l0IGxmcyBpbnN0YWxsXCIsXG4gICAgICAgICAgICAgIGBnaXQgY2xvbmUgaHR0cHM6Ly9odWdnaW5nZmFjZS5jby8ke3Byb3BzLm1vZGVsLm1vZGVsSWR9IG1vZGVsYCxcbiAgICAgICAgICAgICAgXCJybSAtcmYgbW9kZWwvLmdpdFwiLFxuICAgICAgICAgICAgICBcInB5dGhvbiAuL2NvbXBpbGUucHlcIixcbiAgICAgICAgICAgICAgYGF3cyBzMyBzeW5jIC0tbm8tcHJvZ3Jlc3MgLi9tb2RlbCAke3Byb3BzLmJ1Y2tldC5zM1VybEZvck9iamVjdChgJHtjb21waWxlZEFydGlmYWN0UGF0aFByZWZpeH0vbW9kZWxgKX1gLFxuICAgICAgICAgICAgICBgYXdzIHMzIHN5bmMgLS1uby1wcm9ncmVzcyAuL2NvbXBpbGVkICR7cHJvcHMuYnVja2V0LnMzVXJsRm9yT2JqZWN0KGAke2NvbXBpbGVkQXJ0aWZhY3RQYXRoUHJlZml4fS9jb21waWxlZGApfWAsXG4gICAgICAgICAgICBdXG4gICAgICAgICAgICAgIC5maWx0ZXIoKHYpID0+ICEhdilcbiAgICAgICAgICAgICAgLmpvaW4oXCIgJiYgXCIpLFxuICAgICAgICAgIF0sXG4gICAgICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgICAgIE1PREVMX0lEOiBwcm9wcy5tb2RlbC5tb2RlbElkLFxuICAgICAgICAgICAgVFBfREVHUkVFOiB0cERlZ3JlZS50b1N0cmluZygpLFxuICAgICAgICAgICAgTl9QT1NJVElPTlM6IG5Qb3NpdGlvbnMudG9TdHJpbmcoKSxcbiAgICAgICAgICAgIE9QVF9MRVZFTDogb3B0TGV2ZWwudG9TdHJpbmcoKSxcbiAgICAgICAgICAgIFFVQU5UX0RUWVBFOiBxdWFudER0eXBlPy50b1N0cmluZygpID8/IFwiXCIsXG4gICAgICAgICAgICBBUlRJRkFDVF9TM19VUkw6IHByb3BzLmJ1Y2tldC5zM1VybEZvck9iamVjdChcbiAgICAgICAgICAgICAgY29tcGlsZWRBcnRpZmFjdFBhdGhQcmVmaXgsXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgTkVVUk9OWF9UUkFOU0ZPUk1FUlNfVkVSU0lPTjpcbiAgICAgICAgICAgICAgcnVudGltZS5uZXVyb254VHJhbnNmb3JtZXJzVmVyc2lvbiA/PyBcIlwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICApLFxuICAgIH0pO1xuICAgIHRoaXMuY29ubmVjdEFjY2VsZXJhdG9yQ2hpcHMoam9iRGVmaW5pdGlvbiwgaW5zdGFuY2VUeXBlKTtcblxuICAgIGNvbnN0IGpvYlN1Ym1pdEZ1bmN0aW9uID0gbmV3IFNpbmdsZXRvbkZ1bmN0aW9uKHRoaXMsIFwiSm9iU3VibWl0RnVuY3Rpb25cIiwge1xuICAgICAgY29kZTogQ29kZS5mcm9tQXNzZXQoam9pbihfX2Rpcm5hbWUsIFwicHJpdmF0ZS9hd2FpdC1jb21waWxlLWpvYlwiKSksXG4gICAgICBoYW5kbGVyOiBcImluZGV4Lm9uRXZlbnRcIixcbiAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzIwX1gsXG4gICAgICB1dWlkOiBcIjEzNjFmNDY5LTVjOTItNGM0Ni05ZTExLTVkMWRiZjkyNWJhY1wiLFxuICAgIH0pO1xuICAgIGpvYkRlZmluaXRpb24uZ3JhbnRTdWJtaXRKb2Ioam9iU3VibWl0RnVuY3Rpb24sIGpvYlF1ZXVlKTtcbiAgICBjb25zdCBqb2JNb25pdG9yaW5nRnVuY3Rpb24gPSBuZXcgU2luZ2xldG9uRnVuY3Rpb24oXG4gICAgICB0aGlzLFxuICAgICAgXCJKb2JNb25pdG9yaW5nRnVuY3Rpb25cIixcbiAgICAgIHtcbiAgICAgICAgY29kZTogQ29kZS5mcm9tQXNzZXQoam9pbihfX2Rpcm5hbWUsIFwicHJpdmF0ZS9hd2FpdC1jb21waWxlLWpvYlwiKSksXG4gICAgICAgIGhhbmRsZXI6IFwiaW5kZXguaXNDb21wbGV0ZVwiLFxuICAgICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yMF9YLFxuICAgICAgICB1dWlkOiBcImRmMTZkYmE4LTVmNzctNDgwYy1hNmFkLWNmZGY3NGMzZGU2MlwiLFxuICAgICAgfSxcbiAgICApO1xuICAgIEdyYW50LmFkZFRvUHJpbmNpcGFsKHtcbiAgICAgIHJlc291cmNlQXJuczogW1wiKlwiXSxcbiAgICAgIGdyYW50ZWU6IGpvYk1vbml0b3JpbmdGdW5jdGlvbixcbiAgICAgIGFjdGlvbnM6IFtcImJhdGNoOkRlc2NyaWJlSm9ic1wiXSxcbiAgICB9KTtcbiAgICBjb25zdCBwcm92aWRlciA9IG5ldyBQcm92aWRlcih0aGlzLCBcIkNvbXBpbGVKb2JQcm92aWRlclwiLCB7XG4gICAgICBvbkV2ZW50SGFuZGxlcjogam9iU3VibWl0RnVuY3Rpb24sXG4gICAgICBpc0NvbXBsZXRlSGFuZGxlcjogam9iTW9uaXRvcmluZ0Z1bmN0aW9uLFxuICAgICAgcXVlcnlJbnRlcnZhbDogRHVyYXRpb24ubWludXRlcygxKSxcbiAgICAgIHRvdGFsVGltZW91dDogRHVyYXRpb24uaG91cnMoMSksXG4gICAgfSk7XG4gICAgY29uc3QgY29tcGlsZUpvYiA9IG5ldyBDdXN0b21SZXNvdXJjZSh0aGlzLCBcIkNvbXBpbGVKb2JcIiwge1xuICAgICAgc2VydmljZVRva2VuOiBwcm92aWRlci5zZXJ2aWNlVG9rZW4sXG4gICAgICByZXNvdXJjZVR5cGU6IFwiQ3VzdG9tOjpDb21waWxlSm9iXCIsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGpvYkRlZmluaXRpb25Bcm46IGpvYkRlZmluaXRpb24uam9iRGVmaW5pdGlvbkFybixcbiAgICAgICAgam9iUXVldWVBcm46IGpvYlF1ZXVlLmpvYlF1ZXVlQXJuLFxuICAgICAgICBhcnRpZmFjdFMzVXJsOiBwcm9wcy5idWNrZXQuczNVcmxGb3JPYmplY3QoY29tcGlsZWRBcnRpZmFjdFBhdGhQcmVmaXgpLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICB0aGlzLmNvbXBpbGVkQXJ0aWZhY3RTM1VybCA9IGNvbXBpbGVKb2IuZ2V0QXR0U3RyaW5nKFwiQXJ0aWZhY3RTM1VybFwiKTtcbiAgfVxuXG4gIHByaXZhdGUgY29ubmVjdEFjY2VsZXJhdG9yQ2hpcHMoXG4gICAgam9iRGVmaW5pdGlvbjogYmF0Y2guRWNzSm9iRGVmaW5pdGlvbixcbiAgICBpbnN0YW5jZVR5cGU6IE5ldXJvbnhJbnN0YW5jZVR5cGUsXG4gICkge1xuICAgIHR5cGUgUGFzY2FsQ2FzZTxUIGV4dGVuZHMgb2JqZWN0PiA9IHtcbiAgICAgIFtQIGluIGtleW9mIFQgYXMgUCBleHRlbmRzIHN0cmluZyA/IENhcGl0YWxpemU8UD4gOiBuZXZlcl06IFRbUF07XG4gICAgfTtcbiAgICBjb25zdCBkZXZpY2VzID0gQXJyYXkuZnJvbSh7XG4gICAgICBsZW5ndGg6IGluc3RhbmNlVHlwZS5hY2NlbGVyYXRvckNoaXBzLmNoaXBzLFxuICAgIH0pLm1hcChcbiAgICAgIChfLCBpbmRleCkgPT5cbiAgICAgICAgKHtcbiAgICAgICAgICBIb3N0UGF0aDogYC9kZXYvbmV1cm9uJHtpbmRleH1gLFxuICAgICAgICAgIENvbnRhaW5lclBhdGg6IGAvZGV2L25ldXJvbiR7aW5kZXh9YCxcbiAgICAgICAgICBQZXJtaXNzaW9uczogW1wicmVhZFwiLCBcIndyaXRlXCJdLFxuICAgICAgICB9KSBzYXRpc2ZpZXMgUGFzY2FsQ2FzZTxiYXRjaC5DZm5Kb2JEZWZpbml0aW9uLkRldmljZVByb3BlcnR5PixcbiAgICApO1xuICAgIGNvbnN0IGNmbkpvYkRlZmluaXRpb24gPSBqb2JEZWZpbml0aW9uLm5vZGVcbiAgICAgIC5kZWZhdWx0Q2hpbGQgYXMgYmF0Y2guQ2ZuSm9iRGVmaW5pdGlvbjtcbiAgICBjZm5Kb2JEZWZpbml0aW9uLmFkZFByb3BlcnR5T3ZlcnJpZGUoXG4gICAgICBcIkNvbnRhaW5lclByb3BlcnRpZXMuTGludXhQYXJhbWV0ZXJzLkRldmljZXNcIixcbiAgICAgIGRldmljZXMsXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgY2FsY1RwRGVncmVlKHBhcmFtZXRlcnM6IFBhcmFtZXRlcnMsIGNvbXBpbGVPcHRpb25zOiBDb21waWxlT3B0aW9ucykge1xuICAgIC8vIGNhc2Ugb2YgZmxvYXQxNlxuICAgIGNvbnN0IGJ5dGVzUGVyUGFyYW1ldGUgPSAxNiAvIDg7XG4gICAgLy8gbWVtb3J5ID0gYnl0ZXMgcGVyIHBhcmFtZXRlciAqIG51bWJlciBvZiBwYXJhbWV0ZXJzXG4gICAgbGV0IG1lbW9yeSA9IFNpemUuZ2liaWJ5dGVzKGJ5dGVzUGVyUGFyYW1ldGUgKiBwYXJhbWV0ZXJzLnRvQmlsaW9uKCkpO1xuICAgIHN3aXRjaCAoY29tcGlsZU9wdGlvbnMucXVhbnREdHlwZSkge1xuICAgICAgY2FzZSBRdWFudER0eXBlLlM4OlxuICAgICAgICBtZW1vcnkgPSBTaXplLmdpYmlieXRlcyhtZW1vcnkudG9HaWJpYnl0ZXMoKSAvIDIpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgY29uc3QgbmVyb254Q29yZU1lbW9yeSA9IFNpemUuZ2liaWJ5dGVzKDE2KTtcbiAgICBjb25zdCBtaW5pbXVtID0gTWF0aC5jZWlsKFxuICAgICAgbWVtb3J5LnRvR2liaWJ5dGVzKCkgLyBuZXJvbnhDb3JlTWVtb3J5LnRvR2liaWJ5dGVzKCksXG4gICAgKTtcblxuICAgIGNvbnN0IHRwRGVncmVlcyA9IFsxLCAyLCA0LCA4LCAyNF07XG4gICAgZm9yIChjb25zdCB0cERlZ3JlZSBvZiB0cERlZ3JlZXMpIHtcbiAgICAgIGlmIChtaW5pbXVtIDw9IHRwRGVncmVlKSB7XG4gICAgICAgIHJldHVybiB0cERlZ3JlZTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgXCJUaGlzIG1vZGVsIGlzIHRvbyBsYXJnZSwgSSBjYW4gbm90IHN1cHBvcnQgdGhpcyBtb2RlbCBjdXJyZW50IHZlcnNpb24uXCIsXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgc2VsZWN0SW5zdGFuY2VUeXBlQnlUcERlZ3JlZSh0cERlZ3JlZTogbnVtYmVyKSB7XG4gICAgY29uc3QgaW5zdGFuY2VUeXBlcyA9IFtcbiAgICAgIE5ldXJvbnhJbnN0YW5jZVR5cGUuSU5GMl84WExBUkdFLFxuICAgICAgTmV1cm9ueEluc3RhbmNlVHlwZS5JTkYyXzI0WExBUkdFLFxuICAgICAgTmV1cm9ueEluc3RhbmNlVHlwZS5JTkYyXzQ4WExBUkdFLFxuICAgIF07XG4gICAgZm9yIChjb25zdCBpbnN0YW5jZVR5cGUgb2YgaW5zdGFuY2VUeXBlcykge1xuICAgICAgaWYgKHRwRGVncmVlIDw9IGluc3RhbmNlVHlwZS5hY2NlbGVyYXRvckNoaXBzLm5ldXJvbnhDb3Jlcykge1xuICAgICAgICByZXR1cm4gaW5zdGFuY2VUeXBlO1xuICAgICAgfVxuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBcIlRoaXMgbW9kZWwgaXMgdG9vIGxhcmdlLCBJIGNhbiBub3Qgc3VwcG9ydCB0aGlzIG1vZGVsIGN1cnJlbnQgdmVyc2lvbi5cIixcbiAgICApO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,44 @@
1
+ import { Size } from "aws-cdk-lib";
2
+ import * as ec2 from "aws-cdk-lib/aws-ec2";
3
+ /**
4
+ *
5
+ */
6
+ export interface IAcceleratorChips {
7
+ readonly chips: number;
8
+ readonly neuronxCores: number;
9
+ readonly acceleratorMemory: Size;
10
+ }
11
+ export declare class Inferentia2Chips implements IAcceleratorChips {
12
+ readonly chips: number;
13
+ readonly neuronxCores: number;
14
+ readonly acceleratorMemory: Size;
15
+ constructor(chips: number);
16
+ }
17
+ export declare class NeuronxInstanceType {
18
+ readonly instanceType: ec2.InstanceType;
19
+ readonly vCpu: number;
20
+ readonly memory: Size;
21
+ readonly acceleratorChips: IAcceleratorChips;
22
+ /**
23
+ * ml.inf2.xlarge
24
+ */
25
+ static readonly INF2_XLARGE: NeuronxInstanceType;
26
+ /**
27
+ * ml.inf2.8xlarge
28
+ */
29
+ static readonly INF2_8XLARGE: NeuronxInstanceType;
30
+ /**
31
+ * ml.inf2.24xlarge
32
+ */
33
+ static readonly INF2_24XLARGE: NeuronxInstanceType;
34
+ /**
35
+ * ml.inf2.48xlarge
36
+ */
37
+ static readonly INF2_48XLARGE: NeuronxInstanceType;
38
+ private constructor();
39
+ /**
40
+ * Return the instance type as a string
41
+ * @returns The instance type as a string
42
+ */
43
+ toString(): string;
44
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var _a, _b;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.NeuronxInstanceType = exports.Inferentia2Chips = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
7
+ const ec2 = require("aws-cdk-lib/aws-ec2");
8
+ class Inferentia2Chips {
9
+ constructor(chips) {
10
+ this.chips = chips;
11
+ this.neuronxCores = chips * 2;
12
+ this.acceleratorMemory = aws_cdk_lib_1.Size.gibibytes(16 * this.neuronxCores);
13
+ }
14
+ }
15
+ exports.Inferentia2Chips = Inferentia2Chips;
16
+ _a = JSII_RTTI_SYMBOL_1;
17
+ Inferentia2Chips[_a] = { fqn: "aws-cdk-neuronx-patterns.Inferentia2Chips", version: "0.0.0" };
18
+ class NeuronxInstanceType {
19
+ constructor(instanceType, vCpu, memory, acceleratorChips) {
20
+ this.instanceType = instanceType;
21
+ this.vCpu = vCpu;
22
+ this.memory = memory;
23
+ this.acceleratorChips = acceleratorChips;
24
+ }
25
+ /**
26
+ * Return the instance type as a string
27
+ * @returns The instance type as a string
28
+ */
29
+ toString() {
30
+ return `ml.${this.instanceType.toString()}`;
31
+ }
32
+ }
33
+ exports.NeuronxInstanceType = NeuronxInstanceType;
34
+ _b = JSII_RTTI_SYMBOL_1;
35
+ NeuronxInstanceType[_b] = { fqn: "aws-cdk-neuronx-patterns.NeuronxInstanceType", version: "0.0.0" };
36
+ /**
37
+ * ml.inf2.xlarge
38
+ */
39
+ NeuronxInstanceType.INF2_XLARGE = new NeuronxInstanceType(ec2.InstanceType.of(ec2.InstanceClass.INF2, ec2.InstanceSize.XLARGE), 4, aws_cdk_lib_1.Size.gibibytes(16), new Inferentia2Chips(1));
40
+ /**
41
+ * ml.inf2.8xlarge
42
+ */
43
+ NeuronxInstanceType.INF2_8XLARGE = new NeuronxInstanceType(ec2.InstanceType.of(ec2.InstanceClass.INF2, ec2.InstanceSize.XLARGE8), 32, aws_cdk_lib_1.Size.gibibytes(128), new Inferentia2Chips(1));
44
+ /**
45
+ * ml.inf2.24xlarge
46
+ */
47
+ NeuronxInstanceType.INF2_24XLARGE = new NeuronxInstanceType(ec2.InstanceType.of(ec2.InstanceClass.INF2, ec2.InstanceSize.XLARGE24), 96, aws_cdk_lib_1.Size.gibibytes(384), new Inferentia2Chips(6));
48
+ /**
49
+ * ml.inf2.48xlarge
50
+ */
51
+ NeuronxInstanceType.INF2_48XLARGE = new NeuronxInstanceType(ec2.InstanceType.of(ec2.InstanceClass.INF2, ec2.InstanceSize.XLARGE48), 192, aws_cdk_lib_1.Size.gibibytes(768), new Inferentia2Chips(12));
52
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV1cm9ueC1pbnN0YW5jZS10eXBlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL25ldXJvbngtaW5zdGFuY2UtdHlwZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDZDQUFtQztBQUNuQywyQ0FBMkM7QUFXM0MsTUFBYSxnQkFBZ0I7SUFHM0IsWUFBcUIsS0FBYTtRQUFiLFVBQUssR0FBTCxLQUFLLENBQVE7UUFDaEMsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQzlCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxrQkFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ2xFLENBQUM7O0FBTkgsNENBT0M7OztBQUVELE1BQWEsbUJBQW1CO0lBcUM5QixZQUNXLFlBQThCLEVBQzlCLElBQVksRUFDWixNQUFZLEVBQ1osZ0JBQW1DO1FBSG5DLGlCQUFZLEdBQVosWUFBWSxDQUFrQjtRQUM5QixTQUFJLEdBQUosSUFBSSxDQUFRO1FBQ1osV0FBTSxHQUFOLE1BQU0sQ0FBTTtRQUNaLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBbUI7SUFDM0MsQ0FBQztJQUNKOzs7T0FHRztJQUNILFFBQVE7UUFDTixPQUFPLE1BQU0sSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDO0lBQzlDLENBQUM7O0FBakRILGtEQWtEQzs7O0FBakRDOztHQUVHO0FBQ29CLCtCQUFXLEdBQUcsSUFBSSxtQkFBbUIsQ0FDMUQsR0FBRyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsRUFDcEUsQ0FBQyxFQUNELGtCQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUNsQixJQUFJLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUN4QixDQUFDO0FBQ0Y7O0dBRUc7QUFDb0IsZ0NBQVksR0FBRyxJQUFJLG1CQUFtQixDQUMzRCxHQUFHLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxFQUNyRSxFQUFFLEVBQ0Ysa0JBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQ25CLElBQUksZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQ3hCLENBQUM7QUFDRjs7R0FFRztBQUNvQixpQ0FBYSxHQUFHLElBQUksbUJBQW1CLENBQzVELEdBQUcsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLEVBQ3RFLEVBQUUsRUFDRixrQkFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFDbkIsSUFBSSxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FDeEIsQ0FBQztBQUNGOztHQUVHO0FBQ29CLGlDQUFhLEdBQUcsSUFBSSxtQkFBbUIsQ0FDNUQsR0FBRyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsRUFDdEUsR0FBRyxFQUNILGtCQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxFQUNuQixJQUFJLGdCQUFnQixDQUFDLEVBQUUsQ0FBQyxDQUN6QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU2l6ZSB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0ICogYXMgZWMyIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtZWMyXCI7XG5cbi8qKlxuICpcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJQWNjZWxlcmF0b3JDaGlwcyB7XG4gIHJlYWRvbmx5IGNoaXBzOiBudW1iZXI7XG4gIHJlYWRvbmx5IG5ldXJvbnhDb3JlczogbnVtYmVyO1xuICByZWFkb25seSBhY2NlbGVyYXRvck1lbW9yeTogU2l6ZTtcbn1cblxuZXhwb3J0IGNsYXNzIEluZmVyZW50aWEyQ2hpcHMgaW1wbGVtZW50cyBJQWNjZWxlcmF0b3JDaGlwcyB7XG4gIHJlYWRvbmx5IG5ldXJvbnhDb3JlczogbnVtYmVyO1xuICByZWFkb25seSBhY2NlbGVyYXRvck1lbW9yeTogU2l6ZTtcbiAgY29uc3RydWN0b3IocmVhZG9ubHkgY2hpcHM6IG51bWJlcikge1xuICAgIHRoaXMubmV1cm9ueENvcmVzID0gY2hpcHMgKiAyO1xuICAgIHRoaXMuYWNjZWxlcmF0b3JNZW1vcnkgPSBTaXplLmdpYmlieXRlcygxNiAqIHRoaXMubmV1cm9ueENvcmVzKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgTmV1cm9ueEluc3RhbmNlVHlwZSB7XG4gIC8qKlxuICAgKiBtbC5pbmYyLnhsYXJnZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBJTkYyX1hMQVJHRSA9IG5ldyBOZXVyb254SW5zdGFuY2VUeXBlKFxuICAgIGVjMi5JbnN0YW5jZVR5cGUub2YoZWMyLkluc3RhbmNlQ2xhc3MuSU5GMiwgZWMyLkluc3RhbmNlU2l6ZS5YTEFSR0UpLFxuICAgIDQsXG4gICAgU2l6ZS5naWJpYnl0ZXMoMTYpLFxuICAgIG5ldyBJbmZlcmVudGlhMkNoaXBzKDEpLFxuICApO1xuICAvKipcbiAgICogbWwuaW5mMi44eGxhcmdlXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IElORjJfOFhMQVJHRSA9IG5ldyBOZXVyb254SW5zdGFuY2VUeXBlKFxuICAgIGVjMi5JbnN0YW5jZVR5cGUub2YoZWMyLkluc3RhbmNlQ2xhc3MuSU5GMiwgZWMyLkluc3RhbmNlU2l6ZS5YTEFSR0U4KSxcbiAgICAzMixcbiAgICBTaXplLmdpYmlieXRlcygxMjgpLFxuICAgIG5ldyBJbmZlcmVudGlhMkNoaXBzKDEpLFxuICApO1xuICAvKipcbiAgICogbWwuaW5mMi4yNHhsYXJnZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBJTkYyXzI0WExBUkdFID0gbmV3IE5ldXJvbnhJbnN0YW5jZVR5cGUoXG4gICAgZWMyLkluc3RhbmNlVHlwZS5vZihlYzIuSW5zdGFuY2VDbGFzcy5JTkYyLCBlYzIuSW5zdGFuY2VTaXplLlhMQVJHRTI0KSxcbiAgICA5NixcbiAgICBTaXplLmdpYmlieXRlcygzODQpLFxuICAgIG5ldyBJbmZlcmVudGlhMkNoaXBzKDYpLFxuICApO1xuICAvKipcbiAgICogbWwuaW5mMi40OHhsYXJnZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBJTkYyXzQ4WExBUkdFID0gbmV3IE5ldXJvbnhJbnN0YW5jZVR5cGUoXG4gICAgZWMyLkluc3RhbmNlVHlwZS5vZihlYzIuSW5zdGFuY2VDbGFzcy5JTkYyLCBlYzIuSW5zdGFuY2VTaXplLlhMQVJHRTQ4KSxcbiAgICAxOTIsXG4gICAgU2l6ZS5naWJpYnl0ZXMoNzY4KSxcbiAgICBuZXcgSW5mZXJlbnRpYTJDaGlwcygxMiksXG4gICk7XG4gIHByaXZhdGUgY29uc3RydWN0b3IoXG4gICAgcmVhZG9ubHkgaW5zdGFuY2VUeXBlOiBlYzIuSW5zdGFuY2VUeXBlLFxuICAgIHJlYWRvbmx5IHZDcHU6IG51bWJlcixcbiAgICByZWFkb25seSBtZW1vcnk6IFNpemUsXG4gICAgcmVhZG9ubHkgYWNjZWxlcmF0b3JDaGlwczogSUFjY2VsZXJhdG9yQ2hpcHMsXG4gICkge31cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgaW5zdGFuY2UgdHlwZSBhcyBhIHN0cmluZ1xuICAgKiBAcmV0dXJucyBUaGUgaW5zdGFuY2UgdHlwZSBhcyBhIHN0cmluZ1xuICAgKi9cbiAgdG9TdHJpbmcoKSB7XG4gICAgcmV0dXJuIGBtbC4ke3RoaXMuaW5zdGFuY2VUeXBlLnRvU3RyaW5nKCl9YDtcbiAgfVxufVxuIl19
@@ -0,0 +1,4 @@
1
+ import { type CdkCustomResourceHandler, type CdkCustomResourceIsCompleteHandler } from "aws-lambda";
2
+ export declare const onEvent: CdkCustomResourceHandler;
3
+ export declare const onCreate: CdkCustomResourceHandler;
4
+ export declare const isComplete: CdkCustomResourceIsCompleteHandler;