@litigiovirtual/ius-design-components 1.0.288 → 1.0.290

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.
@@ -1,19 +1,30 @@
1
- import { Component, EventEmitter, HostListener, Input, Output } from '@angular/core';
1
+ import { Component, EventEmitter, HostListener, Input, Output, ViewChild } from '@angular/core';
2
+ import { TemplatePortal } from '@angular/cdk/portal';
2
3
  import { IconMdComponent } from '../icon-md/icon-md.component';
3
4
  import { CommonModule } from '@angular/common';
4
5
  import { FormsModule } from '@angular/forms';
5
6
  import { SimpleDividerComponent } from '../simple-divider';
6
7
  import { ButtonStandardTertiaryComponent } from '../button-standard-tertiary';
7
8
  import * as i0 from "@angular/core";
8
- import * as i1 from "@angular/forms";
9
- import * as i2 from "@angular/common";
9
+ import * as i1 from "@angular/cdk/overlay";
10
+ import * as i2 from "@angular/forms";
11
+ import * as i3 from "@angular/common";
10
12
  export class CustomDropdownComponent {
11
- constructor() {
13
+ get showList() {
14
+ return this._overlayRef !== null;
15
+ }
16
+ constructor(_el, _overlay, _vcr) {
17
+ this._el = _el;
18
+ this._overlay = _overlay;
19
+ this._vcr = _vcr;
12
20
  this.isFocused = false;
13
21
  this.isAlertText = false;
14
- this.showList = false;
15
22
  this.hasClickedInside = false;
16
23
  this.selected = false;
24
+ this._overlayRef = null;
25
+ this._scrollListener = () => { this._overlayRef?.updatePosition(); };
26
+ this._debounceTimer = null;
27
+ this._scrolledEndCooldown = false;
17
28
  this.componentId = '';
18
29
  this.required = false;
19
30
  this.disabled = false;
@@ -24,46 +35,104 @@ export class CustomDropdownComponent {
24
35
  this.textBtnAdd = 'Agregar';
25
36
  this.textInput = '';
26
37
  this.element = '';
38
+ this.debounceMs = 300;
39
+ this.enableInfiniteScroll = false;
40
+ this.loading = false;
27
41
  this.onChangesValueEvent = new EventEmitter();
28
42
  this.onEnterKey = new EventEmitter();
29
43
  this.onAddElement = new EventEmitter();
30
44
  this.onBlurEvent = new EventEmitter();
45
+ this.onFocusEvent = new EventEmitter();
46
+ this.onScrolledToEnd = new EventEmitter();
31
47
  }
32
48
  onClickOutside(event) {
33
- if (!this.hasClickedInside)
49
+ if (!this.hasClickedInside) {
34
50
  return;
51
+ }
35
52
  const target = event.target;
36
- const container = document.getElementById(this.componentId);
37
- if (container && !container.contains(target)) {
38
- this.isFocused = false;
39
- this.showList = false;
40
- this.isAlertText = !this.selected && !this.showList;
53
+ // Click dentro del panel overlay (opciones o "agregar elemento") → no cerrar
54
+ if (this._overlayRef?.overlayElement.contains(target)) {
55
+ return;
41
56
  }
57
+ // Click dentro del textfield → no cerrar
58
+ const textfield = this._el.nativeElement.querySelector('.container-textfield');
59
+ if (textfield?.contains(target)) {
60
+ return;
61
+ }
62
+ this.closeList();
63
+ }
64
+ closeList(event) {
65
+ if (event) {
66
+ event.stopImmediatePropagation();
67
+ }
68
+ this.isFocused = false;
69
+ this._closePanel();
70
+ if (!this.selected && this.required) {
71
+ this.isAlertText = true;
72
+ }
73
+ else {
74
+ this.isAlertText = false;
75
+ }
76
+ this.onBlurEvent.emit();
42
77
  }
43
78
  onInput() {
44
- if (this.selected)
79
+ if (this.selected) {
45
80
  this.selected = false;
46
- this.onChangesValueEvent.emit(this.textInput);
81
+ }
82
+ if (this.debounceMs <= 0) {
83
+ this.onChangesValueEvent.emit(this.textInput);
84
+ return;
85
+ }
86
+ if (this._debounceTimer) {
87
+ clearTimeout(this._debounceTimer);
88
+ }
89
+ this._debounceTimer = setTimeout(() => {
90
+ this.onChangesValueEvent.emit(this.textInput);
91
+ }, this.debounceMs);
92
+ }
93
+ onListScroll(event) {
94
+ if (!this.enableInfiniteScroll) {
95
+ return;
96
+ }
97
+ const el = event.target;
98
+ const threshold = 48;
99
+ const nearBottom = el.scrollTop + el.clientHeight >= el.scrollHeight - threshold;
100
+ if (!nearBottom || this._scrolledEndCooldown) {
101
+ return;
102
+ }
103
+ this._scrolledEndCooldown = true;
104
+ this.onScrolledToEnd.emit();
105
+ setTimeout(() => { this._scrolledEndCooldown = false; }, 300);
47
106
  }
48
107
  onFocus() {
108
+ if (this.disabled) {
109
+ return;
110
+ }
49
111
  this.isFocused = true;
50
- this.showList = true;
51
112
  this.hasClickedInside = true;
113
+ if (!this.showList) {
114
+ this._openPanel();
115
+ }
116
+ this.onFocusEvent.emit();
52
117
  }
53
118
  onBlur() {
54
119
  this.isFocused = false;
120
+ if (this.showList) {
121
+ return;
122
+ }
55
123
  if (this.required) {
56
124
  this.isAlertText = this.textInput === '';
57
125
  }
58
- this.onBlurEvent.emit();
59
126
  }
60
127
  onKeyPress(event) {
61
- if (event.key === 'Enter')
128
+ if (event.key === 'Enter') {
62
129
  this.addText();
130
+ }
63
131
  }
64
132
  onKeyPressAddElement(event) {
65
- if (event.key === 'Enter')
133
+ if (event.key === 'Enter') {
66
134
  this.addElementText();
135
+ }
67
136
  }
68
137
  onClickAddElement() {
69
138
  if (this.element.trim() !== '') {
@@ -86,13 +155,46 @@ export class CustomDropdownComponent {
86
155
  }
87
156
  }
88
157
  onSelectOption() {
158
+ this.selected = true;
89
159
  this.isFocused = false;
90
- this.showList = false;
160
+ this._closePanel();
91
161
  this.isAlertText = false;
92
- this.selected = true;
93
162
  }
94
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
95
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: CustomDropdownComponent, isStandalone: true, selector: "ius-custom-dropdown", inputs: { componentId: "componentId", required: "required", disabled: "disabled", showHelpText: "showHelpText", error: "error", labelSuperior: "labelSuperior", labelInferior: "labelInferior", errorText: "errorText", labelInput: "labelInput", iconInput: "iconInput", placeholderAddText: "placeholderAddText", iconBtnAdd: "iconBtnAdd", textBtnAdd: "textBtnAdd", textInput: "textInput", element: "element" }, outputs: { onChangesValueEvent: "onChangesValueEvent", onEnterKey: "onEnterKey", onAddElement: "onAddElement", onBlurEvent: "onBlurEvent" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, ngImport: i0, template: "<div class=\"container-general\" [id]=\"componentId\">\r\n\r\n <!-- Label superior -->\r\n @if (labelSuperior) {\r\n <div class=\"container-label-sup\" [ngClass]=\"{ disabled: disabled }\">\r\n @if (!disabled && required) {\r\n <div class=\"icon-dot\"></div>\r\n }\r\n <span>{{ labelSuperior }}</span>\r\n @if (!disabled && showHelpText) {\r\n <ius-icon-md iconName=\"icon-help\" class=\"icon-color-help\"></ius-icon-md>\r\n }\r\n <span>:</span>\r\n </div>\r\n }\r\n\r\n <!-- Input principal -->\r\n <div\r\n class=\"container-textfield\"\r\n [ngClass]=\"{\r\n disabled: disabled,\r\n focused: isFocused,\r\n alert: (!isFocused && isAlertText && !disabled) || (error && !disabled)\r\n }\"\r\n >\r\n @if (iconInput) {\r\n <ius-icon-md [iconName]=\"iconInput\" class=\"icon-color\"></ius-icon-md>\r\n }\r\n <input\r\n type=\"text\"\r\n [(ngModel)]=\"textInput\"\r\n [placeholder]=\"labelInput\"\r\n [disabled]=\"disabled\"\r\n (input)=\"onInput()\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n (keypress)=\"onKeyPress($event)\"\r\n />\r\n <div class=\"cnt-icon-right\">\r\n @if (!showList) {\r\n <ius-icon-md iconName=\"icon-keyboard-arrow-down\" class=\"icon-arrows\"></ius-icon-md>\r\n } @else {\r\n <ius-icon-md iconName=\"icon-keyboard-arrow-up\" class=\"icon-arrows\"></ius-icon-md>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Label inferior -->\r\n @if (labelInferior && isFocused && !error) {\r\n <span class=\"label-inf\">{{ labelInferior }}</span>\r\n }\r\n @if ((errorText || labelInferior) && ((!isFocused && isAlertText && !disabled) || (error && !disabled))) {\r\n <span class=\"label-inf\" [ngClass]=\"{ alert: (!isFocused && isAlertText && !disabled) || (error && !disabled) }\">\r\n {{ errorText ?? labelInferior }}\r\n </span>\r\n }\r\n\r\n <!-- Lista de opciones -->\r\n @if (showList) {\r\n <div class=\"container-options\">\r\n <div class=\"container-list scrollable-small\">\r\n <div (click)=\"onSelectOption()\">\r\n <ng-content selector=\"ius-option\"></ng-content>\r\n </div>\r\n </div>\r\n <ius-simple-divider></ius-simple-divider>\r\n <div class=\"add-data\">\r\n <div class=\"container-text\">\r\n <input\r\n type=\"text\"\r\n class=\"input-text\"\r\n [(ngModel)]=\"element\"\r\n (keypress)=\"onKeyPressAddElement($event)\"\r\n [placeholder]=\"placeholderAddText\"\r\n />\r\n </div>\r\n <div class=\"button-add-option\">\r\n <ius-button-standard-tertiary\r\n [iconName]=\"iconBtnAdd\"\r\n (click)=\"onClickAddElement()\"\r\n >\r\n {{ textBtnAdd }}\r\n </ius-button-standard-tertiary>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n</div>", styles: [".h1{font-family:Roboto,sans-serif;font-size:2.375rem;font-weight:500;line-height:46px}.h2{font-family:Roboto,sans-serif;font-size:1.875rem;font-weight:700;line-height:38px}.h3{font-family:Roboto,sans-serif;font-size:1.5rem;font-weight:500;line-height:32px}.h4{font-family:Roboto,sans-serif;font-size:1.25rem;font-weight:700;line-height:26px}.h5{font-family:Roboto,sans-serif;font-size:1.125rem;font-weight:500;line-height:24px;letter-spacing:.18px}.label-large{font-family:Roboto,sans-serif;font-size:1rem;font-weight:500;line-height:22px}.body-large{font-family:Rubik,sans-serif;font-size:1rem;font-weight:400;line-height:22px}.label-base{font-family:Rubik,sans-serif;font-size:.875rem;font-weight:500;line-height:20px;letter-spacing:.28px}.body-base{font-family:Rubik,sans-serif;font-size:.875rem;font-weight:400;line-height:20px;font-style:italic;letter-spacing:.28px}.body-base-1,.body-base-1-1{font-family:Rubik,sans-serif;font-size:.875rem;font-weight:400;line-height:20px;letter-spacing:.28px}.body-sm{font-family:Rubik,sans-serif;font-size:.75rem;font-weight:400;line-height:16px;letter-spacing:.28px}.body-sm-italic{font-family:Rubik,sans-serif;font-size:.75rem;font-weight:400;line-height:16px;font-style:italic;letter-spacing:.28px}.caption-sm{font-family:Rubik,sans-serif;font-size:.75rem;font-weight:500;line-height:16px;letter-spacing:.28px}.caption-sm-italic{font-family:Rubik,sans-serif;font-size:.75rem;font-weight:500;line-height:16px;font-style:italic;letter-spacing:.28px}.container-general{position:relative;height:100%}.container-textfield{display:flex;padding:10px 12px;justify-content:center;align-items:flex-start;gap:4px;border:1px solid #f5f5f5;border-radius:8px;background:#f5f5f5;font-family:Rubik,sans-serif;font-size:.875rem;font-weight:400;line-height:20px;letter-spacing:.28px}.container-textfield:hover:not(.disabled):not(.focused):not(.alert){background:#edf6ff}.container-textfield.focused{border:1px solid #0581BC;background:#edf6ff}.container-textfield.disabled{background:#f5f5f5}.container-textfield.disabled .icon-color,.container-textfield.disabled .icon-arrows{color:#bfbfbf}.container-textfield.disabled input::placeholder{color:#bfbfbf;opacity:1}.container-textfield.alert{border:1px solid #DB2E2A;background:#fff4f0}.icon-color{color:#595959}.icon-arrows{color:#333}.icon-color-help{color:#8c8c8c}input{display:flex;align-items:center;flex:1 0 0;border:none;outline:none;background-color:transparent;font-family:Rubik,sans-serif;font-size:.875rem;font-weight:400;line-height:20px;letter-spacing:.28px}.cnt-icon-right{display:flex;align-items:center;justify-content:center;background:none;padding:0;color:#333}.container-label-sup{display:flex;align-items:center;gap:4px;margin-bottom:8px;color:#333;font-family:Roboto,sans-serif;font-size:.875rem;font-weight:500;line-height:20px;letter-spacing:.28px}.container-label-sup.disabled{color:#bfbfbf}.icon-dot{display:flex;align-items:center;width:4px;height:4px;aspect-ratio:1/1;background-color:#db2e2a;border-radius:100px}.label-inf{display:flex;position:absolute;margin-top:4px;color:#595959;font-family:Roboto,sans-serif;font-size:.75rem;font-style:italic;font-weight:500;line-height:16px;letter-spacing:.24px}.label-inf.alert{color:#931224}.container-options{position:absolute;width:100%;margin-top:4px;border-radius:8px;background:#fff;box-shadow:0 2px 6px #00000024,0 1px 10px #0000001a;z-index:1000}.container-list{max-height:144px;display:flex;flex-direction:column;margin-top:4px;overflow-y:auto}.add-data{display:flex;padding-top:8px;padding-bottom:8px;align-items:center;gap:10px;width:100%;background:#fff;border-radius:8px}.add-data .container-text{display:flex;width:60%;align-items:flex-start;gap:4px}.add-data .container-text .input-text{width:100%;display:flex;margin-left:10px;padding:12px;justify-content:center;align-items:flex-start;gap:4px;border-radius:8px;background:#f5f5f5}.add-data .button-add-option{margin-right:10px;width:40%}.scrollable-small::-webkit-scrollbar{-webkit-appearance:none}.scrollable-small::-webkit-scrollbar:vertical{width:4px;height:32px;padding-top:2px;padding-bottom:2px}.scrollable-small::-webkit-scrollbar:horizontal{height:5px;padding-top:2px;padding-bottom:2px}.scrollable-small::-webkit-scrollbar-thumb{background-color:#08a6db;border-radius:4px}\n"], dependencies: [{ kind: "component", type: IconMdComponent, selector: "ius-icon-md", inputs: ["iconName", "color"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: SimpleDividerComponent, selector: "ius-simple-divider" }, { kind: "component", type: ButtonStandardTertiaryComponent, selector: "ius-button-standard-tertiary", inputs: ["disabled", "iconName"], outputs: ["buttonClicked"] }] }); }
163
+ _openPanel() {
164
+ const textfield = this._el.nativeElement.querySelector('.container-textfield');
165
+ const anchor = textfield ?? this._el;
166
+ const positionStrategy = this._overlay
167
+ .position()
168
+ .flexibleConnectedTo(anchor)
169
+ .withFlexibleDimensions(false)
170
+ .withPush(false)
171
+ .withPositions([
172
+ { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },
173
+ { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },
174
+ ]);
175
+ this._overlayRef = this._overlay.create({
176
+ positionStrategy,
177
+ scrollStrategy: this._overlay.scrollStrategies.reposition(),
178
+ width: (textfield ?? this._el.nativeElement).getBoundingClientRect().width,
179
+ });
180
+ this._overlayRef.attach(new TemplatePortal(this.listPanel, this._vcr));
181
+ window.addEventListener('scroll', this._scrollListener, true);
182
+ }
183
+ _closePanel() {
184
+ if (this._overlayRef) {
185
+ this._overlayRef.dispose();
186
+ this._overlayRef = null;
187
+ window.removeEventListener('scroll', this._scrollListener, true);
188
+ }
189
+ }
190
+ ngOnDestroy() {
191
+ if (this._debounceTimer) {
192
+ clearTimeout(this._debounceTimer);
193
+ }
194
+ this._closePanel();
195
+ }
196
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomDropdownComponent, deps: [{ token: i0.ElementRef }, { token: i1.Overlay }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component }); }
197
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: CustomDropdownComponent, isStandalone: true, selector: "ius-custom-dropdown", inputs: { componentId: "componentId", required: "required", disabled: "disabled", showHelpText: "showHelpText", error: "error", labelSuperior: "labelSuperior", labelInferior: "labelInferior", errorText: "errorText", labelInput: "labelInput", iconInput: "iconInput", placeholderAddText: "placeholderAddText", iconBtnAdd: "iconBtnAdd", textBtnAdd: "textBtnAdd", textInput: "textInput", element: "element", debounceMs: "debounceMs", enableInfiniteScroll: "enableInfiniteScroll", loading: "loading" }, outputs: { onChangesValueEvent: "onChangesValueEvent", onEnterKey: "onEnterKey", onAddElement: "onAddElement", onBlurEvent: "onBlurEvent", onFocusEvent: "onFocusEvent", onScrolledToEnd: "onScrolledToEnd" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, viewQueries: [{ propertyName: "listPanel", first: true, predicate: ["listPanel"], descendants: true }], ngImport: i0, template: "<div class=\"container-general\" [id]=\"componentId\">\n\n <!-- Label superior -->\n @if (labelSuperior) {\n <div class=\"container-label-sup\" [ngClass]=\"{ disabled: disabled }\">\n @if (!disabled && required) {\n <div class=\"icon-dot\"></div>\n }\n <span>{{ labelSuperior }}</span>\n @if (!disabled && showHelpText) {\n <ius-icon-md iconName=\"icon-help\" class=\"icon-color-help\"></ius-icon-md>\n }\n <span>:</span>\n </div>\n }\n\n <!-- Input principal -->\n <div\n class=\"container-textfield\"\n [ngClass]=\"{\n disabled: disabled,\n focused: isFocused,\n alert: (!isFocused && isAlertText && !disabled) || (error && !disabled)\n }\"\n (click)=\"onFocus()\"\n >\n @if (iconInput) {\n <ius-icon-md [iconName]=\"iconInput\" class=\"icon-color\"></ius-icon-md>\n }\n <input\n type=\"text\"\n [(ngModel)]=\"textInput\"\n [placeholder]=\"labelInput\"\n [disabled]=\"disabled\"\n (input)=\"onInput()\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n (keypress)=\"onKeyPress($event)\"\n />\n <div class=\"cnt-icon-right\">\n @if (!showList) {\n <ius-icon-md iconName=\"icon-keyboard-arrow-down\" class=\"icon-arrows\"></ius-icon-md>\n } @else {\n <div (click)=\"closeList($event)\" style=\"height: 20px;\">\n <ius-icon-md iconName=\"icon-keyboard-arrow-up\" class=\"icon-arrows\"></ius-icon-md>\n </div>\n }\n </div>\n </div>\n\n <!-- Label inferior -->\n @if (labelInferior && isFocused && !error) {\n <span class=\"label-inf\">{{ labelInferior }}</span>\n }\n @if ((errorText || labelInferior) && ((!isFocused && isAlertText && !disabled) || (error && !disabled))) {\n <span class=\"label-inf\" [ngClass]=\"{ alert: (!isFocused && isAlertText && !disabled) || (error && !disabled) }\">\n {{ errorText ?? labelInferior }}\n </span>\n }\n\n <!-- Lista de opciones (CDK overlay) -->\n <ng-template #listPanel>\n <div class=\"container-options\">\n <div class=\"container-list scrollable-small\" (scroll)=\"onListScroll($event)\">\n <div (click)=\"onSelectOption()\">\n <ng-content selector=\"ius-option\"></ng-content>\n </div>\n @if (loading) {\n <div class=\"cnt-loading-option\">Cargando\u2026</div>\n }\n </div>\n <ius-simple-divider></ius-simple-divider>\n <div class=\"add-data\">\n <div class=\"container-text\">\n <input\n type=\"text\"\n class=\"input-text\"\n [(ngModel)]=\"element\"\n (keypress)=\"onKeyPressAddElement($event)\"\n [placeholder]=\"placeholderAddText\"\n />\n </div>\n <div class=\"button-add-option\">\n <ius-button-standard-tertiary\n [iconName]=\"iconBtnAdd\"\n (click)=\"onClickAddElement()\"\n >\n {{ textBtnAdd }}\n </ius-button-standard-tertiary>\n </div>\n </div>\n </div>\n </ng-template>\n\n</div>\n", styles: [".h1{font-family:Roboto,sans-serif;font-size:2.375rem;font-weight:500;line-height:46px}.h2{font-family:Roboto,sans-serif;font-size:1.875rem;font-weight:700;line-height:38px}.h3{font-family:Roboto,sans-serif;font-size:1.5rem;font-weight:500;line-height:32px}.h4{font-family:Roboto,sans-serif;font-size:1.25rem;font-weight:700;line-height:26px}.h5{font-family:Roboto,sans-serif;font-size:1.125rem;font-weight:500;line-height:24px;letter-spacing:.18px}.label-large{font-family:Roboto,sans-serif;font-size:1rem;font-weight:500;line-height:22px}.body-large{font-family:Rubik,sans-serif;font-size:1rem;font-weight:400;line-height:22px}.label-base{font-family:Rubik,sans-serif;font-size:.875rem;font-weight:500;line-height:20px;letter-spacing:.28px}.body-base{font-family:Rubik,sans-serif;font-size:.875rem;font-weight:400;line-height:20px;font-style:italic;letter-spacing:.28px}.body-base-1,.body-base-1-1{font-family:Rubik,sans-serif;font-size:.875rem;font-weight:400;line-height:20px;letter-spacing:.28px}.body-sm{font-family:Rubik,sans-serif;font-size:.75rem;font-weight:400;line-height:16px;letter-spacing:.28px}.body-sm-italic{font-family:Rubik,sans-serif;font-size:.75rem;font-weight:400;line-height:16px;font-style:italic;letter-spacing:.28px}.caption-sm{font-family:Rubik,sans-serif;font-size:.75rem;font-weight:500;line-height:16px;letter-spacing:.28px}.caption-sm-italic{font-family:Rubik,sans-serif;font-size:.75rem;font-weight:500;line-height:16px;font-style:italic;letter-spacing:.28px}.container-general{position:relative;height:100%}.container-textfield{display:flex;padding:10px 12px;justify-content:center;align-items:flex-start;gap:4px;border:1px solid #f5f5f5;border-radius:8px;background:#f5f5f5;font-family:Rubik,sans-serif;font-size:.875rem;font-weight:400;line-height:20px;letter-spacing:.28px}.container-textfield:hover:not(.disabled):not(.focused):not(.alert){background:#edf6ff}.container-textfield.focused{border:1px solid #0581BC;background:#edf6ff}.container-textfield.disabled{background:#f5f5f5}.container-textfield.disabled .icon-color,.container-textfield.disabled .icon-arrows{color:#bfbfbf}.container-textfield.disabled input::placeholder{color:#bfbfbf;opacity:1}.container-textfield.alert{border:1px solid #DB2E2A;background:#fff4f0}.icon-color{color:#595959}.icon-arrows{color:#333}.icon-color-help{color:#8c8c8c}input{display:flex;align-items:center;flex:1 0 0;border:none;outline:none;background-color:transparent;font-family:Rubik,sans-serif;font-size:.875rem;font-weight:400;line-height:20px;letter-spacing:.28px}.cnt-icon-right{display:flex;align-items:center;justify-content:center;background:none;padding:0;color:#333}.container-label-sup{display:flex;align-items:center;gap:4px;margin-bottom:8px;color:#333;font-family:Roboto,sans-serif;font-size:.875rem;font-weight:500;line-height:20px;letter-spacing:.28px}.container-label-sup.disabled{color:#bfbfbf}.icon-dot{display:flex;align-items:center;width:4px;height:4px;aspect-ratio:1/1;background-color:#db2e2a;border-radius:100px}.label-inf{display:flex;position:absolute;margin-top:4px;color:#595959;font-family:Roboto,sans-serif;font-size:.75rem;font-style:italic;font-weight:500;line-height:16px;letter-spacing:.24px}.label-inf.alert{color:#931224}.container-options{width:100%;border-radius:8px;background:#fff;box-shadow:0 2px 6px #00000024,0 1px 10px #0000001a}.container-list{max-height:144px;display:flex;flex-direction:column;margin-top:4px;overflow-y:auto}.add-data{display:flex;padding-top:8px;padding-bottom:8px;align-items:center;gap:10px;width:100%;background:#fff;border-radius:8px}.add-data .container-text{display:flex;width:60%;align-items:flex-start;gap:4px}.add-data .container-text .input-text{width:100%;display:flex;margin-left:10px;padding:12px;justify-content:center;align-items:flex-start;gap:4px;border-radius:8px;background:#f5f5f5}.add-data .button-add-option{margin-right:10px;width:40%}.scrollable-small::-webkit-scrollbar{-webkit-appearance:none}.scrollable-small::-webkit-scrollbar:vertical{width:4px;height:32px;padding-top:2px;padding-bottom:2px}.scrollable-small::-webkit-scrollbar:horizontal{height:5px;padding-top:2px;padding-bottom:2px}.scrollable-small::-webkit-scrollbar-thumb{background-color:#08a6db;border-radius:4px}\n"], dependencies: [{ kind: "component", type: IconMdComponent, selector: "ius-icon-md", inputs: ["iconName", "color"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: SimpleDividerComponent, selector: "ius-simple-divider" }, { kind: "component", type: ButtonStandardTertiaryComponent, selector: "ius-button-standard-tertiary", inputs: ["disabled", "iconName"], outputs: ["buttonClicked"] }] }); }
96
198
  }
