@smallpearl/ngx-helper 0.29.26 → 0.29.30

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,23 +1,21 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, input, EventEmitter, computed, Component, ChangeDetectionStrategy, Optional, Inject, Self, ViewChild, Input, Output, HostBinding } from '@angular/core';
2
+ import { InjectionToken, input, EventEmitter, computed, inject, ChangeDetectorRef, ElementRef, Component, ChangeDetectionStrategy, ViewChild, Input, Output, HostBinding } from '@angular/core';
3
3
  import { coerceBooleanProperty } from '@angular/cdk/coercion';
4
- import * as i3 from '@angular/common';
5
- import { CommonModule } from '@angular/common';
6
- import * as i1 from '@angular/common/http';
7
- import { HttpContextToken, HttpParams, HttpContext } from '@angular/common/http';
4
+ import * as i1 from '@angular/common';
5
+ import { CommonModule, NgTemplateOutlet } from '@angular/common';
6
+ import { HttpContextToken, HttpClient, HttpParams, HttpContext } from '@angular/common/http';
8
7
  import * as i2 from '@angular/forms';
9
- import { Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
10
- import * as i7 from '@angular/material/form-field';
8
+ import { NgControl, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
11
9
  import { MAT_FORM_FIELD, MatFormFieldControl } from '@angular/material/form-field';
12
- import * as i4 from '@angular/material/select';
10
+ import * as i3 from '@angular/material/select';
13
11
  import { MatSelect, MatSelectModule } from '@angular/material/select';
14
- import * as i6 from 'ngx-mat-select-search';
15
- import { NgxMatSelectSearchModule } from 'ngx-mat-select-search';
16
- import { Subject, BehaviorSubject, combineLatest, debounceTime, takeUntil, switchMap, of, tap } from 'rxjs';
17
12
  import { getNgxHelperConfig } from '@smallpearl/ngx-helper/core';
18
- import { plural } from 'pluralize';
19
13
  import { camelCase } from 'lodash';
20
- import * as i5 from '@angular/material/core';
14
+ import * as i5 from 'ngx-mat-select-search';
15
+ import { NgxMatSelectSearchModule } from 'ngx-mat-select-search';
16
+ import { plural } from 'pluralize';
17
+ import { Subject, BehaviorSubject, combineLatest, debounceTime, takeUntil, switchMap, of, tap } from 'rxjs';
18
+ import * as i4 from '@angular/material/core';
21
19
 
22
20
  const SP_MAT_SELECT_ENTITY_CONFIG = new InjectionToken('SPMatSelectEntityConfig');
23
21
 
@@ -43,13 +41,6 @@ const DEFAULT_SP_MAT_SELECT_ENTITY_CONFIG = {
43
41
  * but this can be customized by specifying the `idKey' property value.
44
42
  */
45
43
  class SPMatSelectEntityComponent {
46
- http;
47
- cdr;
48
- _elementRef;
49
- injector;
50
- _formField;
51
- ngControl;
52
- config;
53
44
  // We cache the entities that we fetch from remote here. Cache is indexed
54
45
  // by the endpoint. Each endpoint also keeps a refCount, which is incremented
55
46
  // for each instance of the component using the same endpoint. When this
@@ -155,6 +146,25 @@ class SPMatSelectEntityComponent {
155
146
  searchText;
156
147
  notFoundText;
157
148
  addItemText;
149
+ /**
150
+ * Template for the option label. If not provided, the default label
151
+ * function will be used. Option label is what is placed inside the
152
+ * <mat-option> tag. The template gets an implicit 'entity' variable
153
+ * in the context, value for which is the entity object.
154
+ *
155
+ * For example:
156
+ * ```
157
+ * <sp-mat-select-entity
158
+ * [url]="'/api/v1/customers/'"
159
+ * [entityLabelFn]="entity => entity.name"
160
+ * [optionLabelTemplate]="optionLabelTemplate"
161
+ * ></sp-mat-select-entity>
162
+ * <ng-template #optionLabelTemplate let-entity>
163
+ * {{ entity.name }} - {{ entity.description }}
164
+ * </ng-template>
165
+ * ```
166
+ */
167
+ optionLabelTemplate = input();
158
168
  _sideloadDataKey = computed(() => {
159
169
  if (this.sideloadDataKey()) {
160
170
  return this.sideloadDataKey();
@@ -190,14 +200,13 @@ class SPMatSelectEntityComponent {
190
200
  id = `sp-select-entity-${SPMatSelectEntityComponent.nextId++}`;
191
201
  _placeholder;
192
202
  ngxHelperConfig = getNgxHelperConfig();
193
- constructor(http, cdr, _elementRef, injector, _formField, ngControl, config) {
194
- this.http = http;
195
- this.cdr = cdr;
196
- this._elementRef = _elementRef;
197
- this.injector = injector;
198
- this._formField = _formField;
199
- this.ngControl = ngControl;
200
- this.config = config;
203
+ http = inject(HttpClient);
204
+ cdr = inject(ChangeDetectorRef);
205
+ _elementRef = inject((ElementRef));
206
+ _formField = inject(MAT_FORM_FIELD, { optional: true });
207
+ config = inject(SP_MAT_SELECT_ENTITY_CONFIG, { optional: true });
208
+ ngControl = inject(NgControl, { optional: true });
209
+ constructor() {
201
210
  if (this.ngControl != null) {
202
211
  this.ngControl.valueAccessor = this;
203
212
  }
@@ -249,7 +258,7 @@ class SPMatSelectEntityComponent {
249
258
  this.notFoundText = config.i18n.notFound;
250
259
  }
251
260
  if (!this.addItemText) {
252
- this.addItemText = config.i18n.addItem.replace(/\{\{\s*item\s*}}/, this.entityName ?? "**Item");
261
+ this.addItemText = config.i18n.addItem.replace(/\{\{\s*item\s*}}/, this.entityName ?? '**Item');
253
262
  }
254
263
  }
255
264
  addEntity(entity) {
@@ -260,14 +269,18 @@ class SPMatSelectEntityComponent {
260
269
  }
261
270
  get selectTriggerValue() {
262
271
  if (this.selectValue) {
263
- const firstSelected = Array.isArray(this.selectValue) ? this.selectValue[0] : this.selectValue;
272
+ const firstSelected = Array.isArray(this.selectValue)
273
+ ? this.selectValue[0]
274
+ : this.selectValue;
264
275
  const selectedEntity = this._entities.get(firstSelected);
265
276
  return selectedEntity ? this.entityLabelFn(selectedEntity) : '';
266
277
  }
267
278
  return '';
268
279
  }
269
280
  get selectTriggerValueAsArray() {
270
- return Array.isArray(this.selectValue) ? this.selectValue : [];
281
+ return Array.isArray(this.selectValue)
282
+ ? this.selectValue
283
+ : [];
271
284
  }
272
285
  entityId(entity) {
273
286
  return entity[this.idKey];
@@ -276,7 +289,7 @@ class SPMatSelectEntityComponent {
276
289
  if (Array.isArray(entityId)) {
277
290
  if (this.multiple) {
278
291
  const selectedValues = [];
279
- entityId.forEach(id => {
292
+ entityId.forEach((id) => {
280
293
  if (this._entities.has(id)) {
281
294
  selectedValues.push(id);
282
295
  }
@@ -307,17 +320,17 @@ class SPMatSelectEntityComponent {
307
320
  }
308
321
  set entities(items) {
309
322
  if (!this.group) {
310
- items.forEach(item => {
323
+ items.forEach((item) => {
311
324
  this._entities.set(item[this.idKey], item);
312
325
  });
313
326
  }
314
327
  else {
315
328
  this._groupedEntities = items;
316
- this._groupedEntities.forEach(group => {
329
+ this._groupedEntities.forEach((group) => {
317
330
  const key = this.groupEntitiesKey();
318
331
  const groupEntities = group[key];
319
332
  group['__items__'] = groupEntities;
320
- groupEntities.forEach(item => {
333
+ groupEntities.forEach((item) => {
321
334
  this._entities.set(item[this.idKey], item);
322
335
  });
323
336
  });
@@ -342,7 +355,8 @@ class SPMatSelectEntityComponent {
342
355
  this.stateChanges.next();
343
356
  }
344
357
  get required() {
345
- return this._required ?? this.ngControl?.control?.hasValidator(Validators.required);
358
+ return (this._required ??
359
+ this.ngControl?.control?.hasValidator(Validators.required));
346
360
  }
347
361
  set required(req) {
348
362
  this._required = coerceBooleanProperty(req);
@@ -356,7 +370,6 @@ class SPMatSelectEntityComponent {
356
370
  }
357
371
  set disabled(value) {
358
372
  const disabled = coerceBooleanProperty(value);
359
- ;
360
373
  if (disabled !== this._disabled) {
361
374
  this.setDisabledState(disabled);
362
375
  this.stateChanges.next();
@@ -421,7 +434,7 @@ class SPMatSelectEntityComponent {
421
434
  this.selectValue = ev.value;
422
435
  this.onTouched();
423
436
  this.onChanged(ev.value);
424
- const selectedEntities = ev.value.map(id => this._entities.get(id));
437
+ const selectedEntities = ev.value.map((id) => this._entities.get(id));
425
438
  this.selectionChange.emit(selectedEntities);
426
439
  }
427
440
  else {
@@ -458,7 +471,9 @@ class SPMatSelectEntityComponent {
458
471
  if (this.entityFilterFn) {
459
472
  return this.entityFilterFn(member, search);
460
473
  }
461
- return this.entityLabelFn(member).toLocaleLowerCase().includes(searchLwr);
474
+ return this.entityLabelFn(member)
475
+ .toLocaleLowerCase()
476
+ .includes(searchLwr);
462
477
  }));
463
478
  }
464
479
  }
@@ -483,15 +498,15 @@ class SPMatSelectEntityComponent {
483
498
  }
484
499
  else {
485
500
  const groupEntitiesKey = this.groupEntitiesKey();
486
- const groups = this._groupedEntities.map(ge => {
501
+ const groups = this._groupedEntities.map((ge) => {
487
502
  const label = this.groupLabel(ge);
488
503
  if (label.toLocaleLowerCase().includes(searchLwr)) {
489
504
  return { ...ge };
490
505
  }
491
506
  else {
492
- const groupEntities = ge.__items__?.filter(e => this.entityLabelFn(e).toLocaleLowerCase().includes(searchLwr));
507
+ const groupEntities = ge.__items__?.filter((e) => this.entityLabelFn(e).toLocaleLowerCase().includes(searchLwr));
493
508
  const ret = {
494
- ...ge
509
+ ...ge,
495
510
  };
496
511
  ret['__items__'] = groupEntities ?? [];
497
512
  return ret;
@@ -512,13 +527,13 @@ class SPMatSelectEntityComponent {
512
527
  let cacheKey;
513
528
  let obs;
514
529
  if (this.loadFromRemoteFn) {
515
- obs = this.loadFromRemoteFn(this.injector);
530
+ obs = this.loadFromRemoteFn();
516
531
  }
517
532
  else {
518
533
  let params;
519
534
  if (this.httpParams) {
520
535
  params = new HttpParams({
521
- fromString: this.httpParams.toString()
536
+ fromString: this.httpParams.toString(),
522
537
  });
523
538
  }
524
539
  else {
@@ -549,7 +564,8 @@ class SPMatSelectEntityComponent {
549
564
  Array.isArray(entities['results'])) {
550
565
  entities = entities['results'];
551
566
  }
552
- else if ( // sideloaded response, where entities are usually provided in 'entityName'
567
+ else if (
568
+ // sideloaded response, where entities are usually provided in 'entityName'
553
569
  this._sideloadDataKey() &&
554
570
  !Array.isArray(entities) &&
555
571
  typeof entities === 'object' &&
@@ -590,8 +606,11 @@ class SPMatSelectEntityComponent {
590
606
  return group[this.groupEntitiesKey()] ?? [];
591
607
  }
592
608
  groupEntitiesKey() {
593
- return this.groupOptionsKey ? this.groupOptionsKey
594
- : (this.entityName ? plural(this.entityName.toLocaleLowerCase()) : 'items');
609
+ return this.groupOptionsKey
610
+ ? this.groupOptionsKey
611
+ : this.entityName
612
+ ? plural(this.entityName.toLocaleLowerCase())
613
+ : 'items';
595
614
  }
596
615
  existsInCache() {
597
616
  const cacheKey = this.getCacheKey();
@@ -605,7 +624,7 @@ class SPMatSelectEntityComponent {
605
624
  let params;
606
625
  if (this.httpParams) {
607
626
  params = new HttpParams({
608
- fromString: this.httpParams.toString()
627
+ fromString: this.httpParams.toString(),
609
628
  });
610
629
  }
611
630
  else {
@@ -619,7 +638,8 @@ class SPMatSelectEntityComponent {
619
638
  getFromCache() {
620
639
  const cacheKey = this.getCacheKey();
621
640
  if (cacheKey && SPMatSelectEntityComponent._entitiesCache.has(cacheKey)) {
622
- return SPMatSelectEntityComponent._entitiesCache.get(cacheKey)?.entities;
641
+ return SPMatSelectEntityComponent._entitiesCache.get(cacheKey)
642
+ ?.entities;
623
643
  }
624
644
  return [];
625
645
  }
@@ -627,7 +647,10 @@ class SPMatSelectEntityComponent {
627
647
  const cacheKey = this.getCacheKey();
628
648
  if (cacheKey) {
629
649
  if (!SPMatSelectEntityComponent._entitiesCache.has(cacheKey)) {
630
- SPMatSelectEntityComponent._entitiesCache.set(cacheKey, { refCount: 0, entities });
650
+ SPMatSelectEntityComponent._entitiesCache.set(cacheKey, {
651
+ refCount: 0,
652
+ entities,
653
+ });
631
654
  }
632
655
  const cacheEntry = SPMatSelectEntityComponent._entitiesCache.get(cacheKey);
633
656
  cacheEntry.refCount += 1;
@@ -651,12 +674,14 @@ class SPMatSelectEntityComponent {
651
674
  context.set(SP_MAT_SELECT_ENTITY_HTTP_CONTEXT, {
652
675
  entityName: this.entityName ?? '',
653
676
  entityNamePlural: this.entityName ? plural(this.entityName) : '',
654
- endpoint: this.url
677
+ endpoint: this.url,
655
678
  });
656
679
  return context;
657
680
  }
658
- /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: SPMatSelectEntityComponent, deps: [{ token: i1.HttpClient }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i0.Injector }, { token: MAT_FORM_FIELD, optional: true }, { token: i2.NgControl, optional: true, self: true }, { token: SP_MAT_SELECT_ENTITY_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
659
- /** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.6", type: SPMatSelectEntityComponent, isStandalone: true, selector: "sp-mat-select-entity", inputs: { entityLabelFn: { classPropertyName: "entityLabelFn", publicName: "entityLabelFn", isSignal: false, isRequired: true, transformFunction: null }, entityFilterFn: { classPropertyName: "entityFilterFn", publicName: "entityFilterFn", isSignal: false, isRequired: false, transformFunction: null }, idKey: { classPropertyName: "idKey", publicName: "idKey", isSignal: false, isRequired: false, transformFunction: null }, url: { classPropertyName: "url", publicName: "url", isSignal: false, isRequired: false, transformFunction: null }, httpParams: { classPropertyName: "httpParams", publicName: "httpParams", isSignal: false, isRequired: false, transformFunction: null }, loadFromRemoteFn: { classPropertyName: "loadFromRemoteFn", publicName: "loadFromRemoteFn", isSignal: false, isRequired: false, transformFunction: null }, inlineNew: { classPropertyName: "inlineNew", publicName: "inlineNew", isSignal: false, isRequired: false, transformFunction: null }, entityName: { classPropertyName: "entityName", publicName: "entityName", isSignal: false, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: false, isRequired: false, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: false, isRequired: false, transformFunction: null }, groupOptionsKey: { classPropertyName: "groupOptionsKey", publicName: "groupOptionsKey", isSignal: false, isRequired: false, transformFunction: null }, groupLabelFn: { classPropertyName: "groupLabelFn", publicName: "groupLabelFn", isSignal: false, isRequired: false, transformFunction: null }, sideloadDataKey: { classPropertyName: "sideloadDataKey", publicName: "sideloadDataKey", isSignal: true, isRequired: false, transformFunction: null }, responseParserFn: { classPropertyName: "responseParserFn", publicName: "responseParserFn", isSignal: true, isRequired: false, transformFunction: null }, searchText: { classPropertyName: "searchText", publicName: "searchText", isSignal: false, isRequired: false, transformFunction: null }, notFoundText: { classPropertyName: "notFoundText", publicName: "notFoundText", isSignal: false, isRequired: false, transformFunction: null }, addItemText: { classPropertyName: "addItemText", publicName: "addItemText", isSignal: false, isRequired: false, transformFunction: null }, entities: { classPropertyName: "entities", publicName: "entities", isSignal: false, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: false, isRequired: false, transformFunction: null }, userAriaDescribedBy: { classPropertyName: "userAriaDescribedBy", publicName: "aria-describedby", isSignal: false, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: false, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: false, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", createNewItemSelected: "createNewItemSelected" }, host: { properties: { "id": "this.id" } }, providers: [{ provide: MatFormFieldControl, useExisting: SPMatSelectEntityComponent }], viewQueries: [{ propertyName: "matSel", first: true, predicate: MatSelect, descendants: true }, { propertyName: "matSelect", first: true, predicate: MatSelect, descendants: true }], ngImport: i0, template: `
681
+ /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: SPMatSelectEntityComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
682
+ /** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.6", type: SPMatSelectEntityComponent, isStandalone: true, selector: "sp-mat-select-entity", inputs: { entityLabelFn: { classPropertyName: "entityLabelFn", publicName: "entityLabelFn", isSignal: false, isRequired: true, transformFunction: null }, entityFilterFn: { classPropertyName: "entityFilterFn", publicName: "entityFilterFn", isSignal: false, isRequired: false, transformFunction: null }, idKey: { classPropertyName: "idKey", publicName: "idKey", isSignal: false, isRequired: false, transformFunction: null }, url: { classPropertyName: "url", publicName: "url", isSignal: false, isRequired: false, transformFunction: null }, httpParams: { classPropertyName: "httpParams", publicName: "httpParams", isSignal: false, isRequired: false, transformFunction: null }, loadFromRemoteFn: { classPropertyName: "loadFromRemoteFn", publicName: "loadFromRemoteFn", isSignal: false, isRequired: false, transformFunction: null }, inlineNew: { classPropertyName: "inlineNew", publicName: "inlineNew", isSignal: false, isRequired: false, transformFunction: null }, entityName: { classPropertyName: "entityName", publicName: "entityName", isSignal: false, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: false, isRequired: false, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: false, isRequired: false, transformFunction: null }, groupOptionsKey: { classPropertyName: "groupOptionsKey", publicName: "groupOptionsKey", isSignal: false, isRequired: false, transformFunction: null }, groupLabelFn: { classPropertyName: "groupLabelFn", publicName: "groupLabelFn", isSignal: false, isRequired: false, transformFunction: null }, sideloadDataKey: { classPropertyName: "sideloadDataKey", publicName: "sideloadDataKey", isSignal: true, isRequired: false, transformFunction: null }, responseParserFn: { classPropertyName: "responseParserFn", publicName: "responseParserFn", isSignal: true, isRequired: false, transformFunction: null }, searchText: { classPropertyName: "searchText", publicName: "searchText", isSignal: false, isRequired: false, transformFunction: null }, notFoundText: { classPropertyName: "notFoundText", publicName: "notFoundText", isSignal: false, isRequired: false, transformFunction: null }, addItemText: { classPropertyName: "addItemText", publicName: "addItemText", isSignal: false, isRequired: false, transformFunction: null }, optionLabelTemplate: { classPropertyName: "optionLabelTemplate", publicName: "optionLabelTemplate", isSignal: true, isRequired: false, transformFunction: null }, entities: { classPropertyName: "entities", publicName: "entities", isSignal: false, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: false, isRequired: false, transformFunction: null }, userAriaDescribedBy: { classPropertyName: "userAriaDescribedBy", publicName: "aria-describedby", isSignal: false, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: false, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: false, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", createNewItemSelected: "createNewItemSelected" }, host: { properties: { "id": "this.id" } }, providers: [
683
+ { provide: MatFormFieldControl, useExisting: SPMatSelectEntityComponent },
684
+ ], viewQueries: [{ propertyName: "matSel", first: true, predicate: MatSelect, descendants: true }, { propertyName: "matSelect", first: true, predicate: MatSelect, descendants: true }], ngImport: i0, template: `
660
685
  <mat-select
661
686
  [placeholder]="placeholder"
662
687
  (opened)="onSelectOpened($event)"
@@ -667,7 +692,9 @@ class SPMatSelectEntityComponent {
667
692
  <mat-select-trigger>
668
693
  {{ selectTriggerValue }}
669
694
  @if (selectTriggerValueAsArray.length > 1) {
670
- <span class="addl-selection-count"> (+{{ selectTriggerValueAsArray.length - 1 }}) </span>
695
+ <span class="addl-selection-count">
696
+ (+{{ selectTriggerValueAsArray.length - 1 }})
697
+ </span>
671
698
  }
672
699
  </mat-select-trigger>
673
700
 
@@ -683,31 +710,50 @@ class SPMatSelectEntityComponent {
683
710
  </mat-option>
684
711
 
685
712
  <ng-container *ngIf="!group; else groupedOptions">
686
- <span *ngIf="(filteredValues | async) as entities">
687
- <mat-option class="sel-entity-option" *ngFor="let entity of entities" [value]="entityId(entity)">
713
+ <span *ngIf="filteredValues | async as entities">
714
+ <ng-template #defaultOptionLabelTemplate let-entity>
688
715
  {{ entityLabelFn(entity) }}
716
+ </ng-template>
717
+ @for (entity of entities; track entityId(entity)) {
718
+ <mat-option class="sel-entity-option" [value]="entityId(entity)">
719
+ <ng-container
720
+ *ngTemplateOutlet="
721
+ optionLabelTemplate() || defaultOptionLabelTemplate;
722
+ context: { $implicit: entity }
723
+ "
724
+ ></ng-container>
689
725
  </mat-option>
726
+ }
727
+
728
+ <!-- <mat-option class="sel-entity-option" *ngFor="let entity of entities" [value]="entityId(entity)">
729
+ {{ entityLabelFn(entity) }}
730
+ </mat-option> -->
690
731
  </span>
691
732
  </ng-container>
692
733
  <ng-template #groupedOptions>
693
- <span *ngIf="(filteredGroupedValues | async) as groups">
734
+ <span *ngIf="filteredGroupedValues | async as groups">
694
735
  @for (group of groups; track groupLabel(group)) {
695
- <mat-optgroup [label]="groupLabel(group)">
696
- @for (entity of group.__items__; track entityId(entity)) {
697
- <mat-option class="sel-entity-option" [value]="entityId(entity)">
698
- {{ entityLabelFn(entity) }}
699
- </mat-option>
700
- }
701
- </mat-optgroup>
736
+ <mat-optgroup [label]="groupLabel(group)">
737
+ @for (entity of group.__items__; track entityId(entity)) {
738
+
739
+ <mat-option class="sel-entity-option" [value]="entityId(entity)">
740
+ {{ entityLabelFn(entity) }}
741
+ </mat-option>
742
+ }
743
+ </mat-optgroup>
702
744
  }
703
745
  </span>
704
746
  </ng-template>
705
747
 
706
- <mat-option *ngIf="!multiple && inlineNew" class="add-item-option" value="0" (click)="$event.stopPropagation()"
748
+ <mat-option
749
+ *ngIf="!multiple && inlineNew"
750
+ class="add-item-option"
751
+ value="0"
752
+ (click)="$event.stopPropagation()"
707
753
  >⊕ {{ addItemText }}</mat-option
708
754
  >
709
755
  </mat-select>
710
- `, isInline: true, styles: [".add-item-option{padding-top:2px;border-top:1px solid gray}.addl-selection-count{opacity:.75;font-size:.8em}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormsModule }, { 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: ReactiveFormsModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i4.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i5.MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "ngmodule", type: NgxMatSelectSearchModule }, { kind: "component", type: i6.MatSelectSearchComponent, selector: "ngx-mat-select-search", inputs: ["placeholderLabel", "type", "closeIcon", "closeSvgIcon", "noEntriesFoundLabel", "clearSearchInput", "searching", "disableInitialFocus", "enableClearOnEscapePressed", "preventHomeEndKeyPropagation", "disableScrollToActiveOnOptionsChanged", "ariaLabel", "showToggleAllCheckbox", "toggleAllCheckboxChecked", "toggleAllCheckboxIndeterminate", "toggleAllCheckboxTooltipMessage", "toggleAllCheckboxTooltipPosition", "hideClearSearchButton", "alwaysRestoreSelectedOptionsMulti", "recreateValuesArray"], outputs: ["toggleAll"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
756
+ `, isInline: true, styles: [".add-item-option{padding-top:2px;border-top:1px solid gray}.addl-selection-count{opacity:.75;font-size:.8em}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormsModule }, { 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: ReactiveFormsModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i3.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i3.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i4.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i4.MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "ngmodule", type: NgxMatSelectSearchModule }, { kind: "component", type: i5.MatSelectSearchComponent, selector: "ngx-mat-select-search", inputs: ["placeholderLabel", "type", "closeIcon", "closeSvgIcon", "noEntriesFoundLabel", "clearSearchInput", "searching", "disableInitialFocus", "enableClearOnEscapePressed", "preventHomeEndKeyPropagation", "disableScrollToActiveOnOptionsChanged", "ariaLabel", "showToggleAllCheckbox", "toggleAllCheckboxChecked", "toggleAllCheckboxIndeterminate", "toggleAllCheckboxTooltipMessage", "toggleAllCheckboxTooltipPosition", "hideClearSearchButton", "alwaysRestoreSelectedOptionsMulti", "recreateValuesArray"], outputs: ["toggleAll"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
711
757
  }
712
758
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: SPMatSelectEntityComponent, decorators: [{
713
759
  type: Component,
@@ -722,7 +768,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImpor
722
768
  <mat-select-trigger>
723
769
  {{ selectTriggerValue }}
724
770
  @if (selectTriggerValueAsArray.length > 1) {
725
- <span class="addl-selection-count"> (+{{ selectTriggerValueAsArray.length - 1 }}) </span>
771
+ <span class="addl-selection-count">
772
+ (+{{ selectTriggerValueAsArray.length - 1 }})
773
+ </span>
726
774
  }
727
775
  </mat-select-trigger>
728
776
 
@@ -738,46 +786,60 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImpor
738
786
  </mat-option>
739
787
 
740
788
  <ng-container *ngIf="!group; else groupedOptions">
741
- <span *ngIf="(filteredValues | async) as entities">
742
- <mat-option class="sel-entity-option" *ngFor="let entity of entities" [value]="entityId(entity)">
789
+ <span *ngIf="filteredValues | async as entities">
790
+ <ng-template #defaultOptionLabelTemplate let-entity>
743
791
  {{ entityLabelFn(entity) }}
792
+ </ng-template>
793
+ @for (entity of entities; track entityId(entity)) {
794
+ <mat-option class="sel-entity-option" [value]="entityId(entity)">
795
+ <ng-container
796
+ *ngTemplateOutlet="
797
+ optionLabelTemplate() || defaultOptionLabelTemplate;
798
+ context: { $implicit: entity }
799
+ "
800
+ ></ng-container>
744
801
  </mat-option>
802
+ }
803
+
804
+ <!-- <mat-option class="sel-entity-option" *ngFor="let entity of entities" [value]="entityId(entity)">
805
+ {{ entityLabelFn(entity) }}
806
+ </mat-option> -->
745
807
  </span>
746
808
  </ng-container>
747
809
  <ng-template #groupedOptions>
748
- <span *ngIf="(filteredGroupedValues | async) as groups">
810
+ <span *ngIf="filteredGroupedValues | async as groups">
749
811
  @for (group of groups; track groupLabel(group)) {
750
- <mat-optgroup [label]="groupLabel(group)">
751
- @for (entity of group.__items__; track entityId(entity)) {
752
- <mat-option class="sel-entity-option" [value]="entityId(entity)">
753
- {{ entityLabelFn(entity) }}
754
- </mat-option>
755
- }
756
- </mat-optgroup>
812
+ <mat-optgroup [label]="groupLabel(group)">
813
+ @for (entity of group.__items__; track entityId(entity)) {
814
+
815
+ <mat-option class="sel-entity-option" [value]="entityId(entity)">
816
+ {{ entityLabelFn(entity) }}
817
+ </mat-option>
818
+ }
819
+ </mat-optgroup>
757
820
  }
758
821
  </span>
759
822
  </ng-template>
760
823
 
761
- <mat-option *ngIf="!multiple && inlineNew" class="add-item-option" value="0" (click)="$event.stopPropagation()"
824
+ <mat-option
825
+ *ngIf="!multiple && inlineNew"
826
+ class="add-item-option"
827
+ value="0"
828
+ (click)="$event.stopPropagation()"
762
829
  >⊕ {{ addItemText }}</mat-option
763
830
  >
764
831
  </mat-select>
765
- `, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, FormsModule, ReactiveFormsModule, MatSelectModule, NgxMatSelectSearchModule], providers: [{ provide: MatFormFieldControl, useExisting: SPMatSelectEntityComponent }], styles: [".add-item-option{padding-top:2px;border-top:1px solid gray}.addl-selection-count{opacity:.75;font-size:.8em}\n"] }]
766
- }], ctorParameters: () => [{ type: i1.HttpClient }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.Injector }, { type: i7.MatFormField, decorators: [{
767
- type: Optional
768
- }, {
769
- type: Inject,
770
- args: [MAT_FORM_FIELD]
771
- }] }, { type: i2.NgControl, decorators: [{
772
- type: Optional
773
- }, {
774
- type: Self
775
- }] }, { type: undefined, decorators: [{
776
- type: Optional
777
- }, {
778
- type: Inject,
779
- args: [SP_MAT_SELECT_ENTITY_CONFIG]
780
- }] }], propDecorators: { matSel: [{
832
+ `, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
833
+ CommonModule,
834
+ NgTemplateOutlet,
835
+ FormsModule,
836
+ ReactiveFormsModule,
837
+ MatSelectModule,
838
+ NgxMatSelectSearchModule,
839
+ ], providers: [
840
+ { provide: MatFormFieldControl, useExisting: SPMatSelectEntityComponent },
841
+ ], styles: [".add-item-option{padding-top:2px;border-top:1px solid gray}.addl-selection-count{opacity:.75;font-size:.8em}\n"] }]
842
+ }], ctorParameters: () => [], propDecorators: { matSel: [{
781
843
  type: ViewChild,
782
844
  args: [MatSelect]
783
845
  }], entityLabelFn: [{
@@ -1 +1 @@
1
- {"version":3,"file":"smallpearl-ngx-helper-mat-select-entity.mjs","sources":["../../../../projects/smallpearl/ngx-helper/mat-select-entity/src/providers.ts","../../../../projects/smallpearl/ngx-helper/mat-select-entity/src/mat-select-entity.component.ts","../../../../projects/smallpearl/ngx-helper/mat-select-entity/smallpearl-ngx-helper-mat-select-entity.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\nexport interface SPMatSelectEntityConfig {\n i18n: {\n search: string;\n notFound: string;\n // Any embedded \"{{ item }}\" in the addItem string will be replaced\n // with entityName property value. If entityName is not specified\n // \"Item\" will be used as the value for \"{{ item }}\".\n addItem: string;\n };\n}\n\nexport const SP_MAT_SELECT_ENTITY_CONFIG = new InjectionToken<SPMatSelectEntityConfig>(\n 'SPMatSelectEntityConfig'\n );\n","import { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { CommonModule } from '@angular/common';\nimport { HttpClient, HttpContext, HttpContextToken, HttpParams } from '@angular/common/http';\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n computed,\n ElementRef,\n EventEmitter,\n HostBinding,\n Inject,\n Injector,\n input,\n Input,\n OnDestroy,\n OnInit,\n Optional,\n Output,\n Self,\n ViewChild\n} from '@angular/core';\nimport { ControlValueAccessor, FormsModule, NgControl, ReactiveFormsModule, Validators } from '@angular/forms';\nimport { MAT_FORM_FIELD, MatFormField, MatFormFieldControl } from '@angular/material/form-field';\nimport { MatSelect, MatSelectChange, MatSelectModule } from '@angular/material/select';\nimport { NgxMatSelectSearchModule } from 'ngx-mat-select-search';\nimport {\n BehaviorSubject,\n combineLatest,\n debounceTime,\n Observable,\n of,\n Subject,\n switchMap,\n takeUntil,\n tap\n} from 'rxjs';\nimport { SP_MAT_SELECT_ENTITY_CONFIG, SPMatSelectEntityConfig } from './providers';\nimport { getNgxHelperConfig } from '@smallpearl/ngx-helper/core';\nimport { plural } from 'pluralize';\nimport { camelCase } from 'lodash';\n\nexport interface SPMatSelectEntityHttpContext {\n entityName: string;\n entityNamePlural: string;\n endpoint: string;\n}\n\nexport const SP_MAT_SELECT_ENTITY_HTTP_CONTEXT =\n new HttpContextToken<SPMatSelectEntityHttpContext>(() => ({\n entityName: '',\n entityNamePlural: '',\n endpoint: '',\n }));\n\nconst DEFAULT_SP_MAT_SELECT_ENTITY_CONFIG: SPMatSelectEntityConfig =\n {\n i18n: {\n search: 'Search',\n notFound: 'Not found',\n addItem: 'New Item',\n },\n };\n\ntype EntityGroup<T> = {\n id?: PropertyKey;\n name?: string;\n label?: string;\n description?: string;\n items?: T[];\n __items__?: T[]; // for internal use\n};\n\nexport type SPMatSelectEntityResponseParser = <\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n>(\n response: any\n) => Array<TEntity>;\n\n/**\n * This is a generic component to display a <mat-select> for a FK field\n * where the select's options are dynamically loaded from the server using\n * the given url (or URL). The objects thus retrieved should have a\n * unique 'id' field that will be used as the value of each `option` element.\n * Therefore upon selection of an `option` element, the `select` value will\n * be set to the object's `id` property. By default 'id' is used as its id,\n * but this can be customized by specifying the `idKey' property value.\n */\n@Component({\n selector: 'sp-mat-select-entity',\n template: `\n <mat-select\n [placeholder]=\"placeholder\"\n (opened)=\"onSelectOpened($event)\"\n (selectionChange)=\"onSelectionChange($event)\"\n [multiple]=\"multiple\"\n [(ngModel)]=\"selectValue\"\n >\n <mat-select-trigger>\n {{ selectTriggerValue }}\n @if (selectTriggerValueAsArray.length > 1) {\n <span class=\"addl-selection-count\"> (+{{ selectTriggerValueAsArray.length - 1 }}) </span>\n }\n </mat-select-trigger>\n\n <mat-option>\n <ngx-mat-select-search\n [(ngModel)]=\"filterStr\"\n (ngModelChange)=\"this.filter$.next($event)\"\n [placeholderLabel]=\"searchText\"\n [noEntriesFoundLabel]=\"notFoundText\"\n [searching]=\"searching\"\n >\n </ngx-mat-select-search>\n </mat-option>\n\n <ng-container *ngIf=\"!group; else groupedOptions\">\n <span *ngIf=\"(filteredValues | async) as entities\">\n <mat-option class=\"sel-entity-option\" *ngFor=\"let entity of entities\" [value]=\"entityId(entity)\">\n {{ entityLabelFn(entity) }}\n </mat-option>\n </span>\n </ng-container>\n <ng-template #groupedOptions>\n <span *ngIf=\"(filteredGroupedValues | async) as groups\">\n @for (group of groups; track groupLabel(group)) {\n <mat-optgroup [label]=\"groupLabel(group)\">\n @for (entity of group.__items__; track entityId(entity)) {\n <mat-option class=\"sel-entity-option\" [value]=\"entityId(entity)\">\n {{ entityLabelFn(entity) }}\n </mat-option>\n }\n </mat-optgroup>\n }\n </span>\n </ng-template>\n\n <mat-option *ngIf=\"!multiple && inlineNew\" class=\"add-item-option\" value=\"0\" (click)=\"$event.stopPropagation()\"\n >⊕ {{ addItemText }}</mat-option\n >\n </mat-select>\n `,\n styles: [\n `\n .add-item-option {\n padding-top: 2px;\n border-top: 1px solid gray;\n }\n .addl-selection-count {\n opacity: 0.75;\n font-size: 0.8em;\n }\n `\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [CommonModule, FormsModule, ReactiveFormsModule, MatSelectModule, NgxMatSelectSearchModule],\n providers: [{ provide: MatFormFieldControl, useExisting: SPMatSelectEntityComponent }]\n})\nexport class SPMatSelectEntityComponent<TEntity extends { [P in IdKey]: PropertyKey }, IdKey extends string = 'id'>\n implements\n OnInit,\n OnDestroy,\n AfterViewInit,\n ControlValueAccessor,\n MatFormFieldControl<string | number | string[] | number[]>\n{\n // We cache the entities that we fetch from remote here. Cache is indexed\n // by the endpoint. Each endpoint also keeps a refCount, which is incremented\n // for each instance of the component using the same endpoint. When this\n // refcount reaches 0, the endpoint is removed from the cache.\n //\n // This mechanism is to suppress multiple fetches from the remote from the\n // same endpoint as that can occur if a form has multiple instances of\n // this component, with the same endpoint.\n static _entitiesCache = new Map<string, { refCount: number; entities: Array<any> }>();\n\n @ViewChild(MatSelect) matSel!: MatSelect;\n\n // REQUIRED PROPERTIES //\n /**\n * Entity label function. Given an entity return its natural label\n * to display to the user.\n */\n @Input({ required: true }) entityLabelFn!: (entity: TEntity) => string;\n\n // OPTIONAL PROPERTIES //\n /**\n * Entity filter function - return a boolean if the entity is to be included\n * in the filtered entities list.\n * @param entity: TEntity object to test for 'search' string.\n * @param search - search string\n */\n @Input({ required: false }) entityFilterFn!: (entity: TEntity, search: string) => boolean;\n /**\n * Entity idKey, if idKey is different from the default 'id'.\n */\n @Input({ required: false }) idKey = 'id';\n /**\n * URL of the remote from where entities are to be loaded.\n * This won't be used if `loadFromRemoteFn` is specified.\n */\n @Input({ required: false }) url!: string;\n /**\n * Parameters to be added to the HTTP request to retrieve data from\n * remote. This won't be used if `loadFromRemoteFn` is specified.\n */\n @Input({ required: false }) httpParams!: HttpParams;\n /**\n * Function to load entities from remote.\n */\n @Input({ required: false }) loadFromRemoteFn!: (injector: Injector) => Observable<TEntity[]>;\n\n @Input({ required: false }) inlineNew: boolean = false;\n /**\n * Entity name, that is used to form the \"New { item }\" menu item if\n * inlineNew=true. This is also used as the key of the object in GET response\n * if the reponse JSON is not an array and rather an object, where the values\n * are stored indexed by the server model name. For eg:-\n *\n * {\n * 'customers': [\n * {...},\n * {...},\n * {...},\n * ]\n * }\n */\n @Input({ required: false }) entityName!: string;\n // Set to true to allow multiple option selection. The returned value\n // would be an array of entity ids.\n @Input({ required: false }) multiple = false;\n /*\n Whether to group options using <mat-optgroup></mat-optgroup>.\n If set to true, the response from the server should be an array of\n groups of TEntity objects, where each object is of the form:\n [\n {\n id: <id>,\n name|label: <>,\n items|<plural_entityName>|<custom_key>: [\n TEntity,\n ...\n ]\n },\n ...\n ]\n */\n @Input({ required: false }) group = false;\n /**\n * The group object key name under which options are stored. Defaults to\n * 'items' or pluralized 'entityName'. Ideally the client class should\n * explicitly set this property value.\n */\n @Input({ required: false }) groupOptionsKey!: string;\n /**\n * If groupOptions = true, specify this to provide accurate label for each\n * group. If not specified, group label will be determined by looking up one\n * of the standard fields - name, label or description - whichever comes\n * first.\n */\n @Input({ required: false }) groupLabelFn!: (group: any) => string;\n /**\n * Sideload data key name.\n */\n sideloadDataKey = input<string>();\n /**\n * Parser function to return the list of entities from the GET response.\n */\n responseParserFn = input<SPMatSelectEntityResponseParser>();\n\n @Output() selectionChange = new EventEmitter<TEntity|TEntity[]>();\n @Output() createNewItemSelected = new EventEmitter<void>();\n\n // allow per component customization\n @Input() searchText!: string;\n @Input() notFoundText!: string;\n @Input() addItemText!: string;\n\n _sideloadDataKey = computed<string>(() => {\n if (this.sideloadDataKey()) {\n return this.sideloadDataKey() as string;\n }\n return this.entityName ? plural(camelCase(this.entityName)) : 'results';\n });\n\n private _entities = new Map<PropertyKey, TEntity>();\n private _groupedEntities = new Array<EntityGroup<TEntity>>();\n\n stateChanges = new Subject<void>();\n focused = false;\n touched = false;\n\n selectValue!: string | number | string[] | number[];\n // For storing last select value, which we use to restore the select's value\n // to when New Item is selected. This ensures that when New Item is selected,\n // the select's value remains the same. If the newly created item is to be\n // set as the select's value, the corresponding TEntity has to be added\n // to _entities (via addEntity()) and then selected by setting the\n // corresponding formControl's value to the entity's id.\n lastSelectValue!: string | number | string[] | number[];\n searching = false;\n filterStr: string = '';\n\n filter$ = new BehaviorSubject<string>('');\n // ControlValueAccessor callback\n onChanged = (_: any) => {};\n onTouched = () => {};\n @ViewChild(MatSelect) matSelect!: MatSelect;\n\n filteredValues = new Subject<TEntity[]>();\n filteredGroupedValues = new Subject<EntityGroup<TEntity>[]>();\n\n destroy = new Subject<void>();\n private loaded = false;\n private load$ = new BehaviorSubject<boolean>(false);\n\n static nextId = 0;\n @HostBinding() id = `sp-select-entity-${SPMatSelectEntityComponent.nextId++}`;\n private _placeholder!: string;\n ngxHelperConfig = getNgxHelperConfig();\n\n constructor(\n protected http: HttpClient,\n protected cdr: ChangeDetectorRef,\n protected _elementRef: ElementRef<HTMLElement>,\n protected injector: Injector,\n @Optional() @Inject(MAT_FORM_FIELD) public _formField: MatFormField,\n @Optional() @Self() public ngControl: NgControl,\n @Optional() @Inject(SP_MAT_SELECT_ENTITY_CONFIG) private config: SPMatSelectEntityConfig\n ) {\n if (this.ngControl != null) {\n this.ngControl.valueAccessor = this;\n }\n }\n\n ngOnInit() {\n this._initStrings();\n combineLatest([this.filter$.pipe(debounceTime(400)), this.load$])\n .pipe(\n takeUntil(this.destroy),\n switchMap(([str, load]) => {\n if (load && !this.loaded) {\n this.searching = true;\n this.cdr.detectChanges();\n return this.loadFromRemote();\n } else {\n return of(this.entities ?? []);\n }\n }),\n tap(() => {\n if (this.group) {\n this.filterGroupedValues(this.filterStr);\n } else {\n this.filterValues(this.filterStr);\n }\n this.cdr.detectChanges();\n })\n )\n .subscribe();\n }\n ngOnDestroy(): void {\n this.destroy.next();\n this.removeFromCache();\n this.stateChanges.complete();\n }\n\n ngAfterViewInit(): void {\n // I'm not sure this is how this logic is right, but this seems to work.\n // if (this.ngControl && this.ngControl.control?.validator) {\n // const validator = this.ngControl.control.validator;\n // const res = validator(this.ngControl.control);\n // if (res && res['required']) {\n // this.required = true;\n // }\n // }\n }\n\n private _initStrings() {\n const config: SPMatSelectEntityConfig = this.config ?? DEFAULT_SP_MAT_SELECT_ENTITY_CONFIG;\n if (!this.searchText) { this.searchText = config.i18n.search; }\n if (!this.notFoundText) { this.notFoundText = config.i18n.notFound; }\n if (!this.addItemText) { this.addItemText = config.i18n.addItem.replace(/\\{\\{\\s*item\\s*}}/, this.entityName ?? \"**Item\"); }\n }\n\n addEntity(entity: TEntity) {\n this._entities.set((entity as any)[this.idKey], entity);\n // So that the newly added entity will be added to the <mat-option> list.\n this.filterValues(this.filterStr);\n this.cdr.detectChanges();\n }\n\n get selectTriggerValue() {\n if (this.selectValue) {\n const firstSelected = Array.isArray(this.selectValue) ? this.selectValue[0] : this.selectValue;\n const selectedEntity = this._entities.get(firstSelected);\n return selectedEntity ? this.entityLabelFn(selectedEntity) : '';\n }\n return '';\n }\n\n get selectTriggerValueAsArray() {\n return Array.isArray(this.selectValue) ? (this.selectValue as Array<string | number>) : [];\n }\n\n entityId(entity: TEntity) {\n return (entity as any)[this.idKey];\n }\n\n writeValue(entityId: string | number | string[] | number[]): void {\n if (Array.isArray(entityId)) {\n if (this.multiple) {\n const selectedValues: any[] = [];\n entityId.forEach(id => {\n if (this._entities.has(id)) {\n selectedValues.push(id);\n }\n });\n this.selectValue = selectedValues;\n this.cdr.detectChanges();\n }\n } else {\n if (this._entities.has(entityId)) {\n this.selectValue = entityId;\n if (this.filterStr) {\n this.filterStr = '';\n this.filterValues(this.filterStr);\n }\n this.cdr.detectChanges();\n }\n }\n }\n registerOnChange(fn: any): void {\n this.onChanged = fn;\n }\n registerOnTouched(fn: any): void {\n this.onTouched = fn;\n }\n\n @Input()\n get entities(): TEntity[] {\n return Array.from(this._entities.values());\n }\n\n set entities(items: TEntity[]) {\n if (!this.group) {\n items.forEach(item => {\n this._entities.set((item as any)[this.idKey], item);\n });\n } else {\n this._groupedEntities = (items as any) as EntityGroup<TEntity>[];\n this._groupedEntities.forEach(group => {\n const key = this.groupEntitiesKey();\n const groupEntities = (group as any)[key] as TEntity[];\n (group as any)['__items__'] = groupEntities;\n groupEntities.forEach(item => {\n this._entities.set((item as any)[this.idKey], item);\n });\n });\n }\n }\n\n @Input()\n get value(): string | number | string[] | number[] {\n return this.selectValue;\n }\n set value(val: string | number | string[] | number[]) {\n this.selectValue = val;\n this.stateChanges.next();\n }\n get shouldLabelFloat() {\n return this.focused || !this.empty;\n }\n\n @Input('aria-describedby') userAriaDescribedBy!: string;\n\n @Input()\n get placeholder(): string {\n return this._placeholder;\n }\n set placeholder(value: string) {\n this._placeholder = value;\n this.stateChanges.next();\n }\n\n @Input()\n get required() {\n return this._required ?? this.ngControl?.control?.hasValidator(Validators.required);\n }\n set required(req: boolean) {\n this._required = coerceBooleanProperty(req);\n this.stateChanges.next();\n }\n // Deliberately 'undefined' so that `get required()` will return the state\n // from ngControl's validators.\n private _required!: boolean;\n\n @Input()\n get disabled(): boolean {\n return this._disabled ?? this.ngControl?.control?.disabled;\n }\n set disabled(value: BooleanInput) {\n const disabled = coerceBooleanProperty(value);;\n if (disabled !== this._disabled) {\n this.setDisabledState(disabled);\n this.stateChanges.next();\n }\n }\n // Same as `_required`, deliberately `undefined` by default.\n private _disabled!: boolean;\n\n get empty() {\n // TODO\n return !this.value;\n }\n get errorState(): boolean {\n // TODO\n return false;\n }\n\n onFocusIn(event: FocusEvent) {\n if (!this.focused) {\n this.focused = true;\n this.stateChanges.next();\n }\n }\n\n onFocusOut(event: FocusEvent) {\n if (!this._elementRef.nativeElement.contains(event.relatedTarget as Element)) {\n this.touched = true;\n this.focused = false;\n this.onTouched();\n this.stateChanges.next();\n }\n }\n\n setDescribedByIds(ids: string[]) {}\n\n onContainerClick() {\n // this._focusMonitor.focusVia(this.countrySelect, 'program');\n // if (this.parts.controls.national.valid) {\n // this._focusMonitor.focusVia(this.nationalInput, 'program');\n // } else if (this.parts.controls.country.valid) {\n // this._focusMonitor.focusVia(this.nationalInput, 'program');\n // // } else if (this.parts.controls.national.valid) {\n // // this._focusMonitor.focusVia(this.nationalInput, 'program');\n // } else {\n // this._focusMonitor.focusVia(this.countrySelect, 'program');\n // }\n }\n\n setDisabledState(isDisabled: boolean): void {\n this._disabled = isDisabled;\n if (this.matSelect) {\n this.matSelect.setDisabledState(isDisabled);\n this.cdr.detectChanges();\n }\n }\n onSelectOpened(ev: any) {\n // Store the current select value so that we can restore it if user\n // eventually selects 'New Item' option.\n this.lastSelectValue = this.selectValue;\n // If values have not been loaded from remote, trigger a load.\n if (!this.loaded) {\n this.load$.next(true); // this will trigger the loadFromRemote() call.\n }\n }\n onSelectionChange(ev: MatSelectChange) {\n // console.log('SelectionChange - sel:', ev);\n if (Array.isArray(ev.value)) {\n this.selectValue = ev.value;\n this.onTouched();\n this.onChanged(ev.value);\n const selectedEntities: TEntity[] = ev.value.map(id => this._entities.get(id)) as TEntity[];\n this.selectionChange.emit(selectedEntities);\n } else {\n if (ev.value !== '0') {\n this.selectValue = ev.value;\n this.onTouched();\n this.onChanged(ev.value);\n this.selectionChange.emit(this._entities.get(ev.value));\n } else {\n // New Item activated, return value to previous value. We track\n // previous value via 'lastSelectValue' member which is updated\n // whenever the select is opened.\n if (this.ngControl) {\n this.ngControl.control?.setValue(this.lastSelectValue)\n }\n ev.source.value = this.lastSelectValue;\n this.createNewItemSelected.emit();\n this.cdr.detectChanges();\n }\n }\n }\n\n filterValues(search: string) {\n const searchLwr = search.toLocaleLowerCase();\n const entities = this.entities;\n if (!entities) {\n return;\n }\n if (!search) {\n this.filteredValues.next(entities.slice());\n } else {\n this.filteredValues.next(\n entities.filter((member) => {\n if (this.entityFilterFn) {\n return this.entityFilterFn(member, search);\n }\n return this.entityLabelFn(member).toLocaleLowerCase().includes(searchLwr);\n })\n );\n }\n }\n\n /**\n * Filtering grouped entities logic works like this. If the search string\n * matches a group label, the entire group is to be included in the results.\n * However, if the search string only matches certain entities, only those\n * groups are to be included and within those groups, only entities whose\n * label matches the search string are to be included in the result set.\n * @param search\n * @returns\n */\n filterGroupedValues(search: string) {\n const searchLwr = search.toLocaleLowerCase();\n const groups = this._groupedEntities;\n if (!groups) {\n return;\n }\n if (!search) {\n const groupsCopy = groups.slice();\n this.filteredGroupedValues.next(groupsCopy);\n } else {\n const groupEntitiesKey = this.groupEntitiesKey();\n const groups = this._groupedEntities.map(ge => {\n const label = this.groupLabel(ge);\n if (label.toLocaleLowerCase().includes(searchLwr)) {\n return {...ge} as EntityGroup<TEntity>;\n } else {\n const groupEntities = ge.__items__?.filter(\n e => this.entityLabelFn(e).toLocaleLowerCase().includes(searchLwr)\n );\n const ret: any = {\n ...ge\n };\n ret['__items__'] = groupEntities ?? [];\n return ret as EntityGroup<TEntity>;\n }\n });\n // filter out groups with no entities\n // console.log(`Groups: ${JSON.stringify(groups)}`);\n this.filteredGroupedValues.next(groups.filter(\n (group) =>\n Array.isArray((group as any)[groupEntitiesKey]) &&\n (group as any)['__items__'].length > 0\n ));\n }\n }\n\n loadFromRemote() {\n if (!this.url && !this.loadFromRemoteFn) {\n // If user had initialized entities, they will be dispalyed\n // in the options list. If not, options would be empty.\n return of(this.group ? this.groupEntities : this.entities);\n }\n let cacheKey!: string;\n let obs: Observable<TEntity[]>;\n if (this.loadFromRemoteFn) {\n obs = this.loadFromRemoteFn(this.injector);\n } else {\n let params!: HttpParams;\n if (this.httpParams) {\n params = new HttpParams({\n fromString: this.httpParams.toString()\n })\n } else {\n params = new HttpParams();\n }\n params = params.set('paginate', false)\n cacheKey = this.getCacheKey();\n if (this.existsInCache()) {\n obs = of(this.getFromCache())\n } else {\n obs = this.http.get<any>(this.url, {\n context: this.getHttpReqContext(),\n params,\n });\n }\n }\n return obs.pipe(\n tap((entities) => {\n this.searching = false; // remote loading done, will hide the loading wheel\n // Handle DRF paginated response\n const responseParserFn = this.responseParserFn();\n if (responseParserFn) {\n entities = (responseParserFn(entities) as unknown) as TEntity[];\n } else {\n if (\n !Array.isArray(entities) &&\n entities['results'] &&\n Array.isArray(entities['results'])\n ) {\n entities = entities['results'];\n } else if ( // sideloaded response, where entities are usually provided in 'entityName'\n this._sideloadDataKey() &&\n !Array.isArray(entities) &&\n typeof entities === 'object' &&\n entities[this._sideloadDataKey()] &&\n Array.isArray(entities[this._sideloadDataKey()])\n ) {\n entities = entities[this._sideloadDataKey()];\n }\n }\n if (Array.isArray(entities)) {\n this.entities = entities;\n // if (this.group) {\n // this._groupedEntities = entities as EntityGroup<TEntity>[];\n // } else {\n // this.entities = entities;\n // }\n }\n this.loaded = true;\n this.addToCache(entities);\n this.cdr.detectChanges();\n })\n );\n }\n\n groupLabel(group: EntityGroup<TEntity>): string {\n if (this.groupLabelFn) {\n return this.groupLabelFn(group);\n }\n const standardLabelFields = ['name', 'label', 'desc', 'description'];\n for (let index = 0; index < standardLabelFields.length; index++) {\n const labelField = standardLabelFields[index];\n if ((group as any)[labelField]) {\n return (group as any)[labelField];\n }\n }\n return `Group ${String(group.id)}`;\n }\n\n groupEntities(group: EntityGroup<TEntity>): TEntity[] {\n const key = this.groupEntitiesKey();\n console.log(`groupEntities - group: ${JSON.stringify(group)}, key: ${key}`);\n return (group as any)[this.groupEntitiesKey()] ?? [];\n }\n\n groupEntitiesKey() {\n return this.groupOptionsKey ? this.groupOptionsKey\n : (this.entityName ? plural(this.entityName.toLocaleLowerCase()) : 'items');\n }\n\n private existsInCache() {\n const cacheKey = this.getCacheKey();\n if (cacheKey) {\n return SPMatSelectEntityComponent._entitiesCache.has(cacheKey);\n }\n return false;\n }\n\n private getCacheKey() {\n if (!this.loadFromRemoteFn) {\n let params!: HttpParams;\n if (this.httpParams) {\n params = new HttpParams({\n fromString: this.httpParams.toString()\n })\n } else {\n params = new HttpParams();\n }\n // params = params.set('paginate', false)\n return `${this.url}?${params.toString()}`;\n }\n return ''; // empty string evalutes to boolean(false)\n }\n private getFromCache() {\n const cacheKey = this.getCacheKey();\n if (cacheKey && SPMatSelectEntityComponent._entitiesCache.has(cacheKey)) {\n return SPMatSelectEntityComponent._entitiesCache.get(cacheKey)?.entities as TEntity[]\n }\n return [];\n }\n private addToCache(entities: TEntity[]) {\n const cacheKey = this.getCacheKey();\n if (cacheKey) {\n if (!SPMatSelectEntityComponent._entitiesCache.has(cacheKey)) {\n SPMatSelectEntityComponent._entitiesCache.set(cacheKey, {refCount: 0, entities});\n }\n const cacheEntry = SPMatSelectEntityComponent._entitiesCache.get(cacheKey);\n cacheEntry!.refCount += 1;\n }\n }\n private removeFromCache() {\n const cacheKey = this.getCacheKey();\n if (cacheKey) {\n const cacheEntry = SPMatSelectEntityComponent._entitiesCache.get(cacheKey);\n if (cacheEntry) {\n cacheEntry!.refCount -= 1;\n if (cacheEntry.refCount <= 0) {\n SPMatSelectEntityComponent._entitiesCache.delete(cacheKey);\n }\n }\n }\n }\n\n private getHttpReqContext() {\n const context = new HttpContext();\n const entityName = this.entityName;\n context.set(SP_MAT_SELECT_ENTITY_HTTP_CONTEXT, {\n entityName: this.entityName ?? '',\n entityNamePlural: this.entityName ? plural(this.entityName) : '',\n endpoint: this.url\n });\n return context;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;MAaa,2BAA2B,GAAG,IAAI,cAAc,CACzD,yBAAyB;;ACmChB,MAAA,iCAAiC,GAC5C,IAAI,gBAAgB,CAA+B,OAAO;AACxD,IAAA,UAAU,EAAE,EAAE;AACd,IAAA,gBAAgB,EAAE,EAAE;AACpB,IAAA,QAAQ,EAAE,EAAE;AACb,CAAA,CAAC;AAEJ,MAAM,mCAAmC,GACvC;AACE,IAAA,IAAI,EAAE;AACJ,QAAA,MAAM,EAAE,QAAQ;AAChB,QAAA,QAAQ,EAAE,WAAW;AACrB,QAAA,OAAO,EAAE,UAAU;AACpB,KAAA;CACF;AAkBH;;;;;;;;AAQG;MAuEU,0BAA0B,CAAA;AAoKzB,IAAA,IAAA;AACA,IAAA,GAAA;AACA,IAAA,WAAA;AACA,IAAA,QAAA;AACiC,IAAA,UAAA;AAChB,IAAA,SAAA;AAC8B,IAAA,MAAA;;;;;;;;;AA1J3D,IAAA,OAAO,cAAc,GAAG,IAAI,GAAG,EAAsD;AAE/D,IAAA,MAAM;;AAG5B;;;AAGG;AACwB,IAAA,aAAa;;AAGxC;;;;;AAKG;AACyB,IAAA,cAAc;AAC1C;;AAEG;IACyB,KAAK,GAAG,IAAI;AACxC;;;AAGG;AACyB,IAAA,GAAG;AAC/B;;;AAGG;AACyB,IAAA,UAAU;AACtC;;AAEG;AACyB,IAAA,gBAAgB;IAEhB,SAAS,GAAY,KAAK;AACtD;;;;;;;;;;;;;AAaG;AACyB,IAAA,UAAU;;;IAGV,QAAQ,GAAG,KAAK;AAC5C;;;;;;;;;;;;;;;AAeE;IAC0B,KAAK,GAAG,KAAK;AACzC;;;;AAIG;AACyB,IAAA,eAAe;AAC3C;;;;;AAKG;AACyB,IAAA,YAAY;AACxC;;AAEG;IACH,eAAe,GAAG,KAAK,EAAU;AACjC;;AAEG;IACH,gBAAgB,GAAG,KAAK,EAAmC;AAEjD,IAAA,eAAe,GAAG,IAAI,YAAY,EAAqB;AACvD,IAAA,qBAAqB,GAAG,IAAI,YAAY,EAAQ;;AAGjD,IAAA,UAAU;AACV,IAAA,YAAY;AACZ,IAAA,WAAW;AAEpB,IAAA,gBAAgB,GAAG,QAAQ,CAAS,MAAK;AACvC,QAAA,IAAI,IAAI,CAAC,eAAe,EAAE,EAAE;AAC1B,YAAA,OAAO,IAAI,CAAC,eAAe,EAAY;;AAEzC,QAAA,OAAO,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,GAAG,SAAS;AACzE,KAAC,CAAC;AAEM,IAAA,SAAS,GAAG,IAAI,GAAG,EAAwB;AAC3C,IAAA,gBAAgB,GAAG,IAAI,KAAK,EAAwB;AAE5D,IAAA,YAAY,GAAG,IAAI,OAAO,EAAQ;IAClC,OAAO,GAAG,KAAK;IACf,OAAO,GAAG,KAAK;AAEf,IAAA,WAAW;;;;;;;AAOX,IAAA,eAAe;IACf,SAAS,GAAG,KAAK;IACjB,SAAS,GAAW,EAAE;AAEtB,IAAA,OAAO,GAAG,IAAI,eAAe,CAAS,EAAE,CAAC;;AAEzC,IAAA,SAAS,GAAG,CAAC,CAAM,KAAI,GAAG;AAC1B,IAAA,SAAS,GAAG,MAAK,GAAG;AACE,IAAA,SAAS;AAE/B,IAAA,cAAc,GAAG,IAAI,OAAO,EAAa;AACzC,IAAA,qBAAqB,GAAG,IAAI,OAAO,EAA0B;AAE7D,IAAA,OAAO,GAAG,IAAI,OAAO,EAAQ;IACrB,MAAM,GAAG,KAAK;AACd,IAAA,KAAK,GAAG,IAAI,eAAe,CAAU,KAAK,CAAC;AAEnD,IAAA,OAAO,MAAM,GAAG,CAAC;AACF,IAAA,EAAE,GAAG,CAAoB,iBAAA,EAAA,0BAA0B,CAAC,MAAM,EAAE,EAAE;AACrE,IAAA,YAAY;IACpB,eAAe,GAAG,kBAAkB,EAAE;AAEtC,IAAA,WAAA,CACY,IAAgB,EAChB,GAAsB,EACtB,WAAoC,EACpC,QAAkB,EACe,UAAwB,EACxC,SAAoB,EACU,MAA+B,EAAA;QAN9E,IAAI,CAAA,IAAA,GAAJ,IAAI;QACJ,IAAG,CAAA,GAAA,GAAH,GAAG;QACH,IAAW,CAAA,WAAA,GAAX,WAAW;QACX,IAAQ,CAAA,QAAA,GAAR,QAAQ;QACyB,IAAU,CAAA,UAAA,GAAV,UAAU;QAC1B,IAAS,CAAA,SAAA,GAAT,SAAS;QACqB,IAAM,CAAA,MAAA,GAAN,MAAM;AAE/D,QAAA,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,EAAE;AAC1B,YAAA,IAAI,CAAC,SAAS,CAAC,aAAa,GAAG,IAAI;;;IAIvC,QAAQ,GAAA;QACN,IAAI,CAAC,YAAY,EAAE;AACnB,QAAA,aAAa,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC;AAC7D,aAAA,IAAI,CACH,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,EACvB,SAAS,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,KAAI;AACxB,YAAA,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;AACxB,gBAAA,IAAI,CAAC,SAAS,GAAG,IAAI;AACrB,gBAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;AACxB,gBAAA,OAAO,IAAI,CAAC,cAAc,EAAE;;iBACvB;gBACL,OAAO,EAAE,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;;AAElC,SAAC,CAAC,EACF,GAAG,CAAC,MAAK;AACP,YAAA,IAAI,IAAI,CAAC,KAAK,EAAE;AACd,gBAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC;;iBACnC;AACL,gBAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC;;AAEnC,YAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;AAC1B,SAAC,CAAC;AAEH,aAAA,SAAS,EAAE;;IAEhB,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;QACnB,IAAI,CAAC,eAAe,EAAE;AACtB,QAAA,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE;;IAG9B,eAAe,GAAA;;;;;;;;;;IAWP,YAAY,GAAA;AAClB,QAAA,MAAM,MAAM,GAA4B,IAAI,CAAC,MAAM,IAAI,mCAAmC;AAC1F,QAAA,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;YAAE,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM;;AAC5D,QAAA,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;YAAE,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ;;AAClE,QAAA,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;AAAE,YAAA,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,UAAU,IAAI,QAAQ,CAAC;;;AAG1H,IAAA,SAAS,CAAC,MAAe,EAAA;AACvB,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAE,MAAc,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;;AAEvD,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC;AACjC,QAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;;AAG1B,IAAA,IAAI,kBAAkB,GAAA;AACpB,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE;YACpB,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW;YAC9F,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC;AACxD,YAAA,OAAO,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,GAAG,EAAE;;AAEjE,QAAA,OAAO,EAAE;;AAGX,IAAA,IAAI,yBAAyB,GAAA;AAC3B,QAAA,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,GAAI,IAAI,CAAC,WAAsC,GAAG,EAAE;;AAG5F,IAAA,QAAQ,CAAC,MAAe,EAAA;AACtB,QAAA,OAAQ,MAAc,CAAC,IAAI,CAAC,KAAK,CAAC;;AAGpC,IAAA,UAAU,CAAC,QAA+C,EAAA;AACxD,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;AAC3B,YAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;gBACjB,MAAM,cAAc,GAAU,EAAE;AAChC,gBAAA,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAG;oBACpB,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;AAC1B,wBAAA,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;;AAE3B,iBAAC,CAAC;AACF,gBAAA,IAAI,CAAC,WAAW,GAAG,cAAc;AACjC,gBAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;;;aAErB;YACL,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;AAChC,gBAAA,IAAI,CAAC,WAAW,GAAG,QAAQ;AAC3B,gBAAA,IAAI,IAAI,CAAC,SAAS,EAAE;AAClB,oBAAA,IAAI,CAAC,SAAS,GAAG,EAAE;AACnB,oBAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC;;AAEnC,gBAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;;;;AAI9B,IAAA,gBAAgB,CAAC,EAAO,EAAA;AACtB,QAAA,IAAI,CAAC,SAAS,GAAG,EAAE;;AAErB,IAAA,iBAAiB,CAAC,EAAO,EAAA;AACvB,QAAA,IAAI,CAAC,SAAS,GAAG,EAAE;;AAGrB,IAAA,IACI,QAAQ,GAAA;QACV,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;;IAG5C,IAAI,QAAQ,CAAC,KAAgB,EAAA;AAC3B,QAAA,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;AACf,YAAA,KAAK,CAAC,OAAO,CAAC,IAAI,IAAG;AACnB,gBAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAE,IAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC;AACrD,aAAC,CAAC;;aACG;AACL,YAAA,IAAI,CAAC,gBAAgB,GAAI,KAAuC;AAChE,YAAA,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,KAAK,IAAG;AACpC,gBAAA,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,EAAE;AACnC,gBAAA,MAAM,aAAa,GAAI,KAAa,CAAC,GAAG,CAAc;AACrD,gBAAA,KAAa,CAAC,WAAW,CAAC,GAAG,aAAa;AAC3C,gBAAA,aAAa,CAAC,OAAO,CAAC,IAAI,IAAG;AAC3B,oBAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAE,IAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC;AACrD,iBAAC,CAAC;AACJ,aAAC,CAAC;;;AAIN,IAAA,IACI,KAAK,GAAA;QACP,OAAO,IAAI,CAAC,WAAW;;IAEzB,IAAI,KAAK,CAAC,GAA0C,EAAA;AAClD,QAAA,IAAI,CAAC,WAAW,GAAG,GAAG;AACtB,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;;AAE1B,IAAA,IAAI,gBAAgB,GAAA;QAClB,OAAO,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK;;AAGT,IAAA,mBAAmB;AAE9C,IAAA,IACI,WAAW,GAAA;QACb,OAAO,IAAI,CAAC,YAAY;;IAE1B,IAAI,WAAW,CAAC,KAAa,EAAA;AAC3B,QAAA,IAAI,CAAC,YAAY,GAAG,KAAK;AACzB,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;;AAG1B,IAAA,IACI,QAAQ,GAAA;AACV,QAAA,OAAO,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC;;IAErF,IAAI,QAAQ,CAAC,GAAY,EAAA;AACvB,QAAA,IAAI,CAAC,SAAS,GAAG,qBAAqB,CAAC,GAAG,CAAC;AAC3C,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;;;;AAIlB,IAAA,SAAS;AAEjB,IAAA,IACI,QAAQ,GAAA;QACV,OAAO,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ;;IAE5D,IAAI,QAAQ,CAAC,KAAmB,EAAA;AAC9B,QAAA,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,CAAC;QAAC;AAC9C,QAAA,IAAI,QAAQ,KAAK,IAAI,CAAC,SAAS,EAAE;AAC/B,YAAA,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;AAC/B,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;;;;AAIpB,IAAA,SAAS;AAEjB,IAAA,IAAI,KAAK,GAAA;;AAEP,QAAA,OAAO,CAAC,IAAI,CAAC,KAAK;;AAEpB,IAAA,IAAI,UAAU,GAAA;;AAEZ,QAAA,OAAO,KAAK;;AAGd,IAAA,SAAS,CAAC,KAAiB,EAAA;AACzB,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;AACjB,YAAA,IAAI,CAAC,OAAO,GAAG,IAAI;AACnB,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;;;AAI5B,IAAA,UAAU,CAAC,KAAiB,EAAA;AAC1B,QAAA,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAwB,CAAC,EAAE;AAC5E,YAAA,IAAI,CAAC,OAAO,GAAG,IAAI;AACnB,YAAA,IAAI,CAAC,OAAO,GAAG,KAAK;YACpB,IAAI,CAAC,SAAS,EAAE;AAChB,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;;;IAI5B,iBAAiB,CAAC,GAAa,EAAA;IAE/B,gBAAgB,GAAA;;;;;;;;;;;;AAahB,IAAA,gBAAgB,CAAC,UAAmB,EAAA;AAClC,QAAA,IAAI,CAAC,SAAS,GAAG,UAAU;AAC3B,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE;AAClB,YAAA,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,UAAU,CAAC;AAC3C,YAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;;;AAG5B,IAAA,cAAc,CAAC,EAAO,EAAA;;;AAGpB,QAAA,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,WAAW;;AAEvC,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAChB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;;AAG1B,IAAA,iBAAiB,CAAC,EAAmB,EAAA;;QAEnC,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE;AAC3B,YAAA,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,KAAK;YAC3B,IAAI,CAAC,SAAS,EAAE;AAChB,YAAA,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC;YACxB,MAAM,gBAAgB,GAAc,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAc;AAC3F,YAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,gBAAgB,CAAC;;aACtC;AACL,YAAA,IAAI,EAAE,CAAC,KAAK,KAAK,GAAG,EAAE;AACpB,gBAAA,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,KAAK;gBAC3B,IAAI,CAAC,SAAS,EAAE;AAChB,gBAAA,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC;AACxB,gBAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;;iBAClD;;;;AAIL,gBAAA,IAAI,IAAI,CAAC,SAAS,EAAE;oBAClB,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC;;gBAExD,EAAE,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,eAAe;AACtC,gBAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE;AACjC,gBAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;;;;AAK9B,IAAA,YAAY,CAAC,MAAc,EAAA;AACzB,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,iBAAiB,EAAE;AAC5C,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ;QAC9B,IAAI,CAAC,QAAQ,EAAE;YACb;;QAEF,IAAI,CAAC,MAAM,EAAE;YACX,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;;aACrC;AACL,YAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CACtB,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,KAAI;AACzB,gBAAA,IAAI,IAAI,CAAC,cAAc,EAAE;oBACvB,OAAO,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC;;AAE5C,gBAAA,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,iBAAiB,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;aAC1E,CAAC,CACH;;;AAIL;;;;;;;;AAQG;AACH,IAAA,mBAAmB,CAAC,MAAc,EAAA;AAChC,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,iBAAiB,EAAE;AAC5C,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB;QACpC,IAAI,CAAC,MAAM,EAAE;YACX;;QAEF,IAAI,CAAC,MAAM,EAAE;AACX,YAAA,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,EAAE;AACjC,YAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,UAAU,CAAC;;aACtC;AACL,YAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,EAAE;YAChD,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,IAAG;gBAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;gBACjC,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;AACjD,oBAAA,OAAO,EAAC,GAAG,EAAE,EAAyB;;qBACjC;oBACL,MAAM,aAAa,GAAG,EAAE,CAAC,SAAS,EAAE,MAAM,CACxC,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CACnE;AACD,oBAAA,MAAM,GAAG,GAAQ;AACf,wBAAA,GAAG;qBACJ;AACD,oBAAA,GAAG,CAAC,WAAW,CAAC,GAAG,aAAa,IAAI,EAAE;AACtC,oBAAA,OAAO,GAA2B;;AAEtC,aAAC,CAAC;;;YAGF,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAC3C,CAAC,KAAK,KACJ,KAAK,CAAC,OAAO,CAAE,KAAa,CAAC,gBAAgB,CAAC,CAAC;gBAC9C,KAAa,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,CACzC,CAAC;;;IAIN,cAAc,GAAA;QACZ,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;;;AAGvC,YAAA,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC;;AAE5D,QAAA,IAAI,QAAiB;AACrB,QAAA,IAAI,GAA0B;AAC9B,QAAA,IAAI,IAAI,CAAC,gBAAgB,EAAE;YACzB,GAAG,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC;;aACrC;AACL,YAAA,IAAI,MAAmB;AACvB,YAAA,IAAI,IAAI,CAAC,UAAU,EAAE;gBACnB,MAAM,GAAG,IAAI,UAAU,CAAC;AACtB,oBAAA,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,QAAQ;AACrC,iBAAA,CAAC;;iBACG;AACL,gBAAA,MAAM,GAAG,IAAI,UAAU,EAAE;;YAE3B,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC;AACtC,YAAA,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE;AAC7B,YAAA,IAAI,IAAI,CAAC,aAAa,EAAE,EAAE;gBACxB,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;;iBACxB;gBACL,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAM,IAAI,CAAC,GAAG,EAAE;AACjC,oBAAA,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE;oBACjC,MAAM;AACP,iBAAA,CAAC;;;QAGN,OAAO,GAAG,CAAC,IAAI,CACb,GAAG,CAAC,CAAC,QAAQ,KAAI;AACf,YAAA,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;;AAEvB,YAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,EAAE;YAChD,IAAI,gBAAgB,EAAE;AACpB,gBAAA,QAAQ,GAAI,gBAAgB,CAAC,QAAQ,CAA0B;;iBAC1D;AACL,gBAAA,IACE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;oBACxB,QAAQ,CAAC,SAAS,CAAC;oBACnB,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAClC;AACA,oBAAA,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC;;AACzB,qBAAA;gBACL,IAAI,CAAC,gBAAgB,EAAE;AACvB,oBAAA,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;oBACxB,OAAO,QAAQ,KAAK,QAAQ;AAC5B,oBAAA,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;AACjC,oBAAA,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAChD;oBACA,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;;;AAGhD,YAAA,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;AAC3B,gBAAA,IAAI,CAAC,QAAQ,GAAG,QAAQ;;;;;;;AAO1B,YAAA,IAAI,CAAC,MAAM,GAAG,IAAI;AAClB,YAAA,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;AACzB,YAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;SACzB,CAAC,CACH;;AAGH,IAAA,UAAU,CAAC,KAA2B,EAAA;AACpC,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE;AACrB,YAAA,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;;QAEjC,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC;AACpE,QAAA,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,mBAAmB,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;AAC/D,YAAA,MAAM,UAAU,GAAG,mBAAmB,CAAC,KAAK,CAAC;AAC7C,YAAA,IAAK,KAAa,CAAC,UAAU,CAAC,EAAE;AAC9B,gBAAA,OAAQ,KAAa,CAAC,UAAU,CAAC;;;QAGrC,OAAO,CAAA,MAAA,EAAS,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE;;AAGpC,IAAA,aAAa,CAAC,KAA2B,EAAA;AACvC,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,EAAE;AACnC,QAAA,OAAO,CAAC,GAAG,CAAC,CAAA,uBAAA,EAA0B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA,OAAA,EAAU,GAAG,CAAA,CAAE,CAAC;QAC3E,OAAQ,KAAa,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,IAAI,EAAE;;IAGtD,gBAAgB,GAAA;QACd,OAAO,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;eAC9B,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,GAAG,OAAO,CAAC;;IAGvE,aAAa,GAAA;AACnB,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE;QACnC,IAAI,QAAQ,EAAE;YACZ,OAAO,0BAA0B,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC;;AAEhE,QAAA,OAAO,KAAK;;IAGN,WAAW,GAAA;AACjB,QAAA,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;AAC1B,YAAA,IAAI,MAAmB;AACvB,YAAA,IAAI,IAAI,CAAC,UAAU,EAAE;gBACnB,MAAM,GAAG,IAAI,UAAU,CAAC;AACtB,oBAAA,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,QAAQ;AACrC,iBAAA,CAAC;;iBACG;AACL,gBAAA,MAAM,GAAG,IAAI,UAAU,EAAE;;;YAG3B,OAAO,CAAA,EAAG,IAAI,CAAC,GAAG,CAAA,CAAA,EAAI,MAAM,CAAC,QAAQ,EAAE,CAAA,CAAE;;QAE3C,OAAO,EAAE,CAAC;;IAEJ,YAAY,GAAA;AAClB,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE;QACnC,IAAI,QAAQ,IAAI,0BAA0B,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;YACvE,OAAO,0BAA0B,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,QAAqB;;AAEvF,QAAA,OAAO,EAAE;;AAEH,IAAA,UAAU,CAAC,QAAmB,EAAA;AACpC,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE;QACnC,IAAI,QAAQ,EAAE;YACZ,IAAI,CAAC,0BAA0B,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;AAC5D,gBAAA,0BAA0B,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAC,CAAC;;YAElF,MAAM,UAAU,GAAG,0BAA0B,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC1E,YAAA,UAAW,CAAC,QAAQ,IAAI,CAAC;;;IAGrB,eAAe,GAAA;AACrB,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE;QACnC,IAAI,QAAQ,EAAE;YACZ,MAAM,UAAU,GAAG,0BAA0B,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC1E,IAAI,UAAU,EAAE;AACd,gBAAA,UAAW,CAAC,QAAQ,IAAI,CAAC;AACzB,gBAAA,IAAI,UAAU,CAAC,QAAQ,IAAI,CAAC,EAAE;AAC5B,oBAAA,0BAA0B,CAAC,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC;;;;;IAM1D,iBAAiB,GAAA;AACvB,QAAA,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE;AACjC,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU;AAClC,QAAA,OAAO,CAAC,GAAG,CAAC,iCAAiC,EAAE;AAC7C,YAAA,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,EAAE;AACjC,YAAA,gBAAgB,EAAE,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE;YAChE,QAAQ,EAAE,IAAI,CAAC;AAChB,SAAA,CAAC;AACF,QAAA,OAAO,OAAO;;0HAhpBL,0BAA0B,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,UAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,iBAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,UAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,QAAA,EAAA,EAAA,EAAA,KAAA,EAwKf,cAAc,EAAA,QAAA,EAAA,IAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,IAAA,EAAA,IAAA,EAAA,EAAA,EAAA,KAAA,EAEd,2BAA2B,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AA1KtC,uBAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,0BAA0B,ozGAFxB,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,0BAA0B,EAAE,CAAC,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,QAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAoB7E,SAAS,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,WAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAmIT,SAAS,EAzNR,WAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDX,EAcW,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,gHAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,YAAY,oTAAE,WAAW,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,qDAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,mBAAmB,EAAE,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,eAAe,k6BAAE,wBAAwB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,wBAAA,EAAA,QAAA,EAAA,uBAAA,EAAA,MAAA,EAAA,CAAA,kBAAA,EAAA,MAAA,EAAA,WAAA,EAAA,cAAA,EAAA,qBAAA,EAAA,kBAAA,EAAA,WAAA,EAAA,qBAAA,EAAA,4BAAA,EAAA,8BAAA,EAAA,uCAAA,EAAA,WAAA,EAAA,uBAAA,EAAA,0BAAA,EAAA,gCAAA,EAAA,iCAAA,EAAA,kCAAA,EAAA,uBAAA,EAAA,mCAAA,EAAA,qBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,WAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAG1F,0BAA0B,EAAA,UAAA,EAAA,CAAA;kBAtEtC,SAAS;AACI,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,sBAAsB,EACtB,QAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDX,EAakB,eAAA,EAAA,uBAAuB,CAAC,MAAM,EACtC,OAAA,EAAA,CAAC,YAAY,EAAE,WAAW,EAAE,mBAAmB,EAAE,eAAe,EAAE,wBAAwB,CAAC,EACzF,SAAA,EAAA,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAA4B,0BAAA,EAAE,CAAC,EAAA,MAAA,EAAA,CAAA,gHAAA,CAAA,EAAA;;0BA0KrF;;0BAAY,MAAM;2BAAC,cAAc;;0BACjC;;0BAAY;;0BACZ;;0BAAY,MAAM;2BAAC,2BAA2B;yCAxJ3B,MAAM,EAAA,CAAA;sBAA3B,SAAS;uBAAC,SAAS;gBAOO,aAAa,EAAA,CAAA;sBAAvC,KAAK;uBAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;gBASG,cAAc,EAAA,CAAA;sBAAzC,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAIE,KAAK,EAAA,CAAA;sBAAhC,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAKE,GAAG,EAAA,CAAA;sBAA9B,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAKE,UAAU,EAAA,CAAA;sBAArC,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAIE,gBAAgB,EAAA,CAAA;sBAA3C,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAEE,SAAS,EAAA,CAAA;sBAApC,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAeE,UAAU,EAAA,CAAA;sBAArC,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAGE,QAAQ,EAAA,CAAA;sBAAnC,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAiBE,KAAK,EAAA,CAAA;sBAAhC,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAME,eAAe,EAAA,CAAA;sBAA1C,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAOE,YAAY,EAAA,CAAA;sBAAvC,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAUhB,eAAe,EAAA,CAAA;sBAAxB;gBACS,qBAAqB,EAAA,CAAA;sBAA9B;gBAGQ,UAAU,EAAA,CAAA;sBAAlB;gBACQ,YAAY,EAAA,CAAA;sBAApB;gBACQ,WAAW,EAAA,CAAA;sBAAnB;gBA+BqB,SAAS,EAAA,CAAA;sBAA9B,SAAS;uBAAC,SAAS;gBAUL,EAAE,EAAA,CAAA;sBAAhB;gBA0HG,QAAQ,EAAA,CAAA;sBADX;gBAwBG,KAAK,EAAA,CAAA;sBADR;gBAY0B,mBAAmB,EAAA,CAAA;sBAA7C,KAAK;uBAAC,kBAAkB;gBAGrB,WAAW,EAAA,CAAA;sBADd;gBAUG,QAAQ,EAAA,CAAA;sBADX;gBAaG,QAAQ,EAAA,CAAA;sBADX;;;AClfH;;AAEG;;;;"}
1
+ {"version":3,"file":"smallpearl-ngx-helper-mat-select-entity.mjs","sources":["../../../../projects/smallpearl/ngx-helper/mat-select-entity/src/providers.ts","../../../../projects/smallpearl/ngx-helper/mat-select-entity/src/mat-select-entity.component.ts","../../../../projects/smallpearl/ngx-helper/mat-select-entity/smallpearl-ngx-helper-mat-select-entity.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\nexport interface SPMatSelectEntityConfig {\n i18n: {\n search: string;\n notFound: string;\n // Any embedded \"{{ item }}\" in the addItem string will be replaced\n // with entityName property value. If entityName is not specified\n // \"Item\" will be used as the value for \"{{ item }}\".\n addItem: string;\n };\n}\n\nexport const SP_MAT_SELECT_ENTITY_CONFIG = new InjectionToken<SPMatSelectEntityConfig>(\n 'SPMatSelectEntityConfig'\n );\n","import { BooleanInput, coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { CommonModule, NgTemplateOutlet } from '@angular/common';\nimport { HttpClient, HttpContext, HttpContextToken, HttpParams } from '@angular/common/http';\nimport {\n AfterViewInit,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n computed,\n ElementRef,\n EventEmitter,\n HostBinding,\n inject,\n input,\n Input,\n OnDestroy,\n OnInit,\n Output,\n TemplateRef,\n ViewChild\n} from '@angular/core';\nimport { ControlValueAccessor, FormsModule, NgControl, ReactiveFormsModule, Validators } from '@angular/forms';\nimport { MAT_FORM_FIELD, MatFormFieldControl } from '@angular/material/form-field';\nimport { MatSelect, MatSelectChange, MatSelectModule } from '@angular/material/select';\nimport { getNgxHelperConfig } from '@smallpearl/ngx-helper/core';\nimport { camelCase } from 'lodash';\nimport { NgxMatSelectSearchModule } from 'ngx-mat-select-search';\nimport { plural } from 'pluralize';\nimport {\n BehaviorSubject,\n combineLatest,\n debounceTime,\n Observable,\n of,\n Subject,\n switchMap,\n takeUntil,\n tap\n} from 'rxjs';\nimport { SP_MAT_SELECT_ENTITY_CONFIG, SPMatSelectEntityConfig } from './providers';\n\nexport interface SPMatSelectEntityHttpContext {\n entityName: string;\n entityNamePlural: string;\n endpoint: string;\n}\n\nexport const SP_MAT_SELECT_ENTITY_HTTP_CONTEXT =\n new HttpContextToken<SPMatSelectEntityHttpContext>(() => ({\n entityName: '',\n entityNamePlural: '',\n endpoint: '',\n }));\n\nconst DEFAULT_SP_MAT_SELECT_ENTITY_CONFIG: SPMatSelectEntityConfig =\n {\n i18n: {\n search: 'Search',\n notFound: 'Not found',\n addItem: 'New Item',\n },\n };\n\ntype EntityGroup<T> = {\n id?: PropertyKey;\n name?: string;\n label?: string;\n description?: string;\n items?: T[];\n __items__?: T[]; // for internal use\n};\n\nexport type SPMatSelectEntityResponseParser = <\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n>(\n response: any\n) => Array<TEntity>;\n\n/**\n * This is a generic component to display a <mat-select> for a FK field\n * where the select's options are dynamically loaded from the server using\n * the given url (or URL). The objects thus retrieved should have a\n * unique 'id' field that will be used as the value of each `option` element.\n * Therefore upon selection of an `option` element, the `select` value will\n * be set to the object's `id` property. By default 'id' is used as its id,\n * but this can be customized by specifying the `idKey' property value.\n */\n@Component({\n selector: 'sp-mat-select-entity',\n template: `\n <mat-select\n [placeholder]=\"placeholder\"\n (opened)=\"onSelectOpened($event)\"\n (selectionChange)=\"onSelectionChange($event)\"\n [multiple]=\"multiple\"\n [(ngModel)]=\"selectValue\"\n >\n <mat-select-trigger>\n {{ selectTriggerValue }}\n @if (selectTriggerValueAsArray.length > 1) {\n <span class=\"addl-selection-count\">\n (+{{ selectTriggerValueAsArray.length - 1 }})\n </span>\n }\n </mat-select-trigger>\n\n <mat-option>\n <ngx-mat-select-search\n [(ngModel)]=\"filterStr\"\n (ngModelChange)=\"this.filter$.next($event)\"\n [placeholderLabel]=\"searchText\"\n [noEntriesFoundLabel]=\"notFoundText\"\n [searching]=\"searching\"\n >\n </ngx-mat-select-search>\n </mat-option>\n\n <ng-container *ngIf=\"!group; else groupedOptions\">\n <span *ngIf=\"filteredValues | async as entities\">\n <ng-template #defaultOptionLabelTemplate let-entity>\n {{ entityLabelFn(entity) }}\n </ng-template>\n @for (entity of entities; track entityId(entity)) {\n <mat-option class=\"sel-entity-option\" [value]=\"entityId(entity)\">\n <ng-container\n *ngTemplateOutlet=\"\n optionLabelTemplate() || defaultOptionLabelTemplate;\n context: { $implicit: entity }\n \"\n ></ng-container>\n </mat-option>\n }\n\n <!-- <mat-option class=\"sel-entity-option\" *ngFor=\"let entity of entities\" [value]=\"entityId(entity)\">\n {{ entityLabelFn(entity) }}\n </mat-option> -->\n </span>\n </ng-container>\n <ng-template #groupedOptions>\n <span *ngIf=\"filteredGroupedValues | async as groups\">\n @for (group of groups; track groupLabel(group)) {\n <mat-optgroup [label]=\"groupLabel(group)\">\n @for (entity of group.__items__; track entityId(entity)) {\n\n <mat-option class=\"sel-entity-option\" [value]=\"entityId(entity)\">\n {{ entityLabelFn(entity) }}\n </mat-option>\n }\n </mat-optgroup>\n }\n </span>\n </ng-template>\n\n <mat-option\n *ngIf=\"!multiple && inlineNew\"\n class=\"add-item-option\"\n value=\"0\"\n (click)=\"$event.stopPropagation()\"\n >⊕ {{ addItemText }}</mat-option\n >\n </mat-select>\n `,\n styles: [\n `\n .add-item-option {\n padding-top: 2px;\n border-top: 1px solid gray;\n }\n .addl-selection-count {\n opacity: 0.75;\n font-size: 0.8em;\n }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n CommonModule,\n NgTemplateOutlet,\n FormsModule,\n ReactiveFormsModule,\n MatSelectModule,\n NgxMatSelectSearchModule,\n ],\n providers: [\n { provide: MatFormFieldControl, useExisting: SPMatSelectEntityComponent },\n ],\n})\nexport class SPMatSelectEntityComponent<\n TEntity extends { [P in IdKey]: PropertyKey },\n IdKey extends string = 'id'\n> implements\n OnInit,\n OnDestroy,\n AfterViewInit,\n ControlValueAccessor,\n MatFormFieldControl<string | number | string[] | number[]>\n{\n // We cache the entities that we fetch from remote here. Cache is indexed\n // by the endpoint. Each endpoint also keeps a refCount, which is incremented\n // for each instance of the component using the same endpoint. When this\n // refcount reaches 0, the endpoint is removed from the cache.\n //\n // This mechanism is to suppress multiple fetches from the remote from the\n // same endpoint as that can occur if a form has multiple instances of\n // this component, with the same endpoint.\n static _entitiesCache = new Map<\n string,\n { refCount: number; entities: Array<any> }\n >();\n\n @ViewChild(MatSelect) matSel!: MatSelect;\n\n // REQUIRED PROPERTIES //\n /**\n * Entity label function. Given an entity return its natural label\n * to display to the user.\n */\n @Input({ required: true }) entityLabelFn!: (entity: TEntity) => string;\n\n // OPTIONAL PROPERTIES //\n /**\n * Entity filter function - return a boolean if the entity is to be included\n * in the filtered entities list.\n * @param entity: TEntity object to test for 'search' string.\n * @param search - search string\n */\n @Input({ required: false }) entityFilterFn!: (\n entity: TEntity,\n search: string\n ) => boolean;\n /**\n * Entity idKey, if idKey is different from the default 'id'.\n */\n @Input({ required: false }) idKey = 'id';\n /**\n * URL of the remote from where entities are to be loaded.\n * This won't be used if `loadFromRemoteFn` is specified.\n */\n @Input({ required: false }) url!: string;\n /**\n * Parameters to be added to the HTTP request to retrieve data from\n * remote. This won't be used if `loadFromRemoteFn` is specified.\n */\n @Input({ required: false }) httpParams!: HttpParams;\n /**\n * Function to load entities from remote.\n */\n @Input({ required: false }) loadFromRemoteFn!: () => Observable<TEntity[]>;\n\n @Input({ required: false }) inlineNew: boolean = false;\n /**\n * Entity name, that is used to form the \"New { item }\" menu item if\n * inlineNew=true. This is also used as the key of the object in GET response\n * if the reponse JSON is not an array and rather an object, where the values\n * are stored indexed by the server model name. For eg:-\n *\n * {\n * 'customers': [\n * {...},\n * {...},\n * {...},\n * ]\n * }\n */\n @Input({ required: false }) entityName!: string;\n // Set to true to allow multiple option selection. The returned value\n // would be an array of entity ids.\n @Input({ required: false }) multiple = false;\n /*\n Whether to group options using <mat-optgroup></mat-optgroup>.\n If set to true, the response from the server should be an array of\n groups of TEntity objects, where each object is of the form:\n [\n {\n id: <id>,\n name|label: <>,\n items|<plural_entityName>|<custom_key>: [\n TEntity,\n ...\n ]\n },\n ...\n ]\n */\n @Input({ required: false }) group = false;\n /**\n * The group object key name under which options are stored. Defaults to\n * 'items' or pluralized 'entityName'. Ideally the client class should\n * explicitly set this property value.\n */\n @Input({ required: false }) groupOptionsKey!: string;\n /**\n * If groupOptions = true, specify this to provide accurate label for each\n * group. If not specified, group label will be determined by looking up one\n * of the standard fields - name, label or description - whichever comes\n * first.\n */\n @Input({ required: false }) groupLabelFn!: (group: any) => string;\n /**\n * Sideload data key name.\n */\n sideloadDataKey = input<string>();\n /**\n * Parser function to return the list of entities from the GET response.\n */\n responseParserFn = input<SPMatSelectEntityResponseParser>();\n\n @Output() selectionChange = new EventEmitter<TEntity | TEntity[]>();\n @Output() createNewItemSelected = new EventEmitter<void>();\n\n // allow per component customization\n @Input() searchText!: string;\n @Input() notFoundText!: string;\n @Input() addItemText!: string;\n\n /**\n * Template for the option label. If not provided, the default label\n * function will be used. Option label is what is placed inside the\n * <mat-option> tag. The template gets an implicit 'entity' variable\n * in the context, value for which is the entity object.\n *\n * For example:\n * ```\n * <sp-mat-select-entity\n * [url]=\"'/api/v1/customers/'\"\n * [entityLabelFn]=\"entity => entity.name\"\n * [optionLabelTemplate]=\"optionLabelTemplate\"\n * ></sp-mat-select-entity>\n * <ng-template #optionLabelTemplate let-entity>\n * {{ entity.name }} - {{ entity.description }}\n * </ng-template>\n * ```\n */\n optionLabelTemplate = input<TemplateRef<any>>();\n\n _sideloadDataKey = computed<string>(() => {\n if (this.sideloadDataKey()) {\n return this.sideloadDataKey() as string;\n }\n return this.entityName ? plural(camelCase(this.entityName)) : 'results';\n });\n\n private _entities = new Map<PropertyKey, TEntity>();\n private _groupedEntities = new Array<EntityGroup<TEntity>>();\n\n stateChanges = new Subject<void>();\n focused = false;\n touched = false;\n\n selectValue!: string | number | string[] | number[];\n // For storing last select value, which we use to restore the select's value\n // to when New Item is selected. This ensures that when New Item is selected,\n // the select's value remains the same. If the newly created item is to be\n // set as the select's value, the corresponding TEntity has to be added\n // to _entities (via addEntity()) and then selected by setting the\n // corresponding formControl's value to the entity's id.\n lastSelectValue!: string | number | string[] | number[];\n searching = false;\n filterStr: string = '';\n\n filter$ = new BehaviorSubject<string>('');\n // ControlValueAccessor callback\n onChanged = (_: any) => {};\n onTouched = () => {};\n @ViewChild(MatSelect) matSelect!: MatSelect;\n\n filteredValues = new Subject<TEntity[]>();\n filteredGroupedValues = new Subject<EntityGroup<TEntity>[]>();\n\n destroy = new Subject<void>();\n private loaded = false;\n private load$ = new BehaviorSubject<boolean>(false);\n\n static nextId = 0;\n @HostBinding() id = `sp-select-entity-${SPMatSelectEntityComponent.nextId++}`;\n private _placeholder!: string;\n ngxHelperConfig = getNgxHelperConfig();\n protected http = inject(HttpClient);\n protected cdr = inject(ChangeDetectorRef);\n protected _elementRef = inject(ElementRef<HTMLElement>);\n protected _formField = inject(MAT_FORM_FIELD, {optional: true});\n protected config = inject(SP_MAT_SELECT_ENTITY_CONFIG, {optional: true});\n public ngControl = inject(NgControl, {optional: true});\n\n constructor(\n // protected http: HttpClient,\n // protected cdr: ChangeDetectorRef,\n // protected _elementRef: ElementRef<HTMLElement>,\n // protected injector: Injector,\n // @Optional() @Inject(MAT_FORM_FIELD) public _formField: MatFormField,\n // @Optional() @Self() public ngControl: NgControl,\n // @Optional()\n // @Inject(SP_MAT_SELECT_ENTITY_CONFIG)\n // private config: SPMatSelectEntityConfig\n ) {\n if (this.ngControl != null) {\n this.ngControl.valueAccessor = this;\n }\n }\n\n ngOnInit() {\n this._initStrings();\n combineLatest([this.filter$.pipe(debounceTime(400)), this.load$])\n .pipe(\n takeUntil(this.destroy),\n switchMap(([str, load]) => {\n if (load && !this.loaded) {\n this.searching = true;\n this.cdr.detectChanges();\n return this.loadFromRemote();\n } else {\n return of(this.entities ?? []);\n }\n }),\n tap(() => {\n if (this.group) {\n this.filterGroupedValues(this.filterStr);\n } else {\n this.filterValues(this.filterStr);\n }\n this.cdr.detectChanges();\n })\n )\n .subscribe();\n }\n ngOnDestroy(): void {\n this.destroy.next();\n this.removeFromCache();\n this.stateChanges.complete();\n }\n\n ngAfterViewInit(): void {\n // I'm not sure this is how this logic is right, but this seems to work.\n // if (this.ngControl && this.ngControl.control?.validator) {\n // const validator = this.ngControl.control.validator;\n // const res = validator(this.ngControl.control);\n // if (res && res['required']) {\n // this.required = true;\n // }\n // }\n }\n\n private _initStrings() {\n const config: SPMatSelectEntityConfig =\n this.config ?? DEFAULT_SP_MAT_SELECT_ENTITY_CONFIG;\n if (!this.searchText) {\n this.searchText = config.i18n.search;\n }\n if (!this.notFoundText) {\n this.notFoundText = config.i18n.notFound;\n }\n if (!this.addItemText) {\n this.addItemText = config.i18n.addItem.replace(\n /\\{\\{\\s*item\\s*}}/,\n this.entityName ?? '**Item'\n );\n }\n }\n\n addEntity(entity: TEntity) {\n this._entities.set((entity as any)[this.idKey], entity);\n // So that the newly added entity will be added to the <mat-option> list.\n this.filterValues(this.filterStr);\n this.cdr.detectChanges();\n }\n\n get selectTriggerValue() {\n if (this.selectValue) {\n const firstSelected = Array.isArray(this.selectValue)\n ? this.selectValue[0]\n : this.selectValue;\n const selectedEntity = this._entities.get(firstSelected);\n return selectedEntity ? this.entityLabelFn(selectedEntity) : '';\n }\n return '';\n }\n\n get selectTriggerValueAsArray() {\n return Array.isArray(this.selectValue)\n ? (this.selectValue as Array<string | number>)\n : [];\n }\n\n entityId(entity: TEntity) {\n return (entity as any)[this.idKey];\n }\n\n writeValue(entityId: string | number | string[] | number[]): void {\n if (Array.isArray(entityId)) {\n if (this.multiple) {\n const selectedValues: any[] = [];\n entityId.forEach((id) => {\n if (this._entities.has(id)) {\n selectedValues.push(id);\n }\n });\n this.selectValue = selectedValues;\n this.cdr.detectChanges();\n }\n } else {\n if (this._entities.has(entityId)) {\n this.selectValue = entityId;\n if (this.filterStr) {\n this.filterStr = '';\n this.filterValues(this.filterStr);\n }\n this.cdr.detectChanges();\n }\n }\n }\n registerOnChange(fn: any): void {\n this.onChanged = fn;\n }\n registerOnTouched(fn: any): void {\n this.onTouched = fn;\n }\n\n @Input()\n get entities(): TEntity[] {\n return Array.from(this._entities.values());\n }\n\n set entities(items: TEntity[]) {\n if (!this.group) {\n items.forEach((item) => {\n this._entities.set((item as any)[this.idKey], item);\n });\n } else {\n this._groupedEntities = items as any as EntityGroup<TEntity>[];\n this._groupedEntities.forEach((group) => {\n const key = this.groupEntitiesKey();\n const groupEntities = (group as any)[key] as TEntity[];\n (group as any)['__items__'] = groupEntities;\n groupEntities.forEach((item) => {\n this._entities.set((item as any)[this.idKey], item);\n });\n });\n }\n }\n\n @Input()\n get value(): string | number | string[] | number[] {\n return this.selectValue;\n }\n set value(val: string | number | string[] | number[]) {\n this.selectValue = val;\n this.stateChanges.next();\n }\n get shouldLabelFloat() {\n return this.focused || !this.empty;\n }\n\n @Input('aria-describedby') userAriaDescribedBy!: string;\n\n @Input()\n get placeholder(): string {\n return this._placeholder;\n }\n set placeholder(value: string) {\n this._placeholder = value;\n this.stateChanges.next();\n }\n\n @Input()\n get required() {\n return (\n this._required ??\n this.ngControl?.control?.hasValidator(Validators.required)\n );\n }\n set required(req: boolean) {\n this._required = coerceBooleanProperty(req);\n this.stateChanges.next();\n }\n // Deliberately 'undefined' so that `get required()` will return the state\n // from ngControl's validators.\n private _required!: boolean;\n\n @Input()\n get disabled(): boolean {\n return this._disabled ?? this.ngControl?.control?.disabled;\n }\n set disabled(value: BooleanInput) {\n const disabled = coerceBooleanProperty(value);\n if (disabled !== this._disabled) {\n this.setDisabledState(disabled);\n this.stateChanges.next();\n }\n }\n // Same as `_required`, deliberately `undefined` by default.\n private _disabled!: boolean;\n\n get empty() {\n // TODO\n return !this.value;\n }\n get errorState(): boolean {\n // TODO\n return false;\n }\n\n onFocusIn(event: FocusEvent) {\n if (!this.focused) {\n this.focused = true;\n this.stateChanges.next();\n }\n }\n\n onFocusOut(event: FocusEvent) {\n if (\n !this._elementRef.nativeElement.contains(event.relatedTarget as Element)\n ) {\n this.touched = true;\n this.focused = false;\n this.onTouched();\n this.stateChanges.next();\n }\n }\n\n setDescribedByIds(ids: string[]) {}\n\n onContainerClick() {\n // this._focusMonitor.focusVia(this.countrySelect, 'program');\n // if (this.parts.controls.national.valid) {\n // this._focusMonitor.focusVia(this.nationalInput, 'program');\n // } else if (this.parts.controls.country.valid) {\n // this._focusMonitor.focusVia(this.nationalInput, 'program');\n // // } else if (this.parts.controls.national.valid) {\n // // this._focusMonitor.focusVia(this.nationalInput, 'program');\n // } else {\n // this._focusMonitor.focusVia(this.countrySelect, 'program');\n // }\n }\n\n setDisabledState(isDisabled: boolean): void {\n this._disabled = isDisabled;\n if (this.matSelect) {\n this.matSelect.setDisabledState(isDisabled);\n this.cdr.detectChanges();\n }\n }\n onSelectOpened(ev: any) {\n // Store the current select value so that we can restore it if user\n // eventually selects 'New Item' option.\n this.lastSelectValue = this.selectValue;\n // If values have not been loaded from remote, trigger a load.\n if (!this.loaded) {\n this.load$.next(true); // this will trigger the loadFromRemote() call.\n }\n }\n onSelectionChange(ev: MatSelectChange) {\n // console.log('SelectionChange - sel:', ev);\n if (Array.isArray(ev.value)) {\n this.selectValue = ev.value;\n this.onTouched();\n this.onChanged(ev.value);\n const selectedEntities: TEntity[] = ev.value.map((id) =>\n this._entities.get(id)\n ) as TEntity[];\n this.selectionChange.emit(selectedEntities);\n } else {\n if (ev.value !== '0') {\n this.selectValue = ev.value;\n this.onTouched();\n this.onChanged(ev.value);\n this.selectionChange.emit(this._entities.get(ev.value));\n } else {\n // New Item activated, return value to previous value. We track\n // previous value via 'lastSelectValue' member which is updated\n // whenever the select is opened.\n if (this.ngControl) {\n this.ngControl.control?.setValue(this.lastSelectValue);\n }\n ev.source.value = this.lastSelectValue;\n this.createNewItemSelected.emit();\n this.cdr.detectChanges();\n }\n }\n }\n\n filterValues(search: string) {\n const searchLwr = search.toLocaleLowerCase();\n const entities = this.entities;\n if (!entities) {\n return;\n }\n if (!search) {\n this.filteredValues.next(entities.slice());\n } else {\n this.filteredValues.next(\n entities.filter((member) => {\n if (this.entityFilterFn) {\n return this.entityFilterFn(member, search);\n }\n return this.entityLabelFn(member)\n .toLocaleLowerCase()\n .includes(searchLwr);\n })\n );\n }\n }\n\n /**\n * Filtering grouped entities logic works like this. If the search string\n * matches a group label, the entire group is to be included in the results.\n * However, if the search string only matches certain entities, only those\n * groups are to be included and within those groups, only entities whose\n * label matches the search string are to be included in the result set.\n * @param search\n * @returns\n */\n filterGroupedValues(search: string) {\n const searchLwr = search.toLocaleLowerCase();\n const groups = this._groupedEntities;\n if (!groups) {\n return;\n }\n if (!search) {\n const groupsCopy = groups.slice();\n this.filteredGroupedValues.next(groupsCopy);\n } else {\n const groupEntitiesKey = this.groupEntitiesKey();\n const groups = this._groupedEntities.map((ge) => {\n const label = this.groupLabel(ge);\n if (label.toLocaleLowerCase().includes(searchLwr)) {\n return { ...ge } as EntityGroup<TEntity>;\n } else {\n const groupEntities = ge.__items__?.filter((e) =>\n this.entityLabelFn(e).toLocaleLowerCase().includes(searchLwr)\n );\n const ret: any = {\n ...ge,\n };\n ret['__items__'] = groupEntities ?? [];\n return ret as EntityGroup<TEntity>;\n }\n });\n // filter out groups with no entities\n // console.log(`Groups: ${JSON.stringify(groups)}`);\n this.filteredGroupedValues.next(\n groups.filter(\n (group) =>\n Array.isArray((group as any)[groupEntitiesKey]) &&\n (group as any)['__items__'].length > 0\n )\n );\n }\n }\n\n loadFromRemote() {\n if (!this.url && !this.loadFromRemoteFn) {\n // If user had initialized entities, they will be dispalyed\n // in the options list. If not, options would be empty.\n return of(this.group ? this.groupEntities : this.entities);\n }\n let cacheKey!: string;\n let obs: Observable<TEntity[]>;\n if (this.loadFromRemoteFn) {\n obs = this.loadFromRemoteFn();\n } else {\n let params!: HttpParams;\n if (this.httpParams) {\n params = new HttpParams({\n fromString: this.httpParams.toString(),\n });\n } else {\n params = new HttpParams();\n }\n params = params.set('paginate', false);\n cacheKey = this.getCacheKey();\n if (this.existsInCache()) {\n obs = of(this.getFromCache());\n } else {\n obs = this.http.get<any>(this.url, {\n context: this.getHttpReqContext(),\n params,\n });\n }\n }\n return obs.pipe(\n tap((entities) => {\n this.searching = false; // remote loading done, will hide the loading wheel\n // Handle DRF paginated response\n const responseParserFn = this.responseParserFn();\n if (responseParserFn) {\n entities = responseParserFn(entities) as unknown as TEntity[];\n } else {\n if (\n !Array.isArray(entities) &&\n entities['results'] &&\n Array.isArray(entities['results'])\n ) {\n entities = entities['results'];\n } else if (\n // sideloaded response, where entities are usually provided in 'entityName'\n this._sideloadDataKey() &&\n !Array.isArray(entities) &&\n typeof entities === 'object' &&\n entities[this._sideloadDataKey()] &&\n Array.isArray(entities[this._sideloadDataKey()])\n ) {\n entities = entities[this._sideloadDataKey()];\n }\n }\n if (Array.isArray(entities)) {\n this.entities = entities;\n // if (this.group) {\n // this._groupedEntities = entities as EntityGroup<TEntity>[];\n // } else {\n // this.entities = entities;\n // }\n }\n this.loaded = true;\n this.addToCache(entities);\n this.cdr.detectChanges();\n })\n );\n }\n\n groupLabel(group: EntityGroup<TEntity>): string {\n if (this.groupLabelFn) {\n return this.groupLabelFn(group);\n }\n const standardLabelFields = ['name', 'label', 'desc', 'description'];\n for (let index = 0; index < standardLabelFields.length; index++) {\n const labelField = standardLabelFields[index];\n if ((group as any)[labelField]) {\n return (group as any)[labelField];\n }\n }\n return `Group ${String(group.id)}`;\n }\n\n groupEntities(group: EntityGroup<TEntity>): TEntity[] {\n const key = this.groupEntitiesKey();\n console.log(`groupEntities - group: ${JSON.stringify(group)}, key: ${key}`);\n return (group as any)[this.groupEntitiesKey()] ?? [];\n }\n\n groupEntitiesKey() {\n return this.groupOptionsKey\n ? this.groupOptionsKey\n : this.entityName\n ? plural(this.entityName.toLocaleLowerCase())\n : 'items';\n }\n\n private existsInCache() {\n const cacheKey = this.getCacheKey();\n if (cacheKey) {\n return SPMatSelectEntityComponent._entitiesCache.has(cacheKey);\n }\n return false;\n }\n\n private getCacheKey() {\n if (!this.loadFromRemoteFn) {\n let params!: HttpParams;\n if (this.httpParams) {\n params = new HttpParams({\n fromString: this.httpParams.toString(),\n });\n } else {\n params = new HttpParams();\n }\n // params = params.set('paginate', false)\n return `${this.url}?${params.toString()}`;\n }\n return ''; // empty string evalutes to boolean(false)\n }\n private getFromCache() {\n const cacheKey = this.getCacheKey();\n if (cacheKey && SPMatSelectEntityComponent._entitiesCache.has(cacheKey)) {\n return SPMatSelectEntityComponent._entitiesCache.get(cacheKey)\n ?.entities as TEntity[];\n }\n return [];\n }\n private addToCache(entities: TEntity[]) {\n const cacheKey = this.getCacheKey();\n if (cacheKey) {\n if (!SPMatSelectEntityComponent._entitiesCache.has(cacheKey)) {\n SPMatSelectEntityComponent._entitiesCache.set(cacheKey, {\n refCount: 0,\n entities,\n });\n }\n const cacheEntry =\n SPMatSelectEntityComponent._entitiesCache.get(cacheKey);\n cacheEntry!.refCount += 1;\n }\n }\n private removeFromCache() {\n const cacheKey = this.getCacheKey();\n if (cacheKey) {\n const cacheEntry =\n SPMatSelectEntityComponent._entitiesCache.get(cacheKey);\n if (cacheEntry) {\n cacheEntry!.refCount -= 1;\n if (cacheEntry.refCount <= 0) {\n SPMatSelectEntityComponent._entitiesCache.delete(cacheKey);\n }\n }\n }\n }\n\n private getHttpReqContext() {\n const context = new HttpContext();\n const entityName = this.entityName;\n context.set(SP_MAT_SELECT_ENTITY_HTTP_CONTEXT, {\n entityName: this.entityName ?? '',\n entityNamePlural: this.entityName ? plural(this.entityName) : '',\n endpoint: this.url,\n });\n return context;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;MAaa,2BAA2B,GAAG,IAAI,cAAc,CACzD,yBAAyB;;ACiChB,MAAA,iCAAiC,GAC5C,IAAI,gBAAgB,CAA+B,OAAO;AACxD,IAAA,UAAU,EAAE,EAAE;AACd,IAAA,gBAAgB,EAAE,EAAE;AACpB,IAAA,QAAQ,EAAE,EAAE;AACb,CAAA,CAAC;AAEJ,MAAM,mCAAmC,GACvC;AACE,IAAA,IAAI,EAAE;AACJ,QAAA,MAAM,EAAE,QAAQ;AAChB,QAAA,QAAQ,EAAE,WAAW;AACrB,QAAA,OAAO,EAAE,UAAU;AACpB,KAAA;CACF;AAkBH;;;;;;;;AAQG;MAqGU,0BAA0B,CAAA;;;;;;;;;AAkBrC,IAAA,OAAO,cAAc,GAAG,IAAI,GAAG,EAG5B;AAEmB,IAAA,MAAM;;AAG5B;;;AAGG;AACwB,IAAA,aAAa;;AAGxC;;;;;AAKG;AACyB,IAAA,cAAc;AAI1C;;AAEG;IACyB,KAAK,GAAG,IAAI;AACxC;;;AAGG;AACyB,IAAA,GAAG;AAC/B;;;AAGG;AACyB,IAAA,UAAU;AACtC;;AAEG;AACyB,IAAA,gBAAgB;IAEhB,SAAS,GAAY,KAAK;AACtD;;;;;;;;;;;;;AAaG;AACyB,IAAA,UAAU;;;IAGV,QAAQ,GAAG,KAAK;AAC5C;;;;;;;;;;;;;;;AAeE;IAC0B,KAAK,GAAG,KAAK;AACzC;;;;AAIG;AACyB,IAAA,eAAe;AAC3C;;;;;AAKG;AACyB,IAAA,YAAY;AACxC;;AAEG;IACH,eAAe,GAAG,KAAK,EAAU;AACjC;;AAEG;IACH,gBAAgB,GAAG,KAAK,EAAmC;AAEjD,IAAA,eAAe,GAAG,IAAI,YAAY,EAAuB;AACzD,IAAA,qBAAqB,GAAG,IAAI,YAAY,EAAQ;;AAGjD,IAAA,UAAU;AACV,IAAA,YAAY;AACZ,IAAA,WAAW;AAEpB;;;;;;;;;;;;;;;;;AAiBG;IACH,mBAAmB,GAAG,KAAK,EAAoB;AAE/C,IAAA,gBAAgB,GAAG,QAAQ,CAAS,MAAK;AACvC,QAAA,IAAI,IAAI,CAAC,eAAe,EAAE,EAAE;AAC1B,YAAA,OAAO,IAAI,CAAC,eAAe,EAAY;;AAEzC,QAAA,OAAO,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,GAAG,SAAS;AACzE,KAAC,CAAC;AAEM,IAAA,SAAS,GAAG,IAAI,GAAG,EAAwB;AAC3C,IAAA,gBAAgB,GAAG,IAAI,KAAK,EAAwB;AAE5D,IAAA,YAAY,GAAG,IAAI,OAAO,EAAQ;IAClC,OAAO,GAAG,KAAK;IACf,OAAO,GAAG,KAAK;AAEf,IAAA,WAAW;;;;;;;AAOX,IAAA,eAAe;IACf,SAAS,GAAG,KAAK;IACjB,SAAS,GAAW,EAAE;AAEtB,IAAA,OAAO,GAAG,IAAI,eAAe,CAAS,EAAE,CAAC;;AAEzC,IAAA,SAAS,GAAG,CAAC,CAAM,KAAI,GAAG;AAC1B,IAAA,SAAS,GAAG,MAAK,GAAG;AACE,IAAA,SAAS;AAE/B,IAAA,cAAc,GAAG,IAAI,OAAO,EAAa;AACzC,IAAA,qBAAqB,GAAG,IAAI,OAAO,EAA0B;AAE7D,IAAA,OAAO,GAAG,IAAI,OAAO,EAAQ;IACrB,MAAM,GAAG,KAAK;AACd,IAAA,KAAK,GAAG,IAAI,eAAe,CAAU,KAAK,CAAC;AAEnD,IAAA,OAAO,MAAM,GAAG,CAAC;AACF,IAAA,EAAE,GAAG,CAAoB,iBAAA,EAAA,0BAA0B,CAAC,MAAM,EAAE,EAAE;AACrE,IAAA,YAAY;IACpB,eAAe,GAAG,kBAAkB,EAAE;AAC5B,IAAA,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC;AACzB,IAAA,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC;AAC/B,IAAA,WAAW,GAAG,MAAM,EAAC,UAAuB,EAAC;IAC7C,UAAU,GAAG,MAAM,CAAC,cAAc,EAAE,EAAC,QAAQ,EAAE,IAAI,EAAC,CAAC;IACrD,MAAM,GAAG,MAAM,CAAC,2BAA2B,EAAE,EAAC,QAAQ,EAAE,IAAI,EAAC,CAAC;IACjE,SAAS,GAAG,MAAM,CAAC,SAAS,EAAE,EAAC,QAAQ,EAAE,IAAI,EAAC,CAAC;AAEtD,IAAA,WAAA,GAAA;AAWE,QAAA,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,EAAE;AAC1B,YAAA,IAAI,CAAC,SAAS,CAAC,aAAa,GAAG,IAAI;;;IAIvC,QAAQ,GAAA;QACN,IAAI,CAAC,YAAY,EAAE;AACnB,QAAA,aAAa,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC;AAC7D,aAAA,IAAI,CACH,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,EACvB,SAAS,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,KAAI;AACxB,YAAA,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;AACxB,gBAAA,IAAI,CAAC,SAAS,GAAG,IAAI;AACrB,gBAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;AACxB,gBAAA,OAAO,IAAI,CAAC,cAAc,EAAE;;iBACvB;gBACL,OAAO,EAAE,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;;AAElC,SAAC,CAAC,EACF,GAAG,CAAC,MAAK;AACP,YAAA,IAAI,IAAI,CAAC,KAAK,EAAE;AACd,gBAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC;;iBACnC;AACL,gBAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC;;AAEnC,YAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;AAC1B,SAAC,CAAC;AAEH,aAAA,SAAS,EAAE;;IAEhB,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;QACnB,IAAI,CAAC,eAAe,EAAE;AACtB,QAAA,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE;;IAG9B,eAAe,GAAA;;;;;;;;;;IAWP,YAAY,GAAA;AAClB,QAAA,MAAM,MAAM,GACV,IAAI,CAAC,MAAM,IAAI,mCAAmC;AACpD,QAAA,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;YACpB,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM;;AAEtC,QAAA,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;YACtB,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ;;AAE1C,QAAA,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;AACrB,YAAA,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAC5C,kBAAkB,EAClB,IAAI,CAAC,UAAU,IAAI,QAAQ,CAC5B;;;AAIL,IAAA,SAAS,CAAC,MAAe,EAAA;AACvB,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAE,MAAc,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;;AAEvD,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC;AACjC,QAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;;AAG1B,IAAA,IAAI,kBAAkB,GAAA;AACpB,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE;YACpB,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW;AAClD,kBAAE,IAAI,CAAC,WAAW,CAAC,CAAC;AACpB,kBAAE,IAAI,CAAC,WAAW;YACpB,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC;AACxD,YAAA,OAAO,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,GAAG,EAAE;;AAEjE,QAAA,OAAO,EAAE;;AAGX,IAAA,IAAI,yBAAyB,GAAA;AAC3B,QAAA,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW;cAChC,IAAI,CAAC;cACN,EAAE;;AAGR,IAAA,QAAQ,CAAC,MAAe,EAAA;AACtB,QAAA,OAAQ,MAAc,CAAC,IAAI,CAAC,KAAK,CAAC;;AAGpC,IAAA,UAAU,CAAC,QAA+C,EAAA;AACxD,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;AAC3B,YAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;gBACjB,MAAM,cAAc,GAAU,EAAE;AAChC,gBAAA,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,KAAI;oBACtB,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;AAC1B,wBAAA,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;;AAE3B,iBAAC,CAAC;AACF,gBAAA,IAAI,CAAC,WAAW,GAAG,cAAc;AACjC,gBAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;;;aAErB;YACL,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;AAChC,gBAAA,IAAI,CAAC,WAAW,GAAG,QAAQ;AAC3B,gBAAA,IAAI,IAAI,CAAC,SAAS,EAAE;AAClB,oBAAA,IAAI,CAAC,SAAS,GAAG,EAAE;AACnB,oBAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC;;AAEnC,gBAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;;;;AAI9B,IAAA,gBAAgB,CAAC,EAAO,EAAA;AACtB,QAAA,IAAI,CAAC,SAAS,GAAG,EAAE;;AAErB,IAAA,iBAAiB,CAAC,EAAO,EAAA;AACvB,QAAA,IAAI,CAAC,SAAS,GAAG,EAAE;;AAGrB,IAAA,IACI,QAAQ,GAAA;QACV,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;;IAG5C,IAAI,QAAQ,CAAC,KAAgB,EAAA;AAC3B,QAAA,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;AACf,YAAA,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,KAAI;AACrB,gBAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAE,IAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC;AACrD,aAAC,CAAC;;aACG;AACL,YAAA,IAAI,CAAC,gBAAgB,GAAG,KAAsC;YAC9D,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,KAAK,KAAI;AACtC,gBAAA,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,EAAE;AACnC,gBAAA,MAAM,aAAa,GAAI,KAAa,CAAC,GAAG,CAAc;AACrD,gBAAA,KAAa,CAAC,WAAW,CAAC,GAAG,aAAa;AAC3C,gBAAA,aAAa,CAAC,OAAO,CAAC,CAAC,IAAI,KAAI;AAC7B,oBAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAE,IAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC;AACrD,iBAAC,CAAC;AACJ,aAAC,CAAC;;;AAIN,IAAA,IACI,KAAK,GAAA;QACP,OAAO,IAAI,CAAC,WAAW;;IAEzB,IAAI,KAAK,CAAC,GAA0C,EAAA;AAClD,QAAA,IAAI,CAAC,WAAW,GAAG,GAAG;AACtB,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;;AAE1B,IAAA,IAAI,gBAAgB,GAAA;QAClB,OAAO,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK;;AAGT,IAAA,mBAAmB;AAE9C,IAAA,IACI,WAAW,GAAA;QACb,OAAO,IAAI,CAAC,YAAY;;IAE1B,IAAI,WAAW,CAAC,KAAa,EAAA;AAC3B,QAAA,IAAI,CAAC,YAAY,GAAG,KAAK;AACzB,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;;AAG1B,IAAA,IACI,QAAQ,GAAA;QACV,QACE,IAAI,CAAC,SAAS;AACd,YAAA,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC;;IAG9D,IAAI,QAAQ,CAAC,GAAY,EAAA;AACvB,QAAA,IAAI,CAAC,SAAS,GAAG,qBAAqB,CAAC,GAAG,CAAC;AAC3C,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;;;;AAIlB,IAAA,SAAS;AAEjB,IAAA,IACI,QAAQ,GAAA;QACV,OAAO,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ;;IAE5D,IAAI,QAAQ,CAAC,KAAmB,EAAA;AAC9B,QAAA,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,CAAC;AAC7C,QAAA,IAAI,QAAQ,KAAK,IAAI,CAAC,SAAS,EAAE;AAC/B,YAAA,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC;AAC/B,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;;;;AAIpB,IAAA,SAAS;AAEjB,IAAA,IAAI,KAAK,GAAA;;AAEP,QAAA,OAAO,CAAC,IAAI,CAAC,KAAK;;AAEpB,IAAA,IAAI,UAAU,GAAA;;AAEZ,QAAA,OAAO,KAAK;;AAGd,IAAA,SAAS,CAAC,KAAiB,EAAA;AACzB,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;AACjB,YAAA,IAAI,CAAC,OAAO,GAAG,IAAI;AACnB,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;;;AAI5B,IAAA,UAAU,CAAC,KAAiB,EAAA;AAC1B,QAAA,IACE,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAwB,CAAC,EACxE;AACA,YAAA,IAAI,CAAC,OAAO,GAAG,IAAI;AACnB,YAAA,IAAI,CAAC,OAAO,GAAG,KAAK;YACpB,IAAI,CAAC,SAAS,EAAE;AAChB,YAAA,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE;;;IAI5B,iBAAiB,CAAC,GAAa,EAAA;IAE/B,gBAAgB,GAAA;;;;;;;;;;;;AAahB,IAAA,gBAAgB,CAAC,UAAmB,EAAA;AAClC,QAAA,IAAI,CAAC,SAAS,GAAG,UAAU;AAC3B,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE;AAClB,YAAA,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,UAAU,CAAC;AAC3C,YAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;;;AAG5B,IAAA,cAAc,CAAC,EAAO,EAAA;;;AAGpB,QAAA,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,WAAW;;AAEvC,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAChB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;;;AAG1B,IAAA,iBAAiB,CAAC,EAAmB,EAAA;;QAEnC,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE;AAC3B,YAAA,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,KAAK;YAC3B,IAAI,CAAC,SAAS,EAAE;AAChB,YAAA,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC;YACxB,MAAM,gBAAgB,GAAc,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,KAClD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CACV;AACd,YAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,gBAAgB,CAAC;;aACtC;AACL,YAAA,IAAI,EAAE,CAAC,KAAK,KAAK,GAAG,EAAE;AACpB,gBAAA,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,KAAK;gBAC3B,IAAI,CAAC,SAAS,EAAE;AAChB,gBAAA,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC;AACxB,gBAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;;iBAClD;;;;AAIL,gBAAA,IAAI,IAAI,CAAC,SAAS,EAAE;oBAClB,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC;;gBAExD,EAAE,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,eAAe;AACtC,gBAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE;AACjC,gBAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;;;;AAK9B,IAAA,YAAY,CAAC,MAAc,EAAA;AACzB,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,iBAAiB,EAAE;AAC5C,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ;QAC9B,IAAI,CAAC,QAAQ,EAAE;YACb;;QAEF,IAAI,CAAC,MAAM,EAAE;YACX,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;;aACrC;AACL,YAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CACtB,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,KAAI;AACzB,gBAAA,IAAI,IAAI,CAAC,cAAc,EAAE;oBACvB,OAAO,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC;;AAE5C,gBAAA,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM;AAC7B,qBAAA,iBAAiB;qBACjB,QAAQ,CAAC,SAAS,CAAC;aACvB,CAAC,CACH;;;AAIL;;;;;;;;AAQG;AACH,IAAA,mBAAmB,CAAC,MAAc,EAAA;AAChC,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,iBAAiB,EAAE;AAC5C,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB;QACpC,IAAI,CAAC,MAAM,EAAE;YACX;;QAEF,IAAI,CAAC,MAAM,EAAE;AACX,YAAA,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,EAAE;AACjC,YAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,UAAU,CAAC;;aACtC;AACL,YAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,EAAE;YAChD,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,EAAE,KAAI;gBAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;gBACjC,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;AACjD,oBAAA,OAAO,EAAE,GAAG,EAAE,EAA0B;;qBACnC;AACL,oBAAA,MAAM,aAAa,GAAG,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,KAC3C,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAC9D;AACD,oBAAA,MAAM,GAAG,GAAQ;AACf,wBAAA,GAAG,EAAE;qBACN;AACD,oBAAA,GAAG,CAAC,WAAW,CAAC,GAAG,aAAa,IAAI,EAAE;AACtC,oBAAA,OAAO,GAA2B;;AAEtC,aAAC,CAAC;;;YAGF,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAC7B,MAAM,CAAC,MAAM,CACX,CAAC,KAAK,KACJ,KAAK,CAAC,OAAO,CAAE,KAAa,CAAC,gBAAgB,CAAC,CAAC;gBAC9C,KAAa,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,CACzC,CACF;;;IAIL,cAAc,GAAA;QACZ,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;;;AAGvC,YAAA,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC;;AAE5D,QAAA,IAAI,QAAiB;AACrB,QAAA,IAAI,GAA0B;AAC9B,QAAA,IAAI,IAAI,CAAC,gBAAgB,EAAE;AACzB,YAAA,GAAG,GAAG,IAAI,CAAC,gBAAgB,EAAE;;aACxB;AACL,YAAA,IAAI,MAAmB;AACvB,YAAA,IAAI,IAAI,CAAC,UAAU,EAAE;gBACnB,MAAM,GAAG,IAAI,UAAU,CAAC;AACtB,oBAAA,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE;AACvC,iBAAA,CAAC;;iBACG;AACL,gBAAA,MAAM,GAAG,IAAI,UAAU,EAAE;;YAE3B,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC;AACtC,YAAA,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE;AAC7B,YAAA,IAAI,IAAI,CAAC,aAAa,EAAE,EAAE;gBACxB,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;;iBACxB;gBACL,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAM,IAAI,CAAC,GAAG,EAAE;AACjC,oBAAA,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE;oBACjC,MAAM;AACP,iBAAA,CAAC;;;QAGN,OAAO,GAAG,CAAC,IAAI,CACb,GAAG,CAAC,CAAC,QAAQ,KAAI;AACf,YAAA,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;;AAEvB,YAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,EAAE;YAChD,IAAI,gBAAgB,EAAE;AACpB,gBAAA,QAAQ,GAAG,gBAAgB,CAAC,QAAQ,CAAyB;;iBACxD;AACL,gBAAA,IACE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;oBACxB,QAAQ,CAAC,SAAS,CAAC;oBACnB,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAClC;AACA,oBAAA,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC;;AACzB,qBAAA;;gBAEL,IAAI,CAAC,gBAAgB,EAAE;AACvB,oBAAA,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;oBACxB,OAAO,QAAQ,KAAK,QAAQ;AAC5B,oBAAA,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;AACjC,oBAAA,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAChD;oBACA,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;;;AAGhD,YAAA,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;AAC3B,gBAAA,IAAI,CAAC,QAAQ,GAAG,QAAQ;;;;;;;AAO1B,YAAA,IAAI,CAAC,MAAM,GAAG,IAAI;AAClB,YAAA,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;AACzB,YAAA,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE;SACzB,CAAC,CACH;;AAGH,IAAA,UAAU,CAAC,KAA2B,EAAA;AACpC,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE;AACrB,YAAA,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;;QAEjC,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC;AACpE,QAAA,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,mBAAmB,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;AAC/D,YAAA,MAAM,UAAU,GAAG,mBAAmB,CAAC,KAAK,CAAC;AAC7C,YAAA,IAAK,KAAa,CAAC,UAAU,CAAC,EAAE;AAC9B,gBAAA,OAAQ,KAAa,CAAC,UAAU,CAAC;;;QAGrC,OAAO,CAAA,MAAA,EAAS,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE;;AAGpC,IAAA,aAAa,CAAC,KAA2B,EAAA;AACvC,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,EAAE;AACnC,QAAA,OAAO,CAAC,GAAG,CAAC,CAAA,uBAAA,EAA0B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA,OAAA,EAAU,GAAG,CAAA,CAAE,CAAC;QAC3E,OAAQ,KAAa,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,IAAI,EAAE;;IAGtD,gBAAgB,GAAA;QACd,OAAO,IAAI,CAAC;cACR,IAAI,CAAC;cACL,IAAI,CAAC;kBACL,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,iBAAiB,EAAE;kBAC1C,OAAO;;IAGL,aAAa,GAAA;AACnB,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE;QACnC,IAAI,QAAQ,EAAE;YACZ,OAAO,0BAA0B,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC;;AAEhE,QAAA,OAAO,KAAK;;IAGN,WAAW,GAAA;AACjB,QAAA,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;AAC1B,YAAA,IAAI,MAAmB;AACvB,YAAA,IAAI,IAAI,CAAC,UAAU,EAAE;gBACnB,MAAM,GAAG,IAAI,UAAU,CAAC;AACtB,oBAAA,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE;AACvC,iBAAA,CAAC;;iBACG;AACL,gBAAA,MAAM,GAAG,IAAI,UAAU,EAAE;;;YAG3B,OAAO,CAAA,EAAG,IAAI,CAAC,GAAG,CAAA,CAAA,EAAI,MAAM,CAAC,QAAQ,EAAE,CAAA,CAAE;;QAE3C,OAAO,EAAE,CAAC;;IAEJ,YAAY,GAAA;AAClB,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE;QACnC,IAAI,QAAQ,IAAI,0BAA0B,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;AACvE,YAAA,OAAO,0BAA0B,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ;AAC3D,kBAAE,QAAqB;;AAE3B,QAAA,OAAO,EAAE;;AAEH,IAAA,UAAU,CAAC,QAAmB,EAAA;AACpC,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE;QACnC,IAAI,QAAQ,EAAE;YACZ,IAAI,CAAC,0BAA0B,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;AAC5D,gBAAA,0BAA0B,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,EAAE;AACtD,oBAAA,QAAQ,EAAE,CAAC;oBACX,QAAQ;AACT,iBAAA,CAAC;;YAEJ,MAAM,UAAU,GACd,0BAA0B,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC;AACzD,YAAA,UAAW,CAAC,QAAQ,IAAI,CAAC;;;IAGrB,eAAe,GAAA;AACrB,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE;QACnC,IAAI,QAAQ,EAAE;YACZ,MAAM,UAAU,GACd,0BAA0B,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC;YACzD,IAAI,UAAU,EAAE;AACd,gBAAA,UAAW,CAAC,QAAQ,IAAI,CAAC;AACzB,gBAAA,IAAI,UAAU,CAAC,QAAQ,IAAI,CAAC,EAAE;AAC5B,oBAAA,0BAA0B,CAAC,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC;;;;;IAM1D,iBAAiB,GAAA;AACvB,QAAA,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE;AACjC,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU;AAClC,QAAA,OAAO,CAAC,GAAG,CAAC,iCAAiC,EAAE;AAC7C,YAAA,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,EAAE;AACjC,YAAA,gBAAgB,EAAE,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE;YAChE,QAAQ,EAAE,IAAI,CAAC,GAAG;AACnB,SAAA,CAAC;AACF,QAAA,OAAO,OAAO;;0HAvtBL,0BAA0B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAA1B,uBAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,0BAA0B,EAJ1B,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,sBAAA,EAAA,MAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,gBAAA,EAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,UAAA,EAAA,kBAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,eAAA,EAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,eAAA,EAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,gBAAA,EAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,UAAA,EAAA,kBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,mBAAA,EAAA,EAAA,iBAAA,EAAA,qBAAA,EAAA,UAAA,EAAA,qBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,mBAAA,EAAA,EAAA,iBAAA,EAAA,qBAAA,EAAA,UAAA,EAAA,kBAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,qBAAA,EAAA,uBAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,IAAA,EAAA,SAAA,EAAA,EAAA,EAAA,SAAA,EAAA;AACT,YAAA,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,0BAA0B,EAAE;SAC1E,EAyBU,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,QAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,SAAS,EA0JT,WAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,WAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,SAAS,EAnRV,WAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwET,EAeC,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,gHAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,YAAY,8VAEZ,WAAW,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,qDAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACX,mBAAmB,EACnB,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,eAAe,k6BACf,wBAAwB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,wBAAA,EAAA,QAAA,EAAA,uBAAA,EAAA,MAAA,EAAA,CAAA,kBAAA,EAAA,MAAA,EAAA,WAAA,EAAA,cAAA,EAAA,qBAAA,EAAA,kBAAA,EAAA,WAAA,EAAA,qBAAA,EAAA,4BAAA,EAAA,8BAAA,EAAA,uCAAA,EAAA,WAAA,EAAA,uBAAA,EAAA,0BAAA,EAAA,gCAAA,EAAA,iCAAA,EAAA,kCAAA,EAAA,uBAAA,EAAA,mCAAA,EAAA,qBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,WAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAMf,0BAA0B,EAAA,UAAA,EAAA,CAAA;kBApGtC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,sBAAsB,EACtB,QAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwET,EAagB,eAAA,EAAA,uBAAuB,CAAC,MAAM,EACtC,OAAA,EAAA;wBACP,YAAY;wBACZ,gBAAgB;wBAChB,WAAW;wBACX,mBAAmB;wBACnB,eAAe;wBACf,wBAAwB;qBACzB,EACU,SAAA,EAAA;AACT,wBAAA,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,4BAA4B,EAAE;AAC1E,qBAAA,EAAA,MAAA,EAAA,CAAA,gHAAA,CAAA,EAAA;wDAyBqB,MAAM,EAAA,CAAA;sBAA3B,SAAS;uBAAC,SAAS;gBAOO,aAAa,EAAA,CAAA;sBAAvC,KAAK;uBAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;gBASG,cAAc,EAAA,CAAA;sBAAzC,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAOE,KAAK,EAAA,CAAA;sBAAhC,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAKE,GAAG,EAAA,CAAA;sBAA9B,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAKE,UAAU,EAAA,CAAA;sBAArC,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAIE,gBAAgB,EAAA,CAAA;sBAA3C,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAEE,SAAS,EAAA,CAAA;sBAApC,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAeE,UAAU,EAAA,CAAA;sBAArC,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAGE,QAAQ,EAAA,CAAA;sBAAnC,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAiBE,KAAK,EAAA,CAAA;sBAAhC,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAME,eAAe,EAAA,CAAA;sBAA1C,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAOE,YAAY,EAAA,CAAA;sBAAvC,KAAK;uBAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAUhB,eAAe,EAAA,CAAA;sBAAxB;gBACS,qBAAqB,EAAA,CAAA;sBAA9B;gBAGQ,UAAU,EAAA,CAAA;sBAAlB;gBACQ,YAAY,EAAA,CAAA;sBAApB;gBACQ,WAAW,EAAA,CAAA;sBAAnB;gBAmDqB,SAAS,EAAA,CAAA;sBAA9B,SAAS;uBAAC,SAAS;gBAUL,EAAE,EAAA,CAAA;sBAAhB;gBAgJG,QAAQ,EAAA,CAAA;sBADX;gBAwBG,KAAK,EAAA,CAAA;sBADR;gBAY0B,mBAAmB,EAAA,CAAA;sBAA7C,KAAK;uBAAC,kBAAkB;gBAGrB,WAAW,EAAA,CAAA;sBADd;gBAUG,QAAQ,EAAA,CAAA;sBADX;gBAgBG,QAAQ,EAAA,CAAA;sBADX;;;ACnkBH;;AAEG;;;;"}
@@ -1,8 +1,8 @@
1
1
  import { BooleanInput } from '@angular/cdk/coercion';
2
2
  import { HttpClient, HttpContextToken, HttpParams } from '@angular/common/http';
3
- import { AfterViewInit, ChangeDetectorRef, ElementRef, EventEmitter, Injector, OnDestroy, OnInit } from '@angular/core';
3
+ import { AfterViewInit, ChangeDetectorRef, ElementRef, EventEmitter, OnDestroy, OnInit, TemplateRef } from '@angular/core';
4
4
  import { ControlValueAccessor, NgControl } from '@angular/forms';
5
- import { MatFormField, MatFormFieldControl } from '@angular/material/form-field';
5
+ import { MatFormFieldControl } from '@angular/material/form-field';
6
6
  import { MatSelect, MatSelectChange } from '@angular/material/select';
7
7
  import { BehaviorSubject, Observable, Subject } from 'rxjs';
8
8
  import { SPMatSelectEntityConfig } from './providers';
@@ -36,13 +36,6 @@ export type SPMatSelectEntityResponseParser = <TEntity extends {
36
36
  export declare class SPMatSelectEntityComponent<TEntity extends {
37
37
  [P in IdKey]: PropertyKey;
38
38
  }, IdKey extends string = 'id'> implements OnInit, OnDestroy, AfterViewInit, ControlValueAccessor, MatFormFieldControl<string | number | string[] | number[]> {
39
- protected http: HttpClient;
40
- protected cdr: ChangeDetectorRef;
41
- protected _elementRef: ElementRef<HTMLElement>;
42
- protected injector: Injector;
43
- _formField: MatFormField;
44
- ngControl: NgControl;
45
- private config;
46
39
  static _entitiesCache: Map<string, {
47
40
  refCount: number;
48
41
  entities: Array<any>;
@@ -77,7 +70,7 @@ export declare class SPMatSelectEntityComponent<TEntity extends {
77
70
  /**
78
71
  * Function to load entities from remote.
79
72
  */
80
- loadFromRemoteFn: (injector: Injector) => Observable<TEntity[]>;
73
+ loadFromRemoteFn: () => Observable<TEntity[]>;
81
74
  inlineNew: boolean;
82
75
  /**
83
76
  * Entity name, that is used to form the "New { item }" menu item if
@@ -122,6 +115,25 @@ export declare class SPMatSelectEntityComponent<TEntity extends {
122
115
  searchText: string;
123
116
  notFoundText: string;
124
117
  addItemText: string;
118
+ /**
119
+ * Template for the option label. If not provided, the default label
120
+ * function will be used. Option label is what is placed inside the
121
+ * <mat-option> tag. The template gets an implicit 'entity' variable
122
+ * in the context, value for which is the entity object.
123
+ *
124
+ * For example:
125
+ * ```
126
+ * <sp-mat-select-entity
127
+ * [url]="'/api/v1/customers/'"
128
+ * [entityLabelFn]="entity => entity.name"
129
+ * [optionLabelTemplate]="optionLabelTemplate"
130
+ * ></sp-mat-select-entity>
131
+ * <ng-template #optionLabelTemplate let-entity>
132
+ * {{ entity.name }} - {{ entity.description }}
133
+ * </ng-template>
134
+ * ```
135
+ */
136
+ optionLabelTemplate: import("@angular/core").InputSignal<TemplateRef<any> | undefined>;
125
137
  _sideloadDataKey: import("@angular/core").Signal<string>;
126
138
  private _entities;
127
139
  private _groupedEntities;
@@ -145,7 +157,13 @@ export declare class SPMatSelectEntityComponent<TEntity extends {
145
157
  id: string;
146
158
  private _placeholder;
147
159
  ngxHelperConfig: import("@smallpearl/ngx-helper/core").SPNgxHelperConfig;
148
- constructor(http: HttpClient, cdr: ChangeDetectorRef, _elementRef: ElementRef<HTMLElement>, injector: Injector, _formField: MatFormField, ngControl: NgControl, config: SPMatSelectEntityConfig);
160
+ protected http: HttpClient;
161
+ protected cdr: ChangeDetectorRef;
162
+ protected _elementRef: ElementRef<any>;
163
+ protected _formField: import("@angular/material/form-field").MatFormField | null;
164
+ protected config: SPMatSelectEntityConfig | null;
165
+ ngControl: NgControl | null;
166
+ constructor();
149
167
  ngOnInit(): void;
150
168
  ngOnDestroy(): void;
151
169
  ngAfterViewInit(): void;
@@ -201,7 +219,7 @@ export declare class SPMatSelectEntityComponent<TEntity extends {
201
219
  private addToCache;
202
220
  private removeFromCache;
203
221
  private getHttpReqContext;
204
- static ɵfac: i0.ɵɵFactoryDeclaration<SPMatSelectEntityComponent<any, any>, [null, null, null, null, { optional: true; }, { optional: true; self: true; }, { optional: true; }]>;
205
- static ɵcmp: i0.ɵɵComponentDeclaration<SPMatSelectEntityComponent<any, any>, "sp-mat-select-entity", never, { "entityLabelFn": { "alias": "entityLabelFn"; "required": true; }; "entityFilterFn": { "alias": "entityFilterFn"; "required": false; }; "idKey": { "alias": "idKey"; "required": false; }; "url": { "alias": "url"; "required": false; }; "httpParams": { "alias": "httpParams"; "required": false; }; "loadFromRemoteFn": { "alias": "loadFromRemoteFn"; "required": false; }; "inlineNew": { "alias": "inlineNew"; "required": false; }; "entityName": { "alias": "entityName"; "required": false; }; "multiple": { "alias": "multiple"; "required": false; }; "group": { "alias": "group"; "required": false; }; "groupOptionsKey": { "alias": "groupOptionsKey"; "required": false; }; "groupLabelFn": { "alias": "groupLabelFn"; "required": false; }; "sideloadDataKey": { "alias": "sideloadDataKey"; "required": false; "isSignal": true; }; "responseParserFn": { "alias": "responseParserFn"; "required": false; "isSignal": true; }; "searchText": { "alias": "searchText"; "required": false; }; "notFoundText": { "alias": "notFoundText"; "required": false; }; "addItemText": { "alias": "addItemText"; "required": false; }; "entities": { "alias": "entities"; "required": false; }; "value": { "alias": "value"; "required": false; }; "userAriaDescribedBy": { "alias": "aria-describedby"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "required": { "alias": "required"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; }, { "selectionChange": "selectionChange"; "createNewItemSelected": "createNewItemSelected"; }, never, never, true, never>;
222
+ static ɵfac: i0.ɵɵFactoryDeclaration<SPMatSelectEntityComponent<any, any>, never>;
223
+ static ɵcmp: i0.ɵɵComponentDeclaration<SPMatSelectEntityComponent<any, any>, "sp-mat-select-entity", never, { "entityLabelFn": { "alias": "entityLabelFn"; "required": true; }; "entityFilterFn": { "alias": "entityFilterFn"; "required": false; }; "idKey": { "alias": "idKey"; "required": false; }; "url": { "alias": "url"; "required": false; }; "httpParams": { "alias": "httpParams"; "required": false; }; "loadFromRemoteFn": { "alias": "loadFromRemoteFn"; "required": false; }; "inlineNew": { "alias": "inlineNew"; "required": false; }; "entityName": { "alias": "entityName"; "required": false; }; "multiple": { "alias": "multiple"; "required": false; }; "group": { "alias": "group"; "required": false; }; "groupOptionsKey": { "alias": "groupOptionsKey"; "required": false; }; "groupLabelFn": { "alias": "groupLabelFn"; "required": false; }; "sideloadDataKey": { "alias": "sideloadDataKey"; "required": false; "isSignal": true; }; "responseParserFn": { "alias": "responseParserFn"; "required": false; "isSignal": true; }; "searchText": { "alias": "searchText"; "required": false; }; "notFoundText": { "alias": "notFoundText"; "required": false; }; "addItemText": { "alias": "addItemText"; "required": false; }; "optionLabelTemplate": { "alias": "optionLabelTemplate"; "required": false; "isSignal": true; }; "entities": { "alias": "entities"; "required": false; }; "value": { "alias": "value"; "required": false; }; "userAriaDescribedBy": { "alias": "aria-describedby"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "required": { "alias": "required"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; }, { "selectionChange": "selectionChange"; "createNewItemSelected": "createNewItemSelected"; }, never, never, true, never>;
206
224
  }
207
225
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smallpearl/ngx-helper",
3
- "version": "0.29.26",
3
+ "version": "0.29.30",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^19.1.0",
6
6
  "@angular/core": "^19.1.0",
@@ -98,14 +98,14 @@
98
98
  "types": "./mat-side-menu-layout/index.d.ts",
99
99
  "default": "./fesm2022/smallpearl-ngx-helper-mat-side-menu-layout.mjs"
100
100
  },
101
- "./sideload": {
102
- "types": "./sideload/index.d.ts",
103
- "default": "./fesm2022/smallpearl-ngx-helper-sideload.mjs"
104
- },
105
101
  "./mat-tel-input": {
106
102
  "types": "./mat-tel-input/index.d.ts",
107
103
  "default": "./fesm2022/smallpearl-ngx-helper-mat-tel-input.mjs"
108
104
  },
105
+ "./sideload": {
106
+ "types": "./sideload/index.d.ts",
107
+ "default": "./fesm2022/smallpearl-ngx-helper-sideload.mjs"
108
+ },
109
109
  "./stationary-with-line-items": {
110
110
  "types": "./stationary-with-line-items/index.d.ts",
111
111
  "default": "./fesm2022/smallpearl-ngx-helper-stationary-with-line-items.mjs"