@byuhbll/components 5.3.0-rc.2 → 6.0.0-rc.0.5

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 (49) hide show
  1. package/fesm2022/byuhbll-components.mjs +107 -116
  2. package/fesm2022/byuhbll-components.mjs.map +1 -1
  3. package/lib/ss-search-bar/advanced-search/advanced-search.component.d.ts +1 -4
  4. package/lib/ss-search-bar/models/advanced-search.model.d.ts +3 -3
  5. package/lib/ss-search-bar/models/search-scope.model.d.ts +1 -1
  6. package/lib/ss-search-bar/simple-search/simple-search.component.d.ts +1 -1
  7. package/lib/status-button/status-button.component.d.ts +1 -1
  8. package/package.json +4 -6
  9. package/esm2022/byuhbll-components.mjs +0 -5
  10. package/esm2022/lib/animations/animations.mjs +0 -22
  11. package/esm2022/lib/button/button.component.mjs +0 -81
  12. package/esm2022/lib/button-group/button-group.component.mjs +0 -155
  13. package/esm2022/lib/checkbox/checkbox.component.mjs +0 -15
  14. package/esm2022/lib/contact-utils.mjs +0 -41
  15. package/esm2022/lib/copy-tooltip/copy-tooltip.component.mjs +0 -49
  16. package/esm2022/lib/expand-collapse/expand-collapse.component.mjs +0 -31
  17. package/esm2022/lib/hbll-footer/hbll-footer.component.mjs +0 -111
  18. package/esm2022/lib/hbll-header/hbll-header.component.mjs +0 -142
  19. package/esm2022/lib/hbll-header/models/library-hours.mjs +0 -2
  20. package/esm2022/lib/hbll-header/nav-bar/nav-bar.component.mjs +0 -352
  21. package/esm2022/lib/hbll-header/nav-bar-dropdown/nav-bar-dropdown.component.mjs +0 -57
  22. package/esm2022/lib/hbll-header/pipes/library-hours.pipe.mjs +0 -31
  23. package/esm2022/lib/hbll-header/pipes/truncate.pipe.mjs +0 -17
  24. package/esm2022/lib/header-with-impersonation/header-with-impersonation.component.mjs +0 -128
  25. package/esm2022/lib/impersonate-modal/impersonate-modal.component.mjs +0 -190
  26. package/esm2022/lib/impersonation-banner/impersonation-banner.component.mjs +0 -151
  27. package/esm2022/lib/impersonation-banner/models/application-access.mjs +0 -7
  28. package/esm2022/lib/impersonation-banner/models/person-summary.mjs +0 -15
  29. package/esm2022/lib/models/token-payload.mjs +0 -2
  30. package/esm2022/lib/multi-select/multi-select.component.mjs +0 -115
  31. package/esm2022/lib/pipes/hbll-item-type-icon.pipe.mjs +0 -128
  32. package/esm2022/lib/snackbar/snackbar.component.mjs +0 -151
  33. package/esm2022/lib/snackbar/snackbar.service.mjs +0 -90
  34. package/esm2022/lib/ss-search-bar/advanced-search/advanced-search.component.mjs +0 -273
  35. package/esm2022/lib/ss-search-bar/constants.mjs +0 -153
  36. package/esm2022/lib/ss-search-bar/date-range/date-range.component.mjs +0 -71
  37. package/esm2022/lib/ss-search-bar/models/advanced-search.model.mjs +0 -5
  38. package/esm2022/lib/ss-search-bar/models/search-config.model.mjs +0 -2
  39. package/esm2022/lib/ss-search-bar/models/search-scope.model.mjs +0 -3
  40. package/esm2022/lib/ss-search-bar/pipes/advanced-field-warning.pipe.mjs +0 -34
  41. package/esm2022/lib/ss-search-bar/pipes/advanced-queries.pipe.mjs +0 -33
  42. package/esm2022/lib/ss-search-bar/pipes/field-by-scope.pipe.mjs +0 -27
  43. package/esm2022/lib/ss-search-bar/simple-search/simple-search.component.mjs +0 -87
  44. package/esm2022/lib/ss-search-bar/ss-search-bar.component.mjs +0 -98
  45. package/esm2022/lib/ss-search-bar/utils.mjs +0 -16
  46. package/esm2022/lib/status-button/status-button.component.mjs +0 -104
  47. package/esm2022/lib/subatomic-components/button-group-item/button-group-item.component.mjs +0 -39
  48. package/esm2022/lib/utils.mjs +0 -7
  49. package/esm2022/public-api.mjs +0 -22