97
199
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CustomDropdownComponent, decorators: [{
98
200
  type: Component,
@@ -102,8 +204,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
102
204
  CommonModule,
103
205
  SimpleDividerComponent,
104
206
  ButtonStandardTertiaryComponent
105
- ], template: "<div class=\"container-general\" [id]=\"componentId\">\r\n\r\n <!-- Label superior -->\r\n @if (labelSuperior) {\r\n <div class=\"container-label-sup\" [ngClass]=\"{ disabled: disabled }\">\r\n @if (!disabled && required) {\r\n <div class=\"icon-dot\"></div>\r\n }\r\n <span>{{ labelSuperior }}</span>\r\n @if (!disabled && showHelpText) {\r\n <ius-icon-md iconName=\"icon-help\" class=\"icon-color-help\"></ius-icon-md>\r\n }\r\n <span>:</span>\r\n </div>\r\n }\r\n\r\n <!-- Input principal -->\r\n <div\r\n class=\"container-textfield\"\r\n [ngClass]=\"{\r\n disabled: disabled,\r\n focused: isFocused,\r\n alert: (!isFocused && isAlertText && !disabled) || (error && !disabled)\r\n }\"\r\n >\r\n @if (iconInput) {\r\n <ius-icon-md [iconName]=\"iconInput\" class=\"icon-color\"></ius-icon-md>\r\n }\r\n <input\r\n type=\"text\"\r\n [(ngModel)]=\"textInput\"\r\n [placeholder]=\"labelInput\"\r\n [disabled]=\"disabled\"\r\n (input)=\"onInput()\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n (keypress)=\"onKeyPress($event)\"\r\n />\r\n <div class=\"cnt-icon-right\">\r\n @if (!showList) {\r\n <ius-icon-md iconName=\"icon-keyboard-arrow-down\" class=\"icon-arrows\"></ius-icon-md>\r\n } @else {\r\n <ius-icon-md iconName=\"icon-keyboard-arrow-up\" class=\"icon-arrows\"></ius-icon-md>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Label inferior -->\r\n @if (labelInferior && isFocused && !error) {\r\n <span class=\"label-inf\">{{ labelInferior }}</span>\r\n }\r\n @if ((errorText || labelInferior) && ((!isFocused && isAlertText && !disabled) || (error && !disabled))) {\r\n <span class=\"label-inf\" [ngClass]=\"{ alert: (!isFocused && isAlertText && !disabled) || (error && !disabled) }\">\r\n {{ errorText ?? labelInferior }}\r\n </span>\r\n }\r\n\r\n <!-- Lista de opciones -->\r\n @if (showList) {\r\n <div class=\"container-options\">\r\n <div class=\"container-list scrollable-small\">\r\n <div (click)=\"onSelectOption()\">\r\n <ng-content selector=\"ius-option\"></ng-content>\r\n </div>\r\n </div>\r\n <ius-simple-divider></ius-simple-divider>\r\n <div class=\"add-data\">\r\n <div class=\"container-text\">\r\n <input\r\n type=\"text\"\r\n class=\"input-text\"\r\n [(ngModel)]=\"element\"\r\n (keypress)=\"onKeyPressAddElement($event)\"\r\n [placeholder]=\"placeholderAddText\"\r\n />\r\n </div>\r\n <div class=\"button-add-option\">\r\n <ius-button-standard-tertiary\r\n [iconName]=\"iconBtnAdd\"\r\n (click)=\"onClickAddElement()\"\r\n >\r\n {{ textBtnAdd }}\r\n </ius-button-standard-tertiary>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n</div>", styles: [".h1{font-family:Roboto,sans-serif;font-size:2.375rem;font-weight:500;line-height:46px}.h2{font-family:Roboto,sans-serif;font-size:1.875rem;font-weight:700;line-height:38px}.h3{font-family:Roboto,sans-serif;font-size:1.5rem;font-weight:500;line-height:32px}.h4{font-family:Roboto,sans-serif;font-size:1.25rem;font-weight:700;line-height:26px}.h5{font-family:Roboto,sans-serif;font-size:1.125rem;font-weight:500;line-height:24px;letter-spacing:.18px}.label-large{font-family:Roboto,sans-serif;font-size:1rem;font-weight:500;line-height:22px}.body-large{font-family:Rubik,sans-serif;font-size:1rem;font-weight:400;line-height:22px}.label-base{font-family:Rubik,sans-serif;font-size:.875rem;font-weight:500;line-height:20px;letter-spacing:.28px}.body-base{font-family:Rubik,sans-serif;font-size:.875rem;font-weight:400;line-height:20px;font-style:italic;letter-spacing:.28px}.body-base-1,.body-base-1-1{font-family:Rubik,sans-serif;font-size:.875rem;font-weight:400;line-height:20px;letter-spacing:.28px}.body-sm{font-family:Rubik,sans-serif;font-size:.75rem;font-weight:400;line-height:16px;letter-spacing:.28px}.body-sm-italic{font-family:Rubik,sans-serif;font-size:.75rem;font-weight:400;line-height:16px;font-style:italic;letter-spacing:.28px}.caption-sm{font-family:Rubik,sans-serif;font-size:.75rem;font-weight:500;line-height:16px;letter-spacing:.28px}.caption-sm-italic{font-family:Rubik,sans-serif;font-size:.75rem;font-weight:500;line-height:16px;font-style:italic;letter-spacing:.28px}.container-general{position:relative;height:100%}.container-textfield{display:flex;padding:10px 12px;justify-content:center;align-items:flex-start;gap:4px;border:1px solid #f5f5f5;border-radius:8px;background:#f5f5f5;font-family:Rubik,sans-serif;font-size:.875rem;font-weight:400;line-height:20px;letter-spacing:.28px}.container-textfield:hover:not(.disabled):not(.focused):not(.alert){background:#edf6ff}.container-textfield.focused{border:1px solid #0581BC;background:#edf6ff}.container-textfield.disabled{background:#f5f5f5}.container-textfield.disabled .icon-color,.container-textfield.disabled .icon-arrows{color:#bfbfbf}.container-textfield.disabled input::placeholder{color:#bfbfbf;opacity:1}.container-textfield.alert{border:1px solid #DB2E2A;background:#fff4f0}.icon-color{color:#595959}.icon-arrows{color:#333}.icon-color-help{color:#8c8c8c}input{display:flex;align-items:center;flex:1 0 0;border:none;outline:none;background-color:transparent;font-family:Rubik,sans-serif;font-size:.875rem;font-weight:400;line-height:20px;letter-spacing:.28px}.cnt-icon-right{display:flex;align-items:center;justify-content:center;background:none;padding:0;color:#333}.container-label-sup{display:flex;align-items:center;gap:4px;margin-bottom:8px;color:#333;font-family:Roboto,sans-serif;font-size:.875rem;font-weight:500;line-height:20px;letter-spacing:.28px}.container-label-sup.disabled{color:#bfbfbf}.icon-dot{display:flex;align-items:center;width:4px;height:4px;aspect-ratio:1/1;background-color:#db2e2a;border-radius:100px}.label-inf{display:flex;position:absolute;margin-top:4px;color:#595959;font-family:Roboto,sans-serif;font-size:.75rem;font-style:italic;font-weight:500;line-height:16px;letter-spacing:.24px}.label-inf.alert{color:#931224}.container-options{position:absolute;width:100%;margin-top:4px;border-radius:8px;background:#fff;box-shadow:0 2px 6px #00000024,0 1px 10px #0000001a;z-index:1000}.container-list{max-height:144px;display:flex;flex-direction:column;margin-top:4px;overflow-y:auto}.add-data{display:flex;padding-top:8px;padding-bottom:8px;align-items:center;gap:10px;width:100%;background:#fff;border-radius:8px}.add-data .container-text{display:flex;width:60%;align-items:flex-start;gap:4px}.add-data .container-text .input-text{width:100%;display:flex;margin-left:10px;padding:12px;justify-content:center;align-items:flex-start;gap:4px;border-radius:8px;background:#f5f5f5}.add-data .button-add-option{margin-right:10px;width:40%}.scrollable-small::-webkit-scrollbar{-webkit-appearance:none}.scrollable-small::-webkit-scrollbar:vertical{width:4px;height:32px;padding-top:2px;padding-bottom:2px}.scrollable-small::-webkit-scrollbar:horizontal{height:5px;padding-top:2px;padding-bottom:2px}.scrollable-small::-webkit-scrollbar-thumb{background-color:#08a6db;border-radius:4px}\n"] }]
106
- }], propDecorators: { componentId: [{
207
+ ], template: "<div class=\"container-general\" [id]=\"componentId\">\n\n <!-- Label superior -->\n @if (labelSuperior) {\n <div class=\"container-label-sup\" [ngClass]=\"{ disabled: disabled }\">\n @if (!disabled && required) {\n <div class=\"icon-dot\"></div>\n }\n <span>{{ labelSuperior }}</span>\n @if (!disabled && showHelpText) {\n <ius-icon-md iconName=\"icon-help\" class=\"icon-color-help\"></ius-icon-md>\n }\n <span>:</span>\n </div>\n }\n\n <!-- Input principal -->\n <div\n class=\"container-textfield\"\n [ngClass]=\"{\n disabled: disabled,\n focused: isFocused,\n alert: (!isFocused && isAlertText && !disabled) || (error && !disabled)\n }\"\n (click)=\"onFocus()\"\n >\n @if (iconInput) {\n <ius-icon-md [iconName]=\"iconInput\" class=\"icon-color\"></ius-icon-md>\n }\n <input\n type=\"text\"\n [(ngModel)]=\"textInput\"\n [placeholder]=\"labelInput\"\n [disabled]=\"disabled\"\n (input)=\"onInput()\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n (keypress)=\"onKeyPress($event)\"\n />\n <div class=\"cnt-icon-right\">\n @if (!showList) {\n <ius-icon-md iconName=\"icon-keyboard-arrow-down\" class=\"icon-arrows\"></ius-icon-md>\n } @else {\n <div (click)=\"closeList($event)\" style=\"height: 20px;\">\n <ius-icon-md iconName=\"icon-keyboard-arrow-up\" class=\"icon-arrows\"></ius-icon-md>\n </div>\n }\n </div>\n </div>\n\n <!-- Label inferior -->\n @if (labelInferior && isFocused && !error) {\n <span class=\"label-inf\">{{ labelInferior }}</span>\n }\n @if ((errorText || labelInferior) && ((!isFocused && isAlertText && !disabled) || (error && !disabled))) {\n <span class=\"label-inf\" [ngClass]=\"{ alert: (!isFocused && isAlertText && !disabled) || (error && !disabled) }\">\n {{ errorText ?? labelInferior }}\n </span>\n }\n\n <!-- Lista de opciones (CDK overlay) -->\n <ng-template #listPanel>\n <div class=\"container-options\">\n <div class=\"container-list scrollable-small\" (scroll)=\"onListScroll($event)\">\n <div (click)=\"onSelectOption()\">\n <ng-content selector=\"ius-option\"></ng-content>\n </div>\n @if (loading) {\n <div class=\"cnt-loading-option\">Cargando\u2026</div>\n }\n </div>\n <ius-simple-divider></ius-simple-divider>\n <div class=\"add-data\">\n <div class=\"container-text\">\n <input\n type=\"text\"\n class=\"input-text\"\n [(ngModel)]=\"element\"\n (keypress)=\"onKeyPressAddElement($event)\"\n [placeholder]=\"placeholderAddText\"\n />\n </div>\n <div class=\"button-add-option\">\n <ius-button-standard-tertiary\n [iconName]=\"iconBtnAdd\"\n (click)=\"onClickAddElement()\"\n >\n {{ textBtnAdd }}\n </ius-button-standard-tertiary>\n </div>\n </div>\n </div>\n </ng-template>\n\n</div>\n", styles: [".h1{font-family:Roboto,sans-serif;font-size:2.375rem;font-weight:500;line-height:46px}.h2{font-family:Roboto,sans-serif;font-size:1.875rem;font-weight:700;line-height:38px}.h3{font-family:Roboto,sans-serif;font-size:1.5rem;font-weight:500;line-height:32px}.h4{font-family:Roboto,sans-serif;font-size:1.25rem;font-weight:700;line-height:26px}.h5{font-family:Roboto,sans-serif;font-size:1.125rem;font-weight:500;line-height:24px;letter-spacing:.18px}.label-large{font-family:Roboto,sans-serif;font-size:1rem;font-weight:500;line-height:22px}.body-large{font-family:Rubik,sans-serif;font-size:1rem;font-weight:400;line-height:22px}.label-base{font-family:Rubik,sans-serif;font-size:.875rem;font-weight:500;line-height:20px;letter-spacing:.28px}.body-base{font-family:Rubik,sans-serif;font-size:.875rem;font-weight:400;line-height:20px;font-style:italic;letter-spacing:.28px}.body-base-1,.body-base-1-1{font-family:Rubik,sans-serif;font-size:.875rem;font-weight:400;line-height:20px;letter-spacing:.28px}.body-sm{font-family:Rubik,sans-serif;font-size:.75rem;font-weight:400;line-height:16px;letter-spacing:.28px}.body-sm-italic{font-family:Rubik,sans-serif;font-size:.75rem;font-weight:400;line-height:16px;font-style:italic;letter-spacing:.28px}.caption-sm{font-family:Rubik,sans-serif;font-size:.75rem;font-weight:500;line-height:16px;letter-spacing:.28px}.caption-sm-italic{font-family:Rubik,sans-serif;font-size:.75rem;font-weight:500;line-height:16px;font-style:italic;letter-spacing:.28px}.container-general{position:relative;height:100%}.container-textfield{display:flex;padding:10px 12px;justify-content:center;align-items:flex-start;gap:4px;border:1px solid #f5f5f5;border-radius:8px;background:#f5f5f5;font-family:Rubik,sans-serif;font-size:.875rem;font-weight:400;line-height:20px;letter-spacing:.28px}.container-textfield:hover:not(.disabled):not(.focused):not(.alert){background:#edf6ff}.container-textfield.focused{border:1px solid #0581BC;background:#edf6ff}.container-textfield.disabled{background:#f5f5f5}.container-textfield.disabled .icon-color,.container-textfield.disabled .icon-arrows{color:#bfbfbf}.container-textfield.disabled input::placeholder{color:#bfbfbf;opacity:1}.container-textfield.alert{border:1px solid #DB2E2A;background:#fff4f0}.icon-color{color:#595959}.icon-arrows{color:#333}.icon-color-help{color:#8c8c8c}input{display:flex;align-items:center;flex:1 0 0;border:none;outline:none;background-color:transparent;font-family:Rubik,sans-serif;font-size:.875rem;font-weight:400;line-height:20px;letter-spacing:.28px}.cnt-icon-right{display:flex;align-items:center;justify-content:center;background:none;padding:0;color:#333}.container-label-sup{display:flex;align-items:center;gap:4px;margin-bottom:8px;color:#333;font-family:Roboto,sans-serif;font-size:.875rem;font-weight:500;line-height:20px;letter-spacing:.28px}.container-label-sup.disabled{color:#bfbfbf}.icon-dot{display:flex;align-items:center;width:4px;height:4px;aspect-ratio:1/1;background-color:#db2e2a;border-radius:100px}.label-inf{display:flex;position:absolute;margin-top:4px;color:#595959;font-family:Roboto,sans-serif;font-size:.75rem;font-style:italic;font-weight:500;line-height:16px;letter-spacing:.24px}.label-inf.alert{color:#931224}.container-options{width:100%;border-radius:8px;background:#fff;box-shadow:0 2px 6px #00000024,0 1px 10px #0000001a}.container-list{max-height:144px;display:flex;flex-direction:column;margin-top:4px;overflow-y:auto}.add-data{display:flex;padding-top:8px;padding-bottom:8px;align-items:center;gap:10px;width:100%;background:#fff;border-radius:8px}.add-data .container-text{display:flex;width:60%;align-items:flex-start;gap:4px}.add-data .container-text .input-text{width:100%;display:flex;margin-left:10px;padding:12px;justify-content:center;align-items:flex-start;gap:4px;border-radius:8px;background:#f5f5f5}.add-data .button-add-option{margin-right:10px;width:40%}.scrollable-small::-webkit-scrollbar{-webkit-appearance:none}.scrollable-small::-webkit-scrollbar:vertical{width:4px;height:32px;padding-top:2px;padding-bottom:2px}.scrollable-small::-webkit-scrollbar:horizontal{height:5px;padding-top:2px;padding-bottom:2px}.scrollable-small::-webkit-scrollbar-thumb{background-color:#08a6db;border-radius:4px}\n"] }]
208
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.Overlay }, { type: i0.ViewContainerRef }], propDecorators: { listPanel: [{
209
+ type: ViewChild,
210
+ args: ['listPanel']
211
+ }], componentId: [{
107
212
  type: Input,
108
213
  args: [{ required: true }]
109
214
  }], required: [{
@@ -134,6 +239,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
134
239
  type: Input
135
240
  }], element: [{
136
241
  type: Input
242
+ }], debounceMs: [{
243
+ type: Input
244
+ }], enableInfiniteScroll: [{
245
+ type: Input
246
+ }], loading: [{
247
+ type: Input
137
248
  }], onChangesValueEvent: [{
138
249
  type: Output
139
250
  }], onEnterKey: [{
@@ -142,8 +253,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
142
253
  type: Output
143
254
  }], onBlurEvent: [{
144
255
  type: Output
256
+ }], onFocusEvent: [{
257
+ type: Output
258
+ }], onScrolledToEnd: [{
259
+ type: Output
145
260
  }], onClickOutside: [{
146
261
  type: HostListener,
147
262
  args: ['document:click', ['$event']]
148
263
  }] } });
