xonecode 0.38.15 → 0.38.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/apps/web/dist/assets/{EditorDeFichero-C9BEoDWh.js → EditorDeFichero-CT2vAqMI.js} +1 -1
  2. package/apps/web/dist/assets/index-DjZ3hYu-.js +506 -0
  3. package/apps/web/dist/assets/index-oppsOrF4.css +1 -0
  4. package/apps/web/dist/assets/{php-DIdt3Vgn.js → php-B5s63fYs.js} +1 -1
  5. package/apps/web/dist/assets/{ruby-DYEvg0Dr.js → ruby-D9QLqlM3.js} +1 -1
  6. package/apps/web/dist/index.html +2 -2
  7. package/dist/agent/conectores/gestorJira.js +118 -1
  8. package/dist/agent/conectores/gestorJira.js.map +1 -1
  9. package/dist/agent/dispositivos/decodificarImagen.js +8 -0
  10. package/dist/agent/dispositivos/decodificarImagen.js.map +1 -1
  11. package/dist/agent/dispositivos/juezVisual.js +43 -40
  12. package/dist/agent/dispositivos/juezVisual.js.map +1 -1
  13. package/dist/agent/grafo/aprendido.js +60 -0
  14. package/dist/agent/grafo/aprendido.js.map +1 -0
  15. package/dist/agent/grafo/criticaVisual.js +17 -5
  16. package/dist/agent/grafo/criticaVisual.js.map +1 -1
  17. package/dist/agent/grafo/xoneAgent.js +2 -0
  18. package/dist/agent/grafo/xoneAgent.js.map +1 -1
  19. package/dist/agent/motores/trueforge/capacidades.js +4 -2
  20. package/dist/agent/motores/trueforge/capacidades.js.map +1 -1
  21. package/dist/agent/motores/trueforge/convertirAP.js +86 -0
  22. package/dist/agent/motores/trueforge/convertirAP.js.map +1 -0
  23. package/dist/agent/motores/trueforge/sesionTrueforge.js +197 -11
  24. package/dist/agent/motores/trueforge/sesionTrueforge.js.map +1 -1
  25. package/dist/agent/motores/trueforge/traerDeStitch.js +65 -5
  26. package/dist/agent/motores/trueforge/traerDeStitch.js.map +1 -1
  27. package/dist/agent/subagentes/agentesEnDisco.js +28 -3
  28. package/dist/agent/subagentes/agentesEnDisco.js.map +1 -1
  29. package/dist/agent/subagentes/escrituraExterna.js +8 -1
  30. package/dist/agent/subagentes/escrituraExterna.js.map +1 -1
  31. package/dist/agent/subagentes/pluginDeSkills.js +31 -6
  32. package/dist/agent/subagentes/pluginDeSkills.js.map +1 -1
  33. package/dist/agent/subagentes/subagenteExterno.js +28 -9
  34. package/dist/agent/subagentes/subagenteExterno.js.map +1 -1
  35. package/dist/agent/tareas/aumentador.js +13 -2
  36. package/dist/agent/tareas/aumentador.js.map +1 -1
  37. package/dist/agent/tareas/juezDeTarea.js +13 -8
  38. package/dist/agent/tareas/juezDeTarea.js.map +1 -1
  39. package/dist/agent/tareas/reflejoEnElGestor.js +120 -0
  40. package/dist/agent/tareas/reflejoEnElGestor.js.map +1 -0
  41. package/dist/agent/tareas/sondeoDelGestor.js +201 -0
  42. package/dist/agent/tareas/sondeoDelGestor.js.map +1 -0
  43. package/dist/agent/turno/resumenDeTool.js +2 -0
  44. package/dist/agent/turno/resumenDeTool.js.map +1 -1
  45. package/dist/agent/turno/turnoReal.js +1 -0
  46. package/dist/agent/turno/turnoReal.js.map +1 -1
  47. package/dist/cli/consola.js.map +1 -1
  48. package/dist/cli/main.js +5 -0
  49. package/dist/cli/main.js.map +1 -1
  50. package/dist/core/agentes.js +87 -2
  51. package/dist/core/agentes.js.map +1 -1
  52. package/dist/core/aprendido.js +68 -0
  53. package/dist/core/aprendido.js.map +1 -0
  54. package/dist/core/comandoExterno.js +29 -0
  55. package/dist/core/comandoExterno.js.map +1 -1
  56. package/dist/core/compararCapturas.js +62 -4
  57. package/dist/core/compararCapturas.js.map +1 -1
  58. package/dist/core/config.js +29 -0
  59. package/dist/core/config.js.map +1 -1
  60. package/dist/core/convertirAP.js +87 -0
  61. package/dist/core/convertirAP.js.map +1 -0
  62. package/dist/core/entrega.js +78 -10
  63. package/dist/core/entrega.js.map +1 -1
  64. package/dist/core/geometriaDePantalla.js +107 -5
  65. package/dist/core/geometriaDePantalla.js.map +1 -1
  66. package/dist/core/gestorDeTareas.js +2 -0
  67. package/dist/core/gestorDeTareas.js.map +1 -1
  68. package/dist/core/idiomaDeLaRespuesta.js +43 -0
  69. package/dist/core/idiomaDeLaRespuesta.js.map +1 -1
  70. package/dist/core/metodoDeComparacionVisual.js +71 -0
  71. package/dist/core/metodoDeComparacionVisual.js.map +1 -0
  72. package/dist/core/notify.js +4 -0
  73. package/dist/core/notify.js.map +1 -1
  74. package/dist/core/nucleoXone.js +42 -0
  75. package/dist/core/nucleoXone.js.map +1 -1
  76. package/dist/core/paqueteDeSoporte.js +2 -0
  77. package/dist/core/paqueteDeSoporte.js.map +1 -1
  78. package/dist/core/ports.js +36 -2
  79. package/dist/core/ports.js.map +1 -1
  80. package/dist/core/stitch.js +43 -0
  81. package/dist/core/stitch.js.map +1 -1
  82. package/dist/core/tareas.js.map +1 -1
  83. package/dist/core/tareasEnElGestor.js +197 -0
  84. package/dist/core/tareasEnElGestor.js.map +1 -0
  85. package/dist/core/textos.js +10 -3
  86. package/dist/core/textos.js.map +1 -1
  87. package/dist/web/servidor/arranque.js +483 -42
  88. package/dist/web/servidor/arranque.js.map +1 -1
  89. package/dist/web/servidor/consolaDeTarea.js +5 -6
  90. package/dist/web/servidor/consolaDeTarea.js.map +1 -1
  91. package/dist/web/servidor/corredorDeTareas.js +33 -4
  92. package/dist/web/servidor/corredorDeTareas.js.map +1 -1
  93. package/dist/web/servidor/transporte.js +11 -0
  94. package/dist/web/servidor/transporte.js.map +1 -1
  95. package/package.json +2 -2
  96. package/skills/xone-development/lib/aUtf8.mjs +68 -0
  97. package/skills/xone-development/references/css/selectores-unidades-colores.md +2 -0
  98. package/skills/xone-development/scripts/xone-a-utf8 +60 -0
  99. package/apps/web/dist/assets/index-BpDt_1vN.js +0 -506
  100. package/apps/web/dist/assets/index-D_Z-V9n1.css +0 -1
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Las tareas en background que VIVEN en el gestor de tareas (Jira, Notion…): las reglas puras de qué se escribe en él
3
+ * y cuándo. Ver `docs/superpowers/specs/2026-10-15-tareas-desde-el-gestor-design.md`.
4
+ *
5
+ * Nada de aquí sabe de qué gestor se trata: escribe a través de `GestorDeTareasPort`, y los destinos los propone
6
+ * `transicionPropuesta` sobre las transiciones que da cada ticket.
7
+ */
8
+ import { transicionPropuesta } from "./gestorDeTareas.js";
9
+ import { CATALOGO_DE_CONECTORES } from "./conectores.js";
10
+ /**
11
+ * La cabecera FIJA del comentario con el encargo ampliado. Es una constante porque la fase 2 la BUSCARÁ entre los
12
+ * comentarios del ticket para leer el último encargo revisado: cambiarla dejaría de encontrar los de antes.
13
+ */
14
+ export const CABECERA_DEL_ENCARGO = "🤖 Encargo para el agente (xonecode)";
15
+ /** El comentario que sube el encargo ampliado al ticket recién creado. Markdown: los dos gestores lo entienden. */
16
+ export function comentarioDeEncargo(encargo) {
17
+ return `**${CABECERA_DEL_ENCARGO}**\n\n${encargo.trim()}\n\n— escrito por xonecode`;
18
+ }
19
+ /**
20
+ * Qué hay que escribir en el gestor cuando una tarea cambia de estado. Solo dos momentos en la fase 1:
21
+ * - **empezar** (→ `en-proceso`): pasar el ticket a EN CURSO. Vuelve a pasar tras cada feedback y tras una
22
+ * reanudación, así que quien lo aplica mira antes si el ticket ya está en curso (`hayQueTransicionar`).
23
+ * - **cerrar** (→ `terminada`): el comentario de cierre y la transición a PROBAR.
24
+ * Aparcar (→ `requiere-atencion`) no escribe nada todavía; volver a la cola (→ `nuevo`) tampoco.
25
+ */
26
+ export function escrituraEnElGestor(antes, despues) {
27
+ if (antes === despues)
28
+ return undefined;
29
+ if (despues === "en-proceso")
30
+ return "empezar";
31
+ if (despues === "terminada")
32
+ return "cerrar";
33
+ return undefined;
34
+ }
35
+ /**
36
+ * Los reflejos que salen de pasar la cola de `antes` a `despues`, comparando por id. Solo las tareas CON ticket, y
37
+ * solo cuando su ESTADO cambió: guardar un aviso en `ticket` (que no cambia el estado) no vuelve a disparar nada. Una
38
+ * tarea nueva cuenta como «antes» ausente; una que desaparece (descartada) no escribe nada.
39
+ */
40
+ export function reflejosPendientes(antes, despues) {
41
+ const previos = new Map(antes.map((t) => [t.id, t.estado]));
42
+ const pendientes = [];
43
+ for (const t of despues) {
44
+ if (t.ticket === undefined)
45
+ continue;
46
+ const escritura = escrituraEnElGestor(previos.get(t.id), t.estado);
47
+ if (escritura !== undefined)
48
+ pendientes.push({ tarea: t, escritura });
49
+ }
50
+ return pendientes;
51
+ }
52
+ /**
53
+ * Si al EMPEZAR hay que mover el ticket: no si ya está en curso (una reanudación, o la persona lo movió a mano). Al
54
+ * cerrar se mueve siempre: comentar y pasar a PROBAR es lo que dice que está hecho.
55
+ */
56
+ export function hayQueTransicionar(escritura, categoriaActual) {
57
+ return escritura === "cerrar" || categoriaActual === "por-hacer";
58
+ }
59
+ /** El `Vinculo` con el que se escribe en el ticket de una tarea: el COPIADO al crearla, nunca el del proyecto ahora. */
60
+ export function vinculoDelTicket(ticket) {
61
+ return { conector: ticket.conector, sitio: ticket.sitio, proyecto: ticket.proyecto };
62
+ }
63
+ /**
64
+ * CERRAR un ticket: comentar y LUEGO transicionar. Una sola secuencia para el «Cerrar en …» de un chat y para una tarea
65
+ * en background que termina —dos copias acabarían distintas—:
66
+ * - si `comentar` falla, LANZA y no se transiciona (no se dice «hecho» de algo sin explicar);
67
+ * - si la transición falla, el comentario YA está en el gestor: no se lanza —repetir el cierre comentaría DOS veces—,
68
+ * se devuelve el motivo en `falloDeTransicion` (traducido por quien llama, que sabe limpiar el mensaje remoto).
69
+ */
70
+ export async function cerrarTicket(g, v, clave, comentario, transicion, motivoDe) {
71
+ await g.comentar(v, clave, comentario);
72
+ if (transicion === undefined)
73
+ return {};
74
+ try {
75
+ await g.transicionar(v, clave, transicion);
76
+ return {};
77
+ }
78
+ catch (error) {
79
+ return { falloDeTransicion: motivoDe(error) };
80
+ }
81
+ }
82
+ /** Cada cuánto mira el gestor el proceso que ejecuta las tareas (la puerta 2). Más «Mirar ahora». */
83
+ export const INTERVALO_DE_SONDEO_MS = 5 * 60 * 1000;
84
+ /**
85
+ * El mapeo que se PROPONE para un flujo, por categoría: preparar = el primero «por hacer», lanzar = el primero «en
86
+ * curso», terminar = PROBAR si existe (el flujo de IXCODE) o el primero «terminada». La persona lo confirma o lo cambia.
87
+ */
88
+ export function mapeoPropuesto(estados) {
89
+ const preparar = estados.find((e) => e.categoria === "por-hacer")?.nombre;
90
+ const lanzar = estados.find((e) => e.categoria === "en-curso")?.nombre;
91
+ const terminar = (estados.find((e) => /^probar$/i.test(e.nombre)) ?? estados.find((e) => e.categoria === "terminada"))?.nombre;
92
+ return {
93
+ ...(preparar === undefined ? {} : { preparar }),
94
+ ...(lanzar === undefined ? {} : { lanzar }),
95
+ ...(terminar === undefined ? {} : { terminar }),
96
+ };
97
+ }
98
+ /**
99
+ * La transición que lleva un ticket al estado del MAPEO para ese momento (empezar → lanzar, cerrar → terminar), por el
100
+ * nombre de su destino sin mayúsculas. Sin estado mapeado, la regla de antes (`transicionPropuesta`). Con estado mapeado
101
+ * y sin transición que lleve a él, `undefined`: no se adivina otra.
102
+ */
103
+ export function transicionHacia(ts, para, estados) {
104
+ const destino = para === "empezar" ? estados?.lanzar : estados?.terminar;
105
+ if (destino === undefined)
106
+ return transicionPropuesta(ts, para);
107
+ return ts.find((t) => t.destino.trim().toLowerCase() === destino.trim().toLowerCase());
108
+ }
109
+ /** Si un estado del gestor es el del mapeo (sin mayúsculas ni espacios de más). */
110
+ export function esEstado(estado, mapeado) {
111
+ return mapeado !== undefined && estado.trim().toLowerCase() === mapeado.trim().toLowerCase();
112
+ }
113
+ /**
114
+ * Qué hacer en una pasada del sondeo, PURO: con los tickets ASIGNADOS a la cuenta del conector, el mapeo, qué tickets
115
+ * ya tienen encargo subido y cuáles ya tienen tarea (no descartada).
116
+ * - En el estado de PREPARAR y sin encargo → preparar.
117
+ * - En el estado de LANZAR y sin tarea → lanzar (con o sin encargo: sin él se usa el texto del ticket).
118
+ * Un ticket ya preparado no se vuelve a preparar; uno con tarea no lanza otra. Sin estado de lanzar no se lanza nada.
119
+ */
120
+ export function accionesDelSondeo(o) {
121
+ const acciones = [];
122
+ for (const ticket of o.tickets) {
123
+ if (o.conTarea.has(ticket.clave))
124
+ continue;
125
+ if (esEstado(ticket.estado, o.estados.lanzar))
126
+ acciones.push({ tipo: "lanzar", ticket });
127
+ else if (esEstado(ticket.estado, o.estados.preparar)) {
128
+ const sinEncargo = !o.conEncargo.has(ticket.clave);
129
+ if (o.revisarEncargo === true) {
130
+ if (sinEncargo)
131
+ acciones.push({ tipo: "preparar", ticket });
132
+ }
133
+ else {
134
+ acciones.push({ tipo: "lanzar", ticket, ...(sinEncargo ? { preparar: true } : {}) });
135
+ }
136
+ }
137
+ }
138
+ return acciones;
139
+ }
140
+ /** Si un comentario es un encargo subido por xonecode: empieza por la cabecera fija (con o sin negrita). */
141
+ export function esComentarioDeEncargo(texto) {
142
+ return texto.trimStart().replace(/^\*\*/, "").startsWith(CABECERA_DEL_ENCARGO);
143
+ }
144
+ /**
145
+ * El encargo que se ejecuta al LANZAR, leído de los comentarios del ticket: el ÚLTIMO con la cabecera, tal como esté
146
+ * (si la persona lo editó, su versión), sin la cabecera ni la firma; y lo comentado DEBAJO de él, como indicaciones
147
+ * añadidas. Sin encargo, `undefined` (se usará el texto del ticket).
148
+ */
149
+ export function encargoDeLosComentarios(comentarios) {
150
+ const ordenados = [...comentarios].sort((a, b) => a.creado.localeCompare(b.creado));
151
+ let i = -1;
152
+ for (let k = ordenados.length - 1; k >= 0; k--) {
153
+ if (esComentarioDeEncargo(ordenados[k].texto)) {
154
+ i = k;
155
+ break;
156
+ }
157
+ }
158
+ if (i === -1)
159
+ return undefined;
160
+ const encargo = ordenados[i].texto
161
+ .trimStart()
162
+ .replace(/^\*\*[^\n]*\*\*\s*|^[^\n]*\n+/, "")
163
+ .replace(/\n*— escrito por xonecode\s*$/, "")
164
+ .trim();
165
+ return { encargo, añadidos: ordenados.slice(i + 1).map((c) => c.texto.trim()).filter((t) => t !== "") };
166
+ }
167
+ /** El encargo final de una tarea lanzada desde el gestor: el encargo, y debajo lo que se comentó después, dicho como tal. */
168
+ export function encargoConAñadidos(encargo, añadidos) {
169
+ if (añadidos.length === 0)
170
+ return encargo;
171
+ return `${encargo}\n\n## Indicaciones añadidas en el ticket\n\n${añadidos.map((a) => `- ${a.replace(/\n+/g, " ")}`).join("\n")}`;
172
+ }
173
+ /**
174
+ * A dónde va el ticket de una tarea DESCARTADA: al primer estado de la categoría «terminada» del flujo (en MAS, «Listo»;
175
+ * en KAN, «Finalizada»), decisión suya. Así sale de las pendientes y el sondeo no la vuelve a crear. No es el estado
176
+ * de «terminar» del mapeo: ese puede ser PROBAR, que diría que hay algo que probar.
177
+ */
178
+ export function transicionDeDescarte(ts) {
179
+ return ts.find((t) => t.categoria === "terminada");
180
+ }
181
+ /** El comentario que deja en el ticket una tarea descartada. */
182
+ export function comentarioDeDescarte() {
183
+ return "Descartada en xonecode.\n\n— escrito por xonecode";
184
+ }
185
+ /** La línea que encabeza el encargo de una tarea que vive en el gestor: el ticket, con su enlace si se conoce. */
186
+ export function lineaDelTicket(nombreDelGestor, clave, url) {
187
+ return `Ticket de ${nombreDelGestor}: ${url === undefined ? clave : `[${clave}](${url})`}`;
188
+ }
189
+ /** El nombre para enseñar de un gestor, del catálogo de conectores («Jira»); uno que no está, por su id. */
190
+ export function nombreDelGestor(conector) {
191
+ return CATALOGO_DE_CONECTORES.find((c) => c.id === conector)?.nombre ?? conector;
192
+ }
193
+ /** El encargo con la línea del ticket delante: así el agente y la conversación saben de qué ticket es y dónde está. */
194
+ export function encargoConTicket(encargo, ticket) {
195
+ return `${lineaDelTicket(nombreDelGestor(ticket.conector), ticket.clave, ticket.url)}\n\n${encargo}`;
196
+ }
197
+ //# sourceMappingURL=tareasEnElGestor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tareasEnElGestor.js","sourceRoot":"","sources":["../../src/core/tareasEnElGestor.ts"],"names":[],"mappings":"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"}
@@ -19,10 +19,17 @@ const LARGO_TITULO_AUTOMATICO = 60;
19
19
  * petición empieza citando, y cortar en una palabra entera con puntos suspensivos. Sigue
