ng-fusion-ui 0.0.1 → 0.1.2

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.
Files changed (40) hide show
  1. package/README.md +29 -22
  2. package/esm2022/lib/data-grid/components/body-row-cell/body-row-cell.component.mjs +64 -0
  3. package/esm2022/lib/data-grid/components/head-row-cell/head-row-cell.component.mjs +37 -0
  4. package/esm2022/lib/data-grid/components/row-actions/row-actions.component.mjs +67 -0
  5. package/esm2022/lib/data-grid/data-grid/data-grid.component.mjs +215 -0
  6. package/esm2022/lib/data-grid/data-grid.module.mjs +62 -0
  7. package/esm2022/lib/data-grid/directives/grid-body-template.directive.mjs +22 -0
  8. package/esm2022/lib/data-grid/directives/grid-columns.directive.mjs +43 -0
  9. package/esm2022/lib/data-grid/directives/grid-expand-template.directive.mjs +19 -0
  10. package/esm2022/lib/data-grid/directives/grid-header-template.directive.mjs +19 -0
  11. package/esm2022/lib/data-grid/directives/sort-column.directive.mjs +25 -0
  12. package/esm2022/lib/data-grid/index.mjs +10 -0
  13. package/esm2022/lib/data-grid/services/data-grid-paginator.mjs +3 -0
  14. package/esm2022/lib/data-grid/services/data-sorting.service.mjs +30 -0
  15. package/esm2022/lib/data-grid/services/edit-row.service.mjs +33 -0
  16. package/esm2022/lib/data-grid/services/paginator.service.mjs +28 -0
  17. package/esm2022/public-api.mjs +2 -3
  18. package/fesm2022/ng-fusion-ui.mjs +604 -22
  19. package/fesm2022/ng-fusion-ui.mjs.map +1 -1
  20. package/lib/data-grid/components/body-row-cell/body-row-cell.component.d.ts +24 -0
  21. package/lib/data-grid/components/head-row-cell/head-row-cell.component.d.ts +17 -0
  22. package/lib/data-grid/components/row-actions/row-actions.component.d.ts +25 -0
  23. package/lib/data-grid/data-grid/data-grid.component.d.ts +61 -0
  24. package/lib/data-grid/data-grid.module.d.ts +17 -0
  25. package/lib/data-grid/directives/grid-body-template.directive.d.ts +12 -0
  26. package/lib/data-grid/directives/grid-columns.directive.d.ts +16 -0
  27. package/lib/data-grid/directives/grid-expand-template.directive.d.ts +12 -0
  28. package/lib/data-grid/directives/grid-header-template.directive.d.ts +11 -0
  29. package/lib/data-grid/directives/sort-column.directive.d.ts +11 -0
  30. package/lib/data-grid/index.d.ts +9 -0
  31. package/lib/data-grid/services/data-grid-paginator.d.ts +5 -0
  32. package/lib/data-grid/services/data-sorting.service.d.ts +16 -0
  33. package/lib/data-grid/services/edit-row.service.d.ts +16 -0
  34. package/lib/data-grid/services/paginator.service.d.ts +15 -0
  35. package/package.json +5 -3
  36. package/public-api.d.ts +1 -2
  37. package/esm2022/lib/ng-fusion-ui.component.mjs +0 -19
  38. package/esm2022/lib/ng-fusion-ui.service.mjs +0 -14
  39. package/lib/ng-fusion-ui.component.d.ts +0 -5
  40. package/lib/ng-fusion-ui.service.d.ts +0 -6
package/README.md CHANGED
@@ -1,24 +1,31 @@
1
1
  # NgFusionUi
2
2
 