149
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tLWRyb3Bkb3duLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2l1cy1kZXNpZ24tY29tcG9uZW50cy9zcmMvbGliL2N1c3RvbS1kcm9wZG93bi9jdXN0b20tZHJvcGRvd24uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaXVzLWRlc2lnbi1jb21wb25lbnRzL3NyYy9saWIvY3VzdG9tLWRyb3Bkb3duL2N1c3RvbS1kcm9wZG93bi5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNyRixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDL0QsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsK0JBQStCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQzs7OztBQWU5RSxNQUFNLE9BQU8sdUJBQXVCO0lBYnBDO1FBZUUsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUNsQixnQkFBVyxHQUFHLEtBQUssQ0FBQztRQUNwQixhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ2pCLHFCQUFnQixHQUFHLEtBQUssQ0FBQztRQUN6QixhQUFRLEdBQUcsS0FBSyxDQUFDO1FBRVUsZ0JBQVcsR0FBVyxFQUFFLENBQUM7UUFDM0MsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ2pCLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLFVBQUssR0FBWSxLQUFLLENBQUM7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SztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBRUksbUJBQW1CO3NCQUE1QixNQUFNO2dCQUNHLFVBQVU7c0JBQW5CLE1BQU07Z0JBQ0csWUFBWTtzQkFBckIsTUFBTTtnQkFDRyxXQUFXO3NCQUFwQixNQUFNO2dCQUdQLGNBQWM7c0JBRGIsWUFBWTt1QkFBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBIb3N0TGlzdGVuZXIsIElucHV0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgSWNvbk1kQ29tcG9uZW50IH0gZnJvbSAnLi4vaWNvbi1tZC9pY29uLW1kLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBTaW1wbGVEaXZpZGVyQ29tcG9uZW50IH0gZnJvbSAnLi4vc2ltcGxlLWRpdmlkZXInO1xyXG5pbXBvcnQgeyBCdXR0b25TdGFuZGFyZFRlcnRpYXJ5Q29tcG9uZW50IH0gZnJvbSAnLi4vYnV0dG9uLXN0YW5kYXJkLXRlcnRpYXJ5JztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnaXVzLWN1c3RvbS1kcm9wZG93bicsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbXHJcbiAgICBJY29uTWRDb21wb25lbnQsXHJcbiAgICBGb3Jtc01vZHVsZSxcclxuICAgIENvbW1vbk1vZHVsZSxcclxuICAgIFNpbXBsZURpdmlkZXJDb21wb25lbnQsXHJcbiAgICBCdXR0b25TdGFuZGFyZFRlcnRpYXJ5Q29tcG9uZW50XHJcbiAgXSxcclxuICB0ZW1wbGF0ZVVybDogJy4vY3VzdG9tLWRyb3Bkb3duLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybDogJy4vY3VzdG9tLWRyb3Bkb3duLmNvbXBvbmVudC5zY3NzJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgQ3VzdG9tRHJvcGRvd25Db21wb25lbnQge1xyXG5cclxuICBpc0ZvY3VzZWQgPSBmYWxzZTtcclxuICBpc0FsZXJ0VGV4dCA9IGZhbHNlO1xyXG4gIHNob3dMaXN0ID0gZmFsc2U7XHJcbiAgaGFzQ2xpY2tlZEluc2lkZSA9IGZhbHNlO1xyXG4gIHNlbGVjdGVkID0gZmFsc2U7XHJcblxyXG4gIEBJbnB1dCh7IHJlcXVpcmVkOiB0cnVlIH0pIGNvbXBvbmVudElkOiBzdHJpbmcgPSAnJztcclxuICBASW5wdXQoKSByZXF1aXJlZCA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIGRpc2FibGVkID0gZmFsc2U7XHJcbiAgQElucHV0KCkgc2hvd0hlbHBUZXh0ID0gZmFsc2U7XHJcbiAgQElucHV0KCkgZXJyb3I6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgQElucHV0KCkgbGFiZWxTdXBlcmlvcj86IHN0cmluZztcclxuICBASW5wdXQoKSBsYWJlbEluZmVyaW9yPzogc3RyaW5nO1xyXG4gIEBJbnB1dCgpIGVycm9yVGV4dD86IHN0cmluZztcclxuICBASW5wdXQoKSBsYWJlbElucHV0Pzogc3RyaW5nO1xyXG4gIEBJbnB1dCgpIGljb25JbnB1dD86IHN0cmluZztcclxuXHJcbiAgQElucHV0KCkgcGxhY2Vob2xkZXJBZGRUZXh0ID0gJ0RpZ2l0ZSB1bmEgbnVldmEnO1xyXG4gIEBJbnB1dCgpIGljb25CdG5BZGQgPSAnaWNvbi1hZGQnO1xyXG4gIEBJbnB1dCgpIHRleHRCdG5BZGQgPSAnQWdyZWdhcic7XHJcblxyXG4gIEBJbnB1dCgpIHRleHRJbnB1dCA9ICcnO1xyXG4gIEBJbnB1dCgpIGVsZW1lbnQgPSAnJztcclxuXHJcbiAgQE91dHB1dCgpIG9uQ2hhbmdlc1ZhbHVlRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICBAT3V0cHV0KCkgb25FbnRlcktleSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xyXG4gIEBPdXRwdXQoKSBvbkFkZEVsZW1lbnQgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcclxuICBAT3V0cHV0KCkgb25CbHVyRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJywgWyckZXZlbnQnXSlcclxuICBvbkNsaWNrT3V0c2lkZShldmVudDogRXZlbnQpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5oYXNDbGlja2VkSW5zaWRlKSByZXR1cm47XHJcblxyXG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xyXG4gICAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5jb21wb25lbnRJZCk7XHJcblxyXG4gICAgaWYgKGNvbnRhaW5lciAmJiAhY29udGFpbmVyLmNvbnRhaW5zKHRhcmdldCkpIHtcclxuICAgICAgdGhpcy5pc0ZvY3VzZWQgPSBmYWxzZTtcclxuICAgICAgdGhpcy5zaG93TGlzdCA9IGZhbHNlO1xyXG4gICAgICB0aGlzLmlzQWxlcnRUZXh0ID0gIXRoaXMuc2VsZWN0ZWQgJiYgIXRoaXMuc2hvd0xpc3Q7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBvbklucHV0KCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuc2VsZWN0ZWQpIHRoaXMuc2VsZWN0ZWQgPSBmYWxzZTtcclxuICAgIHRoaXMub25DaGFuZ2VzVmFsdWVFdmVudC5lbWl0KHRoaXMudGV4dElucHV0KTtcclxuICB9XHJcblxyXG4gIG9uRm9jdXMoKTogdm9pZCB7XHJcbiAgICB0aGlzLmlzRm9jdXNlZCA9IHRydWU7XHJcbiAgICB0aGlzLnNob3dMaXN0ID0gdHJ1ZTtcclxuICAgIHRoaXMuaGFzQ2xpY2tlZEluc2lkZSA9IHRydWU7XHJcbiAgfVxyXG5cclxuICBvbkJsdXIoKTogdm9pZCB7XHJcbiAgICB0aGlzLmlzRm9jdXNlZCA9IGZhbHNlO1xyXG4gICAgaWYgKHRoaXMucmVxdWlyZWQpIHtcclxuICAgICAgdGhpcy5pc0FsZXJ0VGV4dCA9IHRoaXMudGV4dElucHV0ID09PSAnJztcclxuICAgIH1cclxuICAgIHRoaXMub25CbHVyRXZlbnQuZW1pdCgpO1xyXG4gIH1cclxuXHJcbiAgb25LZXlQcmVzcyhldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xyXG4gICAgaWYgKGV2ZW50LmtleSA9PT0gJ0VudGVyJykgdGhpcy5hZGRUZXh0KCk7XHJcbiAgfVxyXG5cclxuICBvbktleVByZXNzQWRkRWxlbWVudChldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xyXG4gICAgaWYgKGV2ZW50LmtleSA9PT0gJ0VudGVyJykgdGhpcy5hZGRFbGVtZW50VGV4dCgpO1xyXG4gIH1cclxuXHJcbiAgb25DbGlja0FkZEVsZW1lbnQoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5lbGVtZW50LnRyaW0oKSAhPT0gJycpIHtcclxuICAgICAgdGhpcy5vbkFkZEVsZW1lbnQuZW1pdCh0aGlzLmVsZW1lbnQpO1xyXG4gICAgICB0aGlzLmVsZW1lbnQgPSAnJztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuaXNBbGVydFRleHQgPSB0cnVlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgYWRkRWxlbWVudFRleHQoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5lbGVtZW50LnRyaW0oKSAhPT0gJycpIHtcclxuICAgICAgdGhpcy5vbkFkZEVsZW1lbnQuZW1pdCh0aGlzLmVsZW1lbnQpO1xyXG4gICAgICB0aGlzLmVsZW1lbnQgPSAnJztcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGFkZFRleHQoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy50ZXh0SW5wdXQudHJpbSgpICE9PSAnJykge1xyXG4gICAgICB0aGlzLm9uRW50ZXJLZXkuZW1pdCh0aGlzLnRleHRJbnB1dCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBvblNlbGVjdE9wdGlvbigpOiB2b2lkIHtcclxuICAgIHRoaXMuaXNGb2N1c2VkID0gZmFsc2U7XHJcbiAgICB0aGlzLnNob3dMaXN0ID0gZmFsc2U7XHJcbiAgICB0aGlzLmlzQWxlcnRUZXh0ID0gZmFsc2U7XHJcbiAgICB0aGlzLnNlbGVjdGVkID0gdHJ1ZTtcclxuICB9XHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cImNvbnRhaW5lci1nZW5lcmFsXCIgW2lkXT1cImNvbXBvbmVudElkXCI+XHJcblxyXG4gIDwhLS0gTGFiZWwgc3VwZXJpb3IgLS0+XHJcbiAgQGlmIChsYWJlbFN1cGVyaW9yKSB7XHJcbiAgICA8ZGl2IGNsYXNzPVwiY29udGFpbmVyLWxhYmVsLXN1cFwiIFtuZ0NsYXNzXT1cInsgZGlzYWJsZWQ6IGRpc2FibGVkIH1cIj5cclxuICAgICAgQGlmICghZGlzYWJsZWQgJiYgcmVxdWlyZWQpIHtcclxuICAgICAgICA8ZGl2IGNsYXNzPVwiaWNvbi1kb3RcIj48L2Rpdj5cclxuICAgICAgfVxyXG4gICAgICA8c3Bhbj57eyBsYWJlbFN1cGVyaW9yIH19PC9zcGFuPlxyXG4gICAgICBAaWYgKCFkaXNhYmxlZCAmJiBzaG93SGVscFRleHQpIHtcclxuICAgICAgICA8aXVzLWljb24tbWQgaWNvbk5hbWU9XCJpY29uLWhlbHBcIiBjbGFzcz1cImljb24tY29sb3ItaGVscFwiPjwvaXVzLWljb24tbWQ+XHJcbiAgICAgIH1cclxuICAgICAgPHNwYW4+Ojwvc3Bhbj5cclxuICAgIDwvZGl2PlxyXG4gIH1cclxuXHJcbiAgPCEtLSBJbnB1dCBwcmluY2lwYWwgLS0+XHJcbiAgPGRpdlxyXG4gICAgY2xhc3M9XCJjb250YWluZXItdGV4dGZpZWxkXCJcclxuICAgIFtuZ0NsYXNzXT1cIntcclxuICAgICAgZGlzYWJsZWQ6IGRpc2FibGVkLFxyXG4gICAgICBmb2N1c2VkOiBpc0ZvY3VzZWQsXHJcbiAgICAgIGFsZXJ0OiAoIWlzRm9jdXNlZCAmJiBpc0FsZXJ0VGV4dCAmJiAhZGlzYWJsZWQpIHx8IChlcnJvciAmJiAhZGlzYWJsZWQpXHJcbiAgICB9XCJcclxuICA+XHJcbiAgICBAaWYgKGljb25JbnB1dCkge1xyXG4gICAgICA8aXVzLWljb24tbWQgW2ljb25OYW1lXT1cImljb25JbnB1dFwiIGNsYXNzPVwiaWNvbi1jb2xvclwiPjwvaXVzLWljb24tbWQ+XHJcbiAgICB9XHJcbiAgICA8aW5wdXRcclxuICAgICAgdHlwZT1cInRleHRcIlxyXG4gICAgICBbKG5nTW9kZWwpXT1cInRleHRJbnB1dFwiXHJcbiAgICAgIFtwbGFjZWhvbGRlcl09XCJsYWJlbElucHV0XCJcclxuICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcclxuICAgICAgKGlucHV0KT1cIm9uSW5wdXQoKVwiXHJcbiAgICAgIChmb2N1cyk9XCJvbkZvY3VzKClcIlxyXG4gICAgICAoYmx1cik9XCJvbkJsdXIoKVwiXHJcbiAgICAgIChrZXlwcmVzcyk9XCJvbktleVByZXNzKCRldmVudClcIlxyXG4gICAgLz5cclxuICAgIDxkaXYgY2xhc3M9XCJjbnQtaWNvbi1yaWdodFwiPlxyXG4gICAgICBAaWYgKCFzaG93TGlzdCkge1xyXG4gICAgICAgIDxpdXMtaWNvbi1tZCBpY29uTmFtZT1cImljb24ta2V5Ym9hcmQtYXJyb3ctZG93blwiIGNsYXNzPVwiaWNvbi1hcnJvd3NcIj48L2l1cy1pY29uLW1kPlxyXG4gICAgICB9IEBlbHNlIHtcclxuICAgICAgICA8aXVzLWljb24tbWQgaWNvbk5hbWU9XCJpY29uLWtleWJvYXJkLWFycm93LXVwXCIgY2xhc3M9XCJpY29uLWFycm93c1wiPjwvaXVzLWljb24tbWQ+XHJcbiAgICAgIH1cclxuICAgIDwvZGl2PlxyXG4gIDwvZGl2PlxyXG5cclxuICA8IS0tIExhYmVsIGluZmVyaW9yIC0tPlxyXG4gIEBpZiAobGFiZWxJbmZlcmlvciAmJiBpc0ZvY3VzZWQgJiYgIWVycm9yKSB7XHJcbiAgICA8c3BhbiBjbGFzcz1cImxhYmVsLWluZlwiPnt7IGxhYmVsSW5mZXJpb3IgfX08L3NwYW4+XHJcbiAgfVxyXG4gIEBpZiAoKGVycm9yVGV4dCB8fCBsYWJlbEluZmVyaW9yKSAmJiAoKCFpc0ZvY3VzZWQgJiYgaXNBbGVydFRleHQgJiYgIWRpc2FibGVkKSB8fCAoZXJyb3IgJiYgIWRpc2FibGVkKSkpIHtcclxuICAgIDxzcGFuIGNsYXNzPVwibGFiZWwtaW5mXCIgW25nQ2xhc3NdPVwieyBhbGVydDogKCFpc0ZvY3VzZWQgJiYgaXNBbGVydFRleHQgJiYgIWRpc2FibGVkKSB8fCAoZXJyb3IgJiYgIWRpc2FibGVkKSB9XCI+XHJcbiAgICAgIHt7IGVycm9yVGV4dCA/PyBsYWJlbEluZmVyaW9yIH19XHJcbiAgICA8L3NwYW4+XHJcbiAgfVxyXG5cclxuICA8IS0tIExpc3RhIGRlIG9wY2lvbmVzIC0tPlxyXG4gIEBpZiAoc2hvd0xpc3QpIHtcclxuICAgIDxkaXYgY2xhc3M9XCJjb250YWluZXItb3B0aW9uc1wiPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiY29udGFpbmVyLWxpc3Qgc2Nyb2xsYWJsZS1zbWFsbFwiPlxyXG4gICAgICAgIDxkaXYgKGNsaWNrKT1cIm9uU2VsZWN0T3B0aW9uKClcIj5cclxuICAgICAgICAgIDxuZy1jb250ZW50IHNlbGVjdG9yPVwiaXVzLW9wdGlvblwiPjwvbmctY29udGVudD5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDxpdXMtc2ltcGxlLWRpdmlkZXI+PC9pdXMtc2ltcGxlLWRpdmlkZXI+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJhZGQtZGF0YVwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb250YWluZXItdGV4dFwiPlxyXG4gICAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcclxuICAgICAgICAgICAgY2xhc3M9XCJpbnB1dC10ZXh0XCJcclxuICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJlbGVtZW50XCJcclxuICAgICAgICAgICAgKGtleXByZXNzKT1cIm9uS2V5UHJlc3NBZGRFbGVtZW50KCRldmVudClcIlxyXG4gICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJBZGRUZXh0XCJcclxuICAgICAgICAgIC8+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImJ1dHRvbi1hZGQtb3B0aW9uXCI+XHJcbiAgICAgICAgICA8aXVzLWJ1dHRvbi1zdGFuZGFyZC10ZXJ0aWFyeVxyXG4gICAgICAgICAgICBbaWNvbk5hbWVdPVwiaWNvbkJ0bkFkZFwiXHJcbiAgICAgICAgICAgIChjbGljayk9XCJvbkNsaWNrQWRkRWxlbWVudCgpXCJcclxuICAgICAgICAgID5cclxuICAgICAgICAgICAge3sgdGV4dEJ0bkFkZCB9fVxyXG4gICAgICAgICAgPC9pdXMtYnV0dG9uLXN0YW5kYXJkLXRlcnRpYXJ5PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gIH1cclxuXHJcbjwvZGl2PiJdfQ==
264
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tLWRyb3Bkb3duLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2l1cy1kZXNpZ24tY29tcG9uZW50cy9zcmMvbGliL2N1c3RvbS1kcm9wZG93bi9jdXN0b20tZHJvcGRvd24uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaXVzLWRlc2lnbi1jb21wb25lbnRzL3NyYy9saWIvY3VzdG9tLWRyb3Bkb3duL2N1c3RvbS1kcm9wZG93bi5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFjLFlBQVksRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFhLE1BQU0sRUFBZSxTQUFTLEVBQW9CLE1BQU0sZUFBZSxDQUFDO0FBRXRKLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDL0QsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsK0JBQStCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQzs7Ozs7QUFlOUUsTUFBTSxPQUFPLHVCQUF1QjtJQWFsQyxJQUFJLFFBQVE7UUFDVixPQUFPLElBQUksQ0FBQyxXQUFXLEtBQUssSUFBSSxDQUFDO0lBQ25DLENBQUM7SUFnQ0QsWUFDbUIsR0FBZSxFQUNmLFFBQWlCLEVBQ2pCLElBQXNCO1FBRnRCLFFBQUcsR0FBSCxHQUFHLENBQVk7UUFDZixhQUFRLEdBQVIsUUFBUSxDQUFTO1FBQ2pCLFNBQUksR0FBSixJQUFJLENBQWtCO1FBaER6QyxjQUFTLEdBQUcsS0FBSyxDQUFDO1FB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dCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBIb3N0TGlzdGVuZXIsIElucHV0LCBPbkRlc3Ryb3ksIE91dHB1dCwgVGVtcGxhdGVSZWYsIFZpZXdDaGlsZCwgVmlld0NvbnRhaW5lclJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT3ZlcmxheSwgT3ZlcmxheVJlZiB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9vdmVybGF5JztcbmltcG9ydCB7IFRlbXBsYXRlUG9ydGFsIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3BvcnRhbCc7XG5pbXBvcnQgeyBJY29uTWRDb21wb25lbnQgfSBmcm9tICcuLi9pY29uLW1kL2ljb24tbWQuY29tcG9uZW50JztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFNpbXBsZURpdmlkZXJDb21wb25lbnQgfSBmcm9tICcuLi9zaW1wbGUtZGl2aWRlcic7XG5pbXBvcnQgeyBCdXR0b25TdGFuZGFyZFRlcnRpYXJ5Q29tcG9uZW50IH0gZnJvbSAnLi4vYnV0dG9uLXN0YW5kYXJkLXRlcnRpYXJ5JztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnaXVzLWN1c3RvbS1kcm9wZG93bicsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBJY29uTWRDb21wb25lbnQsXG4gICAgRm9ybXNNb2R1bGUsXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIFNpbXBsZURpdmlkZXJDb21wb25lbnQsXG4gICAgQnV0dG9uU3RhbmRhcmRUZXJ0aWFyeUNvbXBvbmVudFxuICBdLFxuICB0ZW1wbGF0ZVVybDogJy4vY3VzdG9tLWRyb3Bkb3duLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL2N1c3RvbS1kcm9wZG93bi5jb21wb25lbnQuc2Nzcydcbn0pXG5leHBvcnQgY2xhc3MgQ3VzdG9tRHJvcGRvd25Db21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuXG4gIGlzRm9jdXNlZCA9IGZhbHNlO1xuICBpc0FsZXJ0VGV4dCA9IGZhbHNlO1xuICBoYXNDbGlja2VkSW5zaWRlID0gZmFsc2U7XG4gIHNlbGVjdGVkID0gZmFsc2U7XG5cbiAgQFZpZXdDaGlsZCgnbGlzdFBhbmVsJykgcHJpdmF0ZSBsaXN0UGFuZWwhOiBUZW1wbGF0ZVJlZjx1bmtub3duPjtcbiAgcHJpdmF0ZSBfb3ZlcmxheVJlZjogT3ZlcmxheVJlZiB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIF9zY3JvbGxMaXN0ZW5lciA9ICgpOiB2b2lkID0+IHsgdGhpcy5fb3ZlcmxheVJlZj8udXBkYXRlUG9zaXRpb24oKTsgfTtcbiAgcHJpdmF0ZSBfZGVib3VuY2VUaW1lcjogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfc2Nyb2xsZWRFbmRDb29sZG93biA9IGZhbHNlO1xuXG4gIGdldCBzaG93TGlzdCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fb3ZlcmxheVJlZiAhPT0gbnVsbDtcbiAgfVxuXG4gIEBJbnB1dCh7IHJlcXVpcmVkOiB0cnVlIH0pIGNvbXBvbmVudElkOiBzdHJpbmcgPSAnJztcbiAgQElucHV0KCkgcmVxdWlyZWQgPSBmYWxzZTtcbiAgQElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcbiAgQElucHV0KCkgc2hvd0hlbHBUZXh0ID0gZmFsc2U7XG4gIEBJbnB1dCgpIGVycm9yOiBib29sZWFuID0gZmFsc2U7XG5cbiAgQElucHV0KCkgbGFiZWxTdXBlcmlvcj86IHN0cmluZztcbiAgQElucHV0KCkgbGFiZWxJbmZlcmlvcj86IHN0cmluZztcbiAgQElucHV0KCkgZXJyb3JUZXh0Pzogc3RyaW5nO1xuICBASW5wdXQoKSBsYWJlbElucHV0Pzogc3RyaW5nO1xuICBASW5wdXQoKSBpY29uSW5wdXQ/OiBzdHJpbmc7XG5cbiAgQElucHV0KCkgcGxhY2Vob2xkZXJBZGRUZXh0ID0gJ0RpZ2l0ZSB1bmEgbnVldmEnO1xuICBASW5wdXQoKSBpY29uQnRuQWRkID0gJ2ljb24tYWRkJztcbiAgQElucHV0KCkgdGV4dEJ0bkFkZCA9ICdBZ3JlZ2FyJztcblxuICBASW5wdXQoKSB0ZXh0SW5wdXQgPSAnJztcbiAgQElucHV0KCkgZWxlbWVudCA9ICcnO1xuXG4gIEBJbnB1dCgpIGRlYm91bmNlTXM6IG51bWJlciA9IDMwMDtcbiAgQElucHV0KCkgZW5hYmxlSW5maW5pdGVTY3JvbGwgPSBmYWxzZTtcbiAgQElucHV0KCkgbG9hZGluZyA9IGZhbHNlO1xuXG4gIEBPdXRwdXQoKSBvbkNoYW5nZXNWYWx1ZUV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoKSBvbkVudGVyS2V5ID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG4gIEBPdXRwdXQoKSBvbkFkZEVsZW1lbnQgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgQE91dHB1dCgpIG9uQmx1ckV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICBAT3V0cHV0KCkgb25Gb2N1c0V2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICBAT3V0cHV0KCkgb25TY3JvbGxlZFRvRW5kID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2VsOiBFbGVtZW50UmVmLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX292ZXJsYXk6IE92ZXJsYXksXG4gICAgcHJpdmF0ZSByZWFkb25seSBfdmNyOiBWaWV3Q29udGFpbmVyUmVmXG4gICkge31cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpjbGljaycsIFsnJGV2ZW50J10pXG4gIG9uQ2xpY2tPdXRzaWRlKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5oYXNDbGlja2VkSW5zaWRlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcblxuICAgIC8vIENsaWNrIGRlbnRybyBkZWwgcGFuZWwgb3ZlcmxheSAob3BjaW9uZXMgbyBcImFncmVnYXIgZWxlbWVudG9cIikg4oaSIG5vIGNlcnJhclxuICAgIGlmICh0aGlzLl9vdmVybGF5UmVmPy5vdmVybGF5RWxlbWVudC5jb250YWlucyh0YXJnZXQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQ2xpY2sgZGVudHJvIGRlbCB0ZXh0ZmllbGQg4oaSIG5vIGNlcnJhclxuICAgIGNvbnN0IHRleHRmaWVsZCA9IHRoaXMuX2VsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLmNvbnRhaW5lci10ZXh0ZmllbGQnKSBhcyBIVE1MRWxlbWVudDtcbiAgICBpZiAodGV4dGZpZWxkPy5jb250YWlucyh0YXJnZXQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5jbG9zZUxpc3QoKTtcbiAgfVxuXG4gIGNsb3NlTGlzdChldmVudD86IEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50KSB7XG4gICAgICBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICB9XG4gICAgdGhpcy5pc0ZvY3VzZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9jbG9zZVBhbmVsKCk7XG4gICAgaWYgKCF0aGlzLnNlbGVjdGVkICYmIHRoaXMucmVxdWlyZWQpIHtcbiAgICAgIHRoaXMuaXNBbGVydFRleHQgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmlzQWxlcnRUZXh0ID0gZmFsc2U7XG4gICAgfVxuICAgIHRoaXMub25CbHVyRXZlbnQuZW1pdCgpO1xuICB9XG5cbiAgb25JbnB1dCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zZWxlY3RlZCkge1xuICAgICAgdGhpcy5zZWxlY3RlZCA9IGZhbHNlO1xuICAgIH1cbiAgICBpZiAodGhpcy5kZWJvdW5jZU1zIDw9IDApIHtcbiAgICAgIHRoaXMub25DaGFuZ2VzVmFsdWVFdmVudC5lbWl0KHRoaXMudGV4dElucHV0KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2RlYm91bmNlVGltZXIpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLl9kZWJvdW5jZVRpbWVyKTtcbiAgICB9XG4gICAgdGhpcy5fZGVib3VuY2VUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5vbkNoYW5nZXNWYWx1ZUV2ZW50LmVtaXQodGhpcy50ZXh0SW5wdXQpO1xuICAgIH0sIHRoaXMuZGVib3VuY2VNcyk7XG4gIH1cblxuICBvbkxpc3RTY3JvbGwoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmVuYWJsZUluZmluaXRlU2Nyb2xsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGVsID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuICAgIGNvbnN0IHRocmVzaG9sZCA9IDQ4O1xuICAgIGNvbnN0IG5lYXJCb3R0b20gPSBlbC5zY3JvbGxUb3AgKyBlbC5jbGllbnRIZWlnaHQgPj0gZWwuc2Nyb2xsSGVpZ2h0IC0gdGhyZXNob2xkO1xuICAgIGlmICghbmVhckJvdHRvbSB8fCB0aGlzLl9zY3JvbGxlZEVuZENvb2xkb3duKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX3Njcm9sbGVkRW5kQ29vbGRvd24gPSB0cnVlO1xuICAgIHRoaXMub25TY3JvbGxlZFRvRW5kLmVtaXQoKTtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHsgdGhpcy5fc2Nyb2xsZWRFbmRDb29sZG93biA9IGZhbHNlOyB9LCAzMDApO1xuICB9XG5cbiAgb25Gb2N1cygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmlzRm9jdXNlZCA9IHRydWU7XG4gICAgdGhpcy5oYXNDbGlja2VkSW5zaWRlID0gdHJ1ZTtcbiAgICBpZiAoIXRoaXMuc2hvd0xpc3QpIHtcbiAgICAgIHRoaXMuX29wZW5QYW5lbCgpO1xuICAgIH1cbiAgICB0aGlzLm9uRm9jdXNFdmVudC5lbWl0KCk7XG4gIH1cblxuICBvbkJsdXIoKTogdm9pZCB7XG4gICAgdGhpcy5pc0ZvY3VzZWQgPSBmYWxzZTtcbiAgICBpZiAodGhpcy5zaG93TGlzdCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5yZXF1aXJlZCkge1xuICAgICAgdGhpcy5pc0FsZXJ0VGV4dCA9IHRoaXMudGV4dElucHV0ID09PSAnJztcbiAgICB9XG4gIH1cblxuICBvbktleVByZXNzKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50LmtleSA9PT0gJ0VudGVyJykge1xuICAgICAgdGhpcy5hZGRUZXh0KCk7XG4gICAgfVxuICB9XG5cbiAgb25LZXlQcmVzc0FkZEVsZW1lbnQoZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoZXZlbnQua2V5ID09PSAnRW50ZXInKSB7XG4gICAgICB0aGlzLmFkZEVsZW1lbnRUZXh0KCk7XG4gICAgfVxuICB9XG5cbiAgb25DbGlja0FkZEVsZW1lbnQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZWxlbWVudC50cmltKCkgIT09ICcnKSB7XG4gICAgICB0aGlzLm9uQWRkRWxlbWVudC5lbWl0KHRoaXMuZWxlbWVudCk7XG4gICAgICB0aGlzLmVsZW1lbnQgPSAnJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5pc0FsZXJ0VGV4dCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgYWRkRWxlbWVudFRleHQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZWxlbWVudC50cmltKCkgIT09ICcnKSB7XG4gICAgICB0aGlzLm9uQWRkRWxlbWVudC5lbWl0KHRoaXMuZWxlbWVudCk7XG4gICAgICB0aGlzLmVsZW1lbnQgPSAnJztcbiAgICB9XG4gIH1cblxuICBhZGRUZXh0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnRleHRJbnB1dC50cmltKCkgIT09ICcnKSB7XG4gICAgICB0aGlzLm9uRW50ZXJLZXkuZW1pdCh0aGlzLnRleHRJbnB1dCk7XG4gICAgfVxuICB9XG5cbiAgb25TZWxlY3RPcHRpb24oKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZCA9IHRydWU7XG4gICAgdGhpcy5pc0ZvY3VzZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9jbG9zZVBhbmVsKCk7XG4gICAgdGhpcy5pc0FsZXJ0VGV4dCA9IGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBfb3BlblBhbmVsKCk6IHZvaWQge1xuICAgIGNvbnN0IHRleHRmaWVsZCA9IHRoaXMuX2VsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLmNvbnRhaW5lci10ZXh0ZmllbGQnKSBhcyBIVE1MRWxlbWVudDtcbiAgICBjb25zdCBhbmNob3IgPSB0ZXh0ZmllbGQgPz8gdGhpcy5fZWw7XG4gICAgY29uc3QgcG9zaXRpb25TdHJhdGVneSA9IHRoaXMuX292ZXJsYXlcbiAgICAgIC5wb3NpdGlvbigpXG4gICAgICAuZmxleGlibGVDb25uZWN0ZWRUbyhhbmNob3IpXG4gICAgICAud2l0aEZsZXhpYmxlRGltZW5zaW9ucyhmYWxzZSlcbiAgICAgIC53aXRoUHVzaChmYWxzZSlcbiAgICAgIC53aXRoUG9zaXRpb25zKFtcbiAgICAgICAgeyBvcmlnaW5YOiAnc3RhcnQnLCBvcmlnaW5ZOiAnYm90dG9tJywgb3ZlcmxheVg6ICdzdGFydCcsIG92ZXJsYXlZOiAndG9wJywgb2Zmc2V0WTogNCB9LFxuICAgICAgICB7IG9yaWdpblg6ICdzdGFydCcsIG9yaWdpblk6ICd0b3AnLCAgICBvdmVybGF5WDogJ3N0YXJ0Jywgb3ZlcmxheVk6ICdib3R0b20nLCBvZmZzZXRZOiAtNCB9LFxuICAgICAgXSk7XG5cbiAgICB0aGlzLl9vdmVybGF5UmVmID0gdGhpcy5fb3ZlcmxheS5jcmVhdGUoe1xuICAgICAgcG9zaXRpb25TdHJhdGVneSxcbiAgICAgIHNjcm9sbFN0cmF0ZWd5OiB0aGlzLl9vdmVybGF5LnNjcm9sbFN0cmF0ZWdpZXMucmVwb3NpdGlvbigpLFxuICAgICAgd2lkdGg6ICh0ZXh0ZmllbGQgPz8gdGhpcy5fZWwubmF0aXZlRWxlbWVudCkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGgsXG4gICAgfSk7XG5cbiAgICB0aGlzLl9vdmVybGF5UmVmLmF0dGFjaChuZXcgVGVtcGxhdGVQb3J0YWwodGhpcy5saXN0UGFuZWwsIHRoaXMuX3ZjcikpO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCB0aGlzLl9zY3JvbGxMaXN0ZW5lciwgdHJ1ZSk7XG4gIH1cblxuICBwcml2YXRlIF9jbG9zZVBhbmVsKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9vdmVybGF5UmVmKSB7XG4gICAgICB0aGlzLl9vdmVybGF5UmVmLmRpc3Bvc2UoKTtcbiAgICAgIHRoaXMuX292ZXJsYXlSZWYgPSBudWxsO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRoaXMuX3Njcm9sbExpc3RlbmVyLCB0cnVlKTtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fZGVib3VuY2VUaW1lcikge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX2RlYm91bmNlVGltZXIpO1xuICAgIH1cbiAgICB0aGlzLl9jbG9zZVBhbmVsKCk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJjb250YWluZXItZ2VuZXJhbFwiIFtpZF09XCJjb21wb25lbnRJZFwiPlxuXG4gIDwhLS0gTGFiZWwgc3VwZXJpb3IgLS0+XG4gIEBpZiAobGFiZWxTdXBlcmlvcikge1xuICAgIDxkaXYgY2xhc3M9XCJjb250YWluZXItbGFiZWwtc3VwXCIgW25nQ2xhc3NdPVwieyBkaXNhYmxlZDogZGlzYWJsZWQgfVwiPlxuICAgICAgQGlmICghZGlzYWJsZWQgJiYgcmVxdWlyZWQpIHtcbiAgICAgICAgPGRpdiBjbGFzcz1cImljb24tZG90XCI+PC9kaXY+XG4gICAgICB9XG4gICAgICA8c3Bhbj57eyBsYWJlbFN1cGVyaW9yIH19PC9zcGFuPlxuICAgICAgQGlmICghZGlzYWJsZWQgJiYgc2hvd0hlbHBUZXh0KSB7XG4gICAgICAgIDxpdXMtaWNvbi1tZCBpY29uTmFtZT1cImljb24taGVscFwiIGNsYXNzPVwiaWNvbi1jb2xvci1oZWxwXCI+PC9pdXMtaWNvbi1tZD5cbiAgICAgIH1cbiAgICAgIDxzcGFuPjo8L3NwYW4+XG4gICAgPC9kaXY+XG4gIH1cblxuICA8IS0tIElucHV0IHByaW5jaXBhbCAtLT5cbiAgPGRpdlxuICAgIGNsYXNzPVwiY29udGFpbmVyLXRleHRmaWVsZFwiXG4gICAgW25nQ2xhc3NdPVwie1xuICAgICAgZGlzYWJsZWQ6IGRpc2FibGVkLFxuICAgICAgZm9jdXNlZDogaXNGb2N1c2VkLFxuICAgICAgYWxlcnQ6ICghaXNGb2N1c2VkICYmIGlzQWxlcnRUZXh0ICYmICFkaXNhYmxlZCkgfHwgKGVycm9yICYmICFkaXNhYmxlZClcbiAgICB9XCJcbiAgICAoY2xpY2spPVwib25Gb2N1cygpXCJcbiAgPlxuICAgIEBpZiAoaWNvbklucHV0KSB7XG4gICAgICA8aXVzLWljb24tbWQgW2ljb25OYW1lXT1cImljb25JbnB1dFwiIGNsYXNzPVwiaWNvbi1jb2xvclwiPjwvaXVzLWljb24tbWQ+XG4gICAgfVxuICAgIDxpbnB1dFxuICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgWyhuZ01vZGVsKV09XCJ0ZXh0SW5wdXRcIlxuICAgICAgW3BsYWNlaG9sZGVyXT1cImxhYmVsSW5wdXRcIlxuICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgIChpbnB1dCk9XCJvbklucHV0KClcIlxuICAgICAgKGZvY3VzKT1cIm9uRm9jdXMoKVwiXG4gICAgICAoYmx1cik9XCJvbkJsdXIoKVwiXG4gICAgICAoa2V5cHJlc3MpPVwib25LZXlQcmVzcygkZXZlbnQpXCJcbiAgICAvPlxuICAgIDxkaXYgY2xhc3M9XCJjbnQtaWNvbi1yaWdodFwiPlxuICAgICAgQGlmICghc2hvd0xpc3QpIHtcbiAgICAgICAgPGl1cy1pY29uLW1kIGljb25OYW1lPVwiaWNvbi1rZXlib2FyZC1hcnJvdy1kb3duXCIgY2xhc3M9XCJpY29uLWFycm93c1wiPjwvaXVzLWljb24tbWQ+XG4gICAgICB9IEBlbHNlIHtcbiAgICAgICAgPGRpdiAoY2xpY2spPVwiY2xvc2VMaXN0KCRldmVudClcIiBzdHlsZT1cImhlaWdodDogMjBweDtcIj5cbiAgICAgICAgICA8aXVzLWljb24tbWQgaWNvbk5hbWU9XCJpY29uLWtleWJvYXJkLWFycm93LXVwXCIgY2xhc3M9XCJpY29uLWFycm93c1wiPjwvaXVzLWljb24tbWQ+XG4gICAgICAgIDwvZGl2PlxuICAgICAgfVxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuICA8IS0tIExhYmVsIGluZmVyaW9yIC0tPlxuICBAaWYgKGxhYmVsSW5mZXJpb3IgJiYgaXNGb2N1c2VkICYmICFlcnJvcikge1xuICAgIDxzcGFuIGNsYXNzPVwibGFiZWwtaW5mXCI+e3sgbGFiZWxJbmZlcmlvciB9fTwvc3Bhbj5cbiAgfVxuICBAaWYgKChlcnJvclRleHQgfHwgbGFiZWxJbmZlcmlvcikgJiYgKCghaXNGb2N1c2VkICYmIGlzQWxlcnRUZXh0ICYmICFkaXNhYmxlZCkgfHwgKGVycm9yICYmICFkaXNhYmxlZCkpKSB7XG4gICAgPHNwYW4gY2xhc3M9XCJsYWJlbC1pbmZcIiBbbmdDbGFzc109XCJ7IGFsZXJ0OiAoIWlzRm9jdXNlZCAmJiBpc0FsZXJ0VGV4dCAmJiAhZGlzYWJsZWQpIHx8IChlcnJvciAmJiAhZGlzYWJsZWQpIH1cIj5cbiAgICAgIHt7IGVycm9yVGV4dCA/PyBsYWJlbEluZmVyaW9yIH19XG4gICAgPC9zcGFuPlxuICB9XG5cbiAgPCEtLSBMaXN0YSBkZSBvcGNpb25lcyAoQ0RLIG92ZXJsYXkpIC0tPlxuICA8bmctdGVtcGxhdGUgI2xpc3RQYW5lbD5cbiAgICA8ZGl2IGNsYXNzPVwiY29udGFpbmVyLW9wdGlvbnNcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb250YWluZXItbGlzdCBzY3JvbGxhYmxlLXNtYWxsXCIgKHNjcm9sbCk9XCJvbkxpc3RTY3JvbGwoJGV2ZW50KVwiPlxuICAgICAgICA8ZGl2IChjbGljayk9XCJvblNlbGVjdE9wdGlvbigpXCI+XG4gICAgICAgICAgPG5nLWNvbnRlbnQgc2VsZWN0b3I9XCJpdXMtb3B0aW9uXCI+PC9uZy1jb250ZW50PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgQGlmIChsb2FkaW5nKSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImNudC1sb2FkaW5nLW9wdGlvblwiPkNhcmdhbmRv4oCmPC9kaXY+XG4gICAgICAgIH1cbiAgICAgIDwvZGl2PlxuICAgICAgPGl1cy1zaW1wbGUtZGl2aWRlcj48L2l1cy1zaW1wbGUtZGl2aWRlcj5cbiAgICAgIDxkaXYgY2xhc3M9XCJhZGQtZGF0YVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29udGFpbmVyLXRleHRcIj5cbiAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgIGNsYXNzPVwiaW5wdXQtdGV4dFwiXG4gICAgICAgICAgICBbKG5nTW9kZWwpXT1cImVsZW1lbnRcIlxuICAgICAgICAgICAgKGtleXByZXNzKT1cIm9uS2V5UHJlc3NBZGRFbGVtZW50KCRldmVudClcIlxuICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyQWRkVGV4dFwiXG4gICAgICAgICAgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJidXR0b24tYWRkLW9wdGlvblwiPlxuICAgICAgICAgIDxpdXMtYnV0dG9uLXN0YW5kYXJkLXRlcnRpYXJ5XG4gICAgICAgICAgICBbaWNvbk5hbWVdPVwiaWNvbkJ0bkFkZFwiXG4gICAgICAgICAgICAoY2xpY2spPVwib25DbGlja0FkZEVsZW1lbnQoKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAge3sgdGV4dEJ0bkFkZCB9fVxuICAgICAgICAgIDwvaXVzLWJ1dHRvbi1zdGFuZGFyZC10ZXJ0aWFyeT5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9uZy10ZW1wbGF0ZT5cblxuPC9kaXY+XG4iXX0=
@@ -28,15 +28,32 @@ export class ListFilter {
28
28
  this.match = match;
29
29
  this._term = '';
30
30
  this._reopened = false;
31
+ // Memoización: solo re-filtra cuando cambia (referencia de la fuente, término o reopened).
32
+ // En el resto de ciclos de detección devuelve el resultado cacheado → barato para listas grandes.
33
+ this._hasCache = false;
34
+ this._cache = [];
35
+ this._cacheSrc = null;
36
+ this._cacheTerm = '';
37
+ this._cacheReopened = false;
31
38
  }
