ngx-dynamic-entity 0.0.1 → 1.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 (84) hide show
  1. package/README.md +129 -0
  2. package/esm2022/lib/field-types/array-field.component.mjs +160 -0
  3. package/esm2022/lib/field-types/boolean-field.component.mjs +100 -0
  4. package/esm2022/lib/field-types/checkbox-field.component.mjs +25 -17
  5. package/esm2022/lib/field-types/currency-field.component.mjs +101 -0
  6. package/esm2022/lib/field-types/date-field.component.mjs +21 -13
  7. package/esm2022/lib/field-types/dropdown-field.component.mjs +120 -29
  8. package/esm2022/lib/field-types/email-field.component.mjs +101 -0
  9. package/esm2022/lib/field-types/entity-ref-field.component.mjs +96 -32
  10. package/esm2022/lib/field-types/file-field.component.mjs +156 -0
  11. package/esm2022/lib/field-types/group-field.component.mjs +89 -0
  12. package/esm2022/lib/field-types/image-field.component.mjs +168 -0
  13. package/esm2022/lib/field-types/month-year-field.component.mjs +151 -0
  14. package/esm2022/lib/field-types/multi-select-field.component.mjs +79 -25
  15. package/esm2022/lib/field-types/number-field.component.mjs +60 -17
  16. package/esm2022/lib/field-types/password-field.component.mjs +109 -0
  17. package/esm2022/lib/field-types/radio-field.component.mjs +152 -0
  18. package/esm2022/lib/field-types/text-field.component.mjs +58 -18
  19. package/esm2022/lib/field-types/textarea-field.component.mjs +26 -15
  20. package/esm2022/lib/form/dynamic-field/dynamic-field.component.mjs +44 -26
  21. package/esm2022/lib/form/dynamic-form.component.mjs +676 -69
  22. package/esm2022/lib/form/dynamic-record-form.component.mjs +494 -0
  23. package/esm2022/lib/providers/provide-field-types.mjs +72 -0
  24. package/esm2022/lib/providers/provide-ngx-dynamic-entity.mjs +4 -5
  25. package/esm2022/lib/services/cascade-data.service.mjs +129 -0
  26. package/esm2022/lib/services/config-source.service.mjs +67 -0
  27. package/esm2022/lib/services/entity-ref-cache.mjs +20 -0
  28. package/esm2022/lib/services/entity-ref-registry.service.mjs +3 -3
  29. package/esm2022/lib/services/entity-ref-selection.service.mjs +27 -0
  30. package/esm2022/lib/services/entity-reference.service.mjs +168 -0
  31. package/esm2022/lib/services/field-registry.service.mjs +35 -30
  32. package/esm2022/lib/services/file-upload.service.mjs +89 -0
  33. package/esm2022/lib/services/lookup-registry.service.mjs +246 -0
  34. package/esm2022/lib/services/rbac.service.mjs +5 -11
  35. package/esm2022/lib/services/rules-evaluation.service.mjs +27 -0
  36. package/esm2022/lib/services/validator-registry.service.mjs +35 -7
  37. package/esm2022/lib/tokens/injection-tokens.mjs +104 -7
  38. package/esm2022/public-api.mjs +31 -6
  39. package/fesm2022/ngx-dynamic-entity.mjs +4094 -759
  40. package/fesm2022/ngx-dynamic-entity.mjs.map +1 -1
  41. package/lib/field-types/array-field.component.d.ts +22 -0
  42. package/lib/field-types/boolean-field.component.d.ts +18 -0
  43. package/lib/field-types/checkbox-field.component.d.ts +3 -2
  44. package/lib/field-types/currency-field.component.d.ts +17 -0
  45. package/lib/field-types/date-field.component.d.ts +3 -2
  46. package/lib/field-types/dropdown-field.component.d.ts +24 -4
  47. package/lib/field-types/email-field.component.d.ts +15 -0
  48. package/lib/field-types/entity-ref-field.component.d.ts +24 -11
  49. package/lib/field-types/file-field.component.d.ts +25 -0
  50. package/lib/field-types/group-field.component.d.ts +17 -0
  51. package/lib/field-types/image-field.component.d.ts +30 -0
  52. package/lib/field-types/month-year-field.component.d.ts +28 -0
  53. package/lib/field-types/multi-select-field.component.d.ts +18 -4
  54. package/lib/field-types/number-field.component.d.ts +5 -2
  55. package/lib/field-types/password-field.component.d.ts +17 -0
  56. package/lib/field-types/radio-field.component.d.ts +33 -0
  57. package/lib/field-types/text-field.component.d.ts +5 -3
  58. package/lib/field-types/textarea-field.component.d.ts +4 -2
  59. package/lib/form/dynamic-field/dynamic-field.component.d.ts +20 -7
  60. package/lib/form/dynamic-form.component.d.ts +203 -24
  61. package/lib/form/dynamic-record-form.component.d.ts +180 -0
  62. package/lib/providers/provide-field-types.d.ts +24 -0
  63. package/lib/providers/provide-ngx-dynamic-entity.d.ts +19 -8
  64. package/lib/services/cascade-data.service.d.ts +45 -0
  65. package/lib/services/config-source.service.d.ts +14 -0
  66. package/lib/services/entity-ref-cache.d.ts +27 -0
  67. package/lib/services/entity-ref-registry.service.d.ts +4 -3
  68. package/lib/services/entity-ref-selection.service.d.ts +24 -0
  69. package/lib/services/entity-reference.service.d.ts +49 -0
  70. package/lib/services/field-registry.service.d.ts +17 -7
  71. package/lib/services/file-upload.service.d.ts +27 -0
  72. package/lib/services/lookup-registry.service.d.ts +94 -0
  73. package/lib/services/rbac.service.d.ts +4 -9
  74. package/lib/services/rules-evaluation.service.d.ts +17 -0
  75. package/lib/services/validator-registry.service.d.ts +5 -4
  76. package/lib/tokens/injection-tokens.d.ts +113 -8
  77. package/package.json +18 -8
  78. package/public-api.d.ts +21 -4
  79. package/esm2022/lib/services/config.service.mjs +0 -58
  80. package/esm2022/lib/services/version.service.mjs +0 -40
  81. package/esm2022/lib/table/dynamic-table.component.mjs +0 -160
  82. package/lib/services/config.service.d.ts +0 -25
  83. package/lib/services/version.service.d.ts +0 -26
  84. package/lib/table/dynamic-table.component.d.ts +0 -56
@@ -1,5 +1,6 @@
1
1
  import { Component, Input } from '@angular/core';
