tas-uell-sdk 0.0.5 → 0.1.0
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 +161 -51
- package/esm2020/lib/components/tas-avatar/tas-avatar.component.mjs +75 -0
- package/esm2020/lib/components/tas-btn/tas-btn.component.mjs +146 -61
- package/esm2020/lib/components/tas-floating-call/tas-floating-call.component.mjs +48 -23
- package/esm2020/lib/components/tas-incoming-appointment/tas-incoming-appointment.component.mjs +109 -0
- package/esm2020/lib/components/tas-videocall/tas-videocall.component.mjs +217 -20
- package/esm2020/lib/components/tas-waiting-room/tas-waiting-room.component.mjs +226 -160
- package/esm2020/lib/config/tas.config.mjs +1 -1
- package/esm2020/lib/interfaces/tas.interfaces.mjs +45 -2
- package/esm2020/lib/services/geolocation.service.mjs +56 -0
- package/esm2020/lib/services/tas.service.mjs +400 -34
- package/esm2020/lib/tas-uell-sdk.module.mjs +25 -21
- package/esm2020/public-api.mjs +4 -1
- package/fesm2015/tas-uell-sdk.mjs +1323 -302
- package/fesm2015/tas-uell-sdk.mjs.map +1 -1
- package/fesm2020/tas-uell-sdk.mjs +1307 -300
- package/fesm2020/tas-uell-sdk.mjs.map +1 -1
- package/lib/components/tas-avatar/tas-avatar.component.d.ts +9 -0
- package/lib/components/tas-btn/tas-btn.component.d.ts +35 -15
- package/lib/components/tas-floating-call/tas-floating-call.component.d.ts +5 -1
- package/lib/components/tas-incoming-appointment/tas-incoming-appointment.component.d.ts +33 -0
- package/lib/components/tas-videocall/tas-videocall.component.d.ts +49 -3
- package/lib/components/tas-waiting-room/tas-waiting-room.component.d.ts +50 -35
- package/lib/config/tas.config.d.ts +7 -0
- package/lib/interfaces/tas.interfaces.d.ts +127 -35
- package/lib/services/geolocation.service.d.ts +24 -0
- package/lib/services/tas.service.d.ts +98 -9
- package/lib/tas-uell-sdk.module.d.ts +6 -3
- package/package.json +1 -1
- package/public-api.d.ts +3 -0
- package/src/lib/styles/tas-global.scss +27 -28
- package/INSTALL_AND_TEST.md +0 -427
package/esm2020/lib/components/tas-incoming-appointment/tas-incoming-appointment.component.mjs
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter, } from '@angular/core';
|
|
2
|
+
import { Subscription } from 'rxjs';
|
|
3
|
+
import { AppointmentStatus, TasRoomType, TasBusinessRole, } from '../../interfaces/tas.interfaces';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import * as i1 from "../../services/tas.service";
|
|
6
|
+
import * as i2 from "../tas-avatar/tas-avatar.component";
|
|
7
|
+
import * as i3 from "../tas-btn/tas-btn.component";
|
|
8
|
+
import * as i4 from "@angular/common";
|
|
9
|
+
export class TasIncomingAppointmentComponent {
|
|
10
|
+
constructor(tasService) {
|
|
11
|
+
this.tasService = tasService;
|
|
12
|
+
// Passthrough inputs for tas-btn
|
|
13
|
+
this.roomType = TasRoomType.TAS;
|
|
14
|
+
this.businessRole = TasBusinessRole.USER;
|
|
15
|
+
this.enterCall = new EventEmitter();
|
|
16
|
+
this.appointment = null;
|
|
17
|
+
this.isLoading = true;
|
|
18
|
+
this.hasError = false;
|
|
19
|
+
this.subscriptions = new Subscription();
|
|
20
|
+
}
|
|
21
|
+
ngOnInit() {
|
|
22
|
+
this.loadAppointments();
|
|
23
|
+
}
|
|
24
|
+
ngOnDestroy() {
|
|
25
|
+
this.subscriptions.unsubscribe();
|
|
26
|
+
}
|
|
27
|
+
loadAppointments() {
|
|
28
|
+
const today = new Date();
|
|
29
|
+
const in7Days = new Date(today);
|
|
30
|
+
in7Days.setDate(today.getDate() + 7);
|
|
31
|
+
this.subscriptions.add(this.tasService
|
|
32
|
+
.getAppointments({ fromDate: this.formatDate(today), toDate: this.formatDate(in7Days) })
|
|
33
|
+
.subscribe({
|
|
34
|
+
next: (response) => {
|
|
35
|
+
// Handle both array response and wrapped response (e.g., { content: [...] })
|
|
36
|
+
const appointments = Array.isArray(response)
|
|
37
|
+
? response
|
|
38
|
+
: response?.content || [];
|
|
39
|
+
// Filter for confirmed appointments and get the first one
|
|
40
|
+
const confirmed = appointments.filter((a) => a.status === AppointmentStatus.CONFIRMED);
|
|
41
|
+
this.appointment = confirmed.length > 0 ? confirmed[0] : null;
|
|
42
|
+
this.isLoading = false;
|
|
43
|
+
},
|
|
44
|
+
error: () => {
|
|
45
|
+
this.hasError = true;
|
|
46
|
+
this.isLoading = false;
|
|
47
|
+
},
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
50
|
+
onEnterCall() {
|
|
51
|
+
if (this.appointment) {
|
|
52
|
+
this.enterCall.emit(this.appointment);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Format date to Spanish format: "Lunes 8 de diciembre"
|
|
57
|
+
*/
|
|
58
|
+
get formattedDate() {
|
|
59
|
+
if (!this.appointment)
|
|
60
|
+
return '';
|
|
61
|
+
const [year, month, day] = this.appointment.date.split('-').map(Number);
|
|
62
|
+
const date = new Date(year, month - 1, day);
|
|
63
|
+
const dayNames = [
|
|
64
|
+
'Domingo', 'Lunes', 'Martes', 'Miércoles',
|
|
65
|
+
'Jueves', 'Viernes', 'Sábado'
|
|
66
|
+
];
|
|
67
|
+
const monthNames = [
|
|
68
|
+
'enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio',
|
|
69
|
+
'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'
|
|
70
|
+
];
|
|
71
|
+
const dayName = dayNames[date.getDay()];
|
|
72
|
+
const dayNum = date.getDate();
|
|
73
|
+
const monthName = monthNames[date.getMonth()];
|
|
74
|
+
return `${dayName} ${dayNum} de ${monthName}`;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Format time range: "9:00 - 9:30"
|
|
78
|
+
*/
|
|
79
|
+
get formattedTimeRange() {
|
|
80
|
+
if (!this.appointment)
|
|
81
|
+
return '';
|
|
82
|
+
return `${this.appointment.startTime} - ${this.appointment.endTime}`;
|
|
83
|
+
}
|
|
84
|
+
formatDate(date) {
|
|
85
|
+
const year = date.getFullYear();
|
|
86
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
87
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
88
|
+
return `${year}-${month}-${day}`;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
TasIncomingAppointmentComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: TasIncomingAppointmentComponent, deps: [{ token: i1.TasService }], target: i0.ɵɵFactoryTarget.Component });
|
|
92
|
+
TasIncomingAppointmentComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.12", type: TasIncomingAppointmentComponent, selector: "tas-incoming-appointment", inputs: { roomType: "roomType", entityId: "entityId", tenant: "tenant", businessRole: "businessRole", currentUser: "currentUser" }, outputs: { enterCall: "enterCall" }, ngImport: i0, template: "<div class=\"incoming-appointment-card\">\n <h3 class=\"card-title\">Pr\u00F3ximo turno</h3>\n\n <!-- Loading state -->\n <div class=\"card-content\" *ngIf=\"isLoading\">\n <div class=\"loading-spinner\"></div>\n </div>\n\n <!-- Empty state -->\n <div class=\"card-content empty-state\" *ngIf=\"!isLoading && !appointment\">\n <div class=\"icon-container\">\n <div class=\"icon-circle\">\n <i class=\"fa fa-calendar\" aria-hidden=\"true\"></i>\n </div>\n <span class=\"sparkle sparkle-1\">\u2726</span>\n <span class=\"sparkle sparkle-2\">\u2726</span>\n <span class=\"sparkle sparkle-3\">\u2726</span>\n <span class=\"sparkle sparkle-4\">\u2726</span>\n </div>\n <h4 class=\"empty-title\">Todav\u00EDa no ten\u00E9s turnos agendados</h4>\n <p class=\"empty-subtitle\">\n En caso de que Medicina Laboral requiera una consulta, lo ver\u00E1s en esta secci\u00F3n.\n </p>\n </div>\n\n <!-- Appointment state -->\n <div class=\"card-content appointment-state\" *ngIf=\"!isLoading && appointment\">\n \n <div class=\"appointment-card\">\n <div class=\"appointment-header\">\n <tas-avatar [name]=\"appointment.title\" [size]=\"48\"></tas-avatar>\n \n <span class=\"doctor-name\">{{ appointment.title }}</span>\n </div>\n <div class=\"appointment-details\">\n <div class=\"date-time\">\n <span class=\"date\">{{ formattedDate }}</span>\n <span class=\"time\">{{ formattedTimeRange }}</span>\n </div>\n <tas-btn\n variant=\"teal\"\n buttonLabel=\"Ingresar\"\n [roomType]=\"roomType\"\n [entityId]=\"entityId\"\n [tenant]=\"tenant\"\n [businessRole]=\"businessRole\"\n [currentUser]=\"currentUser\"\n ></tas-btn>\n </div>\n </div>\n </div>\n</div>\n", styles: [":host{display:block}.incoming-appointment-card{background:#ffffff;border-radius:12px;box-shadow:0 2px 8px #00000014;padding:24px;min-width:360px}.card-title{font-size:16px;font-weight:400;color:#6b7280;margin:0 0 24px}.card-content{display:flex;flex-direction:column;align-items:center}.loading-spinner{width:40px;height:40px;border:3px solid #e0f7fa;border-top-color:#0097a7;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.empty-state{text-align:center;padding:20px 0}.icon-container{position:relative;width:120px;height:120px;margin-bottom:24px}.icon-circle{width:100%;height:100%;background:#e0f7fa;border-radius:50%;display:flex;align-items:center;justify-content:center}.icon-circle i{font-size:40px;color:#0097a7}.sparkle{position:absolute;color:#0097a7;font-size:12px}.sparkle-1{top:10px;right:5px}.sparkle-2{top:0;right:30px}.sparkle-3{top:25px;left:0}.sparkle-4{bottom:20px;right:0}.empty-title{font-size:18px;font-weight:600;color:#1f2937;margin:0 0 12px}.empty-subtitle{font-size:14px;color:#6b7280;margin:0;max-width:320px;line-height:1.5}.appointment-state{align-items:stretch}.appointment-card{border-radius:12px;border:1px solid var(--Primary-White-Uell50, #8ED1D8);background:#F1FAFA;padding:1.5rem}.appointment-header{display:flex;align-items:center;gap:12px;margin-bottom:16px}.doctor-name{overflow:hidden;color:var(--Neutral-GreyDark, #383E52);text-overflow:ellipsis;font-size:16px;font-style:normal;font-weight:600;line-height:24px;letter-spacing:.016px}.appointment-details{display:flex;justify-content:space-between;align-items:flex-end}.date-time{display:flex;flex-direction:column;gap:4px}.date{color:var(--Neutral-GreyDark, #383E52);font-size:12px;font-style:normal;font-weight:600;line-height:16px;letter-spacing:.06px}.time{font-size:14px;color:var(--Neutral-GreyDark, #383E52);font-family:Inter;font-size:10px;font-style:normal;font-weight:400;line-height:14px;letter-spacing:.04px}\n"], components: [{ type: i2.TasAvatarComponent, selector: "tas-avatar", inputs: ["name", "size"] }, { type: i3.TasButtonComponent, selector: "tas-btn", inputs: ["roomType", "entityId", "tenant", "businessRole", "currentUser", "variant", "buttonLabel"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
93
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: TasIncomingAppointmentComponent, decorators: [{
|
|
94
|
+
type: Component,
|
|
95
|
+
args: [{ selector: 'tas-incoming-appointment', template: "<div class=\"incoming-appointment-card\">\n <h3 class=\"card-title\">Pr\u00F3ximo turno</h3>\n\n <!-- Loading state -->\n <div class=\"card-content\" *ngIf=\"isLoading\">\n <div class=\"loading-spinner\"></div>\n </div>\n\n <!-- Empty state -->\n <div class=\"card-content empty-state\" *ngIf=\"!isLoading && !appointment\">\n <div class=\"icon-container\">\n <div class=\"icon-circle\">\n <i class=\"fa fa-calendar\" aria-hidden=\"true\"></i>\n </div>\n <span class=\"sparkle sparkle-1\">\u2726</span>\n <span class=\"sparkle sparkle-2\">\u2726</span>\n <span class=\"sparkle sparkle-3\">\u2726</span>\n <span class=\"sparkle sparkle-4\">\u2726</span>\n </div>\n <h4 class=\"empty-title\">Todav\u00EDa no ten\u00E9s turnos agendados</h4>\n <p class=\"empty-subtitle\">\n En caso de que Medicina Laboral requiera una consulta, lo ver\u00E1s en esta secci\u00F3n.\n </p>\n </div>\n\n <!-- Appointment state -->\n <div class=\"card-content appointment-state\" *ngIf=\"!isLoading && appointment\">\n \n <div class=\"appointment-card\">\n <div class=\"appointment-header\">\n <tas-avatar [name]=\"appointment.title\" [size]=\"48\"></tas-avatar>\n \n <span class=\"doctor-name\">{{ appointment.title }}</span>\n </div>\n <div class=\"appointment-details\">\n <div class=\"date-time\">\n <span class=\"date\">{{ formattedDate }}</span>\n <span class=\"time\">{{ formattedTimeRange }}</span>\n </div>\n <tas-btn\n variant=\"teal\"\n buttonLabel=\"Ingresar\"\n [roomType]=\"roomType\"\n [entityId]=\"entityId\"\n [tenant]=\"tenant\"\n [businessRole]=\"businessRole\"\n [currentUser]=\"currentUser\"\n ></tas-btn>\n </div>\n </div>\n </div>\n</div>\n", styles: [":host{display:block}.incoming-appointment-card{background:#ffffff;border-radius:12px;box-shadow:0 2px 8px #00000014;padding:24px;min-width:360px}.card-title{font-size:16px;font-weight:400;color:#6b7280;margin:0 0 24px}.card-content{display:flex;flex-direction:column;align-items:center}.loading-spinner{width:40px;height:40px;border:3px solid #e0f7fa;border-top-color:#0097a7;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.empty-state{text-align:center;padding:20px 0}.icon-container{position:relative;width:120px;height:120px;margin-bottom:24px}.icon-circle{width:100%;height:100%;background:#e0f7fa;border-radius:50%;display:flex;align-items:center;justify-content:center}.icon-circle i{font-size:40px;color:#0097a7}.sparkle{position:absolute;color:#0097a7;font-size:12px}.sparkle-1{top:10px;right:5px}.sparkle-2{top:0;right:30px}.sparkle-3{top:25px;left:0}.sparkle-4{bottom:20px;right:0}.empty-title{font-size:18px;font-weight:600;color:#1f2937;margin:0 0 12px}.empty-subtitle{font-size:14px;color:#6b7280;margin:0;max-width:320px;line-height:1.5}.appointment-state{align-items:stretch}.appointment-card{border-radius:12px;border:1px solid var(--Primary-White-Uell50, #8ED1D8);background:#F1FAFA;padding:1.5rem}.appointment-header{display:flex;align-items:center;gap:12px;margin-bottom:16px}.doctor-name{overflow:hidden;color:var(--Neutral-GreyDark, #383E52);text-overflow:ellipsis;font-size:16px;font-style:normal;font-weight:600;line-height:24px;letter-spacing:.016px}.appointment-details{display:flex;justify-content:space-between;align-items:flex-end}.date-time{display:flex;flex-direction:column;gap:4px}.date{color:var(--Neutral-GreyDark, #383E52);font-size:12px;font-style:normal;font-weight:600;line-height:16px;letter-spacing:.06px}.time{font-size:14px;color:var(--Neutral-GreyDark, #383E52);font-family:Inter;font-size:10px;font-style:normal;font-weight:400;line-height:14px;letter-spacing:.04px}\n"] }]
|
|
96
|
+
}], ctorParameters: function () { return [{ type: i1.TasService }]; }, propDecorators: { roomType: [{
|
|
97
|
+
type: Input
|
|
98
|
+
}], entityId: [{
|
|
99
|
+
type: Input
|
|
100
|
+
}], tenant: [{
|
|
101
|
+
type: Input
|
|
102
|
+
}], businessRole: [{
|
|
103
|
+
type: Input
|
|
104
|
+
}], currentUser: [{
|
|
105
|
+
type: Input
|
|
106
|
+
}], enterCall: [{
|
|
107
|
+
type: Output
|
|
108
|
+
}] } });
|
|
109
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFzLWluY29taW5nLWFwcG9pbnRtZW50LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3Rhcy11ZWxsLXNkay9zcmMvbGliL2NvbXBvbmVudHMvdGFzLWluY29taW5nLWFwcG9pbnRtZW50L3Rhcy1pbmNvbWluZy1hcHBvaW50bWVudC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy90YXMtdWVsbC1zZGsvc3JjL2xpYi9jb21wb25lbnRzL3Rhcy1pbmNvbWluZy1hcHBvaW50bWVudC90YXMtaW5jb21pbmctYXBwb2ludG1lbnQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFHVCxLQUFLLEVBQ0wsTUFBTSxFQUNOLFlBQVksR0FDYixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXBDLE9BQU8sRUFFTCxpQkFBaUIsRUFDakIsV0FBVyxFQUNYLGVBQWUsR0FFaEIsTUFBTSxpQ0FBaUMsQ0FBQzs7Ozs7O0FBT3pDLE1BQU0sT0FBTywrQkFBK0I7SUFnQjFDLFlBQW9CLFVBQXNCO1FBQXRCLGVBQVUsR0FBVixVQUFVLENBQVk7UUFmMUMsaUNBQWlDO1FBQ3hCLGFBQVEsR0FBZ0IsV0FBVyxDQUFDLEdBQUcsQ0FBQztRQUd4QyxpQkFBWSxHQUFvQixlQUFlLENBQUMsSUFBSSxDQUFDO1FBR3BELGNBQVMsR0FBRyxJQUFJLFlBQVksRUFBa0IsQ0FBQztRQUVsRCxnQkFBVyxHQUEwQixJQUFJLENBQUM7UUFDMUMsY0FBUyxHQUFHLElBQUksQ0FBQztRQUNqQixhQUFRLEdBQUcsS0FBSyxDQUFDO1FBRWhCLGtCQUFhLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztJQUVFLENBQUM7SUFFOUMsUUFBUTtRQUNOLElBQUksQ0FBQyxnQkFBZ0IsRUFB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ICBPbkRlc3Ryb3ksXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIEV2ZW50RW1pdHRlcixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFRhc1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy90YXMuc2VydmljZSc7XG5pbXBvcnQge1xuICBUYXNBcHBvaW50bWVudCxcbiAgQXBwb2ludG1lbnRTdGF0dXMsXG4gIFRhc1Jvb21UeXBlLFxuICBUYXNCdXNpbmVzc1JvbGUsXG4gIFRhc0N1cnJlbnRVc2VyLFxufSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL3Rhcy5pbnRlcmZhY2VzJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndGFzLWluY29taW5nLWFwcG9pbnRtZW50JyxcbiAgdGVtcGxhdGVVcmw6ICcuL3Rhcy1pbmNvbWluZy1hcHBvaW50bWVudC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3Rhcy1pbmNvbWluZy1hcHBvaW50bWVudC5jb21wb25lbnQuc2NzcyddLFxufSlcbmV4cG9ydCBjbGFzcyBUYXNJbmNvbWluZ0FwcG9pbnRtZW50Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICAvLyBQYXNzdGhyb3VnaCBpbnB1dHMgZm9yIHRhcy1idG5cbiAgQElucHV0KCkgcm9vbVR5cGU6IFRhc1Jvb21UeXBlID0gVGFzUm9vbVR5cGUuVEFTO1xuICBASW5wdXQoKSBlbnRpdHlJZCE6IG51bWJlcjtcbiAgQElucHV0KCkgdGVuYW50ITogc3RyaW5nO1xuICBASW5wdXQoKSBidXNpbmVzc1JvbGU6IFRhc0J1c2luZXNzUm9sZSA9IFRhc0J1c2luZXNzUm9sZS5VU0VSO1xuICBASW5wdXQoKSBjdXJyZW50VXNlciE6IFRhc0N1cnJlbnRVc2VyO1xuXG4gIEBPdXRwdXQoKSBlbnRlckNhbGwgPSBuZXcgRXZlbnRFbWl0dGVyPFRhc0FwcG9pbnRtZW50PigpO1xuXG4gIHB1YmxpYyBhcHBvaW50bWVudDogVGFzQXBwb2ludG1lbnQgfCBudWxsID0gbnVsbDtcbiAgcHVibGljIGlzTG9hZGluZyA9IHRydWU7XG4gIHB1YmxpYyBoYXNFcnJvciA9IGZhbHNlO1xuXG4gIHByaXZhdGUgc3Vic2NyaXB0aW9ucyA9IG5ldyBTdWJzY3JpcHRpb24oKTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHRhc1NlcnZpY2U6IFRhc1NlcnZpY2UpIHt9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5sb2FkQXBwb2ludG1lbnRzKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMudW5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIHByaXZhdGUgbG9hZEFwcG9pbnRtZW50cygpOiB2b2lkIHtcbiAgICBjb25zdCB0b2RheSA9IG5ldyBEYXRlKCk7XG4gICAgY29uc3QgaW43RGF5cyA9IG5ldyBEYXRlKHRvZGF5KTtcbiAgICBpbjdEYXlzLnNldERhdGUodG9kYXkuZ2V0RGF0ZSgpICsgNyk7XG5cbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKFxuICAgICAgdGhpcy50YXNTZXJ2aWNlXG4gICAgICAgIC5nZXRBcHBvaW50bWVudHMoeyBmcm9tRGF0ZTogdGhpcy5mb3JtYXREYXRlKHRvZGF5KSwgdG9EYXRlOiB0aGlzLmZvcm1hdERhdGUoaW43RGF5cykgfSlcbiAgICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgICAgbmV4dDogKHJlc3BvbnNlOiBhbnkpID0+IHtcbiAgICAgICAgICAgIC8vIEhhbmRsZSBib3RoIGFycmF5IHJlc3BvbnNlIGFuZCB3cmFwcGVkIHJlc3BvbnNlIChlLmcuLCB7IGNvbnRlbnQ6IFsuLi5dIH0pXG4gICAgICAgICAgICBjb25zdCBhcHBvaW50bWVudHM6IFRhc0FwcG9pbnRtZW50W10gPSBBcnJheS5pc0FycmF5KHJlc3BvbnNlKVxuICAgICAgICAgICAgICA/IHJlc3BvbnNlXG4gICAgICAgICAgICAgIDogcmVzcG9uc2U/LmNvbnRlbnQgfHwgW107XG5cbiAgICAgICAgICAgIC8vIEZpbHRlciBmb3IgY29uZmlybWVkIGFwcG9pbnRtZW50cyBhbmQgZ2V0IHRoZSBmaXJzdCBvbmVcbiAgICAgICAgICAgIGNvbnN0IGNvbmZpcm1lZCA9IGFwcG9pbnRtZW50cy5maWx0ZXIoXG4gICAgICAgICAgICAgIChhKSA9PiBhLnN0YXR1cyA9PT0gQXBwb2ludG1lbnRTdGF0dXMuQ09ORklSTUVEXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5hcHBvaW50bWVudCA9IGNvbmZpcm1lZC5sZW5ndGggPiAwID8gY29uZmlybWVkWzBdIDogbnVsbDtcbiAgICAgICAgICAgIHRoaXMuaXNMb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5oYXNFcnJvciA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLmlzTG9hZGluZyA9IGZhbHNlO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBvbkVudGVyQ2FsbCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5hcHBvaW50bWVudCkge1xuICAgICAgdGhpcy5lbnRlckNhbGwuZW1pdCh0aGlzLmFwcG9pbnRtZW50KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRm9ybWF0IGRhdGUgdG8gU3BhbmlzaCBmb3JtYXQ6IFwiTHVuZXMgOCBkZSBkaWNpZW1icmVcIlxuICAgKi9cbiAgcHVibGljIGdldCBmb3JtYXR0ZWREYXRlKCk6IHN0cmluZyB7XG4gICAgaWYgKCF0aGlzLmFwcG9pbnRtZW50KSByZXR1cm4gJyc7XG5cbiAgICBjb25zdCBbeWVhciwgbW9udGgsIGRheV0gPSB0aGlzLmFwcG9pbnRtZW50LmRhdGUuc3BsaXQoJy0nKS5tYXAoTnVtYmVyKTtcbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoeWVhciwgbW9udGggLSAxLCBkYXkpO1xuXG4gICAgY29uc3QgZGF5TmFtZXMgPSBbXG4gICAgICAnRG9taW5nbycsICdMdW5lcycsICdNYXJ0ZXMnLCAnTWnDqXJjb2xlcycsXG4gICAgICAnSnVldmVzJywgJ1ZpZXJuZXMnLCAnU8OhYmFkbydcbiAgICBdO1xuICAgIGNvbnN0IG1vbnRoTmFtZXMgPSBbXG4gICAgICAnZW5lcm8nLCAnZmVicmVybycsICdtYXJ6bycsICdhYnJpbCcsICdtYXlvJywgJ2p1bmlvJyxcbiAgICAgICdqdWxpbycsICdhZ29zdG8nLCAnc2VwdGllbWJyZScsICdvY3R1YnJlJywgJ25vdmllbWJyZScsICdkaWNpZW1icmUnXG4gICAgXTtcblxuICAgIGNvbnN0IGRheU5hbWUgPSBkYXlOYW1lc1tkYXRlLmdldERheSgpXTtcbiAgICBjb25zdCBkYXlOdW0gPSBkYXRlLmdldERhdGUoKTtcbiAgICBjb25zdCBtb250aE5hbWUgPSBtb250aE5hbWVzW2RhdGUuZ2V0TW9udGgoKV07XG5cbiAgICByZXR1cm4gYCR7ZGF5TmFtZX0gJHtkYXlOdW19IGRlICR7bW9udGhOYW1lfWA7XG4gIH1cblxuICAvKipcbiAgICogRm9ybWF0IHRpbWUgcmFuZ2U6IFwiOTowMCAtIDk6MzBcIlxuICAgKi9cbiAgcHVibGljIGdldCBmb3JtYXR0ZWRUaW1lUmFuZ2UoKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMuYXBwb2ludG1lbnQpIHJldHVybiAnJztcbiAgICByZXR1cm4gYCR7dGhpcy5hcHBvaW50bWVudC5zdGFydFRpbWV9IC0gJHt0aGlzLmFwcG9pbnRtZW50LmVuZFRpbWV9YDtcbiAgfVxuXG4gIHByaXZhdGUgZm9ybWF0RGF0ZShkYXRlOiBEYXRlKTogc3RyaW5nIHtcbiAgICBjb25zdCB5ZWFyID0gZGF0ZS5nZXRGdWxsWWVhcigpO1xuICAgIGNvbnN0IG1vbnRoID0gU3RyaW5nKGRhdGUuZ2V0TW9udGgoKSArIDEpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgY29uc3QgZGF5ID0gU3RyaW5nKGRhdGUuZ2V0RGF0ZSgpKS5wYWRTdGFydCgyLCAnMCcpO1xuICAgIHJldHVybiBgJHt5ZWFyfS0ke21vbnRofS0ke2RheX1gO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiaW5jb21pbmctYXBwb2ludG1lbnQtY2FyZFwiPlxuICA8aDMgY2xhc3M9XCJjYXJkLXRpdGxlXCI+UHLDs3hpbW8gdHVybm88L2gzPlxuXG4gIDwhLS0gTG9hZGluZyBzdGF0ZSAtLT5cbiAgPGRpdiBjbGFzcz1cImNhcmQtY29udGVudFwiICpuZ0lmPVwiaXNMb2FkaW5nXCI+XG4gICAgPGRpdiBjbGFzcz1cImxvYWRpbmctc3Bpbm5lclwiPjwvZGl2PlxuICA8L2Rpdj5cblxuICA8IS0tIEVtcHR5IHN0YXRlIC0tPlxuICA8ZGl2IGNsYXNzPVwiY2FyZC1jb250ZW50IGVtcHR5LXN0YXRlXCIgKm5nSWY9XCIhaXNMb2FkaW5nICYmICFhcHBvaW50bWVudFwiPlxuICAgIDxkaXYgY2xhc3M9XCJpY29uLWNvbnRhaW5lclwiPlxuICAgICAgPGRpdiBjbGFzcz1cImljb24tY2lyY2xlXCI+XG4gICAgICAgIDxpIGNsYXNzPVwiZmEgZmEtY2FsZW5kYXJcIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic3BhcmtsZSBzcGFya2xlLTFcIj7inKY8L3NwYW4+XG4gICAgICA8c3BhbiBjbGFzcz1cInNwYXJrbGUgc3BhcmtsZS0yXCI+4pymPC9zcGFuPlxuICAgICAgPHNwYW4gY2xhc3M9XCJzcGFya2xlIHNwYXJrbGUtM1wiPuKcpjwvc3Bhbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic3BhcmtsZSBzcGFya2xlLTRcIj7inKY8L3NwYW4+XG4gICAgPC9kaXY+XG4gICAgPGg0IGNsYXNzPVwiZW1wdHktdGl0bGVcIj5Ub2RhdsOtYSBubyB0ZW7DqXMgdHVybm9zIGFnZW5kYWRvczwvaDQ+XG4gICAgPHAgY2xhc3M9XCJlbXB0eS1zdWJ0aXRsZVwiPlxuICAgICAgRW4gY2FzbyBkZSBxdWUgTWVkaWNpbmEgTGFib3JhbCByZXF1aWVyYSB1bmEgY29uc3VsdGEsIGxvIHZlcsOhcyBlbiBlc3RhIHNlY2Npw7NuLlxuICAgIDwvcD5cbiAgPC9kaXY+XG5cbiAgPCEtLSBBcHBvaW50bWVudCBzdGF0ZSAtLT5cbiAgPGRpdiBjbGFzcz1cImNhcmQtY29udGVudCBhcHBvaW50bWVudC1zdGF0ZVwiICpuZ0lmPVwiIWlzTG9hZGluZyAmJiBhcHBvaW50bWVudFwiPlxuICAgIFxuICAgIDxkaXYgY2xhc3M9XCJhcHBvaW50bWVudC1jYXJkXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiYXBwb2ludG1lbnQtaGVhZGVyXCI+XG4gICAgICAgIDx0YXMtYXZhdGFyIFtuYW1lXT1cImFwcG9pbnRtZW50LnRpdGxlXCIgW3NpemVdPVwiNDhcIj48L3Rhcy1hdmF0YXI+XG4gICAgICAgIFxuICAgICAgICA8c3BhbiBjbGFzcz1cImRvY3Rvci1uYW1lXCI+e3sgYXBwb2ludG1lbnQudGl0bGUgfX08L3NwYW4+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJhcHBvaW50bWVudC1kZXRhaWxzXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkYXRlLXRpbWVcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImRhdGVcIj57eyBmb3JtYXR0ZWREYXRlIH19PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGltZVwiPnt7IGZvcm1hdHRlZFRpbWVSYW5nZSB9fTwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDx0YXMtYnRuXG4gICAgICAgICAgdmFyaWFudD1cInRlYWxcIlxuICAgICAgICAgIGJ1dHRvbkxhYmVsPVwiSW5ncmVzYXJcIlxuICAgICAgICAgIFtyb29tVHlwZV09XCJyb29tVHlwZVwiXG4gICAgICAgICAgW2VudGl0eUlkXT1cImVudGl0eUlkXCJcbiAgICAgICAgICBbdGVuYW50XT1cInRlbmFudFwiXG4gICAgICAgICAgW2J1c2luZXNzUm9sZV09XCJidXNpbmVzc1JvbGVcIlxuICAgICAgICAgIFtjdXJyZW50VXNlcl09XCJjdXJyZW50VXNlclwiXG4gICAgICAgID48L3Rhcy1idG4+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==
|