@idea-ionic/auth 8.5.13 → 8.6.1

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 (37) hide show
  1. package/fesm2022/idea-ionic-auth.mjs +52 -52
  2. package/fesm2022/idea-ionic-auth.mjs.map +1 -1
  3. package/index.d.ts +358 -3
  4. package/package.json +13 -15
  5. package/esm2022/idea-ionic-auth.mjs +0 -5
  6. package/esm2022/public-api.mjs +0 -15
  7. package/esm2022/src/auth.routes.mjs +0 -22
  8. package/esm2022/src/auth.service.mjs +0 -521
  9. package/esm2022/src/commonPasswords.model.mjs +0 -1003
  10. package/esm2022/src/confirmPassword.page.mjs +0 -309
  11. package/esm2022/src/forgotPassword.page.mjs +0 -178
  12. package/esm2022/src/mfaChallenge.page.mjs +0 -163
  13. package/esm2022/src/newPassword.page.mjs +0 -210
  14. package/esm2022/src/okta.page.mjs +0 -150
  15. package/esm2022/src/passwordPolicy.component.mjs +0 -80
  16. package/esm2022/src/resendLink.page.mjs +0 -176
  17. package/esm2022/src/setupMFA/setupMFAButton.component.mjs +0 -60
  18. package/esm2022/src/setupMFA/setupMFAModal.component.mjs +0 -176
  19. package/esm2022/src/setupMFA.page.mjs +0 -83
  20. package/esm2022/src/signIn.page.mjs +0 -498
  21. package/esm2022/src/signUp.page.mjs +0 -376
  22. package/public-api.d.ts +0 -14
  23. package/src/auth.routes.d.ts +0 -2
  24. package/src/auth.service.d.ts +0 -152
  25. package/src/commonPasswords.model.d.ts +0 -1
  26. package/src/confirmPassword.page.d.ts +0 -26
  27. package/src/forgotPassword.page.d.ts +0 -13
  28. package/src/mfaChallenge.page.d.ts +0 -16
  29. package/src/newPassword.page.d.ts +0 -22
  30. package/src/okta.page.d.ts +0 -20
  31. package/src/passwordPolicy.component.d.ts +0 -8
  32. package/src/resendLink.page.d.ts +0 -14
  33. package/src/setupMFA/setupMFAButton.component.d.ts +0 -23
  34. package/src/setupMFA/setupMFAModal.component.d.ts +0 -16
  35. package/src/setupMFA.page.d.ts +0 -8
  36. package/src/signIn.page.d.ts +0 -36
  37. package/src/signUp.page.d.ts +0 -26
