UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

174 lines 23.7 kB
import { Inject, Injectable } from '@angular/core'; import { DOCUMENT as Document } from '@angular/common'; import { BehaviorSubject, combineLatest, from, of } from 'rxjs'; import { UserPreferencesService } from '../common/user-preferences/user-preferences.service'; import { GainsightService } from './gainsight.service'; import { switchMap, take, tap } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "../common/user-preferences/user-preferences.service"; import * as i2 from "./gainsight.service"; export class UserEngagementsService { constructor(document, userPreferencesService, gainsightService) { this.document = document; this.userPreferencesService = userPreferencesService; this.gainsightService = gainsightService; this.USER_PREFERENCES_GAINSIGHT_ENGAGEMENTS_KEY = 'gainsightBotEnabled'; this.userEngagementsEnabled$ = new BehaviorSubject(false); this.HIDE_GAINSIGHT_BOT_STYLE_ID = 'hide-gs-bot'; this.ENGAGEMENTS = 'engagements'; this.handleUserEngagements(); } /** * Handles user engagement settings based on various conditions. * * - Waits for the Gainsight tracking to be loaded. * - Retrieves the engagement settings. * - Updates the engagement settings based on the combined observations. * - Finally, toggles the Gainsight engagements based on the latest `userEngagementsEnabled$` value. */ handleUserEngagements() { this.gainsightService.trackingLoaded$ .pipe(take(1), switchMap(() => this.getEngagementSettingsObservable()), tap((settings) => this.updateUserEngagementSettings(...settings)), switchMap(() => this.userEngagementsEnabled$.pipe(take(1)))) .subscribe(isEnabled => this.toggleGainsightEngagements(isEnabled)); } /** * Updates the user's preference for Gainsight Engagements. * @param {boolean} isEnabled - The new value for the user's engagement preference. */ updateUserEngagementPreference(isEnabled) { this.userEngagementsEnabled$.next(isEnabled); this.userPreferencesService.set(this.gainsightService.USER_PREFERENCES_GAINSIGHT_ENGAGEMENTS_KEY, this.userEngagementsEnabled$.value); } /** * Toggles the visibility of Gainsight Engagements based on the provided flag. * * @param isEnabled - A flag indicating whether Gainsight Engagements should be visible. */ toggleGainsightEngagements(isEnabled) { isEnabled ? this.showGainsightEngagements() : this.hideGainsightEngagements(); } /** * Constructs an observable that emits an array of boolean values representing * the current engagement settings. The observable combines the latest values from: * * 1. User's preferences for Gainsight engagements. * 2. A flag indicating if PII data should be sent. * 3. A flag indicating if the platform uses custom branding. * * @returns An observable emitting an array of boolean values. */ getEngagementSettingsObservable() { return combineLatest([ this.userPreferencesService.observe(this.USER_PREFERENCES_GAINSIGHT_ENGAGEMENTS_KEY), from(this.gainsightService.shouldSendPiiData()), of(this.gainsightService.isCustomBranding()) ]); } /** * Updates user engagement settings based on provided preferences and settings. * * Based on the received values, the method decides to: * 1. Disable user engagements if PII data should not be shared or certain branding/settings conditions are met. * 2. Update the user engagement preference if the user engagement bot setting is undefined. * * @param userEngagementBotSetting - The user's setting for the engagement bot. * @param shouldSendPiiData - Indicates whether PII data should be shared. * @param hasCustomBranding - Indicates if custom branding is applied. */ updateUserEngagementSettings(userEngagementBotSetting, shouldSendPiiData, hasCustomBranding) { if (this.shouldDisableUserEngagementsDueToPIIData(shouldSendPiiData)) { this.userEngagementsEnabled$.next(false); } else if (this.isUserEngagementBotSettingUndefined(userEngagementBotSetting)) { /** * Case where the user is new (freshly created) and has not changed the user engagement settings in the user edit modal (untouched state). * When custom branding is not set, we will set the user engagements in the user preferences to true by default. */ this.updateUserEngagementPreference(!hasCustomBranding); } else { this.userEngagementsEnabled$.next(userEngagementBotSetting); } } /** * Determines whether user engagements should be disabled due to PII data settings. * * If the `shouldSendPiiData` parameter is false, this indicates that the user engagements * should be disabled to prevent sharing personally identifiable information. * * @param {boolean} shouldSendPiiData - Indicates whether PII data is allowed to be sent. * @returns {boolean} Returns true if user engagements should be disabled, otherwise false. */ shouldDisableUserEngagementsDueToPIIData(shouldSendPiiData) { return !shouldSendPiiData; } /** * Determines if the user engagement bot setting is undefined. * * @param {boolean | undefined} userEngagementBotSetting - The setting value to check. * @returns {boolean} Returns `true` if the setting is undefined; otherwise, `false`. * * This scenario occurs when a user is new and hasn't modified the bot settings in the user details UI yet. */ isUserEngagementBotSettingUndefined(userEngagementBotSetting) { return userEngagementBotSetting === undefined; } /** * Enables the visibility of Gainsight engagements. * * This method removes the CSS styles that hide the Gainsight engagements * and updates the relevant user attribute to mark the engagements as visible. */ showGainsightEngagements() { this.removeHidingStyle(this.HIDE_GAINSIGHT_BOT_STYLE_ID); this.gainsightService.updateUserAttribute(this.ENGAGEMENTS, true); } /** * Hides the Gainsight engagements. * * This method applies CSS styles to hide the Gainsight engagements * and updates the relevant user attribute to mark the engagements as hidden. */ hideGainsightEngagements() { this.addHidingStyle(this.HIDE_GAINSIGHT_BOT_STYLE_ID, '#apt-widget { display:none }'); this.gainsightService.updateUserAttribute(this.ENGAGEMENTS, false); } /** * Removes the specified CSS style from the document. * * @param {string} styleId - The ID of the CSS style element to remove. */ removeHidingStyle(styleId) { const style = this.document.getElementById(styleId); style?.remove(); } /** * Adds a new CSS style to the document. * * If the style with the specified ID already exists, the method will do nothing. * Otherwise, it creates a new `<style>` element with the given ID and content, * then appends it to the document head. * * @param {string} styleId - The ID to assign to the new style element. * @param {string} textContent - The CSS rules to be included in the style. */ addHidingStyle(styleId, textContent) { if (this.document.getElementById(styleId)) { return; } const style = this.document.createElement('style'); style.id = styleId; style.textContent = textContent; this.document.head.appendChild(style); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: UserEngagementsService, deps: [{ token: Document }, { token: i1.UserPreferencesService }, { token: i2.GainsightService }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: UserEngagementsService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: UserEngagementsService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: Document, decorators: [{ type: Inject, args: [Document] }] }, { type: i1.UserPreferencesService }, { type: i2.GainsightService }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1lbmdhZ2VtZW50cy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vY29yZS9wcm9kdWN0LWV4cGVyaWVuY2UvdXNlci1lbmdhZ2VtZW50cy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxRQUFRLElBQUksUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdkQsT0FBTyxFQUFFLGVBQWUsRUFBYyxhQUFhLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUM1RSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxxREFBcUQsQ0FBQztBQUM3RixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7OztBQUd0RCxNQUFNLE9BQU8sc0JBQXNCO0lBT2pDLFlBQzRCLFFBQWtCLEVBQ3BDLHNCQUE4QyxFQUM5QyxnQkFBa0M7UUFGaEIsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNwQywyQkFBc0IsR0FBdEIsc0JBQXNCLENBQXdCO1FBQzlDLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFUbkMsK0NBQTBDLEdBQUcscUJBQXFCLENBQUM7UUFDbkUsNEJBQXVCLEdBQTZCLElBQUksZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRS9FLGdDQUEyQixHQUFHLGFBQWEsQ0FBQztRQUNwQyxnQkFBVyxHQUFHLGFBQWEsQ0FBQztRQU8zQyxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUMvQixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILHFCQUFxQjtRQUNuQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsZUFBZTthQUNsQyxJQUFJLENBQ0gsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUNQLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsK0JBQStCLEVBQUUsQ0FBQyxFQUN2RCxHQUFHLENBQUMsQ0FBQyxRQUFxQyxFQUFFLEVBQUUsQ0FDNUMsSUFBSSxDQUFDLDRCQUE0QixDQUFDLEdBQUcsUUFBUSxDQUFDLENBQy9DLEVBQ0QsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FDNUQ7YUFDQSxTQUFTLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsMEJBQTBCLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztJQUN4RSxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsOEJBQThCLENBQUMsU0FBa0I7UUFDL0MsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM3QyxJQUFJLENBQUMsc0JBQXNCLENBQUMsR0FBRyxDQUM3QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsMENBQTBDLEVBQ2hFLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxLQUFLLENBQ25DLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILDBCQUEwQixDQUFDLFNBQWtCO1FBQzNDLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO0lBQ2hGLENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDSywrQkFBK0I7UUFDckMsT0FBTyxhQUFhLENBQUM7WUFDbkIsSUFBSSxDQUFDLHNCQUFzQixDQUFDLE9BQU8sQ0FBVSxJQUFJLENBQUMsMENBQTBDLENBQUM7WUFDN0YsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQy9DLEVBQUUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztTQUM3QyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNLLDRCQUE0QixDQUNsQyx3QkFBNkMsRUFDN0MsaUJBQTBCLEVBQzFCLGlCQUEwQjtRQUUxQixJQUFJLElBQUksQ0FBQyx3Q0FBd0MsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUM7WUFDckUsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMzQyxDQUFDO2FBQU0sSUFBSSxJQUFJLENBQUMsbUNBQW1DLENBQUMsd0JBQXdCLENBQUMsRUFBRSxDQUFDO1lBQzlFOzs7ZUFHRztZQUNILElBQUksQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDMUQsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLENBQUM7UUFDOUQsQ0FBQztJQUNILENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNLLHdDQUF3QyxDQUFDLGlCQUEwQjtRQUN6RSxPQUFPLENBQUMsaUJBQWlCLENBQUM7SUFDNUIsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSyxtQ0FBbUMsQ0FDekMsd0JBQTZDO1FBRTdDLE9BQU8sd0JBQXdCLEtBQUssU0FBUyxDQUFDO0lBQ2hELENBQUM7SUFDRDs7Ozs7T0FLRztJQUNLLHdCQUF3QjtRQUM5QixJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLENBQUM7UUFDekQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDcEUsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ssd0JBQXdCO1FBQzlCLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLDJCQUEyQixFQUFFLDhCQUE4QixDQUFDLENBQUM7UUFDdEYsSUFBSSxDQUFDLGdCQUFnQixDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDckUsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxpQkFBaUIsQ0FBQyxPQUFlO1FBQ3ZDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3BELEtBQUssRUFBRSxNQUFNLEVBQUUsQ0FBQztJQUNsQixDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ssY0FBYyxDQUFDLE9BQWUsRUFBRSxXQUFtQjtRQUN6RCxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDMUMsT0FBTztRQUNULENBQUM7UUFDRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNuRCxLQUFLLENBQUMsRUFBRSxHQUFHLE9BQU8sQ0FBQztRQUNuQixLQUFLLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztRQUNoQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDeEMsQ0FBQzsrR0FwTFUsc0JBQXNCLGtCQVF2QixRQUFRO21IQVJQLHNCQUFzQixjQURULE1BQU07OzRGQUNuQixzQkFBc0I7a0JBRGxDLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFOzswQkFTN0IsTUFBTTsyQkFBQyxRQUFRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBET0NVTUVOVCBhcyBEb2N1bWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUsIGNvbWJpbmVMYXRlc3QsIGZyb20sIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBVc2VyUHJlZmVyZW5jZXNTZXJ2aWNlIH0gZnJvbSAnLi4vY29tbW9uL3VzZXItcHJlZmVyZW5jZXMvdXNlci1wcmVmZXJlbmNlcy5zZXJ2aWNlJztcbmltcG9ydCB7IEdhaW5zaWdodFNlcnZpY2UgfSBmcm9tICcuL2dhaW5zaWdodC5zZXJ2aWNlJztcbmltcG9ydCB7IHN3aXRjaE1hcCwgdGFrZSwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxuZXhwb3J0IGNsYXNzIFVzZXJFbmdhZ2VtZW50c1NlcnZpY2Uge1xuICByZWFkb25seSBVU0VSX1BSRUZFUkVOQ0VTX0dBSU5TSUdIVF9FTkdBR0VNRU5UU19LRVkgPSAnZ2FpbnNpZ2h0Qm90RW5hYmxlZCc7XG4gIHJlYWRvbmx5IHVzZXJFbmdhZ2VtZW50c0VuYWJsZWQkOiBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0KGZhbHNlKTtcblxuICByZWFkb25seSBISURFX0dBSU5TSUdIVF9CT1RfU1RZTEVfSUQgPSAnaGlkZS1ncy1ib3QnO1xuICBwcml2YXRlIHJlYWRvbmx5IEVOR0FHRU1FTlRTID0gJ2VuZ2FnZW1lbnRzJztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KERvY3VtZW50KSBwcml2YXRlIGRvY3VtZW50OiBEb2N1bWVudCxcbiAgICBwcml2YXRlIHVzZXJQcmVmZXJlbmNlc1NlcnZpY2U6IFVzZXJQcmVmZXJlbmNlc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBnYWluc2lnaHRTZXJ2aWNlOiBHYWluc2lnaHRTZXJ2aWNlXG4gICkge1xuICAgIHRoaXMuaGFuZGxlVXNlckVuZ2FnZW1lbnRzKCk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlcyB1c2VyIGVuZ2FnZW1lbnQgc2V0dGluZ3MgYmFzZWQgb24gdmFyaW91cyBjb25kaXRpb25zLlxuICAgKlxuICAgKiAtIFdhaXRzIGZvciB0aGUgR2FpbnNpZ2h0IHRyYWNraW5nIHRvIGJlIGxvYWRlZC5cbiAgICogLSBSZXRyaWV2ZXMgdGhlIGVuZ2FnZW1lbnQgc2V0dGluZ3MuXG4gICAqIC0gVXBkYXRlcyB0aGUgZW5nYWdlbWVudCBzZXR0aW5ncyBiYXNlZCBvbiB0aGUgY29tYmluZWQgb2JzZXJ2YXRpb25zLlxuICAgKiAtIEZpbmFsbHksIHRvZ2dsZXMgdGhlIEdhaW5zaWdodCBlbmdhZ2VtZW50cyBiYXNlZCBvbiB0aGUgbGF0ZXN0IGB1c2VyRW5nYWdlbWVudHNFbmFibGVkJGAgdmFsdWUuXG4gICAqL1xuICBoYW5kbGVVc2VyRW5nYWdlbWVudHMoKSB7XG4gICAgdGhpcy5nYWluc2lnaHRTZXJ2aWNlLnRyYWNraW5nTG9hZGVkJFxuICAgICAgLnBpcGUoXG4gICAgICAgIHRha2UoMSksXG4gICAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLmdldEVuZ2FnZW1lbnRTZXR0aW5nc09ic2VydmFibGUoKSksXG4gICAgICAgIHRhcCgoc2V0dGluZ3M6IFtib29sZWFuLCBib29sZWFuLCBib29sZWFuXSkgPT5cbiAgICAgICAgICB0aGlzLnVwZGF0ZVVzZXJFbmdhZ2VtZW50U2V0dGluZ3MoLi4uc2V0dGluZ3MpXG4gICAgICAgICksXG4gICAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLnVzZXJFbmdhZ2VtZW50c0VuYWJsZWQkLnBpcGUodGFrZSgxKSkpXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKGlzRW5hYmxlZCA9PiB0aGlzLnRvZ2dsZUdhaW5zaWdodEVuZ2FnZW1lbnRzKGlzRW5hYmxlZCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIHVzZXIncyBwcmVmZXJlbmNlIGZvciBHYWluc2lnaHQgRW5nYWdlbWVudHMuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNFbmFibGVkIC0gVGhlIG5ldyB2YWx1ZSBmb3IgdGhlIHVzZXIncyBlbmdhZ2VtZW50IHByZWZlcmVuY2UuXG4gICAqL1xuICB1cGRhdGVVc2VyRW5nYWdlbWVudFByZWZlcmVuY2UoaXNFbmFibGVkOiBib29sZWFuKSB7XG4gICAgdGhpcy51c2VyRW5nYWdlbWVudHNFbmFibGVkJC5uZXh0KGlzRW5hYmxlZCk7XG4gICAgdGhpcy51c2VyUHJlZmVyZW5jZXNTZXJ2aWNlLnNldChcbiAgICAgIHRoaXMuZ2FpbnNpZ2h0U2VydmljZS5VU0VSX1BSRUZFUkVOQ0VTX0dBSU5TSUdIVF9FTkdBR0VNRU5UU19LRVksXG4gICAgICB0aGlzLnVzZXJFbmdhZ2VtZW50c0VuYWJsZWQkLnZhbHVlXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUb2dnbGVzIHRoZSB2aXNpYmlsaXR5IG9mIEdhaW5zaWdodCBFbmdhZ2VtZW50cyBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgZmxhZy5cbiAgICpcbiAgICogQHBhcmFtIGlzRW5hYmxlZCAtIEEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgR2FpbnNpZ2h0IEVuZ2FnZW1lbnRzIHNob3VsZCBiZSB2aXNpYmxlLlxuICAgKi9cbiAgdG9nZ2xlR2FpbnNpZ2h0RW5nYWdlbWVudHMoaXNFbmFibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgaXNFbmFibGVkID8gdGhpcy5zaG93R2FpbnNpZ2h0RW5nYWdlbWVudHMoKSA6IHRoaXMuaGlkZUdhaW5zaWdodEVuZ2FnZW1lbnRzKCk7XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0cyBhbiBvYnNlcnZhYmxlIHRoYXQgZW1pdHMgYW4gYXJyYXkgb2YgYm9vbGVhbiB2YWx1ZXMgcmVwcmVzZW50aW5nXG4gICAqIHRoZSBjdXJyZW50IGVuZ2FnZW1lbnQgc2V0dGluZ3MuIFRoZSBvYnNlcnZhYmxlIGNvbWJpbmVzIHRoZSBsYXRlc3QgdmFsdWVzIGZyb206XG4gICAqXG4gICAqIDEuIFVzZXIncyBwcmVmZXJlbmNlcyBmb3IgR2FpbnNpZ2h0IGVuZ2FnZW1lbnRzLlxuICAgKiAyLiBBIGZsYWcgaW5kaWNhdGluZyBpZiBQSUkgZGF0YSBzaG91bGQgYmUgc2VudC5cbiAgICogMy4gQSBmbGFnIGluZGljYXRpbmcgaWYgdGhlIHBsYXRmb3JtIHVzZXMgY3VzdG9tIGJyYW5kaW5nLlxuICAgKlxuICAgKiBAcmV0dXJucyBBbiBvYnNlcnZhYmxlIGVtaXR0aW5nIGFuIGFycmF5IG9mIGJvb2xlYW4gdmFsdWVzLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXRFbmdhZ2VtZW50U2V0dGluZ3NPYnNlcnZhYmxlKCk6IE9ic2VydmFibGU8Ym9vbGVhbltdPiB7XG4gICAgcmV0dXJuIGNvbWJpbmVMYXRlc3QoW1xuICAgICAgdGhpcy51c2VyUHJlZmVyZW5jZXNTZXJ2aWNlLm9ic2VydmU8Ym9vbGVhbj4odGhpcy5VU0VSX1BSRUZFUkVOQ0VTX0dBSU5TSUdIVF9FTkdBR0VNRU5UU19LRVkpLFxuICAgICAgZnJvbSh0aGlzLmdhaW5zaWdodFNlcnZpY2Uuc2hvdWxkU2VuZFBpaURhdGEoKSksXG4gICAgICBvZih0aGlzLmdhaW5zaWdodFNlcnZpY2UuaXNDdXN0b21CcmFuZGluZygpKVxuICAgIF0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdXNlciBlbmdhZ2VtZW50IHNldHRpbmdzIGJhc2VkIG9uIHByb3ZpZGVkIHByZWZlcmVuY2VzIGFuZCBzZXR0aW5ncy5cbiAgICpcbiAgICogQmFzZWQgb24gdGhlIHJlY2VpdmVkIHZhbHVlcywgdGhlIG1ldGhvZCBkZWNpZGVzIHRvOlxuICAgKiAxLiBEaXNhYmxlIHVzZXIgZW5nYWdlbWVudHMgaWYgUElJIGRhdGEgc2hvdWxkIG5vdCBiZSBzaGFyZWQgb3IgY2VydGFpbiBicmFuZGluZy9zZXR0aW5ncyBjb25kaXRpb25zIGFyZSBtZXQuXG4gICAqIDIuIFVwZGF0ZSB0aGUgdXNlciBlbmdhZ2VtZW50IHByZWZlcmVuY2UgaWYgdGhlIHVzZXIgZW5nYWdlbWVudCBib3Qgc2V0dGluZyBpcyB1bmRlZmluZWQuXG4gICAqXG4gICAqIEBwYXJhbSB1c2VyRW5nYWdlbWVudEJvdFNldHRpbmcgLSBUaGUgdXNlcidzIHNldHRpbmcgZm9yIHRoZSBlbmdhZ2VtZW50IGJvdC5cbiAgICogQHBhcmFtIHNob3VsZFNlbmRQaWlEYXRhIC0gSW5kaWNhdGVzIHdoZXRoZXIgUElJIGRhdGEgc2hvdWxkIGJlIHNoYXJlZC5cbiAgICogQHBhcmFtIGhhc0N1c3RvbUJyYW5kaW5nIC0gSW5kaWNhdGVzIGlmIGN1c3RvbSBicmFuZGluZyBpcyBhcHBsaWVkLlxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVVc2VyRW5nYWdlbWVudFNldHRpbmdzKFxuICAgIHVzZXJFbmdhZ2VtZW50Qm90U2V0dGluZzogYm9vbGVhbiB8IHVuZGVmaW5lZCxcbiAgICBzaG91bGRTZW5kUGlpRGF0YTogYm9vbGVhbixcbiAgICBoYXNDdXN0b21CcmFuZGluZzogYm9vbGVhblxuICApOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zaG91bGREaXNhYmxlVXNlckVuZ2FnZW1lbnRzRHVlVG9QSUlEYXRhKHNob3VsZFNlbmRQaWlEYXRhKSkge1xuICAgICAgdGhpcy51c2VyRW5nYWdlbWVudHNFbmFibGVkJC5uZXh0KGZhbHNlKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuaXNVc2VyRW5nYWdlbWVudEJvdFNldHRpbmdVbmRlZmluZWQodXNlckVuZ2FnZW1lbnRCb3RTZXR0aW5nKSkge1xuICAgICAgLyoqXG4gICAgICAgKiBDYXNlIHdoZXJlIHRoZSB1c2VyIGlzIG5ldyAoZnJlc2hseSBjcmVhdGVkKSBhbmQgaGFzIG5vdCBjaGFuZ2VkIHRoZSB1c2VyIGVuZ2FnZW1lbnQgc2V0dGluZ3MgaW4gdGhlIHVzZXIgZWRpdCBtb2RhbCAodW50b3VjaGVkIHN0YXRlKS5cbiAgICAgICAqIFdoZW4gY3VzdG9tIGJyYW5kaW5nIGlzIG5vdCBzZXQsIHdlIHdpbGwgc2V0IHRoZSB1c2VyIGVuZ2FnZW1lbnRzIGluIHRoZSB1c2VyIHByZWZlcmVuY2VzIHRvIHRydWUgYnkgZGVmYXVsdC5cbiAgICAgICAqL1xuICAgICAgdGhpcy51cGRhdGVVc2VyRW5nYWdlbWVudFByZWZlcmVuY2UoIWhhc0N1c3RvbUJyYW5kaW5nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy51c2VyRW5nYWdlbWVudHNFbmFibGVkJC5uZXh0KHVzZXJFbmdhZ2VtZW50Qm90U2V0dGluZyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgd2hldGhlciB1c2VyIGVuZ2FnZW1lbnRzIHNob3VsZCBiZSBkaXNhYmxlZCBkdWUgdG8gUElJIGRhdGEgc2V0dGluZ3MuXG4gICAqXG4gICAqIElmIHRoZSBgc2hvdWxkU2VuZFBpaURhdGFgIHBhcmFtZXRlciBpcyBmYWxzZSwgdGhpcyBpbmRpY2F0ZXMgdGhhdCB0aGUgdXNlciBlbmdhZ2VtZW50c1xuICAgKiBzaG91bGQgYmUgZGlzYWJsZWQgdG8gcHJldmVudCBzaGFyaW5nIHBlcnNvbmFsbHkgaWRlbnRpZmlhYmxlIGluZm9ybWF0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IHNob3VsZFNlbmRQaWlEYXRhIC0gSW5kaWNhdGVzIHdoZXRoZXIgUElJIGRhdGEgaXMgYWxsb3dlZCB0byBiZSBzZW50LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyB0cnVlIGlmIHVzZXIgZW5nYWdlbWVudHMgc2hvdWxkIGJlIGRpc2FibGVkLCBvdGhlcndpc2UgZmFsc2UuXG4gICAqL1xuICBwcml2YXRlIHNob3VsZERpc2FibGVVc2VyRW5nYWdlbWVudHNEdWVUb1BJSURhdGEoc2hvdWxkU2VuZFBpaURhdGE6IGJvb2xlYW4pOiBib29sZWFuIHtcbiAgICByZXR1cm4gIXNob3VsZFNlbmRQaWlEYXRhO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgaWYgdGhlIHVzZXIgZW5nYWdlbWVudCBib3Qgc2V0dGluZyBpcyB1bmRlZmluZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7Ym9vbGVhbiB8IHVuZGVmaW5lZH0gdXNlckVuZ2FnZW1lbnRCb3RTZXR0aW5nIC0gVGhlIHNldHRpbmcgdmFsdWUgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgc2V0dGluZyBpcyB1bmRlZmluZWQ7IG90aGVyd2lzZSwgYGZhbHNlYC5cbiAgICpcbiAgICogVGhpcyBzY2VuYXJpbyBvY2N1cnMgd2hlbiBhIHVzZXIgaXMgbmV3IGFuZCBoYXNuJ3QgbW9kaWZpZWQgdGhlIGJvdCBzZXR0aW5ncyBpbiB0aGUgdXNlciBkZXRhaWxzIFVJIHlldC5cbiAgICovXG4gIHByaXZhdGUgaXNVc2VyRW5nYWdlbWVudEJvdFNldHRpbmdVbmRlZmluZWQoXG4gICAgdXNlckVuZ2FnZW1lbnRCb3RTZXR0aW5nOiBib29sZWFuIHwgdW5kZWZpbmVkXG4gICk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB1c2VyRW5nYWdlbWVudEJvdFNldHRpbmcgPT09IHVuZGVmaW5lZDtcbiAgfVxuICAvKipcbiAgICogRW5hYmxlcyB0aGUgdmlzaWJpbGl0eSBvZiBHYWluc2lnaHQgZW5nYWdlbWVudHMuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIHJlbW92ZXMgdGhlIENTUyBzdHlsZXMgdGhhdCBoaWRlIHRoZSBHYWluc2lnaHQgZW5nYWdlbWVudHNcbiAgICogYW5kIHVwZGF0ZXMgdGhlIHJlbGV2YW50IHVzZXIgYXR0cmlidXRlIHRvIG1hcmsgdGhlIGVuZ2FnZW1lbnRzIGFzIHZpc2libGUuXG4gICAqL1xuICBwcml2YXRlIHNob3dHYWluc2lnaHRFbmdhZ2VtZW50cygpOiB2b2lkIHtcbiAgICB0aGlzLnJlbW92ZUhpZGluZ1N0eWxlKHRoaXMuSElERV9HQUlOU0lHSFRfQk9UX1NUWUxFX0lEKTtcbiAgICB0aGlzLmdhaW5zaWdodFNlcnZpY2UudXBkYXRlVXNlckF0dHJpYnV0ZSh0aGlzLkVOR0FHRU1FTlRTLCB0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIaWRlcyB0aGUgR2FpbnNpZ2h0IGVuZ2FnZW1lbnRzLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBhcHBsaWVzIENTUyBzdHlsZXMgdG8gaGlkZSB0aGUgR2FpbnNpZ2h0IGVuZ2FnZW1lbnRzXG4gICAqIGFuZCB1cGRhdGVzIHRoZSByZWxldmFudCB1c2VyIGF0dHJpYnV0ZSB0byBtYXJrIHRoZSBlbmdhZ2VtZW50cyBhcyBoaWRkZW4uXG4gICAqL1xuICBwcml2YXRlIGhpZGVHYWluc2lnaHRFbmdhZ2VtZW50cygpOiB2b2lkIHtcbiAgICB0aGlzLmFkZEhpZGluZ1N0eWxlKHRoaXMuSElERV9HQUlOU0lHSFRfQk9UX1NUWUxFX0lELCAnI2FwdC13aWRnZXQgeyBkaXNwbGF5Om5vbmUgfScpO1xuICAgIHRoaXMuZ2FpbnNpZ2h0U2VydmljZS51cGRhdGVVc2VyQXR0cmlidXRlKHRoaXMuRU5HQUdFTUVOVFMsIGZhbHNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIHRoZSBzcGVjaWZpZWQgQ1NTIHN0eWxlIGZyb20gdGhlIGRvY3VtZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3R5bGVJZCAtIFRoZSBJRCBvZiB0aGUgQ1NTIHN0eWxlIGVsZW1lbnQgdG8gcmVtb3ZlLlxuICAgKi9cbiAgcHJpdmF0ZSByZW1vdmVIaWRpbmdTdHlsZShzdHlsZUlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBzdHlsZSA9IHRoaXMuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoc3R5bGVJZCk7XG4gICAgc3R5bGU/LnJlbW92ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBuZXcgQ1NTIHN0eWxlIHRvIHRoZSBkb2N1bWVudC5cbiAgICpcbiAgICogSWYgdGhlIHN0eWxlIHdpdGggdGhlIHNwZWNpZmllZCBJRCBhbHJlYWR5IGV4aXN0cywgdGhlIG1ldGhvZCB3aWxsIGRvIG5vdGhpbmcuXG4gICAqIE90aGVyd2lzZSwgaXQgY3JlYXRlcyBhIG5ldyBgPHN0eWxlPmAgZWxlbWVudCB3aXRoIHRoZSBnaXZlbiBJRCBhbmQgY29udGVudCxcbiAgICogdGhlbiBhcHBlbmRzIGl0IHRvIHRoZSBkb2N1bWVudCBoZWFkLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3R5bGVJZCAtIFRoZSBJRCB0byBhc3NpZ24gdG8gdGhlIG5ldyBzdHlsZSBlbGVtZW50LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dENvbnRlbnQgLSBUaGUgQ1NTIHJ1bGVzIHRvIGJlIGluY2x1ZGVkIGluIHRoZSBzdHlsZS5cbiAgICovXG4gIHByaXZhdGUgYWRkSGlkaW5nU3R5bGUoc3R5bGVJZDogc3RyaW5nLCB0ZXh0Q29udGVudDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoc3R5bGVJZCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc3R5bGUgPSB0aGlzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7XG4gICAgc3R5bGUuaWQgPSBzdHlsZUlkO1xuICAgIHN0eWxlLnRleHRDb250ZW50ID0gdGV4dENvbnRlbnQ7XG4gICAgdGhpcy5kb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHN0eWxlKTtcbiAgfVxufVxuIl19