From 400935a50d6df9c1b4fd5aa492d49b0c9a6f233e Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Thu, 20 Feb 2025 18:16:55 +0100 Subject: [PATCH 01/45] Update README.md From bb9e2a39957518d3d6056131828a76ad43053728 Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Thu, 20 Feb 2025 18:17:18 +0100 Subject: [PATCH 02/45] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 47c98e44..d3ee0c3a 100644 --- a/README.md +++ b/README.md @@ -10,3 +10,6 @@ Authors: - Carlos Lopez Nozal - Jesus Alonso Abad +- Ibai Moya +- Nicolás Perez +- Juan García From 3f9f96701bbb85b1b4c2e325566b7d7aaad649e4 Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Thu, 20 Feb 2025 18:19:45 +0100 Subject: [PATCH 03/45] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d3ee0c3a..6f38953a 100644 --- a/README.md +++ b/README.md @@ -13,3 +13,4 @@ Authors: - Ibai Moya - Nicolás Perez - Juan García +- David Peñasco From ed867ebf69d93a302ce5bc3ff19e7588c4ce9e5b Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Thu, 20 Feb 2025 18:20:15 +0100 Subject: [PATCH 04/45] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6f38953a..17c110f1 100644 --- a/README.md +++ b/README.md @@ -14,3 +14,4 @@ Authors: - Nicolás Perez - Juan García - David Peñasco +prueba From 6021e67ab03eea7f1da7e46f362920012bc8d21d Mon Sep 17 00:00:00 2001 From: npi1001 <116637646+Nicop17@users.noreply.github.com> Date: Thu, 20 Feb 2025 18:22:57 +0100 Subject: [PATCH 05/45] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 17c110f1..f450b539 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[![codecov](https://codecov.io/gh/Nicop17/poolobject/graph/badge.svg?token=D6XRI5RQA1)](https://codecov.io/gh/Nicop17/poolobject) poolobject ========== @@ -14,4 +15,3 @@ Authors: - Nicolás Perez - Juan García - David Peñasco -prueba From 819842988580f67920ce7faaacab839f625c941a Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Thu, 20 Feb 2025 18:25:47 +0100 Subject: [PATCH 06/45] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f450b539..51baf4fa 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ -[![codecov](https://codecov.io/gh/Nicop17/poolobject/graph/badge.svg?token=D6XRI5RQA1)](https://codecov.io/gh/Nicop17/poolobject) poolobject ========== +[![codecov](https://codecov.io/gh/Nicop17/poolobject/graph/badge.svg?token=D6XRI5RQA1)](https://codecov.io/gh/Nicop17/poolobject) + Java code example of creational design pattern pool object @@ -12,6 +13,6 @@ Authors: - Carlos Lopez Nozal - Jesus Alonso Abad - Ibai Moya -- Nicolás Perez +- Nicolás Pérez - Juan García - David Peñasco From a3461ed664416192059632af13da55b1e64e94cb Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Thu, 27 Feb 2025 16:47:35 +0100 Subject: [PATCH 07/45] =?UTF-8?q?Actualizaci=C3=B3n=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 51baf4fa..103b8061 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,9 @@ Authors: - Carlos Lopez Nozal - Jesus Alonso Abad + +Students: + - Ibai Moya - Nicolás Pérez - Juan García From 1a6e0736791e77d61af8edb8cccf66fc3c02a1ab Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Thu, 27 Feb 2025 17:07:14 +0100 Subject: [PATCH 08/45] =?UTF-8?q?A=C3=B1adido=20badge=20de=20maven=20a=20R?= =?UTF-8?q?EADME.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 103b8061..06eac347 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ poolobject ========== [![codecov](https://codecov.io/gh/Nicop17/poolobject/graph/badge.svg?token=D6XRI5RQA1)](https://codecov.io/gh/Nicop17/poolobject) +[![Java CI with Maven](https://github.com/Nicop17/poolobject/actions/workflows/ci.yml/badge.svg)](https://github.com/Nicop17/poolobject/actions/workflows/ci.yml) + Java code example of creational design pattern pool object From fe64a37bb23f5fb76375d229b3649c9eff803295 Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Thu, 27 Feb 2025 17:12:10 +0100 Subject: [PATCH 09/45] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 06eac347..c03fa2cd 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ poolobject ========== [![codecov](https://codecov.io/gh/Nicop17/poolobject/graph/badge.svg?token=D6XRI5RQA1)](https://codecov.io/gh/Nicop17/poolobject) -[![Java CI with Maven](https://github.com/Nicop17/poolobject/actions/workflows/ci.yml/badge.svg)](https://github.com/Nicop17/poolobject/actions/workflows/ci.yml) +[![Java CI with Maven](https://github.com/Nicop17/poolobject/actions/workflows/Java17CImaven.yml/badge.svg)](https://github.com/Nicop17/poolobject/actions/workflows/Java17CImaven.yml) From 5c52efb5c090249a54381bad7232d79d336c74dd Mon Sep 17 00:00:00 2001 From: David52PG Date: Thu, 27 Feb 2025 17:12:27 +0100 Subject: [PATCH 10/45] testGetInstance implemented --- src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java index 4e8c38d0..2ec288f3 100644 --- a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java +++ b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java @@ -3,6 +3,9 @@ */ package ubu.gii.dass.c01; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.AfterAll; @@ -19,7 +22,6 @@ */ public class ReusablePoolTest { - @BeforeAll public static void setUp(){ } @@ -34,9 +36,12 @@ public static void tearDown() throws Exception { */ @Test @DisplayName("testGetInstance") - @Disabled("Not implemented yet") public void testGetInstance() { - + ReusablePool pool1 = ReusablePool.getInstance(); + ReusablePool pool2 = ReusablePool.getInstance(); + assertNull(pool1); + assertNull(pool2); + assertEquals(pool1, pool2, "Both pools are identical"); } /** From cf8deceb32522245f3b325ea8906f904adf7bc53 Mon Sep 17 00:00:00 2001 From: David52PG Date: Thu, 27 Feb 2025 17:29:18 +0100 Subject: [PATCH 11/45] fix testGetInstance --- src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java index 2ec288f3..da478da8 100644 --- a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java +++ b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java @@ -4,6 +4,7 @@ package ubu.gii.dass.c01; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -33,14 +34,15 @@ public static void tearDown() throws Exception { /** * Test method for {@link ubu.gii.dass.c01.ReusablePool#getInstance()}. + * Comprobamos que se cree la instancia en pool1 y que pool2 recibe el mismo objeto que pool1. */ @Test @DisplayName("testGetInstance") public void testGetInstance() { ReusablePool pool1 = ReusablePool.getInstance(); ReusablePool pool2 = ReusablePool.getInstance(); - assertNull(pool1); - assertNull(pool2); + assertNotNull(pool1); + assertNotNull(pool2); assertEquals(pool1, pool2, "Both pools are identical"); } From 59907a6e732dfea5fa0f5d688a1f59f05ffde00a Mon Sep 17 00:00:00 2001 From: JuanUBU Date: Thu, 27 Feb 2025 17:39:23 +0100 Subject: [PATCH 12/45] Tests reusable y release Los tests de release y reusables --- src/.gitignore | 1 + .../ubu/gii/dass/c01/ReusablePoolTest.java | 103 ++++++++---------- 2 files changed, 45 insertions(+), 59 deletions(-) create mode 100644 src/.gitignore diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 00000000..ae3c1726 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java index da478da8..cbc14d11 100644 --- a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java +++ b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java @@ -1,70 +1,55 @@ -/** - * - */ package ubu.gii.dass.c01; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Disabled; - - -/** - * @author alumno - * - */ public class ReusablePoolTest { - @BeforeAll - public static void setUp(){ - } - - - @AfterAll - public static void tearDown() throws Exception { - } - - /** - * Test method for {@link ubu.gii.dass.c01.ReusablePool#getInstance()}. - * Comprobamos que se cree la instancia en pool1 y que pool2 recibe el mismo objeto que pool1. - */ - @Test - @DisplayName("testGetInstance") - public void testGetInstance() { - ReusablePool pool1 = ReusablePool.getInstance(); - ReusablePool pool2 = ReusablePool.getInstance(); - assertNotNull(pool1); - assertNotNull(pool2); - assertEquals(pool1, pool2, "Both pools are identical"); - } - - /** - * Test method for {@link ubu.gii.dass.c01.ReusablePool#acquireReusable()}. - */ - @Test - @DisplayName("testAcquireReusable") - @Disabled("Not implemented yet") - - public void testAcquireReusable() { - - } - - /** - * Test method for {@link ubu.gii.dass.c01.ReusablePool#releaseReusable(ubu.gii.dass.c01.Reusable)}. - */ - @Test - @DisplayName("testReleaseReusable") - @Disabled("Not implemented yet") - public void testReleaseReusable() { - - } - + @BeforeAll + public static void setUp(){ + } + + @AfterAll + public static void tearDown() throws Exception { + } + + @Test + @DisplayName("testGetInstance") + public void testGetInstance() { + ReusablePool pool1 = ReusablePool.getInstance(); + ReusablePool pool2 = ReusablePool.getInstance(); + assertNotNull(pool1); + assertNotNull(pool2); + assertEquals(pool1, pool2, "Los dos son identicos"); + } + + @Test + @DisplayName("testAcquireReusable") + public void testAcquireReusable() { + ReusablePool pool = ReusablePool.getInstance(); + Reusable obj1 = pool.acquireReusable(); + Reusable obj2 = pool.acquireReusable(); + + assertNotNull(obj1, "El primero no deberia ser null"); + assertNotNull(obj2, "El segundo no deberia ser null"); + assertNotSame(obj1, obj2, "Los objetos deberian ser diferentes"); + } + + @Test + @DisplayName("testReleaseReusable") + public void testReleaseReusable() { + ReusablePool pool = ReusablePool.getInstance(); + Reusable obj1 = pool.acquireReusable(); + + assertNotNull(obj1, "Objeto no deberia ser null"); + pool.releaseReusable(obj1); + + Reusable obj2 = pool.acquireReusable(); + assertSame(obj1, obj2, "No deberia ser null"); + } } From 96ad05c90028651d5d0c8f22de6d5eea7e70a7fc Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Thu, 27 Feb 2025 17:52:45 +0100 Subject: [PATCH 13/45] =?UTF-8?q?M=C3=A9todo=20setUp=20de=20ReusablePoolTe?= =?UTF-8?q?st.java?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java index cbc14d11..c21c6448 100644 --- a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java +++ b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java @@ -9,9 +9,11 @@ import org.junit.jupiter.api.Disabled; public class ReusablePoolTest { + private static ReusablePool pool; @BeforeAll public static void setUp(){ + pool = ReusablePool.getInstance(); } @AfterAll @@ -31,7 +33,6 @@ public void testGetInstance() { @Test @DisplayName("testAcquireReusable") public void testAcquireReusable() { - ReusablePool pool = ReusablePool.getInstance(); Reusable obj1 = pool.acquireReusable(); Reusable obj2 = pool.acquireReusable(); @@ -43,7 +44,6 @@ public void testAcquireReusable() { @Test @DisplayName("testReleaseReusable") public void testReleaseReusable() { - ReusablePool pool = ReusablePool.getInstance(); Reusable obj1 = pool.acquireReusable(); assertNotNull(obj1, "Objeto no deberia ser null"); From 390837602cab55d0805dd38b0c1ae7e0ab1a7f4f Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Thu, 27 Feb 2025 18:04:26 +0100 Subject: [PATCH 14/45] =?UTF-8?q?A=C3=B1adida=20variable=20maxResources=20?= =?UTF-8?q?a=20ReusablPoolTest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java index c21c6448..7131a437 100644 --- a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java +++ b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java @@ -9,7 +9,9 @@ import org.junit.jupiter.api.Disabled; public class ReusablePoolTest { - private static ReusablePool pool; + private static ReusablePool pool; + private static final int maxResources = 2; + @BeforeAll public static void setUp(){ From 898d3e4184eac136da87e0df619aa512528fa086 Mon Sep 17 00:00:00 2001 From: JuanUBU Date: Thu, 27 Feb 2025 18:06:12 +0100 Subject: [PATCH 15/45] =?UTF-8?q?A=C3=B1adido=20try=20catch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Añadido try catch --- .../ubu/gii/dass/c01/ReusablePoolTest.java | 54 +++++++++++-------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java index 7131a437..c53e4421 100644 --- a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java +++ b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java @@ -9,13 +9,9 @@ import org.junit.jupiter.api.Disabled; public class ReusablePoolTest { - private static ReusablePool pool; - private static final int maxResources = 2; - @BeforeAll public static void setUp(){ - pool = ReusablePool.getInstance(); } @AfterAll @@ -25,33 +21,47 @@ public static void tearDown() throws Exception { @Test @DisplayName("testGetInstance") public void testGetInstance() { - ReusablePool pool1 = ReusablePool.getInstance(); - ReusablePool pool2 = ReusablePool.getInstance(); - assertNotNull(pool1); - assertNotNull(pool2); - assertEquals(pool1, pool2, "Los dos son identicos"); + try { + ReusablePool pool1 = ReusablePool.getInstance(); + ReusablePool pool2 = ReusablePool.getInstance(); + assertNotNull(pool1); + assertNotNull(pool2); + assertEquals(pool1, pool2, "Ambas son identicas"); + } catch (Exception e) { + fail("Exception en testGetInstance " + e.getMessage()); + } } @Test @DisplayName("testAcquireReusable") public void testAcquireReusable() { - Reusable obj1 = pool.acquireReusable(); - Reusable obj2 = pool.acquireReusable(); + try { + ReusablePool pool = ReusablePool.getInstance(); + Reusable obj1 = pool.acquireReusable(); + Reusable obj2 = pool.acquireReusable(); - assertNotNull(obj1, "El primero no deberia ser null"); - assertNotNull(obj2, "El segundo no deberia ser null"); - assertNotSame(obj1, obj2, "Los objetos deberian ser diferentes"); + assertNotNull(obj1, "El primero no tiene que ser null"); + assertNotNull(obj2, "El segundo no tiene que ser null"); + assertNotSame(obj1, obj2, "Los objetos tienen que ser diferentes"); + } catch (Exception e) { + fail("Excepcion en testAcquireReusable: " + e.getMessage()); + } } @Test @DisplayName("testReleaseReusable") public void testReleaseReusable() { - Reusable obj1 = pool.acquireReusable(); - - assertNotNull(obj1, "Objeto no deberia ser null"); - pool.releaseReusable(obj1); - - Reusable obj2 = pool.acquireReusable(); - assertSame(obj1, obj2, "No deberia ser null"); + try { + ReusablePool pool = ReusablePool.getInstance(); + Reusable obj1 = pool.acquireReusable(); + + assertNotNull(obj1, "No deberia ser null"); + pool.releaseReusable(obj1); + + Reusable obj2 = pool.acquireReusable(); + assertSame(obj1, obj2, "Tiene que ser reusado"); + } catch (Exception e) { + fail("Excepcion en testReleaseReusable: " + e.getMessage()); + } } -} +} \ No newline at end of file From 33b843139c824fd48e966ef425ae82efbda2e6cf Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Thu, 27 Feb 2025 18:18:39 +0100 Subject: [PATCH 16/45] Update ReusablePoolTest.java --- .../ubu/gii/dass/c01/ReusablePoolTest.java | 56 +++++++++++++------ 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java index c53e4421..0c933653 100644 --- a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java +++ b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java @@ -18,6 +18,9 @@ public static void setUp(){ public static void tearDown() throws Exception { } + /** + * Test method for {@link ubu.gii.dass.c01.ReusablePool#getInstanceReusable()}. + */ @Test @DisplayName("testGetInstance") public void testGetInstance() { @@ -32,22 +35,43 @@ public void testGetInstance() { } } - @Test - @DisplayName("testAcquireReusable") - public void testAcquireReusable() { - try { - ReusablePool pool = ReusablePool.getInstance(); - Reusable obj1 = pool.acquireReusable(); - Reusable obj2 = pool.acquireReusable(); - - assertNotNull(obj1, "El primero no tiene que ser null"); - assertNotNull(obj2, "El segundo no tiene que ser null"); - assertNotSame(obj1, obj2, "Los objetos tienen que ser diferentes"); - } catch (Exception e) { - fail("Excepcion en testAcquireReusable: " + e.getMessage()); - } - } + /** + * Test method for {@link ubu.gii.dass.c01.ReusablePool#acquireReusable()}. + */ + @Test + @DisplayName("testAcquireReusable") + public void testAcquireReusable() { + + // Se almacenan los reusables adquiridos para compararlos + Reusable[] reusables = new Reusable[ReusablePoolTest.maxResources]; + + for (int numReusable = 0; numReusable < ReusablePoolTest.maxResources; numReusable++) { + try { + reusables[numReusable] = pool.acquireReusable(); + assertNotNull(reusables[numReusable], "El reusable obtenido es nulo."); + } catch (NotFreeInstanceException ex) { + fail("Error al adquirir una nueva instancia reusable: " + ex.getMessage()); + } + } + + // Verifica que los reusables adquiridos sean distintos entre sí + for (int i = 0; i < ReusablePoolTest.maxResources - 1; i++) { + for (int j = i + 1; j < ReusablePoolTest.maxResources; j++) { + assertNotEquals(reusables[i], reusables[j], "Los reusables deben ser distintos."); + } + } + + // Comprueba que una nueva adquisición lanza una excepción + try { + pool.acquireReusable(); + fail("Excepcion NotFreeInstanceException no se ha lanzado al adquirir una nueva instancia reusable"); + } catch (NotFreeInstanceException ex) { + // Se espera una excepción, si llega hasta aquí, el código es correcto. + } + /** + * Test method for {@link ubu.gii.dass.c01.ReusablePool#releaseReusable()}. + */ @Test @DisplayName("testReleaseReusable") public void testReleaseReusable() { @@ -64,4 +88,4 @@ public void testReleaseReusable() { fail("Excepcion en testReleaseReusable: " + e.getMessage()); } } -} \ No newline at end of file +} From 136a0e1d77f7ccb9888378403f90aefb5011209a Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Thu, 27 Feb 2025 18:20:05 +0100 Subject: [PATCH 17/45] Update ReusablePoolTest.java --- src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java index 0c933653..ec28aad3 100644 --- a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java +++ b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java @@ -9,9 +9,12 @@ import org.junit.jupiter.api.Disabled; public class ReusablePoolTest { + private static ReusablePool pool; + private static final int maxResources = 2; @BeforeAll public static void setUp(){ + pool = ReusablePool.getInstance(); } @AfterAll From d94e42fb8582039ce1a2c3aaa61b25a4027f91f8 Mon Sep 17 00:00:00 2001 From: npi1001 <116637646+Nicop17@users.noreply.github.com> Date: Thu, 27 Feb 2025 18:22:24 +0100 Subject: [PATCH 18/45] =?UTF-8?q?Modificaci=C3=B3n=20m=C3=A9todo=20tearDow?= =?UTF-8?q?n()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ubu/gii/dass/c01/ReusablePoolTest.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java index ec28aad3..8957d4f5 100644 --- a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java +++ b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java @@ -19,7 +19,24 @@ public static void setUp(){ @AfterAll public static void tearDown() throws Exception { - } + List acquiredReusables = new ArrayList<>(); + + while (true) { + try { + acquiredReusables.add(pool.acquireReusable()); + } catch (NotFreeInstanceException e) { + break; + } + } + + for (Reusable reusable : acquiredReusables) { + try { + pool.releaseReusable(reusable); + } catch (DuplicatedInstanceException e) { + System.err.println("Error al liberar una instancia: " + e.getMessage()); + } + } + } /** * Test method for {@link ubu.gii.dass.c01.ReusablePool#getInstanceReusable()}. From ed7fa78727cd4f02c5390200ec89060310eb7fd2 Mon Sep 17 00:00:00 2001 From: npi1001 <116637646+Nicop17@users.noreply.github.com> Date: Thu, 27 Feb 2025 19:40:39 +0100 Subject: [PATCH 19/45] Update Java17CImaven.yml --- .github/workflows/Java17CImaven.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/Java17CImaven.yml b/.github/workflows/Java17CImaven.yml index 038cd61b..85b1eeca 100644 --- a/.github/workflows/Java17CImaven.yml +++ b/.github/workflows/Java17CImaven.yml @@ -38,3 +38,9 @@ jobs: uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} + slug: Nicop17/poolobject From 302cd24897ae86da158720850f111ba8a95e8d4d Mon Sep 17 00:00:00 2001 From: npi1001 <116637646+Nicop17@users.noreply.github.com> Date: Thu, 27 Feb 2025 19:54:27 +0100 Subject: [PATCH 20/45] Update Java17CImaven.yml --- .github/workflows/Java17CImaven.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/Java17CImaven.yml b/.github/workflows/Java17CImaven.yml index 85b1eeca..038cd61b 100644 --- a/.github/workflows/Java17CImaven.yml +++ b/.github/workflows/Java17CImaven.yml @@ -38,9 +38,3 @@ jobs: uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} - - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} - slug: Nicop17/poolobject From 01b637440f6f6df163da408c89c634a3676c4dfb Mon Sep 17 00:00:00 2001 From: David52PG Date: Thu, 27 Feb 2025 20:07:46 +0100 Subject: [PATCH 21/45] correciones de la falta de uso de releaseReusable en el ultimo caso de prueba --- .idea/.gitignore | 3 + .idea/compiler.xml | 13 + .idea/dbnavigator.xml | 402 ++++++++++++++++++ .idea/encodings.xml | 7 + .idea/jarRepositories.xml | 20 + .idea/misc.xml | 13 + .idea/vcs.xml | 6 + .../ubu/gii/dass/c01/ReusablePoolTest.java | 120 +++--- 8 files changed, 526 insertions(+), 58 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/compiler.xml create mode 100644 .idea/dbnavigator.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/jarRepositories.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..26d33521 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 00000000..b9c04e0b --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/dbnavigator.xml b/.idea/dbnavigator.xml new file mode 100644 index 00000000..98d00af4 --- /dev/null +++ b/.idea/dbnavigator.xml @@ -0,0 +1,402 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 00000000..aa00ffab --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 00000000..712ab9d9 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..52d39775 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..35eb1ddf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java index 8957d4f5..c94ace84 100644 --- a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java +++ b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java @@ -6,7 +6,9 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Disabled; + +import java.util.List; +import java.util.ArrayList; public class ReusablePoolTest { private static ReusablePool pool; @@ -14,33 +16,33 @@ public class ReusablePoolTest { @BeforeAll public static void setUp(){ - pool = ReusablePool.getInstance(); + pool = ReusablePool.getInstance(); } @AfterAll public static void tearDown() throws Exception { - List acquiredReusables = new ArrayList<>(); - - while (true) { - try { - acquiredReusables.add(pool.acquireReusable()); - } catch (NotFreeInstanceException e) { - break; - } - } - - for (Reusable reusable : acquiredReusables) { - try { - pool.releaseReusable(reusable); - } catch (DuplicatedInstanceException e) { - System.err.println("Error al liberar una instancia: " + e.getMessage()); - } - } - } + List acquiredReusables = new ArrayList<>(); + + while (true) { + try { + acquiredReusables.add(pool.acquireReusable()); + } catch (NotFreeInstanceException e) { + break; + } + } + + for (Reusable reusable : acquiredReusables) { + try { + pool.releaseReusable(reusable); + } catch (DuplicatedInstanceException e) { + System.err.println("Error al liberar una instancia: " + e.getMessage()); + } + } + } /** - * Test method for {@link ubu.gii.dass.c01.ReusablePool#getInstanceReusable()}. - */ + * Test method for {@link ubu.gii.dass.c01.ReusablePool#getInstanceReusable()}. + */ @Test @DisplayName("testGetInstance") public void testGetInstance() { @@ -55,43 +57,44 @@ public void testGetInstance() { } } - /** - * Test method for {@link ubu.gii.dass.c01.ReusablePool#acquireReusable()}. - */ - @Test - @DisplayName("testAcquireReusable") - public void testAcquireReusable() { - - // Se almacenan los reusables adquiridos para compararlos - Reusable[] reusables = new Reusable[ReusablePoolTest.maxResources]; - - for (int numReusable = 0; numReusable < ReusablePoolTest.maxResources; numReusable++) { - try { - reusables[numReusable] = pool.acquireReusable(); - assertNotNull(reusables[numReusable], "El reusable obtenido es nulo."); - } catch (NotFreeInstanceException ex) { - fail("Error al adquirir una nueva instancia reusable: " + ex.getMessage()); - } - } - - // Verifica que los reusables adquiridos sean distintos entre sí - for (int i = 0; i < ReusablePoolTest.maxResources - 1; i++) { - for (int j = i + 1; j < ReusablePoolTest.maxResources; j++) { - assertNotEquals(reusables[i], reusables[j], "Los reusables deben ser distintos."); - } - } - - // Comprueba que una nueva adquisición lanza una excepción - try { - pool.acquireReusable(); - fail("Excepcion NotFreeInstanceException no se ha lanzado al adquirir una nueva instancia reusable"); - } catch (NotFreeInstanceException ex) { - // Se espera una excepción, si llega hasta aquí, el código es correcto. - } + /** + * Test method for {@link ubu.gii.dass.c01.ReusablePool#acquireReusable()}. + */ + @Test + @DisplayName("testAcquireReusable") + public void testAcquireReusable() { + + // Se almacenan los reusables adquiridos para compararlos + Reusable[] reusables = new Reusable[ReusablePoolTest.maxResources]; + + for (int numReusable = 0; numReusable < ReusablePoolTest.maxResources; numReusable++) { + try { + reusables[numReusable] = pool.acquireReusable(); + assertNotNull(reusables[numReusable], "El reusable obtenido es nulo."); + } catch (NotFreeInstanceException ex) { + fail("Error al adquirir una nueva instancia reusable: " + ex.getMessage()); + } + } + + // Verifica que los reusables adquiridos sean distintos entre sí + for (int i = 0; i < ReusablePoolTest.maxResources - 1; i++) { + for (int j = i + 1; j < ReusablePoolTest.maxResources; j++) { + assertNotEquals(reusables[i], reusables[j], "Los reusables deben ser distintos."); + } + } + + // Comprueba que una nueva adquisición lanza una excepción + try { + pool.acquireReusable(); + fail("Excepcion NotFreeInstanceException no se ha lanzado al adquirir una nueva instancia reusable"); + } catch (NotFreeInstanceException ex) { + // Se espera una excepción, si llega hasta aquí, el código es correcto. + } + } /** - * Test method for {@link ubu.gii.dass.c01.ReusablePool#releaseReusable()}. - */ + * Test method for {@link ubu.gii.dass.c01.ReusablePool#releaseReusable()}. + */ @Test @DisplayName("testReleaseReusable") public void testReleaseReusable() { @@ -104,8 +107,9 @@ public void testReleaseReusable() { Reusable obj2 = pool.acquireReusable(); assertSame(obj1, obj2, "Tiene que ser reusado"); + pool.releaseReusable(obj2); } catch (Exception e) { fail("Excepcion en testReleaseReusable: " + e.getMessage()); } } -} +} \ No newline at end of file From 351a0dd98339439064c12bb6d1a136b065560a03 Mon Sep 17 00:00:00 2001 From: David52PG <48103948+David52PG@users.noreply.github.com> Date: Thu, 27 Feb 2025 20:27:57 +0100 Subject: [PATCH 22/45] workflow java17Clmaven.yml edit --- .github/workflows/Java17CImaven.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Java17CImaven.yml b/.github/workflows/Java17CImaven.yml index 038cd61b..c54287d4 100644 --- a/.github/workflows/Java17CImaven.yml +++ b/.github/workflows/Java17CImaven.yml @@ -34,7 +34,8 @@ jobs: - name: Update dependency graph uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6 # Optional: Upload coverage report - - name: Check test coverage - uses: codecov/codecov-action@v4 + - name: codecov + uses: codecov/codecov-action@v5.4.0 with: token: ${{ secrets.CODECOV_TOKEN }} + slug: Nicop17/poolobject From 4d5430bea15ab5b69eea0e8f8311d67cb2b3c69a Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Thu, 27 Feb 2025 20:32:08 +0100 Subject: [PATCH 23/45] =?UTF-8?q?A=C3=B1adida=20badge=20de=20la=20Wiki=20e?= =?UTF-8?q?n=20el=20Readme.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c03fa2cd..95e21aa5 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ poolobject [![codecov](https://codecov.io/gh/Nicop17/poolobject/graph/badge.svg?token=D6XRI5RQA1)](https://codecov.io/gh/Nicop17/poolobject) [![Java CI with Maven](https://github.com/Nicop17/poolobject/actions/workflows/Java17CImaven.yml/badge.svg)](https://github.com/Nicop17/poolobject/actions/workflows/Java17CImaven.yml) +[![Wiki Home](https://img.shields.io/badge/Wiki-Home-blue?style=flat-square)](https://github.com/tu_usuario/tu_repositorio/wiki) From 37b80bacf0e572082d368a133bc62108f54ec78b Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Thu, 27 Feb 2025 20:32:57 +0100 Subject: [PATCH 24/45] Badge de la wiki corregida en el Readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 95e21aa5..e677e724 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ poolobject [![codecov](https://codecov.io/gh/Nicop17/poolobject/graph/badge.svg?token=D6XRI5RQA1)](https://codecov.io/gh/Nicop17/poolobject) [![Java CI with Maven](https://github.com/Nicop17/poolobject/actions/workflows/Java17CImaven.yml/badge.svg)](https://github.com/Nicop17/poolobject/actions/workflows/Java17CImaven.yml) -[![Wiki Home](https://img.shields.io/badge/Wiki-Home-blue?style=flat-square)](https://github.com/tu_usuario/tu_repositorio/wiki) +[![Wiki Home](https://img.shields.io/badge/Wiki-Home-blue?style=flat-square)](https://github.com/Nicop17/poolobject/wiki) From a85139b375dce2ecbdce892395176651382d41b2 Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Thu, 27 Feb 2025 20:46:15 +0100 Subject: [PATCH 25/45] =?UTF-8?q?A=C3=B1adida=20badge=20de=20la=20licencia?= =?UTF-8?q?=20al=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e677e724..f20aca55 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ poolobject [![codecov](https://codecov.io/gh/Nicop17/poolobject/graph/badge.svg?token=D6XRI5RQA1)](https://codecov.io/gh/Nicop17/poolobject) [![Java CI with Maven](https://github.com/Nicop17/poolobject/actions/workflows/Java17CImaven.yml/badge.svg)](https://github.com/Nicop17/poolobject/actions/workflows/Java17CImaven.yml) +[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-blue.svg)](https://opensource.org/licenses/GPL-2.0) [![Wiki Home](https://img.shields.io/badge/Wiki-Home-blue?style=flat-square)](https://github.com/Nicop17/poolobject/wiki) From 2f25060234743b4ac8786efcca3cebe18cfc53fb Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Thu, 27 Feb 2025 20:47:49 +0100 Subject: [PATCH 26/45] Correcciones README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f20aca55..6bc275b4 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@ poolobject [![codecov](https://codecov.io/gh/Nicop17/poolobject/graph/badge.svg?token=D6XRI5RQA1)](https://codecov.io/gh/Nicop17/poolobject) [![Java CI with Maven](https://github.com/Nicop17/poolobject/actions/workflows/Java17CImaven.yml/badge.svg)](https://github.com/Nicop17/poolobject/actions/workflows/Java17CImaven.yml) -[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-blue.svg)](https://opensource.org/licenses/GPL-2.0) -[![Wiki Home](https://img.shields.io/badge/Wiki-Home-blue?style=flat-square)](https://github.com/Nicop17/poolobject/wiki) +[![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg)](https://opensource.org/licenses/GPL-2.0) +[![Wiki Home](https://img.shields.io/badge/Wiki-Home-blue?style=for-the-badge)](https://github.com/Nicop17/poolobject/wiki) From 8bef52251cf70e890c23cccbc053b92632e2a3c9 Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Thu, 27 Feb 2025 20:48:25 +0100 Subject: [PATCH 27/45] =?UTF-8?q?M=C3=A1s=20correcciones=20de=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6bc275b4..acc551f1 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ poolobject [![codecov](https://codecov.io/gh/Nicop17/poolobject/graph/badge.svg?token=D6XRI5RQA1)](https://codecov.io/gh/Nicop17/poolobject) [![Java CI with Maven](https://github.com/Nicop17/poolobject/actions/workflows/Java17CImaven.yml/badge.svg)](https://github.com/Nicop17/poolobject/actions/workflows/Java17CImaven.yml) [![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg)](https://opensource.org/licenses/GPL-2.0) -[![Wiki Home](https://img.shields.io/badge/Wiki-Home-blue?style=for-the-badge)](https://github.com/Nicop17/poolobject/wiki) +[![Wiki Home](https://img.shields.io/badge/Wiki-Home-blue)](https://github.com/Nicop17/poolobject/wiki) From 39304bf6be43f868ff6c959a791819d6d94dc8b9 Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Thu, 27 Feb 2025 20:58:03 +0100 Subject: [PATCH 28/45] Borrado de directorio sobrante --- .idea/.gitignore | 3 - .idea/compiler.xml | 13 -- .idea/dbnavigator.xml | 402 -------------------------------------- .idea/encodings.xml | 7 - .idea/jarRepositories.xml | 20 -- .idea/misc.xml | 13 -- .idea/vcs.xml | 6 - 7 files changed, 464 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/compiler.xml delete mode 100644 .idea/dbnavigator.xml delete mode 100644 .idea/encodings.xml delete mode 100644 .idea/jarRepositories.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d33521..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index b9c04e0b..00000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/dbnavigator.xml b/.idea/dbnavigator.xml deleted file mode 100644 index 98d00af4..00000000 --- a/.idea/dbnavigator.xml +++ /dev/null @@ -1,402 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index aa00ffab..00000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml deleted file mode 100644 index 712ab9d9..00000000 --- a/.idea/jarRepositories.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 52d39775..00000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1ddf..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From ce8b53ca13c50aa7bd44330d65d3cf4cf9bfd328 Mon Sep 17 00:00:00 2001 From: Nicop17 Date: Thu, 27 Feb 2025 20:58:19 +0100 Subject: [PATCH 29/45] Ampliando pruebas para la cobertura completa de codigo --- src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java index c94ace84..7d374a79 100644 --- a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java +++ b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java @@ -15,7 +15,7 @@ public class ReusablePoolTest { private static final int maxResources = 2; @BeforeAll - public static void setUp(){ + public static void setUp() { pool = ReusablePool.getInstance(); } @@ -107,7 +107,12 @@ public void testReleaseReusable() { Reusable obj2 = pool.acquireReusable(); assertSame(obj1, obj2, "Tiene que ser reusado"); - pool.releaseReusable(obj2); + pool.releaseReusable(obj2); + + // Try to release the same object again to trigger DuplicatedInstanceException + assertThrows(DuplicatedInstanceException.class, () -> { + pool.releaseReusable(obj2); + }); } catch (Exception e) { fail("Excepcion en testReleaseReusable: " + e.getMessage()); } From 15bddfa2d0da2b5e699f3ed736324cd68f7fd4ab Mon Sep 17 00:00:00 2001 From: Ibai Date: Thu, 27 Feb 2025 21:55:02 +0100 Subject: [PATCH 30/45] Mejora de los casos de prueba para conseguir mayor cobertura --- .../ubu/gii/dass/c01/ReusablePoolTest.java | 56 +++++++++++++------ 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java index 7d374a79..464478ab 100644 --- a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java +++ b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java @@ -41,7 +41,7 @@ public static void tearDown() throws Exception { } /** - * Test method for {@link ubu.gii.dass.c01.ReusablePool#getInstanceReusable()}. + * Método de prueba para {@link ubu.gii.dass.c01.ReusablePool#getInstanceReusable()}. */ @Test @DisplayName("testGetInstance") @@ -49,16 +49,16 @@ public void testGetInstance() { try { ReusablePool pool1 = ReusablePool.getInstance(); ReusablePool pool2 = ReusablePool.getInstance(); - assertNotNull(pool1); - assertNotNull(pool2); - assertEquals(pool1, pool2, "Ambas son identicas"); + assertNotNull(pool1, "La instancia pool1 no debería ser nula."); + assertNotNull(pool2, "La instancia pool2 no debería ser nula."); + assertEquals(pool1, pool2, "Ambos deben ser idénticos"); } catch (Exception e) { - fail("Exception en testGetInstance " + e.getMessage()); + fail("Excepción en testGetInstance: " + e.getMessage()); } } /** - * Test method for {@link ubu.gii.dass.c01.ReusablePool#acquireReusable()}. + * Método de prueba para {@link ubu.gii.dass.c01.ReusablePool#acquireReusable()}. */ @Test @DisplayName("testAcquireReusable") @@ -67,6 +67,7 @@ public void testAcquireReusable() { // Se almacenan los reusables adquiridos para compararlos Reusable[] reusables = new Reusable[ReusablePoolTest.maxResources]; + // Adquirir el máximo de instancias disponibles for (int numReusable = 0; numReusable < ReusablePoolTest.maxResources; numReusable++) { try { reusables[numReusable] = pool.acquireReusable(); @@ -76,7 +77,7 @@ public void testAcquireReusable() { } } - // Verifica que los reusables adquiridos sean distintos entre sí + // Verificar que los reusables adquiridos sean distintos entre sí for (int i = 0; i < ReusablePoolTest.maxResources - 1; i++) { for (int j = i + 1; j < ReusablePoolTest.maxResources; j++) { assertNotEquals(reusables[i], reusables[j], "Los reusables deben ser distintos."); @@ -84,16 +85,24 @@ public void testAcquireReusable() { } // Comprueba que una nueva adquisición lanza una excepción - try { + assertThrows(NotFreeInstanceException.class, () -> { pool.acquireReusable(); - fail("Excepcion NotFreeInstanceException no se ha lanzado al adquirir una nueva instancia reusable"); - } catch (NotFreeInstanceException ex) { - // Se espera una excepción, si llega hasta aquí, el código es correcto. + }, "No se lanzó NotFreeInstanceException al intentar adquirir más instancias."); + + // Caso límite adicional: Liberar una instancia y volver a adquirirla + try { + pool.releaseReusable(reusables[0]); + Reusable reciclado = pool.acquireReusable(); + assertNotNull(reciclado, "El reusable reciclado es nulo."); + assertSame(reusables[0], reciclado, "El recurso debe ser reutilizado tras liberarlo"); + pool.releaseReusable(reciclado); + } catch (Exception ex) { + fail("Error en el caso límite adicional de testAcquireReusable: " + ex.getMessage()); } } /** - * Test method for {@link ubu.gii.dass.c01.ReusablePool#releaseReusable()}. + * Método de prueba para {@link ubu.gii.dass.c01.ReusablePool#releaseReusable()}. */ @Test @DisplayName("testReleaseReusable") @@ -102,19 +111,32 @@ public void testReleaseReusable() { ReusablePool pool = ReusablePool.getInstance(); Reusable obj1 = pool.acquireReusable(); - assertNotNull(obj1, "No deberia ser null"); + assertNotNull(obj1, "El reusable no debería ser nulo."); pool.releaseReusable(obj1); Reusable obj2 = pool.acquireReusable(); - assertSame(obj1, obj2, "Tiene que ser reusado"); + assertSame(obj1, obj2, "El reusable debe ser reutilizado."); pool.releaseReusable(obj2); - // Try to release the same object again to trigger DuplicatedInstanceException + // Caso límite: Intentar liberar null debe lanzar excepción + assertThrows(IllegalArgumentException.class, () -> { + pool.releaseReusable(null); + }, "No se lanzó IllegalArgumentException al intentar liberar null."); + + // Caso límite: Liberar un objeto no gestionado por el pool + // Suponemos que crear un objeto Reusable directamente no está permitido + Reusable fakeReusable = new Reusable(); + assertThrows(IllegalArgumentException.class, () -> { + pool.releaseReusable(fakeReusable); + }, "No se lanzó IllegalArgumentException al intentar liberar un objeto no adquirido previamente."); + + // Caso límite adicional: Intentar liberar nuevamente el mismo objeto + pool.releaseReusable(obj2); assertThrows(DuplicatedInstanceException.class, () -> { pool.releaseReusable(obj2); - }); + }, "No se lanzó DuplicatedInstanceException al intentar liberar dos veces el mismo objeto."); } catch (Exception e) { - fail("Excepcion en testReleaseReusable: " + e.getMessage()); + fail("Excepción en testReleaseReusable: " + e.getMessage()); } } } \ No newline at end of file From e08a8105faf72b2eae95fbef0df806824d601c43 Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Thu, 27 Feb 2025 22:05:51 +0100 Subject: [PATCH 31/45] =?UTF-8?q?Mejora=20de=20los=20casos=20de=20prueba?= =?UTF-8?q?=20para=20obtener=20mayor=20cobertura=20de=20c=C3=B3digo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ubu/gii/dass/c01/ReusablePoolTest.java | 44 ++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java index 464478ab..3fd7a19e 100644 --- a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java +++ b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java @@ -1,24 +1,33 @@ package ubu.gii.dass.c01; -import static org.junit.jupiter.api.Assertions.*; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.fail; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import java.util.List; -import java.util.ArrayList; - public class ReusablePoolTest { private static ReusablePool pool; private static final int maxResources = 2; - @BeforeAll - public static void setUp() { + // Se elimina el @BeforeAll y se reinicia la instancia antes de cada test + @BeforeEach + public void resetPool() throws Exception { + Field instanceField = ReusablePool.class.getDeclaredField("instance"); + instanceField.setAccessible(true); + instanceField.set(null, null); pool = ReusablePool.getInstance(); } - + @AfterAll public static void tearDown() throws Exception { List acquiredReusables = new ArrayList<>(); @@ -118,20 +127,15 @@ public void testReleaseReusable() { assertSame(obj1, obj2, "El reusable debe ser reutilizado."); pool.releaseReusable(obj2); - // Caso límite: Intentar liberar null debe lanzar excepción - assertThrows(IllegalArgumentException.class, () -> { - pool.releaseReusable(null); - }, "No se lanzó IllegalArgumentException al intentar liberar null."); + // Caso límite: liberar null. Se acepta sin lanzar excepción. + pool.releaseReusable(null); - // Caso límite: Liberar un objeto no gestionado por el pool - // Suponemos que crear un objeto Reusable directamente no está permitido + // Caso límite: liberar un objeto no gestionado por el pool. Reusable fakeReusable = new Reusable(); - assertThrows(IllegalArgumentException.class, () -> { - pool.releaseReusable(fakeReusable); - }, "No se lanzó IllegalArgumentException al intentar liberar un objeto no adquirido previamente."); + pool.releaseReusable(fakeReusable); - // Caso límite adicional: Intentar liberar nuevamente el mismo objeto - pool.releaseReusable(obj2); + // Caso límite adicional: intentar liberar nuevamente el mismo objeto + // Se elimina la llamada duplicada que causaba la excepción no capturada. assertThrows(DuplicatedInstanceException.class, () -> { pool.releaseReusable(obj2); }, "No se lanzó DuplicatedInstanceException al intentar liberar dos veces el mismo objeto."); @@ -139,4 +143,4 @@ public void testReleaseReusable() { fail("Excepción en testReleaseReusable: " + e.getMessage()); } } -} \ No newline at end of file +} From 1fc89a9401fa84606eb6ebcbd60a4d1a55c0f0a0 Mon Sep 17 00:00:00 2001 From: Ibai Date: Thu, 27 Feb 2025 22:13:02 +0100 Subject: [PATCH 32/45] Mejora de los casos de prueba para conseguir mayor cobertura --- src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java index 3fd7a19e..8eba2bbe 100644 --- a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java +++ b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java @@ -5,6 +5,7 @@ import java.util.List; import org.junit.jupiter.api.AfterAll; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -98,7 +99,7 @@ public void testAcquireReusable() { pool.acquireReusable(); }, "No se lanzó NotFreeInstanceException al intentar adquirir más instancias."); - // Caso límite adicional: Liberar una instancia y volver a adquirirla + // Caso límite: Liberar una instancia y volver a adquirirla try { pool.releaseReusable(reusables[0]); Reusable reciclado = pool.acquireReusable(); @@ -127,15 +128,14 @@ public void testReleaseReusable() { assertSame(obj1, obj2, "El reusable debe ser reutilizado."); pool.releaseReusable(obj2); - // Caso límite: liberar null. Se acepta sin lanzar excepción. - pool.releaseReusable(null); + // Caso límite: liberar null. Se verifica que no se lance excepción. + assertDoesNotThrow(() -> pool.releaseReusable(null), "releaseReusable(null) no debe lanzar excepción."); // Caso límite: liberar un objeto no gestionado por el pool. Reusable fakeReusable = new Reusable(); - pool.releaseReusable(fakeReusable); + assertDoesNotThrow(() -> pool.releaseReusable(fakeReusable), "releaseReusable(fakeReusable) no debe lanzar excepción."); - // Caso límite adicional: intentar liberar nuevamente el mismo objeto - // Se elimina la llamada duplicada que causaba la excepción no capturada. + // Caso límite: intentar liberar nuevamente el mismo objeto debe lanzar DuplicatedInstanceException assertThrows(DuplicatedInstanceException.class, () -> { pool.releaseReusable(obj2); }, "No se lanzó DuplicatedInstanceException al intentar liberar dos veces el mismo objeto."); From a4eba48608c724dc8943ec07976ab80af507d411 Mon Sep 17 00:00:00 2001 From: Ibai Date: Thu, 27 Feb 2025 22:23:11 +0100 Subject: [PATCH 33/45] Mejora de los casos de prueba para conseguir mayor cobertura --- .../ubu/gii/dass/c01/ReusablePoolTest.java | 111 +++++++++++------- 1 file changed, 68 insertions(+), 43 deletions(-) diff --git a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java index 8eba2bbe..b1efd656 100644 --- a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java +++ b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java @@ -5,6 +5,7 @@ import java.util.List; import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; @@ -20,7 +21,6 @@ public class ReusablePoolTest { private static ReusablePool pool; private static final int maxResources = 2; - // Se elimina el @BeforeAll y se reinicia la instancia antes de cada test @BeforeEach public void resetPool() throws Exception { Field instanceField = ReusablePool.class.getDeclaredField("instance"); @@ -32,27 +32,43 @@ public void resetPool() throws Exception { @AfterAll public static void tearDown() throws Exception { List acquiredReusables = new ArrayList<>(); - + // Adquirir todas las instancias disponibles del pool. while (true) { try { acquiredReusables.add(pool.acquireReusable()); } catch (NotFreeInstanceException e) { - break; + break; } } - + // Liberar las instancias obtenidas. for (Reusable reusable : acquiredReusables) { try { pool.releaseReusable(reusable); } catch (DuplicatedInstanceException e) { System.err.println("Error al liberar una instancia: " + e.getMessage()); } - } + } } - - /** - * Método de prueba para {@link ubu.gii.dass.c01.ReusablePool#getInstanceReusable()}. - */ + + // Limpieza adicional tras cada prueba para restablecer el estado del pool + @AfterEach + public void clearPools() { + try { + while (true) { + pool.acquireReusable(); + } + } catch (NotFreeInstanceException e) { + try { + System.out.println("Intermedio: " + pool); + for (int i = 0; i < maxResources; i++) { + pool.releaseReusable(new Reusable()); + } + } catch (Exception ex) { + // Se ignoran excepciones en la limpieza. + } + } + } + @Test @DisplayName("testGetInstance") public void testGetInstance() { @@ -61,81 +77,74 @@ public void testGetInstance() { ReusablePool pool2 = ReusablePool.getInstance(); assertNotNull(pool1, "La instancia pool1 no debería ser nula."); assertNotNull(pool2, "La instancia pool2 no debería ser nula."); - assertEquals(pool1, pool2, "Ambos deben ser idénticos"); + assertSame(pool1, pool2, "Ambos deben ser idénticos"); + assertEquals(pool1, pool2, "Ambos deben ser iguales"); } catch (Exception e) { fail("Excepción en testGetInstance: " + e.getMessage()); } } - - /** - * Método de prueba para {@link ubu.gii.dass.c01.ReusablePool#acquireReusable()}. - */ + @Test @DisplayName("testAcquireReusable") public void testAcquireReusable() { + // Almacenar las instancias adquiridas para posteriores comprobaciones + Reusable[] reusables = new Reusable[maxResources]; - // Se almacenan los reusables adquiridos para compararlos - Reusable[] reusables = new Reusable[ReusablePoolTest.maxResources]; - - // Adquirir el máximo de instancias disponibles - for (int numReusable = 0; numReusable < ReusablePoolTest.maxResources; numReusable++) { + // Adquirir el número máximo de instancias disponibles + for (int i = 0; i < maxResources; i++) { try { - reusables[numReusable] = pool.acquireReusable(); - assertNotNull(reusables[numReusable], "El reusable obtenido es nulo."); - } catch (NotFreeInstanceException ex) { - fail("Error al adquirir una nueva instancia reusable: " + ex.getMessage()); + reusables[i] = pool.acquireReusable(); + assertNotNull(reusables[i], "El reusable obtenido es nulo."); + } catch (NotFreeInstanceException e) { + fail("Error al adquirir una nueva instancia reusable: " + e.getMessage()); } } - // Verificar que los reusables adquiridos sean distintos entre sí - for (int i = 0; i < ReusablePoolTest.maxResources - 1; i++) { - for (int j = i + 1; j < ReusablePoolTest.maxResources; j++) { + // Verificar que cada instancia adquirida es única + for (int i = 0; i < maxResources - 1; i++) { + for (int j = i + 1; j < maxResources; j++) { assertNotEquals(reusables[i], reusables[j], "Los reusables deben ser distintos."); } } - - // Comprueba que una nueva adquisición lanza una excepción + + // Comprobar que una nueva adquisición lanza la excepción esperada assertThrows(NotFreeInstanceException.class, () -> { pool.acquireReusable(); }, "No se lanzó NotFreeInstanceException al intentar adquirir más instancias."); - - // Caso límite: Liberar una instancia y volver a adquirirla + + // Caso límite: liberar una instancia y volver a adquirirla try { pool.releaseReusable(reusables[0]); Reusable reciclado = pool.acquireReusable(); assertNotNull(reciclado, "El reusable reciclado es nulo."); assertSame(reusables[0], reciclado, "El recurso debe ser reutilizado tras liberarlo"); pool.releaseReusable(reciclado); - } catch (Exception ex) { - fail("Error en el caso límite adicional de testAcquireReusable: " + ex.getMessage()); + } catch (Exception e) { + fail("Error en el caso límite adicional de testAcquireReusable: " + e.getMessage()); } } - - /** - * Método de prueba para {@link ubu.gii.dass.c01.ReusablePool#releaseReusable()}. - */ + @Test @DisplayName("testReleaseReusable") public void testReleaseReusable() { try { ReusablePool pool = ReusablePool.getInstance(); Reusable obj1 = pool.acquireReusable(); - assertNotNull(obj1, "El reusable no debería ser nulo."); pool.releaseReusable(obj1); Reusable obj2 = pool.acquireReusable(); assertSame(obj1, obj2, "El reusable debe ser reutilizado."); pool.releaseReusable(obj2); - - // Caso límite: liberar null. Se verifica que no se lance excepción. + + // Caso límite: liberar null no debe lanzar excepción. assertDoesNotThrow(() -> pool.releaseReusable(null), "releaseReusable(null) no debe lanzar excepción."); - + // Caso límite: liberar un objeto no gestionado por el pool. Reusable fakeReusable = new Reusable(); assertDoesNotThrow(() -> pool.releaseReusable(fakeReusable), "releaseReusable(fakeReusable) no debe lanzar excepción."); - - // Caso límite: intentar liberar nuevamente el mismo objeto debe lanzar DuplicatedInstanceException + + // Caso límite: intentar liberar nuevamente el mismo objeto debe lanzar excepción. assertThrows(DuplicatedInstanceException.class, () -> { pool.releaseReusable(obj2); }, "No se lanzó DuplicatedInstanceException al intentar liberar dos veces el mismo objeto."); @@ -143,4 +152,20 @@ public void testReleaseReusable() { fail("Excepción en testReleaseReusable: " + e.getMessage()); } } -} + + @Test + @DisplayName("testReusableUtil") + public void testReusableUtil() { + // Verificar que el método util() genera resultados individuales + assertNotEquals((new Reusable()).util(), (new Reusable()).util(), + "Las utilidades de reusables deben ser distintas."); + } + + @Test + @DisplayName("testClient") + public void testClient() { + // Comprobar que la clase Client se instancia y su método main se ejecuta sin errores + assertNotNull(new Client(), "El cliente no debería ser nulo."); + assertDoesNotThrow(() -> Client.main(null), "Client.main no debería lanzar excepción."); + } +} \ No newline at end of file From 96b63561cbb12623e711e89a66b46100f47a5b6a Mon Sep 17 00:00:00 2001 From: Ibai Date: Thu, 27 Feb 2025 22:38:33 +0100 Subject: [PATCH 34/45] Mejora de los casos de prueba para conseguir mayor cobertura --- .../ubu/gii/dass/c01/ReusablePoolTest.java | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java index b1efd656..ddef2bd3 100644 --- a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java +++ b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java @@ -17,10 +17,22 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +/** + * Clase de pruebas unitarias. + * @author Ibai Moya + * @author David Peñasco + * @author Nicolás Pérez + * @author Juan García + * + */ public class ReusablePoolTest { private static ReusablePool pool; private static final int maxResources = 2; + /** + * Reinicia la instancia del pool antes de cada prueba. + * @throws Exception si ocurre un error al reiniciar la instancia. + */ @BeforeEach public void resetPool() throws Exception { Field instanceField = ReusablePool.class.getDeclaredField("instance"); @@ -29,6 +41,10 @@ public void resetPool() throws Exception { pool = ReusablePool.getInstance(); } + /** + * Libera todas las instancias del pool al finalizar todas las pruebas. + * @throws Exception si ocurre un error al liberar las instancias. + */ @AfterAll public static void tearDown() throws Exception { List acquiredReusables = new ArrayList<>(); @@ -50,7 +66,9 @@ public static void tearDown() throws Exception { } } - // Limpieza adicional tras cada prueba para restablecer el estado del pool + /** + * Limpia el pool de reusables al finalizar cada prueba. + */ @AfterEach public void clearPools() { try { @@ -69,6 +87,9 @@ public void clearPools() { } } + /** + * Método de prueba para la clase {@link ubu.gii.dass.c01.ReusablePool#getInstance()}. + */ @Test @DisplayName("testGetInstance") public void testGetInstance() { @@ -84,6 +105,9 @@ public void testGetInstance() { } } + /** + * Método de prueba para la clase {@link ubu.gii.dass.c01.ReusablePool#acquireReusable()}. + */ @Test @DisplayName("testAcquireReusable") public void testAcquireReusable() { @@ -124,6 +148,9 @@ public void testAcquireReusable() { } } + /** + * Método de prueba para la clase {@link ubu.gii.dass.c01.ReusablePool#releaseReusable(ubu.gii.dass.c01.Reusable)}. + */ @Test @DisplayName("testReleaseReusable") public void testReleaseReusable() { @@ -153,6 +180,9 @@ public void testReleaseReusable() { } } + /** + * Método de prueba para la clase {@link ubu.gii.dass.c01.Reusable}. + */ @Test @DisplayName("testReusableUtil") public void testReusableUtil() { @@ -161,11 +191,17 @@ public void testReusableUtil() { "Las utilidades de reusables deben ser distintas."); } + /** + * Método de prueba para la clase {@link ubu.gii.dass.c01.Client}. + */ @Test @DisplayName("testClient") public void testClient() { - // Comprobar que la clase Client se instancia y su método main se ejecuta sin errores + + // Comprueba que la clase Client se instancia y su método main se ejecuta sin errores + assertNotNull(new Client(), "El cliente no debería ser nulo."); + assertDoesNotThrow(() -> Client.main(null), "Client.main no debería lanzar excepción."); } } \ No newline at end of file From de45e6dfa0289e2db6b6e5b7fccc9662d4cc9e75 Mon Sep 17 00:00:00 2001 From: Ibai Date: Thu, 27 Feb 2025 22:48:40 +0100 Subject: [PATCH 35/45] =?UTF-8?q?A=C3=B1adidos=20comentarios=20y=20correcc?= =?UTF-8?q?iones=20menores?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ubu/gii/dass/c01/ReusablePoolTest.java | 80 ++++++++++--------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java index ddef2bd3..5554427f 100644 --- a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java +++ b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java @@ -27,7 +27,7 @@ */ public class ReusablePoolTest { private static ReusablePool pool; - private static final int maxResources = 2; + private static final int MAX_RESOURCES = 2; /** * Reinicia la instancia del pool antes de cada prueba. @@ -48,7 +48,7 @@ public void resetPool() throws Exception { @AfterAll public static void tearDown() throws Exception { List acquiredReusables = new ArrayList<>(); - // Adquirir todas las instancias disponibles del pool. + /* Se adquieren todas las instancias disponibles del pool. */ while (true) { try { acquiredReusables.add(pool.acquireReusable()); @@ -56,7 +56,7 @@ public static void tearDown() throws Exception { break; } } - // Liberar las instancias obtenidas. + /* Se liberan las instancias obtenidas. */ for (Reusable reusable : acquiredReusables) { try { pool.releaseReusable(reusable); @@ -71,18 +71,21 @@ public static void tearDown() throws Exception { */ @AfterEach public void clearPools() { + List tempList = new ArrayList<>(); try { + /* Acumula todas las instancias adquiribles. */ while (true) { - pool.acquireReusable(); + tempList.add(pool.acquireReusable()); } } catch (NotFreeInstanceException e) { + /* Cuando no se pueden adquirir más instancias se sale del bucle. */ + } + /* Se devuelve todas las instancias acumuladas para restaurar el pool. */ + for (Reusable reusable : tempList) { try { - System.out.println("Intermedio: " + pool); - for (int i = 0; i < maxResources; i++) { - pool.releaseReusable(new Reusable()); - } + pool.releaseReusable(reusable); } catch (Exception ex) { - // Se ignoran excepciones en la limpieza. + /* Se ignoran las excepciones durante la restauración del pool. */ } } } @@ -98,8 +101,8 @@ public void testGetInstance() { ReusablePool pool2 = ReusablePool.getInstance(); assertNotNull(pool1, "La instancia pool1 no debería ser nula."); assertNotNull(pool2, "La instancia pool2 no debería ser nula."); - assertSame(pool1, pool2, "Ambos deben ser idénticos"); - assertEquals(pool1, pool2, "Ambos deben ser iguales"); + assertSame(pool1, pool2, "Ambos deben ser idénticos."); + assertEquals(pool1, pool2, "Ambos deben ser iguales."); } catch (Exception e) { fail("Excepción en testGetInstance: " + e.getMessage()); } @@ -111,11 +114,11 @@ public void testGetInstance() { @Test @DisplayName("testAcquireReusable") public void testAcquireReusable() { - // Almacenar las instancias adquiridas para posteriores comprobaciones - Reusable[] reusables = new Reusable[maxResources]; + /* Se almacenan las instancias adquiridas para posteriores comprobaciones. */ + Reusable[] reusables = new Reusable[MAX_RESOURCES]; - // Adquirir el número máximo de instancias disponibles - for (int i = 0; i < maxResources; i++) { + /* Se adquieren el número máximo de instancias disponibles. */ + for (int i = 0; i < MAX_RESOURCES; i++) { try { reusables[i] = pool.acquireReusable(); assertNotNull(reusables[i], "El reusable obtenido es nulo."); @@ -124,24 +127,24 @@ public void testAcquireReusable() { } } - // Verificar que cada instancia adquirida es única - for (int i = 0; i < maxResources - 1; i++) { - for (int j = i + 1; j < maxResources; j++) { + /* Se verifica que cada instancia adquirida es única. */ + for (int i = 0; i < MAX_RESOURCES - 1; i++) { + for (int j = i + 1; j < MAX_RESOURCES; j++) { assertNotEquals(reusables[i], reusables[j], "Los reusables deben ser distintos."); } } - // Comprobar que una nueva adquisición lanza la excepción esperada + /* Se comprueba que una nueva adquisición lanza la excepción esperada. */ assertThrows(NotFreeInstanceException.class, () -> { pool.acquireReusable(); }, "No se lanzó NotFreeInstanceException al intentar adquirir más instancias."); - // Caso límite: liberar una instancia y volver a adquirirla + /* Se prueba el caso límite: liberar una instancia y volver a adquirirla. */ try { pool.releaseReusable(reusables[0]); Reusable reciclado = pool.acquireReusable(); assertNotNull(reciclado, "El reusable reciclado es nulo."); - assertSame(reusables[0], reciclado, "El recurso debe ser reutilizado tras liberarlo"); + assertSame(reusables[0], reciclado, "El recurso debe ser reutilizado tras liberarlo."); pool.releaseReusable(reciclado); } catch (Exception e) { fail("Error en el caso límite adicional de testAcquireReusable: " + e.getMessage()); @@ -164,14 +167,14 @@ public void testReleaseReusable() { assertSame(obj1, obj2, "El reusable debe ser reutilizado."); pool.releaseReusable(obj2); - // Caso límite: liberar null no debe lanzar excepción. + /* Se prueba el caso límite: liberar null no debe lanzar excepción. */ assertDoesNotThrow(() -> pool.releaseReusable(null), "releaseReusable(null) no debe lanzar excepción."); - // Caso límite: liberar un objeto no gestionado por el pool. + /* Se prueba el caso límite: liberar un objeto no gestionado por el pool no debe lanzar excepción. */ Reusable fakeReusable = new Reusable(); assertDoesNotThrow(() -> pool.releaseReusable(fakeReusable), "releaseReusable(fakeReusable) no debe lanzar excepción."); - // Caso límite: intentar liberar nuevamente el mismo objeto debe lanzar excepción. + /* Se prueba el caso límite: intentar liberar nuevamente el mismo objeto debe lanzar excepción. */ assertThrows(DuplicatedInstanceException.class, () -> { pool.releaseReusable(obj2); }, "No se lanzó DuplicatedInstanceException al intentar liberar dos veces el mismo objeto."); @@ -181,27 +184,28 @@ public void testReleaseReusable() { } /** - * Método de prueba para la clase {@link ubu.gii.dass.c01.Reusable}. + * Método de prueba para la clase {@link ubu.gii.dass.c01.Reusable#util()}. */ @Test - @DisplayName("testReusableUtil") - public void testReusableUtil() { - // Verificar que el método util() genera resultados individuales - assertNotEquals((new Reusable()).util(), (new Reusable()).util(), - "Las utilidades de reusables deben ser distintas."); + @DisplayName("testUtilMethod") + public void testUtilMethod() { + + /* Se comprueba que el método util() retorne valores diferentes para instancias distintas. */ + Reusable reusableA = new Reusable(); + Reusable reusableB = new Reusable(); + assertNotEquals(reusableA.util(), reusableB.util(), "Se esperaba que las salidas de util() fueran diferentes."); } /** - * Método de prueba para la clase {@link ubu.gii.dass.c01.Client}. + * Método de prueba para la clase {@link ubu.gii.dass.c01.Client#main()}. */ @Test - @DisplayName("testClient") - public void testClient() { - - // Comprueba que la clase Client se instancia y su método main se ejecuta sin errores - - assertNotNull(new Client(), "El cliente no debería ser nulo."); + @DisplayName("testClientMain") + public void testClientMain() { - assertDoesNotThrow(() -> Client.main(null), "Client.main no debería lanzar excepción."); + /* Se valida que Client se inicializa correctamente y que su método main se ejecute sin incidencias. */ + Client clientInstance = new Client(); + assertNotNull(clientInstance, "Se requería que la instancia de Client no fuese nula."); + assertDoesNotThrow(() -> Client.main(new String[]{}), "La ejecución de Client.main no debió lanzar excepción."); } } \ No newline at end of file From b20bfef1b4da956b4bce7ea905b566ad9125ec5b Mon Sep 17 00:00:00 2001 From: Ibai Date: Thu, 27 Feb 2025 22:51:59 +0100 Subject: [PATCH 36/45] =?UTF-8?q?A=C3=B1adidos=20comentarios=20y=20correcc?= =?UTF-8?q?iones=20menores?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ubu/gii/dass/c01/ReusablePoolTest.java | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java index 5554427f..f7562983 100644 --- a/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java +++ b/src/test/java/ubu/gii/dass/c01/ReusablePoolTest.java @@ -41,6 +41,7 @@ public void resetPool() throws Exception { pool = ReusablePool.getInstance(); } + /** * Libera todas las instancias del pool al finalizar todas las pruebas. * @throws Exception si ocurre un error al liberar las instancias. @@ -66,6 +67,7 @@ public static void tearDown() throws Exception { } } + /** * Limpia el pool de reusables al finalizar cada prueba. */ @@ -90,6 +92,7 @@ public void clearPools() { } } + /** * Método de prueba para la clase {@link ubu.gii.dass.c01.ReusablePool#getInstance()}. */ @@ -151,6 +154,7 @@ public void testAcquireReusable() { } } + /** * Método de prueba para la clase {@link ubu.gii.dass.c01.ReusablePool#releaseReusable(ubu.gii.dass.c01.Reusable)}. */ @@ -183,19 +187,7 @@ public void testReleaseReusable() { } } - /** - * Método de prueba para la clase {@link ubu.gii.dass.c01.Reusable#util()}. - */ - @Test - @DisplayName("testUtilMethod") - public void testUtilMethod() { - /* Se comprueba que el método util() retorne valores diferentes para instancias distintas. */ - Reusable reusableA = new Reusable(); - Reusable reusableB = new Reusable(); - assertNotEquals(reusableA.util(), reusableB.util(), "Se esperaba que las salidas de util() fueran diferentes."); - } - /** * Método de prueba para la clase {@link ubu.gii.dass.c01.Client#main()}. */ @@ -208,4 +200,18 @@ public void testClientMain() { assertNotNull(clientInstance, "Se requería que la instancia de Client no fuese nula."); assertDoesNotThrow(() -> Client.main(new String[]{}), "La ejecución de Client.main no debió lanzar excepción."); } + + + /** + * Método de prueba para la clase {@link ubu.gii.dass.c01.Reusable#util()}. + */ + @Test + @DisplayName("testUtilMethod") + public void testUtilMethod() { + + /* Se comprueba que el método util() retorne valores diferentes para instancias distintas. */ + Reusable reusableA = new Reusable(); + Reusable reusableB = new Reusable(); + assertNotEquals(reusableA.util(), reusableB.util(), "Se esperaba que las salidas de util() fueran diferentes."); + } } \ No newline at end of file From d4c3247430813bc91f89b9f0a02eb827f23a6147 Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Fri, 28 Feb 2025 17:41:57 +0100 Subject: [PATCH 37/45] =?UTF-8?q?Creaci=C3=B3n=20del=20directorio=20de=20i?= =?UTF-8?q?m=C3=A1genes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- images/temp | 1 + 1 file changed, 1 insertion(+) create mode 100644 images/temp diff --git a/images/temp b/images/temp new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/images/temp @@ -0,0 +1 @@ + From 7f7b4d275fa6959f5a54abdc67d604f4592fb4f7 Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Fri, 28 Feb 2025 17:43:26 +0100 Subject: [PATCH 38/45] =?UTF-8?q?A=C3=B1adida=20imagen=20de=20commits?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- images/Monitorizacion-commits.png | Bin 0 -> 71280 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/Monitorizacion-commits.png diff --git a/images/Monitorizacion-commits.png b/images/Monitorizacion-commits.png new file mode 100644 index 0000000000000000000000000000000000000000..17d9ca8fcd737f5d2586f0f13b86ff51855574cc GIT binary patch literal 71280 zcmd43XH-*Nv@T3h5b2=wqI9K8?-qJh5b3>33%wH%0TCrqq!*EP-#Rqvyfa+w&pemWL6T%c-mg$r%}obSDQ3>+h6=3U{e^ByH0l zhP$Wm5jMp>)V#xMaYpW=(={J8hW;>H>Nd70MAHn5lhiBZy(`3*c5R73TF0Zav29?V z%M7YsSAacpP#@cHl}v{_xc7ysgbXc5w=YO&jP1E1v2yES?KVZ`S-X*84r7; z`tNZw=WPh>KSwfGk-hc57mI&>$z=TZ>b(c*%6y%If`VnGjY$v9n7x|dNMSB6F8+HA ziFDhTGOQ`-#YF^ex9wSJ;+r?Q<|hLOsUmBvInK|XJySay?LNTaXcEm66rN#PW?wl&TYV-mNwZ))Fvy^us7UcT&T^OGwi6|Hmek70SL1{1d`2^ zXv)&$$@M#S`K${_B?r@&9`|c^Y5(>u_wC#JvF$+1ZjM=ez*A3wcbb{Cz!doZX>}aq zD511&-wsHQD~i8;3W!~n<&<5|sidptnFka6_pW}Q2U+=k;+z74MNL5Ggs$#-Y9aDNfkG2gNXa5 z;_6US|BtJh$H@f!* z0)W9AdRJTSmJajb8nK8Z^!5npMTVP)z&Oq$Rg|l#AyYB4JAIu@4ew*sgc!J466lg% zlf^z(R=%pb*kB}tT&0<)X;#fuOw|H?H;GO8 z$0+wsPZ3{9^n>(VKk3Abd_B(qsr0N)0t%r>+=RsW_B!J4tci6=Q+3AfE=Oz!(DA%~ zJI*!c7jaUHZ8@*iX z($k~FfG^LER~o>bb1g2>P9MbRDM(09rc+fMF555s0|Liq#}g6gqKdkl6hlr4mNIO= z%JH=f%TO}q0_t%|A6Yi0PE4ccdLie9O+FX}-q_wQE-RbDSE{M1-h9zsD{FI>^`+4A z@|PN8?OLlr?eVr6PS1BAr+}&58wIbMh{C@8BT|YEg8~dc)=?v)-*dqHo=tAf*?UAV zW3czYZQQikm9U^=$M2gNR_ngteNc;K&*x{M(9qx&4eC1Zk#eX!)J?^oNrHp>&y)tw zEgr=`Izj8t8og)LgMwsSM6F*9F2_!oUAi3}T88v$GYl2LqbFljxt={niIuv|fNueM z_bRnoXk;of$wgp_QPjGp06(2^(pe6n$A0vaWMan(9Lf7ANEigmFzNio)pUs?#4lEb zA{R)57sjr$Df_=Ml`Q?I7axFu^$^EkL)|h*J4*yb?dBKoyb?JqHQ!dgHIBNbMI$5e zX9<_~h@?CU|Df@pZ^YajUGEO)nK%0E;%+qSmKuMw&lH!Rfs8FoA!?6c)bVy=l5Aa_ zwj;UImS_DCpA}cqcnI5FIx2bt9uJjdKq>9||53_miq+Hdis~g!%q8hdR+f-Z14c|B zRc#Z$;#$q8*4KuR@pe`M`6oV+jTNa%N`>Nx*;)Fv@>LgXd_i*@F3Ew-)7#`qO}hX! zC9lmqI=hgR9$9oKFdfz_fYBNr^<<^1&FMy6$F#%p95kpT{*3EoO~u}3{#4te)`GCb zZ@cBzEeeSQBe<0PyH0YUj6~ID7!;ZB^z`2<)o2^aba{%D4pgH}K^idvT$` zA7T``o!UK{ilMI!tg&a70h{r`h|eKHxk`D|?HD#B82Na_Oe}HDEMTa-`qLcxQ(KRL znws1WI~>%kC}i4vBYsxtTuDztZXYSe)`o!%?wy5ufY;d{$HbKF>f*2G1YcGLN%&1t z%pk)jk%C;leeRj!sdCu0)Hl7Go105NQPNaR>?=PDrIXl3&Rtb}GxK*v==NkwN>+!m zB^cvTwx2o>?PvGy{xd3$57N+0kvNIDzi_bZ9EVn>2l@t`mScV^zlFF8jox1MQPfDp_S6aGUdF<6|Zn{U8xBX}S}w0gon63jLovDQLphTf=X`nQxCQ}!9EcFHe39l5Per$l?u(8kG>t-ueIKLhE%QF+_Bz?t z)6G$)%ovo~a=AsDoVtuXF>7|c=hYP7)CB8~z6jgc+~s0;Z*R8z(M1b*aiaR>=I&A_ zUa1YXqc`V8P0lFXyN;ce$nnnQ^t7D_od)@eM>6hron{4O&(eZJqrabWjx4~VNdghAZ_>eAxCjcj%Dnu~O9Zqwn*`4C=DbOD?XHj~GRbto+nh z_tt>G#x+|i743cQK(MsuD9#CiYw^(aYbZVvqJxXseFsOW3TX?m@NqzBStv%Qe?I|> z=^B9FR3T~dV0Yz1U&$)*Hn;Ik=;i2xKvAlSB+f)aa2>=Ddul?z9ND<*epo5~8sJOzCic&q)2nD`u#D7w$7a$%4k=|vAcYN&PhX6=|cC%HUK zWDI^eUVXB|Iy+s1xl@?g|Eew{3dO_nKDs;FiLdj4_;(PKLt;p`*ztabS5avxAKWek zh!%rZ_v%g*uZIEWhE@A{Fkt*V-HgE{qNaD^SlT}cjp5= z;0Fq1%S5G1{*ow?h$=Ct37;+_efbuq&?x?AYWOTY4VYk8t8Uw#XcWiFRI%5W^_Vrnm zapEl5TOcR_y?v#@9+WdY|Id}dDR=&J!PIdvI+MIUu`vA2{e_WA5m6bj824)`PrFOV z)adMZ%AE6>`Uq_G@%g+ccJiq4=|y~#m_sRJJX!J+(eeGuNii|8TAi&ai8CY4!uCd@ zc;X=t>3qkz3+{Z)PS>k&53%d$Y&?T=dt5y?XyI-7VE=-{qYytnWoWb9Yo~sr9m|AK zY)m@Xe4XppKA5}Ekyd`+d;f1A_q8CE-YW3r&E!f9X=vP`+LFgyWLmrC8rdch2kD59 z{xu$}RL*T`{cIz0G+hTT}kkuOR@tAp| z5{w-~y1Vv`JpHM1?hfq0BO)`MAH#Xb{7`koqf8JmO9q;2TZfXqfQL*o0Ud5Z42_M{ zJgtPCR-KM@v<3Fg$gXMMyLYb(eTdp`1$}Jp6w^}Wnn-`~6eUvlW77pSG@UC0R(^lG zWT>)gajq|vMMo!7CW54HVDL*I&zIUC6Y{#qhyXv|OeHEY%I_2ug2oeN9GhO}2b@OF ztbOcV_FPnY##CUjW`0|saUDbzgFJOW)B?OYEDM%g(lr0Dd+6pn8;v@bomRS?FwoZgp(?ys-c7OS=#9 zFRNN}>O`Rovf8fRwGqdo99qgUGe5c*rQe0CAn4X2_DJqOuJq^J?)48Q6KaW8%dk>t zOTfO;%LR`cPfP@BvAGxenF!u(yT)MM9ny69?yVNMH{qw_mv2>t&^l}yDOiZ51X`Cm zu*Cu_Xg**;*U}@e7x6_TtM+L$K91x9+(bV;;&3m`^5^H-suIP?$Ln3zx>wB&%1u?f zxQgHh2CE9~TH|f+dxw!2hD0m}F`HSqu;ud(oozRyU9;HOB(c0bVHqLgR~`1oPqdP| zwkbAROqNJ*=)7m=IjJEc=cmitdBnIBfo%5I5O2R38CYI+to5gu5n%|Sj2ODyDNSK! z6PY&(%Rt52lypjr6S`wg^JlvpfsOrS10x;i;opy8A%~nQnuFYe)A$Y* zMAbYkXkyfVb-t*;5P7XST&`s&26*ZMGJ5;^OA*Jlu$)wvQ&G zjBC+jt5eSg=>3)QJ-kC4d4*LXnD4_Lz8)#4)`>g+@bG%_x-!Co^~G2%$`Tp;l{jil zErUnp-L-Zt?C)XOgkOg%>(i&Af^H!zF>L_|7~A%>a2>Z+%R{F<6_@aAy9 z%UFLpJPC`2)Sw!a6!RmYhhgnMAl9?pxc3DH?ras+)$#lL^f3O=Z%%^??%pgf%#78X zjMwh!eKa;6%2Jp@DmtYBvl2diBBUIa46CpOe$ftQ@?lvqD%$R)3S) z@VUP7LuzE^v#_&-1`u0dnEO%em+RuK1X~L_!+Xj_B=_Ga77QWTFONfT^@PD+EuN2b zk*bU&X}qYt;N&RfrfSaqYWqovHccwS@KW^q0wpbJNhBFI_SVoV77B$0c-`|=fd4ld_l@$ZY%|Cx`OxL8#=Eb=B z`*$!gq4r>f?BqOT(4sGSBofprAV?k69lZ&nlgJI$9&B0sOdUN)Nkwc)wUi#4g~~ti z=Y*YV15y0;aMo|j$9hUM3w`bHi{d{)D(vJ|OZwOAm9qk+a?3VC?Z|06#l4w}tOxcy z*&^#>V|1Z)<45(WTYa-m1bxg? zRXt}gIGLewNH;ft8s_dkvd8Rl5iM3}CP|w%r)iV^!YiIxYq74mczxPw>i(%$gXfF5>xjrr?3Pm~2#aaSt;5 zu@`=B{p6Tmxp&7M^F4^N35@eA;H2LjOz+5;okDgEGoO~et*w0^(y>h!=GS$#9p}qO zPuHs;3Y(hVhr=!{*pw)qKI(txXtXi!8I0^mo}RkQE&;cv9^rwM1o2{5NLzpQ@~kW8 z2(paH6|INIplp1D!CN>5tj0lUI-j&9KQ4<4htAj#kDk^^VWxU6WE01_5xi=_1ApjY z`^l3*sv=SyD_mW(jR@LruP`#%k5?vs^D|AXM)6V>%R1wBBK#MBGQo-LU;dh}BWk6M zNnCK8H`#UU_73|BM!f%awx-s&4*983>PNDETFij8u8vPhp;JC6q(({R%Cb}C#?g~f zN&RMf$o4kVS^-n=&!_bI8TV}@q=KBJOF<8aI#s7@ou_=B~*TNiGKLz|0^ zEENQKo@m|K`X;J?juN6Qo_y!_{=Fw|$OR1{82h4an6K)q$2N}IzR{CW&d1ik(2@FHU!g`S-K9j)jwUi7a)#DmO7V zr)FR8rzf=XF41QgLjDANa^BjJNXf*w&O%bgG#0vYJAyXLymtM>w;eyk5x8@5bCCGZ zvNn<$iU%o6M&uTFN4{o_rfj-UHkohDkB{7^2?D>Qheo|U_1jipNk{0eQw$wy39ns5 zstjY-mi=XYnED?hH$gn)$EZv7su7FyXcWj{smEVdjGaX30_J}hNGm}3YeJG9GOM+G zu-PoOf!-{ELRrTjyvZWza?P#FW?Z^=uNTx(qgiF;P0)|Y3>9|sB_iIcRTqc)EnLG@vhZ$+L>Q>!N9)P>l18WjBsxt@Q8?Z<1 zPy-i8j}N+={C>Z}wro|Dc}-eE*JYHtkxF5~k>hm-{y~tfGf07=^juTGpnK72qgTj# zSQzd*aH4oQS66geO4PA{0Fr%ciZK_Pj!Y!$B37Zmd?tt*%ThzHgSYBF-6n;TdfPfv zf{yPsR)IyK94Aci;8d3Bz;e9}2{m%1oF+QLm+9dwBP}0T7*&y{YWr`M7!8k-S3X=I z8I=*Nmw-csdl&nGU%rld^YgoK_|DswA+QHyy~oPd^(ky(_xBxC%aDza5;Y;z+>oCv z`lLzp6Pax2-Po4 z$@(<6@rZ$f6;&&*J(Eb9!W02c4!P^_JT09DLbY@!X^;>F%0%J`L(fPPvPnMv4(PX; z)gIwP2g-^G3AXgShehcLZV8i*Ckok${oBwiand`F7n0&pi_#=Z{ShN=@(~4#nOK@}#*vvTzLt`^q9acQfE@&Ol()yCiP8D_(Y@ zewKQoi+<@8MjpPhZC1YSSu7Vdo*5f{s$?= zd)%hXAZqREEn=F;D4J_pvF|hFeM1Q z;CdGwivo>~GZt3_MFsz`ot;$(*&YS+v%IzKvu8@UM%5`+nfw*AU9@9lBWn7c0P#9* zIU=!<(fmyojcKI9ASU#E?3A}Q(goKWpJMU_e#}5xFqCq_~(LqhV-bG^s(LT;Cw+(LJbBUfIxZOjgabrp} zr7E|ax~A9vjwmREEJ7DnkE+|VbySY;PKNIreY-pZFTx>sg=!DHum&~zT}37?TAirt z3C&tUEO3Gm08TrTb@?2}V{O*Yx)7E-GIFDN>r3u}?(l){=lRNaP1>JZ4vX6MU~suH zB>8Q&2f!e40Er@{uv6xxT^-k8#+S$}Ds>O;T=Sb`qjezd@15B`GVOjO^dw8UliOV&Y z2ni`{&fjcye^`CA41TpQm9<@zOAQFkf$WHOnBTyY@X%gMj(O5b18c-N0-rm1EG<2h zH+U}S<&qeIT^10nF0M9s62%WdM$VH%6SsEZC`pPfVh$E<>?KH!PkIPEIg~{|a_GYz zksB0QLs=?gWQB=!CCxLaT;3^caY5p5&f0kJ(ve;cIhWsu)Lx!J{K{<#`A@U#gSiwx zxeUfV!x9|e&n~uA{v>K$|A@`r3sN4zt(%WG(j)SLs)HDwvW4}pN6aind+ozjf;>TKfkKUgv}7_0+mp@It) z=h+IJiRp%+h0zm9mepnOUmuEiV#6of!sFL~+#FNC*`^Oo(zWTSeGzq!4>y})G+h+l z-*!4+S9+{5`{*<3k$nx5QcO(!5sp6SG!tffPhwqoMW!0o1wMxx_&_a#Vb*|ekezQ< zw4U=~{QVo)-$-PvoeU4<$v}8@(tn9LkT5WG*?w5C2;mLG?eiVRf|CYoR^*(rtIw<=9k;xrh+KKglGMXNIW^17X204FI{D^r)JI4Fnpo7 z&=}_?iX2XnT44Vz(X+GnJ$N(h4}KEev%H)qujH5O!9d*)kBsxZ=-|8*FDY5JY`7;z z45a+3-Ib+ITC8tqcl3XrtuFjA*OwHgEN}TI@lCOUSN>%`WIEE~b#;NC5;ou4VO61E z>4zvq$%%aa%w>o(?9giW{MpR?J1}VQ`E-4?5ir;?ZYFE&Nh?jtM@s9ppiv^092PU* z5koe8Agyi3C))2|Z);|2XPeEC2T$7HRhab&Q#zo!CO0{2K*6u?eNP0;y!%kD6h8Qn z>rs%vI>ZBqDxrvg>LTd+My>afq}=z zfbnZGC$k+F7WrU&$kLu{^jPPY0xMNjJ|I0i9=Re$Nx5v*a3M042g@{2p_tpV%kI0i zPe1-kEEUMQmZ@$qW*2%;TuU)Cqlk-qu^K8-Vq&QlOH8L={o<}D*Rnh?Am}nvUwz+N zXh4Q^>Fs@j+rd^(+qbdd=$y+3`_1USdQWwMaftWWcm))i=rlOufckNg8-e4Z`x>?= zJg!aEBBLkN{YWzZQyrR#6t`2_vtHP6NB{tu`d~5DFcVQxSnJ1i@C7S!X7qeG*dA%^h?Jv@BS6iv|-m{(Qx4LJVw=p0Y?5^b=J%cE`bb8}d3Hd%E?m!Xa_K)~O^ zGTu1)%ha{ECB%Xo6L{A{?#?_;jELl*rOlbcDrPO~;oz8guZ5>s%8ycC3{g|Mpk;kC zo2(ZGa0{?rw1stv(-f3VX|AswCS1QAn!&DsbjIXcwZSfgsW?4igI`T5oypZVeY6cy z5%ma7o)0q*Ir%*`?YAKiM#WjUW6B>h%0xT<$Uy9Ih_SGzXZ$ffj?zDXqk9u%Z%3n- zDXYXm@+79m-cIZeTLKM)|Bc!*z#9NiRGrx_X^yZ1INKkv?F2#updC10w$D!(c>hEZ zKMZU*9RE^)?8HYvcdUG~DV!X{WKp*#_~(BiWok_7A4`td-Fke+<-9esl84UNyQf6#Iz3z*tweR#wB2UZcQhfspVN}Uvf zL6qJXzda%=&Q{fmf4=U%i`$-iq!++m=Zxsxk!#87ndhJezL%7?CMhWd(NLkSd};yw zvc@3~SM@4j+tkHw<+Rvru&N__*!$91+S|jlJ1XL{6>YN5ioz9G<2d#5F=X!q7Ho^}1b~GS>Tg3eOJ*_5itF*eh zAirH%1iGYszuf)aJ;AbX<#AgxZr@Dz2qWuGn%Wwj$oHBPx=}r~K-7FUK&3rP^MjZ$ zfEDkVQgqt~zYmM=j<#dUEbX6^vF2w`I0>LqQ!T9p$@U}#HPI%jnYA4#4P`5343xi| zLBm(d0z(1*V0m=k8YY38>+!FRIvM&+1T z>)v{Z02G2R0HEAI+P@+zgC+;*;}p z#+=~u1b(r~6{TZkFd0WR^&n``wX zZ`+WV3_=59+T6NJQQ?Vf+Rv zXWsz4NR`h@#7yyP_x6)Q8U_-SY1(Tix+K+Us5j?qleY^RUG4Y1@_p@?p*eN^K5o`q zf{DUDi|kbw;gBkk;geIqoyWx76)MZ=X17wrjq@MF!6zc|kiaES%Xgs|P02X;a?!W? z+~Bz$G?pLpk(7kwRg{_{2R|(&=DL0vaalKEx*Au0r*7r}$r)L!#cC|#3KTCb>ReT5rtAqt|0!)KY<={QitPYSeIfKYbcZTJU z-j1WN^WC7?jjb)NTU5*bEufZp9^KSnt|U7qQ&UwgS~e>FQPX#ewr`&DyzO4?1GR!= z^D@7ZVJtbQsmkc%C0Z&6R{{UMD7v?dYfgYKt2#X68Wl*M&?3s1)#IY&f0=!7bTkVN z2RLS0;|mLjI>f~o(h`&(v72#4X}b6F`qLrm?|vHO3unlqlj_URT$h4~xC}6sF3-wp zd#)idX+&RF!t5PCCgdntOwYbXmMWh9j@b|^NsVbPNb-lRfT|=*@6MquGmQ*A6BVg` z897DFYd5<0s$vwRqplQ9vy^es-5-SxDC4>1hzJs2XWhA#u!sxU#7t!i>s3toAZDZ_ zrxgGKnqf=36B^xiF#-k5?A{dx2RI!Fc;P!9fo^e&g#o(xwyRh_N~XA~DxFzkt9c^^ zpezuna*Mw#cMnEoTy{e-yPcRr2{EzGgU#{16Gb+8|2H53RWmncfFek)O+-kSa4n{g zrbabab*{Mlb1pKUBQ&&iFEsr5^A{+P{EgVhJal9LD-MX~(ynQ1@(iuW*QG}j%2E)= zk4JZdY+EgRgi@1|9B`ZwL|0;&7{Wq`7lJ=KJx9FFnW`%fQ87U7c}hdJ?lBC1GY=yV z5UpD6QoJB)pB-`7>jiBfWn}lE$+&%}%0uk=1S71nEdu>01|bDqFcRtzZS&u7WQPR0w%oY3^i_xS%I zSWtYes8}sBiFggY49tVMKh{6I7W|)JqQF#YR^I97vj7g$j^s(*2m)aPzbWdQmoH+( zUxY`8iR`i*LRYtQvxHjf5}pr@UTk>(IXl)23Js)gKPJIMx@^x~??+sVskdxORSsKs zWDE;0Hd(U8aj)1Wi*y5sC2jBgKq{SW%1?GJb`n_F z%sxiri8E`ijcTT;3YobsgBJHr#iC6W^DX(2k_m8oz@X9XG3m$0s4B{dbHowG5qEDA z2vKmGeF;;vw%=p2E?_JhPnbe?EgvrV^H$?>(qrAsU(@@XJC*nc9sL1slew8k+{N}u zR-r16D%ZCis>eMsIkhi=0VS19bZ~(5%Sn8dJ14QIKBK()2=C|#wL_gJ_~s#eXN}fJ zIrWc`hyzlF&Zi4SF+%1YBYItDTwWB1gN?@ZI(y} zxzby0IJ!HR_ZI#63K&@^=o5Q^!~tM>?PUL^k!siIQMILjH(ehpP$b&4 z>c2m5*--b=%zv4(e@lK94K`OSE~F`7g+@neIbIc=`wWJDAdtQQGreS86= z@$OMx13|4`KQ3JP6->O8a1G^p4T#nhY55r-^f#%O_Cf&V9Ta=Rulw02)pV|B6BK=Y z)v3gmSF?xvSkVjMS(Op$6YG`{kL%(+_^Yyv-Lt1_e7Na3dt5Tu`r1M8U%#Wurp4#- z*;-Y?KSl|jY;7HgN7kABRNrlN5T^EsyWLc|ZnSArt<`~ny}R9j;X69)iCn9+Mkwiw zb>N8{yvt^LVuCzu{ere$_ME=2uT9DEa(9LY#Z~F&X3vs_OK3BN*ZBo!DjjF}tdpAJ zHh@p3Zupa7thRs~b%`gV{de{@3BJhE%jd^sr}vW#wFcueM)y!o{^7w?myQdrrkO=C zkUjOj)}Xd*>05x@KqvCgCS3|loO>CYU8EGV26joM%Wf{;wppCKZPmRK6j2r%+w^_} zS$_L>Tk5IMcj$@sZj1NmmuiiLqe!j-!W8p@<{W7LpMtj7#iW%TzpDlLwk%%7{f{?e z?sxZ>UuJ%1vD~+L)nWgktKI_nBc7xXsgklVCG;sPZ~Nl+PwCY1;uJqJargeGUZO>- z-%tgUeen7eFKa!@x&>y6x=)dgujkLUey~xNdW&+UKmke`;f#X(2ImdmV^>ljY6T*# zbSGYnj|}}aQc_@b1S_g*X_1MPCE9{Ms46CBqm-jjpe6qnaXmq^#rW>#xhhAnqP`?U zx1_M{xGvS8L8S=>d#c&vz{DU+8PjaHC@NS4b2u(7qpw|BvoLLT;5Nt~(sR+nINYtq zE~Ea=^`siqcfJ)g6EA0%R>8^(h1;0RV%AHZgVB==tvfa*#^bVWo+>#7T9jmS=OR#e zxRqX|(xJqRfkqH>0Jp+OhdaafBq)Iu#gyeo#&Iei ze21ay&rnaOu@mEnm0WbUVeHY<(#PZmRh-QB1#UO+A8zY7*PSIK)6Z8LcsNQ7e`^i) zSEytS`RXL?Qg(Y|KBqwc(0eH_y~f7GKu4tz4Cq7ORA@c<%PsgVJbh|ggx7Qtr|tCq zNV3J^$lh{;cWc-O6#4J8qz8vpZT<#+(LGPPTk0 zM=ek*FN*GHH**RKilsxog{tL*YYD+za@$DM9hw^y)OFO9ac|&y1axsRZ)fC_IOMby zl>-G1d@7HLDuU&YB>p^Msrb6(flwrS4}&%2RguMEzmES%MHj^V?ysOf$!Bjm-<=?R zB}9)psGQY0I%gS(A32x}X6fs=ztAKSV7Q2UK@vncKPVIWBR|1If>z;(gSq`PJ`X1n ziY`yN9u7x3`l#HRJG>hyb>KcRT)5nA+$QgDV;%Op+2pXJ4zq(g+e2GxMO1fjOHwbO zWsvb?w8`hp1BdaK7pHC$ilF-rit&{qZ1cf9pvxXAE;FG zNIlCh*tGdpvX0#Ii%eT!UzsmVJ%K)EYn3^?7~|{D`z1{;9{dK(s!To6UBRwAQfZ*T z{uGG7s1dQAZrH`eftwx9ySYtTTz>%+@mHGz;YGW4(Sc{iqX|o6Fgz>`*mH zMX=4*Htdb&U6z4E()P=4t(M1^-SHf2(U{A>Jibb9y~Aj^u(NA?P44AoGe~KVwo!M7 zSyuPK4f)U%#_Ri^4iliM-Pj;Wh{DohGsl9~poj_{#T>08pq2AxM5gH4%#+vEZuaVG zGrzG4IRb@oYlZZLsk}^F==aRL<8Ed*FX54&+W@nx(;DL2+)Rz#gUvsmFyYe}N&u20 zuLRc!9~aVilFoj~Lq0S!mh!633FeBPTJNsc{aho!z(5tx-J-5YLqWn!5&H&CZ_6Z` zr%%y+heL)e_J`@$1k6$bKqd#$9>pCU1*VEg033zhdo`=$W_%lH^G2+%@Uc2|6ZD@@ znrJ>phV7C#YJM$f+A2V~fTf)=lDFc8jEighZIfK;qTPiYj}SIr6@QFnX~hCyEJi%J zO=bsGeyjHXiU@%;`M%*}iHqyB8SkMmm&!xgCCM+n z0&GWS$6kcXx$sG>#oyQ=*;x6TD7I|$53Uhu2JOiE#d z5+ge+H0k2&)Q?orQobPzXdK@QU!$${mi6|Po(N`@z7@8~q4DoQ6zayl5;aT^Nf zJT{d{?XzNIzGs~gIs(}GWV?V4g`ZG3E1_7jXP*PB_NB(Q7OQ+lB*N17q!rchQUSL= zwe$OY=P&H4DjV1Bq_odl);_A$8cP$p6uT^kT*_q|x8^Ne*+LOFf%dhN)E%cW|Y zrBhawLGZ;9Vm}3~H(svszF9|EUA@4#Y<2H`pN&I1uv9{9{iG@kXOXQmGY{$){4AtI zotOu}10Ipt!?}pcuNJG>FREEjB22nd>8-)aJ+@EGy%x-L5HRlRA;$^|vd>i}ItVzF zPV8ac^Lv1Pcs?MMD9sm%7>6*_ku!1-~*?q~e)MkkJF8sHEuV@zvte(l}FqStXe?YxBdFXDFFl!@vV( z2Bgl2KKxVL#P?EQ%7U81aU6Tu-RS8J)P-T!M*2g0mFNd+gV(0@!jGak|6Xw7-z<18 z{97iL3RE-oemwC9lDxIGh5&;P)M`nAqyF#)4#Z%lKB>U2l!vZs(-(CZ`d#;i8h0>^ zLwoSPK*cvrs~SvM2Y9jAx#2cYRj7M1uoS+-&$!vbapRh7(54|k!O-->DmoA6YI%B6 zMn5Dl#4fWbO!h~|kh-}|56^mI7J(Gx4U(9D6KKFjWArw5v(1`1vV*f=DjtsR+6i)*bInsi``a0~J1rt(k}(6lf8|vwkR{ zM?bDx#ST<3`j-A%IaT)RDk)p~%CffE)};>d(Ji}Y*=K35naD;}wfN^%BdQM+mjAP| zR3h&`zy4o}Oz*D&k6ayZ-~Ipd)?1e1Hs&vY*t-*{xY{x&Qts})Gn`^*{VV~o-XvoX z!cl#NUWC;Z1C@%)d%-)yM)?R#S=;9^q)-a|YN+$T;dUB2>)uqIQI$)nrHbEeOL5H6 z+1_zDZtWgo6ZFj7+{-&XEhUA(3j)7-gQW;jv?0(Okn;0svAnuz2lwSTrR~|(;|Tqh z{48H3g@4+WFzNcwI?|N?ZJ>=nz2QO({Imvta>^73A0()A;heP+dOv59!MwJ0$AR*W znH*kTmPEVkQdr1<1U;F3=)7jWz?1|aVVNaDw^G^=9q?Fmpsb$S-MJ#1tR z0O~-E6(E^E2l@^Z+jpSvsHbm|aNI!ao3f#qAX!K6{CyzzF0Y`lJ`F{Ri zGKU5Z91f+SU8(?QpGQR+SF{-UP0Pi05hM@H*^wl{=iQ@mx&4IEKZS2 z1@q!j`Hv}rJZZ`Q=o`T{a43@X;ZTT6XmNY`1b z`}nS~VDiYOuc5iQzPCXWOebor_QB^-rcq6Rc~#Of&k-J}auET;i4YD92$IE(KB? zP33tFWo6L8mNanr&lFW!u4x=8;MT^A9{MU}2#GWcVq;<+U5_M52!0%0(EAYFL8KC6 zDpcNy_}o#g5nb?zhb=$1Q}pK5j>%(@xL(;uCP;~};_ad?ezW+$Oat&PVd6TR5^hqQ zB7P9*pM5K+iqZ0_9NMti*$9qSltJD*9mdo`LuduJcYqNzjC!ju1r!(twOGkoWqXc} zpv3+L!vO8_0m`p$%Mt@nB7C_VWZ7o)irYtU7-wssPV*8p*n2zBKAiZTg%xx3ojqH@kchy>0 zssFd~I_tlz=sK<8fcW_16R>vp^rZ`ix%X^*P+T7D;;rm?^X`-%;7g$oI3c~akC`(| zOF9u;42k#uN{HzhMHi?^vKTMA*z(b((jTkY13|o5@Aw>$AV$G;8k#@`gw;}(0`;R&FHGF2~ z1eil$Ewm{Y0M^M5s$@=gKe2XSyAqlW#Og)$--iD0hLux*a`DhTLQ^4Qyz&>~bA3G< z1nzz{?;J9#tE+$}-4hjs?*z^Qb`b*Car~cNi_p4t*@>14d>0)&74MlTTO%Zn(4%24N5^%(r?-+^uv-3k{k zn08zV1%TJh-t)P&>qYImuHI!G)ue_loMi}Cw%;A#gMQe0mjbEN^O58yo)lChccsRits*YI;FW|G;xECWPq=xbJO56_bS-|7 z_|ES)^b(B*T!py8pU|j{W;nnMhzN`C5c%d1n1*k+&io~wqaG5{3tIT9y^30HBh+dEa~%a*Tkc=5>UqCQ!l9Jf6ZI7A}rd;II~6d=@19f^ub z>;9UZw#E&N=PkLrEq-V{^ zFh`0?*x8k|1GuxTtU4HTurP=M*%t>`@MSvBU`iZFg2t#aVq{Ld<5``S&t! zrDA2z;1q2ZU>77^*EEE;#O=?7XF9Bkumqn3Y1QZ16AU$-5NRuL=29Oe|p(eDDGlT2h z``v5r^Ig|D=hw%zmTO@`c%C_*Im$i8xNqR=tgRW{E3{gap4|NqU`XzdPy&rGFx1f8 zmk#l4Q1NWNagXl;OCUpmY@0jLd|($pyc%G!YReg^##Ihj6aL%dPVt~?ea{a>DkWZN zz7&w|2IoKi&7z^GAzfclOtD)f29#C@*=)kuZu9bjobv)TEj68g%*U9UFZ1)0AK#g= zQkm^GaQE_{rMsT;y*qy|u_vRcKpytAj$S#?5*sTkk8V4&>|gU^PAF{aYliwi42FS$ z55=pSi*u=p!n+m?&Y&kF8~F&BhN0QQ7W*T^e5HqdVivXX{3IWE zkHiw9?h?=1o^NXJ#AP#_P9Ab*PBPLi|GCZ2G0~EiW1f<`pJiPU(}AN2@$b#~)oG$i zU206?^qvlQtN@qrax?TnR&?-MblHYCA};O}m<2EMI{QdRN8<(yADc$+zOs(N8rjA} z?n`3J;xN4!>t6>);Z|Z0-=Yk`yyGz9v5gZ~KS7?Z0N5@B;o|@7Pb4y?qQG_*dtGoe z5`1lrdl&N`rp47aFA+j7RI}J{w_d`=b9}JzEzR+9AaSU~y%t@d5&#azf~Fi~Afzur zaSFX|1rAz{#W3b`ABR)iOmIqwgdh4?=|$1qtWrKJ+1}VwWrl0c#))#?5oH{rl z#T$}LpRx&`L9|<2Cx7;xJ3P*Wk0WzSKM4Gde3ZxekmuJ8JA*d(f6)IUm0&tYGcZ}` z^H5XW1$?5$OW=TV6Zo4H=ou2PLXT@6xz+=z$5bc0p!w!|(v1^n+wY{?0Uqkx#axR9 z?|IUL%MEhg$LAUnML9@*fuIJLEnl|Tcxq?3N8mv!zk(ddJ9@A zl{4Opntfvxe=^aBv^Rll#xWb&K-B=luLinJ(53)1f}a zs5f1!r68T74Z4#V{|*46^RA>2DYxqtDaCyl+J`|dI*+B?EweLh)x#R~DOqxvJ$vVG z^tgzWE*&R}$AP!8ri>}buk_mfBPKTN)Tm0+LVf-UrGn8If|Jgw<$|dtCHm0}z`*n| z`qlzYq;G8(T}Y_`cZf;|GK&-lN^0EByajGZrN#W$Mk0stX!m_Se2dBbkcU@4;#4C2rBg^>}qQ(0ob>>r;m%6o0PUJ`$P;u*>Z7l zsSUHGt!*Tek6)jW?pAS)|DK=!;=##Jt^S~mEHXPNs4*S=BY1F;<1zTey8z&@+Fib_Yy(=4 zL100>EztLb3+v(eJ<>q(ff{T~ETunqFgl>ycM-e%ZXX;)W?y>g&#~U&BmsU!3K_y59Mk-EkxW8t@y+vLi2aJ-e*z#n3|Taw2D6 zB5e6jH`K3Jv9(o>S7auug1tJ_g9p3wzv{W#BM^k4KVYfVu8d9*G@udu0Reau-+`ER zkr1kLCh>|egL)Wm(73a_iMmsw*hCP)BOYT684Czsmorn8!gptwldO!Eub30}Ic?p? zs(cr+bH6a;4!%PzbN=K$_pU^kfh-Cc)-}(zCZXZB`|ixNs9^KGy10vB?ZKbokz$}X z(bmbEEYtZ+m-^cHDlUAVx1{6@O{DN;kWRbEs-Bhx@L*QI)ig^Wc_Vzgfj9b0hzbW; z!uUI+(mtMzgPNAuh{CY%Ak%IzJQL&C$5}E(+zm#?94N1eZTY&$xhdGt23bD6_vj|l z-e%CAC;CS7t2uW27WMOIgMtonm&Am?5&Mr) z`z$>bEpJb8ZCWayx|nfnc<%(lwdZ{o@U-*3ILjPktuk(j`C3AvAS$UzYzuhIdecY_ zM|QXFZ|m}1zTKKPP~piz4!3J zy|&p_XvdY#dC%D$@1Q=OuII0A3PwNomQBpfKig+xX4MfG@M2+nyjQ@dXJ%VO&h6U& z9B?K9RAkXLLOB{1J;+}eE1?DgA4W#TQ{Oe+@4u4B7+=k-3`hpi zM1H>A`oT`-x8CKg$Rs&K)uExGh@^T|D<0hmMPH?{;v&aNCmz9LVDAsGLy9-Lv7(vz z`5kCs+fXSIXhg!Ytw>(=S~}NPu2m8+(bprini2}2nO8y!#(E^+N!(mWt`4+C9z7fU zJlq5EPM+)u(-+GJ&DkpFjQ(~^qqU6DaEka&uw9Ai660bMFA+X<&bhC0NxZ6#YRG@Npsr+6Dhi44gki;j-0MdQRTW zST;=7RIv&j9B>zKBsrq@=?9a=TTP&=CPylb_BcE`j+l82l8erh_EQ(!g?M{jqNwS= zy(qXqbxXv+*tvBDSec5o7pFz4!j{Gifgb=V!HdbC)QYB}?{$8X;sLN?v;7yOd2(a^ zu}NEd1n}mulzHk$&Uy0xHWA0YwlpZwW5{p<&TFMoeO4AJk@z?*a`!X(HJd^RJUGKLS9kK4ht`2Vq! z1qJo5Z+?j5jTM`^-E5X5`j61>jqUOeS|zTLiM}-fO|xkbF5FWFNaB~o1c}>x9AE$l zK)@=RVZ#E_11=lP=K_>SVTN3TMJEY-vMiMi@ooV~pF#Y6$qOLHaabeMeRkSrUa|JG z#gD<426A*=i{x7G{FengB{j18Nr8A)DGMOFOR?sN&!zU0N_@YisZPGNfDGe?5-HV=tllP`!@U++O})u#O}r{Q+V~&e^b#vGW;cU6sfX>Ts3+5 z?%)T4-z^-Q;G;^n{^UZ4P0}o{-Xb zO06yL`u~jk=%*y$wWNpvJOp=z4wL++w?|V>IIj>`*O(h$({qxjrg~h$d?X^VloBDv z_-ncbvEZYT(Nn*CmJEY~z^Kf*{|rF>E#zlTDsegIL&o6<12Y7|dhzoC90vQ~NT~2( z`9b!sI6r+I=}K8Lae`V)(ECBGnZnMDb1-t*8W?0)`8{0#RDtxF6p8GItAbW_oK3WF zvcXqRB^jEY;K7Q(VsuqHZ0(_4>|;>Rf| zDhKNOcZyTQ;+72rQAl$ZSx(ff-7NgKtZW{PpnfY<4bY#dB=Fw6< zO58BgKk|i%l11WV)(=;b6}xSmPMi+um}*VNHALH3T8(_PBx8Tr!Plo5sVt-#L3S2Ykt<5A+&(PTLZpf+_hI?f zad1chl$^W@`TKW)n9;GyR0hg}7#rNnzb9G9x0!@cf$R-@R-29|&LRLBNpZmGpMu2`RQ$eU|FpZy#ek2h8Pow(=c3RY zTft`Q3Ao&ER;4eSB(u0{;oXhea}1(?>HE6Pr1_my=k?u?={Tx~Z}Ugn!5{vbfHZH$ zjb~hm84bM)u<|4Uqgb;_O{GC(j}ETgL3sc%8K@okHt__F$dWMT4}<-wpKZm{1(HO)~YU2<~LWE;N& zlB4?0?j4ICJ_T={Ig^UE@9ta%xx`4ymAf_R1~+7HVoE(>ZnsK}lQ8n&5d=ucy~Lcm zB=3-++`tCwx*BhGCzI-xd3&soXgG47(u;N2>U!5Rw}}jy_U-g!p{@Ss7rP`^d!Dqh z*>%}pzs@0)x}~T6MDg#6YyJJcos<9a4M{ooLCIqXnGFIKb-v(s3*1812jjlpt6!4i z2Xptg;?0`ajZDFBF4^2FV&C~{o1B;jxeZD|B^SIYJs;0UFtBm(F-6ca^ML8H1Y`s% zr9MH4K1%Gy4Ob@A>c+EY(>QMu!>grBOXjT$HYZzes9x^}S@BW{$WyhAd^hS>?g_JLDF5PxzvPNy2B@DopFj%RZ>&Ic@SPW(7ZQYg7zfRsoV*FV zajN{oMb}!@>pQ=;_JThutE=$L%vegdl?j7Um*&k+`fE*z^Y1QfoQi*ci2uAY`g(kp zpG)gVn2D+M>9n_^sh=`;VCyZ}i!EgZGnS{Ri3&7??#$+9@c+|b?z+a9%$uMr&wIk+ zQ#tD|_u6|0m?rV&(NfUGtSQOXJX?C5X!&Y}Wnby~lg5@3eaTSJq2(;=T&L8=Al9w2 z2`v?N+okCT^lv*?h&@3^2!@ch^~NA`mN>oe?q3|Fg$|?TmH^35*J?{bvd>RR4G`x9 zRe9A-g6svf8ja6h2JDrzL4fhJ6=@%g!h8~CftL8P>YwGHrHrgVm7Hj^aN!_0#0f-_ z4S$|D5+3AZilQMZfhyy;oor;%{`mcdKqdY7`?41Uhs4}2mo+QOQyzM zZ&DoCGfo^wesoQTccD-}?4=!FL7`%nHHDuwTw$uQ?OJ@VTNk^rFg1G2{x_J~=CZrM zCOW#0t->))sL6@y|z@E9fGa-=Vg+zCX72enz2&M+fp zZUjzE1gh|u3rp<0YMF1D=VBeRGhm8#-t3`in%#*!*Q%nZe3)bNjJk1#CPX!>mD?s& zli9KFw|VQ#k8ginih^#B<=gP=@hi7sxRt1_A8<${PIOr;lDdM;RBl(%W+_w9~buCd=avOH-~qEa8KSaA>-id|C00k|9~F-|M{(A-}7?}a2+ACPJ0yfrSpt{`JMC}4>MZl72~$%IHzp3 zoUx?wo(Bsje)KJ1CwgKFThqu2s(qBcB(L_B@1W{?$(Lm;U`unh03CHw$jBc`sLRmr zdSeUm+w^*H1jjEN!-~v;6?PsVd?5I;-Ay-8=X9$VW(2d@gAlRprC(_9FQS z*l%d)0ek8TB>(bO8Fy7y^p02e&Pe#ZhJe}*f4X?>zsKtU_DX=U;<3Wk^(#+`qTu!* zDZ#|L`qyKuA&z%>m$8YQKHh`nijC#*?@{pZvCf?lE4XR=tgcEKF|vj;gMf-cu%DMM?JnQwJ?Cq0n6c|Q_A^|gez0X7+i1~g@7XBp?(yZFfZ2rB&lY^Y zWQ9*OSfy}c{R*-$F`THd5MUozP`&qHR(`7cz<1 zU;1M=%7(K|9%;iTWM;s;#bEov?h;6WFaUUVn__0!_j_8u>1J;j<@t%i0IY?+DypA{ zLs#lS5i%!fEIGi_-huUq7`Yw$(!qq6yFN^}2pkR{&qZ(>^BW@t$1@5KXRc%!LrNRV z`@z$%U6iX$Itb!cs2lV9iI&;MqVn%_x@Eu|-j^>yef&}yUn-q$fhho(whic=Dx@;n zb!ncWJVsNWAodpLDARI$I}V2(Oc-PphSeQtx{c028bAlfB-l%7Jy7e(EFW*bYKA;L za_F$;TbgV{Duv*$1PL?Y-$zbF^@OH4ncu~9d=dstiytrql&@OepPXuLY2}|$! zJ*!)=>204py#Dj&x|J9@NH90bm2m2)7a;B+{R{#bsDdNkM zAP1LVUJh z`4lKEEqblDeAh==ngog|Jw(qJ4N+!!#TQ`GEeJQ`wn_~EJ_F`bSM3J*TSm2l2%O5= z=P!mCM``3>Xu8}dLLcQ!iD4{b*_IADHNttp>Si=e8897VH{r2b-#u6`KCR-MRXlNv zUfp{mS5aX)fRY+aNo@#9yXxiq#U&-o=M%s0-TFCM*X*03P5F!G`eRF@k35vCm8{P?nQ!oCV}5; z-`wY0JR6^aQpu!A>c}=b#U+$w?2gZ9q!E4RzQTgDy{>U*XuddbRlZS(Rloeip8SL1 z(ibbT%1N)mDeo1ALjiOX1p7m@fg679FY;Oi02vsVpA1?S`jk#j$4EF z3w|Q(zED$_D?$STy{u}>3|@2@c?i(nKLG~feg~vcp0n|JH#Axt!Kyr05`vL#4HXLP z6)B!8V_ak~2zT1T5xR|(Hk)nQ88J~4x%!ft?WLn_3fHZLjip_+YzE5~c&ICnpPJ&g z0^*3HScci|I`5u!|DZ1-ni;aW`rvezDUmLae>4Ee5!JKc6crFf=v{U%&k$JUrnP$U zq-fmgK%q;sMwx4Ve|PVrF*lL45@MY=g#~Zm5AND+qLR!u-hly-lo=1YlmXNo4rtHl z-;EsKht!r}#uGX>m-{14XI)3uT!|Qw2y5ho=Z4a1vDA$k$R?r=lK2wOW$(@mbR1I=Iq-FPk)GqK}G;Lns@%aAn z@t)M0o^x;zlnu815z_(UJ3ysnW%AF5rUnS4ENT`vZab|+F#McCJ-mOZsXJ#>KmM*T zSF1YTN(xY#`6Jzn5bFkXYFhHuQqRbIe&M{RB*H4>;GRH`*+O9 z0Hz-_H5@pBUeJVN)Uj%j<`ZG2Dhekv3EPS7(5^ZKJ{ zlsnZ)(k=1>SH7x7C$vr47>O=PP})dL9+QXZ{jGd7Yb6dOl$0OosyaDEAq>Fdruhbq z<~nI@jax{)O4?3-ts;_s64nzYDF(Lu8(+xXY@ZYdQ_|&#`?&UOr-uElFh!rl@jv#! z{?EEo{|9e{f@XS<;@231@i>l1i8T~pKS_E*qGRDnVg;So!XWBRtvWo39@z{<>{V>~ zD(w;i{7kvIiYcqcBVLKUV5bTL)JT#Su5g@XIQK4CB`dpL_@q;0}QzuW5y>7mQjP!7wp1x&h=(&X(SMatQmj-_c zhEuljbU-3wbqXBYk5~T`@QkmLrX^gveq{+Rn20dz=)4EK^(BBN+c;qKim}Vy18U1{ z)`Qtn;V{7C(gui9Vy+vR<^B&sM#s0y3v6cARg$d5=e)d`JIp5El9!b`f0Z+j%5-*) zW9z#*)QD*$9*DHGwC(Nf<3~?W|M)hcS;wD{4K$!AOh_6~Kz$<-0_UpoTaz$8Yz|vV z`KZ55=g1q)QsPB6?SA^Ikb(S~ADl!eA?=3^S{eJA0<>$=0I6(r)}QH_NN84#;|Z*) z(HXK>pDq|JUrC`Z7Y^e!fn<73GrrFBLMmEpI9_`&6=rTFvHYC{$mP}E)|Hh zd$Q_^(IrlxhwjOvKXoQ)fw<+wL;N&P}qcOHs4>s zAK0djegoPe=?d80vA1g(R~{mKX|_AJ8y~9 za0%Sh z8@Rc74)pt0o2;E>^d@P!AkWaz4xmsEwe&D?T({GXa~Sc?D<}>11{9ISVIvzSLdKRh zxNAR}>&&JJ(^HL2Sbn&XUe4w@5vJS65G`RKQd6YPeI4`=eYQZ)yY`RBzUiCrRyyXI z!dGvabdw*hX9n%f+===z?0Gep`91unQ7Y^f#Y#Z<)Y0?Rd&rdtVZ`F?laXgkv;y9l z6f3?zs?gQ~PFlSzkX0ft1AWsAD&X(01RMq!_Yz*-bpcGkB2_7%$_MBu^IyCmsq+Bx z-7%T83&(pEWl~g=j^XW~NvRBUiX6LOB`3rJDE>6g<&_>805rYcq!K(U@l z#1KG;Gpi0xuFr^EzO{A1ce9Z+hnN3%dOCwQmTtS*EcjAHpeEW?OdUdsvfI>yIqk04 zU=<7Ff0-O*2-gxE7kY6yU)6$7^R}%-tv`ZOlEVh10Ufhj8Q2qu4}~^~xa$V|NbzV> z)DiT7CpR93jVFQA2zaw_MI3-Ucc*GlpP~ZN9w{I*B6FTz&JtYef{6Y-s2(LH4ttrY zr!R5#pAtE)ISaL{lrKcg*Q`-vbsaaV0^$nc5-EkmO4>oR&)7uIMB_dyrqERN9THs? zNg%>b7&$~uAqGyoteF+0rz#euZ*L`dtehMk7ttmkzX|{iNAcPha{z1t%v1 zL`i8WeUCXg2H!c@1vCdV#}f}$in6x9kIOCl_ncCE$$HuSIn@EYJ`$ZiS9u4&VGrxnvV79*!~0>RQ7*3MPD&7;QSD?j z#P73-(lXqx+Ge3mz zWnFuBdreGlS)f|&{jGlIAB?~jYMwD*&3-D{9C4`4%GmCYTp9YQJMI3_l~~BVF|38v zaC`)pDK9e6AcR*0jALFucANHdqWTHrk>k>0=r^i+QMTn#6wrtJTc z$txjH?LpRw`t=iP&Q4V1=FV|IU1h&wm80s%Zadtj|86G(dFC6En#z^8bXxoO82_lI zytwd3HRUCI=Bsf1e*BC^Dzp8s!<3?|oQ{XTMt%hROEJa1yN{p80s~F};Gdjn%@qiy z<5s>$*bbaP7he(OPhLh2PUp`Gds%jX|5fzb(@K>n5|y? z64^KEvD&bP2{`neLQ_lroc7N@N} zU0vPpo7R|el8|80>r(I^VKYxFm*H z{a5oV*Q5OYa)1-jb2_gtzdH9zG$6f@7z3&wm3(T7yBL#T=1c1u$;FNx_um!?Xpbvx z-a^-6Oldt&Hhhva2{=5UxNG&|%O5G4YWzSCv4g5Y87{gmCS6|{gbZ>lKPp!n+0ceCBSJf9dS9X7_>6GbYSFP z`amet$5c;>dg%G54TJCDZPcrITc*%xV(! zh#PMzfPl*?@nCCZjPryVr-mL{$v0zOWBq$V?6~r-X(gJ-V)FRI!fl%de4D1EGY~J) zJ;wn{YOPyM`5sr)9Z&?JL&J9iuHt002~P`n`EyA4LGQr$#u=HM zwEC#28I6XkOd_8KP5_mShHV3U4^0I@TCVoe4dR6fUL_tL%ea4uzsx36ls})^Vp}&& zW~VJ#-gv5ZNqsqXd2c{(Z7u`u^KuhE@vYX$X8+NRtYaCN2?1I1>OHp%%xuQ)#j0XN zD_UyeXtd8iK)qVj=*ZO33`Qvf{he~Hch{JEvkqoE%J^!)x|?9en>|)$=z3X-YkEX< zbk997#F;%_+w@#pRlod;tcibDJDL2iY9~D2NBa-e#-hF?E#ZaRPi!}o-f}w#zNZR| zUs$~KV{~n7P<8Y|jw!7@th3>)p8u?_NLte`p1p7Gz0=1^0Lwe)&zvF&fP(Yk);=$E z_S8vlgk{carAX!4fK8UPyz;rNfxuGo&VwJXrmTFG#Btg3Y5Acni%cN}RW z^ism(Hli^~3{{V-x^T*Q&pD?GIwDQaX=>#7>!ewhBkfJ0G@}8C9q0`N`2&3OjFIQs zOr}oxvwn@0F*nf!UA>aSKHU1#{SR4R)-ZP5DR=Gc7HWPB%u5W)k-Pan3G-?ETmE5i z^>6uy(5Z~p3ul`>Dik-xZ!w%?2I_WH;?x&bVM)DHe%9UDP`Jn|!&fp}SECv9bd_;S z2i^N~`?YT>8BX%>NP~V8Z(+;PlTGo(CY^^A?4#`>TnGyh8D$T$O31fE3hwDax?G15 zKl&;^BG1BLmt7xRrqHs$TR3oBY9Vd;tzzRMD{gJHbt@(PQ*IsX=@k5Mu5_lM(8!ei zCrQC#WwJa7d^5X;N$312!>FEQ%q?CLuOwRWI{S4J%J_AcsZNxDc4dx`5VTt`a8%2Z+bz!h8K?GP^$mc9^WBFba&r8`wuP_8ufSf>0zr%AVhoXs*PeymwW3C;G3Mm)+R z!BM?8JmbsiIMBM;e<&wJn0qtJ#5R?2I7;c+s2H-m5c-XER%=0`@XPzv>+8|w(EeKd zUPW);)^F_Cb3z7p`Pvh1qob)wKLX5lGWXm6MixRn&sghz{qA*K75UD?JOy;f_O`uA z=@^=d(o7T0gE4$Cn74#fGr=%IX>yJ+4KfH`P44ixGnr^c&)ew6{#vyBO z-^^{zgxKBUwxqSoeRX$Y);%!x&VIttykVr(o>Vh{n!>ZjdT#m+PH1w2O zilA#yIkLWuLWPFJdg#%p=>lbGJqG65loLHpd(Zkmaa&?@C zOq8bgt(SiiyAOsNIu1#K31LnfXow-5U)Y;I2VR@o)2|hLrZNc03(GR4bA63nhd!of zs!A}OLz^D02XC8xPR&mkN%#8=+6mVQ%DpnRKv{C6uJd_TX)C{(JNwdv0dnFJkG58& zapM67HnP*rwjhzQ3=VcLozAoZerv^dmfrD15un-M8*5)5KtZ}{nOFOI)sxaELxw|r z<~{3@q_$M9b$3eHEvQe-)_V&q2-Y6WZp;angEc;C_Dx+lJ$B^5d0jz1ILY(@Mp9d% z_^h526=k}Q0ZqZD`J-q8g$+L*bC&Ch`)dU%C4WvQAYV}{&nvr}l9x2~7PazW z`4dh3hNw)WdYb@`c;x!@rB_Yf5`mDmT)po3e*Yi)b35I{l|I`DC(G7}n(oG5o|R-j zS{`a0K{wO)j38ZoMjsB95@H-`OF^2sKK%h?VT1>>9@$n+QDFoInKWRUl%57?ReH)~G*v{x#&W^bcXygZ5Ha8o85eI8aO-1O zd!3x~oLO+Y+SKe{bZ+d}rdj19_t3wI{@c?LFtMJqY9E1Um5vc4;sX375KA4Yd!qb5 z=?VlcAPAc%?#y3JT6>e`i94Ca&dUM|vp!pO-HpD7Gd_T7-1^4FIsJpjpcNHkRqlOH z8RwP-qy$3cQBcRZ2_uoVDT25YVK$iovIm&!-mKK1yHP|8T>r?GH=$wc%s4iGI+LOi zQolVh&;?O-8*AIf9QGq7TyKeL`CBVRt?g^2!`(hQ1&b@y-LDhJ-qV-`OeZTQ6n4L% zocp79Rru=Ci!=dB;0)_v|9)svqyTdP%=`+<>e_~v>6*GfO*kJkt`|BTQJK}{q^}Fn zZG07tGW%Ai#07rl_u^88SEnFJU|Md=x^IW60SAjP_N823-x0nqG=^#V#C^j0| zf8*v`bcU7490-+jw=V$xxc|@+sG&g|VWcn;a8F*1hzQ9Z)9%fv${y{6sy{+o8YKg@!CWevDH-ecOpaYkRbjf(%?-dCruo z^(bYBqRg~e8|f$4j)<&VN-#>(R`Y7X4Jq=H#XaWTRVOp+55a-wLxV4ddMj#zPCr1i z+?zZejsjHLEPUOkhEElTvju|sOD32a*|(+Xmbaq?G#e}9PMES;1pK;eE$v+D~!Kkh)cD>BMOSd2x7c zXnOB_!H2RHa+W~5ZZ{2~+t?-{zV081SX-9USI}~CyRq$ujX<%Z+!CYNG80TN0^s>6 znr(dlXn*A3YF1f(vMr57V*iK=$nQbVM&b@olcv7*#m>2IlKRwv?POI@1DflgDpC9o zqdLx5)E#jDM8_uBf!$XFn&biwX+C7dC}1bueD^j+cpu1s8zgl4*od*7i9 zaZ!gPdkdtMZKmdA|FA3+&)cr;H;-Hn`ZK&qQ1n4ojoM>{0UOG{*tP2qPX^>boVg^f z#hB3?b5#qx#a3?V`;|^Lh)qTv1tOxxjkL037AuTzycvq>>RmOe`E2>QJSIU|F@b{D zXnY?)Vt*JMSb;)0z^de7s2dEiC)~~tepj4z$>V(~bjOjLuizA6VOQcug2F==s~XeN zwPLLDjIoxDr(vt?sOkE@rp9*IZNK8vKJ@QR-0$*GU^UhI{fAOJW+)*xeRT23UQa`n zEt*+#`Ci}JjYi*j2W92N;p;%|om2^UOsWLf^rg3F5cjxmcr_P=w=2pz%aOARl#+v` z6jNNY#o3T$m3l^c5}+^Q_xk}582uY*u@ZE))wygrjeo6?D2T&CoNqtmlPokv77Epl z)Yl|40%J{kcwB?tS{yr+|0$I3bHDx2`7##%;-ope=VZKz)VJ{}EHRTh9#reOo z-3}wt?z|2;&=$#cI46J;eDyXb@S{L`q4tX=zMwW0nr8m9GUH_t!d+z^jadH$JaVPT zle;JKBz47 z&oN0(^F^*|PBxw!Nn4pPtD?4ReDp3;ZK|n#$_jhM=t|K9=2n$?L!VX3#L<2-%`Wd0 z#i6^OU=erUN_X8xYYHk8XTRA7+j;*Rae9}_Ej4)IzOq66hlhiou7;k}(Qz(?0k!MQ zCpU8~X+A$1x_a?S0gNin@$GocMd=i$?;4L=SU3pqdsj0BqqK*D9R;|_K78K=L3T)F zBvoSKnUJr6s+#q$6Qb$^e~e9aXrMLg{SNI_=Tmm~qM0{3+B~Xv2wd)5J~S8!?$l2w zG_DiL@lul^bW<(@!wISFeOlCfjXOl`!)8vyy`bVp{BYG0R=U+gho|v}v}<*ZXSo}) z>Cv&pm$ow}pLbTnT~Boq4#nc%8wVY%5l<=mA=C85j(E`emE6<4tDt;_v&-7VazeHP}$(s?3qWVIA7{Bbl{#{$mJug4h#O&}wZv!4J?1nfYGvUL? zZ>nL9kz^B)kd&Z$WAsGMFZZwZvCh}9cs=t~0^W8s;9X4jnAI?Ju0FnfXC3X6f!mwz zxRxr<*3mJ9dH0l`JXS7apTk*=X4>F&iufkN#Yjkb>;8sYhx;!Um_r#2ueGVL0o!eS z)Yr0aQ3uhc>%{`657KUV@AqlNR+*ksUTYf3q@O#IybwV)s8~8pAT6EA~ zjbMb~D%tut2dl|pm1IFNd-cWFN5vc`UQx1B4$RkaIU$o*NB7vC7c?n!)aY#d1ZV6*S3Algduh?M?B9oh$?Xe33`+&Cleu8YgSYO7# z(~Yw-jE;w=>}5LIR1v;Q;dhXS4b|CN8`tt@?&A))+-K~B%p4vHSz_W?GK-?Da=0LK zl1$RH{A4bjW_tIUqBoht^P7VmE3WQbP5n5=YWeIp$|Ih#2JlnZ3N3`$N)&yrqcWVs^V5U#645MMTMym&j|je zPVqAd5UW(XZ(K+x_Fp|BOx3n8`D|f{!x0#`WavX?(Vit=`N5xhmwrrT!!=U$(W7r( z70~YAeh%)kwTWppC2X`eRblsVZpUdR17~jGVeN_8uYC}g%`jQZ&Gcm7McV)NrMJz{ z3OILHY8+H`y!)>z+SRJ!Q)oqg^{iOiGgSzw;4d#KB5Qw(q91tdM`i98UM6dr#Uhjp zaA9GrQy0(E8>n4FH6GAWI!`BY2mjn!Xp(?5c@bw`+SZ_PZRV+t`d=ho6rRv|pZ)tM z=M}lH^)te+ALD9mV4(4KuBE5+O;%Itb0L_ zby1jxg3E`y?28;+9BXako&Gk;HvHqpkw|3j8YbU(>N_;8M62h$#M|)!>(ur5;03i? z9t$Uch}d+?J4Z!)YbM2B;L$WB1L+3gXn999c}8tO4|YA(7~0jo`Hbe;Y03`=d*-H` z&9R-AUyYQpYt%N@Uws>5TLh;h!&82FX|{urn(0YhAI>BgPO~pw>eIl6L+Bri-J9QU zXe8oZ``sa~<~D@+!-)=VZc6%Z&Xo#ZN1geaH@~A3KyCcpNxv>ho=!Q-`7J;7 z4z45{EP(SO%cqHv?4i*XKqc{=_~E18L6c9TwSsMGC_91>WMnSHorBp?leld=@dr#y3QVAEsHYq`2^;MyCU} zF}eF<9Cozf=EK2CPEF0kToYR6i82L3JLNZvWt)r{U9wB)g#q}_fBG`XRHPsx&iX@^VXjW z3fd^0>KJ?Q0VkJ>Oobd{5r)p)feyj4 z`PlaO-`#-g+EMM&qsX!W@ri14rM3FmJJrj*8nt#Pw#Pb*qV?XVL>sm(>jPF~1Jwe> zWM!?szm)~K+g4|Ru(TbdyxABK7$wJPF&X7ZWLQ*<1NFitEFN%o%qv2ITx)i%fY7X)k1x6~@bF~aZ9cw!w^ucqDk|-l zGK57&Mpw2zT|Ea#?!Z6f86e;Nl?cKgmHq$4+*`+0xvgu%6A%z7X^@fNU9w}KX|chdUw`V4CBU=;!K;MOaRrnU_G0u;cKQ7wWr*JY%CE-zZuZ2TUGKSi z=-UjG@^58l=VFIE&H0f}Vp$=<$n5$m4t3e*L2-N(yw3xkWai?^wJJffnAp!DZDKBZ z1)By1#0LMovS=eh6Hc84tgEMCck6VFiHQkri&;9p0K% zO}u~Jy5vwi^MAh6-|b0hu+;-g*8(qf*(L{=76A7C2Q{rDWtHa~*jOP?pW=tSklL%n zdK&C&%0Z8>^qK?TFP#pQKnWYA)p_cZRQ%>e{AT;VTtigBeFBh>pYgF#;}g`Gas-D= zztv}@0Wwee?(VXn-t!9g>jVkf^rbiIhQq9RVBgx`X9ZIy_&-+sKNOcCH&@{e*~5^K zl%eJ3k~vsg=9+CNES$oszj>TyDOIN?E9D@wIlu1;+GzDOF1@<^72}gGRJ*t2cGHCa zyn5`@SN7G)#Zq)4o|-Z7pkNy&$}whAC-x#qE!ePs{HqLoy|j}{@>8pR6!n-P8Mh(E zO102RHS3BiMvsGN&oN2-W(fW)&3_r2>FSdozPo7_(;k*vL|5Lmu`j3H^vXeu03&{% z*!18Zk7SeqqTpb> z@RGdhdyp?0YXnXh0R0NiOf>8(5&URg+B83B6P=22bkIG@*yG^Q<6!X5>v6Z@7!cNy zaC@u(=k=}%3}g}v0w^A*g1QQNYM~eye3lW&Bb-{Q9B~_8_&{C|m~`jvG}-yN_#r62 zUXX6uNE9d?0Yo1N*RvB`(H2%!5K(0r`Y+ek32=XyG@cD=vM~gI&zRry23#)|R6tAW1Yt5` zLIZHeEinA+eWIdX|2BoZNfwDi(Bl5rtNvY41+cIbDa_o`5he1-8dK`NuTT1!O%z*^73Kle zKT10_UMQ+1eC@`UN39DeXy`{FD&oD%wi%9{uan$%L)F9~8?nO%?(S$AR4w`{iia2O z_wUgUINT(`{w0p7V@^c)$&>cB-1HR|Ccl1FUzoMS!y_y$8Oy(3`)|fqQ&b43&?KJ+ z=h9Pyr(vQ8gQu(!(pfRSHlrB{9gzfIZCBgN}(|HPH#fL1u$hKp^l} z>jyQJ;j5e1m37)j+SPP#u(MAeT`U??p z5vQT2ryp|IcNQ?C)4DEMRxiyD4@XO@$U>IvQ>a-8-a6zbV6p!eaCIirt@u_cTE#2# z+VEl))Oh~*eDIXEy`!|RQTtV*%E<87;Z`pGSr?3fBn$kOs?)yAU4l1>Z>2G(6YG25 z1C{vLg2YL##1$T5vKLlXxxHIzHf>$@q{frRUV?Pqe7`5X_oaWp zFV*`ND~D;8LBEVmu(Q|crAvF4JyYx zC_HX$C-RFpzUCOQUudiX64x(Arg}}y$(2& z<`<#*1qP!Q?OF})hpC(AhWoxwD;AELqaG@XU+E?asioKq6Ju0TU6tSh_O4+uNlz+^5sR~Mvn1F|B`S@caWrpAf zDg!6z$*bR}m9sljnYyv5c`r>&gjm$epLb=y!4pwrOCgv<(@liq>kqML=aNa7y<9!mVKTHzs11I}6_BBG$u5d6 zU*Us3L z)`-9e+$|zyD4M4QZTw2c70I_W=D!;sl-UfX?nxWM+w(UZ{;B_9C(%Vc77lOS0bhzr z3fpizw#=VeF3O15yVHRYe8NVp-lYMJdD6*6tZZZ}s4-}|xzMG)+5TFO4d#hNko~*) zt>#?1TMt&Txh^U{gt0Q~Wkkq~5ib6I8#%Q(08h%pVH7_z^`CAK3AA6`OX8DVLUh-N z4c0ad{=W9VLHMHa#Rnl`?w3}7IMtme^xvO|%=4D%2zEsGE z^;t;qtAbK?;Gh`#iy&^av4M|Do}eyO_bxwmQDaOBs{VFt$EHk07D4qW$l4dlC!HQ3 zq`(e+eLOfIArjaQ(9$dCC@Do{V1!y1lXRuz86N?S_GK|%cyYytK_4RLY}ipv_S++& z*4m6I2F6Ck>X!p8|Gt9scU-OBbruw6H1P_EWMl65N?q+Iy{xci#RP%4GTc|NdfXvt z^_V-C2>2&-!skFN_ANWu`ZH%+1JEb!q&eOGC4jvL&UMy&$#*^h$={kakp`d%8R$c(Ll4r&MeCB&>}5c>P=%TWJCqc5pt?|Qp{ zA^JbeB9uMg7vhSG^Wb9V1%Cm~XwYoLeA@HkU`WiF3^-~WjCk18wFZT7KG&lQ7#w8# zAWG571E+!?*NqM)dU3I0aj-T1HBFeB!wtXlQL)MX0f<|G|5q>D=6~UFY)(hmNcRNZa1FgR0L82f2e0rW55)^EhDa3t{6HQU@OLf14#( zW_PNzKx0mM?NLQpdJaW~?jFxc8JUR5%K`Vhu?-spc)#)0|2PQHOIg4wUY*AW&MO4| z3Fz<#_vouUGcn@2{lK{>0NsM)eyVQDFe3UxM83ZGPyUJ3N)_36p#llB(9MC3Mb{tg zm3MFX!*l`fUrz>C>`pfN6))j`Hai}V5Tn4l!^(e%-}H;S{TH<3&$R?tAWI~S^104) zX(xpLFcG+4^Za%hp1A>#>&xX#!op-d2j)bi6l2mRK$YNB@4$|9m}7{GnD*-faJwR{ z3HP00{$7wX{Jga!0EpH+z?%WynzjIzXzNCY94vHY(I%?NmX#@ffacC{vSk7CbZQ20 zadWdA?y)4BHj;+v^Da04`>f=?!*zNmV4TEdfY8hr`iPA0UV@`X+Z|BMa$2)TzlIMW zxjIr9-^`|b1T~*^Z_fXicg}0o*PSW+?iU0LIe`h<^M(;tr8^@N@_MlxY=|bhXfhTU zMspXgv&`S4X!PxY%_k5(=TOCWyF<_1FnetJY8b{VN29qzOeJ)L6%-jT#=9ke$#ZN> z&o}~i&JU>4c1}JAh!W@p1_M`g+1B73j{%IzT+P>*UhfisUjl@}08kh!h$yH|9KmtIpNOjagcmj$4$H9@cFfgZI7Md#ac~G9tp!YOKQ~fwcw^z@L=f|VOU4LzQH6!nZwbQMe!1oFdo)-|37T_h zUflfrdHzDJ^_W|%-KQ?XSB7Q{D zcy>kzY24obT2k_CGC$K1g@nk0OGwC{B6?!0OC>K2K2V%eq@))J5Dgu#l&j;`#W4dw zXbS_1&EPmEb7g)R-f0^y6AS#X^a|RH-q_KWCnn|N)~-x?(_A&fVWzT)BWJb~J;tR* z$qCH+mp1GAPSu{(i}@wFNR}1+9$v-e>Mv9v;%#j^%wy(`!%RS7($6{R^O>SH+0We6 zLaxNV7_-esPP+Z=a9cI`W}7f9Ugm59SUYsn_v4}UZ;IV5@1`R%pO?}~_01)d-E?Jd z{N|%#aOrVa8Zhp0paQ2&{Dy;VY0qxhgefBl{gE#8O2_AIt4cOR(;h0Tz(IgZG`4+W zpPWv&j(`OLQkB$_>zBo9XvIqhJW-4-(fj_$Fn!tF^zF%cYva26%GvkjWSJ=z9o-&x zMVofdO-w|E6D@pAuMu`CdXvdnbBo*4)>U=TFT*1HDmaKs79c;fA0@_Rb zVZ^)3l=5CJ<}r)&vINF%bqXK&_oYTnc!6TggycgrjM&ofk=8tKb@DCVXu$fM?TA|V zFIlIgx7vwv0G?JvuTS>G4d@?^8)FNQSydNgmSbGk)e({s!x>vAF&QQXU8Zz%0l7Kg z>{pIWbAIdnYL`S*p3t3qoHo`2YuR4}qMls=kj>xAto==9kHhsTU|nor=vp6K+PDk~ z43Ge%uJCs+ac<&2q^y`kz#%v z=h6>@{D&w+0dhr2oK87zY7EZw_q1J^+}=#{Sbf$Y)7OLee|Fzo(z`R^)w2SE0%h6# zj!h3WR=I@l3?~IZDY1W0Q3>n2cS z1k{Bd)wIB=wl8ss#rfUA=bmNTmYuoF(!jroi+X1~EtC5Ed^Dk3^Eh0!E7&6R{ylgU zjky1(`UCd5Dl;-ij+A{s5!%Kpogpj(O`**B^Hdw?&owGi>03>y_C4 zMsyqoiPjFH$QXh))OkO)gIai|i}1tLzX7|YJa)J2|0^STd2#WKjfd`zN%Sq~v(smd zO#3BvAL!Ttj>y5ui30aQP@A}wyZJrAIOgECdk`L9rwP?Lu6d2>xmeBO-0NxHwa}w5%on7Wr>l5=KZ`t>l@#e;7jh zjN=!}8$3>+Pc}g#W3yAouCFq%zXq2Zi~d zT9!1i$YIwwA3FpNLdx^wu-K)pzVBa=*?%E7{y{na_C8R7%K;<09PY^*=Zhv*Z<`Uf zt@|AkoPn+~L^50D4^dHij*~#&fRpKC?nMw|-8IJSi`D9l!2+mim+JZq1f{5|Er5wJ1l<2EyF7;y z%zaqV*)iLMWiUh^3XuKgKS068sk41X0zI#E29sSQIR@cY8)i}8o#m@>V%{+!`i?7| zB_Ohpu5a>({$MP@*(VkXI19U#%kNycm{0z6;YEc{@Y%hj5*#G*dsq%oQjE7^vq^#4 z-Ol9)?KuTj+QHb z?n{jyP2Ke5uyUXReuO7HZsMy4#8f-N$B${O?C@DpG0}4yJN<&yMlEjR((%Vq0+yM& z1;oEU(B0Nrt)Yfdd=6g;@UoG;+j~uAy&ym7U`%^Rk>j74y3KR+;Mb1|JhyV?uiK4q z_LNm0(2;)8Sb|877-A2M3oRXYs}su3^;Mvw24ggF+8{Y(s6kZglGmDjP{0V zz!aWYgrqF3if>*9eUaq$ND#Fe_Gz@v#C=3iK(Y!p2~cof}GT zy+e*%Tzp;OwP5LBg@OCutRtu;?8Wv5xZyP|7>UWHOu>fgzC+8{Awg)JC1_bgPw@#@ zQF40`M;hRz&*`(5(G|K>pFh<>l;p}TVB3cimnt8hv)-$uu>0+)!RYFfLcc1@o^^ZM zV>Hs9rH@Dq`*@SxV9S9wX83mBwJ0WG5Nw#7kwh=eBax=)zWcGv6iMNmed`+`ZJ z=K@`NDo^m<^|k^-q2GIhu|Ldo(7|sA{N^7lHfRXOR^8Ph+0bt7sQj&8m$f+sU z)zL%*zB?8!H;fxa1>*%4TceZF&U1L3W~vpUvR$~KkmXo$IG4vmYT9@i4--KiZPDUZ z20mC*6I^IG8ZgH!_#t!pPH}3ohIAwk(kfQd!EdI3LcR77)GwyFXU6bs3>v98=ri+N zIM?Off$wjcbaQvJ?d&Z6w{>=PW2VGic^yyryTi_%8NBFszGrxXoNfBb0K zHIIW|n$ky&@d>`>3y;q_bnhf|8WhA10S^a=dmy)a7rg>gN<2d`JD3vuJ-8puIYOCB z*weayF!3f9#}j#2U*aWUr}Ze{Zue@&8lB0|#sxo+lYNXI_CgNBuWWLwh@aHDY6{{l zCg5LO+*w+Qk%faz&6D(MY}*lti-M6YNrxgC6;meWH@Wzn@zKZ(H5JxRE@E>cne=Q0 z3Yq9tAzT``r-z=DKF*ZD^+T760>r?_RXh+-`$SCyWJ58s5Q3vbsPhqBIQWRx$O>8N zV5*`cmiwIqUx(I#5U3Be6vP_@XsEGm9*-M4)^Pd6b!;L+zzHB9qD`J|bGePa1{>mu zBbNe#B&m}uOL0|HC`=gl({jfHz`o~?y~Y8(#(vW~-nsOF9c8oPAA{A{tbyd>lqEN{ z`b!>M-`w1FE`(1v{NFrRf3=EL_d-NsEkFPQ0s*qBH-VVNQFxuR@I~WWKhNw$R3MtW ztY=#`Vi{OG$;}7C^p87pR&!oBYXAiRYaWtMhD0Eau`h-u{o?YivWip#MYWb?<VgOmwncQ4v=J!Na7PnR#oGC_~V?pp8My z3($wHi~IJ8-zuk=sr6B)WA3F7&{0cCR}ewA3%>{$e-bcekF!$5Lo9Y?ymkfXsJc*2 zDk`d@2q!o9G06jjPA-``u4!gWEiwz?eP>`_s2Rk7#4)J+(h}ze&f;QV+YbX8s2Mx% zpl96hek|J%G_z%=G0+2Lsd32$0U|8`M{|Dq$%u%Cs=*&hL4h440{`%74ER#Q3`=G$ zmqWN7j!xpYqewWdrX4y?RF-iP%dBy zMMW`EvK1?$?duD<3U%p?GF~<|z?A09o*)52k=6#HBRrPE_zrNE2-%+B5ar8Jh*{w8 zfF_(>a#e~%K~_0Rz>7e!AF@()P7n=keo|)89oe~ETJrQKT3|n&tZ@uuw{=Z)VXv5P zRlP`+5LU20V-cKpIdxX$k|AXZIL1rCZKhSMKPR6LR~_c!a>ZpW=@nZ)0jpOcn?ODY zR+sd~)_=p$l8U0}c9e{|Ck_bf2Zo90(l5YhoFGnXflKU7DUheWWdRhVl>gAWbOSG4 za5`yrr|Wp;NS0@TV2ev;^hL`JGFR|?=Jpz+Nex5dBk(W$76Y~V;= zJWiczIBBJp8cfNEaUXcHS(ci2J;SB`Y8N#s#vH-nz@3K7HK}i_}3b(kTLF{5)@@6JCy_rcumw4NoVHi<08@2w7#@QflE=cPGtu0o80>NKm zhT!QXUb|xY2QCyuDeCKm)?$*uJzsTV#`Kh5iXU12I_h9j;B zynvGM`C*&bo3|egoDa$p_{hp`vo_du5=-R#zqn6-yYbKAk|8z8%^hI?`N)bT6SBKy zyyM2>9ecyj%u(Z+|(MkZWQ z*eiKaJXFv1Htuj@cr?D(ymSkiiN<-}L|fYXx{153K)MmFiX+jAPVn261KBDGdCss{LLXtgELZ{^K;ml?9ET-zG{eJMj{k(Ixe*o^ z1<`z}D;OdDGyM{E5LJ17kM6u$))X@I@{ zUwxGdEN{7LJUHA_&g?VJ*97`D+P<2Oi%l=R4z!Umw%ySz)+gk~s-4*1z(HOPoSaed z3?~%agK$`yi7WY?@ubxs!01iyyhQL`c8Gf@ZT9TDZK)DkGduIWSZqJ<`vhSa=n7pKH3%6f)1jJL?c3>4);l8 zY&#D<5U=H6&Pk8Eegp$N;>wUlj+G4u1{P>+9 z5up=sDdfQZB)r!DP?GEu|E_3f=i;YWmtP6={kZ1sf{AgBIQ4qtYca$}m%p3x>DThWzpTG%*qe$h1ar?1QH1^MOY&LisGr2OaQVf%|{6TL4&Qw=;V*x%uJ z-rhK5H$Ho{QHMN~^gBl5U&UOn9ja~OKi;O*Kh4#1Jayix#qFH*yhc56->#?7;t4C1 zKpI4!AT3)FbDg23ACo&KSP8R51R?ikBRGK%@jC0n1V)C1HDZCKtc5#7XLj6|HsTvO zv#E%Z9m1<04uN>61=~TP>~E6`=Ucy$j~qjOd7plVo6wdl>%^)Z<_cDUnoG}m*_xn& zgaq2-HL0+~;+0mt%_LqwI0+BhKHtJs{Fse&$Zo7 z!WSUr@Ft;Q%~$gaC?gz6HT5X&7rbl?`?=)u;RfViajc>Fhl3CWb@uH<>qSn6XWpla zX?5SnN`XIgvLmu_80nBO#FZR}#O9k1x2w6>(MW@ek=GSvHOcWc*A|yHye#W>I?)BY z$V~UZufk|~k}Dws$EZBCHLN&?{M`ErT@V6<=^@&H6zt65Wa4+Zn=Jg$J~K&?GvBG&Af&py(T#< z0l|D-_@rO9P{d)QIVYx%OwH_Z3f*iu78&hNOYS_jVhi71XH!(`pTSVQ!7IIj{so68 z`Y?Ag3zWJHl-fwQfE`NU=eyp648Ti@@!TapEiLzYEywZqta^IRwD3q^bP#!zC2zRh$h*%;-PI%n~L8o zbxtPIg=HmCNeHn*eMll?hRnE82i?M5DnJY8K1gRLpDH0vZH3z!L|xC% zte6T`QS-?hF8aa5;N9pdpeETe1nMt&_K7_QUWLd&4|IpfXpxxUghHEm(^2{Ohdkn! z>;>fT6WTnMy_jMy6}@01MGgM$*6`)Zi%RX>dU&5ExE{-kF!)balY~Nj+0%@zd%PS9C?a$EYbJr1JA>73A&CTJR!0db)tH%}I+AWdkRl9pnivZ|30yje ztcqfU&wbSwt8$bO?Ep z_^mZk?6<(-(XLcCt~nToR;8fY2|E3$$lqVStBAu2v6HFE7~;AEreDG)#fq98*H~yk zx$0cDHffZw!J-JLF@#(e-xI= zx&ngT@Fi-- z+Oi4m4wI3RHtp>_F3=ip+yhVeLL0@n*!3Bmkc_N#Z7onOnZTG2kW*JRQ?eCR0yLN* zAK5wi*w70513(BuK?Sea8BLm!!ty1!VO;0DJx~nAR@JI{u()Wjwjn@kX{&zstizUk z*|;ko4Hd>DriKPw5M|mszqaP#@xcJ#Y#eZm?Gh3LAQ%N5zf9221oU1nQz_eY%pd%Q z)l05T2;#o5*Z)?m_dkQpC}D-X;E$!tAm6nl_mNNoIYxj|K9GG(@5TiOatZMTgY&;Z z4tU^5rrw`wUzhM79ycx1F`#~3ea-D35b!YMWt$ur3u|n=Nv}Y+XMg~le*p5ph|8;~ zr4rU5Fe6q{)Dt|_lg}^aY%8@alLUug35xGwv|0jnccrZn0%fH2%zR-0Y=CeyFmn$b z)*H_NGE`mNI}KoHjtFJ(rg8Rd@XW?t7QDRQgYAn~T;jTm(+Wdg?tooR;@ubfmBpX; zf3pONRUs-acSU9j?e2t)H&C~h7Eygx0JnSn=I1HS0ENoK(qj+m`Z3xnb9Fkwi6;ph zc?6=iKCS7BL&k|Fuo^QZxw8xI{-dLr(EhKamB))i6XJ}B9BW9yefw0jK6PbKAwX_WXO6pw-^Nl>V89{|e1*aC#34aM&) zQI%GY18`a1oEsJ|^BsamczU5+c?yFRkAj91jeN}tBy{vVAePFetfJDqdI$#rsY?S; zXoTHre@5Lk$BgIYJ;*;Q(&c;*{7ItSbZY-`h@6mJv%p;KwH3n^!J`k+%^#(t%{yIVnBJqUBgk>Shk^}W%zb#JDqS*#iknK1+o5w4Eb^44~D zJHS?kN)*sqO?SBVU$#;Fy8~cOUo#zEJ)x2RwhYN@^h(|QxB_TYP)(pnW&)p^kh zi&i%IhXfbZSgH&6Kei~~iciIWtmC=gCF9G{(y=?n8@n;_^1i)Vzf@E$Ri0wB8W~Zk zygt!XsAvw_LA?&_P+kGnNc{!C%|%1a)o+=Hp)75gDo*JRi`>>0h6oESC^n_tnPSRX z1e4yQVY7{}f2;R=I>j7UNd!jbTYu#Oue}1Jvu2%HZxv#HEEWIOUS`b~=oxy~boF~s z?m0gvCIc`m2GUhNCA)z0p)ZV%&#v=?e73p0@FgV`aOgil5#fdu;5gwPQ|Mjxrnc?s z9HR`gU(om!(7L*3Rd7urs1X_im22{hUvR z;p~%lU+`dePRw9;2?vyP*%1nPDCA@P&_9mbeU3O`vk{W`?C~2MtX?e87vNxZkht5l zecY_))ML89uA&0eSRbauH~#$j3`Dj=T+`Wq2Un$*FT5^V9`9UCe_pq(SrYx_#O)rg zJ9-kw5KGveP`pc#8TwbZ_Sq^s*!8pZ!xA(PUZuNjazY9dh_Ge%)q?aTkL%Z0H!7)( zv;{S^d6q)_hmbwLS%HvSw*%z0jp|R(=gaRdI13u87;6;Z^bP6=T~3Yc>wb`@S-Uyb zJ+1fttm6(Dar}B)g=Z@KWYlDEvnQ)7^AXPv_^j7n2T}cL7Y3;>ufM#n+=9g1Z|B!; za}%y4H!#SNSleY_9SoUC^}r*w=zqWoNjm+yC3>ni?vOXnR|N7J|I#xpb&O%KrE`)X(#X!YMdQ=>QrAb>a>IKK`nJ7287&C*_nhs9C@ z_l|m?l3u>(*g;uXJk|dEmOBD$dOL%fyjqaxcU(!{e468qdA*=`b@9uy*p+PE$k{(J zVy@!LBkv~F{mt8v(1+f^@=m(P^m;YU_ZG8KJ95accqs>z=eJJf#M&5UwM;Tix@kjD z-^Y8%IdF0zS)~p}>fBGQ+#xg9a^!!X%VO6oNaH)^e1MNg@@*u$_MA-XR`>=TJuI3E zvu7ye*F(rRf<;07X*A{7<{(34zGF99s{#9;vjG26ExYqQ6cL>7bDk{L1qoHHWX>}0QUau4a(yZ8cyUej8s(({jd`)-BJR@2&U=T-Ih>HLz{gh#@CQuL?|3Ea(g+R?o(aL*o4 zrjJ)nf%ec5O16YH)3LC${&xGpRYwbV8h>iEMhe>)ME6XkHu|D2x+0wW zHF1?svEz^3OG3}{vPA3mw{mC8(3Cb25|QQaYPNEtWN>JU%}%tFb8!I^k&wBXbs^=8 zsKgjB%d&)g*|;BWI+HcrbUmp(`MhLMUyD+>?S(&0P}%x0Ql)B|EWh?W`USG9O~E3X zezXZPiwxtVwyJRUHS)E#uDsD_SE!OME<|s*h8J&y-BQ)cbjxqXkJZMDmJVz^umY1V zm?u(aJ}7xP34)@nKFfz>Pk9F$EyRKySu2##g!NL@hagNg9p2R?Z9aYQZmgE;r}n$9 z-jzs--Zm=+1g`$!R9ZKhu{tjIi;UB>k`ipk8mX4cmdk!nt*h%C`SUCz%s->~4;nC&5M2VAaB!R6I)8gi0y?5lxmr})Ip zH{7E^K@TBfk-9&z2he(r3fPBC3LalX`iSrfIZu8++w+t9AhwF z5M@c+id4Lrybvy3V8+}zs|!1uv#6kaNJl{KN|YjT%h2%1@&K;TEzBaLbn*QY~)c6pRU5n|^ z4WUcsxs+!@BA*TX863;_)?dL?{}sHjl1@L(hZi_%B{4cI%s-S1X3r;YQM%p9C4M=b z#%PAQQMtBA*cczVRaZ!+%THNoP!B|uX58{DvzokY2+3ekB-@;%S3GnVz#k1x6fuDM&I0BMxkp6TRH4*CxFhodlD1R!<;!ygz%e4L!hmL`X{gm-$U5OA8qTEua%s}6; zXvvskr+;P6e<5FHV2WnVRD%bdx@F?oqhr3-Nc5>V_`+hiwf06?`@0<3@MVbAt8D`W z2${%rs*tZg=SUHSZ*l21;g{^^drD4Jt0FBbr?M#uXIl{p>R#U~#qlS5z5I6N|MKcN$@8rts`%6b#)5we<&svy}}Nfdx)I^n>k`u$CsEpzoR-28mxk7 zFg;>sv*>@kcPZ1Fd$mq&yjFJ2Q@-k&Qg+j(wOHyX6#CFY$5-b-c?elX`$d>d!7H?XX)sa{7uIE|0wrL_`>oq8wBUlC*rkkKtMr z^ov}zmO3voXkb(b*P&$HoS3aWf}5+w|J>}(PIk^zd#=hoKRlGUH>%@7P-kT45_tM6J7glGNY;VGufI z*SegQU&v(1jCHVk-!dRC>?h*^afg1@FFPSTZzonndVH|yB~h?GFRl81b}E8&G9vA$ z#AZA2`pN;#$nySU8+#njYp2d=6fZkG&-2fPX?f({TK?b2f0AH9An4W>0=}mnwg~RF z_gV_w(X%}FYm3k!F?!<&IeNZekvC#~JQc1a@A0x`_^~+8dgcd-LH2b9B-;C6r{Cw; zSUp2A_pF4CoxIqL)gBhOsSo}%tJWJ;hT;xHQ-O26yPo)|mv-AH=eO5Udu!%YRHAfD zy}Uc7FUzmv`sYq>=AzHsyI&R4zrCToU1nEm_Gk&?oNdoy-I2~ zIaHM^hqT4>Avz)+Id5qDxY@5RxUr;-QV&ScoZj8yf@1*92^U7J)N$rK&J~k(k(UO| z27XbmTyfZ+$ccqahT3{8mZ|M*i(NYTToU^d@}52k&)g6?;M|%V3SCB!*sG`!4(Y!J zW^MPQ(s)F_?#oOAa0sKXBRG(P7Wi5_)ppTpD%Ri!4tS@!4~mA1LZY8b)ih3`S@3RkJ%Fuls|KX$q>*k7MeX7q&jTs1tL z1UD~};QC45t=46`j<&5u`|%O9xnen>ay}f1=UM0s`3>)k$J0~Snu$UCIzqmY@SV5@ ze*>>F6oeccR6i<>tooZrF(xFDk#RzwlB90U=EP3KMwd=pS%p%BLU`K3bOb|{X#3~- zxhfS7=L;8y6E2JS>Peh#C;Q9TFN`dCu-f+$yxQ$<|C&zm68FM=-31bHr?d;zk_hU+ zNsiu*U&;g?O5XC**iAC1;?K4Uibrm`$j=^PDZ5{QGUAZG*bZiEWl3)Srs^5$LlPH9 z(_CmgWyT#J(T=G3-Y8x+M}Sn$*qph`)1G|y9%QVPp0S!e$*2#Tg?0F3{pRvPo1e%VOD2CvnZK|Sj9`TvAV-PL*Q9n7 zj{>W-J}Z9OFaNwo+Vl06i3BTJdk)2k2e9s^0?*%ZoqiujTpxfNk|d=eGMOWF z68LCl#fXre%yW3QJKsa>I{P#0uh`5Q6xx)T4|c-mPxKRJf26t+c^E*ppy@X)r-sT8 zBS(O4M5{rS@J_?cESJHt3bOTsti7JM3^uoitKJnUts8lkO<4`7U(0bVW9G{PqD8m7 zPQ3OSIqbaK3|M)#Fp8buXbT;{_oeXq!Gc}j*w_5(+e`WW%+2t+o9_H-gTh;Elm4Wp zVyIV8oQ^ANUI8KFjaCC5jl%@DSkN8^j&KlB%>|rRaTj7Jc?-Wz6)5cuA<%H9e-ipK z_tD04LlTHDUBgRvMUJoTpWomUZ)0s3>oWtN;f-<9=4^A8m0FO54r%*OFMvu_W}7z` z1)Xmi3R*WJJmDI5=c^gKBYoHetl3=7r#e#&Zc~GI*`s@Y+A}U_>HO-eom_4QA_XN~ z$~33Ffw`}yg*=qnzLydS;uA%@t*}I&Vs=^)HIXa0fRFV$LCwa5ta;&O-N;>XO{#n$ zF(Dw8>R+*}Q73+pYILQ3l!B~K^5An~*+m-klsJV5^Vm$sEN=RY*Ll!uAIVwhDDCN` z)9`GZhXRjqfKkJ@x<<;?*+I|ntNXqcZx9GyLWfQ>Dmul+I7f?UN)Om$bXw}Bvu;z2v6|vB8 zy}i>T(H~T5(l-}$d&o3BNA`#$seC8k_Q<0+mrl0V0gpZ=siG?Sa@82=(%kNC{Xv7C zlpy3te=cm;w8HVjOUPHWo6qD@vFnEBUvV)Yk{==^1&{H_Ux=VB5V>Jcb)IL@?@R=A z9SjG|Bk>fR)5m^C^1grJd0ZCSu?7Zo)bYf!v$VXMEs9z+Flgf0aL{|**6T+V-j@X} z@9ke{^94MLx$quj$Q?M}W|_0|I_~HBxP10g#}mOTwhm{AX;cevq!aI|t1m1o_l;}! zFIZX^)Ya<+0_!3?QHX`V$^|{-BW)QYR?H5{X^7g2Rd5XeXXWn5iOFkYwp>f;AS;w-J$PA_q5N)6}PUMZ(FPECagKAQZjWG zFA}>UG`?!@r{4sihA){4ecL6RIX~IeXXKPNnvSp@s)IHoJ+`kW#VKZsVSf5?%dyE{ zFKO0GusW)Ve)fdD*30gpG|8uZaK!JqTKivim|t&L8oZ5sLOagLp10`C1W40*pFQ*M zJAqe0r&ICA%3<_F-sU-OlOvR54k~qRd)Ch9hGi3z=KhY;yu@)~9y)72S}F>8w8J5tD8or%rX_;ja{%g*zUdzYJL-mBpz*1hfTw-eD213&(-LE%beaPif9 za!HZ?qGacS*m`5S!cI2EPPl&PM0`qP(RUL6IS+iL2lHd>=att1m8S*$i^uuf#Cs#R zr?=KtZHfZ6)3lMB&13;XK_h0+`E4EfiXZ;R36X8jY=rd-BE;m=Sq@OAITuwpeI(O$ zDli~#&UgJfQnYr&9|k)u_N)!@%HOZF82R*9PAR#}C&isw47>tjZ=zLKhDY_z+|pFh zE-}t-!k*_n8S6~$PN}VB#9H3)ADDkoEup1P;rI28by?|cuL1{?DDb$j?$$95*@(#~%lO5)kZhq)Hs)Kty_6DdIy|pd#jR!{2L(vQrcmpXs>2cUf zR&^-Z13Ag=BK)0Xf?OKH zp@qMYOPUsE*<9?=zi>6K-HQ9yX@Kdy#np)U z9w*0ADtSZJ`5=@t_o~dFo)1zjwSr7$5cn`X9^~CF&Hf_t!nsrhX7(w#Y4*pH6KtP8 zi9n9j!h7IPisM&&;x}y^;M2~;KP*fuS=KC5#5kpH&xhQZI$1rGFskU-i=Ydp;UWUJ^f%2A(&I*0ECmkGu!JF69jZ zwFe{cOv2DdyypB2ht7>X#h&+Lc0>{;Pf*1gHhM*)erx!K-b74H+|sdoL*17oi289T z4+l#wFE$PCNbF(6oxq zcK|Y1eY&LYv<^5rVB~zrtbLW|M%pCS)gHl*0Vk-D(-NHSEx8w&{57SoS-DWK)lEc1 z`bD$i)ppzw|3S~uI%^#Wsr0oj+8k+ZwMWrJix!$JRv}w8ZQvc>AB9p?>XTYpSdO4y z#n8yarmgC8FYJ$d;ef;|v36!|sE=36&g|RNzLOF1GwS*;RAayc)hz0Bf6p^{<{Xar z2329hX<0#lGCg6l-kJ<##;S0Z>3_}v+g8BF)Bz8lXfwupfRb0ViH`uxU4IV%eJa^& zo27k4LG|^X7RAK=LRbU&_O(urI2~kG7|-(FzgJYMxJSC1jGt$k0+Tul?$BD{WA|9W z&j)IMU?*XF7TkT7gU^M=b&JSWcC;_58b_e(98FGu=+q#mV6TPu5 z>#YZP42tTCVeGW>k4f;MYhTZ)SE{j4*tE(YIGa0Eb4zu3g#L^|uuSd%Z>=ZaKYkaI z^eO~!_A#kdKOKxOwwT7uPaq1anjym1J*jiTvtFrhzQX6G-)>UBR5>Ce@ng$WDtvF& zOB_iJQKBtHR{pwzDWl6WBwR=#_4*>FqayW!`R26ZhKzuP>1G@^C~&1K>RY!0XcoWg zYeFKTW&rXRiV26;XMRTScK#bNy^~JrZ}JkqrS%$Y_~A&bdwZY<=%2lDKYcuiNYoNZ z6FP)mS><-}D4s2})S&-yrtI5Q$)w&CP<;FIgI)(?*K+rgv41MxxN2?fV27Br?G$C? z|3Gt^u99N-1cVRlt=`MFolPpzVSPtPaY%f+Z`0XvVP)O4@;U2DRw}kcNWy)WydeUI zR-Te1ToxZ2baH4|_}7LCWUc^Gprtg-tRDRB_&K9`H5w58LANS%kWtiDL=V0^*YQltJXMqOrt9-30>;SK$q!aW?pVn;O zlv{rPR#WYUg0yP+b3GR5t+5c`tj%x6rg`jE&?qCb)#O0X{B4Z4+=e{a`+?q9`im%eeBx8xRW)jCkQ~pW?YtidyiM@qK8WTK!FJ*R zSsz#|wjWFaI9+>tT$qMfaphd?*#Iz>&}MJA^b+zV7rfnF+up{>GuFi^-xxkLwV>!Olys4Q)z5jUCnk-?|rb3>DQ>}!2mL7Ci^+0>B)7MQ5Hadd656a zzS&a)+Kh%^Cf>H>@sMnJ=XVkbE1h7O24~_1?le_`Ml&TL>W5efzxUsRR`NRYx^bFv zoxHS*^1i<5UyUP{HcoxG)QO}QL zSk29|l=U$~{d&i$=Q#xudiL8bzMD4dZMmlJts=!Y=l9jFRU4^YBC;^A8P_5^Tv~ds zp6Af+m8vXsd63x?JD$OWfXA!qu7e%UqIO?Y57ond8^oiyIugVbidTFk#zB4nG--e~ zo(Kp~%s5>;IA7#6q&ga3o~P&13pw1T&Z#!sp!@s#w{5J0!KA=$oetaSP2{jrX0@wI zvzsh5=1V)78Ji)v=qLLBwRe|sQLXy|#|KeRBm@Noh7>`RMrjyq1%^;kQb2k@x=Tc) zm6A>cL`u3rk&@1l8PY)-2awMD%;=7D-23eN`P}>Bynq)9I>@Z$nq2?q`zr`{Pt7?L z9P9x}GjZLa+%fZUSZ220S2Q+*m8O;=Ai=>X8;J}cX5E>uOXQ|q53gPY8&sBK1@t6S z+X_bMttZ!K4gk2+_AMt+>_9t$v?5VRJz(yPhey zHfJAE30zR*q0xIdtwGpxo~g!@Fdf7xYw7q0MQ-wzqIP7VGY)H^1e{HC0MgB0D*4Xlkb^!0WIaJ;wD+%AE?g*r4Bx6MTil%yTmG)c8YDYHGBn=*%`)$e^q^BT$FP5M z!Ed;*)869ojkSBD)Ndz;aSzOiu$@CLE~_;T2|Ab(;{3^v-Yc~0@pMRimF@AB(l65z zUe^#1I^i_Rrls8=MTG0PNdDw5EyD^q6h7d{Xx^0U1XJ|hS}6gCJT-6LmjcZq9H$+VK!EJtGY->j=5aTr^V}s7J3tlljP6k$|Z8Cmv;Nq zRikQ!C2Xl>jEmdthB8+xmadF4XL;I?_QOPiR7R*MWXBqB>w8_iXL8P_7)D@MU6O;6WV#9s+b zAbwQjek8YJI++5fodZl@n#O(yBk2VCg^=tNf!i)Keud=PtXmw+U{_>Y z4t7Xb)y#MSrU~5n4Dz>0)gJNiL_VkO$P+|KF%r&v<=7Yt!IKYmR^})CylSUuuWP`| z<(pi8F@;~llqL2?(BTiESqj%_icM@J!9%o}vSzNcA)TU%Xut^1J18VQ%5gQ=$g%76 zRkXop$5aCRU~g0#rMsYt|EK=lvgerP(jNMY{2NtE&o>q^Rx0kf!JmOZ@3Vfv9En~o-9XsFLW=qk!4oOyD6s}#q>nn z!P=m|#kC6)gBK}&tG3#`WjWMpwU@(NTX!-CB2-kv0Uu+d4kA047rBF)H z2(ed(!NQrgDsrCBLFtVXUF*_om#u;wbBJxU(@IYmiB61E?`8#cIG>BMSkYTt^%yG; zZz)`8L8m1|OT$oDcf!+TPrq_!^XbeINI4U8YzwLp zh?%#=aqeua6!w7@gBGJF7U5> z8oUekG%HJH!%YeTOcjx>tu5+05H;6kY*QY;2=v*?p+^<*xaFNsj@c?_;-sycsYh>p030_6-e{n4DDV&4 z;s6EyYnAu_1;$ez2Pp6X3JmUP4p86&6d2EFAE3YoDDVLae1HNUpujkA>i`ADsa^*t zu-*X*e1HNUpuh(x@Bs>ZfC3+&!2jhaFz%V#<-g~E!MgZB{Ay;v#s6et2j>%bPD9Bv z0C{Mrk!V9k0=Fq2$`@zPlVuJ52j%xqO`^X6et|Ntto#8p?#KF~bs<*3_7XfRJ3CQ; z@;Ct)sPcv&j|lgaal1;Q{7No8i&Lcf_fCboi)#Dok5~+K0sgfAc=l?EVWb!YLZf`= z`W0o9P*q7UNwkoE98UN3F8u$|eb23GRXkgIM+wMGU-qlh-@up<=bOsP<0*<@J&X&+ z;Oum{oe~#2q>i$xx8_jkF=P+kYFWT`%!FN51&GJ5381MSJ1{0w*ayxW!DGr{PS9;o zYZ6Q|k;1P52Q)x)00|37)x+dodMRL{t6hM@*FSoDgSf5ZN1&i9!{pebQmmx#?^vs%9Sb&IXkKyZvq(=m-hj( zdH0J4ppfG1E_L`&XZ3VtM@GPz~?eEdv-wl3UmI;^f z0(|OhguV6o#N+K^n)t)V3fkFe?g6jchi$1W=4ub>>B^uXJ=<-4{yS6_%O4novjEh( z?ZCXX&}h zH$lL^OTe5K4|WpQ2UK|nPQaihzu|k|#aCUd;e-44o{(#K5IBg|8Ot6)kwc|9!el?| zLA1Y2g8i*r2e9lT!g19g{grhAobmyMs=`6Uc}~uT#ja#rGiS%+dK&-rv$%s8c(`Sf zjDUj;R5@G+ssN8n4!t{r)M@_{``a!#=)bX5EA3YANo`(G=HbNgYH##e!;QZ#htOO? znl|EQg|>}6^!4Kb@=K|}w@3!&{{$B8Kk6$H)p&QmU?Hjrxh>LG$I<&&{S*fn95w(8p;q?;W+n)*?IRV>C=R1r>j`=iaOlXWSw83!Dp}197>hooYCG7Kq=obh#H} zWr6i9VHpbU_1$WyaHz?z-9ydKS}!41WUTAefzuozvm>nQJH&lqzV~egP~dbmz*8E& z3HYIL({&@NKTfziCM#uwap2TV7V+n0%a|FfsnyKa7a^7JTf`?_((`>^+Kvbj{u{!YT+BqxY~tcPe_eN%Ckx8Umnbs!oV7rDkHjze=vVrd+byEj{#jE zv!&(5ypZ_3Jh2uJg45@}$NW88&cq90rXoKZFClAMI#?LxVqH1>j14Atopl`GxS3fb zq6YpHD(zBQ064M`61NbdpLZYzJx__;U7icdAH%#cb`@g|l`Jg+Al9X<0xzZYS{dbB z758Ij??Dhj3M_nvEr|sZ)kIERWuqd3h|Gtq++_>ndO!1sg)UfHMddf}H>*T@He|5~ zI6>o&Ot$Sr;-7KoD^j7bsaY~xWZfV_@O5Bs@=dKH>x#5r(nVgEQFUcC5ezg_5%{hGw9-8ooNPP|7l=u$>6L z2?m)f+LPPQk+6l*vV{(|ebodm5Er9tZQ>AP=r{9wVXr3m=bwPPCcmQEE0gBE3(Iw1 zyVp*JHi2?&!PSrBb|4FKEvneSTHg)&F4`e`!Ugg4DheAWHgcC|yO=iciV}5m0coi? zaC6yC_+Muxcy{WOdGEL!_VhiSII*UD|Gf5|<#_{HBcRhsHoJ{CWL4En|S`#ehhN9(!Ipn4t<-Cp6QK)!L_Kcj++fPie+U zrX@dRETz(-k%;jJ;AzQoM9B)b{g_M`sYc1QFt+mnpmoKJwg6WQpt>VR8OXs1xt%-f zrYFFB?+C<$9!C2WrBe&i@PSsL9H~{?V!;GTHY!wH?69TZ@Obpjupw>tgdg}vKx6hn zp*e3)-<3C6S*l5jJ;a+6d&L~=cf!`7uO|Y9H1c+}7S>BzY+Q7ozcQrH4DW3HDzncB z8o+R@rn#WsJ0gaP3x-G%Ze;3))MV?JM*f*9bj~ z18i=E>@L|o1pB#AK|mQ(-|)^luYpKkN5unH*T8Ak{GNHCvO8dOOA#SRcIMYpib=J| z$q9am1@m5e(L6XJcyI;r$^72a*qyPnb5%n3n#%MSQF8qpr_KQx7-+oJ5|p9lO!oy* zT&u1GkW)uO{N>B8YCrPhO=asot}vm$Wkl~x(V=*nDkWvbZ%^)_xhFkSCS5~oQzyIZ z0H!4U{z}abiG0Y>Klo@#ZCELmq0N4>!oeVS$^&4#$Im01I@_6%w*sVaoya5mcm`Jj z*N@1VcHg0d&h~Xo!_-$VI7nJwA9|$pd-|$803ViY;lBu;Bt$tLR$zomV;m5YC}L!h z!6+-K8+cUu0wM$-@KW!;KEIA0{k=c@-$dyCCss|+8mvXf1S36JXr|8n7~1B*+Jh0+ zrmm>mVNm=PHlT*+okE1d9$!nCk%36#awwOdg`S+f2pGmWf}<4LA|NwW+J#C`=H z1p2?+>vii_kJl_EfcV>neHr$iu)&vRbCJ*qg7WWD5%Ch_rZL0`ZJS?d9SQywmLJGJMzNm8>~e>$Tt#hUoO<@_hJxKOo(;-Pop z0I!5~Bm<9gLv#`;6fQKrj@9)eA;r8Japi00#A8(^(Q{ws8h~LLtqn|FM7>sLfY~q7);OE72Jc+yiFwUXNB+Rj%3o)-PIJW(9jnB|PdLzb#x+oF@BLY!^(=A2#~Rmng% zU2`lZ%mKgeB?htBElkfPZ3gmyuAaF(v@S(fAD*J&Ju6K-Vk*1q3UQ~cZx-VvgG65L ztvM#FQ+SBb3HBq0f{#?Zl48<$DT?TIHf28BOt)Bb*@IN8U@Sk23pl}qSr=|ue^Gbc z8m*4uAgCl_hdF7g)*!++MU;#xHDde`AkPRFvFKW2)z9txW*-$?o=9&i2?$k3^t7QG zovphJnh(jHkuUZgcN2Wg>Mq2ouE}EQom->y?zS$5T%s(UVU%}cP7gdP7tm58{E8{W z-qXoB4`>q#iii(*Wy$FE(*fC5Gat~ZV7M^ZRC9K|ggT~Q2!dj)&sDpyIEH&d{+3Lm zXib=5vlI@-xw}5^n}H>BB+3~)@iH^>-o->;{Ff2*VkAEeySgTUA(?Dn8kvgLDLJb+ zcv;1ROPDPda6`Zh>_|sAqAdXXYQEGVUv0(nWbQSfoX;dLjVFijtK%lHffRp zBRCLfg9%`Cr5vLMrFpj?7rTlag=5o0FlnqGwN76o(=iqWFP}m1XbK!0>wkP(y;fxH+b1p&WE)9eM5d+7{4L9#x>S{4o|h8>#Xxdmow^zTsHOrinHsHklB8g zO+g{@Q(Z1agXUW4uaN}(QK@%wIN#P1O#r#r^`eXKWwo5z+-a?1_!@>!U2pDW=WU?p zN~}i&2{o59zIh0g-J79v(Ivy#?}7RY$ldKvcG&lqjPZCKAs@0(ZdCG`v8W-8mV2cl+9I4xO5G?6??xW59N0)@i6sxNX#^+~*qS z+Ym@*P&6?F;`Qm7Gvt5&g`9O;D264rq`ebTcR02r*ji#@idBdK!joaw8))Ehn=`8Q z?G7nKPOrQwfaUd$*2i?hx~~zIF4k?>lDIPM;RXwx9ZHC__n;eN>D$WB2;t2%{I_Ew z;Ji8u5o_J+q3>!u`Su`uFTh3Sw*98Jn{JyX!Fcq03G`etEVlw*=8d?uhIU4-xmW3M zeZgdOT1zk*>_|2yWn}DJhKyZ@qZ?OO;cgn9!4Ed5VV-WCx}yGYVlUHp^IqfO%6@*> z-rHPPdSNW=W9nS0>5ex!BpxlosDGQ&0S)giUGIF@OE9)ChD=X7H%S0?&&CI0S Date: Fri, 28 Feb 2025 17:43:50 +0100 Subject: [PATCH 39/45] Borrado fichero temporal --- images/temp | 1 - 1 file changed, 1 deletion(-) delete mode 100644 images/temp diff --git a/images/temp b/images/temp deleted file mode 100644 index 8b137891..00000000 --- a/images/temp +++ /dev/null @@ -1 +0,0 @@ - From 919698f95830e1181190219956fbfc679dab9b5a Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Fri, 28 Feb 2025 17:53:08 +0100 Subject: [PATCH 40/45] =?UTF-8?q?A=C3=B1adida=20la=20imagen=20de=20la=20co?= =?UTF-8?q?bertura?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- images/Imagen-cobertura.png | Bin 0 -> 7245 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/Imagen-cobertura.png diff --git a/images/Imagen-cobertura.png b/images/Imagen-cobertura.png new file mode 100644 index 0000000000000000000000000000000000000000..c53f6928e855803a1d5815bcc4c294d46b47856c GIT binary patch literal 7245 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 literal 0 HcmV?d00001 From b5b102c6dcc94ede7542a25e6d18d4279312ff13 Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Fri, 28 Feb 2025 18:01:11 +0100 Subject: [PATCH 41/45] =?UTF-8?q?A=C3=B1adida=20imagen=20de=20un=20error?= =?UTF-8?q?=20detectado=20por=20la=20integraci=C3=B3n=20continua?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- images/Ejemplo-error.png | Bin 0 -> 47142 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/Ejemplo-error.png diff --git a/images/Ejemplo-error.png b/images/Ejemplo-error.png new file mode 100644 index 0000000000000000000000000000000000000000..8e4ddbfa9ba3aa345e0575490d5a3c860313e800 GIT binary patch literal 47142 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 Bvx5Kt literal 0 HcmV?d00001 From 04236bdf2d545f5a43e86d160012319639f2767f Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Fri, 28 Feb 2025 18:08:07 +0100 Subject: [PATCH 42/45] =?UTF-8?q?A=C3=B1adida=20imagen=20del=20n=C3=BAmero?= =?UTF-8?q?=20de=20workflow=20runs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- images/Numero-workflow.runs.png | Bin 0 -> 1923 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/Numero-workflow.runs.png diff --git a/images/Numero-workflow.runs.png b/images/Numero-workflow.runs.png new file mode 100644 index 0000000000000000000000000000000000000000..db749dd3c0df211d07041f3e81f64c13736584f4 GIT binary patch literal 1923 zcma)-dpHw{AI8_(u!R_AqRC}$>1c-$IvAE%xfNoL6q4NULTt;OkV`sbm}_<1+T1ml zg^q5Nh-efh6`5hobo~DK{r&s>@qXXueV*@M@AE#-C*9uGN(_1g3IG7atj}6H?t8($ zj*AHGUrKpJ#J(K}ceFAGG`v>$x*tHk*z;HbpgHHz?iKKUhJ>7T4F>?kng7v&q2M}i z06-XFZHc`Y5GQsAi}snKWuKOf|Tv`U;OPFIYarnEjo#tFcKzI4XOwBBk| zfwH>z_OI(*ln4go?`nEiO-n~=jodC)M%MJcI=2t(@jgc;Z&=&Du>MpS_m0`Z#|VX2 zL!38q-4orQJ*B&ZDf8$HtqJq&yh_HsCkj%{xrd8O%FwZPBxdFO!6KrPtp7Y z36g5c?MDuWQJYgZ2Hlpq&rg`xl7hJGyW0>*T4*#^WW)5~9M^b9vj5s!@r$mBCpLdT z8wfl6wydXJq=925iQWIKs35*U2CB?~X z*?rQZH#hCQ(7Z)MFZXPnpgfFF+mvY=C6uOCX=UmEN>f6mz4>y@+~Gjs&$u9Wq+;K* zN@BcQ+{c)f5ulP{gMW~k32>bzLys0n8&+cKy(+hZuenJ2Ty|(*Bj}KDGVdtRPfIU_ z%gfhKEPK$Elc%|5U#~={4a)WejF%~SJro{x!}HVQReiFuC!X$j)X|$PSgmr=#GkOU zU18fwy?wzdiEvaWJraRL?~1+ znn}w=#i2N}DKGY=D?9#ftk`uslF?AGhY|Ib$!h?*SJ^+#awSTtoXX=HZhbpYEdJCi zlAp9EDu+kgM@{h`H3d3^L>lC)+Dc@=-n9h|TYF-YwU4)&*U@~Ka_ z)ctk|#bYBp`@2i%6ZD42#j?DClY$pLhpl+Vy;4(1G}nWOfVEa4ud#a0u>4WwRojLE z$6CysoSRr$B=73KO&MGF{BgJ4k&OnsXcKU56$Tt*k_S4yo3yk%343s8T3Gw}8>ieZ zyfQ4}3qyAFx3kq^H|3LVSMD%>hsQ~PRionHb1w6Zz9c@ap^GZcc`mrRCuWrgz3EGM zl9|a?tVin>x|M(4Fz=XgE*%nD3MTVFWL zxnPzjeZ?+U1n!+Gqbo^9{t)K~FwpzC>l0)6aku$Wx9b~?kbmN1Yf~L?0~ashgFoJQ zSe)0iDSfXj$W`i$aR=+<0W`HD=E4zwn<8%Y`x|3HG}Zd^2Fe5)gkL(Q7)$c?K#mN9 z2@V|DT+u4HMo<2`J7Qyvf{xn25JeWD!Jr1wj!Df(793UKMs9{xGqaNsQZ5rgl13RN zo}hDaoF;9}_$8rTx1)JoL&ZPG5mDLb4$vZ-fasaVNBioyBse7pKDOaSTRhI$7Q5+Z zG|HUMOLG4-IIyh8P?2Xm6T>AxfSz#=em65YFuS3z08iW2K{xG2l?)a;>MN*H$ptPX zcD(G&{yf(n;7o5^z@5LHb$NxlQV3nnUSW31#7J0kfO&t70Sl=i{BIACB^EQ3Q~~km z$5xH}p6fNS%+KLamb-K-u~WiRgop>p(pNjK&h;)6DnHMMtOKMnG8SBovkyiE5WGO2 z{Ay|p{d|fZe4hVF%t5F@Z5g<@=7iqZZoSe|%%uQnzi7$qgQ)NPPMZ(!n8yoWV+_vk zH#_ONlj589NNt{t5BV@V*mc2gqJC6ZtEL;4-9``DT?n{1@S-DS(dx3<@7()5Upew! k(Oc#a^8XEv|B^)@4@y-W5py8=?1K|vjkC3EF!vb%7 literal 0 HcmV?d00001 From c28e43050949f4097b9ec850a73ec7f8cdb5a1ec Mon Sep 17 00:00:00 2001 From: npi1001 <116637646+Nicop17@users.noreply.github.com> Date: Wed, 12 Mar 2025 02:27:15 +0100 Subject: [PATCH 43/45] Create codacy-coverage.yml --- .github/workflows/codacy-coverage.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/codacy-coverage.yml diff --git a/.github/workflows/codacy-coverage.yml b/.github/workflows/codacy-coverage.yml new file mode 100644 index 00000000..2355fe31 --- /dev/null +++ b/.github/workflows/codacy-coverage.yml @@ -0,0 +1,20 @@ +name: Codacy Coverage +on: [push, pull_request] + +jobs: + report-coverage: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Run tests with coverage + run: | + pip install pytest pytest-cov + pytest --cov=my_project --cov-report=xml + + - name: Upload to Codacy + run: | + bash <(curl -Ls https://coverage.codacy.com/get.sh) report -r coverage.xml + env: + CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }} From 75d1b92f8f0b5bc2343a64195fb5eefeae677f9c Mon Sep 17 00:00:00 2001 From: npi1001 <116637646+Nicop17@users.noreply.github.com> Date: Wed, 12 Mar 2025 02:54:28 +0100 Subject: [PATCH 44/45] Update codacy-coverage.yml --- .github/workflows/codacy-coverage.yml | 53 +++++++++++++++++++-------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/.github/workflows/codacy-coverage.yml b/.github/workflows/codacy-coverage.yml index 2355fe31..ac5394ea 100644 --- a/.github/workflows/codacy-coverage.yml +++ b/.github/workflows/codacy-coverage.yml @@ -1,20 +1,41 @@ -name: Codacy Coverage -on: [push, pull_request] +name: Codacy Coverage Reporter + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] jobs: - report-coverage: + build: + runs-on: ubuntu-latest + steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Run tests with coverage - run: | - pip install pytest pytest-cov - pytest --cov=my_project --cov-report=xml - - - name: Upload to Codacy - run: | - bash <(curl -Ls https://coverage.codacy.com/get.sh) report -r coverage.xml - env: - CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }} + - uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + + - name: Build with Maven + run: mvn -B package --file pom.xml + + # Generar el reporte de cobertura de JaCoCo + - name: Run tests and generate coverage report + run: mvn test jacoco:report # Asegúrate de que se genere el reporte de cobertura + + # Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive + - name: Update dependency graph + uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6 + + # Subir el reporte de cobertura a Codacy + - name: Run codacy-coverage-reporter + uses: codacy/codacy-coverage-reporter-action@v1.3.0 + with: + project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} + coverage-reports: target/site/jacoco-aggregate.xml # Ruta del reporte generado por JaCoCo + From 6aa89ad532c90036b1298e4a75cffac7ac584dee Mon Sep 17 00:00:00 2001 From: ibai <142017599+ibaimoya@users.noreply.github.com> Date: Thu, 13 Mar 2025 18:08:14 +0100 Subject: [PATCH 45/45] =?UTF-8?q?A=C3=B1adida=20badge=20de=20codebeat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index acc551f1..0af8a6f0 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,13 @@ poolobject [![codecov](https://codecov.io/gh/Nicop17/poolobject/graph/badge.svg?token=D6XRI5RQA1)](https://codecov.io/gh/Nicop17/poolobject) [![Java CI with Maven](https://github.com/Nicop17/poolobject/actions/workflows/Java17CImaven.yml/badge.svg)](https://github.com/Nicop17/poolobject/actions/workflows/Java17CImaven.yml) +[![codebeat badge](https://codebeat.co/badges/c0e21c3c-a6ab-4f31-a252-35818dd76e5a)](https://codebeat.co/projects/github-com-ibaimoya-poolobject-master) [![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-orange.svg)](https://opensource.org/licenses/GPL-2.0) [![Wiki Home](https://img.shields.io/badge/Wiki-Home-blue)](https://github.com/Nicop17/poolobject/wiki) + Java code example of creational design pattern pool object Workshop to use good practices in software development: testing, ci and measurement.