imng-kendo-data-entry 4.62.1 → 4.102.13

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 (86) hide show
  1. package/README.md +1 -1
  2. package/{esm2015/imng-kendo-data-entry.js → esm2020/imng-kendo-data-entry.mjs} +0 -0
  3. package/{esm2015/index.js → esm2020/index.mjs} +2 -2
  4. package/esm2020/lib/base-data-entry.component.mjs +75 -0
  5. package/{esm2015/lib/data-delete-facade.js → esm2020/lib/data-delete-facade.mjs} +0 -0
  6. package/esm2020/lib/data-entry-dialog.component.mjs +112 -0
  7. package/{esm2015/lib/data-entry-facade.js → esm2020/lib/data-entry-facade.mjs} +0 -0
  8. package/{esm2015/lib/dialog-buttons.directive.js → esm2020/lib/dialog-buttons.directive.mjs} +4 -4
  9. package/{esm2015/lib/form-group-patcher.js → esm2020/lib/form-group-patcher.mjs} +0 -0
  10. package/esm2020/lib/imng-kendo-data-entry.module.mjs +20 -0
  11. package/esm2020/lib/reducer-collection-logic.mjs +18 -0
  12. package/esm2020/testing/data-delete-facade-http-tests.mjs +13 -0
  13. package/{esm2015/testing/data-delete-mock.facade.js → esm2020/testing/data-delete-mock.facade.mjs} +0 -0
  14. package/esm2020/testing/data-entry-facade-http-tests.mjs +24 -0
  15. package/esm2020/testing/data-entry-facade-tests.mjs +43 -0
  16. package/esm2020/testing/data-entry-mock.facade.mjs +36 -0
  17. package/{esm2015/testing/imng-kendo-data-entry-testing.js → esm2020/testing/imng-kendo-data-entry-testing.mjs} +2 -2
  18. package/{esm2015/testing/index.js → esm2020/testing/index.mjs} +0 -0
  19. package/{esm2015/testing/mock-data-entry-dialog.component.js → esm2020/testing/mock-data-entry-dialog.component.mjs} +0 -0
  20. package/{esm2015/testing/test-trigger-event-helpers.js → esm2020/testing/test-trigger-event-helpers.mjs} +0 -0
  21. package/fesm2015/{imng-kendo-data-entry-testing.js → imng-kendo-data-entry-testing.mjs} +10 -6
  22. package/fesm2015/imng-kendo-data-entry-testing.mjs.map +1 -0
  23. package/fesm2015/imng-kendo-data-entry.mjs +247 -0
  24. package/fesm2015/imng-kendo-data-entry.mjs.map +1 -0
  25. package/fesm2020/imng-kendo-data-entry-testing.mjs +159 -0
  26. package/fesm2020/imng-kendo-data-entry-testing.mjs.map +1 -0
  27. package/{fesm2015/imng-kendo-data-entry.js → fesm2020/imng-kendo-data-entry.mjs} +66 -31
  28. package/fesm2020/imng-kendo-data-entry.mjs.map +1 -0
  29. package/imng-kendo-data-entry.d.ts +0 -1
  30. package/index.d.ts +1 -2
  31. package/lib/base-data-entry.component.d.ts +5 -6
  32. package/lib/data-delete-facade.d.ts +0 -1
  33. package/lib/data-entry-dialog.component.d.ts +8 -9
  34. package/lib/data-entry-facade.d.ts +0 -1
  35. package/lib/dialog-buttons.directive.d.ts +0 -1
  36. package/lib/form-group-patcher.d.ts +0 -1
  37. package/lib/{data-entry.module.d.ts → imng-kendo-data-entry.module.d.ts} +0 -1
  38. package/lib/reducer-collection-logic.d.ts +0 -1
  39. package/package.json +44 -17
  40. package/testing/README.md +3 -0
  41. package/testing/data-delete-facade-http-tests.d.ts +0 -1
  42. package/testing/data-delete-mock.facade.d.ts +1 -2
  43. package/testing/data-entry-facade-http-tests.d.ts +0 -1
  44. package/testing/data-entry-facade-tests.d.ts +2 -3
  45. package/testing/data-entry-mock.facade.d.ts +4 -5
  46. package/testing/imng-kendo-data-entry-testing.d.ts +1 -2
  47. package/testing/index.d.ts +0 -1
  48. package/testing/mock-data-entry-dialog.component.d.ts +1 -2
  49. package/testing/package.json +5 -5
  50. package/testing/test-trigger-event-helpers.d.ts +0 -1
  51. package/bundles/imng-kendo-data-entry-testing.umd.js +0 -561
  52. package/bundles/imng-kendo-data-entry-testing.umd.js.map +0 -1
  53. package/bundles/imng-kendo-data-entry.umd.js +0 -544
  54. package/bundles/imng-kendo-data-entry.umd.js.map +0 -1
  55. package/esm2015/lib/base-data-entry.component.js +0 -73
  56. package/esm2015/lib/data-entry-dialog.component.js +0 -79
  57. package/esm2015/lib/data-entry.module.js +0 -20
  58. package/esm2015/lib/reducer-collection-logic.js +0 -18
  59. package/esm2015/testing/data-delete-facade-http-tests.js +0 -16
  60. package/esm2015/testing/data-entry-facade-http-tests.js +0 -29
  61. package/esm2015/testing/data-entry-facade-tests.js +0 -52
  62. package/esm2015/testing/data-entry-mock.facade.js +0 -32
  63. package/esm2015/testing/public_api.js +0 -2
  64. package/fesm2015/imng-kendo-data-entry-testing.js.map +0 -1
  65. package/fesm2015/imng-kendo-data-entry.js.map +0 -1
  66. package/imng-kendo-data-entry.d.ts.map +0 -1
  67. package/index.d.ts.map +0 -1
  68. package/lib/base-data-entry.component.d.ts.map +0 -1
  69. package/lib/data-delete-facade.d.ts.map +0 -1
  70. package/lib/data-entry-dialog.component.d.ts.map +0 -1
  71. package/lib/data-entry-facade.d.ts.map +0 -1
  72. package/lib/data-entry.module.d.ts.map +0 -1
  73. package/lib/dialog-buttons.directive.d.ts.map +0 -1
  74. package/lib/form-group-patcher.d.ts.map +0 -1
  75. package/lib/reducer-collection-logic.d.ts.map +0 -1
  76. package/testing/data-delete-facade-http-tests.d.ts.map +0 -1
  77. package/testing/data-delete-mock.facade.d.ts.map +0 -1
  78. package/testing/data-entry-facade-http-tests.d.ts.map +0 -1
  79. package/testing/data-entry-facade-tests.d.ts.map +0 -1
  80. package/testing/data-entry-mock.facade.d.ts.map +0 -1
  81. package/testing/imng-kendo-data-entry-testing.d.ts.map +0 -1
  82. package/testing/index.d.ts.map +0 -1
  83. package/testing/mock-data-entry-dialog.component.d.ts.map +0 -1
  84. package/testing/public_api.d.ts +0 -2
  85. package/testing/public_api.d.ts.map +0 -1
  86. package/testing/test-trigger-event-helpers.d.ts.map +0 -1
