@tuki-io/tuki-widgets 0.0.126 → 0.0.127

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/contact-center/cc-readiness/cc-readiness.module.d.ts +19 -0
  2. package/contact-center/cc-readiness/cc-readiness.service.d.ts +12 -0
  3. package/contact-center/cc-readiness/components/card/card.component.d.ts +6 -0
  4. package/contact-center/cc-readiness/types/cc-readiness.d.ts +20 -0
  5. package/contact-center/cc-readiness/widgets/licences-requirement/licences-requirement.component.d.ts +52 -0
  6. package/contact-center/cc-readiness/widgets/summary-grid/summary-grid.component.d.ts +26 -0
  7. package/contact-center/index.d.ts +5 -0
  8. package/contact-center/public-api.d.ts +3 -0
  9. package/contact-center/shared/api.endpoints.d.ts +6 -0
  10. package/contact-center/shared/api.service.d.ts +20 -0
  11. package/contact-center/shared/material.module.d.ts +15 -0
  12. package/contact-center/shared/shared.module.d.ts +10 -0
  13. package/esm2020/contact-center/cc-readiness/cc-readiness.module.mjs +71 -0
  14. package/esm2020/contact-center/cc-readiness/cc-readiness.service.mjs +35 -0
  15. package/esm2020/contact-center/cc-readiness/components/card/card.component.mjs +13 -0
  16. package/esm2020/contact-center/cc-readiness/types/cc-readiness.mjs +5 -0
  17. package/esm2020/contact-center/cc-readiness/widgets/licences-requirement/licences-requirement.component.mjs +187 -0
  18. package/esm2020/contact-center/cc-readiness/widgets/summary-grid/summary-grid.component.mjs +47 -0
  19. package/esm2020/contact-center/public-api.mjs +4 -0
  20. package/esm2020/contact-center/shared/api.endpoints.mjs +7 -0
  21. package/esm2020/contact-center/shared/api.service.mjs +86 -0
  22. package/esm2020/contact-center/shared/material.module.mjs +76 -0
  23. package/esm2020/contact-center/shared/shared.module.mjs +33 -0
  24. package/esm2020/contact-center/tuki-io-tuki-widgets-contact-center.mjs +5 -0
  25. package/esm2020/di2mt/shared/services/api.service.mjs +1 -1
  26. package/esm2020/users-list/src/users-list.component.mjs +3 -3
  27. package/fesm2015/tuki-io-tuki-widgets-contact-center.mjs +433 -0
  28. package/fesm2015/tuki-io-tuki-widgets-contact-center.mjs.map +1 -0
  29. package/fesm2015/tuki-io-tuki-widgets-di2mt.mjs.map +1 -1
  30. package/fesm2015/tuki-io-tuki-widgets-users-list.mjs +2 -2
  31. package/fesm2015/tuki-io-tuki-widgets-users-list.mjs.map +1 -1
  32. package/fesm2020/tuki-io-tuki-widgets-contact-center.mjs +430 -0
  33. package/fesm2020/tuki-io-tuki-widgets-contact-center.mjs.map +1 -0
  34. package/fesm2020/tuki-io-tuki-widgets-di2mt.mjs.map +1 -1
  35. package/fesm2020/tuki-io-tuki-widgets-users-list.mjs +2 -2
  36. package/fesm2020/tuki-io-tuki-widgets-users-list.mjs.map +1 -1
  37. package/package.json +9 -1
