valtech-components 4.0.937 → 4.0.939
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/esm2022/lib/components/molecules/group-picker/group-picker.component.mjs +97 -0
- package/esm2022/lib/components/organisms/group-members/group-members.component.mjs +178 -0
- package/esm2022/lib/components/organisms/mini-games/mini-games.i18n.mjs +1 -381
- package/esm2022/lib/components/organisms/mini-games/types.mjs +1 -1
- package/esm2022/lib/services/groups/groups.service.mjs +92 -0
- package/esm2022/lib/services/groups/types.mjs +2 -0
- package/esm2022/lib/version.mjs +2 -2
- package/esm2022/public-api.mjs +4 -3
- package/fesm2022/valtech-components.mjs +641 -7612
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/molecules/group-picker/group-picker.component.d.ts +28 -0
- package/lib/components/organisms/group-members/group-members.component.d.ts +43 -0
- package/lib/components/organisms/mini-games/types.d.ts +0 -182
- package/lib/services/groups/groups.service.d.ts +39 -0
- package/lib/services/groups/types.d.ts +69 -0
- package/lib/version.d.ts +1 -1
- package/package.json +1 -1
- package/public-api.d.ts +4 -2
- package/src/lib/assets/games/README.md +8 -0
- package/esm2022/lib/components/organisms/mini-games/christianity-bot.mjs +0 -94
- package/esm2022/lib/components/organisms/mini-games/christianity-card.component.mjs +0 -503
- package/esm2022/lib/components/organisms/mini-games/christianity-catalog.mjs +0 -247
- package/esm2022/lib/components/organisms/mini-games/christianity-game.component.mjs +0 -4580
- package/esm2022/lib/components/organisms/mini-games/christianity-rules.mjs +0 -1383
- package/esm2022/lib/components/organisms/mini-games/christianity-tutorial.mjs +0 -152
- package/lib/components/organisms/mini-games/christianity-bot.d.ts +0 -15
- package/lib/components/organisms/mini-games/christianity-card.component.d.ts +0 -55
- package/lib/components/organisms/mini-games/christianity-catalog.d.ts +0 -18
- package/lib/components/organisms/mini-games/christianity-game.component.d.ts +0 -395
- package/lib/components/organisms/mini-games/christianity-rules.d.ts +0 -57
- package/lib/components/organisms/mini-games/christianity-tutorial.d.ts +0 -38
- package/src/lib/assets/games/christianity/card-symbol.svg +0 -51
- package/src/lib/assets/games/christianity/card-template-reference/front.html +0 -114
- package/src/lib/assets/games/christianity/card-template-reference/front.style.css +0 -352
- package/src/lib/assets/games/christianity/data/01-genesis.bible-reference-suggestions.csv +0 -191
- package/src/lib/assets/games/christianity/data/01-genesis.bible-verses.nbv-open.csv +0 -170
- package/src/lib/assets/games/christianity/data/01-genesis.cards.csv +0 -281
- package/src/lib/assets/games/christianity/data/01-genesis.cards.i18n.csv +0 -281
- package/src/lib/assets/games/christianity/data/01-genesis.cards.json +0 -16453
- package/src/lib/assets/games/christianity/data/01-genesis.unassigned-effects.csv +0 -49
- package/src/lib/assets/games/christianity/data/README.md +0 -40
- package/src/lib/assets/games/christianity/data/data-con-habilides.csv +0 -273
- package/src/lib/assets/games/christianity/data/habilidades-por-tipo.xlsx +0 -0
- package/src/lib/assets/games/christianity/data/listado-edicion.csv +0 -281
- package/src/lib/assets/games/christianity/editions/1/cards/.gitkeep +0 -1
- package/src/lib/assets/games/christianity/editions/1/cards/PLACEHOLDER.png +0 -0
- package/src/lib/assets/games/christianity/editions/README.md +0 -34
- package/src/lib/assets/games/christianity/icons/1-icon.png +0 -0
- package/src/lib/assets/games/christianity/icons/action.png +0 -0
- package/src/lib/assets/games/christianity/icons/character.png +0 -0
- package/src/lib/assets/games/christianity/icons/event.png +0 -0
- package/src/lib/assets/games/christianity/icons/leader.png +0 -0
- package/src/lib/assets/games/christianity/icons/offering.png +0 -0
- package/src/lib/assets/games/christianity/icons/place.png +0 -0
- package/src/lib/assets/games/christianity/icons/tool.png +0 -0
- package/src/lib/assets/games/christianity/icons/wisdom.png +0 -0
- package/src/lib/assets/games/christianity/sources/README.md +0 -16
- package/src/lib/assets/games/christianity/sources/spaonbv_vpl.txt +0 -29102
- package/src/lib/assets/games/christianity/sources/spaonbv_vpl.xml +0 -29104
- package/src/lib/assets/games/christianity/spaonbv.txt +0 -52
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { Component, EventEmitter, Input, Output, inject } from '@angular/core';
|
|
3
|
+
import { IonSelect, IonSelectOption } from '@ionic/angular/standalone';
|
|
4
|
+
import { GroupsService } from '../../../services/groups/groups.service';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
/**
|
|
7
|
+
* val-group-picker — elegir el grupo dueño de un recurso (ADR-083).
|
|
8
|
+
*
|
|
9
|
+
* Se auto-carga: pide sus propios grupos a `GroupsService` en vez de esperar
|
|
10
|
+
* que el consumer se los pase. Es la razón por la que existe como componente y
|
|
11
|
+
* no como un `<select>` armado a mano en cada app — "una línea, una etiqueta
|
|
12
|
+
* i18n" (ver ADR-083 §"Qué se construye una sola vez").
|
|
13
|
+
*
|
|
14
|
+
* Sin texto hardcodeado: los labels llegan por `@Input` (lib i18n-agnostic).
|
|
15
|
+
* Cada app pone su palabra ("Equipo", "Sucursal", "Refugio").
|
|
16
|
+
*/
|
|
17
|
+
export class GroupPickerComponent {
|
|
18
|
+
constructor() {
|
|
19
|
+
this.label = '';
|
|
20
|
+
this.placeholder = '';
|
|
21
|
+
this.noGroupLabel = '';
|
|
22
|
+
this.value = null;
|
|
23
|
+
this.disabled = false;
|
|
24
|
+
this.valueChange = new EventEmitter();
|
|
25
|
+
this.groupsSvc = inject(GroupsService);
|
|
26
|
+
this.groups = [];
|
|
27
|
+
}
|
|
28
|
+
ngOnInit() {
|
|
29
|
+
this.groupsSvc.listGroups().subscribe({
|
|
30
|
+
next: (g) => (this.groups = g),
|
|
31
|
+
// Best-effort: si la lectura falla, el picker queda con la opción "sin
|
|
32
|
+
// grupo" únicamente. No es un error bloqueante — crear el recurso sin
|
|
33
|
+
// asignar sigue siendo válido.
|
|
34
|
+
error: () => (this.groups = []),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
onChange(v) {
|
|
38
|
+
this.value = v || null;
|
|
39
|
+
this.valueChange.emit(this.value);
|
|
40
|
+
}
|
|
41
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GroupPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
42
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: GroupPickerComponent, isStandalone: true, selector: "val-group-picker", inputs: { label: "label", placeholder: "placeholder", noGroupLabel: "noGroupLabel", value: "value", disabled: "disabled" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: `
|
|
43
|
+
<ion-select
|
|
44
|
+
[label]="label"
|
|
45
|
+
[placeholder]="placeholder"
|
|
46
|
+
[value]="value ?? ''"
|
|
47
|
+
[disabled]="disabled"
|
|
48
|
+
interface="popover"
|
|
49
|
+
(ionChange)="onChange($event.detail.value)"
|
|
50
|
+
>
|
|
51
|
+
<!-- Opción vacía SIEMPRE disponible: un recurso sin grupo es visible para
|
|
52
|
+
toda la organización (ADR-083, decisión 3), no un estado inválido. -->
|
|
53
|
+
<ion-select-option value="">{{ noGroupLabel }}</ion-select-option>
|
|
54
|
+
@for (g of groups; track g.id) {
|
|
55
|
+
<ion-select-option [value]="g.id">{{ g.name }}</ion-select-option>
|
|
56
|
+
}
|
|
57
|
+
</ion-select>
|
|
58
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "errorText", "expandedIcon", "fill", "helperText", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }] }); }
|
|
59
|
+
}
|
|
60
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GroupPickerComponent, decorators: [{
|
|
61
|
+
type: Component,
|
|
62
|
+
args: [{
|
|
63
|
+
selector: 'val-group-picker',
|
|
64
|
+
standalone: true,
|
|
65
|
+
imports: [CommonModule, IonSelect, IonSelectOption],
|
|
66
|
+
template: `
|
|
67
|
+
<ion-select
|
|
68
|
+
[label]="label"
|
|
69
|
+
[placeholder]="placeholder"
|
|
70
|
+
[value]="value ?? ''"
|
|
71
|
+
[disabled]="disabled"
|
|
72
|
+
interface="popover"
|
|
73
|
+
(ionChange)="onChange($event.detail.value)"
|
|
74
|
+
>
|
|
75
|
+
<!-- Opción vacía SIEMPRE disponible: un recurso sin grupo es visible para
|
|
76
|
+
toda la organización (ADR-083, decisión 3), no un estado inválido. -->
|
|
77
|
+
<ion-select-option value="">{{ noGroupLabel }}</ion-select-option>
|
|
78
|
+
@for (g of groups; track g.id) {
|
|
79
|
+
<ion-select-option [value]="g.id">{{ g.name }}</ion-select-option>
|
|
80
|
+
}
|
|
81
|
+
</ion-select>
|
|
82
|
+
`,
|
|
83
|
+
}]
|
|
84
|
+
}], propDecorators: { label: [{
|
|
85
|
+
type: Input
|
|
86
|
+
}], placeholder: [{
|
|
87
|
+
type: Input
|
|
88
|
+
}], noGroupLabel: [{
|
|
89
|
+
type: Input
|
|
90
|
+
}], value: [{
|
|
91
|
+
type: Input
|
|
92
|
+
}], disabled: [{
|
|
93
|
+
type: Input
|
|
94
|
+
}], valueChange: [{
|
|
95
|
+
type: Output
|
|
96
|
+
}] } });
|
|
97
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JvdXAtcGlja2VyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9tb2xlY3VsZXMvZ3JvdXAtcGlja2VyL2dyb3VwLXBpY2tlci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZGLE9BQU8sRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDdkUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHlDQUF5QyxDQUFDOztBQUd4RTs7Ozs7Ozs7OztHQVVHO0FBdUJILE1BQU0sT0FBTyxvQkFBb0I7SUF0QmpDO1FBdUJXLFVBQUssR0FBRyxFQUFFLENBQUM7UUFDWCxnQkFBVyxHQUFHLEVBQUUsQ0FBQztRQUNqQixpQkFBWSxHQUFHLEVBQUUsQ0FBQztRQUNsQixVQUFLLEdBQWtCLElBQUksQ0FBQztRQUM1QixhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ2hCLGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQWlCLENBQUM7UUFFekMsY0FBUyxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNuRCxXQUFNLEdBQWUsRUFBRSxDQUFDO0tBZ0J6QjtJQWRDLFFBQVE7UUFDTixJQUFJLENBQUMsU0FBUyxDQUFDLFVBQVUsRUFBRSxDQUFDLFNBQVMsQ0FBQztZQUNwQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7WUFDOUIsdUVBQXVFO1lBQ3ZFLHNFQUFzRTtZQUN0RSwrQkFBK0I7WUFDL0IsS0FBSyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7U0FDaEMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELFFBQVEsQ0FBQyxDQUFTO1FBQ2hCLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQztRQUN2QixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDcEMsQ0FBQzsrR0F4QlUsb0JBQW9CO21HQUFwQixvQkFBb0IsaVBBbEJyQjs7Ozs7Ozs7Ozs7Ozs7OztHQWdCVCwyREFqQlMsWUFBWSwrQkFBRSxTQUFTLGtWQUFFLGVBQWU7OzRGQW1CdkMsb0JBQW9CO2tCQXRCaEMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsa0JBQWtCO29CQUM1QixVQUFVLEVBQUUsSUFBSTtvQkFDaEIsT0FBTyxFQUFFLENBQUMsWUFBWSxFQUFFLFNBQVMsRUFBRSxlQUFlLENBQUM7b0JBQ25ELFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7OztHQWdCVDtpQkFDRjs4QkFFVSxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNJLFdBQVc7c0JBQXBCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE91dHB1dCwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBJb25TZWxlY3QsIElvblNlbGVjdE9wdGlvbiB9IGZyb20gJ0Bpb25pYy9hbmd1bGFyL3N0YW5kYWxvbmUnO1xuaW1wb3J0IHsgR3JvdXBzU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2dyb3Vwcy9ncm91cHMuc2VydmljZSc7XG5pbXBvcnQgeyBWYWxHcm91cCB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2dyb3Vwcy90eXBlcyc7XG5cbi8qKlxuICogdmFsLWdyb3VwLXBpY2tlciDigJQgZWxlZ2lyIGVsIGdydXBvIGR1ZcOxbyBkZSB1biByZWN1cnNvIChBRFItMDgzKS5cbiAqXG4gKiBTZSBhdXRvLWNhcmdhOiBwaWRlIHN1cyBwcm9waW9zIGdydXBvcyBhIGBHcm91cHNTZXJ2aWNlYCBlbiB2ZXogZGUgZXNwZXJhclxuICogcXVlIGVsIGNvbnN1bWVyIHNlIGxvcyBwYXNlLiBFcyBsYSByYXrDs24gcG9yIGxhIHF1ZSBleGlzdGUgY29tbyBjb21wb25lbnRlIHlcbiAqIG5vIGNvbW8gdW4gYDxzZWxlY3Q+YCBhcm1hZG8gYSBtYW5vIGVuIGNhZGEgYXBwIOKAlCBcInVuYSBsw61uZWEsIHVuYSBldGlxdWV0YVxuICogaTE4blwiICh2ZXIgQURSLTA4MyDCp1wiUXXDqSBzZSBjb25zdHJ1eWUgdW5hIHNvbGEgdmV6XCIpLlxuICpcbiAqIFNpbiB0ZXh0byBoYXJkY29kZWFkbzogbG9zIGxhYmVscyBsbGVnYW4gcG9yIGBASW5wdXRgIChsaWIgaTE4bi1hZ25vc3RpYykuXG4gKiBDYWRhIGFwcCBwb25lIHN1IHBhbGFicmEgKFwiRXF1aXBvXCIsIFwiU3VjdXJzYWxcIiwgXCJSZWZ1Z2lvXCIpLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd2YWwtZ3JvdXAtcGlja2VyJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgSW9uU2VsZWN0LCBJb25TZWxlY3RPcHRpb25dLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxpb24tc2VsZWN0XG4gICAgICBbbGFiZWxdPVwibGFiZWxcIlxuICAgICAgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCJcbiAgICAgIFt2YWx1ZV09XCJ2YWx1ZSA/PyAnJ1wiXG4gICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgICAgaW50ZXJmYWNlPVwicG9wb3ZlclwiXG4gICAgICAoaW9uQ2hhbmdlKT1cIm9uQ2hhbmdlKCRldmVudC5kZXRhaWwudmFsdWUpXCJcbiAgICA+XG4gICAgICA8IS0tIE9wY2nDs24gdmFjw61hIFNJRU1QUkUgZGlzcG9uaWJsZTogdW4gcmVjdXJzbyBzaW4gZ3J1cG8gZXMgdmlzaWJsZSBwYXJhXG4gICAgICAgICAgIHRvZGEgbGEgb3JnYW5pemFjacOzbiAoQURSLTA4MywgZGVjaXNpw7NuIDMpLCBubyB1biBlc3RhZG8gaW52w6FsaWRvLiAtLT5cbiAgICAgIDxpb24tc2VsZWN0LW9wdGlvbiB2YWx1ZT1cIlwiPnt7IG5vR3JvdXBMYWJlbCB9fTwvaW9uLXNlbGVjdC1vcHRpb24+XG4gICAgICBAZm9yIChnIG9mIGdyb3VwczsgdHJhY2sgZy5pZCkge1xuICAgICAgICA8aW9uLXNlbGVjdC1vcHRpb24gW3ZhbHVlXT1cImcuaWRcIj57eyBnLm5hbWUgfX08L2lvbi1zZWxlY3Qtb3B0aW9uPlxuICAgICAgfVxuICAgIDwvaW9uLXNlbGVjdD5cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgR3JvdXBQaWNrZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBASW5wdXQoKSBsYWJlbCA9ICcnO1xuICBASW5wdXQoKSBwbGFjZWhvbGRlciA9ICcnO1xuICBASW5wdXQoKSBub0dyb3VwTGFiZWwgPSAnJztcbiAgQElucHV0KCkgdmFsdWU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBkaXNhYmxlZCA9IGZhbHNlO1xuICBAT3V0cHV0KCkgdmFsdWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZyB8IG51bGw+KCk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBncm91cHNTdmMgPSBpbmplY3QoR3JvdXBzU2VydmljZSk7XG4gIGdyb3VwczogVmFsR3JvdXBbXSA9IFtdO1xuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuZ3JvdXBzU3ZjLmxpc3RHcm91cHMoKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKGcpID0+ICh0aGlzLmdyb3VwcyA9IGcpLFxuICAgICAgLy8gQmVzdC1lZmZvcnQ6IHNpIGxhIGxlY3R1cmEgZmFsbGEsIGVsIHBpY2tlciBxdWVkYSBjb24gbGEgb3BjacOzbiBcInNpblxuICAgICAgLy8gZ3J1cG9cIiDDum5pY2FtZW50ZS4gTm8gZXMgdW4gZXJyb3IgYmxvcXVlYW50ZSDigJQgY3JlYXIgZWwgcmVjdXJzbyBzaW5cbiAgICAgIC8vIGFzaWduYXIgc2lndWUgc2llbmRvIHbDoWxpZG8uXG4gICAgICBlcnJvcjogKCkgPT4gKHRoaXMuZ3JvdXBzID0gW10pLFxuICAgIH0pO1xuICB9XG5cbiAgb25DaGFuZ2Uodjogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy52YWx1ZSA9IHYgfHwgbnVsbDtcbiAgICB0aGlzLnZhbHVlQ2hhbmdlLmVtaXQodGhpcy52YWx1ZSk7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { Component, EventEmitter, Input, Output, inject } from '@angular/core';
|
|
3
|
+
import { IonIcon, IonSelect, IonSelectOption } from '@ionic/angular/standalone';
|
|
4
|
+
import { ButtonComponent } from '../../atoms/button/button.component';
|
|
5
|
+
import { ComponentStates } from '../../types';
|
|
6
|
+
import { GroupsService } from '../../../services/groups/groups.service';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
/**
|
|
9
|
+
* val-group-members — administrar la membresía de UN grupo (ADR-083).
|
|
10
|
+
*
|
|
11
|
+
* Deliberadamente NO trae su propio selector de personas: la fuente de
|
|
12
|
+
* "quiénes son los miembros elegibles de la organización" varía por app (org
|
|
13
|
+
* members, invitados, etc.), así que se recibe por `@Input candidates` en vez
|
|
14
|
+
* de que este organismo importe un servicio de organización que no le
|
|
15
|
+
* corresponde. Sin candidatos, igual funciona: solo lista y quita.
|
|
16
|
+
*
|
|
17
|
+
* Sin texto hardcodeado (lib i18n-agnostic): los labels llegan por `@Input`.
|
|
18
|
+
*/
|
|
19
|
+
export class GroupMembersComponent {
|
|
20
|
+
constructor() {
|
|
21
|
+
/** Personas elegibles para agregar. Vacío = el organismo solo lista/quita. */
|
|
22
|
+
this.candidates = [];
|
|
23
|
+
this.addPlaceholder = '';
|
|
24
|
+
this.emptyLabel = '';
|
|
25
|
+
this.removeLabel = '';
|
|
26
|
+
this.membersChange = new EventEmitter();
|
|
27
|
+
this.groupsSvc = inject(GroupsService);
|
|
28
|
+
this.members = [];
|
|
29
|
+
this.busy = false;
|
|
30
|
+
}
|
|
31
|
+
get removeButtonProps() {
|
|
32
|
+
return {
|
|
33
|
+
text: this.removeLabel,
|
|
34
|
+
color: 'dark',
|
|
35
|
+
fill: 'clear',
|
|
36
|
+
size: 'small',
|
|
37
|
+
shape: 'round',
|
|
38
|
+
type: 'button',
|
|
39
|
+
state: this.busy ? ComponentStates.DISABLED : ComponentStates.ENABLED,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
ngOnChanges(changes) {
|
|
43
|
+
if (changes['groupId'] && this.groupId) {
|
|
44
|
+
this.reload();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
reload() {
|
|
48
|
+
this.groupsSvc.listMembers(this.groupId).subscribe({
|
|
49
|
+
next: (m) => (this.members = m),
|
|
50
|
+
error: () => (this.members = []),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/** Candidatos que todavía no están en el grupo — evita ofrecer un alta duplicada. */
|
|
54
|
+
eligible() {
|
|
55
|
+
const current = new Set(this.members.map((m) => m.userId));
|
|
56
|
+
return this.candidates.filter((c) => !current.has(c.userId));
|
|
57
|
+
}
|
|
58
|
+
nameFor(userId) {
|
|
59
|
+
const c = this.candidates.find((x) => x.userId === userId);
|
|
60
|
+
return c?.name || c?.email || userId;
|
|
61
|
+
}
|
|
62
|
+
add(userId) {
|
|
63
|
+
if (!userId || this.busy)
|
|
64
|
+
return;
|
|
65
|
+
this.busy = true;
|
|
66
|
+
this.groupsSvc.addMember(this.groupId, { userId }).subscribe({
|
|
67
|
+
next: (members) => {
|
|
68
|
+
this.members = members;
|
|
69
|
+
this.busy = false;
|
|
70
|
+
this.membersChange.emit(members);
|
|
71
|
+
},
|
|
72
|
+
error: () => (this.busy = false),
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
remove(userId) {
|
|
76
|
+
if (this.busy)
|
|
77
|
+
return;
|
|
78
|
+
this.busy = true;
|
|
79
|
+
this.groupsSvc.removeMember(this.groupId, userId).subscribe({
|
|
80
|
+
next: (members) => {
|
|
81
|
+
this.members = members;
|
|
82
|
+
this.busy = false;
|
|
83
|
+
this.membersChange.emit(members);
|
|
84
|
+
},
|
|
85
|
+
error: () => (this.busy = false),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GroupMembersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
89
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: GroupMembersComponent, isStandalone: true, selector: "val-group-members", inputs: { groupId: "groupId", candidates: "candidates", addPlaceholder: "addPlaceholder", emptyLabel: "emptyLabel", removeLabel: "removeLabel" }, outputs: { membersChange: "membersChange" }, usesOnChanges: true, ngImport: i0, template: `
|
|
90
|
+
<div class="group-members">
|
|
91
|
+
@if (candidates.length > 0) {
|
|
92
|
+
<div class="group-members__add">
|
|
93
|
+
<ion-select
|
|
94
|
+
[placeholder]="addPlaceholder"
|
|
95
|
+
interface="popover"
|
|
96
|
+
[disabled]="busy"
|
|
97
|
+
(ionChange)="add($event.detail.value)"
|
|
98
|
+
>
|
|
99
|
+
@for (c of eligible(); track c.userId) {
|
|
100
|
+
<ion-select-option [value]="c.userId">
|
|
101
|
+
{{ c.name || c.email || c.userId }}
|
|
102
|
+
</ion-select-option>
|
|
103
|
+
}
|
|
104
|
+
</ion-select>
|
|
105
|
+
</div>
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@if (members.length === 0) {
|
|
109
|
+
<p class="group-members__empty">{{ emptyLabel }}</p>
|
|
110
|
+
} @else {
|
|
111
|
+
<ul class="group-members__list">
|
|
112
|
+
@for (m of members; track m.userId) {
|
|
113
|
+
<li class="group-members__row">
|
|
114
|
+
<span class="group-members__name">{{ nameFor(m.userId) }}</span>
|
|
115
|
+
<val-button
|
|
116
|
+
[props]="removeButtonProps"
|
|
117
|
+
(onClick)="remove(m.userId)"
|
|
118
|
+
/>
|
|
119
|
+
</li>
|
|
120
|
+
}
|
|
121
|
+
</ul>
|
|
122
|
+
}
|
|
123
|
+
</div>
|
|
124
|
+
`, isInline: true, styles: [".group-members{display:flex;flex-direction:column;gap:12px}.group-members__empty{font-size:.875rem;color:var(--ion-color-medium, #92949c);margin:0}.group-members__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px}.group-members__row{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;border-radius:10px;background:var(--ion-color-light, #f4f5f8)}.group-members__name{font-size:.9375rem;color:var(--ion-text-color, #000)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "errorText", "expandedIcon", "fill", "helperText", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "component", type: ButtonComponent, selector: "val-button", inputs: ["preset", "props"], outputs: ["onClick"] }] }); }
|
|
125
|
+
}
|
|
126
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: GroupMembersComponent, decorators: [{
|
|
127
|
+
type: Component,
|
|
128
|
+
args: [{ selector: 'val-group-members', standalone: true, imports: [CommonModule, IonIcon, IonSelect, IonSelectOption, ButtonComponent], template: `
|
|
129
|
+
<div class="group-members">
|
|
130
|
+
@if (candidates.length > 0) {
|
|
131
|
+
<div class="group-members__add">
|
|
132
|
+
<ion-select
|
|
133
|
+
[placeholder]="addPlaceholder"
|
|
134
|
+
interface="popover"
|
|
135
|
+
[disabled]="busy"
|
|
136
|
+
(ionChange)="add($event.detail.value)"
|
|
137
|
+
>
|
|
138
|
+
@for (c of eligible(); track c.userId) {
|
|
139
|
+
<ion-select-option [value]="c.userId">
|
|
140
|
+
{{ c.name || c.email || c.userId }}
|
|
141
|
+
</ion-select-option>
|
|
142
|
+
}
|
|
143
|
+
</ion-select>
|
|
144
|
+
</div>
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
@if (members.length === 0) {
|
|
148
|
+
<p class="group-members__empty">{{ emptyLabel }}</p>
|
|
149
|
+
} @else {
|
|
150
|
+
<ul class="group-members__list">
|
|
151
|
+
@for (m of members; track m.userId) {
|
|
152
|
+
<li class="group-members__row">
|
|
153
|
+
<span class="group-members__name">{{ nameFor(m.userId) }}</span>
|
|
154
|
+
<val-button
|
|
155
|
+
[props]="removeButtonProps"
|
|
156
|
+
(onClick)="remove(m.userId)"
|
|
157
|
+
/>
|
|
158
|
+
</li>
|
|
159
|
+
}
|
|
160
|
+
</ul>
|
|
161
|
+
}
|
|
162
|
+
</div>
|
|
163
|
+
`, styles: [".group-members{display:flex;flex-direction:column;gap:12px}.group-members__empty{font-size:.875rem;color:var(--ion-color-medium, #92949c);margin:0}.group-members__list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px}.group-members__row{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;border-radius:10px;background:var(--ion-color-light, #f4f5f8)}.group-members__name{font-size:.9375rem;color:var(--ion-text-color, #000)}\n"] }]
|
|
164
|
+
}], propDecorators: { groupId: [{
|
|
165
|
+
type: Input,
|
|
166
|
+
args: [{ required: true }]
|
|
167
|
+
}], candidates: [{
|
|
168
|
+
type: Input
|
|
169
|
+
}], addPlaceholder: [{
|
|
170
|
+
type: Input
|
|
171
|
+
}], emptyLabel: [{
|
|
172
|
+
type: Input
|
|
173
|
+
}], removeLabel: [{
|
|
174
|
+
type: Input
|
|
175
|
+
}], membersChange: [{
|
|
176
|
+
type: Output
|
|
177
|
+
}] } });
|
|
178
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JvdXAtbWVtYmVycy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvb3JnYW5pc21zL2dyb3VwLW1lbWJlcnMvZ3JvdXAtbWVtYmVycy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBYSxNQUFNLEVBQWlCLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN6RyxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNoRixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDdEUsT0FBTyxFQUFFLGVBQWUsRUFBa0IsTUFBTSxhQUFhLENBQUM7QUFDOUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHlDQUF5QyxDQUFDOztBQVV4RTs7Ozs7Ozs7OztHQVVHO0FBMkNILE1BQU0sT0FBTyxxQkFBcUI7SUExQ2xDO1FBNENFLDhFQUE4RTtRQUNyRSxlQUFVLEdBQTJCLEVBQUUsQ0FBQztRQUN4QyxtQkFBYyxHQUFHLEVBQUUsQ0FBQztRQUNwQixlQUFVLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLGdCQUFXLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLGtCQUFhLEdBQUcsSUFBSSxZQUFZLEVBQW9CLENBQUM7UUFFOUMsY0FBUyxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNuRCxZQUFPLEdBQXFCLEVBQUUsQ0FBQztRQUMvQixTQUFJLEdBQUcsS0FBSyxDQUFDO0tBK0RkO0lBN0RDLElBQUksaUJBQWlCO1FBQ25CLE9BQU87WUFDTCxJQUFJLEVBQUUsSUFBSSxDQUFDLFdBQVc7WUFDdEIsS0FBSyxFQUFFLE1BQU07WUFD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SUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDbkMsQ0FBQztZQUNELEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDO1NBQ2pDLENBQUMsQ0FBQztJQUNMLENBQUM7K0dBekVVLHFCQUFxQjttR0FBckIscUJBQXFCLGlTQXRDdEI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUNULDRpQkFwQ1MsWUFBWSwrQkFBVyxTQUFTLGtWQUFFLGVBQWUsNkZBQUUsZUFBZTs7NEZBdUNqRSxxQkFBcUI7a0JBMUNqQyxTQUFTOytCQUNFLG1CQUFtQixjQUNqQixJQUFJLFdBQ1AsQ0FBQyxZQUFZLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQUUsZUFBZSxDQUFDLFlBQ25FOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1DVDs4QkFJMEIsT0FBTztzQkFBakMsS0FBSzt1QkFBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUU7Z0JBRWhCLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0ksYUFBYTtzQkFBdEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uQ2hhbmdlcywgT3V0cHV0LCBTaW1wbGVDaGFuZ2VzLCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IElvbkljb24sIElvblNlbGVjdCwgSW9uU2VsZWN0T3B0aW9uIH0gZnJvbSAnQGlvbmljL2FuZ3VsYXIvc3RhbmRhbG9uZSc7XG5pbXBvcnQgeyBCdXR0b25Db21wb25lbnQgfSBmcm9tICcuLi8uLi9hdG9tcy9idXR0b24vYnV0dG9uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBDb21wb25lbnRTdGF0ZXMsIEJ1dHRvbk1ldGFkYXRhIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuaW1wb3J0IHsgR3JvdXBzU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2dyb3Vwcy9ncm91cHMuc2VydmljZSc7XG5pbXBvcnQgeyBWYWxHcm91cE1lbWJlciB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2dyb3Vwcy90eXBlcyc7XG5cbi8qKiBQZXJzb25hIGVsZWdpYmxlIHBhcmEgYWdyZWdhciBhbCBncnVwbyAodMOtcGljYW1lbnRlIHVuIGBPcmdNZW1iZXJgKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgR3JvdXBNZW1iZXJDYW5kaWRhdGUge1xuICB1c2VySWQ6IHN0cmluZztcbiAgbmFtZT86IHN0cmluZztcbiAgZW1haWw/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogdmFsLWdyb3VwLW1lbWJlcnMg4oCUIGFkbWluaXN0cmFyIGxhIG1lbWJyZXPDrWEgZGUgVU4gZ3J1cG8gKEFEUi0wODMpLlxuICpcbiAqIERlbGliZXJhZGFtZW50ZSBOTyB0cmFlIHN1IHByb3BpbyBzZWxlY3RvciBkZSBwZXJzb25hczogbGEgZnVlbnRlIGRlXG4gKiBcInF1acOpbmVzIHNvbiBsb3MgbWllbWJyb3MgZWxlZ2libGVzIGRlIGxhIG9yZ2FuaXphY2nDs25cIiB2YXLDrWEgcG9yIGFwcCAob3JnXG4gKiBtZW1iZXJzLCBpbnZpdGFkb3MsIGV0Yy4pLCBhc8OtIHF1ZSBzZSByZWNpYmUgcG9yIGBASW5wdXQgY2FuZGlkYXRlc2AgZW4gdmV6XG4gKiBkZSBxdWUgZXN0ZSBvcmdhbmlzbW8gaW1wb3J0ZSB1biBzZXJ2aWNpbyBkZSBvcmdhbml6YWNpw7NuIHF1ZSBubyBsZVxuICogY29ycmVzcG9uZGUuIFNpbiBjYW5kaWRhdG9zLCBpZ3VhbCBmdW5jaW9uYTogc29sbyBsaXN0YSB5IHF1aXRhLlxuICpcbiAqIFNpbiB0ZXh0byBoYXJkY29kZWFkbyAobGliIGkxOG4tYWdub3N0aWMpOiBsb3MgbGFiZWxzIGxsZWdhbiBwb3IgYEBJbnB1dGAuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3ZhbC1ncm91cC1tZW1iZXJzJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgSW9uSWNvbiwgSW9uU2VsZWN0LCBJb25TZWxlY3RPcHRpb24sIEJ1dHRvbkNvbXBvbmVudF0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cImdyb3VwLW1lbWJlcnNcIj5cbiAgICAgIEBpZiAoY2FuZGlkYXRlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJncm91cC1tZW1iZXJzX19hZGRcIj5cbiAgICAgICAgICA8aW9uLXNlbGVjdFxuICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cImFkZFBsYWNlaG9sZGVyXCJcbiAgICAgICAgICAgIGludGVyZmFjZT1cInBvcG92ZXJcIlxuICAgICAgICAgICAgW2Rpc2FibGVkXT1cImJ1c3lcIlxuICAgICAgICAgICAgKGlvbkNoYW5nZSk9XCJhZGQoJGV2ZW50LmRldGFpbC52YWx1ZSlcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIEBmb3IgKGMgb2YgZWxpZ2libGUoKTsgdHJhY2sgYy51c2VySWQpIHtcbiAgICAgICAgICAgICAgPGlvbi1zZWxlY3Qtb3B0aW9uIFt2YWx1ZV09XCJjLnVzZXJJZFwiPlxuICAgICAgICAgICAgICAgIHt7IGMubmFtZSB8fCBjLmVtYWlsIHx8IGMudXNlcklkIH19XG4gICAgICAgICAgICAgIDwvaW9uLXNlbGVjdC1vcHRpb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9pb24tc2VsZWN0PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIH1cblxuICAgICAgQGlmIChtZW1iZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICA8cCBjbGFzcz1cImdyb3VwLW1lbWJlcnNfX2VtcHR5XCI+e3sgZW1wdHlMYWJlbCB9fTwvcD5cbiAgICAgIH0gQGVsc2Uge1xuICAgICAgICA8dWwgY2xhc3M9XCJncm91cC1tZW1iZXJzX19saXN0XCI+XG4gICAgICAgICAgQGZvciAobSBvZiBtZW1iZXJzOyB0cmFjayBtLnVzZXJJZCkge1xuICAgICAgICAgICAgPGxpIGNsYXNzPVwiZ3JvdXAtbWVtYmVyc19fcm93XCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZ3JvdXAtbWVtYmVyc19fbmFtZVwiPnt7IG5hbWVGb3IobS51c2VySWQpIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8dmFsLWJ1dHRvblxuICAgICAgICAgICAgICAgIFtwcm9wc109XCJyZW1vdmVCdXR0b25Qcm9wc1wiXG4gICAgICAgICAgICAgICAgKG9uQ2xpY2spPVwicmVtb3ZlKG0udXNlcklkKVwiXG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8L2xpPlxuICAgICAgICAgIH1cbiAgICAgICAgPC91bD5cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgYCxcbiAgc3R5bGVVcmxzOiBbJy4vZ3JvdXAtbWVtYmVycy5jb21wb25lbnQuc2NzcyddLFxufSlcbmV4cG9ydCBjbGFzcyBHcm91cE1lbWJlcnNDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICBASW5wdXQoeyByZXF1aXJlZDogdHJ1ZSB9KSBncm91cElkITogc3RyaW5nO1xuICAvKiogUGVyc29uYXMgZWxlZ2libGVzIHBhcmEgYWdyZWdhci4gVmFjw61vID0gZWwgb3JnYW5pc21vIHNvbG8gbGlzdGEvcXVpdGEuICovXG4gIEBJbnB1dCgpIGNhbmRpZGF0ZXM6IEdyb3VwTWVtYmVyQ2FuZGlkYXRlW10gPSBbXTtcbiAgQElucHV0KCkgYWRkUGxhY2Vob2xkZXIgPSAnJztcbiAgQElucHV0KCkgZW1wdHlMYWJlbCA9ICcnO1xuICBASW5wdXQoKSByZW1vdmVMYWJlbCA9ICcnO1xuICBAT3V0cHV0KCkgbWVtYmVyc0NoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8VmFsR3JvdXBNZW1iZXJbXT4oKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGdyb3Vwc1N2YyA9IGluamVjdChHcm91cHNTZXJ2aWNlKTtcbiAgbWVtYmVyczogVmFsR3JvdXBNZW1iZXJbXSA9IFtdO1xuICBidXN5ID0gZmFsc2U7XG5cbiAgZ2V0IHJlbW92ZUJ1dHRvblByb3BzKCk6IEJ1dHRvbk1ldGFkYXRhIHtcbiAgICByZXR1cm4ge1xuICAgICAgdGV4dDogdGhpcy5yZW1vdmVMYWJlbCxcbiAgICAgIGNvbG9yOiAnZGFyaycsXG4gICAgICBmaWxsOiAnY2xlYXInLFxuICAgICAgc2l6ZTogJ3NtYWxsJyxcbiAgICAgIHNoYXBlOiAncm91bmQnLFxuICAgICAgdHlwZTogJ2J1dHRvbicsXG4gICAgICBzdGF0ZTogdGhpcy5idXN5ID8gQ29tcG9uZW50U3RhdGVzLkRJU0FCTEVEIDogQ29tcG9uZW50U3RhdGVzLkVOQUJMRUQsXG4gICAgfTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1snZ3JvdXBJZCddICYmIHRoaXMuZ3JvdXBJZCkge1xuICAgICAgdGhpcy5yZWxvYWQoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlbG9hZCgpOiB2b2lkIHtcbiAgICB0aGlzLmdyb3Vwc1N2Yy5saXN0TWVtYmVycyh0aGlzLmdyb3VwSWQpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAobSkgPT4gKHRoaXMubWVtYmVycyA9IG0pLFxuICAgICAgZXJyb3I6ICgpID0+ICh0aGlzLm1lbWJlcnMgPSBbXSksXG4gICAgfSk7XG4gIH1cblxuICAvKiogQ2FuZGlkYXRvcyBxdWUgdG9kYXbDrWEgbm8gZXN0w6FuIGVuIGVsIGdydXBvIOKAlCBldml0YSBvZnJlY2VyIHVuIGFsdGEgZHVwbGljYWRhLiAqL1xuICBlbGlnaWJsZSgpOiBHcm91cE1lbWJlckNhbmRpZGF0ZVtdIHtcbiAgICBjb25zdCBjdXJyZW50ID0gbmV3IFNldCh0aGlzLm1lbWJlcnMubWFwKChtKSA9PiBtLnVzZXJJZCkpO1xuICAgIHJldHVybiB0aGlzLmNhbmRpZGF0ZXMuZmlsdGVyKChjKSA9PiAhY3VycmVudC5oYXMoYy51c2VySWQpKTtcbiAgfVxuXG4gIG5hbWVGb3IodXNlcklkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGMgPSB0aGlzLmNhbmRpZGF0ZXMuZmluZCgoeCkgPT4geC51c2VySWQgPT09IHVzZXJJZCk7XG4gICAgcmV0dXJuIGM/Lm5hbWUgfHwgYz8uZW1haWwgfHwgdXNlcklkO1xuICB9XG5cbiAgYWRkKHVzZXJJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCF1c2VySWQgfHwgdGhpcy5idXN5KSByZXR1cm47XG4gICAgdGhpcy5idXN5ID0gdHJ1ZTtcbiAgICB0aGlzLmdyb3Vwc1N2Yy5hZGRNZW1iZXIodGhpcy5ncm91cElkLCB7IHVzZXJJZCB9KS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKG1lbWJlcnMpID0+IHtcbiAgICAgICAgdGhpcy5tZW1iZXJzID0gbWVtYmVycztcbiAgICAgICAgdGhpcy5idXN5ID0gZmFsc2U7XG4gICAgICAgIHRoaXMubWVtYmVyc0NoYW5nZS5lbWl0KG1lbWJlcnMpO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoKSA9PiAodGhpcy5idXN5ID0gZmFsc2UpLFxuICAgIH0pO1xuICB9XG5cbiAgcmVtb3ZlKHVzZXJJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYnVzeSkgcmV0dXJuO1xuICAgIHRoaXMuYnVzeSA9IHRydWU7XG4gICAgdGhpcy5ncm91cHNTdmMucmVtb3ZlTWVtYmVyKHRoaXMuZ3JvdXBJZCwgdXNlcklkKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKG1lbWJlcnMpID0+IHtcbiAgICAgICAgdGhpcy5tZW1iZXJzID0gbWVtYmVycztcbiAgICAgICAgdGhpcy5idXN5ID0gZmFsc2U7XG4gICAgICAgIHRoaXMubWVtYmVyc0NoYW5nZS5lbWl0KG1lbWJlcnMpO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoKSA9PiAodGhpcy5idXN5ID0gZmFsc2UpLFxuICAgIH0pO1xuICB9XG59XG4iXX0=
|