wm-menu 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { __awaiter, __decorate, __generator } from "tslib";
1
+ import { __awaiter, __decorate, __generator, __read, __spread } from "tslib";
2
2
  import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
3
3
  import { ReconocimientoVozService } from './reconocimiento-voz.service';
4
4
  import { AsistenteDatosApiService } from './asistente-datos-api.service';
@@ -25,20 +25,28 @@ var AsistenteDatosComponent = /** @class */ (function () {
25
25
  this.proveedorSeleccionado = 'Gemini';
26
26
  // Dictado por voz (Web Speech API) — sin soporte en Firefox, inconsistente en Safari.
27
27
  this.escuchando = false;
28
+ // Las preguntas sugeridas se muestran con el chat vacío. Tras la primera pregunta (cuando ya
29
+ // hay mensajes) quedan plegadas en el botón "Sugerencias" que controla este flag, para que el
30
+ // área de conversación gane ese espacio; el usuario puede volver a abrirlas. Es solo UI, igual
31
+ // con Gemini y con Groq.
32
+ this.sugerenciasAbiertas = false;
28
33
  // Tabla abierta en el modal "ampliar" (null = modal cerrado). El panel del chat es angosto y
29
34
  // recorta las columnas; el modal muestra la misma tabla a todo el ancho de la pantalla.
30
35
  this.tablaAmpliada = null;
31
36
  this.descripcionAmpliada = '';
32
37
  // Aviso efímero "Tabla copiada" tras copiar al portapapeles.
33
38
  this.copiadoAviso = false;
34
- // Preguntas ya verificadas como respondibles hoy (whitelist + contrato de la IA — ver
35
- // ChatConsultaWhitelistServicio/ChatConsultaPromptServicio en el backend), mostradas como chips
36
- // de sugerencia en el estado vacío del chat.
37
- this.chipsSugeridos = [
39
+ // Sugerencias FIJAS: preguntas ya verificadas como respondibles (whitelist + contrato de la IA —
40
+ // ver ChatConsultaWhitelistServicio/ChatConsultaPromptServicio en el backend). Son el estado
41
+ // inicial (chat vacío) y el fallback cuando el backend no devuelve sugerencias contextuales.
42
+ this.chipsFijos = [
38
43
  '¿Cuántos formularios se diligenciaron hoy?',
39
44
  '¿Cuántos formularios se diligenciaron esta semana?',
40
45
  'Muéstrame los últimos 10 formularios diligenciados',
41
46
  ];
47
+ // Sugerencias que se muestran ahora: arrancan en las fijas y, tras cada respuesta, se reemplazan
48
+ // por las contextuales que devuelve el backend (Sugerencias); si no vienen, vuelven a las fijas.
49
+ this.chipsSugeridos = __spread(this.chipsFijos);
42
50
  }
43
51
  Object.defineProperty(AsistenteDatosComponent.prototype, "urlConsultar", {
44
52
  // URL del POST de consulta. Se refleja en el api service (propiedad `url`), que es donde se usa.
@@ -123,6 +131,7 @@ var AsistenteDatosComponent = /** @class */ (function () {
123
131
  resultado: (_a = respuesta.Resultado, (_a !== null && _a !== void 0 ? _a : [])),
124
132
  proveedor: respuesta.Proveedor,
125
133
  });
134
+ _this.actualizarSugerencias(respuesta.Sugerencias);
126
135
  _this.scrollAlFinal();
127
136
  },
128
137
  error: function (error) {
@@ -137,6 +146,14 @@ var AsistenteDatosComponent = /** @class */ (function () {
137
146
  },
138
147
  });
139
148
  };
149
+ // Tras cada respuesta, el backend puede devolver sugerencias de seguimiento acotadas al rol. Si
150
+ // llegan al menos 2, reemplazan a las que se muestran; si no, se vuelve a las fijas. El chat vacío
151
+ // conserva las fijas: este método solo se llama al recibir una respuesta.
152
+ AsistenteDatosComponent.prototype.actualizarSugerencias = function (sugerencias) {
153
+ this.chipsSugeridos = sugerencias && sugerencias.length >= 2
154
+ ? sugerencias
155
+ : __spread(this.chipsFijos);
156
+ };
140
157
  // El nuevo mensaje recién se refleja en el DOM después del siguiente ciclo de detección de
141
158
  // cambios — por eso el scrollTop se ajusta en un setTimeout(0), no inmediatamente después del
142
159
  // push, para que scrollHeight ya incluya el mensaje agregado.
@@ -241,11 +258,11 @@ var AsistenteDatosComponent = /** @class */ (function () {
241
258
  AsistenteDatosComponent = __decorate([
242
259
  Component({
243
260
  selector: 'wm-asistente-datos',
244
- template: "<!-- Panel (abierto) -->\r\n<div class=\"chat-ia-panel\" *ngIf=\"abierto\">\r\n <div class=\"chat-ia-header\">\r\n <div class=\"chat-ia-header-info\">\r\n <div class=\"chat-ia-header-icono\">\r\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#fff\" stroke-width=\"1.8\">\r\n <path d=\"M4 5h16v10H9l-4 4V15H4z\"></path>\r\n </svg>\r\n </div>\r\n <div>\r\n <div class=\"chat-ia-titulo\">Preg\u00FAntale a tus Datos</div>\r\n <div class=\"chat-ia-subtitulo\">Consulta tus reportes en lenguaje natural</div>\r\n </div>\r\n </div>\r\n <div class=\"chat-ia-cerrar\" (click)=\"cerrar()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" stroke=\"#fff\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\">\r\n <path d=\"M6 6l12 12M18 6L6 18\"></path>\r\n </svg>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chat-ia-mensajes\" #mensajesContainer>\r\n <div class=\"chat-ia-bienvenida-texto\">Hola, soy tu asistente de datos de Snap Forms. Preg\u00FAntame lo que quieras saber sobre tu operaci\u00F3n.</div>\r\n\r\n <div class=\"chat-ia-mensaje\" *ngFor=\"let mensaje of mensajes\" [class.chat-ia-mensaje-usuario]=\"mensaje.deUsuario\">\r\n <div class=\"chat-ia-burbuja\" [class.chat-ia-burbuja-error]=\"mensaje.esError\">\r\n <span *ngIf=\"mensaje.texto\">{{ mensaje.texto }}</span>\r\n\r\n <ng-container *ngIf=\"mensaje.resultado\">\r\n <div class=\"chat-ia-descripcion\" *ngIf=\"mensaje.descripcion\">{{ mensaje.descripcion }}</div>\r\n\r\n <div class=\"chat-ia-sin-resultados\" *ngIf=\"mensaje.resultado.length === 0\">La consulta no encontr\u00F3 resultados.</div>\r\n\r\n <div class=\"chat-ia-stat\" *ngIf=\"esConteo(mensaje.resultado)\">\r\n <div class=\"chat-ia-stat-valor\">{{ mensaje.resultado[0].Resultado | number }}</div>\r\n </div>\r\n\r\n <div class=\"chat-ia-lista-simple\" *ngIf=\"esListaSimple(mensaje.resultado)\">{{ textoListaSimple(mensaje.resultado) }}</div>\r\n\r\n <div class=\"chat-ia-tabla-bloque\" *ngIf=\"mensaje.resultado.length > 0 && !esConteo(mensaje.resultado) && !esListaSimple(mensaje.resultado)\">\r\n <div class=\"chat-ia-tabla-acciones\">\r\n <button type=\"button\" class=\"chat-ia-accion\" matTooltip=\"Ampliar\"\r\n (click)=\"ampliar(mensaje.resultado, mensaje.descripcion)\">\r\n <mat-icon>open_in_full</mat-icon>\r\n </button>\r\n <button type=\"button\" class=\"chat-ia-accion\" matTooltip=\"Copiar\"\r\n (click)=\"copiar(mensaje.resultado)\">\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n <button type=\"button\" class=\"chat-ia-accion\" matTooltip=\"Exportar\"\r\n [matMenuTriggerFor]=\"menuExport\">\r\n <mat-icon>download</mat-icon>\r\n </button>\r\n <mat-menu #menuExport=\"matMenu\" class=\"menu-export-chat-ia\">\r\n <button mat-menu-item type=\"button\" (click)=\"exportarCsv(mensaje.resultado)\">CSV (.csv)</button>\r\n <button mat-menu-item type=\"button\" (click)=\"exportarXlsx(mensaje.resultado)\">Excel (.xlsx)</button>\r\n </mat-menu>\r\n </div>\r\n <div class=\"chat-ia-tabla-resultado\">\r\n <table mat-table [dataSource]=\"mensaje.resultado\">\r\n <ng-container *ngFor=\"let columna of columnasDe(mensaje.resultado)\" [matColumnDef]=\"columna\">\r\n <th mat-header-cell *matHeaderCellDef>{{ columna }}</th>\r\n <td mat-cell *matCellDef=\"let fila\">{{ fila[columna] }}</td>\r\n </ng-container>\r\n <tr mat-header-row *matHeaderRowDef=\"columnasDe(mensaje.resultado)\"></tr>\r\n <tr mat-row *matRowDef=\"let fila; columns: columnasDe(mensaje.resultado);\"></tr>\r\n </table>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chat-ia-pensando\" *ngIf=\"consultando\">\r\n <span class=\"chat-ia-dot\"></span><span class=\"chat-ia-dot\"></span><span class=\"chat-ia-dot\"></span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chips-chat-ia\">\r\n <span class=\"chip-chat-ia\" *ngFor=\"let chip of chipsSugeridos\"\r\n (click)=\"onClickEnviar(chip)\">{{ chip }}</span>\r\n </div>\r\n\r\n <div class=\"chat-ia-entrada\">\r\n <div class=\"chat-ia-caja-entrada\">\r\n <mat-icon fontSet=\"wm-menu-iconos\" class=\"chat-ia-expandir\" (click)=\"onClickExpandirBorrador()\">{{ borradorExpandido ? 'close_fullscreen' : 'open_in_full' }}</mat-icon>\r\n <textarea [rows]=\"filasBorrador\" [(ngModel)]=\"borrador\" (keydown.enter)=\"$event.preventDefault(); onClickEnviar()\"\r\n [class.chat-ia-textarea-expandido]=\"borradorExpandido\"\r\n placeholder=\"Escribe tu pregunta...\"></textarea>\r\n <div class=\"chat-ia-pie-entrada\">\r\n <button class=\"chat-ia-selector-modelo\" [matMenuTriggerFor]=\"menuModeloChatIA\" type=\"button\">\r\n <span *ngIf=\"proveedorSeleccionado === 'Gemini'\">Gemini</span>\r\n <span *ngIf=\"proveedorSeleccionado === 'Groq'\">Groq</span>\r\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M6 9l6 6 6-6\"></path>\r\n </svg>\r\n </button>\r\n <button class=\"chat-ia-microfono\" [class.chat-ia-microfono-activo]=\"escuchando\" *ngIf=\"micDisponible\"\r\n (click)=\"onClickMicrofono()\" type=\"button\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\"></path>\r\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"></path>\r\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"></line>\r\n </svg>\r\n </button>\r\n <button class=\"chat-ia-enviar\" [disabled]=\"!borrador.trim() || consultando\" (click)=\"onClickEnviar()\" type=\"button\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M12 19V6\"></path>\r\n <path d=\"M5 13l7-7 7 7\"></path>\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<mat-menu #menuModeloChatIA=\"matMenu\" class=\"menu-modelo-chat-ia\">\r\n <button mat-menu-item [class.opcion-activa]=\"proveedorSeleccionado === 'Gemini'\"\r\n (click)=\"proveedorSeleccionado = 'Gemini'\">\r\n <span>Gemini</span>\r\n <svg *ngIf=\"proveedorSeleccionado === 'Gemini'\" class=\"chat-ia-check\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M20 6L9 17l-5-5\"></path>\r\n </svg>\r\n </button>\r\n <button mat-menu-item [class.opcion-activa]=\"proveedorSeleccionado === 'Groq'\"\r\n (click)=\"proveedorSeleccionado = 'Groq'\">\r\n <span>Groq</span>\r\n <svg *ngIf=\"proveedorSeleccionado === 'Groq'\" class=\"chat-ia-check\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M20 6L9 17l-5-5\"></path>\r\n </svg>\r\n </button>\r\n</mat-menu>\r\n\r\n<!-- Modal \"ampliar\": muestra la tabla a todo el ancho de la pantalla (el panel la recorta). Overlay\r\n propio (no CDK) porque el componente se monta como web-component y el overlay de CDK queda fuera\r\n de su contexto de estilos. -->\r\n<div class=\"chat-ia-modal-overlay\" *ngIf=\"tablaAmpliada\" (click)=\"cerrarAmpliada()\">\r\n <div class=\"chat-ia-modal\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"chat-ia-modal-header\">\r\n <div class=\"chat-ia-modal-titulo\">{{ descripcionAmpliada || 'Resultados' }}</div>\r\n <div class=\"chat-ia-modal-acciones\">\r\n <button type=\"button\" class=\"chat-ia-accion chat-ia-accion-clara\" matTooltip=\"Copiar\"\r\n (click)=\"copiar(tablaAmpliada)\">\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n <button type=\"button\" class=\"chat-ia-accion chat-ia-accion-clara\" matTooltip=\"Exportar\"\r\n [matMenuTriggerFor]=\"menuExportModal\">\r\n <mat-icon>download</mat-icon>\r\n </button>\r\n <mat-menu #menuExportModal=\"matMenu\" class=\"menu-export-chat-ia\">\r\n <button mat-menu-item type=\"button\" (click)=\"exportarCsv(tablaAmpliada)\">CSV (.csv)</button>\r\n <button mat-menu-item type=\"button\" (click)=\"exportarXlsx(tablaAmpliada)\">Excel (.xlsx)</button>\r\n </mat-menu>\r\n <button type=\"button\" class=\"chat-ia-accion chat-ia-accion-clara\" matTooltip=\"Cerrar\"\r\n (click)=\"cerrarAmpliada()\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"chat-ia-modal-tabla\">\r\n <table mat-table [dataSource]=\"tablaAmpliada\">\r\n <ng-container *ngFor=\"let columna of columnasDe(tablaAmpliada)\" [matColumnDef]=\"columna\">\r\n <th mat-header-cell *matHeaderCellDef>{{ columna }}</th>\r\n <td mat-cell *matCellDef=\"let fila\">{{ fila[columna] }}</td>\r\n </ng-container>\r\n <tr mat-header-row *matHeaderRowDef=\"columnasDe(tablaAmpliada)\"></tr>\r\n <tr mat-row *matRowDef=\"let fila; columns: columnasDe(tablaAmpliada);\"></tr>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Aviso ef\u00EDmero tras copiar al portapapeles. -->\r\n<div class=\"chat-ia-copiado-aviso\" *ngIf=\"copiadoAviso\">Tabla copiada</div>\r\n",
245
- styles: [":host{position:fixed;right:32px;bottom:32px;z-index:1000;font-family:Roboto,sans-serif}.chat-ia-panel{width:450px;height:650px;max-width:calc(100vw - 48px);max-height:calc(100vh - 96px);background:#fff;border-radius:18px;box-shadow:0 24px 60px rgba(20,25,30,.28);display:flex;flex-direction:column;overflow:hidden}.chat-ia-header{background:linear-gradient(135deg,#7c5ce0,#5f42bd);padding:16px 18px;display:flex;align-items:center;justify-content:space-between;flex-shrink:0}.chat-ia-header-info{display:flex;align-items:center;gap:10px;min-width:0}.chat-ia-header-icono{width:32px;height:32px;border-radius:50%;background:rgba(255,255,255,.22);display:flex;align-items:center;justify-content:center;flex:none}.chat-ia-titulo{color:#fff;font-size:14px;font-weight:500}.chat-ia-subtitulo{color:rgba(255,255,255,.75);font-size:11px;margin-top:1px}.chat-ia-cerrar{width:24px;height:24px;display:flex;align-items:center;justify-content:center;cursor:pointer;opacity:.85;flex:none}.chat-ia-cerrar:hover{opacity:1}.chat-ia-mensajes{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:12px;padding:16px;background:#fbfafc}.chat-ia-mensaje{display:flex}.chat-ia-mensaje .chat-ia-burbuja{max-width:88%;background:#f2eefb;color:#26313a;border-radius:14px 14px 14px 3px;padding:10px 13px;font-size:13px;line-height:1.5}.chat-ia-mensaje .chat-ia-burbuja-error{background:#fdecea;color:#7a1f14}.chat-ia-mensaje.chat-ia-mensaje-usuario{justify-content:flex-end}.chat-ia-mensaje.chat-ia-mensaje-usuario .chat-ia-burbuja{background:#7c5ce0;color:#fff;border-radius:14px 14px 3px}.chat-ia-bienvenida-texto{align-self:flex-start;max-width:88%;background:#f2eefb;color:#26313a;border-radius:14px 14px 14px 3px;padding:10px 13px;font-size:13px;line-height:1.5}.chips-chat-ia{flex:none;display:flex;flex-wrap:wrap;gap:6px;padding:0 16px 10px}.chip-chat-ia{border:1px solid #e7e2f5;background:#f2eefb;color:#5f42bd;border-radius:14px;padding:5px 10px;font-size:11px;cursor:pointer}.chip-chat-ia:hover{background:#e7ddfa}.chat-ia-descripcion{font-size:13px;line-height:1.5;margin-bottom:6px}.chat-ia-sin-resultados{color:#5a5a5a;font-style:italic}.chat-ia-stat{margin-top:4px}.chat-ia-stat-valor{font-size:30px;font-weight:600;color:#5f42bd;line-height:1.15;font-variant-numeric:proportional-nums}.chat-ia-lista-simple,.chat-ia-tabla-bloque{margin-top:4px;background:#fff;border-radius:10px;padding:8px 10px}.chat-ia-lista-simple{font-size:13px;line-height:1.5}.chat-ia-tabla-acciones{display:flex;justify-content:flex-end;align-items:center;gap:2px;margin-bottom:2px}.chat-ia-accion{width:26px;height:26px;border:none;background:0 0;color:#6b6478;border-radius:7px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;padding:0;flex:none}.chat-ia-accion:hover{background:#f2eefb}.chat-ia-accion .mat-icon{font-size:17px;width:17px;height:17px;line-height:17px}.chat-ia-accion.chat-ia-accion-clara{color:rgba(255,255,255,.9)}.chat-ia-accion.chat-ia-accion-clara:hover{background:rgba(255,255,255,.18);color:#fff}.chat-ia-tabla-resultado{overflow-x:auto;max-width:100%}.chat-ia-tabla-resultado table{font-size:12px;background:0 0}.chat-ia-tabla-resultado th.mat-header-cell{color:#6b6478;font-weight:600;padding:0 14px 5px 0;border-bottom:1px solid #f0edf7;white-space:nowrap}.chat-ia-tabla-resultado td.mat-cell{padding:7px 14px 0 0;white-space:nowrap;font-variant-numeric:tabular-nums}.chat-ia-pensando{align-self:flex-start;background:#f2eefb;padding:12px 16px;border-radius:14px 14px 14px 3px;display:flex;gap:5px;flex-shrink:0}.chat-ia-dot{width:6px;height:6px;border-radius:50%;background:#9a93ae;-webkit-animation:1.1s ease-in-out infinite chatIaBlink;animation:1.1s ease-in-out infinite chatIaBlink}.chat-ia-dot:nth-child(2){-webkit-animation-delay:.15s;animation-delay:.15s}.chat-ia-dot:nth-child(3){-webkit-animation-delay:.3s;animation-delay:.3s}@-webkit-keyframes chatIaBlink{0%,100%,80%{opacity:.25}40%{opacity:1}}@keyframes chatIaBlink{0%,100%,80%{opacity:.25}40%{opacity:1}}.chat-ia-entrada{padding:10px 14px 14px;border-top:1px solid #e9f2ee;flex-shrink:0}.chat-ia-caja-entrada{position:relative;background:#f2f7f5;border:1px solid #e6efea;border-radius:18px;padding:10px 12px 8px}.chat-ia-caja-entrada textarea{border:none;outline:0;background:0 0;width:100%;font:inherit;font-size:13.5px;color:#26313a;resize:none;line-height:1.45;max-height:110px;overflow-y:auto;display:block;padding:0 28px 0 0}.chat-ia-caja-entrada textarea.chat-ia-textarea-expandido{max-height:160px}.chat-ia-caja-entrada textarea::-webkit-input-placeholder{color:#9a93ae}.chat-ia-caja-entrada textarea::-moz-placeholder{color:#9a93ae}.chat-ia-caja-entrada textarea:-ms-input-placeholder{color:#9a93ae}.chat-ia-caja-entrada textarea::-ms-input-placeholder{color:#9a93ae}.chat-ia-caja-entrada textarea::placeholder{color:#9a93ae}.chat-ia-expandir{position:absolute;top:8px;right:10px;font-size:17px;height:17px;width:17px;color:#9a9a9a;cursor:pointer}.chat-ia-pie-entrada{display:flex;align-items:center;justify-content:flex-end;gap:8px;margin-top:8px}.chat-ia-selector-modelo{display:inline-flex;align-items:center;gap:4px;border:none;background:0 0;color:#4e5d57;border-radius:14px;padding:5px 9px;font-size:11.5px;font-weight:600;cursor:pointer}.chat-ia-enviar{width:32px;height:32px;border-radius:50%;border:none;background:#7c5ce0;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;flex:none}.chat-ia-enviar:disabled{background:#dce6e1;color:#a9bab3;cursor:default}.chat-ia-microfono{width:28px;height:28px;border-radius:50%;border:none;background:0 0;color:#6b6478;display:flex;align-items:center;justify-content:center;cursor:pointer;flex:none}.chat-ia-microfono:hover{background:#f2eefb}.chat-ia-microfono.chat-ia-microfono-activo{color:#fff;background:#e05a5a;-webkit-animation:1.1s ease-in-out infinite chatIaBlink;animation:1.1s ease-in-out infinite chatIaBlink}::ng-deep .mat-menu-panel.menu-modelo-chat-ia{min-width:132px;border:1px solid #e6efea;border-radius:10px;box-shadow:0 12px 26px rgba(20,25,30,.16)}::ng-deep .mat-menu-panel.menu-modelo-chat-ia .mat-menu-content{padding:4px}::ng-deep .mat-menu-panel.menu-modelo-chat-ia .mat-menu-item{display:flex;align-items:center;justify-content:space-between;gap:8px;height:auto;line-height:normal;padding:7px 10px;font-size:12px;color:#26313a;border-radius:7px}::ng-deep .mat-menu-panel.menu-modelo-chat-ia .mat-menu-item.opcion-activa{background:#f2f7f5}::ng-deep .mat-menu-panel.menu-modelo-chat-ia .mat-menu-item .chat-ia-check{color:#7c5ce0}.chat-ia-modal-overlay{position:fixed;inset:0;background:rgba(20,25,30,.5);display:flex;align-items:center;justify-content:center;padding:24px;z-index:1100}.chat-ia-modal{background:#fff;border-radius:16px;box-shadow:0 24px 60px rgba(20,25,30,.32);width:auto;max-width:92vw;max-height:86vh;display:flex;flex-direction:column;overflow:hidden}.chat-ia-modal-header{background:linear-gradient(135deg,#7c5ce0,#5f42bd);padding:12px 16px;display:flex;align-items:center;justify-content:space-between;gap:16px;flex-shrink:0}.chat-ia-modal-titulo{color:#fff;font-size:14px;font-weight:500;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.chat-ia-modal-acciones{display:flex;align-items:center;gap:2px;flex:none}.chat-ia-modal-tabla{flex:1;min-height:0;overflow:auto;padding:10px 16px 16px}.chat-ia-modal-tabla table{font-size:13px;background:0 0;width:100%}.chat-ia-modal-tabla th.mat-header-cell{color:#6b6478;font-weight:600;padding:0 18px 8px 0;border-bottom:1px solid #f0edf7;white-space:nowrap}.chat-ia-modal-tabla td.mat-cell{padding:9px 18px 9px 0;white-space:nowrap;color:#26313a;border-bottom:1px solid #f6f4fb;font-variant-numeric:tabular-nums}.chat-ia-copiado-aviso{position:fixed;top:24px;left:50%;transform:translateX(-50%);background:#26313a;color:#fff;font-size:12.5px;padding:8px 16px;border-radius:20px;box-shadow:0 8px 20px rgba(20,25,30,.25);z-index:1200;-webkit-animation:.15s ease-out chatIaAvisoEntrada;animation:.15s ease-out chatIaAvisoEntrada}@-webkit-keyframes chatIaAvisoEntrada{from{opacity:0;transform:translate(-50%,-6px)}to{opacity:1;transform:translate(-50%,0)}}@keyframes chatIaAvisoEntrada{from{opacity:0;transform:translate(-50%,-6px)}to{opacity:1;transform:translate(-50%,0)}}::ng-deep .mat-menu-panel.menu-export-chat-ia{min-width:132px;border:1px solid #e6efea;border-radius:10px;box-shadow:0 12px 26px rgba(20,25,30,.16)}::ng-deep .mat-menu-panel.menu-export-chat-ia .mat-menu-content{padding:4px}::ng-deep .mat-menu-panel.menu-export-chat-ia .mat-menu-item{height:auto;line-height:normal;padding:8px 12px;font-size:12px;color:#26313a;border-radius:7px}::ng-deep .mat-menu-panel.menu-export-chat-ia .mat-menu-item:hover{background:#f2f7f5}"]
261
+ template: "<!-- Panel (abierto) -->\r\n<div class=\"chat-ia-panel\" *ngIf=\"abierto\">\r\n <div class=\"chat-ia-header\">\r\n <div class=\"chat-ia-header-info\">\r\n <div class=\"chat-ia-header-icono\">\r\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#fff\" stroke-width=\"1.8\">\r\n <path d=\"M4 5h16v10H9l-4 4V15H4z\"></path>\r\n </svg>\r\n </div>\r\n <div>\r\n <div class=\"chat-ia-titulo\">Preg\u00FAntale a tus Datos</div>\r\n <div class=\"chat-ia-subtitulo\">Consulta tus reportes en lenguaje natural</div>\r\n </div>\r\n </div>\r\n <div class=\"chat-ia-cerrar\" (click)=\"cerrar()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" stroke=\"#fff\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\">\r\n <path d=\"M6 6l12 12M18 6L6 18\"></path>\r\n </svg>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chat-ia-mensajes\" #mensajesContainer>\r\n <div class=\"chat-ia-bienvenida-texto\">Hola, soy tu asistente de datos de Snap Forms. Preg\u00FAntame lo que quieras saber sobre tu operaci\u00F3n.</div>\r\n\r\n <div class=\"chat-ia-mensaje\" *ngFor=\"let mensaje of mensajes\" [class.chat-ia-mensaje-usuario]=\"mensaje.deUsuario\">\r\n <div class=\"chat-ia-burbuja\" [class.chat-ia-burbuja-error]=\"mensaje.esError\">\r\n <span *ngIf=\"mensaje.texto\">{{ mensaje.texto }}</span>\r\n\r\n <ng-container *ngIf=\"mensaje.resultado\">\r\n <div class=\"chat-ia-descripcion\" *ngIf=\"mensaje.descripcion\">{{ mensaje.descripcion }}</div>\r\n\r\n <div class=\"chat-ia-sin-resultados\" *ngIf=\"mensaje.resultado.length === 0\">La consulta no encontr\u00F3 resultados.</div>\r\n\r\n <div class=\"chat-ia-stat\" *ngIf=\"esConteo(mensaje.resultado)\">\r\n <div class=\"chat-ia-stat-valor\">{{ mensaje.resultado[0].Resultado | number }}</div>\r\n </div>\r\n\r\n <div class=\"chat-ia-lista-simple\" *ngIf=\"esListaSimple(mensaje.resultado)\">{{ textoListaSimple(mensaje.resultado) }}</div>\r\n\r\n <div class=\"chat-ia-tabla-bloque\" *ngIf=\"mensaje.resultado.length > 0 && !esConteo(mensaje.resultado) && !esListaSimple(mensaje.resultado)\">\r\n <div class=\"chat-ia-tabla-acciones\">\r\n <button type=\"button\" class=\"chat-ia-accion\" matTooltip=\"Ampliar\"\r\n (click)=\"ampliar(mensaje.resultado, mensaje.descripcion)\">\r\n <mat-icon>open_in_full</mat-icon>\r\n </button>\r\n <button type=\"button\" class=\"chat-ia-accion\" matTooltip=\"Copiar\"\r\n (click)=\"copiar(mensaje.resultado)\">\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n <button type=\"button\" class=\"chat-ia-accion\" matTooltip=\"Exportar\"\r\n [matMenuTriggerFor]=\"menuExport\">\r\n <mat-icon>download</mat-icon>\r\n </button>\r\n <mat-menu #menuExport=\"matMenu\" class=\"menu-export-chat-ia\">\r\n <button mat-menu-item type=\"button\" (click)=\"exportarCsv(mensaje.resultado)\">CSV (.csv)</button>\r\n <button mat-menu-item type=\"button\" (click)=\"exportarXlsx(mensaje.resultado)\">Excel (.xlsx)</button>\r\n </mat-menu>\r\n </div>\r\n <div class=\"chat-ia-tabla-resultado\">\r\n <table mat-table [dataSource]=\"mensaje.resultado\">\r\n <ng-container *ngFor=\"let columna of columnasDe(mensaje.resultado)\" [matColumnDef]=\"columna\">\r\n <th mat-header-cell *matHeaderCellDef>{{ columna }}</th>\r\n <td mat-cell *matCellDef=\"let fila\">{{ fila[columna] }}</td>\r\n </ng-container>\r\n <tr mat-header-row *matHeaderRowDef=\"columnasDe(mensaje.resultado)\"></tr>\r\n <tr mat-row *matRowDef=\"let fila; columns: columnasDe(mensaje.resultado);\"></tr>\r\n </table>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chat-ia-pensando\" *ngIf=\"consultando\">\r\n <span class=\"chat-ia-dot\"></span><span class=\"chat-ia-dot\"></span><span class=\"chat-ia-dot\"></span>\r\n </div>\r\n </div>\r\n\r\n <!-- Sugerencias: con el chat vac\u00EDo se muestran. Tras la primera pregunta (ya hay mensajes)\r\n quedan plegadas en el bot\u00F3n \"Sugerencias\", que las abre/cierra; al estar plegadas, el \u00E1rea\r\n de conversaci\u00F3n gana ese espacio. -->\r\n <button type=\"button\" class=\"chip-chat-ia-toggle\" *ngIf=\"mensajes.length > 0\"\r\n (click)=\"sugerenciasAbiertas = !sugerenciasAbiertas\">\r\n <svg class=\"chip-chat-ia-toggle-bombilla\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M9 18h6\"></path>\r\n <path d=\"M10 22h4\"></path>\r\n <path d=\"M12 2a7 7 0 0 0-4 12.7c.6.5 1 1.3 1 2.1V18h6v-1.2c0-.8.4-1.6 1-2.1A7 7 0 0 0 12 2z\"></path>\r\n </svg>\r\n <span>Sugerencias</span>\r\n <svg class=\"chip-chat-ia-toggle-chevron\" [class.abierto]=\"sugerenciasAbiertas\" width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M6 9l6 6 6-6\"></path>\r\n </svg>\r\n </button>\r\n <div class=\"chips-chat-ia\" *ngIf=\"mensajes.length === 0 || sugerenciasAbiertas\">\r\n <span class=\"chip-chat-ia\" *ngFor=\"let chip of chipsSugeridos\"\r\n (click)=\"onClickEnviar(chip)\">{{ chip }}</span>\r\n </div>\r\n\r\n <div class=\"chat-ia-entrada\">\r\n <div class=\"chat-ia-caja-entrada\">\r\n <mat-icon fontSet=\"wm-menu-iconos\" class=\"chat-ia-expandir\" (click)=\"onClickExpandirBorrador()\">{{ borradorExpandido ? 'close_fullscreen' : 'open_in_full' }}</mat-icon>\r\n <textarea [rows]=\"filasBorrador\" [(ngModel)]=\"borrador\" (keydown.enter)=\"$event.preventDefault(); onClickEnviar()\"\r\n [class.chat-ia-textarea-expandido]=\"borradorExpandido\"\r\n placeholder=\"Escribe tu pregunta...\"></textarea>\r\n <div class=\"chat-ia-pie-entrada\">\r\n <button class=\"chat-ia-selector-modelo\" [matMenuTriggerFor]=\"menuModeloChatIA\" type=\"button\">\r\n <span *ngIf=\"proveedorSeleccionado === 'Gemini'\">Gemini</span>\r\n <span *ngIf=\"proveedorSeleccionado === 'Groq'\">Groq</span>\r\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M6 9l6 6 6-6\"></path>\r\n </svg>\r\n </button>\r\n <button class=\"chat-ia-microfono\" [class.chat-ia-microfono-activo]=\"escuchando\" *ngIf=\"micDisponible\"\r\n (click)=\"onClickMicrofono()\" type=\"button\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\"></path>\r\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"></path>\r\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"></line>\r\n </svg>\r\n </button>\r\n <button class=\"chat-ia-enviar\" [disabled]=\"!borrador.trim() || consultando\" (click)=\"onClickEnviar()\" type=\"button\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M12 19V6\"></path>\r\n <path d=\"M5 13l7-7 7 7\"></path>\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<mat-menu #menuModeloChatIA=\"matMenu\" class=\"menu-modelo-chat-ia\">\r\n <button mat-menu-item [class.opcion-activa]=\"proveedorSeleccionado === 'Gemini'\"\r\n (click)=\"proveedorSeleccionado = 'Gemini'\">\r\n <span>Gemini</span>\r\n <svg *ngIf=\"proveedorSeleccionado === 'Gemini'\" class=\"chat-ia-check\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M20 6L9 17l-5-5\"></path>\r\n </svg>\r\n </button>\r\n <button mat-menu-item [class.opcion-activa]=\"proveedorSeleccionado === 'Groq'\"\r\n (click)=\"proveedorSeleccionado = 'Groq'\">\r\n <span>Groq</span>\r\n <svg *ngIf=\"proveedorSeleccionado === 'Groq'\" class=\"chat-ia-check\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M20 6L9 17l-5-5\"></path>\r\n </svg>\r\n </button>\r\n</mat-menu>\r\n\r\n<!-- Modal \"ampliar\": muestra la tabla a todo el ancho de la pantalla (el panel la recorta). Overlay\r\n propio (no CDK) porque el componente se monta como web-component y el overlay de CDK queda fuera\r\n de su contexto de estilos. -->\r\n<div class=\"chat-ia-modal-overlay\" *ngIf=\"tablaAmpliada\" (click)=\"cerrarAmpliada()\">\r\n <div class=\"chat-ia-modal\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"chat-ia-modal-header\">\r\n <div class=\"chat-ia-modal-titulo\">{{ descripcionAmpliada || 'Resultados' }}</div>\r\n <div class=\"chat-ia-modal-acciones\">\r\n <button type=\"button\" class=\"chat-ia-accion chat-ia-accion-clara\" matTooltip=\"Copiar\"\r\n (click)=\"copiar(tablaAmpliada)\">\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n <button type=\"button\" class=\"chat-ia-accion chat-ia-accion-clara\" matTooltip=\"Exportar\"\r\n [matMenuTriggerFor]=\"menuExportModal\">\r\n <mat-icon>download</mat-icon>\r\n </button>\r\n <mat-menu #menuExportModal=\"matMenu\" class=\"menu-export-chat-ia\">\r\n <button mat-menu-item type=\"button\" (click)=\"exportarCsv(tablaAmpliada)\">CSV (.csv)</button>\r\n <button mat-menu-item type=\"button\" (click)=\"exportarXlsx(tablaAmpliada)\">Excel (.xlsx)</button>\r\n </mat-menu>\r\n <button type=\"button\" class=\"chat-ia-accion chat-ia-accion-clara\" matTooltip=\"Cerrar\"\r\n (click)=\"cerrarAmpliada()\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"chat-ia-modal-tabla\">\r\n <table mat-table [dataSource]=\"tablaAmpliada\">\r\n <ng-container *ngFor=\"let columna of columnasDe(tablaAmpliada)\" [matColumnDef]=\"columna\">\r\n <th mat-header-cell *matHeaderCellDef>{{ columna }}</th>\r\n <td mat-cell *matCellDef=\"let fila\">{{ fila[columna] }}</td>\r\n </ng-container>\r\n <tr mat-header-row *matHeaderRowDef=\"columnasDe(tablaAmpliada)\"></tr>\r\n <tr mat-row *matRowDef=\"let fila; columns: columnasDe(tablaAmpliada);\"></tr>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Aviso ef\u00EDmero tras copiar al portapapeles. -->\r\n<div class=\"chat-ia-copiado-aviso\" *ngIf=\"copiadoAviso\">Tabla copiada</div>\r\n",
262
+ styles: [":host{position:fixed;right:32px;bottom:32px;z-index:1000;font-family:Roboto,sans-serif}.chat-ia-panel{width:450px;height:650px;max-width:calc(100vw - 48px);max-height:calc(100vh - 96px);background:#fff;border-radius:18px;box-shadow:0 24px 60px rgba(20,25,30,.28);display:flex;flex-direction:column;overflow:hidden}.chat-ia-header{background:linear-gradient(135deg,#7c5ce0,#5f42bd);padding:16px 18px;display:flex;align-items:center;justify-content:space-between;flex-shrink:0}.chat-ia-header-info{display:flex;align-items:center;gap:10px;min-width:0}.chat-ia-header-icono{width:32px;height:32px;border-radius:50%;background:rgba(255,255,255,.22);display:flex;align-items:center;justify-content:center;flex:none}.chat-ia-titulo{color:#fff;font-size:14px;font-weight:500}.chat-ia-subtitulo{color:rgba(255,255,255,.75);font-size:11px;margin-top:1px}.chat-ia-cerrar{width:24px;height:24px;display:flex;align-items:center;justify-content:center;cursor:pointer;opacity:.85;flex:none}.chat-ia-cerrar:hover{opacity:1}.chat-ia-mensajes{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:12px;padding:16px;background:#fbfafc}.chat-ia-mensaje{display:flex}.chat-ia-mensaje .chat-ia-burbuja{max-width:88%;background:#f2eefb;color:#26313a;border-radius:14px 14px 14px 3px;padding:10px 13px;font-size:13px;line-height:1.5}.chat-ia-mensaje .chat-ia-burbuja-error{background:#fdecea;color:#7a1f14}.chat-ia-mensaje.chat-ia-mensaje-usuario{justify-content:flex-end}.chat-ia-mensaje.chat-ia-mensaje-usuario .chat-ia-burbuja{background:#7c5ce0;color:#fff;border-radius:14px 14px 3px}.chat-ia-bienvenida-texto{align-self:flex-start;max-width:88%;background:#f2eefb;color:#26313a;border-radius:14px 14px 14px 3px;padding:10px 13px;font-size:13px;line-height:1.5}.chips-chat-ia{flex:none;display:flex;flex-direction:column;align-items:flex-start;gap:6px;padding:0 16px 10px}.chip-chat-ia{max-width:100%;border:1px solid #e7e2f5;background:#f2eefb;color:#5f42bd;border-radius:14px;padding:5px 10px;font-size:11px;line-height:1.35;cursor:pointer;overflow-wrap:anywhere}.chip-chat-ia:hover{background:#e7ddfa}.chip-chat-ia-toggle{flex:none;align-self:flex-start;display:inline-flex;align-items:center;gap:6px;margin:10px 16px;border:1px solid #e7e2f5;background:#f2eefb;color:#5f42bd;border-radius:16px;padding:6px 12px;font-size:12px;cursor:pointer}.chip-chat-ia-toggle .chip-chat-ia-toggle-chevron{transition:transform .15s}.chip-chat-ia-toggle .chip-chat-ia-toggle-chevron.abierto{transform:rotate(180deg)}.chip-chat-ia-toggle:hover{background:#e7ddfa}.chat-ia-descripcion{font-size:13px;line-height:1.5;margin-bottom:6px}.chat-ia-sin-resultados{color:#5a5a5a;font-style:italic}.chat-ia-stat{margin-top:4px}.chat-ia-stat-valor{font-size:30px;font-weight:600;color:#5f42bd;line-height:1.15;font-variant-numeric:proportional-nums}.chat-ia-lista-simple,.chat-ia-tabla-bloque{margin-top:4px;background:#fff;border-radius:10px;padding:8px 10px}.chat-ia-lista-simple{font-size:13px;line-height:1.5}.chat-ia-tabla-acciones{display:flex;justify-content:flex-end;align-items:center;gap:2px;margin-bottom:2px}.chat-ia-accion{width:26px;height:26px;border:none;background:0 0;color:#6b6478;border-radius:7px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;padding:0;flex:none}.chat-ia-accion:hover{background:#f2eefb}.chat-ia-accion .mat-icon{font-size:17px;width:17px;height:17px;line-height:17px}.chat-ia-accion.chat-ia-accion-clara{color:rgba(255,255,255,.9)}.chat-ia-accion.chat-ia-accion-clara:hover{background:rgba(255,255,255,.18);color:#fff}.chat-ia-tabla-resultado{overflow-x:auto;max-width:100%}.chat-ia-tabla-resultado table{font-size:12px;background:0 0}.chat-ia-tabla-resultado th.mat-header-cell{color:#6b6478;font-weight:600;padding:0 14px 5px 0;border-bottom:1px solid #f0edf7;white-space:nowrap}.chat-ia-tabla-resultado td.mat-cell{padding:7px 14px 0 0;white-space:nowrap;font-variant-numeric:tabular-nums}.chat-ia-pensando{align-self:flex-start;background:#f2eefb;padding:12px 16px;border-radius:14px 14px 14px 3px;display:flex;gap:5px;flex-shrink:0}.chat-ia-dot{width:6px;height:6px;border-radius:50%;background:#9a93ae;-webkit-animation:1.1s ease-in-out infinite chatIaBlink;animation:1.1s ease-in-out infinite chatIaBlink}.chat-ia-dot:nth-child(2){-webkit-animation-delay:.15s;animation-delay:.15s}.chat-ia-dot:nth-child(3){-webkit-animation-delay:.3s;animation-delay:.3s}@-webkit-keyframes chatIaBlink{0%,100%,80%{opacity:.25}40%{opacity:1}}@keyframes chatIaBlink{0%,100%,80%{opacity:.25}40%{opacity:1}}.chat-ia-entrada{padding:10px 14px 14px;border-top:1px solid #e9f2ee;flex-shrink:0}.chat-ia-caja-entrada{position:relative;background:#f2f7f5;border:1px solid #e6efea;border-radius:18px;padding:10px 12px 8px}.chat-ia-caja-entrada textarea{border:none;outline:0;background:0 0;width:100%;font:inherit;font-size:13.5px;color:#26313a;resize:none;line-height:1.45;max-height:110px;overflow-y:auto;display:block;padding:0 28px 0 0}.chat-ia-caja-entrada textarea.chat-ia-textarea-expandido{max-height:160px}.chat-ia-caja-entrada textarea::-webkit-input-placeholder{color:#9a93ae}.chat-ia-caja-entrada textarea::-moz-placeholder{color:#9a93ae}.chat-ia-caja-entrada textarea:-ms-input-placeholder{color:#9a93ae}.chat-ia-caja-entrada textarea::-ms-input-placeholder{color:#9a93ae}.chat-ia-caja-entrada textarea::placeholder{color:#9a93ae}.chat-ia-expandir{position:absolute;top:8px;right:10px;font-size:17px;height:17px;width:17px;color:#9a9a9a;cursor:pointer}.chat-ia-pie-entrada{display:flex;align-items:center;justify-content:flex-end;gap:8px;margin-top:8px}.chat-ia-selector-modelo{display:inline-flex;align-items:center;gap:4px;border:none;background:0 0;color:#4e5d57;border-radius:14px;padding:5px 9px;font-size:11.5px;font-weight:600;cursor:pointer}.chat-ia-enviar{width:32px;height:32px;border-radius:50%;border:none;background:#7c5ce0;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;flex:none}.chat-ia-enviar:disabled{background:#dce6e1;color:#a9bab3;cursor:default}.chat-ia-microfono{width:28px;height:28px;border-radius:50%;border:none;background:0 0;color:#6b6478;display:flex;align-items:center;justify-content:center;cursor:pointer;flex:none}.chat-ia-microfono:hover{background:#f2eefb}.chat-ia-microfono.chat-ia-microfono-activo{color:#fff;background:#e05a5a;-webkit-animation:1.1s ease-in-out infinite chatIaBlink;animation:1.1s ease-in-out infinite chatIaBlink}::ng-deep .mat-menu-panel.menu-modelo-chat-ia{min-width:132px;border:1px solid #e6efea;border-radius:10px;box-shadow:0 12px 26px rgba(20,25,30,.16)}::ng-deep .mat-menu-panel.menu-modelo-chat-ia .mat-menu-content{padding:4px}::ng-deep .mat-menu-panel.menu-modelo-chat-ia .mat-menu-item{display:flex;align-items:center;justify-content:space-between;gap:8px;height:auto;line-height:normal;padding:7px 10px;font-size:12px;color:#26313a;border-radius:7px}::ng-deep .mat-menu-panel.menu-modelo-chat-ia .mat-menu-item.opcion-activa{background:#f2f7f5}::ng-deep .mat-menu-panel.menu-modelo-chat-ia .mat-menu-item .chat-ia-check{color:#7c5ce0}.chat-ia-modal-overlay{position:fixed;inset:0;background:rgba(20,25,30,.5);display:flex;align-items:center;justify-content:center;padding:24px;z-index:1100}.chat-ia-modal{background:#fff;border-radius:16px;box-shadow:0 24px 60px rgba(20,25,30,.32);width:auto;max-width:92vw;max-height:86vh;display:flex;flex-direction:column;overflow:hidden}.chat-ia-modal-header{background:linear-gradient(135deg,#7c5ce0,#5f42bd);padding:12px 16px;display:flex;align-items:center;justify-content:space-between;gap:16px;flex-shrink:0}.chat-ia-modal-titulo{color:#fff;font-size:14px;font-weight:500;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.chat-ia-modal-acciones{display:flex;align-items:center;gap:2px;flex:none}.chat-ia-modal-tabla{flex:1;min-height:0;overflow:auto;padding:10px 16px 16px}.chat-ia-modal-tabla table{font-size:13px;background:0 0;width:100%}.chat-ia-modal-tabla th.mat-header-cell{color:#6b6478;font-weight:600;padding:0 18px 8px 0;border-bottom:1px solid #f0edf7;white-space:nowrap}.chat-ia-modal-tabla td.mat-cell{padding:9px 18px 9px 0;white-space:nowrap;color:#26313a;border-bottom:1px solid #f6f4fb;font-variant-numeric:tabular-nums}.chat-ia-copiado-aviso{position:fixed;top:24px;left:50%;transform:translateX(-50%);background:#26313a;color:#fff;font-size:12.5px;padding:8px 16px;border-radius:20px;box-shadow:0 8px 20px rgba(20,25,30,.25);z-index:1200;-webkit-animation:.15s ease-out chatIaAvisoEntrada;animation:.15s ease-out chatIaAvisoEntrada}@-webkit-keyframes chatIaAvisoEntrada{from{opacity:0;transform:translate(-50%,-6px)}to{opacity:1;transform:translate(-50%,0)}}@keyframes chatIaAvisoEntrada{from{opacity:0;transform:translate(-50%,-6px)}to{opacity:1;transform:translate(-50%,0)}}::ng-deep .mat-menu-panel.menu-export-chat-ia{min-width:132px;border:1px solid #e6efea;border-radius:10px;box-shadow:0 12px 26px rgba(20,25,30,.16)}::ng-deep .mat-menu-panel.menu-export-chat-ia .mat-menu-content{padding:4px}::ng-deep .mat-menu-panel.menu-export-chat-ia .mat-menu-item{height:auto;line-height:normal;padding:8px 12px;font-size:12px;color:#26313a;border-radius:7px}::ng-deep .mat-menu-panel.menu-export-chat-ia .mat-menu-item:hover{background:#f2f7f5}"]
246
263
  })
247
264
  ], AsistenteDatosComponent);
248
265
  return AsistenteDatosComponent;
249
266
  }());
250
267
  export { AsistenteDatosComponent };
251
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNpc3RlbnRlLWRhdG9zLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL3dtLW1lbnUvIiwic291cmNlcyI6WyJsaWIvd20tbWVudS9hc2lzdGVudGUtZGF0b3MvYXNpc3RlbnRlLWRhdG9zLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBYyxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDOUYsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDeEUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDekUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFnQjVEO0lBK0NJLGlDQUNZLHdCQUFrRCxFQUNsRCxpQkFBMkMsRUFDM0MsV0FBK0I7UUFGL0IsNkJBQXdCLEdBQXhCLHdCQUF3QixDQUEwQjtRQUNsRCxzQkFBaUIsR0FBakIsaUJBQWlCLENBQTBCO1FBQzNDLGdCQUFXLEdBQVgsV0FBVyxDQUFvQjtRQS9DM0MsMEZBQTBGO1FBQzFGLHFGQUFxRjtRQUM1RSxZQUFPLEdBQUcsS0FBSyxDQUFDO1FBU3pCLHlEQUF5RDtRQUNoRCxXQUFNLEdBQUcsT0FBTyxDQUFDO1FBRWhCLGlCQUFZLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUUzQyxhQUFRLEdBQTRCLEVBQUUsQ0FBQztRQUN2QyxhQUFRLEdBQUcsRUFBRSxDQUFDO1FBQ3JCLDhGQUE4RjtRQUM5RixrR0FBa0c7UUFDM0Ysc0JBQWlCLEdBQUcsS0FBSyxDQUFDO1FBQzFCLGdCQUFXLEdBQUcsS0FBSyxDQUFDO1FBQzNCLG1GQUFtRjtRQUNuRiwyQ0FBMkM7UUFDcEMsMEJBQXFCLEdBQXNCLFFBQVEsQ0FBQztRQUMzRCxzRkFBc0Y7UUFDL0UsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUUxQiw2RkFB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LElBQUksSUFBSSxFQUFFLENBQUM7UUFDekIsSUFBTSxHQUFHLEdBQUcsVUFBQyxDQUFTLElBQUssT0FBQSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBMUIsQ0FBMEIsQ0FBQztRQUN0RCxPQUFPLENBQ0gsa0JBQWtCO1lBQ2xCLEtBQUssQ0FBQyxXQUFXLEVBQUU7WUFDbkIsR0FBRyxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDekIsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNwQixHQUFHO1lBQ0gsR0FBRyxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNyQixHQUFHLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQzFCLENBQUM7SUFDTixDQUFDOztnQkE3S3FDLHdCQUF3QjtnQkFDL0Isd0JBQXdCO2dCQUM5QixrQkFBa0I7O0lBakRYO1FBQS9CLFNBQVMsQ0FBQyxtQkFBbUIsQ0FBQztzRUFBd0Q7SUFJOUU7UUFBUixLQUFLLEVBQUU7NERBQWlCO0lBR2hCO1FBQVIsS0FBSyxFQUFFOytEQUlQO0lBR1E7UUFBUixLQUFLLEVBQUU7MkRBQWtCO0lBRWhCO1FBQVQsTUFBTSxFQUFFO2lFQUF5QztJQWpCekMsdUJBQXVCO1FBTG5DLFNBQVMsQ0FBQztZQUNQLFFBQVEsRUFBRSxvQkFBb0I7WUFDOUIsMHBXQUErQzs7U0FFbEQsQ0FBQztPQUNXLHVCQUF1QixDQThObkM7SUFBRCw4QkFBQztDQUFBLEFBOU5ELElBOE5DO1NBOU5ZLHVCQUF1QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgUmVjb25vY2ltaWVudG9Wb3pTZXJ2aWNlIH0gZnJvbSAnLi9yZWNvbm9jaW1pZW50by12b3ouc2VydmljZSc7XHJcbmltcG9ydCB7IEFzaXN0ZW50ZURhdG9zQXBpU2VydmljZSB9IGZyb20gJy4vYXNpc3RlbnRlLWRhdG9zLWFwaS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgVGFibGFFeHBvcnRTZXJ2aWNlIH0gZnJvbSAnLi90YWJsYS1leHBvcnQuc2VydmljZSc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIE1lbnNhamVBc2lzdGVudGVEYXRvcyB7XHJcbiAgICBkZVVzdWFyaW86IGJvb2xlYW47XHJcbiAgICB0ZXh0bz86IHN0cmluZztcclxuICAgIGRlc2NyaXBjaW9uPzogc3RyaW5nO1xyXG4gICAgcmVzdWx0YWRvPzogYW55W107XHJcbiAgICBwcm92ZWVkb3I/OiBzdHJpbmc7XHJcbiAgICBlc0Vycm9yPzogYm9vbGVhbjtcclxufVxyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ3dtLWFzaXN0ZW50ZS1kYXRvcycsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vYXNpc3RlbnRlLWRhdG9zLmNvbXBvbmVudC5odG1sJyxcclxuICAgIHN0eWxlVXJsczogWycuL2FzaXN0ZW50ZS1kYXRvcy5jb21wb25lbnQuc2NzcyddLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgQXNpc3RlbnRlRGF0b3NDb21wb25lbnQge1xyXG4gICAgQFZpZXdDaGlsZCgnbWVuc2FqZXNDb250YWluZXInKSBwcml2YXRlIG1lbnNhamVzQ29udGFpbmVyPzogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XHJcblxyXG4gICAgLy8gTGEgYXBlcnR1cmEvY2llcnJlIGRlbCBwYW5lbCBsYSBjb250cm9sYSBlbCBwYWRyZSAoZWwgbWVuw7opLiBFbCBwYW5lbCBzb2xvIHNlIHJlbmRlcml6YVxyXG4gICAgLy8gY3VhbmRvIGBhYmllcnRvYCBlcyB0cnVlIHkgYXZpc2EsIHbDrWEgYGNlcnJhckNoYW5nZWAsIGN1YW5kbyBlbCB1c3VhcmlvIHRvY2EgbGEgWC5cclxuICAgIEBJbnB1dCgpIGFiaWVydG8gPSBmYWxzZTtcclxuXHJcbiAgICAvLyBVUkwgZGVsIFBPU1QgZGUgY29uc3VsdGEuIFNlIHJlZmxlamEgZW4gZWwgYXBpIHNlcnZpY2UgKHByb3BpZWRhZCBgdXJsYCksIHF1ZSBlcyBkb25kZSBzZSB1c2EuXHJcbiAgICBASW5wdXQoKSBzZXQgdXJsQ29uc3VsdGFyKHZhbG9yOiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAodmFsb3IpIHtcclxuICAgICAgICAgICAgdGhpcy5hc2lzdGVudGVEYXRvc0FwaVNlcnZpY2UudXJsID0gdmFsb3I7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIElkaW9tYSBwYXJhIGVsIHJlY29ub2NpbWllbnRvIGRlIHZveiAoV2ViIFNwZWVjaCBBUEkpLlxyXG4gICAgQElucHV0KCkgaWRpb21hID0gJ2VzLUNPJztcclxuXHJcbiAgICBAT3V0cHV0KCkgY2VycmFyQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xyXG5cclxuICAgIHB1YmxpYyBtZW5zYWplczogTWVuc2FqZUFzaXN0ZW50ZURhdG9zW10gPSBbXTtcclxuICAgIHB1YmxpYyBib3JyYWRvciA9ICcnO1xyXG4gICAgLy8gQWx0ZXJuYSBlbCBhbHRvIGRlIGxhIGNhamEgZGVsIG1lbnNhamUgKGNvbXBhY3RhIOKGlCBleHBhbmRpZGEpLCBpZ3VhbCBxdWUgZWwgXCJwZWRpciBjYW1iaW9zXCJcclxuICAgIC8vIGRlbCBhc2lzdGVudGUgZGUgSUEgZGVsIGdlbmVyYWRvciBkZSBmb3JtdWxhcmlvcyAodmVyIGZpbGFzQm9ycmFkb3IgLyBvbkNsaWNrRXhwYW5kaXJCb3JyYWRvcikuXHJcbiAgICBwdWJsaWMgYm9ycmFkb3JFeHBhbmRpZG8gPSBmYWxzZTtcclxuICAgIHB1YmxpYyBjb25zdWx0YW5kbyA9IGZhbHNlO1xyXG4gICAgLy8gXCJHZW1pbmlcIiBvIFwiR3JvcVwiIOKAlCBtaXNtbyBzZWxlY3RvciBxdWUgZWwgYXNpc3RlbnRlIGRlIGdlbmVyYWNpw7NuIGRlIGZvcm11bGFyaW9zXHJcbiAgICAvLyAodmVyIFByb3ZlZWRvcklBU2VydmljaW8gZW4gZWwgYmFja2VuZCkuXHJcbiAgICBwdWJsaWMgcHJvdmVlZG9yU2VsZWNjaW9uYWRvOiAnR2VtaW5pJyB8ICdHcm9xJyA9ICdHZW1pbmknO1xyXG4gICAgLy8gRGljdGFkbyBwb3Igdm96IChXZWIgU3BlZWNoIEFQSSkg4oCUIHNpbiBzb3BvcnRlIGVuIEZpcmVmb3gsIGluY29uc2lzdGVudGUgZW4gU2FmYXJpLlxyXG4gICAgcHVibGljIGVzY3VjaGFuZG8gPSBmYWxzZTtcclxuXHJcbiAgICAvLyBUYWJsYSBhYmllcnRhIGVuIGVsIG1vZGFsIFwiYW1wbGlhclwiIChudWxsID0gbW9kYWwgY2VycmFkbykuIEVsIHBhbmVsIGRlbCBjaGF0IGVzIGFuZ29zdG8geVxyXG4gICAgLy8gcmVjb3J0YSBsYXMgY29sdW1uYXM7IGVsIG1vZGFsIG11ZXN0cmEgbGEgbWlzbWEgdGFibGEgYSB0b2RvIGVsIGFuY2hvIGRlIGxhIHBhbnRhbGxhLlxyXG4gICAgcHVibGljIHRhYmxhQW1wbGlhZGE6IGFueVtdIHwgbnVsbCA9IG51bGw7XHJcbiAgICBwdWJsaWMgZGVzY3JpcGNpb25BbXBsaWFkYSA9ICcnO1xyXG4gICAgLy8gQXZpc28gZWbDrW1lcm8gXCJUYWJsYSBjb3BpYWRhXCIgdHJhcyBjb3BpYXIgYWwgcG9ydGFwYXBlbGVzLlxyXG4gICAgcHVibGljIGNvcGlhZG9BdmlzbyA9IGZhbHNlO1xyXG5cclxuICAgIC8vIFByZWd1bnRhcyB5YSB2ZXJpZmljYWRhcyBjb21vIHJlc3BvbmRpYmxlcyBob3kgKHdoaXRlbGlzdCArIGNvbnRyYXRvIGRlIGxhIElBIOKAlCB2ZXJcclxuICAgIC8vIENoYXRDb25zdWx0YVdoaXRlbGlzdFNlcnZpY2lvL0NoYXRDb25zdWx0YVByb21wdFNlcnZpY2lvIGVuIGVsIGJhY2tlbmQpLCBtb3N0cmFkYXMgY29tbyBjaGlwc1xyXG4gICAgLy8gZGUgc3VnZXJlbmNpYSBlbiBlbCBlc3RhZG8gdmFjw61vIGRlbCBjaGF0LlxyXG4gICAgcHVibGljIGNoaXBzU3VnZXJpZG9zOiBzdHJpbmdbXSA9IFtcclxuICAgICAgICAnwr9DdcOhbnRvcyBmb3JtdWxhcmlvcyBzZSBkaWxpZ2VuY2lhcm9uIGhveT8nLFxyXG4gICAgICAgICfCv0N1w6FudG9zIGZvcm11bGFyaW9zIHNlIGRpbGlnZW5jaWFyb24gZXN0YSBzZW1hbmE/JyxcclxuICAgICAgICAnTXXDqXN0cmFtZSBsb3Mgw7psdGltb3MgMTAgZm9ybXVsYXJpb3MgZGlsaWdlbmNpYWRvcycsXHJcbiAgICBdO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIHByaXZhdGUgYXNpc3RlbnRlRGF0b3NBcGlTZXJ2aWNlOiBBc2lzdGVudGVEYXRvc0FwaVNlcnZpY2UsXHJcbiAgICAgICAgcHJpdmF0ZSByZWNvbm9jaW1pZW50b1ZvejogUmVjb25vY2ltaWVudG9Wb3pTZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgdGFibGFFeHBvcnQ6IFRhYmxhRXhwb3J0U2VydmljZVxyXG4gICAgKSB7fVxyXG5cclxuICAgIC8vIEVsIHBhZHJlIGFicmUvY2llcnJhIGVsIHBhbmVsOyBhcXXDrSBzb2xvIHNlIGF2aXNhIHF1ZSBlbCB1c3VhcmlvIHBpZGnDsyBjZXJyYXJsbyAoYm90w7NuIFgpLlxyXG4gICAgY2VycmFyKCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuY2VycmFyQ2hhbmdlLmVtaXQoKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBDYWphIGRlbCBtZW5zYWplIGNvbXBhY3RhICgxIGZpbGEsIGNvbW8gZXJhIGVsIGNoYXQgb3JpZ2luYWxtZW50ZSkg4oaUIGV4cGFuZGlkYSAoNiBmaWxhcykuXHJcbiAgICAvLyBFbCBib3TDs24gZGUgZXhwYW5kaXIgZXMgZWwgbWlzbW8gcGF0csOzbiBkZWwgXCJwZWRpciBjYW1iaW9zXCIgZGVsIGdlbmVyYWRvci5cclxuICAgIGdldCBmaWxhc0JvcnJhZG9yKCk6IG51bWJlciB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuYm9ycmFkb3JFeHBhbmRpZG8gPyA2IDogMTtcclxuICAgIH1cclxuXHJcbiAgICBvbkNsaWNrRXhwYW5kaXJCb3JyYWRvcigpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmJvcnJhZG9yRXhwYW5kaWRvID0gIXRoaXMuYm9ycmFkb3JFeHBhbmRpZG87XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IG1pY0Rpc3BvbmlibGUoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVjb25vY2ltaWVudG9Wb3ouZXN0YVNvcG9ydGFkbygpO1xyXG4gICAgfVxyXG5cclxuICAgIG9uQ2xpY2tNaWNyb2Zvbm8oKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuZXNjdWNoYW5kbykge1xyXG4gICAgICAgICAgICB0aGlzLnJlY29ub2NpbWllbnRvVm96LmRldGVuZXIoKTtcclxuICAgICAgICAgICAgdGhpcy5lc2N1Y2hhbmRvID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghdGhpcy5yZWNvbm9jaW1pZW50b1Zvei5lc3RhU29wb3J0YWRvKCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gRWwgcmVzdWx0YWRvIGRlbCByZWNvbm9jaW1pZW50byBubyBpbmNsdXllIGxvIHF1ZSB5YSBlc3RhYmEgZXNjcml0byDigJQgc2UgZ3VhcmRhIGFudGVzIGRlXHJcbiAgICAgICAgLy8gZW1wZXphciB5IHNlIGFudGVwb25lIGVuIGNhZGEgYWN0dWFsaXphY2nDs24gKHF1ZSBsbGVnYSBjb24gbGEgdHJhbnNjcmlwY2nDs24gQ09NUExFVEEgZGVcclxuICAgICAgICAvLyBlc3RhIHNlc2nDs24gZGUgZXNjdWNoYSwgbm8gdW4gaW5jcmVtZW50bykgcGFyYSBubyBwZXJkZXIgbG8gcXVlIHlhIGhhYsOtYSBlbiBlbCBjYW1wby5cclxuICAgICAgICBjb25zdCB0ZXh0b1ByZXZpbyA9IHRoaXMuYm9ycmFkb3IudHJpbSgpO1xyXG4gICAgICAgIHRoaXMuZXNjdWNoYW5kbyA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5yZWNvbm9jaW1pZW50b1Zvei5pbmljaWFyKFxyXG4gICAgICAgICAgICB0aGlzLmlkaW9tYSxcclxuICAgICAgICAgICAgKHRleHRvKSA9PiAodGhpcy5ib3JyYWRvciA9IHRleHRvUHJldmlvID8gYCR7dGV4dG9QcmV2aW99ICR7dGV4dG99YCA6IHRleHRvKSxcclxuICAgICAgICAgICAgKCkgPT4gKHRoaXMuZXNjdWNoYW5kbyA9IGZhbHNlKVxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgb25DbGlja0Vudmlhcih0ZXh0b1ByZXNldD86IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IHByZWd1bnRhID0gKHRleHRvUHJlc2V0ID8/IHRoaXMuYm9ycmFkb3IpLnRyaW0oKTtcclxuICAgICAgICBpZiAoIXByZWd1bnRhIHx8IHRoaXMuY29uc3VsdGFuZG8pIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5tZW5zYWplcy5wdXNoKHsgZGVVc3VhcmlvOiB0cnVlLCB0ZXh0bzogcHJlZ3VudGEgfSk7XHJcbiAgICAgICAgdGhpcy5ib3JyYWRvciA9ICcnO1xyXG5cclxuICAgICAgICAvLyBTaW4gdXJsIGRlIGNvbnN1bHRhIG5vIHNlIGhhY2UgbGEgcGV0aWNpw7NuOiBlbCB1c3VhcmlvIHZlIGVsIG1pc21vIGVycm9yIGdlbsOpcmljbyBxdWVcclxuICAgICAgICAvLyBjdWFuZG8gbGEgQVBJIGZhbGxhLlxyXG4gICAgICAgIGlmICghdGhpcy5hc2lzdGVudGVEYXRvc0FwaVNlcnZpY2UudXJsKSB7XHJcbiAgICAgICAgICAgIHRoaXMubWVuc2FqZXMucHVzaCh7XHJcbiAgICAgICAgICAgICAgICBkZVVzdWFyaW86IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgdGV4dG86ICdObyBzZSBwdWRvIHByb2Nlc2FyIGxhIGNvbnN1bHRhLicsXHJcbiAgICAgICAgICAgICAgICBlc0Vycm9yOiB0cnVlLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgdGhpcy5zY3JvbGxBbEZpbmFsKCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuY29uc3VsdGFuZG8gPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuc2Nyb2xsQWxGaW5hbCgpO1xyXG5cclxuICAgICAgICB0aGlzLmFzaXN0ZW50ZURhdG9zQXBpU2VydmljZS5jb25zdWx0YXIocHJlZ3VudGEsIHRoaXMucHJvdmVlZG9yU2VsZWNjaW9uYWRvKS5zdWJzY3JpYmUoe1xyXG4gICAgICAgICAgICAvLyBFbCB0aXBvIChSZXNwdWVzdGFBc2lzdGVudGVEYXRvcykgc2UgaW5maWVyZSBkZWwgT2JzZXJ2YWJsZTogaW1wb3J0YXIgbGEgaW50ZXJmYXpcclxuICAgICAgICAgICAgLy8gZGVqYWJhIHVuIGltcG9ydCBhIHVuIHPDrW1ib2xvIGluZXhpc3RlbnRlIGVuIGVsIEpTIGRlIGxhIGxpYnJlcsOtYSAoYXZpc28gZGUgcm9sbHVwKS5cclxuICAgICAgICAgICAgbmV4dDogKHJlc3B1ZXN0YSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jb25zdWx0YW5kbyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5tZW5zYWplcy5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgICBkZVVzdWFyaW86IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgICAgIGRlc2NyaXBjaW9uOiByZXNwdWVzdGEuRGVzY3JpcGNpb24sXHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0YWRvOiByZXNwdWVzdGEuUmVzdWx0YWRvID8/IFtdLFxyXG4gICAgICAgICAgICAgICAgICAgIHByb3ZlZWRvcjogcmVzcHVlc3RhLlByb3ZlZWRvcixcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zY3JvbGxBbEZpbmFsKCk7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGVycm9yOiAoZXJyb3IpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY29uc3VsdGFuZG8gPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIHRoaXMubWVuc2FqZXMucHVzaCh7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVVc3VhcmlvOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0bzogZXJyb3I/Lk1lbnNhamUgfHwgJ05vIHNlIHB1ZG8gcHJvY2VzYXIgbGEgY29uc3VsdGEuJyxcclxuICAgICAgICAgICAgICAgICAgICBlc0Vycm9yOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNjcm9sbEFsRmluYWwoKTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBFbCBudWV2byBtZW5zYWplIHJlY2nDqW4gc2UgcmVmbGVqYSBlbiBlbCBET00gZGVzcHXDqXMgZGVsIHNpZ3VpZW50ZSBjaWNsbyBkZSBkZXRlY2Npw7NuIGRlXHJcbiAgICAvLyBjYW1iaW9zIOKAlCBwb3IgZXNvIGVsIHNjcm9sbFRvcCBzZSBhanVzdGEgZW4gdW4gc2V0VGltZW91dCgwKSwgbm8gaW5tZWRpYXRhbWVudGUgZGVzcHXDqXMgZGVsXHJcbiAgICAvLyBwdXNoLCBwYXJhIHF1ZSBzY3JvbGxIZWlnaHQgeWEgaW5jbHV5YSBlbCBtZW5zYWplIGFncmVnYWRvLlxyXG4gICAgcHJpdmF0ZSBzY3JvbGxBbEZpbmFsKCk6IHZvaWQge1xyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBlbGVtZW50byA9IHRoaXMubWVuc2FqZXNDb250YWluZXI/Lm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICAgICAgICAgIGlmIChlbGVtZW50bykge1xyXG4gICAgICAgICAgICAgICAgZWxlbWVudG8uc2Nyb2xsVG9wID0gZWxlbWVudG8uc2Nyb2xsSGVpZ2h0O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgY29sdW1uYXNEZShyZXN1bHRhZG86IGFueVtdKTogc3RyaW5nW10ge1xyXG4gICAgICAgIHJldHVybiByZXN1bHRhZG8ubGVuZ3RoID8gT2JqZWN0LmtleXMocmVzdWx0YWRvWzBdKSA6IFtdO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEVsIGJhY2tlbmQgZGV2dWVsdmUgdW4gY29udGVvIChDaGF0Q29uc3VsdGFJQVNlcnZpY2lvLkVqZWN1dGFyQ29udGVvKSBjb21vIHVuYSBzb2xhIGZpbGEgY29uXHJcbiAgICAvLyB1bmEgc29sYSBjb2x1bW5hIGxsYW1hZGEgbGl0ZXJhbG1lbnRlIFwiUmVzdWx0YWRvXCIg4oCUIHNlIG11ZXN0cmEgY29tbyBuw7ptZXJvIGdyYW5kZSBlbiB2ZXogZGVcclxuICAgIC8vIGNvbW8gdGFibGEgZGUgdW5hIGNlbGRhLlxyXG4gICAgZXNDb250ZW8ocmVzdWx0YWRvOiBhbnlbXSk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiByZXN1bHRhZG8/Lmxlbmd0aCA9PT0gMSAmJiBPYmplY3Qua2V5cyhyZXN1bHRhZG9bMF0pLmxlbmd0aCA9PT0gMSAmJiAnUmVzdWx0YWRvJyBpbiByZXN1bHRhZG9bMF07XHJcbiAgICB9XHJcblxyXG4gICAgLy8gTGlzdGFkbyBjb24gdW5hIHNvbGEgY29sdW1uYSAoZWouIHVuYSBsaXN0YSBkZSBub21icmVzL2lkcykg4oCUIHNlIG11ZXN0cmEgY29tbyB0ZXh0byBzaW1wbGVcclxuICAgIC8vIGVuIHZleiBkZSB1bmEgdGFibGEgZGUgdW5hIHNvbGEgY29sdW1uYSByZXBldGlkYS5cclxuICAgIGVzTGlzdGFTaW1wbGUocmVzdWx0YWRvOiBhbnlbXSk6IGJvb2xlYW4ge1xyXG4gICAgICAgIHJldHVybiByZXN1bHRhZG8/Lmxlbmd0aCA+IDAgJiYgIXRoaXMuZXNDb250ZW8ocmVzdWx0YWRvKSAmJiB0aGlzLmNvbHVtbmFzRGUocmVzdWx0YWRvKS5sZW5ndGggPT09IDE7XHJcbiAgICB9XHJcblxyXG4gICAgdGV4dG9MaXN0YVNpbXBsZShyZXN1bHRhZG86IGFueVtdKTogc3RyaW5nIHtcclxuICAgICAgICBjb25zdCBjb2x1bW5hID0gdGhpcy5jb2x1bW5hc0RlKHJlc3VsdGFkbylbMF07XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdGFkby5tYXAoKGZpbGEpID0+IGZpbGFbY29sdW1uYV0pLmpvaW4oJywgJyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gLS0tIEFjY2lvbmVzIHNvYnJlIGxhIHRhYmxhIGRlIHJlc3VsdGFkb3MgKGFtcGxpYXIgLyBjb3BpYXIgLyBleHBvcnRhcikgLS0tXHJcblxyXG4gICAgYW1wbGlhcihyZXN1bHRhZG86IGFueVtdLCBkZXNjcmlwY2lvbj86IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMudGFibGFBbXBsaWFkYSA9IHJlc3VsdGFkbztcclxuICAgICAgICB0aGlzLmRlc2NyaXBjaW9uQW1wbGlhZGEgPSBkZXNjcmlwY2lvbiB8fCAnJztcclxuICAgIH1cclxuXHJcbiAgICBjZXJyYXJBbXBsaWFkYSgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnRhYmxhQW1wbGlhZGEgPSBudWxsO1xyXG4gICAgICAgIHRoaXMuZGVzY3JpcGNpb25BbXBsaWFkYSA9ICcnO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGNvcGlhcihyZXN1bHRhZG86IGFueVtdKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy50YWJsYUV4cG9ydC5jb3BpYXIocmVzdWx0YWRvKTtcclxuICAgICAgICAgICAgdGhpcy5jb3BpYWRvQXZpc28gPSB0cnVlO1xyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+ICh0aGlzLmNvcGlhZG9BdmlzbyA9IGZhbHNlKSwgMTgwMCk7XHJcbiAgICAgICAgfSBjYXRjaCB7XHJcbiAgICAgICAgICAgIC8vIENvcGlhciBwdWVkZSBmYWxsYXIgcG9yIHBlcm1pc29zIGRlbCBwb3J0YXBhcGVsZXM7IHNlIGlnbm9yYSBlbiBzaWxlbmNpbyAoZWwgdXN1YXJpb1xyXG4gICAgICAgICAgICAvLyBhw7puIHB1ZWRlIGFtcGxpYXIgeSBleHBvcnRhcikuXHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGV4cG9ydGFyQ3N2KHJlc3VsdGFkbzogYW55W10pOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnRhYmxhRXhwb3J0LmRlc2NhcmdhckNzdihyZXN1bHRhZG8sIHRoaXMubm9tYnJlQXJjaGl2bygpKTtcclxuICAgIH1cclxuXHJcbiAgICBleHBvcnRhclhsc3gocmVzdWx0YWRvOiBhbnlbXSk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMudGFibGFFeHBvcnQuZGVzY2FyZ2FyWGxzeChyZXN1bHRhZG8sIHRoaXMubm9tYnJlQXJjaGl2bygpKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIG5vbWJyZUFyY2hpdm8oKTogc3RyaW5nIHtcclxuICAgICAgICBjb25zdCBhaG9yYSA9IG5ldyBEYXRlKCk7XHJcbiAgICAgICAgY29uc3QgZG9zID0gKG46IG51bWJlcikgPT4gU3RyaW5nKG4pLnBhZFN0YXJ0KDIsICcwJyk7XHJcbiAgICAgICAgcmV0dXJuIChcclxuICAgICAgICAgICAgJ2FzaXN0ZW50ZS1kYXRvcy0nICtcclxuICAgICAgICAgICAgYWhvcmEuZ2V0RnVsbFllYXIoKSArXHJcbiAgICAgICAgICAgIGRvcyhhaG9yYS5nZXRNb250aCgpICsgMSkgK1xyXG4gICAgICAgICAgICBkb3MoYWhvcmEuZ2V0RGF0ZSgpKSArXHJcbiAgICAgICAgICAgICctJyArXHJcbiAgICAgICAgICAgIGRvcyhhaG9yYS5nZXRIb3VycygpKSArXHJcbiAgICAgICAgICAgIGRvcyhhaG9yYS5nZXRNaW51dGVzKCkpXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxufVxyXG4iXX0=
268
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNpc3RlbnRlLWRhdG9zLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL3dtLW1lbnUvIiwic291cmNlcyI6WyJsaWIvd20tbWVudS9hc2lzdGVudGUtZGF0b3MvYXNpc3RlbnRlLWRhdG9zLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBYyxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDOUYsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDeEUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDekUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFnQjVEO0lBd0RJLGlDQUNZLHdCQUFrRCxFQUNsRCxpQkFBMkMsRUFDM0MsV0FBK0I7UUFGL0IsNkJBQXdCLEdBQXhCLHdCQUF3QixDQUEwQjtRQUNsRCxzQkFBaUIsR0FBakIsaUJBQWlCLENBQTBCO1FBQzNDLGdCQUFXLEdBQVgsV0FBVyxDQUFvQjtRQXhEM0MsMEZBQTBGO1FBQzFGLHFGQUFxRjtRQUM1RSxZQUFPLEdBQUcsS0FBSyxDQUFDO1FBU3pCLHlEQUF5RDtRQUNoRCxXQUFNLEdBQUcsT0FBTyxDQUFDO1FBRWhCLGlCQUFZLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUUzQyxhQUFRLEdBQTRCLEVBQUUsQ0FBQztRQUN2QyxhQUFRLEdBQUcsRUFBRSxDQUFDO1FBQ3JCLDhGQUE4RjtRQUM5RixrR0FBa0c7UUFDM0Ysc0JBQWlCLEdBQUcsS0FBSyxDQUFDO1FBQzFCLGdCQUFXLEdBQUcsS0FBSyxDQUFDO1FBQzNCLG1GQUFtRjtRQUNuRiwyQ0FBMkM7UUFDcEMsMEJBQXFCLEdBQXNCLFFBQVEsQ0FBQztRQUMzRCxzRkFBc0Y7UUFDL0UsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUUxQiw2RkFB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O0lBR2hCO1FBQVIsS0FBSyxFQUFFOytEQUlQO0lBR1E7UUFBUixLQUFLLEVBQUU7MkRBQWtCO0lBRWhCO1FBQVQsTUFBTSxFQUFFO2lFQUF5QztJQWpCekMsdUJBQXVCO1FBTG5DLFNBQVMsQ0FBQztZQUNQLFFBQVEsRUFBRSxvQkFBb0I7WUFDOUIsMDZZQUErQzs7U0FFbEQsQ0FBQztPQUNXLHVCQUF1QixDQWlQbkM7SUFBRCw4QkFBQztDQUFBLEFBalBELElBaVBDO1NBalBZLHVCQUF1QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgUmVjb25vY2ltaWVudG9Wb3pTZXJ2aWNlIH0gZnJvbSAnLi9yZWNvbm9jaW1pZW50by12b3ouc2VydmljZSc7XHJcbmltcG9ydCB7IEFzaXN0ZW50ZURhdG9zQXBpU2VydmljZSB9IGZyb20gJy4vYXNpc3RlbnRlLWRhdG9zLWFwaS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgVGFibGFFeHBvcnRTZXJ2aWNlIH0gZnJvbSAnLi90YWJsYS1leHBvcnQuc2VydmljZSc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIE1lbnNhamVBc2lzdGVudGVEYXRvcyB7XHJcbiAgICBkZVVzdWFyaW86IGJvb2xlYW47XHJcbiAgICB0ZXh0bz86IHN0cmluZztcclxuICAgIGRlc2NyaXBjaW9uPzogc3RyaW5nO1xyXG4gICAgcmVzdWx0YWRvPzogYW55W107XHJcbiAgICBwcm92ZWVkb3I/OiBzdHJpbmc7XHJcbiAgICBlc0Vycm9yPzogYm9vbGVhbjtcclxufVxyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ3dtLWFzaXN0ZW50ZS1kYXRvcycsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vYXNpc3RlbnRlLWRhdG9zLmNvbXBvbmVudC5odG1sJyxcclxuICAgIHN0eWxlVXJsczogWycuL2FzaXN0ZW50ZS1kYXRvcy5jb21wb25lbnQuc2NzcyddLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgQXNpc3RlbnRlRGF0b3NDb21wb25lbnQge1xyXG4gICAgQFZpZXdDaGlsZCgnbWVuc2FqZXNDb250YWluZXInKSBwcml2YXRlIG1lbnNhamVzQ29udGFpbmVyPzogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XHJcblxyXG4gICAgLy8gTGEgYXBlcnR1cmEvY2llcnJlIGRlbCBwYW5lbCBsYSBjb250cm9sYSBlbCBwYWRyZSAoZWwgbWVuw7opLiBFbCBwYW5lbCBzb2xvIHNlIHJlbmRlcml6YVxyXG4gICAgLy8gY3VhbmRvIGBhYmllcnRvYCBlcyB0cnVlIHkgYXZpc2EsIHbDrWEgYGNlcnJhckNoYW5nZWAsIGN1YW5kbyBlbCB1c3VhcmlvIHRvY2EgbGEgWC5cclxuICAgIEBJbnB1dCgpIGFiaWVydG8gPSBmYWxzZTtcclxuXHJcbiAgICAvLyBVUkwgZGVsIFBPU1QgZGUgY29uc3VsdGEuIFNlIHJlZmxlamEgZW4gZWwgYXBpIHNlcnZpY2UgKHByb3BpZWRhZCBgdXJsYCksIHF1ZSBlcyBkb25kZSBzZSB1c2EuXHJcbiAgICBASW5wdXQoKSBzZXQgdXJsQ29uc3VsdGFyKHZhbG9yOiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAodmFsb3IpIHtcclxuICAgICAgICAgICAgdGhpcy5hc2lzdGVudGVEYXRvc0FwaVNlcnZpY2UudXJsID0gdmFsb3I7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIElkaW9tYSBwYXJhIGVsIHJlY29ub2NpbWllbnRvIGRlIHZveiAoV2ViIFNwZWVjaCBBUEkpLlxyXG4gICAgQElucHV0KCkgaWRpb21hID0gJ2VzLUNPJztcclxuXHJcbiAgICBAT3V0cHV0KCkgY2VycmFyQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xyXG5cclxuICAgIHB1YmxpYyBtZW5zYWplczogTWVuc2FqZUFzaXN0ZW50ZURhdG9zW10gPSBbXTtcclxuICAgIHB1YmxpYyBib3JyYWRvciA9ICcnO1xyXG4gICAgLy8gQWx0ZXJuYSBlbCBhbHRvIGRlIGxhIGNhamEgZGVsIG1lbnNhamUgKGNvbXBhY3RhIOKGlCBleHBhbmRpZGEpLCBpZ3VhbCBxdWUgZWwgXCJwZWRpciBjYW1iaW9zXCJcclxuICAgIC8vIGRlbCBhc2lzdGVudGUgZGUgSUEgZGVsIGdlbmVyYWRvciBkZSBmb3JtdWxhcmlvcyAodmVyIGZpbGFzQm9ycmFkb3IgLyBvbkNsaWNrRXhwYW5kaXJCb3JyYWRvcikuXHJcbiAgICBwdWJsaWMgYm9ycmFkb3JFeHBhbmRpZG8gPSBmYWxzZTtcclxuICAgIHB1YmxpYyBjb25zdWx0YW5kbyA9IGZhbHNlO1xyXG4gICAgLy8gXCJHZW1pbmlcIiBvIFwiR3JvcVwiIOKAlCBtaXNtbyBzZWxlY3RvciBxdWUgZWwgYXNpc3RlbnRlIGRlIGdlbmVyYWNpw7NuIGRlIGZvcm11bGFyaW9zXHJcbiAgICAvLyAodmVyIFByb3ZlZWRvcklBU2VydmljaW8gZW4gZWwgYmFja2VuZCkuXHJcbiAgICBwdWJsaWMgcHJvdmVlZG9yU2VsZWNjaW9uYWRvOiAnR2VtaW5pJyB8ICdHcm9xJyA9ICdHZW1pbmknO1xyXG4gICAgLy8gRGljdGFkbyBwb3Igdm96IChXZWIgU3BlZWNoIEFQSSkg4oCUIHNpbiBzb3BvcnRlIGVuIEZpcmVmb3gsIGluY29uc2lzdGVudGUgZW4gU2FmYXJpLlxyXG4gICAgcHVibGljIGVzY3VjaGFuZG8gPSBmYWxzZTtcclxuXHJcbiAgICAvLyBMYXMgcHJlZ3VudGFzIHN1Z2VyaWRhcyBzZSBtdWVzdHJhbiBjb24gZWwgY2hhdCB2YWPDrW8uIFRyYXMgbGEgcHJpbWVyYSBwcmVndW50YSAoY3VhbmRvIHlhXHJcbiAgICAvLyBoYXkgbWVuc2FqZXMpIHF1ZWRhbiBwbGVnYWRhcyBlbiBlbCBib3TDs24gXCJTdWdlcmVuY2lhc1wiIHF1ZSBjb250cm9sYSBlc3RlIGZsYWcsIHBhcmEgcXVlIGVsXHJcbiAgICAvLyDDoXJlYSBkZSBjb252ZXJzYWNpw7NuIGdhbmUgZXNlIGVzcGFjaW87IGVsIHVzdWFyaW8gcHVlZGUgdm9sdmVyIGEgYWJyaXJsYXMuIEVzIHNvbG8gVUksIGlndWFsXHJcbiAgICAvLyBjb24gR2VtaW5pIHkgY29uIEdyb3EuXHJcbiAgICBwdWJsaWMgc3VnZXJlbmNpYXNBYmllcnRhcyA9IGZhbHNlO1xyXG5cclxuICAgIC8vIFRhYmxhIGFiaWVydGEgZW4gZWwgbW9kYWwgXCJhbXBsaWFyXCIgKG51bGwgPSBtb2RhbCBjZXJyYWRvKS4gRWwgcGFuZWwgZGVsIGNoYXQgZXMgYW5nb3N0byB5XHJcbiAgICAvLyByZWNvcnRhIGxhcyBjb2x1bW5hczsgZWwgbW9kYWwgbXVlc3RyYSBsYSBtaXNtYSB0YWJsYSBhIHRvZG8gZWwgYW5jaG8gZGUgbGEgcGFudGFsbGEuXHJcbiAgICBwdWJsaWMgdGFibGFBbXBsaWFkYTogYW55W10gfCBudWxsID0gbnVsbDtcclxuICAgIHB1YmxpYyBkZXNjcmlwY2lvbkFtcGxpYWRhID0gJyc7XHJcbiAgICAvLyBBdmlzbyBlZsOtbWVybyBcIlRhYmxhIGNvcGlhZGFcIiB0cmFzIGNvcGlhciBhbCBwb3J0YXBhcGVsZXMuXHJcbiAgICBwdWJsaWMgY29waWFkb0F2aXNvID0gZmFsc2U7XHJcblxyXG4gICAgLy8gU3VnZXJlbmNpYXMgRklKQVM6IHByZWd1bnRhcyB5YSB2ZXJpZmljYWRhcyBjb21vIHJlc3BvbmRpYmxlcyAod2hpdGVsaXN0ICsgY29udHJhdG8gZGUgbGEgSUEg4oCUXHJcbiAgICAvLyB2ZXIgQ2hhdENvbnN1bHRhV2hpdGVsaXN0U2VydmljaW8vQ2hhdENvbnN1bHRhUHJvbXB0U2VydmljaW8gZW4gZWwgYmFja2VuZCkuIFNvbiBlbCBlc3RhZG9cclxuICAgIC8vIGluaWNpYWwgKGNoYXQgdmFjw61vKSB5IGVsIGZhbGxiYWNrIGN1YW5kbyBlbCBiYWNrZW5kIG5vIGRldnVlbHZlIHN1Z2VyZW5jaWFzIGNvbnRleHR1YWxlcy5cclxuICAgIHB1YmxpYyByZWFkb25seSBjaGlwc0Zpam9zOiBzdHJpbmdbXSA9IFtcclxuICAgICAgICAnwr9DdcOhbnRvcyBmb3JtdWxhcmlvcyBzZSBkaWxpZ2VuY2lhcm9uIGhveT8nLFxyXG4gICAgICAgICfCv0N1w6FudG9zIGZvcm11bGFyaW9zIHNlIGRpbGlnZW5jaWFyb24gZXN0YSBzZW1hbmE/JyxcclxuICAgICAgICAnTXXDqXN0cmFtZSBsb3Mgw7psdGltb3MgMTAgZm9ybXVsYXJpb3MgZGlsaWdlbmNpYWRvcycsXHJcbiAgICBdO1xyXG4gICAgLy8gU3VnZXJlbmNpYXMgcXVlIHNlIG11ZXN0cmFuIGFob3JhOiBhcnJhbmNhbiBlbiBsYXMgZmlqYXMgeSwgdHJhcyBjYWRhIHJlc3B1ZXN0YSwgc2UgcmVlbXBsYXphblxyXG4gICAgLy8gcG9yIGxhcyBjb250ZXh0dWFsZXMgcXVlIGRldnVlbHZlIGVsIGJhY2tlbmQgKFN1Z2VyZW5jaWFzKTsgc2kgbm8gdmllbmVuLCB2dWVsdmVuIGEgbGFzIGZpamFzLlxyXG4gICAgcHVibGljIGNoaXBzU3VnZXJpZG9zOiBzdHJpbmdbXSA9IFsuLi50aGlzLmNoaXBzRmlqb3NdO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIHByaXZhdGUgYXNpc3RlbnRlRGF0b3NBcGlTZXJ2aWNlOiBBc2lzdGVudGVEYXRvc0FwaVNlcnZpY2UsXHJcbiAgICAgICAgcHJpdmF0ZSByZWNvbm9jaW1pZW50b1ZvejogUmVjb25vY2ltaWVudG9Wb3pTZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgdGFibGFFeHBvcnQ6IFRhYmxhRXhwb3J0U2VydmljZVxyXG4gICAgKSB7fVxyXG5cclxuICAgIC8vIEVsIHBhZHJlIGFicmUvY2llcnJhIGVsIHBhbmVsOyBhcXXDrSBzb2xvIHNlIGF2aXNhIHF1ZSBlbCB1c3VhcmlvIHBpZGnDsyBjZXJyYXJsbyAoYm90w7NuIFgpLlxyXG4gICAgY2VycmFyKCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuY2VycmFyQ2hhbmdlLmVtaXQoKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBDYWphIGRlbCBtZW5zYWplIGNvbXBhY3RhICgxIGZpbGEsIGNvbW8gZXJhIGVsIGNoYXQgb3JpZ2luYWxtZW50ZSkg4oaUIGV4cGFuZGlkYSAoNiBmaWxhcykuXHJcbiAgICAvLyBFbCBib3TDs24gZGUgZXhwYW5kaXIgZXMgZWwgbWlzbW8gcGF0csOzbiBkZWwgXCJwZWRpciBjYW1iaW9zXCIgZGVsIGdlbmVyYWRvci5cclxuICAgIGdldCBmaWxhc0JvcnJhZG9yKCk6IG51bWJlciB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuYm9ycmFkb3JFeHBhbmRpZG8gPyA2IDogMTtcclxuICAgIH1cclxuXHJcbiAgICBvbkNsaWNrRXhwYW5kaXJCb3JyYWRvcigpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmJvcnJhZG9yRXhwYW5kaWRvID0gIXRoaXMuYm9ycmFkb3JFeHBhbmRpZG87XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IG1pY0Rpc3BvbmlibGUoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVjb25vY2ltaWVudG9Wb3ouZXN0YVNvcG9ydGFkbygpO1xyXG4gICAgfVxyXG5cclxuICAgIG9uQ2xpY2tNaWNyb2Zvbm8oKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuZXNjdWNoYW5kbykge1xyXG4gICAgICAgICAgICB0aGlzLnJlY29ub2NpbWllbnRvVm96LmRldGVuZXIoKTtcclxuICAgICAgICAgICAgdGhpcy5lc2N1Y2hhbmRvID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghdGhpcy5yZWNvbm9jaW1pZW50b1Zvei5lc3RhU29wb3J0YWRvKCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gRWwgcmVzdWx0YWRvIGRlbCByZWNvbm9jaW1pZW50byBubyBpbmNsdXllIGxvIHF1ZSB5YSBlc3RhYmEgZXNjcml0byDigJQgc2UgZ3VhcmRhIGFudGVzIGRlXHJcbiAgICAgICAgLy8gZW1wZXphciB5IHNlIGFudGVwb25lIGVuIGNhZGEgYWN0dWFsaXphY2nDs24gKHF1ZSBsbGVnYSBjb24gbGEgdHJhbnNjcmlwY2nDs24gQ09NUExFVEEgZGVcclxuICAgICAgICAvLyBlc3RhIHNlc2nDs24gZGUgZXNjdWNoYSwgbm8gdW4gaW5jcmVtZW50bykgcGFyYSBubyBwZXJkZXIgbG8gcXVlIHlhIGhhYsOtYSBlbiBlbCBjYW1wby5cclxuICAgICAgICBjb25zdCB0ZXh0b1ByZXZpbyA9IHRoaXMuYm9ycmFkb3IudHJpbSgpO1xyXG4gICAgICAgIHRoaXMuZXNjdWNoYW5kbyA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5yZWNvbm9jaW1pZW50b1Zvei5pbmljaWFyKFxyXG4gICAgICAgICAgICB0aGlzLmlkaW9tYSxcclxuICAgICAgICAgICAgKHRleHRvKSA9PiAodGhpcy5ib3JyYWRvciA9IHRleHRvUHJldmlvID8gYCR7dGV4dG9QcmV2aW99ICR7dGV4dG99YCA6IHRleHRvKSxcclxuICAgICAgICAgICAgKCkgPT4gKHRoaXMuZXNjdWNoYW5kbyA9IGZhbHNlKVxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgb25DbGlja0Vudmlhcih0ZXh0b1ByZXNldD86IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IHByZWd1bnRhID0gKHRleHRvUHJlc2V0ID8/IHRoaXMuYm9ycmFkb3IpLnRyaW0oKTtcclxuICAgICAgICBpZiAoIXByZWd1bnRhIHx8IHRoaXMuY29uc3VsdGFuZG8pIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5tZW5zYWplcy5wdXNoKHsgZGVVc3VhcmlvOiB0cnVlLCB0ZXh0bzogcHJlZ3VudGEgfSk7XHJcbiAgICAgICAgdGhpcy5ib3JyYWRvciA9ICcnO1xyXG5cclxuICAgICAgICAvLyBTaW4gdXJsIGRlIGNvbnN1bHRhIG5vIHNlIGhhY2UgbGEgcGV0aWNpw7NuOiBlbCB1c3VhcmlvIHZlIGVsIG1pc21vIGVycm9yIGdlbsOpcmljbyBxdWVcclxuICAgICAgICAvLyBjdWFuZG8gbGEgQVBJIGZhbGxhLlxyXG4gICAgICAgIGlmICghdGhpcy5hc2lzdGVudGVEYXRvc0FwaVNlcnZpY2UudXJsKSB7XHJcbiAgICAgICAgICAgIHRoaXMubWVuc2FqZXMucHVzaCh7XHJcbiAgICAgICAgICAgICAgICBkZVVzdWFyaW86IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgdGV4dG86ICdObyBzZSBwdWRvIHByb2Nlc2FyIGxhIGNvbnN1bHRhLicsXHJcbiAgICAgICAgICAgICAgICBlc0Vycm9yOiB0cnVlLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgdGhpcy5zY3JvbGxBbEZpbmFsKCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuY29uc3VsdGFuZG8gPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuc2Nyb2xsQWxGaW5hbCgpO1xyXG5cclxuICAgICAgICB0aGlzLmFzaXN0ZW50ZURhdG9zQXBpU2VydmljZS5jb25zdWx0YXIocHJlZ3VudGEsIHRoaXMucHJvdmVlZG9yU2VsZWNjaW9uYWRvKS5zdWJzY3JpYmUoe1xyXG4gICAgICAgICAgICAvLyBFbCB0aXBvIChSZXNwdWVzdGFBc2lzdGVudGVEYXRvcykgc2UgaW5maWVyZSBkZWwgT2JzZXJ2YWJsZTogaW1wb3J0YXIgbGEgaW50ZXJmYXpcclxuICAgICAgICAgICAgLy8gZGVqYWJhIHVuIGltcG9ydCBhIHVuIHPDrW1ib2xvIGluZXhpc3RlbnRlIGVuIGVsIEpTIGRlIGxhIGxpYnJlcsOtYSAoYXZpc28gZGUgcm9sbHVwKS5cclxuICAgICAgICAgICAgbmV4dDogKHJlc3B1ZXN0YSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jb25zdWx0YW5kbyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5tZW5zYWplcy5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgICBkZVVzdWFyaW86IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgICAgIGRlc2NyaXBjaW9uOiByZXNwdWVzdGEuRGVzY3JpcGNpb24sXHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0YWRvOiByZXNwdWVzdGEuUmVzdWx0YWRvID8/IFtdLFxyXG4gICAgICAgICAgICAgICAgICAgIHByb3ZlZWRvcjogcmVzcHVlc3RhLlByb3ZlZWRvcixcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5hY3R1YWxpemFyU3VnZXJlbmNpYXMocmVzcHVlc3RhLlN1Z2VyZW5jaWFzKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuc2Nyb2xsQWxGaW5hbCgpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBlcnJvcjogKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnN1bHRhbmRvID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm1lbnNhamVzLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgIGRlVXN1YXJpbzogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgdGV4dG86IGVycm9yPy5NZW5zYWplIHx8ICdObyBzZSBwdWRvIHByb2Nlc2FyIGxhIGNvbnN1bHRhLicsXHJcbiAgICAgICAgICAgICAgICAgICAgZXNFcnJvcjogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zY3JvbGxBbEZpbmFsKCk7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gVHJhcyBjYWRhIHJlc3B1ZXN0YSwgZWwgYmFja2VuZCBwdWVkZSBkZXZvbHZlciBzdWdlcmVuY2lhcyBkZSBzZWd1aW1pZW50byBhY290YWRhcyBhbCByb2wuIFNpXHJcbiAgICAvLyBsbGVnYW4gYWwgbWVub3MgMiwgcmVlbXBsYXphbiBhIGxhcyBxdWUgc2UgbXVlc3RyYW47IHNpIG5vLCBzZSB2dWVsdmUgYSBsYXMgZmlqYXMuIEVsIGNoYXQgdmFjw61vXHJcbiAgICAvLyBjb25zZXJ2YSBsYXMgZmlqYXM6IGVzdGUgbcOpdG9kbyBzb2xvIHNlIGxsYW1hIGFsIHJlY2liaXIgdW5hIHJlc3B1ZXN0YS5cclxuICAgIHByaXZhdGUgYWN0dWFsaXphclN1Z2VyZW5jaWFzKHN1Z2VyZW5jaWFzPzogc3RyaW5nW10pOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmNoaXBzU3VnZXJpZG9zID0gc3VnZXJlbmNpYXMgJiYgc3VnZXJlbmNpYXMubGVuZ3RoID49IDJcclxuICAgICAgICAgICAgPyBzdWdlcmVuY2lhc1xyXG4gICAgICAgICAgICA6IFsuLi50aGlzLmNoaXBzRmlqb3NdO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEVsIG51ZXZvIG1lbnNhamUgcmVjacOpbiBzZSByZWZsZWphIGVuIGVsIERPTSBkZXNwdcOpcyBkZWwgc2lndWllbnRlIGNpY2xvIGRlIGRldGVjY2nDs24gZGVcclxuICAgIC8vIGNhbWJpb3Mg4oCUIHBvciBlc28gZWwgc2Nyb2xsVG9wIHNlIGFqdXN0YSBlbiB1biBzZXRUaW1lb3V0KDApLCBubyBpbm1lZGlhdGFtZW50ZSBkZXNwdcOpcyBkZWxcclxuICAgIC8vIHB1c2gsIHBhcmEgcXVlIHNjcm9sbEhlaWdodCB5YSBpbmNsdXlhIGVsIG1lbnNhamUgYWdyZWdhZG8uXHJcbiAgICBwcml2YXRlIHNjcm9sbEFsRmluYWwoKTogdm9pZCB7XHJcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRvID0gdGhpcy5tZW5zYWplc0NvbnRhaW5lcj8ubmF0aXZlRWxlbWVudDtcclxuICAgICAgICAgICAgaWYgKGVsZW1lbnRvKSB7XHJcbiAgICAgICAgICAgICAgICBlbGVtZW50by5zY3JvbGxUb3AgPSBlbGVtZW50by5zY3JvbGxIZWlnaHQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBjb2x1bW5hc0RlKHJlc3VsdGFkbzogYW55W10pOiBzdHJpbmdbXSB7XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdGFkby5sZW5ndGggPyBPYmplY3Qua2V5cyhyZXN1bHRhZG9bMF0pIDogW107XHJcbiAgICB9XHJcblxyXG4gICAgLy8gRWwgYmFja2VuZCBkZXZ1ZWx2ZSB1biBjb250ZW8gKENoYXRDb25zdWx0YUlBU2VydmljaW8uRWplY3V0YXJDb250ZW8pIGNvbW8gdW5hIHNvbGEgZmlsYSBjb25cclxuICAgIC8vIHVuYSBzb2xhIGNvbHVtbmEgbGxhbWFkYSBsaXRlcmFsbWVudGUgXCJSZXN1bHRhZG9cIiDigJQgc2UgbXVlc3RyYSBjb21vIG7Dum1lcm8gZ3JhbmRlIGVuIHZleiBkZVxyXG4gICAgLy8gY29tbyB0YWJsYSBkZSB1bmEgY2VsZGEuXHJcbiAgICBlc0NvbnRlbyhyZXN1bHRhZG86IGFueVtdKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdGFkbz8ubGVuZ3RoID09PSAxICYmIE9iamVjdC5rZXlzKHJlc3VsdGFkb1swXSkubGVuZ3RoID09PSAxICYmICdSZXN1bHRhZG8nIGluIHJlc3VsdGFkb1swXTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBMaXN0YWRvIGNvbiB1bmEgc29sYSBjb2x1bW5hIChlai4gdW5hIGxpc3RhIGRlIG5vbWJyZXMvaWRzKSDigJQgc2UgbXVlc3RyYSBjb21vIHRleHRvIHNpbXBsZVxyXG4gICAgLy8gZW4gdmV6IGRlIHVuYSB0YWJsYSBkZSB1bmEgc29sYSBjb2x1bW5hIHJlcGV0aWRhLlxyXG4gICAgZXNMaXN0YVNpbXBsZShyZXN1bHRhZG86IGFueVtdKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdGFkbz8ubGVuZ3RoID4gMCAmJiAhdGhpcy5lc0NvbnRlbyhyZXN1bHRhZG8pICYmIHRoaXMuY29sdW1uYXNEZShyZXN1bHRhZG8pLmxlbmd0aCA9PT0gMTtcclxuICAgIH1cclxuXHJcbiAgICB0ZXh0b0xpc3RhU2ltcGxlKHJlc3VsdGFkbzogYW55W10pOiBzdHJpbmcge1xyXG4gICAgICAgIGNvbnN0IGNvbHVtbmEgPSB0aGlzLmNvbHVtbmFzRGUocmVzdWx0YWRvKVswXTtcclxuICAgICAgICByZXR1cm4gcmVzdWx0YWRvLm1hcCgoZmlsYSkgPT4gZmlsYVtjb2x1bW5hXSkuam9pbignLCAnKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyAtLS0gQWNjaW9uZXMgc29icmUgbGEgdGFibGEgZGUgcmVzdWx0YWRvcyAoYW1wbGlhciAvIGNvcGlhciAvIGV4cG9ydGFyKSAtLS1cclxuXHJcbiAgICBhbXBsaWFyKHJlc3VsdGFkbzogYW55W10sIGRlc2NyaXBjaW9uPzogc3RyaW5nKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy50YWJsYUFtcGxpYWRhID0gcmVzdWx0YWRvO1xyXG4gICAgICAgIHRoaXMuZGVzY3JpcGNpb25BbXBsaWFkYSA9IGRlc2NyaXBjaW9uIHx8ICcnO1xyXG4gICAgfVxyXG5cclxuICAgIGNlcnJhckFtcGxpYWRhKCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMudGFibGFBbXBsaWFkYSA9IG51bGw7XHJcbiAgICAgICAgdGhpcy5kZXNjcmlwY2lvbkFtcGxpYWRhID0gJyc7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgY29waWFyKHJlc3VsdGFkbzogYW55W10pOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnRhYmxhRXhwb3J0LmNvcGlhcihyZXN1bHRhZG8pO1xyXG4gICAgICAgICAgICB0aGlzLmNvcGlhZG9BdmlzbyA9IHRydWU7XHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gKHRoaXMuY29waWFkb0F2aXNvID0gZmFsc2UpLCAxODAwKTtcclxuICAgICAgICB9IGNhdGNoIHtcclxuICAgICAgICAgICAgLy8gQ29waWFyIHB1ZWRlIGZhbGxhciBwb3IgcGVybWlzb3MgZGVsIHBvcnRhcGFwZWxlczsgc2UgaWdub3JhIGVuIHNpbGVuY2lvIChlbCB1c3VhcmlvXHJcbiAgICAgICAgICAgIC8vIGHDum4gcHVlZGUgYW1wbGlhciB5IGV4cG9ydGFyKS5cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZXhwb3J0YXJDc3YocmVzdWx0YWRvOiBhbnlbXSk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMudGFibGFFeHBvcnQuZGVzY2FyZ2FyQ3N2KHJlc3VsdGFkbywgdGhpcy5ub21icmVBcmNoaXZvKCkpO1xyXG4gICAgfVxyXG5cclxuICAgIGV4cG9ydGFyWGxzeChyZXN1bHRhZG86IGFueVtdKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy50YWJsYUV4cG9ydC5kZXNjYXJnYXJYbHN4KHJlc3VsdGFkbywgdGhpcy5ub21icmVBcmNoaXZvKCkpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgbm9tYnJlQXJjaGl2bygpOiBzdHJpbmcge1xyXG4gICAgICAgIGNvbnN0IGFob3JhID0gbmV3IERhdGUoKTtcclxuICAgICAgICBjb25zdCBkb3MgPSAobjogbnVtYmVyKSA9PiBTdHJpbmcobikucGFkU3RhcnQoMiwgJzAnKTtcclxuICAgICAgICByZXR1cm4gKFxyXG4gICAgICAgICAgICAnYXNpc3RlbnRlLWRhdG9zLScgK1xyXG4gICAgICAgICAgICBhaG9yYS5nZXRGdWxsWWVhcigpICtcclxuICAgICAgICAgICAgZG9zKGFob3JhLmdldE1vbnRoKCkgKyAxKSArXHJcbiAgICAgICAgICAgIGRvcyhhaG9yYS5nZXREYXRlKCkpICtcclxuICAgICAgICAgICAgJy0nICtcclxuICAgICAgICAgICAgZG9zKGFob3JhLmdldEhvdXJzKCkpICtcclxuICAgICAgICAgICAgZG9zKGFob3JhLmdldE1pbnV0ZXMoKSlcclxuICAgICAgICApO1xyXG4gICAgfVxyXG59XHJcbiJdfQ==
@@ -727,20 +727,28 @@ let AsistenteDatosComponent = class AsistenteDatosComponent {
727
727
  this.proveedorSeleccionado = 'Gemini';
728
728
  // Dictado por voz (Web Speech API) — sin soporte en Firefox, inconsistente en Safari.
729
729
  this.escuchando = false;
730
+ // Las preguntas sugeridas se muestran con el chat vacío. Tras la primera pregunta (cuando ya
731
+ // hay mensajes) quedan plegadas en el botón "Sugerencias" que controla este flag, para que el
732
+ // área de conversación gane ese espacio; el usuario puede volver a abrirlas. Es solo UI, igual
733
+ // con Gemini y con Groq.
734
+ this.sugerenciasAbiertas = false;
730
735
  // Tabla abierta en el modal "ampliar" (null = modal cerrado). El panel del chat es angosto y
731
736
  // recorta las columnas; el modal muestra la misma tabla a todo el ancho de la pantalla.
732
737
  this.tablaAmpliada = null;
733
738
  this.descripcionAmpliada = '';
734
739
  // Aviso efímero "Tabla copiada" tras copiar al portapapeles.
735
740
  this.copiadoAviso = false;
736
- // Preguntas ya verificadas como respondibles hoy (whitelist + contrato de la IA — ver
737
- // ChatConsultaWhitelistServicio/ChatConsultaPromptServicio en el backend), mostradas como chips
738
- // de sugerencia en el estado vacío del chat.
739
- this.chipsSugeridos = [
741
+ // Sugerencias FIJAS: preguntas ya verificadas como respondibles (whitelist + contrato de la IA —
742
+ // ver ChatConsultaWhitelistServicio/ChatConsultaPromptServicio en el backend). Son el estado
743
+ // inicial (chat vacío) y el fallback cuando el backend no devuelve sugerencias contextuales.
744
+ this.chipsFijos = [
740
745
  '¿Cuántos formularios se diligenciaron hoy?',
741
746
  '¿Cuántos formularios se diligenciaron esta semana?',
742
747
  'Muéstrame los últimos 10 formularios diligenciados',
743
748
  ];
749
+ // Sugerencias que se muestran ahora: arrancan en las fijas y, tras cada respuesta, se reemplazan
750
+ // por las contextuales que devuelve el backend (Sugerencias); si no vienen, vuelven a las fijas.
751
+ this.chipsSugeridos = [...this.chipsFijos];
744
752
  }
745
753
  // URL del POST de consulta. Se refleja en el api service (propiedad `url`), que es donde se usa.
746
754
  set urlConsultar(valor) {
@@ -811,6 +819,7 @@ let AsistenteDatosComponent = class AsistenteDatosComponent {
811
819
  resultado: (_a = respuesta.Resultado, (_a !== null && _a !== void 0 ? _a : [])),
812
820
  proveedor: respuesta.Proveedor,
813
821
  });
822
+ this.actualizarSugerencias(respuesta.Sugerencias);
814
823
  this.scrollAlFinal();
815
824
  },
816
825
  error: (error) => {
@@ -825,6 +834,14 @@ let AsistenteDatosComponent = class AsistenteDatosComponent {
825
834
  },
826
835
  });
827
836
  }