@@ -0,0 +1,247 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Directive, TemplateRef, Component, ChangeDetectionStrategy, Input, ContentChild, NgModule, InjectionToken, Inject } from '@angular/core';
3
+ import * as i2 from '@angular/common';
4
+ import { CommonModule } from '@angular/common';
5
+ import * as i1 from '@progress/kendo-angular-dialog';
6
+ import { DialogModule } from '@progress/kendo-angular-dialog';
7
+ import { BehaviorSubject } from 'rxjs';
8
+ import { Subscriptions } from 'imng-ngrx-utils';
9
+ import { filter, take, tap } from 'rxjs/operators';
10
+
11
+ class DialogButtonsDirective {
12
+ constructor(tpl) {
13
+ this.tpl = tpl;
14
+ }
15
+ }
16
+ DialogButtonsDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: DialogButtonsDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
17
+ DialogButtonsDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.2", type: DialogButtonsDirective, selector: "[imngDialogBtns]", ngImport: i0 });
18
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: DialogButtonsDirective, decorators: [{
19
+ type: Directive,
20
+ args: [{ selector: '[imngDialogBtns]' }]
21
+ }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });
22
+
23
+ class DataEntryDialogComponent {
24
+ constructor() {
25
+ this.width = 800; //NOSONAR
26
+ this.height = 600; //NOSONAR
27
+ this.saveButtonText = 'Save';
28
+ this.submitted = false;
29
+ }
30
+ ngOnInit() {
31
+ if (!this.parentComponent) {
32
+ throw new TypeError(`The input 'parentComponent' is required`);
33
+ }
34
+ this.dialogTitle = this.parentComponent.dialogTitle;
35
+ this.loading$ = this.parentComponent.loading$;
36
+ this.addEditForm = this.parentComponent.addEditForm;
37
+ }
38
+ close() {
39
+ var _a;
40
+ (_a = this.parentComponent) === null || _a === void 0 ? void 0 : _a.closeForm();
41
+ }
42
+ cancel() {
43
+ var _a;
44
+ (_a = this.parentComponent) === null || _a === void 0 ? void 0 : _a.onCancel();
45
+ }
46
+ submit() {
47
+ var _a;
48
+ (_a = this.parentComponent) === null || _a === void 0 ? void 0 : _a.onSubmit();
49
+ }
50
+ get dialogActionBtnsCtx() {
51
+ return {
52
+ $implicit: { cancel: () => this.cancel(), submit: () => this.submit() },
53
+ };
54
+ }
55
+ }
56
+ DataEntryDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: DataEntryDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
57
+ DataEntryDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.2", type: DataEntryDialogComponent, selector: "imng-data-entry-dialog[parentComponent]", inputs: { width: "width", height: "height", autoFocusedElement: "autoFocusedElement", parentComponent: "parentComponent", saveButtonText: "saveButtonText" }, queries: [{ propertyName: "dialogBtnsTemplate", first: true, predicate: DialogButtonsDirective, descendants: true, read: TemplateRef, static: true }], ngImport: i0, template: `<kendo-dialog
58
+ [width]="width"
59
+ [height]="height"
60
+ (close)="close()"
61
+ [autoFocusedElement]="autoFocusedElement || ''"
62
+ >
63
+ <kendo-dialog-titlebar class="bg-primary">{{
64
+ dialogTitle
65
+ }}</kendo-dialog-titlebar>
66
+ <ng-content></ng-content>
67
+ <kendo-dialog-actions>
68
+ <ng-container
69
+ *ngTemplateOutlet="
70
+ dialogBtnsTemplate || defaultDialogActionsTpl;
71
+ context: dialogActionBtnsCtx
72
+ "
73
+ >
74
+ </ng-container>
75
+ </kendo-dialog-actions>
76
+ </kendo-dialog>
77
+
78
+ <ng-template #defaultDialogActionsTpl>
79
+ <button id="btnCancel" class="k-button" (click)="cancel()">Cancel</button>
80
+ <button id="btnSave" class="k-button k-primary" (click)="submit()">
81
+ {{ saveButtonText }}
82
+ </button>
83
+ </ng-template>`, isInline: true, components: [{ type: i1.DialogComponent, selector: "kendo-dialog", inputs: ["actionsLayout", "actions", "autoFocusedElement", "title", "width", "minWidth", "maxWidth", "height", "minHeight", "maxHeight"], outputs: ["action", "close"], exportAs: ["kendoDialog"] }, { type: i1.DialogTitleBarComponent, selector: "kendo-dialog-titlebar", inputs: ["id", "closeTitle"], outputs: ["close"] }, { type: i1.DialogActionsComponent, selector: "kendo-dialog-actions", inputs: ["layout", "actions"], outputs: ["action"] }], directives: [{ type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
84
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: DataEntryDialogComponent, decorators: [{
85
+ type: Component,
86
+ args: [{
87
+ selector: 'imng-data-entry-dialog[parentComponent]',
88
+ template: `<kendo-dialog
89
+ [width]="width"
90
+ [height]="height"
91
+ (close)="close()"
92
+ [autoFocusedElement]="autoFocusedElement || ''"
93
+ >
94
+ <kendo-dialog-titlebar class="bg-primary">{{
95
+ dialogTitle
96
+ }}</kendo-dialog-titlebar>
97
+ <ng-content></ng-content>
98
+ <kendo-dialog-actions>
99
+ <ng-container
100
+ *ngTemplateOutlet="
101
+ dialogBtnsTemplate || defaultDialogActionsTpl;
102
+ context: dialogActionBtnsCtx
103
+ "
104
+ >
105
+ </ng-container>
106
+ </kendo-dialog-actions>
107
+ </kendo-dialog>
108
+
109
+ <ng-template #defaultDialogActionsTpl>
110
+ <button id="btnCancel" class="k-button" (click)="cancel()">Cancel</button>
111
+ <button id="btnSave" class="k-button k-primary" (click)="submit()">
112
+ {{ saveButtonText }}
113
+ </button>
114
+ </ng-template>`,
115
+ changeDetection: ChangeDetectionStrategy.OnPush,
116
+ }]
117
+ }], propDecorators: { width: [{
118
+ type: Input
119
+ }], height: [{
120
+ type: Input
121
+ }], autoFocusedElement: [{
122
+ type: Input
123
+ }], parentComponent: [{
124
+ type: Input
125
+ }], saveButtonText: [{
126
+ type: Input
127
+ }], dialogBtnsTemplate: [{
128
+ type: ContentChild,
129
+ args: [DialogButtonsDirective, { static: true, read: TemplateRef }]
130
+ }] } });
131
+
132
+ class ImngDataEntryDialogModule {
133
+ }
134
+ ImngDataEntryDialogModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: ImngDataEntryDialogModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
135
+ ImngDataEntryDialogModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: ImngDataEntryDialogModule, declarations: [DataEntryDialogComponent, DialogButtonsDirective], imports: [CommonModule, DialogModule], exports: [DataEntryDialogComponent, DialogButtonsDirective] });
136
+ ImngDataEntryDialogModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: ImngDataEntryDialogModule, imports: [[CommonModule, DialogModule]] });
137
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: ImngDataEntryDialogModule, decorators: [{
138
+ type: NgModule,
139
+ args: [{
140
+ imports: [CommonModule, DialogModule],
141
+ declarations: [DataEntryDialogComponent, DialogButtonsDirective],
142
+ exports: [DataEntryDialogComponent, DialogButtonsDirective],
143
+ }]
144
+ }] });
145
+
146
+ const FACADE = new InjectionToken('imng-data-entry-facade');
147
+ /**
148
+ * The extending class has to implement the following properties on ngInit
149
+ * dialogTitle: string - This will be the text displayed at the top of the modal title bar
150
+ * props: enum - This is a helper property to make the html markup type safe
151
+ *
152
+ * Along with the requirements above, the extending class has to set values to the
153
+ * following properties on ngInit
154
+ * active$: Observable<boolean> - This typically would be assigned to the isNewActive$ or isEditActive on the facade
155
+ * addEditForm: FormGroup - This will be created by your component
156
+ *
157
+ * @class BaseDataEntryComponent>
158
+ */
159
+ class BaseDataEntryComponent {
160
+ constructor(facade) {
161
+ this.facade = facade;
162
+ this.width = 800; //NOSONAR
163
+ this.height = 600; //NOSONAR
164
+ this.allSubscriptions = new Subscriptions();
165
+ this._submitted$ = new BehaviorSubject(false);
166
+ this.loading$ = this.facade.loading$;
167
+ this.initForm();
168
+ }
169
+ get submitted$() {
170
+ return this._submitted$.asObservable();
171
+ }
172
+ // convenience getter for easy access to form fields
173
+ formControl(controlName) {
174
+ var _a;
175
+ return (_a = this.addEditForm) === null || _a === void 0 ? void 0 : _a.controls[controlName];
176
+ }
177
+ formControlErrors(controlName) {
178
+ var _a;
179
+ return ((_a = this.addEditForm) === null || _a === void 0 ? void 0 : _a.controls[controlName].errors) || undefined;
180
+ }
181
+ ngOnDestroy() {
182
+ this.allSubscriptions.unsubscribeAll();
183
+ }
184
+ closeForm() {
185
+ this.initForm();
186
+ this.facade.clearCurrentEntity();
187
+ this._submitted$.next(false);
188
+ }
189
+ onCancel() {
190
+ this.closeForm();
191
+ }
192
+ onSubmit() {
193
+ this._submitted$.next(true);
194
+ // stop here if form is invalid
195
+ if (this.isDataInvalid()) {
196
+ console.error('form validation errors.'); //NOSONAR
197
+ return;
198
+ }
199
+ this.save();
200
+ this.closeForm();
201
+ }
202
+ isDataInvalid() {
203
+ var _a;
204
+ return (_a = this.addEditForm) === null || _a === void 0 ? void 0 : _a.invalid;
205
+ }
206
+ }
207
+ BaseDataEntryComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: BaseDataEntryComponent, deps: [{ token: FACADE }], target: i0.ɵɵFactoryTarget.Directive });
208
+ BaseDataEntryComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.2", type: BaseDataEntryComponent, inputs: { width: "width", height: "height" }, ngImport: i0 });
209
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: BaseDataEntryComponent, decorators: [{
210
+ type: Directive
211
+ }], ctorParameters: function () {
212
+ return [{ type: undefined, decorators: [{
213
+ type: Inject,
214
+ args: [FACADE]
215
+ }] }];
216
+ }, propDecorators: { width: [{
217
+ type: Input
218
+ }], height: [{
219
+ type: Input
220
+ }] } });
221
+
222
+ function updateStateCollectionItem(collection, item) {
223
+ const items = [...collection];
224
+ const index = collection.findIndex((val) => val.id === item.id);
225
+ items.splice(index, 1, item);
226
+ return items;
227
+ }
228
+ function removeStateCollectionItem(collection, item) {
229
+ const items = [...collection];
230
+ const index = collection.findIndex((val) => val.id === item.id);
231
+ items.splice(index, 1);
232
+ return items;
233
+ }
234
+ function addStateCollectionItem(collection, item) {
235
+ const items = [...collection];
236
+ items.unshift(item);
237
+ return items;
238
+ }
239
+
240
+ const formGroupPatcher = (addEditForm) => (source) => source.pipe(filter(t => !!t), take(1), tap(t => addEditForm.patchValue(t)));
241
+
242
+ /**
243
+ * Generated bundle index. Do not edit.
244
+ */
245
+
246
+ export { BaseDataEntryComponent, DataEntryDialogComponent, DialogButtonsDirective, ImngDataEntryDialogModule, addStateCollectionItem, formGroupPatcher, removeStateCollectionItem, updateStateCollectionItem };
247
+ //# sourceMappingURL=imng-kendo-data-entry.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imng-kendo-data-entry.mjs","sources":["../../../../libs/imng-kendo-data-entry/src/lib/dialog-buttons.directive.ts","../../../../libs/imng-kendo-data-entry/src/lib/data-entry-dialog.component.ts","../../../../libs/imng-kendo-data-entry/src/lib/imng-kendo-data-entry.module.ts","../../../../libs/imng-kendo-data-entry/src/lib/base-data-entry.component.ts","../../../../libs/imng-kendo-data-entry/src/lib/reducer-collection-logic.ts","../../../../libs/imng-kendo-data-entry/src/lib/form-group-patcher.ts","../../../../libs/imng-kendo-data-entry/src/imng-kendo-data-entry.ts"],"sourcesContent":["import { Directive, TemplateRef } from '@angular/core';\n\n@Directive({ selector: '[imngDialogBtns]' })\nexport class DialogButtonsDirective {\n constructor(public tpl: TemplateRef<unknown>) { }\n}\n","import {\n Component,\n OnInit,\n Input,\n ChangeDetectionStrategy,\n TemplateRef,\n ContentChild,\n} from '@angular/core';\nimport { Observable } from 'rxjs';\nimport { FormGroup } from '@angular/forms';\nimport { BaseDataEntryComponent } from './base-data-entry.component';\nimport { DialogButtonsDirective } from './dialog-buttons.directive';\n\n@Component({\n selector: 'imng-data-entry-dialog[parentComponent]',\n template: `<kendo-dialog\n [width]=\"width\"\n [height]=\"height\"\n (close)=\"close()\"\n [autoFocusedElement]=\"autoFocusedElement || ''\"\n >\n <kendo-dialog-titlebar class=\"bg-primary\">{{\n dialogTitle\n }}</kendo-dialog-titlebar>\n <ng-content></ng-content>\n <kendo-dialog-actions>\n <ng-container\n *ngTemplateOutlet=\"\n dialogBtnsTemplate || defaultDialogActionsTpl;\n context: dialogActionBtnsCtx\n \"\n >\n </ng-container>\n </kendo-dialog-actions>\n </kendo-dialog>\n\n <ng-template #defaultDialogActionsTpl>\n <button id=\"btnCancel\" class=\"k-button\" (click)=\"cancel()\">Cancel</button>\n <button id=\"btnSave\" class=\"k-button k-primary\" (click)=\"submit()\">\n {{ saveButtonText }}\n </button>\n </ng-template>`,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class DataEntryDialogComponent implements OnInit {\n @Input() public width: string | number = 800; //NOSONAR\n @Input() public height: string | number = 600; //NOSONAR\n /**\n * https://www.telerik.com/kendo-angular-ui/components/dialogs/dialog/initial-focus/\n */\n @Input() public autoFocusedElement?: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n @Input() public parentComponent?: BaseDataEntryComponent<any>; //NOSONAR\n @Input() public saveButtonText = 'Save';\n @ContentChild(DialogButtonsDirective, { static: true, read: TemplateRef })\n /**\n * Example Usage:\n * <imng-data-entry-dialog>\n * ......\n * <ng-template [imngDialogBtns] let-coreButtons>\n * <button id=\"btnCustom1\" class=\"k-button\" (click)=\"cancel()\">Close</button>\n * </ng-template>\n * </imng-data-entry-dialog>\n */\n public dialogBtnsTemplate?: TemplateRef<unknown>;\n public loading$?: Observable<boolean>;\n public addEditForm?: FormGroup;\n public submitted = false;\n public dialogTitle?: string;\n // eslint-disable-next-line @typescript-eslint/ban-types\n public component?: {};\n\n public ngOnInit(): void {\n if (!this.parentComponent) {\n throw new TypeError(`The input 'parentComponent' is required`);\n }\n this.dialogTitle = this.parentComponent.dialogTitle;\n this.loading$ = this.parentComponent.loading$;\n this.addEditForm = this.parentComponent.addEditForm;\n }\n\n public close(): void {\n this.parentComponent?.closeForm();\n }\n public cancel(): void {\n this.parentComponent?.onCancel();\n }\n public submit(): void {\n this.parentComponent?.onSubmit();\n }\n get dialogActionBtnsCtx(): object | null { //NOSONAR\n return {\n $implicit: { cancel: () => this.cancel(), submit: () => this.submit() },\n };\n }\n}\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { DataEntryDialogComponent } from './data-entry-dialog.component';\nimport { DialogButtonsDirective } from './dialog-buttons.directive';\nimport { DialogModule } from '@progress/kendo-angular-dialog';\n\n@NgModule({\n imports: [CommonModule, DialogModule],\n declarations: [DataEntryDialogComponent, DialogButtonsDirective],\n exports: [DataEntryDialogComponent, DialogButtonsDirective],\n})\nexport class ImngDataEntryDialogModule {}\n","import {\n Directive,\n Inject,\n InjectionToken,\n Input,\n OnDestroy,\n} from '@angular/core';\nimport { Observable, BehaviorSubject } from 'rxjs';\nimport { FormGroup, AbstractControl, ValidationErrors } from '@angular/forms';\nimport { IBaseDataEntryFacade } from './data-entry-facade';\nimport { Subscribable, Subscriptions } from 'imng-ngrx-utils';\n\nconst FACADE = new InjectionToken<IBaseDataEntryFacade>(\n 'imng-data-entry-facade'\n);\n\n/**\n * The extending class has to implement the following properties on ngInit\n * dialogTitle: string - This will be the text displayed at the top of the modal title bar\n * props: enum - This is a helper property to make the html markup type safe\n *\n * Along with the requirements above, the extending class has to set values to the\n * following properties on ngInit\n * active$: Observable<boolean> - This typically would be assigned to the isNewActive$ or isEditActive on the facade\n * addEditForm: FormGroup - This will be created by your component\n *\n * @class BaseDataEntryComponent>\n */\n@Directive()\nexport abstract class BaseDataEntryComponent<\n FACADE extends IBaseDataEntryFacade\n > implements OnDestroy, Subscribable {\n @Input() public width: string | number = 800; //NOSONAR\n @Input() public height: string | number = 600; //NOSONAR\n\n public allSubscriptions = new Subscriptions();\n public abstract dialogTitle: string;\n public abstract props: unknown;\n public addEditForm?: FormGroup;\n public loading$: Observable<boolean>;\n private readonly _submitted$: BehaviorSubject<boolean> = new BehaviorSubject(\n false as boolean\n );\n\n public get submitted$(): Observable<boolean> {\n return this._submitted$.asObservable();\n }\n // convenience getter for easy access to form fields\n public formControl(controlName: string): AbstractControl | undefined {\n return this.addEditForm?.controls[controlName];\n }\n public formControlErrors(controlName: string): ValidationErrors | undefined {\n return this.addEditForm?.controls[controlName].errors || undefined;\n }\n constructor(@Inject(FACADE) public readonly facade: FACADE) {\n this.loading$ = this.facade.loading$;\n this.initForm();\n }\n\n public ngOnDestroy(): void {\n this.allSubscriptions.unsubscribeAll();\n }\n\n public closeForm(): void {\n this.initForm();\n this.facade.clearCurrentEntity();\n this._submitted$.next(false);\n }\n\n public onCancel(): void {\n this.closeForm();\n }\n\n public onSubmit(): void {\n this._submitted$.next(true);\n\n // stop here if form is invalid\n if (this.isDataInvalid()) {\n console.error('form validation errors.'); //NOSONAR\n return;\n }\n this.save();\n this.closeForm();\n }\n\n public isDataInvalid(): boolean | undefined {\n return this.addEditForm?.invalid;\n }\n\n public abstract initForm(): void;\n public abstract save(): void;\n}\n","import { ValueType } from 'imng-nrsrx-client-utils';\nexport function updateStateCollectionItem<Entity extends { id?: ValueType }>(\n collection: Entity[],\n item: Entity\n): Entity[] {\n const items = [...collection];\n const index = collection.findIndex((val) => val.id === item.id);\n items.splice(index, 1, item);\n return items;\n}\n\nexport function removeStateCollectionItem<Entity extends { id?: ValueType }>(\n collection: Entity[],\n item: Entity\n): Entity[] {\n const items = [...collection];\n const index = collection.findIndex((val) => val.id === item.id);\n items.splice(index, 1);\n return items;\n}\n\nexport function addStateCollectionItem<Entity extends { id?: ValueType }>(\n collection: Entity[],\n item: Entity\n): Entity[] {\n const items = [...collection];\n items.unshift(item);\n return items;\n}\n","import { FormGroup } from '@angular/forms';\nimport { take, tap, filter } from 'rxjs/operators';\nimport { Observable } from 'rxjs';\n\nexport const formGroupPatcher = <TEntity>(addEditForm: FormGroup) => (source: Observable<TEntity>) =>\n source.pipe(\n filter(t => !!t),\n take(1),\n tap(t => addEditForm.patchValue(t)),\n );\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,159 @@
1
+ import { of } from 'rxjs';
2
+ import { readFirst } from 'imng-ngrx-utils/testing';
3
+ import { By } from '@angular/platform-browser';
4
+ import { BaseDataEntryComponent } from 'imng-kendo-data-entry';
5
+
6
+ // eslint-disable-next-line @typescript-eslint/ban-types
7
+ class DataEntryMockFacade {
8
+ constructor() {
9
+ this.loading$ = of(false);
10
+ // eslint-disable-next-line @typescript-eslint/ban-types
11
+ this.currentEntity$ = of(null);
12
+ this.isEditActive$ = of(false);
13
+ this.isNewActive$ = of(false);
14
+ this.setCurrentEntity = jest.fn();
15
+ this.clearCurrentEntity = jest.fn();
16
+ this.saveNewEntity = jest.fn();
17
+ this.updateExistingEntity = jest.fn();
18
+ }
19
+ }
20
+ function createDataEntryMockFacade(
21
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
+ mockFacade) {
23
+ const localFacade = new DataEntryMockFacade();
24
+ if (!mockFacade) {
25
+ return localFacade;
26
+ }
27
+ mockFacade.loading$ = mockFacade.loading$ || localFacade.loading$;
28
+ mockFacade.currentEntity$ =
29
+ mockFacade.currentEntity$ || localFacade.currentEntity$;
30
+ mockFacade.isEditActive$ =
31
+ mockFacade.isEditActive$ || localFacade.isEditActive$;
32
+ mockFacade.isNewActive$ = mockFacade.isNewActive$ || localFacade.isNewActive$;
33
+ mockFacade.setCurrentEntity = mockFacade.setCurrentEntity || jest.fn();
34
+ mockFacade.clearCurrentEntity = mockFacade.clearCurrentEntity || jest.fn();
35
+ mockFacade.saveNewEntity = mockFacade.saveNewEntity || jest.fn();
36
+ mockFacade.updateExistingEntity =
37
+ mockFacade.updateExistingEntity || jest.fn();
38
+ return mockFacade;
39
+ }
40
+
41
+ async function testAddSetAndClearCurrentEntity(facade) {
42
+ const entity = { name: '🆕' };
43
+ await validateInitialState(facade);
44
+ facade.setCurrentEntity(entity, { name: 'parentEntity' });
45
+ let status = await getEntityStatus(facade);
46
+ expect(status.currentEntity).toStrictEqual(entity);
47
+ expect(status.isEditActive).toBeFalsy();
48
+ expect(status.isNewActive).toBeTruthy();
49
+ facade.clearCurrentEntity();
50
+ status = await getEntityStatus(facade);
51
+ expect(status.currentEntity).toBeFalsy();
52
+ expect(status.isEditActive).toBeFalsy();
53
+ expect(status.isNewActive).toBeFalsy();
54
+ }
55
+ async function testEditSetAndClearCurrentEntity(facade) {
56
+ const entity = { id: '💃', name: '🧓👴👵' };
57
+ await validateInitialState(facade);
58
+ facade.setCurrentEntity(entity, { name: 'parentEntity' });
59
+ let status = await getEntityStatus(facade);
60
+ expect(status.currentEntity).toStrictEqual(entity);
61
+ expect(status.isEditActive).toBeTruthy();
62
+ expect(status.isNewActive).toBeFalsy();
63
+ facade.clearCurrentEntity();
64
+ status = await getEntityStatus(facade);
65
+ expect(status.currentEntity).toBeFalsy();
66
+ expect(status.isEditActive).toBeFalsy();
67
+ expect(status.isNewActive).toBeFalsy();
68
+ }
69
+ async function validateInitialState(facade) {
70
+ const status = await getEntityStatus(facade);
71
+ expect(status.currentEntity).toBeFalsy();
72
+ expect(status.isEditActive).toBeFalsy();
73
+ expect(status.isNewActive).toBeFalsy();
74
+ }
75
+ async function getEntityStatus(facade) {
76
+ return {
77
+ currentEntity: await readFirst(facade.currentEntity$),
78
+ isEditActive: await readFirst(facade.isEditActive$),
79
+ isNewActive: await readFirst(facade.isNewActive$),
80
+ };
81
+ }
82
+
83
+ async function testSaveCurrentEntity(facade, httpClient) {
84
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
85
+ const entity = { name: '🆕' };
86
+ httpClient.post = jest.fn(() => of(entity));
87
+ httpClient.put = jest.fn(() => of(entity));
88
+ httpClient.delete = jest.fn(() => of(entity));
89
+ facade.saveNewEntity(entity);
90
+ expect(httpClient.post).toBeCalledTimes(1);
91
+ expect(httpClient.put).toBeCalledTimes(0);
92
+ expect(httpClient.delete).toBeCalledTimes(0);
93
+ }
94
+ async function testUpdateCurrentEntity(facade, httpClient) {
95
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
96
+ const entity = { id: '💃', name: '🧓👴👵' };
97
+ httpClient.post = jest.fn(() => of(entity));
98
+ httpClient.put = jest.fn(() => of(entity));
99
+ httpClient.delete = jest.fn(() => of(entity));
100
+ facade.updateExistingEntity(entity);
101
+ expect(httpClient.put).toBeCalledTimes(1);
102
+ expect(httpClient.post).toBeCalledTimes(0);
103
+ expect(httpClient.delete).toBeCalledTimes(0);
104
+ }
105
+
106
+ async function testDeleteCurrentEntity(facade, httpClient) {
107
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
108
+ const entity = { id: '💃', name: '🧓👴👵' };
109
+ httpClient.post = jest.fn();
110
+ httpClient.put = jest.fn();
111
+ httpClient.delete = jest.fn(() => of(entity));
112
+ facade.deleteExistingEntity(entity);
113
+ expect(httpClient.put).toBeCalledTimes(0);
114
+ expect(httpClient.post).toBeCalledTimes(0);
115
+ expect(httpClient.delete).toBeCalledTimes(1);
116
+ }
117
+
118
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
119
+ class DataDeleteMockFacade {
120
+ constructor() {
121
+ this.deleteExistingEntity = jest.fn();
122
+ }
123
+ }
124
+ // eslint-disable-next-line @typescript-eslint/ban-types,@typescript-eslint/no-explicit-any
125
+ function createDataDeleteMockFacade(mockFacade) {
126
+ const localFacade = new DataDeleteMockFacade();
127
+ if (!mockFacade) {
128
+ return localFacade;
129
+ }
130
+ mockFacade.deleteExistingEntity = mockFacade.deleteExistingEntity || jest.fn();
131
+ return mockFacade;
132
+ }
133
+
134
+ function triggerSaveClickEvent(fixture) {
135
+ const typeAhead = fixture.debugElement.query(By.css('#btnSave'));
136
+ typeAhead.triggerEventHandler('click', {});
137
+ }
138
+ function triggerCancelClickEvent(fixture) {
139
+ const typeAhead = fixture.debugElement.query(By.css('#btnCancel'));
140
+ typeAhead.triggerEventHandler('click', {});
141
+ }
142
+
143
+ // eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
144
+ class MockDataEntryComponent extends BaseDataEntryComponent {
145
+ constructor() {
146
+ super(...arguments);
147
+ this.dialogTitle = 'MockDataEntryComponent';
148
+ this.props = {};
149
+ this.initForm = jest.fn();
150
+ this.save = () => jest.fn();
151
+ }
152
+ }
153
+
154
+ /**
155
+ * Generated bundle index. Do not edit.
156
+ */
157
+
158
+ export { DataDeleteMockFacade, DataEntryMockFacade, MockDataEntryComponent, createDataDeleteMockFacade, createDataEntryMockFacade, testAddSetAndClearCurrentEntity, testDeleteCurrentEntity, testEditSetAndClearCurrentEntity, testSaveCurrentEntity, testUpdateCurrentEntity, triggerCancelClickEvent, triggerSaveClickEvent };
159
+ //# sourceMappingURL=imng-kendo-data-entry-testing.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imng-kendo-data-entry-testing.mjs","sources":["../../../../libs/imng-kendo-data-entry/testing/src/data-entry-mock.facade.ts","../../../../libs/imng-kendo-data-entry/testing/src/data-entry-facade-tests.ts","../../../../libs/imng-kendo-data-entry/testing/src/data-entry-facade-http-tests.ts","../../../../libs/imng-kendo-data-entry/testing/src/data-delete-facade-http-tests.ts","../../../../libs/imng-kendo-data-entry/testing/src/data-delete-mock.facade.ts","../../../../libs/imng-kendo-data-entry/testing/src/test-trigger-event-helpers.ts","../../../../libs/imng-kendo-data-entry/testing/src/mock-data-entry-dialog.component.ts","../../../../libs/imng-kendo-data-entry/testing/src/imng-kendo-data-entry-testing.ts"],"sourcesContent":["import { Observable, of } from 'rxjs';\n// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries\nimport { IDataEntryFacade } from 'imng-kendo-data-entry';\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport class DataEntryMockFacade implements IDataEntryFacade<unknown> {\n public loading$: Observable<boolean> = of(false);\n // eslint-disable-next-line @typescript-eslint/ban-types\n public currentEntity$: Observable<unknown> = of(null);\n public isEditActive$: Observable<boolean> = of(false);\n public isNewActive$: Observable<boolean> = of(false);\n public setCurrentEntity = jest.fn();\n public clearCurrentEntity = jest.fn();\n public saveNewEntity = jest.fn();\n public updateExistingEntity = jest.fn();\n}\n\nexport function createDataEntryMockFacade(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n mockFacade?: IDataEntryFacade<unknown> | any\n): IDataEntryFacade<unknown> {\n const localFacade = new DataEntryMockFacade();\n if (!mockFacade) {\n return localFacade;\n }\n mockFacade.loading$ = mockFacade.loading$ || localFacade.loading$;\n mockFacade.currentEntity$ =\n mockFacade.currentEntity$ || localFacade.currentEntity$;\n mockFacade.isEditActive$ =\n mockFacade.isEditActive$ || localFacade.isEditActive$;\n mockFacade.isNewActive$ = mockFacade.isNewActive$ || localFacade.isNewActive$;\n mockFacade.setCurrentEntity = mockFacade.setCurrentEntity || jest.fn();\n mockFacade.clearCurrentEntity = mockFacade.clearCurrentEntity || jest.fn();\n mockFacade.saveNewEntity = mockFacade.saveNewEntity || jest.fn();\n mockFacade.updateExistingEntity =\n mockFacade.updateExistingEntity || jest.fn();\n return mockFacade;\n}\n","import { readFirst } from 'imng-ngrx-utils/testing';\nimport { Observable } from 'rxjs';\n\nexport async function testAddSetAndClearCurrentEntity<\n TFacade extends TestableFacade\n>(facade: TFacade): Promise<void> {\n const entity = { name: '🆕' };\n await validateInitialState(facade);\n\n facade.setCurrentEntity(entity, { name: 'parentEntity' });\n let status = await getEntityStatus(facade);\n expect(status.currentEntity).toStrictEqual(entity);\n expect(status.isEditActive).toBeFalsy();\n expect(status.isNewActive).toBeTruthy();\n\n facade.clearCurrentEntity();\n status = await getEntityStatus(facade);\n expect(status.currentEntity).toBeFalsy();\n expect(status.isEditActive).toBeFalsy();\n expect(status.isNewActive).toBeFalsy();\n}\n\nexport async function testEditSetAndClearCurrentEntity<\n TFacade extends TestableFacade\n>(facade: TFacade): Promise<void> {\n const entity = { id: '💃', name: '🧓👴👵' };\n await validateInitialState(facade);\n\n facade.setCurrentEntity(entity, { name: 'parentEntity' });\n let status = await getEntityStatus(facade);\n expect(status.currentEntity).toStrictEqual(entity);\n expect(status.isEditActive).toBeTruthy();\n expect(status.isNewActive).toBeFalsy();\n\n facade.clearCurrentEntity();\n status = await getEntityStatus(facade);\n expect(status.currentEntity).toBeFalsy();\n expect(status.isEditActive).toBeFalsy();\n expect(status.isNewActive).toBeFalsy();\n}\nasync function validateInitialState(facade: TestableFacade): Promise<void> {\n const status = await getEntityStatus(facade);\n expect(status.currentEntity).toBeFalsy();\n expect(status.isEditActive).toBeFalsy();\n expect(status.isNewActive).toBeFalsy();\n}\n\nasync function getEntityStatus<TFacade extends TestableFacade>(\n facade: TFacade\n): Promise<{\n currentEntity: unknown;\n isEditActive: unknown;\n isNewActive: unknown;\n}> {\n return {\n currentEntity: await readFirst(facade.currentEntity$),\n isEditActive: await readFirst(facade.isEditActive$),\n isNewActive: await readFirst(facade.isNewActive$),\n };\n}\n\nexport interface TestableFacade {\n currentEntity$: Observable<unknown>;\n isEditActive$: Observable<boolean | null>;\n isNewActive$: Observable<boolean | null>;\n setCurrentEntity(entity: unknown, parentEntity?: unknown): void;\n clearCurrentEntity(): void;\n}\n","import { HttpClient } from '@angular/common/http';\nimport { of } from 'rxjs';\n\nexport async function testSaveCurrentEntity<TFacade extends { saveNewEntity(entity: unknown): void; }>(\n facade: TFacade,\n httpClient: HttpClient,\n): Promise<void> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const entity: any = { name: '🆕' };\n httpClient.post = jest.fn(() => of(entity));\n httpClient.put = jest.fn(() => of(entity));\n httpClient.delete = jest.fn(() => of(entity));\n\n facade.saveNewEntity(entity);\n expect(httpClient.post).toBeCalledTimes(1);\n expect(httpClient.put).toBeCalledTimes(0);\n expect(httpClient.delete).toBeCalledTimes(0);\n}\n\nexport async function testUpdateCurrentEntity<TFacade extends { updateExistingEntity(entity: unknown): void; }>(\n facade: TFacade,\n httpClient: HttpClient,\n): Promise<void> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const entity: any = { id: '💃', name: '🧓👴👵' };\n\n httpClient.post = jest.fn(() => of(entity));\n httpClient.put = jest.fn(() => of(entity));\n httpClient.delete = jest.fn(() => of(entity));\n\n facade.updateExistingEntity(entity);\n expect(httpClient.put).toBeCalledTimes(1);\n expect(httpClient.post).toBeCalledTimes(0);\n expect(httpClient.delete).toBeCalledTimes(0);\n\n}\n","import { HttpClient } from '@angular/common/http';\nimport { of } from 'rxjs';\n\nexport async function testDeleteCurrentEntity<TFacade extends { deleteExistingEntity(entity: unknown): void; }>(\n facade: TFacade,\n httpClient: HttpClient,\n): Promise<void> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const entity: any = { id: '💃', name: '🧓👴👵' };\n\n httpClient.post = jest.fn();\n httpClient.put = jest.fn();\n httpClient.delete = jest.fn(() => of(entity));\n\n facade.deleteExistingEntity(entity);\n expect(httpClient.put).toBeCalledTimes(0);\n expect(httpClient.post).toBeCalledTimes(0);\n expect(httpClient.delete).toBeCalledTimes(1);\n\n}\n","// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries\nimport { IDataDeleteFacade } from 'imng-kendo-data-entry';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class DataDeleteMockFacade implements IDataDeleteFacade<any> {\n deleteExistingEntity = jest.fn();\n}\n\n// eslint-disable-next-line @typescript-eslint/ban-types,@typescript-eslint/no-explicit-any\nexport function createDataDeleteMockFacade(mockFacade?: IDataDeleteFacade<object> | any): IDataDeleteFacade<object> {\n const localFacade = new DataDeleteMockFacade();\n if (!mockFacade) {\n return localFacade;\n }\n mockFacade.deleteExistingEntity = mockFacade.deleteExistingEntity || jest.fn();\n return mockFacade;\n}\n","import { ComponentFixture } from '@angular/core/testing';\nimport { By } from '@angular/platform-browser';\n\nexport function triggerSaveClickEvent<TComponent>(fixture: ComponentFixture<TComponent>): void {\n const typeAhead = fixture.debugElement.query(By.css('#btnSave'));\n typeAhead.triggerEventHandler('click', {});\n}\nexport function triggerCancelClickEvent<TComponent>(fixture: ComponentFixture<TComponent>): void {\n const typeAhead = fixture.debugElement.query(By.css('#btnCancel'));\n typeAhead.triggerEventHandler('click', {});\n}\n","// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries\nimport { BaseDataEntryComponent } from 'imng-kendo-data-entry';\nimport { DataEntryMockFacade } from './data-entry-mock.facade';\n\nexport class MockDataEntryComponent extends BaseDataEntryComponent<DataEntryMockFacade> {\n public dialogTitle = 'MockDataEntryComponent';\n public props = {};\n public initForm = jest.fn();\n public save = () => jest.fn();\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;AAIA;MACa,mBAAmB,CAAA;AAAhC,IAAA,WAAA,GAAA;AACS,QAAA,IAAA,CAAA,QAAQ,GAAwB,EAAE,CAAC,KAAK,CAAC,CAAC;;AAE1C,QAAA,IAAA,CAAA,cAAc,GAAwB,EAAE,CAAC,IAAI,CAAC,CAAC;AAC/C,QAAA,IAAA,CAAA,aAAa,GAAwB,EAAE,CAAC,KAAK,CAAC,CAAC;AAC/C,QAAA,IAAA,CAAA,YAAY,GAAwB,EAAE,CAAC,KAAK,CAAC,CAAC;AAC9C,QAAA,IAAA,CAAA,gBAAgB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;AAC7B,QAAA,IAAA,CAAA,kBAAkB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;AAC/B,QAAA,IAAA,CAAA,aAAa,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;AAC1B,QAAA,IAAA,CAAA,oBAAoB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;KACzC;AAAA,CAAA;SAEe,yBAAyB;AACvC;AACA,UAA4C,EAAA;AAE5C,IAAA,MAAM,WAAW,GAAG,IAAI,mBAAmB,EAAE,CAAC;IAC9C,IAAI,CAAC,UAAU,EAAE;AACf,QAAA,OAAO,WAAW,CAAC;AACpB,KAAA;IACD,UAAU,CAAC,QAAQ,GAAG,UAAU,CAAC,QAAQ,IAAI,WAAW,CAAC,QAAQ,CAAC;AAClE,IAAA,UAAU,CAAC,cAAc;AACvB,QAAA,UAAU,CAAC,cAAc,IAAI,WAAW,CAAC,cAAc,CAAC;AAC1D,IAAA,UAAU,CAAC,aAAa;AACtB,QAAA,UAAU,CAAC,aAAa,IAAI,WAAW,CAAC,aAAa,CAAC;IACxD,UAAU,CAAC,YAAY,GAAG,UAAU,CAAC,YAAY,IAAI,WAAW,CAAC,YAAY,CAAC;IAC9E,UAAU,CAAC,gBAAgB,GAAG,UAAU,CAAC,gBAAgB,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;IACvE,UAAU,CAAC,kBAAkB,GAAG,UAAU,CAAC,kBAAkB,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;IAC3E,UAAU,CAAC,aAAa,GAAG,UAAU,CAAC,aAAa,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;AACjE,IAAA,UAAU,CAAC,oBAAoB;AAC7B,QAAA,UAAU,CAAC,oBAAoB,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;AAC/C,IAAA,OAAO,UAAU,CAAC;AACpB;;AClCO,eAAe,+BAA+B,CAEnD,MAAe,EAAA;AACf,IAAA,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAC9B,IAAA,MAAM,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAEnC,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;AAC1D,IAAA,IAAI,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACnD,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,EAAE,CAAC;IACxC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,UAAU,EAAE,CAAC;IAExC,MAAM,CAAC,kBAAkB,EAAE,CAAC;AAC5B,IAAA,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,SAAS,EAAE,CAAC;IACzC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,EAAE,CAAC;IACxC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,EAAE,CAAC;AACzC,CAAC;AAEM,eAAe,gCAAgC,CAEpD,MAAe,EAAA;IACf,MAAM,MAAM,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC5C,IAAA,MAAM,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAEnC,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;AAC1D,IAAA,IAAI,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACnD,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,UAAU,EAAE,CAAC;IACzC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,EAAE,CAAC;IAEvC,MAAM,CAAC,kBAAkB,EAAE,CAAC;AAC5B,IAAA,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,SAAS,EAAE,CAAC;IACzC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,EAAE,CAAC;IACxC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,EAAE,CAAC;AACzC,CAAC;AACD,eAAe,oBAAoB,CAAC,MAAsB,EAAA;AACxD,IAAA,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,SAAS,EAAE,CAAC;IACzC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,EAAE,CAAC;IACxC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,EAAE,CAAC;AACzC,CAAC;AAED,eAAe,eAAe,CAC5B,MAAe,EAAA;IAMf,OAAO;AACL,QAAA,aAAa,EAAE,MAAM,SAAS,CAAC,MAAM,CAAC,cAAc,CAAC;AACrD,QAAA,YAAY,EAAE,MAAM,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC;AACnD,QAAA,WAAW,EAAE,MAAM,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC;KAClD,CAAC;AACJ;;ACxDO,eAAe,qBAAqB,CACzC,MAAe,EACf,UAAsB,EAAA;;AAGtB,IAAA,MAAM,MAAM,GAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACnC,IAAA,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;AAC5C,IAAA,UAAU,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3C,IAAA,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;AAE9C,IAAA,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC3C,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC1C,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC;AAEM,eAAe,uBAAuB,CAC3C,MAAe,EACf,UAAsB,EAAA;;IAGtB,MAAM,MAAM,GAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAEjD,IAAA,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;AAC5C,IAAA,UAAU,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3C,IAAA,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;AAE9C,IAAA,MAAM,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC1C,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC3C,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AAE/C;;AChCO,eAAe,uBAAuB,CAC3C,MAAe,EACf,UAAsB,EAAA;;IAGtB,MAAM,MAAM,GAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAEjD,IAAA,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;AAC5B,IAAA,UAAU,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;AAC3B,IAAA,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;AAE9C,IAAA,MAAM,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC1C,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC3C,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AAE/C;;AChBA;MACa,oBAAoB,CAAA;AAAjC,IAAA,WAAA,GAAA;AACE,QAAA,IAAA,CAAA,oBAAoB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;KAClC;AAAA,CAAA;AAED;AACM,SAAU,0BAA0B,CAAC,UAA4C,EAAA;AACrF,IAAA,MAAM,WAAW,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC/C,IAAI,CAAC,UAAU,EAAE;AACf,QAAA,OAAO,WAAW,CAAC;AACpB,KAAA;IACD,UAAU,CAAC,oBAAoB,GAAG,UAAU,CAAC,oBAAoB,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;AAC/E,IAAA,OAAO,UAAU,CAAC;AACpB;;ACbM,SAAU,qBAAqB,CAAa,OAAqC,EAAA;AACrF,IAAA,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;AACjE,IAAA,SAAS,CAAC,mBAAmB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAC7C,CAAC;AACK,SAAU,uBAAuB,CAAa,OAAqC,EAAA;AACvF,IAAA,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;AACnE,IAAA,SAAS,CAAC,mBAAmB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAC7C;;ACVA;AAIM,MAAO,sBAAuB,SAAQ,sBAA2C,CAAA;AAAvF,IAAA,WAAA,GAAA;;QACS,IAAW,CAAA,WAAA,GAAG,wBAAwB,CAAC;QACvC,IAAK,CAAA,KAAA,GAAG,EAAE,CAAC;AACX,QAAA,IAAA,CAAA,QAAQ,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QACrB,IAAI,CAAA,IAAA,GAAG,MAAM,IAAI,CAAC,EAAE,EAAE,CAAC;KAC/B;AAAA;;ACTD;;AAEG;;;;"}