From d8216aad4479d4b502c445ae5faf9293be94d665 Mon Sep 17 00:00:00 2001 From: Sian January Date: Wed, 18 Aug 2010 11:30:50 +0000 Subject: [PATCH] Pack200 - new tests and some accompanying bug fixes git-svn-id: https://svn.apache.org/repos/asf/harmony/enhanced/java/trunk@986626 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/harmony/pack200/ClassBands.java | 10 +- .../harmony/pack200/MetadataBandGroup.java | 2 +- .../apache/harmony/pack200/PackingUtils.java | 2 +- .../harmony/pack200/PopulationCodec.java | 9 +- .../org/apache/harmony/pack200/RunCodec.java | 6 +- .../org/apache/harmony/pack200/Segment.java | 21 ++- .../harmony/pack200/tests/ArchiveTest.java | 14 ++ .../harmony/pack200/tests/CodecTest.java | 17 -- .../pack200/tests/PopulationCodecTest.java | 16 ++ .../harmony/pack200/tests/RunCodecTest.java | 166 ++++++++++++++++++ .../harmony/pack200/tests/annotations.jar | Bin 0 -> 3064 bytes 11 files changed, 226 insertions(+), 37 deletions(-) create mode 100644 src/test/java/org/apache/harmony/pack200/tests/RunCodecTest.java create mode 100644 src/test/resources/org/apache/harmony/pack200/tests/annotations.jar diff --git a/src/main/java/org/apache/harmony/pack200/ClassBands.java b/src/main/java/org/apache/harmony/pack200/ClassBands.java index fb1de8d..67a6c18 100644 --- a/src/main/java/org/apache/harmony/pack200/ClassBands.java +++ b/src/main/java/org/apache/harmony/pack200/ClassBands.java @@ -1328,22 +1328,22 @@ public class ClassBands extends BandSet { boolean visible, List nameRU, List t, List values, List caseArrayN, List nestTypeRS, List nestNameRU, List nestPairN) { if(visible) { method_RVPA_bands.addAnnotation(desc, nameRU, t, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN); - Integer flag = (Integer) tempMethodFlags.remove(tempMethodFlags.size() - 1); + Long flag = (Long) tempMethodFlags.remove(tempMethodFlags.size() - 1); if((flag.intValue() & (1<<23)) != 0) { method_RVPA_bands.incrementAnnoN(); } else { method_RVPA_bands.newEntryInAnnoN(); } - tempMethodFlags.add(new Integer(flag.intValue() | (1<<23))); + tempMethodFlags.add(new Long(flag.longValue() | (1<<23))); } else { method_RIPA_bands.addAnnotation(desc, nameRU, t, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN); - Integer flag = (Integer) tempMethodFlags.remove(tempMethodFlags.size() - 1); - if((flag.intValue() & (1<<24)) != 0) { + Long flag = (Long) tempMethodFlags.remove(tempMethodFlags.size() - 1); + if((flag.longValue() & (1<<24)) != 0) { method_RIPA_bands.incrementAnnoN(); } else { method_RIPA_bands.newEntryInAnnoN(); } - tempMethodFlags.add(new Integer(flag.intValue() | (1<<24))); + tempMethodFlags.add(new Long(flag.longValue() | (1<<24))); } } diff --git a/src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java b/src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java index 9704e2b..cd54dbb 100644 --- a/src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java +++ b/src/main/java/org/apache/harmony/pack200/MetadataBandGroup.java @@ -268,7 +268,7 @@ public class MetadataBandGroup extends BandSet { } else if (tag.equals("J")) { Long value = (Long)valuesIterator.next(); caseJ_KJ.add(cpBands.getConstant(value)); - } else if (tag.equals("C")) { + } else if (tag.equals("c")) { String value = (String)valuesIterator.next(); casec_RS.add(cpBands.getCPSignature(value)); } else if (tag.equals("e")) { diff --git a/src/main/java/org/apache/harmony/pack200/PackingUtils.java b/src/main/java/org/apache/harmony/pack200/PackingUtils.java index 5433e83..689aec4 100644 --- a/src/main/java/org/apache/harmony/pack200/PackingUtils.java +++ b/src/main/java/org/apache/harmony/pack200/PackingUtils.java @@ -86,7 +86,7 @@ public class PackingUtils { } /** - * When effort is 0, the packer copys through the original jar input stream + * When effort is 0, the packer copies through the original jar input stream * without compression * * @param jarInputStream diff --git a/src/main/java/org/apache/harmony/pack200/PopulationCodec.java b/src/main/java/org/apache/harmony/pack200/PopulationCodec.java index 48ad1e7..5a2998b 100644 --- a/src/main/java/org/apache/harmony/pack200/PopulationCodec.java +++ b/src/main/java/org/apache/harmony/pack200/PopulationCodec.java @@ -151,11 +151,16 @@ public class PopulationCodec extends Codec { } public byte[] encode(int[] favoured, int[] tokens, int[] unfavoured) throws Pack200Exception { - byte[] favouredEncoded = favouredCodec.encode(favoured); + int[] favoured2 = new int[favoured.length + 1]; + System.arraycopy(favoured, 0, favoured2, 0, favoured.length); + favoured2[favoured2.length - 1] = favoured[favoured.length - 1]; // repeat last value; + byte[] favouredEncoded = favouredCodec.encode(favoured2); byte[] tokensEncoded = tokenCodec.encode(tokens); byte[] unfavouredEncoded = unfavouredCodec.encode(unfavoured); byte[] band = new byte[favouredEncoded.length + tokensEncoded.length + unfavouredEncoded.length]; - + System.arraycopy(favouredEncoded, 0, band, 0, favouredEncoded.length); + System.arraycopy(tokensEncoded, 0, band, favouredEncoded.length, tokensEncoded.length); + System.arraycopy(unfavouredEncoded, 0, band, favouredEncoded.length + tokensEncoded.length, unfavouredEncoded.length); return band; } diff --git a/src/main/java/org/apache/harmony/pack200/RunCodec.java b/src/main/java/org/apache/harmony/pack200/RunCodec.java index 1f45a00..4842809 100644 --- a/src/main/java/org/apache/harmony/pack200/RunCodec.java +++ b/src/main/java/org/apache/harmony/pack200/RunCodec.java @@ -135,13 +135,11 @@ public class RunCodec extends Codec { } public byte[] encode(int value, int last) throws Pack200Exception { - // TODO Auto-generated method stub - return null; + throw new Pack200Exception("Must encode entire band at once with a RunCodec"); } public byte[] encode(int value) throws Pack200Exception { - // TODO Auto-generated method stub - return null; + throw new Pack200Exception("Must encode entire band at once with a RunCodec"); } public int getK() { diff --git a/src/main/java/org/apache/harmony/pack200/Segment.java b/src/main/java/org/apache/harmony/pack200/Segment.java index 2f748c0..bdbc5dd 100644 --- a/src/main/java/org/apache/harmony/pack200/Segment.java +++ b/src/main/java/org/apache/harmony/pack200/Segment.java @@ -458,31 +458,40 @@ public class Segment implements ClassVisitor { name = ""; } nameRU.add(name); - values.add(value); - addTag(value); + addValueAndTag(value); } - private void addTag(Object value) { + private void addValueAndTag(Object value) { if(value instanceof Integer) { T.add("I"); + values.add(value); } else if (value instanceof Double) { T.add("D"); + values.add(value); } else if (value instanceof Float) { T.add("F"); + values.add(value); } else if (value instanceof Long) { T.add("J"); + values.add(value); } else if (value instanceof Byte) { T.add("B"); + values.add(new Integer(((Byte)value).intValue())); } else if (value instanceof Character) { T.add("C"); + values.add(new Integer(((Character)value).charValue())); } else if (value instanceof Short) { T.add("S"); + values.add(new Integer(((Short)value).intValue())); } else if (value instanceof Boolean) { T.add("Z"); + values.add(new Integer(((Boolean)value).booleanValue() ? 1 : 0)); } else if (value instanceof String) { T.add("s"); + values.add(value); } else if (value instanceof Type) { T.add("c"); + values.add(((Type)value).toString()); } } @@ -499,8 +508,7 @@ public class Segment implements ClassVisitor { Integer numPairs = (Integer) nestPairN.remove(nestPairN.size() - 1); nestPairN.add(new Integer(numPairs.intValue() + 1)); nestNameRU.add(name); - values.add(value); - addTag(value); + addValueAndTag(value); } public AnnotationVisitor visitAnnotation(String arg0, @@ -543,8 +551,7 @@ public class Segment implements ClassVisitor { name = ""; } nameRU.add(name); - values.add(value); - addTag(value); + addValueAndTag(value); } public AnnotationVisitor visitAnnotation(String arg0, diff --git a/src/test/java/org/apache/harmony/pack200/tests/ArchiveTest.java b/src/test/java/org/apache/harmony/pack200/tests/ArchiveTest.java index 02a69fa..4d87b23 100644 --- a/src/test/java/org/apache/harmony/pack200/tests/ArchiveTest.java +++ b/src/test/java/org/apache/harmony/pack200/tests/ArchiveTest.java @@ -344,6 +344,20 @@ public class ArchiveTest extends TestCase { compareFiles(jarFile, jarFile2); } + + public void testAnnotations2() throws IOException, Pack200Exception, + URISyntaxException { + in = new JarFile(new File(Archive.class.getResource( + "/org/apache/harmony/pack200/tests/annotations.jar").toURI())); + file = File.createTempFile("annotations", ".pack"); + file.deleteOnExit(); + out = new FileOutputStream(file); + PackingOptions options = new PackingOptions(); + options.setGzip(false); + new Archive(in, out, options).pack(); + in.close(); + out.close(); + } public void testE0() throws Pack200Exception, IOException, URISyntaxException { File f1 = new File(Archive.class.getResource( diff --git a/src/test/java/org/apache/harmony/pack200/tests/CodecTest.java b/src/test/java/org/apache/harmony/pack200/tests/CodecTest.java index 25818bd..7d59953 100644 --- a/src/test/java/org/apache/harmony/pack200/tests/CodecTest.java +++ b/src/test/java/org/apache/harmony/pack200/tests/CodecTest.java @@ -165,23 +165,6 @@ public class CodecTest extends TestCase { assertFalse(byte2s.encodes(256)); } - public void testRunCodec() throws Exception { - RunCodec runCodec = new RunCodec(1, Codec.UNSIGNED5, Codec.BYTE1); - ByteArrayInputStream bais = new ByteArrayInputStream(new byte[] { - (byte) 192, 0, (byte) 192, 0 }); - assertEquals(192, runCodec.decode(bais)); - assertEquals(192, runCodec.decode(bais)); - assertEquals(0, runCodec.decode(bais)); - assertEquals(0, bais.available()); - runCodec = new RunCodec(1, Codec.BYTE1, Codec.UNSIGNED5); - bais = new ByteArrayInputStream(new byte[] { (byte) 192, 0, (byte) 192, - 0 }); - assertEquals(192, runCodec.decode(bais)); - assertEquals(0, runCodec.decode(bais)); - assertEquals(192, runCodec.decode(bais)); - assertEquals(0, bais.available()); - } - public void testUnsigned5() throws Exception { decode(Codec.UNSIGNED5, new byte[] { 1 }, 1, 0); decode(Codec.UNSIGNED5, new byte[] { (byte) 191 }, 191, 0); diff --git a/src/test/java/org/apache/harmony/pack200/tests/PopulationCodecTest.java b/src/test/java/org/apache/harmony/pack200/tests/PopulationCodecTest.java index 06a07a5..ab1bee3 100644 --- a/src/test/java/org/apache/harmony/pack200/tests/PopulationCodecTest.java +++ b/src/test/java/org/apache/harmony/pack200/tests/PopulationCodecTest.java @@ -22,6 +22,7 @@ import java.io.InputStream; import junit.framework.TestCase; +import org.apache.harmony.pack200.BHSDCodec; import org.apache.harmony.pack200.Codec; import org.apache.harmony.pack200.Pack200Exception; import org.apache.harmony.pack200.PopulationCodec; @@ -63,5 +64,20 @@ public class PopulationCodecTest extends TestCase { } assertEquals(0, in.available()); } + + public void testEncodeSingleValue() { + try { + new PopulationCodec(BHSDCodec.SIGNED5, BHSDCodec.SIGNED5, BHSDCodec.UDELTA5).encode(5); + fail("Should not allow a single value to be encoded as we don't know which codec to use"); + } catch (Pack200Exception e) { + // pass + } + try { + new PopulationCodec(BHSDCodec.SIGNED5, BHSDCodec.SIGNED5, BHSDCodec.UDELTA5).encode(5, 8); + fail("Should not allow a single value to be encoded as we don't know which codec to use"); + } catch (Pack200Exception e) { + // pass + } + } } diff --git a/src/test/java/org/apache/harmony/pack200/tests/RunCodecTest.java b/src/test/java/org/apache/harmony/pack200/tests/RunCodecTest.java new file mode 100644 index 0000000..b11e480 --- /dev/null +++ b/src/test/java/org/apache/harmony/pack200/tests/RunCodecTest.java @@ -0,0 +1,166 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.harmony.pack200.tests; + +import java.io.ByteArrayInputStream; + +import junit.framework.TestCase; + +import org.apache.harmony.pack200.BHSDCodec; +import org.apache.harmony.pack200.Codec; +import org.apache.harmony.pack200.Pack200Exception; +import org.apache.harmony.pack200.PopulationCodec; +import org.apache.harmony.pack200.RunCodec; + +/** + * Test for RunCodec + */ +public class RunCodecTest extends TestCase { + + public void testRunCodec() { + try { + new RunCodec(0, BHSDCodec.SIGNED5, BHSDCodec.UDELTA5); + fail("Should not allow a k value of 0"); + } catch (Pack200Exception e) { + // pass + } + try { + new RunCodec(10, null, BHSDCodec.UDELTA5); + fail("Should not allow a null codec"); + } catch (Pack200Exception e) { + // pass + } + try { + new RunCodec(10, BHSDCodec.UDELTA5, null); + fail("Should not allow a null codec"); + } catch (Pack200Exception e) { + // pass + } + try { + new RunCodec(10, null, null); + fail("Should not allow a null codec"); + } catch (Pack200Exception e) { + // pass + } + } + + public void testDecode() throws Exception { + RunCodec runCodec = new RunCodec(1, Codec.UNSIGNED5, Codec.BYTE1); + ByteArrayInputStream bais = new ByteArrayInputStream(new byte[] { + (byte) 192, 0, (byte) 192, 0 }); + assertEquals(192, runCodec.decode(bais)); + assertEquals(192, runCodec.decode(bais)); + assertEquals(0, runCodec.decode(bais)); + assertEquals(0, bais.available()); + runCodec = new RunCodec(1, Codec.BYTE1, Codec.UNSIGNED5); + bais = new ByteArrayInputStream(new byte[] { (byte) 192, 0, (byte) 192, + 0 }); + assertEquals(192, runCodec.decode(bais)); + assertEquals(0, runCodec.decode(bais)); + assertEquals(192, runCodec.decode(bais)); + assertEquals(0, bais.available()); + } + + public void testDecodeInts() throws Exception { + int[] band = new int[] { 1, -2, -3, 1000, 55, 5, 10, 20 }; + // first 5 of band to be encoded with DELTA5 + byte[] bytes1 = Codec.DELTA5.encode(new int[] { 1, -2, -3, 1000, 55 }); + // rest of band to be encoded with UNSIGNED5 + byte[] bytes2 = Codec.UNSIGNED5.encode(new int[] { 5, 10, 20 }); + byte[] bandEncoded = new byte[bytes1.length + bytes2.length]; + System.arraycopy(bytes1, 0, bandEncoded, 0, bytes1.length); + System.arraycopy(bytes2, 0, bandEncoded, bytes1.length, bytes2.length); + RunCodec runCodec = new RunCodec(5, Codec.DELTA5, Codec.UNSIGNED5); + int[] bandDecoded = runCodec.decodeInts(8, new ByteArrayInputStream( + bandEncoded)); + assertEquals(band.length, bandDecoded.length); + for (int i = 0; i < band.length; i++) { + assertEquals(band[i], bandDecoded[i]); + } + } + + public void testNestedPopulationCodec() throws Exception { + int[] band = new int[] { 11, 12, 33, 4000, -555, 5, 10, 20, 10, 3, 20, + 20, 20, 10, 10, 999, 20, 789, 10, 10, 355, 12345 }; + // first 5 of band to be encoded with DELTA5 + byte[] bytes1 = Codec.DELTA5 + .encode(new int[] { 11, 12, 33, 4000, -555 }); + // rest of band to be encoded with a PopulationCodec + PopulationCodec popCodec = new PopulationCodec(Codec.UNSIGNED5, + Codec.BYTE1, Codec.UNSIGNED5); + byte[] bytes2 = popCodec.encode(new int[] { 10, 20 }, new int[] { 0, 1, + 2, 1, 0, 2, 2, 2, 1, 1, 0, 2, 0, 1, 1, 0, 0 }, new int[] { 5, + 3, 999, 789, 355, 12345 }); + byte[] bandEncoded = new byte[bytes1.length + bytes2.length]; + System.arraycopy(bytes1, 0, bandEncoded, 0, bytes1.length); + System.arraycopy(bytes2, 0, bandEncoded, bytes1.length, bytes2.length); + RunCodec runCodec = new RunCodec(5, Codec.DELTA5, new PopulationCodec( + Codec.UNSIGNED5, Codec.BYTE1, Codec.UNSIGNED5)); + int[] bandDecoded = runCodec.decodeInts(band.length, + new ByteArrayInputStream(bandEncoded)); + assertEquals(band.length, bandDecoded.length); + for (int i = 0; i < band.length; i++) { + assertEquals(band[i], bandDecoded[i]); + } + } + + public void testNestedRunCodec() throws Exception { + int[] band = new int[] { 1, 2, 3, 10, 20, 30, 100, 200, 300 }; + // first 3 of band to be encoded with UDELTA5 + byte[] bytes1 = Codec.UDELTA5.encode(new int[] { 1, 2, 3 }); + // rest of band to be encoded with a RunCodec + byte[] bytes2 = Codec.BYTE1.encode(new int[] { 10, 20, 30 }); + byte[] bytes3 = Codec.UNSIGNED5.encode(new int[] { 100, 200, 300 }); + byte[] bandEncoded = new byte[bytes1.length + bytes2.length + + bytes3.length]; + System.arraycopy(bytes1, 0, bandEncoded, 0, bytes1.length); + System.arraycopy(bytes2, 0, bandEncoded, bytes1.length, bytes2.length); + System.arraycopy(bytes3, 0, bandEncoded, bytes1.length + bytes2.length, + bytes3.length); + RunCodec runCodec = new RunCodec(3, Codec.UDELTA5, new RunCodec(3, + Codec.BYTE1, Codec.UNSIGNED5)); + int[] bandDecoded = runCodec.decodeInts(9, new ByteArrayInputStream( + bandEncoded)); + assertEquals(band.length, bandDecoded.length); + for (int i = 0; i < band.length; i++) { + assertEquals(band[i], bandDecoded[i]); + } + } + + public void testToString() throws Pack200Exception { + RunCodec runCodec = new RunCodec(3, Codec.UNSIGNED5, Codec.BYTE1); + assertEquals( + "RunCodec[k=" + 3 + ";aCodec=" + Codec.UNSIGNED5.toString() + + "bCodec=" + Codec.BYTE1.toString() + "]", + runCodec.toString()); + } + + public void testEncodeSingleValue() { + try { + new RunCodec(10, BHSDCodec.SIGNED5, BHSDCodec.UDELTA5).encode(5); + fail("Should not allow a single value to be encoded as we don't know which codec to use"); + } catch (Pack200Exception e) { + // pass + } + try { + new RunCodec(10, BHSDCodec.SIGNED5, BHSDCodec.UDELTA5).encode(5, 8); + fail("Should not allow a single value to be encoded as we don't know which codec to use"); + } catch (Pack200Exception e) { + // pass + } + } +} diff --git a/src/test/resources/org/apache/harmony/pack200/tests/annotations.jar b/src/test/resources/org/apache/harmony/pack200/tests/annotations.jar new file mode 100644 index 0000000000000000000000000000000000000000..d381bc7b12aa3cac172415766f20a5327fcb7393 GIT binary patch literal 3064 zcmai$2{@Gd9>)jMj4fMZJ=wPs%915ZjOA&Jku6G=29q_iL})Ns8<8x9C`ol3Ymr?T z>t!%GvW7WIlA=rq6XzYBduF)j-uru>_jzWX_x=Cg-{=4TEniC{3m67s1+Kexym}x8 zgMq*xl!>jO62ijtD9X?RVQOMytBf+;>H&c$C}OWUQc3yMex#B@KXIVa`q+>fd3I)& z8DxosvObSuUi<}cB@En_e}7;wf@9YQWPqnAOt7cFyP=<-e=s`O%iquXieIqTC5)X{ zke913M%m359TcRq;yF!{MxP*I3K@Rho;zr33gO+4 z5|5oBrxg$zgMCaPWn}7L!8_X;;=z0o40VyjGH>tZe!=|$#MLezDum;5^B{ws32EVE z4zLLBpsLRwY|I8gCV-ocir=%ByuedBr0QNSiybb%zln6E{~tt*KK!UOi~Z$DFRQ@c z&R?`pAo0l9tQa`F77`W`&cbD7GJ%DJM`>X~cfv$eIO9BlAX0XP>2YoMiSPqYO}#L_ z3bs9XWVE=fvm$3A zMN-tAed-@#Z#Gt%KL6 zvMx{S_$Fn{^@Ie^vVcipdJJU@W2;zGvglwNDq*^RMU$3|!BZ>`>HsoPCdMP$n~eg% z8+)_y-|%|eOop)B&{~RUGF*}`ZqTGOP0NahO)%N}E1_rnz^cqv4uSj2qxSm**%?`i zT(+j#(t7<#&^OB!GLN^7#-^tZ>4Ykw`&2}?!-_;1!5+Ru9ouO6BVBPGsNhe{1@sw()?@NdqB(I_mU*816+Be%b^<;Qn%@o{EjZzZ7n4Dsl%iMPUD zzm06(coHO2pM%3bDQ~S<4SDCI4ci~3Xf*bF#AyUzGMfGodC=1 z?15Y0X{e1~;L`Yj zQY)j>;?9gy({Z}0a>5^5bp1OQChv&sa|)11t_-^UXd+&-sUkpI@BLKb+3Yfm$~zsi zuAmu#Av>eErd7Kz~6MPMl8?w2eH4v zvgEJ`U9y;aOQY@l9q!NnXmHAn1KufGnSw_c6a;P-6j7@#51XV zW^D$rxPj8)DzDd`3(YeY<0zw%vMOs!uppD*qMXW;!)=^0>DSBO7jTn}ZfHKz3Q!3m z-wPUW?4KLy5@~@6iaEqiC0mcPru!UUsX(yaag~K1wiVFt=v7w{t7g5Mf^Wu=`uN6= zNET-tJD4n$yI_S^?9Z~uP1>zRtkG^MM&9*_ArD%u*A?x5})1h@Cj)Lw3piPTJf zc3$pZa99da>sQAQ1-vlcjc3EE{5`FLtFqP^vqwd!6W8pTzsy7y7E2-K>fDhePao@u za@O3Ar+s-Fjt>&JK8iGaDP1Mi)F+D;H?Wp0qNhKCjEbRJRpGI2#qwIS#suMMrQ9eM z+9uAf*@Z!XBCg(5$Q5C`H<1-6WaZ0&{@xh3;47&}E`kKiq${U3A-*nO4O-Rd`6l`b z(8J^RAsart_Jb|27)az| z9r6|=& zK}Ld8nw{05JNC)h6C#~?m-O4CmUOHe^MW=e7qt;f!K7Ebr8e=_!?BR0)Y#j2e1;MQ z-P9I7>2RDkN5?*}xhbb-LNY8OWfkwy;; z+;;VTDYVjSN*q-gM(sPi?0Lf{wU%ukc%{*pgJS>@c*H)P>gcNLr}RAh!1y+MHo2GV zlBa=Ryv!F>_Ht)Z-(`OGxEf$NvO~+n3EJ0Bnabxrb!UGQGn(DC`cGx(3lv99Bq=* zZ3$>QdzpUb38N3%IAm;6v~ftcMV8&ek#Qxhi7{5@ZvH?BBmZA5jd3}xd>Ip*R=#wr nfzpe4?<&Sbp(Q`v$^j?zQm{ns1A+j7*nrCf*o-_j+P^;m^nZh1 literal 0 HcmV?d00001