@dynamic-field-kit/angular 1.2.4 → 1.2.10

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 (55) hide show
  1. package/README.md +54 -46
  2. package/dist/README.md +126 -0
  3. package/dist/components/BaseInput.d.ts +22 -0
  4. package/{components → dist/components}/DynamicInput.d.ts +24 -28
  5. package/dist/components/FieldInput.d.ts +14 -0
  6. package/{components → dist/components}/MultiFieldInput.d.ts +23 -23
  7. package/dist/esm2022/components/BaseInput.mjs +60 -0
  8. package/dist/esm2022/components/DynamicInput.mjs +162 -0
  9. package/dist/esm2022/components/FieldInput.mjs +71 -0
  10. package/dist/esm2022/components/MultiFieldInput.mjs +85 -0
  11. package/{esm2020 → dist/esm2022}/dynamic-field-kit-angular.mjs +4 -4
  12. package/dist/esm2022/layout/defaultLayouts.mjs +67 -0
  13. package/{esm2020 → dist/esm2022}/layout/index.mjs +2 -2
  14. package/dist/esm2022/lib/dynamic-field-kit.module.mjs +52 -0
  15. package/{esm2020 → dist/esm2022}/public-api.mjs +14 -14
  16. package/{esm2020 → dist/esm2022}/types/layout.mjs +2 -2
  17. package/{fesm2020 → dist/fesm2022}/dynamic-field-kit-angular.mjs +434 -337
  18. package/dist/fesm2022/dynamic-field-kit-angular.mjs.map +1 -0
  19. package/{index.d.ts → dist/index.d.ts} +5 -5
  20. package/{layout → dist/layout}/defaultLayouts.d.ts +13 -13
  21. package/dist/layout/index.d.ts +1 -0
  22. package/{lib → dist/lib}/dynamic-field-kit.module.d.ts +11 -11
  23. package/{public-api.d.ts → dist/public-api.d.ts} +9 -9
  24. package/dist/types/layout.d.ts +1 -0
  25. package/ng-package.json +7 -0
  26. package/package.json +31 -28
  27. package/src/adapters/tailwind.ts +13 -0
  28. package/src/components/BaseInput.ts +31 -0
  29. package/src/components/DynamicInput.ts +188 -0
  30. package/src/components/FieldInput.ts +49 -0
  31. package/src/components/MultiFieldInput.ts +75 -0
  32. package/src/components/imports.ts +3 -0
  33. package/src/examples/index.ts +4 -0
  34. package/src/examples/registerExample.ts +7 -0
  35. package/src/examples/text-field.component.ts +18 -0
  36. package/src/layout/defaultLayouts.ts +38 -0
  37. package/src/layout/index.ts +1 -0
  38. package/src/lib/dynamic-field-kit.module.ts +29 -0
  39. package/src/public-api.ts +24 -0
  40. package/src/types/layout.ts +1 -0
  41. package/src/types.ts +1 -0
  42. package/tsconfig.json +13 -0
  43. package/components/BaseInput.d.ts +0 -22
  44. package/components/FieldInput.d.ts +0 -14
  45. package/esm2020/components/BaseInput.mjs +0 -46
  46. package/esm2020/components/DynamicInput.mjs +0 -146
  47. package/esm2020/components/FieldInput.mjs +0 -66
  48. package/esm2020/components/MultiFieldInput.mjs +0 -79
  49. package/esm2020/layout/defaultLayouts.mjs +0 -43
  50. package/esm2020/lib/dynamic-field-kit.module.mjs +0 -20
  51. package/fesm2015/dynamic-field-kit-angular.mjs +0 -393
  52. package/fesm2015/dynamic-field-kit-angular.mjs.map +0 -1
  53. package/fesm2020/dynamic-field-kit-angular.mjs.map +0 -1
  54. package/layout/index.d.ts +0 -1
  55. package/types/layout.d.ts +0 -1
package/README.md CHANGED
@@ -12,6 +12,10 @@ Demo app: https://github.com/vannt-dev/dynamic-field-kit-demo
12
12
  npm install @dynamic-field-kit/core @dynamic-field-kit/angular
13
13
  ```
14
14
 
15
+ Note: Core is shared runtime. Install core separately and ensure a single version is used across adapters to avoid duplicate registries.
16
+
17
+ - Install with core: `npm install @dynamic-field-kit/core @dynamic-field-kit/angular`
18
+
15
19
  If you need to pin versions explicitly:
16
20
 
17
21
  ```bash
@@ -26,37 +30,52 @@ npm install @dynamic-field-kit/core@^1.0.12 @dynamic-field-kit/angular@^1.2.3
26
30
  - `DynamicFieldKitModule`
27
31
  - `fieldRegistry`
28
32
 
29
- ## Basic setup
33
+ ## Basic setup (Angular 19+)
30
34
 
31
- 1. Import `DynamicFieldKitModule` in your Angular module.
35
+ 1. Import the component and register fields before bootstrap.
32
36
 
33
37
  ```ts
34
- import { BrowserModule } from "@angular/platform-browser"
35
- import { NgModule } from "@angular/core"
36
- import { DynamicFieldKitModule } from "@dynamic-field-kit/angular"
37
-
38
- @NgModule({
39
- imports: [BrowserModule, DynamicFieldKitModule],
40
- })
41
- export class AppModule {}
38
+ import 'zone.js';
39
+ import { bootstrapApplication } from '@angular/platform-browser';
40
+ import { fieldRegistry } from '@dynamic-field-kit/angular';
41
+ import { AppComponent } from './app/app.component';
42
+ import { TextFieldComponent } from './app/components/text-field.component';
43
+ import { NumberFieldComponent } from './app/components/number-field.component';
44
+
45
+ fieldRegistry.register('text', TextFieldComponent as any);
46
+ fieldRegistry.register('number', NumberFieldComponent as any);
47
+
48
+ bootstrapApplication(AppComponent, {
49
+ providers: [],
50
+ }).catch((err) => console.error(err));
42
51
  ```