2
2
  import { ReactiveFormsModule } from '@angular/forms';
3
+ import { resolveLabel } from '@dynamic-entity/core';
3
4
  import * as i0 from "@angular/core";
4
5
  import * as i1 from "@angular/forms";
5
6
  export class TextareaFieldComponent {
@@ -8,24 +9,32 @@ export class TextareaFieldComponent {
8
9
  language = 'en';
9
10
  readonly = false;
10
11
  masked = false;
12
+ get label() {
13
+ return resolveLabel(this.field?.label, this.language);
14
+ }
15
+ get placeholder() {
16
+ return resolveLabel(this.field?.placeholder, this.language);
17
+ }
11
18
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TextareaFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12
19
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: TextareaFieldComponent, isStandalone: true, selector: "ngx-textarea-field", inputs: { field: "field", control: "control", language: "language", readonly: "readonly", masked: "masked" }, ngImport: i0, template: `
13
- <div class="ngx-field ngx-field--textarea" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
14
- <label class="ngx-field__label">{{ field.label[language] || field.label['en'] }}</label>
20
+ <div class="ngx-field ngx-field--textarea"
21
+ [attr.data-testid]="'field-' + field.id" [attr.data-field-type]="field.type" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
22
+ <label class="ngx-field__label" [attr.for]="field.id">{{ label }}</label>
15
23
  @if (masked) {
16
- <span class="ngx-field__value ngx-field__value--masked">XXXXXXXXX</span>
24
+ <span class="ngx-field__value ngx-field__value--masked" [attr.data-testid]="'field-' + field.id + '-masked'">XXXXXXXXX</span>
17
25
  } @else if (readonly) {
18
- <span class="ngx-field__value">{{ control.value }}</span>
26
+ <span class="ngx-field__value" [attr.data-testid]="'field-' + field.id + '-value'">{{ control.value }}</span>
19
27
  } @else {
20
28
  <textarea
21
- class="ngx-field__input"
29
+ [id]="field.id"
30
+ class="ngx-field__input" [attr.data-testid]="'field-' + field.id + '-input'"
22
31
  [formControl]="$any(control)"
23
- [placeholder]="field.placeholder?.[language] || field.placeholder?.['en'] || ''"
32
+ [placeholder]="placeholder"
24
33
  [attr.disabled]="field.disabled ? true : null"
25
34
  rows="3"
26
35
  ></textarea>
27
36
  @if (control.invalid && control.touched) {
28
- <span class="ngx-field__error">This field has an error</span>
37
+ <span class="ngx-field__error" [attr.data-testid]="'field-' + field.id + '-error'">This field has an error</span>
29
38
  }
30
39
  }
31
40
  </div>
@@ -38,22 +47,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
38
47
  standalone: true,
39
48
  imports: [ReactiveFormsModule],
40
49
  template: `
41
- <div class="ngx-field ngx-field--textarea" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
42
- <label class="ngx-field__label">{{ field.label[language] || field.label['en'] }}</label>
50
+ <div class="ngx-field ngx-field--textarea"
51
+ [attr.data-testid]="'field-' + field.id" [attr.data-field-type]="field.type" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
52
+ <label class="ngx-field__label" [attr.for]="field.id">{{ label }}</label>
43
53
  @if (masked) {
44
- <span class="ngx-field__value ngx-field__value--masked">XXXXXXXXX</span>
54
+ <span class="ngx-field__value ngx-field__value--masked" [attr.data-testid]="'field-' + field.id + '-masked'">XXXXXXXXX</span>
45
55
  } @else if (readonly) {
46
- <span class="ngx-field__value">{{ control.value }}</span>
56
+ <span class="ngx-field__value" [attr.data-testid]="'field-' + field.id + '-value'">{{ control.value }}</span>
47
57
  } @else {
48
58
  <textarea
49
- class="ngx-field__input"
59
+ [id]="field.id"
60
+ class="ngx-field__input" [attr.data-testid]="'field-' + field.id + '-input'"
50
61
  [formControl]="$any(control)"
51
- [placeholder]="field.placeholder?.[language] || field.placeholder?.['en'] || ''"
62
+ [placeholder]="placeholder"
52
63
  [attr.disabled]="field.disabled ? true : null"
53
64
  rows="3"
54
65
  ></textarea>
55
66
  @if (control.invalid && control.touched) {
56
- <span class="ngx-field__error">This field has an error</span>
67
+ <span class="ngx-field__error" [attr.data-testid]="'field-' + field.id + '-error'">This field has an error</span>
57
68
  }
58
69
  }
59
70
  </div>
@@ -70,4 +81,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
70
81
  }], masked: [{
71
82
  type: Input
72
83
  }] } });
