@seniorsistemas/components-ai 0.0.0-master-d4a804fe
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.
- package/CHANGELOG.md +101 -0
- package/CONTRIBUTING.md +317 -0
- package/README.md +161 -0
- package/docs/API.md +486 -0
- package/docs/COMPONENTS.md +272 -0
- package/docs/EXAMPLES.md +559 -0
- package/docs/MIGRATION.md +367 -0
- package/esm2022/lib/angular-components.module.mjs +25 -0
- package/esm2022/lib/components/breadcrumb/breadcrumb.component.mjs +121 -0
- package/esm2022/lib/components/bulk-delete-dialog/bulk-delete-dialog.component.mjs +176 -0
- package/esm2022/lib/components/dynamic-form/dynamic-form.component.mjs +625 -0
- package/esm2022/lib/components/dynamic-form/fields/dynamic-field-date.component.mjs +86 -0
- package/esm2022/lib/components/dynamic-form/fields/dynamic-field-dropdown.component.mjs +103 -0
- package/esm2022/lib/components/dynamic-form/fields/dynamic-field-lookup.component.mjs +599 -0
- package/esm2022/lib/components/dynamic-form/fields/dynamic-field-number.component.mjs +92 -0
- package/esm2022/lib/components/dynamic-form/fields/dynamic-field-text.component.mjs +163 -0
- package/esm2022/lib/components/dynamic-form/fields/dynamic-field-textarea.component.mjs +81 -0
- package/esm2022/lib/components/dynamic-form/fields/dynamic-field-wrapper.component.mjs +93 -0
- package/esm2022/lib/components/dynamic-form/fields/index.mjs +8 -0
- package/esm2022/lib/components/dynamic-form/models/dynamic-form.models.mjs +2 -0
- package/esm2022/lib/components/export-dialog/export-dialog.component.mjs +219 -0
- package/esm2022/lib/config/translation.config.mjs +70 -0
- package/esm2022/lib/directives/cep-mask.directive.mjs +79 -0
- package/esm2022/lib/directives/document-mask.directive.mjs +62 -0
- package/esm2022/lib/directives/phone-mask.directive.mjs +59 -0
- package/esm2022/lib/interceptors/api.interceptor.mjs +55 -0
- package/esm2022/lib/models/base-entity.interface.mjs +2 -0
- package/esm2022/lib/models/entity-list.config.mjs +2 -0
- package/esm2022/lib/pipes/translate.pipe.mjs +74 -0
- package/esm2022/lib/services/auth.service.mjs +169 -0
- package/esm2022/lib/services/cookie.service.mjs +90 -0
- package/esm2022/lib/services/entity.service.mjs +208 -0
- package/esm2022/lib/services/mask.service.mjs +121 -0
- package/esm2022/lib/services/permission.service.mjs +180 -0
- package/esm2022/lib/services/senior-token.service.mjs +209 -0
- package/esm2022/lib/services/theme.service.mjs +85 -0
- package/esm2022/lib/services/translation.service.mjs +232 -0
- package/esm2022/public-api.mjs +90 -0
- package/esm2022/seniorsistemas-components-ai.mjs +5 -0
- package/fesm2022/seniorsistemas-components-ai.mjs +4006 -0
- package/fesm2022/seniorsistemas-components-ai.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/angular-components.module.d.ts +13 -0
- package/lib/components/breadcrumb/breadcrumb.component.d.ts +23 -0
- package/lib/components/bulk-delete-dialog/bulk-delete-dialog.component.d.ts +46 -0
- package/lib/components/dynamic-form/dynamic-form.component.d.ts +97 -0
- package/lib/components/dynamic-form/fields/dynamic-field-date.component.d.ts +16 -0
- package/lib/components/dynamic-form/fields/dynamic-field-dropdown.component.d.ts +17 -0
- package/lib/components/dynamic-form/fields/dynamic-field-lookup.component.d.ts +52 -0
- package/lib/components/dynamic-form/fields/dynamic-field-number.component.d.ts +16 -0
- package/lib/components/dynamic-form/fields/dynamic-field-text.component.d.ts +17 -0
- package/lib/components/dynamic-form/fields/dynamic-field-textarea.component.d.ts +16 -0
- package/lib/components/dynamic-form/fields/dynamic-field-wrapper.component.d.ts +20 -0
- package/lib/components/dynamic-form/fields/index.d.ts +7 -0
- package/lib/components/dynamic-form/models/dynamic-form.models.d.ts +178 -0
- package/lib/components/export-dialog/export-dialog.component.d.ts +56 -0
- package/lib/config/translation.config.d.ts +24 -0
- package/lib/directives/cep-mask.directive.d.ts +13 -0
- package/lib/directives/document-mask.directive.d.ts +19 -0
- package/lib/directives/phone-mask.directive.d.ts +11 -0
- package/lib/interceptors/api.interceptor.d.ts +2 -0
- package/lib/models/base-entity.interface.d.ts +7 -0
- package/lib/models/entity-list.config.d.ts +161 -0
- package/lib/pipes/translate.pipe.d.ts +21 -0
- package/lib/services/auth.service.d.ts +82 -0
- package/lib/services/cookie.service.d.ts +31 -0
- package/lib/services/entity.service.d.ts +99 -0
- package/lib/services/mask.service.d.ts +36 -0
- package/lib/services/permission.service.d.ts +91 -0
- package/lib/services/senior-token.service.d.ts +70 -0
- package/lib/services/theme.service.d.ts +16 -0
- package/lib/services/translation.service.d.ts +54 -0
- package/package.json +53 -0
- package/public-api.d.ts +17 -0
- package/src/lib/styles/entity-list.shared.scss +383 -0
- package/src/lib/styles/index.scss +10 -0
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
# Guia de Migração
|
|
2
|
+
|
|
3
|
+
## 📦 Migrando para @seniorsistemas/components-ia
|
|
4
|
+
|
|
5
|
+
Este guia ajuda na migração de projetos que usavam componentes antigos ou outras bibliotecas.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 🔄 Migração de @senior-gestao-relacionamento/angular-components
|
|
10
|
+
|
|
11
|
+
Se você está migrando do pacote antigo `@senior-gestao-relacionamento/angular-components`:
|
|
12
|
+
|
|
13
|
+
### 1. Atualizar Dependência
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Remover pacote antigo
|
|
17
|
+
npm uninstall @senior-gestao-relacionamento/angular-components
|
|
18
|
+
|
|
19
|
+
# Instalar novo pacote
|
|
20
|
+
npm install @seniorsistemas/components-ia
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### 2. Atualizar Imports
|
|
24
|
+
|
|
25
|
+
Substituir todos os imports:
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
// Antes
|
|
29
|
+
import { DynamicFormComponent } from '@senior-gestao-relacionamento/angular-components';
|
|
30
|
+
|
|
31
|
+
// Depois
|
|
32
|
+
import { DynamicFormComponent } from '@seniorsistemas/components-ia';
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Script para substituição em massa (Linux/Mac):**
|
|
36
|
+
```bash
|
|
37
|
+
find src -type f -name "*.ts" -exec sed -i 's/@senior-gestao-relacionamento\/angular-components/@seniorsistemas\/components-ia/g' {} +
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Script para substituição em massa (Windows PowerShell):**
|
|
41
|
+
```powershell
|
|
42
|
+
Get-ChildItem -Path src -Filter *.ts -Recurse | ForEach-Object {
|
|
43
|
+
(Get-Content $_.FullName) -replace '@senior-gestao-relacionamento/angular-components', '@seniorsistemas/components-ia' |
|
|
44
|
+
Set-Content $_.FullName
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 3. Atualizar Prefixos de Componentes
|
|
49
|
+
|
|
50
|
+
Os componentes agora usam o prefixo `sia-` ao invés de `sgr-`:
|
|
51
|
+
|
|
52
|
+
```html
|
|
53
|
+
<!-- Antes -->
|
|
54
|
+
<sgr-dynamic-form></sgr-dynamic-form>
|
|
55
|
+
<sgr-export-dialog></sgr-export-dialog>
|
|
56
|
+
<sgr-breadcrumb></sgr-breadcrumb>
|
|
57
|
+
|
|
58
|
+
<!-- Depois -->
|
|
59
|
+
<sia-dynamic-form></sia-dynamic-form>
|
|
60
|
+
<sia-export-dialog></sia-export-dialog>
|
|
61
|
+
<sia-breadcrumb></sia-breadcrumb>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Script para substituição em massa (Linux/Mac):**
|
|
65
|
+
```bash
|
|
66
|
+
find src -type f -name "*.html" -exec sed -i 's/<sgr-/<sia-/g' {} +
|
|
67
|
+
find src -type f -name "*.html" -exec sed -i 's/<\/sgr-/<\/sia-/g' {} +
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Script para substituição em massa (Windows PowerShell):**
|
|
71
|
+
```powershell
|
|
72
|
+
Get-ChildItem -Path src -Filter *.html -Recurse | ForEach-Object {
|
|
73
|
+
(Get-Content $_.FullName) -replace '<sgr-', '<sia-' -replace '</sgr-', '</sia-' |
|
|
74
|
+
Set-Content $_.FullName
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 4. Recompilar
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npm run build
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## 🔄 Migração de Componentes Legados
|
|
87
|
+
|
|
88
|
+
### De EntityFormDialogComponent para DynamicFormComponent
|
|
89
|
+
|
|
90
|
+
**Antes:**
|
|
91
|
+
```typescript
|
|
92
|
+
<app-entity-form-dialog
|
|
93
|
+
[(visible)]="showDialog"
|
|
94
|
+
[entity]="selectedEntity"
|
|
95
|
+
[formFields]="formFields"
|
|
96
|
+
[service]="entityService"
|
|
97
|
+
[entityName]="'Product'"
|
|
98
|
+
(onSave)="loadData()"
|
|
99
|
+
></app-entity-form-dialog>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Depois:**
|
|
103
|
+
```typescript
|
|
104
|
+
<sia-dynamic-form
|
|
105
|
+
[(visible)]="showDialog"
|
|
106
|
+
[entity]="selectedEntity"
|
|
107
|
+
[formFields]="formFields"
|
|
108
|
+
[mode]="selectedEntity ? 'edit' : 'create'"
|
|
109
|
+
[displayMode]="'dialog'"
|
|
110
|
+
[dialogHeader]="selectedEntity ? 'Editar Produto' : 'Novo Produto'"
|
|
111
|
+
(onSubmit)="handleSubmit($event)"
|
|
112
|
+
></sia-dynamic-form>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Mudanças no TypeScript:**
|
|
116
|
+
```typescript
|
|
117
|
+
// Antes
|
|
118
|
+
onSave(): void {
|
|
119
|
+
this.loadData();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Depois
|
|
123
|
+
handleSubmit(formValue: any): void {
|
|
124
|
+
const operation = this.selectedEntity
|
|
125
|
+
? this.entityService.update(this.selectedEntity.id, formValue)
|
|
126
|
+
: this.entityService.insert(formValue);
|
|
127
|
+
|
|
128
|
+
operation.subscribe({
|
|
129
|
+
next: () => {
|
|
130
|
+
this.messageService.add({
|
|
131
|
+
severity: 'success',
|
|
132
|
+
summary: 'Sucesso',
|
|
133
|
+
detail: 'Registro salvo com sucesso'
|
|
134
|
+
});
|
|
135
|
+
this.showDialog = false;
|
|
136
|
+
this.loadData();
|
|
137
|
+
},
|
|
138
|
+
error: (error: any) => {
|
|
139
|
+
this.messageService.add({
|
|
140
|
+
severity: 'error',
|
|
141
|
+
summary: 'Erro',
|
|
142
|
+
detail: 'Erro ao salvar registro'
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
### De FormFilterComponent para DynamicFormComponent
|
|
152
|
+
|
|
153
|
+
**Antes:**
|
|
154
|
+
```typescript
|
|
155
|
+
<app-form-filter
|
|
156
|
+
[filterFields]="filterFields"
|
|
157
|
+
(onFilter)="applyFilter($event)"
|
|
158
|
+
></app-form-filter>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Depois:**
|
|
162
|
+
```typescript
|
|
163
|
+
<sia-dynamic-form
|
|
164
|
+
[formFields]="filterFields"
|
|
165
|
+
[mode]="'filter'"
|
|
166
|
+
[submitButtonLabel]="'Filtrar'"
|
|
167
|
+
(onSubmit)="applyFilter($event)"
|
|
168
|
+
></sia-dynamic-form>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Mudanças no TypeScript:**
|
|
172
|
+
```typescript
|
|
173
|
+
// Antes
|
|
174
|
+
applyFilter(filters: any): void {
|
|
175
|
+
this.filters = filters;
|
|
176
|
+
this.loadData();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Depois
|
|
180
|
+
applyFilter(filterValues: any): void {
|
|
181
|
+
// Remover valores vazios
|
|
182
|
+
const filters = Object.entries(filterValues)
|
|
183
|
+
.filter(([_, value]) => value !== null && value !== undefined && value !== '')
|
|
184
|
+
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {});
|
|
185
|
+
|
|
186
|
+
this.filters = filters;
|
|
187
|
+
this.loadData();
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
### De EditInlineComponent para DynamicFormComponent
|
|
194
|
+
|
|
195
|
+
**Antes:**
|
|
196
|
+
```typescript
|
|
197
|
+
<app-edit-inline
|
|
198
|
+
[fields]="editFields"
|
|
199
|
+
[entity]="entity"
|
|
200
|
+
(onSave)="handleSave($event)"
|
|
201
|
+
></app-edit-inline>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**Depois:**
|
|
205
|
+
```typescript
|
|
206
|
+
<sia-dynamic-form
|
|
207
|
+
[formFields]="editFields"
|
|
208
|
+
[entity]="entity"
|
|
209
|
+
[mode]="'inline-edit'"
|
|
210
|
+
(onSubmit)="handleSave($event)"
|
|
211
|
+
></sia-dynamic-form>
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## 🆕 Novos Recursos
|
|
217
|
+
|
|
218
|
+
### Suporte a Seções
|
|
219
|
+
|
|
220
|
+
O DynamicFormComponent agora suporta seções colapsáveis:
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
formSections: DynamicFormSection[] = [
|
|
224
|
+
{
|
|
225
|
+
title: 'Dados Básicos',
|
|
226
|
+
fields: [/* campos */]
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
title: 'Endereço',
|
|
230
|
+
collapsible: true,
|
|
231
|
+
collapsed: true,
|
|
232
|
+
fields: [/* campos */]
|
|
233
|
+
}
|
|
234
|
+
];
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
```html
|
|
238
|
+
<sia-dynamic-form
|
|
239
|
+
[formSections]="formSections"
|
|
240
|
+
[mode]="'create'"
|
|
241
|
+
(onSubmit)="handleSubmit($event)"
|
|
242
|
+
></sia-dynamic-form>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Modo Inline Edit
|
|
246
|
+
|
|
247
|
+
Novo modo para edição inline sem botões de ação:
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
<sia-dynamic-form
|
|
251
|
+
[formFields]="fields"
|
|
252
|
+
[entity]="entity"
|
|
253
|
+
[mode]="'inline-edit'"
|
|
254
|
+
(onSubmit)="handleSubmit($event)"
|
|
255
|
+
></sia-dynamic-form>
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Display Modes
|
|
259
|
+
|
|
260
|
+
Três modos de exibição:
|
|
261
|
+
|
|
262
|
+
- `inline`: Formulário inline (padrão)
|
|
263
|
+
- `dialog`: Formulário em dialog modal
|
|
264
|
+
- `drawer`: Formulário em drawer lateral
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## ⚠️ Breaking Changes
|
|
269
|
+
|
|
270
|
+
### 1. Método create() renomeado para insert()
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
// Antes
|
|
274
|
+
this.entityService.create(entity);
|
|
275
|
+
|
|
276
|
+
// Depois
|
|
277
|
+
this.entityService.insert(entity);
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### 2. Evento onSave renomeado para onSubmit
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
// Antes
|
|
284
|
+
(onSave)="handleSave($event)"
|
|
285
|
+
|
|
286
|
+
// Depois
|
|
287
|
+
(onSubmit)="handleSubmit($event)"
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### 3. Prefixo de componentes alterado
|
|
291
|
+
|
|
292
|
+
Todos os componentes agora usam `sia-` ao invés de `sgr-`.
|
|
293
|
+
|
|
294
|
+
### 4. Estrutura de FormFields
|
|
295
|
+
|
|
296
|
+
O campo `cols` agora é obrigatório para controle de layout:
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
// Antes
|
|
300
|
+
{
|
|
301
|
+
name: 'name',
|
|
302
|
+
label: 'Nome',
|
|
303
|
+
type: FieldType.TEXT
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Depois
|
|
307
|
+
{
|
|
308
|
+
name: 'name',
|
|
309
|
+
label: 'Nome',
|
|
310
|
+
type: FieldType.TEXT,
|
|
311
|
+
cols: 12 // 1-12 (grid de 12 colunas)
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## 📋 Checklist de Migração
|
|
318
|
+
|
|
319
|
+
- [ ] Atualizar dependência no package.json
|
|
320
|
+
- [ ] Substituir imports em arquivos TypeScript
|
|
321
|
+
- [ ] Atualizar prefixos de componentes em templates HTML
|
|
322
|
+
- [ ] Substituir `create()` por `insert()` nos serviços
|
|
323
|
+
- [ ] Atualizar eventos `onSave` para `onSubmit`
|
|
324
|
+
- [ ] Adicionar propriedade `cols` nos formFields
|
|
325
|
+
- [ ] Testar compilação
|
|
326
|
+
- [ ] Testar funcionalidades em desenvolvimento
|
|
327
|
+
- [ ] Executar testes automatizados
|
|
328
|
+
- [ ] Atualizar documentação do projeto
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
## 🆘 Problemas Comuns
|
|
333
|
+
|
|
334
|
+
### Erro: Module not found '@senior-gestao-relacionamento/angular-components'
|
|
335
|
+
|
|
336
|
+
**Solução:** Certifique-se de ter atualizado todos os imports. Use os scripts de substituição em massa fornecidos acima.
|
|
337
|
+
|
|
338
|
+
### Erro: Property 'create' does not exist on type 'EntityService'
|
|
339
|
+
|
|
340
|
+
**Solução:** Substitua `create()` por `insert()`.
|
|
341
|
+
|
|
342
|
+
### Componentes não aparecem no template
|
|
343
|
+
|
|
344
|
+
**Solução:** Verifique se atualizou os prefixos de `sgr-` para `sia-`.
|
|
345
|
+
|
|
346
|
+
### Erro de compilação em formFields
|
|
347
|
+
|
|
348
|
+
**Solução:** Adicione a propriedade `cols` em todos os campos.
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
## 📞 Suporte
|
|
353
|
+
|
|
354
|
+
Se encontrar problemas durante a migração:
|
|
355
|
+
|
|
356
|
+
1. Consulte a [documentação completa](./COMPONENTS.md)
|
|
357
|
+
2. Veja os [exemplos práticos](./EXAMPLES.md)
|
|
358
|
+
3. Abra uma issue no repositório
|
|
359
|
+
4. Entre em contato com a equipe de desenvolvimento
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## 🔗 Veja Também
|
|
364
|
+
|
|
365
|
+
- [Documentação de Componentes](./COMPONENTS.md)
|
|
366
|
+
- [Exemplos Práticos](./EXAMPLES.md)
|
|
367
|
+
- [Referência da API](./API.md)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* Módulo principal da biblioteca @seniorsistemas/components-ia
|
|
6
|
+
*
|
|
7
|
+
* Este módulo será populado conforme os componentes forem migrados.
|
|
8
|
+
* Por enquanto, é um módulo vazio para permitir o build inicial.
|
|
9
|
+
*/
|
|
10
|
+
export class AngularComponentsModule {
|
|
11
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AngularComponentsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
12
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: AngularComponentsModule, imports: [CommonModule] });
|
|
13
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AngularComponentsModule, imports: [CommonModule] });
|
|
14
|
+
}
|
|
15
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AngularComponentsModule, decorators: [{
|
|
16
|
+
type: NgModule,
|
|
17
|
+
args: [{
|
|
18
|
+
declarations: [],
|
|
19
|
+
imports: [
|
|
20
|
+
CommonModule
|
|
21
|
+
],
|
|
22
|
+
exports: []
|
|
23
|
+
}]
|
|
24
|
+
}] });
|
|
25
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhci1jb21wb25lbnRzLm1vZHVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMtYWkvc3JjL2xpYi9hbmd1bGFyLWNvbXBvbmVudHMubW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDOztBQUUvQzs7Ozs7R0FLRztBQVFILE1BQU0sT0FBTyx1QkFBdUI7d0dBQXZCLHVCQUF1Qjt5R0FBdkIsdUJBQXVCLFlBSmhDLFlBQVk7eUdBSUgsdUJBQXVCLFlBSmhDLFlBQVk7OzRGQUlILHVCQUF1QjtrQkFQbkMsUUFBUTttQkFBQztvQkFDUixZQUFZLEVBQUUsRUFBRTtvQkFDaEIsT0FBTyxFQUFFO3dCQUNQLFlBQVk7cUJBQ2I7b0JBQ0QsT0FBTyxFQUFFLEVBQUU7aUJBQ1oiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcblxuLyoqXG4gKiBNw7NkdWxvIHByaW5jaXBhbCBkYSBiaWJsaW90ZWNhIEBzZW5pb3JzaXN0ZW1hcy9jb21wb25lbnRzLWlhXG4gKiBcbiAqIEVzdGUgbcOzZHVsbyBzZXLDoSBwb3B1bGFkbyBjb25mb3JtZSBvcyBjb21wb25lbnRlcyBmb3JlbSBtaWdyYWRvcy5cbiAqIFBvciBlbnF1YW50bywgw6kgdW0gbcOzZHVsbyB2YXppbyBwYXJhIHBlcm1pdGlyIG8gYnVpbGQgaW5pY2lhbC5cbiAqL1xuQE5nTW9kdWxlKHtcbiAgZGVjbGFyYXRpb25zOiBbXSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZVxuICBdLFxuICBleHBvcnRzOiBbXVxufSlcbmV4cG9ydCBjbGFzcyBBbmd1bGFyQ29tcG9uZW50c01vZHVsZSB7IH1cbiJdfQ==
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { Component, Optional, Inject, Input } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { RouterModule, NavigationEnd } from '@angular/router';
|
|
4
|
+
import { BreadcrumbModule } from 'primeng/breadcrumb';
|
|
5
|
+
import { filter } from 'rxjs/operators';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
import * as i1 from "@angular/router";
|
|
8
|
+
import * as i2 from "primeng/breadcrumb";
|
|
9
|
+
export class BreadcrumbComponent {
|
|
10
|
+
router;
|
|
11
|
+
activatedRoute;
|
|
12
|
+
translationService;
|
|
13
|
+
translationPrefix = 'crmx.business';
|
|
14
|
+
isProduction = false;
|
|
15
|
+
breadcrumbItems = [];
|
|
16
|
+
constructor(router, activatedRoute, translationService) {
|
|
17
|
+
this.router = router;
|
|
18
|
+
this.activatedRoute = activatedRoute;
|
|
19
|
+
this.translationService = translationService;
|
|
20
|
+
}
|
|
21
|
+
ngOnInit() {
|
|
22
|
+
this.buildBreadcrumbs();
|
|
23
|
+
// Atualiza breadcrumbs quando a navegação muda
|
|
24
|
+
this.router.events
|
|
25
|
+
.pipe(filter(event => event instanceof NavigationEnd))
|
|
26
|
+
.subscribe(() => this.buildBreadcrumbs());
|
|
27
|
+
}
|
|
28
|
+
get homeItem() {
|
|
29
|
+
// Só mostra o link do home em desenvolvimento
|
|
30
|
+
if (!this.isProduction) {
|
|
31
|
+
return {
|
|
32
|
+
icon: 'pi pi-home',
|
|
33
|
+
routerLink: '/main',
|
|
34
|
+
title: this.t('breadcrumb_home')
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
// Em produção, o home não tem link (apenas ícone)
|
|
38
|
+
return {
|
|
39
|
+
icon: 'pi pi-home',
|
|
40
|
+
title: this.t('breadcrumb_home'),
|
|
41
|
+
disabled: true
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
buildBreadcrumbs() {
|
|
45
|
+
const breadcrumbs = [];
|
|
46
|
+
let currentRoute = this.activatedRoute.root;
|
|
47
|
+
let url = '';
|
|
48
|
+
let lastBreadcrumbLabel = '';
|
|
49
|
+
// Percorre toda a árvore de rotas
|
|
50
|
+
while (currentRoute) {
|
|
51
|
+
// Verifica se há segmentos de URL
|
|
52
|
+
if (currentRoute.snapshot.url.length > 0) {
|
|
53
|
+
const routeURL = currentRoute.snapshot.url.map(segment => segment.path).join('/');
|
|
54
|
+
url += `/${routeURL}`;
|
|
55
|
+
}
|
|
56
|
+
// Verifica se a rota tem dados de breadcrumb
|
|
57
|
+
const breadcrumbData = currentRoute.snapshot.data['breadcrumb'];
|
|
58
|
+
// Adiciona o breadcrumb se existir e não for duplicado
|
|
59
|
+
if (breadcrumbData) {
|
|
60
|
+
const label = this.t(breadcrumbData.title);
|
|
61
|
+
// Só adiciona se não for o mesmo label do anterior (evita duplicação)
|
|
62
|
+
if (label !== lastBreadcrumbLabel) {
|
|
63
|
+
breadcrumbs.push({
|
|
64
|
+
label: label,
|
|
65
|
+
icon: breadcrumbData.icon,
|
|
66
|
+
routerLink: url || undefined
|
|
67
|
+
});
|
|
68
|
+
lastBreadcrumbLabel = label;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Move para a próxima rota filha
|
|
72
|
+
currentRoute = currentRoute.firstChild;
|
|
73
|
+
}
|
|
74
|
+
// O último item não deve ter link (está desabilitado)
|
|
75
|
+
if (breadcrumbs.length > 0) {
|
|
76
|
+
const lastItem = breadcrumbs[breadcrumbs.length - 1];
|
|
77
|
+
lastItem.routerLink = undefined;
|
|
78
|
+
lastItem.disabled = true;
|
|
79
|
+
}
|
|
80
|
+
this.breadcrumbItems = breadcrumbs;
|
|
81
|
+
}
|
|
82
|
+
t(key) {
|
|
83
|
+
if (this.translationService) {
|
|
84
|
+
// Se a chave já tem o prefixo, usa diretamente
|
|
85
|
+
if (key.includes('.')) {
|
|
86
|
+
return this.translationService.translate(key);
|
|
87
|
+
}
|
|
88
|
+
// Caso contrário, adiciona o prefixo
|
|
89
|
+
return this.translationService.translate(`${this.translationPrefix}.${key}`);
|
|
90
|
+
}
|
|
91
|
+
return key;
|
|
92
|
+
}
|
|
93
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BreadcrumbComponent, deps: [{ token: i1.Router }, { token: i1.ActivatedRoute }, { token: 'TranslationService', optional: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
94
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: BreadcrumbComponent, isStandalone: true, selector: "sia-breadcrumb", inputs: { translationPrefix: "translationPrefix", isProduction: "isProduction" }, ngImport: i0, template: `
|
|
95
|
+
<p-breadcrumb
|
|
96
|
+
[model]="breadcrumbItems"
|
|
97
|
+
[home]="homeItem"
|
|
98
|
+
styleClass="custom-breadcrumb"
|
|
99
|
+
></p-breadcrumb>
|
|
100
|
+
`, isInline: true, styles: ["::ng-deep .p-breadcrumb{background:transparent;border:none;padding:0!important}::ng-deep .custom-breadcrumb{background:transparent;border:none;padding:0!important;.p-breadcrumb-list{background:transparent;padding:0!important;.p-menuitem{.p-menuitem-link{color:var(--text-secondary);text-decoration:none;font-size:14px;font-weight:500;padding:8px 12px;border-radius:6px;transition:all .2s ease;display:flex;align-items:center;&:hover{background:var(--p-primary-50);color:var(--p-primary-600)}.p-menuitem-icon{margin-right:8px;font-size:16px;display:inline-flex;align-items:center}}&:last-child .p-menuitem-link{color:var(--p-primary-600);font-weight:600;background:var(--p-primary-50)}}.p-breadcrumb-separator{color:var(--text-muted);margin:0 8px;font-size:14px}}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: BreadcrumbModule }, { kind: "component", type: i2.Breadcrumb, selector: "p-breadcrumb", inputs: ["model", "style", "styleClass", "home", "homeAriaLabel"], outputs: ["onItemClick"] }] });
|
|
101
|
+
}
|
|
102
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BreadcrumbComponent, decorators: [{
|
|
103
|
+
type: Component,
|
|
104
|
+
args: [{ selector: 'sia-breadcrumb', standalone: true, imports: [CommonModule, RouterModule, BreadcrumbModule], template: `
|
|
105
|
+
<p-breadcrumb
|
|
106
|
+
[model]="breadcrumbItems"
|
|
107
|
+
[home]="homeItem"
|
|
108
|
+
styleClass="custom-breadcrumb"
|
|
109
|
+
></p-breadcrumb>
|
|
110
|
+
`, styles: ["::ng-deep .p-breadcrumb{background:transparent;border:none;padding:0!important}::ng-deep .custom-breadcrumb{background:transparent;border:none;padding:0!important;.p-breadcrumb-list{background:transparent;padding:0!important;.p-menuitem{.p-menuitem-link{color:var(--text-secondary);text-decoration:none;font-size:14px;font-weight:500;padding:8px 12px;border-radius:6px;transition:all .2s ease;display:flex;align-items:center;&:hover{background:var(--p-primary-50);color:var(--p-primary-600)}.p-menuitem-icon{margin-right:8px;font-size:16px;display:inline-flex;align-items:center}}&:last-child .p-menuitem-link{color:var(--p-primary-600);font-weight:600;background:var(--p-primary-50)}}.p-breadcrumb-separator{color:var(--text-muted);margin:0 8px;font-size:14px}}}\n"] }]
|
|
111
|
+
}], ctorParameters: () => [{ type: i1.Router }, { type: i1.ActivatedRoute }, { type: undefined, decorators: [{
|
|
112
|
+
type: Optional
|
|
113
|
+
}, {
|
|
114
|
+
type: Inject,
|
|
115
|
+
args: ['TranslationService']
|
|
116
|
+
}] }], propDecorators: { translationPrefix: [{
|
|
117
|
+
type: Input
|
|
118
|
+
}], isProduction: [{
|
|
119
|
+
type: Input
|
|
120
|
+
}] } });
|
|
121
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJlYWRjcnVtYi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzLWFpL3NyYy9saWIvY29tcG9uZW50cy9icmVhZGNydW1iL2JyZWFkY3J1bWIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsUUFBUSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0UsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBVSxZQUFZLEVBQWtCLGFBQWEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3RGLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRXRELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7OztBQStFeEMsTUFBTSxPQUFPLG1CQUFtQjtJQU9wQjtJQUNBO0lBQzBDO0lBUjNDLGlCQUFpQixHQUFXLGVBQWUsQ0FBQztJQUM1QyxZQUFZLEdBQVksS0FBSyxDQUFDO0lBRXZDLGVBQWUsR0FBZSxFQUFFLENBQUM7SUFFakMsWUFDVSxNQUFjLEVBQ2QsY0FBOEIsRUFDWSxrQkFBdUM7UUFGakYsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQUNZLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBcUI7SUFDeEYsQ0FBQztJQUVKLFFBQVE7UUFDTixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUV4QiwrQ0FBK0M7UUFDL0MsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNO2FBQ2YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssWUFBWSxhQUFhLENBQUMsQ0FBQzthQUNyRCxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFD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QUFDLGlCQUFpQixJQUFJLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDL0UsQ0FBQztRQUNELE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQzt3R0EvRlUsbUJBQW1CLHNFQVNSLG9CQUFvQjs0RkFUL0IsbUJBQW1CLDRKQWhFcEI7Ozs7OztHQU1ULHMwQkFQUyxZQUFZLDhCQUFFLFlBQVksOEJBQUUsZ0JBQWdCOzs0RkFpRTNDLG1CQUFtQjtrQkFwRS9CLFNBQVM7K0JBQ0UsZ0JBQWdCLGNBQ2QsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLFlBQVksRUFBRSxnQkFBZ0IsQ0FBQyxZQUM3Qzs7Ozs7O0dBTVQ7OzBCQW1FRSxRQUFROzswQkFBSSxNQUFNOzJCQUFDLG9CQUFvQjt5Q0FSakMsaUJBQWlCO3NCQUF6QixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgT3B0aW9uYWwsIEluamVjdCwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBSb3V0ZXIsIFJvdXRlck1vZHVsZSwgQWN0aXZhdGVkUm91dGUsIE5hdmlnYXRpb25FbmQgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgQnJlYWRjcnVtYk1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvYnJlYWRjcnVtYic7XG5pbXBvcnQgeyBNZW51SXRlbSB9IGZyb20gJ3ByaW1lbmcvYXBpJztcbmltcG9ydCB7IGZpbHRlciB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW50ZXJmYWNlIEJyZWFkY3J1bWJEYXRhIHtcbiAgdGl0bGU6IHN0cmluZztcbiAgaWNvbj86IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIFRyYW5zbGF0aW9uU2VydmljZSB7XG4gIHRyYW5zbGF0ZShrZXk6IHN0cmluZywgcGFyYW1zPzogYW55KTogc3RyaW5nO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdzaWEtYnJlYWRjcnVtYicsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIFJvdXRlck1vZHVsZSwgQnJlYWRjcnVtYk1vZHVsZV0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPHAtYnJlYWRjcnVtYiBcbiAgICAgIFttb2RlbF09XCJicmVhZGNydW1iSXRlbXNcIiBcbiAgICAgIFtob21lXT1cImhvbWVJdGVtXCJcbiAgICAgIHN0eWxlQ2xhc3M9XCJjdXN0b20tYnJlYWRjcnVtYlwiXG4gICAgPjwvcC1icmVhZGNydW1iPlxuICBgLFxuICBzdHlsZXM6IFtgXG4gICAgOjpuZy1kZWVwIC5wLWJyZWFkY3J1bWIge1xuICAgICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gICAgICBib3JkZXI6IG5vbmU7XG4gICAgICBwYWRkaW5nOiAwICFpbXBvcnRhbnQ7XG4gICAgfVxuICAgIFxuICAgIDo6bmctZGVlcCAuY3VzdG9tLWJyZWFkY3J1bWIge1xuICAgICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gICAgICBib3JkZXI6IG5vbmU7XG4gICAgICBwYWRkaW5nOiAwICFpbXBvcnRhbnQ7XG4gICAgICBcbiAgICAgIC5wLWJyZWFkY3J1bWItbGlzdCB7XG4gICAgICAgIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xuICAgICAgICBwYWRkaW5nOiAwICFpbXBvcnRhbnQ7XG4gICAgICAgIFxuICAgICAgICAucC1tZW51aXRlbSB7XG4gICAgICAgICAgLnAtbWVudWl0ZW0tbGluayB7XG4gICAgICAgICAgICBjb2xvcjogdmFyKC0tdGV4dC1zZWNvbmRhcnkpO1xuICAgICAgICAgICAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xuICAgICAgICAgICAgZm9udC1zaXplOiAxNHB4O1xuICAgICAgICAgICAgZm9udC13ZWlnaHQ6IDUwMDtcbiAgICAgICAgICAgIHBhZGRpbmc6IDhweCAxMnB4O1xuICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogNnB4O1xuICAgICAgICAgICAgdHJhbnNpdGlvbjogYWxsIDAuMnMgZWFzZTtcbiAgICAgICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICAmOmhvdmVyIHtcbiAgICAgICAgICAgICAgYmFja2dyb3VuZDogdmFyKC0tcC1wcmltYXJ5LTUwKTtcbiAgICAgICAgICAgICAgY29sb3I6IHZhcigtLXAtcHJpbWFyeS02MDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgXG4gICAgICAgICAgICAucC1tZW51aXRlbS1pY29uIHtcbiAgICAgICAgICAgICAgbWFyZ2luLXJpZ2h0OiA4cHg7XG4gICAgICAgICAgICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICAgICAgICAgICAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gICAgICAgICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIFxuICAgICAgICAgICY6bGFzdC1jaGlsZCAucC1tZW51aXRlbS1saW5rIHtcbiAgICAgICAgICAgIGNvbG9yOiB2YXIoLS1wLXByaW1hcnktNjAwKTtcbiAgICAgICAgICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiB2YXIoLS1wLXByaW1hcnktNTApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgLnAtYnJlYWRjcnVtYi1zZXBhcmF0b3Ige1xuICAgICAgICAgIGNvbG9yOiB2YXIoLS10ZXh0LW11dGVkKTtcbiAgICAgICAgICBtYXJnaW46IDAgOHB4O1xuICAgICAgICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgYF1cbn0pXG5leHBvcnQgY2xhc3MgQnJlYWRjcnVtYkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIEBJbnB1dCgpIHRyYW5zbGF0aW9uUHJlZml4OiBzdHJpbmcgPSAnY3JteC5idXNpbmVzcyc7XG4gIEBJbnB1dCgpIGlzUHJvZHVjdGlvbjogYm9vbGVhbiA9IGZhbHNlO1xuICBcbiAgYnJlYWRjcnVtYkl0ZW1zOiBNZW51SXRlbVtdID0gW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlcixcbiAgICBwcml2YXRlIGFjdGl2YXRlZFJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSxcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KCdUcmFuc2xhdGlvblNlcnZpY2UnKSBwcml2YXRlIHRyYW5zbGF0aW9uU2VydmljZT86IFRyYW5zbGF0aW9uU2VydmljZVxuICApIHt9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5idWlsZEJyZWFkY3J1bWJzKCk7XG4gICAgXG4gICAgLy8gQXR1YWxpemEgYnJlYWRjcnVtYnMgcXVhbmRvIGEgbmF2ZWdhw6fDo28gbXVkYVxuICAgIHRoaXMucm91dGVyLmV2ZW50c1xuICAgICAgLnBpcGUoZmlsdGVyKGV2ZW50ID0+IGV2ZW50IGluc3RhbmNlb2YgTmF2aWdhdGlvbkVuZCkpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMuYnVpbGRCcmVhZGNydW1icygpKTtcbiAgfVxuXG4gIGdldCBob21lSXRlbSgpOiBNZW51SXRlbSB7XG4gICAgLy8gU8OzIG1vc3RyYSBvIGxpbmsgZG8gaG9tZSBlbSBkZXNlbnZvbHZpbWVudG9cbiAgICBpZiAoIXRoaXMuaXNQcm9kdWN0aW9uKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBpY29uOiAncGkgcGktaG9tZScsXG4gICAgICAgIHJvdXRlckxpbms6ICcvbWFpbicsXG4gICAgICAgIHRpdGxlOiB0aGlzLnQoJ2JyZWFkY3J1bWJfaG9tZScpXG4gICAgICB9O1xuICAgIH1cbiAgICBcbiAgICAvLyBFbSBwcm9kdcOnw6NvLCBvIGhvbWUgbsOjbyB0ZW0gbGluayAoYXBlbmFzIMOtY29uZSlcbiAgICByZXR1cm4ge1xuICAgICAgaWNvbjogJ3BpIHBpLWhvbWUnLFxuICAgICAgdGl0bGU6IHRoaXMudCgnYnJlYWRjcnVtYl9ob21lJyksXG4gICAgICBkaXNhYmxlZDogdHJ1ZVxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkQnJlYWRjcnVtYnMoKTogdm9pZCB7XG4gICAgY29uc3QgYnJlYWRjcnVtYnM6IE1lbnVJdGVtW10gPSBbXTtcbiAgICBsZXQgY3VycmVudFJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSB8IG51bGwgPSB0aGlzLmFjdGl2YXRlZFJvdXRlLnJvb3Q7XG4gICAgbGV0IHVybCA9ICcnO1xuICAgIGxldCBsYXN0QnJlYWRjcnVtYkxhYmVsID0gJyc7XG5cbiAgICAvLyBQZXJjb3JyZSB0b2RhIGEgw6Fydm9yZSBkZSByb3Rhc1xuICAgIHdoaWxlIChjdXJyZW50Um91dGUpIHtcbiAgICAgIC8vIFZlcmlmaWNhIHNlIGjDoSBzZWdtZW50b3MgZGUgVVJMXG4gICAgICBpZiAoY3VycmVudFJvdXRlLnNuYXBzaG90LnVybC5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IHJvdXRlVVJMID0gY3VycmVudFJvdXRlLnNuYXBzaG90LnVybC5tYXAoc2VnbWVudCA9PiBzZWdtZW50LnBhdGgpLmpvaW4oJy8nKTtcbiAgICAgICAgdXJsICs9IGAvJHtyb3V0ZVVSTH1gO1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBWZXJpZmljYSBzZSBhIHJvdGEgdGVtIGRhZG9zIGRlIGJyZWFkY3J1bWJcbiAgICAgIGNvbnN0IGJyZWFkY3J1bWJEYXRhID0gY3VycmVudFJvdXRlLnNuYXBzaG90LmRhdGFbJ2JyZWFkY3J1bWInXSBhcyBCcmVhZGNydW1iRGF0YTtcbiAgICAgIFxuICAgICAgLy8gQWRpY2lvbmEgbyBicmVhZGNydW1iIHNlIGV4aXN0aXIgZSBuw6NvIGZvciBkdXBsaWNhZG9cbiAgICAgIGlmIChicmVhZGNydW1iRGF0YSkge1xuICAgICAgICBjb25zdCBsYWJlbCA9IHRoaXMudChicmVhZGNydW1iRGF0YS50aXRsZSk7XG4gICAgICAgIFxuICAgICAgICAvLyBTw7MgYWRpY2lvbmEgc2UgbsOjbyBmb3IgbyBtZXNtbyBsYWJlbCBkbyBhbnRlcmlvciAoZXZpdGEgZHVwbGljYcOnw6NvKVxuICAgICAgICBpZiAobGFiZWwgIT09IGxhc3RCcmVhZGNydW1iTGFiZWwpIHtcbiAgICAgICAgICBicmVhZGNydW1icy5wdXNoKHtcbiAgICAgICAgICAgIGxhYmVsOiBsYWJlbCxcbiAgICAgICAgICAgIGljb246IGJyZWFkY3J1bWJEYXRhLmljb24sXG4gICAgICAgICAgICByb3V0ZXJMaW5rOiB1cmwgfHwgdW5kZWZpbmVkXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgbGFzdEJyZWFkY3J1bWJMYWJlbCA9IGxhYmVsO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIE1vdmUgcGFyYSBhIHByw7N4aW1hIHJvdGEgZmlsaGFcbiAgICAgIGN1cnJlbnRSb3V0ZSA9IGN1cnJlbnRSb3V0ZS5maXJzdENoaWxkO1xuICAgIH1cblxuICAgIC8vIE8gw7psdGltbyBpdGVtIG7Do28gZGV2ZSB0ZXIgbGluayAoZXN0w6EgZGVzYWJpbGl0YWRvKVxuICAgIGlmIChicmVhZGNydW1icy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBsYXN0SXRlbSA9IGJyZWFkY3J1bWJzW2JyZWFkY3J1bWJzLmxlbmd0aCAtIDFdO1xuICAgICAgbGFzdEl0ZW0ucm91dGVyTGluayA9IHVuZGVmaW5lZDtcbiAgICAgIGxhc3RJdGVtLmRpc2FibGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB0aGlzLmJyZWFkY3J1bWJJdGVtcyA9IGJyZWFkY3J1bWJzO1xuICB9XG5cbiAgcHJpdmF0ZSB0KGtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy50cmFuc2xhdGlvblNlcnZpY2UpIHtcbiAgICAgIC8vIFNlIGEgY2hhdmUgasOhIHRlbSBvIHByZWZpeG8sIHVzYSBkaXJldGFtZW50ZVxuICAgICAgaWYgKGtleS5pbmNsdWRlcygnLicpKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRyYW5zbGF0aW9uU2VydmljZS50cmFuc2xhdGUoa2V5KTtcbiAgICAgIH1cbiAgICAgIC8vIENhc28gY29udHLDoXJpbywgYWRpY2lvbmEgbyBwcmVmaXhvXG4gICAgICByZXR1cm4gdGhpcy50cmFuc2xhdGlvblNlcnZpY2UudHJhbnNsYXRlKGAke3RoaXMudHJhbnNsYXRpb25QcmVmaXh9LiR7a2V5fWApO1xuICAgIH1cbiAgICByZXR1cm4ga2V5O1xuICB9XG59XG4iXX0=
|