@seniorsistemas/angular-components 19.9.1 → 19.9.2-fix-sds-586-7857a0d0

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 (29) hide show
  1. package/README.md +99 -13
  2. package/esm2022/dynamic-form/dynamic-form/components/structure/fieldset/fieldset.component.mjs +4 -3
  3. package/esm2022/fieldset/lib/fieldset/fieldset.component.mjs +51 -34
  4. package/esm2022/spotlight/lib/spotlight/spotlight-overlay/rect-stability.mjs +61 -0
  5. package/esm2022/spotlight/lib/spotlight/spotlight-overlay/spotlight-overlay.component.mjs +91 -21
  6. package/fesm2022/seniorsistemas-angular-components-dynamic-form.mjs +4 -4
  7. package/fesm2022/seniorsistemas-angular-components-dynamic-form.mjs.map +1 -1
  8. package/fesm2022/seniorsistemas-angular-components-fieldset.mjs +50 -33
  9. package/fesm2022/seniorsistemas-angular-components-fieldset.mjs.map +1 -1
  10. package/fesm2022/seniorsistemas-angular-components-spotlight.mjs +150 -20
  11. package/fesm2022/seniorsistemas-angular-components-spotlight.mjs.map +1 -1
  12. package/fieldset/README.md +77 -15
  13. package/fieldset/lib/fieldset/fieldset.component.d.ts +27 -13
  14. package/package.json +1 -1
  15. package/schematics/collection.json +26 -1
  16. package/schematics/migrations/migrate-dynamic-form-v19/index.js +15 -34
  17. package/schematics/migrations/migrate-dynamic-form-v19/index.js.map +1 -1
  18. package/schematics/migrations/migrate-fieldset-body-template/index.d.ts +2 -0
  19. package/schematics/migrations/migrate-fieldset-body-template/index.js +421 -0
  20. package/schematics/migrations/migrate-fieldset-body-template/index.js.map +1 -0
  21. package/schematics/migrations/migrate-steps-to-stepper/index.js +1 -19
  22. package/schematics/migrations/migrate-steps-to-stepper/index.js.map +1 -1
  23. package/schematics/migrations.json +5 -0
  24. package/schematics/utils/ast-utils.d.ts +33 -1
  25. package/schematics/utils/ast-utils.js +175 -4
  26. package/schematics/utils/ast-utils.js.map +1 -1
  27. package/spotlight/README.md +28 -0
  28. package/spotlight/lib/spotlight/spotlight-overlay/rect-stability.d.ts +32 -0
  29. package/spotlight/lib/spotlight/spotlight-overlay/spotlight-overlay.component.d.ts +33 -0
package/README.md CHANGED
@@ -1,25 +1,111 @@
1
- # AngularComponents
1
+ # @seniorsistemas/angular-components
2
2
 
3
- This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 18.2.0.
3
+ Biblioteca de componentes Angular reutilizáveis da Senior Sistemas, construída com Angular 18 e Tailwind CSS.
4
4
 
5
- ## Code scaffolding
5
+ Inclui mais de 70 componentes, diretivas e pipes para construção de interfaces — desde inputs e formulários dinâmicos até tabelas, kanban, chat e muito mais.
6
6
 
7
- Run `ng generate component component-name --project angular-components` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project angular-components`.
7
+ ## Documentação
8
8
 
9
- > Note: Don't forget to add `--project angular-components` or else it will be added to the default project in your `angular.json` file.
9
+ A documentação oficial é feita via **Storybook**. Cada componente tem stories com exemplos interativos, descrição de inputs/outputs e variantes visuais.
10
10
 
11
- ## Build
11
+ ### Rodar o Storybook localmente
12
12
 
13
- Run `ng build angular-components` to build the project. The build artifacts will be stored in the `dist/` directory.
13
+ ```bash
14
+ npm run storybook
15
+ ```
14
16
 
15
- ## Publishing
17
+ Acesse em `http://localhost:6006`.
16
18
 
17
- After building your library with `ng build angular-components`, go to the dist folder `cd dist/angular-components` and run `npm publish`.
19
+ ### Build do Storybook
18
20
 
19
- ## Running unit tests
21
+ ```bash
22
+ npm run build-storybook
23
+ ```
20
24
 
21
- Run `ng test angular-components` to execute the unit tests via [Karma](https://karma-runner.github.io).
25
+ O output é gerado em `storybook-static/`.
22
26
 
23
- ## Further help
27
+ ## Showcase
28
+
29
+ Além do Storybook, há um projeto de showcase com exemplos reais de uso:
30
+
31
+ ```bash
32
+ npm run start
33
+ ```
34
+
35
+ Acesse em `http://localhost:4200`.
36
+
37
+ ## Estrutura do monorepo
38
+
39
+ ```
40
+ projects/
41
+ angular-components/ # Biblioteca de componentes
42
+ <nome-componente>/ # Cada componente é um sub-pacote independente
43
+ src/lib/
44
+ ng-package.json
45
+ showcase/ # Aplicação de demonstração
46
+ ```
47
+
48
+ ## Instalação
49
+
50
+ ```bash
51
+ npm install @seniorsistemas/angular-components
52
+ ```
53
+
54
+ Cada componente é importado individualmente pelo seu sub-pacote:
55
+
56
+ ```typescript
57
+ import { ButtonModule } from '@seniorsistemas/angular-components/button';
58
+ import { DynamicFormModule } from '@seniorsistemas/angular-components/dynamic-form';
59
+ ```
60
+
61
+ ## Schematics de migração
62
+
63
+ A biblioteca oferece schematics de migração via `ng update`, então é boa prática sempre atualizar a versão instalada com esse comando em vez de só trocar o número no `package.json` — além de atualizar a dependência, ele aplica automaticamente as migrations necessárias no seu projeto e mostra o que há de novo relevante para o seu código:
64
+
65
+ ```bash
66
+ ng update @seniorsistemas/angular-components
67
+ ```
68
+
69
+ Migrations disponíveis (por versão em que passam a ser aplicadas):
70
+
71
+ | Versão | Migration | O que faz |
72
+ | -------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
73
+ | `19.0.0` | `migration-v19-0-0-dynamic-form` | Migra o `DynamicForm` de v18 para v19: construtores → plain objects, enums → string literals, `[fields]` → `[configs]`, `Editor` → `provideEditorField()`, estilos → `angular.json` |
74
+ | `19.0.0` | `migration-v19-0-0-steps-to-stepper` | Migra `Steps` para `Stepper`: `<s-steps>` → `<s-stepper>`, import de `.../steps` → `.../stepper`, `StepsComponent` → `StepperComponent`, e remove o `StepsModule` (componente agora standalone) substituindo por `StepperComponent` |
75
+ | `19.6.0` | `migration-v19-6-0-p-datepicker` | Migra `p-datepicker` (PrimeNG) para `s-datepicker` (`@seniorsistemas/angular-components`) |
76
+ | `19.6.0` | `migration-v19-6-0-p-editor` | Migra `p-editor` (PrimeNG/Quill) para `s-editor`: renomeia tag e eventos, remove atributos sem equivalente, limpa configs legadas do `DynamicForm` e atualiza dependências do `package.json` |
77
+ | `19.6.2` | `migration-v19-6-2-s-chips-outputs` | Renomeia outputs legados do `s-chips`: `onAdd`→`added`, `onRemove`→`removed`, `onChipClick`→`chipClicked`, `onFocus`→`focused`, `onBlur`→`focusLost` |
78
+ | `19.9.3` | `migration-v19-9-3-fieldset-body-template` | Envolve o conteúdo projetado do `s-fieldset` em `<ng-template sTemplate="body">`, mantendo templates de slot como `sTemplate="header"` fora do body, e garante o `TemplateDirective` no escopo do componente (standalone ou via `NgModule`) |
79
+
80
+ A lista completa, com a `version` que dispara cada migration e a `factory` correspondente, fica em [`projects/angular-components/schematics/migrations.json`](projects/angular-components/schematics/migrations.json).
81
+
82
+ ### Executando uma migration individualmente
83
+
84
+ Se você já está na versão instalada (não chegou até ela via `ng update`) e só precisa aplicar uma migration específica no seu projeto, sem atualizar nada, há duas formas:
85
+
86
+ **Via `ng generate`** (mais simples) — cada migration também está disponível com um nome curto, sem o prefixo de versão (`migrate-<nome>` em vez de `migration-v<versão>-<nome>`):
87
+
88
+ ```bash
89
+ ng generate @seniorsistemas/angular-components:migrate-fieldset-body-template
90
+ ```
91
+
92
+ **Via `ng update --name`** (mais completo) — usa o nome versionado, o mesmo que aparece na tabela acima:
93
+
94
+ ```bash
95
+ ng update @seniorsistemas/angular-components --name migration-v19-9-3-fieldset-body-template
96
+ ```
97
+
98
+ Os dois rodam exatamente a mesma migration e nenhum dos dois altera a versão instalada ou reinstala dependências.
99
+
100
+ ## Build da biblioteca
101
+
102
+ ```bash
103
+ npm run build
104
+ ```
105
+
106
+ ## Testes
107
+
108
+ ```bash
109
+ npm run test
110
+ ```
24
111
 
25
- To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
@@ -1,6 +1,7 @@
1
1
  import { Component, input } from '@angular/core';
2
2
  import { DynamicFormDirective } from '../../../dynamic-form.directive';
3
3
  import { FieldsetModule } from '@seniorsistemas/angular-components/fieldset';
4
+ import { TemplateDirective } from '@seniorsistemas/angular-components/template';
4
5
  import * as i0 from "@angular/core";
5
6
  import * as i1 from "@seniorsistemas/angular-components/fieldset";
6
7
  export class FieldsetComponent {
@@ -9,10 +10,10 @@ export class FieldsetComponent {
9
10
  group = input.required();
10
11
  errorMessages = input();
11
12
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FieldsetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: FieldsetComponent, isStandalone: true, selector: "ng-component", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: true, transformFunction: null }, errorMessages: { classPropertyName: "errorMessages", publicName: "errorMessages", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@let _config = config();\n<s-fieldset\n [toggleable]=\"true\"\n (onBeforeToggle)=\"_config.beforeToggle ? _config.beforeToggle($event) : null\"\n (onAfterToggle)=\"_config.afterToggle ? _config.afterToggle($event) : null\"\n [legend]=\"_config.header ? _config.header : ''\"\n>\n @for (conf of _config.configs; let i = $index; track i) {\n <ng-container\n *sDynamicForm=\"{ id: id(), config: conf, group: group(), errorMessages: errorMessages() }\"\n ></ng-container>\n }\n</s-fieldset>\n\n", dependencies: [{ kind: "directive", type: DynamicFormDirective, selector: "[sDynamicForm]", inputs: ["sDynamicForm"] }, { kind: "ngmodule", type: FieldsetModule }, { kind: "component", type: i1.FieldsetComponent, selector: "s-fieldset", inputs: ["legend", "toggleable", "icon", "destroyOnHide"], outputs: ["beforeToggle", "afterToggle"] }] });
13
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: FieldsetComponent, isStandalone: true, selector: "ng-component", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: true, transformFunction: null }, errorMessages: { classPropertyName: "errorMessages", publicName: "errorMessages", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@let _config = config();\n<s-fieldset\n [toggleable]=\"true\"\n (beforeToggle)=\"_config.beforeToggle ? _config.beforeToggle($event) : null\"\n (afterToggle)=\"_config.afterToggle ? _config.afterToggle($event) : null\"\n [legend]=\"_config.header ? _config.header : ''\"\n>\n <ng-template sTemplate=\"body\">\n @for (conf of _config.configs; let i = $index; track i) {\n <ng-container\n *sDynamicForm=\"{ id: id(), config: conf, group: group(), errorMessages: errorMessages() }\"\n ></ng-container>\n }\n </ng-template>\n</s-fieldset>\n\n", dependencies: [{ kind: "directive", type: DynamicFormDirective, selector: "[sDynamicForm]", inputs: ["sDynamicForm"] }, { kind: "ngmodule", type: FieldsetModule }, { kind: "component", type: i1.FieldsetComponent, selector: "s-fieldset", inputs: ["legend", "toggleable", "icon", "destroyOnHide", "active"], outputs: ["beforeToggle", "afterToggle", "activeChange"] }, { kind: "directive", type: TemplateDirective, selector: "[sTemplate]", inputs: ["sTemplate"] }] });
13
14
  }
14
15
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FieldsetComponent, decorators: [{
15
16
  type: Component,
16
- args: [{ standalone: true, imports: [DynamicFormDirective, FieldsetModule], template: "@let _config = config();\n<s-fieldset\n [toggleable]=\"true\"\n (onBeforeToggle)=\"_config.beforeToggle ? _config.beforeToggle($event) : null\"\n (onAfterToggle)=\"_config.afterToggle ? _config.afterToggle($event) : null\"\n [legend]=\"_config.header ? _config.header : ''\"\n>\n @for (conf of _config.configs; let i = $index; track i) {\n <ng-container\n *sDynamicForm=\"{ id: id(), config: conf, group: group(), errorMessages: errorMessages() }\"\n ></ng-container>\n }\n</s-fieldset>\n\n" }]
17
+ args: [{ standalone: true, imports: [DynamicFormDirective, FieldsetModule, TemplateDirective], template: "@let _config = config();\n<s-fieldset\n [toggleable]=\"true\"\n (beforeToggle)=\"_config.beforeToggle ? _config.beforeToggle($event) : null\"\n (afterToggle)=\"_config.afterToggle ? _config.afterToggle($event) : null\"\n [legend]=\"_config.header ? _config.header : ''\"\n>\n <ng-template sTemplate=\"body\">\n @for (conf of _config.configs; let i = $index; track i) {\n <ng-container\n *sDynamicForm=\"{ id: id(), config: conf, group: group(), errorMessages: errorMessages() }\"\n ></ng-container>\n }\n </ng-template>\n</s-fieldset>\n\n" }]
17
18
  }] });
18
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmllbGRzZXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1jb21wb25lbnRzL2R5bmFtaWMtZm9ybS9zcmMvbGliL2R5bmFtaWMtZm9ybS9jb21wb25lbnRzL3N0cnVjdHVyZS9maWVsZHNldC9maWVsZHNldC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLWNvbXBvbmVudHMvZHluYW1pYy1mb3JtL3NyYy9saWIvZHluYW1pYy1mb3JtL2NvbXBvbmVudHMvc3RydWN0dXJlL2ZpZWxkc2V0L2ZpZWxkc2V0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBS2pELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQzs7O0FBTTdFLE1BQU0sT0FBTyxpQkFBaUI7SUFDMUIsRUFBRSxHQUFHLEtBQUssRUFBVSxDQUFDO0lBQ3JCLE1BQU0sR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFrQixDQUFDO0lBQzFDLEtBQUssR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFhLENBQUM7SUFDcEMsYUFBYSxHQUFHLEtBQUssRUFBTyxDQUFDO3dHQUpwQixpQkFBaUI7NEZBQWpCLGlCQUFpQixva0JDWjlCLHVoQkFjQSw0Q0RMYyxvQkFBb0Isb0ZBQUUsY0FBYzs7NEZBR3JDLGlCQUFpQjtrQkFMN0IsU0FBUztpQ0FDTSxJQUFJLFdBQ1AsQ0FBQyxvQkFBb0IsRUFBRSxjQUFjLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIGlucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGb3JtR3JvdXAgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmltcG9ydCB7IEZpZWxkc2V0Q29uZmlnIH0gZnJvbSAnLi4vLi4vLi4vY29uZmlndXJhdGlvbnMvc3RydWN0dXJlL2ZpZWxkc2V0JztcbmltcG9ydCB7IEJhc2VTdHJ1Y3R1cmVDb21wb25lbnRDb25maWcgfSBmcm9tICcuLi9iYXNlLXN0cnVjdHVyZS1jb21wb25lbnQnO1xuaW1wb3J0IHsgRHluYW1pY0Zvcm1EaXJlY3RpdmUgfSBmcm9tICcuLi8uLi8uLi9keW5hbWljLWZvcm0uZGlyZWN0aXZlJztcbmltcG9ydCB7IEZpZWxkc2V0TW9kdWxlIH0gZnJvbSAnQHNlbmlvcnNpc3RlbWFzL2FuZ3VsYXItY29tcG9uZW50cy9maWVsZHNldCc7XG5AQ29tcG9uZW50KHtcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxuICAgIGltcG9ydHM6IFtEeW5hbWljRm9ybURpcmVjdGl2ZSwgRmllbGRzZXRNb2R1bGVdLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9maWVsZHNldC5jb21wb25lbnQuaHRtbCcsXG59KVxuZXhwb3J0IGNsYXNzIEZpZWxkc2V0Q29tcG9uZW50IGltcGxlbWVudHMgQmFzZVN0cnVjdHVyZUNvbXBvbmVudENvbmZpZyB7XG4gICAgaWQgPSBpbnB1dDxzdHJpbmc+KCk7XG4gICAgY29uZmlnID0gaW5wdXQucmVxdWlyZWQ8RmllbGRzZXRDb25maWc+KCk7XG4gICAgZ3JvdXAgPSBpbnB1dC5yZXF1aXJlZDxGb3JtR3JvdXA+KCk7XG4gICAgZXJyb3JNZXNzYWdlcyA9IGlucHV0PGFueT4oKTtcbn1cblxuIiwiQGxldCBfY29uZmlnID0gY29uZmlnKCk7XG48cy1maWVsZHNldFxuICAgIFt0b2dnbGVhYmxlXT1cInRydWVcIlxuICAgIChvbkJlZm9yZVRvZ2dsZSk9XCJfY29uZmlnLmJlZm9yZVRvZ2dsZSA/IF9jb25maWcuYmVmb3JlVG9nZ2xlKCRldmVudCkgOiBudWxsXCJcbiAgICAob25BZnRlclRvZ2dsZSk9XCJfY29uZmlnLmFmdGVyVG9nZ2xlID8gX2NvbmZpZy5hZnRlclRvZ2dsZSgkZXZlbnQpIDogbnVsbFwiXG4gICAgW2xlZ2VuZF09XCJfY29uZmlnLmhlYWRlciA/IF9jb25maWcuaGVhZGVyIDogJydcIlxuPlxuICAgIEBmb3IgKGNvbmYgb2YgX2NvbmZpZy5jb25maWdzOyBsZXQgaSA9ICRpbmRleDsgdHJhY2sgaSkge1xuICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAqc0R5bmFtaWNGb3JtPVwieyBpZDogaWQoKSwgY29uZmlnOiBjb25mLCBncm91cDogZ3JvdXAoKSwgZXJyb3JNZXNzYWdlczogZXJyb3JNZXNzYWdlcygpIH1cIlxuICAgICAgICA+PC9uZy1jb250YWluZXI+XG4gICAgfVxuPC9zLWZpZWxkc2V0PlxuXG4iXX0=
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmllbGRzZXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1jb21wb25lbnRzL2R5bmFtaWMtZm9ybS9zcmMvbGliL2R5bmFtaWMtZm9ybS9jb21wb25lbnRzL3N0cnVjdHVyZS9maWVsZHNldC9maWVsZHNldC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLWNvbXBvbmVudHMvZHluYW1pYy1mb3JtL3NyYy9saWIvZHluYW1pYy1mb3JtL2NvbXBvbmVudHMvc3RydWN0dXJlL2ZpZWxkc2V0L2ZpZWxkc2V0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBS2pELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQztBQUM3RSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQzs7O0FBTWhGLE1BQU0sT0FBTyxpQkFBaUI7SUFDMUIsRUFBRSxHQUFHLEtBQUssRUFBVSxDQUFDO0lBQ3JCLE1BQU0sR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFrQixDQUFDO0lBQzFDLEtBQUssR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFhLENBQUM7SUFDcEMsYUFBYSxHQUFHLEtBQUssRUFBTyxDQUFDO3dHQUpwQixpQkFBaUI7NEZBQWpCLGlCQUFpQixva0JDYjlCLGltQkFnQkEsNENETmMsb0JBQW9CLG9GQUFFLGNBQWMseU9BQUUsaUJBQWlCOzs0RkFHeEQsaUJBQWlCO2tCQUw3QixTQUFTO2lDQUNNLElBQUksV0FDUCxDQUFDLG9CQUFvQixFQUFFLGNBQWMsRUFBRSxpQkFBaUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgaW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1Hcm91cCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcblxuaW1wb3J0IHsgRmllbGRzZXRDb25maWcgfSBmcm9tICcuLi8uLi8uLi9jb25maWd1cmF0aW9ucy9zdHJ1Y3R1cmUvZmllbGRzZXQnO1xuaW1wb3J0IHsgQmFzZVN0cnVjdHVyZUNvbXBvbmVudENvbmZpZyB9IGZyb20gJy4uL2Jhc2Utc3RydWN0dXJlLWNvbXBvbmVudCc7XG5pbXBvcnQgeyBEeW5hbWljRm9ybURpcmVjdGl2ZSB9IGZyb20gJy4uLy4uLy4uL2R5bmFtaWMtZm9ybS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgRmllbGRzZXRNb2R1bGUgfSBmcm9tICdAc2VuaW9yc2lzdGVtYXMvYW5ndWxhci1jb21wb25lbnRzL2ZpZWxkc2V0JztcbmltcG9ydCB7IFRlbXBsYXRlRGlyZWN0aXZlIH0gZnJvbSAnQHNlbmlvcnNpc3RlbWFzL2FuZ3VsYXItY29tcG9uZW50cy90ZW1wbGF0ZSc7XG5AQ29tcG9uZW50KHtcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxuICAgIGltcG9ydHM6IFtEeW5hbWljRm9ybURpcmVjdGl2ZSwgRmllbGRzZXRNb2R1bGUsIFRlbXBsYXRlRGlyZWN0aXZlXSxcbiAgICB0ZW1wbGF0ZVVybDogJy4vZmllbGRzZXQuY29tcG9uZW50Lmh0bWwnLFxufSlcbmV4cG9ydCBjbGFzcyBGaWVsZHNldENvbXBvbmVudCBpbXBsZW1lbnRzIEJhc2VTdHJ1Y3R1cmVDb21wb25lbnRDb25maWcge1xuICAgIGlkID0gaW5wdXQ8c3RyaW5nPigpO1xuICAgIGNvbmZpZyA9IGlucHV0LnJlcXVpcmVkPEZpZWxkc2V0Q29uZmlnPigpO1xuICAgIGdyb3VwID0gaW5wdXQucmVxdWlyZWQ8Rm9ybUdyb3VwPigpO1xuICAgIGVycm9yTWVzc2FnZXMgPSBpbnB1dDxhbnk+KCk7XG59XG5cbiIsIkBsZXQgX2NvbmZpZyA9IGNvbmZpZygpO1xuPHMtZmllbGRzZXRcbiAgICBbdG9nZ2xlYWJsZV09XCJ0cnVlXCJcbiAgICAoYmVmb3JlVG9nZ2xlKT1cIl9jb25maWcuYmVmb3JlVG9nZ2xlID8gX2NvbmZpZy5iZWZvcmVUb2dnbGUoJGV2ZW50KSA6IG51bGxcIlxuICAgIChhZnRlclRvZ2dsZSk9XCJfY29uZmlnLmFmdGVyVG9nZ2xlID8gX2NvbmZpZy5hZnRlclRvZ2dsZSgkZXZlbnQpIDogbnVsbFwiXG4gICAgW2xlZ2VuZF09XCJfY29uZmlnLmhlYWRlciA/IF9jb25maWcuaGVhZGVyIDogJydcIlxuPlxuICAgIDxuZy10ZW1wbGF0ZSBzVGVtcGxhdGU9XCJib2R5XCI+XG4gICAgICAgIEBmb3IgKGNvbmYgb2YgX2NvbmZpZy5jb25maWdzOyBsZXQgaSA9ICRpbmRleDsgdHJhY2sgaSkge1xuICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICpzRHluYW1pY0Zvcm09XCJ7IGlkOiBpZCgpLCBjb25maWc6IGNvbmYsIGdyb3VwOiBncm91cCgpLCBlcnJvck1lc3NhZ2VzOiBlcnJvck1lc3NhZ2VzKCkgfVwiXG4gICAgICAgICAgICA+PC9uZy1jb250YWluZXI+XG4gICAgICAgIH1cbiAgICA8L25nLXRlbXBsYXRlPlxuPC9zLWZpZWxkc2V0PlxuXG4iXX0=
@@ -1,18 +1,27 @@
1
1
  import { animate, state, style, transition, trigger } from '@angular/animations';
2
- import { Component, ContentChildren, EventEmitter, Input, Output, } from '@angular/core';
3
- import { TemplateDirective } from '@seniorsistemas/angular-components/template';
4
- import { InteractiveContentDirective } from '@seniorsistemas/angular-components/interactive-content';
2
+ import { Component, computed, contentChildren, EventEmitter, input, model, Output } from '@angular/core';
5
3
  import { NgTemplateOutlet } from '@angular/common';
4
+ import { InteractiveContentDirective } from '@seniorsistemas/angular-components/interactive-content';
5
+ import { TemplateDirective } from '@seniorsistemas/angular-components/template';
6
6
  import * as i0 from "@angular/core";
7
7
  /**
8
8
  * @description Componente de fieldset com legenda, ícone configurável e suporte a
9
- * toggle (recolher/expandir) com animação. Suporta template personalizado para o
10
- * cabeçalho via diretiva `TemplateDirective` com tipo `'header'`.
9
+ * toggle (recolher/expandir) com animação. Suporta templates personalizados via
10
+ * diretiva `TemplateDirective`, com os tipos `'header'` (substitui a legenda) e
11
+ * `'body'` (conteúdo do fieldset).
12
+ *
13
+ * Prefira declarar o conteúdo em `sTemplate="body"` em vez de projetá-lo direto:
14
+ * o `ng-content` é instanciado pelo componente pai mesmo com o fieldset recolhido,
15
+ * disparando o `ngOnInit` dos filhos prematuramente. O template de corpo só é
16
+ * instanciado quando o fieldset está de fato ativo, e é obrigatório para que
17
+ * `destroyOnHide` funcione.
11
18
  *
12
19
  * @example
13
20
  * ```html
14
21
  * <s-fieldset legend="Dados pessoais" [toggleable]="true">
15
- * <p>Conteúdo do fieldset</p>
22
+ * <ng-template sTemplate="body">
23
+ * <p>Conteúdo do fieldset</p>
24
+ * </ng-template>
16
25
  * </s-fieldset>
17
26
  * ```
18
27
  *
@@ -20,33 +29,52 @@ import * as i0 from "@angular/core";
20
29
  */
21
30
  export class FieldsetComponent {
22
31
  /** @description Texto exibido como título do fieldset. @default '' */
23
- legend = '';
32
+ legend = input('');
24
33
  /** @description Habilita o botão de toggle que permite recolher e expandir o conteúdo. @default false */
25
- toggleable = false;
34
+ toggleable = input(false);
26
35
  /** @description Classe de ícone exibida ao lado da legenda (ex.: `'fas fa-cog'`). @default '' */
27
- icon = '';
28
- /** @description Quando `true`, remove o conteúdo do DOM ao recolher o fieldset. @default true */
29
- destroyOnHide = true;
30
- templateDirectives;
31
- headerTemplate;
36
+ icon = input('');
37
+ /** @description Quando `true`, remove o conteúdo do DOM ao recolher o fieldset. @default false */
38
+ destroyOnHide = input(false);
39
+ templateDirectives = contentChildren(TemplateDirective);
40
+ headerTemplate = computed(() => {
41
+ return this.templateDirectives()?.find((template) => template.type === 'header')?.template;
42
+ });
43
+ bodyTemplate = computed(() => {
44
+ return this.templateDirectives()?.find((template) => template.type === 'body')?.template;
45
+ });
32
46
  /** @description Emitido imediatamente antes da animação de toggle iniciar, com o estado atual. */
33
47
  beforeToggle = new EventEmitter();
34
48
  /** @description Emitido após a animação de toggle concluir, com o novo estado. */
35
49
  afterToggle = new EventEmitter();
36
- active = true;
50
+ active = model(true);
51
+ displayType = 'block';
37
52
  ngAfterViewInit() {
38
- this.headerTemplate = this.templateDirectives?.find((template) => template.type === 'header')?.template;
53
+ const hasBodyTemplate = this.bodyTemplate();
54
+ if (!hasBodyTemplate && this.destroyOnHide()) {
55
+ console.warn('FieldsetComponent: O uso de destroyOnHide=true requer um template de corpo definido com sTemplate="body".');
56
+ }
39
57
  }
40
58
  toggleActive(originalEvent) {
41
- if (!this.toggleable) {
59
+ if (!this.toggleable()) {
42
60
  return;
43
61
  }
44
- this.beforeToggle.next({ collapsed: this.active, originalEvent });
45
- this.active = !this.active;
46
- this.afterToggle.next({ collapsed: this.active, originalEvent });
62
+ this.beforeToggle.next({ collapsed: this.active(), originalEvent });
63
+ this.active.set(!this.active());
64
+ this.afterToggle.next({ collapsed: this.active(), originalEvent });
65
+ }
66
+ handleAnimationStart(event) {
67
+ if (event.toState === 'open') {
68
+ this.displayType = 'block';
69
+ }
70
+ }
71
+ handleAnimationDone(event) {
72
+ if (event.toState === 'closed') {
73
+ this.displayType = 'none';
74
+ }
47
75
  }
48
76
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FieldsetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
49
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: FieldsetComponent, isStandalone: true, selector: "s-fieldset", inputs: { legend: "legend", toggleable: "toggleable", icon: "icon", destroyOnHide: "destroyOnHide" }, outputs: { beforeToggle: "beforeToggle", afterToggle: "afterToggle" }, queries: [{ propertyName: "templateDirectives", predicate: TemplateDirective }], ngImport: i0, template: "<fieldset\r\n class=\"bg-grayscale-0 border border-grayscale-20 rounded-xbig mb-[10px] min-h-[4.5em] px-2 py-1.5 w-full min-w-0\"\r\n>\r\n <legend\r\n class=\"flex items-center text-grayscale-90 font-open-sans text-sm font-bold px-1 gap-1 ml-4 select-none\"\r\n [class.cursor-pointer]=\"toggleable\"\r\n (sInteractiveContent)=\"toggleActive($event)\"\r\n >\r\n @if (toggleable) {\r\n @if (active) {\r\n <i class=\"fas fa-plus\"></i>\r\n } @else {\r\n <i class=\"fas fa-minus\"></i>\r\n }\r\n }\r\n @if (headerTemplate) {\r\n <ng-container *ngTemplateOutlet=\"headerTemplate\"></ng-container>\r\n } @else {\r\n @if (icon) {\r\n <i [class]=\"icon\"></i>\r\n }\r\n {{ legend }}\r\n }\r\n </legend>\r\n @if (destroyOnHide ? (toggleable ? active : true) : true) {\r\n <div [@toggleAnimation]=\"destroyOnHide ? null : active ? 'open' : 'closed'\">\r\n <ng-content></ng-content>\r\n </div>\r\n }\r\n</fieldset>\r\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: InteractiveContentDirective, selector: "[sInteractiveContent]", inputs: ["focusable", "disabled", "stopPropagation"], outputs: ["sInteractiveContent"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], animations: [
77
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: FieldsetComponent, isStandalone: true, selector: "s-fieldset", inputs: { legend: { classPropertyName: "legend", publicName: "legend", isSignal: true, isRequired: false, transformFunction: null }, toggleable: { classPropertyName: "toggleable", publicName: "toggleable", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, destroyOnHide: { classPropertyName: "destroyOnHide", publicName: "destroyOnHide", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { beforeToggle: "beforeToggle", afterToggle: "afterToggle", active: "activeChange" }, queries: [{ propertyName: "templateDirectives", predicate: TemplateDirective, isSignal: true }], ngImport: i0, template: "<fieldset\r\n class=\"mb-[10px] min-h-[4.5em] w-full min-w-0 rounded-xbig border border-grayscale-20 bg-grayscale-0 px-2 py-1.5\"\r\n>\r\n <legend\r\n class=\"ml-4 flex select-none items-center gap-1 px-1 font-open-sans text-sm font-bold text-grayscale-90\"\r\n [class.cursor-pointer]=\"toggleable()\"\r\n (sInteractiveContent)=\"toggleActive($event)\"\r\n >\r\n @if (toggleable()) {\r\n @if (active()) {\r\n <i class=\"fas fa-minus\"></i>\r\n } @else {\r\n <i class=\"fas fa-plus\"></i>\r\n }\r\n }\r\n @let _headerTemplate = headerTemplate();\r\n @if (_headerTemplate) {\r\n <ng-container *ngTemplateOutlet=\"_headerTemplate\"></ng-container>\r\n } @else {\r\n @if (icon()) {\r\n <i [class]=\"icon()\"></i>\r\n }\r\n {{ legend() }}\r\n }\r\n </legend>\r\n @if (destroyOnHide() ? (toggleable() ? active() : true) : true) {\r\n <div\r\n [class.hidden]=\"displayType === 'none'\"\r\n [class.block]=\"displayType === 'block'\"\r\n [@toggleAnimation]=\"destroyOnHide() ? null : active() ? 'open' : 'closed'\"\r\n (@toggleAnimation.start)=\"handleAnimationStart($event)\"\r\n (@toggleAnimation.done)=\"handleAnimationDone($event)\"\r\n >\r\n @let _bodyTemplate = bodyTemplate();\r\n @if (_bodyTemplate) {\r\n <ng-container *ngTemplateOutlet=\"_bodyTemplate\"></ng-container>\r\n } @else {\r\n <ng-content></ng-content>\r\n }\r\n </div>\r\n }\r\n</fieldset>\r\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: InteractiveContentDirective, selector: "[sInteractiveContent]", inputs: ["focusable", "disabled", "stopPropagation"], outputs: ["sInteractiveContent"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], animations: [
50
78
  trigger('toggleAnimation', [
51
79
  transition(':enter', [
52
80
  style({ opacity: 0, height: 0 }),
@@ -78,21 +106,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
78
106
  state('closed', style({ opacity: 0, height: 0 })),
79
107
  transition('open <=> closed', animate('300ms ease')),
80
108
  ]),
81
- ], standalone: true, imports: [InteractiveContentDirective, NgTemplateOutlet], template: "<fieldset\r\n class=\"bg-grayscale-0 border border-grayscale-20 rounded-xbig mb-[10px] min-h-[4.5em] px-2 py-1.5 w-full min-w-0\"\r\n>\r\n <legend\r\n class=\"flex items-center text-grayscale-90 font-open-sans text-sm font-bold px-1 gap-1 ml-4 select-none\"\r\n [class.cursor-pointer]=\"toggleable\"\r\n (sInteractiveContent)=\"toggleActive($event)\"\r\n >\r\n @if (toggleable) {\r\n @if (active) {\r\n <i class=\"fas fa-plus\"></i>\r\n } @else {\r\n <i class=\"fas fa-minus\"></i>\r\n }\r\n }\r\n @if (headerTemplate) {\r\n <ng-container *ngTemplateOutlet=\"headerTemplate\"></ng-container>\r\n } @else {\r\n @if (icon) {\r\n <i [class]=\"icon\"></i>\r\n }\r\n {{ legend }}\r\n }\r\n </legend>\r\n @if (destroyOnHide ? (toggleable ? active : true) : true) {\r\n <div [@toggleAnimation]=\"destroyOnHide ? null : active ? 'open' : 'closed'\">\r\n <ng-content></ng-content>\r\n </div>\r\n }\r\n</fieldset>\r\n", styles: [":host{display:block}\n"] }]
82
- }], propDecorators: { legend: [{
83
- type: Input
84
- }], toggleable: [{
85
- type: Input
86
- }], icon: [{
87
- type: Input
88
- }], destroyOnHide: [{
89
- type: Input
90
- }], templateDirectives: [{
91
- type: ContentChildren,
92
- args: [TemplateDirective]
93
- }], beforeToggle: [{
109
+ ], standalone: true, imports: [InteractiveContentDirective, NgTemplateOutlet], template: "<fieldset\r\n class=\"mb-[10px] min-h-[4.5em] w-full min-w-0 rounded-xbig border border-grayscale-20 bg-grayscale-0 px-2 py-1.5\"\r\n>\r\n <legend\r\n class=\"ml-4 flex select-none items-center gap-1 px-1 font-open-sans text-sm font-bold text-grayscale-90\"\r\n [class.cursor-pointer]=\"toggleable()\"\r\n (sInteractiveContent)=\"toggleActive($event)\"\r\n >\r\n @if (toggleable()) {\r\n @if (active()) {\r\n <i class=\"fas fa-minus\"></i>\r\n } @else {\r\n <i class=\"fas fa-plus\"></i>\r\n }\r\n }\r\n @let _headerTemplate = headerTemplate();\r\n @if (_headerTemplate) {\r\n <ng-container *ngTemplateOutlet=\"_headerTemplate\"></ng-container>\r\n } @else {\r\n @if (icon()) {\r\n <i [class]=\"icon()\"></i>\r\n }\r\n {{ legend() }}\r\n }\r\n </legend>\r\n @if (destroyOnHide() ? (toggleable() ? active() : true) : true) {\r\n <div\r\n [class.hidden]=\"displayType === 'none'\"\r\n [class.block]=\"displayType === 'block'\"\r\n [@toggleAnimation]=\"destroyOnHide() ? null : active() ? 'open' : 'closed'\"\r\n (@toggleAnimation.start)=\"handleAnimationStart($event)\"\r\n (@toggleAnimation.done)=\"handleAnimationDone($event)\"\r\n >\r\n @let _bodyTemplate = bodyTemplate();\r\n @if (_bodyTemplate) {\r\n <ng-container *ngTemplateOutlet=\"_bodyTemplate\"></ng-container>\r\n } @else {\r\n <ng-content></ng-content>\r\n }\r\n </div>\r\n }\r\n</fieldset>\r\n", styles: [":host{display:block}\n"] }]
110
+ }], propDecorators: { beforeToggle: [{
94
111
  type: Output
95
112
  }], afterToggle: [{
96
113
  type: Output
97
114
  }] } });
98
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmllbGRzZXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1jb21wb25lbnRzL2ZpZWxkc2V0L3NyYy9saWIvZmllbGRzZXQvZmllbGRzZXQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1jb21wb25lbnRzL2ZpZWxkc2V0L3NyYy9saWIvZmllbGRzZXQvZmllbGRzZXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRixPQUFPLEVBRUgsU0FBUyxFQUNULGVBQWUsRUFDZixZQUFZLEVBQ1osS0FBSyxFQUNMLE1BQU0sR0FHVCxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQztBQUVoRixPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSx3REFBd0QsQ0FBQztBQUNyRyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7QUFFbkQ7Ozs7Ozs7Ozs7Ozs7R0FhRztBQXVCSCxNQUFNLE9BQU8saUJBQWlCO0lBQzFCLHNFQUFzRTtJQUM3RCxNQUFNLEdBQUcsRUFBRSxDQUFDO0lBQ3JCLHlHQUF5RztJQUNoRyxVQUFVLEdBQUcsS0FBSyxDQUFDO0lBQzVCLGlHQUFpRztJQUN4RixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ25CLGlHQUFpRztJQUN4RixhQUFhLEdBQUcsSUFBSSxDQUFDO0lBQ2Usa0JBQWtCLENBQTJDO0lBQzFHLGNBQWMsQ0FBK0I7SUFDN0Msa0dBQWtHO0lBQ3hGLFlBQVksR0FBRyxJQUFJLFlBQVksRUFBa0IsQ0FBQztJQUM1RCxrRkFBa0Y7SUFDeEUsV0FBVyxHQUFHLElB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TyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQzs0QkFDakQsS0FBSyxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDOzRCQUNqRCxVQUFVLENBQUMsaUJBQWlCLEVBQUUsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFDO3lCQUN2RCxDQUFDO3FCQUNMLGNBQ1csSUFBSSxXQUNQLENBQUMsMkJBQTJCLEVBQUUsZ0JBQWdCLENBQUM7OEJBSS9DLE1BQU07c0JBQWQsS0FBSztnQkFFRyxVQUFVO3NCQUFsQixLQUFLO2dCQUVHLElBQUk7c0JBQVosS0FBSztnQkFFRyxhQUFhO3NCQUFyQixLQUFLO2dCQUN1QyxrQkFBa0I7c0JBQTlELGVBQWU7dUJBQUMsaUJBQWlCO2dCQUd4QixZQUFZO3NCQUFyQixNQUFNO2dCQUVHLFdBQVc7c0JBQXBCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBhbmltYXRlLCBzdGF0ZSwgc3R5bGUsIHRyYW5zaXRpb24sIHRyaWdnZXIgfSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJztcclxuaW1wb3J0IHtcclxuICAgIEFmdGVyVmlld0luaXQsXHJcbiAgICBDb21wb25lbnQsXHJcbiAgICBDb250ZW50Q2hpbGRyZW4sXHJcbiAgICBFdmVudEVtaXR0ZXIsXHJcbiAgICBJbnB1dCxcclxuICAgIE91dHB1dCxcclxuICAgIFF1ZXJ5TGlzdCxcclxuICAgIFRlbXBsYXRlUmVmLFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5cclxuaW1wb3J0IHsgVGVtcGxhdGVEaXJlY3RpdmUgfSBmcm9tICdAc2VuaW9yc2lzdGVtYXMvYW5ndWxhci1jb21wb25lbnRzL3RlbXBsYXRlJztcclxuaW1wb3J0IHsgRmllbGRTZXRUb2dnbGUgfSBmcm9tICcuL2ZpZWxkc2V0Lm1vZGVscyc7XHJcbmltcG9ydCB7IEludGVyYWN0aXZlQ29udGVudERpcmVjdGl2ZSB9IGZyb20gJ0BzZW5pb3JzaXN0ZW1hcy9hbmd1bGFyLWNvbXBvbmVudHMvaW50ZXJhY3RpdmUtY29udGVudCc7XHJcbmltcG9ydCB7IE5nVGVtcGxhdGVPdXRsZXQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5cclxuLyoqXHJcbiAqIEBkZXNjcmlwdGlvbiBDb21wb25lbnRlIGRlIGZpZWxkc2V0IGNvbSBsZWdlbmRhLCDDrWNvbmUgY29uZmlndXLDoXZlbCBlIHN1cG9ydGUgYVxyXG4gKiB0b2dnbGUgKHJlY29saGVyL2V4cGFuZGlyKSBjb20gYW5pbWHDp8Ojby4gU3Vwb3J0YSB0ZW1wbGF0ZSBwZXJzb25hbGl6YWRvIHBhcmEgb1xyXG4gKiBjYWJlw6dhbGhvIHZpYSBkaXJldGl2YSBgVGVtcGxhdGVEaXJlY3RpdmVgIGNvbSB0aXBvIGAnaGVhZGVyJ2AuXHJcbiAqXHJcbiAqIEBleGFtcGxlXHJcbiAqIGBgYGh0bWxcclxuICogPHMtZmllbGRzZXQgbGVnZW5kPVwiRGFkb3MgcGVzc29haXNcIiBbdG9nZ2xlYWJsZV09XCJ0cnVlXCI+XHJcbiAqICAgPHA+Q29udGXDumRvIGRvIGZpZWxkc2V0PC9wPlxyXG4gKiA8L3MtZmllbGRzZXQ+XHJcbiAqIGBgYFxyXG4gKlxyXG4gKiBAY2F0ZWdvcnkgSW5wdXRzXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAncy1maWVsZHNldCcsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vZmllbGRzZXQuY29tcG9uZW50Lmh0bWwnLFxyXG4gICAgc3R5bGVzOiBbJzpob3N0IHsgZGlzcGxheTogYmxvY2s7IH0nXSxcclxuICAgIGFuaW1hdGlvbnM6IFtcclxuICAgICAgICB0cmlnZ2VyKCd0b2dnbGVBbmltYXRpb24nLCBbXHJcbiAgICAgICAgICAgIHRyYW5zaXRpb24oJzplbnRlcicsIFtcclxuICAgICAgICAgICAgICAgIHN0eWxlKHsgb3BhY2l0eTogMCwgaGVpZ2h0OiAwIH0pLFxyXG4gICAgICAgICAgICAgICAgYW5pbWF0ZSgnMzAwbXMgZWFzZS1vdXQnLCBzdHlsZSh7IG9wYWNpdHk6IDEsIGhlaWdodDogJyonIH0pKSxcclxuICAgICAgICAgICAgXSksXHJcbiAgICAgICAgICAgIHRyYW5zaXRpb24oJzpsZWF2ZScsIFtcclxuICAgICAgICAgICAgICAgIHN0eWxlKHsgb3BhY2l0eTogMSwgaGVpZ2h0OiAnKicgfSksXHJcbiAgICAgICAgICAgICAgICBhbmltYXRlKCczMDBtcyBlYXNlLWluJywgc3R5bGUoeyBvcGFjaXR5OiAwLCBoZWlnaHQ6IDAgfSkpLFxyXG4gICAgICAgICAgICBdKSxcclxuICAgICAgICAgICAgc3RhdGUoJ29wZW4nLCBzdHlsZSh7IG9wYWNpdHk6IDEsIGhlaWdodDogJyonIH0pKSxcclxuICAgICAgICAgICAgc3RhdGUoJ2Nsb3NlZCcsIHN0eWxlKHsgb3BhY2l0eTogMCwgaGVpZ2h0OiAwIH0pKSxcclxuICAgICAgICAgICAgdHJhbnNpdGlvbignb3BlbiA8PT4gY2xvc2VkJywgYW5pbWF0ZSgnMzAwbXMgZWFzZScpKSxcclxuICAgICAgICBdKSxcclxuICAgIF0sXHJcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gICAgaW1wb3J0czogW0ludGVyYWN0aXZlQ29udGVudERpcmVjdGl2ZSwgTmdUZW1wbGF0ZU91dGxldF0sXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBGaWVsZHNldENvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQge1xyXG4gICAgLyoqIEBkZXNjcmlwdGlvbiBUZXh0byBleGliaWRvIGNvbW8gdMOtdHVsbyBkbyBmaWVsZHNldC4gQGRlZmF1bHQgJycgKi9cclxuICAgIEBJbnB1dCgpIGxlZ2VuZCA9ICcnO1xyXG4gICAgLyoqIEBkZXNjcmlwdGlvbiBIYWJpbGl0YSBvIGJvdMOjbyBkZSB0b2dnbGUgcXVlIHBlcm1pdGUgcmVjb2xoZXIgZSBleHBhbmRpciBvIGNvbnRlw7pkby4gQGRlZmF1bHQgZmFsc2UgKi9cclxuICAgIEBJbnB1dCgpIHRvZ2dsZWFibGUgPSBmYWxzZTtcclxuICAgIC8qKiBAZGVzY3JpcHRpb24gQ2xhc3NlIGRlIMOtY29uZSBleGliaWRhIGFvIGxhZG8gZGEgbGVnZW5kYSAoZXguOiBgJ2ZhcyBmYS1jb2cnYCkuIEBkZWZhdWx0ICcnICovXHJcbiAgICBASW5wdXQoKSBpY29uID0gJyc7XHJcbiAgICAvKiogQGRlc2NyaXB0aW9uIFF1YW5kbyBgdHJ1ZWAsIHJlbW92ZSBvIGNvbnRlw7pkbyBkbyBET00gYW8gcmVjb2xoZXIgbyBmaWVsZHNldC4gQGRlZmF1bHQgdHJ1ZSAqL1xyXG4gICAgQElucHV0KCkgZGVzdHJveU9uSGlkZSA9IHRydWU7XHJcbiAgICBAQ29udGVudENoaWxkcmVuKFRlbXBsYXRlRGlyZWN0aXZlKSByZWFkb25seSB0ZW1wbGF0ZURpcmVjdGl2ZXM6IFF1ZXJ5TGlzdDxUZW1wbGF0ZURpcmVjdGl2ZT4gfCB1bmRlZmluZWQ7XHJcbiAgICBoZWFkZXJUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZDtcclxuICAgIC8qKiBAZGVzY3JpcHRpb24gRW1pdGlkbyBpbWVkaWF0YW1lbnRlIGFudGVzIGRhIGFuaW1hw6fDo28gZGUgdG9nZ2xlIGluaWNpYXIsIGNvbSBvIGVzdGFkbyBhdHVhbC4gKi9cclxuICAgIEBPdXRwdXQoKSBiZWZvcmVUb2dnbGUgPSBuZXcgRXZlbnRFbWl0dGVyPEZpZWxkU2V0VG9nZ2xlPigpO1xyXG4gICAgLyoqIEBkZXNjcmlwdGlvbiBFbWl0aWRvIGFww7NzIGEgYW5pbWHDp8OjbyBkZSB0b2dnbGUgY29uY2x1aXIsIGNvbSBvIG5vdm8gZXN0YWRvLiAqL1xyXG4gICAgQE91dHB1dCgpIGFmdGVyVG9nZ2xlID0gbmV3IEV2ZW50RW1pdHRlcjxGaWVsZFNldFRvZ2dsZT4oKTtcclxuICAgIGFjdGl2ZSA9IHRydWU7XHJcblxyXG4gICAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuaGVhZGVyVGVtcGxhdGUgPSB0aGlzLnRlbXBsYXRlRGlyZWN0aXZlcz8uZmluZCgodGVtcGxhdGUpID0+IHRlbXBsYXRlLnR5cGUgPT09ICdoZWFkZXInKT8udGVtcGxhdGU7XHJcbiAgICB9XHJcblxyXG4gICAgdG9nZ2xlQWN0aXZlKG9yaWdpbmFsRXZlbnQ6IFBvaW50ZXJFdmVudCB8IEtleWJvYXJkRXZlbnQpIHtcclxuICAgICAgICBpZiAoIXRoaXMudG9nZ2xlYWJsZSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuYmVmb3JlVG9nZ2xlLm5leHQoeyBjb2xsYXBzZWQ6IHRoaXMuYWN0aXZlLCBvcmlnaW5hbEV2ZW50IH0pO1xyXG4gICAgICAgIHRoaXMuYWN0aXZlID0gIXRoaXMuYWN0aXZlO1xyXG4gICAgICAgIHRoaXMuYWZ0ZXJUb2dnbGUubmV4dCh7IGNvbGxhcHNlZDogdGhpcy5hY3RpdmUsIG9yaWdpbmFsRXZlbnQgfSk7XHJcbiAgICB9XHJcbn1cclxuIiwiPGZpZWxkc2V0XHJcbiAgICBjbGFzcz1cImJnLWdyYXlzY2FsZS0wIGJvcmRlciBib3JkZXItZ3JheXNjYWxlLTIwIHJvdW5kZWQteGJpZyBtYi1bMTBweF0gbWluLWgtWzQuNWVtXSBweC0yIHB5LTEuNSB3LWZ1bGwgbWluLXctMFwiXHJcbj5cclxuICAgIDxsZWdlbmRcclxuICAgICAgICBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIHRleHQtZ3JheXNjYWxlLTkwIGZvbnQtb3Blbi1zYW5zIHRleHQtc20gZm9udC1ib2xkIHB4LTEgZ2FwLTEgbWwtNCBzZWxlY3Qtbm9uZVwiXHJcbiAgICAgICAgW2NsYXNzLmN1cnNvci1wb2ludGVyXT1cInRvZ2dsZWFibGVcIlxyXG4gICAgICAgIChzSW50ZXJhY3RpdmVDb250ZW50KT1cInRvZ2dsZUFjdGl2ZSgkZXZlbnQpXCJcclxuICAgID5cclxuICAgICAgICBAaWYgKHRvZ2dsZWFibGUpIHtcclxuICAgICAgICAgICAgQGlmIChhY3RpdmUpIHtcclxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLXBsdXNcIj48L2k+XHJcbiAgICAgICAgICAgIH0gQGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtbWludXNcIj48L2k+XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgQGlmIChoZWFkZXJUZW1wbGF0ZSkge1xyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiaGVhZGVyVGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cclxuICAgICAgICB9IEBlbHNlIHtcclxuICAgICAgICAgICAgQGlmIChpY29uKSB7XHJcbiAgICAgICAgICAgICAgICA8aSBbY2xhc3NdPVwiaWNvblwiPjwvaT5cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB7eyBsZWdlbmQgfX1cclxuICAgICAgICB9XHJcbiAgICA8L2xlZ2VuZD5cclxuICAgIEBpZiAoZGVzdHJveU9uSGlkZSA/ICh0b2dnbGVhYmxlID8gYWN0aXZlIDogdHJ1ZSkgOiB0cnVlKSB7XHJcbiAgICAgICAgPGRpdiBbQHRvZ2dsZUFuaW1hdGlvbl09XCJkZXN0cm95T25IaWRlID8gbnVsbCA6IGFjdGl2ZSA/ICdvcGVuJyA6ICdjbG9zZWQnXCI+XHJcbiAgICAgICAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIH1cclxuPC9maWVsZHNldD5cclxuIl19
115
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmllbGRzZXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1jb21wb25lbnRzL2ZpZWxkc2V0L3NyYy9saWIvZmllbGRzZXQvZmllbGRzZXQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1jb21wb25lbnRzL2ZpZWxkc2V0L3NyYy9saWIvZmllbGRzZXQvZmllbGRzZXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBa0IsS0FBSyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDakcsT0FBTyxFQUFpQixTQUFTLEVBQUUsUUFBUSxFQUFFLGVBQWUsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFeEgsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDbkQsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sd0RBQXdELENBQUM7QUFDckcsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNkNBQTZDLENBQUM7O0FBR2hGOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0JHO0FBdUJILE1BQU0sT0FBTyxpQkFBaUI7SUFDMUIsc0VBQXNFO0lBQ3RFLE1BQU0sR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDbkIseUdBQXlHO0lBQ3pHLFVBQVUsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDMUIsaUdBQWlHO0lBQ2pHLElBQUksR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDakIsa0dBQWtHO0lBQ2xHLGFBQWEsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7SUFFN0Isa0JBQWtCLEdBQUcsZUFBZSxD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QUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQzs0QkFDakQsVUFBVSxDQUFDLGlCQUFpQixFQUFFLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQzt5QkFDdkQsQ0FBQztxQkFDTCxjQUNXLElBQUksV0FDUCxDQUFDLDJCQUEyQixFQUFFLGdCQUFnQixDQUFDOzhCQXFCOUMsWUFBWTtzQkFBckIsTUFBTTtnQkFFRyxXQUFXO3NCQUFwQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgYW5pbWF0ZSwgQW5pbWF0aW9uRXZlbnQsIHN0YXRlLCBzdHlsZSwgdHJhbnNpdGlvbiwgdHJpZ2dlciB9IGZyb20gJ0Bhbmd1bGFyL2FuaW1hdGlvbnMnO1xyXG5pbXBvcnQgeyBBZnRlclZpZXdJbml0LCBDb21wb25lbnQsIGNvbXB1dGVkLCBjb250ZW50Q2hpbGRyZW4sIEV2ZW50RW1pdHRlciwgaW5wdXQsIG1vZGVsLCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuXHJcbmltcG9ydCB7IE5nVGVtcGxhdGVPdXRsZXQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBJbnRlcmFjdGl2ZUNvbnRlbnREaXJlY3RpdmUgfSBmcm9tICdAc2VuaW9yc2lzdGVtYXMvYW5ndWxhci1jb21wb25lbnRzL2ludGVyYWN0aXZlLWNvbnRlbnQnO1xyXG5pbXBvcnQgeyBUZW1wbGF0ZURpcmVjdGl2ZSB9IGZyb20gJ0BzZW5pb3JzaXN0ZW1hcy9hbmd1bGFyLWNvbXBvbmVudHMvdGVtcGxhdGUnO1xyXG5pbXBvcnQgeyBGaWVsZFNldFRvZ2dsZSB9IGZyb20gJy4vZmllbGRzZXQubW9kZWxzJztcclxuXHJcbi8qKlxyXG4gKiBAZGVzY3JpcHRpb24gQ29tcG9uZW50ZSBkZSBmaWVsZHNldCBjb20gbGVnZW5kYSwgw61jb25lIGNvbmZpZ3Vyw6F2ZWwgZSBzdXBvcnRlIGFcclxuICogdG9nZ2xlIChyZWNvbGhlci9leHBhbmRpcikgY29tIGFuaW1hw6fDo28uIFN1cG9ydGEgdGVtcGxhdGVzIHBlcnNvbmFsaXphZG9zIHZpYVxyXG4gKiBkaXJldGl2YSBgVGVtcGxhdGVEaXJlY3RpdmVgLCBjb20gb3MgdGlwb3MgYCdoZWFkZXInYCAoc3Vic3RpdHVpIGEgbGVnZW5kYSkgZVxyXG4gKiBgJ2JvZHknYCAoY29udGXDumRvIGRvIGZpZWxkc2V0KS5cclxuICpcclxuICogUHJlZmlyYSBkZWNsYXJhciBvIGNvbnRlw7pkbyBlbSBgc1RlbXBsYXRlPVwiYm9keVwiYCBlbSB2ZXogZGUgcHJvamV0w6EtbG8gZGlyZXRvOlxyXG4gKiBvIGBuZy1jb250ZW50YCDDqSBpbnN0YW5jaWFkbyBwZWxvIGNvbXBvbmVudGUgcGFpIG1lc21vIGNvbSBvIGZpZWxkc2V0IHJlY29saGlkbyxcclxuICogZGlzcGFyYW5kbyBvIGBuZ09uSW5pdGAgZG9zIGZpbGhvcyBwcmVtYXR1cmFtZW50ZS4gTyB0ZW1wbGF0ZSBkZSBjb3JwbyBzw7Mgw6lcclxuICogaW5zdGFuY2lhZG8gcXVhbmRvIG8gZmllbGRzZXQgZXN0w6EgZGUgZmF0byBhdGl2bywgZSDDqSBvYnJpZ2F0w7NyaW8gcGFyYSBxdWVcclxuICogYGRlc3Ryb3lPbkhpZGVgIGZ1bmNpb25lLlxyXG4gKlxyXG4gKiBAZXhhbXBsZVxyXG4gKiBgYGBodG1sXHJcbiAqIDxzLWZpZWxkc2V0IGxlZ2VuZD1cIkRhZG9zIHBlc3NvYWlzXCIgW3RvZ2dsZWFibGVdPVwidHJ1ZVwiPlxyXG4gKiAgIDxuZy10ZW1wbGF0ZSBzVGVtcGxhdGU9XCJib2R5XCI+XHJcbiAqICAgICA8cD5Db250ZcO6ZG8gZG8gZmllbGRzZXQ8L3A+XHJcbiAqICAgPC9uZy10ZW1wbGF0ZT5cclxuICogPC9zLWZpZWxkc2V0PlxyXG4gKiBgYGBcclxuICpcclxuICogQGNhdGVnb3J5IElucHV0c1xyXG4gKi9cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ3MtZmllbGRzZXQnLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL2ZpZWxkc2V0LmNvbXBvbmVudC5odG1sJyxcclxuICAgIHN0eWxlczogWyc6aG9zdCB7IGRpc3BsYXk6IGJsb2NrOyB9J10sXHJcbiAgICBhbmltYXRpb25zOiBbXHJcbiAgICAgICAgdHJpZ2dlcigndG9nZ2xlQW5pbWF0aW9uJywgW1xyXG4gICAgICAgICAgICB0cmFuc2l0aW9uKCc6ZW50ZXInLCBbXHJcbiAgICAgICAgICAgICAgICBzdHlsZSh7IG9wYWNpdHk6IDAsIGhlaWdodDogMCB9KSxcclxuICAgICAgICAgICAgICAgIGFuaW1hdGUoJzMwMG1zIGVhc2Utb3V0Jywgc3R5bGUoeyBvcGFjaXR5OiAxLCBoZWlnaHQ6ICcqJyB9KSksXHJcbiAgICAgICAgICAgIF0pLFxyXG4gICAgICAgICAgICB0cmFuc2l0aW9uKCc6bGVhdmUnLCBbXHJcbiAgICAgICAgICAgICAgICBzdHlsZSh7IG9wYWNpdHk6IDEsIGhlaWdodDogJyonIH0pLFxyXG4gICAgICAgICAgICAgICAgYW5pbWF0ZSgnMzAwbXMgZWFzZS1pbicsIHN0eWxlKHsgb3BhY2l0eTogMCwgaGVpZ2h0OiAwIH0pKSxcclxuICAgICAgICAgICAgXSksXHJcbiAgICAgICAgICAgIHN0YXRlKCdvcGVuJywgc3R5bGUoeyBvcGFjaXR5OiAxLCBoZWlnaHQ6ICcqJyB9KSksXHJcbiAgICAgICAgICAgIHN0YXRlKCdjbG9zZWQnLCBzdHlsZSh7IG9wYWNpdHk6IDAsIGhlaWdodDogMCB9KSksXHJcbiAgICAgICAgICAgIHRyYW5zaXRpb24oJ29wZW4gPD0+IGNsb3NlZCcsIGFuaW1hdGUoJzMwMG1zIGVhc2UnKSksXHJcbiAgICAgICAgXSksXHJcbiAgICBdLFxyXG4gICAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICAgIGltcG9ydHM6IFtJbnRlcmFjdGl2ZUNvbnRlbnREaXJlY3RpdmUsIE5nVGVtcGxhdGVPdXRsZXRdLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgRmllbGRzZXRDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0IHtcclxuICAgIC8qKiBAZGVzY3JpcHRpb24gVGV4dG8gZXhpYmlkbyBjb21vIHTDrXR1bG8gZG8gZmllbGRzZXQuIEBkZWZhdWx0ICcnICovXHJcbiAgICBsZWdlbmQgPSBpbnB1dCgnJyk7XHJcbiAgICAvKiogQGRlc2NyaXB0aW9uIEhhYmlsaXRhIG8gYm90w6NvIGRlIHRvZ2dsZSBxdWUgcGVybWl0ZSByZWNvbGhlciBlIGV4cGFuZGlyIG8gY29udGXDumRvLiBAZGVmYXVsdCBmYWxzZSAqL1xyXG4gICAgdG9nZ2xlYWJsZSA9IGlucHV0KGZhbHNlKTtcclxuICAgIC8qKiBAZGVzY3JpcHRpb24gQ2xhc3NlIGRlIMOtY29uZSBleGliaWRhIGFvIGxhZG8gZGEgbGVnZW5kYSAoZXguOiBgJ2ZhcyBmYS1jb2cnYCkuIEBkZWZhdWx0ICcnICovXHJcbiAgICBpY29uID0gaW5wdXQoJycpO1xyXG4gICAgLyoqIEBkZXNjcmlwdGlvbiBRdWFuZG8gYHRydWVgLCByZW1vdmUgbyBjb250ZcO6ZG8gZG8gRE9NIGFvIHJlY29saGVyIG8gZmllbGRzZXQuIEBkZWZhdWx0IGZhbHNlICovXHJcbiAgICBkZXN0cm95T25IaWRlID0gaW5wdXQoZmFsc2UpO1xyXG5cclxuICAgIHRlbXBsYXRlRGlyZWN0aXZlcyA9IGNvbnRlbnRDaGlsZHJlbihUZW1wbGF0ZURpcmVjdGl2ZSk7XHJcbiAgICBoZWFkZXJUZW1wbGF0ZSA9IGNvbXB1dGVkKCgpID0+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy50ZW1wbGF0ZURpcmVjdGl2ZXMoKT8uZmluZCgodGVtcGxhdGUpID0+IHRlbXBsYXRlLnR5cGUgPT09ICdoZWFkZXInKT8udGVtcGxhdGU7XHJcbiAgICB9KTtcclxuXHJcbiAgICBib2R5VGVtcGxhdGUgPSBjb21wdXRlZCgoKSA9PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudGVtcGxhdGVEaXJlY3RpdmVzKCk/LmZpbmQoKHRlbXBsYXRlKSA9PiB0ZW1wbGF0ZS50eXBlID09PSAnYm9keScpPy50ZW1wbGF0ZTtcclxuICAgIH0pO1xyXG4gICAgLyoqIEBkZXNjcmlwdGlvbiBFbWl0aWRvIGltZWRpYXRhbWVudGUgYW50ZXMgZGEgYW5pbWHDp8OjbyBkZSB0b2dnbGUgaW5pY2lhciwgY29tIG8gZXN0YWRvIGF0dWFsLiAqL1xyXG4gICAgQE91dHB1dCgpIGJlZm9yZVRvZ2dsZSA9IG5ldyBFdmVudEVtaXR0ZXI8RmllbGRTZXRUb2dnbGU+KCk7XHJcbiAgICAvKiogQGRlc2NyaXB0aW9uIEVtaXRpZG8gYXDDs3MgYSBhbmltYcOnw6NvIGRlIHRvZ2dsZSBjb25jbHVpciwgY29tIG8gbm92byBlc3RhZG8uICovXHJcbiAgICBAT3V0cHV0KCkgYWZ0ZXJUb2dnbGUgPSBuZXcgRXZlbnRFbWl0dGVyPEZpZWxkU2V0VG9nZ2xlPigpO1xyXG5cclxuICAgIGFjdGl2ZSA9IG1vZGVsKHRydWUpO1xyXG5cclxuICAgIHByb3RlY3RlZCBkaXNwbGF5VHlwZSA9ICdibG9jayc7XHJcblxyXG4gICAgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgICAgIGNvbnN0IGhhc0JvZHlUZW1wbGF0ZSA9IHRoaXMuYm9keVRlbXBsYXRlKCk7XHJcbiAgICAgICAgaWYgKCFoYXNCb2R5VGVtcGxhdGUgJiYgdGhpcy5kZXN0cm95T25IaWRlKCkpIHtcclxuICAgICAgICAgICAgY29uc29sZS53YXJuKFxyXG4gICAgICAgICAgICAgICAgJ0ZpZWxkc2V0Q29tcG9uZW50OiBPIHVzbyBkZSBkZXN0cm95T25IaWRlPXRydWUgcmVxdWVyIHVtIHRlbXBsYXRlIGRlIGNvcnBvIGRlZmluaWRvIGNvbSBzVGVtcGxhdGU9XCJib2R5XCIuJyxcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgdG9nZ2xlQWN0aXZlKG9yaWdpbmFsRXZlbnQ6IFBvaW50ZXJFdmVudCB8IEtleWJvYXJkRXZlbnQpIHtcclxuICAgICAgICBpZiAoIXRoaXMudG9nZ2xlYWJsZSgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5iZWZvcmVUb2dnbGUubmV4dCh7IGNvbGxhcHNlZDogdGhpcy5hY3RpdmUoKSwgb3JpZ2luYWxFdmVudCB9KTtcclxuICAgICAgICB0aGlzLmFjdGl2ZS5zZXQoIXRoaXMuYWN0aXZlKCkpO1xyXG4gICAgICAgIHRoaXMuYWZ0ZXJUb2dnbGUubmV4dCh7IGNvbGxhcHNlZDogdGhpcy5hY3RpdmUoKSwgb3JpZ2luYWxFdmVudCB9KTtcclxuICAgIH1cclxuXHJcbiAgICBoYW5kbGVBbmltYXRpb25TdGFydChldmVudDogQW5pbWF0aW9uRXZlbnQpIHtcclxuICAgICAgICBpZiAoZXZlbnQudG9TdGF0ZSA9PT0gJ29wZW4nKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZGlzcGxheVR5cGUgPSAnYmxvY2snO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBoYW5kbGVBbmltYXRpb25Eb25lKGV2ZW50OiBBbmltYXRpb25FdmVudCkge1xyXG4gICAgICAgIGlmIChldmVudC50b1N0YXRlID09PSAnY2xvc2VkJykge1xyXG4gICAgICAgICAgICB0aGlzLmRpc3BsYXlUeXBlID0gJ25vbmUnO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4iLCI8ZmllbGRzZXRcclxuICAgIGNsYXNzPVwibWItWzEwcHhdIG1pbi1oLVs0LjVlbV0gdy1mdWxsIG1pbi13LTAgcm91bmRlZC14YmlnIGJvcmRlciBib3JkZXItZ3JheXNjYWxlLTIwIGJnLWdyYXlzY2FsZS0wIHB4LTIgcHktMS41XCJcclxuPlxyXG4gICAgPGxlZ2VuZFxyXG4gICAgICAgIGNsYXNzPVwibWwtNCBmbGV4IHNlbGVjdC1ub25lIGl0ZW1zLWNlbnRlciBnYXAtMSBweC0xIGZvbnQtb3Blbi1zYW5zIHRleHQtc20gZm9udC1ib2xkIHRleHQtZ3JheXNjYWxlLTkwXCJcclxuICAgICAgICBbY2xhc3MuY3Vyc29yLXBvaW50ZXJdPVwidG9nZ2xlYWJsZSgpXCJcclxuICAgICAgICAoc0ludGVyYWN0aXZlQ29udGVudCk9XCJ0b2dnbGVBY3RpdmUoJGV2ZW50KVwiXHJcbiAgICA+XHJcbiAgICAgICAgQGlmICh0b2dnbGVhYmxlKCkpIHtcclxuICAgICAgICAgICAgQGlmIChhY3RpdmUoKSkge1xyXG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtbWludXNcIj48L2k+XHJcbiAgICAgICAgICAgIH0gQGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtcGx1c1wiPjwvaT5cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBAbGV0IF9oZWFkZXJUZW1wbGF0ZSA9IGhlYWRlclRlbXBsYXRlKCk7XHJcbiAgICAgICAgQGlmIChfaGVhZGVyVGVtcGxhdGUpIHtcclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIl9oZWFkZXJUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxyXG4gICAgICAgIH0gQGVsc2Uge1xyXG4gICAgICAgICAgICBAaWYgKGljb24oKSkge1xyXG4gICAgICAgICAgICAgICAgPGkgW2NsYXNzXT1cImljb24oKVwiPjwvaT5cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB7eyBsZWdlbmQoKSB9fVxyXG4gICAgICAgIH1cclxuICAgIDwvbGVnZW5kPlxyXG4gICAgQGlmIChkZXN0cm95T25IaWRlKCkgPyAodG9nZ2xlYWJsZSgpID8gYWN0aXZlKCkgOiB0cnVlKSA6IHRydWUpIHtcclxuICAgICAgICA8ZGl2XHJcbiAgICAgICAgICAgIFtjbGFzcy5oaWRkZW5dPVwiZGlzcGxheVR5cGUgPT09ICdub25lJ1wiXHJcbiAgICAgICAgICAgIFtjbGFzcy5ibG9ja109XCJkaXNwbGF5VHlwZSA9PT0gJ2Jsb2NrJ1wiXHJcbiAgICAgICAgICAgIFtAdG9nZ2xlQW5pbWF0aW9uXT1cImRlc3Ryb3lPbkhpZGUoKSA/IG51bGwgOiBhY3RpdmUoKSA/ICdvcGVuJyA6ICdjbG9zZWQnXCJcclxuICAgICAgICAgICAgKEB0b2dnbGVBbmltYXRpb24uc3RhcnQpPVwiaGFuZGxlQW5pbWF0aW9uU3RhcnQoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgIChAdG9nZ2xlQW5pbWF0aW9uLmRvbmUpPVwiaGFuZGxlQW5pbWF0aW9uRG9uZSgkZXZlbnQpXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICAgIEBsZXQgX2JvZHlUZW1wbGF0ZSA9IGJvZHlUZW1wbGF0ZSgpO1xyXG4gICAgICAgICAgICBAaWYgKF9ib2R5VGVtcGxhdGUpIHtcclxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJfYm9keVRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgIH0gQGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICB9XHJcbjwvZmllbGRzZXQ+XHJcbiJdfQ==
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Utilitário puro (sem dependência de Angular/NgZone) para aguardar até que a posição
3
+ * e o tamanho de um elemento parem de mudar — usado para medir corretamente elementos
4
+ * que podem estar em transição/animação (ex: um menu abrindo) no momento em que o
5
+ * Spotlight precisa apontar para eles.
6
+ */
7
+ export const DEFAULT_RECT_STABILITY_OPTIONS = {
8
+ requiredStableSamples: 3,
9
+ tolerancePx: 0.5,
10
+ maxWaitMs: 600,
11
+ };
12
+ function isRectStable(a, b, tolerancePx) {
13
+ return (Math.abs(a.top - b.top) <= tolerancePx &&
14
+ Math.abs(a.left - b.left) <= tolerancePx &&
15
+ Math.abs(a.width - b.width) <= tolerancePx &&
16
+ Math.abs(a.height - b.height) <= tolerancePx);
17
+ }
18
+ /**
19
+ * Faz polling de `el.getBoundingClientRect()` em frames sucessivos até que
20
+ * `requiredStableSamples` amostras consecutivas sejam iguais (dentro de `tolerancePx`),
21
+ * ou até que `maxWaitMs` seja atingido — o que ocorrer primeiro.
22
+ *
23
+ * `scheduleFrame`/`cancelFrame`/`now` são injetáveis para permitir testes determinísticos;
24
+ * por padrão usam as APIs nativas do navegador.
25
+ */
26
+ export function waitForStableRect(el, options = DEFAULT_RECT_STABILITY_OPTIONS, scheduleFrame = requestAnimationFrame, cancelFrame = cancelAnimationFrame, now = () => performance.now()) {
27
+ let cancelled = false;
28
+ let frameHandle = 0;
29
+ let resolveFn;
30
+ const promise = new Promise((resolve) => {
31
+ resolveFn = resolve;
32
+ });
33
+ const startedAt = now();
34
+ let lastRect = el.getBoundingClientRect();
35
+ let stableCount = 1;
36
+ const tick = () => {
37
+ if (cancelled)
38
+ return;
39
+ const rect = el.getBoundingClientRect();
40
+ stableCount = isRectStable(rect, lastRect, options.tolerancePx) ? stableCount + 1 : 1;
41
+ lastRect = rect;
42
+ if (stableCount >= options.requiredStableSamples) {
43
+ resolveFn({ rect, timedOut: false });
44
+ return;
45
+ }
46
+ if (now() - startedAt >= options.maxWaitMs) {
47
+ resolveFn({ rect, timedOut: true });
48
+ return;
49
+ }
50
+ frameHandle = scheduleFrame(tick);
51
+ };
52
+ frameHandle = scheduleFrame(tick);
53
+ return {
54
+ promise,
55
+ cancel: () => {
56
+ cancelled = true;
57
+ cancelFrame(frameHandle);
58
+ },
59
+ };
60
+ }
61
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjdC1zdGFiaWxpdHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLWNvbXBvbmVudHMvc3BvdGxpZ2h0L3NyYy9saWIvc3BvdGxpZ2h0L3Nwb3RsaWdodC1vdmVybGF5L3JlY3Qtc3RhYmlsaXR5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7OztHQUtHO0FBV0gsTUFBTSxDQUFDLE1BQU0sOEJBQThCLEdBQXlCO0lBQ2hFLHFCQUFxQixFQUFFLENBQUM7SUFDeEIsV0FBVyxFQUFFLEdBQUc7SUFDaEIsU0FBUyxFQUFFLEdBQUc7Q0FDakIsQ0FBQztBQVlGLFNBQVMsWUFBWSxDQUFDLENBQVUsRUFBRSxDQUFVLEVBQUUsV0FBbUI7SUFDN0QsT0FBTyxDQUNILElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksV0FBVztRQUN0QyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLFdBQVc7UUFDeEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxXQUFXO1FBQzFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksV0FBVyxDQUMvQyxDQUFDO0FBQ04sQ0FBQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUsaUJBQWlCLENBQzdCLEVBQWUsRUFDZixVQUFnQyw4QkFBOEIsRUFDOUQsZ0JBQXNELHFCQUFxQixFQUMzRSxjQUF3QyxvQkFBb0IsRUFDNUQsTUFBb0IsR0FBRyxFQUFFLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRTtJQUUzQyxJQUFJLFNBQVMsR0FBRyxLQUFLLENBQUM7SUFDdEIsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDO0lBQ3BCLElBQUksU0FBOEMsQ0FBQztJQUVuRCxNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBbUIsQ0FBQyxPQUFPLEVBQUUsRUFBRTtRQUN0RCxTQUFTLEdBQUcsT0FBTyxDQUFDO0lBQ3hCLENBQUMsQ0FBQyxDQUFDO0lBRUgsTUFBTSxTQUFTLEdBQUcsR0FBRyxFQUFFLENBQUM7SUFDeEIsSUFBSSxRQUFRLEdBQUcsRUFBRSxDQUFDLHFCQUFxQixFQUFFLENBQUM7SUFDMUMsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDO0lBRXBCLE1BQU0sSUFBSSxHQUFHLEdBQVMsRUFBRTtRQUNwQixJQUFJLFNBQVM7WUFBRSxPQUFPO1FBRXRCLE1BQU0sSUFBSSxHQUFHLEVBQUUsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQ3hDLFdBQVcsR0FBRyxZQUFZLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0RixRQUFRLEdBQUcsSUFBSSxDQUFDO1FBRWhCLElBQUksV0FBVyxJQUFJLE9BQU8sQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBQy9DLFNBQVMsQ0FBQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUNyQyxPQUFPO1FBQ1gsQ0FBQztRQUNELElBQUksR0FBRyxFQUFFLEdBQUcsU0FBUyxJQUFJLE9BQU8sQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUN6QyxTQUFTLENBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7WUFDcEMsT0FBTztRQUNYLENBQUM7UUFDRCxXQUFXLEdBQUcsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3RDLENBQUMsQ0FBQztJQUVGLFdBQVcsR0FBRyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFbEMsT0FBTztRQUNILE9BQU87UUFDUCxNQUFNLEVBQUUsR0FBUyxFQUFFO1lBQ2YsU0FBUyxHQUFHLElBQUksQ0FBQztZQUNqQixXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDN0IsQ0FBQztLQUNKLENBQUM7QUFDTixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBVdGlsaXTDoXJpbyBwdXJvIChzZW0gZGVwZW5kw6puY2lhIGRlIEFuZ3VsYXIvTmdab25lKSBwYXJhIGFndWFyZGFyIGF0w6kgcXVlIGEgcG9zacOnw6NvXG4gKiBlIG8gdGFtYW5obyBkZSB1bSBlbGVtZW50byBwYXJlbSBkZSBtdWRhciDigJQgdXNhZG8gcGFyYSBtZWRpciBjb3JyZXRhbWVudGUgZWxlbWVudG9zXG4gKiBxdWUgcG9kZW0gZXN0YXIgZW0gdHJhbnNpw6fDo28vYW5pbWHDp8OjbyAoZXg6IHVtIG1lbnUgYWJyaW5kbykgbm8gbW9tZW50byBlbSBxdWUgb1xuICogU3BvdGxpZ2h0IHByZWNpc2EgYXBvbnRhciBwYXJhIGVsZXMuXG4gKi9cblxuZXhwb3J0IGludGVyZmFjZSBSZWN0U3RhYmlsaXR5T3B0aW9ucyB7XG4gICAgLyoqIFF1YW50YXMgYW1vc3RyYXMgY29uc2VjdXRpdmFzIGRlbnRybyBkYSB0b2xlcsOibmNpYSBkZWZpbmVtIFwiZXN0w6F2ZWxcIi4gKi9cbiAgICByZXF1aXJlZFN0YWJsZVNhbXBsZXM6IG51bWJlcjtcbiAgICAvKiogRGlmZXJlbsOnYSBtw6F4aW1hIChweCkgZW50cmUgZHVhcyBhbW9zdHJhcyBwYXJhIHNlcmVtIGNvbnNpZGVyYWRhcyBpZ3VhaXMuICovXG4gICAgdG9sZXJhbmNlUHg6IG51bWJlcjtcbiAgICAvKiogVGV0byBkZSBzZWd1cmFuw6dhIChtcykg4oCUIG51bmNhIGVzcGVyYXIgYWzDqW0gZGlzc28uICovXG4gICAgbWF4V2FpdE1zOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1JFQ1RfU1RBQklMSVRZX09QVElPTlM6IFJlY3RTdGFiaWxpdHlPcHRpb25zID0ge1xuICAgIHJlcXVpcmVkU3RhYmxlU2FtcGxlczogMyxcbiAgICB0b2xlcmFuY2VQeDogMC41LFxuICAgIG1heFdhaXRNczogNjAwLFxufTtcblxuZXhwb3J0IGludGVyZmFjZSBTdGFibGVSZWN0UmVzdWx0IHtcbiAgICByZWN0OiBET01SZWN0O1xuICAgIHRpbWVkT3V0OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFN0YWJpbGl6ZUhhbmRsZSB7XG4gICAgcmVhZG9ubHkgcHJvbWlzZTogUHJvbWlzZTxTdGFibGVSZWN0UmVzdWx0PjtcbiAgICBjYW5jZWwoKTogdm9pZDtcbn1cblxuZnVuY3Rpb24gaXNSZWN0U3RhYmxlKGE6IERPTVJlY3QsIGI6IERPTVJlY3QsIHRvbGVyYW5jZVB4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgICBNYXRoLmFicyhhLnRvcCAtIGIudG9wKSA8PSB0b2xlcmFuY2VQeCAmJlxuICAgICAgICBNYXRoLmFicyhhLmxlZnQgLSBiLmxlZnQpIDw9IHRvbGVyYW5jZVB4ICYmXG4gICAgICAgIE1hdGguYWJzKGEud2lkdGggLSBiLndpZHRoKSA8PSB0b2xlcmFuY2VQeCAmJlxuICAgICAgICBNYXRoLmFicyhhLmhlaWdodCAtIGIuaGVpZ2h0KSA8PSB0b2xlcmFuY2VQeFxuICAgICk7XG59XG5cbi8qKlxuICogRmF6IHBvbGxpbmcgZGUgYGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpYCBlbSBmcmFtZXMgc3VjZXNzaXZvcyBhdMOpIHF1ZVxuICogYHJlcXVpcmVkU3RhYmxlU2FtcGxlc2AgYW1vc3RyYXMgY29uc2VjdXRpdmFzIHNlamFtIGlndWFpcyAoZGVudHJvIGRlIGB0b2xlcmFuY2VQeGApLFxuICogb3UgYXTDqSBxdWUgYG1heFdhaXRNc2Agc2VqYSBhdGluZ2lkbyDigJQgbyBxdWUgb2NvcnJlciBwcmltZWlyby5cbiAqXG4gKiBgc2NoZWR1bGVGcmFtZWAvYGNhbmNlbEZyYW1lYC9gbm93YCBzw6NvIGluamV0w6F2ZWlzIHBhcmEgcGVybWl0aXIgdGVzdGVzIGRldGVybWluw61zdGljb3M7XG4gKiBwb3IgcGFkcsOjbyB1c2FtIGFzIEFQSXMgbmF0aXZhcyBkbyBuYXZlZ2Fkb3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3YWl0Rm9yU3RhYmxlUmVjdChcbiAgICBlbDogSFRNTEVsZW1lbnQsXG4gICAgb3B0aW9uczogUmVjdFN0YWJpbGl0eU9wdGlvbnMgPSBERUZBVUxUX1JFQ1RfU1RBQklMSVRZX09QVElPTlMsXG4gICAgc2NoZWR1bGVGcmFtZTogKGNiOiBGcmFtZVJlcXVlc3RDYWxsYmFjaykgPT4gbnVtYmVyID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lLFxuICAgIGNhbmNlbEZyYW1lOiAoaGFuZGxlOiBudW1iZXIpID0+IHZvaWQgPSBjYW5jZWxBbmltYXRpb25GcmFtZSxcbiAgICBub3c6ICgpID0+IG51bWJlciA9ICgpID0+IHBlcmZvcm1hbmNlLm5vdygpLFxuKTogU3RhYmlsaXplSGFuZGxlIHtcbiAgICBsZXQgY2FuY2VsbGVkID0gZmFsc2U7XG4gICAgbGV0IGZyYW1lSGFuZGxlID0gMDtcbiAgICBsZXQgcmVzb2x2ZUZuITogKHJlc3VsdDogU3RhYmxlUmVjdFJlc3VsdCkgPT4gdm9pZDtcblxuICAgIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZTxTdGFibGVSZWN0UmVzdWx0PigocmVzb2x2ZSkgPT4ge1xuICAgICAgICByZXNvbHZlRm4gPSByZXNvbHZlO1xuICAgIH0pO1xuXG4gICAgY29uc3Qgc3RhcnRlZEF0ID0gbm93KCk7XG4gICAgbGV0IGxhc3RSZWN0ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgbGV0IHN0YWJsZUNvdW50ID0gMTtcblxuICAgIGNvbnN0IHRpY2sgPSAoKTogdm9pZCA9PiB7XG4gICAgICAgIGlmIChjYW5jZWxsZWQpIHJldHVybjtcblxuICAgICAgICBjb25zdCByZWN0ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIHN0YWJsZUNvdW50ID0gaXNSZWN0U3RhYmxlKHJlY3QsIGxhc3RSZWN0LCBvcHRpb25zLnRvbGVyYW5jZVB4KSA/IHN0YWJsZUNvdW50ICsgMSA6IDE7XG4gICAgICAgIGxhc3RSZWN0ID0gcmVjdDtcblxuICAgICAgICBpZiAoc3RhYmxlQ291bnQgPj0gb3B0aW9ucy5yZXF1aXJlZFN0YWJsZVNhbXBsZXMpIHtcbiAgICAgICAgICAgIHJlc29sdmVGbih7IHJlY3QsIHRpbWVkT3V0OiBmYWxzZSB9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAobm93KCkgLSBzdGFydGVkQXQgPj0gb3B0aW9ucy5tYXhXYWl0TXMpIHtcbiAgICAgICAgICAgIHJlc29sdmVGbih7IHJlY3QsIHRpbWVkT3V0OiB0cnVlIH0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGZyYW1lSGFuZGxlID0gc2NoZWR1bGVGcmFtZSh0aWNrKTtcbiAgICB9O1xuXG4gICAgZnJhbWVIYW5kbGUgPSBzY2hlZHVsZUZyYW1lKHRpY2spO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgcHJvbWlzZSxcbiAgICAgICAgY2FuY2VsOiAoKTogdm9pZCA9PiB7XG4gICAgICAgICAgICBjYW5jZWxsZWQgPSB0cnVlO1xuICAgICAgICAgICAgY2FuY2VsRnJhbWUoZnJhbWVIYW5kbGUpO1xuICAgICAgICB9LFxuICAgIH07XG59XG5cbiJdfQ==