73
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dGFyZWEtZmllbGQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9maWVsZC10eXBlcy90ZXh0YXJlYS1maWVsZC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDakQsT0FBTyxFQUFtQixtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7QUE2QnRFLE1BQU0sT0FBTyxzQkFBc0I7SUFDeEIsS0FBSyxDQUFlO0lBQ3BCLE9BQU8sQ0FBbUI7SUFDMUIsUUFBUSxHQUFXLElBQUksQ0FBQztJQUN4QixRQUFRLEdBQVksS0FBSyxDQUFDO0lBQzFCLE1BQU0sR0FBWSxLQUFLLENBQUM7d0dBTHRCLHNCQUFzQjs0RkFBdEIsc0JBQXNCLDRMQXRCdkI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JULDJEQXJCUyxtQkFBbUI7OzRGQXVCbEIsc0JBQXNCO2tCQTFCbEMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsb0JBQW9CO29CQUM5QixVQUFVLEVBQUUsSUFBSTtvQkFDaEIsT0FBTyxFQUFFLENBQUMsbUJBQW1CLENBQUM7b0JBQzlCLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQlQ7aUJBQ0Y7OEJBRVUsS0FBSztzQkFBYixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sLCBSZWFjdGl2ZUZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHR5cGUgeyBGaWVsZENvbmZpZyB9IGZyb20gJ0BkeW5hbWljLWVudGl0eS9jb3JlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LXRleHRhcmVhLWZpZWxkJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1JlYWN0aXZlRm9ybXNNb2R1bGVdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJuZ3gtZmllbGQgbmd4LWZpZWxkLS10ZXh0YXJlYVwiIFtjbGFzcy5uZ3gtZmllbGQtLXJlYWRvbmx5XT1cInJlYWRvbmx5XCIgW2NsYXNzLm5neC1maWVsZC0tbWFza2VkXT1cIm1hc2tlZFwiPlxuICAgICAgPGxhYmVsIGNsYXNzPVwibmd4LWZpZWxkX19sYWJlbFwiPnt7IGZpZWxkLmxhYmVsW2xhbmd1YWdlXSB8fCBmaWVsZC5sYWJlbFsnZW4nXSB9fTwvbGFiZWw+XG4gICAgICBAaWYgKG1hc2tlZCkge1xuICAgICAgICA8c3BhbiBjbGFzcz1cIm5neC1maWVsZF9fdmFsdWUgbmd4LWZpZWxkX192YWx1ZS0tbWFza2VkXCI+WFhYWFhYWFhYPC9zcGFuPlxuICAgICAgfSBAZWxzZSBpZiAocmVhZG9ubHkpIHtcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX3ZhbHVlXCI+e3sgY29udHJvbC52YWx1ZSB9fTwvc3Bhbj5cbiAgICAgIH0gQGVsc2Uge1xuICAgICAgICA8dGV4dGFyZWFcbiAgICAgICAgICBjbGFzcz1cIm5neC1maWVsZF9faW5wdXRcIlxuICAgICAgICAgIFtmb3JtQ29udHJvbF09XCIkYW55KGNvbnRyb2wpXCJcbiAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiZmllbGQucGxhY2Vob2xkZXI/LltsYW5ndWFnZV0gfHwgZmllbGQucGxhY2Vob2xkZXI/LlsnZW4nXSB8fCAnJ1wiXG4gICAgICAgICAgW2F0dHIuZGlzYWJsZWRdPVwiZmllbGQuZGlzYWJsZWQgPyB0cnVlIDogbnVsbFwiXG4gICAgICAgICAgcm93cz1cIjNcIlxuICAgICAgICA+PC90ZXh0YXJlYT5cbiAgICAgICAgQGlmIChjb250cm9sLmludmFsaWQgJiYgY29udHJvbC50b3VjaGVkKSB7XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX2Vycm9yXCI+VGhpcyBmaWVsZCBoYXMgYW4gZXJyb3I8L3NwYW4+XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgVGV4dGFyZWFGaWVsZENvbXBvbmVudCB7XG4gIEBJbnB1dCgpIGZpZWxkITogRmllbGRDb25maWc7XG4gIEBJbnB1dCgpIGNvbnRyb2whOiBBYnN0cmFjdENvbnRyb2w7XG4gIEBJbnB1dCgpIGxhbmd1YWdlOiBzdHJpbmcgPSAnZW4nO1xuICBASW5wdXQoKSByZWFkb25seTogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBtYXNrZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbn1cbiJdfQ==
84
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dGFyZWEtZmllbGQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9maWVsZC10eXBlcy90ZXh0YXJlYS1maWVsZC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDakQsT0FBTyxFQUFtQixtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXRFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQzs7O0FBOEJwRCxNQUFNLE9BQU8sc0JBQXNCO0lBQ3hCLEtBQUssQ0FBcUI7SUFDMUIsT0FBTyxDQUFtQjtJQUMxQixRQUFRLEdBQVcsSUFBSSxDQUFDO0lBQ3hCLFFBQVEsR0FBWSxLQUFLLENBQUM7SUFDMUIsTUFBTSxHQUFZLEtBQUssQ0FBQztJQUVqQyxJQUFJLEtBQUs7UUFDUCxPQUFPLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUVELElBQUksV0FBVztRQUNiLE9BQU8sWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM5RCxDQUFDO3dHQWJVLHNCQUFzQjs0RkFBdEIsc0JBQXNCLDRMQXhCdkI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FzQlQsMkRBdkJTLG1CQUFtQjs7NEZBeUJsQixzQkFBc0I7a0JBNUJsQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxvQkFBb0I7b0JBQzlCLFVBQVUsRUFBRSxJQUFJO29CQUNoQixPQUFPLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQztvQkFDOUIsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0JUO2lCQUNGOzhCQUVVLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFic3RyYWN0Q29udHJvbCwgUmVhY3RpdmVGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB0eXBlIHsgTmVzdGVkRmllbGRDb25maWcgfSBmcm9tICdAZHluYW1pYy1lbnRpdHkvY29yZSc7XG5pbXBvcnQgeyByZXNvbHZlTGFiZWwgfSBmcm9tICdAZHluYW1pYy1lbnRpdHkvY29yZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC10ZXh0YXJlYS1maWVsZCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtSZWFjdGl2ZUZvcm1zTW9kdWxlXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2IGNsYXNzPVwibmd4LWZpZWxkIG5neC1maWVsZC0tdGV4dGFyZWFcIlxuICAgICAgW2F0dHIuZGF0YS10ZXN0aWRdPVwiJ2ZpZWxkLScgKyBmaWVsZC5pZFwiIFthdHRyLmRhdGEtZmllbGQtdHlwZV09XCJmaWVsZC50eXBlXCIgW2NsYXNzLm5neC1maWVsZC0tcmVhZG9ubHldPVwicmVhZG9ubHlcIiBbY2xhc3Mubmd4LWZpZWxkLS1tYXNrZWRdPVwibWFza2VkXCI+XG4gICAgICA8bGFiZWwgY2xhc3M9XCJuZ3gtZmllbGRfX2xhYmVsXCIgW2F0dHIuZm9yXT1cImZpZWxkLmlkXCI+e3sgbGFiZWwgfX08L2xhYmVsPlxuICAgICAgQGlmIChtYXNrZWQpIHtcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX3ZhbHVlIG5neC1maWVsZF9fdmFsdWUtLW1hc2tlZFwiIFthdHRyLmRhdGEtdGVzdGlkXT1cIidmaWVsZC0nICsgZmllbGQuaWQgKyAnLW1hc2tlZCdcIj5YWFhYWFhYWFg8L3NwYW4+XG4gICAgICB9IEBlbHNlIGlmIChyZWFkb25seSkge1xuICAgICAgICA8c3BhbiBjbGFzcz1cIm5neC1maWVsZF9fdmFsdWVcIiBbYXR0ci5kYXRhLXRlc3RpZF09XCInZmllbGQtJyArIGZpZWxkLmlkICsgJy12YWx1ZSdcIj57eyBjb250cm9sLnZhbHVlIH19PC9zcGFuPlxuICAgICAgfSBAZWxzZSB7XG4gICAgICAgIDx0ZXh0YXJlYVxuICAgICAgICAgIFtpZF09XCJmaWVsZC5pZFwiXG4gICAgICAgICAgY2xhc3M9XCJuZ3gtZmllbGRfX2lucHV0XCIgW2F0dHIuZGF0YS10ZXN0aWRdPVwiJ2ZpZWxkLScgKyBmaWVsZC5pZCArICctaW5wdXQnXCJcbiAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiJGFueShjb250cm9sKVwiXG4gICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCJcbiAgICAgICAgICBbYXR0ci5kaXNhYmxlZF09XCJmaWVsZC5kaXNhYmxlZCA/IHRydWUgOiBudWxsXCJcbiAgICAgICAgICByb3dzPVwiM1wiXG4gICAgICAgID48L3RleHRhcmVhPlxuICAgICAgICBAaWYgKGNvbnRyb2wuaW52YWxpZCAmJiBjb250cm9sLnRvdWNoZWQpIHtcbiAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5neC1maWVsZF9fZXJyb3JcIiBbYXR0ci5kYXRhLXRlc3RpZF09XCInZmllbGQtJyArIGZpZWxkLmlkICsgJy1lcnJvcidcIj5UaGlzIGZpZWxkIGhhcyBhbiBlcnJvcjwvc3Bhbj5cbiAgICAgICAgfVxuICAgICAgfVxuICAgIDwvZGl2PlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBUZXh0YXJlYUZpZWxkQ29tcG9uZW50IHtcbiAgQElucHV0KCkgZmllbGQhOiBOZXN0ZWRGaWVsZENvbmZpZztcbiAgQElucHV0KCkgY29udHJvbCE6IEFic3RyYWN0Q29udHJvbDtcbiAgQElucHV0KCkgbGFuZ3VhZ2U6IHN0cmluZyA9ICdlbic7XG4gIEBJbnB1dCgpIHJlYWRvbmx5OiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIG1hc2tlZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIGdldCBsYWJlbCgpOiBzdHJpbmcge1xuICAgIHJldHVybiByZXNvbHZlTGFiZWwodGhpcy5maWVsZD8ubGFiZWwsIHRoaXMubGFuZ3VhZ2UpO1xuICB9XG5cbiAgZ2V0IHBsYWNlaG9sZGVyKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHJlc29sdmVMYWJlbCh0aGlzLmZpZWxkPy5wbGFjZWhvbGRlciwgdGhpcy5sYW5ndWFnZSk7XG4gIH1cbn1cbiJdfQ==
@@ -1,9 +1,10 @@
1
- import { Component, Input, ViewChild, ViewContainerRef, inject, } from '@angular/core';
1
+ import { Component, Input, ViewChild, ViewContainerRef, inject, isDevMode, } from '@angular/core';
2
+ import { findTab } from '@dynamic-entity/core';
2
3
  import { FieldRegistryService } from '../../services/field-registry.service';
