cdk-serverless 3.3.2 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/.agents/tasks/task-dependency-cve-upgrade/2026-10-12-233633-review.md +98 -0
  2. package/.agents/tasks/task-dependency-cve-upgrade/2026-10-12-234937-review.md +86 -0
  3. package/.agents/tasks/task-dependency-cve-upgrade/context.json +24 -0
  4. package/.agents/tasks/task-dependency-cve-upgrade/features/FEAT-001.json +28 -0
  5. package/.agents/tasks/task-dependency-cve-upgrade/features/FEAT-002.json +33 -0
  6. package/.agents/tasks/task-dependency-cve-upgrade/task.json +7 -0
  7. package/docs/constructs/assets/hierarchy.js +1 -1
  8. package/docs/constructs/assets/highlight.css +1 -1
  9. package/docs/constructs/assets/main.js +1 -1
  10. package/docs/constructs/assets/search.js +1 -1
  11. package/docs/constructs/assets/style.css +18 -3
  12. package/docs/constructs/classes/AssetCdn.html +161 -20
  13. package/docs/constructs/classes/BaseApi.html +153 -13
  14. package/docs/constructs/classes/CognitoAuthentication.html +188 -22
  15. package/docs/constructs/classes/GraphQlApi.html +349 -23
  16. package/docs/constructs/classes/LambdaFunction.html +1074 -106
  17. package/docs/constructs/classes/McpAuth.html +152 -16
  18. package/docs/constructs/classes/McpCognitoAuth.html +152 -16
  19. package/docs/constructs/classes/RestApi.html +344 -37
  20. package/docs/constructs/classes/SingleTableDatastore.html +173 -19
  21. package/docs/constructs/classes/Workflow.html +170 -21
  22. package/docs/constructs/hierarchy.html +47 -1
  23. package/docs/constructs/index.html +75 -2
  24. package/docs/constructs/interfaces/AssetCdnProps.html +61 -5
  25. package/docs/constructs/interfaces/BaseApiProps.html +141 -20
  26. package/docs/constructs/interfaces/CognitoAuthenticationProps.html +135 -20
  27. package/docs/constructs/interfaces/GraphQlApiProps.html +185 -22
  28. package/docs/constructs/interfaces/ICognitoAuthentication.html +57 -3
  29. package/docs/constructs/interfaces/IJwtAuthentication.html +63 -5
  30. package/docs/constructs/interfaces/ISingleTableDatastore.html +57 -3
  31. package/docs/constructs/interfaces/JsResolverOptions.html +66 -6
  32. package/docs/constructs/interfaces/LambdaFunctionProps.html +126 -18
  33. package/docs/constructs/interfaces/LambdaTracingOptions.html +57 -4
  34. package/docs/constructs/interfaces/McpAuthCognitoOptions.html +75 -8
  35. package/docs/constructs/interfaces/McpAuthFunctions.html +76 -8
  36. package/docs/constructs/interfaces/McpAuthGenericOptions.html +66 -6
  37. package/docs/constructs/interfaces/McpAuthOptions.html +107 -15
  38. package/docs/constructs/interfaces/McpAuthProps.html +123 -18
  39. package/docs/constructs/interfaces/McpCognitoAuthProps.html +127 -19
  40. package/docs/constructs/interfaces/RestApiProps.html +237 -37
  41. package/docs/constructs/interfaces/SingleTableDatastoreProps.html +77 -9
  42. package/docs/constructs/interfaces/SingleTableDesign.html +72 -7
  43. package/docs/constructs/interfaces/VtlResolverOptions.html +62 -5
  44. package/docs/constructs/interfaces/WorkflowProps.html +63 -2
  45. package/docs/constructs/modules.html +44 -1
  46. package/docs/constructs/types/LambdaOptions.html +31 -1
  47. package/docs/experiments/appsync-unit-resolver-error-probe.md +201 -0
  48. package/docs/lambda/assets/hierarchy.js +1 -1
  49. package/docs/lambda/assets/highlight.css +1 -1
  50. package/docs/lambda/assets/main.js +1 -1
  51. package/docs/lambda/assets/navigation.js +1 -1
  52. package/docs/lambda/assets/search.js +1 -1
  53. package/docs/lambda/assets/style.css +18 -3
  54. package/docs/lambda/classes/auth.ApiGatewayv1CognitoAuthorizer.html +248 -21
  55. package/docs/lambda/classes/auth.ApiGatewayv1JwtAuthorizer.html +247 -20
  56. package/docs/lambda/classes/auth.ApiGatewayv2CognitoAuthorizer.html +248 -21
  57. package/docs/lambda/classes/auth.ApiGatewayv2JwtAuthorizer.html +246 -20
  58. package/docs/lambda/classes/auth.AppSyncCognitoAuthorizer.html +242 -21
  59. package/docs/lambda/classes/auth.CognitoAuthorizer.html +235 -20
  60. package/docs/lambda/classes/auth.JwtAuthorizer.html +225 -20
  61. package/docs/lambda/classes/errors.BadRequestError.html +147 -11
  62. package/docs/lambda/classes/errors.ForbiddenError.html +147 -11
  63. package/docs/lambda/classes/errors.HttpError.html +154 -12
  64. package/docs/lambda/classes/errors.NotFoundError.html +147 -11
  65. package/docs/lambda/classes/errors.UnauthenticatedError.html +147 -11
  66. package/docs/lambda/classes/errors.appsync.AppSyncError.html +193 -0
  67. package/docs/lambda/classes/errors.appsync.ConflictError.html +184 -0
  68. package/docs/lambda/classes/errors.appsync.ForbiddenError.html +184 -0
  69. package/docs/lambda/classes/errors.appsync.NotFoundError.html +184 -0
  70. package/docs/lambda/classes/errors.appsync.ValidationError.html +184 -0
  71. package/docs/lambda/functions/api.createAppSyncHandler.html +50 -3
  72. package/docs/lambda/functions/api.createHttpHandler.html +48 -2
  73. package/docs/lambda/functions/api.createOpenApiHandler.html +48 -2
  74. package/docs/lambda/functions/api.createOpenApiHandlerWithRequestBody.html +48 -2
  75. package/docs/lambda/functions/api.createOpenApiHandlerWithRequestBodyNoResponse.html +47 -2
  76. package/docs/lambda/hierarchy.html +59 -1
  77. package/docs/lambda/index.html +75 -2
  78. package/docs/lambda/interfaces/api.AppSyncHandlerContext.html +68 -3
  79. package/docs/lambda/interfaces/api.HttpHandlerContext.html +67 -3
  80. package/docs/lambda/interfaces/api.HttpResponseContext.html +61 -3
  81. package/docs/lambda/interfaces/api.Operation.html +61 -3
  82. package/docs/lambda/interfaces/api.OperationWithRequestBody.html +65 -3
  83. package/docs/lambda/modules/api.html +45 -1
  84. package/docs/lambda/modules/auth.html +37 -1
  85. package/docs/lambda/modules/errors.appsync.html +38 -0
  86. package/docs/lambda/modules/errors.html +41 -1
  87. package/docs/lambda/modules.html +36 -1
  88. package/docs/lambda/types/api.APIGatewayv1Handler.html +34 -2
  89. package/docs/lambda/types/api.AppSyncHandler.html +51 -2
  90. package/docs/lambda/types/api.HttpHandler.html +52 -2
  91. package/docs/projen/assets/highlight.css +5 -12
  92. package/docs/projen/assets/main.js +1 -1
  93. package/docs/projen/assets/style.css +18 -3
  94. package/docs/projen/classes/Datastore.html +254 -18
  95. package/docs/projen/classes/GraphQlApi.html +238 -18
  96. package/docs/projen/classes/RestApi.html +325 -40
  97. package/docs/projen/classes/ServerlessProject.html +1021 -159
  98. package/docs/projen/classes/Workflow.html +288 -31
  99. package/docs/projen/hierarchy.html +29 -1
  100. package/docs/projen/index.html +75 -2
  101. package/docs/projen/interfaces/DatastoreOptions.html +54 -2
  102. package/docs/projen/interfaces/GraphQlApiOptions.html +54 -2
  103. package/docs/projen/interfaces/RestApiOptions.html +54 -2
  104. package/docs/projen/interfaces/ServerlessProjectOptions.html +2089 -692
  105. package/docs/projen/interfaces/WorkflowOptions.html +54 -2
  106. package/docs/projen/modules.html +44 -1
  107. package/docs/projen/variables/PACKAGE_NAME.html +31 -1
  108. package/lib/constructs/graphql.d.ts +17 -0
  109. package/lib/constructs/graphql.js +78 -2
  110. package/lib/lambda/appsync-errors.d.ts +67 -0
  111. package/lib/lambda/appsync-errors.js +91 -0
  112. package/lib/lambda/errors.d.ts +1 -0
  113. package/lib/lambda/errors.js +36 -2
  114. package/lib/lambda/handler.js +78 -1
  115. package/llm.md +31 -0
  116. package/package.json +26 -24
@@ -39,6 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.createAppSyncHandler = exports.createHttpHandler = exports.createOpenApiHandler = exports.createOpenApiHandlerWithRequestBodyNoResponse = exports.createOpenApiHandlerWithRequestBody = void 0;
40
40
  const process_1 = require("process");
41
41
  const lambda_log_1 = __importDefault(require("lambda-log"));
42
+ const appsyncErrors = __importStar(require("./appsync-errors"));
42
43
  const auth_1 = require("./auth");
43
44
  const errors = __importStar(require("./errors"));