43
52
 
44
- 2. Register Angular field components before bootstrap.
53
+ 2. Use the component in a standalone component.
45
54
 
46
55
  ```ts
47
- import "zone.js"
48
- import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"
49
- import { fieldRegistry } from "@dynamic-field-kit/angular"
50
- import { AppModule } from "./app/app.module"
51
- import { TextFieldComponent } from "./app/components/text-field.component"
52
- import { NumberFieldComponent } from "./app/components/number-field.component"
53
-
54
- fieldRegistry.register("text", TextFieldComponent as any)
55
- fieldRegistry.register("number", NumberFieldComponent as any)
56
-
57
- platformBrowserDynamic()
58
- .bootstrapModule(AppModule)
59
- .catch((err) => console.error(err))
56
+ import { Component } from '@angular/core';
57
+ import { CommonModule } from '@angular/common';
58
+ import { FieldDescription } from '@dynamic-field-kit/core';
59
+ import { MultiFieldInput } from '@dynamic-field-kit/angular';
60
+
61
+ @Component({
62
+ selector: 'app-root',
63
+ standalone: true,
64
+ imports: [CommonModule, MultiFieldInput],
65
+ templateUrl: './app.component.html',
66
+ })
67
+ export class AppComponent {
68
+ fields: FieldDescription[] = [
69
+ { name: 'name', type: 'text', label: 'Name' },
70
+ { name: 'age', type: 'number', label: 'Age' },
71
+ ];
72
+
73
+ data: any = {};
74
+
75
+ onChange(data: any) {
76
+ this.data = data;
77
+ }
78
+ }
60
79
  ```
61
80
 
62
81
  3. Render your schema in a template.
@@ -69,39 +88,28 @@ platformBrowserDynamic()
69
88
  ></dfk-multi-field-input>
70
89
  ```
71
90
 
72
- 4. Define your field schema in the component.
91
+ ## Legacy setup (Angular 14 and earlier with NgModule)
73
92
 
74
93
  ```ts
75
- import { Component } from "@angular/core"
76
- import { FieldDescription } from "@dynamic-field-kit/core"
94
+ import { BrowserModule } from '@angular/platform-browser';
95
+ import { NgModule } from '@angular/core';
96
+ import { DynamicFieldKitModule } from '@dynamic-field-kit/angular';
77
97
 
