tas-uell-sdk 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,304 @@
1
+ # TAS-Uell-SDK
2
+
3
+ Angular library for TAS (Telemedicine Assistance Service) video call functionality using OpenTok/Vonage Video API.
4
+
5
+ ## Features
6
+
7
+ - 📹 Video call integration with OpenTok/Vonage
8
+ - 🔘 Ready-to-use button component to initiate calls
9
+ - 🖼️ Picture-in-Picture (PiP) mode support
10
+ - 🎤 Mute/unmute functionality
11
+ - 📱 Draggable floating call widget
12
+ - 🔌 Pluggable architecture for HTTP and user data providers
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install tas-uell-sdk
18
+ ```
19
+
20
+ ### Peer Dependencies
21
+
22
+ Make sure you have these peer dependencies installed:
23
+
24
+ ```bash
25
+ npm install @angular/common @angular/core @ng-bootstrap/ng-bootstrap @opentok/client interactjs rxjs
26
+ ```
27
+
28
+ ## Setup
29
+
30
+ ### 1. Implement Required Adapters
31
+
32
+ The library requires two adapters to integrate with your application:
33
+
34
+ #### HTTP Client Adapter
35
+
36
+ Create a service that implements `TasHttpClient`:
37
+
38
+ ```typescript
39
+ import { Injectable } from "@angular/core";
40
+ import { Observable } from "rxjs";
41
+ import { TasHttpClient } from "tas-uell-sdk";
42
+
43
+ @Injectable({ providedIn: 'root' })
44
+ export class TasHttpAdapter implements TasHttpClient {
45
+ constructor(private http: HttpClient) {}
46
+
47
+ post<T>(url: string, body: any, options?: { headers?: Record<string, string> }): Observable<T> {
48
+ return this.http.post<T>(url, body, { headers: options?.headers });
49
+ }
50
+ }
51
+ ```
52
+
53
+ #### User Data Provider Adapter
54
+
55
+ Create a service that implements `TasUserDataProvider`:
56
+
57
+ ```typescript
58
+ import { Injectable } from "@angular/core";
59
+ import { TasUserDataProvider, TasUserData } from "tas-uell-sdk";
60
+
61
+ @Injectable({ providedIn: 'root' })
62
+ export class TasUserDataAdapter implements TasUserDataProvider {
63
+ getUserData(): TasUserData | null {
64
+ // Return the current user's data
65
+ const user = this.authService.getCurrentUser();
66
+ if (user) {
67
+ return {
68
+ id: user.id,
69
+ name: user.firstName,
70
+ surname: user.lastName,
71
+ };
72
+ }
73
+ return null;
74
+ }
75
+
76
+ getTenantId(): string | null {
77
+ // Return the current tenant ID
78
+ return this.authService.getTenantId();
79
+ }
80
+ }
81
+ ```
82
+
83
+ ### 2. Configure the Module
84
+
85
+ In your root module (e.g., `AppModule`):
86
+
87
+ ```typescript
88
+ import { NgModule } from '@angular/core';
89
+ import { TasModule, TAS_CONFIG, TAS_HTTP_CLIENT, TAS_USER_DATA_PROVIDER } from 'tas-uell-sdk';
90
+ import { TasHttpAdapter } from './adapters/tas-http-adapter.service';
91
+ import { TasUserDataAdapter } from './adapters/tas-user-data-adapter.service';
92
+ import { environment } from '../environments/environment';
93
+
94
+ @NgModule({
95
+ imports: [
96
+ // ... other imports
97
+ TasModule
98
+ ],
99
+ providers: [
100
+ {
101
+ provide: TAS_CONFIG,
102
+ useValue: {
103
+ tokBoxApiKey: environment.tokBoxApiKey,
104
+ apiBaseUrl: environment.apiUrl
105
+ }
106
+ },
107
+ { provide: TAS_HTTP_CLIENT, useExisting: TasHttpAdapter },
108
+ { provide: TAS_USER_DATA_PROVIDER, useExisting: TasUserDataAdapter }
109
+ ]
110
+ })
111
+ export class AppModule { }
112
+ ```
113
+
114
+ ### 3. Import in Feature Modules
115
+
116
+ In any feature module where you want to use the TAS components:
117
+
118
+ ```typescript
119
+ import { TasModule } from 'tas-uell-sdk';
120
+
121
+ @NgModule({
122
+ imports: [
123
+ TasModule
124
+ ]
125
+ })
126
+ export class MyFeatureModule { }
127
+ ```
128
+
129
+ ## Usage
130
+
131
+ ### TAS Button Component
132
+
133
+ Add the video call button to your template:
134
+
135
+ ```html
136
+ <tas-btn *ngIf="showVideoCall"></tas-btn>
137
+ ```
138
+
139
+ When clicked, this button will:
140
+ 1. Create a video room via your API
141
+ 2. Generate a session token
142
+ 3. Open the video call modal
143
+
144
+ ### Floating Call Component
145
+
146
+ Add the floating PiP widget to your root component template:
147
+
148
+ ```html
149
+ <router-outlet></router-outlet>
150
+ <tas-floating-call></tas-floating-call>
151
+ ```
152
+
153
+ This component shows a draggable mini video player when the user switches to PiP mode during a call.
154
+
155
+ ## Components
156
+
157
+ | Component | Selector | Description |
158
+ |-----------|----------|-------------|
159
+ | `TasButtonComponent` | `<tas-btn>` | Button to initiate a video call |
160
+ | `TasVideocallComponent` | `<tas-videocall>` | Full video call modal (opened automatically) |
161
+ | `TasFloatingCallComponent` | `<tas-floating-call>` | Floating PiP widget for minimized calls |
162
+
163
+ ## Services
164
+
165
+ ### TasService
166
+
167
+ The main service for managing video calls.
168
+
169
+ ```typescript
170
+ import { TasService } from 'tas-uell-sdk';
171
+
172
+ @Component({...})
173
+ export class MyComponent {
174
+ constructor(private tasService: TasService) {}
175
+
176
+ // Subscribe to call state changes
177
+ ngOnInit() {
178
+ this.tasService.callState$.subscribe(state => {
179
+ console.log('Call state:', state); // IDLE, CONNECTING, CONNECTED, DISCONNECTED, ERROR
180
+ });
181
+
182
+ this.tasService.viewMode$.subscribe(mode => {
183
+ console.log('View mode:', mode); // FULLSCREEN, PIP
184
+ });
185
+
186
+ this.tasService.isMuted$.subscribe(muted => {
187
+ console.log('Is muted:', muted);
188
+ });
189
+ }
190
+ }
191
+ ```
192
+
193
+ ## Interfaces
194
+
195
+ ### TasConfig
196
+
197
+ ```typescript
198
+ interface TasConfig {
199
+ tokBoxApiKey: string; // Your OpenTok/Vonage API Key
200
+ apiBaseUrl: string; // Base URL for TAS API endpoints
201
+ }
202
+ ```
203
+
204
+ ### TasHttpClient
205
+
206
+ ```typescript
207
+ interface TasHttpClient {
208
+ post<T>(url: string, body: any, options?: { headers?: Record<string, string> }): Observable<T>;
209
+ }
210
+ ```
211
+
212
+ ### TasUserDataProvider
213
+
214
+ ```typescript
215
+ interface TasUserDataProvider {
216
+ getUserData(): TasUserData | null;
217
+ getTenantId(): string | null;
218
+ }
219
+ ```
220
+
221
+ ### TasUserData
222
+
223
+ ```typescript
224
+ interface TasUserData {
225
+ id: string | number;
226
+ name: string;
227
+ surname: string;
228
+ }
229
+ ```
230
+
231
+ ## API Endpoints
232
+
233
+ The library expects the following API endpoints to be available:
234
+
235
+ | Method | Endpoint | Description |
236
+ |--------|----------|-------------|
237
+ | POST | `{apiBaseUrl}/v2/room` | Create a video room |
238
+ | POST | `{apiBaseUrl}/v2/room/token` | Generate session token |
239
+
240
+ ### Create Room Request
241
+
242
+ ```typescript
243
+ {
244
+ tenant: string;
245
+ userId: string;
246
+ product: string;
247
+ record: boolean;
248
+ roomType: string;
249
+ type: string;
250
+ }
251
+ ```
252
+
253
+ ### Generate Token Request
254
+
255
+ ```typescript
256
+ {
257
+ sessionId: string;
258
+ name: string;
259
+ lastname: string;
260
+ }
261
+ ```
262
+
263
+ ## Styling
264
+
265
+ The library includes default styles for all components. You may need to add global styles for the modal:
266
+
267
+ ```scss
268
+ // styles.scss
269
+ ngb-modal-window.tas-video-modal {
270
+ .modal-dialog {
271
+ max-width: 100vw;
272
+ height: 100vh;
273
+ margin: 0;
274
+ }
275
+ .modal-content {
276
+ background-color: transparent;
277
+ border: none;
278
+ height: 100%;
279
+ }
280
+ }
281
+ ```
282
+
283
+ ## Building the Library
284
+
285
+ ```bash
286
+ cd TAS-Uell-SDK
287
+ npm install
288
+ npm run build
289
+ ```
290
+
291
+ The built library will be in the `dist/` folder.
292
+
293
+ ## Publishing
294
+
295
+ ```bash
296
+ cd dist/tas-uell-sdk
297
+ npm publish
298
+ ```
299
+
300
+ ## License
301
+
302
+ MIT
303
+
304
+
@@ -0,0 +1,123 @@
1
+ import { Component, Inject, Optional } from "@angular/core";
2
+ import { ViewMode } from "../../services/tas.service";
3
+ import { TAS_USER_DATA_PROVIDER, } from "../../tas.config";
4
+ import { TasVideocallComponent } from "../tas-videocall/tas-videocall.component";
5
+ import { Subscription } from "rxjs";
6
+ import { switchMap } from "rxjs/operators";
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "../../services/tas.service";
9
+ import * as i2 from "@ng-bootstrap/ng-bootstrap";
10
+ import * as i3 from "@angular/common";
11
+ export class TasButtonComponent {
12
+ constructor(tasService, modalService, userDataProvider) {
13
+ this.tasService = tasService;
14
+ this.modalService = modalService;
15
+ this.userDataProvider = userDataProvider;
16
+ this.isLoading = false;
17
+ this.userData = null;
18
+ this.tenantId = null;
19
+ this.subscriptions = new Subscription();
20
+ this.currentModalRef = null;
21
+ }
22
+ ngOnInit() {
23
+ this.loadUserData();
24
+ this.setupViewModeSubscription();
25
+ }
26
+ ngOnDestroy() {
27
+ this.subscriptions.unsubscribe();
28
+ }
29
+ onClick() {
30
+ if (!this.userData || !this.tenantId) {
31
+ console.error("User data or tenant ID not available");
32
+ return;
33
+ }
34
+ this.isLoading = true;
35
+ this.subscriptions.add(this.tasService
36
+ .createRoom({
37
+ tenant: this.tenantId,
38
+ userId: this.userData.id.toString(),
39
+ product: "Uell",
40
+ record: true,
41
+ roomType: "TAS",
42
+ type: "SPONTANEOUS",
43
+ })
44
+ .pipe(switchMap((response) => {
45
+ const sessionId = response.content.sessionId;
46
+ return this.tasService
47
+ .generateToken({
48
+ sessionId: sessionId,
49
+ name: this.userData.name,
50
+ lastname: this.userData.surname,
51
+ })
52
+ .pipe(switchMap((tokenResponse) => {
53
+ return [
54
+ {
55
+ sessionId,
56
+ token: tokenResponse.content.token,
57
+ },
58
+ ];
59
+ }));
60
+ }))
61
+ .subscribe({
62
+ next: ({ sessionId, token }) => {
63
+ this.isLoading = false;
64
+ this.openVideoCallModal(sessionId, token);
65
+ },
66
+ error: (err) => {
67
+ console.error("Error starting video call:", err);
68
+ this.isLoading = false;
69
+ },
70
+ }));
71
+ }
72
+ // Private Methods
73
+ loadUserData() {
74
+ if (!this.userDataProvider) {
75
+ console.warn("TasButtonComponent: UserDataProvider not configured");
76
+ return;
77
+ }
78
+ this.userData = this.userDataProvider.getUserData();
79
+ this.tenantId = this.userDataProvider.getTenantId();
80
+ }
81
+ setupViewModeSubscription() {
82
+ this.subscriptions.add(this.tasService.viewMode$.subscribe((mode) => {
83
+ if (mode === ViewMode.FULLSCREEN &&
84
+ this.tasService.isCallActive() &&
85
+ !this.currentModalRef) {
86
+ const sessionId = this.tasService.sessionId;
87
+ const token = this.tasService.token;
88
+ if (sessionId && token) {
89
+ this.openVideoCallModal(sessionId, token, true);
90
+ }
91
+ }
92
+ }));
93
+ }
94
+ openVideoCallModal(sessionId, token, isReturningFromPip = false) {
95
+ this.currentModalRef = this.modalService.open(TasVideocallComponent, {
96
+ size: "xl",
97
+ windowClass: "tas-video-modal",
98
+ backdrop: "static",
99
+ keyboard: false,
100
+ });
101
+ this.currentModalRef.componentInstance.sessionId = sessionId;
102
+ this.currentModalRef.componentInstance.token = token;
103
+ this.currentModalRef.componentInstance.isReturningFromPip =
104
+ isReturningFromPip;
105
+ this.currentModalRef.result.then(() => {
106
+ this.currentModalRef = null;
107
+ }, () => {
108
+ this.currentModalRef = null;
109
+ });
110
+ }
111
+ }
112
+ TasButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasButtonComponent, deps: [{ token: i1.TasService }, { token: i2.NgbModal }, { token: TAS_USER_DATA_PROVIDER, optional: true }], target: i0.ɵɵFactoryTarget.Component });
113
+ TasButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TasButtonComponent, selector: "tas-btn", ngImport: i0, template: "<button\n type=\"button\"\n class=\"btn btn-primary boton\"\n (click)=\"onClick()\"\n [disabled]=\"isLoading\"\n>\n <i class=\"fa fa-video-camera\" aria-hidden=\"true\" *ngIf=\"!isLoading\"></i>\n <span *ngIf=\"!isLoading\"> Iniciar TAS</span>\n <span *ngIf=\"isLoading\"> Processing...</span>\n</button>\n", styles: [":host{display:inline-block}.boton{background-color:#ee316b!important;color:#fff!important;margin-right:24px}.boton:disabled{background-color:#ccc!important;border-color:#ccc!important;cursor:not-allowed}.boton i{margin-right:5px}\n"], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
114
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasButtonComponent, decorators: [{
115
+ type: Component,
116
+ args: [{ selector: "tas-btn", template: "<button\n type=\"button\"\n class=\"btn btn-primary boton\"\n (click)=\"onClick()\"\n [disabled]=\"isLoading\"\n>\n <i class=\"fa fa-video-camera\" aria-hidden=\"true\" *ngIf=\"!isLoading\"></i>\n <span *ngIf=\"!isLoading\"> Iniciar TAS</span>\n <span *ngIf=\"isLoading\"> Processing...</span>\n</button>\n", styles: [":host{display:inline-block}.boton{background-color:#ee316b!important;color:#fff!important;margin-right:24px}.boton:disabled{background-color:#ccc!important;border-color:#ccc!important;cursor:not-allowed}.boton i{margin-right:5px}\n"] }]
117
+ }], ctorParameters: function () { return [{ type: i1.TasService }, { type: i2.NgbModal }, { type: undefined, decorators: [{
118
+ type: Optional
119
+ }, {
120
+ type: Inject,
121
+ args: [TAS_USER_DATA_PROVIDER]
122
+ }] }]; } });
123
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFzLWJ0bi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvdGFzLWJ0bi90YXMtYnRuLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy90YXMtYnRuL3Rhcy1idG4uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBcUIsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRSxPQUFPLEVBQWMsUUFBUSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDbEUsT0FBTyxFQUNMLHNCQUFzQixHQUd2QixNQUFNLGtCQUFrQixDQUFDO0FBRTFCLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDBDQUEwQyxDQUFDO0FBQ2pGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDcEMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7OztBQU8zQyxNQUFNLE9BQU8sa0JBQWtCO0lBUTdCLFlBQ1UsVUFBc0IsRUFDdEIsWUFBc0IsRUFHdEIsZ0JBQTRDO1FBSjVDLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIsaUJBQVksR0FBWixZQUFZLENBQVU7UUFHdEIscUJBQWdCLEdBQWhCLGdCQUFnQixDQUE0QjtRQVp0RCxjQUFTLEdBQUcsS0FBSyxDQUFDO1FBRVYsYUFBUSxHQUF1QixJQUFJLENBQUM7UUFDcEMsYUFBUSxHQUFrQixJQUFJLENBQUM7UUFDL0Isa0JBQWEsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ25DLG9CQUFlLEdBQXVCLElBQUksQ0FBQztJQVFoRCxDQUFDO0lBRUosUUFBUTtRQUNOLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNwQixJQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQztJQUNuQyxDQUFDO0lB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b21wb25lbnQsIE9uSW5pdCwgT25EZXN0cm95LCBJbmplY3QsIE9wdGlvbmFsIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IFRhc1NlcnZpY2UsIFZpZXdNb2RlIH0gZnJvbSBcIi4uLy4uL3NlcnZpY2VzL3Rhcy5zZXJ2aWNlXCI7XG5pbXBvcnQge1xuICBUQVNfVVNFUl9EQVRBX1BST1ZJREVSLFxuICBUYXNVc2VyRGF0YVByb3ZpZGVyLFxuICBUYXNVc2VyRGF0YSxcbn0gZnJvbSBcIi4uLy4uL3Rhcy5jb25maWdcIjtcbmltcG9ydCB7IE5nYk1vZGFsLCBOZ2JNb2RhbFJlZiB9IGZyb20gXCJAbmctYm9vdHN0cmFwL25nLWJvb3RzdHJhcFwiO1xuaW1wb3J0IHsgVGFzVmlkZW9jYWxsQ29tcG9uZW50IH0gZnJvbSBcIi4uL3Rhcy12aWRlb2NhbGwvdGFzLXZpZGVvY2FsbC5jb21wb25lbnRcIjtcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gXCJyeGpzXCI7XG5pbXBvcnQgeyBzd2l0Y2hNYXAgfSBmcm9tIFwicnhqcy9vcGVyYXRvcnNcIjtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiBcInRhcy1idG5cIixcbiAgdGVtcGxhdGVVcmw6IFwiLi90YXMtYnRuLmNvbXBvbmVudC5odG1sXCIsXG4gIHN0eWxlVXJsczogW1wiLi90YXMtYnRuLmNvbXBvbmVudC5zY3NzXCJdLFxufSlcbmV4cG9ydCBjbGFzcyBUYXNCdXR0b25Db21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIGlzTG9hZGluZyA9IGZhbHNlO1xuXG4gIHByaXZhdGUgdXNlckRhdGE6IFRhc1VzZXJEYXRhIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgdGVuYW50SWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHN1YnNjcmlwdGlvbnMgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gIHByaXZhdGUgY3VycmVudE1vZGFsUmVmOiBOZ2JNb2RhbFJlZiB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgdGFzU2VydmljZTogVGFzU2VydmljZSxcbiAgICBwcml2YXRlIG1vZGFsU2VydmljZTogTmdiTW9kYWwsXG4gICAgQE9wdGlvbmFsKClcbiAgICBASW5qZWN0KFRBU19VU0VSX0RBVEFfUFJPVklERVIpXG4gICAgcHJpdmF0ZSB1c2VyRGF0YVByb3ZpZGVyOiBUYXNVc2VyRGF0YVByb3ZpZGVyIHwgbnVsbFxuICApIHt9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5sb2FkVXNlckRhdGEoKTtcbiAgICB0aGlzLnNldHVwVmlld01vZGVTdWJzY3JpcHRpb24oKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgb25DbGljaygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMudXNlckRhdGEgfHwgIXRoaXMudGVuYW50SWQpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJVc2VyIGRhdGEgb3IgdGVuYW50IElEIG5vdCBhdmFpbGFibGVcIik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5pc0xvYWRpbmcgPSB0cnVlO1xuXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChcbiAgICAgIHRoaXMudGFzU2VydmljZVxuICAgICAgICAuY3JlYXRlUm9vbSh7XG4gICAgICAgICAgdGVuYW50OiB0aGlzLnRlbmFudElkLFxuICAgICAgICAgIHVzZXJJZDogdGhpcy51c2VyRGF0YS5pZC50b1N0cmluZygpLFxuICAgICAgICAgIHByb2R1Y3Q6IFwiVWVsbFwiLFxuICAgICAgICAgIHJlY29yZDogdHJ1ZSxcbiAgICAgICAgICByb29tVHlwZTogXCJUQVNcIixcbiAgICAgICAgICB0eXBlOiBcIlNQT05UQU5FT1VTXCIsXG4gICAgICAgIH0pXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIHN3aXRjaE1hcCgocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHNlc3Npb25JZCA9IHJlc3BvbnNlLmNvbnRlbnQuc2Vzc2lvbklkO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudGFzU2VydmljZVxuICAgICAgICAgICAgICAuZ2VuZXJhdGVUb2tlbih7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbklkOiBzZXNzaW9uSWQsXG4gICAgICAgICAgICAgICAgbmFtZTogdGhpcy51c2VyRGF0YSEubmFtZSxcbiAgICAgICAgICAgICAgICBsYXN0bmFtZTogdGhpcy51c2VyRGF0YSEuc3VybmFtZSxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgc3dpdGNoTWFwKCh0b2tlblJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgIHRva2VuOiB0b2tlblJlc3BvbnNlLmNvbnRlbnQudG9rZW4sXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgfSlcbiAgICAgICAgKVxuICAgICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgICBuZXh0OiAoeyBzZXNzaW9uSWQsIHRva2VuIH0pID0+IHtcbiAgICAgICAgICAgIHRoaXMuaXNMb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLm9wZW5WaWRlb0NhbGxNb2RhbChzZXNzaW9uSWQsIHRva2VuKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVycm9yOiAoZXJyKSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc3RhcnRpbmcgdmlkZW8gY2FsbDpcIiwgZXJyKTtcbiAgICAgICAgICAgIHRoaXMuaXNMb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLy8gUHJpdmF0ZSBNZXRob2RzXG4gIHByaXZhdGUgbG9hZFVzZXJEYXRhKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy51c2VyRGF0YVByb3ZpZGVyKSB7XG4gICAgICBjb25zb2xlLndhcm4oXCJUYXNCdXR0b25Db21wb25lbnQ6IFVzZXJEYXRhUHJvdmlkZXIgbm90IGNvbmZpZ3VyZWRcIik7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMudXNlckRhdGEgPSB0aGlzLnVzZXJEYXRhUHJvdmlkZXIuZ2V0VXNlckRhdGEoKTtcbiAgICB0aGlzLnRlbmFudElkID0gdGhpcy51c2VyRGF0YVByb3ZpZGVyLmdldFRlbmFudElkKCk7XG4gIH1cblxuICBwcml2YXRlIHNldHVwVmlld01vZGVTdWJzY3JpcHRpb24oKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChcbiAgICAgIHRoaXMudGFzU2VydmljZS52aWV3TW9kZSQuc3Vic2NyaWJlKChtb2RlKSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBtb2RlID09PSBWaWV3TW9kZS5GVUxMU0NSRUVOICYmXG4gICAgICAgICAgdGhpcy50YXNTZXJ2aWNlLmlzQ2FsbEFjdGl2ZSgpICYmXG4gICAgICAgICAgIXRoaXMuY3VycmVudE1vZGFsUmVmXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IHNlc3Npb25JZCA9IHRoaXMudGFzU2VydmljZS5zZXNzaW9uSWQ7XG4gICAgICAgICAgY29uc3QgdG9rZW4gPSB0aGlzLnRhc1NlcnZpY2UudG9rZW47XG4gICAgICAgICAgaWYgKHNlc3Npb25JZCAmJiB0b2tlbikge1xuICAgICAgICAgICAgdGhpcy5vcGVuVmlkZW9DYWxsTW9kYWwoc2Vzc2lvbklkLCB0b2tlbiwgdHJ1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIG9wZW5WaWRlb0NhbGxNb2RhbChcbiAgICBzZXNzaW9uSWQ6IHN0cmluZyxcbiAgICB0b2tlbjogc3RyaW5nLFxuICAgIGlzUmV0dXJuaW5nRnJvbVBpcDogYm9vbGVhbiA9IGZhbHNlXG4gICk6IHZvaWQge1xuICAgIHRoaXMuY3VycmVudE1vZGFsUmVmID0gdGhpcy5tb2RhbFNlcnZpY2Uub3BlbihUYXNWaWRlb2NhbGxDb21wb25lbnQsIHtcbiAgICAgIHNpemU6IFwieGxcIixcbiAgICAgIHdpbmRvd0NsYXNzOiBcInRhcy12aWRlby1tb2RhbFwiLFxuICAgICAgYmFja2Ryb3A6IFwic3RhdGljXCIsXG4gICAgICBrZXlib2FyZDogZmFsc2UsXG4gICAgfSk7XG5cbiAgICB0aGlzLmN1cnJlbnRNb2RhbFJlZi5jb21wb25lbnRJbnN0YW5jZS5zZXNzaW9uSWQgPSBzZXNzaW9uSWQ7XG4gICAgdGhpcy5jdXJyZW50TW9kYWxSZWYuY29tcG9uZW50SW5zdGFuY2UudG9rZW4gPSB0b2tlbjtcbiAgICB0aGlzLmN1cnJlbnRNb2RhbFJlZi5jb21wb25lbnRJbnN0YW5jZS5pc1JldHVybmluZ0Zyb21QaXAgPVxuICAgICAgaXNSZXR1cm5pbmdGcm9tUGlwO1xuXG4gICAgdGhpcy5jdXJyZW50TW9kYWxSZWYucmVzdWx0LnRoZW4oXG4gICAgICAoKSA9PiB7XG4gICAgICAgIHRoaXMuY3VycmVudE1vZGFsUmVmID0gbnVsbDtcbiAgICAgIH0sXG4gICAgICAoKSA9PiB7XG4gICAgICAgIHRoaXMuY3VycmVudE1vZGFsUmVmID0gbnVsbDtcbiAgICAgIH1cbiAgICApO1xuICB9XG59XG4iLCI8YnV0dG9uXG4gIHR5cGU9XCJidXR0b25cIlxuICBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSBib3RvblwiXG4gIChjbGljayk9XCJvbkNsaWNrKClcIlxuICBbZGlzYWJsZWRdPVwiaXNMb2FkaW5nXCJcbj5cbiAgPGkgY2xhc3M9XCJmYSBmYS12aWRlby1jYW1lcmFcIiBhcmlhLWhpZGRlbj1cInRydWVcIiAqbmdJZj1cIiFpc0xvYWRpbmdcIj48L2k+XG4gIDxzcGFuICpuZ0lmPVwiIWlzTG9hZGluZ1wiPiBJbmljaWFyIFRBUzwvc3Bhbj5cbiAgPHNwYW4gKm5nSWY9XCJpc0xvYWRpbmdcIj4gUHJvY2Vzc2luZy4uLjwvc3Bhbj5cbjwvYnV0dG9uPlxuIl19
@@ -0,0 +1,79 @@
1
+ import { Component } from "@angular/core";
2
+ import { CallState, ViewMode } from "../../services/tas.service";
3
+ import { Subscription } from "rxjs";
4
+ import interact from "interactjs";
5
+ import * as i0 from "@angular/core";
6
+ import * as i1 from "../../services/tas.service";
7
+ export class TasFloatingCallComponent {
8
+ constructor(tasService) {
9
+ this.tasService = tasService;
10
+ this.isVisible = false;
11
+ this.isMuted = false;
12
+ this.subscriptions = new Subscription();
13
+ }
14
+ ngOnInit() {
15
+ this.setupSubscriptions();
16
+ }
17
+ ngOnDestroy() {
18
+ this.subscriptions.unsubscribe();
19
+ interact(".tas-floating-container").unset();
20
+ }
21
+ // Public Methods
22
+ onExpand() {
23
+ this.tasService.exitPipMode();
24
+ }
25
+ onHangUp() {
26
+ this.tasService.disconnectSession();
27
+ }
28
+ toggleMute() {
29
+ this.tasService.toggleMute();
30
+ }
31
+ // Private Methods
32
+ setupSubscriptions() {
33
+ this.subscriptions.add(this.tasService.callState$.subscribe((state) => {
34
+ if (state === CallState.DISCONNECTED) {
35
+ this.isVisible = false;
36
+ }
37
+ }));
38
+ this.subscriptions.add(this.tasService.viewMode$.subscribe((mode) => {
39
+ this.isVisible =
40
+ mode === ViewMode.PIP && this.tasService.isCallActive();
41
+ if (this.isVisible) {
42
+ setTimeout(() => this.initInteract(), 100);
43
+ }
44
+ }));
45
+ this.subscriptions.add(this.tasService.isMuted$.subscribe((muted) => {
46
+ this.isMuted = muted;
47
+ }));
48
+ }
49
+ initInteract() {
50
+ interact(".tas-floating-container").unset();
51
+ interact(".tas-floating-container").draggable({
52
+ inertia: true,
53
+ modifiers: [
54
+ interact.modifiers.restrictRect({
55
+ restriction: "body",
56
+ endOnly: true,
57
+ }),
58
+ ],
59
+ autoScroll: false,
60
+ listeners: {
61
+ move: (event) => {
62
+ const target = event.target;
63
+ const x = (parseFloat(target.getAttribute("data-x")) || 0) + event.dx;
64
+ const y = (parseFloat(target.getAttribute("data-y")) || 0) + event.dy;
65
+ target.style.transform = `translate(${x}px, ${y}px)`;
66
+ target.setAttribute("data-x", String(x));
67
+ target.setAttribute("data-y", String(y));
68
+ },
69
+ },
70
+ });
71
+ }
72
+ }
73
+ TasFloatingCallComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasFloatingCallComponent, deps: [{ token: i1.TasService }], target: i0.ɵɵFactoryTarget.Component });
74
+ TasFloatingCallComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TasFloatingCallComponent, selector: "tas-floating-call", ngImport: i0, template: "<div class=\"tas-floating-container\" [class.visible]=\"isVisible\">\n <div class=\"floating-content\">\n <div id=\"pip-main-video\" class=\"pip-main-video\"></div>\n\n <div class=\"floating-controls\">\n <button\n class=\"action-btn expand-btn\"\n (click)=\"onExpand()\"\n title=\"Expandir a pantalla completa\"\n >\n <i class=\"fa fa-expand\"></i>\n </button>\n <button\n class=\"action-btn mute-btn\"\n [class.muted]=\"isMuted\"\n (click)=\"toggleMute()\"\n [title]=\"isMuted ? 'Activar micr\u00F3fono' : 'Silenciar micr\u00F3fono'\"\n >\n <i\n class=\"fa\"\n [class.fa-microphone]=\"!isMuted\"\n [class.fa-microphone-slash]=\"isMuted\"\n ></i>\n </button>\n <button\n class=\"action-btn hangup-btn\"\n (click)=\"onHangUp()\"\n title=\"Colgar llamada\"\n >\n <i class=\"fa fa-phone\" style=\"transform: rotate(135deg)\"></i>\n </button>\n </div>\n </div>\n</div>\n", styles: [".tas-floating-container{position:fixed;bottom:20px;right:20px;width:280px;height:180px;background:#000;border-radius:12px;box-shadow:0 8px 32px #00000080;z-index:9999;overflow:hidden;touch-action:none;-webkit-user-select:none;user-select:none;transition:opacity .3s ease,visibility .3s ease;opacity:0;visibility:hidden;pointer-events:none}.tas-floating-container.visible{opacity:1;visibility:visible;pointer-events:auto}.floating-content{position:relative;width:100%;height:100%;overflow:hidden}.pip-main-video{position:absolute;top:0;left:0;width:100%;height:100%;background:#000}.pip-main-video ::ng-deep video{width:100%;height:100%;object-fit:cover}.pip-main-video ::ng-deep .OT_subscriber,.pip-main-video ::ng-deep .OT_publisher{width:100%!important;height:100%!important}.pip-main-video ::ng-deep .OT_edge-bar-item,.pip-main-video ::ng-deep .OT_mute,.pip-main-video ::ng-deep .OT_audio-level-meter,.pip-main-video ::ng-deep .OT_bar,.pip-main-video ::ng-deep .OT_name{display:none!important}.floating-controls{position:absolute;bottom:10px;left:50%;transform:translate(-50%);display:flex;gap:12px;padding:6px 14px;background:rgba(0,0,0,.7);border-radius:24px;backdrop-filter:blur(8px)}.action-btn{width:32px;height:32px;border:none;border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:13px;transition:all .2s ease}.action-btn.expand-btn{background:rgba(255,255,255,.2);color:#fff}.action-btn.expand-btn:hover{background:rgba(255,255,255,.35);transform:scale(1.1)}.action-btn.mute-btn{background:rgba(255,255,255,.2);color:#fff}.action-btn.mute-btn:hover{background:rgba(255,255,255,.35);transform:scale(1.1)}.action-btn.mute-btn.muted{background:#f39c12;color:#fff}.action-btn.mute-btn.muted:hover{background:#e67e22}.action-btn.hangup-btn{background:#dc3545;color:#fff}.action-btn.hangup-btn:hover{background:#c82333;transform:scale(1.1)}\n"] });
75
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasFloatingCallComponent, decorators: [{
76
+ type: Component,
77
+ args: [{ selector: "tas-floating-call", template: "<div class=\"tas-floating-container\" [class.visible]=\"isVisible\">\n <div class=\"floating-content\">\n <div id=\"pip-main-video\" class=\"pip-main-video\"></div>\n\n <div class=\"floating-controls\">\n <button\n class=\"action-btn expand-btn\"\n (click)=\"onExpand()\"\n title=\"Expandir a pantalla completa\"\n >\n <i class=\"fa fa-expand\"></i>\n </button>\n <button\n class=\"action-btn mute-btn\"\n [class.muted]=\"isMuted\"\n (click)=\"toggleMute()\"\n [title]=\"isMuted ? 'Activar micr\u00F3fono' : 'Silenciar micr\u00F3fono'\"\n >\n <i\n class=\"fa\"\n [class.fa-microphone]=\"!isMuted\"\n [class.fa-microphone-slash]=\"isMuted\"\n ></i>\n </button>\n <button\n class=\"action-btn hangup-btn\"\n (click)=\"onHangUp()\"\n title=\"Colgar llamada\"\n >\n <i class=\"fa fa-phone\" style=\"transform: rotate(135deg)\"></i>\n </button>\n </div>\n </div>\n</div>\n", styles: [".tas-floating-container{position:fixed;bottom:20px;right:20px;width:280px;height:180px;background:#000;border-radius:12px;box-shadow:0 8px 32px #00000080;z-index:9999;overflow:hidden;touch-action:none;-webkit-user-select:none;user-select:none;transition:opacity .3s ease,visibility .3s ease;opacity:0;visibility:hidden;pointer-events:none}.tas-floating-container.visible{opacity:1;visibility:visible;pointer-events:auto}.floating-content{position:relative;width:100%;height:100%;overflow:hidden}.pip-main-video{position:absolute;top:0;left:0;width:100%;height:100%;background:#000}.pip-main-video ::ng-deep video{width:100%;height:100%;object-fit:cover}.pip-main-video ::ng-deep .OT_subscriber,.pip-main-video ::ng-deep .OT_publisher{width:100%!important;height:100%!important}.pip-main-video ::ng-deep .OT_edge-bar-item,.pip-main-video ::ng-deep .OT_mute,.pip-main-video ::ng-deep .OT_audio-level-meter,.pip-main-video ::ng-deep .OT_bar,.pip-main-video ::ng-deep .OT_name{display:none!important}.floating-controls{position:absolute;bottom:10px;left:50%;transform:translate(-50%);display:flex;gap:12px;padding:6px 14px;background:rgba(0,0,0,.7);border-radius:24px;backdrop-filter:blur(8px)}.action-btn{width:32px;height:32px;border:none;border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:13px;transition:all .2s ease}.action-btn.expand-btn{background:rgba(255,255,255,.2);color:#fff}.action-btn.expand-btn:hover{background:rgba(255,255,255,.35);transform:scale(1.1)}.action-btn.mute-btn{background:rgba(255,255,255,.2);color:#fff}.action-btn.mute-btn:hover{background:rgba(255,255,255,.35);transform:scale(1.1)}.action-btn.mute-btn.muted{background:#f39c12;color:#fff}.action-btn.mute-btn.muted:hover{background:#e67e22}.action-btn.hangup-btn{background:#dc3545;color:#fff}.action-btn.hangup-btn:hover{background:#c82333;transform:scale(1.1)}\n"] }]
78
+ }], ctorParameters: function () { return [{ type: i1.TasService }]; } });
79
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFzLWZsb2F0aW5nLWNhbGwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9jb21wb25lbnRzL3Rhcy1mbG9hdGluZy1jYWxsL3Rhcy1mbG9hdGluZy1jYWxsLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy90YXMtZmxvYXRpbmctY2FsbC90YXMtZmxvYXRpbmctY2FsbC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFxQixNQUFNLGVBQWUsQ0FBQztBQUM3RCxPQUFPLEVBQWMsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzdFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDcEMsT0FBTyxRQUFRLE1BQU0sWUFBWSxDQUFDOzs7QUFPbEMsTUFBTSxPQUFPLHdCQUF3QjtJQU1uQyxZQUFvQixVQUFzQjtRQUF0QixlQUFVLEdBQVYsVUFBVSxDQUFZO1FBTG5DLGNBQVMsR0FBRyxLQUFLLENBQUM7UUFDbEIsWUFBTyxHQUFHLEtBQUssQ0FBQztRQUVmLGtCQUFhLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztJQUVFLENBQUM7SUFFOUMsUUFBUTtRQUNOLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNqQyxRQUFRLENBQUMseUJBQXlCLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUM5QyxDQUFDO0lBRUQsaUJBQWlCO0lBQ2pCLFFBQVE7UUFDTixJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ2hDLENBQUM7SUFFRCxRQUFRO1FBQ04sSUFBSSxDQUFDLFVBQVUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0lBQ3RDLENBQUM7SUFFRCxVQUFVO1FBQ1IsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUMvQixDQUFDO0lBRUQsa0JBQWtCO0lBQ1Ysa0JBQWtCO1FBQ3hCLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUNwQixJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUM3QyxJQUFJLEtBQUssS0FBSyxTQUFTLENBQUMsWUFBWSxFQUFFO2dCQUNwQyxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQzthQUN4QjtRQUNILENBQUMsQ0FBQyxDQUNILENBQUM7UUFFRixJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FDcEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFDM0MsSUFBSSxDQUFDLFNBQVM7Z0JBQ1osSUFBSSxLQUFLLFFBQVEsQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUMxRCxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7Z0JBQ2xCLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7YUFDNUM7UUFDSCxDQUFDLENBQUMsQ0FDSCxDQUFDO1FBRUYsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQ3BCLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQzNDLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLENBQUMsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDO0lBRU8sWUFBWTtRQUNsQixRQUFRLENBQUMseUJBQXlCLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUU1QyxRQUFRLENBQUMseUJBQXlCLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDNUMsT0FBTyxFQUFFLElBQUk7WUFDYixTQUFTLEVBQUU7Z0JBQ1QsUUFBUSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUM7b0JBQzlCLFdBQVcsRUFBRSxNQUFNO29CQUNuQixPQUFPLEVBQUUsSUFBSTtpQkFDZCxDQUFDO2FBQ0g7WUFDRCxVQUFVLEVBQUUsS0FBSztZQUNqQixTQUFTLEVBQUU7Z0JBQ1QsSUFBSSxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7b0JBQ2QsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztvQkFDNUIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUM7b0JBQ3RFLE1BQU0sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDO29CQUV0RSxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxhQUFhLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztvQkFDckQsTUFBTSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3pDLE1BQU0sQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUMzQyxDQUFDO2FBQ0Y7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDOztxSEFqRlUsd0JBQXdCO3lHQUF4Qix3QkFBd0IseURDVnJDLDBoQ0FrQ0E7MkZEeEJhLHdCQUF3QjtrQkFMcEMsU0FBUzsrQkFDRSxtQkFBbUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgT25EZXN0cm95IH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IFRhc1NlcnZpY2UsIENhbGxTdGF0ZSwgVmlld01vZGUgfSBmcm9tIFwiLi4vLi4vc2VydmljZXMvdGFzLnNlcnZpY2VcIjtcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gXCJyeGpzXCI7XG5pbXBvcnQgaW50ZXJhY3QgZnJvbSBcImludGVyYWN0anNcIjtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiBcInRhcy1mbG9hdGluZy1jYWxsXCIsXG4gIHRlbXBsYXRlVXJsOiBcIi4vdGFzLWZsb2F0aW5nLWNhbGwuY29tcG9uZW50Lmh0bWxcIixcbiAgc3R5bGVVcmxzOiBbXCIuL3Rhcy1mbG9hdGluZy1jYWxsLmNvbXBvbmVudC5zY3NzXCJdLFxufSlcbmV4cG9ydCBjbGFzcyBUYXNGbG9hdGluZ0NhbGxDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIHB1YmxpYyBpc1Zpc2libGUgPSBmYWxzZTtcbiAgcHVibGljIGlzTXV0ZWQgPSBmYWxzZTtcblxuICBwcml2YXRlIHN1YnNjcmlwdGlvbnMgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSB0YXNTZXJ2aWNlOiBUYXNTZXJ2aWNlKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuc2V0dXBTdWJzY3JpcHRpb25zKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMudW5zdWJzY3JpYmUoKTtcbiAgICBpbnRlcmFjdChcIi50YXMtZmxvYXRpbmctY29udGFpbmVyXCIpLnVuc2V0KCk7XG4gIH1cblxuICAvLyBQdWJsaWMgTWV0aG9kc1xuICBvbkV4cGFuZCgpOiB2b2lkIHtcbiAgICB0aGlzLnRhc1NlcnZpY2UuZXhpdFBpcE1vZGUoKTtcbiAgfVxuXG4gIG9uSGFuZ1VwKCk6IHZvaWQge1xuICAgIHRoaXMudGFzU2VydmljZS5kaXNjb25uZWN0U2Vzc2lvbigpO1xuICB9XG5cbiAgdG9nZ2xlTXV0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLnRhc1NlcnZpY2UudG9nZ2xlTXV0ZSgpO1xuICB9XG5cbiAgLy8gUHJpdmF0ZSBNZXRob2RzXG4gIHByaXZhdGUgc2V0dXBTdWJzY3JpcHRpb25zKCk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXG4gICAgICB0aGlzLnRhc1NlcnZpY2UuY2FsbFN0YXRlJC5zdWJzY3JpYmUoKHN0YXRlKSA9PiB7XG4gICAgICAgIGlmIChzdGF0ZSA9PT0gQ2FsbFN0YXRlLkRJU0NPTk5FQ1RFRCkge1xuICAgICAgICAgIHRoaXMuaXNWaXNpYmxlID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgKTtcblxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQoXG4gICAgICB0aGlzLnRhc1NlcnZpY2Uudmlld01vZGUkLnN1YnNjcmliZSgobW9kZSkgPT4ge1xuICAgICAgICB0aGlzLmlzVmlzaWJsZSA9XG4gICAgICAgICAgbW9kZSA9PT0gVmlld01vZGUuUElQICYmIHRoaXMudGFzU2VydmljZS5pc0NhbGxBY3RpdmUoKTtcbiAgICAgICAgaWYgKHRoaXMuaXNWaXNpYmxlKSB7XG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmluaXRJbnRlcmFjdCgpLCAxMDApO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICk7XG5cbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKFxuICAgICAgdGhpcy50YXNTZXJ2aWNlLmlzTXV0ZWQkLnN1YnNjcmliZSgobXV0ZWQpID0+IHtcbiAgICAgICAgdGhpcy5pc011dGVkID0gbXV0ZWQ7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGluaXRJbnRlcmFjdCgpOiB2b2lkIHtcbiAgICBpbnRlcmFjdChcIi50YXMtZmxvYXRpbmctY29udGFpbmVyXCIpLnVuc2V0KCk7XG5cbiAgICBpbnRlcmFjdChcIi50YXMtZmxvYXRpbmctY29udGFpbmVyXCIpLmRyYWdnYWJsZSh7XG4gICAgICBpbmVydGlhOiB0cnVlLFxuICAgICAgbW9kaWZpZXJzOiBbXG4gICAgICAgIGludGVyYWN0Lm1vZGlmaWVycy5yZXN0cmljdFJlY3Qoe1xuICAgICAgICAgIHJlc3RyaWN0aW9uOiBcImJvZHlcIixcbiAgICAgICAgICBlbmRPbmx5OiB0cnVlLFxuICAgICAgICB9KSxcbiAgICAgIF0sXG4gICAgICBhdXRvU2Nyb2xsOiBmYWxzZSxcbiAgICAgIGxpc3RlbmVyczoge1xuICAgICAgICBtb3ZlOiAoZXZlbnQpID0+IHtcbiAgICAgICAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQ7XG4gICAgICAgICAgY29uc3QgeCA9IChwYXJzZUZsb2F0KHRhcmdldC5nZXRBdHRyaWJ1dGUoXCJkYXRhLXhcIikpIHx8IDApICsgZXZlbnQuZHg7XG4gICAgICAgICAgY29uc3QgeSA9IChwYXJzZUZsb2F0KHRhcmdldC5nZXRBdHRyaWJ1dGUoXCJkYXRhLXlcIikpIHx8IDApICsgZXZlbnQuZHk7XG5cbiAgICAgICAgICB0YXJnZXQuc3R5bGUudHJhbnNmb3JtID0gYHRyYW5zbGF0ZSgke3h9cHgsICR7eX1weClgO1xuICAgICAgICAgIHRhcmdldC5zZXRBdHRyaWJ1dGUoXCJkYXRhLXhcIiwgU3RyaW5nKHgpKTtcbiAgICAgICAgICB0YXJnZXQuc2V0QXR0cmlidXRlKFwiZGF0YS15XCIsIFN0cmluZyh5KSk7XG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwidGFzLWZsb2F0aW5nLWNvbnRhaW5lclwiIFtjbGFzcy52aXNpYmxlXT1cImlzVmlzaWJsZVwiPlxuICA8ZGl2IGNsYXNzPVwiZmxvYXRpbmctY29udGVudFwiPlxuICAgIDxkaXYgaWQ9XCJwaXAtbWFpbi12aWRlb1wiIGNsYXNzPVwicGlwLW1haW4tdmlkZW9cIj48L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJmbG9hdGluZy1jb250cm9sc1wiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBjbGFzcz1cImFjdGlvbi1idG4gZXhwYW5kLWJ0blwiXG4gICAgICAgIChjbGljayk9XCJvbkV4cGFuZCgpXCJcbiAgICAgICAgdGl0bGU9XCJFeHBhbmRpciBhIHBhbnRhbGxhIGNvbXBsZXRhXCJcbiAgICAgID5cbiAgICAgICAgPGkgY2xhc3M9XCJmYSBmYS1leHBhbmRcIj48L2k+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgY2xhc3M9XCJhY3Rpb24tYnRuIG11dGUtYnRuXCJcbiAgICAgICAgW2NsYXNzLm11dGVkXT1cImlzTXV0ZWRcIlxuICAgICAgICAoY2xpY2spPVwidG9nZ2xlTXV0ZSgpXCJcbiAgICAgICAgW3RpdGxlXT1cImlzTXV0ZWQgPyAnQWN0aXZhciBtaWNyw7Nmb25vJyA6ICdTaWxlbmNpYXIgbWljcsOzZm9ubydcIlxuICAgICAgPlxuICAgICAgICA8aVxuICAgICAgICAgIGNsYXNzPVwiZmFcIlxuICAgICAgICAgIFtjbGFzcy5mYS1taWNyb3Bob25lXT1cIiFpc011dGVkXCJcbiAgICAgICAgICBbY2xhc3MuZmEtbWljcm9waG9uZS1zbGFzaF09XCJpc011dGVkXCJcbiAgICAgICAgPjwvaT5cbiAgICAgIDwvYnV0dG9uPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBjbGFzcz1cImFjdGlvbi1idG4gaGFuZ3VwLWJ0blwiXG4gICAgICAgIChjbGljayk9XCJvbkhhbmdVcCgpXCJcbiAgICAgICAgdGl0bGU9XCJDb2xnYXIgbGxhbWFkYVwiXG4gICAgICA+XG4gICAgICAgIDxpIGNsYXNzPVwiZmEgZmEtcGhvbmVcIiBzdHlsZT1cInRyYW5zZm9ybTogcm90YXRlKDEzNWRlZylcIj48L2k+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==