3
4
  import { RbacService } from '../../services/rbac.service';
4
5
  import * as i0 from "@angular/core";
5
6
  /**
6
- * DynamicFieldComponent — mounts the correct field component for a given FieldConfig.
7
+ * DynamicFieldComponent — mounts the correct field component for a given NestedFieldConfig.
7
8
  * Uses ViewContainerRef.createComponent() and passes inputs via setInput() (ADR-008).
8
9
  * Never add field-type-specific logic here — this component must remain generic.
9
10
  *
@@ -14,13 +15,14 @@ export class DynamicFieldComponent {
14
15
  field;
15
16
  control;
16
17
  config;
18
+ currentTabId;
17
19
  language = 'en';
18
20
  readonly = false;
19
21
  userRoles = [];
20
22
  fieldHost;
21
23
  fieldRegistry = inject(FieldRegistryService);
22
24
  rbacService = inject(RbacService);
23
- mountedComponent = null;
25
+ componentRef = null;
24
26
  ngOnChanges(_changes) {
25
27
  this.mountField();
26
28
  }
@@ -28,37 +30,51 @@ export class DynamicFieldComponent {
28
30
  if (!this.field || !this.control)
29
31
  return;
30
32
  const ComponentClass = this.fieldRegistry.resolve(this.field.type);
31
- if (!ComponentClass)
33
+ if (!ComponentClass) {
34
+ this.warnUnresolved(this.field.type);
32
35
  return; // Unknown field type — render nothing
36
+ }
33
37
  // Determine masking for this specific field
34
- const tab = (this.config?.tabs || []).find(t => t.id === this.field.tab);
35
- const masked = this.rbacService.shouldMaskField(this.field, tab, this.config, this.userRoles);
38
+ const tab = this.currentTabId ? findTab(this.config?.tabs, this.currentTabId) : null;
39
+ const masked = this.rbacService.shouldMaskField(this.field, tab ?? undefined, this.config, this.userRoles);
36
40
  // Re-use existing component if same type, otherwise recreate
37
- if (this.mountedComponent && this.mountedComponent instanceof ComponentClass) {
38
- this.setInputs(this.mountedComponent, masked);
41
+ if (this.componentRef && this.componentRef.instance instanceof ComponentClass) {
42
+ this.setInputs(this.componentRef, masked);
39
43
  return;
40
44
  }
41
45
  this.fieldHost.clear();
42
- const ref = this.fieldHost.createComponent(ComponentClass);
43
- this.mountedComponent = ref.instance;
44
- this.setInputs(ref.instance, masked);
45
- ref.changeDetectorRef.markForCheck();
46
+ this.componentRef = this.fieldHost.createComponent(ComponentClass);
47
+ this.setInputs(this.componentRef, masked);
48
+ this.componentRef.changeDetectorRef.markForCheck();
49
+ }
50
+ /**
51
+ * Field types are opt-in (see `provideFieldTypes` / `provideBuiltInFieldTypes`), so an
52
+ * unregistered type renders nothing. Say so once per type in dev builds rather than
53
+ * leaving a silently blank slot.
54
+ */
55
+ warnUnresolved(type) {
56
+ if (!isDevMode() || DynamicFieldComponent.warnedTypes.has(type))
57
+ return;
58
+ DynamicFieldComponent.warnedTypes.add(type);
59
+ console.warn(`[ngx-dynamic-entity] No component registered for field type "${type}" — the field was not rendered. ` +
60
+ `Register it with provideFieldTypes({ '${type}': MyComponent }) or provideBuiltInFieldTypes().`);
46
61
  }