@@ -0,0 +1,19 @@
1
+ import * as i0 from "@angular/core";
2
+ import * as i1 from "./widgets/licences-requirement/licences-requirement.component";
3
+ import * as i2 from "./widgets/summary-grid/summary-grid.component";
4
+ import * as i3 from "./components/card/card.component";
5
+ import * as i4 from "@angular/common";
6
+ import * as i5 from "@angular/common/http";
7
+ import * as i6 from "ng-apexcharts";
8
+ import * as i7 from "@angular/material/table";
9
+ import * as i8 from "@angular/material/button";
10
+ import * as i9 from "@angular/material/checkbox";
11
+ import * as i10 from "@angular/material/select";
12
+ import * as i11 from "@angular/material/progress-spinner";
13
+ import * as i12 from "@angular/material/core";
14
+ import * as i13 from "@angular/material/paginator";
15
+ export declare class CcReadinessModule {
16
+ static ɵfac: i0.ɵɵFactoryDeclaration<CcReadinessModule, never>;
17
+ static ɵmod: i0.ɵɵNgModuleDeclaration<CcReadinessModule, [typeof i1.LicencesRequirementComponent, typeof i2.SummaryGridComponent, typeof i3.CardComponent], [typeof i4.CommonModule, typeof i5.HttpClientModule, typeof i6.NgApexchartsModule, typeof i7.MatTableModule, typeof i8.MatButtonModule, typeof i9.MatCheckboxModule, typeof i10.MatSelectModule, typeof i11.MatProgressSpinnerModule, typeof i12.MatOptionModule, typeof i13.MatPaginatorModule, typeof i10.MatSelectModule], [typeof i1.LicencesRequirementComponent, typeof i2.SummaryGridComponent]>;
18
+ static ɵinj: i0.ɵɵInjectorDeclaration<CcReadinessModule>;
19
+ }
@@ -0,0 +1,12 @@
1
+ import { UccxServerEntityStats, WebexLicenseUsageSummary } from './types/cc-readiness';
2
+ import { Observable } from 'rxjs';
3
+ import * as i0 from "@angular/core";
4
+ export declare class CcReadinessService {
5
+ private readonly api;
6
+ constructor();
7
+ fetchUccxServerEntityStats(customerId: number): Observable<UccxServerEntityStats[]>;
8
+ fetchWebexLicenseUsageSummary(customerId: number): Observable<WebexLicenseUsageSummary[]>;
9
+ setToken(token: string): void;
10
+ static ɵfac: i0.ɵɵFactoryDeclaration<CcReadinessService, never>;
11
+ static ɵprov: i0.ɵɵInjectableDeclaration<CcReadinessService>;
12
+ }
@@ -0,0 +1,6 @@
1
+ import * as i0 from "@angular/core";
2
+ export declare class CardComponent {
3
+ title: string;
4
+ static ɵfac: i0.ɵɵFactoryDeclaration<CardComponent, never>;
5
+ static ɵcmp: i0.ɵɵComponentDeclaration<CardComponent, "tk-card", never, { "title": "title"; }, {}, never, ["card-content"], false, never>;
6
+ }
@@ -0,0 +1,20 @@
1
+ export type EntityType = 'applications' | 'triggers' | 'contactServiceQueues' | 'resources' | 'resourceGroups' | 'skills' | 'xml' | 'scripts' | 'audioPrompts' | 'teams' | 'phonebooks' | 'wrapUpCodes';
2
+ export interface UccxServerEntityStats {
3
+ uccxIp: string;
4
+ counts: {
5
+ [key in EntityType]: number;
6
+ };
7
+ }
8
+ export interface WebexLicenseFeatureUsage {
9
+ feature: 'PERSON' | 'ORPHANED_DEVICE';
10
+ totalCount: number;
11
+ usageCount: number;
12
+ unUsedCount: number;
13
+ }
14
+ export interface WebexLicenseUsageSummary {
15
+ webexReadinessLicenseStats: WebexLicenseFeatureUsage[];
16
+ totalProfessionalLicenseCount: number;
17
+ totalWorkspaceProfessionalLicenseCount: number;
18
+ professionalWebexReadinessTotalLicenseStatCoverage: number;
19
+ workspaceWebexReadinessTotalLicenseStatCoverage: number;
20
+ }
@@ -0,0 +1,52 @@
1
+ import { OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core';
2
+ import { ApexChart, ApexDataLabels, ApexLegend, ApexNonAxisChartSeries, ApexPlotOptions } from 'ng-apexcharts';
3
+ import * as i0 from "@angular/core";
4
+ interface LicenseLegendItem {
5
+ label: string;
6
+ count: number;
7
+ percentage: number;
8
+ color: string;
9
+ }
10
+ interface LicenseTableRow {
11
+ label: string;
12
+ value: number;
13
+ }
14
+ interface LicenseChartOptions {
15
+ series: ApexNonAxisChartSeries;
16
+ chart: ApexChart;
17
+ labels: string[];
18
+ colors: string[];
19
+ legend: ApexLegend;
20
+ plotOptions: ApexPlotOptions;
21
+ dataLabels: ApexDataLabels;
22
+ }
23
+ interface LicenseRequirementViewModel {
24
+ chartOptions: LicenseChartOptions;
25
+ legendItems: LicenseLegendItem[];
26
+ rows: LicenseTableRow[];
27
+ totalRequired: number;
28
+ }
29
+ export declare class LicencesRequirementComponent implements OnInit, OnDestroy, OnChanges {
30
+ customerId: number;
31
+ token: string;
32
+ private readonly ccReadinessService;
33
+ private subscription?;
34
+ viewModel: LicenseRequirementViewModel | null;
35
+ loading: boolean;
36
+ error: boolean;
37
+ filters: string[];
38
+ selectedSummaryIndex: number;
39
+ private summary;
40
+ ngOnInit(): void;
41
+ ngOnDestroy(): void;
42
+ ngOnChanges(changes: SimpleChanges): void;
43
+ onFilterChange(index: number): void;
44
+ private loadSummaries;
45
+ private selectFilter;
46
+ private mapSummaryToViewModel;
47
+ private buildChartOptions;
48
+ private normalizePercentage;
49
+ static ɵfac: i0.ɵɵFactoryDeclaration<LicencesRequirementComponent, never>;
50
+ static ɵcmp: i0.ɵɵComponentDeclaration<LicencesRequirementComponent, "cc-licenses-requirement", never, { "customerId": "customerId"; "token": "token"; }, {}, never, never, false, never>;
51
+ }
52
+ export {};
@@ -0,0 +1,26 @@
1
+ import { OnInit } from "@angular/core";
2
+ import { Observable } from "rxjs";
3
+ import * as i0 from "@angular/core";
4
+ interface SummaryGridCount {
5
+ name: string;
6
+ value: number;
7
+ }
8
+ interface SummaryGridItem {
9
+ uccxIp: string;
10
+ counts: SummaryGridCount[];
11
+ }
12
+ export declare class SummaryGridComponent implements OnInit {
13
+ customerId: number;
14
+ token: string;
15
+ private readonly ccReadinessService;
16
+ readonly ENTITY_CONFIG: {
17
+ [key: string]: {
18
+ label: string;
19
+ };
20
+ };
21
+ data$: Observable<SummaryGridItem[]>;
22
+ ngOnInit(): void;
23
+ static ɵfac: i0.ɵɵFactoryDeclaration<SummaryGridComponent, never>;
24
+ static ɵcmp: i0.ɵɵComponentDeclaration<SummaryGridComponent, "cc-summary-grid", never, { "customerId": "customerId"; "token": "token"; }, {}, never, never, false, never>;
25
+ }
26
+ export {};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ /// <amd-module name="@tuki-io/tuki-widgets/contact-center" />
5
+ export * from './public-api';
@@ -0,0 +1,3 @@
1
+ export * from './cc-readiness/cc-readiness.module';
2
+ export * from './cc-readiness/widgets/summary-grid/summary-grid.component';
3
+ export * from './cc-readiness/widgets/licences-requirement/licences-requirement.component';
@@ -0,0 +1,6 @@
1
+ export declare const API: {
2
+ READINESS: {
3
+ UCCX_SERVER_ENTITY_STATS: (customerId: number) => string;
4
+ LICENSE_USAGE_SUMMARY: (customerId: number) => string;
5
+ };
6
+ };
@@ -0,0 +1,20 @@
1
+ import { HttpClient } from '@angular/common/http';
2
+ import { Observable } from 'rxjs';
3
+ import * as i0 from "@angular/core";
4
+ export declare class APIService {
5
+ private httpClient;
6
+ token: any;
7
+ apiUrl: string;
8
+ constructor(httpClient: HttpClient);
9
+ fetch(url: string, params?: any, cache?: boolean): Observable<any>;
10
+ post(url: string, body: any, params?: {}): Observable<any>;
11
+ postExtended(url: string, body?: null, params?: {}, headers?: {}): Observable<import("@angular/common/http").HttpResponse<Object>>;
12
+ put(url: string, body?: null, params?: {}): Observable<Object>;
13
+ delete(url: string, params?: {}): Observable<Object>;
14
+ fetchPagination(url: string, pageSize: number, pageNumber: number, additionalParams?: {}, cache?: boolean): Observable<any>;
15
+ private prepareEncodedParams;
16
+ private getHeaders;
17
+ private getParameterByName;
18
+ static ɵfac: i0.ɵɵFactoryDeclaration<APIService, never>;
19
+ static ɵprov: i0.ɵɵInjectableDeclaration<APIService>;
20
+ }
@@ -0,0 +1,15 @@
1
+ import * as i0 from "@angular/core";
2
+ import * as i1 from "@angular/material/progress-bar";
3
+ import * as i2 from "@angular/material/tooltip";
4
+ import * as i3 from "@angular/material/table";
5
+ import * as i4 from "@angular/material/checkbox";
6
+ import * as i5 from "@angular/material/button";
7
+ import * as i6 from "@angular/material/icon";
8
+ import * as i7 from "@angular/material/form-field";
9
+ import * as i8 from "@angular/material/input";
10
+ import * as i9 from "@angular/material/select";
11
+ export declare class MaterialModule {
12
+ static ɵfac: i0.ɵɵFactoryDeclaration<MaterialModule, never>;
13
+ static ɵmod: i0.ɵɵNgModuleDeclaration<MaterialModule, never, [typeof i1.MatProgressBarModule, typeof i2.MatTooltipModule, typeof i3.MatTableModule, typeof i4.MatCheckboxModule, typeof i5.MatButtonModule, typeof i6.MatIconModule, typeof i7.MatFormFieldModule, typeof i8.MatInputModule, typeof i9.MatSelectModule], [typeof i1.MatProgressBarModule, typeof i2.MatTooltipModule, typeof i3.MatTableModule, typeof i4.MatCheckboxModule, typeof i5.MatButtonModule, typeof i6.MatIconModule, typeof i7.MatFormFieldModule, typeof i8.MatInputModule, typeof i9.MatSelectModule]>;
14
+ static ɵinj: i0.ɵɵInjectorDeclaration<MaterialModule>;
15
+ }
@@ -0,0 +1,10 @@
1
+ import * as i0 from "@angular/core";
2
+ import * as i1 from "@angular/common";
3
+ import * as i2 from "./material.module";
4
+ import * as i3 from "ng-apexcharts";
5
+ import * as i4 from "@angular/common/http";
6
+ export declare class SharedModule {
7
+ static ɵfac: i0.ɵɵFactoryDeclaration<SharedModule, never>;
8
+ static ɵmod: i0.ɵɵNgModuleDeclaration<SharedModule, never, [typeof i1.CommonModule, typeof i2.MaterialModule, typeof i3.NgApexchartsModule, typeof i4.HttpClientModule], [typeof i2.MaterialModule]>;
9
+ static ɵinj: i0.ɵɵInjectorDeclaration<SharedModule>;
10
+ }
@@ -0,0 +1,71 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { HttpClientModule } from '@angular/common/http';
4
+ import { LicencesRequirementComponent } from './widgets/licences-requirement/licences-requirement.component';
5
+ import { SummaryGridComponent } from './widgets/summary-grid/summary-grid.component';
6
+ import { CardComponent } from './components/card/card.component';
7
+ import { NgApexchartsModule } from 'ng-apexcharts';
8
+ import { MatButtonModule } from '@angular/material/button';
9
+ import { MatCheckboxModule } from '@angular/material/checkbox';
10
+ import { MatOptionModule } from '@angular/material/core';
11
+ import { MatPaginatorModule } from '@angular/material/paginator';
12
+ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
13
+ import { MatSelectModule } from '@angular/material/select';
14
+ import { MatTableModule } from '@angular/material/table';
15
+ import * as i0 from "@angular/core";
16
+ export class CcReadinessModule {
17
+ }
18
+ CcReadinessModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CcReadinessModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
19
+ CcReadinessModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: CcReadinessModule, declarations: [LicencesRequirementComponent,
20
+ SummaryGridComponent,
21
+ CardComponent], imports: [CommonModule,
22
+ HttpClientModule,
23
+ NgApexchartsModule,
24
+ MatTableModule,
25
+ MatButtonModule,
26
+ MatCheckboxModule,
27
+ MatSelectModule,
28
+ MatProgressSpinnerModule,
29
+ MatOptionModule,
30
+ MatPaginatorModule,
31
+ MatSelectModule], exports: [LicencesRequirementComponent,
32
+ SummaryGridComponent] });
33
+ CcReadinessModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CcReadinessModule, imports: [CommonModule,
34
+ HttpClientModule,
35
+ NgApexchartsModule,
36
+ MatTableModule,
37
+ MatButtonModule,
38
+ MatCheckboxModule,
39
+ MatSelectModule,
40
+ MatProgressSpinnerModule,
41
+ MatOptionModule,
42
+ MatPaginatorModule,
43
+ MatSelectModule] });
44
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CcReadinessModule, decorators: [{
45
+ type: NgModule,
46
+ args: [{
47
+ declarations: [
48
+ LicencesRequirementComponent,
49
+ SummaryGridComponent,
50
+ CardComponent
51
+ ],
52
+ imports: [
53
+ CommonModule,
54
+ HttpClientModule,
55
+ NgApexchartsModule,
56
+ MatTableModule,
57
+ MatButtonModule,
58
+ MatCheckboxModule,
59
+ MatSelectModule,
60
+ MatProgressSpinnerModule,
61
+ MatOptionModule,
62
+ MatPaginatorModule,
63
+ MatSelectModule
64
+ ],
65
+ exports: [
66
+ LicencesRequirementComponent,
67
+ SummaryGridComponent
68
+ ]
69
+ }]
70
+ }] });
71
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2MtcmVhZGluZXNzLm1vZHVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3R1a2kvd2lkZ2V0cy9jb250YWN0LWNlbnRlci9jYy1yZWFkaW5lc3MvY2MtcmVhZGluZXNzLm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSwrREFBK0QsQ0FBQztBQUM3RyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwrQ0FBK0MsQ0FBQztBQUNyRixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDakUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR25ELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDekQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDakUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDOUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQzs7QUE0QnpELE1BQU0sT0FBTyxpQkFBaUI7OytHQUFqQixpQkFBaUI7Z0hBQWpCLGlCQUFpQixpQkF0QjFCLDRCQUE0QjtRQUM1QixvQkFBb0I7UUFDcEIsYUFBYSxhQUdiLFlBQVk7UUFDWixnQkFBZ0I7UUFDaEIsa0JBQWtCO1FBQ2xCLGNBQWM7UUFDZCxlQUFlO1FBQ2YsaUJBQWlCO1FBQ2pCLGVBQWU7UUFDZix3QkFBd0I7UUFDeEIsZUFBZTtRQUNmLGtCQUFrQjtRQUNsQixlQUFlLGFBR2YsNEJBQTRCO1FBQzVCLG9CQUFvQjtnSEFHWCxpQkFBaUIsWUFqQjFCLFlBQVk7UUFDWixnQkFBZ0I7UUFDaEIsa0JBQWtCO1FBQ2xCLGNBQWM7UUFDZCxlQUFlO1FBQ2YsaUJBQWlCO1FBQ2pCLGVBQWU7UUFDZix3QkFBd0I7UUFDeEIsZUFBZTtRQUNmLGtCQUFrQjtRQUNsQixlQUFlOzRGQU9OLGlCQUFpQjtrQkF4QjdCLFFBQVE7bUJBQUM7b0JBQ1IsWUFBWSxFQUFFO3dCQUNaLDRCQUE0Qjt3QkFDNUIsb0JBQW9CO3dCQUNwQixhQUFhO3FCQUNkO29CQUNELE9BQU8sRUFBRTt3QkFDUCxZQUFZO3dCQUNaLGdCQUFnQjt3QkFDaEIsa0JBQWtCO3dCQUNsQixjQUFjO3dCQUNkLGVBQWU7d0JBQ2YsaUJBQWlCO3dCQUNqQixlQUFlO3dCQUNmLHdCQUF3Qjt3QkFDeEIsZUFBZTt3QkFDZixrQkFBa0I7d0JBQ2xCLGVBQWU7cUJBQ2hCO29CQUNELE9BQU8sRUFBRTt3QkFDUCw0QkFBNEI7d0JBQzVCLG9CQUFvQjtxQkFDckI7aUJBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEh0dHBDbGllbnRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBMaWNlbmNlc1JlcXVpcmVtZW50Q29tcG9uZW50IH0gZnJvbSAnLi93aWRnZXRzL2xpY2VuY2VzLXJlcXVpcmVtZW50L2xpY2VuY2VzLXJlcXVpcmVtZW50LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTdW1tYXJ5R3JpZENvbXBvbmVudCB9IGZyb20gJy4vd2lkZ2V0cy9zdW1tYXJ5LWdyaWQvc3VtbWFyeS1ncmlkLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBDYXJkQ29tcG9uZW50IH0gZnJvbSAnLi9jb21wb25lbnRzL2NhcmQvY2FyZC5jb21wb25lbnQnO1xuaW1wb3J0IHsgTmdBcGV4Y2hhcnRzTW9kdWxlIH0gZnJvbSAnbmctYXBleGNoYXJ0cyc7XG5pbXBvcnQgeyBNYXRlcmlhbE1vZHVsZSB9IGZyb20gJy4uL3NoYXJlZC9tYXRlcmlhbC5tb2R1bGUnO1xuaW1wb3J0IHsgU2hhcmVkTW9kdWxlIH0gZnJvbSAnLi4vc2hhcmVkL3NoYXJlZC5tb2R1bGUnO1xuaW1wb3J0IHsgTWF0QnV0dG9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvYnV0dG9uJztcbmltcG9ydCB7IE1hdENoZWNrYm94TW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvY2hlY2tib3gnO1xuaW1wb3J0IHsgTWF0T3B0aW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvY29yZSc7XG5pbXBvcnQgeyBNYXRQYWdpbmF0b3JNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9wYWdpbmF0b3InO1xuaW1wb3J0IHsgTWF0UHJvZ3Jlc3NTcGlubmVyTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvcHJvZ3Jlc3Mtc3Bpbm5lcic7XG5pbXBvcnQgeyBNYXRTZWxlY3RNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xuaW1wb3J0IHsgTWF0VGFibGVNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC90YWJsZSc7XG5cblxuXG5ATmdNb2R1bGUoe1xuICBkZWNsYXJhdGlvbnM6IFtcbiAgICBMaWNlbmNlc1JlcXVpcmVtZW50Q29tcG9uZW50LFxuICAgIFN1bW1hcnlHcmlkQ29tcG9uZW50LFxuICAgIENhcmRDb21wb25lbnRcbiAgXSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBIdHRwQ2xpZW50TW9kdWxlLFxuICAgIE5nQXBleGNoYXJ0c01vZHVsZSxcbiAgICBNYXRUYWJsZU1vZHVsZSxcbiAgICBNYXRCdXR0b25Nb2R1bGUsXG4gICAgTWF0Q2hlY2tib3hNb2R1bGUsXG4gICAgTWF0U2VsZWN0TW9kdWxlLFxuICAgIE1hdFByb2dyZXNzU3Bpbm5lck1vZHVsZSxcbiAgICBNYXRPcHRpb25Nb2R1bGUsXG4gICAgTWF0UGFnaW5hdG9yTW9kdWxlLFxuICAgIE1hdFNlbGVjdE1vZHVsZVxuICBdLFxuICBleHBvcnRzOiBbXG4gICAgTGljZW5jZXNSZXF1aXJlbWVudENvbXBvbmVudCxcbiAgICBTdW1tYXJ5R3JpZENvbXBvbmVudFxuICBdXG59KVxuZXhwb3J0IGNsYXNzIENjUmVhZGluZXNzTW9kdWxlIHsgfVxuIl19
@@ -0,0 +1,35 @@
1
+ import { inject, Injectable } from '@angular/core';
2
+ import { APIService } from '../shared/api.service';
3
+ import { API } from '../shared/api.endpoints';
4
+ import { map } from 'rxjs';
5
+ import * as i0 from "@angular/core";
6
+ export class CcReadinessService {
7
+ constructor() {
8
+ this.api = inject(APIService);
9
+ }
10
+ fetchUccxServerEntityStats(customerId) {
11
+ return this.api.fetch(API.READINESS.UCCX_SERVER_ENTITY_STATS(customerId))
12
+ .pipe(map((stats) => {
13
+ stats.forEach(stat => {
14
+ // @ts-ignore
15
+ delete stat.counts.reasonCodes;
16
+ });
17
+ return stats;
18
+ }));
19
+ }
20
+ fetchWebexLicenseUsageSummary(customerId) {
21
+ return this.api.fetch(API.READINESS.LICENSE_USAGE_SUMMARY(customerId));
22
+ }
23
+ setToken(token) {
24
+ this.api.token = token;
25
+ }
26
+ }
27
+ CcReadinessService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CcReadinessService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
28
+ CcReadinessService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CcReadinessService, providedIn: 'root' });
29
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CcReadinessService, decorators: [{
30
+ type: Injectable,
31
+ args: [{
32
+ providedIn: 'root'
33
+ }]
34
+ }], ctorParameters: function () { return []; } });
35
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2MtcmVhZGluZXNzLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy90dWtpL3dpZGdldHMvY29udGFjdC1jZW50ZXIvY2MtcmVhZGluZXNzL2NjLXJlYWRpbmVzcy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQVUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUVuRCxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDOUMsT0FBTyxFQUFjLEdBQUcsRUFBMEIsTUFBTSxNQUFNLENBQUM7O0FBSy9ELE1BQU0sT0FBTyxrQkFBa0I7SUFHN0I7UUFGaUIsUUFBRyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUUxQixDQUFDO0lBRWpCLDBCQUEwQixDQUFDLFVBQWtCO1FBQzNDLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyx3QkFBd0IsQ0FBQyxVQUFVLENBQUMsQ0FBQzthQUN0RSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBOEIsRUFBRSxFQUFFO1lBQzNDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ25CLGFBQWE7Z0JBQ2IsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQztZQUNqQyxDQUFDLENBQUMsQ0FBQztZQUNILE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNSLENBQUM7SUFFRCw2QkFBNkIsQ0FBQyxVQUFrQjtRQUM5QyxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMscUJBQXFCLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztJQUN6RSxDQUFDO0lBRUQsUUFBUSxDQUFDLEtBQWE7UUFDcEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO0lBQ3pCLENBQUM7O2dIQXRCVSxrQkFBa0I7b0hBQWxCLGtCQUFrQixjQUZqQixNQUFNOzRGQUVQLGtCQUFrQjtrQkFIOUIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbmplY3QsIEluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQVBJU2VydmljZSB9IGZyb20gJy4uL3NoYXJlZC9hcGkuc2VydmljZSc7XG5pbXBvcnQgeyBVY2N4U2VydmVyRW50aXR5U3RhdHMsIFdlYmV4TGljZW5zZVVzYWdlU3VtbWFyeSB9IGZyb20gJy4vdHlwZXMvY2MtcmVhZGluZXNzJztcbmltcG9ydCB7IEFQSSB9IGZyb20gJy4uL3NoYXJlZC9hcGkuZW5kcG9pbnRzJztcbmltcG9ydCB7IGNhdGNoRXJyb3IsIG1hcCwgT2JzZXJ2YWJsZSwgdGhyb3dFcnJvciB9IGZyb20gJ3J4anMnO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBDY1JlYWRpbmVzc1NlcnZpY2Uge1xuICBwcml2YXRlIHJlYWRvbmx5IGFwaSA9IGluamVjdChBUElTZXJ2aWNlKTtcblxuICBjb25zdHJ1Y3RvcigpIHsgfVxuXG4gIGZldGNoVWNjeFNlcnZlckVudGl0eVN0YXRzKGN1c3RvbWVySWQ6IG51bWJlcik6IE9ic2VydmFibGU8VWNjeFNlcnZlckVudGl0eVN0YXRzW10+IHtcbiAgICByZXR1cm4gdGhpcy5hcGkuZmV0Y2goQVBJLlJFQURJTkVTUy5VQ0NYX1NFUlZFUl9FTlRJVFlfU1RBVFMoY3VzdG9tZXJJZCkpXG4gICAgICAucGlwZShtYXAoKHN0YXRzOiBVY2N4U2VydmVyRW50aXR5U3RhdHNbXSkgPT4ge1xuICAgICAgICBzdGF0cy5mb3JFYWNoKHN0YXQgPT4ge1xuICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICBkZWxldGUgc3RhdC5jb3VudHMucmVhc29uQ29kZXM7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gc3RhdHM7XG4gICAgICB9KSk7XG4gIH1cblxuICBmZXRjaFdlYmV4TGljZW5zZVVzYWdlU3VtbWFyeShjdXN0b21lcklkOiBudW1iZXIpOiBPYnNlcnZhYmxlPFdlYmV4TGljZW5zZVVzYWdlU3VtbWFyeVtdPiB7XG4gICAgcmV0dXJuIHRoaXMuYXBpLmZldGNoKEFQSS5SRUFESU5FU1MuTElDRU5TRV9VU0FHRV9TVU1NQVJZKGN1c3RvbWVySWQpKTtcbiAgfVxuXG4gIHNldFRva2VuKHRva2VuOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmFwaS50b2tlbiA9IHRva2VuO1xuICB9XG59Il19
@@ -0,0 +1,13 @@
1
+ import { Component, Input } from "@angular/core";
2
+ import * as i0 from "@angular/core";
3
+ export class CardComponent {
4
+ }
5
+ CardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6
+ CardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: CardComponent, selector: "tk-card", inputs: { title: "title" }, ngImport: i0, template: "<article class=\"card\">\r\n <header class=\"card__header\">\r\n <h2>{{ title }}</h2>\r\n <!--<div class=\"card__menu-button\">\r\n <img width=\"18\" src=\"assets/icons/menu_icon.png\" alt=\"Menu Icon\">\r\n </div>-->\r\n </header>\r\n <div class=\"card__content\">\r\n <ng-content select=\"card-content\"></ng-content>\r\n </div>\r\n</article>\r\n", styles: ["@import\"https://fonts.googleapis.com/css?family=Poppins:400,100,200,300,500,600,800,700,900\";@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap\";:host{display:block;height:100%;box-sizing:border-box}.card{font-family:Inter,Inter,sans-serif;background-color:#fff;border-radius:1rem;padding:2rem;border:1px solid hsla(0,0%,0%,.2);min-width:300px;max-width:100%;height:100%;display:flex;flex-direction:column;box-sizing:border-box;gap:2.5rem}.card__header{position:relative;display:flex;align-items:center;justify-content:space-between}.card__header h2{font-size:16px;margin:0}.card__header .card__menu-button{position:relative;display:flex;align-items:center}.card__content{display:flex;flex-direction:column;gap:2.5rem;flex-grow:1}\n"] });
7
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CardComponent, decorators: [{
8
+ type: Component,
9
+ args: [{ selector: 'tk-card', template: "<article class=\"card\">\r\n <header class=\"card__header\">\r\n <h2>{{ title }}</h2>\r\n <!--<div class=\"card__menu-button\">\r\n <img width=\"18\" src=\"assets/icons/menu_icon.png\" alt=\"Menu Icon\">\r\n </div>-->\r\n </header>\r\n <div class=\"card__content\">\r\n <ng-content select=\"card-content\"></ng-content>\r\n </div>\r\n</article>\r\n", styles: ["@import\"https://fonts.googleapis.com/css?family=Poppins:400,100,200,300,500,600,800,700,900\";@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap\";:host{display:block;height:100%;box-sizing:border-box}.card{font-family:Inter,Inter,sans-serif;background-color:#fff;border-radius:1rem;padding:2rem;border:1px solid hsla(0,0%,0%,.2);min-width:300px;max-width:100%;height:100%;display:flex;flex-direction:column;box-sizing:border-box;gap:2.5rem}.card__header{position:relative;display:flex;align-items:center;justify-content:space-between}.card__header h2{font-size:16px;margin:0}.card__header .card__menu-button{position:relative;display:flex;align-items:center}.card__content{display:flex;flex-direction:column;gap:2.5rem;flex-grow:1}\n"] }]
10
+ }], propDecorators: { title: [{
11
+ type: Input
12
+ }] } });
13
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FyZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy90dWtpL3dpZGdldHMvY29udGFjdC1jZW50ZXIvY2MtcmVhZGluZXNzL2NvbXBvbmVudHMvY2FyZC9jYXJkLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3R1a2kvd2lkZ2V0cy9jb250YWN0LWNlbnRlci9jYy1yZWFkaW5lc3MvY29tcG9uZW50cy9jYXJkL2NhcmQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBT2pELE1BQU0sT0FBTyxhQUFhOzsyR0FBYixhQUFhOytGQUFiLGFBQWEsMkVDUDFCLGlaQVdBOzRGREphLGFBQWE7a0JBTHpCLFNBQVM7K0JBQ0ksU0FBUzs4QkFLVixLQUFLO3NCQUFiLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0IH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICd0ay1jYXJkJyxcclxuICAgIHRlbXBsYXRlVXJsOiAnLi9jYXJkLmNvbXBvbmVudC5odG1sJyxcclxuICAgIHN0eWxlVXJsczogWycuL2NhcmQuY29tcG9uZW50LnNjc3MnXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgQ2FyZENvbXBvbmVudCB7XHJcbiAgICBASW5wdXQoKSB0aXRsZSE6IHN0cmluZztcclxufSIsIjxhcnRpY2xlIGNsYXNzPVwiY2FyZFwiPlxyXG4gICAgPGhlYWRlciBjbGFzcz1cImNhcmRfX2hlYWRlclwiPlxyXG4gICAgICAgIDxoMj57eyB0aXRsZSB9fTwvaDI+XHJcbiAgICAgICAgPCEtLTxkaXYgY2xhc3M9XCJjYXJkX19tZW51LWJ1dHRvblwiPlxyXG4gICAgICAgICAgICA8aW1nIHdpZHRoPVwiMThcIiBzcmM9XCJhc3NldHMvaWNvbnMvbWVudV9pY29uLnBuZ1wiIGFsdD1cIk1lbnUgSWNvblwiPlxyXG4gICAgICAgIDwvZGl2Pi0tPlxyXG4gICAgPC9oZWFkZXI+XHJcbiAgICA8ZGl2IGNsYXNzPVwiY2FyZF9fY29udGVudFwiPlxyXG4gICAgICAgIDxuZy1jb250ZW50IHNlbGVjdD1cImNhcmQtY29udGVudFwiPjwvbmctY29udGVudD5cclxuICAgIDwvZGl2PlxyXG48L2FydGljbGU+XHJcbiJdfQ==
@@ -0,0 +1,5 @@
1
+ ;
2
+ ;
3
+ ;
4
+ export {};
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2MtcmVhZGluZXNzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdHVraS93aWRnZXRzL2NvbnRhY3QtY2VudGVyL2NjLXJlYWRpbmVzcy90eXBlcy9jYy1yZWFkaW5lc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBa0JDLENBQUM7QUFPRCxDQUFDO0FBUUQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB0eXBlIEVudGl0eVR5cGUgPVxyXG4gICAgfCAnYXBwbGljYXRpb25zJ1xyXG4gICAgfCAndHJpZ2dlcnMnXHJcbiAgICB8ICdjb250YWN0U2VydmljZVF1ZXVlcydcclxuICAgIHwgJ3Jlc291cmNlcydcclxuICAgIHwgJ3Jlc291cmNlR3JvdXBzJ1xyXG4gICAgfCAnc2tpbGxzJ1xyXG4gICAgfCAneG1sJ1xyXG4gICAgfCAnc2NyaXB0cydcclxuICAgIHwgJ2F1ZGlvUHJvbXB0cydcclxuICAgIHwgJ3RlYW1zJ1xyXG4gICAgLy8gfCAncmVhc29uQ29kZXMnXHJcbiAgICB8ICdwaG9uZWJvb2tzJ1xyXG4gICAgfCAnd3JhcFVwQ29kZXMnO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBVY2N4U2VydmVyRW50aXR5U3RhdHMge1xyXG4gICAgdWNjeElwOiBzdHJpbmc7XHJcbiAgICBjb3VudHM6IHsgW2tleSBpbiBFbnRpdHlUeXBlXTogbnVtYmVyIH1cclxufTtcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgV2ViZXhMaWNlbnNlRmVhdHVyZVVzYWdlIHtcclxuICAgIGZlYXR1cmU6ICdQRVJTT04nIHwgJ09SUEhBTkVEX0RFVklDRScsXHJcbiAgICB0b3RhbENvdW50OiBudW1iZXIsXHJcbiAgICB1c2FnZUNvdW50OiBudW1iZXIsXHJcbiAgICB1blVzZWRDb3VudDogbnVtYmVyXHJcbn07XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFdlYmV4TGljZW5zZVVzYWdlU3VtbWFyeSB7XHJcbiAgICB3ZWJleFJlYWRpbmVzc0xpY2Vuc2VTdGF0czogV2ViZXhMaWNlbnNlRmVhdHVyZVVzYWdlW10sXHJcbiAgICB0b3RhbFByb2Zlc3Npb25hbExpY2Vuc2VDb3VudDogbnVtYmVyLFxyXG4gICAgdG90YWxXb3Jrc3BhY2VQcm9mZXNzaW9uYWxMaWNlbnNlQ291bnQ6IG51bWJlcixcclxuICAgIHByb2Zlc3Npb25hbFdlYmV4UmVhZGluZXNzVG90YWxMaWNlbnNlU3RhdENvdmVyYWdlOiBudW1iZXIsXHJcbiAgICB3b3Jrc3BhY2VXZWJleFJlYWRpbmVzc1RvdGFsTGljZW5zZVN0YXRDb3ZlcmFnZTogbnVtYmVyXHJcbn07Il19
@@ -0,0 +1,187 @@
1
+ import { Component, Input, inject } from '@angular/core';
2
+ import { catchError, finalize, of } from 'rxjs';
3
+ import { CcReadinessService } from '../../cc-readiness.service';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@angular/common";
6
+ import * as i2 from "ng-apexcharts";
7
+ import * as i3 from "@angular/material/select";
8
+ import * as i4 from "@angular/material/core";
9
+ import * as i5 from "../../components/card/card.component";
10
+ const LEGEND_COLORS = {
11
+ existing: '#16A693',
12
+ missing: '#808080'
13
+ };
14
+ export class LicencesRequirementComponent {
15
+ constructor() {
16
+ this.ccReadinessService = inject(CcReadinessService);
17
+ this.viewModel = null;
18
+ this.loading = false;
19
+ this.error = false;
20
+ this.filters = ['All', 'Professional licenses', 'Workspace licenses'];
21
+ this.selectedSummaryIndex = 0;
22
+ this.summary = null;
23
+ }
24
+ ngOnInit() {
25
+ this.loadSummaries();
26
+ }
27
+ ngOnDestroy() {
28
+ this.subscription?.unsubscribe();
29
+ }
30
+ ngOnChanges(changes) {
31
+ if ((changes['customerId'] && !changes['customerId'].firstChange) ||
32
+ (changes['token'] && !changes['token'].firstChange)) {
33
+ this.loadSummaries();
34
+ }
35
+ }
36
+ onFilterChange(index) {
37
+ if (!isNaN(index) && index >= 0 && index < this.filters.length) {
38
+ this.selectFilter(index);
39
+ }
40
+ }
41
+ loadSummaries() {
42
+ const numericCustomerId = Number(this.customerId);
43
+ if (!numericCustomerId || !this.token) {
44
+ return;
45
+ }
46
+ this.subscription?.unsubscribe();
47
+ this.loading = true;
48
+ this.error = false;
49
+ this.viewModel = null;
50
+ this.selectedSummaryIndex = 0;
51
+ this.ccReadinessService.setToken(this.token);
52
+ this.subscription = this.ccReadinessService.fetchWebexLicenseUsageSummary(numericCustomerId)
53
+ .pipe(catchError(error => {
54
+ console.error('Unable to load Webex license usage summary', error);
55
+ this.error = true;
56
+ return of([]);
57
+ }), finalize(() => this.loading = false))
58
+ .subscribe(items => {
59
+ console.log('Raw API response:', items);
60
+ // Handle both array and single object responses
61
+ if (Array.isArray(items) && items.length > 0) {
62
+ this.summary = items[0];
63
+ }
64
+ else if (items && typeof items === 'object' && !Array.isArray(items)) {
65
+ // If single object returned, use it directly
66
+ this.summary = items;
67
+ }
68
+ else {
69
+ this.summary = null;
70
+ }
71
+ console.log('Processed summary:', this.summary);
72
+ this.selectFilter(0);
73
+ });
74
+ }
75
+ selectFilter(index) {
76
+ this.selectedSummaryIndex = index;
77
+ if (!this.summary) {
78
+ this.viewModel = null;
79
+ return;
80
+ }
81
+ this.viewModel = this.mapSummaryToViewModel(this.summary, index);
82
+ console.log('Created viewModel for filter index', index, ':', this.viewModel);
83
+ }
84
+ mapSummaryToViewModel(summary, filterIndex) {
85
+ console.log('Mapping summary to viewModel:', summary, 'filterIndex:', filterIndex);
86
+ // Extract data from webexReadinessLicenseStats and license counts
87
+ const personStat = summary.webexReadinessLicenseStats?.find(stat => stat.feature === 'PERSON');
88
+ const deviceStat = summary.webexReadinessLicenseStats?.find(stat => stat.feature === 'ORPHANED_DEVICE');
89
+ const professionalNeeded = personStat?.totalCount ?? 0;
90
+ const workspaceNeeded = deviceStat?.totalCount ?? 0;
91
+ const professionalOwned = Number(summary.totalProfessionalLicenseCount ?? 0);
92
+ const workspaceOwned = Number(summary.totalWorkspaceProfessionalLicenseCount ?? 0);
93
+ // Filter data based on selection
94
+ let existingCount;
95
+ let missingCount;
96
+ let rows;
97
+ if (filterIndex === 0) {
98
+ // All - show both
99
+ existingCount = professionalOwned + workspaceOwned;
100
+ const totalNeeded = professionalNeeded + workspaceNeeded;
101
+ missingCount = Math.max(0, totalNeeded - existingCount);
102
+ rows = [
103
+ { label: 'Professional licenses', value: professionalNeeded },
104
+ { label: 'Workspace licenses', value: workspaceNeeded }
105
+ ];
106
+ }
107
+ else if (filterIndex === 1) {
108
+ // Professional licenses only
109
+ existingCount = professionalOwned;
110
+ missingCount = Math.max(0, professionalNeeded - professionalOwned);
111
+ rows = [{ label: 'Professional licenses', value: professionalNeeded }];
112
+ }
113
+ else {
114
+ // Workspace licenses only
115
+ existingCount = workspaceOwned;
116
+ missingCount = Math.max(0, workspaceNeeded - workspaceOwned);
117
+ rows = [{ label: 'Workspace licenses', value: workspaceNeeded }];
118
+ }
119
+ const totalLicenses = existingCount + missingCount;
120
+ const legendItems = [
121
+ {
122
+ label: 'Existing licenses',
123
+ count: existingCount,
124
+ percentage: totalLicenses > 0 ? (existingCount / totalLicenses) * 100 : 0,
125
+ color: LEGEND_COLORS.existing
126
+ },
127
+ {
128
+ label: 'Missing licenses',
129
+ count: missingCount,
130
+ percentage: totalLicenses > 0 ? (missingCount / totalLicenses) * 100 : 0,
131
+ color: LEGEND_COLORS.missing
132
+ }
133
+ ];
134
+ console.log('Legend items:', legendItems);
135
+ console.log('Table rows:', rows);
136
+ const totalRequired = rows.reduce((acc, row) => acc + row.value, 0);
137
+ return {
138
+ chartOptions: this.buildChartOptions(legendItems),
139
+ legendItems,
140
+ rows,
141
+ totalRequired
142
+ };
143
+ }
144
+ buildChartOptions(legendItems) {
145
+ return {
146
+ series: legendItems.map(item => item.count),
147
+ chart: {
148
+ type: 'donut',
149
+ height: 220
150
+ },
151
+ labels: legendItems.map(item => item.label),
152
+ colors: legendItems.map(item => item.color),
153
+ legend: {
154
+ show: false
155
+ },
156
+ plotOptions: {
157
+ pie: {
158
+ donut: {
159
+ size: '75%'
160
+ }
161
+ }
162
+ },
163
+ dataLabels: {
164
+ enabled: false
165
+ }
166
+ };
167
+ }
168
+ normalizePercentage(value) {
169
+ if (!isFinite(value)) {
170
+ return 0;
171
+ }
172
+ // Convert decimal to percentage (0.9487 → 94.9)
173
+ const percentage = value * 100;
174
+ return Math.round(percentage * 10) / 10;
175
+ }
176
+ }
177
+ LicencesRequirementComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: LicencesRequirementComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
178
+ LicencesRequirementComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: LicencesRequirementComponent, selector: "cc-licenses-requirement", inputs: { customerId: "customerId", token: "token" }, usesOnChanges: true, ngImport: i0, template: "<tk-card title=\"Licenses requirement\">\n <ng-container ngProjectAs=\"card-content\">\n <div\n class=\"widget-body\"\n *ngIf=\"!loading && !error && viewModel; else widgetState\"\n >\n <div class=\"left-section\">\n <mat-select\n [(value)]=\"selectedSummaryIndex\"\n (selectionChange)=\"onFilterChange($event.value)\"\n class=\"filter-select\"\n >\n <mat-option *ngFor=\"let option of filters; index as i\" [value]=\"i\">\n {{ option }}\n </mat-option>\n </mat-select>\n\n <div class=\"chart-section\">\n <div class=\"chart-wrapper\">\n <apx-chart\n [series]=\"viewModel.chartOptions.series\"\n [chart]=\"viewModel.chartOptions.chart\"\n [labels]=\"viewModel.chartOptions.labels\"\n [colors]=\"viewModel.chartOptions.colors\"\n [legend]=\"viewModel.chartOptions.legend\"\n [plotOptions]=\"viewModel.chartOptions.plotOptions\"\n [dataLabels]=\"viewModel.chartOptions.dataLabels\"\n >\n </apx-chart>\n </div>\n <div class=\"legend\">\n <div class=\"legend-item\" *ngFor=\"let item of viewModel.legendItems\">\n <span\n class=\"legend-marker\"\n [style.backgroundColor]=\"item.color\"\n ></span>\n <span class=\"legend-label\">{{ item.label }}</span>\n <span class=\"legend-value\">{{ item.count | number }}</span>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"divider\" aria-hidden=\"true\"></div>\n\n <div class=\"table-section\">\n <div class=\"table-header\">\n <span>License</span>\n <span>Required</span>\n </div>\n <div class=\"table-row\" *ngFor=\"let row of viewModel.rows\">\n <span>{{ row.label }}</span>\n <span>{{ row.value | number }}</span>\n </div>\n <div class=\"table-row total-row\">\n <span>Total</span>\n <span>{{ viewModel.totalRequired | number }}</span>\n </div>\n </div>\n </div>\n\n <ng-template #widgetState>\n <div class=\"state-message\" *ngIf=\"loading\">\n Loading license requirements\u2026\n </div>\n <div class=\"state-message error\" *ngIf=\"!loading && error\">\n Unable to load license requirements.\n </div>\n <div class=\"state-message\" *ngIf=\"!loading && !error && !viewModel\">\n No license data available.\n </div>\n </ng-template>\n </ng-container>\n</tk-card>\n", styles: ["@import\"https://fonts.googleapis.com/css?family=Poppins:400,100,200,300,500,600,800,700,900\";@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap\";:host{display:block;width:100%;box-sizing:border-box}.filter-select{font-family:Inter,Inter,sans-serif;font-size:14px;min-width:140px;border:1px solid #e5e7eb;border-radius:.5rem;padding:.5rem .75rem;background-color:#fff}.filter-select:hover{border-color:#d1d5db}:host ::ng-deep .filter-select.mat-mdc-select{border:1px solid #e5e7eb;border-radius:.5rem;background-color:#fff}:host ::ng-deep .filter-select.mat-mdc-select:hover{border-color:#d1d5db}:host ::ng-deep .filter-select.mat-mdc-select.mat-focused{border-color:#16a693}:host ::ng-deep .filter-select .mat-mdc-select-trigger{font-size:14px;padding:.5rem .75rem}:host ::ng-deep .filter-select .mat-mdc-select-value{color:#111827}:host ::ng-deep .filter-select .mat-mdc-select-arrow-wrapper{padding-left:.5rem}.widget-body{display:flex;gap:2.5rem;align-items:flex-start}.left-section{flex:2;display:flex;flex-direction:column;gap:1rem}.chart-section{display:flex;gap:1.5rem;align-items:center}.chart-wrapper{width:220px;min-height:220px;flex-shrink:0}.chart-wrapper apx-chart{width:220px!important;height:220px!important}.legend{display:flex;flex-direction:column;gap:.75rem}.legend-item{display:flex;align-items:center;gap:.5rem;font-family:Inter,Inter,sans-serif;font-size:14px}.legend-marker{width:14px;height:14px;border-radius:50%;display:inline-flex}.legend-label{color:#4b5563}.legend-value{margin-left:auto;font-weight:600;color:#111827}.divider{width:1px;min-height:200px;align-self:stretch;background:#e5e7eb}.table-section{flex:3;display:flex;flex-direction:column;gap:.75rem;font-family:Inter,Inter,sans-serif}.table-header,.table-row{display:flex;justify-content:space-between;font-size:14px}.table-header{font-weight:600;color:#6b7280;padding-bottom:.5rem;border-bottom:1px solid #e5e7eb}.table-row{color:#111827}.total-row{font-weight:700;margin-top:.5rem;padding-top:.5rem;border-top:1px solid #e5e7eb}.state-message{font-family:Inter,Inter,sans-serif;font-size:14px;color:#6b7280}.state-message.error{color:#b91c1c}@media (max-width: 960px){.widget-body{flex-direction:column}.divider{display:none}.chart-section{justify-content:space-between}}:host ::ng-deep .apexcharts-legend{display:none!important}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.ChartComponent, selector: "apx-chart", inputs: ["chart", "annotations", "colors", "dataLabels", "series", "stroke", "labels", "legend", "markers", "noData", "fill", "tooltip", "plotOptions", "responsive", "xaxis", "yaxis", "forecastDataPoints", "grid", "states", "title", "subtitle", "theme", "autoUpdateSeries"] }, { kind: "component", type: i3.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i4.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i5.CardComponent, selector: "tk-card", inputs: ["title"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }] });
179
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: LicencesRequirementComponent, decorators: [{
180
+ type: Component,
181
+ args: [{ selector: 'cc-licenses-requirement', template: "<tk-card title=\"Licenses requirement\">\n <ng-container ngProjectAs=\"card-content\">\n <div\n class=\"widget-body\"\n *ngIf=\"!loading && !error && viewModel; else widgetState\"\n >\n <div class=\"left-section\">\n <mat-select\n [(value)]=\"selectedSummaryIndex\"\n (selectionChange)=\"onFilterChange($event.value)\"\n class=\"filter-select\"\n >\n <mat-option *ngFor=\"let option of filters; index as i\" [value]=\"i\">\n {{ option }}\n </mat-option>\n </mat-select>\n\n <div class=\"chart-section\">\n <div class=\"chart-wrapper\">\n <apx-chart\n [series]=\"viewModel.chartOptions.series\"\n [chart]=\"viewModel.chartOptions.chart\"\n [labels]=\"viewModel.chartOptions.labels\"\n [colors]=\"viewModel.chartOptions.colors\"\n [legend]=\"viewModel.chartOptions.legend\"\n [plotOptions]=\"viewModel.chartOptions.plotOptions\"\n [dataLabels]=\"viewModel.chartOptions.dataLabels\"\n >\n </apx-chart>\n </div>\n <div class=\"legend\">\n <div class=\"legend-item\" *ngFor=\"let item of viewModel.legendItems\">\n <span\n class=\"legend-marker\"\n [style.backgroundColor]=\"item.color\"\n ></span>\n <span class=\"legend-label\">{{ item.label }}</span>\n <span class=\"legend-value\">{{ item.count | number }}</span>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"divider\" aria-hidden=\"true\"></div>\n\n <div class=\"table-section\">\n <div class=\"table-header\">\n <span>License</span>\n <span>Required</span>\n </div>\n <div class=\"table-row\" *ngFor=\"let row of viewModel.rows\">\n <span>{{ row.label }}</span>\n <span>{{ row.value | number }}</span>\n </div>\n <div class=\"table-row total-row\">\n <span>Total</span>\n <span>{{ viewModel.totalRequired | number }}</span>\n </div>\n </div>\n </div>\n\n <ng-template #widgetState>\n <div class=\"state-message\" *ngIf=\"loading\">\n Loading license requirements\u2026\n </div>\n <div class=\"state-message error\" *ngIf=\"!loading && error\">\n Unable to load license requirements.\n </div>\n <div class=\"state-message\" *ngIf=\"!loading && !error && !viewModel\">\n No license data available.\n </div>\n </ng-template>\n </ng-container>\n</tk-card>\n", styles: ["@import\"https://fonts.googleapis.com/css?family=Poppins:400,100,200,300,500,600,800,700,900\";@import\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400&display=swap\";:host{display:block;width:100%;box-sizing:border-box}.filter-select{font-family:Inter,Inter,sans-serif;font-size:14px;min-width:140px;border:1px solid #e5e7eb;border-radius:.5rem;padding:.5rem .75rem;background-color:#fff}.filter-select:hover{border-color:#d1d5db}:host ::ng-deep .filter-select.mat-mdc-select{border:1px solid #e5e7eb;border-radius:.5rem;background-color:#fff}:host ::ng-deep .filter-select.mat-mdc-select:hover{border-color:#d1d5db}:host ::ng-deep .filter-select.mat-mdc-select.mat-focused{border-color:#16a693}:host ::ng-deep .filter-select .mat-mdc-select-trigger{font-size:14px;padding:.5rem .75rem}:host ::ng-deep .filter-select .mat-mdc-select-value{color:#111827}:host ::ng-deep .filter-select .mat-mdc-select-arrow-wrapper{padding-left:.5rem}.widget-body{display:flex;gap:2.5rem;align-items:flex-start}.left-section{flex:2;display:flex;flex-direction:column;gap:1rem}.chart-section{display:flex;gap:1.5rem;align-items:center}.chart-wrapper{width:220px;min-height:220px;flex-shrink:0}.chart-wrapper apx-chart{width:220px!important;height:220px!important}.legend{display:flex;flex-direction:column;gap:.75rem}.legend-item{display:flex;align-items:center;gap:.5rem;font-family:Inter,Inter,sans-serif;font-size:14px}.legend-marker{width:14px;height:14px;border-radius:50%;display:inline-flex}.legend-label{color:#4b5563}.legend-value{margin-left:auto;font-weight:600;color:#111827}.divider{width:1px;min-height:200px;align-self:stretch;background:#e5e7eb}.table-section{flex:3;display:flex;flex-direction:column;gap:.75rem;font-family:Inter,Inter,sans-serif}.table-header,.table-row{display:flex;justify-content:space-between;font-size:14px}.table-header{font-weight:600;color:#6b7280;padding-bottom:.5rem;border-bottom:1px solid #e5e7eb}.table-row{color:#111827}.total-row{font-weight:700;margin-top:.5rem;padding-top:.5rem;border-top:1px solid #e5e7eb}.state-message{font-family:Inter,Inter,sans-serif;font-size:14px;color:#6b7280}.state-message.error{color:#b91c1c}@media (max-width: 960px){.widget-body{flex-direction:column}.divider{display:none}.chart-section{justify-content:space-between}}:host ::ng-deep .apexcharts-legend{display:none!important}\n"] }]
182
+ }], propDecorators: { customerId: [{
183
+ type: Input
184
+ }], token: [{
185
+ type: Input
186
+ }] } });
187
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGljZW5jZXMtcmVxdWlyZW1lbnQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdHVraS93aWRnZXRzL2NvbnRhY3QtY2VudGVyL2NjLXJlYWRpbmVzcy93aWRnZXRzL2xpY2VuY2VzLXJlcXVpcmVtZW50L2xpY2VuY2VzLXJlcXVpcmVtZW50LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3R1a2kvd2lkZ2V0cy9jb250YWN0LWNlbnRlci9jYy1yZWFkaW5lc3Mvd2lkZ2V0cy9saWNlbmNlcy1yZXF1aXJlbWVudC9saWNlbmNlcy1yZXF1aXJlbWVudC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBK0MsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXRHLE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDOUQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7Ozs7Ozs7QUFnQ2hFLE1BQU0sYUFBYSxHQUFHO0lBQ3BCLFFBQVEsRUFBRSxTQUFTO0lBQ25CLE9BQU8sRUFBRSxTQUFTO0NBQ25CLENBQUM7QUFPRixNQUFNLE9BQU8sNEJBQTRCO0lBTHpDO1FBU21CLHVCQUFrQixHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBR2pFLGNBQVMsR0FBdUMsSUFBSSxDQUFDO1FBQ3JELFlBQU8sR0FBRyxLQUFLLENBQUM7UUFDaEIsVUFBSyxHQUFHLEtBQUssQ0FBQztRQUVkLFlBQU8sR0FBYSxDQUFDLEtBQUssRUFBRSx1QkFBdUIsRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO1FBQzNFLHlCQUFvQixHQUFHLENBQUMsQ0FBQztRQUVqQixZQUFPLEdBQW9DLElBQUksQ0FB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RCxNQUFNLEVBQUUsV0FBVyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7WUFDM0MsTUFBTSxFQUFFLFdBQVcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO1lBQzNDLE1BQU0sRUFBRTtnQkFDTixJQUFJLEVBQUUsS0FBSzthQUNaO1lBQ0QsV0FBVyxFQUFFO2dCQUNYLEdBQUcsRUFBRTtvQkFDSCxLQUFLLEVBQUU7d0JBQ0wsSUFBSSxFQUFFLEtBQUs7cUJBQ1o7aUJBQ0Y7YUFDRjtZQUNELFVBQVUsRUFBRTtnQkFDVixPQUFPLEVBQUUsS0FBSzthQUNmO1NBQ0YsQ0FBQztJQUNKLENBQUM7SUFFTyxtQkFBbUIsQ0FBQyxLQUFhO1FBQ3ZDLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDcEIsT0FBTyxDQUFDLENBQUM7U0FDVjtRQUNELGdEQUFnRDtRQUNoRCxNQUFNLFVBQVUsR0FBRyxLQUFLLEdBQUcsR0FBRyxDQUFDO1FBQy9CLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQzFDLENBQUM7OzBIQTlMVSw0QkFBNEI7OEdBQTVCLDRCQUE0QiwwSUM3Q3pDLDRtRkEwRUE7NEZEN0JhLDRCQUE0QjtrQkFMeEMsU0FBUzsrQkFDRSx5QkFBeUI7OEJBSzFCLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIE9uSW5pdCwgU2ltcGxlQ2hhbmdlcywgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBcGV4Q2hhcnQsIEFwZXhEYXRhTGFiZWxzLCBBcGV4TGVnZW5kLCBBcGV4Tm9uQXhpc0NoYXJ0U2VyaWVzLCBBcGV4UGxvdE9wdGlvbnMgfSBmcm9tICduZy1hcGV4Y2hhcnRzJztcbmltcG9ydCB7IGNhdGNoRXJyb3IsIGZpbmFsaXplLCBvZiwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBDY1JlYWRpbmVzc1NlcnZpY2UgfSBmcm9tICcuLi8uLi9jYy1yZWFkaW5lc3Muc2VydmljZSc7XG5pbXBvcnQgeyBXZWJleExpY2Vuc2VVc2FnZVN1bW1hcnkgfSBmcm9tICcuLi8uLi90eXBlcy9jYy1yZWFkaW5lc3MnO1xuXG5pbnRlcmZhY2UgTGljZW5zZUxlZ2VuZEl0ZW0ge1xuICBsYWJlbDogc3RyaW5nO1xuICBjb3VudDogbnVtYmVyO1xuICBwZXJjZW50YWdlOiBudW1iZXI7XG4gIGNvbG9yOiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBMaWNlbnNlVGFibGVSb3cge1xuICBsYWJlbDogc3RyaW5nO1xuICB2YWx1ZTogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgTGljZW5zZUNoYXJ0T3B0aW9ucyB7XG4gIHNlcmllczogQXBleE5vbkF4aXNDaGFydFNlcmllcztcbiAgY2hhcnQ6IEFwZXhDaGFydDtcbiAgbGFiZWxzOiBzdHJpbmdbXTtcbiAgY29sb3JzOiBzdHJpbmdbXTtcbiAgbGVnZW5kOiBBcGV4TGVnZW5kO1xuICBwbG90T3B0aW9uczogQXBleFBsb3RPcHRpb25zO1xuICBkYXRhTGFiZWxzOiBBcGV4RGF0YUxhYmVscztcbn1cblxuaW50ZXJmYWNlIExpY2Vuc2VSZXF1aXJlbWVudFZpZXdNb2RlbCB7XG4gIGNoYXJ0T3B0aW9uczogTGljZW5zZUNoYXJ0T3B0aW9ucztcbiAgbGVnZW5kSXRlbXM6IExpY2Vuc2VMZWdlbmRJdGVtW107XG4gIHJvd3M6IExpY2Vuc2VUYWJsZVJvd1tdO1xuICB0b3RhbFJlcXVpcmVkOiBudW1iZXI7XG59XG5cbmNvbnN0IExFR0VORF9DT0xPUlMgPSB7XG4gIGV4aXN0aW5nOiAnIzE2QTY5MycsXG4gIG1pc3Npbmc6ICcjODA4MDgwJ1xufTtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY2MtbGljZW5zZXMtcmVxdWlyZW1lbnQnLFxuICB0ZW1wbGF0ZVVybDogJy4vbGljZW5jZXMtcmVxdWlyZW1lbnQuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9saWNlbmNlcy1yZXF1aXJlbWVudC5jb21wb25lbnQuc2NzcyddXG59KVxuZXhwb3J0IGNsYXNzIExpY2VuY2VzUmVxdWlyZW1lbnRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSwgT25DaGFuZ2VzIHtcbiAgQElucHV0KCkgY3VzdG9tZXJJZCE6IG51bWJlcjtcbiAgQElucHV0KCkgdG9rZW4hOiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBjY1JlYWRpbmVzc1NlcnZpY2UgPSBpbmplY3QoQ2NSZWFkaW5lc3NTZXJ2aWNlKTtcbiAgcHJpdmF0ZSBzdWJzY3JpcHRpb24/OiBTdWJzY3JpcHRpb247XG5cbiAgdmlld01vZGVsOiBMaWNlbnNlUmVxdWlyZW1lbnRWaWV3TW9kZWwgfCBudWxsID0gbnVsbDtcbiAgbG9hZGluZyA9IGZhbHNlO1xuICBlcnJvciA9IGZhbHNlO1xuXG4gIGZpbHRlcnM6IHN0cmluZ1tdID0gWydBbGwnLCAnUHJvZmVzc2lvbmFsIGxpY2Vuc2VzJywgJ1dvcmtzcGFjZSBsaWNlbnNlcyddO1xuICBzZWxlY3RlZFN1bW1hcnlJbmRleCA9IDA7XG5cbiAgcHJpdmF0ZSBzdW1tYXJ5OiBXZWJleExpY2Vuc2VVc2FnZVN1bW1hcnkgfCBudWxsID0gbnVsbDtcblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmxvYWRTdW1tYXJpZXMoKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmICgoY2hhbmdlc1snY3VzdG9tZXJJZCddICYmICFjaGFuZ2VzWydjdXN0b21lcklkJ10uZmlyc3RDaGFuZ2UpIHx8XG4gICAgICAoY2hhbmdlc1sndG9rZW4nXSAmJiAhY2hhbmdlc1sndG9rZW4nXS5maXJzdENoYW5nZSkpIHtcbiAgICAgIHRoaXMubG9hZFN1bW1hcmllcygpO1xuICAgIH1cbiAgfVxuXG4gIG9uRmlsdGVyQ2hhbmdlKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoIWlzTmFOKGluZGV4KSAmJiBpbmRleCA+PSAwICYmIGluZGV4IDwgdGhpcy5maWx0ZXJzLmxlbmd0aCkge1xuICAgICAgdGhpcy5zZWxlY3RGaWx0ZXIoaW5kZXgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbG9hZFN1bW1hcmllcygpOiB2b2lkIHtcbiAgICBjb25zdCBudW1lcmljQ3VzdG9tZXJJZCA9IE51bWJlcih0aGlzLmN1c3RvbWVySWQpO1xuICAgIGlmICghbnVtZXJpY0N1c3RvbWVySWQgfHwgIXRoaXMudG9rZW4pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLmxvYWRpbmcgPSB0cnVlO1xuICAgIHRoaXMuZXJyb3IgPSBmYWxzZTtcbiAgICB0aGlzLnZpZXdNb2RlbCA9IG51bGw7XG4gICAgdGhpcy5zZWxlY3RlZFN1bW1hcnlJbmRleCA9IDA7XG5cbiAgICB0aGlzLmNjUmVhZGluZXNzU2VydmljZS5zZXRUb2tlbih0aGlzLnRva2VuKTtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbiA9IHRoaXMuY2NSZWFkaW5lc3NTZXJ2aWNlLmZldGNoV2ViZXhMaWNlbnNlVXNhZ2VTdW1tYXJ5KG51bWVyaWNDdXN0b21lcklkKVxuICAgICAgLnBpcGUoXG4gICAgICAgIGNhdGNoRXJyb3IoZXJyb3IgPT4ge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1VuYWJsZSB0byBsb2FkIFdlYmV4IGxpY2Vuc2UgdXNhZ2Ugc3VtbWFyeScsIGVycm9yKTtcbiAgICAgICAgICB0aGlzLmVycm9yID0gdHJ1ZTtcbiAgICAgICAgICByZXR1cm4gb2Y8V2ViZXhMaWNlbnNlVXNhZ2VTdW1tYXJ5W10+KFtdKTtcbiAgICAgICAgfSksXG4gICAgICAgIGZpbmFsaXplKCgpID0+IHRoaXMubG9hZGluZyA9IGZhbHNlKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZShpdGVtcyA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdSYXcgQVBJIHJlc3BvbnNlOicsIGl0ZW1zKTtcbiAgICAgICAgLy8gSGFuZGxlIGJvdGggYXJyYXkgYW5kIHNpbmdsZSBvYmplY3QgcmVzcG9uc2VzXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGl0ZW1zKSAmJiBpdGVtcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdGhpcy5zdW1tYXJ5ID0gaXRlbXNbMF07XG4gICAgICAgIH0gZWxzZSBpZiAoaXRlbXMgJiYgdHlwZW9mIGl0ZW1zID09PSAnb2JqZWN0JyAmJiAhQXJyYXkuaXNBcnJheShpdGVtcykpIHtcbiAgICAgICAgICAvLyBJZiBzaW5nbGUgb2JqZWN0IHJldHVybmVkLCB1c2UgaXQgZGlyZWN0bHlcbiAgICAgICAgICB0aGlzLnN1bW1hcnkgPSBpdGVtcyBhcyB1bmtub3duIGFzIFdlYmV4TGljZW5zZVVzYWdlU3VtbWFyeTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnN1bW1hcnkgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc29sZS5sb2coJ1Byb2Nlc3NlZCBzdW1tYXJ5OicsIHRoaXMuc3VtbWFyeSk7XG4gICAgICAgIHRoaXMuc2VsZWN0RmlsdGVyKDApO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHNlbGVjdEZpbHRlcihpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZFN1bW1hcnlJbmRleCA9IGluZGV4O1xuICAgIGlmICghdGhpcy5zdW1tYXJ5KSB7XG4gICAgICB0aGlzLnZpZXdNb2RlbCA9IG51bGw7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMudmlld01vZGVsID0gdGhpcy5tYXBTdW1tYXJ5VG9WaWV3TW9kZWwodGhpcy5zdW1tYXJ5LCBpbmRleCk7XG4gICAgY29uc29sZS5sb2coJ0NyZWF0ZWQgdmlld01vZGVsIGZvciBmaWx0ZXIgaW5kZXgnLCBpbmRleCwgJzonLCB0aGlzLnZpZXdNb2RlbCk7XG4gIH1cblxuICBwcml2YXRlIG1hcFN1bW1hcnlUb1ZpZXdNb2RlbChzdW1tYXJ5OiBXZWJleExpY2Vuc2VVc2FnZVN1bW1hcnksIGZpbHRlckluZGV4OiBudW1iZXIpOiBMaWNlbnNlUmVxdWlyZW1lbnRWaWV3TW9kZWwge1xuICAgIGNvbnNvbGUubG9nKCdNYXBwaW5nIHN1bW1hcnkgdG8gdmlld01vZGVsOicsIHN1bW1hcnksICdmaWx0ZXJJbmRleDonLCBmaWx0ZXJJbmRleCk7XG5cbiAgICAvLyBFeHRyYWN0IGRhdGEgZnJvbSB3ZWJleFJlYWRpbmVzc0xpY2Vuc2VTdGF0cyBhbmQgbGljZW5zZSBjb3VudHNcbiAgICBjb25zdCBwZXJzb25TdGF0ID0gc3VtbWFyeS53ZWJleFJlYWRpbmVzc0xpY2Vuc2VTdGF0cz8uZmluZChzdGF0ID0+IHN0YXQuZmVhdHVyZSA9PT0gJ1BFUlNPTicpO1xuICAgIGNvbnN0IGRldmljZVN0YXQgPSBzdW1tYXJ5LndlYmV4UmVhZGluZXNzTGljZW5zZVN0YXRzPy5maW5kKHN0YXQgPT4gc3RhdC5mZWF0dXJlID09PSAnT1JQSEFORURfREVWSUNFJyk7XG5cbiAgICBjb25zdCBwcm9mZXNzaW9uYWxOZWVkZWQgPSBwZXJzb25TdGF0Py50b3RhbENvdW50ID8/IDA7XG4gICAgY29uc3Qgd29ya3NwYWNlTmVlZGVkID0gZGV2aWNlU3RhdD8udG90YWxDb3VudCA/PyAwO1xuXG4gICAgY29uc3QgcHJvZmVzc2lvbmFsT3duZWQgPSBOdW1iZXIoc3VtbWFyeS50b3RhbFByb2Zlc3Npb25hbExpY2Vuc2VDb3VudCA/PyAwKTtcbiAgICBjb25zdCB3b3Jrc3BhY2VPd25lZCA9IE51bWJlcihzdW1tYXJ5LnRvdGFsV29ya3NwYWNlUHJvZmVzc2lvbmFsTGljZW5zZUNvdW50ID8/IDApO1xuXG4gICAgLy8gRmlsdGVyIGRhdGEgYmFzZWQgb24gc2VsZWN0aW9uXG4gICAgbGV0IGV4aXN0aW5nQ291bnQ6IG51bWJlcjtcbiAgICBsZXQgbWlzc2luZ0NvdW50OiBudW1iZXI7XG4gICAgbGV0IHJvd3M6IExpY2Vuc2VUYWJsZVJvd1tdO1xuXG4gICAgaWYgKGZpbHRlckluZGV4ID09PSAwKSB7XG4gICAgICAvLyBBbGwgLSBzaG93IGJvdGhcbiAgICAgIGV4aXN0aW5nQ291bnQgPSBwcm9mZXNzaW9uYWxPd25lZCArIHdvcmtzcGFjZU93bmVkO1xuICAgICAgY29uc3QgdG90YWxOZWVkZWQgPSBwcm9mZXNzaW9uYWxOZWVkZWQgKyB3b3Jrc3BhY2VOZWVkZWQ7XG4gICAgICBtaXNzaW5nQ291bnQgPSBNYXRoLm1heCgwLCB0b3RhbE5lZWRlZCAtIGV4aXN0aW5nQ291bnQpO1xuXG4gICAgICByb3dzID0gW1xuICAgICAgICB7IGxhYmVsOiAnUHJvZmVzc2lvbmFsIGxpY2Vuc2VzJywgdmFsdWU6IHByb2Zlc3Npb25hbE5lZWRlZCB9LFxuICAgICAgICB7IGxhYmVsOiAnV29ya3NwYWNlIGxpY2Vuc2VzJywgdmFsdWU6IHdvcmtzcGFjZU5lZWRlZCB9XG4gICAgICBdO1xuICAgIH0gZWxzZSBpZiAoZmlsdGVySW5kZXggPT09IDEpIHtcbiAgICAgIC8vIFByb2Zlc3Npb25hbCBsaWNlbnNlcyBvbmx5XG4gICAgICBleGlzdGluZ0NvdW50ID0gcHJvZmVzc2lvbmFsT3duZWQ7XG4gICAgICBtaXNzaW5nQ291bnQgPSBNYXRoLm1heCgwLCBwcm9mZXNzaW9uYWxOZWVkZWQgLSBwcm9mZXNzaW9uYWxPd25lZCk7XG5cbiAgICAgIHJvd3MgPSBbeyBsYWJlbDogJ1Byb2Zlc3Npb25hbCBsaWNlbnNlcycsIHZhbHVlOiBwcm9mZXNzaW9uYWxOZWVkZWQgfV07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFdvcmtzcGFjZSBsaWNlbnNlcyBvbmx5XG4gICAgICBleGlzdGluZ0NvdW50ID0gd29ya3NwYWNlT3duZWQ7XG4gICAgICBtaXNzaW5nQ291bnQgPSBNYXRoLm1heCgwLCB3b3Jrc3BhY2VOZWVkZWQgLSB3b3Jrc3BhY2VPd25lZCk7XG5cbiAgICAgIHJvd3MgPSBbeyBsYWJlbDogJ1dvcmtzcGFjZSBsaWNlbnNlcycsIHZhbHVlOiB3b3Jrc3BhY2VOZWVkZWQgfV07XG4gICAgfVxuXG4gICAgY29uc3QgdG90YWxMaWNlbnNlcyA9IGV4aXN0aW5nQ291bnQgKyBtaXNzaW5nQ291bnQ7XG5cbiAgICBjb25zdCBsZWdlbmRJdGVtczogTGljZW5zZUxlZ2VuZEl0ZW1bXSA9IFtcbiAgICAgIHtcbiAgICAgICAgbGFiZWw6ICdFeGlzdGluZyBsaWNlbnNlcycsXG4gICAgICAgIGNvdW50OiBleGlzdGluZ0NvdW50LFxuICAgICAgICBwZXJjZW50YWdlOiB0b3RhbExpY2Vuc2VzID4gMCA/IChleGlzdGluZ0NvdW50IC8gdG90YWxMaWNlbnNlcykgKiAxMDAgOiAwLFxuICAgICAgICBjb2xvcjogTEVHRU5EX0NPTE9SUy5leGlzdGluZ1xuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbGFiZWw6ICdNaXNzaW5nIGxpY2Vuc2VzJyxcbiAgICAgICAgY291bnQ6IG1pc3NpbmdDb3VudCxcbiAgICAgICAgcGVyY2VudGFnZTogdG90YWxMaWNlbnNlcyA+IDAgPyAobWlzc2luZ0NvdW50IC8gdG90YWxMaWNlbnNlcykgKiAxMDAgOiAwLFxuICAgICAgICBjb2xvcjogTEVHRU5EX0NPTE9SUy5taXNzaW5nXG4gICAgICB9XG4gICAgXTtcblxuICAgIGNvbnNvbGUubG9nKCdMZWdlbmQgaXRlbXM6JywgbGVnZW5kSXRlbXMpO1xuICAgIGNvbnNvbGUubG9nKCdUYWJsZSByb3dzOicsIHJvd3MpO1xuXG4gICAgY29uc3QgdG90YWxSZXF1aXJlZCA9IHJvd3MucmVkdWNlKChhY2MsIHJvdykgPT4gYWNjICsgcm93LnZhbHVlLCAwKTtcblxuICAgIHJldHVybiB7XG4gICAgICBjaGFydE9wdGlvbnM6IHRoaXMuYnVpbGRDaGFydE9wdGlvbnMobGVnZW5kSXRlbXMpLFxuICAgICAgbGVnZW5kSXRlbXMsXG4gICAgICByb3dzLFxuICAgICAgdG90YWxSZXF1aXJlZFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkQ2hhcnRPcHRpb25zKGxlZ2VuZEl0ZW1zOiBMaWNlbnNlTGVnZW5kSXRlbVtdKTogTGljZW5zZUNoYXJ0T3B0aW9ucyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNlcmllczogbGVnZW5kSXRlbXMubWFwKGl0ZW0gPT4gaXRlbS5jb3VudCksXG4gICAgICBjaGFydDoge1xuICAgICAgICB0eXBlOiAnZG9udXQnLFxuICAgICAgICBoZWlnaHQ6IDIyMFxuICAgICAgfSxcbiAgICAgIGxhYmVsczogbGVnZW5kSXRlbXMubWFwKGl0ZW0gPT4gaXRlbS5sYWJlbCksXG4gICAgICBjb2xvcnM6IGxlZ2VuZEl0ZW1zLm1hcChpdGVtID0+IGl0ZW0uY29sb3IpLFxuICAgICAgbGVnZW5kOiB7XG4gICAgICAgIHNob3c6IGZhbHNlXG4gICAgICB9LFxuICAgICAgcGxvdE9wdGlvbnM6IHtcbiAgICAgICAgcGllOiB7XG4gICAgICAgICAgZG9udXQ6IHtcbiAgICAgICAgICAgIHNpemU6ICc3NSUnXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZGF0YUxhYmVsczoge1xuICAgICAgICBlbmFibGVkOiBmYWxzZVxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIG5vcm1hbGl6ZVBlcmNlbnRhZ2UodmFsdWU6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKCFpc0Zpbml0ZSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICAvLyBDb252ZXJ0IGRlY2ltYWwgdG8gcGVyY2VudGFnZSAoMC45NDg3IOKGkiA5NC45KVxuICAgIGNvbnN0IHBlcmNlbnRhZ2UgPSB2YWx1ZSAqIDEwMDtcbiAgICByZXR1cm4gTWF0aC5yb3VuZChwZXJjZW50YWdlICogMTApIC8gMTA7XG4gIH1cbn1cbiIsIjx0ay1jYXJkIHRpdGxlPVwiTGljZW5zZXMgcmVxdWlyZW1lbnRcIj5cbiAgPG5nLWNvbnRhaW5lciBuZ1Byb2plY3RBcz1cImNhcmQtY29udGVudFwiPlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwid2lkZ2V0LWJvZHlcIlxuICAgICAgKm5nSWY9XCIhbG9hZGluZyAmJiAhZXJyb3IgJiYgdmlld01vZGVsOyBlbHNlIHdpZGdldFN0YXRlXCJcbiAgICA+XG4gICAgICA8ZGl2IGNsYXNzPVwibGVmdC1zZWN0aW9uXCI+XG4gICAgICAgIDxtYXQtc2VsZWN0XG4gICAgICAgICAgWyh2YWx1ZSldPVwic2VsZWN0ZWRTdW1tYXJ5SW5kZXhcIlxuICAgICAgICAgIChzZWxlY3Rpb25DaGFuZ2UpPVwib25GaWx0ZXJDaGFuZ2UoJGV2ZW50LnZhbHVlKVwiXG4gICAgICAgICAgY2xhc3M9XCJmaWx0ZXItc2VsZWN0XCJcbiAgICAgICAgPlxuICAgICAgICAgIDxtYXQtb3B0aW9uICpuZ0Zvcj1cImxldCBvcHRpb24gb2YgZmlsdGVyczsgaW5kZXggYXMgaVwiIFt2YWx1ZV09XCJpXCI+XG4gICAgICAgICAgICB7eyBvcHRpb24gfX1cbiAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgIDwvbWF0LXNlbGVjdD5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwiY2hhcnQtc2VjdGlvblwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjaGFydC13cmFwcGVyXCI+XG4gICAgICAgICAgICA8YXB4LWNoYXJ0XG4gICAgICAgICAgICAgIFtzZXJpZXNdPVwidmlld01vZGVsLmNoYXJ0T3B0aW9ucy5zZXJpZXNcIlxuICAgICAgICAgICAgICBbY2hhcnRdPVwidmlld01vZGVsLmNoYXJ0T3B0aW9ucy5jaGFydFwiXG4gICAgICAgICAgICAgIFtsYWJlbHNdPVwidmlld01vZGVsLmNoYXJ0T3B0aW9ucy5sYWJlbHNcIlxuICAgICAgICAgICAgICBbY29sb3JzXT1cInZpZXdNb2RlbC5jaGFydE9wdGlvbnMuY29sb3JzXCJcbiAgICAgICAgICAgICAgW2xlZ2VuZF09XCJ2aWV3TW9kZWwuY2hhcnRPcHRpb25zLmxlZ2VuZFwiXG4gICAgICAgICAgICAgIFtwbG90T3B0aW9uc109XCJ2aWV3TW9kZWwuY2hhcnRPcHRpb25zLnBsb3RPcHRpb25zXCJcbiAgICAgICAgICAgICAgW2RhdGFMYWJlbHNdPVwidmlld01vZGVsLmNoYXJ0T3B0aW9ucy5kYXRhTGFiZWxzXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgIDwvYXB4LWNoYXJ0PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJsZWdlbmRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsZWdlbmQtaXRlbVwiICpuZ0Zvcj1cImxldCBpdGVtIG9mIHZpZXdNb2RlbC5sZWdlbmRJdGVtc1wiPlxuICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgIGNsYXNzPVwibGVnZW5kLW1hcmtlclwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLmJhY2tncm91bmRDb2xvcl09XCJpdGVtLmNvbG9yXCJcbiAgICAgICAgICAgICAgPjwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJsZWdlbmQtbGFiZWxcIj57eyBpdGVtLmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImxlZ2VuZC12YWx1ZVwiPnt7IGl0ZW0uY291bnQgfCBudW1iZXIgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cImRpdmlkZXJcIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cInRhYmxlLXNlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInRhYmxlLWhlYWRlclwiPlxuICAgICAgICAgIDxzcGFuPkxpY2Vuc2U8L3NwYW4+XG4gICAgICAgICAgPHNwYW4+UmVxdWlyZWQ8L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGFibGUtcm93XCIgKm5nRm9yPVwibGV0IHJvdyBvZiB2aWV3TW9kZWwucm93c1wiPlxuICAgICAgICAgIDxzcGFuPnt7IHJvdy5sYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICA8c3Bhbj57eyByb3cudmFsdWUgfCBudW1iZXIgfX08L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGFibGUtcm93IHRvdGFsLXJvd1wiPlxuICAgICAgICAgIDxzcGFuPlRvdGFsPC9zcGFuPlxuICAgICAgICAgIDxzcGFuPnt7IHZpZXdNb2RlbC50b3RhbFJlcXVpcmVkIHwgbnVtYmVyIH19PC9zcGFuPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPG5nLXRlbXBsYXRlICN3aWRnZXRTdGF0ZT5cbiAgICAgIDxkaXYgY2xhc3M9XCJzdGF0ZS1tZXNzYWdlXCIgKm5nSWY9XCJsb2FkaW5nXCI+XG4gICAgICAgIExvYWRpbmcgbGljZW5zZSByZXF1aXJlbWVudHPigKZcbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cInN0YXRlLW1lc3NhZ2UgZXJyb3JcIiAqbmdJZj1cIiFsb2FkaW5nICYmIGVycm9yXCI+XG4gICAgICAgIFVuYWJsZSB0byBsb2FkIGxpY2Vuc2UgcmVxdWlyZW1lbnRzLlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwic3RhdGUtbWVzc2FnZVwiICpuZ0lmPVwiIWxvYWRpbmcgJiYgIWVycm9yICYmICF2aWV3TW9kZWxcIj5cbiAgICAgICAgTm8gbGljZW5zZSBkYXRhIGF2YWlsYWJsZS5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctdGVtcGxhdGU+XG4gIDwvbmctY29udGFpbmVyPlxuPC90ay1jYXJkPlxuIl19