@dso-design-system/ui 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/esm2022/lib/alert/alert.component.mjs +54 -0
  2. package/esm2022/lib/badge/badge.component.mjs +22 -0
  3. package/esm2022/lib/breadcrumb/breadcrumb.component.mjs +29 -0
  4. package/esm2022/lib/checkbox/checkbox.component.mjs +82 -0
  5. package/esm2022/lib/datepicker/datepicker.component.mjs +161 -0
  6. package/esm2022/lib/dialog/dialog.component.mjs +25 -0
  7. package/esm2022/lib/directives/truncate.directive.mjs +71 -0
  8. package/esm2022/lib/dropdown-list/dropdown-list.component.mjs +89 -0
  9. package/esm2022/lib/file-upload-items/file-upload-items.component.mjs +65 -0
  10. package/esm2022/lib/file-upload-multiple/file-upload-multiple.component.mjs +232 -0
  11. package/esm2022/lib/file-upload-multiple/upload-item.model.mjs +2 -0
  12. package/esm2022/lib/file-upload-multiple/upload-simulator.service.mjs +76 -0
  13. package/esm2022/lib/file-upload-single/file-upload-single.component.mjs +100 -0
  14. package/esm2022/lib/input-text/input-text.component.mjs +93 -0
  15. package/esm2022/lib/pagination/pagination.component.mjs +115 -0
  16. package/esm2022/lib/progress-bar/progress-bar.component.mjs +25 -0
  17. package/esm2022/lib/radio/radio.component.mjs +41 -0
  18. package/esm2022/lib/select-dropdown/select-dropdown.component.mjs +228 -0
  19. package/esm2022/lib/service/toast.service.mjs +20 -0
  20. package/esm2022/lib/side-navigation-bar/side-navigation-bar.component.mjs +113 -0
  21. package/esm2022/lib/spinner/spinner.component.mjs +60 -0
  22. package/esm2022/lib/table/table.component.mjs +136 -0
  23. package/esm2022/lib/tabs/tab.component.mjs +20 -0
  24. package/esm2022/lib/tabs/tabs.component.mjs +40 -0
  25. package/esm2022/lib/tag/tag.component.mjs +27 -0
  26. package/esm2022/lib/text-area/text-area.component.mjs +74 -0
  27. package/esm2022/lib/toast/toast.component.mjs +36 -0
  28. package/esm2022/lib/tooltip/tooltip.component.mjs +38 -0
  29. package/esm2022/lib/tooltip/tooltip.directive.mjs +105 -0
  30. package/esm2022/lib/top-navigation-bar/top-navigation-bar.component.mjs +24 -0
  31. package/esm2022/public-api.mjs +27 -2
  32. package/fesm2022/dso-design-system-ui.mjs +2056 -3
  33. package/fesm2022/dso-design-system-ui.mjs.map +1 -1
  34. package/lib/alert/alert.component.d.ts +20 -0
  35. package/lib/badge/badge.component.d.ts +8 -0
  36. package/lib/breadcrumb/breadcrumb.component.d.ts +15 -0
  37. package/lib/checkbox/checkbox.component.d.ts +42 -0
  38. package/lib/datepicker/datepicker.component.d.ts +48 -0
  39. package/lib/dialog/dialog.component.d.ts +10 -0
  40. package/lib/directives/truncate.directive.d.ts +23 -0
  41. package/lib/dropdown-list/dropdown-list.component.d.ts +33 -0
  42. package/lib/file-upload-items/file-upload-items.component.d.ts +27 -0
  43. package/lib/file-upload-multiple/file-upload-multiple.component.d.ts +44 -0
  44. package/lib/file-upload-multiple/upload-item.model.d.ts +7 -0
  45. package/lib/file-upload-multiple/upload-simulator.service.d.ts +34 -0
  46. package/lib/file-upload-single/file-upload-single.component.d.ts +28 -0
  47. package/lib/input-text/input-text.component.d.ts +24 -0
  48. package/lib/pagination/pagination.component.d.ts +31 -0
  49. package/lib/progress-bar/progress-bar.component.d.ts +11 -0
  50. package/lib/radio/radio.component.d.ts +14 -0
  51. package/lib/select-dropdown/select-dropdown.component.d.ts +78 -0
  52. package/lib/service/toast.service.d.ts +16 -0
  53. package/lib/side-navigation-bar/side-navigation-bar.component.d.ts +74 -0
  54. package/lib/spinner/spinner.component.d.ts +23 -0
  55. package/lib/table/table.component.d.ts +43 -0
  56. package/lib/tabs/tab.component.d.ts +9 -0
  57. package/lib/tabs/tabs.component.d.ts +15 -0
  58. package/lib/tag/tag.component.d.ts +10 -0
  59. package/lib/text-area/text-area.component.d.ts +21 -0
  60. package/lib/toast/toast.component.d.ts +13 -0
  61. package/lib/tooltip/tooltip.component.d.ts +15 -0
  62. package/lib/tooltip/tooltip.directive.d.ts +19 -0
  63. package/lib/top-navigation-bar/top-navigation-bar.component.d.ts +16 -0
  64. package/package.json +13 -7
  65. package/public-api.d.ts +25 -0