@@ -1,521 +0,0 @@
1
- import { Injectable, inject } from '@angular/core';
2
- import { AuthenticationDetails, CognitoUser, CognitoUserAttribute, CognitoUserPool, CognitoRefreshToken } from 'amazon-cognito-identity-js';
3
- import { IDEAEnvironment, IDEAStorageService, IDEATranslationsService } from '@idea-ionic/common';
4
- import { COMMON_PASSWORDS_TOP_1000 } from './commonPasswords.model';
5
- import * as i0 from "@angular/core";
6
- /**
7
- * Cognito wrapper to manage the authentication flow.
8
- *
9
- * Note: in IDEA's Cognito users pools, the email is an alias of the username.
10
- */
11
- export class IDEAAuthService {
12
- constructor() {
13
- this._env = inject(IDEAEnvironment);
14
- this._translate = inject(IDEATranslationsService);
15
- this._storage = inject(IDEAStorageService);
16
- this.deviceKeyAttribute = 'custom:'.concat(this._env.idea.project);
17
- this.userPool = new CognitoUserPool({
18
- UserPoolId: this._env.aws.cognito.userPoolId,
19
- ClientId: this._env.aws.cognito.userPoolClientId
20
- });
21
- this.mfaProjectName = this._env.idea.auth.title || this._env.idea.project;
22
- this.passwordPolicy = this._env.idea.auth.passwordPolicy;
23
- }
24
- /**
25
- * Prepare the necessary structure to get authorized in Cognito.
26
- */
27
- prepareAuthDetails(username, pwd) {
28
- return new AuthenticationDetails({ Username: username, Password: pwd });
29
- }
30
- /**
31
- * Prepare the necessary structure to identify a Cognito user.
32
- */
33
- prepareCognitoUser(username) {
34
- return new CognitoUser({ Username: username, Pool: this.userPool });
35
- }
36
- /**
37
- * Prepare a user attribute (they are all strings) in Cognito's format.
38
- */
39
- prepareUserAttribute(name, value) {
40
- return new CognitoUserAttribute({ Name: name, Value: value });
41
- }
42
- /**
43
- * Perform a login through username and password.
44
- */
45
- login(username, password) {
46
- return new Promise((resolve, reject) => {
47
- const user = this.prepareCognitoUser(username);
48
- user.authenticateUser(this.prepareAuthDetails(username, password), {
49
- onSuccess: () => resolve(this._env.idea.auth.forceLoginWithMFA ? LoginOutcomeActions.MFA_SETUP : LoginOutcomeActions.NONE),
50
- onFailure: (err) => reject(err),
51
- newPasswordRequired: () => {
52
- this.challengeUsername = username;
53
- this.challengePassword = password;
54
- resolve(LoginOutcomeActions.NEW_PASSWORD);
55
- },
56
- totpRequired: () => {
57
- this.challengeUsername = username;
58
- this.challengePassword = password;
59
- resolve(LoginOutcomeActions.MFA_CHALLENGE);
60
- }
61
- });
62
- });
63
- }
64
- /**
65
- * Complete the new password flow in the authentication.
66
- */
67
- confirmNewPassword(newPassword) {
68
- return new Promise((resolve, reject) => {
69
- const user = this.prepareCognitoUser(this.challengeUsername);
70
- user.authenticateUser(this.prepareAuthDetails(this.challengeUsername, this.challengePassword), {
71
- onSuccess: () => resolve(),
72
- onFailure: (err) => reject(err),
73
- newPasswordRequired: () => user.completeNewPasswordChallenge(newPassword, {}, {
74
- onSuccess: () => {
75
- this.challengeUsername = null;
76
- this.challengePassword = null;
77
- resolve();
78
- },
79
- onFailure: (err) => reject(err)
80
- })
81
- });
82
- });
83
- }
84
- /**
85
- * Complete the MFA challenge flow in the authentication.
86
- */
87
- completeMFAChallenge(otpCode) {
88
- return new Promise((resolve, reject) => {
89
- const user = this.prepareCognitoUser(this.challengeUsername);
90
- user.authenticateUser(this.prepareAuthDetails(this.challengeUsername, this.challengePassword), {
91
- onSuccess: () => resolve(),
92
- onFailure: (err) => reject(err),
93
- totpRequired: (challengeName) => user.sendMFACode(otpCode, {
94
- onSuccess: () => {
95
- this.challengeUsername = null;
96
- this.challengePassword = null;
97
- resolve();
98
- },
99
- onFailure: err => reject(err)
100
- }, challengeName)
101
- });
102
- });
103
- }
104
- /**
105
- * Register a new user a set its default attributes.
106
- */
107
- register(username, password, attributes) {
108
- attributes = attributes || {};
109
- return new Promise((resolve, reject) => {
110
- // add attributes like the email address and the fullname
111
- const attrs = [];
112
- for (const prop in attributes)
113
- if (attributes[prop])
114
- attrs.push(this.prepareUserAttribute(prop, attributes[prop]));
115
- // add the email, which is equal to the username for most of our Pools
116
- if (!attributes.email)
117
- attrs.push(this.prepareUserAttribute('email', username));
118
- // register the new user to the pool
119
- this.userPool.signUp(username, password, attrs, null, (err, res) => {
120
- if (err)
121
- return reject(err);
122
- this.newAccountJustRegistered = username;
123
- resolve(res.user);
124
- });
125
- });
126
- }
127
- /**
128
- * In case a new account has just been registered, return the username.
129
- */
130
- getNewAccountJustRegistered() {
131
- return this.newAccountJustRegistered;
132
- }
133
- /**
134
- * Confirm a new registration through the confirmation code sent by Cognito.
135
- */
136
- confirmRegistration(username, code) {
137
- return new Promise((resolve, reject) => {
138
- this.prepareCognitoUser(username).confirmRegistration(code, true, (err) => err ? reject(err) : resolve());
139
- });
140
- }
141
- /**
142
- * Send again a confirmation code for a new registration.
143
- */
144
- resendConfirmationCode(username) {
145
- return new Promise((resolve, reject) => {
146
- this.prepareCognitoUser(username).resendConfirmationCode((err) => (err ? reject(err) : resolve()));
147
- });
148
- }
149
- /**
150
- * Logout the currently signed-in user.
151
- */
152
- logout(options) {
153
- options = Object.assign({ global: false }, options);
154
- return new Promise((resolve, reject) => {
155
- // remove the refresh token previosly saved
156
- this._storage.remove('AuthRefreshToken').then(() =>
157
- // remove the optional auth details
158
- this._storage.remove('AuthUserDetails').then(() => {
159
- // get the user and the session
160
- const user = this.userPool.getCurrentUser();
161
- user.getSession(async (err) => {
162
- // if the session is active, run the online sign-out; otherwise, only the local data has been deleted
163
- if (err)
164
- return resolve();
165
- // if a reference to the device was saved, forget it
166
- if (this._env.idea.auth.singleSimultaneousSession)
167
- await this.setCurrentDeviceForProject(null);
168
- // sign-out from the pool (terminate the current session or all the sessions)
169
- if (options.global)
170
- user.globalSignOut({ onSuccess: () => resolve(), onFailure: err => reject(err) });
171
- else {
172
- user.signOut();
173
- resolve();
174
- }
175
- });
176
- }));
177
- });
178
- }
179
- /**
180
- * Send a password reset request.
181
- */
182
- forgotPassword(username) {
183
- return new Promise((resolve, reject) => {
184
- this.prepareCognitoUser(username).forgotPassword({
185
- onSuccess: () => resolve(),
186
- onFailure: (err) => reject(err)
187
- });
188
- });
189
- }
190
- /**
191
- * Confirm a new password after a password reset request.
192
- */
193
- confirmPassword(username, code, newPwd) {
194
- return new Promise((resolve, reject) => {
195
- this.prepareCognitoUser(username).confirmPassword(code, newPwd, {
196
- onSuccess: () => resolve(),
197
- onFailure: (err) => reject(err)
198
- });
199
- });
200
- }
201
- /**
202
- * Gets the URL for enabling MFA. This URL can be used to generate a QR Code to read with an authenticator app.
203
- */
204
- getURLForEnablingMFA() {
205
- return new Promise((resolve, reject) => {
206
- const user = this.userPool.getCurrentUser();
207
- if (!user)
208
- return reject();
209
- user.getSession((err) => {
210
- if (err)
211
- return reject(err);
212
- user.associateSoftwareToken({
213
- associateSecretCode: (secretCode) => resolve(`otpauth://totp/${encodeURI(this.mfaProjectName)}?secret=${secretCode}`),
214
- onFailure: (err) => reject(err)
215
- });
216
- });
217
- });
218
- }
219
- /**
220
- * Check whether the user has MFA enabled.
221
- */
222
- checkIfUserHasMFAEnabled(bypassCache = false) {
223
- return new Promise((resolve, reject) => {
224
- const user = this.userPool.getCurrentUser();
225
- if (!user)
226
- return reject();
227
- user.getSession((err) => {
228
- if (err)
229
- return reject(err);
230
- user.getUserData((err, data) => {
231
- if (err)
232
- return reject(err);
233
- const isMFAEnabled = !!(data.UserMFASettingList && data.UserMFASettingList.includes('SOFTWARE_TOKEN_MFA'));
234
- resolve(isMFAEnabled);
235
- }, { bypassCache });
236
- });
237
- });
238
- }
239
- /**
240
- * Configure a MFA device for the user.
241
- */
242
- setMFADevice(otp, mfaDeviceName, enabled = true, preferred = true) {
243
- return new Promise((resolve, reject) => {
244
- const user = this.userPool.getCurrentUser();
245
- if (!user)
246
- return reject();
247
- user.getSession((err) => {
248
- if (err)
249
- return reject(err);
250
- user.verifySoftwareToken(otp, mfaDeviceName, {
251
- onSuccess: () => user.setUserMfaPreference(null, { Enabled: enabled, PreferredMfa: preferred }, (err) => err ? reject(err) : resolve()),
252
- onFailure: (err) => reject(err)
253
- });
254
- });
255
- });
256
- }
257
- /**
258
- * Enable a new MFA device for the user by inserting an OTP code generated by it.
259
- */
260
- enableMFA(otp, mfaDeviceName = 'default') {
261
- return this.setMFADevice(otp, mfaDeviceName, true, true);
262
- }
263
- /**
264
- * Disable MFA for a user by inserting an OTP code generated by it.
265
- */
266
- disableMFA(otp, mfaDeviceName = 'default') {
267
- return this.setMFADevice(otp, mfaDeviceName, false, false);
268
- }
269
- /**
270
- * Check if a user is currently authenticated.
271
- * @param offlineAllowed if set and if offline, skip authentication and retrieve data locally
272
- * @param getFreshIdTokenOnExp cb function to execute when the idToken is refreshed
273
- */
274
- isAuthenticated(offlineAllowed, getFreshIdTokenOnExp) {
275
- return new Promise((resolve, reject) => {
276
- if (offlineAllowed && !navigator.onLine) {
277
- this._storage.get('AuthUserDetails').then(userDetails => resolve({ idToken: null, userDetails }));
278
- // re-execute the method when back online, so that you can retrieve a token to make requests
279
- window.addEventListener('online', () => this.isAuthenticated(true, getFreshIdTokenOnExp)
280
- // set the new token as if it was refreshed
281
- .then(result => getFreshIdTokenOnExp(result.idToken)));
282
- }
283
- else {
284
- const user = this.userPool.getCurrentUser();
285
- if (!user)
286
- return reject();
287
- user.getSession((err, session) => {
288
- if (err)
289
- return reject(err);
290
- user.getUserData((err, data) => {
291
- if (err)
292
- return reject(err);
293
- const isMFAEnabled = !!(data.UserMFASettingList && data.UserMFASettingList.includes('SOFTWARE_TOKEN_MFA'));
294
- if (!isMFAEnabled && this._env.idea.auth.forceLoginWithMFA)
295
- return reject(new Error(LoginOutcomeActions.MFA_SETUP));
296
- user.getUserAttributes((e, attributes) => {
297
- if (e)
298
- return reject(e);
299
- // remap user attributes
300
- const userDetails = {};
301
- attributes.forEach((a) => (userDetails[a.getName()] = a.getValue()));
302
- // add the user's groups to the attributes
303
- const sessionInfo = session.getAccessToken().decodePayload();
304
- const groups = sessionInfo['cognito:groups'] || [];
305
- userDetails['groups'] = groups;
306
- // run some checks considering the user's groups and devices (based on the project's configuration)
307
- this.runPostAuthChecks(userDetails, err => {
308
- // in case some check failed, reject the authorisation flow
309
- if (err)
310
- return reject(err);
311
- // (async) save the refresh token so it can be accessed by other procedures
312
- this._storage.set('AuthRefreshToken', session.getRefreshToken().getToken());
313
- // set a timer to manage the autorefresh of the idToken (through the refreshToken)
314
- setTimeout(() => this.refreshSession(user, session.getRefreshToken().getToken(), getFreshIdTokenOnExp), 15 * 60 * 1000); // every 15 minutes
315
- // (async) if offlineAllowed, save data locally, to use it next time we'll be offline
316
- if (offlineAllowed)
317
- this._storage.set('AuthUserDetails', userDetails);
318
- // return the idToken (to use with API)
319
- resolve({ idToken: session.getIdToken().getJwtToken(), userDetails });
320
- });
321
- });
322
- }, { bypassCache: true });
323
- });
324
- }
325
- });
326
- }
327
- /**
328
- * Helper to refresh the session every N minutes.
329
- */
330
- refreshSession(user, refreshToken, callback) {
331
- user.refreshSession(new CognitoRefreshToken({ RefreshToken: refreshToken }), (err, session) => {
332
- if (err) {
333
- // try again in 1 minute
334
- setTimeout(() => this.refreshSession(user, refreshToken, callback), 1 * 60 * 1000);
335
- }
336
- else {
337
- // (async) save the refresh token so it can be accessed by other procedures
338
- this._storage.set('AuthRefreshToken', session.getRefreshToken().getToken());
339
- // repeat every 15 minutes
340
- setTimeout(() => this.refreshSession(user, session.getRefreshToken().getToken(), callback), 15 * 60 * 1000);
341
- // run the callback action, if set
342
- if (callback)
343
- callback(session.getIdToken().getJwtToken());
344
- }
345
- });
346
- }
347
- /**
348
- * Run some post-auth checks, based on the users groups and on the app's configuration:
349
- * - users in the Cognito's "admins" grup skip all the following rules.
350
- * - users in the Cognito's "robots" group can't sign-into front-ends (they serve only back-end purposes).
351
- * - if `env.idea.auth.singleSimultaneousSession` is on, make sure there is only one active session per user.
352
- */
353
- runPostAuthChecks(userDetails, callback) {
354
- const groups = userDetails['groups'];
355
- // skip checks if the user is in the "admins" group
356
- const isAdmin = groups.some(x => x === 'admins');
357
- if (isAdmin)
358
- return callback();
359
- // users in the "robots" group can't sign-into front-ends (they serve only back-end purposes)
360
- const isRobot = groups.some(x => x === 'robots');
361
- if (isRobot)
362
- return callback(new Error('ROBOT_USER'));
363
- // in case the project limits each account to only one simultaneous session, run a check
364
- if (this._env.idea.auth.singleSimultaneousSession)
365
- return this.checkForSimultaneousSessions(userDetails, callback);
366
- // otherwise, we're done
367
- callback();
368
- }
369
- /**
370
- * Check whether the user signed-into multiple devices.
371
- */
372
- async checkForSimultaneousSessions(userDetails, callback) {
373
- // get or create a key for the current device (~random)
374
- let currentDeviceKey = await this._storage.get('AuthDeviceKey');
375
- if (!currentDeviceKey) {
376
- const randomKey = Math.random().toString(36).substring(10);
377
- currentDeviceKey = randomKey.concat(String(Date.now()));
378
- await this._storage.set('AuthDeviceKey', currentDeviceKey);
379
- }
380
- // check whether the last device to sign-into this project (if any) is the current one
381
- const lastDeviceToSignIntoThisProject = userDetails[this.deviceKeyAttribute];
382
- // if it's the first user's device to sign-in, save the reference in Cognito and resolve
383
- if (!lastDeviceToSignIntoThisProject) {
384
- this.setCurrentDeviceForProject(currentDeviceKey)
385
- .then(() => callback())
386
- .catch(() => callback(new Error('CANT_SET_DEVICE')));
387
- // if the device didn't change, resolve
388
- }
389
- else if (lastDeviceToSignIntoThisProject === currentDeviceKey)
390
- callback();
391
- // othwerwise, report there is more than one simultaneous session
392
- else
393
- callback(new Error('SIMULTANEOUS_SESSION'));
394
- }
395
- /**
396
- * Set (or reset) the current user's device (by key) in the current project (stored in Cognito).
397
- */
398
- setCurrentDeviceForProject(deviceKey) {
399
- const attributes = {};
400
- // note: an empty string will remove the attribute from Cognito
401
- attributes[this.deviceKeyAttribute] = deviceKey || '';
402
- return this.updateUserAttributes(attributes);
403
- }
404
- /**
405
- * Update the currently logged in user's attributes.
406
- */
407
- updateUserAttributes(attributes) {
408
- return new Promise((resolve, reject) => {
409
- // prepare the attributes we want to change
410
- const attrs = new Array();
411
- for (const prop in attributes)
412
- if (attributes[prop] !== undefined)
413
- attrs.push(this.prepareUserAttribute(prop, attributes[prop]));
414
- const user = this.userPool.getCurrentUser();
415
- if (!user)
416
- return reject();
417
- // we need to get the session before to make changes
418
- user.getSession((err) => {
419
- if (err)
420
- reject(err);
421
- else
422
- user.updateAttributes(attrs, (e) => (e ? reject(e) : resolve()));
423
- });
424
- });
425
- }
426
- /**
427
- * Validate the password against the policy set in the environments configuration.
428
- * In case there are errors, they are returned as an array of strings.
429
- */
430
- validatePasswordAgainstPolicy(password) {
431
- const errors = [];
432
- if (password?.trim().length < this.passwordPolicy.minLength)
433
- errors.push('MIN_LENGTH');
434
- if (this.passwordPolicy.requireDigits && !/\d/.test(password))
435
- errors.push('REQUIRE_DIGITS');
436
- if (this.passwordPolicy.requireLowercase && !/[a-z]/.test(password))
437
- errors.push('REQUIRE_LOWERCASE');
438
- if (this.passwordPolicy.requireSymbols && !/[\^\$\*\.\_\~\`\+\=@\!\?\>\<\:\;\\\,\#\%\&]/.test(password))
439
- errors.push('REQUIRE_SYMBOLS');
440
- if (this.passwordPolicy.requireUppercase && !/[A-Z]/.test(password))
441
- errors.push('REQUIRE_UPPERCASE');
442
- return errors;
443
- }
444
- /**
445
- * Validate the password against offline and online databases, to avoid common and exploited passwords.
446
- */
447
- async validatePasswordAgainstDatabases(password, customStringsToAvoid) {
448
- const errors = [];
449
- let pwd = (password || '').trim().toLowerCase();
450
- const pwdContains = (str) => pwd.includes((str || '').trim().toLowerCase());
451
- const projectReferencesToAvoid = [
452
- this._env.idea.project,
453
- this._env.idea.auth.title,
454
- this._translate._('COMMON.APP_NAME')
455
- ];
456
- if (projectReferencesToAvoid.some(x => pwdContains(x)))
457
- errors.push('COMMON_PASSWORD_PROJECT');
458
- if (customStringsToAvoid && customStringsToAvoid.some(x => pwdContains(x)))
459
- errors.push('COMMON_PASSWORD_CUSTOM');
460
- if (COMMON_PASSWORDS_TOP_1000.some(x => pwdContains(x)))
461
- errors.push('COMMON_PASSWORD_INTERNAL');
462
- if (errors.length === 0) {
463
- const pwdSHA1 = await SHA1(password);
464
- if (pwdSHA1) {
465
- const res = await fetch('https://api.pwnedpasswords.com/range/'.concat(pwdSHA1.slice(0, 5)));
466
- if (res.status === 200) {
467
- const pwnedPasswordsRawSuffixes = await res.text();
468
- if (pwnedPasswordsRawSuffixes.includes(pwdSHA1.slice(5)))
469
- errors.push('COMMON_PASSWORD_EXTERNAL');
470
- }
471
- }
472
- }
473
- return errors;
474
- }
475
- /**
476
- * Get a complete password policy pattern, based on the environments configuration, to use on password input fields.
477
- * Note: some of the symbols couldn't be included because unsupported by the input[pattern] attribute.
478
- */
479
- getPasswordPolicyPatternForInput() {
480
- let pattern = '';
481
- if (this.passwordPolicy.requireDigits)
482
- pattern += `(?=.*[0-9])`;
483
- if (this.passwordPolicy.requireLowercase)
484
- pattern += `(?=.*[a-z])`;
485
- if (this.passwordPolicy.requireSymbols)
486
- pattern += `(?=.*[\^\$\*\.\_\~\`\+\=@\!\?\>\<\:\;\\\,\#\%\&])`;
487
- if (this.passwordPolicy.requireUppercase)
488
- pattern += `(?=.*[A-Z])`;
489
- pattern += `.{${this.passwordPolicy.minLength},}`;
490
- return pattern;
491
- }
492
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: IDEAAuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
493
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: IDEAAuthService, providedIn: 'root' }); }
494
- }
495
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: IDEAAuthService, decorators: [{
496
- type: Injectable,
497
- args: [{ providedIn: 'root' }]
498
- }], ctorParameters: () => [] });
499
- /**
500
- * The possible actions following a successful login.
501
- */
502
- export var LoginOutcomeActions;
503
- (function (LoginOutcomeActions) {
504
- LoginOutcomeActions["NONE"] = "none";
505
- LoginOutcomeActions["NEW_PASSWORD"] = "newPassword";
506
- LoginOutcomeActions["MFA_CHALLENGE"] = "mfaChallenge";
507
- LoginOutcomeActions["MFA_SETUP"] = "mfaSetup";
508
- })(LoginOutcomeActions || (LoginOutcomeActions = {}));
509
- /**
510
- * Get the SHA1 hex uppercase hash of a string, using web crypto.
511
- */
512
- const SHA1 = async (str) => {
513
- if (!window.crypto)
514
- return null;
515
- const msgUint8 = new TextEncoder().encode(str);
516
- const hashBuffer = await window.crypto.subtle.digest('SHA-1', msgUint8);
517
- const hashArray = Array.from(new Uint8Array(hashBuffer));
518
- const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
519
- return hashHex.toUpperCase();
520
- };
521
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vbW9kdWxlcy9hdXRoL3NyYy9hdXRoLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUNMLHFCQUFxQixFQUNyQixXQUFXLEVBQ1gsb0JBQW9CLEVBQ3BCLGVBQWUsRUFDZixtQkFBbUIsRUFJcEIsTUFBTSw0QkFBNEIsQ0FBQztBQUNwQyxPQUFPLEVBQUUsZUFBZSxFQUFFLGtCQUFrQixFQUFFLHVCQUF1QixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFbEcsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0seUJBQXlCLENBQUM7O0FBRXBFOzs7O0dBSUc7QUFFSCxNQUFNLE9BQU8sZUFBZTtJQXFCMUI7UUFwQlUsU0FBSSxHQUFHLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUMvQixlQUFVLEdBQUcsTUFBTSxDQUFDLHVCQUF1QixDQUFDLENBQUM7UUFDN0MsYUFBUSxHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBbUI5QyxJQUFJLENBQUMsa0JBQWtCLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNuRSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksZUFBZSxDQUFDO1lBQ2xDLFVBQVUsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsVUFBVTtZQUM1QyxRQUFRLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLGdCQUFnQjtTQUNqRCxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxL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QUFHLEtBQUssRUFBRSxHQUFXLEVBQTBCLEVBQUU7SUFDekQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDaEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDL0MsTUFBTSxVQUFVLEdBQUcsTUFBTSxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ3hFLE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztJQUN6RCxNQUFNLE9BQU8sR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzdFLE9BQU8sT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDO0FBQy9CLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgQXV0aGVudGljYXRpb25EZXRhaWxzLFxuICBDb2duaXRvVXNlcixcbiAgQ29nbml0b1VzZXJBdHRyaWJ1dGUsXG4gIENvZ25pdG9Vc2VyUG9vbCxcbiAgQ29nbml0b1JlZnJlc2hUb2tlbixcbiAgQ29nbml0b1VzZXJTZXNzaW9uLFxuICBJU2lnblVwUmVzdWx0LFxuICBDaGFsbGVuZ2VOYW1lXG59IGZyb20gJ2FtYXpvbi1jb2duaXRvLWlkZW50aXR5LWpzJztcbmltcG9ydCB7IElERUFFbnZpcm9ubWVudCwgSURFQVN0b3JhZ2VTZXJ2aWNlLCBJREVBVHJhbnNsYXRpb25zU2VydmljZSB9IGZyb20gJ0BpZGVhLWlvbmljL2NvbW1vbic7XG5cbmltcG9ydCB7IENPTU1PTl9QQVNTV09SRFNfVE9QXzEwMDAgfSBmcm9tICcuL2NvbW1vblBhc3N3b3Jkcy5tb2RlbCc7XG5cbi8qKlxuICogQ29nbml0byB3cmFwcGVyIHRvIG1hbmFnZSB0aGUgYXV0aGVudGljYXRpb24gZmxvdy5cbiAqXG4gKiBOb3RlOiBpbiBJREVBJ3MgQ29nbml0byB1c2VycyBwb29scywgdGhlIGVtYWlsIGlzIGFuIGFsaWFzIG9mIHRoZSB1c2VybmFtZS5cbiAqL1xuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBJREVBQXV0aFNlcnZpY2Uge1xuICBwcm90ZWN0ZWQgX2VudiA9IGluamVjdChJREVBRW52aXJvbm1lbnQpO1xuICBwcm90ZWN0ZWQgX3RyYW5zbGF0ZSA9IGluamVjdChJREVBVHJhbnNsYXRpb25zU2VydmljZSk7XG4gIHByb3RlY3RlZCBfc3RvcmFnZSA9IGluamVjdChJREVBU3RvcmFnZVNlcnZpY2UpO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgQ29nbml0bydzIHVzZXIgYXR0cmlidXRlIHdoaWNoIGNvbnRhaW5zIHRoZSBrZXkgb2YgdGhlIGxhc3QgZGV2aWNlIHRvIGxvZ2luIGluIHRoaXMgcHJvamVjdC5cbiAgICovXG4gIHByb3RlY3RlZCBkZXZpY2VLZXlBdHRyaWJ1dGU6IHN0cmluZztcblxuICBwcml2YXRlIHVzZXJQb29sOiBDb2duaXRvVXNlclBvb2w7XG5cbiAgY2hhbGxlbmdlVXNlcm5hbWU6IHN0cmluZztcbiAgcHJpdmF0ZSBjaGFsbGVuZ2VQYXNzd29yZDogc3RyaW5nO1xuXG4gIHByaXZhdGUgbmV3QWNjb3VudEp1c3RSZWdpc3RlcmVkOiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSBtZmFQcm9qZWN0TmFtZTogc3RyaW5nO1xuXG4gIHByaXZhdGUgcGFzc3dvcmRQb2xpY3k6IGFueTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmRldmljZUtleUF0dHJpYnV0ZSA9ICdjdXN0b206Jy5jb25jYXQodGhpcy5fZW52LmlkZWEucHJvamVjdCk7XG4gICAgdGhpcy51c2VyUG9vbCA9IG5ldyBDb2duaXRvVXNlclBvb2woe1xuICAgICAgVXNlclBvb2xJZDogdGhpcy5fZW52LmF3cy5jb2duaXRvLnVzZXJQb29sSWQsXG4gICAgICBDbGllbnRJZDogdGhpcy5fZW52LmF3cy5jb2duaXRvLnVzZXJQb29sQ2xpZW50SWRcbiAgICB9KTtcbiAgICB0aGlzLm1mYVByb2plY3ROYW1lID0gdGhpcy5fZW52LmlkZWEuYXV0aC50aXRsZSB8fCB0aGlzLl9lbnYuaWRlYS5wcm9qZWN0O1xuICAgIHRoaXMucGFzc3dvcmRQb2xpY3kgPSB0aGlzLl9lbnYuaWRlYS5hdXRoLnBhc3N3b3JkUG9saWN5O1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXBhcmUgdGhlIG5lY2Vzc2FyeSBzdHJ1Y3R1cmUgdG8gZ2V0IGF1dGhvcml6ZWQgaW4gQ29nbml0by5cbiAgICovXG4gIHByaXZhdGUgcHJlcGFyZUF1dGhEZXRhaWxzKHVzZXJuYW1lOiBzdHJpbmcsIHB3ZDogc3RyaW5nKTogQXV0aGVudGljYXRpb25EZXRhaWxzIHtcbiAgICByZXR1cm4gbmV3IEF1dGhlbnRpY2F0aW9uRGV0YWlscyh7IFVzZXJuYW1lOiB1c2VybmFtZSwgUGFzc3dvcmQ6IHB3ZCB9KTtcbiAgfVxuICAvKipcbiAgICogUHJlcGFyZSB0aGUgbmVjZXNzYXJ5IHN0cnVjdHVyZSB0byBpZGVudGlmeSBhIENvZ25pdG8gdXNlci5cbiAgICovXG4gIHByZXBhcmVDb2duaXRvVXNlcih1c2VybmFtZTogc3RyaW5nKTogQ29nbml0b1VzZXIge1xuICAgIHJldHVybiBuZXcgQ29nbml0b1VzZXIoeyBVc2VybmFtZTogdXNlcm5hbWUsIFBvb2w6IHRoaXMudXNlclBvb2wgfSk7XG4gIH1cbiAgLyoqXG4gICAqIFByZXBhcmUgYSB1c2VyIGF0dHJpYnV0ZSAodGhleSBhcmUgYWxsIHN0cmluZ3MpIGluIENvZ25pdG8ncyBmb3JtYXQuXG4gICAqL1xuICBwcml2YXRlIHByZXBhcmVVc2VyQXR0cmlidXRlKG5hbWU6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IENvZ25pdG9Vc2VyQXR0cmlidXRlIHtcbiAgICByZXR1cm4gbmV3IENvZ25pdG9Vc2VyQXR0cmlidXRlKHsgTmFtZTogbmFtZSwgVmFsdWU6IHZhbHVlIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFBlcmZvcm0gYSBsb2dpbiB0aHJvdWdoIHVzZXJuYW1lIGFuZCBwYXNzd29yZC5cbiAgICovXG4gIGxvZ2luKHVzZXJuYW1lOiBzdHJpbmcsIHBhc3N3b3JkOiBzdHJpbmcpOiBQcm9taXNlPExvZ2luT3V0Y29tZUFjdGlvbnM+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCk6IHZvaWQgPT4ge1xuICAgICAgY29uc3QgdXNlciA9IHRoaXMucHJlcGFyZUNvZ25pdG9Vc2VyKHVzZXJuYW1lKTtcbiAgICAgIHVzZXIuYXV0aGVudGljYXRlVXNlcih0aGlzLnByZXBhcmVBdXRoRGV0YWlscyh1c2VybmFtZSwgcGFzc3dvcmQpLCB7XG4gICAgICAgIG9uU3VjY2VzczogKCk6IHZvaWQgPT5cbiAgICAgICAgICByZXNvbHZlKHRoaXMuX2Vudi5pZGVhLmF1dGguZm9yY2VMb2dpbldpdGhNRkEgPyBMb2dpbk91dGNvbWVBY3Rpb25zLk1GQV9TRVRVUCA6IExvZ2luT3V0Y29tZUFjdGlvbnMuTk9ORSksXG4gICAgICAgIG9uRmFpbHVyZTogKGVycjogRXJyb3IpOiB2b2lkID0+IHJlamVjdChlcnIpLFxuICAgICAgICBuZXdQYXNzd29yZFJlcXVpcmVkOiAoKTogdm9pZCA9PiB7XG4gICAgICAgICAgdGhpcy5jaGFsbGVuZ2VVc2VybmFtZSA9IHVzZXJuYW1lO1xuICAgICAgICAgIHRoaXMuY2hhbGxlbmdlUGFzc3dvcmQgPSBwYXNzd29yZDtcbiAgICAgICAgICByZXNvbHZlKExvZ2luT3V0Y29tZUFjdGlvbnMuTkVXX1BBU1NXT1JEKTtcbiAgICAgICAgfSxcbiAgICAgICAgdG90cFJlcXVpcmVkOiAoKTogdm9pZCA9PiB7XG4gICAgICAgICAgdGhpcy5jaGFsbGVuZ2VVc2VybmFtZSA9IHVzZXJuYW1lO1xuICAgICAgICAgIHRoaXMuY2hhbGxlbmdlUGFzc3dvcmQgPSBwYXNzd29yZDtcbiAgICAgICAgICByZXNvbHZlKExvZ2luT3V0Y29tZUFjdGlvbnMuTUZBX0NIQUxMRU5HRSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIC8qKlxuICAgKiBDb21wbGV0ZSB0aGUgbmV3IHBhc3N3b3JkIGZsb3cgaW4gdGhlIGF1dGhlbnRpY2F0aW9uLlxuICAgKi9cbiAgY29uZmlybU5ld1Bhc3N3b3JkKG5ld1Bhc3N3b3JkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCk6IHZvaWQgPT4ge1xuICAgICAgY29uc3QgdXNlciA9IHRoaXMucHJlcGFyZUNvZ25pdG9Vc2VyKHRoaXMuY2hhbGxlbmdlVXNlcm5hbWUpO1xuICAgICAgdXNlci5hdXRoZW50aWNhdGVVc2VyKHRoaXMucHJlcGFyZUF1dGhEZXRhaWxzKHRoaXMuY2hhbGxlbmdlVXNlcm5hbWUsIHRoaXMuY2hhbGxlbmdlUGFzc3dvcmQpLCB7XG4gICAgICAgIG9uU3VjY2VzczogKCk6IHZvaWQgPT4gcmVzb2x2ZSgpLFxuICAgICAgICBvbkZhaWx1cmU6IChlcnI6IEVycm9yKTogdm9pZCA9PiByZWplY3QoZXJyKSxcbiAgICAgICAgbmV3UGFzc3dvcmRSZXF1aXJlZDogKCk6IHZvaWQgPT5cbiAgICAgICAgICB1c2VyLmNvbXBsZXRlTmV3UGFzc3dvcmRDaGFsbGVuZ2UoXG4gICAgICAgICAgICBuZXdQYXNzd29yZCxcbiAgICAgICAgICAgIHt9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBvblN1Y2Nlc3M6ICgpOiB2b2lkID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNoYWxsZW5nZVVzZXJuYW1lID0gbnVsbDtcbiAgICAgICAgICAgICAgICB0aGlzLmNoYWxsZW5nZVBhc3N3b3JkID0gbnVsbDtcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIG9uRmFpbHVyZTogKGVycjogRXJyb3IpOiB2b2lkID0+IHJlamVjdChlcnIpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgLyoqXG4gICAqICBDb21wbGV0ZSB0aGUgTUZBIGNoYWxsZW5nZSBmbG93IGluIHRoZSBhdXRoZW50aWNhdGlvbi5cbiAgICovXG4gIGNvbXBsZXRlTUZBQ2hhbGxlbmdlKG90cENvZGU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KTogdm9pZCA9PiB7XG4gICAgICBjb25zdCB1c2VyID0gdGhpcy5wcmVwYXJlQ29nbml0b1VzZXIodGhpcy5jaGFsbGVuZ2VVc2VybmFtZSk7XG4gICAgICB1c2VyLmF1dGhlbnRpY2F0ZVVzZXIodGhpcy5wcmVwYXJlQXV0aERldGFpbHModGhpcy5jaGFsbGVuZ2VVc2VybmFtZSwgdGhpcy5jaGFsbGVuZ2VQYXNzd29yZCksIHtcbiAgICAgICAgb25TdWNjZXNzOiAoKTogdm9pZCA9PiByZXNvbHZlKCksXG4gICAgICAgIG9uRmFpbHVyZTogKGVycjogRXJyb3IpOiB2b2lkID0+IHJlamVjdChlcnIpLFxuICAgICAgICB0b3RwUmVxdWlyZWQ6IChjaGFsbGVuZ2VOYW1lOiBDaGFsbGVuZ2VOYW1lKTogdm9pZCA9PlxuICAgICAgICAgIHVzZXIuc2VuZE1GQUNvZGUoXG4gICAgICAgICAgICBvdHBDb2RlLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBvblN1Y2Nlc3M6ICgpOiB2b2lkID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNoYWxsZW5nZVVzZXJuYW1lID0gbnVsbDtcbiAgICAgICAgICAgICAgICB0aGlzLmNoYWxsZW5nZVBhc3N3b3JkID0gbnVsbDtcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIG9uRmFpbHVyZTogZXJyID0+IHJlamVjdChlcnIpXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY2hhbGxlbmdlTmFtZVxuICAgICAgICAgIClcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIC8qKlxuICAgKiBSZWdpc3RlciBhIG5ldyB1c2VyIGEgc2V0IGl0cyBkZWZhdWx0IGF0dHJpYnV0ZXMuXG4gICAqL1xuICByZWdpc3Rlcih1c2VybmFtZTogc3RyaW5nLCBwYXNzd29yZDogc3RyaW5nLCBhdHRyaWJ1dGVzPzogYW55KTogUHJvbWlzZTxDb2duaXRvVXNlcj4ge1xuICAgIGF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzIHx8IHt9O1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KTogdm9pZCA9PiB7XG4gICAgICAvLyBhZGQgYXR0cmlidXRlcyBsaWtlIHRoZSBlbWFpbCBhZGRyZXNzIGFuZCB0aGUgZnVsbG5hbWVcbiAgICAgIGNvbnN0IGF0dHJzID0gW107XG4gICAgICBmb3IgKGNvbnN0IHByb3AgaW4gYXR0cmlidXRlcylcbiAgICAgICAgaWYgKGF0dHJpYnV0ZXNbcHJvcF0pIGF0dHJzLnB1c2godGhpcy5wcmVwYXJlVXNlckF0dHJpYnV0ZShwcm9wLCBhdHRyaWJ1dGVzW3Byb3BdKSk7XG4gICAgICAvLyBhZGQgdGhlIGVtYWlsLCB3aGljaCBpcyBlcXVhbCB0byB0aGUgdXNlcm5hbWUgZm9yIG1vc3Qgb2Ygb3VyIFBvb2xzXG4gICAgICBpZiAoIWF0dHJpYnV0ZXMuZW1haWwpIGF0dHJzLnB1c2godGhpcy5wcmVwYXJlVXNlckF0dHJpYnV0ZSgnZW1haWwnLCB1c2VybmFtZSkpO1xuICAgICAgLy8gcmVnaXN0ZXIgdGhlIG5ldyB1c2VyIHRvIHRoZSBwb29sXG4gICAgICB0aGlzLnVzZXJQb29sLnNpZ25VcCh1c2VybmFtZSwgcGFzc3dvcmQsIGF0dHJzLCBudWxsLCAoZXJyOiBFcnJvciwgcmVzOiBJU2lnblVwUmVzdWx0KTogdm9pZCA9PiB7XG4gICAgICAgIGlmIChlcnIpIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgdGhpcy5uZXdBY2NvdW50SnVzdFJlZ2lzdGVyZWQgPSB1c2VybmFtZTtcbiAgICAgICAgcmVzb2x2ZShyZXMudXNlcik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuICAvKipcbiAgICogSW4gY2FzZSBhIG5ldyBhY2NvdW50IGhhcyBqdXN0IGJlZW4gcmVnaXN0ZXJlZCwgcmV0dXJuIHRoZSB1c2VybmFtZS5cbiAgICovXG4gIGdldE5ld0FjY291bnRKdXN0UmVnaXN0ZXJlZCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLm5ld0FjY291bnRKdXN0UmVnaXN0ZXJlZDtcbiAgfVxuICAvKipcbiAgICogQ29uZmlybSBhIG5ldyByZWdpc3RyYXRpb24gdGhyb3VnaCB0aGUgY29uZmlybWF0aW9uIGNvZGUgc2VudCBieSBDb2duaXRvLlxuICAgKi9cbiAgY29uZmlybVJlZ2lzdHJhdGlvbih1c2VybmFtZTogc3RyaW5nLCBjb2RlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCk6IHZvaWQgPT4ge1xuICAgICAgdGhpcy5wcmVwYXJlQ29nbml0b1VzZXIodXNlcm5hbWUpLmNvbmZpcm1SZWdpc3RyYXRpb24oY29kZSwgdHJ1ZSwgKGVycjogRXJyb3IpOiB2b2lkID0+XG4gICAgICAgIGVyciA/IHJlamVjdChlcnIpIDogcmVzb2x2ZSgpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG4gIC8qKlxuICAgKiBTZW5kIGFnYWluIGEgY29uZmlybWF0aW9uIGNvZGUgZm9yIGEgbmV3IHJlZ2lzdHJhdGlvbi5cbiAgICovXG4gIHJlc2VuZENvbmZpcm1hdGlvbkNvZGUodXNlcm5hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KTogdm9pZCA9PiB7XG4gICAgICB0aGlzLnByZXBhcmVDb2duaXRvVXNlcih1c2VybmFtZSkucmVzZW5kQ29uZmlybWF0aW9uQ29kZSgoZXJyOiBFcnJvcik6IHZvaWQgPT4gKGVyciA/IHJlamVjdChlcnIpIDogcmVzb2x2ZSgpKSk7XG4gICAgfSk7XG4gIH1cbiAgLyoqXG4gICAqIExvZ291dCB0aGUgY3VycmVudGx5IHNpZ25lZC1pbiB1c2VyLlxuICAgKi9cbiAgbG9nb3V0KG9wdGlvbnM/OiB7IGdsb2JhbDogYm9vbGVhbiB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oeyBnbG9iYWw6IGZhbHNlIH0sIG9wdGlvbnMpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KTogdm9pZCA9PiB7XG4gICAgICAvLyByZW1vdmUgdGhlIHJlZnJlc2ggdG9rZW4gcHJldmlvc2x5IHNhdmVkXG4gICAgICB0aGlzLl9zdG9yYWdlLnJlbW92ZSgnQXV0aFJlZnJlc2hUb2tlbicpLnRoZW4oXG4gICAgICAgICgpOiBQcm9taXNlPHZvaWQ+ID0+XG4gICAgICAgICAgLy8gcmVtb3ZlIHRoZSBvcHRpb25hbCBhdXRoIGRldGFpbHNcbiAgICAgICAgICB0aGlzLl9zdG9yYWdlLnJlbW92ZSgnQXV0aFVzZXJEZXRhaWxzJykudGhlbigoKTogdm9pZCA9PiB7XG4gICAgICAgICAgICAvLyBnZXQgdGhlIHVzZXIgYW5kIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICBjb25zdCB1c2VyID0gdGhpcy51c2VyUG9vbC5nZXRDdXJyZW50VXNlcigpO1xuICAgICAgICAgICAgdXNlci5nZXRTZXNzaW9uKGFzeW5jIChlcnI6IEVycm9yKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgICAgICAgIC8vIGlmIHRoZSBzZXNzaW9uIGlzIGFjdGl2ZSwgcnVuIHRoZSBvbmxpbmUgc2lnbi1vdXQ7IG90aGVyd2lzZSwgb25seSB0aGUgbG9jYWwgZGF0YSBoYXMgYmVlbiBkZWxldGVkXG4gICAgICAgICAgICAgIGlmIChlcnIpIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICAgIC8vIGlmIGEgcmVmZXJlbmNlIHRvIHRoZSBkZXZpY2Ugd2FzIHNhdmVkLCBmb3JnZXQgaXRcbiAgICAgICAgICAgICAgaWYgKHRoaXMuX2Vudi5pZGVhLmF1dGguc2luZ2xlU2ltdWx0YW5lb3VzU2Vzc2lvbikgYXdhaXQgdGhpcy5zZXRDdXJyZW50RGV2aWNlRm9yUHJvamVjdChudWxsKTtcbiAgICAgICAgICAgICAgLy8gc2lnbi1vdXQgZnJvbSB0aGUgcG9vbCAodGVybWluYXRlIHRoZSBjdXJyZW50IHNlc3Npb24gb3IgYWxsIHRoZSBzZXNzaW9ucylcbiAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuZ2xvYmFsKVxuICAgICAgICAgICAgICAgIHVzZXIuZ2xvYmFsU2lnbk91dCh7IG9uU3VjY2VzczogKCk6IHZvaWQgPT4gcmVzb2x2ZSgpLCBvbkZhaWx1cmU6IGVyciA9PiByZWplY3QoZXJyKSB9KTtcbiAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdXNlci5zaWduT3V0KCk7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuICAvKipcbiAgICogU2VuZCBhIHBhc3N3b3JkIHJlc2V0IHJlcXVlc3QuXG4gICAqL1xuICBmb3Jnb3RQYXNzd29yZCh1c2VybmFtZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpOiB2b2lkID0+IHtcbiAgICAgIHRoaXMucHJlcGFyZUNvZ25pdG9Vc2VyKHVzZXJuYW1lKS5mb3Jnb3RQYXNzd29yZCh7XG4gICAgICAgIG9uU3VjY2VzczogKCk6IHZvaWQgPT4gcmVzb2x2ZSgpLFxuICAgICAgICBvbkZhaWx1cmU6IChlcnI6IEVycm9yKTogdm9pZCA9PiByZWplY3QoZXJyKVxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgLyoqXG4gICAqIENvbmZpcm0gYSBuZXcgcGFzc3dvcmQgYWZ0ZXIgYSBwYXNzd29yZCByZXNldCByZXF1ZXN0LlxuICAgKi9cbiAgY29uZmlybVBhc3N3b3JkKHVzZXJuYW1lOiBzdHJpbmcsIGNvZGU6IHN0cmluZywgbmV3UHdkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCk6IHZvaWQgPT4ge1xuICAgICAgdGhpcy5wcmVwYXJlQ29nbml0b1VzZXIodXNlcm5hbWUpLmNvbmZpcm1QYXNzd29yZChjb2RlLCBuZXdQd2QsIHtcbiAgICAgICAgb25TdWNjZXNzOiAoKTogdm9pZCA9PiByZXNvbHZlKCksXG4gICAgICAgIG9uRmFpbHVyZTogKGVycjogRXJyb3IpOiB2b2lkID0+IHJlamVjdChlcnIpXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuICAvKipcbiAgICogR2V0cyB0aGUgVVJMIGZvciBlbmFibGluZyBNRkEuIFRoaXMgVVJMIGNhbiBiZSB1c2VkIHRvIGdlbmVyYXRlIGEgUVIgQ29kZSB0byByZWFkIHdpdGggYW4gYXV0aGVudGljYXRvciBhcHAuXG4gICAqL1xuICBnZXRVUkxGb3JFbmFibGluZ01GQSgpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KTogdm9pZCA9PiB7XG4gICAgICBjb25zdCB1c2VyID0gdGhpcy51c2VyUG9vbC5nZXRDdXJyZW50VXNlcigpO1xuICAgICAgaWYgKCF1c2VyKSByZXR1cm4gcmVqZWN0KCk7XG4gICAgICB1c2VyLmdldFNlc3Npb24oKGVycjogRXJyb3IpOiB2b2lkID0+IHtcbiAgICAgICAgaWYgKGVycikgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgICB1c2VyLmFzc29jaWF0ZVNvZnR3YXJlVG9rZW4oe1xuICAgICAgICAgIGFzc29jaWF0ZVNlY3JldENvZGU6IChzZWNyZXRDb2RlOiBzdHJpbmcpOiB2b2lkID0+XG4gICAgICAgICAgICByZXNvbHZlKGBvdHBhdXRoOi8vdG90cC8ke2VuY29kZVVSSSh0aGlzLm1mYVByb2plY3ROYW1lKX0/c2VjcmV0PSR7c2VjcmV0Q29kZX1gKSxcbiAgICAgICAgICBvbkZhaWx1cmU6IChlcnI6IGFueSk6IHZvaWQgPT4gcmVqZWN0KGVycilcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuICAvKipcbiAgICogQ2hlY2sgd2hldGhlciB0aGUgdXNlciBoYXMgTUZBIGVuYWJsZWQuXG4gICAqL1xuICBjaGVja0lmVXNlckhhc01GQUVuYWJsZWQoYnlwYXNzQ2FjaGUgPSBmYWxzZSk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KTogdm9pZCA9PiB7XG4gICAgICBjb25zdCB1c2VyID0gdGhpcy51c2VyUG9vbC5nZXRDdXJyZW50VXNlcigpO1xuICAgICAgaWYgKCF1c2VyKSByZXR1cm4gcmVqZWN0KCk7XG4gICAgICB1c2VyLmdldFNlc3Npb24oKGVycjogRXJyb3IpOiB2b2lkID0+IHtcbiAgICAgICAgaWYgKGVycikgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgICB1c2VyLmdldFVzZXJEYXRhKFxuICAgICAgICAgIChlcnIsIGRhdGEpOiB2b2lkID0+IHtcbiAgICAgICAgICAgIGlmIChlcnIpIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgICAgIGNvbnN0IGlzTUZBRW5hYmxlZCA9ICEhKGRhdGEuVXNlck1GQVNldHRpbmdMaXN0ICYmIGRhdGEuVXNlck1GQVNldHRpbmdMaXN0LmluY2x1ZGVzKCdTT0ZUV0FSRV9UT0tFTl9NRkEnKSk7XG4gICAgICAgICAgICByZXNvbHZlKGlzTUZBRW5hYmxlZCk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7IGJ5cGFzc0NhY2hlIH1cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIC8qKlxuICAgKiBDb25maWd1cmUgYSBNRkEgZGV2aWNlIGZvciB0aGUgdXNlci5cbiAgICovXG4gIHByaXZhdGUgc2V0TUZBRGV2aWNlKG90cDogc3RyaW5nLCBtZmFEZXZpY2VOYW1lOiBzdHJpbmcsIGVuYWJsZWQgPSB0cnVlLCBwcmVmZXJyZWQgPSB0cnVlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpOiB2b2lkID0+IHtcbiAgICAgIGNvbnN0IHVzZXIgPSB0aGlzLnVzZXJQb29sLmdldEN1cnJlbnRVc2VyKCk7XG4gICAgICBpZiAoIXVzZXIpIHJldHVybiByZWplY3QoKTtcbiAgICAgIHVzZXIuZ2V0U2Vzc2lvbigoZXJyOiBFcnJvcik6IHZvaWQgPT4ge1xuICAgICAgICBpZiAoZXJyKSByZXR1cm4gcmVqZWN0KGVycik7XG4gICAgICAgIHVzZXIudmVyaWZ5U29mdHdhcmVUb2tlbihvdHAsIG1mYURldmljZU5hbWUsIHtcbiAgICAgICAgICBvblN1Y2Nlc3M6ICgpOiB2b2lkID0+XG4gICAgICAgICAgICB1c2VyLnNldFVzZXJNZmFQcmVmZXJlbmNlKG51bGwsIHsgRW5hYmxlZDogZW5hYmxlZCwgUHJlZmVycmVkTWZhOiBwcmVmZXJyZWQgfSwgKGVycjogRXJyb3IpOiB2b2lkID0+XG4gICAgICAgICAgICAgIGVyciA/IHJlamVjdChlcnIpIDogcmVzb2x2ZSgpXG4gICAgICAgICAgICApLFxuICAgICAgICAgIG9uRmFpbHVyZTogKGVycik6IHZvaWQgPT4gcmVqZWN0KGVycilcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuICAvKipcbiAgICogRW5hYmxlIGEgbmV3IE1GQSBkZXZpY2UgZm9yIHRoZSB1c2VyIGJ5IGluc2VydGluZyBhbiBPVFAgY29kZSBnZW5lcmF0ZWQgYnkgaXQuXG4gICAqL1xuICBlbmFibGVNRkEob3RwOiBzdHJpbmcsIG1mYURldmljZU5hbWUgPSAnZGVmYXVsdCcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZXRNRkFEZXZpY2Uob3RwLCBtZmFEZXZpY2VOYW1lLCB0cnVlLCB0cnVlKTtcbiAgfVxuICAvKipcbiAgICogRGlzYWJsZSBNRkEgZm9yIGEgdXNlciBieSBpbnNlcnRpbmcgYW4gT1RQIGNvZGUgZ2VuZXJhdGVkIGJ5IGl0LlxuICAgKi9cbiAgZGlzYWJsZU1GQShvdHA6IHN0cmluZywgbWZhRGV2aWNlTmFtZSA9ICdkZWZhdWx0Jyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLnNldE1GQURldmljZShvdHAsIG1mYURldmljZU5hbWUsIGZhbHNlLCBmYWxzZSk7XG4gIH1cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgdXNlciBpcyBjdXJyZW50bHkgYXV0aGVudGljYXRlZC5cbiAgICogQHBhcmFtIG9mZmxpbmVBbGxvd2VkIGlmIHNldCBhbmQgaWYgb2ZmbGluZSwgc2tpcCBhdXRoZW50aWNhdGlvbiBhbmQgcmV0cmlldmUgZGF0YSBsb2NhbGx5XG4gICAqIEBwYXJhbSBnZXRGcmVzaElkVG9rZW5PbkV4cCBjYiBmdW5jdGlvbiB0byBleGVjdXRlIHdoZW4gdGhlIGlkVG9rZW4gaXMgcmVmcmVzaGVkXG4gICAqL1xuICBpc0F1dGhlbnRpY2F0ZWQob2ZmbGluZUFsbG93ZWQ6IGJvb2xlYW4sIGdldEZyZXNoSWRUb2tlbk9uRXhwPzogKGZyZXNoSWRUb2tlbjogc3RyaW5nKSA9PiB2b2lkKTogUHJvbWlzZTxhbnk+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCk6IHZvaWQgPT4ge1xuICAgICAgaWYgKG9mZmxpbmVBbGxvd2VkICYmICFuYXZpZ2F0b3Iub25MaW5lKSB7XG4gICAgICAgIHRoaXMuX3N0b3JhZ2UuZ2V0KCdBdXRoVXNlckRldGFpbHMnKS50aGVuKHVzZXJEZXRhaWxzID0+IHJlc29sdmUoeyBpZFRva2VuOiBudWxsLCB1c2VyRGV0YWlscyB9KSk7XG4gICAgICAgIC8vIHJlLWV4ZWN1dGUgdGhlIG1ldGhvZCB3aGVuIGJhY2sgb25saW5lLCBzbyB0aGF0IHlvdSBjYW4gcmV0cmlldmUgYSB0b2tlbiB0byBtYWtlIHJlcXVlc3RzXG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICAgICdvbmxpbmUnLFxuICAgICAgICAgICgpOiBQcm9taXNlPHZvaWQ+ID0+XG4gICAgICAgICAgICB0aGlzLmlzQXV0aGVudGljYXRlZCh0cnVlLCBnZXRGcmVzaElkVG9rZW5PbkV4cClcbiAgICAgICAgICAgICAgLy8gc2V0IHRoZSBuZXcgdG9rZW4gYXMgaWYgaXQgd2FzIHJlZnJlc2hlZFxuICAgICAgICAgICAgICAudGhlbihyZXN1bHQgPT4gZ2V0RnJlc2hJZFRva2VuT25FeHAocmVzdWx0LmlkVG9rZW4pKVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgdXNlciA9IHRoaXMudXNlclBvb2wuZ2V0Q3VycmVudFVzZXIoKTtcbiAgICAgICAgaWYgKCF1c2VyKSByZXR1cm4gcmVqZWN0KCk7XG4gICAgICAgIHVzZXIuZ2V0U2Vzc2lvbigoZXJyOiBFcnJvciwgc2Vzc2lvbjogQ29nbml0b1VzZXJTZXNzaW9uKTogdm9pZCA9PiB7XG4gICAgICAgICAgaWYgKGVycikgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgICAgIHVzZXIuZ2V0VXNlckRhdGEoXG4gICAgICAgICAgICAoZXJyLCBkYXRhKTogdm9pZCA9PiB7XG4gICAgICAgICAgICAgIGlmIChlcnIpIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgICAgICAgY29uc3QgaXNNRkFFbmFibGVkID0gISEoXG4gICAgICAgICAgICAgICAgZGF0YS5Vc2VyTUZBU2V0dGluZ0xpc3QgJiYgZGF0YS5Vc2VyTUZBU2V0dGluZ0xpc3QuaW5jbHVkZXMoJ1NPRlRXQVJFX1RPS0VOX01GQScpXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGlmICghaXNNRkFFbmFibGVkICYmIHRoaXMuX2Vudi5pZGVhLmF1dGguZm9yY2VMb2dpbldpdGhNRkEpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoTG9naW5PdXRjb21lQWN0aW9ucy5NRkFfU0VUVVApKTtcbiAgICAgICAgICAgICAgdXNlci5nZXRVc2VyQXR0cmlidXRlcygoZTogRXJyb3IsIGF0dHJpYnV0ZXM6IENvZ25pdG9Vc2VyQXR0cmlidXRlW10pOiB2b2lkID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZSkgcmV0dXJuIHJlamVjdChlKTtcbiAgICAgICAgICAgICAgICAvLyByZW1hcCB1c2VyIGF0dHJpYnV0ZXNcbiAgICAgICAgICAgICAgICBjb25zdCB1c2VyRGV0YWlsczogYW55ID0ge307XG4gICAgICAgICAgICAgICAgYXR0cmlidXRlcy5mb3JFYWNoKChhOiBDb2duaXRvVXNlckF0dHJpYnV0ZSk6IHN0cmluZyA9PiAodXNlckRldGFpbHNbYS5nZXROYW1lKCldID0gYS5nZXRWYWx1ZSgpKSk7XG4gICAgICAgICAgICAgICAgLy8gYWRkIHRoZSB1c2VyJ3MgZ3JvdXBzIHRvIHRoZSBhdHRyaWJ1dGVzXG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbkluZm8gPSBzZXNzaW9uLmdldEFjY2Vzc1Rva2VuKCkuZGVjb2RlUGF5bG9hZCgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGdyb3Vwczogc3RyaW5nW10gPSBzZXNzaW9uSW5mb1snY29nbml0bzpncm91cHMnXSB8fCBbXTtcbiAgICAgICAgICAgICAgICB1c2VyRGV0YWlsc1snZ3JvdXBzJ10gPSBncm91cHM7XG4gICAgICAgICAgICAgICAgLy8gcnVuIHNvbWUgY2hlY2tzIGNvbnNpZGVyaW5nIHRoZSB1c2VyJ3MgZ3JvdXBzIGFuZCBkZXZpY2VzIChiYXNlZCBvbiB0aGUgcHJvamVjdCdzIGNvbmZpZ3VyYXRpb24pXG4gICAgICAgICAgICAgICAgdGhpcy5ydW5Qb3N0QXV0aENoZWNrcyh1c2VyRGV0YWlscywgZXJyID0+IHtcbiAgICAgICAgICAgICAgICAgIC8vIGluIGNhc2Ugc29tZSBjaGVjayBmYWlsZWQsIHJlamVjdCB0aGUgYXV0aG9yaXNhdGlvbiBmbG93XG4gICAgICAgICAgICAgICAgICBpZiAoZXJyKSByZXR1cm4gcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgICAvLyAoYXN5bmMpIHNhdmUgdGhlIHJlZnJlc2ggdG9rZW4gc28gaXQgY2FuIGJlIGFjY2Vzc2VkIGJ5IG90aGVyIHByb2NlZHVyZXNcbiAgICAgICAgICAgICAgICAgIHRoaXMuX3N0b3JhZ2Uuc2V0KCdBdXRoUmVmcmVzaFRva2VuJywgc2Vzc2lvbi5nZXRSZWZyZXNoVG9rZW4oKS5nZXRUb2tlbigpKTtcbiAgICAgICAgICAgICAgICAgIC8vIHNldCBhIHRpbWVyIHRvIG1hbmFnZSB0aGUgYXV0b3JlZnJlc2ggb2YgdGhlIGlkVG9rZW4gKHRocm91Z2ggdGhlIHJlZnJlc2hUb2tlbilcbiAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoXG4gICAgICAgICAgICAgICAgICAgICgpOiB2b2lkID0+IHRoaXMucmVmcmVzaFNlc3Npb24odXNlciwgc2Vzc2lvbi5nZXRSZWZyZXNoVG9rZW4oKS5nZXRUb2tlbigpLCBnZXRGcmVzaElkVG9rZW5PbkV4cCksXG4gICAgICAgICAgICAgICAgICAgIDE1ICogNjAgKiAxMDAwXG4gICAgICAgICAgICAgICAgICApOyAvLyBldmVyeSAxNSBtaW51dGVzXG4gICAgICAgICAgICAgICAgICAvLyAoYXN5bmMpIGlmIG9mZmxpbmVBbGxvd2VkLCBzYXZlIGRhdGEgbG9jYWxseSwgdG8gdXNlIGl0IG5leHQgdGltZSB3ZSdsbCBiZSBvZmZsaW5lXG4gICAgICAgICAgICAgICAgICBpZiAob2ZmbGluZUFsbG93ZWQpIHRoaXMuX3N0b3JhZ2Uuc2V0KCdBdXRoVXNlckRldGFpbHMnLCB1c2VyRGV0YWlscyk7XG4gICAgICAgICAgICAgICAgICAvLyByZXR1cm4gdGhlIGlkVG9rZW4gKHRvIHVzZSB3aXRoIEFQSSlcbiAgICAgICAgICAgICAgICAgIHJlc29sdmUoeyBpZFRva2VuOiBzZXNzaW9uLmdldElkVG9rZW4oKS5nZXRKd3RUb2tlbigpLCB1c2VyRGV0YWlscyB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeyBieXBhc3NDYWNoZTogdHJ1ZSB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgLyoqXG4gICAqIEhlbHBlciB0byByZWZyZXNoIHRoZSBzZXNzaW9uIGV2ZXJ5IE4gbWludXRlcy5cbiAgICovXG4gIHByaXZhdGUgcmVmcmVzaFNlc3Npb24odXNlcjogQ29nbml0b1VzZXIsIHJlZnJlc2hUb2tlbjogc3RyaW5nLCBjYWxsYmFjazogKGZyZXNoSWRUb2tlbjogc3RyaW5nKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgdXNlci5yZWZyZXNoU2Vzc2lvbihcbiAgICAgIG5ldyBDb2duaXRvUmVmcmVzaFRva2VuKHsgUmVmcmVzaFRva2VuOiByZWZyZXNoVG9rZW4gfSksXG4gICAgICAoZXJyOiBFcnJvciwgc2Vzc2lvbjogQ29nbml0b1VzZXJTZXNzaW9uKTogdm9pZCA9PiB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAvLyB0cnkgYWdhaW4gaW4gMSBtaW51dGVcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpOiB2b2lkID0+IHRoaXMucmVmcmVzaFNlc3Npb24odXNlciwgcmVmcmVzaFRva2VuLCBjYWxsYmFjayksIDEgKiA2MCAqIDEwMDApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIChhc3luYykgc2F2ZSB0aGUgcmVmcmVzaCB0b2tlbiBzbyBpdCBjYW4gYmUgYWNjZXNzZWQgYnkgb3RoZXIgcHJvY2VkdXJlc1xuICAgICAgICAgIHRoaXMuX3N0b3JhZ2Uuc2V0KCdBdXRoUmVmcmVzaFRva2VuJywgc2Vzc2lvbi5nZXRSZWZyZXNoVG9rZW4oKS5nZXRUb2tlbigpKTtcbiAgICAgICAgICAvLyByZXBlYXQgZXZlcnkgMTUgbWludXRlc1xuICAgICAgICAgIHNldFRpbWVvdXQoXG4gICAgICAgICAgICAoKTogdm9pZCA9PiB0aGlzLnJlZnJlc2hTZXNzaW9uKHVzZXIsIHNlc3Npb24uZ2V0UmVmcmVzaFRva2VuKCkuZ2V0VG9rZW4oKSwgY2FsbGJhY2spLFxuICAgICAgICAgICAgMTUgKiA2MCAqIDEwMDBcbiAgICAgICAgICApO1xuICAgICAgICAgIC8vIHJ1biB0aGUgY2FsbGJhY2sgYWN0aW9uLCBpZiBzZXRcbiAgICAgICAgICBpZiAoY2FsbGJhY2spIGNhbGxiYWNrKHNlc3Npb24uZ2V0SWRUb2tlbigpLmdldEp3dFRva2VuKCkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgKTtcbiAgfVxuICAvKipcbiAgICogUnVuIHNvbWUgcG9zdC1hdXRoIGNoZWNrcywgYmFzZWQgb24gdGhlIHVzZXJzIGdyb3VwcyBhbmQgb24gdGhlIGFwcCdzIGNvbmZpZ3VyYXRpb246XG4gICAqICAtIHVzZXJzIGluIHRoZSBDb2duaXRvJ3MgXCJhZG1pbnNcIiBncnVwIHNraXAgYWxsIHRoZSBmb2xsb3dpbmcgcnVsZXMuXG4gICAqICAtIHVzZXJzIGluIHRoZSBDb2duaXRvJ3MgXCJyb2JvdHNcIiBncm91cCBjYW4ndCBzaWduLWludG8gZnJvbnQtZW5kcyAodGhleSBzZXJ2ZSBvbmx5IGJhY2stZW5kIHB1cnBvc2VzKS5cbiAgICogIC0gaWYgYGVudi5pZGVhLmF1dGguc2luZ2xlU2ltdWx0YW5lb3VzU2Vzc2lvbmAgaXMgb24sIG1ha2Ugc3VyZSB0aGVyZSBpcyBvbmx5IG9uZSBhY3RpdmUgc2Vzc2lvbiBwZXIgdXNlci5cbiAgICovXG4gIHByaXZhdGUgcnVuUG9zdEF1dGhDaGVja3ModXNlckRldGFpbHM6IGFueSwgY2FsbGJhY2s6IChlcnI/OiBFcnJvcikgPT4gdm9pZCk6IHZvaWQgfCBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBncm91cHM6IHN0cmluZ1tdID0gdXNlckRldGFpbHNbJ2dyb3VwcyddO1xuICAgIC8vIHNraXAgY2hlY2tzIGlmIHRoZSB1c2VyIGlzIGluIHRoZSBcImFkbWluc1wiIGdyb3VwXG4gICAgY29uc3QgaXNBZG1pbiA9IGdyb3Vwcy5zb21lKHggPT4geCA9PT0gJ2FkbWlucycpO1xuICAgIGlmIChpc0FkbWluKSByZXR1cm4gY2FsbGJhY2soKTtcbiAgICAvLyB1c2VycyBpbiB0aGUgXCJyb2JvdHNcIiBncm91cCBjYW4ndCBzaWduLWludG8gZnJvbnQtZW5kcyAodGhleSBzZXJ2ZSBvbmx5IGJhY2stZW5kIHB1cnBvc2VzKVxuICAgIGNvbnN0IGlzUm9ib3QgPSBncm91cHMuc29tZSh4ID0+IHggPT09ICdyb2JvdHMnKTtcbiAgICBpZiAoaXNSb2JvdCkgcmV0dXJuIGNhbGxiYWNrKG5ldyBFcnJvcignUk9CT1RfVVNFUicpKTtcbiAgICAvLyBpbiBjYXNlIHRoZSBwcm9qZWN0IGxpbWl0cyBlYWNoIGFjY291bnQgdG8gb25seSBvbmUgc2ltdWx0YW5lb3VzIHNlc3Npb24sIHJ1biBhIGNoZWNrXG4gICAgaWYgKHRoaXMuX2Vudi5pZGVhLmF1dGguc2luZ2xlU2ltdWx0YW5lb3VzU2Vzc2lvbikgcmV0dXJuIHRoaXMuY2hlY2tGb3JTaW11bHRhbmVvdXNTZXNzaW9ucyh1c2VyRGV0YWlscywgY2FsbGJhY2spO1xuICAgIC8vIG90aGVyd2lzZSwgd2UncmUgZG9uZVxuICAgIGNhbGxiYWNrKCk7XG4gIH1cbiAgLyoqXG4gICAqIENoZWNrIHdoZXRoZXIgdGhlIHVzZXIgc2lnbmVkLWludG8gbXVsdGlwbGUgZGV2aWNlcy5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgY2hlY2tGb3JTaW11bHRhbmVvdXNTZXNzaW9ucyh1c2VyRGV0YWlsczogYW55LCBjYWxsYmFjazogKGVycj86IEVycm9yKSA9PiB2b2lkKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gZ2V0IG9yIGNyZWF0ZSBhIGtleSBmb3IgdGhlIGN1cnJlbnQgZGV2aWNlICh+cmFuZG9tKVxuICAgIGxldCBjdXJyZW50RGV2aWNlS2V5ID0gYXdhaXQgdGhpcy5fc3RvcmFnZS5nZXQoJ0F1dGhEZXZpY2VLZXknKTtcbiAgICBpZiAoIWN1cnJlbnREZXZpY2VLZXkpIHtcbiAgICAgIGNvbnN0IHJhbmRvbUtleSA9IE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cmluZygxMCk7XG4gICAgICBjdXJyZW50RGV2aWNlS2V5ID0gcmFuZG9tS2V5LmNvbmNhdChTdHJpbmcoRGF0ZS5ub3coKSkpO1xuICAgICAgYXdhaXQgdGhpcy5fc3RvcmFnZS5zZXQoJ0F1dGhEZXZpY2VLZXknLCBjdXJyZW50RGV2aWNlS2V5KTtcbiAgICB9XG4gICAgLy8gY2hlY2sgd2hldGhlciB0aGUgbGFzdCBkZXZpY2UgdG8gc2lnbi1pbnRvIHRoaXMgcHJvamVjdCAoaWYgYW55KSBpcyB0aGUgY3VycmVudCBvbmVcbiAgICBjb25zdCBsYXN0RGV2aWNlVG9TaWduSW50b1RoaXNQcm9qZWN0ID0gdXNlckRldGFpbHNbdGhpcy5kZXZpY2VLZXlBdHRyaWJ1dGVdO1xuICAgIC8vIGlmIGl0J3MgdGhlIGZpcnN0IHVzZXIncyBkZXZpY2UgdG8gc2lnbi1pbiwgc2F2ZSB0aGUgcmVmZXJlbmNlIGluIENvZ25pdG8gYW5kIHJlc29sdmVcbiAgICBpZiAoIWxhc3REZXZpY2VUb1NpZ25JbnRvVGhpc1Byb2plY3QpIHtcbiAgICAgIHRoaXMuc2V0Q3VycmVudERldmljZUZvclByb2plY3QoY3VycmVudERldmljZUtleSlcbiAgICAgICAgLnRoZW4oKCk6IHZvaWQgPT4gY2FsbGJhY2soKSlcbiAgICAgICAgLmNhdGNoKCgpOiB2b2lkID0+IGNhbGxiYWNrKG5ldyBFcnJvcignQ0FOVF9TRVRfREVWSUNFJykpKTtcbiAgICAgIC8vIGlmIHRoZSBkZXZpY2UgZGlkbid0IGNoYW5nZSwgcmVzb2x2ZVxuICAgIH0gZWxzZSBpZiAobGFzdERldmljZVRvU2lnbkludG9UaGlzUHJvamVjdCA9PT0gY3VycmVudERldmljZUtleSkgY2FsbGJhY2soKTtcbiAgICAvLyBvdGh3ZXJ3aXNlLCByZXBvcnQgdGhlcmUgaXMgbW9yZSB0aGFuIG9uZSBzaW11bHRhbmVvdXMgc2Vzc2lvblxuICAgIGVsc2UgY2FsbGJhY2sobmV3IEVycm9yKCdTSU1VTFRBTkVPVVNfU0VTU0lPTicpKTtcbiAgfVxuICAvKipcbiAgICogU2V0IChvciByZXNldCkgdGhlIGN1cnJlbnQgdXNlcidzIGRldmljZSAoYnkga2V5KSBpbiB0aGUgY3VycmVudCBwcm9qZWN0IChzdG9yZWQgaW4gQ29nbml0bykuXG4gICAqL1xuICBwcml2YXRlIHNldEN1cnJlbnREZXZpY2VGb3JQcm9qZWN0KGRldmljZUtleT86IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGF0dHJpYnV0ZXM6IGFueSA9IHt9O1xuICAgIC8vIG5vdGU6IGFuIGVtcHR5IHN0cmluZyB3aWxsIHJlbW92ZSB0aGUgYXR0cmlidXRlIGZyb20gQ29nbml0b1xuICAgIGF0dHJpYnV0ZXNbdGhpcy5kZXZpY2VLZXlBdHRyaWJ1dGVdID0gZGV2aWNlS2V5IHx8ICcnO1xuICAgIHJldHVybiB0aGlzLnVwZGF0ZVVzZXJBdHRyaWJ1dGVzKGF0dHJpYnV0ZXMpO1xuICB9XG4gIC8qKlxuICAgKiBVcGRhdGUgdGhlIGN1cnJlbnRseSBsb2dnZWQgaW4gdXNlcidzIGF0dHJpYnV0ZXMuXG4gICAqL1xuICB1cGRhdGVVc2VyQXR0cmlidXRlcyhhdHRyaWJ1dGVzOiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCk6IHZvaWQgPT4ge1xuICAgICAgLy8gcHJlcGFyZSB0aGUgYXR0cmlidXRlcyB3ZSB3YW50IHRvIGNoYW5nZVxuICAgICAgY29uc3QgYXR0cnMgPSBuZXcgQXJyYXk8YW55PigpO1xuICAgICAgZm9yIChjb25zdCBwcm9wIGluIGF0dHJpYnV0ZXMpXG4gICAgICAgIGlmIChhdHRyaWJ1dGVzW3Byb3BdICE9PSB1bmRlZmluZWQpIGF0dHJzLnB1c2godGhpcy5wcmVwYXJlVXNlckF0dHJpYnV0ZShwcm9wLCBhdHRyaWJ1dGVzW3Byb3BdKSk7XG4gICAgICBjb25zdCB1c2VyID0gdGhpcy51c2VyUG9vbC5nZXRDdXJyZW50VXNlcigpO1xuICAgICAgaWYgKCF1c2VyKSByZXR1cm4gcmVqZWN0KCk7XG4gICAgICAvLyB3ZSBuZWVkIHRvIGdldCB0aGUgc2Vzc2lvbiBiZWZvcmUgdG8gbWFrZSBjaGFuZ2VzXG4gICAgICB1c2VyLmdldFNlc3Npb24oKGVycjogRXJyb3IpOiB2b2lkID0+IHtcbiAgICAgICAgaWYgKGVycikgcmVqZWN0KGVycik7XG4gICAgICAgIGVsc2UgdXNlci51cGRhdGVBdHRyaWJ1dGVzKGF0dHJzLCAoZTogRXJyb3IpOiB2b2lkID0+IChlID8gcmVqZWN0KGUpIDogcmVzb2x2ZSgpKSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB0aGUgcGFzc3dvcmQgYWdhaW5zdCB0aGUgcG9saWN5IHNldCBpbiB0aGUgZW52aXJvbm1lbnRzIGNvbmZpZ3VyYXRpb24uXG4gICAqIEluIGNhc2UgdGhlcmUgYXJlIGVycm9ycywgdGhleSBhcmUgcmV0dXJuZWQgYXMgYW4gYXJyYXkgb2Ygc3RyaW5ncy5cbiAgICovXG4gIHZhbGlkYXRlUGFzc3dvcmRBZ2FpbnN0UG9saWN5KHBhc3N3b3JkOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGlmIChwYXNzd29yZD8udHJpbSgpLmxlbmd0aCA8IHRoaXMucGFzc3dvcmRQb2xpY3kubWluTGVuZ3RoKSBlcnJvcnMucHVzaCgnTUlOX0xFTkdUSCcpO1xuICAgIGlmICh0aGlzLnBhc3N3b3JkUG9saWN5LnJlcXVpcmVEaWdpdHMgJiYgIS9cXGQvLnRlc3QocGFzc3dvcmQpKSBlcnJvcnMucHVzaCgnUkVRVUlSRV9ESUdJVFMnKTtcbiAgICBpZiAodGhpcy5wYXNzd29yZFBvbGljeS5yZXF1aXJlTG93ZXJjYXNlICYmICEvW2Etel0vLnRlc3QocGFzc3dvcmQpKSBlcnJvcnMucHVzaCgnUkVRVUlSRV9MT1dFUkNBU0UnKTtcbiAgICBpZiAodGhpcy5wYXNzd29yZFBvbGljeS5yZXF1aXJlU3ltYm9scyAmJiAhL1tcXF5cXCRcXCpcXC5cXF9cXH5cXGBcXCtcXD1AXFwhXFw/XFw+XFw8XFw6XFw7XFxcXFxcLFxcI1xcJVxcJl0vLnRlc3QocGFzc3dvcmQpKVxuICAgICAgZXJyb3JzLnB1c2goJ1JFUVVJUkVfU1lNQk9MUycpO1xuICAgIGlmICh0aGlzLnBhc3N3b3JkUG9saWN5LnJlcXVpcmVVcHBlcmNhc2UgJiYgIS9bQS1aXS8udGVzdChwYXNzd29yZCkpIGVycm9ycy5wdXNoKCdSRVFVSVJFX1VQUEVSQ0FTRScpO1xuICAgIHJldHVybiBlcnJvcnM7XG4gIH1cbiAgLyoqXG4gICAqIFZhbGlkYXRlIHRoZSBwYXNzd29yZCBhZ2FpbnN0IG9mZmxpbmUgYW5kIG9ubGluZSBkYXRhYmFzZXMsIHRvIGF2b2lkIGNvbW1vbiBhbmQgZXhwbG9pdGVkIHBhc3N3b3Jkcy5cbiAgICovXG4gIGFzeW5jIHZhbGlkYXRlUGFzc3dvcmRBZ2FpbnN0RGF0YWJhc2VzKHBhc3N3b3JkOiBzdHJpbmcsIGN1c3RvbVN0cmluZ3NUb0F2b2lkPzogc3RyaW5nW10pOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgY29uc3QgZXJyb3JzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGxldCBwd2QgPSAocGFzc3dvcmQgfHwgJycpLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICAgIGNvbnN0IHB3ZENvbnRhaW5zID0gKHN0cjogc3RyaW5nKTogYm9vbGVhbiA9PiBwd2QuaW5jbHVkZXMoKHN0ciB8fCAnJykudHJpbSgpLnRvTG93ZXJDYXNlKCkpO1xuICAgIGNvbnN0IHByb2plY3RSZWZlcmVuY2VzVG9Bdm9pZCA9IFtcbiAgICAgIHRoaXMuX2Vudi5pZGVhLnByb2plY3QsXG4gICAgICB0aGlzLl9lbnYuaWRlYS5hdXRoLnRpdGxlLFxuICAgICAgdGhpcy5fdHJhbnNsYXRlLl8oJ0NPTU1PTi5BUFBfTkFNRScpXG4gICAgXTtcbiAgICBpZiAocHJvamVjdFJlZmVyZW5jZXNUb0F2b2lkLnNvbWUoeCA9PiBwd2RDb250YWlucyh4KSkpIGVycm9ycy5wdXNoKCdDT01NT05fUEFTU1dPUkRfUFJPSkVDVCcpO1xuICAgIGlmIChjdXN0b21TdHJpbmdzVG9Bdm9pZCAmJiBjdXN0b21TdHJpbmdzVG9Bdm9pZC5zb21lKHggPT4gcHdkQ29udGFpbnMoeCkpKSBlcnJvcnMucHVzaCgnQ09NTU9OX1BBU1NXT1JEX0NVU1RPTScpO1xuICAgIGlmIChDT01NT05fUEFTU1dPUkRTX1RPUF8xMDAwLnNvbWUoeCA9PiBwd2RDb250YWlucyh4KSkpIGVycm9ycy5wdXNoKCdDT01NT05fUEFTU1dPUkRfSU5URVJOQUwnKTtcbiAgICBpZiAoZXJyb3JzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgY29uc3QgcHdkU0hBMSA9IGF3YWl0IFNIQTEocGFzc3dvcmQpO1xuICAgICAgaWYgKHB3ZFNIQTEpIHtcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2goJ2h0dHBzOi8vYXBpLnB3bmVkcGFzc3dvcmRzLmNvbS9yYW5nZS8nLmNvbmNhdChwd2RTSEExLnNsaWNlKDAsIDUpKSk7XG4gICAgICAgIGlmIChyZXMuc3RhdHVzID09PSAyMDApIHtcbiAgICAgICAgICBjb25zdCBwd25lZFBhc3N3b3Jkc1Jhd1N1ZmZpeGVzID0gYXdhaXQgcmVzLnRleHQoKTtcbiAgICAgICAgICBpZiAocHduZWRQYXNzd29yZHNSYXdTdWZmaXhlcy5pbmNsdWRlcyhwd2RTSEExLnNsaWNlKDUpKSkgZXJyb3JzLnB1c2goJ0NPTU1PTl9QQVNTV09SRF9FWFRFUk5BTCcpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBlcnJvcnM7XG4gIH1cbiAgLyoqXG4gICAqIEdldCBhIGNvbXBsZXRlIHBhc3N3b3JkIHBvbGljeSBwYXR0ZXJuLCBiYXNlZCBvbiB0aGUgZW52aXJvbm1lbnRzIGNvbmZpZ3VyYXRpb24sIHRvIHVzZSBvbiBwYXNzd29yZCBpbnB1dCBmaWVsZHMuXG4gICAqIE5vdGU6IHNvbWUgb2YgdGhlIHN5bWJvbHMgY291bGRuJ3QgYmUgaW5jbHVkZWQgYmVjYXVzZSB1bnN1cHBvcnRlZCBieSB0aGUgaW5wdXRbcGF0dGVybl0gYXR0cmlidXRlLlxuICAgKi9cbiAgZ2V0UGFzc3dvcmRQb2xpY3lQYXR0ZXJuRm9ySW5wdXQoKTogc3RyaW5nIHtcbiAgICBsZXQgcGF0dGVybiA9ICcnO1xuICAgIGlmICh0aGlzLnBhc3N3b3JkUG9saWN5LnJlcXVpcmVEaWdpdHMpIHBhdHRlcm4gKz0gYCg/PS4qWzAtOV0pYDtcbiAgICBpZiAodGhpcy5wYXNzd29yZFBvbGljeS5yZXF1aXJlTG93ZXJjYXNlKSBwYXR0ZXJuICs9IGAoPz0uKlthLXpdKWA7XG4gICAgaWYgKHRoaXMucGFzc3dvcmRQb2xpY3kucmVxdWlyZVN5bWJvbHMpIHBhdHRlcm4gKz0gYCg/PS4qW1xcXlxcJFxcKlxcLlxcX1xcflxcYFxcK1xcPUBcXCFcXD9cXD5cXDxcXDpcXDtcXFxcXFwsXFwjXFwlXFwmXSlgO1xuICAgIGlmICh0aGlzLnBhc3N3b3JkUG9saWN5LnJlcXVpcmVVcHBlcmNhc2UpIHBhdHRlcm4gKz0gYCg/PS4qW0EtWl0pYDtcbiAgICBwYXR0ZXJuICs9IGAueyR7dGhpcy5wYXNzd29yZFBvbGljeS5taW5MZW5ndGh9LH1gO1xuICAgIHJldHVybiBwYXR0ZXJuO1xuICB9XG59XG5cbi8qKlxuICogVGhlIHBvc3NpYmxlIGFjdGlvbnMgZm9sbG93aW5nIGEgc3VjY2Vzc2Z1bCBsb2dpbi5cbiAqL1xuZXhwb3J0IGVudW0gTG9naW5PdXRjb21lQWN0aW9ucyB7XG4gIE5PTkUgPSAnbm9uZScsXG4gIE5FV19QQVNTV09SRCA9ICduZXdQYXNzd29yZCcsXG4gIE1GQV9DSEFMTEVOR0UgPSAnbWZhQ2hhbGxlbmdlJyxcbiAgTUZBX1NFVFVQID0gJ21mYVNldHVwJ1xufVxuXG4vKipcbiAqIEdldCB0aGUgU0hBMSBoZXggdXBwZXJjYXNlIGhhc2ggb2YgYSBzdHJpbmcsIHVzaW5nIHdlYiBjcnlwdG8uXG4gKi9cbmNvbnN0IFNIQTEgPSBhc3luYyAoc3RyOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+ID0+IHtcbiAgaWYgKCF3aW5kb3cuY3J5cHRvKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgbXNnVWludDggPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoc3RyKTtcbiAgY29uc3QgaGFzaEJ1ZmZlciA9IGF3YWl0IHdpbmRvdy5jcnlwdG8uc3VidGxlLmRpZ2VzdCgnU0hBLTEnLCBtc2dVaW50OCk7XG4gIGNvbnN0IGhhc2hBcnJheSA9IEFycmF5LmZyb20obmV3IFVpbnQ4QXJyYXkoaGFzaEJ1ZmZlcikpO1xuICBjb25zdCBoYXNoSGV4ID0gaGFzaEFycmF5Lm1hcChiID0+IGIudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsICcwJykpLmpvaW4oJycpO1xuICByZXR1cm4gaGFzaEhleC50b1VwcGVyQ2FzZSgpO1xufTtcbiJdfQ==