47
- /** Pass all 5 contract inputs via setInput() — uniform for all types (ADR-008) */
48
- setInputs(instance, masked) {
49
- if ('field' in instance)
50
- instance.field = this.field;
51
- if ('control' in instance)
52
- instance.control = this.control;
53
- if ('language' in instance)
54
- instance.language = this.language;
55
- if ('readonly' in instance)
56
- instance.readonly = this.readonly || !!this.field.readonly;
57
- if ('masked' in instance)
58
- instance.masked = masked;
62
+ static warnedTypes = new Set();
63
+ /**
64
+ * Pass all 5 contract inputs via ComponentRef.setInput() — uniform for all types (ADR-008).
65
+ * Must use setInput(), not property assignment: the field components declare inputs with
66
+ * definite assignment and no initializer, and the lib compiles with
67
+ * useDefineForClassFields:false, so `'field' in instance` is false until first set.
68
+ */
69
+ setInputs(ref, masked) {
70
+ ref.setInput('field', this.field);
71
+ ref.setInput('control', this.control);
72
+ ref.setInput('language', this.language);
73
+ ref.setInput('readonly', this.readonly || !!this.field.readonly);
74
+ ref.setInput('masked', masked);
59
75
  }
60
76
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DynamicFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
61
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DynamicFieldComponent, isStandalone: true, selector: "ngx-dynamic-field", inputs: { field: "field", control: "control", config: "config", language: "language", readonly: "readonly", userRoles: "userRoles" }, viewQueries: [{ propertyName: "fieldHost", first: true, predicate: ["fieldHost"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: `<ng-container #fieldHost></ng-container>`, isInline: true });
77
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DynamicFieldComponent, isStandalone: true, selector: "ngx-dynamic-field", inputs: { field: "field", control: "control", config: "config", currentTabId: "currentTabId", language: "language", readonly: "readonly", userRoles: "userRoles" }, viewQueries: [{ propertyName: "fieldHost", first: true, predicate: ["fieldHost"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: `<ng-container #fieldHost></ng-container>`, isInline: true });
62
78
  }
63
79
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DynamicFieldComponent, decorators: [{
64
80
  type: Component,
@@ -73,6 +89,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
73
89
  type: Input
74
90
  }], config: [{
75
91
  type: Input
92
+ }], currentTabId: [{
93
+ type: Input
76
94
  }], language: [{
77
95
  type: Input
78
96
  }], readonly: [{
@@ -83,4 +101,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
83
101
  type: ViewChild,
84
102
  args: ['fieldHost', { read: ViewContainerRef, static: true }]
85
103
  }] } });