44
45
  /**
@@ -198,6 +199,28 @@ function corsHeader(event) {
198
199
  'Access-Control-Allow-Headers': 'Authorization, *', // Allow the Authorization header and any other headers
199
200
  };
200
201
  }
202
+ /**
203
+ * Maps an HTTP status code to the GraphQL errorType reported to AppSync.
204
+ *
205
+ * Local (non-exported) helper used only by createAppSyncHandler when it
206
+ * translates an errors.HttpError into a typed AppSync error. The explicit
207
+ * default keeps any unmapped status (for example a 418 or a 5xx) reported as
208
+ * the generic 'Error' errorType rather than leaking the raw status code.
209
+ */
210
+ function httpStatusToErrorType(statusCode) {
211
+ switch (statusCode) {
212
+ case 400:
213
+ return 'BadRequest';
214
+ case 401:
215
+ return 'Unauthorized';
216
+ case 403:
217
+ return 'Forbidden';
218
+ case 404:
219
+ return 'NotFound';
220
+ default:
221
+ return 'Error';
222
+ }
223
+ }
201
224
  /**
202
225
  * Creates an AppSync resolver handler from the given AppSyncHandler.
203
226
  * Returns a function that can be used as an AppSync resolver.
@@ -225,6 +248,60 @@ const createAppSyncHandler = (handler) => {
225
248
  return await handler(ctx);
226
249
  }
227
250
  catch (error) {
251
+ // Normalise the two recognised typed-error shapes to a common
252
+ // { errorType, message, errorInfo } so the gate, envelope and rethrow
253
+ // below are a single code path.
254
+ //
255
+ // - appsyncErrors.AppSyncError carries its own GraphQL errorType and an
256
+ // optional errorInfo, which flow through unchanged.
257
+ // - errors.HttpError (the HTTP base thrown by the shared JwtAuthorizer
258
+ // via assertAuthenticated/assertGroup/assertAdmin, and by resolver
259
+ // code directly) has no GraphQL errorType, so map its statusCode with
260
+ // httpStatusToErrorType. HttpError carries no errorInfo, so errorInfo
261
+ // is undefined.
262
+ //
263
+ // The two instanceof checks are disjoint: HttpError and AppSyncError
264
+ // share no ancestry, so an appsync.ForbiddenError takes the AppSyncError
265
+ // branch and an errors.ForbiddenError the HttpError branch. Anything that
266
+ // is neither (plain Error, Boom) leaves typed undefined and rethrows.
267
+ let typed;
268
+ if (error instanceof appsyncErrors.AppSyncError) {
269
+ typed = { errorType: error.errorType, message: error.message, errorInfo: error.errorInfo };
270
+ }
271
+ else if (error instanceof errors.HttpError) {
272
+ typed = { errorType: httpStatusToErrorType(error.statusCode), message: error.message, errorInfo: undefined };
273
+ }
274
+ if (typed && process.env.APPSYNC_TYPED_ERRORS === 'true') {
275
+ // The envelope-return is gated on APPSYNC_TYPED_ERRORS === 'true'.
276
+ // GraphQlApi.addLambdaResolver injects that env var only on its
277
+ // typedErrors: true path, whose APPSYNC_JS resolver has a response
278
+ // handler that reads this envelope and calls
279
+ // util.error(errorMessage, errorType, null, errorInfo), turning it into
280
+ // a GraphQL error on a successful invocation. Returning (not throwing)
281
+ // keeps the invocation off the Lambda Errors metric.
282
+ //
283
+ // When the env var is absent (the default UNIT resolver path, or a
284
+ // hand-wired handler used without GraphQlApi) the typed error falls
285
+ // through to the rethrow below, so the invocation fails loudly instead
286
+ // of surfacing the envelope as field data. Any value other than the
287
+ // exact string 'true' means rethrow. This is why a default UNIT
288
+ // resolver whose handler hits an auth assertion (an HttpError) still
289
+ // fails loudly unless typedErrors is active.
290
+ //
291
+ // __appSyncError is a reserved sentinel key the resolver response
292
+ // handler keys on to recognise this envelope. Branching on the sentinel
293
+ // (rather than on a bare errorMessage) means a legitimate resolver result
294
+ // that merely contains an errorMessage field is not misclassified as a
295
+ // typed error.
296
+ ctx.logger.warn(typed.message, { errorType: typed.errorType, errorInfo: typed.errorInfo });
297
+ return {
298
+ __appSyncError: true,
299
+ data: null,
300
+ errorType: typed.errorType,
301
+ errorMessage: typed.message,
302
+ errorInfo: typed.errorInfo,
303
+ };
304
+ }
228
305
  // log the error and throw it again
229
306
  ctx.logger.error(error);
230
307
  throw error;
@@ -232,4 +309,4 @@ const createAppSyncHandler = (handler) => {
232
309
  };
233
310
  };
234
311
  exports.createAppSyncHandler = createAppSyncHandler;
235
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9sYW1iZGEvaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxxQ0FBOEI7QUFDOUIsNERBQStDO0FBQy9DLGlDQU1nQjtBQUNoQixpREFBbUM7QUE2RG5DOztHQUVHO0FBQ0ksTUFBTSxtQ0FBbUMsR0FBRyxDQUErRCxPQUEwSCxFQUF1QixFQUFFO0lBQ25RLE9BQU8sSUFBQSx5QkFBaUIsRUFBQyxPQUFPLENBQUMsQ0FBQztBQUNwQyxDQUFDLENBQUM7QUFGVyxRQUFBLG1DQUFtQyx1Q0FFOUM7QUFFRjs7R0FFRztBQUNJLE1BQU0sNkNBQTZDLEdBQUcsQ0FBc0MsT0FBNEUsRUFBdUIsRUFBRTtJQUN0TSxPQUFPLElBQUEseUJBQWlCLEVBQUMsT0FBTyxDQUFDLENBQUM7QUFDcEMsQ0FBQyxDQUFDO0FBRlcsUUFBQSw2Q0FBNkMsaURBRXhEO0FBRUY7O0dBRUc7QUFDSSxNQUFNLG9CQUFvQixHQUFHLENBQWdELE9BQTZFLEVBQXVCLEVBQUU7SUFDeEwsT0FBTyxJQUFBLHlCQUFpQixFQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3BDLENBQUMsQ0FBQztBQUZXLFFBQUEsb0JBQW9CLHdCQUUvQjtBQUVGOztHQUVHO0FBQ0gsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLEtBQXFGLEVBQUUsR0FBYyxFQUFFLEVBQUU7SUFDakksaUhBQWlIO0lBQ2pILElBQUksYUFBRyxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3JCLE9BQU8sSUFBSSxvQ0FBNkIsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDdkQsQ0FBQztTQUFNLENBQUM7UUFDTixnR0FBZ0c7UUFDaEcsT0FBTyxJQUFJLGdDQUF5QixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDNUQsQ0FBQztBQUNI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QUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUM7UUFDekQsZ0NBQWdDO1FBQ2hDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssS0FBSyxNQUFNLENBQUM7UUFFeEQseUJBQXlCO1FBQ3pCLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUV4QyxJQUFJLENBQUM7WUFDSCxvQ0FBb0M7WUFDcEMsTUFBTSxHQUFHLENBQUMsV0FBVyxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3JDLCtDQUErQztZQUMvQyxPQUFPLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzVCLENBQUM7UUFBQyxPQUFPLEtBQVUsRUFBRSxDQUFDO1lBQ3BCLG1DQUFtQztZQUNuQyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN4QixNQUFNLEtBQUssQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDLENBQUM7QUFDSixDQUFDLENBQUM7QUE3QlMsUUFBQSxvQkFBb0Isd0JBNkI3QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGVudiB9IGZyb20gJ3Byb2Nlc3MnO1xuaW1wb3J0IGxvZ2dlciwgeyBMYW1iZGFMb2cgfSBmcm9tICdsYW1iZGEtbG9nJztcbmltcG9ydCB7XG4gIEFwaUdhdGV3YXl2MUNvZ25pdG9BdXRob3JpemVyLFxuICBBcGlHYXRld2F5djFKd3RBdXRob3JpemVyLFxuICBBcHBTeW5jQ29nbml0b0F1dGhvcml6ZXIsXG4gIENvZ25pdG9BdXRob3JpemVyLFxuICBKd3RBdXRob3JpemVyLFxufSBmcm9tICcuL2F1dGgnO1xuaW1wb3J0ICogYXMgZXJyb3JzIGZyb20gJy4vZXJyb3JzJztcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vLyBIVFRQIEFwaVxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbi8qKlxuICogQW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIHByb3BlcnRpZXMgZm9yIGFuIEhUVFAgcmVzcG9uc2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSHR0cFJlc3BvbnNlQ29udGV4dCB7XG4gIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gIGhlYWRlcnM6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9O1xuICBqc29uOiBib29sZWFuO1xufVxuXG4vKipcbiAqIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBwcm9wZXJ0aWVzIGZvciBhbiBIVFRQIHJlcXVlc3QgaGFuZGxlci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBIdHRwSGFuZGxlckNvbnRleHQge1xuICBldmVudDogQVdTTGFtYmRhLkFQSUdhdGV3YXlQcm94eVdpdGhDb2duaXRvQXV0aG9yaXplckV2ZW50O1xuICBsYW1iZGFDb250ZXh0OiBBV1NMYW1iZGEuQ29udGV4dDtcbiAgbG9nZ2VyOiBsb2dnZXIuTGFtYmRhTG9nO1xuICByZXNwb25zZTogSHR0cFJlc3BvbnNlQ29udGV4dDtcbiAgYXV0aDogSnd0QXV0aG9yaXplcjtcbn1cblxuLyoqXG4gKiBBIHR5cGUgZGVmaW5pdGlvbiBmb3IgYW4gSFRUUCBoYW5kbGVyLlxuICovXG5leHBvcnQgdHlwZSBIdHRwSGFuZGxlcjxULCBSPiA9IChcbiAgY29udGV4dDogSHR0cEhhbmRsZXJDb250ZXh0LFxuICBib2R5OiBULFxuKSA9PiBQcm9taXNlPFI+O1xuXG4vKipcbiAqIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBwcm9wZXJ0aWVzIGZvciBhbiBPcGVuQVBJIG9wZXJhdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPcGVyYXRpb24ge1xuICByZXNwb25zZXM6IHtcbiAgICBbc3RhdHVzQ29kZTogbnVtYmVyXToge1xuICAgICAgY29udGVudDoge1xuICAgICAgICAnYXBwbGljYXRpb24vanNvbic6IGFueTtcbiAgICAgIH07XG4gICAgfSB8IGFueTtcbiAgfTtcbn1cblxuLyoqXG4gKiBBIHR5cGUgZGVmaW5pdGlvbiBmb3IgYW4gQVBJIEdhdGV3YXkgdjEgcmVxdWVzdCBoYW5kbGVyLlxuICovXG5leHBvcnQgdHlwZSBBUElHYXRld2F5djFIYW5kbGVyID1cbiAgQVdTTGFtYmRhLkhhbmRsZXI8QVdTTGFtYmRhLkFQSUdhdGV3YXlQcm94eVdpdGhDb2duaXRvQXV0aG9yaXplckV2ZW50LCBBV1NMYW1iZGEuQVBJR2F0ZXdheVByb3h5UmVzdWx0IHwgdW5kZWZpbmVkPjtcblxuLyoqXG4gKiBBbiBvYmplY3QgY29udGFpbmluZyB0aGUgcHJvcGVydGllcyBmb3IgYW4gT3BlbkFQSSBvcGVyYXRpb24gd2l0aCBhIHJlcXVlc3QgYm9keS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPcGVyYXRpb25XaXRoUmVxdWVzdEJvZHkgZXh0ZW5kcyBPcGVyYXRpb24ge1xuICByZXF1ZXN0Qm9keTogeyBjb250ZW50OiB7ICdhcHBsaWNhdGlvbi9qc29uJzogYW55IH0gfTtcbn1cblxuLyoqXG4gKiBBIGZhY3RvcnkgZnVuY3Rpb24gdGhhdCBjcmVhdGVzIGFuIEhUVFAgcmVxdWVzdCBoYW5kbGVyIGZvciBhbiBPcGVuQVBJIG9wZXJhdGlvbiB3aXRoIGEgcmVxdWVzdCBib2R5LlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlT3BlbkFwaUhhbmRsZXJXaXRoUmVxdWVzdEJvZHkgPSA8T1AgZXh0ZW5kcyBPcGVyYXRpb25XaXRoUmVxdWVzdEJvZHksIFNDIGV4dGVuZHMgbnVtYmVyID0gMjAwPihoYW5kbGVyOiBIdHRwSGFuZGxlcjxPUFsncmVxdWVzdEJvZHknXVsnY29udGVudCddWydhcHBsaWNhdGlvbi9qc29uJ10sIE9QWydyZXNwb25zZXMnXVtTQ11bJ2NvbnRlbnQnXVsnYXBwbGljYXRpb24vanNvbiddPik6IEFQSUdhdGV3YXl2MUhhbmRsZXIgPT4ge1xuICByZXR1cm4gY3JlYXRlSHR0cEhhbmRsZXIoaGFuZGxlcik7XG59O1xuXG4vKipcbiAqIEEgZmFjdG9yeSBmdW5jdGlvbiB0aGF0IGNyZWF0ZXMgYW4gSFRUUCByZXF1ZXN0IGhhbmRsZXIgZm9yIGFuIE9wZW5BUEkgb3BlcmF0aW9uIHdpdGggYSByZXF1ZXN0IGJvZHkgYW5kIG5vIHJlc3BvbnNlLlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlT3BlbkFwaUhhbmRsZXJXaXRoUmVxdWVzdEJvZHlOb1Jlc3BvbnNlID0gPE9QIGV4dGVuZHMgT3BlcmF0aW9uV2l0aFJlcXVlc3RCb2R5PihoYW5kbGVyOiBIdHRwSGFuZGxlcjxPUFsncmVxdWVzdEJvZHknXVsnY29udGVudCddWydhcHBsaWNhdGlvbi9qc29uJ10sIHZvaWQ+KTogQVBJR2F0ZXdheXYxSGFuZGxlciA9PiB7XG4gIHJldHVybiBjcmVhdGVIdHRwSGFuZGxlcihoYW5kbGVyKTtcbn07XG5cbi8qKlxuICogQSBmYWN0b3J5IGZ1bmN0aW9uIHRoYXQgY3JlYXRlcyBhbiBIVFRQIHJlcXVlc3QgaGFuZGxlciBmb3IgYW4gT3BlbkFQSSBvcGVyYXRpb24uXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVPcGVuQXBpSGFuZGxlciA9IDxPUCBleHRlbmRzIE9wZXJhdGlvbiwgU0MgZXh0ZW5kcyBudW1iZXIgPSAyMDA+KGhhbmRsZXI6IEh0dHBIYW5kbGVyPGFueSwgT1BbJ3Jlc3BvbnNlcyddW1NDXVsnY29udGVudCddWydhcHBsaWNhdGlvbi9qc29uJ10+KTogQVBJR2F0ZXdheXYxSGFuZGxlciA9PiB7XG4gIHJldHVybiBjcmVhdGVIdHRwSGFuZGxlcihoYW5kbGVyKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGFuIGF1dGhvcml6ZXIgZm9yIHRoZSBhdXRoZW50aWNhdGlvbiBtZXRob2QgY2hvc2VuIChKV1Qgb3IgQ29nbml0bykuXG4gKi9cbmNvbnN0IGNyZWF0ZUF1dGhvcml6ZXIgPSAoZXZlbnQ6IEFXU0xhbWJkYS5BUElHYXRld2F5UHJveHlFdmVudEJhc2U8QVdTTGFtYmRhLkFQSUdhdGV3YXlQcm94eUNvZ25pdG9BdXRob3JpemVyPiwgbG9nOiBMYW1iZGFMb2cpID0+IHtcbiAgLy8gSWYgQ29nbml0byBpcyB1c2VkLCBVU0VSX1BPT0xfSUQgaXMgaW5qZWN0ZWQgaW50byB0aGUgZnVuY3Rpb24ncyBlbnZpcm9ubWVudC4gQ3VycmVudGx5IGFzc3VtZXMgSldUIG90aGVyd2lzZS5cbiAgaWYgKGVudi5VU0VSX1BPT0xfSUQpIHtcbiAgICByZXR1cm4gbmV3IEFwaUdhdGV3YXl2MUNvZ25pdG9BdXRob3JpemVyKGV2ZW50LCBsb2cpO1xuICB9IGVsc2Uge1xuICAgIC8vIFRoaXMgbWlnaHQgbmVlZCB0byBnZXQgbW9yZSBzb3BoaXN0aWNhdGVkIGlmIG1vcmUgYXV0aG9yaXphdGlvbiBtZXRob2RzIG5lZWQgdG8gYmUgc3VwcG9ydGVkLlxuICAgIHJldHVybiBuZXcgQXBpR2F0ZXdheXYxSnd0QXV0aG9yaXplcihldmVudCwgJ2FkbWluJywgbG9nKTtcbiAgfVxufTtcblxuLyoqXG4gKiBBIGZhY3RvcnkgZnVuY3Rpb24gdGhhdCBjcmVhdGVzIGFuIEhUVFAgcmVxdWVzdCBoYW5kbGVyLlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlSHR0cEhhbmRsZXIgPVxuICA8VCwgUj4oaGFuZGxlcjogSHR0cEhhbmRsZXI8VCwgUj4pOiBBUElHYXRld2F5djFIYW5kbGVyID0+IHtcbiAgICByZXR1cm4gYXN5bmMgKGV2ZW50LCBjb250ZXh0KSA9PiB7XG4gICAgICAvLyBDcmVhdGUgYW4gb2JqZWN0IHRvIGhvbGQgdGhlIGNvbnRleHQgZm9yIHRoaXMgSFRUUCByZXF1ZXN0XG4gICAgICBjb25zdCBhdXRoID0gY3JlYXRlQXV0aG9yaXplcihldmVudCwgbG9nZ2VyIGFzIHVua25vd24gYXMgbG9nZ2VyLkxhbWJkYUxvZyk7XG4gICAgICBjb25zdCBjdHg6IEh0dHBIYW5kbGVyQ29udGV4dCA9IHtcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIGF1dGgsXG4gICAgICAgIGxhbWJkYUNvbnRleHQ6IGNvbnRleHQsXG4gICAgICAgIGxvZ2dlcjogbG9nZ2VyIGFzIHVua25vd24gYXMgbG9nZ2VyLkxhbWJkYUxvZyxcbiAgICAgICAgcmVzcG9uc2U6IHsgaGVhZGVyczoge30sIGpzb246IHRydWUgfSxcbiAgICAgIH07XG4gICAgICAvLyBBZGQgdGhlIHJlcXVlc3QgSUQgdG8gdGhlIGxvZ2dpbmcgbWV0YWRhdGEsIGFuZCBlbmFibGUgZGVidWcgbG9nZ2luZyBpZiB0aGUgREVCVUcgZW52aXJvbm1lbnQgdmFyaWFibGUgaXMgc2V0IHRvIFwidHJ1ZVwiXG4gICAgICBjdHgubG9nZ2VyLm9wdGlvbnMubWV0YS5yZXF1ZXN0SWQgPSBjb250ZXh0LmF3c1JlcXVlc3RJZDtcbiAgICAgIGN0eC5sb2dnZXIub3B0aW9ucy5kZWJ1ZyA9IHByb2Nlc3MuZW52LkRFQlVHID09PSAndHJ1ZSc7XG5cbiAgICAgIC8vIExvZyB0aGUgZXZlbnQgb2JqZWN0IGZvciBkZWJ1Z2dpbmcgcHVycG9zZXNcbiAgICAgIGN0eC5sb2dnZXIuZGVidWcoSlNPTi5zdHJpbmdpZnkoZXZlbnQpKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gQXV0aGVudGljYXRlIHRoZSB1c2VyIHVzaW5nIHRoZSBDb2duaXRvIGF1dGhvcml6ZXJcbiAgICAgICAgYXdhaXQgY3R4LmF1dGguYXV0aGVudGljYXRlKCk7XG5cbiAgICAgICAgLy8gQ2FsbCB0aGUgdXNlci1kZWZpbmVkIGhhbmRsZXIgZnVuY3Rpb24sIHBhc3NpbmcgaW4gdGhlIHJlcXVlc3QgY29udGV4dCBvYmplY3QgYW5kIHRoZSBwYXJzZWQgcmVxdWVzdCBib2R5XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGhhbmRsZXIoY3R4LCBwYXJzZUJvZHkoZXZlbnQpKTtcblxuICAgICAgICAvLyBDb25zdHJ1Y3QgYW5kIHJldHVybiB0aGUgSFRUUCByZXNwb25zZVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN0YXR1c0NvZGU6IGN0eC5yZXNwb25zZS5zdGF0dXNDb2RlID8/IChyZXMgPyAyMDAgOiAyMDQpLFxuICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgICAuLi5jb3JzSGVhZGVyKGV2ZW50KSxcbiAgICAgICAgICAgIC4uLmN0eC5yZXNwb25zZS5oZWFkZXJzLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYm9keTogcmVzID8gKGN0eC5yZXNwb25zZS5qc29uID8gSlNPTi5zdHJpbmdpZnkocmVzKSA6IHJlcykgOiAnJyxcbiAgICAgICAgfTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgLy8gSGFuZGxlIGFueSBlcnJvcnMgdGhhdCBvY2N1ciBkdXJpbmcgcmVxdWVzdCBwcm9jZXNzaW5nXG5cbiAgICAgICAgLy8gSWYgdGhlIGVycm9yIGlzIGFuIGluc3RhbmNlIG9mIEh0dHBFcnJvciwgcmV0dXJuIGFuIEhUVFAgcmVzcG9uc2Ugd2l0aCB0aGUgZXJyb3Igc3RhdHVzIGNvZGUgYW5kIG1lc3NhZ2VcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgZXJyb3JzLkh0dHBFcnJvcikge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGF0dXNDb2RlOiBlcnJvci5zdGF0dXNDb2RlLFxuICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgICAgICAuLi5jb3JzSGVhZGVyKGV2ZW50KSxcbiAgICAgICAgICAgICAgLi4uY3R4LnJlc3BvbnNlLmhlYWRlcnMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYm9keTogZXJyb3IubWVzc2FnZSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIC8vIElmIHRoZSBlcnJvciBpcyBhIEJvb20gZXJyb3IgKGZyb20gdGhlIGhhcGkuanMgZnJhbWV3b3JrKSwgcmV0dXJuIGFuIEhUVFAgcmVzcG9uc2Ugd2l0aCB0aGUgZXJyb3Igc3RhdHVzIGNvZGUgYW5kIHBheWxvYWRcbiAgICAgICAgaWYgKGVycm9yLmlzQm9vbSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGF0dXNDb2RlOiBlcnJvci5vdXRwdXQuc3RhdHVzQ29kZSxcbiAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICAgICAgLi4uZXJyb3Iub3V0cHV0LmhlYWRlcnMsXG4gICAgICAgICAgICAgIC4uLmNvcnNIZWFkZXIoZXZlbnQpLFxuICAgICAgICAgICAgICAuLi5jdHgucmVzcG9uc2UuaGVhZGVycyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShlcnJvci5vdXRwdXQucGF5bG9hZCksXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICAvLyBGb3IgYWxsIG90aGVyIHR5cGVzIG9mIGVycm9ycywgbG9nIHRoZSBlcnJvciBhbmQgcmV0dXJuIGEgNTAwIHN0YXR1cyBjb2RlIHdpdGggdGhlIGVycm9yIG1lc3NhZ2VcbiAgICAgICAgY3R4LmxvZ2dlci5lcnJvcihlcnJvcik7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3RhdHVzQ29kZTogY3R4LnJlc3BvbnNlLnN0YXR1c0NvZGUgPz8gNTAwLFxuICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgICAuLi5jb3JzSGVhZGVyKGV2ZW50KSxcbiAgICAgICAgICAgIC4uLmN0eC5yZXNwb25zZS5oZWFkZXJzLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYm9keTogZXJyb3IudG9TdHJpbmcoKSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9O1xuICB9O1xuXG4vKipcbiAqIExvb2tzIHVwIGEgaGVhZGVyIHZhbHVlIGNhc2UtaW5zZW5zaXRpdmVseS5cbiAqIEhUVFAgaGVhZGVyIG5hbWVzIGFyZSBjYXNlLWluc2Vuc2l0aXZlIHBlciBSRkMgOTExMCDCpzUuMS5cbiAqL1xuZnVuY3Rpb24gaGVhZGVyVmFsdWUoaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPiB8IG51bGwgfCB1bmRlZmluZWQsIG5hbWU6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICghaGVhZGVycykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3Qga2V5ID0gT2JqZWN0LmtleXMoaGVhZGVycykuZmluZChrID0+IGsudG9Mb3dlckNhc2UoKSA9PT0gbmFtZS50b0xvd2VyQ2FzZSgpKTtcbiAgcmV0dXJuIGtleSA/IGhlYWRlcnNba2V5XSA6IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIHRha2VzIGFuIGV2ZW50IG9iamVjdCByZXByZXNlbnRpbmcgYW4gQVBJIEdhdGV3YXkgUHJveHkgZXZlbnRcbiAqIHdpdGggYSBDb2duaXRvIGF1dGhvcml6ZXIsIGFuZCBleHRyYWN0cyBhbmQgcGFyc2VzIHRoZSByZXF1ZXN0IGJvZHksIGlmIHByZXNlbnQuXG4gKlxuICogQHBhcmFtIGV2ZW50IFRoZSBBUEkgR2F0ZXdheSBQcm94eSBldmVudCB3aXRoIGEgQ29nbml0byBhdXRob3JpemVyXG4gKiBAcmV0dXJucyBUaGUgcGFyc2VkIHJlcXVlc3QgYm9keVxuICovXG5mdW5jdGlvbiBwYXJzZUJvZHk8VD4oZXZlbnQ6IEFXU0xhbWJkYS5BUElHYXRld2F5UHJveHlXaXRoQ29nbml0b0F1dGhvcml6ZXJFdmVudCk6IFQge1xuICBsZXQgYm9keSA9IGV2ZW50LmJvZHk7XG5cbiAgLy8gSWYgdGhlIHJlcXVlc3QgYm9keSBpcyBiYXNlNjQtZW5jb2RlZCwgZGVjb2RlIGl0XG4gIGlmIChldmVudC5ib2R5ICYmIGV2ZW50LmlzQmFzZTY0RW5jb2RlZCkge1xuICAgIGNvbnN0IGJ1ZmYgPSBCdWZmZXIuZnJvbShldmVudC5ib2R5ISwgJ2Jhc2U2NCcpO1xuICAgIGJvZHkgPSBidWZmLnRvU3RyaW5nKCd1dGY4Jyk7XG4gIH1cblxuICAvLyBJZiB0aGUgcmVxdWVzdCBib2R5IGlzIGluIEpTT04gZm9ybWF0LCBwYXJzZSBpdCBpbnRvIGEgSmF2YVNjcmlwdCBvYmplY3RcbiAgaWYgKGhlYWRlclZhbHVlKGV2ZW50LmhlYWRlcnMsICdjb250ZW50LXR5cGUnKT8uaW5jbHVkZXMoJ2FwcGxpY2F0aW9uL2pzb24nKSkge1xuICAgIHJldHVybiBKU09OLnBhcnNlKGJvZHkgPz8gJ3t9Jyk7XG4gIH1cblxuICAvLyBJZiB0aGUgcmVxdWVzdCBib2R5IGlzIG5vdCBwcmVzZW50IG9yIG5vdCBpbiBKU09OIGZvcm1hdCwgcmV0dXJuIGl0IGFzLWlzXG4gIHJldHVybiBib2R5IGFzIGFueTtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgdGhlIENPUlMgaGVhZGVycyB0byBiZSBpbmNsdWRlZCBpbiB0aGUgQVBJIEdhdGV3YXkgcmVzcG9uc2UuXG4gKlxuICogQHBhcmFtIGV2ZW50IC0gVGhlIEFQSSBHYXRld2F5IGV2ZW50IG9iamVjdC5cbiAqIEByZXR1cm5zIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBDT1JTIGhlYWRlcnMuXG4gKi9cbmZ1bmN0aW9uIGNvcnNIZWFkZXIoZXZlbnQ6IEFXU0xhbWJkYS5BUElHYXRld2F5UHJveHlXaXRoQ29nbml0b0F1dGhvcml6ZXJFdmVudCk6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9IHtcbiAgY29uc3Qgb3JpZ2luID0gaGVhZGVyVmFsdWUoZXZlbnQ/LmhlYWRlcnMsICdvcmlnaW4nKTtcbiAgcmV0dXJuIHtcbiAgICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luJzogb3JpZ2luID8/ICcqJywgLy8gQWxsb3cgcmVxdWVzdHMgZnJvbSB0aGUgb3JpZ2luIGhlYWRlciwgb3IgYWxsb3cgYW55IG9yaWdpbiBpZiBub3QgcHJlc2VudFxuICAgICdBY2Nlc3MtQ29udHJvbC1BbGxvdy1DcmVkZW50aWFscyc6IG9yaWdpbiA/ICd0cnVlJyA6ICdmYWxzZScsIC8vIEluY2x1ZGUgY29va2llcyBpbiBjcm9zcy1vcmlnaW4gcmVxdWVzdHMgaWYgdGhlIG9yaWdpbiBoZWFkZXIgaXMgcHJlc2VudFxuICAgICdBY2Nlc3MtQ29udHJvbC1BbGxvdy1NZXRob2RzJzogJyonLCAvLyBBbGxvdyBhbnkgSFRUUCBtZXRob2RcbiAgICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctSGVhZGVycyc6ICdBdXRob3JpemF0aW9uLCAqJywgLy8gQWxsb3cgdGhlIEF1dGhvcml6YXRpb24gaGVhZGVyIGFuZCBhbnkgb3RoZXIgaGVhZGVyc1xuICB9O1xufVxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vLyBBcHBTeW5jXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBUaGUgY29udGV4dCBmb3IgdGhlIEFwcFN5bmMgcmVzb2x2ZXIgZnVuY3Rpb24uXG4gKiBDb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZXZlbnQsIGxhbWJkYSBjb250ZXh0LCBsb2dnZXIsIGFuZCBDb2duaXRvIGF1dGhvcml6ZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXBwU3luY0hhbmRsZXJDb250ZXh0PFQ+IHtcbiAgZXZlbnQ6IEFXU0xhbWJkYS5BcHBTeW5jUmVzb2x2ZXJFdmVudDxUPjtcbiAgbGFtYmRhQ29udGV4dDogQVdTTGFtYmRhLkNvbnRleHQ7XG4gIGxvZ2dlcjogbG9nZ2VyLkxhbWJkYUxvZztcbiAgY29nbml0b0F1dGg6IENvZ25pdG9BdXRob3JpemVyO1xufVxuXG4vKipcbiAqIEEgZnVuY3Rpb24gdGhhdCBoYW5kbGVzIGFuIEFwcFN5bmMgcmVzb2x2ZXIgZXZlbnQuXG4gKiBSZWNlaXZlcyB0aGUgY29udGV4dCBvYmplY3QgYW5kIHJldHVybnMgdGhlIHJlc3BvbnNlLlxuICovXG5leHBvcnQgdHlwZSBBcHBTeW5jSGFuZGxlcjxULCBSPiA9IChcbiAgY29udGV4dDogQXBwU3luY0hhbmRsZXJDb250ZXh0PFQ+LFxuKSA9PiBQcm9taXNlPFI+O1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gQXBwU3luYyByZXNvbHZlciBoYW5kbGVyIGZyb20gdGhlIGdpdmVuIEFwcFN5bmNIYW5kbGVyLlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIHVzZWQgYXMgYW4gQXBwU3luYyByZXNvbHZlci5cbiAqXG4gKiBAcGFyYW0gaGFuZGxlciBUaGUgQXBwU3luY0hhbmRsZXIgdG8gdXNlIGFzIHRoZSByZXNvbHZlci5cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUFwcFN5bmNIYW5kbGVyID1cbiAgPFQsIFI+KGhhbmRsZXI6IEFwcFN5bmNIYW5kbGVyPFQsIFI+KTogQVdTTGFtYmRhLkFwcFN5bmNSZXNvbHZlckhhbmRsZXI8VCwgUj4gPT4ge1xuICAgIHJldHVybiBhc3luYyAoZXZlbnQsIGNvbnRleHQpID0+IHtcbiAgICAgIGNvbnN0IGN0eDogQXBwU3luY0hhbmRsZXJDb250ZXh0PFQ+ID0ge1xuICAgICAgICBldmVudCxcbiAgICAgICAgbGFtYmRhQ29udGV4dDogY29udGV4dCxcbiAgICAgICAgbG9nZ2VyOiBsb2dnZXIgYXMgdW5rbm93biBhcyBsb2dnZXIuTGFtYmRhTG9nLFxuICAgICAgICBjb2duaXRvQXV0aDogbmV3IEFwcFN5bmNDb2duaXRvQXV0aG9yaXplcihldmVudCksXG4gICAgICB9O1xuXG4gICAgICAvLyBzZXQgdGhlIG1ldGEgaW5mb3JtYXRpb24gaW4gbG9nZ2VyXG4gICAgICBjdHgubG9nZ2VyLm9wdGlvbnMubWV0YS5yZXF1ZXN0SWQgPSBjb250ZXh0LmF3c1JlcXVlc3RJZDtcbiAgICAgIC8vIHNldCB0aGUgZGVidWcgZmxhZyBmb3IgbG9nZ2VyXG4gICAgICBjdHgubG9nZ2VyLm9wdGlvbnMuZGVidWcgPSBwcm9jZXNzLmVudi5ERUJVRyA9PT0gJ3RydWUnO1xuXG4gICAgICAvLyBsb2cgdGhlIHJlY2VpdmVkIGV2ZW50XG4gICAgICBjdHgubG9nZ2VyLmRlYnVnKEpTT04uc3RyaW5naWZ5KGV2ZW50KSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIGF1dGhlbnRpY2F0ZSB0aGUgaW5jb21pbmcgcmVxdWVzdFxuICAgICAgICBhd2FpdCBjdHguY29nbml0b0F1dGguYXV0aGVudGljYXRlKCk7XG4gICAgICAgIC8vIGludm9rZSB0aGUgaGFuZGxlciBmdW5jdGlvbiB3aXRoIHRoZSBjb250ZXh0XG4gICAgICAgIHJldHVybiBhd2FpdCBoYW5kbGVyKGN0eCk7XG4gICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgIC8vIGxvZyB0aGUgZXJyb3IgYW5kIHRocm93IGl0IGFnYWluXG4gICAgICAgIGN0eC5sb2dnZXIuZXJyb3IoZXJyb3IpO1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9O1xuICB9O1xuXG4iXX0=
312
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9sYW1iZGEvaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxxQ0FBOEI7QUFDOUIsNERBQStDO0FBQy9DLGdFQUFrRDtBQUNsRCxpQ0FNZ0I7QUFDaEIsaURBQW1DO0FBNkRuQzs7R0FFRztBQUNJLE1BQU0sbUNBQW1DLEdBQUcsQ0FBK0QsT0FBMEgsRUFBdUIsRUFBRTtJQUNuUSxPQUFPLElBQUEseUJBQWlCLEVBQUMsT0FBTyxDQUFDLENBQUM7QUFDcEMsQ0FBQyxDQUFDO0FBRlcsUUFBQSxtQ0FBbUMsdUNBRTlDO0FBRUY7O0dBRUc7QUFDSSxNQUFNLDZDQUE2QyxHQUFHLENBQXNDLE9BQTRFLEVBQXVCLEVBQUU7SUFDdE0sT0FBTyxJQUFBLHlCQUFpQixFQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3BDLENBQUMsQ0FBQztBQUZXLFFBQUEsNkNBQTZDLGlEQUV4RDtBQUVGOztHQUVHO0FBQ0ksTUFBTSxvQkFBb0IsR0FBRyxDQUFnRCxPQUE2RSxFQUF1QixFQUFFO0lBQ3hMLE9BQU8sSUFBQSx5QkFBaUIsRUFBQyxPQUFPLENBQUMsQ0FBQztBQUNwQyxDQUFDLENBQUM7QUFGVyxRQUFBLG9CQUFvQix3QkFFL0I7QUFFRjs7R0FFRztBQUNILE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxLQUFxRixFQUFFLEdBQWMsRUFBRSxFQUFFO0lBQ2pJLGlIQUFpSDtJQUNqSCxJQUFJLGFBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNyQixPQUFPLElBQUksb0NBQTZCLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZELENBQUM7U0FBTSxDQUFDO1FBQ04sZ0dBQWdHO1FBQ2hHLE9BQU8sSUFBSSxnQ0FBeUIsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lB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RSxJQUFJO29CQUNWLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUztvQkFDMUIsWUFBWSxFQUFFLEtBQUssQ0FBQyxPQUFPO29CQUMzQixTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7aUJBQ1gsQ0FBQztZQUNwQixDQUFDO1lBQ0QsbUNBQW1DO1lBQ25DLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3hCLE1BQU0sS0FBSyxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUMsQ0FBQztBQUNKLENBQUMsQ0FBQztBQW5GUyxRQUFBLG9CQUFvQix3QkFtRjdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZW52IH0gZnJvbSAncHJvY2Vzcyc7XG5pbXBvcnQgbG9nZ2VyLCB7IExhbWJkYUxvZyB9IGZyb20gJ2xhbWJkYS1sb2cnO1xuaW1wb3J0ICogYXMgYXBwc3luY0Vycm9ycyBmcm9tICcuL2FwcHN5bmMtZXJyb3JzJztcbmltcG9ydCB7XG4gIEFwaUdhdGV3YXl2MUNvZ25pdG9BdXRob3JpemVyLFxuICBBcGlHYXRld2F5djFKd3RBdXRob3JpemVyLFxuICBBcHBTeW5jQ29nbml0b0F1dGhvcml6ZXIsXG4gIENvZ25pdG9BdXRob3JpemVyLFxuICBKd3RBdXRob3JpemVyLFxufSBmcm9tICcuL2F1dGgnO1xuaW1wb3J0ICogYXMgZXJyb3JzIGZyb20gJy4vZXJyb3JzJztcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vLyBIVFRQIEFwaVxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbi8qKlxuICogQW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIHByb3BlcnRpZXMgZm9yIGFuIEhUVFAgcmVzcG9uc2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSHR0cFJlc3BvbnNlQ29udGV4dCB7XG4gIHN0YXR1c0NvZGU/OiBudW1iZXI7XG4gIGhlYWRlcnM6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9O1xuICBqc29uOiBib29sZWFuO1xufVxuXG4vKipcbiAqIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBwcm9wZXJ0aWVzIGZvciBhbiBIVFRQIHJlcXVlc3QgaGFuZGxlci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBIdHRwSGFuZGxlckNvbnRleHQge1xuICBldmVudDogQVdTTGFtYmRhLkFQSUdhdGV3YXlQcm94eVdpdGhDb2duaXRvQXV0aG9yaXplckV2ZW50O1xuICBsYW1iZGFDb250ZXh0OiBBV1NMYW1iZGEuQ29udGV4dDtcbiAgbG9nZ2VyOiBsb2dnZXIuTGFtYmRhTG9nO1xuICByZXNwb25zZTogSHR0cFJlc3BvbnNlQ29udGV4dDtcbiAgYXV0aDogSnd0QXV0aG9yaXplcjtcbn1cblxuLyoqXG4gKiBBIHR5cGUgZGVmaW5pdGlvbiBmb3IgYW4gSFRUUCBoYW5kbGVyLlxuICovXG5leHBvcnQgdHlwZSBIdHRwSGFuZGxlcjxULCBSPiA9IChcbiAgY29udGV4dDogSHR0cEhhbmRsZXJDb250ZXh0LFxuICBib2R5OiBULFxuKSA9PiBQcm9taXNlPFI+O1xuXG4vKipcbiAqIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBwcm9wZXJ0aWVzIGZvciBhbiBPcGVuQVBJIG9wZXJhdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPcGVyYXRpb24ge1xuICByZXNwb25zZXM6IHtcbiAgICBbc3RhdHVzQ29kZTogbnVtYmVyXToge1xuICAgICAgY29udGVudDoge1xuICAgICAgICAnYXBwbGljYXRpb24vanNvbic6IGFueTtcbiAgICAgIH07XG4gICAgfSB8IGFueTtcbiAgfTtcbn1cblxuLyoqXG4gKiBBIHR5cGUgZGVmaW5pdGlvbiBmb3IgYW4gQVBJIEdhdGV3YXkgdjEgcmVxdWVzdCBoYW5kbGVyLlxuICovXG5leHBvcnQgdHlwZSBBUElHYXRld2F5djFIYW5kbGVyID1cbiAgQVdTTGFtYmRhLkhhbmRsZXI8QVdTTGFtYmRhLkFQSUdhdGV3YXlQcm94eVdpdGhDb2duaXRvQXV0aG9yaXplckV2ZW50LCBBV1NMYW1iZGEuQVBJR2F0ZXdheVByb3h5UmVzdWx0IHwgdW5kZWZpbmVkPjtcblxuLyoqXG4gKiBBbiBvYmplY3QgY29udGFpbmluZyB0aGUgcHJvcGVydGllcyBmb3IgYW4gT3BlbkFQSSBvcGVyYXRpb24gd2l0aCBhIHJlcXVlc3QgYm9keS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPcGVyYXRpb25XaXRoUmVxdWVzdEJvZHkgZXh0ZW5kcyBPcGVyYXRpb24ge1xuICByZXF1ZXN0Qm9keTogeyBjb250ZW50OiB7ICdhcHBsaWNhdGlvbi9qc29uJzogYW55IH0gfTtcbn1cblxuLyoqXG4gKiBBIGZhY3RvcnkgZnVuY3Rpb24gdGhhdCBjcmVhdGVzIGFuIEhUVFAgcmVxdWVzdCBoYW5kbGVyIGZvciBhbiBPcGVuQVBJIG9wZXJhdGlvbiB3aXRoIGEgcmVxdWVzdCBib2R5LlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlT3BlbkFwaUhhbmRsZXJXaXRoUmVxdWVzdEJvZHkgPSA8T1AgZXh0ZW5kcyBPcGVyYXRpb25XaXRoUmVxdWVzdEJvZHksIFNDIGV4dGVuZHMgbnVtYmVyID0gMjAwPihoYW5kbGVyOiBIdHRwSGFuZGxlcjxPUFsncmVxdWVzdEJvZHknXVsnY29udGVudCddWydhcHBsaWNhdGlvbi9qc29uJ10sIE9QWydyZXNwb25zZXMnXVtTQ11bJ2NvbnRlbnQnXVsnYXBwbGljYXRpb24vanNvbiddPik6IEFQSUdhdGV3YXl2MUhhbmRsZXIgPT4ge1xuICByZXR1cm4gY3JlYXRlSHR0cEhhbmRsZXIoaGFuZGxlcik7XG59O1xuXG4vKipcbiAqIEEgZmFjdG9yeSBmdW5jdGlvbiB0aGF0IGNyZWF0ZXMgYW4gSFRUUCByZXF1ZXN0IGhhbmRsZXIgZm9yIGFuIE9wZW5BUEkgb3BlcmF0aW9uIHdpdGggYSByZXF1ZXN0IGJvZHkgYW5kIG5vIHJlc3BvbnNlLlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlT3BlbkFwaUhhbmRsZXJXaXRoUmVxdWVzdEJvZHlOb1Jlc3BvbnNlID0gPE9QIGV4dGVuZHMgT3BlcmF0aW9uV2l0aFJlcXVlc3RCb2R5PihoYW5kbGVyOiBIdHRwSGFuZGxlcjxPUFsncmVxdWVzdEJvZHknXVsnY29udGVudCddWydhcHBsaWNhdGlvbi9qc29uJ10sIHZvaWQ+KTogQVBJR2F0ZXdheXYxSGFuZGxlciA9PiB7XG4gIHJldHVybiBjcmVhdGVIdHRwSGFuZGxlcihoYW5kbGVyKTtcbn07XG5cbi8qKlxuICogQSBmYWN0b3J5IGZ1bmN0aW9uIHRoYXQgY3JlYXRlcyBhbiBIVFRQIHJlcXVlc3QgaGFuZGxlciBmb3IgYW4gT3BlbkFQSSBvcGVyYXRpb24uXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVPcGVuQXBpSGFuZGxlciA9IDxPUCBleHRlbmRzIE9wZXJhdGlvbiwgU0MgZXh0ZW5kcyBudW1iZXIgPSAyMDA+KGhhbmRsZXI6IEh0dHBIYW5kbGVyPGFueSwgT1BbJ3Jlc3BvbnNlcyddW1NDXVsnY29udGVudCddWydhcHBsaWNhdGlvbi9qc29uJ10+KTogQVBJR2F0ZXdheXYxSGFuZGxlciA9PiB7XG4gIHJldHVybiBjcmVhdGVIdHRwSGFuZGxlcihoYW5kbGVyKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGFuIGF1dGhvcml6ZXIgZm9yIHRoZSBhdXRoZW50aWNhdGlvbiBtZXRob2QgY2hvc2VuIChKV1Qgb3IgQ29nbml0bykuXG4gKi9cbmNvbnN0IGNyZWF0ZUF1dGhvcml6ZXIgPSAoZXZlbnQ6IEFXU0xhbWJkYS5BUElHYXRld2F5UHJveHlFdmVudEJhc2U8QVdTTGFtYmRhLkFQSUdhdGV3YXlQcm94eUNvZ25pdG9BdXRob3JpemVyPiwgbG9nOiBMYW1iZGFMb2cpID0+IHtcbiAgLy8gSWYgQ29nbml0byBpcyB1c2VkLCBVU0VSX1BPT0xfSUQgaXMgaW5qZWN0ZWQgaW50byB0aGUgZnVuY3Rpb24ncyBlbnZpcm9ubWVudC4gQ3VycmVudGx5IGFzc3VtZXMgSldUIG90aGVyd2lzZS5cbiAgaWYgKGVudi5VU0VSX1BPT0xfSUQpIHtcbiAgICByZXR1cm4gbmV3IEFwaUdhdGV3YXl2MUNvZ25pdG9BdXRob3JpemVyKGV2ZW50LCBsb2cpO1xuICB9IGVsc2Uge1xuICAgIC8vIFRoaXMgbWlnaHQgbmVlZCB0byBnZXQgbW9yZSBzb3BoaXN0aWNhdGVkIGlmIG1vcmUgYXV0aG9yaXphdGlvbiBtZXRob2RzIG5lZWQgdG8gYmUgc3VwcG9ydGVkLlxuICAgIHJldHVybiBuZXcgQXBpR2F0ZXdheXYxSnd0QXV0aG9yaXplcihldmVudCwgJ2FkbWluJywgbG9nKTtcbiAgfVxufTtcblxuLyoqXG4gKiBBIGZhY3RvcnkgZnVuY3Rpb24gdGhhdCBjcmVhdGVzIGFuIEhUVFAgcmVxdWVzdCBoYW5kbGVyLlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlSHR0cEhhbmRsZXIgPVxuICA8VCwgUj4oaGFuZGxlcjogSHR0cEhhbmRsZXI8VCwgUj4pOiBBUElHYXRld2F5djFIYW5kbGVyID0+IHtcbiAgICByZXR1cm4gYXN5bmMgKGV2ZW50LCBjb250ZXh0KSA9PiB7XG4gICAgICAvLyBDcmVhdGUgYW4gb2JqZWN0IHRvIGhvbGQgdGhlIGNvbnRleHQgZm9yIHRoaXMgSFRUUCByZXF1ZXN0XG4gICAgICBjb25zdCBhdXRoID0gY3JlYXRlQXV0aG9yaXplcihldmVudCwgbG9nZ2VyIGFzIHVua25vd24gYXMgbG9nZ2VyLkxhbWJkYUxvZyk7XG4gICAgICBjb25zdCBjdHg6IEh0dHBIYW5kbGVyQ29udGV4dCA9IHtcbiAgICAgICAgZXZlbnQsXG4gICAgICAgIGF1dGgsXG4gICAgICAgIGxhbWJkYUNvbnRleHQ6IGNvbnRleHQsXG4gICAgICAgIGxvZ2dlcjogbG9nZ2VyIGFzIHVua25vd24gYXMgbG9nZ2VyLkxhbWJkYUxvZyxcbiAgICAgICAgcmVzcG9uc2U6IHsgaGVhZGVyczoge30sIGpzb246IHRydWUgfSxcbiAgICAgIH07XG4gICAgICAvLyBBZGQgdGhlIHJlcXVlc3QgSUQgdG8gdGhlIGxvZ2dpbmcgbWV0YWRhdGEsIGFuZCBlbmFibGUgZGVidWcgbG9nZ2luZyBpZiB0aGUgREVCVUcgZW52aXJvbm1lbnQgdmFyaWFibGUgaXMgc2V0IHRvIFwidHJ1ZVwiXG4gICAgICBjdHgubG9nZ2VyLm9wdGlvbnMubWV0YS5yZXF1ZXN0SWQgPSBjb250ZXh0LmF3c1JlcXVlc3RJZDtcbiAgICAgIGN0eC5sb2dnZXIub3B0aW9ucy5kZWJ1ZyA9IHByb2Nlc3MuZW52LkRFQlVHID09PSAndHJ1ZSc7XG5cbiAgICAgIC8vIExvZyB0aGUgZXZlbnQgb2JqZWN0IGZvciBkZWJ1Z2dpbmcgcHVycG9zZXNcbiAgICAgIGN0eC5sb2dnZXIuZGVidWcoSlNPTi5zdHJpbmdpZnkoZXZlbnQpKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gQXV0aGVudGljYXRlIHRoZSB1c2VyIHVzaW5nIHRoZSBDb2duaXRvIGF1dGhvcml6ZXJcbiAgICAgICAgYXdhaXQgY3R4LmF1dGguYXV0aGVudGljYXRlKCk7XG5cbiAgICAgICAgLy8gQ2FsbCB0aGUgdXNlci1kZWZpbmVkIGhhbmRsZXIgZnVuY3Rpb24sIHBhc3NpbmcgaW4gdGhlIHJlcXVlc3QgY29udGV4dCBvYmplY3QgYW5kIHRoZSBwYXJzZWQgcmVxdWVzdCBib2R5XG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGhhbmRsZXIoY3R4LCBwYXJzZUJvZHkoZXZlbnQpKTtcblxuICAgICAgICAvLyBDb25zdHJ1Y3QgYW5kIHJldHVybiB0aGUgSFRUUCByZXNwb25zZVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN0YXR1c0NvZGU6IGN0eC5yZXNwb25zZS5zdGF0dXNDb2RlID8/IChyZXMgPyAyMDAgOiAyMDQpLFxuICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgICAuLi5jb3JzSGVhZGVyKGV2ZW50KSxcbiAgICAgICAgICAgIC4uLmN0eC5yZXNwb25zZS5oZWFkZXJzLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYm9keTogcmVzID8gKGN0eC5yZXNwb25zZS5qc29uID8gSlNPTi5zdHJpbmdpZnkocmVzKSA6IHJlcykgOiAnJyxcbiAgICAgICAgfTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgLy8gSGFuZGxlIGFueSBlcnJvcnMgdGhhdCBvY2N1ciBkdXJpbmcgcmVxdWVzdCBwcm9jZXNzaW5nXG5cbiAgICAgICAgLy8gSWYgdGhlIGVycm9yIGlzIGFuIGluc3RhbmNlIG9mIEh0dHBFcnJvciwgcmV0dXJuIGFuIEhUVFAgcmVzcG9uc2Ugd2l0aCB0aGUgZXJyb3Igc3RhdHVzIGNvZGUgYW5kIG1lc3NhZ2VcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgZXJyb3JzLkh0dHBFcnJvcikge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGF0dXNDb2RlOiBlcnJvci5zdGF0dXNDb2RlLFxuICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgICAgICAuLi5jb3JzSGVhZGVyKGV2ZW50KSxcbiAgICAgICAgICAgICAgLi4uY3R4LnJlc3BvbnNlLmhlYWRlcnMsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYm9keTogZXJyb3IubWVzc2FnZSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIC8vIElmIHRoZSBlcnJvciBpcyBhIEJvb20gZXJyb3IgKGZyb20gdGhlIGhhcGkuanMgZnJhbWV3b3JrKSwgcmV0dXJuIGFuIEhUVFAgcmVzcG9uc2Ugd2l0aCB0aGUgZXJyb3Igc3RhdHVzIGNvZGUgYW5kIHBheWxvYWRcbiAgICAgICAgaWYgKGVycm9yLmlzQm9vbSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGF0dXNDb2RlOiBlcnJvci5vdXRwdXQuc3RhdHVzQ29kZSxcbiAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICAgICAgLi4uZXJyb3Iub3V0cHV0LmhlYWRlcnMsXG4gICAgICAgICAgICAgIC4uLmNvcnNIZWFkZXIoZXZlbnQpLFxuICAgICAgICAgICAgICAuLi5jdHgucmVzcG9uc2UuaGVhZGVycyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShlcnJvci5vdXRwdXQucGF5bG9hZCksXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICAvLyBGb3IgYWxsIG90aGVyIHR5cGVzIG9mIGVycm9ycywgbG9nIHRoZSBlcnJvciBhbmQgcmV0dXJuIGEgNTAwIHN0YXR1cyBjb2RlIHdpdGggdGhlIGVycm9yIG1lc3NhZ2VcbiAgICAgICAgY3R4LmxvZ2dlci5lcnJvcihlcnJvcik7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3RhdHVzQ29kZTogY3R4LnJlc3BvbnNlLnN0YXR1c0NvZGUgPz8gNTAwLFxuICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgICAuLi5jb3JzSGVhZGVyKGV2ZW50KSxcbiAgICAgICAgICAgIC4uLmN0eC5yZXNwb25zZS5oZWFkZXJzLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYm9keTogZXJyb3IudG9TdHJpbmcoKSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9O1xuICB9O1xuXG4vKipcbiAqIExvb2tzIHVwIGEgaGVhZGVyIHZhbHVlIGNhc2UtaW5zZW5zaXRpdmVseS5cbiAqIEhUVFAgaGVhZGVyIG5hbWVzIGFyZSBjYXNlLWluc2Vuc2l0aXZlIHBlciBSRkMgOTExMCDCpzUuMS5cbiAqL1xuZnVuY3Rpb24gaGVhZGVyVmFsdWUoaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPiB8IG51bGwgfCB1bmRlZmluZWQsIG5hbWU6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICghaGVhZGVycykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3Qga2V5ID0gT2JqZWN0LmtleXMoaGVhZGVycykuZmluZChrID0+IGsudG9Mb3dlckNhc2UoKSA9PT0gbmFtZS50b0xvd2VyQ2FzZSgpKTtcbiAgcmV0dXJuIGtleSA/IGhlYWRlcnNba2V5XSA6IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIHRha2VzIGFuIGV2ZW50IG9iamVjdCByZXByZXNlbnRpbmcgYW4gQVBJIEdhdGV3YXkgUHJveHkgZXZlbnRcbiAqIHdpdGggYSBDb2duaXRvIGF1dGhvcml6ZXIsIGFuZCBleHRyYWN0cyBhbmQgcGFyc2VzIHRoZSByZXF1ZXN0IGJvZHksIGlmIHByZXNlbnQuXG4gKlxuICogQHBhcmFtIGV2ZW50IFRoZSBBUEkgR2F0ZXdheSBQcm94eSBldmVudCB3aXRoIGEgQ29nbml0byBhdXRob3JpemVyXG4gKiBAcmV0dXJucyBUaGUgcGFyc2VkIHJlcXVlc3QgYm9keVxuICovXG5mdW5jdGlvbiBwYXJzZUJvZHk8VD4oZXZlbnQ6IEFXU0xhbWJkYS5BUElHYXRld2F5UHJveHlXaXRoQ29nbml0b0F1dGhvcml6ZXJFdmVudCk6IFQge1xuICBsZXQgYm9keSA9IGV2ZW50LmJvZHk7XG5cbiAgLy8gSWYgdGhlIHJlcXVlc3QgYm9keSBpcyBiYXNlNjQtZW5jb2RlZCwgZGVjb2RlIGl0XG4gIGlmIChldmVudC5ib2R5ICYmIGV2ZW50LmlzQmFzZTY0RW5jb2RlZCkge1xuICAgIGNvbnN0IGJ1ZmYgPSBCdWZmZXIuZnJvbShldmVudC5ib2R5ISwgJ2Jhc2U2NCcpO1xuICAgIGJvZHkgPSBidWZmLnRvU3RyaW5nKCd1dGY4Jyk7XG4gIH1cblxuICAvLyBJZiB0aGUgcmVxdWVzdCBib2R5IGlzIGluIEpTT04gZm9ybWF0LCBwYXJzZSBpdCBpbnRvIGEgSmF2YVNjcmlwdCBvYmplY3RcbiAgaWYgKGhlYWRlclZhbHVlKGV2ZW50LmhlYWRlcnMsICdjb250ZW50LXR5cGUnKT8uaW5jbHVkZXMoJ2FwcGxpY2F0aW9uL2pzb24nKSkge1xuICAgIHJldHVybiBKU09OLnBhcnNlKGJvZHkgPz8gJ3t9Jyk7XG4gIH1cblxuICAvLyBJZiB0aGUgcmVxdWVzdCBib2R5IGlzIG5vdCBwcmVzZW50IG9yIG5vdCBpbiBKU09OIGZvcm1hdCwgcmV0dXJuIGl0IGFzLWlzXG4gIHJldHVybiBib2R5IGFzIGFueTtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgdGhlIENPUlMgaGVhZGVycyB0byBiZSBpbmNsdWRlZCBpbiB0aGUgQVBJIEdhdGV3YXkgcmVzcG9uc2UuXG4gKlxuICogQHBhcmFtIGV2ZW50IC0gVGhlIEFQSSBHYXRld2F5IGV2ZW50IG9iamVjdC5cbiAqIEByZXR1cm5zIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBDT1JTIGhlYWRlcnMuXG4gKi9cbmZ1bmN0aW9uIGNvcnNIZWFkZXIoZXZlbnQ6IEFXU0xhbWJkYS5BUElHYXRld2F5UHJveHlXaXRoQ29nbml0b0F1dGhvcml6ZXJFdmVudCk6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9IHtcbiAgY29uc3Qgb3JpZ2luID0gaGVhZGVyVmFsdWUoZXZlbnQ/LmhlYWRlcnMsICdvcmlnaW4nKTtcbiAgcmV0dXJuIHtcbiAgICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luJzogb3JpZ2luID8/ICcqJywgLy8gQWxsb3cgcmVxdWVzdHMgZnJvbSB0aGUgb3JpZ2luIGhlYWRlciwgb3IgYWxsb3cgYW55IG9yaWdpbiBpZiBub3QgcHJlc2VudFxuICAgICdBY2Nlc3MtQ29udHJvbC1BbGxvdy1DcmVkZW50aWFscyc6IG9yaWdpbiA/ICd0cnVlJyA6ICdmYWxzZScsIC8vIEluY2x1ZGUgY29va2llcyBpbiBjcm9zcy1vcmlnaW4gcmVxdWVzdHMgaWYgdGhlIG9yaWdpbiBoZWFkZXIgaXMgcHJlc2VudFxuICAgICdBY2Nlc3MtQ29udHJvbC1BbGxvdy1NZXRob2RzJzogJyonLCAvLyBBbGxvdyBhbnkgSFRUUCBtZXRob2RcbiAgICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctSGVhZGVycyc6ICdBdXRob3JpemF0aW9uLCAqJywgLy8gQWxsb3cgdGhlIEF1dGhvcml6YXRpb24gaGVhZGVyIGFuZCBhbnkgb3RoZXIgaGVhZGVyc1xuICB9O1xufVxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vLyBBcHBTeW5jXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBUaGUgY29udGV4dCBmb3IgdGhlIEFwcFN5bmMgcmVzb2x2ZXIgZnVuY3Rpb24uXG4gKiBDb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZXZlbnQsIGxhbWJkYSBjb250ZXh0LCBsb2dnZXIsIGFuZCBDb2duaXRvIGF1dGhvcml6ZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXBwU3luY0hhbmRsZXJDb250ZXh0PFQ+IHtcbiAgZXZlbnQ6IEFXU0xhbWJkYS5BcHBTeW5jUmVzb2x2ZXJFdmVudDxUPjtcbiAgbGFtYmRhQ29udGV4dDogQVdTTGFtYmRhLkNvbnRleHQ7XG4gIGxvZ2dlcjogbG9nZ2VyLkxhbWJkYUxvZztcbiAgY29nbml0b0F1dGg6IENvZ25pdG9BdXRob3JpemVyO1xufVxuXG4vKipcbiAqIEEgZnVuY3Rpb24gdGhhdCBoYW5kbGVzIGFuIEFwcFN5bmMgcmVzb2x2ZXIgZXZlbnQuXG4gKiBSZWNlaXZlcyB0aGUgY29udGV4dCBvYmplY3QgYW5kIHJldHVybnMgdGhlIHJlc3BvbnNlLlxuICovXG5leHBvcnQgdHlwZSBBcHBTeW5jSGFuZGxlcjxULCBSPiA9IChcbiAgY29udGV4dDogQXBwU3luY0hhbmRsZXJDb250ZXh0PFQ+LFxuKSA9PiBQcm9taXNlPFI+O1xuXG4vKipcbiAqIE1hcHMgYW4gSFRUUCBzdGF0dXMgY29kZSB0byB0aGUgR3JhcGhRTCBlcnJvclR5cGUgcmVwb3J0ZWQgdG8gQXBwU3luYy5cbiAqXG4gKiBMb2NhbCAobm9uLWV4cG9ydGVkKSBoZWxwZXIgdXNlZCBvbmx5IGJ5IGNyZWF0ZUFwcFN5bmNIYW5kbGVyIHdoZW4gaXRcbiAqIHRyYW5zbGF0ZXMgYW4gZXJyb3JzLkh0dHBFcnJvciBpbnRvIGEgdHlwZWQgQXBwU3luYyBlcnJvci4gVGhlIGV4cGxpY2l0XG4gKiBkZWZhdWx0IGtlZXBzIGFueSB1bm1hcHBlZCBzdGF0dXMgKGZvciBleGFtcGxlIGEgNDE4IG9yIGEgNXh4KSByZXBvcnRlZCBhc1xuICogdGhlIGdlbmVyaWMgJ0Vycm9yJyBlcnJvclR5cGUgcmF0aGVyIHRoYW4gbGVha2luZyB0aGUgcmF3IHN0YXR1cyBjb2RlLlxuICovXG5mdW5jdGlvbiBodHRwU3RhdHVzVG9FcnJvclR5cGUoc3RhdHVzQ29kZTogbnVtYmVyKTogc3RyaW5nIHtcbiAgc3dpdGNoIChzdGF0dXNDb2RlKSB7XG4gICAgY2FzZSA0MDA6XG4gICAgICByZXR1cm4gJ0JhZFJlcXVlc3QnO1xuICAgIGNhc2UgNDAxOlxuICAgICAgcmV0dXJuICdVbmF1dGhvcml6ZWQnO1xuICAgIGNhc2UgNDAzOlxuICAgICAgcmV0dXJuICdGb3JiaWRkZW4nO1xuICAgIGNhc2UgNDA0OlxuICAgICAgcmV0dXJuICdOb3RGb3VuZCc7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiAnRXJyb3InO1xuICB9XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBBcHBTeW5jIHJlc29sdmVyIGhhbmRsZXIgZnJvbSB0aGUgZ2l2ZW4gQXBwU3luY0hhbmRsZXIuXG4gKiBSZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCBjYW4gYmUgdXNlZCBhcyBhbiBBcHBTeW5jIHJlc29sdmVyLlxuICpcbiAqIEBwYXJhbSBoYW5kbGVyIFRoZSBBcHBTeW5jSGFuZGxlciB0byB1c2UgYXMgdGhlIHJlc29sdmVyLlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlQXBwU3luY0hhbmRsZXIgPVxuICA8VCwgUj4oaGFuZGxlcjogQXBwU3luY0hhbmRsZXI8VCwgUj4pOiBBV1NMYW1iZGEuQXBwU3luY1Jlc29sdmVySGFuZGxlcjxULCBSPiA9PiB7XG4gICAgcmV0dXJuIGFzeW5jIChldmVudCwgY29udGV4dCkgPT4ge1xuICAgICAgY29uc3QgY3R4OiBBcHBTeW5jSGFuZGxlckNvbnRleHQ8VD4gPSB7XG4gICAgICAgIGV2ZW50LFxuICAgICAgICBsYW1iZGFDb250ZXh0OiBjb250ZXh0LFxuICAgICAgICBsb2dnZXI6IGxvZ2dlciBhcyB1bmtub3duIGFzIGxvZ2dlci5MYW1iZGFMb2csXG4gICAgICAgIGNvZ25pdG9BdXRoOiBuZXcgQXBwU3luY0NvZ25pdG9BdXRob3JpemVyKGV2ZW50KSxcbiAgICAgIH07XG5cbiAgICAgIC8vIHNldCB0aGUgbWV0YSBpbmZvcm1hdGlvbiBpbiBsb2dnZXJcbiAgICAgIGN0eC5sb2dnZXIub3B0aW9ucy5tZXRhLnJlcXVlc3RJZCA9IGNvbnRleHQuYXdzUmVxdWVzdElkO1xuICAgICAgLy8gc2V0IHRoZSBkZWJ1ZyBmbGFnIGZvciBsb2dnZXJcbiAgICAgIGN0eC5sb2dnZXIub3B0aW9ucy5kZWJ1ZyA9IHByb2Nlc3MuZW52LkRFQlVHID09PSAndHJ1ZSc7XG5cbiAgICAgIC8vIGxvZyB0aGUgcmVjZWl2ZWQgZXZlbnRcbiAgICAgIGN0eC5sb2dnZXIuZGVidWcoSlNPTi5zdHJpbmdpZnkoZXZlbnQpKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gYXV0aGVudGljYXRlIHRoZSBpbmNvbWluZyByZXF1ZXN0XG4gICAgICAgIGF3YWl0IGN0eC5jb2duaXRvQXV0aC5hdXRoZW50aWNhdGUoKTtcbiAgICAgICAgLy8gaW52b2tlIHRoZSBoYW5kbGVyIGZ1bmN0aW9uIHdpdGggdGhlIGNvbnRleHRcbiAgICAgICAgcmV0dXJuIGF3YWl0IGhhbmRsZXIoY3R4KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgLy8gTm9ybWFsaXNlIHRoZSB0d28gcmVjb2duaXNlZCB0eXBlZC1lcnJvciBzaGFwZXMgdG8gYSBjb21tb25cbiAgICAgICAgLy8geyBlcnJvclR5cGUsIG1lc3NhZ2UsIGVycm9ySW5mbyB9IHNvIHRoZSBnYXRlLCBlbnZlbG9wZSBhbmQgcmV0aHJvd1xuICAgICAgICAvLyBiZWxvdyBhcmUgYSBzaW5nbGUgY29kZSBwYXRoLlxuICAgICAgICAvL1xuICAgICAgICAvLyAtIGFwcHN5bmNFcnJvcnMuQXBwU3luY0Vycm9yIGNhcnJpZXMgaXRzIG93biBHcmFwaFFMIGVycm9yVHlwZSBhbmQgYW5cbiAgICAgICAgLy8gICBvcHRpb25hbCBlcnJvckluZm8sIHdoaWNoIGZsb3cgdGhyb3VnaCB1bmNoYW5nZWQuXG4gICAgICAgIC8vIC0gZXJyb3JzLkh0dHBFcnJvciAodGhlIEhUVFAgYmFzZSB0aHJvd24gYnkgdGhlIHNoYXJlZCBKd3RBdXRob3JpemVyXG4gICAgICAgIC8vICAgdmlhIGFzc2VydEF1dGhlbnRpY2F0ZWQvYXNzZXJ0R3JvdXAvYXNzZXJ0QWRtaW4sIGFuZCBieSByZXNvbHZlclxuICAgICAgICAvLyAgIGNvZGUgZGlyZWN0bHkpIGhhcyBubyBHcmFwaFFMIGVycm9yVHlwZSwgc28gbWFwIGl0cyBzdGF0dXNDb2RlIHdpdGhcbiAgICAgICAgLy8gICBodHRwU3RhdHVzVG9FcnJvclR5cGUuIEh0dHBFcnJvciBjYXJyaWVzIG5vIGVycm9ySW5mbywgc28gZXJyb3JJbmZvXG4gICAgICAgIC8vICAgaXMgdW5kZWZpbmVkLlxuICAgICAgICAvL1xuICAgICAgICAvLyBUaGUgdHdvIGluc3RhbmNlb2YgY2hlY2tzIGFyZSBkaXNqb2ludDogSHR0cEVycm9yIGFuZCBBcHBTeW5jRXJyb3JcbiAgICAgICAgLy8gc2hhcmUgbm8gYW5jZXN0cnksIHNvIGFuIGFwcHN5bmMuRm9yYmlkZGVuRXJyb3IgdGFrZXMgdGhlIEFwcFN5bmNFcnJvclxuICAgICAgICAvLyBicmFuY2ggYW5kIGFuIGVycm9ycy5Gb3JiaWRkZW5FcnJvciB0aGUgSHR0cEVycm9yIGJyYW5jaC4gQW55dGhpbmcgdGhhdFxuICAgICAgICAvLyBpcyBuZWl0aGVyIChwbGFpbiBFcnJvciwgQm9vbSkgbGVhdmVzIHR5cGVkIHVuZGVmaW5lZCBhbmQgcmV0aHJvd3MuXG4gICAgICAgIGxldCB0eXBlZDogeyBlcnJvclR5cGU6IHN0cmluZzsgbWVzc2FnZTogc3RyaW5nOyBlcnJvckluZm8/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+IH0gfCB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIGFwcHN5bmNFcnJvcnMuQXBwU3luY0Vycm9yKSB7XG4gICAgICAgICAgdHlwZWQgPSB7IGVycm9yVHlwZTogZXJyb3IuZXJyb3JUeXBlLCBtZXNzYWdlOiBlcnJvci5tZXNzYWdlLCBlcnJvckluZm86IGVycm9yLmVycm9ySW5mbyB9O1xuICAgICAgICB9IGVsc2UgaWYgKGVycm9yIGluc3RhbmNlb2YgZXJyb3JzLkh0dHBFcnJvcikge1xuICAgICAgICAgIHR5cGVkID0geyBlcnJvclR5cGU6IGh0dHBTdGF0dXNUb0Vycm9yVHlwZShlcnJvci5zdGF0dXNDb2RlKSwgbWVzc2FnZTogZXJyb3IubWVzc2FnZSwgZXJyb3JJbmZvOiB1bmRlZmluZWQgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlZCAmJiBwcm9jZXNzLmVudi5BUFBTWU5DX1RZUEVEX0VSUk9SUyA9PT0gJ3RydWUnKSB7XG4gICAgICAgICAgLy8gVGhlIGVudmVsb3BlLXJldHVybiBpcyBnYXRlZCBvbiBBUFBTWU5DX1RZUEVEX0VSUk9SUyA9PT0gJ3RydWUnLlxuICAgICAgICAgIC8vIEdyYXBoUWxBcGkuYWRkTGFtYmRhUmVzb2x2ZXIgaW5qZWN0cyB0aGF0IGVudiB2YXIgb25seSBvbiBpdHNcbiAgICAgICAgICAvLyB0eXBlZEVycm9yczogdHJ1ZSBwYXRoLCB3aG9zZSBBUFBTWU5DX0pTIHJlc29sdmVyIGhhcyBhIHJlc3BvbnNlXG4gICAgICAgICAgLy8gaGFuZGxlciB0aGF0IHJlYWRzIHRoaXMgZW52ZWxvcGUgYW5kIGNhbGxzXG4gICAgICAgICAgLy8gdXRpbC5lcnJvcihlcnJvck1lc3NhZ2UsIGVycm9yVHlwZSwgbnVsbCwgZXJyb3JJbmZvKSwgdHVybmluZyBpdCBpbnRvXG4gICAgICAgICAgLy8gYSBHcmFwaFFMIGVycm9yIG9uIGEgc3VjY2Vzc2Z1bCBpbnZvY2F0aW9uLiBSZXR1cm5pbmcgKG5vdCB0aHJvd2luZylcbiAgICAgICAgICAvLyBrZWVwcyB0aGUgaW52b2NhdGlvbiBvZmYgdGhlIExhbWJkYSBFcnJvcnMgbWV0cmljLlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gV2hlbiB0aGUgZW52IHZhciBpcyBhYnNlbnQgKHRoZSBkZWZhdWx0IFVOSVQgcmVzb2x2ZXIgcGF0aCwgb3IgYVxuICAgICAgICAgIC8vIGhhbmQtd2lyZWQgaGFuZGxlciB1c2VkIHdpdGhvdXQgR3JhcGhRbEFwaSkgdGhlIHR5cGVkIGVycm9yIGZhbGxzXG4gICAgICAgICAgLy8gdGhyb3VnaCB0byB0aGUgcmV0aHJvdyBiZWxvdywgc28gdGhlIGludm9jYXRpb24gZmFpbHMgbG91ZGx5IGluc3RlYWRcbiAgICAgICAgICAvLyBvZiBzdXJmYWNpbmcgdGhlIGVudmVsb3BlIGFzIGZpZWxkIGRhdGEuIEFueSB2YWx1ZSBvdGhlciB0aGFuIHRoZVxuICAgICAgICAgIC8vIGV4YWN0IHN0cmluZyAndHJ1ZScgbWVhbnMgcmV0aHJvdy4gVGhpcyBpcyB3aHkgYSBkZWZhdWx0IFVOSVRcbiAgICAgICAgICAvLyByZXNvbHZlciB3aG9zZSBoYW5kbGVyIGhpdHMgYW4gYXV0aCBhc3NlcnRpb24gKGFuIEh0dHBFcnJvcikgc3RpbGxcbiAgICAgICAgICAvLyBmYWlscyBsb3VkbHkgdW5sZXNzIHR5cGVkRXJyb3JzIGlzIGFjdGl2ZS5cbiAgICAgICAgICAvL1xuICAgICAgICAgIC8vIF9fYXBwU3luY0Vycm9yIGlzIGEgcmVzZXJ2ZWQgc2VudGluZWwga2V5IHRoZSByZXNvbHZlciByZXNwb25zZVxuICAgICAgICAgIC8vIGhhbmRsZXIga2V5cyBvbiB0byByZWNvZ25pc2UgdGhpcyBlbnZlbG9wZS4gQnJhbmNoaW5nIG9uIHRoZSBzZW50aW5lbFxuICAgICAgICAgIC8vIChyYXRoZXIgdGhhbiBvbiBhIGJhcmUgZXJyb3JNZXNzYWdlKSBtZWFucyBhIGxlZ2l0aW1hdGUgcmVzb2x2ZXIgcmVzdWx0XG4gICAgICAgICAgLy8gdGhhdCBtZXJlbHkgY29udGFpbnMgYW4gZXJyb3JNZXNzYWdlIGZpZWxkIGlzIG5vdCBtaXNjbGFzc2lmaWVkIGFzIGFcbiAgICAgICAgICAvLyB0eXBlZCBlcnJvci5cbiAgICAgICAgICBjdHgubG9nZ2VyLndhcm4odHlwZWQubWVzc2FnZSwgeyBlcnJvclR5cGU6IHR5cGVkLmVycm9yVHlwZSwgZXJyb3JJbmZvOiB0eXBlZC5lcnJvckluZm8gfSk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIF9fYXBwU3luY0Vycm9yOiB0cnVlLFxuICAgICAgICAgICAgZGF0YTogbnVsbCxcbiAgICAgICAgICAgIGVycm9yVHlwZTogdHlwZWQuZXJyb3JUeXBlLFxuICAgICAgICAgICAgZXJyb3JNZXNzYWdlOiB0eXBlZC5tZXNzYWdlLFxuICAgICAgICAgICAgZXJyb3JJbmZvOiB0eXBlZC5lcnJvckluZm8sXG4gICAgICAgICAgfSBhcyB1bmtub3duIGFzIFI7XG4gICAgICAgIH1cbiAgICAgICAgLy8gbG9nIHRoZSBlcnJvciBhbmQgdGhyb3cgaXQgYWdhaW5cbiAgICAgICAgY3R4LmxvZ2dlci5lcnJvcihlcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgIH07XG4gIH07XG5cbiJdfQ==
package/llm.md CHANGED
@@ -182,6 +182,37 @@ export const handler = createAppSyncHandler<GetItemsQuery, GetItemsResult>(async
182
182
  });
183
183
  ```
184
184
 
185
+ AppSync resolvers can throw typed errors from the `errors.appsync` namespace. `createAppSyncHandler` catches them and logs at `warn`. Whether it returns a `{ data, errorType, errorMessage, errorInfo }` envelope or rethrows is gated on the `APPSYNC_TYPED_ERRORS` environment variable. When `APPSYNC_TYPED_ERRORS === 'true'` the handler returns the envelope so the invocation stays off the Lambda Errors metric. Otherwise it rethrows the typed error, logging at `error`, so the invocation fails. A plain `Error` always fails the invocation regardless of the flag.
186
+
187
+ ```typescript
188
+ import { createAppSyncHandler, errors } from 'cdk-serverless/lambda';
189
+
190
+ export const handler = createAppSyncHandler<GetItemQuery, Item>(async (ctx) => {
191
+ const item = await getItem(ctx.arguments.id);
192
+
193
+ if (!item) {
194
+ throw new errors.appsync.NotFoundError('Item not found');
195
+ }
196
+
197
+ return item;
198
+ });
199
+ ```
200
+
201
+ HTTP errors from the shared authorizer are translated the same way. The shared `JwtAuthorizer` base throws `errors.UnauthenticatedError` (401) and `errors.ForbiddenError` (403) from `assertAuthenticated`/`assertGroup`/`assertAdmin`, and `AppSyncCognitoAuthorizer` extends that base, so these reach `createAppSyncHandler`'s catch. `createAppSyncHandler` treats any `errors.HttpError` like a typed error and maps its `statusCode` to an `errorType`: 400 `BadRequest`, 401 `Unauthorized`, 403 `Forbidden`, 404 `NotFound`, any other status `Error`. The mapped error goes through the same `APPSYNC_TYPED_ERRORS` gate and `{ __appSyncError: true, ... }` envelope as `errors.appsync.*` (with `errorInfo` undefined, since `HttpError` carries none). `src/lambda/auth.ts` and the HTTP handler `createHttpHandler` are unchanged. The same rethrow-when-not-activated rule applies, so a default UNIT resolver whose handler hits an auth assertion still fails loudly unless `typedErrors` is active.
202
+
203
+ The envelope only becomes a GraphQL error when the resolver is wired via `GraphQlApi.addLambdaResolver` and the API opts in with `typedErrors: true`. On that path the method creates an `APPSYNC_JS` pipeline resolver whose response handler reads the envelope and calls `util.error(errorMessage, errorType, null, errorInfo)` (and `util.appendError` for invoke-level errors), turning the typed error into a GraphQL error with the matching `errorType` and `errorInfo`. Without `typedErrors: true`, `addLambdaResolver` creates a plain direct-Lambda UNIT resolver with no response handler, so the envelope is surfaced as the field's data instead. If you build the resolver yourself, replicate that response handler.
204
+
205
+ The response handler recognises the envelope by a reserved `__appSyncError` sentinel key that `createAppSyncHandler` stamps, not by the presence of an `errorMessage` field. A resolver whose real return type happens to include an `errorMessage` field is therefore passed through unchanged.
206
+
207
+ Opting in with `typedErrors`: by default `addLambdaResolver` synthesizes a plain direct-Lambda UNIT resolver (the pre-#385 shape), so upgrading consumers who do not opt in see no resolver topology change and no `cdk diff` surprise. Set `typedErrors: true` on the `GraphQlApi` to get the typed `errors.appsync.*` behavior. With the flag enabled, each Lambda-backed field gains a new `AWS::AppSync::FunctionConfiguration` (`LambdaFn${type}.${field}`), and the resolver flips from a `dataSource` UNIT resolver to a `pipelineConfig` + `code` PIPELINE resolver with the response handler described above. The data source and resolver logical IDs are unchanged, so the resolver updates in place rather than being replaced, while the new per-field function resource is additive. The flag applies to all Lambda resolvers on the API, so run `cdk diff` after enabling it to review the topology change.
208
+
209
+ `APPSYNC_TYPED_ERRORS` is the coupling mechanism between the handler and the pipeline. `createAppSyncHandler` returns the `{ __appSyncError: true, ... }` sentinel envelope only when `APPSYNC_TYPED_ERRORS === 'true'` is set in the Lambda environment, and rethrows the `errors.appsync.*` error otherwise. `GraphQlApi.addLambdaResolver` injects `APPSYNC_TYPED_ERRORS=true` automatically on the `typedErrors: true` path, the same path that carries the response handler to translate the envelope. On the default UNIT path the flag is left unset, so a handler that throws an `errors.appsync.*` error fails the invocation loudly (rethrow) instead of returning a broken envelope as field data. If you wire `createAppSyncHandler` yourself without `GraphQlApi`, set `APPSYNC_TYPED_ERRORS=true` on the Lambda yourself to get envelope behavior and replicate the response handler. Without it, typed errors rethrow.
210
+
211
+ Two classes share the short names `ForbiddenError` and `NotFoundError`, so pick the namespace deliberately:
212
+
213
+ - `errors.ForbiddenError` / `errors.NotFoundError` are HTTP errors (HTTP 403 / 404) for `createHttpHandler`. They carry a `statusCode`.
214
+ - `errors.appsync.ForbiddenError` / `errors.appsync.NotFoundError` are AppSync errors for `createAppSyncHandler`. They carry a GraphQL `errorType` (`'Forbidden'` / `'NotFound'`), not an HTTP status code.
215
+
185
216
  #### Error Handling
186
217
 
187
218
  ```typescript
package/package.json CHANGED
@@ -7,6 +7,7 @@
7
7
  "scripts": {
8
8
  "build": "projen build",
9
9
  "bump": "projen bump",
10
+ "bump:releasable-commits": "projen bump:releasable-commits",
10
11
  "clobber": "projen clobber",
11
12
  "compile": "projen compile",
12
13
  "default": "projen default",
@@ -32,13 +33,13 @@
32
33
  "organization": true
33
34
  },
34
35
  "devDependencies": {
35
- "@aws-sdk/client-cognito-identity-provider": "3.1029.0",
36
- "@aws-sdk/client-dynamodb": "3.1029.0",
37
- "@aws-sdk/client-s3": "3.1029.0",
38
- "@aws-sdk/lib-dynamodb": "3.1029.0",
36
+ "@aws-sdk/client-cognito-identity-provider": "3.1150.0",
37
+ "@aws-sdk/client-dynamodb": "3.1150.0",
38
+ "@aws-sdk/client-s3": "3.1150.0",
39
+ "@aws-sdk/lib-dynamodb": "3.1150.0",
39
40
  "@hapi/boom": "^10.0.1",
40
41
  "@stylistic/eslint-plugin": "^2",
41
- "@types/jest": "^29.5.14",
42
+ "@types/jest": "^30",
42
43
  "@types/js-yaml": "^4.0.9",
43
44
  "@types/jsonwebtoken": "^9.0.10",
44
45
  "@types/jwk-to-pem": "^2.0.3",
@@ -46,37 +47,37 @@
46
47
  "@types/node": "^18",
47
48
  "@typescript-eslint/eslint-plugin": "^8",
48
49
  "@typescript-eslint/parser": "^8",
49
- "aws-cdk-lib": "2.248.0",
50
- "commit-and-tag-version": "^12",
50
+ "aws-cdk-lib": "2.273.0",
51
+ "commit-and-tag-version": "^13",
51
52
  "constructs": "^10.0.0",
52
53
  "dynamodb-onetable": "2.7.7",
53
54
  "eslint": "^9",
54
- "eslint-import-resolver-typescript": "^4.4.4",
55
+ "eslint-import-resolver-typescript": "^4.4.5",
55
56
  "eslint-plugin-import": "^2.32.0",
56
- "jest": "^29.7.0",
57
- "jest-junit": "^16",
57
+ "jest": "^30",
58
+ "jest-junit": "^17",
58
59
  "openapi-typescript": "7.13.0",
59
- "projen": "0.99.47",
60
- "ts-jest": "^29.4.9",
60
+ "projen": "0.104.5",
61
+ "ts-jest": "^29",
61
62
  "ts-node": "^10.9.2",
62
- "typedoc": "0.28.19",
63
+ "typedoc": "0.28.20",
63
64
  "typescript": "^5.9.3"
64
65
  },
65
66
  "peerDependencies": {
66
- "@aws-sdk/client-cognito-identity-provider": "^3.1014.0",
67
- "@aws-sdk/client-dynamodb": "^3.1014.0",
68
- "@aws-sdk/client-s3": "^3.1014.0",
69
- "@aws-sdk/lib-dynamodb": "^3.1014.0",
70
- "aws-cdk-lib": ">=2.248.0 <3.0.0",
67
+ "@aws-sdk/client-cognito-identity-provider": "^3.1150.0",
68
+ "@aws-sdk/client-dynamodb": "^3.1150.0",
69
+ "@aws-sdk/client-s3": "^3.1150.0",
70
+ "@aws-sdk/lib-dynamodb": "^3.1150.0",
71
+ "aws-cdk-lib": ">=2.273.0 <3.0.0",
71
72
  "dynamodb-onetable": "2.7.7",
72
73
  "openapi-typescript": "^7.13.0",
73
- "projen": ">=0.99.47 <1.0.0"
74
+ "projen": ">=0.104.5 <1.0.0"
74
75
  },
75
76
  "dependencies": {
76
- "@types/aws-lambda": "^8.10.161",
77
+ "@types/aws-lambda": "^8.10.164",
77
78
  "constructs": "^10.5.1",
78
- "date-fns": "^4.1.0",
79
- "js-yaml": "^4.1.1",
79
+ "date-fns": "^4.4.0",
80
+ "js-yaml": "^4.3.2",
80
81
  "jsonwebtoken": "^9.0.3",
81
82
  "jwk-to-pem": "^2.0.7",
82
83
  "lambda-log": "^3.1.0"
@@ -96,10 +97,11 @@
96
97
  },
97
98
  "main": "lib/index.js",
98
99
  "license": "Apache-2.0",
100
+ "stability": "experimental",
99
101
  "publishConfig": {
100
102
  "access": "public"
101
103
  },
102
- "version": "3.3.2",
104
+ "version": "3.4.0",
103
105
  "jest": {
104
106
  "coverageProvider": "v8",
105
107
  "testMatch": [
@@ -140,7 +142,7 @@
140
142
  "^.+\\.[t]sx?$": [
141
143
  "ts-jest",
142
144
  {
143
- "tsconfig": "tsconfig.dev.json"
145
+ "tsconfig": "test/tsconfig.json"
144
146
  }
145
147
  ]
146
148
  }