@@ -1,128 +0,0 @@
1
- import { Component, computed, EventEmitter, input, Output, effect, runInInjectionContext, inject, Injector, } from '@angular/core';
2
- import { HbllHeaderComponent } from '../hbll-header/hbll-header.component';
3
- import { ImpersonationBannerComponent } from '../impersonation-banner/impersonation-banner.component';
4
- import { defaultOidcBaseUri, defaultOidcDefaultIdp, ImpersonateModalComponent, } from '../impersonate-modal/impersonate-modal.component';
5
- import { jwtDecode } from 'jwt-decode';
6
- import * as i0 from "@angular/core";
7
- export class HeaderWithImpersonationComponent {
8
- constructor() {
9
- this.accessTokenPayload = input.required();
10
- this.oidcBaseUri = input(defaultOidcBaseUri);
11
- this.oidcDefaultIdp = input(defaultOidcDefaultIdp);
12
- this.mainSiteBaseUrl = input('https://lib.byu.edu');
13
- this.personBaseUri = input('https://apps.lib.byu.edu/person/v2/');
14
- this.myAccountApiBaseUri = input('https://api.lib.byu.edu/v1');
15
- this.login = new EventEmitter();
16
- this.logout = new EventEmitter();
17
- this.endImpersonation = new EventEmitter();
18
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
- this.parsedToken = computed(() => this.accessTokenPayload().token ? jwtDecode(this.accessTokenPayload().token) : null);
20
- this.name = computed(() => (this.parsedToken() ? this.parsedToken()['given_name'] : ''));
21
- this.showImpersonateButton = computed(() => this.parsedToken()
22
- ? !!(!this.isImpersonating() &&
23
- this.parsedToken()['resource_access']['realm-management']?.['roles']?.includes('impersonation'))
24
- : false);
25
- this.showImpersonationModal = false;
26
- this.isImpersonating = computed(() => !!this.parsedToken()?.['impersonator']);
27
- // Inactivity timeout for impersonation
28
- this.activityEvents = [
29
- 'keydown',
30
- 'pointerdown',
31
- 'wheel',
32
- 'scroll',
33
- ];
34
- this.inactivityTimerId = null;
35
- this.inactivityTimeoutMs = 5 * 60 * 1000; // 5 minutes
36
- this.debounceTimerId = null;
37
- this.debounceDelayMs = 250;
38
- this.trackingActive = false;
39
- this.injector = inject(Injector);
40
- /** Reset the inactivity countdown (no-op if not impersonating) */
41
- this.resetInactivityTimer = () => {
42
- if (!this.isImpersonating())
43
- return;
44
- if (this.inactivityTimerId)
45
- clearTimeout(this.inactivityTimerId);
46
- this.inactivityTimerId = window.setTimeout(() => {
47
- this.endImpersonation.emit();
48
- this.stopInactivityTracking();
49
- }, this.inactivityTimeoutMs);
50
- };
51
- /** Debounce activity to avoid hammering resets during event storms */
52
- this.debouncedResetTimer = () => {
53
- if (this.debounceTimerId)
54
- clearTimeout(this.debounceTimerId);
55
- this.debounceTimerId = window.setTimeout(() => {
56
- this.resetInactivityTimer();
57
- }, this.debounceDelayMs);
58
- };
59
- }
60
- ngOnInit() {
61
- // effect can only be used within an injection context (ex: constructor)
62
- runInInjectionContext(this.injector, () => {
63
- effect(() => {
64
- const impersonating = this.isImpersonating();
65
- const token = this.parsedToken();
66
- // when token refreshes after 5 minutes, it leaves a small moment where there is no token
67
- // this prevents dropping inactivtiy timer during that blip
68
- if (!token)
69
- return;
70
- if (impersonating) {
71
- if (!this.trackingActive)
72
- this.startInactivityTracking();
73
- }
74
- else {
75
- if (this.trackingActive)
76
- this.stopInactivityTracking();
77
- }
78
- });
79
- });
80
- }
81
- ngOnDestroy() {
82
- this.stopInactivityTracking();
83
- }
84
- /** Begin listening and start countdown */
85
- startInactivityTracking() {
86
- this.activityEvents.forEach((event) => {
87
- // 'scroll' on document doesn't bubble; use window + capture to catch nested scrolls
88
- const target = event === 'scroll' ? window : document;
89
- const options = event === 'scroll'
90
- ? { passive: true, capture: true }
91
- : { passive: true };
92
- target.addEventListener(event, this.debouncedResetTimer, options);
93
- });
94
- this.trackingActive = true;
95
- this.resetInactivityTimer();
96
- }
97
- /** Remove listeners and clear timers */
98
- stopInactivityTracking() {
99
- this.activityEvents.forEach((event) => {
100
- const target = event === 'scroll' ? window : document;
101
- // IMPORTANT: capture must match how it was added for scroll
102
- const options = event === 'scroll' ? { capture: true } : undefined;
103
- target.removeEventListener(event, this.debouncedResetTimer, options);
104
- });
105
- if (this.inactivityTimerId) {
106
- clearTimeout(this.inactivityTimerId);
107
- this.inactivityTimerId = null;
108
- }
109
- if (this.debounceTimerId) {
110
- clearTimeout(this.debounceTimerId);
111
- this.debounceTimerId = null;
112
- }
113
- this.trackingActive = false;
114
- }
115
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: HeaderWithImpersonationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
116
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.1.0", type: HeaderWithImpersonationComponent, isStandalone: true, selector: "lib-header-with-impersonation", inputs: { accessTokenPayload: { classPropertyName: "accessTokenPayload", publicName: "accessTokenPayload", isSignal: true, isRequired: true, transformFunction: null }, oidcBaseUri: { classPropertyName: "oidcBaseUri", publicName: "oidcBaseUri", isSignal: true, isRequired: false, transformFunction: null }, oidcDefaultIdp: { classPropertyName: "oidcDefaultIdp", publicName: "oidcDefaultIdp", isSignal: true, isRequired: false, transformFunction: null }, mainSiteBaseUrl: { classPropertyName: "mainSiteBaseUrl", publicName: "mainSiteBaseUrl", isSignal: true, isRequired: false, transformFunction: null }, personBaseUri: { classPropertyName: "personBaseUri", publicName: "personBaseUri", isSignal: true, isRequired: false, transformFunction: null }, myAccountApiBaseUri: { classPropertyName: "myAccountApiBaseUri", publicName: "myAccountApiBaseUri", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { login: "login", logout: "logout", endImpersonation: "endImpersonation" }, ngImport: i0, template: "<lib-impersonation-banner\n [accessTokenPayload]=\"accessTokenPayload()\"\n (endImpersonation)=\"endImpersonation.emit()\"\n [personBaseUri]=\"personBaseUri()\"\n [myAccountApiBaseUri]=\"myAccountApiBaseUri()\"\n></lib-impersonation-banner>\n<lib-hbll-header\n [name]=\"name()\"\n [showImpersonateButton]=\"showImpersonateButton()\"\n (openImpersonationModal)=\"showImpersonationModal = true\"\n (login)=\"login.emit()\"\n (logout)=\"logout.emit()\"\n [mainsitebaseurl]=\"mainSiteBaseUrl()\"\n/>\n<lib-impersonate-modal\n [showModal]=\"showImpersonationModal\"\n [oidcBaseUri]=\"oidcBaseUri()\"\n [oidcDefaultIdp]=\"oidcDefaultIdp()\"\n [accessTokenPayload]=\"accessTokenPayload()\"\n (dismiss)=\"showImpersonationModal = false\"\n (init)=\"showImpersonationModal = true\"\n></lib-impersonate-modal>\n", styles: [""], dependencies: [{ kind: "component", type: HbllHeaderComponent, selector: "lib-hbll-header", inputs: ["name", "mainsitebaseurl", "showImpersonateButton"], outputs: ["openImpersonationModal", "login", "logout"] }, { kind: "component", type: ImpersonationBannerComponent, selector: "lib-impersonation-banner", inputs: ["accessTokenPayload", "personBaseUri", "myAccountApiBaseUri"], outputs: ["endImpersonation"] }, { kind: "component", type: ImpersonateModalComponent, selector: "lib-impersonate-modal", inputs: ["showModal", "oidcBaseUri", "oidcDefaultIdp", "accessTokenPayload"], outputs: ["dismiss", "init"] }] }); }
117
- }
118
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: HeaderWithImpersonationComponent, decorators: [{
119
- type: Component,
120
- args: [{ selector: 'lib-header-with-impersonation', standalone: true, imports: [HbllHeaderComponent, ImpersonationBannerComponent, ImpersonateModalComponent], template: "<lib-impersonation-banner\n [accessTokenPayload]=\"accessTokenPayload()\"\n (endImpersonation)=\"endImpersonation.emit()\"\n [personBaseUri]=\"personBaseUri()\"\n [myAccountApiBaseUri]=\"myAccountApiBaseUri()\"\n></lib-impersonation-banner>\n<lib-hbll-header\n [name]=\"name()\"\n [showImpersonateButton]=\"showImpersonateButton()\"\n (openImpersonationModal)=\"showImpersonationModal = true\"\n (login)=\"login.emit()\"\n (logout)=\"logout.emit()\"\n [mainsitebaseurl]=\"mainSiteBaseUrl()\"\n/>\n<lib-impersonate-modal\n [showModal]=\"showImpersonationModal\"\n [oidcBaseUri]=\"oidcBaseUri()\"\n [oidcDefaultIdp]=\"oidcDefaultIdp()\"\n [accessTokenPayload]=\"accessTokenPayload()\"\n (dismiss)=\"showImpersonationModal = false\"\n (init)=\"showImpersonationModal = true\"\n></lib-impersonate-modal>\n" }]
121
- }], propDecorators: { login: [{
122
- type: Output
123
- }], logout: [{
124
- type: Output
125
- }], endImpersonation: [{
126
- type: Output
127
- }] } });
128
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVhZGVyLXdpdGgtaW1wZXJzb25hdGlvbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL3NyYy9saWIvaGVhZGVyLXdpdGgtaW1wZXJzb25hdGlvbi9oZWFkZXItd2l0aC1pbXBlcnNvbmF0aW9uLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMvc3JjL2xpYi9oZWFkZXItd2l0aC1pbXBlcnNvbmF0aW9uL2hlYWRlci13aXRoLWltcGVyc29uYXRpb24uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNILFNBQVMsRUFDVCxRQUFRLEVBQ1IsWUFBWSxFQUNaLEtBQUssRUFDTCxNQUFNLEVBSU4sTUFBTSxFQUNOLHFCQUFxQixFQUNyQixNQUFNLEVBQ04sUUFBUSxHQUNYLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQzNFLE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLHdEQUF3RCxDQUFDO0FBQ3RHLE9BQU8sRUFDSCxrQkFBa0IsRUFDbEIscUJBQXFCLEVBQ3JCLHlCQUF5QixHQUM1QixNQUFNLGtEQUFrRCxDQUFDO0FBRTFELE9BQU8sRUFBRSxTQUFTLEVBQWMsTUFBTSxZQUFZLENBQUM7O0FBU25ELE1BQU0sT0FBTyxnQ0FBZ0M7SUFQN0M7UUFRSSx1QkFBa0IsR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFnQixDQUFDO1FBQ3BELGdCQUFXLEdBQUcsS0FBSyxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDeEMsbUJBQWMsR0FBRyxLQUFLLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUM5QyxvQkFBZSxHQUFHLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQy9DLGtCQUFhLEdBQUcsS0FBSyxDQUFDLHFDQUFxQyxD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a0JBUDVDLFNBQVM7K0JBQ0ksK0JBQStCLGNBQzdCLElBQUksV0FDUCxDQUFDLG1CQUFtQixFQUFFLDRCQUE0QixFQUFFLHlCQUF5QixDQUFDOzhCQVk3RSxLQUFLO3NCQUFkLE1BQU07Z0JBQ0csTUFBTTtzQkFBZixNQUFNO2dCQUNHLGdCQUFnQjtzQkFBekIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICAgQ29tcG9uZW50LFxuICAgIGNvbXB1dGVkLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBpbnB1dCxcbiAgICBPdXRwdXQsXG4gICAgU2lnbmFsLFxuICAgIE9uSW5pdCxcbiAgICBPbkRlc3Ryb3ksXG4gICAgZWZmZWN0LFxuICAgIHJ1bkluSW5qZWN0aW9uQ29udGV4dCxcbiAgICBpbmplY3QsXG4gICAgSW5qZWN0b3IsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSGJsbEhlYWRlckNvbXBvbmVudCB9IGZyb20gJy4uL2hibGwtaGVhZGVyL2hibGwtaGVhZGVyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBJbXBlcnNvbmF0aW9uQmFubmVyQ29tcG9uZW50IH0gZnJvbSAnLi4vaW1wZXJzb25hdGlvbi1iYW5uZXIvaW1wZXJzb25hdGlvbi1iYW5uZXIuY29tcG9uZW50JztcbmltcG9ydCB7XG4gICAgZGVmYXVsdE9pZGNCYXNlVXJpLFxuICAgIGRlZmF1bHRPaWRjRGVmYXVsdElkcCxcbiAgICBJbXBlcnNvbmF0ZU1vZGFsQ29tcG9uZW50LFxufSBmcm9tICcuLi9pbXBlcnNvbmF0ZS1tb2RhbC9pbXBlcnNvbmF0ZS1tb2RhbC5jb21wb25lbnQnO1xuaW1wb3J0IHsgVG9rZW5QYXlsb2FkIH0gZnJvbSAnLi4vbW9kZWxzL3Rva2VuLXBheWxvYWQnO1xuaW1wb3J0IHsgand0RGVjb2RlLCBKd3RQYXlsb2FkIH0gZnJvbSAnand0LWRlY29kZSc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbGliLWhlYWRlci13aXRoLWltcGVyc29uYXRpb24nLFxuICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgaW1wb3J0czogW0hibGxIZWFkZXJDb21wb25lbnQsIEltcGVyc29uYXRpb25CYW5uZXJDb21wb25lbnQsIEltcGVyc29uYXRlTW9kYWxDb21wb25lbnRdLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9oZWFkZXItd2l0aC1pbXBlcnNvbmF0aW9uLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybDogJy4vaGVhZGVyLXdpdGgtaW1wZXJzb25hdGlvbi5jb21wb25lbnQuc2NzcycsXG59KVxuZXhwb3J0IGNsYXNzIEhlYWRlcldpdGhJbXBlcnNvbmF0aW9uQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICAgIGFjY2Vzc1Rva2VuUGF5bG9hZCA9IGlucHV0LnJlcXVpcmVkPFRva2VuUGF5bG9hZD4oKTtcbiAgICBvaWRjQmFzZVVyaSA9IGlucHV0KGRlZmF1bHRPaWRjQmFzZVVyaSk7XG4gICAgb2lkY0RlZmF1bHRJZHAgPSBpbnB1dChkZWZhdWx0T2lkY0RlZmF1bHRJZHApO1xuICAgIG1haW5TaXRlQmFzZVVybCA9IGlucHV0KCdodHRwczovL2xpYi5ieXUuZWR1Jyk7XG4gICAgcGVyc29uQmFzZVVyaSA9IGlucHV0KCdodHRwczovL2FwcHMubGliLmJ5dS5lZHUvcGVyc29uL3YyLycpO1xuICAgIG15QWNjb3VudEFwaUJhc2VVcmkgPSBpbnB1dCgnaHR0cHM6Ly9hcGkubGliLmJ5dS5lZHUvdjEnKTtcblxuICAgIEBPdXRwdXQoKSBsb2dpbiA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgICBAT3V0cHV0KCkgbG9nb3V0ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAgIEBPdXRwdXQoKSBlbmRJbXBlcnNvbmF0aW9uID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBwcm90ZWN0ZWQgcGFyc2VkVG9rZW46IFNpZ25hbDwoSnd0UGF5bG9hZCAmIFJlY29yZDxzdHJpbmcsIGFueT4pIHwgbnVsbD4gPSBjb21wdXRlZCgoKSA9PlxuICAgICAgICB0aGlzLmFjY2Vzc1Rva2VuUGF5bG9hZCgpLnRva2VuID8gand0RGVjb2RlKHRoaXMuYWNjZXNzVG9rZW5QYXlsb2FkKCkudG9rZW4pIDogbnVsbCxcbiAgICApO1xuICAgIHByb3RlY3RlZCBuYW1lID0gY29tcHV0ZWQoKCkgPT4gKHRoaXMucGFyc2VkVG9rZW4oKSA/IHRoaXMucGFyc2VkVG9rZW4oKSFbJ2dpdmVuX25hbWUnXSA6ICcnKSk7XG4gICAgcHJvdGVjdGVkIHNob3dJbXBlcnNvbmF0ZUJ1dHRvbiA9IGNvbXB1dGVkKCgpID0+XG4gICAgICAgIHRoaXMucGFyc2VkVG9rZW4oKVxuICAgICAgICAgICAgPyAhIShcbiAgICAgICAgICAgICAgICAgICF0aGlzLmlzSW1wZXJzb25hdGluZygpICYmXG4gICAgICAgICAgICAgICAgICB0aGlzLnBhcnNlZFRva2VuKCkhWydyZXNvdXJjZV9hY2Nlc3MnXVsncmVhbG0tbWFuYWdlbWVudCddPy5bJ3JvbGVzJ10/LmluY2x1ZGVzKFxuICAgICAgICAgICAgICAgICAgICAgICdpbXBlcnNvbmF0aW9uJyxcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgOiBmYWxzZSxcbiAgICApO1xuXG4gICAgcHJvdGVjdGVkIHNob3dJbXBlcnNvbmF0aW9uTW9kYWwgPSBmYWxzZTtcbiAgICBwcml2YXRlIGlzSW1wZXJzb25hdGluZyA9IGNvbXB1dGVkKCgpID0+ICEhdGhpcy5wYXJzZWRUb2tlbigpPy5bJ2ltcGVyc29uYXRvciddKTtcblxuICAgIC8vIEluYWN0aXZpdHkgdGltZW91dCBmb3IgaW1wZXJzb25hdGlvblxuICAgIHByaXZhdGUgYWN0aXZpdHlFdmVudHM6IEFycmF5PCdrZXlkb3duJyB8ICdwb2ludGVyZG93bicgfCAnd2hlZWwnIHwgJ3Njcm9sbCc+ID0gW1xuICAgICAgICAna2V5ZG93bicsXG4gICAgICAgICdwb2ludGVyZG93bicsXG4gICAgICAgICd3aGVlbCcsXG4gICAgICAgICdzY3JvbGwnLFxuICAgIF07XG4gICAgcHJpdmF0ZSBpbmFjdGl2aXR5VGltZXJJZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSBpbmFjdGl2aXR5VGltZW91dE1zID0gNSAqIDYwICogMTAwMDsgLy8gNSBtaW51dGVzXG4gICAgcHJpdmF0ZSBkZWJvdW5jZVRpbWVySWQ6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICAgIHByaXZhdGUgZGVib3VuY2VEZWxheU1zID0gMjUwO1xuXG4gICAgcHJpdmF0ZSB0cmFja2luZ0FjdGl2ZSA9IGZhbHNlO1xuXG4gICAgcHJpdmF0ZSBpbmplY3RvciA9IGluamVjdChJbmplY3Rvcik7XG5cbiAgICBuZ09uSW5pdCgpIHtcbiAgICAgICAgLy8gZWZmZWN0IGNhbiBvbmx5IGJlIHVzZWQgd2l0aGluIGFuIGluamVjdGlvbiBjb250ZXh0IChleDogY29uc3RydWN0b3IpXG4gICAgICAgIHJ1bkluSW5qZWN0aW9uQ29udGV4dCh0aGlzLmluamVjdG9yLCAoKSA9PiB7XG4gICAgICAgICAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGltcGVyc29uYXRpbmcgPSB0aGlzLmlzSW1wZXJzb25hdGluZygpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHRva2VuID0gdGhpcy5wYXJzZWRUb2tlbigpO1xuXG4gICAgICAgICAgICAgICAgLy8gd2hlbiB0b2tlbiByZWZyZXNoZXMgYWZ0ZXIgNSBtaW51dGVzLCBpdCBsZWF2ZXMgYSBzbWFsbCBtb21lbnQgd2hlcmUgdGhlcmUgaXMgbm8gdG9rZW5cbiAgICAgICAgICAgICAgICAvLyB0aGlzIHByZXZlbnRzIGRyb3BwaW5nIGluYWN0aXZ0aXkgdGltZXIgZHVyaW5nIHRoYXQgYmxpcFxuICAgICAgICAgICAgICAgIGlmICghdG9rZW4pIHJldHVybjtcblxuICAgICAgICAgICAgICAgIGlmIChpbXBlcnNvbmF0aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy50cmFja2luZ0FjdGl2ZSkgdGhpcy5zdGFydEluYWN0aXZpdHlUcmFja2luZygpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnRyYWNraW5nQWN0aXZlKSB0aGlzLnN0b3BJbmFjdGl2aXR5VHJhY2tpbmcoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMuc3RvcEluYWN0aXZpdHlUcmFja2luZygpO1xuICAgIH1cblxuICAgIC8qKiBCZWdpbiBsaXN0ZW5pbmcgYW5kIHN0YXJ0IGNvdW50ZG93biAqL1xuICAgIHByaXZhdGUgc3RhcnRJbmFjdGl2aXR5VHJhY2tpbmcoKSB7XG4gICAgICAgIHRoaXMuYWN0aXZpdHlFdmVudHMuZm9yRWFjaCgoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIC8vICdzY3JvbGwnIG9uIGRvY3VtZW50IGRvZXNuJ3QgYnViYmxlOyB1c2Ugd2luZG93ICsgY2FwdHVyZSB0byBjYXRjaCBuZXN0ZWQgc2Nyb2xsc1xuICAgICAgICAgICAgY29uc3QgdGFyZ2V0OiBXaW5kb3cgfCBEb2N1bWVudCA9IGV2ZW50ID09PSAnc2Nyb2xsJyA/IHdpbmRvdyA6IGRvY3VtZW50O1xuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9XG4gICAgICAgICAgICAgICAgZXZlbnQgPT09ICdzY3JvbGwnXG4gICAgICAgICAgICAgICAgICAgID8gKHsgcGFzc2l2ZTogdHJ1ZSwgY2FwdHVyZTogdHJ1ZSB9IGFzIEFkZEV2ZW50TGlzdGVuZXJPcHRpb25zKVxuICAgICAgICAgICAgICAgICAgICA6ICh7IHBhc3NpdmU6IHRydWUgfSBhcyBBZGRFdmVudExpc3RlbmVyT3B0aW9ucyk7XG5cbiAgICAgICAgICAgIHRhcmdldC5hZGRFdmVudExpc3RlbmVyKGV2ZW50LCB0aGlzLmRlYm91bmNlZFJlc2V0VGltZXIsIG9wdGlvbnMpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnRyYWNraW5nQWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5yZXNldEluYWN0aXZpdHlUaW1lcigpO1xuICAgIH1cblxuICAgIC8qKiBSZW1vdmUgbGlzdGVuZXJzIGFuZCBjbGVhciB0aW1lcnMgKi9cbiAgICBwcml2YXRlIHN0b3BJbmFjdGl2aXR5VHJhY2tpbmcoKSB7XG4gICAgICAgIHRoaXMuYWN0aXZpdHlFdmVudHMuZm9yRWFjaCgoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldDogV2luZG93IHwgRG9jdW1lbnQgPSBldmVudCA9PT0gJ3Njcm9sbCcgPyB3aW5kb3cgOiBkb2N1bWVudDtcbiAgICAgICAgICAgIC8vIElNUE9SVEFOVDogY2FwdHVyZSBtdXN0IG1hdGNoIGhvdyBpdCB3YXMgYWRkZWQgZm9yIHNjcm9sbFxuICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9XG4gICAgICAgICAgICAgICAgZXZlbnQgPT09ICdzY3JvbGwnID8gKHsgY2FwdHVyZTogdHJ1ZSB9IGFzIEFkZEV2ZW50TGlzdGVuZXJPcHRpb25zKSA6IHVuZGVmaW5lZDtcblxuICAgICAgICAgICAgdGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnQsIHRoaXMuZGVib3VuY2VkUmVzZXRUaW1lciwgb3B0aW9ucyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICh0aGlzLmluYWN0aXZpdHlUaW1lcklkKSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5pbmFjdGl2aXR5VGltZXJJZCk7XG4gICAgICAgICAgICB0aGlzLmluYWN0aXZpdHlUaW1lcklkID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5kZWJvdW5jZVRpbWVySWQpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLmRlYm91bmNlVGltZXJJZCk7XG4gICAgICAgICAgICB0aGlzLmRlYm91bmNlVGltZXJJZCA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnRyYWNraW5nQWN0aXZlID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqIFJlc2V0IHRoZSBpbmFjdGl2aXR5IGNvdW50ZG93biAobm8tb3AgaWYgbm90IGltcGVyc29uYXRpbmcpICovXG4gICAgcHJpdmF0ZSByZXNldEluYWN0aXZpdHlUaW1lciA9ICgpID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLmlzSW1wZXJzb25hdGluZygpKSByZXR1cm47XG5cbiAgICAgICAgaWYgKHRoaXMuaW5hY3Rpdml0eVRpbWVySWQpIGNsZWFyVGltZW91dCh0aGlzLmluYWN0aXZpdHlUaW1lcklkKTtcblxuICAgICAgICB0aGlzLmluYWN0aXZpdHlUaW1lcklkID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5lbmRJbXBlcnNvbmF0aW9uLmVtaXQoKTtcbiAgICAgICAgICAgIHRoaXMuc3RvcEluYWN0aXZpdHlUcmFja2luZygpO1xuICAgICAgICB9LCB0aGlzLmluYWN0aXZpdHlUaW1lb3V0TXMpO1xuICAgIH07XG5cbiAgICAvKiogRGVib3VuY2UgYWN0aXZpdHkgdG8gYXZvaWQgaGFtbWVyaW5nIHJlc2V0cyBkdXJpbmcgZXZlbnQgc3Rvcm1zICovXG4gICAgcHJpdmF0ZSBkZWJvdW5jZWRSZXNldFRpbWVyID0gKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5kZWJvdW5jZVRpbWVySWQpIGNsZWFyVGltZW91dCh0aGlzLmRlYm91bmNlVGltZXJJZCk7XG5cbiAgICAgICAgdGhpcy5kZWJvdW5jZVRpbWVySWQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlc2V0SW5hY3Rpdml0eVRpbWVyKCk7XG4gICAgICAgIH0sIHRoaXMuZGVib3VuY2VEZWxheU1zKTtcbiAgICB9O1xufVxuIiwiPGxpYi1pbXBlcnNvbmF0aW9uLWJhbm5lclxuICAgIFthY2Nlc3NUb2tlblBheWxvYWRdPVwiYWNjZXNzVG9rZW5QYXlsb2FkKClcIlxuICAgIChlbmRJbXBlcnNvbmF0aW9uKT1cImVuZEltcGVyc29uYXRpb24uZW1pdCgpXCJcbiAgICBbcGVyc29uQmFzZVVyaV09XCJwZXJzb25CYXNlVXJpKClcIlxuICAgIFtteUFjY291bnRBcGlCYXNlVXJpXT1cIm15QWNjb3VudEFwaUJhc2VVcmkoKVwiXG4+PC9saWItaW1wZXJzb25hdGlvbi1iYW5uZXI+XG48bGliLWhibGwtaGVhZGVyXG4gICAgW25hbWVdPVwibmFtZSgpXCJcbiAgICBbc2hvd0ltcGVyc29uYXRlQnV0dG9uXT1cInNob3dJbXBlcnNvbmF0ZUJ1dHRvbigpXCJcbiAgICAob3BlbkltcGVyc29uYXRpb25Nb2RhbCk9XCJzaG93SW1wZXJzb25hdGlvbk1vZGFsID0gdHJ1ZVwiXG4gICAgKGxvZ2luKT1cImxvZ2luLmVtaXQoKVwiXG4gICAgKGxvZ291dCk9XCJsb2dvdXQuZW1pdCgpXCJcbiAgICBbbWFpbnNpdGViYXNldXJsXT1cIm1haW5TaXRlQmFzZVVybCgpXCJcbi8+XG48bGliLWltcGVyc29uYXRlLW1vZGFsXG4gICAgW3Nob3dNb2RhbF09XCJzaG93SW1wZXJzb25hdGlvbk1vZGFsXCJcbiAgICBbb2lkY0Jhc2VVcmldPVwib2lkY0Jhc2VVcmkoKVwiXG4gICAgW29pZGNEZWZhdWx0SWRwXT1cIm9pZGNEZWZhdWx0SWRwKClcIlxuICAgIFthY2Nlc3NUb2tlblBheWxvYWRdPVwiYWNjZXNzVG9rZW5QYXlsb2FkKClcIlxuICAgIChkaXNtaXNzKT1cInNob3dJbXBlcnNvbmF0aW9uTW9kYWwgPSBmYWxzZVwiXG4gICAgKGluaXQpPVwic2hvd0ltcGVyc29uYXRpb25Nb2RhbCA9IHRydWVcIlxuPjwvbGliLWltcGVyc29uYXRlLW1vZGFsPlxuIl19
@@ -1,190 +0,0 @@
1
- import { Component, ElementRef, EventEmitter, HostListener, Input, Output, Pipe, inject, input, } from '@angular/core';
2
- import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
3
- import { Subject, Subscription, of } from 'rxjs';
4
- import { catchError, startWith, switchMap, tap } from 'rxjs/operators';
5
- import { libHbllFadeInOut } from '../animations/animations';
6
- import urlcat from 'urlcat';
7
- import { HttpClient } from '@angular/common/http';
8
- import { CommonModule } from '@angular/common';
9
- import { toSignal } from '@angular/core/rxjs-interop';
10
- import * as i0 from "@angular/core";
11
- import * as i1 from "@angular/forms";
12
- export const defaultOidcBaseUri = 'https://keycloak.lib.byu.edu/';
13
- export const defaultOidcDefaultIdp = 'ces';
14
- export class ImpersonateUserPipe {
15
- transform(user) {
16
- return `${user.name} (${user.netId || 'Unknown'})${user.restricted ? ' — Restricted' : ''}`;
17
- }
18
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ImpersonateUserPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
19
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.1.0", ngImport: i0, type: ImpersonateUserPipe, isStandalone: true, name: "impersonateUser" }); }
20
- }
21
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ImpersonateUserPipe, decorators: [{
22
- type: Pipe,
23
- args: [{
24
- name: 'impersonateUser',
25
- standalone: true,
26
- }]
27
- }] });
28
- const SEARCH_USERS_PATH = '/impersonate/api/search/';
29
- const START_IMPERSONATE_PATH = '/impersonate/:username';
30
- export class ImpersonateModalComponent {
31
- constructor() {
32
- this.http = inject(HttpClient);
33
- this.fb = inject(FormBuilder);
34
- this.eref = inject(ElementRef);
35
- this.oidcBaseUri = input(defaultOidcBaseUri);
36
- this.oidcDefaultIdp = input(defaultOidcDefaultIdp);
37
- // Require an object here so that access tokens are not visible/extractable from the DOM in consuming applications. Instead they are only stored in memory.
38
- this.accessTokenPayload = input.required();
39
- this.dismiss = new EventEmitter();
40
- this.init = new EventEmitter();
41
- this.isOpen = false;
42
- this.hasError = false;
43
- this.form = this.fb.nonNullable.group({
44
- search: this.fb.control('', { validators: Validators.minLength(3) }),
45
- });
46
- this.loading = false;
47
- this.handleSearchSubject = new Subject();
48
- this.results = toSignal(this.form.controls.search.valueChanges.pipe(switchMap((search) => this.handleSearchSubject.pipe(startWith(false), switchMap((handleSearch) => {
49
- this.selectedUsername = undefined;
50
- this.hasError = false;
51
- if (!search || !handleSearch) {
52
- return of(null);
53
- }
54
- this.loading = true;
55
- const results = this.searchUsers(search);
56
- return results.pipe(catchError((e) => {
57
- this.hasError = true;
58
- console.error(e);
59
- return of(null);
60
- }));
61
- }))), tap(() => {
62
- this.loading = false;
63
- })));
64
- this.subs = new Subscription();
65
- this.handleKeyDown = (event) => {
66
- switch (event.key) {
67
- case 'Esc':
68
- case 'Escape': {
69
- this.close();
70
- break;
71
- }
72
- case 'I':
73
- case 'i': {
74
- if (event.ctrlKey || event.metaKey) {
75
- if (this.isOpen) {
76
- this.close();
77
- }
78
- else {
79
- this.init.emit();
80
- }
81
- event.preventDefault();
82
- }
83
- break;
84
- }
85
- default:
86
- break;
87
- }
88
- };
89
- /** Redirect to Keycloak impersonate page, which will redirect back
90
- * after impersonation begins.
91
- */
92
- this.startImpersonation = (username) => {
93
- const _username = username ?? this.selectedUsername;
94
- if (!_username) {
95
- return;
96
- }
97
- const url = urlcat(this.oidcBaseUri(), START_IMPERSONATE_PATH, {
98
- username,
99
- returnUri: window.location.href,
100
- defaultIdp: this.oidcDefaultIdp(),
101
- });
102
- this.replaceUrl(url);
103
- };
104
- this.handleSelectUser = (event) => {
105
- this.selectedUsername = event.target.value;
106
- };
107
- this.clearSearch = () => {
108
- this.form.reset();
109
- };
110
- this.close = () => {
111
- this.dismiss.emit();
112
- this.clearSearch();
113
- };
114
- this.handleFormSubmit = (event) => {
115
- event.preventDefault();
116
- if (this.form.valid) {
117
- this.handleSearchSubject.next(true);
118
- }
119
- };
120
- this.handleSearchKeyPress = (event) => {
121
- if (!['ArrowDown', 'Down'].includes(event.key)) {
122
- return;
123
- }
124
- event.preventDefault();
125
- if (this.results()?.length) {
126
- const firstResult = this.eref.nativeElement.querySelector(`#result_0`);
127
- firstResult?.click();
128
- firstResult?.focus();
129
- }
130
- };
131
- this.handleResultKeyPress = (event) => {
132
- if (['ArrowUp', 'Up'].includes(event.key) &&
133
- event.target?.id === 'result_0') {
134
- event.preventDefault();
135
- this.eref.nativeElement.querySelector('#searchInput')?.focus();
136
- }
137
- else if (event.key === 'Enter') {
138
- event.preventDefault();
139
- this.startImpersonation();
140
- }
141
- };
142
- /** Search Keycloak users using a generic search query. */
143
- this.searchUsers = (query) => {
144
- const uri = urlcat(this.oidcBaseUri(), SEARCH_USERS_PATH, {
145
- query,
146
- });
147
- return this.http.get(uri, {
148
- headers: {
149
- Authorization: `Bearer ${this.accessTokenPayload().token}`,
150
- },
151
- });
152
- };
153
- this.replaceUrl = (url) => window.location.replace(url);
154
- }
155
- set showModal(open) {
156
- this.isOpen = open;
157
- if (open) {
158
- // Set focus on search input shortly after opening modal so user notices
159
- // the input receiving focus.
160
- setTimeout(() => this.eref.nativeElement.querySelector('#searchInput')?.focus(), 250);
161
- }
162
- }
163
- outsideClick(event) {
164
- if (event.target?.id === 'modalBackdrop') {
165
- this.close();
166
- }
167
- }
168
- ngOnDestroy() {
169
- this.subs.unsubscribe();
170
- }
171
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ImpersonateModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
172
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.0", type: ImpersonateModalComponent, isStandalone: true, selector: "lib-impersonate-modal", inputs: { showModal: { classPropertyName: "showModal", publicName: "showModal", isSignal: false, isRequired: false, transformFunction: null }, oidcBaseUri: { classPropertyName: "oidcBaseUri", publicName: "oidcBaseUri", isSignal: true, isRequired: false, transformFunction: null }, oidcDefaultIdp: { classPropertyName: "oidcDefaultIdp", publicName: "oidcDefaultIdp", isSignal: true, isRequired: false, transformFunction: null }, accessTokenPayload: { classPropertyName: "accessTokenPayload", publicName: "accessTokenPayload", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { dismiss: "dismiss", init: "init" }, host: { listeners: { "document:mousedown": "outsideClick($event)", "document:keydown": "handleKeyDown($event)" } }, ngImport: i0, template: "@if (isOpen) {\n <div @libHbllFadeInOut class=\"modal-wrapper\" id=\"modalBackdrop\" data-testid=\"backdrop\">\n <div class=\"modal-container\" data-testid=\"modal\">\n <div class=\"modal-header\">\n <h2>Impersonate</h2>\n <button type=\"button\" (click)=\"close()\" aria-label=\"Close\" data-testid=\"close\">\n <span class=\"material-symbols-outlined icon-close\"> close </span>\n </button>\n </div>\n <form [formGroup]=\"form\" (submit)=\"handleFormSubmit($event)\" data-testid=\"searchForm\">\n <div class=\"search-header\">\n <div class=\"secondary\" [class.disabled]=\"!form.valid\">\n <span class=\"keyboard-key\">Enter</span> to search\n </div>\n </div>\n <label\n for=\"searchInput\"\n class=\"search-wrapper\"\n [class.invalid]=\"form.invalid && form.dirty\"\n >\n <span class=\"material-symbols-outlined icon-search\"> search </span>\n <input\n id=\"searchInput\"\n type=\"text\"\n autocomplete=\"off\"\n formControlName=\"search\"\n placeholder=\"Search patrons...\"\n (keydown)=\"handleSearchKeyPress($event)\"\n #searchBox\n data-testid=\"searchInput\"\n />\n @if (!!searchBox.value && form.valid) {\n <span class=\"material-symbols-outlined icon-checkmark\"> check </span>\n }\n @if (searchBox.value.length) {\n <span\n (click)=\"clearSearch()\"\n @libHbllFadeInOut\n class=\"material-symbols-outlined icon-close\"\n >\n close\n </span>\n }\n </label>\n </form>\n <fieldset\n class=\"search-results-wrapper\"\n id=\"resultsScrollContainer\"\n (change)=\"handleSelectUser($event)\"\n >\n @if (!loading && results()) {\n @for (user of results(); track user.netId; let idx = $index) {\n <div\n class=\"result-field result\"\n [class.focus]=\"user.username === selectedUsername\"\n data-testid=\"result\"\n >\n <label\n [for]=\"'result_' + idx\"\n [class.warning]=\"user.restricted\"\n (mouseover)=\"selectedUsername = user.username\"\n >\n @if (user.restricted) {\n <span class=\"material-symbols-outlined icon\"> warning </span>\n } @else {\n <span class=\"material-symbols-outlined icon\"> person </span>\n }\n &nbsp; &nbsp;\n <span [title]=\"user\" data-testid=\"resultText\">{{\n user | impersonateUser\n }}</span>\n <input\n type=\"radio\"\n [value]=\"user.username\"\n class=\"hidden\"\n [id]=\"'result_' + idx\"\n name=\"resultSelect\"\n (keydown)=\"handleResultKeyPress($event)\"\n />\n </label>\n <button\n class=\"impersonate-button\"\n data-testid=\"impersonateBtn\"\n (click)=\"startImpersonation(user.username)\"\n >\n Impersonate\n </button>\n </div>\n } @empty {\n <div class=\"result-field\">\n No results. Try searching by Net ID or BYU ID.\n </div>\n }\n }\n @if (loading) {\n <div class=\"result-field\">\n <div class=\"lib-spinner\"></div>\n </div>\n }\n @if (hasError) {\n <div class=\"result-field\">Something went wrong. We'll keep trying.</div>\n }\n </fieldset>\n </div>\n </div>\n}\n", styles: [".lib-spinner{border:.3em solid #dfe9f7;border-top:.3em solid #4070b0;border-radius:100%;width:30px;height:30px;animation:loadingSpinnerAnimate 1s ease infinite;position:relative}@keyframes loadingSpinnerAnimate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}*{box-sizing:border-box}h2{font-size:1.2em;font-weight:600;margin:0;color:#404040}.warning{color:#b04940}.modal-wrapper{position:fixed;inset:0;background-color:#0000007f;z-index:10000;display:grid;place-items:center}.modal-container{color:#404040;padding:1.2em 1.4em;width:90%;max-width:30em;border-radius:4px;border:1px solid #b7b7b7;box-shadow:0 3px 6px #002e5d20;background-color:#fff;display:grid;grid-template-columns:1fr;gap:1em}.modal-container .modal-header{display:flex;justify-content:space-between;border-bottom:1px solid #e6e6e6;padding-bottom:.8em}.modal-container .modal-header .icon-close{transition:opacity .15s;color:#707070;opacity:1;cursor:pointer}.modal-container .modal-header .icon-close:hover{opacity:.8}.modal-container .hidden{opacity:0;width:0;height:0}.modal-container .search-header{display:flex;align-items:center;justify-content:flex-end;margin-bottom:.8em}.modal-container .search-header .secondary{color:#70707095}.modal-container .search-header .keyboard-key{padding:.1em .4em;border:1px solid currentColor;border-radius:4px}.modal-container .search-wrapper{display:flex;align-items:center;border-radius:4px;border:solid 1px currentColor;color:#ca7ad1cc;background-color:#e6e6e655;padding:.1em .3em .1em .5em;transition:background-color .15s,color .15s}.modal-container .search-wrapper.invalid{background-color:#b0494022}.modal-container .search-wrapper .icon-search{font-size:1.2em}.modal-container .search-wrapper .icon-checkmark{color:#1dce7b}.modal-container .search-wrapper .icon-close{color:#ca7ad1cc;cursor:pointer}.modal-container .search-wrapper .icon-close:hover{color:#ca7ad1}.modal-container .search-wrapper input[type=text]{background:transparent;border:none;outline:none;width:100%;color:#404040;padding:.5em .4em;font-size:1em}.modal-container .search-wrapper input[type=text]:focus{background-color:transparent}.modal-container .search-results-wrapper{border:none;margin:0;padding:0;max-height:25em;overflow-y:auto;overflow-x:hidden;scrollbar-width:thin;display:flex;flex-direction:column;align-items:stretch;min-width:0}.modal-container .search-results-wrapper::-webkit-scrollbar{width:6px}.modal-container .search-results-wrapper::-webkit-scrollbar-track{background:#e6e6e6}.modal-container .search-results-wrapper::-webkit-scrollbar-thumb{background-color:#b3b3b3;border-radius:5px}.modal-container .search-results-wrapper::-webkit-scrollbar-thumb:hover{background-color:#888}.modal-container .search-results-wrapper .result-field{font-style:italic;display:flex;align-items:center;justify-content:space-between;padding:.8em}.modal-container .search-results-wrapper .result-field .lib-spinner{margin:auto;display:grid;place-items:center}.modal-container .search-results-wrapper .result-field.result{font-style:normal;padding:0}.modal-container .search-results-wrapper .result-field.result label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex-grow:1;padding:.8em;display:flex;align-items:center}.modal-container .search-results-wrapper .result-field.result label .icon{font-size:1.2em;margin-right:.4em}.modal-container .search-results-wrapper .result-field.result .impersonate-button{cursor:pointer;display:none;color:#ca7ad1cc;padding:.1em .6em;border:1px solid currentColor;border-radius:4px;background-color:#fff;flex-shrink:0;margin-block:.6em;margin-right:.8em}.modal-container .search-results-wrapper .result-field.result .impersonate-button:hover{color:#ca7ad1;background-color:#fff8}.modal-container .search-results-wrapper .result-field.result:active,.modal-container .search-results-wrapper .result-field.result.focus{background:#f2f2f2}.modal-container .search-results-wrapper .result-field.result.focus .impersonate-button{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "pipe", type: ImpersonateUserPipe, name: "impersonateUser" }], animations: [libHbllFadeInOut] }); }
173
- }
174
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: ImpersonateModalComponent, decorators: [{
175
- type: Component,
176
- args: [{ standalone: true, imports: [CommonModule, ReactiveFormsModule, ImpersonateUserPipe], selector: 'lib-impersonate-modal', animations: [libHbllFadeInOut], template: "@if (isOpen) {\n <div @libHbllFadeInOut class=\"modal-wrapper\" id=\"modalBackdrop\" data-testid=\"backdrop\">\n <div class=\"modal-container\" data-testid=\"modal\">\n <div class=\"modal-header\">\n <h2>Impersonate</h2>\n <button type=\"button\" (click)=\"close()\" aria-label=\"Close\" data-testid=\"close\">\n <span class=\"material-symbols-outlined icon-close\"> close </span>\n </button>\n </div>\n <form [formGroup]=\"form\" (submit)=\"handleFormSubmit($event)\" data-testid=\"searchForm\">\n <div class=\"search-header\">\n <div class=\"secondary\" [class.disabled]=\"!form.valid\">\n <span class=\"keyboard-key\">Enter</span> to search\n </div>\n </div>\n <label\n for=\"searchInput\"\n class=\"search-wrapper\"\n [class.invalid]=\"form.invalid && form.dirty\"\n >\n <span class=\"material-symbols-outlined icon-search\"> search </span>\n <input\n id=\"searchInput\"\n type=\"text\"\n autocomplete=\"off\"\n formControlName=\"search\"\n placeholder=\"Search patrons...\"\n (keydown)=\"handleSearchKeyPress($event)\"\n #searchBox\n data-testid=\"searchInput\"\n />\n @if (!!searchBox.value && form.valid) {\n <span class=\"material-symbols-outlined icon-checkmark\"> check </span>\n }\n @if (searchBox.value.length) {\n <span\n (click)=\"clearSearch()\"\n @libHbllFadeInOut\n class=\"material-symbols-outlined icon-close\"\n >\n close\n </span>\n }\n </label>\n </form>\n <fieldset\n class=\"search-results-wrapper\"\n id=\"resultsScrollContainer\"\n (change)=\"handleSelectUser($event)\"\n >\n @if (!loading && results()) {\n @for (user of results(); track user.netId; let idx = $index) {\n <div\n class=\"result-field result\"\n [class.focus]=\"user.username === selectedUsername\"\n data-testid=\"result\"\n >\n <label\n [for]=\"'result_' + idx\"\n [class.warning]=\"user.restricted\"\n (mouseover)=\"selectedUsername = user.username\"\n >\n @if (user.restricted) {\n <span class=\"material-symbols-outlined icon\"> warning </span>\n } @else {\n <span class=\"material-symbols-outlined icon\"> person </span>\n }\n &nbsp; &nbsp;\n <span [title]=\"user\" data-testid=\"resultText\">{{\n user | impersonateUser\n }}</span>\n <input\n type=\"radio\"\n [value]=\"user.username\"\n class=\"hidden\"\n [id]=\"'result_' + idx\"\n name=\"resultSelect\"\n (keydown)=\"handleResultKeyPress($event)\"\n />\n </label>\n <button\n class=\"impersonate-button\"\n data-testid=\"impersonateBtn\"\n (click)=\"startImpersonation(user.username)\"\n >\n Impersonate\n </button>\n </div>\n } @empty {\n <div class=\"result-field\">\n No results. Try searching by Net ID or BYU ID.\n </div>\n }\n }\n @if (loading) {\n <div class=\"result-field\">\n <div class=\"lib-spinner\"></div>\n </div>\n }\n @if (hasError) {\n <div class=\"result-field\">Something went wrong. We'll keep trying.</div>\n }\n </fieldset>\n </div>\n </div>\n}\n", styles: [".lib-spinner{border:.3em solid #dfe9f7;border-top:.3em solid #4070b0;border-radius:100%;width:30px;height:30px;animation:loadingSpinnerAnimate 1s ease infinite;position:relative}@keyframes loadingSpinnerAnimate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}*{box-sizing:border-box}h2{font-size:1.2em;font-weight:600;margin:0;color:#404040}.warning{color:#b04940}.modal-wrapper{position:fixed;inset:0;background-color:#0000007f;z-index:10000;display:grid;place-items:center}.modal-container{color:#404040;padding:1.2em 1.4em;width:90%;max-width:30em;border-radius:4px;border:1px solid #b7b7b7;box-shadow:0 3px 6px #002e5d20;background-color:#fff;display:grid;grid-template-columns:1fr;gap:1em}.modal-container .modal-header{display:flex;justify-content:space-between;border-bottom:1px solid #e6e6e6;padding-bottom:.8em}.modal-container .modal-header .icon-close{transition:opacity .15s;color:#707070;opacity:1;cursor:pointer}.modal-container .modal-header .icon-close:hover{opacity:.8}.modal-container .hidden{opacity:0;width:0;height:0}.modal-container .search-header{display:flex;align-items:center;justify-content:flex-end;margin-bottom:.8em}.modal-container .search-header .secondary{color:#70707095}.modal-container .search-header .keyboard-key{padding:.1em .4em;border:1px solid currentColor;border-radius:4px}.modal-container .search-wrapper{display:flex;align-items:center;border-radius:4px;border:solid 1px currentColor;color:#ca7ad1cc;background-color:#e6e6e655;padding:.1em .3em .1em .5em;transition:background-color .15s,color .15s}.modal-container .search-wrapper.invalid{background-color:#b0494022}.modal-container .search-wrapper .icon-search{font-size:1.2em}.modal-container .search-wrapper .icon-checkmark{color:#1dce7b}.modal-container .search-wrapper .icon-close{color:#ca7ad1cc;cursor:pointer}.modal-container .search-wrapper .icon-close:hover{color:#ca7ad1}.modal-container .search-wrapper input[type=text]{background:transparent;border:none;outline:none;width:100%;color:#404040;padding:.5em .4em;font-size:1em}.modal-container .search-wrapper input[type=text]:focus{background-color:transparent}.modal-container .search-results-wrapper{border:none;margin:0;padding:0;max-height:25em;overflow-y:auto;overflow-x:hidden;scrollbar-width:thin;display:flex;flex-direction:column;align-items:stretch;min-width:0}.modal-container .search-results-wrapper::-webkit-scrollbar{width:6px}.modal-container .search-results-wrapper::-webkit-scrollbar-track{background:#e6e6e6}.modal-container .search-results-wrapper::-webkit-scrollbar-thumb{background-color:#b3b3b3;border-radius:5px}.modal-container .search-results-wrapper::-webkit-scrollbar-thumb:hover{background-color:#888}.modal-container .search-results-wrapper .result-field{font-style:italic;display:flex;align-items:center;justify-content:space-between;padding:.8em}.modal-container .search-results-wrapper .result-field .lib-spinner{margin:auto;display:grid;place-items:center}.modal-container .search-results-wrapper .result-field.result{font-style:normal;padding:0}.modal-container .search-results-wrapper .result-field.result label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex-grow:1;padding:.8em;display:flex;align-items:center}.modal-container .search-results-wrapper .result-field.result label .icon{font-size:1.2em;margin-right:.4em}.modal-container .search-results-wrapper .result-field.result .impersonate-button{cursor:pointer;display:none;color:#ca7ad1cc;padding:.1em .6em;border:1px solid currentColor;border-radius:4px;background-color:#fff;flex-shrink:0;margin-block:.6em;margin-right:.8em}.modal-container .search-results-wrapper .result-field.result .impersonate-button:hover{color:#ca7ad1;background-color:#fff8}.modal-container .search-results-wrapper .result-field.result:active,.modal-container .search-results-wrapper .result-field.result.focus{background:#f2f2f2}.modal-container .search-results-wrapper .result-field.result.focus .impersonate-button{display:block}\n"] }]
177
- }], propDecorators: { showModal: [{
178
- type: Input
179
- }], dismiss: [{
180
- type: Output
181
- }], init: [{
182
- type: Output
183
- }], outsideClick: [{
184
- type: HostListener,
185
- args: ['document:mousedown', ['$event']]
186
- }], handleKeyDown: [{
187
- type: HostListener,
188
- args: ['document:keydown', ['$event']]
189
- }] } });
190
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1wZXJzb25hdGUtbW9kYWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29tcG9uZW50cy9zcmMvbGliL2ltcGVyc29uYXRlLW1vZGFsL2ltcGVyc29uYXRlLW1vZGFsLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMvc3JjL2xpYi9pbXBlcnNvbmF0ZS1tb2RhbC9pbXBlcnNvbmF0ZS1tb2RhbC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0gsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBQ04sSUFBSSxFQUVKLE1BQU0sRUFDTixLQUFLLEdBQ1IsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFdBQVcsRUFBRSxtQkFBbUIsRUFBRSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5RSxPQUFPLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDakQsT0FBTyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzVELE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUM1QixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQzs7O0FBR3RELE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLCtCQUErQixDQUFDO0FBQ2xFLE1BQU0sQ0FBQyxNQUFNLHFCQUFxQixHQUFHLEtB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b25lbnQsXG4gICAgRWxlbWVudFJlZixcbiAgICBFdmVudEVtaXR0ZXIsXG4gICAgSG9zdExpc3RlbmVyLFxuICAgIElucHV0LFxuICAgIE9uRGVzdHJveSxcbiAgICBPdXRwdXQsXG4gICAgUGlwZSxcbiAgICBQaXBlVHJhbnNmb3JtLFxuICAgIGluamVjdCxcbiAgICBpbnB1dCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGb3JtQnVpbGRlciwgUmVhY3RpdmVGb3Jtc01vZHVsZSwgVmFsaWRhdG9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFN1YmplY3QsIFN1YnNjcmlwdGlvbiwgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGNhdGNoRXJyb3IsIHN0YXJ0V2l0aCwgc3dpdGNoTWFwLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBsaWJIYmxsRmFkZUluT3V0IH0gZnJvbSAnLi4vYW5pbWF0aW9ucy9hbmltYXRpb25zJztcbmltcG9ydCB1cmxjYXQgZnJvbSAndXJsY2F0JztcbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgdG9TaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQgeyBUb2tlblBheWxvYWQgfSBmcm9tICcuLi9tb2RlbHMvdG9rZW4tcGF5bG9hZCc7XG5cbmV4cG9ydCBjb25zdCBkZWZhdWx0T2lkY0Jhc2VVcmkgPSAnaHR0cHM6Ly9rZXljbG9hay5saWIuYnl1LmVkdS8nO1xuZXhwb3J0IGNvbnN0IGRlZmF1bHRPaWRjRGVmYXVsdElkcCA9ICdjZXMnO1xuXG5AUGlwZSh7XG4gICAgbmFtZTogJ2ltcGVyc29uYXRlVXNlcicsXG4gICAgc3RhbmRhbG9uZTogdHJ1ZSxcbn0pXG5leHBvcnQgY2xhc3MgSW1wZXJzb25hdGVVc2VyUGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xuICAgIHRyYW5zZm9ybSh1c2VyOiBJbXBlcnNvbmF0ZVNlYXJjaFJlc3VsdCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBgJHt1c2VyLm5hbWV9ICgke3VzZXIubmV0SWQgfHwgJ1Vua25vd24nfSkke3VzZXIucmVzdHJpY3RlZCA/ICcg4oCUIFJlc3RyaWN0ZWQnIDogJyd9YDtcbiAgICB9XG59XG5leHBvcnQgaW50ZXJmYWNlIEltcGVyc29uYXRlU2VhcmNoUmVzdWx0IHtcbiAgICBuZXRJZDogc3RyaW5nO1xuICAgIGluc3RpdHV0aW9uOiBzdHJpbmc7XG4gICAgdXNlcm5hbWU6IHN0cmluZztcbiAgICBuYW1lOiBzdHJpbmc7XG4gICAgcHJlZmVycmVkTmFtZTogc3RyaW5nO1xuICAgIGdpdmVuTmFtZTogc3RyaW5nO1xuICAgIHN1cm5hbWU6IHN0cmluZztcbiAgICByZXN0cmljdGVkOiBib29sZWFuO1xufVxuXG5jb25zdCBTRUFSQ0hfVVNFUlNfUEFUSCA9ICcvaW1wZXJzb25hdGUvYXBpL3NlYXJjaC8nO1xuY29uc3QgU1RBUlRfSU1QRVJTT05BVEVfUEFUSCA9ICcvaW1wZXJzb25hdGUvOnVzZXJuYW1lJztcblxuQENvbXBvbmVudCh7XG4gICAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBSZWFjdGl2ZUZvcm1zTW9kdWxlLCBJbXBlcnNvbmF0ZVVzZXJQaXBlXSxcbiAgICBzZWxlY3RvcjogJ2xpYi1pbXBlcnNvbmF0ZS1tb2RhbCcsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2ltcGVyc29uYXRlLW1vZGFsLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9pbXBlcnNvbmF0ZS1tb2RhbC5jb21wb25lbnQuc2NzcyddLFxuICAgIGFuaW1hdGlvbnM6IFtsaWJIYmxsRmFkZUluT3V0XSxcbn0pXG5leHBvcnQgY2xhc3MgSW1wZXJzb25hdGVNb2RhbENvbXBvbmVudCBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBodHRwID0gaW5qZWN0KEh0dHBDbGllbnQpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgZmIgPSBpbmplY3QoRm9ybUJ1aWxkZXIpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgZXJlZiA9IGluamVjdChFbGVtZW50UmVmKTtcblxuICAgIEBJbnB1dCgpIHNldCBzaG93TW9kYWwob3BlbjogYm9vbGVhbikge1xuICAgICAgICB0aGlzLmlzT3BlbiA9IG9wZW47XG4gICAgICAgIGlmIChvcGVuKSB7XG4gICAgICAgICAgICAvLyBTZXQgZm9jdXMgb24gc2VhcmNoIGlucHV0IHNob3J0bHkgYWZ0ZXIgb3BlbmluZyBtb2RhbCBzbyB1c2VyIG5vdGljZXNcbiAgICAgICAgICAgIC8vIHRoZSBpbnB1dCByZWNlaXZpbmcgZm9jdXMuXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuZXJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJyNzZWFyY2hJbnB1dCcpPy5mb2N1cygpLCAyNTApO1xuICAgICAgICB9XG4gICAgfVxuICAgIG9pZGNCYXNlVXJpID0gaW5wdXQoZGVmYXVsdE9pZGNCYXNlVXJpKTtcbiAgICBvaWRjRGVmYXVsdElkcCA9IGlucHV0KGRlZmF1bHRPaWRjRGVmYXVsdElkcCk7XG4gICAgLy8gUmVxdWlyZSBhbiBvYmplY3QgaGVyZSBzbyB0aGF0IGFjY2VzcyB0b2tlbnMgYXJlIG5vdCB2aXNpYmxlL2V4dHJhY3RhYmxlIGZyb20gdGhlIERPTSBpbiBjb25zdW1pbmcgYXBwbGljYXRpb25zLiBJbnN0ZWFkIHRoZXkgYXJlIG9ubHkgc3RvcmVkIGluIG1lbW9yeS5cbiAgICBhY2Nlc3NUb2tlblBheWxvYWQgPSBpbnB1dC5yZXF1aXJlZDxUb2tlblBheWxvYWQ+KCk7XG4gICAgQE91dHB1dCgpIGRpc21pc3MgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gICAgQE91dHB1dCgpIGluaXQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgICBwcm90ZWN0ZWQgaXNPcGVuID0gZmFsc2U7XG4gICAgcHJvdGVjdGVkIGhhc0Vycm9yID0gZmFsc2U7XG4gICAgcHJvdGVjdGVkIGZvcm0gPSB0aGlzLmZiLm5vbk51bGxhYmxlLmdyb3VwKHtcbiAgICAgICAgc2VhcmNoOiB0aGlzLmZiLmNvbnRyb2woJycsIHsgdmFsaWRhdG9yczogVmFsaWRhdG9ycy5taW5MZW5ndGgoMykgfSksXG4gICAgfSk7XG4gICAgcHJvdGVjdGVkIHNlbGVjdGVkVXNlcm5hbWU/OiBzdHJpbmc7XG5cbiAgICBwcm90ZWN0ZWQgbG9hZGluZyA9IGZhbHNlO1xuICAgIHByb3RlY3RlZCBoYW5kbGVTZWFyY2hTdWJqZWN0ID0gbmV3IFN1YmplY3Q8Ym9vbGVhbj4oKTtcbiAgICBwcm90ZWN0ZWQgcmVzdWx0cyA9IHRvU2lnbmFsKFxuICAgICAgICB0aGlzLmZvcm0uY29udHJvbHMuc2VhcmNoLnZhbHVlQ2hhbmdlcy5waXBlKFxuICAgICAgICAgICAgc3dpdGNoTWFwKChzZWFyY2gpID0+XG4gICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVTZWFyY2hTdWJqZWN0LnBpcGUoXG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0V2l0aChmYWxzZSksXG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgoaGFuZGxlU2VhcmNoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkVXNlcm5hbWUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhc0Vycm9yID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghc2VhcmNoIHx8ICFoYW5kbGVTZWFyY2gpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2YobnVsbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9hZGluZyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZXN1bHRzID0gdGhpcy5zZWFyY2hVc2VycyhzZWFyY2gpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0cy5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoRXJyb3IoKGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5oYXNFcnJvciA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgdGFwKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICApLFxuICAgICk7XG5cbiAgICBwcml2YXRlIHN1YnMgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG5cbiAgICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDptb3VzZWRvd24nLCBbJyRldmVudCddKSBvdXRzaWRlQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICAgICAgaWYgKChldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQpPy5pZCA9PT0gJ21vZGFsQmFja2Ryb3AnKSB7XG4gICAgICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDprZXlkb3duJywgWyckZXZlbnQnXSkgaGFuZGxlS2V5RG93biA9IChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgICAgICBzd2l0Y2ggKGV2ZW50LmtleSkge1xuICAgICAgICAgICAgY2FzZSAnRXNjJzpcbiAgICAgICAgICAgIGNhc2UgJ0VzY2FwZSc6IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlICdJJzpcbiAgICAgICAgICAgIGNhc2UgJ2knOiB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc09wZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW5pdC5lbWl0KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIG5nT25EZXN0cm95KCkge1xuICAgICAgICB0aGlzLnN1YnMudW5zdWJzY3JpYmUoKTtcbiAgICB9XG5cbiAgICAvKiogUmVkaXJlY3QgdG8gS2V5Y2xvYWsgaW1wZXJzb25hdGUgcGFnZSwgd2hpY2ggd2lsbCByZWRpcmVjdCBiYWNrXG4gICAgICogYWZ0ZXIgaW1wZXJzb25hdGlvbiBiZWdpbnMuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHN0YXJ0SW1wZXJzb25hdGlvbiA9ICh1c2VybmFtZT86IHN0cmluZykgPT4ge1xuICAgICAgICBjb25zdCBfdXNlcm5hbWUgPSB1c2VybmFtZSA/PyB0aGlzLnNlbGVjdGVkVXNlcm5hbWU7XG4gICAgICAgIGlmICghX3VzZXJuYW1lKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJsID0gdXJsY2F0KHRoaXMub2lkY0Jhc2VVcmkoKSwgU1RBUlRfSU1QRVJTT05BVEVfUEFUSCwge1xuICAgICAgICAgICAgdXNlcm5hbWUsXG4gICAgICAgICAgICByZXR1cm5Vcmk6IHdpbmRvdy5sb2NhdGlvbi5ocmVmLFxuICAgICAgICAgICAgZGVmYXVsdElkcDogdGhpcy5vaWRjRGVmYXVsdElkcCgpLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5yZXBsYWNlVXJsKHVybCk7XG4gICAgfTtcblxuICAgIHByb3RlY3RlZCBoYW5kbGVTZWxlY3RVc2VyID0gKGV2ZW50OiBFdmVudCkgPT4ge1xuICAgICAgICB0aGlzLnNlbGVjdGVkVXNlcm5hbWUgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQpLnZhbHVlO1xuICAgIH07XG5cbiAgICBwcm90ZWN0ZWQgY2xlYXJTZWFyY2ggPSAoKSA9PiB7XG4gICAgICAgIHRoaXMuZm9ybS5yZXNldCgpO1xuICAgIH07XG5cbiAgICBwcm90ZWN0ZWQgY2xvc2UgPSAoKSA9PiB7XG4gICAgICAgIHRoaXMuZGlzbWlzcy5lbWl0KCk7XG4gICAgICAgIHRoaXMuY2xlYXJTZWFyY2goKTtcbiAgICB9O1xuXG4gICAgcHJvdGVjdGVkIGhhbmRsZUZvcm1TdWJtaXQgPSAoZXZlbnQ6IFN1Ym1pdEV2ZW50KSA9PiB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGlmICh0aGlzLmZvcm0udmFsaWQpIHtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlU2VhcmNoU3ViamVjdC5uZXh0KHRydWUpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHByb3RlY3RlZCBoYW5kbGVTZWFyY2hLZXlQcmVzcyA9IChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgICAgICBpZiAoIVsnQXJyb3dEb3duJywgJ0Rvd24nXS5pbmNsdWRlcyhldmVudC5rZXkpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgaWYgKHRoaXMucmVzdWx0cygpPy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnN0IGZpcnN0UmVzdWx0ID0gdGhpcy5lcmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihgI3Jlc3VsdF8wYCk7XG4gICAgICAgICAgICBmaXJzdFJlc3VsdD8uY2xpY2soKTtcbiAgICAgICAgICAgIGZpcnN0UmVzdWx0Py5mb2N1cygpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHByb3RlY3RlZCBoYW5kbGVSZXN1bHRLZXlQcmVzcyA9IChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICBbJ0Fycm93VXAnLCAnVXAnXS5pbmNsdWRlcyhldmVudC5rZXkpICYmXG4gICAgICAgICAgICAoZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQpPy5pZCA9PT0gJ3Jlc3VsdF8wJ1xuICAgICAgICApIHtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICB0aGlzLmVyZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcjc2VhcmNoSW5wdXQnKT8uZm9jdXMoKTtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXkgPT09ICdFbnRlcicpIHtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0SW1wZXJzb25hdGlvbigpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8qKiBTZWFyY2ggS2V5Y2xvYWsgdXNlcnMgdXNpbmcgYSBnZW5lcmljIHNlYXJjaCBxdWVyeS4gKi9cbiAgICBwcml2YXRlIHNlYXJjaFVzZXJzID0gKHF1ZXJ5OiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3QgdXJpID0gdXJsY2F0KHRoaXMub2lkY0Jhc2VVcmkoKSwgU0VBUkNIX1VTRVJTX1BBVEgsIHtcbiAgICAgICAgICAgIHF1ZXJ5LFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gdGhpcy5odHRwLmdldDxJbXBlcnNvbmF0ZVNlYXJjaFJlc3VsdFtdPih1cmksIHtcbiAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7dGhpcy5hY2Nlc3NUb2tlblBheWxvYWQoKS50b2tlbn1gLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgcmVwbGFjZVVybCA9ICh1cmw6IHN0cmluZykgPT4gd2luZG93LmxvY2F0aW9uLnJlcGxhY2UodXJsKTtcbn1cbiIsIkBpZiAoaXNPcGVuKSB7XG4gICAgPGRpdiBAbGliSGJsbEZhZGVJbk91dCBjbGFzcz1cIm1vZGFsLXdyYXBwZXJcIiBpZD1cIm1vZGFsQmFja2Ryb3BcIiBkYXRhLXRlc3RpZD1cImJhY2tkcm9wXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1jb250YWluZXJcIiBkYXRhLXRlc3RpZD1cIm1vZGFsXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgPGgyPkltcGVyc29uYXRlPC9oMj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiY2xvc2UoKVwiIGFyaWEtbGFiZWw9XCJDbG9zZVwiIGRhdGEtdGVzdGlkPVwiY2xvc2VcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkIGljb24tY2xvc2VcIj4gY2xvc2UgPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8Zm9ybSBbZm9ybUdyb3VwXT1cImZvcm1cIiAoc3VibWl0KT1cImhhbmRsZUZvcm1TdWJtaXQoJGV2ZW50KVwiIGRhdGEtdGVzdGlkPVwic2VhcmNoRm9ybVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZWFyY2gtaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZWNvbmRhcnlcIiBbY2xhc3MuZGlzYWJsZWRdPVwiIWZvcm0udmFsaWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwia2V5Ym9hcmQta2V5XCI+RW50ZXI8L3NwYW4+IHRvIHNlYXJjaFxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8bGFiZWxcbiAgICAgICAgICAgICAgICAgICAgZm9yPVwic2VhcmNoSW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNlYXJjaC13cmFwcGVyXCJcbiAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmludmFsaWRdPVwiZm9ybS5pbnZhbGlkICYmIGZvcm0uZGlydHlcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkIGljb24tc2VhcmNoXCI+IHNlYXJjaCA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJzZWFyY2hJbnB1dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvY29tcGxldGU9XCJvZmZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwic2VhcmNoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiU2VhcmNoIHBhdHJvbnMuLi5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGtleWRvd24pPVwiaGFuZGxlU2VhcmNoS2V5UHJlc3MoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAjc2VhcmNoQm94XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhLXRlc3RpZD1cInNlYXJjaElucHV0XCJcbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgQGlmICghIXNlYXJjaEJveC52YWx1ZSAmJiBmb3JtLnZhbGlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWQgaWNvbi1jaGVja21hcmtcIj4gY2hlY2sgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBpZiAoc2VhcmNoQm94LnZhbHVlLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY2xlYXJTZWFyY2goKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQGxpYkhibGxGYWRlSW5PdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWQgaWNvbi1jbG9zZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICA8L2Zvcm0+XG4gICAgICAgICAgICA8ZmllbGRzZXRcbiAgICAgICAgICAgICAgICBjbGFzcz1cInNlYXJjaC1yZXN1bHRzLXdyYXBwZXJcIlxuICAgICAgICAgICAgICAgIGlkPVwicmVzdWx0c1Njcm9sbENvbnRhaW5lclwiXG4gICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJoYW5kbGVTZWxlY3RVc2VyKCRldmVudClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIEBpZiAoIWxvYWRpbmcgJiYgcmVzdWx0cygpKSB7XG4gICAgICAgICAgICAgICAgICAgIEBmb3IgKHVzZXIgb2YgcmVzdWx0cygpOyB0cmFjayB1c2VyLm5ldElkOyBsZXQgaWR4ID0gJGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJyZXN1bHQtZmllbGQgcmVzdWx0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuZm9jdXNdPVwidXNlci51c2VybmFtZSA9PT0gc2VsZWN0ZWRVc2VybmFtZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS10ZXN0aWQ9XCJyZXN1bHRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZm9yXT1cIidyZXN1bHRfJyArIGlkeFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy53YXJuaW5nXT1cInVzZXIucmVzdHJpY3RlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtb3VzZW92ZXIpPVwic2VsZWN0ZWRVc2VybmFtZSA9IHVzZXIudXNlcm5hbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmICh1c2VyLnJlc3RyaWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWF0ZXJpYWwtc3ltYm9scy1vdXRsaW5lZCBpY29uXCI+IHdhcm5pbmcgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWF0ZXJpYWwtc3ltYm9scy1vdXRsaW5lZCBpY29uXCI+IHBlcnNvbiA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm5ic3A7ICZuYnNwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBbdGl0bGVdPVwidXNlclwiIGRhdGEtdGVzdGlkPVwicmVzdWx0VGV4dFwiPnt7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VyIHwgaW1wZXJzb25hdGVVc2VyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJyYWRpb1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwidXNlci51c2VybmFtZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImhpZGRlblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaWRdPVwiJ3Jlc3VsdF8nICsgaWR4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU9XCJyZXN1bHRTZWxlY3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGtleWRvd24pPVwiaGFuZGxlUmVzdWx0S2V5UHJlc3MoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaW1wZXJzb25hdGUtYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS10ZXN0aWQ9XCJpbXBlcnNvbmF0ZUJ0blwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzdGFydEltcGVyc29uYXRpb24odXNlci51c2VybmFtZSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW1wZXJzb25hdGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9IEBlbXB0eSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVzdWx0LWZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTm8gcmVzdWx0cy4gVHJ5IHNlYXJjaGluZyBieSBOZXQgSUQgb3IgQllVIElELlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgQGlmIChsb2FkaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZXN1bHQtZmllbGRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsaWItc3Bpbm5lclwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgQGlmIChoYXNFcnJvcikge1xuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVzdWx0LWZpZWxkXCI+U29tZXRoaW5nIHdlbnQgd3JvbmcuIFdlJ2xsIGtlZXAgdHJ5aW5nLjwvZGl2PlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvZmllbGRzZXQ+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxufVxuIl19