From 3efa856453971045103431c7f63f4f375a623b5f Mon Sep 17 00:00:00 2001 From: apuente Date: Wed, 12 Jun 2024 16:05:36 +0200 Subject: [PATCH 01/36] Groups base structure display --- ogWebconsole/src/app/app-routing.module.ts | 2 + ogWebconsole/src/app/app.module.ts | 4 +- .../src/app/components/groups/data.service.ts | 35 ++++++++++ .../components/groups/groups.component.css | 7 ++ .../components/groups/groups.component.html | 39 +++++++++++ .../groups/groups.component.spec.ts | 23 +++++++ .../app/components/groups/groups.component.ts | 33 ++++++++++ .../src/app/components/groups/model.ts | 19 ++++++ .../layout/header/header.component.html | 2 +- .../change-password-modal.component.css | 10 +++ .../change-password-modal.component.html | 21 ++++++ .../change-password-modal.component.spec.ts | 23 +++++++ .../change-password-modal.component.ts | 65 +++++++++++++++++++ 13 files changed, 281 insertions(+), 2 deletions(-) create mode 100644 ogWebconsole/src/app/components/groups/data.service.ts create mode 100644 ogWebconsole/src/app/components/groups/groups.component.css create mode 100644 ogWebconsole/src/app/components/groups/groups.component.html create mode 100644 ogWebconsole/src/app/components/groups/groups.component.spec.ts create mode 100644 ogWebconsole/src/app/components/groups/groups.component.ts create mode 100644 ogWebconsole/src/app/components/groups/model.ts create mode 100644 ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component.css create mode 100644 ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component.html create mode 100644 ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component.spec.ts create mode 100644 ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component.ts diff --git a/ogWebconsole/src/app/app-routing.module.ts b/ogWebconsole/src/app/app-routing.module.ts index ba8e87d..084a8e1 100644 --- a/ogWebconsole/src/app/app-routing.module.ts +++ b/ogWebconsole/src/app/app-routing.module.ts @@ -8,6 +8,7 @@ import { PageNotFoundComponent } from './components/page-not-found/page-not-foun import { AdminComponent } from './components/pages/admin/admin.component'; import { UsersComponent } from './components/pages/admin/users/users/users.component'; import { RolesComponent } from './components/pages/admin/roles/roles/roles.component'; +import { GroupsComponent } from './components/groups/groups.component'; const routes: Routes = [ { path: '', redirectTo: 'auth/login', pathMatch: 'full' }, { @@ -18,6 +19,7 @@ const routes: Routes = [ { path: 'admin', component: AdminComponent }, { path: 'users', component: UsersComponent }, { path: 'user-groups', component: RolesComponent }, + { path: 'groups', component: GroupsComponent }, ], }, { diff --git a/ogWebconsole/src/app/app.module.ts b/ogWebconsole/src/app/app.module.ts index f687bf7..b8c1f8c 100644 --- a/ogWebconsole/src/app/app.module.ts +++ b/ogWebconsole/src/app/app.module.ts @@ -33,6 +33,7 @@ import { EditUserModalComponent } from './components/pages/admin/users/users/edi import { AddRoleModalComponent } from './components/pages/admin/roles/roles/add-role-modal/add-role-modal.component'; import { DeleteRoleModalComponent } from './components/pages/admin/roles/roles/delete-role-modal/delete-role-modal.component'; import { ChangePasswordModalComponent } from './components/pages/admin/users/users/change-password-modal/change-password-modal.component'; +import { GroupsComponent } from './components/groups/groups.component'; @NgModule({ declarations: [ @@ -51,7 +52,8 @@ import { ChangePasswordModalComponent } from './components/pages/admin/users/use EditUserModalComponent, AddRoleModalComponent, DeleteRoleModalComponent, - ChangePasswordModalComponent + ChangePasswordModalComponent, + GroupsComponent ], bootstrap: [AppComponent], imports: [BrowserModule, diff --git a/ogWebconsole/src/app/components/groups/data.service.ts b/ogWebconsole/src/app/components/groups/data.service.ts new file mode 100644 index 0000000..5ee1405 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/data.service.ts @@ -0,0 +1,35 @@ +// data.service.ts +import { Injectable } from '@angular/core'; +import { UnidadOrganizativa } from './model'; + +@Injectable({ + providedIn: 'root', +}) +export class DataService { + private unidadesOrganizativas: UnidadOrganizativa[] = [ + { + id: 1, + nombre: 'Unidad Organizativa 1', + aulas: [ + { + id: 1, + nombre: 'Aula 1', + clientes: [ + { id: 1, nombre: 'Cliente 1' }, + { id: 2, nombre: 'Cliente 2' }, + ], + }, + { + id: 2, + nombre: 'Aula 2', + clientes: [{ id: 3, nombre: 'Cliente 3' }], + }, + ], + }, + // Otros datos de ejemplo + ]; + + getUnidadesOrganizativas(): UnidadOrganizativa[] { + return this.unidadesOrganizativas; + } +} diff --git a/ogWebconsole/src/app/components/groups/groups.component.css b/ogWebconsole/src/app/components/groups/groups.component.css new file mode 100644 index 0000000..aaecff2 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/groups.component.css @@ -0,0 +1,7 @@ +.groupLists-container{ + display: flex; +} + +mat-card { + margin: 10px; +} \ No newline at end of file diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html new file mode 100644 index 0000000..2706b33 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/groups.component.html @@ -0,0 +1,39 @@ + +

groups works!

+
+ + Unidad organizativa + + + + {{ unidad.nombre }} + + + + + + Aulas + + + + {{ aula.nombre }} + + + + + + Clientes + + + + {{ cliente.nombre }} + + + + +
diff --git a/ogWebconsole/src/app/components/groups/groups.component.spec.ts b/ogWebconsole/src/app/components/groups/groups.component.spec.ts new file mode 100644 index 0000000..ee75d8e --- /dev/null +++ b/ogWebconsole/src/app/components/groups/groups.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { GroupsComponent } from './groups.component'; + +describe('GroupsComponent', () => { + let component: GroupsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [GroupsComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(GroupsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/ogWebconsole/src/app/components/groups/groups.component.ts b/ogWebconsole/src/app/components/groups/groups.component.ts new file mode 100644 index 0000000..e84cacf --- /dev/null +++ b/ogWebconsole/src/app/components/groups/groups.component.ts @@ -0,0 +1,33 @@ +// groups.component.ts +import { Component, OnInit } from '@angular/core'; +import { DataService } from './data.service'; +import { UnidadOrganizativa, Aula, Cliente } from './model'; + +@Component({ + selector: 'app-groups', + templateUrl: './groups.component.html', + styleUrls: ['./groups.component.css'] +}) +export class GroupsComponent implements OnInit { + unidadesOrganizativas: UnidadOrganizativa[] = []; + selectedUnidad: UnidadOrganizativa | null = null; + selectedAula: Aula | null = null; + selectedClientes: Cliente[] = []; + + constructor(private dataService: DataService) {} + + ngOnInit(): void { + this.unidadesOrganizativas = this.dataService.getUnidadesOrganizativas(); + } + + onSelectUnidad(unidad: UnidadOrganizativa): void { + this.selectedUnidad = unidad; + this.selectedAula = null; + this.selectedClientes = []; + } + + onSelectAula(aula: Aula): void { + this.selectedAula = aula; + this.selectedClientes = aula.clientes; + } +} diff --git a/ogWebconsole/src/app/components/groups/model.ts b/ogWebconsole/src/app/components/groups/model.ts new file mode 100644 index 0000000..7a672a4 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/model.ts @@ -0,0 +1,19 @@ +// models.ts +export interface Cliente { + id: number; + nombre: string; + } + + export interface Aula { + id: number; + nombre: string; + clientes: Cliente[]; + bloques?: Aula[]; + } + + export interface UnidadOrganizativa { + id: number; + nombre: string; + aulas: Aula[]; + } + \ No newline at end of file diff --git a/ogWebconsole/src/app/components/layout/header/header.component.html b/ogWebconsole/src/app/components/layout/header/header.component.html index b00e6be..737223f 100644 --- a/ogWebconsole/src/app/components/layout/header/header.component.html +++ b/ogWebconsole/src/app/components/layout/header/header.component.html @@ -4,7 +4,7 @@ Opengnsys webconsole diff --git a/ogWebconsole/src/app/components/groups/groups.component.ts b/ogWebconsole/src/app/components/groups/groups.component.ts index 10218db..fae8627 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.ts +++ b/ogWebconsole/src/app/components/groups/groups.component.ts @@ -1,10 +1,8 @@ -// groups.component.ts import { Component, OnInit } from '@angular/core'; import { DataService } from './data.service'; -import { UnidadOrganizativa, Aula, Cliente } from './model'; -import { CreateOrganizationalUnitComponent } from './organizational-units/create-organizational-unit/create-organizational-unit.component'; +import { UnidadOrganizativa } from './model'; import { MatDialog } from '@angular/material/dialog'; -import { CreateClientComponent } from './clients/create-client/create-client.component'; +import { CreateOrganizationalUnitComponent } from './organizational-units/create-organizational-unit/create-organizational-unit.component'; @Component({ selector: 'app-groups', @@ -14,32 +12,21 @@ import { CreateClientComponent } from './clients/create-client/create-client.com export class GroupsComponent implements OnInit { unidadesOrganizativas: UnidadOrganizativa[] = []; selectedUnidad: UnidadOrganizativa | null = null; - selectedAula: Aula | null = null; - selectedClientes: Cliente[] = []; constructor(private dataService: DataService, public dialog: MatDialog) {} ngOnInit(): void { - this.unidadesOrganizativas = this.dataService.getUnidadesOrganizativas(); + this.dataService.getUnidadesOrganizativas().subscribe( + data => this.unidadesOrganizativas = data, + error => console.error('Error fetching unidades organizativas', error) + ); } onSelectUnidad(unidad: UnidadOrganizativa): void { this.selectedUnidad = unidad; - this.selectedAula = null; - this.selectedClientes = []; } - onSelectAula(aula: Aula): void { - this.selectedAula = aula; - this.selectedClientes = aula.clientes; - } - - - addOU() { - const dialogRef = this.dialog.open(CreateOrganizationalUnitComponent); - } - - addClient() { - const dialogRef = this.dialog.open(CreateClientComponent); + addOU(): void { + this.dialog.open(CreateOrganizationalUnitComponent); } } diff --git a/ogWebconsole/src/app/components/groups/model.ts b/ogWebconsole/src/app/components/groups/model.ts index 7a672a4..2436b80 100644 --- a/ogWebconsole/src/app/components/groups/model.ts +++ b/ogWebconsole/src/app/components/groups/model.ts @@ -1,19 +1,16 @@ -// models.ts +// model.ts export interface Cliente { - id: number; - nombre: string; - } - - export interface Aula { - id: number; - nombre: string; - clientes: Cliente[]; - bloques?: Aula[]; - } - - export interface UnidadOrganizativa { - id: number; - nombre: string; - aulas: Aula[]; - } - \ No newline at end of file + nombre: string; +} + +export interface Aula { + nombre: string; + clientes: Cliente[]; +} + +export interface UnidadOrganizativa { + id: number; + nombre: string; + uuid: string; + aulas: Aula[]; +} diff --git a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html index ebaf5a7..44f0b27 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html +++ b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html @@ -1,24 +1,30 @@

Añadir Unidad Organizativa

- +
General + + Tipo + + {{ type }} + + Nombre Padre - + Descripción
- +
@@ -31,13 +37,9 @@ Comentarios - - Tipo - -
- +
@@ -101,7 +103,7 @@ Validación
- +
diff --git a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts index d5c41af..3e4ef34 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts +++ b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts @@ -9,10 +9,10 @@ import { MatDialogRef } from '@angular/material/dialog'; }) export class CreateOrganizationalUnitComponent implements OnInit { isLinear = true; - networkForm: FormGroup; generalFormGroup: FormGroup; additionalInfoFormGroup: FormGroup; networkSettingsFormGroup: FormGroup; + types: string[] = ['organizational-unit', 'classrooms-group', 'classroom', 'clients-group']; constructor( private _formBuilder: FormBuilder, @@ -20,12 +20,12 @@ export class CreateOrganizationalUnitComponent implements OnInit { ) { this.generalFormGroup = this._formBuilder.group({ name: ['', Validators.required], - parent: ['', [Validators.required, Validators.pattern('https?://.+')]], - description: [''] + parent: ['', Validators.required], + description: [''], + type: ['', Validators.required] }); this.additionalInfoFormGroup = this._formBuilder.group({ comments: [''], - type: ['', Validators.required] }); this.networkSettingsFormGroup = this._formBuilder.group({ proxy: [''], @@ -43,26 +43,23 @@ export class CreateOrganizationalUnitComponent implements OnInit { hardwareProfile: ['', Validators.pattern('https?://.+')], validation: [false] }); - - this.networkForm = this._formBuilder.group({ - general: this.generalFormGroup, - additionalInfo: this.additionalInfoFormGroup, - networkSettings: this.networkSettingsFormGroup - }); } ngOnInit() {} onSubmit() { - if (this.networkForm.valid) { - const formData = this.networkForm.value; + if (this.generalFormGroup.valid && this.additionalInfoFormGroup.valid && this.networkSettingsFormGroup.valid) { + const formData = { + ...this.generalFormGroup.value, + ...this.additionalInfoFormGroup.value, + ...this.networkSettingsFormGroup.value, + }; console.log('Form Data:', formData); - // handle form submission logic - this.dialogRef.close(formData); // Cierra el modal y pasa los datos del formulario + this.dialogRef.close(formData); } } onNoClick(): void { - this.dialogRef.close(); // Cierra el modal sin pasar datos + this.dialogRef.close(); } } diff --git a/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.css b/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.css index 081d0e5..d68e53c 100644 --- a/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.css +++ b/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.css @@ -7,6 +7,7 @@ background-color: rgb(245, 245, 245); transition: left 0.3s ease-in-out; box-shadow: 10px 0 10px -5px rgba(0, 0, 0, 0.5); + z-index: 99999999999; } .sidebar.visible { diff --git a/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.ts b/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.ts index 89f5112..ad83d71 100644 --- a/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.ts +++ b/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.ts @@ -21,7 +21,6 @@ export class SidebarComponent { if (token) { try { this.decodedToken = jwtDecode(token); - console.log('Decoded token:', this.decodedToken); this.isSuperAdmin = this.decodedToken.roles.includes('ROLE_SUPER_ADMIN'); this.username = this.decodedToken.username; } catch (error) { -- 2.40.1 From 3d77c179ba42cb0f5cfb2e9844ebb2dd968ad861 Mon Sep 17 00:00:00 2001 From: apuente Date: Thu, 20 Jun 2024 21:37:42 +0200 Subject: [PATCH 04/36] Groups base structure new container --- .../src/app/components/groups/data.service.ts | 21 ++++++++++- .../components/groups/groups.component.css | 35 ++++++++++--------- .../components/groups/groups.component.html | 18 +++++++++- .../app/components/groups/groups.component.ts | 31 ++++++++++++++++ 4 files changed, 86 insertions(+), 19 deletions(-) diff --git a/ogWebconsole/src/app/components/groups/data.service.ts b/ogWebconsole/src/app/components/groups/data.service.ts index b2f9ee8..795ebec 100644 --- a/ogWebconsole/src/app/components/groups/data.service.ts +++ b/ogWebconsole/src/app/components/groups/data.service.ts @@ -10,6 +10,7 @@ import { UnidadOrganizativa } from './model'; export class DataService { private apiUrl = 'http://127.0.0.1:8080/organizational-units?page=1&itemsPerPage=30'; + private clientsUrl = 'http://127.0.0.1:8080/clients?page=1&itemsPerPage=30'; constructor(private http: HttpClient) {} @@ -38,7 +39,8 @@ export class DataService { } getChildren(uuid: string): Observable { - return this.http.get(this.apiUrl).pipe( + console.log('uuid', uuid); + return this.http.get(`${this.apiUrl}&parent=${uuid}`).pipe( map(response => { if (response['hydra:member'] && Array.isArray(response['hydra:member'])) { return response['hydra:member'].filter((element: any) => element.parent === `/organizational-units/${uuid}`); @@ -52,4 +54,21 @@ export class DataService { }) ); } + + getClients(unidadId: string): Observable { + console.log('unidadId', unidadId); + return this.http.get(this.clientsUrl).pipe( + map(response => { + if (response['hydra:member'] && Array.isArray(response['hydra:member'])) { + return response['hydra:member'].filter((client: any) => client.organizationalUnit === `/organizational-units/${unidadId}`); + } else { + throw new Error('Unexpected response format'); + } + }), + catchError(error => { + console.error('Error fetching clients', error); + return throwError(error); + }) + ); + } } diff --git a/ogWebconsole/src/app/components/groups/groups.component.css b/ogWebconsole/src/app/components/groups/groups.component.css index 8dcc781..5b9e321 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.css +++ b/ogWebconsole/src/app/components/groups/groups.component.css @@ -1,25 +1,26 @@ -.groupLists-container{ - display: flex; +.groupLists-container { + display: flex; + flex-wrap: wrap; } mat-card { - margin: 10px; + margin: 10px; } .groups-button-row { - display: flex; - flex-grow: 1; + display: flex; + flex-grow: 1; } -button { - margin-left: 10px; - - margin-bottom: 20px; -} - .clickable-item:hover { - cursor: pointer; - } - .selected-item { - background-color: #e0e0e0; - } - \ No newline at end of file +button { + margin-left: 10px; + margin-bottom: 20px; +} + +.clickable-item:hover { + cursor: pointer; +} + +.selected-item { + background-color: #e0e0e0; +} diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html index d9eaaed..efeb674 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.html +++ b/ogWebconsole/src/app/components/groups/groups.component.html @@ -12,7 +12,23 @@ - {{ unidad.nombre }} +
+ apartment + {{ unidad.nombre }} +
+
+ + + + + + {{ breadcrumb.join(' > ') }} + + + + {{ child.name || child.nombre }} diff --git a/ogWebconsole/src/app/components/groups/groups.component.ts b/ogWebconsole/src/app/components/groups/groups.component.ts index fae8627..6009b91 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.ts +++ b/ogWebconsole/src/app/components/groups/groups.component.ts @@ -12,6 +12,8 @@ import { CreateOrganizationalUnitComponent } from './organizational-units/create export class GroupsComponent implements OnInit { unidadesOrganizativas: UnidadOrganizativa[] = []; selectedUnidad: UnidadOrganizativa | null = null; + children: any[] = []; + breadcrumb: string[] = []; constructor(private dataService: DataService, public dialog: MatDialog) {} @@ -24,6 +26,35 @@ export class GroupsComponent implements OnInit { onSelectUnidad(unidad: UnidadOrganizativa): void { this.selectedUnidad = unidad; + this.breadcrumb = [unidad.nombre]; + this.loadChildrenAndClients(unidad.uuid); + } + + onSelectChild(child: any): void { + if (child.uuid && child.id) { + this.breadcrumb.push(child.name || child.nombre); + this.loadChildrenAndClients(child.uuid); + } + } + + loadChildrenAndClients(uuid: string): void { + this.dataService.getChildren(uuid).subscribe( + childrenData => { + this.dataService.getClients(uuid).subscribe( + clientsData => { + const newChildren = [...childrenData, ...clientsData]; + if (newChildren.length > 0) { + this.children = newChildren; + } else { + // No se encontraron elementos hijos o clientes, revertimos el breadcrumb + this.breadcrumb.pop(); + } + }, + error => console.error('Error fetching clients', error) + ); + }, + error => console.error('Error fetching children', error) + ); } addOU(): void { -- 2.40.1 From ff983176c95da1176ccaa39a424e3166c391a86b Mon Sep 17 00:00:00 2001 From: apuente Date: Fri, 21 Jun 2024 01:05:03 +0200 Subject: [PATCH 05/36] Groups edit and delete --- .../components/groups/groups.component.css | 21 ++++++++++++ .../components/groups/groups.component.html | 25 +++++++++++--- .../app/components/groups/groups.component.ts | 33 +++++++++++++++++-- .../src/app/components/groups/model.ts | 1 + 4 files changed, 72 insertions(+), 8 deletions(-) diff --git a/ogWebconsole/src/app/components/groups/groups.component.css b/ogWebconsole/src/app/components/groups/groups.component.css index 5b9e321..74b2034 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.css +++ b/ogWebconsole/src/app/components/groups/groups.component.css @@ -24,3 +24,24 @@ button { .selected-item { background-color: #e0e0e0; } + +.actions { + margin-left: auto; +} + +.actions mat-icon { + cursor: pointer; + margin-left: 48px; + color: #757575; +} + +.actions mat-icon:hover { + color: #212121; +} + +.elements-card{ + margin: 10px; + width: 800px; + background-color: #fafafa; + +} \ No newline at end of file diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html index efeb674..4dc1d5d 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.html +++ b/ogWebconsole/src/app/components/groups/groups.component.html @@ -5,7 +5,7 @@

Grupos

- + Unidad organizativa @@ -15,20 +15,35 @@
apartment {{ unidad.nombre }} -
+
- + {{ breadcrumb.join(' > ') }} - {{ child.name || child.nombre }} +
+ + + apartment + + + + + + {{ child.name || child.nombre }} + + + edit + delete + +
diff --git a/ogWebconsole/src/app/components/groups/groups.component.ts b/ogWebconsole/src/app/components/groups/groups.component.ts index 6009b91..340a751 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.ts +++ b/ogWebconsole/src/app/components/groups/groups.component.ts @@ -27,17 +27,17 @@ export class GroupsComponent implements OnInit { onSelectUnidad(unidad: UnidadOrganizativa): void { this.selectedUnidad = unidad; this.breadcrumb = [unidad.nombre]; - this.loadChildrenAndClients(unidad.uuid); + this.loadChildrenAndClients(unidad.uuid, unidad.id); } onSelectChild(child: any): void { if (child.uuid && child.id) { this.breadcrumb.push(child.name || child.nombre); - this.loadChildrenAndClients(child.uuid); + this.loadChildrenAndClients(child.uuid, child.id); } } - loadChildrenAndClients(uuid: string): void { + loadChildrenAndClients(uuid: string, id: number): void { this.dataService.getChildren(uuid).subscribe( childrenData => { this.dataService.getClients(uuid).subscribe( @@ -60,4 +60,31 @@ export class GroupsComponent implements OnInit { addOU(): void { this.dialog.open(CreateOrganizationalUnitComponent); } + + getIcon(type: string): string { + switch(type) { + case 'organizational-unit': + return 'apartment'; + case 'classroom-group': + return 'classrooms-group-icon'; + case 'classroom': + return 'classroom-icon'; + case 'client': + return 'client-icon'; + case 'clients-group': + return 'clients-group-icon'; + default: + return ''; + } + } + + onDeleteClick(uuid: string): void { + console.log('UUID del elemento a eliminar:', uuid); + // Aquí puedes agregar lógica adicional para eliminar el elemento si es necesario + } + + onEditClick(uuid: string): void { + console.log('UUID del elemento a editar:', uuid); + // Aquí puedes agregar lógica adicional para editar el elemento si es necesario + } } diff --git a/ogWebconsole/src/app/components/groups/model.ts b/ogWebconsole/src/app/components/groups/model.ts index 2436b80..77c405d 100644 --- a/ogWebconsole/src/app/components/groups/model.ts +++ b/ogWebconsole/src/app/components/groups/model.ts @@ -14,3 +14,4 @@ export interface UnidadOrganizativa { uuid: string; aulas: Aula[]; } + -- 2.40.1 From b14605f2488983d94cac2bbddf6fde5ccdf61a38 Mon Sep 17 00:00:00 2001 From: apuente Date: Fri, 21 Jun 2024 01:15:54 +0200 Subject: [PATCH 06/36] Groups edit and delete ou --- .../components/groups/groups.component.html | 53 ++++++++++++------- .../app/components/groups/groups.component.ts | 3 +- 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html index 4dc1d5d..51b2cc0 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.html +++ b/ogWebconsole/src/app/components/groups/groups.component.html @@ -5,39 +5,56 @@

Grupos

- + Unidad organizativa - -
+ apartment {{ unidad.nombre }} -
+ + + edit + delete +
- + {{ breadcrumb.join(' > ') }} - +
- - apartment - - - - - - {{ child.name || child.nombre }} + + apartment + + + + + + + + + + + + + + {{ child.name || child.nombre }} edit @@ -48,4 +65,4 @@ -
+
\ No newline at end of file diff --git a/ogWebconsole/src/app/components/groups/groups.component.ts b/ogWebconsole/src/app/components/groups/groups.component.ts index 340a751..19c3970 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.ts +++ b/ogWebconsole/src/app/components/groups/groups.component.ts @@ -83,7 +83,8 @@ export class GroupsComponent implements OnInit { // Aquí puedes agregar lógica adicional para eliminar el elemento si es necesario } - onEditClick(uuid: string): void { + onEditClick(type: any, uuid: string): void { + console.log('Tipo del elemento a editar:', type); console.log('UUID del elemento a editar:', uuid); // Aquí puedes agregar lógica adicional para editar el elemento si es necesario } -- 2.40.1 From 67177c423781bec8363ca37e6143bf8e7d6ba85e Mon Sep 17 00:00:00 2001 From: apuente Date: Fri, 21 Jun 2024 12:29:12 +0200 Subject: [PATCH 07/36] Groups new fetch for API updates --- .../src/app/components/groups/data.service.ts | 11 ++++++----- .../src/app/components/groups/groups.component.html | 10 ++++------ .../src/app/components/groups/groups.component.ts | 9 ++++++--- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/ogWebconsole/src/app/components/groups/data.service.ts b/ogWebconsole/src/app/components/groups/data.service.ts index 795ebec..6e8ae9d 100644 --- a/ogWebconsole/src/app/components/groups/data.service.ts +++ b/ogWebconsole/src/app/components/groups/data.service.ts @@ -39,11 +39,10 @@ export class DataService { } getChildren(uuid: string): Observable { - console.log('uuid', uuid); return this.http.get(`${this.apiUrl}&parent=${uuid}`).pipe( map(response => { if (response['hydra:member'] && Array.isArray(response['hydra:member'])) { - return response['hydra:member'].filter((element: any) => element.parent === `/organizational-units/${uuid}`); + return response['hydra:member'].filter((element: any) => element.parent && element.parent['@id'] === `/organizational-units/${uuid}`); } else { throw new Error('Unexpected response format'); } @@ -55,12 +54,12 @@ export class DataService { ); } - getClients(unidadId: string): Observable { - console.log('unidadId', unidadId); + getClients(uuid: string): Observable { + console.log('unidadId', uuid); return this.http.get(this.clientsUrl).pipe( map(response => { if (response['hydra:member'] && Array.isArray(response['hydra:member'])) { - return response['hydra:member'].filter((client: any) => client.organizationalUnit === `/organizational-units/${unidadId}`); + return response['hydra:member'].filter((client: any) => client.organizationalUnit && client.organizationalUnit['@id'] === `/organizational-units/${uuid}`); } else { throw new Error('Unexpected response format'); } @@ -71,4 +70,6 @@ export class DataService { }) ); } + + } diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html index 51b2cc0..b61ca4a 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.html +++ b/ogWebconsole/src/app/components/groups/groups.component.html @@ -15,15 +15,12 @@ apartment {{ unidad.nombre }} - - edit - delete - +
- + {{ breadcrumb.join(' > ') }} @@ -31,7 +28,7 @@
- + apartment @@ -65,4 +62,5 @@ +
\ No newline at end of file diff --git a/ogWebconsole/src/app/components/groups/groups.component.ts b/ogWebconsole/src/app/components/groups/groups.component.ts index 19c3970..c379d78 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.ts +++ b/ogWebconsole/src/app/components/groups/groups.component.ts @@ -27,21 +27,23 @@ export class GroupsComponent implements OnInit { onSelectUnidad(unidad: UnidadOrganizativa): void { this.selectedUnidad = unidad; this.breadcrumb = [unidad.nombre]; - this.loadChildrenAndClients(unidad.uuid, unidad.id); + this.loadChildrenAndClients(unidad.uuid); } onSelectChild(child: any): void { if (child.uuid && child.id) { this.breadcrumb.push(child.name || child.nombre); - this.loadChildrenAndClients(child.uuid, child.id); + this.loadChildrenAndClients(child.uuid); } } - loadChildrenAndClients(uuid: string, id: number): void { + loadChildrenAndClients(uuid: string): void { this.dataService.getChildren(uuid).subscribe( childrenData => { + console.log('Children data:', childrenData); // Depuración this.dataService.getClients(uuid).subscribe( clientsData => { + console.log('Clients data:', clientsData); // Depuración const newChildren = [...childrenData, ...clientsData]; if (newChildren.length > 0) { this.children = newChildren; @@ -57,6 +59,7 @@ export class GroupsComponent implements OnInit { ); } + addOU(): void { this.dialog.open(CreateOrganizationalUnitComponent); } -- 2.40.1 From 844fd23bb4036acacb7334dcecdbc6e0150e017f Mon Sep 17 00:00:00 2001 From: apuente Date: Fri, 21 Jun 2024 12:41:26 +0200 Subject: [PATCH 08/36] Groups type fix organizational units --- .../src/app/components/groups/groups.component.html | 9 ++++++--- .../src/app/components/groups/groups.component.ts | 2 -- ogWebconsole/src/app/components/groups/model.ts | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html index b61ca4a..d468caf 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.html +++ b/ogWebconsole/src/app/components/groups/groups.component.html @@ -9,13 +9,16 @@ Unidad organizativa - - + apartment {{ unidad.nombre }} - + + edit + delete + diff --git a/ogWebconsole/src/app/components/groups/groups.component.ts b/ogWebconsole/src/app/components/groups/groups.component.ts index c379d78..54b4fae 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.ts +++ b/ogWebconsole/src/app/components/groups/groups.component.ts @@ -40,10 +40,8 @@ export class GroupsComponent implements OnInit { loadChildrenAndClients(uuid: string): void { this.dataService.getChildren(uuid).subscribe( childrenData => { - console.log('Children data:', childrenData); // Depuración this.dataService.getClients(uuid).subscribe( clientsData => { - console.log('Clients data:', clientsData); // Depuración const newChildren = [...childrenData, ...clientsData]; if (newChildren.length > 0) { this.children = newChildren; diff --git a/ogWebconsole/src/app/components/groups/model.ts b/ogWebconsole/src/app/components/groups/model.ts index 77c405d..8d52796 100644 --- a/ogWebconsole/src/app/components/groups/model.ts +++ b/ogWebconsole/src/app/components/groups/model.ts @@ -12,6 +12,7 @@ export interface UnidadOrganizativa { id: number; nombre: string; uuid: string; + type: string; aulas: Aula[]; } -- 2.40.1 From 4f651c68c348a387043c86fb42d0fac5d31a9f82 Mon Sep 17 00:00:00 2001 From: apuente Date: Fri, 21 Jun 2024 13:08:16 +0200 Subject: [PATCH 09/36] Groups add delete functionallity --- ogWebconsole/src/app/app.module.ts | 4 +++- .../src/app/components/groups/data.service.ts | 13 +++++++++++ .../components/groups/groups.component.html | 4 ++-- .../app/components/groups/groups.component.ts | 23 +++++++++++++++---- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/ogWebconsole/src/app/app.module.ts b/ogWebconsole/src/app/app.module.ts index 6a50c12..9881dfd 100644 --- a/ogWebconsole/src/app/app.module.ts +++ b/ogWebconsole/src/app/app.module.ts @@ -39,6 +39,7 @@ import { CreateOrganizationalUnitComponent } from './components/groups/organizat import {MatStepperModule} from '@angular/material/stepper'; import { MatSlideToggleModule } from '@angular/material/slide-toggle'; import { CreateClientComponent } from './components/groups/clients/create-client/create-client.component'; +import { DeleteModalComponent } from './components/groups/delete-modal/delete-modal.component'; @NgModule({ declarations: [ @@ -60,7 +61,8 @@ import { CreateClientComponent } from './components/groups/clients/create-client ChangePasswordModalComponent, GroupsComponent, CreateOrganizationalUnitComponent, - CreateClientComponent + CreateClientComponent, + DeleteModalComponent ], bootstrap: [AppComponent], imports: [BrowserModule, diff --git a/ogWebconsole/src/app/components/groups/data.service.ts b/ogWebconsole/src/app/components/groups/data.service.ts index 6e8ae9d..ee41398 100644 --- a/ogWebconsole/src/app/components/groups/data.service.ts +++ b/ogWebconsole/src/app/components/groups/data.service.ts @@ -71,5 +71,18 @@ export class DataService { ); } + deleteElement(uuid: string, type: string): Observable { + const url = type === 'client' + ? `http://127.0.0.1:8080/clients/${uuid}` + : `http://127.0.0.1:8080/organizational-units/${uuid}`; + return this.http.delete(url).pipe( + catchError(error => { + console.error('Error deleting element', error); + return throwError(error); + }) + ); + } + + } diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html index d468caf..133871e 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.html +++ b/ogWebconsole/src/app/components/groups/groups.component.html @@ -17,7 +17,7 @@ edit - delete + delete
@@ -58,7 +58,7 @@ edit - delete + delete
diff --git a/ogWebconsole/src/app/components/groups/groups.component.ts b/ogWebconsole/src/app/components/groups/groups.component.ts index 54b4fae..c8ec8a2 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.ts +++ b/ogWebconsole/src/app/components/groups/groups.component.ts @@ -3,6 +3,7 @@ import { DataService } from './data.service'; import { UnidadOrganizativa } from './model'; import { MatDialog } from '@angular/material/dialog'; import { CreateOrganizationalUnitComponent } from './organizational-units/create-organizational-unit/create-organizational-unit.component'; +import { DeleteModalComponent } from './delete-modal/delete-modal.component'; @Component({ selector: 'app-groups', @@ -40,8 +41,10 @@ export class GroupsComponent implements OnInit { loadChildrenAndClients(uuid: string): void { this.dataService.getChildren(uuid).subscribe( childrenData => { + console.log('Children data:', childrenData); // Depuración this.dataService.getClients(uuid).subscribe( clientsData => { + console.log('Clients data:', clientsData); // Depuración const newChildren = [...childrenData, ...clientsData]; if (newChildren.length > 0) { this.children = newChildren; @@ -57,7 +60,6 @@ export class GroupsComponent implements OnInit { ); } - addOU(): void { this.dialog.open(CreateOrganizationalUnitComponent); } @@ -79,9 +81,22 @@ export class GroupsComponent implements OnInit { } } - onDeleteClick(uuid: string): void { - console.log('UUID del elemento a eliminar:', uuid); - // Aquí puedes agregar lógica adicional para eliminar el elemento si es necesario + onDeleteClick(uuid: string, name: string, type: string): void { + const dialogRef = this.dialog.open(DeleteModalComponent, { + width: '250px', + data: { name } + }); + + dialogRef.afterClosed().subscribe(result => { + if (result) { + this.dataService.deleteElement(uuid, type).subscribe( + () => { + this.loadChildrenAndClients(this.selectedUnidad?.uuid || ''); + }, + error => console.error('Error deleting element', error) + ); + } + }); } onEditClick(type: any, uuid: string): void { -- 2.40.1 From d64a55ba0d0de1cff4833e6e08823dab3633ec8c Mon Sep 17 00:00:00 2001 From: apuente Date: Tue, 25 Jun 2024 13:44:13 +0200 Subject: [PATCH 10/36] Editar uo y clientes modales --- ogWebconsole/src/app/app.module.ts | 6 +- .../create-client.component.html | 19 +-- .../create-client/create-client.component.ts | 49 ++++++-- .../edit-client/edit-client.component.css | 39 ++++++ .../edit-client/edit-client.component.html | 19 +++ .../edit-client/edit-client.component.spec.ts | 23 ++++ .../edit-client/edit-client.component.ts | 70 +++++++++++ .../delete-modal/delete-modal.component.css | 0 .../delete-modal.component.spec.ts | 23 ++++ .../delete-modal/delete-modal.component.ts | 30 +++++ .../components/groups/groups.component.html | 1 + .../app/components/groups/groups.component.ts | 67 ++++++++-- .../create-organizational-unit.component.html | 6 +- .../create-organizational-unit.component.ts | 59 +++++++-- .../edit-organizational-unit.component.css | 39 ++++++ .../edit-organizational-unit.component.html | 116 ++++++++++++++++++ ...edit-organizational-unit.component.spec.ts | 23 ++++ .../edit-organizational-unit.component.ts | 107 ++++++++++++++++ 18 files changed, 654 insertions(+), 42 deletions(-) create mode 100644 ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.css create mode 100644 ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.html create mode 100644 ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.spec.ts create mode 100644 ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.ts create mode 100644 ogWebconsole/src/app/components/groups/delete-modal/delete-modal.component.css create mode 100644 ogWebconsole/src/app/components/groups/delete-modal/delete-modal.component.spec.ts create mode 100644 ogWebconsole/src/app/components/groups/delete-modal/delete-modal.component.ts create mode 100644 ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.css create mode 100644 ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.html create mode 100644 ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.spec.ts create mode 100644 ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.ts diff --git a/ogWebconsole/src/app/app.module.ts b/ogWebconsole/src/app/app.module.ts index 9881dfd..7fd54d9 100644 --- a/ogWebconsole/src/app/app.module.ts +++ b/ogWebconsole/src/app/app.module.ts @@ -40,6 +40,8 @@ import {MatStepperModule} from '@angular/material/stepper'; import { MatSlideToggleModule } from '@angular/material/slide-toggle'; import { CreateClientComponent } from './components/groups/clients/create-client/create-client.component'; import { DeleteModalComponent } from './components/groups/delete-modal/delete-modal.component'; +import { EditOrganizationalUnitComponent } from './components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component'; +import { EditClientComponent } from './components/groups/clients/edit-client/edit-client.component'; @NgModule({ declarations: [ @@ -62,7 +64,9 @@ import { DeleteModalComponent } from './components/groups/delete-modal/delete-mo GroupsComponent, CreateOrganizationalUnitComponent, CreateClientComponent, - DeleteModalComponent + DeleteModalComponent, + EditOrganizationalUnitComponent, + EditClientComponent ], bootstrap: [AppComponent], imports: [BrowserModule, diff --git a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.html b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.html index 5f3f1c8..6061f94 100644 --- a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.html +++ b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.html @@ -1,13 +1,19 @@

Añadir Cliente

+ + Padre + + {{ unit.name }} + + Nombre - + Número de Serie - + Interfaz de Red @@ -19,23 +25,18 @@ MAC - + Formato de MAC inválido. Ejemplo válido: 00:11:22:33:44:55 Dirección IP - + Formato de dirección IP inválido. Ejemplo válido: 127.0.0.1 Estado - - Unidad Organizativa - - Formato de URL inválido. - Menú URL diff --git a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts index c08f536..16b1f77 100644 --- a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts +++ b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts @@ -1,3 +1,4 @@ +import { HttpClient } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { MatDialogRef } from '@angular/material/dialog'; @@ -9,32 +10,56 @@ import { MatDialogRef } from '@angular/material/dialog'; }) export class CreateClientComponent implements OnInit { clientForm!: FormGroup; + parentUnits: any[] = []; // Array to store parent units fetched from API constructor( private fb: FormBuilder, - private dialogRef: MatDialogRef + private dialogRef: MatDialogRef, + private http: HttpClient ) { } ngOnInit(): void { + this.loadParentUnits(); // Load parent units when component initializes this.clientForm = this.fb.group({ + organizationalUnit: [''], name: ['', Validators.required], - serialNumber: ['', Validators.required], - netiface: [''], - netDriver: [''], - mac: ['', [Validators.required, Validators.pattern('^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$')]], - ip: ['', [Validators.required, Validators.pattern('^([0-9]{1,3}\.){3}[0-9]{1,3}$')]], - status: [''], - organizationalUnit: ['', Validators.pattern('https?://.+')], - menu: ['', Validators.pattern('https?://.+')], - hardwareProfile: ['', Validators.pattern('https?://.+')], + serialNumber: [''], + netiface: "eth0", + netDriver: "e1000e", + mac: "00:11:22:33:44:55", + ip: "127.0.0.1", + status: "test", + menu: null, + hardwareProfile: null, }); } + loadParentUnits() { + const url = 'http://127.0.0.1:8080/organizational-units?page=1&itemsPerPage=30'; + + this.http.get(url).subscribe( + response => { + this.parentUnits = response['hydra:member']; + }, + error => { + console.error('Error fetching parent units:', error); + } + ); + } + onSubmit() { + console.log('Form data:', this.clientForm.value); if (this.clientForm.valid) { const formData = this.clientForm.value; - console.log('Form Data:', formData); - this.dialogRef.close(formData); + this.http.post('http://127.0.0.1:8080/clients', formData).subscribe( + response => { + console.log('Response from POST:', response); + this.dialogRef.close(response); + }, + error => { + console.error('Error during POST:', error); + } + ); } } diff --git a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.css b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.css new file mode 100644 index 0000000..40124bd --- /dev/null +++ b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.css @@ -0,0 +1,39 @@ +h1 { + text-align: center; + font-family: 'Roboto', sans-serif; + font-weight: 400; + color: #3f51b5; + margin-bottom: 20px; + } + + .network-form { + display: flex; + flex-direction: column; + gap: 15px; + } + + .form-field { + width: 100%; + margin-top: 10px; + } + + .mat-dialog-content { + padding: 20px; + } + + .mat-dialog-actions { + display: flex; + justify-content: flex-end; + padding: 10px 20px; + } + + button { + text-transform: none; + font-size: 16px; + font-weight: 500; + } + + .mat-slide-toggle { + margin-top: 20px; + } + \ No newline at end of file diff --git a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.html b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.html new file mode 100644 index 0000000..dce2116 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.html @@ -0,0 +1,19 @@ +

Editar Cliente

+
+ + + Padre + + {{ unit.name }} + + + + Nombre + + + +
+
+ + +
diff --git a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.spec.ts b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.spec.ts new file mode 100644 index 0000000..ce87e4f --- /dev/null +++ b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EditClientComponent } from './edit-client.component'; + +describe('EditClientComponent', () => { + let component: EditClientComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [EditClientComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(EditClientComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.ts b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.ts new file mode 100644 index 0000000..3e2dffc --- /dev/null +++ b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.ts @@ -0,0 +1,70 @@ +import { HttpClient } from '@angular/common/http'; +import { Component } from '@angular/core'; +import { FormGroup, FormBuilder, Validators } from '@angular/forms'; +import { MatDialogRef } from '@angular/material/dialog'; +import { CreateClientComponent } from '../create-client/create-client.component'; + +@Component({ + selector: 'app-edit-client', + templateUrl: './edit-client.component.html', + styleUrl: './edit-client.component.css' +}) +export class EditClientComponent { + clientForm!: FormGroup; + parentUnits: any[] = []; // Array to store parent units fetched from API + + constructor( + private fb: FormBuilder, + private dialogRef: MatDialogRef, + private http: HttpClient + ) { } + + ngOnInit(): void { + this.loadParentUnits(); // Load parent units when component initializes + this.clientForm = this.fb.group({ + organizationalUnit: [''], + name: ['', Validators.required], + serialNumber: [''], + netiface: "eth0", + netDriver: "e1000e", + mac: "00:11:22:33:44:55", + ip: "127.0.0.1", + status: "test", + menu: null, + hardwareProfile: null, + }); + } + + loadParentUnits() { + const url = 'http://127.0.0.1:8080/organizational-units?page=1&itemsPerPage=30'; + + this.http.get(url).subscribe( + response => { + this.parentUnits = response['hydra:member']; + }, + error => { + console.error('Error fetching parent units:', error); + } + ); + } + + onSubmit() { + console.log('Form data:', this.clientForm.value); + if (this.clientForm.valid) { + const formData = this.clientForm.value; + this.http.post('http://127.0.0.1:8080/clients', formData).subscribe( + response => { + console.log('Response from POST:', response); + this.dialogRef.close(response); + }, + error => { + console.error('Error during POST:', error); + } + ); + } + } + + onNoClick(): void { + this.dialogRef.close(); + } +} diff --git a/ogWebconsole/src/app/components/groups/delete-modal/delete-modal.component.css b/ogWebconsole/src/app/components/groups/delete-modal/delete-modal.component.css new file mode 100644 index 0000000..e69de29 diff --git a/ogWebconsole/src/app/components/groups/delete-modal/delete-modal.component.spec.ts b/ogWebconsole/src/app/components/groups/delete-modal/delete-modal.component.spec.ts new file mode 100644 index 0000000..1db28bd --- /dev/null +++ b/ogWebconsole/src/app/components/groups/delete-modal/delete-modal.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DeleteModalComponent } from './delete-modal.component'; + +describe('DeleteModalComponent', () => { + let component: DeleteModalComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [DeleteModalComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(DeleteModalComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/ogWebconsole/src/app/components/groups/delete-modal/delete-modal.component.ts b/ogWebconsole/src/app/components/groups/delete-modal/delete-modal.component.ts new file mode 100644 index 0000000..7285277 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/delete-modal/delete-modal.component.ts @@ -0,0 +1,30 @@ +import { Component, Inject } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; + +@Component({ + selector: 'app-delete-confirm-dialog', + template: ` +

Eliminar

+
+

¿Estás seguro que deseas eliminar {{data.name}}?

+
+
+ + +
+ ` +}) +export class DeleteModalComponent { + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: { name: string } + ) {} + + onNoClick(): void { + this.dialogRef.close(false); + } + + onYesClick(): void { + this.dialogRef.close(true); + } +} diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html index 133871e..7e46598 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.html +++ b/ogWebconsole/src/app/components/groups/groups.component.html @@ -1,6 +1,7 @@

Crear

+

Grupos

diff --git a/ogWebconsole/src/app/components/groups/groups.component.ts b/ogWebconsole/src/app/components/groups/groups.component.ts index c8ec8a2..c29a1db 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.ts +++ b/ogWebconsole/src/app/components/groups/groups.component.ts @@ -4,6 +4,9 @@ import { UnidadOrganizativa } from './model'; import { MatDialog } from '@angular/material/dialog'; import { CreateOrganizationalUnitComponent } from './organizational-units/create-organizational-unit/create-organizational-unit.component'; import { DeleteModalComponent } from './delete-modal/delete-modal.component'; +import { CreateClientComponent } from './clients/create-client/create-client.component'; +import { EditOrganizationalUnitComponent } from './organizational-units/edit-organizational-unit/edit-organizational-unit.component'; +import { EditClientComponent } from './clients/edit-client/edit-client.component'; @Component({ selector: 'app-groups', @@ -41,27 +44,58 @@ export class GroupsComponent implements OnInit { loadChildrenAndClients(uuid: string): void { this.dataService.getChildren(uuid).subscribe( childrenData => { - console.log('Children data:', childrenData); // Depuración + console.log('Children data:', childrenData); this.dataService.getClients(uuid).subscribe( clientsData => { - console.log('Clients data:', clientsData); // Depuración + console.log('Clients data:', clientsData); const newChildren = [...childrenData, ...clientsData]; + if (newChildren.length > 0) { this.children = newChildren; } else { - // No se encontraron elementos hijos o clientes, revertimos el breadcrumb - this.breadcrumb.pop(); + this.children = []; // Limpiar card2 cuando no hay elementos + this.breadcrumb.pop(); // Revertir breadcrumb solo si no hay elementos + + // Si deseas que la unidad organizativa se limpie completamente, descomenta la línea siguiente: + // this.selectedUnidad = null; } }, - error => console.error('Error fetching clients', error) + error => { + console.error('Error fetching clients', error); + this.children = []; // Limpiar card2 en caso de error + } ); }, - error => console.error('Error fetching children', error) + error => { + console.error('Error fetching children', error); + this.children = []; // Limpiar card2 en caso de error + } ); } - addOU(): void { - this.dialog.open(CreateOrganizationalUnitComponent); + const dialogRef = this.dialog.open(CreateOrganizationalUnitComponent); + + // Subscribirse al evento unitAdded del componente de creación después de cerrar el diálogo + dialogRef.afterClosed().subscribe(() => { + // Aquí puedes actualizar las cards o hacer cualquier otra acción necesaria después de añadir una unidad organizativa + this.dataService.getUnidadesOrganizativas().subscribe( + data => this.unidadesOrganizativas = data, + error => console.error('Error fetching unidades organizativas', error) + ); + }); + } + + addClient(): void { + const dialogRef = this.dialog.open(CreateClientComponent); + + // Subscribirse al evento unitAdded del componente de creación después de cerrar el diálogo + dialogRef.afterClosed().subscribe(() => { + // Aquí puedes actualizar las cards o hacer cualquier otra acción necesaria después de añadir una unidad organizativa + this.dataService.getUnidadesOrganizativas().subscribe( + data => this.unidadesOrganizativas = data, + error => console.error('Error fetching unidades organizativas', error) + ); + }); } getIcon(type: string): string { @@ -92,6 +126,12 @@ export class GroupsComponent implements OnInit { this.dataService.deleteElement(uuid, type).subscribe( () => { this.loadChildrenAndClients(this.selectedUnidad?.uuid || ''); + + this.dataService.getUnidadesOrganizativas().subscribe( + data => this.unidadesOrganizativas = data, + error => console.error('Error fetching unidades organizativas', error) + ); + }, error => console.error('Error deleting element', error) ); @@ -102,6 +142,15 @@ export class GroupsComponent implements OnInit { onEditClick(type: any, uuid: string): void { console.log('Tipo del elemento a editar:', type); console.log('UUID del elemento a editar:', uuid); - // Aquí puedes agregar lógica adicional para editar el elemento si es necesario + if (type != "client") { + const dialogRef = this.dialog.open(EditOrganizationalUnitComponent, { + data: { type, uuid } + }); + } else { + console.log('Editar cliente'); + const dialogRef = this.dialog.open(EditClientComponent, { + data: { type, uuid } + }); + } } } diff --git a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html index 44f0b27..ec35819 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html +++ b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html @@ -17,8 +17,10 @@
Padre - - + + {{ unit.name }} + + Descripción diff --git a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts index 3e4ef34..1d2247e 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts +++ b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts @@ -1,6 +1,7 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, Output, EventEmitter } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { MatDialogRef } from '@angular/material/dialog'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; @Component({ selector: 'app-create-organizational-unit', @@ -13,14 +14,18 @@ export class CreateOrganizationalUnitComponent implements OnInit { additionalInfoFormGroup: FormGroup; networkSettingsFormGroup: FormGroup; types: string[] = ['organizational-unit', 'classrooms-group', 'classroom', 'clients-group']; + parentUnits: any[] = []; // Array to store parent units fetched from API + + @Output() unitAdded = new EventEmitter(); // Event emitter to notify parent component about unit addition constructor( private _formBuilder: FormBuilder, - private dialogRef: MatDialogRef + private dialogRef: MatDialogRef, + private http: HttpClient // Inject HttpClient for HTTP requests ) { this.generalFormGroup = this._formBuilder.group({ name: ['', Validators.required], - parent: ['', Validators.required], + parent: [''], description: [''], type: ['', Validators.required] }); @@ -45,19 +50,55 @@ export class CreateOrganizationalUnitComponent implements OnInit { }); } - ngOnInit() {} + ngOnInit() { + this.loadParentUnits(); // Load parent units when component initializes + } + + loadParentUnits() { + const url = 'http://127.0.0.1:8080/organizational-units?page=1&itemsPerPage=30'; + + this.http.get(url).subscribe( + response => { + this.parentUnits = response['hydra:member']; + }, + error => { + console.error('Error fetching parent units:', error); + } + ); + } onSubmit() { if (this.generalFormGroup.valid && this.additionalInfoFormGroup.valid && this.networkSettingsFormGroup.valid) { + const parentValue = this.generalFormGroup.value.parent; + const formData = { - ...this.generalFormGroup.value, - ...this.additionalInfoFormGroup.value, - ...this.networkSettingsFormGroup.value, + name: this.generalFormGroup.value.name, + parent: parentValue || null, + description: this.generalFormGroup.value.description, + comments: this.additionalInfoFormGroup.value.comments, + type: this.generalFormGroup.value.type }; - console.log('Form Data:', formData); - this.dialogRef.close(formData); + + // Realizar la solicitud POST + console.log('POST data:', formData); + const postUrl = 'http://127.0.0.1:8080/organizational-units'; + const headers = new HttpHeaders({ 'Content-Type': 'application/json' }); + + this.http.post(postUrl, formData, { headers }).subscribe( + response => { + console.log('POST successful:', response); + // Emitir evento para notificar que se ha añadido una nueva unidad + this.unitAdded.emit(); + this.dialogRef.close(); // Cerrar el diálogo después de añadir + }, + error => { + console.error('Error al realizar POST:', error); + // Manejar el error según sea necesario + } + ); } } + onNoClick(): void { this.dialogRef.close(); diff --git a/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.css b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.css new file mode 100644 index 0000000..40124bd --- /dev/null +++ b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.css @@ -0,0 +1,39 @@ +h1 { + text-align: center; + font-family: 'Roboto', sans-serif; + font-weight: 400; + color: #3f51b5; + margin-bottom: 20px; + } + + .network-form { + display: flex; + flex-direction: column; + gap: 15px; + } + + .form-field { + width: 100%; + margin-top: 10px; + } + + .mat-dialog-content { + padding: 20px; + } + + .mat-dialog-actions { + display: flex; + justify-content: flex-end; + padding: 10px 20px; + } + + button { + text-transform: none; + font-size: 16px; + font-weight: 500; + } + + .mat-slide-toggle { + margin-top: 20px; + } + \ No newline at end of file diff --git a/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.html b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.html new file mode 100644 index 0000000..b0361d9 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.html @@ -0,0 +1,116 @@ +

Editar Unidad Organizativa

+
+ + + +
+ General + + Tipo + + {{ type }} + + + + Nombre + + + + Padre + + {{ unit.name }} + + + + Descripción + + +
+ +
+
+
+ + + +
+ Información Adicional + + Comentarios + + +
+ + +
+
+
+ + + +
+ Configuración de Red + + Proxy + + + + DNS + + + + Máscara de Red + + + + Router + + + + NTP + + + + Modo P2P + + + + Tiempo P2P + + + + IP Multicast + + + + Velocidad Multicast + + + + Puerto Multicast + + + + Modo Multicast + + + + Menú URL + + + + Perfil de Hardware + + + Validación +
+ + +
+
+
+
+
+
+ +
diff --git a/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.spec.ts b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.spec.ts new file mode 100644 index 0000000..0659793 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EditOrganizationalUnitComponent } from './edit-organizational-unit.component'; + +describe('EditOrganizationalUnitComponent', () => { + let component: EditOrganizationalUnitComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [EditOrganizationalUnitComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(EditOrganizationalUnitComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.ts b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.ts new file mode 100644 index 0000000..c9c18f6 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.ts @@ -0,0 +1,107 @@ +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { Component, EventEmitter, Output } from '@angular/core'; +import { FormGroup, FormBuilder, Validators } from '@angular/forms'; +import { MatDialogRef } from '@angular/material/dialog'; +import { CreateOrganizationalUnitComponent } from '../create-organizational-unit/create-organizational-unit.component'; + +@Component({ + selector: 'app-edit-organizational-unit', + templateUrl: './edit-organizational-unit.component.html', + styleUrl: './edit-organizational-unit.component.css' +}) +export class EditOrganizationalUnitComponent { + isLinear = true; + generalFormGroup: FormGroup; + additionalInfoFormGroup: FormGroup; + networkSettingsFormGroup: FormGroup; + types: string[] = ['organizational-unit', 'classrooms-group', 'classroom', 'clients-group']; + parentUnits: any[] = []; // Array to store parent units fetched from API + + @Output() unitAdded = new EventEmitter(); // Event emitter to notify parent component about unit addition + + constructor( + private _formBuilder: FormBuilder, + private dialogRef: MatDialogRef, + private http: HttpClient // Inject HttpClient for HTTP requests + ) { + this.generalFormGroup = this._formBuilder.group({ + name: ['', Validators.required], + parent: [''], + description: [''], + type: ['', Validators.required] + }); + this.additionalInfoFormGroup = this._formBuilder.group({ + comments: [''], + }); + this.networkSettingsFormGroup = this._formBuilder.group({ + proxy: [''], + dns: [''], + netmask: [''], + router: [''], + ntp: [''], + p2pMode: [''], + p2pTime: [0, Validators.min(0)], + mcastIp: [''], + mcastSpeed: [0, Validators.min(0)], + mcastPort: [0, Validators.min(0)], + mcastMode: [''], + menu: ['', Validators.pattern('https?://.+')], + hardwareProfile: ['', Validators.pattern('https?://.+')], + validation: [false] + }); + } + + ngOnInit() { + this.loadParentUnits(); // Load parent units when component initializes + } + + loadParentUnits() { + const url = 'http://127.0.0.1:8080/organizational-units?page=1&itemsPerPage=30'; + + this.http.get(url).subscribe( + response => { + this.parentUnits = response['hydra:member']; + }, + error => { + console.error('Error fetching parent units:', error); + } + ); + } + + onSubmit() { + if (this.generalFormGroup.valid && this.additionalInfoFormGroup.valid && this.networkSettingsFormGroup.valid) { + const parentValue = this.generalFormGroup.value.parent; + + const formData = { + name: this.generalFormGroup.value.name, + parent: parentValue || null, + description: this.generalFormGroup.value.description, + comments: this.additionalInfoFormGroup.value.comments, + type: this.generalFormGroup.value.type + }; + + // Realizar la solicitud POST + console.log('POST data:', formData); + const postUrl = 'http://127.0.0.1:8080/organizational-units'; + const headers = new HttpHeaders({ 'Content-Type': 'application/json' }); + + this.http.post(postUrl, formData, { headers }).subscribe( + response => { + console.log('POST successful:', response); + // Emitir evento para notificar que se ha añadido una nueva unidad + this.unitAdded.emit(); + this.dialogRef.close(); // Cerrar el diálogo después de añadir + }, + error => { + console.error('Error al realizar POST:', error); + // Manejar el error según sea necesario + } + ); + } + } + + + onNoClick(): void { + this.dialogRef.close(); + } +} -- 2.40.1 From eea8cf6db26f83188a551c109b76b05212cd3352 Mon Sep 17 00:00:00 2001 From: apuente Date: Tue, 25 Jun 2024 14:55:41 +0200 Subject: [PATCH 11/36] Nuevo layout para las cards --- .../components/groups/groups.component.html | 22 +++++++++++++++---- .../app/components/groups/groups.component.ts | 14 ++++++------ 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html index 7e46598..22082d7 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.html +++ b/ogWebconsole/src/app/components/groups/groups.component.html @@ -24,9 +24,10 @@ - - - {{ breadcrumb.join(' > ') }} + + + Elementos + {{ breadcrumb.join(' > ') }} @@ -67,4 +68,17 @@ -
\ No newline at end of file + + Detalles del elemento + +

Nombre: {{ selectedDetail.name || selectedDetail.nombre }}

+

Tipo: {{ selectedDetail.type }}

+

ID: {{ selectedDetail.id }}

+

UUID: {{ selectedDetail.uuid }}

+ +
+ +

Selecciona un elemento para ver sus detalles.

+
+
+ diff --git a/ogWebconsole/src/app/components/groups/groups.component.ts b/ogWebconsole/src/app/components/groups/groups.component.ts index c29a1db..1e249c5 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.ts +++ b/ogWebconsole/src/app/components/groups/groups.component.ts @@ -16,6 +16,7 @@ import { EditClientComponent } from './clients/edit-client/edit-client.component export class GroupsComponent implements OnInit { unidadesOrganizativas: UnidadOrganizativa[] = []; selectedUnidad: UnidadOrganizativa | null = null; + selectedDetail: any | null = null; // Nueva variable para el detalle del elemento seleccionado children: any[] = []; breadcrumb: string[] = []; @@ -30,12 +31,14 @@ export class GroupsComponent implements OnInit { onSelectUnidad(unidad: UnidadOrganizativa): void { this.selectedUnidad = unidad; + this.selectedDetail = unidad; // Mostrar detalles de la unidad seleccionada this.breadcrumb = [unidad.nombre]; this.loadChildrenAndClients(unidad.uuid); } onSelectChild(child: any): void { - if (child.uuid && child.id) { + this.selectedDetail = child; // Mostrar detalles del niño seleccionado + if (child.type !== 'client' && child.uuid && child.id) { this.breadcrumb.push(child.name || child.nombre); this.loadChildrenAndClients(child.uuid); } @@ -72,6 +75,7 @@ export class GroupsComponent implements OnInit { } ); } + addOU(): void { const dialogRef = this.dialog.open(CreateOrganizationalUnitComponent); @@ -143,14 +147,10 @@ export class GroupsComponent implements OnInit { console.log('Tipo del elemento a editar:', type); console.log('UUID del elemento a editar:', uuid); if (type != "client") { - const dialogRef = this.dialog.open(EditOrganizationalUnitComponent, { - data: { type, uuid } - }); + const dialogRef = this.dialog.open(EditOrganizationalUnitComponent); } else { console.log('Editar cliente'); - const dialogRef = this.dialog.open(EditClientComponent, { - data: { type, uuid } - }); + const dialogRef = this.dialog.open(EditClientComponent); } } } -- 2.40.1 From 60917acd2a0746aef5ed7f393e741632b0a3276b Mon Sep 17 00:00:00 2001 From: apuente Date: Wed, 26 Jun 2024 12:14:56 +0200 Subject: [PATCH 12/36] Cards estaticas --- .../change-password-modal.component.html | 4 ++++ ...-password-modal.component_BACKUP_16366.css | 23 ------------------- ...-password-modal.component_BACKUP_24186.css | 23 ------------------- ...-password-modal.component_BACKUP_29029.css | 23 ------------------- ...ge-password-modal.component_BASE_16366.css | 0 ...ge-password-modal.component_BASE_24186.css | 0 ...ge-password-modal.component_BASE_29029.css | 0 ...e-password-modal.component_LOCAL_16366.css | 10 -------- ...e-password-modal.component_LOCAL_24186.css | 10 -------- ...e-password-modal.component_LOCAL_29029.css | 10 -------- ...-password-modal.component_REMOTE_16366.css | 15 ------------ ...-password-modal.component_REMOTE_24186.css | 15 ------------ ...-password-modal.component_REMOTE_29029.css | 15 ------------ 13 files changed, 4 insertions(+), 144 deletions(-) delete mode 100644 ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BACKUP_16366.css delete mode 100644 ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BACKUP_24186.css delete mode 100644 ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BACKUP_29029.css delete mode 100644 ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BASE_16366.css delete mode 100644 ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BASE_24186.css delete mode 100644 ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BASE_29029.css delete mode 100644 ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_LOCAL_16366.css delete mode 100644 ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_LOCAL_24186.css delete mode 100644 ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_LOCAL_29029.css delete mode 100644 ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_REMOTE_16366.css delete mode 100644 ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_REMOTE_24186.css delete mode 100644 ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_REMOTE_29029.css diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component.html b/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component.html index 5873379..3fb4682 100644 --- a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component.html +++ b/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component.html @@ -5,6 +5,10 @@ Nombre de usuario + + Contraseña actual + + Nueva contraseña diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BACKUP_16366.css b/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BACKUP_16366.css deleted file mode 100644 index bd09f65..0000000 --- a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BACKUP_16366.css +++ /dev/null @@ -1,23 +0,0 @@ -.user-form .form-field { - display: block; -<<<<<<< HEAD - margin-bottom: 10px; /* Puedes ajustar el valor para cambiar la separación */ -======= - margin-bottom: 10px; ->>>>>>> main - } - - .checkbox-group label { - display: block; -<<<<<<< HEAD - margin-bottom: 8px; /* Ajusta este valor según necesites */ -======= - margin-bottom: 8px; - } - - .error-message { - color: red; - margin-top: 10px; ->>>>>>> main - } - \ No newline at end of file diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BACKUP_24186.css b/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BACKUP_24186.css deleted file mode 100644 index bd09f65..0000000 --- a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BACKUP_24186.css +++ /dev/null @@ -1,23 +0,0 @@ -.user-form .form-field { - display: block; -<<<<<<< HEAD - margin-bottom: 10px; /* Puedes ajustar el valor para cambiar la separación */ -======= - margin-bottom: 10px; ->>>>>>> main - } - - .checkbox-group label { - display: block; -<<<<<<< HEAD - margin-bottom: 8px; /* Ajusta este valor según necesites */ -======= - margin-bottom: 8px; - } - - .error-message { - color: red; - margin-top: 10px; ->>>>>>> main - } - \ No newline at end of file diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BACKUP_29029.css b/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BACKUP_29029.css deleted file mode 100644 index bd09f65..0000000 --- a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BACKUP_29029.css +++ /dev/null @@ -1,23 +0,0 @@ -.user-form .form-field { - display: block; -<<<<<<< HEAD - margin-bottom: 10px; /* Puedes ajustar el valor para cambiar la separación */ -======= - margin-bottom: 10px; ->>>>>>> main - } - - .checkbox-group label { - display: block; -<<<<<<< HEAD - margin-bottom: 8px; /* Ajusta este valor según necesites */ -======= - margin-bottom: 8px; - } - - .error-message { - color: red; - margin-top: 10px; ->>>>>>> main - } - \ No newline at end of file diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BASE_16366.css b/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BASE_16366.css deleted file mode 100644 index e69de29..0000000 diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BASE_24186.css b/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BASE_24186.css deleted file mode 100644 index e69de29..0000000 diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BASE_29029.css b/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_BASE_29029.css deleted file mode 100644 index e69de29..0000000 diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_LOCAL_16366.css b/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_LOCAL_16366.css deleted file mode 100644 index 6916e95..0000000 --- a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_LOCAL_16366.css +++ /dev/null @@ -1,10 +0,0 @@ -.user-form .form-field { - display: block; - margin-bottom: 10px; /* Puedes ajustar el valor para cambiar la separación */ - } - - .checkbox-group label { - display: block; - margin-bottom: 8px; /* Ajusta este valor según necesites */ - } - \ No newline at end of file diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_LOCAL_24186.css b/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_LOCAL_24186.css deleted file mode 100644 index 6916e95..0000000 --- a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_LOCAL_24186.css +++ /dev/null @@ -1,10 +0,0 @@ -.user-form .form-field { - display: block; - margin-bottom: 10px; /* Puedes ajustar el valor para cambiar la separación */ - } - - .checkbox-group label { - display: block; - margin-bottom: 8px; /* Ajusta este valor según necesites */ - } - \ No newline at end of file diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_LOCAL_29029.css b/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_LOCAL_29029.css deleted file mode 100644 index 6916e95..0000000 --- a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_LOCAL_29029.css +++ /dev/null @@ -1,10 +0,0 @@ -.user-form .form-field { - display: block; - margin-bottom: 10px; /* Puedes ajustar el valor para cambiar la separación */ - } - - .checkbox-group label { - display: block; - margin-bottom: 8px; /* Ajusta este valor según necesites */ - } - \ No newline at end of file diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_REMOTE_16366.css b/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_REMOTE_16366.css deleted file mode 100644 index 605ecf3..0000000 --- a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_REMOTE_16366.css +++ /dev/null @@ -1,15 +0,0 @@ -.user-form .form-field { - display: block; - margin-bottom: 10px; - } - - .checkbox-group label { - display: block; - margin-bottom: 8px; - } - - .error-message { - color: red; - margin-top: 10px; - } - \ No newline at end of file diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_REMOTE_24186.css b/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_REMOTE_24186.css deleted file mode 100644 index 605ecf3..0000000 --- a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_REMOTE_24186.css +++ /dev/null @@ -1,15 +0,0 @@ -.user-form .form-field { - display: block; - margin-bottom: 10px; - } - - .checkbox-group label { - display: block; - margin-bottom: 8px; - } - - .error-message { - color: red; - margin-top: 10px; - } - \ No newline at end of file diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_REMOTE_29029.css b/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_REMOTE_29029.css deleted file mode 100644 index 605ecf3..0000000 --- a/ogWebconsole/src/app/components/pages/admin/users/users/change-password-modal/change-password-modal.component_REMOTE_29029.css +++ /dev/null @@ -1,15 +0,0 @@ -.user-form .form-field { - display: block; - margin-bottom: 10px; - } - - .checkbox-group label { - display: block; - margin-bottom: 8px; - } - - .error-message { - color: red; - margin-top: 10px; - } - \ No newline at end of file -- 2.40.1 From 0f47ebeb21e02a51a6afcccf1b26da14c0b369b4 Mon Sep 17 00:00:00 2001 From: apuente Date: Thu, 27 Jun 2024 15:59:19 +0200 Subject: [PATCH 13/36] Login css fix --- .../components/groups/groups.component.css | 13 +++--- .../app/components/login/login.component.css | 40 ++++++++++++++----- .../app/components/login/login.component.html | 2 + .../app/components/login/login.component.ts | 8 ++++ 4 files changed, 47 insertions(+), 16 deletions(-) diff --git a/ogWebconsole/src/app/components/groups/groups.component.css b/ogWebconsole/src/app/components/groups/groups.component.css index 74b2034..eb6ceca 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.css +++ b/ogWebconsole/src/app/components/groups/groups.component.css @@ -7,6 +7,13 @@ mat-card { margin: 10px; } +.elements-card{ + margin: 10px; + width: 800px; + background-color: #fafafa; + +} + .groups-button-row { display: flex; flex-grow: 1; @@ -39,9 +46,3 @@ button { color: #212121; } -.elements-card{ - margin: 10px; - width: 800px; - background-color: #fafafa; - -} \ No newline at end of file diff --git a/ogWebconsole/src/app/components/login/login.component.css b/ogWebconsole/src/app/components/login/login.component.css index 36514b6..f2cb166 100644 --- a/ogWebconsole/src/app/components/login/login.component.css +++ b/ogWebconsole/src/app/components/login/login.component.css @@ -1,16 +1,17 @@ .login { overflow: hidden; - background-color: rgb(255, 255, 255); - border: 1px solid grey; - padding: 40px 30px 30px 30px; + background-color: #fff; + border: 1px solid rgba(128, 128, 128, 0.801); + padding: 40px 30px; border-radius: 10px; position: absolute; top: 50%; left: 50%; - width: 400px; + width: 300px; transform: translate(-50%, -50%); transition: transform 300ms, box-shadow 300ms; box-shadow: 5px 10px 10px rgba(2, 128, 144, 0.2); + text-align: center; } .login::before, .login::after { @@ -18,13 +19,17 @@ position: absolute; width: 600px; height: 600px; - border-top-left-radius: 40%; - border-top-right-radius: 45%; - border-bottom-left-radius: 35%; - border-bottom-right-radius: 40%; + border-radius: 40% 45% 35% 40%; z-index: -1; } +.login-logo { + height: 100px; + width: 100px; + display: block; + margin: 0 auto 20px; +} + .login input { font-family: "Asap", sans-serif; display: block; @@ -32,8 +37,9 @@ font-size: 16px; background: rgba(230, 230, 230); width: 100%; - padding: 10px 10px; + padding: 10px; margin: 15px -10px; + text-align: center; } .login button { @@ -48,7 +54,7 @@ margin-top: 10px; margin-left: -5px; border-radius: 5px; - background-color: #0084ff; + background-color: #3f51b5; transition: background-color 300ms; } @@ -64,3 +70,17 @@ color: red; margin-top: 10px; } + + +@keyframes rotate360 { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } + } + + .rotating { + animation: rotate360 0.6s cubic-bezier(.42,0,1,1) infinite; + } \ No newline at end of file diff --git a/ogWebconsole/src/app/components/login/login.component.html b/ogWebconsole/src/app/components/login/login.component.html index 02cfc41..f6a58a1 100644 --- a/ogWebconsole/src/app/components/login/login.component.html +++ b/ogWebconsole/src/app/components/login/login.component.html @@ -1,5 +1,7 @@
- +
diff --git a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.ts b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.ts index 3e2dffc..60d38d3 100644 --- a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.ts +++ b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.ts @@ -1,7 +1,7 @@ -import { HttpClient } from '@angular/common/http'; -import { Component } from '@angular/core'; +import {HttpClient, HttpHeaders} from '@angular/common/http'; +import {Component, Inject} from '@angular/core'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; -import { MatDialogRef } from '@angular/material/dialog'; +import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; import { CreateClientComponent } from '../create-client/create-client.component'; @Component({ @@ -12,12 +12,20 @@ import { CreateClientComponent } from '../create-client/create-client.component' export class EditClientComponent { clientForm!: FormGroup; parentUnits: any[] = []; // Array to store parent units fetched from API + isEditMode: boolean; // Flag to check if it's edit mode constructor( private fb: FormBuilder, private dialogRef: MatDialogRef, - private http: HttpClient - ) { } + private http: HttpClient, + @Inject(MAT_DIALOG_DATA) public data: any // Inject data for edit mode + + ) { + this.isEditMode = !!data?.uuid; // Check if uuid is passed to determine edit mode + if (this.isEditMode) { + this.loadData(data.uuid); + } + } ngOnInit(): void { this.loadParentUnits(); // Load parent units when component initializes @@ -48,19 +56,52 @@ export class EditClientComponent { ); } + loadData(uuid: string) { + const url = `http://127.0.0.1:8080/clients/${uuid}`; + + this.http.get(url).subscribe( + data => { + this.clientForm.patchValue({ + name: data.name, + organizationalUnit: data.organizationalUnit ? data.organizationalUnit['@id'] : '' + }); + }); + } + onSubmit() { console.log('Form data:', this.clientForm.value); if (this.clientForm.valid) { const formData = this.clientForm.value; - this.http.post('http://127.0.0.1:8080/clients', formData).subscribe( - response => { - console.log('Response from POST:', response); - this.dialogRef.close(response); - }, - error => { - console.error('Error during POST:', error); - } - ); + + if (this.isEditMode) { + // Edit mode: Send PUT request to update the unit + const putUrl = `http://127.0.0.1:8080/clients/${this.data.uuid}`; + const headers = new HttpHeaders({ 'Content-Type': 'application/json' }); + + this.http.patch(putUrl, formData, { headers }).subscribe( + response => { + console.log('PUT successful:', response); + this.dialogRef.close(); + }, + error => { + console.error('Error al realizar PUT:', error); + } + ); + } else { + // Create mode: Send POST request to create a new unit + const postUrl = 'http://127.0.0.1:8080/clients'; + const headers = new HttpHeaders({ 'Content-Type': 'application/json' }); + + this.http.post(postUrl, formData, { headers }).subscribe( + response => { + console.log('POST successful:', response); + this.dialogRef.close(); + }, + error => { + console.error('Error al realizar POST:', error); + } + ); + } } } diff --git a/ogWebconsole/src/app/components/groups/data.service.ts b/ogWebconsole/src/app/components/groups/data.service.ts index ee41398..81bca43 100644 --- a/ogWebconsole/src/app/components/groups/data.service.ts +++ b/ogWebconsole/src/app/components/groups/data.service.ts @@ -72,8 +72,8 @@ export class DataService { } deleteElement(uuid: string, type: string): Observable { - const url = type === 'client' - ? `http://127.0.0.1:8080/clients/${uuid}` + const url = type === 'client' + ? `http://127.0.0.1:8080/clients/${uuid}` : `http://127.0.0.1:8080/organizational-units/${uuid}`; return this.http.delete(url).pipe( catchError(error => { @@ -82,7 +82,7 @@ export class DataService { }) ); } - + } diff --git a/ogWebconsole/src/app/components/groups/groups.component.css b/ogWebconsole/src/app/components/groups/groups.component.css index eb6ceca..4f9c5bd 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.css +++ b/ogWebconsole/src/app/components/groups/groups.component.css @@ -7,11 +7,36 @@ mat-card { margin: 10px; } +mat-card-title { + display: flex; + justify-content: space-between; + margin: 10px; +} + .elements-card{ margin: 10px; width: 800px; background-color: #fafafa; - +} + +.title-with-breadcrumb { + display: flex; + flex-direction: column; +} + +mat-card-subtitle { + font-size: 0.875rem; + color: rgba(0, 0, 0, 0.54); +} + +mat-card-subtitle a { + cursor: pointer; + text-decoration: underline; + color: #1976d2; /* Color azul típico de enlaces */ +} + +mat-card-subtitle a:hover { + text-decoration: none; } .groups-button-row { @@ -33,13 +58,13 @@ button { } .actions { - margin-left: auto; + margin-left: auto; } .actions mat-icon { - cursor: pointer; - margin-left: 48px; - color: #757575; + cursor: pointer; + margin-left: 48px; + color: #757575; } .actions mat-icon:hover { diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html index f9c7cdd..8c393d2 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.html +++ b/ogWebconsole/src/app/components/groups/groups.component.html @@ -10,7 +10,7 @@ Unidad organizativa - apartment @@ -25,8 +25,17 @@ - Elementos - {{ breadcrumb.join(' > ') }} + +
+ Elementos + + + {{ crumb }} + > + + +
+
diff --git a/ogWebconsole/src/app/components/groups/groups.component.ts b/ogWebconsole/src/app/components/groups/groups.component.ts index 1e249c5..11edf0d 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.ts +++ b/ogWebconsole/src/app/components/groups/groups.component.ts @@ -19,6 +19,7 @@ export class GroupsComponent implements OnInit { selectedDetail: any | null = null; // Nueva variable para el detalle del elemento seleccionado children: any[] = []; breadcrumb: string[] = []; + breadcrumbData: any[] = []; // Almacenar datos de breadcrumb para navegar constructor(private dataService: DataService, public dialog: MatDialog) {} @@ -33,6 +34,7 @@ export class GroupsComponent implements OnInit { this.selectedUnidad = unidad; this.selectedDetail = unidad; // Mostrar detalles de la unidad seleccionada this.breadcrumb = [unidad.nombre]; + this.breadcrumbData = [unidad]; this.loadChildrenAndClients(unidad.uuid); } @@ -40,10 +42,22 @@ export class GroupsComponent implements OnInit { this.selectedDetail = child; // Mostrar detalles del niño seleccionado if (child.type !== 'client' && child.uuid && child.id) { this.breadcrumb.push(child.name || child.nombre); + this.breadcrumbData.push(child); this.loadChildrenAndClients(child.uuid); } } + navigateToBreadcrumb(index: number): void { + this.breadcrumb = this.breadcrumb.slice(0, index + 1); + const target = this.breadcrumbData[index]; + this.breadcrumbData = this.breadcrumbData.slice(0, index + 1); + if (target.type === 'client') { + this.selectedDetail = target; + } else { + this.loadChildrenAndClients(target.uuid); + } + } + loadChildrenAndClients(uuid: string): void { this.dataService.getChildren(uuid).subscribe( childrenData => { @@ -52,13 +66,12 @@ export class GroupsComponent implements OnInit { clientsData => { console.log('Clients data:', clientsData); const newChildren = [...childrenData, ...clientsData]; - + if (newChildren.length > 0) { this.children = newChildren; } else { this.children = []; // Limpiar card2 cuando no hay elementos - this.breadcrumb.pop(); // Revertir breadcrumb solo si no hay elementos - + // Si deseas que la unidad organizativa se limpie completamente, descomenta la línea siguiente: // this.selectedUnidad = null; } @@ -75,7 +88,7 @@ export class GroupsComponent implements OnInit { } ); } - + addOU(): void { const dialogRef = this.dialog.open(CreateOrganizationalUnitComponent); @@ -130,12 +143,12 @@ export class GroupsComponent implements OnInit { this.dataService.deleteElement(uuid, type).subscribe( () => { this.loadChildrenAndClients(this.selectedUnidad?.uuid || ''); - + this.dataService.getUnidadesOrganizativas().subscribe( data => this.unidadesOrganizativas = data, error => console.error('Error fetching unidades organizativas', error) ); - + }, error => console.error('Error deleting element', error) ); @@ -147,10 +160,10 @@ export class GroupsComponent implements OnInit { console.log('Tipo del elemento a editar:', type); console.log('UUID del elemento a editar:', uuid); if (type != "client") { - const dialogRef = this.dialog.open(EditOrganizationalUnitComponent); + const dialogRef = this.dialog.open(EditOrganizationalUnitComponent, { data: { uuid } }); } else { console.log('Editar cliente'); - const dialogRef = this.dialog.open(EditClientComponent); + const dialogRef = this.dialog.open(EditClientComponent, { data: { uuid } } ); } } } diff --git a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html index ec35819..e8aee32 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html +++ b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html @@ -1,4 +1,5 @@

Añadir Unidad Organizativa

+
@@ -20,7 +21,7 @@ {{ unit.name }} - + Descripción @@ -30,7 +31,7 @@
- +
diff --git a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts index 1d2247e..43eb8eb 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts +++ b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts @@ -70,7 +70,7 @@ export class CreateOrganizationalUnitComponent implements OnInit { onSubmit() { if (this.generalFormGroup.valid && this.additionalInfoFormGroup.valid && this.networkSettingsFormGroup.valid) { const parentValue = this.generalFormGroup.value.parent; - + const formData = { name: this.generalFormGroup.value.name, parent: parentValue || null, @@ -78,12 +78,12 @@ export class CreateOrganizationalUnitComponent implements OnInit { comments: this.additionalInfoFormGroup.value.comments, type: this.generalFormGroup.value.type }; - + // Realizar la solicitud POST console.log('POST data:', formData); const postUrl = 'http://127.0.0.1:8080/organizational-units'; const headers = new HttpHeaders({ 'Content-Type': 'application/json' }); - + this.http.post(postUrl, formData, { headers }).subscribe( response => { console.log('POST successful:', response); @@ -98,7 +98,7 @@ export class CreateOrganizationalUnitComponent implements OnInit { ); } } - + onNoClick(): void { this.dialogRef.close(); diff --git a/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.html b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.html index b0361d9..839c4da 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.html +++ b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.html @@ -20,7 +20,7 @@ {{ unit.name }} - + Descripción @@ -30,7 +30,7 @@
- +
diff --git a/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.ts b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.ts index c9c18f6..6c86f66 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.ts +++ b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.ts @@ -1,7 +1,7 @@ import { HttpClient, HttpHeaders } from '@angular/common/http'; -import { Component, EventEmitter, Output } from '@angular/core'; +import { Component, EventEmitter, Inject, OnInit, Output } from '@angular/core'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; -import { MatDialogRef } from '@angular/material/dialog'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { CreateOrganizationalUnitComponent } from '../create-organizational-unit/create-organizational-unit.component'; @Component({ @@ -9,30 +9,36 @@ import { CreateOrganizationalUnitComponent } from '../create-organizational-unit templateUrl: './edit-organizational-unit.component.html', styleUrl: './edit-organizational-unit.component.css' }) -export class EditOrganizationalUnitComponent { +export class EditOrganizationalUnitComponent implements OnInit { isLinear = true; generalFormGroup: FormGroup; additionalInfoFormGroup: FormGroup; networkSettingsFormGroup: FormGroup; types: string[] = ['organizational-unit', 'classrooms-group', 'classroom', 'clients-group']; parentUnits: any[] = []; // Array to store parent units fetched from API + isEditMode: boolean; // Flag to check if it's edit mode @Output() unitAdded = new EventEmitter(); // Event emitter to notify parent component about unit addition constructor( private _formBuilder: FormBuilder, private dialogRef: MatDialogRef, - private http: HttpClient // Inject HttpClient for HTTP requests + private http: HttpClient, // Inject HttpClient for HTTP requests + @Inject(MAT_DIALOG_DATA) public data: any // Inject data for edit mode ) { + this.isEditMode = !!data?.uuid; // Check if uuid is passed to determine edit mode + this.generalFormGroup = this._formBuilder.group({ name: ['', Validators.required], parent: [''], description: [''], type: ['', Validators.required] }); + this.additionalInfoFormGroup = this._formBuilder.group({ comments: [''], }); + this.networkSettingsFormGroup = this._formBuilder.group({ proxy: [''], dns: [''], @@ -49,6 +55,10 @@ export class EditOrganizationalUnitComponent { hardwareProfile: ['', Validators.pattern('https?://.+')], validation: [false] }); + + if (this.isEditMode) { + this.loadData(data.uuid); + } } ngOnInit() { @@ -68,38 +78,89 @@ export class EditOrganizationalUnitComponent { ); } + loadData(uuid: string) { + const url = `http://127.0.0.1:8080/organizational-units/${uuid}`; + + this.http.get(url).subscribe( + data => { + this.generalFormGroup.patchValue({ + name: data.name, + parent: data.parent ? data.parent['@id'] : '', + description: data.description, + type: data.type + }); + this.additionalInfoFormGroup.patchValue({ + comments: data.comments + }); + this.networkSettingsFormGroup.patchValue({ + proxy: data.proxy, + dns: data.dns, + netmask: data.netmask, + router: data.router, + ntp: data.ntp, + p2pMode: data.p2pMode, + p2pTime: data.p2pTime, + mcastIp: data.mcastIp, + mcastSpeed: data.mcastSpeed, + mcastPort: data.mcastPort, + mcastMode: data.mcastMode, + menu: data.menu, + hardwareProfile: data.hardwareProfile, + validation: data.validation + }); + }, + error => { + console.error('Error fetching data for edit:', error); + } + ); + } + onSubmit() { if (this.generalFormGroup.valid && this.additionalInfoFormGroup.valid && this.networkSettingsFormGroup.valid) { const parentValue = this.generalFormGroup.value.parent; - + const formData = { name: this.generalFormGroup.value.name, parent: parentValue || null, description: this.generalFormGroup.value.description, comments: this.additionalInfoFormGroup.value.comments, - type: this.generalFormGroup.value.type + type: this.generalFormGroup.value.type, + ...this.networkSettingsFormGroup.value }; - - // Realizar la solicitud POST - console.log('POST data:', formData); - const postUrl = 'http://127.0.0.1:8080/organizational-units'; - const headers = new HttpHeaders({ 'Content-Type': 'application/json' }); - - this.http.post(postUrl, formData, { headers }).subscribe( - response => { - console.log('POST successful:', response); - // Emitir evento para notificar que se ha añadido una nueva unidad - this.unitAdded.emit(); - this.dialogRef.close(); // Cerrar el diálogo después de añadir - }, - error => { - console.error('Error al realizar POST:', error); - // Manejar el error según sea necesario - } - ); + + if (this.isEditMode) { + // Edit mode: Send PUT request to update the unit + const putUrl = `http://127.0.0.1:8080/organizational-units/${this.data.uuid}`; + const headers = new HttpHeaders({ 'Content-Type': 'application/json' }); + + this.http.put(putUrl, formData, { headers }).subscribe( + response => { + console.log('PUT successful:', response); + this.unitAdded.emit(); + this.dialogRef.close(); + }, + error => { + console.error('Error al realizar PUT:', error); + } + ); + } else { + // Create mode: Send POST request to create a new unit + const postUrl = 'http://127.0.0.1:8080/organizational-units'; + const headers = new HttpHeaders({ 'Content-Type': 'application/json' }); + + this.http.post(postUrl, formData, { headers }).subscribe( + response => { + console.log('POST successful:', response); + this.unitAdded.emit(); + this.dialogRef.close(); + }, + error => { + console.error('Error al realizar POST:', error); + } + ); + } } } - onNoClick(): void { this.dialogRef.close(); -- 2.40.1 From ea9ec9087bab525a88d86d2ccbc711346ffa9f6c Mon Sep 17 00:00:00 2001 From: apuente Date: Wed, 3 Jul 2024 16:24:08 +0200 Subject: [PATCH 17/36] Git revert commit --- ogWebconsole/src/app/app.module.ts | 4 ++- .../src/app/components/groups/data.service.ts | 2 +- .../components/groups/groups.component.html | 4 +++ .../app/components/groups/groups.component.ts | 4 ++- .../src/app/components/groups/model.ts | 35 +++++++++++++++++++ 5 files changed, 46 insertions(+), 3 deletions(-) diff --git a/ogWebconsole/src/app/app.module.ts b/ogWebconsole/src/app/app.module.ts index 7fd54d9..2e28d37 100644 --- a/ogWebconsole/src/app/app.module.ts +++ b/ogWebconsole/src/app/app.module.ts @@ -42,6 +42,7 @@ import { CreateClientComponent } from './components/groups/clients/create-client import { DeleteModalComponent } from './components/groups/delete-modal/delete-modal.component'; import { EditOrganizationalUnitComponent } from './components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component'; import { EditClientComponent } from './components/groups/clients/edit-client/edit-client.component'; +import { ClassroomViewComponent } from './components/groups/classroom-view/classroom-view.component'; @NgModule({ declarations: [ @@ -66,7 +67,8 @@ import { EditClientComponent } from './components/groups/clients/edit-client/edi CreateClientComponent, DeleteModalComponent, EditOrganizationalUnitComponent, - EditClientComponent + EditClientComponent, + ClassroomViewComponent ], bootstrap: [AppComponent], imports: [BrowserModule, diff --git a/ogWebconsole/src/app/components/groups/data.service.ts b/ogWebconsole/src/app/components/groups/data.service.ts index ee41398..e25336e 100644 --- a/ogWebconsole/src/app/components/groups/data.service.ts +++ b/ogWebconsole/src/app/components/groups/data.service.ts @@ -55,10 +55,10 @@ export class DataService { } getClients(uuid: string): Observable { - console.log('unidadId', uuid); return this.http.get(this.clientsUrl).pipe( map(response => { if (response['hydra:member'] && Array.isArray(response['hydra:member'])) { + console.log(response); return response['hydra:member'].filter((client: any) => client.organizationalUnit && client.organizationalUnit['@id'] === `/organizational-units/${uuid}`); } else { throw new Error('Unexpected response format'); diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html index 7edc5cd..84a1aa7 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.html +++ b/ogWebconsole/src/app/components/groups/groups.component.html @@ -68,3 +68,7 @@ + + + \ No newline at end of file diff --git a/ogWebconsole/src/app/components/groups/groups.component.ts b/ogWebconsole/src/app/components/groups/groups.component.ts index 163b45e..ad342f2 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.ts +++ b/ogWebconsole/src/app/components/groups/groups.component.ts @@ -1,6 +1,6 @@ import { Component, OnInit } from '@angular/core'; import { DataService } from './data.service'; -import { UnidadOrganizativa } from './model'; +import { ClientCollection, UnidadOrganizativa } from './model'; import { MatDialog } from '@angular/material/dialog'; import { CreateOrganizationalUnitComponent } from './organizational-units/create-organizational-unit/create-organizational-unit.component'; import { DeleteModalComponent } from './delete-modal/delete-modal.component'; @@ -114,4 +114,6 @@ export class GroupsComponent implements OnInit { const dialogComponent = type === 'client' ? EditClientComponent : EditOrganizationalUnitComponent; this.dialog.open(dialogComponent as any); // Usando type assertion aquí } + + } diff --git a/ogWebconsole/src/app/components/groups/model.ts b/ogWebconsole/src/app/components/groups/model.ts index 8d52796..f90b50d 100644 --- a/ogWebconsole/src/app/components/groups/model.ts +++ b/ogWebconsole/src/app/components/groups/model.ts @@ -16,3 +16,38 @@ export interface UnidadOrganizativa { aulas: Aula[]; } +export interface OrganizationalUnit { + "@id": string; + "@type": string; + id: number; + name: string; + type: string; + uuid: string; +} + +export interface Client { + "@id": string; + "@type": string; + id: number; + name: string; + type: string; + serialNumber: string; + netiface: string; + organizationalUnit: OrganizationalUnit; + partitions: any[]; + createdAt: string; + createdBy: string; + uuid: string; +} + +export interface ClientCollection { + "@context": string; + "@id": string; + "@type": string; + "hydra:totalItems": number; + "hydra:member": Client[]; + "hydra:view": { + "@id": string; + "@type": string; + }; +} \ No newline at end of file -- 2.40.1 From 59d91b99b66afab812dfc51b7310b7c84a5280e6 Mon Sep 17 00:00:00 2001 From: apuente Date: Wed, 3 Jul 2024 23:48:51 +0200 Subject: [PATCH 18/36] =?UTF-8?q?Visualizaci=C3=B3n=20de=20aulas=20y=20cli?= =?UTF-8?q?entes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../create-client/create-client.component.ts | 2 - .../src/app/components/groups/data.service.ts | 1 - .../components/groups/groups.component.css | 16 +-- .../components/groups/groups.component.html | 71 +++++++----- .../app/components/groups/groups.component.ts | 109 ++++++++++++------ 5 files changed, 119 insertions(+), 80 deletions(-) diff --git a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts index 16b1f77..857c62e 100644 --- a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts +++ b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts @@ -48,12 +48,10 @@ export class CreateClientComponent implements OnInit { } onSubmit() { - console.log('Form data:', this.clientForm.value); if (this.clientForm.valid) { const formData = this.clientForm.value; this.http.post('http://127.0.0.1:8080/clients', formData).subscribe( response => { - console.log('Response from POST:', response); this.dialogRef.close(response); }, error => { diff --git a/ogWebconsole/src/app/components/groups/data.service.ts b/ogWebconsole/src/app/components/groups/data.service.ts index e25336e..ed9d78f 100644 --- a/ogWebconsole/src/app/components/groups/data.service.ts +++ b/ogWebconsole/src/app/components/groups/data.service.ts @@ -58,7 +58,6 @@ export class DataService { return this.http.get(this.clientsUrl).pipe( map(response => { if (response['hydra:member'] && Array.isArray(response['hydra:member'])) { - console.log(response); return response['hydra:member'].filter((client: any) => client.organizationalUnit && client.organizationalUnit['@id'] === `/organizational-units/${uuid}`); } else { throw new Error('Unexpected response format'); diff --git a/ogWebconsole/src/app/components/groups/groups.component.css b/ogWebconsole/src/app/components/groups/groups.component.css index 4f49ead..f982e9b 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.css +++ b/ogWebconsole/src/app/components/groups/groups.component.css @@ -7,7 +7,8 @@ mat-card { margin: 10px; } -.elements-card { +.elements-card{ + margin: 10px; width: 800px; background-color: #fafafa; } @@ -31,21 +32,16 @@ button { } .actions { - margin-left: auto; + margin-left: auto; } .actions mat-icon { - cursor: pointer; - margin-left: 48px; - color: #757575; + cursor: pointer; + margin-left: 48px; + color: #757575; } .actions mat-icon:hover { color: #212121; } -.element-name{ - position: relative; - top: -5px; - margin-left: 3px; -} \ No newline at end of file diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html index 84a1aa7..d61929e 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.html +++ b/ogWebconsole/src/app/components/groups/groups.component.html @@ -11,12 +11,13 @@ - apartment - {{ unidad.nombre }} + [ngClass]="{'selected-item': unidad === selectedUnidad, 'clickable-item': true}"> + + apartment + {{ unidad.nombre }} + - edit + edit @@ -28,28 +29,39 @@ {{ breadcrumb.join(' > ') }} - - - apartment - - - - - - - - - - - - - - {{ child.name || child.nombre }} - - edit - delete - + +
+ + + apartment + + + + + + + + + + + + + + {{ child.name || child.nombre }} + + + edit + delete + +
@@ -62,6 +74,7 @@

Tipo: {{ selectedDetail.type }}

ID: {{ selectedDetail.id }}

UUID: {{ selectedDetail.uuid }}

+

Selecciona un elemento para ver sus detalles.

@@ -69,6 +82,4 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/ogWebconsole/src/app/components/groups/groups.component.ts b/ogWebconsole/src/app/components/groups/groups.component.ts index ad342f2..7f3e840 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.ts +++ b/ogWebconsole/src/app/components/groups/groups.component.ts @@ -16,17 +16,14 @@ import { EditClientComponent } from './clients/edit-client/edit-client.component export class GroupsComponent implements OnInit { unidadesOrganizativas: UnidadOrganizativa[] = []; selectedUnidad: UnidadOrganizativa | null = null; - selectedDetail: any | null = null; + selectedDetail: any | null = null; // Nueva variable para el detalle del elemento seleccionado children: any[] = []; breadcrumb: string[] = []; + clientsData: any[] = []; // Nueva variable para almacenar los datos de clients constructor(private dataService: DataService, public dialog: MatDialog) {} ngOnInit(): void { - this.fetchUnidadesOrganizativas(); - } - - fetchUnidadesOrganizativas(): void { this.dataService.getUnidadesOrganizativas().subscribe( data => this.unidadesOrganizativas = data, error => console.error('Error fetching unidades organizativas', error) @@ -35,14 +32,14 @@ export class GroupsComponent implements OnInit { onSelectUnidad(unidad: UnidadOrganizativa): void { this.selectedUnidad = unidad; - this.selectedDetail = unidad; + this.selectedDetail = unidad; // Mostrar detalles de la unidad seleccionada this.breadcrumb = [unidad.nombre]; this.loadChildrenAndClients(unidad.uuid); } onSelectChild(child: any): void { - this.selectedDetail = child; - if (child.type !== 'client' && child.uuid) { + this.selectedDetail = child; // Mostrar detalles del niño seleccionado + if (child.type !== 'client' && child.uuid && child.id) { this.breadcrumb.push(child.name || child.nombre); this.loadChildrenAndClients(child.uuid); } @@ -53,55 +50,93 @@ export class GroupsComponent implements OnInit { childrenData => { this.dataService.getClients(uuid).subscribe( clientsData => { - this.children = [...childrenData, ...clientsData]; - if (this.children.length === 0) { - this.breadcrumb.pop(); + this.clientsData = clientsData; // Almacenar clientsData para pasarlo al componente hijo + const newChildren = [...childrenData, ...clientsData]; + + if (newChildren.length > 0) { + this.children = newChildren; + } else { + this.children = []; // Limpiar card2 cuando no hay elementos + this.breadcrumb.pop(); // Revertir breadcrumb solo si no hay elementos + + // Si deseas que la unidad organizativa se limpie completamente, descomenta la línea siguiente: + // this.selectedUnidad = null; } }, error => { console.error('Error fetching clients', error); - this.children = []; + this.clientsData = []; // Limpiar clientsData en caso de error + this.children = []; // Limpiar card2 en caso de error } ); }, error => { console.error('Error fetching children', error); - this.children = []; + this.children = []; // Limpiar card2 en caso de error } ); } - + addOU(): void { - this.dialog.open(CreateOrganizationalUnitComponent).afterClosed().subscribe(() => { - this.fetchUnidadesOrganizativas(); + const dialogRef = this.dialog.open(CreateOrganizationalUnitComponent); + + // Subscribirse al evento unitAdded del componente de creación después de cerrar el diálogo + dialogRef.afterClosed().subscribe(() => { + // Aquí puedes actualizar las cards o hacer cualquier otra acción necesaria después de añadir una unidad organizativa + this.dataService.getUnidadesOrganizativas().subscribe( + data => this.unidadesOrganizativas = data, + error => console.error('Error fetching unidades organizativas', error) + ); }); } addClient(): void { - this.dialog.open(CreateClientComponent).afterClosed().subscribe(() => { - this.fetchUnidadesOrganizativas(); + const dialogRef = this.dialog.open(CreateClientComponent); + + // Subscribirse al evento unitAdded del componente de creación después de cerrar el diálogo + dialogRef.afterClosed().subscribe(() => { + // Aquí puedes actualizar las cards o hacer cualquier otra acción necesaria después de añadir una unidad organizativa + this.dataService.getUnidadesOrganizativas().subscribe( + data => this.unidadesOrganizativas = data, + error => console.error('Error fetching unidades organizativas', error) + ); }); } getIcon(type: string): string { - const iconMap: { [key: string]: string } = { - 'organizational-unit': 'apartment', - 'classroom-group': 'classrooms-group-icon', - 'classroom': 'classroom-icon', - 'client': 'client-icon', - 'clients-group': 'clients-group-icon' - }; - return iconMap[type] || ''; + switch(type) { + case 'organizational-unit': + return 'apartment'; + case 'classroom-group': + return 'classrooms-group-icon'; + case 'classroom': + return 'classroom-icon'; + case 'client': + return 'client-icon'; + case 'clients-group': + return 'clients-group-icon'; + default: + return ''; + } } - onDeleteClick(uuid: string, name: string, type: string, event: MouseEvent): void { - event.stopPropagation(); - this.dialog.open(DeleteModalComponent, { width: '250px', data: { name } }).afterClosed().subscribe(result => { + onDeleteClick(uuid: string, name: string, type: string): void { + const dialogRef = this.dialog.open(DeleteModalComponent, { + width: '250px', + data: { name } + }); + + dialogRef.afterClosed().subscribe(result => { if (result) { this.dataService.deleteElement(uuid, type).subscribe( () => { this.loadChildrenAndClients(this.selectedUnidad?.uuid || ''); - this.fetchUnidadesOrganizativas(); + + this.dataService.getUnidadesOrganizativas().subscribe( + data => this.unidadesOrganizativas = data, + error => console.error('Error fetching unidades organizativas', error) + ); + }, error => console.error('Error deleting element', error) ); @@ -109,11 +144,11 @@ export class GroupsComponent implements OnInit { }); } - onEditClick(type: string, uuid: string, event: MouseEvent): void { - event.stopPropagation(); - const dialogComponent = type === 'client' ? EditClientComponent : EditOrganizationalUnitComponent; - this.dialog.open(dialogComponent as any); // Usando type assertion aquí + onEditClick(type: any, uuid: string): void { + if (type != "client") { + const dialogRef = this.dialog.open(EditOrganizationalUnitComponent); + } else { + const dialogRef = this.dialog.open(EditClientComponent); + } } - - -} +} \ No newline at end of file -- 2.40.1 From 151a3223c263ba046f8b88aa1d5e43f7086d5141 Mon Sep 17 00:00:00 2001 From: apuente Date: Wed, 3 Jul 2024 23:49:04 +0200 Subject: [PATCH 19/36] =?UTF-8?q?Visualizaci=C3=B3n=20de=20aulas=20y=20cli?= =?UTF-8?q?entes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../classroom-view.component.css | 47 +++++++++++++++ .../classroom-view.component.html | 14 +++++ .../classroom-view.component.spec.ts | 23 ++++++++ .../classroom-view.component.ts | 57 +++++++++++++++++++ 4 files changed, 141 insertions(+) create mode 100644 ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css create mode 100644 ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html create mode 100644 ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.spec.ts create mode 100644 ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css new file mode 100644 index 0000000..aaf3365 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css @@ -0,0 +1,47 @@ +/* src/app/classroom-view/classroom-view.component.css */ + +.classroom { + display: flex; + flex-direction: column; + align-items: center; +} + +.classroom-group { + margin: 10px; + width: 800px; + background-color: #fafafa; +} + +.organizational-unit-name { + font-weight: bold; + font-size: 18px; + margin-bottom: 10px; +} + +.client-row { + display: flex; + justify-content: center; + flex-wrap: wrap; + gap: 10px; +} + +.client-container { + margin: 5px; +} + +.client-box { + width: 100px; + height: 100px; + background-color: lightblue; + display: flex; + justify-content: center; + align-items: center; + border: 1px solid #000; + box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1); + border-radius: 5px; + cursor: pointer; +} + +.client-box p { + margin: 0; +} diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html new file mode 100644 index 0000000..cf19f6e --- /dev/null +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html @@ -0,0 +1,14 @@ +
+
+ +

{{ group.organizationalUnitName }}

+
+
+
+

{{ client.name }}

+
+
+
+
+
+
diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.spec.ts b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.spec.ts new file mode 100644 index 0000000..ce539a8 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ClassroomViewComponent } from './classroom-view.component'; + +describe('ClassroomViewComponent', () => { + let component: ClassroomViewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ClassroomViewComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ClassroomViewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts new file mode 100644 index 0000000..48f799b --- /dev/null +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts @@ -0,0 +1,57 @@ +// src/app/classroom-view/classroom-view.component.ts + +import { Component, Input, OnInit } from '@angular/core'; + +interface GroupedClients { + organizationalUnitName: string; + clientRows: any[][]; +} + +@Component({ + selector: 'app-classroom-view', + templateUrl: './classroom-view.component.html', + styleUrls: ['./classroom-view.component.css'] +}) +export class ClassroomViewComponent implements OnInit { + @Input() clients: any[] = []; + @Input() pcInTable: number = 3; + groupedClients: GroupedClients[] = []; + + constructor() {} + + ngOnInit(): void { + this.groupClientsByOrganizationalUnit(); + } + + ngOnChanges(): void { + this.groupClientsByOrganizationalUnit(); + } + + groupClientsByOrganizationalUnit(): void { + const grouped = this.clients.reduce((acc, client) => { + const ouName = client.organizationalUnit.name; + if (!acc[ouName]) { + acc[ouName] = []; + } + acc[ouName].push(client); + return acc; + }, {}); + + this.groupedClients = Object.keys(grouped).map(ouName => ({ + organizationalUnitName: ouName, + clientRows: this.chunkArray(grouped[ouName], this.pcInTable) + })); + } + + chunkArray(arr: any[], chunkSize: number): any[][] { + const chunks = []; + for (let i = 0; i < arr.length; i += chunkSize) { + chunks.push(arr.slice(i, i + chunkSize)); + } + return chunks; + } + + handleClientClick(client: any): void { + console.log('Client clicked:', client); + } +} -- 2.40.1 From af5e2b6a124bcf91e26f4e06eb5f3c05d64ae828 Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Thu, 4 Jul 2024 15:27:27 +0200 Subject: [PATCH 20/36] Added new UX. Sidebar, and main styles --- ogWebconsole/.gitignore | 1 + ogWebconsole/angular.json | 4 ++ ogWebconsole/src/app/app.component.css | 7 ++ ogWebconsole/src/app/app.module.ts | 42 ++++++------ .../layout/header/header.component.css | 10 ++- .../layout/header/header.component.html | 24 +++---- .../main-layout/main-layout.component.css | 15 +++-- .../main-layout/main-layout.component.html | 13 ++-- .../main-layout/main-layout.component.ts | 2 +- .../layout/sidebar/sidebar.component.css | 58 +++++++++------- .../layout/sidebar/sidebar.component.html | 66 ++++++++++++++++--- .../layout/sidebar/sidebar.component.spec.ts | 2 +- .../layout/sidebar/sidebar.component.ts | 2 +- package-lock.json | 6 ++ 14 files changed, 166 insertions(+), 86 deletions(-) create mode 100644 package-lock.json diff --git a/ogWebconsole/.gitignore b/ogWebconsole/.gitignore index 0711527..03923dd 100644 --- a/ogWebconsole/.gitignore +++ b/ogWebconsole/.gitignore @@ -40,3 +40,4 @@ testem.log # System files .DS_Store Thumbs.db + diff --git a/ogWebconsole/angular.json b/ogWebconsole/angular.json index e3dd628..9ffbc13 100644 --- a/ogWebconsole/angular.json +++ b/ogWebconsole/angular.json @@ -104,6 +104,10 @@ } }, "cli": { +<<<<<<< Updated upstream "analytics": "95fac95c-8936-41a8-8c9c-1fae82fe6912" +======= + "analytics": "ba7c0825-8034-43ff-9c60-83dac232db7e" +>>>>>>> Stashed changes } } diff --git a/ogWebconsole/src/app/app.component.css b/ogWebconsole/src/app/app.component.css index e69de29..aac26c0 100644 --- a/ogWebconsole/src/app/app.component.css +++ b/ogWebconsole/src/app/app.component.css @@ -0,0 +1,7 @@ +.sidenav-container { + height: 100%; +} + +.content { + padding: 16px; +} diff --git a/ogWebconsole/src/app/app.module.ts b/ogWebconsole/src/app/app.module.ts index 2009f5a..dc823f7 100644 --- a/ogWebconsole/src/app/app.module.ts +++ b/ogWebconsole/src/app/app.module.ts @@ -43,7 +43,7 @@ import { DeleteModalComponent } from './components/groups/delete-modal/delete-mo import { EditOrganizationalUnitComponent } from './components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component'; import { EditClientComponent } from './components/groups/clients/edit-client/edit-client.component'; import {MatProgressSpinner} from "@angular/material/progress-spinner"; - +import {MatMenu, MatMenuItem, MatMenuTrigger} from "@angular/material/menu"; @NgModule({ declarations: [ AppComponent, @@ -70,26 +70,26 @@ import {MatProgressSpinner} from "@angular/material/progress-spinner"; EditClientComponent ], bootstrap: [AppComponent], - imports: [BrowserModule, - AppRoutingModule, - FormsModule, - ReactiveFormsModule, - MatToolbarModule, - MatIconModule, - MatButtonModule, - MatSidenavModule, - BrowserAnimationsModule, - MatCardModule, - MatCheckboxModule, - MatFormFieldModule, - MatInputModule, - MatListModule, - MatTableModule, - MatDialogModule, - MatSelectModule, - MatDividerModule, - MatStepperModule, - MatSlideToggleModule, MatProgressSpinner], + imports: [BrowserModule, + AppRoutingModule, + FormsModule, + ReactiveFormsModule, + MatToolbarModule, + MatIconModule, + MatButtonModule, + MatSidenavModule, + BrowserAnimationsModule, + MatCardModule, + MatCheckboxModule, + MatFormFieldModule, + MatInputModule, + MatListModule, + MatTableModule, + MatDialogModule, + MatSelectModule, + MatDividerModule, + MatStepperModule, + MatSlideToggleModule, MatMenu, MatMenuTrigger, MatMenuItem], providers: [ { provide: HTTP_INTERCEPTORS, diff --git a/ogWebconsole/src/app/components/layout/header/header.component.css b/ogWebconsole/src/app/components/layout/header/header.component.css index d5ba1ce..6c84df7 100644 --- a/ogWebconsole/src/app/components/layout/header/header.component.css +++ b/ogWebconsole/src/app/components/layout/header/header.component.css @@ -1,15 +1,13 @@ mat-toolbar { - display: flex; - justify-content: space-between; - padding: 10px; height: 50px; - box-shadow: 10px 0 10px -5px rgba(0, 0, 0, 0.5); + background-color: #3f51b5; + color: white; } .navbar-button-row { display: flex; - justify-content: space-around; + justify-content: end; flex-grow: 1; } @@ -20,4 +18,4 @@ button[mat-flat-button] { .navbar-tittle{ padding-left: 20px; cursor: pointer; -} \ No newline at end of file +} diff --git a/ogWebconsole/src/app/components/layout/header/header.component.html b/ogWebconsole/src/app/components/layout/header/header.component.html index 737223f..6a54ed5 100644 --- a/ogWebconsole/src/app/components/layout/header/header.component.html +++ b/ogWebconsole/src/app/components/layout/header/header.component.html @@ -1,19 +1,11 @@ - Opengnsys webconsole - - \ No newline at end of file + + + + + + + + diff --git a/ogWebconsole/src/app/components/layout/main-layout/main-layout.component.css b/ogWebconsole/src/app/components/layout/main-layout/main-layout.component.css index 09b9d86..0b7bd3a 100644 --- a/ogWebconsole/src/app/components/layout/main-layout/main-layout.component.css +++ b/ogWebconsole/src/app/components/layout/main-layout/main-layout.component.css @@ -1,6 +1,11 @@ -.content-wrapper{ - display: block; - grid-area: content; - margin: 20px; -} \ No newline at end of file +.container { + width: auto; + height: 100%; +} + +.content { + margin: 10px; + padding: 10px; +} + diff --git a/ogWebconsole/src/app/components/layout/main-layout/main-layout.component.html b/ogWebconsole/src/app/components/layout/main-layout/main-layout.component.html index 1373e77..f5e4d99 100644 --- a/ogWebconsole/src/app/components/layout/main-layout/main-layout.component.html +++ b/ogWebconsole/src/app/components/layout/main-layout/main-layout.component.html @@ -1,6 +1,11 @@ -
- -
+ + + + + + + -
\ No newline at end of file + + diff --git a/ogWebconsole/src/app/components/layout/main-layout/main-layout.component.ts b/ogWebconsole/src/app/components/layout/main-layout/main-layout.component.ts index 1365866..8017e31 100644 --- a/ogWebconsole/src/app/components/layout/main-layout/main-layout.component.ts +++ b/ogWebconsole/src/app/components/layout/main-layout/main-layout.component.ts @@ -2,7 +2,7 @@ import { Component } from '@angular/core'; @Component({ selector: 'app-main-layout', templateUrl: './main-layout.component.html', - styleUrl: './main-layout.component.css' + styleUrl: './main-layout.component.css', }) export class MainLayoutComponent { isSidebarVisible: boolean = false; diff --git a/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.css b/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.css index d68e53c..60409d3 100644 --- a/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.css +++ b/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.css @@ -1,25 +1,37 @@ -.sidebar { - width: 250px; - position: fixed; - top: 50px; - left: -260px; - height: 100%; - background-color: rgb(245, 245, 245); - transition: left 0.3s ease-in-out; - box-shadow: 10px 0 10px -5px rgba(0, 0, 0, 0.5); - z-index: 99999999999; - } - - .sidebar.visible { - left: 0; - } - - .sidebar-content{ - margin: 20px; - } - - button { - margin-bottom: 10px; +mat-nav-list { + width: 250px; } - +mat-list-item { + cursor: pointer; + display: flex; + align-items: center; +} + +.entry{ + display: flex; + align-items: center; + gap: 1rem; + padding:0.75rem; +} + +mat-icon { + margin-right: 8px; +} + +.user-logged{ + align-items: center; + gap: 2rem; + padding:1.5rem; + font-size: x-large; +} + +.sidebar-content { + display: flex; + flex-direction: column; + height: 100%; +} + +.admin-link { + margin-top: auto; +} diff --git a/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.html b/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.html index a4a5b88..3c47833 100644 --- a/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.html +++ b/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.html @@ -1,8 +1,58 @@ - - \ No newline at end of file + + + + {{username}} + + + + + + + + apartment + Grupos + + + + + chevron_right + Acciones + + + + + desktop_windows + Imágenes + + + + + settings_input_component + Componentes + + + + + warehouse + Repositorios + + + + + list + Menús + + + + + search + Buscar + + + + + calendar_month + Calendarios + + + diff --git a/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.spec.ts b/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.spec.ts index 85e49bd..5445f3c 100644 --- a/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.spec.ts +++ b/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.spec.ts @@ -11,7 +11,7 @@ describe('SidebarComponent', () => { imports: [SidebarComponent] }) .compileComponents(); - + fixture = TestBed.createComponent(SidebarComponent); component = fixture.componentInstance; fixture.detectChanges(); diff --git a/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.ts b/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.ts index ad83d71..9f6c4b1 100644 --- a/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.ts +++ b/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.ts @@ -38,4 +38,4 @@ export class SidebarComponent { console.log("User edited successfully!") }); */ } -} \ No newline at end of file +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d8af095 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "oggui", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} -- 2.40.1 From 17ed7adaf172f40763950ef2c6eb4ed65c4beecc Mon Sep 17 00:00:00 2001 From: apuente Date: Thu, 4 Jul 2024 15:51:33 +0200 Subject: [PATCH 21/36] =?UTF-8?q?Visualizaci=C3=B3n=20de=20aulas=20y=20cli?= =?UTF-8?q?entes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ogWebconsole/src/app/components/groups/groups.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html index d61929e..2e5ef0b 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.html +++ b/ogWebconsole/src/app/components/groups/groups.component.html @@ -82,4 +82,4 @@
- \ No newline at end of file + \ No newline at end of file -- 2.40.1 From e8dbd3d5f8695e314146b4bf65b8701eea68a8f3 Mon Sep 17 00:00:00 2001 From: apuente Date: Thu, 4 Jul 2024 17:03:46 +0200 Subject: [PATCH 22/36] Merge fix --- .../classroom-view.component.html | 18 ++++++++---------- .../components/groups/groups.component.html | 6 +++--- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html index cf19f6e..4707c19 100644 --- a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html @@ -1,14 +1,12 @@
-
- -

{{ group.organizationalUnitName }}

-
-
-
-

{{ client.name }}

-
+ +

Disposición {{ group.organizationalUnitName }}

+
+
+
+

{{ client.name }}

- -
+
+
diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html index 8ad719a..f0baca6 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.html +++ b/ogWebconsole/src/app/components/groups/groups.component.html @@ -76,7 +76,7 @@
- + Detalles del elemento

Nombre: {{ selectedDetail.name || selectedDetail.nombre }}

@@ -89,6 +89,6 @@

Selecciona un elemento para ver sus detalles.

-
- \ No newline at end of file + +
\ No newline at end of file -- 2.40.1 From c2795eda48fe758ee79e5fc8ff4ec5f56b5c8be8 Mon Sep 17 00:00:00 2001 From: apuente Date: Fri, 5 Jul 2024 09:53:35 +0200 Subject: [PATCH 23/36] Group Cards flex width --- .../classroom-view.component.css | 3 +- .../components/groups/groups.component.css | 37 ++++++++------ .../components/groups/groups.component.html | 48 ++++++------------- 3 files changed, 39 insertions(+), 49 deletions(-) diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css index aaf3365..40b80f1 100644 --- a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css @@ -7,8 +7,7 @@ } .classroom-group { - margin: 10px; - width: 800px; + flex: 1 1 25%; background-color: #fafafa; } diff --git a/ogWebconsole/src/app/components/groups/groups.component.css b/ogWebconsole/src/app/components/groups/groups.component.css index 920d648..444afe7 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.css +++ b/ogWebconsole/src/app/components/groups/groups.component.css @@ -3,22 +3,26 @@ flex-wrap: wrap; } -mat-card { +.card { + flex-grow: 1; margin: 10px; } +.unidad-card, .elements-card { + flex: 1 1 45%; + background-color: #fafafa; +} + +.details-card, .classroom-view { + flex: 1 1 25%; +} + mat-card-title { display: flex; justify-content: space-between; margin: 10px; } -.elements-card{ - margin: 10px; - width: 800px; - background-color: #fafafa; -} - .title-with-breadcrumb { display: flex; flex-direction: column; @@ -32,7 +36,7 @@ mat-card-subtitle { mat-card-subtitle a { cursor: pointer; text-decoration: underline; - color: #1976d2; /* Color azul típico de enlaces */ + color: #1976d2; } mat-card-subtitle a:hover { @@ -49,6 +53,11 @@ button { margin-bottom: 20px; } +.item-content { + display: flex; + width: 100%; +} + .clickable-item:hover { cursor: pointer; } @@ -58,16 +67,16 @@ button { } .actions { - margin-left: auto; + display: flex; + margin-left: auto; } .actions mat-icon { - cursor: pointer; - margin-left: 48px; - color: #757575; + cursor: pointer; + margin-left: 16px; + color: #757575; } .actions mat-icon:hover { color: #212121; -} - +} \ No newline at end of file diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html index f0baca6..d97103a 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.html +++ b/ogWebconsole/src/app/components/groups/groups.component.html @@ -6,25 +6,27 @@

Grupos

- + Unidad organizativa - - apartment - {{ unidad.nombre }} - - - edit - +
+ + apartment + {{ unidad.nombre }} + + + edit + +
- +
Elementos @@ -39,30 +41,10 @@ -
+
- apartment - - - - - - - - - - - - + {{ child.name || child.nombre }} @@ -76,7 +58,7 @@ - + Detalles del elemento

Nombre: {{ selectedDetail.name || selectedDetail.nombre }}

@@ -90,5 +72,5 @@
- +
\ No newline at end of file -- 2.40.1 From a477e3fca86aba116f6781dfaa6d2fc362010716 Mon Sep 17 00:00:00 2001 From: apuente Date: Fri, 5 Jul 2024 10:55:53 +0200 Subject: [PATCH 24/36] Crear clasroom info en el stepper --- .../create-organizational-unit.component.css | 4 ++ .../create-organizational-unit.component.html | 29 ++++++++++- .../create-organizational-unit.component.ts | 52 ++++++++++++++----- 3 files changed, 71 insertions(+), 14 deletions(-) diff --git a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.css b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.css index 8293a6b..f8e9c6c 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.css +++ b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.css @@ -36,3 +36,7 @@ button { .mat-slide-toggle { margin-top: 20px; } + +mat-slide-toggle{ + margin-left: 10px; +} \ No newline at end of file diff --git a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html index e8aee32..2c4fafa 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html +++ b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html @@ -32,7 +32,32 @@ - + + +
+ Información del Aula + + Ubicación + + + Proyector + Pizarra + + Aforo + + + + Foto (URL) (string de prueba) + + +
+ + +
+
+
+ +
Información Adicional @@ -47,7 +72,7 @@
- +
Configuración de Red diff --git a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts index 43eb8eb..3584ffa 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts +++ b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts @@ -13,15 +13,16 @@ export class CreateOrganizationalUnitComponent implements OnInit { generalFormGroup: FormGroup; additionalInfoFormGroup: FormGroup; networkSettingsFormGroup: FormGroup; + classroomInfoFormGroup: FormGroup; types: string[] = ['organizational-unit', 'classrooms-group', 'classroom', 'clients-group']; - parentUnits: any[] = []; // Array to store parent units fetched from API + parentUnits: any[] = []; - @Output() unitAdded = new EventEmitter(); // Event emitter to notify parent component about unit addition + @Output() unitAdded = new EventEmitter(); constructor( private _formBuilder: FormBuilder, private dialogRef: MatDialogRef, - private http: HttpClient // Inject HttpClient for HTTP requests + private http: HttpClient ) { this.generalFormGroup = this._formBuilder.group({ name: ['', Validators.required], @@ -48,10 +49,17 @@ export class CreateOrganizationalUnitComponent implements OnInit { hardwareProfile: ['', Validators.pattern('https?://.+')], validation: [false] }); + this.classroomInfoFormGroup = this._formBuilder.group({ + location: [''], + projector: [false], + board: [false], + capacity: [0, Validators.min(0)], + photo: ['', Validators.pattern('https?://.+')] + }); } ngOnInit() { - this.loadParentUnits(); // Load parent units when component initializes + this.loadParentUnits(); } loadParentUnits() { @@ -68,18 +76,41 @@ export class CreateOrganizationalUnitComponent implements OnInit { } onSubmit() { - if (this.generalFormGroup.valid && this.additionalInfoFormGroup.valid && this.networkSettingsFormGroup.valid) { + if (this.generalFormGroup.valid && this.additionalInfoFormGroup.valid && this.networkSettingsFormGroup.valid && (this.generalFormGroup.value.type !== 'classroom' || this.classroomInfoFormGroup.valid)) { const parentValue = this.generalFormGroup.value.parent; - const formData = { + const formData: any = { name: this.generalFormGroup.value.name, parent: parentValue || null, description: this.generalFormGroup.value.description, comments: this.additionalInfoFormGroup.value.comments, - type: this.generalFormGroup.value.type + type: this.generalFormGroup.value.type, + networkSettings: { + proxy: this.networkSettingsFormGroup.value.proxy, + dns: this.networkSettingsFormGroup.value.dns, + netmask: this.networkSettingsFormGroup.value.netmask, + router: this.networkSettingsFormGroup.value.router, + ntp: this.networkSettingsFormGroup.value.ntp, + p2pMode: this.networkSettingsFormGroup.value.p2pMode, + p2pTime: this.networkSettingsFormGroup.value.p2pTime, + mcastIp: this.networkSettingsFormGroup.value.mcastIp, + mcastSpeed: this.networkSettingsFormGroup.value.mcastSpeed, + mcastPort: this.networkSettingsFormGroup.value.mcastPort, + mcastMode: this.networkSettingsFormGroup.value.mcastMode, + menu: this.networkSettingsFormGroup.value.menu, + hardwareProfile: this.networkSettingsFormGroup.value.hardwareProfile, + validation: this.networkSettingsFormGroup.value.validation + } }; - // Realizar la solicitud POST + if (this.generalFormGroup.value.type === 'classroom') { + formData.location = this.classroomInfoFormGroup.value.location; + formData.projector = this.classroomInfoFormGroup.value.projector; + formData.board = this.classroomInfoFormGroup.value.board; + formData.capacity = this.classroomInfoFormGroup.value.capacity; + formData.photo = this.classroomInfoFormGroup.value.photo; + } + console.log('POST data:', formData); const postUrl = 'http://127.0.0.1:8080/organizational-units'; const headers = new HttpHeaders({ 'Content-Type': 'application/json' }); @@ -87,19 +118,16 @@ export class CreateOrganizationalUnitComponent implements OnInit { this.http.post(postUrl, formData, { headers }).subscribe( response => { console.log('POST successful:', response); - // Emitir evento para notificar que se ha añadido una nueva unidad this.unitAdded.emit(); - this.dialogRef.close(); // Cerrar el diálogo después de añadir + this.dialogRef.close(); }, error => { console.error('Error al realizar POST:', error); - // Manejar el error según sea necesario } ); } } - onNoClick(): void { this.dialogRef.close(); } -- 2.40.1 From 1a9a455c1e98c970bcac3d79c4c2f3dfad1dfdda Mon Sep 17 00:00:00 2001 From: apuente Date: Fri, 5 Jul 2024 12:14:53 +0200 Subject: [PATCH 25/36] Minnor fix --- .../groups/classroom-view/classroom-view.component.css | 2 -- .../groups/classroom-view/classroom-view.component.html | 2 +- ogWebconsole/src/app/components/groups/groups.component.css | 2 +- .../src/app/components/layout/sidebar/sidebar.component.css | 4 ++-- .../src/app/components/layout/sidebar/sidebar.component.html | 2 +- 5 files changed, 5 insertions(+), 7 deletions(-) diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css index 40b80f1..b701ae8 100644 --- a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css @@ -1,5 +1,3 @@ -/* src/app/classroom-view/classroom-view.component.css */ - .classroom { display: flex; flex-direction: column; diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html index 4707c19..382e3b1 100644 --- a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html @@ -9,4 +9,4 @@
-
+ \ No newline at end of file diff --git a/ogWebconsole/src/app/components/groups/groups.component.css b/ogWebconsole/src/app/components/groups/groups.component.css index 444afe7..c5ff72f 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.css +++ b/ogWebconsole/src/app/components/groups/groups.component.css @@ -36,7 +36,7 @@ mat-card-subtitle { mat-card-subtitle a { cursor: pointer; text-decoration: underline; - color: #1976d2; + color: #929292; } mat-card-subtitle a:hover { diff --git a/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.css b/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.css index 60409d3..f20f424 100644 --- a/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.css +++ b/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.css @@ -22,8 +22,8 @@ mat-icon { .user-logged{ align-items: center; gap: 2rem; - padding:1.5rem; - font-size: x-large; + padding:1rem; + font-size: medium; } .sidebar-content { diff --git a/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.html b/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.html index 3c47833..b3658ea 100644 --- a/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.html +++ b/ogWebconsole/src/app/components/layout/sidebar/sidebar.component.html @@ -1,7 +1,7 @@ - {{username}} + Bienvenido {{username}} -- 2.40.1 From 27063fc1fbdac1fd3a50425b328753d480f3898f Mon Sep 17 00:00:00 2001 From: apuente Date: Fri, 5 Jul 2024 12:41:31 +0200 Subject: [PATCH 26/36] Create UO playload fix --- .../app/components/groups/groups.component.ts | 4 -- .../create-organizational-unit.component.ts | 56 +++++++++---------- 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/ogWebconsole/src/app/components/groups/groups.component.ts b/ogWebconsole/src/app/components/groups/groups.component.ts index adc928c..ce0b6f5 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.ts +++ b/ogWebconsole/src/app/components/groups/groups.component.ts @@ -96,10 +96,7 @@ constructor(private dataService: DataService, public dialog: MatDialog) {} addOU(): void { const dialogRef = this.dialog.open(CreateOrganizationalUnitComponent); - - // Subscribirse al evento unitAdded del componente de creación después de cerrar el diálogo dialogRef.afterClosed().subscribe(() => { - // Aquí puedes actualizar las cards o hacer cualquier otra acción necesaria después de añadir una unidad organizativa this.dataService.getUnidadesOrganizativas().subscribe( data => this.unidadesOrganizativas = data, error => console.error('Error fetching unidades organizativas', error) @@ -112,7 +109,6 @@ constructor(private dataService: DataService, public dialog: MatDialog) {} // Subscribirse al evento unitAdded del componente de creación después de cerrar el diálogo dialogRef.afterClosed().subscribe(() => { - // Aquí puedes actualizar las cards o hacer cualquier otra acción necesaria después de añadir una unidad organizativa this.dataService.getUnidadesOrganizativas().subscribe( data => this.unidadesOrganizativas = data, error => console.error('Error fetching unidades organizativas', error) diff --git a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts index 3584ffa..43229eb 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts +++ b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts @@ -75,42 +75,42 @@ export class CreateOrganizationalUnitComponent implements OnInit { ); } + private cleanFormValues(formGroup: FormGroup): any { + const cleanedValues: any = {}; + Object.keys(formGroup.controls).forEach(key => { + const value = formGroup.get(key)?.value; + if (value !== '' && value !== 0) { + cleanedValues[key] = value; + } + }); + return cleanedValues; + } + onSubmit() { if (this.generalFormGroup.valid && this.additionalInfoFormGroup.valid && this.networkSettingsFormGroup.valid && (this.generalFormGroup.value.type !== 'classroom' || this.classroomInfoFormGroup.valid)) { - const parentValue = this.generalFormGroup.value.parent; + const generalFormValues = this.cleanFormValues(this.generalFormGroup); + const additionalInfoFormValues = this.cleanFormValues(this.additionalInfoFormGroup); + const networkSettingsFormValues = this.cleanFormValues(this.networkSettingsFormGroup); + const classroomInfoFormValues = this.cleanFormValues(this.classroomInfoFormGroup); const formData: any = { - name: this.generalFormGroup.value.name, - parent: parentValue || null, - description: this.generalFormGroup.value.description, - comments: this.additionalInfoFormGroup.value.comments, - type: this.generalFormGroup.value.type, - networkSettings: { - proxy: this.networkSettingsFormGroup.value.proxy, - dns: this.networkSettingsFormGroup.value.dns, - netmask: this.networkSettingsFormGroup.value.netmask, - router: this.networkSettingsFormGroup.value.router, - ntp: this.networkSettingsFormGroup.value.ntp, - p2pMode: this.networkSettingsFormGroup.value.p2pMode, - p2pTime: this.networkSettingsFormGroup.value.p2pTime, - mcastIp: this.networkSettingsFormGroup.value.mcastIp, - mcastSpeed: this.networkSettingsFormGroup.value.mcastSpeed, - mcastPort: this.networkSettingsFormGroup.value.mcastPort, - mcastMode: this.networkSettingsFormGroup.value.mcastMode, - menu: this.networkSettingsFormGroup.value.menu, - hardwareProfile: this.networkSettingsFormGroup.value.hardwareProfile, - validation: this.networkSettingsFormGroup.value.validation - } + ...generalFormValues, + comments: additionalInfoFormValues.comments, + networkSettings: { ...networkSettingsFormValues } }; if (this.generalFormGroup.value.type === 'classroom') { - formData.location = this.classroomInfoFormGroup.value.location; - formData.projector = this.classroomInfoFormGroup.value.projector; - formData.board = this.classroomInfoFormGroup.value.board; - formData.capacity = this.classroomInfoFormGroup.value.capacity; - formData.photo = this.classroomInfoFormGroup.value.photo; + formData.location = classroomInfoFormValues.location; + formData.projector = classroomInfoFormValues.projector; + formData.board = classroomInfoFormValues.board; + if (classroomInfoFormValues.capacity !== undefined) { + formData.capacity = classroomInfoFormValues.capacity; + } + if (classroomInfoFormValues.photo !== undefined) { + formData.photo = classroomInfoFormValues.photo; + } } - + console.log('POST data:', formData); const postUrl = 'http://127.0.0.1:8080/organizational-units'; const headers = new HttpHeaders({ 'Content-Type': 'application/json' }); -- 2.40.1 From 876ab85a8e9db5c4250db807b7cfafbe1024c493 Mon Sep 17 00:00:00 2001 From: apuente Date: Fri, 5 Jul 2024 13:46:57 +0200 Subject: [PATCH 27/36] Elements card scroll --- ogWebconsole/src/app/components/groups/groups.component.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ogWebconsole/src/app/components/groups/groups.component.css b/ogWebconsole/src/app/components/groups/groups.component.css index c5ff72f..8696ff5 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.css +++ b/ogWebconsole/src/app/components/groups/groups.component.css @@ -11,6 +11,8 @@ .unidad-card, .elements-card { flex: 1 1 45%; background-color: #fafafa; + max-height: 300px; + overflow-y: auto; } .details-card, .classroom-view { -- 2.40.1 From a1e2b7aec12e2af5fa1314015e1424dcaddc39bf Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Wed, 10 Jul 2024 16:13:29 +0200 Subject: [PATCH 28/36] refs #486. Some several improvements. Change in UX, and added new client-classroom view --- ogWebconsole/src/app/app.component.css | 1 + ogWebconsole/src/app/app.module.ts | 16 +- .../classroom-view.component.css | 29 ++-- .../classroom-view.component.html | 20 ++- .../classroom-view.component.ts | 13 +- .../client-view/client-view.component.css | 41 +++++ .../client-view/client-view.component.html | 40 +++++ .../client-view/client-view.component.spec.ts | 23 +++ .../client-view/client-view.component.ts | 14 ++ .../create-client/create-client.component.css | 85 +++++----- .../create-client.component.html | 19 ++- .../create-client/create-client.component.ts | 58 +++++-- .../edit-client/edit-client.component.css | 75 +++++---- .../edit-client/edit-client.component.html | 36 ++++- .../edit-client/edit-client.component.ts | 39 +++-- .../src/app/components/groups/data.service.ts | 36 +++-- .../delete-groups-modal.component.css | 0 .../delete-groups-modal.component.spec.ts | 23 +++ .../delete-groups-modal.component.ts | 30 ++++ .../components/groups/groups.component.css | 32 +++- .../components/groups/groups.component.html | 94 ++++++----- .../app/components/groups/groups.component.ts | 149 ++++++++++-------- .../src/app/components/groups/model.ts | 8 +- .../create-organizational-unit.component.html | 12 +- .../create-organizational-unit.component.ts | 35 ++-- .../edit-organizational-unit.component.ts | 30 ++-- .../layout/header/header.component.css | 8 +- .../layout/header/header.component.html | 3 +- .../layout/header/header.component.ts | 36 ++++- .../main-layout/main-layout.component.css | 5 +- .../main-layout/main-layout.component.html | 2 +- .../layout/sidebar/sidebar.component.css | 2 + .../layout/sidebar/sidebar.component.ts | 12 +- .../app/components/login/login.component.css | 46 ++---- .../app/components/login/login.component.html | 25 ++- .../app/components/login/login.component.ts | 18 ++- .../change-password-modal.component.css | 30 ++-- .../change-password-modal.component.html | 18 +-- .../change-password-modal.component.ts | 26 +-- .../edit-user-modal.component.html | 8 +- .../edit-user-modal.component.ts | 53 +++---- .../admin/users/users/users.component.ts | 5 +- .../pages/admin/users/users/users.service.ts | 15 +- 43 files changed, 843 insertions(+), 427 deletions(-) create mode 100644 ogWebconsole/src/app/components/groups/client-view/client-view.component.css create mode 100644 ogWebconsole/src/app/components/groups/client-view/client-view.component.html create mode 100644 ogWebconsole/src/app/components/groups/client-view/client-view.component.spec.ts create mode 100644 ogWebconsole/src/app/components/groups/client-view/client-view.component.ts create mode 100644 ogWebconsole/src/app/components/groups/delete-groups-modal/delete-groups-modal.component.css create mode 100644 ogWebconsole/src/app/components/groups/delete-groups-modal/delete-groups-modal.component.spec.ts create mode 100644 ogWebconsole/src/app/components/groups/delete-groups-modal/delete-groups-modal.component.ts diff --git a/ogWebconsole/src/app/app.component.css b/ogWebconsole/src/app/app.component.css index aac26c0..ee894d6 100644 --- a/ogWebconsole/src/app/app.component.css +++ b/ogWebconsole/src/app/app.component.css @@ -2,6 +2,7 @@ height: 100%; } + .content { padding: 16px; } diff --git a/ogWebconsole/src/app/app.module.ts b/ogWebconsole/src/app/app.module.ts index ae1361b..3b27cb0 100644 --- a/ogWebconsole/src/app/app.module.ts +++ b/ogWebconsole/src/app/app.module.ts @@ -11,8 +11,8 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import { CustomInterceptor } from './services/custom.interceptor'; import { provideAnimationsAsync } from '@angular/platform-browser/animations/async'; -import {MatToolbarModule} from '@angular/material/toolbar'; -import {MatIconModule} from '@angular/material/icon'; +import {MatToolbarModule} from '@angular/material/toolbar'; +import {MatIconModule} from '@angular/material/icon'; import { MatButtonModule } from '@angular/material/button'; import { MatSidenavModule } from '@angular/material/sidenav'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; @@ -46,6 +46,12 @@ import { ClassroomViewComponent } from './components/groups/classroom-view/class import {MatProgressSpinner} from "@angular/material/progress-spinner"; import {MatMenu, MatMenuItem, MatMenuTrigger} from "@angular/material/menu"; +import {MatAutocomplete} from "@angular/material/autocomplete"; +import {MatChip, MatChipListbox, MatChipOption, MatChipSet} from "@angular/material/chips"; +import { ClientViewComponent } from './components/groups/client-view/client-view.component'; +import {MatTab, MatTabGroup} from "@angular/material/tabs"; +import {MatTooltip} from "@angular/material/tooltip"; +import { DeleteGroupsModalComponent } from './components/groups/delete-groups-modal/delete-groups-modal.component'; @NgModule({ declarations: [ AppComponent, @@ -70,7 +76,9 @@ import {MatMenu, MatMenuItem, MatMenuTrigger} from "@angular/material/menu"; DeleteModalComponent, EditOrganizationalUnitComponent, EditClientComponent, - ClassroomViewComponent + ClassroomViewComponent, + ClientViewComponent, + DeleteGroupsModalComponent ], bootstrap: [AppComponent], imports: [BrowserModule, @@ -92,7 +100,7 @@ import {MatMenu, MatMenuItem, MatMenuTrigger} from "@angular/material/menu"; MatSelectModule, MatDividerModule, MatStepperModule, - MatSlideToggleModule, MatMenu, MatMenuTrigger, MatMenuItem], + MatSlideToggleModule, MatMenu, MatMenuTrigger, MatMenuItem, MatAutocomplete, MatChipListbox, MatChipOption, MatChipSet, MatChip, MatProgressSpinner, MatTabGroup, MatTab, MatTooltip], providers: [ { provide: HTTP_INTERCEPTORS, diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css index b701ae8..ea072ec 100644 --- a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css @@ -1,7 +1,9 @@ .classroom { display: flex; - flex-direction: column; - align-items: center; + flex-wrap: wrap; + gap: 10px; + height: 57vh; + overflow-y: auto; } .classroom-group { @@ -9,12 +11,11 @@ background-color: #fafafa; } -.organizational-unit-name { - font-weight: bold; - font-size: 18px; - margin-bottom: 10px; +mat-card-title { + display: flex; + justify-content: space-between; + margin: 10px; } - .client-row { display: flex; justify-content: center; @@ -27,18 +28,20 @@ } .client-box { - width: 100px; - height: 100px; + width: 100%; + height: auto; background-color: lightblue; - display: flex; - justify-content: center; - align-items: center; - border: 1px solid #000; box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1); border-radius: 5px; cursor: pointer; } +.client-box:hover { + box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.2); + scale: 1.1; + transition: 0.3s ease-in-out; +} + .client-box p { margin: 0; } diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html index 382e3b1..5243026 100644 --- a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html @@ -1,12 +1,26 @@
-

Disposición {{ group.organizationalUnitName }}

+ Clientes dentro de: {{ group.organizationalUnitName }}
-

{{ client.name }}

+ + + {{ client.name }} + + + + + {{ client.ip }} + + + {{ client.mac }} + + + +
-
\ No newline at end of file + diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts index 48f799b..0549a65 100644 --- a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts @@ -1,6 +1,12 @@ // src/app/classroom-view/classroom-view.component.ts import { Component, Input, OnInit } from '@angular/core'; +import { + ChangePasswordModalComponent +} from "../../pages/admin/users/users/change-password-modal/change-password-modal.component"; +import {MatDialog} from "@angular/material/dialog"; +import {CreateClientComponent} from "../clients/create-client/create-client.component"; +import {ClientViewComponent} from "../client-view/client-view.component"; interface GroupedClients { organizationalUnitName: string; @@ -12,19 +18,19 @@ interface GroupedClients { templateUrl: './classroom-view.component.html', styleUrls: ['./classroom-view.component.css'] }) -export class ClassroomViewComponent implements OnInit { +export class ClassroomViewComponent implements OnInit { @Input() clients: any[] = []; @Input() pcInTable: number = 3; groupedClients: GroupedClients[] = []; - constructor() {} + constructor(public dialog: MatDialog) {} ngOnInit(): void { this.groupClientsByOrganizationalUnit(); } ngOnChanges(): void { - this.groupClientsByOrganizationalUnit(); + this.groupClientsByOrganizationalUnit(); } groupClientsByOrganizationalUnit(): void { @@ -53,5 +59,6 @@ export class ClassroomViewComponent implements OnInit { handleClientClick(client: any): void { console.log('Client clicked:', client); + const dialogRef = this.dialog.open(ClientViewComponent, { data: { client }, width: '700px', height:'700px'}); } } diff --git a/ogWebconsole/src/app/components/groups/client-view/client-view.component.css b/ogWebconsole/src/app/components/groups/client-view/client-view.component.css new file mode 100644 index 0000000..0ce046b --- /dev/null +++ b/ogWebconsole/src/app/components/groups/client-view/client-view.component.css @@ -0,0 +1,41 @@ +.mat-dialog-content { + padding: 20px; +} + +.button-column { + display: flex; + flex-direction: column; + gap: 20px; + margin: 20px; + padding: 20px; +} + +.button-encender { + background-color: #3f51b5; /* Azul */ + color: white; +} + +.button-apagar { + background-color: #e91e63; /* Rosa */ + color: white; +} + +.button-resetear { + background-color: #f44336; /* Rojo */ + color: white; +} + +.button-otros-1 { + background-color: #4caf50; /* Verde */ + color: white; +} + +.button-otros-2 { + background-color: #ff9800; /* Naranja */ + color: white; +} + +.button-otros-3 { + background-color: #9c27b0; /* Púrpura */ + color: white; +} diff --git a/ogWebconsole/src/app/components/groups/client-view/client-view.component.html b/ogWebconsole/src/app/components/groups/client-view/client-view.component.html new file mode 100644 index 0000000..3e02ffa --- /dev/null +++ b/ogWebconsole/src/app/components/groups/client-view/client-view.component.html @@ -0,0 +1,40 @@ +

Propiedades cliente

+
+ + + + Nombre: {{ data.client.name }} + IP: {{ data.client.ip }} + MAC: {{data.client.mac }} + Nº de serie: {{data.client.serialNumber }} + Netiface: {{data.client.netiface }} + Fecha de creación: {{data.client.createdAt | date }} + Creado por: {{data.client.createdBy }} + + + + + Menu: {{ data.client.menu }} + Perfil hardware: {{ data.client.hardwareProfile }} + OGlive: {{data.client.mac }} + Autoexec: {{data.client.serialNumber }} + Repositorio: {{data.client.netiface }} + Validacion: {{data.client.netiface }} + Página login: {{data.client.netiface }} + Página validacion: {{data.client.netiface }} + Fecha de creación: {{data.client.createdAt | date }} + Creado por: {{data.client.createdBy }} + + + +
+ + + + + + +
+
+
+
diff --git a/ogWebconsole/src/app/components/groups/client-view/client-view.component.spec.ts b/ogWebconsole/src/app/components/groups/client-view/client-view.component.spec.ts new file mode 100644 index 0000000..4ec9b84 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/client-view/client-view.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ClientViewComponent } from './client-view.component'; + +describe('ClientViewComponent', () => { + let component: ClientViewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ClientViewComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ClientViewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/ogWebconsole/src/app/components/groups/client-view/client-view.component.ts b/ogWebconsole/src/app/components/groups/client-view/client-view.component.ts new file mode 100644 index 0000000..f31c7d3 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/client-view/client-view.component.ts @@ -0,0 +1,14 @@ +import {Component, Inject} from '@angular/core'; +import {MAT_DIALOG_DATA} from "@angular/material/dialog"; + +@Component({ + selector: 'app-client-view', + templateUrl: './client-view.component.html', + styleUrl: './client-view.component.css' +}) +export class ClientViewComponent { + constructor( + @Inject(MAT_DIALOG_DATA) public data: any // Inject data for edit mode + ) { + } +} diff --git a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.css b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.css index 40124bd..ceac8f6 100644 --- a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.css +++ b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.css @@ -1,39 +1,48 @@ h1 { - text-align: center; - font-family: 'Roboto', sans-serif; - font-weight: 400; - color: #3f51b5; - margin-bottom: 20px; - } - - .network-form { - display: flex; - flex-direction: column; - gap: 15px; - } - - .form-field { - width: 100%; - margin-top: 10px; - } - - .mat-dialog-content { - padding: 20px; - } - - .mat-dialog-actions { - display: flex; - justify-content: flex-end; - padding: 10px 20px; - } - - button { - text-transform: none; - font-size: 16px; - font-weight: 500; - } - - .mat-slide-toggle { - margin-top: 20px; - } - \ No newline at end of file + text-align: center; + font-family: 'Roboto', sans-serif; + font-weight: 400; + color: #3f51b5; + margin-bottom: 20px; +} + +.network-form { + display: flex; + flex-direction: column; + gap: 15px; +} + +.form-field { + width: 100%; + margin-top: 10px; +} + +.mat-dialog-content { + padding: 50px; +} + +.mat-dialog-actions { + display: flex; + justify-content: flex-end; + padding: 10px 20px; +} + +button { + text-transform: none; + font-size: 16px; + font-weight: 500; +} + +.mat-slide-toggle { + margin-top: 20px; +} + +mat-option .unit-name { + display: block; +} + +mat-option .unit-path { + display: block; + font-size: 0.8em; + color: gray; +} diff --git a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.html b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.html index 6061f94..8044bc3 100644 --- a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.html +++ b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.html @@ -1,10 +1,13 @@

Añadir Cliente

-
+
Padre - {{ unit.name }} + +
{{ unit.name }}
+
{{ unit.path }}
+
@@ -17,26 +20,26 @@ Interfaz de Red + Ejemplo: eth0 Controlador de Red + Ejemplo: e1000e MAC + Ejemplo: 00:11:22:33:44:55 Formato de MAC inválido. Ejemplo válido: 00:11:22:33:44:55 Dirección IP + Ejemplo: 127.0.0.1 Formato de dirección IP inválido. Ejemplo válido: 127.0.0.1 - - Estado - - Menú URL @@ -44,7 +47,9 @@ Perfil de Hardware - + + {{ unit.name }} + Formato de URL inválido. diff --git a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts index 857c62e..78bfea9 100644 --- a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts +++ b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts @@ -1,7 +1,8 @@ import { HttpClient } from '@angular/common/http'; -import { Component, OnInit } from '@angular/core'; +import {Component, Inject, OnInit} from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MatDialogRef } from '@angular/material/dialog'; +import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; +import {MatSnackBar} from "@angular/material/snack-bar"; @Component({ selector: 'app-create-client', @@ -11,31 +12,36 @@ import { MatDialogRef } from '@angular/material/dialog'; export class CreateClientComponent implements OnInit { clientForm!: FormGroup; parentUnits: any[] = []; // Array to store parent units fetched from API + hardwareProfiles: any[] = []; // Array to store hardware profiles fetched from API + private errorForm: boolean = false; constructor( private fb: FormBuilder, private dialogRef: MatDialogRef, - private http: HttpClient - ) { } + private http: HttpClient, + private snackBar: MatSnackBar, + @Inject(MAT_DIALOG_DATA) public data: any // Inject data for edit mode + ) { + } ngOnInit(): void { this.loadParentUnits(); // Load parent units when component initializes + this.loadHardwareProfiles(); // Load hardware profiles when component initializes this.clientForm = this.fb.group({ - organizationalUnit: [''], + organizationalUnit: [this.data.organizationalUnit ? this.data.organizationalUnit['@id'] : null, Validators.required], name: ['', Validators.required], - serialNumber: [''], - netiface: "eth0", - netDriver: "e1000e", - mac: "00:11:22:33:44:55", - ip: "127.0.0.1", - status: "test", - menu: null, - hardwareProfile: null, + serialNumber: ['', Validators.required], + netiface: null, + netDriver: null, + mac: ['', Validators.required], + ip: ['', Validators.required], + menu: [this.data.organizationalUnit && this.data.organizationalUnit.menu ? this.data.organizationalUnit.menu['@id'] : null], + hardwareProfile: [this.data.organizationalUnit && this.data.organizationalUnit.hardwareProfile ? this.data.organizationalUnit.hardwareProfile['@id'] : null], }); } loadParentUnits() { - const url = 'http://127.0.0.1:8080/organizational-units?page=1&itemsPerPage=30'; + const url = 'http://127.0.0.1:8080/organizational-units?page=1&itemsPerPage=10000'; this.http.get(url).subscribe( response => { @@ -47,15 +53,31 @@ export class CreateClientComponent implements OnInit { ); } + loadHardwareProfiles() { + const url = 'http://127.0.0.1:8080/hardware-profiles'; + + this.http.get(url).subscribe( + response => { + this.hardwareProfiles = response['hydra:member']; + }, + error => { + console.error('Error fetching hardware profiles:', error); + } + ); + } + onSubmit() { if (this.clientForm.valid) { + this.errorForm = false const formData = this.clientForm.value; this.http.post('http://127.0.0.1:8080/clients', formData).subscribe( response => { this.dialogRef.close(response); - }, + this.openSnackBar(false, 'Cliente creado exitosamente'); }, error => { console.error('Error during POST:', error); + this.errorForm = true + this.openSnackBar(true, 'Error al crear el cliente: ' + error.error['hydra:description']); } ); } @@ -64,4 +86,10 @@ export class CreateClientComponent implements OnInit { onNoClick(): void { this.dialogRef.close(); } + + openSnackBar(isError: boolean, message: string) { + this.snackBar.open(message, 'Cerrar', { + panelClass: isError ? ['snackbar-error'] : ['snackbar-success'] + }); + } } diff --git a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.css b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.css index 40124bd..39cb26a 100644 --- a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.css +++ b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.css @@ -1,39 +1,38 @@ h1 { - text-align: center; - font-family: 'Roboto', sans-serif; - font-weight: 400; - color: #3f51b5; - margin-bottom: 20px; - } - - .network-form { - display: flex; - flex-direction: column; - gap: 15px; - } - - .form-field { - width: 100%; - margin-top: 10px; - } - - .mat-dialog-content { - padding: 20px; - } - - .mat-dialog-actions { - display: flex; - justify-content: flex-end; - padding: 10px 20px; - } - - button { - text-transform: none; - font-size: 16px; - font-weight: 500; - } - - .mat-slide-toggle { - margin-top: 20px; - } - \ No newline at end of file + text-align: center; + font-family: 'Roboto', sans-serif; + font-weight: 400; + color: #3f51b5; + margin-bottom: 20px; +} + +.network-form { + display: flex; + flex-direction: column; + gap: 15px; +} + +.form-field { + width: 100%; + margin-top: 10px; +} + +.mat-dialog-content { + padding: 50px; +} + +.mat-dialog-actions { + display: flex; + justify-content: flex-end; + padding: 10px 20px; +} + +button { + text-transform: none; + font-size: 16px; + font-weight: 500; +} + +.mat-slide-toggle { + margin-top: 20px; +} diff --git a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.html b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.html index 6a520fd..022cd3c 100644 --- a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.html +++ b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.html @@ -1,5 +1,5 @@

Editar Cliente

-
+
Padre @@ -11,6 +11,40 @@ Nombre + + Número de Serie + + + + Interfaz de Red + + + + Controlador de Red + + + + MAC + + Formato de MAC inválido. Ejemplo válido: 00:11:22:33:44:55 + + + Dirección IP + + Formato de dirección IP inválido. Ejemplo válido: 127.0.0.1 + + + Menú URL + + Formato de URL inválido. + + + Perfil de Hardware + + {{ unit.name }} + + Formato de URL inválido. +
diff --git a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.ts b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.ts index 60d38d3..584fe69 100644 --- a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.ts +++ b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.ts @@ -12,6 +12,7 @@ import { CreateClientComponent } from '../create-client/create-client.component' export class EditClientComponent { clientForm!: FormGroup; parentUnits: any[] = []; // Array to store parent units fetched from API + hardwareProfiles: any[] = []; // Array to store hardware profiles fetched from API isEditMode: boolean; // Flag to check if it's edit mode constructor( @@ -19,7 +20,6 @@ export class EditClientComponent { private dialogRef: MatDialogRef, private http: HttpClient, @Inject(MAT_DIALOG_DATA) public data: any // Inject data for edit mode - ) { this.isEditMode = !!data?.uuid; // Check if uuid is passed to determine edit mode if (this.isEditMode) { @@ -29,22 +29,22 @@ export class EditClientComponent { ngOnInit(): void { this.loadParentUnits(); // Load parent units when component initializes + this.loadHardwareProfiles(); // Load hardware profiles when component initializes this.clientForm = this.fb.group({ - organizationalUnit: [''], + organizationalUnit: [null,Validators.required], name: ['', Validators.required], - serialNumber: [''], - netiface: "eth0", - netDriver: "e1000e", - mac: "00:11:22:33:44:55", - ip: "127.0.0.1", - status: "test", + serialNumber: null, + netiface: null, + netDriver: null, + mac: null, + ip: null, menu: null, hardwareProfile: null, }); } loadParentUnits() { - const url = 'http://127.0.0.1:8080/organizational-units?page=1&itemsPerPage=30'; + const url = 'http://127.0.0.1:8080/organizational-units?page=1&itemsPerPage=10000'; this.http.get(url).subscribe( response => { @@ -56,6 +56,19 @@ export class EditClientComponent { ); } + loadHardwareProfiles() { + const url = 'http://127.0.0.1:8080/hardware-profiles'; + + this.http.get(url).subscribe( + response => { + this.hardwareProfiles = response['hydra:member']; + }, + error => { + console.error('Error fetching hardware profiles:', error); + } + ); + } + loadData(uuid: string) { const url = `http://127.0.0.1:8080/clients/${uuid}`; @@ -63,7 +76,13 @@ export class EditClientComponent { data => { this.clientForm.patchValue({ name: data.name, - organizationalUnit: data.organizationalUnit ? data.organizationalUnit['@id'] : '' + ip: data.ip, + mac: data.mac, + netiface: data.netiface, + netDriver: data.netDriver, + serialNumber: data.serialNumber, + hardwareProfile: data.hardwareProfile ? data.hardwareProfile['@id'] : null, + organizationalUnit: data.organizationalUnit ? data.organizationalUnit['@id'] : null }); }); } diff --git a/ogWebconsole/src/app/components/groups/data.service.ts b/ogWebconsole/src/app/components/groups/data.service.ts index 4b56083..2b9ace5 100644 --- a/ogWebconsole/src/app/components/groups/data.service.ts +++ b/ogWebconsole/src/app/components/groups/data.service.ts @@ -9,24 +9,16 @@ import { UnidadOrganizativa } from './model'; }) export class DataService { - private apiUrl = 'http://127.0.0.1:8080/organizational-units?page=1&itemsPerPage=30'; + private apiUrl = 'http://127.0.0.1:8080/organizational-units?page=1&itemsPerPage=1000'; private clientsUrl = 'http://127.0.0.1:8080/clients?page=1&itemsPerPage=30'; constructor(private http: HttpClient) {} - getUnidadesOrganizativas(): Observable { - return this.http.get(this.apiUrl).pipe( + getOrganizationalUnits(): Observable { + return this.http.get(`${this.apiUrl}&type=organizational-unit`).pipe( map(response => { if (response['hydra:member'] && Array.isArray(response['hydra:member'])) { return response['hydra:member'] - .filter((unidad: any) => unidad.type === 'organizational-unit') - .map((unidad: any) => ({ - id: unidad.id, - nombre: unidad.name, - uuid: unidad.uuid, - type: unidad.type, - aulas: [] - })); } else { throw new Error('Unexpected response format'); } @@ -38,11 +30,11 @@ export class DataService { ); } - getChildren(uuid: string): Observable { - return this.http.get(`${this.apiUrl}&parent=${uuid}`).pipe( + getChildren(id: string): Observable { + return this.http.get(`${this.apiUrl}&parent.id=${id}`).pipe( map(response => { if (response['hydra:member'] && Array.isArray(response['hydra:member'])) { - return response['hydra:member'].filter((element: any) => element.parent && element.parent['@id'] === `/organizational-units/${uuid}`); + return response['hydra:member'] } else { throw new Error('Unexpected response format'); } @@ -54,11 +46,11 @@ export class DataService { ); } - getClients(uuid: string): Observable { - return this.http.get(this.clientsUrl).pipe( + getClients(id: string): Observable { + return this.http.get(`${this.clientsUrl}&organizationalUnit.id=${id}`).pipe( map(response => { if (response['hydra:member'] && Array.isArray(response['hydra:member'])) { - return response['hydra:member'].filter((client: any) => client.organizationalUnit && client.organizationalUnit['@id'] === `/organizational-units/${uuid}`); + return response['hydra:member'] } else { throw new Error('Unexpected response format'); } @@ -82,6 +74,16 @@ export class DataService { ); } + changeParent(uuid: string): Observable { + const url = `http://127.0.0.1:8080/organizational-units/${uuid}/change-parent`; + // @ts-ignore + return this.http.post(url).pipe( + catchError(error => { + console.error('Error deleting element', error); + return throwError(error); + }) + ); + } } diff --git a/ogWebconsole/src/app/components/groups/delete-groups-modal/delete-groups-modal.component.css b/ogWebconsole/src/app/components/groups/delete-groups-modal/delete-groups-modal.component.css new file mode 100644 index 0000000..e69de29 diff --git a/ogWebconsole/src/app/components/groups/delete-groups-modal/delete-groups-modal.component.spec.ts b/ogWebconsole/src/app/components/groups/delete-groups-modal/delete-groups-modal.component.spec.ts new file mode 100644 index 0000000..9f88c39 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/delete-groups-modal/delete-groups-modal.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DeleteGroupsModalComponent } from './delete-groups-modal.component'; + +describe('DeleteGroupsModalComponent', () => { + let component: DeleteGroupsModalComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [DeleteGroupsModalComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(DeleteGroupsModalComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/ogWebconsole/src/app/components/groups/delete-groups-modal/delete-groups-modal.component.ts b/ogWebconsole/src/app/components/groups/delete-groups-modal/delete-groups-modal.component.ts new file mode 100644 index 0000000..524987f --- /dev/null +++ b/ogWebconsole/src/app/components/groups/delete-groups-modal/delete-groups-modal.component.ts @@ -0,0 +1,30 @@ +import { Component, Inject } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; + +@Component({ + selector: 'app-delete-confirm-dialog', + template: ` +

Eliminar

+
+

¿Quiere borrar los clientes situados en {{data.name}} o quiere resituarlos en el nivel superior?

+
+
+ + +
+ ` +}) +export class DeleteGroupsModalComponent { + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: { name: string } + ) {} + + deleteClick(): void { + this.dialogRef.close('delete'); + } + + changeClick(): void { + this.dialogRef.close('change'); + } +} diff --git a/ogWebconsole/src/app/components/groups/groups.component.css b/ogWebconsole/src/app/components/groups/groups.component.css index 8696ff5..bf6b4bd 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.css +++ b/ogWebconsole/src/app/components/groups/groups.component.css @@ -8,13 +8,24 @@ margin: 10px; } +.header-container { + height: 100px; +} + .unidad-card, .elements-card { flex: 1 1 45%; background-color: #fafafa; - max-height: 300px; + max-height: 400px; +} + +.element-content { overflow-y: auto; } +.title { + margin-left: 10px; +} + .details-card, .classroom-view { flex: 1 1 25%; } @@ -60,6 +71,10 @@ button { width: 100%; } +.item-content mat-icon { + margin-right: 10px; +} + .clickable-item:hover { cursor: pointer; } @@ -71,6 +86,7 @@ button { .actions { display: flex; margin-left: auto; + align-self: center; } .actions mat-icon { @@ -81,4 +97,16 @@ button { .actions mat-icon:hover { color: #212121; -} \ No newline at end of file +} + +.empty-list { + display: flex; + justify-content: center; + align-items: center; + height: 100%; +} + +mat-spinner { + margin: 0 auto; + align-self: center; +} diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html index d97103a..d655b26 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.html +++ b/ogWebconsole/src/app/components/groups/groups.component.html @@ -1,24 +1,41 @@ -

Crear

-
- - +
+

Administrar grupos

+
+ + +
- -

Grupos

Unidad organizativa - - + +
- - apartment - {{ unidad.nombre }} - + apartment + {{ unidad.name }} - edit + edit + + add_home_work + + devices +
@@ -29,7 +46,7 @@
- Elementos + Elementos internos {{ crumb }} @@ -38,19 +55,28 @@
- - - + + + +
+ info + No hay elementos internos +
+
- - - - - {{ child.name || child.nombre }} - + + apartment + groups + school + computer + lan + help_outline + + {{child.name}} edit - delete + devices + delete
@@ -58,19 +84,5 @@
- - Detalles del elemento - -

Nombre: {{ selectedDetail.name || selectedDetail.nombre }}

-

Tipo: {{ selectedDetail.type }}

-

ID: {{ selectedDetail.id }}

-

UUID: {{ selectedDetail.uuid }}

- -
- -

Selecciona un elemento para ver sus detalles.

-
-
- - -
\ No newline at end of file + +
diff --git a/ogWebconsole/src/app/components/groups/groups.component.ts b/ogWebconsole/src/app/components/groups/groups.component.ts index ce0b6f5..e34873a 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.ts +++ b/ogWebconsole/src/app/components/groups/groups.component.ts @@ -7,6 +7,7 @@ import { DeleteModalComponent } from './delete-modal/delete-modal.component'; import { CreateClientComponent } from './clients/create-client/create-client.component'; import { EditOrganizationalUnitComponent } from './organizational-units/edit-organizational-unit/edit-organizational-unit.component'; import { EditClientComponent } from './clients/edit-client/edit-client.component'; +import {DeleteGroupsModalComponent} from "./delete-groups-modal/delete-groups-modal.component"; @Component({ selector: 'app-groups', @@ -14,21 +15,19 @@ import { EditClientComponent } from './clients/edit-client/edit-client.component styleUrls: ['./groups.component.css'] }) export class GroupsComponent implements OnInit { - unidadesOrganizativas: UnidadOrganizativa[] = []; + organizationalUnits: UnidadOrganizativa[] = []; selectedUnidad: UnidadOrganizativa | null = null; selectedDetail: any | null = null; // Nueva variable para el detalle del elemento seleccionado children: any[] = []; breadcrumb: string[] = []; clientsData: any[] = []; // Nueva variable para almacenar los datos de clients - - - breadcrumbData: any[] = []; // Almacenar datos de breadcrumb para navegar + loading:boolean = false; constructor(private dataService: DataService, public dialog: MatDialog) {} ngOnInit(): void { - this.dataService.getUnidadesOrganizativas().subscribe( - data => this.unidadesOrganizativas = data, + this.dataService.getOrganizationalUnits().subscribe( + data => this.organizationalUnits = data, error => console.error('Error fetching unidades organizativas', error) ); } @@ -36,17 +35,17 @@ constructor(private dataService: DataService, public dialog: MatDialog) {} onSelectUnidad(unidad: UnidadOrganizativa): void { this.selectedUnidad = unidad; this.selectedDetail = unidad; // Mostrar detalles de la unidad seleccionada - this.breadcrumb = [unidad.nombre]; + this.breadcrumb = [unidad.name]; this.breadcrumbData = [unidad]; - this.loadChildrenAndClients(unidad.uuid); + this.loadChildrenAndClients(unidad.id); } onSelectChild(child: any): void { this.selectedDetail = child; // Mostrar detalles del niño seleccionado if (child.type !== 'client' && child.uuid && child.id) { - this.breadcrumb.push(child.name || child.nombre); + this.breadcrumb.push(child.name || child.name); this.breadcrumbData.push(child); - this.loadChildrenAndClients(child.uuid); + this.loadChildrenAndClients(child.id); } } @@ -57,25 +56,25 @@ constructor(private dataService: DataService, public dialog: MatDialog) {} if (target.type === 'client') { this.selectedDetail = target; } else { - this.loadChildrenAndClients(target.uuid); + this.loadChildrenAndClients(target.id); } } - loadChildrenAndClients(uuid: string): void { - this.dataService.getChildren(uuid).subscribe( + loadChildrenAndClients(id: string): void { + this.loading = true + this.dataService.getChildren(id).subscribe( childrenData => { console.log('Children data:', childrenData); - this.dataService.getClients(uuid).subscribe( + this.dataService.getClients(id).subscribe( clientsData => { this.clientsData = clientsData; // Almacenar clientsData para pasarlo al componente hijo const newChildren = [...childrenData, ...clientsData]; - + if (newChildren.length > 0) { this.children = newChildren; } else { this.children = []; // Limpiar card2 cuando no hay elementos - this.breadcrumb.pop(); // Revertir breadcrumb solo si no hay elementos - + // Si deseas que la unidad organizativa se limpie completamente, descomenta la línea siguiente: // this.selectedUnidad = null; } @@ -92,79 +91,97 @@ constructor(private dataService: DataService, public dialog: MatDialog) {} this.children = []; // Limpiar card2 en caso de error } ); + this.loading = false } - - addOU(): void { - const dialogRef = this.dialog.open(CreateOrganizationalUnitComponent); + + addOU(parent:any = null): void { + console.log('Parent:', parent); + const dialogRef = this.dialog.open(CreateOrganizationalUnitComponent, { data: { parent }, width: '700px'}); dialogRef.afterClosed().subscribe(() => { - this.dataService.getUnidadesOrganizativas().subscribe( - data => this.unidadesOrganizativas = data, + this.dataService.getOrganizationalUnits().subscribe( + data => this.organizationalUnits = data, error => console.error('Error fetching unidades organizativas', error) ); }); } - addClient(): void { - const dialogRef = this.dialog.open(CreateClientComponent); + addClient(organizationalUnit:any = null): void { + const dialogRef = this.dialog.open(CreateClientComponent, { data: { organizationalUnit }, width: '700px'}); // Subscribirse al evento unitAdded del componente de creación después de cerrar el diálogo dialogRef.afterClosed().subscribe(() => { - this.dataService.getUnidadesOrganizativas().subscribe( - data => this.unidadesOrganizativas = data, + this.dataService.getOrganizationalUnits().subscribe( + data => this.organizationalUnits = data, error => console.error('Error fetching unidades organizativas', error) ); }); } + onDeleteClick(event: MouseEvent, uuid: string, name: string, type: string): void { + event.stopPropagation(); + if (type === 'client') { + const dialogRef = this.dialog.open(DeleteModalComponent, { + width: '400px', + data: { name } + }); - getIcon(type: string): string { - switch(type) { - case 'organizational-unit': - return 'apartment'; - case 'classroom-group': - return 'classrooms-group-icon'; - case 'classroom': - return 'classroom-icon'; - case 'client': - return 'client-icon'; - case 'clients-group': - return 'clients-group-icon'; - default: - return ''; + dialogRef.afterClosed().subscribe(result => { + if (result) { + this.dataService.deleteElement(uuid, type).subscribe( + () => { + this.loadChildrenAndClients(this.selectedUnidad?.id || ''); + + this.dataService.getOrganizationalUnits().subscribe( + data => this.organizationalUnits = data, + error => console.error('Error fetching unidades organizativas', error) + ); + + }, + error => console.error('Error deleting element', error) + ); + } + }); + } else { + const dialogDeleteGroupRef = this.dialog.open(DeleteGroupsModalComponent, { + width: '400px', + data: { name } + }); + + dialogDeleteGroupRef.afterClosed().subscribe(result => { + if (result && result === 'delete') { + this.dataService.deleteElement(uuid, type).subscribe( + () => { + this.loadChildrenAndClients(this.selectedUnidad?.id || ''); + this.dataService.getOrganizationalUnits().subscribe( + data => this.organizationalUnits = data, + error => console.error('Error fetching unidades organizativas', error) + ); + }, + error => console.error('Error deleting element', error) + ); + } else if (result && result === 'change') { + this.dataService.changeParent(uuid).subscribe( + () => { + this.loadChildrenAndClients(this.selectedUnidad?.id || ''); + this.dataService.getOrganizationalUnits().subscribe( + data => this.organizationalUnits = data, + error => console.error('Error fetching unidades organizativas', error) + ); + }, + error => console.error('Error deleting element', error) + ); + } + }); } } - onDeleteClick(uuid: string, name: string, type: string): void { - const dialogRef = this.dialog.open(DeleteModalComponent, { - width: '250px', - data: { name } - }); - - dialogRef.afterClosed().subscribe(result => { - if (result) { - this.dataService.deleteElement(uuid, type).subscribe( - () => { - this.loadChildrenAndClients(this.selectedUnidad?.uuid || ''); - - this.dataService.getUnidadesOrganizativas().subscribe( - data => this.unidadesOrganizativas = data, - error => console.error('Error fetching unidades organizativas', error) - ); - - }, - error => console.error('Error deleting element', error) - ); - } - }); - } - onEditClick(type: any, uuid: string): void { console.log('Tipo del elemento a editar:', type); console.log('UUID del elemento a editar:', uuid); if (type != "client") { - const dialogRef = this.dialog.open(EditOrganizationalUnitComponent); + const dialogRef = this.dialog.open(EditOrganizationalUnitComponent, { data: { uuid }, width: '700px'}); } else { console.log('Editar cliente'); - const dialogRef = this.dialog.open(EditClientComponent); + const dialogRef = this.dialog.open(EditClientComponent, { data: { uuid }, width: '700px' } ); } } } diff --git a/ogWebconsole/src/app/components/groups/model.ts b/ogWebconsole/src/app/components/groups/model.ts index f90b50d..b37b389 100644 --- a/ogWebconsole/src/app/components/groups/model.ts +++ b/ogWebconsole/src/app/components/groups/model.ts @@ -9,11 +9,11 @@ export interface Aula { } export interface UnidadOrganizativa { - id: number; - nombre: string; + id: string; + name: string; uuid: string; type: string; - aulas: Aula[]; + parent: UnidadOrganizativa[]; } export interface OrganizationalUnit { @@ -50,4 +50,4 @@ export interface ClientCollection { "@id": string; "@type": string; }; -} \ No newline at end of file +} diff --git a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html index 2c4fafa..9143c20 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html +++ b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html @@ -9,7 +9,9 @@ Tipo - {{ type }} + + {{ typeTranslations[type] }} + @@ -17,8 +19,9 @@ - Padre + Unidad organizativa padre + -- {{ unit.name }} @@ -46,10 +49,6 @@ Aforo - - Foto (URL) (string de prueba) - -
@@ -128,7 +127,6 @@ Perfil de Hardware - Validación
diff --git a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts index 43229eb..c5ce903 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts +++ b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts @@ -1,6 +1,6 @@ -import { Component, OnInit, Output, EventEmitter } from '@angular/core'; +import {Component, OnInit, Output, EventEmitter, Inject} from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { MatDialogRef } from '@angular/material/dialog'; +import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; import { HttpClient, HttpHeaders } from '@angular/common/http'; @Component({ @@ -13,20 +13,27 @@ export class CreateOrganizationalUnitComponent implements OnInit { generalFormGroup: FormGroup; additionalInfoFormGroup: FormGroup; networkSettingsFormGroup: FormGroup; - classroomInfoFormGroup: FormGroup; + classroomInfoFormGroup: FormGroup; types: string[] = ['organizational-unit', 'classrooms-group', 'classroom', 'clients-group']; - parentUnits: any[] = []; + typeTranslations: { [key: string]: string } = { + 'organizational-unit': 'Unidad organizativa', + 'classrooms-group': 'Grupo de aulas', + 'classroom': 'Aula', + 'clients-group': 'Grupo de clientes' + }; + parentUnits: any[] = []; - @Output() unitAdded = new EventEmitter(); + @Output() unitAdded = new EventEmitter(); constructor( private _formBuilder: FormBuilder, private dialogRef: MatDialogRef, - private http: HttpClient + private http: HttpClient, + @Inject(MAT_DIALOG_DATA) public data: any // Inject data for edit mode ) { this.generalFormGroup = this._formBuilder.group({ name: ['', Validators.required], - parent: [''], + parent: [this.data.parent ? this.data.parent['@id'] : null], description: [''], type: ['', Validators.required] }); @@ -53,17 +60,16 @@ export class CreateOrganizationalUnitComponent implements OnInit { location: [''], projector: [false], board: [false], - capacity: [0, Validators.min(0)], - photo: ['', Validators.pattern('https?://.+')] + capacity: [0, Validators.min(0)] }); } ngOnInit() { - this.loadParentUnits(); + this.loadParentUnits(); } loadParentUnits() { - const url = 'http://127.0.0.1:8080/organizational-units?page=1&itemsPerPage=30'; + const url = 'http://127.0.0.1:8080/organizational-units?page=1&itemsPerPage=10000'; this.http.get(url).subscribe( response => { @@ -106,11 +112,8 @@ export class CreateOrganizationalUnitComponent implements OnInit { if (classroomInfoFormValues.capacity !== undefined) { formData.capacity = classroomInfoFormValues.capacity; } - if (classroomInfoFormValues.photo !== undefined) { - formData.photo = classroomInfoFormValues.photo; - } } - + console.log('POST data:', formData); const postUrl = 'http://127.0.0.1:8080/organizational-units'; const headers = new HttpHeaders({ 'Content-Type': 'application/json' }); @@ -119,7 +122,7 @@ export class CreateOrganizationalUnitComponent implements OnInit { response => { console.log('POST successful:', response); this.unitAdded.emit(); - this.dialogRef.close(); + this.dialogRef.close(); }, error => { console.error('Error al realizar POST:', error); diff --git a/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.ts b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.ts index 6c86f66..6e2de73 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.ts +++ b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.ts @@ -66,7 +66,7 @@ export class EditOrganizationalUnitComponent implements OnInit { } loadParentUnits() { - const url = 'http://127.0.0.1:8080/organizational-units?page=1&itemsPerPage=30'; + const url = 'http://127.0.0.1:8080/organizational-units?page=1&itemsPerPage=10000'; this.http.get(url).subscribe( response => { @@ -93,20 +93,20 @@ export class EditOrganizationalUnitComponent implements OnInit { comments: data.comments }); this.networkSettingsFormGroup.patchValue({ - proxy: data.proxy, - dns: data.dns, - netmask: data.netmask, - router: data.router, - ntp: data.ntp, - p2pMode: data.p2pMode, - p2pTime: data.p2pTime, - mcastIp: data.mcastIp, - mcastSpeed: data.mcastSpeed, - mcastPort: data.mcastPort, - mcastMode: data.mcastMode, - menu: data.menu, - hardwareProfile: data.hardwareProfile, - validation: data.validation + proxy: data.networkSettings.proxy, + dns: data.networkSettings.dns, + netmask: data.networkSettings.netmask, + router: data.networkSettings.router, + ntp: data.networkSettings.ntp, + p2pMode: data.networkSettings.p2pMode, + p2pTime: data.networkSettings.p2pTime, + mcastIp: data.networkSettings.mcastIp, + mcastSpeed: data.networkSettings.mcastSpeed, + mcastPort: data.networkSettings.mcastPort, + mcastMode: data.networkSettings.mcastMode, + menu: data.networkSettings.menu, + hardwareProfile: data.networkSettings.hardwareProfile, + validation: data.networkSettings.validation }); }, error => { diff --git a/ogWebconsole/src/app/components/layout/header/header.component.css b/ogWebconsole/src/app/components/layout/header/header.component.css index 6c84df7..6e944a1 100644 --- a/ogWebconsole/src/app/components/layout/header/header.component.css +++ b/ogWebconsole/src/app/components/layout/header/header.component.css @@ -1,10 +1,15 @@ mat-toolbar { - height: 50px; + height: 60px; background-color: #3f51b5; color: white; } +.admin-button, +.user-button{ + background-color: #e0e0e0; +} + .navbar-button-row { display: flex; justify-content: end; @@ -16,6 +21,5 @@ button[mat-flat-button] { } .navbar-tittle{ - padding-left: 20px; cursor: pointer; } diff --git a/ogWebconsole/src/app/components/layout/header/header.component.html b/ogWebconsole/src/app/components/layout/header/header.component.html index 6a54ed5..cb93cff 100644 --- a/ogWebconsole/src/app/components/layout/header/header.component.html +++ b/ogWebconsole/src/app/components/layout/header/header.component.html @@ -1,7 +1,8 @@ Opengnsys webconsole
diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/edit-user-modal/edit-user-modal.component.ts b/ogWebconsole/src/app/components/pages/admin/users/users/edit-user-modal/edit-user-modal.component.ts index 3b7fdb5..3a18cf1 100644 --- a/ogWebconsole/src/app/components/pages/admin/users/users/edit-user-modal/edit-user-modal.component.ts +++ b/ogWebconsole/src/app/components/pages/admin/users/users/edit-user-modal/edit-user-modal.component.ts @@ -3,12 +3,6 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { UserService } from '../users.service'; -interface UserGroup { - '@id': string; - name: string; - role: string[]; -} - @Component({ selector: 'app-edit-user-modal', templateUrl: './edit-user-modal.component.html', @@ -16,7 +10,7 @@ interface UserGroup { }) export class EditUserModalComponent implements OnInit {@Output() userEdited = new EventEmitter(); userForm: FormGroup; - userGroups: UserGroup[] = []; + userGroups: any[] = []; organizationalUnits: any[] = []; constructor( @@ -26,11 +20,12 @@ export class EditUserModalComponent implements OnInit {@Output() userEdited = ne private userService: UserService // Inyecta el servicio ) { this.userForm = this.fb.group({ - username: [this.data], + username: [this.data.user.username], password: [''], - role: this.data.user.allowedOrganizationalUnits, - organizationalUnit: [[this.data.user.allowedOrganizationalUnits], Validators.required] + userGroups: [this.data.user.userGroups.map((group: { '@id': any; }) => group['@id'])], + allowedOrganizationalUnits: [this.data.user.allowedOrganizationalUnits.map((unit: { '@id': any; }) => unit['@id'])] }); + console.log(this.userForm.value) } ngOnInit(): void { @@ -47,25 +42,25 @@ export class EditUserModalComponent implements OnInit {@Output() userEdited = ne } onSubmit(): void { + console.log(this.userForm.value); + const userPayload = { + username: this.userForm.value.username, + allowedOrganizationalUnits: this.userForm.value.allowedOrganizationalUnits, + password: this.userForm.value.password, + enabled: true, + userGroups: this.userForm.value.userGroups + }; - const userPayload = { - username: this.userForm.value.username, - allowedOrganizationalUnits: [], - password: this.userForm.value.password, - enabled: true, - userGroups: [this.userForm.value.role ] - }; - - this.userService.updateUser(this.data.user.uuid, userPayload).subscribe( - response => { - console.log('User added successfully:', response); - this.userEdited.emit(); - this.dialogRef.close(this.userForm.value); - }, - error => { - console.error('Error adding user:', error); - // Agregar alguna lógica para manejar el error en la interfaz de usuario - } - ); + this.userService.updateUser(this.data.user.uuid, userPayload).subscribe( + response => { + console.log('User added successfully:', response); + this.userEdited.emit(); + this.dialogRef.close(this.userForm.value); + }, + error => { + console.error('Error adding user:', error); + // Agregar alguna lógica para manejar el error en la interfaz de usuario + } + ); } } diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/users.component.ts b/ogWebconsole/src/app/components/pages/admin/users/users/users.component.ts index 078193a..35bbdf8 100644 --- a/ogWebconsole/src/app/components/pages/admin/users/users/users.component.ts +++ b/ogWebconsole/src/app/components/pages/admin/users/users/users.component.ts @@ -62,7 +62,8 @@ export class UsersComponent implements OnInit { editUser(user: any) { // Implementar la lógica de edición const dialogRef = this.dialog.open(EditUserModalComponent, { - data: { user: user } + data: { user: user }, + width: '400px' }); dialogRef.componentInstance.userEdited.subscribe(() => { this.loadUsers(); @@ -71,7 +72,7 @@ export class UsersComponent implements OnInit { deleteUser(user: any) { const dialogRef = this.dialog.open(DeleteUserModalComponent, { - data: user + data: user, }); dialogRef.afterClosed().subscribe(result => { diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/users.service.ts b/ogWebconsole/src/app/components/pages/admin/users/users/users.service.ts index e64f772..3e0811a 100644 --- a/ogWebconsole/src/app/components/pages/admin/users/users/users.service.ts +++ b/ogWebconsole/src/app/components/pages/admin/users/users/users.service.ts @@ -10,6 +10,12 @@ interface UserPayload { allowedOrganizationalUnits: any[]; } +interface ChangePasswordPayload { + currentPassword: string; + newPassword: string; + repeatNewPassword: string; +} + interface UserGroup { '@id': string; name: string; @@ -38,6 +44,13 @@ export class UserService { return this.http.put(`${this.apiUrl}/users/${userId}`, userPayload, { headers }); } + changePassword(userId: number, userPayload: ChangePasswordPayload): Observable { + const headers = new HttpHeaders({ + 'Content-Type': 'application/ld+json', + }); + return this.http.put(`${this.apiUrl}/users/${userId}/reset-password`, userPayload, { headers }); + } + getUserGroups(): Observable<{ 'hydra:member': UserGroup[] }> { return this.http.get<{ 'hydra:member': UserGroup[] }>(`${this.apiUrl}/user-groups`); } @@ -48,6 +61,6 @@ export class UserService { getOrganizationalUnits(): Observable { return this.http.get(`${this.apiUrl}/organizational-units?page=1&itemsPerPage=30`); - + } } -- 2.40.1 From 8239aa0d535de5f044ac7a739582391605d845fe Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Fri, 12 Jul 2024 13:08:14 +0200 Subject: [PATCH 29/36] refs #486. Added tree-view. Snackbar response, and some UX improvements --- ogWebconsole/angular.json | 7 +- ogWebconsole/package-lock.json | 14 +++ ogWebconsole/package.json | 1 + ogWebconsole/src/app/app.component.css | 3 + ogWebconsole/src/app/app.module.ts | 44 ++++++- .../classroom-view.component.css | 20 +++- .../classroom-view.component.html | 12 +- .../classroom-view.component.ts | 3 +- .../client-view/client-view.component.css | 34 ++++-- .../client-view/client-view.component.html | 74 +++++++----- .../client-view/client-view.component.ts | 50 +++++++- .../create-client.component.html | 20 ++-- .../create-client/create-client.component.ts | 48 +++++--- .../edit-client/edit-client.component.html | 18 ++- .../edit-client/edit-client.component.ts | 38 ++++-- .../src/app/components/groups/data.service.ts | 28 ++++- .../components/groups/groups.component.css | 13 ++- .../components/groups/groups.component.html | 52 ++++++--- .../app/components/groups/groups.component.ts | 102 +++++++++++++--- .../groups/legend/legend.component.css | 0 .../groups/legend/legend.component.html | 22 ++++ .../groups/legend/legend.component.spec.ts | 23 ++++ .../groups/legend/legend.component.ts | 16 +++ .../create-organizational-unit.component.html | 21 +++- .../create-organizational-unit.component.ts | 40 ++++++- .../edit-organizational-unit.component.html | 46 +++++++- .../edit-organizational-unit.component.ts | 60 +++++++++- .../show-organizational-unit.component.css | 26 +++++ .../show-organizational-unit.component.html | 43 +++++++ ...show-organizational-unit.component.spec.ts | 23 ++++ .../show-organizational-unit.component.ts | 48 ++++++++ .../groups/tree-view/tree-view.component.css | 40 +++++++ .../groups/tree-view/tree-view.component.html | 55 +++++++++ .../tree-view/tree-view.component.spec.ts | 23 ++++ .../groups/tree-view/tree-view.component.ts | 70 +++++++++++ .../app/components/login/login.component.html | 1 - .../app/components/login/login.component.ts | 24 ++-- .../components/pages/admin/admin.component.ts | 5 +- .../admin/roles/roles/roles.component.css | 5 + .../admin/roles/roles/roles.component.html | 2 +- .../add-user-modal.component.css | 17 ++- .../add-user-modal.component.ts | 15 ++- .../edit-user-modal.component.css | 24 ++-- .../edit-user-modal.component.html | 3 +- .../edit-user-modal.component.ts | 24 +++- .../admin/users/users/users.component.css | 4 + .../admin/users/users/users.component.html | 2 +- .../admin/users/users/users.component.ts | 4 +- .../pages/admin/users/users/users.service.ts | 2 +- package-lock.json | 110 +++++++++++++++++- package.json | 6 + 51 files changed, 1191 insertions(+), 194 deletions(-) create mode 100644 ogWebconsole/src/app/components/groups/legend/legend.component.css create mode 100644 ogWebconsole/src/app/components/groups/legend/legend.component.html create mode 100644 ogWebconsole/src/app/components/groups/legend/legend.component.spec.ts create mode 100644 ogWebconsole/src/app/components/groups/legend/legend.component.ts create mode 100644 ogWebconsole/src/app/components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component.css create mode 100644 ogWebconsole/src/app/components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component.html create mode 100644 ogWebconsole/src/app/components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component.spec.ts create mode 100644 ogWebconsole/src/app/components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component.ts create mode 100644 ogWebconsole/src/app/components/groups/tree-view/tree-view.component.css create mode 100644 ogWebconsole/src/app/components/groups/tree-view/tree-view.component.html create mode 100644 ogWebconsole/src/app/components/groups/tree-view/tree-view.component.spec.ts create mode 100644 ogWebconsole/src/app/components/groups/tree-view/tree-view.component.ts create mode 100644 package.json diff --git a/ogWebconsole/angular.json b/ogWebconsole/angular.json index 9ffbc13..f9f3df9 100644 --- a/ogWebconsole/angular.json +++ b/ogWebconsole/angular.json @@ -36,7 +36,8 @@ ], "styles": [ "src/custom-theme.scss", - "src/styles.css" + "src/styles.css", + "node_modules/ngx-toastr/toastr.css" ], "scripts": [] }, @@ -104,10 +105,6 @@ } }, "cli": { -<<<<<<< Updated upstream "analytics": "95fac95c-8936-41a8-8c9c-1fae82fe6912" -======= - "analytics": "ba7c0825-8034-43ff-9c60-83dac232db7e" ->>>>>>> Stashed changes } } diff --git a/ogWebconsole/package-lock.json b/ogWebconsole/package-lock.json index edafdbf..01ded5e 100644 --- a/ogWebconsole/package-lock.json +++ b/ogWebconsole/package-lock.json @@ -19,6 +19,7 @@ "@angular/platform-browser-dynamic": "^18.0.0", "@angular/router": "^18.0.0", "jwt-decode": "^4.0.0", + "ngx-toastr": "^19.0.0", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "^0.14.6" @@ -9854,6 +9855,19 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "node_modules/ngx-toastr": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/ngx-toastr/-/ngx-toastr-19.0.0.tgz", + "integrity": "sha512-6pTnktwwWD+kx342wuMOWB4+bkyX9221pAgGz3SHOJH0/MI9erLucS8PeeJDFwbUYyh75nQ6AzVtolgHxi52dQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": ">=16.0.0-0", + "@angular/core": ">=16.0.0-0", + "@angular/platform-browser": ">=16.0.0-0" + } + }, "node_modules/nice-napi": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz", diff --git a/ogWebconsole/package.json b/ogWebconsole/package.json index e5dbf45..ad2a0a8 100644 --- a/ogWebconsole/package.json +++ b/ogWebconsole/package.json @@ -21,6 +21,7 @@ "@angular/platform-browser-dynamic": "^18.0.0", "@angular/router": "^18.0.0", "jwt-decode": "^4.0.0", + "ngx-toastr": "^19.0.0", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "^0.14.6" diff --git a/ogWebconsole/src/app/app.component.css b/ogWebconsole/src/app/app.component.css index ee894d6..958301e 100644 --- a/ogWebconsole/src/app/app.component.css +++ b/ogWebconsole/src/app/app.component.css @@ -1,3 +1,5 @@ + + .sidenav-container { height: 100%; } @@ -6,3 +8,4 @@ .content { padding: 16px; } + diff --git a/ogWebconsole/src/app/app.module.ts b/ogWebconsole/src/app/app.module.ts index 3b27cb0..d60b118 100644 --- a/ogWebconsole/src/app/app.module.ts +++ b/ogWebconsole/src/app/app.module.ts @@ -1,4 +1,6 @@ -import { NgModule } from '@angular/core'; +// @ts-ignore + +import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @@ -43,16 +45,29 @@ import { DeleteModalComponent } from './components/groups/delete-modal/delete-mo import { EditOrganizationalUnitComponent } from './components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component'; import { EditClientComponent } from './components/groups/clients/edit-client/edit-client.component'; import { ClassroomViewComponent } from './components/groups/classroom-view/classroom-view.component'; - import {MatProgressSpinner} from "@angular/material/progress-spinner"; import {MatMenu, MatMenuItem, MatMenuTrigger} from "@angular/material/menu"; import {MatAutocomplete} from "@angular/material/autocomplete"; -import {MatChip, MatChipListbox, MatChipOption, MatChipSet} from "@angular/material/chips"; +import {MatChip, MatChipListbox, MatChipOption, MatChipSet, MatChipsModule} from "@angular/material/chips"; import { ClientViewComponent } from './components/groups/client-view/client-view.component'; import {MatTab, MatTabGroup} from "@angular/material/tabs"; import {MatTooltip} from "@angular/material/tooltip"; import { DeleteGroupsModalComponent } from './components/groups/delete-groups-modal/delete-groups-modal.component'; +import { ToastrModule } from 'ngx-toastr'; +import { ShowOrganizationalUnitComponent } from './components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component'; +import {MatGridList} from "@angular/material/grid-list"; +import { TreeViewComponent } from './components/groups/tree-view/tree-view.component'; +import { + MatNestedTreeNode, + MatTree, + MatTreeNode, + MatTreeNodeDef, MatTreeNodeOutlet, + MatTreeNodePadding, + MatTreeNodeToggle +} from "@angular/material/tree"; +import { LegendComponent } from './components/groups/legend/legend.component'; + @NgModule({ declarations: [ AppComponent, AuthLayoutComponent, @@ -78,7 +93,10 @@ import { DeleteGroupsModalComponent } from './components/groups/delete-groups-mo EditClientComponent, ClassroomViewComponent, ClientViewComponent, - DeleteGroupsModalComponent + DeleteGroupsModalComponent, + ShowOrganizationalUnitComponent, + TreeViewComponent, + LegendComponent ], bootstrap: [AppComponent], imports: [BrowserModule, @@ -100,7 +118,21 @@ import { DeleteGroupsModalComponent } from './components/groups/delete-groups-mo MatSelectModule, MatDividerModule, MatStepperModule, - MatSlideToggleModule, MatMenu, MatMenuTrigger, MatMenuItem, MatAutocomplete, MatChipListbox, MatChipOption, MatChipSet, MatChip, MatProgressSpinner, MatTabGroup, MatTab, MatTooltip], + MatSlideToggleModule, MatMenu, MatMenuTrigger, MatMenuItem, MatAutocomplete, MatChipListbox, MatChipOption, MatChipSet, MatChipsModule, MatChip, MatProgressSpinner, MatTabGroup, MatTab, MatTooltip, + ToastrModule.forRoot( + { + timeOut: 5000, + positionClass: 'toast-bottom-right', + preventDuplicates: true, + progressBar: true, + progressAnimation: 'increasing', + closeButton: true + } + ), MatGridList, MatTree, MatTreeNode, MatNestedTreeNode, MatTreeNodeToggle, MatTreeNodeDef, MatTreeNodePadding, MatTreeNodeOutlet + ], + schemas: [ + CUSTOM_ELEMENTS_SCHEMA, + ], providers: [ { provide: HTTP_INTERCEPTORS, @@ -109,5 +141,5 @@ import { DeleteGroupsModalComponent } from './components/groups/delete-groups-mo }, provideAnimationsAsync(), provideHttpClient(withInterceptorsFromDi()) - ] }) + ], }) export class AppModule { } diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css index ea072ec..47667ca 100644 --- a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css @@ -2,8 +2,7 @@ display: flex; flex-wrap: wrap; gap: 10px; - height: 57vh; - overflow-y: auto; + min-height: 43vh; } .classroom-group { @@ -11,10 +10,21 @@ background-color: #fafafa; } +mat-card { + width: 150px; +} + +mat-chip { + margin: 5px; + font-size: small; +} + + mat-card-title { display: flex; justify-content: space-between; margin: 10px; + font-size: medium; } .client-row { display: flex; @@ -25,6 +35,7 @@ mat-card-title { .client-container { margin: 5px; + padding-bottom: 20px; } .client-box { @@ -34,14 +45,15 @@ mat-card-title { box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1); border-radius: 5px; cursor: pointer; + transition: box-shadow 0.3s ease-in-out, transform 0.3s ease-in-out; } .client-box:hover { box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.2); - scale: 1.1; - transition: 0.3s ease-in-out; + transform: scale(1.2); } .client-box p { margin: 0; } + diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html index 5243026..7fd84b6 100644 --- a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html @@ -9,14 +9,10 @@ {{ client.name }} - - - {{ client.ip }} - - - {{ client.mac }} - - + + {{ client.ip }} + {{ client.mac }} +
diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts index 0549a65..70f244a 100644 --- a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts @@ -58,7 +58,6 @@ export class ClassroomViewComponent implements OnInit { } handleClientClick(client: any): void { - console.log('Client clicked:', client); - const dialogRef = this.dialog.open(ClientViewComponent, { data: { client }, width: '700px', height:'700px'}); + const dialogRef = this.dialog.open(ClientViewComponent, { data: { client }, width: '800px', height:'700px'}); } } diff --git a/ogWebconsole/src/app/components/groups/client-view/client-view.component.css b/ogWebconsole/src/app/components/groups/client-view/client-view.component.css index 0ce046b..65254cb 100644 --- a/ogWebconsole/src/app/components/groups/client-view/client-view.component.css +++ b/ogWebconsole/src/app/components/groups/client-view/client-view.component.css @@ -1,12 +1,4 @@ -.mat-dialog-content { - padding: 20px; -} - -.button-column { - display: flex; - flex-direction: column; - gap: 20px; - margin: 20px; +mat-dialog-content { padding: 20px; } @@ -39,3 +31,27 @@ background-color: #9c27b0; /* Púrpura */ color: white; } + +table { + width: 100%; +} + +.fixed-column { + width: 300px; +} + +.mat-elevation-z8 { + box-shadow: 0px 4px 6px rgba(0,0,0,0.2); +} + +.button-column { + display: flex; + flex-direction: column; + gap: 10px; + align-items: center; +} + +.button-action { + width: 200px; +} + diff --git a/ogWebconsole/src/app/components/groups/client-view/client-view.component.html b/ogWebconsole/src/app/components/groups/client-view/client-view.component.html index 3e02ffa..3519f4e 100644 --- a/ogWebconsole/src/app/components/groups/client-view/client-view.component.html +++ b/ogWebconsole/src/app/components/groups/client-view/client-view.component.html @@ -2,39 +2,59 @@
- - Nombre: {{ data.client.name }} - IP: {{ data.client.ip }} - MAC: {{data.client.mac }} - Nº de serie: {{data.client.serialNumber }} - Netiface: {{data.client.netiface }} - Fecha de creación: {{data.client.createdAt | date }} - Creado por: {{data.client.createdBy }} - + + + + + + + + + + + +
Propiedad {{element.property}} Valor {{element.value}}
- - Menu: {{ data.client.menu }} - Perfil hardware: {{ data.client.hardwareProfile }} - OGlive: {{data.client.mac }} - Autoexec: {{data.client.serialNumber }} - Repositorio: {{data.client.netiface }} - Validacion: {{data.client.netiface }} - Página login: {{data.client.netiface }} - Página validacion: {{data.client.netiface }} - Fecha de creación: {{data.client.createdAt | date }} - Creado por: {{data.client.createdBy }} - + + + + + + + + + + + +
Propiedad {{element.property}} Valor {{element.value}}
+
+ + + + + + + + + + + + +
Propiedad {{element.property}} Valor {{element.value}}
- - - - - - + + + + + +
+ + + diff --git a/ogWebconsole/src/app/components/groups/client-view/client-view.component.ts b/ogWebconsole/src/app/components/groups/client-view/client-view.component.ts index f31c7d3..dda2b48 100644 --- a/ogWebconsole/src/app/components/groups/client-view/client-view.component.ts +++ b/ogWebconsole/src/app/components/groups/client-view/client-view.component.ts @@ -1,5 +1,5 @@ import {Component, Inject} from '@angular/core'; -import {MAT_DIALOG_DATA} from "@angular/material/dialog"; +import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog"; @Component({ selector: 'app-client-view', @@ -7,8 +7,56 @@ import {MAT_DIALOG_DATA} from "@angular/material/dialog"; styleUrl: './client-view.component.css' }) export class ClientViewComponent { + + displayedColumns: string[] = ['property', 'value']; + + generalData = [ + {property: 'Nombre', value: this.data.client.name}, + {property: 'Uuid', value: this.data.client.uuid}, + {property: 'IP', value: this.data.client.ip}, + {property: 'MAC', value: this.data.client.mac}, + {property: 'Nº de serie', value: this.data.client.serialNumber}, + {property: 'Netiface', value: this.data.client.netiface}, + {property: 'Fecha de creación', value: this.data.client.createdAt}, + {property: 'Creado por', value: this.data.client.createdBy} + ]; + + networkData = [ + {property: 'Menu', value: this.data.client.menu}, + {property: 'Perfil hardware', value: this.data.client.hardwareProfile ? this.data.client.hardwareProfile.description : ''}, + {property: 'OGlive', value: ''}, + {property: 'Autoexec', value: ''}, + {property: 'Repositorio', value: ''}, + {property: 'Validacion', value: ''}, + {property: 'Página login', value: ''}, + {property: 'Página validacion', value: ''}, + {property: 'Fecha de creación', value: this.data.client.createdAt}, + {property: 'Creado por', value: this.data.client.createdBy} + ]; + + classroomData = [ + {property: 'Url servidor proxy', value: this.data.client.networkSettings ? this.data.client.networkSettings.proxy : ''}, + {property: 'IP DNS', value: this.data.client.networkSettings ? this.data.client.networkSettings.dns : ''}, + {property: 'Máscara de red', value: this.data.client.networkSettings ? this.data.client.networkSettings.mask : ''}, + {property: 'Router', value: this.data.client.networkSettings ? this.data.client.networkSettings.router : ''}, + {property: 'NTP', value: this.data.client.networkSettings ? this.data.client.networkSettings.ntp : ''}, + {property: 'Modo p2p', value: this.data.client.networkSettings ? this.data.client.networkSettings.p2pMode : ''}, + {property: 'Tiempo p2p', value: this.data.client.networkSettings ? this.data.client.networkSettings.p2pTime : ''}, + {property: 'IP multicast', value: this.data.client.networkSettings ? this.data.client.networkSettings.mcastIp : ''}, + {property: 'Modo multicast', value: this.data.client.networkSettings ? this.data.client.networkSettings.mcastMode : ''}, + {property: 'Puerto multicast', value: this.data.client.networkSettings ? this.data.client.networkSettings.mcastPort : ''}, + {property: 'Velocidad multicast', value: this.data.client.networkSettings ? this.data.client.networkSettings.mcastSpeed : ''}, + {property: 'Perfil hardware', value: this.data.client.networkSettings && this.data.client.networkSettings.hardwareProfile ? this.data.client.networkSettings.hardwareProfile.description : ''}, + {property: 'Menú', value: this.data.client.networkSettings && this.data.client.networkSettings.menu ? this.data.client.networkSettings.menu.description : ''} + ]; + constructor( + private dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: any // Inject data for edit mode ) { } + + onNoClick(): void { + this.dialogRef.close(); + } } diff --git a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.html b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.html index 8044bc3..27c6787 100644 --- a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.html +++ b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.html @@ -19,14 +19,20 @@ - Interfaz de Red - Ejemplo: eth0 - + Interfaz de red + + + {{ type.name }} + + - Controlador de Red - Ejemplo: e1000e - + Controlador de red + + + {{ type.name }} + + MAC @@ -48,7 +54,7 @@ Perfil de Hardware - {{ unit.name }} + {{ unit.description }} Formato de URL inválido. diff --git a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts index 78bfea9..dddd84a 100644 --- a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts +++ b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts @@ -3,6 +3,8 @@ import {Component, Inject, OnInit} from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; import {MatSnackBar} from "@angular/material/snack-bar"; +import {ToastrService} from "ngx-toastr"; +import {DataService} from "../../data.service"; @Component({ selector: 'app-create-client', @@ -14,19 +16,29 @@ export class CreateClientComponent implements OnInit { parentUnits: any[] = []; // Array to store parent units fetched from API hardwareProfiles: any[] = []; // Array to store hardware profiles fetched from API private errorForm: boolean = false; + protected netifaceTypes = [ + {"name": 'Eth0', "value": "eth0"}, + {"name": 'Eth1', "value": "eth1"}, + {"name": 'Eth2', "value": "eth2"}, + ]; + protected netDriverTypes = [ + {"name": 'Generic', "value": "generic"}, + ]; constructor( private fb: FormBuilder, private dialogRef: MatDialogRef, private http: HttpClient, private snackBar: MatSnackBar, + private toastService: ToastrService, + private dataService: DataService, @Inject(MAT_DIALOG_DATA) public data: any // Inject data for edit mode ) { } ngOnInit(): void { this.loadParentUnits(); // Load parent units when component initializes - this.loadHardwareProfiles(); // Load hardware profiles when component initializes + this.loadHardwareProfiles(); this.clientForm = this.fb.group({ organizationalUnit: [this.data.organizationalUnit ? this.data.organizationalUnit['@id'] : null, Validators.required], name: ['', Validators.required], @@ -40,6 +52,17 @@ export class CreateClientComponent implements OnInit { }); } + loadHardwareProfiles(): void { + this.dataService.getHardwareProfiles().subscribe( + (data: any[]) => { + this.hardwareProfiles = data; + }, + (error: any) => { + console.error('Error fetching hardware profiles', error); + } + ); + } + loadParentUnits() { const url = 'http://127.0.0.1:8080/organizational-units?page=1&itemsPerPage=10000'; @@ -53,19 +76,6 @@ export class CreateClientComponent implements OnInit { ); } - loadHardwareProfiles() { - const url = 'http://127.0.0.1:8080/hardware-profiles'; - - this.http.get(url).subscribe( - response => { - this.hardwareProfiles = response['hydra:member']; - }, - error => { - console.error('Error fetching hardware profiles:', error); - } - ); - } - onSubmit() { if (this.clientForm.valid) { this.errorForm = false @@ -73,7 +83,8 @@ export class CreateClientComponent implements OnInit { this.http.post('http://127.0.0.1:8080/clients', formData).subscribe( response => { this.dialogRef.close(response); - this.openSnackBar(false, 'Cliente creado exitosamente'); }, + this.openSnackBar(false, 'Cliente creado exitosamente'); + }, error => { console.error('Error during POST:', error); this.errorForm = true @@ -88,8 +99,9 @@ export class CreateClientComponent implements OnInit { } openSnackBar(isError: boolean, message: string) { - this.snackBar.open(message, 'Cerrar', { - panelClass: isError ? ['snackbar-error'] : ['snackbar-success'] - }); + if (isError) { + this.toastService.error(' Error al crear el cliente: ' + message, 'Error'); + } else + this.toastService.success(message, 'Éxito'); } } diff --git a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.html b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.html index 022cd3c..9d427ea 100644 --- a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.html +++ b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.html @@ -16,12 +16,20 @@ - Interfaz de Red - + Interfaz de red + + + {{ type.name }} + + - Controlador de Red - + Controlador de red + + + {{ type.name }} + + MAC @@ -41,7 +49,7 @@ Perfil de Hardware - {{ unit.name }} + {{ unit.description }} Formato de URL inválido. diff --git a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.ts b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.ts index 584fe69..bd1a339 100644 --- a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.ts +++ b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.ts @@ -3,6 +3,8 @@ import {Component, Inject} from '@angular/core'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; import { CreateClientComponent } from '../create-client/create-client.component'; +import {DataService} from "../../data.service"; +import {ToastrService} from "ngx-toastr"; @Component({ selector: 'app-edit-client', @@ -14,11 +16,21 @@ export class EditClientComponent { parentUnits: any[] = []; // Array to store parent units fetched from API hardwareProfiles: any[] = []; // Array to store hardware profiles fetched from API isEditMode: boolean; // Flag to check if it's edit mode + protected netifaceTypes = [ + {"name": 'Eth0', "value": "eth0"}, + {"name": 'Eth1', "value": "eth1"}, + {"name": 'Eth2', "value": "eth2"}, + ]; + protected netDriverTypes = [ + {"name": 'Generic', "value": "generic"}, + ]; constructor( private fb: FormBuilder, private dialogRef: MatDialogRef, private http: HttpClient, + private dataService: DataService, + private toastService: ToastrService, @Inject(MAT_DIALOG_DATA) public data: any // Inject data for edit mode ) { this.isEditMode = !!data?.uuid; // Check if uuid is passed to determine edit mode @@ -56,15 +68,13 @@ export class EditClientComponent { ); } - loadHardwareProfiles() { - const url = 'http://127.0.0.1:8080/hardware-profiles'; - - this.http.get(url).subscribe( - response => { - this.hardwareProfiles = response['hydra:member']; + loadHardwareProfiles(): void { + this.dataService.getHardwareProfiles().subscribe( + (data: any[]) => { + this.hardwareProfiles = data; }, - error => { - console.error('Error fetching hardware profiles:', error); + (error: any) => { + console.error('Error fetching hardware profiles', error); } ); } @@ -101,9 +111,12 @@ export class EditClientComponent { response => { console.log('PUT successful:', response); this.dialogRef.close(); + this.openSnackBar(false, 'Cliente actualizado exitosamente'); + }, error => { console.error('Error al realizar PUT:', error); + this.openSnackBar(true, 'Error al actualizar el cliente: ' + error.error['hydra:description']); } ); } else { @@ -115,9 +128,11 @@ export class EditClientComponent { response => { console.log('POST successful:', response); this.dialogRef.close(); + this.openSnackBar(false, 'Cliente creado exitosamente'); }, error => { console.error('Error al realizar POST:', error); + this.openSnackBar(true, 'Error al crear el cliente: ' + error.error['hydra:description']); } ); } @@ -127,4 +142,11 @@ export class EditClientComponent { onNoClick(): void { this.dialogRef.close(); } + + openSnackBar(isError: boolean, message: string) { + if (isError) { + this.toastService.error(' Error al crear el cliente: ' + message, 'Error'); + } else + this.toastService.success(message, 'Éxito'); + } } diff --git a/ogWebconsole/src/app/components/groups/data.service.ts b/ogWebconsole/src/app/components/groups/data.service.ts index 2b9ace5..9b0f503 100644 --- a/ogWebconsole/src/app/components/groups/data.service.ts +++ b/ogWebconsole/src/app/components/groups/data.service.ts @@ -14,11 +14,16 @@ export class DataService { constructor(private http: HttpClient) {} - getOrganizationalUnits(): Observable { - return this.http.get(`${this.apiUrl}&type=organizational-unit`).pipe( + getOrganizationalUnits(search: string = ''): Observable { + let url = `${this.apiUrl}&type=organizational-unit`; + if (search) { + url += `&name=${encodeURIComponent(search)}`; + } + + return this.http.get(url).pipe( map(response => { if (response['hydra:member'] && Array.isArray(response['hydra:member'])) { - return response['hydra:member'] + return response['hydra:member']; } else { throw new Error('Unexpected response format'); } @@ -62,6 +67,23 @@ export class DataService { ); } + getHardwareProfiles(): Observable { + const url = 'http://127.0.0.1:8080/hardware-profiles'; + return this.http.get(url).pipe( + map(response => { + if (response['hydra:member'] && Array.isArray(response['hydra:member'])) { + return response['hydra:member'] + } else { + throw new Error('Unexpected response format'); + } + }), + catchError(error => { + console.error('Error fetching clients', error); + return throwError(error); + }) + ); + } + deleteElement(uuid: string, type: string): Observable { const url = type === 'client' ? `http://127.0.0.1:8080/clients/${uuid}` diff --git a/ogWebconsole/src/app/components/groups/groups.component.css b/ogWebconsole/src/app/components/groups/groups.component.css index bf6b4bd..3ceb1dd 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.css +++ b/ogWebconsole/src/app/components/groups/groups.component.css @@ -3,6 +3,16 @@ flex-wrap: wrap; } +.search-container { + display: flex; + flex-grow: 1; + margin: 10px; +} + +.search-container mat-form-field { + width: 50%; +} + .card { flex-grow: 1; margin: 10px; @@ -15,7 +25,8 @@ .unidad-card, .elements-card { flex: 1 1 45%; background-color: #fafafa; - max-height: 400px; + height: 400px; + overflow-y: auto; } .element-content { diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html index d655b26..2132e84 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.html +++ b/ogWebconsole/src/app/components/groups/groups.component.html @@ -1,37 +1,61 @@

Administrar grupos

- - + + +
+
+ + Búsqueda + + search + Pulsar 'enter' para buscar entre las unidades organizativas + +
- Unidad organizativa + Unidad organizativa - + +
apartment {{ unidad.name }} + account_tree + edit visibility + + add_home_work devices @@ -56,8 +80,8 @@
- - + +
info No hay elementos internos @@ -66,7 +90,7 @@
apartment - groups + meeting_room school computer lan @@ -74,9 +98,11 @@ {{child.name}} - edit - devices - delete + edit + visibility + add_home_work + devices + delete
diff --git a/ogWebconsole/src/app/components/groups/groups.component.ts b/ogWebconsole/src/app/components/groups/groups.component.ts index e34873a..6f5edb4 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.ts +++ b/ogWebconsole/src/app/components/groups/groups.component.ts @@ -7,7 +7,12 @@ import { DeleteModalComponent } from './delete-modal/delete-modal.component'; import { CreateClientComponent } from './clients/create-client/create-client.component'; import { EditOrganizationalUnitComponent } from './organizational-units/edit-organizational-unit/edit-organizational-unit.component'; import { EditClientComponent } from './clients/edit-client/edit-client.component'; -import {DeleteGroupsModalComponent} from "./delete-groups-modal/delete-groups-modal.component"; +import { DeleteGroupsModalComponent } from "./delete-groups-modal/delete-groups-modal.component"; +import { ShowOrganizationalUnitComponent} from "./organizational-units/show-organizational-unit/show-organizational-unit.component"; +import {ToastrService} from "ngx-toastr"; +import {TreeViewComponent} from "./tree-view/tree-view.component"; +import {MatBottomSheet} from "@angular/material/bottom-sheet"; +import {LegendComponent} from "./legend/legend.component"; @Component({ selector: 'app-groups', @@ -23,15 +28,34 @@ export class GroupsComponent implements OnInit { clientsData: any[] = []; // Nueva variable para almacenar los datos de clients breadcrumbData: any[] = []; // Almacenar datos de breadcrumb para navegar loading:boolean = false; -constructor(private dataService: DataService, public dialog: MatDialog) {} + loadingChildren:boolean = false; + searchTerm: string = ''; +constructor( + private dataService: DataService, + public dialog: MatDialog, + private toastService: ToastrService, + private _bottomSheet: MatBottomSheet + ) {} ngOnInit(): void { - this.dataService.getOrganizationalUnits().subscribe( - data => this.organizationalUnits = data, - error => console.error('Error fetching unidades organizativas', error) + this.search(); + } + + search(): void { + this.loading = true; + this.dataService.getOrganizationalUnits(this.searchTerm).subscribe( + data => { + this.organizationalUnits = data; + this.loading = false; // Desactivar el spinner después de obtener los datos + }, + error => { + console.error('Error fetching unidades organizativas', error); + this.loading = false; // Desactivar el spinner en caso de error + } ); } + onSelectUnidad(unidad: UnidadOrganizativa): void { this.selectedUnidad = unidad; this.selectedDetail = unidad; // Mostrar detalles de la unidad seleccionada @@ -61,7 +85,7 @@ constructor(private dataService: DataService, public dialog: MatDialog) {} } loadChildrenAndClients(id: string): void { - this.loading = true + this.loadingChildren = true this.dataService.getChildren(id).subscribe( childrenData => { console.log('Children data:', childrenData); @@ -74,44 +98,51 @@ constructor(private dataService: DataService, public dialog: MatDialog) {} this.children = newChildren; } else { this.children = []; // Limpiar card2 cuando no hay elementos - - // Si deseas que la unidad organizativa se limpie completamente, descomenta la línea siguiente: - // this.selectedUnidad = null; } + this.loadingChildren = false }, error => { console.error('Error fetching clients', error); this.clientsData = []; // Limpiar clientsData en caso de error this.children = []; // Limpiar card2 en caso de error + this.loadingChildren = false } ); }, error => { console.error('Error fetching children', error); this.children = []; // Limpiar card2 en caso de error + this.loadingChildren = false } ); - this.loading = false } - addOU(parent:any = null): void { - console.log('Parent:', parent); + addOU(event: MouseEvent, parent:any = null): void { + event.stopPropagation(); const dialogRef = this.dialog.open(CreateOrganizationalUnitComponent, { data: { parent }, width: '700px'}); dialogRef.afterClosed().subscribe(() => { this.dataService.getOrganizationalUnits().subscribe( - data => this.organizationalUnits = data, + data => { + this.organizationalUnits = data + this.loadChildrenAndClients(parent.id); + }, error => console.error('Error fetching unidades organizativas', error) ); }); } - addClient(organizationalUnit:any = null): void { + addClient(event: MouseEvent, organizationalUnit:any = null): void { + event.stopPropagation(); + const dialogRef = this.dialog.open(CreateClientComponent, { data: { organizationalUnit }, width: '700px'}); // Subscribirse al evento unitAdded del componente de creación después de cerrar el diálogo dialogRef.afterClosed().subscribe(() => { this.dataService.getOrganizationalUnits().subscribe( - data => this.organizationalUnits = data, + data => { + this.organizationalUnits = data + this.loadChildrenAndClients(organizationalUnit.id); + }, error => console.error('Error fetching unidades organizativas', error) ); }); @@ -134,7 +165,7 @@ constructor(private dataService: DataService, public dialog: MatDialog) {} data => this.organizationalUnits = data, error => console.error('Error fetching unidades organizativas', error) ); - + this.openSnackBar(false, 'Entidad eliminada exitosamente') }, error => console.error('Error deleting element', error) ); @@ -155,8 +186,12 @@ constructor(private dataService: DataService, public dialog: MatDialog) {} data => this.organizationalUnits = data, error => console.error('Error fetching unidades organizativas', error) ); + this.openSnackBar(false, 'Entidad eliminada exitosamente') }, - error => console.error('Error deleting element', error) + error => { + console.error('Error deleting element', error) + this.openSnackBar(true, error.error['hydra:description']) + } ); } else if (result && result === 'change') { this.dataService.changeParent(uuid).subscribe( @@ -167,14 +202,18 @@ constructor(private dataService: DataService, public dialog: MatDialog) {} error => console.error('Error fetching unidades organizativas', error) ); }, - error => console.error('Error deleting element', error) + error => { + console.error('Error deleting element', error) + this.openSnackBar(true, error.error['hydra:description']) + } ); } }); } } - onEditClick(type: any, uuid: string): void { + onEditClick(event: MouseEvent, type: any, uuid: string): void { + event.stopPropagation(); console.log('Tipo del elemento a editar:', type); console.log('UUID del elemento a editar:', uuid); if (type != "client") { @@ -184,4 +223,29 @@ constructor(private dataService: DataService, public dialog: MatDialog) {} const dialogRef = this.dialog.open(EditClientComponent, { data: { uuid }, width: '700px' } ); } } + + onShowClick(event: MouseEvent, data: any): void { + event.stopPropagation(); + if (data.type != "client") { + const dialogRef = this.dialog.open(ShowOrganizationalUnitComponent, { data: { data }, width: '700px'}); + } + } + + onTreeClick(event: MouseEvent, data: any): void { + event.stopPropagation(); + if (data.type != "client") { + const dialogRef = this.dialog.open(TreeViewComponent, { data: { data }, width: '800px'}); + } + } + + openSnackBar(isError: boolean, message: string) { + if (isError) { + this.toastService.error(' Error al eliminar la entidad: ' + message, 'Error'); + } else + this.toastService.success(message, 'Éxito'); + } + + openBottomSheet(): void { + this._bottomSheet.open(LegendComponent); + } } diff --git a/ogWebconsole/src/app/components/groups/legend/legend.component.css b/ogWebconsole/src/app/components/groups/legend/legend.component.css new file mode 100644 index 0000000..e69de29 diff --git a/ogWebconsole/src/app/components/groups/legend/legend.component.html b/ogWebconsole/src/app/components/groups/legend/legend.component.html new file mode 100644 index 0000000..24929b2 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/legend/legend.component.html @@ -0,0 +1,22 @@ + + + apartment +
Unidad organizativa
+
+ + meeting_room +
Grupos de aula
+
+ + school +
Aula
+
+ + lan +
Grupos de clientes
+
+ + computer +
Cliente
+
+
diff --git a/ogWebconsole/src/app/components/groups/legend/legend.component.spec.ts b/ogWebconsole/src/app/components/groups/legend/legend.component.spec.ts new file mode 100644 index 0000000..db1b102 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/legend/legend.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LegendComponent } from './legend.component'; + +describe('LegendComponent', () => { + let component: LegendComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [LegendComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(LegendComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/ogWebconsole/src/app/components/groups/legend/legend.component.ts b/ogWebconsole/src/app/components/groups/legend/legend.component.ts new file mode 100644 index 0000000..46fbf80 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/legend/legend.component.ts @@ -0,0 +1,16 @@ +import { Component } from '@angular/core'; +import {MatBottomSheetRef} from "@angular/material/bottom-sheet"; + +@Component({ + selector: 'app-legend', + templateUrl: './legend.component.html', + styleUrl: './legend.component.css' +}) +export class LegendComponent { + constructor(private _bottomSheetRef: MatBottomSheetRef) {} + + openLink(event: MouseEvent): void { + this._bottomSheetRef.dismiss(); + event.preventDefault(); + } +} diff --git a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html index 9143c20..de5061d 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html +++ b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html @@ -97,7 +97,13 @@ Modo P2P - + + + {{ option.name }} + + Tiempo P2P @@ -117,7 +123,13 @@ Modo Multicast - + + + {{ option.name }} + + Menú URL @@ -125,7 +137,10 @@ Perfil de Hardware - + + {{ unit.description }} + + Formato de URL inválido.
diff --git a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts index c5ce903..61d38cc 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts +++ b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.ts @@ -2,6 +2,8 @@ import {Component, OnInit, Output, EventEmitter, Inject} from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; import { HttpClient, HttpHeaders } from '@angular/common/http'; +import {ToastrService} from "ngx-toastr"; +import {DataService} from "../../data.service"; @Component({ selector: 'app-create-organizational-unit', @@ -22,13 +24,24 @@ export class CreateOrganizationalUnitComponent implements OnInit { 'clients-group': 'Grupo de clientes' }; parentUnits: any[] = []; - + hardwareProfiles: any[] = []; + protected p2pModeOptions = [ + {"name": 'Leecher', "value": "p2p-mode-leecher"}, + {"name": 'Peer', "value": "p2p-mode-peer"}, + {"name": 'Seeder', "value": "p2p-mode-seeder"}, + ]; + protected multicastModeOptions = [ + {"name": 'Half duplex', "value": "half-duplex"}, + {"name": 'Full duplex', "value": "full-duplex"}, + ]; @Output() unitAdded = new EventEmitter(); constructor( private _formBuilder: FormBuilder, private dialogRef: MatDialogRef, private http: HttpClient, + private toastService: ToastrService, + private dataService: DataService, @Inject(MAT_DIALOG_DATA) public data: any // Inject data for edit mode ) { this.generalFormGroup = this._formBuilder.group({ @@ -52,8 +65,8 @@ export class CreateOrganizationalUnitComponent implements OnInit { mcastSpeed: [0, Validators.min(0)], mcastPort: [0, Validators.min(0)], mcastMode: [''], - menu: ['', Validators.pattern('https?://.+')], - hardwareProfile: ['', Validators.pattern('https?://.+')], + menu: [null], + hardwareProfile: [null], validation: [false] }); this.classroomInfoFormGroup = this._formBuilder.group({ @@ -66,6 +79,7 @@ export class CreateOrganizationalUnitComponent implements OnInit { ngOnInit() { this.loadParentUnits(); + this.loadHardwareProfiles(); } loadParentUnits() { @@ -81,6 +95,17 @@ export class CreateOrganizationalUnitComponent implements OnInit { ); } + loadHardwareProfiles(): void { + this.dataService.getHardwareProfiles().subscribe( + (data: any[]) => { + this.hardwareProfiles = data; + }, + (error: any) => { + console.error('Error fetching hardware profiles', error); + } + ); + } + private cleanFormValues(formGroup: FormGroup): any { const cleanedValues: any = {}; Object.keys(formGroup.controls).forEach(key => { @@ -123,9 +148,11 @@ export class CreateOrganizationalUnitComponent implements OnInit { console.log('POST successful:', response); this.unitAdded.emit(); this.dialogRef.close(); + this.openSnackBar(false, 'Cliente creado exitosamente'); }, error => { console.error('Error al realizar POST:', error); + this.openSnackBar(true, 'Error al crear la unidad organizativa: ' + error.error['hydra:description']); } ); } @@ -134,4 +161,11 @@ export class CreateOrganizationalUnitComponent implements OnInit { onNoClick(): void { this.dialogRef.close(); } + + openSnackBar(isError: boolean, message: string) { + if (isError) { + this.toastService.error(' Error al crear el cliente: ' + message, 'Error'); + } else + this.toastService.success('Cliente creado exitosamente', 'Éxito'); + } } diff --git a/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.html b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.html index 839c4da..b0434c7 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.html +++ b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.html @@ -31,7 +31,28 @@ - + + +
+ Información del Aula + + Ubicación + + + Proyector + Pizarra + + Aforo + + +
+ + +
+
+
+ +
Información Adicional @@ -46,7 +67,7 @@
- +
Configuración de Red @@ -72,7 +93,13 @@ Modo P2P - + + + {{ option.name }} + + Tiempo P2P @@ -92,7 +119,13 @@ Modo Multicast - + + + {{ option.name }} + + Menú URL @@ -100,7 +133,10 @@ Perfil de Hardware - + + {{ unit.description }} + + Formato de URL inválido. Validación
diff --git a/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.ts b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.ts index 6e2de73..280632e 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.ts +++ b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.ts @@ -3,6 +3,8 @@ import { Component, EventEmitter, Inject, OnInit, Output } from '@angular/core'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { CreateOrganizationalUnitComponent } from '../create-organizational-unit/create-organizational-unit.component'; +import {DataService} from "../../data.service"; +import {ToastrService} from "ngx-toastr"; @Component({ selector: 'app-edit-organizational-unit', @@ -14,16 +16,28 @@ export class EditOrganizationalUnitComponent implements OnInit { generalFormGroup: FormGroup; additionalInfoFormGroup: FormGroup; networkSettingsFormGroup: FormGroup; + classroomInfoFormGroup: FormGroup; types: string[] = ['organizational-unit', 'classrooms-group', 'classroom', 'clients-group']; parentUnits: any[] = []; // Array to store parent units fetched from API + hardwareProfiles: any[] = []; isEditMode: boolean; // Flag to check if it's edit mode - + protected p2pModeOptions = [ + {"name": 'Leecher', "value": "p2p-mode-leecher"}, + {"name": 'Peer', "value": "p2p-mode-peer"}, + {"name": 'Seeder', "value": "p2p-mode-seeder"}, + ]; + protected multicastModeOptions = [ + {"name": 'Half duplex', "value": "half-duplex"}, + {"name": 'Full duplex', "value": "full-duplex"}, + ]; @Output() unitAdded = new EventEmitter(); // Event emitter to notify parent component about unit addition constructor( private _formBuilder: FormBuilder, private dialogRef: MatDialogRef, private http: HttpClient, // Inject HttpClient for HTTP requests + private dataService: DataService, + private toastService: ToastrService, @Inject(MAT_DIALOG_DATA) public data: any // Inject data for edit mode ) { this.isEditMode = !!data?.uuid; // Check if uuid is passed to determine edit mode @@ -51,11 +65,18 @@ export class EditOrganizationalUnitComponent implements OnInit { mcastSpeed: [0, Validators.min(0)], mcastPort: [0, Validators.min(0)], mcastMode: [''], - menu: ['', Validators.pattern('https?://.+')], - hardwareProfile: ['', Validators.pattern('https?://.+')], + menu: [null], + hardwareProfile: [null], validation: [false] }); + this.classroomInfoFormGroup = this._formBuilder.group({ + location: [''], + projector: [false], + board: [false], + capacity: [0, Validators.min(0)] + }); + if (this.isEditMode) { this.loadData(data.uuid); } @@ -63,6 +84,7 @@ export class EditOrganizationalUnitComponent implements OnInit { ngOnInit() { this.loadParentUnits(); // Load parent units when component initializes + this.loadHardwareProfiles(); } loadParentUnits() { @@ -78,6 +100,17 @@ export class EditOrganizationalUnitComponent implements OnInit { ); } + loadHardwareProfiles(): void { + this.dataService.getHardwareProfiles().subscribe( + (data: any[]) => { + this.hardwareProfiles = data; + }, + (error: any) => { + console.error('Error fetching hardware profiles', error); + } + ); + } + loadData(uuid: string) { const url = `http://127.0.0.1:8080/organizational-units/${uuid}`; @@ -104,13 +137,21 @@ export class EditOrganizationalUnitComponent implements OnInit { mcastSpeed: data.networkSettings.mcastSpeed, mcastPort: data.networkSettings.mcastPort, mcastMode: data.networkSettings.mcastMode, - menu: data.networkSettings.menu, - hardwareProfile: data.networkSettings.hardwareProfile, + menu: data.networkSettings.menu ? data.networkSettings.menu['@id'] : null, + hardwareProfile: data.networkSettings.hardwareProfile ? data.networkSettings.hardwareProfile['@id'] : null, validation: data.networkSettings.validation }); + this.classroomInfoFormGroup.patchValue({ + location: data.classroomInfo.location, + projector: data.classroomInfo.projector, + board: data.classroomInfo.board, + capacity: data.classroomInfo.capacity + }); }, error => { console.error('Error fetching data for edit:', error); + this.openSnackBar(true, 'Error al cargar la unidad organizativa: ' + error.error['hydra:description']) + this.onNoClick() } ); } @@ -153,9 +194,11 @@ export class EditOrganizationalUnitComponent implements OnInit { console.log('POST successful:', response); this.unitAdded.emit(); this.dialogRef.close(); + this.openSnackBar(false, 'Cliente creado exitosamente'); }, error => { console.error('Error al realizar POST:', error); + this.openSnackBar(true, 'Error al crear la unidad organizativa: ' + error.error['hydra:description']); } ); } @@ -165,4 +208,11 @@ export class EditOrganizationalUnitComponent implements OnInit { onNoClick(): void { this.dialogRef.close(); } + + openSnackBar(isError: boolean, message: string) { + if (isError) { + this.toastService.error(' Error al crear el cliente: ' + message, 'Error'); + } else + this.toastService.success('Cliente creado exitosamente', 'Éxito'); + } } diff --git a/ogWebconsole/src/app/components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component.css b/ogWebconsole/src/app/components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component.css new file mode 100644 index 0000000..21236d6 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component.css @@ -0,0 +1,26 @@ +mat-dialog-content { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; +} + +table { + width: 80%; + margin: 20px 0; +} + +.mat-elevation-z8 { + box-shadow: 0px 0px 0px rgba(0, 0, 0, 0.2); +} + +.button-column { + display: flex; + flex-direction: column; + gap: 10px; + align-items: center; +} + +button { + width: 200px; +} diff --git a/ogWebconsole/src/app/components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component.html b/ogWebconsole/src/app/components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component.html new file mode 100644 index 0000000..61639be --- /dev/null +++ b/ogWebconsole/src/app/components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component.html @@ -0,0 +1,43 @@ +

Propiedades unidad organizativa

+
+ + + + + + + + + + + + + +
Propiedad {{ element.property }} Valor {{ element.value }}
+
+ + + + + + + + + + + + +
Propiedad {{ element.property }} Valor {{ element.value }}
+
+ +
+ + + + + + +
+
+
+
diff --git a/ogWebconsole/src/app/components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component.spec.ts b/ogWebconsole/src/app/components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component.spec.ts new file mode 100644 index 0000000..7b18886 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ShowOrganizationalUnitComponent } from './show-organizational-unit.component'; + +describe('ShowOrganizationalUnitComponent', () => { + let component: ShowOrganizationalUnitComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ShowOrganizationalUnitComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ShowOrganizationalUnitComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/ogWebconsole/src/app/components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component.ts b/ogWebconsole/src/app/components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component.ts new file mode 100644 index 0000000..61e45a2 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component.ts @@ -0,0 +1,48 @@ +import {Component, Inject} from '@angular/core'; +import {MAT_DIALOG_DATA} from "@angular/material/dialog"; + +@Component({ + selector: 'app-show-organizational-unit', + templateUrl: './show-organizational-unit.component.html', + styleUrl: './show-organizational-unit.component.css' +}) +export class ShowOrganizationalUnitComponent { + + displayedColumns: string[] = ['property', 'value']; + + generalData = [ + { property: 'Nombre', value: this.data.data.name }, + { property: 'Uuid', value: this.data.data.uuid }, + { property: 'Comentarios', value: this.data.data.comments }, + { property: 'Tipo', value: this.data.data.type }, + { property: 'Unidad organizativa superior', value: this.data.data.parent ? this.data.data.parent.name : '-' }, + { property: 'Creado por', value: this.data.data.createdBy }, + { property: 'Creado el', value: this.data.data.createdAt } + ]; + + networkData = [ + { property: 'Localización', value: this.data.data.location }, + { property: 'Proyector', value: this.data.data.projector ? 'Sí' : 'No' }, + { property: 'Pizzarra', value: this.data.data.board ? 'Sí' : 'No' }, + { property: 'Aforo', value: this.data.data.capacity }, + { property: 'Url servidor proxy', value: this.data.data.networkSettings ? this.data.data.networkSettings.proxy : '' }, + { property: 'IP DNS', value: this.data.data.networkSettings ? this.data.data.networkSettings.dns : '' }, + { property: 'Máscara de red', value: this.data.data.networkSettings ? this.data.data.networkSettings.mask : '' }, + { property: 'Router', value: this.data.data.networkSettings ? this.data.data.networkSettings.router : '' }, + { property: 'NTP', value: this.data.data.networkSettings ? this.data.data.networkSettings.ntp : '' }, + { property: 'Modo p2p', value: this.data.data.networkSettings ? this.data.data.networkSettings.p2pMode : '' }, + { property: 'Tiempo p2p', value: this.data.data.networkSettings ? this.data.data.networkSettings.p2pTime : '' }, + { property: 'IP multicast', value: this.data.data.networkSettings ? this.data.data.networkSettings.mcastIp : '' }, + { property: 'Modo multicast', value: this.data.data.networkSettings ? this.data.data.networkSettings.mcastMode : '' }, + { property: 'Puerto multicast', value: this.data.data.networkSettings ? this.data.data.networkSettings.mcastPort : '' }, + { property: 'Velocidad multicast', value: this.data.data.networkSettings ? this.data.data.networkSettings.mcastSpeed : '' }, + { property: 'Perfil hardware', value: this.data.data.networkSettings && this.data.data.networkSettings.hardwareProfile ? this.data.data.networkSettings.hardwareProfile.description : '' }, + { property: 'Menú', value: this.data.data.networkSettings && this.data.data.networkSettings.menu ? this.data.data.networkSettings.menu.description : '' } + ]; + + constructor( + @Inject(MAT_DIALOG_DATA) public data: any // Inject data for edit mode + ) { + console.log(this.data) + } +} diff --git a/ogWebconsole/src/app/components/groups/tree-view/tree-view.component.css b/ogWebconsole/src/app/components/groups/tree-view/tree-view.component.css new file mode 100644 index 0000000..5e7e53a --- /dev/null +++ b/ogWebconsole/src/app/components/groups/tree-view/tree-view.component.css @@ -0,0 +1,40 @@ +mat-content { + padding: 20px; +} + +.item-content { + display: flex; + width: 100%; + padding: 10px; +} + +.item-content mat-icon { + margin-right: 10px; +} + +.tree-invisible { + display: none; +} + +.tree ul, +.tree li { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +/* + * This padding sets alignment of the nested nodes. + */ +.tree .mat-nested-tree-node div[role=group] { + padding-left: 40px; +} + +/* + * Padding for leaf nodes. + * Leaf nodes need to have padding so as to align with other non-leaf nodes + * under the same parent. + */ +.tree div[role=group] > .mat-tree-node { + padding-left: 40px; +} diff --git a/ogWebconsole/src/app/components/groups/tree-view/tree-view.component.html b/ogWebconsole/src/app/components/groups/tree-view/tree-view.component.html new file mode 100644 index 0000000..4c4e7ec --- /dev/null +++ b/ogWebconsole/src/app/components/groups/tree-view/tree-view.component.html @@ -0,0 +1,55 @@ +

Visualizar arbol unidad Organizativa

+ + + + + + apartment + meeting_room + school + computer + lan + help_outline + + {{node.name}} + + + +
+ +
+ + apartment + meeting_room + school + computer + lan + help_outline + + {{node.name}} +
+
+ +
+ + + + computer + {{ client.name }} + {{ client.ip }} | {{ client.mac }} + + +
+
+
+
+ + + diff --git a/ogWebconsole/src/app/components/groups/tree-view/tree-view.component.spec.ts b/ogWebconsole/src/app/components/groups/tree-view/tree-view.component.spec.ts new file mode 100644 index 0000000..2f4b128 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/tree-view/tree-view.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TreeViewComponent } from './tree-view.component'; + +describe('TreeViewComponent', () => { + let component: TreeViewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [TreeViewComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TreeViewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/ogWebconsole/src/app/components/groups/tree-view/tree-view.component.ts b/ogWebconsole/src/app/components/groups/tree-view/tree-view.component.ts new file mode 100644 index 0000000..4f6d76e --- /dev/null +++ b/ogWebconsole/src/app/components/groups/tree-view/tree-view.component.ts @@ -0,0 +1,70 @@ +import {Component, Inject, OnInit} from '@angular/core'; +import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog"; +import {NestedTreeControl} from "@angular/cdk/tree"; +import {MatTreeNestedDataSource} from "@angular/material/tree"; + +interface OrganizationalUnit { + id: number; + name: string; + type: string; + clients?: Client[]; + children?: OrganizationalUnit[]; +} + +interface Client { + id: number; + name: string; + ip: string; + mac: string; + serialNumber: string; +} + +@Component({ + selector: 'app-tree-view', + templateUrl: './tree-view.component.html', + styleUrl: './tree-view.component.css' +}) +export class TreeViewComponent implements OnInit { + treeControl = new NestedTreeControl(node => node.children); + dataSource = new MatTreeNestedDataSource(); + + constructor( + private dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any + ) { + } + ngOnInit() { + this.dataSource.data = [this.mapData(this.data.data)]; + } + + hasChild = (_: number, node: OrganizationalUnit) => (!!node.children && node.children.length > 0 || !!node.clients && node.clients.length > 0); + + private mapData(data: any): OrganizationalUnit { + const mapClients = (clients: any[]): Client[] => { + console.log(clients) + return clients.map(client => ({ + id: client.id, + name: client.name, + ip: client.ip, + mac: client.mac, + serialNumber: client.serialNumber, + })); + }; + + const mapChildren = (children: any[]): OrganizationalUnit[] => { + return children.map(child => this.mapData(child)); + }; + + return { + id: data.id, + name: data.name, + type: data.type, + clients: data.clients ? mapClients(data.clients) : [], + children: data.children ? mapChildren(data.children) : [] + }; + } + + close(): void { + this.dialogRef.close(); + } +} diff --git a/ogWebconsole/src/app/components/login/login.component.html b/ogWebconsole/src/app/components/login/login.component.html index 2ff21d5..1ddffba 100644 --- a/ogWebconsole/src/app/components/login/login.component.html +++ b/ogWebconsole/src/app/components/login/login.component.html @@ -23,6 +23,5 @@
-
{{ errorMessage }}
diff --git a/ogWebconsole/src/app/components/login/login.component.ts b/ogWebconsole/src/app/components/login/login.component.ts index a4d7a8e..de37ed7 100644 --- a/ogWebconsole/src/app/components/login/login.component.ts +++ b/ogWebconsole/src/app/components/login/login.component.ts @@ -1,6 +1,7 @@ import { HttpClient } from '@angular/common/http'; import {Component, signal} from '@angular/core'; import { Router } from '@angular/router'; +import {ToastrService} from "ngx-toastr"; @Component({ selector: 'app-login', @@ -15,7 +16,11 @@ export class LoginComponent { errorMessage: string = ''; isLoading: boolean = false; - constructor(private http: HttpClient, private router: Router) { } + constructor( + private http: HttpClient, + private router: Router, + private toastService: ToastrService, + ) { } onLogin() { this.errorMessage = ''; @@ -44,20 +49,14 @@ export class LoginComponent { localStorage.setItem('loginToken', res.token); localStorage.setItem('refreshToken', res.refreshToken); localStorage.setItem('username', this.loginObj.username); + this.openSnackBar(false, 'Bienvenido ' + this.loginObj.username); this.router.navigateByUrl('/dashboard'); } this.isLoading = false; }, error: (err) => { this.isLoading = false; - if (err.status === 401) { - this.errorMessage = 'Usuario o contraseña incorrectos'; - } else { - this.errorMessage = 'Ha ocurrido un error. Por favor, inténtelo de nuevo.'; - - //BYPASS TO DASHBOARD - /* this.router.navigateByUrl('/dashboard'); */ - } + this.openSnackBar(true, 'Error al iniciar sesion: ' + err.error.message); } }); } @@ -67,4 +66,11 @@ export class LoginComponent { this.hide.set(!this.hide()); event.stopPropagation(); } + + openSnackBar(isError: boolean, message: string) { + if (isError) { + this.toastService.error(message, 'Error'); + } else + this.toastService.success(message, 'Éxito'); + } } diff --git a/ogWebconsole/src/app/components/pages/admin/admin.component.ts b/ogWebconsole/src/app/components/pages/admin/admin.component.ts index ec768d6..c8de9ee 100644 --- a/ogWebconsole/src/app/components/pages/admin/admin.component.ts +++ b/ogWebconsole/src/app/components/pages/admin/admin.component.ts @@ -6,5 +6,8 @@ import { Component } from '@angular/core'; styleUrl: './admin.component.css' }) export class AdminComponent { - + +} + +export class UsersComponent { } diff --git a/ogWebconsole/src/app/components/pages/admin/roles/roles/roles.component.css b/ogWebconsole/src/app/components/pages/admin/roles/roles/roles.component.css index ef18a39..5c924e8 100644 --- a/ogWebconsole/src/app/components/pages/admin/roles/roles/roles.component.css +++ b/ogWebconsole/src/app/components/pages/admin/roles/roles/roles.component.css @@ -14,3 +14,8 @@ table { .header-container h1 { margin: 0; } + +.mat-elevation-z8 { + box-shadow: 0px 0px 0px rgba(0,0,0,0.2); +} + diff --git a/ogWebconsole/src/app/components/pages/admin/roles/roles/roles.component.html b/ogWebconsole/src/app/components/pages/admin/roles/roles/roles.component.html index 3247992..bd5223b 100644 --- a/ogWebconsole/src/app/components/pages/admin/roles/roles/roles.component.html +++ b/ogWebconsole/src/app/components/pages/admin/roles/roles/roles.component.html @@ -2,7 +2,7 @@

Gestión de roles

- +
diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/add-user-modal/add-user-modal.component.css b/ogWebconsole/src/app/components/pages/admin/users/users/add-user-modal/add-user-modal.component.css index 6916e95..4eb0278 100644 --- a/ogWebconsole/src/app/components/pages/admin/users/users/add-user-modal/add-user-modal.component.css +++ b/ogWebconsole/src/app/components/pages/admin/users/users/add-user-modal/add-user-modal.component.css @@ -1,10 +1,9 @@ .user-form .form-field { - display: block; - margin-bottom: 10px; /* Puedes ajustar el valor para cambiar la separación */ - } - - .checkbox-group label { - display: block; - margin-bottom: 8px; /* Ajusta este valor según necesites */ - } - \ No newline at end of file + display: block; + margin-bottom: 10px; /* Puedes ajustar el valor para cambiar la separación */ +} + +.checkbox-group label { + display: block; + margin-bottom: 8px; /* Ajusta este valor según necesites */ +} diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/add-user-modal/add-user-modal.component.ts b/ogWebconsole/src/app/components/pages/admin/users/users/add-user-modal/add-user-modal.component.ts index 1c82b3e..22af5d4 100644 --- a/ogWebconsole/src/app/components/pages/admin/users/users/add-user-modal/add-user-modal.component.ts +++ b/ogWebconsole/src/app/components/pages/admin/users/users/add-user-modal/add-user-modal.component.ts @@ -2,6 +2,7 @@ import { Component, EventEmitter, Inject, OnInit, Output } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { UserService } from '../users.service'; +import {ToastrService} from "ngx-toastr"; interface UserGroup { '@id': string; @@ -24,7 +25,8 @@ export class AddUserModalComponent implements OnInit { public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: any, private fb: FormBuilder, - private userService: UserService // Inyecta el servicio + private userService: UserService, + private toastService: ToastrService ) { this.userForm = this.fb.group({ username: ['', Validators.required], @@ -41,7 +43,7 @@ export class AddUserModalComponent implements OnInit { this.userService.getOrganizationalUnits().subscribe((data) => { this.organizationalUnits = data['hydra:member']; }); - + } onNoClick(): void { @@ -64,12 +66,21 @@ export class AddUserModalComponent implements OnInit { console.log('User added successfully:', response); this.userAdded.emit(); this.dialogRef.close(this.userForm.value); + this.openSnackBar(false, 'Usuario creado correctamente') }, error => { console.error('Error adding user:', error); + this.openSnackBar(true, error.error['hydra:description']); // Agregar alguna lógica para manejar el error en la interfaz de usuario } ); } } + + openSnackBar(isError: boolean, message: string) { + if (isError) { + this.toastService.error(' Error al eliminar la entidad: ' + message, 'Error'); + } else + this.toastService.success(message, 'Éxito'); + } } diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/edit-user-modal/edit-user-modal.component.css b/ogWebconsole/src/app/components/pages/admin/users/users/edit-user-modal/edit-user-modal.component.css index 6916e95..44b82d0 100644 --- a/ogWebconsole/src/app/components/pages/admin/users/users/edit-user-modal/edit-user-modal.component.css +++ b/ogWebconsole/src/app/components/pages/admin/users/users/edit-user-modal/edit-user-modal.component.css @@ -1,10 +1,16 @@ .user-form .form-field { - display: block; - margin-bottom: 10px; /* Puedes ajustar el valor para cambiar la separación */ - } - - .checkbox-group label { - display: block; - margin-bottom: 8px; /* Ajusta este valor según necesites */ - } - \ No newline at end of file + display: block; + margin-bottom: 10px; /* Puedes ajustar el valor para cambiar la separación */ +} + +.checkbox-group label { + display: block; + margin-bottom: 8px; /* Ajusta este valor según necesites */ +} + +.loading-container{ + display: flex; + justify-content: center; + align-items: center; + height: 100%; +} diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/edit-user-modal/edit-user-modal.component.html b/ogWebconsole/src/app/components/pages/admin/users/users/edit-user-modal/edit-user-modal.component.html index 447eb5d..39610df 100644 --- a/ogWebconsole/src/app/components/pages/admin/users/users/edit-user-modal/edit-user-modal.component.html +++ b/ogWebconsole/src/app/components/pages/admin/users/users/edit-user-modal/edit-user-modal.component.html @@ -1,5 +1,6 @@

Editar Usuario

-
+ +
Nombre de usuario diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/edit-user-modal/edit-user-modal.component.ts b/ogWebconsole/src/app/components/pages/admin/users/users/edit-user-modal/edit-user-modal.component.ts index 3a18cf1..0cbd03c 100644 --- a/ogWebconsole/src/app/components/pages/admin/users/users/edit-user-modal/edit-user-modal.component.ts +++ b/ogWebconsole/src/app/components/pages/admin/users/users/edit-user-modal/edit-user-modal.component.ts @@ -2,6 +2,7 @@ import { Component, EventEmitter, Inject, OnInit, Output } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { UserService } from '../users.service'; +import {ToastrService} from "ngx-toastr"; @Component({ selector: 'app-edit-user-modal', @@ -12,28 +13,34 @@ export class EditUserModalComponent implements OnInit {@Output() userEdited = ne userForm: FormGroup; userGroups: any[] = []; organizationalUnits: any[] = []; + loading:boolean = false; constructor( public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: any, private fb: FormBuilder, - private userService: UserService // Inyecta el servicio + private userService: UserService, // Inyecta el servicio + private toastService: ToastrService ) { this.userForm = this.fb.group({ username: [this.data.user.username], - password: [''], + password: [null], userGroups: [this.data.user.userGroups.map((group: { '@id': any; }) => group['@id'])], allowedOrganizationalUnits: [this.data.user.allowedOrganizationalUnits.map((unit: { '@id': any; }) => unit['@id'])] }); - console.log(this.userForm.value) } ngOnInit(): void { + this.loading = true this.userService.getUserGroups().subscribe((data) => { this.userGroups = data['hydra:member']; }); this.userService.getOrganizationalUnits().subscribe((data) => { - this.organizationalUnits = data['hydra:member']; + this.organizationalUnits = data['hydra:member'].filter((item: any) => item.type === 'organizational-unit'); + this.loading = false + }, (error) => { + console.error('Error fetching organizational units', error); + this.loading = false }); } @@ -56,11 +63,20 @@ export class EditUserModalComponent implements OnInit {@Output() userEdited = ne console.log('User added successfully:', response); this.userEdited.emit(); this.dialogRef.close(this.userForm.value); + this.openSnackBar(false, 'Usuario actualizado correctamente') }, error => { console.error('Error adding user:', error); + this.openSnackBar(true, error.message); // Agregar alguna lógica para manejar el error en la interfaz de usuario } ); } + + openSnackBar(isError: boolean, message: string) { + if (isError) { + this.toastService.error(' Error al eliminar la entidad: ' + message, 'Error'); + } else + this.toastService.success(message, 'Éxito'); + } } diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/users.component.css b/ogWebconsole/src/app/components/pages/admin/users/users/users.component.css index ef18a39..42bdbdf 100644 --- a/ogWebconsole/src/app/components/pages/admin/users/users/users.component.css +++ b/ogWebconsole/src/app/components/pages/admin/users/users/users.component.css @@ -14,3 +14,7 @@ table { .header-container h1 { margin: 0; } + +.mat-elevation-z8 { + box-shadow: 0px 0px 0px rgba(0,0,0,0.2); +} diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/users.component.html b/ogWebconsole/src/app/components/pages/admin/users/users/users.component.html index dc3bb9f..115ec9e 100644 --- a/ogWebconsole/src/app/components/pages/admin/users/users/users.component.html +++ b/ogWebconsole/src/app/components/pages/admin/users/users/users.component.html @@ -2,7 +2,7 @@

Gestión de usuarios

-
{{ column.header }}
+
diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/users.component.ts b/ogWebconsole/src/app/components/pages/admin/users/users/users.component.ts index 35bbdf8..2e597b4 100644 --- a/ogWebconsole/src/app/components/pages/admin/users/users/users.component.ts +++ b/ogWebconsole/src/app/components/pages/admin/users/users/users.component.ts @@ -51,7 +51,7 @@ export class UsersComponent implements OnInit { } addUser() { - const dialogRef = this.dialog.open(AddUserModalComponent); + const dialogRef = this.dialog.open(AddUserModalComponent, { width: '500px' }); dialogRef.componentInstance.userAdded.subscribe(() => { this.loadUsers(); @@ -63,7 +63,7 @@ export class UsersComponent implements OnInit { // Implementar la lógica de edición const dialogRef = this.dialog.open(EditUserModalComponent, { data: { user: user }, - width: '400px' + width: '500px' }); dialogRef.componentInstance.userEdited.subscribe(() => { this.loadUsers(); diff --git a/ogWebconsole/src/app/components/pages/admin/users/users/users.service.ts b/ogWebconsole/src/app/components/pages/admin/users/users/users.service.ts index 3e0811a..52338fe 100644 --- a/ogWebconsole/src/app/components/pages/admin/users/users/users.service.ts +++ b/ogWebconsole/src/app/components/pages/admin/users/users/users.service.ts @@ -60,7 +60,7 @@ export class UserService { } getOrganizationalUnits(): Observable { - return this.http.get(`${this.apiUrl}/organizational-units?page=1&itemsPerPage=30`); + return this.http.get(`${this.apiUrl}/organizational-units?page=1&itemsPerPage=10000`); } } diff --git a/package-lock.json b/package-lock.json index d8af095..6b7f1a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2,5 +2,113 @@ "name": "oggui", "lockfileVersion": 3, "requires": true, - "packages": {} + "packages": { + "": { + "dependencies": { + "@angular/animations": "^18.1.0", + "ngx-toastr": "^19.0.0" + } + }, + "node_modules/@angular/animations": { + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.1.0.tgz", + "integrity": "sha512-K0BhvZ/SIVoGXZVuh1KOJDdgcGlHfFGMGrs58utndndAb+gYXReMfz4GR5cQs2OObH6TKmIOY2EH7Og1CY2tsw==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "18.1.0" + } + }, + "node_modules/@angular/common": { + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.1.0.tgz", + "integrity": "sha512-noHDLarQSCZZh7hyNd0HR61Fut+q4QCVq9qc/jKPglfbV/6nPujQSmSpT+rNJlNuBOrCLuvH/CNBNbiqii+x3g==", + "peer": true, + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "18.1.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/core": { + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.1.0.tgz", + "integrity": "sha512-/57/s7CD/0CwlN+3FlhVmx7ypCWXjKi5UKtnlBAUg0D1denIf6ADxwTHFZABYZcYBqOTJgeQUtUw9u/A+0CIlg==", + "peer": true, + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "rxjs": "^6.5.3 || ^7.4.0", + "zone.js": "~0.14.0" + } + }, + "node_modules/@angular/platform-browser": { + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.1.0.tgz", + "integrity": "sha512-jCmxthiI4Zef54crckNht60xwfIsuciGeyZvb7SsXna2maLW9fA4uz1VhZqIWTiBnHwNynVlyfBX3/jBD7S9+g==", + "peer": true, + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/animations": "18.1.0", + "@angular/common": "18.1.0", + "@angular/core": "18.1.0" + }, + "peerDependenciesMeta": { + "@angular/animations": { + "optional": true + } + } + }, + "node_modules/ngx-toastr": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/ngx-toastr/-/ngx-toastr-19.0.0.tgz", + "integrity": "sha512-6pTnktwwWD+kx342wuMOWB4+bkyX9221pAgGz3SHOJH0/MI9erLucS8PeeJDFwbUYyh75nQ6AzVtolgHxi52dQ==", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": ">=16.0.0-0", + "@angular/core": ">=16.0.0-0", + "@angular/platform-browser": ">=16.0.0-0" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "peer": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, + "node_modules/zone.js": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.14.7.tgz", + "integrity": "sha512-0w6DGkX2BPuiK/NLf+4A8FLE43QwBfuqz2dVgi/40Rj1WmqUskCqj329O/pwrqFJLG5X8wkeG2RhIAro441xtg==", + "peer": true + } + } } diff --git a/package.json b/package.json new file mode 100644 index 0000000..0e5cbb7 --- /dev/null +++ b/package.json @@ -0,0 +1,6 @@ +{ + "dependencies": { + "@angular/animations": "^18.1.0", + "ngx-toastr": "^19.0.0" + } +} -- 2.40.1 From 604327f453d071242a30a0608eb8fc446b1f5f0b Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Mon, 15 Jul 2024 08:22:31 +0200 Subject: [PATCH 30/36] refs #435. UX improvements --- .../classroom-view.component.css | 19 +++ .../classroom-view.component.ts | 3 +- .../client-view/client-view.component.ts | 30 +++-- .../create-client.component.html | 5 +- .../create-client/create-client.component.ts | 8 +- .../edit-client/edit-client.component.css | 20 +++ .../edit-client/edit-client.component.html | 19 +-- .../edit-client/edit-client.component.ts | 6 +- .../components/groups/groups.component.html | 123 ++++++++++++------ .../app/components/groups/groups.component.ts | 7 +- .../show-organizational-unit.component.ts | 3 +- 11 files changed, 170 insertions(+), 73 deletions(-) diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css index 47667ca..ffb644b 100644 --- a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css @@ -57,3 +57,22 @@ mat-card-title { margin: 0; } +.loading-spinner { + display: block; + margin: 0 auto; +} + +.mat-dialog-content.loading { + display: flex; + align-items: center; + justify-content: center; + height: 100%; +} + +.client-form { + width: 100%; +} + +.form-field { + width: 100%; +} diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts index 70f244a..1a6e498 100644 --- a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts @@ -20,7 +20,7 @@ interface GroupedClients { }) export class ClassroomViewComponent implements OnInit { @Input() clients: any[] = []; - @Input() pcInTable: number = 3; + @Input() pcInTable: number = 5; groupedClients: GroupedClients[] = []; constructor(public dialog: MatDialog) {} @@ -43,6 +43,7 @@ export class ClassroomViewComponent implements OnInit { return acc; }, {}); + console.log(grouped) this.groupedClients = Object.keys(grouped).map(ouName => ({ organizationalUnitName: ouName, clientRows: this.chunkArray(grouped[ouName], this.pcInTable) diff --git a/ogWebconsole/src/app/components/groups/client-view/client-view.component.ts b/ogWebconsole/src/app/components/groups/client-view/client-view.component.ts index dda2b48..63ccb03 100644 --- a/ogWebconsole/src/app/components/groups/client-view/client-view.component.ts +++ b/ogWebconsole/src/app/components/groups/client-view/client-view.component.ts @@ -17,12 +17,14 @@ export class ClientViewComponent { {property: 'MAC', value: this.data.client.mac}, {property: 'Nº de serie', value: this.data.client.serialNumber}, {property: 'Netiface', value: this.data.client.netiface}, + {property: 'Perfil hardware', value: this.data.client.hardwareProfile ? this.data.client.hardwareProfile.description : ''}, + {property: 'Menú', value: this.data.client.menu ? this.data.client.menu.description : ''}, {property: 'Fecha de creación', value: this.data.client.createdAt}, {property: 'Creado por', value: this.data.client.createdBy} ]; networkData = [ - {property: 'Menu', value: this.data.client.menu}, + {property: 'Menú', value: this.data.client.menu ? this.data.client.menu.description : ''}, {property: 'Perfil hardware', value: this.data.client.hardwareProfile ? this.data.client.hardwareProfile.description : ''}, {property: 'OGlive', value: ''}, {property: 'Autoexec', value: ''}, @@ -35,19 +37,19 @@ export class ClientViewComponent { ]; classroomData = [ - {property: 'Url servidor proxy', value: this.data.client.networkSettings ? this.data.client.networkSettings.proxy : ''}, - {property: 'IP DNS', value: this.data.client.networkSettings ? this.data.client.networkSettings.dns : ''}, - {property: 'Máscara de red', value: this.data.client.networkSettings ? this.data.client.networkSettings.mask : ''}, - {property: 'Router', value: this.data.client.networkSettings ? this.data.client.networkSettings.router : ''}, - {property: 'NTP', value: this.data.client.networkSettings ? this.data.client.networkSettings.ntp : ''}, - {property: 'Modo p2p', value: this.data.client.networkSettings ? this.data.client.networkSettings.p2pMode : ''}, - {property: 'Tiempo p2p', value: this.data.client.networkSettings ? this.data.client.networkSettings.p2pTime : ''}, - {property: 'IP multicast', value: this.data.client.networkSettings ? this.data.client.networkSettings.mcastIp : ''}, - {property: 'Modo multicast', value: this.data.client.networkSettings ? this.data.client.networkSettings.mcastMode : ''}, - {property: 'Puerto multicast', value: this.data.client.networkSettings ? this.data.client.networkSettings.mcastPort : ''}, - {property: 'Velocidad multicast', value: this.data.client.networkSettings ? this.data.client.networkSettings.mcastSpeed : ''}, - {property: 'Perfil hardware', value: this.data.client.networkSettings && this.data.client.networkSettings.hardwareProfile ? this.data.client.networkSettings.hardwareProfile.description : ''}, - {property: 'Menú', value: this.data.client.networkSettings && this.data.client.networkSettings.menu ? this.data.client.networkSettings.menu.description : ''} + {property: 'Url servidor proxy', value: this.data.client.organizationalUnit.networkSettings ? this.data.client.organizationalUnit.networkSettings.proxy : ''}, + {property: 'IP DNS', value: this.data.client.organizationalUnit.networkSettings ? this.data.client.organizationalUnit.networkSettings.dns : ''}, + {property: 'Máscara de red', value: this.data.client.organizationalUnit.networkSettings ? this.data.client.organizationalUnit.networkSettings.netmask : ''}, + {property: 'Router', value: this.data.client.organizationalUnit.networkSettings ? this.data.client.organizationalUnit.networkSettings.router : ''}, + {property: 'NTP', value: this.data.client.organizationalUnit.networkSettings ? this.data.client.organizationalUnit.networkSettings.ntp : ''}, + {property: 'Modo p2p', value: this.data.client.organizationalUnit.networkSettings ? this.data.client.organizationalUnit.networkSettings.p2pMode : ''}, + {property: 'Tiempo p2p', value: this.data.client.organizationalUnit.networkSettings ? this.data.client.organizationalUnit.networkSettings.p2pTime : ''}, + {property: 'IP multicast', value: this.data.client.organizationalUnit.networkSettings ? this.data.client.organizationalUnit.networkSettings.mcastIp : ''}, + {property: 'Modo multicast', value: this.data.client.organizationalUnit.networkSettings ? this.data.client.organizationalUnit.networkSettings.mcastMode : ''}, + {property: 'Puerto multicast', value: this.data.client.organizationalUnit.networkSettings ? this.data.client.organizationalUnit.networkSettings.mcastPort : ''}, + {property: 'Velocidad multicast', value: this.data.client.organizationalUnit.networkSettings ? this.data.client.organizationalUnit.networkSettings.mcastSpeed : ''}, + {property: 'Perfil hardware', value: this.data.client.organizationalUnit.networkSettings && this.data.client.organizationalUnit.networkSettings.hardwareProfile ? this.data.client.organizationalUnit.networkSettings.hardwareProfile.description : ''}, + {property: 'Menú', value: this.data.client.organizationalUnit.networkSettings && this.data.client.organizationalUnit.networkSettings.menu ? this.data.client.organizationalUnit.networkSettings.menu.description : ''} ]; constructor( diff --git a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.html b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.html index 27c6787..5281297 100644 --- a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.html +++ b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.html @@ -1,6 +1,7 @@

Añadir Cliente

-
- +
+ + Padre diff --git a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts index dddd84a..876277d 100644 --- a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts +++ b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts @@ -24,6 +24,7 @@ export class CreateClientComponent implements OnInit { protected netDriverTypes = [ {"name": 'Generic', "value": "generic"}, ]; + loading:boolean = false constructor( private fb: FormBuilder, @@ -47,8 +48,8 @@ export class CreateClientComponent implements OnInit { netDriver: null, mac: ['', Validators.required], ip: ['', Validators.required], - menu: [this.data.organizationalUnit && this.data.organizationalUnit.menu ? this.data.organizationalUnit.menu['@id'] : null], - hardwareProfile: [this.data.organizationalUnit && this.data.organizationalUnit.hardwareProfile ? this.data.organizationalUnit.hardwareProfile['@id'] : null], + menu: [this.data.organizationalUnit && this.data.organizationalUnit.networkSettings.menu ? this.data.organizationalUnit.menu['@id'] : null], + hardwareProfile: [this.data.organizationalUnit && this.data.organizationalUnit.networkSettings.hardwareProfile ? this.data.organizationalUnit.networkSettings.hardwareProfile['@id'] : null], }); } @@ -64,14 +65,17 @@ export class CreateClientComponent implements OnInit { } loadParentUnits() { + this.loading = true const url = 'http://127.0.0.1:8080/organizational-units?page=1&itemsPerPage=10000'; this.http.get(url).subscribe( response => { this.parentUnits = response['hydra:member']; + this.loading = false }, error => { console.error('Error fetching parent units:', error); + this.loading = false } ); } diff --git a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.css b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.css index 39cb26a..1dedbe9 100644 --- a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.css +++ b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.css @@ -36,3 +36,23 @@ button { .mat-slide-toggle { margin-top: 20px; } + +.loading-spinner { + display: block; + margin: 0 auto; +} + +.mat-dialog-content.loading { + display: flex; + align-items: center; + justify-content: center; + height: 100%; +} + +.client-form { + width: 100%; +} + +.form-field { + width: 100%; +} diff --git a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.html b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.html index 9d427ea..7ed4b23 100644 --- a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.html +++ b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.html @@ -1,6 +1,7 @@

Editar Cliente

-
- +
+ + Padre @@ -9,31 +10,31 @@ Nombre - + Número de Serie - + Interfaz de red - - + + {{ type.name }} Controlador de red - - + + {{ type.name }} MAC - + Formato de MAC inválido. Ejemplo válido: 00:11:22:33:44:55 diff --git a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.ts b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.ts index bd1a339..c86e7cd 100644 --- a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.ts +++ b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.ts @@ -24,6 +24,7 @@ export class EditClientComponent { protected netDriverTypes = [ {"name": 'Generic', "value": "generic"}, ]; + loading:boolean = false constructor( private fb: FormBuilder, @@ -80,6 +81,7 @@ export class EditClientComponent { } loadData(uuid: string) { + this.loading = true const url = `http://127.0.0.1:8080/clients/${uuid}`; this.http.get(url).subscribe( @@ -94,7 +96,9 @@ export class EditClientComponent { hardwareProfile: data.hardwareProfile ? data.hardwareProfile['@id'] : null, organizationalUnit: data.organizationalUnit ? data.organizationalUnit['@id'] : null }); - }); + this.loading = false + } + ); } onSubmit() { diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html index 2132e84..59f9179 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.html +++ b/ogWebconsole/src/app/components/groups/groups.component.html @@ -16,50 +16,73 @@
- Unidad organizativa + Unidad organizativa + [ngClass]="{'selected-item': unidad === selectedUnidad, 'clickable-item': true}" (click)="onSelectUnidad(unidad)">
apartment {{ unidad.name }} - account_tree - - edit - - visibility - - add_home_work - - devices - + menu + + + + + + + +
@@ -98,11 +121,29 @@ {{child.name}} - edit - visibility - add_home_work - devices - delete + menu + + + + + + +
diff --git a/ogWebconsole/src/app/components/groups/groups.component.ts b/ogWebconsole/src/app/components/groups/groups.component.ts index 6f5edb4..e68d3d6 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.ts +++ b/ogWebconsole/src/app/components/groups/groups.component.ts @@ -160,14 +160,16 @@ constructor( this.dataService.deleteElement(uuid, type).subscribe( () => { this.loadChildrenAndClients(this.selectedUnidad?.id || ''); - this.dataService.getOrganizationalUnits().subscribe( data => this.organizationalUnits = data, error => console.error('Error fetching unidades organizativas', error) ); this.openSnackBar(false, 'Entidad eliminada exitosamente') }, - error => console.error('Error deleting element', error) + error => { + console.error('Error deleting element', error) + this.openSnackBar(true, error.error['hydra:description']) + } ); } }); @@ -201,6 +203,7 @@ constructor( data => this.organizationalUnits = data, error => console.error('Error fetching unidades organizativas', error) ); + this.openSnackBar(false, 'Entidad eliminada exitosamente') }, error => { console.error('Error deleting element', error) diff --git a/ogWebconsole/src/app/components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component.ts b/ogWebconsole/src/app/components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component.ts index 61e45a2..a1e6bb4 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component.ts +++ b/ogWebconsole/src/app/components/groups/organizational-units/show-organizational-unit/show-organizational-unit.component.ts @@ -13,6 +13,7 @@ export class ShowOrganizationalUnitComponent { generalData = [ { property: 'Nombre', value: this.data.data.name }, { property: 'Uuid', value: this.data.data.uuid }, + { property: 'Descripción', value: this.data.data.description }, { property: 'Comentarios', value: this.data.data.comments }, { property: 'Tipo', value: this.data.data.type }, { property: 'Unidad organizativa superior', value: this.data.data.parent ? this.data.data.parent.name : '-' }, @@ -27,7 +28,7 @@ export class ShowOrganizationalUnitComponent { { property: 'Aforo', value: this.data.data.capacity }, { property: 'Url servidor proxy', value: this.data.data.networkSettings ? this.data.data.networkSettings.proxy : '' }, { property: 'IP DNS', value: this.data.data.networkSettings ? this.data.data.networkSettings.dns : '' }, - { property: 'Máscara de red', value: this.data.data.networkSettings ? this.data.data.networkSettings.mask : '' }, + { property: 'Máscara de red', value: this.data.data.networkSettings ? this.data.data.networkSettings.netmask : '' }, { property: 'Router', value: this.data.data.networkSettings ? this.data.data.networkSettings.router : '' }, { property: 'NTP', value: this.data.data.networkSettings ? this.data.data.networkSettings.ntp : '' }, { property: 'Modo p2p', value: this.data.data.networkSettings ? this.data.data.networkSettings.p2pMode : '' }, -- 2.40.1 From 3ce8bfe8fe5d7d068c8a84bbf731ae7c0273c893 Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Mon, 15 Jul 2024 09:52:49 +0200 Subject: [PATCH 31/36] refs #435. UX improvements --- .../src/app/components/groups/groups.component.html | 9 --------- .../users/add-user-modal/add-user-modal.component.ts | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/ogWebconsole/src/app/components/groups/groups.component.html b/ogWebconsole/src/app/components/groups/groups.component.html index 59f9179..541d2cc 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.html +++ b/ogWebconsole/src/app/components/groups/groups.component.html @@ -46,15 +46,6 @@ Editar -
- +
diff --git a/ogWebconsole/src/app/components/login/login.component.ts b/ogWebconsole/src/app/components/login/login.component.ts index de37ed7..3b6f805 100644 --- a/ogWebconsole/src/app/components/login/login.component.ts +++ b/ogWebconsole/src/app/components/login/login.component.ts @@ -63,6 +63,7 @@ export class LoginComponent { hide = signal(true); clickEvent(event: MouseEvent) { + event.preventDefault(); this.hide.set(!this.hide()); event.stopPropagation(); } -- 2.40.1 From becc06e26a1e565abf6bb7bf3df70b53fe1f5880 Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Mon, 15 Jul 2024 10:18:21 +0200 Subject: [PATCH 33/36] refs #435. UX improvements --- .../create-organizational-unit.component.html | 6 +++--- .../edit-organizational-unit.component.html | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html index de5061d..21d080c 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html +++ b/ogWebconsole/src/app/components/groups/organizational-units/create-organizational-unit/create-organizational-unit.component.html @@ -76,11 +76,11 @@
Configuración de Red - Proxy + Url servidor Proxy - DNS + IP servidor DNS @@ -92,7 +92,7 @@ - NTP + IP servidor NTP diff --git a/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.html b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.html index b0434c7..3160f95 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.html +++ b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.html @@ -72,11 +72,11 @@ Configuración de Red - Proxy + Url servidor Proxy - DNS + IP servidor DNS @@ -88,7 +88,7 @@ - NTP + IP servidor NTP -- 2.40.1 From 5c72cc2fd6a13aebad545fc2bab0669ef7750d29 Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Mon, 15 Jul 2024 11:15:17 +0200 Subject: [PATCH 34/36] refs #435. UX improvements --- .../groups/client-view/client-view.component.css | 4 +++- .../groups/client-view/client-view.component.html | 6 ++++-- .../clients/create-client/create-client.component.css | 7 +++++++ .../groups/clients/edit-client/edit-client.component.css | 2 ++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/ogWebconsole/src/app/components/groups/client-view/client-view.component.css b/ogWebconsole/src/app/components/groups/client-view/client-view.component.css index 65254cb..d26e902 100644 --- a/ogWebconsole/src/app/components/groups/client-view/client-view.component.css +++ b/ogWebconsole/src/app/components/groups/client-view/client-view.component.css @@ -1,5 +1,6 @@ -mat-dialog-content { +.mat-dialog-content { padding: 20px; + height: 100%; } .button-encender { @@ -46,6 +47,7 @@ table { .button-column { display: flex; + margin-top: 40px; flex-direction: column; gap: 10px; align-items: center; diff --git a/ogWebconsole/src/app/components/groups/client-view/client-view.component.html b/ogWebconsole/src/app/components/groups/client-view/client-view.component.html index 3519f4e..3ddfe30 100644 --- a/ogWebconsole/src/app/components/groups/client-view/client-view.component.html +++ b/ogWebconsole/src/app/components/groups/client-view/client-view.component.html @@ -1,5 +1,5 @@

Propiedades cliente

-
+
{{ column.header }}
@@ -53,8 +53,10 @@ + + - + diff --git a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.css b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.css index ceac8f6..21401e2 100644 --- a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.css +++ b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.css @@ -46,3 +46,10 @@ mat-option .unit-path { font-size: 0.8em; color: gray; } + +.loading-spinner { + display: block; + margin: 0 auto; + align-items: center; + justify-content: center; +} diff --git a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.css b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.css index 1dedbe9..79104af 100644 --- a/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.css +++ b/ogWebconsole/src/app/components/groups/clients/edit-client/edit-client.component.css @@ -40,6 +40,8 @@ button { .loading-spinner { display: block; margin: 0 auto; + align-items: center; + justify-content: center; } .mat-dialog-content.loading { -- 2.40.1 From 26a81228908f0dda8382c0cae51fa0bb03703e06 Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Mon, 15 Jul 2024 12:52:38 +0200 Subject: [PATCH 35/36] refs #434. Fixed bug --- .../clients/create-client/create-client.component.ts | 7 +++++-- .../edit-organizational-unit.component.ts | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts index 876277d..a5ce5db 100644 --- a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts +++ b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.ts @@ -38,6 +38,7 @@ export class CreateClientComponent implements OnInit { } ngOnInit(): void { + console.log(this.data); this.loadParentUnits(); // Load parent units when component initializes this.loadHardwareProfiles(); this.clientForm = this.fb.group({ @@ -48,8 +49,8 @@ export class CreateClientComponent implements OnInit { netDriver: null, mac: ['', Validators.required], ip: ['', Validators.required], - menu: [this.data.organizationalUnit && this.data.organizationalUnit.networkSettings.menu ? this.data.organizationalUnit.menu['@id'] : null], - hardwareProfile: [this.data.organizationalUnit && this.data.organizationalUnit.networkSettings.hardwareProfile ? this.data.organizationalUnit.networkSettings.hardwareProfile['@id'] : null], + menu: [this.data.organizationalUnit && this.data.organizationalUnit.networkSettings && this.data.organizationalUnit.networkSettings.menu ? this.data.organizationalUnit.networkSettings.menu['@id'] : null], + hardwareProfile: [this.data.organizationalUnit && this.data.organizationalUnit.networkSettings && this.data.organizationalUnit.networkSettings.hardwareProfile ? this.data.organizationalUnit.networkSettings.hardwareProfile['@id'] : null], }); } @@ -57,9 +58,11 @@ export class CreateClientComponent implements OnInit { this.dataService.getHardwareProfiles().subscribe( (data: any[]) => { this.hardwareProfiles = data; + this.loading = false }, (error: any) => { console.error('Error fetching hardware profiles', error); + this.loading = false } ); } diff --git a/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.ts b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.ts index 280632e..74564f8 100644 --- a/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.ts +++ b/ogWebconsole/src/app/components/groups/organizational-units/edit-organizational-unit/edit-organizational-unit.component.ts @@ -166,9 +166,10 @@ export class EditOrganizationalUnitComponent implements OnInit { description: this.generalFormGroup.value.description, comments: this.additionalInfoFormGroup.value.comments, type: this.generalFormGroup.value.type, - ...this.networkSettingsFormGroup.value + networkSettings: this.networkSettingsFormGroup.value }; + if (this.isEditMode) { // Edit mode: Send PUT request to update the unit const putUrl = `http://127.0.0.1:8080/organizational-units/${this.data.uuid}`; -- 2.40.1 From ae57c3c8cfcf04047eb2c8d3024c1dde5b98639d Mon Sep 17 00:00:00 2001 From: apuente Date: Mon, 15 Jul 2024 14:52:49 +0200 Subject: [PATCH 36/36] Add board and minnor fix --- ogWebconsole/package-lock.json | 4336 ++++++++--------- .../classroom-view.component.css | 68 +- .../classroom-view.component.html | 22 +- .../classroom-view.component.ts | 7 - .../create-client/create-client.component.css | 5 + .../create-client.component.html | 2 + ogWebconsole/src/assets/images/board.png | Bin 0 -> 32063 bytes ogWebconsole/src/assets/images/client.png | Bin 0 -> 41800 bytes ogWebconsole/src/assets/images/proyector.png | Bin 0 -> 6076 bytes 9 files changed, 2231 insertions(+), 2209 deletions(-) create mode 100644 ogWebconsole/src/assets/images/board.png create mode 100644 ogWebconsole/src/assets/images/client.png create mode 100644 ogWebconsole/src/assets/images/proyector.png diff --git a/ogWebconsole/package-lock.json b/ogWebconsole/package-lock.json index 01ded5e..1610f0f 100644 --- a/ogWebconsole/package-lock.json +++ b/ogWebconsole/package-lock.json @@ -52,12 +52,12 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1800.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1800.1.tgz", - "integrity": "sha512-L3n1Rh0NUNTlQZBBuPY8VFc5Skr6Oa6xT821k+XLLZTbz1ci2e3ltINyUhqISeksa3AyyL8e4JR2kCbDli9uJA==", + "version": "0.1801.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1801.0.tgz", + "integrity": "sha512-iZa3J3CrZT6MKiHPw8ijgVwMyCMewCsP4xc75SetUwF/yuqRUHygALs5jJVZQFQjSFUrkg9gqXa1cCjFDwpT8A==", "dev": true, "dependencies": { - "@angular-devkit/core": "18.0.1", + "@angular-devkit/core": "18.1.0", "rxjs": "7.8.1" }, "engines": { @@ -67,71 +67,70 @@ } }, "node_modules/@angular-devkit/build-angular": { - "version": "18.0.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.0.1.tgz", - "integrity": "sha512-FDVxR+VR0WP/lukOrnhEdy+hcGNBzqyfmrW0fyIthwP+A/gHlB3Qd/lehkeLngTjPwtBXssxuwR6BgWmpjy69Q==", + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.1.0.tgz", + "integrity": "sha512-j/YrEFuEX90Pcyzjew6EcCoxT+Va0AlGjgWyVIuStNTEsCx9Vp7T2tS7w6LL1t6leM7gzf8f/ZKtvRPnAsWdQg==", "dev": true, "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.1800.1", - "@angular-devkit/build-webpack": "0.1800.1", - "@angular-devkit/core": "18.0.1", - "@angular/build": "18.0.1", - "@babel/core": "7.24.5", - "@babel/generator": "7.24.5", - "@babel/helper-annotate-as-pure": "7.22.5", - "@babel/helper-split-export-declaration": "7.24.5", - "@babel/plugin-transform-async-generator-functions": "7.24.3", - "@babel/plugin-transform-async-to-generator": "7.24.1", - "@babel/plugin-transform-runtime": "7.24.3", - "@babel/preset-env": "7.24.5", - "@babel/runtime": "7.24.5", + "@angular-devkit/architect": "0.1801.0", + "@angular-devkit/build-webpack": "0.1801.0", + "@angular-devkit/core": "18.1.0", + "@angular/build": "18.1.0", + "@babel/core": "7.24.7", + "@babel/generator": "7.24.7", + "@babel/helper-annotate-as-pure": "7.24.7", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-transform-async-generator-functions": "7.24.7", + "@babel/plugin-transform-async-to-generator": "7.24.7", + "@babel/plugin-transform-runtime": "7.24.7", + "@babel/preset-env": "7.24.7", + "@babel/runtime": "7.24.7", "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "18.0.1", + "@ngtools/webpack": "18.1.0", "@vitejs/plugin-basic-ssl": "1.1.0", "ansi-colors": "4.1.3", "autoprefixer": "10.4.19", "babel-loader": "9.1.3", - "babel-plugin-istanbul": "6.1.1", "browserslist": "^4.21.5", - "copy-webpack-plugin": "11.0.0", - "critters": "0.0.22", - "css-loader": "7.1.1", - "esbuild-wasm": "0.21.3", + "copy-webpack-plugin": "12.0.2", + "critters": "0.0.24", + "css-loader": "7.1.2", + "esbuild-wasm": "0.21.5", "fast-glob": "3.3.2", "http-proxy-middleware": "3.0.0", - "https-proxy-agent": "7.0.4", - "inquirer": "9.2.22", - "jsonc-parser": "3.2.1", + "https-proxy-agent": "7.0.5", + "istanbul-lib-instrument": "6.0.2", + "jsonc-parser": "3.3.1", "karma-source-map-support": "1.4.0", "less": "4.2.0", "less-loader": "12.2.0", "license-webpack-plugin": "4.0.2", - "loader-utils": "3.2.1", + "loader-utils": "3.3.1", "magic-string": "0.30.10", "mini-css-extract-plugin": "2.9.0", "mrmime": "2.0.0", - "open": "8.4.2", + "open": "10.1.0", "ora": "5.4.1", "parse5-html-rewriting-stream": "7.0.0", "picomatch": "4.0.2", - "piscina": "4.5.0", + "piscina": "4.6.1", "postcss": "8.4.38", "postcss-loader": "8.1.1", "resolve-url-loader": "5.0.0", "rxjs": "7.8.1", - "sass": "1.77.2", + "sass": "1.77.6", "sass-loader": "14.2.1", "semver": "7.6.2", "source-map-loader": "5.0.0", "source-map-support": "0.5.21", - "terser": "5.31.0", + "terser": "5.29.2", "tree-kill": "1.2.2", - "tslib": "2.6.2", - "undici": "6.18.0", - "vite": "5.2.11", + "tslib": "2.6.3", + "undici": "6.19.2", + "vite": "5.3.2", "watchpack": "2.4.1", - "webpack": "5.91.0", + "webpack": "5.92.1", "webpack-dev-middleware": "7.2.1", "webpack-dev-server": "5.0.4", "webpack-merge": "5.10.0", @@ -143,7 +142,7 @@ "yarn": ">= 1.13.0" }, "optionalDependencies": { - "esbuild": "0.21.3" + "esbuild": "0.21.5" }, "peerDependencies": { "@angular/compiler-cli": "^18.0.0", @@ -158,7 +157,7 @@ "ng-packagr": "^18.0.0", "protractor": "^7.0.0", "tailwindcss": "^2.0.0 || ^3.0.0", - "typescript": ">=5.4 <5.5" + "typescript": ">=5.4 <5.6" }, "peerDependenciesMeta": { "@angular/localize": { @@ -197,12 +196,12 @@ } }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.1800.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1800.1.tgz", - "integrity": "sha512-a5/0mOBRgrQZVv2yc0TXlnwb5etil6Wb/T44tXh0EHsOeaKXGCqWQPVu1EjVJoHieVdXOcajGrPo0aGd8blsdg==", + "version": "0.1801.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1801.0.tgz", + "integrity": "sha512-EnkkhE4tVOk3lU5/bt8hNCQCJMefcpU5E4jChRmFu+m0OtKK2kax3hjPTUVwcpbjwpG5rO7J/U5yIhCY9afXKw==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1800.1", + "@angular-devkit/architect": "0.1801.0", "rxjs": "7.8.1" }, "engines": { @@ -216,14 +215,14 @@ } }, "node_modules/@angular-devkit/core": { - "version": "18.0.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.0.1.tgz", - "integrity": "sha512-91eKZoObs+wRgwssw81Y/94Nvixj0WqJkNusBAg+gAfZTCEeJoGGZJkRK8wrONbM79C3Bx8lN/TfSIPRbjnfOQ==", + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.1.0.tgz", + "integrity": "sha512-6eXQDzHZCbpSMLv9Ohl+1QyLVDmGEXpuuHz3y64LfUTP0aEiBaxk96FjLXIxzJ4f2pbbW2XHzc+yuboGToRA0w==", "dev": true, "dependencies": { - "ajv": "8.13.0", + "ajv": "8.16.0", "ajv-formats": "3.0.1", - "jsonc-parser": "3.2.1", + "jsonc-parser": "3.3.1", "picomatch": "4.0.2", "rxjs": "7.8.1", "source-map": "0.7.4" @@ -243,13 +242,13 @@ } }, "node_modules/@angular-devkit/schematics": { - "version": "18.0.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.0.1.tgz", - "integrity": "sha512-AKcEGa3fIgyXT6XTQZWEJZzgmcqlB89fcF7JFOuz4rgQfRmnE2xFw37lKE6ZclCOSiEoffAvgrL8acjdPI1ouw==", + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.1.0.tgz", + "integrity": "sha512-BjrYutLfYFiPOSEcLBWCj3ENkwDn8gMfBSJesaBz7OrZBZGK5j0dVgBLIsGTP96TKo4o4vszJQOvS4AtV6xMGg==", "dev": true, "dependencies": { - "@angular-devkit/core": "18.0.1", - "jsonc-parser": "3.2.1", + "@angular-devkit/core": "18.1.0", + "jsonc-parser": "3.3.1", "magic-string": "0.30.10", "ora": "5.4.1", "rxjs": "7.8.1" @@ -261,49 +260,51 @@ } }, "node_modules/@angular/animations": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.0.0.tgz", - "integrity": "sha512-An/IqDBCyWZXVC23+jRKdmvJB/b4P1BVljZxGxF+CiocNd/xvVVeBYuuxzp3vhhVobyO8A9iD12itPudLOpt2Q==", + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.1.0.tgz", + "integrity": "sha512-K0BhvZ/SIVoGXZVuh1KOJDdgcGlHfFGMGrs58utndndAb+gYXReMfz4GR5cQs2OObH6TKmIOY2EH7Og1CY2tsw==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^18.13.0 || >=20.9.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "18.0.0" + "@angular/core": "18.1.0" } }, "node_modules/@angular/build": { - "version": "18.0.1", - "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.0.1.tgz", - "integrity": "sha512-n2So6inJ4Prw3NOPC6keyVyFDryFNCJ4UUzmjtPOS8FyYqThWBcuXFzsUsUCFbXSUqVBZh9vxEqHqggnCAs9Og==", + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.1.0.tgz", + "integrity": "sha512-4yLrGqMDoNBis2Z4s8F3wSqlB2XLtwy/10tREBk9xVaCojERiwDvtHqzbMeHqD6ZMGDFtdhI12q8FT5jZVUmAw==", "dev": true, "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.1800.1", - "@babel/core": "7.24.5", - "@babel/helper-annotate-as-pure": "7.22.5", - "@babel/helper-split-export-declaration": "7.24.5", + "@angular-devkit/architect": "0.1801.0", + "@babel/core": "7.24.7", + "@babel/helper-annotate-as-pure": "7.24.7", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-syntax-import-attributes": "7.24.7", + "@inquirer/confirm": "3.1.11", "@vitejs/plugin-basic-ssl": "1.1.0", "ansi-colors": "4.1.3", "browserslist": "^4.23.0", - "critters": "0.0.22", - "esbuild": "0.21.3", + "critters": "0.0.24", + "esbuild": "0.21.5", "fast-glob": "3.3.2", - "https-proxy-agent": "7.0.4", - "inquirer": "9.2.22", - "lmdb": "3.0.8", + "https-proxy-agent": "7.0.5", + "lmdb": "3.0.12", "magic-string": "0.30.10", "mrmime": "2.0.0", "ora": "5.4.1", "parse5-html-rewriting-stream": "7.0.0", "picomatch": "4.0.2", - "piscina": "4.5.0", - "sass": "1.77.2", + "piscina": "4.6.1", + "rollup": "4.18.0", + "sass": "1.77.6", "semver": "7.6.2", - "undici": "6.18.0", - "vite": "5.2.11", + "undici": "6.19.2", + "vite": "5.3.2", "watchpack": "2.4.1" }, "engines": { @@ -319,7 +320,7 @@ "less": "^4.2.0", "postcss": "^8.4.0", "tailwindcss": "^2.0.0 || ^3.0.0", - "typescript": ">=5.4 <5.5" + "typescript": ">=5.4 <5.6" }, "peerDependenciesMeta": { "@angular/localize": { @@ -343,9 +344,9 @@ } }, "node_modules/@angular/cdk": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.0.0.tgz", - "integrity": "sha512-V0i1SAiT2PTNyugBW0E4fev8G/4XP5FdyX2YD6oc5sNyt3GFcoDNHcz+oEne8+aYVnQ3Ax9Zutq/SQincDHIbw==", + "version": "18.0.6", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.0.6.tgz", + "integrity": "sha512-9CmlQ8uZ0cHuj+1jDdabbFw90QpjrJzh1/cgeHN/8vAGE4ranxX3l6cqpVxuoWRLkB2ykTHt2xeoTM8y0d9ERA==", "dependencies": { "tslib": "^2.3.0" }, @@ -359,23 +360,23 @@ } }, "node_modules/@angular/cli": { - "version": "18.0.1", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.0.1.tgz", - "integrity": "sha512-O1kQOxXsfxHgGyqdHc2OTwlUTXLE8O1UcGkWROxvKt4MXccdJLjMjypMiV+jSpzc0FJTV1ihSkCxMtBezF926A==", + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.1.0.tgz", + "integrity": "sha512-2E+b7S/736AOmxf5je9OWoPpgPY240TfJfFXwQiVvq/4KyC+ZR9lBrqRx72Xghn8nu3z8Q2BPZIXVGZppl0USQ==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1800.1", - "@angular-devkit/core": "18.0.1", - "@angular-devkit/schematics": "18.0.1", - "@schematics/angular": "18.0.1", + "@angular-devkit/architect": "0.1801.0", + "@angular-devkit/core": "18.1.0", + "@angular-devkit/schematics": "18.1.0", + "@inquirer/prompts": "5.0.7", + "@listr2/prompt-adapter-inquirer": "2.0.13", + "@schematics/angular": "18.1.0", "@yarnpkg/lockfile": "1.1.0", - "ansi-colors": "4.1.3", - "ini": "4.1.2", - "inquirer": "9.2.22", - "jsonc-parser": "3.2.1", + "ini": "4.1.3", + "jsonc-parser": "3.3.1", + "listr2": "8.2.3", "npm-package-arg": "11.0.2", "npm-pick-manifest": "9.0.1", - "ora": "5.4.1", "pacote": "18.0.6", "resolve": "1.22.8", "semver": "7.6.2", @@ -392,32 +393,32 @@ } }, "node_modules/@angular/common": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.0.0.tgz", - "integrity": "sha512-s43ZcOhXTUlkdOPMiMtr4Pz1qKIS8nClXhaahY0JBQZYGsOSn7NR42SoEeB8/ixktfY60s3SLhizXTKMAYtOTA==", + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.1.0.tgz", + "integrity": "sha512-noHDLarQSCZZh7hyNd0HR61Fut+q4QCVq9qc/jKPglfbV/6nPujQSmSpT+rNJlNuBOrCLuvH/CNBNbiqii+x3g==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^18.13.0 || >=20.9.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "18.0.0", + "@angular/core": "18.1.0", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-18.0.0.tgz", - "integrity": "sha512-KbyjUfpdVE8+6fiHqo4PgVrGppYUhlU1JVAj6dqeUug9lQ5HBcANfiZ7p8CA2lU3gvIZ1cj+ZDKA1NEB1wvvtQ==", + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-18.1.0.tgz", + "integrity": "sha512-JRQzVTeJGSfRLY+dx+gwu/hPQVB8K+5pW12Z42M9x/HBgGW4in0cO2zHkeQPvImqm0nak82Us1Hyf5C+qTlMMQ==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^18.13.0 || >=20.9.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "18.0.0" + "@angular/core": "18.1.0" }, "peerDependenciesMeta": { "@angular/core": { @@ -426,12 +427,12 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-18.0.0.tgz", - "integrity": "sha512-fy9MBSHDM/YAyrIWa15JV1ZrpuSc51HHUSA3W/UKrDqUqSfYyj11/0PeYkdIWUD/dACZSrEge3nVnYCjdyJqPA==", + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-18.1.0.tgz", + "integrity": "sha512-BBsogLPJwxkPh7f8RVHsxyyqNE8XpHbAanjB5fAwnU4W6Sw1kR5rFzkeZM3xaRm2MDiC8DovIl6hlf+s/mKYOw==", "dev": true, "dependencies": { - "@babel/core": "7.24.4", + "@babel/core": "7.24.7", "@jridgewell/sourcemap-codec": "^1.4.14", "chokidar": "^3.0.0", "convert-source-map": "^1.5.1", @@ -446,67 +447,22 @@ "ngcc": "bundles/ngcc/index.js" }, "engines": { - "node": "^18.13.0 || >=20.9.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/compiler": "18.0.0", - "typescript": ">=5.4 <5.5" - } - }, - "node_modules/@angular/compiler-cli/node_modules/@babel/core": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.4.tgz", - "integrity": "sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.2", - "@babel/generator": "^7.24.4", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.24.4", - "@babel/parser": "^7.24.4", - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.1", - "@babel/types": "^7.24.0", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" + "@angular/compiler": "18.1.0", + "typescript": ">=5.4 <5.6" } }, "node_modules/@angular/core": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.0.0.tgz", - "integrity": "sha512-tpR7HIY4MJuM9ETpG15IvBr1wsI8Cyec3ZxYFe/27FKHARvxDbqIrT9QevmC6lxg1NdfD990G2XphYML1EyJ8g==", + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.1.0.tgz", + "integrity": "sha512-/57/s7CD/0CwlN+3FlhVmx7ypCWXjKi5UKtnlBAUg0D1denIf6ADxwTHFZABYZcYBqOTJgeQUtUw9u/A+0CIlg==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^18.13.0 || >=20.9.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { "rxjs": "^6.5.3 || ^7.4.0", @@ -514,26 +470,26 @@ } }, "node_modules/@angular/forms": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-18.0.0.tgz", - "integrity": "sha512-Q+4WExdgALP7VJ5lKSYmpz8CtAFZI4f3n09JhExIZoPTLD/mqOJcxxO7wTc9lXG4jKSE8BlfgK2txKz1cQvrEQ==", + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-18.1.0.tgz", + "integrity": "sha512-m+7m9wa+n5dEacd458eSZsZTz0B+HbOtr7/uqM0YTMQaPrhwl1epG5Y103mB6yr00JiJcLNlPLjP888cHFjldQ==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^18.13.0 || >=20.9.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "18.0.0", - "@angular/core": "18.0.0", - "@angular/platform-browser": "18.0.0", + "@angular/common": "18.1.0", + "@angular/core": "18.1.0", + "@angular/platform-browser": "18.1.0", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/material": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@angular/material/-/material-18.0.0.tgz", - "integrity": "sha512-4WfMcr4cX3cF7dKz+cXf9YIvhWOJGTP24rbMF5C6eC5K20IK6zgA//Qn0VSTwZkm54Tu9C7kF+CfNLeLy6i5uQ==", + "version": "18.0.6", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-18.0.6.tgz", + "integrity": "sha512-6Gp+oW7zjkb5A6HnHMYlxCt4wB8JqjIoAQu1MgQ6OKOOaDlvhMg2+a1ww5mov/OuoFE+FluLQkMCmVkjG1t/Aw==", "dependencies": { "@material/animation": "15.0.0-canary.7f224ddd4.0", "@material/auto-init": "15.0.0-canary.7f224ddd4.0", @@ -587,7 +543,7 @@ }, "peerDependencies": { "@angular/animations": "^18.0.0 || ^19.0.0", - "@angular/cdk": "18.0.0", + "@angular/cdk": "18.0.6", "@angular/common": "^18.0.0 || ^19.0.0", "@angular/core": "^18.0.0 || ^19.0.0", "@angular/forms": "^18.0.0 || ^19.0.0", @@ -596,19 +552,19 @@ } }, "node_modules/@angular/platform-browser": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.0.0.tgz", - "integrity": "sha512-fOqXQn15H33xGTGgNBUwXAg5KRpqcdsVfipFBuD1GMbjMLQAx/AagxsBavRiq3mKEdHZyQ+hI4mvaKQWOPKUOQ==", + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.1.0.tgz", + "integrity": "sha512-jCmxthiI4Zef54crckNht60xwfIsuciGeyZvb7SsXna2maLW9fA4uz1VhZqIWTiBnHwNynVlyfBX3/jBD7S9+g==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^18.13.0 || >=20.9.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/animations": "18.0.0", - "@angular/common": "18.0.0", - "@angular/core": "18.0.0" + "@angular/animations": "18.1.0", + "@angular/common": "18.1.0", + "@angular/core": "18.1.0" }, "peerDependenciesMeta": { "@angular/animations": { @@ -617,46 +573,46 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-18.0.0.tgz", - "integrity": "sha512-Z7Y2qzEuFgCrkgcKPuyHGStEnZ89L3gr3SIgqoVlz4kauf0Fa70H6dxyd/RXV61OZwLXx0yt9rV5d8v+Ay+3fQ==", + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-18.1.0.tgz", + "integrity": "sha512-D/wuOQf+gULld9DVEzn2Lw3WbTyAYf/sp3DC5k83O+DQsG3eAIsVkt0zdE+U3DrDYsiWg8M3X+ioi3ouqK0mNg==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^18.13.0 || >=20.9.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "18.0.0", - "@angular/compiler": "18.0.0", - "@angular/core": "18.0.0", - "@angular/platform-browser": "18.0.0" + "@angular/common": "18.1.0", + "@angular/compiler": "18.1.0", + "@angular/core": "18.1.0", + "@angular/platform-browser": "18.1.0" } }, "node_modules/@angular/router": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-18.0.0.tgz", - "integrity": "sha512-bytfTypkJbHDv2QkD8jT2w63DWKicSYi5l7N+LPukb9/0pl3XYXKJ8cjlVLbiFvoo5Oz2oBFWYFucWsaPqDw3A==", + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-18.1.0.tgz", + "integrity": "sha512-dl2cSxZkl4we+rWMxdm123TZzlor6yxwNFI2yT7b6DP2i+rXaaHBSSPet0ASp+UX6djz+Osr56Bifs6wi4rhiQ==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^18.13.0 || >=20.9.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "18.0.0", - "@angular/core": "18.0.0", - "@angular/platform-browser": "18.0.0", + "@angular/common": "18.1.0", + "@angular/core": "18.1.0", + "@angular/platform-browser": "18.1.0", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@babel/code-frame": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.6.tgz", - "integrity": "sha512-ZJhac6FkEd1yhG2AHOmfcXG4ceoLltoCVJjN5XsWN9BifBQr+cHJbWi0h68HZuSORq+3WtJ2z0hwF2NG1b5kcA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.24.6", + "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" }, "engines": { @@ -664,30 +620,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.6.tgz", - "integrity": "sha512-aC2DGhBq5eEdyXWqrDInSqQjO0k8xtPRf5YylULqx8MCd6jBtzqfta/3ETMRpuKIc5hyswfO80ObyA1MvkCcUQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.8.tgz", + "integrity": "sha512-c4IM7OTg6k1Q+AJ153e2mc2QVTezTwnb4VzquwcyiEzGnW0Kedv4do/TrkU98qPeC5LNiMt/QXwIjzYXLBpyZg==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.5.tgz", - "integrity": "sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", + "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.2", - "@babel/generator": "^7.24.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.24.5", - "@babel/helpers": "^7.24.5", - "@babel/parser": "^7.24.5", - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.5", - "@babel/types": "^7.24.5", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helpers": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -718,12 +674,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.5.tgz", - "integrity": "sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", + "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", "dev": true, "dependencies": { - "@babel/types": "^7.24.5", + "@babel/types": "^7.24.7", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -733,38 +689,39 @@ } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.6.tgz", - "integrity": "sha512-+wnfqc5uHiMYtvRX7qu80Toef8BXeh4HHR1SPeonGb1SKPniNEd4a/nlaJJMv/OIEYvIVavvo0yR7u10Gqz0Iw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", + "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", "dev": true, "dependencies": { - "@babel/types": "^7.24.6" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.6.tgz", - "integrity": "sha512-VZQ57UsDGlX/5fFA7GkVPplZhHsVc+vuErWgdOiysI9Ksnw0Pbbd6pnPiR/mmJyKHgyIW0c7KT32gmhiF+cirg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz", + "integrity": "sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.24.6", - "@babel/helper-validator-option": "^7.24.6", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -782,19 +739,19 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.6.tgz", - "integrity": "sha512-djsosdPJVZE6Vsw3kk7IPRWethP94WHGOhQTc67SNXE0ZzMhHgALw8iGmYS0TD1bbMM0VDROy43od7/hN6WYcA==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.8.tgz", + "integrity": "sha512-4f6Oqnmyp2PP3olgUMmOwC3akxSm5aBYraQ6YDdKy7NcAMkDECHWG0DEnV6M2UAkERgIBhYt8S27rURPg7SxWA==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.6", - "@babel/helper-environment-visitor": "^7.24.6", - "@babel/helper-function-name": "^7.24.6", - "@babel/helper-member-expression-to-functions": "^7.24.6", - "@babel/helper-optimise-call-expression": "^7.24.6", - "@babel/helper-replace-supers": "^7.24.6", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6", - "@babel/helper-split-export-declaration": "^7.24.6", + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", "semver": "^6.3.1" }, "engines": { @@ -804,30 +761,6 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.6.tgz", - "integrity": "sha512-DitEzDfOMnd13kZnDqns1ccmftwJTS9DMkyn9pYTxulS7bZxUxpMly3Nf23QQ6NwA4UB8lAqjbqWtyvElEMAkg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.6.tgz", - "integrity": "sha512-CvLSkwXGWnYlF9+J3iZUvwgAxKiYzK3BWuo+mLzD/MDGOZDj7Gq8+hqaOkMxmJwmlv0iu86uH5fdADd9Hxkymw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -838,12 +771,12 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.6.tgz", - "integrity": "sha512-C875lFBIWWwyv6MHZUG9HmRrlTDgOsLWZfYR0nW69gaKJNe0/Mpxx5r0EID2ZdHQkdUmQo2t0uNckTL08/1BgA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.7.tgz", + "integrity": "sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.6", + "@babel/helper-annotate-as-pure": "^7.24.7", "regexpu-core": "^5.3.1", "semver": "^6.3.1" }, @@ -854,18 +787,6 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.6.tgz", - "integrity": "sha512-DitEzDfOMnd13kZnDqns1ccmftwJTS9DMkyn9pYTxulS7bZxUxpMly3Nf23QQ6NwA4UB8lAqjbqWtyvElEMAkg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -892,74 +813,79 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.6.tgz", - "integrity": "sha512-Y50Cg3k0LKLMjxdPjIl40SdJgMB85iXn27Vk/qbHZCFx/o5XO3PSnpi675h1KEmmDb6OFArfd5SCQEQ5Q4H88g==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", "dev": true, + "dependencies": { + "@babel/types": "^7.24.7" + }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.6.tgz", - "integrity": "sha512-xpeLqeeRkbxhnYimfr2PC+iA0Q7ljX/d1eZ9/inYbmfG2jpl8Lu3DyXvpOAnrS5kxkfOWJjioIMQsaMBXFI05w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", "dev": true, "dependencies": { - "@babel/template": "^7.24.6", - "@babel/types": "^7.24.6" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.6.tgz", - "integrity": "sha512-SF/EMrC3OD7dSta1bLJIlrsVxwtd0UpjRJqLno6125epQMJ/kyFmpTT4pbvPbdQHzCHg+biQ7Syo8lnDtbR+uA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", "dev": true, "dependencies": { - "@babel/types": "^7.24.6" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.6.tgz", - "integrity": "sha512-OTsCufZTxDUsv2/eDXanw/mUZHWOxSbEmC3pP8cgjcy5rgeVPWWMStnv274DV60JtHxTk0adT0QrCzC4M9NWGg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", + "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", "dev": true, "dependencies": { - "@babel/types": "^7.24.6" + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.8" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.6.tgz", - "integrity": "sha512-a26dmxFJBF62rRO9mmpgrfTLsAuyHk4e1hKTUkD/fcMfynt8gvEKwQPQDVxWhca8dHoDck+55DFt42zV0QMw5g==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "dev": true, "dependencies": { - "@babel/types": "^7.24.6" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.6.tgz", - "integrity": "sha512-Y/YMPm83mV2HJTbX1Qh2sjgjqcacvOlhbzdCCsSlblOKjSYmQqEbO6rUniWQyRo9ncyfjT8hnUjlG06RXDEmcA==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.8.tgz", + "integrity": "sha512-m4vWKVqvkVAWLXfHCCfff2luJj86U+J0/x+0N3ArG/tP0Fq7zky2dYwMbtPmkc/oulkkbjdL3uWzuoBwQ8R00Q==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.24.6", - "@babel/helper-module-imports": "^7.24.6", - "@babel/helper-simple-access": "^7.24.6", - "@babel/helper-split-export-declaration": "^7.24.6", - "@babel/helper-validator-identifier": "^7.24.6" + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -968,48 +894,36 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-module-transforms/node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.6.tgz", - "integrity": "sha512-CvLSkwXGWnYlF9+J3iZUvwgAxKiYzK3BWuo+mLzD/MDGOZDj7Gq8+hqaOkMxmJwmlv0iu86uH5fdADd9Hxkymw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.6.tgz", - "integrity": "sha512-3SFDJRbx7KuPRl8XDUr8O7GAEB8iGyWPjLKJh/ywP/Iy9WOmEfMrsWbaZpvBu2HSYn4KQygIsz0O7m8y10ncMA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", "dev": true, "dependencies": { - "@babel/types": "^7.24.6" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.6.tgz", - "integrity": "sha512-MZG/JcWfxybKwsA9N9PmtF2lOSFSEMVCpIRrbxccZFLJPrJciJdG/UhSh5W96GEteJI2ARqm5UAHxISwRDLSNg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.6.tgz", - "integrity": "sha512-1Qursq9ArRZPAMOZf/nuzVW8HgJLkTB9y9LfP4lW2MVp4e9WkLJDovfKBxoDcCk6VuzIxyqWHyBoaCtSRP10yg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.7.tgz", + "integrity": "sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.6", - "@babel/helper-environment-visitor": "^7.24.6", - "@babel/helper-wrap-function": "^7.24.6" + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-wrap-function": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1018,27 +932,15 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-remap-async-to-generator/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.6.tgz", - "integrity": "sha512-DitEzDfOMnd13kZnDqns1ccmftwJTS9DMkyn9pYTxulS7bZxUxpMly3Nf23QQ6NwA4UB8lAqjbqWtyvElEMAkg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-replace-supers": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.6.tgz", - "integrity": "sha512-mRhfPwDqDpba8o1F8ESxsEkJMQkUF8ZIWrAc0FtWhxnjfextxMWxr22RtFizxxSYLjVHDeMgVsRq8BBZR2ikJQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", + "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.24.6", - "@babel/helper-member-expression-to-functions": "^7.24.6", - "@babel/helper-optimise-call-expression": "^7.24.6" + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1048,102 +950,105 @@ } }, "node_modules/@babel/helper-simple-access": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.6.tgz", - "integrity": "sha512-nZzcMMD4ZhmB35MOOzQuiGO5RzL6tJbsT37Zx8M5L/i9KSrukGXWTjLe1knIbb/RmxoJE9GON9soq0c0VEMM5g==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "dev": true, "dependencies": { - "@babel/types": "^7.24.6" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.6.tgz", - "integrity": "sha512-jhbbkK3IUKc4T43WadP96a27oYti9gEf1LdyGSP2rHGH77kwLwfhO7TgwnWvxxQVmke0ImmCSS47vcuxEMGD3Q==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", "dev": true, "dependencies": { - "@babel/types": "^7.24.6" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz", - "integrity": "sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", "dev": true, "dependencies": { - "@babel/types": "^7.24.5" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.6.tgz", - "integrity": "sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.6.tgz", - "integrity": "sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.6.tgz", - "integrity": "sha512-Jktc8KkF3zIkePb48QO+IapbXlSapOW9S+ogZZkcO6bABgYAxtZcjZ/O005111YLf+j4M84uEgwYoidDkXbCkQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.6.tgz", - "integrity": "sha512-f1JLrlw/jbiNfxvdrfBgio/gRBk3yTAEJWirpAkiJG2Hb22E7cEYKHWo0dFPTv/niPovzIdPdEDetrv6tC6gPQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.7.tgz", + "integrity": "sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==", "dev": true, "dependencies": { - "@babel/helper-function-name": "^7.24.6", - "@babel/template": "^7.24.6", - "@babel/types": "^7.24.6" + "@babel/helper-function-name": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.6.tgz", - "integrity": "sha512-V2PI+NqnyFu1i0GyTd/O/cTpxzQCYioSkUIRmgo7gFEHKKCg5w46+r/A6WeUR1+P3TeQ49dspGPNd/E3n9AnnA==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz", + "integrity": "sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==", "dev": true, "dependencies": { - "@babel/template": "^7.24.6", - "@babel/types": "^7.24.6" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.8" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.6.tgz", - "integrity": "sha512-2YnuOp4HAk2BsBrJJvYCbItHx0zWscI1C3zgWkz+wDyD9I7GIVrfnLyrR4Y1VR+7p+chAEcrgRQYZAGIKMV7vQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.24.6", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -1153,9 +1058,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.6.tgz", - "integrity": "sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", + "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -1165,13 +1070,13 @@ } }, "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.6.tgz", - "integrity": "sha512-bYndrJ6Ph6Ar+GaB5VAc0JPoP80bQCm4qon6JEzXfRl5QZyQ8Ur1K6k7htxWmPA5z+k7JQvaMUrtXlqclWYzKw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.7.tgz", + "integrity": "sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.24.6", - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1181,12 +1086,12 @@ } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.6.tgz", - "integrity": "sha512-iVuhb6poq5ikqRq2XWU6OQ+R5o9wF+r/or9CeUyovgptz0UlnK4/seOQ1Istu/XybYjAhQv1FRSSfHHufIku5Q==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.7.tgz", + "integrity": "sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1196,14 +1101,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.6.tgz", - "integrity": "sha512-c8TER5xMDYzzFcGqOEp9l4hvB7dcbhcGjcLVwxWfe4P5DOafdwjsBJZKsmv+o3aXh7NhopvayQIovHrh2zSRUQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", + "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6", - "@babel/plugin-transform-optional-chaining": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1213,13 +1118,13 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.6.tgz", - "integrity": "sha512-z8zEjYmwBUHN/pCF3NuWBhHQjJCrd33qAi8MgANfMrAvn72k2cImT8VjK9LJFu4ysOLJqhfkYYb3MvwANRUNZQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.7.tgz", + "integrity": "sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.24.6", - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1304,12 +1209,12 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.6.tgz", - "integrity": "sha512-BE6o2BogJKJImTmGpkmOic4V0hlRRxVtzqxiSPa8TIFxyhi4EFjHm08nq1M4STK4RytuLMgnSz0/wfflvGFNOg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", + "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1319,12 +1224,12 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.6.tgz", - "integrity": "sha512-D+CfsVZousPXIdudSII7RGy52+dYRtbyKAZcvtQKq/NpsivyMVduepzcLqG5pMBugtMdedxdC8Ramdpcne9ZWQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", + "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1476,12 +1381,12 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.6.tgz", - "integrity": "sha512-jSSSDt4ZidNMggcLx8SaKsbGNEfIl0PHx/4mFEulorE7bpYLbN0d3pDW3eJ7Y5Z3yPhy3L3NaPCYyTUY7TuugQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", + "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1491,14 +1396,14 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz", - "integrity": "sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.7.tgz", + "integrity": "sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7", "@babel/plugin-syntax-async-generators": "^7.8.4" }, "engines": { @@ -1509,14 +1414,14 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz", - "integrity": "sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", + "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-remap-async-to-generator": "^7.22.20" + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1526,12 +1431,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.6.tgz", - "integrity": "sha512-XNW7jolYHW9CwORrZgA/97tL/k05qe/HL0z/qqJq1mdWhwwCM6D4BJBV7wAz9HgFziN5dTOG31znkVIzwxv+vw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", + "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1541,12 +1446,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.6.tgz", - "integrity": "sha512-S/t1Xh4ehW7sGA7c1j/hiOBLnEYCp/c2sEG4ZkL8kI1xX9tW2pqJTCHKtdhe/jHKt8nG0pFCrDHUXd4DvjHS9w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.7.tgz", + "integrity": "sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1556,13 +1461,13 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.6.tgz", - "integrity": "sha512-j6dZ0Z2Z2slWLR3kt9aOmSIrBvnntWjMDN/TVcMPxhXMLmJVqX605CBRlcGI4b32GMbfifTEsdEjGjiE+j/c3A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", + "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.6", - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1572,13 +1477,13 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.6.tgz", - "integrity": "sha512-1QSRfoPI9RoLRa8Mnakc6v3e0gJxiZQTYrMfLn+mD0sz5+ndSzwymp2hDcYJTyT0MOn0yuWzj8phlIvO72gTHA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", + "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.6", - "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, "engines": { @@ -1589,18 +1494,18 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.6.tgz", - "integrity": "sha512-+fN+NO2gh8JtRmDSOB6gaCVo36ha8kfCW1nMq2Gc0DABln0VcHN4PrALDvF5/diLzIRKptC7z/d7Lp64zk92Fg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.8.tgz", + "integrity": "sha512-VXy91c47uujj758ud9wx+OMgheXm4qJfyhj1P18YvlrQkNOSrwsteHk+EFS3OMGfhMhpZa0A+81eE7G4QC+3CA==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.6", - "@babel/helper-compilation-targets": "^7.24.6", - "@babel/helper-environment-visitor": "^7.24.6", - "@babel/helper-function-name": "^7.24.6", - "@babel/helper-plugin-utils": "^7.24.6", - "@babel/helper-replace-supers": "^7.24.6", - "@babel/helper-split-export-declaration": "^7.24.6", + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", "globals": "^11.1.0" }, "engines": { @@ -1610,38 +1515,14 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.6.tgz", - "integrity": "sha512-DitEzDfOMnd13kZnDqns1ccmftwJTS9DMkyn9pYTxulS7bZxUxpMly3Nf23QQ6NwA4UB8lAqjbqWtyvElEMAkg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.6.tgz", - "integrity": "sha512-CvLSkwXGWnYlF9+J3iZUvwgAxKiYzK3BWuo+mLzD/MDGOZDj7Gq8+hqaOkMxmJwmlv0iu86uH5fdADd9Hxkymw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.6.tgz", - "integrity": "sha512-cRzPobcfRP0ZtuIEkA8QzghoUpSB3X3qSH5W2+FzG+VjWbJXExtx0nbRqwumdBN1x/ot2SlTNQLfBCnPdzp6kg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", + "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6", - "@babel/template": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/template": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1651,12 +1532,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.6.tgz", - "integrity": "sha512-YLW6AE5LQpk5npNXL7i/O+U9CE4XsBCuRPgyjl1EICZYKmcitV+ayuuUGMJm2lC1WWjXYszeTnIxF/dq/GhIZQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz", + "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -1666,13 +1547,13 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.6.tgz", - "integrity": "sha512-rCXPnSEKvkm/EjzOtLoGvKseK+dS4kZwx1HexO3BtRtgL0fQ34awHn34aeSHuXtZY2F8a1X8xqBBPRtOxDVmcA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", + "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.6", - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1682,12 +1563,12 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.6.tgz", - "integrity": "sha512-/8Odwp/aVkZwPFJMllSbawhDAO3UJi65foB00HYnK/uXvvCPm0TAXSByjz1mpRmp0q6oX2SIxpkUOpPFHk7FLA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", + "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1697,12 +1578,12 @@ } }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.6.tgz", - "integrity": "sha512-vpq8SSLRTBLOHUZHSnBqVo0AKX3PBaoPs2vVzYVWslXDTDIpwAcCDtfhUcHSQQoYoUvcFPTdC8TZYXu9ZnLT/w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", + "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.7", "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { @@ -1713,13 +1594,13 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.6.tgz", - "integrity": "sha512-EemYpHtmz0lHE7hxxxYEuTYOOBZ43WkDgZ4arQ4r+VX9QHuNZC+WH3wUWmRNvR8ECpTRne29aZV6XO22qpOtdA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", + "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", "dev": true, "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.6", - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1729,12 +1610,12 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.6.tgz", - "integrity": "sha512-inXaTM1SVrIxCkIJ5gqWiozHfFMStuGbGJAxZFBoHcRRdDP0ySLb3jH6JOwmfiinPwyMZqMBX+7NBDCO4z0NSA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", + "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.7", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { @@ -1745,13 +1626,13 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.6.tgz", - "integrity": "sha512-n3Sf72TnqK4nw/jziSqEl1qaWPbCRw2CziHH+jdRYvw4J6yeCzsj4jdw8hIntOEeDGTmHVe2w4MVL44PN0GMzg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", + "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1761,14 +1642,14 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.6.tgz", - "integrity": "sha512-sOajCu6V0P1KPljWHKiDq6ymgqB+vfo3isUS4McqW1DZtvSVU2v/wuMhmRmkg3sFoq6GMaUUf8W4WtoSLkOV/Q==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.7.tgz", + "integrity": "sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.24.6", - "@babel/helper-function-name": "^7.24.6", - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1778,12 +1659,12 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.6.tgz", - "integrity": "sha512-Uvgd9p2gUnzYJxVdBLcU0KurF8aVhkmVyMKW4MIY1/BByvs3EBpv45q01o7pRTVmTvtQq5zDlytP3dcUgm7v9w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", + "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.7", "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { @@ -1794,12 +1675,12 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.6.tgz", - "integrity": "sha512-f2wHfR2HF6yMj+y+/y07+SLqnOSwRp8KYLpQKOzS58XLVlULhXbiYcygfXQxJlMbhII9+yXDwOUFLf60/TL5tw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.7.tgz", + "integrity": "sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1809,12 +1690,12 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.6.tgz", - "integrity": "sha512-EKaWvnezBCMkRIHxMJSIIylzhqK09YpiJtDbr2wsXTwnO0TxyjMUkaw4RlFIZMIS0iDj0KyIg7H7XCguHu/YDA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", + "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.7", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { @@ -1825,12 +1706,12 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.6.tgz", - "integrity": "sha512-9g8iV146szUo5GWgXpRbq/GALTnY+WnNuRTuRHWWFfWGbP9ukRL0aO/jpu9dmOPikclkxnNsjY8/gsWl6bmZJQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", + "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1840,13 +1721,13 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.6.tgz", - "integrity": "sha512-eAGogjZgcwqAxhyFgqghvoHRr+EYRQPFjUXrTYKBRb5qPnAVxOOglaxc4/byHqjvq/bqO2F3/CGwTHsgKJYHhQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", + "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.24.6", - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1856,14 +1737,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.6.tgz", - "integrity": "sha512-JEV8l3MHdmmdb7S7Cmx6rbNEjRCgTQMZxllveHO0mx6uiclB0NflCawlQQ6+o5ZrwjUBYPzHm2XoK4wqGVUFuw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", + "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.24.6", - "@babel/helper-plugin-utils": "^7.24.6", - "@babel/helper-simple-access": "^7.24.6" + "@babel/helper-module-transforms": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-simple-access": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1873,15 +1754,15 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.6.tgz", - "integrity": "sha512-xg1Z0J5JVYxtpX954XqaaAT6NpAY6LtZXvYFCJmGFJWwtlz2EmJoR8LycFRGNE8dBKizGWkGQZGegtkV8y8s+w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.7.tgz", + "integrity": "sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==", "dev": true, "dependencies": { - "@babel/helper-hoist-variables": "^7.24.6", - "@babel/helper-module-transforms": "^7.24.6", - "@babel/helper-plugin-utils": "^7.24.6", - "@babel/helper-validator-identifier": "^7.24.6" + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1891,13 +1772,13 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.6.tgz", - "integrity": "sha512-esRCC/KsSEUvrSjv5rFYnjZI6qv4R1e/iHQrqwbZIoRJqk7xCvEUiN7L1XrmW5QSmQe3n1XD88wbgDTWLbVSyg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", + "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.24.6", - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1907,13 +1788,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.6.tgz", - "integrity": "sha512-6DneiCiu91wm3YiNIGDWZsl6GfTTbspuj/toTEqLh9d4cx50UIzSdg+T96p8DuT7aJOBRhFyaE9ZvTHkXrXr6Q==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", + "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.6", - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1923,12 +1804,12 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.6.tgz", - "integrity": "sha512-f8liz9JG2Va8A4J5ZBuaSdwfPqN6axfWRK+y66fjKYbwf9VBLuq4WxtinhJhvp1w6lamKUwLG0slK2RxqFgvHA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", + "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1938,12 +1819,12 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.6.tgz", - "integrity": "sha512-+QlAiZBMsBK5NqrBWFXCYeXyiU1y7BQ/OYaiPAcQJMomn5Tyg+r5WuVtyEuvTbpV7L25ZSLfE+2E9ywj4FD48A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", + "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.7", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" }, "engines": { @@ -1954,12 +1835,12 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.6.tgz", - "integrity": "sha512-6voawq8T25Jvvnc4/rXcWZQKKxUNZcKMS8ZNrjxQqoRFernJJKjE3s18Qo6VFaatG5aiX5JV1oPD7DbJhn0a4Q==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", + "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.7", "@babel/plugin-syntax-numeric-separator": "^7.10.4" }, "engines": { @@ -1970,15 +1851,15 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.6.tgz", - "integrity": "sha512-OKmi5wiMoRW5Smttne7BwHM8s/fb5JFs+bVGNSeHWzwZkWXWValR1M30jyXo1s/RaqgwwhEC62u4rFH/FBcBPg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", + "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.24.6", - "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.6" + "@babel/plugin-transform-parameters": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -1988,13 +1869,13 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.6.tgz", - "integrity": "sha512-N/C76ihFKlZgKfdkEYKtaRUtXZAgK7sOY4h2qrbVbVTXPrKGIi8aww5WGe/+Wmg8onn8sr2ut6FXlsbu/j6JHg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", + "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6", - "@babel/helper-replace-supers": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -2004,12 +1885,12 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.6.tgz", - "integrity": "sha512-L5pZ+b3O1mSzJ71HmxSCmTVd03VOT2GXOigug6vDYJzE5awLI7P1g0wFcdmGuwSDSrQ0L2rDOe/hHws8J1rv3w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", + "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.7", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" }, "engines": { @@ -2020,13 +1901,13 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.6.tgz", - "integrity": "sha512-cHbqF6l1QP11OkYTYQ+hhVx1E017O5ZcSPXk9oODpqhcAD1htsWG2NpHrrhthEO2qZomLK0FXS+u7NfrkF5aOQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz", + "integrity": "sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { @@ -2037,12 +1918,12 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.6.tgz", - "integrity": "sha512-ST7guE8vLV+vI70wmAxuZpIKzVjvFX9Qs8bl5w6tN/6gOypPWUmMQL2p7LJz5E63vEGrDhAiYetniJFyBH1RkA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", + "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -2052,13 +1933,13 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.6.tgz", - "integrity": "sha512-T9LtDI0BgwXOzyXrvgLTT8DFjCC/XgWLjflczTLXyvxbnSR/gpv0hbmzlHE/kmh9nOvlygbamLKRo6Op4yB6aw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", + "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.6", - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -2068,14 +1949,14 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.6.tgz", - "integrity": "sha512-Qu/ypFxCY5NkAnEhCF86Mvg3NSabKsh/TPpBVswEdkGl7+FbsYHy1ziRqJpwGH4thBdQHh8zx+z7vMYmcJ7iaQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", + "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.6", - "@babel/helper-create-class-features-plugin": "^7.24.6", - "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { @@ -2085,25 +1966,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-private-property-in-object/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.6.tgz", - "integrity": "sha512-DitEzDfOMnd13kZnDqns1ccmftwJTS9DMkyn9pYTxulS7bZxUxpMly3Nf23QQ6NwA4UB8lAqjbqWtyvElEMAkg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.6.tgz", - "integrity": "sha512-oARaglxhRsN18OYsnPTpb8TcKQWDYNsPNmTnx5++WOAsUJ0cSC/FZVlIJCKvPbU4yn/UXsS0551CFKJhN0CaMw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", + "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -2113,12 +1982,12 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.6.tgz", - "integrity": "sha512-SMDxO95I8WXRtXhTAc8t/NFQUT7VYbIWwJCJgEli9ml4MhqUMh4S6hxgH6SmAC3eAQNWCDJFxcFeEt9w2sDdXg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", + "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.7", "regenerator-transform": "^0.15.2" }, "engines": { @@ -2129,12 +1998,12 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.6.tgz", - "integrity": "sha512-DcrgFXRRlK64dGE0ZFBPD5egM2uM8mgfrvTMOSB2yKzOtjpGegVYkzh3s1zZg1bBck3nkXiaOamJUqK3Syk+4A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", + "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -2144,13 +2013,13 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.3.tgz", - "integrity": "sha512-J0BuRPNlNqlMTRJ72eVptpt9VcInbxO6iP3jaxr+1NPhC0UkKL+6oeX6VXMEYdADnuqmMmsBspt4d5w8Y/TCbQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.7.tgz", + "integrity": "sha512-YqXjrk4C+a1kZjewqt+Mmu2UuV1s07y8kqcUf4qYLnoqemhR4gRQikhdAhSVJioMjVTu6Mo6pAbaypEA3jY6fw==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.24.3", - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", "babel-plugin-polyfill-corejs2": "^0.4.10", "babel-plugin-polyfill-corejs3": "^0.10.1", "babel-plugin-polyfill-regenerator": "^0.6.1", @@ -2173,12 +2042,12 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.6.tgz", - "integrity": "sha512-xnEUvHSMr9eOWS5Al2YPfc32ten7CXdH7Zwyyk7IqITg4nX61oHj+GxpNvl+y5JHjfN3KXE2IV55wAWowBYMVw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", + "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -2188,13 +2057,13 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.6.tgz", - "integrity": "sha512-h/2j7oIUDjS+ULsIrNZ6/TKG97FgmEk1PXryk/HQq6op4XUUUwif2f69fJrzK0wza2zjCS1xhXmouACaWV5uPA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", + "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -2204,12 +2073,12 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.6.tgz", - "integrity": "sha512-fN8OcTLfGmYv7FnDrsjodYBo1DhPL3Pze/9mIIE2MGCT1KgADYIOD7rEglpLHZj8PZlC/JFX5WcD+85FLAQusw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", + "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -2219,12 +2088,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.6.tgz", - "integrity": "sha512-BJbEqJIcKwrqUP+KfUIkxz3q8VzXe2R8Wv8TaNgO1cx+nNavxn/2+H8kp9tgFSOL6wYPPEgFvU6IKS4qoGqhmg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", + "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -2234,12 +2103,12 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.6.tgz", - "integrity": "sha512-IshCXQ+G9JIFJI7bUpxTE/oA2lgVLAIK8q1KdJNoPXOpvRaNjMySGuvLfBw/Xi2/1lLo953uE8hyYSDW3TSYig==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz", + "integrity": "sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -2249,12 +2118,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.6.tgz", - "integrity": "sha512-bKl3xxcPbkQQo5eX9LjjDpU2xYHeEeNQbOhj0iPvetSzA+Tu9q/o5lujF4Sek60CM6MgYvOS/DJuwGbiEYAnLw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", + "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -2264,13 +2133,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.6.tgz", - "integrity": "sha512-8EIgImzVUxy15cZiPii9GvLZwsy7Vxc+8meSlR3cXFmBIl5W5Tn9LGBf7CDKkHj4uVfNXCJB8RsVfnmY61iedA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", + "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.6", - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -2280,13 +2149,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.6.tgz", - "integrity": "sha512-pssN6ExsvxaKU638qcWb81RrvvgZom3jDgU/r5xFZ7TONkZGFf4MhI2ltMb8OcQWhHyxgIavEU+hgqtbKOmsPA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", + "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.6", - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -2296,13 +2165,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.6.tgz", - "integrity": "sha512-quiMsb28oXWIDK0gXLALOJRXLgICLiulqdZGOaPPd0vRT7fQp74NtdADAVu+D8s00C+0Xs0MxVP0VKF/sZEUgw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz", + "integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.24.6", - "@babel/helper-plugin-utils": "^7.24.6" + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -2312,27 +2181,27 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.5.tgz", - "integrity": "sha512-UGK2ifKtcC8i5AI4cH+sbLLuLc2ktYSFJgBAXorKAsHUZmrQ1q6aQ6i3BvU24wWs2AAKqQB6kq3N9V9Gw1HiMQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.7.tgz", + "integrity": "sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.24.4", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.5", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.1", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.1", + "@babel/compat-data": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.7", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.7", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.24.1", - "@babel/plugin-syntax-import-attributes": "^7.24.1", + "@babel/plugin-syntax-import-assertions": "^7.24.7", + "@babel/plugin-syntax-import-attributes": "^7.24.7", "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", @@ -2344,54 +2213,54 @@ "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.24.1", - "@babel/plugin-transform-async-generator-functions": "^7.24.3", - "@babel/plugin-transform-async-to-generator": "^7.24.1", - "@babel/plugin-transform-block-scoped-functions": "^7.24.1", - "@babel/plugin-transform-block-scoping": "^7.24.5", - "@babel/plugin-transform-class-properties": "^7.24.1", - "@babel/plugin-transform-class-static-block": "^7.24.4", - "@babel/plugin-transform-classes": "^7.24.5", - "@babel/plugin-transform-computed-properties": "^7.24.1", - "@babel/plugin-transform-destructuring": "^7.24.5", - "@babel/plugin-transform-dotall-regex": "^7.24.1", - "@babel/plugin-transform-duplicate-keys": "^7.24.1", - "@babel/plugin-transform-dynamic-import": "^7.24.1", - "@babel/plugin-transform-exponentiation-operator": "^7.24.1", - "@babel/plugin-transform-export-namespace-from": "^7.24.1", - "@babel/plugin-transform-for-of": "^7.24.1", - "@babel/plugin-transform-function-name": "^7.24.1", - "@babel/plugin-transform-json-strings": "^7.24.1", - "@babel/plugin-transform-literals": "^7.24.1", - "@babel/plugin-transform-logical-assignment-operators": "^7.24.1", - "@babel/plugin-transform-member-expression-literals": "^7.24.1", - "@babel/plugin-transform-modules-amd": "^7.24.1", - "@babel/plugin-transform-modules-commonjs": "^7.24.1", - "@babel/plugin-transform-modules-systemjs": "^7.24.1", - "@babel/plugin-transform-modules-umd": "^7.24.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.24.1", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1", - "@babel/plugin-transform-numeric-separator": "^7.24.1", - "@babel/plugin-transform-object-rest-spread": "^7.24.5", - "@babel/plugin-transform-object-super": "^7.24.1", - "@babel/plugin-transform-optional-catch-binding": "^7.24.1", - "@babel/plugin-transform-optional-chaining": "^7.24.5", - "@babel/plugin-transform-parameters": "^7.24.5", - "@babel/plugin-transform-private-methods": "^7.24.1", - "@babel/plugin-transform-private-property-in-object": "^7.24.5", - "@babel/plugin-transform-property-literals": "^7.24.1", - "@babel/plugin-transform-regenerator": "^7.24.1", - "@babel/plugin-transform-reserved-words": "^7.24.1", - "@babel/plugin-transform-shorthand-properties": "^7.24.1", - "@babel/plugin-transform-spread": "^7.24.1", - "@babel/plugin-transform-sticky-regex": "^7.24.1", - "@babel/plugin-transform-template-literals": "^7.24.1", - "@babel/plugin-transform-typeof-symbol": "^7.24.5", - "@babel/plugin-transform-unicode-escapes": "^7.24.1", - "@babel/plugin-transform-unicode-property-regex": "^7.24.1", - "@babel/plugin-transform-unicode-regex": "^7.24.1", - "@babel/plugin-transform-unicode-sets-regex": "^7.24.1", + "@babel/plugin-transform-arrow-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.24.7", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoped-functions": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.24.7", + "@babel/plugin-transform-class-properties": "^7.24.7", + "@babel/plugin-transform-class-static-block": "^7.24.7", + "@babel/plugin-transform-classes": "^7.24.7", + "@babel/plugin-transform-computed-properties": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.7", + "@babel/plugin-transform-dotall-regex": "^7.24.7", + "@babel/plugin-transform-duplicate-keys": "^7.24.7", + "@babel/plugin-transform-dynamic-import": "^7.24.7", + "@babel/plugin-transform-exponentiation-operator": "^7.24.7", + "@babel/plugin-transform-export-namespace-from": "^7.24.7", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.24.7", + "@babel/plugin-transform-json-strings": "^7.24.7", + "@babel/plugin-transform-literals": "^7.24.7", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-member-expression-literals": "^7.24.7", + "@babel/plugin-transform-modules-amd": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.7", + "@babel/plugin-transform-modules-systemjs": "^7.24.7", + "@babel/plugin-transform-modules-umd": "^7.24.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-new-target": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-numeric-separator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-object-super": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-property-literals": "^7.24.7", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/plugin-transform-reserved-words": "^7.24.7", + "@babel/plugin-transform-shorthand-properties": "^7.24.7", + "@babel/plugin-transform-spread": "^7.24.7", + "@babel/plugin-transform-sticky-regex": "^7.24.7", + "@babel/plugin-transform-template-literals": "^7.24.7", + "@babel/plugin-transform-typeof-symbol": "^7.24.7", + "@babel/plugin-transform-unicode-escapes": "^7.24.7", + "@babel/plugin-transform-unicode-property-regex": "^7.24.7", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.7", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.10", "babel-plugin-polyfill-corejs3": "^0.10.4", @@ -2436,9 +2305,9 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", - "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", "dev": true, "dependencies": { "regenerator-runtime": "^0.14.0" @@ -2448,33 +2317,33 @@ } }, "node_modules/@babel/template": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.6.tgz", - "integrity": "sha512-3vgazJlLwNXi9jhrR1ef8qiB65L1RK90+lEQwv4OxveHnqC3BfmnHdgySwRLzf6akhlOYenT+b7AfWq+a//AHw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.24.6", - "@babel/parser": "^7.24.6", - "@babel/types": "^7.24.6" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.6.tgz", - "integrity": "sha512-OsNjaJwT9Zn8ozxcfoBc+RaHdj3gFmCmYoQLUII1o6ZrUwku0BMg80FoOTPx+Gi6XhcQxAYE4xyjPTo4SxEQqw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz", + "integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.24.6", - "@babel/generator": "^7.24.6", - "@babel/helper-environment-visitor": "^7.24.6", - "@babel/helper-function-name": "^7.24.6", - "@babel/helper-hoist-variables": "^7.24.6", - "@babel/helper-split-export-declaration": "^7.24.6", - "@babel/parser": "^7.24.6", - "@babel/types": "^7.24.6", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.8", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.8", + "@babel/types": "^7.24.8", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2483,12 +2352,12 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/generator": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.6.tgz", - "integrity": "sha512-S7m4eNa6YAPJRHmKsLHIDJhNAGNKoWNiWefz1MBbpnt8g9lvMDl1hir4P9bo/57bQEmuwEhnRU/AMWsD0G/Fbg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.8.tgz", + "integrity": "sha512-47DG+6F5SzOi0uEvK4wMShmn5yY0mVjVJoWTphdY2B4Rx9wHgjK7Yhtr0ru6nE+sn0v38mzrWOlah0p/YlHHOQ==", "dev": true, "dependencies": { - "@babel/types": "^7.24.6", + "@babel/types": "^7.24.8", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -2497,26 +2366,14 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/traverse/node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.6.tgz", - "integrity": "sha512-CvLSkwXGWnYlF9+J3iZUvwgAxKiYzK3BWuo+mLzD/MDGOZDj7Gq8+hqaOkMxmJwmlv0iu86uH5fdADd9Hxkymw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/types": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.6.tgz", - "integrity": "sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.8.tgz", + "integrity": "sha512-SkSBEHwwJRU52QEVZBmMBnE5Ux2/6WU1grdYyOhpbCNxbmJrDuDCphBzKZSO3taf0zztp+qkWlymE5tVL5l0TA==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.24.6", - "@babel/helper-validator-identifier": "^7.24.6", + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -2542,9 +2399,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.3.tgz", - "integrity": "sha512-yTgnwQpFVYfvvo4SvRFB0SwrW8YjOxEoT7wfMT7Ol5v7v5LDNvSGo67aExmxOb87nQNeWPVvaGBNfQ7BXcrZ9w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", "cpu": [ "ppc64" ], @@ -2558,9 +2415,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.3.tgz", - "integrity": "sha512-bviJOLMgurLJtF1/mAoJLxDZDL6oU5/ztMHnJQRejbJrSc9FFu0QoUoFhvi6qSKJEw9y5oGyvr9fuDtzJ30rNQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", "cpu": [ "arm" ], @@ -2574,9 +2431,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.3.tgz", - "integrity": "sha512-c+ty9necz3zB1Y+d/N+mC6KVVkGUUOcm4ZmT5i/Fk5arOaY3i6CA3P5wo/7+XzV8cb4GrI/Zjp8NuOQ9Lfsosw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", "cpu": [ "arm64" ], @@ -2590,9 +2447,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.3.tgz", - "integrity": "sha512-JReHfYCRK3FVX4Ra+y5EBH1b9e16TV2OxrPAvzMsGeES0X2Ndm9ImQRI4Ket757vhc5XBOuGperw63upesclRw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "cpu": [ "x64" ], @@ -2606,9 +2463,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.3.tgz", - "integrity": "sha512-U3fuQ0xNiAkXOmQ6w5dKpEvXQRSpHOnbw7gEfHCRXPeTKW9sBzVck6C5Yneb8LfJm0l6le4NQfkNPnWMSlTFUQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], @@ -2622,9 +2479,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.3.tgz", - "integrity": "sha512-3m1CEB7F07s19wmaMNI2KANLcnaqryJxO1fXHUV5j1rWn+wMxdUYoPyO2TnAbfRZdi7ADRwJClmOwgT13qlP3Q==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "cpu": [ "x64" ], @@ -2638,9 +2495,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.3.tgz", - "integrity": "sha512-fsNAAl5pU6wmKHq91cHWQT0Fz0vtyE1JauMzKotrwqIKAswwP5cpHUCxZNSTuA/JlqtScq20/5KZ+TxQdovU/g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", "cpu": [ "arm64" ], @@ -2654,9 +2511,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.3.tgz", - "integrity": "sha512-tci+UJ4zP5EGF4rp8XlZIdq1q1a/1h9XuronfxTMCNBslpCtmk97Q/5qqy1Mu4zIc0yswN/yP/BLX+NTUC1bXA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", "cpu": [ "x64" ], @@ -2670,9 +2527,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.3.tgz", - "integrity": "sha512-f6kz2QpSuyHHg01cDawj0vkyMwuIvN62UAguQfnNVzbge2uWLhA7TCXOn83DT0ZvyJmBI943MItgTovUob36SQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", "cpu": [ "arm" ], @@ -2686,9 +2543,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.3.tgz", - "integrity": "sha512-vvG6R5g5ieB4eCJBQevyDMb31LMHthLpXTc2IGkFnPWS/GzIFDnaYFp558O+XybTmYrVjxnryru7QRleJvmZ6Q==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", "cpu": [ "arm64" ], @@ -2702,9 +2559,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.3.tgz", - "integrity": "sha512-HjCWhH7K96Na+66TacDLJmOI9R8iDWDDiqe17C7znGvvE4sW1ECt9ly0AJ3dJH62jHyVqW9xpxZEU1jKdt+29A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", "cpu": [ "ia32" ], @@ -2718,9 +2575,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.3.tgz", - "integrity": "sha512-BGpimEccmHBZRcAhdlRIxMp7x9PyJxUtj7apL2IuoG9VxvU/l/v1z015nFs7Si7tXUwEsvjc1rOJdZCn4QTU+Q==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", "cpu": [ "loong64" ], @@ -2734,9 +2591,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.3.tgz", - "integrity": "sha512-5rMOWkp7FQGtAH3QJddP4w3s47iT20hwftqdm7b+loe95o8JU8ro3qZbhgMRy0VuFU0DizymF1pBKkn3YHWtsw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", "cpu": [ "mips64el" ], @@ -2750,9 +2607,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.3.tgz", - "integrity": "sha512-h0zj1ldel89V5sjPLo5H1SyMzp4VrgN1tPkN29TmjvO1/r0MuMRwJxL8QY05SmfsZRs6TF0c/IDH3u7XYYmbAg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", "cpu": [ "ppc64" ], @@ -2766,9 +2623,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.3.tgz", - "integrity": "sha512-dkAKcTsTJ+CRX6bnO17qDJbLoW37npd5gSNtSzjYQr0svghLJYGYB0NF1SNcU1vDcjXLYS5pO4qOW4YbFama4A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", "cpu": [ "riscv64" ], @@ -2782,9 +2639,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.3.tgz", - "integrity": "sha512-vnD1YUkovEdnZWEuMmy2X2JmzsHQqPpZElXx6dxENcIwTu+Cu5ERax6+Ke1QsE814Zf3c6rxCfwQdCTQ7tPuXA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", "cpu": [ "s390x" ], @@ -2798,9 +2655,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.3.tgz", - "integrity": "sha512-IOXOIm9WaK7plL2gMhsWJd+l2bfrhfilv0uPTptoRoSb2p09RghhQQp9YY6ZJhk/kqmeRt6siRdMSLLwzuT0KQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "cpu": [ "x64" ], @@ -2814,9 +2671,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.3.tgz", - "integrity": "sha512-uTgCwsvQ5+vCQnqM//EfDSuomo2LhdWhFPS8VL8xKf+PKTCrcT/2kPPoWMTs22aB63MLdGMJiE3f1PHvCDmUOw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", "cpu": [ "x64" ], @@ -2830,9 +2687,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.3.tgz", - "integrity": "sha512-vNAkR17Ub2MgEud2Wag/OE4HTSI6zlb291UYzHez/psiKarp0J8PKGDnAhMBcHFoOHMXHfExzmjMojJNbAStrQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", "cpu": [ "x64" ], @@ -2846,9 +2703,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.3.tgz", - "integrity": "sha512-W8H9jlGiSBomkgmouaRoTXo49j4w4Kfbl6I1bIdO/vT0+0u4f20ko3ELzV3hPI6XV6JNBVX+8BC+ajHkvffIJA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "cpu": [ "x64" ], @@ -2862,9 +2719,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.3.tgz", - "integrity": "sha512-EjEomwyLSCg8Ag3LDILIqYCZAq/y3diJ04PnqGRgq8/4O3VNlXyMd54j/saShaN4h5o5mivOjAzmU6C3X4v0xw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "cpu": [ "arm64" ], @@ -2878,9 +2735,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.3.tgz", - "integrity": "sha512-WGiE/GgbsEwR33++5rzjiYsKyHywE8QSZPF7Rfx9EBfK3Qn3xyR6IjyCr5Uk38Kg8fG4/2phN7sXp4NPWd3fcw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "cpu": [ "ia32" ], @@ -2894,9 +2751,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.3.tgz", - "integrity": "sha512-xRxC0jaJWDLYvcUvjQmHCJSfMrgmUuvsoXgDeU/wTorQ1ngDdUBuFtgY3W1Pc5sprGAvZBtWdJX7RPg/iZZUqA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "cpu": [ "x64" ], @@ -2909,11 +2766,348 @@ "node": ">=12" } }, - "node_modules/@inquirer/figures": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.2.tgz", - "integrity": "sha512-4F1MBwVr3c/m4bAUef6LgkvBfSjzwH+OfldgHqcuacWwSUetFebM2wi58WfG9uk1rR98U6GwLed4asLJbwdV5w==", + "node_modules/@inquirer/checkbox": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-2.3.10.tgz", + "integrity": "sha512-CTc864M2/523rKc9AglIzAcUCuPXDZENgc5S2KZFVRbnMzpXcYTsUWmbqSeL0XLvtlvEtNevkkVbfVhJpruOyQ==", "dev": true, + "dependencies": { + "@inquirer/core": "^9.0.2", + "@inquirer/figures": "^1.0.3", + "@inquirer/type": "^1.4.0", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/checkbox/node_modules/@inquirer/core": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.0.2.tgz", + "integrity": "sha512-nguvH3TZar3ACwbytZrraRTzGqyxJfYJwv+ZwqZNatAosdWQMP1GV8zvmkNlBe2JeZSaw0WYBHZk52pDpWC9qA==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.3", + "@inquirer/type": "^1.4.0", + "@types/mute-stream": "^0.0.4", + "@types/node": "^20.14.9", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/confirm": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-3.1.11.tgz", + "integrity": "sha512-3wWw10VPxQP279FO4bzWsf8YjIAq7NdwATJ4xS2h1uwsXZu/RmtOVV95rZ7yllS1h/dzu+uLewjMAzNDEj8h2w==", + "dev": true, + "dependencies": { + "@inquirer/core": "^8.2.4", + "@inquirer/type": "^1.3.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/core": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-8.2.4.tgz", + "integrity": "sha512-7vsXSfxtrrbwMTirfaKwPcjqJy7pzeuF/bP62yo1NQrRJ5HjmMlrhZml/Ljm9ODc1RnbhJlTeSnCkjtFddKjwA==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.3", + "@inquirer/type": "^1.3.3", + "@types/mute-stream": "^0.0.4", + "@types/node": "^20.14.9", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "picocolors": "^1.0.1", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/editor": { + "version": "2.1.14", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-2.1.14.tgz", + "integrity": "sha512-6nWpoJyVAKwAcv67bkbBmmi3f32xua79fP7TRmNUoR4K+B1GiOBsHO1YdvET/jvC+nTlBZL7puKAKyM7G+Lkzw==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.0.2", + "@inquirer/type": "^1.4.0", + "external-editor": "^3.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/editor/node_modules/@inquirer/core": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.0.2.tgz", + "integrity": "sha512-nguvH3TZar3ACwbytZrraRTzGqyxJfYJwv+ZwqZNatAosdWQMP1GV8zvmkNlBe2JeZSaw0WYBHZk52pDpWC9qA==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.3", + "@inquirer/type": "^1.4.0", + "@types/mute-stream": "^0.0.4", + "@types/node": "^20.14.9", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/expand": { + "version": "2.1.14", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-2.1.14.tgz", + "integrity": "sha512-JcxsLajwPykF2kq6biIUdoOzTQ3LXqb8XMVrWkCprG/pFeU1SsxcSSFbF1T5jJGvvlTVcsE+JdGjbQ8ZRZ82RA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.0.2", + "@inquirer/type": "^1.4.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/expand/node_modules/@inquirer/core": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.0.2.tgz", + "integrity": "sha512-nguvH3TZar3ACwbytZrraRTzGqyxJfYJwv+ZwqZNatAosdWQMP1GV8zvmkNlBe2JeZSaw0WYBHZk52pDpWC9qA==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.3", + "@inquirer/type": "^1.4.0", + "@types/mute-stream": "^0.0.4", + "@types/node": "^20.14.9", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.3.tgz", + "integrity": "sha512-ErXXzENMH5pJt5/ssXV0DfWUZqly8nGzf0UcBV9xTnP+KyffE2mqyxIMBrZ8ijQck2nU0TQm40EQB53YreyWHw==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-2.2.1.tgz", + "integrity": "sha512-Yl1G6h7qWydzrJwqN777geeJVaAFL5Ly83aZlw4xHf8Z/BoTMfKRheyuMaQwOG7LQ4e5nQP7PxXdEg4SzQ+OKw==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.0.2", + "@inquirer/type": "^1.4.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input/node_modules/@inquirer/core": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.0.2.tgz", + "integrity": "sha512-nguvH3TZar3ACwbytZrraRTzGqyxJfYJwv+ZwqZNatAosdWQMP1GV8zvmkNlBe2JeZSaw0WYBHZk52pDpWC9qA==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.3", + "@inquirer/type": "^1.4.0", + "@types/mute-stream": "^0.0.4", + "@types/node": "^20.14.9", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/password": { + "version": "2.1.14", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-2.1.14.tgz", + "integrity": "sha512-sPzOkXLhWJQ96K6nPZFnF8XB8tsDrcCRobd1d3EDz81F+4hp8BbdmsnsQcqZ7oYDIOVM/mWJyIUtJ35TrssJxQ==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.0.2", + "@inquirer/type": "^1.4.0", + "ansi-escapes": "^4.3.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/password/node_modules/@inquirer/core": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.0.2.tgz", + "integrity": "sha512-nguvH3TZar3ACwbytZrraRTzGqyxJfYJwv+ZwqZNatAosdWQMP1GV8zvmkNlBe2JeZSaw0WYBHZk52pDpWC9qA==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.3", + "@inquirer/type": "^1.4.0", + "@types/mute-stream": "^0.0.4", + "@types/node": "^20.14.9", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/prompts": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-5.0.7.tgz", + "integrity": "sha512-GFcigCxJTKCH3aECzMIu4FhgLJWnFvMXzpI4CCSoELWFtkOOU2P+goYA61+OKpGrB8fPE7q6n8zAXBSlZRrHjQ==", + "dev": true, + "dependencies": { + "@inquirer/checkbox": "^2.3.7", + "@inquirer/confirm": "^3.1.11", + "@inquirer/editor": "^2.1.11", + "@inquirer/expand": "^2.1.11", + "@inquirer/input": "^2.1.11", + "@inquirer/password": "^2.1.11", + "@inquirer/rawlist": "^2.1.11", + "@inquirer/select": "^2.3.7" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/rawlist": { + "version": "2.1.14", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-2.1.14.tgz", + "integrity": "sha512-pLpEzhKNQ/ugFAFfgCNaXljB+dcCwmXwR1jOxAbVeFIdB3l02E5gjI+h1rb136tq0T8JO6P5KFR1oTeld/wdrA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.0.2", + "@inquirer/type": "^1.4.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/rawlist/node_modules/@inquirer/core": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.0.2.tgz", + "integrity": "sha512-nguvH3TZar3ACwbytZrraRTzGqyxJfYJwv+ZwqZNatAosdWQMP1GV8zvmkNlBe2JeZSaw0WYBHZk52pDpWC9qA==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.3", + "@inquirer/type": "^1.4.0", + "@types/mute-stream": "^0.0.4", + "@types/node": "^20.14.9", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/select": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-2.3.10.tgz", + "integrity": "sha512-rr7iR0Zj1YFfgM8IUGimPD9Yukd+n/U63CnYT9kdum6DbRXtMxR45rrreP+EA9ixCnShr+W4xj7suRxC1+8t9g==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.0.2", + "@inquirer/figures": "^1.0.3", + "@inquirer/type": "^1.4.0", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/select/node_modules/@inquirer/core": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.0.2.tgz", + "integrity": "sha512-nguvH3TZar3ACwbytZrraRTzGqyxJfYJwv+ZwqZNatAosdWQMP1GV8zvmkNlBe2JeZSaw0WYBHZk52pDpWC9qA==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.3", + "@inquirer/type": "^1.4.0", + "@types/mute-stream": "^0.0.4", + "@types/node": "^20.14.9", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-spinners": "^2.9.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.4.0.tgz", + "integrity": "sha512-AjOqykVyjdJQvtfkNDGUyMYGF8xN50VUxftCQWsOyIo4DFRLr6VQhW0VItGI1JIyQGCGgIpKa7hMMwNhZb4OIw==", + "dev": true, + "dependencies": { + "mute-stream": "^1.0.0" + }, "engines": { "node": ">=18" } @@ -3014,22 +3208,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", @@ -3082,9 +3260,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { @@ -3136,9 +3314,9 @@ } }, "node_modules/@jsonjoy.com/util": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.1.3.tgz", - "integrity": "sha512-g//kkF4kOwUjemValCtOc/xiYzmwMRmWq3Bn+YnzOzuZLHq2PpMOxxIayN3cKbo7Ko2Np65t6D9H81IvXbXhqg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.2.0.tgz", + "integrity": "sha512-4B8B+3vFsY4eo33DMKyJPlQ3sBMpPFUZK2dr3O3rXrOGKKbYG44J0XSFkDo1VOQiri5HFEhIeVvItjR2xcazmg==", "dev": true, "engines": { "node": ">=10.0" @@ -3157,22 +3335,25 @@ "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", "dev": true }, - "node_modules/@ljharb/through": { - "version": "2.3.13", - "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.13.tgz", - "integrity": "sha512-/gKJun8NNiWGZJkGzI/Ragc53cOdcLNdzjLaIa+GEjguQs0ulsurx8WN0jijdK9yPqDvziX995sMRLyLt1uZMQ==", + "node_modules/@listr2/prompt-adapter-inquirer": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-2.0.13.tgz", + "integrity": "sha512-nAl6teTt7EWSjttNavAnv3uFR3w3vPP3OTYmHyPNHzKhAj2NoBDHmbS3MGpvvO8KXXPASnHjEGrrKrdKTMKPnQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.7" + "@inquirer/type": "^1.3.3" }, "engines": { - "node": ">= 0.4" + "node": ">=18.0.0" + }, + "peerDependencies": { + "@inquirer/prompts": ">= 3 < 6" } }, "node_modules/@lmdb/lmdb-darwin-arm64": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.0.8.tgz", - "integrity": "sha512-+lFwFvU+zQ9zVIFETNtmW++syh3Ps5JS8MPQ8zOYtQZoU+dTR8ivWHTaE2QVk1JG2payGDLUAvpndLAjGMdeeA==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.0.12.tgz", + "integrity": "sha512-vgTwzNUD3Hy4aqtGhX2+nV/usI0mwy3hDRuTjs8VcK0BLiMVEpNQXgzwlWEgPmA8AAPloUgyOs2nK5clJF5oIg==", "cpu": [ "arm64" ], @@ -3183,9 +3364,9 @@ ] }, "node_modules/@lmdb/lmdb-darwin-x64": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.0.8.tgz", - "integrity": "sha512-T98rfsgfdQMS5/mqdsPb6oHSJ+iBYNa+PQDLtXLh6rzTEBsYP9x2uXxIj6VS4qXVDWXVi8rv85NCOG+UBOsHXQ==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.0.12.tgz", + "integrity": "sha512-qOt0hAhj2ZLY6aEWu85rzt5zcyCAQITMhCMEPNlo1tuYekpVAdkQNiwXxEkCjBYvwTskvXuwXOOUpjuSc+aJnA==", "cpu": [ "x64" ], @@ -3196,9 +3377,9 @@ ] }, "node_modules/@lmdb/lmdb-linux-arm": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.0.8.tgz", - "integrity": "sha512-gVNCi3bYWatdPMeFpFjuZl6bzVL55FkeZU3sPeU+NsMRXC+Zl3qOx3M6cM4OMlJWbhHjYjf2b8q83K0mczaiWQ==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.0.12.tgz", + "integrity": "sha512-Ggd/UXpE+alMncbELCXA3OKpDj9bDBR3qVO7WRTxstloDglRAHfZmUJgTkeaNKjFO1JHqS7AKy0jba9XebZB1w==", "cpu": [ "arm" ], @@ -3209,9 +3390,9 @@ ] }, "node_modules/@lmdb/lmdb-linux-arm64": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.0.8.tgz", - "integrity": "sha512-uEBGCQIChsixpykL0pjCxfF64btv64vzsb1NoM5u0qvabKvKEvErhXGoqovyldDu9u1T/fswD8Kf6ih0vJEvDQ==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.0.12.tgz", + "integrity": "sha512-Qy4cFXFe9h1wAWMsojex8x1ifvw2kqiZv686YiRTdQEzAfc3vJASHFcD/QejHUCx7YHMYdnUoCS45rG2AiGDTQ==", "cpu": [ "arm64" ], @@ -3222,9 +3403,9 @@ ] }, "node_modules/@lmdb/lmdb-linux-x64": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.0.8.tgz", - "integrity": "sha512-6v0B4sa9ulNezmDZtVpLjNHmA0qZzUl3001YJ2RF0naxsuv/Jq/xEwNYpOzfcdizHfpCE0oBkWzk/r+Slr+0zw==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.0.12.tgz", + "integrity": "sha512-c+noT9IofktxktFllKHFmci8ka2SYGSLN17pj/KSl1hg7mmfAiGp4xxFxEwMLTb+SX95vP1DFiR++1I3WLVxvA==", "cpu": [ "x64" ], @@ -3235,9 +3416,9 @@ ] }, "node_modules/@lmdb/lmdb-win32-x64": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.0.8.tgz", - "integrity": "sha512-lDLGRIMqdwYD39vinwNqqZUxCdL2m2iIdn+0HyQgIHEiT0g5rIAlzaMKzoGWon5NQumfxXFk9y0DarttkR7C1w==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.0.12.tgz", + "integrity": "sha512-CO3MFV8gUx16NU/CyyuumAKblESwvoGVA2XhQKZ976OTOxaTbb8F8D3f0iiZ4MYqsN74jIrFuCmXpPnpjbhfOQ==", "cpu": [ "x64" ], @@ -4000,9 +4181,9 @@ } }, "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.2.tgz", - "integrity": "sha512-9bfjwDxIDWmmOKusUcqdS4Rw+SETlp9Dy39Xui9BEGEk19dDwH0jhipwFzEff/pFg95NKymc6TOTbRKcWeRqyQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", "cpu": [ "arm64" ], @@ -4013,9 +4194,9 @@ ] }, "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.2.tgz", - "integrity": "sha512-lwriRAHm1Yg4iDf23Oxm9n/t5Zpw1lVnxYU3HnJPTi2lJRkKTrps1KVgvL6m7WvmhYVt/FIsssWay+k45QHeuw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", "cpu": [ "x64" ], @@ -4026,9 +4207,9 @@ ] }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.2.tgz", - "integrity": "sha512-MOI9Dlfrpi2Cuc7i5dXdxPbFIgbDBGgKR5F2yWEa6FVEtSWncfVNKW5AKjImAQ6CZlBK9tympdsZJ2xThBiWWA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", "cpu": [ "arm" ], @@ -4039,9 +4220,9 @@ ] }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.2.tgz", - "integrity": "sha512-FU20Bo66/f7He9Fp9sP2zaJ1Q8L9uLPZQDub/WlUip78JlPeMbVL8546HbZfcW9LNciEXc8d+tThSJjSC+tmsg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", "cpu": [ "arm64" ], @@ -4052,9 +4233,9 @@ ] }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.2.tgz", - "integrity": "sha512-gsWNDCklNy7Ajk0vBBf9jEx04RUxuDQfBse918Ww+Qb9HCPoGzS+XJTLe96iN3BVK7grnLiYghP/M4L8VsaHeA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", "cpu": [ "x64" ], @@ -4065,9 +4246,9 @@ ] }, "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.2.tgz", - "integrity": "sha512-O+6Gs8UeDbyFpbSh2CPEz/UOrrdWPTBYNblZK5CxxLisYt4kGX3Sc+czffFonyjiGSq3jWLwJS/CCJc7tBr4sQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", "cpu": [ "x64" ], @@ -4078,9 +4259,9 @@ ] }, "node_modules/@ngtools/webpack": { - "version": "18.0.1", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.0.1.tgz", - "integrity": "sha512-uetWaviDUK3lgjKxN/FOxhEuZ5O3PVY8vWFAv1LkPSLFJbcKAQZlYbKnrn7uvQzyrkUc3W5+bYEGx2OcXMpb9g==", + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.1.0.tgz", + "integrity": "sha512-J4ATDGq0AubLbP3DOFRjp0pDBvSgzjtiu5l1hGq3xf6AzVAEmZFlp2Ac2EykuK2r8XDnCVoLrxICJOXZWWzP2g==", "dev": true, "engines": { "node": "^18.19.1 || ^20.11.1 || >=22.0.0", @@ -4089,7 +4270,7 @@ }, "peerDependencies": { "@angular/compiler-cli": "^18.0.0", - "typescript": ">=5.4 <5.5", + "typescript": ">=5.4 <5.6", "webpack": "^5.54.0" } }, @@ -4145,13 +4326,10 @@ } }, "node_modules/@npmcli/agent/node_modules/lru-cache": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", - "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true }, "node_modules/@npmcli/fs": { "version": "3.1.1", @@ -4166,12 +4344,13 @@ } }, "node_modules/@npmcli/git": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.7.tgz", - "integrity": "sha512-WaOVvto604d5IpdCRV2KjQu8PzkfE96d50CQGKgywXh2GxXmDeUO5EWcBC4V57uFyrNqx83+MewuJh3WTR3xPA==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.8.tgz", + "integrity": "sha512-liASfw5cqhjNW9UFd+ruwwdEf/lbOAQjLL2XY2dFW/bkJheXDYZgOyul/4gVvEV4BWkTXjYGmDqMw9uegdbJNQ==", "dev": true, "dependencies": { "@npmcli/promise-spawn": "^7.0.0", + "ini": "^4.1.3", "lru-cache": "^10.0.1", "npm-pick-manifest": "^9.0.0", "proc-log": "^4.0.0", @@ -4194,13 +4373,10 @@ } }, "node_modules/@npmcli/git/node_modules/lru-cache": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", - "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true }, "node_modules/@npmcli/git/node_modules/which": { "version": "4.0.0", @@ -4243,9 +4419,9 @@ } }, "node_modules/@npmcli/package-json": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.1.0.tgz", - "integrity": "sha512-1aL4TuVrLS9sf8quCLerU3H9J4vtCtgu8VauYozrmEyU57i/EdKleCnsQ7vpnABIH6c9mnTxcH5sFkO3BlV8wQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.2.0.tgz", + "integrity": "sha512-qe/kiqqkW0AGtvBjL8TJKZk/eBBSpnJkUWvHdQ9jM2lKHXRYYJuyNpJPlJw3c8QjC2ow6NZYiLExhUaeJelbxQ==", "dev": true, "dependencies": { "@npmcli/git": "^5.0.0", @@ -4270,31 +4446,29 @@ } }, "node_modules/@npmcli/package-json/node_modules/glob": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", - "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@npmcli/package-json/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -4343,9 +4517,9 @@ } }, "node_modules/@npmcli/redact": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-2.0.0.tgz", - "integrity": "sha512-SEjCPAVHWYUIQR+Yn03kJmrJjZDtJLYpj300m3HV9OTRZNpC5YpbMsM3eTkECyT4aWj8lDr9WeY6TWefpubtYQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-2.0.1.tgz", + "integrity": "sha512-YgsR5jCQZhVmTJvjduTOIHph0L73pK8xwMVaDY0PatySqVM9AZj93jpoXYSJqfHFxFkN9dmqTw6OiqExsS3LPw==", "dev": true, "engines": { "node": "^16.14.0 || >=18.0.0" @@ -4611,14 +4785,14 @@ ] }, "node_modules/@schematics/angular": { - "version": "18.0.1", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.0.1.tgz", - "integrity": "sha512-ho9QOUiS4wqKRzbKFWUGU8iecfcdrjnrjBXbzJEQ6GNIOz7iDniLMNXYRP7P+xanWQGLPDIOVR2lGaryPdTXDw==", + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.1.0.tgz", + "integrity": "sha512-k9Dy6JD7hqvCzDqnMjDm7J8H/P6m5mLuX2yEgQWKRAJ/YMINtBQAaKA1T9qXk97kEX6RNLpHMuDIsrIfK/H31Q==", "dev": true, "dependencies": { - "@angular-devkit/core": "18.0.1", - "@angular-devkit/schematics": "18.0.1", - "jsonc-parser": "3.2.1" + "@angular-devkit/core": "18.1.0", + "@angular-devkit/schematics": "18.1.0", + "jsonc-parser": "3.3.1" }, "engines": { "node": "^18.19.1 || ^20.11.1 || >=22.0.0", @@ -4700,6 +4874,18 @@ "node": "^16.14.0 || >=18.0.0" } }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@socket.io/component-emitter": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", @@ -4738,9 +4924,9 @@ } }, "node_modules/@tufjs/models/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -4844,9 +5030,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.1.tgz", - "integrity": "sha512-ej0phymbFLoCB26dbbq5PGScsf2JAJ4IJHjG10LalgUV36XKTmA4GdA+PVllKvRk0sEKt64X8975qFnkSi0hqA==", + "version": "4.19.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", + "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", "dev": true, "dependencies": { "@types/node": "*", @@ -4888,10 +5074,19 @@ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "dev": true }, + "node_modules/@types/mute-stream": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@types/mute-stream/-/mute-stream-0.0.4.tgz", + "integrity": "sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/node": { - "version": "20.12.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", - "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", + "version": "20.14.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", + "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -4963,10 +5158,16 @@ "@types/node": "*" } }, + "node_modules/@types/wrap-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz", + "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==", + "dev": true + }, "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "version": "8.5.11", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.11.tgz", + "integrity": "sha512-4+q7P5h3SpJxaBft0Dzpbr6lmMaqh0Jr2tbhJZ/luAwvD7ohSCniYkwz/pLxuT2h0EOa6QADgJj1Ko+TzRfZ+w==", "dev": true, "dependencies": { "@types/node": "*" @@ -5171,9 +5372,9 @@ } }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -5182,10 +5383,10 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", "dev": true, "peerDependencies": { "acorn": "^8" @@ -5244,9 +5445,9 @@ } }, "node_modules/ajv": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", - "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", + "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3", @@ -5371,13 +5572,10 @@ } }, "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "node_modules/array-flatten": { "version": "1.1.1", @@ -5439,22 +5637,6 @@ "webpack": ">=5" } }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/babel-plugin-polyfill-corejs2": { "version": "0.4.11", "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", @@ -5654,9 +5836,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", + "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", "dev": true, "funding": [ { @@ -5673,10 +5855,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", + "caniuse-lite": "^1.0.30001640", + "electron-to-chromium": "^1.4.820", "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -5740,9 +5922,9 @@ } }, "node_modules/cacache": { - "version": "18.0.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.3.tgz", - "integrity": "sha512-qXCd4rh6I07cnDqh8V48/94Tc/WSfj+o3Gn6NZ0aZovS255bUx8O13uKxRFd2eWG0xgsco7+YItQNPaa5E85hg==", + "version": "18.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", + "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", "dev": true, "dependencies": { "@npmcli/fs": "^3.1.0", @@ -5772,40 +5954,35 @@ } }, "node_modules/cacache/node_modules/glob": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", - "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/cacache/node_modules/lru-cache": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", - "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true }, "node_modules/cacache/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -5845,19 +6022,10 @@ "node": ">=6" } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/caniuse-lite": { - "version": "1.0.30001624", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001624.tgz", - "integrity": "sha512-0dWnQG87UevOCPYaOR49CBcLBwoZLpws+k6W37nLjWUhumP1Isusj0p2u+3KhjNloRWK9OKMgjBBzPujQHw4nA==", + "version": "1.0.30001642", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001642.tgz", + "integrity": "sha512-3XQ0DoRgLijXJErLSl+bLnJ+Et4KqV1PY6JJBGAFlsNsz31zeAIncyeZfLCabHK/jtSh+671RM9YMldxjUPZtA==", "dev": true, "funding": [ { @@ -5928,9 +6096,9 @@ } }, "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", "dev": true, "engines": { "node": ">=6.0" @@ -5946,15 +6114,18 @@ } }, "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", "dev": true, "dependencies": { - "restore-cursor": "^3.1.0" + "restore-cursor": "^4.0.0" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cli-spinners": { @@ -5969,6 +6140,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cli-width": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", @@ -6025,6 +6212,35 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/cliui/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -6258,20 +6474,20 @@ } }, "node_modules/copy-webpack-plugin": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", - "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz", + "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==", "dev": true, "dependencies": { - "fast-glob": "^3.2.11", + "fast-glob": "^3.3.2", "glob-parent": "^6.0.1", - "globby": "^13.1.1", + "globby": "^14.0.0", "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2" }, "engines": { - "node": ">= 14.15.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", @@ -6351,28 +6567,10 @@ } } }, - "node_modules/cosmiconfig/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/cosmiconfig/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/critters": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.22.tgz", - "integrity": "sha512-NU7DEcQZM2Dy8XTKFHxtdnIM/drE312j2T4PCVaSUcS0oBeyT/NImpRw/Ap0zOr/1SE7SgPK9tGPg1WK/sVakw==", + "version": "0.0.24", + "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.24.tgz", + "integrity": "sha512-Oyqew0FGM0wYUSNqR0L6AteO5MpMoUU0rhKRieXeiKs+PmRTxiJMyaunYB2KF6fQ3dzChXKCpbFOEJx3OQ1v/Q==", "dev": true, "dependencies": { "chalk": "^4.1.0", @@ -6484,9 +6682,9 @@ } }, "node_modules/css-loader": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.1.tgz", - "integrity": "sha512-OxIR5P2mjO1PSXk44bWuQ8XtMK4dpEqpIyERCx3ewOo3I8EmbcxMPUc5ScLtQfgXtOojoMv57So4V/C02HQLsw==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", + "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", "dev": true, "dependencies": { "icss-utils": "^5.1.0", @@ -6574,9 +6772,9 @@ } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -6660,12 +6858,15 @@ } }, "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "dev": true, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/depd": { @@ -6708,18 +6909,6 @@ "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", "dev": true }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/dns-packet": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", @@ -6812,15 +7001,15 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.783", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.783.tgz", - "integrity": "sha512-bT0jEz/Xz1fahQpbZ1D7LgmPYZ3iHVY39NcWWro1+hA2IvjiPeaXtfSqrQ+nXjApMvQRE2ASt1itSLRrebHMRQ==", + "version": "1.4.827", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.827.tgz", + "integrity": "sha512-VY+J0e4SFcNfQy19MEoMdaIcZLmDCprqvBtkii1WTCTQHpRvf5N8+3kTYCgL/PcntvwQvmMJWTuDPsq+IlhWKQ==", "dev": true }, "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", "dev": true }, "node_modules/emojis-list": { @@ -6865,9 +7054,9 @@ } }, "node_modules/engine.io": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz", - "integrity": "sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==", + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", + "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -6879,25 +7068,25 @@ "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.2.1", - "ws": "~8.11.0" + "ws": "~8.17.1" }, "engines": { "node": ">=10.2.0" } }, "node_modules/engine.io-parser": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", - "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", "dev": true, "engines": { "node": ">=10.0.0" } }, "node_modules/enhanced-resolve": { - "version": "5.16.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz", - "integrity": "sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==", + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", + "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -6908,10 +7097,16 @@ } }, "node_modules/ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", - "dev": true + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.1.tgz", + "integrity": "sha512-QHuXVeZx9d+tIQAz/XztU0ZwZf2Agg9CcXcgE1rurqvdBeDBrpSwjl8/6XUqMg7tw2Y7uAdKb2sRv+bSEFqQ5A==", + "dev": true, + "dependencies": { + "punycode": "^1.4.1" + }, + "engines": { + "node": ">= 0.4" + } }, "node_modules/entities": { "version": "4.5.0", @@ -6984,15 +7179,15 @@ } }, "node_modules/es-module-lexer": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.3.tgz", - "integrity": "sha512-i1gCgmR9dCl6Vil6UKPI/trA69s08g/syhiDK9TG0Nf1RJjjFI+AzoWW7sPufzkgYAn861skuCwJa0pIIHYxvg==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", "dev": true }, "node_modules/esbuild": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.3.tgz", - "integrity": "sha512-Kgq0/ZsAPzKrbOjCQcjoSmPoWhlcVnGAUo7jvaLHoxW1Drto0KGkR1xBNg2Cp43b9ImvxmPEJZ9xkfcnqPsfBw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, "bin": { @@ -7002,35 +7197,35 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.3", - "@esbuild/android-arm": "0.21.3", - "@esbuild/android-arm64": "0.21.3", - "@esbuild/android-x64": "0.21.3", - "@esbuild/darwin-arm64": "0.21.3", - "@esbuild/darwin-x64": "0.21.3", - "@esbuild/freebsd-arm64": "0.21.3", - "@esbuild/freebsd-x64": "0.21.3", - "@esbuild/linux-arm": "0.21.3", - "@esbuild/linux-arm64": "0.21.3", - "@esbuild/linux-ia32": "0.21.3", - "@esbuild/linux-loong64": "0.21.3", - "@esbuild/linux-mips64el": "0.21.3", - "@esbuild/linux-ppc64": "0.21.3", - "@esbuild/linux-riscv64": "0.21.3", - "@esbuild/linux-s390x": "0.21.3", - "@esbuild/linux-x64": "0.21.3", - "@esbuild/netbsd-x64": "0.21.3", - "@esbuild/openbsd-x64": "0.21.3", - "@esbuild/sunos-x64": "0.21.3", - "@esbuild/win32-arm64": "0.21.3", - "@esbuild/win32-ia32": "0.21.3", - "@esbuild/win32-x64": "0.21.3" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/esbuild-wasm": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.21.3.tgz", - "integrity": "sha512-DMOV+eeVra0yVq3XIojfczdEQsz+RiFnpEj7lqs8Gux9mlTpN7yIbw0a4KzLspn0Uhw6UVEH3nUAidSqc/rcQg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.21.5.tgz", + "integrity": "sha512-L/FlOPMMFtw+6qPAbuPvJXdrOYOp9yx/PEwSrIZW0qghY4vgV003evdYDwqQ/9ENMQI0B6RMod9xT4FHtto6OQ==", "dev": true, "bin": { "esbuild": "bin/esbuild" @@ -7076,19 +7271,6 @@ "node": ">=8.0.0" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -7175,6 +7357,12 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/execa/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, "node_modules/exponential-backoff": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", @@ -7417,16 +7605,19 @@ } }, "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", "dev": true, "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/flat": { @@ -7465,9 +7656,9 @@ } }, "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", "dev": true, "dependencies": { "cross-spawn": "^7.0.0", @@ -7480,18 +7671,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -7596,6 +7775,18 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-intrinsic": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", @@ -7615,15 +7806,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -7685,19 +7867,20 @@ } }, "node_modules/globby": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", "dev": true, "dependencies": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.3.0", + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", "ignore": "^5.2.4", - "merge2": "^1.4.1", - "slash": "^4.0.0" + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -7797,13 +7980,10 @@ } }, "node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", - "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true }, "node_modules/hpack.js": { "version": "2.1.6", @@ -7976,9 +8156,9 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dev": true, "dependencies": { "agent-base": "^7.0.2", @@ -8081,9 +8261,9 @@ } }, "node_modules/ignore-walk/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -8130,15 +8310,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -8175,52 +8346,14 @@ "dev": true }, "node_modules/ini": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.2.tgz", - "integrity": "sha512-AMB1mvwR1pyBFY/nSevUX6y8nJWS63/SzUKD3JyQn97s4xgIdgQPT75IRouIiBAN4yLQBUShNYVW0+UG25daCw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", "dev": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/inquirer": { - "version": "9.2.22", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.22.tgz", - "integrity": "sha512-SqLLa/Oe5rZUagTR9z+Zd6izyatHglbmbvVofo1KzuVB54YHleWzeHNLoR7FOICGOeQSqeLh1cordb3MzhGcEw==", - "dev": true, - "dependencies": { - "@inquirer/figures": "^1.0.2", - "@ljharb/through": "^2.3.13", - "ansi-escapes": "^4.3.2", - "chalk": "^5.3.0", - "cli-cursor": "^3.1.0", - "cli-width": "^4.1.0", - "external-editor": "^3.1.0", - "lodash": "^4.17.21", - "mute-stream": "1.0.0", - "ora": "^5.4.1", - "run-async": "^3.0.0", - "rxjs": "^7.8.1", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^6.2.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/inquirer/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/ip-address": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", @@ -8234,12 +8367,6 @@ "node": ">= 12" } }, - "node_modules/ip-address/node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true - }, "node_modules/ipaddr.js": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", @@ -8268,27 +8395,30 @@ } }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", + "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", "dev": true, "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", "dev": true, "bin": { "is-docker": "cli.js" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8304,12 +8434,15 @@ } }, "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "dev": true, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-glob": { @@ -8342,21 +8475,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-inside-container/node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", @@ -8448,15 +8566,18 @@ "dev": true }, "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", "dev": true, "dependencies": { - "is-docker": "^2.0.0" + "is-inside-container": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/isarray": { @@ -8502,28 +8623,19 @@ } }, "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz", + "integrity": "sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==", "dev": true, "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" + "semver": "^7.5.4" }, "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" + "node": ">=10" } }, "node_modules/istanbul-lib-report": { @@ -8598,16 +8710,13 @@ } }, "node_modules/jackspeak": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.1.2.tgz", - "integrity": "sha512-kWmLKn2tRtfYMF/BakihVVRzBKOxz4gJMiL2Rj91WnAB5TPZumSH99R/Yf1qE1u4uRimvCSJfm6hnxohXeEXjQ==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": ">=14" - }, "funding": { "url": "https://github.com/sponsors/isaacs" }, @@ -8660,9 +8769,9 @@ } }, "node_modules/jiti": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", - "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", "dev": true, "bin": { "jiti": "bin/jiti.js" @@ -8675,13 +8784,12 @@ "dev": true }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" @@ -8733,9 +8841,9 @@ } }, "node_modules/jsonc-parser": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", - "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", "dev": true }, "node_modules/jsonfile": { @@ -8828,6 +8936,31 @@ "node": ">=10.0.0" } }, + "node_modules/karma-coverage/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma-coverage/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/karma-jasmine": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz", @@ -8913,6 +9046,21 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/karma/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/karma/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/karma/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -8922,6 +9070,20 @@ "node": ">=0.10.0" } }, + "node_modules/karma/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/karma/node_modules/tmp": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", @@ -8985,9 +9147,9 @@ } }, "node_modules/launch-editor": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", - "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.0.tgz", + "integrity": "sha512-vJranOAJrI/llyWGRQqiDM+adrw+k83fvmmx3+nV47g3+36xM15jE+zyZ6Ffel02+xSvuM0b2GDRosXZkbb6wA==", "dev": true, "dependencies": { "picocolors": "^1.0.0", @@ -9116,16 +9278,95 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/listr2": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.3.tgz", + "integrity": "sha512-Lllokma2mtoniUOS94CcOErHWAug5iu7HOmDrvWgpw8jyQH2fomgB+7lZS4HWZxytUuQwkGOwe49FvwVaA85Xw==", + "dev": true, + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.0.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "node_modules/listr2/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/lmdb": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.0.8.tgz", - "integrity": "sha512-9rp8JT4jPhCRJUL7vRARa2N06OLSYzLwQsEkhC6Qu5XbcLyM/XBLMzDlgS/K7l7c5CdURLdDk9uE+hPFIogHTQ==", + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.0.12.tgz", + "integrity": "sha512-JnoEulTgveoC64vlYJ9sufGLuNkk6TcxSYpKxSC9aM42I61jIv3pQH0fgb6qW7HV0+FNqA3g1WCQQYfhfawGoQ==", "dev": true, "hasInstallScript": true, "dependencies": { - "msgpackr": "^1.9.9", + "msgpackr": "^1.10.2", "node-addon-api": "^6.1.0", - "node-gyp-build-optional-packages": "5.1.1", + "node-gyp-build-optional-packages": "5.2.2", "ordered-binary": "^1.4.1", "weak-lru-cache": "^1.2.2" }, @@ -9133,12 +9374,12 @@ "download-lmdb-prebuilds": "bin/download-prebuilds.js" }, "optionalDependencies": { - "@lmdb/lmdb-darwin-arm64": "3.0.8", - "@lmdb/lmdb-darwin-x64": "3.0.8", - "@lmdb/lmdb-linux-arm": "3.0.8", - "@lmdb/lmdb-linux-arm64": "3.0.8", - "@lmdb/lmdb-linux-x64": "3.0.8", - "@lmdb/lmdb-win32-x64": "3.0.8" + "@lmdb/lmdb-darwin-arm64": "3.0.12", + "@lmdb/lmdb-darwin-x64": "3.0.12", + "@lmdb/lmdb-linux-arm": "3.0.12", + "@lmdb/lmdb-linux-arm64": "3.0.12", + "@lmdb/lmdb-linux-x64": "3.0.12", + "@lmdb/lmdb-win32-x64": "3.0.12" } }, "node_modules/loader-runner": { @@ -9151,24 +9392,27 @@ } }, "node_modules/loader-utils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", - "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", "dev": true, "engines": { "node": ">= 12.13.0" } }, "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", "dev": true, "dependencies": { - "p-locate": "^4.1.0" + "p-locate": "^6.0.0" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lodash": { @@ -9269,6 +9513,124 @@ "node": ">=8" } }, + "node_modules/log-update": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", + "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", + "dev": true, + "dependencies": { + "ansi-escapes": "^6.2.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^7.0.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", + "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/log4js": { "version": "6.9.1", "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", @@ -9351,14 +9713,14 @@ } }, "node_modules/memfs": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.9.2.tgz", - "integrity": "sha512-f16coDZlTG1jskq3mxarwB+fGRrd0uXWt+o1WIhRfOwbXQZqUDsTVxQBFK9JjRQHblg8eAG2JSbprDXKjc7ijQ==", + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.9.3.tgz", + "integrity": "sha512-bsYSSnirtYTWi1+OPMFb0M048evMKyUYe0EbtuGQgq6BVQM1g1W8/KIUJCCvjgI/El0j6Q4WsmMiBwLUBSw8LA==", "dev": true, "dependencies": { "@jsonjoy.com/json-pack": "^1.0.3", "@jsonjoy.com/util": "^1.1.2", - "sonic-forest": "^1.0.0", + "tree-dump": "^1.0.1", "tslib": "^2.0.0" }, "engines": { @@ -9581,34 +9943,6 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "node_modules/minipass-json-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz", - "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==", - "dev": true, - "dependencies": { - "jsonparse": "^1.3.1", - "minipass": "^3.0.0" - } - }, - "node_modules/minipass-json-stream/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-json-stream/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/minipass-pipeline": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", @@ -9728,46 +10062,34 @@ "dev": true }, "node_modules/msgpackr": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.10.2.tgz", - "integrity": "sha512-L60rsPynBvNE+8BWipKKZ9jHcSGbtyJYIwjRq0VrIvQ08cRjntGXJYW/tmciZ2IHWIY8WEW32Qa2xbh5+SKBZA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.0.tgz", + "integrity": "sha512-I8qXuuALqJe5laEBYoFykChhSXLikZmUhccjGsPuSJ/7uPip2TJ7lwdIQwWSAi0jGZDXv4WOP8Qg65QZRuXxXw==", "dev": true, "optionalDependencies": { "msgpackr-extract": "^3.0.2" } }, "node_modules/msgpackr-extract": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.2.tgz", - "integrity": "sha512-SdzXp4kD/Qf8agZ9+iTu6eql0m3kWm1A2y1hkpTeVNENutaB0BwHlSvAIaMxwntmRUAUjon2V4L8Z/njd0Ct8A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", "dev": true, "hasInstallScript": true, "optional": true, "dependencies": { - "node-gyp-build-optional-packages": "5.0.7" + "node-gyp-build-optional-packages": "5.2.2" }, "bin": { "download-msgpackr-prebuilds": "bin/download-prebuilds.js" }, "optionalDependencies": { - "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.2", - "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.2", - "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.2", - "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.2", - "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.2", - "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.2" - } - }, - "node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.7.tgz", - "integrity": "sha512-YlCCc6Wffkx0kHkmam79GKvDQ6x+QZkMjFGrIMxgFNILFvGSbCp2fCBC55pGTT9gVaz8Na5CLmxt/urtzRv36w==", - "dev": true, - "optional": true, - "bin": { - "node-gyp-build-optional-packages": "bin.js", - "node-gyp-build-optional-packages-optional": "optional.js", - "node-gyp-build-optional-packages-test": "build-test.js" + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" } }, "node_modules/multicast-dns": { @@ -9906,9 +10228,9 @@ } }, "node_modules/node-gyp": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.1.0.tgz", - "integrity": "sha512-B4J5M1cABxPc5PwfjhbV5hoy2DP9p8lFXASnEN6hugXOa61416tnTZ29x9sSwAd0o99XNIcpvDDy1swAExsVKA==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.2.0.tgz", + "integrity": "sha512-sp3FonBAaFe4aYTcFdZUn2NYkbP7xroPGYvQmP4Nl5PxamznItBnNCgjrVTKrEfQynInMsJvZrdmqUnysCJ8rw==", "dev": true, "dependencies": { "env-paths": "^2.2.0", @@ -9917,9 +10239,9 @@ "graceful-fs": "^4.2.6", "make-fetch-happen": "^13.0.0", "nopt": "^7.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.1.0", "semver": "^7.3.5", - "tar": "^6.1.2", + "tar": "^6.2.1", "which": "^4.0.0" }, "bin": { @@ -9942,9 +10264,9 @@ } }, "node_modules/node-gyp-build-optional-packages": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz", - "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", "dev": true, "dependencies": { "detect-libc": "^2.0.1" @@ -9965,23 +10287,21 @@ } }, "node_modules/node-gyp/node_modules/glob": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", - "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -9996,9 +10316,9 @@ } }, "node_modules/node-gyp/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -10010,15 +10330,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/node-gyp/node_modules/proc-log": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", - "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/node-gyp/node_modules/which": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", @@ -10056,13 +10367,12 @@ } }, "node_modules/normalize-package-data": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.1.tgz", - "integrity": "sha512-6rvCfeRW+OEZagAB4lMLSNuTNYZWLVtKccK79VSTf//yTY5VOCgcpH80O+bZK8Neps7pUnd5G+QlMg1yV/2iZQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", "dev": true, "dependencies": { "hosted-git-info": "^7.0.0", - "is-core-module": "^2.8.1", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4" }, @@ -10164,16 +10474,16 @@ } }, "node_modules/npm-registry-fetch": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-17.0.1.tgz", - "integrity": "sha512-fLu9MTdZTlJAHUek/VLklE6EpIiP3VZpTiuN7OOMCt2Sd67NCpSEetMaxHHEZiZxllp8ZLsUpvbEszqTFEc+wA==", + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-17.1.0.tgz", + "integrity": "sha512-5+bKQRH0J1xG1uZ1zMNvxW0VEyoNWgJpY9UDuluPFLKDfJ9u2JmmjmTJV1srBGQOROfdBMiVvnH2Zvpbm+xkVA==", "dev": true, "dependencies": { "@npmcli/redact": "^2.0.0", + "jsonparse": "^1.3.1", "make-fetch-happen": "^13.0.0", "minipass": "^7.0.2", "minipass-fetch": "^3.0.0", - "minipass-json-stream": "^1.0.1", "minizlib": "^2.1.2", "npm-package-arg": "^11.0.0", "proc-log": "^4.0.0" @@ -10216,10 +10526,13 @@ } }, "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", "dev": true, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -10276,17 +10589,18 @@ } }, "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", "dev": true, "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" }, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -10346,6 +10660,18 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/ora/node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ora/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -10373,6 +10699,25 @@ "node": ">=8" } }, + "node_modules/ora/node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, "node_modules/ora/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -10401,30 +10746,33 @@ } }, "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", "dev": true, "dependencies": { - "p-try": "^2.0.0" + "yocto-queue": "^1.0.0" }, "engines": { - "node": ">=6" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", "dev": true, "dependencies": { - "p-limit": "^2.2.0" + "p-limit": "^4.0.0" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-map": { @@ -10468,14 +10816,11 @@ "node": ">= 4" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true }, "node_modules/pacote": { "version": "18.0.6", @@ -10601,12 +10946,12 @@ } }, "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", "dev": true, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, "node_modules/path-is-absolute": { @@ -10650,13 +10995,10 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", - "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true }, "node_modules/path-to-regexp": { "version": "0.1.7", @@ -10665,12 +11007,15 @@ "dev": true }, "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", "dev": true, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/picocolors": { @@ -10702,9 +11047,9 @@ } }, "node_modules/piscina": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.5.0.tgz", - "integrity": "sha512-iBaLWI56PFP81cfBSomWTmhOo9W2/yhIOL+Tk8O1vBCpK39cM0tGxB+wgYjG31qq4ohGvysfXSdnj8h7g4rZxA==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.6.1.tgz", + "integrity": "sha512-z30AwWGtQE+Apr+2WBZensP2lIvwoaMcOPkQlIEmSGMJNUvaYACylPYrQM6wSdUNJlnDVMSpLv7xTMJqlVshOA==", "dev": true, "optionalDependencies": { "nice-napi": "^1.0.2" @@ -10725,76 +11070,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "dev": true, - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "dev": true, - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "dev": true, - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, "node_modules/postcss": { "version": "8.4.38", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", @@ -10920,9 +11195,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", - "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", + "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -11002,13 +11277,10 @@ "optional": true }, "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true }, "node_modules/qjobs": { "version": "1.2.0", @@ -11250,12 +11522,12 @@ } }, "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, "engines": { - "node": ">=8" + "node": ">=4" } }, "node_modules/resolve-url-loader": { @@ -11298,18 +11570,27 @@ } }, "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", "dev": true, "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, "node_modules/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", @@ -11330,9 +11611,9 @@ } }, "node_modules/rfdc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", - "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "dev": true }, "node_modules/rimraf": { @@ -11398,15 +11679,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/run-async": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", - "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -11470,9 +11742,9 @@ "integrity": "sha512-LRneZZRXNgjzwG4bDQdOTSbze3fHm1EAKN/8bePxnlEZiBmkYEDggaHbuvHI9/hoqHbGfsEA7tWS9GhYHZBBsw==" }, "node_modules/sass": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.2.tgz", - "integrity": "sha512-eb4GZt1C3avsX3heBNlrc7I09nyT00IUuo4eFhAbeXWU2fvA7oXI53SxODVAA+zgZCk9aunAZgO+losjR3fAwA==", + "version": "1.77.6", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.6.tgz", + "integrity": "sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -11843,10 +12115,16 @@ } }, "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, "node_modules/sigstore": { "version": "2.3.1", @@ -11866,15 +12144,43 @@ } }, "node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/smart-buffer": { @@ -11906,13 +12212,13 @@ } }, "node_modules/socket.io-adapter": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.4.tgz", - "integrity": "sha512-wDNHGXGewWAjQPt3pyeYBtpWSq9cLE5UW1ZUPL/2eGK9jtse/FpXib7epSTsz0Q0m+6sg6Y4KtcFTlah1bdOVg==", + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", + "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", "dev": true, "dependencies": { "debug": "~4.3.4", - "ws": "~8.11.0" + "ws": "~8.17.1" } }, "node_modules/socket.io-parser": { @@ -11954,38 +12260,19 @@ } }, "node_modules/socks-proxy-agent": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.3.tgz", - "integrity": "sha512-VNegTZKhuGq5vSD6XNKlbqWhyt/40CgoEw8XxD6dhnm8Jq9IEa3nIa4HwnM8XOqU0CdB0BwWVXusqiFXfHB3+A==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", + "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", "dev": true, "dependencies": { "agent-base": "^7.1.1", "debug": "^4.3.4", - "socks": "^2.7.1" + "socks": "^2.8.3" }, "engines": { "node": ">= 14" } }, - "node_modules/sonic-forest": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sonic-forest/-/sonic-forest-1.0.3.tgz", - "integrity": "sha512-dtwajos6IWMEWXdEbW1IkEkyL2gztCAgDplRIX+OT5aRKnEd5e7r7YCxRgXZdhRP1FBdOBf8axeTPhzDv8T4wQ==", - "dev": true, - "dependencies": { - "tree-dump": "^1.0.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, "node_modules/source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", @@ -12118,9 +12405,9 @@ } }, "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", "dev": true }, "node_modules/ssri": { @@ -12168,17 +12455,20 @@ } }, "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/string-width-cjs": { @@ -12196,6 +12486,48 @@ "node": ">=8" } }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -12341,9 +12673,9 @@ "dev": true }, "node_modules/terser": { - "version": "5.31.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz", - "integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==", + "version": "5.29.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.29.2.tgz", + "integrity": "sha512-ZiGkhUBIM+7LwkNjXYJq8svgkd+QK3UUr0wJqY4MieaezBSAIPgbSPZyIx0idM6XWK5CMzSWa8MJIzmRcB8Caw==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -12441,20 +12773,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/thingies": { "version": "1.21.0", "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", @@ -12516,9 +12834,9 @@ } }, "node_modules/tree-dump": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.1.tgz", - "integrity": "sha512-WCkcRBVPSlHHq1dc/px9iOfqklvzCbdRwvlNfxGZsrHqf6aZttfPrd7DJTt6oR10dwUfpFFQeVTkPbBIZxX/YA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", + "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", "dev": true, "engines": { "node": ">=10.0" @@ -12541,9 +12859,9 @@ } }, "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/tuf-js": { "version": "2.2.1", @@ -12627,9 +12945,9 @@ } }, "node_modules/undici": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.18.0.tgz", - "integrity": "sha512-nT8jjv/fE9Et1ilR6QoW8ingRTY2Pp4l2RUrdzV5Yz35RJDrtPc1DXvuNqcpsJSGIRHFdt3YKKktTzJA6r0fTA==", + "version": "6.19.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.2.tgz", + "integrity": "sha512-JfjKqIauur3Q6biAtHJ564e3bWa8VvT+7cSiOJHFbX4Erv6CLGDpg8z+Fmg/1OI/47RA+GI2QZaF48SSaLvyBA==", "dev": true, "engines": { "node": ">=18.17" @@ -12681,6 +12999,18 @@ "node": ">=4" } }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/unique-filename": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", @@ -12724,9 +13054,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", - "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "dev": true, "funding": [ { @@ -12762,6 +13092,15 @@ "punycode": "^2.1.0" } }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -12815,12 +13154,12 @@ } }, "node_modules/vite": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", - "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", + "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", "dev": true, "dependencies": { - "esbuild": "^0.20.1", + "esbuild": "^0.21.3", "postcss": "^8.4.38", "rollup": "^4.13.0" }, @@ -12869,412 +13208,6 @@ } } }, - "node_modules/vite/node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" - } - }, "node_modules/void-elements": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", @@ -13322,9 +13255,9 @@ "dev": true }, "node_modules/webpack": { - "version": "5.91.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", - "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", + "version": "5.92.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz", + "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", @@ -13333,10 +13266,10 @@ "@webassemblyjs/wasm-edit": "^1.12.1", "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", + "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.16.0", + "enhanced-resolve": "^5.17.0", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -13465,36 +13398,22 @@ "balanced-match": "^1.0.0" } }, - "node_modules/webpack-dev-server/node_modules/define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/webpack-dev-server/node_modules/glob": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", - "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -13523,25 +13442,10 @@ } } }, - "node_modules/webpack-dev-server/node_modules/is-wsl": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", - "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", - "dev": true, - "dependencies": { - "is-inside-container": "^1.0.0" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/webpack-dev-server/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -13553,28 +13457,10 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/webpack-dev-server/node_modules/open": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", - "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", - "dev": true, - "dependencies": { - "default-browser": "^5.2.1", - "define-lazy-prop": "^3.0.0", - "is-inside-container": "^1.0.0", - "is-wsl": "^3.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/webpack-dev-server/node_modules/rimraf": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.7.tgz", - "integrity": "sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.9.tgz", + "integrity": "sha512-3i7b8OcswU6CpU8Ej89quJD4O98id7TtVM5U4Mybh84zQXdrFmDLouWBEEaD/QfO3gDDfH+AGFCGsR7kngzQnA==", "dev": true, "dependencies": { "glob": "^10.3.7" @@ -13583,33 +13469,12 @@ "rimraf": "dist/esm/bin.mjs" }, "engines": { - "node": ">=14.18" + "node": "14 >=14.20 || 16 >=16.20 || >=18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.17.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz", - "integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/webpack-merge": { "version": "5.10.0", "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", @@ -13815,6 +13680,35 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -13848,6 +13742,35 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -13855,16 +13778,16 @@ "dev": true }, "node_modules/ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -13917,10 +13840,39 @@ "node": ">=12" } }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", "dev": true, "engines": { "node": ">=12.20" @@ -13929,10 +13881,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zone.js": { - "version": "0.14.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.14.6.tgz", - "integrity": "sha512-vyRNFqofdaHVdWAy7v3Bzmn84a1JHWSjpuTZROT/uYn8I3p2cmo7Ro9twFmYRQDPhiYOV7QLk0hhY4JJQVqS6Q==" + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.14.7.tgz", + "integrity": "sha512-0w6DGkX2BPuiK/NLf+4A8FLE43QwBfuqz2dVgi/40Rj1WmqUskCqj329O/pwrqFJLG5X8wkeG2RhIAro441xtg==" } } } diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css index ffb644b..a03bf1c 100644 --- a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.css @@ -12,6 +12,48 @@ mat-card { width: 150px; + position: relative; +} + +.client-image-container { + position: relative; +} + +.client-image { + width: 100%; + height: auto; +} + +.proyector-image { + width: auto; + height: 100px; /* Ajusta la altura según sea necesario */ +} + +.client-info { + position: absolute; + top: 20px; + left: 5px; + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + background-color: rgba(0, 0, 0, 0); /* Fondo semitransparente para el texto */ + color: black; /* Color del texto */ + text-align: center; + padding: 10px; + box-sizing: border-box; +} + +.client-name { + font-size: medium; + font-weight: bold; +} + +.client-details { + display: flex; + flex-direction: column; + gap: 5px; + font-size: small; } mat-chip { @@ -19,13 +61,6 @@ mat-chip { font-size: small; } - -mat-card-title { - display: flex; - justify-content: space-between; - margin: 10px; - font-size: medium; -} .client-row { display: flex; justify-content: center; @@ -76,3 +111,22 @@ mat-card-title { .form-field { width: 100%; } + +.classroom-board { + width: 250px; + height: 120px; + background-color: black; + color: white; + display: flex; + align-items: center; + justify-content: center; + text-align: center; + margin-right: 20px; /* Espacio entre la pizarra y el proyector */ +} + +.misc-clients { + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 25px; +} diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html index 7fd84b6..617043b 100644 --- a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.html @@ -1,19 +1,23 @@
Clientes dentro de: {{ group.organizationalUnitName }} +
+
Pizarra digital
+ Proyector +
- - {{ client.name }} - - - - {{ client.ip }} - {{ client.mac }} - - +
+ Client +
+
{{ client.name }}
+
+ {{ client.ip }} +
+
+
diff --git a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts index 1a6e498..4689922 100644 --- a/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts +++ b/ogWebconsole/src/app/components/groups/classroom-view/classroom-view.component.ts @@ -1,11 +1,5 @@ -// src/app/classroom-view/classroom-view.component.ts - import { Component, Input, OnInit } from '@angular/core'; -import { - ChangePasswordModalComponent -} from "../../pages/admin/users/users/change-password-modal/change-password-modal.component"; import {MatDialog} from "@angular/material/dialog"; -import {CreateClientComponent} from "../clients/create-client/create-client.component"; import {ClientViewComponent} from "../client-view/client-view.component"; interface GroupedClients { @@ -43,7 +37,6 @@ export class ClassroomViewComponent implements OnInit { return acc; }, {}); - console.log(grouped) this.groupedClients = Object.keys(grouped).map(ouName => ({ organizationalUnitName: ouName, clientRows: this.chunkArray(grouped[ouName], this.pcInTable) diff --git a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.css b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.css index 21401e2..687587d 100644 --- a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.css +++ b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.css @@ -53,3 +53,8 @@ mat-option .unit-path { align-items: center; justify-content: center; } + +.create-client-container { + position: relative; + height: 90vh; +} diff --git a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.html b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.html index 5281297..0458898 100644 --- a/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.html +++ b/ogWebconsole/src/app/components/groups/clients/create-client/create-client.component.html @@ -1,3 +1,4 @@ +

Añadir Cliente

@@ -65,3 +66,4 @@
+
diff --git a/ogWebconsole/src/assets/images/board.png b/ogWebconsole/src/assets/images/board.png new file mode 100644 index 0000000000000000000000000000000000000000..3d53237575a5fc39416ae83b57e0a6011fa18e8f GIT binary patch literal 32063 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

Y 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

A0gOVSf2%hMSjz-ePNpq!UbTp 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 C0EhPg literal 0 HcmV?d00001 diff --git a/ogWebconsole/src/assets/images/proyector.png b/ogWebconsole/src/assets/images/proyector.png new file mode 100644 index 0000000000000000000000000000000000000000..52bb399861dbcc05eb5594dcae41a25d7215701b GIT binary patch literal 6076 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 q7efof(Vg