86
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1pYy1maWVsZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2Zvcm0vZHluYW1pYy1maWVsZC9keW5hbWljLWZpZWxkLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFHTCxTQUFTLEVBQ1QsZ0JBQWdCLEVBQ2hCLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUd2QixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM3RSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7O0FBRTFEOzs7Ozs7O0dBT0c7QUFNSCxNQUFNLE9BQU8scUJBQXFCO0lBQ3ZCLEtBQUssQ0FBZTtJQUNwQixPQUFPLENBQW1CO0lBQzFCLE1BQU0sQ0FBZ0I7SUFDdEIsUUFBUSxHQUFXLElBQUksQ0FBQztJQUN4QixRQUFRLEdBQVksS0FBSyxDQUFDO0lBQzFCLFNBQVMsR0FBYSxFQUFFLENBQUM7SUFHakIsU0FBUyxDQUFvQjtJQUU3QixhQUFhLEdBQUcsTUFBTSxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDN0MsV0FBVyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUUzQyxnQkFBZ0IsR0FBUSxJQUFJLENBQUM7SUFFckMsV0FBVyxDQUFDLFFBQXVCO1FBQ2pDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUNwQixDQUFDO0lBRU8sVUFBVTtRQUNoQixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPO1lBQUUsT0FBTztRQUV6QyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ25FLElBQUksQ0FBQyxjQUFjO1lBQUUsT0FBTyxDQUFDLHNDQUFzQztRQUVuRSw0Q0FBNEM7UUFDNUMsTUFBTSxHQUFHLEdBQTBCLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2hHLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRTlGLDZEQUE2RDtRQUM3RCxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLFlBQVksY0FBYyxFQUFFLENBQUM7WUFDN0UsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDOUMsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3ZCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQzNELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDO1FBQ3JDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNyQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDdkMsQ0FBQztJQUVELGtGQUFrRjtJQUMxRSxTQUFTLENBQUMsUUFBYSxFQUFFLE1BQWU7UUFDOUMsSUFBSSxPQUFPLElBQUksUUFBUTtZQUFFLFFBQVEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUNyRCxJQUFJLFNBQVMsSUFBSSxRQUFRO1lBQUUsUUFBUSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO1FBQzNELElBQUksVUFBVSxJQUFJLFFBQVE7WUFBRSxRQUFRLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7UUFDOUQsSUFBSSxVQUFVLElBQUksUUFBUTtZQUFFLFFBQVEsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUM7UUFDdkYsSUFBSSxRQUFRLElBQUksUUFBUTtZQUFFLFFBQVEsQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO0lBQ3JELENBQUM7d0dBbERVLHFCQUFxQjs0RkFBckIscUJBQXFCLHNTQVFBLGdCQUFnQixnRUFWdEMsMENBQTBDOzs0RkFFekMscUJBQXFCO2tCQUxqQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxtQkFBbUI7b0JBQzdCLFVBQVUsRUFBRSxJQUFJO29CQUNoQixRQUFRLEVBQUUsMENBQTBDO2lCQUNyRDs4QkFFVSxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFHVyxTQUFTO3NCQUR6QixTQUFTO3VCQUFDLFdBQVcsRUFBRSxFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBTaW1wbGVDaGFuZ2VzLFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdDb250YWluZXJSZWYsXG4gIGluamVjdCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgdHlwZSB7IEZpZWxkQ29uZmlnLCBFbnRpdHlDb25maWcsIFRhYkNvbmZpZyB9IGZyb20gJ0BkeW5hbWljLWVudGl0eS9jb3JlJztcbmltcG9ydCB7IEZpZWxkUmVnaXN0cnlTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZmllbGQtcmVnaXN0cnkuc2VydmljZSc7XG5pbXBvcnQgeyBSYmFjU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3JiYWMuc2VydmljZSc7XG5cbi8qKlxuICogRHluYW1pY0ZpZWxkQ29tcG9uZW50IOKAlCBtb3VudHMgdGhlIGNvcnJlY3QgZmllbGQgY29tcG9uZW50IGZvciBhIGdpdmVuIEZpZWxkQ29uZmlnLlxuICogVXNlcyBWaWV3Q29udGFpbmVyUmVmLmNyZWF0ZUNvbXBvbmVudCgpIGFuZCBwYXNzZXMgaW5wdXRzIHZpYSBzZXRJbnB1dCgpIChBRFItMDA4KS5cbiAqIE5ldmVyIGFkZCBmaWVsZC10eXBlLXNwZWNpZmljIGxvZ2ljIGhlcmUg4oCUIHRoaXMgY29tcG9uZW50IG11c3QgcmVtYWluIGdlbmVyaWMuXG4gKlxuICogVGhlIDUgaW5wdXRzIChmaWVsZCwgY29udHJvbCwgbGFuZ3VhZ2UsIHJlYWRvbmx5LCBtYXNrZWQpIGFyZSBwYXNzZWQgdG8gZXZlcnkgbW91bnRlZFxuICogY29tcG9uZW50IHVuaWZvcm1seSDigJQgbm8gc3BlY2lhbC1jYXNpbmcgcGVyIHR5cGUuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC1keW5hbWljLWZpZWxkJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgdGVtcGxhdGU6IGA8bmctY29udGFpbmVyICNmaWVsZEhvc3Q+PC9uZy1jb250YWluZXI+YCxcbn0pXG5leHBvcnQgY2xhc3MgRHluYW1pY0ZpZWxkQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgQElucHV0KCkgZmllbGQhOiBGaWVsZENvbmZpZztcbiAgQElucHV0KCkgY29udHJvbCE6IEFic3RyYWN0Q29udHJvbDtcbiAgQElucHV0KCkgY29uZmlnITogRW50aXR5Q29uZmlnO1xuICBASW5wdXQoKSBsYW5ndWFnZTogc3RyaW5nID0gJ2VuJztcbiAgQElucHV0KCkgcmVhZG9ubHk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgdXNlclJvbGVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIEBWaWV3Q2hpbGQoJ2ZpZWxkSG9zdCcsIHsgcmVhZDogVmlld0NvbnRhaW5lclJlZiwgc3RhdGljOiB0cnVlIH0pXG4gIHByaXZhdGUgcmVhZG9ubHkgZmllbGRIb3N0ITogVmlld0NvbnRhaW5lclJlZjtcblxuICBwcml2YXRlIHJlYWRvbmx5IGZpZWxkUmVnaXN0cnkgPSBpbmplY3QoRmllbGRSZWdpc3RyeVNlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IHJiYWNTZXJ2aWNlID0gaW5qZWN0KFJiYWNTZXJ2aWNlKTtcblxuICBwcml2YXRlIG1vdW50ZWRDb21wb25lbnQ6IGFueSA9IG51bGw7XG5cbiAgbmdPbkNoYW5nZXMoX2NoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICB0aGlzLm1vdW50RmllbGQoKTtcbiAgfVxuXG4gIHByaXZhdGUgbW91bnRGaWVsZCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZmllbGQgfHwgIXRoaXMuY29udHJvbCkgcmV0dXJuO1xuXG4gICAgY29uc3QgQ29tcG9uZW50Q2xhc3MgPSB0aGlzLmZpZWxkUmVnaXN0cnkucmVzb2x2ZSh0aGlzLmZpZWxkLnR5cGUpO1xuICAgIGlmICghQ29tcG9uZW50Q2xhc3MpIHJldHVybjsgLy8gVW5rbm93biBmaWVsZCB0eXBlIOKAlCByZW5kZXIgbm90aGluZ1xuXG4gICAgLy8gRGV0ZXJtaW5lIG1hc2tpbmcgZm9yIHRoaXMgc3BlY2lmaWMgZmllbGRcbiAgICBjb25zdCB0YWI6IFRhYkNvbmZpZyB8IHVuZGVmaW5lZCA9ICh0aGlzLmNvbmZpZz8udGFicyB8fCBbXSkuZmluZCh0ID0+IHQuaWQgPT09IHRoaXMuZmllbGQudGFiKTtcbiAgICBjb25zdCBtYXNrZWQgPSB0aGlzLnJiYWNTZXJ2aWNlLnNob3VsZE1hc2tGaWVsZCh0aGlzLmZpZWxkLCB0YWIsIHRoaXMuY29uZmlnLCB0aGlzLnVzZXJSb2xlcyk7XG5cbiAgICAvLyBSZS11c2UgZXhpc3RpbmcgY29tcG9uZW50IGlmIHNhbWUgdHlwZSwgb3RoZXJ3aXNlIHJlY3JlYXRlXG4gICAgaWYgKHRoaXMubW91bnRlZENvbXBvbmVudCAmJiB0aGlzLm1vdW50ZWRDb21wb25lbnQgaW5zdGFuY2VvZiBDb21wb25lbnRDbGFzcykge1xuICAgICAgdGhpcy5zZXRJbnB1dHModGhpcy5tb3VudGVkQ29tcG9uZW50LCBtYXNrZWQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuZmllbGRIb3N0LmNsZWFyKCk7XG4gICAgY29uc3QgcmVmID0gdGhpcy5maWVsZEhvc3QuY3JlYXRlQ29tcG9uZW50KENvbXBvbmVudENsYXNzKTtcbiAgICB0aGlzLm1vdW50ZWRDb21wb25lbnQgPSByZWYuaW5zdGFuY2U7XG4gICAgdGhpcy5zZXRJbnB1dHMocmVmLmluc3RhbmNlLCBtYXNrZWQpO1xuICAgIHJlZi5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIC8qKiBQYXNzIGFsbCA1IGNvbnRyYWN0IGlucHV0cyB2aWEgc2V0SW5wdXQoKSDigJQgdW5pZm9ybSBmb3IgYWxsIHR5cGVzIChBRFItMDA4KSAqL1xuICBwcml2YXRlIHNldElucHV0cyhpbnN0YW5jZTogYW55LCBtYXNrZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAoJ2ZpZWxkJyBpbiBpbnN0YW5jZSkgaW5zdGFuY2UuZmllbGQgPSB0aGlzLmZpZWxkO1xuICAgIGlmICgnY29udHJvbCcgaW4gaW5zdGFuY2UpIGluc3RhbmNlLmNvbnRyb2wgPSB0aGlzLmNvbnRyb2w7XG4gICAgaWYgKCdsYW5ndWFnZScgaW4gaW5zdGFuY2UpIGluc3RhbmNlLmxhbmd1YWdlID0gdGhpcy5sYW5ndWFnZTtcbiAgICBpZiAoJ3JlYWRvbmx5JyBpbiBpbnN0YW5jZSkgaW5zdGFuY2UucmVhZG9ubHkgPSB0aGlzLnJlYWRvbmx5IHx8ICEhdGhpcy5maWVsZC5yZWFkb25seTtcbiAgICBpZiAoJ21hc2tlZCcgaW4gaW5zdGFuY2UpIGluc3RhbmNlLm1hc2tlZCA9IG1hc2tlZDtcbiAgfVxufVxuIl19
104
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1pYy1maWVsZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2Zvcm0vZHluYW1pYy1maWVsZC9keW5hbWljLWZpZWxkLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUVULEtBQUssRUFHTCxTQUFTLEVBQ1QsZ0JBQWdCLEVBQ2hCLE1BQU0sRUFDTixTQUFTLEdBQ1YsTUFBTSxlQUFlLENBQUM7QUFHdkIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQzdFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQzs7QUFFMUQ7Ozs7Ozs7R0FPRztBQU1ILE1BQU0sT0FBTyxxQkFBcUI7SUFDdkIsS0FBSyxDQUFxQjtJQUMxQixPQUFPLENBQW1CO0lBQzFCLE1BQU0sQ0FBb0I7SUFDMUIsWUFBWSxDQUFVO0lBQ3RCLFFBQVEsR0FBVyxJQUFJLENBQUM7SUFDeEIsUUFBUSxHQUFZLEtBQUssQ0FBQztJQUMxQixTQUFTLEdBQWEsRUFBRSxDQUFDO0lBR2pCLFNBQVMsQ0FBb0I7SUFFN0IsYUFBYSxHQUFHLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBQzdDLFdBQVcsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7SUFFM0MsWUFBWSxHQUFpQyxJQUFJLENBQUM7SUFFMUQsV0FBVyxDQUFDLFFBQXVCO1FBQ2pDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUNwQixDQUFDO0lBRU8sVUFBVTtRQUNoQixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPO1lBQUUsT0FBTztRQUV6QyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxJ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SztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFHVyxTQUFTO3NCQUR6QixTQUFTO3VCQUFDLFdBQVcsRUFBRSxFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBDb21wb25lbnRSZWYsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFZpZXdDaGlsZCxcbiAgVmlld0NvbnRhaW5lclJlZixcbiAgaW5qZWN0LFxuICBpc0Rldk1vZGUsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHR5cGUgeyBOZXN0ZWRGaWVsZENvbmZpZywgRW50aXR5Rm9ybUNvbmZpZywgTmVzdGVkVGFiQ29uZmlnIH0gZnJvbSAnQGR5bmFtaWMtZW50aXR5L2NvcmUnO1xuaW1wb3J0IHsgZmluZFRhYiB9IGZyb20gJ0BkeW5hbWljLWVudGl0eS9jb3JlJztcbmltcG9ydCB7IEZpZWxkUmVnaXN0cnlTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZmllbGQtcmVnaXN0cnkuc2VydmljZSc7XG5pbXBvcnQgeyBSYmFjU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3JiYWMuc2VydmljZSc7XG5cbi8qKlxuICogRHluYW1pY0ZpZWxkQ29tcG9uZW50IOKAlCBtb3VudHMgdGhlIGNvcnJlY3QgZmllbGQgY29tcG9uZW50IGZvciBhIGdpdmVuIE5lc3RlZEZpZWxkQ29uZmlnLlxuICogVXNlcyBWaWV3Q29udGFpbmVyUmVmLmNyZWF0ZUNvbXBvbmVudCgpIGFuZCBwYXNzZXMgaW5wdXRzIHZpYSBzZXRJbnB1dCgpIChBRFItMDA4KS5cbiAqIE5ldmVyIGFkZCBmaWVsZC10eXBlLXNwZWNpZmljIGxvZ2ljIGhlcmUg4oCUIHRoaXMgY29tcG9uZW50IG11c3QgcmVtYWluIGdlbmVyaWMuXG4gKlxuICogVGhlIDUgaW5wdXRzIChmaWVsZCwgY29udHJvbCwgbGFuZ3VhZ2UsIHJlYWRvbmx5LCBtYXNrZWQpIGFyZSBwYXNzZWQgdG8gZXZlcnkgbW91bnRlZFxuICogY29tcG9uZW50IHVuaWZvcm1seSDigJQgbm8gc3BlY2lhbC1jYXNpbmcgcGVyIHR5cGUuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC1keW5hbWljLWZpZWxkJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgdGVtcGxhdGU6IGA8bmctY29udGFpbmVyICNmaWVsZEhvc3Q+PC9uZy1jb250YWluZXI+YCxcbn0pXG5leHBvcnQgY2xhc3MgRHluYW1pY0ZpZWxkQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgQElucHV0KCkgZmllbGQhOiBOZXN0ZWRGaWVsZENvbmZpZztcbiAgQElucHV0KCkgY29udHJvbCE6IEFic3RyYWN0Q29udHJvbDtcbiAgQElucHV0KCkgY29uZmlnITogRW50aXR5Rm9ybUNvbmZpZztcbiAgQElucHV0KCkgY3VycmVudFRhYklkPzogc3RyaW5nO1xuICBASW5wdXQoKSBsYW5ndWFnZTogc3RyaW5nID0gJ2VuJztcbiAgQElucHV0KCkgcmVhZG9ubHk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgdXNlclJvbGVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIEBWaWV3Q2hpbGQoJ2ZpZWxkSG9zdCcsIHsgcmVhZDogVmlld0NvbnRhaW5lclJlZiwgc3RhdGljOiB0cnVlIH0pXG4gIHByaXZhdGUgcmVhZG9ubHkgZmllbGRIb3N0ITogVmlld0NvbnRhaW5lclJlZjtcblxuICBwcml2YXRlIHJlYWRvbmx5IGZpZWxkUmVnaXN0cnkgPSBpbmplY3QoRmllbGRSZWdpc3RyeVNlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IHJiYWNTZXJ2aWNlID0gaW5qZWN0KFJiYWNTZXJ2aWNlKTtcblxuICBwcml2YXRlIGNvbXBvbmVudFJlZjogQ29tcG9uZW50UmVmPHVua25vd24+IHwgbnVsbCA9IG51bGw7XG5cbiAgbmdPbkNoYW5nZXMoX2NoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICB0aGlzLm1vdW50RmllbGQoKTtcbiAgfVxuXG4gIHByaXZhdGUgbW91bnRGaWVsZCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZmllbGQgfHwgIXRoaXMuY29udHJvbCkgcmV0dXJuO1xuXG4gICAgY29uc3QgQ29tcG9uZW50Q2xhc3MgPSB0aGlzLmZpZWxkUmVnaXN0cnkucmVzb2x2ZSh0aGlzLmZpZWxkLnR5cGUpO1xuICAgIGlmICghQ29tcG9uZW50Q2xhc3MpIHtcbiAgICAgIHRoaXMud2FyblVucmVzb2x2ZWQodGhpcy5maWVsZC50eXBlKTtcbiAgICAgIHJldHVybjsgLy8gVW5rbm93biBmaWVsZCB0eXBlIOKAlCByZW5kZXIgbm90aGluZ1xuICAgIH1cblxuICAgIC8vIERldGVybWluZSBtYXNraW5nIGZvciB0aGlzIHNwZWNpZmljIGZpZWxkXG4gICAgY29uc3QgdGFiOiBOZXN0ZWRUYWJDb25maWcgfCBudWxsID0gdGhpcy5jdXJyZW50VGFiSWQgPyBmaW5kVGFiKHRoaXMuY29uZmlnPy50YWJzLCB0aGlzLmN1cnJlbnRUYWJJZCkgOiBudWxsO1xuICAgIGNvbnN0IG1hc2tlZCA9IHRoaXMucmJhY1NlcnZpY2Uuc2hvdWxkTWFza0ZpZWxkKHRoaXMuZmllbGQsIHRhYiA/PyB1bmRlZmluZWQsIHRoaXMuY29uZmlnLCB0aGlzLnVzZXJSb2xlcyk7XG5cbiAgICAvLyBSZS11c2UgZXhpc3RpbmcgY29tcG9uZW50IGlmIHNhbWUgdHlwZSwgb3RoZXJ3aXNlIHJlY3JlYXRlXG4gICAgaWYgKHRoaXMuY29tcG9uZW50UmVmICYmIHRoaXMuY29tcG9uZW50UmVmLmluc3RhbmNlIGluc3RhbmNlb2YgQ29tcG9uZW50Q2xhc3MpIHtcbiAgICAgIHRoaXMuc2V0SW5wdXRzKHRoaXMuY29tcG9uZW50UmVmLCBtYXNrZWQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuZmllbGRIb3N0LmNsZWFyKCk7XG4gICAgdGhpcy5jb21wb25lbnRSZWYgPSB0aGlzLmZpZWxkSG9zdC5jcmVhdGVDb21wb25lbnQoQ29tcG9uZW50Q2xhc3MpO1xuICAgIHRoaXMuc2V0SW5wdXRzKHRoaXMuY29tcG9uZW50UmVmLCBtYXNrZWQpO1xuICAgIHRoaXMuY29tcG9uZW50UmVmLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpZWxkIHR5cGVzIGFyZSBvcHQtaW4gKHNlZSBgcHJvdmlkZUZpZWxkVHlwZXNgIC8gYHByb3ZpZGVCdWlsdEluRmllbGRUeXBlc2ApLCBzbyBhblxuICAgKiB1bnJlZ2lzdGVyZWQgdHlwZSByZW5kZXJzIG5vdGhpbmcuIFNheSBzbyBvbmNlIHBlciB0eXBlIGluIGRldiBidWlsZHMgcmF0aGVyIHRoYW5cbiAgICogbGVhdmluZyBhIHNpbGVudGx5IGJsYW5rIHNsb3QuXG4gICAqL1xuICBwcml2YXRlIHdhcm5VbnJlc29sdmVkKHR5cGU6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghaXNEZXZNb2RlKCkgfHwgRHluYW1pY0ZpZWxkQ29tcG9uZW50Lndhcm5lZFR5cGVzLmhhcyh0eXBlKSkgcmV0dXJuO1xuICAgIER5bmFtaWNGaWVsZENvbXBvbmVudC53YXJuZWRUeXBlcy5hZGQodHlwZSk7XG4gICAgY29uc29sZS53YXJuKFxuICAgICAgYFtuZ3gtZHluYW1pYy1lbnRpdHldIE5vIGNvbXBvbmVudCByZWdpc3RlcmVkIGZvciBmaWVsZCB0eXBlIFwiJHt0eXBlfVwiIOKAlCB0aGUgZmllbGQgd2FzIG5vdCByZW5kZXJlZC4gYCArXG4gICAgICAgIGBSZWdpc3RlciBpdCB3aXRoIHByb3ZpZGVGaWVsZFR5cGVzKHsgJyR7dHlwZX0nOiBNeUNvbXBvbmVudCB9KSBvciBwcm92aWRlQnVpbHRJbkZpZWxkVHlwZXMoKS5gLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSB3YXJuZWRUeXBlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gIC8qKlxuICAgKiBQYXNzIGFsbCA1IGNvbnRyYWN0IGlucHV0cyB2aWEgQ29tcG9uZW50UmVmLnNldElucHV0KCkg4oCUIHVuaWZvcm0gZm9yIGFsbCB0eXBlcyAoQURSLTAwOCkuXG4gICAqIE11c3QgdXNlIHNldElucHV0KCksIG5vdCBwcm9wZXJ0eSBhc3NpZ25tZW50OiB0aGUgZmllbGQgY29tcG9uZW50cyBkZWNsYXJlIGlucHV0cyB3aXRoXG4gICAqIGRlZmluaXRlIGFzc2lnbm1lbnQgYW5kIG5vIGluaXRpYWxpemVyLCBhbmQgdGhlIGxpYiBjb21waWxlcyB3aXRoXG4gICAqIHVzZURlZmluZUZvckNsYXNzRmllbGRzOmZhbHNlLCBzbyBgJ2ZpZWxkJyBpbiBpbnN0YW5jZWAgaXMgZmFsc2UgdW50aWwgZmlyc3Qgc2V0LlxuICAgKi9cbiAgcHJpdmF0ZSBzZXRJbnB1dHMocmVmOiBDb21wb25lbnRSZWY8dW5rbm93bj4sIG1hc2tlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIHJlZi5zZXRJbnB1dCgnZmllbGQnLCB0aGlzLmZpZWxkKTtcbiAgICByZWYuc2V0SW5wdXQoJ2NvbnRyb2wnLCB0aGlzLmNvbnRyb2wpO1xuICAgIHJlZi5zZXRJbnB1dCgnbGFuZ3VhZ2UnLCB0aGlzLmxhbmd1YWdlKTtcbiAgICByZWYuc2V0SW5wdXQoJ3JlYWRvbmx5JywgdGhpcy5yZWFkb25seSB8fCAhIXRoaXMuZmllbGQucmVhZG9ubHkpO1xuICAgIHJlZi5zZXRJbnB1dCgnbWFza2VkJywgbWFza2VkKTtcbiAgfVxufVxuIl19