20
20
  * siendo lo que el usuario escribió, no un resumen: renombrar sigue estando en el «…».
21
21
  */
22
+ /**
23
+ * Un ENCABEZADO de sección al empezar la petición —«Resumen», «## Contexto», «Descripción:»—: no es el título. Medido en
24
+ * Maset: una petición pegada de un ticket empezaba por «Resumen» y dos tareas se llamaban así. Una o dos palabras sin
25
+ * frase detrás (con `#` o `:` delante o detrás) se saltan, si queda otra línea con texto.
26
+ */
27
+ const ENCABEZADO = /^#{0,6}\s*[\p{L}]+(\s+[\p{L}]+)?\s*:?$/u;
22
28
  export function tituloDesde(texto) {
23
- const primera = texto
24
- .trim()
25
- .split(/\r?\n/)[0]
29
+ const lineas = texto.trim().split(/\r?\n/).map((l) => l.trim()).filter((l) => l !== "");
30
+ const primeraLinea = lineas.find((l) => !ENCABEZADO.test(l)) ?? lineas[0] ?? "";
31
+ const primera = primeraLinea
32
+ .replace(/^#{1,6}\s*/u, "")
26
33
  .split(/(?<=[.!?:;])\s/)[0]
27
34
  .replace(/[.!?:;]+$/u, "")
28
35
  .replace(/^[«"“'‘¿¡\s]+/u, "")
@@ -1 +1 @@
1
- {"version":3,"file":"textos.js","sourceRoot":"","sources":["../../src/core/textos.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,iFAAiF;AACjF,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB,sFAAsF;AACtF,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAEnC;;;;;;;;;GASG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,MAAM,OAAO,GAAG,KAAK;SAClB,IAAI,EAAE;SACN,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAE;SAClB,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAE;SAC3B,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;SACzB,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC;SAC7B,IAAI,EAAE,CAAC;IACV,IAAI,OAAO,CAAC,MAAM,IAAI,uBAAuB;QAAE,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;IACrF,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,uBAAuB,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACzC,OAAO,GAAG,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,GAAG,CAAC;AAC9F,CAAC"}
1
+ {"version":3,"file":"textos.js","sourceRoot":"","sources":["../../src/core/textos.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,iFAAiF;AACjF,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB,sFAAsF;AACtF,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAEnC;;;;;;;;;GASG;AACH;;;;GAIG;AACH,MAAM,UAAU,GAAG,yCAAyC,CAAC;AAE7D,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IACxF,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAChF,MAAM,OAAO,GAAG,YAAY;SACzB,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;SAC1B,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAE;SAC3B,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;SACzB,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC;SAC7B,IAAI,EAAE,CAAC;IACV,IAAI,OAAO,CAAC,MAAM,IAAI,uBAAuB;QAAE,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;IACrF,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,uBAAuB,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACzC,OAAO,GAAG,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,GAAG,CAAC;AAC9F,CAAC"}