32
- /** Lista a renderizar en el `@for`. */
39
+ /** Lista a renderizar en el `@for`. Memoizada: re-filtra solo cuando cambian fuente/término/reopened. */
33
40
  get visible() {
34
41
  const all = this.source() ?? [];
35
- if (this._reopened || !this._term.trim()) {
36
- return all;
42
+ if (this._hasCache &&
43
+ all === this._cacheSrc &&
44
+ this._term === this._cacheTerm &&
45
+ this._reopened === this._cacheReopened) {
46
+ return this._cache;
37
47
  }
38
- const t = this._term.toLowerCase();
39
- return all.filter((i) => this.match(i, t));
48
+ const result = this._reopened || !this._term.trim()
49
+ ? all
50
+ : all.filter((i) => this.match(i, this._term.toLowerCase()));
51
+ this._cache = result;
52
+ this._cacheSrc = all;
53
+ this._cacheTerm = this._term;
54
+ this._cacheReopened = this._reopened;
55
+ this._hasCache = true;
56
+ return result;
40
57
  }
41
58
  /** Término de filtro actual (sin normalizar). */
42
59
  get term() {
@@ -57,4 +74,4 @@ export class ListFilter {
57
74
  this._reopened = false;
58
75
  }
59
76
  }
60
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC1maWx0ZXIudXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2l1cy1kZXNpZ24tY29tcG9uZW50cy91dGlscy9zcmMvbGlzdC1maWx0ZXIudXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILE1BQU0sT0FBTyxVQUFVO0lBSXJCOzs7T0FHRztJQUNILFlBQ21CLE1BQWlCLEVBQ2pCLEtBQXlDO1FBRHpDLFdBQU0sR0FBTixNQUFNLENBQVc7UUFDakIsVUFBSyxHQUFMLEtBQUssQ0FBb0M7UUFUcEQsVUFBSyxHQUFHLEVBQUUsQ0FBQztRQUNYLGNBQVMsR0FBRyxLQUFLLENBQUM7SUFTdkIsQ0FBQztJQUVKLHVDQUF1QztJQUN2QyxJQUFJLE9BQU87UUFDVCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDO1FBQ2hDLElBQUksSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQztZQUN6QyxPQUFPLEdBQUcsQ0FBQztRQUNiLENBQUM7UUFDRCxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ25DLE9BQU8sR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRUQsaURBQWlEO0lBQ2pELElBQUksSUFBSTtRQUNOLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztJQUNwQixDQUFDO0lBRUQsMEZBQTBGO0lBQzFGLE1BQU0sQ0FBQyxJQUFZO1FBQ2pCLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRUQsb0ZBQW9GO0lBQ3BGLE1BQU07UUFDSixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztJQUN4QixDQUFDO0lBRUQsbUVBQW1FO0lBQ25FLEtBQUs7UUFDSCxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztRQUNoQixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztJQUN6QixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIExpc3RGaWx0ZXI8VD4g4oCUIHBhdHLDs24gw7puaWNvIGRlIGZpbHRyYWRvIHBhcmEgYGl1cy1pbnB1dC1zZWxlY3RgIGRlbCBlY29zaXN0ZW1hLlxuICpcbiAqIENlbnRyYWxpemEgZWwgZmlsdHJhZG8gY2xpZW50LXNpZGUgZGUgbGlzdGFzIGVuIG1lbW9yaWEgY29uIGRvcyBjb21wb3J0YW1pZW50b3M6XG4gKiAgLSBEZWJvdW5jZTogbG8gYXBvcnRhIGVsIHByb3BpbyBgaXVzLWlucHV0LXNlbGVjdGAgKGlucHV0IGBkZWJvdW5jZU1zYCwgZGVmYXVsdCAzMDApLlxuICogIC0gXCJSZS1jbGljayBtdWVzdHJhIGxpc3RhIGNvbXBsZXRhXCI6IGFsIHJlLWVuZm9jYXIgdW4gc2VsZWN0IHlhIHNlbGVjY2lvbmFkbyxcbiAqICAgIHJlYXBhcmVjZSBsYSBsaXN0YSBjb21wbGV0YSAobWFudGVuaWVuZG8gZWwgdGV4dG8pOyBhbCB0ZWNsZWFyLCB2dWVsdmUgYSBmaWx0cmFyLlxuICpcbiAqIENsYXNlIHBsYW5hIChzaW4gc2lnbmFscyk6IGZ1bmNpb25hIGVuIGNoYW5nZSBkZXRlY3Rpb24gY29uIG8gc2luIHNpZ25hbHMuXG4gKlxuICogVXNvOlxuICogICB0aXBvRmlsdGVyID0gbmV3IExpc3RGaWx0ZXIoXG4gKiAgICAgKCkgPT4gdGhpcy50aXBvQWN0aXZpZGFkZXMsXG4gKiAgICAgKHQsIHEpID0+ICh0LnRpcG9BY3RpdmlkYWQgPz8gJycpLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMocSksXG4gKiAgICk7XG4gKiAgIC8vIHRlbXBsYXRlOlxuICogICAvLyAgIEBmb3IgKHQgb2YgdGlwb0ZpbHRlci52aXNpYmxlOyB0cmFjayB0LmlkKSB7IC4uLiB9XG4gKiAgIC8vICAgKG9uQ2hhbmdlc1ZhbHVlRXZlbnQpPVwib25TZWFyY2goJGV2ZW50KVwiICAtPiBkZW50cm86IHRpcG9GaWx0ZXIuc2VhcmNoKCRldmVudClcbiAqICAgLy8gICAob25Gb2N1c0V2ZW50KT1cInRpcG9GaWx0ZXIucmVvcGVuKClcIlxuICovXG5leHBvcnQgY2xhc3MgTGlzdEZpbHRlcjxUPiB7XG4gIHByaXZhdGUgX3Rlcm0gPSAnJztcbiAgcHJpdmF0ZSBfcmVvcGVuZWQgPSBmYWxzZTtcblxuICAvKipcbiAgICogQHBhcmFtIHNvdXJjZSBGdW5jacOzbiBxdWUgZGV2dWVsdmUgbGEgbGlzdGEgY29tcGxldGEgYWN0dWFsIChhc3luYy1zYWZlOiBzZSBsZWUgZW4gY2FkYSBhY2Nlc28gYSBgdmlzaWJsZWApLlxuICAgKiBAcGFyYW0gbWF0Y2ggIFByZWRpY2FkbyBkZSBjb2luY2lkZW5jaWEuIGB0ZXJtYCBsbGVnYSB5YSBlbiBtaW7DunNjdWxhcy5cbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgc291cmNlOiAoKSA9PiBUW10sXG4gICAgcHJpdmF0ZSByZWFkb25seSBtYXRjaDogKGl0ZW06IFQsIHRlcm06IHN0cmluZykgPT4gYm9vbGVhbixcbiAgKSB7fVxuXG4gIC8qKiBMaXN0YSBhIHJlbmRlcml6YXIgZW4gZWwgYEBmb3JgLiAqL1xuICBnZXQgdmlzaWJsZSgpOiBUW10ge1xuICAgIGNvbnN0IGFsbCA9IHRoaXMuc291cmNlKCkgPz8gW107XG4gICAgaWYgKHRoaXMuX3Jlb3BlbmVkIHx8ICF0aGlzLl90ZXJtLnRyaW0oKSkge1xuICAgICAgcmV0dXJuIGFsbDtcbiAgICB9XG4gICAgY29uc3QgdCA9IHRoaXMuX3Rlcm0udG9Mb3dlckNhc2UoKTtcbiAgICByZXR1cm4gYWxsLmZpbHRlcigoaSkgPT4gdGhpcy5tYXRjaChpLCB0KSk7XG4gIH1cblxuICAvKiogVMOpcm1pbm8gZGUgZmlsdHJvIGFjdHVhbCAoc2luIG5vcm1hbGl6YXIpLiAqL1xuICBnZXQgdGVybSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl90ZXJtO1xuICB9XG5cbiAgLyoqIExsYW1hciBkZXNkZSBlbCBoYW5kbGVyIGRlIGLDunNxdWVkYSAoYWwgdGVjbGVhcik6IGFwYWdhIGVsIFwibW9zdHJhciB0b2RvXCIgeSBmaWx0cmEuICovXG4gIHNlYXJjaCh0ZXJtOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLl9yZW9wZW5lZCA9IGZhbHNlO1xuICAgIHRoaXMuX3Rlcm0gPSB0ZXJtID8/ICcnO1xuICB9XG5cbiAgLyoqIExsYW1hciBkZXNkZSBgKG9uRm9jdXNFdmVudClgOiBtdWVzdHJhIGxhIGxpc3RhIGNvbXBsZXRhIHNpbiBwZXJkZXIgZWwgdGV4dG8uICovXG4gIHJlb3BlbigpOiB2b2lkIHtcbiAgICB0aGlzLl9yZW9wZW5lZCA9IHRydWU7XG4gIH1cblxuICAvKiogTGltcGlhIHTDqXJtaW5vIHkgZXN0YWRvIChlai4gYWwgYWJyaXIvY2VycmFyIHVuIGZvcm11bGFyaW8pLiAqL1xuICByZXNldCgpOiB2b2lkIHtcbiAgICB0aGlzLl90ZXJtID0gJyc7XG4gICAgdGhpcy5fcmVvcGVuZWQgPSBmYWxzZTtcbiAgfVxufVxuIl19
77
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC1maWx0ZXIudXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2l1cy1kZXNpZ24tY29tcG9uZW50cy91dGlscy9zcmMvbGlzdC1maWx0ZXIudXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILE1BQU0sT0FBTyxVQUFVO0lBWXJCOzs7T0FHRztJQUNILFlBQ21CLE1BQWlCLEVBQ2pCLEtBQXlDO1FBRHpDLFdBQU0sR0FBTixNQUFNLENBQVc7UUFDakIsVUFBSyxHQUFMLEtBQUssQ0FBb0M7UUFqQnBELFVBQUssR0FBRyxFQUFFLENBQUM7UUFDWCxjQUFTLEdBQUcsS0FBSyxDQUFDO1FBRTFCLDJGQUEyRjtRQUMzRixrR0FBa0c7UUFDMUYsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUNsQixXQUFNLEdBQVEsRUFBRSxDQUFDO1FBQ2pCLGNBQVMsR0FBZSxJQUFJLENBQUM7UUFDN0IsZUFBVSxHQUFHLEVBQUUsQ0FBQztRQUNoQixtQkFBYyxHQUFHLEtBQUssQ0FBQztJQVM1QixDQUFDO0lBRUoseUdBQXlHO0lBQ3pHLElBQUksT0FBTztRQUNULE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFDaEMsSUFDRSxJQUFJLENBQUMsU0FBUztZQUNkLEdBQUcsS0FBSyxJQUFJLENBQUMsU0FBUztZQUN0QixJQUFJLENBQUMsS0FBSyxLQUFLLElBQUksQ0FBQyxVQUFVO1lBQzlCLElBQUksQ0FBQyxTQUFTLEtBQUssSUFBSSxDQUFDLGNBQWMsRUFDdEMsQ0FBQztZQUNELE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUNyQixDQUFDO1FBRUQsTUFBTSxNQUFNLEdBQ1YsSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFO1lBQ2xDLENBQUMsQ0FBQyxHQUFHO1lBQ0wsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRWpFLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxTQUFTLEdBQUcsR0FBRyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUM3QixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7UUFDckMsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFDdEIsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVELGlEQUFpRDtJQUNqRCxJQUFJLElBQUk7UUFDTixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDcEIsQ0FBQztJQUVELDBGQUEwRjtJQUMxRixNQUFNLENBQUMsSUFBWTtRQUNqQixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztRQUN2QixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVELG9GQUFvRjtJQUNwRixNQUFNO1FBQ0osSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7SUFDeEIsQ0FBQztJQUVELG1FQUFtRTtJQUNuRSxLQUFLO1FBQ0gsSUFBSSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7UUFDaEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7SUFDekIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBMaXN0RmlsdGVyPFQ+IOKAlCBwYXRyw7NuIMO6bmljbyBkZSBmaWx0cmFkbyBwYXJhIGBpdXMtaW5wdXQtc2VsZWN0YCBkZWwgZWNvc2lzdGVtYS5cbiAqXG4gKiBDZW50cmFsaXphIGVsIGZpbHRyYWRvIGNsaWVudC1zaWRlIGRlIGxpc3RhcyBlbiBtZW1vcmlhIGNvbiBkb3MgY29tcG9ydGFtaWVudG9zOlxuICogIC0gRGVib3VuY2U6IGxvIGFwb3J0YSBlbCBwcm9waW8gYGl1cy1pbnB1dC1zZWxlY3RgIChpbnB1dCBgZGVib3VuY2VNc2AsIGRlZmF1bHQgMzAwKS5cbiAqICAtIFwiUmUtY2xpY2sgbXVlc3RyYSBsaXN0YSBjb21wbGV0YVwiOiBhbCByZS1lbmZvY2FyIHVuIHNlbGVjdCB5YSBzZWxlY2Npb25hZG8sXG4gKiAgICByZWFwYXJlY2UgbGEgbGlzdGEgY29tcGxldGEgKG1hbnRlbmllbmRvIGVsIHRleHRvKTsgYWwgdGVjbGVhciwgdnVlbHZlIGEgZmlsdHJhci5cbiAqXG4gKiBDbGFzZSBwbGFuYSAoc2luIHNpZ25hbHMpOiBmdW5jaW9uYSBlbiBjaGFuZ2UgZGV0ZWN0aW9uIGNvbiBvIHNpbiBzaWduYWxzLlxuICpcbiAqIFVzbzpcbiAqICAgdGlwb0ZpbHRlciA9IG5ldyBMaXN0RmlsdGVyKFxuICogICAgICgpID0+IHRoaXMudGlwb0FjdGl2aWRhZGVzLFxuICogICAgICh0LCBxKSA9PiAodC50aXBvQWN0aXZpZGFkID8/ICcnKS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHEpLFxuICogICApO1xuICogICAvLyB0ZW1wbGF0ZTpcbiAqICAgLy8gICBAZm9yICh0IG9mIHRpcG9GaWx0ZXIudmlzaWJsZTsgdHJhY2sgdC5pZCkgeyAuLi4gfVxuICogICAvLyAgIChvbkNoYW5nZXNWYWx1ZUV2ZW50KT1cIm9uU2VhcmNoKCRldmVudClcIiAgLT4gZGVudHJvOiB0aXBvRmlsdGVyLnNlYXJjaCgkZXZlbnQpXG4gKiAgIC8vICAgKG9uRm9jdXNFdmVudCk9XCJ0aXBvRmlsdGVyLnJlb3BlbigpXCJcbiAqL1xuZXhwb3J0IGNsYXNzIExpc3RGaWx0ZXI8VD4ge1xuICBwcml2YXRlIF90ZXJtID0gJyc7XG4gIHByaXZhdGUgX3Jlb3BlbmVkID0gZmFsc2U7XG5cbiAgLy8gTWVtb2l6YWNpw7NuOiBzb2xvIHJlLWZpbHRyYSBjdWFuZG8gY2FtYmlhIChyZWZlcmVuY2lhIGRlIGxhIGZ1ZW50ZSwgdMOpcm1pbm8gbyByZW9wZW5lZCkuXG4gIC8vIEVuIGVsIHJlc3RvIGRlIGNpY2xvcyBkZSBkZXRlY2Npw7NuIGRldnVlbHZlIGVsIHJlc3VsdGFkbyBjYWNoZWFkbyDihpIgYmFyYXRvIHBhcmEgbGlzdGFzIGdyYW5kZXMuXG4gIHByaXZhdGUgX2hhc0NhY2hlID0gZmFsc2U7XG4gIHByaXZhdGUgX2NhY2hlOiBUW10gPSBbXTtcbiAgcHJpdmF0ZSBfY2FjaGVTcmM6IFRbXSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIF9jYWNoZVRlcm0gPSAnJztcbiAgcHJpdmF0ZSBfY2FjaGVSZW9wZW5lZCA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBAcGFyYW0gc291cmNlIEZ1bmNpw7NuIHF1ZSBkZXZ1ZWx2ZSBsYSBsaXN0YSBjb21wbGV0YSBhY3R1YWwgKGFzeW5jLXNhZmU6IHNlIGxlZSBlbiBjYWRhIGFjY2VzbyBhIGB2aXNpYmxlYCkuXG4gICAqIEBwYXJhbSBtYXRjaCAgUHJlZGljYWRvIGRlIGNvaW5jaWRlbmNpYS4gYHRlcm1gIGxsZWdhIHlhIGVuIG1pbsO6c2N1bGFzLlxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBzb3VyY2U6ICgpID0+IFRbXSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IG1hdGNoOiAoaXRlbTogVCwgdGVybTogc3RyaW5nKSA9PiBib29sZWFuLFxuICApIHt9XG5cbiAgLyoqIExpc3RhIGEgcmVuZGVyaXphciBlbiBlbCBgQGZvcmAuIE1lbW9pemFkYTogcmUtZmlsdHJhIHNvbG8gY3VhbmRvIGNhbWJpYW4gZnVlbnRlL3TDqXJtaW5vL3Jlb3BlbmVkLiAqL1xuICBnZXQgdmlzaWJsZSgpOiBUW10ge1xuICAgIGNvbnN0IGFsbCA9IHRoaXMuc291cmNlKCkgPz8gW107XG4gICAgaWYgKFxuICAgICAgdGhpcy5faGFzQ2FjaGUgJiZcbiAgICAgIGFsbCA9PT0gdGhpcy5fY2FjaGVTcmMgJiZcbiAgICAgIHRoaXMuX3Rlcm0gPT09IHRoaXMuX2NhY2hlVGVybSAmJlxuICAgICAgdGhpcy5fcmVvcGVuZWQgPT09IHRoaXMuX2NhY2hlUmVvcGVuZWRcbiAgICApIHtcbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZTtcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPVxuICAgICAgdGhpcy5fcmVvcGVuZWQgfHwgIXRoaXMuX3Rlcm0udHJpbSgpXG4gICAgICAgID8gYWxsXG4gICAgICAgIDogYWxsLmZpbHRlcigoaSkgPT4gdGhpcy5tYXRjaChpLCB0aGlzLl90ZXJtLnRvTG93ZXJDYXNlKCkpKTtcblxuICAgIHRoaXMuX2NhY2hlID0gcmVzdWx0O1xuICAgIHRoaXMuX2NhY2hlU3JjID0gYWxsO1xuICAgIHRoaXMuX2NhY2hlVGVybSA9IHRoaXMuX3Rlcm07XG4gICAgdGhpcy5fY2FjaGVSZW9wZW5lZCA9IHRoaXMuX3Jlb3BlbmVkO1xuICAgIHRoaXMuX2hhc0NhY2hlID0gdHJ1ZTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqIFTDqXJtaW5vIGRlIGZpbHRybyBhY3R1YWwgKHNpbiBub3JtYWxpemFyKS4gKi9cbiAgZ2V0IHRlcm0oKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fdGVybTtcbiAgfVxuXG4gIC8qKiBMbGFtYXIgZGVzZGUgZWwgaGFuZGxlciBkZSBiw7pzcXVlZGEgKGFsIHRlY2xlYXIpOiBhcGFnYSBlbCBcIm1vc3RyYXIgdG9kb1wiIHkgZmlsdHJhLiAqL1xuICBzZWFyY2godGVybTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5fcmVvcGVuZWQgPSBmYWxzZTtcbiAgICB0aGlzLl90ZXJtID0gdGVybSA/PyAnJztcbiAgfVxuXG4gIC8qKiBMbGFtYXIgZGVzZGUgYChvbkZvY3VzRXZlbnQpYDogbXVlc3RyYSBsYSBsaXN0YSBjb21wbGV0YSBzaW4gcGVyZGVyIGVsIHRleHRvLiAqL1xuICByZW9wZW4oKTogdm9pZCB7XG4gICAgdGhpcy5fcmVvcGVuZWQgPSB0cnVlO1xuICB9XG5cbiAgLyoqIExpbXBpYSB0w6lybWlubyB5IGVzdGFkbyAoZWouIGFsIGFicmlyL2NlcnJhciB1biBmb3JtdWxhcmlvKS4gKi9cbiAgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy5fdGVybSA9ICcnO1xuICAgIHRoaXMuX3Jlb3BlbmVkID0gZmFsc2U7XG4gIH1cbn1cbiJdfQ==
@@ -272,15 +272,32 @@ class ListFilter {
272
272
  this.match = match;
273
273
  this._term = '';
274
274
  this._reopened = false;
275
+ // Memoización: solo re-filtra cuando cambia (referencia de la fuente, término o reopened).
276
+ // En el resto de ciclos de detección devuelve el resultado cacheado → barato para listas grandes.
277
+ this._hasCache = false;
278
+ this._cache = [];
279
+ this._cacheSrc = null;
280
+ this._cacheTerm = '';
281
+ this._cacheReopened = false;
275
282
  }
276
- /** Lista a renderizar en el `@for`. */
283
+ /** Lista a renderizar en el `@for`. Memoizada: re-filtra solo cuando cambian fuente/término/reopened. */
277
284
  get visible() {
278
285
  const all = this.source() ?? [];
279
- if (this._reopened || !this._term.trim()) {
280
- return all;
286
+ if (this._hasCache &&
287
+ all === this._cacheSrc &&
288
+ this._term === this._cacheTerm &&
289
+ this._reopened === this._cacheReopened) {
290
+ return this._cache;
281
291
  }
282
- const t = this._term.toLowerCase();
283
- return all.filter((i) => this.match(i, t));
292
+ const result = this._reopened || !this._term.trim()
293
+ ? all
294
+ : all.filter((i) => this.match(i, this._term.toLowerCase()));
295
+ this._cache = result;
296
+ this._cacheSrc = all;
297
+ this._cacheTerm = this._term;
298
+ this._cacheReopened = this._reopened;
299
+ this._hasCache = true;
300
+ return result;
284
301
  }
285
302
  /** Término de filtro actual (sin normalizar). */
286
303
  get term() {
@@ -1 +1 @@
1
- {"version":3,"file":"litigiovirtual-ius-design-components-utils.mjs","sources":["../../../projects/ius-design-components/utils/src/currency-format.pipe.ts","../../../projects/ius-design-components/utils/src/formato-hora.pipe.ts","../../../projects/ius-design-components/utils/src/date-format.util.ts","../../../projects/ius-design-components/utils/src/file-mime.util.ts","../../../projects/ius-design-components/utils/src/file-size.util.ts","../../../projects/ius-design-components/utils/src/list-filter.util.ts","../../../projects/ius-design-components/utils/src/public-api.ts","../../../projects/ius-design-components/utils/src/litigiovirtual-ius-design-components-utils.ts"],"sourcesContent":["import { Pipe, PipeTransform } from '@angular/core';\n\n// ============================================================\n// Utilidades de moneda (locale es-CO por defecto). Reutilizables en cualquier app.\n//\n// En un input controlado:\n// import { parseCurrencyInput, buildCurrencyDisplay, formatCurrencyOnBlur }\n// from '@litigiovirtual/ius-design-components/utils';\n//\n// onChange(event: string) {\n// const { rawStr, intPart, decPart } = parseCurrencyInput(event);\n// this.valorRaw = rawStr;\n// this.display = buildCurrencyDisplay(intPart, decPart);\n// }\n// onBlur() { this.display = formatCurrencyOnBlur(this.valorRaw); }\n// ============================================================\n\n/**\n * Parsea lo que el usuario escribe en un input de moneda (es-CO: punto = miles, coma = decimal).\n * - rawStr: string con punto decimal para cálculos JS (\"150000.50\")\n * - intPart: parte entera sin formato (\"150000\")\n * - decPart: parte decimal tal como la escribió el usuario (\"50\") o null si no hay coma\n */\nexport function parseCurrencyInput(display: string): {\n rawStr: string;\n intPart: string;\n decPart: string | null;\n} {\n const stripped = display.replace(/\\./g, '').replace(/[^0-9,]/g, '');\n const commaIndex = stripped.indexOf(',');\n const intPart = commaIndex >= 0 ? stripped.slice(0, commaIndex) : stripped;\n const decPart = commaIndex >= 0 ? stripped.slice(commaIndex + 1) : null;\n const rawStr = decPart !== null ? `${intPart}.${decPart}` : intPart;\n return { rawStr, intPart, decPart };\n}\n\n/**\n * Formatea la parte entera con separadores de miles (es-CO) y conserva la decimal\n * exactamente como la escribió el usuario (sin redondear). Para actualizar el display al escribir.\n */\nexport function buildCurrencyDisplay(intPart: string, decPart: string | null): string {\n if (!intPart && decPart === null) return '';\n const intNum = intPart ? parseInt(intPart, 10) : 0;\n const formattedInt = isNaN(intNum)\n ? intPart\n : new Intl.NumberFormat('es-CO', { minimumFractionDigits: 0, maximumFractionDigits: 0 }).format(intNum);\n return decPart !== null ? `${formattedInt},${decPart}` : formattedInt;\n}\n\n/**\n * Formatea el valor raw al salir del campo (blur): completa decimales si los hay.\n * formatCurrencyOnBlur('150000.5') → \"150.000,50\"\n * formatCurrencyOnBlur('150000') → \"150.000\"\n */\nexport function formatCurrencyOnBlur(rawValue: string): string {\n if (!rawValue) return '';\n const num = parseFloat(rawValue);\n if (isNaN(num) || num <= 0) return rawValue;\n return new Intl.NumberFormat('es-CO', {\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n }).format(num);\n}\n\n// ============================================================\n// Pipe para mostrar valores en templates\n// {{ 150000 | currencyFormat }} → \"150.000\"\n// {{ 150000.5 | currencyFormat }} → \"150.000,5\"\n// {{ 150000 | currencyFormat: true }} → \"$ 150.000\" (símbolo COP)\n// ============================================================\n@Pipe({\n name: 'currencyFormat',\n standalone: true,\n})\nexport class CurrencyFormatPipe implements PipeTransform {\n transform(\n value: number | string | null | undefined,\n showSymbol = false,\n currencyCode = 'COP',\n locale = 'es-CO',\n ): string {\n if (value === null || value === undefined || value === '') return '';\n\n const num = typeof value === 'string' ? parseFloat(value.replace(/,/g, '')) : value;\n\n if (isNaN(num)) return String(value);\n\n try {\n return new Intl.NumberFormat(locale, {\n style: showSymbol ? 'currency' : 'decimal',\n currency: showSymbol ? currencyCode : undefined,\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n }).format(num);\n } catch {\n return num.toString();\n }\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\n/**\n * Muestra una hora en formato 12h con am/pm.\n * {{ '14:30:00' | formatoHora }} → \"2:30 pm\"\n * {{ '09:00' | formatoHora }} → \"9 am\"\n * Acepta string (con HH:mm[:ss] en cualquier parte), Date o ISO.\n */\n@Pipe({\n name: 'formatoHora',\n standalone: true,\n})\nexport class FormatoHoraPipe implements PipeTransform {\n transform(value?: string | Date | null): string {\n if (!value) return '';\n\n if (value instanceof Date) {\n return this.formatHours(value.getHours(), value.getMinutes());\n }\n\n const str = String(value);\n\n const match = str.match(/(\\d{1,2}):(\\d{2})(?::\\d{2})?/);\n if (match) {\n return this.formatHours(Number(match[1]), Number(match[2]));\n }\n\n const parsed = new Date(str);\n if (!isNaN(parsed.getTime())) {\n return this.formatHours(parsed.getHours(), parsed.getMinutes());\n }\n\n return '';\n }\n\n private formatHours(hours: number, minutes: number): string {\n const period = hours >= 12 ? 'pm' : 'am';\n const hour12 = hours % 12 === 0 ? 12 : hours % 12;\n if (minutes === 0) return `${hour12} ${period}`;\n return `${hour12}:${minutes.toString().padStart(2, '0')} ${period}`;\n }\n}\n","/**\n * Helpers de fecha/hora para inputs Angular ↔ backend (DateOnly / TimeOnly de C#).\n *\n * IMPORTANTE: se usa SIEMPRE el constructor local Date(y, m, d) para evitar el shift de\n * zona horaria. new Date('yyyy-MM-dd') se interpreta como UTC y puede saltar un día según\n * la zona; estos helpers reconstruyen la fecha desde sus componentes (hora local).\n */\n\n/**\n * Convierte cualquier valor de fecha (string \"yyyy-MM-dd\", \"yyyy-MM-ddTHH:mm:ss\" o Date)\n * a Date en hora LOCAL. Devuelve undefined si es vacío/ inválido.\n */\nexport function parseLocalDate(value: any): Date | undefined {\n if (value === null || value === undefined || value === '') return undefined;\n if (value instanceof Date) return isNaN(value.getTime()) ? undefined : value;\n if (typeof value === 'string') {\n const m = value.match(/^(\\d{4})-(\\d{2})-(\\d{2})(?:[T ](\\d{2}):(\\d{2})(?::(\\d{2}))?)?/);\n if (m) {\n return new Date(+m[1], +m[2] - 1, +m[3], +(m[4] ?? 0), +(m[5] ?? 0), +(m[6] ?? 0));\n }\n const parsed = new Date(value);\n return isNaN(parsed.getTime()) ? undefined : parsed;\n }\n return undefined;\n}\n\n/** Parsea evento de date-picker (ISO string, Date, \"YYYY-MM-DD\") a Date local. */\nexport function parseDateEvent(event: any): Date | undefined {\n if (!event) return undefined;\n if (event instanceof Date) return event;\n if (typeof event === 'string') {\n const match = event.match(/^(\\d{4})-(\\d{2})-(\\d{2})/);\n if (match) {\n return new Date(+match[1], +match[2] - 1, +match[3]);\n }\n const parsed = new Date(event);\n return isNaN(parsed.getTime()) ? undefined : parsed;\n }\n return undefined;\n}\n\n/** Parsea evento de time-picker a string \"HH:mm:ss\". */\nexport function parseHoraEvent(event: any): string | undefined {\n if (!event) return undefined;\n if (event instanceof Date) return toTimeOnlyString(event);\n if (typeof event === 'string') {\n const trimmed = event.trim();\n if (/^\\d{2}:\\d{2}(:\\d{2})?$/.test(trimmed)) {\n return trimmed.length === 5 ? `${trimmed}:00` : trimmed;\n }\n const parsed = new Date(event);\n return isNaN(parsed.getTime()) ? undefined : toTimeOnlyString(parsed);\n }\n return undefined;\n}\n\n/** Date -> \"yyyy-MM-dd\" en hora local (formato DateOnly C#). */\nexport function toDateOnlyString(d: Date): string {\n const y = d.getFullYear();\n const m = (d.getMonth() + 1).toString().padStart(2, '0');\n const dd = d.getDate().toString().padStart(2, '0');\n return `${y}-${m}-${dd}`;\n}\n\n/** Date -> \"HH:mm:ss\" en hora local (formato TimeOnly C#). */\nexport function toTimeOnlyString(d: Date): string {\n const h = d.getHours().toString().padStart(2, '0');\n const min = d.getMinutes().toString().padStart(2, '0');\n const s = d.getSeconds().toString().padStart(2, '0');\n return `${h}:${min}:${s}`;\n}\n","/**\n * Infiere el MIME type a partir de la extensión del nombre de archivo.\n *\n * Útil cuando el backend devuelve el nombre del archivo pero no su MIME type, y la UI\n * necesita uno para decidir ícono/visor (ej. distinguir PDF de Word/Excel/imagen).\n * Para archivos NUEVOS subidos por el usuario, usar `File.type` (ya viene del navegador).\n */\nexport function inferMimeTypeFromName(fileName?: string): string {\n if (!fileName) return '';\n const ext = fileName.split('.').pop()?.toLowerCase();\n switch (ext) {\n case 'pdf': return 'application/pdf';\n case 'jpg':\n case 'jpeg': return 'image/jpeg';\n case 'png': return 'image/png';\n case 'docx': return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';\n case 'xlsx': return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';\n default: return '';\n }\n}\n","/**\n * Constantes y conversión de tamaño de archivo. Centraliza los números mágicos\n * (1024) y ofrece una conversión a MB para mostrar totales agregados en UI.\n */\nexport const KB_IN_BYTES = 1024;\nexport const MB_IN_BYTES = 1024 * 1024;\n\n/** Bytes -> MB (1 decimal). Para mostrar totales agregados (ej. \"X MB de 25 MB\"). */\nexport function bytesToMB(bytes: number): number {\n return Math.round((bytes / MB_IN_BYTES) * 10) / 10;\n}\n","/**\n * ListFilter<T> — patrón único de filtrado para `ius-input-select` del ecosistema.\n *\n * Centraliza el filtrado client-side de listas en memoria con dos comportamientos:\n * - Debounce: lo aporta el propio `ius-input-select` (input `debounceMs`, default 300).\n * - \"Re-click muestra lista completa\": al re-enfocar un select ya seleccionado,\n * reaparece la lista completa (manteniendo el texto); al teclear, vuelve a filtrar.\n *\n * Clase plana (sin signals): funciona en change detection con o sin signals.\n *\n * Uso:\n * tipoFilter = new ListFilter(\n * () => this.tipoActividades,\n * (t, q) => (t.tipoActividad ?? '').toLowerCase().includes(q),\n * );\n * // template:\n * // @for (t of tipoFilter.visible; track t.id) { ... }\n * // (onChangesValueEvent)=\"onSearch($event)\" -> dentro: tipoFilter.search($event)\n * // (onFocusEvent)=\"tipoFilter.reopen()\"\n */\nexport class ListFilter<T> {\n private _term = '';\n private _reopened = false;\n\n /**\n * @param source Función que devuelve la lista completa actual (async-safe: se lee en cada acceso a `visible`).\n * @param match Predicado de coincidencia. `term` llega ya en minúsculas.\n */\n constructor(\n private readonly source: () => T[],\n private readonly match: (item: T, term: string) => boolean,\n ) {}\n\n /** Lista a renderizar en el `@for`. */\n get visible(): T[] {\n const all = this.source() ?? [];\n if (this._reopened || !this._term.trim()) {\n return all;\n }\n const t = this._term.toLowerCase();\n return all.filter((i) => this.match(i, t));\n }\n\n /** Término de filtro actual (sin normalizar). */\n get term(): string {\n return this._term;\n }\n\n /** Llamar desde el handler de búsqueda (al teclear): apaga el \"mostrar todo\" y filtra. */\n search(term: string): void {\n this._reopened = false;\n this._term = term ?? '';\n }\n\n /** Llamar desde `(onFocusEvent)`: muestra la lista completa sin perder el texto. */\n reopen(): void {\n this._reopened = true;\n }\n\n /** Limpia término y estado (ej. al abrir/cerrar un formulario). */\n reset(): void {\n this._term = '';\n this._reopened = false;\n }\n}\n","/*\n * Entry-point secundario: @litigiovirtual/ius-design-components/utils\n *\n * Utilidades compartidas (sin UI) para todas las apps del ecosistema:\n * moneda, fechas/horas y archivos. Evita duplicar este código en cada app.\n *\n * Uso:\n * import { CurrencyFormatPipe, parseLocalDate } from '@litigiovirtual/ius-design-components/utils';\n */\nexport * from './currency-format.pipe';\nexport * from './formato-hora.pipe';\nexport * from './date-format.util';\nexport * from './file-mime.util';\nexport * from './file-size.util';\nexport * from './list-filter.util';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"litigiovirtual-ius-design-components-utils.mjs","sources":["../../../projects/ius-design-components/utils/src/currency-format.pipe.ts","../../../projects/ius-design-components/utils/src/formato-hora.pipe.ts","../../../projects/ius-design-components/utils/src/date-format.util.ts","../../../projects/ius-design-components/utils/src/file-mime.util.ts","../../../projects/ius-design-components/utils/src/file-size.util.ts","../../../projects/ius-design-components/utils/src/list-filter.util.ts","../../../projects/ius-design-components/utils/src/public-api.ts","../../../projects/ius-design-components/utils/src/litigiovirtual-ius-design-components-utils.ts"],"sourcesContent":["import { Pipe, PipeTransform } from '@angular/core';\n\n// ============================================================\n// Utilidades de moneda (locale es-CO por defecto). Reutilizables en cualquier app.\n//\n// En un input controlado:\n// import { parseCurrencyInput, buildCurrencyDisplay, formatCurrencyOnBlur }\n// from '@litigiovirtual/ius-design-components/utils';\n//\n// onChange(event: string) {\n// const { rawStr, intPart, decPart } = parseCurrencyInput(event);\n// this.valorRaw = rawStr;\n// this.display = buildCurrencyDisplay(intPart, decPart);\n// }\n// onBlur() { this.display = formatCurrencyOnBlur(this.valorRaw); }\n// ============================================================\n\n/**\n * Parsea lo que el usuario escribe en un input de moneda (es-CO: punto = miles, coma = decimal).\n * - rawStr: string con punto decimal para cálculos JS (\"150000.50\")\n * - intPart: parte entera sin formato (\"150000\")\n * - decPart: parte decimal tal como la escribió el usuario (\"50\") o null si no hay coma\n */\nexport function parseCurrencyInput(display: string): {\n rawStr: string;\n intPart: string;\n decPart: string | null;\n} {\n const stripped = display.replace(/\\./g, '').replace(/[^0-9,]/g, '');\n const commaIndex = stripped.indexOf(',');\n const intPart = commaIndex >= 0 ? stripped.slice(0, commaIndex) : stripped;\n const decPart = commaIndex >= 0 ? stripped.slice(commaIndex + 1) : null;\n const rawStr = decPart !== null ? `${intPart}.${decPart}` : intPart;\n return { rawStr, intPart, decPart };\n}\n\n/**\n * Formatea la parte entera con separadores de miles (es-CO) y conserva la decimal\n * exactamente como la escribió el usuario (sin redondear). Para actualizar el display al escribir.\n */\nexport function buildCurrencyDisplay(intPart: string, decPart: string | null): string {\n if (!intPart && decPart === null) return '';\n const intNum = intPart ? parseInt(intPart, 10) : 0;\n const formattedInt = isNaN(intNum)\n ? intPart\n : new Intl.NumberFormat('es-CO', { minimumFractionDigits: 0, maximumFractionDigits: 0 }).format(intNum);\n return decPart !== null ? `${formattedInt},${decPart}` : formattedInt;\n}\n\n/**\n * Formatea el valor raw al salir del campo (blur): completa decimales si los hay.\n * formatCurrencyOnBlur('150000.5') → \"150.000,50\"\n * formatCurrencyOnBlur('150000') → \"150.000\"\n */\nexport function formatCurrencyOnBlur(rawValue: string): string {\n if (!rawValue) return '';\n const num = parseFloat(rawValue);\n if (isNaN(num) || num <= 0) return rawValue;\n return new Intl.NumberFormat('es-CO', {\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n }).format(num);\n}\n\n// ============================================================\n// Pipe para mostrar valores en templates\n// {{ 150000 | currencyFormat }} → \"150.000\"\n// {{ 150000.5 | currencyFormat }} → \"150.000,5\"\n// {{ 150000 | currencyFormat: true }} → \"$ 150.000\" (símbolo COP)\n// ============================================================\n@Pipe({\n name: 'currencyFormat',\n standalone: true,\n})\nexport class CurrencyFormatPipe implements PipeTransform {\n transform(\n value: number | string | null | undefined,\n showSymbol = false,\n currencyCode = 'COP',\n locale = 'es-CO',\n ): string {\n if (value === null || value === undefined || value === '') return '';\n\n const num = typeof value === 'string' ? parseFloat(value.replace(/,/g, '')) : value;\n\n if (isNaN(num)) return String(value);\n\n try {\n return new Intl.NumberFormat(locale, {\n style: showSymbol ? 'currency' : 'decimal',\n currency: showSymbol ? currencyCode : undefined,\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n }).format(num);\n } catch {\n return num.toString();\n }\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\n/**\n * Muestra una hora en formato 12h con am/pm.\n * {{ '14:30:00' | formatoHora }} → \"2:30 pm\"\n * {{ '09:00' | formatoHora }} → \"9 am\"\n * Acepta string (con HH:mm[:ss] en cualquier parte), Date o ISO.\n */\n@Pipe({\n name: 'formatoHora',\n standalone: true,\n})\nexport class FormatoHoraPipe implements PipeTransform {\n transform(value?: string | Date | null): string {\n if (!value) return '';\n\n if (value instanceof Date) {\n return this.formatHours(value.getHours(), value.getMinutes());\n }\n\n const str = String(value);\n\n const match = str.match(/(\\d{1,2}):(\\d{2})(?::\\d{2})?/);\n if (match) {\n return this.formatHours(Number(match[1]), Number(match[2]));\n }\n\n const parsed = new Date(str);\n if (!isNaN(parsed.getTime())) {\n return this.formatHours(parsed.getHours(), parsed.getMinutes());\n }\n\n return '';\n }\n\n private formatHours(hours: number, minutes: number): string {\n const period = hours >= 12 ? 'pm' : 'am';\n const hour12 = hours % 12 === 0 ? 12 : hours % 12;\n if (minutes === 0) return `${hour12} ${period}`;\n return `${hour12}:${minutes.toString().padStart(2, '0')} ${period}`;\n }\n}\n","/**\n * Helpers de fecha/hora para inputs Angular ↔ backend (DateOnly / TimeOnly de C#).\n *\n * IMPORTANTE: se usa SIEMPRE el constructor local Date(y, m, d) para evitar el shift de\n * zona horaria. new Date('yyyy-MM-dd') se interpreta como UTC y puede saltar un día según\n * la zona; estos helpers reconstruyen la fecha desde sus componentes (hora local).\n */\n\n/**\n * Convierte cualquier valor de fecha (string \"yyyy-MM-dd\", \"yyyy-MM-ddTHH:mm:ss\" o Date)\n * a Date en hora LOCAL. Devuelve undefined si es vacío/ inválido.\n */\nexport function parseLocalDate(value: any): Date | undefined {\n if (value === null || value === undefined || value === '') return undefined;\n if (value instanceof Date) return isNaN(value.getTime()) ? undefined : value;\n if (typeof value === 'string') {\n const m = value.match(/^(\\d{4})-(\\d{2})-(\\d{2})(?:[T ](\\d{2}):(\\d{2})(?::(\\d{2}))?)?/);\n if (m) {\n return new Date(+m[1], +m[2] - 1, +m[3], +(m[4] ?? 0), +(m[5] ?? 0), +(m[6] ?? 0));\n }\n const parsed = new Date(value);\n return isNaN(parsed.getTime()) ? undefined : parsed;\n }\n return undefined;\n}\n\n/** Parsea evento de date-picker (ISO string, Date, \"YYYY-MM-DD\") a Date local. */\nexport function parseDateEvent(event: any): Date | undefined {\n if (!event) return undefined;\n if (event instanceof Date) return event;\n if (typeof event === 'string') {\n const match = event.match(/^(\\d{4})-(\\d{2})-(\\d{2})/);\n if (match) {\n return new Date(+match[1], +match[2] - 1, +match[3]);\n }\n const parsed = new Date(event);\n return isNaN(parsed.getTime()) ? undefined : parsed;\n }\n return undefined;\n}\n\n/** Parsea evento de time-picker a string \"HH:mm:ss\". */\nexport function parseHoraEvent(event: any): string | undefined {\n if (!event) return undefined;\n if (event instanceof Date) return toTimeOnlyString(event);\n if (typeof event === 'string') {\n const trimmed = event.trim();\n if (/^\\d{2}:\\d{2}(:\\d{2})?$/.test(trimmed)) {\n return trimmed.length === 5 ? `${trimmed}:00` : trimmed;\n }\n const parsed = new Date(event);\n return isNaN(parsed.getTime()) ? undefined : toTimeOnlyString(parsed);\n }\n return undefined;\n}\n\n/** Date -> \"yyyy-MM-dd\" en hora local (formato DateOnly C#). */\nexport function toDateOnlyString(d: Date): string {\n const y = d.getFullYear();\n const m = (d.getMonth() + 1).toString().padStart(2, '0');\n const dd = d.getDate().toString().padStart(2, '0');\n return `${y}-${m}-${dd}`;\n}\n\n/** Date -> \"HH:mm:ss\" en hora local (formato TimeOnly C#). */\nexport function toTimeOnlyString(d: Date): string {\n const h = d.getHours().toString().padStart(2, '0');\n const min = d.getMinutes().toString().padStart(2, '0');\n const s = d.getSeconds().toString().padStart(2, '0');\n return `${h}:${min}:${s}`;\n}\n","/**\n * Infiere el MIME type a partir de la extensión del nombre de archivo.\n *\n * Útil cuando el backend devuelve el nombre del archivo pero no su MIME type, y la UI\n * necesita uno para decidir ícono/visor (ej. distinguir PDF de Word/Excel/imagen).\n * Para archivos NUEVOS subidos por el usuario, usar `File.type` (ya viene del navegador).\n */\nexport function inferMimeTypeFromName(fileName?: string): string {\n if (!fileName) return '';\n const ext = fileName.split('.').pop()?.toLowerCase();\n switch (ext) {\n case 'pdf': return 'application/pdf';\n case 'jpg':\n case 'jpeg': return 'image/jpeg';\n case 'png': return 'image/png';\n case 'docx': return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';\n case 'xlsx': return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';\n default: return '';\n }\n}\n","/**\n * Constantes y conversión de tamaño de archivo. Centraliza los números mágicos\n * (1024) y ofrece una conversión a MB para mostrar totales agregados en UI.\n */\nexport const KB_IN_BYTES = 1024;\nexport const MB_IN_BYTES = 1024 * 1024;\n\n/** Bytes -> MB (1 decimal). Para mostrar totales agregados (ej. \"X MB de 25 MB\"). */\nexport function bytesToMB(bytes: number): number {\n return Math.round((bytes / MB_IN_BYTES) * 10) / 10;\n}\n","/**\n * ListFilter<T> — patrón único de filtrado para `ius-input-select` del ecosistema.\n *\n * Centraliza el filtrado client-side de listas en memoria con dos comportamientos:\n * - Debounce: lo aporta el propio `ius-input-select` (input `debounceMs`, default 300).\n * - \"Re-click muestra lista completa\": al re-enfocar un select ya seleccionado,\n * reaparece la lista completa (manteniendo el texto); al teclear, vuelve a filtrar.\n *\n * Clase plana (sin signals): funciona en change detection con o sin signals.\n *\n * Uso:\n * tipoFilter = new ListFilter(\n * () => this.tipoActividades,\n * (t, q) => (t.tipoActividad ?? '').toLowerCase().includes(q),\n * );\n * // template:\n * // @for (t of tipoFilter.visible; track t.id) { ... }\n * // (onChangesValueEvent)=\"onSearch($event)\" -> dentro: tipoFilter.search($event)\n * // (onFocusEvent)=\"tipoFilter.reopen()\"\n */\nexport class ListFilter<T> {\n private _term = '';\n private _reopened = false;\n\n // Memoización: solo re-filtra cuando cambia (referencia de la fuente, término o reopened).\n // En el resto de ciclos de detección devuelve el resultado cacheado → barato para listas grandes.\n private _hasCache = false;\n private _cache: T[] = [];\n private _cacheSrc: T[] | null = null;\n private _cacheTerm = '';\n private _cacheReopened = false;\n\n /**\n * @param source Función que devuelve la lista completa actual (async-safe: se lee en cada acceso a `visible`).\n * @param match Predicado de coincidencia. `term` llega ya en minúsculas.\n */\n constructor(\n private readonly source: () => T[],\n private readonly match: (item: T, term: string) => boolean,\n ) {}\n\n /** Lista a renderizar en el `@for`. Memoizada: re-filtra solo cuando cambian fuente/término/reopened. */\n get visible(): T[] {\n const all = this.source() ?? [];\n if (\n this._hasCache &&\n all === this._cacheSrc &&\n this._term === this._cacheTerm &&\n this._reopened === this._cacheReopened\n ) {\n return this._cache;\n }\n\n const result =\n this._reopened || !this._term.trim()\n ? all\n : all.filter((i) => this.match(i, this._term.toLowerCase()));\n\n this._cache = result;\n this._cacheSrc = all;\n this._cacheTerm = this._term;\n this._cacheReopened = this._reopened;\n this._hasCache = true;\n return result;\n }\n\n /** Término de filtro actual (sin normalizar). */\n get term(): string {\n return this._term;\n }\n\n /** Llamar desde el handler de búsqueda (al teclear): apaga el \"mostrar todo\" y filtra. */\n search(term: string): void {\n this._reopened = false;\n this._term = term ?? '';\n }\n\n /** Llamar desde `(onFocusEvent)`: muestra la lista completa sin perder el texto. */\n reopen(): void {\n this._reopened = true;\n }\n\n /** Limpia término y estado (ej. al abrir/cerrar un formulario). */\n reset(): void {\n this._term = '';\n this._reopened = false;\n }\n}\n","/*\n * Entry-point secundario: @litigiovirtual/ius-design-components/utils\n *\n * Utilidades compartidas (sin UI) para todas las apps del ecosistema:\n * moneda, fechas/horas y archivos. Evita duplicar este código en cada app.\n *\n * Uso:\n * import { CurrencyFormatPipe, parseLocalDate } from '@litigiovirtual/ius-design-components/utils';\n */\nexport * from './currency-format.pipe';\nexport * from './formato-hora.pipe';\nexport * from './date-format.util';\nexport * from './file-mime.util';\nexport * from './file-size.util';\nexport * from './list-filter.util';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}