78
- @Component({
79
- selector: "app-root",
80
- templateUrl: "./app.component.html",
98
+ @NgModule({
99
+ imports: [BrowserModule, DynamicFieldKitModule],
81
100
  })
82
- export class AppComponent {
83
- fields: FieldDescription[] = [
84
- { name: "name", type: "text", label: "Name" },
85
- { name: "age", type: "number", label: "Age" },
86
- ]
87
-
88
- data: any = {}
89
-
90
- onChange(data: any) {
91
- this.data = data
92
- }
93
- }
101
+ export class AppModule {}
94
102
  ```
95
103
 
96
104
  ## Type augmentation
97
105
 
98
106
  ```ts
99
- import "@dynamic-field-kit/core"
107
+ import '@dynamic-field-kit/core';
100
108
 
101
- declare module "@dynamic-field-kit/core" {
109
+ declare module '@dynamic-field-kit/core' {
102
110
  interface FieldTypeMap {
103
- text: string
104
- number: number
111
+ text: string;
112
+ number: number;
105
113
  }
106
114
  }
107
115
  ```
package/dist/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # @dynamic-field-kit/angular
2
+
3
+ Angular adapter for `@dynamic-field-kit/core`.
4
+
5
+ This package provides Angular components and a convenience module that render field schemas defined with `@dynamic-field-kit/core`.
6
+
7
+ Demo app: https://github.com/vannt-dev/dynamic-field-kit-demo
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install @dynamic-field-kit/core @dynamic-field-kit/angular
13
+ ```
14
+
15
+ Note: Core is shared runtime. Install core separately and ensure a single version is used across adapters to avoid duplicate registries.
16
+
17
+ - Install with core: `npm install @dynamic-field-kit/core @dynamic-field-kit/angular`
18
+
19
+ If you need to pin versions explicitly:
20
+
21
+ ```bash
22
+ npm install @dynamic-field-kit/core@^1.0.12 @dynamic-field-kit/angular@^1.2.3
23
+ ```
24
+
25
+ ## What it exports
26
+
27
+ - `DynamicInput`
28
+ - `FieldInput`
29
+ - `MultiFieldInput`
30
+ - `DynamicFieldKitModule`
31
+ - `fieldRegistry`
32
+
33
+ ## Basic setup (Angular 19+)
34
+
35
+ 1. Import the component and register fields before bootstrap.
36
+
37
+ ```ts
38
+ import 'zone.js';
39
+ import { bootstrapApplication } from '@angular/platform-browser';
40
+ import { fieldRegistry } from '@dynamic-field-kit/angular';
41
+ import { AppComponent } from './app/app.component';
42
+ import { TextFieldComponent } from './app/components/text-field.component';
43
+ import { NumberFieldComponent } from './app/components/number-field.component';
44
+
45
+ fieldRegistry.register('text', TextFieldComponent as any);
46
+ fieldRegistry.register('number', NumberFieldComponent as any);
47
+
48
+ bootstrapApplication(AppComponent, {
49
+ providers: [],
50
+ }).catch((err) => console.error(err));
51
+ ```
52
+
53
+ 2. Use the component in a standalone component.
54
+
55
+ ```ts
56
+ import { Component } from '@angular/core';
57
+ import { CommonModule } from '@angular/common';
58
+ import { FieldDescription } from '@dynamic-field-kit/core';
59
+ import { MultiFieldInput } from '@dynamic-field-kit/angular';
60
+
61
+ @Component({
62
+ selector: 'app-root',
63
+ standalone: true,
64
+ imports: [CommonModule, MultiFieldInput],
65
+ templateUrl: './app.component.html',
66
+ })
67
+ export class AppComponent {
68
+ fields: FieldDescription[] = [
69
+ { name: 'name', type: 'text', label: 'Name' },
70
+ { name: 'age', type: 'number', label: 'Age' },
71
+ ];
72
+
73
+ data: any = {};
74
+
75
+ onChange(data: any) {
76
+ this.data = data;
77
+ }
78
+ }
79
+ ```
80
+
81
+ 3. Render your schema in a template.
82
+
83
+ ```html
84
+ <dfk-multi-field-input
85
+ [fieldDescriptions]="fields"
86
+ [properties]="data"
87
+ (onChange)="onChange($event)"
88
+ ></dfk-multi-field-input>
89
+ ```
90
+
91
+ ## Legacy setup (Angular 14 and earlier with NgModule)
92
+
93
+ ```ts
94
+ import { BrowserModule } from '@angular/platform-browser';
95
+ import { NgModule } from '@angular/core';
96
+ import { DynamicFieldKitModule } from '@dynamic-field-kit/angular';
97
+
98
+ @NgModule({
99
+ imports: [BrowserModule, DynamicFieldKitModule],
100
+ })
101
+ export class AppModule {}
102
+ ```
103
+
104
+ ## Type augmentation
105
+
106
+ ```ts
107
+ import '@dynamic-field-kit/core';
108
+
109
+ declare module '@dynamic-field-kit/core' {
110
+ interface FieldTypeMap {
111
+ text: string;
112
+ number: number;
113
+ }
114
+ }
115
+ ```
116
+
117
+ ## Notes
118
+
119
+ - Register Angular component classes in `fieldRegistry`.
120
+ - Do not register React or Vue renderers in the Angular adapter.
121
+ - `MultiFieldInput` supports `column`, `row`, and `grid` layouts.
122
+ - The shared schema and field types still come from `@dynamic-field-kit/core`.
123
+
124
+ ## License
125
+
126
+ MIT
@@ -0,0 +1,22 @@
1
+ import { ChangeDetectorRef, EventEmitter } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export declare abstract class BaseInputComponent {
4
+ protected cdr: ChangeDetectorRef;
5
+ value?: any;
6
+ label?: string;
7
+ placeholder?: string;
8
+ required?: boolean;
9
+ disabled?: boolean;
10
+ options?: any[];
11
+ className?: string;
12
+ description?: string;
13
+ errorMessage?: string;
14
+ acceptFile?: string;
15
+ maxLength?: number;
16
+ minNumber?: number;
17
+ maxNumber?: number;
18
+ valueChange: EventEmitter<any>;
19
+ constructor(cdr: ChangeDetectorRef);
20
+ static ɵfac: i0.ɵɵFactoryDeclaration<BaseInputComponent, never>;
21
+ static ɵcmp: i0.ɵɵComponentDeclaration<BaseInputComponent, "ng-component", never, { "value": { "alias": "value"; "required": false; }; "label": { "alias": "label"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "required": { "alias": "required"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "options": { "alias": "options"; "required": false; }; "className": { "alias": "className"; "required": false; }; "description": { "alias": "description"; "required": false; }; "errorMessage": { "alias": "errorMessage"; "required": false; }; "acceptFile": { "alias": "acceptFile"; "required": false; }; "maxLength": { "alias": "maxLength"; "required": false; }; "minNumber": { "alias": "minNumber"; "required": false; }; "maxNumber": { "alias": "maxNumber"; "required": false; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
22
+ }
@@ -1,28 +1,24 @@
1
- import { EventEmitter, ViewContainerRef, OnChanges, AfterViewInit, SimpleChanges } from "@angular/core";
2
- import { FieldTypeKey } from "@dynamic-field-kit/core";
3
- import { BaseInputComponent } from "./BaseInput";
4
- import * as i0 from "@angular/core";
5
- export declare class DynamicInput extends BaseInputComponent implements OnChanges, AfterViewInit {
6
- type: FieldTypeKey;
7
- value?: any;
8
- label?: string;
9
- placeholder?: string;
10
- required?: boolean;
11
- options?: any[];
12
- className?: string;
13
- description?: any;
14
- valueChange: EventEmitter<any>;
15
- onChange: EventEmitter<any>;
16
- host: ViewContainerRef;
17
- private compRef?;
18
- private inputInstance?;
19
- ngOnChanges(changes: SimpleChanges): void;
20
- ngAfterViewInit(): void;
21
- private render;
22
- private applyKnownProps;
23
- private bindOutput;
24
- private emitValue;
25
- private cleanupRenderedComponent;
26
- static ɵfac: i0.ɵɵFactoryDeclaration<DynamicInput, never>;
27
- static ɵcmp: i0.ɵɵComponentDeclaration<DynamicInput, "dfk-dynamic-input", never, { "type": "type"; "value": "value"; "label": "label"; "placeholder": "placeholder"; "required": "required"; "options": "options"; "className": "className"; "description": "description"; }, { "valueChange": "valueChange"; "onChange": "onChange"; }, never, never, true, never>;
28
- }
1
+ import { EventEmitter, ViewContainerRef, OnChanges, AfterViewInit, OnDestroy, SimpleChanges } from '@angular/core';
2
+ import { FieldTypeKey } from '@dynamic-field-kit/core';
3
+ import { BaseInputComponent } from './BaseInput';
4
+ import * as i0 from "@angular/core";
5
+ export declare class DynamicInput extends BaseInputComponent implements OnChanges, AfterViewInit, OnDestroy {
6
+ type: FieldTypeKey;
7
+ valueChange: EventEmitter<any>;
8
+ onChange: EventEmitter<any>;
9
+ host: ViewContainerRef;
10
+ private compRef?;
11
+ private inputInstance?;
12
+ private subscriptions;
13
+ ngOnChanges(changes: SimpleChanges): void;
14
+ ngAfterViewInit(): void;
15
+ ngOnDestroy(): void;
16
+ private cleanupSubscriptions;
17
+ private render;
18
+ private applyKnownProps;
19
+ private bindOutput;
20
+ private emitValue;
21
+ private cleanupRenderedComponent;
22
+ static ɵfac: i0.ɵɵFactoryDeclaration<DynamicInput, never>;
23
+ static ɵcmp: i0.ɵɵComponentDeclaration<DynamicInput, "dfk-dynamic-input", never, { "type": { "alias": "type"; "required": false; }; }, { "valueChange": "valueChange"; "onChange": "onChange"; }, never, never, true, never>;
24
+ }
@@ -0,0 +1,14 @@
1
+ import { EventEmitter } from '@angular/core';
2
+ import { FieldDescription, Properties } from '@dynamic-field-kit/core';
3
+ import * as i0 from "@angular/core";
4
+ export declare class FieldInput {
5
+ fieldDescription?: FieldDescription;
6
+ renderInfos?: Properties;
7
+ onValueChangeField: EventEmitter<{
8
+ value: any;
9
+ key: string;
10
+ }>;
11
+ getFieldValue(): unknown;
12
+ static ɵfac: i0.ɵɵFactoryDeclaration<FieldInput, never>;
13
+ static ɵcmp: i0.ɵɵComponentDeclaration<FieldInput, "dfk-field-input", never, { "fieldDescription": { "alias": "fieldDescription"; "required": false; }; "renderInfos": { "alias": "renderInfos"; "required": false; }; }, { "onValueChangeField": "onValueChangeField"; }, never, never, true, never>;
14
+ }
@@ -1,23 +1,23 @@
1
- import { EventEmitter, OnChanges, OnInit, SimpleChanges } from "@angular/core";
2
- import { FieldDescription, Properties } from "@dynamic-field-kit/core";
3
- import { LayoutConfig } from "../types/layout";
4
- import * as i0 from "@angular/core";
5
- export declare class MultiFieldInput implements OnInit, OnChanges {
6
- fieldDescriptions: FieldDescription[];
7
- properties?: Properties;
8
- onChange: EventEmitter<Properties>;
9
- layout: LayoutConfig;
10
- data: Properties;
11
- visibleFields: FieldDescription[];
12
- trackByFn(index: number, field: FieldDescription): string | number;
13
- ngOnInit(): void;
14
- ngOnChanges(_changes: SimpleChanges): void;
15
- private init;
16
- private updateVisibleFields;
17
- onFieldChange(event: {
18
- value: any;
19
- key: string;
20
- }): void;
21
- static ɵfac: i0.ɵɵFactoryDeclaration<MultiFieldInput, never>;
22
- static ɵcmp: i0.ɵɵComponentDeclaration<MultiFieldInput, "dfk-multi-field-input", never, { "fieldDescriptions": "fieldDescriptions"; "properties": "properties"; "layout": "layout"; }, { "onChange": "onChange"; }, never, never, true, never>;
23
- }
1
+ import { EventEmitter, OnChanges, OnInit, SimpleChanges } from '@angular/core';
2
+ import { FieldDescription, Properties } from '@dynamic-field-kit/core';
3
+ import { LayoutConfig } from '../types/layout';
4
+ import * as i0 from "@angular/core";
5
+ export declare class MultiFieldInput implements OnInit, OnChanges {
6
+ fieldDescriptions: FieldDescription[];
7
+ properties?: Properties;
8
+ onChange: EventEmitter<Properties>;
9
+ layout: LayoutConfig;
10
+ data: Properties;
11
+ visibleFields: FieldDescription[];
12
+ trackByFn(index: number, field: FieldDescription): string | number;
13
+ ngOnInit(): void;
14
+ ngOnChanges(_changes: SimpleChanges): void;
15
+ private init;
16
+ private updateVisibleFields;
17
+ onFieldChange(event: {
18
+ value: any;
19
+ key: string;
20
+ }): void;
21
+ static ɵfac: i0.ɵɵFactoryDeclaration<MultiFieldInput, never>;
22
+ static ɵcmp: i0.ɵɵComponentDeclaration<MultiFieldInput, "dfk-multi-field-input", never, { "fieldDescriptions": { "alias": "fieldDescriptions"; "required": false; }; "properties": { "alias": "properties"; "required": false; }; "layout": { "alias": "layout"; "required": false; }; }, { "onChange": "onChange"; }, never, never, true, never>;
23
+ }
@@ -0,0 +1,60 @@
1
+ import { Component, EventEmitter, Input, Output, } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export class BaseInputComponent {
4
+ cdr;
5
+ value;
6
+ label;
7
+ placeholder;
8
+ required;
9
+ disabled;
10
+ options;
11
+ className;
12
+ description;
13
+ errorMessage;
14
+ acceptFile;
15
+ maxLength;
16
+ minNumber;
17
+ maxNumber;
18
+ // Add more from mplis as needed
19
+ valueChange = new EventEmitter();
20
+ constructor(cdr) {
21
+ this.cdr = cdr;
22
+ }
23
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: BaseInputComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
24
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.20", type: BaseInputComponent, isStandalone: true, selector: "ng-component", inputs: { value: "value", label: "label", placeholder: "placeholder", required: "required", disabled: "disabled", options: "options", className: "className", description: "description", errorMessage: "errorMessage", acceptFile: "acceptFile", maxLength: "maxLength", minNumber: "minNumber", maxNumber: "maxNumber" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: '', isInline: true });
25
+ }
26
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: BaseInputComponent, decorators: [{
27
+ type: Component,
28
+ args: [{
29
+ template: '',
30
+ }]
31
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { value: [{
32
+ type: Input
33
+ }], label: [{
34
+ type: Input
35
+ }], placeholder: [{
36
+ type: Input
37
+ }], required: [{
38
+ type: Input
39
+ }], disabled: [{
40
+ type: Input
41
+ }], options: [{
42
+ type: Input
43
+ }], className: [{
44
+ type: Input
45
+ }], description: [{
46
+ type: Input
47
+ }], errorMessage: [{
48
+ type: Input
49
+ }], acceptFile: [{
50
+ type: Input
51
+ }], maxLength: [{
52
+ type: Input
53
+ }], minNumber: [{
54
+ type: Input
55
+ }], maxNumber: [{
56
+ type: Input
57
+ }], valueChange: [{
58
+ type: Output
59
+ }] } });
60
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQmFzZUlucHV0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvQmFzZUlucHV0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCxTQUFTLEVBQ1QsWUFBWSxFQUNaLEtBQUssRUFDTCxNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7O0FBS3ZCLE1BQU0sT0FBZ0Isa0JBQWtCO0lBa0JoQjtJQWpCYixLQUFLLENBQU87SUFDWixLQUFLLENBQVU7SUFDZixXQUFXLENBQVU7SUFDckIsUUFBUSxDQUFXO0lBQ25CLFFBQVEsQ0FBVztJQUNuQixPQUFPLENBQVM7SUFDaEIsU0FBUyxDQUFVO0lBQ25CLFdBQVcsQ0FBVTtJQUNyQixZQUFZLENBQVU7SUFDdEIsVUFBVSxDQUFVO0lBQ3BCLFNBQVMsQ0FBVTtJQUNuQixTQUFTLENBQVU7SUFDbkIsU0FBUyxDQUFVO0lBQzVCLGdDQUFnQztJQUV0QixXQUFXLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztJQUVoRCxZQUFzQixHQUFzQjtRQUF0QixRQUFHLEdBQUgsR0FBRyxDQUFtQjtJQUFHLENBQUM7d0dBbEI1QixrQkFBa0I7NEZBQWxCLGtCQUFrQiw2YUFGNUIsRUFBRTs7NEZBRVEsa0JBQWtCO2tCQUh2QyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxFQUFFO2lCQUNiO3NGQUVVLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBR0ksV0FBVztzQkFBcEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE91dHB1dCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBDb21wb25lbnQoe1xuICB0ZW1wbGF0ZTogJycsXG59KVxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEJhc2VJbnB1dENvbXBvbmVudCB7XG4gIEBJbnB1dCgpIHZhbHVlPzogYW55O1xuICBASW5wdXQoKSBsYWJlbD86IHN0cmluZztcbiAgQElucHV0KCkgcGxhY2Vob2xkZXI/OiBzdHJpbmc7XG4gIEBJbnB1dCgpIHJlcXVpcmVkPzogYm9vbGVhbjtcbiAgQElucHV0KCkgZGlzYWJsZWQ/OiBib29sZWFuO1xuICBASW5wdXQoKSBvcHRpb25zPzogYW55W107XG4gIEBJbnB1dCgpIGNsYXNzTmFtZT86IHN0cmluZztcbiAgQElucHV0KCkgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gIEBJbnB1dCgpIGVycm9yTWVzc2FnZT86IHN0cmluZztcbiAgQElucHV0KCkgYWNjZXB0RmlsZT86IHN0cmluZztcbiAgQElucHV0KCkgbWF4TGVuZ3RoPzogbnVtYmVyO1xuICBASW5wdXQoKSBtaW5OdW1iZXI/OiBudW1iZXI7XG4gIEBJbnB1dCgpIG1heE51bWJlcj86IG51bWJlcjtcbiAgLy8gQWRkIG1vcmUgZnJvbSBtcGxpcyBhcyBuZWVkZWRcblxuICBAT3V0cHV0KCkgdmFsdWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZikge31cbn1cbiJdfQ==
@@ -0,0 +1,162 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { Component, Input, Output, EventEmitter, ViewChild, ViewContainerRef, SimpleChange, } from '@angular/core';
3
+ import { fieldRegistry } from '@dynamic-field-kit/core';
4
+ import { BaseInputComponent } from './BaseInput';
5
+ import * as i0 from "@angular/core";
6
+ export class DynamicInput extends BaseInputComponent {
7
+ type;
8
+ valueChange = new EventEmitter();
9
+ onChange = new EventEmitter(); // backward compat
10
+ host;
11
+ compRef;
12
+ inputInstance;
13
+ subscriptions = [];
14
+ ngOnChanges(changes) {
15
+ if (changes['type'] && !changes['type'].firstChange && this.host) {
16
+ this.render();
17
+ return;
18
+ }
19
+ if (this.inputInstance) {
20
+ this.applyKnownProps(this.inputInstance);
21
+ const childChanges = {};
22
+ for (const prop in changes) {
23
+ childChanges[prop] = new SimpleChange(changes[prop].previousValue, changes[prop].currentValue, changes[prop].firstChange);
24
+ }
25
+ this.inputInstance.ngOnChanges?.(childChanges);
26
+ this.compRef?.changeDetectorRef.detectChanges();
27
+ }
28
+ else if (this.host) {
29
+ this.render();
30
+ }
31
+ }
32
+ ngAfterViewInit() {
33
+ this.render();
34
+ }
35
+ ngOnDestroy() {
36
+ this.cleanupSubscriptions();
37
+ this.cleanupRenderedComponent();
38
+ }
39
+ cleanupSubscriptions() {
40
+ this.subscriptions.forEach((s) => s.unsubscribe());
41
+ this.subscriptions = [];
42
+ }
43
+ render() {
44
+ const Renderer = fieldRegistry.get(this.type);
45
+ this.cleanupRenderedComponent();
46
+ this.cleanupSubscriptions();
47
+ this.host.clear();
48
+ if (!Renderer) {
49
+ const el = document.createElement('div');
50
+ el.textContent = `Unknown field type: ${this.type}`;
51
+ this.host.element.nativeElement.appendChild(el);
52
+ return;
53
+ }
54
+ try {
55
+ const compType = Renderer;
56
+ const compRef = this.host.createComponent(compType);
57
+ const instance = compRef.instance;
58
+ if (!instance) {
59
+ throw new Error(`Failed to create instance for ${this.type}`);
60
+ }
61
+ this.applyKnownProps(instance);
62
+ const subA = this.bindOutput(instance, 'valueChange');
63
+ if (subA) {
64
+ this.subscriptions.push(subA);
65
+ }
66
+ const subB = this.bindOutput(instance, 'onValueChange');
67
+ if (subB) {
68
+ this.subscriptions.push(subB);
69
+ }
70
+ instance.changeDetectorRef?.detectChanges();
71
+ this.compRef = compRef;
72
+ this.inputInstance = instance;
73
+ compRef.changeDetectorRef.detectChanges();
74
+ }
75
+ catch (err) {
76
+ // Fallback to function renderer
77
+ try {
78
+ const props = {
79
+ value: this.value,
80
+ onValueChange: (v) => this.emitValue(v),
81
+ label: this.label,
82
+ placeholder: this.placeholder,
83
+ required: this.required,
84
+ options: this.options,
85
+ className: this.className,
86
+ description: this.description,
87
+ disabled: this.disabled,
88
+ errorMessage: this.errorMessage,
89
+ };
90
+ const out = Renderer(props);
91
+ if (typeof out === 'string') {
92
+ const el = document.createElement('div');
93
+ el.innerHTML = out;
94
+ this.host.element.nativeElement.appendChild(el);
95
+ }
96
+ }
97
+ catch (e) {
98
+ const el = document.createElement('div');
99
+ el.textContent = `Failed to render field: ${this.type}`;
100
+ this.host.element.nativeElement.appendChild(el);
101
+ }
102
+ }
103
+ }
104
+ applyKnownProps(instance) {
105
+ const knownProps = [
106
+ 'value',
107
+ 'label',
108
+ 'placeholder',
109
+ 'required',
110
+ 'disabled',
111
+ 'options',
112
+ 'className',
113
+ 'description',
114
+ 'errorMessage',
115
+ ];
116
+ for (const prop of knownProps) {
117
+ if (prop in this && prop in instance) {
118
+ instance[prop] = this[prop];
119
+ }
120
+ }
121
+ }
122
+ bindOutput(instance, outputName) {
123
+ const output = instance?.[outputName];
124
+ if (!output || typeof output.subscribe !== 'function') {
125
+ return;
126
+ }
127
+ const sub = output.subscribe((value) => {
128
+ this.emitValue(value);
129
+ });
130
+ return sub;
131
+ }
132
+ emitValue(value) {
133
+ this.valueChange.emit(value);
134
+ this.onChange.emit(value);
135
+ }
136
+ cleanupRenderedComponent() {
137
+ this.compRef?.destroy();
138
+ this.compRef = undefined;
139
+ this.inputInstance = undefined;
140
+ }
141
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: DynamicInput, deps: null, target: i0.ɵɵFactoryTarget.Component });
142
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.20", type: DynamicInput, isStandalone: true, selector: "dfk-dynamic-input", inputs: { type: "type" }, outputs: { valueChange: "valueChange", onChange: "onChange" }, viewQueries: [{ propertyName: "host", first: true, predicate: ["host"], descendants: true, read: ViewContainerRef }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: `<div #host style="display: contents;"></div>`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }] });
143
+ }
144
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: DynamicInput, decorators: [{
145
+ type: Component,
146
+ args: [{
147
+ selector: 'dfk-dynamic-input',
148
+ standalone: true,
149
+ imports: [CommonModule],
150
+ template: `<div #host style="display: contents;"></div>`,
151
+ }]
152
+ }], propDecorators: { type: [{
153
+ type: Input
154
+ }], valueChange: [{
155
+ type: Output
156
+ }], onChange: [{
157
+ type: Output
158
+ }], host: [{
159
+ type: ViewChild,
160
+ args: ['host', { read: ViewContainerRef, static: false }]
161
+ }] } });
162
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRHluYW1pY0lucHV0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvRHluYW1pY0lucHV0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQ0wsU0FBUyxFQUVULEtBQUssRUFDTCxNQUFNLEVBQ04sWUFBWSxFQUNaLFNBQVMsRUFDVCxnQkFBZ0IsRUFNaEIsWUFBWSxHQUNiLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxhQUFhLEVBQWdCLE1BQU0seUJBQXlCLENBQUM7QUFFdEUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sYUFBYSxDQUFDOztBQVFqRCxNQUFNLE9BQU8sWUFDWCxTQUFRLGtCQUFrQjtJQUdqQixJQUFJLENBQWdCO0lBQ1YsV0FBVyxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7SUFDL0MsUUFBUSxHQUFHLElBQUksWUFBWSxFQUFPLENBQUMsQ0FBQyxrQkFBa0I7SUFHaEUsSUFBSSxDQUFvQjtJQUNoQixPQUFPLENBQXFCO0lBQzVCLGFBQWEsQ0FBTztJQUNwQixhQUFhLEdBQW1CLEVBQUUsQ0FBQztJQUUzQyxXQUFXLENBQUMsT0FBc0I7UUFDaEMsSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNqRSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDZCxPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBRXpDLE1BQU0sWUFBWSxHQUFrQixFQUFFLENBQUM7WUFDdkMsS0FBSyxNQUFNLElBQUksSUFBSSxPQUFPLEVB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O0lBQzVCLENBQUM7SUFFTyx3QkFBd0I7UUFDOUIsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsT0FBTyxHQUFHLFNBQVMsQ0FBQztRQUN6QixJQUFJLENBQUMsYUFBYSxHQUFHLFNBQVMsQ0FBQztJQUNqQyxDQUFDO3dHQWhLVSxZQUFZOzRGQUFaLFlBQVksK09BUUksZ0JBQWdCLHlFQVZqQyw4Q0FBOEMsMkRBRDlDLFlBQVk7OzRGQUdYLFlBQVk7a0JBTnhCLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLG1CQUFtQjtvQkFDN0IsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLE9BQU8sRUFBRSxDQUFDLFlBQVksQ0FBQztvQkFDdkIsUUFBUSxFQUFFLDhDQUE4QztpQkFDekQ7OEJBS1UsSUFBSTtzQkFBWixLQUFLO2dCQUNhLFdBQVc7c0JBQTdCLE1BQU07Z0JBQ0csUUFBUTtzQkFBakIsTUFBTTtnQkFHUCxJQUFJO3NCQURILFNBQVM7dUJBQUMsTUFBTSxFQUFFLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBDb21wb25lbnRSZWYsXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIEV2ZW50RW1pdHRlcixcbiAgVmlld0NoaWxkLFxuICBWaWV3Q29udGFpbmVyUmVmLFxuICBPbkNoYW5nZXMsXG4gIEFmdGVyVmlld0luaXQsXG4gIE9uRGVzdHJveSxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVHlwZSxcbiAgU2ltcGxlQ2hhbmdlLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGZpZWxkUmVnaXN0cnksIEZpZWxkVHlwZUtleSB9IGZyb20gJ0BkeW5hbWljLWZpZWxkLWtpdC9jb3JlJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQmFzZUlucHV0Q29tcG9uZW50IH0gZnJvbSAnLi9CYXNlSW5wdXQnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdkZmstZHluYW1pYy1pbnB1dCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxuICB0ZW1wbGF0ZTogYDxkaXYgI2hvc3Qgc3R5bGU9XCJkaXNwbGF5OiBjb250ZW50cztcIj48L2Rpdj5gLFxufSlcbmV4cG9ydCBjbGFzcyBEeW5hbWljSW5wdXRcbiAgZXh0ZW5kcyBCYXNlSW5wdXRDb21wb25lbnRcbiAgaW1wbGVtZW50cyBPbkNoYW5nZXMsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveVxue1xuICBASW5wdXQoKSB0eXBlITogRmllbGRUeXBlS2V5O1xuICBAT3V0cHV0KCkgb3ZlcnJpZGUgdmFsdWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgQE91dHB1dCgpIG9uQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7IC8vIGJhY2t3YXJkIGNvbXBhdFxuXG4gIEBWaWV3Q2hpbGQoJ2hvc3QnLCB7IHJlYWQ6IFZpZXdDb250YWluZXJSZWYsIHN0YXRpYzogZmFsc2UgfSlcbiAgaG9zdCE6IFZpZXdDb250YWluZXJSZWY7XG4gIHByaXZhdGUgY29tcFJlZj86IENvbXBvbmVudFJlZjxhbnk+O1xuICBwcml2YXRlIGlucHV0SW5zdGFuY2U/OiBhbnk7XG4gIHByaXZhdGUgc3Vic2NyaXB0aW9uczogU3Vic2NyaXB0aW9uW10gPSBbXTtcblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgaWYgKGNoYW5nZXNbJ3R5cGUnXSAmJiAhY2hhbmdlc1sndHlwZSddLmZpcnN0Q2hhbmdlICYmIHRoaXMuaG9zdCkge1xuICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pbnB1dEluc3RhbmNlKSB7XG4gICAgICB0aGlzLmFwcGx5S25vd25Qcm9wcyh0aGlzLmlucHV0SW5zdGFuY2UpO1xuXG4gICAgICBjb25zdCBjaGlsZENoYW5nZXM6IFNpbXBsZUNoYW5nZXMgPSB7fTtcbiAgICAgIGZvciAoY29uc3QgcHJvcCBpbiBjaGFuZ2VzKSB7XG4gICAgICAgIGNoaWxkQ2hhbmdlc1twcm9wXSA9IG5ldyBTaW1wbGVDaGFuZ2UoXG4gICAgICAgICAgY2hhbmdlc1twcm9wXS5wcmV2aW91c1ZhbHVlLFxuICAgICAgICAgIGNoYW5nZXNbcHJvcF0uY3VycmVudFZhbHVlLFxuICAgICAgICAgIGNoYW5nZXNbcHJvcF0uZmlyc3RDaGFuZ2VcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5pbnB1dEluc3RhbmNlLm5nT25DaGFuZ2VzPy4oY2hpbGRDaGFuZ2VzKTtcbiAgICAgIHRoaXMuY29tcFJlZj8uY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5ob3N0KSB7XG4gICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH1cbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5jbGVhbnVwU3Vic2NyaXB0aW9ucygpO1xuICAgIHRoaXMuY2xlYW51cFJlbmRlcmVkQ29tcG9uZW50KCk7XG4gIH1cblxuICBwcml2YXRlIGNsZWFudXBTdWJzY3JpcHRpb25zKCkge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5mb3JFYWNoKChzKSA9PiBzLnVuc3Vic2NyaWJlKCkpO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucyA9IFtdO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXIoKSB7XG4gICAgY29uc3QgUmVuZGVyZXIgPSBmaWVsZFJlZ2lzdHJ5LmdldCh0aGlzLnR5cGUgYXMgRmllbGRUeXBlS2V5KTtcbiAgICB0aGlzLmNsZWFudXBSZW5kZXJlZENvbXBvbmVudCgpO1xuICAgIHRoaXMuY2xlYW51cFN1YnNjcmlwdGlvbnMoKTtcbiAgICB0aGlzLmhvc3QuY2xlYXIoKTtcbiAgICBpZiAoIVJlbmRlcmVyKSB7XG4gICAgICBjb25zdCBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgZWwudGV4dENvbnRlbnQgPSBgVW5rbm93biBmaWVsZCB0eXBlOiAke3RoaXMudHlwZX1gO1xuICAgICAgdGhpcy5ob3N0LmVsZW1lbnQubmF0aXZlRWxlbWVudC5hcHBlbmRDaGlsZChlbCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGNvbXBUeXBlID0gUmVuZGVyZXIgYXMgdW5rbm93biBhcyBUeXBlPGFueT47XG4gICAgICBjb25zdCBjb21wUmVmID0gdGhpcy5ob3N0LmNyZWF0ZUNvbXBvbmVudChjb21wVHlwZSk7XG4gICAgICBjb25zdCBpbnN0YW5jZSA9IGNvbXBSZWYuaW5zdGFuY2U7XG4gICAgICBpZiAoIWluc3RhbmNlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGNyZWF0ZSBpbnN0YW5jZSBmb3IgJHt0aGlzLnR5cGV9YCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuYXBwbHlLbm93blByb3BzKGluc3RhbmNlKTtcblxuICAgICAgY29uc3Qgc3ViQSA9IHRoaXMuYmluZE91dHB1dChpbnN0YW5jZSwgJ3ZhbHVlQ2hhbmdlJyk7XG4gICAgICBpZiAoc3ViQSkge1xuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaChzdWJBKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHN1YkIgPSB0aGlzLmJpbmRPdXRwdXQoaW5zdGFuY2UsICdvblZhbHVlQ2hhbmdlJyk7XG4gICAgICBpZiAoc3ViQikge1xuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaChzdWJCKTtcbiAgICAgIH1cblxuICAgICAgaW5zdGFuY2UuY2hhbmdlRGV0ZWN0b3JSZWY/LmRldGVjdENoYW5nZXMoKTtcbiAgICAgIHRoaXMuY29tcFJlZiA9IGNvbXBSZWY7XG4gICAgICB0aGlzLmlucHV0SW5zdGFuY2UgPSBpbnN0YW5jZTtcbiAgICAgIGNvbXBSZWYuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgLy8gRmFsbGJhY2sgdG8gZnVuY3Rpb24gcmVuZGVyZXJcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHByb3BzOiBhbnkgPSB7XG4gICAgICAgICAgdmFsdWU6IHRoaXMudmFsdWUsXG4gICAgICAgICAgb25WYWx1ZUNoYW5nZTogKHY6IGFueSkgPT4gdGhpcy5lbWl0VmFsdWUodiksXG4gICAgICAgICAgbGFiZWw6IHRoaXMubGFiZWwsXG4gICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMucGxhY2Vob2xkZXIsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRoaXMucmVxdWlyZWQsXG4gICAgICAgICAgb3B0aW9uczogdGhpcy5vcHRpb25zLFxuICAgICAgICAgIGNsYXNzTmFtZTogdGhpcy5jbGFzc05hbWUsXG4gICAgICAgICAgZGVzY3JpcHRpb246IHRoaXMuZGVzY3JpcHRpb24sXG4gICAgICAgICAgZGlzYWJsZWQ6IHRoaXMuZGlzYWJsZWQsXG4gICAgICAgICAgZXJyb3JNZXNzYWdlOiB0aGlzLmVycm9yTWVzc2FnZSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgb3V0ID0gKFJlbmRlcmVyIGFzIChwcm9wczogdW5rbm93bikgPT4gdW5rbm93bikocHJvcHMpO1xuICAgICAgICBpZiAodHlwZW9mIG91dCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBjb25zdCBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgIGVsLmlubmVySFRNTCA9IG91dDtcbiAgICAgICAgICB0aGlzLmhvc3QuZWxlbWVudC5uYXRpdmVFbGVtZW50LmFwcGVuZENoaWxkKGVsKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zdCBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBlbC50ZXh0Q29udGVudCA9IGBGYWlsZWQgdG8gcmVuZGVyIGZpZWxkOiAke3RoaXMudHlwZX1gO1xuICAgICAgICB0aGlzLmhvc3QuZWxlbWVudC5uYXRpdmVFbGVtZW50LmFwcGVuZENoaWxkKGVsKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFwcGx5S25vd25Qcm9wcyhpbnN0YW5jZTogYW55KSB7XG4gICAgY29uc3Qga25vd25Qcm9wcyA9IFtcbiAgICAgICd2YWx1ZScsXG4gICAgICAnbGFiZWwnLFxuICAgICAgJ3BsYWNlaG9sZGVyJyxcbiAgICAgICdyZXF1aXJlZCcsXG4gICAgICAnZGlzYWJsZWQnLFxuICAgICAgJ29wdGlvbnMnLFxuICAgICAgJ2NsYXNzTmFtZScsXG4gICAgICAnZGVzY3JpcHRpb24nLFxuICAgICAgJ2Vycm9yTWVzc2FnZScsXG4gICAgXTtcbiAgICBmb3IgKGNvbnN0IHByb3Agb2Yga25vd25Qcm9wcykge1xuICAgICAgaWYgKHByb3AgaW4gdGhpcyAmJiBwcm9wIGluIGluc3RhbmNlKSB7XG4gICAgICAgIGluc3RhbmNlW3Byb3BdID0gKHRoaXMgYXMgYW55KVtwcm9wXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGJpbmRPdXRwdXQoXG4gICAgaW5zdGFuY2U6IGFueSxcbiAgICBvdXRwdXROYW1lOiAndmFsdWVDaGFuZ2UnIHwgJ29uVmFsdWVDaGFuZ2UnXG4gICk6IFN1YnNjcmlwdGlvbiB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3Qgb3V0cHV0ID0gaW5zdGFuY2U/LltvdXRwdXROYW1lXTtcbiAgICBpZiAoIW91dHB1dCB8fCB0eXBlb2Ygb3V0cHV0LnN1YnNjcmliZSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHN1YiA9IChvdXRwdXQgYXMgRXZlbnRFbWl0dGVyPGFueT4pLnN1YnNjcmliZSgodmFsdWUpID0+IHtcbiAgICAgIHRoaXMuZW1pdFZhbHVlKHZhbHVlKTtcbiAgICB9KTtcbiAgICByZXR1cm4gc3ViO1xuICB9XG5cbiAgcHJpdmF0ZSBlbWl0VmFsdWUodmFsdWU6IGFueSkge1xuICAgIHRoaXMudmFsdWVDaGFuZ2UuZW1pdCh2YWx1ZSk7XG4gICAgdGhpcy5vbkNoYW5nZS5lbWl0KHZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgY2xlYW51cFJlbmRlcmVkQ29tcG9uZW50KCkge1xuICAgIHRoaXMuY29tcFJlZj8uZGVzdHJveSgpO1xuICAgIHRoaXMuY29tcFJlZiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmlucHV0SW5zdGFuY2UgPSB1bmRlZmluZWQ7XG4gIH1cbn1cbiJdfQ==