@@ -0,0 +1,100 @@
1
+ import { Component, EventEmitter, Input, Output } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { ButtonComponent } from '../button/button.component';
4
+ import { FileUploadItemComponent } from '../file-upload-items/file-upload-items.component';
5
+ import * as i0 from "@angular/core";
6
+ import * as i1 from "../file-upload-multiple/upload-simulator.service";
7
+ import * as i2 from "@angular/common";
8
+ export class FileUploadSingleComponent {
9
+ sim;
10
+ /** Button label text */
11
+ btnLabel = 'Choose File';
12
+ /** Allowed file types, e.g. ".png,.jpg,.pdf" */
13
+ accept = '';
14
+ /** Emit the selected file to parent component */
15
+ fileSelected = new EventEmitter();
16
+ /** The currently uploaded file shown in the UI */
17
+ item = null;
18
+ constructor(sim) {
19
+ this.sim = sim;
20
+ }
21
+ /** Trigger the hidden file input click */
22
+ onButtonClick(input) {
23
+ input.click();
24
+ }
25
+ /** Handle file selection from input */
26
+ onFileChange(event) {
27
+ const input = event.target;
28
+ if (!input.files || input.files.length === 0)
29
+ return;
30
+ const file = input.files[0];
31
+ // Wrap file in UploadItem structure (same as multi-upload)
32
+ this.item = {
33
+ file,
34
+ progress: 0,
35
+ status: 'queued',
36
+ hideProgressBar: false
37
+ };
38
+ // Emit file to parent
39
+ this.fileSelected.emit(file);
40
+ // Start simulated upload
41
+ this.startUpload();
42
+ // Reset input so user can pick same file again
43
+ input.value = '';
44
+ }
45
+ /** Start upload simulation */
46
+ startUpload() {
47
+ if (!this.item)
48
+ return;
49
+ const item = this.item;
50
+ item.status = 'uploading';
51
+ item.progress = 0;
52
+ this.sim.simulateUpload(item,
53
+ // onProgress callback
54
+ (progress) => {
55
+ item.progress = progress;
56
+ },
57
+ // onComplete callback
58
+ () => {
59
+ item.status = 'completed';
60
+ item.progress = 100;
61
+ setTimeout(() => item.hideProgressBar = true, 300);
62
+ },
63
+ // onError callback
64
+ () => {
65
+ item.status = 'failed';
66
+ item.progress = null;
67
+ setTimeout(() => item.hideProgressBar = true, 300);
68
+ });
69
+ }
70
+ /** Retry failed upload */
71
+ retry() {
72
+ if (!this.item)
73
+ return;
74
+ this.item.status = 'queued';
75
+ this.item.progress = 0;
76
+ this.item.hideProgressBar = false;
77
+ this.startUpload();
78
+ }
79
+ /** Cancel or remove the file from UI */
80
+ clearFile() {
81
+ this.item = null;
82
+ }
83
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FileUploadSingleComponent, deps: [{ token: i1.UploadSimulatorService }], target: i0.ɵɵFactoryTarget.Component });
84
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: FileUploadSingleComponent, isStandalone: true, selector: "dso-file-upload-single", inputs: { btnLabel: "btnLabel", accept: "accept" }, outputs: { fileSelected: "fileSelected" }, ngImport: i0, template: "<div class=\"file-upload-single\">\r\n\r\n <!-- Hidden file input -->\r\n <input\r\n type=\"file\"\r\n #fileInput\r\n [accept]=\"accept\"\r\n (change)=\"onFileChange($event)\"\r\n hidden\r\n />\r\n\r\n <!-- Main button -->\r\n <dso-button\r\n [btnLabel]=\"btnLabel\"\r\n btnType=\"filled\"\r\n (onClick)=\"onButtonClick(fileInput)\"\r\n ></dso-button>\r\n\r\n <!-- Render file info using shared reusable component -->\r\n <dso-file-item\r\n *ngIf=\"item\"\r\n [item]=\"item\"\r\n (cancel)=\"clearFile()\"\r\n (remove)=\"clearFile()\"\r\n (retry)=\"retry()\"\r\n ></dso-file-item>\r\n\r\n</div>\r\n", styles: [".file-upload-single{display:flex;flex-direction:column;gap:8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ButtonComponent, selector: "dso-button", inputs: ["btnLabel", "btnType", "btnSize", "btnIconName", "isDisabled", "isActive"], outputs: ["onClick"] }, { kind: "component", type: FileUploadItemComponent, selector: "dso-file-item", inputs: ["item"], outputs: ["retry", "remove", "cancel"] }] });
85
+ }
86
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FileUploadSingleComponent, decorators: [{
87
+ type: Component,
88
+ args: [{ selector: 'dso-file-upload-single', standalone: true, imports: [
89
+ CommonModule,
90
+ ButtonComponent,
91
+ FileUploadItemComponent
92
+ ], template: "<div class=\"file-upload-single\">\r\n\r\n <!-- Hidden file input -->\r\n <input\r\n type=\"file\"\r\n #fileInput\r\n [accept]=\"accept\"\r\n (change)=\"onFileChange($event)\"\r\n hidden\r\n />\r\n\r\n <!-- Main button -->\r\n <dso-button\r\n [btnLabel]=\"btnLabel\"\r\n btnType=\"filled\"\r\n (onClick)=\"onButtonClick(fileInput)\"\r\n ></dso-button>\r\n\r\n <!-- Render file info using shared reusable component -->\r\n <dso-file-item\r\n *ngIf=\"item\"\r\n [item]=\"item\"\r\n (cancel)=\"clearFile()\"\r\n (remove)=\"clearFile()\"\r\n (retry)=\"retry()\"\r\n ></dso-file-item>\r\n\r\n</div>\r\n", styles: [".file-upload-single{display:flex;flex-direction:column;gap:8px}\n"] }]
93
+ }], ctorParameters: () => [{ type: i1.UploadSimulatorService }], propDecorators: { btnLabel: [{
94
+ type: Input
95
+ }], accept: [{
96
+ type: Input
97
+ }], fileSelected: [{
98
+ type: Output
99
+ }] } });
100
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS11cGxvYWQtc2luZ2xlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3VpL3NyYy9saWIvZmlsZS11cGxvYWQtc2luZ2xlL2ZpbGUtdXBsb2FkLXNpbmdsZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS9zcmMvbGliL2ZpbGUtdXBsb2FkLXNpbmdsZS9maWxlLXVwbG9hZC1zaW5nbGUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRzdELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGtEQUFrRCxDQUFDOzs7O0FBYTNGLE1BQU0sT0FBTyx5QkFBeUI7SUFjaEI7SUFacEIsd0JBQXdCO0lBQ2YsUUFBUSxHQUFXLGFBQWEsQ0FBQztJQUUxQyxnREFBZ0Q7SUFDdkMsTUFBTSxHQUFXLEVBQUUsQ0FBQztJQUU3QixpREFBaUQ7SUFDdkMsWUFBWSxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7SUFFbEQsa0RBQWtEO0lBQ2xELElBQUksR0FBc0IsSUFBSSxDQUFDO0lBRS9CLFlBQW9CLEdBQTJCO1FBQTNCLFFBQUcsR0FBSCxHQUFHLENBQXdCO0lBQUcsQ0FBQztJQUVuRCwwQ0FBMEM7SUFDMUMsYUFBYSxDQUFDLEtBQXVCO1FBQ25DLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNoQixDQUFDO0lBRUQsdUNBQXVDO0lBQ3ZDLFlBQVksQ0FBQyxLQUFZO1FBQ3ZCLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxNQUEwQixDQUFDO1FBQy9DLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUM7WUFBRSxPQUFPO1FBRXJELE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFNUIsMkRBQTJEO1FBQzNELElBQUksQ0FBQyxJQUFJLEdBQUc7WUFDVixJQUFJO1lBQ0osUUFBUSxFQUFFLENBQUM7WUFDWCxNQUFNLEVBQUUsUUFBUTtZQUNoQixlQUFlLEVBQUUsS0FBSztTQUN2QixDQUFDO1FBRUYsc0JBQXNCO1FBQ3RCLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRTdCLHlCQUF5QjtRQUN6QixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFFbkIsK0NBQStDO1FBQy9DLEtBQUssQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDO0lBQ25CLENBQUM7SUFFRCw4QkFBOEI7SUFDOUIsV0FBVztRQUNULElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU87UUFFdkIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztRQUN2QixJQUFJLENBQUMsTUFBTSxHQUFHLFdBQVcsQ0FBQztRQUMxQixJQUFJLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQztRQUVsQixJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FDckIsSUFBSTtRQUVKLHNCQUFzQjtRQUN0QixDQUFDLFFBQVEsRUFBRSxFQUFFO1lBQ1gsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDM0IsQ0FBQztRQUVELHNCQUFzQjtRQUN0QixHQUFHLEVBQUU7WUFDSCxJQUFJLENBQUMsTUFBTSxHQUFHLFdBQVcsQ0FBQztZQUMxQixJQUFJLENBQUMsUUFBUSxHQUFHLEdBQUcsQ0FBQztZQUNwQixVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDckQsQ0FBQztRQUVELG1CQUFtQjtRQUNuQixHQUFHLEVBQUU7WUFDSCxJQUFJLENBQUMsTUFBTSxHQUFHLFFBQVEsQ0FBQztZQUN2QixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztZQUNyQixVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDckQsQ0FBQyxDQUNGLENBQUM7SUFDSixDQUFDO0lBRUQsMEJBQTBCO0lBQzFCLEtBQUs7UUFDSCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUk7WUFBRSxPQUFPO1FBRXZCLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLFFBQVEsQ0FBQztRQUM1QixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUM7UUFDdkIsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO1FBQ2xDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRUQsd0NBQXdDO0lBQ3hDLFNBQVM7UUFDUCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztJQUNuQixDQUFDO3dHQTNGVSx5QkFBeUI7NEZBQXpCLHlCQUF5QixpTENsQnRDLHVvQkE0QkEsMEhEakJJLFlBQVksbUlBQ1osZUFBZSxrS0FDZix1QkFBdUI7OzRGQUtkLHlCQUF5QjtrQkFYckMsU0FBUzsrQkFDRSx3QkFBd0IsY0FDdEIsSUFBSSxXQUNQO3dCQUNQLFlBQVk7d0JBQ1osZUFBZTt3QkFDZix1QkFBdUI7cUJBQ3hCOzJGQU9RLFFBQVE7c0JBQWhCLEtBQUs7Z0JBR0csTUFBTTtzQkFBZCxLQUFLO2dCQUdJLFlBQVk7c0JBQXJCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBCdXR0b25Db21wb25lbnQgfSBmcm9tICcuLi9idXR0b24vYnV0dG9uLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IFVwbG9hZEl0ZW0gfSBmcm9tICcuLi9maWxlLXVwbG9hZC1tdWx0aXBsZS91cGxvYWQtaXRlbS5tb2RlbCc7XHJcbmltcG9ydCB7IFVwbG9hZFNpbXVsYXRvclNlcnZpY2UgfSBmcm9tICcuLi9maWxlLXVwbG9hZC1tdWx0aXBsZS91cGxvYWQtc2ltdWxhdG9yLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBGaWxlVXBsb2FkSXRlbUNvbXBvbmVudCB9IGZyb20gJy4uL2ZpbGUtdXBsb2FkLWl0ZW1zL2ZpbGUtdXBsb2FkLWl0ZW1zLmNvbXBvbmVudCc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2Rzby1maWxlLXVwbG9hZC1zaW5nbGUnLFxyXG4gIHN0YW5kYWxvbmU6IHRydWUsXHJcbiAgaW1wb3J0czogW1xyXG4gICAgQ29tbW9uTW9kdWxlLFxyXG4gICAgQnV0dG9uQ29tcG9uZW50LFxyXG4gICAgRmlsZVVwbG9hZEl0ZW1Db21wb25lbnRcclxuICBdLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9maWxlLXVwbG9hZC1zaW5nbGUuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL2ZpbGUtdXBsb2FkLXNpbmdsZS5jb21wb25lbnQuc2NzcyddXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBGaWxlVXBsb2FkU2luZ2xlQ29tcG9uZW50IHtcclxuXHJcbiAgLyoqIEJ1dHRvbiBsYWJlbCB0ZXh0ICovXHJcbiAgQElucHV0KCkgYnRuTGFiZWw6IHN0cmluZyA9ICdDaG9vc2UgRmlsZSc7XHJcbiAgXHJcbiAgLyoqIEFsbG93ZWQgZmlsZSB0eXBlcywgZS5nLiBcIi5wbmcsLmpwZywucGRmXCIgKi9cclxuICBASW5wdXQoKSBhY2NlcHQ6IHN0cmluZyA9ICcnO1xyXG4gIFxyXG4gIC8qKiBFbWl0IHRoZSBzZWxlY3RlZCBmaWxlIHRvIHBhcmVudCBjb21wb25lbnQgKi9cclxuICBAT3V0cHV0KCkgZmlsZVNlbGVjdGVkID0gbmV3IEV2ZW50RW1pdHRlcjxGaWxlPigpO1xyXG5cclxuICAvKiogVGhlIGN1cnJlbnRseSB1cGxvYWRlZCBmaWxlIHNob3duIGluIHRoZSBVSSAqL1xyXG4gIGl0ZW06IFVwbG9hZEl0ZW0gfCBudWxsID0gbnVsbDtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBzaW06IFVwbG9hZFNpbXVsYXRvclNlcnZpY2UpIHt9XHJcblxyXG4gIC8qKiBUcmlnZ2VyIHRoZSBoaWRkZW4gZmlsZSBpbnB1dCBjbGljayAqL1xyXG4gIG9uQnV0dG9uQ2xpY2soaW5wdXQ6IEhUTUxJbnB1dEVsZW1lbnQpIHtcclxuICAgIGlucHV0LmNsaWNrKCk7XHJcbiAgfVxyXG5cclxuICAvKiogSGFuZGxlIGZpbGUgc2VsZWN0aW9uIGZyb20gaW5wdXQgKi9cclxuICBvbkZpbGVDaGFuZ2UoZXZlbnQ6IEV2ZW50KSB7XHJcbiAgICBjb25zdCBpbnB1dCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50O1xyXG4gICAgaWYgKCFpbnB1dC5maWxlcyB8fCBpbnB1dC5maWxlcy5sZW5ndGggPT09IDApIHJldHVybjtcclxuXHJcbiAgICBjb25zdCBmaWxlID0gaW5wdXQuZmlsZXNbMF07XHJcblxyXG4gICAgLy8gV3JhcCBmaWxlIGluIFVwbG9hZEl0ZW0gc3RydWN0dXJlIChzYW1lIGFzIG11bHRpLXVwbG9hZClcclxuICAgIHRoaXMuaXRlbSA9IHtcclxuICAgICAgZmlsZSxcclxuICAgICAgcHJvZ3Jlc3M6IDAsXHJcbiAgICAgIHN0YXR1czogJ3F1ZXVlZCcsXHJcbiAgICAgIGhpZGVQcm9ncmVzc0JhcjogZmFsc2VcclxuICAgIH07XHJcblxyXG4gICAgLy8gRW1pdCBmaWxlIHRvIHBhcmVudFxyXG4gICAgdGhpcy5maWxlU2VsZWN0ZWQuZW1pdChmaWxlKTtcclxuXHJcbiAgICAvLyBTdGFydCBzaW11bGF0ZWQgdXBsb2FkXHJcbiAgICB0aGlzLnN0YXJ0VXBsb2FkKCk7XHJcblxyXG4gICAgLy8gUmVzZXQgaW5wdXQgc28gdXNlciBjYW4gcGljayBzYW1lIGZpbGUgYWdhaW5cclxuICAgIGlucHV0LnZhbHVlID0gJyc7XHJcbiAgfVxyXG5cclxuICAvKiogU3RhcnQgdXBsb2FkIHNpbXVsYXRpb24gKi9cclxuICBzdGFydFVwbG9hZCgpIHtcclxuICAgIGlmICghdGhpcy5pdGVtKSByZXR1cm47XHJcblxyXG4gICAgY29uc3QgaXRlbSA9IHRoaXMuaXRlbTtcclxuICAgIGl0ZW0uc3RhdHVzID0gJ3VwbG9hZGluZyc7XHJcbiAgICBpdGVtLnByb2dyZXNzID0gMDtcclxuXHJcbiAgICB0aGlzLnNpbS5zaW11bGF0ZVVwbG9hZChcclxuICAgICAgaXRlbSxcclxuXHJcbiAgICAgIC8vIG9uUHJvZ3Jlc3MgY2FsbGJhY2tcclxuICAgICAgKHByb2dyZXNzKSA9PiB7XHJcbiAgICAgICAgaXRlbS5wcm9ncmVzcyA9IHByb2dyZXNzO1xyXG4gICAgICB9LFxyXG5cclxuICAgICAgLy8gb25Db21wbGV0ZSBjYWxsYmFja1xyXG4gICAgICAoKSA9PiB7XHJcbiAgICAgICAgaXRlbS5zdGF0dXMgPSAnY29tcGxldGVkJztcclxuICAgICAgICBpdGVtLnByb2dyZXNzID0gMTAwO1xyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gaXRlbS5oaWRlUHJvZ3Jlc3NCYXIgPSB0cnVlLCAzMDApO1xyXG4gICAgICB9LFxyXG5cclxuICAgICAgLy8gb25FcnJvciBjYWxsYmFja1xyXG4gICAgICAoKSA9PiB7XHJcbiAgICAgICAgaXRlbS5zdGF0dXMgPSAnZmFpbGVkJztcclxuICAgICAgICBpdGVtLnByb2dyZXNzID0gbnVsbDtcclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IGl0ZW0uaGlkZVByb2dyZXNzQmFyID0gdHJ1ZSwgMzAwKTtcclxuICAgICAgfVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIC8qKiBSZXRyeSBmYWlsZWQgdXBsb2FkICovXHJcbiAgcmV0cnkoKSB7XHJcbiAgICBpZiAoIXRoaXMuaXRlbSkgcmV0dXJuO1xyXG5cclxuICAgIHRoaXMuaXRlbS5zdGF0dXMgPSAncXVldWVkJztcclxuICAgIHRoaXMuaXRlbS5wcm9ncmVzcyA9IDA7XHJcbiAgICB0aGlzLml0ZW0uaGlkZVByb2dyZXNzQmFyID0gZmFsc2U7XHJcbiAgICB0aGlzLnN0YXJ0VXBsb2FkKCk7XHJcbiAgfVxyXG5cclxuICAvKiogQ2FuY2VsIG9yIHJlbW92ZSB0aGUgZmlsZSBmcm9tIFVJICovXHJcbiAgY2xlYXJGaWxlKCkge1xyXG4gICAgdGhpcy5pdGVtID0gbnVsbDtcclxuICB9XHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cImZpbGUtdXBsb2FkLXNpbmdsZVwiPlxyXG5cclxuICA8IS0tIEhpZGRlbiBmaWxlIGlucHV0IC0tPlxyXG4gIDxpbnB1dFxyXG4gICAgdHlwZT1cImZpbGVcIlxyXG4gICAgI2ZpbGVJbnB1dFxyXG4gICAgW2FjY2VwdF09XCJhY2NlcHRcIlxyXG4gICAgKGNoYW5nZSk9XCJvbkZpbGVDaGFuZ2UoJGV2ZW50KVwiXHJcbiAgICBoaWRkZW5cclxuICAvPlxyXG5cclxuICA8IS0tIE1haW4gYnV0dG9uIC0tPlxyXG4gIDxkc28tYnV0dG9uXHJcbiAgICBbYnRuTGFiZWxdPVwiYnRuTGFiZWxcIlxyXG4gICAgYnRuVHlwZT1cImZpbGxlZFwiXHJcbiAgICAob25DbGljayk9XCJvbkJ1dHRvbkNsaWNrKGZpbGVJbnB1dClcIlxyXG4gID48L2Rzby1idXR0b24+XHJcblxyXG4gIDwhLS0gUmVuZGVyIGZpbGUgaW5mbyB1c2luZyBzaGFyZWQgcmV1c2FibGUgY29tcG9uZW50IC0tPlxyXG4gIDxkc28tZmlsZS1pdGVtXHJcbiAgICAqbmdJZj1cIml0ZW1cIlxyXG4gICAgW2l0ZW1dPVwiaXRlbVwiXHJcbiAgICAoY2FuY2VsKT1cImNsZWFyRmlsZSgpXCJcclxuICAgIChyZW1vdmUpPVwiY2xlYXJGaWxlKClcIlxyXG4gICAgKHJldHJ5KT1cInJldHJ5KClcIlxyXG4gID48L2Rzby1maWxlLWl0ZW0+XHJcblxyXG48L2Rpdj5cclxuIl19
@@ -0,0 +1,93 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { Component, Input, Output, EventEmitter } from '@angular/core';
3
+ import { FormsModule } from '@angular/forms';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@angular/common";
6
+ import * as i2 from "@angular/forms";
7
+ export class TextInputComponent {
8
+ // -------------------------------
9
+ // INPUT PROPERTIES
10
+ // -------------------------------
11
+ inputLabel = ''; // Optional label displayed above input
12
+ value = ''; // Two-way bound input value
13
+ placeholder = 'Input value'; // Placeholder text
14
+ type = ''; // Input type (text, email, etc.)
15
+ isDisabled = false; // Disable the input
16
+ helperText = ''; // Optional helper text below input
17
+ errorText = ''; // Optional error message
18
+ enableValidation = true; // Flag to enable/disable validation
19
+ maxLength = 80; // Maximum characters allowed
20
+ // -------------------------------
21
+ // OUTPUT EVENTS
22
+ // -------------------------------
23
+ valueChange = new EventEmitter(); // Emit input changes to parent
24
+ // -------------------------------
25
+ // INTERNAL STATE
26
+ // -------------------------------
27
+ isTouched = false; // Tracks if user has interacted with input
28
+ isInvalid = false; // True if validation fails
29
+ charCount = 0; // Tracks current character count
30
+ isExceeded = false; // True if charCount exceeds maxLength
31
+ // -------------------------------
32
+ // EVENT HANDLERS
33
+ // -------------------------------
34
+ onInputChange(event) {
35
+ this.value = event.target.value; // Update value
36
+ const inputValue = event.target.value;
37
+ const charCount = inputValue.length;
38
+ // Track if max length exceeded
39
+ this.isExceeded = charCount > this.maxLength;
40
+ this.isTouched = true; // Mark input as touched
41
+ this.valueChange.emit(this.value); // Notify parent
42
+ this.checkValidity(); // Validate input
43
+ }
44
+ onBlur() {
45
+ this.isTouched = true; // Input lost focus → mark as touched
46
+ this.checkValidity(); // Validate when blurred
47
+ }
48
+ // -------------------------------
49
+ // HELPER METHODS
50
+ // -------------------------------
51
+ getCharCountStyle() {
52
+ const charCount = this.value.length;
53
+ if (this.isExceeded) {
54
+ return 'char-count-error'; // Apply error style if limit exceeded
55
+ }
56
+ // Optional: style differently if more than 50% of maxLength used
57
+ if (charCount > this.maxLength / 2) {
58
+ return '';
59
+ }
60
+ return ''; // Default style
61
+ }
62
+ checkValidity() {
63
+ // If touched and value is empty, mark as invalid
64
+ this.isInvalid = this.isTouched && !this.value.trim();
65
+ }
66
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TextInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
67
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: TextInputComponent, isStandalone: true, selector: "dso-input-text", inputs: { inputLabel: "inputLabel", value: "value", placeholder: "placeholder", type: "type", isDisabled: "isDisabled", helperText: "helperText", errorText: "errorText", enableValidation: "enableValidation", maxLength: "maxLength" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"input-container\">\r\n <!-- Optional label -->\r\n <div class=\"text-wrapper\">\r\n <!-- Optional label -->\r\n <label *ngIf=\"inputLabel\">\r\n {{ inputLabel }}\r\n </label> \r\n <!-- Character count inside the container -->\r\n <div class=\"char-count\" [ngClass]=\"getCharCountStyle()\" *ngIf=\"maxLength\">\r\n <span>\r\n {{ value.length }} \r\n </span>\r\n / {{ maxLength }}\r\n </div>\r\n </div> \r\n <input\r\n [type]=\"type\" \r\n [placeholder]=\"placeholder\"\r\n [(ngModel)]=\"value\"\r\n (input)=\"onInputChange($event)\" \r\n (blur)=\"onBlur()\"\r\n [disabled]=\"isDisabled\"\r\n [class.disabled]=\"isDisabled\"\r\n [class.invalid]=\"(isInvalid && isTouched && enableValidation) || isExceeded\" \r\n />\r\n\r\n <!-- Helper Text \r\n This condition checks if the helper text should be displayed:\r\n - If the character limit is **not exceeded** and validation is **not enabled**, show the helper text.\r\n - If validation **is enabled**, show the helper text only if the input is **not invalid** and `helperText` is provided.\r\n - If the character limit is exceeded, the helper text will be replaced with an error message. -->\r\n <div *ngIf=\"!isExceeded && !enableValidation || ((!isInvalid && helperText) && !isExceeded)\" class=\"helper-text\">\r\n {{ helperText }}\r\n </div>\r\n\r\n <!-- Specified Error Text -->\r\n <div *ngIf=\"isInvalid && isTouched && enableValidation\" class=\"error-message\">\r\n {{ errorText }}\r\n </div>\r\n\r\n <!-- Error message if character limit exceeded -->\r\n <div *ngIf=\"isExceeded\" class=\"error-message\">\r\n Character limit exceeded.\r\n </div>\r\n</div>\r\n\r\n", styles: [":host{display:inline-block}.input-container{width:500px;display:flex;flex-direction:column;gap:8px}.text-wrapper{display:flex;justify-content:space-between}input{width:100%;height:48px;padding:12px 8px;font-size:16px;border:1px solid #ccc;border-radius:4px}input:hover{border:1px solid #071d35}input:focus{border-color:#007bff;outline:none}input.invalid{border-color:red}.error-message{color:red;font-size:16px}input.disabled{cursor:not-allowed;background-color:#f0f0f0;border:1px solid #ddd;color:#000}.helper-text{font-size:16px;color:#6c757d}.error-message{font-size:16px;color:red}.char-count{font-size:12px;color:#666;align-self:flex-end}.char-count span,.char-count-error{font-size:12px;color:#666}.char-count-error span{font-size:12px;color:red}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
68
+ }
69
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TextInputComponent, decorators: [{
70
+ type: Component,
71
+ args: [{ selector: 'dso-input-text', standalone: true, imports: [CommonModule, FormsModule], template: "<div class=\"input-container\">\r\n <!-- Optional label -->\r\n <div class=\"text-wrapper\">\r\n <!-- Optional label -->\r\n <label *ngIf=\"inputLabel\">\r\n {{ inputLabel }}\r\n </label> \r\n <!-- Character count inside the container -->\r\n <div class=\"char-count\" [ngClass]=\"getCharCountStyle()\" *ngIf=\"maxLength\">\r\n <span>\r\n {{ value.length }} \r\n </span>\r\n / {{ maxLength }}\r\n </div>\r\n </div> \r\n <input\r\n [type]=\"type\" \r\n [placeholder]=\"placeholder\"\r\n [(ngModel)]=\"value\"\r\n (input)=\"onInputChange($event)\" \r\n (blur)=\"onBlur()\"\r\n [disabled]=\"isDisabled\"\r\n [class.disabled]=\"isDisabled\"\r\n [class.invalid]=\"(isInvalid && isTouched && enableValidation) || isExceeded\" \r\n />\r\n\r\n <!-- Helper Text \r\n This condition checks if the helper text should be displayed:\r\n - If the character limit is **not exceeded** and validation is **not enabled**, show the helper text.\r\n - If validation **is enabled**, show the helper text only if the input is **not invalid** and `helperText` is provided.\r\n - If the character limit is exceeded, the helper text will be replaced with an error message. -->\r\n <div *ngIf=\"!isExceeded && !enableValidation || ((!isInvalid && helperText) && !isExceeded)\" class=\"helper-text\">\r\n {{ helperText }}\r\n </div>\r\n\r\n <!-- Specified Error Text -->\r\n <div *ngIf=\"isInvalid && isTouched && enableValidation\" class=\"error-message\">\r\n {{ errorText }}\r\n </div>\r\n\r\n <!-- Error message if character limit exceeded -->\r\n <div *ngIf=\"isExceeded\" class=\"error-message\">\r\n Character limit exceeded.\r\n </div>\r\n</div>\r\n\r\n", styles: [":host{display:inline-block}.input-container{width:500px;display:flex;flex-direction:column;gap:8px}.text-wrapper{display:flex;justify-content:space-between}input{width:100%;height:48px;padding:12px 8px;font-size:16px;border:1px solid #ccc;border-radius:4px}input:hover{border:1px solid #071d35}input:focus{border-color:#007bff;outline:none}input.invalid{border-color:red}.error-message{color:red;font-size:16px}input.disabled{cursor:not-allowed;background-color:#f0f0f0;border:1px solid #ddd;color:#000}.helper-text{font-size:16px;color:#6c757d}.error-message{font-size:16px;color:red}.char-count{font-size:12px;color:#666;align-self:flex-end}.char-count span,.char-count-error{font-size:12px;color:#666}.char-count-error span{font-size:12px;color:red}\n"] }]
72
+ }], propDecorators: { inputLabel: [{
73
+ type: Input
74
+ }], value: [{
75
+ type: Input
76
+ }], placeholder: [{
77
+ type: Input
78
+ }], type: [{
79
+ type: Input
80
+ }], isDisabled: [{
81
+ type: Input
82
+ }], helperText: [{
83
+ type: Input
84
+ }], errorText: [{
85
+ type: Input
86
+ }], enableValidation: [{
87
+ type: Input
88
+ }], maxLength: [{
89
+ type: Input
90
+ }], valueChange: [{
91
+ type: Output
92
+ }] } });
93
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQtdGV4dC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS9zcmMvbGliL2lucHV0LXRleHQvaW5wdXQtdGV4dC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS9zcmMvbGliL2lucHV0LXRleHQvaW5wdXQtdGV4dC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2RSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7QUFTN0MsTUFBTSxPQUFPLGtCQUFrQjtJQUM3QixrQ0FBa0M7SUFDbEMsbUJBQW1CO0lBQ25CLGtDQUFrQztJQUN6QixVQUFVLEdBQVcsRUFBRSxDQUFDLENBQUMsdUNBQXVDO0lBQ2hFLEtBQUssR0FBVyxFQUFFLENBQUMsQ0FBTSw0QkFBNEI7SUFDckQsV0FBVyxHQUFXLGFBQWEsQ0FBQyxDQUFDLG1CQUFtQjtJQUN4RCxJQUFJLEdBQVcsRUFBRSxDQUFDLENBQU8saUNBQWlDO0lBQzFELFVBQVUsR0FBWSxLQUFLLENBQUMsQ0FBQyxvQkFBb0I7SUFDakQsVUFBVSxHQUFXLEVBQUUsQ0FBQyxDQUFLLG1DQUFtQztJQUNoRSxTQUFTLEdBQVcsRUFBRSxDQUFDLENBQU0seUJBQXlCO0lBQ3RELGdCQUFnQixHQUFZLElBQUksQ0FBQyxDQUFDLG9DQUFvQztJQUN0RSxTQUFTLEdBQVcsRUFBRSxDQUFDLENBQU0sNkJBQTZCO0lBRW5FLGtDQUFrQztJQUNsQyxnQkFBZ0I7SUFDaEIsa0NBQWtDO0lBQ3hCLFdBQVcsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDLENBQUMsK0JBQStCO0lBRW5GLGtDQUFrQztJQUNsQyxpQkFBaUI7SUFDakIsa0NBQWtDO0lBQ2xDLFNBQVMsR0FBWSxLQUFLLENBQUMsQ0FBRSwyQ0FBMkM7SUFDeEUsU0FBUyxHQUFZLEtBQUssQ0FBQyxDQUFFLDJCQUEyQjtJQUN4RCxTQUFTLEdBQVcsQ0FBQyxDQUFDLENBQU8saUNBQWlDO0lBQzlELFVBQVUsR0FBWSxLQUFLLENBQUMsQ0FBQyxzQ0FBc0M7SUFFbkUsa0NBQWtDO0lBQ2xDLGlCQUFpQjtJQUNqQixrQ0FBa0M7SUFDbEMsYUFBYSxDQUFDLEtBQVU7UUFDdEIsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLGVBQWU7UUFDaEQsTUFBTSxVQUFVLEdBQUksS0FBSyxDQUFDLE1BQThCLENBQUMsS0FBSyxDQUFDO1FBQy9ELE1BQU0sU0FBUyxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUM7UUFFcEMsK0JBQStCO1FBQy9CLElBQUksQ0FBQyxVQUFVLEdBQUcsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7UUFFN0MsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsQ0FBWSx3QkFBd0I7UUFDMUQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsZ0JBQWdCO1FBQ25ELElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFhLGlCQUFpQjtJQUNyRCxDQUFDO0lBRUQsTUFBTTtRQUNKLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLENBQUUscUNBQXFDO1FBQzdELElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFHLHdCQUF3QjtJQUNsRCxDQUFDO0lBRUQsa0NBQWtDO0lBQ2xDLGlCQUFpQjtJQUNqQixrQ0FBa0M7SUFDbEMsaUJBQWlCO1FBQ2YsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFFcEMsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDcEIsT0FBTyxrQkFBa0IsQ0FBQyxDQUFDLHNDQUFzQztRQUNuRSxDQUFDO1FBRUQsaUVBQWlFO1FBQ2pFLElBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDbkMsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDO1FBRUQsT0FBTyxFQUFFLENBQUMsQ0FBQyxnQkFBZ0I7SUFDN0IsQ0FBQztJQUVELGFBQWE7UUFDWCxpREFBaUQ7UUFDakQsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUN4RCxDQUFDO3dHQXJFVSxrQkFBa0I7NEZBQWxCLGtCQUFrQiw2VkNYL0IsNHpEQThDQSwyeUJEckNhLFlBQVksZ09BQUUsV0FBVzs7NEZBRXpCLGtCQUFrQjtrQkFQOUIsU0FBUzsrQkFDRSxnQkFBZ0IsY0FDZCxJQUFJLFdBR1AsQ0FBRSxZQUFZLEVBQUUsV0FBVyxDQUFFOzhCQU03QixVQUFVO3NCQUFsQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFLSSxXQUFXO3NCQUFwQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2Rzby1pbnB1dC10ZXh0JyxcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9pbnB1dC10ZXh0LmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9pbnB1dC10ZXh0LmNvbXBvbmVudC5zY3NzJ10sXHJcbiAgaW1wb3J0czogWyBDb21tb25Nb2R1bGUsIEZvcm1zTW9kdWxlIF1cclxufSlcclxuZXhwb3J0IGNsYXNzIFRleHRJbnB1dENvbXBvbmVudCB7XHJcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gIC8vIElOUFVUIFBST1BFUlRJRVNcclxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgQElucHV0KCkgaW5wdXRMYWJlbDogc3RyaW5nID0gJyc7IC8vIE9wdGlvbmFsIGxhYmVsIGRpc3BsYXllZCBhYm92ZSBpbnB1dFxyXG4gIEBJbnB1dCgpIHZhbHVlOiBzdHJpbmcgPSAnJzsgICAgICAvLyBUd28td2F5IGJvdW5kIGlucHV0IHZhbHVlXHJcbiAgQElucHV0KCkgcGxhY2Vob2xkZXI6IHN0cmluZyA9ICdJbnB1dCB2YWx1ZSc7IC8vIFBsYWNlaG9sZGVyIHRleHRcclxuICBASW5wdXQoKSB0eXBlOiBzdHJpbmcgPSAnJzsgICAgICAgLy8gSW5wdXQgdHlwZSAodGV4dCwgZW1haWwsIGV0Yy4pXHJcbiAgQElucHV0KCkgaXNEaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlOyAvLyBEaXNhYmxlIHRoZSBpbnB1dFxyXG4gIEBJbnB1dCgpIGhlbHBlclRleHQ6IHN0cmluZyA9ICcnOyAgICAgLy8gT3B0aW9uYWwgaGVscGVyIHRleHQgYmVsb3cgaW5wdXRcclxuICBASW5wdXQoKSBlcnJvclRleHQ6IHN0cmluZyA9ICcnOyAgICAgIC8vIE9wdGlvbmFsIGVycm9yIG1lc3NhZ2VcclxuICBASW5wdXQoKSBlbmFibGVWYWxpZGF0aW9uOiBib29sZWFuID0gdHJ1ZTsgLy8gRmxhZyB0byBlbmFibGUvZGlzYWJsZSB2YWxpZGF0aW9uXHJcbiAgQElucHV0KCkgbWF4TGVuZ3RoOiBudW1iZXIgPSA4MDsgICAgICAvLyBNYXhpbXVtIGNoYXJhY3RlcnMgYWxsb3dlZFxyXG5cclxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgLy8gT1VUUFVUIEVWRU5UU1xyXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuICBAT3V0cHV0KCkgdmFsdWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTsgLy8gRW1pdCBpbnB1dCBjaGFuZ2VzIHRvIHBhcmVudFxyXG5cclxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgLy8gSU5URVJOQUwgU1RBVEVcclxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgaXNUb3VjaGVkOiBib29sZWFuID0gZmFsc2U7ICAvLyBUcmFja3MgaWYgdXNlciBoYXMgaW50ZXJhY3RlZCB3aXRoIGlucHV0XHJcbiAgaXNJbnZhbGlkOiBib29sZWFuID0gZmFsc2U7ICAvLyBUcnVlIGlmIHZhbGlkYXRpb24gZmFpbHNcclxuICBjaGFyQ291bnQ6IG51bWJlciA9IDA7ICAgICAgIC8vIFRyYWNrcyBjdXJyZW50IGNoYXJhY3RlciBjb3VudFxyXG4gIGlzRXhjZWVkZWQ6IGJvb2xlYW4gPSBmYWxzZTsgLy8gVHJ1ZSBpZiBjaGFyQ291bnQgZXhjZWVkcyBtYXhMZW5ndGhcclxuXHJcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gIC8vIEVWRU5UIEhBTkRMRVJTXHJcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gIG9uSW5wdXRDaGFuZ2UoZXZlbnQ6IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy52YWx1ZSA9IGV2ZW50LnRhcmdldC52YWx1ZTsgLy8gVXBkYXRlIHZhbHVlXHJcbiAgICBjb25zdCBpbnB1dFZhbHVlID0gKGV2ZW50LnRhcmdldCBhcyBIVE1MVGV4dEFyZWFFbGVtZW50KS52YWx1ZTtcclxuICAgIGNvbnN0IGNoYXJDb3VudCA9IGlucHV0VmFsdWUubGVuZ3RoO1xyXG5cclxuICAgIC8vIFRyYWNrIGlmIG1heCBsZW5ndGggZXhjZWVkZWRcclxuICAgIHRoaXMuaXNFeGNlZWRlZCA9IGNoYXJDb3VudCA+IHRoaXMubWF4TGVuZ3RoO1xyXG5cclxuICAgIHRoaXMuaXNUb3VjaGVkID0gdHJ1ZTsgICAgICAgICAgICAvLyBNYXJrIGlucHV0IGFzIHRvdWNoZWRcclxuICAgIHRoaXMudmFsdWVDaGFuZ2UuZW1pdCh0aGlzLnZhbHVlKTsgLy8gTm90aWZ5IHBhcmVudFxyXG4gICAgdGhpcy5jaGVja1ZhbGlkaXR5KCk7ICAgICAgICAgICAgIC8vIFZhbGlkYXRlIGlucHV0XHJcbiAgfVxyXG5cclxuICBvbkJsdXIoKTogdm9pZCB7XHJcbiAgICB0aGlzLmlzVG91Y2hlZCA9IHRydWU7ICAvLyBJbnB1dCBsb3N0IGZvY3VzIOKGkiBtYXJrIGFzIHRvdWNoZWRcclxuICAgIHRoaXMuY2hlY2tWYWxpZGl0eSgpOyAgIC8vIFZhbGlkYXRlIHdoZW4gYmx1cnJlZFxyXG4gIH1cclxuXHJcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gIC8vIEhFTFBFUiBNRVRIT0RTXHJcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gIGdldENoYXJDb3VudFN0eWxlKCkge1xyXG4gICAgY29uc3QgY2hhckNvdW50ID0gdGhpcy52YWx1ZS5sZW5ndGg7XHJcblxyXG4gICAgaWYgKHRoaXMuaXNFeGNlZWRlZCkge1xyXG4gICAgICByZXR1cm4gJ2NoYXItY291bnQtZXJyb3InOyAvLyBBcHBseSBlcnJvciBzdHlsZSBpZiBsaW1pdCBleGNlZWRlZFxyXG4gICAgfVxyXG5cclxuICAgIC8vIE9wdGlvbmFsOiBzdHlsZSBkaWZmZXJlbnRseSBpZiBtb3JlIHRoYW4gNTAlIG9mIG1heExlbmd0aCB1c2VkXHJcbiAgICBpZiAoY2hhckNvdW50ID4gdGhpcy5tYXhMZW5ndGggLyAyKSB7XHJcbiAgICAgIHJldHVybiAnJztcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gJyc7IC8vIERlZmF1bHQgc3R5bGVcclxuICB9XHJcblxyXG4gIGNoZWNrVmFsaWRpdHkoKTogdm9pZCB7XHJcbiAgICAvLyBJZiB0b3VjaGVkIGFuZCB2YWx1ZSBpcyBlbXB0eSwgbWFyayBhcyBpbnZhbGlkXHJcbiAgICB0aGlzLmlzSW52YWxpZCA9IHRoaXMuaXNUb3VjaGVkICYmICF0aGlzLnZhbHVlLnRyaW0oKTtcclxuICB9XHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cImlucHV0LWNvbnRhaW5lclwiPlxyXG4gIDwhLS0gT3B0aW9uYWwgbGFiZWwgLS0+XHJcbiAgICA8ZGl2IGNsYXNzPVwidGV4dC13cmFwcGVyXCI+XHJcbiAgICAgICAgPCEtLSBPcHRpb25hbCBsYWJlbCAtLT5cclxuICAgICAgICA8bGFiZWwgKm5nSWY9XCJpbnB1dExhYmVsXCI+XHJcbiAgICAgICAgICAgIHt7IGlucHV0TGFiZWwgfX1cclxuICAgICAgICA8L2xhYmVsPiAgXHJcbiAgICAgICAgPCEtLSBDaGFyYWN0ZXIgY291bnQgaW5zaWRlIHRoZSBjb250YWluZXIgLS0+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImNoYXItY291bnRcIiBbbmdDbGFzc109XCJnZXRDaGFyQ291bnRTdHlsZSgpXCIgKm5nSWY9XCJtYXhMZW5ndGhcIj5cclxuICAgICAgICAgICAgPHNwYW4+XHJcbiAgICAgICAgICAgICAgICB7eyB2YWx1ZS5sZW5ndGggfX0gIFxyXG4gICAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgICAgIC8ge3sgbWF4TGVuZ3RoIH19XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj4gXHJcbiAgPGlucHV0XHJcbiAgICBbdHlwZV09XCJ0eXBlXCIgXHJcbiAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJcIlxyXG4gICAgWyhuZ01vZGVsKV09XCJ2YWx1ZVwiXHJcbiAgICAoaW5wdXQpPVwib25JbnB1dENoYW5nZSgkZXZlbnQpXCIgXHJcbiAgICAoYmx1cik9XCJvbkJsdXIoKVwiXHJcbiAgICBbZGlzYWJsZWRdPVwiaXNEaXNhYmxlZFwiXHJcbiAgICBbY2xhc3MuZGlzYWJsZWRdPVwiaXNEaXNhYmxlZFwiXHJcbiAgICBbY2xhc3MuaW52YWxpZF09XCIoaXNJbnZhbGlkICYmIGlzVG91Y2hlZCAmJiBlbmFibGVWYWxpZGF0aW9uKSB8fCBpc0V4Y2VlZGVkXCIgXHJcbiAgICAvPlxyXG5cclxuICAgIDwhLS0gSGVscGVyIFRleHQgXHJcbiAgICAgICAgVGhpcyBjb25kaXRpb24gY2hlY2tzIGlmIHRoZSBoZWxwZXIgdGV4dCBzaG91bGQgYmUgZGlzcGxheWVkOlxyXG4gICAgICAgICAgLSBJZiB0aGUgY2hhcmFjdGVyIGxpbWl0IGlzICoqbm90IGV4Y2VlZGVkKiogYW5kIHZhbGlkYXRpb24gaXMgKipub3QgZW5hYmxlZCoqLCBzaG93IHRoZSBoZWxwZXIgdGV4dC5cclxuICAgICAgICAgIC0gSWYgdmFsaWRhdGlvbiAqKmlzIGVuYWJsZWQqKiwgc2hvdyB0aGUgaGVscGVyIHRleHQgb25seSBpZiB0aGUgaW5wdXQgaXMgKipub3QgaW52YWxpZCoqIGFuZCBgaGVscGVyVGV4dGAgaXMgcHJvdmlkZWQuXHJcbiAgICAgICAgICAtIElmIHRoZSBjaGFyYWN0ZXIgbGltaXQgaXMgZXhjZWVkZWQsIHRoZSBoZWxwZXIgdGV4dCB3aWxsIGJlIHJlcGxhY2VkIHdpdGggYW4gZXJyb3IgbWVzc2FnZS4gLS0+XHJcbiAgICA8ZGl2ICpuZ0lmPVwiIWlzRXhjZWVkZWQgJiYgIWVuYWJsZVZhbGlkYXRpb24gfHwgKCghaXNJbnZhbGlkICYmIGhlbHBlclRleHQpICYmICFpc0V4Y2VlZGVkKVwiIGNsYXNzPVwiaGVscGVyLXRleHRcIj5cclxuICAgICAge3sgaGVscGVyVGV4dCB9fVxyXG4gICAgPC9kaXY+XHJcblxyXG4gICAgPCEtLSBTcGVjaWZpZWQgRXJyb3IgVGV4dCAtLT5cclxuICAgIDxkaXYgKm5nSWY9XCJpc0ludmFsaWQgJiYgaXNUb3VjaGVkICYmIGVuYWJsZVZhbGlkYXRpb25cIiBjbGFzcz1cImVycm9yLW1lc3NhZ2VcIj5cclxuICAgICAge3sgZXJyb3JUZXh0IH19XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8IS0tIEVycm9yIG1lc3NhZ2UgaWYgY2hhcmFjdGVyIGxpbWl0IGV4Y2VlZGVkIC0tPlxyXG4gICAgPGRpdiAqbmdJZj1cImlzRXhjZWVkZWRcIiBjbGFzcz1cImVycm9yLW1lc3NhZ2VcIj5cclxuICAgICAgICBDaGFyYWN0ZXIgbGltaXQgZXhjZWVkZWQuXHJcbiAgICA8L2Rpdj5cclxuPC9kaXY+XHJcblxyXG4iXX0=
@@ -0,0 +1,115 @@
1
+ import { Component, Input, Output, EventEmitter } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { FormsModule } from '@angular/forms';
4
+ import { ButtonComponent } from '../button/button.component';
5
+ import { DropdownListComponent } from '../dropdown-list/dropdown-list.component';
6
+ import * as i0 from "@angular/core";
7
+ import * as i1 from "@angular/common";
8
+ import * as i2 from "@angular/forms";
9
+ export class PaginationComponent {
10
+ /* =======================
11
+ Inputs (controlled state)
12
+ ======================= */
13
+ page = 1;
14
+ pageSize = 10;
15
+ totalItems = 0;
16
+ pageSizes = [10, 20, 50, 100];
17
+ /* =======================
18
+ Outputs (user intent)
19
+ ======================= */
20
+ pageChange = new EventEmitter();
21
+ pageSizeChange = new EventEmitter();
22
+ /* =======================
23
+ Internal UI state
24
+ ======================= */
25
+ pageNumbers = [];
26
+ jumpPageNumber = null;
27
+ pageSizeOptions = [];
28
+ /* =======================
29
+ Lifecycle
30
+ ======================= */
31
+ ngOnChanges() {
32
+ this.buildPageSizeOptions();
33
+ this.generatePageNumbers();
34
+ }
35
+ /* =======================
36
+ Derived values
37
+ ======================= */
38
+ get totalPages() {
39
+ return Math.max(Math.ceil(this.totalItems / this.pageSize), 1);
40
+ }
41
+ get startItem() {
42
+ return this.totalItems === 0 ? 0 : (this.page - 1) * this.pageSize + 1;
43
+ }
44
+ get endItem() {
45
+ return Math.min(this.page * this.pageSize, this.totalItems);
46
+ }
47
+ /* =======================
48
+ UI helpers
49
+ ======================= */
50
+ buildPageSizeOptions() {
51
+ this.pageSizeOptions = this.pageSizes.map(size => ({
52
+ label: `${size} per page`,
53
+ value: size
54
+ }));
55
+ }
56
+ generatePageNumbers() {
57
+ const total = this.totalPages;
58
+ let start = Math.max(this.page - 2, 1);
59
+ let end = Math.min(start + 4, total);
60
+ start = Math.max(end - 4, 1);
61
+ this.pageNumbers = [];
62
+ for (let i = start; i <= end; i++) {
63
+ this.pageNumbers.push(i);
64
+ }
65
+ }
66
+ /* =======================
67
+ Navigation (emit only)
68
+ ======================= */
69
+ goToPage(page) {
70
+ if (page >= 1 && page <= this.totalPages && page !== this.page) {
71
+ this.pageChange.emit(page);
72
+ }
73
+ }
74
+ goFirst() {
75
+ this.goToPage(1);
76
+ }
77
+ goPrevious() {
78
+ this.goToPage(this.page - 1);
79
+ }
80
+ goNext() {
81
+ this.goToPage(this.page + 1);
82
+ }
83
+ goLast() {
84
+ this.goToPage(this.totalPages);
85
+ }
86
+ onPageSizeChange(newSize) {
87
+ this.pageSizeChange.emit(newSize);
88
+ }
89
+ jumpToPage() {
90
+ if (!this.jumpPageNumber)
91
+ return;
92
+ const page = Math.max(1, Math.min(this.jumpPageNumber, this.totalPages));
93
+ this.pageChange.emit(page);
94
+ this.jumpPageNumber = null;
95
+ }
96
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
97
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: PaginationComponent, isStandalone: true, selector: "dso-pagination", inputs: { page: "page", pageSize: "pageSize", totalItems: "totalItems", pageSizes: "pageSizes" }, outputs: { pageChange: "pageChange", pageSizeChange: "pageSizeChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"pagination-container\">\r\n\r\n <!-- First / Previous -->\r\n <dso-button\r\n btnLabel=\"\u00AB\"\r\n btnType=\"outlined\"\r\n [isDisabled]=\"page === 1\"\r\n (onClick)=\"goFirst()\">\r\n </dso-button>\r\n\r\n <dso-button\r\n btnLabel=\"\u2039\"\r\n btnType=\"outlined\"\r\n [isDisabled]=\"page === 1\"\r\n (onClick)=\"goPrevious()\">\r\n </dso-button>\r\n\r\n <!-- Page numbers -->\r\n <div class=\"page-buttons\">\r\n <ng-container *ngFor=\"let p of pageNumbers\">\r\n <dso-button\r\n [btnLabel]=\"p.toString()\"\r\n btnType=\"ghost\"\r\n btnSize=\"mdBtn\"\r\n [isDisabled]=\"page === p\"\r\n [isActive]=\"page === p\"\r\n (onClick)=\"goToPage(p)\">\r\n </dso-button>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Next / Last -->\r\n <dso-button\r\n btnLabel=\"\u203A\"\r\n btnType=\"outlined\"\r\n [isDisabled]=\"page === totalPages\"\r\n (onClick)=\"goNext()\">\r\n </dso-button>\r\n\r\n <dso-button\r\n btnLabel=\"\u00BB\"\r\n btnType=\"outlined\"\r\n [isDisabled]=\"page === totalPages\"\r\n (onClick)=\"goLast()\">\r\n </dso-button>\r\n\r\n <!-- Page size -->\r\n <dso-dropdown-list\r\n [options]=\"pageSizeOptions\"\r\n [value]=\"pageSize\"\r\n (selectionChange)=\"onPageSizeChange($event)\">\r\n </dso-dropdown-list>\r\n\r\n <!-- Range info -->\r\n <span class=\"range-info\">\r\n Showing {{ startItem }}\u2013{{ endItem }} of {{ totalItems }} results\r\n </span>\r\n\r\n <!-- Jump to page -->\r\n <div class=\"jump-to-page\">\r\n <input\r\n type=\"number\"\r\n min=\"1\"\r\n [(ngModel)]=\"jumpPageNumber\"\r\n (keydown.enter)=\"jumpToPage()\" />\r\n\r\n <dso-button\r\n btnLabel=\"Go\"\r\n btnType=\"ghost\"\r\n btnSize=\"mdBtn\"\r\n [isDisabled]=\"!jumpPageNumber\"\r\n (onClick)=\"jumpToPage()\">\r\n </dso-button>\r\n </div>\r\n\r\n</div>\r\n", styles: [".pagination-container{display:flex;align-items:center;gap:8px;font-size:14px}.range-info{margin-right:12px}button{padding:6px 10px;border-radius:4px;border:1px solid #ccc;background:#f0f0f0;cursor:pointer}button:disabled{opacity:.4;cursor:not-allowed}button.page-number.active{background-color:#007bff;color:#fff;font-weight:700}.page-buttons{display:flex;gap:4px}.page-buttons dso-button{flex:0 0 44px;text-align:center}.jump-to-page{display:flex;align-items:center;gap:4px}.jump-to-page input{width:48px;padding:6px 8px;border-radius:4px;border:1px solid #ccc;text-align:center}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "dso-button", inputs: ["btnLabel", "btnType", "btnSize", "btnIconName", "isDisabled", "isActive"], outputs: ["onClick"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: DropdownListComponent, selector: "dso-dropdown-list", inputs: ["options", "placeholder", "value", "disabled"], outputs: ["selectionChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
98
+ }
99
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PaginationComponent, decorators: [{
100
+ type: Component,
101
+ args: [{ selector: 'dso-pagination', standalone: true, imports: [ButtonComponent, CommonModule, DropdownListComponent, FormsModule], template: "<div class=\"pagination-container\">\r\n\r\n <!-- First / Previous -->\r\n <dso-button\r\n btnLabel=\"\u00AB\"\r\n btnType=\"outlined\"\r\n [isDisabled]=\"page === 1\"\r\n (onClick)=\"goFirst()\">\r\n </dso-button>\r\n\r\n <dso-button\r\n btnLabel=\"\u2039\"\r\n btnType=\"outlined\"\r\n [isDisabled]=\"page === 1\"\r\n (onClick)=\"goPrevious()\">\r\n </dso-button>\r\n\r\n <!-- Page numbers -->\r\n <div class=\"page-buttons\">\r\n <ng-container *ngFor=\"let p of pageNumbers\">\r\n <dso-button\r\n [btnLabel]=\"p.toString()\"\r\n btnType=\"ghost\"\r\n btnSize=\"mdBtn\"\r\n [isDisabled]=\"page === p\"\r\n [isActive]=\"page === p\"\r\n (onClick)=\"goToPage(p)\">\r\n </dso-button>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Next / Last -->\r\n <dso-button\r\n btnLabel=\"\u203A\"\r\n btnType=\"outlined\"\r\n [isDisabled]=\"page === totalPages\"\r\n (onClick)=\"goNext()\">\r\n </dso-button>\r\n\r\n <dso-button\r\n btnLabel=\"\u00BB\"\r\n btnType=\"outlined\"\r\n [isDisabled]=\"page === totalPages\"\r\n (onClick)=\"goLast()\">\r\n </dso-button>\r\n\r\n <!-- Page size -->\r\n <dso-dropdown-list\r\n [options]=\"pageSizeOptions\"\r\n [value]=\"pageSize\"\r\n (selectionChange)=\"onPageSizeChange($event)\">\r\n </dso-dropdown-list>\r\n\r\n <!-- Range info -->\r\n <span class=\"range-info\">\r\n Showing {{ startItem }}\u2013{{ endItem }} of {{ totalItems }} results\r\n </span>\r\n\r\n <!-- Jump to page -->\r\n <div class=\"jump-to-page\">\r\n <input\r\n type=\"number\"\r\n min=\"1\"\r\n [(ngModel)]=\"jumpPageNumber\"\r\n (keydown.enter)=\"jumpToPage()\" />\r\n\r\n <dso-button\r\n btnLabel=\"Go\"\r\n btnType=\"ghost\"\r\n btnSize=\"mdBtn\"\r\n [isDisabled]=\"!jumpPageNumber\"\r\n (onClick)=\"jumpToPage()\">\r\n </dso-button>\r\n </div>\r\n\r\n</div>\r\n", styles: [".pagination-container{display:flex;align-items:center;gap:8px;font-size:14px}.range-info{margin-right:12px}button{padding:6px 10px;border-radius:4px;border:1px solid #ccc;background:#f0f0f0;cursor:pointer}button:disabled{opacity:.4;cursor:not-allowed}button.page-number.active{background-color:#007bff;color:#fff;font-weight:700}.page-buttons{display:flex;gap:4px}.page-buttons dso-button{flex:0 0 44px;text-align:center}.jump-to-page{display:flex;align-items:center;gap:4px}.jump-to-page input{width:48px;padding:6px 8px;border-radius:4px;border:1px solid #ccc;text-align:center}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}\n"] }]
102
+ }], propDecorators: { page: [{
103
+ type: Input
104
+ }], pageSize: [{
105
+ type: Input
106
+ }], totalItems: [{
107
+ type: Input
108
+ }], pageSizes: [{
109
+ type: Input
110
+ }], pageChange: [{
111
+ type: Output
112
+ }], pageSizeChange: [{
113
+ type: Output
114
+ }] } });
115
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnaW5hdGlvbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS9zcmMvbGliL3BhZ2luYXRpb24vcGFnaW5hdGlvbi5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS9zcmMvbGliL3BhZ2luYXRpb24vcGFnaW5hdGlvbi5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFhLE1BQU0sZUFBZSxDQUFDO0FBQ2xGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzdELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDBDQUEwQyxDQUFDOzs7O0FBU2pGLE1BQU0sT0FBTyxtQkFBbUI7SUFFOUI7O2lDQUU2QjtJQUVwQixJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBQ1QsUUFBUSxHQUFHLEVBQUUsQ0FBQztJQUNkLFVBQVUsR0FBRyxDQUFDLENBQUM7SUFDZixTQUFTLEdBQWEsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUVqRDs7aUNBRTZCO0lBRW5CLFVBQVUsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO0lBQ3hDLGNBQWMsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO0lBRXREOztpQ0FFNkI7SUFFN0IsV0FBVyxHQUFhLEVBQUUsQ0FBQztJQUMzQixjQUFjLEdBQWtCLElBQUksQ0FBQztJQUNyQyxlQUFlLEdBQXVDLEVBQUUsQ0FBQztJQUV6RDs7aUNBRTZCO0lBRTdCLFdBQVc7UUFDVCxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUM1QixJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBRUQ7O2lDQUU2QjtJQUU3QixJQUFJLFVBQVU7UUFDWixPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNqRSxDQUFDO0lBRUQsSUFBSSxTQUFTO1FBQ1gsT0FBTyxJQUFJLENBQUMsVUFBVSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUM7SUFDekUsQ0FBQztJQUVELElBQUksT0FBTztRQUNULE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzlELENBQUM7SUFFRDs7aUNBRTZCO0lBRXJCLG9CQUFvQjtRQUMxQixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNqRCxLQUFLLEVBQUUsR0FBRyxJQUFJLFdBQVc7WUFDekIsS0FBSyxFQUFFLElBQUk7U0FDWixDQUFDLENBQUMsQ0FBQztJQUNOLENBQUM7SUFFTyxtQkFBbUI7UUFDekIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztRQUM5QixJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUVyQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRTdCLElBQUksQ0FBQyxXQUFXLEdBQUcsRUFBRSxDQUFDO1FBQ3RCLEtBQUssSUFBSSxDQUFDLEdBQUcsS0FBSyxFQUFFLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNsQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMzQixDQUFDO0lBQ0gsQ0FBQztJQUVEOztpQ0FFNkI7SUFFN0IsUUFBUSxDQUFDLElBQVk7UUFDbkIsSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsVUFBVSxJQUFJLElBQUksS0FBSyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDL0QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDN0IsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPO1FBQ0wsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNuQixDQUFDO0lBRUQsVUFBVTtRQUNSLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQztJQUMvQixDQUFDO0lBRUQsTUFBTTtRQUNKLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQztJQUMvQixDQUFDO0lBRUQsTUFBTTtRQUNKLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxPQUFlO1FBQzlCLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRCxVQUFVO1FBQ1IsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjO1lBQUUsT0FBTztRQUVqQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDekUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDM0IsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7SUFDN0IsQ0FBQzt3R0EvR1UsbUJBQW1COzRGQUFuQixtQkFBbUIsMFFDYmhDLDA2REE0RUEsbXVCRG5FWSxlQUFlLGlLQUFFLFlBQVksNEpBQUUscUJBQXFCLG9KQUFFLFdBQVc7OzRGQUloRSxtQkFBbUI7a0JBUC9CLFNBQVM7K0JBQ0UsZ0JBQWdCLGNBQ2QsSUFBSSxXQUNQLENBQUMsZUFBZSxFQUFFLFlBQVksRUFBRSxxQkFBcUIsRUFBRSxXQUFXLENBQUM7OEJBVW5FLElBQUk7c0JBQVosS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFNSSxVQUFVO3NCQUFuQixNQUFNO2dCQUNHLGNBQWM7c0JBQXZCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPdXRwdXQsIEV2ZW50RW1pdHRlciwgT25DaGFuZ2VzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBCdXR0b25Db21wb25lbnQgfSBmcm9tICcuLi9idXR0b24vYnV0dG9uLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IERyb3Bkb3duTGlzdENvbXBvbmVudCB9IGZyb20gJy4uL2Ryb3Bkb3duLWxpc3QvZHJvcGRvd24tbGlzdC5jb21wb25lbnQnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdkc28tcGFnaW5hdGlvbicsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbQnV0dG9uQ29tcG9uZW50LCBDb21tb25Nb2R1bGUsIERyb3Bkb3duTGlzdENvbXBvbmVudCwgRm9ybXNNb2R1bGVdLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9wYWdpbmF0aW9uLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9wYWdpbmF0aW9uLmNvbXBvbmVudC5zY3NzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIFBhZ2luYXRpb25Db21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xyXG5cclxuICAvKiA9PT09PT09PT09PT09PT09PT09PT09PVxyXG4gICAgIElucHV0cyAoY29udHJvbGxlZCBzdGF0ZSlcclxuICAgICA9PT09PT09PT09PT09PT09PT09PT09PSAqL1xyXG5cclxuICBASW5wdXQoKSBwYWdlID0gMTtcclxuICBASW5wdXQoKSBwYWdlU2l6ZSA9IDEwO1xyXG4gIEBJbnB1dCgpIHRvdGFsSXRlbXMgPSAwO1xyXG4gIEBJbnB1dCgpIHBhZ2VTaXplczogbnVtYmVyW10gPSBbMTAsIDIwLCA1MCwgMTAwXTtcclxuXHJcbiAgLyogPT09PT09PT09PT09PT09PT09PT09PT1cclxuICAgICBPdXRwdXRzICh1c2VyIGludGVudClcclxuICAgICA9PT09PT09PT09PT09PT09PT09PT09PSAqL1xyXG5cclxuICBAT3V0cHV0KCkgcGFnZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xyXG4gIEBPdXRwdXQoKSBwYWdlU2l6ZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xyXG5cclxuICAvKiA9PT09PT09PT09PT09PT09PT09PT09PVxyXG4gICAgIEludGVybmFsIFVJIHN0YXRlXHJcbiAgICAgPT09PT09PT09PT09PT09PT09PT09PT0gKi9cclxuXHJcbiAgcGFnZU51bWJlcnM6IG51bWJlcltdID0gW107XHJcbiAganVtcFBhZ2VOdW1iZXI6IG51bWJlciB8IG51bGwgPSBudWxsO1xyXG4gIHBhZ2VTaXplT3B0aW9uczogeyBsYWJlbDogc3RyaW5nOyB2YWx1ZTogbnVtYmVyIH1bXSA9IFtdO1xyXG5cclxuICAvKiA9PT09PT09PT09PT09PT09PT09PT09PVxyXG4gICAgIExpZmVjeWNsZVxyXG4gICAgID09PT09PT09PT09PT09PT09PT09PT09ICovXHJcblxyXG4gIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xyXG4gICAgdGhpcy5idWlsZFBhZ2VTaXplT3B0aW9ucygpO1xyXG4gICAgdGhpcy5nZW5lcmF0ZVBhZ2VOdW1iZXJzKCk7XHJcbiAgfVxyXG5cclxuICAvKiA9PT09PT09PT09PT09PT09PT09PT09PVxyXG4gICAgIERlcml2ZWQgdmFsdWVzXHJcbiAgICAgPT09PT09PT09PT09PT09PT09PT09PT0gKi9cclxuXHJcbiAgZ2V0IHRvdGFsUGFnZXMoKTogbnVtYmVyIHtcclxuICAgIHJldHVybiBNYXRoLm1heChNYXRoLmNlaWwodGhpcy50b3RhbEl0ZW1zIC8gdGhpcy5wYWdlU2l6ZSksIDEpO1xyXG4gIH1cclxuXHJcbiAgZ2V0IHN0YXJ0SXRlbSgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMudG90YWxJdGVtcyA9PT0gMCA/IDAgOiAodGhpcy5wYWdlIC0gMSkgKiB0aGlzLnBhZ2VTaXplICsgMTtcclxuICB9XHJcblxyXG4gIGdldCBlbmRJdGVtKCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gTWF0aC5taW4odGhpcy5wYWdlICogdGhpcy5wYWdlU2l6ZSwgdGhpcy50b3RhbEl0ZW1zKTtcclxuICB9XHJcblxyXG4gIC8qID09PT09PT09PT09PT09PT09PT09PT09XHJcbiAgICAgVUkgaGVscGVyc1xyXG4gICAgID09PT09PT09PT09PT09PT09PT09PT09ICovXHJcblxyXG4gIHByaXZhdGUgYnVpbGRQYWdlU2l6ZU9wdGlvbnMoKTogdm9pZCB7XHJcbiAgICB0aGlzLnBhZ2VTaXplT3B0aW9ucyA9IHRoaXMucGFnZVNpemVzLm1hcChzaXplID0+ICh7XHJcbiAgICAgIGxhYmVsOiBgJHtzaXplfSBwZXIgcGFnZWAsXHJcbiAgICAgIHZhbHVlOiBzaXplXHJcbiAgICB9KSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdlbmVyYXRlUGFnZU51bWJlcnMoKTogdm9pZCB7XHJcbiAgICBjb25zdCB0b3RhbCA9IHRoaXMudG90YWxQYWdlcztcclxuICAgIGxldCBzdGFydCA9IE1hdGgubWF4KHRoaXMucGFnZSAtIDIsIDEpO1xyXG4gICAgbGV0IGVuZCA9IE1hdGgubWluKHN0YXJ0ICsgNCwgdG90YWwpO1xyXG5cclxuICAgIHN0YXJ0ID0gTWF0aC5tYXgoZW5kIC0gNCwgMSk7XHJcblxyXG4gICAgdGhpcy5wYWdlTnVtYmVycyA9IFtdO1xyXG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDw9IGVuZDsgaSsrKSB7XHJcbiAgICAgIHRoaXMucGFnZU51bWJlcnMucHVzaChpKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qID09PT09PT09PT09PT09PT09PT09PT09XHJcbiAgICAgTmF2aWdhdGlvbiAoZW1pdCBvbmx5KVxyXG4gICAgID09PT09PT09PT09PT09PT09PT09PT09ICovXHJcblxyXG4gIGdvVG9QYWdlKHBhZ2U6IG51bWJlcik6IHZvaWQge1xyXG4gICAgaWYgKHBhZ2UgPj0gMSAmJiBwYWdlIDw9IHRoaXMudG90YWxQYWdlcyAmJiBwYWdlICE9PSB0aGlzLnBhZ2UpIHtcclxuICAgICAgdGhpcy5wYWdlQ2hhbmdlLmVtaXQocGFnZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnb0ZpcnN0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5nb1RvUGFnZSgxKTtcclxuICB9XHJcblxyXG4gIGdvUHJldmlvdXMoKTogdm9pZCB7XHJcbiAgICB0aGlzLmdvVG9QYWdlKHRoaXMucGFnZSAtIDEpO1xyXG4gIH1cclxuXHJcbiAgZ29OZXh0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5nb1RvUGFnZSh0aGlzLnBhZ2UgKyAxKTtcclxuICB9XHJcblxyXG4gIGdvTGFzdCgpOiB2b2lkIHtcclxuICAgIHRoaXMuZ29Ub1BhZ2UodGhpcy50b3RhbFBhZ2VzKTtcclxuICB9XHJcblxyXG4gIG9uUGFnZVNpemVDaGFuZ2UobmV3U2l6ZTogbnVtYmVyKTogdm9pZCB7XHJcbiAgICB0aGlzLnBhZ2VTaXplQ2hhbmdlLmVtaXQobmV3U2l6ZSk7XHJcbiAgfVxyXG5cclxuICBqdW1wVG9QYWdlKCk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLmp1bXBQYWdlTnVtYmVyKSByZXR1cm47XHJcblxyXG4gICAgY29uc3QgcGFnZSA9IE1hdGgubWF4KDEsIE1hdGgubWluKHRoaXMuanVtcFBhZ2VOdW1iZXIsIHRoaXMudG90YWxQYWdlcykpO1xyXG4gICAgdGhpcy5wYWdlQ2hhbmdlLmVtaXQocGFnZSk7XHJcbiAgICB0aGlzLmp1bXBQYWdlTnVtYmVyID0gbnVsbDtcclxuICB9XHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cInBhZ2luYXRpb24tY29udGFpbmVyXCI+XHJcblxyXG4gIDwhLS0gRmlyc3QgLyBQcmV2aW91cyAtLT5cclxuICA8ZHNvLWJ1dHRvblxyXG4gICAgYnRuTGFiZWw9XCLCq1wiXHJcbiAgICBidG5UeXBlPVwib3V0bGluZWRcIlxyXG4gICAgW2lzRGlzYWJsZWRdPVwicGFnZSA9PT0gMVwiXHJcbiAgICAob25DbGljayk9XCJnb0ZpcnN0KClcIj5cclxuICA8L2Rzby1idXR0b24+XHJcblxyXG4gIDxkc28tYnV0dG9uXHJcbiAgICBidG5MYWJlbD1cIuKAuVwiXHJcbiAgICBidG5UeXBlPVwib3V0bGluZWRcIlxyXG4gICAgW2lzRGlzYWJsZWRdPVwicGFnZSA9PT0gMVwiXHJcbiAgICAob25DbGljayk9XCJnb1ByZXZpb3VzKClcIj5cclxuICA8L2Rzby1idXR0b24+XHJcblxyXG4gIDwhLS0gUGFnZSBudW1iZXJzIC0tPlxyXG4gIDxkaXYgY2xhc3M9XCJwYWdlLWJ1dHRvbnNcIj5cclxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHAgb2YgcGFnZU51bWJlcnNcIj5cclxuICAgICAgPGRzby1idXR0b25cclxuICAgICAgICBbYnRuTGFiZWxdPVwicC50b1N0cmluZygpXCJcclxuICAgICAgICBidG5UeXBlPVwiZ2hvc3RcIlxyXG4gICAgICAgIGJ0blNpemU9XCJtZEJ0blwiXHJcbiAgICAgICAgW2lzRGlzYWJsZWRdPVwicGFnZSA9PT0gcFwiXHJcbiAgICAgICAgW2lzQWN0aXZlXT1cInBhZ2UgPT09IHBcIlxyXG4gICAgICAgIChvbkNsaWNrKT1cImdvVG9QYWdlKHApXCI+XHJcbiAgICAgIDwvZHNvLWJ1dHRvbj5cclxuICAgIDwvbmctY29udGFpbmVyPlxyXG4gIDwvZGl2PlxyXG5cclxuICA8IS0tIE5leHQgLyBMYXN0IC0tPlxyXG4gIDxkc28tYnV0dG9uXHJcbiAgICBidG5MYWJlbD1cIuKAulwiXHJcbiAgICBidG5UeXBlPVwib3V0bGluZWRcIlxyXG4gICAgW2lzRGlzYWJsZWRdPVwicGFnZSA9PT0gdG90YWxQYWdlc1wiXHJcbiAgICAob25DbGljayk9XCJnb05leHQoKVwiPlxyXG4gIDwvZHNvLWJ1dHRvbj5cclxuXHJcbiAgPGRzby1idXR0b25cclxuICAgIGJ0bkxhYmVsPVwiwrtcIlxyXG4gICAgYnRuVHlwZT1cIm91dGxpbmVkXCJcclxuICAgIFtpc0Rpc2FibGVkXT1cInBhZ2UgPT09IHRvdGFsUGFnZXNcIlxyXG4gICAgKG9uQ2xpY2spPVwiZ29MYXN0KClcIj5cclxuICA8L2Rzby1idXR0b24+XHJcblxyXG4gIDwhLS0gUGFnZSBzaXplIC0tPlxyXG4gIDxkc28tZHJvcGRvd24tbGlzdFxyXG4gICAgW29wdGlvbnNdPVwicGFnZVNpemVPcHRpb25zXCJcclxuICAgIFt2YWx1ZV09XCJwYWdlU2l6ZVwiXHJcbiAgICAoc2VsZWN0aW9uQ2hhbmdlKT1cIm9uUGFnZVNpemVDaGFuZ2UoJGV2ZW50KVwiPlxyXG4gIDwvZHNvLWRyb3Bkb3duLWxpc3Q+XHJcblxyXG4gIDwhLS0gUmFuZ2UgaW5mbyAtLT5cclxuICA8c3BhbiBjbGFzcz1cInJhbmdlLWluZm9cIj5cclxuICAgIFNob3dpbmcge3sgc3RhcnRJdGVtIH194oCTe3sgZW5kSXRlbSB9fSBvZiB7eyB0b3RhbEl0ZW1zIH19IHJlc3VsdHNcclxuICA8L3NwYW4+XHJcblxyXG4gIDwhLS0gSnVtcCB0byBwYWdlIC0tPlxyXG4gIDxkaXYgY2xhc3M9XCJqdW1wLXRvLXBhZ2VcIj5cclxuICAgIDxpbnB1dFxyXG4gICAgICB0eXBlPVwibnVtYmVyXCJcclxuICAgICAgbWluPVwiMVwiXHJcbiAgICAgIFsobmdNb2RlbCldPVwianVtcFBhZ2VOdW1iZXJcIlxyXG4gICAgICAoa2V5ZG93bi5lbnRlcik9XCJqdW1wVG9QYWdlKClcIiAvPlxyXG5cclxuICAgIDxkc28tYnV0dG9uXHJcbiAgICAgIGJ0bkxhYmVsPVwiR29cIlxyXG4gICAgICBidG5UeXBlPVwiZ2hvc3RcIlxyXG4gICAgICBidG5TaXplPVwibWRCdG5cIlxyXG4gICAgICBbaXNEaXNhYmxlZF09XCIhanVtcFBhZ2VOdW1iZXJcIlxyXG4gICAgICAob25DbGljayk9XCJqdW1wVG9QYWdlKClcIj5cclxuICAgIDwvZHNvLWJ1dHRvbj5cclxuICA8L2Rpdj5cclxuXHJcbjwvZGl2PlxyXG4iXX0=
@@ -0,0 +1,25 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { Component, Input } from '@angular/core';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "@angular/common";
5
+ export class ProgressBarComponent {
6
+ /** Progress value (0–100). If null, shows indeterminate animation. */
7
+ value = null;
8
+ /** Color variants */
9
+ color = 'primary';
10
+ /** Optional animation toggle */
11
+ animated = true;
12
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ProgressBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
13
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ProgressBarComponent, isStandalone: true, selector: "dso-progress-bar", inputs: { value: "value", color: "color", animated: "animated" }, ngImport: i0, template: "<div class=\"progress-bar-container\">\r\n <div\r\n class=\"progress-bar-fill\"\r\n [ngClass]=\"[\r\n color,\r\n animated ? 'animated' : '',\r\n value === null ? 'indeterminate' : ''\r\n ]\"\r\n [style.width.%]=\"value !== null ? value : 50\"\r\n ></div>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.progress-bar-container{width:100%;height:8px;background-color:#e9ecef;border-radius:4px;overflow:hidden;position:relative;min-width:240px}.progress-bar-fill{position:absolute;height:100%;border-radius:4px;transition:width .4s ease}.progress-bar-fill.primary{background-color:#007bff}.progress-bar-fill.success{background-color:#28a745}.progress-bar-fill.warning{background-color:#ffc107}.progress-bar-fill.danger{background-color:#dc3545}.progress-bar-fill.animated{transition:width .4s ease-in-out}.progress-bar-fill.indeterminate{width:30%;animation:scrollLoop 1.5s linear infinite}@keyframes scrollLoop{0%{transform:translate(-100%)}to{transform:translate(400%)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
14
+ }
15
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ProgressBarComponent, decorators: [{
16
+ type: Component,
17
+ args: [{ selector: 'dso-progress-bar', standalone: true, imports: [CommonModule], template: "<div class=\"progress-bar-container\">\r\n <div\r\n class=\"progress-bar-fill\"\r\n [ngClass]=\"[\r\n color,\r\n animated ? 'animated' : '',\r\n value === null ? 'indeterminate' : ''\r\n ]\"\r\n [style.width.%]=\"value !== null ? value : 50\"\r\n ></div>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";.progress-bar-container{width:100%;height:8px;background-color:#e9ecef;border-radius:4px;overflow:hidden;position:relative;min-width:240px}.progress-bar-fill{position:absolute;height:100%;border-radius:4px;transition:width .4s ease}.progress-bar-fill.primary{background-color:#007bff}.progress-bar-fill.success{background-color:#28a745}.progress-bar-fill.warning{background-color:#ffc107}.progress-bar-fill.danger{background-color:#dc3545}.progress-bar-fill.animated{transition:width .4s ease-in-out}.progress-bar-fill.indeterminate{width:30%;animation:scrollLoop 1.5s linear infinite}@keyframes scrollLoop{0%{transform:translate(-100%)}to{transform:translate(400%)}}\n"] }]
18
+ }], propDecorators: { value: [{
19
+ type: Input
20
+ }], color: [{
21
+ type: Input
22
+ }], animated: [{
23
+ type: Input
24
+ }] } });
25
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZ3Jlc3MtYmFyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3VpL3NyYy9saWIvcHJvZ3Jlc3MtYmFyL3Byb2dyZXNzLWJhci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS9zcmMvbGliL3Byb2dyZXNzLWJhci9wcm9ncmVzcy1iYXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDOzs7QUFTakQsTUFBTSxPQUFPLG9CQUFvQjtJQUMvQixzRUFBc0U7SUFDN0QsS0FBSyxHQUFrQixJQUFJLENBQUM7SUFFckMscUJBQXFCO0lBQ1osS0FBSyxHQUFpRCxTQUFTLENBQUM7SUFFekUsZ0NBQWdDO0lBQ3ZCLFFBQVEsR0FBWSxJQUFJLENBQUM7d0dBUnZCLG9CQUFvQjs0RkFBcEIsb0JBQW9CLDhJQ1ZqQywyU0FXQSx5dUJESFksWUFBWTs7NEZBRVgsb0JBQW9CO2tCQVBoQyxTQUFTOytCQUNFLGtCQUFrQixjQUdoQixJQUFJLFdBQ1AsQ0FBQyxZQUFZLENBQUM7OEJBSWQsS0FBSztzQkFBYixLQUFLO2dCQUdHLEtBQUs7c0JBQWIsS0FBSztnQkFHRyxRQUFRO3NCQUFoQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdkc28tcHJvZ3Jlc3MtYmFyJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vcHJvZ3Jlc3MtYmFyLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9wcm9ncmVzcy1iYXIuY29tcG9uZW50LnNjc3MnXSxcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBQcm9ncmVzc0JhckNvbXBvbmVudCB7XHJcbiAgLyoqIFByb2dyZXNzIHZhbHVlICgw4oCTMTAwKS4gSWYgbnVsbCwgc2hvd3MgaW5kZXRlcm1pbmF0ZSBhbmltYXRpb24uICovXHJcbiAgQElucHV0KCkgdmFsdWU6IG51bWJlciB8IG51bGwgPSBudWxsO1xyXG5cclxuICAvKiogQ29sb3IgdmFyaWFudHMgKi9cclxuICBASW5wdXQoKSBjb2xvcjogJ3ByaW1hcnknIHwgJ3N1Y2Nlc3MnIHwgJ3dhcm5pbmcnIHwgJ2RhbmdlcicgPSAncHJpbWFyeSc7XHJcblxyXG4gIC8qKiBPcHRpb25hbCBhbmltYXRpb24gdG9nZ2xlICovXHJcbiAgQElucHV0KCkgYW5pbWF0ZWQ6IGJvb2xlYW4gPSB0cnVlO1xyXG59IiwiPGRpdiBjbGFzcz1cInByb2dyZXNzLWJhci1jb250YWluZXJcIj5cclxuICA8ZGl2XHJcbiAgICBjbGFzcz1cInByb2dyZXNzLWJhci1maWxsXCJcclxuICAgIFtuZ0NsYXNzXT1cIltcclxuICAgICAgY29sb3IsXHJcbiAgICAgIGFuaW1hdGVkID8gJ2FuaW1hdGVkJyA6ICcnLFxyXG4gICAgICB2YWx1ZSA9PT0gbnVsbCA/ICdpbmRldGVybWluYXRlJyA6ICcnXHJcbiAgICBdXCJcclxuICAgIFtzdHlsZS53aWR0aC4lXT1cInZhbHVlICE9PSBudWxsID8gdmFsdWUgOiA1MFwiXHJcbiAgPjwvZGl2PlxyXG48L2Rpdj5cclxuIl19
@@ -0,0 +1,41 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { Component, Input, Output, EventEmitter } from '@angular/core';
3
+ import { FormsModule } from '@angular/forms';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@angular/common";
6
+ export class RadioComponent {
7
+ label = 'Radio label';
8
+ value;
9
+ name; // for grouping radios
10
+ disabled = false;
11
+ error = false;
12
+ isChecked = false;
13
+ change = new EventEmitter();
14
+ // Method to handle change in radio state
15
+ toggleRadio(event) {
16
+ // console.log(this.value);
17
+ event.stopPropagation();
18
+ this.change.emit(this.value); // Emit the updated value to the parent
19
+ }
20
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RadioComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
21
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: RadioComponent, isStandalone: true, selector: "dso-radio", inputs: { label: "label", value: "value", name: "name", disabled: "disabled", error: "error", isChecked: "isChecked" }, outputs: { change: "change" }, ngImport: i0, template: "<label class=\"radio-wrapper\" \r\n[class.disabled]=\"disabled\" \r\n[class.error]=\"error\">\r\n <input\r\n class=\"radio-input\"\r\n type=\"radio\"\r\n [attr.name]=\"name\"\r\n [value]=\"value\"\r\n [checked]=\"isChecked\"\r\n [disabled]=\"disabled\"\r\n (change)=\"toggleRadio($event)\"\r\n />\r\n <span class=\"custom-radio\"></span>\r\n <span *ngIf=\"label\" class=\"radio-label\">{{ label }}</span>\r\n</label>\r\n", styles: [".radio-wrapper{display:flex;align-items:center;gap:8px;cursor:pointer}.radio-wrapper.disabled{cursor:not-allowed}.radio-wrapper.disabled .custom-radio{background-color:#f0f0f0;border-color:#d0d0d0}.radio-wrapper.disabled .radio-input:checked~.custom-radio{border:1px solid rgba(0,0,255,.5)}.radio-wrapper.disabled .custom-radio:after{opacity:.5}.radio-input{position:absolute;width:1px;height:1px;margin:-1px;border:0;padding:0;clip:rect(0 0 0 0);clip-path:inset(100%);overflow:hidden;white-space:nowrap}.custom-radio{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border:1px solid #666666;border-radius:50%}.radio-input:checked~.custom-radio{border:1px solid blue}input[type=radio]:checked+.custom-radio:after{display:block;content:\"\";width:100%;height:100%;background:#00f;border:5px solid blue;background:transparent;box-sizing:border-box;border-radius:50%}.radio-label{font-size:14px}.error .custom-radio{border-color:red}.radio-wrapper:not(.disabled):hover .custom-radio{background-color:#eef5f9;border-color:#0000ffc0;cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
22
+ }
23
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RadioComponent, decorators: [{
24
+ type: Component,
25
+ args: [{ selector: 'dso-radio', standalone: true, imports: [FormsModule, CommonModule], template: "<label class=\"radio-wrapper\" \r\n[class.disabled]=\"disabled\" \r\n[class.error]=\"error\">\r\n <input\r\n class=\"radio-input\"\r\n type=\"radio\"\r\n [attr.name]=\"name\"\r\n [value]=\"value\"\r\n [checked]=\"isChecked\"\r\n [disabled]=\"disabled\"\r\n (change)=\"toggleRadio($event)\"\r\n />\r\n <span class=\"custom-radio\"></span>\r\n <span *ngIf=\"label\" class=\"radio-label\">{{ label }}</span>\r\n</label>\r\n", styles: [".radio-wrapper{display:flex;align-items:center;gap:8px;cursor:pointer}.radio-wrapper.disabled{cursor:not-allowed}.radio-wrapper.disabled .custom-radio{background-color:#f0f0f0;border-color:#d0d0d0}.radio-wrapper.disabled .radio-input:checked~.custom-radio{border:1px solid rgba(0,0,255,.5)}.radio-wrapper.disabled .custom-radio:after{opacity:.5}.radio-input{position:absolute;width:1px;height:1px;margin:-1px;border:0;padding:0;clip:rect(0 0 0 0);clip-path:inset(100%);overflow:hidden;white-space:nowrap}.custom-radio{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border:1px solid #666666;border-radius:50%}.radio-input:checked~.custom-radio{border:1px solid blue}input[type=radio]:checked+.custom-radio:after{display:block;content:\"\";width:100%;height:100%;background:#00f;border:5px solid blue;background:transparent;box-sizing:border-box;border-radius:50%}.radio-label{font-size:14px}.error .custom-radio{border-color:red}.radio-wrapper:not(.disabled):hover .custom-radio{background-color:#eef5f9;border-color:#0000ffc0;cursor:pointer}\n"] }]
26
+ }], propDecorators: { label: [{
27
+ type: Input
28
+ }], value: [{
29
+ type: Input
30
+ }], name: [{
31
+ type: Input
32
+ }], disabled: [{
33
+ type: Input
34
+ }], error: [{
35
+ type: Input
36
+ }], isChecked: [{
37
+ type: Input
38
+ }], change: [{
39
+ type: Output
40
+ }] } });
41
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFkaW8uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdWkvc3JjL2xpYi9yYWRpby9yYWRpby5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS9zcmMvbGliL3JhZGlvL3JhZGlvLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7O0FBUzdDLE1BQU0sT0FBTyxjQUFjO0lBQ2hCLEtBQUssR0FBWSxhQUFhLENBQUM7SUFDL0IsS0FBSyxDQUFVO0lBQ2YsSUFBSSxDQUFVLENBQUMsc0JBQXNCO0lBQ3JDLFFBQVEsR0FBRyxLQUFLLENBQUM7SUFDakIsS0FBSyxHQUFHLEtBQUssQ0FBQztJQUNkLFNBQVMsR0FBWSxLQUFLLENBQUM7SUFFMUIsTUFBTSxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7SUFHNUMseUNBQXlDO0lBQzNDLFdBQVcsQ0FBQyxLQUFZO1FBQ3BCLDJCQUEyQjtRQUMzQixLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsdUNBQXVDO0lBQ3pFLENBQUM7d0dBaEJVLGNBQWM7NEZBQWQsY0FBYyw0TkNYM0IsK2JBZUEsMm1DRE5hLFdBQVcsOEJBQUUsWUFBWTs7NEZBRXpCLGNBQWM7a0JBUDFCLFNBQVM7K0JBQ0UsV0FBVyxjQUNULElBQUksV0FHUCxDQUFFLFdBQVcsRUFBRSxZQUFZLENBQUU7OEJBRzdCLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBRUksTUFBTTtzQkFBZixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2Rzby1yYWRpbycsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICB0ZW1wbGF0ZVVybDogJy4vcmFkaW8uY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL3JhZGlvLmNvbXBvbmVudC5zY3NzJ10sXHJcbiAgaW1wb3J0czogWyBGb3Jtc01vZHVsZSwgQ29tbW9uTW9kdWxlIF1cclxufSlcclxuZXhwb3J0IGNsYXNzIFJhZGlvQ29tcG9uZW50IHtcclxuICBASW5wdXQoKSBsYWJlbD86IHN0cmluZyA9ICdSYWRpbyBsYWJlbCc7XHJcbiAgQElucHV0KCkgdmFsdWUhOiBzdHJpbmc7XHJcbiAgQElucHV0KCkgbmFtZSE6IHN0cmluZzsgLy8gZm9yIGdyb3VwaW5nIHJhZGlvc1xyXG4gIEBJbnB1dCgpIGRpc2FibGVkID0gZmFsc2U7XHJcbiAgQElucHV0KCkgZXJyb3IgPSBmYWxzZTtcclxuICBASW5wdXQoKSBpc0NoZWNrZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgQE91dHB1dCgpIGNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xyXG5cclxuICBcclxuICAgIC8vIE1ldGhvZCB0byBoYW5kbGUgY2hhbmdlIGluIHJhZGlvIHN0YXRlXHJcbiAgdG9nZ2xlUmFkaW8oZXZlbnQ6IEV2ZW50KSB7XHJcbiAgICAgIC8vIGNvbnNvbGUubG9nKHRoaXMudmFsdWUpO1xyXG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgXHJcbiAgICAgIHRoaXMuY2hhbmdlLmVtaXQodGhpcy52YWx1ZSk7IC8vIEVtaXQgdGhlIHVwZGF0ZWQgdmFsdWUgdG8gdGhlIHBhcmVudFxyXG4gIH1cclxuXHJcbn1cclxuIiwiPGxhYmVsIGNsYXNzPVwicmFkaW8td3JhcHBlclwiIFxyXG5bY2xhc3MuZGlzYWJsZWRdPVwiZGlzYWJsZWRcIiBcclxuW2NsYXNzLmVycm9yXT1cImVycm9yXCI+XHJcbiAgPGlucHV0XHJcbiAgICBjbGFzcz1cInJhZGlvLWlucHV0XCJcclxuICAgIHR5cGU9XCJyYWRpb1wiXHJcbiAgICBbYXR0ci5uYW1lXT1cIm5hbWVcIlxyXG4gICAgW3ZhbHVlXT1cInZhbHVlXCJcclxuICAgIFtjaGVja2VkXT1cImlzQ2hlY2tlZFwiXHJcbiAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxyXG4gICAgKGNoYW5nZSk9XCJ0b2dnbGVSYWRpbygkZXZlbnQpXCJcclxuICAvPlxyXG4gIDxzcGFuIGNsYXNzPVwiY3VzdG9tLXJhZGlvXCI+PC9zcGFuPlxyXG4gIDxzcGFuICpuZ0lmPVwibGFiZWxcIiBjbGFzcz1cInJhZGlvLWxhYmVsXCI+e3sgbGFiZWwgfX08L3NwYW4+XHJcbjwvbGFiZWw+XHJcbiJdfQ==