837
+ // Tras cada respuesta, el backend puede devolver sugerencias de seguimiento acotadas al rol. Si
838
+ // llegan al menos 2, reemplazan a las que se muestran; si no, se vuelve a las fijas. El chat vacío
839
+ // conserva las fijas: este método solo se llama al recibir una respuesta.
840
+ actualizarSugerencias(sugerencias) {
841
+ this.chipsSugeridos = sugerencias && sugerencias.length >= 2
842
+ ? sugerencias
843
+ : [...this.chipsFijos];
844
+ }
828
845
  // El nuevo mensaje recién se refleja en el DOM después del siguiente ciclo de detección de
829
846
  // cambios — por eso el scrollTop se ajusta en un setTimeout(0), no inmediatamente después del
830
847
  // push, para que scrollHeight ya incluya el mensaje agregado.
@@ -920,8 +937,8 @@ __decorate([
920
937
  AsistenteDatosComponent = __decorate([
921
938
  Component({
922
939
  selector: 'wm-asistente-datos',
923
- template: "<!-- Panel (abierto) -->\r\n<div class=\"chat-ia-panel\" *ngIf=\"abierto\">\r\n <div class=\"chat-ia-header\">\r\n <div class=\"chat-ia-header-info\">\r\n <div class=\"chat-ia-header-icono\">\r\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#fff\" stroke-width=\"1.8\">\r\n <path d=\"M4 5h16v10H9l-4 4V15H4z\"></path>\r\n </svg>\r\n </div>\r\n <div>\r\n <div class=\"chat-ia-titulo\">Preg\u00FAntale a tus Datos</div>\r\n <div class=\"chat-ia-subtitulo\">Consulta tus reportes en lenguaje natural</div>\r\n </div>\r\n </div>\r\n <div class=\"chat-ia-cerrar\" (click)=\"cerrar()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" stroke=\"#fff\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\">\r\n <path d=\"M6 6l12 12M18 6L6 18\"></path>\r\n </svg>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chat-ia-mensajes\" #mensajesContainer>\r\n <div class=\"chat-ia-bienvenida-texto\">Hola, soy tu asistente de datos de Snap Forms. Preg\u00FAntame lo que quieras saber sobre tu operaci\u00F3n.</div>\r\n\r\n <div class=\"chat-ia-mensaje\" *ngFor=\"let mensaje of mensajes\" [class.chat-ia-mensaje-usuario]=\"mensaje.deUsuario\">\r\n <div class=\"chat-ia-burbuja\" [class.chat-ia-burbuja-error]=\"mensaje.esError\">\r\n <span *ngIf=\"mensaje.texto\">{{ mensaje.texto }}</span>\r\n\r\n <ng-container *ngIf=\"mensaje.resultado\">\r\n <div class=\"chat-ia-descripcion\" *ngIf=\"mensaje.descripcion\">{{ mensaje.descripcion }}</div>\r\n\r\n <div class=\"chat-ia-sin-resultados\" *ngIf=\"mensaje.resultado.length === 0\">La consulta no encontr\u00F3 resultados.</div>\r\n\r\n <div class=\"chat-ia-stat\" *ngIf=\"esConteo(mensaje.resultado)\">\r\n <div class=\"chat-ia-stat-valor\">{{ mensaje.resultado[0].Resultado | number }}</div>\r\n </div>\r\n\r\n <div class=\"chat-ia-lista-simple\" *ngIf=\"esListaSimple(mensaje.resultado)\">{{ textoListaSimple(mensaje.resultado) }}</div>\r\n\r\n <div class=\"chat-ia-tabla-bloque\" *ngIf=\"mensaje.resultado.length > 0 && !esConteo(mensaje.resultado) && !esListaSimple(mensaje.resultado)\">\r\n <div class=\"chat-ia-tabla-acciones\">\r\n <button type=\"button\" class=\"chat-ia-accion\" matTooltip=\"Ampliar\"\r\n (click)=\"ampliar(mensaje.resultado, mensaje.descripcion)\">\r\n <mat-icon>open_in_full</mat-icon>\r\n </button>\r\n <button type=\"button\" class=\"chat-ia-accion\" matTooltip=\"Copiar\"\r\n (click)=\"copiar(mensaje.resultado)\">\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n <button type=\"button\" class=\"chat-ia-accion\" matTooltip=\"Exportar\"\r\n [matMenuTriggerFor]=\"menuExport\">\r\n <mat-icon>download</mat-icon>\r\n </button>\r\n <mat-menu #menuExport=\"matMenu\" class=\"menu-export-chat-ia\">\r\n <button mat-menu-item type=\"button\" (click)=\"exportarCsv(mensaje.resultado)\">CSV (.csv)</button>\r\n <button mat-menu-item type=\"button\" (click)=\"exportarXlsx(mensaje.resultado)\">Excel (.xlsx)</button>\r\n </mat-menu>\r\n </div>\r\n <div class=\"chat-ia-tabla-resultado\">\r\n <table mat-table [dataSource]=\"mensaje.resultado\">\r\n <ng-container *ngFor=\"let columna of columnasDe(mensaje.resultado)\" [matColumnDef]=\"columna\">\r\n <th mat-header-cell *matHeaderCellDef>{{ columna }}</th>\r\n <td mat-cell *matCellDef=\"let fila\">{{ fila[columna] }}</td>\r\n </ng-container>\r\n <tr mat-header-row *matHeaderRowDef=\"columnasDe(mensaje.resultado)\"></tr>\r\n <tr mat-row *matRowDef=\"let fila; columns: columnasDe(mensaje.resultado);\"></tr>\r\n </table>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chat-ia-pensando\" *ngIf=\"consultando\">\r\n <span class=\"chat-ia-dot\"></span><span class=\"chat-ia-dot\"></span><span class=\"chat-ia-dot\"></span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chips-chat-ia\">\r\n <span class=\"chip-chat-ia\" *ngFor=\"let chip of chipsSugeridos\"\r\n (click)=\"onClickEnviar(chip)\">{{ chip }}</span>\r\n </div>\r\n\r\n <div class=\"chat-ia-entrada\">\r\n <div class=\"chat-ia-caja-entrada\">\r\n <mat-icon fontSet=\"wm-menu-iconos\" class=\"chat-ia-expandir\" (click)=\"onClickExpandirBorrador()\">{{ borradorExpandido ? 'close_fullscreen' : 'open_in_full' }}</mat-icon>\r\n <textarea [rows]=\"filasBorrador\" [(ngModel)]=\"borrador\" (keydown.enter)=\"$event.preventDefault(); onClickEnviar()\"\r\n [class.chat-ia-textarea-expandido]=\"borradorExpandido\"\r\n placeholder=\"Escribe tu pregunta...\"></textarea>\r\n <div class=\"chat-ia-pie-entrada\">\r\n <button class=\"chat-ia-selector-modelo\" [matMenuTriggerFor]=\"menuModeloChatIA\" type=\"button\">\r\n <span *ngIf=\"proveedorSeleccionado === 'Gemini'\">Gemini</span>\r\n <span *ngIf=\"proveedorSeleccionado === 'Groq'\">Groq</span>\r\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M6 9l6 6 6-6\"></path>\r\n </svg>\r\n </button>\r\n <button class=\"chat-ia-microfono\" [class.chat-ia-microfono-activo]=\"escuchando\" *ngIf=\"micDisponible\"\r\n (click)=\"onClickMicrofono()\" type=\"button\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\"></path>\r\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"></path>\r\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"></line>\r\n </svg>\r\n </button>\r\n <button class=\"chat-ia-enviar\" [disabled]=\"!borrador.trim() || consultando\" (click)=\"onClickEnviar()\" type=\"button\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M12 19V6\"></path>\r\n <path d=\"M5 13l7-7 7 7\"></path>\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<mat-menu #menuModeloChatIA=\"matMenu\" class=\"menu-modelo-chat-ia\">\r\n <button mat-menu-item [class.opcion-activa]=\"proveedorSeleccionado === 'Gemini'\"\r\n (click)=\"proveedorSeleccionado = 'Gemini'\">\r\n <span>Gemini</span>\r\n <svg *ngIf=\"proveedorSeleccionado === 'Gemini'\" class=\"chat-ia-check\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M20 6L9 17l-5-5\"></path>\r\n </svg>\r\n </button>\r\n <button mat-menu-item [class.opcion-activa]=\"proveedorSeleccionado === 'Groq'\"\r\n (click)=\"proveedorSeleccionado = 'Groq'\">\r\n <span>Groq</span>\r\n <svg *ngIf=\"proveedorSeleccionado === 'Groq'\" class=\"chat-ia-check\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M20 6L9 17l-5-5\"></path>\r\n </svg>\r\n </button>\r\n</mat-menu>\r\n\r\n<!-- Modal \"ampliar\": muestra la tabla a todo el ancho de la pantalla (el panel la recorta). Overlay\r\n propio (no CDK) porque el componente se monta como web-component y el overlay de CDK queda fuera\r\n de su contexto de estilos. -->\r\n<div class=\"chat-ia-modal-overlay\" *ngIf=\"tablaAmpliada\" (click)=\"cerrarAmpliada()\">\r\n <div class=\"chat-ia-modal\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"chat-ia-modal-header\">\r\n <div class=\"chat-ia-modal-titulo\">{{ descripcionAmpliada || 'Resultados' }}</div>\r\n <div class=\"chat-ia-modal-acciones\">\r\n <button type=\"button\" class=\"chat-ia-accion chat-ia-accion-clara\" matTooltip=\"Copiar\"\r\n (click)=\"copiar(tablaAmpliada)\">\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n <button type=\"button\" class=\"chat-ia-accion chat-ia-accion-clara\" matTooltip=\"Exportar\"\r\n [matMenuTriggerFor]=\"menuExportModal\">\r\n <mat-icon>download</mat-icon>\r\n </button>\r\n <mat-menu #menuExportModal=\"matMenu\" class=\"menu-export-chat-ia\">\r\n <button mat-menu-item type=\"button\" (click)=\"exportarCsv(tablaAmpliada)\">CSV (.csv)</button>\r\n <button mat-menu-item type=\"button\" (click)=\"exportarXlsx(tablaAmpliada)\">Excel (.xlsx)</button>\r\n </mat-menu>\r\n <button type=\"button\" class=\"chat-ia-accion chat-ia-accion-clara\" matTooltip=\"Cerrar\"\r\n (click)=\"cerrarAmpliada()\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"chat-ia-modal-tabla\">\r\n <table mat-table [dataSource]=\"tablaAmpliada\">\r\n <ng-container *ngFor=\"let columna of columnasDe(tablaAmpliada)\" [matColumnDef]=\"columna\">\r\n <th mat-header-cell *matHeaderCellDef>{{ columna }}</th>\r\n <td mat-cell *matCellDef=\"let fila\">{{ fila[columna] }}</td>\r\n </ng-container>\r\n <tr mat-header-row *matHeaderRowDef=\"columnasDe(tablaAmpliada)\"></tr>\r\n <tr mat-row *matRowDef=\"let fila; columns: columnasDe(tablaAmpliada);\"></tr>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Aviso ef\u00EDmero tras copiar al portapapeles. -->\r\n<div class=\"chat-ia-copiado-aviso\" *ngIf=\"copiadoAviso\">Tabla copiada</div>\r\n",
924
- styles: [":host{position:fixed;right:32px;bottom:32px;z-index:1000;font-family:Roboto,sans-serif}.chat-ia-panel{width:450px;height:650px;max-width:calc(100vw - 48px);max-height:calc(100vh - 96px);background:#fff;border-radius:18px;box-shadow:0 24px 60px rgba(20,25,30,.28);display:flex;flex-direction:column;overflow:hidden}.chat-ia-header{background:linear-gradient(135deg,#7c5ce0,#5f42bd);padding:16px 18px;display:flex;align-items:center;justify-content:space-between;flex-shrink:0}.chat-ia-header-info{display:flex;align-items:center;gap:10px;min-width:0}.chat-ia-header-icono{width:32px;height:32px;border-radius:50%;background:rgba(255,255,255,.22);display:flex;align-items:center;justify-content:center;flex:none}.chat-ia-titulo{color:#fff;font-size:14px;font-weight:500}.chat-ia-subtitulo{color:rgba(255,255,255,.75);font-size:11px;margin-top:1px}.chat-ia-cerrar{width:24px;height:24px;display:flex;align-items:center;justify-content:center;cursor:pointer;opacity:.85;flex:none}.chat-ia-cerrar:hover{opacity:1}.chat-ia-mensajes{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:12px;padding:16px;background:#fbfafc}.chat-ia-mensaje{display:flex}.chat-ia-mensaje .chat-ia-burbuja{max-width:88%;background:#f2eefb;color:#26313a;border-radius:14px 14px 14px 3px;padding:10px 13px;font-size:13px;line-height:1.5}.chat-ia-mensaje .chat-ia-burbuja-error{background:#fdecea;color:#7a1f14}.chat-ia-mensaje.chat-ia-mensaje-usuario{justify-content:flex-end}.chat-ia-mensaje.chat-ia-mensaje-usuario .chat-ia-burbuja{background:#7c5ce0;color:#fff;border-radius:14px 14px 3px}.chat-ia-bienvenida-texto{align-self:flex-start;max-width:88%;background:#f2eefb;color:#26313a;border-radius:14px 14px 14px 3px;padding:10px 13px;font-size:13px;line-height:1.5}.chips-chat-ia{flex:none;display:flex;flex-wrap:wrap;gap:6px;padding:0 16px 10px}.chip-chat-ia{border:1px solid #e7e2f5;background:#f2eefb;color:#5f42bd;border-radius:14px;padding:5px 10px;font-size:11px;cursor:pointer}.chip-chat-ia:hover{background:#e7ddfa}.chat-ia-descripcion{font-size:13px;line-height:1.5;margin-bottom:6px}.chat-ia-sin-resultados{color:#5a5a5a;font-style:italic}.chat-ia-stat{margin-top:4px}.chat-ia-stat-valor{font-size:30px;font-weight:600;color:#5f42bd;line-height:1.15;font-variant-numeric:proportional-nums}.chat-ia-lista-simple,.chat-ia-tabla-bloque{margin-top:4px;background:#fff;border-radius:10px;padding:8px 10px}.chat-ia-lista-simple{font-size:13px;line-height:1.5}.chat-ia-tabla-acciones{display:flex;justify-content:flex-end;align-items:center;gap:2px;margin-bottom:2px}.chat-ia-accion{width:26px;height:26px;border:none;background:0 0;color:#6b6478;border-radius:7px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;padding:0;flex:none}.chat-ia-accion:hover{background:#f2eefb}.chat-ia-accion .mat-icon{font-size:17px;width:17px;height:17px;line-height:17px}.chat-ia-accion.chat-ia-accion-clara{color:rgba(255,255,255,.9)}.chat-ia-accion.chat-ia-accion-clara:hover{background:rgba(255,255,255,.18);color:#fff}.chat-ia-tabla-resultado{overflow-x:auto;max-width:100%}.chat-ia-tabla-resultado table{font-size:12px;background:0 0}.chat-ia-tabla-resultado th.mat-header-cell{color:#6b6478;font-weight:600;padding:0 14px 5px 0;border-bottom:1px solid #f0edf7;white-space:nowrap}.chat-ia-tabla-resultado td.mat-cell{padding:7px 14px 0 0;white-space:nowrap;font-variant-numeric:tabular-nums}.chat-ia-pensando{align-self:flex-start;background:#f2eefb;padding:12px 16px;border-radius:14px 14px 14px 3px;display:flex;gap:5px;flex-shrink:0}.chat-ia-dot{width:6px;height:6px;border-radius:50%;background:#9a93ae;-webkit-animation:1.1s ease-in-out infinite chatIaBlink;animation:1.1s ease-in-out infinite chatIaBlink}.chat-ia-dot:nth-child(2){-webkit-animation-delay:.15s;animation-delay:.15s}.chat-ia-dot:nth-child(3){-webkit-animation-delay:.3s;animation-delay:.3s}@-webkit-keyframes chatIaBlink{0%,100%,80%{opacity:.25}40%{opacity:1}}@keyframes chatIaBlink{0%,100%,80%{opacity:.25}40%{opacity:1}}.chat-ia-entrada{padding:10px 14px 14px;border-top:1px solid #e9f2ee;flex-shrink:0}.chat-ia-caja-entrada{position:relative;background:#f2f7f5;border:1px solid #e6efea;border-radius:18px;padding:10px 12px 8px}.chat-ia-caja-entrada textarea{border:none;outline:0;background:0 0;width:100%;font:inherit;font-size:13.5px;color:#26313a;resize:none;line-height:1.45;max-height:110px;overflow-y:auto;display:block;padding:0 28px 0 0}.chat-ia-caja-entrada textarea.chat-ia-textarea-expandido{max-height:160px}.chat-ia-caja-entrada textarea::-webkit-input-placeholder{color:#9a93ae}.chat-ia-caja-entrada textarea::-moz-placeholder{color:#9a93ae}.chat-ia-caja-entrada textarea:-ms-input-placeholder{color:#9a93ae}.chat-ia-caja-entrada textarea::-ms-input-placeholder{color:#9a93ae}.chat-ia-caja-entrada textarea::placeholder{color:#9a93ae}.chat-ia-expandir{position:absolute;top:8px;right:10px;font-size:17px;height:17px;width:17px;color:#9a9a9a;cursor:pointer}.chat-ia-pie-entrada{display:flex;align-items:center;justify-content:flex-end;gap:8px;margin-top:8px}.chat-ia-selector-modelo{display:inline-flex;align-items:center;gap:4px;border:none;background:0 0;color:#4e5d57;border-radius:14px;padding:5px 9px;font-size:11.5px;font-weight:600;cursor:pointer}.chat-ia-enviar{width:32px;height:32px;border-radius:50%;border:none;background:#7c5ce0;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;flex:none}.chat-ia-enviar:disabled{background:#dce6e1;color:#a9bab3;cursor:default}.chat-ia-microfono{width:28px;height:28px;border-radius:50%;border:none;background:0 0;color:#6b6478;display:flex;align-items:center;justify-content:center;cursor:pointer;flex:none}.chat-ia-microfono:hover{background:#f2eefb}.chat-ia-microfono.chat-ia-microfono-activo{color:#fff;background:#e05a5a;-webkit-animation:1.1s ease-in-out infinite chatIaBlink;animation:1.1s ease-in-out infinite chatIaBlink}::ng-deep .mat-menu-panel.menu-modelo-chat-ia{min-width:132px;border:1px solid #e6efea;border-radius:10px;box-shadow:0 12px 26px rgba(20,25,30,.16)}::ng-deep .mat-menu-panel.menu-modelo-chat-ia .mat-menu-content{padding:4px}::ng-deep .mat-menu-panel.menu-modelo-chat-ia .mat-menu-item{display:flex;align-items:center;justify-content:space-between;gap:8px;height:auto;line-height:normal;padding:7px 10px;font-size:12px;color:#26313a;border-radius:7px}::ng-deep .mat-menu-panel.menu-modelo-chat-ia .mat-menu-item.opcion-activa{background:#f2f7f5}::ng-deep .mat-menu-panel.menu-modelo-chat-ia .mat-menu-item .chat-ia-check{color:#7c5ce0}.chat-ia-modal-overlay{position:fixed;inset:0;background:rgba(20,25,30,.5);display:flex;align-items:center;justify-content:center;padding:24px;z-index:1100}.chat-ia-modal{background:#fff;border-radius:16px;box-shadow:0 24px 60px rgba(20,25,30,.32);width:auto;max-width:92vw;max-height:86vh;display:flex;flex-direction:column;overflow:hidden}.chat-ia-modal-header{background:linear-gradient(135deg,#7c5ce0,#5f42bd);padding:12px 16px;display:flex;align-items:center;justify-content:space-between;gap:16px;flex-shrink:0}.chat-ia-modal-titulo{color:#fff;font-size:14px;font-weight:500;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.chat-ia-modal-acciones{display:flex;align-items:center;gap:2px;flex:none}.chat-ia-modal-tabla{flex:1;min-height:0;overflow:auto;padding:10px 16px 16px}.chat-ia-modal-tabla table{font-size:13px;background:0 0;width:100%}.chat-ia-modal-tabla th.mat-header-cell{color:#6b6478;font-weight:600;padding:0 18px 8px 0;border-bottom:1px solid #f0edf7;white-space:nowrap}.chat-ia-modal-tabla td.mat-cell{padding:9px 18px 9px 0;white-space:nowrap;color:#26313a;border-bottom:1px solid #f6f4fb;font-variant-numeric:tabular-nums}.chat-ia-copiado-aviso{position:fixed;top:24px;left:50%;transform:translateX(-50%);background:#26313a;color:#fff;font-size:12.5px;padding:8px 16px;border-radius:20px;box-shadow:0 8px 20px rgba(20,25,30,.25);z-index:1200;-webkit-animation:.15s ease-out chatIaAvisoEntrada;animation:.15s ease-out chatIaAvisoEntrada}@-webkit-keyframes chatIaAvisoEntrada{from{opacity:0;transform:translate(-50%,-6px)}to{opacity:1;transform:translate(-50%,0)}}@keyframes chatIaAvisoEntrada{from{opacity:0;transform:translate(-50%,-6px)}to{opacity:1;transform:translate(-50%,0)}}::ng-deep .mat-menu-panel.menu-export-chat-ia{min-width:132px;border:1px solid #e6efea;border-radius:10px;box-shadow:0 12px 26px rgba(20,25,30,.16)}::ng-deep .mat-menu-panel.menu-export-chat-ia .mat-menu-content{padding:4px}::ng-deep .mat-menu-panel.menu-export-chat-ia .mat-menu-item{height:auto;line-height:normal;padding:8px 12px;font-size:12px;color:#26313a;border-radius:7px}::ng-deep .mat-menu-panel.menu-export-chat-ia .mat-menu-item:hover{background:#f2f7f5}"]
940
+ template: "<!-- Panel (abierto) -->\r\n<div class=\"chat-ia-panel\" *ngIf=\"abierto\">\r\n <div class=\"chat-ia-header\">\r\n <div class=\"chat-ia-header-info\">\r\n <div class=\"chat-ia-header-icono\">\r\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#fff\" stroke-width=\"1.8\">\r\n <path d=\"M4 5h16v10H9l-4 4V15H4z\"></path>\r\n </svg>\r\n </div>\r\n <div>\r\n <div class=\"chat-ia-titulo\">Preg\u00FAntale a tus Datos</div>\r\n <div class=\"chat-ia-subtitulo\">Consulta tus reportes en lenguaje natural</div>\r\n </div>\r\n </div>\r\n <div class=\"chat-ia-cerrar\" (click)=\"cerrar()\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" stroke=\"#fff\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\">\r\n <path d=\"M6 6l12 12M18 6L6 18\"></path>\r\n </svg>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chat-ia-mensajes\" #mensajesContainer>\r\n <div class=\"chat-ia-bienvenida-texto\">Hola, soy tu asistente de datos de Snap Forms. Preg\u00FAntame lo que quieras saber sobre tu operaci\u00F3n.</div>\r\n\r\n <div class=\"chat-ia-mensaje\" *ngFor=\"let mensaje of mensajes\" [class.chat-ia-mensaje-usuario]=\"mensaje.deUsuario\">\r\n <div class=\"chat-ia-burbuja\" [class.chat-ia-burbuja-error]=\"mensaje.esError\">\r\n <span *ngIf=\"mensaje.texto\">{{ mensaje.texto }}</span>\r\n\r\n <ng-container *ngIf=\"mensaje.resultado\">\r\n <div class=\"chat-ia-descripcion\" *ngIf=\"mensaje.descripcion\">{{ mensaje.descripcion }}</div>\r\n\r\n <div class=\"chat-ia-sin-resultados\" *ngIf=\"mensaje.resultado.length === 0\">La consulta no encontr\u00F3 resultados.</div>\r\n\r\n <div class=\"chat-ia-stat\" *ngIf=\"esConteo(mensaje.resultado)\">\r\n <div class=\"chat-ia-stat-valor\">{{ mensaje.resultado[0].Resultado | number }}</div>\r\n </div>\r\n\r\n <div class=\"chat-ia-lista-simple\" *ngIf=\"esListaSimple(mensaje.resultado)\">{{ textoListaSimple(mensaje.resultado) }}</div>\r\n\r\n <div class=\"chat-ia-tabla-bloque\" *ngIf=\"mensaje.resultado.length > 0 && !esConteo(mensaje.resultado) && !esListaSimple(mensaje.resultado)\">\r\n <div class=\"chat-ia-tabla-acciones\">\r\n <button type=\"button\" class=\"chat-ia-accion\" matTooltip=\"Ampliar\"\r\n (click)=\"ampliar(mensaje.resultado, mensaje.descripcion)\">\r\n <mat-icon>open_in_full</mat-icon>\r\n </button>\r\n <button type=\"button\" class=\"chat-ia-accion\" matTooltip=\"Copiar\"\r\n (click)=\"copiar(mensaje.resultado)\">\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n <button type=\"button\" class=\"chat-ia-accion\" matTooltip=\"Exportar\"\r\n [matMenuTriggerFor]=\"menuExport\">\r\n <mat-icon>download</mat-icon>\r\n </button>\r\n <mat-menu #menuExport=\"matMenu\" class=\"menu-export-chat-ia\">\r\n <button mat-menu-item type=\"button\" (click)=\"exportarCsv(mensaje.resultado)\">CSV (.csv)</button>\r\n <button mat-menu-item type=\"button\" (click)=\"exportarXlsx(mensaje.resultado)\">Excel (.xlsx)</button>\r\n </mat-menu>\r\n </div>\r\n <div class=\"chat-ia-tabla-resultado\">\r\n <table mat-table [dataSource]=\"mensaje.resultado\">\r\n <ng-container *ngFor=\"let columna of columnasDe(mensaje.resultado)\" [matColumnDef]=\"columna\">\r\n <th mat-header-cell *matHeaderCellDef>{{ columna }}</th>\r\n <td mat-cell *matCellDef=\"let fila\">{{ fila[columna] }}</td>\r\n </ng-container>\r\n <tr mat-header-row *matHeaderRowDef=\"columnasDe(mensaje.resultado)\"></tr>\r\n <tr mat-row *matRowDef=\"let fila; columns: columnasDe(mensaje.resultado);\"></tr>\r\n </table>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chat-ia-pensando\" *ngIf=\"consultando\">\r\n <span class=\"chat-ia-dot\"></span><span class=\"chat-ia-dot\"></span><span class=\"chat-ia-dot\"></span>\r\n </div>\r\n </div>\r\n\r\n <!-- Sugerencias: con el chat vac\u00EDo se muestran. Tras la primera pregunta (ya hay mensajes)\r\n quedan plegadas en el bot\u00F3n \"Sugerencias\", que las abre/cierra; al estar plegadas, el \u00E1rea\r\n de conversaci\u00F3n gana ese espacio. -->\r\n <button type=\"button\" class=\"chip-chat-ia-toggle\" *ngIf=\"mensajes.length > 0\"\r\n (click)=\"sugerenciasAbiertas = !sugerenciasAbiertas\">\r\n <svg class=\"chip-chat-ia-toggle-bombilla\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M9 18h6\"></path>\r\n <path d=\"M10 22h4\"></path>\r\n <path d=\"M12 2a7 7 0 0 0-4 12.7c.6.5 1 1.3 1 2.1V18h6v-1.2c0-.8.4-1.6 1-2.1A7 7 0 0 0 12 2z\"></path>\r\n </svg>\r\n <span>Sugerencias</span>\r\n <svg class=\"chip-chat-ia-toggle-chevron\" [class.abierto]=\"sugerenciasAbiertas\" width=\"11\" height=\"11\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M6 9l6 6 6-6\"></path>\r\n </svg>\r\n </button>\r\n <div class=\"chips-chat-ia\" *ngIf=\"mensajes.length === 0 || sugerenciasAbiertas\">\r\n <span class=\"chip-chat-ia\" *ngFor=\"let chip of chipsSugeridos\"\r\n (click)=\"onClickEnviar(chip)\">{{ chip }}</span>\r\n </div>\r\n\r\n <div class=\"chat-ia-entrada\">\r\n <div class=\"chat-ia-caja-entrada\">\r\n <mat-icon fontSet=\"wm-menu-iconos\" class=\"chat-ia-expandir\" (click)=\"onClickExpandirBorrador()\">{{ borradorExpandido ? 'close_fullscreen' : 'open_in_full' }}</mat-icon>\r\n <textarea [rows]=\"filasBorrador\" [(ngModel)]=\"borrador\" (keydown.enter)=\"$event.preventDefault(); onClickEnviar()\"\r\n [class.chat-ia-textarea-expandido]=\"borradorExpandido\"\r\n placeholder=\"Escribe tu pregunta...\"></textarea>\r\n <div class=\"chat-ia-pie-entrada\">\r\n <button class=\"chat-ia-selector-modelo\" [matMenuTriggerFor]=\"menuModeloChatIA\" type=\"button\">\r\n <span *ngIf=\"proveedorSeleccionado === 'Gemini'\">Gemini</span>\r\n <span *ngIf=\"proveedorSeleccionado === 'Groq'\">Groq</span>\r\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M6 9l6 6 6-6\"></path>\r\n </svg>\r\n </button>\r\n <button class=\"chat-ia-microfono\" [class.chat-ia-microfono-activo]=\"escuchando\" *ngIf=\"micDisponible\"\r\n (click)=\"onClickMicrofono()\" type=\"button\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\"></path>\r\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"></path>\r\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"></line>\r\n </svg>\r\n </button>\r\n <button class=\"chat-ia-enviar\" [disabled]=\"!borrador.trim() || consultando\" (click)=\"onClickEnviar()\" type=\"button\">\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M12 19V6\"></path>\r\n <path d=\"M5 13l7-7 7 7\"></path>\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<mat-menu #menuModeloChatIA=\"matMenu\" class=\"menu-modelo-chat-ia\">\r\n <button mat-menu-item [class.opcion-activa]=\"proveedorSeleccionado === 'Gemini'\"\r\n (click)=\"proveedorSeleccionado = 'Gemini'\">\r\n <span>Gemini</span>\r\n <svg *ngIf=\"proveedorSeleccionado === 'Gemini'\" class=\"chat-ia-check\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M20 6L9 17l-5-5\"></path>\r\n </svg>\r\n </button>\r\n <button mat-menu-item [class.opcion-activa]=\"proveedorSeleccionado === 'Groq'\"\r\n (click)=\"proveedorSeleccionado = 'Groq'\">\r\n <span>Groq</span>\r\n <svg *ngIf=\"proveedorSeleccionado === 'Groq'\" class=\"chat-ia-check\" width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M20 6L9 17l-5-5\"></path>\r\n </svg>\r\n </button>\r\n</mat-menu>\r\n\r\n<!-- Modal \"ampliar\": muestra la tabla a todo el ancho de la pantalla (el panel la recorta). Overlay\r\n propio (no CDK) porque el componente se monta como web-component y el overlay de CDK queda fuera\r\n de su contexto de estilos. -->\r\n<div class=\"chat-ia-modal-overlay\" *ngIf=\"tablaAmpliada\" (click)=\"cerrarAmpliada()\">\r\n <div class=\"chat-ia-modal\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"chat-ia-modal-header\">\r\n <div class=\"chat-ia-modal-titulo\">{{ descripcionAmpliada || 'Resultados' }}</div>\r\n <div class=\"chat-ia-modal-acciones\">\r\n <button type=\"button\" class=\"chat-ia-accion chat-ia-accion-clara\" matTooltip=\"Copiar\"\r\n (click)=\"copiar(tablaAmpliada)\">\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n <button type=\"button\" class=\"chat-ia-accion chat-ia-accion-clara\" matTooltip=\"Exportar\"\r\n [matMenuTriggerFor]=\"menuExportModal\">\r\n <mat-icon>download</mat-icon>\r\n </button>\r\n <mat-menu #menuExportModal=\"matMenu\" class=\"menu-export-chat-ia\">\r\n <button mat-menu-item type=\"button\" (click)=\"exportarCsv(tablaAmpliada)\">CSV (.csv)</button>\r\n <button mat-menu-item type=\"button\" (click)=\"exportarXlsx(tablaAmpliada)\">Excel (.xlsx)</button>\r\n </mat-menu>\r\n <button type=\"button\" class=\"chat-ia-accion chat-ia-accion-clara\" matTooltip=\"Cerrar\"\r\n (click)=\"cerrarAmpliada()\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"chat-ia-modal-tabla\">\r\n <table mat-table [dataSource]=\"tablaAmpliada\">\r\n <ng-container *ngFor=\"let columna of columnasDe(tablaAmpliada)\" [matColumnDef]=\"columna\">\r\n <th mat-header-cell *matHeaderCellDef>{{ columna }}</th>\r\n <td mat-cell *matCellDef=\"let fila\">{{ fila[columna] }}</td>\r\n </ng-container>\r\n <tr mat-header-row *matHeaderRowDef=\"columnasDe(tablaAmpliada)\"></tr>\r\n <tr mat-row *matRowDef=\"let fila; columns: columnasDe(tablaAmpliada);\"></tr>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Aviso ef\u00EDmero tras copiar al portapapeles. -->\r\n<div class=\"chat-ia-copiado-aviso\" *ngIf=\"copiadoAviso\">Tabla copiada</div>\r\n",
941
+ styles: [":host{position:fixed;right:32px;bottom:32px;z-index:1000;font-family:Roboto,sans-serif}.chat-ia-panel{width:450px;height:650px;max-width:calc(100vw - 48px);max-height:calc(100vh - 96px);background:#fff;border-radius:18px;box-shadow:0 24px 60px rgba(20,25,30,.28);display:flex;flex-direction:column;overflow:hidden}.chat-ia-header{background:linear-gradient(135deg,#7c5ce0,#5f42bd);padding:16px 18px;display:flex;align-items:center;justify-content:space-between;flex-shrink:0}.chat-ia-header-info{display:flex;align-items:center;gap:10px;min-width:0}.chat-ia-header-icono{width:32px;height:32px;border-radius:50%;background:rgba(255,255,255,.22);display:flex;align-items:center;justify-content:center;flex:none}.chat-ia-titulo{color:#fff;font-size:14px;font-weight:500}.chat-ia-subtitulo{color:rgba(255,255,255,.75);font-size:11px;margin-top:1px}.chat-ia-cerrar{width:24px;height:24px;display:flex;align-items:center;justify-content:center;cursor:pointer;opacity:.85;flex:none}.chat-ia-cerrar:hover{opacity:1}.chat-ia-mensajes{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:12px;padding:16px;background:#fbfafc}.chat-ia-mensaje{display:flex}.chat-ia-mensaje .chat-ia-burbuja{max-width:88%;background:#f2eefb;color:#26313a;border-radius:14px 14px 14px 3px;padding:10px 13px;font-size:13px;line-height:1.5}.chat-ia-mensaje .chat-ia-burbuja-error{background:#fdecea;color:#7a1f14}.chat-ia-mensaje.chat-ia-mensaje-usuario{justify-content:flex-end}.chat-ia-mensaje.chat-ia-mensaje-usuario .chat-ia-burbuja{background:#7c5ce0;color:#fff;border-radius:14px 14px 3px}.chat-ia-bienvenida-texto{align-self:flex-start;max-width:88%;background:#f2eefb;color:#26313a;border-radius:14px 14px 14px 3px;padding:10px 13px;font-size:13px;line-height:1.5}.chips-chat-ia{flex:none;display:flex;flex-direction:column;align-items:flex-start;gap:6px;padding:0 16px 10px}.chip-chat-ia{max-width:100%;border:1px solid #e7e2f5;background:#f2eefb;color:#5f42bd;border-radius:14px;padding:5px 10px;font-size:11px;line-height:1.35;cursor:pointer;overflow-wrap:anywhere}.chip-chat-ia:hover{background:#e7ddfa}.chip-chat-ia-toggle{flex:none;align-self:flex-start;display:inline-flex;align-items:center;gap:6px;margin:10px 16px;border:1px solid #e7e2f5;background:#f2eefb;color:#5f42bd;border-radius:16px;padding:6px 12px;font-size:12px;cursor:pointer}.chip-chat-ia-toggle .chip-chat-ia-toggle-chevron{transition:transform .15s}.chip-chat-ia-toggle .chip-chat-ia-toggle-chevron.abierto{transform:rotate(180deg)}.chip-chat-ia-toggle:hover{background:#e7ddfa}.chat-ia-descripcion{font-size:13px;line-height:1.5;margin-bottom:6px}.chat-ia-sin-resultados{color:#5a5a5a;font-style:italic}.chat-ia-stat{margin-top:4px}.chat-ia-stat-valor{font-size:30px;font-weight:600;color:#5f42bd;line-height:1.15;font-variant-numeric:proportional-nums}.chat-ia-lista-simple,.chat-ia-tabla-bloque{margin-top:4px;background:#fff;border-radius:10px;padding:8px 10px}.chat-ia-lista-simple{font-size:13px;line-height:1.5}.chat-ia-tabla-acciones{display:flex;justify-content:flex-end;align-items:center;gap:2px;margin-bottom:2px}.chat-ia-accion{width:26px;height:26px;border:none;background:0 0;color:#6b6478;border-radius:7px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;padding:0;flex:none}.chat-ia-accion:hover{background:#f2eefb}.chat-ia-accion .mat-icon{font-size:17px;width:17px;height:17px;line-height:17px}.chat-ia-accion.chat-ia-accion-clara{color:rgba(255,255,255,.9)}.chat-ia-accion.chat-ia-accion-clara:hover{background:rgba(255,255,255,.18);color:#fff}.chat-ia-tabla-resultado{overflow-x:auto;max-width:100%}.chat-ia-tabla-resultado table{font-size:12px;background:0 0}.chat-ia-tabla-resultado th.mat-header-cell{color:#6b6478;font-weight:600;padding:0 14px 5px 0;border-bottom:1px solid #f0edf7;white-space:nowrap}.chat-ia-tabla-resultado td.mat-cell{padding:7px 14px 0 0;white-space:nowrap;font-variant-numeric:tabular-nums}.chat-ia-pensando{align-self:flex-start;background:#f2eefb;padding:12px 16px;border-radius:14px 14px 14px 3px;display:flex;gap:5px;flex-shrink:0}.chat-ia-dot{width:6px;height:6px;border-radius:50%;background:#9a93ae;-webkit-animation:1.1s ease-in-out infinite chatIaBlink;animation:1.1s ease-in-out infinite chatIaBlink}.chat-ia-dot:nth-child(2){-webkit-animation-delay:.15s;animation-delay:.15s}.chat-ia-dot:nth-child(3){-webkit-animation-delay:.3s;animation-delay:.3s}@-webkit-keyframes chatIaBlink{0%,100%,80%{opacity:.25}40%{opacity:1}}@keyframes chatIaBlink{0%,100%,80%{opacity:.25}40%{opacity:1}}.chat-ia-entrada{padding:10px 14px 14px;border-top:1px solid #e9f2ee;flex-shrink:0}.chat-ia-caja-entrada{position:relative;background:#f2f7f5;border:1px solid #e6efea;border-radius:18px;padding:10px 12px 8px}.chat-ia-caja-entrada textarea{border:none;outline:0;background:0 0;width:100%;font:inherit;font-size:13.5px;color:#26313a;resize:none;line-height:1.45;max-height:110px;overflow-y:auto;display:block;padding:0 28px 0 0}.chat-ia-caja-entrada textarea.chat-ia-textarea-expandido{max-height:160px}.chat-ia-caja-entrada textarea::-webkit-input-placeholder{color:#9a93ae}.chat-ia-caja-entrada textarea::-moz-placeholder{color:#9a93ae}.chat-ia-caja-entrada textarea:-ms-input-placeholder{color:#9a93ae}.chat-ia-caja-entrada textarea::-ms-input-placeholder{color:#9a93ae}.chat-ia-caja-entrada textarea::placeholder{color:#9a93ae}.chat-ia-expandir{position:absolute;top:8px;right:10px;font-size:17px;height:17px;width:17px;color:#9a9a9a;cursor:pointer}.chat-ia-pie-entrada{display:flex;align-items:center;justify-content:flex-end;gap:8px;margin-top:8px}.chat-ia-selector-modelo{display:inline-flex;align-items:center;gap:4px;border:none;background:0 0;color:#4e5d57;border-radius:14px;padding:5px 9px;font-size:11.5px;font-weight:600;cursor:pointer}.chat-ia-enviar{width:32px;height:32px;border-radius:50%;border:none;background:#7c5ce0;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;flex:none}.chat-ia-enviar:disabled{background:#dce6e1;color:#a9bab3;cursor:default}.chat-ia-microfono{width:28px;height:28px;border-radius:50%;border:none;background:0 0;color:#6b6478;display:flex;align-items:center;justify-content:center;cursor:pointer;flex:none}.chat-ia-microfono:hover{background:#f2eefb}.chat-ia-microfono.chat-ia-microfono-activo{color:#fff;background:#e05a5a;-webkit-animation:1.1s ease-in-out infinite chatIaBlink;animation:1.1s ease-in-out infinite chatIaBlink}::ng-deep .mat-menu-panel.menu-modelo-chat-ia{min-width:132px;border:1px solid #e6efea;border-radius:10px;box-shadow:0 12px 26px rgba(20,25,30,.16)}::ng-deep .mat-menu-panel.menu-modelo-chat-ia .mat-menu-content{padding:4px}::ng-deep .mat-menu-panel.menu-modelo-chat-ia .mat-menu-item{display:flex;align-items:center;justify-content:space-between;gap:8px;height:auto;line-height:normal;padding:7px 10px;font-size:12px;color:#26313a;border-radius:7px}::ng-deep .mat-menu-panel.menu-modelo-chat-ia .mat-menu-item.opcion-activa{background:#f2f7f5}::ng-deep .mat-menu-panel.menu-modelo-chat-ia .mat-menu-item .chat-ia-check{color:#7c5ce0}.chat-ia-modal-overlay{position:fixed;inset:0;background:rgba(20,25,30,.5);display:flex;align-items:center;justify-content:center;padding:24px;z-index:1100}.chat-ia-modal{background:#fff;border-radius:16px;box-shadow:0 24px 60px rgba(20,25,30,.32);width:auto;max-width:92vw;max-height:86vh;display:flex;flex-direction:column;overflow:hidden}.chat-ia-modal-header{background:linear-gradient(135deg,#7c5ce0,#5f42bd);padding:12px 16px;display:flex;align-items:center;justify-content:space-between;gap:16px;flex-shrink:0}.chat-ia-modal-titulo{color:#fff;font-size:14px;font-weight:500;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.chat-ia-modal-acciones{display:flex;align-items:center;gap:2px;flex:none}.chat-ia-modal-tabla{flex:1;min-height:0;overflow:auto;padding:10px 16px 16px}.chat-ia-modal-tabla table{font-size:13px;background:0 0;width:100%}.chat-ia-modal-tabla th.mat-header-cell{color:#6b6478;font-weight:600;padding:0 18px 8px 0;border-bottom:1px solid #f0edf7;white-space:nowrap}.chat-ia-modal-tabla td.mat-cell{padding:9px 18px 9px 0;white-space:nowrap;color:#26313a;border-bottom:1px solid #f6f4fb;font-variant-numeric:tabular-nums}.chat-ia-copiado-aviso{position:fixed;top:24px;left:50%;transform:translateX(-50%);background:#26313a;color:#fff;font-size:12.5px;padding:8px 16px;border-radius:20px;box-shadow:0 8px 20px rgba(20,25,30,.25);z-index:1200;-webkit-animation:.15s ease-out chatIaAvisoEntrada;animation:.15s ease-out chatIaAvisoEntrada}@-webkit-keyframes chatIaAvisoEntrada{from{opacity:0;transform:translate(-50%,-6px)}to{opacity:1;transform:translate(-50%,0)}}@keyframes chatIaAvisoEntrada{from{opacity:0;transform:translate(-50%,-6px)}to{opacity:1;transform:translate(-50%,0)}}::ng-deep .mat-menu-panel.menu-export-chat-ia{min-width:132px;border:1px solid #e6efea;border-radius:10px;box-shadow:0 12px 26px rgba(20,25,30,.16)}::ng-deep .mat-menu-panel.menu-export-chat-ia .mat-menu-content{padding:4px}::ng-deep .mat-menu-panel.menu-export-chat-ia .mat-menu-item{height:auto;line-height:normal;padding:8px 12px;font-size:12px;color:#26313a;border-radius:7px}::ng-deep .mat-menu-panel.menu-export-chat-ia .mat-menu-item:hover{background:#f2f7f5}"]
925
942
  })
926
943
  ], AsistenteDatosComponent);
927
944