@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
174 lines • 23.7 kB
JavaScript
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci1lbmdhZ2VtZW50cy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vY29yZS9wcm9kdWN0LWV4cGVyaWVuY2UvdXNlci1lbmdhZ2VtZW50cy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxRQUFRLElBQUksUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdkQsT0FBTyxFQUFFLGVBQWUsRUFBYyxhQUFhLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUM1RSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxxREFBcUQsQ0FBQztBQUM3RixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7OztBQUd0RCxNQUFNLE9BQU8sc0JBQXNCO0lBT2pDLFlBQzRCLFFBQWtCLEVBQ3BDLHNCQUE4QyxFQUM5QyxnQkFBa0M7UUFGaEIsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNwQywyQkFBc0IsR0FBdEIsc0JBQXNCLENBQXdCO1FBQzlDLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFUbkMsK0NBQTBDLEdBQUcscUJBQXFCLENBQUM7UUFDbkUsNEJBQXVCLEdBQTZCLElBQUksZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRS9FLGdDQUEyQixHQUFHLGFBQWEsQ0FBQztRQUNwQyxnQkFBVyxHQUFHLGFBQWEsQ0FBQztRQU8zQyxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUMvQixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILHFCQUFxQjtRQUNuQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsZUFBZTthQUNsQyxJ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QUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDckUsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxpQkFBaUIsQ0FBQyxPQUFlO1FBQ3ZDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3BELEtBQUssRUFBRSxNQUFNLEVBQUUsQ0FBQztJQUNsQixDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ssY0FBYyxDQUFDLE9BQWUsRUFBRSxXQUFtQjtRQUN6RCxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDMUMsT0FBTztRQUNULENBQUM7UUFDRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNuRCxLQUFLLENBQUMsRUFBRSxHQUFHLE9BQU8sQ0FBQztRQUNuQixLQUFLLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztRQUNoQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDeEMsQ0FBQzsrR0FwTFUsc0JBQXNCLGtCQVF2QixRQUFRO21IQVJQLHNCQUFzQixjQURULE1BQU07OzRGQUNuQixzQkFBc0I7a0JBRGxDLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFOzswQkFTN0IsTUFBTTsyQkFBQyxRQUFRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBET0NVTUVOVCBhcyBEb2N1bWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUsIGNvbWJpbmVMYXRlc3QsIGZyb20sIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBVc2VyUHJlZmVyZW5jZXNTZXJ2aWNlIH0gZnJvbSAnLi4vY29tbW9uL3VzZXItcHJlZmVyZW5jZXMvdXNlci1wcmVmZXJlbmNlcy5zZXJ2aWNlJztcbmltcG9ydCB7IEdhaW5zaWdodFNlcnZpY2UgfSBmcm9tICcuL2dhaW5zaWdodC5zZXJ2aWNlJztcbmltcG9ydCB7IHN3aXRjaE1hcCwgdGFrZSwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxuZXhwb3J0IGNsYXNzIFVzZXJFbmdhZ2VtZW50c1NlcnZpY2Uge1xuICByZWFkb25seSBVU0VSX1BSRUZFUkVOQ0VTX0dBSU5TSUdIVF9FTkdBR0VNRU5UU19LRVkgPSAnZ2FpbnNpZ2h0Qm90RW5hYmxlZCc7XG4gIHJlYWRvbmx5IHVzZXJFbmdhZ2VtZW50c0VuYWJsZWQkOiBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0KGZhbHNlKTtcblxuICByZWFkb25seSBISURFX0dBSU5TSUdIVF9CT1RfU1RZTEVfSUQgPSAnaGlkZS1ncy1ib3QnO1xuICBwcml2YXRlIHJlYWRvbmx5IEVOR0FHRU1FTlRTID0gJ2VuZ2FnZW1lbnRzJztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KERvY3VtZW50KSBwcml2YXRlIGRvY3VtZW50OiBEb2N1bWVudCxcbiAgICBwcml2YXRlIHVzZXJQcmVmZXJlbmNlc1NlcnZpY2U6IFVzZXJQcmVmZXJlbmNlc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBnYWluc2lnaHRTZXJ2aWNlOiBHYWluc2lnaHRTZXJ2aWNlXG4gICkge1xuICAgIHRoaXMuaGFuZGxlVXNlckVuZ2FnZW1lbnRzKCk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlcyB1c2VyIGVuZ2FnZW1lbnQgc2V0dGluZ3MgYmFzZWQgb24gdmFyaW91cyBjb25kaXRpb25zLlxuICAgKlxuICAgKiAtIFdhaXRzIGZvciB0aGUgR2FpbnNpZ2h0IHRyYWNraW5nIHRvIGJlIGxvYWRlZC5cbiAgICogLSBSZXRyaWV2ZXMgdGhlIGVuZ2FnZW1lbnQgc2V0dGluZ3MuXG4gICAqIC0gVXBkYXRlcyB0aGUgZW5nYWdlbWVudCBzZXR0aW5ncyBiYXNlZCBvbiB0aGUgY29tYmluZWQgb2JzZXJ2YXRpb25zLlxuICAgKiAtIEZpbmFsbHksIHRvZ2dsZXMgdGhlIEdhaW5zaWdodCBlbmdhZ2VtZW50cyBiYXNlZCBvbiB0aGUgbGF0ZXN0IGB1c2VyRW5nYWdlbWVudHNFbmFibGVkJGAgdmFsdWUuXG4gICAqL1xuICBoYW5kbGVVc2VyRW5nYWdlbWVudHMoKSB7XG4gICAgdGhpcy5nYWluc2lnaHRTZXJ2aWNlLnRyYWNraW5nTG9hZGVkJFxuICAgICAgLnBpcGUoXG4gICAgICAgIHRha2UoMSksXG4gICAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLmdldEVuZ2FnZW1lbnRTZXR0aW5nc09ic2VydmFibGUoKSksXG4gICAgICAgIHRhcCgoc2V0dGluZ3M6IFtib29sZWFuLCBib29sZWFuLCBib29sZWFuXSkgPT5cbiAgICAgICAgICB0aGlzLnVwZGF0ZVVzZXJFbmdhZ2VtZW50U2V0dGluZ3MoLi4uc2V0dGluZ3MpXG4gICAgICAgICksXG4gICAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLnVzZXJFbmdhZ2VtZW50c0VuYWJsZWQkLnBpcGUodGFrZSgxKSkpXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKGlzRW5hYmxlZCA9PiB0aGlzLnRvZ2dsZUdhaW5zaWdodEVuZ2FnZW1lbnRzKGlzRW5hYmxlZCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIHVzZXIncyBwcmVmZXJlbmNlIGZvciBHYWluc2lnaHQgRW5nYWdlbWVudHMuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNFbmFibGVkIC0gVGhlIG5ldyB2YWx1ZSBmb3IgdGhlIHVzZXIncyBlbmdhZ2VtZW50IHByZWZlcmVuY2UuXG4gICAqL1xuICB1cGRhdGVVc2VyRW5nYWdlbWVudFByZWZlcmVuY2UoaXNFbmFibGVkOiBib29sZWFuKSB7XG4gICAgdGhpcy51c2VyRW5nYWdlbWVudHNFbmFibGVkJC5uZXh0KGlzRW5hYmxlZCk7XG4gICAgdGhpcy51c2VyUHJlZmVyZW5jZXNTZXJ2aWNlLnNldChcbiAgICAgIHRoaXMuZ2FpbnNpZ2h0U2VydmljZS5VU0VSX1BSRUZFUkVOQ0VTX0dBSU5TSUdIVF9FTkdBR0VNRU5UU19LRVksXG4gICAgICB0aGlzLnVzZXJFbmdhZ2VtZW50c0VuYWJsZWQkLnZhbHVlXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUb2dnbGVzIHRoZSB2aXNpYmlsaXR5IG9mIEdhaW5zaWdodCBFbmdhZ2VtZW50cyBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgZmxhZy5cbiAgICpcbiAgICogQHBhcmFtIGlzRW5hYmxlZCAtIEEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgR2FpbnNpZ2h0IEVuZ2FnZW1lbnRzIHNob3VsZCBiZSB2aXNpYmxlLlxuICAgKi9cbiAgdG9nZ2xlR2FpbnNpZ2h0RW5nYWdlbWVudHMoaXNFbmFibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgaXNFbmFibGVkID8gdGhpcy5zaG93R2FpbnNpZ2h0RW5nYWdlbWVudHMoKSA6IHRoaXMuaGlkZUdhaW5zaWdodEVuZ2FnZW1lbnRzKCk7XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0cyBhbiBvYnNlcnZhYmxlIHRoYXQgZW1pdHMgYW4gYXJyYXkgb2YgYm9vbGVhbiB2YWx1ZXMgcmVwcmVzZW50aW5nXG4gICAqIHRoZSBjdXJyZW50IGVuZ2FnZW1lbnQgc2V0dGluZ3MuIFRoZSBvYnNlcnZhYmxlIGNvbWJpbmVzIHRoZSBsYXRlc3QgdmFsdWVzIGZyb206XG4gICAqXG4gICAqIDEuIFVzZXIncyBwcmVmZXJlbmNlcyBmb3IgR2FpbnNpZ2h0IGVuZ2FnZW1lbnRzLlxuICAgKiAyLiBBIGZsYWcgaW5kaWNhdGluZyBpZiBQSUkgZGF0YSBzaG91bGQgYmUgc2VudC5cbiAgICogMy4gQSBmbGFnIGluZGljYXRpbmcgaWYgdGhlIHBsYXRmb3JtIHVzZXMgY3VzdG9tIGJyYW5kaW5nLlxuICAgKlxuICAgKiBAcmV0dXJucyBBbiBvYnNlcnZhYmxlIGVtaXR0aW5nIGFuIGFycmF5IG9mIGJvb2xlYW4gdmFsdWVzLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXRFbmdhZ2VtZW50U2V0dGluZ3NPYnNlcnZhYmxlKCk6IE9ic2VydmFibGU8Ym9vbGVhbltdPiB7XG4gICAgcmV0dXJuIGNvbWJpbmVMYXRlc3QoW1xuICAgICAgdGhpcy51c2VyUHJlZmVyZW5jZXNTZXJ2aWNlLm9ic2VydmU8Ym9vbGVhbj4odGhpcy5VU0VSX1BSRUZFUkVOQ0VTX0dBSU5TSUdIVF9FTkdBR0VNRU5UU19LRVkpLFxuICAgICAgZnJvbSh0aGlzLmdhaW5zaWdodFNlcnZpY2Uuc2hvdWxkU2VuZFBpaURhdGEoKSksXG4gICAgICBvZih0aGlzLmdhaW5zaWdodFNlcnZpY2UuaXNDdXN0b21CcmFuZGluZygpKVxuICAgIF0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdXNlciBlbmdhZ2VtZW50IHNldHRpbmdzIGJhc2VkIG9uIHByb3ZpZGVkIHByZWZlcmVuY2VzIGFuZCBzZXR0aW5ncy5cbiAgICpcbiAgICogQmFzZWQgb24gdGhlIHJlY2VpdmVkIHZhbHVlcywgdGhlIG1ldGhvZCBkZWNpZGVzIHRvOlxuICAgKiAxLiBEaXNhYmxlIHVzZXIgZW5nYWdlbWVudHMgaWYgUElJIGRhdGEgc2hvdWxkIG5vdCBiZSBzaGFyZWQgb3IgY2VydGFpbiBicmFuZGluZy9zZXR0aW5ncyBjb25kaXRpb25zIGFyZSBtZXQuXG4gICAqIDIuIFVwZGF0ZSB0aGUgdXNlciBlbmdhZ2VtZW50IHByZWZlcmVuY2UgaWYgdGhlIHVzZXIgZW5nYWdlbWVudCBib3Qgc2V0dGluZyBpcyB1bmRlZmluZWQuXG4gICAqXG4gICAqIEBwYXJhbSB1c2VyRW5nYWdlbWVudEJvdFNldHRpbmcgLSBUaGUgdXNlcidzIHNldHRpbmcgZm9yIHRoZSBlbmdhZ2VtZW50IGJvdC5cbiAgICogQHBhcmFtIHNob3VsZFNlbmRQaWlEYXRhIC0gSW5kaWNhdGVzIHdoZXRoZXIgUElJIGRhdGEgc2hvdWxkIGJlIHNoYXJlZC5cbiAgICogQHBhcmFtIGhhc0N1c3RvbUJyYW5kaW5nIC0gSW5kaWNhdGVzIGlmIGN1c3RvbSBicmFuZGluZyBpcyBhcHBsaWVkLlxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVVc2VyRW5nYWdlbWVudFNldHRpbmdzKFxuICAgIHVzZXJFbmdhZ2VtZW50Qm90U2V0dGluZzogYm9vbGVhbiB8IHVuZGVmaW5lZCxcbiAgICBzaG91bGRTZW5kUGlpRGF0YTogYm9vbGVhbixcbiAgICBoYXNDdXN0b21CcmFuZGluZzogYm9vbGVhblxuICApOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zaG91bGREaXNhYmxlVXNlckVuZ2FnZW1lbnRzRHVlVG9QSUlEYXRhKHNob3VsZFNlbmRQaWlEYXRhKSkge1xuICAgICAgdGhpcy51c2VyRW5nYWdlbWVudHNFbmFibGVkJC5uZXh0KGZhbHNlKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuaXNVc2VyRW5nYWdlbWVudEJvdFNldHRpbmdVbmRlZmluZWQodXNlckVuZ2FnZW1lbnRCb3RTZXR0aW5nKSkge1xuICAgICAgLyoqXG4gICAgICAgKiBDYXNlIHdoZXJlIHRoZSB1c2VyIGlzIG5ldyAoZnJlc2hseSBjcmVhdGVkKSBhbmQgaGFzIG5vdCBjaGFuZ2VkIHRoZSB1c2VyIGVuZ2FnZW1lbnQgc2V0dGluZ3MgaW4gdGhlIHVzZXIgZWRpdCBtb2RhbCAodW50b3VjaGVkIHN0YXRlKS5cbiAgICAgICAqIFdoZW4gY3VzdG9tIGJyYW5kaW5nIGlzIG5vdCBzZXQsIHdlIHdpbGwgc2V0IHRoZSB1c2VyIGVuZ2FnZW1lbnRzIGluIHRoZSB1c2VyIHByZWZlcmVuY2VzIHRvIHRydWUgYnkgZGVmYXVsdC5cbiAgICAgICAqL1xuICAgICAgdGhpcy51cGRhdGVVc2VyRW5nYWdlbWVudFByZWZlcmVuY2UoIWhhc0N1c3RvbUJyYW5kaW5nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy51c2VyRW5nYWdlbWVudHNFbmFibGVkJC5uZXh0KHVzZXJFbmdhZ2VtZW50Qm90U2V0dGluZyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgd2hldGhlciB1c2VyIGVuZ2FnZW1lbnRzIHNob3VsZCBiZSBkaXNhYmxlZCBkdWUgdG8gUElJIGRhdGEgc2V0dGluZ3MuXG4gICAqXG4gICAqIElmIHRoZSBgc2hvdWxkU2VuZFBpaURhdGFgIHBhcmFtZXRlciBpcyBmYWxzZSwgdGhpcyBpbmRpY2F0ZXMgdGhhdCB0aGUgdXNlciBlbmdhZ2VtZW50c1xuICAgKiBzaG91bGQgYmUgZGlzYWJsZWQgdG8gcHJldmVudCBzaGFyaW5nIHBlcnNvbmFsbHkgaWRlbnRpZmlhYmxlIGluZm9ybWF0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IHNob3VsZFNlbmRQaWlEYXRhIC0gSW5kaWNhdGVzIHdoZXRoZXIgUElJIGRhdGEgaXMgYWxsb3dlZCB0byBiZSBzZW50LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyB0cnVlIGlmIHVzZXIgZW5nYWdlbWVudHMgc2hvdWxkIGJlIGRpc2FibGVkLCBvdGhlcndpc2UgZmFsc2UuXG4gICAqL1xuICBwcml2YXRlIHNob3VsZERpc2FibGVVc2VyRW5nYWdlbWVudHNEdWVUb1BJSURhdGEoc2hvdWxkU2VuZFBpaURhdGE6IGJvb2xlYW4pOiBib29sZWFuIHtcbiAgICByZXR1cm4gIXNob3VsZFNlbmRQaWlEYXRhO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgaWYgdGhlIHVzZXIgZW5nYWdlbWVudCBib3Qgc2V0dGluZyBpcyB1bmRlZmluZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7Ym9vbGVhbiB8IHVuZGVmaW5lZH0gdXNlckVuZ2FnZW1lbnRCb3RTZXR0aW5nIC0gVGhlIHNldHRpbmcgdmFsdWUgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgc2V0dGluZyBpcyB1bmRlZmluZWQ7IG90aGVyd2lzZSwgYGZhbHNlYC5cbiAgICpcbiAgICogVGhpcyBzY2VuYXJpbyBvY2N1cnMgd2hlbiBhIHVzZXIgaXMgbmV3IGFuZCBoYXNuJ3QgbW9kaWZpZWQgdGhlIGJvdCBzZXR0aW5ncyBpbiB0aGUgdXNlciBkZXRhaWxzIFVJIHlldC5cbiAgICovXG4gIHByaXZhdGUgaXNVc2VyRW5nYWdlbWVudEJvdFNldHRpbmdVbmRlZmluZWQoXG4gICAgdXNlckVuZ2FnZW1lbnRCb3RTZXR0aW5nOiBib29sZWFuIHwgdW5kZWZpbmVkXG4gICk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB1c2VyRW5nYWdlbWVudEJvdFNldHRpbmcgPT09IHVuZGVmaW5lZDtcbiAgfVxuICAvKipcbiAgICogRW5hYmxlcyB0aGUgdmlzaWJpbGl0eSBvZiBHYWluc2lnaHQgZW5nYWdlbWVudHMuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIHJlbW92ZXMgdGhlIENTUyBzdHlsZXMgdGhhdCBoaWRlIHRoZSBHYWluc2lnaHQgZW5nYWdlbWVudHNcbiAgICogYW5kIHVwZGF0ZXMgdGhlIHJlbGV2YW50IHVzZXIgYXR0cmlidXRlIHRvIG1hcmsgdGhlIGVuZ2FnZW1lbnRzIGFzIHZpc2libGUuXG4gICAqL1xuICBwcml2YXRlIHNob3dHYWluc2lnaHRFbmdhZ2VtZW50cygpOiB2b2lkIHtcbiAgICB0aGlzLnJlbW92ZUhpZGluZ1N0eWxlKHRoaXMuSElERV9HQUlOU0lHSFRfQk9UX1NUWUxFX0lEKTtcbiAgICB0aGlzLmdhaW5zaWdodFNlcnZpY2UudXBkYXRlVXNlckF0dHJpYnV0ZSh0aGlzLkVOR0FHRU1FTlRTLCB0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIaWRlcyB0aGUgR2FpbnNpZ2h0IGVuZ2FnZW1lbnRzLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBhcHBsaWVzIENTUyBzdHlsZXMgdG8gaGlkZSB0aGUgR2FpbnNpZ2h0IGVuZ2FnZW1lbnRzXG4gICAqIGFuZCB1cGRhdGVzIHRoZSByZWxldmFudCB1c2VyIGF0dHJpYnV0ZSB0byBtYXJrIHRoZSBlbmdhZ2VtZW50cyBhcyBoaWRkZW4uXG4gICAqL1xuICBwcml2YXRlIGhpZGVHYWluc2lnaHRFbmdhZ2VtZW50cygpOiB2b2lkIHtcbiAgICB0aGlzLmFkZEhpZGluZ1N0eWxlKHRoaXMuSElERV9HQUlOU0lHSFRfQk9UX1NUWUxFX0lELCAnI2FwdC13aWRnZXQgeyBkaXNwbGF5Om5vbmUgfScpO1xuICAgIHRoaXMuZ2FpbnNpZ2h0U2VydmljZS51cGRhdGVVc2VyQXR0cmlidXRlKHRoaXMuRU5HQUdFTUVOVFMsIGZhbHNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIHRoZSBzcGVjaWZpZWQgQ1NTIHN0eWxlIGZyb20gdGhlIGRvY3VtZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3R5bGVJZCAtIFRoZSBJRCBvZiB0aGUgQ1NTIHN0eWxlIGVsZW1lbnQgdG8gcmVtb3ZlLlxuICAgKi9cbiAgcHJpdmF0ZSByZW1vdmVIaWRpbmdTdHlsZShzdHlsZUlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBzdHlsZSA9IHRoaXMuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoc3R5bGVJZCk7XG4gICAgc3R5bGU/LnJlbW92ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBuZXcgQ1NTIHN0eWxlIHRvIHRoZSBkb2N1bWVudC5cbiAgICpcbiAgICogSWYgdGhlIHN0eWxlIHdpdGggdGhlIHNwZWNpZmllZCBJRCBhbHJlYWR5IGV4aXN0cywgdGhlIG1ldGhvZCB3aWxsIGRvIG5vdGhpbmcuXG4gICAqIE90aGVyd2lzZSwgaXQgY3JlYXRlcyBhIG5ldyBgPHN0eWxlPmAgZWxlbWVudCB3aXRoIHRoZSBnaXZlbiBJRCBhbmQgY29udGVudCxcbiAgICogdGhlbiBhcHBlbmRzIGl0IHRvIHRoZSBkb2N1bWVudCBoZWFkLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3R5bGVJZCAtIFRoZSBJRCB0byBhc3NpZ24gdG8gdGhlIG5ldyBzdHlsZSBlbGVtZW50LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dENvbnRlbnQgLSBUaGUgQ1NTIHJ1bGVzIHRvIGJlIGluY2x1ZGVkIGluIHRoZSBzdHlsZS5cbiAgICovXG4gIHByaXZhdGUgYWRkSGlkaW5nU3R5bGUoc3R5bGVJZDogc3RyaW5nLCB0ZXh0Q29udGVudDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoc3R5bGVJZCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc3R5bGUgPSB0aGlzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7XG4gICAgc3R5bGUuaWQgPSBzdHlsZUlkO1xuICAgIHN0eWxlLnRleHRDb250ZW50ID0gdGV4dENvbnRlbnQ7XG4gICAgdGhpcy5kb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHN0eWxlKTtcbiAgfVxufVxuIl19