3
- This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 18.0.0.
4
-
5
- ## Code scaffolding
6
-
7
- Run `ng generate component component-name --project ng-fusion-ui` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project ng-fusion-ui`.
8
- > Note: Don't forget to add `--project ng-fusion-ui` or else it will be added to the default project in your `angular.json` file.
9
-
10
- ## Build
11
-
12
- Run `ng build ng-fusion-ui` to build the project. The build artifacts will be stored in the `dist/` directory.
13
-
14
- ## Publishing
15
-
16
- After building your library with `ng build ng-fusion-ui`, go to the dist folder `cd dist/ng-fusion-ui` and run `npm publish`.
17
-
18
- ## Running unit tests
19
-
20
- Run `ng test ng-fusion-ui` to execute the unit tests via [Karma](https://karma-runner.github.io).
21
-
22
- ## Further help
23
-
24
- To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
3
+ Angular - mobile firednly and type safe data-grid system!
4
+
5
+ ## Basic Usage/Examples
6
+
7
+ ```javascript
8
+ <fu-data-grid
9
+ [dataSource]="data"
10
+ [expandable]="true"
11
+ [paginator]="true"
12
+ >
13
+ <ng-container *fuHeaderTemplate>
14
+ <fu-head-row-cell cellDef="Code" />
15
+ <fu-head-row-cell cellDef="Name" />
16
+ <fu-head-row-cell cellDef="Category" />
17
+ <fu-head-row-cell cellDef="Quantity" />
18
+ </ng-container>
19
+
20
+ <ng-container *fuBodyTemplate="data; let row">
21
+ <fu-body-row-cell [cellValue]="row.id" />
22
+ <fu-body-row-cell [cellValue]="row.name" />
23
+ <fu-body-row-cell [cellValue]="row.email" />
24
+ <fu-body-row-cell [cellValue]="row.phone" />
25
+ </ng-container>
26
+
27
+ <ng-container *fuExpandTemplate="data; let row">
28
+ expand content goes here...
29
+ </ng-container>
30
+ </fu-data-grid>
31
+ ```
@@ -0,0 +1,64 @@
1
+ import { ChangeDetectionStrategy, Component, Input, ViewEncapsulation, model, signal, } from '@angular/core';
2
+ import { filter } from 'rxjs';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "../../services/data-sorting.service";
5
+ import * as i2 from "../../services/edit-row.service";
6
+ import * as i3 from "@angular/forms";
7
+ export class BodyRowCellComponent {
8
+ constructor(sortService, editRowService, elementRef) {
9
+ this.sortService = sortService;
10
+ this.editRowService = editRowService;
11
+ this.elementRef = elementRef;
12
+ this.editCellValue = model();
13
+ this.isEditing = signal(false);
14
+ }
15
+ ngOnInit() {
16
+ const index = this.getCellIndex();
17
+ this.cellDef = this.sortService.getCellDef(index) || '';
18
+ }
19
+ ngOnChanges(changes) {
20
+ const index = this.getRowIndex();
21
+ if (changes['editKey']) {
22
+ this.subscription = this.editRowService.editState$
23
+ .pipe(filter(() => !!this.editKey))
24
+ .subscribe((state) => {
25
+ this.editCellValue.set(this.cellValue);
26
+ this.isEditing.set(state === index);
27
+ });
28
+ }
29
+ }
30
+ onInputChange(value) {
31
+ this.editCellValue.set(value);
32
+ if (this.isEditing()) {
33
+ this.editRowService.updateEditValues(this.editKey, value);
34
+ }
35
+ }
36
+ getCellIndex() {
37
+ const parent = this.elementRef.nativeElement.parentElement;
38
+ return Array.from(parent.children).indexOf(this.elementRef.nativeElement);
39
+ }
40
+ getRowIndex() {
41
+ const element = this.elementRef.nativeElement.parentElement;
42
+ const parent = element.parentElement;
43
+ if (!parent)
44
+ return -1;
45
+ const children = Array.from(parent.children);
46
+ return children.indexOf(element);
47
+ }
48
+ ngOnDestroy() {
49
+ if (this.subscription) {
50
+ this.subscription.unsubscribe();
51
+ }
52
+ }
53
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: BodyRowCellComponent, deps: [{ token: i1.DataSortingService }, { token: i2.EditRowService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
54
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.6", type: BodyRowCellComponent, selector: "fu-body-row-cell", inputs: { cellValue: { classPropertyName: "cellValue", publicName: "cellValue", isSignal: false, isRequired: false, transformFunction: null }, editKey: { classPropertyName: "editKey", publicName: "editKey", isSignal: false, isRequired: false, transformFunction: null }, editCellValue: { classPropertyName: "editCellValue", publicName: "editCellValue", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { editCellValue: "editCellValueChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"fu-body-row-cell\" [attr.data-edit]=\"isEditing()\">\r\n <span>{{ cellDef }}</span>\r\n\r\n @if (cellValue) { @if(isEditing()){\r\n <input\r\n class=\"fu-edit-input\"\r\n [(ngModel)]=\"editCellValue\"\r\n (ngModelChange)=\"onInputChange($event)\"\r\n (click)=\"$event.stopPropagation()\"\r\n />\r\n }@else {\r\n <span>{{ cellValue }}</span>\r\n } } @else {\r\n <ng-content />\r\n }\r\n</div>\r\n", styles: [".fu-body-row-cell{padding:12px 16px}.fu-body-row-cell[data-edit=true]{padding:8px 16px}.fu-body-row-cell>span:nth-child(1){display:none}@media (max-width: 900px){.fu-body-row-cell>span:nth-child(1){display:inline;font-weight:700}}.fu-body-row-cell>span:nth-child(2){color:var(--fu-grid-cell-color);word-break:break-all}@media (max-width: 900px){.fu-body-row-cell{display:grid;grid-template-columns:repeat(2,1fr)}}@media (max-width: 600px){.fu-body-row-cell{grid-template-columns:35% 1fr;padding:8px 16px}}.fu-edit-input{background-color:transparent;color:#fff;width:100%;padding:4px;border:none;outline:1px solid gray;border-radius:4px}\n"], dependencies: [{ kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
55
+ }
56
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: BodyRowCellComponent, decorators: [{
57
+ type: Component,
58
+ args: [{ selector: 'fu-body-row-cell', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"fu-body-row-cell\" [attr.data-edit]=\"isEditing()\">\r\n <span>{{ cellDef }}</span>\r\n\r\n @if (cellValue) { @if(isEditing()){\r\n <input\r\n class=\"fu-edit-input\"\r\n [(ngModel)]=\"editCellValue\"\r\n (ngModelChange)=\"onInputChange($event)\"\r\n (click)=\"$event.stopPropagation()\"\r\n />\r\n }@else {\r\n <span>{{ cellValue }}</span>\r\n } } @else {\r\n <ng-content />\r\n }\r\n</div>\r\n", styles: [".fu-body-row-cell{padding:12px 16px}.fu-body-row-cell[data-edit=true]{padding:8px 16px}.fu-body-row-cell>span:nth-child(1){display:none}@media (max-width: 900px){.fu-body-row-cell>span:nth-child(1){display:inline;font-weight:700}}.fu-body-row-cell>span:nth-child(2){color:var(--fu-grid-cell-color);word-break:break-all}@media (max-width: 900px){.fu-body-row-cell{display:grid;grid-template-columns:repeat(2,1fr)}}@media (max-width: 600px){.fu-body-row-cell{grid-template-columns:35% 1fr;padding:8px 16px}}.fu-edit-input{background-color:transparent;color:#fff;width:100%;padding:4px;border:none;outline:1px solid gray;border-radius:4px}\n"] }]
59
+ }], ctorParameters: () => [{ type: i1.DataSortingService }, { type: i2.EditRowService }, { type: i0.ElementRef }], propDecorators: { cellValue: [{
60
+ type: Input
61
+ }], editKey: [{
62
+ type: Input
63
+ }] } });
64
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9keS1yb3ctY2VsbC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1mdXNpb24tdWkvc3JjL2xpYi9kYXRhLWdyaWQvY29tcG9uZW50cy9ib2R5LXJvdy1jZWxsL2JvZHktcm93LWNlbGwuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctZnVzaW9uLXVpL3NyYy9saWIvZGF0YS1ncmlkL2NvbXBvbmVudHMvYm9keS1yb3ctY2VsbC9ib2R5LXJvdy1jZWxsLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUVULEtBQUssRUFLTCxpQkFBaUIsRUFDakIsS0FBSyxFQUNMLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUd2QixPQUFPLEVBQWdCLE1BQU0sRUFBRSxNQUFNLE1BQU0sQ0FBQzs7Ozs7QUFTNUMsTUFBTSxPQUFPLG9CQUFvQjtJQVUvQixZQUNVLFdBQStCLEVBQy9CLGNBQThCLEVBQzlCLFVBQXNCO1FBRnRCLGdCQUFXLEdBQVgsV0FBVyxDQUFvQjtRQUMvQixtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFDOUIsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQVJ6QixrQkFBYSxHQUFHLEtBQUssRUFBbUIsQ0FBQztRQUN6QyxjQUFTLEdBQUcsTUFBTSxDQUFVLEtBQUssQ0FBQyxDQUFDO0lBUXZDLENBQUM7SUFFRyxRQUFRO1FBQ2IsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzFELENBQUM7SUFFTSxXQUFXLENBQUMsT0FBc0I7UUFDdkMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBRWpDLElBQUksT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVU7aUJBQy9DLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztpQkFDbEMsU0FBUyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7Z0JBQ25CLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDdkMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsS0FBSyxLQUFLLEtBQUssQ0FBQyxDQUFDO1lBQ3RDLENBQUMsQ0FBQyxDQUFDO1FBQ1AsQ0FBQztJQUNILENBQUM7SUFFTSxhQUFhLENBQUMsS0FBVTtRQUM3QixJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5QixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxjQUFjLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUM1RCxDQUFDO0lBQ0gsQ0FBQztJQUVPLFlBQVk7UUFDbEIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsYUFBNEIsQ0FBQztRQUMxRSxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQzVFLENBQUM7SUFFTyxXQUFXO1FBQ2pCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLGFBQTRCLENBQUM7UUFDM0UsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQztRQUNyQyxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFFdkIsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDN0MsT0FBTyxRQUFRLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFTSxXQUFXO1FBQ2hCLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3RCLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbEMsQ0FBQztJQUNILENBQUM7OEdBM0RVLG9CQUFvQjtrR0FBcEIsb0JBQW9CLGdpQkN4QmpDLCthQWdCQTs7MkZEUWEsb0JBQW9CO2tCQVBoQyxTQUFTOytCQUNFLGtCQUFrQixtQkFHWCx1QkFBdUIsQ0FBQyxNQUFNLGlCQUNoQyxpQkFBaUIsQ0FBQyxJQUFJOzZJQUdyQixTQUFTO3NCQUF4QixLQUFLO2dCQUNVLE9BQU87c0JBQXRCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxyXG4gIENvbXBvbmVudCxcclxuICBFbGVtZW50UmVmLFxyXG4gIElucHV0LFxyXG4gIE9uQ2hhbmdlcyxcclxuICBPbkRlc3Ryb3ksXHJcbiAgT25Jbml0LFxyXG4gIFNpbXBsZUNoYW5nZXMsXHJcbiAgVmlld0VuY2Fwc3VsYXRpb24sXHJcbiAgbW9kZWwsXHJcbiAgc2lnbmFsLFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBEYXRhU29ydGluZ1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9kYXRhLXNvcnRpbmcuc2VydmljZSc7XHJcbmltcG9ydCB7IEVkaXRSb3dTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZWRpdC1yb3cuc2VydmljZSc7XHJcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiwgZmlsdGVyIH0gZnJvbSAncnhqcyc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2Z1LWJvZHktcm93LWNlbGwnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9ib2R5LXJvdy1jZWxsLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybDogJy4vYm9keS1yb3ctY2VsbC5jb21wb25lbnQuc2NzcycsXHJcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXHJcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcclxufSlcclxuZXhwb3J0IGNsYXNzIEJvZHlSb3dDZWxsQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XHJcbiAgQElucHV0KCkgcHVibGljIGNlbGxWYWx1ZTogc3RyaW5nIHwgbnVtYmVyO1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBlZGl0S2V5OiBzdHJpbmc7XHJcblxyXG4gIHB1YmxpYyBjZWxsRGVmOiBzdHJpbmc7XHJcbiAgcHVibGljIGVkaXRDZWxsVmFsdWUgPSBtb2RlbDxzdHJpbmcgfCBudW1iZXI+KCk7XHJcbiAgcHVibGljIGlzRWRpdGluZyA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XHJcblxyXG4gIHByaXZhdGUgc3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBzb3J0U2VydmljZTogRGF0YVNvcnRpbmdTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBlZGl0Um93U2VydmljZTogRWRpdFJvd1NlcnZpY2UsXHJcbiAgICBwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWZcclxuICApIHt9XHJcblxyXG4gIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5nZXRDZWxsSW5kZXgoKTtcclxuICAgIHRoaXMuY2VsbERlZiA9IHRoaXMuc29ydFNlcnZpY2UuZ2V0Q2VsbERlZihpbmRleCkgfHwgJyc7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xyXG4gICAgY29uc3QgaW5kZXggPSB0aGlzLmdldFJvd0luZGV4KCk7XHJcblxyXG4gICAgaWYgKGNoYW5nZXNbJ2VkaXRLZXknXSkge1xyXG4gICAgICB0aGlzLnN1YnNjcmlwdGlvbiA9IHRoaXMuZWRpdFJvd1NlcnZpY2UuZWRpdFN0YXRlJFxyXG4gICAgICAgIC5waXBlKGZpbHRlcigoKSA9PiAhIXRoaXMuZWRpdEtleSkpXHJcbiAgICAgICAgLnN1YnNjcmliZSgoc3RhdGUpID0+IHtcclxuICAgICAgICAgIHRoaXMuZWRpdENlbGxWYWx1ZS5zZXQodGhpcy5jZWxsVmFsdWUpO1xyXG4gICAgICAgICAgdGhpcy5pc0VkaXRpbmcuc2V0KHN0YXRlID09PSBpbmRleCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgb25JbnB1dENoYW5nZSh2YWx1ZTogYW55KTogdm9pZCB7XHJcbiAgICB0aGlzLmVkaXRDZWxsVmFsdWUuc2V0KHZhbHVlKTtcclxuICAgIGlmICh0aGlzLmlzRWRpdGluZygpKSB7XHJcbiAgICAgIHRoaXMuZWRpdFJvd1NlcnZpY2UudXBkYXRlRWRpdFZhbHVlcyh0aGlzLmVkaXRLZXksIHZhbHVlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0Q2VsbEluZGV4KCk6IG51bWJlciB7XHJcbiAgICBjb25zdCBwYXJlbnQgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5wYXJlbnRFbGVtZW50IGFzIEhUTUxFbGVtZW50O1xyXG4gICAgcmV0dXJuIEFycmF5LmZyb20ocGFyZW50LmNoaWxkcmVuKS5pbmRleE9mKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0Um93SW5kZXgoKTogbnVtYmVyIHtcclxuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5wYXJlbnRFbGVtZW50IGFzIEhUTUxFbGVtZW50O1xyXG4gICAgY29uc3QgcGFyZW50ID0gZWxlbWVudC5wYXJlbnRFbGVtZW50O1xyXG4gICAgaWYgKCFwYXJlbnQpIHJldHVybiAtMTtcclxuXHJcbiAgICBjb25zdCBjaGlsZHJlbiA9IEFycmF5LmZyb20ocGFyZW50LmNoaWxkcmVuKTtcclxuICAgIHJldHVybiBjaGlsZHJlbi5pbmRleE9mKGVsZW1lbnQpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuc3Vic2NyaXB0aW9uKSB7XHJcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcbiIsIjxkaXYgY2xhc3M9XCJmdS1ib2R5LXJvdy1jZWxsXCIgW2F0dHIuZGF0YS1lZGl0XT1cImlzRWRpdGluZygpXCI+XHJcbiAgPHNwYW4+e3sgY2VsbERlZiB9fTwvc3Bhbj5cclxuXHJcbiAgQGlmIChjZWxsVmFsdWUpIHsgQGlmKGlzRWRpdGluZygpKXtcclxuICA8aW5wdXRcclxuICAgIGNsYXNzPVwiZnUtZWRpdC1pbnB1dFwiXHJcbiAgICBbKG5nTW9kZWwpXT1cImVkaXRDZWxsVmFsdWVcIlxyXG4gICAgKG5nTW9kZWxDaGFuZ2UpPVwib25JbnB1dENoYW5nZSgkZXZlbnQpXCJcclxuICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxyXG4gIC8+XHJcbiAgfUBlbHNlIHtcclxuICA8c3Bhbj57eyBjZWxsVmFsdWUgfX08L3NwYW4+XHJcbiAgfSB9IEBlbHNlIHtcclxuICA8bmctY29udGVudCAvPlxyXG4gIH1cclxuPC9kaXY+XHJcbiJdfQ==
@@ -0,0 +1,37 @@
1
+ import { ChangeDetectionStrategy, Component, Input, ViewEncapsulation, effect, } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ import * as i1 from "../../services/data-sorting.service";
4
+ import * as i2 from "../../directives/sort-column.directive";
5
+ export class HeadRowCellComponent {
6
+ constructor(sortService, elementRef) {
7
+ this.sortService = sortService;
8
+ this.elementRef = elementRef;
9
+ effect(() => {
10
+ this.direction = this.sortService.sortDirection();
11
+ this.sorting = this.sortService.sortKey();
12
+ });
13
+ }
14
+ ngOnInit() {
15
+ const index = this.getIndex();
16
+ this.sortService.setCellDef(index, this.cellDef);
17
+ }
18
+ onSort() {
19
+ this.sortService.setSortKey(this.sortKey);
20
+ }
21
+ getIndex() {
22
+ const parent = this.elementRef.nativeElement.parentElement;
23
+ return Array.from(parent.children).indexOf(this.elementRef.nativeElement);
24
+ }
25
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: HeadRowCellComponent, deps: [{ token: i1.DataSortingService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
26
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.6", type: HeadRowCellComponent, selector: "fu-head-row-cell", inputs: { cellDef: "cellDef", sortKey: "sortKey" }, ngImport: i0, template: "<div class=\"fu-head-row-cell\" [sortColumn]=\"sortKey\" (click)=\"onSort()\">\r\n <span>{{ cellDef }}</span>\r\n @if (sortKey) { @if (sortKey === sorting) {\r\n <button>{{ direction === \"asc\" ? \"&#8593;\" : \"&#8595;\" }}</button>\r\n } @else {\r\n <button>&#8645;</button>\r\n } }\r\n</div>\r\n", styles: [".fu-head-row-cell{padding:16px;font-weight:700}.fu-head-row-cell>span{margin-right:4px}.fu-head-row-cell>button{cursor:pointer;background-color:transparent;color:var(--fu-grid-text-color);font-weight:700;border:none;width:16px;height:16px}@media (max-width: 900px){.fu-head-row-cell{display:none;width:100%}.fu-head-row-cell[data-sorted]{display:block}}.fu-head-row-cell[data-sorted]:hover{cursor:pointer;background-color:var(--fu-grid-hover-color)}.fu-head-row-cell.sort-asc,.fu-head-row-cell.sort-desc{background-color:var(--fu-grid-fg-color)}\n"], dependencies: [{ kind: "directive", type: i2.SortColumnDirective, selector: "[sortColumn]", inputs: ["sortColumn"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
27
+ }
28
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: HeadRowCellComponent, decorators: [{
29
+ type: Component,
30
+ args: [{ selector: 'fu-head-row-cell', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"fu-head-row-cell\" [sortColumn]=\"sortKey\" (click)=\"onSort()\">\r\n <span>{{ cellDef }}</span>\r\n @if (sortKey) { @if (sortKey === sorting) {\r\n <button>{{ direction === \"asc\" ? \"&#8593;\" : \"&#8595;\" }}</button>\r\n } @else {\r\n <button>&#8645;</button>\r\n } }\r\n</div>\r\n", styles: [".fu-head-row-cell{padding:16px;font-weight:700}.fu-head-row-cell>span{margin-right:4px}.fu-head-row-cell>button{cursor:pointer;background-color:transparent;color:var(--fu-grid-text-color);font-weight:700;border:none;width:16px;height:16px}@media (max-width: 900px){.fu-head-row-cell{display:none;width:100%}.fu-head-row-cell[data-sorted]{display:block}}.fu-head-row-cell[data-sorted]:hover{cursor:pointer;background-color:var(--fu-grid-hover-color)}.fu-head-row-cell.sort-asc,.fu-head-row-cell.sort-desc{background-color:var(--fu-grid-fg-color)}\n"] }]
31
+ }], ctorParameters: () => [{ type: i1.DataSortingService }, { type: i0.ElementRef }], propDecorators: { cellDef: [{
32
+ type: Input,
33
+ args: [{ required: true }]
34
+ }], sortKey: [{
35
+ type: Input
36
+ }] } });
37
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVhZC1yb3ctY2VsbC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1mdXNpb24tdWkvc3JjL2xpYi9kYXRhLWdyaWQvY29tcG9uZW50cy9oZWFkLXJvdy1jZWxsL2hlYWQtcm93LWNlbGwuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctZnVzaW9uLXVpL3NyYy9saWIvZGF0YS1ncmlkL2NvbXBvbmVudHMvaGVhZC1yb3ctY2VsbC9oZWFkLXJvdy1jZWxsLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUVULEtBQUssRUFFTCxpQkFBaUIsRUFDakIsTUFBTSxHQUNQLE1BQU0sZUFBZSxDQUFDOzs7O0FBVXZCLE1BQU0sT0FBTyxvQkFBb0I7SUFPL0IsWUFDVSxXQUErQixFQUMvQixVQUFzQjtRQUR0QixnQkFBVyxHQUFYLFdBQVcsQ0FBb0I7UUFDL0IsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUU5QixNQUFNLENBQUMsR0FBRyxFQUFFO1lBQ1YsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ2xELElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUM1QyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTSxRQUFRO1FBQ2IsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUVELE1BQU07UUFDSixJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVPLFFBQVE7UUFDZCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUM7UUFDM0QsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUM1RSxDQUFDOzhHQTdCVSxvQkFBb0I7a0dBQXBCLG9CQUFvQiw0R0NsQmpDLG1UQVFBOzsyRkRVYSxvQkFBb0I7a0JBUGhDLFNBQVM7K0JBQ0Usa0JBQWtCLG1CQUdYLHVCQUF1QixDQUFDLE1BQU0saUJBQ2hDLGlCQUFpQixDQUFDLElBQUk7Z0hBR0gsT0FBTztzQkFBeEMsS0FBSzt1QkFBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUU7Z0JBQ1QsT0FBTztzQkFBdEIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXHJcbiAgQ29tcG9uZW50LFxyXG4gIEVsZW1lbnRSZWYsXHJcbiAgSW5wdXQsXHJcbiAgT25Jbml0LFxyXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxyXG4gIGVmZmVjdCxcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRGF0YVNvcnRpbmdTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZGF0YS1zb3J0aW5nLnNlcnZpY2UnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdmdS1oZWFkLXJvdy1jZWxsJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vaGVhZC1yb3ctY2VsbC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmw6ICcuL2hlYWQtcm93LWNlbGwuY29tcG9uZW50LnNjc3MnLFxyXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxyXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBIZWFkUm93Q2VsbENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcbiAgQElucHV0KHsgcmVxdWlyZWQ6IHRydWUgfSkgcHVibGljIGNlbGxEZWY6IHN0cmluZztcclxuICBASW5wdXQoKSBwdWJsaWMgc29ydEtleTogc3RyaW5nO1xyXG5cclxuICBwdWJsaWMgZGlyZWN0aW9uOiBzdHJpbmc7XHJcbiAgcHVibGljIHNvcnRpbmc6IHN0cmluZztcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIHNvcnRTZXJ2aWNlOiBEYXRhU29ydGluZ1NlcnZpY2UsXHJcbiAgICBwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWZcclxuICApIHtcclxuICAgIGVmZmVjdCgoKSA9PiB7XHJcbiAgICAgIHRoaXMuZGlyZWN0aW9uID0gdGhpcy5zb3J0U2VydmljZS5zb3J0RGlyZWN0aW9uKCk7XHJcbiAgICAgIHRoaXMuc29ydGluZyA9IHRoaXMuc29ydFNlcnZpY2Uuc29ydEtleSgpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICBjb25zdCBpbmRleCA9IHRoaXMuZ2V0SW5kZXgoKTtcclxuICAgIHRoaXMuc29ydFNlcnZpY2Uuc2V0Q2VsbERlZihpbmRleCwgdGhpcy5jZWxsRGVmKTtcclxuICB9XHJcblxyXG4gIG9uU29ydCgpOiB2b2lkIHtcclxuICAgIHRoaXMuc29ydFNlcnZpY2Uuc2V0U29ydEtleSh0aGlzLnNvcnRLZXkpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRJbmRleCgpOiBudW1iZXIge1xyXG4gICAgY29uc3QgcGFyZW50ID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucGFyZW50RWxlbWVudDtcclxuICAgIHJldHVybiBBcnJheS5mcm9tKHBhcmVudC5jaGlsZHJlbikuaW5kZXhPZih0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCk7XHJcbiAgfVxyXG59XHJcbiIsIjxkaXYgY2xhc3M9XCJmdS1oZWFkLXJvdy1jZWxsXCIgW3NvcnRDb2x1bW5dPVwic29ydEtleVwiIChjbGljayk9XCJvblNvcnQoKVwiPlxyXG4gIDxzcGFuPnt7IGNlbGxEZWYgfX08L3NwYW4+XHJcbiAgQGlmIChzb3J0S2V5KSB7IEBpZiAoc29ydEtleSA9PT0gc29ydGluZykge1xyXG4gIDxidXR0b24+e3sgZGlyZWN0aW9uID09PSBcImFzY1wiID8gXCImIzg1OTM7XCIgOiBcIiYjODU5NTtcIiB9fTwvYnV0dG9uPlxyXG4gIH0gQGVsc2Uge1xyXG4gIDxidXR0b24+JiM4NjQ1OzwvYnV0dG9uPlxyXG4gIH0gfVxyXG48L2Rpdj5cclxuIl19
@@ -0,0 +1,67 @@
1
+ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewEncapsulation, signal, } from '@angular/core';
2
+ import { take } from 'rxjs';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "../../services/edit-row.service";
5
+ export class RowActionsComponent {
6
+ constructor(renderer, el, editRowService) {
7
+ this.renderer = renderer;
8
+ this.el = el;
9
+ this.editRowService = editRowService;
10
+ this.isEditing = signal(false);
11
+ this.showDelete = false;
12
+ this.editSave = new EventEmitter();
13
+ this.delete = new EventEmitter();
14
+ this.renderer.setAttribute(this.el.nativeElement, 'data-actions', 'true');
15
+ }
16
+ ngOnInit() {
17
+ this.showDelete = this.delete.observers.length > 0;
18
+ }
19
+ ngOnChanges(changes) {
20
+ if (changes['editRow'] && changes['editIndex']) {
21
+ this.subscription = this.editRowService.editState$.subscribe((state) => {
22
+ this.isEditing.set(state === this.editIndex);
23
+ });
24
+ }
25
+ }
26
+ setEdit(e) {
27
+ this.editRowService.startEditing(this.editIndex);
28
+ e.stopPropagation();
29
+ }
30
+ cancelEdit(e) {
31
+ this.editRowService.stopEditing();
32
+ e.stopPropagation();
33
+ }
34
+ saveEdit(e) {
35
+ this.editRowService.stopEditing();
36
+ this.editRowService.editValues$.pipe(take(1)).subscribe((editedValues) => {
37
+ const updatedRow = { ...this.editRow, ...editedValues };
38
+ this.editSave.emit(updatedRow);
39
+ });
40
+ this.editRowService.resetEditValues();
41
+ e.stopPropagation();
42
+ }
43
+ emitDelete(e) {
44
+ this.delete.emit();
45
+ e.stopPropagation();
46
+ }
47
+ ngOnDestroy() {
48
+ if (this.subscription) {
49
+ this.subscription.unsubscribe();
50
+ }
51
+ }
52
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: RowActionsComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i1.EditRowService }], target: i0.ɵɵFactoryTarget.Component }); }
53
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.6", type: RowActionsComponent, selector: "fu-row-actions", inputs: { editRow: "editRow", editIndex: "editIndex" }, outputs: { editSave: "editSave", delete: "delete" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"actions\">\r\n @if (editRow && editIndex !== null) { @if(isEditing()){\r\n <button (click)=\"cancelEdit($event)\">&#8861;</button>\r\n <button (click)=\"saveEdit($event)\">&#10003;</button>\r\n }@else {\r\n <button (click)=\"setEdit($event)\">&#9998;</button>\r\n } } @if (!isEditing() && showDelete) {\r\n <button (click)=\"emitDelete($event)\">&#10007;</button>\r\n }\r\n <ng-content />\r\n</div>\r\n", styles: [".actions{display:flex;justify-content:center;align-items:center;height:100%;gap:12px}.actions button{width:25px;height:25px;border:none;background-color:#958d8d}.actions button:hover{cursor:pointer;background-color:#ff4500}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
54
+ }
55
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: RowActionsComponent, decorators: [{
56
+ type: Component,
57
+ args: [{ selector: 'fu-row-actions', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"actions\">\r\n @if (editRow && editIndex !== null) { @if(isEditing()){\r\n <button (click)=\"cancelEdit($event)\">&#8861;</button>\r\n <button (click)=\"saveEdit($event)\">&#10003;</button>\r\n }@else {\r\n <button (click)=\"setEdit($event)\">&#9998;</button>\r\n } } @if (!isEditing() && showDelete) {\r\n <button (click)=\"emitDelete($event)\">&#10007;</button>\r\n }\r\n <ng-content />\r\n</div>\r\n", styles: [".actions{display:flex;justify-content:center;align-items:center;height:100%;gap:12px}.actions button{width:25px;height:25px;border:none;background-color:#958d8d}.actions button:hover{cursor:pointer;background-color:#ff4500}\n"] }]
58
+ }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i1.EditRowService }], propDecorators: { editRow: [{
59
+ type: Input
60
+ }], editIndex: [{
61
+ type: Input
62
+ }], editSave: [{
63
+ type: Output
64
+ }], delete: [{
65
+ type: Output
66
+ }] } });
67
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm93LWFjdGlvbnMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctZnVzaW9uLXVpL3NyYy9saWIvZGF0YS1ncmlkL2NvbXBvbmVudHMvcm93LWFjdGlvbnMvcm93LWFjdGlvbnMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctZnVzaW9uLXVpL3NyYy9saWIvZGF0YS1ncmlkL2NvbXBvbmVudHMvcm93LWFjdGlvbnMvcm93LWFjdGlvbnMuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBRVQsWUFBWSxFQUNaLEtBQUssRUFJTCxNQUFNLEVBR04saUJBQWlCLEVBQ2pCLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQWdCLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQzs7O0FBUzFDLE1BQU0sT0FBTyxtQkFBbUI7SUFZOUIsWUFDVSxRQUFtQixFQUNuQixFQUFjLEVBQ2QsY0FBOEI7UUFGOUIsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQUNuQixPQUFFLEdBQUYsRUFBRSxDQUFZO1FBQ2QsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBWGpDLGNBQVMsR0FBRyxNQUFNLENBQVUsS0FBSyxDQUFDLENBQUM7UUFDbkMsZUFBVSxHQUFZLEtBQUssQ0FBQztRQUVsQixhQUFRLEdBQUcsSUFBSSxZQUFZLEVBQUssQ0FBQztRQUNqQyxXQUFNLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQVNqRCxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxjQUFjLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDNUUsQ0FBQztJQUVNLFFBQVE7UUFDYixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDckQsQ0FBQztJQUVNLFdBQVcsQ0FBQyxPQUFzQjtRQUN2QyxJQUFJLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxPQUFPLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztZQUMvQyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO2dCQUNyRSxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQy9DLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUM7SUFFTSxPQUFPLENBQUMsQ0FBUTtRQUNyQixJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFakQsQ0FBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO0lBQ3RCLENBQUM7SUFFTSxVQUFVLENBQUMsQ0FBUTtRQUN4QixJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBRWxDLENBQUMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUN0QixDQUFDO0lBRU0sUUFBUSxDQUFDLENBQVE7UUFDdEIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUVsQyxJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsWUFBWSxFQUFFLEVBQUU7WUFDdkUsTUFBTSxVQUFVLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsR0FBRyxZQUFZLEVBQUUsQ0FBQztZQUV4RCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNqQyxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxjQUFjLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdEMsQ0FBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO0lBQ3RCLENBQUM7SUFFTSxVQUFVLENBQUMsQ0FBUTtRQUN4QixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ25CLENBQUMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUN0QixDQUFDO0lBRU0sV0FBVztRQUNoQixJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUN0QixJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ2xDLENBQUM7SUFDSCxDQUFDOzhHQWxFVSxtQkFBbUI7a0dBQW5CLG1CQUFtQix3TEN6QmhDLDBhQVdBOzsyRkRjYSxtQkFBbUI7a0JBUC9CLFNBQVM7K0JBQ0UsZ0JBQWdCLG1CQUdULHVCQUF1QixDQUFDLE1BQU0saUJBQ2hDLGlCQUFpQixDQUFDLElBQUk7b0lBR3JCLE9BQU87c0JBQXRCLEtBQUs7Z0JBQ1UsU0FBUztzQkFBeEIsS0FBSztnQkFLVyxRQUFRO3NCQUF4QixNQUFNO2dCQUNVLE1BQU07c0JBQXRCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxyXG4gIENvbXBvbmVudCxcclxuICBFbGVtZW50UmVmLFxyXG4gIEV2ZW50RW1pdHRlcixcclxuICBJbnB1dCxcclxuICBPbkNoYW5nZXMsXHJcbiAgT25EZXN0cm95LFxyXG4gIE9uSW5pdCxcclxuICBPdXRwdXQsXHJcbiAgUmVuZGVyZXIyLFxyXG4gIFNpbXBsZUNoYW5nZXMsXHJcbiAgVmlld0VuY2Fwc3VsYXRpb24sXHJcbiAgc2lnbmFsLFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBFZGl0Um93U2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2VkaXQtcm93LnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBTdWJzY3JpcHRpb24sIHRha2UgfSBmcm9tICdyeGpzJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnZnUtcm93LWFjdGlvbnMnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9yb3ctYWN0aW9ucy5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmw6ICcuL3Jvdy1hY3Rpb25zLmNvbXBvbmVudC5zY3NzJyxcclxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcclxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgUm93QWN0aW9uc0NvbXBvbmVudDxUPiBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25Jbml0LCBPbkRlc3Ryb3kge1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBlZGl0Um93OiBUO1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBlZGl0SW5kZXg6IG51bWJlcjtcclxuXHJcbiAgcHVibGljIGlzRWRpdGluZyA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XHJcbiAgcHVibGljIHNob3dEZWxldGU6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgQE91dHB1dCgpIHB1YmxpYyBlZGl0U2F2ZSA9IG5ldyBFdmVudEVtaXR0ZXI8VD4oKTtcclxuICBAT3V0cHV0KCkgcHVibGljIGRlbGV0ZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcclxuXHJcbiAgcHJpdmF0ZSBzdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXHJcbiAgICBwcml2YXRlIGVsOiBFbGVtZW50UmVmLFxyXG4gICAgcHJpdmF0ZSBlZGl0Um93U2VydmljZTogRWRpdFJvd1NlcnZpY2VcclxuICApIHtcclxuICAgIHRoaXMucmVuZGVyZXIuc2V0QXR0cmlidXRlKHRoaXMuZWwubmF0aXZlRWxlbWVudCwgJ2RhdGEtYWN0aW9ucycsICd0cnVlJyk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLnNob3dEZWxldGUgPSB0aGlzLmRlbGV0ZS5vYnNlcnZlcnMubGVuZ3RoID4gMDtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XHJcbiAgICBpZiAoY2hhbmdlc1snZWRpdFJvdyddICYmIGNoYW5nZXNbJ2VkaXRJbmRleCddKSB7XHJcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9uID0gdGhpcy5lZGl0Um93U2VydmljZS5lZGl0U3RhdGUkLnN1YnNjcmliZSgoc3RhdGUpID0+IHtcclxuICAgICAgICB0aGlzLmlzRWRpdGluZy5zZXQoc3RhdGUgPT09IHRoaXMuZWRpdEluZGV4KTtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2V0RWRpdChlOiBFdmVudCk6IHZvaWQge1xyXG4gICAgdGhpcy5lZGl0Um93U2VydmljZS5zdGFydEVkaXRpbmcodGhpcy5lZGl0SW5kZXgpO1xyXG5cclxuICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgY2FuY2VsRWRpdChlOiBFdmVudCk6IHZvaWQge1xyXG4gICAgdGhpcy5lZGl0Um93U2VydmljZS5zdG9wRWRpdGluZygpO1xyXG5cclxuICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2F2ZUVkaXQoZTogRXZlbnQpOiB2b2lkIHtcclxuICAgIHRoaXMuZWRpdFJvd1NlcnZpY2Uuc3RvcEVkaXRpbmcoKTtcclxuXHJcbiAgICB0aGlzLmVkaXRSb3dTZXJ2aWNlLmVkaXRWYWx1ZXMkLnBpcGUodGFrZSgxKSkuc3Vic2NyaWJlKChlZGl0ZWRWYWx1ZXMpID0+IHtcclxuICAgICAgY29uc3QgdXBkYXRlZFJvdyA9IHsgLi4udGhpcy5lZGl0Um93LCAuLi5lZGl0ZWRWYWx1ZXMgfTtcclxuXHJcbiAgICAgIHRoaXMuZWRpdFNhdmUuZW1pdCh1cGRhdGVkUm93KTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuZWRpdFJvd1NlcnZpY2UucmVzZXRFZGl0VmFsdWVzKCk7XHJcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGVtaXREZWxldGUoZTogRXZlbnQpOiB2b2lkIHtcclxuICAgIHRoaXMuZGVsZXRlLmVtaXQoKTtcclxuICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5zdWJzY3JpcHRpb24pIHtcclxuICAgICAgdGhpcy5zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cImFjdGlvbnNcIj5cclxuICBAaWYgKGVkaXRSb3cgJiYgZWRpdEluZGV4ICE9PSBudWxsKSB7IEBpZihpc0VkaXRpbmcoKSl7XHJcbiAgPGJ1dHRvbiAoY2xpY2spPVwiY2FuY2VsRWRpdCgkZXZlbnQpXCI+JiM4ODYxOzwvYnV0dG9uPlxyXG4gIDxidXR0b24gKGNsaWNrKT1cInNhdmVFZGl0KCRldmVudClcIj4mIzEwMDAzOzwvYnV0dG9uPlxyXG4gIH1AZWxzZSB7XHJcbiAgPGJ1dHRvbiAoY2xpY2spPVwic2V0RWRpdCgkZXZlbnQpXCI+JiM5OTk4OzwvYnV0dG9uPlxyXG4gIH0gfSBAaWYgKCFpc0VkaXRpbmcoKSAmJiBzaG93RGVsZXRlKSB7XHJcbiAgPGJ1dHRvbiAoY2xpY2spPVwiZW1pdERlbGV0ZSgkZXZlbnQpXCI+JiMxMDAwNzs8L2J1dHRvbj5cclxuICB9XHJcbiAgPG5nLWNvbnRlbnQgLz5cclxuPC9kaXY+XHJcbiJdfQ==
@@ -0,0 +1,215 @@
1
+ import { ChangeDetectionStrategy, Component, ContentChild, ContentChildren, EventEmitter, Input, Output, TemplateRef, ViewEncapsulation, effect, } from '@angular/core';
2
+ import { DataSortingService } from '../services/data-sorting.service';
3
+ import { GridHeaderTemplateDirective } from '../directives/grid-header-template.directive';
4
+ import { GridBodyTemplateDirective } from '../directives/grid-body-template.directive';
5
+ import { GridExpandTemplateDirective } from '../directives/grid-expand-template.directive';
6
+ import { HeadRowCellComponent } from '../components/head-row-cell/head-row-cell.component';
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "../services/data-sorting.service";
9
+ import * as i2 from "../services/paginator.service";
10
+ import * as i3 from "@angular/common";
11
+ import * as i4 from "@angular/forms";
12
+ import * as i5 from "../directives/grid-columns.directive";
13
+ import * as i6 from "../components/body-row-cell/body-row-cell.component";
14
+ import * as i7 from "../components/head-row-cell/head-row-cell.component";
15
+ export class DataGridComponent {
16
+ constructor(sortService, paginationService) {
17
+ this.sortService = sortService;
18
+ this.paginationService = paginationService;
19
+ this.dataSource = [];
20
+ this.pageSize = 5;
21
+ this.pageSizeOptions = [5, 10, 15];
22
+ this.responsive = [];
23
+ this.localStorageKey = 'data';
24
+ this.dataLoading = false;
25
+ this.lazyLoading = false;
26
+ this.expandable = false;
27
+ this.filter = false;
28
+ this.paginator = false;
29
+ this.hoverable = true;
30
+ this.striped = true;
31
+ this.rowSelect = new EventEmitter();
32
+ this.sortedData = [...this.dataSource];
33
+ this.sortDirection = 'asc';
34
+ this.sortKey = '';
35
+ this.filteredData = [];
36
+ this.filterText = '';
37
+ this.currentPage = 1;
38
+ this.paginatedData = [];
39
+ this.expandedRowIndex = null;
40
+ this.originalOrder = (a, b) => {
41
+ const keys = Object.keys(this.dataSource);
42
+ return keys.indexOf(a.key) - keys.indexOf(b.key);
43
+ };
44
+ effect(() => {
45
+ this.sortData(this.sortService.sortKey());
46
+ });
47
+ this.pageSize = JSON.parse(window.localStorage.getItem(`fu-grid-${this.localStorageKey}-pageSize`) ||
48
+ '5');
49
+ this.currentPage = JSON.parse(window.localStorage.getItem(`fu-grid-${this.localStorageKey}-currentPage`) || '1');
50
+ this.paginationService.setPageSize(this.pageSize);
51
+ this.paginationService.setPage(this.currentPage);
52
+ }
53
+ ngOnChanges(changes) {
54
+ if (changes['dataSource']) {
55
+ if (!this.lazyLoading) {
56
+ this.filteredData = [...this.dataSource];
57
+ this.sortedData = [...this.filteredData];
58
+ }
59
+ this.updatePagination();
60
+ }
61
+ }
62
+ ngAfterContentInit() {
63
+ this.sortService.clear();
64
+ this.headRowCells.forEach((cell, index) => {
65
+ this.sortService.setCellDef(index, cell.cellDef);
66
+ });
67
+ }
68
+ sortData(key) {
69
+ this.sortKey = key;
70
+ const sortDirection = this.sortService.sortDirection();
71
+ this.sortedData.sort((a, b) => {
72
+ if (a[key] < b[key]) {
73
+ return sortDirection === 'asc' ? -1 : 1;
74
+ }
75
+ else if (a[key] > b[key]) {
76
+ return sortDirection === 'asc' ? 1 : -1;
77
+ }
78
+ return 0;
79
+ });
80
+ this.addSortClass(key);
81
+ this.updatePagination();
82
+ }
83
+ addSortClass(key) {
84
+ const sortDirection = this.sortService.sortDirection();
85
+ const element = document.querySelector(`[data-sorted="${key}"]`);
86
+ document
87
+ .querySelectorAll('[data-sorted]')
88
+ .forEach((th) => th.classList.remove('sort-asc', 'sort-desc'));
89
+ if (element) {
90
+ element.classList.add(sortDirection === 'asc' ? 'sort-asc' : 'sort-desc');
91
+ }
92
+ }
93
+ filterData() {
94
+ if (this.filterText.trim() === '') {
95
+ this.filteredData = [...this.dataSource];
96
+ }
97
+ else {
98
+ this.filteredData = this.dataSource.filter((item) => Object.values(item).some((value) => value.toString().toLowerCase().includes(this.filterText.toLowerCase())));
99
+ }
100
+ this.sortedData = [...this.filteredData];
101
+ this.currentPage = 1;
102
+ this.updatePagination();
103
+ window.localStorage.setItem(`fu-grid-${this.localStorageKey}-currentPage`, this.currentPage.toString());
104
+ }
105
+ serverSidePagination() {
106
+ this.paginatedData = this.dataSource;
107
+ }
108
+ updatePagination() {
109
+ this.expandedRowIndex = null;
110
+ if (this.lazyLoading) {
111
+ return this.serverSidePagination();
112
+ }
113
+ const start = (this.currentPage - 1) * this.pageSize;
114
+ const end = start + this.pageSize;
115
+ this.paginatedData = this.sortedData.slice(start, end);
116
+ }
117
+ goToPage(page) {
118
+ if (page < 1 || page > this.totalPages()) {
119
+ return;
120
+ }
121
+ this.currentPage = page;
122
+ window.localStorage.setItem(`fu-grid-${this.localStorageKey}-currentPage`, this.currentPage.toString());
123
+ this.paginationService.setPage(page);
124
+ this.updatePagination();
125
+ }
126
+ totalPages() {
127
+ return Math.ceil(this.totalItemCount() / this.pageSize);
128
+ }
129
+ getPageStart() {
130
+ return (this.currentPage - 1) * this.pageSize + 1;
131
+ }
132
+ getPageEnd() {
133
+ return Math.min(this.currentPage * this.pageSize, this.totalItemCount());
134
+ }
135
+ changePageSize(event) {
136
+ this.pageSize = Number(event.target.value);
137
+ this.currentPage = 1;
138
+ this.paginationService.setPageSize(this.pageSize);
139
+ this.updatePagination();
140
+ window.localStorage.setItem(`fu-grid-${this.localStorageKey}-currentPage`, this.currentPage.toString());
141
+ window.localStorage.setItem(`fu-grid-${this.localStorageKey}-pageSize`, this.pageSize.toString());
142
+ }
143
+ totalItemCount() {
144
+ return this.totalCount || this.filteredData.length;
145
+ }
146
+ rowClick(row, index = 0) {
147
+ if (this.expandable) {
148
+ if (this.expandedRowIndex === index) {
149
+ this.expandedRowIndex = null;
150
+ }
151
+ else {
152
+ this.expandedRowIndex = index;
153
+ }
154
+ return;
155
+ }
156
+ // this.rowSelect.emit(row);
157
+ }
158
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: DataGridComponent, deps: [{ token: i1.DataSortingService }, { token: i2.PaginationService }], target: i0.ɵɵFactoryTarget.Component }); }
159
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.6", type: DataGridComponent, selector: "fu-data-grid", inputs: { dataSource: "dataSource", totalCount: "totalCount", pageSize: "pageSize", pageSizeOptions: "pageSizeOptions", responsive: "responsive", localStorageKey: "localStorageKey", dataLoading: "dataLoading", lazyLoading: "lazyLoading", expandable: "expandable", filter: "filter", paginator: "paginator", hoverable: "hoverable", striped: "striped" }, outputs: { rowSelect: "rowSelect" }, providers: [DataSortingService], queries: [{ propertyName: "captionTemplate", first: true, predicate: ["caption"], descendants: true }, { propertyName: "headerTemplate", first: true, predicate: GridHeaderTemplateDirective, descendants: true, read: TemplateRef }, { propertyName: "bodyTemplate", first: true, predicate: GridBodyTemplateDirective, descendants: true, read: TemplateRef }, { propertyName: "expandTemplate", first: true, predicate: GridExpandTemplateDirective, descendants: true, read: TemplateRef }, { propertyName: "footerTemplate", first: true, predicate: ["footer"], descendants: true }, { propertyName: "noContentTemplate", first: true, predicate: ["nocontent"], descendants: true }, { propertyName: "headRowCells", predicate: HeadRowCellComponent }], usesOnChanges: true, ngImport: i0, template: "<div id=\"fusion-datagrid\" class=\"fu-data-grid-wrapper\">\r\n @if (filter) {\r\n <input\r\n class=\"fu-data-grid-filter\"\r\n type=\"text\"\r\n [(ngModel)]=\"filterText\"\r\n (input)=\"filterData()\"\r\n placeholder=\"Search keyword...\"\r\n />\r\n }\r\n\r\n <div class=\"fu-data-grid-container\">\r\n <div class=\"fu-data-grid-header\">\r\n <div class=\"fu-head-row\" gridColumns [responsive]=\"responsive\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerTemplate || defaultHeaderTemplate;\r\n context: { $implicit: dataSource }\r\n \"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"fu-data-grid-body\">\r\n <div *ngIf=\"dataLoading\" class=\"fu-data-grid-spinner-overlay\">\r\n <div class=\"fu-spinner\"></div>\r\n </div>\r\n\r\n @for (row of paginatedData; track $index) {\r\n <div\r\n class=\"fu-body-row\"\r\n [ngClass]=\"{ hoverable, striped }\"\r\n (click)=\"rowClick(row, $index)\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n bodyTemplate || defaultBodyTemplate;\r\n context: { $implicit: row, index: $index }\r\n \"\r\n />\r\n\r\n @if (expandable && expandedRowIndex === $index) {\r\n <div class=\"fu-expanded-row\" (click)=\"$event.stopPropagation()\">\r\n <div>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n expandTemplate;\r\n context: { $implicit: row, index: $index }\r\n \"\r\n />\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngTemplateOutlet=\"footerTemplate\" />\r\n\r\n @if (paginator) {\r\n <ng-container\r\n *ngTemplateOutlet=\"defaultPaginator; context: { $implicit: sortData }\"\r\n />\r\n }\r\n</div>\r\n\r\n<ng-template #defaultHeaderTemplate let-data>\r\n @for (header of data[0] | keyvalue: originalOrder; track $index) {\r\n <fu-head-row-cell [cellDef]=\"$any(header.key)\" [sortKey]=\"$any(header.key)\" />\r\n }\r\n</ng-template>\r\n\r\n<ng-template #defaultBodyTemplate let-rows>\r\n @for (row of rows | keyvalue: originalOrder; track $index) {\r\n <fu-body-row-cell [cellValue]=\"$any(row.value)\" />\r\n }\r\n</ng-template>\r\n\r\n<ng-template #defaultPaginator let-data>\r\n <div class=\"fu-data-grid-paginator\">\r\n <div>\r\n <span>Items per page:</span>\r\n <select (change)=\"changePageSize($event)\">\r\n <option\r\n *ngFor=\"let size of pageSizeOptions\"\r\n [value]=\"size\"\r\n [selected]=\"size === pageSize\"\r\n >\r\n {{ size }}\r\n </option>\r\n </select>\r\n </div>\r\n <div>\r\n {{ getPageStart() }} - {{ getPageEnd() }} of {{ totalItemCount() }}\r\n </div>\r\n <button (click)=\"goToPage(1)\" [disabled]=\"currentPage === 1\"><<</button>\r\n <button (click)=\"goToPage(currentPage - 1)\" [disabled]=\"currentPage === 1\">\r\n <\r\n </button>\r\n <button\r\n (click)=\"goToPage(currentPage + 1)\"\r\n [disabled]=\"currentPage >= totalPages()\"\r\n >\r\n >\r\n </button>\r\n <button\r\n (click)=\"goToPage(totalPages())\"\r\n [disabled]=\"currentPage >= totalPages()\"\r\n >\r\n >>\r\n </button>\r\n </div>\r\n</ng-template>\r\n", styles: [":root{--fu-grid-fg-color: #232534;--fu-grid-bg-color: #1e1f2b;--fu-grid-hover-color: #12121240;--fu-grid-striped-color: #22232e;--fu-grid-border-color: #4b444d;--fu-grid-text-color: #ffffff;--fu-grid-cell-color: #bab9b9;--fu-filter-input-color: #ccc;--fu-grid-shape: 4px}.fu-data-grid-wrapper{border-radius:var(--fu-grid-shape);box-shadow:0 2px 4px #00000080;background-color:var(--fu-grid-bg-color);color:var(--fu-grid-text-color);font-family:Roboto,sans-serif;font-size:14px}.fu-data-grid-container{width:100%}.fu-data-grid-container .fu-data-grid-header .fu-head-row{display:grid;grid-template-columns:repeat(var(--grid-columns),1fr);border-bottom:1px solid var(--fu-grid-border-color)}@media (max-width: 900px){.fu-data-grid-container .fu-data-grid-header .fu-head-row{display:flex;justify-content:space-between;flex-wrap:wrap}.fu-data-grid-container .fu-data-grid-header .fu-head-row>*{flex:1 1 auto}}.fu-data-grid-container .fu-data-grid-body{min-height:150px;position:relative}.fu-data-grid-container .fu-data-grid-body .fu-body-row{display:grid;grid-template-columns:repeat(var(--grid-columns),1fr);border-bottom:1px solid var(--fu-grid-border-color)}.fu-data-grid-container .fu-data-grid-body .fu-body-row.striped:nth-child(2n){background-color:var(--fu-grid-striped-color)}.fu-data-grid-container .fu-data-grid-body .fu-body-row.hoverable:hover{cursor:pointer;background-color:var(--fu-grid-hover-color)}@media (max-width: 900px){.fu-data-grid-container .fu-data-grid-body .fu-body-row{grid-template-columns:repeat(var(--grid-columns),1fr)}.fu-data-grid-container .fu-data-grid-body .fu-body-row :nth-child(odd):last-child{grid-column:span 2}.fu-data-grid-container .fu-data-grid-body .fu-body-row [data-actions]{grid-column:1/-1;margin:8px 0}}@media (max-width: 600px){.fu-data-grid-container .fu-data-grid-body .fu-body-row{grid-template-columns:1fr;border-bottom:1px solid var(--fu-grid-border-color)}.fu-data-grid-container .fu-data-grid-body .fu-body-row>:nth-child(odd):last-child{grid-column:span 1}}.fu-data-grid-container .fu-data-grid-body .fu-body-row .fu-expanded-row{grid-column:1/-1;border-top:1px solid rgba(128,128,128,.1);padding:12px 16px}.fu-data-grid-container .fu-data-grid-body .fu-body-row .fu-expanded-row>div{cursor:default}.fu-data-grid-paginator{display:flex;justify-content:flex-end;padding:16px;gap:4px}.fu-data-grid-paginator div{display:flex;align-items:center;margin-right:12px;font-size:14px}.fu-data-grid-paginator div span{margin-right:8px}.fu-data-grid-paginator button{cursor:pointer;padding:0 4px}.fu-data-grid-filter{box-sizing:border-box;background-color:var(--fu-grid-fg-color);color:var(--fu-filter-input-color);width:calc(100% - 32px);padding:12px 8px;margin:16px;outline:none;border:none}.fu-data-grid-spinner-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#78787880;display:flex;justify-content:center;align-items:center;z-index:1000}.fu-data-grid-spinner-overlay .fu-spinner{border:10px solid var(--fu-grid-bg-color);border-top:10px solid #3498db;border-radius:50%;width:30px;height:30px;animation:spin 2s linear infinite;margin:5px auto}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i4.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.GridColumnsDirective, selector: "[gridColumns]", inputs: ["responsive"] }, { kind: "component", type: i6.BodyRowCellComponent, selector: "fu-body-row-cell", inputs: ["cellValue", "editKey", "editCellValue"], outputs: ["editCellValueChange"] }, { kind: "component", type: i7.HeadRowCellComponent, selector: "fu-head-row-cell", inputs: ["cellDef", "sortKey"] }, { kind: "pipe", type: i3.KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
160
+ }
161
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.6", ngImport: i0, type: DataGridComponent, decorators: [{
162
+ type: Component,
163
+ args: [{ selector: 'fu-data-grid', providers: [DataSortingService], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div id=\"fusion-datagrid\" class=\"fu-data-grid-wrapper\">\r\n @if (filter) {\r\n <input\r\n class=\"fu-data-grid-filter\"\r\n type=\"text\"\r\n [(ngModel)]=\"filterText\"\r\n (input)=\"filterData()\"\r\n placeholder=\"Search keyword...\"\r\n />\r\n }\r\n\r\n <div class=\"fu-data-grid-container\">\r\n <div class=\"fu-data-grid-header\">\r\n <div class=\"fu-head-row\" gridColumns [responsive]=\"responsive\">\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n headerTemplate || defaultHeaderTemplate;\r\n context: { $implicit: dataSource }\r\n \"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"fu-data-grid-body\">\r\n <div *ngIf=\"dataLoading\" class=\"fu-data-grid-spinner-overlay\">\r\n <div class=\"fu-spinner\"></div>\r\n </div>\r\n\r\n @for (row of paginatedData; track $index) {\r\n <div\r\n class=\"fu-body-row\"\r\n [ngClass]=\"{ hoverable, striped }\"\r\n (click)=\"rowClick(row, $index)\"\r\n >\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n bodyTemplate || defaultBodyTemplate;\r\n context: { $implicit: row, index: $index }\r\n \"\r\n />\r\n\r\n @if (expandable && expandedRowIndex === $index) {\r\n <div class=\"fu-expanded-row\" (click)=\"$event.stopPropagation()\">\r\n <div>\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n expandTemplate;\r\n context: { $implicit: row, index: $index }\r\n \"\r\n />\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <ng-container *ngTemplateOutlet=\"footerTemplate\" />\r\n\r\n @if (paginator) {\r\n <ng-container\r\n *ngTemplateOutlet=\"defaultPaginator; context: { $implicit: sortData }\"\r\n />\r\n }\r\n</div>\r\n\r\n<ng-template #defaultHeaderTemplate let-data>\r\n @for (header of data[0] | keyvalue: originalOrder; track $index) {\r\n <fu-head-row-cell [cellDef]=\"$any(header.key)\" [sortKey]=\"$any(header.key)\" />\r\n }\r\n</ng-template>\r\n\r\n<ng-template #defaultBodyTemplate let-rows>\r\n @for (row of rows | keyvalue: originalOrder; track $index) {\r\n <fu-body-row-cell [cellValue]=\"$any(row.value)\" />\r\n }\r\n</ng-template>\r\n\r\n<ng-template #defaultPaginator let-data>\r\n <div class=\"fu-data-grid-paginator\">\r\n <div>\r\n <span>Items per page:</span>\r\n <select (change)=\"changePageSize($event)\">\r\n <option\r\n *ngFor=\"let size of pageSizeOptions\"\r\n [value]=\"size\"\r\n [selected]=\"size === pageSize\"\r\n >\r\n {{ size }}\r\n </option>\r\n </select>\r\n </div>\r\n <div>\r\n {{ getPageStart() }} - {{ getPageEnd() }} of {{ totalItemCount() }}\r\n </div>\r\n <button (click)=\"goToPage(1)\" [disabled]=\"currentPage === 1\"><<</button>\r\n <button (click)=\"goToPage(currentPage - 1)\" [disabled]=\"currentPage === 1\">\r\n <\r\n </button>\r\n <button\r\n (click)=\"goToPage(currentPage + 1)\"\r\n [disabled]=\"currentPage >= totalPages()\"\r\n >\r\n >\r\n </button>\r\n <button\r\n (click)=\"goToPage(totalPages())\"\r\n [disabled]=\"currentPage >= totalPages()\"\r\n >\r\n >>\r\n </button>\r\n </div>\r\n</ng-template>\r\n", styles: [":root{--fu-grid-fg-color: #232534;--fu-grid-bg-color: #1e1f2b;--fu-grid-hover-color: #12121240;--fu-grid-striped-color: #22232e;--fu-grid-border-color: #4b444d;--fu-grid-text-color: #ffffff;--fu-grid-cell-color: #bab9b9;--fu-filter-input-color: #ccc;--fu-grid-shape: 4px}.fu-data-grid-wrapper{border-radius:var(--fu-grid-shape);box-shadow:0 2px 4px #00000080;background-color:var(--fu-grid-bg-color);color:var(--fu-grid-text-color);font-family:Roboto,sans-serif;font-size:14px}.fu-data-grid-container{width:100%}.fu-data-grid-container .fu-data-grid-header .fu-head-row{display:grid;grid-template-columns:repeat(var(--grid-columns),1fr);border-bottom:1px solid var(--fu-grid-border-color)}@media (max-width: 900px){.fu-data-grid-container .fu-data-grid-header .fu-head-row{display:flex;justify-content:space-between;flex-wrap:wrap}.fu-data-grid-container .fu-data-grid-header .fu-head-row>*{flex:1 1 auto}}.fu-data-grid-container .fu-data-grid-body{min-height:150px;position:relative}.fu-data-grid-container .fu-data-grid-body .fu-body-row{display:grid;grid-template-columns:repeat(var(--grid-columns),1fr);border-bottom:1px solid var(--fu-grid-border-color)}.fu-data-grid-container .fu-data-grid-body .fu-body-row.striped:nth-child(2n){background-color:var(--fu-grid-striped-color)}.fu-data-grid-container .fu-data-grid-body .fu-body-row.hoverable:hover{cursor:pointer;background-color:var(--fu-grid-hover-color)}@media (max-width: 900px){.fu-data-grid-container .fu-data-grid-body .fu-body-row{grid-template-columns:repeat(var(--grid-columns),1fr)}.fu-data-grid-container .fu-data-grid-body .fu-body-row :nth-child(odd):last-child{grid-column:span 2}.fu-data-grid-container .fu-data-grid-body .fu-body-row [data-actions]{grid-column:1/-1;margin:8px 0}}@media (max-width: 600px){.fu-data-grid-container .fu-data-grid-body .fu-body-row{grid-template-columns:1fr;border-bottom:1px solid var(--fu-grid-border-color)}.fu-data-grid-container .fu-data-grid-body .fu-body-row>:nth-child(odd):last-child{grid-column:span 1}}.fu-data-grid-container .fu-data-grid-body .fu-body-row .fu-expanded-row{grid-column:1/-1;border-top:1px solid rgba(128,128,128,.1);padding:12px 16px}.fu-data-grid-container .fu-data-grid-body .fu-body-row .fu-expanded-row>div{cursor:default}.fu-data-grid-paginator{display:flex;justify-content:flex-end;padding:16px;gap:4px}.fu-data-grid-paginator div{display:flex;align-items:center;margin-right:12px;font-size:14px}.fu-data-grid-paginator div span{margin-right:8px}.fu-data-grid-paginator button{cursor:pointer;padding:0 4px}.fu-data-grid-filter{box-sizing:border-box;background-color:var(--fu-grid-fg-color);color:var(--fu-filter-input-color);width:calc(100% - 32px);padding:12px 8px;margin:16px;outline:none;border:none}.fu-data-grid-spinner-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#78787880;display:flex;justify-content:center;align-items:center;z-index:1000}.fu-data-grid-spinner-overlay .fu-spinner{border:10px solid var(--fu-grid-bg-color);border-top:10px solid #3498db;border-radius:50%;width:30px;height:30px;animation:spin 2s linear infinite;margin:5px auto}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
164
+ }], ctorParameters: () => [{ type: i1.DataSortingService }, { type: i2.PaginationService }], propDecorators: { dataSource: [{
165
+ type: Input,
166
+ args: [{ required: true }]
167
+ }], totalCount: [{
168
+ type: Input
169
+ }], pageSize: [{
170
+ type: Input
171
+ }], pageSizeOptions: [{
172
+ type: Input
173
+ }], responsive: [{
174
+ type: Input
175
+ }], localStorageKey: [{
176
+ type: Input
177
+ }], dataLoading: [{
178
+ type: Input
179
+ }], lazyLoading: [{
180
+ type: Input
181
+ }], expandable: [{
182
+ type: Input
183
+ }], filter: [{
184
+ type: Input
185
+ }], paginator: [{
186
+ type: Input
187
+ }], hoverable: [{
188
+ type: Input
189
+ }], striped: [{
190
+ type: Input
191
+ }], captionTemplate: [{
192
+ type: ContentChild,
193
+ args: ['caption']
194
+ }], headerTemplate: [{
195
+ type: ContentChild,
196
+ args: [GridHeaderTemplateDirective, { read: TemplateRef }]
197
+ }], bodyTemplate: [{
198
+ type: ContentChild,
199
+ args: [GridBodyTemplateDirective, { read: TemplateRef }]
200
+ }], expandTemplate: [{
201
+ type: ContentChild,
202
+ args: [GridExpandTemplateDirective, { read: TemplateRef }]
203
+ }], footerTemplate: [{
204
+ type: ContentChild,
205
+ args: ['footer']
206
+ }], noContentTemplate: [{
207
+ type: ContentChild,
208
+ args: ['nocontent']
209
+ }], headRowCells: [{
210
+ type: ContentChildren,
211
+ args: [HeadRowCellComponent]
212
+ }], rowSelect: [{
213
+ type: Output
214
+ }] } });
215
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS1ncmlkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nLWZ1c2lvbi11aS9zcmMvbGliL2RhdGEtZ3JpZC9kYXRhLWdyaWQvZGF0YS1ncmlkLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nLWZ1c2lvbi11aS9zcmMvbGliL2RhdGEtZ3JpZC9kYXRhLWdyaWQvZGF0YS1ncmlkLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFlBQVksRUFDWixlQUFlLEVBQ2YsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBR04sV0FBVyxFQUNYLGlCQUFpQixFQUNqQixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDdEUsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sOENBQThDLENBQUM7QUFDM0YsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFDdkYsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sOENBQThDLENBQUM7QUFDM0YsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0scURBQXFELENBQUM7Ozs7Ozs7OztBQWtCM0YsTUFBTSxPQUFPLGlCQUFpQjtJQTZDNUIsWUFDVSxXQUErQixFQUMvQixpQkFBb0M7UUFEcEMsZ0JBQVcsR0FBWCxXQUFXLENBQW9CO1FBQy9CLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUE1Q1osZUFBVSxHQUFRLEVBQUUsQ0FBQztRQUV2QyxhQUFRLEdBQVcsQ0FBQyxDQUFDO1FBQ3JCLG9CQUFlLEdBQWUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzFDLGVBQVUsR0FBa0IsRUFBRSxD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c0JBQXpCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIEFmdGVyQ29udGVudEluaXQsXHJcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXHJcbiAgQ29tcG9uZW50LFxyXG4gIENvbnRlbnRDaGlsZCxcclxuICBDb250ZW50Q2hpbGRyZW4sXHJcbiAgRXZlbnRFbWl0dGVyLFxyXG4gIElucHV0LFxyXG4gIE9uQ2hhbmdlcyxcclxuICBPdXRwdXQsXHJcbiAgUXVlcnlMaXN0LFxyXG4gIFNpbXBsZUNoYW5nZXMsXHJcbiAgVGVtcGxhdGVSZWYsXHJcbiAgVmlld0VuY2Fwc3VsYXRpb24sXHJcbiAgZWZmZWN0LFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBEYXRhU29ydGluZ1NlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9kYXRhLXNvcnRpbmcuc2VydmljZSc7XHJcbmltcG9ydCB7IEdyaWRIZWFkZXJUZW1wbGF0ZURpcmVjdGl2ZSB9IGZyb20gJy4uL2RpcmVjdGl2ZXMvZ3JpZC1oZWFkZXItdGVtcGxhdGUuZGlyZWN0aXZlJztcclxuaW1wb3J0IHsgR3JpZEJvZHlUZW1wbGF0ZURpcmVjdGl2ZSB9IGZyb20gJy4uL2RpcmVjdGl2ZXMvZ3JpZC1ib2R5LXRlbXBsYXRlLmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IEdyaWRFeHBhbmRUZW1wbGF0ZURpcmVjdGl2ZSB9IGZyb20gJy4uL2RpcmVjdGl2ZXMvZ3JpZC1leHBhbmQtdGVtcGxhdGUuZGlyZWN0aXZlJztcclxuaW1wb3J0IHsgSGVhZFJvd0NlbGxDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnRzL2hlYWQtcm93LWNlbGwvaGVhZC1yb3ctY2VsbC5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBQYWdpbmF0aW9uU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL3BhZ2luYXRvci5zZXJ2aWNlJztcclxuXHJcbnR5cGUgUGFnZVNpemUgPSA1IHwgMTAgfCAxNTtcclxuXHJcbmV4cG9ydCB0eXBlIFRSZXNwb25zaXZlID0ge1xyXG4gIGJyZWFrcG9pbnQ6IG51bWJlcjtcclxuICBjb2x1bW5zOiBudW1iZXI7XHJcbn07XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2Z1LWRhdGEtZ3JpZCcsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2RhdGEtZ3JpZC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmw6ICcuL2RhdGEtZ3JpZC5jb21wb25lbnQuc2NzcycsXHJcbiAgcHJvdmlkZXJzOiBbRGF0YVNvcnRpbmdTZXJ2aWNlXSxcclxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcclxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgRGF0YUdyaWRDb21wb25lbnQ8VCBleHRlbmRzIG9iamVjdD5cclxuICBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgQWZ0ZXJDb250ZW50SW5pdFxyXG57XHJcbiAgQElucHV0KHsgcmVxdWlyZWQ6IHRydWUgfSkgcHVibGljIGRhdGFTb3VyY2U6IFRbXSA9IFtdO1xyXG4gIEBJbnB1dCgpIHB1YmxpYyB0b3RhbENvdW50OiBudW1iZXI7XHJcbiAgQElucHV0KCkgcHVibGljIHBhZ2VTaXplOiBudW1iZXIgPSA1O1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBwYWdlU2l6ZU9wdGlvbnM6IFBhZ2VTaXplW10gPSBbNSwgMTAsIDE1XTtcclxuICBASW5wdXQoKSBwdWJsaWMgcmVzcG9uc2l2ZTogVFJlc3BvbnNpdmVbXSA9IFtdO1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBsb2NhbFN0b3JhZ2VLZXk6IHN0cmluZyA9ICdkYXRhJztcclxuXHJcbiAgQElucHV0KCkgcHVibGljIGRhdGFMb2FkaW5nOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgcHVibGljIGxhenlMb2FkaW5nOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgcHVibGljIGV4cGFuZGFibGU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBwdWJsaWMgZmlsdGVyOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgcHVibGljIHBhZ2luYXRvcjogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBob3ZlcmFibGU6IGJvb2xlYW4gPSB0cnVlO1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBzdHJpcGVkOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgQENvbnRlbnRDaGlsZCgnY2FwdGlvbicpIHB1YmxpYyBjYXB0aW9uVGVtcGxhdGUhOiBUZW1wbGF0ZVJlZjxhbnk+O1xyXG4gIEBDb250ZW50Q2hpbGQoR3JpZEhlYWRlclRlbXBsYXRlRGlyZWN0aXZlLCB7IHJlYWQ6IFRlbXBsYXRlUmVmIH0pXHJcbiAgcHVibGljIGhlYWRlclRlbXBsYXRlITogVGVtcGxhdGVSZWY8YW55PjtcclxuICBAQ29udGVudENoaWxkKEdyaWRCb2R5VGVtcGxhdGVEaXJlY3RpdmUsIHsgcmVhZDogVGVtcGxhdGVSZWYgfSlcclxuICBwdWJsaWMgYm9keVRlbXBsYXRlITogVGVtcGxhdGVSZWY8YW55PjtcclxuICBAQ29udGVudENoaWxkKEdyaWRFeHBhbmRUZW1wbGF0ZURpcmVjdGl2ZSwgeyByZWFkOiBUZW1wbGF0ZVJlZiB9KVxyXG4gIHB1YmxpYyBleHBhbmRUZW1wbGF0ZSE6IFRlbXBsYXRlUmVmPGFueT47XHJcbiAgQENvbnRlbnRDaGlsZCgnZm9vdGVyJykgcHVibGljIGZvb3RlclRlbXBsYXRlITogVGVtcGxhdGVSZWY8YW55PjtcclxuICBAQ29udGVudENoaWxkKCdub2NvbnRlbnQnKSBwdWJsaWMgbm9Db250ZW50VGVtcGxhdGUhOiBUZW1wbGF0ZVJlZjxhbnk+O1xyXG5cclxuICBAQ29udGVudENoaWxkcmVuKEhlYWRSb3dDZWxsQ29tcG9uZW50KVxyXG4gIHByaXZhdGUgaGVhZFJvd0NlbGxzITogUXVlcnlMaXN0PEhlYWRSb3dDZWxsQ29tcG9uZW50PjtcclxuXHJcbiAgQE91dHB1dCgpIHB1YmxpYyByb3dTZWxlY3QgPSBuZXcgRXZlbnRFbWl0dGVyPFQ+KCk7XHJcblxyXG4gIHB1YmxpYyBzb3J0ZWREYXRhOiBUW10gPSBbLi4udGhpcy5kYXRhU291cmNlXTtcclxuICBwdWJsaWMgc29ydERpcmVjdGlvbjogJ2FzYycgfCAnZGVzYycgPSAnYXNjJztcclxuICBwdWJsaWMgc29ydEtleTogc3RyaW5nID0gJyc7XHJcblxyXG4gIHB1YmxpYyBmaWx0ZXJlZERhdGE6IFRbXSA9IFtdO1xyXG4gIHB1YmxpYyBmaWx0ZXJUZXh0OiBzdHJpbmcgPSAnJztcclxuXHJcbiAgcHVibGljIGN1cnJlbnRQYWdlOiBudW1iZXIgPSAxO1xyXG4gIHB1YmxpYyBwYWdpbmF0ZWREYXRhOiBUW10gPSBbXTtcclxuXHJcbiAgcHVibGljIGV4cGFuZGVkUm93SW5kZXg6IG51bWJlciB8IG51bGwgPSBudWxsO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgc29ydFNlcnZpY2U6IERhdGFTb3J0aW5nU2VydmljZSxcclxuICAgIHByaXZhdGUgcGFnaW5hdGlvblNlcnZpY2U6IFBhZ2luYXRpb25TZXJ2aWNlXHJcbiAgKSB7XHJcbiAgICBlZmZlY3QoKCkgPT4ge1xyXG4gICAgICB0aGlzLnNvcnREYXRhKHRoaXMuc29ydFNlcnZpY2Uuc29ydEtleSgpKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMucGFnZVNpemUgPSBKU09OLnBhcnNlKFxyXG4gICAgICB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0oYGZ1LWdyaWQtJHt0aGlzLmxvY2FsU3RvcmFnZUtleX0tcGFnZVNpemVgKSB8fFxyXG4gICAgICAgICc1J1xyXG4gICAgKTtcclxuICAgIHRoaXMuY3VycmVudFBhZ2UgPSBKU09OLnBhcnNlKFxyXG4gICAgICB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0oXHJcbiAgICAgICAgYGZ1LWdyaWQtJHt0aGlzLmxvY2FsU3RvcmFnZUtleX0tY3VycmVudFBhZ2VgXHJcbiAgICAgICkgfHwgJzEnXHJcbiAgICApO1xyXG5cclxuICAgIHRoaXMucGFnaW5hdGlvblNlcnZpY2Uuc2V0UGFnZVNpemUodGhpcy5wYWdlU2l6ZSk7XHJcbiAgICB0aGlzLnBhZ2luYXRpb25TZXJ2aWNlLnNldFBhZ2UodGhpcy5jdXJyZW50UGFnZSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xyXG4gICAgaWYgKGNoYW5nZXNbJ2RhdGFTb3VyY2UnXSkge1xyXG4gICAgICBpZiAoIXRoaXMubGF6eUxvYWRpbmcpIHtcclxuICAgICAgICB0aGlzLmZpbHRlcmVkRGF0YSA9IFsuLi50aGlzLmRhdGFTb3VyY2VdO1xyXG4gICAgICAgIHRoaXMuc29ydGVkRGF0YSA9IFsuLi50aGlzLmZpbHRlcmVkRGF0YV07XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMudXBkYXRlUGFnaW5hdGlvbigpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIG5nQWZ0ZXJDb250ZW50SW5pdCgpOiB2b2lkIHtcclxuICAgIHRoaXMuc29ydFNlcnZpY2UuY2xlYXIoKTtcclxuICAgIHRoaXMuaGVhZFJvd0NlbGxzLmZvckVhY2goKGNlbGwsIGluZGV4KSA9PiB7XHJcbiAgICAgIHRoaXMuc29ydFNlcnZpY2Uuc2V0Q2VsbERlZihpbmRleCwgY2VsbC5jZWxsRGVmKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG9yaWdpbmFsT3JkZXIgPSAoYTogYW55LCBiOiBhbnkpOiBudW1iZXIgPT4ge1xyXG4gICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHRoaXMuZGF0YVNvdXJjZSk7XHJcbiAgICByZXR1cm4ga2V5cy5pbmRleE9mKGEua2V5KSAtIGtleXMuaW5kZXhPZihiLmtleSk7XHJcbiAgfTtcclxuXHJcbiAgcHVibGljIHNvcnREYXRhKGtleTogYW55KTogdm9pZCB7XHJcbiAgICB0aGlzLnNvcnRLZXkgPSBrZXk7XHJcbiAgICBjb25zdCBzb3J0RGlyZWN0aW9uID0gdGhpcy5zb3J0U2VydmljZS5zb3J0RGlyZWN0aW9uKCk7XHJcblxyXG4gICAgdGhpcy5zb3J0ZWREYXRhLnNvcnQoKGE6IGFueSwgYjogYW55KSA9PiB7XHJcbiAgICAgIGlmIChhW2tleV0gPCBiW2tleV0pIHtcclxuICAgICAgICByZXR1cm4gc29ydERpcmVjdGlvbiA9PT0gJ2FzYycgPyAtMSA6IDE7XHJcbiAgICAgIH0gZWxzZSBpZiAoYVtrZXldID4gYltrZXldKSB7XHJcbiAgICAgICAgcmV0dXJuIHNvcnREaXJlY3Rpb24gPT09ICdhc2MnID8gMSA6IC0xO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiAwO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5hZGRTb3J0Q2xhc3Moa2V5KTtcclxuICAgIHRoaXMudXBkYXRlUGFnaW5hdGlvbigpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhZGRTb3J0Q2xhc3Moa2V5OiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIGNvbnN0IHNvcnREaXJlY3Rpb24gPSB0aGlzLnNvcnRTZXJ2aWNlLnNvcnREaXJlY3Rpb24oKTtcclxuXHJcbiAgICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihgW2RhdGEtc29ydGVkPVwiJHtrZXl9XCJdYCk7XHJcblxyXG4gICAgZG9jdW1lbnRcclxuICAgICAgLnF1ZXJ5U2VsZWN0b3JBbGwoJ1tkYXRhLXNvcnRlZF0nKVxyXG4gICAgICAuZm9yRWFjaCgodGgpID0+IHRoLmNsYXNzTGlzdC5yZW1vdmUoJ3NvcnQtYXNjJywgJ3NvcnQtZGVzYycpKTtcclxuXHJcbiAgICBpZiAoZWxlbWVudCkge1xyXG4gICAgICBlbGVtZW50LmNsYXNzTGlzdC5hZGQoc29ydERpcmVjdGlvbiA9PT0gJ2FzYycgPyAnc29ydC1hc2MnIDogJ3NvcnQtZGVzYycpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIGZpbHRlckRhdGEoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5maWx0ZXJUZXh0LnRyaW0oKSA9PT0gJycpIHtcclxuICAgICAgdGhpcy5maWx0ZXJlZERhdGEgPSBbLi4udGhpcy5kYXRhU291cmNlXTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZmlsdGVyZWREYXRhID0gdGhpcy5kYXRhU291cmNlLmZpbHRlcigoaXRlbTogYW55KSA9PlxyXG4gICAgICAgIE9iamVjdC52YWx1ZXMoaXRlbSkuc29tZSgodmFsdWU6IGFueSkgPT5cclxuICAgICAgICAgIHZhbHVlLnRvU3RyaW5nKCkudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh0aGlzLmZpbHRlclRleHQudG9Mb3dlckNhc2UoKSlcclxuICAgICAgICApXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5zb3J0ZWREYXRhID0gWy4uLnRoaXMuZmlsdGVyZWREYXRhXTtcclxuICAgIHRoaXMuY3VycmVudFBhZ2UgPSAxO1xyXG5cclxuICAgIHRoaXMudXBkYXRlUGFnaW5hdGlvbigpO1xyXG5cclxuICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbShcclxuICAgICAgYGZ1LWdyaWQtJHt0aGlzLmxvY2FsU3RvcmFnZUtleX0tY3VycmVudFBhZ2VgLFxyXG4gICAgICB0aGlzLmN1cnJlbnRQYWdlLnRvU3RyaW5nKClcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHNlcnZlclNpZGVQYWdpbmF0aW9uKCk6IHZvaWQge1xyXG4gICAgdGhpcy5wYWdpbmF0ZWREYXRhID0gdGhpcy5kYXRhU291cmNlO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB1cGRhdGVQYWdpbmF0aW9uKCk6IHZvaWQge1xyXG4gICAgdGhpcy5leHBhbmRlZFJvd0luZGV4ID0gbnVsbDtcclxuXHJcbiAgICBpZiAodGhpcy5sYXp5TG9hZGluZykge1xyXG4gICAgICByZXR1cm4gdGhpcy5zZXJ2ZXJTaWRlUGFnaW5hdGlvbigpO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHN0YXJ0ID0gKHRoaXMuY3VycmVudFBhZ2UgLSAxKSAqIHRoaXMucGFnZVNpemU7XHJcbiAgICBjb25zdCBlbmQgPSBzdGFydCArIHRoaXMucGFnZVNpemU7XHJcbiAgICB0aGlzLnBhZ2luYXRlZERhdGEgPSB0aGlzLnNvcnRlZERhdGEuc2xpY2Uoc3RhcnQsIGVuZCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ29Ub1BhZ2UocGFnZTogbnVtYmVyKTogdm9pZCB7XHJcbiAgICBpZiAocGFnZSA8IDEgfHwgcGFnZSA+IHRoaXMudG90YWxQYWdlcygpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIHRoaXMuY3VycmVudFBhZ2UgPSBwYWdlO1xyXG4gICAgd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKFxyXG4gICAgICBgZnUtZ3JpZC0ke3RoaXMubG9jYWxTdG9yYWdlS2V5fS1jdXJyZW50UGFnZWAsXHJcbiAgICAgIHRoaXMuY3VycmVudFBhZ2UudG9TdHJpbmcoKVxyXG4gICAgKTtcclxuXHJcbiAgICB0aGlzLnBhZ2luYXRpb25TZXJ2aWNlLnNldFBhZ2UocGFnZSk7XHJcbiAgICB0aGlzLnVwZGF0ZVBhZ2luYXRpb24oKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyB0b3RhbFBhZ2VzKCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gTWF0aC5jZWlsKHRoaXMudG90YWxJdGVtQ291bnQoKSAvIHRoaXMucGFnZVNpemUpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldFBhZ2VTdGFydCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuICh0aGlzLmN1cnJlbnRQYWdlIC0gMSkgKiB0aGlzLnBhZ2VTaXplICsgMTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXRQYWdlRW5kKCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gTWF0aC5taW4odGhpcy5jdXJyZW50UGFnZSAqIHRoaXMucGFnZVNpemUsIHRoaXMudG90YWxJdGVtQ291bnQoKSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgY2hhbmdlUGFnZVNpemUoZXZlbnQ6IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy5wYWdlU2l6ZSA9IE51bWJlcihldmVudC50YXJnZXQudmFsdWUpO1xyXG4gICAgdGhpcy5jdXJyZW50UGFnZSA9IDE7XHJcblxyXG4gICAgdGhpcy5wYWdpbmF0aW9uU2VydmljZS5zZXRQYWdlU2l6ZSh0aGlzLnBhZ2VTaXplKTtcclxuICAgIHRoaXMudXBkYXRlUGFnaW5hdGlvbigpO1xyXG5cclxuICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbShcclxuICAgICAgYGZ1LWdyaWQtJHt0aGlzLmxvY2FsU3RvcmFnZUtleX0tY3VycmVudFBhZ2VgLFxyXG4gICAgICB0aGlzLmN1cnJlbnRQYWdlLnRvU3RyaW5nKClcclxuICAgICk7XHJcblxyXG4gICAgd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKFxyXG4gICAgICBgZnUtZ3JpZC0ke3RoaXMubG9jYWxTdG9yYWdlS2V5fS1wYWdlU2l6ZWAsXHJcbiAgICAgIHRoaXMucGFnZVNpemUudG9TdHJpbmcoKVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyB0b3RhbEl0ZW1Db3VudCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMudG90YWxDb3VudCB8fCB0aGlzLmZpbHRlcmVkRGF0YS5sZW5ndGg7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgcm93Q2xpY2socm93OiBULCBpbmRleDogbnVtYmVyID0gMCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuZXhwYW5kYWJsZSkge1xyXG4gICAgICBpZiAodGhpcy5leHBhbmRlZFJvd0luZGV4ID09PSBpbmRleCkge1xyXG4gICAgICAgIHRoaXMuZXhwYW5kZWRSb3dJbmRleCA9IG51bGw7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5leHBhbmRlZFJvd0luZGV4ID0gaW5kZXg7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHRoaXMucm93U2VsZWN0LmVtaXQocm93KTtcclxuICB9XHJcbn1cclxuIiwiPGRpdiBpZD1cImZ1c2lvbi1kYXRhZ3JpZFwiIGNsYXNzPVwiZnUtZGF0YS1ncmlkLXdyYXBwZXJcIj5cclxuICBAaWYgKGZpbHRlcikge1xyXG4gIDxpbnB1dFxyXG4gICAgY2xhc3M9XCJmdS1kYXRhLWdyaWQtZmlsdGVyXCJcclxuICAgIHR5cGU9XCJ0ZXh0XCJcclxuICAgIFsobmdNb2RlbCldPVwiZmlsdGVyVGV4dFwiXHJcbiAgICAoaW5wdXQpPVwiZmlsdGVyRGF0YSgpXCJcclxuICAgIHBsYWNlaG9sZGVyPVwiU2VhcmNoIGtleXdvcmQuLi5cIlxyXG4gIC8+XHJcbiAgfVxyXG5cclxuICA8ZGl2IGNsYXNzPVwiZnUtZGF0YS1ncmlkLWNvbnRhaW5lclwiPlxyXG4gICAgPGRpdiBjbGFzcz1cImZ1LWRhdGEtZ3JpZC1oZWFkZXJcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cImZ1LWhlYWQtcm93XCIgZ3JpZENvbHVtbnMgW3Jlc3BvbnNpdmVdPVwicmVzcG9uc2l2ZVwiPlxyXG4gICAgICAgIDxuZy1jb250YWluZXJcclxuICAgICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiXHJcbiAgICAgICAgICAgIGhlYWRlclRlbXBsYXRlIHx8IGRlZmF1bHRIZWFkZXJUZW1wbGF0ZTtcclxuICAgICAgICAgICAgY29udGV4dDogeyAkaW1wbGljaXQ6IGRhdGFTb3VyY2UgfVxyXG4gICAgICAgICAgXCJcclxuICAgICAgICAvPlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gICAgPGRpdiBjbGFzcz1cImZ1LWRhdGEtZ3JpZC1ib2R5XCI+XHJcbiAgICAgIDxkaXYgKm5nSWY9XCJkYXRhTG9hZGluZ1wiIGNsYXNzPVwiZnUtZGF0YS1ncmlkLXNwaW5uZXItb3ZlcmxheVwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmdS1zcGlubmVyXCI+PC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgQGZvciAocm93IG9mIHBhZ2luYXRlZERhdGE7IHRyYWNrICRpbmRleCkge1xyXG4gICAgICA8ZGl2XHJcbiAgICAgICAgY2xhc3M9XCJmdS1ib2R5LXJvd1wiXHJcbiAgICAgICAgW25nQ2xhc3NdPVwieyBob3ZlcmFibGUsIHN0cmlwZWQgfVwiXHJcbiAgICAgICAgKGNsaWNrKT1cInJvd0NsaWNrKHJvdywgJGluZGV4KVwiXHJcbiAgICAgID5cclxuICAgICAgICA8bmctY29udGFpbmVyXHJcbiAgICAgICAgICAqbmdUZW1wbGF0ZU91dGxldD1cIlxyXG4gICAgICAgICAgICBib2R5VGVtcGxhdGUgfHwgZGVmYXVsdEJvZHlUZW1wbGF0ZTtcclxuICAgICAgICAgICAgY29udGV4dDogeyAkaW1wbGljaXQ6IHJvdywgaW5kZXg6ICRpbmRleCB9XHJcbiAgICAgICAgICBcIlxyXG4gICAgICAgIC8+XHJcblxyXG4gICAgICAgIEBpZiAoZXhwYW5kYWJsZSAmJiBleHBhbmRlZFJvd0luZGV4ID09PSAkaW5kZXgpIHtcclxuICAgICAgICA8ZGl2IGNsYXNzPVwiZnUtZXhwYW5kZWQtcm93XCIgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxyXG4gICAgICAgICAgPGRpdj5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxyXG4gICAgICAgICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiXHJcbiAgICAgICAgICAgICAgICBleHBhbmRUZW1wbGF0ZTtcclxuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHsgJGltcGxpY2l0OiByb3csIGluZGV4OiAkaW5kZXggfVxyXG4gICAgICAgICAgICAgIFwiXHJcbiAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICB9XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICB9XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuXHJcbiAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImZvb3RlclRlbXBsYXRlXCIgLz5cclxuXHJcbiAgQGlmIChwYWdpbmF0b3IpIHtcclxuICA8bmctY29udGFpbmVyXHJcbiAgICAqbmdUZW1wbGF0ZU91dGxldD1cImRlZmF1bHRQYWdpbmF0b3I7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBzb3J0RGF0YSB9XCJcclxuICAvPlxyXG4gIH1cclxuPC9kaXY+XHJcblxyXG48bmctdGVtcGxhdGUgI2RlZmF1bHRIZWFkZXJUZW1wbGF0ZSBsZXQtZGF0YT5cclxuICBAZm9yIChoZWFkZXIgb2YgZGF0YVswXSB8IGtleXZhbHVlOiBvcmlnaW5hbE9yZGVyOyB0cmFjayAkaW5kZXgpIHtcclxuICA8ZnUtaGVhZC1yb3ctY2VsbCBbY2VsbERlZl09XCIkYW55KGhlYWRlci5rZXkpXCIgW3NvcnRLZXldPVwiJGFueShoZWFkZXIua2V5KVwiIC8+XHJcbiAgfVxyXG48L25nLXRlbXBsYXRlPlxyXG5cclxuPG5nLXRlbXBsYXRlICNkZWZhdWx0Qm9keVRlbXBsYXRlIGxldC1yb3dzPlxyXG4gIEBmb3IgKHJvdyBvZiByb3dzIHwga2V5dmFsdWU6IG9yaWdpbmFsT3JkZXI7IHRyYWNrICRpbmRleCkge1xyXG4gIDxmdS1ib2R5LXJvdy1jZWxsIFtjZWxsVmFsdWVdPVwiJGFueShyb3cudmFsdWUpXCIgLz5cclxuICB9XHJcbjwvbmctdGVtcGxhdGU+XHJcblxyXG48bmctdGVtcGxhdGUgI2RlZmF1bHRQYWdpbmF0b3IgbGV0LWRhdGE+XHJcbiAgPGRpdiBjbGFzcz1cImZ1LWRhdGEtZ3JpZC1wYWdpbmF0b3JcIj5cclxuICAgIDxkaXY+XHJcbiAgICAgIDxzcGFuPkl0ZW1zIHBlciBwYWdlOjwvc3Bhbj5cclxuICAgICAgPHNlbGVjdCAoY2hhbmdlKT1cImNoYW5nZVBhZ2VTaXplKCRldmVudClcIj5cclxuICAgICAgICA8b3B0aW9uXHJcbiAgICAgICAgICAqbmdGb3I9XCJsZXQgc2l6ZSBvZiBwYWdlU2l6ZU9wdGlvbnNcIlxyXG4gICAgICAgICAgW3ZhbHVlXT1cInNpemVcIlxyXG4gICAgICAgICAgW3NlbGVjdGVkXT1cInNpemUgPT09IHBhZ2VTaXplXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICB7eyBzaXplIH19XHJcbiAgICAgICAgPC9vcHRpb24+XHJcbiAgICAgIDwvc2VsZWN0PlxyXG4gICAgPC9kaXY+XHJcbiAgICA8ZGl2PlxyXG4gICAgICB7eyBnZXRQYWdlU3RhcnQoKSB9fSAtIHt7IGdldFBhZ2VFbmQoKSB9fSBvZiB7eyB0b3RhbEl0ZW1Db3VudCgpIH19XHJcbiAgICA8L2Rpdj5cclxuICAgIDxidXR0b24gKGNsaWNrKT1cImdvVG9QYWdlKDEpXCIgW2Rpc2FibGVkXT1cImN1cnJlbnRQYWdlID09PSAxXCI+PDw8L2J1dHRvbj5cclxuICAgIDxidXR0b24gKGNsaWNrKT1cImdvVG9QYWdlKGN1cnJlbnRQYWdlIC0gMSlcIiBbZGlzYWJsZWRdPVwiY3VycmVudFBhZ2UgPT09IDFcIj5cclxuICAgICAgPFxyXG4gICAgPC9idXR0b24+XHJcbiAgICA8YnV0dG9uXHJcbiAgICAgIChjbGljayk9XCJnb1RvUGFnZShjdXJyZW50UGFnZSArIDEpXCJcclxuICAgICAgW2Rpc2FibGVkXT1cImN1cnJlbnRQYWdlID49IHRvdGFsUGFnZXMoKVwiXHJcbiAgICA+XHJcbiAgICAgID5cclxuICAgIDwvYnV0dG9uPlxyXG4gICAgPGJ1dHRvblxyXG4gICAgICAoY2xpY2spPVwiZ29Ub1BhZ2UodG90YWxQYWdlcygpKVwiXHJcbiAgICAgIFtkaXNhYmxlZF09XCJjdXJyZW50UGFnZSA+PSB0b3RhbFBhZ2VzKClcIlxyXG4gICAgPlxyXG4gICAgICA+PlxyXG4gICAgPC9idXR0b24+XHJcbiAgPC9kaXY+XHJcbjwvbmctdGVtcGxhdGU+XHJcbiJdfQ==