@keycloakify/angular 0.0.1-rc.7 → 0.0.1-rc.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/login/components/user-profile-form-fields/user-profile-form-fields.component.d.ts +1 -0
- package/login/components/user-profile-form-fields/user-profile-form-fields.component.js +8 -5
- package/login/pages/idp-review-user-profile/idp-review-user-profile.component.d.ts +5 -8
- package/login/pages/idp-review-user-profile/idp-review-user-profile.component.js +16 -20
- package/login/pages/login-update-profile/login-update-profile.component.d.ts +6 -1
- package/login/pages/login-update-profile/login-update-profile.component.js +17 -9
- package/login/pages/register/register.component.d.ts +6 -1
- package/login/pages/register/register.component.js +17 -10
- package/login/pages/update-email/update-email.component.d.ts +6 -1
- package/login/pages/update-email/update-email.component.js +17 -9
- package/login/providers/keycloakify-angular.providers.d.ts +0 -1
- package/login/providers/keycloakify-angular.providers.js +2 -7
- package/login/services/submit.service.d.ts +9 -0
- package/login/services/submit.service.js +20 -0
- package/package.json +4 -4
- package/src/login/components/user-profile-form-fields/user-profile-form-fields.component.html +0 -3
- package/src/login/components/user-profile-form-fields/user-profile-form-fields.component.ts +9 -4
- package/src/login/pages/idp-review-user-profile/idp-review-user-profile.component.html +2 -2
- package/src/login/pages/idp-review-user-profile/idp-review-user-profile.component.ts +12 -19
- package/src/login/pages/login-update-profile/login-update-profile.component.html +2 -3
- package/src/login/pages/login-update-profile/login-update-profile.component.ts +14 -2
- package/src/login/pages/register/register.component.html +2 -2
- package/src/login/pages/register/register.component.ts +14 -3
- package/src/login/pages/update-email/update-email.component.html +2 -2
- package/src/login/pages/update-email/update-email.component.ts +15 -2
- package/src/login/providers/keycloakify-angular.providers.ts +1 -7
- package/src/login/services/submit.service.ts +12 -0
- package/login/tokens/user-profile-form-fields-ejected-path.token.d.ts +0 -2
- package/login/tokens/user-profile-form-fields-ejected-path.token.js +0 -3
- package/src/login/tokens/user-profile-form-fields-ejected-path.token.ts +0 -3
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { NgComponentOutlet } from '@angular/common';
|
|
2
|
+
import { ChangeDetectionStrategy, Component, forwardRef, inject, input, signal, Type } from '@angular/core';
|
|
3
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
3
4
|
import { USE_DEFAULT_CSS } from '@keycloakify/angular/lib/tokens/use-default-css.token';
|
|
4
5
|
import { ComponentReference } from '@keycloakify/angular/login/classes/component-reference.class';
|
|
5
6
|
import { UserProfileFormFieldsComponent } from '@keycloakify/angular/login/components/user-profile-form-fields/user-profile-form-fields.component';
|
|
@@ -8,15 +9,14 @@ import { KcClassDirective } from '@keycloakify/angular/login/directives/kc-class
|
|
|
8
9
|
import { LOGIN_CLASSES } from '@keycloakify/angular/login/tokens/classes.token';
|
|
9
10
|
import { LOGIN_I18N } from '@keycloakify/angular/login/tokens/i18n.token';
|
|
10
11
|
import { KC_LOGIN_CONTEXT } from '@keycloakify/angular/login/tokens/kc-context.token';
|
|
11
|
-
import { USER_PROFILE_FORM_FIELDS_EJECTED_PATH } from '@keycloakify/angular/login/tokens/user-profile-form-fields-ejected-path.token';
|
|
12
12
|
import { type ClassKey } from 'keycloakify/login/lib/kcClsx';
|
|
13
|
-
import { from, Observable, tap } from 'rxjs';
|
|
14
13
|
import { type I18n } from '../../i18n';
|
|
15
14
|
import { type KcContext } from '../../KcContext';
|
|
15
|
+
import { SubmitService } from '@keycloakify/angular/login/services/submit.service';
|
|
16
16
|
|
|
17
17
|
@Component({
|
|
18
18
|
standalone: true,
|
|
19
|
-
imports: [TemplateComponent, KcClassDirective, NgComponentOutlet
|
|
19
|
+
imports: [TemplateComponent, KcClassDirective, NgComponentOutlet],
|
|
20
20
|
selector: 'kc-root',
|
|
21
21
|
templateUrl: 'idp-review-user-profile.component.html',
|
|
22
22
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
@@ -27,8 +27,8 @@ import { type KcContext } from '../../KcContext';
|
|
|
27
27
|
}
|
|
28
28
|
]
|
|
29
29
|
})
|
|
30
|
-
export class IdpReviewUserProfileComponent extends ComponentReference
|
|
31
|
-
|
|
30
|
+
export class IdpReviewUserProfileComponent extends ComponentReference {
|
|
31
|
+
#submitService = inject(SubmitService);
|
|
32
32
|
|
|
33
33
|
kcContext = inject<Extract<KcContext, { pageId: 'idp-review-user-profile.ftl' }>>(KC_LOGIN_CONTEXT);
|
|
34
34
|
displayRequiredFields = input(true);
|
|
@@ -41,20 +41,13 @@ export class IdpReviewUserProfileComponent extends ComponentReference implements
|
|
|
41
41
|
displayInfo: boolean = false;
|
|
42
42
|
displayMessage: boolean = !this.kcContext?.messagesPerField?.existsError('global');
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
userProfileFormFields = input<Type<UserProfileFormFieldsComponent>>();
|
|
45
|
+
|
|
46
46
|
constructor() {
|
|
47
47
|
super();
|
|
48
|
-
this.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
'../../components/user-profile-form-fields/user-profile-form-fields.component'
|
|
52
|
-
).then(c => c.UserProfileFormFieldsComponent)
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
ngAfterContentInit(): void {
|
|
57
|
-
this.userProfileFormFields?.onIsFormSubmittable?.subscribe(submittable => this.isFormSubmittable.set(submittable));
|
|
48
|
+
this.#submitService.isSubmittable.pipe(takeUntilDestroyed()).subscribe(submittable => {
|
|
49
|
+
this.isFormSubmittable.set(submittable);
|
|
50
|
+
});
|
|
58
51
|
}
|
|
59
52
|
|
|
60
53
|
onCallback() {
|
|
@@ -17,8 +17,7 @@
|
|
|
17
17
|
[action]="url.loginAction"
|
|
18
18
|
method="post"
|
|
19
19
|
>
|
|
20
|
-
<
|
|
21
|
-
|
|
20
|
+
<ng-container [ngComponentOutlet]="userProfileFormFields() ?? null"></ng-container>
|
|
22
21
|
<div [kcClass]="'kcFormGroupClass'">
|
|
23
22
|
<div
|
|
24
23
|
id="kc-form-options"
|
|
@@ -31,7 +30,7 @@
|
|
|
31
30
|
[kcClass]="'kcFormButtonsClass'"
|
|
32
31
|
>
|
|
33
32
|
<input
|
|
34
|
-
[disabled]="!isFormSubmittable"
|
|
33
|
+
[disabled]="!isFormSubmittable()"
|
|
35
34
|
[kcClass]="{
|
|
36
35
|
kcButtonClass: true,
|
|
37
36
|
kcButtonPrimaryClass: true,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NgComponentOutlet } from '@angular/common';
|
|
2
|
+
import { ChangeDetectionStrategy, Component, forwardRef, inject, input, signal, Type } from '@angular/core';
|
|
3
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
2
4
|
import { USE_DEFAULT_CSS } from '@keycloakify/angular/lib/tokens/use-default-css.token';
|
|
3
5
|
import { ComponentReference } from '@keycloakify/angular/login/classes/component-reference.class';
|
|
4
6
|
import { UserProfileFormFieldsComponent } from '@keycloakify/angular/login/components/user-profile-form-fields/user-profile-form-fields.component';
|
|
@@ -10,10 +12,11 @@ import { KC_LOGIN_CONTEXT } from '@keycloakify/angular/login/tokens/kc-context.t
|
|
|
10
12
|
import { type ClassKey } from 'keycloakify/login/lib/kcClsx';
|
|
11
13
|
import { type I18n } from '../../i18n';
|
|
12
14
|
import { type KcContext } from '../../KcContext';
|
|
15
|
+
import { SubmitService } from '@keycloakify/angular/login/services/submit.service';
|
|
13
16
|
|
|
14
17
|
@Component({
|
|
15
18
|
standalone: true,
|
|
16
|
-
imports: [TemplateComponent, KcClassDirective,
|
|
19
|
+
imports: [TemplateComponent, KcClassDirective, NgComponentOutlet],
|
|
17
20
|
selector: 'kc-root',
|
|
18
21
|
templateUrl: 'login-update-profile.component.html',
|
|
19
22
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
@@ -25,6 +28,7 @@ import { type KcContext } from '../../KcContext';
|
|
|
25
28
|
]
|
|
26
29
|
})
|
|
27
30
|
export class LoginUpdateProfileComponent extends ComponentReference {
|
|
31
|
+
#submitService = inject(SubmitService);
|
|
28
32
|
kcContext = inject<Extract<KcContext, { pageId: 'login-update-profile.ftl' }>>(KC_LOGIN_CONTEXT);
|
|
29
33
|
i18n = inject<I18n>(LOGIN_I18N);
|
|
30
34
|
override doUseDefaultCss = inject<boolean>(USE_DEFAULT_CSS);
|
|
@@ -36,4 +40,12 @@ export class LoginUpdateProfileComponent extends ComponentReference {
|
|
|
36
40
|
displayMessage: boolean = this.kcContext.messagesPerField.exists('global');
|
|
37
41
|
|
|
38
42
|
isFormSubmittable = signal(false);
|
|
43
|
+
|
|
44
|
+
userProfileFormFields = input<Type<UserProfileFormFieldsComponent>>();
|
|
45
|
+
constructor() {
|
|
46
|
+
super();
|
|
47
|
+
this.#submitService.isSubmittable.pipe(takeUntilDestroyed()).subscribe(submittable => {
|
|
48
|
+
this.isFormSubmittable.set(submittable);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
39
51
|
}
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
[action]="url.registrationAction"
|
|
25
25
|
method="post"
|
|
26
26
|
>
|
|
27
|
-
<
|
|
27
|
+
<ng-container [ngComponentOutlet]="userProfileFormFields() ?? null"></ng-container>
|
|
28
28
|
@if (termsAcceptanceRequired) {
|
|
29
29
|
<div className="form-group">
|
|
30
30
|
<div [kcClass]="'kcInputWrapperClass'">
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
[kcClass]="'kcFormButtonsClass'"
|
|
114
114
|
>
|
|
115
115
|
<input
|
|
116
|
-
[disabled]="!isFormSubmittable || (termsAcceptanceRequired && !areTermsAccepted)"
|
|
116
|
+
[disabled]="!isFormSubmittable() || (termsAcceptanceRequired && !areTermsAccepted())"
|
|
117
117
|
[kcClass]="['kcButtonClass', 'kcButtonPrimaryClass', 'kcButtonBlockClass', 'kcButtonLargeClass']"
|
|
118
118
|
type="submit"
|
|
119
119
|
[value]="i18n.msgStr('doRegister')"
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { AsyncPipe, NgClass } from '@angular/common';
|
|
2
|
-
import { ChangeDetectionStrategy, Component, forwardRef, inject, input, signal } from '@angular/core';
|
|
1
|
+
import { AsyncPipe, NgClass, NgComponentOutlet } from '@angular/common';
|
|
2
|
+
import { ChangeDetectionStrategy, Component, forwardRef, inject, input, signal, Type } from '@angular/core';
|
|
3
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
3
4
|
import { USE_DEFAULT_CSS } from '@keycloakify/angular/lib/tokens/use-default-css.token';
|
|
4
5
|
import { ComponentReference } from '@keycloakify/angular/login/classes/component-reference.class';
|
|
5
6
|
import { UserProfileFormFieldsComponent } from '@keycloakify/angular/login/components/user-profile-form-fields/user-profile-form-fields.component';
|
|
@@ -12,13 +13,14 @@ import { KC_LOGIN_CONTEXT } from '@keycloakify/angular/login/tokens/kc-context.t
|
|
|
12
13
|
import { type ClassKey } from 'keycloakify/login/lib/kcClsx';
|
|
13
14
|
import { type I18n } from '../../i18n';
|
|
14
15
|
import { type KcContext } from '../../KcContext';
|
|
16
|
+
import { SubmitService } from '@keycloakify/angular/login/services/submit.service';
|
|
15
17
|
|
|
16
18
|
@Component({
|
|
17
19
|
selector: 'kc-root',
|
|
18
20
|
templateUrl: './register.component.html',
|
|
19
21
|
standalone: true,
|
|
20
22
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
21
|
-
imports: [KcClassDirective, AsyncPipe, KcSanitizePipe, NgClass, TemplateComponent,
|
|
23
|
+
imports: [KcClassDirective, AsyncPipe, KcSanitizePipe, NgClass, TemplateComponent, NgComponentOutlet],
|
|
22
24
|
providers: [
|
|
23
25
|
{
|
|
24
26
|
provide: ComponentReference,
|
|
@@ -27,6 +29,7 @@ import { type KcContext } from '../../KcContext';
|
|
|
27
29
|
]
|
|
28
30
|
})
|
|
29
31
|
export class RegisterComponent extends ComponentReference {
|
|
32
|
+
#submitService = inject(SubmitService);
|
|
30
33
|
kcContext = inject<Extract<KcContext, { pageId: 'register.ftl' }>>(KC_LOGIN_CONTEXT);
|
|
31
34
|
displayRequiredFields = input(false);
|
|
32
35
|
documentTitle = input<string>();
|
|
@@ -39,6 +42,14 @@ export class RegisterComponent extends ComponentReference {
|
|
|
39
42
|
displayInfo: boolean = false;
|
|
40
43
|
displayMessage: boolean = !this.kcContext?.messagesPerField?.existsError('global');
|
|
41
44
|
|
|
45
|
+
userProfileFormFields = input<Type<UserProfileFormFieldsComponent>>();
|
|
46
|
+
|
|
47
|
+
constructor() {
|
|
48
|
+
super();
|
|
49
|
+
this.#submitService.isSubmittable.pipe(takeUntilDestroyed()).subscribe(submittable => {
|
|
50
|
+
this.isFormSubmittable.set(submittable);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
42
53
|
onCallback() {
|
|
43
54
|
(document.getElementById('kc-register-form') as HTMLFormElement).submit();
|
|
44
55
|
}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
[action]="url.loginAction"
|
|
18
18
|
method="post"
|
|
19
19
|
>
|
|
20
|
-
<
|
|
20
|
+
<ng-container [ngComponentOutlet]="userProfileFormFields() ?? null"></ng-container>
|
|
21
21
|
<div [kcClass]="'kcFormGroupClass'">
|
|
22
22
|
<div
|
|
23
23
|
id="kc-form-options"
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
[kcClass]="'kcFormButtonsClass'"
|
|
32
32
|
>
|
|
33
33
|
<input
|
|
34
|
-
[disabled]="!isFormSubmittable"
|
|
34
|
+
[disabled]="!isFormSubmittable()"
|
|
35
35
|
[kcClass]="{
|
|
36
36
|
kcButtonClass: true,
|
|
37
37
|
kcButtonPrimaryClass: true,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NgComponentOutlet } from '@angular/common';
|
|
2
|
+
import { ChangeDetectionStrategy, Component, forwardRef, inject, input, signal, Type } from '@angular/core';
|
|
3
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
2
4
|
import { USE_DEFAULT_CSS } from '@keycloakify/angular/lib/tokens/use-default-css.token';
|
|
3
5
|
import { ComponentReference } from '@keycloakify/angular/login/classes/component-reference.class';
|
|
4
6
|
import { LogoutOtherSessionsComponent } from '@keycloakify/angular/login/components/logout-other-sessions/logout-other-sessions.component';
|
|
@@ -11,10 +13,11 @@ import { KC_LOGIN_CONTEXT } from '@keycloakify/angular/login/tokens/kc-context.t
|
|
|
11
13
|
import { type ClassKey } from 'keycloakify/login/lib/kcClsx';
|
|
12
14
|
import { type I18n } from '../../i18n';
|
|
13
15
|
import { type KcContext } from '../../KcContext';
|
|
16
|
+
import { SubmitService } from '@keycloakify/angular/login/services/submit.service';
|
|
14
17
|
|
|
15
18
|
@Component({
|
|
16
19
|
standalone: true,
|
|
17
|
-
imports: [TemplateComponent, KcClassDirective,
|
|
20
|
+
imports: [TemplateComponent, KcClassDirective, NgComponentOutlet, LogoutOtherSessionsComponent],
|
|
18
21
|
selector: 'kc-root',
|
|
19
22
|
templateUrl: 'update-email.component.html',
|
|
20
23
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
@@ -26,6 +29,7 @@ import { type KcContext } from '../../KcContext';
|
|
|
26
29
|
]
|
|
27
30
|
})
|
|
28
31
|
export class UpdateEmailComponent extends ComponentReference {
|
|
32
|
+
#submitService = inject(SubmitService);
|
|
29
33
|
kcContext = inject<Extract<KcContext, { pageId: 'update-email.ftl' }>>(KC_LOGIN_CONTEXT);
|
|
30
34
|
i18n = inject<I18n>(LOGIN_I18N);
|
|
31
35
|
override doUseDefaultCss = inject<boolean>(USE_DEFAULT_CSS);
|
|
@@ -36,4 +40,13 @@ export class UpdateEmailComponent extends ComponentReference {
|
|
|
36
40
|
displayInfo: boolean = false;
|
|
37
41
|
displayMessage: boolean = this.kcContext.messagesPerField.exists('global');
|
|
38
42
|
isFormSubmittable = signal(false);
|
|
43
|
+
|
|
44
|
+
userProfileFormFields = input<Type<UserProfileFormFieldsComponent>>();
|
|
45
|
+
|
|
46
|
+
constructor() {
|
|
47
|
+
super();
|
|
48
|
+
this.#submitService.isSubmittable.pipe(takeUntilDestroyed()).subscribe(submittable => {
|
|
49
|
+
this.isFormSubmittable.set(submittable);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
39
52
|
}
|
|
@@ -5,7 +5,6 @@ import { LOGIN_CLASSES } from '@keycloakify/angular/login/tokens/classes.token';
|
|
|
5
5
|
import { LOGIN_I18N } from '@keycloakify/angular/login/tokens/i18n.token';
|
|
6
6
|
import { KC_LOGIN_CONTEXT } from '@keycloakify/angular/login/tokens/kc-context.token';
|
|
7
7
|
import { DO_MAKE_USER_CONFIRM_PASSWORD } from '@keycloakify/angular/login/tokens/make-user-confirm-password.token';
|
|
8
|
-
import { USER_PROFILE_FORM_FIELDS_EJECTED_PATH } from '@keycloakify/angular/login/tokens/user-profile-form-fields-ejected-path.token';
|
|
9
8
|
import { type KcContextLike } from 'keycloakify/login/i18n/noJsx';
|
|
10
9
|
import { type ClassKey } from 'keycloakify/login/lib/kcClsx';
|
|
11
10
|
import { type KcContext } from '../KcContext';
|
|
@@ -15,7 +14,6 @@ export type KeycloakifyAngularLoginConfig = {
|
|
|
15
14
|
doMakeUserConfirmPassword?: boolean;
|
|
16
15
|
doUseDefaultCss?: boolean;
|
|
17
16
|
classes?: { [key in ClassKey]?: string };
|
|
18
|
-
userProfileFormFieldsEjectedPath?: string;
|
|
19
17
|
getI18n: (params: { kcContext: KcContextLike }) => {
|
|
20
18
|
i18n: unknown;
|
|
21
19
|
prI18n_currentLanguage: Promise<unknown> | undefined;
|
|
@@ -66,9 +64,5 @@ export const provideKeycloakifyAngularLogin = (config: KeycloakifyAngularLoginCo
|
|
|
66
64
|
deps: [I18nService]
|
|
67
65
|
},
|
|
68
66
|
{ provide: USE_DEFAULT_CSS, useValue: config?.doUseDefaultCss ?? true },
|
|
69
|
-
{ provide: LOGIN_CLASSES, useValue: config?.classes ?? {} }
|
|
70
|
-
{
|
|
71
|
-
provide: USER_PROFILE_FORM_FIELDS_EJECTED_PATH,
|
|
72
|
-
useValue: config.userProfileFormFieldsEjectedPath
|
|
73
|
-
}
|
|
67
|
+
{ provide: LOGIN_CLASSES, useValue: config?.classes ?? {} }
|
|
74
68
|
]);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { Observable, BehaviorSubject } from 'rxjs';
|
|
3
|
+
|
|
4
|
+
@Injectable({ providedIn: 'root' })
|
|
5
|
+
export class SubmitService {
|
|
6
|
+
#submittableSubj: BehaviorSubject<boolean> = new BehaviorSubject(false);
|
|
7
|
+
isSubmittable: Observable<boolean> = this.#submittableSubj.asObservable();
|
|
8
|
+
|
|
9
|
+
setIsSubmittable(submittable: boolean) {
|
|
10
|
+
this.#submittableSubj.next(submittable);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import { InjectionToken } from "@angular/core";
|
|
2
|
-
export const USER_PROFILE_FORM_FIELDS_EJECTED_PATH = new InjectionToken('profile form fields ejected path');
|
|
3
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1wcm9maWxlLWZvcm0tZmllbGRzLWVqZWN0ZWQtcGF0aC50b2tlbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2tleWNsb2FraWZ5LWFuZ3VsYXIvc3JjL2xvZ2luL3Rva2Vucy91c2VyLXByb2ZpbGUtZm9ybS1maWVsZHMtZWplY3RlZC1wYXRoLnRva2VuLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFL0MsTUFBTSxDQUFDLE1BQU0scUNBQXFDLEdBQUcsSUFBSSxjQUFjLENBQVMsa0NBQWtDLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGlvblRva2VuIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcblxuZXhwb3J0IGNvbnN0IFVTRVJfUFJPRklMRV9GT1JNX0ZJRUxEU19FSkVDVEVEX1BBVEggPSBuZXcgSW5qZWN0aW9uVG9rZW48c3RyaW5nPigncHJvZmlsZSBmb3JtIGZpZWxkcyBlamVjdGVkIHBhdGgnKSJdfQ==
|